ada-agent 0.6.0 → 0.6.1
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/package.json +1 -1
- package/src/client/autostart.ts +16 -7
- package/src/client/tools.ts +16 -9
package/package.json
CHANGED
package/src/client/autostart.ts
CHANGED
|
@@ -30,13 +30,22 @@ export function healthUrl(backendUrl: string): string {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
// Plain node:http with agent:false, NOT fetch: undici's keep-alive socket from a probe lingers into
|
|
34
|
+
// process teardown and deterministically prints "Assertion failed: !(handle->flags &
|
|
35
|
+
// UV_HANDLE_CLOSING)" on Windows at exit. agent:false closes the socket with the response.
|
|
36
|
+
function probe(url: string, timeoutMs = 800): Promise<boolean> {
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
import("node:http")
|
|
39
|
+
.then((http) => {
|
|
40
|
+
const req = http.get(url, { agent: false, timeout: timeoutMs }, (res) => {
|
|
41
|
+
res.resume(); // drain so the socket can close
|
|
42
|
+
resolve((res.statusCode ?? 500) < 400);
|
|
43
|
+
});
|
|
44
|
+
req.on("timeout", () => req.destroy());
|
|
45
|
+
req.on("error", () => resolve(false));
|
|
46
|
+
})
|
|
47
|
+
.catch(() => resolve(false));
|
|
48
|
+
});
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
/** Resolved path to bin/ada-server.mjs (sibling of bin/ada.mjs, packaged in the npm tarball). */
|
package/src/client/tools.ts
CHANGED
|
@@ -99,14 +99,21 @@ export function formatFile(abs: string): boolean {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
// node-pty gives the bash tool a real terminal. It's a required dependency; if the native build is
|
|
102
|
-
// ever broken on a platform, fall back to spawnSync so bash still works.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
// ever broken on a platform, fall back to spawnSync so bash still works. Loaded LAZILY on the first
|
|
103
|
+
// bash call: merely loading the native module on Windows sets up async handles whose teardown races
|
|
104
|
+
// process.exit and prints "Assertion failed: !(handle->flags & UV_HANDLE_CLOSING)" — commands that
|
|
105
|
+
// never spawn a PTY (--version, catalog, --list-models, …) shouldn't pay that.
|
|
106
|
+
let ptyMod: typeof PtyType | null | undefined;
|
|
107
|
+
function getPty(): typeof PtyType | null {
|
|
108
|
+
if (ptyMod === undefined) {
|
|
109
|
+
try {
|
|
110
|
+
ptyMod = createRequire(import.meta.url)("node-pty") as typeof PtyType;
|
|
111
|
+
} catch {
|
|
112
|
+
ptyMod = null;
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
|
-
|
|
115
|
+
return ptyMod;
|
|
116
|
+
}
|
|
110
117
|
|
|
111
118
|
// Built via new RegExp (string escapes) so no literal ESC/BEL bytes live in the source.
|
|
112
119
|
const ANSI = new RegExp("[\\u001B\\u009B][\\[\\]()#;?]*(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007|(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~])", "g");
|
|
@@ -120,7 +127,7 @@ function runPty(command: string, timeoutMs = 120_000): Promise<{ output: string;
|
|
|
120
127
|
const win = process.platform === "win32";
|
|
121
128
|
const shell = win ? process.env.COMSPEC ?? "cmd.exe" : process.env.SHELL ?? "/bin/bash";
|
|
122
129
|
const shellArgs = win ? ["/c", command] : ["-lc", command];
|
|
123
|
-
const p =
|
|
130
|
+
const p = getPty()!.spawn(shell, shellArgs, { name: "xterm-256color", cols: 120, rows: 30, cwd: process.cwd(), env: process.env as Record<string, string> });
|
|
124
131
|
let out = "";
|
|
125
132
|
const cap = 10 * 1024 * 1024;
|
|
126
133
|
p.onData((d) => {
|
|
@@ -360,7 +367,7 @@ export const tools: Tool[] = [
|
|
|
360
367
|
needsApproval: true,
|
|
361
368
|
async run(args) {
|
|
362
369
|
const command = String(args.command);
|
|
363
|
-
if (
|
|
370
|
+
if (getPty()) {
|
|
364
371
|
const { output, code } = await runPty(command);
|
|
365
372
|
return { output: `exit ${code ?? "null"}\n${spillIfHuge(stripAnsi(output).trim() || "(no output)")}`, isError: code !== 0 };
|
|
366
373
|
}
|