theorum 0.1.15 → 1.1.3
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 +241 -98
- package/esm/mod.d.ts +57 -28
- package/esm/mod.js +43 -23
- package/esm/src/cli/commands/bench.js +18 -18
- package/esm/src/cli/commands/fuzz-canary.d.ts +13 -0
- package/esm/src/cli/commands/fuzz-canary.js +191 -0
- package/esm/src/cli/commands/fuzz-guardrails.d.ts +3 -5
- package/esm/src/cli/commands/fuzz-guardrails.js +4 -581
- package/esm/src/cli/commands/guardrails-eval.d.ts +14 -0
- package/esm/src/cli/commands/guardrails-eval.js +15 -0
- package/esm/src/cli/commands/profile.js +35 -15
- package/esm/src/cli/commands/run.d.ts +3 -0
- package/esm/src/cli/commands/run.js +23 -32
- package/esm/src/cli/commands/test.d.ts +10 -1
- package/esm/src/cli/commands/test.js +34 -34
- package/esm/src/cli/event-log.d.ts +19 -0
- package/esm/src/cli/event-log.js +147 -0
- package/esm/src/cli/index.js +57 -11
- package/esm/src/cli/matrix/synthesizer.d.ts +10 -12
- package/esm/src/cli/matrix/synthesizer.js +45 -118
- package/esm/src/guardrails/canary-gate.d.ts +21 -0
- package/esm/src/guardrails/canary-gate.js +32 -0
- package/esm/src/guardrails/canary.d.ts +34 -0
- package/esm/src/guardrails/canary.js +150 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +17 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +151 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +11 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +213 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +10 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +125 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +20 -0
- package/esm/src/guardrails/corpus/live-attacks.js +231 -0
- package/esm/src/guardrails/corpus/mod.d.ts +14 -0
- package/esm/src/guardrails/corpus/mod.js +11 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +17 -0
- package/esm/src/guardrails/corpus/secrets.js +17 -0
- package/esm/src/guardrails/corpus/strings.d.ts +28 -0
- package/esm/src/guardrails/corpus/strings.js +34 -0
- package/esm/src/guardrails/corpus/types.d.ts +38 -0
- package/esm/src/guardrails/corpus/types.js +6 -0
- package/esm/src/guardrails/egress.d.ts +32 -0
- package/esm/src/guardrails/egress.js +87 -0
- package/esm/src/guardrails/error.d.ts +14 -23
- package/esm/src/guardrails/error.js +87 -76
- package/esm/src/guardrails/eval/corpus.d.ts +108 -0
- package/esm/src/guardrails/eval/corpus.js +978 -0
- package/esm/src/guardrails/eval/mod.d.ts +51 -0
- package/esm/src/guardrails/eval/mod.js +133 -0
- package/esm/src/guardrails/eval/score.d.ts +66 -0
- package/esm/src/guardrails/eval/score.js +114 -0
- package/esm/src/guardrails/events.d.ts +25 -0
- package/esm/src/guardrails/events.js +56 -0
- package/esm/src/guardrails/hits.d.ts +24 -0
- package/esm/src/guardrails/hits.js +45 -0
- package/esm/src/guardrails/injection.js +28 -5
- package/esm/src/guardrails/lexicon.d.ts +39 -0
- package/esm/src/guardrails/lexicon.js +200 -0
- package/esm/src/guardrails/live-outbound-gate.d.ts +41 -0
- package/esm/src/guardrails/live-outbound-gate.js +222 -0
- package/esm/src/guardrails/mod.d.ts +30 -6
- package/esm/src/guardrails/mod.js +20 -5
- package/esm/src/guardrails/network.d.ts +19 -0
- package/esm/src/guardrails/network.js +234 -0
- package/esm/src/guardrails/policy.d.ts +35 -0
- package/esm/src/guardrails/policy.js +50 -0
- package/esm/src/guardrails/progressive-yield.d.ts +51 -0
- package/esm/src/guardrails/progressive-yield.js +98 -0
- package/esm/src/guardrails/quota.d.ts +17 -3
- package/esm/src/guardrails/quota.js +18 -4
- package/esm/src/guardrails/sanitize.d.ts +45 -19
- package/esm/src/guardrails/sanitize.js +177 -94
- package/esm/src/guardrails/sensitive.js +2 -1
- package/esm/src/guardrails/serialize.d.ts +35 -0
- package/esm/src/guardrails/serialize.js +58 -0
- package/esm/src/guardrails/testing.d.ts +17 -0
- package/esm/src/guardrails/testing.js +13 -0
- package/esm/src/guardrails/theorum-error.d.ts +12 -0
- package/esm/src/guardrails/theorum-error.js +15 -0
- package/esm/src/guardrails/tool-directives.d.ts +48 -0
- package/esm/src/guardrails/tool-directives.js +124 -0
- package/esm/src/guardrails/tool-result.d.ts +93 -0
- package/esm/src/guardrails/tool-result.js +276 -0
- package/esm/src/guardrails/types.d.ts +291 -0
- package/esm/src/guardrails/types.js +72 -0
- package/esm/src/host/client-turn.d.ts +19 -0
- package/esm/src/host/client-turn.js +36 -0
- package/esm/src/host/mint-trace.d.ts +1 -1
- package/esm/src/host/mod.d.ts +5 -3
- package/esm/src/host/mod.js +4 -3
- package/esm/src/kernel/auth/crypto.d.ts +42 -0
- package/esm/src/kernel/auth/crypto.js +106 -0
- package/esm/src/kernel/auth/mod.d.ts +11 -0
- package/esm/src/kernel/auth/mod.js +11 -0
- package/esm/src/kernel/auth/oauth.d.ts +47 -0
- package/esm/src/kernel/auth/oauth.js +278 -0
- package/esm/src/kernel/auth/types.d.ts +133 -0
- package/esm/src/kernel/auth/types.js +13 -0
- package/esm/src/kernel/engine/delta.d.ts +24 -2
- package/esm/src/kernel/engine/delta.js +478 -39
- package/esm/src/kernel/engine/live-inbound.d.ts +21 -0
- package/esm/src/kernel/engine/live-inbound.js +31 -0
- package/esm/src/kernel/engine/live-ingress.d.ts +19 -0
- package/esm/src/kernel/engine/live-ingress.js +47 -0
- package/esm/src/kernel/engine/repair.js +13 -12
- package/esm/src/kernel/engine/runner/gates.d.ts +1 -1
- package/esm/src/kernel/engine/runner/gates.js +130 -43
- package/esm/src/kernel/engine/runner/mod.d.ts +6 -4
- package/esm/src/kernel/engine/runner/mod.js +192 -53
- package/esm/src/kernel/engine/runner/schema-validation.js +3 -3
- package/esm/src/kernel/engine/runner/stages.d.ts +39 -0
- package/esm/src/kernel/engine/runner/stages.js +89 -0
- package/esm/src/kernel/engine/runner/state.d.ts +31 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +1 -1
- package/esm/src/kernel/engine/runner/steps.js +244 -43
- package/esm/src/kernel/engine/runner/stream.d.ts +9 -3
- package/esm/src/kernel/engine/runner/stream.js +140 -44
- package/esm/src/kernel/engine/session/mod.d.ts +25 -0
- package/esm/src/kernel/engine/session/mod.js +557 -0
- package/esm/src/kernel/interaction-parts.d.ts +14 -0
- package/esm/src/kernel/interaction-parts.js +23 -0
- package/esm/src/kernel/mod.d.ts +21 -10
- package/esm/src/kernel/mod.js +11 -8
- package/esm/src/kernel/profile-graph.d.ts +159 -0
- package/esm/src/kernel/profile-graph.js +156 -0
- package/esm/src/kernel/registry/attachments.d.ts +12 -10
- package/esm/src/kernel/registry/attachments.js +33 -27
- package/esm/src/kernel/registry/catalog.d.ts +25 -24
- package/esm/src/kernel/registry/catalog.js +60 -101
- package/esm/src/kernel/registry/ingress.d.ts +9 -4
- package/esm/src/kernel/registry/ingress.js +97 -75
- package/esm/src/kernel/registry/profile-outputs.d.ts +4 -0
- package/esm/src/kernel/registry/profile-outputs.js +8 -0
- package/esm/src/kernel/registry/profiles.d.ts +55 -12
- package/esm/src/kernel/registry/profiles.js +413 -73
- package/esm/src/kernel/registry/provider-request.js +13 -7
- package/esm/src/kernel/registry/resolve.d.ts +8 -8
- package/esm/src/kernel/registry/resolve.js +169 -154
- package/esm/src/kernel/registry/schemas.js +1 -1
- package/esm/src/kernel/registry/sole-model.d.ts +8 -0
- package/esm/src/kernel/registry/sole-model.js +10 -0
- package/esm/src/kernel/registry/system-prompt.d.ts +10 -0
- package/esm/src/kernel/registry/system-prompt.js +40 -0
- package/esm/src/kernel/registry/system-role.d.ts +8 -0
- package/esm/src/kernel/registry/system-role.js +14 -0
- package/esm/src/kernel/registry/vault.d.ts +12 -7
- package/esm/src/kernel/registry/vault.js +32 -10
- package/esm/src/kernel/schema.d.ts +231 -0
- package/esm/src/kernel/schema.js +607 -0
- package/esm/src/kernel/stages.d.ts +175 -0
- package/esm/src/kernel/stages.js +476 -0
- package/esm/src/kernel/stop.d.ts +78 -19
- package/esm/src/kernel/stop.js +51 -16
- package/esm/src/kernel/tools/events.d.ts +41 -0
- package/esm/src/kernel/tools/events.js +71 -0
- package/esm/src/kernel/tools/execute.d.ts +84 -0
- package/esm/src/kernel/tools/execute.js +614 -0
- package/esm/src/kernel/tools/harness.d.ts +8 -0
- package/esm/src/kernel/tools/harness.js +46 -0
- package/esm/src/kernel/tools/invoke.d.ts +10 -0
- package/esm/src/kernel/tools/invoke.js +101 -0
- package/esm/src/kernel/tools/mod.d.ts +13 -0
- package/esm/src/kernel/tools/mod.js +11 -0
- package/esm/src/kernel/tools/permission.d.ts +15 -0
- package/esm/src/kernel/tools/permission.js +47 -0
- package/esm/src/kernel/tools/project.d.ts +12 -0
- package/esm/src/kernel/tools/project.js +36 -0
- package/esm/src/kernel/tools/registry.d.ts +23 -0
- package/esm/src/kernel/tools/registry.js +81 -0
- package/esm/src/kernel/tools/remote.d.ts +94 -0
- package/esm/src/kernel/tools/remote.js +577 -0
- package/esm/src/kernel/tools/resolve.d.ts +39 -0
- package/esm/src/kernel/tools/resolve.js +283 -0
- package/esm/src/kernel/tools/schema.d.ts +15 -0
- package/esm/src/kernel/tools/schema.js +176 -0
- package/esm/src/kernel/tools/stage-run.d.ts +105 -0
- package/esm/src/kernel/tools/stage-run.js +155 -0
- package/esm/src/kernel/tools/types.d.ts +394 -0
- package/esm/src/kernel/tools/types.js +9 -0
- package/esm/src/kernel/types.d.ts +540 -256
- package/esm/src/kernel/util/find-last.d.ts +2 -0
- package/esm/src/kernel/util/find-last.js +10 -0
- package/esm/src/observability/destinations.d.ts +31 -0
- package/esm/src/observability/destinations.js +67 -0
- package/esm/src/observability/mod.d.ts +10 -3
- package/esm/src/observability/mod.js +6 -2
- package/esm/src/observability/policy.d.ts +27 -0
- package/esm/src/observability/policy.js +80 -0
- package/esm/src/observability/resolve-policy.d.ts +16 -0
- package/esm/src/observability/resolve-policy.js +64 -0
- package/esm/src/observability/trace-attach.d.ts +8 -4
- package/esm/src/observability/trace-attach.js +50 -29
- package/esm/src/observability/trace-record.d.ts +23 -13
- package/esm/src/observability/trace-record.js +96 -39
- package/esm/src/observability/trace-sink.d.ts +19 -0
- package/esm/src/observability/trace-sink.js +10 -0
- package/esm/src/observability/trace-usage.d.ts +10 -3
- package/esm/src/observability/trace-usage.js +70 -17
- package/esm/src/observability/trace.d.ts +18 -7
- package/esm/src/observability/trace.js +34 -17
- package/esm/src/observability/types.d.ts +113 -0
- package/esm/src/observability/types.js +11 -0
- package/esm/src/presets/google/speech-voices.d.ts +11 -0
- package/esm/src/presets/google/speech-voices.js +41 -0
- package/esm/src/presets/google.d.ts +36 -24
- package/esm/src/presets/google.js +50 -63
- package/esm/src/presets/mod.d.ts +2 -2
- package/esm/src/presets/mod.js +1 -1
- package/esm/src/providers/create-provider.d.ts +20 -17
- package/esm/src/providers/create-provider.js +72 -26
- package/esm/src/providers/google/interactions/framing.d.ts +23 -0
- package/esm/src/providers/google/interactions/framing.js +269 -0
- package/esm/src/providers/google/interactions/mod.d.ts +7 -0
- package/esm/src/providers/google/interactions/mod.js +7 -0
- package/esm/src/providers/google/interactions/stream.d.ts +83 -0
- package/esm/src/providers/google/interactions/stream.js +588 -0
- package/esm/src/providers/google/keys.d.ts +26 -0
- package/esm/src/providers/{keys.js → google/keys.js} +19 -31
- package/esm/src/providers/google/live/framing.d.ts +49 -0
- package/esm/src/providers/google/live/framing.js +552 -0
- package/esm/src/providers/google/live/openapi-schema.d.ts +6 -0
- package/esm/src/providers/google/live/openapi-schema.js +46 -0
- package/esm/src/providers/google/live/session.d.ts +25 -0
- package/esm/src/providers/google/live/session.js +134 -0
- package/esm/src/providers/google/live/stream.d.ts +45 -0
- package/esm/src/providers/google/live/stream.js +214 -0
- package/esm/src/providers/google/urls.d.ts +6 -0
- package/esm/src/providers/google/urls.js +6 -0
- package/esm/src/providers/local/local.d.ts +30 -0
- package/esm/src/providers/{local.js → local/local.js} +66 -126
- package/esm/src/providers/local/mod.d.ts +9 -0
- package/esm/src/providers/local/mod.js +9 -0
- package/esm/src/providers/mod.d.ts +6 -3
- package/esm/src/providers/mod.js +3 -1
- package/esm/src/providers/openrouter/cache-control.d.ts +24 -0
- package/esm/src/providers/openrouter/cache-control.js +23 -0
- package/esm/src/providers/openrouter/chat.d.ts +107 -0
- package/esm/src/providers/{openrouter.js → openrouter/chat.js} +117 -231
- package/esm/src/providers/openrouter/image.d.ts +34 -0
- package/esm/src/providers/openrouter/image.js +275 -0
- package/esm/src/providers/openrouter/openai/chat-payload.d.ts +24 -0
- package/esm/src/providers/openrouter/openai/chat-payload.js +82 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +53 -0
- package/esm/src/providers/openrouter/openai/compat.js +213 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +18 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +90 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +22 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.js +122 -0
- package/esm/src/providers/openrouter/resolve-api-key.d.ts +9 -0
- package/esm/src/providers/openrouter/resolve-api-key.js +24 -0
- package/esm/src/providers/openrouter/speech.d.ts +23 -0
- package/esm/src/providers/{speech.js → openrouter/speech.js} +32 -55
- package/esm/src/providers/probe.d.ts +1 -0
- package/esm/src/providers/probe.js +22 -0
- package/esm/src/providers/shared/pcm.d.ts +12 -0
- package/esm/src/providers/{pcm.js → shared/pcm.js} +16 -3
- package/esm/src/providers/shared/sse.d.ts +18 -0
- package/esm/src/providers/shared/sse.js +87 -0
- package/esm/src/providers/shared/tool-args.d.ts +17 -0
- package/esm/src/providers/shared/tool-args.js +45 -0
- package/esm/src/providers/shared/upstream-tap.d.ts +5 -0
- package/esm/src/providers/{google-tap.js → shared/upstream-tap.js} +4 -7
- package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
- package/esm/src/providers/{gemini-tape.js → shared/upstream-tape.js} +12 -22
- package/esm/src/providers/types.d.ts +27 -0
- package/esm/src/providers/types.js +1 -0
- package/package.json +11 -7
- package/docs/cli.md +0 -97
- package/docs/guardrails.md +0 -178
- package/docs/host.md +0 -97
- package/docs/kernel.md +0 -404
- package/docs/observability.md +0 -105
- package/docs/openrouter.md +0 -125
- package/docs/presets-google.md +0 -91
- package/docs/presets.md +0 -88
- package/docs/providers.md +0 -202
- package/docs/streaming.md +0 -96
- package/esm/src/kernel/engine/boundary.d.ts +0 -10
- package/esm/src/kernel/engine/boundary.js +0 -55
- package/esm/src/kernel/engine/runner/tools.d.ts +0 -13
- package/esm/src/kernel/engine/runner/tools.js +0 -198
- package/esm/src/kernel/registry/tools.d.ts +0 -12
- package/esm/src/kernel/registry/tools.js +0 -36
- package/esm/src/providers/expose-for-tests.d.ts +0 -1
- package/esm/src/providers/expose-for-tests.js +0 -25
- package/esm/src/providers/gemini-tape.d.ts +0 -2
- package/esm/src/providers/google-tap.d.ts +0 -3
- package/esm/src/providers/interactions.d.ts +0 -5
- package/esm/src/providers/interactions.js +0 -169
- package/esm/src/providers/keys.d.ts +0 -19
- package/esm/src/providers/local.d.ts +0 -29
- package/esm/src/providers/openrouter-mod.d.ts +0 -13
- package/esm/src/providers/openrouter-mod.js +0 -12
- package/esm/src/providers/openrouter-payload.d.ts +0 -39
- package/esm/src/providers/openrouter-payload.js +0 -195
- package/esm/src/providers/openrouter.d.ts +0 -15
- package/esm/src/providers/pcm.d.ts +0 -7
- package/esm/src/providers/provider.d.ts +0 -15
- package/esm/src/providers/provider.js +0 -202
- package/esm/src/providers/speech.d.ts +0 -23
- package/esm/src/providers/sse.d.ts +0 -7
- package/esm/src/providers/sse.js +0 -55
- package/esm/src/streaming/mod.d.ts +0 -9
- package/esm/src/streaming/mod.js +0 -8
- /package/esm/src/{streaming → host}/readStreamingJsonStringField.d.ts +0 -0
- /package/esm/src/{streaming → host}/readStreamingJsonStringField.js +0 -0
|
@@ -3,25 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* THEORUM keeps the public `ModelProvider` and `TurnEvent` contract; AI SDK
|
|
5
5
|
* owns the OpenRouter call, stream parsing, provider compatibility, and tool
|
|
6
|
-
* call normalization.
|
|
6
|
+
* call normalization. Message assembly delegates to `openai/sdk-messages.ts`.
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
|
|
11
11
|
import { jsonSchema, streamText, tool, } from 'ai';
|
|
12
|
-
import { isAbortError, toErrorEvent } from '
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
12
|
+
import { isAbortError, TheorumError, toErrorEvent } from '../../guardrails/error.js';
|
|
13
|
+
import { extractUsageTokens, parseStructuredOutput } from '../../kernel/engine/delta.js';
|
|
14
|
+
import { turnStopFromOpenAiFinishReason } from '../../kernel/stop.js';
|
|
15
|
+
import { cacheControlJson } from './cache-control.js';
|
|
16
|
+
import { resolveOpenRouterPlugins } from './openai/chat-payload.js';
|
|
17
|
+
import { openAiGatewayHeaders, resolveResponseFormat } from './openai/compat.js';
|
|
18
|
+
import { buildAiSdkMessages } from './openai/sdk-messages.js';
|
|
19
|
+
import { resolveOpenAiGatewayApiKey } from './resolve-api-key.js';
|
|
20
|
+
export function trimApiKey(explicitKey) {
|
|
19
21
|
if (explicitKey?.trim()) {
|
|
20
22
|
return explicitKey.trim();
|
|
21
23
|
}
|
|
22
24
|
return undefined;
|
|
23
25
|
}
|
|
24
|
-
function createAccumulator() {
|
|
26
|
+
export function createAccumulator() {
|
|
25
27
|
return {
|
|
26
28
|
text: '',
|
|
27
29
|
evidenceSeen: false,
|
|
@@ -29,127 +31,35 @@ function createAccumulator() {
|
|
|
29
31
|
errored: false,
|
|
30
32
|
};
|
|
31
33
|
}
|
|
32
|
-
function
|
|
33
|
-
if (part.type === 'text') {
|
|
34
|
-
return { type: 'text', text: part.text };
|
|
35
|
-
}
|
|
36
|
-
if (part.type === 'image') {
|
|
37
|
-
return {
|
|
38
|
-
type: 'image',
|
|
39
|
-
image: `data:${part.mimeType};base64,${part.data}`,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
return { type: 'file', mediaType: part.mimeType, data: part.data };
|
|
43
|
-
}
|
|
44
|
-
function contentFromParts(parts) {
|
|
45
|
-
if (parts.every((part) => part.type === 'text')) {
|
|
46
|
-
return parts
|
|
47
|
-
.map((part) => (part.type === 'text' ? part.text : ''))
|
|
48
|
-
.filter(Boolean)
|
|
49
|
-
.join('\n');
|
|
50
|
-
}
|
|
51
|
-
return parts.map(mediaPart);
|
|
52
|
-
}
|
|
53
|
-
function parseToolInput(raw) {
|
|
54
|
-
try {
|
|
55
|
-
return JSON.parse(raw);
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
return { _raw: raw };
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function stringDefault(value, fallback) {
|
|
62
|
-
return value === undefined ? fallback : value;
|
|
63
|
-
}
|
|
64
|
-
function fallbackToolCallId(name) {
|
|
65
|
-
return `call_${stringDefault(name, 'tool')}`;
|
|
66
|
-
}
|
|
67
|
-
function toolResultContent(msg) {
|
|
68
|
-
const toolName = stringDefault(msg.name, 'tool');
|
|
69
|
-
return {
|
|
70
|
-
role: 'tool',
|
|
71
|
-
content: [
|
|
72
|
-
{
|
|
73
|
-
type: 'tool-result',
|
|
74
|
-
toolCallId: stringDefault(msg.tool_call_id, fallbackToolCallId(msg.name)),
|
|
75
|
-
toolName,
|
|
76
|
-
output: { type: 'text', value: stringDefault(msg.content, '') },
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function assistantToolCallContent(msg) {
|
|
82
|
-
if (!msg.tool_calls || msg.tool_calls.length === 0) {
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
role: 'assistant',
|
|
87
|
-
content: msg.tool_calls.map((call) => ({
|
|
88
|
-
type: 'tool-call',
|
|
89
|
-
toolCallId: call.id,
|
|
90
|
-
toolName: call.function.name,
|
|
91
|
-
input: parseToolInput(call.function.arguments),
|
|
92
|
-
})),
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
function historyMessage(msg) {
|
|
96
|
-
if (msg.role === 'tool') {
|
|
97
|
-
return toolResultContent(msg);
|
|
98
|
-
}
|
|
99
|
-
return assistantToolCallContent(msg) || contentHistoryMessage(msg);
|
|
100
|
-
}
|
|
101
|
-
function contentFromOptionalParts(parts, text) {
|
|
102
|
-
if (!parts || parts.length === 0) {
|
|
103
|
-
return stringDefault(text, '');
|
|
104
|
-
}
|
|
105
|
-
return contentFromParts(parts);
|
|
106
|
-
}
|
|
107
|
-
function contentHistoryMessage(msg) {
|
|
108
|
-
const content = contentFromOptionalParts(msg.parts, msg.content);
|
|
109
|
-
return { role: msg.role, content };
|
|
110
|
-
}
|
|
111
|
-
function sourceEvent(part) {
|
|
34
|
+
export function sourceEvent(part) {
|
|
112
35
|
if (part.sourceType !== 'url') {
|
|
113
36
|
return {
|
|
114
37
|
type: 'evidence',
|
|
115
38
|
evidence: { provider: 'openrouter', raw: part },
|
|
116
39
|
};
|
|
117
40
|
}
|
|
118
|
-
const title = part.title ?? part.url;
|
|
41
|
+
const title = part.title ?? part.url ?? '';
|
|
119
42
|
return {
|
|
120
43
|
type: 'evidence',
|
|
121
44
|
evidence: {
|
|
122
45
|
provider: 'openrouter',
|
|
123
46
|
raw: part,
|
|
124
|
-
citations: [part.url],
|
|
125
|
-
sources: [{ title, uri: part.url, type: 'web' }],
|
|
47
|
+
citations: part.url ? [part.url] : [],
|
|
48
|
+
sources: part.url ? [{ title, uri: part.url, type: 'web' }] : [],
|
|
126
49
|
},
|
|
127
50
|
};
|
|
128
51
|
}
|
|
129
|
-
function
|
|
130
|
-
const messages = [];
|
|
131
|
-
for (const msg of req.history ?? []) {
|
|
132
|
-
const wired = historyMessage(msg);
|
|
133
|
-
if (wired) {
|
|
134
|
-
messages.push(wired);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if (req.input.length > 0) {
|
|
138
|
-
messages.push({ role: 'user', content: contentFromParts(req.input) });
|
|
139
|
-
}
|
|
140
|
-
return messages;
|
|
141
|
-
}
|
|
142
|
-
function schemaForTool(decl) {
|
|
52
|
+
export function schemaForTool(decl) {
|
|
143
53
|
return decl.parameters ?? { type: 'object', properties: {}, additionalProperties: true };
|
|
144
54
|
}
|
|
145
|
-
function buildTools(
|
|
146
|
-
if (!
|
|
55
|
+
export function buildTools(wireTools) {
|
|
56
|
+
if (!wireTools || wireTools.length === 0) {
|
|
147
57
|
return undefined;
|
|
148
58
|
}
|
|
149
59
|
const tools = {};
|
|
150
|
-
for (const decl of
|
|
60
|
+
for (const decl of wireTools) {
|
|
151
61
|
tools[decl.name] = tool({
|
|
152
|
-
description: decl.description
|
|
62
|
+
description: decl.description,
|
|
153
63
|
inputSchema: jsonSchema(schemaForTool(decl)),
|
|
154
64
|
});
|
|
155
65
|
}
|
|
@@ -167,36 +77,44 @@ function openRouterSettings(req) {
|
|
|
167
77
|
settings.web_search_options = {};
|
|
168
78
|
return settings;
|
|
169
79
|
}
|
|
170
|
-
function tokensFromUsage(usage) {
|
|
80
|
+
export function tokensFromUsage(usage) {
|
|
171
81
|
const input = usage.inputTokens ?? 0;
|
|
172
82
|
const output = usage.outputTokens ?? 0;
|
|
173
83
|
const total = usage.totalTokens ?? input + output;
|
|
174
|
-
|
|
84
|
+
const cached = usage.inputTokenDetails?.cacheReadTokens ?? usage.cachedInputTokens ?? undefined;
|
|
85
|
+
const cacheWrite = usage.inputTokenDetails?.cacheWriteTokens ?? undefined;
|
|
86
|
+
if (input === 0 &&
|
|
87
|
+
output === 0 &&
|
|
88
|
+
total === 0 &&
|
|
89
|
+
!(cached && cached > 0) &&
|
|
90
|
+
!(cacheWrite && cacheWrite > 0)) {
|
|
175
91
|
return undefined;
|
|
176
92
|
}
|
|
177
93
|
return {
|
|
178
94
|
input,
|
|
179
95
|
output,
|
|
180
96
|
total,
|
|
97
|
+
...(cached && cached > 0 ? { cached } : {}),
|
|
98
|
+
...(cacheWrite && cacheWrite > 0 ? { cacheWrite } : {}),
|
|
181
99
|
};
|
|
182
100
|
}
|
|
183
|
-
function rawRecord(value) {
|
|
101
|
+
export function rawRecord(value) {
|
|
184
102
|
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
185
103
|
return value;
|
|
186
104
|
}
|
|
187
105
|
return undefined;
|
|
188
106
|
}
|
|
189
|
-
function stringArray(value) {
|
|
107
|
+
export function stringArray(value) {
|
|
190
108
|
if (!Array.isArray(value)) {
|
|
191
109
|
return undefined;
|
|
192
110
|
}
|
|
193
111
|
const out = value.filter((item) => typeof item === 'string');
|
|
194
112
|
return out.length > 0 ? out : undefined;
|
|
195
113
|
}
|
|
196
|
-
function metadataRecord(raw, key) {
|
|
114
|
+
export function metadataRecord(raw, key) {
|
|
197
115
|
return rawRecord(raw[key]);
|
|
198
116
|
}
|
|
199
|
-
function citationCandidates(raw) {
|
|
117
|
+
export function citationCandidates(raw) {
|
|
200
118
|
const openrouter = metadataRecord(raw, 'openrouter') ?? {};
|
|
201
119
|
return [
|
|
202
120
|
raw.citations,
|
|
@@ -207,7 +125,7 @@ function citationCandidates(raw) {
|
|
|
207
125
|
metadataRecord(openrouter, 'provider_metadata')?.citations,
|
|
208
126
|
];
|
|
209
127
|
}
|
|
210
|
-
function nestedCitations(raw) {
|
|
128
|
+
export function nestedCitations(raw) {
|
|
211
129
|
for (const candidate of citationCandidates(raw)) {
|
|
212
130
|
const citations = stringArray(candidate);
|
|
213
131
|
if (citations) {
|
|
@@ -216,7 +134,7 @@ function nestedCitations(raw) {
|
|
|
216
134
|
}
|
|
217
135
|
return undefined;
|
|
218
136
|
}
|
|
219
|
-
function metadataAnnotations(raw) {
|
|
137
|
+
export function metadataAnnotations(raw) {
|
|
220
138
|
const openrouter = metadataRecord(raw, 'openrouter');
|
|
221
139
|
if (Array.isArray(raw.annotations)) {
|
|
222
140
|
return raw.annotations;
|
|
@@ -226,7 +144,7 @@ function metadataAnnotations(raw) {
|
|
|
226
144
|
}
|
|
227
145
|
return undefined;
|
|
228
146
|
}
|
|
229
|
-
function evidenceFromMetadata(metadata, acc) {
|
|
147
|
+
export function evidenceFromMetadata(metadata, acc) {
|
|
230
148
|
const raw = rawRecord(metadata);
|
|
231
149
|
if (!raw || acc.evidenceSeen) {
|
|
232
150
|
return undefined;
|
|
@@ -242,7 +160,7 @@ function evidenceFromMetadata(metadata, acc) {
|
|
|
242
160
|
evidence: { provider: 'openrouter', raw, citations, annotations },
|
|
243
161
|
};
|
|
244
162
|
}
|
|
245
|
-
function toolArguments(input) {
|
|
163
|
+
export function toolArguments(input) {
|
|
246
164
|
if (input && typeof input === 'object' && !Array.isArray(input)) {
|
|
247
165
|
return input;
|
|
248
166
|
}
|
|
@@ -251,10 +169,10 @@ function toolArguments(input) {
|
|
|
251
169
|
}
|
|
252
170
|
return { value: input };
|
|
253
171
|
}
|
|
254
|
-
function toolResultData(output) {
|
|
172
|
+
export function toolResultData(output) {
|
|
255
173
|
return rawRecord(output);
|
|
256
174
|
}
|
|
257
|
-
function rawThoughtEvent(raw) {
|
|
175
|
+
export function rawThoughtEvent(raw) {
|
|
258
176
|
const choices = raw.choices;
|
|
259
177
|
if (!Array.isArray(choices)) {
|
|
260
178
|
return undefined;
|
|
@@ -267,7 +185,7 @@ function rawThoughtEvent(raw) {
|
|
|
267
185
|
}
|
|
268
186
|
return undefined;
|
|
269
187
|
}
|
|
270
|
-
function rawChoiceMessageEvidence(raw, acc) {
|
|
188
|
+
export function rawChoiceMessageEvidence(raw, acc) {
|
|
271
189
|
const choices = raw.choices;
|
|
272
190
|
if (!Array.isArray(choices)) {
|
|
273
191
|
return undefined;
|
|
@@ -284,7 +202,7 @@ function rawChoiceMessageEvidence(raw, acc) {
|
|
|
284
202
|
}
|
|
285
203
|
return undefined;
|
|
286
204
|
}
|
|
287
|
-
function rawEvents(raw, acc) {
|
|
205
|
+
export function rawEvents(raw, acc) {
|
|
288
206
|
const record = rawRecord(raw);
|
|
289
207
|
if (!record) {
|
|
290
208
|
return [];
|
|
@@ -302,6 +220,13 @@ function rawEvents(raw, acc) {
|
|
|
302
220
|
if (messageEvidence) {
|
|
303
221
|
events.push(messageEvidence);
|
|
304
222
|
}
|
|
223
|
+
if (!acc.emittedTokens) {
|
|
224
|
+
const usage = extractUsageTokens(record.usage);
|
|
225
|
+
if (usage) {
|
|
226
|
+
acc.emittedTokens = true;
|
|
227
|
+
events.push({ type: 'tokens', tokens: usage });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
305
230
|
const choices = Array.isArray(record.choices) ? record.choices : [];
|
|
306
231
|
for (const choice of choices) {
|
|
307
232
|
const row = rawRecord(choice);
|
|
@@ -316,7 +241,7 @@ function rawEvents(raw, acc) {
|
|
|
316
241
|
}
|
|
317
242
|
return events;
|
|
318
243
|
}
|
|
319
|
-
function toolCallEvent(part) {
|
|
244
|
+
export function toolCallEvent(part) {
|
|
320
245
|
return {
|
|
321
246
|
type: 'tool',
|
|
322
247
|
tool: {
|
|
@@ -326,32 +251,30 @@ function toolCallEvent(part) {
|
|
|
326
251
|
},
|
|
327
252
|
};
|
|
328
253
|
}
|
|
329
|
-
function toolResultEvent(part) {
|
|
254
|
+
export function toolResultEvent(part) {
|
|
255
|
+
const output = typeof part.output === 'string' ? part.output : toolResultData(part.output);
|
|
330
256
|
return {
|
|
331
257
|
type: 'tool',
|
|
332
258
|
tool: {
|
|
333
259
|
name: part.toolName,
|
|
334
260
|
arguments: toolArguments(part.input),
|
|
335
|
-
result: {
|
|
336
|
-
status: 'ok',
|
|
337
|
-
data: toolResultData(part.output),
|
|
338
|
-
finding: typeof part.output === 'string' ? part.output : undefined,
|
|
339
|
-
},
|
|
340
261
|
id: part.toolCallId,
|
|
262
|
+
phase: 'complete',
|
|
263
|
+
output,
|
|
341
264
|
},
|
|
342
265
|
};
|
|
343
266
|
}
|
|
344
|
-
function tokenEvent(part) {
|
|
267
|
+
export function tokenEvent(part) {
|
|
345
268
|
const tokens = tokensFromUsage(part.totalUsage);
|
|
346
269
|
return tokens ? { type: 'tokens', tokens } : undefined;
|
|
347
270
|
}
|
|
348
|
-
function providerMetadataEvent(part, acc) {
|
|
271
|
+
export function providerMetadataEvent(part, acc) {
|
|
349
272
|
if (!('providerMetadata' in part)) {
|
|
350
273
|
return undefined;
|
|
351
274
|
}
|
|
352
275
|
return evidenceFromMetadata(part.providerMetadata, acc);
|
|
353
276
|
}
|
|
354
|
-
function eventFromPart(part, acc) {
|
|
277
|
+
export function eventFromPart(part, acc) {
|
|
355
278
|
const mapped = primaryEventFromPart(part, acc);
|
|
356
279
|
if (mapped) {
|
|
357
280
|
return [mapped];
|
|
@@ -359,7 +282,7 @@ function eventFromPart(part, acc) {
|
|
|
359
282
|
const evidence = providerMetadataEvent(part, acc);
|
|
360
283
|
return evidence ? [evidence] : [];
|
|
361
284
|
}
|
|
362
|
-
function primaryEventFromPart(part, acc) {
|
|
285
|
+
export function primaryEventFromPart(part, acc) {
|
|
363
286
|
switch (part.type) {
|
|
364
287
|
case 'text-delta':
|
|
365
288
|
acc.text += part.text;
|
|
@@ -385,59 +308,84 @@ function primaryEventFromPart(part, acc) {
|
|
|
385
308
|
return undefined;
|
|
386
309
|
}
|
|
387
310
|
}
|
|
388
|
-
function finishEvent(part, acc) {
|
|
389
|
-
if (
|
|
311
|
+
export function finishEvent(part, acc) {
|
|
312
|
+
if (part.finishReason != null) {
|
|
390
313
|
acc.finishReason = String(part.finishReason);
|
|
391
314
|
}
|
|
392
315
|
if (acc.emittedTokens) {
|
|
393
316
|
return undefined;
|
|
394
317
|
}
|
|
395
|
-
|
|
318
|
+
if (!part.totalUsage) {
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
const event = tokenEvent({ totalUsage: part.totalUsage });
|
|
396
322
|
if (event) {
|
|
397
323
|
acc.emittedTokens = true;
|
|
398
324
|
}
|
|
399
325
|
return event;
|
|
400
326
|
}
|
|
401
|
-
function* finalEvents(req, acc) {
|
|
327
|
+
export function* finalEvents(req, acc) {
|
|
402
328
|
if (acc.errored) {
|
|
403
329
|
return;
|
|
404
330
|
}
|
|
405
331
|
if (req.structured && acc.text) {
|
|
406
|
-
const
|
|
407
|
-
if (
|
|
408
|
-
yield
|
|
332
|
+
const parsed = parseStructuredOutput(acc.text);
|
|
333
|
+
if (!parsed.ok) {
|
|
334
|
+
yield toErrorEvent(new TheorumError(parsed.error));
|
|
335
|
+
return;
|
|
409
336
|
}
|
|
337
|
+
yield { type: 'structured', structured: parsed.structured };
|
|
410
338
|
}
|
|
411
339
|
yield {
|
|
412
340
|
type: 'done',
|
|
413
|
-
stop:
|
|
341
|
+
stop: turnStopFromOpenAiFinishReason(acc.finishReason, acc.nativeFinishReason),
|
|
414
342
|
};
|
|
415
343
|
}
|
|
416
344
|
function createStreamContext(req, config, apiKey) {
|
|
417
345
|
const openrouter = createOpenRouter({
|
|
418
346
|
apiKey,
|
|
419
347
|
baseURL: config.baseUrl,
|
|
420
|
-
headers:
|
|
348
|
+
headers: openAiGatewayHeaders(config),
|
|
421
349
|
fetch: config.fetch,
|
|
422
350
|
compatibility: 'strict',
|
|
423
351
|
});
|
|
424
352
|
return {
|
|
425
353
|
openrouter,
|
|
426
|
-
modelName:
|
|
427
|
-
apiId: req.apiId,
|
|
428
|
-
openRouterId: req.openRouterId,
|
|
429
|
-
}),
|
|
354
|
+
modelName: req.apiId,
|
|
430
355
|
};
|
|
431
356
|
}
|
|
357
|
+
/** System via instructions XOR a cache-marked system message — never both. */
|
|
358
|
+
export function systemDelivery(req) {
|
|
359
|
+
if (!req.system) {
|
|
360
|
+
return {};
|
|
361
|
+
}
|
|
362
|
+
if (req.cache?.mode === 'system') {
|
|
363
|
+
return {
|
|
364
|
+
systemMessage: {
|
|
365
|
+
role: 'system',
|
|
366
|
+
content: req.system,
|
|
367
|
+
providerOptions: {
|
|
368
|
+
openrouter: { cacheControl: cacheControlJson(req.cache) },
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
return { instructions: req.system };
|
|
374
|
+
}
|
|
432
375
|
function streamTextOptions(req, context) {
|
|
376
|
+
const delivery = systemDelivery(req);
|
|
377
|
+
const messages = buildAiSdkMessages(req);
|
|
378
|
+
if (delivery.systemMessage) {
|
|
379
|
+
messages.unshift(delivery.systemMessage);
|
|
380
|
+
}
|
|
433
381
|
return {
|
|
434
382
|
model: context.openrouter.chat(context.modelName, openRouterSettings(req)),
|
|
435
|
-
instructions:
|
|
436
|
-
messages
|
|
383
|
+
instructions: delivery.instructions,
|
|
384
|
+
messages,
|
|
437
385
|
allowSystemInMessages: true,
|
|
438
386
|
temperature: req.temperature,
|
|
439
387
|
maxOutputTokens: req.maxOutputTokens,
|
|
440
|
-
tools: buildTools(req.
|
|
388
|
+
tools: buildTools(req.wireTools),
|
|
441
389
|
providerOptions: providerOptionsFor(req),
|
|
442
390
|
include: { rawChunks: true },
|
|
443
391
|
abortSignal: req.signal,
|
|
@@ -448,7 +396,7 @@ async function* yieldAiSdkStream(req, acc, context) {
|
|
|
448
396
|
const result = streamText(streamTextOptions(req, context));
|
|
449
397
|
for await (const part of result.stream) {
|
|
450
398
|
if (part.type === 'raw') {
|
|
451
|
-
req.
|
|
399
|
+
req.tapUpstream?.(rawRecord(part.rawValue) ?? { rawValue: part.rawValue });
|
|
452
400
|
for (const event of rawEvents(part.rawValue, acc)) {
|
|
453
401
|
yield event;
|
|
454
402
|
}
|
|
@@ -459,13 +407,16 @@ async function* yieldAiSdkStream(req, acc, context) {
|
|
|
459
407
|
}
|
|
460
408
|
}
|
|
461
409
|
}
|
|
462
|
-
function missingOpenRouterKey() {
|
|
410
|
+
export function missingOpenRouterKey() {
|
|
463
411
|
return toErrorEvent('missing OpenRouter API key');
|
|
464
412
|
}
|
|
465
413
|
async function* streamOpenRouter(req, config) {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
414
|
+
let apiKey;
|
|
415
|
+
try {
|
|
416
|
+
apiKey = resolveOpenAiGatewayApiKey(config, req.keySlot);
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
yield toErrorEvent(err);
|
|
469
420
|
return;
|
|
470
421
|
}
|
|
471
422
|
const acc = createAccumulator();
|
|
@@ -481,93 +432,28 @@ async function* streamOpenRouter(req, config) {
|
|
|
481
432
|
yield toErrorEvent(err);
|
|
482
433
|
}
|
|
483
434
|
}
|
|
484
|
-
function
|
|
485
|
-
if (!req.structured)
|
|
486
|
-
return undefined;
|
|
487
|
-
const spec = getStructured(req.structured);
|
|
488
|
-
if (!spec.jsonSchema)
|
|
489
|
-
return undefined;
|
|
490
|
-
return {
|
|
491
|
-
type: 'json_schema',
|
|
492
|
-
json_schema: {
|
|
493
|
-
name: String(req.structured),
|
|
494
|
-
strict: true,
|
|
495
|
-
schema: spec.jsonSchema,
|
|
496
|
-
},
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
function providerOptionsFor(req) {
|
|
435
|
+
export function providerOptionsFor(req) {
|
|
500
436
|
const openrouter = {};
|
|
501
|
-
if (req.thinking !== 'none') {
|
|
437
|
+
if (req.thinking && req.thinking !== 'none') {
|
|
502
438
|
openrouter.reasoning = { effort: req.thinking };
|
|
503
439
|
}
|
|
504
|
-
const responseFormat =
|
|
440
|
+
const responseFormat = resolveResponseFormat(req.structured);
|
|
505
441
|
if (responseFormat) {
|
|
506
442
|
openrouter.response_format = responseFormat;
|
|
507
443
|
}
|
|
444
|
+
if (req.cache?.mode === 'automatic') {
|
|
445
|
+
openrouter.cacheControl = cacheControlJson(req.cache);
|
|
446
|
+
}
|
|
447
|
+
if (req.sessionId) {
|
|
448
|
+
openrouter.session_id = req.sessionId;
|
|
449
|
+
}
|
|
508
450
|
if (Object.keys(openrouter).length === 0)
|
|
509
451
|
return undefined;
|
|
510
452
|
return { openrouter };
|
|
511
453
|
}
|
|
512
|
-
function openRouterHeaders(config) {
|
|
513
|
-
const headers = {};
|
|
514
|
-
if (config.siteUrl) {
|
|
515
|
-
headers['HTTP-Referer'] = config.siteUrl;
|
|
516
|
-
}
|
|
517
|
-
if (config.siteName) {
|
|
518
|
-
headers['X-Title'] = config.siteName;
|
|
519
|
-
}
|
|
520
|
-
return Object.keys(headers).length > 0 ? headers : undefined;
|
|
521
|
-
}
|
|
522
454
|
/** Create a `ModelProvider` backed by OpenRouter through AI SDK Core. */
|
|
523
|
-
function createOpenRouterProvider(config = {}) {
|
|
455
|
+
export function createOpenRouterProvider(config = {}) {
|
|
524
456
|
return {
|
|
525
457
|
complete: (req) => streamOpenRouter(req, config),
|
|
526
458
|
};
|
|
527
459
|
}
|
|
528
|
-
export { createOpenRouterProvider, resolveOpenRouterModel, toOpenRouterPayload };
|
|
529
|
-
exposeForTests('openrouter', {
|
|
530
|
-
trimApiKey,
|
|
531
|
-
createAccumulator,
|
|
532
|
-
mediaPart,
|
|
533
|
-
contentFromParts,
|
|
534
|
-
parseToolInput,
|
|
535
|
-
stringDefault,
|
|
536
|
-
fallbackToolCallId,
|
|
537
|
-
toolResultContent,
|
|
538
|
-
assistantToolCallContent,
|
|
539
|
-
historyMessage,
|
|
540
|
-
contentFromOptionalParts,
|
|
541
|
-
contentHistoryMessage,
|
|
542
|
-
buildMessages,
|
|
543
|
-
schemaForTool,
|
|
544
|
-
buildTools,
|
|
545
|
-
openRouterSettings,
|
|
546
|
-
tokensFromUsage,
|
|
547
|
-
rawRecord,
|
|
548
|
-
stringArray,
|
|
549
|
-
metadataRecord,
|
|
550
|
-
citationCandidates,
|
|
551
|
-
nestedCitations,
|
|
552
|
-
metadataAnnotations,
|
|
553
|
-
evidenceFromMetadata,
|
|
554
|
-
toolArguments,
|
|
555
|
-
toolResultData,
|
|
556
|
-
rawThoughtEvent,
|
|
557
|
-
rawChoiceMessageEvidence,
|
|
558
|
-
rawEvents,
|
|
559
|
-
toolCallEvent,
|
|
560
|
-
toolResultEvent,
|
|
561
|
-
tokenEvent,
|
|
562
|
-
providerMetadataEvent,
|
|
563
|
-
eventFromPart,
|
|
564
|
-
primaryEventFromPart,
|
|
565
|
-
finishEvent,
|
|
566
|
-
sourceEvent,
|
|
567
|
-
finalEvents,
|
|
568
|
-
responseFormatFor,
|
|
569
|
-
providerOptionsFor,
|
|
570
|
-
openRouterHeaders,
|
|
571
|
-
missingOpenRouterKey,
|
|
572
|
-
streamTextOptions,
|
|
573
|
-
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible image generation transport (internal).
|
|
3
|
+
*
|
|
4
|
+
* Hosts use `createProvider(profile, { openAiGateway })` — this module is selected
|
|
5
|
+
* when the profile is an openAi image role on OpenRouter.
|
|
6
|
+
*
|
|
7
|
+
* Image-only turns POST `/images`. When `image.includeText` is set, chat
|
|
8
|
+
* completions carry an OpenRouter image-generation server tool so the model may
|
|
9
|
+
* return interleaved assistant text and images.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import type { ModelProvider, ProviderCompleteRequest, TurnEvent } from '../../kernel/types.js';
|
|
14
|
+
import type { OpenAiGatewayConfig } from '../types.js';
|
|
15
|
+
/** OpenRouter chat server tool for inline image generation. */
|
|
16
|
+
export declare const OPENROUTER_IMAGE_TOOL = "openrouter:image_generation";
|
|
17
|
+
export type ImageProviderConfig = OpenAiGatewayConfig;
|
|
18
|
+
export declare function buildImageHeaders(apiKey: string, config: ImageProviderConfig): Record<string, string>;
|
|
19
|
+
export declare function mediaFromImagesResponse(body: Record<string, unknown>, fallbackMime?: string): {
|
|
20
|
+
mimeType: string;
|
|
21
|
+
data: string;
|
|
22
|
+
} | null;
|
|
23
|
+
export declare function fetchImageAsBase64(url: string, fetchFn: typeof fetch, signal?: AbortSignal): Promise<{
|
|
24
|
+
mimeType: string;
|
|
25
|
+
data: string;
|
|
26
|
+
} | null>;
|
|
27
|
+
export declare function markdownImageUrls(content: string): string[];
|
|
28
|
+
export declare function plainTextFromContent(content: unknown): string;
|
|
29
|
+
export declare function buildInterleavedChatPayload(req: ProviderCompleteRequest): Record<string, unknown>;
|
|
30
|
+
export declare function yieldInterleavedChat(req: ProviderCompleteRequest, config: ImageProviderConfig, apiKey: string): AsyncGenerator<TurnEvent>;
|
|
31
|
+
export declare function yieldImagesEndpoint(req: ProviderCompleteRequest, config: ImageProviderConfig, apiKey: string): AsyncGenerator<TurnEvent>;
|
|
32
|
+
export declare function streamImage(req: ProviderCompleteRequest, config?: ImageProviderConfig): AsyncGenerator<TurnEvent>;
|
|
33
|
+
/** Internal ModelProvider for openAi image roles on OpenRouter. */
|
|
34
|
+
export declare function createImageProvider(config?: ImageProviderConfig): ModelProvider;
|