@myagentroam/agent 0.9.156 → 0.9.157
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/model/anthropic-messages.js +20 -2
- package/dist/agent-core/model/contracts.d.ts +4 -0
- package/dist/agent-core/model/openai-responses.js +38 -1
- package/dist/agent-core/runtime/event-projection.d.ts +6 -2
- package/dist/agent-core/runtime/event-projection.js +45 -0
- package/dist/agent-core/runtime/events.d.ts +3 -0
- package/dist/agent-core/runtime/execution.js +3 -8
- package/dist/agent-core/session/catalog.js +17 -0
- package/package.json +1 -1
|
@@ -160,13 +160,16 @@ export class AnthropicMessagesAdapter {
|
|
|
160
160
|
delta: text(block.text) ?? ''
|
|
161
161
|
};
|
|
162
162
|
else if (blockType === 'server_tool_use') {
|
|
163
|
-
const
|
|
163
|
+
const toolName = text(block.name) ?? 'unknown';
|
|
164
|
+
const kind = toolName === 'web_fetch' ? 'WEB_FETCH' : 'WEB_SEARCH';
|
|
164
165
|
const summary = anthropicHostedInputSummary(record(block.input));
|
|
165
|
-
hostedTools.set(id, { kind, summary });
|
|
166
|
+
hostedTools.set(id, { kind, toolName, summary });
|
|
166
167
|
yield {
|
|
167
168
|
type: 'hosted_tool',
|
|
168
169
|
itemId: id,
|
|
169
170
|
kind,
|
|
171
|
+
toolName,
|
|
172
|
+
...(Object.keys(summary).length ? { input: summary } : {}),
|
|
170
173
|
status: 'RUNNING',
|
|
171
174
|
summary
|
|
172
175
|
};
|
|
@@ -188,6 +191,19 @@ export class AnthropicMessagesAdapter {
|
|
|
188
191
|
type: 'hosted_tool',
|
|
189
192
|
itemId: toolId,
|
|
190
193
|
kind: hosted.kind,
|
|
194
|
+
toolName: hosted.toolName,
|
|
195
|
+
...(Object.keys(anthropicHostedInputSummary(hosted.summary)).length
|
|
196
|
+
? { input: anthropicHostedInputSummary(hosted.summary) }
|
|
197
|
+
: {}),
|
|
198
|
+
...(sources.length
|
|
199
|
+
? {
|
|
200
|
+
output: {
|
|
201
|
+
sources,
|
|
202
|
+
...(summary.sourcesTruncated ? { sourcesTruncated: true } : {})
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
: {}),
|
|
206
|
+
...(summary.sourcesTruncated ? { truncated: true } : {}),
|
|
191
207
|
status: anthropicHostedResultFailed(result) ? 'FAILED' : 'COMPLETED',
|
|
192
208
|
summary
|
|
193
209
|
};
|
|
@@ -267,6 +283,8 @@ export class AnthropicMessagesAdapter {
|
|
|
267
283
|
type: 'hosted_tool',
|
|
268
284
|
itemId: block.id,
|
|
269
285
|
kind: hosted.kind,
|
|
286
|
+
toolName: hosted.toolName,
|
|
287
|
+
input: anthropicHostedInputSummary(record(input)),
|
|
270
288
|
status: 'RUNNING',
|
|
271
289
|
summary
|
|
272
290
|
};
|
|
@@ -118,6 +118,10 @@ export type ModelEvent = {
|
|
|
118
118
|
itemId: string;
|
|
119
119
|
kind: 'WEB_SEARCH' | 'WEB_FETCH';
|
|
120
120
|
status: 'RUNNING' | 'COMPLETED' | 'FAILED';
|
|
121
|
+
toolName?: string;
|
|
122
|
+
input?: Record<string, unknown>;
|
|
123
|
+
output?: unknown;
|
|
124
|
+
truncated?: boolean;
|
|
121
125
|
summary: {
|
|
122
126
|
query?: string | undefined;
|
|
123
127
|
url?: string | undefined;
|
|
@@ -475,11 +475,25 @@ export class OpenAiResponsesAdapter {
|
|
|
475
475
|
? 'WEB_FETCH'
|
|
476
476
|
: (previous?.kind ?? 'WEB_SEARCH');
|
|
477
477
|
const summary = { ...previous?.summary, ...hostedWebActionSummary(action) };
|
|
478
|
-
|
|
478
|
+
const projected = hostedWebActionInput(action);
|
|
479
|
+
const input = { ...previous?.input, ...projected.input };
|
|
480
|
+
const truncated = previous?.truncated === true || projected.truncated;
|
|
481
|
+
hostedWebCalls.set(itemId, { kind, summary, input, truncated });
|
|
482
|
+
const output = {
|
|
483
|
+
...(summary.title === undefined ? {} : { title: summary.title }),
|
|
484
|
+
...(summary.sources === undefined ? {} : { sources: summary.sources }),
|
|
485
|
+
...(summary.sourcesTruncated === undefined
|
|
486
|
+
? {}
|
|
487
|
+
: { sourcesTruncated: summary.sourcesTruncated })
|
|
488
|
+
};
|
|
479
489
|
yield {
|
|
480
490
|
type: 'hosted_tool',
|
|
481
491
|
itemId,
|
|
482
492
|
kind,
|
|
493
|
+
toolName: 'web_search',
|
|
494
|
+
...(Object.keys(input).length ? { input } : {}),
|
|
495
|
+
...(Object.keys(output).length ? { output } : {}),
|
|
496
|
+
...(truncated || summary.sourcesTruncated === true ? { truncated: true } : {}),
|
|
483
497
|
status: type.endsWith('.failed')
|
|
484
498
|
? 'FAILED'
|
|
485
499
|
: type.endsWith('.completed') || type === 'response.output_item.done'
|
|
@@ -1510,6 +1524,29 @@ const RESPONSE_ITEM_TYPES = new Set([
|
|
|
1510
1524
|
]);
|
|
1511
1525
|
// A freeform patch item can contain the complete 4 MiB patch plus its JSON envelope.
|
|
1512
1526
|
const MAX_RESPONSE_ITEM_BYTES = 5 * 1024 * 1024;
|
|
1527
|
+
function hostedWebActionInput(action) {
|
|
1528
|
+
const input = {};
|
|
1529
|
+
let truncated = false;
|
|
1530
|
+
for (const [key, limit] of [
|
|
1531
|
+
['type', 128],
|
|
1532
|
+
['query', 10_000],
|
|
1533
|
+
['url', 2_048],
|
|
1534
|
+
['pattern', 10_000]
|
|
1535
|
+
]) {
|
|
1536
|
+
const value = action[key];
|
|
1537
|
+
if (typeof value !== 'string')
|
|
1538
|
+
continue;
|
|
1539
|
+
input[key] = value.slice(0, limit);
|
|
1540
|
+
truncated ||= value.length > limit;
|
|
1541
|
+
}
|
|
1542
|
+
if (Array.isArray(action.queries)) {
|
|
1543
|
+
const queries = action.queries.filter((value) => typeof value === 'string');
|
|
1544
|
+
input.queries = queries.slice(0, 10).map((value) => value.slice(0, 10_000));
|
|
1545
|
+
truncated ||=
|
|
1546
|
+
queries.length > 10 || queries.slice(0, 10).some((value) => value.length > 10_000);
|
|
1547
|
+
}
|
|
1548
|
+
return { input, truncated };
|
|
1549
|
+
}
|
|
1513
1550
|
function hostedWebActionSummary(action) {
|
|
1514
1551
|
const queries = Array.isArray(action.queries)
|
|
1515
1552
|
? action.queries
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import type { ModelUsage } from '../model/contracts.js';
|
|
2
|
-
import type { MarAgentEvent } from './events.js';
|
|
1
|
+
import type { ModelEvent, ModelUsage } from '../model/contracts.js';
|
|
2
|
+
import type { EventPayload, MarAgentEvent } from './events.js';
|
|
3
3
|
/** Keep streaming deltas live-only; exec output has one durable copy in model context records. */
|
|
4
4
|
export declare function eventForPersistence(event: MarAgentEvent): MarAgentEvent | undefined;
|
|
5
5
|
export declare function publicModelUsage(usage: ModelUsage): Omit<ModelUsage, 'rolloutBudgetUnits'>;
|
|
6
|
+
/** Provider-hosted calls are ordinary public tools, never local execution requests. */
|
|
7
|
+
export declare function publicHostedToolEvents(event: Extract<ModelEvent, {
|
|
8
|
+
type: 'hosted_tool';
|
|
9
|
+
}>): readonly EventPayload[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AGENT_EXECUTION_POLICY } from './execution-policy.js';
|
|
1
2
|
/** Keep streaming deltas live-only; exec output has one durable copy in model context records. */
|
|
2
3
|
export function eventForPersistence(event) {
|
|
3
4
|
if (event.type === 'message.delta' ||
|
|
@@ -15,3 +16,47 @@ export function publicModelUsage(usage) {
|
|
|
15
16
|
void rolloutBudgetUnits;
|
|
16
17
|
return publicUsage;
|
|
17
18
|
}
|
|
19
|
+
/** Provider-hosted calls are ordinary public tools, never local execution requests. */
|
|
20
|
+
export function publicHostedToolEvents(event) {
|
|
21
|
+
const toolName = event.toolName ?? (event.kind === 'WEB_SEARCH' ? 'web_search' : 'web_fetch');
|
|
22
|
+
const legacyInput = {
|
|
23
|
+
...(event.summary.query === undefined ? {} : { query: event.summary.query }),
|
|
24
|
+
...(event.summary.url === undefined ? {} : { url: event.summary.url })
|
|
25
|
+
};
|
|
26
|
+
const input = event.input ?? (Object.keys(legacyInput).length ? legacyInput : undefined);
|
|
27
|
+
const legacyOutput = {
|
|
28
|
+
...(event.summary.title === undefined ? {} : { title: event.summary.title }),
|
|
29
|
+
...(event.summary.sources?.length ? { sources: event.summary.sources.slice(0, 20) } : {}),
|
|
30
|
+
...(event.summary.sourcesTruncated === true || (event.summary.sources?.length ?? 0) > 20
|
|
31
|
+
? { sourcesTruncated: true }
|
|
32
|
+
: {})
|
|
33
|
+
};
|
|
34
|
+
const output = event.output ?? (Object.keys(legacyOutput).length ? legacyOutput : undefined);
|
|
35
|
+
const text = typeof output === 'string' ? output : output === undefined ? '' : JSON.stringify(output);
|
|
36
|
+
const summary = text.slice(0, AGENT_EXECUTION_POLICY.toolEventSummaryCharacters);
|
|
37
|
+
const truncated = event.truncated === true ||
|
|
38
|
+
legacyOutput.sourcesTruncated === true ||
|
|
39
|
+
summary.length < text.length;
|
|
40
|
+
const started = {
|
|
41
|
+
type: 'tool.started',
|
|
42
|
+
toolName,
|
|
43
|
+
callId: event.itemId,
|
|
44
|
+
...(input === undefined ? {} : { input }),
|
|
45
|
+
...(truncated ? { truncated: true } : {})
|
|
46
|
+
};
|
|
47
|
+
if (event.status === 'RUNNING')
|
|
48
|
+
return [started];
|
|
49
|
+
if (event.status === 'FAILED')
|
|
50
|
+
return [
|
|
51
|
+
started,
|
|
52
|
+
{
|
|
53
|
+
type: 'tool.failed',
|
|
54
|
+
toolName,
|
|
55
|
+
callId: event.itemId,
|
|
56
|
+
code: 'HOSTED_TOOL_FAILED',
|
|
57
|
+
message: summary || 'Hosted tool failed.',
|
|
58
|
+
truncated
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
return [started, { type: 'tool.completed', toolName, callId: event.itemId, summary, truncated }];
|
|
62
|
+
}
|
|
@@ -46,6 +46,7 @@ export type MarAgentEvent = MarAgentEventBase & ({
|
|
|
46
46
|
type: 'reasoning.summary';
|
|
47
47
|
text: string;
|
|
48
48
|
} | {
|
|
49
|
+
/** Legacy persisted event; the Catalog exposes standard tool events instead. */
|
|
49
50
|
type: 'hosted_tool.updated';
|
|
50
51
|
itemId: string;
|
|
51
52
|
kind: 'WEB_SEARCH' | 'WEB_FETCH';
|
|
@@ -71,6 +72,7 @@ export type MarAgentEvent = MarAgentEventBase & ({
|
|
|
71
72
|
callId: string;
|
|
72
73
|
parentCallId?: string;
|
|
73
74
|
input?: unknown;
|
|
75
|
+
truncated?: boolean;
|
|
74
76
|
} | {
|
|
75
77
|
type: 'tool.completed';
|
|
76
78
|
toolName: string;
|
|
@@ -88,6 +90,7 @@ export type MarAgentEvent = MarAgentEventBase & ({
|
|
|
88
90
|
parentCallId?: string;
|
|
89
91
|
code: string;
|
|
90
92
|
message?: string;
|
|
93
|
+
truncated?: boolean;
|
|
91
94
|
} | {
|
|
92
95
|
type: 'usage.updated';
|
|
93
96
|
inputTokens?: number | undefined;
|
|
@@ -3,7 +3,7 @@ import { isProviderContextOverflow, recoverModelStream } from '../model/recovery
|
|
|
3
3
|
import { modelStreamEventObservedAt } from '../model/sse.js';
|
|
4
4
|
import { modelOutputContinuationMessage } from '../prompts/output.js';
|
|
5
5
|
import { executeRoundTools } from '../tools/execution.js';
|
|
6
|
-
import { publicModelUsage } from './event-projection.js';
|
|
6
|
+
import { publicHostedToolEvents, publicModelUsage } from './event-projection.js';
|
|
7
7
|
import { PlanOutputPrefix, splitPlanOutput } from './plan-output.js';
|
|
8
8
|
/** Own the single model/tool loop; the SDK owns its handle, terminal events and cleanup. */
|
|
9
9
|
export class ExecutionLoop {
|
|
@@ -215,13 +215,8 @@ export class ExecutionLoop {
|
|
|
215
215
|
}
|
|
216
216
|
else if (event.type === 'hosted_tool') {
|
|
217
217
|
if (mode !== 'compact')
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
itemId: event.itemId,
|
|
221
|
-
kind: event.kind,
|
|
222
|
-
status: event.status,
|
|
223
|
-
summary: event.summary
|
|
224
|
-
});
|
|
218
|
+
for (const toolEvent of publicHostedToolEvents(event))
|
|
219
|
+
await input.publish(toolEvent);
|
|
225
220
|
}
|
|
226
221
|
else if (event.type === 'citation') {
|
|
227
222
|
if (mode !== 'compact')
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MarAgentError } from '../error.js';
|
|
2
|
+
import { publicHostedToolEvents } from '../runtime/event-projection.js';
|
|
2
3
|
import { JsonlSessionStore } from './jsonl-store.js';
|
|
3
4
|
const MAX_INPUT_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
4
5
|
const INPUT_IMAGE_MIME_TYPES = new Set(['image/png', 'image/jpeg', 'image/gif', 'image/webp']);
|
|
@@ -39,6 +40,22 @@ export async function openMarAgentSessionCatalog(input) {
|
|
|
39
40
|
}
|
|
40
41
|
];
|
|
41
42
|
}
|
|
43
|
+
if (isMarAgentEvent(record.payload) && record.payload.type === 'hosted_tool.updated') {
|
|
44
|
+
const legacy = record.payload;
|
|
45
|
+
return publicHostedToolEvents({ ...legacy, type: 'hosted_tool' }).map((event) => ({
|
|
46
|
+
kind: 'event',
|
|
47
|
+
sequence: record.sequence,
|
|
48
|
+
event: {
|
|
49
|
+
sequence: legacy.sequence,
|
|
50
|
+
timestamp: legacy.timestamp,
|
|
51
|
+
sessionId: legacy.sessionId,
|
|
52
|
+
executionId: legacy.executionId,
|
|
53
|
+
...(legacy.turnId === undefined ? {} : { turnId: legacy.turnId }),
|
|
54
|
+
...event,
|
|
55
|
+
eventId: `${legacy.eventId}:${event.type}`
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
42
59
|
if (isMarAgentEvent(record.payload))
|
|
43
60
|
return [{ kind: 'event', sequence: record.sequence, event: record.payload }];
|
|
44
61
|
return [];
|