Skip to content

feat(samples): add Blob report downloads to Deep Agents sample - #1107

Draft
JiahuiGu (Jiahui-Gu) wants to merge 10 commits into
mainfrom
port-azure-sample-1207
Draft

JiahuiGu (Jiahui-Gu) wants to merge 10 commits into
mainfrom
port-azure-sample-1207

Conversation

@Jiahui-Gu

@Jiahui-Gu JiahuiGu (Jiahui-Gu) commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add private Azure Blob report publication to the existing Foundry Deep Agents sample. This is now a focused extension, not a wholesale SDK sample port.

The existing agent still researches and writes /final_report.md. The added publish_report tool exports the saved file, returns its SHA256 and a one-hour read-only HTTPS download URL, and publishes a new immutable snapshot after a requested revision. The tool is adapted from langchain-azure #1207, where Blob export was an explicit review requirement.

Blob-only scope audit

Compared with original sample baseline 6a7a868919b1c4458c0cda6cc06246cbce51ab5b:

| Area | Necessary change / preserved behavior |

| --- | --- |

| report_export.py | Reuse the saved-file publication tool; validate a simple Markdown name, read conversation state, create a private snapshot, sign a read-only HTTPS URL, and handle expected Azure errors without inventing a link or modifying the report. |

| agent.py | Add one optional publication-tool argument and attach it only to the coordinator. Existing three-argument callers remain valid; original researcher tools, planning middleware, delegation limits, model, and graph assembly are preserved. |

| main.py | Construct the added Blob credential/tool and keep that new credential alive until the host exits. Preserve the existing build_chat_model, checkpoint, dotenv, port, and server setup. Default message-content capture off because the new tool output contains bearer SAS URLs. |

| Research prompts | Keep the original instructions and exported constant names. Add only a publication step and guidance for re-exporting edits, failures, and keeping links out of saved reports. Researcher/delegation instructions remain identical. |

| Configuration/docs | Add report account/container settings, explicit developer/agent Blob RBAC setup, download/republish usage, privacy and acceptance instructions, and a catalog mention. Retain the original README flow and hosting layout. |

| Dependencies | Declare the already-locked azure-storage-blob==12.30.0 directly. uv.lock changes by two added lines only; every existing third-party package entry/version/source/hash remains unchanged. |

| Tests | Add focused publication, compatibility/wiring, new-credential lifetime, and native JSON/SSE success/failure regressions. Extend the existing cloud smoke contract to publish and republish the existing report; no shared CI/schema extension. Exclude the new tests from deployment packaging. |

Restored unchanged: research_agent/__init__.py including its package exports, research_agent/tools.py, utils.py, and the collection-level hosted-agent README. Removed the unrelated model migration, Toolbox filtering/think_tool, research-prompt rewrite, standalone demo client/client tests, broad lifecycle refactor, telemetry setup expansion, and dependency upgrades.

The complete PR now has 18 changed files, 942 additions and 17 deletions, including tests and the separately requested ownership entries. The old 3,291-line lock churn is reduced to two direct-dependency registration lines.

Validation — 18549eab9d308f5968fead7a917b97dbdbd04704

| Check | Result |

| --- | --- |

| Focused Blob suite in an isolated environment installed from the frozen baseline export with artifact hashes enforced | 11 passed |

| Existing repository script suite | 114 passed in WSL/Linux |

| Existing hosted-agent harness suite | 70 passed in WSL/Linux |

| Original dependency versions used for the focused suite | SDK 1.2.9, Deep Agents 0.7.8, LangChain 1.3.16, Blob SDK 12.30.0 |

| All 142 third-party lock entries compared with baseline | Unchanged |

| Restored package initializer, model helper, Toolbox loader, and original researcher/delegation instructions | Unchanged |

| Ruff 0.9.10 / Black 23.12.1 | Passed, ten Python modules |

| Dependency policy including --resolve, frozen export, offline lock check | Passed |

| Cloud contract schema and hosted Responses plan | Passed, two turns / eight assertions; owner remains aochengwang |

| Diff whitespace and scope guard | Passed |

The focused tests use the published baseline SDK and real native graph/host; external model, Storage, and project boundaries are simulated. No dependency upgrade is required for these Blob regressions. A Starlette deprecation warning about the existing HTTP client is unrelated and deliberately not fixed.

Ownership

Preserve the separately requested @Jiahui-Gu co-owner entries for this sample and its fixture in .github/CODEOWNERS, alongside @microsoft-foundry/hosted-agents. Keep the original CI primary responsible alias sample.owner: aochengwang. No repository permissions or other sample ownership changes.

Cloud acceptance boundary

This head is not yet cloud-accepted. The actual deployed agent instance needs explicit container data access and account delegation rights before invoking the Blob workflow; developer/project permissions do not transfer to that identity.

The existing cloud runner checks delegated research, publication, editing, and returned URLs, not downloaded bytes. For full acceptance, invoke the deployed agent, download the original and revised snapshots, compare their SHA256/content, and re-download the earlier URL to confirm it is unchanged. The README documents this path without introducing another client framework.

No new live model/search/Blob deployment or Toolkit/Inspector UI acceptance is claimed. Keep this PR Draft until the required cloud validation is complete; missing Blob access must not be bypassed with account keys.

Live user-path acceptance — 2026-10-28

Result: not cloud-accepted; keep Draft. Do not treat HTTP 200, completed model responses, or a successful summary job as successful Blob publication.

Actual execution Observed result
Clean exported checkout at 18549eab using the frozen-baseline environment All 11 focused tests passed. A fresh uv sync --frozen was attempted twice but blocked by PyPI TLS HandshakeFailure; this is an installation/environment blocker, not a dependency-upgrade justification.
Local real Azure model + Toolbox + Foundry checkpoint + native Responses ASGI host Four real-model turns completed: delegated research and saved report, SSE edit/republish, exact report read-back retaining citations and Recovery Limitations, and a fresh conversation whose ls returned No files found. No model/search/Blob/checkpoint mocks. Uses the existing developer project and its gpt-4.1-mini deployment; in-process ASGI, not a TCP/F5/Inspector acceptance claim.
Local real Blob delegation request HTTP 403 AuthorizationPermissionMismatch for the developer identity. Publication returned no link, and the saved report remained editable and readable.
Targeted cloud run 243239929, exact source 18549eab9d308f5968fead7a917b97dbdbd04704 Both container and code remote build deployed and completed both real-model turns. Both reported publication failure, not a download link.
Code remote build, agent version 177 Private raw responses both have terminal completed. Tool outputs prove task, report write/read, edit_file, and publish_report; the revised report was read back with citations and the new section. 6/8 assertions passed; both download-link assertions failed. The publication tool reports HttpResponseError; cloud response details do not establish its exact HTTP status.
Container, agent version 174 Both real response turns completed with explicit publication failures. A later Azure DevOps certificate-hostname mismatch prevented status/assertion collection, artifact upload, and session/toolbox cleanup. This infrastructure failure is separate from the observed Blob failure.
Actual download/digest/immutability check Not passed: no successful publication URL exists to download. The external verifier correctly reports failure; no fabricated link or account-key fallback.

Necessary test-only repair: following the README test command exposed new workflow tests writing response state under the developer home. Commit c509ef2df8998b4801633d1eba8c748f685d7320 scopes those tests to a temporary AGENTSERVER_STATE_ROOT. All 11 tests pass again, with zero new/modified home-state files; Ruff 0.9.10 and Black 23.12.1 pass. Only the added test file changes after the cloud-tested head; application code, manifests, dependencies, and deployment inputs are unchanged. Identified test-owned home files were removed without deleting unrelated state.

Remaining prerequisites before acceptance: the Storage administrator must verify/grant container-scoped Storage Blob Data Contributor and account-scoped Storage Blob Delegator to the actual local developer and each deployed agent instance principal (code and container separately), and check the private container exists. The local user cannot assign roles and has no access to the CI project. Cloud HttpResponseError still needs the operator to check Storage/RBAC details rather than assume the developer's grants transfer. After correcting that setup, rerun both turns and download/compare original and revised report bytes, then re-download the old URL.

Cleanup: the code job deleted its own session and temporary Toolbox. The container job's cleanup was blocked by the Azure DevOps TLS error; a narrowly scoped local retry also returned project RBAC 403. The CI operator must delete only session ado-ci-243239929-1-python-1 for ci-langgraph-deep-agents-container-f26da203 and run-owned Toolbox ci-e2e-tb-deep-agents-tools-d543bf333532. Do not revoke shared identities or remove shared infrastructure. No successful Blob export is evidenced. Local ASGI lifespan/credentials are closed; private transcripts and diagnostic evidence remain outside the repository.

Keep verification cleanup scoped to observed report exports so concurrent builds sharing stable agent identities retain Storage access. Preserve explicit deployment retirement cleanup and expose only safe Azure CLI error codes for authorization diagnostics.
Document complementary SDK and Foundry sample scope, explain the native SDK/framework integration and adaptation points, and pin external Storage lookup, role management, and retirement cleanup to its configured subscription. Add cross-subscription and receipt-scope regressions.
@Jiahui-Gu JiahuiGu (Jiahui-Gu) changed the title feat(samples): port Deep Research report workflow from langchain-azure feat(samples): demonstrate Deep Research SDK integration on Foundry Oct 27, 2026
@Jiahui-Gu JiahuiGu (Jiahui-Gu) changed the title feat(samples): demonstrate Deep Research SDK integration on Foundry feat(samples): add Blob report downloads to Deep Agents sample Oct 28, 2026

This branch was successfully deployed

1 active deployment
L4-validation — c509ef2d Deployed Oct 28, 2026 by Jiahui-Gu via trusted #754
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.

1 participant