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
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
import { exposeForTests } from './expose-for-tests.js';
|
|
2
1
|
const SECRET_HEADER = /key|auth|cookie|secret|token/i;
|
|
3
|
-
function tapeHeaderValue(key, value) {
|
|
2
|
+
export function tapeHeaderValue(key, value) {
|
|
4
3
|
if (SECRET_HEADER.test(key)) {
|
|
5
4
|
return '[redacted]';
|
|
6
5
|
}
|
|
7
6
|
return value;
|
|
8
7
|
}
|
|
9
|
-
function tapeHeaders(headers) {
|
|
8
|
+
export function tapeHeaders(headers) {
|
|
10
9
|
const out = {};
|
|
11
10
|
for (const [key, value] of new Headers(headers).entries()) {
|
|
12
11
|
out[key] = tapeHeaderValue(key, value);
|
|
13
12
|
}
|
|
14
13
|
return out;
|
|
15
14
|
}
|
|
16
|
-
function throwRow(err) {
|
|
15
|
+
export function throwRow(err) {
|
|
17
16
|
if (err instanceof Error) {
|
|
18
17
|
return { eventType: 'http_throw', name: err.name, message: err.message };
|
|
19
18
|
}
|
|
20
19
|
return { eventType: 'http_throw', name: 'Error', message: String(err) };
|
|
21
20
|
}
|
|
22
|
-
function tapFetch(tap, send = fetch) {
|
|
21
|
+
export function tapFetch(tap, send = fetch) {
|
|
23
22
|
return async (url, init) => {
|
|
24
23
|
const method = init?.method ?? 'GET';
|
|
25
24
|
tap?.({
|
|
@@ -46,5 +45,3 @@ function tapFetch(tap, send = fetch) {
|
|
|
46
45
|
}
|
|
47
46
|
};
|
|
48
47
|
}
|
|
49
|
-
export { tapFetch };
|
|
50
|
-
exposeForTests('google-tap', { tapeHeaderValue, tapeHeaders, throwRow, tapFetch });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isImageBlob(rec: Record<string, unknown>): boolean;
|
|
2
|
+
export declare function scrubEntry(rec: Record<string, unknown>, key: string, nested: unknown): Promise<[string, unknown]>;
|
|
3
|
+
export declare function scrubRecord(rec: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
4
|
+
export declare function scrubUpstream(value: unknown): Promise<unknown>;
|
|
5
|
+
export declare function redactCanaryInTree(value: unknown, canary: string): unknown;
|
|
6
|
+
export declare function tapeUpstream(value: unknown, canary: string): Promise<unknown>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { OMIT_CANARY } from '
|
|
2
|
-
import { sha256 } from '
|
|
3
|
-
import { mapStrings } from '
|
|
4
|
-
|
|
5
|
-
function isImageBlob(rec) {
|
|
1
|
+
import { OMIT_CANARY } from '../../guardrails/canary.js';
|
|
2
|
+
import { sha256 } from '../../kernel/engine/hash.js';
|
|
3
|
+
import { mapStrings } from '../../kernel/engine/tree.js';
|
|
4
|
+
export function isImageBlob(rec) {
|
|
6
5
|
if (rec.type === 'image' || rec.type === 'media') {
|
|
7
6
|
return true;
|
|
8
7
|
}
|
|
@@ -11,13 +10,13 @@ function isImageBlob(rec) {
|
|
|
11
10
|
}
|
|
12
11
|
return false;
|
|
13
12
|
}
|
|
14
|
-
async function scrubEntry(rec, key, nested) {
|
|
13
|
+
export async function scrubEntry(rec, key, nested) {
|
|
15
14
|
if (key === 'data' && typeof nested === 'string' && isImageBlob(rec)) {
|
|
16
15
|
return [key, await sha256(nested)];
|
|
17
16
|
}
|
|
18
|
-
return [key, await
|
|
17
|
+
return [key, await scrubUpstream(nested)];
|
|
19
18
|
}
|
|
20
|
-
function scrubRecord(rec) {
|
|
19
|
+
export function scrubRecord(rec) {
|
|
21
20
|
return Promise.all(Object.entries(rec).map(([key, nested]) => scrubEntry(rec, key, nested))).then((pairs) => {
|
|
22
21
|
const out = Object.fromEntries(pairs);
|
|
23
22
|
if (typeof rec.data === 'string' && isImageBlob(rec)) {
|
|
@@ -26,30 +25,21 @@ function scrubRecord(rec) {
|
|
|
26
25
|
return out;
|
|
27
26
|
});
|
|
28
27
|
}
|
|
29
|
-
function
|
|
28
|
+
export function scrubUpstream(value) {
|
|
30
29
|
if (Array.isArray(value)) {
|
|
31
|
-
return Promise.all(value.map((item) =>
|
|
30
|
+
return Promise.all(value.map((item) => scrubUpstream(item)));
|
|
32
31
|
}
|
|
33
32
|
if (value && typeof value === 'object') {
|
|
34
33
|
return scrubRecord(value);
|
|
35
34
|
}
|
|
36
35
|
return Promise.resolve(value);
|
|
37
36
|
}
|
|
38
|
-
function redactCanaryInTree(value, canary) {
|
|
37
|
+
export function redactCanaryInTree(value, canary) {
|
|
39
38
|
if (!canary) {
|
|
40
39
|
return value;
|
|
41
40
|
}
|
|
42
41
|
return mapStrings(value, (text) => text.replaceAll(canary, OMIT_CANARY));
|
|
43
42
|
}
|
|
44
|
-
async function
|
|
45
|
-
return redactCanaryInTree(await
|
|
43
|
+
export async function tapeUpstream(value, canary) {
|
|
44
|
+
return redactCanaryInTree(await scrubUpstream(value), canary);
|
|
46
45
|
}
|
|
47
|
-
export { tapeGemini };
|
|
48
|
-
exposeForTests('gemini-tape', {
|
|
49
|
-
isImageBlob,
|
|
50
|
-
scrubEntry,
|
|
51
|
-
scrubRecord,
|
|
52
|
-
scrubGemini,
|
|
53
|
-
redactCanaryInTree,
|
|
54
|
-
tapeGemini,
|
|
55
|
-
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { KeyVault } from '../kernel/types.js';
|
|
2
|
+
/** OpenAI-gateway credentials for `openAi` profiles (OpenRouter or compatible). */
|
|
3
|
+
export interface OpenAiGatewayConfig {
|
|
4
|
+
/**
|
|
5
|
+
* Multi-slot credential vault (same `KEY_SLOTS` shape as Google).
|
|
6
|
+
* When `keySlot` is set on the turn, the adapter reads `vault[keySlot]`.
|
|
7
|
+
*/
|
|
8
|
+
vault?: KeyVault;
|
|
9
|
+
/**
|
|
10
|
+
* Single-key fallback when the profile does not pin `model.key` / `keySlot`.
|
|
11
|
+
* Ignored when `keySlot` is set (vault is required then).
|
|
12
|
+
*/
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
siteUrl?: string;
|
|
16
|
+
siteName?: string;
|
|
17
|
+
fetch?: typeof fetch;
|
|
18
|
+
}
|
|
19
|
+
/** Host-supplied config for the local OpenAI-compat provider. */
|
|
20
|
+
export interface LocalProviderConfig {
|
|
21
|
+
/**
|
|
22
|
+
* Base URL of the OpenAI-compat server (no trailing slash).
|
|
23
|
+
* Defaults to `http://127.0.0.1:11434`.
|
|
24
|
+
*/
|
|
25
|
+
baseUrl?: string;
|
|
26
|
+
fetch?: typeof globalThis.fetch;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "theorum",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A flat TypeScript agent kernel for typed profiles, deterministic turn execution,
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A flat TypeScript agent kernel for typed profiles, deterministic turn execution, registered tools, provider adapters, guardrails, and host-injected traces.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
7
7
|
"ai",
|
|
@@ -29,12 +29,15 @@
|
|
|
29
29
|
"./providers": {
|
|
30
30
|
"import": "./esm/src/providers/mod.js"
|
|
31
31
|
},
|
|
32
|
-
"./
|
|
33
|
-
"import": "./esm/src/providers/
|
|
32
|
+
"./providers/local": {
|
|
33
|
+
"import": "./esm/src/providers/local/mod.js"
|
|
34
34
|
},
|
|
35
35
|
"./guardrails": {
|
|
36
36
|
"import": "./esm/src/guardrails/mod.js"
|
|
37
37
|
},
|
|
38
|
+
"./guardrails/testing": {
|
|
39
|
+
"import": "./esm/src/guardrails/testing.js"
|
|
40
|
+
},
|
|
38
41
|
"./observability": {
|
|
39
42
|
"import": "./esm/src/observability/mod.js"
|
|
40
43
|
},
|
|
@@ -49,9 +52,6 @@
|
|
|
49
52
|
},
|
|
50
53
|
"./presets/google": {
|
|
51
54
|
"import": "./esm/src/presets/google.js"
|
|
52
|
-
},
|
|
53
|
-
"./streaming": {
|
|
54
|
-
"import": "./esm/src/streaming/mod.js"
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
"scripts": {},
|
|
@@ -64,8 +64,12 @@
|
|
|
64
64
|
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
65
65
|
"ai": "^7.0.0",
|
|
66
66
|
"gpt-tokenizer": "^4.0.0",
|
|
67
|
+
"zod": "^4.1.8",
|
|
67
68
|
"@deno/shim-deno": "~0.18.0"
|
|
68
69
|
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"zod": "^4.1.8"
|
|
72
|
+
},
|
|
69
73
|
"devDependencies": {
|
|
70
74
|
"@types/node": "^20.9.0"
|
|
71
75
|
},
|
package/docs/cli.md
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# CLI (`theorum/cli`)
|
|
2
|
-
|
|
3
|
-
Profile inspection and stress-test CLI. On npm this entry is also the
|
|
4
|
-
`theorum` binary. Hosts must register profiles (and providers) in-process
|
|
5
|
-
before commands that execute turns — the CLI does not embed app profiles.
|
|
6
|
-
|
|
7
|
-
## Export
|
|
8
|
-
|
|
9
|
-
| Field | Value |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| Import | `theorum/cli` / `jsr:@theorum/core/cli` |
|
|
12
|
-
| Module | `src/cli/index.ts` |
|
|
13
|
-
| Binary | `theorum` (npm `bin`) |
|
|
14
|
-
|
|
15
|
-
## Ownership
|
|
16
|
-
|
|
17
|
-
| Path | Role |
|
|
18
|
-
| --- | --- |
|
|
19
|
-
| `src/cli/index.ts` | Argument parser + command dispatch |
|
|
20
|
-
| `src/cli/commands/*` | `bench`, `fuzz`, `test`, `run`, `profile` |
|
|
21
|
-
| `src/cli/matrix/*` | Permutation synthesizer + fixtures |
|
|
22
|
-
|
|
23
|
-
## Commands
|
|
24
|
-
|
|
25
|
-
```text
|
|
26
|
-
theorum <command> [options]
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
| Command | Purpose |
|
|
30
|
-
| --- | --- |
|
|
31
|
-
| `bench` | Synthetic kernel performance benchmark (`--chunks`, `--iterations`, `--warmup`) |
|
|
32
|
-
| `fuzz` | Adversarial guardrail fuzzer |
|
|
33
|
-
| `test` | Stress matrix or custom profile tests (`--profile`, `--all`, `--lite`, `--matrix`, `--mode`, `--search`, `--map`) |
|
|
34
|
-
| `run` | Execute a turn with streaming output (`--profile`, `--prompt`, `--mode`, …) |
|
|
35
|
-
| `profile list` / `profile show <id>` | Inspect registered profile blueprints |
|
|
36
|
-
| `help` | Usage |
|
|
37
|
-
|
|
38
|
-
Exit code `1` on failed `test` runs. `run` requires `--profile` (or `-p`).
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
theorum test --profile my.agent --matrix
|
|
42
|
-
theorum run --profile my.agent --prompt "ping"
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Matrix and fixtures
|
|
46
|
-
|
|
47
|
-
| Module | Role |
|
|
48
|
-
| --- | --- |
|
|
49
|
-
| `matrix/synthesizer.ts` | Builds valid permutation cases (modes, optional tools) |
|
|
50
|
-
| `matrix/fixtures.ts` | Shared harness fixtures (not product personas) |
|
|
51
|
-
|
|
52
|
-
The matrix respects profile allowlists — e.g. `--search` only applies when
|
|
53
|
-
`googleSearch` is allowlisted.
|
|
54
|
-
|
|
55
|
-
## Exported API
|
|
56
|
-
|
|
57
|
-
The entry module is the CLI program itself (side-effect main when run as a
|
|
58
|
-
bin). Prefer `deno task theorum` / `npx theorum` over importing commands in
|
|
59
|
-
application code.
|
|
60
|
-
|
|
61
|
-
```theorum-evidence
|
|
62
|
-
{
|
|
63
|
-
"sections": {
|
|
64
|
-
"Export": {
|
|
65
|
-
"supports": [
|
|
66
|
-
{ "kind": "source", "path": "src/cli/index.ts" },
|
|
67
|
-
{ "kind": "config", "path": "package.json" }
|
|
68
|
-
]
|
|
69
|
-
},
|
|
70
|
-
"Ownership": {
|
|
71
|
-
"supports": [
|
|
72
|
-
{ "kind": "source", "path": "src/cli/index.ts" },
|
|
73
|
-
{ "kind": "graph", "path": "docs/_map.mjs" }
|
|
74
|
-
]
|
|
75
|
-
},
|
|
76
|
-
"Commands": {
|
|
77
|
-
"supports": [
|
|
78
|
-
{ "kind": "source", "path": "src/cli/index.ts" },
|
|
79
|
-
{ "kind": "source", "path": "src/cli/commands/run.ts" },
|
|
80
|
-
{ "kind": "contract_test", "path": "tests/cli/cli.test.ts" }
|
|
81
|
-
]
|
|
82
|
-
},
|
|
83
|
-
"Matrix and fixtures": {
|
|
84
|
-
"supports": [
|
|
85
|
-
{ "kind": "source", "path": "src/cli/matrix/synthesizer.ts" },
|
|
86
|
-
{ "kind": "contract_test", "path": "tests/cli/cli.test.ts" }
|
|
87
|
-
]
|
|
88
|
-
},
|
|
89
|
-
"Exported API": {
|
|
90
|
-
"supports": [
|
|
91
|
-
{ "kind": "source", "path": "src/cli/index.ts" },
|
|
92
|
-
{ "kind": "contract_test", "path": "tests/cli/cli.test.ts" }
|
|
93
|
-
]
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
```
|
package/docs/guardrails.md
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
# Guardrails (`theorum/guardrails`)
|
|
2
|
-
|
|
3
|
-
Generic inbound and outbound guardrail primitives. App-specific policy,
|
|
4
|
-
product copy, and channel UX remain host-owned — this entry ships reusable
|
|
5
|
-
detectors, sanitizers, public error mapping, and optional per-day quota slots.
|
|
6
|
-
|
|
7
|
-
## Export
|
|
8
|
-
|
|
9
|
-
| Field | Value |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| Import | `theorum/guardrails` / `jsr:@theorum/core/guardrails` |
|
|
12
|
-
| Module | `src/guardrails/mod.ts` |
|
|
13
|
-
| Also on | Root `theorum` re-exports common error/sanitize/quota helpers |
|
|
14
|
-
|
|
15
|
-
## Ownership
|
|
16
|
-
|
|
17
|
-
Owns every module under `src/guardrails/`.
|
|
18
|
-
|
|
19
|
-
| Module | Role |
|
|
20
|
-
| --- | --- |
|
|
21
|
-
| `error.ts` | `TheorumError`, `publicError`, abort helpers |
|
|
22
|
-
| `sanitize.ts` | Turn + text sanitization |
|
|
23
|
-
| `injection.ts` | Prompt-injection span patterns |
|
|
24
|
-
| `sensitive.ts` | Credential / PII span patterns |
|
|
25
|
-
| `normalize.ts` | Detection normalization |
|
|
26
|
-
| `quota.ts` | In-memory daily slots for HTTP hosts |
|
|
27
|
-
|
|
28
|
-
## Public errors
|
|
29
|
-
|
|
30
|
-
`TheorumError` marks expected contract failures. Never show raw internal
|
|
31
|
-
messages to end users — map through `publicError(err)` (or `toErrorEvent` for
|
|
32
|
-
streams).
|
|
33
|
-
|
|
34
|
-
| Internal marker | Public copy |
|
|
35
|
-
| --- | --- |
|
|
36
|
-
| `UPSTREAM_FAILED` | `PUBLIC_UNAVAILABLE` |
|
|
37
|
-
| `canary leaked` / egress violations | `PUBLIC_CANARY` |
|
|
38
|
-
| Abort | `PUBLIC_CANCELLED` |
|
|
39
|
-
| Tool / MIME / size denials | `PUBLIC_ACTION` / `PUBLIC_FILE_*` |
|
|
40
|
-
|
|
41
|
-
`describeError` returns structured detail for logs. `throwIfAborted(signal)`
|
|
42
|
-
rethrows `AbortError` when a turn should stop early.
|
|
43
|
-
|
|
44
|
-
Exact-message and regex rules live in `error.ts` (`EXACT`, `RULES` arrays) —
|
|
45
|
-
extend there when adding new stable public mappings.
|
|
46
|
-
|
|
47
|
-
## Sanitization
|
|
48
|
-
|
|
49
|
-
Driven by profile `guardrails.sanitizeInput` and `guardrails.redactSensitive`
|
|
50
|
-
(default both on in `sanitizeText` unless overridden).
|
|
51
|
-
|
|
52
|
-
| API | Role |
|
|
53
|
-
| --- | --- |
|
|
54
|
-
| `sanitizeText` | Strip injection + sensitive spans from one string |
|
|
55
|
-
| `sanitizeTurnRequest` | Full turn: text, slots, dynamic tool args, blobs |
|
|
56
|
-
| `sanitizeProjectId` | Bound project id strings (`PROJECT_ID_MAX`) |
|
|
57
|
-
|
|
58
|
-
`injectionSpans` and `sensitiveSpans` return `RedactSpan[]`; `applySpans`
|
|
59
|
-
(from observability) performs replacement. Detection runs on normalized text
|
|
60
|
-
(`normalizeForDetection`).
|
|
61
|
-
|
|
62
|
-
### Injection categories (non-exhaustive)
|
|
63
|
-
|
|
64
|
-
Patterns target untrusted user text before provider submission:
|
|
65
|
-
|
|
66
|
-
- Instruction override (`ignore previous instructions`, `disregard rules`, …)
|
|
67
|
-
- Mode hijack (`developer mode`, `jailbreak`, `DAN`, `do anything now`)
|
|
68
|
-
- Safety bypass (`disable safety filters`, …)
|
|
69
|
-
- Role / delimiter forgery (`<system>`, `[System Message]`, ChatML tokens)
|
|
70
|
-
- Prompt exfiltration (`reveal your system prompt`, …)
|
|
71
|
-
- Multilingual override fragments
|
|
72
|
-
|
|
73
|
-
False-positive tuning belongs in `injection.ts` tests
|
|
74
|
-
(`tests/guardrails/false-positives.test.ts`).
|
|
75
|
-
|
|
76
|
-
## Sensitive data
|
|
77
|
-
|
|
78
|
-
| API | Role |
|
|
79
|
-
| --- | --- |
|
|
80
|
-
| `sensitiveSpans` | Credential / PII span detection |
|
|
81
|
-
| `redactSensitiveOnly` | Model output path without injection patterns |
|
|
82
|
-
|
|
83
|
-
`sensitiveSpans` redacts credential-like and PII patterns from inbound text and,
|
|
84
|
-
when enabled, outbound paths. Use `redactSensitiveOnly` on model output when
|
|
85
|
-
injection patterns should not run.
|
|
86
|
-
|
|
87
|
-
## Quota
|
|
88
|
-
|
|
89
|
-
**Not** enforced inside `runTurn`. HTTP hosts call:
|
|
90
|
-
|
|
91
|
-
```ts
|
|
92
|
-
const ip = clientIp(peer, req);
|
|
93
|
-
if (skipQuota(peer, req)) { /* local dev */ }
|
|
94
|
-
const status = takeSlot(profile, ip, Date.now());
|
|
95
|
-
// 'ok' | 'busy' | 'quota' | 'not_configured'
|
|
96
|
-
try {
|
|
97
|
-
await runTurn(...);
|
|
98
|
-
} finally {
|
|
99
|
-
releaseSlot(profile, ip);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
| Status | Meaning |
|
|
104
|
-
| --- | --- |
|
|
105
|
-
| `ok` | Slot taken; increment daily count |
|
|
106
|
-
| `busy` | Same ip/profile already in flight |
|
|
107
|
-
| `quota` | `perDay` exhausted |
|
|
108
|
-
| `not_configured` | Profile has no `guardrails.quota` |
|
|
109
|
-
|
|
110
|
-
`quotaMessage(profile)` uses `identity.handle` for user-facing limit copy.
|
|
111
|
-
`resetSlots()` clears in-memory state (tests).
|
|
112
|
-
|
|
113
|
-
## Exported API
|
|
114
|
-
|
|
115
|
-
From `src/guardrails/mod.ts`:
|
|
116
|
-
|
|
117
|
-
| Group | Symbols |
|
|
118
|
-
| --- | --- |
|
|
119
|
-
| Public errors | `describeError`, `isAbortError`, `publicError`, `TheorumError`, `throwIfAborted`, `toErrorEvent`, `PUBLIC_ACTION`, `PUBLIC_CANARY`, `PUBLIC_CANCELLED`, `PUBLIC_FILE_COUNT`, `PUBLIC_FILE_SIZE`, `PUBLIC_FILE_TYPE`, `PUBLIC_GENERIC`, `PUBLIC_IMAGE_SIZE`, `PUBLIC_UNAVAILABLE`, `UPSTREAM_FAILED` |
|
|
120
|
-
| Injection / sensitive | `injectionSpans`, `sensitiveSpans` |
|
|
121
|
-
| Quota | `QuotaSlotStatus`, `clientIp`, `quotaMessage`, `releaseSlot`, `resetSlots`, `skipQuota`, `takeSlot` |
|
|
122
|
-
| Sanitize | `PROJECT_ID_MAX`, `sanitizeProjectId`, `sanitizeText`, `sanitizeTurnRequest` |
|
|
123
|
-
|
|
124
|
-
```theorum-evidence
|
|
125
|
-
{
|
|
126
|
-
"sections": {
|
|
127
|
-
"Export": {
|
|
128
|
-
"supports": [
|
|
129
|
-
{ "kind": "source", "path": "src/guardrails/mod.ts" },
|
|
130
|
-
{ "kind": "config", "path": "package.json" }
|
|
131
|
-
]
|
|
132
|
-
},
|
|
133
|
-
"Ownership": {
|
|
134
|
-
"supports": [
|
|
135
|
-
{ "kind": "source", "path": "src/guardrails/mod.ts" },
|
|
136
|
-
{ "kind": "graph", "path": "docs/_map.mjs" }
|
|
137
|
-
]
|
|
138
|
-
},
|
|
139
|
-
"Public errors": {
|
|
140
|
-
"supports": [
|
|
141
|
-
{ "kind": "source", "path": "src/guardrails/error.ts" },
|
|
142
|
-
{ "kind": "contract_test", "path": "tests/guardrails/error.test.ts" }
|
|
143
|
-
]
|
|
144
|
-
},
|
|
145
|
-
"Sanitization": {
|
|
146
|
-
"supports": [
|
|
147
|
-
{ "kind": "source", "path": "src/guardrails/sanitize.ts" },
|
|
148
|
-
{ "kind": "source", "path": "src/guardrails/injection.ts" },
|
|
149
|
-
{ "kind": "contract_test", "path": "tests/guardrails/sanitize.test.ts" }
|
|
150
|
-
]
|
|
151
|
-
},
|
|
152
|
-
"Injection categories (non-exhaustive)": {
|
|
153
|
-
"supports": [
|
|
154
|
-
{ "kind": "source", "path": "src/guardrails/injection.ts" },
|
|
155
|
-
{ "kind": "contract_test", "path": "tests/guardrails/false-positives.test.ts" }
|
|
156
|
-
]
|
|
157
|
-
},
|
|
158
|
-
"Sensitive data": {
|
|
159
|
-
"supports": [
|
|
160
|
-
{ "kind": "source", "path": "src/guardrails/sensitive.ts" },
|
|
161
|
-
{ "kind": "contract_test", "path": "tests/guardrails/sanitize.test.ts" }
|
|
162
|
-
]
|
|
163
|
-
},
|
|
164
|
-
"Quota": {
|
|
165
|
-
"supports": [
|
|
166
|
-
{ "kind": "source", "path": "src/guardrails/quota.ts" },
|
|
167
|
-
{ "kind": "contract_test", "path": "tests/guardrails/quota.test.ts" }
|
|
168
|
-
]
|
|
169
|
-
},
|
|
170
|
-
"Exported API": {
|
|
171
|
-
"supports": [
|
|
172
|
-
{ "kind": "source", "path": "src/guardrails/mod.ts" },
|
|
173
|
-
{ "kind": "contract_test", "path": "tests/guardrails/error.test.ts" }
|
|
174
|
-
]
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
```
|
package/docs/host.md
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# Host (`theorum/host`)
|
|
2
|
-
|
|
3
|
-
Optional Deno HTTP helpers for host applications. **Not** part of the turn
|
|
4
|
-
kernel — import only when you want shared reply/status glue and cutout-trace
|
|
5
|
-
flushing without reimplementing it per route.
|
|
6
|
-
|
|
7
|
-
## Export
|
|
8
|
-
|
|
9
|
-
| Field | Value |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| Import | `theorum/host` / `jsr:@theorum/core/host` |
|
|
12
|
-
| Module | `src/host/mod.ts` |
|
|
13
|
-
|
|
14
|
-
## Ownership
|
|
15
|
-
|
|
16
|
-
| Path | Role |
|
|
17
|
-
| --- | --- |
|
|
18
|
-
| `src/host/reply.ts` | JSON responses + HTTP status constants |
|
|
19
|
-
| `src/host/mint-trace.ts` | Cutout mint trace flush helpers |
|
|
20
|
-
| `src/host/mod.ts` | Public barrel |
|
|
21
|
-
|
|
22
|
-
## HTTP replies
|
|
23
|
-
|
|
24
|
-
| Export | Role |
|
|
25
|
-
| --- | --- |
|
|
26
|
-
| `json(status, body, cors)` | JSON `Response` with merged CORS headers |
|
|
27
|
-
| `caughtStatus(err)` | `400` for `TheorumError`, else `500` |
|
|
28
|
-
| `HTTP_OK` | `200` |
|
|
29
|
-
| `HTTP_BUSY` | `429` |
|
|
30
|
-
| `HTTP_NOT_FOUND` | `404` |
|
|
31
|
-
| `HTTP_METHOD` | `405` |
|
|
32
|
-
|
|
33
|
-
Example:
|
|
34
|
-
|
|
35
|
-
```ts
|
|
36
|
-
import { caughtStatus, HTTP_BUSY, json } from "theorum/host";
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
return json(200, { ok: true }, cors);
|
|
40
|
-
} catch (err) {
|
|
41
|
-
return json(caughtStatus(err), { error: publicError(err) }, cors);
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Quota busy responses typically use `HTTP_BUSY` after `takeSlot` returns `busy`.
|
|
46
|
-
|
|
47
|
-
## Cutout mint trace
|
|
48
|
-
|
|
49
|
-
| Export | Role |
|
|
50
|
-
| --- | --- |
|
|
51
|
-
| `flushMintTrace` | Flush pending cutout mint records after a turn |
|
|
52
|
-
| `CutoutTape` | Tape type for mint/cutout correlation |
|
|
53
|
-
|
|
54
|
-
Use when your Deno HTTP host records mint/cutout telemetry alongside THEORUM
|
|
55
|
-
turns. Skip entirely for non-HTTP or non-Deno hosts.
|
|
56
|
-
|
|
57
|
-
## Exported API
|
|
58
|
-
|
|
59
|
-
Live list: `src/host/mod.ts` (`json`, status constants, `caughtStatus`,
|
|
60
|
-
`flushMintTrace`, `CutoutTape`).
|
|
61
|
-
|
|
62
|
-
```theorum-evidence
|
|
63
|
-
{
|
|
64
|
-
"sections": {
|
|
65
|
-
"Export": {
|
|
66
|
-
"supports": [
|
|
67
|
-
{ "kind": "source", "path": "src/host/mod.ts" },
|
|
68
|
-
{ "kind": "config", "path": "package.json" }
|
|
69
|
-
]
|
|
70
|
-
},
|
|
71
|
-
"Ownership": {
|
|
72
|
-
"supports": [
|
|
73
|
-
{ "kind": "source", "path": "src/host/mod.ts" },
|
|
74
|
-
{ "kind": "graph", "path": "docs/_map.mjs" }
|
|
75
|
-
]
|
|
76
|
-
},
|
|
77
|
-
"HTTP replies": {
|
|
78
|
-
"supports": [
|
|
79
|
-
{ "kind": "source", "path": "src/host/reply.ts" },
|
|
80
|
-
{ "kind": "contract_test", "path": "tests/host/host.test.ts" }
|
|
81
|
-
]
|
|
82
|
-
},
|
|
83
|
-
"Cutout mint trace": {
|
|
84
|
-
"supports": [
|
|
85
|
-
{ "kind": "source", "path": "src/host/mint-trace.ts" },
|
|
86
|
-
{ "kind": "contract_test", "path": "tests/host/host.test.ts" }
|
|
87
|
-
]
|
|
88
|
-
},
|
|
89
|
-
"Exported API": {
|
|
90
|
-
"supports": [
|
|
91
|
-
{ "kind": "source", "path": "src/host/mod.ts" },
|
|
92
|
-
{ "kind": "contract_test", "path": "tests/host/host.test.ts" }
|
|
93
|
-
]
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
```
|