@adecore/agents 0.23.1 → 0.24.0
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
|
@@ -12,7 +12,9 @@ export function spawnChatProcess(options) {
|
|
|
12
12
|
env: options.env,
|
|
13
13
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
14
14
|
// A group of its own, so ending the chat also ends what its agent started (a dev server, a watcher).
|
|
15
|
-
|
|
15
|
+
// On Windows that would open a console window of its own instead; `taskkill` reaches the tree there.
|
|
16
|
+
detached: process.platform !== 'win32',
|
|
17
|
+
windowsHide: true
|
|
16
18
|
});
|
|
17
19
|
// Node reports a missing executable as an event after the call; a start that failed says so on the spot.
|
|
18
20
|
child.on('error', () => undefined);
|
|
@@ -44,16 +46,31 @@ export function spawnChatProcess(options) {
|
|
|
44
46
|
},
|
|
45
47
|
stdout: Readable.toWeb(child.stdout),
|
|
46
48
|
stderr: Readable.toWeb(child.stderr),
|
|
47
|
-
kill: (signal) =>
|
|
48
|
-
try {
|
|
49
|
-
process.kill(-pid, signal);
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
// Nothing of the group is left to signal.
|
|
53
|
-
}
|
|
54
|
-
}
|
|
49
|
+
kill: (signal) => killProcessTree(pid, signal)
|
|
55
50
|
};
|
|
56
51
|
}
|
|
52
|
+
/* Signals a process and everything it started. Windows has no process groups and no SIGTERM, so there the tree is ended at once. */
|
|
53
|
+
export function killProcessTree(pid, signal, options = {}) {
|
|
54
|
+
const { platform = process.platform, kill = process.kill, run = runQuietly } = options;
|
|
55
|
+
if (platform === 'win32') {
|
|
56
|
+
run(['taskkill', '/pid', String(pid), '/t', '/f']);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
kill(-pid, signal);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Nothing of the group is left to signal.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function runQuietly([command, ...args]) {
|
|
67
|
+
if (command === undefined) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const child = spawn(command, args, { stdio: 'ignore', windowsHide: true });
|
|
71
|
+
// A tree that already ended makes taskkill fail, which is what the caller wanted anyway.
|
|
72
|
+
child.on('error', () => undefined);
|
|
73
|
+
}
|
|
57
74
|
// After stdin closed, a CLI that is still around is not going to say more.
|
|
58
75
|
const EXIT_GRACE_MS = 3000;
|
|
59
76
|
// What a CLI and everything it started get between the SIGTERM and the SIGKILL.
|
|
@@ -99,6 +116,89 @@ export class StreamTail {
|
|
|
99
116
|
}
|
|
100
117
|
}
|
|
101
118
|
}
|
|
119
|
+
// Far above any frame either CLI writes, a base64 document in a tool result included; it only bounds a CLI that stopped breaking lines.
|
|
120
|
+
export const MAX_LINE_LENGTH = 64_000_000;
|
|
121
|
+
/*
|
|
122
|
+
* Cuts decoded output into lines. A chunk is searched only for itself and a partial line is joined
|
|
123
|
+
* once, when its line break comes, so a long line costs its length once. A line longer than `max`
|
|
124
|
+
* UTF-16 units is dropped whole, with `onOverflow` called once for it, and the next line reads as usual.
|
|
125
|
+
*/
|
|
126
|
+
export class LineSplitter {
|
|
127
|
+
onLine;
|
|
128
|
+
onOverflow;
|
|
129
|
+
max;
|
|
130
|
+
parts = [];
|
|
131
|
+
length = 0;
|
|
132
|
+
dropping = false;
|
|
133
|
+
constructor(onLine, onOverflow, max = MAX_LINE_LENGTH) {
|
|
134
|
+
this.onLine = onLine;
|
|
135
|
+
this.onOverflow = onOverflow;
|
|
136
|
+
this.max = max;
|
|
137
|
+
}
|
|
138
|
+
push(text) {
|
|
139
|
+
let start = 0;
|
|
140
|
+
let newline = text.indexOf('\n');
|
|
141
|
+
while (newline >= 0) {
|
|
142
|
+
this.add(text.slice(start, newline));
|
|
143
|
+
const line = this.take();
|
|
144
|
+
if (line !== null) {
|
|
145
|
+
this.onLine(line);
|
|
146
|
+
}
|
|
147
|
+
start = newline + 1;
|
|
148
|
+
newline = text.indexOf('\n', start);
|
|
149
|
+
}
|
|
150
|
+
this.add(text.slice(start));
|
|
151
|
+
}
|
|
152
|
+
/* Hands on what came after the last line break, for a stream that ended without one. */
|
|
153
|
+
end() {
|
|
154
|
+
const line = this.take();
|
|
155
|
+
if (line !== null && line !== '') {
|
|
156
|
+
this.onLine(line);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
add(piece) {
|
|
160
|
+
if (this.dropping || piece === '') {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
this.length += piece.length;
|
|
164
|
+
if (this.length > this.max) {
|
|
165
|
+
this.parts = [];
|
|
166
|
+
this.dropping = true;
|
|
167
|
+
this.onOverflow();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.parts.push(piece);
|
|
171
|
+
}
|
|
172
|
+
take() {
|
|
173
|
+
const line = this.dropping ? null : this.parts.join('');
|
|
174
|
+
this.parts = [];
|
|
175
|
+
this.length = 0;
|
|
176
|
+
this.dropping = false;
|
|
177
|
+
return line;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/*
|
|
181
|
+
* Hands every line of a CLI's output to `onLine` until the stream ends, through a `LineSplitter`.
|
|
182
|
+
* A read that fails rejects, after every line that came before it was handed on.
|
|
183
|
+
*/
|
|
184
|
+
export async function readStreamLines(stream, onLine, onOverflow, max = MAX_LINE_LENGTH) {
|
|
185
|
+
const reader = stream.getReader();
|
|
186
|
+
const decoder = new TextDecoder();
|
|
187
|
+
const lines = new LineSplitter(onLine, onOverflow, max);
|
|
188
|
+
try {
|
|
189
|
+
while (true) {
|
|
190
|
+
const { value, done } = await reader.read();
|
|
191
|
+
if (done) {
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
lines.push(decoder.decode(value, { stream: true }));
|
|
195
|
+
}
|
|
196
|
+
lines.end();
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
reader.releaseLock();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
102
202
|
/*
|
|
103
203
|
* A spawned CLI and how it ends. Every signal goes to its process group, SIGTERM first and SIGKILL
|
|
104
204
|
* after a grace, and only ever because a person stopped, removed or restarted something.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { ChatAttachment,
|
|
2
|
-
import type { UiCompileOptions } from '@adecore/intelligent-ui/compiler';
|
|
1
|
+
import type { ChatAttachment, ChatCheckpointDiff, ChatEvent, ChatGoalAction, ChatInfo, ChatItem, ChatQueuedMessage, ChatQuoteSource, ChatSkill, ChatUiChoiceOrigin, ChatUiChoicePayload, ChatUiQueryState, ModelSelection, RuntimeMode } from '@adecore/agent-contracts';
|
|
3
2
|
import type { ChatProvider } from '../providers/provider.ts';
|
|
4
3
|
import type { LimitsUpdate } from '../usage/limits/normalize.ts';
|
|
5
4
|
import type { BackendLaunch } from './backend.ts';
|
|
@@ -7,6 +6,7 @@ import type { SpawnChatProcess } from './chat-process.ts';
|
|
|
7
6
|
import type { ChatTitleInput } from './chat-title.ts';
|
|
8
7
|
import type { SubagentSettlement } from './subagent-settlement.ts';
|
|
9
8
|
import { ChatThread } from './thread.ts';
|
|
9
|
+
import { type UiReplyHost } from './ui-replies.ts';
|
|
10
10
|
import { type OutboxClock } from '../outbox/outbox-worker.ts';
|
|
11
11
|
export interface TurnCheckpoints {
|
|
12
12
|
take(cwd: string): Promise<string | null>;
|
|
@@ -46,10 +46,7 @@ export interface ChatSessionOptions {
|
|
|
46
46
|
references?: ChatReferences;
|
|
47
47
|
checkpoints?: TurnCheckpoints;
|
|
48
48
|
uiFenceLanguage?: string;
|
|
49
|
-
ui?:
|
|
50
|
-
schemas: UiCompileOptions['querySchemas'];
|
|
51
|
-
observe(item: ChatAssistantItem, final: boolean): void;
|
|
52
|
-
};
|
|
49
|
+
ui?: UiReplyHost;
|
|
53
50
|
emit(event: ChatEvent): void;
|
|
54
51
|
onLimits?(update: LimitsUpdate): void;
|
|
55
52
|
persist(): void;
|
|
@@ -109,13 +106,8 @@ export declare class ChatSession {
|
|
|
109
106
|
private pendingPreambles;
|
|
110
107
|
private submission;
|
|
111
108
|
private readonly steering;
|
|
112
|
-
private readonly uiStreams;
|
|
113
|
-
private readonly uiCompiled;
|
|
114
109
|
private readonly capturedUiAccess;
|
|
115
|
-
private readonly
|
|
116
|
-
private readonly uiReferencing;
|
|
117
|
-
private readonly uiAttachments;
|
|
118
|
-
private readonly uiFenceLanguage;
|
|
110
|
+
private readonly uiReplies;
|
|
119
111
|
constructor(options: ChatSessionOptions);
|
|
120
112
|
get uiPreviews(): ChatEvent[];
|
|
121
113
|
previewItems(items: ChatItem[]): ChatItem[];
|
|
@@ -125,6 +117,8 @@ export declare class ChatSession {
|
|
|
125
117
|
get preambles(): readonly string[];
|
|
126
118
|
get pid(): number | null;
|
|
127
119
|
get busy(): boolean;
|
|
120
|
+
private goalWorks;
|
|
121
|
+
goal(action: ChatGoalAction): Promise<void>;
|
|
128
122
|
configure(patch: {
|
|
129
123
|
selection?: ModelSelection;
|
|
130
124
|
runtimeMode?: RuntimeMode;
|
|
@@ -162,6 +156,8 @@ export declare class ChatSession {
|
|
|
162
156
|
approve(requestId: string, decision: 'allow' | 'allow-always' | 'deny', message?: string): boolean;
|
|
163
157
|
answer(requestId: string, answers: Record<string, string>): boolean;
|
|
164
158
|
dismiss(itemId: string): boolean;
|
|
159
|
+
holdForPerson(key: string): void;
|
|
160
|
+
releaseHold(key: string): void;
|
|
165
161
|
clear(force: boolean): Promise<void>;
|
|
166
162
|
settleStored(selection: ModelSelection, resume: ResumeDecision): void;
|
|
167
163
|
resume(turnId: string, attempt: number, words: ResumeWords): Promise<void>;
|
|
@@ -193,6 +189,7 @@ export declare class ChatSession {
|
|
|
193
189
|
upsertItems(items: readonly ChatItem[]): void;
|
|
194
190
|
addNote(level: 'info' | 'warning' | 'error', text: string): void;
|
|
195
191
|
end(reason: string): void;
|
|
192
|
+
restart(): Promise<void>;
|
|
196
193
|
freeze(): void;
|
|
197
194
|
dispose(): Promise<void>;
|
|
198
195
|
turnDiff(turnId: string): Promise<ChatCheckpointDiff | null>;
|
|
@@ -237,6 +234,7 @@ export declare class ChatSession {
|
|
|
237
234
|
private pauseQueue;
|
|
238
235
|
private clearWorkflowWarnings;
|
|
239
236
|
private watchWorkflows;
|
|
237
|
+
private watchWorkflow;
|
|
240
238
|
private reportsCurrentWindow;
|
|
241
239
|
private refreshTitle;
|
|
242
240
|
private applyTitle;
|
|
@@ -245,11 +243,6 @@ export declare class ChatSession {
|
|
|
245
243
|
private settleFromTranscripts;
|
|
246
244
|
private settleRows;
|
|
247
245
|
private emit;
|
|
248
|
-
private unscannedUiText;
|
|
249
|
-
private forgetUiScan;
|
|
250
|
-
private latestUiAttachment;
|
|
251
|
-
private findUiAttachment;
|
|
252
|
-
private clearUi;
|
|
253
246
|
private delegatingChange;
|
|
254
247
|
}
|
|
255
248
|
export interface ResumeDecision {
|