@ycodium-ai/agent-grok 0.2.2634 → 0.2.2664
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +660 -152
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -70,7 +70,10 @@ var GROK_CARD = {
|
|
|
70
70
|
// 档位走 spawn 旗标,切档要重开会话(与 runtimeModeSwitch 同为 next-turn 的原因)。
|
|
71
71
|
// 声明这一位让界面画这双手自报的三档;不声明就退回宿主四档,而四档在这只手上
|
|
72
72
|
// 有两档撞车(都落到 `auto`)。
|
|
73
|
-
nativeModeSwitch: true
|
|
73
|
+
nativeModeSwitch: true,
|
|
74
|
+
// 压缩走 CLI 宣告过的 `/compact` 命令(见 `compactContext`),进度与结果由执行器按
|
|
75
|
+
// 压缩生命周期事件报;CLI 没宣告这条命令时 `compactContext` 拒绝,不退回发文本。
|
|
76
|
+
contextCompaction: "native"
|
|
74
77
|
},
|
|
75
78
|
// 凭据由 CLI 自己保管在 `<GROK_HOME>/auth.json`,宿主读它只认 `/token`。
|
|
76
79
|
credentialSources: [
|
|
@@ -152,7 +155,7 @@ var GROK_CARD = {
|
|
|
152
155
|
|
|
153
156
|
// src/grokInstance.ts
|
|
154
157
|
import * as NodeCrypto2 from "node:crypto";
|
|
155
|
-
import * as
|
|
158
|
+
import * as NodeOS2 from "node:os";
|
|
156
159
|
import * as NodePath2 from "node:path";
|
|
157
160
|
import { mergeLaunchEnv } from "@ycodium-ai/plugin-api/executor";
|
|
158
161
|
import { nodeStreamsFromHandle as nodeStreamsFromHandle2 } from "@ycodium-ai/plugin-api/process-stdin";
|
|
@@ -3000,23 +3003,23 @@ function canParseURL(input2) {
|
|
|
3000
3003
|
return false;
|
|
3001
3004
|
}
|
|
3002
3005
|
}
|
|
3003
|
-
function validateURL(
|
|
3006
|
+
function validateURL(trimmed3, def) {
|
|
3004
3007
|
if (!("normalize" in def) && !("hostname" in def) && !("protocol" in def)) {
|
|
3005
|
-
return canParseURL(
|
|
3008
|
+
return canParseURL(trimmed3) || URL_UNPARSEABLE;
|
|
3006
3009
|
}
|
|
3007
|
-
return parseURLObject(
|
|
3010
|
+
return parseURLObject(trimmed3, def);
|
|
3008
3011
|
}
|
|
3009
|
-
function parseURLObject(
|
|
3010
|
-
if (!def.normalize && def.protocol?.source === httpProtocol.source && !/^https?:\/\//i.test(
|
|
3012
|
+
function parseURLObject(trimmed3, def) {
|
|
3013
|
+
if (!def.normalize && def.protocol?.source === httpProtocol.source && !/^https?:\/\//i.test(trimmed3)) {
|
|
3011
3014
|
return URL_BAD_FORMAT;
|
|
3012
3015
|
}
|
|
3013
3016
|
try {
|
|
3014
3017
|
if (typeof URL !== "undefined") {
|
|
3015
3018
|
const URLStatic = URL;
|
|
3016
3019
|
if (typeof URLStatic.parse === "function")
|
|
3017
|
-
return URLStatic.parse(
|
|
3020
|
+
return URLStatic.parse(trimmed3) ?? URL_UNPARSEABLE;
|
|
3018
3021
|
}
|
|
3019
|
-
return new URL(
|
|
3022
|
+
return new URL(trimmed3);
|
|
3020
3023
|
} catch {
|
|
3021
3024
|
return URL_UNPARSEABLE;
|
|
3022
3025
|
}
|
|
@@ -3037,8 +3040,8 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
3037
3040
|
$ZodStringFormat.init(inst, def);
|
|
3038
3041
|
inst._zod.check = (payload) => {
|
|
3039
3042
|
try {
|
|
3040
|
-
const
|
|
3041
|
-
const url2 = validateURL(
|
|
3043
|
+
const trimmed3 = payload.value.trim();
|
|
3044
|
+
const url2 = validateURL(trimmed3, def);
|
|
3042
3045
|
if (url2 === URL_BAD_FORMAT) {
|
|
3043
3046
|
payload.issues.push({
|
|
3044
3047
|
code: "invalid_format",
|
|
@@ -3061,7 +3064,7 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
3061
3064
|
return;
|
|
3062
3065
|
}
|
|
3063
3066
|
if (url2 === true) {
|
|
3064
|
-
payload.value = stripTabAndNewline(
|
|
3067
|
+
payload.value = stripTabAndNewline(trimmed3);
|
|
3065
3068
|
return;
|
|
3066
3069
|
}
|
|
3067
3070
|
if (def.hostname && !urlHostnameOk(url2, def.hostname)) {
|
|
@@ -3086,7 +3089,7 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
|
|
|
3086
3089
|
continue: !def.abort
|
|
3087
3090
|
});
|
|
3088
3091
|
}
|
|
3089
|
-
payload.value = def.normalize ? url2.href : stripTabAndNewline(
|
|
3092
|
+
payload.value = def.normalize ? url2.href : stripTabAndNewline(trimmed3);
|
|
3090
3093
|
return;
|
|
3091
3094
|
} catch (_) {
|
|
3092
3095
|
payload.issues.push({
|
|
@@ -9521,8 +9524,8 @@ function ko_default() {
|
|
|
9521
9524
|
}
|
|
9522
9525
|
|
|
9523
9526
|
// ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/locales/lt.js
|
|
9524
|
-
var capitalizeFirstCharacter = (
|
|
9525
|
-
return
|
|
9527
|
+
var capitalizeFirstCharacter = (text2) => {
|
|
9528
|
+
return text2.charAt(0).toUpperCase() + text2.slice(1);
|
|
9526
9529
|
};
|
|
9527
9530
|
function getUnitTypeFromNumber(number4) {
|
|
9528
9531
|
const abs = Math.abs(number4);
|
|
@@ -16816,8 +16819,8 @@ function rewriteKeyNames(ctx) {
|
|
|
16816
16819
|
bySchema.set(entry.schema, entry);
|
|
16817
16820
|
}
|
|
16818
16821
|
const rewrites = /* @__PURE__ */ new Map();
|
|
16819
|
-
for (const
|
|
16820
|
-
const seen = ctx.seen.get(
|
|
16822
|
+
for (const record3 of pendingRecords.get(ctx) ?? []) {
|
|
16823
|
+
const seen = ctx.seen.get(record3);
|
|
16821
16824
|
const names = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
16822
16825
|
if (!names || names === true || rewrites.has(names))
|
|
16823
16826
|
continue;
|
|
@@ -23584,11 +23587,21 @@ var AcpExecutorRequestError = class extends AcpExecutorError {
|
|
|
23584
23587
|
}
|
|
23585
23588
|
};
|
|
23586
23589
|
var AcpConnectionClosedError = class extends Error {
|
|
23587
|
-
constructor(message = "ACP connection closed") {
|
|
23588
|
-
super(message);
|
|
23590
|
+
constructor(message = "ACP connection closed", options) {
|
|
23591
|
+
super(message, options);
|
|
23589
23592
|
this.name = "AcpConnectionClosedError";
|
|
23590
23593
|
}
|
|
23591
23594
|
};
|
|
23595
|
+
async function withStartupStderr(error62, stderrTail) {
|
|
23596
|
+
if (!(error62 instanceof AcpConnectionClosedError) || stderrTail === void 0) return error62;
|
|
23597
|
+
const tail = await stderrTail();
|
|
23598
|
+
if (tail.length === 0) return error62;
|
|
23599
|
+
return new AcpConnectionClosedError(`${error62.message}
|
|
23600
|
+
Agent stderr (last lines):
|
|
23601
|
+
${tail}`, {
|
|
23602
|
+
cause: error62
|
|
23603
|
+
});
|
|
23604
|
+
}
|
|
23592
23605
|
|
|
23593
23606
|
// ../../packages/ycodium-acp-executor/src/jsonrpc.ts
|
|
23594
23607
|
function isRecord2(value) {
|
|
@@ -23730,12 +23743,12 @@ function asBytes(chunk) {
|
|
|
23730
23743
|
throw new TypeError("ACP readable produced a non-byte chunk");
|
|
23731
23744
|
}
|
|
23732
23745
|
function isEnqueueableLine(lineBytes) {
|
|
23733
|
-
const
|
|
23734
|
-
if (!
|
|
23746
|
+
const trimmed3 = textDecoder.decode(lineBytes).trim();
|
|
23747
|
+
if (!trimmed3) {
|
|
23735
23748
|
return false;
|
|
23736
23749
|
}
|
|
23737
23750
|
try {
|
|
23738
|
-
const parsed = JSON.parse(
|
|
23751
|
+
const parsed = JSON.parse(trimmed3);
|
|
23739
23752
|
return typeof parsed === "object" && parsed !== null;
|
|
23740
23753
|
} catch {
|
|
23741
23754
|
return false;
|
|
@@ -23933,9 +23946,9 @@ function createAcpConnection(options) {
|
|
|
23933
23946
|
const handleChunk = async (bytes) => {
|
|
23934
23947
|
const lines = lineBuffer.push(bytes);
|
|
23935
23948
|
for (const line of lines) {
|
|
23936
|
-
const
|
|
23937
|
-
if (
|
|
23938
|
-
log({ direction: "incoming", stage: "raw", payload:
|
|
23949
|
+
const trimmed3 = textDecoder.decode(line).trim();
|
|
23950
|
+
if (trimmed3) {
|
|
23951
|
+
log({ direction: "incoming", stage: "raw", payload: trimmed3 });
|
|
23939
23952
|
}
|
|
23940
23953
|
}
|
|
23941
23954
|
const expected = lines.filter(isEnqueueableLine).length;
|
|
@@ -23972,9 +23985,9 @@ function createAcpConnection(options) {
|
|
|
23972
23985
|
enqueueInbound(async () => {
|
|
23973
23986
|
const last = lineBuffer.flush();
|
|
23974
23987
|
if (last) {
|
|
23975
|
-
const
|
|
23976
|
-
if (
|
|
23977
|
-
log({ direction: "incoming", stage: "raw", payload:
|
|
23988
|
+
const trimmed3 = textDecoder.decode(last).trim();
|
|
23989
|
+
if (trimmed3) {
|
|
23990
|
+
log({ direction: "incoming", stage: "raw", payload: trimmed3 });
|
|
23978
23991
|
}
|
|
23979
23992
|
}
|
|
23980
23993
|
const expected = last && isEnqueueableLine(last) ? 1 : 0;
|
|
@@ -24087,10 +24100,10 @@ function selectAutoApprovedAcpPermissionOption(request) {
|
|
|
24087
24100
|
}
|
|
24088
24101
|
function parseAcpResumeCursor(raw, schemaVersion) {
|
|
24089
24102
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return void 0;
|
|
24090
|
-
const
|
|
24091
|
-
if (
|
|
24092
|
-
if (typeof
|
|
24093
|
-
return { sessionId:
|
|
24103
|
+
const record3 = raw;
|
|
24104
|
+
if (record3["schemaVersion"] !== schemaVersion) return void 0;
|
|
24105
|
+
if (typeof record3["sessionId"] !== "string" || !record3["sessionId"].trim()) return void 0;
|
|
24106
|
+
return { sessionId: record3["sessionId"].trim() };
|
|
24094
24107
|
}
|
|
24095
24108
|
function acpPromptSettlementBelongsToContext(input2) {
|
|
24096
24109
|
return input2.liveAcpSessionId === input2.expectedAcpSessionId && (input2.liveActiveTurnId === input2.turnId || input2.liveSessionActiveTurnId === input2.turnId);
|
|
@@ -24099,18 +24112,18 @@ function isAcpRequestPermissionParams(value) {
|
|
|
24099
24112
|
if (typeof value !== "object" || value === null) {
|
|
24100
24113
|
return false;
|
|
24101
24114
|
}
|
|
24102
|
-
const
|
|
24103
|
-
if (typeof
|
|
24115
|
+
const record3 = value;
|
|
24116
|
+
if (typeof record3["sessionId"] !== "string") {
|
|
24104
24117
|
return false;
|
|
24105
24118
|
}
|
|
24106
|
-
const toolCall =
|
|
24119
|
+
const toolCall = record3["toolCall"];
|
|
24107
24120
|
if (typeof toolCall !== "object" || toolCall === null) {
|
|
24108
24121
|
return false;
|
|
24109
24122
|
}
|
|
24110
24123
|
if (typeof toolCall["toolCallId"] !== "string") {
|
|
24111
24124
|
return false;
|
|
24112
24125
|
}
|
|
24113
|
-
return Array.isArray(
|
|
24126
|
+
return Array.isArray(record3["options"]);
|
|
24114
24127
|
}
|
|
24115
24128
|
|
|
24116
24129
|
// ../../packages/ycodium-acp-executor/src/approvals.ts
|
|
@@ -24635,8 +24648,8 @@ function asTrimmedString(value) {
|
|
|
24635
24648
|
if (typeof value !== "string") {
|
|
24636
24649
|
return void 0;
|
|
24637
24650
|
}
|
|
24638
|
-
const
|
|
24639
|
-
return
|
|
24651
|
+
const trimmed3 = value.trim();
|
|
24652
|
+
return trimmed3.length > 0 ? trimmed3 : void 0;
|
|
24640
24653
|
}
|
|
24641
24654
|
|
|
24642
24655
|
// ../../packages/ycodium-acp-executor/src/tool-presentation.ts
|
|
@@ -24658,12 +24671,12 @@ function normalizeCommandValue(value) {
|
|
|
24658
24671
|
return parts.length > 0 ? parts.join(" ") : void 0;
|
|
24659
24672
|
}
|
|
24660
24673
|
function stripTrailingExitCode(value) {
|
|
24661
|
-
const
|
|
24662
|
-
if (!
|
|
24674
|
+
const trimmed3 = value?.trim();
|
|
24675
|
+
if (!trimmed3) {
|
|
24663
24676
|
return void 0;
|
|
24664
24677
|
}
|
|
24665
|
-
const match = /^(?<output>[\s\S]*?)(?:\s*<exited with exit code \d+>)\s*$/iu.exec(
|
|
24666
|
-
const output2 = match?.groups?.output?.trim() ??
|
|
24678
|
+
const match = /^(?<output>[\s\S]*?)(?:\s*<exited with exit code \d+>)\s*$/iu.exec(trimmed3);
|
|
24679
|
+
const output2 = match?.groups?.output?.trim() ?? trimmed3;
|
|
24667
24680
|
return output2.length > 0 ? output2 : void 0;
|
|
24668
24681
|
}
|
|
24669
24682
|
function extractCommandFromTitle(title) {
|
|
@@ -24753,11 +24766,11 @@ function extractPrimaryPath(data) {
|
|
|
24753
24766
|
return paths[0];
|
|
24754
24767
|
}
|
|
24755
24768
|
function normalizeEquivalentValue(value) {
|
|
24756
|
-
const
|
|
24757
|
-
if (!
|
|
24769
|
+
const trimmed3 = asTrimmedString(value);
|
|
24770
|
+
if (!trimmed3) {
|
|
24758
24771
|
return void 0;
|
|
24759
24772
|
}
|
|
24760
|
-
return
|
|
24773
|
+
return trimmed3.replace(/\s+/gu, " ").replace(/\s+(?:complete|completed|started)\s*$/iu, "").trim();
|
|
24761
24774
|
}
|
|
24762
24775
|
function isEquivalent(left, right) {
|
|
24763
24776
|
const normalizedLeft = normalizeEquivalentValue(left)?.toLowerCase();
|
|
@@ -24845,7 +24858,7 @@ function extractModelConfigId(sessionResponse) {
|
|
|
24845
24858
|
return opt.id.trim();
|
|
24846
24859
|
}
|
|
24847
24860
|
}
|
|
24848
|
-
return void 0;
|
|
24861
|
+
return configOptions.find((opt) => opt.id.trim() === "model" && opt.type === "select") ? "model" : void 0;
|
|
24849
24862
|
}
|
|
24850
24863
|
function findSessionConfigOption(configOptions, configId) {
|
|
24851
24864
|
if (!configOptions) {
|
|
@@ -25023,11 +25036,11 @@ function extractToolCallCommand(rawInput, title) {
|
|
|
25023
25036
|
}
|
|
25024
25037
|
var TOOL_CALL_CONTENT_MAX_CHARS = 8e3;
|
|
25025
25038
|
var TOOL_CALL_CONTENT_TRUNCATION_MARKER = "[Earlier output truncated]\n\n";
|
|
25026
|
-
function boundToolCallOutputText(
|
|
25027
|
-
if (
|
|
25028
|
-
return
|
|
25039
|
+
function boundToolCallOutputText(text2) {
|
|
25040
|
+
if (text2.length <= TOOL_CALL_CONTENT_MAX_CHARS) {
|
|
25041
|
+
return text2;
|
|
25029
25042
|
}
|
|
25030
|
-
const tail =
|
|
25043
|
+
const tail = text2.slice(text2.length - TOOL_CALL_CONTENT_MAX_CHARS);
|
|
25031
25044
|
return `${TOOL_CALL_CONTENT_TRUNCATION_MARKER}${tail}`;
|
|
25032
25045
|
}
|
|
25033
25046
|
var RAW_OUTPUT_TEXT_FIELDS = ["content", "stdout", "stderr", "output"];
|
|
@@ -25059,9 +25072,9 @@ function extractTextContentFromToolCallContent(content) {
|
|
|
25059
25072
|
const typed = content;
|
|
25060
25073
|
const chunks = [];
|
|
25061
25074
|
for (const entry of typed) {
|
|
25062
|
-
const
|
|
25063
|
-
if (
|
|
25064
|
-
chunks.push(
|
|
25075
|
+
const text2 = toolCallContentText(entry)?.trim();
|
|
25076
|
+
if (text2) {
|
|
25077
|
+
chunks.push(text2);
|
|
25065
25078
|
}
|
|
25066
25079
|
}
|
|
25067
25080
|
if (chunks.length === 0) {
|
|
@@ -25239,8 +25252,15 @@ function boundToolCallRawPayload(params, update, toolCall) {
|
|
|
25239
25252
|
function readAcpText(source, key) {
|
|
25240
25253
|
const value = source?.[key];
|
|
25241
25254
|
if (typeof value !== "string") return void 0;
|
|
25242
|
-
const
|
|
25243
|
-
return
|
|
25255
|
+
const trimmed3 = value.trim();
|
|
25256
|
+
return trimmed3.length > 0 ? trimmed3 : void 0;
|
|
25257
|
+
}
|
|
25258
|
+
function textFromContentBlocks(blocks) {
|
|
25259
|
+
const parts = blocks.flatMap(
|
|
25260
|
+
(block) => isRecord5(block) && block["type"] === "text" && typeof block["text"] === "string" ? [block["text"]] : []
|
|
25261
|
+
);
|
|
25262
|
+
const joined = parts.join("");
|
|
25263
|
+
return joined.trim().length > 0 ? joined : void 0;
|
|
25244
25264
|
}
|
|
25245
25265
|
function parseSessionUpdateEvent(params) {
|
|
25246
25266
|
const upd = params.update;
|
|
@@ -25305,11 +25325,11 @@ function parseSessionUpdateEvent(params) {
|
|
|
25305
25325
|
const contentType = content?.["type"];
|
|
25306
25326
|
const streamKind = kind === "agent_thought_chunk" ? "reasoning_text" : "assistant_text";
|
|
25307
25327
|
if (contentType === "text") {
|
|
25308
|
-
const
|
|
25309
|
-
if (
|
|
25328
|
+
const text2 = typeof content?.["text"] === "string" ? content["text"] : "";
|
|
25329
|
+
if (text2.length > 0) {
|
|
25310
25330
|
events.push({
|
|
25311
25331
|
_tag: "ContentDelta",
|
|
25312
|
-
text,
|
|
25332
|
+
text: text2,
|
|
25313
25333
|
streamKind,
|
|
25314
25334
|
rawPayload: params
|
|
25315
25335
|
});
|
|
@@ -25325,6 +25345,28 @@ function parseSessionUpdateEvent(params) {
|
|
|
25325
25345
|
}
|
|
25326
25346
|
break;
|
|
25327
25347
|
}
|
|
25348
|
+
case "compaction_update": {
|
|
25349
|
+
const compactionId = readAcpText(upd, "compactionId");
|
|
25350
|
+
const status = readAcpText(upd, "status");
|
|
25351
|
+
if (compactionId === void 0 || status === void 0) break;
|
|
25352
|
+
const rawSummary = upd["summary"];
|
|
25353
|
+
events.push({
|
|
25354
|
+
_tag: "CompactionUpdated",
|
|
25355
|
+
compactionId,
|
|
25356
|
+
status,
|
|
25357
|
+
summary: rawSummary === void 0 ? void 0 : Array.isArray(rawSummary) ? textFromContentBlocks(rawSummary) ?? null : null,
|
|
25358
|
+
error: readAcpText(upd, "error")
|
|
25359
|
+
});
|
|
25360
|
+
break;
|
|
25361
|
+
}
|
|
25362
|
+
case "compaction_summary_chunk": {
|
|
25363
|
+
const compactionId = readAcpText(upd, "compactionId");
|
|
25364
|
+
const content = isRecord5(upd["content"]) ? upd["content"] : void 0;
|
|
25365
|
+
const text2 = content?.["type"] === "text" ? content["text"] : void 0;
|
|
25366
|
+
if (compactionId === void 0 || typeof text2 !== "string" || text2.length === 0) break;
|
|
25367
|
+
events.push({ _tag: "CompactionSummaryChunk", compactionId, text: text2 });
|
|
25368
|
+
break;
|
|
25369
|
+
}
|
|
25328
25370
|
default:
|
|
25329
25371
|
break;
|
|
25330
25372
|
}
|
|
@@ -25421,6 +25463,97 @@ function createAcpExecutor(options) {
|
|
|
25421
25463
|
if (settledPromptKeys.length > SETTLED_PROMPT_KEY_LIMIT) settledPromptKeys.shift();
|
|
25422
25464
|
};
|
|
25423
25465
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
25466
|
+
const compactions = /* @__PURE__ */ new Map();
|
|
25467
|
+
let manualCompaction;
|
|
25468
|
+
const COMPACTION_SUMMARY_MAX_CHARS = 8e3;
|
|
25469
|
+
const nowMs = () => options.nowMs?.() ?? Date.now();
|
|
25470
|
+
const emitCompactionState = (record3, state) => {
|
|
25471
|
+
const summary = record3.summary?.trim() ?? "";
|
|
25472
|
+
const truncated = summary.length > COMPACTION_SUMMARY_MAX_CHARS;
|
|
25473
|
+
emit({
|
|
25474
|
+
type: "thread.state.changed",
|
|
25475
|
+
...stamp(),
|
|
25476
|
+
provider: options.provider,
|
|
25477
|
+
threadId: options.threadId,
|
|
25478
|
+
...activeTurnId !== void 0 ? { turnId: activeTurnId } : {},
|
|
25479
|
+
payload: {
|
|
25480
|
+
state,
|
|
25481
|
+
compaction: {
|
|
25482
|
+
compactionId: record3.snapshotId,
|
|
25483
|
+
trigger: record3.trigger,
|
|
25484
|
+
...state === "compacted" ? { durationMs: Math.max(0, nowMs() - record3.startedAtMs) } : {},
|
|
25485
|
+
...summary.length > 0 ? {
|
|
25486
|
+
summary: truncated ? summary.slice(0, COMPACTION_SUMMARY_MAX_CHARS) : summary,
|
|
25487
|
+
...truncated ? { summaryTruncated: true } : {}
|
|
25488
|
+
} : {}
|
|
25489
|
+
}
|
|
25490
|
+
}
|
|
25491
|
+
});
|
|
25492
|
+
};
|
|
25493
|
+
const applyCompactionUpdate = (event) => {
|
|
25494
|
+
let record3 = compactions.get(event.compactionId);
|
|
25495
|
+
if (record3 === void 0) {
|
|
25496
|
+
if (manualCompaction !== void 0 && !manualCompaction.adopted) {
|
|
25497
|
+
manualCompaction.adopted = true;
|
|
25498
|
+
record3 = manualCompaction;
|
|
25499
|
+
} else {
|
|
25500
|
+
record3 = {
|
|
25501
|
+
snapshotId: randomId(),
|
|
25502
|
+
trigger: "automatic",
|
|
25503
|
+
startedAtMs: nowMs(),
|
|
25504
|
+
summary: void 0,
|
|
25505
|
+
announced: false,
|
|
25506
|
+
finished: false,
|
|
25507
|
+
adopted: false
|
|
25508
|
+
};
|
|
25509
|
+
}
|
|
25510
|
+
compactions.set(event.compactionId, record3);
|
|
25511
|
+
}
|
|
25512
|
+
if (event.summary !== void 0) record3.summary = event.summary ?? void 0;
|
|
25513
|
+
switch (event.status) {
|
|
25514
|
+
case "in_progress":
|
|
25515
|
+
if (!record3.announced) {
|
|
25516
|
+
record3.announced = true;
|
|
25517
|
+
emitCompactionState(record3, "compacting");
|
|
25518
|
+
}
|
|
25519
|
+
return;
|
|
25520
|
+
case "completed":
|
|
25521
|
+
record3.announced = true;
|
|
25522
|
+
record3.finished = true;
|
|
25523
|
+
compactions.delete(event.compactionId);
|
|
25524
|
+
emitCompactionState(record3, "compacted");
|
|
25525
|
+
return;
|
|
25526
|
+
case "failed":
|
|
25527
|
+
case "cancelled":
|
|
25528
|
+
record3.finished = true;
|
|
25529
|
+
compactions.delete(event.compactionId);
|
|
25530
|
+
emit({
|
|
25531
|
+
type: "runtime.warning",
|
|
25532
|
+
...stamp(),
|
|
25533
|
+
provider: options.provider,
|
|
25534
|
+
threadId: options.threadId,
|
|
25535
|
+
...activeTurnId !== void 0 ? { turnId: activeTurnId } : {},
|
|
25536
|
+
payload: {
|
|
25537
|
+
message: event.error ?? `Context compaction ${event.status}`,
|
|
25538
|
+
detail: { code: `context-compaction-${event.status}` }
|
|
25539
|
+
}
|
|
25540
|
+
});
|
|
25541
|
+
return;
|
|
25542
|
+
default:
|
|
25543
|
+
return;
|
|
25544
|
+
}
|
|
25545
|
+
};
|
|
25546
|
+
const shownToolCallIds = /* @__PURE__ */ new Set();
|
|
25547
|
+
const SHOWN_TOOL_CALL_LIMIT = 256;
|
|
25548
|
+
const rememberShownToolCall = (toolCallId) => {
|
|
25549
|
+
shownToolCallIds.add(toolCallId);
|
|
25550
|
+
if (shownToolCallIds.size <= SHOWN_TOOL_CALL_LIMIT) return;
|
|
25551
|
+
for (const id of shownToolCallIds) {
|
|
25552
|
+
if (toolCalls.has(id)) continue;
|
|
25553
|
+
shownToolCallIds.delete(id);
|
|
25554
|
+
return;
|
|
25555
|
+
}
|
|
25556
|
+
};
|
|
25424
25557
|
let assistantSegment = { nextSegmentIndex: 0 };
|
|
25425
25558
|
let modeState;
|
|
25426
25559
|
let availableCommands = [];
|
|
@@ -25507,7 +25640,6 @@ function createAcpExecutor(options) {
|
|
|
25507
25640
|
}
|
|
25508
25641
|
for (const event of parsed.events) {
|
|
25509
25642
|
if (event._tag === "ToolCallUpdated") {
|
|
25510
|
-
closeActiveAssistantSegment(activeTurnId);
|
|
25511
25643
|
const tracked = toolCalls.get(event.toolCall.toolCallId);
|
|
25512
25644
|
const previous = tracked?.state;
|
|
25513
25645
|
const nextToolCall = mergeToolCallState(previous, event.toolCall);
|
|
@@ -25526,9 +25658,35 @@ function createAcpExecutor(options) {
|
|
|
25526
25658
|
skippedSinceEmit: decision.skippedSinceEmit
|
|
25527
25659
|
});
|
|
25528
25660
|
}
|
|
25529
|
-
|
|
25661
|
+
const hookResult = hooks.onToolCallUpdated?.({
|
|
25662
|
+
toolCallId: nextToolCall.toolCallId,
|
|
25663
|
+
status: nextToolCall.status,
|
|
25664
|
+
title: nextToolCall.title,
|
|
25665
|
+
kind: nextToolCall.kind,
|
|
25666
|
+
rawInput: nextToolCall.data["rawInput"],
|
|
25667
|
+
rawOutput: nextToolCall.data["rawOutput"],
|
|
25668
|
+
meta: params.update._meta,
|
|
25669
|
+
turnId: activeTurnId
|
|
25670
|
+
});
|
|
25671
|
+
const taskEvents = hookResult === void 0 ? [] : "events" in hookResult ? hookResult.events : hookResult;
|
|
25672
|
+
const handledByHook = hookResult !== void 0 && "events" in hookResult && hookResult.handled === true;
|
|
25673
|
+
for (const taskEvent of taskEvents) {
|
|
25674
|
+
emit({
|
|
25675
|
+
type: taskEvent.type,
|
|
25676
|
+
...stamp(),
|
|
25677
|
+
provider: options.provider,
|
|
25678
|
+
threadId: options.threadId,
|
|
25679
|
+
...taskEvent.turnId !== void 0 ? { turnId: taskEvent.turnId } : {},
|
|
25680
|
+
payload: taskEvent.payload
|
|
25681
|
+
});
|
|
25682
|
+
}
|
|
25683
|
+
if (handledByHook || !decision.emit) {
|
|
25530
25684
|
continue;
|
|
25531
25685
|
}
|
|
25686
|
+
if (!shownToolCallIds.has(nextToolCall.toolCallId)) {
|
|
25687
|
+
rememberShownToolCall(nextToolCall.toolCallId);
|
|
25688
|
+
closeActiveAssistantSegment(activeTurnId);
|
|
25689
|
+
}
|
|
25532
25690
|
emit(
|
|
25533
25691
|
makeAcpToolCallEvent({
|
|
25534
25692
|
stamp: stamp(),
|
|
@@ -25541,7 +25699,21 @@ function createAcpExecutor(options) {
|
|
|
25541
25699
|
);
|
|
25542
25700
|
continue;
|
|
25543
25701
|
}
|
|
25702
|
+
if (event._tag === "CompactionUpdated") {
|
|
25703
|
+
applyCompactionUpdate(event);
|
|
25704
|
+
continue;
|
|
25705
|
+
}
|
|
25706
|
+
if (event._tag === "CompactionSummaryChunk") {
|
|
25707
|
+
const record3 = compactions.get(event.compactionId);
|
|
25708
|
+
if (record3 !== void 0 && !record3.finished) {
|
|
25709
|
+
record3.summary = (record3.summary ?? "") + event.text;
|
|
25710
|
+
}
|
|
25711
|
+
continue;
|
|
25712
|
+
}
|
|
25544
25713
|
if (event._tag === "ContentDelta") {
|
|
25714
|
+
if (manualCompaction !== void 0) {
|
|
25715
|
+
continue;
|
|
25716
|
+
}
|
|
25545
25717
|
if (event.streamKind === "reasoning_text") {
|
|
25546
25718
|
if (event.text.trim().length === 0) {
|
|
25547
25719
|
continue;
|
|
@@ -25784,7 +25956,9 @@ function createAcpExecutor(options) {
|
|
|
25784
25956
|
},
|
|
25785
25957
|
onNotification: (notification) => {
|
|
25786
25958
|
if (notification.method === "session/update") {
|
|
25787
|
-
|
|
25959
|
+
const params = notification.params;
|
|
25960
|
+
const transformed = hooks.transformSessionUpdate ? hooks.transformSessionUpdate(params) : params;
|
|
25961
|
+
if (transformed !== void 0) handleSessionUpdate(transformed);
|
|
25788
25962
|
return;
|
|
25789
25963
|
}
|
|
25790
25964
|
if (settleFromNotification(notification.method, notification.params)) return;
|
|
@@ -25918,13 +26092,15 @@ function createAcpExecutor(options) {
|
|
|
25918
26092
|
options.mcpServers ?? [],
|
|
25919
26093
|
initialized.agentCapabilities
|
|
25920
26094
|
);
|
|
26095
|
+
const additionalDirectories = options.additionalDirectories !== void 0 && options.additionalDirectories.length > 0 ? { additionalDirectories: options.additionalDirectories } : {};
|
|
25921
26096
|
let setup;
|
|
25922
26097
|
let nextSessionId;
|
|
25923
26098
|
if (options.resumeSessionId && options.resumeMethod === "session/resume") {
|
|
25924
26099
|
setup = await connection.request("session/resume", {
|
|
25925
26100
|
sessionId: options.resumeSessionId,
|
|
25926
26101
|
cwd: options.cwd,
|
|
25927
|
-
mcpServers
|
|
26102
|
+
mcpServers,
|
|
26103
|
+
...additionalDirectories
|
|
25928
26104
|
});
|
|
25929
26105
|
nextSessionId = options.resumeSessionId;
|
|
25930
26106
|
} else if (options.resumeSessionId) {
|
|
@@ -25933,7 +26109,8 @@ function createAcpExecutor(options) {
|
|
|
25933
26109
|
setup = await connection.request("session/load", {
|
|
25934
26110
|
sessionId: options.resumeSessionId,
|
|
25935
26111
|
cwd: options.cwd,
|
|
25936
|
-
mcpServers
|
|
26112
|
+
mcpServers,
|
|
26113
|
+
...additionalDirectories
|
|
25937
26114
|
});
|
|
25938
26115
|
} finally {
|
|
25939
26116
|
sessionLoadInFlight = false;
|
|
@@ -25946,7 +26123,8 @@ function createAcpExecutor(options) {
|
|
|
25946
26123
|
} else {
|
|
25947
26124
|
const created = await connection.request("session/new", {
|
|
25948
26125
|
cwd: options.cwd,
|
|
25949
|
-
mcpServers
|
|
26126
|
+
mcpServers,
|
|
26127
|
+
...additionalDirectories
|
|
25950
26128
|
});
|
|
25951
26129
|
nextSessionId = created.sessionId;
|
|
25952
26130
|
setup = created;
|
|
@@ -26020,13 +26198,13 @@ function createAcpExecutor(options) {
|
|
|
26020
26198
|
startInFlight = void 0;
|
|
26021
26199
|
return result;
|
|
26022
26200
|
},
|
|
26023
|
-
(error62) => {
|
|
26201
|
+
async (error62) => {
|
|
26024
26202
|
startInFlight = void 0;
|
|
26025
26203
|
if (isLive(expectedGeneration) && !startResult) {
|
|
26026
26204
|
status = "idle";
|
|
26027
26205
|
generation = expectedGeneration;
|
|
26028
26206
|
}
|
|
26029
|
-
throw error62;
|
|
26207
|
+
throw await withStartupStderr(error62, options.stderrTail);
|
|
26030
26208
|
}
|
|
26031
26209
|
);
|
|
26032
26210
|
return startInFlight;
|
|
@@ -26094,6 +26272,36 @@ function createAcpExecutor(options) {
|
|
|
26094
26272
|
interruptedTurnIds.delete(input2.turnId);
|
|
26095
26273
|
}
|
|
26096
26274
|
};
|
|
26275
|
+
const sendPromptRpc = async (sessionId2, promptParts) => {
|
|
26276
|
+
const settlementHooks = hooks.promptSettlement;
|
|
26277
|
+
const promptKey = settlementHooks === void 0 ? void 0 : randomId();
|
|
26278
|
+
const promptRpc = connection.request("session/prompt", {
|
|
26279
|
+
sessionId: sessionId2,
|
|
26280
|
+
prompt: promptParts,
|
|
26281
|
+
...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
|
|
26282
|
+
});
|
|
26283
|
+
if (settlementHooks === void 0 || promptKey === void 0) {
|
|
26284
|
+
return await promptRpc;
|
|
26285
|
+
} else {
|
|
26286
|
+
const { promise: early, resolve: settleEarly } = Promise.withResolvers();
|
|
26287
|
+
pendingSettlement = { promptKey, sessionId: sessionId2, settle: settleEarly };
|
|
26288
|
+
try {
|
|
26289
|
+
const outcome = await Promise.race([
|
|
26290
|
+
promptRpc.then((value) => {
|
|
26291
|
+
const key = settlementHooks.responseKey?.(value);
|
|
26292
|
+
if (key !== void 0) rememberSettledPromptKey(key);
|
|
26293
|
+
return { response: value };
|
|
26294
|
+
}),
|
|
26295
|
+
early
|
|
26296
|
+
]);
|
|
26297
|
+
if (outcome.error !== void 0) throw outcome.error;
|
|
26298
|
+
return outcome.response;
|
|
26299
|
+
} finally {
|
|
26300
|
+
pendingSettlement = void 0;
|
|
26301
|
+
void promptRpc.catch(() => void 0);
|
|
26302
|
+
}
|
|
26303
|
+
}
|
|
26304
|
+
};
|
|
26097
26305
|
const prompt = async (input2) => {
|
|
26098
26306
|
failIfDisposed();
|
|
26099
26307
|
const started = requireStarted();
|
|
@@ -26144,35 +26352,8 @@ function createAcpExecutor(options) {
|
|
|
26144
26352
|
expectedGeneration: started.generation
|
|
26145
26353
|
});
|
|
26146
26354
|
closeActiveAssistantSegment(turnId);
|
|
26147
|
-
const settlementHooks = hooks.promptSettlement;
|
|
26148
|
-
const promptKey = settlementHooks === void 0 ? void 0 : randomId();
|
|
26149
|
-
const promptRpc = connection.request("session/prompt", {
|
|
26150
|
-
sessionId: started.sessionId,
|
|
26151
|
-
prompt: promptParts,
|
|
26152
|
-
...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
|
|
26153
|
-
});
|
|
26154
26355
|
try {
|
|
26155
|
-
|
|
26156
|
-
response = await promptRpc;
|
|
26157
|
-
} else {
|
|
26158
|
-
const { promise: early, resolve: settleEarly } = Promise.withResolvers();
|
|
26159
|
-
pendingSettlement = { promptKey, sessionId: started.sessionId, settle: settleEarly };
|
|
26160
|
-
try {
|
|
26161
|
-
const outcome = await Promise.race([
|
|
26162
|
-
promptRpc.then((value) => {
|
|
26163
|
-
const key = settlementHooks.responseKey?.(value);
|
|
26164
|
-
if (key !== void 0) rememberSettledPromptKey(key);
|
|
26165
|
-
return { response: value };
|
|
26166
|
-
}),
|
|
26167
|
-
early
|
|
26168
|
-
]);
|
|
26169
|
-
if (outcome.error !== void 0) throw outcome.error;
|
|
26170
|
-
response = outcome.response;
|
|
26171
|
-
} finally {
|
|
26172
|
-
pendingSettlement = void 0;
|
|
26173
|
-
void promptRpc.catch(() => void 0);
|
|
26174
|
-
}
|
|
26175
|
-
}
|
|
26356
|
+
response = await sendPromptRpc(started.sessionId, promptParts);
|
|
26176
26357
|
} catch (error62) {
|
|
26177
26358
|
if (disposed) {
|
|
26178
26359
|
throw new AcpExecutorDisposedError();
|
|
@@ -26336,6 +26517,74 @@ function createAcpExecutor(options) {
|
|
|
26336
26517
|
};
|
|
26337
26518
|
apply();
|
|
26338
26519
|
};
|
|
26520
|
+
const compact = async (input2) => {
|
|
26521
|
+
failIfDisposed();
|
|
26522
|
+
const started = requireStarted();
|
|
26523
|
+
const trimmedName = input2.commandName.trim();
|
|
26524
|
+
const commandName = trimmedName.startsWith("/") ? trimmedName.slice(1) : trimmedName;
|
|
26525
|
+
if (!availableCommands.some((command) => command.name === commandName)) {
|
|
26526
|
+
throw new AcpExecutorError(
|
|
26527
|
+
"command-unavailable",
|
|
26528
|
+
`The agent has not advertised the /${commandName} command`
|
|
26529
|
+
);
|
|
26530
|
+
}
|
|
26531
|
+
if (promptsInFlight > 0 || promptMutex.isLocked || manualCompaction !== void 0) {
|
|
26532
|
+
throw new AcpExecutorError(
|
|
26533
|
+
"busy",
|
|
26534
|
+
"Cannot compact while a turn or another compaction is running"
|
|
26535
|
+
);
|
|
26536
|
+
}
|
|
26537
|
+
const record3 = {
|
|
26538
|
+
snapshotId: randomId(),
|
|
26539
|
+
trigger: "manual",
|
|
26540
|
+
startedAtMs: nowMs(),
|
|
26541
|
+
summary: void 0,
|
|
26542
|
+
announced: true,
|
|
26543
|
+
finished: false,
|
|
26544
|
+
adopted: false
|
|
26545
|
+
};
|
|
26546
|
+
await promptMutex.acquire();
|
|
26547
|
+
manualCompaction = record3;
|
|
26548
|
+
const emitSessionState = (state) => {
|
|
26549
|
+
emit({
|
|
26550
|
+
type: "session.state.changed",
|
|
26551
|
+
...stamp(),
|
|
26552
|
+
provider: options.provider,
|
|
26553
|
+
threadId: options.threadId,
|
|
26554
|
+
payload: { state, reason: "compaction" }
|
|
26555
|
+
});
|
|
26556
|
+
};
|
|
26557
|
+
try {
|
|
26558
|
+
failIfDisposed();
|
|
26559
|
+
emitSessionState("compacting");
|
|
26560
|
+
emitCompactionState(record3, "compacting");
|
|
26561
|
+
let response;
|
|
26562
|
+
try {
|
|
26563
|
+
response = await sendPromptRpc(started.sessionId, [
|
|
26564
|
+
{ type: "text", text: `/${commandName}` }
|
|
26565
|
+
]);
|
|
26566
|
+
} catch (error62) {
|
|
26567
|
+
if (disposed) throw new AcpExecutorDisposedError();
|
|
26568
|
+
throw error62;
|
|
26569
|
+
}
|
|
26570
|
+
await connection.awaitInboundIdle();
|
|
26571
|
+
if (response.stopReason === "cancelled") {
|
|
26572
|
+
return;
|
|
26573
|
+
}
|
|
26574
|
+
if (!record3.finished) {
|
|
26575
|
+
record3.finished = true;
|
|
26576
|
+
emitCompactionState(record3, "compacted");
|
|
26577
|
+
}
|
|
26578
|
+
} finally {
|
|
26579
|
+
for (const [agentId, tracked] of compactions) {
|
|
26580
|
+
if (tracked === record3) compactions.delete(agentId);
|
|
26581
|
+
}
|
|
26582
|
+
manualCompaction = void 0;
|
|
26583
|
+
promptMutex.release();
|
|
26584
|
+
notifyPromptSettled();
|
|
26585
|
+
if (!disposed) emitSessionState("ready");
|
|
26586
|
+
}
|
|
26587
|
+
};
|
|
26339
26588
|
const setNativeMode = async (modeId) => {
|
|
26340
26589
|
failIfDisposed();
|
|
26341
26590
|
const started = startResult;
|
|
@@ -26423,6 +26672,7 @@ function createAcpExecutor(options) {
|
|
|
26423
26672
|
respondToRequest,
|
|
26424
26673
|
respondToUserInput,
|
|
26425
26674
|
setNativeMode,
|
|
26675
|
+
compact,
|
|
26426
26676
|
dispose
|
|
26427
26677
|
};
|
|
26428
26678
|
}
|
|
@@ -26498,13 +26748,13 @@ function parseCliVersion(output2) {
|
|
|
26498
26748
|
}
|
|
26499
26749
|
async function collectCappedText(stream, maxBytes) {
|
|
26500
26750
|
const decoder = new TextDecoder();
|
|
26501
|
-
let
|
|
26751
|
+
let text2 = "";
|
|
26502
26752
|
let total = 0;
|
|
26503
26753
|
for await (const chunk of stream) {
|
|
26504
26754
|
total += chunk.byteLength;
|
|
26505
|
-
if (total <= maxBytes)
|
|
26755
|
+
if (total <= maxBytes) text2 += decoder.decode(chunk, { stream: true });
|
|
26506
26756
|
}
|
|
26507
|
-
return { text:
|
|
26757
|
+
return { text: text2 + decoder.decode(), overflowed: total > maxBytes };
|
|
26508
26758
|
}
|
|
26509
26759
|
async function collectProbeProcess(child, input2) {
|
|
26510
26760
|
try {
|
|
@@ -26645,11 +26895,11 @@ import * as NodeFS from "node:fs";
|
|
|
26645
26895
|
import * as NodePath from "node:path";
|
|
26646
26896
|
var AUTH_FILE_NAME = "auth.json";
|
|
26647
26897
|
var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26648
|
-
var readString2 = (
|
|
26649
|
-
const value =
|
|
26898
|
+
var readString2 = (record3, key) => {
|
|
26899
|
+
const value = record3[key];
|
|
26650
26900
|
if (typeof value !== "string") return void 0;
|
|
26651
|
-
const
|
|
26652
|
-
return
|
|
26901
|
+
const trimmed3 = value.trim();
|
|
26902
|
+
return trimmed3.length > 0 ? trimmed3 : void 0;
|
|
26653
26903
|
};
|
|
26654
26904
|
var parseJsonRecord = (raw) => {
|
|
26655
26905
|
let parsed;
|
|
@@ -26688,9 +26938,9 @@ var unreadableProbe = (exists) => ({
|
|
|
26688
26938
|
name: void 0,
|
|
26689
26939
|
expiresAt: void 0
|
|
26690
26940
|
});
|
|
26691
|
-
var joinName = (
|
|
26692
|
-
const first = readString2(
|
|
26693
|
-
const last = readString2(
|
|
26941
|
+
var joinName = (record3) => {
|
|
26942
|
+
const first = readString2(record3, "first_name");
|
|
26943
|
+
const last = readString2(record3, "last_name");
|
|
26694
26944
|
const joined = [first, last].filter((part) => part !== void 0).join(" ");
|
|
26695
26945
|
return joined.length > 0 ? joined : void 0;
|
|
26696
26946
|
};
|
|
@@ -26725,13 +26975,176 @@ var readGrokAccount = (homePath) => {
|
|
|
26725
26975
|
};
|
|
26726
26976
|
};
|
|
26727
26977
|
|
|
26728
|
-
// src/
|
|
26729
|
-
|
|
26978
|
+
// src/grokPlanGate.ts
|
|
26979
|
+
var XAI_EXIT_PLAN_MODE_METHODS = [
|
|
26980
|
+
"_x.ai/exit_plan_mode",
|
|
26981
|
+
"x.ai/exit_plan_mode"
|
|
26982
|
+
];
|
|
26983
|
+
var GROK_PLAN_APPROVE_OPTION_ID = "approved";
|
|
26984
|
+
var GROK_PLAN_ABANDON_OPTION_ID = "abandoned";
|
|
26985
|
+
var GROK_EMPTY_PLAN_TEXT = "The agent exited plan mode without writing a plan.";
|
|
26730
26986
|
var isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26731
26987
|
var trimmed = (value) => {
|
|
26732
26988
|
if (typeof value !== "string") return void 0;
|
|
26733
|
-
const
|
|
26734
|
-
return
|
|
26989
|
+
const text2 = value.trim();
|
|
26990
|
+
return text2.length > 0 ? text2 : void 0;
|
|
26991
|
+
};
|
|
26992
|
+
function parseXAiExitPlanModeParams(params) {
|
|
26993
|
+
const candidates = [params, ...isRecord8(params) ? [params["params"]] : []];
|
|
26994
|
+
for (const candidate of candidates) {
|
|
26995
|
+
if (!isRecord8(candidate)) continue;
|
|
26996
|
+
const toolCallId = trimmed(candidate["toolCallId"]);
|
|
26997
|
+
if (toolCallId === void 0) continue;
|
|
26998
|
+
return { toolCallId, planContent: trimmed(candidate["planContent"]) };
|
|
26999
|
+
}
|
|
27000
|
+
return void 0;
|
|
27001
|
+
}
|
|
27002
|
+
function grokPlanQuestion(params) {
|
|
27003
|
+
return {
|
|
27004
|
+
id: params.toolCallId,
|
|
27005
|
+
header: "Plan",
|
|
27006
|
+
question: params.planContent ?? GROK_EMPTY_PLAN_TEXT,
|
|
27007
|
+
kind: "plan",
|
|
27008
|
+
allowFreeform: true,
|
|
27009
|
+
multiSelect: false,
|
|
27010
|
+
// 选项只给语义:用户读到的文案由宿主按界面语言渲染,label 仅是协议要求非空的稳定值。
|
|
27011
|
+
options: [
|
|
27012
|
+
{
|
|
27013
|
+
id: GROK_PLAN_APPROVE_OPTION_ID,
|
|
27014
|
+
label: GROK_PLAN_APPROVE_OPTION_ID,
|
|
27015
|
+
description: "",
|
|
27016
|
+
planAction: "approve"
|
|
27017
|
+
},
|
|
27018
|
+
{
|
|
27019
|
+
id: GROK_PLAN_ABANDON_OPTION_ID,
|
|
27020
|
+
label: GROK_PLAN_ABANDON_OPTION_ID,
|
|
27021
|
+
description: "",
|
|
27022
|
+
planAction: "stop"
|
|
27023
|
+
}
|
|
27024
|
+
]
|
|
27025
|
+
};
|
|
27026
|
+
}
|
|
27027
|
+
var ABANDONED_FEEDBACK = "The user chose not to continue with this plan. Stop here and wait for their next message.";
|
|
27028
|
+
var abandoned = () => ({
|
|
27029
|
+
outcome: "abandoned",
|
|
27030
|
+
feedback: ABANDONED_FEEDBACK
|
|
27031
|
+
});
|
|
27032
|
+
function makeXAiExitPlanModeResponse(params, resolution) {
|
|
27033
|
+
if (resolution.kind === "cancelled") return abandoned();
|
|
27034
|
+
const answer = resolution.answers[params.toolCallId];
|
|
27035
|
+
const selected = typeof answer === "string" ? answer : Array.isArray(answer) && answer.length === 1 && typeof answer[0] === "string" ? answer[0] : void 0;
|
|
27036
|
+
const text2 = trimmed(selected);
|
|
27037
|
+
if (text2 === void 0) return abandoned();
|
|
27038
|
+
if (text2 === GROK_PLAN_APPROVE_OPTION_ID) return { outcome: "approved" };
|
|
27039
|
+
if (text2 === GROK_PLAN_ABANDON_OPTION_ID) return abandoned();
|
|
27040
|
+
return { outcome: "request_changes", feedback: text2 };
|
|
27041
|
+
}
|
|
27042
|
+
|
|
27043
|
+
// src/grokBackgroundTasks.ts
|
|
27044
|
+
var record2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
27045
|
+
var text = (value) => typeof value === "string" ? value.trim() || void 0 : void 0;
|
|
27046
|
+
var lifecycle = (status, exitCode) => {
|
|
27047
|
+
switch (text(status)?.toLowerCase()) {
|
|
27048
|
+
case "pending":
|
|
27049
|
+
case "running":
|
|
27050
|
+
return "running";
|
|
27051
|
+
case "completed":
|
|
27052
|
+
case "success":
|
|
27053
|
+
case "succeeded":
|
|
27054
|
+
return "completed";
|
|
27055
|
+
case "failed":
|
|
27056
|
+
case "error":
|
|
27057
|
+
return "failed";
|
|
27058
|
+
case "stopped":
|
|
27059
|
+
case "killed":
|
|
27060
|
+
case "cancelled":
|
|
27061
|
+
return "stopped";
|
|
27062
|
+
default:
|
|
27063
|
+
return typeof exitCode === "number" && Number.isFinite(exitCode) ? exitCode === 0 ? "completed" : "failed" : void 0;
|
|
27064
|
+
}
|
|
27065
|
+
};
|
|
27066
|
+
function buildGrokBackgroundTaskEvents(input2) {
|
|
27067
|
+
const { tasks, toolCallId, toolCallStatus, turnId } = input2;
|
|
27068
|
+
const output2 = record2(input2.rawOutput);
|
|
27069
|
+
const events = [];
|
|
27070
|
+
if (toolCallStatus !== "completed" && toolCallStatus !== "failed" && output2["type"] !== "BackgroundTaskStarted") {
|
|
27071
|
+
return events;
|
|
27072
|
+
}
|
|
27073
|
+
const attribution = (task) => task.turnId !== void 0 && task.turnId === turnId ? { turnId } : {};
|
|
27074
|
+
const start = (id, taskType, description, toolUseId) => {
|
|
27075
|
+
const known = tasks.get(id);
|
|
27076
|
+
if (known) return known;
|
|
27077
|
+
const task = {
|
|
27078
|
+
payload: {
|
|
27079
|
+
taskId: id,
|
|
27080
|
+
taskType,
|
|
27081
|
+
description,
|
|
27082
|
+
title: description,
|
|
27083
|
+
...toolUseId ? { toolUseId } : {}
|
|
27084
|
+
},
|
|
27085
|
+
// 轮询可能重新发现老任务,那时并不知道它是哪一轮起的。
|
|
27086
|
+
turnId: toolUseId ? turnId : void 0
|
|
27087
|
+
};
|
|
27088
|
+
tasks.set(id, task);
|
|
27089
|
+
events.push({ type: "task.started", payload: task.payload, ...attribution(task) });
|
|
27090
|
+
return task;
|
|
27091
|
+
};
|
|
27092
|
+
const complete = (task, status, summary) => {
|
|
27093
|
+
tasks.delete(task.payload.taskId);
|
|
27094
|
+
events.push({
|
|
27095
|
+
type: "task.completed",
|
|
27096
|
+
payload: { ...task.payload, status, ...summary ? { summary } : {} },
|
|
27097
|
+
...attribution(task)
|
|
27098
|
+
});
|
|
27099
|
+
};
|
|
27100
|
+
if (output2["type"] === "Monitor" && toolCallStatus === "completed") {
|
|
27101
|
+
const id = text(output2["taskId"]);
|
|
27102
|
+
if (id) {
|
|
27103
|
+
start(id, "monitor", text(record2(input2.rawInput)["description"]) ?? "Monitor", toolCallId);
|
|
27104
|
+
}
|
|
27105
|
+
} else if (output2["type"] === "BackgroundTaskStarted") {
|
|
27106
|
+
const id = text(output2["task_id"]) ?? text(output2["taskId"]);
|
|
27107
|
+
const command = text(output2["command"]);
|
|
27108
|
+
if (id && command) start(id, "shell", command.split("\n")[0].slice(0, 200), toolCallId);
|
|
27109
|
+
} else if (output2["type"] === "TaskOutput" || output2["type"] === "KillTask") {
|
|
27110
|
+
const results = record2(output2["MultiResult"])["results"];
|
|
27111
|
+
for (const value of Array.isArray(results) ? results : [output2["Result"]]) {
|
|
27112
|
+
const result = record2(value);
|
|
27113
|
+
const id = text(result["task_id"]);
|
|
27114
|
+
if (!id) continue;
|
|
27115
|
+
if (output2["type"] === "KillTask") {
|
|
27116
|
+
const task2 = tasks.get(id);
|
|
27117
|
+
if (task2 && toolCallStatus === "completed" && result["outcome"] === "killed") {
|
|
27118
|
+
complete(task2, "stopped");
|
|
27119
|
+
}
|
|
27120
|
+
continue;
|
|
27121
|
+
}
|
|
27122
|
+
const command = text(result["command"]);
|
|
27123
|
+
const status = lifecycle(result["status"], result["exit_code"]);
|
|
27124
|
+
if (!command || !status || command.startsWith("[subagent:")) continue;
|
|
27125
|
+
const task = start(id, /^\[monitor[:\]]/.test(command) ? "monitor" : "shell", command);
|
|
27126
|
+
const summary = text(result["output"])?.split("\n").find((line) => line.trim())?.trim();
|
|
27127
|
+
if (status === "running") {
|
|
27128
|
+
events.push({
|
|
27129
|
+
type: "task.progress",
|
|
27130
|
+
payload: { ...task.payload, ...summary ? { summary } : {} },
|
|
27131
|
+
...attribution(task)
|
|
27132
|
+
});
|
|
27133
|
+
} else {
|
|
27134
|
+
complete(task, status, summary);
|
|
27135
|
+
}
|
|
27136
|
+
}
|
|
27137
|
+
}
|
|
27138
|
+
return events;
|
|
27139
|
+
}
|
|
27140
|
+
|
|
27141
|
+
// src/grokSupport.ts
|
|
27142
|
+
import { modelSelectionStringOption } from "@ycodium-ai/plugin-api/executor";
|
|
27143
|
+
var isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27144
|
+
var trimmed2 = (value) => {
|
|
27145
|
+
if (typeof value !== "string") return void 0;
|
|
27146
|
+
const text2 = value.trim();
|
|
27147
|
+
return text2.length > 0 ? text2 : void 0;
|
|
26735
27148
|
};
|
|
26736
27149
|
function grokReasoningEffortArgs(effort) {
|
|
26737
27150
|
const value = effort?.trim();
|
|
@@ -26842,45 +27255,45 @@ function grokRuntimeModeCaveat(nativeModeId) {
|
|
|
26842
27255
|
}
|
|
26843
27256
|
var GROK_REASONING_OPTION_ID = "reasoningEffort";
|
|
26844
27257
|
function resolveGrokAuthMethodId(initializeResult) {
|
|
26845
|
-
const authMethods =
|
|
27258
|
+
const authMethods = isRecord9(initializeResult) ? initializeResult["authMethods"] : void 0;
|
|
26846
27259
|
if (!Array.isArray(authMethods)) return void 0;
|
|
26847
27260
|
for (const method of authMethods) {
|
|
26848
|
-
if (
|
|
27261
|
+
if (isRecord9(method) && method["id"] === "cached_token") return "cached_token";
|
|
26849
27262
|
}
|
|
26850
27263
|
return void 0;
|
|
26851
27264
|
}
|
|
26852
27265
|
var positive = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.trunc(value) : void 0;
|
|
26853
27266
|
function grokPromptUsage(promptResponse) {
|
|
26854
|
-
if (!
|
|
27267
|
+
if (!isRecord9(promptResponse)) return void 0;
|
|
26855
27268
|
const meta3 = promptResponse["_meta"];
|
|
26856
|
-
if (!
|
|
27269
|
+
if (!isRecord9(meta3)) return void 0;
|
|
26857
27270
|
const usedTokens = positive(meta3["totalTokens"]);
|
|
26858
27271
|
if (usedTokens === void 0) return void 0;
|
|
26859
|
-
return { usedTokens, modelId:
|
|
27272
|
+
return { usedTokens, modelId: trimmed2(meta3["modelId"]) };
|
|
26860
27273
|
}
|
|
26861
27274
|
function grokModelState(initializeResult) {
|
|
26862
|
-
if (!
|
|
27275
|
+
if (!isRecord9(initializeResult)) return void 0;
|
|
26863
27276
|
const meta3 = initializeResult["_meta"];
|
|
26864
|
-
if (!
|
|
27277
|
+
if (!isRecord9(meta3)) return void 0;
|
|
26865
27278
|
const modelState = meta3["modelState"];
|
|
26866
|
-
if (!
|
|
27279
|
+
if (!isRecord9(modelState)) return void 0;
|
|
26867
27280
|
const availableModels = modelState["availableModels"];
|
|
26868
27281
|
if (!Array.isArray(availableModels)) return void 0;
|
|
26869
|
-
return { currentModelId:
|
|
27282
|
+
return { currentModelId: trimmed2(modelState["currentModelId"]), availableModels };
|
|
26870
27283
|
}
|
|
26871
27284
|
function grokAdvertisedModels(initializeResult) {
|
|
26872
27285
|
const state = grokModelState(initializeResult);
|
|
26873
27286
|
if (state === void 0) return [];
|
|
26874
27287
|
const models = [];
|
|
26875
27288
|
for (const entry of state.availableModels) {
|
|
26876
|
-
if (!
|
|
26877
|
-
const modelId =
|
|
27289
|
+
if (!isRecord9(entry)) continue;
|
|
27290
|
+
const modelId = trimmed2(entry["modelId"]);
|
|
26878
27291
|
if (modelId === void 0) continue;
|
|
26879
27292
|
const modelMeta = entry["_meta"];
|
|
26880
|
-
const contextWindow =
|
|
27293
|
+
const contextWindow = isRecord9(modelMeta) ? positive(modelMeta["totalContextTokens"]) : void 0;
|
|
26881
27294
|
models.push({
|
|
26882
27295
|
modelId,
|
|
26883
|
-
name:
|
|
27296
|
+
name: trimmed2(entry["name"]),
|
|
26884
27297
|
isDefault: state.currentModelId !== void 0 && modelId === state.currentModelId,
|
|
26885
27298
|
contextWindow
|
|
26886
27299
|
});
|
|
@@ -26892,7 +27305,7 @@ var XAI_ASK_USER_QUESTION_METHODS = [
|
|
|
26892
27305
|
"x.ai/ask_user_question"
|
|
26893
27306
|
];
|
|
26894
27307
|
var readOption = (value) => {
|
|
26895
|
-
if (!
|
|
27308
|
+
if (!isRecord9(value)) return void 0;
|
|
26896
27309
|
const label = typeof value["label"] === "string" ? value["label"] : void 0;
|
|
26897
27310
|
if (label === void 0) return void 0;
|
|
26898
27311
|
return {
|
|
@@ -26903,7 +27316,7 @@ var readOption = (value) => {
|
|
|
26903
27316
|
};
|
|
26904
27317
|
};
|
|
26905
27318
|
var readQuestion = (value) => {
|
|
26906
|
-
if (!
|
|
27319
|
+
if (!isRecord9(value)) return void 0;
|
|
26907
27320
|
const question = typeof value["question"] === "string" ? value["question"] : void 0;
|
|
26908
27321
|
if (question === void 0) return void 0;
|
|
26909
27322
|
const optionsRaw = value["options"];
|
|
@@ -26919,9 +27332,9 @@ var readQuestion = (value) => {
|
|
|
26919
27332
|
};
|
|
26920
27333
|
};
|
|
26921
27334
|
function parseXAiAskUserQuestionParams(params) {
|
|
26922
|
-
const candidates = [params, ...
|
|
27335
|
+
const candidates = [params, ...isRecord9(params) ? [params["params"]] : []];
|
|
26923
27336
|
for (const candidate of candidates) {
|
|
26924
|
-
if (!
|
|
27337
|
+
if (!isRecord9(candidate)) continue;
|
|
26925
27338
|
const questionsRaw = candidate["questions"];
|
|
26926
27339
|
if (!Array.isArray(questionsRaw)) continue;
|
|
26927
27340
|
const questions = questionsRaw.flatMap((entry) => {
|
|
@@ -26947,12 +27360,12 @@ function extractXAiAskUserQuestions(params) {
|
|
|
26947
27360
|
var answerValues = (answer) => {
|
|
26948
27361
|
if (Array.isArray(answer)) {
|
|
26949
27362
|
return answer.flatMap((entry) => {
|
|
26950
|
-
const
|
|
26951
|
-
return
|
|
27363
|
+
const text3 = trimmed2(entry);
|
|
27364
|
+
return text3 === void 0 ? [] : [text3];
|
|
26952
27365
|
});
|
|
26953
27366
|
}
|
|
26954
|
-
const
|
|
26955
|
-
return
|
|
27367
|
+
const text2 = trimmed2(answer);
|
|
27368
|
+
return text2 === void 0 ? [] : [text2];
|
|
26956
27369
|
};
|
|
26957
27370
|
function makeXAiAskUserQuestionResponse(params, answers) {
|
|
26958
27371
|
const normalized = params.questions.flatMap((question) => {
|
|
@@ -26963,7 +27376,7 @@ function makeXAiAskUserQuestionResponse(params, answers) {
|
|
|
26963
27376
|
const resolved = values.map((value) => ({ value, option: optionByLabel.get(value) }));
|
|
26964
27377
|
const selectedLabels = resolved.flatMap(({ option }) => option ? [option.label] : []);
|
|
26965
27378
|
const notes = resolved.flatMap(({ option, value }) => option ? [] : [value]);
|
|
26966
|
-
const preview = question.multiSelect ? void 0 : resolved.map(({ option }) =>
|
|
27379
|
+
const preview = question.multiSelect ? void 0 : resolved.map(({ option }) => trimmed2(option?.preview)).find((value) => value);
|
|
26967
27380
|
const annotation = preview !== void 0 || notes.length > 0 ? {
|
|
26968
27381
|
...preview !== void 0 ? { preview } : {},
|
|
26969
27382
|
...notes.length > 0 ? { notes: notes.join("\n") } : {}
|
|
@@ -26993,34 +27406,99 @@ function makeXAiAskUserQuestionCancelledResponse() {
|
|
|
26993
27406
|
return { outcome: "cancelled" };
|
|
26994
27407
|
}
|
|
26995
27408
|
var XAI_PROMPT_COMPLETE_METHOD = "_x.ai/session/prompt_complete";
|
|
27409
|
+
var GROK_RATE_LIMIT_MESSAGE = "Grok usage limit reached or rate limited. Try again later.";
|
|
27410
|
+
var grokAgentResultMessage = (value) => {
|
|
27411
|
+
if (typeof value === "string") return trimmed2(value);
|
|
27412
|
+
return isRecord9(value) ? trimmed2(value["message"]) : void 0;
|
|
27413
|
+
};
|
|
26996
27414
|
var grokPromptSettlement = {
|
|
26997
27415
|
// 关联 id 双写 promptId 与 requestId(宿主 XAiAcpExtension 同款):
|
|
26998
27416
|
// agent 认回哪个键是它的事,两个都给才不猜版本。
|
|
26999
27417
|
requestFields: (promptKey) => ({ _meta: { promptId: promptKey, requestId: promptKey } }),
|
|
27000
27418
|
responseKey: (response) => {
|
|
27001
|
-
if (!
|
|
27419
|
+
if (!isRecord9(response)) return void 0;
|
|
27002
27420
|
const meta3 = response["_meta"];
|
|
27003
|
-
if (!
|
|
27004
|
-
return
|
|
27421
|
+
if (!isRecord9(meta3)) return void 0;
|
|
27422
|
+
return trimmed2(meta3["promptId"]) ?? trimmed2(meta3["requestId"]);
|
|
27005
27423
|
},
|
|
27006
27424
|
fromNotification: (method, params) => {
|
|
27007
27425
|
if (method !== XAI_PROMPT_COMPLETE_METHOD) return void 0;
|
|
27008
|
-
if (!
|
|
27426
|
+
if (!isRecord9(params)) return void 0;
|
|
27009
27427
|
const sessionId = params["sessionId"];
|
|
27010
27428
|
if (typeof sessionId !== "string") return void 0;
|
|
27011
|
-
const stopReason =
|
|
27429
|
+
const stopReason = trimmed2(params["stopReason"]);
|
|
27430
|
+
const failed = stopReason === "error" || stopReason === "rate_limit";
|
|
27431
|
+
const detail = stopReason === "rate_limit" ? GROK_RATE_LIMIT_MESSAGE : grokAgentResultMessage(params["agentResult"]);
|
|
27012
27432
|
return {
|
|
27013
27433
|
sessionId,
|
|
27014
27434
|
...typeof params["promptId"] === "string" ? { promptKey: params["promptId"] } : {},
|
|
27015
|
-
outcome:
|
|
27435
|
+
outcome: failed ? "error" : "completed",
|
|
27016
27436
|
...stopReason === void 0 ? {} : { stopReason },
|
|
27017
|
-
...
|
|
27437
|
+
...detail === void 0 ? {} : { detail }
|
|
27018
27438
|
};
|
|
27019
27439
|
}
|
|
27020
27440
|
};
|
|
27021
27441
|
|
|
27442
|
+
// src/grokSkills.ts
|
|
27443
|
+
import * as NodeOS from "node:os";
|
|
27444
|
+
var INSPECT_TIMEOUT_MS = 15e3;
|
|
27445
|
+
var MAX_INSPECT_OUTPUT_BYTES = 4 * 1024 * 1024;
|
|
27446
|
+
var GROK_INSPECT_ARGS = ["inspect", "--json"];
|
|
27447
|
+
var isRecord10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27448
|
+
var trimmedString = (value) => typeof value === "string" ? value.trim() : "";
|
|
27449
|
+
function parseGrokInspectSkills(stdout) {
|
|
27450
|
+
let parsed;
|
|
27451
|
+
try {
|
|
27452
|
+
parsed = JSON.parse(stdout);
|
|
27453
|
+
} catch {
|
|
27454
|
+
return [];
|
|
27455
|
+
}
|
|
27456
|
+
const entries = isRecord10(parsed) ? parsed["skills"] : void 0;
|
|
27457
|
+
if (!Array.isArray(entries)) return [];
|
|
27458
|
+
const byName = /* @__PURE__ */ new Map();
|
|
27459
|
+
for (const entry of entries) {
|
|
27460
|
+
if (!isRecord10(entry)) continue;
|
|
27461
|
+
const name = trimmedString(entry["name"]);
|
|
27462
|
+
const source = isRecord10(entry["source"]) ? entry["source"] : void 0;
|
|
27463
|
+
const path = trimmedString(source?.["path"]);
|
|
27464
|
+
if (name.length === 0 || path.length === 0) continue;
|
|
27465
|
+
const scope = trimmedString(source?.["type"]);
|
|
27466
|
+
const description = trimmedString(entry["description"]);
|
|
27467
|
+
byName.set(name, {
|
|
27468
|
+
name,
|
|
27469
|
+
path,
|
|
27470
|
+
enabled: entry["userInvocable"] !== false,
|
|
27471
|
+
...scope.length > 0 ? { scope } : {},
|
|
27472
|
+
...description.length > 0 ? { description } : {}
|
|
27473
|
+
});
|
|
27474
|
+
}
|
|
27475
|
+
return [...byName.values()].toSorted((left, right) => left.name.localeCompare(right.name));
|
|
27476
|
+
}
|
|
27477
|
+
async function probeGrokSkills(input2) {
|
|
27478
|
+
const { recipe, host, env } = input2;
|
|
27479
|
+
try {
|
|
27480
|
+
const handle = await host.process.spawn({
|
|
27481
|
+
program: recipe.binaryPath,
|
|
27482
|
+
args: GROK_INSPECT_ARGS,
|
|
27483
|
+
cwd: NodeOS.homedir(),
|
|
27484
|
+
owner: { bindingId: host.bindingId },
|
|
27485
|
+
...Object.keys(env).length > 0 ? { env } : {}
|
|
27486
|
+
});
|
|
27487
|
+
const run = await collectProbeProcess(handle, {
|
|
27488
|
+
timeoutMs: INSPECT_TIMEOUT_MS,
|
|
27489
|
+
maxOutputBytes: MAX_INSPECT_OUTPUT_BYTES,
|
|
27490
|
+
what: "grok inspect"
|
|
27491
|
+
});
|
|
27492
|
+
if (run.exitCode !== 0 || run.stdout === void 0) return [];
|
|
27493
|
+
return parseGrokInspectSkills(run.stdout);
|
|
27494
|
+
} catch {
|
|
27495
|
+
return [];
|
|
27496
|
+
}
|
|
27497
|
+
}
|
|
27498
|
+
|
|
27022
27499
|
// src/probeModels.ts
|
|
27023
27500
|
import {
|
|
27501
|
+
describeExecutorSpawnFailure,
|
|
27024
27502
|
ExecutorSpawnRefusedError
|
|
27025
27503
|
} from "@ycodium-ai/plugin-api/executor";
|
|
27026
27504
|
import { nodeStreamsFromHandle } from "@ycodium-ai/plugin-api/process-stdin";
|
|
@@ -27048,7 +27526,7 @@ async function probeGrokModels(input2) {
|
|
|
27048
27526
|
});
|
|
27049
27527
|
} catch (error62) {
|
|
27050
27528
|
if (error62 instanceof ExecutorSpawnRefusedError) throw error62;
|
|
27051
|
-
return { kind: "not-started",
|
|
27529
|
+
return { kind: "not-started", ...describeExecutorSpawnFailure(error62) };
|
|
27052
27530
|
}
|
|
27053
27531
|
let handshake;
|
|
27054
27532
|
try {
|
|
@@ -27123,16 +27601,16 @@ var deviceCodeUrl = (output2) => DEVICE_CODE_URL.exec(output2)?.[0];
|
|
|
27123
27601
|
var deviceCodeValue = (output2) => DEVICE_CODE_VALUE.exec(output2)?.[1];
|
|
27124
27602
|
var hasDeviceCode = (output2) => deviceCodeUrl(output2) !== void 0 && deviceCodeValue(output2) !== void 0;
|
|
27125
27603
|
function expandHomePath(value) {
|
|
27126
|
-
if (value === "~") return
|
|
27604
|
+
if (value === "~") return NodeOS2.homedir();
|
|
27127
27605
|
if (value.startsWith("~/") || value.startsWith("~\\")) {
|
|
27128
|
-
return NodePath2.join(
|
|
27606
|
+
return NodePath2.join(NodeOS2.homedir(), value.slice(2));
|
|
27129
27607
|
}
|
|
27130
27608
|
return value;
|
|
27131
27609
|
}
|
|
27132
27610
|
function resolveGrokHomePath(value) {
|
|
27133
|
-
const
|
|
27134
|
-
if (
|
|
27135
|
-
return NodePath2.resolve(expandHomePath(
|
|
27611
|
+
const trimmed3 = value.trim();
|
|
27612
|
+
if (trimmed3.length === 0) return NodePath2.join(NodeOS2.homedir(), ".grok");
|
|
27613
|
+
return NodePath2.resolve(expandHomePath(trimmed3));
|
|
27136
27614
|
}
|
|
27137
27615
|
function probeGrokAccount(accountPath) {
|
|
27138
27616
|
const resolved = resolveGrokHomePath(accountPath);
|
|
@@ -27157,7 +27635,7 @@ function resolveAccountHomePath(recipe, configuredHome) {
|
|
|
27157
27635
|
}
|
|
27158
27636
|
function absentPath() {
|
|
27159
27637
|
return NodePath2.join(
|
|
27160
|
-
|
|
27638
|
+
NodeOS2.tmpdir(),
|
|
27161
27639
|
`ycodium-grok-no-auth-${NodeCrypto2.randomUUID()}`,
|
|
27162
27640
|
"auth.json"
|
|
27163
27641
|
);
|
|
@@ -27239,7 +27717,7 @@ var createGrokInstance = (config2, host) => {
|
|
|
27239
27717
|
return {
|
|
27240
27718
|
installed: false,
|
|
27241
27719
|
version: null,
|
|
27242
|
-
readiness: "
|
|
27720
|
+
readiness: "not-installed",
|
|
27243
27721
|
auth: { status: "unknown" },
|
|
27244
27722
|
detail: "Grok program path is not configured"
|
|
27245
27723
|
};
|
|
@@ -27250,15 +27728,17 @@ var createGrokInstance = (config2, host) => {
|
|
|
27250
27728
|
resolveGrokHomePath(configuredHome),
|
|
27251
27729
|
configuredHome.trim().length > 0
|
|
27252
27730
|
);
|
|
27253
|
-
const [outcome, version2] = await Promise.all([
|
|
27731
|
+
const [outcome, version2, skills] = await Promise.all([
|
|
27254
27732
|
probeGrokModels({ recipe, host, env }),
|
|
27255
|
-
probeGrokVersion({ recipe, host, env })
|
|
27733
|
+
probeGrokVersion({ recipe, host, env }),
|
|
27734
|
+
probeGrokSkills({ recipe, host, env })
|
|
27256
27735
|
]);
|
|
27257
27736
|
if (outcome.kind !== "answered") {
|
|
27258
27737
|
return {
|
|
27259
27738
|
installed: outcome.kind === "failed",
|
|
27260
27739
|
version: version2,
|
|
27261
|
-
|
|
27740
|
+
// 找不到、路径不存在、不可执行是 not-installed,别的启动失败与握不上手都是 error。
|
|
27741
|
+
readiness: outcome.kind === "not-started" ? outcome.readiness : "error",
|
|
27262
27742
|
auth: probeAuth(),
|
|
27263
27743
|
...outcome.detail === void 0 ? {} : { detail: outcome.detail },
|
|
27264
27744
|
// 装着但握不上手时,界面照样画权限格。不报档就退回宿主四档,而那四档对这双手
|
|
@@ -27272,6 +27752,7 @@ var createGrokInstance = (config2, host) => {
|
|
|
27272
27752
|
readiness: "ready",
|
|
27273
27753
|
auth: probeAuth(),
|
|
27274
27754
|
...outcome.models === void 0 ? {} : { models: outcome.models },
|
|
27755
|
+
skills,
|
|
27275
27756
|
...GROK_NATIVE_MODE_REPORT
|
|
27276
27757
|
};
|
|
27277
27758
|
};
|
|
@@ -27315,13 +27796,15 @@ var createGrokInstance = (config2, host) => {
|
|
|
27315
27796
|
owner: { bindingId: host.bindingId },
|
|
27316
27797
|
...Object.keys(env).length > 0 ? { env } : {}
|
|
27317
27798
|
});
|
|
27318
|
-
const { readable, writable } = nodeStreamsFromHandle2(handle);
|
|
27799
|
+
const { readable, writable, stderrTail } = nodeStreamsFromHandle2(handle);
|
|
27319
27800
|
const resume = input2.discardResumeCursor === true ? void 0 : parseAcpResumeCursor(input2.resumeCursor, RESUME_SCHEMA_VERSION);
|
|
27320
27801
|
const requestedModelId = modelIdFromSelection(input2.modelSelection);
|
|
27321
27802
|
let initializeResult;
|
|
27803
|
+
const backgroundTasks = /* @__PURE__ */ new Map();
|
|
27322
27804
|
const executor = createAcpExecutor({
|
|
27323
27805
|
readable,
|
|
27324
27806
|
writable,
|
|
27807
|
+
stderrTail,
|
|
27325
27808
|
cwd,
|
|
27326
27809
|
threadId: input2.threadId,
|
|
27327
27810
|
provider: GROK_DRIVER_KIND,
|
|
@@ -27333,7 +27816,23 @@ var createGrokInstance = (config2, host) => {
|
|
|
27333
27816
|
authMethodId: resolveGrokAuthMethodId,
|
|
27334
27817
|
hooks: {
|
|
27335
27818
|
promptSettlement: grokPromptSettlement,
|
|
27819
|
+
onToolCallUpdated: (update) => buildGrokBackgroundTaskEvents({
|
|
27820
|
+
tasks: backgroundTasks,
|
|
27821
|
+
toolCallId: update.toolCallId,
|
|
27822
|
+
rawInput: update.rawInput,
|
|
27823
|
+
rawOutput: update.rawOutput,
|
|
27824
|
+
toolCallStatus: update.status,
|
|
27825
|
+
turnId: update.turnId
|
|
27826
|
+
}),
|
|
27336
27827
|
onExtensionRequest: async (method, params, ctx) => {
|
|
27828
|
+
if (XAI_EXIT_PLAN_MODE_METHODS.includes(method)) {
|
|
27829
|
+
const plan = parseXAiExitPlanModeParams(params);
|
|
27830
|
+
if (plan === void 0) {
|
|
27831
|
+
throw new Error(`malformed ${method} params`);
|
|
27832
|
+
}
|
|
27833
|
+
const resolution2 = await ctx.askUserInput([grokPlanQuestion(plan)]);
|
|
27834
|
+
return makeXAiExitPlanModeResponse(plan, resolution2);
|
|
27835
|
+
}
|
|
27337
27836
|
if (!XAI_ASK_USER_QUESTION_METHODS.includes(method)) {
|
|
27338
27837
|
throw new Error(`unsupported extension method ${method}`);
|
|
27339
27838
|
}
|
|
@@ -27495,6 +27994,15 @@ var createGrokInstance = (config2, host) => {
|
|
|
27495
27994
|
const booked = requireThread(threadId);
|
|
27496
27995
|
await booked.executor.respondToUserInput(requestId, answers);
|
|
27497
27996
|
},
|
|
27997
|
+
// 原生压缩:让 CLI 执行它自己宣告的 `/compact`。这不是用户消息——执行器不开轮次、
|
|
27998
|
+
// 不把命令吐的文本放进时间线,进度与结果只走压缩生命周期事件。
|
|
27999
|
+
compactContext: async (threadId) => {
|
|
28000
|
+
const booked = requireThread(threadId);
|
|
28001
|
+
if (booked.session.status === "running") {
|
|
28002
|
+
throw new Error("Cannot compact context while a turn is running");
|
|
28003
|
+
}
|
|
28004
|
+
await booked.executor.compact({ commandName: "compact" });
|
|
28005
|
+
},
|
|
27498
28006
|
stopSession: async (threadId) => {
|
|
27499
28007
|
const booked = threads.get(threadId);
|
|
27500
28008
|
if (booked === void 0) return;
|
|
@@ -27546,9 +28054,9 @@ var createGrokInstance = (config2, host) => {
|
|
|
27546
28054
|
const stdoutText = (async () => {
|
|
27547
28055
|
const decoder = new TextDecoder();
|
|
27548
28056
|
for await (const chunk of handle.stdout) {
|
|
27549
|
-
const
|
|
27550
|
-
collected.push(
|
|
27551
|
-
host.log.info("sign-in output", { text });
|
|
28057
|
+
const text2 = decoder.decode(chunk, { stream: true });
|
|
28058
|
+
collected.push(text2);
|
|
28059
|
+
host.log.info("sign-in output", { text: text2 });
|
|
27552
28060
|
if (onCodeFound !== void 0 && hasDeviceCode(collected.join(""))) {
|
|
27553
28061
|
onCodeFound();
|
|
27554
28062
|
onCodeFound = void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/agent-grok",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2664",
|
|
4
4
|
"description": "Grok executor: grok CLI over Agent Client Protocol stdio.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"@types/node": "24.12.4",
|
|
22
22
|
"esbuild": "0.28.1",
|
|
23
23
|
"vite-plus": "0.2.2",
|
|
24
|
+
"@ycodium-ai/plugin-api": "0.2.2664",
|
|
24
25
|
"ycodium-executor-testing": "0.0.0",
|
|
25
|
-
"
|
|
26
|
-
"ycodium-acp-executor": "0.2.2634"
|
|
26
|
+
"ycodium-acp-executor": "0.2.2664"
|
|
27
27
|
},
|
|
28
28
|
"ycodium": {
|
|
29
29
|
"plugin": "./dist/index.js",
|