@ycodium-ai/agent-grok 0.2.2974 → 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 +847 -818
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -24548,64 +24548,146 @@ function deriveToolActivityPresentation(input2) {
24548
24548
  };
24549
24549
  }
24550
24550
 
24551
- // ../../packages/ycodium-acp-executor/src/events.ts
24552
- function canonicalRequestTypeFromAcpKind(kind) {
24553
- switch (kind) {
24554
- case "execute":
24555
- return "exec_command_approval";
24556
- case "read":
24557
- return "file_read_approval";
24558
- case "edit":
24559
- case "delete":
24560
- case "move":
24561
- return "file_change_approval";
24562
- case "fetch":
24563
- return "web_fetch_approval";
24564
- case "search":
24565
- return "web_search_approval";
24566
- default:
24567
- return "dynamic_tool_call";
24551
+ // ../../packages/ycodium-acp-executor/src/runtime-model.ts
24552
+ function extractModelConfigId(sessionResponse) {
24553
+ const configOptions = sessionResponse.configOptions;
24554
+ if (!configOptions) return void 0;
24555
+ for (const opt of configOptions) {
24556
+ if (opt.category === "model" && opt.id.trim().length > 0) {
24557
+ return opt.id.trim();
24558
+ }
24568
24559
  }
24560
+ return configOptions.find((opt) => opt.id.trim() === "model" && opt.type === "select") ? "model" : void 0;
24569
24561
  }
24570
- function fileChangesFromAcpPermission(permissionRequest) {
24571
- const content = permissionRequest.toolCall?.data["content"];
24572
- const changes = Array.isArray(content) ? content.flatMap((entry) => {
24573
- if (entry === null || typeof entry !== "object") {
24574
- return [];
24562
+ function findSessionConfigOption(configOptions, configId) {
24563
+ if (!configOptions) {
24564
+ return void 0;
24565
+ }
24566
+ const normalizedConfigId = configId.trim();
24567
+ if (!normalizedConfigId) {
24568
+ return void 0;
24569
+ }
24570
+ return configOptions.find((option) => option.id.trim() === normalizedConfigId);
24571
+ }
24572
+ function collectSessionConfigOptionValues(configOption) {
24573
+ if (configOption.type !== "select" || !configOption.options) {
24574
+ return [];
24575
+ }
24576
+ return configOption.options.flatMap(
24577
+ (entry) => "value" in entry ? [entry.value] : entry.options.map((option) => option.value)
24578
+ );
24579
+ }
24580
+ function collectSessionModelIds(models) {
24581
+ if (!isRecord3(models) || !Array.isArray(models["availableModels"])) {
24582
+ return [];
24583
+ }
24584
+ return models["availableModels"].flatMap(
24585
+ (model) => isRecord3(model) && typeof model["modelId"] === "string" ? [model["modelId"]] : []
24586
+ );
24587
+ }
24588
+ function catalogModelLastSegment(value) {
24589
+ if (value.startsWith("[")) {
24590
+ let parsed;
24591
+ try {
24592
+ parsed = JSON.parse(value);
24593
+ } catch {
24594
+ return void 0;
24575
24595
  }
24576
- const block = entry;
24577
- if (block["type"] !== "diff" || typeof block["path"] !== "string" || typeof block["newText"] !== "string") {
24578
- return [];
24596
+ if (!Array.isArray(parsed) || parsed.length < 2) return void 0;
24597
+ const last = parsed[parsed.length - 1];
24598
+ return typeof last === "string" ? last : void 0;
24599
+ }
24600
+ const separator = value.indexOf("/");
24601
+ return separator > 0 && separator < value.length - 1 ? value.slice(separator + 1) : void 0;
24602
+ }
24603
+ function matchAdvertisedModelValue(requestedModelId, advertisedValues) {
24604
+ const wanted = requestedModelId.trim();
24605
+ if (!wanted) return void 0;
24606
+ if (advertisedValues.includes(wanted)) return wanted;
24607
+ const byLastSegment = advertisedValues.filter(
24608
+ (value) => catalogModelLastSegment(value) === wanted
24609
+ );
24610
+ return byLastSegment.length === 1 ? byLastSegment[0] : void 0;
24611
+ }
24612
+ function parseSessionModeState(sessionResponse) {
24613
+ const modes = sessionResponse.modes;
24614
+ if (!modes) return void 0;
24615
+ const currentModeId = modes.currentModeId.trim();
24616
+ if (!currentModeId) {
24617
+ return void 0;
24618
+ }
24619
+ const availableModes = [];
24620
+ for (const mode of modes.availableModes) {
24621
+ const id = mode.id.trim();
24622
+ const name = mode.name.trim();
24623
+ if (!id || !name) {
24624
+ continue;
24579
24625
  }
24580
- const oldText = typeof block["oldText"] === "string" ? block["oldText"] : void 0;
24581
- return [
24582
- {
24583
- path: block["path"],
24584
- changeKind: oldText === void 0 ? "add" : "modify",
24585
- content: {
24586
- kind: "replace",
24587
- ...oldText !== void 0 ? { oldText } : {},
24588
- newText: block["newText"]
24589
- }
24590
- }
24591
- ];
24592
- }) : [];
24593
- if (changes.length > 0) {
24594
- return changes;
24626
+ const description = mode.description?.trim() || void 0;
24627
+ availableModes.push(
24628
+ description !== void 0 ? { id, name, description } : { id, name }
24629
+ );
24595
24630
  }
24596
- if (canonicalRequestTypeFromAcpKind(permissionRequest.kind) !== "file_change_approval") {
24631
+ if (availableModes.length === 0) {
24597
24632
  return void 0;
24598
24633
  }
24599
- const locations = permissionRequest.toolCall?.data["locations"];
24600
- const paths = Array.isArray(locations) ? locations.flatMap((entry) => {
24601
- const path = entry?.["path"];
24602
- return typeof path === "string" && path.trim().length > 0 ? [path] : [];
24603
- }) : [];
24604
- return paths.length > 0 ? paths.map((path) => ({ path, omitted: "unavailable" })) : void 0;
24634
+ return {
24635
+ currentModeId,
24636
+ availableModes
24637
+ };
24605
24638
  }
24606
- function runtimeItemStatusFromAcpToolStatus(status) {
24607
- switch (status) {
24639
+ function acpCommandsToSlashCommands(commands) {
24640
+ return commands.map((command) => ({
24641
+ name: command.name,
24642
+ ...command.description === void 0 ? {} : { description: command.description },
24643
+ ...command.inputHint === void 0 ? {} : { input: { hint: command.inputHint } }
24644
+ }));
24645
+ }
24646
+ function parseAvailableCommandsUpdate(params) {
24647
+ const update = params.update;
24648
+ if (update["sessionUpdate"] !== "available_commands_update") {
24649
+ return void 0;
24650
+ }
24651
+ const availableCommands = update["availableCommands"];
24652
+ if (!Array.isArray(availableCommands)) {
24653
+ return [];
24654
+ }
24655
+ const commands = [];
24656
+ for (const command of availableCommands) {
24657
+ if (!isRecord3(command)) {
24658
+ continue;
24659
+ }
24660
+ const name = typeof command["name"] === "string" ? command["name"].trim() : "";
24661
+ if (!name) {
24662
+ continue;
24663
+ }
24664
+ const description = typeof command["description"] === "string" ? command["description"].trim() || void 0 : void 0;
24665
+ const input2 = isRecord3(command["input"]) ? command["input"] : void 0;
24666
+ const inputHint = typeof input2?.["hint"] === "string" ? input2["hint"].trim() || void 0 : void 0;
24667
+ commands.push({
24668
+ name,
24669
+ ...description ? { description } : {},
24670
+ ...inputHint ? { inputHint } : {}
24671
+ });
24672
+ }
24673
+ return commands;
24674
+ }
24675
+ function normalizePlanStepStatus(raw) {
24676
+ switch (raw) {
24677
+ case "completed":
24678
+ return "completed";
24679
+ case "in_progress":
24680
+ case "inProgress":
24681
+ return "inProgress";
24682
+ default:
24683
+ return "pending";
24684
+ }
24685
+ }
24686
+ function normalizeToolCallStatus(raw, fallback) {
24687
+ switch (raw) {
24608
24688
  case "pending":
24689
+ return "pending";
24690
+ case "in_progress":
24609
24691
  case "inProgress":
24610
24692
  return "inProgress";
24611
24693
  case "completed":
@@ -24613,448 +24695,453 @@ function runtimeItemStatusFromAcpToolStatus(status) {
24613
24695
  case "failed":
24614
24696
  return "failed";
24615
24697
  default:
24616
- return void 0;
24698
+ return fallback;
24617
24699
  }
24618
24700
  }
24619
- function makeAcpRequestOpenedEvent(input2) {
24620
- const requestType = canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind);
24621
- const toolName = requestType === "dynamic_tool_call" ? input2.permissionRequest.toolCall?.title : void 0;
24622
- return {
24623
- type: "request.opened",
24624
- ...input2.stamp,
24625
- provider: input2.provider,
24626
- threadId: input2.threadId,
24627
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
24628
- requestId: input2.requestId,
24629
- payload: {
24630
- requestType,
24631
- detail: input2.detail,
24632
- ...toolName ? { toolName } : {},
24633
- args: input2.args,
24634
- ...input2.options ? { options: input2.options } : {},
24635
- ...input2.fileChanges ? { fileChanges: input2.fileChanges } : {},
24636
- declineReasonRelay: "queued"
24637
- },
24638
- raw: {
24639
- source: input2.source,
24640
- method: input2.method,
24641
- payload: input2.rawPayload
24701
+ function normalizeCommandValue2(value) {
24702
+ if (typeof value === "string" && value.trim().length > 0) {
24703
+ return value.trim();
24704
+ }
24705
+ if (!Array.isArray(value)) {
24706
+ return void 0;
24707
+ }
24708
+ const parts = [];
24709
+ for (const entry of value) {
24710
+ if (typeof entry === "string") {
24711
+ const part = entry.trim();
24712
+ if (part.length > 0) {
24713
+ parts.push(part);
24714
+ }
24642
24715
  }
24643
- };
24716
+ }
24717
+ return parts.length > 0 ? parts.join(" ") : void 0;
24644
24718
  }
24645
- function makeAcpRequestResolvedEvent(input2) {
24646
- return {
24647
- type: "request.resolved",
24648
- ...input2.stamp,
24649
- provider: input2.provider,
24650
- threadId: input2.threadId,
24651
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
24652
- requestId: input2.requestId,
24653
- payload: {
24654
- requestType: canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind),
24655
- decision: input2.decision,
24656
- ...input2.reason ? { reason: input2.reason } : {}
24657
- }
24658
- };
24719
+ function extractCommandFromTitle2(title) {
24720
+ if (!title) {
24721
+ return void 0;
24722
+ }
24723
+ const match = /`([^`]+)`/.exec(title);
24724
+ return match?.[1]?.trim() || void 0;
24659
24725
  }
24660
- function makeAcpPlanUpdatedEvent(input2) {
24661
- return {
24662
- type: "turn.plan.updated",
24663
- ...input2.stamp,
24664
- provider: input2.provider,
24665
- threadId: input2.threadId,
24666
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
24667
- payload: input2.payload,
24668
- raw: {
24669
- source: input2.source,
24670
- method: input2.method,
24671
- payload: input2.rawPayload
24672
- }
24673
- };
24674
- }
24675
- function makeAcpToolCallEvent(input2) {
24676
- const runtimeStatus = runtimeItemStatusFromAcpToolStatus(input2.toolCall.status);
24677
- const { data } = input2.toolCall;
24678
- return {
24679
- type: input2.toolCall.status === "completed" || input2.toolCall.status === "failed" ? "item.completed" : "item.updated",
24680
- ...input2.stamp,
24681
- provider: input2.provider,
24682
- threadId: input2.threadId,
24683
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
24684
- itemId: input2.toolCall.toolCallId,
24685
- payload: {
24686
- itemType: canonicalItemTypeFromAcpToolKind(input2.toolCall.kind),
24687
- ...runtimeStatus ? { status: runtimeStatus } : {},
24688
- ...input2.toolCall.title ? { title: input2.toolCall.title } : {},
24689
- ...input2.toolCall.detail ? { detail: input2.toolCall.detail } : {},
24690
- ...Object.keys(data).length > 0 ? { data } : {}
24691
- },
24692
- raw: {
24693
- source: "acp.jsonrpc",
24694
- method: "session/update",
24695
- payload: input2.rawPayload
24726
+ function extractToolCallCommand(rawInput, title) {
24727
+ if (isRecord3(rawInput)) {
24728
+ const directCommand = normalizeCommandValue2(rawInput["command"]);
24729
+ if (directCommand) {
24730
+ return directCommand;
24696
24731
  }
24697
- };
24698
- }
24699
- function makeAcpAssistantItemEvent(input2) {
24700
- return {
24701
- type: input2.lifecycle,
24702
- ...input2.stamp,
24703
- provider: input2.provider,
24704
- threadId: input2.threadId,
24705
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
24706
- itemId: input2.itemId,
24707
- payload: {
24708
- itemType: "assistant_message",
24709
- status: input2.lifecycle === "item.completed" ? "completed" : "inProgress"
24732
+ const executable = typeof rawInput["executable"] === "string" ? rawInput["executable"].trim() : "";
24733
+ const args = normalizeCommandValue2(rawInput["args"]);
24734
+ if (executable && args) {
24735
+ return `${executable} ${args}`;
24710
24736
  }
24711
- };
24712
- }
24713
- function makeAcpContentDeltaEvent(input2) {
24714
- return {
24715
- type: "content.delta",
24716
- ...input2.stamp,
24717
- provider: input2.provider,
24718
- threadId: input2.threadId,
24719
- ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
24720
- ...input2.itemId ? { itemId: input2.itemId } : {},
24721
- payload: {
24722
- streamKind: input2.streamKind ?? "assistant_text",
24723
- delta: input2.text
24724
- },
24725
- raw: {
24726
- source: "acp.jsonrpc",
24727
- method: "session/update",
24728
- payload: input2.rawPayload
24737
+ if (executable) {
24738
+ return executable;
24729
24739
  }
24730
- };
24731
- }
24732
-
24733
- // ../../packages/ycodium-acp-executor/src/config-options.ts
24734
- function isRecord4(value) {
24735
- return typeof value === "object" && value !== null && !Array.isArray(value);
24736
- }
24737
- function asString(value) {
24738
- return typeof value === "string" ? value : void 0;
24739
- }
24740
- function normalizedField(option, key) {
24741
- return asString(option[key])?.trim().toLowerCase() ?? "";
24740
+ }
24741
+ return extractCommandFromTitle2(title);
24742
24742
  }
24743
- function looksLikeEffortOption(option) {
24744
- const id = normalizedField(option, "id");
24745
- const name = normalizedField(option, "name");
24746
- return id === "effort" || id === "reasoning" || name === "effort" || name === "reasoning" || name.includes("effort") || name.includes("reasoning") || normalizedField(option, "category") === "thought_level";
24743
+ var TOOL_CALL_CONTENT_MAX_CHARS = 8e3;
24744
+ var TOOL_CALL_CONTENT_TRUNCATION_MARKER = "[Earlier output truncated]\n\n";
24745
+ function boundToolCallOutputText(text3) {
24746
+ if (text3.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
24747
+ return text3;
24748
+ }
24749
+ const tail = text3.slice(text3.length - TOOL_CALL_CONTENT_MAX_CHARS);
24750
+ return `${TOOL_CALL_CONTENT_TRUNCATION_MARKER}${tail}`;
24747
24751
  }
24748
- function flattenChoices(rawOptions, currentValue) {
24749
- if (!Array.isArray(rawOptions)) return [];
24750
- const out = [];
24751
- const seen = /* @__PURE__ */ new Set();
24752
- const push = (entry) => {
24753
- if (!isRecord4(entry)) return;
24754
- const value = asString(entry["value"]);
24755
- if (value === void 0 || seen.has(value)) return;
24756
- seen.add(value);
24757
- const description = asString(entry["description"])?.trim();
24758
- const name = asString(entry["name"])?.trim();
24759
- out.push({
24760
- value,
24761
- ...name ? { name } : {},
24762
- label: name || value,
24763
- ...description ? { description } : {},
24764
- ...currentValue !== void 0 && currentValue === value ? { isDefault: true } : {}
24765
- });
24766
- };
24767
- for (const entry of rawOptions) {
24768
- if (isRecord4(entry) && Array.isArray(entry["options"])) {
24769
- for (const nested of entry["options"]) push(nested);
24770
- continue;
24752
+ var RAW_OUTPUT_TEXT_FIELDS = ["content", "stdout", "stderr", "output"];
24753
+ function boundToolCallRawOutput(rawOutput) {
24754
+ if (!isRecord3(rawOutput)) {
24755
+ return rawOutput;
24756
+ }
24757
+ let changed = false;
24758
+ const bounded = { ...rawOutput };
24759
+ for (const field of RAW_OUTPUT_TEXT_FIELDS) {
24760
+ const value = rawOutput[field];
24761
+ if (typeof value === "string" && value.length > TOOL_CALL_CONTENT_MAX_CHARS) {
24762
+ bounded[field] = boundToolCallOutputText(value);
24763
+ changed = true;
24771
24764
  }
24772
- push(entry);
24773
24765
  }
24774
- return out;
24775
- }
24776
- function findAcpEffortConfig(configOptions) {
24777
- if (!Array.isArray(configOptions)) return void 0;
24778
- const candidates = configOptions.filter(isRecord4).filter((option) => normalizedField(option, "type") === "select").filter(looksLikeEffortOption);
24779
- if (candidates.length === 0) return void 0;
24780
- 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];
24781
- if (picked === void 0) return void 0;
24782
- const configId = asString(picked["id"])?.trim();
24783
- if (!configId) return void 0;
24784
- const choices = flattenChoices(picked["options"], asString(picked["currentValue"])?.trim());
24785
- if (choices.length === 0) return void 0;
24786
- return {
24787
- configId,
24788
- label: asString(picked["name"])?.trim() ?? "",
24789
- choices
24790
- };
24791
- }
24792
-
24793
- // ../../packages/ycodium-acp-executor/src/runtime-mode.ts
24794
- function isRecord5(value) {
24795
- return typeof value === "object" && value !== null && !Array.isArray(value);
24766
+ return changed ? bounded : rawOutput;
24796
24767
  }
24797
- function asString2(value) {
24798
- return typeof value === "string" ? value : void 0;
24768
+ function toolCallContentText(entry) {
24769
+ if (entry.type !== "content" || entry.content?.type !== "text") {
24770
+ return void 0;
24771
+ }
24772
+ return entry.content.text;
24799
24773
  }
24800
- function acpModeConfigId(setup) {
24801
- if (!isRecord5(setup)) return void 0;
24802
- const configOptions = setup["configOptions"];
24803
- if (!Array.isArray(configOptions)) return void 0;
24804
- for (const option of configOptions) {
24805
- if (!isRecord5(option)) continue;
24806
- if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
24807
- const id = asString2(option["id"])?.trim();
24808
- if (id) return id;
24774
+ function extractTextContentFromToolCallContent(content) {
24775
+ if (!Array.isArray(content)) {
24776
+ return { text: void 0, content: void 0 };
24809
24777
  }
24810
- return void 0;
24778
+ const typed = content;
24779
+ const chunks = [];
24780
+ for (const entry of typed) {
24781
+ const text3 = toolCallContentText(entry)?.trim();
24782
+ if (text3) {
24783
+ chunks.push(text3);
24784
+ }
24785
+ }
24786
+ if (chunks.length === 0) {
24787
+ return { text: void 0, content: typed };
24788
+ }
24789
+ const joined = chunks.join("\n");
24790
+ if (joined.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
24791
+ return { text: joined, content: typed };
24792
+ }
24793
+ const bounded = boundToolCallOutputText(joined);
24794
+ const lastContributingTextIndex = typed.reduce(
24795
+ (lastIndex, entry, index) => toolCallContentText(entry)?.trim() ? index : lastIndex,
24796
+ -1
24797
+ );
24798
+ const boundedContent = typed.flatMap((entry, index) => {
24799
+ if (toolCallContentText(entry) === void 0) {
24800
+ return [entry];
24801
+ }
24802
+ if (index !== lastContributingTextIndex) {
24803
+ return [];
24804
+ }
24805
+ return [{ type: "content", content: { type: "text", text: bounded } }];
24806
+ });
24807
+ return { text: bounded, content: boundedContent };
24811
24808
  }
24812
-
24813
- // ../../packages/ycodium-acp-executor/src/handshake.ts
24814
- function acpInitializePayload(clientInfo, overrides) {
24815
- return {
24816
- protocolVersion: PROTOCOL_VERSION,
24817
- clientCapabilities: {
24818
- fs: {
24819
- readTextFile: false,
24820
- writeTextFile: false,
24821
- ...overrides?.fs
24822
- },
24823
- terminal: overrides?.terminal ?? false
24824
- },
24825
- clientInfo
24826
- };
24809
+ function normalizeToolKind(kind) {
24810
+ return typeof kind === "string" && kind.trim().length > 0 ? kind.trim() : void 0;
24827
24811
  }
24828
-
24829
- // ../../packages/ycodium-acp-executor/src/config-option-wiring.ts
24830
- var VENDOR_CATEGORY_PREFIX = "_";
24831
- var ACP_CONFIG_CATEGORY_HANDLING = {
24832
- mode: {
24833
- consumed: true,
24834
- via: "runtime-mode.ts\uFF1AacpAvailableModes / acpCurrentModeId / acpModeConfigId"
24835
- },
24836
- model: {
24837
- consumed: true,
24838
- via: "runtime-model.ts:extractModelConfigId \u2192 executor.ts:applyRequestedModel"
24839
- },
24840
- thought_level: {
24841
- consumed: true,
24842
- via: "config-options.ts:findAcpEffortConfig \u2192 executor.ts:applyRequestedEffort"
24843
- },
24844
- model_option: {
24845
- consumed: true,
24846
- // 精确说法:它不是**识别器**,是**优先级**。`looksLikeEffortOption` 先筛出候选,
24847
- // 标了 `model_option` 的在候选里排第一(厂商自己标的最准),排在 id 叫 `effort`
24848
- // 的和标 `thought_level` 的前面。光有这个 category 而 id/name 不像力度档的,
24849
- // 压根进不了候选。
24850
- via: "config-options.ts:findAcpEffortConfig\uFF08\u5019\u9009\u91CC\u7684\u6700\u9AD8\u4F18\u5148\u7EA7\uFF0C\u538B\u8FC7 thought_level\uFF09"
24851
- },
24852
- model_config: {
24853
- consumed: false,
24854
- 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"
24812
+ function makeToolCallState(input2, options) {
24813
+ const toolCallId = typeof input2.toolCallId === "string" ? input2.toolCallId.trim() : "";
24814
+ if (!toolCallId) {
24815
+ return void 0;
24855
24816
  }
24856
- };
24857
- var KNOWN_CATEGORIES = new Set(Object.keys(ACP_CONFIG_CATEGORY_HANDLING));
24858
- function unhandledConfigCategories(configOptions) {
24859
- if (!configOptions) return [];
24860
- const seen = /* @__PURE__ */ new Set();
24861
- const out = [];
24862
- for (const option of configOptions) {
24863
- const category = option.category?.trim();
24864
- if (!category) continue;
24865
- if (KNOWN_CATEGORIES.has(category)) continue;
24866
- if (seen.has(category)) continue;
24867
- seen.add(category);
24868
- out.push({
24869
- category,
24870
- optionId: option.id.trim(),
24871
- vendorExtension: category.startsWith(VENDOR_CATEGORY_PREFIX)
24872
- });
24817
+ const title = typeof input2.title === "string" ? input2.title.trim() || void 0 : void 0;
24818
+ const command = extractToolCallCommand(input2.rawInput, title);
24819
+ const extractedContent = extractTextContentFromToolCallContent(input2.content);
24820
+ const textContent = extractedContent.text;
24821
+ const normalizedTitle = title && title.toLowerCase() !== "terminal" && title.toLowerCase() !== "tool call" ? title : void 0;
24822
+ const data = { toolCallId };
24823
+ const kind = normalizeToolKind(input2.kind);
24824
+ if (kind) {
24825
+ data["kind"] = kind;
24873
24826
  }
24874
- return out;
24875
- }
24876
-
24877
- // ../../packages/ycodium-acp-executor/src/mutex.ts
24878
- var Mutex = class {
24879
- locked = false;
24880
- waiters = [];
24881
- get isLocked() {
24882
- return this.locked;
24827
+ const name = readAcpText(input2, "name");
24828
+ if (name) {
24829
+ data["name"] = name;
24883
24830
  }
24884
- acquire() {
24885
- if (!this.locked) {
24886
- this.locked = true;
24887
- return Promise.resolve();
24888
- }
24889
- return new Promise((resolve2) => {
24890
- this.waiters.push(resolve2);
24891
- });
24831
+ if (command) {
24832
+ data["command"] = command;
24892
24833
  }
24893
- tryAcquire() {
24894
- if (this.locked) {
24895
- return false;
24896
- }
24897
- this.locked = true;
24898
- return true;
24834
+ if (input2.rawInput !== void 0) {
24835
+ data["rawInput"] = input2.rawInput;
24899
24836
  }
24900
- release() {
24901
- const next = this.waiters.shift();
24902
- if (next) {
24903
- next();
24904
- return;
24837
+ if (input2.rawOutput !== void 0) {
24838
+ data["rawOutput"] = boundToolCallRawOutput(input2.rawOutput);
24839
+ }
24840
+ if (input2.content !== void 0) {
24841
+ data["content"] = extractedContent.content ?? input2.content;
24842
+ }
24843
+ if (input2.locations !== void 0) {
24844
+ data["locations"] = input2.locations;
24845
+ }
24846
+ const fallbackDetail = command ?? normalizedTitle ?? textContent;
24847
+ const hasPresentationSeed = title !== void 0 || kind !== void 0 || command !== void 0 || normalizedTitle !== void 0 || textContent !== void 0;
24848
+ const presentation = hasPresentationSeed ? deriveToolActivityPresentation({
24849
+ itemType: canonicalItemTypeFromAcpToolKind(kind),
24850
+ title,
24851
+ detail: fallbackDetail,
24852
+ data,
24853
+ fallbackSummary: title ?? "Tool"
24854
+ }) : void 0;
24855
+ const status = normalizeToolCallStatus(input2.status, options?.fallbackStatus);
24856
+ return {
24857
+ toolCallId,
24858
+ ...kind ? { kind } : {},
24859
+ ...presentation?.summary ? { title: presentation.summary } : {},
24860
+ ...status ? { status } : {},
24861
+ ...command ? { command } : {},
24862
+ ...presentation?.detail ? { detail: presentation.detail } : {},
24863
+ data
24864
+ };
24865
+ }
24866
+ function mergeToolCallState(previous, next) {
24867
+ const nextKind = typeof next.data["kind"] === "string" ? next.data["kind"] : void 0;
24868
+ const kind = nextKind ?? previous?.kind;
24869
+ const title = next.title ?? previous?.title;
24870
+ const status = next.status ?? previous?.status;
24871
+ const command = next.command ?? previous?.command;
24872
+ const detail = next.detail ?? previous?.detail;
24873
+ return {
24874
+ toolCallId: next.toolCallId,
24875
+ ...kind ? { kind } : {},
24876
+ ...title ? { title } : {},
24877
+ ...status ? { status } : {},
24878
+ ...command ? { command } : {},
24879
+ ...detail ? { detail } : {},
24880
+ data: {
24881
+ ...previous?.data,
24882
+ ...next.data
24905
24883
  }
24906
- this.locked = false;
24884
+ };
24885
+ }
24886
+ var TOOL_CALL_UPDATE_MIN_DETAIL_GROWTH_CHARS = 256;
24887
+ var TOOL_CALL_UPDATE_COALESCE_LIMIT = 10;
24888
+ function decideToolCallUpdateEmission(input2) {
24889
+ const { previous, next, lastEmittedDetailLength, skippedSinceEmit } = input2;
24890
+ if (next.status === "completed" || next.status === "failed") {
24891
+ return { emit: true, skippedSinceEmit: 0 };
24907
24892
  }
24908
- async runExclusive(fn) {
24909
- await this.acquire();
24910
- try {
24911
- return await fn();
24912
- } finally {
24913
- this.release();
24914
- }
24893
+ if (!next.detail) {
24894
+ return { emit: false, skippedSinceEmit };
24915
24895
  }
24916
- };
24917
-
24918
- // ../../packages/ycodium-acp-executor/src/runtime-model.ts
24919
- function extractModelConfigId(sessionResponse) {
24920
- const configOptions = sessionResponse.configOptions;
24921
- if (!configOptions) return void 0;
24922
- for (const opt of configOptions) {
24923
- if (opt.category === "model" && opt.id.trim().length > 0) {
24924
- return opt.id.trim();
24925
- }
24896
+ if (previous === void 0 || previous.title !== next.title) {
24897
+ return { emit: true, skippedSinceEmit: 0 };
24926
24898
  }
24927
- return configOptions.find((opt) => opt.id.trim() === "model" && opt.type === "select") ? "model" : void 0;
24928
- }
24929
- function findSessionConfigOption(configOptions, configId) {
24930
- if (!configOptions) {
24931
- return void 0;
24899
+ if (previous.detail === next.detail) {
24900
+ return { emit: false, skippedSinceEmit };
24932
24901
  }
24933
- const normalizedConfigId = configId.trim();
24934
- if (!normalizedConfigId) {
24935
- return void 0;
24902
+ const grewMeaningfully = lastEmittedDetailLength === void 0 || Math.abs(next.detail.length - lastEmittedDetailLength) >= TOOL_CALL_UPDATE_MIN_DETAIL_GROWTH_CHARS;
24903
+ if (grewMeaningfully || skippedSinceEmit + 1 >= TOOL_CALL_UPDATE_COALESCE_LIMIT) {
24904
+ return { emit: true, skippedSinceEmit: 0 };
24936
24905
  }
24937
- return configOptions.find((option) => option.id.trim() === normalizedConfigId);
24906
+ return { emit: false, skippedSinceEmit: skippedSinceEmit + 1 };
24938
24907
  }
24939
- function collectSessionConfigOptionValues(configOption) {
24940
- if (configOption.type !== "select" || !configOption.options) {
24941
- return [];
24942
- }
24943
- return configOption.options.flatMap(
24944
- (entry) => "value" in entry ? [entry.value] : entry.options.map((option) => option.value)
24908
+ function parsePermissionRequest(params) {
24909
+ const toolCall = makeToolCallState(
24910
+ {
24911
+ toolCallId: params.toolCall.toolCallId,
24912
+ title: params.toolCall.title,
24913
+ kind: params.toolCall.kind,
24914
+ status: params.toolCall.status,
24915
+ rawInput: params.toolCall.rawInput,
24916
+ rawOutput: params.toolCall.rawOutput,
24917
+ content: params.toolCall.content,
24918
+ locations: params.toolCall.locations
24919
+ },
24920
+ { fallbackStatus: "pending" }
24945
24921
  );
24922
+ const kind = normalizeToolKind(params.toolCall.kind) ?? "unknown";
24923
+ const detail = toolCall?.command ?? toolCall?.title ?? toolCall?.detail ?? (typeof params.sessionId === "string" ? `Session ${params.sessionId}` : void 0);
24924
+ return {
24925
+ kind,
24926
+ ...detail ? { detail } : {},
24927
+ ...toolCall ? { toolCall } : {}
24928
+ };
24946
24929
  }
24947
- function collectSessionModelIds(models) {
24948
- if (!isRecord3(models) || !Array.isArray(models["availableModels"])) {
24949
- return [];
24930
+ function boundToolCallRawPayload(params, update, toolCall) {
24931
+ const boundedContent = toolCall.data["content"];
24932
+ const boundedRawOutput = toolCall.data["rawOutput"];
24933
+ const contentBounded = update["content"] !== void 0 && boundedContent !== update["content"];
24934
+ const rawOutputBounded = update["rawOutput"] !== void 0 && boundedRawOutput !== update["rawOutput"];
24935
+ if (!contentBounded && !rawOutputBounded) {
24936
+ return params;
24950
24937
  }
24951
- return models["availableModels"].flatMap(
24952
- (model) => isRecord3(model) && typeof model["modelId"] === "string" ? [model["modelId"]] : []
24953
- );
24954
- }
24955
- function catalogModelLastSegment(value) {
24956
- if (value.startsWith("[")) {
24957
- let parsed;
24958
- try {
24959
- parsed = JSON.parse(value);
24960
- } catch {
24961
- return void 0;
24938
+ return {
24939
+ ...params,
24940
+ update: {
24941
+ ...update,
24942
+ ...contentBounded ? { content: boundedContent } : {},
24943
+ ...rawOutputBounded ? { rawOutput: boundedRawOutput } : {}
24962
24944
  }
24963
- if (!Array.isArray(parsed) || parsed.length < 2) return void 0;
24964
- const last = parsed[parsed.length - 1];
24965
- return typeof last === "string" ? last : void 0;
24966
- }
24967
- const separator = value.indexOf("/");
24968
- return separator > 0 && separator < value.length - 1 ? value.slice(separator + 1) : void 0;
24945
+ };
24969
24946
  }
24970
- function matchAdvertisedModelValue(requestedModelId, advertisedValues) {
24971
- const wanted = requestedModelId.trim();
24972
- if (!wanted) return void 0;
24973
- if (advertisedValues.includes(wanted)) return wanted;
24974
- const byLastSegment = advertisedValues.filter(
24975
- (value) => catalogModelLastSegment(value) === wanted
24947
+ function readAcpText(source, key) {
24948
+ const value = source?.[key];
24949
+ if (typeof value !== "string") return void 0;
24950
+ const trimmed3 = value.trim();
24951
+ return trimmed3.length > 0 ? trimmed3 : void 0;
24952
+ }
24953
+ function textFromContentBlocks(blocks) {
24954
+ const parts = blocks.flatMap(
24955
+ (block) => isRecord3(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
24976
24956
  );
24977
- return byLastSegment.length === 1 ? byLastSegment[0] : void 0;
24957
+ const joined = parts.join("");
24958
+ return joined.trim().length > 0 ? joined : void 0;
24978
24959
  }
24979
- function parseSessionModeState(sessionResponse) {
24980
- const modes = sessionResponse.modes;
24981
- if (!modes) return void 0;
24982
- const currentModeId = modes.currentModeId.trim();
24983
- if (!currentModeId) {
24984
- return void 0;
24985
- }
24986
- const availableModes = [];
24987
- for (const mode of modes.availableModes) {
24988
- const id = mode.id.trim();
24989
- const name = mode.name.trim();
24990
- if (!id || !name) {
24991
- continue;
24960
+ function parseSessionUpdateEvent(params) {
24961
+ const upd = params.update;
24962
+ const events = [];
24963
+ let modeId;
24964
+ const kind = upd["sessionUpdate"];
24965
+ switch (kind) {
24966
+ case "current_mode_update": {
24967
+ modeId = readAcpText(upd, "currentModeId");
24968
+ if (modeId) {
24969
+ events.push({
24970
+ _tag: "ModeChanged",
24971
+ modeId
24972
+ });
24973
+ }
24974
+ break;
24975
+ }
24976
+ case "plan": {
24977
+ const entries = Array.isArray(upd["entries"]) ? upd["entries"] : [];
24978
+ const plan = entries.map((entry, index) => ({
24979
+ step: readAcpText(entry, "content") ?? `Step ${index + 1}`,
24980
+ status: normalizePlanStepStatus(isRecord3(entry) ? entry["status"] : void 0)
24981
+ }));
24982
+ if (plan.length > 0) {
24983
+ events.push({
24984
+ _tag: "PlanUpdated",
24985
+ payload: {
24986
+ plan
24987
+ },
24988
+ rawPayload: params
24989
+ });
24990
+ }
24991
+ break;
24992
+ }
24993
+ case "tool_call":
24994
+ case "tool_call_update": {
24995
+ const toolCall = makeToolCallState(
24996
+ {
24997
+ toolCallId: upd["toolCallId"],
24998
+ name: upd["name"],
24999
+ title: typeof upd["title"] === "string" ? upd["title"] : void 0,
25000
+ kind: upd["kind"],
25001
+ status: upd["status"],
25002
+ rawInput: upd["rawInput"],
25003
+ rawOutput: upd["rawOutput"],
25004
+ content: upd["content"],
25005
+ locations: upd["locations"]
25006
+ },
25007
+ kind === "tool_call" ? { fallbackStatus: "pending" } : void 0
25008
+ );
25009
+ if (toolCall) {
25010
+ events.push({
25011
+ _tag: "ToolCallUpdated",
25012
+ toolCall,
25013
+ rawPayload: boundToolCallRawPayload(params, upd, toolCall)
25014
+ });
25015
+ }
25016
+ break;
25017
+ }
25018
+ case "agent_message_chunk":
25019
+ case "agent_thought_chunk": {
25020
+ const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
25021
+ const contentType = content?.["type"];
25022
+ const streamKind = kind === "agent_thought_chunk" ? "reasoning_text" : "assistant_text";
25023
+ if (contentType === "text") {
25024
+ const text3 = typeof content?.["text"] === "string" ? content["text"] : "";
25025
+ if (text3.length > 0) {
25026
+ events.push({
25027
+ _tag: "ContentDelta",
25028
+ text: text3,
25029
+ streamKind,
25030
+ rawPayload: params
25031
+ });
25032
+ }
25033
+ break;
25034
+ }
25035
+ if (streamKind === "assistant_text" && content && contentType !== "audio") {
25036
+ events.push({
25037
+ _tag: "AssistantContentBlock",
25038
+ content,
25039
+ rawPayload: params
25040
+ });
25041
+ }
25042
+ break;
25043
+ }
25044
+ case "compaction_update": {
25045
+ const compactionId = readAcpText(upd, "compactionId");
25046
+ const status = readAcpText(upd, "status");
25047
+ if (compactionId === void 0 || status === void 0) break;
25048
+ const rawSummary = upd["summary"];
25049
+ events.push({
25050
+ _tag: "CompactionUpdated",
25051
+ compactionId,
25052
+ status,
25053
+ summary: rawSummary === void 0 ? void 0 : Array.isArray(rawSummary) ? textFromContentBlocks(rawSummary) ?? null : null,
25054
+ error: readAcpText(upd, "error")
25055
+ });
25056
+ break;
25057
+ }
25058
+ case "compaction_summary_chunk": {
25059
+ const compactionId = readAcpText(upd, "compactionId");
25060
+ const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
25061
+ const text3 = content?.["type"] === "text" ? content["text"] : void 0;
25062
+ if (compactionId === void 0 || typeof text3 !== "string" || text3.length === 0) break;
25063
+ events.push({ _tag: "CompactionSummaryChunk", compactionId, text: text3 });
25064
+ break;
24992
25065
  }
24993
- const description = mode.description?.trim() || void 0;
24994
- availableModes.push(
24995
- description !== void 0 ? { id, name, description } : { id, name }
24996
- );
24997
- }
24998
- if (availableModes.length === 0) {
24999
- return void 0;
25066
+ default:
25067
+ break;
25000
25068
  }
25001
- return {
25002
- currentModeId,
25003
- availableModes
25004
- };
25069
+ return { ...modeId !== void 0 ? { modeId } : {}, events };
25005
25070
  }
25006
- function acpCommandsToSlashCommands(commands) {
25007
- return commands.map((command) => ({
25008
- name: command.name,
25009
- ...command.description === void 0 ? {} : { description: command.description },
25010
- ...command.inputHint === void 0 ? {} : { input: { hint: command.inputHint } }
25011
- }));
25071
+ function filterMcpServersByAgentCapabilities(mcpServers, agentCapabilities) {
25072
+ return mcpServers.filter((server) => {
25073
+ if (!("type" in server) || server.type === void 0) {
25074
+ return true;
25075
+ }
25076
+ switch (server.type) {
25077
+ case "http":
25078
+ return agentCapabilities?.mcpCapabilities?.http === true;
25079
+ case "sse":
25080
+ return agentCapabilities?.mcpCapabilities?.sse === true;
25081
+ default:
25082
+ return true;
25083
+ }
25084
+ });
25012
25085
  }
25013
- function parseAvailableCommandsUpdate(params) {
25014
- const update = params.update;
25015
- if (update["sessionUpdate"] !== "available_commands_update") {
25016
- return void 0;
25017
- }
25018
- const availableCommands = update["availableCommands"];
25019
- if (!Array.isArray(availableCommands)) {
25020
- return [];
25086
+
25087
+ // ../../packages/ycodium-acp-executor/src/events.ts
25088
+ function canonicalRequestTypeFromAcpKind(kind) {
25089
+ switch (kind) {
25090
+ case "execute":
25091
+ return "exec_command_approval";
25092
+ case "read":
25093
+ return "file_read_approval";
25094
+ case "edit":
25095
+ case "delete":
25096
+ case "move":
25097
+ return "file_change_approval";
25098
+ case "fetch":
25099
+ return "web_fetch_approval";
25100
+ case "search":
25101
+ return "web_search_approval";
25102
+ default:
25103
+ return "dynamic_tool_call";
25021
25104
  }
25022
- const commands = [];
25023
- for (const command of availableCommands) {
25024
- if (!isRecord3(command)) {
25025
- continue;
25105
+ }
25106
+ function fileChangesFromAcpPermission(permissionRequest) {
25107
+ const content = permissionRequest.toolCall?.data["content"];
25108
+ const changes = Array.isArray(content) ? content.flatMap((entry) => {
25109
+ if (entry === null || typeof entry !== "object") {
25110
+ return [];
25026
25111
  }
25027
- const name = typeof command["name"] === "string" ? command["name"].trim() : "";
25028
- if (!name) {
25029
- continue;
25112
+ const block = entry;
25113
+ if (block["type"] !== "diff" || typeof block["path"] !== "string" || typeof block["newText"] !== "string") {
25114
+ return [];
25030
25115
  }
25031
- const description = typeof command["description"] === "string" ? command["description"].trim() || void 0 : void 0;
25032
- const input2 = isRecord3(command["input"]) ? command["input"] : void 0;
25033
- const inputHint = typeof input2?.["hint"] === "string" ? input2["hint"].trim() || void 0 : void 0;
25034
- commands.push({
25035
- name,
25036
- ...description ? { description } : {},
25037
- ...inputHint ? { inputHint } : {}
25038
- });
25116
+ const oldText = typeof block["oldText"] === "string" ? block["oldText"] : void 0;
25117
+ return [
25118
+ {
25119
+ path: block["path"],
25120
+ changeKind: oldText === void 0 ? "add" : "modify",
25121
+ content: {
25122
+ kind: "replace",
25123
+ ...oldText !== void 0 ? { oldText } : {},
25124
+ newText: block["newText"]
25125
+ }
25126
+ }
25127
+ ];
25128
+ }) : [];
25129
+ if (changes.length > 0) {
25130
+ return changes;
25039
25131
  }
25040
- return commands;
25041
- }
25042
- function normalizePlanStepStatus(raw) {
25043
- switch (raw) {
25044
- case "completed":
25045
- return "completed";
25046
- case "in_progress":
25047
- case "inProgress":
25048
- return "inProgress";
25049
- default:
25050
- return "pending";
25132
+ if (canonicalRequestTypeFromAcpKind(permissionRequest.kind) !== "file_change_approval") {
25133
+ return void 0;
25051
25134
  }
25135
+ const locations = permissionRequest.toolCall?.data["locations"];
25136
+ const paths = Array.isArray(locations) ? locations.flatMap((entry) => {
25137
+ const path = entry?.["path"];
25138
+ return typeof path === "string" && path.trim().length > 0 ? [path] : [];
25139
+ }) : [];
25140
+ return paths.length > 0 ? paths.map((path) => ({ path, omitted: "unavailable" })) : void 0;
25052
25141
  }
25053
- function normalizeToolCallStatus(raw, fallback) {
25054
- switch (raw) {
25142
+ function runtimeItemStatusFromAcpToolStatus(status) {
25143
+ switch (status) {
25055
25144
  case "pending":
25056
- return "pending";
25057
- case "in_progress":
25058
25145
  case "inProgress":
25059
25146
  return "inProgress";
25060
25147
  case "completed":
@@ -25062,394 +25149,348 @@ function normalizeToolCallStatus(raw, fallback) {
25062
25149
  case "failed":
25063
25150
  return "failed";
25064
25151
  default:
25065
- return fallback;
25066
- }
25067
- }
25068
- function normalizeCommandValue2(value) {
25069
- if (typeof value === "string" && value.trim().length > 0) {
25070
- return value.trim();
25071
- }
25072
- if (!Array.isArray(value)) {
25073
- return void 0;
25074
- }
25075
- const parts = [];
25076
- for (const entry of value) {
25077
- if (typeof entry === "string") {
25078
- const part = entry.trim();
25079
- if (part.length > 0) {
25080
- parts.push(part);
25081
- }
25082
- }
25083
- }
25084
- return parts.length > 0 ? parts.join(" ") : void 0;
25085
- }
25086
- function extractCommandFromTitle2(title) {
25087
- if (!title) {
25088
- return void 0;
25089
- }
25090
- const match = /`([^`]+)`/.exec(title);
25091
- return match?.[1]?.trim() || void 0;
25092
- }
25093
- function extractToolCallCommand(rawInput, title) {
25094
- if (isRecord3(rawInput)) {
25095
- const directCommand = normalizeCommandValue2(rawInput["command"]);
25096
- if (directCommand) {
25097
- return directCommand;
25098
- }
25099
- const executable = typeof rawInput["executable"] === "string" ? rawInput["executable"].trim() : "";
25100
- const args = normalizeCommandValue2(rawInput["args"]);
25101
- if (executable && args) {
25102
- return `${executable} ${args}`;
25103
- }
25104
- if (executable) {
25105
- return executable;
25106
- }
25107
- }
25108
- return extractCommandFromTitle2(title);
25109
- }
25110
- var TOOL_CALL_CONTENT_MAX_CHARS = 8e3;
25111
- var TOOL_CALL_CONTENT_TRUNCATION_MARKER = "[Earlier output truncated]\n\n";
25112
- function boundToolCallOutputText(text3) {
25113
- if (text3.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
25114
- return text3;
25152
+ return void 0;
25115
25153
  }
25116
- const tail = text3.slice(text3.length - TOOL_CALL_CONTENT_MAX_CHARS);
25117
- return `${TOOL_CALL_CONTENT_TRUNCATION_MARKER}${tail}`;
25118
25154
  }
25119
- var RAW_OUTPUT_TEXT_FIELDS = ["content", "stdout", "stderr", "output"];
25120
- function boundToolCallRawOutput(rawOutput) {
25121
- if (!isRecord3(rawOutput)) {
25122
- return rawOutput;
25123
- }
25124
- let changed = false;
25125
- const bounded = { ...rawOutput };
25126
- for (const field of RAW_OUTPUT_TEXT_FIELDS) {
25127
- const value = rawOutput[field];
25128
- if (typeof value === "string" && value.length > TOOL_CALL_CONTENT_MAX_CHARS) {
25129
- bounded[field] = boundToolCallOutputText(value);
25130
- changed = true;
25155
+ function makeAcpRequestOpenedEvent(input2) {
25156
+ const requestType = canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind);
25157
+ const toolName = requestType === "dynamic_tool_call" ? input2.permissionRequest.toolCall?.title : void 0;
25158
+ return {
25159
+ type: "request.opened",
25160
+ ...input2.stamp,
25161
+ provider: input2.provider,
25162
+ threadId: input2.threadId,
25163
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
25164
+ requestId: input2.requestId,
25165
+ payload: {
25166
+ requestType,
25167
+ detail: input2.detail,
25168
+ ...toolName ? { toolName } : {},
25169
+ args: input2.args,
25170
+ ...input2.options ? { options: input2.options } : {},
25171
+ ...input2.fileChanges ? { fileChanges: input2.fileChanges } : {},
25172
+ declineReasonRelay: "queued"
25173
+ },
25174
+ raw: {
25175
+ source: input2.source,
25176
+ method: input2.method,
25177
+ payload: input2.rawPayload
25131
25178
  }
25132
- }
25133
- return changed ? bounded : rawOutput;
25134
- }
25135
- function toolCallContentText(entry) {
25136
- if (entry.type !== "content" || entry.content?.type !== "text") {
25137
- return void 0;
25138
- }
25139
- return entry.content.text;
25179
+ };
25140
25180
  }
25141
- function extractTextContentFromToolCallContent(content) {
25142
- if (!Array.isArray(content)) {
25143
- return { text: void 0, content: void 0 };
25144
- }
25145
- const typed = content;
25146
- const chunks = [];
25147
- for (const entry of typed) {
25148
- const text3 = toolCallContentText(entry)?.trim();
25149
- if (text3) {
25150
- chunks.push(text3);
25151
- }
25152
- }
25153
- if (chunks.length === 0) {
25154
- return { text: void 0, content: typed };
25155
- }
25156
- const joined = chunks.join("\n");
25157
- if (joined.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
25158
- return { text: joined, content: typed };
25159
- }
25160
- const bounded = boundToolCallOutputText(joined);
25161
- const lastContributingTextIndex = typed.reduce(
25162
- (lastIndex, entry, index) => toolCallContentText(entry)?.trim() ? index : lastIndex,
25163
- -1
25164
- );
25165
- const boundedContent = typed.flatMap((entry, index) => {
25166
- if (toolCallContentText(entry) === void 0) {
25167
- return [entry];
25181
+ function makeAcpRequestResolvedEvent(input2) {
25182
+ return {
25183
+ type: "request.resolved",
25184
+ ...input2.stamp,
25185
+ provider: input2.provider,
25186
+ threadId: input2.threadId,
25187
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
25188
+ requestId: input2.requestId,
25189
+ payload: {
25190
+ requestType: canonicalRequestTypeFromAcpKind(input2.permissionRequest.kind),
25191
+ decision: input2.decision,
25192
+ ...input2.reason ? { reason: input2.reason } : {}
25168
25193
  }
25169
- if (index !== lastContributingTextIndex) {
25170
- return [];
25194
+ };
25195
+ }
25196
+ function makeAcpPlanUpdatedEvent(input2) {
25197
+ return {
25198
+ type: "turn.plan.updated",
25199
+ ...input2.stamp,
25200
+ provider: input2.provider,
25201
+ threadId: input2.threadId,
25202
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
25203
+ payload: input2.payload,
25204
+ raw: {
25205
+ source: input2.source,
25206
+ method: input2.method,
25207
+ payload: input2.rawPayload
25171
25208
  }
25172
- return [{ type: "content", content: { type: "text", text: bounded } }];
25173
- });
25174
- return { text: bounded, content: boundedContent };
25209
+ };
25175
25210
  }
25176
- function normalizeToolKind(kind) {
25177
- return typeof kind === "string" && kind.trim().length > 0 ? kind.trim() : void 0;
25211
+ function makeAcpToolCallEvent(input2) {
25212
+ const runtimeStatus = runtimeItemStatusFromAcpToolStatus(input2.toolCall.status);
25213
+ const { data } = input2.toolCall;
25214
+ return {
25215
+ type: input2.toolCall.status === "completed" || input2.toolCall.status === "failed" ? "item.completed" : "item.updated",
25216
+ ...input2.stamp,
25217
+ provider: input2.provider,
25218
+ threadId: input2.threadId,
25219
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
25220
+ itemId: input2.toolCall.toolCallId,
25221
+ payload: {
25222
+ itemType: canonicalItemTypeFromAcpToolKind(input2.toolCall.kind),
25223
+ ...runtimeStatus ? { status: runtimeStatus } : {},
25224
+ ...input2.toolCall.title ? { title: input2.toolCall.title } : {},
25225
+ ...input2.toolCall.detail ? { detail: input2.toolCall.detail } : {},
25226
+ ...Object.keys(data).length > 0 ? { data } : {}
25227
+ },
25228
+ raw: {
25229
+ source: "acp.jsonrpc",
25230
+ method: "session/update",
25231
+ payload: input2.rawPayload
25232
+ }
25233
+ };
25178
25234
  }
25179
- function makeToolCallState(input2, options) {
25180
- const toolCallId = typeof input2.toolCallId === "string" ? input2.toolCallId.trim() : "";
25181
- if (!toolCallId) {
25182
- return void 0;
25183
- }
25184
- const title = typeof input2.title === "string" ? input2.title.trim() || void 0 : void 0;
25185
- const command = extractToolCallCommand(input2.rawInput, title);
25186
- const extractedContent = extractTextContentFromToolCallContent(input2.content);
25187
- const textContent = extractedContent.text;
25188
- const normalizedTitle = title && title.toLowerCase() !== "terminal" && title.toLowerCase() !== "tool call" ? title : void 0;
25189
- const data = { toolCallId };
25190
- const kind = normalizeToolKind(input2.kind);
25191
- if (kind) {
25192
- data["kind"] = kind;
25193
- }
25194
- const name = readAcpText(input2, "name");
25195
- if (name) {
25196
- data["name"] = name;
25197
- }
25198
- if (command) {
25199
- data["command"] = command;
25200
- }
25201
- if (input2.rawInput !== void 0) {
25202
- data["rawInput"] = input2.rawInput;
25203
- }
25204
- if (input2.rawOutput !== void 0) {
25205
- data["rawOutput"] = boundToolCallRawOutput(input2.rawOutput);
25206
- }
25207
- if (input2.content !== void 0) {
25208
- data["content"] = extractedContent.content ?? input2.content;
25209
- }
25210
- if (input2.locations !== void 0) {
25211
- data["locations"] = input2.locations;
25212
- }
25213
- const fallbackDetail = command ?? normalizedTitle ?? textContent;
25214
- const hasPresentationSeed = title !== void 0 || kind !== void 0 || command !== void 0 || normalizedTitle !== void 0 || textContent !== void 0;
25215
- const presentation = hasPresentationSeed ? deriveToolActivityPresentation({
25216
- itemType: canonicalItemTypeFromAcpToolKind(kind),
25217
- title,
25218
- detail: fallbackDetail,
25219
- data,
25220
- fallbackSummary: title ?? "Tool"
25221
- }) : void 0;
25222
- const status = normalizeToolCallStatus(input2.status, options?.fallbackStatus);
25235
+ function makeAcpAssistantItemEvent(input2) {
25223
25236
  return {
25224
- toolCallId,
25225
- ...kind ? { kind } : {},
25226
- ...presentation?.summary ? { title: presentation.summary } : {},
25227
- ...status ? { status } : {},
25228
- ...command ? { command } : {},
25229
- ...presentation?.detail ? { detail: presentation.detail } : {},
25230
- data
25237
+ type: input2.lifecycle,
25238
+ ...input2.stamp,
25239
+ provider: input2.provider,
25240
+ threadId: input2.threadId,
25241
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
25242
+ itemId: input2.itemId,
25243
+ payload: {
25244
+ itemType: "assistant_message",
25245
+ status: input2.lifecycle === "item.completed" ? "completed" : "inProgress"
25246
+ }
25231
25247
  };
25232
25248
  }
25233
- function mergeToolCallState(previous, next) {
25234
- const nextKind = typeof next.data["kind"] === "string" ? next.data["kind"] : void 0;
25235
- const kind = nextKind ?? previous?.kind;
25236
- const title = next.title ?? previous?.title;
25237
- const status = next.status ?? previous?.status;
25238
- const command = next.command ?? previous?.command;
25239
- const detail = next.detail ?? previous?.detail;
25249
+ function makeAcpContentDeltaEvent(input2) {
25240
25250
  return {
25241
- toolCallId: next.toolCallId,
25242
- ...kind ? { kind } : {},
25243
- ...title ? { title } : {},
25244
- ...status ? { status } : {},
25245
- ...command ? { command } : {},
25246
- ...detail ? { detail } : {},
25247
- data: {
25248
- ...previous?.data,
25249
- ...next.data
25251
+ type: "content.delta",
25252
+ ...input2.stamp,
25253
+ provider: input2.provider,
25254
+ threadId: input2.threadId,
25255
+ ...input2.turnId !== void 0 ? { turnId: input2.turnId } : {},
25256
+ ...input2.itemId ? { itemId: input2.itemId } : {},
25257
+ payload: {
25258
+ streamKind: input2.streamKind ?? "assistant_text",
25259
+ delta: input2.text
25260
+ },
25261
+ raw: {
25262
+ source: "acp.jsonrpc",
25263
+ method: "session/update",
25264
+ payload: input2.rawPayload
25250
25265
  }
25251
25266
  };
25252
25267
  }
25253
- var TOOL_CALL_UPDATE_MIN_DETAIL_GROWTH_CHARS = 256;
25254
- var TOOL_CALL_UPDATE_COALESCE_LIMIT = 10;
25255
- function decideToolCallUpdateEmission(input2) {
25256
- const { previous, next, lastEmittedDetailLength, skippedSinceEmit } = input2;
25257
- if (next.status === "completed" || next.status === "failed") {
25258
- return { emit: true, skippedSinceEmit: 0 };
25259
- }
25260
- if (!next.detail) {
25261
- return { emit: false, skippedSinceEmit };
25262
- }
25263
- if (previous === void 0 || previous.title !== next.title) {
25264
- return { emit: true, skippedSinceEmit: 0 };
25268
+ function retainToolCallUpdate(toolCalls, next, seen) {
25269
+ const tracked = toolCalls.get(next.toolCallId);
25270
+ const previous = tracked?.state;
25271
+ const nextToolCall = mergeToolCallState(previous, next);
25272
+ const decision = decideToolCallUpdateEmission({
25273
+ previous,
25274
+ next: nextToolCall,
25275
+ lastEmittedDetailLength: tracked?.lastEmittedDetailLength,
25276
+ skippedSinceEmit: tracked?.skippedSinceEmit ?? 0
25277
+ });
25278
+ if (nextToolCall.status === "completed" || nextToolCall.status === "failed") {
25279
+ toolCalls.delete(nextToolCall.toolCallId);
25280
+ } else {
25281
+ toolCalls.set(nextToolCall.toolCallId, {
25282
+ state: nextToolCall,
25283
+ lastEmittedDetailLength: decision.emit ? nextToolCall.detail?.length : tracked?.lastEmittedDetailLength,
25284
+ skippedSinceEmit: decision.skippedSinceEmit,
25285
+ turnId: tracked === void 0 ? seen.turnId : tracked.turnId,
25286
+ startedAtMs: tracked?.startedAtMs ?? (nextToolCall.status === "inProgress" ? seen.nowMs() : void 0),
25287
+ rawTitle: typeof seen.rawTitle === "string" ? seen.rawTitle : tracked?.rawTitle
25288
+ });
25265
25289
  }
25266
- if (previous.detail === next.detail) {
25267
- return { emit: false, skippedSinceEmit };
25290
+ return { nextToolCall, decision };
25291
+ }
25292
+
25293
+ // ../../packages/ycodium-acp-executor/src/openCommands.ts
25294
+ function readOpenToolCalls(toolCalls, turnId) {
25295
+ const running = [];
25296
+ for (const tracked of toolCalls.values()) {
25297
+ if (tracked.turnId !== turnId || tracked.startedAtMs === void 0) continue;
25298
+ running.push({
25299
+ toolCallId: tracked.state.toolCallId,
25300
+ turnId: tracked.turnId,
25301
+ startedAtMs: tracked.startedAtMs,
25302
+ kind: tracked.state.kind,
25303
+ title: tracked.rawTitle,
25304
+ rawInput: tracked.state.data["rawInput"]
25305
+ });
25268
25306
  }
25269
- const grewMeaningfully = lastEmittedDetailLength === void 0 || Math.abs(next.detail.length - lastEmittedDetailLength) >= TOOL_CALL_UPDATE_MIN_DETAIL_GROWTH_CHARS;
25270
- if (grewMeaningfully || skippedSinceEmit + 1 >= TOOL_CALL_UPDATE_COALESCE_LIMIT) {
25271
- return { emit: true, skippedSinceEmit: 0 };
25307
+ return running;
25308
+ }
25309
+
25310
+ // ../../packages/ycodium-acp-executor/src/config-options.ts
25311
+ function isRecord4(value) {
25312
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25313
+ }
25314
+ function asString(value) {
25315
+ return typeof value === "string" ? value : void 0;
25316
+ }
25317
+ function normalizedField(option, key) {
25318
+ return asString(option[key])?.trim().toLowerCase() ?? "";
25319
+ }
25320
+ function looksLikeEffortOption(option) {
25321
+ const id = normalizedField(option, "id");
25322
+ const name = normalizedField(option, "name");
25323
+ return id === "effort" || id === "reasoning" || name === "effort" || name === "reasoning" || name.includes("effort") || name.includes("reasoning") || normalizedField(option, "category") === "thought_level";
25324
+ }
25325
+ function flattenChoices(rawOptions, currentValue) {
25326
+ if (!Array.isArray(rawOptions)) return [];
25327
+ const out = [];
25328
+ const seen = /* @__PURE__ */ new Set();
25329
+ const push = (entry) => {
25330
+ if (!isRecord4(entry)) return;
25331
+ const value = asString(entry["value"]);
25332
+ if (value === void 0 || seen.has(value)) return;
25333
+ seen.add(value);
25334
+ const description = asString(entry["description"])?.trim();
25335
+ const name = asString(entry["name"])?.trim();
25336
+ out.push({
25337
+ value,
25338
+ ...name ? { name } : {},
25339
+ label: name || value,
25340
+ ...description ? { description } : {},
25341
+ ...currentValue !== void 0 && currentValue === value ? { isDefault: true } : {}
25342
+ });
25343
+ };
25344
+ for (const entry of rawOptions) {
25345
+ if (isRecord4(entry) && Array.isArray(entry["options"])) {
25346
+ for (const nested of entry["options"]) push(nested);
25347
+ continue;
25348
+ }
25349
+ push(entry);
25272
25350
  }
25273
- return { emit: false, skippedSinceEmit: skippedSinceEmit + 1 };
25351
+ return out;
25274
25352
  }
25275
- function parsePermissionRequest(params) {
25276
- const toolCall = makeToolCallState(
25277
- {
25278
- toolCallId: params.toolCall.toolCallId,
25279
- title: params.toolCall.title,
25280
- kind: params.toolCall.kind,
25281
- status: params.toolCall.status,
25282
- rawInput: params.toolCall.rawInput,
25283
- rawOutput: params.toolCall.rawOutput,
25284
- content: params.toolCall.content,
25285
- locations: params.toolCall.locations
25286
- },
25287
- { fallbackStatus: "pending" }
25288
- );
25289
- const kind = normalizeToolKind(params.toolCall.kind) ?? "unknown";
25290
- const detail = toolCall?.command ?? toolCall?.title ?? toolCall?.detail ?? (typeof params.sessionId === "string" ? `Session ${params.sessionId}` : void 0);
25353
+ function findAcpEffortConfig(configOptions) {
25354
+ if (!Array.isArray(configOptions)) return void 0;
25355
+ const candidates = configOptions.filter(isRecord4).filter((option) => normalizedField(option, "type") === "select").filter(looksLikeEffortOption);
25356
+ if (candidates.length === 0) return void 0;
25357
+ 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];
25358
+ if (picked === void 0) return void 0;
25359
+ const configId = asString(picked["id"])?.trim();
25360
+ if (!configId) return void 0;
25361
+ const choices = flattenChoices(picked["options"], asString(picked["currentValue"])?.trim());
25362
+ if (choices.length === 0) return void 0;
25291
25363
  return {
25292
- kind,
25293
- ...detail ? { detail } : {},
25294
- ...toolCall ? { toolCall } : {}
25364
+ configId,
25365
+ label: asString(picked["name"])?.trim() ?? "",
25366
+ choices
25295
25367
  };
25296
25368
  }
25297
- function boundToolCallRawPayload(params, update, toolCall) {
25298
- const boundedContent = toolCall.data["content"];
25299
- const boundedRawOutput = toolCall.data["rawOutput"];
25300
- const contentBounded = update["content"] !== void 0 && boundedContent !== update["content"];
25301
- const rawOutputBounded = update["rawOutput"] !== void 0 && boundedRawOutput !== update["rawOutput"];
25302
- if (!contentBounded && !rawOutputBounded) {
25303
- return params;
25369
+
25370
+ // ../../packages/ycodium-acp-executor/src/runtime-mode.ts
25371
+ function isRecord5(value) {
25372
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25373
+ }
25374
+ function asString2(value) {
25375
+ return typeof value === "string" ? value : void 0;
25376
+ }
25377
+ function acpModeConfigId(setup) {
25378
+ if (!isRecord5(setup)) return void 0;
25379
+ const configOptions = setup["configOptions"];
25380
+ if (!Array.isArray(configOptions)) return void 0;
25381
+ for (const option of configOptions) {
25382
+ if (!isRecord5(option)) continue;
25383
+ if (asString2(option["category"])?.trim().toLowerCase() !== "mode") continue;
25384
+ const id = asString2(option["id"])?.trim();
25385
+ if (id) return id;
25304
25386
  }
25387
+ return void 0;
25388
+ }
25389
+
25390
+ // ../../packages/ycodium-acp-executor/src/handshake.ts
25391
+ function acpInitializePayload(clientInfo, overrides) {
25305
25392
  return {
25306
- ...params,
25307
- update: {
25308
- ...update,
25309
- ...contentBounded ? { content: boundedContent } : {},
25310
- ...rawOutputBounded ? { rawOutput: boundedRawOutput } : {}
25311
- }
25393
+ protocolVersion: PROTOCOL_VERSION,
25394
+ clientCapabilities: {
25395
+ fs: {
25396
+ readTextFile: false,
25397
+ writeTextFile: false,
25398
+ ...overrides?.fs
25399
+ },
25400
+ terminal: overrides?.terminal ?? false
25401
+ },
25402
+ clientInfo
25312
25403
  };
25313
25404
  }
25314
- function readAcpText(source, key) {
25315
- const value = source?.[key];
25316
- if (typeof value !== "string") return void 0;
25317
- const trimmed3 = value.trim();
25318
- return trimmed3.length > 0 ? trimmed3 : void 0;
25319
- }
25320
- function textFromContentBlocks(blocks) {
25321
- const parts = blocks.flatMap(
25322
- (block) => isRecord3(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
25323
- );
25324
- const joined = parts.join("");
25325
- return joined.trim().length > 0 ? joined : void 0;
25405
+
25406
+ // ../../packages/ycodium-acp-executor/src/config-option-wiring.ts
25407
+ var VENDOR_CATEGORY_PREFIX = "_";
25408
+ var ACP_CONFIG_CATEGORY_HANDLING = {
25409
+ mode: {
25410
+ consumed: true,
25411
+ via: "runtime-mode.ts\uFF1AacpAvailableModes / acpCurrentModeId / acpModeConfigId"
25412
+ },
25413
+ model: {
25414
+ consumed: true,
25415
+ via: "runtime-model.ts:extractModelConfigId \u2192 executor.ts:applyRequestedModel"
25416
+ },
25417
+ thought_level: {
25418
+ consumed: true,
25419
+ via: "config-options.ts:findAcpEffortConfig \u2192 executor.ts:applyRequestedEffort"
25420
+ },
25421
+ model_option: {
25422
+ consumed: true,
25423
+ // 精确说法:它不是**识别器**,是**优先级**。`looksLikeEffortOption` 先筛出候选,
25424
+ // 标了 `model_option` 的在候选里排第一(厂商自己标的最准),排在 id 叫 `effort`
25425
+ // 的和标 `thought_level` 的前面。光有这个 category 而 id/name 不像力度档的,
25426
+ // 压根进不了候选。
25427
+ via: "config-options.ts:findAcpEffortConfig\uFF08\u5019\u9009\u91CC\u7684\u6700\u9AD8\u4F18\u5148\u7EA7\uFF0C\u538B\u8FC7 thought_level\uFF09"
25428
+ },
25429
+ model_config: {
25430
+ consumed: false,
25431
+ 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"
25432
+ }
25433
+ };
25434
+ var KNOWN_CATEGORIES = new Set(Object.keys(ACP_CONFIG_CATEGORY_HANDLING));
25435
+ function unhandledConfigCategories(configOptions) {
25436
+ if (!configOptions) return [];
25437
+ const seen = /* @__PURE__ */ new Set();
25438
+ const out = [];
25439
+ for (const option of configOptions) {
25440
+ const category = option.category?.trim();
25441
+ if (!category) continue;
25442
+ if (KNOWN_CATEGORIES.has(category)) continue;
25443
+ if (seen.has(category)) continue;
25444
+ seen.add(category);
25445
+ out.push({
25446
+ category,
25447
+ optionId: option.id.trim(),
25448
+ vendorExtension: category.startsWith(VENDOR_CATEGORY_PREFIX)
25449
+ });
25450
+ }
25451
+ return out;
25326
25452
  }
25327
- function parseSessionUpdateEvent(params) {
25328
- const upd = params.update;
25329
- const events = [];
25330
- let modeId;
25331
- const kind = upd["sessionUpdate"];
25332
- switch (kind) {
25333
- case "current_mode_update": {
25334
- modeId = readAcpText(upd, "currentModeId");
25335
- if (modeId) {
25336
- events.push({
25337
- _tag: "ModeChanged",
25338
- modeId
25339
- });
25340
- }
25341
- break;
25342
- }
25343
- case "plan": {
25344
- const entries = Array.isArray(upd["entries"]) ? upd["entries"] : [];
25345
- const plan = entries.map((entry, index) => ({
25346
- step: readAcpText(entry, "content") ?? `Step ${index + 1}`,
25347
- status: normalizePlanStepStatus(isRecord3(entry) ? entry["status"] : void 0)
25348
- }));
25349
- if (plan.length > 0) {
25350
- events.push({
25351
- _tag: "PlanUpdated",
25352
- payload: {
25353
- plan
25354
- },
25355
- rawPayload: params
25356
- });
25357
- }
25358
- break;
25359
- }
25360
- case "tool_call":
25361
- case "tool_call_update": {
25362
- const toolCall = makeToolCallState(
25363
- {
25364
- toolCallId: upd["toolCallId"],
25365
- name: upd["name"],
25366
- title: typeof upd["title"] === "string" ? upd["title"] : void 0,
25367
- kind: upd["kind"],
25368
- status: upd["status"],
25369
- rawInput: upd["rawInput"],
25370
- rawOutput: upd["rawOutput"],
25371
- content: upd["content"],
25372
- locations: upd["locations"]
25373
- },
25374
- kind === "tool_call" ? { fallbackStatus: "pending" } : void 0
25375
- );
25376
- if (toolCall) {
25377
- events.push({
25378
- _tag: "ToolCallUpdated",
25379
- toolCall,
25380
- rawPayload: boundToolCallRawPayload(params, upd, toolCall)
25381
- });
25382
- }
25383
- break;
25384
- }
25385
- case "agent_message_chunk":
25386
- case "agent_thought_chunk": {
25387
- const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
25388
- const contentType = content?.["type"];
25389
- const streamKind = kind === "agent_thought_chunk" ? "reasoning_text" : "assistant_text";
25390
- if (contentType === "text") {
25391
- const text3 = typeof content?.["text"] === "string" ? content["text"] : "";
25392
- if (text3.length > 0) {
25393
- events.push({
25394
- _tag: "ContentDelta",
25395
- text: text3,
25396
- streamKind,
25397
- rawPayload: params
25398
- });
25399
- }
25400
- break;
25401
- }
25402
- if (streamKind === "assistant_text" && content && contentType !== "audio") {
25403
- events.push({
25404
- _tag: "AssistantContentBlock",
25405
- content,
25406
- rawPayload: params
25407
- });
25408
- }
25409
- break;
25410
- }
25411
- case "compaction_update": {
25412
- const compactionId = readAcpText(upd, "compactionId");
25413
- const status = readAcpText(upd, "status");
25414
- if (compactionId === void 0 || status === void 0) break;
25415
- const rawSummary = upd["summary"];
25416
- events.push({
25417
- _tag: "CompactionUpdated",
25418
- compactionId,
25419
- status,
25420
- summary: rawSummary === void 0 ? void 0 : Array.isArray(rawSummary) ? textFromContentBlocks(rawSummary) ?? null : null,
25421
- error: readAcpText(upd, "error")
25422
- });
25423
- break;
25453
+
25454
+ // ../../packages/ycodium-acp-executor/src/mutex.ts
25455
+ var Mutex = class {
25456
+ locked = false;
25457
+ waiters = [];
25458
+ get isLocked() {
25459
+ return this.locked;
25460
+ }
25461
+ acquire() {
25462
+ if (!this.locked) {
25463
+ this.locked = true;
25464
+ return Promise.resolve();
25424
25465
  }
25425
- case "compaction_summary_chunk": {
25426
- const compactionId = readAcpText(upd, "compactionId");
25427
- const content = isRecord3(upd["content"]) ? upd["content"] : void 0;
25428
- const text3 = content?.["type"] === "text" ? content["text"] : void 0;
25429
- if (compactionId === void 0 || typeof text3 !== "string" || text3.length === 0) break;
25430
- events.push({ _tag: "CompactionSummaryChunk", compactionId, text: text3 });
25431
- break;
25466
+ return new Promise((resolve2) => {
25467
+ this.waiters.push(resolve2);
25468
+ });
25469
+ }
25470
+ tryAcquire() {
25471
+ if (this.locked) {
25472
+ return false;
25432
25473
  }
25433
- default:
25434
- break;
25474
+ this.locked = true;
25475
+ return true;
25435
25476
  }
25436
- return { ...modeId !== void 0 ? { modeId } : {}, events };
25437
- }
25438
- function filterMcpServersByAgentCapabilities(mcpServers, agentCapabilities) {
25439
- return mcpServers.filter((server) => {
25440
- if (!("type" in server) || server.type === void 0) {
25441
- return true;
25477
+ release() {
25478
+ const next = this.waiters.shift();
25479
+ if (next) {
25480
+ next();
25481
+ return;
25442
25482
  }
25443
- switch (server.type) {
25444
- case "http":
25445
- return agentCapabilities?.mcpCapabilities?.http === true;
25446
- case "sse":
25447
- return agentCapabilities?.mcpCapabilities?.sse === true;
25448
- default:
25449
- return true;
25483
+ this.locked = false;
25484
+ }
25485
+ async runExclusive(fn) {
25486
+ await this.acquire();
25487
+ try {
25488
+ return await fn();
25489
+ } finally {
25490
+ this.release();
25450
25491
  }
25451
- });
25452
- }
25492
+ }
25493
+ };
25453
25494
 
25454
25495
  // ../../packages/ycodium-acp-executor/src/model-selection.ts
25455
25496
  function normalizeModelId(value) {
@@ -25708,24 +25749,11 @@ function createAcpExecutor(options) {
25708
25749
  }
25709
25750
  for (const event of parsed.events) {
25710
25751
  if (event._tag === "ToolCallUpdated") {
25711
- const tracked = toolCalls.get(event.toolCall.toolCallId);
25712
- const previous = tracked?.state;
25713
- const nextToolCall = mergeToolCallState(previous, event.toolCall);
25714
- const decision = decideToolCallUpdateEmission({
25715
- previous,
25716
- next: nextToolCall,
25717
- lastEmittedDetailLength: tracked?.lastEmittedDetailLength,
25718
- skippedSinceEmit: tracked?.skippedSinceEmit ?? 0
25752
+ const { nextToolCall, decision } = retainToolCallUpdate(toolCalls, event.toolCall, {
25753
+ turnId: activeTurnId,
25754
+ rawTitle: params.update.title,
25755
+ nowMs
25719
25756
  });
25720
- if (nextToolCall.status === "completed" || nextToolCall.status === "failed") {
25721
- toolCalls.delete(nextToolCall.toolCallId);
25722
- } else {
25723
- toolCalls.set(nextToolCall.toolCallId, {
25724
- state: nextToolCall,
25725
- lastEmittedDetailLength: decision.emit ? nextToolCall.detail?.length : tracked?.lastEmittedDetailLength,
25726
- skippedSinceEmit: decision.skippedSinceEmit
25727
- });
25728
- }
25729
25757
  const hookResult = hooks.onToolCallUpdated?.({
25730
25758
  toolCallId: nextToolCall.toolCallId,
25731
25759
  status: nextToolCall.status,
@@ -26753,6 +26781,7 @@ function createAcpExecutor(options) {
26753
26781
  respondToUserInput,
26754
26782
  setNativeMode,
26755
26783
  compact,
26784
+ openToolCalls: () => readOpenToolCalls(toolCalls, activeTurnId),
26756
26785
  dispose
26757
26786
  };
26758
26787
  }
@@ -28571,7 +28600,7 @@ var executors = [
28571
28600
  ];
28572
28601
  var index_default = definePlugin({
28573
28602
  id: "agent-grok",
28574
- apiVersion: 3,
28603
+ apiVersion: 5,
28575
28604
  executors,
28576
28605
  activate(ctx) {
28577
28606
  ctx.log.info("grok executor ready");