@yolk-sdk/agent 0.1.0-canary.95 → 0.1.0-canary.96
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 +114 -37
- 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/state.d.mts +82 -82
- package/dist/client/state.d.mts.map +1 -1
- package/dist/client/transport.d.mts +1 -1
- package/dist/client/transport.mjs +1 -1
- package/dist/loop/error.d.mts +1 -1
- package/dist/loop/error.mjs +1 -1
- package/dist/loop/llm-event.d.mts +1 -1
- package/dist/loop/llm-event.mjs +1 -1
- package/dist/loop/run.d.mts.map +1 -1
- package/dist/loop/run.mjs +16 -5
- 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/protocol/event.d.mts +1 -1
- package/dist/protocol/event.mjs +1 -1
- package/dist/protocol/index.d.mts +4 -3
- package/dist/protocol/index.d.mts.map +1 -1
- package/dist/protocol/index.mjs +4 -3
- package/dist/protocol/nested-tool-calls.d.mts +67 -0
- package/dist/protocol/nested-tool-calls.d.mts.map +1 -0
- package/dist/protocol/nested-tool-calls.mjs +118 -0
- package/dist/protocol/nested-tool-calls.mjs.map +1 -0
- package/dist/protocol/tool.d.mts +47 -1
- package/dist/protocol/tool.d.mts.map +1 -1
- package/dist/protocol/tool.mjs +44 -2
- package/dist/protocol/tool.mjs.map +1 -1
- 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/usage.d.mts +6 -0
- package/dist/providers/anthropic/usage.d.mts.map +1 -1
- package/dist/providers/anthropic/usage.mjs +1 -1
- package/dist/providers/anthropic/usage.mjs.map +1 -1
- package/dist/providers/anthropic-messages-provider-internal.d.mts +6 -0
- package/dist/providers/anthropic-messages-provider-internal.d.mts.map +1 -1
- package/dist/providers/anthropic-messages-provider-internal.mjs +5 -2
- package/dist/providers/anthropic-messages-provider-internal.mjs.map +1 -1
- package/dist/providers/anthropic-provider-internal.mjs +1 -1
- package/dist/providers/openai/codex-usage.d.mts +6 -0
- package/dist/providers/openai/codex-usage.d.mts.map +1 -1
- package/dist/providers/openai/codex-usage.mjs +1 -1
- package/dist/providers/openai/codex-usage.mjs.map +1 -1
- 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/provider.d.mts +1 -1
- package/dist/providers/openai/provider.mjs +1 -1
- package/dist/providers/openai/realtime/client-codec.mjs +1 -1
- package/dist/providers/openai/realtime/session-config.d.mts +7 -3
- package/dist/providers/openai/realtime/session-config.d.mts.map +1 -1
- package/dist/providers/openai/realtime/session-config.mjs +9 -4
- package/dist/providers/openai/realtime/session-config.mjs.map +1 -1
- package/dist/providers/openai-responses-provider-internal.d.mts +1 -1
- package/dist/providers/openai-responses-provider-internal.mjs +1 -1
- 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/usage.d.mts +7 -1
- package/dist/providers/opencode/usage.d.mts.map +1 -1
- package/dist/providers/opencode/usage.mjs +2 -2
- package/dist/providers/opencode/usage.mjs.map +1 -1
- package/dist/providers/provider-error.d.mts +5 -3
- package/dist/providers/provider-error.d.mts.map +1 -1
- package/dist/providers/provider-error.mjs +6 -5
- package/dist/providers/provider-error.mjs.map +1 -1
- 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.map +1 -1
- package/dist/providers/vercel/ai-gateway-provider.mjs +2 -1
- package/dist/providers/vercel/ai-gateway-provider.mjs.map +1 -1
- 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/usage.d.mts +6 -0
- package/dist/providers/xai/usage.d.mts.map +1 -1
- package/dist/providers/xai/usage.mjs +1 -1
- package/dist/providers/xai/usage.mjs.map +1 -1
- package/dist/react/chat-items.d.mts +68 -68
- package/dist/react/chat-items.d.mts.map +1 -1
- package/dist/react/chat-items.mjs +1 -1
- package/dist/react/chat-messages.d.mts +96 -96
- package/dist/react/chat-messages.d.mts.map +1 -1
- package/dist/react/chat-session-events.d.mts +1 -1
- package/dist/react/chat-session-events.mjs +1 -1
- package/dist/runtime/error.d.mts +1 -1
- package/dist/runtime/error.mjs +1 -1
- package/dist/runtime/session-event-store.d.mts +1 -1
- package/dist/runtime/session-event-store.mjs +1 -1
- package/dist/skillset/merge.d.mts +1 -1
- package/dist/tools/background.d.mts +1 -1
- package/dist/tools/background.mjs +1 -1
- package/dist/tools/index.d.mts +2 -2
- package/dist/tools/input.d.mts +1 -1
- package/dist/tools/input.mjs +1 -1
- package/dist/tools/interaction.d.mts +1 -1
- package/dist/tools/interaction.mjs +1 -1
- package/dist/tools/registry.d.mts +53 -7
- package/dist/tools/registry.d.mts.map +1 -1
- package/dist/tools/registry.mjs +111 -39
- package/dist/tools/registry.mjs.map +1 -1
- package/dist/tools/subagent.mjs +1 -1
- package/dist/voice/projection.d.mts +1 -1
- package/dist/voice/projection.mjs +1 -1
- package/dist/voice/protocol.d.mts +1 -1
- package/dist/voice/protocol.mjs +1 -1
- package/dist/voice/session-log.d.mts +1 -1
- package/dist/voice/session-log.mjs +1 -1
- package/dist/voice/speech.d.mts +1 -1
- package/dist/voice/speech.mjs +1 -1
- package/dist/voice/tool-bridge.mjs +1 -1
- package/dist/voice/tool-server.d.mts.map +1 -1
- package/dist/voice/tool-server.mjs +2 -1
- package/dist/voice/tool-server.mjs.map +1 -1
- package/package.json +39 -3
- 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/loop/run.ts +31 -3
- package/src/loop/services/llm-provider.ts +3 -0
- package/src/protocol/index.ts +28 -1
- package/src/protocol/nested-tool-calls.ts +230 -0
- package/src/protocol/tool.ts +64 -1
- 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/usage.ts +7 -1
- package/src/providers/anthropic-messages-provider-internal.ts +8 -1
- package/src/providers/openai/codex-usage.ts +7 -1
- 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/realtime/session-config.ts +12 -5
- 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/usage.ts +8 -2
- package/src/providers/provider-error.ts +8 -5
- 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 +2 -3
- 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/usage.ts +7 -1
- package/src/tools/README.md +19 -0
- package/src/tools/index.ts +3 -0
- package/src/tools/registry.ts +307 -59
- package/src/voice/tool-server.ts +5 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @yolk-sdk/agent
|
|
2
2
|
|
|
3
|
-
Domain-free agent protocol, loop, runtime, Effect-native client, compaction, tools, React, providers, OAuth, skillset, and voice primitives.
|
|
3
|
+
Domain-free agent protocol, loop, runtime, Effect-native client, compaction, classifier models, tools, React, providers, OAuth, skillset, and voice primitives.
|
|
4
4
|
|
|
5
5
|
Root export is intentionally empty. Import feature APIs from explicit subpaths.
|
|
6
6
|
|
|
@@ -12,46 +12,55 @@ pnpm add @yolk-sdk/agent@canary effect@4.0.0-rc.115
|
|
|
12
12
|
|
|
13
13
|
Add `react` if you use `@yolk-sdk/agent/react` or `@yolk-sdk/agent/voice/react`.
|
|
14
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
|
+
|
|
15
17
|
Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
|
|
16
18
|
Use the SDK's matching Effect version (`4.0.0-rc.115`) in host code.
|
|
17
19
|
Published package metadata requires Node.js 22+.
|
|
18
20
|
|
|
19
21
|
## Subpaths
|
|
20
22
|
|
|
21
|
-
| Subpath
|
|
22
|
-
|
|
|
23
|
-
| `@yolk-sdk/agent/protocol`
|
|
24
|
-
| `@yolk-sdk/agent/loop`
|
|
25
|
-
| `@yolk-sdk/agent/loop/testing`
|
|
26
|
-
| `@yolk-sdk/agent/runtime`
|
|
27
|
-
| `@yolk-sdk/agent/client`
|
|
28
|
-
| `@yolk-sdk/agent/compaction`
|
|
29
|
-
| `@yolk-sdk/agent/
|
|
30
|
-
| `@yolk-sdk/agent/
|
|
31
|
-
| `@yolk-sdk/agent/
|
|
32
|
-
| `@yolk-sdk/agent/
|
|
33
|
-
| `@yolk-sdk/agent/providers/openai
|
|
34
|
-
| `@yolk-sdk/agent/providers/openai/codex
|
|
35
|
-
| `@yolk-sdk/agent/providers/openai/codex-
|
|
36
|
-
| `@yolk-sdk/agent/providers/openai/provider`
|
|
37
|
-
| `@yolk-sdk/agent/providers/openai/
|
|
38
|
-
| `@yolk-sdk/agent/providers/openai/
|
|
39
|
-
| `@yolk-sdk/agent/providers/
|
|
40
|
-
| `@yolk-sdk/agent/providers/
|
|
41
|
-
| `@yolk-sdk/agent/providers/
|
|
42
|
-
| `@yolk-sdk/agent/providers/
|
|
43
|
-
| `@yolk-sdk/agent/providers/
|
|
44
|
-
| `@yolk-sdk/agent/providers/
|
|
45
|
-
| `@yolk-sdk/agent/providers/
|
|
46
|
-
| `@yolk-sdk/agent/providers/
|
|
47
|
-
| `@yolk-sdk/agent/providers/
|
|
48
|
-
| `@yolk-sdk/agent/providers/
|
|
49
|
-
| `@yolk-sdk/agent/providers/
|
|
50
|
-
| `@yolk-sdk/agent/providers/
|
|
51
|
-
| `@yolk-sdk/agent/
|
|
52
|
-
| `@yolk-sdk/agent/
|
|
53
|
-
| `@yolk-sdk/agent/
|
|
54
|
-
| `@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 |
|
|
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 |
|
|
55
64
|
|
|
56
65
|
## Imports
|
|
57
66
|
|
|
@@ -248,7 +257,7 @@ const usageEffect = fetchOpenCodeGoSubscriptionUsage(Redacted.make(hostOpenCodeG
|
|
|
248
257
|
}).pipe(Effect.provide(FetchHttpClient.layer))
|
|
249
258
|
```
|
|
250
259
|
|
|
251
|
-
The
|
|
260
|
+
The API-key endpoint (default `openCodeGoSubscriptionUsageUrl`) returns used percentages/reset instants for `five-hour`, `seven-day`, and
|
|
252
261
|
`monthly` windows. Monthly resets follow the subscription's anniversary, not the first of the month;
|
|
253
262
|
the adapter preserves the provider's timestamp. Missing/invalid percentages are omitted, not treated
|
|
254
263
|
as zero. Treat snapshots as best-effort; hosts own polling, stale-data policy, persistence, and UI.
|
|
@@ -430,7 +439,8 @@ version.
|
|
|
430
439
|
Provider adapters return an immutable Effect `Chunk` of semantic window ids, percentages, and
|
|
431
440
|
optional reset/duration fields; hosts own labels, polling, persistence, stale-data policy, alert
|
|
432
441
|
thresholds, billing interpretation, and UI. Configure `requestTimeoutMs` at the server integration
|
|
433
|
-
boundary.
|
|
442
|
+
boundary. Each fetcher defaults to its exported URL constant; the optional `url` override is only
|
|
443
|
+
for a trusted proxy or local emulator, because the credential is sent to it. `FetchHttpClient.layer` is configured for manual
|
|
434
444
|
redirects. A custom `HttpClient` must not follow redirects for these credential-bearing requests.
|
|
435
445
|
|
|
436
446
|
Subscription allowance snapshots are separate from protocol `AgentUsage`, which accounts for tokens
|
|
@@ -748,6 +758,47 @@ handler, approval HITL, transcript projection, and one-shot TTS/STT contracts.
|
|
|
748
758
|
overflow such as `{"n":1e999}` takes the same mapper-specific fallbacks. Approval identifiers,
|
|
749
759
|
gates, deny, and execution schema validation are unchanged.
|
|
750
760
|
|
|
761
|
+
## Classifier models
|
|
762
|
+
|
|
763
|
+
`@yolk-sdk/agent/classification` is a provider-neutral contract for classifier models such as
|
|
764
|
+
TypeSafe's Jev: one `state` (a string, JSON object, or JSON array) and named `boolean`, `choice`
|
|
765
|
+
(2-255 options), or `score` (2-10 levels, lowest first) questions, answered together with
|
|
766
|
+
probabilities. `classify` types each answer from its question (a choice answer's `choice` is the
|
|
767
|
+
union of its option keys) and checks every answer against its question. Probabilities are kept as
|
|
768
|
+
returned, never renormalized. Failures are typed (`ClassificationRequestInvalid`,
|
|
769
|
+
`ClassificationProviderError`, `ClassificationResponseInvalid`); a response that fails to decode
|
|
770
|
+
keeps the billed `usage`. Classification is a read; authorization stays host policy.
|
|
771
|
+
|
|
772
|
+
`@yolk-sdk/agent/providers/vercel/ai-gateway-classifier` calls AI Gateway `POST /v1/evaluate`
|
|
773
|
+
(Gateway calls this evaluation) with `typesafe-ai/jev` by default and the same Gateway credential
|
|
774
|
+
as the chat provider:
|
|
775
|
+
|
|
776
|
+
```ts
|
|
777
|
+
import { Effect, Redacted } from 'effect'
|
|
778
|
+
import { FetchHttpClient } from 'effect/unstable/http'
|
|
779
|
+
import { classify } from '@yolk-sdk/agent/classification'
|
|
780
|
+
import { makeVercelAiGatewayClassifierLayer } from '@yolk-sdk/agent/providers/vercel/ai-gateway-classifier'
|
|
781
|
+
|
|
782
|
+
const program = classify({
|
|
783
|
+
state: { subject: 'Invoice question', body: 'I was charged twice.' },
|
|
784
|
+
questions: {
|
|
785
|
+
route: {
|
|
786
|
+
type: 'choice',
|
|
787
|
+
instructions: 'Which team should handle this ticket?',
|
|
788
|
+
criteria: { billing: 'Payments and refunds.', bug: 'Product defects.' }
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}).pipe(
|
|
792
|
+
Effect.map(result => result.answers.route.choice), // 'billing' | 'bug'
|
|
793
|
+
Effect.provide(makeVercelAiGatewayClassifierLayer({ apiKey: Redacted.make(gatewayKey) })),
|
|
794
|
+
Effect.provide(FetchHttpClient.layer)
|
|
795
|
+
)
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
`providerOptions` passes through unchanged (for example `{ gateway: { zeroDataRetention: true } }`).
|
|
799
|
+
`providerMetadata.gateway.cost` becomes `usage.costUsd`, and `x-ai-gateway-evaluation-fallback-*`
|
|
800
|
+
response headers are kept in `providerMetadata.evaluationFallbackHeaders`.
|
|
801
|
+
|
|
751
802
|
## Subagents
|
|
752
803
|
|
|
753
804
|
`subagent` is the package-owned contract for child-agent delegation. The SDK provides schema,
|
|
@@ -838,6 +889,28 @@ Without a host, definitions, approval ids, and inline behavior are unchanged.
|
|
|
838
889
|
- Hosts own authorization, status/wait tools, cancellation, terminal storage, usage, and delivery.
|
|
839
890
|
Never append a second result for the original call.
|
|
840
891
|
|
|
892
|
+
## Code mode tool contract
|
|
893
|
+
|
|
894
|
+
These options are the tool contract that [`@yolk-sdk/codemode`](../codemode/README.md) builds on.
|
|
895
|
+
This package declares them; it does not run scripts.
|
|
896
|
+
|
|
897
|
+
- `makeTool({ output })` adds declaration-only `ToolDef.outputSchema`, lowered like `parameters`.
|
|
898
|
+
- `callableBy: 'all' | 'model' | 'codemode'` (default `all`) decides who may call a tool. For
|
|
899
|
+
`codemode` only, `discovery: 'listed' | 'search'` (default `listed`) decides how scripts find it.
|
|
900
|
+
Codemode-only tools never reach providers. Approval, input, interaction, activated background,
|
|
901
|
+
`question`, `subagent`, and nested-access tools never run from code mode; `resolveTools` rejects
|
|
902
|
+
`callableBy: 'codemode'` on them.
|
|
903
|
+
- `nestedToolAccess: true` gives a registration's `execute` a `nested` executor over the other
|
|
904
|
+
code-mode-callable tools of the same resolution and host context. Nested calls run through the
|
|
905
|
+
resolved execute path and fail closed with model-visible error results. Assign nested call ids as
|
|
906
|
+
`<parentToolCallId>/<seq>`.
|
|
907
|
+
- `describe: ({ tools }) => string` on a nested-access registration computes its resolved
|
|
908
|
+
description from those nested tools; `def.description` stays the static fallback.
|
|
909
|
+
- Report nested calls with protocol `recordNestedToolCall` and `nestedToolCallResultFields`. The
|
|
910
|
+
bounded `ToolResult.nestedCalls` record and summed `ToolResult.usage` never reach the model:
|
|
911
|
+
`toolResultMessageFromResult` drops both, and the loop does not add `ToolResult.usage` to run
|
|
912
|
+
usage. Capture them from the `ToolResult` or tool events when you need audit or billing records.
|
|
913
|
+
|
|
841
914
|
## Tool failures
|
|
842
915
|
|
|
843
916
|
Use `modelVisibleToolError(...)` for expected tool-domain failures the model can recover
|
|
@@ -867,12 +940,16 @@ aborts, and implementation bugs outside typed tool execution.
|
|
|
867
940
|
- Persist/return one `ToolResultMessage` for every host tool call, including `isError` failures.
|
|
868
941
|
- Persist terminal provider failures and clear active run ids where applicable.
|
|
869
942
|
- Provide tools, approval policy, auth, storage, and observability.
|
|
943
|
+
- If you send `ToolDef`s to providers yourself (outside `run`/`runModelTurn`), filter them with
|
|
944
|
+
protocol `providerToolDefs`; codemode-only tools must never reach providers. Executor decorators
|
|
945
|
+
outside `ResolvedToolSet.execute` do not see nested code mode calls.
|
|
870
946
|
- Compact context and decide memory/search policy.
|
|
871
947
|
|
|
872
948
|
## Boundaries
|
|
873
949
|
|
|
874
950
|
- Core loop/protocol/runtime/tools have no React, Next.js, provider SDKs, auth, storage drivers, or app concepts.
|
|
875
951
|
- `@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.
|
|
952
|
+
- `@yolk-sdk/agent/classification` is provider-neutral (no Node, React, or provider code); provider subpaths supply `ClassifierModel` layers.
|
|
876
953
|
- `@yolk-sdk/agent/react` is headless and uses React as an optional peer.
|
|
877
954
|
- Provider subpaths own vendor wire/auth mechanics only; hosts own token storage, refresh, routing, and policy.
|
|
878
955
|
- `@yolk-sdk/agent/providers/openai/speech` is server integration requiring runtime
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
import { ProviderErrorInfo } from "@yolk-sdk/agent/protocol";
|
|
3
|
+
|
|
4
|
+
//#region src/classification/errors.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Why an answer does not fit its question:
|
|
7
|
+
*
|
|
8
|
+
* - `missing_answer`: a question has no answer.
|
|
9
|
+
* - `unexpected_answer`: an answer names no question that was asked.
|
|
10
|
+
* - `type_mismatch`: the answer's `type` is not the question's.
|
|
11
|
+
* - `invalid_probability`: a probability is missing, not a number, non-finite, or outside `[0, 1]`.
|
|
12
|
+
* - `invalid_confidence`: a confidence is not a finite number in `[0, 1]`.
|
|
13
|
+
* - `invalid_choice`: a choice answer names no option of its question.
|
|
14
|
+
* - `invalid_score`: a score answer has no finite `score`.
|
|
15
|
+
* - `malformed_answer`: the answer is not an object.
|
|
16
|
+
*/
|
|
17
|
+
declare const ClassificationAnswerIssueReason: Schema.Literals<readonly ["missing_answer", "unexpected_answer", "type_mismatch", "invalid_probability", "invalid_confidence", "invalid_choice", "invalid_score", "malformed_answer"]>;
|
|
18
|
+
type ClassificationAnswerIssueReason = typeof ClassificationAnswerIssueReason.Type;
|
|
19
|
+
/** `malformed_response`: the response body is not the provider's documented envelope. */
|
|
20
|
+
declare const ClassificationResponseIssue: Schema.Literals<readonly ["malformed_response", "missing_answer", "unexpected_answer", "type_mismatch", "invalid_probability", "invalid_confidence", "invalid_choice", "invalid_score", "malformed_answer"]>;
|
|
21
|
+
type ClassificationResponseIssue = typeof ClassificationResponseIssue.Type;
|
|
22
|
+
declare const ClassificationRequestInvalid_base: Schema.Class<ClassificationRequestInvalid, Schema.TaggedStruct<"ClassificationRequestInvalid", {
|
|
23
|
+
readonly message: Schema.String;
|
|
24
|
+
}>, import("effect/Cause").YieldableError>;
|
|
25
|
+
/** The request does not satisfy the classification contract; nothing was sent. */
|
|
26
|
+
declare class ClassificationRequestInvalid extends ClassificationRequestInvalid_base {}
|
|
27
|
+
declare const ClassificationProviderError_base: Schema.Class<ClassificationProviderError, Schema.TaggedStruct<"ClassificationProviderError", {
|
|
28
|
+
readonly message: Schema.String;
|
|
29
|
+
readonly retryable: Schema.Boolean;
|
|
30
|
+
readonly provider: typeof ProviderErrorInfo;
|
|
31
|
+
}>, import("effect/Cause").YieldableError>;
|
|
32
|
+
/**
|
|
33
|
+
* The provider could not be reached or rejected the request. `message` is safe to show: it never
|
|
34
|
+
* carries provider bodies, headers, or credentials. `provider` classifies the failure (status,
|
|
35
|
+
* provider error code, retry delay).
|
|
36
|
+
*/
|
|
37
|
+
declare class ClassificationProviderError extends ClassificationProviderError_base {}
|
|
38
|
+
declare const ClassificationResponseInvalid_base: Schema.Class<ClassificationResponseInvalid, Schema.TaggedStruct<"ClassificationResponseInvalid", {
|
|
39
|
+
readonly message: Schema.String; /** Provider id, when a provider (not the typed `classify` check) found the issue. */
|
|
40
|
+
readonly provider: Schema.optional<Schema.String>;
|
|
41
|
+
readonly reason: Schema.Literals<readonly ["malformed_response", "missing_answer", "unexpected_answer", "type_mismatch", "invalid_probability", "invalid_confidence", "invalid_choice", "invalid_score", "malformed_answer"]>;
|
|
42
|
+
readonly questionId: Schema.optional<Schema.String>;
|
|
43
|
+
readonly usage: Schema.optional<Schema.Struct<{
|
|
44
|
+
readonly inputTokens: Schema.Int;
|
|
45
|
+
readonly outputTokens: Schema.Int;
|
|
46
|
+
readonly costUsd: Schema.optionalKey<Schema.Finite>;
|
|
47
|
+
}>>;
|
|
48
|
+
}>, import("effect/Cause").YieldableError>;
|
|
49
|
+
/**
|
|
50
|
+
* The provider answered, but the response or one of its answers does not fit the request.
|
|
51
|
+
* `usage` is kept when the provider reported it, because the request was billed.
|
|
52
|
+
*/
|
|
53
|
+
declare class ClassificationResponseInvalid extends ClassificationResponseInvalid_base {}
|
|
54
|
+
type ClassificationError = ClassificationRequestInvalid | ClassificationProviderError | ClassificationResponseInvalid;
|
|
55
|
+
//#endregion
|
|
56
|
+
export { ClassificationAnswerIssueReason, ClassificationError, ClassificationProviderError, ClassificationRequestInvalid, ClassificationResponseInvalid, ClassificationResponseIssue };
|
|
57
|
+
//# sourceMappingURL=errors.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../src/classification/errors.ts"],"mappings":";;;;;;AAgBA;;;;AAA4C;AAW5C;;;;AAAyF;cAX5E,+BAAA,EAA+B,MAAA,CAAA,QAAA;AAAA,KAWhC,+BAAA,UAAyC,+BAAA,CAAgC,IAAI;;cAG5E,2BAAA,EAA2B,MAAA,CAAA,QAAA;AAAA,KAK5B,2BAAA,UAAqC,2BAAA,CAA4B,IAAI;AAAA,cAAA,iCAAA;;;;cAGpE,4BAAA,SAAqC,iCAKjD;AAAA,cAAG,gCAAA;;;;;;;;;;cAOS,2BAAA,SAAoC,gCAOhD;AAAA,cAAG,kCAAA;;;;;;;;;;;AAdA;;;;AAAA,cAoBS,6BAAA,SAAsC,kCAUlD;AAAA,KAEW,mBAAA,GACR,4BAAA,GACA,2BAAA,GACA,6BAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ClassificationUsage } from "./schema.mjs";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { ProviderErrorInfo } from "@yolk-sdk/agent/protocol";
|
|
4
|
+
//#region src/classification/errors.ts
|
|
5
|
+
/**
|
|
6
|
+
* Why an answer does not fit its question:
|
|
7
|
+
*
|
|
8
|
+
* - `missing_answer`: a question has no answer.
|
|
9
|
+
* - `unexpected_answer`: an answer names no question that was asked.
|
|
10
|
+
* - `type_mismatch`: the answer's `type` is not the question's.
|
|
11
|
+
* - `invalid_probability`: a probability is missing, not a number, non-finite, or outside `[0, 1]`.
|
|
12
|
+
* - `invalid_confidence`: a confidence is not a finite number in `[0, 1]`.
|
|
13
|
+
* - `invalid_choice`: a choice answer names no option of its question.
|
|
14
|
+
* - `invalid_score`: a score answer has no finite `score`.
|
|
15
|
+
* - `malformed_answer`: the answer is not an object.
|
|
16
|
+
*/
|
|
17
|
+
const ClassificationAnswerIssueReason = Schema.Literals([
|
|
18
|
+
"missing_answer",
|
|
19
|
+
"unexpected_answer",
|
|
20
|
+
"type_mismatch",
|
|
21
|
+
"invalid_probability",
|
|
22
|
+
"invalid_confidence",
|
|
23
|
+
"invalid_choice",
|
|
24
|
+
"invalid_score",
|
|
25
|
+
"malformed_answer"
|
|
26
|
+
]);
|
|
27
|
+
/** `malformed_response`: the response body is not the provider's documented envelope. */
|
|
28
|
+
const ClassificationResponseIssue = Schema.Literals(["malformed_response", ...ClassificationAnswerIssueReason.literals]);
|
|
29
|
+
/** The request does not satisfy the classification contract; nothing was sent. */
|
|
30
|
+
var ClassificationRequestInvalid = class extends Schema.TaggedError()("ClassificationRequestInvalid", { message: Schema.String }) {};
|
|
31
|
+
/**
|
|
32
|
+
* The provider could not be reached or rejected the request. `message` is safe to show: it never
|
|
33
|
+
* carries provider bodies, headers, or credentials. `provider` classifies the failure (status,
|
|
34
|
+
* provider error code, retry delay).
|
|
35
|
+
*/
|
|
36
|
+
var ClassificationProviderError = class extends Schema.TaggedError()("ClassificationProviderError", {
|
|
37
|
+
message: Schema.String,
|
|
38
|
+
retryable: Schema.Boolean,
|
|
39
|
+
provider: ProviderErrorInfo
|
|
40
|
+
}) {};
|
|
41
|
+
/**
|
|
42
|
+
* The provider answered, but the response or one of its answers does not fit the request.
|
|
43
|
+
* `usage` is kept when the provider reported it, because the request was billed.
|
|
44
|
+
*/
|
|
45
|
+
var ClassificationResponseInvalid = class extends Schema.TaggedError()("ClassificationResponseInvalid", {
|
|
46
|
+
message: Schema.String,
|
|
47
|
+
/** Provider id, when a provider (not the typed `classify` check) found the issue. */
|
|
48
|
+
provider: Schema.optional(Schema.String),
|
|
49
|
+
reason: ClassificationResponseIssue,
|
|
50
|
+
questionId: Schema.optional(Schema.String),
|
|
51
|
+
usage: Schema.optional(ClassificationUsage)
|
|
52
|
+
}) {};
|
|
53
|
+
//#endregion
|
|
54
|
+
export { ClassificationAnswerIssueReason, ClassificationProviderError, ClassificationRequestInvalid, ClassificationResponseInvalid, ClassificationResponseIssue };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=errors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../../src/classification/errors.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\nimport { ProviderErrorInfo } from '@yolk-sdk/agent/protocol'\nimport { ClassificationUsage } from './schema.ts'\n\n/**\n * Why an answer does not fit its question:\n *\n * - `missing_answer`: a question has no answer.\n * - `unexpected_answer`: an answer names no question that was asked.\n * - `type_mismatch`: the answer's `type` is not the question's.\n * - `invalid_probability`: a probability is missing, not a number, non-finite, or outside `[0, 1]`.\n * - `invalid_confidence`: a confidence is not a finite number in `[0, 1]`.\n * - `invalid_choice`: a choice answer names no option of its question.\n * - `invalid_score`: a score answer has no finite `score`.\n * - `malformed_answer`: the answer is not an object.\n */\nexport const ClassificationAnswerIssueReason = Schema.Literals([\n 'missing_answer',\n 'unexpected_answer',\n 'type_mismatch',\n 'invalid_probability',\n 'invalid_confidence',\n 'invalid_choice',\n 'invalid_score',\n 'malformed_answer'\n])\n\nexport type ClassificationAnswerIssueReason = typeof ClassificationAnswerIssueReason.Type\n\n/** `malformed_response`: the response body is not the provider's documented envelope. */\nexport const ClassificationResponseIssue = Schema.Literals([\n 'malformed_response',\n ...ClassificationAnswerIssueReason.literals\n])\n\nexport type ClassificationResponseIssue = typeof ClassificationResponseIssue.Type\n\n/** The request does not satisfy the classification contract; nothing was sent. */\nexport class ClassificationRequestInvalid extends Schema.TaggedError<ClassificationRequestInvalid>()(\n 'ClassificationRequestInvalid',\n {\n message: Schema.String\n }\n) {}\n\n/**\n * The provider could not be reached or rejected the request. `message` is safe to show: it never\n * carries provider bodies, headers, or credentials. `provider` classifies the failure (status,\n * provider error code, retry delay).\n */\nexport class ClassificationProviderError extends Schema.TaggedError<ClassificationProviderError>()(\n 'ClassificationProviderError',\n {\n message: Schema.String,\n retryable: Schema.Boolean,\n provider: ProviderErrorInfo\n }\n) {}\n\n/**\n * The provider answered, but the response or one of its answers does not fit the request.\n * `usage` is kept when the provider reported it, because the request was billed.\n */\nexport class ClassificationResponseInvalid extends Schema.TaggedError<ClassificationResponseInvalid>()(\n 'ClassificationResponseInvalid',\n {\n message: Schema.String,\n /** Provider id, when a provider (not the typed `classify` check) found the issue. */\n provider: Schema.optional(Schema.String),\n reason: ClassificationResponseIssue,\n questionId: Schema.optional(Schema.String),\n usage: Schema.optional(ClassificationUsage)\n }\n) {}\n\nexport type ClassificationError =\n | ClassificationRequestInvalid\n | ClassificationProviderError\n | ClassificationResponseInvalid\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,MAAa,kCAAkC,OAAO,SAAS;CAC7D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;AAKD,MAAa,8BAA8B,OAAO,SAAS,CACzD,sBACA,GAAG,gCAAgC,QACrC,CAAC;;AAKD,IAAa,+BAAb,cAAkD,OAAO,YAA0C,EACjG,gCACA,EACE,SAAS,OAAO,OAClB,CACF,EAAE,CAAC;;;;;;AAOH,IAAa,8BAAb,cAAiD,OAAO,YAAyC,EAC/F,+BACA;CACE,SAAS,OAAO;CAChB,WAAW,OAAO;CAClB,UAAU;AACZ,CACF,EAAE,CAAC;;;;;AAMH,IAAa,gCAAb,cAAmD,OAAO,YAA2C,EACnG,iCACA;CACE,SAAS,OAAO;;CAEhB,UAAU,OAAO,SAAS,OAAO,MAAM;CACvC,QAAQ;CACR,YAAY,OAAO,SAAS,OAAO,MAAM;CACzC,OAAO,OAAO,SAAS,mBAAmB;AAC5C,CACF,EAAE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ClassificationAnswerIssueReason, ClassificationError, ClassificationProviderError, ClassificationRequestInvalid, ClassificationResponseInvalid, ClassificationResponseIssue } from "./errors.mjs";
|
|
2
|
+
import { BooleanClassifierAnswer, BooleanClassifierQuestion, ChoiceClassifierAnswer, ChoiceClassifierQuestion, ClassificationRequest, ClassificationResult, ClassificationUsage, ClassifierAnswer, ClassifierCriterion, ClassifierProbabilities, ClassifierProbability, ClassifierQuestion, ClassifierQuestionType, ClassifierQuestions, ClassifierState, ScoreClassifierAnswer, ScoreClassifierQuestion, maxClassifierChoiceOptions, maxClassifierScoreLevels, minClassifierChoiceOptions, minClassifierScoreLevels } from "./schema.mjs";
|
|
3
|
+
import { ClassificationAnswerIssue, ClassificationRequestFor, ClassificationResultFor, ClassifierAnswerFor, ClassifierAnswersFor, ClassifierModel, ClassifierQuestionsInput, classificationAnswersIssue, classify, decodeClassificationRequest, decodeClassifierAnswer, decodeClassifierAnswers, isClassificationResultFor } from "./model.mjs";
|
|
4
|
+
export { BooleanClassifierAnswer, BooleanClassifierQuestion, ChoiceClassifierAnswer, ChoiceClassifierQuestion, type ClassificationAnswerIssue, ClassificationAnswerIssueReason, type ClassificationError, ClassificationProviderError, ClassificationRequest, type ClassificationRequestFor, ClassificationRequestInvalid, ClassificationResponseInvalid, ClassificationResponseIssue, ClassificationResult, type ClassificationResultFor, ClassificationUsage, ClassifierAnswer, type ClassifierAnswerFor, type ClassifierAnswersFor, ClassifierCriterion, ClassifierModel, ClassifierProbabilities, ClassifierProbability, ClassifierQuestion, type ClassifierQuestionType, ClassifierQuestions, type ClassifierQuestionsInput, ClassifierState, ScoreClassifierAnswer, ScoreClassifierQuestion, classificationAnswersIssue, classify, decodeClassificationRequest, decodeClassifierAnswer, decodeClassifierAnswers, isClassificationResultFor, maxClassifierChoiceOptions, maxClassifierScoreLevels, minClassifierChoiceOptions, minClassifierScoreLevels };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BooleanClassifierAnswer, BooleanClassifierQuestion, ChoiceClassifierAnswer, ChoiceClassifierQuestion, ClassificationRequest, ClassificationResult, ClassificationUsage, ClassifierAnswer, ClassifierCriterion, ClassifierProbabilities, ClassifierProbability, ClassifierQuestion, ClassifierQuestions, ClassifierState, ScoreClassifierAnswer, ScoreClassifierQuestion, maxClassifierChoiceOptions, maxClassifierScoreLevels, minClassifierChoiceOptions, minClassifierScoreLevels } from "./schema.mjs";
|
|
2
|
+
import { ClassificationAnswerIssueReason, ClassificationProviderError, ClassificationRequestInvalid, ClassificationResponseInvalid, ClassificationResponseIssue } from "./errors.mjs";
|
|
3
|
+
import { ClassifierModel, classificationAnswersIssue, classify, decodeClassificationRequest, decodeClassifierAnswer, decodeClassifierAnswers, isClassificationResultFor } from "./model.mjs";
|
|
4
|
+
export { BooleanClassifierAnswer, BooleanClassifierQuestion, ChoiceClassifierAnswer, ChoiceClassifierQuestion, ClassificationAnswerIssueReason, ClassificationProviderError, ClassificationRequest, ClassificationRequestInvalid, ClassificationResponseInvalid, ClassificationResponseIssue, ClassificationResult, ClassificationUsage, ClassifierAnswer, ClassifierCriterion, ClassifierModel, ClassifierProbabilities, ClassifierProbability, ClassifierQuestion, ClassifierQuestions, ClassifierState, ScoreClassifierAnswer, ScoreClassifierQuestion, classificationAnswersIssue, classify, decodeClassificationRequest, decodeClassifierAnswer, decodeClassifierAnswers, isClassificationResultFor, maxClassifierChoiceOptions, maxClassifierScoreLevels, minClassifierChoiceOptions, minClassifierScoreLevels };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ClassificationAnswerIssueReason, ClassificationError, ClassificationRequestInvalid } from "./errors.mjs";
|
|
2
|
+
import { BooleanClassifierAnswer, ChoiceClassifierAnswer, ClassificationRequest, ClassificationResult, ClassifierAnswer, ClassifierQuestion, ScoreClassifierAnswer } from "./schema.mjs";
|
|
3
|
+
import { Context, Effect, Result } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/classification/model.d.ts
|
|
6
|
+
declare const ClassifierModel_base: Context.ServiceClass<ClassifierModel, "@yolk-sdk/agent/classification/ClassifierModel", {
|
|
7
|
+
readonly classify: (request: ClassificationRequest) => Effect.Effect<ClassificationResult, ClassificationError>;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Answers typed questions about one state. Classification is a read: it has no side effects.
|
|
11
|
+
* Providers supply layers; `classify` is the typed entry point.
|
|
12
|
+
*/
|
|
13
|
+
declare class ClassifierModel extends ClassifierModel_base {}
|
|
14
|
+
/** Named questions, typed for inference. */
|
|
15
|
+
type ClassifierQuestionsInput = {
|
|
16
|
+
readonly [questionId: string]: ClassifierQuestion;
|
|
17
|
+
};
|
|
18
|
+
/** The answer type a question gets; a choice answer's `choice` is the union of its option keys. */
|
|
19
|
+
type ClassifierAnswerFor<Q extends ClassifierQuestion> = Q extends {
|
|
20
|
+
readonly type: 'boolean';
|
|
21
|
+
} ? BooleanClassifierAnswer : Q extends {
|
|
22
|
+
readonly type: 'choice';
|
|
23
|
+
readonly criteria: infer Criteria;
|
|
24
|
+
} ? ChoiceClassifierAnswer & {
|
|
25
|
+
readonly choice: Extract<keyof Criteria, string>;
|
|
26
|
+
} : ScoreClassifierAnswer;
|
|
27
|
+
type ClassifierAnswersFor<Q extends ClassifierQuestionsInput> = { readonly [K in keyof Q]: ClassifierAnswerFor<Q[K]> };
|
|
28
|
+
type ClassificationRequestFor<Q extends ClassifierQuestionsInput> = Omit<ClassificationRequest, 'questions'> & {
|
|
29
|
+
readonly questions: Q;
|
|
30
|
+
};
|
|
31
|
+
type ClassificationResultFor<Q extends ClassifierQuestionsInput> = ClassificationResult & {
|
|
32
|
+
readonly answers: ClassifierAnswersFor<Q>;
|
|
33
|
+
};
|
|
34
|
+
/** Where an answer leaves its question. */
|
|
35
|
+
type ClassificationAnswerIssue = {
|
|
36
|
+
readonly reason: ClassificationAnswerIssueReason;
|
|
37
|
+
readonly questionId: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Decode one raw provider answer against the question it answers. The answer must be an object
|
|
41
|
+
* whose `type` is the question's; probabilities and confidence must be finite numbers in `[0, 1]`
|
|
42
|
+
* and are kept exactly as given (never renormalized); a choice must name one of the question's
|
|
43
|
+
* options; a score must be finite. Only the contract fields are kept.
|
|
44
|
+
*/
|
|
45
|
+
declare const decodeClassifierAnswer: (question: ClassifierQuestion, raw: unknown) => Result.Result<ClassifierAnswer, ClassificationAnswerIssueReason>;
|
|
46
|
+
/**
|
|
47
|
+
* Decode raw provider answers (a JSON object keyed by question id) against the questions asked:
|
|
48
|
+
* every question needs exactly one answer of its type, and no answer may name a question that was
|
|
49
|
+
* not asked. Fails with the first issue, in question order (then unexpected answers); answers that
|
|
50
|
+
* are not an object fail as the first question's `malformed_answer`.
|
|
51
|
+
*/
|
|
52
|
+
declare const decodeClassifierAnswers: (questions: ClassifierQuestionsInput, raw: unknown) => Result.Result<Record<string, ClassifierAnswer>, ClassificationAnswerIssue>;
|
|
53
|
+
/** The first way `answers` leaves `questions`, or undefined when every answer fits its question. */
|
|
54
|
+
declare const classificationAnswersIssue: (questions: ClassifierQuestionsInput, answers: {
|
|
55
|
+
readonly [questionId: string]: ClassifierAnswer;
|
|
56
|
+
}) => ClassificationAnswerIssue | undefined;
|
|
57
|
+
/** Narrow a result to the answer types its questions infer, after checking every answer. */
|
|
58
|
+
declare const isClassificationResultFor: <const Q extends ClassifierQuestionsInput>(questions: Q, result: ClassificationResult) => result is ClassificationResultFor<Q>;
|
|
59
|
+
/**
|
|
60
|
+
* Validate a request against the classification contract before anything is sent. Fails with
|
|
61
|
+
* `ClassificationRequestInvalid` (for example a choice with more than 255 options, or a score with
|
|
62
|
+
* more than 10 levels).
|
|
63
|
+
*/
|
|
64
|
+
declare const decodeClassificationRequest: (request: unknown) => Effect.Effect<ClassificationRequest, ClassificationRequestInvalid>;
|
|
65
|
+
/**
|
|
66
|
+
* Classify with the `ClassifierModel` in context, typing each answer from its question: a choice
|
|
67
|
+
* answer's `choice` is the union of that question's option keys. Every answer is checked against
|
|
68
|
+
* its question; a provider that returns a mismatching answer fails with
|
|
69
|
+
* `ClassificationResponseInvalid` (keeping usage).
|
|
70
|
+
*/
|
|
71
|
+
declare const classify: <const Q extends ClassifierQuestionsInput>(request: ClassificationRequestFor<Q>) => Effect.Effect<ClassificationResultFor<Q>, ClassificationError, ClassifierModel>;
|
|
72
|
+
//#endregion
|
|
73
|
+
export { ClassificationAnswerIssue, ClassificationRequestFor, ClassificationResultFor, ClassifierAnswerFor, ClassifierAnswersFor, ClassifierModel, ClassifierQuestionsInput, classificationAnswersIssue, classify, decodeClassificationRequest, decodeClassifierAnswer, decodeClassifierAnswers, isClassificationResultFor };
|
|
74
|
+
//# sourceMappingURL=model.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.mts","names":[],"sources":["../../src/classification/model.ts"],"mappings":";;;;;cAiBoB,oBAAA;sBAUd,OAAA,EAAS,qBAAA,KACN,MAAA,CAAO,MAAA,CAAO,oBAAA,EAAsB,mBAAA;AAAA;;;;;cALhC,eAAA,SAAwB,oBAOgB;;KAGzC,wBAAA;EAAA,UAAuC,UAAA,WAAqB,kBAAkB;AAAA;;KAG9E,mBAAA,WAA8B,kBAAA,IAAsB,CAAA;EAAA,SACrD,IAAA;AAAA,IAEP,uBAAA,GACA,CAAA;EAAA,SAAqB,IAAA;EAAA,SAAyB,QAAA;AAAA,IAC5C,sBAAA;EAAA,SAAoC,MAAA,EAAQ,OAAA,OAAc,QAAA;AAAA,IAC1D,qBAAA;AAAA,KAEM,oBAAA,WAA+B,wBAAA,2BACpB,CAAA,GAAI,mBAAA,CAAoB,CAAA,CAAE,CAAA;AAAA,KAGrC,wBAAA,WAAmC,wBAAA,IAA4B,IAAA,CACzE,qBAAA;EAAA,SAEa,SAAA,EAAW,CAAA;AAAA;AAAA,KAEd,uBAAA,WAAkC,wBAAA,IAA4B,oBAAA;EAAA,SAC/D,OAAA,EAAS,oBAAA,CAAqB,CAAA;AAAA;;KAI7B,yBAAA;EAAA,SACD,MAAA,EAAQ,+BAA+B;EAAA,SACvC,UAAA;AAAA;;;;;;;cAuDE,sBAAA,GACX,QAAA,EAAU,kBAAA,EACV,GAAA,cACC,MAAA,CAAO,MAAA,CAAO,gBAAA,EAAkB,+BAAA;;;;;;;cAwDtB,uBAAA,GACX,SAAA,EAAW,wBAAA,EACX,GAAA,cACC,MAAA,CAAO,MAAA,CAAO,MAAA,SAAe,gBAAA,GAAmB,yBAAA;;cAkCtC,0BAAA,GACX,SAAA,EAAW,wBAAA,EACX,OAAA;EAAA,UAAqB,UAAA,WAAqB,gBAAA;AAAA,MACzC,yBAAA;;cAOU,yBAAA,mBAA6C,wBAAA,EACxD,SAAA,EAAW,CAAA,EACX,MAAA,EAAQ,oBAAA,KACP,MAAA,IAAU,uBAAA,CAAwB,CAAA;;;;;;cAQxB,2BAAA,GACX,OAAA,cACC,MAAA,CAAO,MAAA,CAAO,qBAAA,EAAuB,4BAAA;;AAhMb;AAE3B;;;;cA6Ma,QAAA,mBAA4B,wBAAA,EACvC,OAAA,EAAS,wBAAA,CAAyB,CAAA,MACjC,MAAA,CAAO,MAAA,CAAO,uBAAA,CAAwB,CAAA,GAAI,mBAAA,EAAqB,eAAA"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { ClassificationRequest } from "./schema.mjs";
|
|
2
|
+
import { ClassificationRequestInvalid, ClassificationResponseInvalid } from "./errors.mjs";
|
|
3
|
+
import { Context, Effect, Predicate, Result } from "effect";
|
|
4
|
+
import * as Schema$1 from "effect/Schema";
|
|
5
|
+
//#region src/classification/model.ts
|
|
6
|
+
/**
|
|
7
|
+
* Answers typed questions about one state. Classification is a read: it has no side effects.
|
|
8
|
+
* Providers supply layers; `classify` is the typed entry point.
|
|
9
|
+
*/
|
|
10
|
+
var ClassifierModel = class extends Context.Service()("@yolk-sdk/agent/classification/ClassifierModel") {};
|
|
11
|
+
const isProbability = (value) => Predicate.isNumber(value) && Number.isFinite(value) && value >= 0 && value <= 1;
|
|
12
|
+
const isFieldObject = (value) => Predicate.isObject(value) && !Array.isArray(value);
|
|
13
|
+
/** An own field of a JSON object, never an inherited one (`toString`, `__proto__`). */
|
|
14
|
+
const ownField = (value, key) => Object.hasOwn(value, key) && Predicate.hasProperty(value, key) ? value[key] : void 0;
|
|
15
|
+
const decodeProbabilities = (value) => {
|
|
16
|
+
if (!isFieldObject(value)) return Result.fail("invalid_probability");
|
|
17
|
+
const entries = [];
|
|
18
|
+
for (const key of Object.keys(value)) {
|
|
19
|
+
const probability = ownField(value, key);
|
|
20
|
+
if (!isProbability(probability)) return Result.fail("invalid_probability");
|
|
21
|
+
entries.push([key, probability]);
|
|
22
|
+
}
|
|
23
|
+
return Result.succeed(Object.fromEntries(entries));
|
|
24
|
+
};
|
|
25
|
+
const decodeConfidence = (raw, fields) => {
|
|
26
|
+
if (!Object.hasOwn(raw, "confidence")) return void 0;
|
|
27
|
+
const confidence = ownField(raw, "confidence");
|
|
28
|
+
if (!isProbability(confidence)) return "invalid_confidence";
|
|
29
|
+
fields.confidence = confidence;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Decode one raw provider answer against the question it answers. The answer must be an object
|
|
33
|
+
* whose `type` is the question's; probabilities and confidence must be finite numbers in `[0, 1]`
|
|
34
|
+
* and are kept exactly as given (never renormalized); a choice must name one of the question's
|
|
35
|
+
* options; a score must be finite. Only the contract fields are kept.
|
|
36
|
+
*/
|
|
37
|
+
const decodeClassifierAnswer = (question, raw) => {
|
|
38
|
+
if (!isFieldObject(raw)) return Result.fail("malformed_answer");
|
|
39
|
+
if (ownField(raw, "type") !== question.type) return Result.fail("type_mismatch");
|
|
40
|
+
if (question.type === "boolean") {
|
|
41
|
+
const probability = ownField(raw, "probability");
|
|
42
|
+
return isProbability(probability) ? Result.succeed({
|
|
43
|
+
type: "boolean",
|
|
44
|
+
probability
|
|
45
|
+
}) : Result.fail("invalid_probability");
|
|
46
|
+
}
|
|
47
|
+
const probabilities = decodeProbabilities(ownField(raw, "probabilities"));
|
|
48
|
+
if (Result.isFailure(probabilities)) return Result.fail(probabilities.failure);
|
|
49
|
+
if (question.type === "choice") {
|
|
50
|
+
const choice = ownField(raw, "choice");
|
|
51
|
+
if (!Predicate.isString(choice) || !Object.hasOwn(question.criteria, choice)) return Result.fail("invalid_choice");
|
|
52
|
+
const fields = {
|
|
53
|
+
type: "choice",
|
|
54
|
+
choice,
|
|
55
|
+
probabilities: probabilities.success
|
|
56
|
+
};
|
|
57
|
+
const issue = decodeConfidence(raw, fields);
|
|
58
|
+
return issue === void 0 ? Result.succeed(fields) : Result.fail(issue);
|
|
59
|
+
}
|
|
60
|
+
const score = ownField(raw, "score");
|
|
61
|
+
if (!Predicate.isNumber(score) || !Number.isFinite(score)) return Result.fail("invalid_score");
|
|
62
|
+
const fields = {
|
|
63
|
+
type: "score",
|
|
64
|
+
score,
|
|
65
|
+
probabilities: probabilities.success
|
|
66
|
+
};
|
|
67
|
+
const issue = decodeConfidence(raw, fields);
|
|
68
|
+
return issue === void 0 ? Result.succeed(fields) : Result.fail(issue);
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Decode raw provider answers (a JSON object keyed by question id) against the questions asked:
|
|
72
|
+
* every question needs exactly one answer of its type, and no answer may name a question that was
|
|
73
|
+
* not asked. Fails with the first issue, in question order (then unexpected answers); answers that
|
|
74
|
+
* are not an object fail as the first question's `malformed_answer`.
|
|
75
|
+
*/
|
|
76
|
+
const decodeClassifierAnswers = (questions, raw) => {
|
|
77
|
+
const questionIds = Object.keys(questions);
|
|
78
|
+
if (!isFieldObject(raw)) return Result.fail({
|
|
79
|
+
reason: "malformed_answer",
|
|
80
|
+
questionId: questionIds[0] ?? ""
|
|
81
|
+
});
|
|
82
|
+
const entries = [];
|
|
83
|
+
for (const [questionId, question] of Object.entries(questions)) {
|
|
84
|
+
if (!Object.hasOwn(raw, questionId)) return Result.fail({
|
|
85
|
+
reason: "missing_answer",
|
|
86
|
+
questionId
|
|
87
|
+
});
|
|
88
|
+
const answer = decodeClassifierAnswer(question, ownField(raw, questionId));
|
|
89
|
+
if (Result.isFailure(answer)) return Result.fail({
|
|
90
|
+
reason: answer.failure,
|
|
91
|
+
questionId
|
|
92
|
+
});
|
|
93
|
+
entries.push([questionId, answer.success]);
|
|
94
|
+
}
|
|
95
|
+
const answers = Object.fromEntries(entries);
|
|
96
|
+
for (const questionId of Object.keys(raw)) if (!Object.hasOwn(questions, questionId)) return Result.fail({
|
|
97
|
+
reason: "unexpected_answer",
|
|
98
|
+
questionId
|
|
99
|
+
});
|
|
100
|
+
return Result.succeed(answers);
|
|
101
|
+
};
|
|
102
|
+
/** The first way `answers` leaves `questions`, or undefined when every answer fits its question. */
|
|
103
|
+
const classificationAnswersIssue = (questions, answers) => {
|
|
104
|
+
const decoded = decodeClassifierAnswers(questions, answers);
|
|
105
|
+
return Result.isFailure(decoded) ? decoded.failure : void 0;
|
|
106
|
+
};
|
|
107
|
+
/** Narrow a result to the answer types its questions infer, after checking every answer. */
|
|
108
|
+
const isClassificationResultFor = (questions, result) => classificationAnswersIssue(questions, result.answers) === void 0;
|
|
109
|
+
/**
|
|
110
|
+
* Validate a request against the classification contract before anything is sent. Fails with
|
|
111
|
+
* `ClassificationRequestInvalid` (for example a choice with more than 255 options, or a score with
|
|
112
|
+
* more than 10 levels).
|
|
113
|
+
*/
|
|
114
|
+
const decodeClassificationRequest = (request) => Schema$1.decodeUnknownEffect(ClassificationRequest)(request).pipe(Effect.mapError((error) => ClassificationRequestInvalid.make({ message: `Invalid classification request: ${error.message}` })));
|
|
115
|
+
/**
|
|
116
|
+
* Classify with the `ClassifierModel` in context, typing each answer from its question: a choice
|
|
117
|
+
* answer's `choice` is the union of that question's option keys. Every answer is checked against
|
|
118
|
+
* its question; a provider that returns a mismatching answer fails with
|
|
119
|
+
* `ClassificationResponseInvalid` (keeping usage).
|
|
120
|
+
*/
|
|
121
|
+
const classify = (request) => Effect.gen(function* () {
|
|
122
|
+
const result = yield* (yield* ClassifierModel).classify(request);
|
|
123
|
+
if (isClassificationResultFor(request.questions, result)) return result;
|
|
124
|
+
const issue = classificationAnswersIssue(request.questions, result.answers);
|
|
125
|
+
const reason = issue?.reason ?? "malformed_answer";
|
|
126
|
+
return yield* Effect.fail(ClassificationResponseInvalid.make({
|
|
127
|
+
message: `Classification answers do not fit their questions: ${reason}`,
|
|
128
|
+
reason,
|
|
129
|
+
questionId: issue?.questionId,
|
|
130
|
+
usage: result.usage
|
|
131
|
+
}));
|
|
132
|
+
});
|
|
133
|
+
//#endregion
|
|
134
|
+
export { ClassifierModel, classificationAnswersIssue, classify, decodeClassificationRequest, decodeClassifierAnswer, decodeClassifierAnswers, isClassificationResultFor };
|
|
135
|
+
|
|
136
|
+
//# sourceMappingURL=model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.mjs","names":["Schema"],"sources":["../../src/classification/model.ts"],"sourcesContent":["import { Context, Effect, Predicate, Result } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport {\n ClassificationRequestInvalid,\n ClassificationResponseInvalid,\n type ClassificationAnswerIssueReason,\n type ClassificationError\n} from './errors.ts'\nimport {\n ClassificationRequest,\n type BooleanClassifierAnswer,\n type ChoiceClassifierAnswer,\n type ClassificationResult,\n type ClassifierAnswer,\n type ClassifierProbabilities,\n type ClassifierQuestion,\n type ScoreClassifierAnswer\n} from './schema.ts'\n\n/**\n * Answers typed questions about one state. Classification is a read: it has no side effects.\n * Providers supply layers; `classify` is the typed entry point.\n */\nexport class ClassifierModel extends Context.Service<\n ClassifierModel,\n {\n readonly classify: (\n request: ClassificationRequest\n ) => Effect.Effect<ClassificationResult, ClassificationError>\n }\n>()('@yolk-sdk/agent/classification/ClassifierModel') {}\n\n/** Named questions, typed for inference. */\nexport type ClassifierQuestionsInput = { readonly [questionId: string]: ClassifierQuestion }\n\n/** The answer type a question gets; a choice answer's `choice` is the union of its option keys. */\nexport type ClassifierAnswerFor<Q extends ClassifierQuestion> = Q extends {\n readonly type: 'boolean'\n}\n ? BooleanClassifierAnswer\n : Q extends { readonly type: 'choice'; readonly criteria: infer Criteria }\n ? ChoiceClassifierAnswer & { readonly choice: Extract<keyof Criteria, string> }\n : ScoreClassifierAnswer\n\nexport type ClassifierAnswersFor<Q extends ClassifierQuestionsInput> = {\n readonly [K in keyof Q]: ClassifierAnswerFor<Q[K]>\n}\n\nexport type ClassificationRequestFor<Q extends ClassifierQuestionsInput> = Omit<\n ClassificationRequest,\n 'questions'\n> & { readonly questions: Q }\n\nexport type ClassificationResultFor<Q extends ClassifierQuestionsInput> = ClassificationResult & {\n readonly answers: ClassifierAnswersFor<Q>\n}\n\n/** Where an answer leaves its question. */\nexport type ClassificationAnswerIssue = {\n readonly reason: ClassificationAnswerIssueReason\n readonly questionId: string\n}\n\nconst isProbability = (value: unknown): value is number =>\n Predicate.isNumber(value) && Number.isFinite(value) && value >= 0 && value <= 1\n\nconst isFieldObject = (value: unknown): value is object =>\n Predicate.isObject(value) && !Array.isArray(value)\n\n/** An own field of a JSON object, never an inherited one (`toString`, `__proto__`). */\nconst ownField = (value: object, key: string): unknown =>\n Object.hasOwn(value, key) && Predicate.hasProperty(value, key) ? value[key] : undefined\n\nconst decodeProbabilities = (\n value: unknown\n): Result.Result<ClassifierProbabilities, ClassificationAnswerIssueReason> => {\n if (!isFieldObject(value)) return Result.fail('invalid_probability')\n\n const entries: Array<readonly [string, number]> = []\n\n for (const key of Object.keys(value)) {\n const probability = ownField(value, key)\n\n if (!isProbability(probability)) return Result.fail('invalid_probability')\n\n entries.push([key, probability])\n }\n\n // `Object.fromEntries` defines own data properties, so keys such as `__proto__` are kept.\n return Result.succeed(Object.fromEntries(entries))\n}\n\ntype ConfidenceField = { confidence?: number }\n\nconst decodeConfidence = (\n raw: object,\n fields: ConfidenceField\n): ClassificationAnswerIssueReason | undefined => {\n if (!Object.hasOwn(raw, 'confidence')) return undefined\n\n const confidence = ownField(raw, 'confidence')\n\n if (!isProbability(confidence)) return 'invalid_confidence'\n\n fields.confidence = confidence\n\n return undefined\n}\n\n/**\n * Decode one raw provider answer against the question it answers. The answer must be an object\n * whose `type` is the question's; probabilities and confidence must be finite numbers in `[0, 1]`\n * and are kept exactly as given (never renormalized); a choice must name one of the question's\n * options; a score must be finite. Only the contract fields are kept.\n */\nexport const decodeClassifierAnswer = (\n question: ClassifierQuestion,\n raw: unknown\n): Result.Result<ClassifierAnswer, ClassificationAnswerIssueReason> => {\n if (!isFieldObject(raw)) return Result.fail('malformed_answer')\n\n if (ownField(raw, 'type') !== question.type) return Result.fail('type_mismatch')\n\n if (question.type === 'boolean') {\n const probability = ownField(raw, 'probability')\n\n return isProbability(probability)\n ? Result.succeed({ type: 'boolean', probability })\n : Result.fail('invalid_probability')\n }\n\n const probabilities = decodeProbabilities(ownField(raw, 'probabilities'))\n\n if (Result.isFailure(probabilities)) return Result.fail(probabilities.failure)\n\n if (question.type === 'choice') {\n const choice = ownField(raw, 'choice')\n\n if (!Predicate.isString(choice) || !Object.hasOwn(question.criteria, choice)) {\n return Result.fail('invalid_choice')\n }\n\n const fields: ChoiceClassifierAnswer & ConfidenceField = {\n type: 'choice',\n choice,\n probabilities: probabilities.success\n }\n\n const issue = decodeConfidence(raw, fields)\n\n return issue === undefined ? Result.succeed(fields) : Result.fail(issue)\n }\n\n const score = ownField(raw, 'score')\n\n if (!Predicate.isNumber(score) || !Number.isFinite(score)) return Result.fail('invalid_score')\n\n const fields: ScoreClassifierAnswer & ConfidenceField = {\n type: 'score',\n score,\n probabilities: probabilities.success\n }\n\n const issue = decodeConfidence(raw, fields)\n\n return issue === undefined ? Result.succeed(fields) : Result.fail(issue)\n}\n\n/**\n * Decode raw provider answers (a JSON object keyed by question id) against the questions asked:\n * every question needs exactly one answer of its type, and no answer may name a question that was\n * not asked. Fails with the first issue, in question order (then unexpected answers); answers that\n * are not an object fail as the first question's `malformed_answer`.\n */\nexport const decodeClassifierAnswers = (\n questions: ClassifierQuestionsInput,\n raw: unknown\n): Result.Result<Record<string, ClassifierAnswer>, ClassificationAnswerIssue> => {\n const questionIds = Object.keys(questions)\n\n if (!isFieldObject(raw)) {\n return Result.fail({ reason: 'malformed_answer', questionId: questionIds[0] ?? '' })\n }\n\n const entries: Array<readonly [string, ClassifierAnswer]> = []\n\n for (const [questionId, question] of Object.entries(questions)) {\n if (!Object.hasOwn(raw, questionId)) {\n return Result.fail({ reason: 'missing_answer', questionId })\n }\n\n const answer = decodeClassifierAnswer(question, ownField(raw, questionId))\n\n if (Result.isFailure(answer)) return Result.fail({ reason: answer.failure, questionId })\n\n entries.push([questionId, answer.success])\n }\n\n // Own data properties: question ids such as `__proto__` stay answers, not prototypes.\n const answers: Record<string, ClassifierAnswer> = Object.fromEntries(entries)\n\n for (const questionId of Object.keys(raw)) {\n if (!Object.hasOwn(questions, questionId)) {\n return Result.fail({ reason: 'unexpected_answer', questionId })\n }\n }\n\n return Result.succeed(answers)\n}\n\n/** The first way `answers` leaves `questions`, or undefined when every answer fits its question. */\nexport const classificationAnswersIssue = (\n questions: ClassifierQuestionsInput,\n answers: { readonly [questionId: string]: ClassifierAnswer }\n): ClassificationAnswerIssue | undefined => {\n const decoded = decodeClassifierAnswers(questions, answers)\n\n return Result.isFailure(decoded) ? decoded.failure : undefined\n}\n\n/** Narrow a result to the answer types its questions infer, after checking every answer. */\nexport const isClassificationResultFor = <const Q extends ClassifierQuestionsInput>(\n questions: Q,\n result: ClassificationResult\n): result is ClassificationResultFor<Q> =>\n classificationAnswersIssue(questions, result.answers) === undefined\n\n/**\n * Validate a request against the classification contract before anything is sent. Fails with\n * `ClassificationRequestInvalid` (for example a choice with more than 255 options, or a score with\n * more than 10 levels).\n */\nexport const decodeClassificationRequest = (\n request: unknown\n): Effect.Effect<ClassificationRequest, ClassificationRequestInvalid> =>\n Schema.decodeUnknownEffect(ClassificationRequest)(request).pipe(\n Effect.mapError(error =>\n ClassificationRequestInvalid.make({\n message: `Invalid classification request: ${error.message}`\n })\n )\n )\n\n/**\n * Classify with the `ClassifierModel` in context, typing each answer from its question: a choice\n * answer's `choice` is the union of that question's option keys. Every answer is checked against\n * its question; a provider that returns a mismatching answer fails with\n * `ClassificationResponseInvalid` (keeping usage).\n */\nexport const classify = <const Q extends ClassifierQuestionsInput>(\n request: ClassificationRequestFor<Q>\n): Effect.Effect<ClassificationResultFor<Q>, ClassificationError, ClassifierModel> =>\n Effect.gen(function* () {\n const model = yield* ClassifierModel\n const result = yield* model.classify(request)\n\n if (isClassificationResultFor(request.questions, result)) return result\n\n const issue = classificationAnswersIssue(request.questions, result.answers)\n const reason = issue?.reason ?? 'malformed_answer'\n\n return yield* Effect.fail(\n ClassificationResponseInvalid.make({\n message: `Classification answers do not fit their questions: ${reason}`,\n reason,\n questionId: issue?.questionId,\n usage: result.usage\n })\n )\n })\n"],"mappings":";;;;;;;;;AAuBA,IAAa,kBAAb,cAAqC,QAAQ,QAO3C,EAAE,gDAAgD,EAAE,CAAC;AAiCvD,MAAM,iBAAiB,UACrB,UAAU,SAAS,KAAK,KAAK,OAAO,SAAS,KAAK,KAAK,SAAS,KAAK,SAAS;AAEhF,MAAM,iBAAiB,UACrB,UAAU,SAAS,KAAK,KAAK,CAAC,MAAM,QAAQ,KAAK;;AAGnD,MAAM,YAAY,OAAe,QAC/B,OAAO,OAAO,OAAO,GAAG,KAAK,UAAU,YAAY,OAAO,GAAG,IAAI,MAAM,OAAO,KAAA;AAEhF,MAAM,uBACJ,UAC4E;CAC5E,IAAI,CAAC,cAAc,KAAK,GAAG,OAAO,OAAO,KAAK,qBAAqB;CAEnE,MAAM,UAA4C,CAAC;CAEnD,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG;EACpC,MAAM,cAAc,SAAS,OAAO,GAAG;EAEvC,IAAI,CAAC,cAAc,WAAW,GAAG,OAAO,OAAO,KAAK,qBAAqB;EAEzE,QAAQ,KAAK,CAAC,KAAK,WAAW,CAAC;CACjC;CAGA,OAAO,OAAO,QAAQ,OAAO,YAAY,OAAO,CAAC;AACnD;AAIA,MAAM,oBACJ,KACA,WACgD;CAChD,IAAI,CAAC,OAAO,OAAO,KAAK,YAAY,GAAG,OAAO,KAAA;CAE9C,MAAM,aAAa,SAAS,KAAK,YAAY;CAE7C,IAAI,CAAC,cAAc,UAAU,GAAG,OAAO;CAEvC,OAAO,aAAa;AAGtB;;;;;;;AAQA,MAAa,0BACX,UACA,QACqE;CACrE,IAAI,CAAC,cAAc,GAAG,GAAG,OAAO,OAAO,KAAK,kBAAkB;CAE9D,IAAI,SAAS,KAAK,MAAM,MAAM,SAAS,MAAM,OAAO,OAAO,KAAK,eAAe;CAE/E,IAAI,SAAS,SAAS,WAAW;EAC/B,MAAM,cAAc,SAAS,KAAK,aAAa;EAE/C,OAAO,cAAc,WAAW,IAC5B,OAAO,QAAQ;GAAE,MAAM;GAAW;EAAY,CAAC,IAC/C,OAAO,KAAK,qBAAqB;CACvC;CAEA,MAAM,gBAAgB,oBAAoB,SAAS,KAAK,eAAe,CAAC;CAExE,IAAI,OAAO,UAAU,aAAa,GAAG,OAAO,OAAO,KAAK,cAAc,OAAO;CAE7E,IAAI,SAAS,SAAS,UAAU;EAC9B,MAAM,SAAS,SAAS,KAAK,QAAQ;EAErC,IAAI,CAAC,UAAU,SAAS,MAAM,KAAK,CAAC,OAAO,OAAO,SAAS,UAAU,MAAM,GACzE,OAAO,OAAO,KAAK,gBAAgB;EAGrC,MAAM,SAAmD;GACvD,MAAM;GACN;GACA,eAAe,cAAc;EAC/B;EAEA,MAAM,QAAQ,iBAAiB,KAAK,MAAM;EAE1C,OAAO,UAAU,KAAA,IAAY,OAAO,QAAQ,MAAM,IAAI,OAAO,KAAK,KAAK;CACzE;CAEA,MAAM,QAAQ,SAAS,KAAK,OAAO;CAEnC,IAAI,CAAC,UAAU,SAAS,KAAK,KAAK,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO,OAAO,KAAK,eAAe;CAE7F,MAAM,SAAkD;EACtD,MAAM;EACN;EACA,eAAe,cAAc;CAC/B;CAEA,MAAM,QAAQ,iBAAiB,KAAK,MAAM;CAE1C,OAAO,UAAU,KAAA,IAAY,OAAO,QAAQ,MAAM,IAAI,OAAO,KAAK,KAAK;AACzE;;;;;;;AAQA,MAAa,2BACX,WACA,QAC+E;CAC/E,MAAM,cAAc,OAAO,KAAK,SAAS;CAEzC,IAAI,CAAC,cAAc,GAAG,GACpB,OAAO,OAAO,KAAK;EAAE,QAAQ;EAAoB,YAAY,YAAY,MAAM;CAAG,CAAC;CAGrF,MAAM,UAAsD,CAAC;CAE7D,KAAK,MAAM,CAAC,YAAY,aAAa,OAAO,QAAQ,SAAS,GAAG;EAC9D,IAAI,CAAC,OAAO,OAAO,KAAK,UAAU,GAChC,OAAO,OAAO,KAAK;GAAE,QAAQ;GAAkB;EAAW,CAAC;EAG7D,MAAM,SAAS,uBAAuB,UAAU,SAAS,KAAK,UAAU,CAAC;EAEzE,IAAI,OAAO,UAAU,MAAM,GAAG,OAAO,OAAO,KAAK;GAAE,QAAQ,OAAO;GAAS;EAAW,CAAC;EAEvF,QAAQ,KAAK,CAAC,YAAY,OAAO,OAAO,CAAC;CAC3C;CAGA,MAAM,UAA4C,OAAO,YAAY,OAAO;CAE5E,KAAK,MAAM,cAAc,OAAO,KAAK,GAAG,GACtC,IAAI,CAAC,OAAO,OAAO,WAAW,UAAU,GACtC,OAAO,OAAO,KAAK;EAAE,QAAQ;EAAqB;CAAW,CAAC;CAIlE,OAAO,OAAO,QAAQ,OAAO;AAC/B;;AAGA,MAAa,8BACX,WACA,YAC0C;CAC1C,MAAM,UAAU,wBAAwB,WAAW,OAAO;CAE1D,OAAO,OAAO,UAAU,OAAO,IAAI,QAAQ,UAAU,KAAA;AACvD;;AAGA,MAAa,6BACX,WACA,WAEA,2BAA2B,WAAW,OAAO,OAAO,MAAM,KAAA;;;;;;AAO5D,MAAa,+BACX,YAEAA,SAAO,oBAAoB,qBAAqB,EAAE,OAAO,EAAE,KACzD,OAAO,UAAS,UACd,6BAA6B,KAAK,EAChC,SAAS,mCAAmC,MAAM,UACpD,CAAC,CACH,CACF;;;;;;;AAQF,MAAa,YACX,YAEA,OAAO,IAAI,aAAa;CAEtB,MAAM,SAAS,QAAO,OADD,iBACO,SAAS,OAAO;CAE5C,IAAI,0BAA0B,QAAQ,WAAW,MAAM,GAAG,OAAO;CAEjE,MAAM,QAAQ,2BAA2B,QAAQ,WAAW,OAAO,OAAO;CAC1E,MAAM,SAAS,OAAO,UAAU;CAEhC,OAAO,OAAO,OAAO,KACnB,8BAA8B,KAAK;EACjC,SAAS,sDAAsD;EAC/D;EACA,YAAY,OAAO;EACnB,OAAO,OAAO;CAChB,CAAC,CACH;AACF,CAAC"}
|