@aisy/core 0.1.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/LICENSE +202 -0
- package/dist/agent-loop/index.d.ts +4 -0
- package/dist/agent-loop/index.d.ts.map +1 -0
- package/dist/agent-loop/index.js +352 -0
- package/dist/agent-loop/index.js.map +1 -0
- package/dist/agent-loop/types.d.ts +183 -0
- package/dist/agent-loop/types.d.ts.map +1 -0
- package/dist/agent-loop/types.js +3 -0
- package/dist/agent-loop/types.js.map +1 -0
- package/dist/bin/aisy.d.ts +3 -0
- package/dist/bin/aisy.d.ts.map +1 -0
- package/dist/bin/aisy.js +14 -0
- package/dist/bin/aisy.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +114 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/context-engine/index.d.ts +4 -0
- package/dist/context-engine/index.d.ts.map +1 -0
- package/dist/context-engine/index.js +126 -0
- package/dist/context-engine/index.js.map +1 -0
- package/dist/context-engine/types.d.ts +54 -0
- package/dist/context-engine/types.d.ts.map +1 -0
- package/dist/context-engine/types.js +4 -0
- package/dist/context-engine/types.js.map +1 -0
- package/dist/eval/index.d.ts +20 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +128 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/types.d.ts +62 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +17 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/gateway/index.d.ts +5 -0
- package/dist/gateway/index.d.ts.map +1 -0
- package/dist/gateway/index.js +288 -0
- package/dist/gateway/index.js.map +1 -0
- package/dist/gateway/types.d.ts +194 -0
- package/dist/gateway/types.d.ts.map +1 -0
- package/dist/gateway/types.js +94 -0
- package/dist/gateway/types.js.map +1 -0
- package/dist/goals/index.d.ts +11 -0
- package/dist/goals/index.d.ts.map +1 -0
- package/dist/goals/index.js +21 -0
- package/dist/goals/index.js.map +1 -0
- package/dist/goals/types.d.ts +47 -0
- package/dist/goals/types.d.ts.map +1 -0
- package/dist/goals/types.js +5 -0
- package/dist/goals/types.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +215 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/types.d.ts +148 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +4 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/memory/index.d.ts +6 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +419 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/types.d.ts +131 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +33 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/nightly/index.d.ts +4 -0
- package/dist/nightly/index.d.ts.map +1 -0
- package/dist/nightly/index.js +470 -0
- package/dist/nightly/index.js.map +1 -0
- package/dist/nightly/types.d.ts +326 -0
- package/dist/nightly/types.d.ts.map +1 -0
- package/dist/nightly/types.js +3 -0
- package/dist/nightly/types.js.map +1 -0
- package/dist/observability/index.d.ts +11 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +396 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/types.d.ts +139 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js +4 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/onboarding/index.d.ts +16 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +787 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/interactive.d.ts +23 -0
- package/dist/onboarding/interactive.d.ts.map +1 -0
- package/dist/onboarding/interactive.js +45 -0
- package/dist/onboarding/interactive.js.map +1 -0
- package/dist/onboarding/types.d.ts +388 -0
- package/dist/onboarding/types.d.ts.map +1 -0
- package/dist/onboarding/types.js +35 -0
- package/dist/onboarding/types.js.map +1 -0
- package/dist/orchestration/index.d.ts +8 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +706 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/types.d.ts +391 -0
- package/dist/orchestration/types.d.ts.map +1 -0
- package/dist/orchestration/types.js +30 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/personality/index.d.ts +65 -0
- package/dist/personality/index.d.ts.map +1 -0
- package/dist/personality/index.js +339 -0
- package/dist/personality/index.js.map +1 -0
- package/dist/personality/types.d.ts +103 -0
- package/dist/personality/types.d.ts.map +1 -0
- package/dist/personality/types.js +15 -0
- package/dist/personality/types.js.map +1 -0
- package/dist/provider/index.d.ts +4 -0
- package/dist/provider/index.d.ts.map +1 -0
- package/dist/provider/index.js +236 -0
- package/dist/provider/index.js.map +1 -0
- package/dist/provider/types.d.ts +180 -0
- package/dist/provider/types.d.ts.map +1 -0
- package/dist/provider/types.js +4 -0
- package/dist/provider/types.js.map +1 -0
- package/dist/runtime/agent-cards.d.ts +14 -0
- package/dist/runtime/agent-cards.d.ts.map +1 -0
- package/dist/runtime/agent-cards.js +90 -0
- package/dist/runtime/agent-cards.js.map +1 -0
- package/dist/runtime/agent-runner.d.ts +30 -0
- package/dist/runtime/agent-runner.d.ts.map +1 -0
- package/dist/runtime/agent-runner.js +37 -0
- package/dist/runtime/agent-runner.js.map +1 -0
- package/dist/runtime/budget.d.ts +15 -0
- package/dist/runtime/budget.d.ts.map +1 -0
- package/dist/runtime/budget.js +24 -0
- package/dist/runtime/budget.js.map +1 -0
- package/dist/runtime/delegation-driver.d.ts +11 -0
- package/dist/runtime/delegation-driver.d.ts.map +1 -0
- package/dist/runtime/delegation-driver.js +132 -0
- package/dist/runtime/delegation-driver.js.map +1 -0
- package/dist/runtime/exact-cache.d.ts +10 -0
- package/dist/runtime/exact-cache.d.ts.map +1 -0
- package/dist/runtime/exact-cache.js +30 -0
- package/dist/runtime/exact-cache.js.map +1 -0
- package/dist/runtime/execute-tool.d.ts +29 -0
- package/dist/runtime/execute-tool.d.ts.map +1 -0
- package/dist/runtime/execute-tool.js +80 -0
- package/dist/runtime/execute-tool.js.map +1 -0
- package/dist/runtime/guardian.d.ts +9 -0
- package/dist/runtime/guardian.d.ts.map +1 -0
- package/dist/runtime/guardian.js +41 -0
- package/dist/runtime/guardian.js.map +1 -0
- package/dist/runtime/hook-gate.d.ts +17 -0
- package/dist/runtime/hook-gate.d.ts.map +1 -0
- package/dist/runtime/hook-gate.js +56 -0
- package/dist/runtime/hook-gate.js.map +1 -0
- package/dist/runtime/memory-adapter.d.ts +6 -0
- package/dist/runtime/memory-adapter.d.ts.map +1 -0
- package/dist/runtime/memory-adapter.js +38 -0
- package/dist/runtime/memory-adapter.js.map +1 -0
- package/dist/runtime/nightly-adapters.d.ts +48 -0
- package/dist/runtime/nightly-adapters.d.ts.map +1 -0
- package/dist/runtime/nightly-adapters.js +139 -0
- package/dist/runtime/nightly-adapters.js.map +1 -0
- package/dist/runtime/nightly-generator.d.ts +10 -0
- package/dist/runtime/nightly-generator.d.ts.map +1 -0
- package/dist/runtime/nightly-generator.js +335 -0
- package/dist/runtime/nightly-generator.js.map +1 -0
- package/dist/runtime/onboarding-node.d.ts +6 -0
- package/dist/runtime/onboarding-node.d.ts.map +1 -0
- package/dist/runtime/onboarding-node.js +356 -0
- package/dist/runtime/onboarding-node.js.map +1 -0
- package/dist/runtime/provider-anthropic.d.ts +43 -0
- package/dist/runtime/provider-anthropic.d.ts.map +1 -0
- package/dist/runtime/provider-anthropic.js +148 -0
- package/dist/runtime/provider-anthropic.js.map +1 -0
- package/dist/runtime/provider-cli.d.ts +18 -0
- package/dist/runtime/provider-cli.d.ts.map +1 -0
- package/dist/runtime/provider-cli.js +73 -0
- package/dist/runtime/provider-cli.js.map +1 -0
- package/dist/runtime/provider-openai.d.ts +30 -0
- package/dist/runtime/provider-openai.d.ts.map +1 -0
- package/dist/runtime/provider-openai.js +114 -0
- package/dist/runtime/provider-openai.js.map +1 -0
- package/dist/runtime/providers.d.ts +43 -0
- package/dist/runtime/providers.d.ts.map +1 -0
- package/dist/runtime/providers.js +72 -0
- package/dist/runtime/providers.js.map +1 -0
- package/dist/runtime/sandbox-bash.d.ts +21 -0
- package/dist/runtime/sandbox-bash.d.ts.map +1 -0
- package/dist/runtime/sandbox-bash.js +51 -0
- package/dist/runtime/sandbox-bash.js.map +1 -0
- package/dist/runtime/scoped-tool-executor.d.ts +10 -0
- package/dist/runtime/scoped-tool-executor.d.ts.map +1 -0
- package/dist/runtime/scoped-tool-executor.js +30 -0
- package/dist/runtime/scoped-tool-executor.js.map +1 -0
- package/dist/runtime/session-log.d.ts +6 -0
- package/dist/runtime/session-log.d.ts.map +1 -0
- package/dist/runtime/session-log.js +54 -0
- package/dist/runtime/session-log.js.map +1 -0
- package/dist/runtime/settings.d.ts +24 -0
- package/dist/runtime/settings.d.ts.map +1 -0
- package/dist/runtime/settings.js +29 -0
- package/dist/runtime/settings.js.map +1 -0
- package/dist/runtime/spawn-plan.d.ts +13 -0
- package/dist/runtime/spawn-plan.d.ts.map +1 -0
- package/dist/runtime/spawn-plan.js +107 -0
- package/dist/runtime/spawn-plan.js.map +1 -0
- package/dist/runtime/spend.d.ts +41 -0
- package/dist/runtime/spend.d.ts.map +1 -0
- package/dist/runtime/spend.js +0 -0
- package/dist/runtime/spend.js.map +1 -0
- package/dist/runtime/sub-agent-runner.d.ts +19 -0
- package/dist/runtime/sub-agent-runner.d.ts.map +1 -0
- package/dist/runtime/sub-agent-runner.js +47 -0
- package/dist/runtime/sub-agent-runner.js.map +1 -0
- package/dist/safety/grants.d.ts +7 -0
- package/dist/safety/grants.d.ts.map +1 -0
- package/dist/safety/grants.js +53 -0
- package/dist/safety/grants.js.map +1 -0
- package/dist/safety/index.d.ts +72 -0
- package/dist/safety/index.d.ts.map +1 -0
- package/dist/safety/index.js +464 -0
- package/dist/safety/index.js.map +1 -0
- package/dist/safety/types.d.ts +254 -0
- package/dist/safety/types.d.ts.map +1 -0
- package/dist/safety/types.js +3 -0
- package/dist/safety/types.js.map +1 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +463 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/types.d.ts +177 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +3 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/testing/clock.d.ts +8 -0
- package/dist/testing/clock.d.ts.map +1 -0
- package/dist/testing/clock.js +13 -0
- package/dist/testing/clock.js.map +1 -0
- package/dist/testing/effect-verifier.d.ts +15 -0
- package/dist/testing/effect-verifier.d.ts.map +1 -0
- package/dist/testing/effect-verifier.js +27 -0
- package/dist/testing/effect-verifier.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/provider-fake.d.ts +14 -0
- package/dist/testing/provider-fake.d.ts.map +1 -0
- package/dist/testing/provider-fake.js +18 -0
- package/dist/testing/provider-fake.js.map +1 -0
- package/dist/testing/sandbox-stub.d.ts +15 -0
- package/dist/testing/sandbox-stub.d.ts.map +1 -0
- package/dist/testing/sandbox-stub.js +15 -0
- package/dist/testing/sandbox-stub.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +0 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/types.d.ts +138 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +4 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/triggers/index.d.ts +4 -0
- package/dist/triggers/index.d.ts.map +1 -0
- package/dist/triggers/index.js +187 -0
- package/dist/triggers/index.js.map +1 -0
- package/dist/triggers/types.d.ts +74 -0
- package/dist/triggers/types.d.ts.map +1 -0
- package/dist/triggers/types.js +5 -0
- package/dist/triggers/types.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// CLI subprocess provider adapter (runtime).
|
|
2
|
+
//
|
|
3
|
+
// Drives a local CLI (e.g. `claude -p`) as a model backend — no API key, uses
|
|
4
|
+
// the CLI's own auth/subscription. The assembled conversation is fed on stdin
|
|
5
|
+
// and stdout is taken as the reply. Reply-only: structured tool-calling is not
|
|
6
|
+
// available over a plain CLI, so the agent degrades to no-tools for this
|
|
7
|
+
// provider (documented limitation). The spawn is injected for tests.
|
|
8
|
+
import { spawn } from 'node:child_process';
|
|
9
|
+
class CliError extends Error {
|
|
10
|
+
kind;
|
|
11
|
+
constructor(kind, message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.kind = kind;
|
|
14
|
+
this.name = 'ProviderError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Flatten spans into a plain-text transcript for a CLI prompt. */
|
|
18
|
+
export function promptFromSpans(spans, prefix) {
|
|
19
|
+
const parts = [];
|
|
20
|
+
if (prefix.length > 0)
|
|
21
|
+
parts.push(prefix);
|
|
22
|
+
for (const s of spans) {
|
|
23
|
+
const label = s.role === 'system' ? 'System' : s.role === 'assistant' ? 'Assistant' : s.role === 'tool' ? 'Tool' : 'User';
|
|
24
|
+
parts.push(`${label}: ${s.text}`);
|
|
25
|
+
}
|
|
26
|
+
return parts.join('\n\n');
|
|
27
|
+
}
|
|
28
|
+
function defaultRun(timeoutMs) {
|
|
29
|
+
return (argv, input, signal) => new Promise((resolve, reject) => {
|
|
30
|
+
const [cmd, ...args] = argv;
|
|
31
|
+
if (!cmd) {
|
|
32
|
+
reject(new CliError('server-error', 'empty CLI command'));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const child = spawn(cmd, args, { timeout: timeoutMs });
|
|
36
|
+
const onAbort = () => { child.kill(); };
|
|
37
|
+
if (signal) {
|
|
38
|
+
if (signal.aborted)
|
|
39
|
+
child.kill();
|
|
40
|
+
else
|
|
41
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
42
|
+
}
|
|
43
|
+
let stdout = '';
|
|
44
|
+
child.stdout.on('data', (d) => (stdout += String(d)));
|
|
45
|
+
child.on('error', (e) => {
|
|
46
|
+
if (signal)
|
|
47
|
+
signal.removeEventListener('abort', onAbort);
|
|
48
|
+
reject(new CliError('server-error', `CLI spawn failed: ${e.message}`));
|
|
49
|
+
});
|
|
50
|
+
child.on('close', (code) => {
|
|
51
|
+
if (signal)
|
|
52
|
+
signal.removeEventListener('abort', onAbort);
|
|
53
|
+
resolve({ stdout, exitCode: code ?? 0 });
|
|
54
|
+
});
|
|
55
|
+
child.stdin.end(input);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function makeCliProvider(deps) {
|
|
59
|
+
const run = deps.run ?? defaultRun(deps.timeoutMs ?? 120_000);
|
|
60
|
+
const argv = deps.model ? [...deps.command, '--model', deps.model] : [...deps.command];
|
|
61
|
+
return {
|
|
62
|
+
async complete(req, signal) {
|
|
63
|
+
const prefix = req.prefixBytes.byteLength > 0 ? Buffer.from(req.prefixBytes).toString('utf8') : '';
|
|
64
|
+
const prompt = promptFromSpans(req.spans, prefix);
|
|
65
|
+
const r = await run(argv, prompt, signal);
|
|
66
|
+
if (r.exitCode !== 0) {
|
|
67
|
+
throw new CliError('server-error', `CLI exited ${r.exitCode}`);
|
|
68
|
+
}
|
|
69
|
+
return { reply: r.stdout.trim() };
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=provider-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-cli.js","sourceRoot":"","sources":["../../src/runtime/provider-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ProviderAdapter, ModelResponse } from '../agent-loop/types.js';
|
|
2
|
+
import { type AnthropicTool } from './provider-anthropic.js';
|
|
3
|
+
export interface ModelPrice {
|
|
4
|
+
inPerMtok: number;
|
|
5
|
+
outPerMtok: number;
|
|
6
|
+
}
|
|
7
|
+
export interface OpenAIProviderDeps {
|
|
8
|
+
apiKey: string;
|
|
9
|
+
model: string;
|
|
10
|
+
/** Base URL incl. scheme, no trailing slash, e.g. https://api.deepseek.com/v1 */
|
|
11
|
+
baseUrl: string;
|
|
12
|
+
tools?: AnthropicTool[];
|
|
13
|
+
/** Optional per-model price for cost accounting; absent ⇒ zero dollars. */
|
|
14
|
+
price?: ModelPrice;
|
|
15
|
+
maxTokens?: number;
|
|
16
|
+
fetchImpl?: typeof fetch;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Cache strategy:
|
|
20
|
+
* - 'auto' (default): plain string content — OpenAI/DeepSeek/Gemini/GLM/Qwen
|
|
21
|
+
* auto-cache transparently, no request change needed.
|
|
22
|
+
* - 'breakpoints': wraps system + last message content in cache_control blocks
|
|
23
|
+
* for OpenRouter passthrough to Anthropic.
|
|
24
|
+
*/
|
|
25
|
+
cache?: 'auto' | 'breakpoints';
|
|
26
|
+
}
|
|
27
|
+
/** Parse an OpenAI chat-completions body into a ModelResponse. */
|
|
28
|
+
export declare function parseOpenAIResponse(body: unknown, price?: ModelPrice): ModelResponse;
|
|
29
|
+
export declare function makeOpenAICompatProvider(deps: OpenAIProviderDeps): ProviderAdapter;
|
|
30
|
+
//# sourceMappingURL=provider-openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-openai.d.ts","sourceRoot":"","sources":["../../src/runtime/provider-openai.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EAEf,aAAa,EAGd,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAE7E,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAAA;CAC/B;AAaD,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,aAAa,CAkCpF;AAUD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,CA8DlF"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Generic OpenAI-compatible provider adapter (runtime).
|
|
2
|
+
//
|
|
3
|
+
// Covers OpenAI, DeepSeek, OpenRouter, Qwen, GLM/Zhipu, Gemini (openai-compat),
|
|
4
|
+
// and any custom baseURL that speaks the OpenAI chat-completions API. Implements
|
|
5
|
+
// the agent-loop's ProviderAdapter.complete: spans -> messages, tools -> function
|
|
6
|
+
// tools, choices[0].message -> {reply, toolCalls}, usage -> tokens + dollars.
|
|
7
|
+
import { spansToMessages } from './provider-anthropic.js';
|
|
8
|
+
class OpenAIError extends Error {
|
|
9
|
+
kind;
|
|
10
|
+
constructor(kind, message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.kind = kind;
|
|
13
|
+
this.name = 'ProviderError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Parse an OpenAI chat-completions body into a ModelResponse. */
|
|
17
|
+
export function parseOpenAIResponse(body, price) {
|
|
18
|
+
const b = (body && typeof body === 'object' ? body : {});
|
|
19
|
+
const message = b.choices?.[0]?.message;
|
|
20
|
+
const reply = typeof message?.content === 'string' ? message.content : '';
|
|
21
|
+
const toolCalls = [];
|
|
22
|
+
for (const tc of message?.tool_calls ?? []) {
|
|
23
|
+
const name = tc.function?.name;
|
|
24
|
+
if (typeof name !== 'string')
|
|
25
|
+
continue;
|
|
26
|
+
let args = {};
|
|
27
|
+
try {
|
|
28
|
+
args = tc.function?.arguments ? JSON.parse(tc.function.arguments) : {};
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
args = {};
|
|
32
|
+
}
|
|
33
|
+
toolCalls.push({ name, args });
|
|
34
|
+
}
|
|
35
|
+
let usage;
|
|
36
|
+
if (b.usage) {
|
|
37
|
+
const inputTokens = b.usage.prompt_tokens ?? 0;
|
|
38
|
+
const outputTokens = b.usage.completion_tokens ?? 0;
|
|
39
|
+
const dollars = price ? (inputTokens / 1e6) * price.inPerMtok + (outputTokens / 1e6) * price.outPerMtok : 0;
|
|
40
|
+
usage = { inputTokens, outputTokens, dollars };
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
reply,
|
|
44
|
+
...(toolCalls.length > 0 ? { toolCalls } : {}),
|
|
45
|
+
...(usage ? { usage } : {}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Convert the neutral tool schema to the OpenAI function-tool shape. */
|
|
49
|
+
function toOpenAITools(tools) {
|
|
50
|
+
return tools.map((t) => ({
|
|
51
|
+
type: 'function',
|
|
52
|
+
function: { name: t.name, description: t.description, parameters: t.input_schema },
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
export function makeOpenAICompatProvider(deps) {
|
|
56
|
+
const fetchImpl = deps.fetchImpl ?? fetch;
|
|
57
|
+
const maxTokens = deps.maxTokens ?? 4096;
|
|
58
|
+
const timeoutMs = deps.timeoutMs ?? 60_000;
|
|
59
|
+
const url = `${deps.baseUrl.replace(/\/$/, '')}/chat/completions`;
|
|
60
|
+
return {
|
|
61
|
+
async complete(req, signal) {
|
|
62
|
+
const prefix = req.prefixBytes.byteLength > 0 ? Buffer.from(req.prefixBytes).toString('utf8') : '';
|
|
63
|
+
const { system, messages } = spansToMessages(req.spans, prefix);
|
|
64
|
+
const cache = deps.cache ?? 'auto';
|
|
65
|
+
const oaMessages = [];
|
|
66
|
+
if (system.length > 0) {
|
|
67
|
+
oaMessages.push(cache === 'breakpoints'
|
|
68
|
+
? { role: 'system', content: [{ type: 'text', text: system, cache_control: { type: 'ephemeral' } }] }
|
|
69
|
+
: { role: 'system', content: system });
|
|
70
|
+
}
|
|
71
|
+
if (cache === 'breakpoints' && messages.length > 0) {
|
|
72
|
+
messages.forEach((m, i) => oaMessages.push(i === messages.length - 1
|
|
73
|
+
? { role: m.role, content: [{ type: 'text', text: m.content, cache_control: { type: 'ephemeral' } }] }
|
|
74
|
+
: { role: m.role, content: m.content }));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
for (const m of messages)
|
|
78
|
+
oaMessages.push({ role: m.role, content: m.content });
|
|
79
|
+
}
|
|
80
|
+
const payload = {
|
|
81
|
+
model: deps.model,
|
|
82
|
+
max_tokens: maxTokens,
|
|
83
|
+
messages: oaMessages,
|
|
84
|
+
};
|
|
85
|
+
if (deps.tools && deps.tools.length > 0)
|
|
86
|
+
payload['tools'] = toOpenAITools(deps.tools);
|
|
87
|
+
let res;
|
|
88
|
+
try {
|
|
89
|
+
res = await fetchImpl(url, {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
headers: {
|
|
92
|
+
authorization: `Bearer ${deps.apiKey}`,
|
|
93
|
+
'content-type': 'application/json',
|
|
94
|
+
},
|
|
95
|
+
body: JSON.stringify(payload),
|
|
96
|
+
signal: signal ? AbortSignal.any([AbortSignal.timeout(timeoutMs), signal]) : AbortSignal.timeout(timeoutMs),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
const kind = err?.name === 'TimeoutError' ? 'timeout' : 'server-error';
|
|
101
|
+
throw new OpenAIError(kind, `OpenAI-compat request failed: ${err?.message ?? 'unknown'}`);
|
|
102
|
+
}
|
|
103
|
+
if (res.status === 429)
|
|
104
|
+
throw new OpenAIError('rate-limit', 'OpenAI-compat 429');
|
|
105
|
+
if (res.status >= 500)
|
|
106
|
+
throw new OpenAIError('server-error', `OpenAI-compat ${res.status}`);
|
|
107
|
+
if (res.status >= 400)
|
|
108
|
+
throw new OpenAIError('server-error', `OpenAI-compat client error ${res.status}`);
|
|
109
|
+
const body = (await res.json());
|
|
110
|
+
return parseOpenAIResponse(body, deps.price);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=provider-openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-openai.js","sourceRoot":"","sources":["../../src/runtime/provider-openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ProviderAdapter } from '../agent-loop/types.js';
|
|
2
|
+
import type { RouteTier } from '../provider/types.js';
|
|
3
|
+
import { type AnthropicTool } from './provider-anthropic.js';
|
|
4
|
+
import { type ModelPrice } from './provider-openai.js';
|
|
5
|
+
export type ProviderKind = 'anthropic' | 'openai-compat' | 'cli';
|
|
6
|
+
export interface ProviderEntry {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
kind: ProviderKind;
|
|
10
|
+
/** OpenAI-compat default base URL (custom entries leave this unset). */
|
|
11
|
+
defaultBaseUrl?: string;
|
|
12
|
+
/** Vault/env key name; absent for CLI providers (no API key). */
|
|
13
|
+
keyEnv?: string;
|
|
14
|
+
defaultModels?: string[];
|
|
15
|
+
/** argv for CLI providers. */
|
|
16
|
+
cliCommand?: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare const PROVIDER_CATALOG: readonly ProviderEntry[];
|
|
19
|
+
export declare function findProvider(id: string): ProviderEntry | undefined;
|
|
20
|
+
export interface BuildProviderConfig {
|
|
21
|
+
provider: string;
|
|
22
|
+
model: string;
|
|
23
|
+
apiKey?: string;
|
|
24
|
+
baseUrl?: string;
|
|
25
|
+
tools?: AnthropicTool[];
|
|
26
|
+
price?: ModelPrice;
|
|
27
|
+
/** Emit cache_control breakpoints on system + last message. Default true. */
|
|
28
|
+
prefixCache?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Injected fetch implementation for testing. Passed through to the underlying
|
|
31
|
+
* adapter when provided (both adapters accept fetchImpl in their deps).
|
|
32
|
+
*/
|
|
33
|
+
fetchImpl?: typeof fetch;
|
|
34
|
+
}
|
|
35
|
+
/** Build a single ProviderAdapter from a catalog id + config. */
|
|
36
|
+
export declare function buildProvider(cfg: BuildProviderConfig): ProviderAdapter;
|
|
37
|
+
export type TierAdapters = Record<RouteTier, ProviderAdapter>;
|
|
38
|
+
/**
|
|
39
|
+
* Wrap per-tier adapters behind one complete(): classify the request → delegate.
|
|
40
|
+
* With a single model, pass the same adapter for all tiers (classify is moot).
|
|
41
|
+
*/
|
|
42
|
+
export declare function makeTieredProvider(byTier: TierAdapters, classify?: (req: Parameters<ProviderAdapter['complete']>[0]) => RouteTier): ProviderAdapter;
|
|
43
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/runtime/providers.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACnF,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAGhF,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,eAAe,GAAG,KAAK,CAAA;AAEhE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,YAAY,CAAA;IAClB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,8BAA8B;IAC9B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,eAAO,MAAM,gBAAgB,EAAE,SAAS,aAAa,EAUpD,CAAA;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAElE;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,eAAe,CAmCvE;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,CAAA;AAE7D;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,GACxE,eAAe,CAKjB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Provider catalog + factory (runtime).
|
|
2
|
+
//
|
|
3
|
+
// One place that enumerates supported providers and builds the right adapter by
|
|
4
|
+
// kind. Most providers are OpenAI-compatible (one HTTP adapter); Anthropic has a
|
|
5
|
+
// native adapter; CLI providers shell out. All implement the agent-loop's
|
|
6
|
+
// ProviderAdapter.complete. makeTieredProvider maps reasoning/critique/routine to
|
|
7
|
+
// (possibly different) adapters behind one complete() — single-model ⇒ all equal.
|
|
8
|
+
import { makeAnthropicProvider } from './provider-anthropic.js';
|
|
9
|
+
import { makeOpenAICompatProvider } from './provider-openai.js';
|
|
10
|
+
import { makeCliProvider } from './provider-cli.js';
|
|
11
|
+
export const PROVIDER_CATALOG = [
|
|
12
|
+
{ id: 'anthropic', label: 'Anthropic (Claude API)', kind: 'anthropic', keyEnv: 'AISY_PROVIDER_ANTHROPIC_KEY', defaultModels: ['claude-sonnet-4-6', 'claude-opus-4-8'] },
|
|
13
|
+
{ id: 'openai', label: 'OpenAI', kind: 'openai-compat', defaultBaseUrl: 'https://api.openai.com/v1', keyEnv: 'AISY_PROVIDER_OPENAI_KEY' },
|
|
14
|
+
{ id: 'deepseek', label: 'DeepSeek', kind: 'openai-compat', defaultBaseUrl: 'https://api.deepseek.com/v1', keyEnv: 'AISY_PROVIDER_DEEPSEEK_KEY' },
|
|
15
|
+
{ id: 'openrouter', label: 'OpenRouter', kind: 'openai-compat', defaultBaseUrl: 'https://openrouter.ai/api/v1', keyEnv: 'AISY_PROVIDER_OPENROUTER_KEY' },
|
|
16
|
+
{ id: 'qwen', label: 'Qwen (DashScope)', kind: 'openai-compat', defaultBaseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1', keyEnv: 'AISY_PROVIDER_QWEN_KEY' },
|
|
17
|
+
{ id: 'glm', label: 'GLM (Zhipu)', kind: 'openai-compat', defaultBaseUrl: 'https://open.bigmodel.cn/api/paas/v4', keyEnv: 'AISY_PROVIDER_GLM_KEY' },
|
|
18
|
+
{ id: 'gemini', label: 'Gemini (OpenAI-compat)', kind: 'openai-compat', defaultBaseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai', keyEnv: 'AISY_PROVIDER_GEMINI_KEY' },
|
|
19
|
+
{ id: 'openai-compat', label: 'Custom (OpenAI-compatible)', kind: 'openai-compat', keyEnv: 'AISY_PROVIDER_CUSTOM_KEY' },
|
|
20
|
+
{ id: 'claude-cli', label: 'Claude CLI (subprocess, no key)', kind: 'cli', cliCommand: ['claude', '-p'] },
|
|
21
|
+
];
|
|
22
|
+
export function findProvider(id) {
|
|
23
|
+
return PROVIDER_CATALOG.find((p) => p.id === id);
|
|
24
|
+
}
|
|
25
|
+
/** Build a single ProviderAdapter from a catalog id + config. */
|
|
26
|
+
export function buildProvider(cfg) {
|
|
27
|
+
const entry = findProvider(cfg.provider);
|
|
28
|
+
if (!entry)
|
|
29
|
+
throw new Error(`unknown provider: ${cfg.provider}`);
|
|
30
|
+
switch (entry.kind) {
|
|
31
|
+
case 'anthropic':
|
|
32
|
+
return makeAnthropicProvider({
|
|
33
|
+
apiKey: cfg.apiKey ?? '',
|
|
34
|
+
model: cfg.model,
|
|
35
|
+
prefixCache: cfg.prefixCache ?? true,
|
|
36
|
+
...(cfg.tools ? { tools: cfg.tools } : {}),
|
|
37
|
+
...(cfg.baseUrl ? { apiBase: cfg.baseUrl } : {}),
|
|
38
|
+
...(cfg.fetchImpl ? { fetchImpl: cfg.fetchImpl } : {}),
|
|
39
|
+
});
|
|
40
|
+
case 'openai-compat': {
|
|
41
|
+
const baseUrl = cfg.baseUrl ?? entry.defaultBaseUrl;
|
|
42
|
+
if (!baseUrl)
|
|
43
|
+
throw new Error(`provider ${cfg.provider} needs a baseUrl`);
|
|
44
|
+
const cache = (cfg.prefixCache ?? true) && entry.id === 'openrouter' ? 'breakpoints' : 'auto';
|
|
45
|
+
return makeOpenAICompatProvider({
|
|
46
|
+
apiKey: cfg.apiKey ?? '',
|
|
47
|
+
model: cfg.model,
|
|
48
|
+
baseUrl,
|
|
49
|
+
cache,
|
|
50
|
+
...(cfg.tools ? { tools: cfg.tools } : {}),
|
|
51
|
+
...(cfg.price ? { price: cfg.price } : {}),
|
|
52
|
+
...(cfg.fetchImpl ? { fetchImpl: cfg.fetchImpl } : {}),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
case 'cli':
|
|
56
|
+
return makeCliProvider({
|
|
57
|
+
command: entry.cliCommand ?? ['claude', '-p'],
|
|
58
|
+
...(cfg.model ? { model: cfg.model } : {}),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Wrap per-tier adapters behind one complete(): classify the request → delegate.
|
|
64
|
+
* With a single model, pass the same adapter for all tiers (classify is moot).
|
|
65
|
+
*/
|
|
66
|
+
export function makeTieredProvider(byTier, classify) {
|
|
67
|
+
const pick = classify ?? (() => 'reasoning');
|
|
68
|
+
return {
|
|
69
|
+
complete: (req, signal) => byTier[pick(req)].complete(req, signal),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/runtime/providers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface DockerResult {
|
|
2
|
+
stdout: string;
|
|
3
|
+
stderr: string;
|
|
4
|
+
exitCode: number;
|
|
5
|
+
}
|
|
6
|
+
export interface DockerBashDeps {
|
|
7
|
+
/** Container image to run commands in. */
|
|
8
|
+
image: string;
|
|
9
|
+
/** Host workspace mounted read-write at /work. */
|
|
10
|
+
workspaceRoot: string;
|
|
11
|
+
/** Run `docker` with these args; injected for tests. Default: child_process. */
|
|
12
|
+
runDocker?: (args: string[]) => Promise<DockerResult>;
|
|
13
|
+
/** Use the gVisor (runsc) runtime when available. */
|
|
14
|
+
gvisor?: boolean;
|
|
15
|
+
/** Per-command wall-clock cap (seconds) enforced inside the container. */
|
|
16
|
+
timeoutSec?: number;
|
|
17
|
+
}
|
|
18
|
+
/** Build the hardened `docker run` argv for a single command. */
|
|
19
|
+
export declare function dockerRunArgs(deps: DockerBashDeps, cmd: string): string[];
|
|
20
|
+
export declare function makeDockerBash(deps: DockerBashDeps): (cmd: string) => Promise<DockerResult>;
|
|
21
|
+
//# sourceMappingURL=sandbox-bash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-bash.d.ts","sourceRoot":"","sources":["../../src/runtime/sandbox-bash.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAA;IACrB,gFAAgF;IAChF,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IACrD,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBzE;AAoBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAG3F"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Sandbox bash adapter (runtime).
|
|
2
|
+
//
|
|
3
|
+
// Provides executeTool's `runBash` port by running each command in a locked-down
|
|
4
|
+
// throwaway container (ADR-0012 invariants: cap-drop ALL, no-new-privileges,
|
|
5
|
+
// default-deny network, read-only root with a writable workspace mount + tmpfs,
|
|
6
|
+
// pids cap, optional gVisor runtime). The docker invocation is injected so the
|
|
7
|
+
// argv construction and result mapping are unit-tested without a daemon.
|
|
8
|
+
import { execFile } from 'node:child_process';
|
|
9
|
+
/** Build the hardened `docker run` argv for a single command. */
|
|
10
|
+
export function dockerRunArgs(deps, cmd) {
|
|
11
|
+
const wrapped = deps.timeoutSec ? `timeout ${deps.timeoutSec}s sh -lc ${shellQuote(cmd)}` : `sh -lc ${shellQuote(cmd)}`;
|
|
12
|
+
return [
|
|
13
|
+
'run',
|
|
14
|
+
'--rm',
|
|
15
|
+
'--cap-drop=ALL',
|
|
16
|
+
'--security-opt=no-new-privileges',
|
|
17
|
+
'--network=none',
|
|
18
|
+
'--read-only',
|
|
19
|
+
'--tmpfs=/tmp',
|
|
20
|
+
'--pids-limit=256',
|
|
21
|
+
...(deps.gvisor ? ['--runtime=runsc'] : []),
|
|
22
|
+
'-v',
|
|
23
|
+
`${deps.workspaceRoot}:/work`,
|
|
24
|
+
'-w',
|
|
25
|
+
'/work',
|
|
26
|
+
deps.image,
|
|
27
|
+
'sh',
|
|
28
|
+
'-lc',
|
|
29
|
+
wrapped,
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
function shellQuote(s) {
|
|
33
|
+
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
34
|
+
}
|
|
35
|
+
function defaultRunDocker(args) {
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
execFile('docker', args, { maxBuffer: 8 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
38
|
+
const code = err && typeof err.code === 'number'
|
|
39
|
+
? (err.code)
|
|
40
|
+
: err
|
|
41
|
+
? 1
|
|
42
|
+
: 0;
|
|
43
|
+
resolve({ stdout: String(stdout), stderr: String(stderr), exitCode: code });
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function makeDockerBash(deps) {
|
|
48
|
+
const runDocker = deps.runDocker ?? defaultRunDocker;
|
|
49
|
+
return (cmd) => runDocker(dockerRunArgs(deps, cmd));
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=sandbox-bash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-bash.js","sourceRoot":"","sources":["../../src/runtime/sandbox-bash.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,iFAAiF;AACjF,6EAA6E;AAC7E,gFAAgF;AAChF,+EAA+E;AAC/E,yEAAyE;AAEzE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAqB7C,iEAAiE;AACjE,MAAM,UAAU,aAAa,CAAC,IAAoB,EAAE,GAAW;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,UAAU,YAAY,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,GAAG,CAAC,EAAE,CAAA;IACvH,OAAO;QACL,KAAK;QACL,MAAM;QACN,gBAAgB;QAChB,kCAAkC;QAClC,gBAAgB;QAChB,aAAa;QACb,cAAc;QACd,kBAAkB;QAClB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,IAAI;QACJ,GAAG,IAAI,CAAC,aAAa,QAAQ;QAC7B,IAAI;QACJ,OAAO;QACP,IAAI,CAAC,KAAK;QACV,IAAI;QACJ,KAAK;QACL,OAAO;KACR,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAA;AACxC,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAc;IACtC,OAAO,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,EAAE;QAC3C,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC/E,MAAM,IAAI,GACR,GAAG,IAAI,OAAQ,GAA0B,CAAC,IAAI,KAAK,QAAQ;gBACzD,CAAC,CAAC,CAAE,GAAwB,CAAC,IAAI,CAAC;gBAClC,CAAC,CAAC,GAAG;oBACH,CAAC,CAAC,CAAC;oBACH,CAAC,CAAC,CAAC,CAAA;YACT,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QAC7E,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAoB;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,gBAAgB,CAAA;IACpD,OAAO,CAAC,GAAW,EAAyB,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;AACpF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ToolCall } from '../agent-loop/types.js';
|
|
2
|
+
import type { ToolResult } from './execute-tool.js';
|
|
3
|
+
export interface ScopedToolExecutorDeps {
|
|
4
|
+
base: (call: ToolCall) => Promise<ToolResult>;
|
|
5
|
+
permitsTool: (name: string) => boolean;
|
|
6
|
+
owns: string[];
|
|
7
|
+
doNotTouch: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function makeScopedToolExecutor(deps: ScopedToolExecutorDeps): (call: ToolCall) => Promise<ToolResult>;
|
|
10
|
+
//# sourceMappingURL=scoped-tool-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoped-tool-executor.d.ts","sourceRoot":"","sources":["../../src/runtime/scoped-tool-executor.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IAC7C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;IACtC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB;AASD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,sBAAsB,GAC3B,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,UAAU,CAAC,CAiBzC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Sub-agent scope enforcement (runtime, ADR-0052).
|
|
2
|
+
//
|
|
3
|
+
// Wraps a base tool executor so a delegated sub-agent can only call tools its
|
|
4
|
+
// AgentCard permits, and can only WRITE inside its delegation's owned lane
|
|
5
|
+
// (owns minus doNotTouch). Reads/non-write tools pass through once the card
|
|
6
|
+
// permits the tool. The DelegationManager already enforces write-disjointness
|
|
7
|
+
// across delegations at spawn; this is the per-call runtime guard.
|
|
8
|
+
import { globMatches } from '../orchestration/index.js';
|
|
9
|
+
const WRITE_TOOLS = new Set(['write_file', 'edit_file']);
|
|
10
|
+
function pathArg(call) {
|
|
11
|
+
const p = call.args.path;
|
|
12
|
+
return typeof p === 'string' ? p : undefined;
|
|
13
|
+
}
|
|
14
|
+
export function makeScopedToolExecutor(deps) {
|
|
15
|
+
const inOwnedLane = (p) => deps.owns.some((g) => globMatches(g, p)) &&
|
|
16
|
+
!deps.doNotTouch.some((g) => globMatches(g, p));
|
|
17
|
+
return async (call) => {
|
|
18
|
+
if (!deps.permitsTool(call.name)) {
|
|
19
|
+
return { ok: false, output: `tool '${call.name}' is not on this sub-agent's card` };
|
|
20
|
+
}
|
|
21
|
+
if (WRITE_TOOLS.has(call.name)) {
|
|
22
|
+
const p = pathArg(call);
|
|
23
|
+
if (p === undefined || !inOwnedLane(p)) {
|
|
24
|
+
return { ok: false, output: `write tool '${call.name}' needs a path inside this sub-agent's owned scope` };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return deps.base(call);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=scoped-tool-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoped-tool-executor.js","sourceRoot":"","sources":["../../src/runtime/scoped-tool-executor.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,mEAAmE;AAEnE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAWvD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAA;AAExD,SAAS,OAAO,CAAC,IAAc;IAC7B,MAAM,CAAC,GAAI,IAAI,CAAC,IAA2B,CAAC,IAAI,CAAA;IAChD,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,IAA4B;IAE5B,MAAM,WAAW,GAAG,CAAC,CAAS,EAAW,EAAE,CACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACxC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAEjD,OAAO,KAAK,EAAE,IAAc,EAAuB,EAAE;QACnD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,IAAI,CAAC,IAAI,mCAAmC,EAAE,CAAA;QACrF,CAAC;QACD,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;YACvB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,IAAI,CAAC,IAAI,oDAAoD,EAAE,CAAA;YAC5G,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-log.d.ts","sourceRoot":"","sources":["../../src/runtime/session-log.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAA4B,MAAM,wBAAwB,CAAA;AAElF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,SAAS,CAAC,EAAE,MAAM,MAAM,EAAE,CAAA;CAC3B,GAAG,UAAU,CAsCb"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// packages/core-ts/src/runtime/session-log.ts
|
|
2
|
+
// Durable append-only session log: each LogEntry is one JSON line via the
|
|
3
|
+
// injected sink (the node bin appends to ~/.aisy/session-log.jsonl). resume()
|
|
4
|
+
// returns null — full crash-resume (TurnState replay) is a deferred follow-up;
|
|
5
|
+
// this gives a durable, inspectable audit trail today.
|
|
6
|
+
export function makeJsonlSessionLog(deps) {
|
|
7
|
+
return {
|
|
8
|
+
append: (entry) => deps.appendLine(JSON.stringify(entry)),
|
|
9
|
+
resume: () => null,
|
|
10
|
+
recent: (n) => {
|
|
11
|
+
// Counts log entries carrying `sessionId`. In the live loop only `turn.start`
|
|
12
|
+
// carries it (one per turn), so `turns` is the real turn count and `lastAt` the
|
|
13
|
+
// last turn-start ts — this depends on `turn.start` keeping `sessionId`.
|
|
14
|
+
const lines = deps.readLines?.() ?? [];
|
|
15
|
+
const map = new Map();
|
|
16
|
+
for (const line of lines) {
|
|
17
|
+
if (!line.trim())
|
|
18
|
+
continue;
|
|
19
|
+
let entry;
|
|
20
|
+
try {
|
|
21
|
+
entry = JSON.parse(line);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (typeof entry !== 'object' || entry === null)
|
|
27
|
+
continue;
|
|
28
|
+
const e = entry;
|
|
29
|
+
// Extract sessionId from payload (the log writes LogEntry; payload carries sessionId)
|
|
30
|
+
const payload = e['payload'];
|
|
31
|
+
const sessionId = typeof payload === 'object' && payload !== null
|
|
32
|
+
? payload['sessionId']
|
|
33
|
+
: undefined;
|
|
34
|
+
if (typeof sessionId !== 'string')
|
|
35
|
+
continue;
|
|
36
|
+
const ts = typeof e['ts'] === 'string' ? e['ts'] : '';
|
|
37
|
+
const existing = map.get(sessionId);
|
|
38
|
+
if (!existing) {
|
|
39
|
+
map.set(sessionId, { turns: 1, lastAt: ts });
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
existing.turns += 1;
|
|
43
|
+
if (ts > existing.lastAt)
|
|
44
|
+
existing.lastAt = ts;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return [...map.entries()]
|
|
48
|
+
.map(([sessionId, { turns, lastAt }]) => ({ sessionId, turns, lastAt }))
|
|
49
|
+
.sort((a, b) => (b.lastAt > a.lastAt ? 1 : b.lastAt < a.lastAt ? -1 : 0))
|
|
50
|
+
.slice(0, n);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=session-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-log.js","sourceRoot":"","sources":["../../src/runtime/session-log.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,0EAA0E;AAC1E,8EAA8E;AAC9E,+EAA+E;AAC/E,uDAAuD;AAIvD,MAAM,UAAU,mBAAmB,CAAC,IAGnC;IACC,OAAO;QACL,MAAM,EAAE,CAAC,KAAe,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI;QAClB,MAAM,EAAE,CAAC,CAAS,EAAoB,EAAE;YACtC,8EAA8E;YAC9E,gFAAgF;YAChF,yEAAyE;YACzE,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAA;YACtC,MAAM,GAAG,GAAG,IAAI,GAAG,EAA6C,CAAA;YAChE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBAAE,SAAQ;gBAC1B,IAAI,KAAc,CAAA;gBAClB,IAAI,CAAC;oBAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,SAAQ;gBAAC,CAAC;gBACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;oBAAE,SAAQ;gBACzD,MAAM,CAAC,GAAG,KAAgC,CAAA;gBAC1C,sFAAsF;gBACtF,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,CAAA;gBAC5B,MAAM,SAAS,GACb,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;oBAC7C,CAAC,CAAE,OAAmC,CAAC,WAAW,CAAC;oBACnD,CAAC,CAAC,SAAS,CAAA;gBACf,IAAI,OAAO,SAAS,KAAK,QAAQ;oBAAE,SAAQ;gBAC3C,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;gBACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;gBACnC,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;gBAC9C,CAAC;qBAAM,CAAC;oBACN,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAA;oBACnB,IAAI,EAAE,GAAG,QAAQ,CAAC,MAAM;wBAAE,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAA;gBAChD,CAAC;YACH,CAAC;YACD,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;iBACtB,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;iBACvE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;iBACxE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAChB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface Settings {
|
|
2
|
+
/** Send a cost summary after every turn (default off — view spend on demand). */
|
|
3
|
+
showCostPerTurn: boolean;
|
|
4
|
+
/** Enforce per-agent budgets (Phase 3); the toggle lives here from Phase 2. */
|
|
5
|
+
budgetEnabled: boolean;
|
|
6
|
+
/** Append a compact per-turn debug footer after replies (default off). */
|
|
7
|
+
debug: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const DEFAULT_SETTINGS: Settings;
|
|
10
|
+
/** Persistence seam — load a (possibly partial) settings object, save the full. */
|
|
11
|
+
export interface SettingsPersistencePort {
|
|
12
|
+
load(): Partial<Settings>;
|
|
13
|
+
save(settings: Settings): void;
|
|
14
|
+
}
|
|
15
|
+
export interface SettingsStore {
|
|
16
|
+
get(): Settings;
|
|
17
|
+
set<K extends keyof Settings>(key: K, value: Settings[K]): void;
|
|
18
|
+
/** Flip a boolean flag; returns the new value (convenient for menu taps). */
|
|
19
|
+
toggle(key: keyof Settings): boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function makeSettingsStore(deps: {
|
|
22
|
+
persistence?: SettingsPersistencePort;
|
|
23
|
+
}): SettingsStore;
|
|
24
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/runtime/settings.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,QAAQ;IACvB,iFAAiF;IACjF,eAAe,EAAE,OAAO,CAAA;IACxB,+EAA+E;IAC/E,aAAa,EAAE,OAAO,CAAA;IACtB,0EAA0E;IAC1E,KAAK,EAAE,OAAO,CAAA;CACf;AAED,eAAO,MAAM,gBAAgB,EAAE,QAI9B,CAAA;AAED,mFAAmF;AACnF,MAAM,WAAW,uBAAuB;IACtC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAA;IACzB,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,IAAI,QAAQ,CAAA;IACf,GAAG,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAC/D,6EAA6E;IAC7E,MAAM,CAAC,GAAG,EAAE,MAAM,QAAQ,GAAG,OAAO,CAAA;CACrC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,WAAW,CAAC,EAAE,uBAAuB,CAAA;CAAE,GAAG,aAAa,CAkBhG"}
|