Skip to content

feat(sdk,api): build-kit tools cleanup: discover renames, 12-op overlay, query_spans, one playbook skill, test_run server half - #5068

Merged
mmabrouk merged 8 commits into
big-agentsfrom
feat/build-kit-tools-cleanup
Jul 5, 2026
Merged

feat(sdk,api): build-kit tools cleanup: discover renames, 12-op overlay, query_spans, one playbook skill, test_run server half#5068
mmabrouk merged 8 commits into
big-agentsfrom
feat/build-kit-tools-cleanup

Conversation

@mmabrouk

@mmabrouk mmabrouk commented Jul 4, 2026

Copy link
Copy Markdown
Member

PR title

feat(sdk,api): build-kit tools cleanup + test_run server half

PR body

Context

The playground build kit is the tool set a fresh agent uses to build itself. It carried 19 tools plus three cross-referencing authoring skills, and in end-to-end tests the builder agent wandered: it guessed op names, drifted between overlapping skills, and had no way to test the agent it had just built. The agent-creation-lab kit proved the fix outside Agenta: a small ordered tool set, one playbook, and a self-verifying test step. The tools-review compared the 19 inside tools against the lab's 13 outside scripts, with evidence per verdict, and design PR #5060 turned that into this plan. This PR executes it: slices 1-5a, one commit per slice, on docs/design/agent-workflows/projects/build-kit-tools-cleanup/plan.md.

Changes

Slice 1: rename the discovery ops, hard. find_capabilities is now discover_tools and find_triggers is now discover_triggers. No aliases (decided; pre-production). The legacy reserved /tools/call route for tools.agenta.find_capabilities is deleted. A sweep script rewrites committed revisions that still carry the old keys (projects/build-kit-tools-cleanup/scripts/sweep_platform_op_renames.py).

Slice 2: an explicit default overlay. The overlay previously embedded every catalog op. It now embeds an explicit DEFAULT_BUILD_KIT_OPS list of 12 ops plus the request_connection client tool. Cut from the default (all stay in the catalog for opt-in): pause_schedule, resume_schedule, pause_subscription, resume_subscription, query_workflows, list_connections, list_subscriptions.

Slice 3: query_spans. A new read-only platform op over POST /api/spans/query, so the builder can read its own past runs and verify a tool actually fired. The op schema mirrors SpansQueryRequest; a drift contract test pins the two together.

Slice 4: one playbook skill. A single ordered build-an-agent skill (slug __ag__build_an_agent) replaces build-your-first-app, discover-and-wire-tools, and set-up-triggers. The overlay embeds only the playbook. getting-started stays harness-forced on pi_agenta, so it is delivered once instead of twice.

Slice 5a: test_run, server half only. The op that lets the builder test its own variant:

  • PlatformOp gains a handler mode: an op targets exactly one of method+path (endpoint) or handler (an allowlisted reserved tools.agenta.<op> call-ref).
  • The resolver emits handler ops as callRef + spec-level contextBindings + timeoutMs. This is flag-gated OFF (AGENTA_AGENT_ENABLE_PLATFORM_HANDLERS) until the runner half lands.
  • /tools/call gains a reserved-ref registry: a registered tools.agenta.* ref dispatches to its Python handler; an unknown one fails loud with a 404.
  • The test_run handler hydrates the bound variant's committed revision, applies an optional in-memory delta (requires EDIT_WORKFLOWS), invokes it headless with a server-minted token, and returns a digest with a terminal-result-wins verdict, under a 120s ceiling. A recursion marker is emitted but inert until the runner half lands.
  • test_run is NOT in the overlay yet; it joins when the flag flips.

Plus one SDK resolver fix found live: an inline revision committed without parameters now seeds the default agent template, the same way a reference resolution does. Before the fix, test_run against a fresh playground app failed because the child invoke saw an empty config.

Assumed decisions (review these first)

Three calls proceeded on their recommendations as provisional defaults. They were flagged, not decided:

  1. Static overlay, including query_spans. The default is a fixed 12-op list, not a conditional event pack. Argued in projects/build-kit-tools-cleanup/research.md (overlay-scope).
  2. test_run is sync with an in-memory delta. 120s cap, per-op timeout_ms plumbing; test_id stays reserved so an async pair remains additive. Argued in api-design.md (shape-decision).
  3. query_spans ships now, not held for test_run. It stays useful after test_run lands (reading scheduled fires). Argued in api-design.md (query_spans stopgap).

Scope / risk

  • The runner half of test_run (slice 5b) is deferred. The flag (AGENTA_AGENT_ENABLE_PLATFORM_HANDLERS, default off) protects exactly this: with it off, a handler-mode op fails resolution loudly instead of reaching a runner that cannot dispatch a reserved callRef, inject spec-level context, or honor timeoutMs. protocol.ts and the golden wire fixtures do not carry the new spec fields yet. Open-issues entry filed with the full 5b scope.
  • The gateway -> server rename (slice 6) is deferred. Codex review scoped the safe version to docs/UI labels; the stored type: "gateway" literal is a data migration. Open-issues entry filed.
  • The rename is a hard migration. Old committed revisions that reference find_capabilities / find_triggers fail loud (UnknownPlatformOpError) at resolve time until the sweep script runs against that database. Dev DBs are swept; a production deploy must run the same sweep. Acceptable pre-production, but it is a deploy step, not a no-op.
  • FE fixtures and generated clients are deferred. agentRequest.test.ts op literals and the CapabilitiesResult docstrings in the generated clients update at the next codegen.
  • Approval semantics are untouched: test_run sets read_only=False and nothing else, so the merged permission plan resolves it to ask by default.

How to QA

Prerequisites: local dev stack (load-env hosting/docker-compose/ee/.env.ee.dev + bash ./hosting/docker-compose/run.sh --ee --dev --build). For step 4, set AGENTA_AGENT_ENABLE_PLATFORM_HANDLERS=true on the API and grab a project API key.

Steps:

  1. Create a fresh agent application in the playground. Open its config: the build-kit block must show the 12 default ops (discover_tools, commit_revision, annotate_trace, query_spans, discover_triggers, create_schedule, create_subscription, list_schedules, list_deliveries, test_subscription, remove_schedule, remove_subscription), the request_connection client tool, and exactly one skill embed, the build-an-agent playbook. No pause/resume ops, no query_workflows.

  2. Chat with the agent ("find me a tool that creates GitHub issues"). Watch it call discover_tools and come back with Agenta-shaped capabilities and connection state.

  3. Confirm the old names are gone: a config carrying {type:"platform", op:"find_capabilities"} fails resolution with UnknownPlatformOpError.

  4. Curl test_run directly (server half):

    curl -s -X POST "$API/tools/call" -H "Authorization: ApiKey $KEY" -H "Content-Type: application/json" -d '{
      "data": {"id": "call_qa1", "type": "function", "function": {
        "name": "tools__agenta__test_run",
        "arguments": {"target": {"workflow_variant_id": "<variant-id>"},
                      "inputs": {"messages": [{"role": "user", "content": "hi"}]}}}}}'
    
    • Happy path: 200; call.data.content is a JSON digest with a verdict.
    • Negative 404: same call with "name": "tools__agenta__nope" (unknown reserved ref).
    • Negative 400: arguments that fail the schema (e.g. drop inputs). A delta from a caller without EDIT_WORKFLOWS returns 403.
  5. Run the sweep script against the dev DB (dry run is the default; it reads POSTGRES_URI_CORE, falls back to DATABASE_URL) and confirm it reports zero remaining old-key tools or old-slug skill embeds: uv run --script docs/design/agent-workflows/projects/build-kit-tools-cleanup/scripts/sweep_platform_op_renames.py. Add --apply to commit rewrites.

Expected result: steps 1-2 show the leaner kit working end to end; steps 3-5 show the hard migration failing loud and the sweep closing it.

Automated tests:

cd api && uv run --no-sync python -m pytest oss/tests/pytest/unit/tools oss/tests/pytest/unit/applications oss/tests/pytest/unit/workflows oss/tests/pytest/unit/tracing
cd sdks/python && uv run --no-sync python -m pytest oss/tests/pytest/unit

Expected: 250 passed (api) and 1596 passed, 10 xfailed (sdk).

Edge cases: a revision committed before this PR with the old op keys (fails loud until swept, by design); a handler-mode op with the flag off (must fail resolution with a clear message, not resolve to a broken spec); the playbook embed on a fresh app (must resolve by artifact slug; a bare revision slug 500s).

Live verification

Phase-3 verification ran against the local dev stack: a fresh playground agent showed the 12-op block plus the playbook and resolved getting-started once (forced) and the playbook once (overlay); discover_tools / discover_triggers ran end to end in chat; query_spans returned model-digestible spans for a real trace; test_run returned a digest and verdict with the flag on, and the 404/400/403 negative paths behaved; the sweep dry-run came back clean after the dev sweep.

Two findings from that pass:

  • Fresh-app bug, found and fixed here. A fresh playground app commits an inline revision with no parameters, which broke test_run's child invoke. The SDK resolver now seeds the default template for parameters-less inline revisions, matching the reference path.
  • Known gap, not this PR. Child invokes through the local in-process -> sub-sidecar path return trace_id=None (the sidecar's persist/heartbeat 401s), leaving test_run's span digest empty on that path. Tracked as a tracing follow-up in the project workspace, not a build-kit bug.

https://claude.ai/code/session_014iPB7HL5PjgT9npyPHaFMT

@vercel

vercel Bot commented Jul 4, 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 Jul 5, 2026 2:06pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1c0f608e-22d0-4570-9df6-5ab522507926

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR migrates platform tool discovery from find_capabilities/find_triggers to discover_tools/discover_triggers, introduces a handler-mode test_run platform tool with a server-side dispatch handler and tracing integration, replaces three legacy authoring skills with a single build-an-agent skill in the build-kit overlay and static catalog, updates related SDK contracts/tests, design docs, and adds a database migration sweep script.

Changes

Platform tool and handler migration

Layer / File(s) Summary
SDK PlatformOp contract
sdks/python/agenta/sdk/agents/platform/op_catalog.py, sdks/python/agenta/sdk/agents/tools/models.py, sdks/python/agenta/sdk/agents/wire_models.py
PlatformOp supports endpoint-mode and handler-mode ops with validation, timeout_ms, and to_call_ref(); discover_tools/discover_triggers replace find_capabilities/find_triggers; query_spans and test_run ops added; CallbackToolSpec/WireResolvedToolSpec gain context_bindings/timeout_ms.
SDK resolver and build-an-agent skill
sdks/python/agenta/sdk/agents/platform/platform_tools.py, sdks/python/agenta/sdk/agents/adapters/agenta_builtins.py
Resolver builds handler-mode callbacks gated by AGENTA_AGENT_ENABLE_PLATFORM_HANDLERS; legacy authoring skills replaced with BUILD_AN_AGENT_SLUG/SKILL.
Server-side test_run handler
api/oss/src/core/tools/platform_handlers.py
New handle_test_run/dispatch_platform_tool_handler invoke a child workflow, digest responses (tools, approvals, spans), and compute a verdict.
Router reserved-call dispatch and renames
api/oss/src/apis/fastapi/tools/router.py, api/entrypoints/routers.py, api/oss/src/core/tools/discovery.py, dtos.py, service.py, api/oss/src/core/triggers/dtos.py, api/oss/src/apis/fastapi/tools/models.py
Router dispatches reserved calls including permission-gated test_run delta; wires tracing_service; comments renamed to discover_tools/discover_triggers.
Build-kit overlay and static catalog
api/oss/src/apis/fastapi/applications/overlay.py, api/oss/src/core/workflows/static_catalog.py
Overlay uses DEFAULT_BUILD_KIT_OPS and embeds BUILD_AN_AGENT_SLUG; static catalog replaces legacy skill entries.
Tests
api/oss/tests/pytest/unit/tools/*, sdks/python/oss/tests/pytest/unit/agents/*, api/oss/tests/pytest/unit/applications/test_build_kit_overlay.py, api/oss/tests/pytest/unit/workflows/test_static_catalog.py, api/oss/tests/manual/tools/tools.http
Extensive test coverage for handler/router dispatch, op catalog contracts, overlay contents, and static catalog behavior.

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

Design documentation and migration script

Layer / File(s) Summary
Design docs
docs/design/agent-workflows/documentation/*, docs/design/agent-workflows/interfaces/**
Docs updated to describe discover_tools/discover_triggers, handler-mode ops, build-kit defaults, and author-configurable skills.
Sweep script
docs/design/agent-workflows/projects/build-kit-tools-cleanup/scripts/sweep_platform_op_renames.py
New CLI script to rewrite stored workflow_revisions JSON, renaming ops and consolidating skill embeds, with dry-run/apply and verification.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ToolsRouter
  participant PlatformHandlers
  participant WorkflowsService
  participant TracingService
  participant ChildWorkflow

  ToolsRouter->>PlatformHandlers: call_tool(tools.agenta.test_run)
  PlatformHandlers->>PlatformHandlers: check delta => require EDIT_WORKFLOWS
  PlatformHandlers->>WorkflowsService: ensure/prepare revision, resolve delta
  PlatformHandlers->>ChildWorkflow: POST /invoke (via httpx)
  ChildWorkflow-->>PlatformHandlers: workflow batch response
  PlatformHandlers->>TracingService: query spans by trace_id
  TracingService-->>PlatformHandlers: span observations
  PlatformHandlers-->>ToolsRouter: TestRunResponse (verdict, output)
Loading

Possibly related PRs

  • Agenta-AI/agenta#4860: Both modify ToolsRouter wiring/routing in api/entrypoints/routers.py and api/oss/src/apis/fastapi/tools/router.py.
  • Agenta-AI/agenta#4884: Directly refactors the reserved tools.agenta.find_capabilities dispatch path this PR replaces.
  • Agenta-AI/agenta#4929: Introduces the playground build-kit agent-template overlay this PR modifies in overlay.py.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title accurately summarizes the main build-kit cleanup, overlay, query_spans, playbook, and test_run changes.
Description check ✅ Passed The description is clearly about the same build-kit tools cleanup and matches the implemented changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/build-kit-tools-cleanup

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 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.

Review guide: inline pointers to the key hunks follow.

Comment thread sdks/python/agenta/sdk/agents/platform/op_catalog.py
Comment thread sdks/python/agenta/sdk/agents/platform/op_catalog.py
Comment thread api/oss/src/apis/fastapi/applications/overlay.py
# Slice 5 seam: replace the query_spans verification paragraph above with the test_run paragraph
# when that platform op ships.
BUILD_AN_AGENT_SKILL = SkillTemplate(
name="build-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.

Review guide: the one-playbook port: numbered loop, decision table, query_spans verify recipe (test_run seam marked), prefer-wired-tools rule, approval stops.

data=WorkflowServiceRequestData(inputs={"messages": request.inputs.messages}),
)

if request.delta is not None:

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 guide: security: delta requires EDIT_WORKFLOWS + fetch-and-fail target validation (closes the caller-authored-revision hole the adversarial review found).

if not _platform_handlers_enabled():
error = GatewayToolResolutionError(
f"Platform handler-mode op '{op.op}' requires "
f"{_ENABLE_PLATFORM_HANDLERS_ENV}=true before it can resolve.",

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 guide: handler-mode specs cannot reach a runner that does not dispatch them: flag-gated OFF until 5b; resolving without the flag fails loud.

@mmabrouk

mmabrouk commented Jul 4, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 4, 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 commented Jul 4, 2026

Copy link
Copy Markdown
Member Author

What feedback is needed here:

  1. The three assumed decisions (see the PR body section): the static 12-op overlay, sync test_run with an in-memory delta, and shipping query_spans now. Each proceeded on its recommendation; a veto on any is cheap before the runner half lands.
  2. The playbook text in agenta_builtins.py: the numbered loop, the decision table, and the verify recipe are the agent's actual operating manual — read it as prose, not as code.
  3. The test_run security posture: the delta EDIT_WORKFLOWS gate, the flag gate (handler-mode ops fail resolution loudly with the flag off), and the recursion-marker contract.
  4. The deferred 5b scope (runner callRef dispatch, spec-level context injection, timeoutMs, overlay flip): confirm the cut line is right.

One correction to the PR body: the SDK resolver seed fix described in "Changes" and "Live verification" (parameters-less inline revisions seeding the default template) is implemented and live-verified but is NOT in this diff yet. Its resolver.py hunk is textually entangled with the parallel invoke-validation lane (#5002), which edits the same region; committing it here conflicts the GitButler workspace re-merge. It lands as a follow-up commit once #5002 merges (or the lanes are restacked). The 4-file fix (utils.py seed helper, resolver.py wiring, shape tests, a platform-handlers test tweak) sits intact in the working tree.

@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

🧹 Nitpick comments (8)
api/oss/src/apis/fastapi/applications/overlay.py (1)

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

Importing a private module-level dict across module boundary.

_STATIC_WORKFLOWS is a leading-underscore (private) module attribute of static_catalog.py. Importing it directly into overlay.py for iteration (used later in _reserved_static_tool_embeds) couples this file to static_catalog's internal representation rather than its public StaticWorkflowCatalog API (e.g. a method to list slugs). Any internal refactor of that dict's shape in static_catalog.py risks silently breaking this file without a contract signal.

♻️ Suggested direction
-from oss.src.core.workflows.static_catalog import (
-    STATIC_SLUG_PREFIX,
-    StaticWorkflowCatalog,
-    _STATIC_WORKFLOWS,
-)
+from oss.src.core.workflows.static_catalog import (
+    STATIC_SLUG_PREFIX,
+    StaticWorkflowCatalog,
+)

Add a small public accessor on StaticWorkflowCatalog (e.g. list_slugs()) and use catalog.list_slugs() in _reserved_static_tool_embeds instead of iterating the private dict directly.

api/oss/tests/pytest/unit/workflows/test_static_catalog.py (1)

54-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded "ag" prefix duplicates STATIC_SLUG_PREFIX.

_old_authoring_slug hardcodes the literal "__ag__" even though STATIC_SLUG_PREFIX is already imported and used elsewhere in this file (e.g. line 174). If the prefix constant ever changes, this helper silently drifts out of sync and the negative assertions (lines 112-114, 176-178) stop testing what they claim to.

♻️ Suggested fix
 def _old_authoring_slug(name: str) -> str:
-    return "__ag__" + name
+    return STATIC_SLUG_PREFIX + name
sdks/python/agenta/sdk/agents/adapters/agenta_builtins.py (1)

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

Tracked seam note for the test_run migration.

This comment marks a deferred content swap (replace the query_spans verification paragraph with the test_run paragraph once that op ships in the overlay). Just confirming it's an intentional follow-up rather than a leftover; want me to open a tracking issue so it isn't lost?

sdks/python/agenta/sdk/agents/tools/models.py (1)

366-390: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider restricting context_bindings to call_ref-mode specs.

context_bindings is documented as handler-mode metadata that "carries run-context bindings at the spec level so the relay can inject them before posting to /tools/call", which only applies when call_ref is set (gateway dispatch). The _check_call_target validator only enforces the call/call_ref XOR invariant but doesn't prevent a caller from setting context_bindings alongside a direct call descriptor, which would be a semantically invalid combination (direct calls bypass /tools/call and have no relay to apply the bindings).

Consider extending the validator to reject context_bindings when call is set (or when call_ref is None).

🛡️ Proposed validator extension
     `@model_validator`(mode="after")
     def _check_call_target(self) -> "CallbackToolSpec":
         # A callback tool must have exactly one place to call: the gateway slug (``call_ref``) or
         # the direct descriptor (``call``). This encodes the design's ``call`` XOR ``call_ref``
         # rule and preserves the prior invariant that a callback spec always has a target (back
         # when ``call_ref`` was required).
         if (self.call_ref is None) == (self.call is None):
             raise ValueError(
                 "a callback tool spec must carry exactly one of `call_ref` (gateway) "
                 "or `call` (direct)"
             )
+        if self.context_bindings is not None and self.call_ref is None:
+            raise ValueError(
+                "`context_bindings` is only valid with `call_ref` (gateway dispatch)"
+            )
         return self
api/oss/src/apis/fastapi/tools/router.py (1)

1211-1220: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Delta permission gating is hardcoded to TEST_RUN_CALL_REF in the router.

The call_ref == TEST_RUN_CALL_REF check couples this generic reserved-tool dispatcher to test_run-specific policy. If a future handler also needs delta-style elevated permissions, this conditional will need another hardcoded branch. Consider carrying the required permission (or a "requires elevated permission when X" predicate) on PlatformToolHandlerRegistration in platform_handlers.py so the router stays generic.

api/oss/tests/pytest/unit/tools/test_platform_handlers.py (1)

1-594: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Solid coverage of happy path, delta, permissions, pauses, timeouts, and span retries.

One gap worth adding once the _tools_from_messages overwrite bug (flagged in platform_handlers.py) is fixed: a test where the same tool name is invoked twice in one run, once erroring and once succeeding, to lock in correct accumulation of error/returned.

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

197-219: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid depending on WorkflowsService internals platform_handlers.py calls underscore-prefixed helpers on WorkflowsService (_ensure_request_revision, _resolve_revision_delta, _prepare_invoke, _coerce_invoke_response) across a module boundary, so this handler is coupled to an internal API that can change without notice. Expose a small public method or interface for revision resolution and invoke preparation instead.

docs/design/agent-workflows/projects/build-kit-tools-cleanup/scripts/sweep_platform_op_renames.py (1)

189-239: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate skill-consolidation logic between planning and execution.

_planned_skill_embed_changes and rewrite_skill_embeds both re-implement the same seen_playbook walk independently. If one is changed without the other, the printed change log and the actual rewritten data would silently diverge.

Consider having rewrite_skill_embeds compute and return the change list as it mutates, and have _planned_skill_embed_changes/old_skill_embed_paths call into a shared single-pass helper (or have rewrite_skill_embeds be the sole source of truth and drop the separate planning pass in rewrite_revision_data).


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b55a246c-f0e2-4d6a-9b32-e49c4f468b98

📥 Commits

Reviewing files that changed from the base of the PR and between d68193f and 734acba.

📒 Files selected for processing (36)
  • api/entrypoints/routers.py
  • api/oss/src/apis/fastapi/applications/overlay.py
  • 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/platform_handlers.py
  • api/oss/src/core/tools/service.py
  • api/oss/src/core/triggers/dtos.py
  • api/oss/src/core/workflows/static_catalog.py
  • api/oss/tests/manual/tools/tools.http
  • api/oss/tests/pytest/unit/applications/test_build_kit_overlay.py
  • api/oss/tests/pytest/unit/tools/test_discovery.py
  • api/oss/tests/pytest/unit/tools/test_platform_handlers.py
  • api/oss/tests/pytest/unit/tools/test_workflow_tool_call.py
  • api/oss/tests/pytest/unit/tracing/test_query_spans_op_contract.py
  • api/oss/tests/pytest/unit/triggers/test_triggers_discovery.py
  • api/oss/tests/pytest/unit/workflows/test_static_catalog.py
  • docs/design/agent-workflows/documentation/agent-configuration.md
  • 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/interfaces/public-edge/agent-config-schema.md
  • docs/design/agent-workflows/projects/build-kit-tools-cleanup/scripts/sweep_platform_op_renames.py
  • sdks/python/agenta/sdk/agents/adapters/agenta_builtins.py
  • sdks/python/agenta/sdk/agents/platform/op_catalog.py
  • sdks/python/agenta/sdk/agents/platform/platform_tools.py
  • sdks/python/agenta/sdk/agents/tools/models.py
  • sdks/python/agenta/sdk/agents/wire_models.py
  • sdks/python/oss/tests/pytest/unit/agents/platform/conftest.py
  • sdks/python/oss/tests/pytest/unit/agents/platform/test_op_catalog.py
  • sdks/python/oss/tests/pytest/unit/agents/tools/test_models.py
  • sdks/python/oss/tests/pytest/unit/agents/tools/test_parsing.py
  • sdks/python/oss/tests/pytest/unit/agents/tools/test_resolver.py
  • sdks/python/oss/tests/pytest/unit/test_skill_template_catalog.py

Comment thread api/oss/src/apis/fastapi/tools/router.py
Comment thread api/oss/src/core/tools/platform_handlers.py Outdated
Comment thread api/oss/src/core/tools/platform_handlers.py Outdated
Comment thread api/oss/src/core/tools/platform_handlers.py
@mmabrouk

mmabrouk commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Review round 1 addressed (two new commits, no force-push)

1. The seed fix is now IN the diff64ae0d41. This corrects the earlier note that the 4-file fresh-app seed fix (utils.py / resolver.py / 2 tests) was excluded. It was blocked by a workspace entanglement with #5002's resolver commit; since that validation approach was rejected, I unapplied that lane locally (the #5002 branch and PR are untouched) and landed the seed fix here. Fresh parameters-less agents now resolve to the seeded default config on the inline data.revision path, matching reference hydration.

2. CodeRabbit round 1 + a code-organization pass6e52d578. All 5 actionable comments have inline replies (4 fixed, 1 declined). The organization pass, per the review feedback:

  • platform_handlers.py now holds only orchestration: the TestRun* contracts moved to core/tools/dtos.py and the handler exceptions to core/tools/exceptions.py (under the domain's ToolsError base). The module reads top-down: constants → the test_run pipeline (parse → resolve → invoke → digest → verdict) → the registry.
  • The delta→EDIT_WORKFLOWS elevation policy moved off the router onto the handler registration (required_elevated_permission); the reserved-tool dispatcher in the router is now generic (nitpick on the hardcoded TEST_RUN_CALL_REF check — fixed).
  • Security hardening from the review: test_run deltas are confined to the parameters tree (closes the url-redirect hole), tool error flags accumulate across repeated calls, and infra failures surface as STATUS_CODE_ERROR on the outer tool result.

Nitpick dispositions:

  • _STATIC_WORKFLOWS private import → fixed: new public StaticWorkflowCatalog.list_slugs(); overlay and both test files use it.
  • context_bindings on a direct-call spec → fixed: the validator rejects it (bindings belong in call.context for direct calls); test added.
  • Handler allowlist → tightened from prefix match to exact match, with a test that tools.agenta.test_run_extra is rejected.
  • Hardcoded "__ag__" in _old_authoring_slug → declined: the helper pins the historical slugs as they shipped. Tying it to the live STATIC_SLUG_PREFIX would stop testing the old namespace if the prefix ever changed.
  • test_run seam note in the playbook skill → intentional; tracked in the open-issues entry "Land the runner half of test_run (slice 5b)".
  • WorkflowsService underscore-helper coupling → agreed in principle, deferred: it needs a public revision-resolution/invoke-preparation seam on WorkflowsService, which is outside this PR's file set. Tracked as a follow-up.
  • Sweep-script duplicate planning/execution logic → declined for the same reason as the inline reply: one-shot, already-executed migration script kept for provenance.

One heads-up: overlay.py in 6e52d578 also carries a concurrently-authored hunk (builtin read/bash grants via AGENTA_FORCED_TOOLS, adapting the template to the just-merged Pi builtin gating). It landed in my working tree mid-round from a parallel session; it complements the overlay and tests pass with it, so I kept it with an attribution note in the commit message.

Tests: api tools/applications/workflows/tracing suites 259 passed; SDK unit 1597 passed. Ruff clean on both sides.

https://claude.ai/code/session_014iPB7HL5PjgT9npyPHaFMT

mmabrouk added 7 commits July 5, 2026 15:52
… drop the legacy reserved call_ref route; revision sweep script

Claude-Session: https://claude.ai/code/session_014iPB7HL5PjgT9npyPHaFMT
…kill (slices 3-4)

- query_spans: read-only platform op over POST /api/spans/query, schema mirrors SpansQueryRequest, drift contract test pins schema<->endpoint agreement
- one ordered playbook skill replaces the three authoring skills; overlay embeds only the playbook (getting-started stays harness-forced); concrete query_spans verify recipe; approval stops on trigger creation
- sweep script extended to rewrite committed old-slug skill embeds

Claude-Session: https://claude.ai/code/session_014iPB7HL5PjgT9npyPHaFMT
- PlatformOp handler mode (method+path XOR handler), to_call/to_call_ref, allowlist
- resolver emits callRef + contextBindings + timeoutMs specs, flag-gated OFF (AGENTA_AGENT_ENABLE_PLATFORM_HANDLERS) until the runner half lands
- /tools/call reserved-ref registry: registered refs dispatch, unknown fail loud 404
- tools-domain handler: hydrate revision (delta requires EDIT_WORKFLOWS, fetch-and-fail target validation), headless invoke via signed secret, spans-confirmed digest, terminal-result-wins verdict, recursion marker, 120s ceiling
- test_run NOT in the overlay yet (5b flips it with the runner dispatch)

Claude-Session: https://claude.ai/code/session_014iPB7HL5PjgT9npyPHaFMT
Aligns the inline data.revision path with reference hydration; live-verified (fresh-app test_run: failed(model-auth) -> 200).

Claude-Session: https://claude.ai/code/session_014iPB7HL5PjgT9npyPHaFMT
- Move the TestRun* contracts to core/tools/dtos.py and the PlatformToolHandler* exceptions to core/tools/exceptions.py (base ToolsError); platform_handlers.py keeps only orchestration + the registry.
- Block test_run deltas outside the parameters tree (url/uri/headers could redirect the server-side child invoke).
- Accumulate per-tool error flags across repeated calls; regression test.
- Surface infra failures (timeout/5xx/no output) as STATUS_CODE_ERROR on the outer ToolResult; business verdicts stay OK.
- Move the delta->EDIT_WORKFLOWS elevation policy onto the handler registration; the router dispatcher stays generic.
- Reject context_bindings on direct-call specs; exact-match the handler call_ref allowlist.
- Public StaticWorkflowCatalog.list_slugs(); overlay + tests stop importing the private dict.
- overlay.py also carries a concurrently-authored builtin-grants hunk (AGENTA_FORCED_TOOLS) adapting the template to Pi builtin gating; kept as-is.

Claude-Session: https://claude.ai/code/session_014iPB7HL5PjgT9npyPHaFMT
@mmabrouk
mmabrouk force-pushed the docs/build-kit-tools-cleanup branch 2 times, most recently from 7a97f8b to 5929758 Compare July 5, 2026 13:55
@mmabrouk
mmabrouk force-pushed the docs/build-kit-tools-cleanup branch from 5929758 to 7a97f8b Compare July 5, 2026 14:04
@mmabrouk
mmabrouk force-pushed the feat/build-kit-tools-cleanup branch from 6e52d57 to 3f20371 Compare July 5, 2026 14:04
@mmabrouk
mmabrouk changed the base branch from docs/build-kit-tools-cleanup to big-agents July 5, 2026 14:05
@mmabrouk
mmabrouk marked this pull request as ready for review July 5, 2026 14:05
@mmabrouk
mmabrouk merged commit 1756d3d into big-agents Jul 5, 2026
16 of 17 checks passed
@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend enhancement New feature or request SDK 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