Skip to content

Epic: a third-party backend or tool renderer can do what the first-party ones do using supported API #1345

Open
2 of 17 issues completed

Description

@schlessera

Outcome

The agent-backend and tool-renderer seams, both on the sanctioned seam list, are expressible by an implementation outside this repo: no closed union names the first-party backends, no backend-specific helper sits in a public entry, and first-party renderers use the same ToolCallView contract a third party gets.

Why now

Found by the 2026-10-09 code-quality review of main @ 0c69e0cb. The backend toolkit ruling (docs/decisions/backend-authoring-toolkit.md, #535) and the export boundary (docs/decisions/public-export-boundary.md, #534) settled what is public and what is first-party sharing. Three things still contradict the seam promise:

  • BridgeToolAdapter/ToolAdapter = "claude" | "pi" is a closed union in a public entry (packages/ui-sdk/src/tool-contracts/contract.ts:23), consumed by ui-react (packages/ui-react/src/lib/tool-names.ts).
  • Backend-specific helpers still live in the SDK and reach backends through /internal. The mask-file naming helpers (claudeMaskFilename, piMaskFilename and their reported-path pairs, packages/ui-sdk/src/server/bridge-tools/mask.ts:408-442) are no longer in a public entry — only packages/ui-sdk/src/internal.ts:12 exports them — but the host and each backend import them, so their home is a host-plus-one-backend question (ui-sdk: classify the SDK helpers that only the host and one backend import #2772), not a public-removal task.
  • Built-in renderers cast ToolCallView back to an internal type (packages/ui-react/src/components/chat/renderers/claude-tools.tsx:45, pi-tools.tsx:27, generic.tsx:20) and forward to switch (tool.name) blocks (packages/ui-react/src/components/chat/tool-views.tsx:129, :182, :237, :421).

Shared context

Constraints and non-goals

  • No new seam; the wire protocol stays non-pluggable.
  • Changing a public type is a contract change and, if it removes a name, breaking with a maintainer ruling first.

Breakdown

Native children retain their own implementation and proof boundaries. The original third-backend id, renderer-contract, single-backend ownership and internal-import gate tasks remain. Already delivered #1397/#1399 supply the module/toolkit foundations.

The later repository review attached #2489 (shared worker-host API), #2490 (bridge availability), #2491 (application policy), #2492 (shared configuration/state-room rules) and #2538 (third-id parent-effect authority). Each directly advances the external-backend/toolkit outcome; their current briefs, actual dependencies and recorded reproductions govern delivery. These are already native children, not new attachments in this pass.

#1374 split, 2026-10-24: #1374 keeps pi web-search ownership; its other ruled families are #2770 (geo alias removal, breaking) and #2771 (SDK→render-template link policy, dropping SDK→ui-kit). The host-plus-one-backend helpers that decision 3 left "internal pending #1374" are classified by the 2026-10-24 ruling on #2772: public experimental SDK spawn/timeout helpers and backend-owned public mask helpers consumed through the loaded backend module (A/A/B); implementation remains open. #1372 now moves only the Claude-only bashCommand and loadedSdkIdentity.

Coordinated maintainer amendment, 2026-10-22: #2489 selects supported experimental APIs for all 41 shared worker-host helpers in the server-only runtime package extracted by #2528 under #2541 (working name @schlessera/brain-ui-worker). This amends the owning package for that set; existing public SDK toolkit APIs remain supported. Both first-party and third-party authors use the same supported runtime primitives, with no internal exception, duplicate SDK aliases or SDK-to-worker reverse dependency. #2489 consumes #2528 after #2530; no reverse implementation blocker or reparenting is selected. Durable toolkit/export-boundary amendments remain implementation deliverables.

The October 9 ruling above remains historical context for the earlier SDK toolkit set. A recorded choice is not delivered API or conformance proof. Keep this epic without agent-ready.

Definition of done

A test-only third backend id and a test-only renderer compile and pass conformance using only public entry points.

2026-10-24: corrected the baseline claim that the mask helpers ship in public /server (they are internal-only and a host-plus-one-backend question, #2772), recorded #1374's split into #2770, #2771 and #2772, and moved the dated triage notes to a comment.

2026-10-24 triage at main af6300478a07379178bd30221a31c0b917df2283: Refreshed moved current-source pointers by inspecting their named anchors. Historical receipts retain their source identities; scope, rulings, priorities and outstanding prerequisites are preserved. No runtime result or readiness is inferred from this navigation repair.

2026-10-24 maintainer reconciliation: #1400 now permits exported brain-common/internal/* as shared infrastructure without a compatibility promise; extensions still use public APIs of every other package. #2772 selects A/A/B as above. These amend the earlier pending boundaries; they do not claim implementation or epic completion.

Activity

  1. added
    type: refactorStructure changes; behaviour does not. No changeset-visible effect.
    area: ui-sdkWire protocol, runtime schemas, the server and client SDK surfaces.
    area: ui-reactReact chat/files/voice components, stores, WebSocket transport.
    area: backendsAgentBackend implementations and the seam they share.
    priority: p2Wanted, not scheduled. Pulled in when a milestone has room.
    epicA tracking issue. The work lives in its sub-issues; this one is never coded directly.
    on Oct 9, 2026
  2. 6 remaining items

  3. schlessera commented on Oct 13, 2026

    @schlessera
    OwnerAuthor

    2026-10-13 triage: refreshed the current source pointers against 857ab01d1; preserved immutable historical evidence and all existing prerequisites. No completed outcome is inferred from moved code.

  4. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    2026-10-22 triage at main aa8c896: folded the later native children and coordinated #2489/#2528 owning-package rulings into the active breakdown. Verified the current closed ToolAdapter union, adapter-specific mask helpers and renderer casts still exist. Existing public toolkit guarantees, child dependencies, priorities and no epic readiness remain; no package extraction, public API delivery or third-party runtime conformance is claimed.

  5. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    2026-10-22 triage at 0332f1f093d6d3fdc8fe83465eb762d6e90c3650: verified claudeMaskFilename and piMaskFilename and corrected its moved source anchor after #2619. Preserved the brief, labels, native parent, assignment, release attribution and all original proof limits; no new runtime result.

  6. schlessera commented on Oct 24, 2026

    @schlessera
    OwnerAuthor

    Dated notes removed from the epic body on 2026-10-24, kept here verbatim as history:

    2026-10-09: folded in the maintainer rulings on /internal and the shared-file copies.

    2026-10-10 triage at main 7e398dc207f2c4725f6c364331c3cd5d3112954d: 1397 supported module entry is delivered by1466/a4120ed2, and1399 public backend toolkit by1461/02fd0b94. Current source exports those supported entry/toolkit surfaces;1396 common helpers were delivered separately. Remaining single-backend ownership, internal-import gate/removal and third-party renderer/conformance outcomes retain their native tasks. New public exports do not prove the entire third-party outcome. This triage inspected landed source/ancestry and current issue receipts, not a fresh test suite or independent automatic-main CI audit. Native child lists retain progress; epic readiness remains absent.

    2026-10-10 triage at main 0fff240b6167390276e141ff9aaf06e927289ea2: Refreshed runBackendContract to its actual named complete suite; no conformance criterion is removed.

    2026-10-13 source reconciliation at main 857ab01d1f9cb591f928755f5be516ab7f73338e: refreshed named current-source anchors after governed-flow integration. Historical receipts, scope and remaining prerequisites are unchanged; source inspection supplies no new runtime proof.

    2026-10-20 triage at main af0547c2d4d197ed3766f2817cf56eb5f0486ab4: refreshed the four active switch (tool.name) pointers after verifying the renderer casts and current switch anchors. The public toolkit/extension rulings, native children and complete third-party conformance outcome are unchanged. No new runtime proof or epic completion is claimed.

    2026-10-22 triage at main aa8c896: folded the later native children and coordinated #2489/#2528 owning-package rulings into the active breakdown. Verified the current closed ToolAdapter union, adapter-specific mask helpers and renderer casts still exist. Existing public toolkit guarantees, child dependencies, priorities and no epic readiness remain; no package extraction, public API delivery or third-party runtime conformance is claimed.

    2026-10-22 source navigation at main 0332f1f093d6d3fdc8fe83465eb762d6e90c3650: refreshed the moved citation for claudeMaskFilename and piMaskFilename after #2619. Scope, unresolved prerequisites and original runtime evidence are unchanged; source inspection is not a reproduction or repair.

    2026-10-24 correction: the body's baseline said claudeMaskFilename and piMaskFilename ship in public /server. They do not: only packages/ui-sdk/src/internal.ts:12 exports them, and packages/ui-sdk/tests/backend-toolkit.test.ts:22-28 asserts the ordinary entries exclude them. The host imports both (packages/ui-server/src/brain/mask-application.ts:6), so their home is the host-plus-one-backend question decision 3 left pending; that is now #2772. #1374 was split into #1374 (web-search), #2770 (geo), #2771 (link policy) and #2772.

  7. schlessera commented on Oct 24, 2026

    @schlessera
    OwnerAuthor

    2026-10-24 triage at main af6300478a07379178bd30221a31c0b917df2283: Refreshed moved current-source pointers by inspecting their named anchors. Historical receipts retain their source identities; scope, rulings, priorities and outstanding prerequisites are preserved. No runtime result or readiness is inferred from this navigation repair.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: backendsAgentBackend implementations and the seam they share.area: ui-reactReact chat/files/voice components, stores, WebSocket transport.area: ui-sdkWire protocol, runtime schemas, the server and client SDK surfaces.epicA tracking issue. The work lives in its sub-issues; this one is never coded directly.priority: p2Wanted, not scheduled. Pulled in when a milestone has room.type: refactorStructure changes; behaviour does not. No changeset-visible effect.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions