@ycodium-ai/agent-grok 0.2.2126 → 0.2.2143

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 +113 -16
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -23751,6 +23751,7 @@ function createAcpConnection(options) {
23751
23751
  options.readable.off("data", onData);
23752
23752
  options.readable.off("end", onEnd);
23753
23753
  options.readable.off("error", onError);
23754
+ options.writable.off("error", onWritableError);
23754
23755
  try {
23755
23756
  await byteWriter.close();
23756
23757
  } catch {
@@ -23889,8 +23890,17 @@ function createAcpConnection(options) {
23889
23890
  endInboundBatch();
23890
23891
  }
23891
23892
  };
23893
+ const failInbound = (error62) => {
23894
+ if (closedError !== void 0) return;
23895
+ options.onInboundFailure?.(error62);
23896
+ void shutdown(
23897
+ new AcpConnectionClosedError(
23898
+ `ACP inbound handling failed: ${error62 instanceof Error ? error62.message : String(error62)}`
23899
+ )
23900
+ );
23901
+ };
23892
23902
  const enqueueInbound = (work) => {
23893
- inboundTail = inboundTail.then(work, work);
23903
+ inboundTail = inboundTail.then(work).catch(failInbound);
23894
23904
  };
23895
23905
  const onData = (chunk) => {
23896
23906
  if (closedError !== void 0) {
@@ -23940,9 +23950,15 @@ function createAcpConnection(options) {
23940
23950
  );
23941
23951
  });
23942
23952
  };
23953
+ const onWritableError = (error62) => {
23954
+ void shutdown(
23955
+ error62 instanceof Error ? error62 : new AcpConnectionClosedError("ACP output stream error")
23956
+ );
23957
+ };
23943
23958
  options.readable.on("data", onData);
23944
23959
  options.readable.on("end", onEnd);
23945
23960
  options.readable.on("error", onError);
23961
+ options.writable.once("error", onWritableError);
23946
23962
  const request = (async (method, params) => {
23947
23963
  failIfClosed();
23948
23964
  const id = nextRequestId;
@@ -23951,7 +23967,7 @@ function createAcpConnection(options) {
23951
23967
  pending.set(String(id), { method, resolve: resolve2, reject });
23952
23968
  const message = params === void 0 ? { jsonrpc: "2.0", id, method } : { jsonrpc: "2.0", id, method, params };
23953
23969
  try {
23954
- await writeMessage(message);
23970
+ await Promise.race([writeMessage(message), promise2]);
23955
23971
  } catch (error62) {
23956
23972
  if (pending.delete(String(id))) {
23957
23973
  reject(error62);
@@ -25726,6 +25742,12 @@ function createAcpExecutor(options) {
25726
25742
  const connection = createAcpConnection({
25727
25743
  readable: options.readable,
25728
25744
  writable: options.writable,
25745
+ onInboundFailure: (error62) => {
25746
+ options.log?.warn?.("acp connection closed: an inbound request could not be answered", {
25747
+ threadId: options.threadId,
25748
+ error: error62 instanceof Error ? error62.message : String(error62)
25749
+ });
25750
+ },
25729
25751
  onNotification: (notification) => {
25730
25752
  if (notification.method === "session/update") {
25731
25753
  handleSessionUpdate(notification.params);
@@ -26363,10 +26385,10 @@ function createAcpExecutor(options) {
26363
26385
  }
26364
26386
 
26365
26387
  // ../../packages/ycodium-acp-executor/src/probe.ts
26366
- function withProbeTimeout(promise2, timeoutMs, method) {
26388
+ function withProbeTimeout(promise2, timeoutMs, what) {
26367
26389
  return new Promise((resolve2, reject) => {
26368
26390
  const timer = setTimeout(() => {
26369
- reject(new Error(`ACP probe request '${method}' timed out after ${timeoutMs}ms`));
26391
+ reject(new Error(`${what} timed out after ${timeoutMs}ms`));
26370
26392
  }, timeoutMs);
26371
26393
  timer.unref?.();
26372
26394
  promise2.then(
@@ -26391,11 +26413,15 @@ async function openAcpProbeHandshake(input2) {
26391
26413
  const initializeResult = await withProbeTimeout(
26392
26414
  connection.request("initialize", acpInitializePayload(input2.clientInfo)),
26393
26415
  input2.requestTimeoutMs,
26394
- "initialize"
26416
+ "ACP probe request 'initialize'"
26395
26417
  );
26396
26418
  return {
26397
26419
  initializeResult,
26398
- request: (method, params) => withProbeTimeout(connection.request(method, params), input2.requestTimeoutMs, method),
26420
+ request: (method, params) => withProbeTimeout(
26421
+ connection.request(method, params),
26422
+ input2.requestTimeoutMs,
26423
+ `ACP probe request '${method}'`
26424
+ ),
26399
26425
  close: () => connection.close()
26400
26426
  };
26401
26427
  } catch (error62) {
@@ -26403,6 +26429,57 @@ async function openAcpProbeHandshake(input2) {
26403
26429
  throw error62;
26404
26430
  }
26405
26431
  }
26432
+ var CLI_VERSION_PATTERN = /(?<![\d.])(\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?)/;
26433
+ function parseCliVersion(output2) {
26434
+ return CLI_VERSION_PATTERN.exec(output2)?.[1] ?? null;
26435
+ }
26436
+ async function collectCappedText(stream, maxBytes) {
26437
+ const decoder = new TextDecoder();
26438
+ let text = "";
26439
+ let total = 0;
26440
+ for await (const chunk of stream) {
26441
+ total += chunk.byteLength;
26442
+ if (total <= maxBytes) text += decoder.decode(chunk, { stream: true });
26443
+ }
26444
+ return { text: text + decoder.decode(), overflowed: total > maxBytes };
26445
+ }
26446
+ async function collectProbeProcess(child, input2) {
26447
+ try {
26448
+ await child.closeStdin().catch(() => void 0);
26449
+ const [stdout, stderr, exitCode] = await withProbeTimeout(
26450
+ Promise.all([
26451
+ collectCappedText(child.stdout, input2.maxOutputBytes),
26452
+ collectCappedText(child.stderr, input2.maxOutputBytes),
26453
+ child.exited
26454
+ ]),
26455
+ input2.timeoutMs,
26456
+ input2.what
26457
+ );
26458
+ return { stdout: stdout.overflowed ? void 0 : stdout.text, stderr: stderr.text, exitCode };
26459
+ } finally {
26460
+ await child.kill("SIGTERM").catch(() => void 0);
26461
+ }
26462
+ }
26463
+ var MAX_VERSION_OUTPUT_BYTES = 64 * 1024;
26464
+ async function probeCliVersion(input2) {
26465
+ let child;
26466
+ try {
26467
+ child = await input2.spawn();
26468
+ } catch {
26469
+ return null;
26470
+ }
26471
+ try {
26472
+ const run = await collectProbeProcess(child, {
26473
+ timeoutMs: input2.timeoutMs,
26474
+ maxOutputBytes: MAX_VERSION_OUTPUT_BYTES,
26475
+ what: "--version"
26476
+ });
26477
+ if (run.exitCode !== 0) return null;
26478
+ return parseCliVersion(run.stdout ?? "") ?? parseCliVersion(run.stderr);
26479
+ } catch {
26480
+ return null;
26481
+ }
26482
+ }
26406
26483
 
26407
26484
  // src/config.ts
26408
26485
  var GROK_DEFAULT_LAUNCH_ARGS = "agent stdio";
@@ -26880,6 +26957,9 @@ var grokPromptSettlement = {
26880
26957
  };
26881
26958
 
26882
26959
  // src/probeModels.ts
26960
+ import {
26961
+ ExecutorSpawnRefusedError
26962
+ } from "@ycodium-ai/plugin-api/executor";
26883
26963
  import { nodeStreamsFromHandle } from "@ycodium-ai/plugin-api/process-stdin";
26884
26964
  var PROBE_REQUEST_TIMEOUT_MS = 2e4;
26885
26965
  function grokProbeModels(initializeResult) {
@@ -26904,6 +26984,7 @@ async function probeGrokModels(input2) {
26904
26984
  ...Object.keys(env).length > 0 ? { env } : {}
26905
26985
  });
26906
26986
  } catch (error62) {
26987
+ if (error62 instanceof ExecutorSpawnRefusedError) throw error62;
26907
26988
  return { kind: "not-started", detail: failureDetail(error62) };
26908
26989
  }
26909
26990
  let handshake;
@@ -26923,6 +27004,18 @@ async function probeGrokModels(input2) {
26923
27004
  await handle.kill("SIGTERM").catch(() => void 0);
26924
27005
  }
26925
27006
  }
27007
+ async function probeGrokVersion(input2) {
27008
+ const { recipe, host, env } = input2;
27009
+ return probeCliVersion({
27010
+ spawn: () => host.process.spawn({
27011
+ program: recipe.binaryPath,
27012
+ args: ["--version"],
27013
+ owner: { bindingId: host.bindingId },
27014
+ ...Object.keys(env).length > 0 ? { env } : {}
27015
+ }),
27016
+ timeoutMs: PROBE_REQUEST_TIMEOUT_MS
27017
+ });
27018
+ }
26926
27019
 
26927
27020
  // src/grokInstance.ts
26928
27021
  var RESUME_SCHEMA_VERSION = 1;
@@ -26978,6 +27071,9 @@ function resolveGrokHomePath(value) {
26978
27071
  if (trimmed2.length === 0) return NodePath2.join(NodeOS.homedir(), ".grok");
26979
27072
  return NodePath2.resolve(expandHomePath(trimmed2));
26980
27073
  }
27074
+ function grokContinuationKey(recipe) {
27075
+ return `grok:home:${resolveGrokHomePath(recipe.homePath)}`;
27076
+ }
26981
27077
  function resolveAccountHomePath(recipe, configuredHome) {
26982
27078
  const fromEnvironment = recipe.environment["GROK_HOME"]?.trim();
26983
27079
  if (fromEnvironment !== void 0 && fromEnvironment.length > 0) {
@@ -27048,19 +27144,19 @@ var createGrokInstance = (config2, host) => {
27048
27144
  };
27049
27145
  }
27050
27146
  const configuredHome = recipe.homePath;
27051
- const outcome = await probeGrokModels({
27147
+ const env = buildSpawnEnv(
27052
27148
  recipe,
27053
- host,
27054
- env: buildSpawnEnv(
27055
- recipe,
27056
- resolveGrokHomePath(configuredHome),
27057
- configuredHome.trim().length > 0
27058
- )
27059
- });
27149
+ resolveGrokHomePath(configuredHome),
27150
+ configuredHome.trim().length > 0
27151
+ );
27152
+ const [outcome, version2] = await Promise.all([
27153
+ probeGrokModels({ recipe, host, env }),
27154
+ probeGrokVersion({ recipe, host, env })
27155
+ ]);
27060
27156
  if (outcome.kind !== "answered") {
27061
27157
  return {
27062
27158
  installed: outcome.kind === "failed",
27063
- version: null,
27159
+ version: version2,
27064
27160
  readiness: "error",
27065
27161
  auth: probeAuth(),
27066
27162
  ...outcome.detail === void 0 ? {} : { detail: outcome.detail },
@@ -27071,7 +27167,7 @@ var createGrokInstance = (config2, host) => {
27071
27167
  }
27072
27168
  return {
27073
27169
  installed: true,
27074
- version: null,
27170
+ version: version2,
27075
27171
  readiness: "ready",
27076
27172
  auth: probeAuth(),
27077
27173
  ...outcome.models === void 0 ? {} : { models: outcome.models },
@@ -27305,6 +27401,7 @@ var createGrokInstance = (config2, host) => {
27305
27401
  return { threadId, turns: booked.turns };
27306
27402
  },
27307
27403
  events,
27404
+ continuationKey: grokContinuationKey(recipe),
27308
27405
  dispose: async () => {
27309
27406
  if (disposed) return;
27310
27407
  disposed = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-grok",
3
- "version": "0.2.2126",
3
+ "version": "0.2.2143",
4
4
  "description": "Grok executor: grok CLI over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -20,7 +20,7 @@
20
20
  "@types/node": "24.12.4",
21
21
  "esbuild": "0.28.1",
22
22
  "vite-plus": "0.2.2",
23
- "@ycodium-ai/plugin-api": "0.2.2126",
23
+ "@ycodium-ai/plugin-api": "0.2.2143",
24
24
  "ycodium-acp-executor": "0.0.0",
25
25
  "ycodium-acp-protocol": "0.0.0"
26
26
  },