Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

reviews:
auto_review:
enabled: true
drafts: false
path_filters:
- "examples/**"
- "!examples/**/data/**"
- "!examples/**/fixtures/**"
- "examples/**/fixtures/SOURCES.md"
- "!examples/**/verified-run/**"
- "examples/**/verified-run/README.md"
- "!examples/**/uv.lock"
path_instructions:
- path: "examples/**"
instructions: |
Review runnable source, tests, configuration, and documentation.
Check that commands match the implementation and that tests cover failure paths.
Flag client-side model-name translation and undocumented synthetic results.
3 changes: 3 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ service keys.
| [Multi-model contract review with the OpenAI Agents SDK](./contract-review-agent) | Running an OpenAI Agents SDK agent whose every model call (triage, orchestration, vision, OCR, embeddings, rerank, entity extraction, text-to-SQL, reasoning, and a safety guardrail) is served by one SIE cluster, each step on the right catalog model, with per-model observability | `chat/completions`, `encode`, `score`, `extract` | GPU SIE deployment required; standalone `uv` project; real contracts fetched from CUAD (CC BY 4.0) | Runnable demo |
| [Turn difficult PDFs into Markdown](./document-to-markdown) | Preserving tables, reading order, headings, and form labels across real financial, academic, and government PDFs | `extract` | SIE endpoint with `docling`; standalone `uv` project; source PDFs fetched at run time | Runnable evaluation example |
| [Review a flood claim packet](./insurance-claims-agent) | Finding an unsigned form and a $400 evidence mismatch across a policy, estimate, inventory, and damage photograph | `extract`, `score`, `chat/completions` | GPU SIE deployment; standalone `uv` project; public FEMA documents and public-domain photograph fetched at run time | Runnable agent example |
| [Trace a restated filing figure](./financial-filing-agent) | Following one reported figure through an original filing, corrective notice, and restatement while preserving source status | `extract`, `encode`, `score` | SIE endpoint; standalone `uv` project; public SEC facts and saved verified evidence | Runnable agent example |
| [Reproduce CMS's L1851 documentation finding](./prior-authorization-review-agent) | Tracing a published six-month requirement against a seven-month face-to-face encounter and CMS's recoupment result | `extract`, `encode`, `score` | SIE endpoint; standalone `uv` project; exact CMS published example | Runnable agent example |
| [Reconstruct a bearing failure](./maintenance-triage-agent) | Turning the NTSB's three East Palestine detector readings into a cited temperature and alert sequence without adding a new causal claim | `extract`, `encode`, `score` | SIE endpoint; standalone `uv` project; exact NTSB illustrated report spread | Runnable agent example |

For docs publishing, lead with the quickest runnable demos, then use the
benchmark and evaluation examples for deeper technical users.
Expand Down
2 changes: 2 additions & 0 deletions examples/financial-filing-agent/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SIE_CLUSTER_URL=http://localhost:8080
SIE_API_KEY=
7 changes: 7 additions & 0 deletions examples/financial-filing-agent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.env
.venv/
.pytest_cache/
.ruff_cache/
__pycache__/
*.pyc
runs/
84 changes: 84 additions & 0 deletions examples/financial-filing-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Trace a restated figure back to the controlling filings

This example follows one Pathward Financial fact through exact table rows from
an original Form 10-Q and a restated Form 10-K/A, plus exact sentences from an
Item 4.02 Form 8-K. It returns both versions, calculates the change, and keeps
the source status and company caveat attached.

The result is narrow on purpose. It does not classify the restatement as fraud
or misconduct, and it does not make an investment recommendation.

## What runs on SIE

| Step | Model | Output |
|---|---|---|
| Parse the source packet | `docling` | Markdown with source headings |
| Retrieve candidate passages | `BAAI/bge-m3` | Dense vectors and cosine ranking |
| Rerank against the exact question | `Qwen/Qwen3-Reranker-4B` | Ordered evidence with scores |
| Verify the cited spans | `urchade/gliner_multi-v2.1` | Exact source spans |
| Recover exact source spans | `fastino/gliner2-large-v1` | Table values, period, company and reliance-status entities |

Each stage consumes the prior stage. The result fails closed if either entity
model omits a required source span. The original values come from the original
Form 10-Q table. The restated values come from the Form 10-K/A table, and the
pipeline checks that its “As Previously Reported” column matches the Form 10-Q.
The company caveat is retained verbatim only when the reranked evidence contains
its exact source sentence. Ordinary Python code calculates the difference with
decimal arithmetic.

## Verified result

The recorded component calls ran through the public SIE server on an NVIDIA L4.
The restated passage ranked first for the question about the restated Q3 FY2023
figure.

```text
Net income attributable to parent $45.096M -> $36.080M
Change -$9.016M (-20.0%)
Diluted EPS $1.68 -> $1.34
Source status earlier affected filings should no longer be relied upon
```

Pathward's exact statement stays in the result: the accounting change does not
impact net income over the life of the portfolio, but changes when elements of
the programs are recognized.

## Run it

```bash
cd examples/financial-filing-agent
cp .env.example .env
uv sync

uv run review-filing --run-id local
uv run eval-filing runs/local
```

Set `SIE_CLUSTER_URL` and `SIE_API_KEY` to use SIE Cloud. The default points to
a local server at `http://localhost:8080`.

## Evidence bundle

Every run writes:

```text
runs/<run-id>/manifest.json endpoint, model IDs, fixture hashes, latency
runs/<run-id>/raw/parse.json complete Docling response
runs/<run-id>/raw/retrieve.json embeddings and cosine ranking
runs/<run-id>/raw/rerank.json complete reranker response
runs/<run-id>/raw/entities.json combined entity spans
runs/<run-id>/raw/gliner2-*.json raw GLiNER2 source-span responses
runs/<run-id>/raw/mapped.json validated record mapped from Docling table coordinates
runs/<run-id>/parsed.md parsed packet used downstream
runs/<run-id>/review.json source-versioned result and calculated delta
runs/<run-id>/evaluation.json deterministic checks
```
Comment on lines +60 to +75

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Artifact bundle list omits per-stage entity extraction files.

review.py also writes raw/entities-original-10q.json, raw/entities-restated-10ka.json, and raw/entities-status.json (per-stage GLiNER responses) in addition to the combined raw/entities.json, but only the combined file is documented here.

📝 Proposed doc fix
-runs/<run-id>/raw/entities.json   combined entity spans
+runs/<run-id>/raw/entities.json   combined entity spans
+runs/<run-id>/raw/entities-*.json per-stage GLiNER responses (original 10-Q, restated 10-K/A, filing status)

As per path instructions, examples documentation should be checked so "commands match the implementation."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Evidence bundle
Every run writes:
```text
runs/<run-id>/manifest.json endpoint, model IDs, fixture hashes, latency
runs/<run-id>/raw/parse.json complete Docling response
runs/<run-id>/raw/retrieve.json embeddings and cosine ranking
runs/<run-id>/raw/rerank.json complete reranker response
runs/<run-id>/raw/entities.json combined entity spans
runs/<run-id>/raw/gliner2-*.json raw GLiNER2 source-span responses
runs/<run-id>/raw/mapped.json validated record mapped from Docling table coordinates
runs/<run-id>/parsed.md parsed packet used downstream
runs/<run-id>/review.json source-versioned result and calculated delta
runs/<run-id>/evaluation.json deterministic checks
```
## Evidence bundle
Every run writes:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/financial-filing-agent/README.md` around lines 60 - 75, Update the
“Evidence bundle” artifact list in the README to document the per-stage files
written by review.py: raw/entities-original-10q.json,
raw/entities-restated-10ka.json, and raw/entities-status.json, alongside the
existing combined raw/entities.json entry.

Source: Path instructions


`verified-run/` contains the saved evidence used to design the example. It is
not a latency benchmark. The first request included model provisioning.
Its manifest preserves the upstream-style Docling name configured during
acquisition and the canonical `docling` ID that SIE actually served. New runs
use the canonical ID directly.

See [fixtures/SOURCES.md](fixtures/SOURCES.md) for accession numbers, URLs, and
source checksums.
16 changes: 16 additions & 0 deletions examples/financial-filing-agent/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cluster:
url: "http://localhost:8080"
api_key: ""
provision_timeout_s: 900

models:
parse: "docling"
retrieve: "BAAI/bge-m3"
rerank: "Qwen/Qwen3-Reranker-4B"
entities: "urchade/gliner_multi-v2.1"
extract: "fastino/gliner2-large-v1"

review:
query: "Compare Pathward's original and restated Q3 FY2023 net income and diluted EPS, then identify the superseded source and company caveat."
candidate_chunks: 8
top_k: 8
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Source-versioned financial filing review."""
102 changes: 102 additions & 0 deletions examples/financial-filing-agent/financial_filing/evaluate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from __future__ import annotations

import argparse
import hashlib
import json
from dataclasses import asdict, dataclass
from pathlib import Path
from typing import Any

from rich.console import Console
from rich.table import Table

console = Console()


@dataclass(frozen=True)
class Check:
name: str
passed: bool
detail: str


def evaluate_review(review: dict[str, Any]) -> list[Check]:
change = review.get("change", {})
excluded = set(review.get("claims_excluded", []))
evidence = review.get("ranked_evidence", [])
evidence_text = "\n".join(str(row.get("text", "")) for row in evidence).casefold()
return [
Check("route", review.get("route") == "superseded_figure", str(review.get("route"))),
Check("net-income-delta", abs(float(change.get("value_millions", 0)) + 9.016) < 0.0001, str(change)),
Check("eps-delta", abs(float(change.get("diluted_eps", 0)) + 0.34) < 0.0001, str(change)),
Check("percent-delta", abs(float(change.get("percent", 0)) + 20.0) < 0.05, str(change)),
Check(
"source-lineage", len(review.get("controlling_sources", [])) == 3, str(review.get("controlling_sources"))
),
Check(
"caveat-preserved",
"over the life of the portfolio" in review.get("company_caveat", ""),
review.get("company_caveat", ""),
),
Check(
"ranked-source-evidence",
bool(evidence)
and all(
token in evidence_text
for token in (
"pathward financial",
"$45,096",
"$36,080",
"$1.68",
"$1.34",
"no longer",
"over the life of the portfolio",
)
),
str([row.get("chunk_id") for row in evidence]),
),
Check(
"unsafe-claims-excluded",
{"fraud", "misconduct", "investment recommendation"} <= excluded,
", ".join(sorted(excluded)),
),
]


def evaluate_run(run_dir: Path) -> bool:
review = json.loads((run_dir / "review.json").read_text(encoding="utf-8"))
checks = evaluate_review(review)
passed = all(check.passed for check in checks)
evaluation_path = run_dir / "evaluation.json"
evaluation_path.write_text(
json.dumps({"passed": passed, "checks": [asdict(check) for check in checks]}, indent=2) + "\n",
encoding="utf-8",
)
manifest_path = run_dir / "manifest.json"
if manifest_path.exists():
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
artifacts = [
artifact for artifact in manifest.get("artifacts", []) if artifact.get("path") != "evaluation.json"
]
artifacts.append(
{"path": "evaluation.json", "sha256": hashlib.sha256(evaluation_path.read_bytes()).hexdigest()}
)
manifest["artifacts"] = artifacts
manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
table = Table("Check", "Result", "Detail")
for check in checks:
table.add_row(check.name, "[green]pass[/]" if check.passed else "[red]fail[/]", check.detail)
console.print(table)
return passed


def main() -> None:
parser = argparse.ArgumentParser(description="Evaluate a saved filing review")
parser.add_argument("run_dir", type=Path)
args = parser.parse_args()
if not evaluate_run(args.run_dir):
raise SystemExit(1)


if __name__ == "__main__":
main()
Loading