@myagentroam/agent 0.11.2 → 0.11.3
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/dist/agent-core/extensions/model-stream.js +4 -2
- package/dist/agent-core/model/anthropic-messages.js +11 -2
- package/dist/agent-core/model/contracts.d.ts +2 -1
- package/dist/agent-core/model/openai-responses.js +17 -6
- package/dist/agent-core/runtime/compaction/operation.js +1 -1
- package/dist/agent-core/runtime/events.d.ts +7 -1
- package/dist/agent-core/runtime/execution.js +31 -4
- package/dist/agent-core/runtime/model-progress.js +1 -1
- package/dist/agent-core/session/catalog.js +5 -2
- package/package.json +1 -1
|
@@ -74,8 +74,10 @@ function validEvent(event) {
|
|
|
74
74
|
return (typeof event.itemId === 'string' &&
|
|
75
75
|
typeof event.text === 'string' &&
|
|
76
76
|
(event.phase === undefined || ['commentary', 'final_answer'].includes(event.phase)));
|
|
77
|
-
case 'reasoning.
|
|
78
|
-
return typeof event.itemId === 'string' &&
|
|
77
|
+
case 'reasoning.completed':
|
|
78
|
+
return (typeof event.itemId === 'string' &&
|
|
79
|
+
typeof event.text === 'string' &&
|
|
80
|
+
['summary', 'visible_thinking', 'unspecified'].includes(String(event.representation)));
|
|
79
81
|
case 'client_tool.call':
|
|
80
82
|
return (typeof event.callId === 'string' &&
|
|
81
83
|
typeof event.name === 'string' &&
|
|
@@ -144,6 +144,7 @@ export class AnthropicMessagesAdapter {
|
|
|
144
144
|
// Block completion precedes the stop reason, which determines commentary vs final answer.
|
|
145
145
|
const pendingTextBlocks = new Set();
|
|
146
146
|
let responseId = `anthropic-${randomUUID()}`;
|
|
147
|
+
const completedThinking = new Set();
|
|
147
148
|
let terminal;
|
|
148
149
|
let latestInputUsage;
|
|
149
150
|
let thinkingBytes = 0;
|
|
@@ -305,6 +306,9 @@ export class AnthropicMessagesAdapter {
|
|
|
305
306
|
if (block?.type === 'text')
|
|
306
307
|
pendingTextBlocks.add(index);
|
|
307
308
|
else if (block?.type === 'thinking' || block?.type === 'redacted_thinking') {
|
|
309
|
+
if (completedThinking.has(index))
|
|
310
|
+
continue;
|
|
311
|
+
completedThinking.add(index);
|
|
308
312
|
if (block.type === 'redacted_thinking' || block.signature) {
|
|
309
313
|
const item = anthropicThinkingBlock(block.type === 'thinking'
|
|
310
314
|
? { type: 'thinking', thinking: block.text, signature: block.signature }
|
|
@@ -315,8 +319,13 @@ export class AnthropicMessagesAdapter {
|
|
|
315
319
|
assertAnthropicThinkingBudget(thinkingBytes);
|
|
316
320
|
yield observeModelStreamEvent({ type: 'response.item', provider: 'ANTHROPIC_MESSAGES', item }, modelStreamEventObservedAt(raw));
|
|
317
321
|
}
|
|
318
|
-
if (block.type === 'thinking' && block.text)
|
|
319
|
-
yield observeModelStreamEvent({
|
|
322
|
+
if (block.type === 'thinking' && block.text.trim())
|
|
323
|
+
yield observeModelStreamEvent({
|
|
324
|
+
type: 'reasoning.completed',
|
|
325
|
+
itemId: block.id,
|
|
326
|
+
representation: 'visible_thinking',
|
|
327
|
+
text: block.text
|
|
328
|
+
}, modelStreamEventObservedAt(raw));
|
|
320
329
|
}
|
|
321
330
|
else if (block?.type === 'server_tool_use') {
|
|
322
331
|
yield observeModelStreamEvent({ type: 'output.paused' }, modelStreamEventObservedAt(raw));
|
|
@@ -161,8 +161,9 @@ export type ModelEvent = {
|
|
|
161
161
|
phase?: 'commentary' | 'final_answer';
|
|
162
162
|
text: string;
|
|
163
163
|
} | {
|
|
164
|
-
type: 'reasoning.
|
|
164
|
+
type: 'reasoning.completed';
|
|
165
165
|
itemId: string;
|
|
166
|
+
representation: 'summary' | 'visible_thinking' | 'unspecified';
|
|
166
167
|
text: string;
|
|
167
168
|
} | {
|
|
168
169
|
type: 'client_tool.call';
|
|
@@ -305,6 +305,7 @@ export class OpenAiResponsesAdapter {
|
|
|
305
305
|
const textPhases = new Map();
|
|
306
306
|
const pendingCompletedText = new Map();
|
|
307
307
|
const emittedCompletedText = new Set();
|
|
308
|
+
const emittedReasoning = new Set();
|
|
308
309
|
const emittedFunctionCalls = new Set();
|
|
309
310
|
const hostedWebCalls = new Map();
|
|
310
311
|
try {
|
|
@@ -412,12 +413,22 @@ export class OpenAiResponsesAdapter {
|
|
|
412
413
|
else
|
|
413
414
|
pendingCompletedText.set(itemId, completedText);
|
|
414
415
|
}
|
|
415
|
-
else if (type === 'response.reasoning_summary_text.done')
|
|
416
|
+
else if (type === 'response.reasoning_summary_text.done') {
|
|
417
|
+
const itemId = JSON.stringify([
|
|
418
|
+
text(event.item_id) ?? `reasoning-${event.output_index ?? 0}`,
|
|
419
|
+
event.summary_index ?? 0
|
|
420
|
+
]);
|
|
421
|
+
const summary = text(event.text) ?? '';
|
|
422
|
+
if (!summary.trim() || emittedReasoning.has(itemId))
|
|
423
|
+
continue;
|
|
424
|
+
emittedReasoning.add(itemId);
|
|
416
425
|
yield observeModelStreamEvent({
|
|
417
|
-
type: 'reasoning.
|
|
418
|
-
itemId
|
|
419
|
-
|
|
426
|
+
type: 'reasoning.completed',
|
|
427
|
+
itemId,
|
|
428
|
+
representation: 'summary',
|
|
429
|
+
text: summary
|
|
420
430
|
}, modelStreamEventObservedAt(raw));
|
|
431
|
+
}
|
|
421
432
|
else if (type === 'response.output_item.done' &&
|
|
422
433
|
text(record(event.item).type) === 'tool_search_call') {
|
|
423
434
|
const item = record(event.item);
|
|
@@ -687,7 +698,7 @@ class OpenAiResponsesTurnSession {
|
|
|
687
698
|
else if (event.type === 'text.delta' ||
|
|
688
699
|
event.type === 'output.delta' ||
|
|
689
700
|
event.type === 'text.completed' ||
|
|
690
|
-
event.type === 'reasoning.
|
|
701
|
+
event.type === 'reasoning.completed' ||
|
|
691
702
|
event.type === 'client_tool.call' ||
|
|
692
703
|
event.type === 'hosted_tool' ||
|
|
693
704
|
event.type === 'citation' ||
|
|
@@ -1435,7 +1446,7 @@ function isSemanticEvent(event) {
|
|
|
1435
1446
|
return false;
|
|
1436
1447
|
if (event.type === 'text.delta')
|
|
1437
1448
|
return event.delta.length > 0;
|
|
1438
|
-
if (event.type === 'text.completed' || event.type === 'reasoning.
|
|
1449
|
+
if (event.type === 'text.completed' || event.type === 'reasoning.completed')
|
|
1439
1450
|
return event.text.length > 0;
|
|
1440
1451
|
return true;
|
|
1441
1452
|
}
|
|
@@ -47,7 +47,7 @@ export class CompactionOperation {
|
|
|
47
47
|
if (event.type === 'text.delta')
|
|
48
48
|
this.#textDeltaCharacters += event.delta.length;
|
|
49
49
|
if ((event.type === 'text.delta' && event.delta.length > 0) ||
|
|
50
|
-
((event.type === 'text.completed' || event.type === 'reasoning.
|
|
50
|
+
((event.type === 'text.completed' || event.type === 'reasoning.completed') &&
|
|
51
51
|
event.text.length > 0)) {
|
|
52
52
|
this.#lastOutputAfterMs = Math.max(0, Date.now() - this.#startedAt);
|
|
53
53
|
this.#firstOutputAfterMs ??= this.#lastOutputAfterMs;
|
|
@@ -22,6 +22,10 @@ export type MarAgentEvent = MarAgentEventBase & ({
|
|
|
22
22
|
type: 'execution.started';
|
|
23
23
|
mode: ExecutionMode;
|
|
24
24
|
permissionMode?: import('../tools/permissions.js').PermissionMode;
|
|
25
|
+
} | {
|
|
26
|
+
type: 'message.started';
|
|
27
|
+
itemId: string;
|
|
28
|
+
phase: 'commentary' | 'final_answer';
|
|
25
29
|
} | {
|
|
26
30
|
type: 'message.delta';
|
|
27
31
|
itemId: string;
|
|
@@ -53,7 +57,9 @@ export type MarAgentEvent = MarAgentEventBase & ({
|
|
|
53
57
|
itemId: string;
|
|
54
58
|
text: string;
|
|
55
59
|
} | {
|
|
56
|
-
type: 'reasoning.
|
|
60
|
+
type: 'reasoning.completed';
|
|
61
|
+
itemId: string;
|
|
62
|
+
representation: 'summary' | 'visible_thinking' | 'unspecified';
|
|
57
63
|
text: string;
|
|
58
64
|
} | {
|
|
59
65
|
/** Legacy persisted event; the Catalog exposes standard tool events instead. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { MarAgentError } from '../error.js';
|
|
2
3
|
import { isProviderContextOverflow, recoverModelStream } from '../model/recovery.js';
|
|
3
4
|
import { modelStreamEventObservedAt } from '../model/sse.js';
|
|
@@ -35,6 +36,10 @@ export class ExecutionLoop {
|
|
|
35
36
|
const pendingTools = [];
|
|
36
37
|
let incompleteToolCall = false;
|
|
37
38
|
const round = await input.prepareRound(pendingOutputContinuation);
|
|
39
|
+
const reasoningScope = randomUUID();
|
|
40
|
+
const publishedReasoning = new Set();
|
|
41
|
+
const startedMessages = new Set();
|
|
42
|
+
const leadingMessageWhitespace = new Map();
|
|
38
43
|
let sawModelSemanticEvent = false;
|
|
39
44
|
let requestStartedAt;
|
|
40
45
|
let firstModelResponseAt;
|
|
@@ -146,6 +151,20 @@ export class ExecutionLoop {
|
|
|
146
151
|
delta = prefix.push(delta);
|
|
147
152
|
}
|
|
148
153
|
if (mode !== 'compact' && delta) {
|
|
154
|
+
if (!startedMessages.has(event.itemId)) {
|
|
155
|
+
delta = (leadingMessageWhitespace.get(event.itemId) ?? '') + delta;
|
|
156
|
+
if (!delta.trim()) {
|
|
157
|
+
leadingMessageWhitespace.set(event.itemId, delta);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
leadingMessageWhitespace.delete(event.itemId);
|
|
161
|
+
startedMessages.add(event.itemId);
|
|
162
|
+
await input.publish({
|
|
163
|
+
type: 'message.started',
|
|
164
|
+
itemId: event.itemId,
|
|
165
|
+
phase: event.phase
|
|
166
|
+
});
|
|
167
|
+
}
|
|
149
168
|
await input.publish({
|
|
150
169
|
type: 'message.delta',
|
|
151
170
|
itemId: event.itemId,
|
|
@@ -155,6 +174,7 @@ export class ExecutionLoop {
|
|
|
155
174
|
}
|
|
156
175
|
}
|
|
157
176
|
else if (event.type === 'text.completed') {
|
|
177
|
+
leadingMessageWhitespace.delete(event.itemId);
|
|
158
178
|
const phase = event.phase ?? 'final_answer';
|
|
159
179
|
if (phase === 'final_answer')
|
|
160
180
|
this.finalAnswer = event.text;
|
|
@@ -218,9 +238,16 @@ export class ExecutionLoop {
|
|
|
218
238
|
}
|
|
219
239
|
await input.publish({ type: 'usage.updated', ...publicModelUsage(event.usage) });
|
|
220
240
|
}
|
|
221
|
-
else if (event.type === 'reasoning.
|
|
222
|
-
if (mode !== 'compact')
|
|
223
|
-
await input.publish({
|
|
241
|
+
else if (event.type === 'reasoning.completed') {
|
|
242
|
+
if (mode !== 'compact' && event.text.trim() && !publishedReasoning.has(event.itemId)) {
|
|
243
|
+
await input.publish({
|
|
244
|
+
type: 'reasoning.completed',
|
|
245
|
+
itemId: `${reasoningScope}:${event.itemId}`,
|
|
246
|
+
representation: event.representation,
|
|
247
|
+
text: event.text
|
|
248
|
+
});
|
|
249
|
+
publishedReasoning.add(event.itemId);
|
|
250
|
+
}
|
|
224
251
|
}
|
|
225
252
|
else if (event.type === 'hosted_tool') {
|
|
226
253
|
if (mode !== 'compact')
|
|
@@ -404,7 +431,7 @@ export class ExecutionLoop {
|
|
|
404
431
|
function isModelResponseEvent(event) {
|
|
405
432
|
if (event.type === 'text.delta')
|
|
406
433
|
return event.delta.length > 0;
|
|
407
|
-
if (event.type === 'text.completed' || event.type === 'reasoning.
|
|
434
|
+
if (event.type === 'text.completed' || event.type === 'reasoning.completed')
|
|
408
435
|
return event.text.length > 0;
|
|
409
436
|
return (event.type === 'response.item' ||
|
|
410
437
|
event.type === 'output.delta' ||
|
|
@@ -72,7 +72,7 @@ function isGenerationProgress(event, hostedStates) {
|
|
|
72
72
|
case 'text.delta':
|
|
73
73
|
return event.delta.length > 0;
|
|
74
74
|
case 'text.completed':
|
|
75
|
-
case 'reasoning.
|
|
75
|
+
case 'reasoning.completed':
|
|
76
76
|
return event.text.length > 0;
|
|
77
77
|
case 'hosted_tool': {
|
|
78
78
|
const previous = hostedStates.get(event.itemId);
|
|
@@ -58,8 +58,10 @@ export async function openMarAgentSessionCatalog(input) {
|
|
|
58
58
|
}
|
|
59
59
|
}));
|
|
60
60
|
}
|
|
61
|
-
if (isMarAgentEvent(record.payload))
|
|
62
|
-
|
|
61
|
+
if (isMarAgentEvent(record.payload)) {
|
|
62
|
+
const event = record.payload;
|
|
63
|
+
return [{ kind: 'event', sequence: record.sequence, event }];
|
|
64
|
+
}
|
|
63
65
|
return [];
|
|
64
66
|
});
|
|
65
67
|
return {
|
|
@@ -147,6 +149,7 @@ export function imageMetadata(value) {
|
|
|
147
149
|
function isMarAgentEvent(value) {
|
|
148
150
|
return (isRecord(value) &&
|
|
149
151
|
typeof value.type === 'string' &&
|
|
152
|
+
value.type !== 'reasoning.summary' &&
|
|
150
153
|
typeof value.eventId === 'string' &&
|
|
151
154
|
typeof value.sequence === 'number' &&
|
|
152
155
|
typeof value.timestamp === 'string' &&
|