Skip to content

[feat] Tool discovery: POST /tools/discover + reserved find_capabilities tool#4884

Merged
mmabrouk merged 4 commits into
big-agentsfrom
docs/tool-discovery-find-capabilities
Jun 28, 2026
Merged

[feat] Tool discovery: POST /tools/discover + reserved find_capabilities tool#4884
mmabrouk merged 4 commits into
big-agentsfrom
docs/tool-discovery-find-capabilities

Conversation

@mmabrouk

@mmabrouk mmabrouk commented Jun 27, 2026

Copy link
Copy Markdown
Member

Context

Building an agent that spans a few SaaS tools (say a Slack bot that searches GitHub, files an issue, and replies in Slack) currently takes about 20 sequential, slug-guessing API calls just to discover the right tools and check their connections. Every step depends on the previous one, and the caller has to stitch three concerns by hand: which action, does a connection exist, and what is its input schema.

This PR collapses that discovery into one call and returns the result in Agenta concepts, so the agent never sees Composio. It adds POST /tools/discover for setup code and a reserved, agent-facing tool tools.agenta.find_capabilities for an agent that is wiring its own tools. Both wrap Composio's COMPOSIO_SEARCH_TOOLS meta-tool, which already does the semantic search and returns, in one call, the matched tools, alternatives, input schemas, an execution plan, pitfalls, and per-user connection state. The load-bearing mapping is that Composio's user_id is the Agenta project_id, so the connection state it returns is the calling project's real state.

Changes

  • POST /tools/discover (requires VIEW_TOOLS): CapabilitiesQuery to ToolsService.discover_capabilities to CapabilitiesResult. An unsupported provider returns 422. Project scope comes from caller auth, not the body.
  • Reserved agent-facing tool tools.agenta.find_capabilities. call_tool routes any tools.agenta.* call_ref to _call_agenta_tool by prefix, so the reserved tool stays out of Composio's 5-segment tools.{provider}.{integration}.{action}.{connection} namespace. v1 handles find_capabilities and 404s any other reserved op.
  • ComposioToolsAdapter.search_capabilities: one COMPOSIO_SEARCH_TOOLS request. A tool-level failure, missing data, or a malformed envelope raises AdapterError (surfaced as 424) instead of a silent empty result.
  • Pure Composio-to-Agenta translation in core/tools/discovery.py: tools become integration.action, connection state becomes ready / needs_auth / needs_input, and guidance is mapped to the same Agenta names. No provider slugs leak to the agent.
  • The discover-and-wire-tools skill (the setup-agent loop: discover, read, connect, create) and the project design docs under docs/design/agent-workflows/projects/tool-discovery/.

Scope / risk

How to QA

Prerequisites: local dev stack (run.sh --oss --dev or --ee --dev). For a live run, the calling project needs a Composio provider key in its vault. The unit tests need none; they replay a recorded COMPOSIO_SEARCH_TOOLS response.

Steps (offline, no credentials):

  1. From api/, run the discovery unit suite (command below).
  2. Confirm the translation, adapter envelope handling, and reserved-tool parsing tests pass.

Steps (live, needs a Composio key):

  1. Discover via the HTTP endpoint:
    curl -X POST "$API/tools/discover" -H "Authorization: ApiKey $KEY" \
      -H "content-type: application/json" \
      -d '{"use_cases": ["create a github issue", "send a slack message"]}'
    
  2. Discover via the reserved tool (the path an agent uses):
    curl -X POST "$API/tools/call" -H "Authorization: ApiKey $KEY" \
      -H "content-type: application/json" \
      -d '{"data": {"id": "1", "function": {"name": "tools.agenta.find_capabilities",
           "arguments": "{\"use_cases\": [\"create a github issue\"]}"}}}'
    

Expected result: a CapabilitiesResult with one capabilities[] entry per use case (best-match tool as integration.action plus its input_schema), a deduped connections[] list with each integration's state, guidance (plan steps and pitfalls), and ready true only when every primary connection is ready. No raw Composio slug appears except the clearly-labelled provider_action debug field.

Automated tests:

cd api && uv run python -m pytest oss/tests/pytest/unit/tools/ -q

Manual request samples live in api/oss/tests/manual/tools/tools.http.

Edge cases: a bare-string use_cases must be rejected (422 on /discover) or treated as one use case (reserved tool), never iterated character by character. A use case with no primary match keeps ready false. A trigger-shaped use case ("when a new email arrives") returns a note, not a tool.

Interface reference

Request (POST /tools/discover, body CapabilitiesQuery):

{
  "use_cases": ["create a github issue", "send a slack message"], // required, non-empty
  "provider": "composio",        // optional, default "composio"
  "limit_alternatives": 3         // optional, default 3, >= 0
}

Response (CapabilitiesResult, returned by /discover and as the reserved tool's result):

{
  "capabilities": [
    {
      "use_case": "create a github issue",
      "integration": "github",
      "tool": {
        "type": "gateway", "provider": "composio",
        "integration": "github", "action": "CREATE_AN_ISSUE",
        "connection": "github-main",           // set only when state == ready
        "input_schema": { /* JSON schema */ },
        "provider_action": "GITHUB_CREATE_AN_ISSUE" // opaque debug field, not the interface
      },
      "alternatives": [ /* DiscoveredAlternative[] */ ],
      "connection": { "state": "ready", "slug": "github-main" },
      "note": null
    }
  ],
  "connections": [
    { "integration": "github", "state": "ready", "slug": "github-main" },
    { "integration": "slack", "state": "needs_auth",
      "connect": { "endpoint": "POST /tools/connections/", "body": { /* ... */ } } }
  ],
  "guidance": { "plan_steps": ["..."], "pitfalls": ["..."] },
  "ready": false,
  "notes": []
}

Reserved tool call_ref: tools.agenta.find_capabilities. An agent calls it through POST /tools/call (the runner forwards the call_ref opaquely); the router routes it by the tools.agenta. prefix to the same discover_capabilities service. Its input schema mirrors the request above with use_cases required.

https://claude.ai/code/session_01QCZZZawwY95v8gXiTQBgZp

@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jun 27, 2026 10:17pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d00587fe-160c-4e9f-9836-1d00d7748352

📥 Commits

Reviewing files that changed from the base of the PR and between 7cdaa0b and 2df7029.

📒 Files selected for processing (7)
  • api/oss/src/apis/fastapi/tools/router.py
  • api/oss/src/core/tools/discovery.py
  • api/oss/src/core/tools/providers/composio/adapter.py
  • api/oss/tests/pytest/unit/tools/test_discovery.py
  • docs/design/agent-workflows/projects/tool-discovery/plan.md
  • docs/design/agent-workflows/projects/tool-discovery/skills/discover-and-wire-tools/SKILL.md
  • docs/design/agent-workflows/projects/tool-discovery/status.md
✅ Files skipped from review due to trivial changes (3)
  • docs/design/agent-workflows/projects/tool-discovery/skills/discover-and-wire-tools/SKILL.md
  • docs/design/agent-workflows/projects/tool-discovery/plan.md
  • docs/design/agent-workflows/projects/tool-discovery/status.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • api/oss/src/core/tools/providers/composio/adapter.py
  • api/oss/src/apis/fastapi/tools/router.py
  • api/oss/tests/pytest/unit/tools/test_discovery.py
  • api/oss/src/core/tools/discovery.py

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added tool discovery for agents, letting them turn plain-language use cases into suggested tools, actions, schemas, and connection status in one step.
    • Added support for a reserved agent-facing capability lookup flow alongside existing tool execution.
  • Documentation

    • Added detailed design, walkthrough, status, and skill docs for the new discovery workflow and its current limitations.
    • Updated interface docs to reflect the new discovery route and reserved tool behavior.

Walkthrough

Adds Composio-backed tool discovery, server routing for POST /tools/discover and tools.agenta.find_capabilities, cached connection-state recomputation, tests and fixtures, plus matching design and interface documentation.

Changes

Tool Discovery Workflow

Layer / File(s) Summary
Project framing and research
docs/design/agent-workflows/projects/tool-discovery/README.md, context.md, research.md
Adds the project overview, context framing, and research notes for the Composio discovery call, response shape, and connection-state behavior.
Contract design and walkthrough
docs/design/agent-workflows/projects/tool-discovery/design.md, use-case-walkthrough.md
Defines the find_capabilities contract, consumer roles, connection-state model, and the Slack bot walkthrough showing the single-call discovery flow and Agenta-native translation.
Plan, status, skill, and interface docs
docs/design/agent-workflows/projects/tool-discovery/plan.md, status.md, skills/discover-and-wire-tools/SKILL.md, docs/design/agent-workflows/documentation/tools.md, docs/design/agent-workflows/interfaces/...
Adds the implementation plan, status tracking, setup-agent skill, and interface documentation updates for the reserved callback grammar and discovery endpoint.
Discovery contracts and Composio adapter
api/oss/src/apis/fastapi/tools/models.py, api/oss/src/core/tools/dtos.py, api/oss/src/core/tools/exceptions.py, api/oss/src/core/tools/providers/composio/dtos.py, api/oss/src/core/tools/providers/composio/adapter.py
Defines the discovery request and response models, Composio search DTOs, the discovery-unsupported exception, and the adapter method that executes and validates COMPOSIO_SEARCH_TOOLS.
Discovery translation helpers
api/oss/src/core/tools/discovery.py
Implements argument normalization, trigger detection, slug rewriting, integration extraction, and translation from Composio search results into Agenta-native capability data.
Service orchestration and FastAPI routing
api/oss/src/core/tools/service.py, api/oss/src/apis/fastapi/tools/router.py
Adds cached discovery orchestration, per-project connection-state resolution, the /discover endpoint, and reserved tools.agenta.* routing from /tools/call.
Discovery tests and fixtures
api/oss/tests/pytest/unit/tools/test_discovery.py, api/oss/tests/pytest/unit/tools/fixtures/composio_search_tools.json, api/oss/tests/manual/tools/tools.http
Adds the recorded Composio fixture, unit coverage for adapter, translation, service, router, reserved-tool contract behavior, and the manual HTTP workflow.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Agenta-AI/agenta#4821: Updates the same agent-workflow interface docs to cover the reserved tools.agenta.* callback contract.
  • Agenta-AI/agenta#4860: Modifies ToolsRouter call-ref dispatch behavior on the same /tools/call surface.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.78% which is insufficient. The required threshold is 60.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 clearly summarizes the main change: tool discovery via /tools/discover and the reserved find_capabilities tool.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the new discovery endpoint, reserved tool, and translation layer.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/tool-discovery-find-capabilities

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@mmabrouk mmabrouk added the needs-review Agent updated; awaiting Mahmoud's review label Jun 27, 2026
@mmabrouk

Copy link
Copy Markdown
Member Author

🔸 Two things needed here (both your call, not a code review):

1. Design review of the find_capabilities contract and the Composio→Agenta translation in design.md (the field-by-field "useful to whom + maps to which Agenta concept" table) and the connection state machine. That is the load-bearing design.

2. Decisions D2–D6 in status.md to unblock implementation. D1 (new POST /tools/discover endpoint, agent tool as reserved tools.agenta.find_capabilities) is settled per chat. My recommendation for the rest:

  • D2 — translate vs pass through. Translate fully to Agenta concepts (integration + action, connection slugs, our POST /tools/connections/ affordance). Keep the raw Composio slug only as an opaque provider_action; keep plan/pitfalls as guidance text. → Recommend: translate fully.
  • D3 — report vs act on connections. Report state + return the create affordance; do not auto-create (a human approves OAuth). → Recommend: report + affordance.
  • D4 — agents_md draft. Return plan + pitfalls as structured guidance and let the setup agent compose agents_md; add a ready-made draft later if useful. → Recommend: structured now, draft later.
  • D5 — triggers in scope? Verified Composio has no semantic trigger search (COMPOSIO_SEARCH_TRIGGERS 404; tool search ignores trigger phrasing; only keyword /triggers_types + COMPOSIO_LIST_TRIGGERS). So the Slack "listen" step can't share the one-call path. → Recommend: scope v1 to action tools, return a clear "needs a trigger subscription" note, do triggers as a follow-up.
  • D6 — caching. Cache the tool/schema half; re-check connection state fresh (it flips when a user connects). → Recommend: split cache keys, short TTL on the connection part.

Once you pick (or just say "go with the recommendations"), I'll queue the implementation starting with Phase 1 (the adapter method + a recorded-fixture test).

- Capture the Composio response as a replay fixture (`agent-replay-test` skill) so the
contract is pinned without a live LLM.

## Phase 6 — Follow-ups (separate slices)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Add as part of the PR a skill to deal with this (not agents.md). And test it using a subagent after this is implemented to see if they can easily setup the tools for an agent

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: Done. The skill ships in this PR at docs/design/agent-workflows/projects/tool-discovery/skills/discover-and-wire-tools/SKILL.md (the discover, resolve-connections, create, test loop, not an agents.md blob). The subagent setup test you asked for needs a live Composio key, so it runs in the orchestrator's e2e phase (/debug-local plus a setup subagent) after this lands. Phase 5 in plan.md and the note in status.md track it as that follow-up.

- Optional `manage_connection` helper tool (design note #6) so the agent can initiate a
connection without composing the raw `POST /tools/connections/` body.

## Testing and conventions

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

dont forget spinning off a subagent to qa this explorative with /debug local

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: Acknowledged. The live /debug-local exploratory QA needs the running stack and a real Composio connection, so it goes to the orchestrator's e2e pass rather than this implementation step. plan.md Phase 5 marks it as that follow-up.

@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

🧹 Nitpick comments (4)
docs/design/agent-workflows/projects/tool-discovery/research.md (1)

10-21: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add language specifiers to fenced code blocks.

Several code blocks documenting API request/response shapes lack language identifiers. Adding json or jsonc improves syntax highlighting and readability.

♻️ Proposed fixes

+```json
{
"user_id": "",


And similarly for the other data-structure blocks at lines 32, 43, 57, 72, 79, 90.
</details>


Also applies to: 32-39, 43-53, 57-61, 72-75, 79-82, 90-96

<!-- cr-comment:v1:1f9c7a95eba1aa1e570bde7a -->

</blockquote></details>
<details>
<summary>docs/design/agent-workflows/projects/tool-discovery/use-case-walkthrough.md (1)</summary><blockquote>

`49-59`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _💤 Low value_

**Add language specifier to the JSON request block.**

```diff

+```jsonc
{
"use_cases": [


<!-- cr-comment:v1:42f8ea08667123c472586810 -->

</blockquote></details>
<details>
<summary>docs/design/agent-workflows/projects/tool-discovery/plan.md (1)</summary><blockquote>

`50-52`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _⚡ Quick win_

**Confirm cache TTL values align with operational requirements.**

The plan specifies "existing 5-min TTL" for tool/schema cache and "short TTL for the connection part" without stating the short duration. Document the intended connection-state TTL (e.g., 30s, 60s) or reference the operational SLO for connection freshness to ensure implementers don't default to the same 5-minute window.

```diff
-  re-resolve connection state fresh each call (it changes when a user connects). Split keys or
-  short TTL for the connection part.
+  re-resolve connection state fresh each call (it changes when a user connects). Split keys or
+  short TTL (e.g., 30–60s) for the connection part.
docs/design/agent-workflows/projects/tool-discovery/status.md (1)

59-60: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Clarify tie-breaking rule for multiple active connections.

The risk notes multiple connections per toolkit per project are possible. Specify the selection priority (e.g., most-recently-created, first-active, specific connection ID) in the design or plan so Phase 2 implementers don't guess.

-  resolving the slug.
+  resolving the slug (e.g., prefer the most-recently-authenticated active connection).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 809f987c-e56b-46b2-a991-2d8476ea91ee

📥 Commits

Reviewing files that changed from the base of the PR and between fd43144 and 8b03b3d.

📒 Files selected for processing (7)
  • docs/design/agent-workflows/projects/tool-discovery/README.md
  • docs/design/agent-workflows/projects/tool-discovery/context.md
  • docs/design/agent-workflows/projects/tool-discovery/design.md
  • docs/design/agent-workflows/projects/tool-discovery/plan.md
  • docs/design/agent-workflows/projects/tool-discovery/research.md
  • docs/design/agent-workflows/projects/tool-discovery/status.md
  • docs/design/agent-workflows/projects/tool-discovery/use-case-walkthrough.md

Comment thread docs/design/agent-workflows/projects/tool-discovery/design.md Outdated

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

lgtm see comments

@mmabrouk mmabrouk added lgtm This PR has been approved by a maintainer and removed needs-review Agent updated; awaiting Mahmoud's review labels Jun 27, 2026
@mmabrouk mmabrouk added implementing Design approved; implementation queued/in progress (not awaiting review) and removed lgtm This PR has been approved by a maintainer labels Jun 27, 2026
@mmabrouk mmabrouk force-pushed the docs/tool-discovery-find-capabilities branch from aae9788 to 9c0237a Compare June 27, 2026 14:44
@mmabrouk mmabrouk changed the base branch from big-agents to feat/agent-embedref-tools June 27, 2026 14:48
@mmabrouk mmabrouk changed the base branch from feat/agent-embedref-tools to fe-feat/agent-embedref-tools-onbig June 27, 2026 15:15
@mmabrouk mmabrouk force-pushed the fe-feat/agent-embedref-tools-onbig branch from 80ee74c to 20f6636 Compare June 27, 2026 15:16
@mmabrouk mmabrouk force-pushed the docs/tool-discovery-find-capabilities branch from 9c0237a to b3226c5 Compare June 27, 2026 15:16
mmabrouk added a commit that referenced this pull request Jun 27, 2026
Address Mahmoud's round-2 comments + CodeRabbit:
- reference input_schema from the workflow's revision.schemas.inputs (messages via x-ag-type-ref); output schemas deferred
- permissions uniform across all tool types (not special-cased on the call path)
- platform-op catalog mirrors the reserved tools.agenta.* pattern (#4884 find_capabilities) + evaluators catalog, not platform_catalog.py wholesale
- schema sourcing standardized on the in-process CATALOG_TYPES catalog (fixes the openapi.json inconsistency)
- merge order/organization framed as the orchestrator's call
@mmabrouk mmabrouk force-pushed the docs/tool-discovery-find-capabilities branch from b3226c5 to b871014 Compare June 27, 2026 17:05
Planning workspace for find_capabilities: an agent-facing tool that wraps
Composio's COMPOSIO_SEARCH_TOOLS to turn natural-language use cases into a
wired set of Agenta tools plus a connection plan in one call, translated to
Agenta concepts. Verified the endpoint, schemas, and per-project connection
state (user_id == project_id) live. Design only, no runtime change.

Claude-Session: https://claude.ai/code/session_01QCZZZawwY95v8gXiTQBgZp
@mmabrouk mmabrouk changed the base branch from fe-feat/agent-embedref-tools-onbig to big-agents June 27, 2026 18:21

return ToolCallResponse(call=result)

async def _call_agenta_tool(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: This is the reserved-tool dispatch. call_tool routes any tools.agenta.* call here by prefix, so the reserved tool stays out of Composio's 5-segment namespace. v1 handles only find_capabilities and 404s anything else.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

review with codex on alignement with best practices and other places in the code

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

and address if strong opinion

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: Done. Reviewed the reserved-tool dispatch with Codex (xhigh). Verdict: the prefix if-ladder in call_tool (workflow / agenta / gateway) is fine and consistent. It is a single tool-execute ingress, and there is no competing dispatch pattern elsewhere in the FastAPI routers to mirror. The one must-fix it raised was permission placement, addressed below.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: Addressed. Codex's strong opinion was that the permission policy belongs at the call_tool dispatch boundary, not only inside the private handler. Fixed in 2df7029e: the tools.agenta.* branch in call_tool now requires VIEW_TOOLS on top of the outer RUN_TOOLS before dispatching, with an auth-split regression test. I also applied its anti-drift nit, deriving AGENTA_TOOL_CALL_REF_PREFIX from ToolProviderKind.AGENTA. Two nice-to-haves are deferred: a reserved-op registry (premature for one op), and unifying the /discover validator with the reserved-tool parser (their input handling differs on purpose, /discover rejects a scalar string with 422 while the reserved tool coerces a bare string to one use case).

return out


def translate_search_result(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: This is the Composio→Agenta translation. Pure functions turn a raw Composio search into the native contract: tools as integration.action, connection state, and structured guidance. No provider slugs leak to the agent. This is the load-bearing mapping to review.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

we need some testing of this with real credential (ask parent agent) and creation of tests that makes sure that covers this well.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: Split into two. (1) Real-credential testing: handed to the orchestrator's e2e pass, which runs find_capabilities against a project with a live Composio key and captures a replay fixture (agent-replay-test); the live call needs creds this step does not hold. (2) Translation test coverage: it is unit-covered in test_discovery.py (the Composio to Agenta contract, the three connection states, slug split, guidance rewrite, alternatives cap, trigger detection, and an end-to-end run over the recorded fixture). This round adds the auth-split test and non-dict-envelope cases. 77 tests pass.

# Discovery — semantic tool search (COMPOSIO_SEARCH_TOOLS)
# -----------------------------------------------------------------------

async def search_capabilities(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: This is the Composio adapter call. One COMPOSIO_SEARCH_TOOLS request returns matched tools, alternatives, inline schemas, and connection state. Agenta passes str(project_id) as the Composio user, so the state reflects the calling project.

description: Use find_capabilities to discover the right Agenta tools for an agent you are building, report what each integration needs to connect, and wire the tools into the new agent's config. Use when a setup/builder agent must turn a plain-language task ("post to Slack and open GitHub issues") into attached, connected, ready-to-run tools.
---

# Discover and wire tools with `find_capabilities`

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 The AI agent says: This is the discover-and-wire-tools skill, the agent-facing loop. It walks a setup agent from a plain-language task to attached, connected, ready-to-run tools (discover → read → connect → create agent). Check the steps are clear enough to follow unaided.

@mmabrouk mmabrouk marked this pull request as ready for review June 27, 2026 18:35
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jun 27, 2026
@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@dosubot dosubot Bot added the documentation Improvements or additions to documentation label Jun 27, 2026
@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 7

🧹 Nitpick comments (3)
docs/design/agent-workflows/projects/tool-discovery/research.md (1)

10-10: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add language specifiers to fenced code blocks for better markdown rendering.

The pseudocode and data-structure blocks will render more consistently with explicit language tags (e.g. json, http, text). This is optional hygiene for design docs.

Also applies to: 32-32, 43-43, 57-57, 72-72, 79-79, 90-90

docs/design/agent-workflows/projects/tool-discovery/use-case-walkthrough.md (1)

20-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add language specifiers to fenced code blocks.

The HTTP request and JSON body blocks will render with better syntax highlighting using http and json tags respectively.

Also applies to: 49-49

api/oss/src/core/tools/dtos.py (1)

280-288: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Type the create-connection payload explicitly.

ConnectAffordance.body has a fixed shape, but exposing it as Dict[str, Any] weakens the discovery contract and makes the service return a raw nested dict. This should be modeled with named DTOs like the rest of the response.

Proposed refactor
+class ConnectAffordanceConnection(BaseModel):
+    provider_key: str
+    integration_key: str
+    slug: str
+
+
+class ConnectAffordanceBody(BaseModel):
+    connection: ConnectAffordanceConnection
+
+
 class ConnectAffordance(BaseModel):
     endpoint: str = "POST /tools/connections/"
-    body: Dict[str, Any]
+    body: ConnectAffordanceBody

As per coding guidelines, "Do not return raw dicts or tuples from service methods or clients; define named DTOs in core/{domain}/dtos.py instead."

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a3e98d46-7495-49af-89d2-ec429890c4cc

📥 Commits

Reviewing files that changed from the base of the PR and between 8b03b3d and 485b8b2.

📒 Files selected for processing (23)
  • api/oss/src/apis/fastapi/tools/models.py
  • api/oss/src/apis/fastapi/tools/router.py
  • api/oss/src/core/tools/discovery.py
  • api/oss/src/core/tools/dtos.py
  • api/oss/src/core/tools/exceptions.py
  • api/oss/src/core/tools/providers/composio/adapter.py
  • api/oss/src/core/tools/providers/composio/dtos.py
  • api/oss/src/core/tools/service.py
  • api/oss/tests/manual/tools/tools.http
  • api/oss/tests/pytest/unit/tools/fixtures/composio_search_tools.json
  • api/oss/tests/pytest/unit/tools/test_discovery.py
  • docs/design/agent-workflows/documentation/tools.md
  • docs/design/agent-workflows/interfaces/README.md
  • docs/design/agent-workflows/interfaces/cross-service/runner-to-tool-callback.md
  • docs/design/agent-workflows/interfaces/in-service/tool-models-and-resolution.md
  • docs/design/agent-workflows/projects/tool-discovery/README.md
  • docs/design/agent-workflows/projects/tool-discovery/context.md
  • docs/design/agent-workflows/projects/tool-discovery/design.md
  • docs/design/agent-workflows/projects/tool-discovery/plan.md
  • docs/design/agent-workflows/projects/tool-discovery/research.md
  • docs/design/agent-workflows/projects/tool-discovery/skills/discover-and-wire-tools/SKILL.md
  • docs/design/agent-workflows/projects/tool-discovery/status.md
  • docs/design/agent-workflows/projects/tool-discovery/use-case-walkthrough.md
✅ Files skipped from review due to trivial changes (4)
  • api/oss/tests/pytest/unit/tools/fixtures/composio_search_tools.json
  • docs/design/agent-workflows/interfaces/README.md
  • docs/design/agent-workflows/interfaces/in-service/tool-models-and-resolution.md
  • docs/design/agent-workflows/documentation/tools.md

Comment thread api/oss/src/apis/fastapi/tools/models.py Outdated
Comment thread api/oss/src/apis/fastapi/tools/router.py
Comment thread api/oss/src/core/tools/discovery.py Outdated
Comment thread api/oss/src/core/tools/discovery.py
Comment thread api/oss/src/core/tools/discovery.py Outdated
Comment thread api/oss/src/core/tools/providers/composio/adapter.py Outdated
Comment thread api/oss/src/core/tools/service.py
mmabrouk added 2 commits June 27, 2026 22:00
…nslation, cache)

Composio semantic-search adapter (search_capabilities) + Agenta-native
translation (core/tools/discovery.py), connection-state reporting, structured
guidance, v1 action-only scope with a trigger note (D5), and the D6 cache split
(cache the tool/schema half, recompute connection state fresh). Recorded-fixture
replay test + the setup-agent skill. Phase 2 (POST /tools/discover endpoint +
reserved tools.agenta.find_capabilities) deferred behind router.py/models.py.

Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
…rved tool route)

Adds the project-scoped POST /tools/discover endpoint (CapabilitiesQuery ->
ToolsService.discover_capabilities -> CapabilitiesResult; DiscoveryUnsupportedError
-> 422) and the server side of the reserved tools.agenta.find_capabilities tool:
/tools/call routes the tools.agenta. prefix to _call_agenta_tool (out of the
Composio 5-segment namespace). The canonical reserved-tool spec lives in
core/tools/discovery.py. Docs synced (tools.md, interface inventory, manual http).

Stacked on feat/agent-embedref-tools: the router dispatch branch sits on the
workflow.* routing committed there. The SDK-side declaration/resolution (emitting
the CallbackToolSpec for the reserved tool) is deferred to the direct-call-tools
platform-op seam; the runner is unchanged (forwards the call_ref opaquely).

Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
@mmabrouk

Copy link
Copy Markdown
Member Author

🤖 The AI agent says: Addressed the review on head 7cdaa0b.

Fixed (4 real findings + 1 quick win):

  • adapter.pysearch_capabilities raises AdapterError on an unsuccessful, empty, or malformed COMPOSIO_SEARCH_TOOLS envelope, so a tool-level failure no longer validates to a silent empty result.
  • discovery.pyready is False whenever a requested use_case has no primary tool.
  • discovery.pyreferenced_integrations mirrors the single tool _translate_one exposes (first primary only), so connections[] lists only offered integrations.
  • discovery.py + models.py — a scalar-string use_cases is coerced to one fragment (reserved tool) or rejected with a 422 (HTTP body), never iterated character by character.
  • service.py — the connect affordance suggests a non-colliding <integration>-main slug.

Deferred: the /discover count + payload envelope. CapabilitiesResult is a single composite object, not a collection, and the same DTO is serialized into the reserved tool result, so an HTTP-only wrapper would split one contract into two.

Eight new tests cover the fixes. The tools suite is green (74 passed) and ruff is clean.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

@mmabrouk Thanks for the detailed update — those fixes line up with the review points, and the rationale for deferring the /discover envelope change makes sense if you want to preserve a single shared contract between the HTTP path and tools.agenta.find_capabilities.

I’ll re-review the latest changes on head 7cdaa0b.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 5


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a30d433f-4337-41fa-b908-1c40d19d31fa

📥 Commits

Reviewing files that changed from the base of the PR and between 485b8b2 and 7cdaa0b.

📒 Files selected for processing (20)
  • api/oss/src/apis/fastapi/tools/models.py
  • api/oss/src/apis/fastapi/tools/router.py
  • api/oss/src/core/tools/discovery.py
  • api/oss/src/core/tools/dtos.py
  • api/oss/src/core/tools/exceptions.py
  • api/oss/src/core/tools/providers/composio/adapter.py
  • api/oss/src/core/tools/providers/composio/dtos.py
  • api/oss/src/core/tools/service.py
  • api/oss/tests/manual/tools/tools.http
  • api/oss/tests/pytest/unit/tools/fixtures/composio_search_tools.json
  • api/oss/tests/pytest/unit/tools/test_discovery.py
  • docs/design/agent-workflows/documentation/tools.md
  • docs/design/agent-workflows/interfaces/README.md
  • docs/design/agent-workflows/interfaces/cross-service/runner-to-tool-callback.md
  • docs/design/agent-workflows/interfaces/in-service/tool-models-and-resolution.md
  • docs/design/agent-workflows/projects/tool-discovery/README.md
  • docs/design/agent-workflows/projects/tool-discovery/design.md
  • docs/design/agent-workflows/projects/tool-discovery/plan.md
  • docs/design/agent-workflows/projects/tool-discovery/skills/discover-and-wire-tools/SKILL.md
  • docs/design/agent-workflows/projects/tool-discovery/status.md
✅ Files skipped from review due to trivial changes (6)
  • api/oss/tests/pytest/unit/tools/fixtures/composio_search_tools.json
  • docs/design/agent-workflows/interfaces/in-service/tool-models-and-resolution.md
  • docs/design/agent-workflows/interfaces/README.md
  • docs/design/agent-workflows/interfaces/cross-service/runner-to-tool-callback.md
  • docs/design/agent-workflows/projects/tool-discovery/design.md
  • docs/design/agent-workflows/documentation/tools.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • api/oss/tests/manual/tools/tools.http
  • api/oss/src/apis/fastapi/tools/models.py
  • api/oss/src/core/tools/exceptions.py
  • api/oss/src/core/tools/providers/composio/dtos.py
  • api/oss/src/core/tools/dtos.py
  • api/oss/src/core/tools/discovery.py
  • api/oss/src/core/tools/service.py
  • api/oss/tests/pytest/unit/tools/test_discovery.py

Comment thread api/oss/src/apis/fastapi/tools/router.py
Comment thread api/oss/src/core/tools/providers/composio/adapter.py
Comment thread docs/design/agent-workflows/projects/tool-discovery/plan.md Outdated
Comment thread docs/design/agent-workflows/projects/tool-discovery/status.md Outdated

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

would lgtm after addressing the comments by me and coderabbit. if well tested then feel free to merge

@mmabrouk mmabrouk removed the needs-review Agent updated; awaiting Mahmoud's review label Jun 27, 2026
@mmabrouk mmabrouk changed the title docs(agent): tool-discovery find_capabilities design + plan [feat] Tool discovery: POST /tools/discover + reserved find_capabilities tool Jun 27, 2026
…e guard, doc sync

Address PR #4884 review (Mahmoud + CodeRabbit + Codex xhigh):
- Gate the reserved tools.agenta.* branch in call_tool with VIEW_TOOLS at the dispatch
  boundary (was RUN_TOOLS-only); discovery exposes per-project connection state. Add an
  auth-split regression test.
- Adapter: reject a non-object COMPOSIO_SEARCH_TOOLS envelope as AdapterError instead of
  letting .get() raise AttributeError (500). Cover with non-dict envelope cases.
- Derive AGENTA_TOOL_CALL_REF_PREFIX from ToolProviderKind.AGENTA (anti-drift).
- Sync stale status banner / Phase headings / D1 in the project docs; add a
  find_capabilities availability caveat to the discover-and-wire-tools skill.

Claude-Session: https://claude.ai/code/session_01QCZZZawwY95v8gXiTQBgZp
@mmabrouk

Copy link
Copy Markdown
Member Author

🤖 The AI agent says: Review pass on this PR. Renamed it and rewrote the description so it reads as the implementation it is (it was titled docs(agent): ... and read as docs-only). Every review comment is addressed; details are in the threads above.

What changed this pass (commit 2df7029e)

  • VIEW_TOOLS at the dispatch boundary (CodeRabbit + Codex must-fix). The tools.agenta.* branch in call_tool now requires VIEW_TOOLS on top of the outer RUN_TOOLS, so a run-only caller can no longer read discovery or per-project connection state through /tools/call. Added an auth-split regression test.
  • Adapter envelope guard (CodeRabbit). A non-object COMPOSIO_SEARCH_TOOLS body is now an AdapterError, not an AttributeError and a 500. Non-dict cases added to the test.
  • Anti-drift (Codex nit). AGENTA_TOOL_CALL_REF_PREFIX is derived from ToolProviderKind.AGENTA.
  • Doc staleness (CodeRabbit). Synced the plan banner, the status Phase headings and D1, and added a find_capabilities availability caveat to the skill.

Comment map

Comment Outcome
Mahmoud: add a skill (not agents.md) + subagent setup test Skill ships in the PR; live subagent test handed to orchestrator e2e
Mahmoud: /debug-local exploratory QA Deferred to orchestrator e2e (needs the live stack)
Mahmoud: review dispatch with Codex, address if strong Done; VIEW_TOOLS-at-boundary applied (see thread)
Mahmoud: test the translation with real credentials Real-cred run is orchestrator e2e; translation is unit-covered, more tests added
CodeRabbit: VIEW_TOOLS / envelope guard / 3 doc staleness All fixed in 2df7029e
CodeRabbit: /discover count+payload envelope Withdrawn by CodeRabbit (shared contract, deferred)

design-interfaces review

Ran the design-interfaces skill over the /tools/discover request and the CapabilitiesResult response. The contract is role-aligned: top-level sections read as capabilities / connections / guidance / ready / notes, lists are plural maps, no secret leaks into the contract (connection state is a slug plus an enum, not a credential), and the connect affordance is scoped under the integration it connects. No low-risk in-file change is needed. One follow-up worth noting (a contract change, not forced now): DiscoveredTool.provider_action carries the raw Composio slug as a debug field. It is documented as opaque and debug-only, but it is a mild implementation-detail leak, so dropping it from the response is a candidate cleanup for a later slice.

Deferred (follow-ups, not blockers)

  • SDK-side reserved-tool declaration so an agent config surfaces find_capabilities to the model (rides the direct-call-tools platform-op seam, Workstream A).
  • Codex P2s: a reserved-op registry (premature for one op) and unifying the /discover validator with the reserved-tool parser (their input handling differs by design).
  • Live e2e plus a replay-fixture upgrade with a real Composio key.

Stack note

This is the base of the Workstream A stack, so re-pushing it rebased the three lanes above. All four are re-pushed and remote matches: docs/tool-discovery-find-capabilities (2df7029e), feat/direct-call-tools (ac471ec8), feat/direct-call-tools-dispatch (2bb2c6a6), feat/direct-call-tools-runcontext (85f4db7a). The rebase preserved the already-merged review fixes.

What I need: a re-review of 2df7029e (the VIEW_TOOLS gate, the envelope guard, and the doc sync). Gates are green: ruff format and ruff check clean, and 77 tests pass in oss/tests/pytest/unit/tools/. I am not merging from here; the orchestrator merges after the live e2e pass.

@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@mmabrouk mmabrouk added the needs-review Agent updated; awaiting Mahmoud's review label Jun 27, 2026
@mmabrouk mmabrouk merged commit 59079bb into big-agents Jun 28, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-review Agent updated; awaiting Mahmoud's review size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant