@myagentroam/agent 0.9.152 → 0.9.153
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/host/contracts.d.ts +1 -1
- package/dist/agent-core/host/local-agent-host.d.ts +1 -6
- package/dist/agent-core/host/local-agent-host.js +13 -14
- package/dist/agent-core/sdk/session.js +4 -6
- package/dist/agent-core/tools/contracts.d.ts +3 -1
- package/dist/agent-core/tools/local/registry.d.ts +1 -7
- package/dist/agent-core/tools/local/registry.js +9 -29
- package/dist/agent-core/tools/registry.js +1 -5
- package/dist/agent-core/tools/runtime-context.d.ts +1 -0
- package/dist/agent-core/tools/runtime.js +1 -0
- package/package.json +1 -1
- package/dist/agent-core/tools/local/web-fetch.d.ts +0 -4
- package/dist/agent-core/tools/local/web-fetch.js +0 -85
- package/dist/agent-core/tools/local/web-search.d.ts +0 -7
- package/dist/agent-core/tools/local/web-search.js +0 -34
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MarAgentEvent } from '../runtime/events.js';
|
|
2
2
|
import type { ClientToolDefinition, McpToolCallContext, McpToolCatalog, McpToolCatalogContext, ToolCall, ToolExecutionContext, ToolExecutionResult } from '../tools/contracts.js';
|
|
3
3
|
export declare const MAR_AGENT_HOST_API_VERSION = "1.0";
|
|
4
|
-
export type MarAgentHostCapability = 'workspace.read' | 'workspace.patch' | 'process.manage' | 'code.execute' | 'user-input.request' | 'event.publish' | 'session.store' | 'mcp.tools' | 'image.read'
|
|
4
|
+
export type MarAgentHostCapability = 'workspace.read' | 'workspace.patch' | 'process.manage' | 'code.execute' | 'user-input.request' | 'event.publish' | 'session.store' | 'mcp.tools' | 'image.read';
|
|
5
5
|
export interface HostDescription {
|
|
6
6
|
apiVersion: string;
|
|
7
7
|
mode: 'normal' | 'node';
|
|
@@ -16,6 +16,7 @@ export interface LocalAgentExecutionMcpBinding extends LocalAgentMcpBinding {
|
|
|
16
16
|
export interface LocalAgentExecutionExtensions extends HostExecutionExtensions {
|
|
17
17
|
/** Host-private process environment, snapshotted when bound to an execution. */
|
|
18
18
|
readonly environment?: Readonly<Record<string, string>>;
|
|
19
|
+
isToolAvailable?(name: string, context: Pick<ToolExecutionContext, 'sessionId' | 'executionId' | 'modelId'>): boolean;
|
|
19
20
|
executeTool?(call: ToolCall, context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
20
21
|
}
|
|
21
22
|
export declare class LocalAgentHost implements MarAgentHost {
|
|
@@ -36,12 +37,6 @@ export declare class LocalAgentHost implements MarAgentHost {
|
|
|
36
37
|
extensions?: LocalAgentExecutionExtensions;
|
|
37
38
|
environment?: NodeJS.ProcessEnv;
|
|
38
39
|
guaranteedCommands?: Readonly<Record<string, string>>;
|
|
39
|
-
webSearch?: (input: {
|
|
40
|
-
query: string;
|
|
41
|
-
maxResults: number;
|
|
42
|
-
}, signal: AbortSignal) => Promise<ToolExecutionResult>;
|
|
43
|
-
webFetch?: boolean;
|
|
44
|
-
allowUntrustedTls?: boolean;
|
|
45
40
|
resourceIdleTtlMs?: number;
|
|
46
41
|
processExecutor?: LocalProcessExecutor;
|
|
47
42
|
codeModeEngineFactory?: CodeModeEngineFactory;
|
|
@@ -25,8 +25,6 @@ export class LocalAgentHost {
|
|
|
25
25
|
#environment;
|
|
26
26
|
#guaranteedCommands;
|
|
27
27
|
#shell;
|
|
28
|
-
#hasWebSearch;
|
|
29
|
-
#hasWebFetch;
|
|
30
28
|
#resourceIdleTtlMs;
|
|
31
29
|
constructor(input) {
|
|
32
30
|
this.#home = resolve(input.homeDirectory);
|
|
@@ -34,15 +32,9 @@ export class LocalAgentHost {
|
|
|
34
32
|
this.#environment = input.environment ?? process.env;
|
|
35
33
|
this.#guaranteedCommands = input.guaranteedCommands ?? {};
|
|
36
34
|
this.#shell = selectExecutionShell(this.#environment);
|
|
37
|
-
this.#hasWebSearch = input.webSearch !== undefined;
|
|
38
|
-
this.#hasWebFetch = input.webFetch !== false;
|
|
39
35
|
this.#resourceIdleTtlMs = input.resourceIdleTtlMs;
|
|
40
36
|
const processExecutor = input.processExecutor ?? directLocalProcessExecutor;
|
|
41
37
|
this.#tools = new LocalToolRegistry(this.#workspace, this.#environment, this.#shell.path, {
|
|
42
|
-
...(input.webSearch ? { webSearch: input.webSearch } : {}),
|
|
43
|
-
webFetch: this.#hasWebFetch,
|
|
44
|
-
allowUntrustedTls: input.allowUntrustedTls ??
|
|
45
|
-
this.#environment['MAR_AGENT_WEB_FETCH_ALLOW_UNTRUSTED_TLS'] === '1',
|
|
46
38
|
...(input.codeModeEngineFactory === undefined
|
|
47
39
|
? {}
|
|
48
40
|
: { codeModeEngineFactory: input.codeModeEngineFactory }),
|
|
@@ -97,9 +89,7 @@ export class LocalAgentHost {
|
|
|
97
89
|
'code.execute',
|
|
98
90
|
'user-input.request',
|
|
99
91
|
'event.publish',
|
|
100
|
-
'session.store'
|
|
101
|
-
...(this.#hasWebFetch ? ['web.fetch'] : []),
|
|
102
|
-
...(this.#hasWebSearch ? ['web.search'] : [])
|
|
92
|
+
'session.store'
|
|
103
93
|
],
|
|
104
94
|
limits: {
|
|
105
95
|
maxProcesses: TOOL_EXECUTION_LIMITS.maxProcesses,
|
|
@@ -113,7 +103,9 @@ export class LocalAgentHost {
|
|
|
113
103
|
const binding = this.#executionMcp.get(context.executionId);
|
|
114
104
|
const extensions = binding?.extensions ?? this.#extensions;
|
|
115
105
|
if (extensions?.tools?.some((tool) => tool.name === call.name)) {
|
|
116
|
-
if (binding?.active === false ||
|
|
106
|
+
if (binding?.active === false ||
|
|
107
|
+
!extensions.executeTool ||
|
|
108
|
+
extensions.isToolAvailable?.(call.name, context) === false)
|
|
117
109
|
throw new MarAgentError('MAR_AGENT_TOOL_INPUT_INVALID', 'Host tool execution is unavailable.');
|
|
118
110
|
context.signal.throwIfAborted();
|
|
119
111
|
return extensions.executeTool(call, context);
|
|
@@ -141,8 +133,15 @@ export class LocalAgentHost {
|
|
|
141
133
|
}
|
|
142
134
|
async listExecutionExtensions(context) {
|
|
143
135
|
const binding = this.#executionBinding(context);
|
|
144
|
-
const { environment: _environment, ...extensions } = binding?.extensions ?? this.#extensions ?? {};
|
|
145
|
-
return
|
|
136
|
+
const { environment: _environment, isToolAvailable, ...extensions } = binding?.extensions ?? this.#extensions ?? {};
|
|
137
|
+
return {
|
|
138
|
+
...extensions,
|
|
139
|
+
...(extensions.tools === undefined
|
|
140
|
+
? {}
|
|
141
|
+
: {
|
|
142
|
+
tools: extensions.tools.filter((tool) => isToolAvailable?.(tool.name, context) !== false)
|
|
143
|
+
})
|
|
144
|
+
};
|
|
146
145
|
}
|
|
147
146
|
emit(event) {
|
|
148
147
|
this.events.push(event);
|
|
@@ -423,6 +423,7 @@ export function createSessionOpener(services) {
|
|
|
423
423
|
const catalogContext = {
|
|
424
424
|
sessionId,
|
|
425
425
|
executionId,
|
|
426
|
+
modelId: selectedModel.id,
|
|
426
427
|
...(sessionSource.type === 'subagent'
|
|
427
428
|
? internal.mcpExecutionScopeId === undefined
|
|
428
429
|
? {}
|
|
@@ -482,12 +483,8 @@ export function createSessionOpener(services) {
|
|
|
482
483
|
? selectedModelForTools.codeMode && description.capabilities.includes('code.execute')
|
|
483
484
|
: tool.name === 'question'
|
|
484
485
|
? mode === 'plan'
|
|
485
|
-
: tool.name
|
|
486
|
-
|
|
487
|
-
description.capabilities.includes('web.search')
|
|
488
|
-
: tool.name === 'view_image'
|
|
489
|
-
? selectedModelForTools.inputCapabilities.includes('IMAGE')
|
|
490
|
-
: tool.name !== 'web_fetch' || description.capabilities.includes('web.fetch');
|
|
486
|
+
: tool.name !== 'view_image' ||
|
|
487
|
+
selectedModelForTools.inputCapabilities.includes('IMAGE');
|
|
491
488
|
};
|
|
492
489
|
mcpRegistry.update(mcpCatalog, (tool) => toolEligible(tool.definition));
|
|
493
490
|
rebindMcpToolSearchOutputs(messages, mcpRegistry);
|
|
@@ -840,6 +837,7 @@ export function createSessionOpener(services) {
|
|
|
840
837
|
mode,
|
|
841
838
|
sessionId,
|
|
842
839
|
executionId,
|
|
840
|
+
modelId: selectedModel.id,
|
|
843
841
|
signal: controller.signal,
|
|
844
842
|
emit,
|
|
845
843
|
skills: instructionContext?.skills ?? new Map()
|
|
@@ -25,6 +25,8 @@ export interface ToolExecutionContext {
|
|
|
25
25
|
signal: AbortSignal;
|
|
26
26
|
sessionId: string;
|
|
27
27
|
executionId: string;
|
|
28
|
+
/** Current model identity for neutral Host-owned tool policies. */
|
|
29
|
+
modelId?: string;
|
|
28
30
|
recentImages?: readonly {
|
|
29
31
|
readonly mimeType: string;
|
|
30
32
|
readonly data: Buffer;
|
|
@@ -39,7 +41,7 @@ export interface ToolExecutionContext {
|
|
|
39
41
|
invoke(call: ToolCall, signal: AbortSignal): Promise<ToolExecutionResult>;
|
|
40
42
|
};
|
|
41
43
|
}
|
|
42
|
-
export interface McpToolCatalogContext extends Pick<ToolExecutionContext, 'sessionId' | 'executionId'> {
|
|
44
|
+
export interface McpToolCatalogContext extends Pick<ToolExecutionContext, 'sessionId' | 'executionId' | 'modelId'> {
|
|
43
45
|
executionScopeId?: string;
|
|
44
46
|
claimExecutionScope?: boolean;
|
|
45
47
|
}
|
|
@@ -4,13 +4,7 @@ import type { ToolCall, ToolExecutionContext, ToolExecutionResult } from '../con
|
|
|
4
4
|
import { type WorkspacePathMount } from '../shared/path-resolver.js';
|
|
5
5
|
export declare class LocalToolRegistry {
|
|
6
6
|
#private;
|
|
7
|
-
constructor(workspace: string, environment?: NodeJS.ProcessEnv, shell?: string,
|
|
8
|
-
webSearch?: (input: {
|
|
9
|
-
query: string;
|
|
10
|
-
maxResults: number;
|
|
11
|
-
}, signal: AbortSignal) => Promise<ToolExecutionResult>;
|
|
12
|
-
webFetch?: boolean;
|
|
13
|
-
allowUntrustedTls?: boolean;
|
|
7
|
+
constructor(workspace: string, environment?: NodeJS.ProcessEnv, shell?: string, options?: {
|
|
14
8
|
processExecutor?: LocalProcessExecutor;
|
|
15
9
|
codeModeEngineFactory?: CodeModeEngineFactory;
|
|
16
10
|
restrictPaths?: boolean;
|
|
@@ -3,25 +3,25 @@ import { ApplyPatchTool, applyPatchToolInput } from './apply-patch.js';
|
|
|
3
3
|
import { CodeModeTool } from '../code-mode/index.js';
|
|
4
4
|
import { ExecTool, execToolInput } from './exec.js';
|
|
5
5
|
import { ReadTool, formatBatchReadOutput } from './read.js';
|
|
6
|
-
import { executeWebFetch } from './web-fetch.js';
|
|
7
|
-
import { executeWebSearch } from './web-search.js';
|
|
8
6
|
import { WorkspacePathResolver } from '../shared/path-resolver.js';
|
|
9
7
|
import { ViewImageTool } from './view-image.js';
|
|
10
8
|
export class LocalToolRegistry {
|
|
11
9
|
#exec;
|
|
12
10
|
#code;
|
|
13
11
|
#handlers;
|
|
14
|
-
constructor(workspace, environment = process.env, shell,
|
|
12
|
+
constructor(workspace, environment = process.env, shell, options = {}) {
|
|
15
13
|
const paths = new WorkspacePathResolver(workspace, {
|
|
16
|
-
...(
|
|
17
|
-
...(
|
|
18
|
-
|
|
14
|
+
...(options.restrictPaths === undefined ? {} : { restrictPaths: options.restrictPaths }),
|
|
15
|
+
...(options.workspaceWritable === undefined
|
|
16
|
+
? {}
|
|
17
|
+
: { rootWritable: options.workspaceWritable }),
|
|
18
|
+
...(options.pathMounts === undefined ? {} : { mounts: options.pathMounts })
|
|
19
19
|
});
|
|
20
20
|
const read = new ReadTool(paths);
|
|
21
21
|
const viewImage = new ViewImageTool(paths);
|
|
22
22
|
const patch = new ApplyPatchTool(paths);
|
|
23
|
-
this.#exec = new ExecTool(paths, undefined, undefined, environment, shell,
|
|
24
|
-
this.#code = new CodeModeTool(paths, environment,
|
|
23
|
+
this.#exec = new ExecTool(paths, undefined, undefined, environment, shell, options.processExecutor);
|
|
24
|
+
this.#code = new CodeModeTool(paths, environment, options.processExecutor, options.codeModeEngineFactory);
|
|
25
25
|
this.#handlers = new Map([
|
|
26
26
|
['code_exec', (arguments_, context) => this.#code.start(arguments_, context)],
|
|
27
27
|
['code_exec_wait', (arguments_, context) => this.#code.wait(arguments_, context)],
|
|
@@ -57,27 +57,7 @@ export class LocalToolRegistry {
|
|
|
57
57
|
});
|
|
58
58
|
return { content: JSON.stringify(result), data: result, truncated: result.truncated };
|
|
59
59
|
}
|
|
60
|
-
])
|
|
61
|
-
...(web.webSearch
|
|
62
|
-
? [
|
|
63
|
-
[
|
|
64
|
-
'web_search',
|
|
65
|
-
async (arguments_, context) => {
|
|
66
|
-
return executeWebSearch(arguments_, context.signal, (input, signal) => web.webSearch(input, signal));
|
|
67
|
-
}
|
|
68
|
-
]
|
|
69
|
-
]
|
|
70
|
-
: []),
|
|
71
|
-
...(web.webFetch === false
|
|
72
|
-
? []
|
|
73
|
-
: [
|
|
74
|
-
[
|
|
75
|
-
'web_fetch',
|
|
76
|
-
async (arguments_, context) => {
|
|
77
|
-
return executeWebFetch(arguments_, context.signal, web.allowUntrustedTls === true);
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
])
|
|
60
|
+
])
|
|
81
61
|
]);
|
|
82
62
|
}
|
|
83
63
|
execute(call, context) {
|
|
@@ -12,8 +12,6 @@ import { executeTodoRead, todoReadToolDefinition } from './agent/todo-read.js';
|
|
|
12
12
|
import { executeTodoWrite, todoWriteToolDefinition } from './agent/todo-write.js';
|
|
13
13
|
import { executeToolSearch, toolSearchToolDefinition } from './mcp/tool-search.js';
|
|
14
14
|
import { viewImageToolDefinition } from './local/view-image.js';
|
|
15
|
-
import { webFetchToolDefinition } from './local/web-fetch.js';
|
|
16
|
-
import { webSearchToolDefinition } from './local/web-search.js';
|
|
17
15
|
export const BUILTIN_TOOL_DEFINITIONS = [
|
|
18
16
|
skillToolDefinition,
|
|
19
17
|
toolSearchToolDefinition,
|
|
@@ -30,9 +28,7 @@ export const BUILTIN_TOOL_DEFINITIONS = [
|
|
|
30
28
|
agentStartToolDefinition,
|
|
31
29
|
agentWaitToolDefinition,
|
|
32
30
|
agentMessageToolDefinition,
|
|
33
|
-
agentCancelToolDefinition
|
|
34
|
-
webSearchToolDefinition,
|
|
35
|
-
webFetchToolDefinition
|
|
31
|
+
agentCancelToolDefinition
|
|
36
32
|
];
|
|
37
33
|
export const AGENT_TOOL_HANDLERS = new Map([
|
|
38
34
|
['skill', executeSkill],
|
|
@@ -44,6 +44,7 @@ export interface ToolRuntimeContext {
|
|
|
44
44
|
mode: ExecutionMode;
|
|
45
45
|
sessionId: string;
|
|
46
46
|
executionId: string;
|
|
47
|
+
modelId?: string;
|
|
47
48
|
signal: AbortSignal;
|
|
48
49
|
codeMode?: import('./contracts.js').ToolExecutionContext['codeMode'];
|
|
49
50
|
skills: ReadonlyMap<string, AgentSkill>;
|
|
@@ -20,6 +20,7 @@ export async function executeRegisteredTool(name, arguments_, callId, context) {
|
|
|
20
20
|
signal: context.signal,
|
|
21
21
|
sessionId: context.sessionId,
|
|
22
22
|
executionId: context.executionId,
|
|
23
|
+
...(context.modelId === undefined ? {} : { modelId: context.modelId }),
|
|
23
24
|
...(context.recentImages === undefined ? {} : { recentImages: context.recentImages }),
|
|
24
25
|
...(context.codeMode === undefined ? {} : { codeMode: context.codeMode })
|
|
25
26
|
});
|
package/package.json
CHANGED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ToolExecutionResult } from '../contracts.js';
|
|
2
|
-
import type { ClientToolDefinition } from '../../model/contracts.js';
|
|
3
|
-
export declare const webFetchToolDefinition: ClientToolDefinition;
|
|
4
|
-
export declare function executeWebFetch(input: unknown, signal: AbortSignal, allowUntrustedTls?: boolean): Promise<ToolExecutionResult>;
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { request as httpRequest } from 'node:http';
|
|
2
|
-
import { request as httpsRequest } from 'node:https';
|
|
3
|
-
import { MarAgentError } from '../../error.js';
|
|
4
|
-
export const webFetchToolDefinition = {
|
|
5
|
-
name: 'web_fetch',
|
|
6
|
-
allowedCallers: ['direct', 'programmatic'],
|
|
7
|
-
parallelSafety: 'safe',
|
|
8
|
-
description: 'Fetch a specific HTTP or HTTPS URL, including explicitly permitted intranet URLs.',
|
|
9
|
-
inputSchema: {
|
|
10
|
-
type: 'object',
|
|
11
|
-
properties: { url: { type: 'string' } },
|
|
12
|
-
required: ['url'],
|
|
13
|
-
additionalProperties: false
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
export async function executeWebFetch(input, signal, allowUntrustedTls = false) {
|
|
17
|
-
const value = input;
|
|
18
|
-
if (typeof value?.url !== 'string')
|
|
19
|
-
throw new MarAgentError('MAR_AGENT_TOOL_INPUT_INVALID', 'URL is required.');
|
|
20
|
-
let url;
|
|
21
|
-
try {
|
|
22
|
-
url = new URL(value.url);
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
throw new MarAgentError('MAR_AGENT_TOOL_INPUT_INVALID', 'URL is invalid.');
|
|
26
|
-
}
|
|
27
|
-
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
28
|
-
throw new MarAgentError('MAR_AGENT_TOOL_INPUT_INVALID', 'Only HTTP and HTTPS URLs are supported.');
|
|
29
|
-
return fetchWebUrl(url, signal, allowUntrustedTls);
|
|
30
|
-
}
|
|
31
|
-
async function fetchWebUrl(url, signal, allowUntrustedTls, redirects = 0) {
|
|
32
|
-
if (redirects > 5)
|
|
33
|
-
throw new MarAgentError('MAR_AGENT_WEB_FETCH_FAILED', 'Too many redirects.');
|
|
34
|
-
return new Promise((resolve, reject) => {
|
|
35
|
-
const request = (url.protocol === 'https:' ? httpsRequest : httpRequest)(url, {
|
|
36
|
-
signal,
|
|
37
|
-
headers: {
|
|
38
|
-
accept: 'text/html,application/json,text/plain;q=0.9,*/*;q=0.1',
|
|
39
|
-
'accept-encoding': 'identity',
|
|
40
|
-
'user-agent': 'MyAgentRoam/0.9'
|
|
41
|
-
},
|
|
42
|
-
...(url.protocol === 'https:' ? { rejectUnauthorized: !allowUntrustedTls } : {})
|
|
43
|
-
}, (response) => {
|
|
44
|
-
const status = response.statusCode ?? 0;
|
|
45
|
-
if (status >= 300 && status < 400 && response.headers.location) {
|
|
46
|
-
response.resume();
|
|
47
|
-
void fetchWebUrl(new URL(response.headers.location, url), signal, allowUntrustedTls, redirects + 1).then(resolve, reject);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
if (status < 200 || status >= 300) {
|
|
51
|
-
response.resume();
|
|
52
|
-
reject(new MarAgentError('MAR_AGENT_WEB_FETCH_FAILED', `HTTP ${status}.`));
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const contentType = String(response.headers['content-type'] ?? 'text/plain').toLowerCase();
|
|
56
|
-
if (!/^(text\/|application\/(json|xml|xhtml\+xml))/u.test(contentType)) {
|
|
57
|
-
response.resume();
|
|
58
|
-
reject(new MarAgentError('MAR_AGENT_WEB_FETCH_UNSUPPORTED_CONTENT', 'Response is not readable text.'));
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
const chunks = [];
|
|
62
|
-
let bytes = 0;
|
|
63
|
-
let truncated = false;
|
|
64
|
-
response.on('data', (chunk) => {
|
|
65
|
-
if (bytes >= 1_000_000) {
|
|
66
|
-
truncated = true;
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const remaining = 1_000_000 - bytes;
|
|
70
|
-
chunks.push(chunk.subarray(0, remaining));
|
|
71
|
-
bytes += Math.min(chunk.length, remaining);
|
|
72
|
-
if (chunk.length > remaining)
|
|
73
|
-
truncated = true;
|
|
74
|
-
});
|
|
75
|
-
response.on('end', () => resolve({
|
|
76
|
-
content: Buffer.concat(chunks).toString('utf8'),
|
|
77
|
-
data: { url: url.href, status },
|
|
78
|
-
truncated
|
|
79
|
-
}));
|
|
80
|
-
response.on('error', reject);
|
|
81
|
-
});
|
|
82
|
-
request.on('error', reject);
|
|
83
|
-
request.end();
|
|
84
|
-
});
|
|
85
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ClientToolDefinition } from '../../model/contracts.js';
|
|
2
|
-
import type { ToolExecutionResult } from '../contracts.js';
|
|
3
|
-
export declare const webSearchToolDefinition: ClientToolDefinition;
|
|
4
|
-
export declare function executeWebSearch(input: unknown, signal: AbortSignal, search: (input: {
|
|
5
|
-
query: string;
|
|
6
|
-
maxResults: number;
|
|
7
|
-
}, signal: AbortSignal) => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { MarAgentError } from '../../error.js';
|
|
2
|
-
export const webSearchToolDefinition = {
|
|
3
|
-
name: 'web_search',
|
|
4
|
-
allowedCallers: ['direct', 'programmatic'],
|
|
5
|
-
parallelSafety: 'safe',
|
|
6
|
-
description: 'Search the web for current information. Use web_fetch to open a specific result.',
|
|
7
|
-
inputSchema: {
|
|
8
|
-
type: 'object',
|
|
9
|
-
properties: {
|
|
10
|
-
query: { type: 'string', description: 'Search query.' },
|
|
11
|
-
maxResults: { type: 'integer', minimum: 1, maximum: 10, default: 8 }
|
|
12
|
-
},
|
|
13
|
-
required: ['query'],
|
|
14
|
-
additionalProperties: false
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
export async function executeWebSearch(input, signal, search) {
|
|
18
|
-
const value = input;
|
|
19
|
-
if (typeof value?.query !== 'string' || value.query.trim().length === 0)
|
|
20
|
-
throw new MarAgentError('MAR_AGENT_TOOL_INPUT_INVALID', 'Search query is required.');
|
|
21
|
-
try {
|
|
22
|
-
return await search({
|
|
23
|
-
query: value.query.trim(),
|
|
24
|
-
maxResults: typeof value.maxResults === 'number'
|
|
25
|
-
? Math.min(10, Math.max(1, Math.trunc(value.maxResults)))
|
|
26
|
-
: 8
|
|
27
|
-
}, signal);
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
if (error instanceof MarAgentError)
|
|
31
|
-
throw error;
|
|
32
|
-
throw new MarAgentError('MAR_AGENT_WEB_SEARCH_FAILED', 'Web search failed.', { cause: error });
|
|
33
|
-
}
|
|
34
|
-
}
|