Skip to content

fix(deep-research): require writer-committed final reports - #375

Merged
rapids-bot[bot] merged 3 commits into
NVIDIA-AI-Blueprints:release/2.2from
KyleZheng1284:fix/writer-final-report-commit
Jul 22, 2026
Merged

rapids-bot[bot] merged 3 commits into
NVIDIA-AI-Blueprints:release/2.2from
KyleZheng1284:fix/writer-final-report-commit

Conversation

@KyleZheng1284

@KyleZheng1284 KyleZheng1284 commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Deep-research currently accepts any non-empty /shared/output.md as the final report, including stale planner/orchestrator content from the same state. This prerequisite establishes a small writer-owned commit boundary before the broader convergence/artifact work in #373.

  • Create one run-local FinalReportCommitTracker per DeepResearcherAgent.run().
  • Deny non-writer write_file/edit_file mutations of /shared/output.md and its route-local /output.md state alias with final_report_writer_only.
  • Upsert writer write_file calls through the existing backend, refresh the exact UTF-8 SHA-256 after successful edits, and sanitize backend failures as writer_output_commit_failed.
  • Require a successful writer mutation, non-empty current content, and an exact digest match before writer completion or final extraction.
  • Preserve the existing one-turn correction, then fail closed with writer_output_not_committed.
  • Remove production inline-orchestrator report salvage.
  • Document that the proof is run-local and byte-exact; it is not persistent across restart and does not claim cross-provider filesystem atomicity.

This changes no API fields, configuration schema, database schema, deployment behavior, or sandbox-provider implementation.

After this prerequisite merges, #373 can rebase onto release/2.2 and use its validated ResearchNotes fallback when no committed writer report exists.

DCO sign-off for the squash commit

Signed-off-by: Kyle Zheng kyzheng@nvidia.com

Validation

  • uv run ruff check . — passed
  • uv run ruff format --check . — passed (372 files)
  • Focused deep-research/job-runner regressions — 265 passed
  • uv run pytest — 1,836 passed, 13 skipped
  • pre-commit run --all-files — all 13 hooks passed, including secrets, lockfiles, links, and notebook output
  • cd docs && make html — passed
  • Live Modal smoke — deep_researcher reached success with a non-empty 12,351-byte report
  • Live OpenShell 0.0.80 local-demo smoke — strict readiness passed; job reached success with a non-empty 7,360-byte report; attestation and cleanup events were recorded; no owned sandbox remained
  • I added or updated tests for behavior changes.
  • I updated documentation for contributor-facing architecture behavior.
  • I confirmed this PR does not include secrets, credentials, local configs, generated policy files, or internal-only data.
  • I certify this contribution under the Developer Certificate of Origin (DCO) and signed the commit with git commit -s.
  • I replaced the DCO sign-off placeholder with my GitHub commit identity and kept the required angle brackets.

Where should reviewers start?

  1. FinalReportCommitTracker, FinalReportOwnershipGuardMiddleware, and FinalReportCommitMiddleware in custom_middleware.py.
  2. Per-run tracker construction/extraction in agent.py and role-specific wiring in factory.py.
  3. The routed StateBackend/CompositeBackend stale-planner overwrite regression in test_custom_middleware.py.

Related Issues

Summary by CodeRabbit

  • Bug Fixes
    • Final research reports are now accepted only after the writer commits /shared/output.md (or the supported backend alias) during the current run.
    • Commit verification is digest-based, rejecting stale/modified/missing/whitespace-only output and detecting any post-write tampering.
    • Only the designated writer can create/update the final report artifact; completion is blocked until the verified commit occurs.
    • Removed inline fallback/salvage behavior—if the commit proof isn’t present, runs fail with writer_output_not_committed.
  • Documentation
    • Updated deep-research architecture docs to describe the stricter writer/output commit contract, ownership guardrails, and failure-closed handoffs.
  • Tests
    • Expanded coverage for digest-verified commit tracking, writer-only ownership enforcement, and updated failure reason/validation scenarios.

@copy-pr-bot

copy-pr-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: d949d277-8c26-43be-ae42-ec2b8a508a40

📥 Commits

Reviewing files that changed from the base of the PR and between 221bd07 and 385d34b.

📒 Files selected for processing (1)
  • docs/source/architecture/agents/deep-researcher.md
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (2)
docs/source/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Update the docs under docs/source/ when behavior, configuration, or workflows change

Files:

  • docs/source/architecture/agents/deep-researcher.md
{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}: Review documentation for command accuracy, branch-name consistency, current CI and copy-pr-bot behavior, public
vs internal boundary clarity, stale examples, and links that no longer match the repository layout.

Files:

  • docs/source/architecture/agents/deep-researcher.md
🔇 Additional comments (1)
docs/source/architecture/agents/deep-researcher.md (1)

43-46: LGTM!

Also applies to: 91-109, 157-161, 298-309


Walkthrough

Deep research now restricts final-report mutations to the writer, records backend-committed output with a run-local SHA-256 digest, validates that digest before completion, removes inline report salvage, and rejects missing or stale output with writer_output_not_committed.

Changes

Final report commitment

Layer / File(s) Summary
Digest tracking and middleware enforcement
src/aiq_agent/agents/deep_researcher/custom_middleware.py, tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
Writer report writes and edits are persisted, verified, and recorded by digest; non-writer mutations, stale output, tampering, failed edits, and invalid content are rejected.
Graph context and middleware wiring
src/aiq_agent/agents/deep_researcher/factory.py, tests/aiq_agent/agents/deep_researcher/test_factory.py, tests/aiq_agent/jobs/test_runner.py
A shared FinalReportCommitTracker is passed through graph construction; ownership guards cover non-writer roles, while commit and required-output middleware are attached to the writer.
Run-local report extraction
src/aiq_agent/agents/deep_researcher/agent.py, tests/aiq_agent/agents/deep_researcher/test_agent.py
Final Markdown is extracted only from digest-matching writer output; inline salvage and stale-file acceptance are removed, with failures raising RuntimeError("writer_output_not_committed").
Architecture contract documentation
docs/source/architecture/agents/deep-researcher.md
The documented flow and middleware boundaries describe byte-exact run-local commit verification and closed failure behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant DeepResearcherAgent
  participant OrchestratorGraph
  participant WriterSubagent
  participant Backend
  participant FinalReportCommitTracker
  DeepResearcherAgent->>FinalReportCommitTracker: create tracker for current run
  DeepResearcherAgent->>OrchestratorGraph: build graph with tracker
  OrchestratorGraph->>WriterSubagent: request final report
  WriterSubagent->>Backend: write or edit final report
  Backend-->>WriterSubagent: mutation result and report bytes
  WriterSubagent->>FinalReportCommitTracker: record committed digest
  OrchestratorGraph->>FinalReportCommitTracker: validate backend report digest
  FinalReportCommitTracker-->>DeepResearcherAgent: committed Markdown or failure
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches Conventional Commits, stays under 72 characters, and accurately summarizes the main change.
Description check ✅ Passed The description includes all required template sections with concrete implementation, DCO, validation, reviewer guidance, and related issue context.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@KyleZheng1284
KyleZheng1284 marked this pull request as ready for review July 21, 2026 22:46
@KyleZheng1284
KyleZheng1284 requested a review from a team July 21, 2026 22:46
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
@AjayThorve
AjayThorve force-pushed the fix/writer-final-report-commit branch from 690de2f to 221bd07 Compare July 21, 2026 22:47
@copy-pr-bot

copy-pr-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@AjayThorve AjayThorve added this to the v2.2 milestone Jul 21, 2026
@AjayThorve

Copy link
Copy Markdown
Member

/ok to test 221bd07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with 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.

Inline comments:
In `@docs/source/architecture/agents/deep-researcher.md`:
- Around line 43-46: Update the flow, handoff, and middleware descriptions in
this document to mention both canonical /shared/output.md and the route-local
/output.md alias wherever writer output paths, digest validation, or ownership
guards are described. Explicitly identify /output.md as route-local while
preserving the existing public-versus-internal path distinction.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 07580737-c0ff-484d-a599-470f2befcad0

📥 Commits

Reviewing files that changed from the base of the PR and between e9025bb and 690de2f.

📒 Files selected for processing (8)
  • docs/source/architecture/agents/deep-researcher.md
  • src/aiq_agent/agents/deep_researcher/agent.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
  • src/aiq_agent/agents/deep_researcher/factory.py
  • tests/aiq_agent/agents/deep_researcher/test_agent.py
  • tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_factory.py
  • tests/aiq_agent/jobs/test_runner.py
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Lint and Hooks
  • GitHub Check: Pytest and Coverage
🧰 Additional context used
📓 Path-based instructions (6)
**/*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run ruff check and ruff format validation for Python code changes

**/*.py: Python code must be linted and formatted with Ruff using line length 120, target Python 3.11, rule sets E,F,W,I,PL,UP, and isort force-single-line configuration
Never commit secrets, tokens, or environment-specific hostnames; use environment variables and SecretStr instead, resolving API keys at runtime
Never print or log secret values, including in tool output or error messages
Missing-secret paths must degrade gracefully (stub/skip), not crash or leak
Do not hand-reformat unrelated code when making changes; match the existing import and formatting style

Files:

  • tests/aiq_agent/jobs/test_runner.py
  • tests/aiq_agent/agents/deep_researcher/test_factory.py
  • src/aiq_agent/agents/deep_researcher/factory.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
  • src/aiq_agent/agents/deep_researcher/agent.py
  • tests/aiq_agent/agents/deep_researcher/test_agent.py
**/*test*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run pytest for all behavior changes in Python code

Files:

  • tests/aiq_agent/jobs/test_runner.py
  • tests/aiq_agent/agents/deep_researcher/test_factory.py
  • tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_agent.py
docs/source/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Update the docs under docs/source/ when behavior, configuration, or workflows change

Files:

  • docs/source/architecture/agents/deep-researcher.md
{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}: Review documentation for command accuracy, branch-name consistency, current CI and copy-pr-bot behavior, public
vs internal boundary clarity, stale examples, and links that no longer match the repository layout.

Files:

  • docs/source/architecture/agents/deep-researcher.md
src/aiq_agent/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/aiq_agent/**/*.py: Respect authenticated data sources by honoring requires_auth, per-user token pass-through, and backend token validators; apply owner guardrails before loading protected report or artifact context into an agent
Do not weaken or bypass AuthMiddleware, validators, or auth gating without a prior design discussion

Files:

  • src/aiq_agent/agents/deep_researcher/factory.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
  • src/aiq_agent/agents/deep_researcher/agent.py
src/aiq_agent/agents/**/*

⚙️ CodeRabbit configuration file

src/aiq_agent/agents/**/*: Review agent changes for research workflow correctness, graph state transitions, prompt/tool contracts,
HITL behavior, and failure handling. Flag changes that weaken source attribution, report generation,
async cancellation, checkpointing, or data-source selection without focused tests and docs.

Files:

  • src/aiq_agent/agents/deep_researcher/factory.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
  • src/aiq_agent/agents/deep_researcher/agent.py
🧠 Learnings (1)
📚 Learning: 2026-07-06T23:55:42.908Z
Learnt from: cdgamarose-nv
Repo: NVIDIA-AI-Blueprints/aiq PR: 311
File: src/aiq_agent/agents/deep_researcher/prompts/orchestrator.j2:74-81
Timestamp: 2026-07-06T23:55:42.908Z
Learning: In agent test files (e.g., tests/aiq_agent/agents/*/test_agent.py), avoid brittle assertions that match exact substrings from prompt template files (such as *.j2 prompt wording). Prompt wording can change frequently, so instead assert structural/behavioral properties (e.g., that the prompt builder is called, that required sections/fields are present via stable markers, that the model output/agent behavior conforms to an expected schema, or that key actions are taken) rather than matching literal prompt text.

Applied to files:

  • tests/aiq_agent/agents/deep_researcher/test_agent.py
🔇 Additional comments (8)
src/aiq_agent/agents/deep_researcher/custom_middleware.py (2)

98-138: LGTM!

Also applies to: 286-403, 404-479


60-65: 🔒 Security & Privacy

Normalize repeated leading slashes before path matching. //shared/output.md stays double-slash here, so it misses FINAL_REPORT_STATE_PATHS and the ownership/commit hooks don't see that form.

tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py (1)

284-462: LGTM!

Also applies to: 465-639

src/aiq_agent/agents/deep_researcher/factory.py (1)

48-50: LGTM!

Also applies to: 139-139, 435-492, 508-508, 540-540, 552-596

tests/aiq_agent/agents/deep_researcher/test_factory.py (1)

28-30: LGTM!

Also applies to: 115-133, 255-276, 318-373

tests/aiq_agent/jobs/test_runner.py (1)

73-73: LGTM!

Also applies to: 2344-2344, 2403-2403

src/aiq_agent/agents/deep_researcher/agent.py (1)

38-38: LGTM!

Also applies to: 177-215, 256-277

tests/aiq_agent/agents/deep_researcher/test_agent.py (1)

35-73: LGTM!

Also applies to: 424-424, 494-494, 563-563, 1121-1324, 1363-1471, 1499-1530, 1565-1729

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/source/architecture/agents/deep-researcher.md (1)

298-303: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Stale docs: _salvage_inline_report() was removed in this PR.

This Phase 4 paragraph still presents inline salvage as a live "defensive compatibility path" (≥400 chars + heading), but this PR deletes _salvage_inline_report() and makes missing/stale/modified writer output fail closed with writer_output_not_committed. This directly contradicts the new contract documented at lines 100-103. Remove the salvage description here.

📝 Proposed doc fix
-This is the normative synthesis contract. As a defensive compatibility path,
-`_salvage_inline_report()` accepts the orchestrator's final message when the
-output file is missing, but only if the message is substantive Markdown: at
-least 400 characters with a Markdown heading and not merely the writer
-completion marker. Otherwise, missing writer output remains an error.
+This is the synthesis contract. There is no inline-message salvage path: the
+runtime accepts only writer output whose exact UTF-8 bytes match the run-local
+writer digest. Missing, stale, or modified output fails closed with
+`writer_output_not_committed`.
🤖 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 `@docs/source/architecture/agents/deep-researcher.md` around lines 298 - 303,
Remove the paragraph describing `_salvage_inline_report()` and inline Markdown
fallback from the Phase 4 synthesis contract. Keep the documentation aligned
with the current fail-closed behavior, where missing, stale, or modified writer
output produces `writer_output_not_committed`, and preserve the surrounding
normative synthesis content.

Source: Path instructions

🤖 Prompt for all review comments with 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.

Outside diff comments:
In `@docs/source/architecture/agents/deep-researcher.md`:
- Around line 298-303: Remove the paragraph describing
`_salvage_inline_report()` and inline Markdown fallback from the Phase 4
synthesis contract. Keep the documentation aligned with the current fail-closed
behavior, where missing, stale, or modified writer output produces
`writer_output_not_committed`, and preserve the surrounding normative synthesis
content.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: bcd28d19-10bb-44d6-a804-f849725a8f19

📥 Commits

Reviewing files that changed from the base of the PR and between 690de2f and 221bd07.

📒 Files selected for processing (8)
  • docs/source/architecture/agents/deep-researcher.md
  • src/aiq_agent/agents/deep_researcher/agent.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
  • src/aiq_agent/agents/deep_researcher/factory.py
  • tests/aiq_agent/agents/deep_researcher/test_agent.py
  • tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_factory.py
  • tests/aiq_agent/jobs/test_runner.py
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: Pytest and Coverage
  • GitHub Check: Script Validation
🧰 Additional context used
📓 Path-based instructions (6)
**/*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run ruff check and ruff format validation for Python code changes

**/*.py: Python code must be linted and formatted with Ruff using line length 120, target Python 3.11, rule sets E,F,W,I,PL,UP, and isort force-single-line configuration
Never commit secrets, tokens, or environment-specific hostnames; use environment variables and SecretStr instead, resolving API keys at runtime
Never print or log secret values, including in tool output or error messages
Missing-secret paths must degrade gracefully (stub/skip), not crash or leak
Do not hand-reformat unrelated code when making changes; match the existing import and formatting style

Files:

  • tests/aiq_agent/jobs/test_runner.py
  • src/aiq_agent/agents/deep_researcher/factory.py
  • tests/aiq_agent/agents/deep_researcher/test_factory.py
  • src/aiq_agent/agents/deep_researcher/agent.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_agent.py
**/*test*.py

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Run pytest for all behavior changes in Python code

Files:

  • tests/aiq_agent/jobs/test_runner.py
  • tests/aiq_agent/agents/deep_researcher/test_factory.py
  • tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py
  • tests/aiq_agent/agents/deep_researcher/test_agent.py
src/aiq_agent/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

src/aiq_agent/**/*.py: Respect authenticated data sources by honoring requires_auth, per-user token pass-through, and backend token validators; apply owner guardrails before loading protected report or artifact context into an agent
Do not weaken or bypass AuthMiddleware, validators, or auth gating without a prior design discussion

Files:

  • src/aiq_agent/agents/deep_researcher/factory.py
  • src/aiq_agent/agents/deep_researcher/agent.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
src/aiq_agent/agents/**/*

⚙️ CodeRabbit configuration file

src/aiq_agent/agents/**/*: Review agent changes for research workflow correctness, graph state transitions, prompt/tool contracts,
HITL behavior, and failure handling. Flag changes that weaken source attribution, report generation,
async cancellation, checkpointing, or data-source selection without focused tests and docs.

Files:

  • src/aiq_agent/agents/deep_researcher/factory.py
  • src/aiq_agent/agents/deep_researcher/agent.py
  • src/aiq_agent/agents/deep_researcher/custom_middleware.py
docs/source/**/*

📄 CodeRabbit inference engine (AGENTS.md)

Update the docs under docs/source/ when behavior, configuration, or workflows change

Files:

  • docs/source/architecture/agents/deep-researcher.md
{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,CONTRIBUTING.md,SECURITY.md,CODE-OF-CONDUCT.md}: Review documentation for command accuracy, branch-name consistency, current CI and copy-pr-bot behavior, public
vs internal boundary clarity, stale examples, and links that no longer match the repository layout.

Files:

  • docs/source/architecture/agents/deep-researcher.md
🧠 Learnings (1)
📚 Learning: 2026-07-06T23:55:42.908Z
Learnt from: cdgamarose-nv
Repo: NVIDIA-AI-Blueprints/aiq PR: 311
File: src/aiq_agent/agents/deep_researcher/prompts/orchestrator.j2:74-81
Timestamp: 2026-07-06T23:55:42.908Z
Learning: In agent test files (e.g., tests/aiq_agent/agents/*/test_agent.py), avoid brittle assertions that match exact substrings from prompt template files (such as *.j2 prompt wording). Prompt wording can change frequently, so instead assert structural/behavioral properties (e.g., that the prompt builder is called, that required sections/fields are present via stable markers, that the model output/agent behavior conforms to an expected schema, or that key actions are taken) rather than matching literal prompt text.

Applied to files:

  • tests/aiq_agent/agents/deep_researcher/test_agent.py
🔇 Additional comments (19)
docs/source/architecture/agents/deep-researcher.md (1)

43-46: Document the route-local /output.md alias. The digest gate, ownership guard, and handoff descriptions at lines 43-46, 91-109, and 157-161 still name only /shared/output.md, though the implementation also accepts the route-local /output.md alias.

Also applies to: 91-109, 157-161

Source: Path instructions

src/aiq_agent/agents/deep_researcher/custom_middleware.py (3)

60-136: LGTM!


286-401: LGTM!


415-465: LGTM!

tests/aiq_agent/agents/deep_researcher/test_custom_middleware.py (2)

284-462: LGTM!


477-639: LGTM!

src/aiq_agent/agents/deep_researcher/factory.py (3)

139-139: LGTM!


435-492: LGTM!


508-596: LGTM!

tests/aiq_agent/agents/deep_researcher/test_factory.py (3)

115-133: LGTM!


255-277: LGTM!


353-373: LGTM!

tests/aiq_agent/jobs/test_runner.py (1)

2344-2344: LGTM!

Also applies to: 2403-2403

src/aiq_agent/agents/deep_researcher/agent.py (2)

177-215: LGTM!


256-277: LGTM!

tests/aiq_agent/agents/deep_researcher/test_agent.py (4)

55-73: LGTM!


424-563: LGTM!


1121-1306: LGTM!


1363-1530: LGTM!

Copy link
Copy Markdown
Member

One documentation correction before merge:

docs/source/architecture/agents/deep-researcher.md still describes _salvage_inline_report() as a live compatibility path in Phase 4, but this PR removes that method and changes the contract to fail closed with writer_output_not_committed when no current writer-committed report exists. Please remove the salvage paragraph and state that the runtime accepts only non-empty writer output whose exact UTF-8 bytes match the run-local committed digest.

For the route-local alias, keep /shared/output.md as the sole writer-facing path. If /output.md is documented, describe it once as CompositeBackend's internal route-stripped state key, not as an equivalent writer destination.

Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
@KyleZheng1284

Copy link
Copy Markdown
Contributor Author

/ok to test 385d34b

@tanleach

Copy link
Copy Markdown
Collaborator

/merge

@rapids-bot
rapids-bot Bot merged commit 09cb55d into NVIDIA-AI-Blueprints:release/2.2 Jul 22, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants