Skip to content

feat(deepagent): datastores= parity for create_research_workflow#207

Merged
fede-kamel merged 1 commit into
mainfrom
feat/workflow-datastores
May 17, 2026
Merged

feat(deepagent): datastores= parity for create_research_workflow#207
fede-kamel merged 1 commit into
mainfrom
feat/workflow-datastores

Conversation

@fede-kamel
Copy link
Copy Markdown
Contributor

Follow-up to #203 / v0.2.0b11. Closes the only remaining surface gap between create_deepagent and create_research_workflow: the workflow factory now accepts the same datastores= mapping.

Why

create_deepagent(datastores={...}) shipped in v0.2.0b11 with auto-wired search_<name> tools + a per-store routing block prepended to the system prompt. create_research_workflow — the StateGraph variant with the post-hoc grounding loop — exposed only tools=, so users had to hand-wire the retrieval tools via locus.rag.tools.create_rag_tool and write the routing block themselves.

After this change, the two factories are surface-identical for the datastore path:

# Same `datastores=` shape works for both
workflow = create_research_workflow(
    model=...,
    tools=[],
    output_schema=Report,
    datastores={"medical": {"retriever": medical_retriever, "top_k": 6}},
    grounding_threshold=0.65,
)

Implementation

  • factory.py: extracted the auto-wiring logic into a new public wire_datastores(datastores, datastore_top_k) -> (tools, routing_block) helper. create_deepagent now calls it (semantics unchanged from b11 — same tools, same prompt block, same TypeError on bad values).
  • workflow.py: added datastores= + datastore_top_k= kwargs to create_research_workflow; the execute node sees tools + ds_tools and the prepended routing block.
  • docs/concepts/deepagent.md: workflow datastores= example + cross-ref under "When to use each".
  • tests/unit/test_research_workflow_datastores.py: 8 cases covering None/empty input, bare-retriever vs dict form, multi-store routing, TypeError on bad value types, and workflow construction with a configured datastore.

Test plan

  • 8 new unit tests pass locally
  • wire_datastores smoke-tested in isolation
  • create_deepagent semantics unchanged (regression via existing tests + smoke test)
  • create_research_workflow compiles with datastores= configured
  • ruff / mypy / codespell / markdownlint / commitizen all pass

Goes into the next release cut (b12 or 1.0-rc, depending on the call).

Brings the workflow factory to feature parity with create_deepagent:
both now accept datastores={name: {retriever, description, top_k,
threshold}} and produce an identical auto-wired search_<name> tool
surface plus per-store system-prompt routing block.

- factory.py: extract the auto-wiring logic into wire_datastores() so
  both call sites use the same path. create_deepagent now calls into
  it (semantics unchanged from b11).
- workflow.py: add datastores= + datastore_top_k= kwargs to
  create_research_workflow; the execute node sees the merged tools and
  the prepended routing block.
- docs/concepts/deepagent.md: add the workflow datastores= example +
  cross-reference under 'When to use each'.
- tests/unit/test_research_workflow_datastores.py: 8 cases covering
  None/empty, bare-retriever vs dict form, multi-store routing,
  TypeError on bad values, and workflow construction with a
  datastore configured.

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label May 17, 2026
@fede-kamel fede-kamel merged commit 8dffbcf into main May 17, 2026
10 checks passed
@fede-kamel fede-kamel deleted the feat/workflow-datastores branch May 17, 2026 00:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant