theorum 0.1.14 → 1.0.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/README.md +178 -89
- package/esm/mod.d.ts +21 -11
- package/esm/mod.js +15 -8
- package/esm/src/cli/commands/bench.js +6 -3
- package/esm/src/cli/commands/fuzz-canary.d.ts +13 -0
- package/esm/src/cli/commands/fuzz-canary.js +195 -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/profile.js +25 -14
- package/esm/src/cli/commands/run.d.ts +3 -0
- package/esm/src/cli/commands/run.js +22 -30
- package/esm/src/cli/commands/test.d.ts +10 -1
- package/esm/src/cli/commands/test.js +31 -31
- 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 +45 -11
- package/esm/src/cli/matrix/synthesizer.d.ts +7 -9
- package/esm/src/cli/matrix/synthesizer.js +32 -106
- package/esm/src/guardrails/canary-gate.d.ts +20 -0
- package/esm/src/guardrails/canary-gate.js +31 -0
- package/esm/src/guardrails/canary.d.ts +26 -0
- package/esm/src/guardrails/canary.js +139 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +16 -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 +216 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +10 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +124 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +20 -0
- package/esm/src/guardrails/corpus/live-attacks.js +232 -0
- package/esm/src/guardrails/corpus/mod.d.ts +13 -0
- package/esm/src/guardrails/corpus/mod.js +11 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +16 -0
- package/esm/src/guardrails/corpus/secrets.js +16 -0
- package/esm/src/guardrails/corpus/strings.d.ts +27 -0
- package/esm/src/guardrails/corpus/strings.js +33 -0
- package/esm/src/guardrails/corpus/types.d.ts +37 -0
- package/esm/src/guardrails/corpus/types.js +6 -0
- package/esm/src/guardrails/egress.d.ts +9 -0
- package/esm/src/guardrails/egress.js +36 -0
- package/esm/src/guardrails/error.js +6 -4
- package/esm/src/guardrails/injection.js +28 -5
- package/esm/src/guardrails/live-outbound-gate.d.ts +39 -0
- package/esm/src/guardrails/live-outbound-gate.js +180 -0
- package/esm/src/guardrails/mod.d.ts +13 -4
- package/esm/src/guardrails/mod.js +10 -4
- package/esm/src/guardrails/quota.js +1 -1
- package/esm/src/guardrails/sanitize.d.ts +11 -15
- package/esm/src/guardrails/sanitize.js +40 -49
- package/esm/src/guardrails/sensitive.js +2 -1
- package/esm/src/guardrails/testing.d.ts +10 -0
- package/esm/src/guardrails/testing.js +9 -0
- package/esm/src/host/client-turn.d.ts +19 -0
- package/esm/src/host/client-turn.js +32 -0
- package/esm/src/host/mod.d.ts +5 -3
- package/esm/src/host/mod.js +4 -3
- package/esm/src/interface/blocks.d.ts +20 -0
- package/esm/src/interface/blocks.js +180 -0
- package/esm/src/interface/from-profile.d.ts +14 -0
- package/esm/src/interface/from-profile.js +104 -0
- package/esm/src/interface/inputs.d.ts +8 -0
- package/esm/src/interface/inputs.js +127 -0
- package/esm/src/interface/mod.d.ts +10 -0
- package/esm/src/interface/mod.js +9 -0
- package/esm/src/interface/types.d.ts +153 -0
- package/esm/src/interface/types.js +13 -0
- package/esm/src/kernel/engine/delta.d.ts +24 -2
- package/esm/src/kernel/engine/delta.js +519 -29
- package/esm/src/kernel/engine/live-inbound.d.ts +9 -0
- package/esm/src/kernel/engine/live-inbound.js +17 -0
- package/esm/src/kernel/engine/repair.js +1 -1
- package/esm/src/kernel/engine/runner/gates.d.ts +1 -1
- package/esm/src/kernel/engine/runner/gates.js +7 -7
- package/esm/src/kernel/engine/runner/mod.js +13 -13
- package/esm/src/kernel/engine/runner/state.d.ts +7 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +1 -1
- package/esm/src/kernel/engine/runner/steps.js +171 -37
- package/esm/src/kernel/engine/runner/stream.d.ts +1 -2
- package/esm/src/kernel/engine/runner/stream.js +66 -29
- package/esm/src/kernel/engine/session/mod.d.ts +23 -0
- package/esm/src/kernel/engine/session/mod.js +205 -0
- package/esm/src/kernel/mod.d.ts +9 -10
- package/esm/src/kernel/mod.js +6 -8
- package/esm/src/kernel/registry/attachments.d.ts +4 -2
- package/esm/src/kernel/registry/attachments.js +6 -3
- package/esm/src/kernel/registry/catalog.d.ts +3 -16
- package/esm/src/kernel/registry/catalog.js +5 -81
- package/esm/src/kernel/registry/ingress.d.ts +9 -4
- package/esm/src/kernel/registry/ingress.js +73 -63
- package/esm/src/kernel/registry/profiles.d.ts +35 -12
- package/esm/src/kernel/registry/profiles.js +159 -66
- package/esm/src/kernel/registry/provider-request.js +11 -7
- package/esm/src/kernel/registry/resolve.d.ts +5 -6
- package/esm/src/kernel/registry/resolve.js +100 -70
- package/esm/src/kernel/registry/vault.d.ts +12 -7
- package/esm/src/kernel/registry/vault.js +30 -8
- package/esm/src/kernel/schema.d.ts +145 -0
- package/esm/src/kernel/schema.js +462 -0
- package/esm/src/kernel/stop.d.ts +15 -10
- package/esm/src/kernel/stop.js +5 -5
- package/esm/src/kernel/tools/execute.d.ts +45 -0
- package/esm/src/kernel/tools/execute.js +363 -0
- package/esm/src/kernel/tools/harness.d.ts +8 -0
- package/esm/src/kernel/tools/harness.js +44 -0
- package/esm/src/kernel/tools/invoke.d.ts +10 -0
- package/esm/src/kernel/tools/invoke.js +83 -0
- package/esm/src/kernel/tools/mod.d.ts +11 -0
- package/esm/src/kernel/tools/mod.js +10 -0
- package/esm/src/kernel/tools/project.d.ts +12 -0
- package/esm/src/kernel/tools/project.js +34 -0
- package/esm/src/kernel/tools/registry.d.ts +23 -0
- package/esm/src/kernel/tools/registry.js +71 -0
- package/esm/src/kernel/tools/resolve.d.ts +29 -0
- package/esm/src/kernel/tools/resolve.js +262 -0
- package/esm/src/kernel/tools/schema.d.ts +13 -0
- package/esm/src/kernel/tools/schema.js +159 -0
- package/esm/src/kernel/tools/types.d.ts +216 -0
- package/esm/src/kernel/tools/types.js +9 -0
- package/esm/src/kernel/types.d.ts +338 -193
- package/esm/src/observability/trace-attach.d.ts +6 -4
- package/esm/src/observability/trace-attach.js +39 -25
- package/esm/src/observability/trace-record.d.ts +11 -9
- package/esm/src/observability/trace-record.js +36 -23
- 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 +9 -1
- package/esm/src/observability/trace.js +11 -3
- 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 +14 -14
- package/esm/src/providers/create-provider.js +55 -23
- package/esm/src/providers/google/interactions/framing.d.ts +15 -0
- package/esm/src/providers/google/interactions/framing.js +208 -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 +46 -0
- package/esm/src/providers/google/live/framing.js +515 -0
- package/esm/src/providers/google/live/openapi-schema.d.ts +6 -0
- package/esm/src/providers/google/live/openapi-schema.js +45 -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 +36 -0
- package/esm/src/providers/google/live/stream.js +201 -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/chat.d.ts +87 -0
- package/esm/src/providers/{openrouter.js → openrouter/chat.js} +70 -229
- package/esm/src/providers/openrouter/image.d.ts +34 -0
- package/esm/src/providers/openrouter/image.js +286 -0
- package/esm/src/providers/openrouter/openai/chat-payload.d.ts +24 -0
- package/esm/src/providers/openrouter/openai/chat-payload.js +60 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +47 -0
- package/esm/src/providers/openrouter/openai/compat.js +194 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +18 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +84 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +22 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.js +95 -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 -201
- 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 -176
- 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
|
@@ -5,14 +5,19 @@
|
|
|
5
5
|
* Streams SSE from `/v1/chat/completions`, accumulates tool calls, and yields
|
|
6
6
|
* normalized `TurnEvent` objects. No external SDK dependency — raw fetch + SSE.
|
|
7
7
|
*
|
|
8
|
+
* Wire-format message building delegates to the shared `openai/compat` module.
|
|
9
|
+
* SSE parsing delegates to the shared `parseSseStream` from `sse.ts`.
|
|
10
|
+
*
|
|
8
11
|
* Hosts pass `baseUrl` explicitly. THEORUM does not read `OLLAMA_HOST` or other
|
|
9
|
-
* environment variables (see
|
|
12
|
+
* environment variables (see docs/contracts/providers.md).
|
|
10
13
|
*
|
|
11
14
|
* @module
|
|
12
15
|
*/
|
|
13
|
-
import { isAbortError, toErrorEvent } from '
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
+
import { isAbortError, toErrorEvent } from '../../guardrails/error.js';
|
|
17
|
+
import { turnStopFromOpenAiFinishReason } from '../../kernel/stop.js';
|
|
18
|
+
import { buildChatMessages, wireTools } from '../openrouter/openai/compat.js';
|
|
19
|
+
import { parseSseStream } from '../shared/sse.js';
|
|
20
|
+
import { parseToolArgumentsObject } from '../shared/tool-args.js';
|
|
16
21
|
/** Default OpenAI-compat base when the host omits `baseUrl` (Ollama's default port). */
|
|
17
22
|
export const DEFAULT_LOCAL_BASE_URL = 'http://127.0.0.1:11434';
|
|
18
23
|
// ── request mapping ─────────────────────────────────
|
|
@@ -22,132 +27,48 @@ function normalizeBaseUrl(baseUrl) {
|
|
|
22
27
|
end -= 1;
|
|
23
28
|
return baseUrl.slice(0, end);
|
|
24
29
|
}
|
|
25
|
-
function resolveBaseUrl(config) {
|
|
30
|
+
export function resolveBaseUrl(config) {
|
|
26
31
|
return normalizeBaseUrl(config?.baseUrl?.trim() || DEFAULT_LOCAL_BASE_URL);
|
|
27
32
|
}
|
|
28
|
-
function inputToContent(parts) {
|
|
29
|
-
if (parts.every((p) => p.type === 'text')) {
|
|
30
|
-
return parts.map((p) => ('text' in p ? p.text : '')).join('\n');
|
|
31
|
-
}
|
|
32
|
-
return parts.map((p) => {
|
|
33
|
-
if (p.type === 'text')
|
|
34
|
-
return { type: 'text', text: p.text };
|
|
35
|
-
return {
|
|
36
|
-
type: 'image_url',
|
|
37
|
-
image_url: { url: `data:${p.mimeType};base64,${p.data}` },
|
|
38
|
-
};
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
function historyMessageContent(msg) {
|
|
42
|
-
if (msg.parts && msg.parts.length > 0) {
|
|
43
|
-
return inputToContent(msg.parts);
|
|
44
|
-
}
|
|
45
|
-
if (msg.content != null)
|
|
46
|
-
return msg.content;
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
function historyToWire(req) {
|
|
50
|
-
const msgs = [];
|
|
51
|
-
if (req.system)
|
|
52
|
-
msgs.push({ role: 'system', content: req.system });
|
|
53
|
-
for (const msg of req.history ?? []) {
|
|
54
|
-
msgs.push(historyMessageToWire(msg));
|
|
55
|
-
}
|
|
56
|
-
if (req.input.length > 0) {
|
|
57
|
-
msgs.push({ role: 'user', content: inputToContent(req.input) });
|
|
58
|
-
}
|
|
59
|
-
return msgs;
|
|
60
|
-
}
|
|
61
|
-
function historyMessageToWire(msg) {
|
|
62
|
-
if (msg.role === 'tool') {
|
|
63
|
-
return {
|
|
64
|
-
role: 'tool',
|
|
65
|
-
tool_call_id: msg.tool_call_id ?? `call_${msg.name ?? 'tool'}`,
|
|
66
|
-
name: msg.name,
|
|
67
|
-
content: msg.content ?? '',
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
if (msg.role === 'assistant' && msg.tool_calls && msg.tool_calls.length > 0) {
|
|
71
|
-
return {
|
|
72
|
-
role: 'assistant',
|
|
73
|
-
content: historyMessageContent(msg) ?? undefined,
|
|
74
|
-
tool_calls: msg.tool_calls.map((tc) => ({
|
|
75
|
-
id: tc.id,
|
|
76
|
-
type: 'function',
|
|
77
|
-
function: { name: tc.function.name, arguments: tc.function.arguments },
|
|
78
|
-
})),
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return { role: msg.role, content: historyMessageContent(msg) ?? '' };
|
|
82
|
-
}
|
|
83
|
-
function toolsToWire(dynamicTools) {
|
|
84
|
-
if (!dynamicTools || dynamicTools.length === 0)
|
|
85
|
-
return undefined;
|
|
86
|
-
return dynamicTools.map((t) => ({
|
|
87
|
-
type: 'function',
|
|
88
|
-
function: {
|
|
89
|
-
name: t.name,
|
|
90
|
-
description: t.description ?? '',
|
|
91
|
-
parameters: t.parameters ?? { type: 'object', properties: {} },
|
|
92
|
-
},
|
|
93
|
-
}));
|
|
94
|
-
}
|
|
95
33
|
function buildBody(req) {
|
|
96
34
|
const body = {
|
|
97
35
|
model: req.apiId,
|
|
98
|
-
messages:
|
|
36
|
+
messages: buildChatMessages(req),
|
|
99
37
|
stream: true,
|
|
100
38
|
stream_options: { include_usage: true },
|
|
101
39
|
temperature: req.temperature,
|
|
102
40
|
max_tokens: req.maxOutputTokens,
|
|
103
41
|
};
|
|
104
|
-
const tools =
|
|
42
|
+
const tools = wireTools(req.wireTools);
|
|
105
43
|
if (tools)
|
|
106
44
|
body.tools = tools;
|
|
107
45
|
return body;
|
|
108
46
|
}
|
|
109
|
-
// ── SSE parsing ─────────────────────────────────────
|
|
110
|
-
async function* parseSse(body) {
|
|
111
|
-
const reader = body.getReader();
|
|
112
|
-
const decoder = new TextDecoder();
|
|
113
|
-
let buffer = '';
|
|
114
|
-
for (;;) {
|
|
115
|
-
const { done, value } = await reader.read();
|
|
116
|
-
if (done)
|
|
117
|
-
break;
|
|
118
|
-
buffer += decoder.decode(value, { stream: true });
|
|
119
|
-
const lines = buffer.split('\n');
|
|
120
|
-
buffer = lines.pop() ?? '';
|
|
121
|
-
for (const line of lines) {
|
|
122
|
-
const trimmed = line.trim();
|
|
123
|
-
if (!trimmed.startsWith('data: '))
|
|
124
|
-
continue;
|
|
125
|
-
const data = trimmed.slice(6);
|
|
126
|
-
if (data === '[DONE]')
|
|
127
|
-
return;
|
|
128
|
-
try {
|
|
129
|
-
yield JSON.parse(data);
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
// skip malformed
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
47
|
// ── stream → TurnEvent ──────────────────────────────
|
|
138
|
-
function flushPending(pending) {
|
|
48
|
+
export function flushPending(pending) {
|
|
139
49
|
const events = [];
|
|
140
50
|
for (const [, tc] of pending) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
51
|
+
const parsed = parseToolArgumentsObject(tc.args);
|
|
52
|
+
if (!parsed.ok) {
|
|
53
|
+
events.push({
|
|
54
|
+
type: 'tool',
|
|
55
|
+
tool: {
|
|
56
|
+
name: tc.name,
|
|
57
|
+
arguments: {},
|
|
58
|
+
id: tc.id,
|
|
59
|
+
phase: 'error',
|
|
60
|
+
failure: {
|
|
61
|
+
code: 'malformed_arguments',
|
|
62
|
+
message: parsed.error,
|
|
63
|
+
details: { raw: parsed.raw },
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
147
68
|
}
|
|
148
69
|
events.push({
|
|
149
70
|
type: 'tool',
|
|
150
|
-
tool: { name: tc.name, arguments: parsed, id: tc.id },
|
|
71
|
+
tool: { name: tc.name, arguments: parsed.value, id: tc.id },
|
|
151
72
|
});
|
|
152
73
|
}
|
|
153
74
|
pending.clear();
|
|
@@ -174,11 +95,11 @@ async function* streamComplete(baseUrl, req, fetchFn) {
|
|
|
174
95
|
async function* streamOpenAiBody(body) {
|
|
175
96
|
const pending = new Map();
|
|
176
97
|
let finishReason;
|
|
177
|
-
for await (const
|
|
178
|
-
const usageEvent = tokensFromUsage(
|
|
98
|
+
for await (const raw of parseSseStream(body)) {
|
|
99
|
+
const usageEvent = tokensFromUsage(readOpenAiUsage(raw));
|
|
179
100
|
if (usageEvent)
|
|
180
101
|
yield usageEvent;
|
|
181
|
-
const choice =
|
|
102
|
+
const choice = firstOpenAiChoice(raw);
|
|
182
103
|
if (!choice)
|
|
183
104
|
continue;
|
|
184
105
|
yield* eventsFromChoiceDelta(choice.delta, pending);
|
|
@@ -190,7 +111,37 @@ async function* streamOpenAiBody(body) {
|
|
|
190
111
|
}
|
|
191
112
|
for (const event of flushPending(pending))
|
|
192
113
|
yield event;
|
|
193
|
-
yield { type: 'done', stop:
|
|
114
|
+
yield { type: 'done', stop: turnStopFromOpenAiFinishReason(finishReason) };
|
|
115
|
+
}
|
|
116
|
+
function readOpenAiUsage(raw) {
|
|
117
|
+
const usage = raw.usage;
|
|
118
|
+
if (!usage || typeof usage !== 'object' || Array.isArray(usage))
|
|
119
|
+
return undefined;
|
|
120
|
+
const row = usage;
|
|
121
|
+
return {
|
|
122
|
+
prompt_tokens: typeof row.prompt_tokens === 'number' ? row.prompt_tokens : undefined,
|
|
123
|
+
completion_tokens: typeof row.completion_tokens === 'number' ? row.completion_tokens : undefined,
|
|
124
|
+
total_tokens: typeof row.total_tokens === 'number' ? row.total_tokens : undefined,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function firstOpenAiChoice(raw) {
|
|
128
|
+
if (!Array.isArray(raw.choices) || raw.choices.length === 0)
|
|
129
|
+
return undefined;
|
|
130
|
+
const choice = raw.choices[0];
|
|
131
|
+
if (!choice || typeof choice !== 'object' || Array.isArray(choice))
|
|
132
|
+
return undefined;
|
|
133
|
+
const row = choice;
|
|
134
|
+
const deltaRaw = row.delta;
|
|
135
|
+
const delta = deltaRaw && typeof deltaRaw === 'object' && !Array.isArray(deltaRaw)
|
|
136
|
+
? deltaRaw
|
|
137
|
+
: undefined;
|
|
138
|
+
return {
|
|
139
|
+
index: typeof row.index === 'number' ? row.index : 0,
|
|
140
|
+
delta,
|
|
141
|
+
finish_reason: typeof row.finish_reason === 'string' || row.finish_reason === null
|
|
142
|
+
? row.finish_reason
|
|
143
|
+
: undefined,
|
|
144
|
+
};
|
|
194
145
|
}
|
|
195
146
|
function tokensFromUsage(usage) {
|
|
196
147
|
if (!usage)
|
|
@@ -245,15 +196,4 @@ function createLocalProvider(config) {
|
|
|
245
196
|
},
|
|
246
197
|
};
|
|
247
198
|
}
|
|
248
|
-
export { createLocalProvider };
|
|
249
|
-
exposeForTests('local', {
|
|
250
|
-
inputToContent,
|
|
251
|
-
historyMessageContent,
|
|
252
|
-
historyToWire,
|
|
253
|
-
toolsToWire,
|
|
254
|
-
buildBody,
|
|
255
|
-
parseSse,
|
|
256
|
-
flushPending,
|
|
257
|
-
resolveBaseUrl,
|
|
258
|
-
DEFAULT_LOCAL_BASE_URL,
|
|
259
|
-
});
|
|
199
|
+
export { buildChatMessages as historyToWire, createLocalProvider, wireTools as toolsToWire };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct entry for local OpenAI-compat providers (Ollama, vLLM, etc.).
|
|
3
|
+
* Importing this module loads the local adapter graph — prefer `createProvider`
|
|
4
|
+
* when routing from a profile unless you intentionally bypass the factory.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import "../../../_dnt.polyfills.js";
|
|
9
|
+
export { createLocalProvider, DEFAULT_LOCAL_BASE_URL } from './local.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct entry for local OpenAI-compat providers (Ollama, vLLM, etc.).
|
|
3
|
+
* Importing this module loads the local adapter graph — prefer `createProvider`
|
|
4
|
+
* when routing from a profile unless you intentionally bypass the factory.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import "../../../_dnt.polyfills.js";
|
|
9
|
+
export { createLocalProvider, DEFAULT_LOCAL_BASE_URL } from './local.js';
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
* Host apps should use `createProvider(profile, options)` — the single door.
|
|
5
5
|
* Credentials are always supplied by the host application.
|
|
6
6
|
*
|
|
7
|
+
* For direct local adapter access (bypassing the factory), import
|
|
8
|
+
* `@theorum/core/providers/local`.
|
|
9
|
+
*
|
|
7
10
|
* @module
|
|
8
11
|
*/
|
|
9
12
|
import "../../_dnt.polyfills.js";
|
|
13
|
+
export type { KeyVault } from '../kernel/types.js';
|
|
10
14
|
export type { CreateProviderOptions } from './create-provider.js';
|
|
11
15
|
export { createProvider } from './create-provider.js';
|
|
12
|
-
export type { GeminiTransport
|
|
13
|
-
export type { LocalProviderConfig } from './
|
|
14
|
-
export { createLocalProvider, DEFAULT_LOCAL_BASE_URL } from './local.js';
|
|
16
|
+
export type { GeminiTransport } from './google/keys.js';
|
|
17
|
+
export type { LocalProviderConfig, OpenAiGatewayConfig } from './types.js';
|
package/esm/src/providers/mod.js
CHANGED
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* Host apps should use `createProvider(profile, options)` — the single door.
|
|
5
5
|
* Credentials are always supplied by the host application.
|
|
6
6
|
*
|
|
7
|
+
* For direct local adapter access (bypassing the factory), import
|
|
8
|
+
* `@theorum/core/providers/local`.
|
|
9
|
+
*
|
|
7
10
|
* @module
|
|
8
11
|
*/
|
|
9
12
|
import "../../_dnt.polyfills.js";
|
|
10
13
|
export { createProvider } from './create-provider.js';
|
|
11
|
-
export { createLocalProvider, DEFAULT_LOCAL_BASE_URL } from './local.js';
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter provider adapter powered by Vercel AI SDK Core.
|
|
3
|
+
*
|
|
4
|
+
* THEORUM keeps the public `ModelProvider` and `TurnEvent` contract; AI SDK
|
|
5
|
+
* owns the OpenRouter call, stream parsing, provider compatibility, and tool
|
|
6
|
+
* call normalization. Message assembly delegates to `openai/sdk-messages.ts`.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { type TextStreamPart, type ToolSet } from 'ai';
|
|
11
|
+
import type { ModelProvider, ProviderCompleteRequest, TurnEvent, TurnTokens, WireFunctionTool } from '../../kernel/types.js';
|
|
12
|
+
import type { OpenAiGatewayConfig } from '../types.js';
|
|
13
|
+
export interface StreamAccumulator {
|
|
14
|
+
text: string;
|
|
15
|
+
evidenceSeen: boolean;
|
|
16
|
+
emittedTokens: boolean;
|
|
17
|
+
errored: boolean;
|
|
18
|
+
finishReason?: string | null;
|
|
19
|
+
nativeFinishReason?: string | null;
|
|
20
|
+
}
|
|
21
|
+
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
22
|
+
[key: string]: JsonValue;
|
|
23
|
+
};
|
|
24
|
+
export type ProviderOptions = Record<string, {
|
|
25
|
+
[key: string]: JsonValue;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function trimApiKey(explicitKey?: string): string | undefined;
|
|
28
|
+
export declare function createAccumulator(): StreamAccumulator;
|
|
29
|
+
export declare function sourceEvent(part: {
|
|
30
|
+
sourceType?: string;
|
|
31
|
+
title?: string | null;
|
|
32
|
+
url?: string;
|
|
33
|
+
}): TurnEvent;
|
|
34
|
+
export declare function schemaForTool(decl: WireFunctionTool): Record<string, unknown>;
|
|
35
|
+
export declare function buildTools(wireTools?: WireFunctionTool[]): ToolSet | undefined;
|
|
36
|
+
export declare function tokensFromUsage(usage: {
|
|
37
|
+
inputTokens?: number | null;
|
|
38
|
+
outputTokens?: number | null;
|
|
39
|
+
totalTokens?: number | null;
|
|
40
|
+
}): TurnTokens | undefined;
|
|
41
|
+
export declare function rawRecord(value: unknown): Record<string, unknown> | undefined;
|
|
42
|
+
export declare function stringArray(value: unknown): string[] | undefined;
|
|
43
|
+
export declare function metadataRecord(raw: Record<string, unknown>, key: string): Record<string, unknown> | undefined;
|
|
44
|
+
export declare function citationCandidates(raw: Record<string, unknown>): unknown[];
|
|
45
|
+
export declare function nestedCitations(raw: Record<string, unknown>): string[] | undefined;
|
|
46
|
+
export declare function metadataAnnotations(raw: Record<string, unknown>): unknown[] | undefined;
|
|
47
|
+
export declare function evidenceFromMetadata(metadata: unknown, acc: StreamAccumulator): TurnEvent | undefined;
|
|
48
|
+
export declare function toolArguments(input: unknown): Record<string, unknown> | undefined;
|
|
49
|
+
export declare function toolResultData(output: unknown): Record<string, unknown> | undefined;
|
|
50
|
+
export declare function rawThoughtEvent(raw: Record<string, unknown>): TurnEvent | undefined;
|
|
51
|
+
export declare function rawChoiceMessageEvidence(raw: Record<string, unknown>, acc: StreamAccumulator): TurnEvent | undefined;
|
|
52
|
+
export declare function rawEvents(raw: unknown, acc: StreamAccumulator): TurnEvent[];
|
|
53
|
+
export declare function toolCallEvent(part: {
|
|
54
|
+
toolName: string;
|
|
55
|
+
toolCallId: string;
|
|
56
|
+
input?: unknown;
|
|
57
|
+
}): TurnEvent;
|
|
58
|
+
export declare function toolResultEvent(part: {
|
|
59
|
+
toolName: string;
|
|
60
|
+
toolCallId: string;
|
|
61
|
+
input?: unknown;
|
|
62
|
+
output?: unknown;
|
|
63
|
+
}): TurnEvent;
|
|
64
|
+
export declare function tokenEvent(part: {
|
|
65
|
+
totalUsage: {
|
|
66
|
+
inputTokens?: number | null;
|
|
67
|
+
outputTokens?: number | null;
|
|
68
|
+
totalTokens?: number | null;
|
|
69
|
+
};
|
|
70
|
+
}): TurnEvent | undefined;
|
|
71
|
+
export declare function providerMetadataEvent(part: TextStreamPart<ToolSet>, acc: StreamAccumulator): TurnEvent | undefined;
|
|
72
|
+
export declare function eventFromPart(part: TextStreamPart<ToolSet>, acc: StreamAccumulator): TurnEvent[];
|
|
73
|
+
export declare function primaryEventFromPart(part: TextStreamPart<ToolSet>, acc: StreamAccumulator): TurnEvent | undefined;
|
|
74
|
+
export declare function finishEvent(part: {
|
|
75
|
+
finishReason?: string | null;
|
|
76
|
+
totalUsage?: {
|
|
77
|
+
inputTokens?: number | null;
|
|
78
|
+
outputTokens?: number | null;
|
|
79
|
+
totalTokens?: number | null;
|
|
80
|
+
};
|
|
81
|
+
}, acc: StreamAccumulator): TurnEvent | undefined;
|
|
82
|
+
export declare function finalEvents(req: ProviderCompleteRequest, acc: StreamAccumulator): Generator<TurnEvent>;
|
|
83
|
+
export declare function missingOpenRouterKey(): TurnEvent;
|
|
84
|
+
export declare function providerOptionsFor(req: ProviderCompleteRequest): ProviderOptions | undefined;
|
|
85
|
+
/** Create a `ModelProvider` backed by OpenRouter through AI SDK Core. */
|
|
86
|
+
export declare function createOpenRouterProvider(config?: OpenAiGatewayConfig): ModelProvider;
|
|
87
|
+
export type { OpenAiGatewayConfig };
|