dsh-agy-cli 0.12.3 → 0.12.4

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/README.md CHANGED
@@ -30,7 +30,7 @@
30
30
 
31
31
  - **双工具路线**:MCP 桥把 DSH 工具交给 AGY(真工具事件、过程流可视化,推荐),失败自动降级为 prompt 契约
32
32
  - **DSH 主导 harness**:工作区、审批、沙箱、上下文预算全在 DSH;AGY 只出模型
33
- - **流式 + 状态机**:`stdinMode: hold` 防回滚、思考链折叠、尾流交付、断连保文本
33
+ - **流式 + 状态机**:`stdinMode: hold` 防回滚、工具步骤折叠显示(只列执行了哪些工具,不显示模型的内部思考内容)、尾流交付、断连保文本
34
34
  - **会话管理 + 历史指纹链**:resume / full 双模式,每轮成功后记录 DSH 历史指纹;resume 前本地比对前缀,检出历史被编辑/压缩/截断即废弃旧会话并从完整历史重建,delta prompt 不会落在过期上下文上;死亡会话自动重放,会话映射落盘可迁移
35
35
  - **图片输入**(experimental):附件经图片桥落盘,由最小权限的 view_file Agent 查看
36
36
  - **配额面板与凭据保活**:loopback-only;面板显示真实双窗口配额,令牌临近过期时自动拉起官方 CLI 续期
Binary file
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'node:child_process';
2
+ import { buildWindowsNoConsoleLaunch } from './windows-launcher.js';
2
3
  import { randomUUID } from 'node:crypto';
3
4
  export class PersistentTransportError extends Error {
4
5
  code;
@@ -200,8 +201,9 @@ class PersistentAgyWorker {
200
201
  await this.stop('reset');
201
202
  throw new PersistentTransportError('Persistent AGY request aborted before write', 'ABORTED');
202
203
  }
203
- const timeoutMs = input.timeoutMs ?? this.options.defaultRequestTimeoutMs;
204
- validateInteger('timeoutMs', timeoutMs, 1, 3_600_000);
204
+ const timeoutMs = input.timeoutMs !== undefined
205
+ ? validateInteger('timeoutMs', input.timeoutMs, 1, 3_600_000)
206
+ : undefined;
205
207
  const maxOutputBytes = Math.min(input.maxOutputBytes ?? this.options.maxOutputBytes, this.options.maxOutputBytes);
206
208
  validateInteger('maxOutputBytes', maxOutputBytes, 1, this.options.maxOutputBytes);
207
209
  this.clearIdleTimer();
@@ -225,7 +227,9 @@ class PersistentAgyWorker {
225
227
  this.active = active;
226
228
  active.abortListener = () => this.failActiveAndReset(new PersistentTransportError('Persistent AGY request aborted', 'ABORTED'));
227
229
  input.signal?.addEventListener('abort', active.abortListener, { once: true });
228
- active.timer = setTimeout(() => this.failActiveAndReset(new PersistentTransportError('Persistent AGY request exceeded its timeout', 'TIMEOUT')), timeoutMs);
230
+ if (timeoutMs !== undefined) {
231
+ active.timer = setTimeout(() => this.failActiveAndReset(new PersistentTransportError('Persistent AGY request exceeded its timeout', 'TIMEOUT')), timeoutMs);
232
+ }
229
233
  void this.sendRequest(active, input.payload);
230
234
  });
231
235
  }
@@ -279,7 +283,11 @@ class PersistentAgyWorker {
279
283
  this.readyReject = reject;
280
284
  });
281
285
  try {
282
- const child = spawn(this.options.executable, [...this.options.args], {
286
+ const args = [...this.options.args];
287
+ const launch = process.platform === 'win32'
288
+ ? buildWindowsNoConsoleLaunch(this.options.executable, args)
289
+ : { executable: this.options.executable, args };
290
+ const child = spawn(launch.executable, [...launch.args], {
283
291
  cwd: this.options.cwd,
284
292
  env: {
285
293
  ...process.env,
@@ -56,46 +56,46 @@ export const AGY_KEYRING_TARGET = 'gemini:antigravity';
56
56
  * 2026-10-22. Duplicated rather than imported so the keep-alive path has no
57
57
  * dependency on the HTTP layer.
58
58
  */
59
- const WIN_CRED_SCRIPT = `
60
- param($target)
61
- $sig = @'
62
- using System;
63
- using System.Runtime.InteropServices;
64
- public class WinCredKeepalive {
65
- [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
66
- public static extern bool CredRead(string target, int type, int flags, out IntPtr credential);
67
- [DllImport("advapi32.dll", SetLastError=true)]
68
- public static extern void CredFree(IntPtr cred);
69
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
70
- public struct CREDENTIAL {
71
- public int Flags;
72
- public int Type;
73
- public string TargetName;
74
- public string Comment;
75
- public long LastWritten;
76
- public int CredentialBlobSize;
77
- public IntPtr CredentialBlob;
78
- public int Persist;
79
- public int AttributeCount;
80
- public IntPtr Attributes;
81
- public string TargetAlias;
82
- public string UserName;
83
- }
84
- public static string Read(string target) {
85
- IntPtr ptr;
86
- if (CredRead(target, 1, 0, out ptr)) {
87
- CREDENTIAL c = (CREDENTIAL)Marshal.PtrToStructure(ptr, typeof(CREDENTIAL));
88
- byte[] b = new byte[c.CredentialBlobSize];
89
- Marshal.Copy(c.CredentialBlob, b, 0, c.CredentialBlobSize);
90
- CredFree(ptr);
91
- return System.Convert.ToBase64String(b);
92
- }
93
- return null;
94
- }
95
- }
96
- '@
97
- Add-Type -TypeDefinition $sig -ErrorAction SilentlyContinue
98
- [Console]::Out.Write([WinCredKeepalive]::Read($target))
59
+ const WIN_CRED_SCRIPT = `
60
+ param($target)
61
+ $sig = @'
62
+ using System;
63
+ using System.Runtime.InteropServices;
64
+ public class WinCredKeepalive {
65
+ [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
66
+ public static extern bool CredRead(string target, int type, int flags, out IntPtr credential);
67
+ [DllImport("advapi32.dll", SetLastError=true)]
68
+ public static extern void CredFree(IntPtr cred);
69
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
70
+ public struct CREDENTIAL {
71
+ public int Flags;
72
+ public int Type;
73
+ public string TargetName;
74
+ public string Comment;
75
+ public long LastWritten;
76
+ public int CredentialBlobSize;
77
+ public IntPtr CredentialBlob;
78
+ public int Persist;
79
+ public int AttributeCount;
80
+ public IntPtr Attributes;
81
+ public string TargetAlias;
82
+ public string UserName;
83
+ }
84
+ public static string Read(string target) {
85
+ IntPtr ptr;
86
+ if (CredRead(target, 1, 0, out ptr)) {
87
+ CREDENTIAL c = (CREDENTIAL)Marshal.PtrToStructure(ptr, typeof(CREDENTIAL));
88
+ byte[] b = new byte[c.CredentialBlobSize];
89
+ Marshal.Copy(c.CredentialBlob, b, 0, c.CredentialBlobSize);
90
+ CredFree(ptr);
91
+ return System.Convert.ToBase64String(b);
92
+ }
93
+ return null;
94
+ }
95
+ }
96
+ '@
97
+ Add-Type -TypeDefinition $sig -ErrorAction SilentlyContinue
98
+ [Console]::Out.Write([WinCredKeepalive]::Read($target))
99
99
  `;
100
100
  /** macOS/Linux read path: untouched, never part of the Windows hot path. */
101
101
  function readKeyringTokenStateSyncImpl() {
@@ -401,6 +401,7 @@ export async function startAgyKeepaliveRun(input) {
401
401
  executable: input.executable,
402
402
  args: buildKeepaliveArgs(input.model),
403
403
  stdinMode: 'close',
404
+ windowsNoConsole: true,
404
405
  ...(home === undefined ? {} : { cwd: home }),
405
406
  timeoutMs: input.timeoutMs ?? 45_000,
406
407
  });
@@ -276,10 +276,12 @@ class PersistentAgyWorker {
276
276
  await this.stop('reset');
277
277
  throw new PersistentTransportError('Persistent AGY request aborted before write', 'ABORTED');
278
278
  }
279
- const timeoutMs = input.timeoutMs ?? this.options.defaultRequestTimeoutMs;
280
- validateInteger('timeoutMs', timeoutMs, 1, 3_600_000);
281
- const idleTimeoutMs = input.idleTimeoutMs ?? timeoutMs;
282
- validateInteger('idleTimeoutMs', idleTimeoutMs, 1, 3_600_000);
279
+ const timeoutMs = input.timeoutMs !== undefined
280
+ ? validateInteger('timeoutMs', input.timeoutMs, 1, 3_600_000)
281
+ : undefined;
282
+ const idleTimeoutMs = input.idleTimeoutMs !== undefined
283
+ ? validateInteger('idleTimeoutMs', input.idleTimeoutMs, 1, 3_600_000)
284
+ : this.options.defaultRequestTimeoutMs;
283
285
  const maxOutputBytes = Math.min(input.maxOutputBytes ?? this.options.maxOutputBytes, this.options.maxOutputBytes);
284
286
  validateInteger('maxOutputBytes', maxOutputBytes, 1, this.options.maxOutputBytes);
285
287
  this.clearIdleTimer();
@@ -305,10 +307,12 @@ class PersistentAgyWorker {
305
307
  this.active = active;
306
308
  active.abortListener = () => this.failActiveAndReset(new PersistentTransportError('Persistent AGY request aborted', 'ABORTED'));
307
309
  input.signal?.addEventListener('abort', active.abortListener, { once: true });
308
- // Two independent clocks: the wall clock is a hard ceiling, the idle clock
309
- // is re-armed by every frame so a long thinking or tool pause is not a kill.
310
- const wallClock = setTimeout(() => this.failActiveAndReset(new PersistentTransportError('Persistent AGY request exceeded its wall-clock timeout', 'TIMEOUT')), timeoutMs);
311
- active.timer = wallClock;
310
+ // Idle watchdog is re-armed by every frame so a long thinking or tool pause is not a kill.
311
+ // Wall clock is an optional ceiling only armed when an explicit timeoutMs is requested.
312
+ if (timeoutMs !== undefined) {
313
+ const wallClock = setTimeout(() => this.failActiveAndReset(new PersistentTransportError('Persistent AGY request exceeded its wall-clock timeout', 'TIMEOUT')), timeoutMs);
314
+ active.timer = wallClock;
315
+ }
312
316
  this.touchActive(active);
313
317
  void this.sendRequest(active, input.text);
314
318
  });
@@ -914,7 +914,7 @@ export class AgyAdapter extends LlmAdapter {
914
914
  const envTimeout = process.env.DSH_AGY_TIMEOUT_MS ? Number(process.env.DSH_AGY_TIMEOUT_MS) : undefined;
915
915
  this.timeoutMs = envTimeout !== undefined && Number.isFinite(envTimeout) && envTimeout > 0
916
916
  ? envTimeout
917
- : (config.timeoutMs ?? 600_000);
917
+ : undefined;
918
918
  const envIdleTimeout = process.env.DSH_AGY_IDLE_TIMEOUT_MS ? Number(process.env.DSH_AGY_IDLE_TIMEOUT_MS) : undefined;
919
919
  this.idleTimeoutMs = envIdleTimeout !== undefined && Number.isFinite(envIdleTimeout) && envIdleTimeout > 0
920
920
  ? envIdleTimeout
@@ -1048,7 +1048,7 @@ export class AgyAdapter extends LlmAdapter {
1048
1048
  ...(this.agyPath === undefined ? {} : { executable: this.agyPath }),
1049
1049
  expectedAgent: this.agent,
1050
1050
  minimumVersion: this.minimumAgyVersion,
1051
- timeoutMs: Math.min(this.timeoutMs, 10_000),
1051
+ timeoutMs: Math.min(this.timeoutMs ?? 10_000, 10_000),
1052
1052
  });
1053
1053
  }
1054
1054
  providerInfo(provider) {
@@ -1168,7 +1168,7 @@ export class AgyAdapter extends LlmAdapter {
1168
1168
  ...(persistentExtraArgsOf(this.mode).length === 0
1169
1169
  ? {}
1170
1170
  : { extraArgs: persistentExtraArgsOf(this.mode) }),
1171
- timeoutMs: this.timeoutMs,
1171
+ ...(this.timeoutMs === undefined ? {} : { timeoutMs: this.timeoutMs }),
1172
1172
  idleTimeoutMs: this.idleTimeoutMs,
1173
1173
  maxOutputBytes: this.maxOutputBytes,
1174
1174
  ...(options.signal === undefined ? {} : { signal: options.signal }),
@@ -1799,7 +1799,7 @@ export class AgyAdapter extends LlmAdapter {
1799
1799
  prompt,
1800
1800
  agent: imageRuntime?.agent ?? route.agent,
1801
1801
  model: route.model,
1802
- timeoutMs: this.timeoutMs,
1802
+ ...(this.timeoutMs === undefined ? {} : { timeoutMs: this.timeoutMs }),
1803
1803
  idleTimeoutMs: this.idleTimeoutMs,
1804
1804
  maxStdoutBytes: this.maxOutputBytes,
1805
1805
  maxStderrBytes: this.maxOutputBytes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-agy-cli",
3
- "version": "0.12.3",
3
+ "version": "0.12.4",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"