feat(deeprag): default to single-shot from-attachments (kill switch: DisableDeepRagFromAttachments) - #1049
Conversation
…re flag When EnableDeepRagFromAttachments is on, the DeepRag internal tool emits a single CreateDeepRag interrupt carrying the attachment ids directly, letting the server create the ephemeral index and start the Deep RAG task in one call. The two-step path (create ephemeral index → wait for ingestion → create Deep RAG) is untouched when the flag is off.
Single durable interrupt returning CreateDeepRag(attachments=[...]); the server does index creation + task start in one call. Removes the WaitEphemeralIndex wait, the ReadyEphemeralIndex helper, and the imports that only served the old path.
9aad97b to
0928d59
Compare
The old two-step DeepRAG flow (ephemeral index → wait → create_deeprag) is gone, so the tests that patched `deeprag_tool.UiPath` and asserted on `create_ephemeral_index_async` were referencing a symbol the module no longer imports — every test decorated with @patch(...deeprag_tool.UiPath) failed with AttributeError at collection time. - Drop the wait-for-ingestion test entirely (that path no longer exists). - Rewrite the ready/dynamic/folder-key tests to patch just the durable interrupt and assert the CreateDeepRag payload it receives (attachments, prompt, citation_mode, index_folder_key from UIPATH_FOLDER_KEY). - Bump `uipath-platform` pin to >=0.2.22 for the new primitive; regenerate uv.lock. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ship the single-shot DeepRAG from-attachments path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the DeepRag internal tool implementation to use the newer single-shot “from attachments” creation flow, and bumps the uipath-platform dependency to a version that provides the required CreateDeepRag.attachments support.
Changes:
- Replace the previous two-step ephemeral-index + wait flow with a single
@durable_interruptemittingCreateDeepRag(attachments=[...], ...). - Update DeepRag internal tool tests to assert the single-interrupt payload (attachments, prompt, citation mode, folder key propagation).
- Bump
uipath-platformdependency pin to0.2.22(and updateuv.lockaccordingly).
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/uipath_langchain/agent/tools/internal_tools/deeprag_tool.py |
Switch DeepRag internal tool to emit a single CreateDeepRag interrupt using attachments (removes ephemeral index path). |
tests/agent/tools/internal_tools/test_deeprag_tool.py |
Update tests to validate the new single-shot interrupt payload and folder key propagation. |
pyproject.toml |
Bump uipath-platform version constraint to >=0.2.22,<0.3.0. |
uv.lock |
Lockfile updates reflecting the uipath-platform bump and resolution metadata changes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Bring back the DeepRagFromAttachments feature flag and the two-step ephemeral-index path so the new single-shot from-attachments flow ships opt-in. When UIPATH_FEATURE_DeepRagFromAttachments is not set (the default), the tool falls back to the pre-existing behaviour: create_ephemeral_index_async → wait for ingestion → create_deeprag. The DEEP_RAG_FROM_ATTACHMENTS_FEATURE_FLAG constant that lived in an earlier draft of uipath-python#1872 never made it into the merged SDK, so the flag name is defined locally here — the FeatureFlags manager resolves any string against UIPATH_FEATURE_<name> env vars. Test coverage restored for the flag-off (default) path; adds one new test asserting the flag-on path emits a single CreateDeepRag interrupt carrying attachments and prompt. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… runs) Previous commit implemented a feature flag (opt-in) rather than a kill switch — the new from-attachments path was gated behind EnableDeepRagFromAttachments=1 and the two-step path was still the default. That's the wrong shape for a kill switch: we're committing to shipping the new path; the flag exists so we can flip back to the old path if something breaks in production. Renamed the flag to DisableDeepRagFromAttachments. Default (unset) runs the new single-shot CreateDeepRag interrupt; setting UIPATH_FEATURE_DisableDeepRagFromAttachments=1 falls back to the old create_ephemeral_index → wait → create_deeprag two-step path. Tests: default-suite tests now exercise the new path; the three old-path tests set the env var to activate the fallback. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
| DEEP_RAG_FROM_ATTACHMENTS_KILL_SWITCH, default=False | ||
| ): | ||
|
|
||
| @durable_interrupt |
There was a problem hiding this comment.
nit: while this code works, durrable_interrupt is not the right primitive here.
it was created specifically for interrupts in subgraphs. for regular tools we can use the plain interrupt.
the PR can be merged as is, we already use durrable_interrupt in sibling tools although is not needed
Address Radu's review nit: durable_interrupt is designed for side-effect-carrying subgraph bodies. The from-attachments path just constructs a CreateDeepRag Pydantic model — no side effect to protect from replay — so plain langgraph.types.interrupt is the right primitive. Old ephemeral-index branch (behind the kill switch) unchanged: that path does have an API call in the body, so keeping the wrapper avoids a duplicate Orchestrator round-trip on resume. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|



What
Makes DeepRag's internal tool default to the single-call
start_deep_rag_from_attachmentsprimitive — one durable interrupt returningCreateDeepRag(attachments=[attachment_id], ...); the server creates the ephemeral index and starts the Deep RAG task in one operation. The previous two-step ephemeral-index flow is retained behind a kill switch so we can flip back in production if something goes wrong.Changes
deeprag_tool.py:@durable_interruptemittingCreateDeepRag(attachments=[...], index_folder_key=UiPathConfig.folder_key).create_ephemeral_index+WaitEphemeralIndex/ReadyEphemeralIndex+create_deeprag(index_id, index_name, is_ephemeral_index=True)two-step flow, unchanged.DisableDeepRagFromAttachments— declared locally asDEEP_RAG_FROM_ATTACHMENTS_KILL_SWITCHbecause the constant that lived in an earlier draft of the SDK PR never made it into the merged SDK.FeatureFlags.is_flag_enabled(..., default=False)resolves it againstUIPATH_FEATURE_DisableDeepRagFromAttachments.test_deeprag_tool.py:CreateDeepRag.attachments,.prompt,.citation_mode,.index_folder_keyfromUIPATH_FOLDER_KEY.UIPATH_FEATURE_DisableDeepRagFromAttachments=1and exercise the two-step path (instant-ready index, wait-for-ingestion, folder-key passthrough).pyproject.toml/uv.lock: bumpuipath-platform>=0.2.20→>=0.2.22for the new primitive; bump package0.16.12→0.16.13.Depends on
start_deep_rag_from_attachmentsprimitive,CreateDeepRag.attachmentsfield, and dispatcher branch this PR relies on.Why
Old path: two durable interrupts, one with a
WaitEphemeralIndexsuspend in between while the server ingested the attachments. New path: one interrupt — the server does index creation + ingestion + task start in one call. The trailing wait for the DeepRag task itself is unchanged.Making the new path the default (rather than opt-in) commits us to the simpler flow; the kill switch is the safety net for a fast rollback without a code change if the server-side path regresses in production.
Rollback
Set
UIPATH_FEATURE_DisableDeepRagFromAttachments=1on the runtime. The tool reverts to the previous two-step behaviour immediately — no redeploy needed.