@yolk-sdk/agent 0.0.1-canary.9 → 0.1.0-canary.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +924 -34
- package/dist/background-execution-internal.d.mts +8 -0
- package/dist/background-execution-internal.d.mts.map +1 -0
- package/dist/background-execution-internal.mjs +8 -0
- package/dist/background-execution-internal.mjs.map +1 -0
- package/dist/classification/errors.d.mts +57 -0
- package/dist/classification/errors.d.mts.map +1 -0
- package/dist/classification/errors.mjs +56 -0
- package/dist/classification/errors.mjs.map +1 -0
- package/dist/classification/index.d.mts +4 -0
- package/dist/classification/index.mjs +4 -0
- package/dist/classification/model.d.mts +74 -0
- package/dist/classification/model.d.mts.map +1 -0
- package/dist/classification/model.mjs +136 -0
- package/dist/classification/model.mjs.map +1 -0
- package/dist/classification/schema.d.mts +172 -0
- package/dist/classification/schema.d.mts.map +1 -0
- package/dist/classification/schema.mjs +104 -0
- package/dist/classification/schema.mjs.map +1 -0
- package/dist/client/attachments.d.mts +10 -0
- package/dist/client/attachments.d.mts.map +1 -0
- package/dist/client/attachments.mjs +58 -0
- package/dist/client/attachments.mjs.map +1 -0
- package/dist/client/index.d.mts +4 -3
- package/dist/client/index.mjs +4 -3
- package/dist/client/state.d.mts +452 -5
- package/dist/client/state.d.mts.map +1 -1
- package/dist/client/state.mjs +221 -172
- package/dist/client/state.mjs.map +1 -1
- package/dist/client/transport.d.mts +54 -20
- package/dist/client/transport.d.mts.map +1 -1
- package/dist/client/transport.mjs +487 -58
- package/dist/client/transport.mjs.map +1 -1
- package/dist/compaction/budget.d.mts +22 -0
- package/dist/compaction/budget.d.mts.map +1 -0
- package/dist/compaction/budget.mjs +23 -0
- package/dist/compaction/budget.mjs.map +1 -0
- package/dist/compaction/checkpoint.d.mts +25 -0
- package/dist/compaction/checkpoint.d.mts.map +1 -0
- package/dist/compaction/checkpoint.mjs +34 -0
- package/dist/compaction/checkpoint.mjs.map +1 -0
- package/dist/compaction/estimator.d.mts +21 -0
- package/dist/compaction/estimator.d.mts.map +1 -0
- package/dist/compaction/estimator.mjs +22 -0
- package/dist/compaction/estimator.mjs.map +1 -0
- package/dist/compaction/index.d.mts +8 -0
- package/dist/compaction/index.mjs +8 -0
- package/dist/compaction/retry.d.mts +142 -0
- package/dist/compaction/retry.d.mts.map +1 -0
- package/dist/compaction/retry.mjs +43 -0
- package/dist/compaction/retry.mjs.map +1 -0
- package/dist/compaction/summary.d.mts +26 -0
- package/dist/compaction/summary.d.mts.map +1 -0
- package/dist/compaction/summary.mjs +59 -0
- package/dist/compaction/summary.mjs.map +1 -0
- package/dist/compaction/transformer.d.mts +21 -0
- package/dist/compaction/transformer.d.mts.map +1 -0
- package/dist/compaction/transformer.mjs +24 -0
- package/dist/compaction/transformer.mjs.map +1 -0
- package/dist/compaction/window.d.mts +184 -0
- package/dist/compaction/window.d.mts.map +1 -0
- package/dist/compaction/window.mjs +75 -0
- package/dist/compaction/window.mjs.map +1 -0
- package/dist/loop/accumulator.d.mts +4 -2
- package/dist/loop/accumulator.d.mts.map +1 -1
- package/dist/loop/accumulator.mjs +39 -25
- package/dist/loop/accumulator.mjs.map +1 -1
- package/dist/loop/collect.d.mts +38 -0
- package/dist/loop/collect.d.mts.map +1 -0
- package/dist/loop/collect.mjs +94 -0
- package/dist/loop/collect.mjs.map +1 -0
- package/dist/loop/error.d.mts +7 -3
- package/dist/loop/error.d.mts.map +1 -1
- package/dist/loop/error.mjs +49 -46
- package/dist/loop/error.mjs.map +1 -1
- package/dist/loop/index.d.mts +7 -5
- package/dist/loop/index.mjs +5 -3
- package/dist/loop/layer.d.mts +17 -0
- package/dist/loop/layer.d.mts.map +1 -0
- package/dist/loop/layer.mjs +15 -0
- package/dist/loop/layer.mjs.map +1 -0
- package/dist/loop/llm-event.d.mts.map +1 -1
- package/dist/loop/llm-event.mjs.map +1 -1
- package/dist/loop/run.d.mts +49 -6
- package/dist/loop/run.d.mts.map +1 -1
- package/dist/loop/run.mjs +407 -175
- package/dist/loop/run.mjs.map +1 -1
- package/dist/loop/services/llm-provider.d.mts +3 -0
- package/dist/loop/services/llm-provider.d.mts.map +1 -1
- package/dist/loop/services/llm-provider.mjs.map +1 -1
- package/dist/loop/services/loop-config.d.mts +4 -4
- package/dist/loop/services/loop-config.d.mts.map +1 -1
- package/dist/loop/services/loop-config.mjs +1 -1
- package/dist/loop/services/loop-config.mjs.map +1 -1
- package/dist/loop/services/tool-executor.d.mts +16 -5
- package/dist/loop/services/tool-executor.d.mts.map +1 -1
- package/dist/loop/services/tool-executor.mjs +11 -3
- package/dist/loop/services/tool-executor.mjs.map +1 -1
- package/dist/loop/testing/faux-provider.d.mts.map +1 -1
- package/dist/loop/testing/faux-provider.mjs +1 -1
- package/dist/loop/testing/faux-provider.mjs.map +1 -1
- package/dist/oauth/error.d.mts +15 -0
- package/dist/oauth/error.d.mts.map +1 -0
- package/dist/oauth/error.mjs +19 -0
- package/dist/oauth/error.mjs.map +1 -0
- package/dist/oauth/index.d.mts +4 -0
- package/dist/oauth/index.mjs +4 -0
- package/dist/oauth/source.d.mts +19 -0
- package/dist/oauth/source.d.mts.map +1 -0
- package/dist/oauth/source.mjs +12 -0
- package/dist/oauth/source.mjs.map +1 -0
- package/dist/oauth/token.d.mts +30 -0
- package/dist/oauth/token.d.mts.map +1 -0
- package/dist/oauth/token.mjs +27 -0
- package/dist/oauth/token.mjs.map +1 -0
- package/dist/protocol/bounded-text.d.mts +20 -0
- package/dist/protocol/bounded-text.d.mts.map +1 -0
- package/dist/protocol/bounded-text.mjs +48 -0
- package/dist/protocol/bounded-text.mjs.map +1 -0
- package/dist/protocol/content.d.mts +58 -30
- package/dist/protocol/content.d.mts.map +1 -1
- package/dist/protocol/content.mjs +140 -90
- package/dist/protocol/content.mjs.map +1 -1
- package/dist/protocol/event.d.mts +98 -9
- package/dist/protocol/event.d.mts.map +1 -1
- package/dist/protocol/event.mjs +245 -78
- package/dist/protocol/event.mjs.map +1 -1
- package/dist/protocol/index.d.mts +8 -6
- package/dist/protocol/index.d.mts.map +1 -1
- package/dist/protocol/index.mjs +9 -7
- package/dist/protocol/message.d.mts +129 -25
- package/dist/protocol/message.d.mts.map +1 -1
- package/dist/protocol/message.mjs +153 -23
- package/dist/protocol/message.mjs.map +1 -1
- package/dist/protocol/nested-tool-calls.d.mts +116 -0
- package/dist/protocol/nested-tool-calls.d.mts.map +1 -0
- package/dist/protocol/nested-tool-calls.mjs +143 -0
- package/dist/protocol/nested-tool-calls.mjs.map +1 -0
- package/dist/protocol/reasoning.d.mts.map +1 -1
- package/dist/protocol/reasoning.mjs.map +1 -1
- package/dist/protocol/session.d.mts +19 -5
- package/dist/protocol/session.d.mts.map +1 -1
- package/dist/protocol/session.mjs +17 -3
- package/dist/protocol/session.mjs.map +1 -1
- package/dist/protocol/tool-argument-hints.d.mts +12 -0
- package/dist/protocol/tool-argument-hints.d.mts.map +1 -0
- package/dist/protocol/tool-argument-hints.mjs +60 -0
- package/dist/protocol/tool-argument-hints.mjs.map +1 -0
- package/dist/protocol/tool.d.mts +851 -64
- package/dist/protocol/tool.d.mts.map +1 -1
- package/dist/protocol/tool.mjs +593 -41
- package/dist/protocol/tool.mjs.map +1 -1
- package/dist/protocol/usage.mjs +11 -11
- package/dist/protocol/usage.mjs.map +1 -1
- package/dist/providers/anthropic/claude-provider.d.mts +84 -0
- package/dist/providers/anthropic/claude-provider.d.mts.map +1 -0
- package/dist/providers/anthropic/claude-provider.mjs +9 -0
- package/dist/providers/anthropic/claude-provider.mjs.map +1 -0
- package/dist/providers/anthropic/claude.d.mts +55 -0
- package/dist/providers/anthropic/claude.d.mts.map +1 -0
- package/dist/providers/anthropic/claude.mjs +96 -0
- package/dist/providers/anthropic/claude.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/cases.d.mts +50 -0
- package/dist/providers/anthropic/conformance/cases.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/cases.mjs +248 -0
- package/dist/providers/anthropic/conformance/cases.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/claude-usage-cases.d.mts +27 -0
- package/dist/providers/anthropic/conformance/claude-usage-cases.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/claude-usage-cases.mjs +55 -0
- package/dist/providers/anthropic/conformance/claude-usage-cases.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/claude-usage-snapshot.d.mts +14 -0
- package/dist/providers/anthropic/conformance/claude-usage-snapshot.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/claude-usage-snapshot.mjs +33 -0
- package/dist/providers/anthropic/conformance/claude-usage-snapshot.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/error-envelope.d.mts +15 -0
- package/dist/providers/anthropic/conformance/error-envelope.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/error-envelope.mjs +51 -0
- package/dist/providers/anthropic/conformance/error-envelope.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/index.d.mts +18 -0
- package/dist/providers/anthropic/conformance/index.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/index.mjs +23 -0
- package/dist/providers/anthropic/conformance/index.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/max-tokens.d.mts +15 -0
- package/dist/providers/anthropic/conformance/max-tokens.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/max-tokens.mjs +60 -0
- package/dist/providers/anthropic/conformance/max-tokens.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/plain-text.d.mts +17 -0
- package/dist/providers/anthropic/conformance/plain-text.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/plain-text.mjs +63 -0
- package/dist/providers/anthropic/conformance/plain-text.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/thinking-before-text.d.mts +16 -0
- package/dist/providers/anthropic/conformance/thinking-before-text.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/thinking-before-text.mjs +70 -0
- package/dist/providers/anthropic/conformance/thinking-before-text.mjs.map +1 -0
- package/dist/providers/anthropic/conformance/tool-use-input-deltas.d.mts +17 -0
- package/dist/providers/anthropic/conformance/tool-use-input-deltas.d.mts.map +1 -0
- package/dist/providers/anthropic/conformance/tool-use-input-deltas.mjs +79 -0
- package/dist/providers/anthropic/conformance/tool-use-input-deltas.mjs.map +1 -0
- package/dist/providers/anthropic/index.d.mts +2 -0
- package/dist/providers/anthropic/index.mjs +2 -0
- package/dist/providers/anthropic/usage.d.mts +21 -0
- package/dist/providers/anthropic/usage.d.mts.map +1 -0
- package/dist/providers/anthropic/usage.mjs +76 -0
- package/dist/providers/anthropic/usage.mjs.map +1 -0
- package/dist/providers/anthropic-messages-provider-internal.d.mts +22 -0
- package/dist/providers/anthropic-messages-provider-internal.d.mts.map +1 -0
- package/dist/providers/anthropic-messages-provider-internal.mjs +71 -0
- package/dist/providers/anthropic-messages-provider-internal.mjs.map +1 -0
- package/dist/providers/anthropic-provider-internal.d.mts +89 -0
- package/dist/providers/anthropic-provider-internal.d.mts.map +1 -0
- package/dist/providers/anthropic-provider-internal.mjs +1006 -0
- package/dist/providers/anthropic-provider-internal.mjs.map +1 -0
- package/dist/providers/openai/codex-provider.d.mts +82 -0
- package/dist/providers/openai/codex-provider.d.mts.map +1 -0
- package/dist/providers/openai/codex-provider.mjs +58 -0
- package/dist/providers/openai/codex-provider.mjs.map +1 -0
- package/dist/providers/openai/codex-usage.d.mts +21 -0
- package/dist/providers/openai/codex-usage.d.mts.map +1 -0
- package/dist/providers/openai/codex-usage.mjs +87 -0
- package/dist/providers/openai/codex-usage.mjs.map +1 -0
- package/dist/providers/openai/codex.d.mts +52 -0
- package/dist/providers/openai/codex.d.mts.map +1 -0
- package/dist/providers/openai/codex.mjs +53 -0
- package/dist/providers/openai/codex.mjs.map +1 -0
- package/dist/providers/openai/conformance/cases.d.mts +36 -0
- package/dist/providers/openai/conformance/cases.d.mts.map +1 -0
- package/dist/providers/openai/conformance/cases.mjs +165 -0
- package/dist/providers/openai/conformance/cases.mjs.map +1 -0
- package/dist/providers/openai/conformance/codex-cases.d.mts +37 -0
- package/dist/providers/openai/conformance/codex-cases.d.mts.map +1 -0
- package/dist/providers/openai/conformance/codex-cases.mjs +64 -0
- package/dist/providers/openai/conformance/codex-cases.mjs.map +1 -0
- package/dist/providers/openai/conformance/codex-error-envelope.d.mts +13 -0
- package/dist/providers/openai/conformance/codex-error-envelope.d.mts.map +1 -0
- package/dist/providers/openai/conformance/codex-error-envelope.mjs +50 -0
- package/dist/providers/openai/conformance/codex-error-envelope.mjs.map +1 -0
- package/dist/providers/openai/conformance/codex-function-call-arguments.d.mts +13 -0
- package/dist/providers/openai/conformance/codex-function-call-arguments.d.mts.map +1 -0
- package/dist/providers/openai/conformance/codex-function-call-arguments.mjs +79 -0
- package/dist/providers/openai/conformance/codex-function-call-arguments.mjs.map +1 -0
- package/dist/providers/openai/conformance/codex-plain-text.d.mts +13 -0
- package/dist/providers/openai/conformance/codex-plain-text.d.mts.map +1 -0
- package/dist/providers/openai/conformance/codex-plain-text.mjs +70 -0
- package/dist/providers/openai/conformance/codex-plain-text.mjs.map +1 -0
- package/dist/providers/openai/conformance/codex-terminal-event.d.mts +13 -0
- package/dist/providers/openai/conformance/codex-terminal-event.d.mts.map +1 -0
- package/dist/providers/openai/conformance/codex-terminal-event.mjs +67 -0
- package/dist/providers/openai/conformance/codex-terminal-event.mjs.map +1 -0
- package/dist/providers/openai/conformance/codex-usage-cases.d.mts +28 -0
- package/dist/providers/openai/conformance/codex-usage-cases.d.mts.map +1 -0
- package/dist/providers/openai/conformance/codex-usage-cases.mjs +55 -0
- package/dist/providers/openai/conformance/codex-usage-cases.mjs.map +1 -0
- package/dist/providers/openai/conformance/codex-usage-snapshot.d.mts +15 -0
- package/dist/providers/openai/conformance/codex-usage-snapshot.d.mts.map +1 -0
- package/dist/providers/openai/conformance/codex-usage-snapshot.mjs +34 -0
- package/dist/providers/openai/conformance/codex-usage-snapshot.mjs.map +1 -0
- package/dist/providers/openai/conformance/error-envelope.d.mts +14 -0
- package/dist/providers/openai/conformance/error-envelope.d.mts.map +1 -0
- package/dist/providers/openai/conformance/error-envelope.mjs +50 -0
- package/dist/providers/openai/conformance/error-envelope.mjs.map +1 -0
- package/dist/providers/openai/conformance/index.d.mts +24 -0
- package/dist/providers/openai/conformance/index.d.mts.map +1 -0
- package/dist/providers/openai/conformance/index.mjs +33 -0
- package/dist/providers/openai/conformance/index.mjs.map +1 -0
- package/dist/providers/openai/conformance/json-plain-text.d.mts +14 -0
- package/dist/providers/openai/conformance/json-plain-text.d.mts.map +1 -0
- package/dist/providers/openai/conformance/json-plain-text.mjs +49 -0
- package/dist/providers/openai/conformance/json-plain-text.mjs.map +1 -0
- package/dist/providers/openai/conformance/plain-text.d.mts +15 -0
- package/dist/providers/openai/conformance/plain-text.d.mts.map +1 -0
- package/dist/providers/openai/conformance/plain-text.mjs +60 -0
- package/dist/providers/openai/conformance/plain-text.mjs.map +1 -0
- package/dist/providers/openai/conformance/responses-cases-internal.d.mts +40 -0
- package/dist/providers/openai/conformance/responses-cases-internal.d.mts.map +1 -0
- package/dist/providers/openai/conformance/responses-cases-internal.mjs +271 -0
- package/dist/providers/openai/conformance/responses-cases-internal.mjs.map +1 -0
- package/dist/providers/openai/conformance/subscription-usage-cases-internal.d.mts +37 -0
- package/dist/providers/openai/conformance/subscription-usage-cases-internal.d.mts.map +1 -0
- package/dist/providers/openai/conformance/subscription-usage-cases-internal.mjs +85 -0
- package/dist/providers/openai/conformance/subscription-usage-cases-internal.mjs.map +1 -0
- package/dist/providers/openai/conformance/tool-call-deltas.d.mts +15 -0
- package/dist/providers/openai/conformance/tool-call-deltas.d.mts.map +1 -0
- package/dist/providers/openai/conformance/tool-call-deltas.mjs +77 -0
- package/dist/providers/openai/conformance/tool-call-deltas.mjs.map +1 -0
- package/dist/providers/openai/index.d.mts +2 -0
- package/dist/providers/openai/index.mjs +2 -0
- package/dist/providers/openai/provider.d.mts +121 -0
- package/dist/providers/openai/provider.d.mts.map +1 -0
- package/dist/providers/openai/provider.mjs +793 -0
- package/dist/providers/openai/provider.mjs.map +1 -0
- package/dist/providers/openai/realtime/client-codec.d.mts +18 -0
- package/dist/providers/openai/realtime/client-codec.d.mts.map +1 -0
- package/dist/providers/openai/realtime/client-codec.mjs +52 -0
- package/dist/providers/openai/realtime/client-codec.mjs.map +1 -0
- package/dist/providers/openai/realtime/events.d.mts +131 -0
- package/dist/providers/openai/realtime/events.d.mts.map +1 -0
- package/dist/providers/openai/realtime/events.mjs +213 -0
- package/dist/providers/openai/realtime/events.mjs.map +1 -0
- package/dist/providers/openai/realtime/index.d.mts +5 -0
- package/dist/providers/openai/realtime/index.mjs +5 -0
- package/dist/providers/openai/realtime/session-config.d.mts +96 -0
- package/dist/providers/openai/realtime/session-config.d.mts.map +1 -0
- package/dist/providers/openai/realtime/session-config.mjs +181 -0
- package/dist/providers/openai/realtime/session-config.mjs.map +1 -0
- package/dist/providers/openai/realtime/to-voice.d.mts +14 -0
- package/dist/providers/openai/realtime/to-voice.d.mts.map +1 -0
- package/dist/providers/openai/realtime/to-voice.mjs +44 -0
- package/dist/providers/openai/realtime/to-voice.mjs.map +1 -0
- package/dist/providers/openai/speech.d.mts +35 -0
- package/dist/providers/openai/speech.d.mts.map +1 -0
- package/dist/providers/openai/speech.mjs +132 -0
- package/dist/providers/openai/speech.mjs.map +1 -0
- package/dist/providers/openai-responses-provider-internal.d.mts +128 -0
- package/dist/providers/openai-responses-provider-internal.d.mts.map +1 -0
- package/dist/providers/openai-responses-provider-internal.mjs +708 -0
- package/dist/providers/openai-responses-provider-internal.mjs.map +1 -0
- package/dist/providers/opencode/conformance/cases.d.mts +47 -0
- package/dist/providers/opencode/conformance/cases.d.mts.map +1 -0
- package/dist/providers/opencode/conformance/cases.mjs +208 -0
- package/dist/providers/opencode/conformance/cases.mjs.map +1 -0
- package/dist/providers/opencode/conformance/chat-plain-text.d.mts +13 -0
- package/dist/providers/opencode/conformance/chat-plain-text.d.mts.map +1 -0
- package/dist/providers/opencode/conformance/chat-plain-text.mjs +58 -0
- package/dist/providers/opencode/conformance/chat-plain-text.mjs.map +1 -0
- package/dist/providers/opencode/conformance/index.d.mts +14 -0
- package/dist/providers/opencode/conformance/index.d.mts.map +1 -0
- package/dist/providers/opencode/conformance/index.mjs +19 -0
- package/dist/providers/opencode/conformance/index.mjs.map +1 -0
- package/dist/providers/opencode/conformance/messages-plain-text.d.mts +13 -0
- package/dist/providers/opencode/conformance/messages-plain-text.d.mts.map +1 -0
- package/dist/providers/opencode/conformance/messages-plain-text.mjs +60 -0
- package/dist/providers/opencode/conformance/messages-plain-text.mjs.map +1 -0
- package/dist/providers/opencode/conformance/responses-commentary-replay.d.mts +13 -0
- package/dist/providers/opencode/conformance/responses-commentary-replay.d.mts.map +1 -0
- package/dist/providers/opencode/conformance/responses-commentary-replay.mjs +89 -0
- package/dist/providers/opencode/conformance/responses-commentary-replay.mjs.map +1 -0
- package/dist/providers/opencode/conformance/responses-plain-text.d.mts +13 -0
- package/dist/providers/opencode/conformance/responses-plain-text.d.mts.map +1 -0
- package/dist/providers/opencode/conformance/responses-plain-text.mjs +60 -0
- package/dist/providers/opencode/conformance/responses-plain-text.mjs.map +1 -0
- package/dist/providers/opencode/conformance/usage-snapshot.d.mts +13 -0
- package/dist/providers/opencode/conformance/usage-snapshot.d.mts.map +1 -0
- package/dist/providers/opencode/conformance/usage-snapshot.mjs +32 -0
- package/dist/providers/opencode/conformance/usage-snapshot.mjs.map +1 -0
- package/dist/providers/opencode/go-provider.d.mts +21 -0
- package/dist/providers/opencode/go-provider.d.mts.map +1 -0
- package/dist/providers/opencode/go-provider.mjs +87 -0
- package/dist/providers/opencode/go-provider.mjs.map +1 -0
- package/dist/providers/opencode/usage.d.mts +22 -0
- package/dist/providers/opencode/usage.d.mts.map +1 -0
- package/dist/providers/opencode/usage.mjs +75 -0
- package/dist/providers/opencode/usage.mjs.map +1 -0
- package/dist/providers/provider-error.d.mts +35 -0
- package/dist/providers/provider-error.d.mts.map +1 -0
- package/dist/providers/provider-error.mjs +99 -0
- package/dist/providers/provider-error.mjs.map +1 -0
- package/dist/providers/subscription-usage-internal.d.mts +26 -0
- package/dist/providers/subscription-usage-internal.d.mts.map +1 -0
- package/dist/providers/subscription-usage-internal.mjs +62 -0
- package/dist/providers/subscription-usage-internal.mjs.map +1 -0
- package/dist/providers/subscription-usage.d.mts +49 -0
- package/dist/providers/subscription-usage.d.mts.map +1 -0
- package/dist/providers/subscription-usage.mjs +58 -0
- package/dist/providers/subscription-usage.mjs.map +1 -0
- package/dist/providers/transcript.d.mts +9 -0
- package/dist/providers/transcript.d.mts.map +1 -0
- package/dist/providers/transcript.mjs +13 -0
- package/dist/providers/transcript.mjs.map +1 -0
- package/dist/providers/vercel/ai-gateway-classifier.d.mts +45 -0
- package/dist/providers/vercel/ai-gateway-classifier.d.mts.map +1 -0
- package/dist/providers/vercel/ai-gateway-classifier.mjs +253 -0
- package/dist/providers/vercel/ai-gateway-classifier.mjs.map +1 -0
- package/dist/providers/vercel/ai-gateway-credential-internal.d.mts +12 -0
- package/dist/providers/vercel/ai-gateway-credential-internal.d.mts.map +1 -0
- package/dist/providers/vercel/ai-gateway-credential-internal.mjs +12 -0
- package/dist/providers/vercel/ai-gateway-credential-internal.mjs.map +1 -0
- package/dist/providers/vercel/ai-gateway-provider.d.mts +52 -0
- package/dist/providers/vercel/ai-gateway-provider.d.mts.map +1 -0
- package/dist/providers/vercel/ai-gateway-provider.mjs +56 -0
- package/dist/providers/vercel/ai-gateway-provider.mjs.map +1 -0
- package/dist/providers/vercel/conformance/cases.d.mts +41 -0
- package/dist/providers/vercel/conformance/cases.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/cases.mjs +182 -0
- package/dist/providers/vercel/conformance/cases.mjs.map +1 -0
- package/dist/providers/vercel/conformance/classifier-boolean.d.mts +13 -0
- package/dist/providers/vercel/conformance/classifier-boolean.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/classifier-boolean.mjs +48 -0
- package/dist/providers/vercel/conformance/classifier-boolean.mjs.map +1 -0
- package/dist/providers/vercel/conformance/classifier-cases.d.mts +32 -0
- package/dist/providers/vercel/conformance/classifier-cases.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/classifier-cases.mjs +193 -0
- package/dist/providers/vercel/conformance/classifier-cases.mjs.map +1 -0
- package/dist/providers/vercel/conformance/classifier-choice.d.mts +16 -0
- package/dist/providers/vercel/conformance/classifier-choice.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/classifier-choice.mjs +55 -0
- package/dist/providers/vercel/conformance/classifier-choice.mjs.map +1 -0
- package/dist/providers/vercel/conformance/classifier-error-envelope.d.mts +13 -0
- package/dist/providers/vercel/conformance/classifier-error-envelope.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/classifier-error-envelope.mjs +48 -0
- package/dist/providers/vercel/conformance/classifier-error-envelope.mjs.map +1 -0
- package/dist/providers/vercel/conformance/classifier-score.d.mts +16 -0
- package/dist/providers/vercel/conformance/classifier-score.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/classifier-score.mjs +56 -0
- package/dist/providers/vercel/conformance/classifier-score.mjs.map +1 -0
- package/dist/providers/vercel/conformance/deepseek-reasoning.d.mts +13 -0
- package/dist/providers/vercel/conformance/deepseek-reasoning.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/deepseek-reasoning.mjs +64 -0
- package/dist/providers/vercel/conformance/deepseek-reasoning.mjs.map +1 -0
- package/dist/providers/vercel/conformance/error-envelope.d.mts +13 -0
- package/dist/providers/vercel/conformance/error-envelope.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/error-envelope.mjs +49 -0
- package/dist/providers/vercel/conformance/error-envelope.mjs.map +1 -0
- package/dist/providers/vercel/conformance/index.d.mts +20 -0
- package/dist/providers/vercel/conformance/index.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/index.mjs +29 -0
- package/dist/providers/vercel/conformance/index.mjs.map +1 -0
- package/dist/providers/vercel/conformance/plain-text.d.mts +13 -0
- package/dist/providers/vercel/conformance/plain-text.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/plain-text.mjs +53 -0
- package/dist/providers/vercel/conformance/plain-text.mjs.map +1 -0
- package/dist/providers/vercel/conformance/tool-call-deltas.d.mts +13 -0
- package/dist/providers/vercel/conformance/tool-call-deltas.d.mts.map +1 -0
- package/dist/providers/vercel/conformance/tool-call-deltas.mjs +63 -0
- package/dist/providers/vercel/conformance/tool-call-deltas.mjs.map +1 -0
- package/dist/providers/xai/conformance/cases.d.mts +43 -0
- package/dist/providers/xai/conformance/cases.d.mts.map +1 -0
- package/dist/providers/xai/conformance/cases.mjs +70 -0
- package/dist/providers/xai/conformance/cases.mjs.map +1 -0
- package/dist/providers/xai/conformance/error-envelope.d.mts +14 -0
- package/dist/providers/xai/conformance/error-envelope.d.mts.map +1 -0
- package/dist/providers/xai/conformance/error-envelope.mjs +48 -0
- package/dist/providers/xai/conformance/error-envelope.mjs.map +1 -0
- package/dist/providers/xai/conformance/function-call-arguments.d.mts +14 -0
- package/dist/providers/xai/conformance/function-call-arguments.d.mts.map +1 -0
- package/dist/providers/xai/conformance/function-call-arguments.mjs +70 -0
- package/dist/providers/xai/conformance/function-call-arguments.mjs.map +1 -0
- package/dist/providers/xai/conformance/index.d.mts +17 -0
- package/dist/providers/xai/conformance/index.d.mts.map +1 -0
- package/dist/providers/xai/conformance/index.mjs +21 -0
- package/dist/providers/xai/conformance/index.mjs.map +1 -0
- package/dist/providers/xai/conformance/plain-text.d.mts +14 -0
- package/dist/providers/xai/conformance/plain-text.d.mts.map +1 -0
- package/dist/providers/xai/conformance/plain-text.mjs +61 -0
- package/dist/providers/xai/conformance/plain-text.mjs.map +1 -0
- package/dist/providers/xai/conformance/terminal-event.d.mts +14 -0
- package/dist/providers/xai/conformance/terminal-event.d.mts.map +1 -0
- package/dist/providers/xai/conformance/terminal-event.mjs +59 -0
- package/dist/providers/xai/conformance/terminal-event.mjs.map +1 -0
- package/dist/providers/xai/conformance/usage-cases.d.mts +29 -0
- package/dist/providers/xai/conformance/usage-cases.d.mts.map +1 -0
- package/dist/providers/xai/conformance/usage-cases.mjs +81 -0
- package/dist/providers/xai/conformance/usage-cases.mjs.map +1 -0
- package/dist/providers/xai/conformance/usage-snapshot.d.mts +15 -0
- package/dist/providers/xai/conformance/usage-snapshot.d.mts.map +1 -0
- package/dist/providers/xai/conformance/usage-snapshot.mjs +34 -0
- package/dist/providers/xai/conformance/usage-snapshot.mjs.map +1 -0
- package/dist/providers/xai/grok-provider.d.mts +85 -0
- package/dist/providers/xai/grok-provider.d.mts.map +1 -0
- package/dist/providers/xai/grok-provider.mjs +35 -0
- package/dist/providers/xai/grok-provider.mjs.map +1 -0
- package/dist/providers/xai/grok.d.mts +60 -0
- package/dist/providers/xai/grok.d.mts.map +1 -0
- package/dist/providers/xai/grok.mjs +104 -0
- package/dist/providers/xai/grok.mjs.map +1 -0
- package/dist/providers/xai/index.d.mts +2 -0
- package/dist/providers/xai/index.mjs +2 -0
- package/dist/providers/xai/usage.d.mts +23 -0
- package/dist/providers/xai/usage.d.mts.map +1 -0
- package/dist/providers/xai/usage.mjs +134 -0
- package/dist/providers/xai/usage.mjs.map +1 -0
- package/dist/react/chat-actions.d.mts +418 -0
- package/dist/react/chat-actions.d.mts.map +1 -0
- package/dist/react/chat-actions.mjs +12 -0
- package/dist/react/chat-actions.mjs.map +1 -0
- package/dist/react/chat-core.d.mts +95 -0
- package/dist/react/chat-core.d.mts.map +1 -0
- package/dist/react/chat-core.mjs +170 -0
- package/dist/react/chat-core.mjs.map +1 -0
- package/dist/react/chat-items.d.mts +781 -0
- package/dist/react/chat-items.d.mts.map +1 -0
- package/dist/react/chat-items.mjs +179 -0
- package/dist/react/chat-items.mjs.map +1 -0
- package/dist/react/chat-messages.d.mts +821 -0
- package/dist/react/chat-messages.d.mts.map +1 -0
- package/dist/react/chat-messages.mjs +679 -0
- package/dist/react/chat-messages.mjs.map +1 -0
- package/dist/react/chat-session-events.d.mts +33 -0
- package/dist/react/chat-session-events.d.mts.map +1 -0
- package/dist/react/chat-session-events.mjs +29 -0
- package/dist/react/chat-session-events.mjs.map +1 -0
- package/dist/react/index.d.mts +7 -0
- package/dist/react/index.mjs +7 -0
- package/dist/react/use-agent-chat.d.mts +98 -0
- package/dist/react/use-agent-chat.d.mts.map +1 -0
- package/dist/react/use-agent-chat.mjs +245 -0
- package/dist/react/use-agent-chat.mjs.map +1 -0
- package/dist/runtime/error.d.mts.map +1 -1
- package/dist/runtime/error.mjs +25 -36
- package/dist/runtime/error.mjs.map +1 -1
- package/dist/runtime/index.d.mts +1 -1
- package/dist/runtime/index.d.mts.map +1 -1
- package/dist/runtime/index.mjs +2 -2
- package/dist/runtime/run-runtime.d.mts +150 -20
- package/dist/runtime/run-runtime.d.mts.map +1 -1
- package/dist/runtime/run-runtime.mjs +26 -35
- package/dist/runtime/run-runtime.mjs.map +1 -1
- package/dist/runtime/session-event-store.d.mts +19 -19
- package/dist/runtime/session-event-store.d.mts.map +1 -1
- package/dist/runtime/session-event-store.mjs +28 -56
- package/dist/runtime/session-event-store.mjs.map +1 -1
- package/dist/skillset/command.d.mts +53 -0
- package/dist/skillset/command.d.mts.map +1 -0
- package/dist/skillset/command.mjs +137 -0
- package/dist/skillset/command.mjs.map +1 -0
- package/dist/skillset/errors.d.mts +13 -0
- package/dist/skillset/errors.d.mts.map +1 -0
- package/dist/skillset/errors.mjs +18 -0
- package/dist/skillset/errors.mjs.map +1 -0
- package/dist/skillset/index.d.mts +8 -0
- package/dist/skillset/index.mjs +8 -0
- package/dist/skillset/manifest.d.mts +33 -0
- package/dist/skillset/manifest.d.mts.map +1 -0
- package/dist/skillset/manifest.mjs +18 -0
- package/dist/skillset/manifest.mjs.map +1 -0
- package/dist/skillset/markdown.d.mts +17 -0
- package/dist/skillset/markdown.d.mts.map +1 -0
- package/dist/skillset/markdown.mjs +41 -0
- package/dist/skillset/markdown.mjs.map +1 -0
- package/dist/skillset/merge.d.mts +42 -0
- package/dist/skillset/merge.d.mts.map +1 -0
- package/dist/skillset/merge.mjs +32 -0
- package/dist/skillset/merge.mjs.map +1 -0
- package/dist/skillset/name.d.mts +10 -0
- package/dist/skillset/name.d.mts.map +1 -0
- package/dist/skillset/name.mjs +18 -0
- package/dist/skillset/name.mjs.map +1 -0
- package/dist/skillset/skill.d.mts +30 -0
- package/dist/skillset/skill.d.mts.map +1 -0
- package/dist/skillset/skill.mjs +47 -0
- package/dist/skillset/skill.mjs.map +1 -0
- package/dist/tools/arguments.d.mts +40 -0
- package/dist/tools/arguments.d.mts.map +1 -0
- package/dist/tools/arguments.mjs +364 -0
- package/dist/tools/arguments.mjs.map +1 -0
- package/dist/tools/background.d.mts +37 -0
- package/dist/tools/background.d.mts.map +1 -0
- package/dist/tools/background.mjs +130 -0
- package/dist/tools/background.mjs.map +1 -0
- package/dist/tools/index.d.mts +11 -4
- package/dist/tools/index.mjs +10 -4
- package/dist/tools/input.d.mts +41 -0
- package/dist/tools/input.d.mts.map +1 -0
- package/dist/tools/input.mjs +85 -0
- package/dist/tools/input.mjs.map +1 -0
- package/dist/tools/interaction.d.mts +55 -0
- package/dist/tools/interaction.d.mts.map +1 -0
- package/dist/tools/interaction.mjs +139 -0
- package/dist/tools/interaction.mjs.map +1 -0
- package/dist/tools/ledger.d.mts +452 -0
- package/dist/tools/ledger.d.mts.map +1 -0
- package/dist/tools/ledger.mjs +471 -0
- package/dist/tools/ledger.mjs.map +1 -0
- package/dist/tools/question.d.mts +1 -1
- package/dist/tools/question.d.mts.map +1 -1
- package/dist/tools/question.mjs +4 -3
- package/dist/tools/question.mjs.map +1 -1
- package/dist/tools/registry.d.mts +176 -17
- package/dist/tools/registry.d.mts.map +1 -1
- package/dist/tools/registry.mjs +489 -52
- package/dist/tools/registry.mjs.map +1 -1
- package/dist/tools/sha256.d.mts +6 -0
- package/dist/tools/sha256.d.mts.map +1 -0
- package/dist/tools/sha256.mjs +138 -0
- package/dist/tools/sha256.mjs.map +1 -0
- package/dist/tools/subagent.d.mts +102 -0
- package/dist/tools/subagent.d.mts.map +1 -0
- package/dist/tools/subagent.mjs +332 -0
- package/dist/tools/subagent.mjs.map +1 -0
- package/dist/voice/browser/index.d.mts +2 -0
- package/dist/voice/browser/index.mjs +2 -0
- package/dist/voice/browser/webrtc.d.mts +72 -0
- package/dist/voice/browser/webrtc.d.mts.map +1 -0
- package/dist/voice/browser/webrtc.mjs +163 -0
- package/dist/voice/browser/webrtc.mjs.map +1 -0
- package/dist/voice/client-codec.d.mts +18 -0
- package/dist/voice/client-codec.d.mts.map +1 -0
- package/dist/voice/client-codec.mjs +1 -0
- package/dist/voice/controller.d.mts +55 -0
- package/dist/voice/controller.d.mts.map +1 -0
- package/dist/voice/controller.mjs +120 -0
- package/dist/voice/controller.mjs.map +1 -0
- package/dist/voice/index.d.mts +13 -0
- package/dist/voice/index.mjs +12 -0
- package/dist/voice/outbox.d.mts +40 -0
- package/dist/voice/outbox.d.mts.map +1 -0
- package/dist/voice/outbox.mjs +71 -0
- package/dist/voice/outbox.mjs.map +1 -0
- package/dist/voice/projection.d.mts +103 -0
- package/dist/voice/projection.d.mts.map +1 -0
- package/dist/voice/projection.mjs +196 -0
- package/dist/voice/projection.mjs.map +1 -0
- package/dist/voice/protocol.d.mts +217 -0
- package/dist/voice/protocol.d.mts.map +1 -0
- package/dist/voice/protocol.mjs +197 -0
- package/dist/voice/protocol.mjs.map +1 -0
- package/dist/voice/react.d.mts +56 -0
- package/dist/voice/react.d.mts.map +1 -0
- package/dist/voice/react.mjs +226 -0
- package/dist/voice/react.mjs.map +1 -0
- package/dist/voice/session-log.d.mts +77 -0
- package/dist/voice/session-log.d.mts.map +1 -0
- package/dist/voice/session-log.mjs +137 -0
- package/dist/voice/session-log.mjs.map +1 -0
- package/dist/voice/session.d.mts +56 -0
- package/dist/voice/session.d.mts.map +1 -0
- package/dist/voice/session.mjs +48 -0
- package/dist/voice/session.mjs.map +1 -0
- package/dist/voice/speech.d.mts +70 -0
- package/dist/voice/speech.d.mts.map +1 -0
- package/dist/voice/speech.mjs +57 -0
- package/dist/voice/speech.mjs.map +1 -0
- package/dist/voice/tool-bridge.d.mts +24 -0
- package/dist/voice/tool-bridge.d.mts.map +1 -0
- package/dist/voice/tool-bridge.mjs +46 -0
- package/dist/voice/tool-bridge.mjs.map +1 -0
- package/dist/voice/tool-server.d.mts +111 -0
- package/dist/voice/tool-server.d.mts.map +1 -0
- package/dist/voice/tool-server.mjs +88 -0
- package/dist/voice/tool-server.mjs.map +1 -0
- package/dist/voice/transport.d.mts +19 -0
- package/dist/voice/transport.d.mts.map +1 -0
- package/dist/voice/transport.mjs +7 -0
- package/dist/voice/transport.mjs.map +1 -0
- package/dist/voice/websocket.d.mts +30 -0
- package/dist/voice/websocket.d.mts.map +1 -0
- package/dist/voice/websocket.mjs +79 -0
- package/dist/voice/websocket.mjs.map +1 -0
- package/package.json +177 -3
- package/src/background-execution-internal.ts +10 -0
- package/src/classification/errors.ts +79 -0
- package/src/classification/index.ts +53 -0
- package/src/classification/model.ts +270 -0
- package/src/classification/schema.ts +154 -0
- package/src/client/README.md +13 -0
- package/src/client/attachments.ts +85 -0
- package/src/client/index.ts +27 -8
- package/src/client/state.ts +585 -169
- package/src/client/transport.ts +975 -123
- package/src/compaction/budget.ts +55 -0
- package/src/compaction/checkpoint.ts +69 -0
- package/src/compaction/estimator.ts +91 -0
- package/src/compaction/index.ts +92 -0
- package/src/compaction/retry.ts +167 -0
- package/src/compaction/summary.ts +214 -0
- package/src/compaction/transformer.ts +55 -0
- package/src/compaction/window.ts +191 -0
- package/src/loop/README.md +15 -0
- package/src/loop/accumulator.ts +75 -26
- package/src/loop/collect.ts +268 -0
- package/src/loop/error.ts +64 -34
- package/src/loop/index.ts +40 -3
- package/src/loop/layer.ts +32 -0
- package/src/loop/llm-event.ts +1 -0
- package/src/loop/run.ts +871 -254
- package/src/loop/services/llm-provider.ts +3 -0
- package/src/loop/services/loop-config.ts +4 -4
- package/src/loop/services/tool-executor.ts +31 -6
- package/src/loop/testing/faux-provider.ts +2 -0
- package/src/loop/testing/index.ts +2 -0
- package/src/oauth/error.ts +18 -0
- package/src/oauth/index.ts +14 -0
- package/src/oauth/source.ts +36 -0
- package/src/oauth/token.ts +31 -0
- package/src/protocol/README.md +1 -1
- package/src/protocol/bounded-text.ts +78 -0
- package/src/protocol/content.ts +241 -77
- package/src/protocol/event.ts +357 -23
- package/src/protocol/index.ts +158 -3
- package/src/protocol/message.ts +318 -6
- package/src/protocol/nested-tool-calls.ts +261 -0
- package/src/protocol/reasoning.ts +1 -0
- package/src/protocol/session.ts +31 -2
- package/src/protocol/tool-argument-hints.ts +113 -0
- package/src/protocol/tool.ts +1265 -17
- package/src/providers/anthropic/claude-provider.ts +96 -0
- package/src/providers/anthropic/claude.ts +154 -0
- package/src/providers/anthropic/conformance/cases.ts +467 -0
- package/src/providers/anthropic/conformance/claude-usage-cases.ts +85 -0
- package/src/providers/anthropic/conformance/claude-usage-snapshot.ts +36 -0
- package/src/providers/anthropic/conformance/error-envelope.ts +56 -0
- package/src/providers/anthropic/conformance/index.ts +89 -0
- package/src/providers/anthropic/conformance/max-tokens.ts +65 -0
- package/src/providers/anthropic/conformance/plain-text.ts +68 -0
- package/src/providers/anthropic/conformance/thinking-before-text.ts +75 -0
- package/src/providers/anthropic/conformance/tool-use-input-deltas.ts +90 -0
- package/src/providers/anthropic/index.ts +21 -0
- package/src/providers/anthropic/usage.ts +175 -0
- package/src/providers/anthropic-messages-provider-internal.ts +147 -0
- package/src/providers/anthropic-provider-internal.ts +2103 -0
- package/src/providers/openai/codex-provider.ts +236 -0
- package/src/providers/openai/codex-usage.ts +213 -0
- package/src/providers/openai/codex.ts +85 -0
- package/src/providers/openai/conformance/cases.ts +290 -0
- package/src/providers/openai/conformance/codex-cases.ts +103 -0
- package/src/providers/openai/conformance/codex-error-envelope.ts +53 -0
- package/src/providers/openai/conformance/codex-function-call-arguments.ts +88 -0
- package/src/providers/openai/conformance/codex-plain-text.ts +73 -0
- package/src/providers/openai/conformance/codex-terminal-event.ts +70 -0
- package/src/providers/openai/conformance/codex-usage-cases.ts +87 -0
- package/src/providers/openai/conformance/codex-usage-snapshot.ts +37 -0
- package/src/providers/openai/conformance/error-envelope.ts +56 -0
- package/src/providers/openai/conformance/index.ts +126 -0
- package/src/providers/openai/conformance/json-plain-text.ts +53 -0
- package/src/providers/openai/conformance/plain-text.ts +66 -0
- package/src/providers/openai/conformance/responses-cases-internal.ts +580 -0
- package/src/providers/openai/conformance/subscription-usage-cases-internal.ts +199 -0
- package/src/providers/openai/conformance/tool-call-deltas.ts +91 -0
- package/src/providers/openai/index.ts +19 -0
- package/src/providers/openai/provider.ts +1892 -0
- package/src/providers/openai/realtime/client-codec.ts +84 -0
- package/src/providers/openai/realtime/events.ts +371 -0
- package/src/providers/openai/realtime/index.ts +56 -0
- package/src/providers/openai/realtime/session-config.ts +394 -0
- package/src/providers/openai/realtime/to-voice.ts +75 -0
- package/src/providers/openai/speech.ts +276 -0
- package/src/providers/openai-responses-provider-internal.ts +1692 -0
- package/src/providers/opencode/conformance/cases.ts +372 -0
- package/src/providers/opencode/conformance/chat-plain-text.ts +64 -0
- package/src/providers/opencode/conformance/index.ts +63 -0
- package/src/providers/opencode/conformance/messages-plain-text.ts +65 -0
- package/src/providers/opencode/conformance/responses-commentary-replay.ts +96 -0
- package/src/providers/opencode/conformance/responses-plain-text.ts +63 -0
- package/src/providers/opencode/conformance/usage-snapshot.ts +35 -0
- package/src/providers/opencode/go-provider.ts +144 -0
- package/src/providers/opencode/usage.ts +159 -0
- package/src/providers/provider-error.ts +267 -0
- package/src/providers/subscription-usage-internal.ts +128 -0
- package/src/providers/subscription-usage.ts +97 -0
- package/src/providers/transcript.ts +20 -0
- package/src/providers/vercel/ai-gateway-classifier.ts +492 -0
- package/src/providers/vercel/ai-gateway-credential-internal.ts +10 -0
- package/src/providers/vercel/ai-gateway-provider.ts +157 -0
- package/src/providers/vercel/conformance/cases.ts +319 -0
- package/src/providers/vercel/conformance/classifier-boolean.ts +51 -0
- package/src/providers/vercel/conformance/classifier-cases.ts +333 -0
- package/src/providers/vercel/conformance/classifier-choice.ts +58 -0
- package/src/providers/vercel/conformance/classifier-error-envelope.ts +51 -0
- package/src/providers/vercel/conformance/classifier-score.ts +56 -0
- package/src/providers/vercel/conformance/deepseek-reasoning.ts +72 -0
- package/src/providers/vercel/conformance/error-envelope.ts +55 -0
- package/src/providers/vercel/conformance/index.ts +99 -0
- package/src/providers/vercel/conformance/plain-text.ts +59 -0
- package/src/providers/vercel/conformance/tool-call-deltas.ts +78 -0
- package/src/providers/xai/conformance/cases.ts +115 -0
- package/src/providers/xai/conformance/error-envelope.ts +51 -0
- package/src/providers/xai/conformance/function-call-arguments.ts +79 -0
- package/src/providers/xai/conformance/index.ts +81 -0
- package/src/providers/xai/conformance/plain-text.ts +64 -0
- package/src/providers/xai/conformance/terminal-event.ts +62 -0
- package/src/providers/xai/conformance/usage-cases.ts +145 -0
- package/src/providers/xai/conformance/usage-snapshot.ts +37 -0
- package/src/providers/xai/grok-provider.ts +138 -0
- package/src/providers/xai/grok.ts +171 -0
- package/src/providers/xai/index.ts +22 -0
- package/src/providers/xai/usage.ts +302 -0
- package/src/react/chat-actions.ts +33 -0
- package/src/react/chat-core.ts +419 -0
- package/src/react/chat-items.ts +446 -0
- package/src/react/chat-messages.ts +1990 -0
- package/src/react/chat-session-events.ts +48 -0
- package/src/react/index.ts +81 -0
- package/src/react/use-agent-chat.ts +472 -0
- package/src/runtime/error.ts +35 -36
- package/src/runtime/index.ts +6 -2
- package/src/runtime/run-runtime.ts +143 -101
- package/src/runtime/session-event-store.ts +42 -48
- package/src/skillset/command.ts +227 -0
- package/src/skillset/errors.ts +17 -0
- package/src/skillset/index.ts +29 -0
- package/src/skillset/manifest.ts +17 -0
- package/src/skillset/markdown.ts +75 -0
- package/src/skillset/merge.ts +61 -0
- package/src/skillset/name.ts +29 -0
- package/src/skillset/skill.ts +75 -0
- package/src/tools/README.md +222 -18
- package/src/tools/arguments.ts +743 -0
- package/src/tools/background.ts +214 -0
- package/src/tools/index.ts +115 -17
- package/src/tools/input.ts +197 -0
- package/src/tools/interaction.ts +365 -0
- package/src/tools/ledger.ts +1068 -0
- package/src/tools/question.ts +8 -3
- package/src/tools/registry.ts +1288 -81
- package/src/tools/sha256.ts +98 -0
- package/src/tools/subagent.ts +806 -0
- package/src/voice/browser/index.ts +14 -0
- package/src/voice/browser/webrtc.ts +341 -0
- package/src/voice/client-codec.ts +23 -0
- package/src/voice/controller.ts +318 -0
- package/src/voice/index.ts +128 -0
- package/src/voice/outbox.ts +165 -0
- package/src/voice/projection.ts +394 -0
- package/src/voice/protocol.ts +351 -0
- package/src/voice/react.ts +419 -0
- package/src/voice/session-log.ts +200 -0
- package/src/voice/session.ts +138 -0
- package/src/voice/speech.ts +100 -0
- package/src/voice/tool-bridge.ts +97 -0
- package/src/voice/tool-server.ts +182 -0
- package/src/voice/transport.ts +17 -0
- package/src/voice/websocket.ts +156 -0
- package/dist/tools/task.d.mts +0 -53
- package/dist/tools/task.d.mts.map +0 -1
- package/dist/tools/task.mjs +0 -110
- package/dist/tools/task.mjs.map +0 -1
- package/src/tools/task.ts +0 -200
package/README.md
CHANGED
|
@@ -1,49 +1,147 @@
|
|
|
1
1
|
# @yolk-sdk/agent
|
|
2
2
|
|
|
3
|
-
Domain-free agent protocol, loop, runtime, client, and
|
|
3
|
+
Domain-free agent protocol, loop, runtime, Effect-native client, compaction, classifier models, tools, React, providers, OAuth, skillset, and voice primitives.
|
|
4
4
|
|
|
5
|
-
Root export is intentionally
|
|
5
|
+
Root export is intentionally empty. Import feature APIs from explicit subpaths.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
pnpm add @yolk-sdk/agent@canary effect
|
|
10
|
+
pnpm add @yolk-sdk/agent@canary effect@4.0.0
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
Add `react` if you use `@yolk-sdk/agent/react` or `@yolk-sdk/agent/voice/react`.
|
|
14
|
+
|
|
15
|
+
Running the experimental `@yolk-sdk/agent/providers/*/conformance` cases? Also add `@yolk-sdk/conformance@canary` (usually as a dev dependency); the cases run through `@yolk-sdk/conformance/runner`.
|
|
16
|
+
|
|
13
17
|
Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
|
|
18
|
+
Use the SDK's matching Effect version (`4.0.0`) in host code.
|
|
19
|
+
Published package metadata requires Node.js 22+.
|
|
14
20
|
|
|
15
21
|
## Subpaths
|
|
16
22
|
|
|
17
|
-
| Subpath
|
|
18
|
-
|
|
|
19
|
-
| `@yolk-sdk/agent/protocol`
|
|
20
|
-
| `@yolk-sdk/agent/loop`
|
|
21
|
-
| `@yolk-sdk/agent/loop/testing`
|
|
22
|
-
| `@yolk-sdk/agent/runtime`
|
|
23
|
-
| `@yolk-sdk/agent/client`
|
|
24
|
-
| `@yolk-sdk/agent/
|
|
23
|
+
| Subpath | Purpose |
|
|
24
|
+
| -------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
25
|
+
| `@yolk-sdk/agent/protocol` | Wire messages, events, content, usage, tool schemas |
|
|
26
|
+
| `@yolk-sdk/agent/loop` | Stateless LLM/tool loop |
|
|
27
|
+
| `@yolk-sdk/agent/loop/testing` | Faux provider and tool executor test helpers |
|
|
28
|
+
| `@yolk-sdk/agent/runtime` | Transcript or append-backed runtime orchestration |
|
|
29
|
+
| `@yolk-sdk/agent/client` | HTTP/NDJSON transport, HITL resume, retry/error state helpers |
|
|
30
|
+
| `@yolk-sdk/agent/compaction` | Host-owned compaction budgets, checkpoints, formatting, retry |
|
|
31
|
+
| `@yolk-sdk/agent/classification` | Classifier model contract: typed questions, answers, usage, errors |
|
|
32
|
+
| `@yolk-sdk/agent/tools` | Tool registry, typed inputs, interactions, subagents/questions, durable tool ledger |
|
|
33
|
+
| `@yolk-sdk/agent/react` | Headless React chat hook, reducer, selectors, and render model |
|
|
34
|
+
| `@yolk-sdk/agent/oauth` | Provider-neutral OAuth token and broker contracts |
|
|
35
|
+
| `@yolk-sdk/agent/providers/openai` | OpenAI/Codex OAuth and broker helpers |
|
|
36
|
+
| `@yolk-sdk/agent/providers/openai/codex` | OpenAI Codex request and auth helpers |
|
|
37
|
+
| `@yolk-sdk/agent/providers/openai/codex-usage` | Codex subscription-allowance snapshots |
|
|
38
|
+
| `@yolk-sdk/agent/providers/openai/codex-provider` | Codex LLM provider factory |
|
|
39
|
+
| `@yolk-sdk/agent/providers/openai/provider` | OpenAI-compatible LLM provider factory |
|
|
40
|
+
| `@yolk-sdk/agent/providers/openai/conformance` | Synthetic OpenAI chat, Codex Responses, and Codex usage fixtures and conformance cases |
|
|
41
|
+
| `@yolk-sdk/agent/providers/openai/realtime` | OpenAI Realtime session config and event codecs |
|
|
42
|
+
| `@yolk-sdk/agent/providers/openai/speech` | OpenAI text-to-speech and transcription adapters |
|
|
43
|
+
| `@yolk-sdk/agent/providers/vercel/ai-gateway-provider` | Vercel AI Gateway Chat Completions provider factory |
|
|
44
|
+
| `@yolk-sdk/agent/providers/vercel/ai-gateway-classifier` | Vercel AI Gateway classifier (`POST /v1/evaluate`) layer |
|
|
45
|
+
| `@yolk-sdk/agent/providers/vercel/conformance` | Verified Gateway chat fixtures, synthetic classifier fixtures, and conformance cases |
|
|
46
|
+
| `@yolk-sdk/agent/providers/opencode/go-provider` | OpenCode Go Chat Completions, Messages, and Responses provider |
|
|
47
|
+
| `@yolk-sdk/agent/providers/opencode/usage` | OpenCode Go subscription-allowance snapshots |
|
|
48
|
+
| `@yolk-sdk/agent/providers/opencode/conformance` | Synthetic OpenCode Go (per protocol, commentary replay, usage) fixtures and conformance cases |
|
|
49
|
+
| `@yolk-sdk/agent/providers/anthropic` | Anthropic/Claude OAuth and broker helpers |
|
|
50
|
+
| `@yolk-sdk/agent/providers/anthropic/claude` | Claude request and auth helpers |
|
|
51
|
+
| `@yolk-sdk/agent/providers/anthropic/usage` | Claude subscription-allowance snapshots |
|
|
52
|
+
| `@yolk-sdk/agent/providers/anthropic/claude-provider` | Claude LLM provider factory |
|
|
53
|
+
| `@yolk-sdk/agent/providers/anthropic/conformance` | Synthetic Anthropic Messages and Claude usage fixtures and conformance cases |
|
|
54
|
+
| `@yolk-sdk/agent/providers/xai` | Grok subscription OAuth and token broker helpers |
|
|
55
|
+
| `@yolk-sdk/agent/providers/xai/grok` | Grok subscription request and auth helpers |
|
|
56
|
+
| `@yolk-sdk/agent/providers/xai/grok-provider` | Grok subscription LLM provider factory |
|
|
57
|
+
| `@yolk-sdk/agent/providers/xai/usage` | Grok subscription-allowance snapshots |
|
|
58
|
+
| `@yolk-sdk/agent/providers/xai/conformance` | Synthetic Grok Responses and Grok usage fixtures and conformance cases |
|
|
59
|
+
| `@yolk-sdk/agent/providers/subscription-usage` | Shared allowance snapshot and safe error schemas |
|
|
60
|
+
| `@yolk-sdk/agent/skillset` | Portable skill and slash-command parsing/catalogs |
|
|
61
|
+
| `@yolk-sdk/agent/voice` | Voice protocol, controller, tool handler, projection, speech |
|
|
62
|
+
| `@yolk-sdk/agent/voice/browser` | Browser WebRTC voice transport |
|
|
63
|
+
| `@yolk-sdk/agent/voice/react` | Headless browser voice React hook |
|
|
25
64
|
|
|
26
65
|
## Imports
|
|
27
66
|
|
|
28
67
|
```ts
|
|
29
|
-
import {
|
|
68
|
+
import {
|
|
69
|
+
danglingHostToolCalls,
|
|
70
|
+
hitlResponseEvent,
|
|
71
|
+
isTerminalAgentEvent,
|
|
72
|
+
makeSubagentRunId,
|
|
73
|
+
ProviderErrorInfo,
|
|
74
|
+
PlainHitlResponse,
|
|
75
|
+
questionResponseStructuredContent,
|
|
76
|
+
repairDanglingHostToolCalls,
|
|
77
|
+
UserMessage,
|
|
78
|
+
validateNoDanglingHostToolCalls
|
|
79
|
+
} from '@yolk-sdk/agent/protocol'
|
|
30
80
|
import { run } from '@yolk-sdk/agent/loop'
|
|
31
|
-
import { runRuntime } from '@yolk-sdk/agent/runtime'
|
|
32
|
-
import {
|
|
81
|
+
import { runRuntime, RuntimeRequest } from '@yolk-sdk/agent/runtime'
|
|
82
|
+
import {
|
|
83
|
+
documentPartFromTextFile,
|
|
84
|
+
initialAgentClientState,
|
|
85
|
+
streamAgentEventStreamUntilTerminal,
|
|
86
|
+
toolRunsFromHitlRequests
|
|
87
|
+
} from '@yolk-sdk/agent/client'
|
|
33
88
|
import {
|
|
34
|
-
|
|
35
|
-
|
|
89
|
+
makeContextBudget,
|
|
90
|
+
makePreviewSummaryMessage,
|
|
91
|
+
makeWindowCompactionTransformer
|
|
92
|
+
} from '@yolk-sdk/agent/compaction'
|
|
93
|
+
import {
|
|
94
|
+
makeInteractionTool,
|
|
95
|
+
makeNonRecursiveSubagentToolModule,
|
|
96
|
+
makeSubagentToolResult,
|
|
97
|
+
modelVisibleToolError,
|
|
98
|
+
modelVisibleToolErrorStructuredContent,
|
|
36
99
|
makeQuestionToolModule,
|
|
37
|
-
|
|
100
|
+
omitNullOptionalToolArguments,
|
|
101
|
+
resolveTools,
|
|
102
|
+
withToolArgumentsErrorHint
|
|
38
103
|
} from '@yolk-sdk/agent/tools'
|
|
104
|
+
import {
|
|
105
|
+
AgentChatAction,
|
|
106
|
+
AgentChatPart,
|
|
107
|
+
applyAgentEventToChatProjection,
|
|
108
|
+
makeAgentChatEventProjectionState,
|
|
109
|
+
useAgentChat
|
|
110
|
+
} from '@yolk-sdk/agent/react'
|
|
111
|
+
import { makeVercelAiGatewayProviderLayer } from '@yolk-sdk/agent/providers/vercel/ai-gateway-provider'
|
|
39
112
|
```
|
|
40
113
|
|
|
114
|
+
`RuntimeRequest` is a value on `@yolk-sdk/agent/runtime` (`Transcript`, `AppendInput`, `AppendHitlResponse`). Pass `RuntimeRequest.Transcript({ sessionId, messages })` into `runRuntime`. For append requests, omitted or `undefined` `expectedRevision` still means use the loaded log revision (`??`).
|
|
115
|
+
|
|
41
116
|
Test helpers live behind their own subpath:
|
|
42
117
|
|
|
43
118
|
```ts
|
|
44
119
|
import { FauxProvider, Reply, TestToolExecutor } from '@yolk-sdk/agent/loop/testing'
|
|
45
120
|
```
|
|
46
121
|
|
|
122
|
+
## Headless React chat
|
|
123
|
+
|
|
124
|
+
`useAgentChat` exposes protocol messages, render-oriented chat messages, run/error/waiting state,
|
|
125
|
+
and actions for submit, stop, edit, regenerate, delete, tool approval, question, and typed input responses. The
|
|
126
|
+
package supplies no components, styling, auth, or route ownership, and React remains an optional
|
|
127
|
+
peer used only by React subpaths.
|
|
128
|
+
|
|
129
|
+
Chat ADTs on `@yolk-sdk/agent/react` are value constructors: `AgentChatPart`, `ChatToolState`,
|
|
130
|
+
`DeleteChatTurnResult`, `EditChatUserMessageResult`, `RegenerateChatMessagesResult`, `AgentChatItem`,
|
|
131
|
+
`ToolRunState`, `AgentChatAction`, and hook results such as `AgentChatSubmitResult`. They are
|
|
132
|
+
`Data.taggedEnum` plain objects (`_tag` last), not Equal/Hash classes. Duration descriptors use
|
|
133
|
+
`ToolDurationKnown` / `ToolDurationUnknown` (`Schema.TaggedStruct.make` validates those plains).
|
|
134
|
+
Prefer `AgentChatPart.Text({ ... })` over handwritten `{ _tag: 'Text', ... }`, omit absent optionals,
|
|
135
|
+
and discriminate with `$is` (for example `AgentChatSubmitResult.$is('Submitted')(result)`).
|
|
136
|
+
`useAgentChat` dispatches `AgentChatAction` constructors and returns those hook-result values.
|
|
137
|
+
|
|
138
|
+
By default the hook streams HTTP/NDJSON through `@yolk-sdk/agent/client`. Pass an
|
|
139
|
+
`AgentChatTransport` through the `transport` option to use another runtime. A custom transport
|
|
140
|
+
receives the transcript, session/model options, HITL responses, and an `AbortSignal`, and returns an
|
|
141
|
+
`AsyncIterable<AgentEvent>`; the host still owns endpoint auth and persistence. Custom transport
|
|
142
|
+
rejections are normalized to `AgentTransportError` internally while retaining the original cause.
|
|
143
|
+
Native abort causes stop quietly; other non-Error rejections display `Agent request failed`.
|
|
144
|
+
|
|
47
145
|
## Quick start
|
|
48
146
|
|
|
49
147
|
```ts
|
|
@@ -61,6 +159,368 @@ const program = run({
|
|
|
61
159
|
// Provide LLM provider, loop config, context transformer, and tool executor layers in the host app.
|
|
62
160
|
```
|
|
63
161
|
|
|
162
|
+
Loop composition is those four Layers plus `run` / `runModelTurn` / `runToolBatch`.
|
|
163
|
+
Merge them with `makeAgentLoopLayer`. Omitted tools use `ToolExecutor.unavailable`; omitted transformer/config use identity and `LoopConfig.defaultLayer`.
|
|
164
|
+
Intercept by decorating a service (`decorateLLMProvider`), not with hooks.
|
|
165
|
+
Durable hosts fold model-turn steps with `collectModelTurn`. Use `collectModelTurnAttempt` when the fold must retain partial output after a failed stream. Kernel incomplete streams (zero `Done` events) set optional `LLMError.responseIssue: 'missing_done'` and stay `invalid_response` / `retryable: false`.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { makeAgentLoopLayer } from '@yolk-sdk/agent/loop'
|
|
169
|
+
import { FauxProvider, Reply } from '@yolk-sdk/agent/loop/testing'
|
|
170
|
+
|
|
171
|
+
const LoopLayer = makeAgentLoopLayer({
|
|
172
|
+
provider: FauxProvider.layer(Reply.text('ok'))
|
|
173
|
+
})
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Guide source: [Loop and runtime](https://github.com/magoz/yolk-sdk/blob/main/apps/docs/content/docs/agent/loop-runtime.mdx#compose-the-loop-layer).
|
|
177
|
+
|
|
178
|
+
## OAuth credentials
|
|
179
|
+
|
|
180
|
+
`@yolk-sdk/agent/oauth` defines provider-neutral access-token, broker, freshness, and credential-source
|
|
181
|
+
contracts. Provider subpaths add vendor request/response conversion without owning persistence.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import { credentialSourceFromBroker, type TokenBrokerClient } from '@yolk-sdk/agent/oauth'
|
|
185
|
+
|
|
186
|
+
const makeTokenProgram = (hostBroker: TokenBrokerClient) =>
|
|
187
|
+
credentialSourceFromBroker(hostBroker, {
|
|
188
|
+
provider: 'openai-codex',
|
|
189
|
+
subjectId: 'host-user-id'
|
|
190
|
+
}).getAccessToken({ minTtlSeconds: 300 })
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`hostBroker` is a host implementation of `TokenBrokerClient`. The host stores, refreshes, revokes,
|
|
194
|
+
and authorizes credentials; the package receives short-lived access tokens and never persists
|
|
195
|
+
secrets.
|
|
196
|
+
|
|
197
|
+
## Provider configuration
|
|
198
|
+
|
|
199
|
+
Provider output limits are host-owned when the endpoint supports them. Yolk does not infer model
|
|
200
|
+
limits or apply hidden fallbacks.
|
|
201
|
+
|
|
202
|
+
| Provider factory | Output-limit field |
|
|
203
|
+
| ---------------------------------- | --------------------- |
|
|
204
|
+
| `makeOpenAiProviderLayer` | `maxCompletionTokens` |
|
|
205
|
+
| `makeVercelAiGatewayProviderLayer` | `maxCompletionTokens` |
|
|
206
|
+
| `makeOpenCodeGoProviderLayer` | `maxOutputTokens` |
|
|
207
|
+
| `makeOpenAiCodexProviderLayer` | none |
|
|
208
|
+
| `makeAnthropicClaudeProviderLayer` | `maxTokens` |
|
|
209
|
+
| `makeXAiGrokProviderLayer` | `maxOutputTokens` |
|
|
210
|
+
|
|
211
|
+
The public `toOpenAiRequestBody`, `toAnthropicClaudeRequestBody`, and `toXAiGrokRequestBody` helpers
|
|
212
|
+
require the matching limit configuration. ChatGPT subscription Codex rejects vendor
|
|
213
|
+
`max_output_tokens`, so `makeOpenAiCodexProviderLayer` and `toOpenAiCodexRequestBody` ignore the
|
|
214
|
+
optional deprecated `maxOutputTokens` compatibility field. `OpenAiProviderLayer` reads both
|
|
215
|
+
`OPENAI_API_KEY` and integer `OPENAI_MAX_COMPLETION_TOKENS` through Effect Config.
|
|
216
|
+
|
|
217
|
+
OpenCode Go uses API-key authentication with an explicit host-selected `protocol`:
|
|
218
|
+
`chat-completions`, `messages`, or `responses`. Model IDs stay opaque: pass the Go API model ID
|
|
219
|
+
without OpenCode's `opencode-go/` CLI prefix. The SDK does not fetch a catalog or guess the protocol
|
|
220
|
+
from a model name. Check the [Go endpoint catalog](https://opencode.ai/docs/go/#endpoints).
|
|
221
|
+
|
|
222
|
+
Server-side configuration fragment (the host supplies credentials and model policy):
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { Layer, Redacted } from 'effect'
|
|
226
|
+
import { FetchHttpClient } from 'effect/http'
|
|
227
|
+
import { makeOpenCodeGoProviderLayer } from '@yolk-sdk/agent/providers/opencode/go-provider'
|
|
228
|
+
|
|
229
|
+
const GoLayer = makeOpenCodeGoProviderLayer({
|
|
230
|
+
apiKey: Redacted.make(hostOpenCodeGoApiKey),
|
|
231
|
+
protocol: 'messages',
|
|
232
|
+
maxOutputTokens: hostModelConfig.maxOutputTokens
|
|
233
|
+
}).pipe(Layer.provide(FetchHttpClient.layer))
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The default base URL is `https://opencode.ai/zen/go/v1`. Chat streams SSE (the Go adapter sets
|
|
237
|
+
`streaming: true`) with Bearer auth; Messages uses SSE and `x-api-key`; Responses uses SSE and Bearer
|
|
238
|
+
auth. All normalize to `LLMEvent`s.
|
|
239
|
+
Messages retains native tool names and system instructions, without Claude OAuth fingerprinting.
|
|
240
|
+
Responses sends `max_output_tokens`, unlike Codex. Go requires a nonempty key and positive safe-integer
|
|
241
|
+
limit at layer construction. `extraHeaders` cannot override required protocol headers, regardless of
|
|
242
|
+
case. Only override `baseUrl` with a trusted proxy because it receives the credential.
|
|
243
|
+
|
|
244
|
+
Request `reasoningEffort` becomes chat `reasoning_effort`, Messages `output_config.effort` (omitting
|
|
245
|
+
`minimal`), or Responses `reasoning.effort` with `summary: 'auto'`. `reasoningSummary` changes the
|
|
246
|
+
Responses summary mode. Hosts must offer only model-supported efforts and media capabilities.
|
|
247
|
+
Chat preserves provider `reasoning_content` in events and assistant replay. No OAuth, model discovery,
|
|
248
|
+
automatic polling, or example-app UI integration is included.
|
|
249
|
+
|
|
250
|
+
Read Go subscription allowance separately from per-request token usage (server-side fragment):
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { Effect, Redacted } from 'effect'
|
|
254
|
+
import { FetchHttpClient } from 'effect/http'
|
|
255
|
+
import { fetchOpenCodeGoSubscriptionUsage } from '@yolk-sdk/agent/providers/opencode/usage'
|
|
256
|
+
|
|
257
|
+
const usageEffect = fetchOpenCodeGoSubscriptionUsage(Redacted.make(hostOpenCodeGoApiKey), {
|
|
258
|
+
requestTimeoutMs: 10_000
|
|
259
|
+
}).pipe(Effect.provide(FetchHttpClient.layer))
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The API-key endpoint (default `openCodeGoSubscriptionUsageUrl`) returns used percentages/reset instants for `five-hour`, `seven-day`, and
|
|
263
|
+
`monthly` windows. Monthly resets follow the subscription's anniversary, not the first of the month;
|
|
264
|
+
the adapter preserves the provider's timestamp. Missing/invalid percentages are omitted, not treated
|
|
265
|
+
as zero. Treat snapshots as best-effort; hosts own polling, stale-data policy, persistence, and UI.
|
|
266
|
+
The fetcher blocks redirects and sanitizes failures using the shared subscription-usage error types.
|
|
267
|
+
|
|
268
|
+
Vercel AI Gateway uses its OpenAI-compatible Chat Completions endpoint, with a single JSON
|
|
269
|
+
completion by default. Native PDF `DocumentPart` inputs are lowered to Gateway file parts by
|
|
270
|
+
default; the selected Gateway model must advertise PDF input. Set factory option `streaming: true`
|
|
271
|
+
for SSE deltas and independently set `reasoningContent: true` to preserve compatible models'
|
|
272
|
+
`reasoning_content` output and assistant
|
|
273
|
+
replay. Both default to false; replayed reasoning spends input tokens. Pass either an AI
|
|
274
|
+
Gateway API key or Vercel OIDC token as `apiKey`; `maxCompletionTokens` is sent as Gateway
|
|
275
|
+
`max_tokens`. The env-backed `VercelAiGatewayProviderLayer` tries `AI_GATEWAY_API_KEY` first, then
|
|
276
|
+
`VERCEL_OIDC_TOKEN`, and requires integer
|
|
277
|
+
`AI_GATEWAY_MAX_COMPLETION_TOKENS`. Model ids are opaque `provider/model` strings. Hosts may set
|
|
278
|
+
`fallbackModels`, provider `routing`, and optional `http-referer` / `x-title` attribution headers.
|
|
279
|
+
A request `reasoningEffort` is sent as Gateway `{ reasoning: { effort } }` by default; `reasoningEffortFormat: 'reasoning-effort'` sends the literal field instead (e.g. for DeepSeek-style hosts, with an optional `thinking` toggle merged into the request body). Hosts remain responsible for offering only efforts supported by the selected model. Required
|
|
280
|
+
authorization and JSON headers cannot be replaced through `extraHeaders`. Only override
|
|
281
|
+
`chatCompletionsUrl` with a trusted proxy because it receives the bearer credential.
|
|
282
|
+
|
|
283
|
+
Grok subscription access uses `https://cli-chat-proxy.grok.com/v1/responses`, not the xAI developer
|
|
284
|
+
API-key endpoint. The adapter sends the required CLI-session and model-routing headers and rejects
|
|
285
|
+
mismatched or expired access-token envelopes before HTTP. `makeXAiGrokProviderLayer` also requires
|
|
286
|
+
a truthful host-owned `clientVersion`, sent as `x-grok-client-version`, because the xAI CLI proxy
|
|
287
|
+
version-gates requests and rejects missing or outdated versions with HTTP 426; required headers
|
|
288
|
+
stay non-overridable through `extraHeaders`. The package exports browser-PKCE and
|
|
289
|
+
device-flow constants; hosts own the callback listener or device polling, token exchange/refresh,
|
|
290
|
+
secure storage, and model discovery. Only set `responsesUrl` to a trusted proxy because it receives
|
|
291
|
+
the OAuth bearer. xAI controls the public CLI OAuth client and private, unsupported proxy contract,
|
|
292
|
+
so hosts should treat those surfaces as changeable and confirm that their use complies with xAI
|
|
293
|
+
terms.
|
|
294
|
+
|
|
295
|
+
Set optional `reasoningEffort` on `run` or `runRuntime`; provider adapters lower it to vendor
|
|
296
|
+
configuration. Anthropic Claude forwards `low`, `medium`, `high`, and `xhigh` through
|
|
297
|
+
`output_config.effort`. It omits `minimal`, which Anthropic does not support. Hosts remain
|
|
298
|
+
responsible for choosing an effort accepted by the selected provider and model.
|
|
299
|
+
|
|
300
|
+
### Anthropic tool schemas
|
|
301
|
+
|
|
302
|
+
Claude subscription OAuth rejects some valid JSON Schema constructs that Effect Schema can emit
|
|
303
|
+
for unions, refinements, and tuples. The Claude adapter therefore projects tool parameters to a
|
|
304
|
+
provider-compatible object schema without `anyOf`, `oneOf`, `allOf`, or tuple-only `prefixItems`.
|
|
305
|
+
When a constraint cannot be represented faithfully, the projection widens the model-facing schema
|
|
306
|
+
rather than excluding a valid call. Tool execution remains safe because `makeTool` validates the
|
|
307
|
+
returned arguments against the original Effect Schema (through its JSON codec) before invoking the
|
|
308
|
+
executor.
|
|
309
|
+
|
|
310
|
+
Before projection, `toAnthropicClaudeRequestBody` and the Claude provider decode `ToolDef.parameters`
|
|
311
|
+
and `ToolCall.params` as `Schema.Json`. Non-JSON values fail as non-retryable `LLMError` with
|
|
312
|
+
`cause: 'provider_error'`. `ToolDef.parameters` now admits `ToolJsonSchema` at construction;
|
|
313
|
+
`ToolCall.params` stays opaque. Provider admission also catches post-construction forgeries.
|
|
314
|
+
After lone-surrogate rewrite, the request
|
|
315
|
+
body is decoded as JSON again and fails rather than skipping serialization. HTTP error bodies that
|
|
316
|
+
are not JSON still classify from status. Tool-result blocks omit `is_error` when the result carries
|
|
317
|
+
no flag, so follow-up request bodies stay valid; an explicit boolean `isError` is still serialized.
|
|
318
|
+
|
|
319
|
+
### Tool parameter documents
|
|
320
|
+
|
|
321
|
+
`ToolDef.parameters` uses `ToolJsonSchema` from `@yolk-sdk/agent/protocol`: a boolean schema or
|
|
322
|
+
plain JSON object. `ToolJsonSchemaObject` is the object arm; `decodeToolJsonSchema` and
|
|
323
|
+
`decodeToolJsonSchemaObject` return `Option`. This checks representation, not JSON Schema semantics.
|
|
324
|
+
Construction/decode preserve admitted identity and accept finite primitives, dense ordinary arrays,
|
|
325
|
+
plain/null-prototype objects, own `__proto__`/`constructor` keys and DAG aliases. Accessors are
|
|
326
|
+
rejected unread; exotic prototypes, hidden/symbol keys, undefined, nonfinite values and cycles fail.
|
|
327
|
+
No Proxy side-effect immunity or immutability is promised. Tool call parameters/results and HITL
|
|
328
|
+
remain opaque. Background wrapping preserves boolean `true`/`false` as the arguments schema;
|
|
329
|
+
reference/resource restrictions still apply at activation. `makeTool` may add root `type: "object"`
|
|
330
|
+
to typeless `anyOf`/`oneOf` unions whose members are all object schemas, as required by strict
|
|
331
|
+
OpenAI-compatible upstreams; primitives, unknown, and already-typed roots are unchanged, and call
|
|
332
|
+
validation still decodes through the original Effect Schema's JSON codec. Effect 4.0.0 exports
|
|
333
|
+
`Schema.isPattern` to JSON Schema only for `u`-flag regexes (optionally with `d`, `g`, or `y`);
|
|
334
|
+
add `u` to keep model-visible `pattern` hints.
|
|
335
|
+
|
|
336
|
+
### Tool arguments: `null` and unknown keys
|
|
337
|
+
|
|
338
|
+
Tool arguments are accepted exactly as advertised: unambiguous `null`s are normalized, and keys
|
|
339
|
+
that would be silently lost are rejected. `ToolDef.parameters` describes the schema's canonical JSON codec, so `Schema.optional(X)` is
|
|
340
|
+
advertised as `X | null`. `makeTool` (validate and execute), `makeInputTool`/`makeInteractionTool`
|
|
341
|
+
call params, and the loop `question` decode model arguments with `Schema.toCodecJson(parameters)`:
|
|
342
|
+
`null` on `Schema.optional(X)` decodes as absent and `withDecodingDefault` still applies,
|
|
343
|
+
`Schema.optional(Schema.NullOr(X))` keeps `null`, and required non-nullable fields still reject it.
|
|
344
|
+
`undefined`-valued keys from in-process callers count as absent.
|
|
345
|
+
Non-finite numbers (the codec's `"NaN"`/`"Infinity"` strings) are validation errors. Objects are
|
|
346
|
+
advertised closed (`additionalProperties: false`), so unknown keys at any depth are model-visible
|
|
347
|
+
validation errors instead of being stripped (also through closed-input declarations whose JSON codec
|
|
348
|
+
bypasses their own parser). Their error message names each unknown key and lists the allowed keys at that path; this includes
|
|
349
|
+
a `null` on another union member's field.
|
|
350
|
+
`resolveTools` also drops `null` where the advertised schema declares a property optional without
|
|
351
|
+
admitting `null` (for example `Schema.optionalKey(X)`, the subagent `model`, or raw MCP schemas)
|
|
352
|
+
before any registration sees the call; `omitNullOptionalToolArguments` (`@yolk-sdk/agent/tools`) exposes that step for hosts
|
|
353
|
+
that dispatch registrations themselves. User-submitted input/interaction responses are unchanged.
|
|
354
|
+
|
|
355
|
+
### OpenAI Chat Completions, Responses, and extraBody
|
|
356
|
+
|
|
357
|
+
OpenAI Chat Completions and Responses lowering (including Codex) likewise admits
|
|
358
|
+
`ToolDef.parameters` and tool-call `params` as `Schema.Json` before they are copied onto the request
|
|
359
|
+
body. Non-JSON tool documents and arguments fail as non-retryable `LLMError` `provider_error` before
|
|
360
|
+
transport. `ToolDef.parameters` admits `ToolJsonSchema`; `ToolCall.params` stays opaque. Public Codex wrapper
|
|
361
|
+
`OpenAiCodexTool.parameters` remains `unknown`; that field is not a `Schema.Json` input type.
|
|
362
|
+
|
|
363
|
+
Optional request-body fields such as `max_output_tokens`, `tools`, `parallel_tool_calls`, and
|
|
364
|
+
`reasoning` are omitted unless present — they are not own-property `undefined`. After lone-surrogate
|
|
365
|
+
rewrite, Chat Completions and Responses request bodies are decoded as `Schema.Json` again and fail
|
|
366
|
+
rather than skipping serialization. Inbound HTTP JSON bodies admit `Schema.Json` before class/helper
|
|
367
|
+
consumption (`invalid_response` on failure). Responses SSE event JSON admits `Schema.Json`;
|
|
368
|
+
non-object JSON events are ignored (not failed), while malformed non-JSON event text still fails
|
|
369
|
+
`invalid_response`. First `response.completed` remains terminal. HTTP error bodies stay raw text for
|
|
370
|
+
`classifyProviderFailure`.
|
|
371
|
+
|
|
372
|
+
Chat Completions transport defaults to one JSON body. Set `OpenAiProviderConfig.streaming: true` to
|
|
373
|
+
request incremental `chat.completion.chunk` SSE deltas with `stream_options.include_usage`, folded
|
|
374
|
+
into text/reasoning/tool-call events plus terminal and usage events. Unterminated streams fail
|
|
375
|
+
`invalid_response` and never emit `Done`. Hosts must only enable streaming against endpoints that
|
|
376
|
+
serve chat SSE; OpenCode Go `chat-completions` always sets it.
|
|
377
|
+
|
|
378
|
+
`OpenAiProviderConfig.extraBody` takes `OpenAiRequestExtras` (JSON-object input). Lowering
|
|
379
|
+
projects enumerable own string fields into an independent portable-data snapshot. Canonical
|
|
380
|
+
`model`, `messages`, `stream`, `tools`, `parallel_tool_calls`, `max_completion_tokens`, and
|
|
381
|
+
`max_tokens` are discarded **without reading their values**; `reasoning` is also discarded when
|
|
382
|
+
`reasoningEffortFormat` is `reasoning-object`. Root symbols/non-enumerable fields are not projected.
|
|
383
|
+
Surviving accessors are rejected unread. Nested values must be finite JSON data with plain/null
|
|
384
|
+
prototypes or dense ordinary arrays; exotic objects, cycles, hidden/symbol keys and extra array
|
|
385
|
+
properties fail. DAG aliases remain aliases in the snapshot; the input is not mutated or retained.
|
|
386
|
+
Invalid extras fail with non-retryable `provider_error`, fixed message
|
|
387
|
+
`Invalid … extraBody JSON: expected a JSON object`, and no HTTP request. Messages never echo values.
|
|
388
|
+
The composed request still passes final `Schema.Json` admission after lone-surrogate rewriting.
|
|
389
|
+
This is not a guarantee against Proxy traps. Gateway routing projects its declared `order`, `only`
|
|
390
|
+
and `sort` fields into JSON; canonical headers and provider identity stay host-owned.
|
|
391
|
+
|
|
392
|
+
### OpenAI Realtime tool JSON
|
|
393
|
+
|
|
394
|
+
Public `OpenAiRealtimeFunctionTool.parameters` and `openAiRealtimeToolParameters(parameters: Schema.Json)`
|
|
395
|
+
now require admitted JSON. Non-JSON advertisement fails `VoiceToolBridgeError` before transport:
|
|
396
|
+
synchronous `toOpenAiRealtimeTool`, `makeOpenAiRealtimeSessionConfig`, and
|
|
397
|
+
`openAiRealtimeSessionConfigFromVoice` throw; `toOpenAiRealtimeToolEffect`,
|
|
398
|
+
`makeOpenAiRealtimeSessionConfigEffect`, and `openAiRealtimeSessionConfigFromVoiceEffect` fail in the
|
|
399
|
+
Effect error channel. Unexpected mapper defects (for example throwing getters) remain defects via
|
|
400
|
+
`Effect.suspend` / `Result`, not `VoiceToolBridgeError`.
|
|
401
|
+
|
|
402
|
+
Union-root lowering uses `Map<string, Schema.Json>` plus `Object.fromEntries` so own `__proto__` /
|
|
403
|
+
`constructor` fields merge (first-seen / string-enum union) instead of prototype assignment or
|
|
404
|
+
inherited `constructor` masquerading as Schema.Json. Required intersection, empty-required omission,
|
|
405
|
+
and object-root identity are unchanged.
|
|
406
|
+
|
|
407
|
+
## Provider failures and retries
|
|
408
|
+
|
|
409
|
+
Provider adapters classify safe failure metadata at the boundary. The loop owns bounded retry
|
|
410
|
+
policy and emits protocol-visible retry/error state:
|
|
411
|
+
|
|
412
|
+
- `ProviderErrorInfo` carries safe provider id, failure kind, HTTP status, provider code, optional
|
|
413
|
+
`retryAfterMs`, and optional `stream` diagnostics (`ProviderStreamDiagnostics`) on chat
|
|
414
|
+
`unexpected_content_type` / `incomplete_stream` failures. Diagnostics contain counters and
|
|
415
|
+
milestones, never transcript content, raw headers, or body fragments. See the
|
|
416
|
+
[stream diagnostics guide](https://github.com/magoz/yolk-sdk/blob/main/apps/docs/content/docs/troubleshooting.mdx#diagnose-chat-stream-failures-with-stream-diagnostics).
|
|
417
|
+
- Chat Completions and Responses HTTP failures copy the envelope string `code` (falling back to
|
|
418
|
+
`type`) into `provider.providerCode`; free-text upstream bodies stay out of `LLMError`.
|
|
419
|
+
- `AgentRetry.provider` exposes current retry metadata and chosen `delayMs`.
|
|
420
|
+
- `AgentError.provider` preserves final terminal metadata.
|
|
421
|
+
- `AgentErrorCode` includes `rate_limit`, `overloaded`, `context_overflow`, and generic
|
|
422
|
+
`provider_error`.
|
|
423
|
+
- Client and React state keep `error: string | null` for compatibility and add typed `errorInfo` /
|
|
424
|
+
`retryInfo`.
|
|
425
|
+
- `buildAgentChatItems` can project active retry state as an `AgentChatItem` with `_tag: 'Retry'`.
|
|
426
|
+
- Anthropic prompt-too-long responses become non-retryable `context_overflow`; the host-owned
|
|
427
|
+
compaction wrapper may compact and retry once.
|
|
428
|
+
- Anthropic `max_tokens` and OpenAI-compatible `finish_reason: "length"` / `"content_filter"`
|
|
429
|
+
completions fail as non-retryable `invalid_response` instead of reporting truncated or filtered
|
|
430
|
+
output as complete.
|
|
431
|
+
|
|
432
|
+
Raw provider response bodies stay out of protocol/UI. Hosts own durable persistence and display of
|
|
433
|
+
typed retry/error state.
|
|
434
|
+
|
|
435
|
+
## Subscription allowance snapshots
|
|
436
|
+
|
|
437
|
+
The Claude, Codex, and Grok usage adapters read best-effort consumer subscription allowance
|
|
438
|
+
percentages and reset windows. Claude normalizes its aggregate five-hour and seven-day windows;
|
|
439
|
+
Codex normalizes primary and secondary rate-limit windows; Grok normalizes its aggregate shared
|
|
440
|
+
credit allowance. Additional provider-specific buckets are ignored. These private provider
|
|
441
|
+
endpoints may change without notice. Pass a fresh host-owned `OAuthAccessToken` and provide an
|
|
442
|
+
Effect `HttpClient`:
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
import { Effect } from 'effect'
|
|
446
|
+
import { FetchHttpClient } from 'effect/http'
|
|
447
|
+
import { fetchOpenAiCodexSubscriptionUsage } from '@yolk-sdk/agent/providers/openai/codex-usage'
|
|
448
|
+
|
|
449
|
+
const snapshot = await fetchOpenAiCodexSubscriptionUsage(hostOAuthAccessToken).pipe(
|
|
450
|
+
Effect.provide(FetchHttpClient.layer),
|
|
451
|
+
Effect.runPromise
|
|
452
|
+
)
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Use `fetchAnthropicClaudeSubscriptionUsage` from
|
|
456
|
+
`@yolk-sdk/agent/providers/anthropic/usage` for Claude. Use
|
|
457
|
+
`fetchXAiGrokSubscriptionUsage` from `@yolk-sdk/agent/providers/xai/usage` for Grok and pass the
|
|
458
|
+
actual authenticated xAI `user_id` as `xAiUserId`. The generic token `accountId` is not interpreted
|
|
459
|
+
as an xAI user id. Also pass your host integration's truthful version as `clientVersion`; the
|
|
460
|
+
adapter sends it with `x-grok-client-mode: headless` and never claims an official Grok client
|
|
461
|
+
version.
|
|
462
|
+
|
|
463
|
+
Provider adapters return an immutable Effect `Chunk` of semantic window ids, percentages, and
|
|
464
|
+
optional reset/duration fields; hosts own labels, polling, persistence, stale-data policy, alert
|
|
465
|
+
thresholds, billing interpretation, and UI. Configure `requestTimeoutMs` at the server integration
|
|
466
|
+
boundary. Each fetcher defaults to its exported URL constant; the optional `url` override is only
|
|
467
|
+
for a trusted proxy or local emulator, because the credential is sent to it. `FetchHttpClient.layer` is configured for manual
|
|
468
|
+
redirects. A custom `HttpClient` must not follow redirects for these credential-bearing requests.
|
|
469
|
+
|
|
470
|
+
Subscription allowance snapshots are separate from protocol `AgentUsage`, which accounts for tokens
|
|
471
|
+
used by model requests and nested model work.
|
|
472
|
+
|
|
473
|
+
## Usage accounting
|
|
474
|
+
|
|
475
|
+
Provider `LLMUsage` events are additive deltas. Adapters normalize vendor counters before emitting;
|
|
476
|
+
for example, Anthropic stream snapshots become deltas and cached input tokens count toward input
|
|
477
|
+
totals. The loop aggregates usage and emits protocol `UsageUpdate` / terminal usage for hosts to
|
|
478
|
+
persist or display.
|
|
479
|
+
|
|
480
|
+
## Context compaction
|
|
481
|
+
|
|
482
|
+
`@yolk-sdk/agent/compaction` provides pure budgeting, planning, estimation, checkpoint, and
|
|
483
|
+
formatting utilities plus Effect-native context-transformer and provider-retry adapters. It does
|
|
484
|
+
not summarize or persist checkpoints. Hosts own thresholds, summary policy, durable storage, and
|
|
485
|
+
active-run guards. The one-shot context-overflow wrapper calls your host compactor.
|
|
486
|
+
|
|
487
|
+
```ts
|
|
488
|
+
import {
|
|
489
|
+
makeContextBudget,
|
|
490
|
+
makePreviewSummaryMessage,
|
|
491
|
+
makeWindowCompactionTransformer
|
|
492
|
+
} from '@yolk-sdk/agent/compaction'
|
|
493
|
+
|
|
494
|
+
const budget = makeContextBudget({
|
|
495
|
+
contextWindowTokens: 200_000,
|
|
496
|
+
reservedOutputTokens: 20_000,
|
|
497
|
+
warningRatio: 0.8,
|
|
498
|
+
compactionRatio: 1
|
|
499
|
+
})
|
|
500
|
+
|
|
501
|
+
const ContextLayer = makeWindowCompactionTransformer({
|
|
502
|
+
strategy: 'window-summary-v1',
|
|
503
|
+
thresholdTokens: budget.compactionInputTokens,
|
|
504
|
+
tailMessageCount: 16,
|
|
505
|
+
makeSummaryMessage: messages => makePreviewSummaryMessage(messages)
|
|
506
|
+
})
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
The default estimator uses provider-neutral character and media heuristics. Pass
|
|
510
|
+
`TokenEstimateOptions.countTextTokens` to improve estimates for selected message text, reasoning,
|
|
511
|
+
and host tool-call identifiers, or pass a whole-transcript `estimateTokens` to planners and
|
|
512
|
+
transformers. Exact provider-request accounting must also include system prompts, tool definitions,
|
|
513
|
+
vendor framing, and a safety margin. Reuse one estimator for warnings, planning, and before/after
|
|
514
|
+
checks; tokenizer dependencies remain host-owned.
|
|
515
|
+
|
|
516
|
+
## Skillsets
|
|
517
|
+
|
|
518
|
+
`@yolk-sdk/agent/skillset` parses skill Markdown and slash-command Markdown into portable
|
|
519
|
+
`SkillInfo`, `CommandInfo`, and `SkillsetManifest` data. Use `parseSkillMarkdown` /
|
|
520
|
+
`parseCommandMarkdown` at file or database boundaries, `renderCommand` for command invocation, and
|
|
521
|
+
`mergeSkillsets` to combine host sources. Earlier sources win name conflicts; duplicate names
|
|
522
|
+
inside one source fail validation. Hosts own file discovery, storage, enablement, and source order.
|
|
523
|
+
|
|
64
524
|
## Protocol content
|
|
65
525
|
|
|
66
526
|
`Content` is either plain text or ordered parts:
|
|
@@ -71,55 +531,485 @@ const program = run({
|
|
|
71
531
|
- `AudioPart` with `InlineBase64`, `Url`, or host-owned `Ref` source
|
|
72
532
|
|
|
73
533
|
Build sources with `inlineBase64AttachmentSource`, `urlAttachmentSource`, or
|
|
74
|
-
`refAttachmentSource`.
|
|
75
|
-
|
|
76
|
-
|
|
534
|
+
`refAttachmentSource`. OpenAI-compatible Chat Completions providers support inline text documents;
|
|
535
|
+
native PDF `DocumentPart` lowering is opt-in through `supportsPdfAttachments`, while Vercel AI
|
|
536
|
+
Gateway enables it by default (set `supportsPdfAttachments: false` to disable it). For URL-backed
|
|
537
|
+
user-message PDFs, both opted-in generic OpenAI chat and Gateway use the host-provided `HttpClient`
|
|
538
|
+
to fetch and buffer the PDF before sending inline file data; the provider does not fetch the URL.
|
|
539
|
+
Hosts must authorize attachment URLs and enforce destination and redirect policy, streamed-byte
|
|
540
|
+
limits, timeouts, safe logging, and credential isolation so provider credentials are never attached
|
|
541
|
+
to attachment destinations. The SDK resolver does not establish those guarantees. Prefer validated
|
|
542
|
+
inline bytes when the host cannot provide a bounded attachment transport. OpenAI Chat and Vercel AI
|
|
543
|
+
Gateway support image URLs; OpenAI Codex supports image
|
|
544
|
+
and document URLs; Anthropic supports image and PDF URLs. The Grok
|
|
545
|
+
Responses lowerer can encode image URLs/data URLs, but hosts should enable image capability only for
|
|
546
|
+
subscription models they have verified accept image input. Use
|
|
547
|
+
inline base64 for simple apps, durable URLs for app-owned uploads, or persist opaque `Ref` values and
|
|
548
|
+
resolve them immediately before each provider attempt. `resolveContentAttachmentSources` handles one
|
|
549
|
+
`Content`; `resolveMessageAttachmentSources` and `resolveMessagesAttachmentSources` also walk assistant
|
|
550
|
+
text and nested provider tool results, preserving metadata and ordering without mutating history.
|
|
551
|
+
All accept `AttachmentSourceResolver<E, R>`, preserve typed Effect errors/services, and leave opaque
|
|
552
|
+
tool/provider payloads alone. Resolution does not add provider media capabilities or cache sources.
|
|
553
|
+
|
|
554
|
+
Host apps own upload, authorization, byte/MIME limits, retention, and fresh signing. Put a host
|
|
555
|
+
resolving provider wrapper inside `makeContextOverflowRetryProvider` so compaction sees refs and each
|
|
556
|
+
retry signs the effective context afresh. Never persist the resolved copy. See the
|
|
557
|
+
[private attachment guide](https://github.com/magoz/yolk-sdk/blob/main/apps/docs/content/docs/guides/private-attachments.mdx) for the
|
|
558
|
+
host-owned composition and bounded connector transport.
|
|
559
|
+
|
|
560
|
+
OpenAI Codex preserves text, image, and document `ToolResultMessage` parts as native function output
|
|
561
|
+
content. Anthropic Claude preserves text, images, inline text documents, and URL/base64 PDFs as
|
|
562
|
+
nested tool-result content. OpenAI-compatible Chat Completions, including Vercel AI Gateway, keep
|
|
563
|
+
tool-result text in the tool message and lower images, readable text documents, and opted-in PDFs to
|
|
564
|
+
origin-labeled supplementary user content after the complete tool-result block. Canonical history is
|
|
565
|
+
unchanged. Audio, unresolved references, and other document formats still fail before the provider
|
|
566
|
+
request.
|
|
567
|
+
|
|
568
|
+
```ts
|
|
569
|
+
import { ImagePart, UserMessage, urlAttachmentSource } from '@yolk-sdk/agent/protocol'
|
|
570
|
+
|
|
571
|
+
const message = UserMessage.make({
|
|
572
|
+
content: [
|
|
573
|
+
ImagePart.make({
|
|
574
|
+
source: urlAttachmentSource('https://cdn.example.com/image.webp'),
|
|
575
|
+
mimeType: 'image/webp'
|
|
576
|
+
})
|
|
577
|
+
]
|
|
578
|
+
})
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
For text files, use `documentPartFromText`, `inferTextDocumentMimeType`, and the client helper
|
|
582
|
+
`documentPartFromTextFile` to create UTF-8 inline
|
|
583
|
+
`DocumentPart` values without trusting filename extensions over explicit non-text MIME types.
|
|
77
584
|
|
|
78
585
|
Use model capabilities like `textOnlyModelCapabilities`, `textImageModelCapabilities`, or
|
|
79
586
|
`textImageDocumentModelCapabilities` so the loop rejects unsupported inputs before provider calls.
|
|
80
587
|
|
|
588
|
+
## Message envelope
|
|
589
|
+
|
|
590
|
+
Messages may carry model-visible envelope facts without polluting authored `content`:
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
UserMessage.make({
|
|
594
|
+
content: 'Can you summarize this?',
|
|
595
|
+
createdAtMs: 1781260200000,
|
|
596
|
+
author: { displayName: 'Magoz' },
|
|
597
|
+
annotations: {
|
|
598
|
+
source: 'web',
|
|
599
|
+
ui_origin: 'document_toolbar',
|
|
600
|
+
timezone: 'Europe/Madrid',
|
|
601
|
+
locale: 'en-US',
|
|
602
|
+
input_method: 'keyboard',
|
|
603
|
+
message_kind: 'question',
|
|
604
|
+
client_sent_at: '2026-06-12T10:30:00.000Z'
|
|
605
|
+
}
|
|
606
|
+
})
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
- `content`: authored message body only.
|
|
610
|
+
- `createdAtMs`: message creation/sent time; providers render it as ISO `sent_at` context.
|
|
611
|
+
- `author.displayName`: presentation label only; not identity, auth, or a stable id.
|
|
612
|
+
- `annotations`: app-owned JSON object; context only, not instructions.
|
|
613
|
+
|
|
614
|
+
Provider adapters can use `messageContextText` and `prependMessageContextToContent` to render
|
|
615
|
+
envelopes into model input while keeping `content` authored-only.
|
|
616
|
+
|
|
617
|
+
Annotations must be JSON-compatible. Use stable app-owned keys, preferably `snake_case`. Use ISO
|
|
618
|
+
strings for dates inside annotations. Never put secrets, credentials, private ids, auth state, or
|
|
619
|
+
hidden policy in annotations, author, or timestamps; providers may send them to models.
|
|
620
|
+
|
|
621
|
+
## Replay-safe chat projection
|
|
622
|
+
|
|
623
|
+
Durable transports may reconnect or replay overlapping chunks. Protocol events can carry optional
|
|
624
|
+
`eventId`; `LLMTextDelta` and `LLMReasoningDelta` can also carry `textSoFar` / `reasoningSoFar`
|
|
625
|
+
snapshots when a host can provide cumulative text.
|
|
626
|
+
|
|
627
|
+
Use `applyAgentEventToChatProjection` for replayable event logs:
|
|
628
|
+
|
|
629
|
+
```ts
|
|
630
|
+
import {
|
|
631
|
+
applyAgentEventToChatProjection,
|
|
632
|
+
makeAgentChatEventProjectionState
|
|
633
|
+
} from '@yolk-sdk/agent/react'
|
|
634
|
+
|
|
635
|
+
const projection = events.reduce(
|
|
636
|
+
(state, event) => applyAgentEventToChatProjection(state, event),
|
|
637
|
+
makeAgentChatEventProjectionState()
|
|
638
|
+
)
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
Use `applyAgentEventToChatMessages` only for ephemeral local streams where append-only deltas cannot
|
|
642
|
+
replay.
|
|
643
|
+
|
|
644
|
+
When the host promotes queued user input into a durable stream, emit a replay-safe user event:
|
|
645
|
+
|
|
646
|
+
```ts
|
|
647
|
+
import { UserMessage, UserMessageEvent } from '@yolk-sdk/agent/protocol'
|
|
648
|
+
|
|
649
|
+
const event = UserMessageEvent.make({
|
|
650
|
+
eventId: 'session_1:user-message_42',
|
|
651
|
+
message: UserMessage.make({ content: 'Please also compare the alternatives.' })
|
|
652
|
+
})
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
The host owns queueing and promotion policy and must assign a stable `eventId` so reconnects do not
|
|
656
|
+
project the same promoted message twice.
|
|
657
|
+
|
|
658
|
+
## Parallel tool calls
|
|
659
|
+
|
|
660
|
+
OpenAI, Vercel AI Gateway, OpenAI Codex, and Grok requests enable vendor parallel tool calls when tools are available. The
|
|
661
|
+
Codex stream adapter preserves every sibling function call and suppresses final-response replays
|
|
662
|
+
by call id. The loop executes calls emitted in the same model turn concurrently, bounded by the
|
|
663
|
+
host-configured `LoopConfig.toolConcurrency`; dependent work waits for the next model turn.
|
|
664
|
+
|
|
665
|
+
## Transcript invariants
|
|
666
|
+
|
|
667
|
+
Every assistant host tool call must be followed by a matching `ToolResultMessage` before the next
|
|
668
|
+
non-tool message/provider request. Use `validateNoDanglingHostToolCalls` for preflight checks,
|
|
669
|
+
`danglingHostToolCalls` for diagnostics, and `repairDanglingHostToolCalls` only when loading older
|
|
670
|
+
persisted transcripts that already have gaps. Built-in providers reject dangling host tool calls
|
|
671
|
+
before vendor lowering with a non-retryable validation error.
|
|
672
|
+
|
|
81
673
|
## Human-in-the-loop
|
|
82
674
|
|
|
83
675
|
HITL is protocol-level, not UI-level:
|
|
84
676
|
|
|
85
677
|
- Add `approval: { mode: 'manual' }` to a `ToolDef` to pause before execution.
|
|
86
678
|
- `run` / `runRuntime` emit `ToolApprovalRequested` then `AgentAwaitingInput`.
|
|
87
|
-
- Resume by passing `hitlResponses
|
|
679
|
+
- Resume by passing `hitlResponses`, using `useAgentChat` methods like
|
|
680
|
+
`submitToolApprovalResponse` / `submitQuestionResponse`, or using client stream helpers like
|
|
681
|
+
`streamToolApprovalResponseEventStream`.
|
|
88
682
|
- Denials become model-visible `ToolResult` messages with `isError = true`.
|
|
89
|
-
- Use `makeQuestionToolModule` to expose the package-owned `question` tool; answers resume as structured tool results and model-visible text with selected labels.
|
|
683
|
+
- Use `makeQuestionToolModule` to expose the package-owned `question` tool; answers resume as structured tool results and model-visible text with selected labels. The loop intercepts questions only when the tool is enabled in `tools`; omitted questions return an unavailable result without HITL or executor dispatch, even if a provider emits one.
|
|
684
|
+
- Use `makeInputTool({ name, description, response, renderer })` for custom typed input. Apps own the response Effect schema and renderer; the SDK carries JSON data only. Pass `resolveTools(...).inputs` alongside `tools` to loop/runtime configs. The original `callParameters` and `response` schemas validate server-side, including refinements; display JSON Schema is not the validator. Invalid calls fail before prompting; invalid submissions remain pending for correction. The first valid submission or cancellation settles the request and cannot be overwritten by stale responses.
|
|
685
|
+
- Resume custom inputs with `submitInputResponse`, `streamInputResponseEventStream`, or WebSocket `InputResponseInput`. Echo request/call IDs; do not reconstruct them. Input collection is not authorization: a draft composer never grants permission to send. Input tools cannot carry approval/background policy or execute directly.
|
|
686
|
+
- Use `makeInteractionTool` when a person must edit proposed values and authorize one server-defined action. Unlike data-only inputs, interactions execute the selected action on the exact validated values before the next model turn. Hosts own renderers, authentication, scoped immutable receipt storage, and atomic acceptance; browser responses alone never authorize execution. Pass `interactionHost` to `resolveTools`, then both `toolSet.interactions` and `toolSet.interactionHost` to loop/runtime configs. Durable hosts load `loadInteractionReceipts` before passing `interactionReceipts` to `prepareToolBatch`.
|
|
687
|
+
- Submit interactions with `submitInteractionResponse`, `streamInteractionResponseEventStream`, or WebSocket `InteractionResponseInput`; the host must authenticate and atomically accept the response server-side before SDK resume. Submission is not completion; only real server results settle the UI. An `unknown` outcome needs host reconciliation, never automatic action retry. Voice/realtime and background activation are unsupported. See [action-backed interactions](https://github.com/magoz/yolk-sdk/blob/main/packages/agent/src/tools/README.md#action-backed-interactions) for registration and host-boundary details.
|
|
688
|
+
- Use `questionResponseStructuredContent` / `plainHitlResponse` before storing durable HITL payloads that must be plain JSON. `PlainHitlResponse` is a `Data.taggedEnum` value (`QuestionResponse` / `ToolApprovalResponse` / `InputResponse` / `InteractionResponse`); the helpers omit absent optionals then call those constructors (`_tag` last, plain objects, not Schema classes).
|
|
689
|
+
- Use `toolRunsFromHitlRequests` to hydrate paused UI state from `AgentAwaitingInput.requests`.
|
|
690
|
+
- Use `hitlResponseEvent` when a client needs optimistic approval/question UI updates before resumed stream events arrive. Typed input and interaction submissions stay pending until server acceptance; accepted interactions stay active until the actual outcome. Never synthesize an interaction result from local submission or acceptance.
|
|
90
691
|
- Approval is a host-enforced per-call gate for normal tools, not a model-callable permission tool or persisted allow-always system.
|
|
91
692
|
|
|
92
|
-
|
|
693
|
+
HTTP client helpers treat `AgentEnd`, `AgentError`, and `AgentAwaitingInput` as logical stream
|
|
694
|
+
end for consumers. Use `isTerminalAgentEvent` when projecting generic protocol streams. After a
|
|
695
|
+
terminal event the response body drains to EOF; cancellation before a terminal event still aborts
|
|
696
|
+
the active body reader.
|
|
697
|
+
Durable Workflow clients can use `streamAgentEventStreamUntilTerminal`,
|
|
698
|
+
`streamAgentRunEventStreamUntilTerminal`, and `streamAgentRunHitlResponseEventStreamUntilTerminal` to follow
|
|
699
|
+
continuation chunks by `x-workflow-run-id` and `x-workflow-stream-tail-index` headers. These helpers
|
|
700
|
+
fail with `AgentTransportError` if no terminal event is reached before the continuation limit.
|
|
701
|
+
Empty non-terminal continuation chunks are polling gaps: the client waits briefly, retries from the
|
|
702
|
+
same `startIndex`, and respects the request `signal` while waiting.
|
|
703
|
+
Outbound `startIndex` values must be non-negative safe integers; invalid values fail before the
|
|
704
|
+
HTTP request is sent.
|
|
705
|
+
For HITL resume responses, `x-workflow-stream-tail-index` means the stream tail before the returned
|
|
706
|
+
body. The returned body starts at `tail + 1`; the next continuation starts after all returned
|
|
707
|
+
events. `continuationLimit: 0` disables follow-up chunks, so any non-terminal response fails
|
|
708
|
+
immediately.
|
|
709
|
+
|
|
710
|
+
```ts
|
|
711
|
+
import { Stream } from 'effect'
|
|
712
|
+
import { streamAgentEventStreamUntilTerminal } from '@yolk-sdk/agent/client'
|
|
713
|
+
import { UserMessage } from '@yolk-sdk/agent/protocol'
|
|
714
|
+
|
|
715
|
+
const events = Stream.toAsyncIterable(
|
|
716
|
+
streamAgentEventStreamUntilTerminal({
|
|
717
|
+
endpoint: '/api/agent/workflow',
|
|
718
|
+
sessionId: 'session_1',
|
|
719
|
+
messages: [UserMessage.make({ content: 'Hello' })],
|
|
720
|
+
runEndpoint: runId => `/api/agent/workflow/${encodeURIComponent(runId)}`
|
|
721
|
+
})
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
for await (const event of events) {
|
|
725
|
+
// Apply AgentEvent to app state.
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
The SDK client does not own durable route auth, run ownership, Workflow hook-token routing, or HITL
|
|
730
|
+
request matching. Hosts expose the run endpoints and validate access/response identity server-side.
|
|
731
|
+
|
|
732
|
+
## Voice
|
|
733
|
+
|
|
734
|
+
`VoiceSession.layer` (`@yolk-sdk/agent/voice`) composes a supplied `VoiceTransport` layer,
|
|
735
|
+
`VoiceController`, and an optional `VoiceEventOutbox`. Configured `eventLog` captures events without
|
|
736
|
+
an external stream consumer; omitting it never captures an ambient outbox. The returned event stream
|
|
737
|
+
has one queue consumer and is not a broadcast subscription. Without a consumer, events accumulate
|
|
738
|
+
in memory; hosts should normally drain it. Seeds run during acquisition.
|
|
739
|
+
|
|
740
|
+
Breaking 0.x migration: `makeVoiceController` no longer takes `options.transport`; provide
|
|
741
|
+
`VoiceTransport` with `Effect.provideService`, or use `VoiceSession.layer`.
|
|
742
|
+
`webRtcVoiceTransportLayer` (`voice/browser`) and `webSocketVoiceTransportLayer` (`voice`) acquire
|
|
743
|
+
scoped transports. `Layer.succeed(VoiceTransport, transport)` injects a caller-owned value; it does
|
|
744
|
+
not allocate/finalize it or guarantee fresh resources. Keep the entire usage effect inside a
|
|
745
|
+
provided layer, or use `Layer.buildWithScope` when an explicit session scope owns its lifetime.
|
|
746
|
+
`useYolkVoice` builds each attempt in that attempt's scope and retains stop/unmount cleanup.
|
|
747
|
+
|
|
748
|
+
Voice is a first-class modality: browser WebRTC transport, client controller, server tool
|
|
749
|
+
handler, approval HITL, transcript projection, and one-shot TTS/STT contracts.
|
|
750
|
+
|
|
751
|
+
- `useYolkVoice` (`@yolk-sdk/agent/voice/react`) owns browser session lifecycle, user drafts,
|
|
752
|
+
and pending approvals; provider codecs come from `@yolk-sdk/agent/providers/openai/realtime`.
|
|
753
|
+
- Tools execute server-side only: the controller forwards the normalized
|
|
754
|
+
`VoiceSessionToolCallRequest` JSON envelope to your endpoint; `handleVoiceToolCall` returns a
|
|
755
|
+
JSON-compatible `VoiceToolCallOutcome` envelope, applies `ToolDef.approval` policy, and never runs
|
|
756
|
+
approval-gated tools without a matching approved response.
|
|
757
|
+
- Approval-gated calls pause with `AwaitingInput`; approvals/denials resume through
|
|
758
|
+
`submitHitlResponse`. Voice questions and custom typed inputs are unsupported in v1.
|
|
759
|
+
- `projectVoiceEvent` turns voice events into protocol messages with no dangling host tool
|
|
760
|
+
calls. Assistant drafts are keyed per provider output item (falling back to response id), so
|
|
761
|
+
back-to-back responses, multi-item responses, and duplicate final transcript event families
|
|
762
|
+
never concatenate, wipe, or duplicate messages. `sequenceVoiceEvent`/`dedupeStoredVoiceEvents`
|
|
763
|
+
give replay-safe durable event ids; `voiceSeedTextsFromMessages` seeds new provider sessions
|
|
764
|
+
after reconnect, optionally prefixing user seeds with author display names via
|
|
765
|
+
`{ includeAuthors: true }` for multi-user transcripts.
|
|
766
|
+
- `makeWebSocketVoiceTransport` covers Node/server realtime sessions and requires a host-provided
|
|
767
|
+
`Socket.WebSocketConstructor` layer, such as `Socket.layerWebSocketConstructorGlobal`;
|
|
768
|
+
`@yolk-sdk/agent/providers/openai/speech` provides `makeOpenAiSpeechSynthesizerLayer` and
|
|
769
|
+
`makeOpenAiTranscriberLayer` for the provider-neutral voice services.
|
|
770
|
+
`VoiceSpeechRequest.instructions` steers delivery style only, and
|
|
771
|
+
provider 429s (rate limit or exhausted credits) surface as `VoiceSpeechError` code
|
|
772
|
+
`rate_limited` so hosts can distinguish quota from outage.
|
|
773
|
+
- Browser WebRTC hosts that implement `WebRtcPeerConnectionLike`
|
|
774
|
+
(`@yolk-sdk/agent/voice/browser`) treat `addTrack(track, stream)` as a void command. The
|
|
775
|
+
transport discards the DOM `RTCRtpSender`. Hosts and fakes must not read a sender from this
|
|
776
|
+
capability. Real `RTCPeerConnection.addTrack` remains assignable.
|
|
777
|
+
- `protocolToolCallFromVoice` still returns `ToolCall`. Voice raw argument JSON admits finite
|
|
778
|
+
JSON (`Schema.Json`). Actual `null`, `false`, and `0` still admit as those values. Non-JSON
|
|
779
|
+
and non-finite numbers fail admission: raw text `1e999` projects as the argument string
|
|
780
|
+
`'1e999'`, and `decideVoiceToolCall` approval display params are `{ argumentsJson: '1e999' }`
|
|
781
|
+
(not `Infinity`; do not demonstrate with `JSON.stringify(Infinity)`, which is `null`). Nested
|
|
782
|
+
overflow such as `{"n":1e999}` takes the same mapper-specific fallbacks. Approval identifiers,
|
|
783
|
+
gates, deny, and execution schema validation are unchanged.
|
|
784
|
+
|
|
785
|
+
## Classifier models
|
|
786
|
+
|
|
787
|
+
`@yolk-sdk/agent/classification` is a provider-neutral contract for classifier models such as
|
|
788
|
+
TypeSafe's Jev: one `state` (a string, JSON object, or JSON array) and named `boolean`, `choice`
|
|
789
|
+
(2-255 options), or `score` (2-10 levels, lowest first) questions, answered together with
|
|
790
|
+
probabilities. `classify` types each answer from its question (a choice answer's `choice` is the
|
|
791
|
+
union of its option keys) and checks every answer against its question. Probabilities are kept as
|
|
792
|
+
returned, never renormalized. Failures are typed (`ClassificationRequestInvalid`,
|
|
793
|
+
`ClassificationProviderError`, `ClassificationResponseInvalid`); a response that fails to decode
|
|
794
|
+
keeps the billed `usage`. Classification is a read; authorization stays host policy.
|
|
795
|
+
|
|
796
|
+
`@yolk-sdk/agent/providers/vercel/ai-gateway-classifier` calls AI Gateway `POST /v1/evaluate`
|
|
797
|
+
(Gateway calls this evaluation) with `typesafe-ai/jev` by default and the same Gateway credential
|
|
798
|
+
as the chat provider:
|
|
93
799
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
800
|
+
```ts
|
|
801
|
+
import { Effect, Redacted } from 'effect'
|
|
802
|
+
import { FetchHttpClient } from 'effect/http'
|
|
803
|
+
import { classify } from '@yolk-sdk/agent/classification'
|
|
804
|
+
import { makeVercelAiGatewayClassifierLayer } from '@yolk-sdk/agent/providers/vercel/ai-gateway-classifier'
|
|
805
|
+
|
|
806
|
+
const program = classify({
|
|
807
|
+
state: { subject: 'Invoice question', body: 'I was charged twice.' },
|
|
808
|
+
questions: {
|
|
809
|
+
route: {
|
|
810
|
+
type: 'choice',
|
|
811
|
+
instructions: 'Which team should handle this ticket?',
|
|
812
|
+
criteria: { billing: 'Payments and refunds.', bug: 'Product defects.' }
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}).pipe(
|
|
816
|
+
Effect.map(result => result.answers.route.choice), // 'billing' | 'bug'
|
|
817
|
+
Effect.provide(makeVercelAiGatewayClassifierLayer({ apiKey: Redacted.make(gatewayKey) })),
|
|
818
|
+
Effect.provide(FetchHttpClient.layer)
|
|
819
|
+
)
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
`providerOptions` passes through unchanged (for example `{ gateway: { zeroDataRetention: true } }`).
|
|
823
|
+
`providerMetadata.gateway.cost` becomes `usage.costUsd`, and `x-ai-gateway-evaluation-fallback-*`
|
|
824
|
+
response headers are kept in `providerMetadata.evaluationFallbackHeaders`.
|
|
825
|
+
|
|
826
|
+
## Subagents
|
|
827
|
+
|
|
828
|
+
`subagent` is the package-owned contract for child-agent delegation. The SDK provides schema,
|
|
829
|
+
validation, non-recursive module wiring, subagent result extraction, and structured result
|
|
830
|
+
metadata. Host apps provide inline or independently durable child execution.
|
|
97
831
|
|
|
98
832
|
Recommended setup:
|
|
99
833
|
|
|
100
|
-
- expose `
|
|
834
|
+
- expose `makeNonRecursiveSubagentToolModule` only to the top-level agent
|
|
101
835
|
- resolve subagent tools with `subagent: true`
|
|
102
|
-
- omit `
|
|
836
|
+
- omit `subagent` from subagent toolsets
|
|
103
837
|
- include only tools that are safe for autonomous delegated work
|
|
104
838
|
- use `makeSubagentRunId(call.id)` for protocol-aligned run ids
|
|
105
|
-
-
|
|
106
|
-
|
|
107
|
-
|
|
839
|
+
- optionally configure model and reasoning-effort choices so the parent can select child runtime settings
|
|
840
|
+
- treat omitted `model` and `reasoning_effort` parameters as inheritance of host runtime settings
|
|
841
|
+
- return `makeSubagentToolResult(...)` so UI can show subagent id, type, status, model, reasoning effort, timing, optional usage/turns, and typed failure metadata
|
|
842
|
+
- use `subagentUsageFromToolResult(...)` when a host must add child usage to cumulative workflow usage
|
|
843
|
+
|
|
844
|
+
Durable hosts may opt into `background: true` in the tool registration options. This advertises
|
|
845
|
+
an optional model parameter `background`; inline hosts keep their existing schema and behavior.
|
|
846
|
+
Return `makeSubagentAcceptedToolResult({ callId, workflowRunId, parentRunId })` for background acceptance.
|
|
847
|
+
The optional parent identity lets a later conversation run address the original child. Keep
|
|
848
|
+
acceptance independent of how quickly the child finishes.
|
|
849
|
+
It emits normal tool completion but **not** `SubagentCompleted`, and carries no usage. Keep the
|
|
850
|
+
logical `subagent:<toolCallId>` identity separate from the physical Workflow id. Never append a
|
|
851
|
+
second tool result for the original launch. Hosts may deliver findings automatically or expose
|
|
852
|
+
host-owned status/wait tools whose observations do not masquerade as fresh child usage. The SDK
|
|
853
|
+
registers none of those observation tools and promises no automatic delivery. Its default background
|
|
854
|
+
parameter and acceptance text therefore defer to host instructions instead of naming unavailable
|
|
855
|
+
tools. Hosts should describe their actual completion policy in model-visible instructions and retain
|
|
856
|
+
lookup identities in accepted-result text if they customize it; structured metadata alone may not
|
|
857
|
+
survive provider lowering. Host-owned storage must remain readable after parent end.
|
|
858
|
+
|
|
859
|
+
A lost control response or exhausted observation budget is not a terminal child failure. Hosts
|
|
860
|
+
can return a `ToolResult` with `structuredContent.type: 'subagent_observation'` and a matching
|
|
861
|
+
`subagent_run_id: makeSubagentRunId(call.id)`. The loop completes the tool observation but suppresses
|
|
862
|
+
`SubagentCompleted`; nested results do not contribute child usage. Include truthful status and an
|
|
863
|
+
owned recovery handle in the observation. Use normal final results for genuine terminal outcomes,
|
|
864
|
+
not this marker. These child observations are separate from generic background tool `acceptance`.
|
|
865
|
+
|
|
866
|
+
`prepareToolBatch` from `@yolk-sdk/agent/loop` exposes the same HITL preflight used by the loop.
|
|
867
|
+
Durable orchestration must check `pendingRequests` before dispatching **any** tool, even calls
|
|
868
|
+
listed in `callsToExecute`. Preserve synthetic results and original call ordering when committing.
|
|
869
|
+
|
|
870
|
+
Keep host-owned subagent execution wiring outside this package; pass only the package subagent contract across the boundary.
|
|
871
|
+
|
|
872
|
+
## Background tool calls
|
|
873
|
+
|
|
874
|
+
Any `makeTool` registration can opt into model-chosen background execution with `background: true`.
|
|
875
|
+
The flag is inert until `resolveTools(modules, context, { backgroundHost })` receives a
|
|
876
|
+
`BackgroundToolHost`, which asserts a real lifecycle owner (durable run, queue, or session) exists.
|
|
877
|
+
Without a host, definitions, approval ids, and inline behavior are unchanged.
|
|
878
|
+
|
|
879
|
+
- Activated tools advertise a required `{ execution: 'foreground' | 'background', arguments }`
|
|
880
|
+
envelope; the original parameter schema nests under `arguments` and `$defs` stay at the root.
|
|
881
|
+
Only document-root `#/$defs/...` references (without percent-encoded fragments) are supported.
|
|
882
|
+
Other reference forms and resource/anchor keywords (`$id`, legacy `id`, `$anchor`, `$dynamicAnchor`,
|
|
883
|
+
`$dynamicRef`, `$recursiveAnchor`, `$recursiveRef`) fail activation with
|
|
884
|
+
`ToolRegistryError.cause: 'background_unsupported_schema'`. Literal defaults/examples/const/enum
|
|
885
|
+
data are not traversed as schemas.
|
|
886
|
+
- The registry validates the envelope and original parameters without business effects, strips the
|
|
887
|
+
control fields, then executes inline or calls `host.accept({ call, request, context })`.
|
|
888
|
+
`makeTool` invalid business arguments still return structured model-visible errors in either
|
|
889
|
+
mode, without business/admission effects. Raw validator and host errors remain typed failures.
|
|
890
|
+
- `accept` returns a versioned `BackgroundToolAccepted` receipt (`{ version: 1, executionId }`),
|
|
891
|
+
never a closure. Make it idempotent per call id; fail with a `ToolError` to decline. The registry
|
|
892
|
+
never falls back to inline execution.
|
|
893
|
+
- Use protocol `toolResultMessageFromResult(result, envelope?)` to preserve every result field and
|
|
894
|
+
receipt when creating transcript messages; timestamps/authors remain explicit host inputs.
|
|
895
|
+
- The result is one acknowledgement `ToolResult` with typed `acceptance` metadata; the loop emits
|
|
896
|
+
`ToolExecutionAccepted` (no `ToolExecutionCompleted`, no usage). Client state, chat projection,
|
|
897
|
+
and tool cards treat `Accepted` as settled but not completed; active input/approval/Started
|
|
898
|
+
replays cannot replace accepted calls or receipts, including across turn cleanup and hydration.
|
|
899
|
+
- Activated definitions are unsupported in voice/realtime, including foreground envelope calls.
|
|
900
|
+
Resolve voice toolsets without a background host. Synchronous realtime tool/config mappers throw
|
|
901
|
+
`VoiceToolBridgeError` for unsupported activation **and** for non-JSON tool `parameters`; use
|
|
902
|
+
`toOpenAiRealtimeToolEffect`, `makeOpenAiRealtimeSessionConfigEffect`, or
|
|
903
|
+
`openAiRealtimeSessionConfigFromVoiceEffect` inside Effect programs to catch that typed error.
|
|
904
|
+
Unexpected mapper defects stay defects, not `VoiceToolBridgeError`. Voice handlers deny before
|
|
905
|
+
approval matching, and the low-level bridge rejects activated registry dispatch before validation,
|
|
906
|
+
inline execution, or admission.
|
|
907
|
+
- Raw `ToolRegistration` objects need a side-effect-free `validate` to activate; the loop-owned
|
|
908
|
+
`question` and `subagent` tools cannot activate (subagents keep `makeSubagentAcceptedToolResult`).
|
|
909
|
+
- Manual approval fences the whole batch; activated calls bind the approval `requestId` to the tool
|
|
910
|
+
name, mode, and canonical arguments, and malformed envelopes are rejected before any prompt.
|
|
911
|
+
IDs intentionally contain the full canonical payload: hosts must accommodate opaque, potentially
|
|
912
|
+
long IDs or enforce input bounds before admission; never truncate or rebuild them.
|
|
913
|
+
- Hosts own authorization, status/wait tools, cancellation, terminal storage, usage, and delivery.
|
|
914
|
+
Never append a second result for the original call.
|
|
915
|
+
|
|
916
|
+
## Code mode tool contract
|
|
917
|
+
|
|
918
|
+
These options are the tool contract that [`@yolk-sdk/codemode`](https://github.com/magoz/yolk-sdk/blob/main/packages/codemode/README.md) builds on.
|
|
919
|
+
This package declares them; it does not run scripts.
|
|
920
|
+
|
|
921
|
+
- `makeTool({ output })` adds declaration-only `ToolDef.outputSchema`, lowered like `parameters`.
|
|
922
|
+
- `callableBy: 'all' | 'model' | 'codemode'` (default `all`) decides who may call a tool. For
|
|
923
|
+
`codemode` only, `discovery: 'listed' | 'search'` (default `listed`) decides how scripts find it.
|
|
924
|
+
Codemode-only tools never reach providers. Approval, input, interaction, activated background,
|
|
925
|
+
`question`, `subagent`, and nested-access tools never run from code mode; `resolveTools` rejects
|
|
926
|
+
`callableBy: 'codemode'` on them.
|
|
927
|
+
- `nestedToolAccess: true` gives a registration's `execute` a `nested` executor over the other
|
|
928
|
+
code-mode-callable tools of the same resolution and host context. Nested calls run through the
|
|
929
|
+
resolved execute path and fail closed with model-visible error results. Assign nested call ids as
|
|
930
|
+
`<parentToolCallId>/<seq>`.
|
|
931
|
+
- `describe: ({ tools }) => string` on a nested-access registration computes its resolved
|
|
932
|
+
description from those nested tools; `def.description` stays the static fallback.
|
|
933
|
+
- Report nested calls with protocol `recordNestedToolCall` and `nestedToolCallResultFields`. The
|
|
934
|
+
bounded `ToolResult.nestedCalls` record and summed `ToolResult.usage` never reach the model:
|
|
935
|
+
`toolResultMessageFromResult` drops both, and the loop does not add `ToolResult.usage` to run
|
|
936
|
+
usage. Capture them from the `ToolResult` or tool events when you need audit or billing records.
|
|
937
|
+
Size the record with `makeNestedToolCallRecorder({ maxCalls })`; per-status `counts` cover
|
|
938
|
+
every call, dropped ones included.
|
|
939
|
+
|
|
940
|
+
## Durable tool ledger
|
|
941
|
+
|
|
942
|
+
Steps that hosts re-execute (Vercel Workflow's queue is at-least-once) must not repeat writes.
|
|
943
|
+
Pass `resolveTools(modules, context, { ledger: { store } })` with a host-implemented durable
|
|
944
|
+
`ToolLedgerStore` scoped to the run: every ledgered call (by default every non-`read` call plus the
|
|
945
|
+
built-in `subagent` tool, top-level or nested in code mode) runs at most once per ledger key. Add
|
|
946
|
+
custom delegation tools with `isLedgered`. Input and interaction tools are never ledgered; their
|
|
947
|
+
at-most-once guarantee is the host's `InteractionHost` receipts. A different call under the same key (tool name or a
|
|
948
|
+
SHA-256 `argsDigest` of the full arguments, a stable format hosts persist) is a conflict, never a
|
|
949
|
+
replay. Completed calls return their stored result, concurrent duplicates wait, and calls abandoned
|
|
950
|
+
by a crash are never re-run (the model is told to verify). Executors receive a stable
|
|
951
|
+
`idempotencyKey`. Stores get the lease length (`leaseMs`) so they can use database time, and must
|
|
952
|
+
keep their operations interruptible (the ledger's timeouts cannot cut uninterruptible store work).
|
|
953
|
+
`deadline` bounds only waiting for a duplicate; recording an outcome can take about 15 s more.
|
|
954
|
+
`onLedgerDecision` reports each call's decision (`fresh`, `completed`, `in_flight_wait`, ...) for
|
|
955
|
+
logs and metrics. Without the option behavior is unchanged. See
|
|
956
|
+
[the tools README](https://github.com/magoz/yolk-sdk/blob/main/packages/agent/src/tools/README.md#durable-tool-ledger).
|
|
957
|
+
|
|
958
|
+
## Tool failures
|
|
959
|
+
|
|
960
|
+
Use `modelVisibleToolError(...)` for expected tool-domain failures the model can recover
|
|
961
|
+
from, such as invalid arguments, not-found resources, denied policy, or unavailable upstream
|
|
962
|
+
data. `makeTool` converts these failures into `ToolResult.isError = true` so the agent can
|
|
963
|
+
see the message and continue. The result includes structured content with `type`, `tool`,
|
|
964
|
+
`reason`, `message`, and optional `details` for UI/runtime handling.
|
|
965
|
+
|
|
966
|
+
Optional `makeTool({ invalidParamsMessage })` receives the `Schema.SchemaError` produced by
|
|
967
|
+
decoding `parameters` through its JSON codec (validate and execute). The decode error is passed
|
|
968
|
+
through unwrapped. Default text is `Invalid ${name} arguments: ${String(error)}`, which keeps the
|
|
969
|
+
`SchemaError(...)` wrapper, followed by one line per object (path and allowed-key set) naming its unknown keys and
|
|
970
|
+
listing the allowed keys. Custom callbacks can append the same hint with `withToolArgumentsErrorHint(message, error)`. In Effect 4, `SchemaError` extends native `Error`, but the
|
|
971
|
+
wrapper remains part of this tool-message contract; do not default to `.message`.
|
|
972
|
+
Existing `(error: unknown) => string` callbacks remain assignable.
|
|
973
|
+
|
|
974
|
+
Thrown `ToolError`s become model-visible failed tool results plus `ToolExecutionError` events,
|
|
975
|
+
so keep messages safe and non-secret. Reserve stream failure for provider/runtime defects,
|
|
976
|
+
aborts, and implementation bugs outside typed tool execution.
|
|
108
977
|
|
|
109
978
|
## Host responsibilities
|
|
110
979
|
|
|
111
|
-
- Choose models/providers and
|
|
980
|
+
- Choose models/providers and provide an LLM provider layer, using SDK provider subpaths or host adapters.
|
|
981
|
+
- Store, refresh, revoke, and authorize OAuth credentials; expose only runtime access tokens.
|
|
982
|
+
- Configure model-specific provider output-token limits.
|
|
983
|
+
- Build UI components and styling, own auth, and wire headless React hooks to host transports.
|
|
112
984
|
- Persist sessions, transcripts, and append logs.
|
|
985
|
+
- Persist/return one `ToolResultMessage` for every host tool call, including `isError` failures.
|
|
986
|
+
- Persist terminal provider failures and clear active run ids where applicable.
|
|
113
987
|
- Provide tools, approval policy, auth, storage, and observability.
|
|
988
|
+
- When steps can re-execute, implement a durable `ToolLedgerStore` scoped to one run (plus the turn
|
|
989
|
+
or step when call ids can repeat), keep its operations interruptible, and reserve about 15 s of
|
|
990
|
+
the step budget after `deadline` for recording outcomes.
|
|
991
|
+
- If you send `ToolDef`s to providers yourself (outside `run`/`runModelTurn`), filter them with
|
|
992
|
+
protocol `providerToolDefs`; codemode-only tools must never reach providers. Executor decorators
|
|
993
|
+
outside `ResolvedToolSet.execute` do not see nested code mode calls.
|
|
114
994
|
- Compact context and decide memory/search policy.
|
|
115
995
|
|
|
116
996
|
## Boundaries
|
|
117
997
|
|
|
118
|
-
-
|
|
998
|
+
- Core loop/protocol/runtime/tools have no React, Next.js, provider SDKs, auth, storage drivers, or app concepts.
|
|
999
|
+
- `@yolk-sdk/agent/compaction` combines pure planning/formatting helpers with Effect-native transformer and retry adapters; hosts own thresholds, summaries, compaction payloads, and durable compactor policy.
|
|
1000
|
+
- `@yolk-sdk/agent/classification` is provider-neutral (no Node, React, or provider code); provider subpaths supply `ClassifierModel` layers.
|
|
1001
|
+
- `@yolk-sdk/agent/react` is headless and uses React as an optional peer.
|
|
1002
|
+
- Provider subpaths own vendor wire/auth mechanics only; hosts own token storage, refresh, routing, and policy.
|
|
1003
|
+
- `@yolk-sdk/agent/providers/openai/speech` is server integration requiring runtime
|
|
1004
|
+
`FormData`/`Blob`, a host `HttpClient` layer, and a secret API key; do not invoke it from browser
|
|
1005
|
+
code.
|
|
119
1006
|
- Loop stays stateless: transcript in, events out.
|
|
120
1007
|
- Runtime owns generic session orchestration only; host apps own persistence adapters and policy.
|
|
1008
|
+
- Client HTTP helpers are runtime-portable with a host `HttpClient` layer. Attachment helpers need
|
|
1009
|
+
`Blob`/`File` and may use `FileReader`; the Cloudflare WebSocket transport needs the global
|
|
1010
|
+
`WebSocket` constructor when its stream runs. None read browser globals at import time.
|
|
121
1011
|
- Tools model generic metadata/execution; host apps own concrete tool catalogs.
|
|
122
|
-
- `
|
|
1012
|
+
- `subagent` is the standard delegation tool. Packages define the schema; host apps execute subagents and omit `subagent` from child toolsets in v1.
|
|
123
1013
|
|
|
124
1014
|
## Testing
|
|
125
1015
|
|