@adecore/agents 0.33.3 → 0.34.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.
|
@@ -13,7 +13,7 @@ export interface ChatSpawnOptions {
|
|
|
13
13
|
command: string[];
|
|
14
14
|
cwd: string;
|
|
15
15
|
env: Record<string, string>;
|
|
16
|
-
onExit(exitCode: number | null): void;
|
|
16
|
+
onExit(exitCode: number | null, signal?: string | null): void;
|
|
17
17
|
onError?(error: Error): void;
|
|
18
18
|
}
|
|
19
19
|
export type SpawnChatProcess = (options: ChatSpawnOptions) => ChatProcess;
|
|
@@ -48,7 +48,7 @@ export declare class LineSplitter {
|
|
|
48
48
|
export declare function readStreamLines(stream: ReadableStream<Uint8Array>, onLine: (line: string) => void, onOverflow: () => void, max?: number): Promise<void>;
|
|
49
49
|
export interface ChatChildOptions extends Omit<ChatSpawnOptions, 'onExit'> {
|
|
50
50
|
spawn?: SpawnChatProcess;
|
|
51
|
-
onExit(exitCode: number | null, stderr: string | null): void;
|
|
51
|
+
onExit(exitCode: number | null, stderr: string | null, signal?: string | null): void;
|
|
52
52
|
onError?(error: Error): void;
|
|
53
53
|
}
|
|
54
54
|
export declare class ChatChild {
|
|
@@ -26,12 +26,12 @@ export function spawnChatProcess(options) {
|
|
|
26
26
|
throw new Error(`Could not start ${command}: no such executable`);
|
|
27
27
|
}
|
|
28
28
|
child.stdin.on('error', (error) => options.onError?.(error));
|
|
29
|
-
child.on('exit', (exitCode) => {
|
|
29
|
+
child.on('exit', (exitCode, signal) => {
|
|
30
30
|
// The last lines may still be on their way through the pipe; they belong before the exit.
|
|
31
31
|
const report = () => {
|
|
32
32
|
clearTimeout(timer);
|
|
33
33
|
child.stdout.off('end', report);
|
|
34
|
-
setImmediate(() => options.onExit(exitCode));
|
|
34
|
+
setImmediate(() => options.onExit(exitCode, signal));
|
|
35
35
|
};
|
|
36
36
|
const timer = setTimeout(report, STDOUT_DRAIN_MS);
|
|
37
37
|
if (child.stdout.readableEnded) {
|
|
@@ -225,11 +225,11 @@ export class ChatChild {
|
|
|
225
225
|
cwd: options.cwd,
|
|
226
226
|
env: options.env,
|
|
227
227
|
...(options.onError ? { onError: options.onError } : {}),
|
|
228
|
-
onExit: (exitCode) => {
|
|
228
|
+
onExit: (exitCode, signal = null) => {
|
|
229
229
|
this.hasExited = true;
|
|
230
230
|
this.clearGrace();
|
|
231
231
|
settle();
|
|
232
|
-
void this.report(exitCode, options.onExit);
|
|
232
|
+
void this.report(exitCode, signal, options.onExit);
|
|
233
233
|
}
|
|
234
234
|
});
|
|
235
235
|
this.tail = this.process.stderr ? new StreamTail(this.process.stderr) : null;
|
|
@@ -274,9 +274,9 @@ export class ChatChild {
|
|
|
274
274
|
this.graceTimer = null;
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
|
-
async report(exitCode, onExit) {
|
|
277
|
+
async report(exitCode, signal, onExit) {
|
|
278
278
|
if (exitCode === null || exitCode === 0 || this.tail === null) {
|
|
279
|
-
onExit(exitCode, null);
|
|
279
|
+
onExit(exitCode, null, signal);
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
282
|
let release = () => undefined;
|
|
@@ -288,6 +288,6 @@ export class ChatChild {
|
|
|
288
288
|
})
|
|
289
289
|
]);
|
|
290
290
|
clearTimeout(timer);
|
|
291
|
-
onExit(exitCode, this.tail.lines());
|
|
291
|
+
onExit(exitCode, this.tail.lines(), signal);
|
|
292
292
|
}
|
|
293
293
|
}
|
package/dist/record-directory.js
CHANGED
|
@@ -82,7 +82,8 @@ export class RecordDirectory {
|
|
|
82
82
|
/*
|
|
83
83
|
* Holds the record in memory at once, so the next question in the same tick already sees it, and
|
|
84
84
|
* answers whether it is still the one this directory holds by the time the file is written. A
|
|
85
|
-
* record removed while its file was being written does not come back: the rename is undone
|
|
85
|
+
* record removed while its file was being written does not come back: the rename is undone, unless
|
|
86
|
+
* a newer record took the id meanwhile, whose own write is queued behind this one and replaces the file.
|
|
86
87
|
*/
|
|
87
88
|
write(record) {
|
|
88
89
|
const id = this.idOf(record);
|
|
@@ -93,11 +94,13 @@ export class RecordDirectory {
|
|
|
93
94
|
}
|
|
94
95
|
await mkdir(this.dir, { recursive: true, mode: 0o700 });
|
|
95
96
|
await this.writeFile(this.pathOf(id), JSON.stringify(record));
|
|
97
|
+
if (this.records.get(id) === record) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
96
100
|
if (!this.records.has(id)) {
|
|
97
101
|
await this.removeFile(this.pathOf(id));
|
|
98
|
-
return false;
|
|
99
102
|
}
|
|
100
|
-
return
|
|
103
|
+
return false;
|
|
101
104
|
});
|
|
102
105
|
}
|
|
103
106
|
/* Forgets a record here and now; its file follows, after what is queued for it. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adecore/agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.1",
|
|
4
4
|
"description": "Node-compatible agent chat hosts, providers, accounts, usage and durable task coordination.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"test": "bun --conditions=source test"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@adecore/agent-contracts": "0.
|
|
85
|
-
"@adecore/intelligent-ui": "0.
|
|
84
|
+
"@adecore/agent-contracts": "0.34.1",
|
|
85
|
+
"@adecore/intelligent-ui": "0.34.1",
|
|
86
86
|
"zod": "^4.6.5"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
package/src/chat/chat-process.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface ChatSpawnOptions {
|
|
|
24
24
|
command: string[];
|
|
25
25
|
cwd: string;
|
|
26
26
|
env: Record<string, string>;
|
|
27
|
-
onExit(exitCode: number | null): void;
|
|
27
|
+
onExit(exitCode: number | null, signal?: string | null): void;
|
|
28
28
|
onError?(error: Error): void;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -56,12 +56,12 @@ export function spawnChatProcess(options: ChatSpawnOptions): ChatProcess {
|
|
|
56
56
|
throw new Error(`Could not start ${command}: no such executable`);
|
|
57
57
|
}
|
|
58
58
|
child.stdin.on('error', (error) => options.onError?.(error));
|
|
59
|
-
child.on('exit', (exitCode) => {
|
|
59
|
+
child.on('exit', (exitCode, signal) => {
|
|
60
60
|
// The last lines may still be on their way through the pipe; they belong before the exit.
|
|
61
61
|
const report = (): void => {
|
|
62
62
|
clearTimeout(timer);
|
|
63
63
|
child.stdout.off('end', report);
|
|
64
|
-
setImmediate(() => options.onExit(exitCode));
|
|
64
|
+
setImmediate(() => options.onExit(exitCode, signal));
|
|
65
65
|
};
|
|
66
66
|
const timer = setTimeout(report, STDOUT_DRAIN_MS);
|
|
67
67
|
if (child.stdout.readableEnded) {
|
|
@@ -259,7 +259,7 @@ export async function readStreamLines(
|
|
|
259
259
|
export interface ChatChildOptions extends Omit<ChatSpawnOptions, 'onExit'> {
|
|
260
260
|
spawn?: SpawnChatProcess;
|
|
261
261
|
// `stderr` is the tail of what the CLI wrote there, for an exit with an error code only.
|
|
262
|
-
onExit(exitCode: number | null, stderr: string | null): void;
|
|
262
|
+
onExit(exitCode: number | null, stderr: string | null, signal?: string | null): void;
|
|
263
263
|
onError?(error: Error): void;
|
|
264
264
|
}
|
|
265
265
|
|
|
@@ -287,11 +287,11 @@ export class ChatChild {
|
|
|
287
287
|
cwd: options.cwd,
|
|
288
288
|
env: options.env,
|
|
289
289
|
...(options.onError ? { onError: options.onError } : {}),
|
|
290
|
-
onExit: (exitCode) => {
|
|
290
|
+
onExit: (exitCode, signal = null) => {
|
|
291
291
|
this.hasExited = true;
|
|
292
292
|
this.clearGrace();
|
|
293
293
|
settle();
|
|
294
|
-
void this.report(exitCode, options.onExit);
|
|
294
|
+
void this.report(exitCode, signal, options.onExit);
|
|
295
295
|
}
|
|
296
296
|
});
|
|
297
297
|
this.tail = this.process.stderr ? new StreamTail(this.process.stderr) : null;
|
|
@@ -341,9 +341,9 @@ export class ChatChild {
|
|
|
341
341
|
}
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
private async report(exitCode: number | null, onExit: ChatChildOptions['onExit']): Promise<void> {
|
|
344
|
+
private async report(exitCode: number | null, signal: string | null, onExit: ChatChildOptions['onExit']): Promise<void> {
|
|
345
345
|
if (exitCode === null || exitCode === 0 || this.tail === null) {
|
|
346
|
-
onExit(exitCode, null);
|
|
346
|
+
onExit(exitCode, null, signal);
|
|
347
347
|
return;
|
|
348
348
|
}
|
|
349
349
|
let release: () => void = () => undefined;
|
|
@@ -355,6 +355,6 @@ export class ChatChild {
|
|
|
355
355
|
})
|
|
356
356
|
]);
|
|
357
357
|
clearTimeout(timer);
|
|
358
|
-
onExit(exitCode, this.tail.lines());
|
|
358
|
+
onExit(exitCode, this.tail.lines(), signal);
|
|
359
359
|
}
|
|
360
360
|
}
|
package/src/record-directory.ts
CHANGED
|
@@ -103,7 +103,8 @@ export class RecordDirectory<T> {
|
|
|
103
103
|
/*
|
|
104
104
|
* Holds the record in memory at once, so the next question in the same tick already sees it, and
|
|
105
105
|
* answers whether it is still the one this directory holds by the time the file is written. A
|
|
106
|
-
* record removed while its file was being written does not come back: the rename is undone
|
|
106
|
+
* record removed while its file was being written does not come back: the rename is undone, unless
|
|
107
|
+
* a newer record took the id meanwhile, whose own write is queued behind this one and replaces the file.
|
|
107
108
|
*/
|
|
108
109
|
write(record: T): Promise<boolean> {
|
|
109
110
|
const id = this.idOf(record);
|
|
@@ -114,11 +115,13 @@ export class RecordDirectory<T> {
|
|
|
114
115
|
}
|
|
115
116
|
await mkdir(this.dir, { recursive: true, mode: 0o700 });
|
|
116
117
|
await this.writeFile(this.pathOf(id), JSON.stringify(record));
|
|
118
|
+
if (this.records.get(id) === record) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
117
121
|
if (!this.records.has(id)) {
|
|
118
122
|
await this.removeFile(this.pathOf(id));
|
|
119
|
-
return false;
|
|
120
123
|
}
|
|
121
|
-
return
|
|
124
|
+
return false;
|
|
122
125
|
});
|
|
123
126
|
}
|
|
124
127
|
|