zidane 5.13.4 → 5.13.5
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/dist/{acp-BqIU2mo-.js → acp-CJ1yHdpK.js} +467 -16
- package/dist/acp-CJ1yHdpK.js.map +1 -0
- package/dist/acp-cli.js +24 -340
- package/dist/acp-cli.js.map +1 -1
- package/dist/acp.d.ts +10 -1
- package/dist/acp.d.ts.map +1 -1
- package/dist/acp.js +1 -1
- package/docs/ACP.md +31 -0
- package/package.json +1 -1
- package/dist/acp-BqIU2mo-.js.map +0 -1
|
@@ -7,8 +7,10 @@ import { l as errorMessage } from "./errors-BpPfMo_4.js";
|
|
|
7
7
|
import { t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
|
|
8
8
|
import { i as basic_default } from "./presets-HDIxliiq.js";
|
|
9
9
|
import { r as loadSession, t as createSession } from "./session-BDWZZaYa.js";
|
|
10
|
-
import { resolve } from "node:path";
|
|
10
|
+
import { basename, resolve } from "node:path";
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
11
12
|
import { Buffer } from "node:buffer";
|
|
13
|
+
import { parseArgs } from "node:util";
|
|
12
14
|
//#region src/acp/json-rpc.ts
|
|
13
15
|
function createJsonRpcConnection(options) {
|
|
14
16
|
let nextId = 1;
|
|
@@ -183,6 +185,342 @@ function isObject$1(value) {
|
|
|
183
185
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
184
186
|
}
|
|
185
187
|
//#endregion
|
|
188
|
+
//#region src/start/shared-options.ts
|
|
189
|
+
const validThinkingLevels = [
|
|
190
|
+
"off",
|
|
191
|
+
"minimal",
|
|
192
|
+
"low",
|
|
193
|
+
"medium",
|
|
194
|
+
"high",
|
|
195
|
+
"xhigh",
|
|
196
|
+
"max",
|
|
197
|
+
"adaptive"
|
|
198
|
+
];
|
|
199
|
+
const startProviderNames = [
|
|
200
|
+
"anthropic",
|
|
201
|
+
"openai",
|
|
202
|
+
"openrouter",
|
|
203
|
+
"cerebras",
|
|
204
|
+
"xai",
|
|
205
|
+
"arcee",
|
|
206
|
+
"baseten",
|
|
207
|
+
"local",
|
|
208
|
+
"openai-compat"
|
|
209
|
+
];
|
|
210
|
+
const startPresetNames = ["basic"];
|
|
211
|
+
const startFormatNames = ["zidane", "provider"];
|
|
212
|
+
var StartUsageError = class extends Error {
|
|
213
|
+
constructor(message) {
|
|
214
|
+
super(message);
|
|
215
|
+
this.name = "StartUsageError";
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* The shared `bun start` / `zidane run` option table. Exported so
|
|
220
|
+
* `parseStartArgs` (start CLI) can compose it with the Restate-only options
|
|
221
|
+
* and parse argv ONCE — two diverging tables would let new flags silently
|
|
222
|
+
* drift between the two parsers.
|
|
223
|
+
*/
|
|
224
|
+
const startLocalArgOptions = {
|
|
225
|
+
"help": {
|
|
226
|
+
type: "boolean",
|
|
227
|
+
short: "h",
|
|
228
|
+
default: false
|
|
229
|
+
},
|
|
230
|
+
"prompt": {
|
|
231
|
+
type: "string",
|
|
232
|
+
short: "p"
|
|
233
|
+
},
|
|
234
|
+
"model": {
|
|
235
|
+
type: "string",
|
|
236
|
+
short: "m"
|
|
237
|
+
},
|
|
238
|
+
"preset": {
|
|
239
|
+
type: "string",
|
|
240
|
+
short: "t",
|
|
241
|
+
default: "basic"
|
|
242
|
+
},
|
|
243
|
+
"system": {
|
|
244
|
+
type: "string",
|
|
245
|
+
short: "s"
|
|
246
|
+
},
|
|
247
|
+
"thinking": {
|
|
248
|
+
type: "string",
|
|
249
|
+
default: "off"
|
|
250
|
+
},
|
|
251
|
+
"provider": {
|
|
252
|
+
type: "string",
|
|
253
|
+
default: "anthropic"
|
|
254
|
+
},
|
|
255
|
+
"base-url": { type: "string" },
|
|
256
|
+
"api-key-env": { type: "string" },
|
|
257
|
+
"headers-env": { type: "string" },
|
|
258
|
+
"header": {
|
|
259
|
+
type: "string",
|
|
260
|
+
multiple: true
|
|
261
|
+
},
|
|
262
|
+
"vision": { type: "boolean" },
|
|
263
|
+
"image-in-tool-result": { type: "boolean" },
|
|
264
|
+
"temperature": { type: "string" },
|
|
265
|
+
"seed": { type: "string" },
|
|
266
|
+
"context": {
|
|
267
|
+
type: "string",
|
|
268
|
+
short: "c",
|
|
269
|
+
default: "process"
|
|
270
|
+
},
|
|
271
|
+
"image": { type: "string" },
|
|
272
|
+
"cwd": { type: "string" },
|
|
273
|
+
"env": {
|
|
274
|
+
type: "string",
|
|
275
|
+
multiple: true
|
|
276
|
+
},
|
|
277
|
+
"pass-env": {
|
|
278
|
+
type: "string",
|
|
279
|
+
multiple: true
|
|
280
|
+
},
|
|
281
|
+
"pregame": { type: "string" },
|
|
282
|
+
"sandbox": { type: "string" },
|
|
283
|
+
"sandbox-on-destroy": { type: "string" },
|
|
284
|
+
"mcp": { type: "string" },
|
|
285
|
+
"session-db": { type: "string" },
|
|
286
|
+
"session-id": { type: "string" },
|
|
287
|
+
"json": {
|
|
288
|
+
type: "boolean",
|
|
289
|
+
default: false
|
|
290
|
+
},
|
|
291
|
+
"stream-json": {
|
|
292
|
+
type: "boolean",
|
|
293
|
+
default: false
|
|
294
|
+
},
|
|
295
|
+
"format": {
|
|
296
|
+
type: "string",
|
|
297
|
+
default: "zidane"
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* Strict argv parse shared by the start CLIs. `strict: true` rejects unknown
|
|
302
|
+
* flags and stray positionals loudly — without it, a typo'd flag's value
|
|
303
|
+
* silently leaks into the run (e.g. as a bogus prompt). Parse failures are
|
|
304
|
+
* rethrown as {@link StartUsageError}.
|
|
305
|
+
*/
|
|
306
|
+
function parseStartArgValues(argv, options) {
|
|
307
|
+
try {
|
|
308
|
+
const { values } = parseArgs({
|
|
309
|
+
args: [...argv],
|
|
310
|
+
options,
|
|
311
|
+
strict: true
|
|
312
|
+
});
|
|
313
|
+
return values;
|
|
314
|
+
} catch (err) {
|
|
315
|
+
throw new StartUsageError(`${err instanceof Error ? err.message : String(err)}\n\nRun with --help for usage.`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/** Assemble {@link StartLocalOptions} from already-parsed argv values. */
|
|
319
|
+
function buildStartLocalOptions(values, config = {}) {
|
|
320
|
+
const { requirePrompt = true, usage = startLocalUsage } = config;
|
|
321
|
+
if (values.help === true) throw new StartUsageError(usage());
|
|
322
|
+
const prompt = values.prompt;
|
|
323
|
+
if (requirePrompt && (!prompt || prompt.trim() === "")) throw new StartUsageError(usage());
|
|
324
|
+
const thinkingRaw = values.thinking || "off";
|
|
325
|
+
if (!validThinkingLevels.includes(thinkingRaw)) throw new Error(`Unknown thinking level: ${thinkingRaw}. Available: ${validThinkingLevels.join(", ")}`);
|
|
326
|
+
const provider = values.provider || "anthropic";
|
|
327
|
+
if (!startProviderNames.includes(provider)) throw new Error(`Unknown provider: ${provider}. Available: ${startProviderNames.join(", ")}`);
|
|
328
|
+
const preset = values.preset || "basic";
|
|
329
|
+
if (!startPresetNames.includes(preset)) throw new Error(`Unknown preset: ${preset}. Available: ${startPresetNames.join(", ")}`);
|
|
330
|
+
if (values.json === true && values["stream-json"] === true) throw new StartUsageError("Use either `--json` or `--stream-json`, not both.");
|
|
331
|
+
const format = values.format || "zidane";
|
|
332
|
+
if (!startFormatNames.includes(format)) throw new Error(`Unknown format: ${format}. Available: ${startFormatNames.join(", ")}`);
|
|
333
|
+
const baseURL = values["base-url"];
|
|
334
|
+
const apiKeyEnv = values["api-key-env"];
|
|
335
|
+
const headersEnv = values["headers-env"];
|
|
336
|
+
const extraHeaders = parseHeaderArgs(values.header, "--header");
|
|
337
|
+
const temperature = parseOptionalNumber(values.temperature, "--temperature");
|
|
338
|
+
const seed = parseOptionalInteger(values.seed, "--seed");
|
|
339
|
+
const env = parseEnvArgs(values.env, values["pass-env"]);
|
|
340
|
+
const context = values.context || "process";
|
|
341
|
+
const pregame = loadPregame(values.pregame, context);
|
|
342
|
+
const sandboxId = resolveSandboxId(values.sandbox, context);
|
|
343
|
+
const sandboxOnDestroy = resolveSandboxOnDestroy(values["sandbox-on-destroy"], context);
|
|
344
|
+
return {
|
|
345
|
+
system: values.system,
|
|
346
|
+
prompt: prompt ?? "",
|
|
347
|
+
model: values.model,
|
|
348
|
+
...baseURL !== void 0 ? { baseURL } : {},
|
|
349
|
+
...apiKeyEnv !== void 0 ? { apiKeyEnv } : {},
|
|
350
|
+
...headersEnv !== void 0 ? { headersEnv } : {},
|
|
351
|
+
...Object.keys(extraHeaders).length > 0 ? { extraHeaders } : {},
|
|
352
|
+
...values.vision === true ? { vision: true } : {},
|
|
353
|
+
...values["image-in-tool-result"] === true ? { imageInToolResult: true } : {},
|
|
354
|
+
...temperature !== void 0 ? { temperature } : {},
|
|
355
|
+
...seed !== void 0 ? { seed } : {},
|
|
356
|
+
preset,
|
|
357
|
+
thinking: thinkingRaw,
|
|
358
|
+
provider,
|
|
359
|
+
context,
|
|
360
|
+
image: values.image,
|
|
361
|
+
cwd: values.cwd,
|
|
362
|
+
...Object.keys(env).length > 0 ? { env } : {},
|
|
363
|
+
...pregame ? { pregame } : {},
|
|
364
|
+
...sandboxId ? { sandboxId } : {},
|
|
365
|
+
...sandboxOnDestroy ? { sandboxOnDestroy } : {},
|
|
366
|
+
mcp: parseMcpConfig(values.mcp),
|
|
367
|
+
sessionDb: values["session-db"],
|
|
368
|
+
sessionId: values["session-id"],
|
|
369
|
+
json: values.json === true,
|
|
370
|
+
streamJson: values["stream-json"] === true,
|
|
371
|
+
format
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function startLocalUsage() {
|
|
375
|
+
return [
|
|
376
|
+
`Usage: bun start --prompt "your message" \\`,
|
|
377
|
+
` [--provider ${startProviderNames.join("|")}] [--model <id>] [--thinking ${validThinkingLevels.join("|")}]`,
|
|
378
|
+
` [--base-url <url>] [--api-key-env <NAME>] [--headers-env <NAME>] [--header 'Name: value']`,
|
|
379
|
+
` [--vision] [--image-in-tool-result] [--temperature <f>] [--seed <n>]`,
|
|
380
|
+
` [--context process|docker|e2b|daytona] [--image node:22] [--cwd /workspace]`,
|
|
381
|
+
` [--env KEY=VALUE ...] [--pass-env VARNAME ...] [--pregame setup.sh] [--sandbox <id>] [--sandbox-on-destroy kill|pause|leave]`,
|
|
382
|
+
` [--mcp '[...]'] [--session-db ./sessions.db] [--session-id <id>] [--json|--stream-json] [--format zidane|provider]`,
|
|
383
|
+
``,
|
|
384
|
+
` --stream-json streams COMPLETE TURNS as JSONL (one line per turn), then the result.`,
|
|
385
|
+
` For the full event stream (text deltas, tool calls, …) use the headless CLI's`,
|
|
386
|
+
` --output-format stream-json instead.`
|
|
387
|
+
].join("\n");
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Parse the `--mcp` argument: inline JSON (object or array) or a path to a JSON
|
|
391
|
+
* file. Validates that each server declares the fields its transport requires.
|
|
392
|
+
*/
|
|
393
|
+
function parseMcpConfig(raw) {
|
|
394
|
+
if (!raw) return void 0;
|
|
395
|
+
let text = raw.trim();
|
|
396
|
+
if (!text.startsWith("[") && !text.startsWith("{")) text = readFileSync(text, "utf8");
|
|
397
|
+
const parsed = JSON.parse(text);
|
|
398
|
+
const configs = Array.isArray(parsed) ? parsed : [parsed];
|
|
399
|
+
for (const config of configs) {
|
|
400
|
+
if (!config.name || !config.transport) throw new Error(`Invalid MCP config: each server needs "name" and "transport". Got: ${JSON.stringify(config)}`);
|
|
401
|
+
if (config.transport === "stdio" && !config.command) throw new Error(`MCP server "${config.name}": stdio transport requires "command"`);
|
|
402
|
+
if ((config.transport === "sse" || config.transport === "streamable-http") && !config.url) throw new Error(`MCP server "${config.name}": ${config.transport} transport requires "url"`);
|
|
403
|
+
}
|
|
404
|
+
return configs;
|
|
405
|
+
}
|
|
406
|
+
function parseOptionalNumber(raw, flag) {
|
|
407
|
+
if (raw === void 0) return void 0;
|
|
408
|
+
const value = Number(raw);
|
|
409
|
+
if (Number.isNaN(value)) throw new Error(`${flag} must be a number, got '${raw}'.`);
|
|
410
|
+
return value;
|
|
411
|
+
}
|
|
412
|
+
function parseOptionalInteger(raw, flag) {
|
|
413
|
+
if (raw === void 0) return void 0;
|
|
414
|
+
const value = Number(raw);
|
|
415
|
+
if (!Number.isInteger(value)) throw new Error(`${flag} must be an integer, got '${raw}'.`);
|
|
416
|
+
return value;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Build the execution-context environment from `--pass-env VARNAME` (forward
|
|
420
|
+
* the named variable from the current shell) and `--env KEY=VALUE` (set a
|
|
421
|
+
* value explicitly). `--pass-env` is applied first so an explicit `--env`
|
|
422
|
+
* wins when both name the same key. An unset `--pass-env` variable is a hard
|
|
423
|
+
* error rather than a silently-empty value.
|
|
424
|
+
*/
|
|
425
|
+
function parseEnvArgs(envArgs, passEnvArgs, source = process.env) {
|
|
426
|
+
const env = {};
|
|
427
|
+
for (const name of passEnvArgs ?? []) {
|
|
428
|
+
const key = name.trim();
|
|
429
|
+
if (!key) throw new Error("--pass-env requires a variable name.");
|
|
430
|
+
const value = source[key];
|
|
431
|
+
if (value === void 0) throw new Error(`--pass-env ${key}: environment variable ${key} is not set.`);
|
|
432
|
+
env[key] = value;
|
|
433
|
+
}
|
|
434
|
+
for (const item of envArgs ?? []) {
|
|
435
|
+
const eq = item.indexOf("=");
|
|
436
|
+
const key = eq === -1 ? "" : item.slice(0, eq).trim();
|
|
437
|
+
if (!key) throw new Error(`--env must be formatted as KEY=VALUE, got '${item}'.`);
|
|
438
|
+
env[key] = item.slice(eq + 1);
|
|
439
|
+
}
|
|
440
|
+
return env;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Resolve the `--pregame <file>` setup script. Returns `undefined` when no path
|
|
444
|
+
* is given. The script only runs in remote sandbox contexts (it's uploaded into
|
|
445
|
+
* the ready sandbox before prompting); for any other context this warns and
|
|
446
|
+
* ignores it rather than failing. For supported contexts the file is read
|
|
447
|
+
* eagerly — consistent with `--prompt-file`/`--schema` — so a missing or
|
|
448
|
+
* unreadable file surfaces as a usage error up front rather than mid-spawn.
|
|
449
|
+
* The returned `name` is the basename used for the uploaded file.
|
|
450
|
+
*/
|
|
451
|
+
function loadPregame(path, context) {
|
|
452
|
+
if (!path) return void 0;
|
|
453
|
+
if (!supportsRemoteSandboxFlags(context)) {
|
|
454
|
+
console.error(`--pregame is only supported with --context e2b or daytona; ignoring it for context '${context}'.`);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
let content;
|
|
458
|
+
try {
|
|
459
|
+
content = readFileSync(path, "utf8");
|
|
460
|
+
} catch (err) {
|
|
461
|
+
throw new Error(`--pregame: failed to read '${path}': ${err.message}`);
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
name: basename(path),
|
|
465
|
+
content
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Resolve the `--sandbox <id>` argument. Returns `undefined` when no id is
|
|
470
|
+
* given. Connecting to a pre-existing sandbox is supported by the remote
|
|
471
|
+
* sandbox providers; for any other context this warns and ignores it rather
|
|
472
|
+
* than failing, mirroring {@link loadPregame}. A blank value (e.g.
|
|
473
|
+
* `--sandbox ''`) is treated as absent.
|
|
474
|
+
*/
|
|
475
|
+
function resolveSandboxId(raw, context) {
|
|
476
|
+
const id = raw?.trim();
|
|
477
|
+
if (!id) return void 0;
|
|
478
|
+
if (!supportsRemoteSandboxFlags(context)) {
|
|
479
|
+
console.error(`--sandbox is only supported with --context e2b or daytona; ignoring it for context '${context}'.`);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
return id;
|
|
483
|
+
}
|
|
484
|
+
const validSandboxOnDestroyValues = [
|
|
485
|
+
"kill",
|
|
486
|
+
"pause",
|
|
487
|
+
"leave"
|
|
488
|
+
];
|
|
489
|
+
/**
|
|
490
|
+
* Resolve the `--sandbox-on-destroy kill|pause|leave` argument. Returns
|
|
491
|
+
* `undefined` when not set (the provider defaults to `'kill'` / delete).
|
|
492
|
+
* Applies to remote sandbox contexts; warns and ignores for any other context,
|
|
493
|
+
* mirroring {@link resolveSandboxId} and {@link loadPregame}.
|
|
494
|
+
*/
|
|
495
|
+
function resolveSandboxOnDestroy(raw, context) {
|
|
496
|
+
const value = raw?.trim();
|
|
497
|
+
if (!value) return void 0;
|
|
498
|
+
if (!supportsRemoteSandboxFlags(context)) {
|
|
499
|
+
console.error(`--sandbox-on-destroy is only supported with --context e2b or daytona; ignoring it for context '${context}'.`);
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (!validSandboxOnDestroyValues.includes(value)) throw new StartUsageError(`--sandbox-on-destroy must be kill|pause|leave, got '${value}'.`);
|
|
503
|
+
return value;
|
|
504
|
+
}
|
|
505
|
+
function supportsRemoteSandboxFlags(context) {
|
|
506
|
+
return context === "e2b" || context === "daytona";
|
|
507
|
+
}
|
|
508
|
+
function parseHeaderArgs(raw, flag) {
|
|
509
|
+
if (!raw || raw.length === 0) return {};
|
|
510
|
+
const headers = {};
|
|
511
|
+
for (const item of raw) {
|
|
512
|
+
const colon = item.indexOf(":");
|
|
513
|
+
const equals = item.indexOf("=");
|
|
514
|
+
const separator = colon === -1 ? equals : equals === -1 ? colon : Math.min(colon, equals);
|
|
515
|
+
if (separator <= 0) throw new Error(`${flag} must be formatted as "Name: value" or "Name=value".`);
|
|
516
|
+
const name = item.slice(0, separator).trim();
|
|
517
|
+
const value = item.slice(separator + 1).trim();
|
|
518
|
+
if (!name || !value) throw new Error(`${flag} must include both a header name and value.`);
|
|
519
|
+
headers[name] = value;
|
|
520
|
+
}
|
|
521
|
+
return headers;
|
|
522
|
+
}
|
|
523
|
+
//#endregion
|
|
186
524
|
//#region src/acp/mapping.ts
|
|
187
525
|
function acpMcpServersToZidane(servers) {
|
|
188
526
|
if (!servers) return [];
|
|
@@ -635,6 +973,9 @@ function seedReadState(ctx, path, content, offset, limit) {
|
|
|
635
973
|
//#region src/acp/server.ts
|
|
636
974
|
const ACP_AGENT_VERSION = "1";
|
|
637
975
|
const MODEL_CONFIG_ID = "model";
|
|
976
|
+
const MODE_CONFIG_ID = "mode";
|
|
977
|
+
const THINKING_CONFIG_ID = "thinking";
|
|
978
|
+
const MODEL_OPTION_CONFIG_PREFIX = "model_option:";
|
|
638
979
|
const DEFAULT_PERMISSION_OPTIONS = [
|
|
639
980
|
{
|
|
640
981
|
optionId: "allow_once",
|
|
@@ -689,18 +1030,35 @@ var AcpServerImpl = class {
|
|
|
689
1030
|
return ((this.options.model ? this.modelChoices.find((choice) => choice.id === this.options.model || choice.model === this.options.model) : void 0) ?? this.modelChoices[0]).id;
|
|
690
1031
|
}
|
|
691
1032
|
buildDefaultConfigOptions(userConfig) {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
id:
|
|
695
|
-
name: "
|
|
1033
|
+
const reserved = new Set([MODE_CONFIG_ID]);
|
|
1034
|
+
const options = [{
|
|
1035
|
+
id: MODE_CONFIG_ID,
|
|
1036
|
+
name: "Mode",
|
|
696
1037
|
type: "select",
|
|
697
|
-
category: "
|
|
698
|
-
currentValue: this.
|
|
699
|
-
options: this.
|
|
700
|
-
value:
|
|
701
|
-
name:
|
|
1038
|
+
category: "mode",
|
|
1039
|
+
currentValue: this.defaultModeId,
|
|
1040
|
+
options: this.modes.map((mode) => ({
|
|
1041
|
+
value: mode.id,
|
|
1042
|
+
name: mode.name,
|
|
1043
|
+
...mode.description ? { description: mode.description } : {}
|
|
702
1044
|
}))
|
|
703
|
-
}
|
|
1045
|
+
}];
|
|
1046
|
+
if (this.modelChoices.length > 0) {
|
|
1047
|
+
reserved.add(MODEL_CONFIG_ID);
|
|
1048
|
+
options.push({
|
|
1049
|
+
id: MODEL_CONFIG_ID,
|
|
1050
|
+
name: "Model",
|
|
1051
|
+
type: "select",
|
|
1052
|
+
category: "model",
|
|
1053
|
+
currentValue: this.defaultModelChoiceId,
|
|
1054
|
+
options: this.modelChoices.map((choice) => ({
|
|
1055
|
+
value: choice.id,
|
|
1056
|
+
name: choice.name ?? choice.model
|
|
1057
|
+
}))
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
options.push(...this.modelDependentConfigOptions(this.defaultModelChoiceId));
|
|
1061
|
+
return [...options, ...userConfig.filter((option) => !reserved.has(option.id) && !isGeneratedModelOptionConfig(option.id) && option.id !== THINKING_CONFIG_ID)];
|
|
704
1062
|
}
|
|
705
1063
|
providerForChoiceId(id) {
|
|
706
1064
|
const choice = this.modelChoices.find((candidate) => candidate.id === id);
|
|
@@ -911,6 +1269,7 @@ var AcpServerImpl = class {
|
|
|
911
1269
|
stats = await runtime.agent.run({
|
|
912
1270
|
prompt: mapped.prompt,
|
|
913
1271
|
...runtime.runModel ? { model: runtime.runModel } : {},
|
|
1272
|
+
...this.runConfig(runtime),
|
|
914
1273
|
...this.options.system ? { system: this.options.system } : {},
|
|
915
1274
|
signal: abortController.signal
|
|
916
1275
|
});
|
|
@@ -938,21 +1297,33 @@ var AcpServerImpl = class {
|
|
|
938
1297
|
}
|
|
939
1298
|
async setMode(params) {
|
|
940
1299
|
const runtime = this.requireSession(params.sessionId);
|
|
941
|
-
|
|
942
|
-
runtime.modeId = params.modeId;
|
|
1300
|
+
const configOptions = this.selectMode(runtime, params.modeId);
|
|
943
1301
|
await this.sessionUpdate(params.sessionId, {
|
|
944
1302
|
sessionUpdate: "current_mode_update",
|
|
945
1303
|
currentModeId: params.modeId
|
|
946
1304
|
});
|
|
1305
|
+
await this.sessionUpdate(params.sessionId, {
|
|
1306
|
+
sessionUpdate: "config_option_update",
|
|
1307
|
+
configOptions
|
|
1308
|
+
});
|
|
947
1309
|
return {};
|
|
948
1310
|
}
|
|
949
1311
|
async setConfigOption(params) {
|
|
950
1312
|
const runtime = this.requireSession(params.sessionId);
|
|
951
1313
|
const isModelSwitch = this.modelChoices.length > 0 && params.configId === MODEL_CONFIG_ID;
|
|
1314
|
+
const isModeSwitch = params.configId === MODE_CONFIG_ID;
|
|
952
1315
|
if (isModelSwitch && runtime.inFlight) throw new AcpProtocolError(-32600, "Cannot switch model while a prompt is in flight.");
|
|
953
|
-
|
|
1316
|
+
let configOptions = this.applyConfigSelection(runtime, params.configId, params.value);
|
|
954
1317
|
if (isModelSwitch) this.selectModel(runtime, params.value);
|
|
1318
|
+
if (isModeSwitch) {
|
|
1319
|
+
runtime.modeId = params.value;
|
|
1320
|
+
await this.sessionUpdate(params.sessionId, {
|
|
1321
|
+
sessionUpdate: "current_mode_update",
|
|
1322
|
+
currentModeId: params.value
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
955
1325
|
runtime.config.set(params.configId, params.value);
|
|
1326
|
+
if (isModelSwitch) configOptions = runtime.configOptions;
|
|
956
1327
|
await this.sessionUpdate(params.sessionId, {
|
|
957
1328
|
sessionUpdate: "config_option_update",
|
|
958
1329
|
configOptions
|
|
@@ -969,6 +1340,74 @@ var AcpServerImpl = class {
|
|
|
969
1340
|
if (!choice) throw new AcpProtocolError(-32602, `Unknown model: ${choiceId}`);
|
|
970
1341
|
runtime.setProviderDelegate?.(this.providerForChoiceId(choice.id));
|
|
971
1342
|
runtime.runModel = choice.model;
|
|
1343
|
+
this.refreshModelDependentConfigOptions(runtime, choice.id);
|
|
1344
|
+
}
|
|
1345
|
+
selectMode(runtime, modeId) {
|
|
1346
|
+
if (!this.modes.some((mode) => mode.id === modeId)) throw new AcpProtocolError(-32602, `Unknown mode: ${modeId}`);
|
|
1347
|
+
runtime.modeId = modeId;
|
|
1348
|
+
return this.applyConfigSelection(runtime, MODE_CONFIG_ID, modeId);
|
|
1349
|
+
}
|
|
1350
|
+
runConfig(runtime) {
|
|
1351
|
+
const thinking = configValue(runtime.configOptions, THINKING_CONFIG_ID);
|
|
1352
|
+
const modelOptions = {};
|
|
1353
|
+
for (const option of runtime.configOptions) {
|
|
1354
|
+
if (!isGeneratedModelOptionConfig(option.id) || option.currentValue !== "on") continue;
|
|
1355
|
+
modelOptions[option.id.slice(13)] = true;
|
|
1356
|
+
}
|
|
1357
|
+
return {
|
|
1358
|
+
...isThinkingLevel(thinking) ? { thinking } : {},
|
|
1359
|
+
...Object.keys(modelOptions).length > 0 ? { modelOptions } : {}
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
refreshModelDependentConfigOptions(runtime, choiceId) {
|
|
1363
|
+
const insertAfter = (option) => option.id === MODEL_CONFIG_ID;
|
|
1364
|
+
const base = runtime.configOptions.filter((option) => option.id !== THINKING_CONFIG_ID && !isGeneratedModelOptionConfig(option.id));
|
|
1365
|
+
const generated = this.modelDependentConfigOptions(choiceId, runtime.config);
|
|
1366
|
+
const index = base.findIndex(insertAfter);
|
|
1367
|
+
runtime.configOptions = index === -1 ? [...base, ...generated] : [
|
|
1368
|
+
...base.slice(0, index + 1),
|
|
1369
|
+
...generated,
|
|
1370
|
+
...base.slice(index + 1)
|
|
1371
|
+
];
|
|
1372
|
+
}
|
|
1373
|
+
modelDependentConfigOptions(choiceId, previous) {
|
|
1374
|
+
if (!choiceId) return [];
|
|
1375
|
+
const choice = this.modelChoices.find((candidate) => candidate.id === choiceId);
|
|
1376
|
+
if (!choice) return [];
|
|
1377
|
+
const options = [];
|
|
1378
|
+
if (choice.reasoning === true) {
|
|
1379
|
+
const current = previous?.get(THINKING_CONFIG_ID);
|
|
1380
|
+
options.push({
|
|
1381
|
+
id: THINKING_CONFIG_ID,
|
|
1382
|
+
name: "Thinking",
|
|
1383
|
+
type: "select",
|
|
1384
|
+
category: "thought_level",
|
|
1385
|
+
currentValue: isThinkingLevel(current) ? current : "off",
|
|
1386
|
+
options: validThinkingLevels.map((level) => ({
|
|
1387
|
+
value: level,
|
|
1388
|
+
name: thinkingLabel(level)
|
|
1389
|
+
}))
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
for (const option of choice.options ?? []) {
|
|
1393
|
+
const id = `${MODEL_OPTION_CONFIG_PREFIX}${option.id}`;
|
|
1394
|
+
const current = previous?.get(id);
|
|
1395
|
+
options.push({
|
|
1396
|
+
id,
|
|
1397
|
+
name: option.label,
|
|
1398
|
+
type: "select",
|
|
1399
|
+
currentValue: current === "on" ? "on" : "off",
|
|
1400
|
+
...option.description ? { description: option.description } : {},
|
|
1401
|
+
options: [{
|
|
1402
|
+
value: "off",
|
|
1403
|
+
name: "Off"
|
|
1404
|
+
}, {
|
|
1405
|
+
value: "on",
|
|
1406
|
+
name: "On"
|
|
1407
|
+
}]
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
return options;
|
|
972
1411
|
}
|
|
973
1412
|
/** Reflect a `select` choice back into the advertised option set's `currentValue`. */
|
|
974
1413
|
applyConfigSelection(runtime, configId, value) {
|
|
@@ -1323,6 +1762,18 @@ function configOptionHasValue(option, value) {
|
|
|
1323
1762
|
} else if (item.value === value) return true;
|
|
1324
1763
|
return false;
|
|
1325
1764
|
}
|
|
1765
|
+
function configValue(options, id) {
|
|
1766
|
+
return options.find((option) => option.id === id)?.currentValue;
|
|
1767
|
+
}
|
|
1768
|
+
function isGeneratedModelOptionConfig(id) {
|
|
1769
|
+
return id.startsWith(MODEL_OPTION_CONFIG_PREFIX);
|
|
1770
|
+
}
|
|
1771
|
+
function isThinkingLevel(value) {
|
|
1772
|
+
return typeof value === "string" && validThinkingLevels.includes(value);
|
|
1773
|
+
}
|
|
1774
|
+
function thinkingLabel(level) {
|
|
1775
|
+
return level === "xhigh" ? "Extra high" : level.charAt(0).toUpperCase() + level.slice(1);
|
|
1776
|
+
}
|
|
1326
1777
|
function sameStringArray(left, right) {
|
|
1327
1778
|
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
1328
1779
|
}
|
|
@@ -1405,6 +1856,6 @@ function runAcpStdioServer(options) {
|
|
|
1405
1856
|
};
|
|
1406
1857
|
}
|
|
1407
1858
|
//#endregion
|
|
1408
|
-
export { acpMcpServersToZidane as a, stopReasonFromRun as c,
|
|
1859
|
+
export { acpMcpServersToZidane as a, stopReasonFromRun as c, buildStartLocalOptions as d, parseStartArgValues as f, createJsonRpcConnection as g, JsonRpcRemoteError as h, wrapToolsForAcpClient as i, toolResultToAcpContent as l, startProviderNames as m, AcpProtocolError as n, acpPromptToPromptParts as o, startLocalArgOptions as p, createAcpServer as r, sessionBlocksToAcp as s, runAcpStdioServer as t, StartUsageError as u };
|
|
1409
1860
|
|
|
1410
|
-
//# sourceMappingURL=acp-
|
|
1861
|
+
//# sourceMappingURL=acp-CJ1yHdpK.js.map
|