YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
DeepResearch-RL (tearsheet-agent-service)
Containerized pi (@earendil-works/pi-coding-agent@1.0.4)
deep-research agent service for generating multi-section company tearsheets with grounded [N]
citations, deterministic section/fact completeness auditing, tool-execution policy guards, and
OpenTelemetry GenAI trajectory + reasoning-token export to W&B Weave
(forge-ai-dev/Tearsheet-Pi-Agent).
Built under epic FND-516 as the harnessed agent foundation for Reinforcement Learning (RL /
GRPO with Prime Intellect): frontier trajectories (xai/grok-4.7) and deterministic completeness
audits (section_parser) serve as reference rollouts, reward signals, and evaluation benchmarks for
training compact open-weight reasoning models (such as LiquidAI/LFM2.5-8B-A1B served via vLLM).
Architecture & Layout
agent_runtime/β PI agent runtime configuration (baked into/app/agent_runtime_templatein the container and rendered at startup bydocker/entrypoint.sh):AGENTS.mdβ 10-section tearsheet output contract, inline[N]citation rules, and structured```facts/```retractionsYAML block specification.required_facts.yamlβ Per-section required-fact inventory with stable identities and intentional blank allow-lists (e.g., target-company valuation/multiple cells in the comparables table).skills/section-completeness/SKILL.mdβ Meta-harness skill embedding the canonical fact inventory and anti-gaming rules.extensions/websearch_fetch.tsβ PI extension registering customwebsearch(Perplexity/searchAPI) andfetchtools backed by Python clients andSourceRegistry.extensions/tool_call_guard.tsβ Pre-tool execution hook enforcingToolPolicy({read, websearch, fetch}allow-list and protected config/registry paths).models.jsonβ Multi-provider configuration supporting both:perplexity-agent(api: "openai-responses", default modelxai/grok-4.7,reasoning: true)hf-vllm(api: "openai-completions", default modelLiquidAI/LFM2.5-8B-A1B,contextWindow: 128000,reasoning: true, compatible with any vLLM / OpenAI-compatible server).
src/tearsheet_agent_service/cli.pyβ Terminal CLI entrypoint (tearsheet-research).pi_rpc_client.pyβ Asyncio JSONL RPC client forpi --mode rpc.run_manager.pyβrun_research_stream()async generator andrun_research()wrapper.source_registry.pyβ Persistent citation ledger ([N]β URL, title, retrieved excerpt, status).agent_runtime_support/βsection_parser.py(deterministic 10-section & fact-identity auditor) andtool_policy.py(tool/path authorization).api/β FastAPI HTTP/SSE service (app.py,run_manager.py,schemas.py,auth.py,trace_bridge.py).web_tools/βSearchClient,FetchClient, and subprocess CLI bridge.rl/β Prime Intellectverifiers-compatible Stage 2 RL / GRPO training & evaluation suite:rubric.pyβ 33-failure-mode (EA03-*)TearsheetRubric(15Tier-A deterministic Python verifiers +18Tier-B closed-world NLI Judge specs), Multiplicative Anti-Hacking Gate (MiMo-V2.6Eq. 2), Groupwise Advantage Redistribution (GAR, Eq. 3), and Group-Relative Length Penalty (Eq. 4).census_meta_eval.pyβ Offline meta-verification runner evaluating the 33-mode rubric against the 555-claim historical census (146not_supported+409supportedcontrols).env.pyβ Stateful multi-turnTearsheetToolEnvwith isolated per-rolloutSourceRegistry,HybridReplayCache, andfull_tearsheetprompt contract enforcement (Decision D3).sampler.pyβDynamicDiscrepancySampler($\max R - \min R \ge 0.05$, Decision D1) and multi-providerJudgeClient(perplexityxai/grok-4.7primary +mistralmistral-large-latestfallback, Decision D2).weave_dataset.pyβ W&B Weave teacher trajectory harvester (forge-ai-dev/Tearsheet-Pi-Agent) and Teacher-Prefix On-Policy Distillation (Teacher-Prefix OPD,MiMo-V2.6Β§5.6) dataset builder.train_sft_warmup.pyβ Stage 1 100-step SFT / Prefix-OPD warm-up trainer with strict assistant-only loss masking (labels = -100onsystem/user/toolturns) and frozen MoE routing gates.train_grpo.pyβ Stage 2 Split-GPUA100x2MoE GRPO trainer withfreeze_moe_router(MiMo-V2.6Β§5.4 Fig. 11) andprompt_meantoken loss aggregation (MiMo-V2.6Β§5.2).
spaces/DeepResearch-RL-Trainer/β Ready-to-deploy Hugging Face Space bundle (Dockerfile,rl.toml,start_a100x2_grpo.sh,README.md) targetinga100x2(2Γ NVIDIA A100 80GB = 160GB VRAM) with GPU 0 dedicated to vLLM rollout generation and GPU 1 dedicated to SFT/GRPO training.scripts/build_and_push_ecr.pyβ Automated cloud Docker build & push to AWS ECR via AWS CodeBuild (no local Docker daemon required).deploy_hf_lfm25_endpoint.shβ DeploysLiquidAI/LFM2.5-8B-A1Bon Hugging Face Inference Endpoints usingvllm/vllm-openai:v0.29.0with FP8 quantization (--quantization fp8 --kv-cache-dtype fp8),--reasoning-parser qwen3, and--tool-call-parser lfm2onnvidia-l40s(48 GB VRAM).
Docker & AWS ECR Usage
1. Pre-built Image in AWS ECR
- ECR Repository URI:
526489132647.dkr.ecr.us-west-2.amazonaws.com/tearsheet-agent-service-poc:latest - Current Image Digest:
sha256:d71f274bd32ca71615828b7754febea01da00ddaf69c931c2cfd22521e01a659 - Region / Account:
us-west-2/526489132647(sandboxprofile)
2. Rebuilding & Pushing to ECR (via AWS CodeBuild)
When local Docker is unavailable, build and push directly in AWS using:
aws sso login --profile sandbox
python3 scripts/build_and_push_ecr.py --cleanup-builder
(Packages the repo, runs buildspec.yml inside CodeBuild including container smoke tests, pushes :latest to ECR, and cleans up the temporary CodeBuild project/IAM role/S3 zip).
If building on a machine with Docker installed:
docker build -t tearsheet-agent-service:latest .
3. Running the Container as an HTTP/SSE Microservice (Default CMD)
By default, the container starts uvicorn tearsheet_agent_service.api.app:create_default_app --factory --host 0.0.0.0 --port 8000:
# Authenticate to ECR (if pulling from AWS)
aws ecr get-login-password --region us-west-2 --profile sandbox \
| docker login --username AWS --password-stdin 526489132647.dkr.ecr.us-west-2.amazonaws.com
docker run --rm -p 8000:8000 \
-e PERPLEXITY_API_KEY="$PERPLEXITY_API_KEY" \
-e WANDB_API_KEY="$WANDB_API_KEY" \
-e TEARSHEET_SERVICE_API_KEY="dev-local-api-key" \
-e TEARSHEET_AGENT_PROVIDER="perplexity-agent" \
-e TEARSHEET_AGENT_MODEL_ID="xai/grok-4.7" \
-e HF_TOKEN="${HF_TOKEN:-}" \
-e HF_INFERENCE_ENDPOINT_URL="https://6ad3b6e6d2d0ab8296e5999d.endpoints.huggingface.cloud/v1" \
-e OTEL_EXPORTER_OTLP_ENDPOINT="https://trace.wandb.ai/agents/otel" \
-e OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" \
-e OTEL_RESOURCE_ATTRIBUTES="wandb.entity=forge-ai-dev,wandb.project=Tearsheet-Pi-Agent" \
-e OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="true" \
526489132647.dkr.ecr.us-west-2.amazonaws.com/tearsheet-agent-service-poc:latest
4. Running the Container in One-Shot CLI Mode
Override the container command with tearsheet-research (or pi --list-models):
# Verify configured providers & models inside the container
docker run --rm \
-e PERPLEXITY_API_KEY="$PERPLEXITY_API_KEY" \
-e HF_TOKEN="$HF_TOKEN" \
526489132647.dkr.ecr.us-west-2.amazonaws.com/tearsheet-agent-service-poc:latest \
pi --list-models
# Run a tearsheet research job via CLI inside the container
docker run --rm \
-e PERPLEXITY_API_KEY="$PERPLEXITY_API_KEY" \
-e WANDB_API_KEY="$WANDB_API_KEY" \
-e HF_TOKEN="${HF_TOKEN:-}" \
526489132647.dkr.ecr.us-west-2.amazonaws.com/tearsheet-agent-service-poc:latest \
tearsheet-research --company "Ayar Labs"
5. Container Environment Variables Reference
| Variable | Default | Description |
|---|---|---|
PERPLEXITY_API_KEY |
(required) | API key used for Perplexity /search (websearch tool) and perplexity-agent provider. |
WANDB_API_KEY |
(optional) | W&B API key for exporting OTel GenAI trajectories to Weave. |
TEARSHEET_SERVICE_API_KEY |
dev-local-api-key |
Expected X-API-Key header for all FastAPI endpoints (/runs). |
TEARSHEET_AGENT_PROVIDER |
perplexity-agent |
Default PI provider (perplexity-agent or hf-vllm). |
TEARSHEET_AGENT_MODEL_ID |
xai/grok-4.7 |
Default model ID rendered into models.json at container startup. |
HF_TOKEN |
(optional) | Hugging Face token for authenticating against hf-vllm endpoints. |
HF_INFERENCE_ENDPOINT_URL |
https://6ad3b6e6d2d0ab8296e5999d.endpoints.huggingface.cloud/v1 |
OpenAI-compatible /v1 base URL for hf-vllm (HF Inference Endpoint or any vLLM server). |
TEARSHEET_HF_MODEL_ID |
LiquidAI/LFM2.5-8B-A1B |
Additional model ID dynamically registered under hf-vllm in models.json. |
TEARSHEET_WANDB_ENTITY |
forge-ai-dev |
Target W&B entity for Weave traces. |
TEARSHEET_WANDB_PROJECT |
Tearsheet-Pi-Agent |
Target W&B Weave project for agent trajectories. |
Local Usage (CLI & API)
Install Dependencies
uv sync
Mode A: Terminal CLI (tearsheet-research)
Only --company is required. Runs PI with live turn/tool/reasoning telemetry, prints the
10-section section_parser audit table, and exports the trajectory to forge-ai-dev/Tearsheet-Pi-Agent:
# 1. Frontier baseline (Perplexity Grok 4.7 with reasoning token tracking)
uv run tearsheet-research --company "Ayar Labs"
# 2. Quick single-section demo
uv run tearsheet-research \
--company "FloQast" \
--part "ONLY the single section ## Business Overview"
# 3. Open-weight model on HF Inference Endpoint / vLLM (LiquidAI/LFM2.5-8B-A1B FP8)
uv run tearsheet-research \
--provider hf-vllm \
--model "LiquidAI/LFM2.5-8B-A1B" \
--hf-endpoint-url "https://6ad3b6e6d2d0ab8296e5999d.endpoints.huggingface.cloud/v1" \
--company "Ayar Labs"
Mode B: Local FastAPI Server (runs-api)
uv run uvicorn tearsheet_agent_service.api.app:create_default_app --factory --host 127.0.0.1 --port 8090
Trigger a run (only "company" is required; provider, model, part, website, start_year, issuer_slug are optional):
# Start a run
RUN_ID=$(curl -s -X POST http://127.0.0.1:8090/runs \
-H "X-API-Key: dev-local-api-key" \
-H "Content-Type: application/json" \
-d '{"company": "Ayar Labs", "provider": "perplexity-agent", "model": "xai/grok-4.7"}' \
| jq -r .run_id) && echo "RUN_ID=$RUN_ID"
# Stream live SSE events
curl -N -H "X-API-Key: dev-local-api-key" "http://127.0.0.1:8090/runs/$RUN_ID/events"
# Fetch status, resolved citations, reasoning tokens, and W&B Weave trace URL
curl -s -H "X-API-Key: dev-local-api-key" "http://127.0.0.1:8090/runs/$RUN_ID" \
| jq '{status, cost, trace_url, sources_count: (.result.sources|length)}'
Managing the Hugging Face vLLM Endpoint (LiquidAI/LFM2.5-8B-A1B)
The endpoint lfm2-5-8b-a1b-xcj runs vllm/vllm-openai:v0.29.0 on 1Γ NVIDIA L40S (48 GB VRAM) with:
-tp 1 --reasoning-parser qwen3 --enable-auto-tool-choice --tool-call-parser lfm2 --quantization fp8 --kv-cache-dtype fp8 --max-model-len 128000
# Resume when testing
hf endpoints resume lfm2-5-8b-a1b-xcj
# Check status & URL
hf endpoints describe lfm2-5-8b-a1b-xcj
# Pause when done ($0/hr)
hf endpoints pause lfm2-5-8b-a1b-xcj
# Or deploy a fresh endpoint from scratch
./scripts/deploy_hf_lfm25_endpoint.sh
Stage 2 RL / GRPO Training Suite (tearsheet_agent_service.rl & spaces/DeepResearch-RL-Trainer/)
1. 33-Failure-Mode (EA03-*) Rubric & 555-Claim Census Meta-Evaluator
- Exact 33-Mode Bijection (
rl/rubric.py): Partitions the 33EA03-*failure modes fromea03-taxonomy-v1/taxonomy.jsoninto two disjoint tiers:- 15 Tier-A Deterministic Python Verifiers (
TIER_A_FAILURE_MODES,<5ms/rollouton CPU):EA03-SUBJECT,EA03-PROFILE,EA03-TOPIC,EA03-LIST,EA03-MARKET,EA03-VALUE,EA03-DERIVE,EA03-TABLE,EA03-MISS,EA03-MIX,EA03-CITE,EA03-ACCESS,EA03-ASSOC,EA03-FETCH, andEA03-CROSS. - 18 Tier-B Closed-World NLI Judge Specs (
TIER_B_FAILURE_MODES):EA03-REL,EA03-QTY,EA03-NUM,EA03-SCOPE,EA03-ROUND,EA03-INSTRUMENT,EA03-EVENT,EA03-INCUMBENT,EA03-ADJROLE,EA03-HOMONYM,EA03-BRIDGE,EA03-RANK,EA03-DIRECTION,EA03-FLOW,EA03-VOICE,EA03-PRODUCT,EA03-PRODUCT_TYPE, andEA03-DELTA.
- 15 Tier-A Deterministic Python Verifiers (
- Offline 555-Claim Census Meta-Evaluation (
rl/census_meta_eval.py): Replays all 555 parent claims (146not_supportedinpopulation.jsonl+409supportedcontrols incontrols_index.jsonl,207mode memberships, and10,149evidence rows) to verify per-mode recall and control false-rejection rates:uv run python -m tearsheet_agent_service.rl.census_meta_eval
2. Xiaomi MiMo-V2.6 RL Stabilization Mechanisms & Locked Decisions (D1βD4)
- Multiplicative Anti-Reward-Hacking Gate (
MiMo-V2.6Eq. 2): Composite episode reward $R_i = R^{\text{gate}}_i \cdot S^{\text{sol}}_i \cdot S^{\text{beh}}_i$ caps rollouts with zerowebsearchcalls or prompt-template contamination (SampleCorp,Jane Doe,Mina Patel,example.com) at $\le 0.05$, and penalizes malformed```markdown\nfactsfences or premature 6/10-section Part-1 stops below $0.35$. - Dynamic Discrepancy Filtering (
MiMo-V2.6Β§5.3, Decision D1):DynamicDiscrepancySampler(rl/sampler.py) requires $\max_i R^{\text{Tier-A}}_i - \min_i R^{\text{Tier-A}}_i \ge 0.05$ across a rollout group ($G=8$) before invokingJudgeClientor emitting the group to the GPU 1 Trainerβsaving 100% of external Judge API calls onall-failandall-passgroups. - Closed-World NLI Judge & Groupwise Advantage Redistribution (
MiMo-V2.6Eq. 3, Decision D2):JudgeClientdefaults toprovider="perplexity",model="xai/grok-4.7"with secondary fallbackprovider="mistral",model="mistral-large-latest"(and configurabledeepseek,openai,glmsupport), followed by zero-mean, unit-variancecompute_gar_advantages()andapply_group_relative_length_penalty()(MiMo-V2.6Eq. 4). - Full-Tearsheet Curriculum Only (Decision D3): All environment prompts (
rl/env.py), W&B Weave trajectory harvesters (rl/weave_dataset.py), SFT warm-up configs (rl/train_sft_warmup.py), and GRPO configs (rl/train_grpo.py) enforcecurriculum_mode = "full_tearsheet"(all 10 sections fromrequired_facts.yaml). - MoE Router Freezing (
MiMo-V2.6Β§5.4 Fig. 11) & Prompt-Mean Loss (MiMo-V2.6Β§5.2):freeze_moe_router(model)freezes all MoE routing gate parameters (*.mlp.gate.*,*.block_sparse_moe.gate.*,*.moe.gate.*,*.router.*,*.expert_gate.*) onLiquidAI/LFM2.5-8B-A1B(Lfm2MoeForCausalLM) while preserving SwiGLUgate_proj/up_proj/down_proj/w1..w3and attention projections as trainable under LoRA, andcompute_prompt_mean_grpo_loss()normalizes per-rollout token losses by each rollout's active assistant length before group averaging. - Teacher-Prefix On-Policy Distillation (
MiMo-V2.6Β§5.6):weave_dataset.pyharvests 10/10-completexai/grok-4.7teacher traces from W&B Weave (forge-ai-dev/Tearsheet-Pi-Agent), extractsreference_factsandreplay_snapshots, and slices intermediate tool-observation prefix states viabuild_teacher_prefix_opd_examples().
3. Split-GPU A100x2 (160GB VRAM) Hugging Face Space (spaces/DeepResearch-RL-Trainer/)
The spaces/DeepResearch-RL-Trainer/ bundle packages the complete Split-GPU training stack (GPU 0 co-located vLLM rollout server + GPU 1 Stage 1 SFT Warm-Up & Stage 2 GRPO Trainer) while keeping the standalone HF Inference Endpoint lfm2-5-8b-a1b-xcj paused at $0/hr for live boss demos (Decision D4):
# Validate shell syntax and run the offline Split-GPU dry-run check
bash -n spaces/DeepResearch-RL-Trainer/start_a100x2_grpo.sh
./spaces/DeepResearch-RL-Trainer/start_a100x2_grpo.sh --dry-run
# Launch full Stage 1 (100-step SFT warm-up) + Stage 2 (GRPO) on an A100x2 Space
./spaces/DeepResearch-RL-Trainer/start_a100x2_grpo.sh
Running Tests & Linter
uv run pytest tests/ -q # Full unit + RL + census meta-eval test suite
uv run ruff check . # Ruff lint check