@adecore/agents 0.23.1 → 0.24.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/README.md +3 -3
- package/dist/chat/attachment-store.js +4 -5
- package/dist/chat/backend.d.ts +6 -1
- package/dist/chat/background-work.d.ts +1 -1
- package/dist/chat/background-work.js +2 -1
- package/dist/chat/chat-core.d.ts +53 -161
- package/dist/chat/chat-core.js +146 -112
- package/dist/chat/chat-log.js +3 -3
- package/dist/chat/chat-process.d.ts +21 -0
- package/dist/chat/chat-process.js +109 -9
- package/dist/chat/chat-session.d.ts +10 -17
- package/dist/chat/chat-session.js +141 -182
- package/dist/chat/chat-store.d.ts +1 -0
- package/dist/chat/chat-store.js +105 -1
- package/dist/chat/claude-backend.d.ts +4 -0
- package/dist/chat/claude-backend.js +51 -27
- package/dist/chat/claude-protocol.d.ts +12 -0
- package/dist/chat/claude-protocol.js +137 -7
- package/dist/chat/claude-title.d.ts +1 -3
- package/dist/chat/claude-title.js +11 -39
- package/dist/chat/claude-transcript.d.ts +1 -0
- package/dist/chat/claude-transcript.js +36 -17
- package/dist/chat/codex-backend.d.ts +21 -1
- package/dist/chat/codex-backend.js +168 -10
- package/dist/chat/codex-protocol.d.ts +2 -0
- package/dist/chat/codex-protocol.js +37 -3
- package/dist/chat/codex-thread.js +1 -3
- package/dist/chat/codex-transport.d.ts +3 -0
- package/dist/chat/codex-transport.js +38 -35
- package/dist/chat/context-breakdown.js +2 -2
- package/dist/chat/errors.d.ts +1 -1
- package/dist/chat/external-sessions.js +2 -2
- package/dist/chat/fixtures/claude-2.1.296-goal.json +136 -0
- package/dist/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10.jsonl +2 -0
- package/dist/chat/index.d.ts +29 -0
- package/dist/chat/index.js +23 -0
- package/dist/chat/projector.d.ts +2 -1
- package/dist/chat/projector.js +12 -3
- package/dist/chat/request-summary.js +1 -4
- package/dist/chat/subagent-settlement.js +1 -3
- package/dist/chat/thread.d.ts +3 -0
- package/dist/chat/thread.js +20 -3
- package/dist/chat/ui-queries.d.ts +2 -0
- package/dist/chat/ui-queries.js +40 -5
- package/dist/chat/ui-replies.d.ts +33 -0
- package/dist/chat/ui-replies.js +152 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +3 -0
- package/dist/coordination/index.d.ts +15 -0
- package/dist/coordination/index.js +16 -0
- package/dist/host/handlers.js +8 -0
- package/dist/host/index.d.ts +7 -0
- package/dist/host/index.js +7 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +10 -0
- package/dist/providers/accounts/status.js +1 -3
- package/dist/providers/claude.js +3 -1
- package/dist/providers/codex.js +3 -1
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.js +12 -0
- package/dist/run-process.js +54 -14
- package/dist/skills.d.ts +1 -0
- package/dist/skills.js +4 -0
- package/dist/tasks/task-coordinator.d.ts +4 -0
- package/dist/tasks/task-coordinator.js +16 -2
- package/dist/tasks/wiring.js +7 -1
- package/dist/{providers/accounts/test-accounts.d.ts → testing/accounts.d.ts} +2 -2
- package/dist/{providers/accounts/test-accounts.js → testing/accounts.js} +3 -3
- package/dist/testing/bin/fake-claude.d.ts +1 -0
- package/dist/testing/bin/fake-claude.js +6 -0
- package/dist/testing/bin/fake-codex.d.ts +1 -0
- package/dist/testing/bin/fake-codex.js +6 -0
- package/dist/{chat → testing}/fake-claude.d.ts +1 -1
- package/dist/{chat → testing}/fake-claude.js +0 -4
- package/dist/{chat → testing}/fake-cli.d.ts +1 -1
- package/dist/{chat → testing}/fake-codex.d.ts +1 -1
- package/dist/{chat → testing}/fake-codex.js +70 -8
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.js +7 -0
- package/dist/{outbox → testing}/manual-clock.d.ts +1 -1
- package/dist/{watch-test-helpers.d.ts → testing/watch.d.ts} +1 -1
- package/dist/usage/exchange.d.ts +5 -3
- package/dist/usage/exchange.js +25 -16
- package/dist/usage/index-file.d.ts +1 -0
- package/dist/usage/index-file.js +20 -2
- package/dist/usage/index.d.ts +9 -0
- package/dist/usage/index.js +6 -0
- package/dist/usage/limits/normalize.js +1 -3
- package/dist/usage/pricing.d.ts +5 -3
- package/dist/usage/pricing.js +28 -19
- package/dist/usage/scanner.js +39 -11
- package/dist/usage/usage-service.js +8 -3
- package/package.json +72 -11
- package/src/chat/attachment-store.ts +4 -6
- package/src/chat/backend.ts +8 -0
- package/src/chat/background-work.ts +2 -2
- package/src/chat/chat-core.ts +221 -143
- package/src/chat/chat-log.ts +3 -3
- package/src/chat/chat-process.ts +128 -8
- package/src/chat/chat-session.ts +153 -204
- package/src/chat/chat-store.ts +104 -1
- package/src/chat/claude-backend.ts +58 -26
- package/src/chat/claude-protocol.ts +147 -8
- package/src/chat/claude-title.ts +11 -39
- package/src/chat/claude-transcript.ts +38 -18
- package/src/chat/codex-backend.ts +182 -20
- package/src/chat/codex-protocol.ts +40 -5
- package/src/chat/codex-thread.ts +1 -4
- package/src/chat/codex-transport.ts +45 -35
- package/src/chat/context-breakdown.ts +2 -2
- package/src/chat/errors.ts +1 -0
- package/src/chat/external-sessions.ts +2 -2
- package/src/chat/fixtures/claude-2.1.296-goal.json +136 -0
- package/src/chat/fixtures/claude-projects/-work-demo/5f1c2a9e-0b7d-4c1e-9a53-3e2f8d6b7a10.jsonl +2 -0
- package/src/chat/index.ts +49 -0
- package/src/chat/projector.ts +13 -4
- package/src/chat/request-summary.ts +8 -5
- package/src/chat/subagent-settlement.ts +1 -4
- package/src/chat/thread.ts +22 -3
- package/src/chat/ui-queries.ts +46 -5
- package/src/chat/ui-replies.ts +187 -0
- package/src/context/index.ts +26 -0
- package/src/coordination/index.ts +67 -0
- package/src/host/handlers.ts +8 -0
- package/src/host/index.ts +8 -0
- package/src/index.ts +20 -0
- package/src/providers/accounts/status.ts +1 -4
- package/src/providers/claude.ts +3 -1
- package/src/providers/codex.ts +3 -1
- package/src/providers/index.ts +15 -0
- package/src/run-process.ts +56 -16
- package/src/skills.ts +5 -0
- package/src/tasks/task-coordinator.ts +22 -2
- package/src/tasks/wiring.ts +7 -1
- package/src/{providers/accounts/test-accounts.ts → testing/accounts.ts} +4 -4
- package/src/testing/bin/fake-claude.ts +7 -0
- package/src/testing/bin/fake-codex.ts +7 -0
- package/src/{chat → testing}/fake-claude.ts +1 -5
- package/src/{chat → testing}/fake-cli.ts +1 -1
- package/src/{chat → testing}/fake-codex.ts +75 -6
- package/src/testing/index.ts +7 -0
- package/src/{outbox → testing}/manual-clock.ts +1 -1
- package/src/{watch-test-helpers.ts → testing/watch.ts} +1 -1
- package/src/usage/exchange.ts +31 -20
- package/src/usage/index-file.ts +23 -2
- package/src/usage/index.ts +10 -0
- package/src/usage/limits/normalize.ts +1 -4
- package/src/usage/pricing.ts +34 -23
- package/src/usage/scanner.ts +48 -11
- package/src/usage/usage-service.ts +8 -3
- /package/dist/{chat → testing}/fake-cli.js +0 -0
- /package/dist/{outbox → testing}/manual-clock.js +0 -0
- /package/dist/{watch-test-helpers.js → testing/watch.js} +0 -0
package/src/chat/chat-log.ts
CHANGED
|
@@ -66,7 +66,7 @@ export class ChatLog {
|
|
|
66
66
|
constructor(path: string | null, state: ChatLogState = { seq: 0, resetSeq: 0, lines: [] }) {
|
|
67
67
|
this.path = path;
|
|
68
68
|
this.lines = state.lines;
|
|
69
|
-
this.bytes = state.lines.reduce((sum, line) => sum + JSON.stringify(line)
|
|
69
|
+
this.bytes = state.lines.reduce((sum, line) => sum + Buffer.byteLength(JSON.stringify(line)) + 1, 0);
|
|
70
70
|
this.seqValue = Math.max(state.seq, state.lines.at(-1)?.seq ?? 0);
|
|
71
71
|
this.resetSeqValue = state.resetSeq;
|
|
72
72
|
const first = state.lines[0];
|
|
@@ -107,7 +107,7 @@ export class ChatLog {
|
|
|
107
107
|
}
|
|
108
108
|
const text = `${JSON.stringify(line)}\n`;
|
|
109
109
|
this.lines.push(line);
|
|
110
|
-
this.bytes += text
|
|
110
|
+
this.bytes += Buffer.byteLength(text);
|
|
111
111
|
if (this.path !== null) {
|
|
112
112
|
try {
|
|
113
113
|
this.fd ??= this.open(this.path);
|
|
@@ -146,7 +146,7 @@ export class ChatLog {
|
|
|
146
146
|
this.lines = this.lines.filter((line) => line.seq > seq);
|
|
147
147
|
this.base = seq;
|
|
148
148
|
const text = this.lines.map((line) => `${JSON.stringify(line)}\n`).join('');
|
|
149
|
-
this.bytes = text
|
|
149
|
+
this.bytes = Buffer.byteLength(text);
|
|
150
150
|
if (this.path === null) {
|
|
151
151
|
return;
|
|
152
152
|
}
|
package/src/chat/chat-process.ts
CHANGED
|
@@ -42,7 +42,9 @@ export function spawnChatProcess(options: ChatSpawnOptions): ChatProcess {
|
|
|
42
42
|
env: options.env,
|
|
43
43
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
44
44
|
// A group of its own, so ending the chat also ends what its agent started (a dev server, a watcher).
|
|
45
|
-
|
|
45
|
+
// On Windows that would open a console window of its own instead; `taskkill` reaches the tree there.
|
|
46
|
+
detached: process.platform !== 'win32',
|
|
47
|
+
windowsHide: true
|
|
46
48
|
});
|
|
47
49
|
// Node reports a missing executable as an event after the call; a start that failed says so on the spot.
|
|
48
50
|
child.on('error', () => undefined);
|
|
@@ -74,16 +76,39 @@ export function spawnChatProcess(options: ChatSpawnOptions): ChatProcess {
|
|
|
74
76
|
},
|
|
75
77
|
stdout: Readable.toWeb(child.stdout) as unknown as ReadableStream<Uint8Array>,
|
|
76
78
|
stderr: Readable.toWeb(child.stderr) as unknown as ReadableStream<Uint8Array>,
|
|
77
|
-
kill: (signal) =>
|
|
78
|
-
try {
|
|
79
|
-
process.kill(-pid, signal);
|
|
80
|
-
} catch {
|
|
81
|
-
// Nothing of the group is left to signal.
|
|
82
|
-
}
|
|
83
|
-
}
|
|
79
|
+
kill: (signal) => killProcessTree(pid, signal)
|
|
84
80
|
};
|
|
85
81
|
}
|
|
86
82
|
|
|
83
|
+
export interface ProcessTreeKillOptions {
|
|
84
|
+
platform?: NodeJS.Platform;
|
|
85
|
+
kill?(pid: number, signal: NodeJS.Signals): void;
|
|
86
|
+
run?(command: string[]): void;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Signals a process and everything it started. Windows has no process groups and no SIGTERM, so there the tree is ended at once. */
|
|
90
|
+
export function killProcessTree(pid: number, signal: 'SIGTERM' | 'SIGKILL', options: ProcessTreeKillOptions = {}): void {
|
|
91
|
+
const { platform = process.platform, kill = process.kill, run = runQuietly } = options;
|
|
92
|
+
if (platform === 'win32') {
|
|
93
|
+
run(['taskkill', '/pid', String(pid), '/t', '/f']);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
kill(-pid, signal);
|
|
98
|
+
} catch {
|
|
99
|
+
// Nothing of the group is left to signal.
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function runQuietly([command, ...args]: string[]): void {
|
|
104
|
+
if (command === undefined) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const child = spawn(command, args, { stdio: 'ignore', windowsHide: true });
|
|
108
|
+
// A tree that already ended makes taskkill fail, which is what the caller wanted anyway.
|
|
109
|
+
child.on('error', () => undefined);
|
|
110
|
+
}
|
|
111
|
+
|
|
87
112
|
// After stdin closed, a CLI that is still around is not going to say more.
|
|
88
113
|
const EXIT_GRACE_MS = 3000;
|
|
89
114
|
// What a CLI and everything it started get between the SIGTERM and the SIGKILL.
|
|
@@ -133,6 +158,101 @@ export class StreamTail {
|
|
|
133
158
|
}
|
|
134
159
|
}
|
|
135
160
|
|
|
161
|
+
// Far above any frame either CLI writes, a base64 document in a tool result included; it only bounds a CLI that stopped breaking lines.
|
|
162
|
+
export const MAX_LINE_LENGTH = 64_000_000;
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* Cuts decoded output into lines. A chunk is searched only for itself and a partial line is joined
|
|
166
|
+
* once, when its line break comes, so a long line costs its length once. A line longer than `max`
|
|
167
|
+
* UTF-16 units is dropped whole, with `onOverflow` called once for it, and the next line reads as usual.
|
|
168
|
+
*/
|
|
169
|
+
export class LineSplitter {
|
|
170
|
+
private readonly onLine: (line: string) => void;
|
|
171
|
+
private readonly onOverflow: () => void;
|
|
172
|
+
private readonly max: number;
|
|
173
|
+
private parts: string[] = [];
|
|
174
|
+
private length = 0;
|
|
175
|
+
private dropping = false;
|
|
176
|
+
|
|
177
|
+
constructor(onLine: (line: string) => void, onOverflow: () => void, max = MAX_LINE_LENGTH) {
|
|
178
|
+
this.onLine = onLine;
|
|
179
|
+
this.onOverflow = onOverflow;
|
|
180
|
+
this.max = max;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
push(text: string): void {
|
|
184
|
+
let start = 0;
|
|
185
|
+
let newline = text.indexOf('\n');
|
|
186
|
+
while (newline >= 0) {
|
|
187
|
+
this.add(text.slice(start, newline));
|
|
188
|
+
const line = this.take();
|
|
189
|
+
if (line !== null) {
|
|
190
|
+
this.onLine(line);
|
|
191
|
+
}
|
|
192
|
+
start = newline + 1;
|
|
193
|
+
newline = text.indexOf('\n', start);
|
|
194
|
+
}
|
|
195
|
+
this.add(text.slice(start));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Hands on what came after the last line break, for a stream that ended without one. */
|
|
199
|
+
end(): void {
|
|
200
|
+
const line = this.take();
|
|
201
|
+
if (line !== null && line !== '') {
|
|
202
|
+
this.onLine(line);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private add(piece: string): void {
|
|
207
|
+
if (this.dropping || piece === '') {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
this.length += piece.length;
|
|
211
|
+
if (this.length > this.max) {
|
|
212
|
+
this.parts = [];
|
|
213
|
+
this.dropping = true;
|
|
214
|
+
this.onOverflow();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
this.parts.push(piece);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private take(): string | null {
|
|
221
|
+
const line = this.dropping ? null : this.parts.join('');
|
|
222
|
+
this.parts = [];
|
|
223
|
+
this.length = 0;
|
|
224
|
+
this.dropping = false;
|
|
225
|
+
return line;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
* Hands every line of a CLI's output to `onLine` until the stream ends, through a `LineSplitter`.
|
|
231
|
+
* A read that fails rejects, after every line that came before it was handed on.
|
|
232
|
+
*/
|
|
233
|
+
export async function readStreamLines(
|
|
234
|
+
stream: ReadableStream<Uint8Array>,
|
|
235
|
+
onLine: (line: string) => void,
|
|
236
|
+
onOverflow: () => void,
|
|
237
|
+
max = MAX_LINE_LENGTH
|
|
238
|
+
): Promise<void> {
|
|
239
|
+
const reader = stream.getReader();
|
|
240
|
+
const decoder = new TextDecoder();
|
|
241
|
+
const lines = new LineSplitter(onLine, onOverflow, max);
|
|
242
|
+
try {
|
|
243
|
+
while (true) {
|
|
244
|
+
const { value, done } = await reader.read();
|
|
245
|
+
if (done) {
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
lines.push(decoder.decode(value, { stream: true }));
|
|
249
|
+
}
|
|
250
|
+
lines.end();
|
|
251
|
+
} finally {
|
|
252
|
+
reader.releaseLock();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
136
256
|
export interface ChatChildOptions extends Omit<ChatSpawnOptions, 'onExit'> {
|
|
137
257
|
spawn?: SpawnChatProcess;
|
|
138
258
|
// `stderr` is the tail of what the CLI wrote there, for an exit with an error code only.
|