@rarebit-one/harness-kernel 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +286 -0
- package/dist/agent.d.ts +71 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +258 -0
- package/dist/agent.js.map +1 -0
- package/dist/connectors/mcpClient.d.ts +22 -0
- package/dist/connectors/mcpClient.d.ts.map +1 -0
- package/dist/connectors/mcpClient.js +63 -0
- package/dist/connectors/mcpClient.js.map +1 -0
- package/dist/context/types.d.ts +68 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +43 -0
- package/dist/context/types.js.map +1 -0
- package/dist/engines/capability.d.ts +67 -0
- package/dist/engines/capability.d.ts.map +1 -0
- package/dist/engines/capability.js +73 -0
- package/dist/engines/capability.js.map +1 -0
- package/dist/engines/capabilityEmissions.d.ts +27 -0
- package/dist/engines/capabilityEmissions.d.ts.map +1 -0
- package/dist/engines/capabilityEmissions.js +37 -0
- package/dist/engines/capabilityEmissions.js.map +1 -0
- package/dist/engines/capabilityMcp.d.ts +23 -0
- package/dist/engines/capabilityMcp.d.ts.map +1 -0
- package/dist/engines/capabilityMcp.js +36 -0
- package/dist/engines/capabilityMcp.js.map +1 -0
- package/dist/engines/capabilityStdio.d.ts +46 -0
- package/dist/engines/capabilityStdio.d.ts.map +1 -0
- package/dist/engines/capabilityStdio.js +39 -0
- package/dist/engines/capabilityStdio.js.map +1 -0
- package/dist/engines/claudeCode.d.ts +73 -0
- package/dist/engines/claudeCode.d.ts.map +1 -0
- package/dist/engines/claudeCode.js +100 -0
- package/dist/engines/claudeCode.js.map +1 -0
- package/dist/engines/claudeCodeDriver.d.ts +14 -0
- package/dist/engines/claudeCodeDriver.d.ts.map +1 -0
- package/dist/engines/claudeCodeDriver.js +90 -0
- package/dist/engines/claudeCodeDriver.js.map +1 -0
- package/dist/engines/codex.d.ts +72 -0
- package/dist/engines/codex.d.ts.map +1 -0
- package/dist/engines/codex.js +157 -0
- package/dist/engines/codex.js.map +1 -0
- package/dist/engines/codexDriver.d.ts +43 -0
- package/dist/engines/codexDriver.d.ts.map +1 -0
- package/dist/engines/codexDriver.js +110 -0
- package/dist/engines/codexDriver.js.map +1 -0
- package/dist/engines/connectorMcp.d.ts +60 -0
- package/dist/engines/connectorMcp.d.ts.map +1 -0
- package/dist/engines/connectorMcp.js +137 -0
- package/dist/engines/connectorMcp.js.map +1 -0
- package/dist/engines/index.d.ts +33 -0
- package/dist/engines/index.d.ts.map +1 -0
- package/dist/engines/index.js +29 -0
- package/dist/engines/index.js.map +1 -0
- package/dist/engines/native.d.ts +55 -0
- package/dist/engines/native.d.ts.map +1 -0
- package/dist/engines/native.js +117 -0
- package/dist/engines/native.js.map +1 -0
- package/dist/engines/types.d.ts +107 -0
- package/dist/engines/types.d.ts.map +1 -0
- package/dist/engines/types.js +2 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/events.d.ts +211 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +69 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/loop.d.ts +132 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +77 -0
- package/dist/loop.js.map +1 -0
- package/dist/models/chat.d.ts +65 -0
- package/dist/models/chat.d.ts.map +1 -0
- package/dist/models/chat.js +66 -0
- package/dist/models/chat.js.map +1 -0
- package/dist/models/middleware.d.ts +63 -0
- package/dist/models/middleware.d.ts.map +1 -0
- package/dist/models/middleware.js +139 -0
- package/dist/models/middleware.js.map +1 -0
- package/dist/models/registry.d.ts +78 -0
- package/dist/models/registry.d.ts.map +1 -0
- package/dist/models/registry.js +0 -0
- package/dist/models/registry.js.map +1 -0
- package/dist/models/types.d.ts +149 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +64 -0
- package/dist/models/types.js.map +1 -0
- package/dist/primitives/codeExec.d.ts +25 -0
- package/dist/primitives/codeExec.d.ts.map +1 -0
- package/dist/primitives/codeExec.js +69 -0
- package/dist/primitives/codeExec.js.map +1 -0
- package/dist/primitives/download.d.ts +19 -0
- package/dist/primitives/download.d.ts.map +1 -0
- package/dist/primitives/download.js +113 -0
- package/dist/primitives/download.js.map +1 -0
- package/dist/primitives/fs.d.ts +5 -0
- package/dist/primitives/fs.d.ts.map +1 -0
- package/dist/primitives/fs.js +59 -0
- package/dist/primitives/fs.js.map +1 -0
- package/dist/primitives/http.d.ts +100 -0
- package/dist/primitives/http.d.ts.map +1 -0
- package/dist/primitives/http.js +257 -0
- package/dist/primitives/http.js.map +1 -0
- package/dist/providers/anthropic.d.ts +15 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +90 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/clientOptions.d.ts +14 -0
- package/dist/providers/clientOptions.d.ts.map +1 -0
- package/dist/providers/clientOptions.js +26 -0
- package/dist/providers/clientOptions.js.map +1 -0
- package/dist/providers/index.d.ts +24 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +51 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/mock.d.ts +25 -0
- package/dist/providers/mock.d.ts.map +1 -0
- package/dist/providers/mock.js +85 -0
- package/dist/providers/mock.js.map +1 -0
- package/dist/providers/openai.d.ts +32 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +118 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/openrouter.d.ts +29 -0
- package/dist/providers/openrouter.d.ts.map +1 -0
- package/dist/providers/openrouter.js +35 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/providers/types.d.ts +60 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/routing/staticResolver.d.ts +41 -0
- package/dist/routing/staticResolver.d.ts.map +1 -0
- package/dist/routing/staticResolver.js +67 -0
- package/dist/routing/staticResolver.js.map +1 -0
- package/dist/routing/types.d.ts +72 -0
- package/dist/routing/types.d.ts.map +1 -0
- package/dist/routing/types.js +11 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/secrets.d.ts +8 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +14 -0
- package/dist/secrets.js.map +1 -0
- package/dist/tools/metadata.d.ts +93 -0
- package/dist/tools/metadata.d.ts.map +1 -0
- package/dist/tools/metadata.js +49 -0
- package/dist/tools/metadata.js.map +1 -0
- package/dist/tools/modelTool.d.ts +35 -0
- package/dist/tools/modelTool.d.ts.map +1 -0
- package/dist/tools/modelTool.js +37 -0
- package/dist/tools/modelTool.js.map +1 -0
- package/dist/tools/registry.d.ts +65 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +166 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CompletionRequest, ConverseRequest, ConverseResult, Provider } from "./types.js";
|
|
2
|
+
import type { ProviderSelection } from "./index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Deterministic, offline provider. Used when no API key is configured — or when a
|
|
5
|
+
* workflow explicitly asks for `preferred: mock` — so the end-to-end loop (and
|
|
6
|
+
* tests) run without network access or credentials.
|
|
7
|
+
*
|
|
8
|
+
* It cannot call a model, but it is handed the SAME provider selection a real
|
|
9
|
+
* provider would receive (the resolved per-run model + per-org BYO keys) and
|
|
10
|
+
* self-documents what a real run WOULD have used. That makes model/key
|
|
11
|
+
* resolution OBSERVABLE offline — a caller's e2e harness can read it back out of
|
|
12
|
+
* the run's output artifact to assert key precedence. It never echoes a key,
|
|
13
|
+
* only its last-4 marker.
|
|
14
|
+
*/
|
|
15
|
+
export declare class MockProvider implements Provider {
|
|
16
|
+
readonly name = "mock";
|
|
17
|
+
private readonly selection;
|
|
18
|
+
constructor(selection?: ProviderSelection);
|
|
19
|
+
private resolvedModel;
|
|
20
|
+
private byoKeyMarker;
|
|
21
|
+
private selectionLines;
|
|
22
|
+
complete(req: CompletionRequest): Promise<string>;
|
|
23
|
+
converse(req: ConverseRequest): Promise<ConverseResult>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=mock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/providers/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD;;;;;;;;;;;GAWG;AACH,qBAAa,YAAa,YAAW,QAAQ;IAC3C,QAAQ,CAAC,IAAI,UAAS;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;gBAEjC,SAAS,GAAE,iBAAsB;IAS7C,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,cAAc;IAWtB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB3C,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAS9D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic, offline provider. Used when no API key is configured — or when a
|
|
3
|
+
* workflow explicitly asks for `preferred: mock` — so the end-to-end loop (and
|
|
4
|
+
* tests) run without network access or credentials.
|
|
5
|
+
*
|
|
6
|
+
* It cannot call a model, but it is handed the SAME provider selection a real
|
|
7
|
+
* provider would receive (the resolved per-run model + per-org BYO keys) and
|
|
8
|
+
* self-documents what a real run WOULD have used. That makes model/key
|
|
9
|
+
* resolution OBSERVABLE offline — a caller's e2e harness can read it back out of
|
|
10
|
+
* the run's output artifact to assert key precedence. It never echoes a key,
|
|
11
|
+
* only its last-4 marker.
|
|
12
|
+
*/
|
|
13
|
+
export class MockProvider {
|
|
14
|
+
name = "mock";
|
|
15
|
+
selection;
|
|
16
|
+
constructor(selection = {}) {
|
|
17
|
+
this.selection = selection;
|
|
18
|
+
}
|
|
19
|
+
// "What a real provider would have used" for the model: the model the caller
|
|
20
|
+
// resolved (workflow YAML → org default), else the host's
|
|
21
|
+
// env-default model (the SAME env vars the real providers read), else
|
|
22
|
+
// the provider's built-in default. `source` labels which rung of that fallback
|
|
23
|
+
// won, so the offline observer can tell the org-default case from the env case.
|
|
24
|
+
resolvedModel() {
|
|
25
|
+
if (this.selection.model)
|
|
26
|
+
return { value: this.selection.model, source: "resolved" };
|
|
27
|
+
const envModel = process.env.ANTHROPIC_MODEL ?? process.env.OPENAI_MODEL ?? process.env.OPENROUTER_MODEL;
|
|
28
|
+
if (envModel)
|
|
29
|
+
return { value: envModel, source: "runner env default" };
|
|
30
|
+
return { value: "(provider built-in default)", source: "provider built-in default" };
|
|
31
|
+
}
|
|
32
|
+
// Which per-org BYO key WOULD have been threaded, by masked last-4 ONLY — never
|
|
33
|
+
// the key itself. `(none …)` means the org set no key for that provider, so the
|
|
34
|
+
// runner's own env key would be used.
|
|
35
|
+
byoKeyMarker() {
|
|
36
|
+
const creds = this.selection.credentials ?? {};
|
|
37
|
+
const present = ["anthropic", "openai", "openrouter"]
|
|
38
|
+
.filter((p) => creds[p])
|
|
39
|
+
.map((p) => `${p}:…${creds[p].slice(-4)}`);
|
|
40
|
+
return present.length ? present.join(", ") : "(none — runner env key would be used)";
|
|
41
|
+
}
|
|
42
|
+
// The block the e2e harness parses out of output.md. Deterministic and offline.
|
|
43
|
+
selectionLines() {
|
|
44
|
+
const model = this.resolvedModel();
|
|
45
|
+
return [
|
|
46
|
+
"## Provider selection (mock — dry run)",
|
|
47
|
+
"",
|
|
48
|
+
`model: ${model.value} (${model.source}; would be used)`,
|
|
49
|
+
`org BYO key: ${this.byoKeyMarker()}`,
|
|
50
|
+
"",
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
complete(req) {
|
|
54
|
+
const preview = req.prompt.slice(0, 600);
|
|
55
|
+
return Promise.resolve([
|
|
56
|
+
"# Workflow Output (mock provider)",
|
|
57
|
+
"",
|
|
58
|
+
"_Generated offline by the harness-kernel mock provider. Set ANTHROPIC_API_KEY",
|
|
59
|
+
"or OPENAI_API_KEY to use a real model._",
|
|
60
|
+
"",
|
|
61
|
+
...this.selectionLines(),
|
|
62
|
+
"## System",
|
|
63
|
+
"",
|
|
64
|
+
req.system,
|
|
65
|
+
"",
|
|
66
|
+
"## Context + Inputs (excerpt)",
|
|
67
|
+
"",
|
|
68
|
+
"```",
|
|
69
|
+
preview,
|
|
70
|
+
"```",
|
|
71
|
+
].join("\n"));
|
|
72
|
+
}
|
|
73
|
+
// The mock never calls tools, so the agent loop terminates after one turn. It
|
|
74
|
+
// echoes which tools were available, which is handy when running offline.
|
|
75
|
+
async converse(req) {
|
|
76
|
+
const lastUser = [...req.messages].reverse().find((m) => m.role === "user");
|
|
77
|
+
const prompt = lastUser && lastUser.role === "user" ? lastUser.text : "";
|
|
78
|
+
const text = await this.complete({
|
|
79
|
+
system: `${req.system}\n\nAvailable tools: ${req.tools.map((t) => t.name).join(", ") || "(none)"}`,
|
|
80
|
+
prompt,
|
|
81
|
+
});
|
|
82
|
+
return { text, toolCalls: [] };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=mock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.js","sourceRoot":"","sources":["../../src/providers/mock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
import type { AgentMessage, CompletionRequest, ConverseRequest, ConverseResult, Provider } from "./types.js";
|
|
3
|
+
/** Map provider-neutral messages to OpenAI chat messages (pure; tested). */
|
|
4
|
+
export declare function toOpenAIMessages(messages: AgentMessage[]): OpenAI.Chat.Completions.ChatCompletionMessageParam[];
|
|
5
|
+
/** Reduce an OpenAI response message to text + tool calls (pure; tested). */
|
|
6
|
+
export declare function parseOpenAIMessage(message: OpenAI.Chat.Completions.ChatCompletionMessage): ConverseResult;
|
|
7
|
+
/** Constructor options for an OpenAI-compatible (chat.completions) provider. */
|
|
8
|
+
export interface OpenAICompatibleOptions {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
model: string;
|
|
11
|
+
/** Alternate chat.completions endpoint (e.g. OpenRouter); omit for api.openai.com. */
|
|
12
|
+
baseURL?: string;
|
|
13
|
+
/** Extra headers sent on every request (e.g. OpenRouter attribution). */
|
|
14
|
+
defaultHeaders?: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Shared core for providers speaking the OpenAI chat.completions dialect
|
|
18
|
+
* (including tools). OpenAI proper and OpenRouter both instantiate this —
|
|
19
|
+
* they differ only in name, endpoint, headers, and env defaults.
|
|
20
|
+
*/
|
|
21
|
+
export declare class OpenAICompatibleProvider implements Provider {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
private client;
|
|
24
|
+
private model;
|
|
25
|
+
constructor(name: string, opts: OpenAICompatibleOptions);
|
|
26
|
+
complete(req: CompletionRequest): Promise<string>;
|
|
27
|
+
converse(req: ConverseRequest): Promise<ConverseResult>;
|
|
28
|
+
}
|
|
29
|
+
export declare class OpenAIProvider extends OpenAICompatibleProvider {
|
|
30
|
+
constructor(apiKey: string, model?: string);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAE3B,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,QAAQ,EAET,MAAM,YAAY,CAAA;AAEnB,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EAAE,GACvB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,0BAA0B,EAAE,CA0BtD;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,qBAAqB,GACrD,cAAc,CAchB;AAaD,gFAAgF;AAChF,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxC;AAED;;;;GAIG;AACH,qBAAa,wBAAyB,YAAW,QAAQ;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,KAAK,CAAQ;gBAET,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB;IAejD,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAajD,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAiB9D;AAED,qBAAa,cAAe,SAAQ,wBAAwB;gBAC9C,MAAM,EAAE,MAAM,EAAE,KAAK,SAAwC;CAG1E"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
import { maxTokens, providerMaxRetries, providerTimeoutMs } from "./clientOptions.js";
|
|
3
|
+
/** Map provider-neutral messages to OpenAI chat messages (pure; tested). */
|
|
4
|
+
export function toOpenAIMessages(messages) {
|
|
5
|
+
const out = [];
|
|
6
|
+
for (const m of messages) {
|
|
7
|
+
if (m.role === "user") {
|
|
8
|
+
out.push({ role: "user", content: m.text });
|
|
9
|
+
}
|
|
10
|
+
else if (m.role === "assistant") {
|
|
11
|
+
const msg = {
|
|
12
|
+
role: "assistant",
|
|
13
|
+
content: m.text,
|
|
14
|
+
};
|
|
15
|
+
if (m.toolCalls.length > 0) {
|
|
16
|
+
msg.tool_calls = m.toolCalls.map((tc) => ({
|
|
17
|
+
id: tc.id,
|
|
18
|
+
type: "function",
|
|
19
|
+
function: { name: tc.name, arguments: JSON.stringify(tc.input) },
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
out.push(msg);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Each tool result becomes its own `tool` message keyed by the call id.
|
|
26
|
+
for (const r of m.results) {
|
|
27
|
+
out.push({ role: "tool", tool_call_id: r.toolCallId, content: r.content });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
/** Reduce an OpenAI response message to text + tool calls (pure; tested). */
|
|
34
|
+
export function parseOpenAIMessage(message) {
|
|
35
|
+
// Surface a refusal as text so a refused turn is distinguishable from a normal
|
|
36
|
+
// empty-but-final one (otherwise the agent loop ends silently with no signal).
|
|
37
|
+
const text = message.content ?? (message.refusal ? `Refused: ${message.refusal}` : "");
|
|
38
|
+
const toolCalls = [];
|
|
39
|
+
for (const tc of message.tool_calls ?? []) {
|
|
40
|
+
if (tc.type !== "function")
|
|
41
|
+
continue;
|
|
42
|
+
toolCalls.push({
|
|
43
|
+
id: tc.id,
|
|
44
|
+
name: tc.function.name,
|
|
45
|
+
input: parseArguments(tc.function.arguments),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return { text, toolCalls };
|
|
49
|
+
}
|
|
50
|
+
/** Parse a tool-call arguments JSON string, tolerating empty/invalid input. */
|
|
51
|
+
function parseArguments(raw) {
|
|
52
|
+
if (!raw)
|
|
53
|
+
return {};
|
|
54
|
+
try {
|
|
55
|
+
const parsed = JSON.parse(raw);
|
|
56
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Shared core for providers speaking the OpenAI chat.completions dialect
|
|
64
|
+
* (including tools). OpenAI proper and OpenRouter both instantiate this —
|
|
65
|
+
* they differ only in name, endpoint, headers, and env defaults.
|
|
66
|
+
*/
|
|
67
|
+
export class OpenAICompatibleProvider {
|
|
68
|
+
name;
|
|
69
|
+
client;
|
|
70
|
+
model;
|
|
71
|
+
constructor(name, opts) {
|
|
72
|
+
// The SDK retries transient 429/5xx/network errors with exponential backoff
|
|
73
|
+
// internally, so a blip doesn't fail the whole run; `timeout` bounds each
|
|
74
|
+
// request. Both are env-overridable.
|
|
75
|
+
this.name = name;
|
|
76
|
+
this.client = new OpenAI({
|
|
77
|
+
apiKey: opts.apiKey,
|
|
78
|
+
timeout: providerTimeoutMs(),
|
|
79
|
+
maxRetries: providerMaxRetries(),
|
|
80
|
+
...(opts.baseURL !== undefined ? { baseURL: opts.baseURL } : {}),
|
|
81
|
+
...(opts.defaultHeaders !== undefined ? { defaultHeaders: opts.defaultHeaders } : {}),
|
|
82
|
+
});
|
|
83
|
+
this.model = opts.model;
|
|
84
|
+
}
|
|
85
|
+
async complete(req) {
|
|
86
|
+
const completion = await this.client.chat.completions.create({
|
|
87
|
+
model: this.model,
|
|
88
|
+
max_tokens: maxTokens(), // match AnthropicProvider rather than the model default
|
|
89
|
+
messages: [
|
|
90
|
+
{ role: "system", content: req.system },
|
|
91
|
+
{ role: "user", content: req.prompt },
|
|
92
|
+
],
|
|
93
|
+
});
|
|
94
|
+
return completion.choices[0]?.message?.content ?? "";
|
|
95
|
+
}
|
|
96
|
+
async converse(req) {
|
|
97
|
+
const tools = req.tools.map((t) => ({
|
|
98
|
+
type: "function",
|
|
99
|
+
function: { name: t.name, description: t.description, parameters: t.inputSchema },
|
|
100
|
+
}));
|
|
101
|
+
const completion = await this.client.chat.completions.create({
|
|
102
|
+
model: this.model,
|
|
103
|
+
max_tokens: maxTokens(), // match AnthropicProvider rather than the model default
|
|
104
|
+
messages: [{ role: "system", content: req.system }, ...toOpenAIMessages(req.messages)],
|
|
105
|
+
...(tools.length > 0 ? { tools } : {}),
|
|
106
|
+
});
|
|
107
|
+
const message = completion.choices[0]?.message;
|
|
108
|
+
if (!message)
|
|
109
|
+
return { text: "", toolCalls: [] };
|
|
110
|
+
return parseOpenAIMessage(message);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export class OpenAIProvider extends OpenAICompatibleProvider {
|
|
114
|
+
constructor(apiKey, model = process.env.OPENAI_MODEL ?? "gpt-4.1") {
|
|
115
|
+
super("openai", { apiKey, model });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { OpenAICompatibleProvider } from "./openai.js";
|
|
2
|
+
export declare const OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
|
|
3
|
+
/**
|
|
4
|
+
* Default model when neither the payload nor OPENROUTER_MODEL specifies one.
|
|
5
|
+
* OpenRouter model ids are provider-namespaced (`anthropic/...`, `openai/...`)
|
|
6
|
+
* and pass through to the API untouched.
|
|
7
|
+
*/
|
|
8
|
+
export declare const OPENROUTER_DEFAULT_MODEL = "anthropic/claude-sonnet-4.5";
|
|
9
|
+
/**
|
|
10
|
+
* The optional attribution OpenRouter's convention asks apps to send, used for
|
|
11
|
+
* its public rankings. The kernel has no app identity of its own, so it sends
|
|
12
|
+
* nothing unless the embedding application supplies one.
|
|
13
|
+
*/
|
|
14
|
+
export interface OpenRouterAttribution {
|
|
15
|
+
/** App URL, sent as the `HTTP-Referer` header. */
|
|
16
|
+
referer?: string;
|
|
17
|
+
/** App name, sent as the `X-Title` header. */
|
|
18
|
+
title?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* OpenRouter speaks the OpenAI chat.completions dialect (including tools), so
|
|
22
|
+
* this is the shared OpenAI-compatible core pointed at openrouter.ai. Pass
|
|
23
|
+
* `attribution` to identify your app in OpenRouter's rankings; omit it and no
|
|
24
|
+
* attribution headers are sent.
|
|
25
|
+
*/
|
|
26
|
+
export declare class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
27
|
+
constructor(apiKey: string, model?: string, attribution?: OpenRouterAttribution);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEtD,eAAO,MAAM,mBAAmB,iCAAiC,CAAA;AAEjE;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,gCAAgC,CAAA;AAErE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAUD;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,wBAAwB;gBAE5D,MAAM,EAAE,MAAM,EACd,KAAK,SAA2D,EAChE,WAAW,GAAE,qBAA0B;CAU1C"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { OpenAICompatibleProvider } from "./openai.js";
|
|
2
|
+
export const OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
|
|
3
|
+
/**
|
|
4
|
+
* Default model when neither the payload nor OPENROUTER_MODEL specifies one.
|
|
5
|
+
* OpenRouter model ids are provider-namespaced (`anthropic/...`, `openai/...`)
|
|
6
|
+
* and pass through to the API untouched.
|
|
7
|
+
*/
|
|
8
|
+
export const OPENROUTER_DEFAULT_MODEL = "anthropic/claude-sonnet-4.5";
|
|
9
|
+
/** Build the attribution headers, omitting any the caller left unset. */
|
|
10
|
+
function attributionHeaders(attribution) {
|
|
11
|
+
const headers = {};
|
|
12
|
+
if (attribution.referer)
|
|
13
|
+
headers["HTTP-Referer"] = attribution.referer;
|
|
14
|
+
if (attribution.title)
|
|
15
|
+
headers["X-Title"] = attribution.title;
|
|
16
|
+
return headers;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* OpenRouter speaks the OpenAI chat.completions dialect (including tools), so
|
|
20
|
+
* this is the shared OpenAI-compatible core pointed at openrouter.ai. Pass
|
|
21
|
+
* `attribution` to identify your app in OpenRouter's rankings; omit it and no
|
|
22
|
+
* attribution headers are sent.
|
|
23
|
+
*/
|
|
24
|
+
export class OpenRouterProvider extends OpenAICompatibleProvider {
|
|
25
|
+
constructor(apiKey, model = process.env.OPENROUTER_MODEL ?? OPENROUTER_DEFAULT_MODEL, attribution = {}) {
|
|
26
|
+
const headers = attributionHeaders(attribution);
|
|
27
|
+
super("openrouter", {
|
|
28
|
+
apiKey,
|
|
29
|
+
model,
|
|
30
|
+
baseURL: OPENROUTER_BASE_URL,
|
|
31
|
+
...(Object.keys(headers).length > 0 ? { defaultHeaders: headers } : {}),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=openrouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,8BAA8B,CAAA;AAEjE;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,6BAA6B,CAAA;AAcrE,yEAAyE;AACzE,SAAS,kBAAkB,CAAC,WAAkC;IAC5D,MAAM,OAAO,GAA2B,EAAE,CAAA;IAC1C,IAAI,WAAW,CAAC,OAAO;QAAE,OAAO,CAAC,cAAc,CAAC,GAAG,WAAW,CAAC,OAAO,CAAA;IACtE,IAAI,WAAW,CAAC,KAAK;QAAE,OAAO,CAAC,SAAS,CAAC,GAAG,WAAW,CAAC,KAAK,CAAA;IAC7D,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,kBAAmB,SAAQ,wBAAwB;IAC9D,YACE,MAAc,EACd,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,wBAAwB,EAChE,cAAqC,EAAE;QAEvC,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;QAC/C,KAAK,CAAC,YAAY,EAAE;YAClB,MAAM;YACN,KAAK;YACL,OAAO,EAAE,mBAAmB;YAC5B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface CompletionRequest {
|
|
2
|
+
system: string;
|
|
3
|
+
prompt: string;
|
|
4
|
+
}
|
|
5
|
+
/** A tool offered to the model, described by a JSON-Schema input shape. */
|
|
6
|
+
export interface ToolSpec {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/** The model's request to invoke a tool. */
|
|
12
|
+
export interface ToolCall {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
input: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/** The reply to a ToolCall. */
|
|
18
|
+
export interface ToolResult {
|
|
19
|
+
toolCallId: string;
|
|
20
|
+
/** The string projection sent to the model — the only part a provider serializes. */
|
|
21
|
+
content: string;
|
|
22
|
+
/**
|
|
23
|
+
* The typed payload `content` was projected from, when the tool produced one.
|
|
24
|
+
* Providers ignore it; callers and clients read it to avoid re-parsing a
|
|
25
|
+
* struct back out of the string.
|
|
26
|
+
*/
|
|
27
|
+
structured?: unknown;
|
|
28
|
+
isError?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Provider-neutral conversation turn (mapped to each provider's wire format). */
|
|
31
|
+
export type AgentMessage = {
|
|
32
|
+
role: "user";
|
|
33
|
+
text: string;
|
|
34
|
+
} | {
|
|
35
|
+
role: "assistant";
|
|
36
|
+
text: string;
|
|
37
|
+
toolCalls: ToolCall[];
|
|
38
|
+
} | {
|
|
39
|
+
role: "tool";
|
|
40
|
+
results: ToolResult[];
|
|
41
|
+
};
|
|
42
|
+
export interface ConverseRequest {
|
|
43
|
+
system: string;
|
|
44
|
+
messages: AgentMessage[];
|
|
45
|
+
tools: ToolSpec[];
|
|
46
|
+
}
|
|
47
|
+
export interface ConverseResult {
|
|
48
|
+
/** Assistant prose for this turn (may be empty when it only calls tools). */
|
|
49
|
+
text: string;
|
|
50
|
+
/** Tools the model wants run; empty means the turn is final. */
|
|
51
|
+
toolCalls: ToolCall[];
|
|
52
|
+
}
|
|
53
|
+
export interface Provider {
|
|
54
|
+
readonly name: string;
|
|
55
|
+
/** One-shot completion (no tools) — kept for simple callers. */
|
|
56
|
+
complete(req: CompletionRequest): Promise<string>;
|
|
57
|
+
/** One step of a tool-use conversation; the agent loop drives the rest. */
|
|
58
|
+
converse(req: ConverseRequest): Promise<ConverseResult>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,2EAA2E;AAC3E,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAED,4CAA4C;AAC5C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,kFAAkF;AAClF,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,QAAQ,EAAE,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAA;CAAE,CAAA;AAE3C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAA;IACZ,gEAAgE;IAChE,SAAS,EAAE,QAAQ,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gEAAgE;IAChE,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACjD,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;CACxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type CapabilityDefinition, type ResolvedRoute, type RouteContext, type RouteResolver } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The kernel's built-in resolver: capabilities as code.
|
|
4
|
+
*
|
|
5
|
+
* It takes a list of {@link CapabilityDefinition}s — from a literal, a JSON
|
|
6
|
+
* file, environment config, anything the application already has — and resolves
|
|
7
|
+
* names against them in memory. No database, no migration, no service to stand
|
|
8
|
+
* up. That matters beyond convenience: it means the whole seam is exercisable
|
|
9
|
+
* in a unit test, and an application that never wants dynamic routing never
|
|
10
|
+
* needs any infrastructure at all.
|
|
11
|
+
*
|
|
12
|
+
* An application that *does* want dynamic routing writes its own
|
|
13
|
+
* {@link RouteResolver} against the same interface. That adapter — with its
|
|
14
|
+
* tables, its prompt versioning, its per-tenant overrides — lives in the app
|
|
15
|
+
* layer. It does not live here.
|
|
16
|
+
*/
|
|
17
|
+
export declare class StaticRouteResolver implements RouteResolver {
|
|
18
|
+
readonly name = "static";
|
|
19
|
+
private readonly definitions;
|
|
20
|
+
constructor(definitions?: CapabilityDefinition[]);
|
|
21
|
+
/**
|
|
22
|
+
* Add or replace a capability. Unlike the model registry, redefinition is
|
|
23
|
+
* allowed: a resolver is configuration, and layering a config file over a
|
|
24
|
+
* built-in default is a normal thing to want.
|
|
25
|
+
*/
|
|
26
|
+
define(definition: CapabilityDefinition): this;
|
|
27
|
+
has(capability: string): boolean;
|
|
28
|
+
/** Every defined capability name. */
|
|
29
|
+
capabilities(): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a name to its route, filling defaults for the optional parts so
|
|
32
|
+
* callers get a fully-determined {@link ResolvedRoute}. Throws
|
|
33
|
+
* {@link UnknownCapabilityError} when the name isn't defined.
|
|
34
|
+
*
|
|
35
|
+
* `ctx` is accepted for interface parity and ignored here — static routing is
|
|
36
|
+
* by definition context-free. A resolver that varies by invocation mode or
|
|
37
|
+
* tenant is exactly the app-layer adapter this interface exists to admit.
|
|
38
|
+
*/
|
|
39
|
+
resolve(capability: string, _ctx?: RouteContext): Promise<ResolvedRoute>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=staticResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staticResolver.d.ts","sourceRoot":"","sources":["../../src/routing/staticResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IACvD,QAAQ,CAAC,IAAI,YAAW;IAExB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0C;gBAE1D,WAAW,GAAE,oBAAoB,EAAO;IAIpD;;;;OAIG;IACH,MAAM,CAAC,UAAU,EAAE,oBAAoB,GAAG,IAAI;IAK9C,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIhC,qCAAqC;IACrC,YAAY,IAAI,MAAM,EAAE;IAIxB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAkBzE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { UnknownCapabilityError, } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The kernel's built-in resolver: capabilities as code.
|
|
4
|
+
*
|
|
5
|
+
* It takes a list of {@link CapabilityDefinition}s — from a literal, a JSON
|
|
6
|
+
* file, environment config, anything the application already has — and resolves
|
|
7
|
+
* names against them in memory. No database, no migration, no service to stand
|
|
8
|
+
* up. That matters beyond convenience: it means the whole seam is exercisable
|
|
9
|
+
* in a unit test, and an application that never wants dynamic routing never
|
|
10
|
+
* needs any infrastructure at all.
|
|
11
|
+
*
|
|
12
|
+
* An application that *does* want dynamic routing writes its own
|
|
13
|
+
* {@link RouteResolver} against the same interface. That adapter — with its
|
|
14
|
+
* tables, its prompt versioning, its per-tenant overrides — lives in the app
|
|
15
|
+
* layer. It does not live here.
|
|
16
|
+
*/
|
|
17
|
+
export class StaticRouteResolver {
|
|
18
|
+
name = "static";
|
|
19
|
+
definitions = new Map();
|
|
20
|
+
constructor(definitions = []) {
|
|
21
|
+
for (const definition of definitions)
|
|
22
|
+
this.define(definition);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Add or replace a capability. Unlike the model registry, redefinition is
|
|
26
|
+
* allowed: a resolver is configuration, and layering a config file over a
|
|
27
|
+
* built-in default is a normal thing to want.
|
|
28
|
+
*/
|
|
29
|
+
define(definition) {
|
|
30
|
+
this.definitions.set(definition.name, definition);
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
has(capability) {
|
|
34
|
+
return this.definitions.has(capability);
|
|
35
|
+
}
|
|
36
|
+
/** Every defined capability name. */
|
|
37
|
+
capabilities() {
|
|
38
|
+
return [...this.definitions.keys()];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve a name to its route, filling defaults for the optional parts so
|
|
42
|
+
* callers get a fully-determined {@link ResolvedRoute}. Throws
|
|
43
|
+
* {@link UnknownCapabilityError} when the name isn't defined.
|
|
44
|
+
*
|
|
45
|
+
* `ctx` is accepted for interface parity and ignored here — static routing is
|
|
46
|
+
* by definition context-free. A resolver that varies by invocation mode or
|
|
47
|
+
* tenant is exactly the app-layer adapter this interface exists to admit.
|
|
48
|
+
*/
|
|
49
|
+
resolve(capability, _ctx) {
|
|
50
|
+
const definition = this.definitions.get(capability);
|
|
51
|
+
if (!definition) {
|
|
52
|
+
// Rejected, not thrown: the interface promises a Promise, and a caller
|
|
53
|
+
// that attached `.catch()` instead of awaiting would otherwise be hit by
|
|
54
|
+
// a synchronous throw it never had a chance to handle.
|
|
55
|
+
return Promise.reject(new UnknownCapabilityError(capability, this.capabilities()));
|
|
56
|
+
}
|
|
57
|
+
return Promise.resolve({
|
|
58
|
+
capability: definition.name,
|
|
59
|
+
model: definition.model,
|
|
60
|
+
prompt: definition.prompt ?? "",
|
|
61
|
+
tools: definition.tools ?? [],
|
|
62
|
+
limits: definition.limits ?? {},
|
|
63
|
+
...(definition.meta ? { meta: definition.meta } : {}),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=staticResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staticResolver.js","sourceRoot":"","sources":["../../src/routing/staticResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,GAKvB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,mBAAmB;IACrB,IAAI,GAAG,QAAQ,CAAA;IAEP,WAAW,GAAG,IAAI,GAAG,EAAgC,CAAA;IAEtE,YAAY,cAAsC,EAAE;QAClD,KAAK,MAAM,UAAU,IAAI,WAAW;YAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAC/D,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,UAAgC;QACrC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QACjD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,GAAG,CAAC,UAAkB;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IACzC,CAAC;IAED,qCAAqC;IACrC,YAAY;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAA;IACrC,CAAC;IAED;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAkB,EAAE,IAAmB;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACnD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,uEAAuE;YACvE,yEAAyE;YACzE,uDAAuD;YACvD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,sBAAsB,CAAC,UAAU,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;QACpF,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,CAAC;YACrB,UAAU,EAAE,UAAU,CAAC,IAAI;YAC3B,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,EAAE;YAC/B,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,EAAE;YAC7B,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,EAAE;YAC/B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ModelRef } from "../models/registry.js";
|
|
2
|
+
import type { InvocationMode } from "../tools/metadata.js";
|
|
3
|
+
/**
|
|
4
|
+
* Route resolution: "which model, prompt and tools should capability X use?"
|
|
5
|
+
*
|
|
6
|
+
* This sits **one layer above** the model registry. A resolver picks the whole
|
|
7
|
+
* bundle for a named capability; the {@link ModelRef} it returns is then bound
|
|
8
|
+
* to a concrete implementation by `ModelRegistry.resolve`. The two are not the
|
|
9
|
+
* same question and must not be conflated:
|
|
10
|
+
*
|
|
11
|
+
* resolver: "summarise-thread" → { model: chat:anthropic, prompt, tools }
|
|
12
|
+
* registry: { kind: "chat", id: "anthropic" } → the ModelInvocation
|
|
13
|
+
*
|
|
14
|
+
* The kernel ships exactly one resolver — {@link StaticRouteResolver}, backed by
|
|
15
|
+
* plain code or config, usable with zero infrastructure. A database-backed
|
|
16
|
+
* resolver is an **app-layer adapter behind this interface**, never a kernel
|
|
17
|
+
* concern: the kernel has no database, no schema and no control plane, and the
|
|
18
|
+
* moment a field here exists only to serve one product's tables, this seam has
|
|
19
|
+
* drifted across the line.
|
|
20
|
+
*/
|
|
21
|
+
/** A capability as declared by the application: the bundle, before resolution. */
|
|
22
|
+
export interface CapabilityDefinition {
|
|
23
|
+
/** The name callers route by. */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Which model kind + id serves it. */
|
|
26
|
+
model: ModelRef;
|
|
27
|
+
/** System prompt for the capability. */
|
|
28
|
+
prompt?: string;
|
|
29
|
+
/** Tool names this capability may use; absent means "no restriction". */
|
|
30
|
+
tools?: string[];
|
|
31
|
+
/** Budgets an engine or loop should honour. */
|
|
32
|
+
limits?: RouteLimits;
|
|
33
|
+
/** Free-form application detail carried through resolution untouched. */
|
|
34
|
+
meta?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
export interface RouteLimits {
|
|
37
|
+
maxSteps?: number;
|
|
38
|
+
maxDurationMs?: number;
|
|
39
|
+
}
|
|
40
|
+
/** What a resolver returns: a fully-determined route for one capability. */
|
|
41
|
+
export interface ResolvedRoute {
|
|
42
|
+
capability: string;
|
|
43
|
+
model: ModelRef;
|
|
44
|
+
prompt: string;
|
|
45
|
+
tools: string[];
|
|
46
|
+
limits: RouteLimits;
|
|
47
|
+
meta?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The little a resolver is told about the call site. Deliberately thin — the
|
|
51
|
+
* moment this grows product-shaped fields, resolution has stopped being generic.
|
|
52
|
+
*/
|
|
53
|
+
export interface RouteContext {
|
|
54
|
+
/** How the turn was invoked; a resolver may route differently per mode. */
|
|
55
|
+
mode?: InvocationMode;
|
|
56
|
+
correlationId?: string;
|
|
57
|
+
}
|
|
58
|
+
/** Thrown when a capability name has no route. */
|
|
59
|
+
export declare class UnknownCapabilityError extends Error {
|
|
60
|
+
readonly capability: string;
|
|
61
|
+
constructor(capability: string, known: string[]);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolves a capability name to a route. Implementations must **fail loud** on
|
|
65
|
+
* an unknown capability rather than returning a default — a silently-defaulted
|
|
66
|
+
* route sends traffic to the wrong model with no signal.
|
|
67
|
+
*/
|
|
68
|
+
export interface RouteResolver {
|
|
69
|
+
readonly name: string;
|
|
70
|
+
resolve(capability: string, ctx?: RouteContext): Promise<ResolvedRoute>;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/routing/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AAEH,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,uCAAuC;IACvC,KAAK,EAAE,QAAQ,CAAA;IACf,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,QAAQ,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE,WAAW,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,kDAAkD;AAClD,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;gBAEf,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;CAMhD;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;CACxE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Thrown when a capability name has no route. */
|
|
2
|
+
export class UnknownCapabilityError extends Error {
|
|
3
|
+
capability;
|
|
4
|
+
constructor(capability, known) {
|
|
5
|
+
const alternatives = known.length > 0 ? known.join(", ") : "(none defined)";
|
|
6
|
+
super(`no route defined for capability "${capability}" — defined: ${alternatives}`);
|
|
7
|
+
this.name = "UnknownCapabilityError";
|
|
8
|
+
this.capability = capability;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=types.js.map
|