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.
@@ -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
- if (this.modelChoices.length === 0) return userConfig;
693
- return [{
694
- id: MODEL_CONFIG_ID,
695
- name: "Model",
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: "model",
698
- currentValue: this.defaultModelChoiceId,
699
- options: this.modelChoices.map((choice) => ({
700
- value: choice.id,
701
- name: choice.name ?? choice.model
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
- }, ...userConfig.filter((option) => option.id !== MODEL_CONFIG_ID)];
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
- if (!this.modes.some((mode) => mode.id === params.modeId)) throw new AcpProtocolError(-32602, `Unknown mode: ${params.modeId}`);
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
- const configOptions = this.applyConfigSelection(runtime, params.configId, params.value);
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, createJsonRpcConnection as d, wrapToolsForAcpClient as i, toolResultToAcpContent as l, AcpProtocolError as n, acpPromptToPromptParts as o, createAcpServer as r, sessionBlocksToAcp as s, runAcpStdioServer as t, JsonRpcRemoteError as u };
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-BqIU2mo-.js.map
1861
+ //# sourceMappingURL=acp-CJ1yHdpK.js.map