theorum 0.1.2 → 0.1.4
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 +83 -27
- package/deno.json +57 -0
- package/deno.lock +469 -0
- package/docs/AGENT_PROFILE_CONTRACT.md +45 -18
- package/docs/CLI_SPEC.md +2 -2
- package/docs/SECRETS.md +27 -22
- package/mod.ts +95 -0
- package/package.json +37 -29
- package/src/cli/commands/profile.ts +57 -0
- package/src/cli/commands/run.ts +66 -0
- package/src/cli/commands/test.ts +195 -0
- package/src/cli/index.ts +161 -0
- package/src/cli/matrix/fixtures.ts +96 -0
- package/src/cli/matrix/synthesizer.ts +240 -0
- package/src/guardrails/error.ts +142 -0
- package/src/guardrails/injection.ts +254 -0
- package/src/guardrails/mod.ts +40 -0
- package/src/guardrails/quota.ts +87 -0
- package/src/guardrails/sanitize.ts +165 -0
- package/src/guardrails/sensitive.ts +96 -0
- package/src/host/mint-trace.ts +54 -0
- package/src/host/mod.ts +20 -0
- package/src/host/reply.ts +32 -0
- package/src/kernel/engine/assert.ts +29 -0
- package/src/kernel/engine/boundary.ts +75 -0
- package/src/kernel/engine/delta.ts +440 -0
- package/src/kernel/engine/hash.ts +11 -0
- package/src/kernel/engine/record.ts +8 -0
- package/src/kernel/engine/repair.ts +56 -0
- package/src/kernel/engine/runner/gates.ts +338 -0
- package/src/kernel/engine/runner/mod.ts +135 -0
- package/src/kernel/engine/runner/state.ts +31 -0
- package/src/kernel/engine/runner/steps.ts +183 -0
- package/src/kernel/engine/runner/stream.ts +83 -0
- package/src/kernel/engine/runner/tokens.ts +47 -0
- package/src/kernel/engine/runner/tools.ts +266 -0
- package/src/kernel/engine/runner.ts +7 -0
- package/src/kernel/engine/tree.ts +18 -0
- package/src/kernel/mod.ts +39 -0
- package/src/kernel/registry/attachments.ts +195 -0
- package/src/kernel/registry/catalog.ts +181 -0
- package/src/kernel/registry/ingress.ts +223 -0
- package/src/kernel/registry/profiles.ts +165 -0
- package/src/kernel/registry/provider-request.ts +31 -0
- package/src/kernel/registry/resolve.ts +290 -0
- package/src/kernel/registry/schemas.ts +29 -0
- package/src/kernel/registry/tools.ts +45 -0
- package/src/kernel/registry/vault.ts +26 -0
- package/src/kernel/types.ts +576 -0
- package/{esm/src/observability/mod.js → src/observability/mod.ts} +11 -2
- package/src/observability/spans.ts +70 -0
- package/src/observability/trace-attach.ts +96 -0
- package/src/observability/trace-record.ts +254 -0
- package/src/observability/trace-usage.ts +36 -0
- package/src/observability/trace.ts +143 -0
- package/src/presets/google.ts +147 -0
- package/src/presets/mod.ts +24 -0
- package/src/providers/create-provider.ts +64 -0
- package/src/providers/gemini-tape.ts +59 -0
- package/src/providers/google-tap.ts +57 -0
- package/src/providers/interactions.ts +182 -0
- package/src/providers/keys.ts +182 -0
- package/src/providers/mod.ts +12 -0
- package/src/providers/openrouter-mod.ts +16 -0
- package/src/providers/openrouter-payload.ts +232 -0
- package/src/providers/openrouter.ts +758 -0
- package/src/providers/pcm.ts +37 -0
- package/src/providers/provider.ts +206 -0
- package/src/providers/speech.ts +180 -0
- package/src/providers/sse.ts +59 -0
- package/esm/_dnt.polyfills.d.ts +0 -11
- package/esm/_dnt.polyfills.js +0 -15
- package/esm/_dnt.shims.d.ts +0 -5
- package/esm/_dnt.shims.js +0 -61
- package/esm/mod.d.ts +0 -37
- package/esm/mod.js +0 -35
- package/esm/package.json +0 -3
- package/esm/src/guardrails/error.d.ts +0 -35
- package/esm/src/guardrails/error.js +0 -116
- package/esm/src/guardrails/injection.d.ts +0 -12
- package/esm/src/guardrails/injection.js +0 -220
- package/esm/src/guardrails/keys.d.ts +0 -12
- package/esm/src/guardrails/keys.js +0 -132
- package/esm/src/guardrails/mod.d.ts +0 -14
- package/esm/src/guardrails/mod.js +0 -14
- package/esm/src/guardrails/sanitize.d.ts +0 -22
- package/esm/src/guardrails/sanitize.js +0 -133
- package/esm/src/guardrails/sensitive.d.ts +0 -12
- package/esm/src/guardrails/sensitive.js +0 -88
- package/esm/src/kernel/engine/boundary.d.ts +0 -10
- package/esm/src/kernel/engine/boundary.js +0 -55
- package/esm/src/kernel/engine/delta.d.ts +0 -8
- package/esm/src/kernel/engine/delta.js +0 -362
- package/esm/src/kernel/engine/hash.d.ts +0 -1
- package/esm/src/kernel/engine/hash.js +0 -9
- package/esm/src/kernel/engine/record.d.ts +0 -2
- package/esm/src/kernel/engine/record.js +0 -7
- package/esm/src/kernel/engine/repair.d.ts +0 -9
- package/esm/src/kernel/engine/repair.js +0 -38
- package/esm/src/kernel/engine/runner.d.ts +0 -14
- package/esm/src/kernel/engine/runner.js +0 -731
- package/esm/src/kernel/engine/tree.d.ts +0 -2
- package/esm/src/kernel/engine/tree.js +0 -17
- package/esm/src/kernel/mod.d.ts +0 -16
- package/esm/src/kernel/mod.js +0 -15
- package/esm/src/kernel/registry/catalog.d.ts +0 -24
- package/esm/src/kernel/registry/catalog.js +0 -213
- package/esm/src/kernel/registry/profiles.d.ts +0 -36
- package/esm/src/kernel/registry/profiles.js +0 -111
- package/esm/src/kernel/registry/resolve.d.ts +0 -20
- package/esm/src/kernel/registry/resolve.js +0 -235
- package/esm/src/kernel/registry/schemas.d.ts +0 -14
- package/esm/src/kernel/registry/schemas.js +0 -23
- package/esm/src/kernel/registry/tools.d.ts +0 -12
- package/esm/src/kernel/registry/tools.js +0 -36
- package/esm/src/kernel/types.d.ts +0 -497
- package/esm/src/kernel/types.js +0 -10
- package/esm/src/observability/mod.d.ts +0 -12
- package/esm/src/observability/spans.d.ts +0 -16
- package/esm/src/observability/spans.js +0 -56
- package/esm/src/observability/trace-attach.d.ts +0 -16
- package/esm/src/observability/trace-attach.js +0 -81
- package/esm/src/observability/trace-record.d.ts +0 -112
- package/esm/src/observability/trace-record.js +0 -140
- package/esm/src/observability/trace-usage.d.ts +0 -3
- package/esm/src/observability/trace-usage.js +0 -32
- package/esm/src/observability/trace.d.ts +0 -23
- package/esm/src/observability/trace.js +0 -121
- package/esm/src/providers/attachments.d.ts +0 -17
- package/esm/src/providers/attachments.js +0 -156
- package/esm/src/providers/gemini-tape.d.ts +0 -3
- package/esm/src/providers/gemini-tape.js +0 -46
- package/esm/src/providers/google-tap.d.ts +0 -3
- package/esm/src/providers/google-tap.js +0 -48
- package/esm/src/providers/interactions.d.ts +0 -5
- package/esm/src/providers/interactions.js +0 -127
- package/esm/src/providers/media.d.ts +0 -5
- package/esm/src/providers/media.js +0 -125
- package/esm/src/providers/mod.d.ts +0 -15
- package/esm/src/providers/mod.js +0 -13
- package/esm/src/providers/openrouter-payload.d.ts +0 -24
- package/esm/src/providers/openrouter-payload.js +0 -177
- package/esm/src/providers/openrouter.d.ts +0 -17
- package/esm/src/providers/openrouter.js +0 -332
- package/esm/src/providers/provider.d.ts +0 -13
- package/esm/src/providers/provider.js +0 -123
- package/esm/src/providers/sse.d.ts +0 -7
- package/esm/src/providers/sse.js +0 -53
- package/esm/src/providers/tts.d.ts +0 -24
- package/esm/src/providers/tts.js +0 -144
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter payload builder.
|
|
3
|
+
*
|
|
4
|
+
* Converts THEORUM provider requests into OpenAI-compatible chat completion
|
|
5
|
+
* payloads for OpenRouter and compatible gateways.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { getTool } from '../kernel/registry/catalog.ts';
|
|
11
|
+
import { getStructured } from '../kernel/registry/schemas.ts';
|
|
12
|
+
import type {
|
|
13
|
+
DynamicToolDeclaration,
|
|
14
|
+
InteractionMediaPart,
|
|
15
|
+
InteractionPart,
|
|
16
|
+
ModelId,
|
|
17
|
+
ProviderCompleteRequest,
|
|
18
|
+
StructuredSchemaId,
|
|
19
|
+
ThinkingLevel,
|
|
20
|
+
TurnHistoryMessage,
|
|
21
|
+
} from '../kernel/types.ts';
|
|
22
|
+
|
|
23
|
+
/** Configuration supplied by the host app when creating OpenRouter providers. */
|
|
24
|
+
interface OpenRouterConfig {
|
|
25
|
+
apiKey?: string;
|
|
26
|
+
baseUrl?: string;
|
|
27
|
+
siteUrl?: string;
|
|
28
|
+
siteName?: string;
|
|
29
|
+
fetch?: typeof fetch;
|
|
30
|
+
modelMap?: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Host-owned wire ids used when resolving an OpenRouter model string. */
|
|
34
|
+
interface OpenRouterWireIds {
|
|
35
|
+
apiId?: string;
|
|
36
|
+
openRouterId?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a THEORUM model id to an OpenRouter model string.
|
|
41
|
+
* Prefer `openRouterId` / `apiId` from the profile model spec on the request.
|
|
42
|
+
*/
|
|
43
|
+
function resolveOpenRouterModel(
|
|
44
|
+
modelId: ModelId | string,
|
|
45
|
+
customMap?: Record<string, string>,
|
|
46
|
+
wire?: OpenRouterWireIds,
|
|
47
|
+
): string {
|
|
48
|
+
if (customMap?.[modelId]) {
|
|
49
|
+
return customMap[modelId];
|
|
50
|
+
}
|
|
51
|
+
if (wire?.openRouterId) {
|
|
52
|
+
return wire.openRouterId;
|
|
53
|
+
}
|
|
54
|
+
if (wire?.apiId?.includes('/')) {
|
|
55
|
+
return wire.apiId;
|
|
56
|
+
}
|
|
57
|
+
if (wire?.apiId) {
|
|
58
|
+
return `google/${wire.apiId}`;
|
|
59
|
+
}
|
|
60
|
+
if (String(modelId).includes('/')) {
|
|
61
|
+
return String(modelId);
|
|
62
|
+
}
|
|
63
|
+
return String(modelId);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Map THEORUM thinking level to OpenRouter/OpenAI `reasoning.effort`. */
|
|
67
|
+
function mapThinkingEffort(thinking: ThinkingLevel): ThinkingLevel {
|
|
68
|
+
return thinking;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function wireAudioPart(part: InteractionMediaPart): Record<string, unknown> {
|
|
72
|
+
let format = 'mp3';
|
|
73
|
+
if (part.mimeType.includes('wav')) {
|
|
74
|
+
format = 'wav';
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
type: 'input_audio',
|
|
78
|
+
input_audio: {
|
|
79
|
+
data: part.data,
|
|
80
|
+
format,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function wireMessageContent(parts: InteractionPart[]): unknown {
|
|
86
|
+
const isAllText = parts.every((p) => p.type === 'text');
|
|
87
|
+
if (isAllText) {
|
|
88
|
+
return parts
|
|
89
|
+
.map((p) => {
|
|
90
|
+
if (p.type === 'text') {
|
|
91
|
+
return p.text;
|
|
92
|
+
}
|
|
93
|
+
return '';
|
|
94
|
+
})
|
|
95
|
+
.join('\n');
|
|
96
|
+
}
|
|
97
|
+
return parts.map((part) => {
|
|
98
|
+
if (part.type === 'text') {
|
|
99
|
+
return { type: 'text', text: part.text };
|
|
100
|
+
}
|
|
101
|
+
if (part.type === 'image') {
|
|
102
|
+
return {
|
|
103
|
+
type: 'image_url',
|
|
104
|
+
image_url: { url: `data:${part.mimeType};base64,${part.data}` },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (part.type === 'audio') {
|
|
108
|
+
return wireAudioPart(part);
|
|
109
|
+
}
|
|
110
|
+
return { type: 'text', text: '' };
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function wireHistoryMessage(msg: TurnHistoryMessage): Record<string, unknown> {
|
|
115
|
+
let content: unknown = msg.content ?? '';
|
|
116
|
+
if (msg.parts && msg.parts.length > 0) {
|
|
117
|
+
content = wireMessageContent(msg.parts);
|
|
118
|
+
}
|
|
119
|
+
const wired: Record<string, unknown> = {
|
|
120
|
+
role: msg.role,
|
|
121
|
+
content,
|
|
122
|
+
};
|
|
123
|
+
if (msg.tool_calls && msg.tool_calls.length > 0) {
|
|
124
|
+
wired.tool_calls = msg.tool_calls;
|
|
125
|
+
}
|
|
126
|
+
if (msg.tool_call_id) {
|
|
127
|
+
wired.tool_call_id = msg.tool_call_id;
|
|
128
|
+
}
|
|
129
|
+
if (msg.name) {
|
|
130
|
+
wired.name = msg.name;
|
|
131
|
+
}
|
|
132
|
+
return wired;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function wireTools(dynamicTools?: DynamicToolDeclaration[]): Record<string, unknown>[] {
|
|
136
|
+
if (!dynamicTools || dynamicTools.length === 0) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
return dynamicTools.map((t) => ({
|
|
140
|
+
type: 'function',
|
|
141
|
+
function: {
|
|
142
|
+
name: t.name,
|
|
143
|
+
description: t.description ?? '',
|
|
144
|
+
parameters: t.parameters ?? { type: 'object', properties: {} },
|
|
145
|
+
},
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function buildMessages(req: ProviderCompleteRequest): Record<string, unknown>[] {
|
|
150
|
+
const messages: Record<string, unknown>[] = [];
|
|
151
|
+
if (req.system) {
|
|
152
|
+
messages.push({ role: 'system', content: req.system });
|
|
153
|
+
}
|
|
154
|
+
if (req.history && req.history.length > 0) {
|
|
155
|
+
for (const h of req.history) {
|
|
156
|
+
messages.push(wireHistoryMessage(h));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (req.input.length > 0) {
|
|
160
|
+
messages.push({
|
|
161
|
+
role: 'user',
|
|
162
|
+
content: wireMessageContent(req.input),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return messages;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function resolveResponseFormat(
|
|
169
|
+
structured: StructuredSchemaId | null,
|
|
170
|
+
): Record<string, unknown> | undefined {
|
|
171
|
+
if (!structured) {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
const spec = getStructured(structured);
|
|
175
|
+
if (!spec.jsonSchema) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
type: 'json_schema',
|
|
180
|
+
json_schema: {
|
|
181
|
+
name: String(structured),
|
|
182
|
+
strict: true,
|
|
183
|
+
schema: spec.jsonSchema,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Convert a provider-neutral request into an OpenRouter chat completion payload. */
|
|
189
|
+
function toOpenRouterPayload(
|
|
190
|
+
req: ProviderCompleteRequest,
|
|
191
|
+
config: OpenRouterConfig,
|
|
192
|
+
): Record<string, unknown> {
|
|
193
|
+
const model = resolveOpenRouterModel(req.model, config.modelMap, {
|
|
194
|
+
apiId: req.apiId,
|
|
195
|
+
openRouterId: req.openRouterId,
|
|
196
|
+
});
|
|
197
|
+
const messages = buildMessages(req);
|
|
198
|
+
|
|
199
|
+
const payload: Record<string, unknown> = {
|
|
200
|
+
model,
|
|
201
|
+
stream: true,
|
|
202
|
+
messages,
|
|
203
|
+
temperature: req.temperature,
|
|
204
|
+
max_tokens: req.maxOutputTokens,
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const effort = mapThinkingEffort(req.thinking);
|
|
208
|
+
payload.reasoning = { effort };
|
|
209
|
+
|
|
210
|
+
const responseFormat = resolveResponseFormat(req.structured);
|
|
211
|
+
if (responseFormat) {
|
|
212
|
+
payload.response_format = responseFormat;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const tools = wireTools(req.dynamicTools);
|
|
216
|
+
if (tools.length > 0) {
|
|
217
|
+
payload.tools = tools;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const plugins = req.builtins
|
|
221
|
+
.map((id) => getTool(id)?.openRouterPlugin)
|
|
222
|
+
.filter((id): id is string => Boolean(id))
|
|
223
|
+
.map((id) => ({ id }));
|
|
224
|
+
if (plugins.length > 0) {
|
|
225
|
+
payload.plugins = plugins;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return payload;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export type { OpenRouterConfig, OpenRouterWireIds };
|
|
232
|
+
export { resolveOpenRouterModel, toOpenRouterPayload };
|