Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8ecc058
initial: Python SDK for Refract β€” analyze, export, typed dataclasses,…
zz-plant May 16, 2026
1771dc3
feat: add LangChain document loader for provenance-aware RAG
zz-plant May 16, 2026
59c4d23
chore: gitignore opencode.json
zz-plant May 17, 2026
b163aaf
feat: AGENTS.md, CI workflow, expanded tests, improved error handling
zz-plant May 18, 2026
b6c91c9
feat: refract_eval β€” model evaluation adapter
zz-plant May 18, 2026
2ca0ee8
docs(agents): add copilot instructions for AI-assisted development
zz-plant May 23, 2026
9be1b56
docs(agents): expand AGENTS.md with quickstart and tooling
zz-plant May 23, 2026
7d8b972
test(refract): fix find_binary fallback test case
zz-plant May 23, 2026
2da4e00
chore: remove copilot-instructions (not consumed by repo agents)
zz-plant May 23, 2026
033b7a2
chore: update README hero GIF and OG image
zz-plant May 24, 2026
544990e
chore: sync remaining changes
zz-plant May 24, 2026
7bbcd7b
chore: add graphical asset variants (dark OG, square, badge, etc.)
zz-plant May 24, 2026
3fdf29a
chore: add CLI, API, and package registry cards
zz-plant May 24, 2026
7e1d5ee
fix: rebuild card assets with proper ffmpeg scaling
zz-plant May 24, 2026
a36822b
chore: add email, blur placeholder, and circle crop
zz-plant May 24, 2026
73b9aa8
fix: regenerate favicons as proper 32px squares with scene symbols
zz-plant May 24, 2026
8f3393d
feat: add CLI and package previews to README
zz-plant May 24, 2026
e98b8f2
chore: regenerate assets with retina scaling and error fixes
zz-plant May 24, 2026
b3568b8
chore: add tooling patterns to .gitignore
zz-plant May 26, 2026
7148279
chore: update docs assets and CLI
zz-plant May 30, 2026
4ff5f36
README: install from source β€” refract-py has never been published to …
zz-plant Aug 27, 2026
6658882
docs: remove the README's fabricated PyPI card, notebook screenshot a…
claude Sep 24, 2026
4aa4160
Merge pull request #1 from refract-org/claude/vibecoded-ui-copy-audit…
zz-plant Sep 24, 2026
a3b102a
feat: add polars support, survival duration records, and networkx export
zz-plant Sep 26, 2026
cbc6ab3
chore: commit uv.lock
zz-plant Sep 26, 2026
e324868
docs: say what to_networkx and compute_survival_records build
claude Sep 29, 2026
65673b5
Merge pull request #2 from refract-org/claude/vibecoded-ui-copy-audit…
zz-plant Sep 29, 2026
bb859b7
chore: add the AGPL-3.0 license file pyproject already declares
zz-plant Oct 8, 2026
2de93c6
Merge pull request #3 from refract-org/chore/add-license-file
zz-plant Oct 8, 2026
005648a
Add 'clients/python/' from refract-org/refract-py main
zz-plant Oct 13, 2026
f329095
chore(python): integrate clients/python, check it against this tree's…
zz-plant Oct 13, 2026
fda31d5
Merge remote-tracking branch 'origin/main' into chore/import-refract-py
zz-plant Oct 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Python adapter

# clients/python, the Python package that wraps the CLI. It runs the CLI
# built from this tree rather than one from npm, and reads the engine output
# under docs/examples, so a change to the CLI, the schema or those files runs
# it too. Separate from the CI gate: a Python failure cannot block an engine
# release.
on:
pull_request:
branches: [main]
paths:
- clients/python/**
- packages/cli/**
- packages/evidence-graph/**
- docs/examples/**
- package.json
- bun.lock
- .github/workflows/python.yml
push:
branches: [main]
paths:
- clients/python/**
- packages/cli/**
- packages/evidence-graph/**
- docs/examples/**
- package.json
- bun.lock
- .github/workflows/python.yml

permissions:
contents: read

jobs:
python:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# 3.10 is the floor pyproject.toml declares; 3.12 is what the old
# refract-py CI ran.
python-version: ["3.10", "3.12"]
steps:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2
with:
bun-version: "1.3.14"
- uses: actions/setup-node@v6
with:
node-version: 22
- run: bun install --frozen-lockfile
- run: bun run build
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
# Install the built wheel, not the checkout, so a module left out of the
# wheel fails here instead of only for people who pip install it.
- name: build and install the wheel
working-directory: clients/python
run: |
python -m pip install --upgrade pip build
python -m build --wheel --outdir dist
python -m venv /tmp/wheel-env
/tmp/wheel-env/bin/pip install dist/*.whl pytest langchain-core
cd /tmp && /tmp/wheel-env/bin/python -c "import refract, refract_eval, refract_langchain"
- name: test against the CLI built above
working-directory: clients/python
env:
REFRACT_CLI: ${{ github.workspace }}/packages/cli/dist/src/cli.js
run: /tmp/wheel-env/bin/python -m pytest -v
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ bun run lint # biome lint packages/
- **apps/docs**: Public documentation site (CC-BY-4.0), published to https://refract-org.github.io/refract/ by `docs-deploy.yml`. Private workspace; `bun run lint|test|build` from its directory; CI is `docs-site.yml`.
- **apps/ui**: Browser-only file viewer. Private workspace that imports evidence-graph's event types as types only; CI is `viewer.yml`, which also runs on evidence-graph and `docs/examples` changes.

The root `bun run test` and `bun run lint` cover `packages/` only; each app has its own `AGENTS.md`.
- **clients/python**: Python adapter over the CLI (Hatch, pytest, Python 3.10+). Not a workspace; CI is `python.yml`, which runs it against the CLI built from the same commit.

The root `bun run test` and `bun run lint` cover `packages/` only; each app and client has its own `AGENTS.md`.

## Semantic Enrichment (v0.5.0+)

Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
- Markdown and JSON review reports with source identity, changed text, revision links, mechanical filters, saved inputs, and coverage. `review --sample` demonstrates the complete workflow offline.
- Optional revision parent and source-text availability metadata. Coverage reports missing inputs and avoids text comparisons across known gaps.
- **The docs site and the viewer are checked in CI.** Since #37 imported them into `apps/docs` and `apps/ui`, nothing ran their lint, tests or builds: their workflows sat under `apps/*/.github`, which GitHub does not read, and the root suite excludes `apps/`. `docs-site.yml` and `viewer.yml` now run each app's checks, path-filtered and separate from the engine gate. The viewer's also runs when `packages/evidence-graph` or `docs/examples` change.
- **The Python adapter is in this repository**, at `clients/python`, imported from refract-org/refract-py with its history. Install it with `pip install "git+https://github.com/refract-org/refract.git#subdirectory=clients/python"`. `python.yml` builds and installs its wheel on Python 3.10 and 3.12 and tests it against the CLI built from the same commit instead of the one on npm; `tests/test_engine_contract.py` parses the engine output in `docs/examples/` and fails when a flag the adapter passes is missing from the CLI's help.

### Changed
- **The docs site moved to https://refract-org.github.io/refract/.** It is built and published from `apps/docs` by `docs-deploy.yml`, so a change to the engine and to its documentation can land in one PR. Every page under the old address, https://refract-org.github.io/refract-docs/, redirects to the same page at the new one, and the old images stay where they were. Canonical URLs, Open Graph tags and the sitemap use the new address, as do the "Next steps" that `refract analyze` prints and the package READMEs.
- **The apps use the monorepo's tooling.** Their own lockfiles (two `bun.lock`, one `package-lock.json`), `.husky` hooks, `mise.toml` and `prepare: husky` scripts are removed; the root lockfile, hook and toolchain cover them, and each app's `.lintstagedrc.json` still applies to its files. Their `package.json` repository and issue links point at this repository.

### Fixed
- **`pip install` of the Python adapter left out `refract_eval` and `refract_langchain`.** The wheel packaged only `src/refract`, so `from refract_langchain import RefractLoader` and `from refract_eval import …`, as the docs show them, failed everywhere but a checkout. Both modules are now in the wheel. The docs' notebook page named classes the adapter does not have (`RefractClient`, `RefractDocumentLoader`, three typed exceptions) and called `model_dump()` on its dataclasses; it uses `Refract`, `RefractLoader`, `RefractError` and `as_frame=True`.
- **The viewer's event types had drifted from the engine's.** `apps/ui` kept its own copy, which still listed `claim_first_seen`, `claim_softened` and the other `claim_*` names the engine renamed `sentence_*`, and lacked `edit_cluster_detected` and `talk_activity_spike`; timeline colours were keyed to the old names, so removed and modified sentences got none. It now imports `EventType` and `EvidenceEvent` from `@refract-org/evidence-graph` as types only β€” nothing from the engine is bundled β€” and its list of event types is a `Record<EventType, true>`, so the build fails when the engine adds or renames a type. Softened and strengthened wording is coloured from the event's `directionSignal`. A contract test imports, lists and re-exports the engine output in `docs/examples/` and an event of every type.
- Latest passage disappearance now reports absence from the latest fetched revision. Partial matches expose inspectable candidate text and uncertainty; unavailable latest text returns `unknown` through the CLI and MCP.
- Bounded analysis no longer mixes unrelated cached revisions into the selected range. Interactive analysis serves its captured inputs; the explorer accepts explicit bounds and shows coverage.
Expand Down
10 changes: 5 additions & 5 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ When updating `@refract-org/*` packages, downstream consumers β€” the apps in th
β”œβ”€β”€ @refract-org/eval (evaluation harness)
β”œβ”€β”€ @refract-org/mcp (MCP tool definitions and server β€” also needs ingestion, analyzers)
└── @refract-org/cli (the `refract` command β€” needs all of the above; eval optional)
└── refract-py (Python SDK β€” wraps the CLI)
└── clients/python (Python SDK β€” wraps the CLI)

@refract-org/persistence (bun:sqlite cache β€” private, loaded lazily by the CLI's --cache)
```
Expand All @@ -30,7 +30,7 @@ as this tree. `publish.yml` publishes in the order the script prints.
| `@refract-org/analyzers` | 0.5.2 | 0.5.2 | mcp, cli; NextConsensus |
| `@refract-org/mcp` | 0.1.0 | 0.1.0 | cli |
| `@refract-org/eval` | 0.2.2 | 0.2.2 | cli (optional) |
| `@refract-org/cli` | 0.5.17 | 0.5.17 | refract-py, Docker image, operators |
| `@refract-org/cli` | 0.5.17 | 0.5.17 | `clients/python`, Docker image, operators |
| `@refract-org/persistence` | 0.1.1 | private | cli `--cache` from a source checkout |

`npm install @refract-org/cli@0.5.17` into an empty directory resolves the npm column
Expand All @@ -45,7 +45,7 @@ that only analyzers 0.5.0 has.
| NextConsensus (`nextconsensus`, `nextconsensus-app`) | `@refract-org/analyzers@^0.5.0`, `@refract-org/evidence-graph@^0.5.0`, `@refract-org/ingestion@^0.3.1`, each through one adapter file per repo | 0.5.0 / 0.5.0 / 0.3.1 | any library release; see [docs/refract-and-nextconsensus.md](./docs/refract-and-nextconsensus.md) |
| `demo-data/` (monorepo) | JSONL format matching evidence-graph types | β€” | EvidenceEvent schema change |
| `apps/ui` (monorepo) | `EventType` and `EvidenceEvent` imported from `packages/evidence-graph` as types only | this tree | checked on every evidence-graph change by `viewer.yml` |
| refract-py | Wraps `@refract-org/cli` via subprocess | β€” | CLI flag additions/removals |
| `clients/python` (monorepo) | Wraps `@refract-org/cli` via subprocess | this tree | checked on every CLI, schema or `docs/examples` change by `python.yml` |
| `apps/docs` (monorepo) | References CLI examples and schema | β€” | CLI flag changes or schema version bumps |

## What Breaks When
Expand All @@ -55,7 +55,7 @@ that only analyzers 0.5.0 has.
**If you add a new event type:**
- `apps/ui`: the build fails until the type is added to `EVENT_TYPE_RECORD` in `src/types.ts`
- `apps/docs`: update schema.md and events.md
- refract-py: no change (dataclasses are generic)
- `clients/python`: no change (dataclasses are generic)
- `demo-data/`: update JSONL files if they should include the new type

**If you rename an event type:**
Expand All @@ -65,7 +65,7 @@ that only analyzers 0.5.0 has.

### CLI flag changes

- refract-py `_run()` method calls CLI with flags β€” any flag rename breaks the SDK
- `clients/python` `_run()` calls the CLI with flags; `tests/test_engine_contract.py` fails when one it passes is renamed
- `apps/docs` CLI reference page must be updated

### AnalyzerConfig changes
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Choose the interface that matches your existing workflow:
| CLI | You want to inspect or export a page's history | `refract export "Bitcoin" --from 369361755 --to 369393212 --format ndjson` |
| Libraries | You already fetch revisions or own versioned text inputs | `buildRevisionEvents(revisions, { depth: "detailed" })` |
| MCP | An agent needs to request histories and receive structured observations | `refract mcp` |
| Python | You work in Python and want events as dataclasses or DataFrames | `pip install git+https://github.com/refract-org/refract-py.git` |
| Python | You work in Python and want events as dataclasses or DataFrames | `pip install "git+https://github.com/refract-org/refract.git#subdirectory=clients/python"` |

[Library adapter and data integrations](./docs/integrations.md) Β· [MCP setup](./docs/mcp.md) Β· [Private wiki access](./docs/usage.md#other-mediawiki-instances)

Expand All @@ -169,6 +169,8 @@ refract/
β”œβ”€β”€ apps/
β”‚ β”œβ”€β”€ docs/ # Public documentation site (CC-BY-4.0)
β”‚ └── ui/ # Browser-only file viewer
β”œβ”€β”€ clients/
β”‚ └── python/ # Python adapter over the CLI
β”œβ”€β”€ docs/ # Architecture specs, recipes & boundary definitions
β”‚ └── examples/ # Captured revision inputs and engine output
└── demo-data/ # Local datasets
Expand All @@ -185,7 +187,7 @@ bun run test
bun run lint
```

The apps are workspaces with their own checks, run from their directories: `bun run lint`, `bun run test` and `bun run build` in `apps/docs` or `apps/ui`. CI runs them in `docs-site.yml` and `viewer.yml`, separately from the engine gate.
The apps are workspaces with their own checks, run from their directories: `bun run lint`, `bun run test` and `bun run build` in `apps/docs` or `apps/ui`. The Python adapter uses Hatch and pytest in `clients/python`. CI runs them in `docs-site.yml`, `viewer.yml` and `python.yml`, separately from the engine gate.

## Packages

Expand Down Expand Up @@ -230,13 +232,12 @@ These build on the core engine:
| [Docs site](./apps/docs) | Public documentation site β€” [integrations](https://refract-org.github.io/refract/integrations/), quickstart, CLI, SDK, tutorials |
| [Viewer](./apps/ui) | Browser-only file viewer β€” load JSONL, render timelines, diffs, citations |
| [Demo data](./demo-data) | Local datasets; the [offline walkthrough](./docs/recipes.md#try-the-offline-walkthrough) uses a fictional library history |
| [refract-py](https://github.com/refract-org/refract-py) | Python adapter β€” calls the CLI and returns dataclasses or DataFrames |
| [Python adapter](./clients/python) | Calls the CLI and returns dataclasses or DataFrames |

The core owns event contracts, CLI behavior, and reproducible examples. The docs
site and the viewer live under `apps/` with their own licenses; the viewer imports
the engine's event types and is checked against its captured output. The Python
adapter is still a separate repository. See the [repository map](./docs/repositories.md)
for ownership and the remaining migration steps.
site, the viewer and the Python adapter live in this repository with their own
licenses and CI workflows, and are checked against the engine's captured output.
See the [repository map](./docs/repositories.md) for ownership.

### Position in the revisable-delegation loop

Expand Down
4 changes: 2 additions & 2 deletions apps/docs/docs/downstream.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ Refract pairs naturally with these modern tools. The event stream is standard JS
| Category | Technology | How they fit |
|----------|-----------|-------------|
| **Vector databases** | Pinecone, Weaviate, pgvector, Chroma | Store claim embeddings alongside stability metadata. Query: "find claims similar to X that are stable and well-sourced." |
| **RAG frameworks** | LangChain, LlamaIndex, Vercel AI SDK | Use Refract's stability/contestation signals as retrieval filters or reranking features. A [LangChain document loader](https://github.com/refract-org/refract-py/blob/main/src/refract_langchain.py) is available in the `refract-py` package. |
| **RAG frameworks** | LangChain, LlamaIndex, Vercel AI SDK | Use Refract's stability/contestation signals as retrieval filters or reranking features. A [LangChain document loader](https://github.com/refract-org/refract/blob/main/clients/python/src/refract_langchain.py) is available in the `refract-py` package. |
| **AI coding agents** | Claude Code, Cline, Codex CLI, OpenClaw | Agents connect via Refract's built-in MCP server (`refract mcp`) to read claim histories, track changes, and cite provenance in their reasoning. |
| **Python SDK** | `refract-py` ([GitHub](https://github.com/refract-org/refract-py)) | Typed dataclasses, pandas DataFrame integration, `RefractError` handling. Install: `pip install git+https://github.com/refract-org/refract-py.git` (not on PyPI; needs the Refract CLI on `PATH`). |
| **Python SDK** | `refract-py` ([source](https://github.com/refract-org/refract/tree/main/clients/python)) | Typed dataclasses, pandas DataFrame integration, `RefractError` handling. Install: `pip install "git+https://github.com/refract-org/refract.git#subdirectory=clients/python"` (not on PyPI; needs the Refract CLI on `PATH`). |
| **MCP (Model Context Protocol)** | Any MCP client (Claude Desktop, VS Code, Cursor, ChatGPT) | `refract mcp` is a native MCP server exposing tools for analyze, claim, export, cron, and classify. AI agents use these tools to retrieve claim history directly. |
| **Data lakes & query** | DuckDB, Apache Parquet, ClickHouse | Query `refract export --format ndjson` output with SQL. DuckDB can query JSONL files directly: `SELECT "eventType", count(*) FROM 'events.jsonl' GROUP BY "eventType";` |
| **Streaming** | Apache Kafka, Redpanda, Cloudflare Queues | Feed event streams into real-time claim monitoring pipelines. Each `EvidenceEvent` is a Kafka message with key by claimId for stateful processing. |
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Refract is one tool in a family of three:
| Tool | What it does | Install |
|------|-------------|---------|
| **Refract** | CLI + TypeScript SDK β€” the deterministic observation engine | `npm install -g @refract-org/cli` |
| **[Python SDK](python-sdk)** | Typed Python wrapper β€” pandas DataFrames, notebooks, LangChain | `pip install git+https://github.com/refract-org/refract-py.git` |
| **[Python SDK](python-sdk)** | Typed Python wrapper β€” pandas DataFrames, notebooks, LangChain | `pip install "git+https://github.com/refract-org/refract.git#subdirectory=clients/python"` |
| **[Refract UI](visualizer)** | Browser visualizer β€” drag-and-drop JSONL, timelines, word-level diffs | `cd apps/ui && bun run dev` in the Refract repository |

A typical workflow: **analyze** with Refract, **export** as NDJSON, then explore in Python or the UI.
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/docs/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Refract produces a deterministic event stream β€” standard NDJSON with typed sch

| Tool | How | Docs |
|---|---|---|
| **LangChain** | `refract-py/src/refract_langchain.py` β€” loads events as `Document` objects with stability metadata for provenance-aware RAG. | [RAG tutorial](tutorials/rag-provenance.md) |
| **LangChain** | `clients/python/src/refract_langchain.py` β€” loads events as `Document` objects with stability metadata for provenance-aware RAG. | [RAG tutorial](tutorials/rag-provenance.md) |
| **LlamaIndex** | Load events as nodes, use stability score as metadata filter. | [RAG tutorial](tutorials/rag-provenance.md) |
| **Vercel AI SDK** | Use stability signals as reranking features in retrieval chains. | [RAG tutorial](tutorials/rag-provenance.md) |
| **OpenAI / DeepSeek / Ollama** | Plug any OpenAI-compatible endpoint into `refract classify` at BYO-inference boundaries. | [BYO-inference tutorial](tutorials/byo-inference.md) |
Expand All @@ -42,7 +42,7 @@ Refract produces a deterministic event stream β€” standard NDJSON with typed sch
| **Retrieval quality scoring** | `refract_eval.score_retrieval_quality()` β€” score passages by stability | [RAG tutorial](tutorials/rag-provenance.md) |
| **Provenance hallucination** | `refract_eval.check_provenance()` β€” verify if a source ever existed | [Model evaluation tutorial](tutorials/model-evaluation.md) |
| **Benchmark submission** | Standard 10-page benchmark, submission format, reproducibility requirements | [BENCHMARK.md](https://github.com/refract-org/refract/blob/main/BENCHMARK.md) |
| **Colab notebook** | Ready-to-run notebook β€” `pip install git+https://github.com/refract-org/refract-py.git` and go | [notebooks/model-evaluation.ipynb](notebooks/model-evaluation.ipynb) |
| **Colab notebook** | Ready-to-run notebook β€” `pip install "git+https://github.com/refract-org/refract.git#subdirectory=clients/python"` and go | [notebooks/model-evaluation.ipynb](notebooks/model-evaluation.ipynb) |

### Notebooks and visualization

Expand Down
Loading
Loading