@ycodium-ai/agent-antigravity 0.2.2976 → 0.2.2978

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.
Files changed (2) hide show
  1. package/dist/index.js +898 -869
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -26011,64 +26011,146 @@ function deriveToolActivityPresentation(input2) {
26011
26011
  };
26012
26012
  }
26013
26013
 
26014
- // ../../packages/ycodium-acp-executor/src/events.ts
26015
- function canonicalRequestTypeFromAcpKind(kind) {
26016
- switch (kind) {
26017
- case "execute":
26018
- return "exec_command_approval";
26019
- case "read":
26020
- return "file_read_approval";
26021
- case "edit":
26022
- case "delete":
26023
- case "move":
26024
- return "file_change_approval";
26025
- case "fetch":
26026
- return "web_fetch_approval";
26027
- case "search":
26028
- return "web_search_approval";
26029
- default:
26030
- return "dynamic_tool_call";
26014
+ // ../../packages/ycodium-acp-executor/src/runtime-model.ts
26015
+ function extractModelConfigId(sessionResponse) {
26016
+ const configOptions = sessionResponse.configOptions;
26017
+ if (!configOptions) return void 0;
26018
+ for (const opt of configOptions) {
26019
+ if (opt.category === "model" && opt.id.trim().length > 0) {
26020
+ return opt.id.trim();
26021
+ }
26031
26022
  }
26023
+ return configOptions.find((opt) => opt.id.trim() === "model" && opt.type === "select") ? "model" : void 0;
26032
26024
  }
26033
- function fileChangesFromAcpPermission(permissionRequest) {
26034
- const content = permissionRequest.toolCall?.data["content"];
26035
- const changes = Array.isArray(content) ? content.flatMap((entry) => {
26036
- if (entry === null || typeof entry !== "object") {
26037
- return [];
26025
+ function findSessionConfigOption(configOptions, configId) {
26026
+ if (!configOptions) {
26027
+ return void 0;
26028
+ }
26029
+ const normalizedConfigId = configId.trim();
26030
+ if (!normalizedConfigId) {
26031
+ return void 0;
26032
+ }
26033
+ return configOptions.find((option) => option.id.trim() === normalizedConfigId);
26034
+ }
26035
+ function collectSessionConfigOptionValues(configOption) {
26036
+ if (configOption.type !== "select" || !configOption.options) {
26037
+ return [];
26038
+ }
26039
+ return configOption.options.flatMap(
26040
+ (entry) => "value" in entry ? [entry.value] : entry.options.map((option) => option.value)
26041
+ );
26042
+ }
26043
+ function collectSessionModelIds(models) {
26044
+ if (!isRecord3(models) || !Array.isArray(models["availableModels"])) {
26045
+ return [];
26046
+ }
26047
+ return models["availableModels"].flatMap(
26048
+ (model) => isRecord3(model) && typeof model["modelId"] === "string" ? [model["modelId"]] : []
26049
+ );
26050
+ }
26051
+ function catalogModelLastSegment(value) {
26052
+ if (value.startsWith("[")) {
26053
+ let parsed;
26054
+ try {
26055
+ parsed = JSON.parse(value);
26056
+ } catch {
26057
+ return void 0;
26038
26058
  }
26039
- const block = entry;
26040
- if (block["type"] !== "diff" || typeof block["path"] !== "string" || typeof block["newText"] !== "string") {
26041
- return [];
26059
+ if (!Array.isArray(parsed) || parsed.length < 2) return void 0;
26060
+ const last = parsed[parsed.length - 1];
26061
+ return typeof last === "string" ? last : void 0;
26062
+ }
26063
+ const separator = value.indexOf("/");
26064
+ return separator > 0 && separator < value.length - 1 ? value.slice(separator + 1) : void 0;
26065
+ }
26066
+ function matchAdvertisedModelValue(requestedModelId, advertisedValues) {
26067
+ const wanted = requestedModelId.trim();
26068
+ if (!wanted) return void 0;
26069
+ if (advertisedValues.includes(wanted)) return wanted;
26070
+ const byLastSegment = advertisedValues.filter(
26071
+ (value) => catalogModelLastSegment(value) === wanted
26072
+ );
26073
+ return byLastSegment.length === 1 ? byLastSegment[0] : void 0;
26074
+ }
26075
+ function parseSessionModeState(sessionResponse) {
26076
+ const modes = sessionResponse.modes;
26077
+ if (!modes) return void 0;
26078
+ const currentModeId = modes.currentModeId.trim();
26079
+ if (!currentModeId) {
26080
+ return void 0;
26081
+ }
26082
+ const availableModes = [];
26083
+ for (const mode of modes.availableModes) {
26084
+ const id = mode.id.trim();
26085
+ const name = mode.name.trim();
26086
+ if (!id || !name) {
26087
+ continue;
26042
26088
  }
26043
- const oldText = typeof block["oldText"] === "string" ? block["oldText"] : void 0;
26044
- return [
26045
- {
26046
- path: block["path"],
26047
- changeKind: oldText === void 0 ? "add" : "modify",
26048
- content: {
26049
- kind: "replace",
26050
- ...oldText !== void 0 ? { oldText } : {},
26051
- newText: block["newText"]
26052
- }
26053
- }
26054
- ];
26055
- }) : [];
26056
- if (changes.length > 0) {
26057
- return changes;
26089
+ const description = mode.description?.trim() || void 0;
26090
+ availableModes.push(
26091
+ description !== void 0 ? { id, name, description } : { id, name }
26092
+ );
26058
26093
  }
26059
- if (canonicalRequestTypeFromAcpKind(permissionRequest.kind) !== "file_change_approval") {
26094
+ if (availableModes.length === 0) {
26060
26095
  return void 0;
26061
26096
  }
26062
- const locations = permissionRequest.toolCall?.data["locations"];
26063
- const paths = Array.isArray(locations) ? locations.flatMap((entry) => {
26064
- const path = entry?.["path"];
26065
- return typeof path === "string" && path.trim().length > 0 ? [path] : [];
26066
- }) : [];
26067
- return paths.length > 0 ? paths.map((path) => ({ path, omitted: "unavailable" })) : void 0;
26097
+ return {
26098
+ currentModeId,
26099
+ availableModes
26100
+ };
26068
26101
  }
26069
- function runtimeItemStatusFromAcpToolStatus(status) {
26070
- switch (status) {
26102
+ function acpCommandsToSlashCommands(commands) {
26103
+ return commands.map((command) => ({
26104
+ name: command.name,
26105
+ ...command.description === void 0 ? {} : { description: command.description },
26106
+ ...command.inputHint === void 0 ? {} : { input: { hint: command.inputHint } }
26107
+ }));
26108
+ }
26109
+ function parseAvailableCommandsUpdate(params) {
26110
+ const update = params.update;
26111
+ if (update["sessionUpdate"] !== "available_commands_update") {
26112
+ return void 0;
26113
+ }
26114
+ const availableCommands = update["availableCommands"];
26115
+ if (!Array.isArray(availableCommands)) {
26116
+ return [];
26117
+ }
26118
+ const commands = [];
26119
+ for (const command of availableCommands) {
26120
+ if (!isRecord3(command)) {
26121
+ continue;
26122
+ }
26123
+ const name = typeof command["name"] === "string" ? command["name"].trim() : "";
26124
+ if (!name) {
26125
+ continue;
26126
+ }
26127
+ const description = typeof command["description"] === "string" ? command["description"].trim() || void 0 : void 0;
26128
+ const input2 = isRecord3(command["input"]) ? command["input"] : void 0;
26129
+ const inputHint = typeof input2?.["hint"] === "string" ? input2["hint"].trim() || void 0 : void 0;
26130
+ commands.push({
26131
+ name,
26132
+ ...description ? { description } : {},
26133
+ ...inputHint ? { inputHint } : {}
26134
+ });
26135
+ }
26136
+ return commands;
26137
+ }
26138
+ function normalizePlanStepStatus(raw) {
26139
+ switch (raw) {
26140
+ case "completed":
26141
+ return "completed";
26142
+ case "in_progress":
26143
+ case "inProgress":
26144
+ return "inProgress";
26145
+ default:
26146
+ return "pending";
26147
+ }
26148
+ }
26149
+ function normalizeToolCallStatus(raw, fallback) {
26150
+ switch (raw) {
26071
26151
  case "pending":
26152
+ return "pending";
26153
+ case "in_progress":
26072
26154
  case "inProgress":
26073
26155
  return "inProgress";
26074
26156
  case "completed":
@@ -26076,706 +26158,172 @@ function runtimeItemStatusFromAcpToolStatus(status) {
26076
26158
  case "failed":
26077
26159
  return "failed";
26078
26160
  default:
26079
- return void 0;
26161
+ return fallback;
26080
26162
  }
26081
26163
  }
26082
- function makeAcpRequestOpenedEvent(input2) {
26083
- const requestType = canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind);
26084
- const toolName = requestType === "dynamic_tool_call" ? input2.permissionRequest.toolCall?.title : void 0;
26085
- return {
26086
- type: "request.opened",
26087
- ...input2.stamp,
26088
- provider: input2.provider,
26089
- threadId: input2.threadId,
26090
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26091
- requestId: input2.requestId,
26092
- payload: {
26093
- requestType,
26094
- detail: input2.detail,
26095
- ...toolName ? { toolName } : {},
26096
- args: input2.args,
26097
- ...input2.options ? { options: input2.options } : {},
26098
- ...input2.fileChanges ? { fileChanges: input2.fileChanges } : {},
26099
- declineReasonRelay: "queued"
26100
- },
26101
- raw: {
26102
- source: input2.source,
26103
- method: input2.method,
26104
- payload: input2.rawPayload
26164
+ function normalizeCommandValue2(value) {
26165
+ if (typeof value === "string" && value.trim().length > 0) {
26166
+ return value.trim();
26167
+ }
26168
+ if (!Array.isArray(value)) {
26169
+ return void 0;
26170
+ }
26171
+ const parts = [];
26172
+ for (const entry of value) {
26173
+ if (typeof entry === "string") {
26174
+ const part = entry.trim();
26175
+ if (part.length > 0) {
26176
+ parts.push(part);
26177
+ }
26105
26178
  }
26106
- };
26179
+ }
26180
+ return parts.length > 0 ? parts.join(" ") : void 0;
26107
26181
  }
26108
- function makeAcpRequestResolvedEvent(input2) {
26109
- return {
26110
- type: "request.resolved",
26111
- ...input2.stamp,
26112
- provider: input2.provider,
26113
- threadId: input2.threadId,
26114
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26115
- requestId: input2.requestId,
26116
- payload: {
26117
- requestType: canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind),
26118
- decision: input2.decision,
26119
- ...input2.reason ? { reason: input2.reason } : {}
26120
- }
26121
- };
26182
+ function extractCommandFromTitle2(title) {
26183
+ if (!title) {
26184
+ return void 0;
26185
+ }
26186
+ const match = /`([^`]+)`/.exec(title);
26187
+ return match?.[1]?.trim() || void 0;
26122
26188
  }
26123
- function makeAcpPlanUpdatedEvent(input2) {
26124
- return {
26125
- type: "turn.plan.updated",
26126
- ...input2.stamp,
26127
- provider: input2.provider,
26128
- threadId: input2.threadId,
26129
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26130
- payload: input2.payload,
26131
- raw: {
26132
- source: input2.source,
26133
- method: input2.method,
26134
- payload: input2.rawPayload
26135
- }
26136
- };
26137
- }
26138
- function makeAcpToolCallEvent(input2) {
26139
- const runtimeStatus = runtimeItemStatusFromAcpToolStatus(input2.toolCall.status);
26140
- const { data } = input2.toolCall;
26141
- return {
26142
- type: input2.toolCall.status === "completed" || input2.toolCall.status === "failed" ? "item.completed" : "item.updated",
26143
- ...input2.stamp,
26144
- provider: input2.provider,
26145
- threadId: input2.threadId,
26146
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26147
- itemId: input2.toolCall.toolCallId,
26148
- payload: {
26149
- itemType: canonicalItemTypeFromAcpToolKind(input2.toolCall.kind),
26150
- ...runtimeStatus ? { status: runtimeStatus } : {},
26151
- ...input2.toolCall.title ? { title: input2.toolCall.title } : {},
26152
- ...input2.toolCall.detail ? { detail: input2.toolCall.detail } : {},
26153
- ...Object.keys(data).length > 0 ? { data } : {}
26154
- },
26155
- raw: {
26156
- source: "acp.jsonrpc",
26157
- method: "session/update",
26158
- payload: input2.rawPayload
26159
- }
26160
- };
26161
- }
26162
- function makeAcpAssistantItemEvent(input2) {
26163
- return {
26164
- type: input2.lifecycle,
26165
- ...input2.stamp,
26166
- provider: input2.provider,
26167
- threadId: input2.threadId,
26168
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26169
- itemId: input2.itemId,
26170
- payload: {
26171
- itemType: "assistant_message",
26172
- status: input2.lifecycle === "item.completed" ? "completed" : "inProgress"
26189
+ function extractToolCallCommand(rawInput, title) {
26190
+ if (isRecord3(rawInput)) {
26191
+ const directCommand = normalizeCommandValue2(rawInput["command"]);
26192
+ if (directCommand) {
26193
+ return directCommand;
26173
26194
  }
26174
- };
26175
- }
26176
- function makeAcpContentDeltaEvent(input2) {
26177
- return {
26178
- type: "content.delta",
26179
- ...input2.stamp,
26180
- provider: input2.provider,
26181
- threadId: input2.threadId,
26182
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26183
- ...input2.itemId ? { itemId: input2.itemId } : {},
26184
- payload: {
26185
- streamKind: input2.streamKind ?? "assistant_text",
26186
- delta: input2.text
26187
- },
26188
- raw: {
26189
- source: "acp.jsonrpc",
26190
- method: "session/update",
26191
- payload: input2.rawPayload
26195
+ const executable = typeof rawInput["executable"] === "string" ? rawInput["executable"].trim() : "";
26196
+ const args = normalizeCommandValue2(rawInput["args"]);
26197
+ if (executable && args) {
26198
+ return `${executable} ${args}`;
26192
26199
  }
26193
- };
26194
- }
26195
-
26196
- // ../../packages/ycodium-acp-executor/src/config-options.ts
26197
- function isRecord4(value) {
26198
- return typeof value === "object" && value !== null && !Array.isArray(value);
26199
- }
26200
- function asString(value) {
26201
- return typeof value === "string" ? value : void 0;
26202
- }
26203
- function normalizedField(option, key) {
26204
- return asString(option[key])?.trim().toLowerCase() ?? "";
26205
- }
26206
- function looksLikeEffortOption(option) {
26207
- const id = normalizedField(option, "id");
26208
- const name = normalizedField(option, "name");
26209
- return id === "effort" || id === "reasoning" || name === "effort" || name === "reasoning" || name.includes("effort") || name.includes("reasoning") || normalizedField(option, "category") === "thought_level";
26210
- }
26211
- function flattenChoices(rawOptions, currentValue) {
26212
- if (!Array.isArray(rawOptions)) return [];
26213
- const out = [];
26214
- const seen = /* @__PURE__ */ new Set();
26215
- const push = (entry) => {
26216
- if (!isRecord4(entry)) return;
26217
- const value = asString(entry["value"]);
26218
- if (value === void 0 || seen.has(value)) return;
26219
- seen.add(value);
26220
- const description = asString(entry["description"])?.trim();
26221
- const name = asString(entry["name"])?.trim();
26222
- out.push({
26223
- value,
26224
- ...name ? { name } : {},
26225
- label: name || value,
26226
- ...description ? { description } : {},
26227
- ...currentValue !== void 0 && currentValue === value ? { isDefault: true } : {}
26228
- });
26229
- };
26230
- for (const entry of rawOptions) {
26231
- if (isRecord4(entry) && Array.isArray(entry["options"])) {
26232
- for (const nested of entry["options"]) push(nested);
26233
- continue;
26200
+ if (executable) {
26201
+ return executable;
26234
26202
  }
26235
- push(entry);
26236
26203
  }
26237
- return out;
26238
- }
26239
- function findAcpEffortConfig(configOptions) {
26240
- if (!Array.isArray(configOptions)) return void 0;
26241
- const candidates = configOptions.filter(isRecord4).filter((option) => normalizedField(option, "type") === "select").filter(looksLikeEffortOption);
26242
- if (candidates.length === 0) return void 0;
26243
- const picked = candidates.find((option) => normalizedField(option, "category") === "model_option") ?? candidates.find((option) => normalizedField(option, "id") === "effort") ?? candidates.find((option) => normalizedField(option, "category") === "thought_level") ?? candidates[0];
26244
- if (picked === void 0) return void 0;
26245
- const configId = asString(picked["id"])?.trim();
26246
- if (!configId) return void 0;
26247
- const choices = flattenChoices(picked["options"], asString(picked["currentValue"])?.trim());
26248
- if (choices.length === 0) return void 0;
26249
- return {
26250
- configId,
26251
- label: asString(picked["name"])?.trim() ?? "",
26252
- choices
26253
- };
26254
- }
26255
- function acpModelChoicesFromConfigOptions(configOptions) {
26256
- if (!Array.isArray(configOptions)) return void 0;
26257
- const records = configOptions.filter(isRecord4);
26258
- const modelOption = records.find((option) => normalizedField(option, "category") === "model") ?? records.find(
26259
- (option) => normalizedField(option, "id") === "model" && normalizedField(option, "type") === "select"
26260
- );
26261
- if (modelOption === void 0) return void 0;
26262
- if (!asString(modelOption["id"])?.trim()) return void 0;
26263
- return flattenChoices(modelOption["options"], asString(modelOption["currentValue"])?.trim());
26204
+ return extractCommandFromTitle2(title);
26264
26205
  }
26265
- function acpModelChoicesFromSessionModels(models) {
26266
- if (!isRecord4(models) || !Array.isArray(models["availableModels"])) return void 0;
26267
- const currentModelId = asString(models["currentModelId"])?.trim();
26268
- const out = [];
26269
- const seen = /* @__PURE__ */ new Set();
26270
- for (const entry of models["availableModels"]) {
26271
- if (!isRecord4(entry)) continue;
26272
- const value = asString(entry["modelId"])?.trim();
26273
- if (!value || seen.has(value)) continue;
26274
- seen.add(value);
26275
- const name = asString(entry["name"])?.trim();
26276
- const description = asString(entry["description"])?.trim();
26277
- out.push({
26278
- value,
26279
- ...name ? { name } : {},
26280
- label: name || value,
26281
- ...description ? { description } : {},
26282
- ...currentModelId !== void 0 && currentModelId === value ? { isDefault: true } : {}
26283
- });
26206
+ var TOOL_CALL_CONTENT_MAX_CHARS = 8e3;
26207
+ var TOOL_CALL_CONTENT_TRUNCATION_MARKER = "[Earlier output truncated]\n\n";
26208
+ function boundToolCallOutputText(text) {
26209
+ if (text.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
26210
+ return text;
26284
26211
  }
26285
- return out;
26286
- }
26287
-
26288
- // ../../packages/ycodium-acp-executor/src/runtime-mode.ts
26289
- function isRecord5(value) {
26290
- return typeof value === "object" && value !== null && !Array.isArray(value);
26291
- }
26292
- function asString2(value) {
26293
- return typeof value === "string" ? value : void 0;
26212
+ const tail = text.slice(text.length - TOOL_CALL_CONTENT_MAX_CHARS);
26213
+ return `${TOOL_CALL_CONTENT_TRUNCATION_MARKER}${tail}`;
26294
26214
  }
26295
- function acpAvailableModes(setup) {
26296
- if (!isRecord5(setup)) return [];
26297
- const out = [];
26298
- const seen = /* @__PURE__ */ new Set();
26299
- const push = (entry) => {
26300
- if (!isRecord5(entry)) return;
26301
- const id = (asString2(entry["id"]) ?? asString2(entry["value"]))?.trim();
26302
- if (!id || seen.has(id)) return;
26303
- seen.add(id);
26304
- const meta3 = entry["_meta"];
26305
- const kind = isRecord5(meta3) ? asString2(meta3["kind"])?.trim().toLowerCase() : void 0;
26306
- const name = asString2(entry["name"])?.trim();
26307
- const description = asString2(entry["description"])?.trim();
26308
- out.push({
26309
- id,
26310
- name: name || id,
26311
- ...description ? { description } : {},
26312
- ...kind ? { kind } : {}
26313
- });
26314
- };
26315
- const modes = setup["modes"];
26316
- if (isRecord5(modes) && Array.isArray(modes["availableModes"])) {
26317
- for (const entry of modes["availableModes"]) push(entry);
26215
+ var RAW_OUTPUT_TEXT_FIELDS = ["content", "stdout", "stderr", "output"];
26216
+ function boundToolCallRawOutput(rawOutput) {
26217
+ if (!isRecord3(rawOutput)) {
26218
+ return rawOutput;
26318
26219
  }
26319
- const configOptions = setup["configOptions"];
26320
- if (Array.isArray(configOptions)) {
26321
- for (const option of configOptions) {
26322
- if (!isRecord5(option)) continue;
26323
- if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
26324
- if (!Array.isArray(option["options"])) continue;
26325
- for (const entry of option["options"]) push(entry);
26220
+ let changed = false;
26221
+ const bounded = { ...rawOutput };
26222
+ for (const field of RAW_OUTPUT_TEXT_FIELDS) {
26223
+ const value = rawOutput[field];
26224
+ if (typeof value === "string" && value.length > TOOL_CALL_CONTENT_MAX_CHARS) {
26225
+ bounded[field] = boundToolCallOutputText(value);
26226
+ changed = true;
26326
26227
  }
26327
26228
  }
26328
- return out;
26229
+ return changed ? bounded : rawOutput;
26329
26230
  }
26330
- function acpModeConfigId(setup) {
26331
- if (!isRecord5(setup)) return void 0;
26332
- const configOptions = setup["configOptions"];
26333
- if (!Array.isArray(configOptions)) return void 0;
26334
- for (const option of configOptions) {
26335
- if (!isRecord5(option)) continue;
26336
- if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
26337
- const id = asString2(option["id"])?.trim();
26338
- if (id) return id;
26231
+ function toolCallContentText(entry) {
26232
+ if (entry.type !== "content" || entry.content?.type !== "text") {
26233
+ return void 0;
26339
26234
  }
26340
- return void 0;
26235
+ return entry.content.text;
26341
26236
  }
26342
- function acpCurrentModeId(setup) {
26343
- if (!isRecord5(setup)) return void 0;
26344
- const modes = setup["modes"];
26345
- if (isRecord5(modes)) {
26346
- const current = asString2(modes["currentModeId"])?.trim();
26347
- if (current) return current;
26237
+ function extractTextContentFromToolCallContent(content) {
26238
+ if (!Array.isArray(content)) {
26239
+ return { text: void 0, content: void 0 };
26348
26240
  }
26349
- const configOptions = setup["configOptions"];
26350
- if (Array.isArray(configOptions)) {
26351
- for (const option of configOptions) {
26352
- if (!isRecord5(option)) continue;
26353
- if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
26354
- const current = asString2(option["currentValue"])?.trim();
26355
- if (current) return current;
26241
+ const typed = content;
26242
+ const chunks = [];
26243
+ for (const entry of typed) {
26244
+ const text = toolCallContentText(entry)?.trim();
26245
+ if (text) {
26246
+ chunks.push(text);
26356
26247
  }
26357
26248
  }
26358
- return void 0;
26359
- }
26360
-
26361
- // ../../packages/ycodium-acp-executor/src/handshake.ts
26362
- function acpInitializePayload(clientInfo, overrides) {
26363
- return {
26364
- protocolVersion: PROTOCOL_VERSION,
26365
- clientCapabilities: {
26366
- fs: {
26367
- readTextFile: false,
26368
- writeTextFile: false,
26369
- ...overrides?.fs
26370
- },
26371
- terminal: overrides?.terminal ?? false
26372
- },
26373
- clientInfo
26374
- };
26375
- }
26376
-
26377
- // ../../packages/ycodium-acp-executor/src/config-option-wiring.ts
26378
- var VENDOR_CATEGORY_PREFIX = "_";
26379
- var ACP_CONFIG_CATEGORY_HANDLING = {
26380
- mode: {
26381
- consumed: true,
26382
- via: "runtime-mode.ts\uFF1AacpAvailableModes / acpCurrentModeId / acpModeConfigId"
26383
- },
26384
- model: {
26385
- consumed: true,
26386
- via: "runtime-model.ts:extractModelConfigId \u2192 executor.ts:applyRequestedModel"
26387
- },
26388
- thought_level: {
26389
- consumed: true,
26390
- via: "config-options.ts:findAcpEffortConfig \u2192 executor.ts:applyRequestedEffort"
26391
- },
26392
- model_option: {
26393
- consumed: true,
26394
- // 精确说法:它不是**识别器**,是**优先级**。`looksLikeEffortOption` 先筛出候选,
26395
- // 标了 `model_option` 的在候选里排第一(厂商自己标的最准),排在 id 叫 `effort`
26396
- // 的和标 `thought_level` 的前面。光有这个 category 而 id/name 不像力度档的,
26397
- // 压根进不了候选。
26398
- via: "config-options.ts:findAcpEffortConfig\uFF08\u5019\u9009\u91CC\u7684\u6700\u9AD8\u4F18\u5148\u7EA7\uFF0C\u538B\u8FC7 thought_level\uFF09"
26399
- },
26400
- model_config: {
26401
- consumed: false,
26402
- note: "\u53EA\u6709\u5BBF\u4E3B\u7684 CursorProvider \u6D88\u8D39\u8FC7\uFF08context / fast / thinking \u4E09\u4E2A\u5F00\u5173\uFF09\u3002Cursor 2026-09-20 \u5E9F\u5F03\u5220\u9664\uFF0C\u8FD9\u4E00\u7C7B\u73B0\u5728\u6CA1\u6709\u6D88\u8D39\u70B9\uFF1B\u6CA1\u89C1\u8FC7\u522B\u5BB6\u7684\u771F\u5B9E\u8F7D\u8377\uFF0C\u5148\u8BB0\u8D26\u4E0D\u731C\u5F62\u72B6\u3002"
26403
- }
26404
- };
26405
- var KNOWN_CATEGORIES = new Set(Object.keys(ACP_CONFIG_CATEGORY_HANDLING));
26406
- function unhandledConfigCategories(configOptions) {
26407
- if (!configOptions) return [];
26408
- const seen = /* @__PURE__ */ new Set();
26409
- const out = [];
26410
- for (const option of configOptions) {
26411
- const category = option.category?.trim();
26412
- if (!category) continue;
26413
- if (KNOWN_CATEGORIES.has(category)) continue;
26414
- if (seen.has(category)) continue;
26415
- seen.add(category);
26416
- out.push({
26417
- category,
26418
- optionId: option.id.trim(),
26419
- vendorExtension: category.startsWith(VENDOR_CATEGORY_PREFIX)
26420
- });
26421
- }
26422
- return out;
26423
- }
26424
-
26425
- // ../../packages/ycodium-acp-executor/src/mutex.ts
26426
- var Mutex = class {
26427
- locked = false;
26428
- waiters = [];
26429
- get isLocked() {
26430
- return this.locked;
26431
- }
26432
- acquire() {
26433
- if (!this.locked) {
26434
- this.locked = true;
26435
- return Promise.resolve();
26436
- }
26437
- return new Promise((resolve6) => {
26438
- this.waiters.push(resolve6);
26439
- });
26440
- }
26441
- tryAcquire() {
26442
- if (this.locked) {
26443
- return false;
26444
- }
26445
- this.locked = true;
26446
- return true;
26249
+ if (chunks.length === 0) {
26250
+ return { text: void 0, content: typed };
26447
26251
  }
26448
- release() {
26449
- const next = this.waiters.shift();
26450
- if (next) {
26451
- next();
26452
- return;
26453
- }
26454
- this.locked = false;
26252
+ const joined = chunks.join("\n");
26253
+ if (joined.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
26254
+ return { text: joined, content: typed };
26455
26255
  }
26456
- async runExclusive(fn) {
26457
- await this.acquire();
26458
- try {
26459
- return await fn();
26460
- } finally {
26461
- this.release();
26256
+ const bounded = boundToolCallOutputText(joined);
26257
+ const lastContributingTextIndex = typed.reduce(
26258
+ (lastIndex, entry, index) => toolCallContentText(entry)?.trim() ? index : lastIndex,
26259
+ -1
26260
+ );
26261
+ const boundedContent = typed.flatMap((entry, index) => {
26262
+ if (toolCallContentText(entry) === void 0) {
26263
+ return [entry];
26462
26264
  }
26463
- }
26464
- };
26465
-
26466
- // ../../packages/ycodium-acp-executor/src/runtime-model.ts
26467
- function extractModelConfigId(sessionResponse) {
26468
- const configOptions = sessionResponse.configOptions;
26469
- if (!configOptions) return void 0;
26470
- for (const opt of configOptions) {
26471
- if (opt.category === "model" && opt.id.trim().length > 0) {
26472
- return opt.id.trim();
26265
+ if (index !== lastContributingTextIndex) {
26266
+ return [];
26473
26267
  }
26474
- }
26475
- return configOptions.find((opt) => opt.id.trim() === "model" && opt.type === "select") ? "model" : void 0;
26268
+ return [{ type: "content", content: { type: "text", text: bounded } }];
26269
+ });
26270
+ return { text: bounded, content: boundedContent };
26476
26271
  }
26477
- function findSessionConfigOption(configOptions, configId) {
26478
- if (!configOptions) {
26272
+ function normalizeToolKind(kind) {
26273
+ return typeof kind === "string" && kind.trim().length > 0 ? kind.trim() : void 0;
26274
+ }
26275
+ function makeToolCallState(input2, options2) {
26276
+ const toolCallId = typeof input2.toolCallId === "string" ? input2.toolCallId.trim() : "";
26277
+ if (!toolCallId) {
26479
26278
  return void 0;
26480
26279
  }
26481
- const normalizedConfigId = configId.trim();
26482
- if (!normalizedConfigId) {
26483
- return void 0;
26280
+ const title = typeof input2.title === "string" ? input2.title.trim() || void 0 : void 0;
26281
+ const command = extractToolCallCommand(input2.rawInput, title);
26282
+ const extractedContent = extractTextContentFromToolCallContent(input2.content);
26283
+ const textContent = extractedContent.text;
26284
+ const normalizedTitle = title && title.toLowerCase() !== "terminal" && title.toLowerCase() !== "tool call" ? title : void 0;
26285
+ const data = { toolCallId };
26286
+ const kind = normalizeToolKind(input2.kind);
26287
+ if (kind) {
26288
+ data["kind"] = kind;
26484
26289
  }
26485
- return configOptions.find((option) => option.id.trim() === normalizedConfigId);
26486
- }
26487
- function collectSessionConfigOptionValues(configOption) {
26488
- if (configOption.type !== "select" || !configOption.options) {
26489
- return [];
26290
+ const name = readAcpText(input2, "name");
26291
+ if (name) {
26292
+ data["name"] = name;
26490
26293
  }
26491
- return configOption.options.flatMap(
26492
- (entry) => "value" in entry ? [entry.value] : entry.options.map((option) => option.value)
26493
- );
26494
- }
26495
- function collectSessionModelIds(models) {
26496
- if (!isRecord3(models) || !Array.isArray(models["availableModels"])) {
26497
- return [];
26294
+ if (command) {
26295
+ data["command"] = command;
26498
26296
  }
26499
- return models["availableModels"].flatMap(
26500
- (model) => isRecord3(model) && typeof model["modelId"] === "string" ? [model["modelId"]] : []
26501
- );
26502
- }
26503
- function catalogModelLastSegment(value) {
26504
- if (value.startsWith("[")) {
26505
- let parsed;
26506
- try {
26507
- parsed = JSON.parse(value);
26508
- } catch {
26509
- return void 0;
26510
- }
26511
- if (!Array.isArray(parsed) || parsed.length < 2) return void 0;
26512
- const last = parsed[parsed.length - 1];
26513
- return typeof last === "string" ? last : void 0;
26297
+ if (input2.rawInput !== void 0) {
26298
+ data["rawInput"] = input2.rawInput;
26514
26299
  }
26515
- const separator = value.indexOf("/");
26516
- return separator > 0 && separator < value.length - 1 ? value.slice(separator + 1) : void 0;
26517
- }
26518
- function matchAdvertisedModelValue(requestedModelId, advertisedValues) {
26519
- const wanted = requestedModelId.trim();
26520
- if (!wanted) return void 0;
26521
- if (advertisedValues.includes(wanted)) return wanted;
26522
- const byLastSegment = advertisedValues.filter(
26523
- (value) => catalogModelLastSegment(value) === wanted
26524
- );
26525
- return byLastSegment.length === 1 ? byLastSegment[0] : void 0;
26526
- }
26527
- function parseSessionModeState(sessionResponse) {
26528
- const modes = sessionResponse.modes;
26529
- if (!modes) return void 0;
26530
- const currentModeId = modes.currentModeId.trim();
26531
- if (!currentModeId) {
26532
- return void 0;
26300
+ if (input2.rawOutput !== void 0) {
26301
+ data["rawOutput"] = boundToolCallRawOutput(input2.rawOutput);
26533
26302
  }
26534
- const availableModes = [];
26535
- for (const mode of modes.availableModes) {
26536
- const id = mode.id.trim();
26537
- const name = mode.name.trim();
26538
- if (!id || !name) {
26539
- continue;
26540
- }
26541
- const description = mode.description?.trim() || void 0;
26542
- availableModes.push(
26543
- description !== void 0 ? { id, name, description } : { id, name }
26544
- );
26303
+ if (input2.content !== void 0) {
26304
+ data["content"] = extractedContent.content ?? input2.content;
26545
26305
  }
26546
- if (availableModes.length === 0) {
26547
- return void 0;
26306
+ if (input2.locations !== void 0) {
26307
+ data["locations"] = input2.locations;
26548
26308
  }
26309
+ const fallbackDetail = command ?? normalizedTitle ?? textContent;
26310
+ const hasPresentationSeed = title !== void 0 || kind !== void 0 || command !== void 0 || normalizedTitle !== void 0 || textContent !== void 0;
26311
+ const presentation = hasPresentationSeed ? deriveToolActivityPresentation({
26312
+ itemType: canonicalItemTypeFromAcpToolKind(kind),
26313
+ title,
26314
+ detail: fallbackDetail,
26315
+ data,
26316
+ fallbackSummary: title ?? "Tool"
26317
+ }) : void 0;
26318
+ const status = normalizeToolCallStatus(input2.status, options2?.fallbackStatus);
26549
26319
  return {
26550
- currentModeId,
26551
- availableModes
26552
- };
26553
- }
26554
- function acpCommandsToSlashCommands(commands) {
26555
- return commands.map((command) => ({
26556
- name: command.name,
26557
- ...command.description === void 0 ? {} : { description: command.description },
26558
- ...command.inputHint === void 0 ? {} : { input: { hint: command.inputHint } }
26559
- }));
26560
- }
26561
- function parseAvailableCommandsUpdate(params) {
26562
- const update = params.update;
26563
- if (update["sessionUpdate"] !== "available_commands_update") {
26564
- return void 0;
26565
- }
26566
- const availableCommands = update["availableCommands"];
26567
- if (!Array.isArray(availableCommands)) {
26568
- return [];
26569
- }
26570
- const commands = [];
26571
- for (const command of availableCommands) {
26572
- if (!isRecord3(command)) {
26573
- continue;
26574
- }
26575
- const name = typeof command["name"] === "string" ? command["name"].trim() : "";
26576
- if (!name) {
26577
- continue;
26578
- }
26579
- const description = typeof command["description"] === "string" ? command["description"].trim() || void 0 : void 0;
26580
- const input2 = isRecord3(command["input"]) ? command["input"] : void 0;
26581
- const inputHint = typeof input2?.["hint"] === "string" ? input2["hint"].trim() || void 0 : void 0;
26582
- commands.push({
26583
- name,
26584
- ...description ? { description } : {},
26585
- ...inputHint ? { inputHint } : {}
26586
- });
26587
- }
26588
- return commands;
26589
- }
26590
- function normalizePlanStepStatus(raw) {
26591
- switch (raw) {
26592
- case "completed":
26593
- return "completed";
26594
- case "in_progress":
26595
- case "inProgress":
26596
- return "inProgress";
26597
- default:
26598
- return "pending";
26599
- }
26600
- }
26601
- function normalizeToolCallStatus(raw, fallback) {
26602
- switch (raw) {
26603
- case "pending":
26604
- return "pending";
26605
- case "in_progress":
26606
- case "inProgress":
26607
- return "inProgress";
26608
- case "completed":
26609
- return "completed";
26610
- case "failed":
26611
- return "failed";
26612
- default:
26613
- return fallback;
26614
- }
26615
- }
26616
- function normalizeCommandValue2(value) {
26617
- if (typeof value === "string" && value.trim().length > 0) {
26618
- return value.trim();
26619
- }
26620
- if (!Array.isArray(value)) {
26621
- return void 0;
26622
- }
26623
- const parts = [];
26624
- for (const entry of value) {
26625
- if (typeof entry === "string") {
26626
- const part = entry.trim();
26627
- if (part.length > 0) {
26628
- parts.push(part);
26629
- }
26630
- }
26631
- }
26632
- return parts.length > 0 ? parts.join(" ") : void 0;
26633
- }
26634
- function extractCommandFromTitle2(title) {
26635
- if (!title) {
26636
- return void 0;
26637
- }
26638
- const match = /`([^`]+)`/.exec(title);
26639
- return match?.[1]?.trim() || void 0;
26640
- }
26641
- function extractToolCallCommand(rawInput, title) {
26642
- if (isRecord3(rawInput)) {
26643
- const directCommand = normalizeCommandValue2(rawInput["command"]);
26644
- if (directCommand) {
26645
- return directCommand;
26646
- }
26647
- const executable = typeof rawInput["executable"] === "string" ? rawInput["executable"].trim() : "";
26648
- const args = normalizeCommandValue2(rawInput["args"]);
26649
- if (executable && args) {
26650
- return `${executable} ${args}`;
26651
- }
26652
- if (executable) {
26653
- return executable;
26654
- }
26655
- }
26656
- return extractCommandFromTitle2(title);
26657
- }
26658
- var TOOL_CALL_CONTENT_MAX_CHARS = 8e3;
26659
- var TOOL_CALL_CONTENT_TRUNCATION_MARKER = "[Earlier output truncated]\n\n";
26660
- function boundToolCallOutputText(text) {
26661
- if (text.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
26662
- return text;
26663
- }
26664
- const tail = text.slice(text.length - TOOL_CALL_CONTENT_MAX_CHARS);
26665
- return `${TOOL_CALL_CONTENT_TRUNCATION_MARKER}${tail}`;
26666
- }
26667
- var RAW_OUTPUT_TEXT_FIELDS = ["content", "stdout", "stderr", "output"];
26668
- function boundToolCallRawOutput(rawOutput) {
26669
- if (!isRecord3(rawOutput)) {
26670
- return rawOutput;
26671
- }
26672
- let changed = false;
26673
- const bounded = { ...rawOutput };
26674
- for (const field of RAW_OUTPUT_TEXT_FIELDS) {
26675
- const value = rawOutput[field];
26676
- if (typeof value === "string" && value.length > TOOL_CALL_CONTENT_MAX_CHARS) {
26677
- bounded[field] = boundToolCallOutputText(value);
26678
- changed = true;
26679
- }
26680
- }
26681
- return changed ? bounded : rawOutput;
26682
- }
26683
- function toolCallContentText(entry) {
26684
- if (entry.type !== "content" || entry.content?.type !== "text") {
26685
- return void 0;
26686
- }
26687
- return entry.content.text;
26688
- }
26689
- function extractTextContentFromToolCallContent(content) {
26690
- if (!Array.isArray(content)) {
26691
- return { text: void 0, content: void 0 };
26692
- }
26693
- const typed = content;
26694
- const chunks = [];
26695
- for (const entry of typed) {
26696
- const text = toolCallContentText(entry)?.trim();
26697
- if (text) {
26698
- chunks.push(text);
26699
- }
26700
- }
26701
- if (chunks.length === 0) {
26702
- return { text: void 0, content: typed };
26703
- }
26704
- const joined = chunks.join("\n");
26705
- if (joined.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
26706
- return { text: joined, content: typed };
26707
- }
26708
- const bounded = boundToolCallOutputText(joined);
26709
- const lastContributingTextIndex = typed.reduce(
26710
- (lastIndex, entry, index) => toolCallContentText(entry)?.trim() ? index : lastIndex,
26711
- -1
26712
- );
26713
- const boundedContent = typed.flatMap((entry, index) => {
26714
- if (toolCallContentText(entry) === void 0) {
26715
- return [entry];
26716
- }
26717
- if (index !== lastContributingTextIndex) {
26718
- return [];
26719
- }
26720
- return [{ type: "content", content: { type: "text", text: bounded } }];
26721
- });
26722
- return { text: bounded, content: boundedContent };
26723
- }
26724
- function normalizeToolKind(kind) {
26725
- return typeof kind === "string" && kind.trim().length > 0 ? kind.trim() : void 0;
26726
- }
26727
- function makeToolCallState(input2, options2) {
26728
- const toolCallId = typeof input2.toolCallId === "string" ? input2.toolCallId.trim() : "";
26729
- if (!toolCallId) {
26730
- return void 0;
26731
- }
26732
- const title = typeof input2.title === "string" ? input2.title.trim() || void 0 : void 0;
26733
- const command = extractToolCallCommand(input2.rawInput, title);
26734
- const extractedContent = extractTextContentFromToolCallContent(input2.content);
26735
- const textContent = extractedContent.text;
26736
- const normalizedTitle = title && title.toLowerCase() !== "terminal" && title.toLowerCase() !== "tool call" ? title : void 0;
26737
- const data = { toolCallId };
26738
- const kind = normalizeToolKind(input2.kind);
26739
- if (kind) {
26740
- data["kind"] = kind;
26741
- }
26742
- const name = readAcpText(input2, "name");
26743
- if (name) {
26744
- data["name"] = name;
26745
- }
26746
- if (command) {
26747
- data["command"] = command;
26748
- }
26749
- if (input2.rawInput !== void 0) {
26750
- data["rawInput"] = input2.rawInput;
26751
- }
26752
- if (input2.rawOutput !== void 0) {
26753
- data["rawOutput"] = boundToolCallRawOutput(input2.rawOutput);
26754
- }
26755
- if (input2.content !== void 0) {
26756
- data["content"] = extractedContent.content ?? input2.content;
26757
- }
26758
- if (input2.locations !== void 0) {
26759
- data["locations"] = input2.locations;
26760
- }
26761
- const fallbackDetail = command ?? normalizedTitle ?? textContent;
26762
- const hasPresentationSeed = title !== void 0 || kind !== void 0 || command !== void 0 || normalizedTitle !== void 0 || textContent !== void 0;
26763
- const presentation = hasPresentationSeed ? deriveToolActivityPresentation({
26764
- itemType: canonicalItemTypeFromAcpToolKind(kind),
26765
- title,
26766
- detail: fallbackDetail,
26767
- data,
26768
- fallbackSummary: title ?? "Tool"
26769
- }) : void 0;
26770
- const status = normalizeToolCallStatus(input2.status, options2?.fallbackStatus);
26771
- return {
26772
- toolCallId,
26773
- ...kind ? { kind } : {},
26774
- ...presentation?.summary ? { title: presentation.summary } : {},
26775
- ...status ? { status } : {},
26776
- ...command ? { command } : {},
26777
- ...presentation?.detail ? { detail: presentation.detail } : {},
26778
- data
26320
+ toolCallId,
26321
+ ...kind ? { kind } : {},
26322
+ ...presentation?.summary ? { title: presentation.summary } : {},
26323
+ ...status ? { status } : {},
26324
+ ...command ? { command } : {},
26325
+ ...presentation?.detail ? { detail: presentation.detail } : {},
26326
+ data
26779
26327
  };
26780
26328
  }
26781
26329
  function mergeToolCallState(previous, next) {
@@ -26850,154 +26398,647 @@ function boundToolCallRawPayload(params, update, toolCall) {
26850
26398
  if (!contentBounded && !rawOutputBounded) {
26851
26399
  return params;
26852
26400
  }
26853
- return {
26854
- ...params,
26855
- update: {
26856
- ...update,
26857
- ...contentBounded ? { content: boundedContent } : {},
26858
- ...rawOutputBounded ? { rawOutput: boundedRawOutput } : {}
26401
+ return {
26402
+ ...params,
26403
+ update: {
26404
+ ...update,
26405
+ ...contentBounded ? { content: boundedContent } : {},
26406
+ ...rawOutputBounded ? { rawOutput: boundedRawOutput } : {}
26407
+ }
26408
+ };
26409
+ }
26410
+ function readAcpText(source, key) {
26411
+ const value = source?.[key];
26412
+ if (typeof value !== "string") return void 0;
26413
+ const trimmed = value.trim();
26414
+ return trimmed.length > 0 ? trimmed : void 0;
26415
+ }
26416
+ function textFromContentBlocks(blocks) {
26417
+ const parts = blocks.flatMap(
26418
+ (block) => isRecord3(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
26419
+ );
26420
+ const joined = parts.join("");
26421
+ return joined.trim().length > 0 ? joined : void 0;
26422
+ }
26423
+ function parseSessionUpdateEvent(params) {
26424
+ const upd = params.update;
26425
+ const events = [];
26426
+ let modeId;
26427
+ const kind = upd["sessionUpdate"];
26428
+ switch (kind) {
26429
+ case "current_mode_update": {
26430
+ modeId = readAcpText(upd, "currentModeId");
26431
+ if (modeId) {
26432
+ events.push({
26433
+ _tag: "ModeChanged",
26434
+ modeId
26435
+ });
26436
+ }
26437
+ break;
26438
+ }
26439
+ case "plan": {
26440
+ const entries = Array.isArray(upd["entries"]) ? upd["entries"] : [];
26441
+ const plan = entries.map((entry, index) => ({
26442
+ step: readAcpText(entry, "content") ?? `Step ${index + 1}`,
26443
+ status: normalizePlanStepStatus(isRecord3(entry) ? entry["status"] : void 0)
26444
+ }));
26445
+ if (plan.length > 0) {
26446
+ events.push({
26447
+ _tag: "PlanUpdated",
26448
+ payload: {
26449
+ plan
26450
+ },
26451
+ rawPayload: params
26452
+ });
26453
+ }
26454
+ break;
26455
+ }
26456
+ case "tool_call":
26457
+ case "tool_call_update": {
26458
+ const toolCall = makeToolCallState(
26459
+ {
26460
+ toolCallId: upd["toolCallId"],
26461
+ name: upd["name"],
26462
+ title: typeof upd["title"] === "string" ? upd["title"] : void 0,
26463
+ kind: upd["kind"],
26464
+ status: upd["status"],
26465
+ rawInput: upd["rawInput"],
26466
+ rawOutput: upd["rawOutput"],
26467
+ content: upd["content"],
26468
+ locations: upd["locations"]
26469
+ },
26470
+ kind === "tool_call" ? { fallbackStatus: "pending" } : void 0
26471
+ );
26472
+ if (toolCall) {
26473
+ events.push({
26474
+ _tag: "ToolCallUpdated",
26475
+ toolCall,
26476
+ rawPayload: boundToolCallRawPayload(params, upd, toolCall)
26477
+ });
26478
+ }
26479
+ break;
26480
+ }
26481
+ case "agent_message_chunk":
26482
+ case "agent_thought_chunk": {
26483
+ const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
26484
+ const contentType = content?.["type"];
26485
+ const streamKind = kind === "agent_thought_chunk" ? "reasoning_text" : "assistant_text";
26486
+ if (contentType === "text") {
26487
+ const text = typeof content?.["text"] === "string" ? content["text"] : "";
26488
+ if (text.length > 0) {
26489
+ events.push({
26490
+ _tag: "ContentDelta",
26491
+ text,
26492
+ streamKind,
26493
+ rawPayload: params
26494
+ });
26495
+ }
26496
+ break;
26497
+ }
26498
+ if (streamKind === "assistant_text" && content && contentType !== "audio") {
26499
+ events.push({
26500
+ _tag: "AssistantContentBlock",
26501
+ content,
26502
+ rawPayload: params
26503
+ });
26504
+ }
26505
+ break;
26506
+ }
26507
+ case "compaction_update": {
26508
+ const compactionId = readAcpText(upd, "compactionId");
26509
+ const status = readAcpText(upd, "status");
26510
+ if (compactionId === void 0 || status === void 0) break;
26511
+ const rawSummary = upd["summary"];
26512
+ events.push({
26513
+ _tag: "CompactionUpdated",
26514
+ compactionId,
26515
+ status,
26516
+ summary: rawSummary === void 0 ? void 0 : Array.isArray(rawSummary) ? textFromContentBlocks(rawSummary) ?? null : null,
26517
+ error: readAcpText(upd, "error")
26518
+ });
26519
+ break;
26520
+ }
26521
+ case "compaction_summary_chunk": {
26522
+ const compactionId = readAcpText(upd, "compactionId");
26523
+ const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
26524
+ const text = content?.["type"] === "text" ? content["text"] : void 0;
26525
+ if (compactionId === void 0 || typeof text !== "string" || text.length === 0) break;
26526
+ events.push({ _tag: "CompactionSummaryChunk", compactionId, text });
26527
+ break;
26528
+ }
26529
+ default:
26530
+ break;
26531
+ }
26532
+ return { ...modeId !== void 0 ? { modeId } : {}, events };
26533
+ }
26534
+ function filterMcpServersByAgentCapabilities(mcpServers, agentCapabilities) {
26535
+ return mcpServers.filter((server) => {
26536
+ if (!("type" in server) || server.type === void 0) {
26537
+ return true;
26538
+ }
26539
+ switch (server.type) {
26540
+ case "http":
26541
+ return agentCapabilities?.mcpCapabilities?.http === true;
26542
+ case "sse":
26543
+ return agentCapabilities?.mcpCapabilities?.sse === true;
26544
+ default:
26545
+ return true;
26546
+ }
26547
+ });
26548
+ }
26549
+
26550
+ // ../../packages/ycodium-acp-executor/src/events.ts
26551
+ function canonicalRequestTypeFromAcpKind(kind) {
26552
+ switch (kind) {
26553
+ case "execute":
26554
+ return "exec_command_approval";
26555
+ case "read":
26556
+ return "file_read_approval";
26557
+ case "edit":
26558
+ case "delete":
26559
+ case "move":
26560
+ return "file_change_approval";
26561
+ case "fetch":
26562
+ return "web_fetch_approval";
26563
+ case "search":
26564
+ return "web_search_approval";
26565
+ default:
26566
+ return "dynamic_tool_call";
26567
+ }
26568
+ }
26569
+ function fileChangesFromAcpPermission(permissionRequest) {
26570
+ const content = permissionRequest.toolCall?.data["content"];
26571
+ const changes = Array.isArray(content) ? content.flatMap((entry) => {
26572
+ if (entry === null || typeof entry !== "object") {
26573
+ return [];
26574
+ }
26575
+ const block = entry;
26576
+ if (block["type"] !== "diff" || typeof block["path"] !== "string" || typeof block["newText"] !== "string") {
26577
+ return [];
26578
+ }
26579
+ const oldText = typeof block["oldText"] === "string" ? block["oldText"] : void 0;
26580
+ return [
26581
+ {
26582
+ path: block["path"],
26583
+ changeKind: oldText === void 0 ? "add" : "modify",
26584
+ content: {
26585
+ kind: "replace",
26586
+ ...oldText !== void 0 ? { oldText } : {},
26587
+ newText: block["newText"]
26588
+ }
26589
+ }
26590
+ ];
26591
+ }) : [];
26592
+ if (changes.length > 0) {
26593
+ return changes;
26594
+ }
26595
+ if (canonicalRequestTypeFromAcpKind(permissionRequest.kind) !== "file_change_approval") {
26596
+ return void 0;
26597
+ }
26598
+ const locations = permissionRequest.toolCall?.data["locations"];
26599
+ const paths = Array.isArray(locations) ? locations.flatMap((entry) => {
26600
+ const path = entry?.["path"];
26601
+ return typeof path === "string" && path.trim().length > 0 ? [path] : [];
26602
+ }) : [];
26603
+ return paths.length > 0 ? paths.map((path) => ({ path, omitted: "unavailable" })) : void 0;
26604
+ }
26605
+ function runtimeItemStatusFromAcpToolStatus(status) {
26606
+ switch (status) {
26607
+ case "pending":
26608
+ case "inProgress":
26609
+ return "inProgress";
26610
+ case "completed":
26611
+ return "completed";
26612
+ case "failed":
26613
+ return "failed";
26614
+ default:
26615
+ return void 0;
26616
+ }
26617
+ }
26618
+ function makeAcpRequestOpenedEvent(input2) {
26619
+ const requestType = canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind);
26620
+ const toolName = requestType === "dynamic_tool_call" ? input2.permissionRequest.toolCall?.title : void 0;
26621
+ return {
26622
+ type: "request.opened",
26623
+ ...input2.stamp,
26624
+ provider: input2.provider,
26625
+ threadId: input2.threadId,
26626
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26627
+ requestId: input2.requestId,
26628
+ payload: {
26629
+ requestType,
26630
+ detail: input2.detail,
26631
+ ...toolName ? { toolName } : {},
26632
+ args: input2.args,
26633
+ ...input2.options ? { options: input2.options } : {},
26634
+ ...input2.fileChanges ? { fileChanges: input2.fileChanges } : {},
26635
+ declineReasonRelay: "queued"
26636
+ },
26637
+ raw: {
26638
+ source: input2.source,
26639
+ method: input2.method,
26640
+ payload: input2.rawPayload
26641
+ }
26642
+ };
26643
+ }
26644
+ function makeAcpRequestResolvedEvent(input2) {
26645
+ return {
26646
+ type: "request.resolved",
26647
+ ...input2.stamp,
26648
+ provider: input2.provider,
26649
+ threadId: input2.threadId,
26650
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26651
+ requestId: input2.requestId,
26652
+ payload: {
26653
+ requestType: canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind),
26654
+ decision: input2.decision,
26655
+ ...input2.reason ? { reason: input2.reason } : {}
26656
+ }
26657
+ };
26658
+ }
26659
+ function makeAcpPlanUpdatedEvent(input2) {
26660
+ return {
26661
+ type: "turn.plan.updated",
26662
+ ...input2.stamp,
26663
+ provider: input2.provider,
26664
+ threadId: input2.threadId,
26665
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26666
+ payload: input2.payload,
26667
+ raw: {
26668
+ source: input2.source,
26669
+ method: input2.method,
26670
+ payload: input2.rawPayload
26671
+ }
26672
+ };
26673
+ }
26674
+ function makeAcpToolCallEvent(input2) {
26675
+ const runtimeStatus = runtimeItemStatusFromAcpToolStatus(input2.toolCall.status);
26676
+ const { data } = input2.toolCall;
26677
+ return {
26678
+ type: input2.toolCall.status === "completed" || input2.toolCall.status === "failed" ? "item.completed" : "item.updated",
26679
+ ...input2.stamp,
26680
+ provider: input2.provider,
26681
+ threadId: input2.threadId,
26682
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26683
+ itemId: input2.toolCall.toolCallId,
26684
+ payload: {
26685
+ itemType: canonicalItemTypeFromAcpToolKind(input2.toolCall.kind),
26686
+ ...runtimeStatus ? { status: runtimeStatus } : {},
26687
+ ...input2.toolCall.title ? { title: input2.toolCall.title } : {},
26688
+ ...input2.toolCall.detail ? { detail: input2.toolCall.detail } : {},
26689
+ ...Object.keys(data).length > 0 ? { data } : {}
26690
+ },
26691
+ raw: {
26692
+ source: "acp.jsonrpc",
26693
+ method: "session/update",
26694
+ payload: input2.rawPayload
26695
+ }
26696
+ };
26697
+ }
26698
+ function makeAcpAssistantItemEvent(input2) {
26699
+ return {
26700
+ type: input2.lifecycle,
26701
+ ...input2.stamp,
26702
+ provider: input2.provider,
26703
+ threadId: input2.threadId,
26704
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26705
+ itemId: input2.itemId,
26706
+ payload: {
26707
+ itemType: "assistant_message",
26708
+ status: input2.lifecycle === "item.completed" ? "completed" : "inProgress"
26709
+ }
26710
+ };
26711
+ }
26712
+ function makeAcpContentDeltaEvent(input2) {
26713
+ return {
26714
+ type: "content.delta",
26715
+ ...input2.stamp,
26716
+ provider: input2.provider,
26717
+ threadId: input2.threadId,
26718
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
26719
+ ...input2.itemId ? { itemId: input2.itemId } : {},
26720
+ payload: {
26721
+ streamKind: input2.streamKind ?? "assistant_text",
26722
+ delta: input2.text
26723
+ },
26724
+ raw: {
26725
+ source: "acp.jsonrpc",
26726
+ method: "session/update",
26727
+ payload: input2.rawPayload
26728
+ }
26729
+ };
26730
+ }
26731
+ function retainToolCallUpdate(toolCalls, next, seen) {
26732
+ const tracked = toolCalls.get(next.toolCallId);
26733
+ const previous = tracked?.state;
26734
+ const nextToolCall = mergeToolCallState(previous, next);
26735
+ const decision = decideToolCallUpdateEmission({
26736
+ previous,
26737
+ next: nextToolCall,
26738
+ lastEmittedDetailLength: tracked?.lastEmittedDetailLength,
26739
+ skippedSinceEmit: tracked?.skippedSinceEmit ?? 0
26740
+ });
26741
+ if (nextToolCall.status === "completed" || nextToolCall.status === "failed") {
26742
+ toolCalls.delete(nextToolCall.toolCallId);
26743
+ } else {
26744
+ toolCalls.set(nextToolCall.toolCallId, {
26745
+ state: nextToolCall,
26746
+ lastEmittedDetailLength: decision.emit ? nextToolCall.detail?.length : tracked?.lastEmittedDetailLength,
26747
+ skippedSinceEmit: decision.skippedSinceEmit,
26748
+ turnId: tracked === void 0 ? seen.turnId : tracked.turnId,
26749
+ startedAtMs: tracked?.startedAtMs ?? (nextToolCall.status === "inProgress" ? seen.nowMs() : void 0),
26750
+ rawTitle: typeof seen.rawTitle === "string" ? seen.rawTitle : tracked?.rawTitle
26751
+ });
26752
+ }
26753
+ return { nextToolCall, decision };
26754
+ }
26755
+
26756
+ // ../../packages/ycodium-acp-executor/src/openCommands.ts
26757
+ function readOpenToolCalls(toolCalls, turnId) {
26758
+ const running = [];
26759
+ for (const tracked of toolCalls.values()) {
26760
+ if (tracked.turnId !== turnId || tracked.startedAtMs === void 0) continue;
26761
+ running.push({
26762
+ toolCallId: tracked.state.toolCallId,
26763
+ turnId: tracked.turnId,
26764
+ startedAtMs: tracked.startedAtMs,
26765
+ kind: tracked.state.kind,
26766
+ title: tracked.rawTitle,
26767
+ rawInput: tracked.state.data["rawInput"]
26768
+ });
26769
+ }
26770
+ return running;
26771
+ }
26772
+
26773
+ // ../../packages/ycodium-acp-executor/src/config-options.ts
26774
+ function isRecord4(value) {
26775
+ return typeof value === "object" && value !== null && !Array.isArray(value);
26776
+ }
26777
+ function asString(value) {
26778
+ return typeof value === "string" ? value : void 0;
26779
+ }
26780
+ function normalizedField(option, key) {
26781
+ return asString(option[key])?.trim().toLowerCase() ?? "";
26782
+ }
26783
+ function looksLikeEffortOption(option) {
26784
+ const id = normalizedField(option, "id");
26785
+ const name = normalizedField(option, "name");
26786
+ return id === "effort" || id === "reasoning" || name === "effort" || name === "reasoning" || name.includes("effort") || name.includes("reasoning") || normalizedField(option, "category") === "thought_level";
26787
+ }
26788
+ function flattenChoices(rawOptions, currentValue) {
26789
+ if (!Array.isArray(rawOptions)) return [];
26790
+ const out = [];
26791
+ const seen = /* @__PURE__ */ new Set();
26792
+ const push = (entry) => {
26793
+ if (!isRecord4(entry)) return;
26794
+ const value = asString(entry["value"]);
26795
+ if (value === void 0 || seen.has(value)) return;
26796
+ seen.add(value);
26797
+ const description = asString(entry["description"])?.trim();
26798
+ const name = asString(entry["name"])?.trim();
26799
+ out.push({
26800
+ value,
26801
+ ...name ? { name } : {},
26802
+ label: name || value,
26803
+ ...description ? { description } : {},
26804
+ ...currentValue !== void 0 && currentValue === value ? { isDefault: true } : {}
26805
+ });
26806
+ };
26807
+ for (const entry of rawOptions) {
26808
+ if (isRecord4(entry) && Array.isArray(entry["options"])) {
26809
+ for (const nested of entry["options"]) push(nested);
26810
+ continue;
26811
+ }
26812
+ push(entry);
26813
+ }
26814
+ return out;
26815
+ }
26816
+ function findAcpEffortConfig(configOptions) {
26817
+ if (!Array.isArray(configOptions)) return void 0;
26818
+ const candidates = configOptions.filter(isRecord4).filter((option) => normalizedField(option, "type") === "select").filter(looksLikeEffortOption);
26819
+ if (candidates.length === 0) return void 0;
26820
+ const picked = candidates.find((option) => normalizedField(option, "category") === "model_option") ?? candidates.find((option) => normalizedField(option, "id") === "effort") ?? candidates.find((option) => normalizedField(option, "category") === "thought_level") ?? candidates[0];
26821
+ if (picked === void 0) return void 0;
26822
+ const configId = asString(picked["id"])?.trim();
26823
+ if (!configId) return void 0;
26824
+ const choices = flattenChoices(picked["options"], asString(picked["currentValue"])?.trim());
26825
+ if (choices.length === 0) return void 0;
26826
+ return {
26827
+ configId,
26828
+ label: asString(picked["name"])?.trim() ?? "",
26829
+ choices
26830
+ };
26831
+ }
26832
+ function acpModelChoicesFromConfigOptions(configOptions) {
26833
+ if (!Array.isArray(configOptions)) return void 0;
26834
+ const records = configOptions.filter(isRecord4);
26835
+ const modelOption = records.find((option) => normalizedField(option, "category") === "model") ?? records.find(
26836
+ (option) => normalizedField(option, "id") === "model" && normalizedField(option, "type") === "select"
26837
+ );
26838
+ if (modelOption === void 0) return void 0;
26839
+ if (!asString(modelOption["id"])?.trim()) return void 0;
26840
+ return flattenChoices(modelOption["options"], asString(modelOption["currentValue"])?.trim());
26841
+ }
26842
+ function acpModelChoicesFromSessionModels(models) {
26843
+ if (!isRecord4(models) || !Array.isArray(models["availableModels"])) return void 0;
26844
+ const currentModelId = asString(models["currentModelId"])?.trim();
26845
+ const out = [];
26846
+ const seen = /* @__PURE__ */ new Set();
26847
+ for (const entry of models["availableModels"]) {
26848
+ if (!isRecord4(entry)) continue;
26849
+ const value = asString(entry["modelId"])?.trim();
26850
+ if (!value || seen.has(value)) continue;
26851
+ seen.add(value);
26852
+ const name = asString(entry["name"])?.trim();
26853
+ const description = asString(entry["description"])?.trim();
26854
+ out.push({
26855
+ value,
26856
+ ...name ? { name } : {},
26857
+ label: name || value,
26858
+ ...description ? { description } : {},
26859
+ ...currentModelId !== void 0 && currentModelId === value ? { isDefault: true } : {}
26860
+ });
26861
+ }
26862
+ return out;
26863
+ }
26864
+
26865
+ // ../../packages/ycodium-acp-executor/src/runtime-mode.ts
26866
+ function isRecord5(value) {
26867
+ return typeof value === "object" && value !== null && !Array.isArray(value);
26868
+ }
26869
+ function asString2(value) {
26870
+ return typeof value === "string" ? value : void 0;
26871
+ }
26872
+ function acpAvailableModes(setup) {
26873
+ if (!isRecord5(setup)) return [];
26874
+ const out = [];
26875
+ const seen = /* @__PURE__ */ new Set();
26876
+ const push = (entry) => {
26877
+ if (!isRecord5(entry)) return;
26878
+ const id = (asString2(entry["id"]) ?? asString2(entry["value"]))?.trim();
26879
+ if (!id || seen.has(id)) return;
26880
+ seen.add(id);
26881
+ const meta3 = entry["_meta"];
26882
+ const kind = isRecord5(meta3) ? asString2(meta3["kind"])?.trim().toLowerCase() : void 0;
26883
+ const name = asString2(entry["name"])?.trim();
26884
+ const description = asString2(entry["description"])?.trim();
26885
+ out.push({
26886
+ id,
26887
+ name: name || id,
26888
+ ...description ? { description } : {},
26889
+ ...kind ? { kind } : {}
26890
+ });
26891
+ };
26892
+ const modes = setup["modes"];
26893
+ if (isRecord5(modes) && Array.isArray(modes["availableModes"])) {
26894
+ for (const entry of modes["availableModes"]) push(entry);
26895
+ }
26896
+ const configOptions = setup["configOptions"];
26897
+ if (Array.isArray(configOptions)) {
26898
+ for (const option of configOptions) {
26899
+ if (!isRecord5(option)) continue;
26900
+ if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
26901
+ if (!Array.isArray(option["options"])) continue;
26902
+ for (const entry of option["options"]) push(entry);
26903
+ }
26904
+ }
26905
+ return out;
26906
+ }
26907
+ function acpModeConfigId(setup) {
26908
+ if (!isRecord5(setup)) return void 0;
26909
+ const configOptions = setup["configOptions"];
26910
+ if (!Array.isArray(configOptions)) return void 0;
26911
+ for (const option of configOptions) {
26912
+ if (!isRecord5(option)) continue;
26913
+ if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
26914
+ const id = asString2(option["id"])?.trim();
26915
+ if (id) return id;
26916
+ }
26917
+ return void 0;
26918
+ }
26919
+ function acpCurrentModeId(setup) {
26920
+ if (!isRecord5(setup)) return void 0;
26921
+ const modes = setup["modes"];
26922
+ if (isRecord5(modes)) {
26923
+ const current = asString2(modes["currentModeId"])?.trim();
26924
+ if (current) return current;
26925
+ }
26926
+ const configOptions = setup["configOptions"];
26927
+ if (Array.isArray(configOptions)) {
26928
+ for (const option of configOptions) {
26929
+ if (!isRecord5(option)) continue;
26930
+ if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
26931
+ const current = asString2(option["currentValue"])?.trim();
26932
+ if (current) return current;
26859
26933
  }
26860
- };
26934
+ }
26935
+ return void 0;
26861
26936
  }
26862
- function readAcpText(source, key) {
26863
- const value = source?.[key];
26864
- if (typeof value !== "string") return void 0;
26865
- const trimmed = value.trim();
26866
- return trimmed.length > 0 ? trimmed : void 0;
26937
+
26938
+ // ../../packages/ycodium-acp-executor/src/handshake.ts
26939
+ function acpInitializePayload(clientInfo, overrides) {
26940
+ return {
26941
+ protocolVersion: PROTOCOL_VERSION,
26942
+ clientCapabilities: {
26943
+ fs: {
26944
+ readTextFile: false,
26945
+ writeTextFile: false,
26946
+ ...overrides?.fs
26947
+ },
26948
+ terminal: overrides?.terminal ?? false
26949
+ },
26950
+ clientInfo
26951
+ };
26867
26952
  }
26868
- function textFromContentBlocks(blocks) {
26869
- const parts = blocks.flatMap(
26870
- (block) => isRecord3(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
26871
- );
26872
- const joined = parts.join("");
26873
- return joined.trim().length > 0 ? joined : void 0;
26953
+
26954
+ // ../../packages/ycodium-acp-executor/src/config-option-wiring.ts
26955
+ var VENDOR_CATEGORY_PREFIX = "_";
26956
+ var ACP_CONFIG_CATEGORY_HANDLING = {
26957
+ mode: {
26958
+ consumed: true,
26959
+ via: "runtime-mode.ts\uFF1AacpAvailableModes / acpCurrentModeId / acpModeConfigId"
26960
+ },
26961
+ model: {
26962
+ consumed: true,
26963
+ via: "runtime-model.ts:extractModelConfigId \u2192 executor.ts:applyRequestedModel"
26964
+ },
26965
+ thought_level: {
26966
+ consumed: true,
26967
+ via: "config-options.ts:findAcpEffortConfig \u2192 executor.ts:applyRequestedEffort"
26968
+ },
26969
+ model_option: {
26970
+ consumed: true,
26971
+ // 精确说法:它不是**识别器**,是**优先级**。`looksLikeEffortOption` 先筛出候选,
26972
+ // 标了 `model_option` 的在候选里排第一(厂商自己标的最准),排在 id 叫 `effort`
26973
+ // 的和标 `thought_level` 的前面。光有这个 category 而 id/name 不像力度档的,
26974
+ // 压根进不了候选。
26975
+ via: "config-options.ts:findAcpEffortConfig\uFF08\u5019\u9009\u91CC\u7684\u6700\u9AD8\u4F18\u5148\u7EA7\uFF0C\u538B\u8FC7 thought_level\uFF09"
26976
+ },
26977
+ model_config: {
26978
+ consumed: false,
26979
+ note: "\u53EA\u6709\u5BBF\u4E3B\u7684 CursorProvider \u6D88\u8D39\u8FC7\uFF08context / fast / thinking \u4E09\u4E2A\u5F00\u5173\uFF09\u3002Cursor 2026-09-20 \u5E9F\u5F03\u5220\u9664\uFF0C\u8FD9\u4E00\u7C7B\u73B0\u5728\u6CA1\u6709\u6D88\u8D39\u70B9\uFF1B\u6CA1\u89C1\u8FC7\u522B\u5BB6\u7684\u771F\u5B9E\u8F7D\u8377\uFF0C\u5148\u8BB0\u8D26\u4E0D\u731C\u5F62\u72B6\u3002"
26980
+ }
26981
+ };
26982
+ var KNOWN_CATEGORIES = new Set(Object.keys(ACP_CONFIG_CATEGORY_HANDLING));
26983
+ function unhandledConfigCategories(configOptions) {
26984
+ if (!configOptions) return [];
26985
+ const seen = /* @__PURE__ */ new Set();
26986
+ const out = [];
26987
+ for (const option of configOptions) {
26988
+ const category = option.category?.trim();
26989
+ if (!category) continue;
26990
+ if (KNOWN_CATEGORIES.has(category)) continue;
26991
+ if (seen.has(category)) continue;
26992
+ seen.add(category);
26993
+ out.push({
26994
+ category,
26995
+ optionId: option.id.trim(),
26996
+ vendorExtension: category.startsWith(VENDOR_CATEGORY_PREFIX)
26997
+ });
26998
+ }
26999
+ return out;
26874
27000
  }
26875
- function parseSessionUpdateEvent(params) {
26876
- const upd = params.update;
26877
- const events = [];
26878
- let modeId;
26879
- const kind = upd["sessionUpdate"];
26880
- switch (kind) {
26881
- case "current_mode_update": {
26882
- modeId = readAcpText(upd, "currentModeId");
26883
- if (modeId) {
26884
- events.push({
26885
- _tag: "ModeChanged",
26886
- modeId
26887
- });
26888
- }
26889
- break;
26890
- }
26891
- case "plan": {
26892
- const entries = Array.isArray(upd["entries"]) ? upd["entries"] : [];
26893
- const plan = entries.map((entry, index) => ({
26894
- step: readAcpText(entry, "content") ?? `Step ${index + 1}`,
26895
- status: normalizePlanStepStatus(isRecord3(entry) ? entry["status"] : void 0)
26896
- }));
26897
- if (plan.length > 0) {
26898
- events.push({
26899
- _tag: "PlanUpdated",
26900
- payload: {
26901
- plan
26902
- },
26903
- rawPayload: params
26904
- });
26905
- }
26906
- break;
26907
- }
26908
- case "tool_call":
26909
- case "tool_call_update": {
26910
- const toolCall = makeToolCallState(
26911
- {
26912
- toolCallId: upd["toolCallId"],
26913
- name: upd["name"],
26914
- title: typeof upd["title"] === "string" ? upd["title"] : void 0,
26915
- kind: upd["kind"],
26916
- status: upd["status"],
26917
- rawInput: upd["rawInput"],
26918
- rawOutput: upd["rawOutput"],
26919
- content: upd["content"],
26920
- locations: upd["locations"]
26921
- },
26922
- kind === "tool_call" ? { fallbackStatus: "pending" } : void 0
26923
- );
26924
- if (toolCall) {
26925
- events.push({
26926
- _tag: "ToolCallUpdated",
26927
- toolCall,
26928
- rawPayload: boundToolCallRawPayload(params, upd, toolCall)
26929
- });
26930
- }
26931
- break;
26932
- }
26933
- case "agent_message_chunk":
26934
- case "agent_thought_chunk": {
26935
- const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
26936
- const contentType = content?.["type"];
26937
- const streamKind = kind === "agent_thought_chunk" ? "reasoning_text" : "assistant_text";
26938
- if (contentType === "text") {
26939
- const text = typeof content?.["text"] === "string" ? content["text"] : "";
26940
- if (text.length > 0) {
26941
- events.push({
26942
- _tag: "ContentDelta",
26943
- text,
26944
- streamKind,
26945
- rawPayload: params
26946
- });
26947
- }
26948
- break;
26949
- }
26950
- if (streamKind === "assistant_text" && content && contentType !== "audio") {
26951
- events.push({
26952
- _tag: "AssistantContentBlock",
26953
- content,
26954
- rawPayload: params
26955
- });
26956
- }
26957
- break;
26958
- }
26959
- case "compaction_update": {
26960
- const compactionId = readAcpText(upd, "compactionId");
26961
- const status = readAcpText(upd, "status");
26962
- if (compactionId === void 0 || status === void 0) break;
26963
- const rawSummary = upd["summary"];
26964
- events.push({
26965
- _tag: "CompactionUpdated",
26966
- compactionId,
26967
- status,
26968
- summary: rawSummary === void 0 ? void 0 : Array.isArray(rawSummary) ? textFromContentBlocks(rawSummary) ?? null : null,
26969
- error: readAcpText(upd, "error")
26970
- });
26971
- break;
27001
+
27002
+ // ../../packages/ycodium-acp-executor/src/mutex.ts
27003
+ var Mutex = class {
27004
+ locked = false;
27005
+ waiters = [];
27006
+ get isLocked() {
27007
+ return this.locked;
27008
+ }
27009
+ acquire() {
27010
+ if (!this.locked) {
27011
+ this.locked = true;
27012
+ return Promise.resolve();
26972
27013
  }
26973
- case "compaction_summary_chunk": {
26974
- const compactionId = readAcpText(upd, "compactionId");
26975
- const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
26976
- const text = content?.["type"] === "text" ? content["text"] : void 0;
26977
- if (compactionId === void 0 || typeof text !== "string" || text.length === 0) break;
26978
- events.push({ _tag: "CompactionSummaryChunk", compactionId, text });
26979
- break;
27014
+ return new Promise((resolve6) => {
27015
+ this.waiters.push(resolve6);
27016
+ });
27017
+ }
27018
+ tryAcquire() {
27019
+ if (this.locked) {
27020
+ return false;
26980
27021
  }
26981
- default:
26982
- break;
27022
+ this.locked = true;
27023
+ return true;
26983
27024
  }
26984
- return { ...modeId !== void 0 ? { modeId } : {}, events };
26985
- }
26986
- function filterMcpServersByAgentCapabilities(mcpServers, agentCapabilities) {
26987
- return mcpServers.filter((server) => {
26988
- if (!("type" in server) || server.type === void 0) {
26989
- return true;
27025
+ release() {
27026
+ const next = this.waiters.shift();
27027
+ if (next) {
27028
+ next();
27029
+ return;
26990
27030
  }
26991
- switch (server.type) {
26992
- case "http":
26993
- return agentCapabilities?.mcpCapabilities?.http === true;
26994
- case "sse":
26995
- return agentCapabilities?.mcpCapabilities?.sse === true;
26996
- default:
26997
- return true;
27031
+ this.locked = false;
27032
+ }
27033
+ async runExclusive(fn) {
27034
+ await this.acquire();
27035
+ try {
27036
+ return await fn();
27037
+ } finally {
27038
+ this.release();
26998
27039
  }
26999
- });
27000
- }
27040
+ }
27041
+ };
27001
27042
 
27002
27043
  // ../../packages/ycodium-acp-executor/src/model-selection.ts
27003
27044
  function normalizeModelId(value) {
@@ -27256,24 +27297,11 @@ function createAcpExecutor(options2) {
27256
27297
  }
27257
27298
  for (const event of parsed.events) {
27258
27299
  if (event._tag === "ToolCallUpdated") {
27259
- const tracked = toolCalls.get(event.toolCall.toolCallId);
27260
- const previous = tracked?.state;
27261
- const nextToolCall = mergeToolCallState(previous, event.toolCall);
27262
- const decision = decideToolCallUpdateEmission({
27263
- previous,
27264
- next: nextToolCall,
27265
- lastEmittedDetailLength: tracked?.lastEmittedDetailLength,
27266
- skippedSinceEmit: tracked?.skippedSinceEmit ?? 0
27300
+ const { nextToolCall, decision } = retainToolCallUpdate(toolCalls, event.toolCall, {
27301
+ turnId: activeTurnId,
27302
+ rawTitle: params.update.title,
27303
+ nowMs
27267
27304
  });
27268
- if (nextToolCall.status === "completed" || nextToolCall.status === "failed") {
27269
- toolCalls.delete(nextToolCall.toolCallId);
27270
- } else {
27271
- toolCalls.set(nextToolCall.toolCallId, {
27272
- state: nextToolCall,
27273
- lastEmittedDetailLength: decision.emit ? nextToolCall.detail?.length : tracked?.lastEmittedDetailLength,
27274
- skippedSinceEmit: decision.skippedSinceEmit
27275
- });
27276
- }
27277
27305
  const hookResult = hooks.onToolCallUpdated?.({
27278
27306
  toolCallId: nextToolCall.toolCallId,
27279
27307
  status: nextToolCall.status,
@@ -28301,6 +28329,7 @@ function createAcpExecutor(options2) {
28301
28329
  respondToUserInput,
28302
28330
  setNativeMode,
28303
28331
  compact,
28332
+ openToolCalls: () => readOpenToolCalls(toolCalls, activeTurnId),
28304
28333
  dispose
28305
28334
  };
28306
28335
  }