@ycodium-ai/agent-dsh 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.
- package/dist/index.js +111 -9
- package/package.json +2 -2
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
|
|
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,
|
|
26366
|
+
function withProbeTimeout(promise2, timeoutMs, what) {
|
|
26345
26367
|
return new Promise((resolve2, reject) => {
|
|
26346
26368
|
const timer = setTimeout(() => {
|
|
26347
|
-
reject(new Error(
|
|
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(
|
|
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
|
|
@@ -26540,6 +26620,10 @@ function resolveHomePath(value) {
|
|
|
26540
26620
|
if (trimmed.length === 0) return "";
|
|
26541
26621
|
return NodePath.resolve(expandHomePath(trimmed));
|
|
26542
26622
|
}
|
|
26623
|
+
function dshContinuationKey(homePath) {
|
|
26624
|
+
const resolved = resolveHomePath(homePath);
|
|
26625
|
+
return `dsh:home:${resolved.length > 0 ? resolved : NodePath.join(NodeOS.homedir(), ".dsh")}`;
|
|
26626
|
+
}
|
|
26543
26627
|
function buildSpawnEnv(recipe, resolvedHomePath, launchEnv = {}, nativeModeId) {
|
|
26544
26628
|
const homeEnvVar = recipe.homeEnvVar.trim() || DSH_CARD.homeEnvVar;
|
|
26545
26629
|
const homeInjection = resolvedHomePath.length > 0 && homeEnvVar.length > 0 ? { [homeEnvVar]: resolvedHomePath } : {};
|
|
@@ -26635,6 +26719,7 @@ async function probeDshModels(input2) {
|
|
|
26635
26719
|
...Object.keys(env).length > 0 ? { env } : {}
|
|
26636
26720
|
});
|
|
26637
26721
|
} catch (error62) {
|
|
26722
|
+
if (error62 instanceof ExecutorSpawnRefusedError) throw error62;
|
|
26638
26723
|
return { kind: "not-started", detail: failureDetail(error62) };
|
|
26639
26724
|
}
|
|
26640
26725
|
let handshake;
|
|
@@ -26657,6 +26742,19 @@ async function probeDshModels(input2) {
|
|
|
26657
26742
|
await handle.kill("SIGTERM").catch(() => void 0);
|
|
26658
26743
|
}
|
|
26659
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
|
+
}
|
|
26660
26758
|
|
|
26661
26759
|
// src/dshInstance.ts
|
|
26662
26760
|
var RESUME_SCHEMA_VERSION = 1;
|
|
@@ -26731,11 +26829,14 @@ var createDshInstance = (config2, host) => {
|
|
|
26731
26829
|
detail: "DeepSeek Harness program path is not configured"
|
|
26732
26830
|
};
|
|
26733
26831
|
}
|
|
26734
|
-
const outcome = await
|
|
26832
|
+
const [outcome, version2] = await Promise.all([
|
|
26833
|
+
probeDshModels({ recipe, host }),
|
|
26834
|
+
probeDshVersion({ recipe, host })
|
|
26835
|
+
]);
|
|
26735
26836
|
if (outcome.kind !== "answered") {
|
|
26736
26837
|
return {
|
|
26737
26838
|
installed: outcome.kind === "failed",
|
|
26738
|
-
version:
|
|
26839
|
+
version: version2,
|
|
26739
26840
|
readiness: "error",
|
|
26740
26841
|
auth: { status: "unknown" },
|
|
26741
26842
|
...outcome.detail === void 0 ? {} : { detail: outcome.detail },
|
|
@@ -26745,7 +26846,7 @@ var createDshInstance = (config2, host) => {
|
|
|
26745
26846
|
}
|
|
26746
26847
|
return {
|
|
26747
26848
|
installed: true,
|
|
26748
|
-
version:
|
|
26849
|
+
version: version2,
|
|
26749
26850
|
readiness: "ready",
|
|
26750
26851
|
auth: { status: "unknown" },
|
|
26751
26852
|
...outcome.models === void 0 ? {} : { models: outcome.models },
|
|
@@ -26919,6 +27020,7 @@ var createDshInstance = (config2, host) => {
|
|
|
26919
27020
|
return { threadId, turns: booked.turns };
|
|
26920
27021
|
},
|
|
26921
27022
|
events,
|
|
27023
|
+
continuationKey: dshContinuationKey(recipe.homePath),
|
|
26922
27024
|
dispose: async () => {
|
|
26923
27025
|
if (disposed) return;
|
|
26924
27026
|
disposed = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/agent-dsh",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2143",
|
|
4
4
|
"description": "DeepSeek Harness executor: dsh CLI over Agent Client Protocol stdio.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -20,8 +20,8 @@
|
|
|
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.2143",
|
|
23
24
|
"ycodium-acp-executor": "0.0.0",
|
|
24
|
-
"@ycodium-ai/plugin-api": "0.2.2126",
|
|
25
25
|
"ycodium-acp-protocol": "0.0.0"
|
|
26
26
|
},
|
|
27
27
|
"ycodium": {
|