Skip to content

design: define cfa-tool to external SDK adapter mapping (eve / claude) #42

Description

@beogip

Problem & Motivation

We want cfa-tool to sit as a framework on top of the existing SDKs (Vercel eve / Claude Agent SDK), not as an SDK that competes with them. A tool is written in cfa-tool from the start and chooses which SDK it targets (eve / claude / none). Layers are a cfa-tool concept the SDK never sees. To emit a cfa-tool tool to a target SDK we must translate the cfa result (layer + error envelope) into that SDK's return format, but the mapping is OPEN and unresolved. This issue is a DESIGN-DECISION task: its deliverable is a written design decision, not code. It is NOT ready to implement until the open decisions below are closed.

Scope & Decomposition

Produce a written design decision that closes the open mapping, sufficient to open a follow-up implementation issue with no arbitrary choices. No code in this issue.

Verified SDK reference (against official docs, not memory):

  • Claude Agent SDK (@anthropic-ai/claude-agent-sdk): tool() + createSdkMcpServer(); the handler returns a CallToolResult with content (required, array of typed blocks), structuredContent (optional, Record<string,unknown>), isError (optional). Two error paths with different semantics: an uncaught throw stops the agent loop (the query fails); isError: true lets the model see the error as data and retry. No native error taxonomy, no native subcommands. Source: code.claude.com/docs/en/agent-sdk.
  • eve (Vercel, package eve v0.13.0, beta): defineTool (one file per tool); execute(input, ctx) returns a plain domain object; optional outputSchema and optional toModelOutput(output) which returns {type:'text'|'json', value} to project what the model sees; no ok convention, no documented error taxonomy, no subcommands. Source: vercel.com/docs/eve + repo vercel/eve.

Acceptance Criteria

This issue is done when each open decision below is decided and documented.

OPEN DECISIONS (resolve when the task is picked up):

  • Layer collapse: if the SDK never sees layers, what does cfa-tool emit as the successful result? Both SDKs have a projection mechanism (structuredContent in claude, toModelOutput in eve). Decide: does each layer (L1/L2/L3) map to a distinct shape using those mechanisms, or do all three flatten to the same format and the layer become purely internal/documentation at the SDK boundary? (The answer changes the value of layers when targeting an SDK.)
  • Error translation: cfa's rich error { ok: false, error, message, detail } vs claude's isError flag + content (and the throw that stops the loop), and eve's lack of a documented error taxonomy. How is the envelope translated without losing cfa's taxonomy?
  • ok: true/ok: false <-> claude isError: near 1:1 mapping, the only one that maps cleanly. Confirm and document.
  • Subcommand exposure: no SDK has a native slot. How are subcommands exposed to the SDK? (Non-exhaustive candidates from the docs: one tool per subcommand; a single tool with an enum action param; in eve, multiple tool files / subagents / skills. The axis and the chosen option are open.)
  • none target: confirm it is the current jsonOutput behavior (pure JSON, no adaptation).
  • The result is a written design decision sufficient to open an implementation issue with no arbitrary decisions.

Risks & Constraints

Implementing before closing the open mapping injects arbitrary decisions the cfa pattern did not choose. Coupling cfa-tool to the eve/claude APIs (which change; eve is beta v0.13.0) adds maintenance.
[inferred] SDK references are pinned to current versions; revalidate the Claude Agent SDK (unpinned docs) and eve (v0.13.0, beta) before locking the mapping, since their return contracts may shift.

Edge Cases

[inferred] An error raised after partial layer output (e.g. L3 instructions already built) must still produce a coherent SDK error result; decide which path (claude isError vs throw) is used so the loop is not silently killed.
[inferred] The none target must remain the default passthrough so existing tools keep emitting pure JSON unchanged.

Out of Scope

  • The cfa-tool layer model and error model themselves (already exist / separate spec).
  • Implementing the adapter (this issue only closes the design).

Source: design session 2026-06-22, spec docs/specs/proposal-sdk-adapter-layer.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiquestionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions