@theoremjs/agents 0.0.0-stage → 0.3.0
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/LICENSE +21 -0
- package/README.md +1264 -2
- package/esm/_dnt.polyfills.d.ts +66 -0
- package/esm/_dnt.polyfills.js +51 -0
- package/esm/mod.d.ts +65 -0
- package/esm/mod.js +42 -0
- package/esm/package.json +3 -0
- package/esm/src/cli/bin.d.ts +7 -0
- package/esm/src/cli/bin.js +9 -0
- package/esm/src/cli/commands/bench.d.ts +6 -0
- package/esm/src/cli/commands/bench.js +458 -0
- package/esm/src/cli/commands/egress-compile.d.ts +17 -0
- package/esm/src/cli/commands/egress-compile.js +25 -0
- package/esm/src/cli/commands/eval.d.ts +37 -0
- package/esm/src/cli/commands/eval.js +190 -0
- package/esm/src/cli/commands/fuzz-canary.d.ts +15 -0
- package/esm/src/cli/commands/fuzz-canary.js +202 -0
- package/esm/src/cli/commands/fuzz-guardrails.d.ts +2 -0
- package/esm/src/cli/commands/fuzz-guardrails.js +5 -0
- package/esm/src/cli/commands/profile.d.ts +2 -0
- package/esm/src/cli/commands/profile.js +80 -0
- package/esm/src/cli/commands/run.d.ts +13 -0
- package/esm/src/cli/commands/run.js +45 -0
- package/esm/src/cli/commands/test.d.ts +25 -0
- package/esm/src/cli/commands/test.js +143 -0
- package/esm/src/cli/event-log.d.ts +15 -0
- package/esm/src/cli/event-log.js +136 -0
- package/esm/src/cli/index.d.ts +10 -0
- package/esm/src/cli/index.js +267 -0
- package/esm/src/cli/matrix/fixtures.d.ts +10 -0
- package/esm/src/cli/matrix/fixtures.js +72 -0
- package/esm/src/cli/matrix/synthesizer.d.ts +18 -0
- package/esm/src/cli/matrix/synthesizer.js +103 -0
- package/esm/src/evals/attachments.d.ts +4 -0
- package/esm/src/evals/attachments.js +53 -0
- package/esm/src/evals/breakdown.d.ts +28 -0
- package/esm/src/evals/breakdown.js +68 -0
- package/esm/src/evals/graders/answer.d.ts +13 -0
- package/esm/src/evals/graders/answer.js +133 -0
- package/esm/src/evals/graders/code.d.ts +64 -0
- package/esm/src/evals/graders/code.js +205 -0
- package/esm/src/evals/graders/judge.d.ts +20 -0
- package/esm/src/evals/graders/judge.js +365 -0
- package/esm/src/evals/graders/latency.d.ts +5 -0
- package/esm/src/evals/graders/latency.js +81 -0
- package/esm/src/evals/graders/live.d.ts +11 -0
- package/esm/src/evals/graders/live.js +40 -0
- package/esm/src/evals/graders/media.d.ts +18 -0
- package/esm/src/evals/graders/media.js +92 -0
- package/esm/src/evals/graders/shared.d.ts +11 -0
- package/esm/src/evals/graders/shared.js +62 -0
- package/esm/src/evals/graders/transcript.d.ts +17 -0
- package/esm/src/evals/graders/transcript.js +200 -0
- package/esm/src/evals/mod.d.ts +42 -0
- package/esm/src/evals/mod.js +30 -0
- package/esm/src/evals/record.d.ts +35 -0
- package/esm/src/evals/record.js +105 -0
- package/esm/src/evals/rubrics/catalog.d.ts +148 -0
- package/esm/src/evals/rubrics/catalog.js +846 -0
- package/esm/src/evals/rubrics/mod.d.ts +24 -0
- package/esm/src/evals/rubrics/mod.js +55 -0
- package/esm/src/evals/rubrics/mustache.d.ts +23 -0
- package/esm/src/evals/rubrics/mustache.js +154 -0
- package/esm/src/evals/rubrics/types.d.ts +54 -0
- package/esm/src/evals/rubrics/types.js +74 -0
- package/esm/src/evals/run.d.ts +118 -0
- package/esm/src/evals/run.js +452 -0
- package/esm/src/evals/suite.d.ts +19 -0
- package/esm/src/evals/suite.js +92 -0
- package/esm/src/evals/summary.d.ts +32 -0
- package/esm/src/evals/summary.js +30 -0
- package/esm/src/evals/trial.d.ts +27 -0
- package/esm/src/evals/trial.js +158 -0
- package/esm/src/evals/types.d.ts +260 -0
- package/esm/src/evals/types.js +126 -0
- package/esm/src/evals/verdict.d.ts +18 -0
- package/esm/src/evals/verdict.js +45 -0
- package/esm/src/guardrails/canary-gate.d.ts +21 -0
- package/esm/src/guardrails/canary-gate.js +40 -0
- package/esm/src/guardrails/canary.d.ts +112 -0
- package/esm/src/guardrails/canary.js +901 -0
- package/esm/src/guardrails/compile-egress.d.ts +11 -0
- package/esm/src/guardrails/compile-egress.js +11 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +22 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +303 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +5 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +202 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +3 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +118 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +13 -0
- package/esm/src/guardrails/corpus/live-attacks.js +224 -0
- package/esm/src/guardrails/corpus/mod.d.ts +7 -0
- package/esm/src/guardrails/corpus/mod.js +4 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +12 -0
- package/esm/src/guardrails/corpus/secrets.js +16 -0
- package/esm/src/guardrails/corpus/strings.d.ts +23 -0
- package/esm/src/guardrails/corpus/strings.js +29 -0
- package/esm/src/guardrails/corpus/types.d.ts +32 -0
- package/esm/src/guardrails/corpus/types.js +1 -0
- package/esm/src/guardrails/egress-automata.d.ts +14 -0
- package/esm/src/guardrails/egress-automata.js +6059 -0
- package/esm/src/guardrails/egress-compiler.d.ts +33 -0
- package/esm/src/guardrails/egress-compiler.js +237 -0
- package/esm/src/guardrails/egress-patterns.d.ts +24 -0
- package/esm/src/guardrails/egress-patterns.js +32 -0
- package/esm/src/guardrails/egress-policy.d.ts +27 -0
- package/esm/src/guardrails/egress-policy.js +76 -0
- package/esm/src/guardrails/egress-rules.d.ts +54 -0
- package/esm/src/guardrails/egress-rules.js +49 -0
- package/esm/src/guardrails/egress-stream.d.ts +105 -0
- package/esm/src/guardrails/egress-stream.js +645 -0
- package/esm/src/guardrails/egress-urls.d.ts +83 -0
- package/esm/src/guardrails/egress-urls.js +917 -0
- package/esm/src/guardrails/egress.d.ts +106 -0
- package/esm/src/guardrails/egress.js +374 -0
- package/esm/src/guardrails/error.d.ts +26 -0
- package/esm/src/guardrails/error.js +91 -0
- package/esm/src/guardrails/event-schemas.d.ts +57 -0
- package/esm/src/guardrails/event-schemas.js +41 -0
- package/esm/src/guardrails/events.d.ts +9 -0
- package/esm/src/guardrails/events.js +42 -0
- package/esm/src/guardrails/hits.d.ts +8 -0
- package/esm/src/guardrails/hits.js +19 -0
- package/esm/src/guardrails/injection-patterns.d.ts +15 -0
- package/esm/src/guardrails/injection-patterns.js +94 -0
- package/esm/src/guardrails/injection.d.ts +14 -0
- package/esm/src/guardrails/injection.js +237 -0
- package/esm/src/guardrails/lexicon.d.ts +30 -0
- package/esm/src/guardrails/lexicon.js +478 -0
- package/esm/src/guardrails/live-outbound-gate.d.ts +54 -0
- package/esm/src/guardrails/live-outbound-gate.js +305 -0
- package/esm/src/guardrails/mod.d.ts +46 -0
- package/esm/src/guardrails/mod.js +29 -0
- package/esm/src/guardrails/network.d.ts +42 -0
- package/esm/src/guardrails/network.js +328 -0
- package/esm/src/guardrails/normalize.d.ts +6 -0
- package/esm/src/guardrails/normalize.js +132 -0
- package/esm/src/guardrails/policy.d.ts +19 -0
- package/esm/src/guardrails/policy.js +50 -0
- package/esm/src/guardrails/progressive-yield.d.ts +69 -0
- package/esm/src/guardrails/progressive-yield.js +237 -0
- package/esm/src/guardrails/prompt-echo.d.ts +38 -0
- package/esm/src/guardrails/prompt-echo.js +225 -0
- package/esm/src/guardrails/quota.d.ts +20 -0
- package/esm/src/guardrails/quota.js +80 -0
- package/esm/src/guardrails/rules.d.ts +56 -0
- package/esm/src/guardrails/rules.js +54 -0
- package/esm/src/guardrails/sanitize.d.ts +23 -0
- package/esm/src/guardrails/sanitize.js +184 -0
- package/esm/src/guardrails/sensitive.d.ts +29 -0
- package/esm/src/guardrails/sensitive.js +113 -0
- package/esm/src/guardrails/serialize.d.ts +14 -0
- package/esm/src/guardrails/serialize.js +37 -0
- package/esm/src/guardrails/testing.d.ts +9 -0
- package/esm/src/guardrails/testing.js +8 -0
- package/esm/src/guardrails/theorem-error.d.ts +18 -0
- package/esm/src/guardrails/theorem-error.js +53 -0
- package/esm/src/guardrails/thought-guard.d.ts +55 -0
- package/esm/src/guardrails/thought-guard.js +464 -0
- package/esm/src/guardrails/tool-directives.d.ts +19 -0
- package/esm/src/guardrails/tool-directives.js +109 -0
- package/esm/src/guardrails/tool-result.d.ts +61 -0
- package/esm/src/guardrails/tool-result.js +248 -0
- package/esm/src/guardrails/types.d.ts +242 -0
- package/esm/src/guardrails/types.js +54 -0
- package/esm/src/host/client-turn.d.ts +9 -0
- package/esm/src/host/client-turn.js +38 -0
- package/esm/src/host/mint-trace.d.ts +28 -0
- package/esm/src/host/mint-trace.js +59 -0
- package/esm/src/host/mod.d.ts +13 -0
- package/esm/src/host/mod.js +11 -0
- package/esm/src/host/readStreamingJsonStringField.d.ts +2 -0
- package/esm/src/host/readStreamingJsonStringField.js +68 -0
- package/esm/src/host/reply.d.ts +7 -0
- package/esm/src/host/reply.js +35 -0
- package/esm/src/interface/blocks.d.ts +8 -0
- package/esm/src/interface/blocks.js +213 -0
- package/esm/src/interface/composer-actions.d.ts +20 -0
- package/esm/src/interface/composer-actions.js +31 -0
- package/esm/src/interface/draft.d.ts +14 -0
- package/esm/src/interface/draft.js +28 -0
- package/esm/src/interface/from-profile.d.ts +12 -0
- package/esm/src/interface/from-profile.js +144 -0
- package/esm/src/interface/history.d.ts +40 -0
- package/esm/src/interface/history.js +269 -0
- package/esm/src/interface/inputs.d.ts +10 -0
- package/esm/src/interface/inputs.js +64 -0
- package/esm/src/interface/mod.d.ts +31 -0
- package/esm/src/interface/mod.js +21 -0
- package/esm/src/interface/models.d.ts +19 -0
- package/esm/src/interface/models.js +45 -0
- package/esm/src/interface/pending.d.ts +48 -0
- package/esm/src/interface/pending.js +146 -0
- package/esm/src/interface/profile-interface.d.ts +4 -0
- package/esm/src/interface/profile-interface.js +223 -0
- package/esm/src/interface/session.d.ts +64 -0
- package/esm/src/interface/session.js +121 -0
- package/esm/src/interface/tool-calls.d.ts +20 -0
- package/esm/src/interface/tool-calls.js +73 -0
- package/esm/src/interface/tool-invoke.d.ts +4 -0
- package/esm/src/interface/tool-invoke.js +20 -0
- package/esm/src/interface/tool-media.d.ts +9 -0
- package/esm/src/interface/tool-media.js +112 -0
- package/esm/src/interface/types.d.ts +213 -0
- package/esm/src/interface/types.js +4 -0
- package/esm/src/kernel/auth/credential-source.d.ts +23 -0
- package/esm/src/kernel/auth/credential-source.js +11 -0
- package/esm/src/kernel/auth/crypto.d.ts +51 -0
- package/esm/src/kernel/auth/crypto.js +161 -0
- package/esm/src/kernel/auth/mod.d.ts +5 -0
- package/esm/src/kernel/auth/mod.js +5 -0
- package/esm/src/kernel/auth/oauth.d.ts +17 -0
- package/esm/src/kernel/auth/oauth.js +438 -0
- package/esm/src/kernel/auth/scope-refusal.d.ts +9 -0
- package/esm/src/kernel/auth/scope-refusal.js +8 -0
- package/esm/src/kernel/auth/typed-secret.d.ts +13 -0
- package/esm/src/kernel/auth/typed-secret.js +23 -0
- package/esm/src/kernel/auth/types.d.ts +139 -0
- package/esm/src/kernel/auth/types.js +1 -0
- package/esm/src/kernel/default-scope.d.ts +34 -0
- package/esm/src/kernel/default-scope.js +72 -0
- package/esm/src/kernel/engine/compaction.d.ts +70 -0
- package/esm/src/kernel/engine/compaction.js +202 -0
- package/esm/src/kernel/engine/decision.d.ts +41 -0
- package/esm/src/kernel/engine/decision.js +412 -0
- package/esm/src/kernel/engine/hash.d.ts +6 -0
- package/esm/src/kernel/engine/hash.js +22 -0
- package/esm/src/kernel/engine/live-inbound.d.ts +9 -0
- package/esm/src/kernel/engine/live-inbound.js +19 -0
- package/esm/src/kernel/engine/live-ingress.d.ts +9 -0
- package/esm/src/kernel/engine/live-ingress.js +37 -0
- package/esm/src/kernel/engine/media-probe/audio.d.ts +7 -0
- package/esm/src/kernel/engine/media-probe/audio.js +342 -0
- package/esm/src/kernel/engine/media-probe/bytes.d.ts +6 -0
- package/esm/src/kernel/engine/media-probe/bytes.js +26 -0
- package/esm/src/kernel/engine/media-probe/image.d.ts +5 -0
- package/esm/src/kernel/engine/media-probe/image.js +171 -0
- package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +19 -0
- package/esm/src/kernel/engine/media-probe/iso-bmff.js +48 -0
- package/esm/src/kernel/engine/media-probe/matroska.d.ts +35 -0
- package/esm/src/kernel/engine/media-probe/matroska.js +226 -0
- package/esm/src/kernel/engine/media-probe/mp4.d.ts +22 -0
- package/esm/src/kernel/engine/media-probe/mp4.js +279 -0
- package/esm/src/kernel/engine/media-probe/opus.d.ts +4 -0
- package/esm/src/kernel/engine/media-probe/opus.js +23 -0
- package/esm/src/kernel/engine/media-probe/pdf.d.ts +5 -0
- package/esm/src/kernel/engine/media-probe/pdf.js +117 -0
- package/esm/src/kernel/engine/media-probe/video.d.ts +15 -0
- package/esm/src/kernel/engine/media-probe/video.js +49 -0
- package/esm/src/kernel/engine/record.d.ts +3 -0
- package/esm/src/kernel/engine/record.js +11 -0
- package/esm/src/kernel/engine/repair.d.ts +7 -0
- package/esm/src/kernel/engine/repair.js +36 -0
- package/esm/src/kernel/engine/runner/gates.d.ts +5 -0
- package/esm/src/kernel/engine/runner/gates.js +322 -0
- package/esm/src/kernel/engine/runner/mod.d.ts +15 -0
- package/esm/src/kernel/engine/runner/mod.js +574 -0
- package/esm/src/kernel/engine/runner/schema-validation.d.ts +14 -0
- package/esm/src/kernel/engine/runner/schema-validation.js +105 -0
- package/esm/src/kernel/engine/runner/stages.d.ts +28 -0
- package/esm/src/kernel/engine/runner/stages.js +48 -0
- package/esm/src/kernel/engine/runner/state.d.ts +76 -0
- package/esm/src/kernel/engine/runner/state.js +40 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +14 -0
- package/esm/src/kernel/engine/runner/steps.js +360 -0
- package/esm/src/kernel/engine/runner/stream.d.ts +40 -0
- package/esm/src/kernel/engine/runner/stream.js +225 -0
- package/esm/src/kernel/engine/runner/usage.d.ts +45 -0
- package/esm/src/kernel/engine/runner/usage.js +150 -0
- package/esm/src/kernel/engine/session/mod.d.ts +31 -0
- package/esm/src/kernel/engine/session/mod.js +951 -0
- package/esm/src/kernel/engine/session/session-trace.d.ts +115 -0
- package/esm/src/kernel/engine/session/session-trace.js +489 -0
- package/esm/src/kernel/engine/token-estimate.d.ts +77 -0
- package/esm/src/kernel/engine/token-estimate.js +218 -0
- package/esm/src/kernel/engine/tool-trace.d.ts +58 -0
- package/esm/src/kernel/engine/tool-trace.js +131 -0
- package/esm/src/kernel/engine/tree.d.ts +2 -0
- package/esm/src/kernel/engine/tree.js +17 -0
- package/esm/src/kernel/engine/turn-trace.d.ts +118 -0
- package/esm/src/kernel/engine/turn-trace.js +863 -0
- package/esm/src/kernel/engine/usage.d.ts +30 -0
- package/esm/src/kernel/engine/usage.js +134 -0
- package/esm/src/kernel/interaction-parts.d.ts +10 -0
- package/esm/src/kernel/interaction-parts.js +22 -0
- package/esm/src/kernel/mod.d.ts +47 -0
- package/esm/src/kernel/mod.js +30 -0
- package/esm/src/kernel/profile-graph.d.ts +140 -0
- package/esm/src/kernel/profile-graph.js +151 -0
- package/esm/src/kernel/profile-presence.d.ts +9 -0
- package/esm/src/kernel/profile-presence.js +143 -0
- package/esm/src/kernel/profile-scope.d.ts +36 -0
- package/esm/src/kernel/profile-scope.js +262 -0
- package/esm/src/kernel/registry/attachments.d.ts +35 -0
- package/esm/src/kernel/registry/attachments.js +211 -0
- package/esm/src/kernel/registry/catalog.d.ts +19 -0
- package/esm/src/kernel/registry/catalog.js +78 -0
- package/esm/src/kernel/registry/ingress.d.ts +8 -0
- package/esm/src/kernel/registry/ingress.js +134 -0
- package/esm/src/kernel/registry/kernel-registry.d.ts +12 -0
- package/esm/src/kernel/registry/kernel-registry.js +8 -0
- package/esm/src/kernel/registry/profile-outputs.d.ts +3 -0
- package/esm/src/kernel/registry/profile-outputs.js +7 -0
- package/esm/src/kernel/registry/profiles.d.ts +92 -0
- package/esm/src/kernel/registry/profiles.js +698 -0
- package/esm/src/kernel/registry/provider-request.d.ts +6 -0
- package/esm/src/kernel/registry/provider-request.js +42 -0
- package/esm/src/kernel/registry/resolve.d.ts +14 -0
- package/esm/src/kernel/registry/resolve.js +237 -0
- package/esm/src/kernel/registry/schemas.d.ts +9 -0
- package/esm/src/kernel/registry/schemas.js +25 -0
- package/esm/src/kernel/registry/sole-model.d.ts +2 -0
- package/esm/src/kernel/registry/sole-model.js +4 -0
- package/esm/src/kernel/registry/system-prompt.d.ts +8 -0
- package/esm/src/kernel/registry/system-prompt.js +33 -0
- package/esm/src/kernel/registry/system-role.d.ts +3 -0
- package/esm/src/kernel/registry/system-role.js +9 -0
- package/esm/src/kernel/registry/vault.d.ts +13 -0
- package/esm/src/kernel/registry/vault.js +14 -0
- package/esm/src/kernel/schema.d.ts +172 -0
- package/esm/src/kernel/schema.js +653 -0
- package/esm/src/kernel/scope.d.ts +22 -0
- package/esm/src/kernel/scope.js +25 -0
- package/esm/src/kernel/stages.d.ts +141 -0
- package/esm/src/kernel/stages.js +388 -0
- package/esm/src/kernel/stop.d.ts +93 -0
- package/esm/src/kernel/stop.js +125 -0
- package/esm/src/kernel/system-parts.d.ts +26 -0
- package/esm/src/kernel/system-parts.js +98 -0
- package/esm/src/kernel/tools/activity-label.d.ts +16 -0
- package/esm/src/kernel/tools/activity-label.js +209 -0
- package/esm/src/kernel/tools/events.d.ts +51 -0
- package/esm/src/kernel/tools/events.js +149 -0
- package/esm/src/kernel/tools/execute.d.ts +64 -0
- package/esm/src/kernel/tools/execute.js +801 -0
- package/esm/src/kernel/tools/gate-answer.d.ts +50 -0
- package/esm/src/kernel/tools/gate-answer.js +54 -0
- package/esm/src/kernel/tools/harness.d.ts +16 -0
- package/esm/src/kernel/tools/harness.js +42 -0
- package/esm/src/kernel/tools/invoke.d.ts +10 -0
- package/esm/src/kernel/tools/invoke.js +129 -0
- package/esm/src/kernel/tools/mcp-sessions.d.ts +20 -0
- package/esm/src/kernel/tools/mcp-sessions.js +64 -0
- package/esm/src/kernel/tools/mod.d.ts +9 -0
- package/esm/src/kernel/tools/mod.js +6 -0
- package/esm/src/kernel/tools/model-text.d.ts +11 -0
- package/esm/src/kernel/tools/model-text.js +25 -0
- package/esm/src/kernel/tools/permission.d.ts +6 -0
- package/esm/src/kernel/tools/permission.js +38 -0
- package/esm/src/kernel/tools/project.d.ts +8 -0
- package/esm/src/kernel/tools/project.js +25 -0
- package/esm/src/kernel/tools/registry.d.ts +20 -0
- package/esm/src/kernel/tools/registry.js +84 -0
- package/esm/src/kernel/tools/remote.d.ts +110 -0
- package/esm/src/kernel/tools/remote.js +998 -0
- package/esm/src/kernel/tools/resolve.d.ts +28 -0
- package/esm/src/kernel/tools/resolve.js +259 -0
- package/esm/src/kernel/tools/schema.d.ts +10 -0
- package/esm/src/kernel/tools/schema.js +174 -0
- package/esm/src/kernel/tools/signed-in-fetch.d.ts +18 -0
- package/esm/src/kernel/tools/signed-in-fetch.js +45 -0
- package/esm/src/kernel/tools/stage-run.d.ts +93 -0
- package/esm/src/kernel/tools/stage-run.js +140 -0
- package/esm/src/kernel/tools/types.d.ts +287 -0
- package/esm/src/kernel/tools/types.js +1 -0
- package/esm/src/kernel/turn-events.d.ts +599 -0
- package/esm/src/kernel/turn-events.js +425 -0
- package/esm/src/kernel/types.d.ts +884 -0
- package/esm/src/kernel/types.js +1 -0
- package/esm/src/kernel/util/base64.d.ts +2 -0
- package/esm/src/kernel/util/base64.js +13 -0
- package/esm/src/kernel/util/exact-type.d.ts +31 -0
- package/esm/src/kernel/util/exact-type.js +1 -0
- package/esm/src/kernel/util/find-last.d.ts +3 -0
- package/esm/src/kernel/util/find-last.js +9 -0
- package/esm/src/kernel/util/mime.d.ts +2 -0
- package/esm/src/kernel/util/mime.js +4 -0
- package/esm/src/kernel/util/record.d.ts +1 -0
- package/esm/src/kernel/util/record.js +3 -0
- package/esm/src/observability/destinations.d.ts +9 -0
- package/esm/src/observability/destinations.js +38 -0
- package/esm/src/observability/jsonl.d.ts +18 -0
- package/esm/src/observability/jsonl.js +117 -0
- package/esm/src/observability/mod.d.ts +22 -0
- package/esm/src/observability/mod.js +16 -0
- package/esm/src/observability/openinference.d.ts +11 -0
- package/esm/src/observability/openinference.js +205 -0
- package/esm/src/observability/otlp.d.ts +68 -0
- package/esm/src/observability/otlp.js +98 -0
- package/esm/src/observability/phoenix.d.ts +29 -0
- package/esm/src/observability/phoenix.js +71 -0
- package/esm/src/observability/policy.d.ts +14 -0
- package/esm/src/observability/policy.js +69 -0
- package/esm/src/observability/resolve-policy.d.ts +8 -0
- package/esm/src/observability/resolve-policy.js +58 -0
- package/esm/src/observability/spans.d.ts +16 -0
- package/esm/src/observability/spans.js +56 -0
- package/esm/src/observability/trace-catalog.d.ts +111 -0
- package/esm/src/observability/trace-catalog.js +865 -0
- package/esm/src/observability/trace-record.d.ts +23 -0
- package/esm/src/observability/trace-record.js +223 -0
- package/esm/src/observability/trace-schema.d.ts +54 -0
- package/esm/src/observability/trace-schema.js +59 -0
- package/esm/src/observability/trace-sink.d.ts +13 -0
- package/esm/src/observability/trace-sink.js +3 -0
- package/esm/src/observability/trace-span.d.ts +92 -0
- package/esm/src/observability/trace-span.js +199 -0
- package/esm/src/observability/trace.d.ts +11 -0
- package/esm/src/observability/trace.js +35 -0
- package/esm/src/observability/types.d.ts +85 -0
- package/esm/src/observability/types.js +3 -0
- package/esm/src/presets/google/speech-voices.d.ts +8 -0
- package/esm/src/presets/google/speech-voices.js +38 -0
- package/esm/src/presets/google-limits.d.ts +12 -0
- package/esm/src/presets/google-limits.js +18 -0
- package/esm/src/presets/google.d.ts +104 -0
- package/esm/src/presets/google.js +188 -0
- package/esm/src/presets/mod.d.ts +10 -0
- package/esm/src/presets/mod.js +9 -0
- package/esm/src/presets/openrouter.d.ts +13 -0
- package/esm/src/presets/openrouter.js +13 -0
- package/esm/src/presets/typesafe.d.ts +2 -0
- package/esm/src/presets/typesafe.js +2 -0
- package/esm/src/providers/create-provider.d.ts +21 -0
- package/esm/src/providers/create-provider.js +90 -0
- package/esm/src/providers/decision/usage.d.ts +3 -0
- package/esm/src/providers/decision/usage.js +25 -0
- package/esm/src/providers/google/api-error.d.ts +8 -0
- package/esm/src/providers/google/api-error.js +123 -0
- package/esm/src/providers/google/grounding.d.ts +5 -0
- package/esm/src/providers/google/grounding.js +226 -0
- package/esm/src/providers/google/interactions/framing.d.ts +15 -0
- package/esm/src/providers/google/interactions/framing.js +263 -0
- package/esm/src/providers/google/interactions/mod.d.ts +2 -0
- package/esm/src/providers/google/interactions/mod.js +2 -0
- package/esm/src/providers/google/interactions/steps.d.ts +12 -0
- package/esm/src/providers/google/interactions/steps.js +200 -0
- package/esm/src/providers/google/interactions/stream.d.ts +24 -0
- package/esm/src/providers/google/interactions/stream.js +297 -0
- package/esm/src/providers/google/keys.d.ts +20 -0
- package/esm/src/providers/google/keys.js +87 -0
- package/esm/src/providers/google/live/framing.d.ts +51 -0
- package/esm/src/providers/google/live/framing.js +597 -0
- package/esm/src/providers/google/live/mod.d.ts +7 -0
- package/esm/src/providers/google/live/mod.js +7 -0
- package/esm/src/providers/google/live/openapi-schema.d.ts +1 -0
- package/esm/src/providers/google/live/openapi-schema.js +42 -0
- package/esm/src/providers/google/live/session.d.ts +14 -0
- package/esm/src/providers/google/live/session.js +150 -0
- package/esm/src/providers/google/live/stream.d.ts +51 -0
- package/esm/src/providers/google/live/stream.js +263 -0
- package/esm/src/providers/google/thinking.d.ts +3 -0
- package/esm/src/providers/google/thinking.js +8 -0
- package/esm/src/providers/google/urls.d.ts +6 -0
- package/esm/src/providers/google/urls.js +6 -0
- package/esm/src/providers/google/usage.d.ts +7 -0
- package/esm/src/providers/google/usage.js +49 -0
- package/esm/src/providers/local/local.d.ts +12 -0
- package/esm/src/providers/local/local.js +186 -0
- package/esm/src/providers/local/mod.d.ts +8 -0
- package/esm/src/providers/local/mod.js +8 -0
- package/esm/src/providers/mod.d.ts +11 -0
- package/esm/src/providers/mod.js +7 -0
- package/esm/src/providers/openrouter/cache-control.d.ts +5 -0
- package/esm/src/providers/openrouter/cache-control.js +4 -0
- package/esm/src/providers/openrouter/chat.d.ts +64 -0
- package/esm/src/providers/openrouter/chat.js +490 -0
- package/esm/src/providers/openrouter/image.d.ts +24 -0
- package/esm/src/providers/openrouter/image.js +187 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +19 -0
- package/esm/src/providers/openrouter/openai/compat.js +162 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +9 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +115 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +10 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.js +99 -0
- package/esm/src/providers/openrouter/openai/usage.d.ts +8 -0
- package/esm/src/providers/openrouter/openai/usage.js +56 -0
- package/esm/src/providers/openrouter/resolve-api-key.d.ts +3 -0
- package/esm/src/providers/openrouter/resolve-api-key.js +8 -0
- package/esm/src/providers/openrouter/speech.d.ts +18 -0
- package/esm/src/providers/openrouter/speech.js +109 -0
- package/esm/src/providers/probe.d.ts +5 -0
- package/esm/src/providers/probe.js +15 -0
- package/esm/src/providers/shared/builtin-wire.d.ts +4 -0
- package/esm/src/providers/shared/builtin-wire.js +9 -0
- package/esm/src/providers/shared/pcm.d.ts +14 -0
- package/esm/src/providers/shared/pcm.js +78 -0
- package/esm/src/providers/shared/response-identity.d.ts +11 -0
- package/esm/src/providers/shared/response-identity.js +12 -0
- package/esm/src/providers/shared/sse.d.ts +10 -0
- package/esm/src/providers/shared/sse.js +79 -0
- package/esm/src/providers/shared/structured-output.d.ts +4 -0
- package/esm/src/providers/shared/structured-output.js +11 -0
- package/esm/src/providers/shared/tool-args.d.ts +25 -0
- package/esm/src/providers/shared/tool-args.js +84 -0
- package/esm/src/providers/shared/upstream-tap.d.ts +8 -0
- package/esm/src/providers/shared/upstream-tap.js +85 -0
- package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
- package/esm/src/providers/shared/upstream-tape.js +88 -0
- package/esm/src/providers/shared/vault.d.ts +13 -0
- package/esm/src/providers/shared/vault.js +41 -0
- package/esm/src/providers/types.d.ts +19 -0
- package/esm/src/providers/types.js +1 -0
- package/esm/src/surface/formats.d.ts +28 -0
- package/esm/src/surface/formats.js +139 -0
- package/esm/src/surface/mod.d.ts +14 -0
- package/esm/src/surface/mod.js +10 -0
- package/esm/src/surface/runtime.d.ts +40 -0
- package/esm/src/surface/runtime.js +439 -0
- package/esm/src/surface/tools.d.ts +15 -0
- package/esm/src/surface/tools.js +80 -0
- package/esm/src/surface/types.d.ts +104 -0
- package/esm/src/surface/types.js +4 -0
- package/package.json +108 -4
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
|
|
2
|
+
import { AISDKError, APICallError, generateText, jsonSchema, RetryError, StreamProviderError, streamText, tool, } from 'ai';
|
|
3
|
+
import { isAbortError, kindOfHttpStatus, TheoremError, toErrorEvent, } from '../../guardrails/error.js';
|
|
4
|
+
import { asRecord } from '../../kernel/engine/record.js';
|
|
5
|
+
import { reportedTokens, usageCount } from '../../kernel/engine/usage.js';
|
|
6
|
+
import { turnStopFromOpenAiFinishReason } from '../../kernel/stop.js';
|
|
7
|
+
import { builtinWire } from '../shared/builtin-wire.js';
|
|
8
|
+
import { foldResponse } from '../shared/response-identity.js';
|
|
9
|
+
import { structuredEvent } from '../shared/structured-output.js';
|
|
10
|
+
import { malformedToolCall, toolCallEvents } from '../shared/tool-args.js';
|
|
11
|
+
import { networkError } from '../shared/upstream-tap.js';
|
|
12
|
+
import { bearerFetch } from '../shared/vault.js';
|
|
13
|
+
import { cacheControlJson } from './cache-control.js';
|
|
14
|
+
import { openAiGatewayHeaders, resolveResponseFormat } from './openai/compat.js';
|
|
15
|
+
import { buildAiSdkMessages } from './openai/sdk-messages.js';
|
|
16
|
+
import { openAiResponse, openAiUsageTokens } from './openai/usage.js';
|
|
17
|
+
import { resolveOpenAiGatewayApiKey } from './resolve-api-key.js';
|
|
18
|
+
export function trimApiKey(explicitKey) {
|
|
19
|
+
if (explicitKey?.trim()) {
|
|
20
|
+
return explicitKey.trim();
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
export function createAccumulator() {
|
|
25
|
+
return {
|
|
26
|
+
text: '',
|
|
27
|
+
citedUris: new Set(),
|
|
28
|
+
reportedAnnotations: new Set(),
|
|
29
|
+
emittedTokens: false,
|
|
30
|
+
errored: false,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function webSource(uri, title) {
|
|
34
|
+
return { title: title || uri, uri, type: 'web' };
|
|
35
|
+
}
|
|
36
|
+
function citationEvent(sources, acc) {
|
|
37
|
+
const fresh = [];
|
|
38
|
+
for (const source of sources) {
|
|
39
|
+
if (acc.citedUris.has(source.uri))
|
|
40
|
+
continue;
|
|
41
|
+
acc.citedUris.add(source.uri);
|
|
42
|
+
fresh.push(source);
|
|
43
|
+
}
|
|
44
|
+
return fresh.length > 0 ? { type: 'citation', sources: fresh } : undefined;
|
|
45
|
+
}
|
|
46
|
+
export function sourceEvent(part, acc) {
|
|
47
|
+
if (part.sourceType === 'url') {
|
|
48
|
+
return citationEvent([webSource(part.url, part.title)], acc);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
type: 'evidence',
|
|
52
|
+
evidence: { provider: 'openrouter', kind: 'provider_step', step: 'source', raw: { ...part } },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function schemaForTool(decl) {
|
|
56
|
+
return decl.parameters ?? { type: 'object', properties: {}, additionalProperties: true };
|
|
57
|
+
}
|
|
58
|
+
export function buildTools(wireTools) {
|
|
59
|
+
if (!wireTools || wireTools.length === 0) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const tools = {};
|
|
63
|
+
for (const decl of wireTools) {
|
|
64
|
+
tools[decl.name] = tool({
|
|
65
|
+
description: decl.description,
|
|
66
|
+
inputSchema: jsonSchema(schemaForTool(decl)),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return tools;
|
|
70
|
+
}
|
|
71
|
+
/** `web` wires as `web_search_options`; every other builtin is a plugin. */
|
|
72
|
+
function openRouterSettings(req) {
|
|
73
|
+
let webSearch = false;
|
|
74
|
+
const plugins = [];
|
|
75
|
+
for (const builtin of req.builtins) {
|
|
76
|
+
const pluginId = builtinWire(builtin, 'openRouter');
|
|
77
|
+
if (pluginId === 'web')
|
|
78
|
+
webSearch = true;
|
|
79
|
+
else
|
|
80
|
+
plugins.push({ id: pluginId });
|
|
81
|
+
}
|
|
82
|
+
if (plugins.length === 0 && !webSearch) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const settings = {};
|
|
86
|
+
if (plugins.length > 0) {
|
|
87
|
+
settings.plugins = plugins;
|
|
88
|
+
}
|
|
89
|
+
if (webSearch)
|
|
90
|
+
settings.web_search_options = {};
|
|
91
|
+
return settings;
|
|
92
|
+
}
|
|
93
|
+
/** Only when the raw stream carried no `usage` row; `rawEvents` reads that one first, with cost. */
|
|
94
|
+
export function tokensFromUsage(usage) {
|
|
95
|
+
return reportedTokens({
|
|
96
|
+
input: usageCount(usage.inputTokens),
|
|
97
|
+
output: usageCount(usage.outputTokens),
|
|
98
|
+
thinking: usageCount(usage.outputTokenDetails?.reasoningTokens),
|
|
99
|
+
cached: usageCount(usage.inputTokenDetails?.cacheReadTokens),
|
|
100
|
+
cacheWrite: usageCount(usage.inputTokenDetails?.cacheWriteTokens),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
export function stringArray(value) {
|
|
104
|
+
if (!Array.isArray(value)) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const out = value.filter((item) => typeof item === 'string');
|
|
108
|
+
return out.length > 0 ? out : undefined;
|
|
109
|
+
}
|
|
110
|
+
export function metadataRecord(raw, key) {
|
|
111
|
+
return asRecord(raw[key]);
|
|
112
|
+
}
|
|
113
|
+
export function citationCandidates(raw) {
|
|
114
|
+
const openrouter = metadataRecord(raw, 'openrouter') ?? {};
|
|
115
|
+
return [
|
|
116
|
+
raw.citations,
|
|
117
|
+
metadataRecord(raw, 'providerMetadata')?.citations,
|
|
118
|
+
metadataRecord(raw, 'provider_metadata')?.citations,
|
|
119
|
+
openrouter.citations,
|
|
120
|
+
metadataRecord(openrouter, 'providerMetadata')?.citations,
|
|
121
|
+
metadataRecord(openrouter, 'provider_metadata')?.citations,
|
|
122
|
+
];
|
|
123
|
+
}
|
|
124
|
+
export function nestedCitations(raw) {
|
|
125
|
+
for (const candidate of citationCandidates(raw)) {
|
|
126
|
+
const citations = stringArray(candidate);
|
|
127
|
+
if (citations) {
|
|
128
|
+
return citations;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
export function metadataAnnotations(raw) {
|
|
134
|
+
const openrouter = metadataRecord(raw, 'openrouter');
|
|
135
|
+
if (Array.isArray(raw.annotations)) {
|
|
136
|
+
return raw.annotations;
|
|
137
|
+
}
|
|
138
|
+
if (Array.isArray(openrouter?.annotations)) {
|
|
139
|
+
return openrouter.annotations;
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
function annotationSource(annotation) {
|
|
144
|
+
const record = asRecord(annotation);
|
|
145
|
+
const cited = asRecord(record?.url_citation);
|
|
146
|
+
if (record?.type !== 'url_citation' || typeof cited?.url !== 'string') {
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
return webSource(cited.url, typeof cited.title === 'string' ? cited.title : undefined);
|
|
150
|
+
}
|
|
151
|
+
/** Each citation or annotation reports once per call, however many rows repeat it. */
|
|
152
|
+
export function eventsFromMetadata(metadata, acc) {
|
|
153
|
+
const raw = asRecord(metadata);
|
|
154
|
+
if (!raw) {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
const annotations = metadataAnnotations(raw) ?? [];
|
|
158
|
+
const sources = (nestedCitations(raw) ?? []).map((uri) => webSource(uri));
|
|
159
|
+
const other = [];
|
|
160
|
+
for (const annotation of annotations) {
|
|
161
|
+
const source = annotationSource(annotation);
|
|
162
|
+
if (source) {
|
|
163
|
+
sources.push(source);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const key = String(JSON.stringify(annotation));
|
|
167
|
+
if (acc.reportedAnnotations.has(key))
|
|
168
|
+
continue;
|
|
169
|
+
acc.reportedAnnotations.add(key);
|
|
170
|
+
other.push(annotation);
|
|
171
|
+
}
|
|
172
|
+
const events = [];
|
|
173
|
+
const citation = citationEvent(sources, acc);
|
|
174
|
+
if (citation) {
|
|
175
|
+
events.push(citation);
|
|
176
|
+
}
|
|
177
|
+
if (other.length > 0) {
|
|
178
|
+
events.push({
|
|
179
|
+
type: 'evidence',
|
|
180
|
+
evidence: {
|
|
181
|
+
provider: 'openrouter',
|
|
182
|
+
kind: 'provider_step',
|
|
183
|
+
step: 'annotations',
|
|
184
|
+
raw: { annotations: other },
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return events;
|
|
189
|
+
}
|
|
190
|
+
export function rawThoughtEvent(raw) {
|
|
191
|
+
const choices = raw.choices;
|
|
192
|
+
if (!Array.isArray(choices)) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
for (const choice of choices) {
|
|
196
|
+
const delta = asRecord(asRecord(choice)?.delta);
|
|
197
|
+
if (typeof delta?.thinking === 'string') {
|
|
198
|
+
return { type: 'thought', text: delta.thinking };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
export function rawChoiceMessageEvents(raw, acc) {
|
|
204
|
+
const choices = Array.isArray(raw.choices) ? raw.choices : [];
|
|
205
|
+
return choices.flatMap((choice) => eventsFromMetadata(asRecord(choice)?.message, acc));
|
|
206
|
+
}
|
|
207
|
+
export function rawEvents(raw, acc) {
|
|
208
|
+
const record = asRecord(raw);
|
|
209
|
+
if (!record) {
|
|
210
|
+
return [];
|
|
211
|
+
}
|
|
212
|
+
const identity = foldResponse(acc.response, openAiResponse(record));
|
|
213
|
+
acc.response = identity.known;
|
|
214
|
+
const events = identity.event ? [identity.event] : [];
|
|
215
|
+
const thought = rawThoughtEvent(record);
|
|
216
|
+
if (thought) {
|
|
217
|
+
events.push(thought);
|
|
218
|
+
}
|
|
219
|
+
events.push(...eventsFromMetadata(record, acc), ...rawChoiceMessageEvents(record, acc));
|
|
220
|
+
if (!acc.emittedTokens) {
|
|
221
|
+
const usage = openAiUsageTokens(record.usage);
|
|
222
|
+
if (usage) {
|
|
223
|
+
acc.emittedTokens = true;
|
|
224
|
+
events.push({ type: 'tokens', tokens: usage });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const choices = Array.isArray(record.choices) ? record.choices : [];
|
|
228
|
+
for (const choice of choices) {
|
|
229
|
+
const row = asRecord(choice);
|
|
230
|
+
if (!row)
|
|
231
|
+
continue;
|
|
232
|
+
if (typeof row.finish_reason === 'string' || row.finish_reason === null) {
|
|
233
|
+
acc.finishReason = row.finish_reason;
|
|
234
|
+
}
|
|
235
|
+
if (typeof row.native_finish_reason === 'string' || row.native_finish_reason === null) {
|
|
236
|
+
acc.nativeFinishReason = row.native_finish_reason;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return events;
|
|
240
|
+
}
|
|
241
|
+
/** A call the SDK could not parse or match is the call with no arguments, then its failure. */
|
|
242
|
+
export function toolCallPartEvents(part) {
|
|
243
|
+
if (part.invalid) {
|
|
244
|
+
const message = part.error instanceof Error ? part.error.message : 'tool call was not valid';
|
|
245
|
+
return malformedToolCall({ name: part.toolName, callId: part.toolCallId }, message, part.input);
|
|
246
|
+
}
|
|
247
|
+
return toolCallEvents({ id: part.toolCallId, name: part.toolName }, part.input);
|
|
248
|
+
}
|
|
249
|
+
export function tokenEvent(part) {
|
|
250
|
+
const tokens = tokensFromUsage(part.totalUsage);
|
|
251
|
+
return tokens ? { type: 'tokens', tokens } : undefined;
|
|
252
|
+
}
|
|
253
|
+
export function providerMetadataEvents(part, acc) {
|
|
254
|
+
return 'providerMetadata' in part ? eventsFromMetadata(part.providerMetadata, acc) : [];
|
|
255
|
+
}
|
|
256
|
+
export function eventFromPart(part, acc) {
|
|
257
|
+
return [...primaryEventsFromPart(part, acc), ...providerMetadataEvents(part, acc)];
|
|
258
|
+
}
|
|
259
|
+
export function primaryEventsFromPart(part, acc) {
|
|
260
|
+
switch (part.type) {
|
|
261
|
+
case 'text-delta':
|
|
262
|
+
acc.text += part.text;
|
|
263
|
+
return [{ type: 'text', text: part.text }];
|
|
264
|
+
case 'reasoning-delta':
|
|
265
|
+
return [{ type: 'thought', text: part.text }];
|
|
266
|
+
case 'tool-call':
|
|
267
|
+
return toolCallPartEvents(part);
|
|
268
|
+
case 'source': {
|
|
269
|
+
const event = sourceEvent(part, acc);
|
|
270
|
+
return event ? [event] : [];
|
|
271
|
+
}
|
|
272
|
+
case 'finish': {
|
|
273
|
+
const event = finishEvent(part, acc);
|
|
274
|
+
return event ? [event] : [];
|
|
275
|
+
}
|
|
276
|
+
case 'error':
|
|
277
|
+
acc.errored = true;
|
|
278
|
+
return [toErrorEvent(streamPartError(part.error))];
|
|
279
|
+
default:
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
export function finishEvent(part, acc) {
|
|
284
|
+
if (part.finishReason != null) {
|
|
285
|
+
acc.finishReason = String(part.finishReason);
|
|
286
|
+
}
|
|
287
|
+
if (acc.emittedTokens) {
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
if (!part.totalUsage) {
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
const event = tokenEvent({ totalUsage: part.totalUsage });
|
|
294
|
+
if (event) {
|
|
295
|
+
acc.emittedTokens = true;
|
|
296
|
+
}
|
|
297
|
+
return event;
|
|
298
|
+
}
|
|
299
|
+
export function* finalEvents(req, acc) {
|
|
300
|
+
if (acc.errored) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
if (req.structured && acc.text) {
|
|
304
|
+
const event = structuredEvent(acc.text);
|
|
305
|
+
yield event;
|
|
306
|
+
if (event.type === 'error')
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
yield {
|
|
310
|
+
type: 'done',
|
|
311
|
+
stop: turnStopFromOpenAiFinishReason(acc.finishReason, acc.nativeFinishReason),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function createStreamContext(req, config, apiKey) {
|
|
315
|
+
const openrouter = createOpenRouter({
|
|
316
|
+
apiKey,
|
|
317
|
+
baseURL: config.baseUrl,
|
|
318
|
+
headers: openAiGatewayHeaders(config),
|
|
319
|
+
// The AI SDK retries internally; tapping its fetch tapes every try.
|
|
320
|
+
fetch: bearerFetch(req, config.fetch ?? fetch, config.vault, apiKey),
|
|
321
|
+
compatibility: 'strict',
|
|
322
|
+
});
|
|
323
|
+
return {
|
|
324
|
+
openrouter,
|
|
325
|
+
modelName: req.apiId,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
/** System via instructions XOR a cache-marked system message — never both. */
|
|
329
|
+
export function systemDelivery(req) {
|
|
330
|
+
if (!req.system) {
|
|
331
|
+
return {};
|
|
332
|
+
}
|
|
333
|
+
if (req.cache?.mode === 'system') {
|
|
334
|
+
return {
|
|
335
|
+
systemMessage: {
|
|
336
|
+
role: 'system',
|
|
337
|
+
content: req.system,
|
|
338
|
+
providerOptions: {
|
|
339
|
+
openrouter: { cacheControl: cacheControlJson(req.cache) },
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
return { instructions: req.system };
|
|
345
|
+
}
|
|
346
|
+
function streamTextOptions(req, context) {
|
|
347
|
+
const delivery = systemDelivery(req);
|
|
348
|
+
const messages = buildAiSdkMessages(req);
|
|
349
|
+
if (delivery.systemMessage) {
|
|
350
|
+
messages.unshift(delivery.systemMessage);
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
model: context.openrouter.chat(context.modelName, openRouterSettings(req)),
|
|
354
|
+
instructions: delivery.instructions,
|
|
355
|
+
messages,
|
|
356
|
+
allowSystemInMessages: true,
|
|
357
|
+
temperature: req.temperature,
|
|
358
|
+
maxOutputTokens: req.maxOutputTokens,
|
|
359
|
+
tools: buildTools(req.wireTools),
|
|
360
|
+
providerOptions: providerOptionsFor(req),
|
|
361
|
+
include: { rawChunks: true },
|
|
362
|
+
abortSignal: req.signal,
|
|
363
|
+
onError: () => undefined,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function shouldEmitProviderEvent(req, event) {
|
|
367
|
+
return event.type !== 'thought' || req.summaries !== 'none';
|
|
368
|
+
}
|
|
369
|
+
async function* yieldAiSdkStream(req, acc, context) {
|
|
370
|
+
const result = streamText(streamTextOptions(req, context));
|
|
371
|
+
for await (const part of result.stream) {
|
|
372
|
+
if (part.type === 'raw') {
|
|
373
|
+
req.tapUpstream?.(asRecord(part.rawValue) ?? { rawValue: part.rawValue });
|
|
374
|
+
for (const event of rawEvents(part.rawValue, acc)) {
|
|
375
|
+
if (shouldEmitProviderEvent(req, event)) {
|
|
376
|
+
yield event;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
for (const event of eventFromPart(part, acc)) {
|
|
382
|
+
if (shouldEmitProviderEvent(req, event)) {
|
|
383
|
+
yield event;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
async function* yieldAiSdkBuffered(req, acc, context) {
|
|
389
|
+
const { include: _, onError: __, ...options } = streamTextOptions(req, context);
|
|
390
|
+
const result = await generateText({ ...options, include: { responseBody: true } });
|
|
391
|
+
const body = asRecord(result.response.body);
|
|
392
|
+
if (body) {
|
|
393
|
+
req.tapUpstream?.(body);
|
|
394
|
+
yield* rawEvents(body, acc).filter((event) => shouldEmitProviderEvent(req, event));
|
|
395
|
+
}
|
|
396
|
+
for (const part of result.content) {
|
|
397
|
+
const events = part.type === 'text'
|
|
398
|
+
? [{ type: 'text', text: part.text }]
|
|
399
|
+
: part.type === 'reasoning'
|
|
400
|
+
? [{ type: 'thought', text: part.text }]
|
|
401
|
+
: part.type === 'tool-call' || part.type === 'source'
|
|
402
|
+
? primaryEventsFromPart(part, acc)
|
|
403
|
+
: [];
|
|
404
|
+
if (part.type === 'text')
|
|
405
|
+
acc.text += part.text;
|
|
406
|
+
yield* events.filter((event) => shouldEmitProviderEvent(req, event));
|
|
407
|
+
}
|
|
408
|
+
yield* eventsFromMetadata(result.providerMetadata, acc).filter((event) => shouldEmitProviderEvent(req, event));
|
|
409
|
+
const tokens = finishEvent(result, acc);
|
|
410
|
+
if (tokens)
|
|
411
|
+
yield tokens;
|
|
412
|
+
}
|
|
413
|
+
async function* streamOpenRouter(req, config) {
|
|
414
|
+
let apiKey;
|
|
415
|
+
try {
|
|
416
|
+
apiKey = resolveOpenAiGatewayApiKey(config, req.keySlot);
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
yield toErrorEvent(err);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const acc = createAccumulator();
|
|
423
|
+
const context = createStreamContext(req, config, apiKey);
|
|
424
|
+
try {
|
|
425
|
+
yield* req.stream === false
|
|
426
|
+
? yieldAiSdkBuffered(req, acc, context)
|
|
427
|
+
: yieldAiSdkStream(req, acc, context);
|
|
428
|
+
yield* finalEvents(req, acc);
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
if (isAbortError(err)) {
|
|
432
|
+
throw err;
|
|
433
|
+
}
|
|
434
|
+
yield toErrorEvent(sdkError(err));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* An HTTP status wins; a call with no response could not reach OpenRouter; a
|
|
439
|
+
* mid-stream error without a status is OpenRouter's own; any other SDK error is
|
|
440
|
+
* a reply the SDK could not read.
|
|
441
|
+
*/
|
|
442
|
+
function sdkError(err) {
|
|
443
|
+
if (RetryError.isInstance(err)) {
|
|
444
|
+
return sdkError(err.lastError);
|
|
445
|
+
}
|
|
446
|
+
if (!AISDKError.isInstance(err)) {
|
|
447
|
+
return err;
|
|
448
|
+
}
|
|
449
|
+
const status = asRecord(err)?.statusCode;
|
|
450
|
+
const kind = typeof status === 'number'
|
|
451
|
+
? kindOfHttpStatus(status)
|
|
452
|
+
: APICallError.isInstance(err)
|
|
453
|
+
? 'network'
|
|
454
|
+
: StreamProviderError.isInstance(err)
|
|
455
|
+
? 'unavailable'
|
|
456
|
+
: 'bad_response';
|
|
457
|
+
return new TheoremError(kind, err.message, { cause: err });
|
|
458
|
+
}
|
|
459
|
+
/** A body that breaks mid-read arrives as a plain error, not an SDK one. */
|
|
460
|
+
function streamPartError(error) {
|
|
461
|
+
return AISDKError.isInstance(error) || RetryError.isInstance(error)
|
|
462
|
+
? sdkError(error)
|
|
463
|
+
: networkError(error);
|
|
464
|
+
}
|
|
465
|
+
export function providerOptionsFor(req) {
|
|
466
|
+
const openrouter = {};
|
|
467
|
+
if (req.thinking) {
|
|
468
|
+
openrouter.reasoning = { effort: req.thinking };
|
|
469
|
+
}
|
|
470
|
+
const responseFormat = resolveResponseFormat(req.structured);
|
|
471
|
+
if (responseFormat) {
|
|
472
|
+
openrouter.response_format = responseFormat;
|
|
473
|
+
// Route only to endpoints that honour the schema; one that ignores it answers in prose.
|
|
474
|
+
openrouter.provider = { require_parameters: true };
|
|
475
|
+
}
|
|
476
|
+
if (req.cache?.mode === 'automatic') {
|
|
477
|
+
openrouter.cacheControl = cacheControlJson(req.cache);
|
|
478
|
+
}
|
|
479
|
+
if (req.sessionId) {
|
|
480
|
+
openrouter.session_id = req.sessionId;
|
|
481
|
+
}
|
|
482
|
+
if (Object.keys(openrouter).length === 0)
|
|
483
|
+
return undefined;
|
|
484
|
+
return { openrouter };
|
|
485
|
+
}
|
|
486
|
+
export function createOpenRouterProvider(config = {}) {
|
|
487
|
+
return {
|
|
488
|
+
complete: (req) => streamOpenRouter(req, config),
|
|
489
|
+
};
|
|
490
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ModelProvider, ProviderCompleteRequest, ProviderEvent } from '../../kernel/types.js';
|
|
2
|
+
import type { OpenAiGatewayTransport } from '../types.js';
|
|
3
|
+
export declare const OPENROUTER_IMAGE_TOOL = "openrouter:image_generation";
|
|
4
|
+
export type ImageProviderConfig = OpenAiGatewayTransport;
|
|
5
|
+
export declare function buildImageHeaders(apiKey: string, config: ImageProviderConfig): Record<string, string>;
|
|
6
|
+
/** `/images` answers `data[]` of `b64_json` + `media_type` (probe 23/09/2026, bytedance-seed/seedream-4.5). */
|
|
7
|
+
export declare function imagesFromImagesBody(body: Record<string, unknown>): {
|
|
8
|
+
mimeType: string;
|
|
9
|
+
data: string;
|
|
10
|
+
}[];
|
|
11
|
+
/**
|
|
12
|
+
* OpenRouter returns chat images on `message.images[]` as `{ type: 'image_url', image_url: { url } }`
|
|
13
|
+
* with a base64 data url; `message.content` holds only the text (probe 23/09/2026,
|
|
14
|
+
* gemini-3.1-flash-lite with the image generation tool).
|
|
15
|
+
*/
|
|
16
|
+
export declare function imagesFromChatMessage(message: Record<string, unknown>): {
|
|
17
|
+
mimeType: string;
|
|
18
|
+
data: string;
|
|
19
|
+
}[];
|
|
20
|
+
export declare function buildInterleavedChatPayload(req: ProviderCompleteRequest): Record<string, unknown>;
|
|
21
|
+
export declare function yieldInterleavedChat(req: ProviderCompleteRequest, config: ImageProviderConfig, apiKey: string): AsyncGenerator<ProviderEvent>;
|
|
22
|
+
export declare function yieldImagesEndpoint(req: ProviderCompleteRequest, config: ImageProviderConfig, apiKey: string): AsyncGenerator<ProviderEvent>;
|
|
23
|
+
export declare function streamImage(req: ProviderCompleteRequest, config?: ImageProviderConfig): AsyncGenerator<ProviderEvent>;
|
|
24
|
+
export declare function createImageProvider(config?: ImageProviderConfig): ModelProvider;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { TheoremError, toErrorEvent } from '../../guardrails/error.js';
|
|
2
|
+
import { asRecord, nonEmptyString } from '../../kernel/engine/record.js';
|
|
3
|
+
import { turnStopFromOpenAiFinishReason } from '../../kernel/stop.js';
|
|
4
|
+
import { networkFetch } from '../shared/upstream-tap.js';
|
|
5
|
+
import { bearerFetch } from '../shared/vault.js';
|
|
6
|
+
import { buildChatMessages, httpErrorEvent, openAiGatewayHeaders } from './openai/compat.js';
|
|
7
|
+
import { buildImagesPayload, extractPromptText, imageToolParameters, } from './openai/image-payload.js';
|
|
8
|
+
import { openAiUsageTokens } from './openai/usage.js';
|
|
9
|
+
import { resolveOpenAiGatewayApiKey } from './resolve-api-key.js';
|
|
10
|
+
const HTTP_OK = 200;
|
|
11
|
+
export const OPENROUTER_IMAGE_TOOL = 'openrouter:image_generation';
|
|
12
|
+
export function buildImageHeaders(apiKey, config) {
|
|
13
|
+
const headers = {
|
|
14
|
+
Authorization: `Bearer ${apiKey}`,
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
};
|
|
17
|
+
const gateway = openAiGatewayHeaders(config);
|
|
18
|
+
if (gateway) {
|
|
19
|
+
Object.assign(headers, gateway);
|
|
20
|
+
}
|
|
21
|
+
return headers;
|
|
22
|
+
}
|
|
23
|
+
function baseUrl(config) {
|
|
24
|
+
return config.baseUrl?.replace(/\/+$/, '') ?? 'https://openrouter.ai/api/v1';
|
|
25
|
+
}
|
|
26
|
+
function* yieldUsage(raw) {
|
|
27
|
+
const tokens = openAiUsageTokens(raw);
|
|
28
|
+
if (!tokens) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
yield { type: 'tokens', tokens };
|
|
32
|
+
}
|
|
33
|
+
/** `/images` answers `data[]` of `b64_json` + `media_type` (probe 23/09/2026, bytedance-seed/seedream-4.5). */
|
|
34
|
+
export function imagesFromImagesBody(body) {
|
|
35
|
+
const entries = Array.isArray(body.data) ? body.data : [];
|
|
36
|
+
return entries.flatMap((value) => {
|
|
37
|
+
const entry = asRecord(value);
|
|
38
|
+
const data = nonEmptyString(entry?.b64_json);
|
|
39
|
+
const mimeType = nonEmptyString(entry?.media_type);
|
|
40
|
+
return data && mimeType ? [{ mimeType, data }] : [];
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function mediaFromDataUrl(url) {
|
|
44
|
+
if (typeof url !== 'string') {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const match = /^data:([^;,]+);base64,(.+)$/s.exec(url);
|
|
48
|
+
if (!match?.[1] || !match[2]) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return { mimeType: match[1], data: match[2] };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* OpenRouter returns chat images on `message.images[]` as `{ type: 'image_url', image_url: { url } }`
|
|
55
|
+
* with a base64 data url; `message.content` holds only the text (probe 23/09/2026,
|
|
56
|
+
* gemini-3.1-flash-lite with the image generation tool).
|
|
57
|
+
*/
|
|
58
|
+
export function imagesFromChatMessage(message) {
|
|
59
|
+
const images = Array.isArray(message.images) ? message.images : [];
|
|
60
|
+
return images.flatMap((entry) => {
|
|
61
|
+
const media = mediaFromDataUrl(asRecord(asRecord(entry)?.image_url)?.url);
|
|
62
|
+
return media ? [media] : [];
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async function postJson(req, config, apiKey, path, body) {
|
|
66
|
+
const fetchFn = bearerFetch(req, networkFetch(config.fetch ?? fetch), config.vault, apiKey);
|
|
67
|
+
return await fetchFn(`${baseUrl(config)}${path}`, {
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: buildImageHeaders(apiKey, config),
|
|
70
|
+
body: JSON.stringify(body),
|
|
71
|
+
signal: req.signal,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function readTapedJson(req, res) {
|
|
75
|
+
const body = (await res.json());
|
|
76
|
+
req.tapUpstream?.(body);
|
|
77
|
+
return body;
|
|
78
|
+
}
|
|
79
|
+
async function requestImages(req, config, apiKey) {
|
|
80
|
+
return await postJson(req, config, apiKey, '/images', buildImagesPayload(req));
|
|
81
|
+
}
|
|
82
|
+
export function buildInterleavedChatPayload(req) {
|
|
83
|
+
if (!req.image) {
|
|
84
|
+
throw new Error('buildInterleavedChatPayload requires req.image');
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
model: req.apiId,
|
|
88
|
+
stream: false,
|
|
89
|
+
messages: buildChatMessages(req),
|
|
90
|
+
temperature: req.temperature,
|
|
91
|
+
max_tokens: req.maxOutputTokens,
|
|
92
|
+
...(req.thinking ? { reasoning: { effort: req.thinking } } : {}),
|
|
93
|
+
tools: [
|
|
94
|
+
{
|
|
95
|
+
type: OPENROUTER_IMAGE_TOOL,
|
|
96
|
+
parameters: imageToolParameters(req.image),
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function requestInterleavedChat(req, config, apiKey) {
|
|
102
|
+
return await postJson(req, config, apiKey, '/chat/completions', buildInterleavedChatPayload(req));
|
|
103
|
+
}
|
|
104
|
+
export async function* yieldInterleavedChat(req, config, apiKey) {
|
|
105
|
+
const res = await requestInterleavedChat(req, config, apiKey);
|
|
106
|
+
if (res.status !== HTTP_OK) {
|
|
107
|
+
yield await httpErrorEvent(res, 'Image chat');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const body = await readTapedJson(req, res);
|
|
111
|
+
const choices = body.choices;
|
|
112
|
+
if (!Array.isArray(choices) || choices.length === 0) {
|
|
113
|
+
yield toErrorEvent(new TheoremError('bad_response', 'no chat choices returned for image generation'));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const choice = asRecord(choices[0]);
|
|
117
|
+
const message = asRecord(choice?.message);
|
|
118
|
+
if (!message) {
|
|
119
|
+
yield toErrorEvent(new TheoremError('bad_response', 'no assistant message returned for image generation'));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const text = nonEmptyString(message.content);
|
|
123
|
+
if (text) {
|
|
124
|
+
yield { type: 'text', text };
|
|
125
|
+
}
|
|
126
|
+
const images = imagesFromChatMessage(message);
|
|
127
|
+
if (images.length === 0) {
|
|
128
|
+
yield toErrorEvent(new TheoremError('bad_response', 'no image returned from chat image generation'));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
for (const media of images) {
|
|
132
|
+
yield { type: 'media', media };
|
|
133
|
+
}
|
|
134
|
+
yield* yieldUsage(body.usage);
|
|
135
|
+
yield {
|
|
136
|
+
type: 'done',
|
|
137
|
+
stop: turnStopFromOpenAiFinishReason(typeof choice?.finish_reason === 'string' ? choice.finish_reason : undefined, typeof choice?.native_finish_reason === 'string' ? choice.native_finish_reason : undefined),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
export async function* yieldImagesEndpoint(req, config, apiKey) {
|
|
141
|
+
const res = await requestImages(req, config, apiKey);
|
|
142
|
+
if (res.status !== HTTP_OK) {
|
|
143
|
+
yield await httpErrorEvent(res, 'Image');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const body = await readTapedJson(req, res);
|
|
147
|
+
const images = imagesFromImagesBody(body);
|
|
148
|
+
if (images.length === 0) {
|
|
149
|
+
yield toErrorEvent(new TheoremError('bad_response', 'no image returned from image generation'));
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
for (const media of images) {
|
|
153
|
+
yield { type: 'media', media };
|
|
154
|
+
}
|
|
155
|
+
yield* yieldUsage(body.usage);
|
|
156
|
+
// The endpoint answers whole or not at all: a body with images completed.
|
|
157
|
+
yield { type: 'done', stop: { kind: 'completed' } };
|
|
158
|
+
}
|
|
159
|
+
export async function* streamImage(req, config = {}) {
|
|
160
|
+
let apiKey;
|
|
161
|
+
try {
|
|
162
|
+
apiKey = resolveOpenAiGatewayApiKey(config, req.keySlot);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
yield toErrorEvent(err);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (!req.image) {
|
|
169
|
+
yield toErrorEvent(new TheoremError('request', 'missing image response format'));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const prompt = extractPromptText(req.input);
|
|
173
|
+
if (!prompt) {
|
|
174
|
+
yield toErrorEvent(new TheoremError('request', 'empty text for image generation'));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (req.image.includeText) {
|
|
178
|
+
yield* yieldInterleavedChat(req, config, apiKey);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
yield* yieldImagesEndpoint(req, config, apiKey);
|
|
182
|
+
}
|
|
183
|
+
export function createImageProvider(config = {}) {
|
|
184
|
+
return {
|
|
185
|
+
complete: (req) => streamImage(req, config),
|
|
186
|
+
};
|
|
187
|
+
}
|