@ycodium-ai/agent-grok 0.2.2808 → 0.2.2840

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 +81 -72
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -24032,22 +24032,28 @@ function createAcpConnection(options) {
24032
24032
  options.readable.on("end", onEnd);
24033
24033
  options.readable.on("error", onError);
24034
24034
  options.writable.once("error", onWritableError);
24035
- const request = (async (method, params) => {
24035
+ const begin = (method, params) => {
24036
24036
  failIfClosed();
24037
24037
  const id = nextRequestId;
24038
24038
  nextRequestId += 1;
24039
24039
  const { promise: promise2, resolve: resolve2, reject } = Promise.withResolvers();
24040
24040
  pending.set(String(id), { method, resolve: resolve2, reject });
24041
24041
  const message = params === void 0 ? { jsonrpc: "2.0", id, method } : { jsonrpc: "2.0", id, method, params };
24042
- try {
24043
- await Promise.race([writeMessage(message), promise2]);
24044
- } catch (error62) {
24045
- if (pending.delete(String(id))) {
24046
- reject(error62);
24042
+ const written = Promise.race([writeMessage(message), promise2]).then(
24043
+ () => void 0,
24044
+ (error62) => {
24045
+ if (pending.delete(String(id))) {
24046
+ reject(error62);
24047
+ }
24048
+ throw error62;
24047
24049
  }
24048
- throw error62;
24049
- }
24050
- return promise2;
24050
+ );
24051
+ return { written, response: promise2 };
24052
+ };
24053
+ const request = (async (method, params) => {
24054
+ const { written, response } = begin(method, params);
24055
+ await written;
24056
+ return response;
24051
24057
  });
24052
24058
  const notify = async (method, params) => {
24053
24059
  failIfClosed();
@@ -24068,6 +24074,7 @@ function createAcpConnection(options) {
24068
24074
  const close = (error62) => shutdown(error62 ?? new AcpConnectionClosedError());
24069
24075
  return {
24070
24076
  request,
24077
+ begin,
24071
24078
  notify,
24072
24079
  awaitInboundIdle,
24073
24080
  close,
@@ -25415,6 +25422,13 @@ function modelSelectionStateFromSetup(setup) {
25415
25422
  };
25416
25423
  }
25417
25424
 
25425
+ // ../../packages/ycodium-acp-executor/src/user-input-pending.ts
25426
+ var userInputAnswerOptionId = (question, answers) => {
25427
+ const answer = answers[question.id];
25428
+ const selected = typeof answer === "string" ? answer : Array.isArray(answer) && answer.length === 1 && typeof answer[0] === "string" ? answer[0] : void 0;
25429
+ return selected !== void 0 && question.options.some((option) => option.id === selected) ? selected : void 0;
25430
+ };
25431
+
25418
25432
  // ../../packages/ycodium-acp-executor/src/vendor-hooks.ts
25419
25433
  var defaultVendorHooks = {
25420
25434
  completedStopReason: (response) => response.stopReason
@@ -25422,11 +25436,6 @@ var defaultVendorHooks = {
25422
25436
 
25423
25437
  // ../../packages/ycodium-acp-executor/src/executor.ts
25424
25438
  var DEFAULT_CANCEL_GRACE_MS = 5e3;
25425
- var userInputAnswerOptionId = (question, answers) => {
25426
- const answer = answers[question.id];
25427
- const selected = typeof answer === "string" ? answer : Array.isArray(answer) && answer.length === 1 && typeof answer[0] === "string" ? answer[0] : void 0;
25428
- return selected !== void 0 && question.options.some((option) => option.id === selected) ? selected : void 0;
25429
- };
25430
25439
  function defaultNowIso() {
25431
25440
  return (/* @__PURE__ */ new Date()).toISOString();
25432
25441
  }
@@ -26250,7 +26259,7 @@ function createAcpExecutor(options) {
26250
26259
  };
26251
26260
  const settleTurn = (input2) => {
26252
26261
  if (!isLive(input2.expectedGeneration)) {
26253
- return;
26262
+ return false;
26254
26263
  }
26255
26264
  if (!acpPromptSettlementBelongsToContext({
26256
26265
  liveAcpSessionId: sessionId ?? "",
@@ -26259,37 +26268,40 @@ function createAcpExecutor(options) {
26259
26268
  liveSessionActiveTurnId: activeTurnId,
26260
26269
  turnId: input2.turnId
26261
26270
  })) {
26262
- return;
26271
+ return false;
26263
26272
  }
26264
26273
  closeActiveAssistantSegment(input2.turnId);
26265
26274
  promptsInFlight = Math.max(0, promptsInFlight - 1);
26266
- if (promptsInFlight === 0 && activeTurnId === input2.turnId) {
26267
- activeTurnId = void 0;
26268
- if (status !== "disposed") {
26269
- status = "ready";
26270
- }
26271
- emit({
26272
- type: "turn.completed",
26273
- ...stamp(),
26274
- provider: options.provider,
26275
- threadId: options.threadId,
26276
- turnId: input2.turnId,
26277
- payload: {
26278
- state: input2.state,
26279
- stopReason: input2.stopReason
26280
- }
26281
- });
26282
- interruptedTurnIds.delete(input2.turnId);
26275
+ if (promptsInFlight !== 0 || activeTurnId !== input2.turnId) return false;
26276
+ activeTurnId = void 0;
26277
+ if (status !== "disposed") {
26278
+ status = "ready";
26283
26279
  }
26280
+ emit({
26281
+ type: "turn.completed",
26282
+ ...stamp(),
26283
+ provider: options.provider,
26284
+ threadId: options.threadId,
26285
+ turnId: input2.turnId,
26286
+ payload: {
26287
+ state: input2.state,
26288
+ stopReason: input2.stopReason,
26289
+ ...input2.errorMessage === void 0 ? {} : { errorMessage: input2.errorMessage }
26290
+ }
26291
+ });
26292
+ interruptedTurnIds.delete(input2.turnId);
26293
+ return true;
26284
26294
  };
26285
- const sendPromptRpc = async (sessionId2, promptParts) => {
26295
+ const sendPromptRpc = async (sessionId2, promptParts, onWritten) => {
26286
26296
  const settlementHooks = hooks.promptSettlement;
26287
26297
  const promptKey = settlementHooks === void 0 ? void 0 : randomId();
26288
- const promptRpc = connection.request("session/prompt", {
26298
+ const pending = connection.begin("session/prompt", {
26289
26299
  sessionId: sessionId2,
26290
26300
  prompt: promptParts,
26291
26301
  ...settlementHooks !== void 0 && promptKey !== void 0 ? settlementHooks.requestFields(promptKey) : {}
26292
26302
  });
26303
+ void pending.written.then(onWritten, () => void 0);
26304
+ const promptRpc = pending.response;
26293
26305
  if (settlementHooks === void 0 || promptKey === void 0) {
26294
26306
  return await promptRpc;
26295
26307
  } else {
@@ -26315,6 +26327,11 @@ function createAcpExecutor(options) {
26315
26327
  const prompt = async (input2) => {
26316
26328
  failIfDisposed();
26317
26329
  const started = requireStarted();
26330
+ const settle2 = (rest) => settleTurn({
26331
+ expectedGeneration: started.generation,
26332
+ expectedSessionId: started.sessionId,
26333
+ ...rest
26334
+ });
26318
26335
  let turnId;
26319
26336
  await threadMutex.acquire();
26320
26337
  try {
@@ -26342,13 +26359,7 @@ function createAcpExecutor(options) {
26342
26359
  try {
26343
26360
  failIfDisposed();
26344
26361
  if (interruptedTurnIds.has(turnId)) {
26345
- settleTurn({
26346
- expectedGeneration: started.generation,
26347
- expectedSessionId: started.sessionId,
26348
- turnId,
26349
- stopReason: "cancelled",
26350
- state: "cancelled"
26351
- });
26362
+ settle2({ turnId, stopReason: "cancelled", state: "cancelled" });
26352
26363
  return {
26353
26364
  threadId: options.threadId,
26354
26365
  turnId,
@@ -26362,12 +26373,24 @@ function createAcpExecutor(options) {
26362
26373
  expectedGeneration: started.generation
26363
26374
  });
26364
26375
  closeActiveAssistantSegment(turnId);
26376
+ let written = false;
26365
26377
  try {
26366
- response = await sendPromptRpc(started.sessionId, promptParts);
26378
+ response = await sendPromptRpc(started.sessionId, promptParts, () => {
26379
+ written = true;
26380
+ input2.onDispatched?.(turnId);
26381
+ });
26367
26382
  } catch (error62) {
26368
26383
  if (disposed) {
26369
26384
  throw new AcpExecutorDisposedError();
26370
26385
  }
26386
+ if (written && input2.onDispatched !== void 0 && !interruptedTurnIds.has(turnId)) {
26387
+ const errorMessage = error62 instanceof Error && error62.message.trim() || "ACP prompt failed";
26388
+ if (settle2({ turnId, stopReason: "error", state: "failed", errorMessage }))
26389
+ options.log?.warn?.("turn failed after dispatch", {
26390
+ threadId: options.threadId,
26391
+ failure: errorMessage
26392
+ });
26393
+ }
26371
26394
  throw error62;
26372
26395
  }
26373
26396
  await connection.awaitInboundIdle();
@@ -26398,13 +26421,7 @@ function createAcpExecutor(options) {
26398
26421
  }
26399
26422
  const finishPrompt = () => {
26400
26423
  if (interruptedTurnIds.has(settledTurnId)) {
26401
- settleTurn({
26402
- expectedGeneration: started.generation,
26403
- expectedSessionId: started.sessionId,
26404
- turnId: settledTurnId,
26405
- stopReason: "cancelled",
26406
- state: "cancelled"
26407
- });
26424
+ settle2({ turnId: settledTurnId, stopReason: "cancelled", state: "cancelled" });
26408
26425
  return {
26409
26426
  threadId: options.threadId,
26410
26427
  turnId: settledTurnId,
@@ -26427,9 +26444,7 @@ function createAcpExecutor(options) {
26427
26444
  }
26428
26445
  });
26429
26446
  }
26430
- settleTurn({
26431
- expectedGeneration: started.generation,
26432
- expectedSessionId: started.sessionId,
26447
+ settle2({
26433
26448
  turnId: settledTurnId,
26434
26449
  stopReason,
26435
26450
  state: response.stopReason === "cancelled" ? "cancelled" : "completed"
@@ -26687,6 +26702,17 @@ function createAcpExecutor(options) {
26687
26702
  };
26688
26703
  }
26689
26704
 
26705
+ // ../../packages/ycodium-acp-executor/src/prompt-dispatch.ts
26706
+ var dispatchAcpPrompt = (executor, input2) => {
26707
+ const { promise: dispatched, resolve: resolve2 } = Promise.withResolvers();
26708
+ const finished = executor.prompt({ ...input2, onDispatched: resolve2 });
26709
+ return Promise.race([
26710
+ dispatched.then((turnId) => ({ turnId })),
26711
+ // 写入之前就落定:成功(写入前被取消)带 turnId;拒绝原样交给调用方,那是起轮失败。
26712
+ finished.then((result) => ({ turnId: result.turnId }))
26713
+ ]);
26714
+ };
26715
+
26690
26716
  // ../../packages/ycodium-acp-executor/src/mcp-servers.ts
26691
26717
  function toAcpMcpServers(entries) {
26692
26718
  return (entries ?? []).map(
@@ -28226,31 +28252,14 @@ var createGrokInstance = (config2, host) => {
28226
28252
  void booked.executor.cancel(input2.expectedTurnId).catch(() => void 0);
28227
28253
  };
28228
28254
  signal?.addEventListener("abort", onAbort);
28229
- booked.session = {
28230
- ...booked.session,
28231
- status: "running",
28232
- updatedAt: nowIso()
28233
- };
28234
28255
  try {
28235
28256
  const requestedModelId = modelIdFromSelection(input2.modelSelection);
28236
- const turn = await booked.executor.prompt({
28257
+ const turn = await dispatchAcpPrompt(booked.executor, {
28237
28258
  text: input2.input ?? "",
28238
28259
  ...input2.expectedTurnId === void 0 ? {} : { turnId: input2.expectedTurnId },
28239
28260
  ...requestedModelId === void 0 ? {} : { requestedModelId }
28240
- }).catch((error62) => {
28241
- if (error62 instanceof Error && "code" in error62 && error62.code === "request-failed" && error62.message === "turn cancelled") {
28242
- return { turnId: input2.expectedTurnId ?? "", cancelled: true };
28243
- }
28244
- throw error62;
28245
28261
  });
28246
- await yieldTick();
28247
28262
  booked.turns.push({ id: turn.turnId, items: [] });
28248
- booked.session = {
28249
- ...booked.session,
28250
- status: "idle",
28251
- updatedAt: nowIso(),
28252
- ...booked.executor.modelId === void 0 ? {} : { model: booked.executor.modelId }
28253
- };
28254
28263
  return {
28255
28264
  threadId: input2.threadId,
28256
28265
  turnId: turn.turnId,
@@ -28283,7 +28292,7 @@ var createGrokInstance = (config2, host) => {
28283
28292
  // 不把命令吐的文本放进时间线,进度与结果只走压缩生命周期事件。
28284
28293
  compactContext: async (threadId) => {
28285
28294
  const booked = requireThread(threadId);
28286
- if (booked.session.status === "running") {
28295
+ if (booked.executor.status === "running") {
28287
28296
  throw new Error("Cannot compact context while a turn is running");
28288
28297
  }
28289
28298
  await booked.executor.compact({ commandName: "compact" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-grok",
3
- "version": "0.2.2808",
3
+ "version": "0.2.2840",
4
4
  "description": "Grok executor: grok CLI over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -21,8 +21,8 @@
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.2808",
25
- "ycodium-acp-executor": "0.2.2808",
24
+ "ycodium-acp-executor": "0.2.2840",
25
+ "@ycodium-ai/plugin-api": "0.2.0",
26
26
  "ycodium-executor-testing": "0.0.0"
27
27
  },
28
28
  "ycodium": {