agent-composer 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/README.md +148 -0
- package/composer.config.schema.json +79 -0
- package/dist/cli/init.d.ts +20 -0
- package/dist/cli/init.js +122 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/config/env.d.ts +13 -0
- package/dist/config/env.js +65 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/loader.d.ts +3 -0
- package/dist/config/loader.js +34 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +93 -0
- package/dist/config/schema.js +44 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/evolve/budget.d.ts +23 -0
- package/dist/evolve/budget.js +55 -0
- package/dist/evolve/budget.js.map +1 -0
- package/dist/evolve/lengthPenalty.d.ts +3 -0
- package/dist/evolve/lengthPenalty.js +30 -0
- package/dist/evolve/lengthPenalty.js.map +1 -0
- package/dist/evolve/operators.d.ts +24 -0
- package/dist/evolve/operators.js +110 -0
- package/dist/evolve/operators.js.map +1 -0
- package/dist/evolve/pareto.d.ts +24 -0
- package/dist/evolve/pareto.js +153 -0
- package/dist/evolve/pareto.js.map +1 -0
- package/dist/evolve/plateau.d.ts +18 -0
- package/dist/evolve/plateau.js +45 -0
- package/dist/evolve/plateau.js.map +1 -0
- package/dist/evolve/postflight.d.ts +12 -0
- package/dist/evolve/postflight.js +61 -0
- package/dist/evolve/postflight.js.map +1 -0
- package/dist/evolve/preflight.d.ts +13 -0
- package/dist/evolve/preflight.js +39 -0
- package/dist/evolve/preflight.js.map +1 -0
- package/dist/evolve/reflection.d.ts +12 -0
- package/dist/evolve/reflection.js +41 -0
- package/dist/evolve/reflection.js.map +1 -0
- package/dist/evolve/runner.d.ts +62 -0
- package/dist/evolve/runner.js +202 -0
- package/dist/evolve/runner.js.map +1 -0
- package/dist/evolve/s2-deny.d.ts +26 -0
- package/dist/evolve/s2-deny.js +75 -0
- package/dist/evolve/s2-deny.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/AnthropicCompatibleProvider.d.ts +48 -0
- package/dist/providers/AnthropicCompatibleProvider.js +50 -0
- package/dist/providers/AnthropicCompatibleProvider.js.map +1 -0
- package/dist/providers/CLIProvider.d.ts +30 -0
- package/dist/providers/CLIProvider.js +106 -0
- package/dist/providers/CLIProvider.js.map +1 -0
- package/dist/providers/IProvider.d.ts +17 -0
- package/dist/providers/IProvider.js +4 -0
- package/dist/providers/IProvider.js.map +1 -0
- package/dist/providers/MockProvider.d.ts +28 -0
- package/dist/providers/MockProvider.js +66 -0
- package/dist/providers/MockProvider.js.map +1 -0
- package/dist/registry.d.ts +21 -0
- package/dist/registry.js +79 -0
- package/dist/registry.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +85 -0
- package/dist/server.js.map +1 -0
- package/dist/util/slug.d.ts +1 -0
- package/dist/util/slug.js +7 -0
- package/dist/util/slug.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IProvider, IProviderExecuteInput, IProviderExecuteOutput, ProviderId } from "./IProvider.js";
|
|
2
|
+
export interface ExecFileResult {
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
}
|
|
6
|
+
export type ExecFileFn = (file: string, args: ReadonlyArray<string>, options: {
|
|
7
|
+
maxBuffer?: number;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}) => Promise<ExecFileResult>;
|
|
10
|
+
export interface CLIProviderOptions {
|
|
11
|
+
/** argv array: [binary, ...staticArgs]. Prompt is appended at runtime. */
|
|
12
|
+
cli: ReadonlyArray<string>;
|
|
13
|
+
/** Optional human-readable model label; defaults to the binary name. */
|
|
14
|
+
model?: string;
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
maxBuffer?: number;
|
|
17
|
+
/** Override execFile for tests. */
|
|
18
|
+
execFn?: ExecFileFn;
|
|
19
|
+
}
|
|
20
|
+
export declare class CLIProvider implements IProvider {
|
|
21
|
+
readonly id: ProviderId;
|
|
22
|
+
readonly modelLabel: string;
|
|
23
|
+
private readonly argv;
|
|
24
|
+
private readonly exec;
|
|
25
|
+
private readonly timeoutMs;
|
|
26
|
+
private readonly maxBuffer;
|
|
27
|
+
constructor(opts: CLIProviderOptions);
|
|
28
|
+
healthCheck(): Promise<boolean>;
|
|
29
|
+
execute(input: IProviderExecuteInput): Promise<IProviderExecuteOutput>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Wave 1 F1.2 — IProvider that shells out to a CLI (default target: `agy`).
|
|
2
|
+
//
|
|
3
|
+
// CRITICAL: uses child_process.execFile (array args), NEVER child_process.exec
|
|
4
|
+
// or any shell-interpolated path — see plan §4 + §9.5 risk matrix. Prompt
|
|
5
|
+
// is appended as the LAST positional argument so quoting/backticks in the
|
|
6
|
+
// prompt cannot break out into the shell.
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
// Default executor uses spawn (not execFile) so we can explicitly ignore
|
|
9
|
+
// stdin. Some CLIs (notably `agy --print`) hang forever waiting on stdin
|
|
10
|
+
// when launched from a non-TTY parent if stdin is inherited.
|
|
11
|
+
const DEFAULT_EXEC = (file, args, options) => new Promise((resolve, reject) => {
|
|
12
|
+
const maxBuffer = options.maxBuffer ?? 32 * 1024 * 1024;
|
|
13
|
+
const timeoutMs = options.timeout;
|
|
14
|
+
const child = spawn(file, [...args], {
|
|
15
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
16
|
+
});
|
|
17
|
+
let stdout = "";
|
|
18
|
+
let stderr = "";
|
|
19
|
+
let timedOut = false;
|
|
20
|
+
let bufferExceeded = false;
|
|
21
|
+
const timer = typeof timeoutMs === "number" && timeoutMs > 0
|
|
22
|
+
? setTimeout(() => {
|
|
23
|
+
timedOut = true;
|
|
24
|
+
child.kill("SIGTERM");
|
|
25
|
+
}, timeoutMs)
|
|
26
|
+
: null;
|
|
27
|
+
const checkBuffer = (kind, payload) => {
|
|
28
|
+
if (payload.length > maxBuffer) {
|
|
29
|
+
bufferExceeded = true;
|
|
30
|
+
child.kill("SIGTERM");
|
|
31
|
+
}
|
|
32
|
+
else if (kind === "stdout") {
|
|
33
|
+
stdout = payload;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
stderr = payload;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
child.stdout?.on("data", (chunk) => {
|
|
40
|
+
checkBuffer("stdout", stdout + chunk.toString());
|
|
41
|
+
});
|
|
42
|
+
child.stderr?.on("data", (chunk) => {
|
|
43
|
+
checkBuffer("stderr", stderr + chunk.toString());
|
|
44
|
+
});
|
|
45
|
+
child.once("error", (err) => {
|
|
46
|
+
if (timer)
|
|
47
|
+
clearTimeout(timer);
|
|
48
|
+
reject(err);
|
|
49
|
+
});
|
|
50
|
+
child.once("close", (code, signal) => {
|
|
51
|
+
if (timer)
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
if (timedOut) {
|
|
54
|
+
return reject(new Error(`CLIProvider: '${file}' timed out after ${timeoutMs}ms`));
|
|
55
|
+
}
|
|
56
|
+
if (bufferExceeded) {
|
|
57
|
+
return reject(new Error(`CLIProvider: '${file}' exceeded maxBuffer ${maxBuffer}`));
|
|
58
|
+
}
|
|
59
|
+
if (code !== 0) {
|
|
60
|
+
return reject(new Error(`CLIProvider: '${file}' exited code=${code} signal=${signal ?? "none"}; stderr: ${stderr.slice(0, 500)}`));
|
|
61
|
+
}
|
|
62
|
+
resolve({ stdout, stderr });
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
const DEFAULT_TIMEOUT_MS = 5 * 60_000; // 5 min — matches tdd_plan.md §6 per-experiment budget cap.
|
|
66
|
+
const DEFAULT_MAX_BUFFER = 32 * 1024 * 1024; // 32 MB.
|
|
67
|
+
export class CLIProvider {
|
|
68
|
+
id = "cli";
|
|
69
|
+
modelLabel;
|
|
70
|
+
argv;
|
|
71
|
+
exec;
|
|
72
|
+
timeoutMs;
|
|
73
|
+
maxBuffer;
|
|
74
|
+
constructor(opts) {
|
|
75
|
+
if (!opts.cli || opts.cli.length === 0) {
|
|
76
|
+
throw new Error("CLIProvider: cli argv must contain at least 1 element (binary path)");
|
|
77
|
+
}
|
|
78
|
+
this.argv = opts.cli;
|
|
79
|
+
const bin = opts.cli[0] ?? "cli";
|
|
80
|
+
this.modelLabel = opts.model ?? bin;
|
|
81
|
+
this.exec = opts.execFn ?? DEFAULT_EXEC;
|
|
82
|
+
this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
83
|
+
this.maxBuffer = opts.maxBuffer ?? DEFAULT_MAX_BUFFER;
|
|
84
|
+
}
|
|
85
|
+
async healthCheck() {
|
|
86
|
+
// Spawning the binary just to probe would block. Caller is expected
|
|
87
|
+
// to verify the binary exists on PATH at startup.
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
async execute(input) {
|
|
91
|
+
const fullPrompt = input.context
|
|
92
|
+
? `Context:\n${input.context}\n\nTask:\n${input.prompt}`
|
|
93
|
+
: input.prompt;
|
|
94
|
+
const [bin, ...staticArgs] = this.argv;
|
|
95
|
+
if (!bin) {
|
|
96
|
+
throw new Error("CLIProvider: argv missing binary");
|
|
97
|
+
}
|
|
98
|
+
const args = [...staticArgs, fullPrompt];
|
|
99
|
+
const { stdout } = await this.exec(bin, args, {
|
|
100
|
+
maxBuffer: this.maxBuffer,
|
|
101
|
+
timeout: this.timeoutMs,
|
|
102
|
+
});
|
|
103
|
+
return { text: stdout };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=CLIProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CLIProvider.js","sourceRoot":"","sources":["../../src/providers/CLIProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ProviderId = "anthropic" | "openai_compatible" | "cli" | "mock";
|
|
2
|
+
export interface IProviderExecuteInput {
|
|
3
|
+
prompt: string;
|
|
4
|
+
context?: string;
|
|
5
|
+
maxTokens?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface IProviderExecuteOutput {
|
|
8
|
+
text: string;
|
|
9
|
+
tokensIn?: number;
|
|
10
|
+
tokensOut?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface IProvider {
|
|
13
|
+
readonly id: ProviderId;
|
|
14
|
+
readonly modelLabel: string;
|
|
15
|
+
healthCheck(): Promise<boolean>;
|
|
16
|
+
execute(input: IProviderExecuteInput): Promise<IProviderExecuteOutput>;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IProvider.js","sourceRoot":"","sources":["../../src/providers/IProvider.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,6EAA6E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IProvider, IProviderExecuteInput, IProviderExecuteOutput } from "./IProvider.js";
|
|
2
|
+
export type MockResponse = string | ((input: IProviderExecuteInput) => string | IProviderExecuteOutput);
|
|
3
|
+
export interface MockProviderOptions {
|
|
4
|
+
/** Override the default 'mock-default' model label. */
|
|
5
|
+
modelLabel?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Scripted responses returned in order; cycles modulo length when exhausted.
|
|
8
|
+
* String entries become `{ text, tokensIn: prompt.length, tokensOut: text.length }`.
|
|
9
|
+
* Function entries get the full execute() input and may return either a string
|
|
10
|
+
* (token counts derived) or a full IProviderExecuteOutput.
|
|
11
|
+
* If omitted, a deterministic echo response is generated.
|
|
12
|
+
*/
|
|
13
|
+
responses?: ReadonlyArray<MockResponse>;
|
|
14
|
+
/** Toggle healthCheck() return value. */
|
|
15
|
+
healthy?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare class MockProvider implements IProvider {
|
|
18
|
+
readonly id: "mock";
|
|
19
|
+
readonly modelLabel: string;
|
|
20
|
+
private readonly _healthy;
|
|
21
|
+
private readonly _responses?;
|
|
22
|
+
private readonly _calls;
|
|
23
|
+
constructor(opts?: MockProviderOptions);
|
|
24
|
+
get callCount(): number;
|
|
25
|
+
get calls(): readonly IProviderExecuteInput[];
|
|
26
|
+
healthCheck(): Promise<boolean>;
|
|
27
|
+
execute(input: IProviderExecuteInput): Promise<IProviderExecuteOutput>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Wave 1 F1.3 — in-memory IProvider for unit tests + offline eval.
|
|
2
|
+
// Real providers (F1.1 AnthropicCompatible, F1.2 CLI) are tape-replayed
|
|
3
|
+
// against fixtures captured ONCE on real GLM/agy traffic; everything else
|
|
4
|
+
// runs against MockProvider so tests stay deterministic + zero-cost.
|
|
5
|
+
export class MockProvider {
|
|
6
|
+
id = "mock";
|
|
7
|
+
modelLabel;
|
|
8
|
+
_healthy;
|
|
9
|
+
_responses;
|
|
10
|
+
_calls = [];
|
|
11
|
+
constructor(opts = {}) {
|
|
12
|
+
this.modelLabel = opts.modelLabel ?? "mock-default";
|
|
13
|
+
this._healthy = opts.healthy ?? true;
|
|
14
|
+
this._responses = opts.responses;
|
|
15
|
+
}
|
|
16
|
+
get callCount() {
|
|
17
|
+
return this._calls.length;
|
|
18
|
+
}
|
|
19
|
+
get calls() {
|
|
20
|
+
return this._calls;
|
|
21
|
+
}
|
|
22
|
+
async healthCheck() {
|
|
23
|
+
return this._healthy;
|
|
24
|
+
}
|
|
25
|
+
async execute(input) {
|
|
26
|
+
const callIndex = this._calls.length;
|
|
27
|
+
this._calls.push(input);
|
|
28
|
+
if (this._responses && this._responses.length > 0) {
|
|
29
|
+
const slot = callIndex % this._responses.length;
|
|
30
|
+
const r = this._responses[slot];
|
|
31
|
+
if (r !== undefined) {
|
|
32
|
+
return resolveResponse(r, input);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const text = echoText(input);
|
|
36
|
+
return {
|
|
37
|
+
text,
|
|
38
|
+
tokensIn: input.prompt.length,
|
|
39
|
+
tokensOut: text.length,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function echoText(input) {
|
|
44
|
+
const ctx = input.context ? `|ctx:${input.context}` : "";
|
|
45
|
+
const cap = input.maxTokens !== undefined ? `|cap:${input.maxTokens}` : "";
|
|
46
|
+
return `mock:${input.prompt}${ctx}${cap}`;
|
|
47
|
+
}
|
|
48
|
+
function resolveResponse(r, input) {
|
|
49
|
+
if (typeof r === "string") {
|
|
50
|
+
return {
|
|
51
|
+
text: r,
|
|
52
|
+
tokensIn: input.prompt.length,
|
|
53
|
+
tokensOut: r.length,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const result = r(input);
|
|
57
|
+
if (typeof result === "string") {
|
|
58
|
+
return {
|
|
59
|
+
text: result,
|
|
60
|
+
tokensIn: input.prompt.length,
|
|
61
|
+
tokensOut: result.length,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=MockProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MockProvider.js","sourceRoot":"","sources":["../../src/providers/MockProvider.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,wEAAwE;AACxE,0EAA0E;AAC1E,qEAAqE;AA2BrE,MAAM,OAAO,YAAY;IACd,EAAE,GAAG,MAAe,CAAC;IACrB,UAAU,CAAS;IAEX,QAAQ,CAAU;IAClB,UAAU,CAA+B;IACzC,MAAM,GAA4B,EAAE,CAAC;IAEtD,YAAY,OAA4B,EAAE;QACxC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,cAAc,CAAC;QACpD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;QACrC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;IACnC,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAA4B;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAExB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAChD,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBACpB,OAAO,eAAe,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO;YACL,IAAI;YACJ,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;YAC7B,SAAS,EAAE,IAAI,CAAC,MAAM;SACvB,CAAC;IACJ,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,KAA4B;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzD,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,QAAQ,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,eAAe,CACtB,CAAe,EACf,KAA4B;IAE5B,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,CAAC;YACP,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;YAC7B,SAAS,EAAE,CAAC,CAAC,MAAM;SACpB,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;YAC7B,SAAS,EAAE,MAAM,CAAC,MAAM;SACzB,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IProvider } from "./providers/IProvider.js";
|
|
2
|
+
import type { ComposerConfig, RoleName } from "./config/schema.js";
|
|
3
|
+
/**
|
|
4
|
+
* Wave 3 Step 4 — fallback when neither process.env.ANTHROPIC_MODEL
|
|
5
|
+
* nor composer.config.json role.model are provided. Tracks the current
|
|
6
|
+
* GLM family release (z.ai Anthropic-compat endpoint).
|
|
7
|
+
*/
|
|
8
|
+
export declare const DEFAULT_ANTHROPIC_MODEL = "glm-5.1";
|
|
9
|
+
export declare class ProviderNotImplementedError extends Error {
|
|
10
|
+
constructor(providerId: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class ProviderConfigError extends Error {
|
|
13
|
+
constructor(providerId: string, field: string);
|
|
14
|
+
}
|
|
15
|
+
export declare class ProviderRegistry {
|
|
16
|
+
private readonly config;
|
|
17
|
+
private readonly cache;
|
|
18
|
+
constructor(config: ComposerConfig);
|
|
19
|
+
getProviderForRole(role: RoleName): IProvider;
|
|
20
|
+
private buildProvider;
|
|
21
|
+
}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Wave 1 F1.4 — ProviderFactory / role → IProvider resolver.
|
|
2
|
+
//
|
|
3
|
+
// Day 2 (2026-05-23): 'anthropic' and 'cli' now wire to real adapters
|
|
4
|
+
// (F1.1 + F1.2). 'openai_compatible' still throws — YAGNI until a
|
|
5
|
+
// concrete need surfaces.
|
|
6
|
+
import { MockProvider } from "./providers/MockProvider.js";
|
|
7
|
+
import { AnthropicCompatibleProvider } from "./providers/AnthropicCompatibleProvider.js";
|
|
8
|
+
import { CLIProvider } from "./providers/CLIProvider.js";
|
|
9
|
+
/**
|
|
10
|
+
* Wave 3 Step 4 — fallback when neither process.env.ANTHROPIC_MODEL
|
|
11
|
+
* nor composer.config.json role.model are provided. Tracks the current
|
|
12
|
+
* GLM family release (z.ai Anthropic-compat endpoint).
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_ANTHROPIC_MODEL = "glm-5.1";
|
|
15
|
+
export class ProviderNotImplementedError extends Error {
|
|
16
|
+
constructor(providerId) {
|
|
17
|
+
super(`Provider '${providerId}' is not wired. Composer ships 'mock', 'anthropic', and 'cli' adapters; 'openai_compatible' is YAGNI until needed.`);
|
|
18
|
+
this.name = "ProviderNotImplementedError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class ProviderConfigError extends Error {
|
|
22
|
+
constructor(providerId, field) {
|
|
23
|
+
super(`Provider '${providerId}' requires '${field}' in composer.config.json (or its env var).`);
|
|
24
|
+
this.name = "ProviderConfigError";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class ProviderRegistry {
|
|
28
|
+
config;
|
|
29
|
+
cache = new Map();
|
|
30
|
+
constructor(config) {
|
|
31
|
+
this.config = config;
|
|
32
|
+
}
|
|
33
|
+
getProviderForRole(role) {
|
|
34
|
+
const cached = this.cache.get(role);
|
|
35
|
+
if (cached)
|
|
36
|
+
return cached;
|
|
37
|
+
const created = this.buildProvider(this.config.roles[role]);
|
|
38
|
+
this.cache.set(role, created);
|
|
39
|
+
return created;
|
|
40
|
+
}
|
|
41
|
+
buildProvider(roleConfig) {
|
|
42
|
+
switch (roleConfig.provider) {
|
|
43
|
+
case "mock":
|
|
44
|
+
return new MockProvider({ modelLabel: roleConfig.model });
|
|
45
|
+
case "anthropic": {
|
|
46
|
+
if (!roleConfig.baseUrl)
|
|
47
|
+
throw new ProviderConfigError("anthropic", "baseUrl");
|
|
48
|
+
if (!roleConfig.apiKeyEnv)
|
|
49
|
+
throw new ProviderConfigError("anthropic", "apiKeyEnv");
|
|
50
|
+
const apiKey = process.env[roleConfig.apiKeyEnv];
|
|
51
|
+
if (!apiKey) {
|
|
52
|
+
throw new ProviderConfigError("anthropic", `env var ${roleConfig.apiKeyEnv} (set it via .env.json or shell)`);
|
|
53
|
+
}
|
|
54
|
+
// Step 4 precedence: env > role.model > DEFAULT_ANTHROPIC_MODEL.
|
|
55
|
+
const envModel = process.env["ANTHROPIC_MODEL"];
|
|
56
|
+
const model = (typeof envModel === "string" && envModel.length > 0 ? envModel : undefined) ??
|
|
57
|
+
roleConfig.model ??
|
|
58
|
+
DEFAULT_ANTHROPIC_MODEL;
|
|
59
|
+
return new AnthropicCompatibleProvider({
|
|
60
|
+
baseUrl: roleConfig.baseUrl,
|
|
61
|
+
apiKey,
|
|
62
|
+
model,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
case "cli": {
|
|
66
|
+
if (!roleConfig.cli || roleConfig.cli.length === 0) {
|
|
67
|
+
throw new ProviderConfigError("cli", "cli (argv array)");
|
|
68
|
+
}
|
|
69
|
+
return new CLIProvider({
|
|
70
|
+
cli: roleConfig.cli,
|
|
71
|
+
model: roleConfig.model,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
case "openai_compatible":
|
|
75
|
+
throw new ProviderNotImplementedError(roleConfig.provider);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { ProviderRegistry } from "./registry.js";
|
|
3
|
+
export declare const COMPOSER_RESEARCH: "composer_research";
|
|
4
|
+
export declare const COMPOSER_CODE: "composer_code";
|
|
5
|
+
export declare const COMPOSER_REVIEW: "composer_review";
|
|
6
|
+
export declare function createComposerServer(registry: ProviderRegistry): McpServer;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Wave 1 F2.1 — factory for the Composer MCP server (per §8 Day 1).
|
|
2
|
+
// Pure function: takes a ProviderRegistry, returns an unconnected McpServer
|
|
3
|
+
// with the three C0.3 tools registered. Test code connects via
|
|
4
|
+
// InMemoryTransport; src/index.ts connects via StdioServerTransport.
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
// C0.3 — locked MCP tool names. Referenced by subagent allowlists +
|
|
8
|
+
// boundary_guard.sh; do not rename without a new ADR.
|
|
9
|
+
export const COMPOSER_RESEARCH = "composer_research";
|
|
10
|
+
export const COMPOSER_CODE = "composer_code";
|
|
11
|
+
export const COMPOSER_REVIEW = "composer_review";
|
|
12
|
+
const RESEARCH_DESCRIPTION = "MANDATORY for ALL research, documentation lookup, web search, and " +
|
|
13
|
+
"context gathering. The orchestrator MUST delegate research questions " +
|
|
14
|
+
"to this tool. Do not search or hypothesise in the main session.";
|
|
15
|
+
const CODE_DESCRIPTION = "MANDATORY for ALL code writing, refactoring, debugging, and " +
|
|
16
|
+
"implementation. The orchestrator MUST delegate implementation to this " +
|
|
17
|
+
"tool. Do not write code in the main session.";
|
|
18
|
+
const REVIEW_DESCRIPTION = "MANDATORY for ALL code review, diff critique, and finding bugs in " +
|
|
19
|
+
"candidate patches. The orchestrator MUST delegate review to this tool " +
|
|
20
|
+
"before integrating worker output.";
|
|
21
|
+
export function createComposerServer(registry) {
|
|
22
|
+
const server = new McpServer({
|
|
23
|
+
name: "composer",
|
|
24
|
+
version: "0.0.0",
|
|
25
|
+
});
|
|
26
|
+
// Per advisor pass 2026-05-23: tool annotations signal behaviour to the
|
|
27
|
+
// orchestrator without changing execution. readOnlyHint / openWorldHint /
|
|
28
|
+
// destructiveHint / idempotentHint are append-only per ADR 0001.
|
|
29
|
+
server.registerTool(COMPOSER_RESEARCH, {
|
|
30
|
+
description: RESEARCH_DESCRIPTION,
|
|
31
|
+
inputSchema: {
|
|
32
|
+
prompt: z.string().min(1),
|
|
33
|
+
context: z.string().optional(),
|
|
34
|
+
},
|
|
35
|
+
annotations: {
|
|
36
|
+
title: "Composer Research",
|
|
37
|
+
readOnlyHint: true,
|
|
38
|
+
openWorldHint: true,
|
|
39
|
+
destructiveHint: false,
|
|
40
|
+
idempotentHint: false,
|
|
41
|
+
},
|
|
42
|
+
}, async ({ prompt, context }) => {
|
|
43
|
+
const provider = registry.getProviderForRole("researcher");
|
|
44
|
+
const result = await provider.execute({ prompt, context });
|
|
45
|
+
return { content: [{ type: "text", text: result.text }] };
|
|
46
|
+
});
|
|
47
|
+
server.registerTool(COMPOSER_CODE, {
|
|
48
|
+
description: CODE_DESCRIPTION,
|
|
49
|
+
inputSchema: {
|
|
50
|
+
prompt: z.string().min(1),
|
|
51
|
+
context: z.string().optional(),
|
|
52
|
+
},
|
|
53
|
+
annotations: {
|
|
54
|
+
title: "Composer Code",
|
|
55
|
+
readOnlyHint: false,
|
|
56
|
+
openWorldHint: false,
|
|
57
|
+
destructiveHint: false,
|
|
58
|
+
idempotentHint: false,
|
|
59
|
+
},
|
|
60
|
+
}, async ({ prompt, context }) => {
|
|
61
|
+
const provider = registry.getProviderForRole("coder");
|
|
62
|
+
const result = await provider.execute({ prompt, context });
|
|
63
|
+
return { content: [{ type: "text", text: result.text }] };
|
|
64
|
+
});
|
|
65
|
+
server.registerTool(COMPOSER_REVIEW, {
|
|
66
|
+
description: REVIEW_DESCRIPTION,
|
|
67
|
+
inputSchema: {
|
|
68
|
+
prompt: z.string().min(1),
|
|
69
|
+
diff: z.string().min(1),
|
|
70
|
+
},
|
|
71
|
+
annotations: {
|
|
72
|
+
title: "Composer Review",
|
|
73
|
+
readOnlyHint: true,
|
|
74
|
+
openWorldHint: false,
|
|
75
|
+
destructiveHint: false,
|
|
76
|
+
idempotentHint: true,
|
|
77
|
+
},
|
|
78
|
+
}, async ({ prompt, diff }) => {
|
|
79
|
+
const provider = registry.getProviderForRole("reviewer");
|
|
80
|
+
const result = await provider.execute({ prompt, context: diff });
|
|
81
|
+
return { content: [{ type: "text", text: result.text }] };
|
|
82
|
+
});
|
|
83
|
+
return server;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function slugify(text: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slug.js","sourceRoot":"","sources":["../../src/util/slug.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-composer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Multi-agent orchestration MCP server. Claude orchestrates; GLM and agy do the work.",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agent-composer": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/",
|
|
11
|
+
"composer.config.schema.json",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./schema": "./composer.config.schema.json"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc && node scripts/postbuild.mjs",
|
|
26
|
+
"start": "tsx src/index.ts",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
30
|
+
"lint": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
31
|
+
"test:hooks": "bash tests/hooks/run.sh",
|
|
32
|
+
"test:scripts": "bash tests/scripts/run.sh",
|
|
33
|
+
"test:all": "npm run test && npm run test:hooks && npm run test:scripts",
|
|
34
|
+
"usage": "npx -y ccusage daily",
|
|
35
|
+
"schema:lint": "ajv compile --strict=true -c ajv-formats -s composer.config.schema.json && ajv validate --strict=false -c ajv-formats -s composer.config.schema.json -d composer.config.json && ajv compile --strict=true -s plugin.schema.json && ajv validate --strict=true -s plugin.schema.json -d 'plugin/*/plugin.json'",
|
|
36
|
+
"prepublishOnly": "npm run lint && npm run test && npm run build && npm run schema:lint"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@anthropic-ai/sdk": "^0.98.0",
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
41
|
+
"dotenv": "^17.4.2",
|
|
42
|
+
"zod": "^4.4.3"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^25.9.1",
|
|
46
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
47
|
+
"ajv-cli": "^5.0.0",
|
|
48
|
+
"ajv-formats": "^3.0.1",
|
|
49
|
+
"tsx": "^4.22.3",
|
|
50
|
+
"typescript": "^6.0.3",
|
|
51
|
+
"vitest": "^4.1.7"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18.17.0"
|
|
55
|
+
}
|
|
56
|
+
}
|