Skip to content

SDK: per-tool capture overrides (inputValues/outputValues/intent) + warn-once for tracking calls outside a wrapped tool #74

Description

@marselsel

Ready to implement. Spec: .specs/sdk/per-tool-capture.md (committed in #78). The spec is the source of truth; the comments below are review history.

Task

withYavio() gains per-tool overrides of the capture flags, merged over the global capture config, so a tool with sensitive input can stay on the proxy instead of being registered outside it:

withYavio(server, {
  capture: { inputValues: true, outputValues: true },
  tools: { "book-contract": { inputValues: false, outputValues: false, intent: false } },
});

Why: registering outside the proxy is the only option today, and it loses the tool_call event and silently turns yavio.conversion() / track() / step() / identify() into no-ops — createYavioContext() has no fallback store. Measured on Commerce for Agents: 46 conversions from a proxied tool, 0 from the unwrapped booking tool, no warning anywhere.

Decisions (final — these supersede anything in the review comments)

  1. Reuse YAVIO-1105 (SDK.CONTEXT_INJECTION_UNAVAILABLE, already defined and unused) for the warn-once. Do not mint a new code. Its catalog text in .specs/07_error-catalog.md is wrong ("will lack traceId and sessionId") and must be corrected to say the event is dropped.
  2. intent: false is a third controller state, not just "ineligible": never advertise context, never capture it, but still strip it when a client sends one from a cached schema — otherwise a strict Zod schema rejects the call.
  3. Cross-spec rule with SDK/shared/ingest: tool results with isError: true must count as errors (status error, category tool_error) #75: with outputValues: false, keep status and error_category but drop the result-derived error_message. That text is output, and a handler echoing "postal code 12345 invalid" would leak the very input the override exists to hide. The thrown-path message stays (developer-written).
  4. Client meta stays coupled to inputValues deliberately. Decoupling would silently start collecting subject_id/locale/country_code for existing integrators who set inputValues: false as their privacy posture. That is a collection expansion needing its own opt-in decision, not a refactor.
  5. Docs: 02-sdk/02-tracking-api.mdx currently documents the silent drop as intended and must change too, not only the README.

Acceptance

  • ToolCaptureOverride + WithYavioOptions.tools + .yaviorc.json tools (no env-var form)
  • resolveToolCapture(name) applied in both interceptors (tool() and registerTool(), MCP SDK and Skybridge conventions)
  • inputValues:false drops input_keys/input_types/input_values and client meta, on success and throw
  • intent:false third state, incl. the strict-schema strip test
  • Warn-once YAVIO-1105 + corrected catalog text
  • Tests per the spec's Tests section (config, proxy, intent integration, context)
  • README + docs pages updated

Independent of #75; both target @yavio/sdk 0.4.0. Additive, no behaviour change without tools.

Follow-up once shipped: migrate Commerce for Agents (book-contract onto the proxy with the override, drop the "unwrapped server" invariant, verify with scripts/analytics-funnel.mjs --book — conversion present, PII grep 0 hits).

Activity

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

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions