@myagentroam/agent 0.11.68 → 0.11.70
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/host/local-tool-registry.js +7 -1
- package/dist/runtime/event-projection.d.ts +1 -0
- package/dist/runtime/event-projection.js +2 -2
- package/dist/runtime/public-tool-metadata.d.ts +5 -0
- package/dist/runtime/public-tool-metadata.js +20 -0
- package/dist/tools/code-mode/dispatch.js +5 -2
- package/dist/tools/contracts.d.ts +5 -0
- package/dist/tools/execution.js +3 -1
- package/dist/tools/local/exec.js +1 -0
- package/dist/tools/local/read.d.ts +8 -0
- package/dist/tools/local/read.js +56 -0
- package/dist/tools/output-projection.js +10 -0
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ import { CodeModeTool, codeModeToolDefinition, codeExecWaitToolDefinition } from
|
|
|
6
6
|
import { normalizeToolInput } from '../tools/input.js';
|
|
7
7
|
import { execToolInput, execToolDefinition, execWaitToolDefinition, formatExecResult } from '../tools/local/exec.js';
|
|
8
8
|
import { ExecTool } from './local-exec-tool.js';
|
|
9
|
-
import { ReadTool, formatBatchReadOutput, readToolDefinition } from '../tools/local/read.js';
|
|
9
|
+
import { ReadTool, formatBatchReadOutput, formatReadEventOutput, readToolDefinition } from '../tools/local/read.js';
|
|
10
10
|
import { WorkspacePathResolver } from '../tools/shared/path-resolver.js';
|
|
11
11
|
import { ViewImageTool, viewImageToolDefinition } from '../tools/local/view-image.js';
|
|
12
12
|
const definitions = [
|
|
@@ -58,9 +58,15 @@ export class LocalToolRegistry {
|
|
|
58
58
|
async (arguments_, context) => {
|
|
59
59
|
const result = await read.execute(arguments_, context.signal);
|
|
60
60
|
const formatted = formatBatchReadOutput(result.results);
|
|
61
|
+
const publicResult = formatReadEventOutput(result.results);
|
|
61
62
|
return {
|
|
62
63
|
content: formatted.content,
|
|
63
64
|
data: result,
|
|
65
|
+
eventSummary: publicResult.source,
|
|
66
|
+
eventData: {
|
|
67
|
+
...publicResult.data,
|
|
68
|
+
truncated: result.truncated || publicResult.truncated
|
|
69
|
+
},
|
|
64
70
|
truncated: result.truncated || formatted.truncated
|
|
65
71
|
};
|
|
66
72
|
}
|
|
@@ -4,6 +4,7 @@ import type { EventPayload, AgentEvent } from './events.js';
|
|
|
4
4
|
export declare function toolEventSummary(text: string): {
|
|
5
5
|
summary: string;
|
|
6
6
|
truncated: boolean;
|
|
7
|
+
retainedLength: number;
|
|
7
8
|
};
|
|
8
9
|
/** Keep streaming deltas live-only; exec output has one durable copy in model context records. */
|
|
9
10
|
export declare function eventForPersistence(event: AgentEvent): AgentEvent | undefined;
|
|
@@ -4,10 +4,10 @@ import { publicToolMetadata } from './public-tool-metadata.js';
|
|
|
4
4
|
export function toolEventSummary(text) {
|
|
5
5
|
const limit = AGENT_EXECUTION_POLICY.toolEventSummaryCharacters;
|
|
6
6
|
if (text.length <= limit)
|
|
7
|
-
return { summary: text, truncated: false };
|
|
7
|
+
return { summary: text, truncated: false, retainedLength: text.length };
|
|
8
8
|
const marker = '... [tool event summary truncated]';
|
|
9
9
|
const prefix = text.slice(0, limit - marker.length).replace(/[\uD800-\uDBFF]$/u, '');
|
|
10
|
-
return { summary: prefix + marker, truncated: true };
|
|
10
|
+
return { summary: prefix + marker, truncated: true, retainedLength: prefix.length };
|
|
11
11
|
}
|
|
12
12
|
/** Keep streaming deltas live-only; exec output has one durable copy in model context records. */
|
|
13
13
|
export function eventForPersistence(event) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type PublicToolMetadata = ({
|
|
2
2
|
query?: string;
|
|
3
|
+
sourcesOnly?: true;
|
|
3
4
|
sources?: {
|
|
4
5
|
url: string;
|
|
5
6
|
title?: string;
|
|
@@ -16,6 +17,10 @@ export type PublicToolMetadata = ({
|
|
|
16
17
|
name: string;
|
|
17
18
|
description?: string;
|
|
18
19
|
source?: string;
|
|
20
|
+
} | {
|
|
21
|
+
tools: string[];
|
|
22
|
+
} | {
|
|
23
|
+
status: 'accepted';
|
|
19
24
|
}) & {
|
|
20
25
|
hostedToolKind?: 'WEB_SEARCH' | 'WEB_FETCH';
|
|
21
26
|
};
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/** Public metadata only; page bodies and skill instructions stay in the bounded output. */
|
|
2
2
|
export function publicToolMetadata(toolName, value) {
|
|
3
3
|
const text = (key, limit) => typeof value[key] === 'string' ? value[key].slice(0, limit) : undefined;
|
|
4
|
+
if (toolName === 'tool_search' &&
|
|
5
|
+
Array.isArray(value.tools) &&
|
|
6
|
+
value.tools.every((name) => typeof name === 'string'))
|
|
7
|
+
return { tools: value.tools.slice(0, 20).map((name) => name.slice(0, 512)) };
|
|
8
|
+
if (toolName === 'smart_compact' && value.status === 'accepted')
|
|
9
|
+
return { status: 'accepted' };
|
|
4
10
|
if (toolName === 'web_search') {
|
|
5
11
|
const entries = Array.isArray(value.results)
|
|
6
12
|
? value.results
|
|
@@ -21,7 +27,21 @@ export function publicToolMetadata(toolName, value) {
|
|
|
21
27
|
}
|
|
22
28
|
];
|
|
23
29
|
});
|
|
30
|
+
const sourcesComplete = entries !== undefined &&
|
|
31
|
+
sources !== undefined &&
|
|
32
|
+
entries.length <= 20 &&
|
|
33
|
+
entries.length === sources.length &&
|
|
34
|
+
value.truncated !== true &&
|
|
35
|
+
value.sourcesTruncated !== true &&
|
|
36
|
+
entries.every((entry, index) => {
|
|
37
|
+
const source = entry;
|
|
38
|
+
const projected = sources[index];
|
|
39
|
+
return (source.url === projected.url &&
|
|
40
|
+
source.title === projected.title &&
|
|
41
|
+
source.snippet === projected.snippet);
|
|
42
|
+
});
|
|
24
43
|
return {
|
|
44
|
+
...(value.sourcesOnly === true && sourcesComplete ? { sourcesOnly: true } : {}),
|
|
25
45
|
...(text('query', 500) === undefined ? {} : { query: text('query', 500) }),
|
|
26
46
|
...(sources === undefined
|
|
27
47
|
? {}
|
|
@@ -40,7 +40,10 @@ export function createCodeToolDispatch(input) {
|
|
|
40
40
|
...(expected ? { expectedMcpTool: expected } : {})
|
|
41
41
|
}, 'programmatic');
|
|
42
42
|
const bounded = boundedModelToolOutput(call.name, result.content, result.data);
|
|
43
|
-
const data = call.name === '
|
|
43
|
+
const data = call.name === 'read' ||
|
|
44
|
+
call.name === 'web_search' ||
|
|
45
|
+
call.name === 'exec' ||
|
|
46
|
+
call.name === 'exec_wait'
|
|
44
47
|
? structuredToolEventData(call.name, result.eventData ?? result.data)
|
|
45
48
|
: result.eventData === undefined
|
|
46
49
|
? structuredToolEventData(call.name, result.data)
|
|
@@ -63,7 +66,7 @@ export function createCodeToolDispatch(input) {
|
|
|
63
66
|
truncated: result.truncated === true || bounded.truncated || preview.truncated,
|
|
64
67
|
...(result.artifacts ? { artifacts: result.artifacts } : {})
|
|
65
68
|
});
|
|
66
|
-
const { eventData: _eventData, ...guestResult } = result;
|
|
69
|
+
const { eventData: _eventData, eventSummary: _eventSummary, ...guestResult } = result;
|
|
67
70
|
return {
|
|
68
71
|
...guestResult,
|
|
69
72
|
...((call.name === 'exec' || call.name === 'exec_wait') && data !== undefined
|
package/dist/tools/execution.js
CHANGED
|
@@ -128,7 +128,9 @@ export async function executeRoundTools(calls, scope) {
|
|
|
128
128
|
: typeof output.eventSummary === 'string'
|
|
129
129
|
? output.eventSummary
|
|
130
130
|
: '');
|
|
131
|
-
const structuredData = call.name === '
|
|
131
|
+
const structuredData = call.name === 'read' ||
|
|
132
|
+
call.name === 'web_search' ||
|
|
133
|
+
call.name === 'exec' ||
|
|
132
134
|
call.name === 'exec_wait' ||
|
|
133
135
|
call.name === 'code_exec' ||
|
|
134
136
|
call.name === 'code_exec_wait'
|
package/dist/tools/local/exec.js
CHANGED
|
@@ -32,6 +32,7 @@ export function formatExecResult(result) {
|
|
|
32
32
|
export const execToolDefinition = {
|
|
33
33
|
name: 'exec',
|
|
34
34
|
allowedCallers: ['direct', 'programmatic'],
|
|
35
|
+
codeModeExposure: 'both',
|
|
35
36
|
parallelSafety: 'safe',
|
|
36
37
|
description: 'Start a platform-native command, script, or program in workspace/default cwd. Returns a stable processId (p_ plus 12 lowercase hex characters), status, bounded stdout/stderr, cumulative byte counts, dropped-byte counts, exitCode and truncated. A completed status does not imply exitCode 0; inspect stderr/exitCode. For subsequent waiting, stdin writes or cancellation, call exec_wait directly with processId, not exec. Truncation does not stop the process. Cancelling the initial wait does not terminate the process. waitOutcome distinguishes snapshot, completion, and timeout. A foreground wait may return interrupted with reason=steer; the process keeps running.',
|
|
37
38
|
outputSchema: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ClientToolDefinition } from '../contracts.js';
|
|
2
|
+
import type { ReadEventData } from '../contracts.js';
|
|
2
3
|
import { WorkspacePathResolver } from '../shared/path-resolver.js';
|
|
3
4
|
export type { ReadEventData } from '../contracts.js';
|
|
4
5
|
export declare const readToolDefinition: ClientToolDefinition;
|
|
@@ -31,6 +32,13 @@ export interface BatchReadResult {
|
|
|
31
32
|
results: Array<ReadResult | ReadErrorResult>;
|
|
32
33
|
truncated: boolean;
|
|
33
34
|
}
|
|
35
|
+
/** Produce public text and offsets together, independently of model-visible markup. */
|
|
36
|
+
export declare function formatReadEventOutput(results: BatchReadResult['results']): {
|
|
37
|
+
source: string;
|
|
38
|
+
summary: string;
|
|
39
|
+
truncated: boolean;
|
|
40
|
+
data: ReadEventData;
|
|
41
|
+
};
|
|
34
42
|
export declare class ReadTool {
|
|
35
43
|
#private;
|
|
36
44
|
private readonly paths;
|
package/dist/tools/local/read.js
CHANGED
|
@@ -85,6 +85,62 @@ export const readToolDefinition = {
|
|
|
85
85
|
additionalProperties: false
|
|
86
86
|
}
|
|
87
87
|
};
|
|
88
|
+
/** Produce public text and offsets together, independently of model-visible markup. */
|
|
89
|
+
export function formatReadEventOutput(results) {
|
|
90
|
+
let source = '';
|
|
91
|
+
const items = results
|
|
92
|
+
.slice(0, TOOL_EXECUTION_LIMITS.readMaxBatchItems)
|
|
93
|
+
.map((item) => {
|
|
94
|
+
const path = item.path.slice(0, 4096).replace(/[\uD800-\uDBFF]$/u, '');
|
|
95
|
+
if ('error' in item) {
|
|
96
|
+
const error = {
|
|
97
|
+
code: item.error.code.slice(0, 80),
|
|
98
|
+
message: item.error.message.slice(0, 1000)
|
|
99
|
+
};
|
|
100
|
+
return { body: `${error.code}: ${error.message}`, result: { path, error } };
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
body: item.text,
|
|
104
|
+
result: {
|
|
105
|
+
path,
|
|
106
|
+
startLine: item.startLine,
|
|
107
|
+
...(item.endLine === undefined ? {} : { endLine: item.endLine }),
|
|
108
|
+
...(item.text.length === 0 ? { empty: true } : {})
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
const maximum = AGENT_EXECUTION_POLICY.toolEventSummaryCharacters;
|
|
113
|
+
const completeLength = items.reduce((length, { body, result }) => length + result.path.length + 1 + body.length, Math.max(0, items.length - 1) * 2);
|
|
114
|
+
let truncated = items.length < results.length;
|
|
115
|
+
const projected = [];
|
|
116
|
+
for (const [index, { body, result }] of items.entries()) {
|
|
117
|
+
const path = result.path;
|
|
118
|
+
const separator = index === 0 ? '' : '\n\n';
|
|
119
|
+
const remaining = items.length - index;
|
|
120
|
+
const budget = completeLength <= maximum
|
|
121
|
+
? maximum - source.length - separator.length
|
|
122
|
+
: Math.floor((maximum - source.length - separator.length - 2 * (remaining - 1)) / remaining);
|
|
123
|
+
// Keep full paths in metadata; long display labels must leave room for each body.
|
|
124
|
+
const pathBudget = Math.max(Math.floor(budget / 2), budget - body.length - 1);
|
|
125
|
+
const label = path.length <= pathBudget
|
|
126
|
+
? path
|
|
127
|
+
: `${path.slice(0, pathBudget - 3).replace(/[\uD800-\uDBFF]$/u, '')}...`;
|
|
128
|
+
const preview = body.slice(0, budget - label.length - 1).replace(/[\uD800-\uDBFF]$/u, '');
|
|
129
|
+
truncated ||= label.length < path.length || preview.length < body.length;
|
|
130
|
+
source += `${separator}${label}\n`;
|
|
131
|
+
const start = source.length;
|
|
132
|
+
source += preview;
|
|
133
|
+
if (!result.error)
|
|
134
|
+
result.contentRange = { start, end: source.length };
|
|
135
|
+
projected.push(result);
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
source,
|
|
139
|
+
summary: source,
|
|
140
|
+
truncated,
|
|
141
|
+
data: { mode: 'batch', results: projected, truncated }
|
|
142
|
+
};
|
|
143
|
+
}
|
|
88
144
|
export class ReadTool {
|
|
89
145
|
paths;
|
|
90
146
|
constructor(paths) {
|
|
@@ -174,6 +174,8 @@ export function publicCodeObservations(values, data) {
|
|
|
174
174
|
export function publicOutputTruncation(toolName, data) {
|
|
175
175
|
if (!isRecord(data))
|
|
176
176
|
return undefined;
|
|
177
|
+
if (toolName === 'read' && data.mode === 'batch' && data.truncated === true)
|
|
178
|
+
return 'SOURCE';
|
|
177
179
|
if (toolName === 'code_exec' || toolName === 'code_exec_wait') {
|
|
178
180
|
if (data.outputSourceTruncated === true)
|
|
179
181
|
return 'SOURCE';
|
|
@@ -300,6 +302,12 @@ export function structuredToolEventData(toolName, value) {
|
|
|
300
302
|
typeof result.path === 'string' &&
|
|
301
303
|
(result.startLine === undefined || isNonnegativeInteger(result.startLine)) &&
|
|
302
304
|
(result.endLine === undefined || isNonnegativeInteger(result.endLine)) &&
|
|
305
|
+
(result.empty === undefined || result.empty === true) &&
|
|
306
|
+
(result.contentRange === undefined ||
|
|
307
|
+
(isRecord(result.contentRange) &&
|
|
308
|
+
isNonnegativeInteger(result.contentRange.start) &&
|
|
309
|
+
isNonnegativeInteger(result.contentRange.end) &&
|
|
310
|
+
result.contentRange.end >= result.contentRange.start)) &&
|
|
303
311
|
(result.error === undefined ||
|
|
304
312
|
(isRecord(result.error) &&
|
|
305
313
|
typeof result.error.code === 'string' &&
|
|
@@ -314,6 +322,8 @@ export function structuredToolEventData(toolName, value) {
|
|
|
314
322
|
? { startLine: item.startLine }
|
|
315
323
|
: {}),
|
|
316
324
|
...('endLine' in item && item.endLine !== undefined ? { endLine: item.endLine } : {}),
|
|
325
|
+
...(item.contentRange === undefined ? {} : { contentRange: { ...item.contentRange } }),
|
|
326
|
+
...(item.empty === true ? { empty: true } : {}),
|
|
317
327
|
...('error' in item ? { error: { ...item.error } } : {})
|
|
318
328
|
}))
|
|
319
329
|
};
|