@ycodium-ai/agent-dsh 0.2.2130 → 0.2.2167

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 +106 -9
  2. package/package.json +4 -3
package/dist/index.js CHANGED
@@ -23721,6 +23721,7 @@ function createAcpConnection(options) {
23721
23721
  options.readable.off("data", onData);
23722
23722
  options.readable.off("end", onEnd);
23723
23723
  options.readable.off("error", onError);
23724
+ options.writable.off("error", onWritableError);
23724
23725
  try {
23725
23726
  await byteWriter.close();
23726
23727
  } catch {
@@ -23859,8 +23860,17 @@ function createAcpConnection(options) {
23859
23860
  endInboundBatch();
23860
23861
  }
23861
23862
  };
23863
+ const failInbound = (error62) => {
23864
+ if (closedError !== void 0) return;
23865
+ options.onInboundFailure?.(error62);
23866
+ void shutdown(
23867
+ new AcpConnectionClosedError(
23868
+ `ACP inbound handling failed: ${error62 instanceof Error ? error62.message : String(error62)}`
23869
+ )
23870
+ );
23871
+ };
23862
23872
  const enqueueInbound = (work) => {
23863
- inboundTail = inboundTail.then(work, work);
23873
+ inboundTail = inboundTail.then(work).catch(failInbound);
23864
23874
  };
23865
23875
  const onData = (chunk) => {
23866
23876
  if (closedError !== void 0) {
@@ -23910,9 +23920,15 @@ function createAcpConnection(options) {
23910
23920
  );
23911
23921
  });
23912
23922
  };
23923
+ const onWritableError = (error62) => {
23924
+ void shutdown(
23925
+ error62 instanceof Error ? error62 : new AcpConnectionClosedError("ACP output stream error")
23926
+ );
23927
+ };
23913
23928
  options.readable.on("data", onData);
23914
23929
  options.readable.on("end", onEnd);
23915
23930
  options.readable.on("error", onError);
23931
+ options.writable.once("error", onWritableError);
23916
23932
  const request = (async (method, params) => {
23917
23933
  failIfClosed();
23918
23934
  const id = nextRequestId;
@@ -23921,7 +23937,7 @@ function createAcpConnection(options) {
23921
23937
  pending.set(String(id), { method, resolve: resolve2, reject });
23922
23938
  const message = params === void 0 ? { jsonrpc: "2.0", id, method } : { jsonrpc: "2.0", id, method, params };
23923
23939
  try {
23924
- await writeMessage(message);
23940
+ await Promise.race([writeMessage(message), promise2]);
23925
23941
  } catch (error62) {
23926
23942
  if (pending.delete(String(id))) {
23927
23943
  reject(error62);
@@ -25704,6 +25720,12 @@ function createAcpExecutor(options) {
25704
25720
  const connection = createAcpConnection({
25705
25721
  readable: options.readable,
25706
25722
  writable: options.writable,
25723
+ onInboundFailure: (error62) => {
25724
+ options.log?.warn?.("acp connection closed: an inbound request could not be answered", {
25725
+ threadId: options.threadId,
25726
+ error: error62 instanceof Error ? error62.message : String(error62)
25727
+ });
25728
+ },
25707
25729
  onNotification: (notification) => {
25708
25730
  if (notification.method === "session/update") {
25709
25731
  handleSessionUpdate(notification.params);
@@ -26341,10 +26363,10 @@ function createAcpExecutor(options) {
26341
26363
  }
26342
26364
 
26343
26365
  // ../../packages/ycodium-acp-executor/src/probe.ts
26344
- function withProbeTimeout(promise2, timeoutMs, method) {
26366
+ function withProbeTimeout(promise2, timeoutMs, what) {
26345
26367
  return new Promise((resolve2, reject) => {
26346
26368
  const timer = setTimeout(() => {
26347
- reject(new Error(`ACP probe request '${method}' timed out after ${timeoutMs}ms`));
26369
+ reject(new Error(`${what} timed out after ${timeoutMs}ms`));
26348
26370
  }, timeoutMs);
26349
26371
  timer.unref?.();
26350
26372
  promise2.then(
@@ -26369,11 +26391,15 @@ async function openAcpProbeHandshake(input2) {
26369
26391
  const initializeResult = await withProbeTimeout(
26370
26392
  connection.request("initialize", acpInitializePayload(input2.clientInfo)),
26371
26393
  input2.requestTimeoutMs,
26372
- "initialize"
26394
+ "ACP probe request 'initialize'"
26373
26395
  );
26374
26396
  return {
26375
26397
  initializeResult,
26376
- request: (method, params) => withProbeTimeout(connection.request(method, params), input2.requestTimeoutMs, method),
26398
+ request: (method, params) => withProbeTimeout(
26399
+ connection.request(method, params),
26400
+ input2.requestTimeoutMs,
26401
+ `ACP probe request '${method}'`
26402
+ ),
26377
26403
  close: () => connection.close()
26378
26404
  };
26379
26405
  } catch (error62) {
@@ -26381,6 +26407,57 @@ async function openAcpProbeHandshake(input2) {
26381
26407
  throw error62;
26382
26408
  }
26383
26409
  }
26410
+ var CLI_VERSION_PATTERN = /(?<![\d.])(\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?)/;
26411
+ function parseCliVersion(output2) {
26412
+ return CLI_VERSION_PATTERN.exec(output2)?.[1] ?? null;
26413
+ }
26414
+ async function collectCappedText(stream, maxBytes) {
26415
+ const decoder = new TextDecoder();
26416
+ let text = "";
26417
+ let total = 0;
26418
+ for await (const chunk of stream) {
26419
+ total += chunk.byteLength;
26420
+ if (total <= maxBytes) text += decoder.decode(chunk, { stream: true });
26421
+ }
26422
+ return { text: text + decoder.decode(), overflowed: total > maxBytes };
26423
+ }
26424
+ async function collectProbeProcess(child, input2) {
26425
+ try {
26426
+ await child.closeStdin().catch(() => void 0);
26427
+ const [stdout, stderr, exitCode] = await withProbeTimeout(
26428
+ Promise.all([
26429
+ collectCappedText(child.stdout, input2.maxOutputBytes),
26430
+ collectCappedText(child.stderr, input2.maxOutputBytes),
26431
+ child.exited
26432
+ ]),
26433
+ input2.timeoutMs,
26434
+ input2.what
26435
+ );
26436
+ return { stdout: stdout.overflowed ? void 0 : stdout.text, stderr: stderr.text, exitCode };
26437
+ } finally {
26438
+ await child.kill("SIGTERM").catch(() => void 0);
26439
+ }
26440
+ }
26441
+ var MAX_VERSION_OUTPUT_BYTES = 64 * 1024;
26442
+ async function probeCliVersion(input2) {
26443
+ let child;
26444
+ try {
26445
+ child = await input2.spawn();
26446
+ } catch {
26447
+ return null;
26448
+ }
26449
+ try {
26450
+ const run = await collectProbeProcess(child, {
26451
+ timeoutMs: input2.timeoutMs,
26452
+ maxOutputBytes: MAX_VERSION_OUTPUT_BYTES,
26453
+ what: "--version"
26454
+ });
26455
+ if (run.exitCode !== 0) return null;
26456
+ return parseCliVersion(run.stdout ?? "") ?? parseCliVersion(run.stderr);
26457
+ } catch {
26458
+ return null;
26459
+ }
26460
+ }
26384
26461
 
26385
26462
  // src/config.ts
26386
26463
  var DSH_DEFAULT_LAUNCH_ARGS = "--profile acp";
@@ -26482,6 +26559,9 @@ function tokenizeLaunchArgs(value) {
26482
26559
  import * as NodeFS from "node:fs";
26483
26560
  import * as NodeOS2 from "node:os";
26484
26561
  import * as NodePath2 from "node:path";
26562
+ import {
26563
+ ExecutorSpawnRefusedError
26564
+ } from "@ycodium-ai/plugin-api/executor";
26485
26565
  import { nodeStreamsFromHandle } from "@ycodium-ai/plugin-api/process-stdin";
26486
26566
 
26487
26567
  // src/spawnEnv.ts
@@ -26639,6 +26719,7 @@ async function probeDshModels(input2) {
26639
26719
  ...Object.keys(env).length > 0 ? { env } : {}
26640
26720
  });
26641
26721
  } catch (error62) {
26722
+ if (error62 instanceof ExecutorSpawnRefusedError) throw error62;
26642
26723
  return { kind: "not-started", detail: failureDetail(error62) };
26643
26724
  }
26644
26725
  let handshake;
@@ -26661,6 +26742,19 @@ async function probeDshModels(input2) {
26661
26742
  await handle.kill("SIGTERM").catch(() => void 0);
26662
26743
  }
26663
26744
  }
26745
+ async function probeDshVersion(input2) {
26746
+ const { recipe, host } = input2;
26747
+ const env = buildSpawnEnv(recipe, resolveHomePath(recipe.homePath));
26748
+ return probeCliVersion({
26749
+ spawn: () => host.process.spawn({
26750
+ program: recipe.binaryPath,
26751
+ args: ["--version"],
26752
+ owner: { bindingId: host.bindingId },
26753
+ ...Object.keys(env).length > 0 ? { env } : {}
26754
+ }),
26755
+ timeoutMs: PROBE_REQUEST_TIMEOUT_MS
26756
+ });
26757
+ }
26664
26758
 
26665
26759
  // src/dshInstance.ts
26666
26760
  var RESUME_SCHEMA_VERSION = 1;
@@ -26735,11 +26829,14 @@ var createDshInstance = (config2, host) => {
26735
26829
  detail: "DeepSeek Harness program path is not configured"
26736
26830
  };
26737
26831
  }
26738
- const outcome = await probeDshModels({ recipe, host });
26832
+ const [outcome, version2] = await Promise.all([
26833
+ probeDshModels({ recipe, host }),
26834
+ probeDshVersion({ recipe, host })
26835
+ ]);
26739
26836
  if (outcome.kind !== "answered") {
26740
26837
  return {
26741
26838
  installed: outcome.kind === "failed",
26742
- version: null,
26839
+ version: version2,
26743
26840
  readiness: "error",
26744
26841
  auth: { status: "unknown" },
26745
26842
  ...outcome.detail === void 0 ? {} : { detail: outcome.detail },
@@ -26749,7 +26846,7 @@ var createDshInstance = (config2, host) => {
26749
26846
  }
26750
26847
  return {
26751
26848
  installed: true,
26752
- version: null,
26849
+ version: version2,
26753
26850
  readiness: "ready",
26754
26851
  auth: { status: "unknown" },
26755
26852
  ...outcome.models === void 0 ? {} : { models: outcome.models },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-dsh",
3
- "version": "0.2.2130",
3
+ "version": "0.2.2167",
4
4
  "description": "DeepSeek Harness executor: dsh CLI over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -20,9 +20,10 @@
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.2130",
23
+ "@ycodium-ai/plugin-api": "0.2.2167",
24
24
  "ycodium-acp-executor": "0.0.0",
25
- "ycodium-acp-protocol": "0.0.0"
25
+ "ycodium-acp-protocol": "0.0.0",
26
+ "ycodium-executor-testing": "0.0.0"
26
27
  },
27
28
  "ycodium": {
28
29
  "plugin": "./dist/index.js",