@robota-sdk/agent-tools 3.0.0-beta.7 → 3.0.0-beta.71
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 +93 -19
- package/dist/browser/browser.d.ts +252 -0
- package/dist/browser/browser.d.ts.map +1 -0
- package/dist/browser/browser.js +2 -0
- package/dist/browser/browser.js.map +1 -0
- package/dist/node/index.cjs +1396 -1438
- package/dist/node/index.d.ts +322 -255
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +1361 -1395
- package/dist/node/index.js.map +1 -0
- package/package.json +21 -5
- package/dist/node/index.d.cts +0 -370
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["DEFAULT_TIMEOUT_MS","DEFAULT_LIMIT","DEFAULT_TIMEOUT_MS"],"sources":["../../src/sandbox/e2b-sandbox-client.ts","../../src/sandbox/in-memory-sandbox-client.ts","../../src/sandbox/workspace-manifest.ts","../../src/registry/tool-registry.ts","../../src/implementations/function-tool/parameter-validator.ts","../../src/implementations/function-tool/schema-converter.ts","../../src/implementations/function-tool.ts","../../src/builtins/bash-tool.ts","../../src/builtins/path-guard.ts","../../src/builtins/read-tool.ts","../../src/builtins/atomic-file-write.ts","../../src/builtins/write-tool.ts","../../src/builtins/edit-tool.ts","../../src/builtins/glob-tool.ts","../../src/builtins/grep-tool.ts","../../src/builtins/web-fetch-tool.ts","../../src/builtins/web-search-tool.ts"],"sourcesContent":["import type { ISandboxClient, ISandboxRunOptions, ISandboxRunResult } from './types.js';\n\ninterface IE2BCommandStartOptions {\n timeoutMs?: number;\n cwd?: string;\n background?: false;\n}\n\ninterface IE2BCommandResult {\n stdout?: string;\n stderr?: string;\n exitCode?: number;\n exit_code?: number;\n}\n\ninterface IE2BCommands {\n run(command: string, options?: IE2BCommandStartOptions): Promise<IE2BCommandResult>;\n}\n\ninterface IE2BFiles {\n read(path: string): Promise<string | Uint8Array>;\n write(path: string, content: string): Promise<void>;\n}\n\ninterface IE2BSnapshot {\n snapshotId?: string;\n id?: string;\n}\n\nexport interface IE2BSandboxAdapter {\n sandboxId?: string;\n commands: IE2BCommands;\n files: IE2BFiles;\n pause?(): Promise<boolean | string | void>;\n connect?(): Promise<IE2BSandboxAdapter>;\n createSnapshot?(): Promise<IE2BSnapshot>;\n}\n\nexport interface IE2BSandboxClientOptions {\n sandbox: IE2BSandboxAdapter;\n connectSandbox?: (sandboxId: string) => Promise<IE2BSandboxAdapter>;\n createSandboxFromSnapshot?: (snapshotId: string) => Promise<IE2BSandboxAdapter>;\n}\n\nexport class E2BSandboxClient implements ISandboxClient {\n private sandbox: IE2BSandboxAdapter;\n private readonly connectSandbox?: (sandboxId: string) => Promise<IE2BSandboxAdapter>;\n private readonly createSandboxFromSnapshot?: (snapshotId: string) => Promise<IE2BSandboxAdapter>;\n\n constructor(options: IE2BSandboxClientOptions) {\n this.sandbox = options.sandbox;\n this.connectSandbox = options.connectSandbox;\n this.createSandboxFromSnapshot = options.createSandboxFromSnapshot;\n }\n\n async run(command: string, options?: ISandboxRunOptions): Promise<ISandboxRunResult> {\n const result = await this.sandbox.commands.run(command, {\n background: false,\n timeoutMs: options?.timeoutMs,\n cwd: options?.workingDirectory,\n });\n\n return {\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n exitCode: result.exitCode ?? result.exit_code ?? 0,\n };\n }\n\n async readFile(path: string): Promise<string> {\n const content = await this.sandbox.files.read(path);\n return typeof content === 'string' ? content : Buffer.from(content).toString('utf8');\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n await this.sandbox.files.write(path, content);\n }\n\n async snapshot(): Promise<string> {\n if (this.sandbox.createSnapshot) {\n const snapshot = await this.sandbox.createSnapshot();\n const snapshotId = snapshot.snapshotId ?? snapshot.id;\n if (!snapshotId) {\n throw new Error('E2B createSnapshot() did not return a snapshot id.');\n }\n return snapshotId;\n }\n const sandboxId = this.sandbox.sandboxId;\n if (!sandboxId) {\n throw new Error('E2B sandboxId is required to create a resumable sandbox snapshot.');\n }\n if (!this.sandbox.pause) {\n throw new Error('E2B sandbox adapter does not expose pause().');\n }\n await this.sandbox.pause();\n return sandboxId;\n }\n\n async restore(snapshotId: string): Promise<void> {\n if (this.createSandboxFromSnapshot) {\n this.sandbox = await this.createSandboxFromSnapshot(snapshotId);\n return;\n }\n if (this.connectSandbox) {\n this.sandbox = await this.connectSandbox(snapshotId);\n return;\n }\n if (this.sandbox.sandboxId === snapshotId && this.sandbox.connect) {\n this.sandbox = await this.sandbox.connect();\n return;\n }\n throw new Error(\n 'E2B sandbox restore requires connectSandbox(snapshotId) or sandbox.connect().',\n );\n }\n}\n","import type { ISandboxClient, ISandboxRunOptions, ISandboxRunResult } from './types.js';\n\nexport type TInMemorySandboxRunHandler = (\n command: string,\n options: ISandboxRunOptions | undefined,\n files: ReadonlyMap<string, string>,\n) => Promise<ISandboxRunResult> | ISandboxRunResult;\n\nexport interface IInMemorySandboxClientOptions {\n files?: Record<string, string>;\n runHandler?: TInMemorySandboxRunHandler;\n}\n\nexport class InMemorySandboxClient implements ISandboxClient {\n private readonly files = new Map<string, string>();\n private readonly snapshots = new Map<string, Map<string, string>>();\n private readonly runHandler?: TInMemorySandboxRunHandler;\n private snapshotSequence = 0;\n\n constructor(options: IInMemorySandboxClientOptions = {}) {\n for (const [path, content] of Object.entries(options.files ?? {})) {\n this.files.set(path, content);\n }\n this.runHandler = options.runHandler;\n }\n\n async run(command: string, options?: ISandboxRunOptions): Promise<ISandboxRunResult> {\n if (this.runHandler) {\n return this.runHandler(command, options, this.files);\n }\n return { stdout: '', stderr: '', exitCode: 0 };\n }\n\n async readFile(path: string): Promise<string> {\n const content = this.files.get(path);\n if (content === undefined) {\n throw new Error(`Sandbox file not found: ${path}`);\n }\n return content;\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n this.files.set(path, content);\n }\n\n async snapshot(): Promise<string> {\n const snapshotId = `snapshot-${++this.snapshotSequence}`;\n this.snapshots.set(snapshotId, new Map(this.files));\n return snapshotId;\n }\n\n async restore(snapshotId: string): Promise<void> {\n const snapshot = this.snapshots.get(snapshotId);\n if (!snapshot) {\n throw new Error(`Sandbox snapshot not found: ${snapshotId}`);\n }\n this.files.clear();\n for (const [path, content] of snapshot.entries()) {\n this.files.set(path, content);\n }\n }\n\n getFile(path: string): string | undefined {\n return this.files.get(path);\n }\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { isAbsolute, join, posix, resolve } from 'node:path';\n\nimport type {\n ISandboxClient,\n IWorkspaceManifest,\n IWorkspaceManifestAppliedEntry,\n IWorkspaceManifestApplyOptions,\n IWorkspaceManifestApplyResult,\n TWorkspaceManifestEntry,\n} from './types.js';\n\nconst DEFAULT_TARGET_ROOT = '/workspace';\nconst WINDOWS_ABSOLUTE_PATH_PATTERN = /^[A-Za-z]:[\\\\/]/;\nconst SHELL_QUOTE_PATTERN = /'/g;\n\nexport async function applyWorkspaceManifest(\n sandboxClient: ISandboxClient,\n manifest: IWorkspaceManifest,\n options: IWorkspaceManifestApplyOptions = {},\n): Promise<IWorkspaceManifestApplyResult> {\n if (sandboxClient.applyManifest) {\n return sandboxClient.applyManifest(manifest, options);\n }\n\n const targetRoot = normalizeSandboxRoot(options.targetRoot ?? DEFAULT_TARGET_ROOT);\n const appliedEntries: IWorkspaceManifestAppliedEntry[] = [];\n\n for (const [rawPath, entry] of Object.entries(manifest.entries)) {\n const path = validateWorkspaceManifestPath(rawPath);\n const targetPath = joinSandboxPath(targetRoot, path);\n appliedEntries.push(\n await applyManifestEntry(sandboxClient, path, targetPath, targetRoot, entry, options),\n );\n }\n\n return { entries: appliedEntries };\n}\n\nexport function validateWorkspaceManifestPath(path: string): string {\n if (path.length === 0) {\n throw new Error('workspace manifest path must not be empty');\n }\n if (path.includes('\\0')) {\n throw new Error('workspace manifest path must not contain NUL bytes');\n }\n if (path.startsWith('/') || path.startsWith('\\\\') || WINDOWS_ABSOLUTE_PATH_PATTERN.test(path)) {\n throw new Error('workspace manifest path must be workspace-relative');\n }\n\n const parts = path.replace(/\\\\/g, '/').split('/').filter(Boolean);\n if (parts.length === 0) {\n throw new Error('workspace manifest path must not resolve to the workspace root');\n }\n if (parts.some((part) => part === '..')) {\n throw new Error('workspace manifest path cannot contain traversal segments');\n }\n\n const normalizedParts = parts.filter((part) => part !== '.');\n if (normalizedParts.length === 0) {\n throw new Error('workspace manifest path must not resolve to the workspace root');\n }\n\n return normalizedParts.join('/');\n}\n\nasync function applyManifestEntry(\n sandboxClient: ISandboxClient,\n path: string,\n targetPath: string,\n targetRoot: string,\n entry: TWorkspaceManifestEntry,\n options: IWorkspaceManifestApplyOptions,\n): Promise<IWorkspaceManifestAppliedEntry> {\n switch (entry.type) {\n case 'file':\n await writeSandboxFile(sandboxClient, targetPath, targetRoot, entry.content);\n return createAppliedEntry(path, entry.type);\n case 'dir':\n await createSandboxDirectory(sandboxClient, targetPath);\n return createAppliedEntry(path, entry.type);\n case 'localFile':\n await copyLocalFile(sandboxClient, entry.src, targetPath, targetRoot, options);\n return createAppliedEntry(path, entry.type);\n case 'localDir':\n await copyLocalDirectory(sandboxClient, entry.src, targetPath, options);\n return createAppliedEntry(path, entry.type);\n case 'gitRepo':\n await cloneGitRepository(sandboxClient, entry, targetPath);\n return createAppliedEntry(path, entry.type);\n case 's3Mount':\n case 'gcsMount':\n case 'r2Mount':\n case 'azureBlobMount':\n return {\n path,\n type: entry.type,\n status: 'unsupported',\n message: `${entry.type} requires a provider-specific sandbox adapter.`,\n };\n default:\n return assertUnreachable(entry);\n }\n}\n\nfunction createAppliedEntry(\n path: string,\n type: TWorkspaceManifestEntry['type'],\n): IWorkspaceManifestAppliedEntry {\n return { path, type, status: 'applied' };\n}\n\nasync function copyLocalFile(\n sandboxClient: ISandboxClient,\n source: string,\n targetPath: string,\n targetRoot: string,\n options: IWorkspaceManifestApplyOptions,\n): Promise<void> {\n const hostSourcePath = resolveHostSourcePath(source, options.hostRoot);\n const content = await readFile(hostSourcePath, 'utf8');\n await writeSandboxFile(sandboxClient, targetPath, targetRoot, content);\n}\n\nasync function copyLocalDirectory(\n sandboxClient: ISandboxClient,\n source: string,\n targetPath: string,\n options: IWorkspaceManifestApplyOptions,\n): Promise<void> {\n const hostSourcePath = resolveHostSourcePath(source, options.hostRoot);\n await copyLocalDirectoryRecursive(sandboxClient, hostSourcePath, targetPath);\n}\n\nasync function copyLocalDirectoryRecursive(\n sandboxClient: ISandboxClient,\n sourcePath: string,\n targetPath: string,\n): Promise<void> {\n await createSandboxDirectory(sandboxClient, targetPath);\n const entries = await readdir(sourcePath, { withFileTypes: true });\n\n for (const entry of entries) {\n const childSourcePath = join(sourcePath, entry.name);\n const childTargetPath = joinSandboxPath(targetPath, entry.name);\n if (entry.isDirectory()) {\n await copyLocalDirectoryRecursive(sandboxClient, childSourcePath, childTargetPath);\n continue;\n }\n if (entry.isFile()) {\n const content = await readFile(childSourcePath, 'utf8');\n await sandboxClient.writeFile(childTargetPath, content);\n }\n }\n}\n\nasync function cloneGitRepository(\n sandboxClient: ISandboxClient,\n entry: Extract<TWorkspaceManifestEntry, { type: 'gitRepo' }>,\n targetPath: string,\n): Promise<void> {\n const shallowArgs = entry.shallow === false ? '' : ' --depth 1';\n const refArgs = entry.ref ? ` --branch ${quoteShellArg(entry.ref)}` : '';\n await runSandboxCommand(\n sandboxClient,\n `git clone${shallowArgs}${refArgs} ${quoteShellArg(entry.url)} ${quoteShellArg(targetPath)}`,\n );\n}\n\nasync function writeSandboxFile(\n sandboxClient: ISandboxClient,\n targetPath: string,\n targetRoot: string,\n content: string,\n): Promise<void> {\n const parentPath = posix.dirname(targetPath);\n if (parentPath !== targetRoot) {\n await createSandboxDirectory(sandboxClient, parentPath);\n }\n await sandboxClient.writeFile(targetPath, content);\n}\n\nasync function createSandboxDirectory(\n sandboxClient: ISandboxClient,\n targetPath: string,\n): Promise<void> {\n await runSandboxCommand(sandboxClient, `mkdir -p ${quoteShellArg(targetPath)}`);\n}\n\nasync function runSandboxCommand(sandboxClient: ISandboxClient, command: string): Promise<void> {\n const result = await sandboxClient.run(command);\n if (result.exitCode !== 0) {\n throw new Error(\n `workspace manifest command failed: ${command}\\n${result.stderr ?? result.stdout}`,\n );\n }\n}\n\nfunction resolveHostSourcePath(source: string, hostRoot: string | undefined): string {\n return isAbsolute(source) ? resolve(source) : resolve(hostRoot ?? process.cwd(), source);\n}\n\nfunction normalizeSandboxRoot(root: string): string {\n const normalized = root.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n if (!normalized.startsWith('/')) {\n throw new Error('workspace manifest targetRoot must be an absolute sandbox path');\n }\n return normalized.length === 0 ? '/' : normalized;\n}\n\nfunction joinSandboxPath(root: string, path: string): string {\n const normalizedRoot = normalizeSandboxRoot(root);\n if (normalizedRoot === '/') {\n return `/${path}`;\n }\n return `${normalizedRoot}/${path}`;\n}\n\nfunction quoteShellArg(value: string): string {\n return `'${value.replace(SHELL_QUOTE_PATTERN, \"'\\\\''\")}'`;\n}\n\nfunction assertUnreachable(value: never): never {\n throw new Error(`unsupported workspace manifest entry: ${JSON.stringify(value)}`);\n}\n","import { ValidationError } from '@robota-sdk/agent-core';\nimport { logger } from '@robota-sdk/agent-core';\n\nimport type { ITool, IToolRegistry } from '@robota-sdk/agent-core';\nimport type { IToolSchema } from '@robota-sdk/agent-core';\n\n/**\n * Tool registry implementation\n * Manages tool registration, validation, and retrieval\n */\nexport class ToolRegistry implements IToolRegistry {\n private tools = new Map<string, ITool>();\n\n /**\n * Register a tool\n */\n register(tool: ITool): void {\n if (!tool.schema?.name) {\n throw new ValidationError('Tool must have a valid schema with name');\n }\n\n const toolName = tool.schema.name;\n\n // Validate tool schema\n this.validateToolSchema(tool.schema);\n\n // Check for duplicate registration\n if (this.tools.has(toolName)) {\n logger.warn(`Tool \"${toolName}\" is already registered, overriding`, {\n toolName,\n existingTool: this.tools.get(toolName)?.constructor.name,\n });\n }\n\n this.tools.set(toolName, tool);\n logger.debug(`Tool \"${toolName}\" registered successfully`, {\n toolName,\n toolType: tool.constructor.name,\n parameters: Object.keys(tool.schema.parameters?.properties || {}),\n });\n }\n\n /**\n * Unregister a tool\n */\n unregister(name: string): void {\n if (!this.tools.has(name)) {\n logger.warn(`Attempted to unregister non-existent tool \"${name}\"`);\n return;\n }\n\n this.tools.delete(name);\n logger.debug(`Tool \"${name}\" unregistered successfully`);\n }\n\n /**\n * Get tool by name\n */\n get(name: string): ITool | undefined {\n return this.tools.get(name);\n }\n\n /**\n * Get all registered tools\n */\n getAll(): ITool[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * Get tool schemas\n */\n getSchemas(): IToolSchema[] {\n const tools = this.getAll();\n\n // 🔍 [TOOL-FLOW] ToolRegistry.getSchemas() - Extracting schemas from tools\n logger.debug('[TOOL-FLOW] ToolRegistry.getSchemas() - Tools before schema extraction', {\n count: tools.length,\n tools: tools.map((t) => ({\n name: t.schema?.name ?? 'unnamed',\n hasSchema: !!t.schema,\n schemaType: typeof t.schema,\n toolType: t.constructor?.name || 'unknown',\n })),\n });\n\n return this.getAll().map((tool) => tool.schema);\n }\n\n /**\n * Check if tool exists\n */\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n /**\n * Clear all tools\n */\n clear(): void {\n const toolCount = this.tools.size;\n this.tools.clear();\n logger.debug(`Cleared ${toolCount} tools from registry`);\n }\n\n /**\n * Get tool names\n */\n getToolNames(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /**\n * Get tools by pattern\n */\n getToolsByPattern(pattern: string | RegExp): ITool[] {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n return this.getAll().filter((tool) => regex.test(tool.schema.name));\n }\n\n /**\n * Get tool count\n */\n size(): number {\n return this.tools.size;\n }\n\n /**\n * Validate tool schema\n */\n private validateToolSchema(schema: IToolSchema): void {\n if (!schema.name || typeof schema.name !== 'string') {\n throw new ValidationError('Tool schema must have a valid name');\n }\n\n if (!schema.description || typeof schema.description !== 'string') {\n throw new ValidationError('Tool schema must have a description');\n }\n\n if (\n !schema.parameters ||\n typeof schema.parameters !== 'object' ||\n schema.parameters === null ||\n Array.isArray(schema.parameters)\n ) {\n throw new ValidationError('Tool schema must have parameters object');\n }\n\n if (schema.parameters.type !== 'object') {\n throw new ValidationError('Tool parameters type must be \"object\"');\n }\n\n // Validate parameter properties\n if (schema.parameters.properties) {\n for (const propName of Object.keys(schema.parameters.properties)) {\n const propSchema = schema.parameters.properties[propName];\n if (!propSchema?.type) {\n throw new ValidationError(`Parameter \"${propName}\" must have a type`);\n }\n\n const validTypes = ['string', 'number', 'boolean', 'array', 'object'];\n if (!validTypes.includes(propSchema.type)) {\n throw new ValidationError(\n `Parameter \"${propName}\" has invalid type \"${propSchema.type}\"`,\n );\n }\n }\n }\n\n // Validate required fields exist in properties\n if (schema.parameters.required) {\n const properties = schema.parameters.properties || {};\n for (const requiredField of schema.parameters.required) {\n if (!properties[requiredField]) {\n throw new ValidationError(\n `Required parameter \"${requiredField}\" is not defined in properties`,\n );\n }\n }\n }\n }\n}\n","import type {\n IParameterSchema,\n TToolParameters,\n IParameterValidationResult,\n} from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\n/**\n * Validate individual parameter type against its schema.\n * Returns an error string if invalid, undefined if valid.\n */\nexport function validateParameterType(\n key: string,\n value: TUniversalValue,\n schema: IParameterSchema,\n): string | undefined {\n const expectedType = schema['type'];\n\n switch (expectedType) {\n case 'string':\n if (typeof value !== 'string') {\n return `Parameter \"${key}\" must be a string, got ${typeof value}`;\n }\n break;\n\n case 'number':\n if (typeof value !== 'number' || isNaN(value)) {\n return `Parameter \"${key}\" must be a number, got ${typeof value}`;\n }\n break;\n\n case 'boolean':\n if (typeof value !== 'boolean') {\n return `Parameter \"${key}\" must be a boolean, got ${typeof value}`;\n }\n break;\n\n case 'array':\n if (!Array.isArray(value)) {\n return `Parameter \"${key}\" must be an array, got ${typeof value}`;\n }\n // Check array items if specified\n if (schema.items) {\n for (let i = 0; i < value.length; i++) {\n const itemError = validateParameterType(`${key}[${i}]`, value[i], schema.items);\n if (itemError) {\n return itemError;\n }\n }\n }\n break;\n\n case 'object':\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return `Parameter \"${key}\" must be an object, got ${typeof value}`;\n }\n break;\n }\n\n // Check enum constraints\n if (schema.enum && schema.enum.length > 0) {\n const enumValues = schema.enum;\n let isValidEnum = false;\n\n // Type-safe enum checking based on JSONSchemaEnum type\n for (const enumValue of enumValues) {\n if (value === enumValue) {\n isValidEnum = true;\n break;\n }\n }\n\n if (!isValidEnum) {\n return `Parameter \"${key}\" must be one of: ${enumValues.join(', ')}, got ${value}`;\n }\n }\n\n return undefined;\n}\n\n/**\n * Collect all validation errors for the given parameters against a schema.\n */\nexport function getValidationErrors(\n parameters: TToolParameters,\n schemaRequired: string[],\n schemaProperties: Record<string, IParameterSchema>,\n additionalProperties?: boolean | IParameterSchema,\n): string[] {\n const errors: string[] = [];\n\n // Check required parameters\n for (const field of schemaRequired) {\n if (!(field in parameters)) {\n errors.push(`Missing required parameter: ${field}`);\n }\n }\n\n // Check parameter types and constraints\n for (const [key, value] of Object.entries(parameters)) {\n const paramSchema = schemaProperties[key];\n if (!paramSchema) {\n if (additionalProperties === true) {\n continue;\n }\n if (additionalProperties && typeof additionalProperties === 'object') {\n const additionalTypeError = validateParameterType(key, value, additionalProperties);\n if (additionalTypeError) errors.push(additionalTypeError);\n continue;\n }\n errors.push(`Unknown parameter: ${key}`);\n continue;\n }\n\n const typeError = validateParameterType(key, value, paramSchema);\n if (typeError) {\n errors.push(typeError);\n }\n }\n\n return errors;\n}\n\n/**\n * Validate parameters and return a structured result.\n */\nexport function validateToolParameters(\n parameters: TToolParameters,\n schemaRequired: string[],\n schemaProperties: Record<string, IParameterSchema>,\n additionalProperties?: boolean | IParameterSchema,\n): IParameterValidationResult {\n const errors = getValidationErrors(\n parameters,\n schemaRequired,\n schemaProperties,\n additionalProperties,\n );\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n","/**\n * FunctionTool - Schema conversion utilities for Facade pattern\n *\n * REASON: Complex Zod to JSON schema conversion requires isolated utility functions\n * ALTERNATIVES_CONSIDERED:\n * 1. Keep conversion logic in main class (violates single responsibility)\n * 2. Use third-party library (adds external dependency)\n * 3. Manual conversion each time (code duplication)\n * 4. Runtime type checking only (loses compile-time safety)\n * 5. Remove Zod support (breaks backward compatibility)\n * TODO: Consider caching conversion results for performance\n */\n\nimport type { IZodSchema, ISchemaConversionOptions } from './types';\nimport type {\n IToolSchema,\n IParameterSchema,\n TJSONSchemaEnum,\n TUniversalValue,\n} from '@robota-sdk/agent-core';\n\n/**\n * Convert Zod schema to JSON Schema format with safe undefined handling\n */\nexport function zodToJsonSchema(\n schema: IZodSchema,\n options: ISchemaConversionOptions = {},\n): IToolSchema['parameters'] {\n const properties: Record<string, IParameterSchema> = {};\n const required: string[] = [];\n\n // Safe access to schema definition (no fallback).\n const schemaDef = schema._def;\n if (!schemaDef) {\n throw new Error('Zod schema is missing _def; cannot convert to JSON schema.');\n }\n\n // Handle object schemas with shape\n if (schemaDef.typeName === 'ZodObject' && schemaDef.shape) {\n // In Zod v3, shape is a property, not a function\n const shape = typeof schemaDef.shape === 'function' ? schemaDef.shape() : schemaDef.shape;\n\n for (const [key, typeObj] of Object.entries(shape)) {\n const property = convertZodTypeToProperty(typeObj);\n properties[key] = property;\n\n // Check if field is required (not optional/nullable)\n if (isRequiredField(typeObj)) {\n required.push(key);\n }\n }\n }\n\n return {\n type: 'object',\n properties,\n required,\n ...((options.allowAdditionalProperties || schemaDef.unknownKeys === 'passthrough') && {\n additionalProperties: true,\n }),\n };\n}\n\n/**\n * Convert individual Zod type to parameter schema with safe undefined handling\n */\nfunction convertZodTypeToProperty(typeObj: IZodSchema): IParameterSchema {\n // Safe access to type definition\n const typeDef = typeObj._def;\n if (!typeDef) {\n throw new Error('Zod type is missing _def; cannot convert to JSON schema.');\n }\n\n const base: Partial<IParameterSchema> = {};\n\n // Add description if available\n if (typeDef.description) {\n base.description = typeDef.description;\n }\n\n // Handle different Zod types\n switch (typeDef.typeName) {\n case 'ZodString':\n return { type: 'string', ...base };\n\n case 'ZodNumber':\n return { type: 'number', ...base };\n\n case 'ZodBoolean':\n return { type: 'boolean', ...base };\n\n case 'ZodArray': {\n if (!typeDef.type) {\n throw new Error('ZodArray is missing item type; cannot convert to JSON schema.');\n }\n const arrayItems = convertZodTypeToProperty(typeDef.type);\n return {\n type: 'array',\n items: arrayItems,\n ...base,\n };\n }\n\n case 'ZodObject':\n return { type: 'object', ...base };\n\n case 'ZodEnum': {\n const enumValues = typeDef.values;\n if (!enumValues || !Array.isArray(enumValues)) {\n throw new Error('ZodEnum is missing enum values; cannot convert to JSON schema.');\n }\n return {\n type: 'string',\n enum: enumValues as TJSONSchemaEnum,\n ...base,\n };\n }\n\n case 'ZodOptional':\n // Handle optional types by recursion\n if (typeDef.innerType) {\n const innerProperty = convertZodTypeToProperty(typeDef.innerType);\n return { ...innerProperty, ...base };\n }\n throw new Error('ZodOptional is missing innerType; cannot convert to JSON schema.');\n\n case 'ZodNullable':\n // Handle nullable types\n if (typeDef.innerType) {\n const innerProperty = convertZodTypeToProperty(typeDef.innerType);\n return { ...innerProperty, ...base };\n }\n throw new Error('ZodNullable is missing innerType; cannot convert to JSON schema.');\n\n case 'ZodDefault':\n // Handle default values by processing the inner type\n if (typeDef.innerType) {\n const innerProperty = convertZodTypeToProperty(typeDef.innerType);\n return { ...innerProperty, ...base };\n }\n throw new Error('ZodDefault is missing innerType; cannot convert to JSON schema.');\n\n case 'ZodRecord':\n // Handle Record<string, T> → JSON Schema additionalProperties\n if (typeDef.valueType) {\n const valueProperty = convertZodTypeToProperty(typeDef.valueType);\n return { type: 'object', additionalProperties: valueProperty, ...base };\n }\n return { type: 'object', additionalProperties: { type: 'string' }, ...base };\n\n default:\n throw new Error(`Unsupported Zod type: ${String(typeDef.typeName)}`);\n }\n}\n\n/**\n * Check if a Zod field is required (not optional or nullable)\n */\nfunction isRequiredField(typeObj: IZodSchema): boolean {\n const typeDef = typeObj._def;\n if (!typeDef) {\n throw new Error('Zod schema is missing _def; cannot determine required fields.');\n }\n\n // Field is optional if it's ZodOptional, ZodNullable, or ZodDefault\n return (\n typeDef.typeName !== 'ZodOptional' &&\n typeDef.typeName !== 'ZodNullable' &&\n typeDef.typeName !== 'ZodDefault'\n );\n}\n\n/**\n * Safely extract enum values from Zod schema\n */\nexport function extractEnumValues(schema: IZodSchema): TUniversalValue[] {\n const typeDef = schema._def;\n if (!typeDef) {\n throw new Error('Zod schema is missing _def; cannot extract enum values.');\n }\n if (!typeDef.values || !Array.isArray(typeDef.values)) {\n throw new Error('ZodEnum schema is missing enum values; cannot extract enum values.');\n }\n return typeDef.values;\n}\n\n/**\n * Check if schema has validation constraints\n */\nexport function hasValidationConstraints(schema: IZodSchema): boolean {\n const typeDef = schema._def;\n if (!typeDef) {\n throw new Error('Zod schema is missing _def; cannot determine validation constraints.');\n }\n\n return !!(typeDef.checks && typeDef.checks.length > 0);\n}\n\n/**\n * Safe schema type name extraction\n */\nexport function getSchemaTypeName(schema: IZodSchema): string {\n const typeDef = schema._def;\n if (!typeDef) {\n throw new Error('Zod schema is missing _def; cannot determine schema type name.');\n }\n if (!typeDef.typeName) {\n throw new Error('Zod schema has empty typeName; cannot determine schema type name.');\n }\n return typeDef.typeName;\n}\n","import { ToolExecutionError, ValidationError } from '@robota-sdk/agent-core';\n\nimport { getValidationErrors, validateToolParameters } from './function-tool/parameter-validator';\nimport { zodToJsonSchema } from './function-tool/schema-converter';\n\nimport type { IZodSchema } from './function-tool/types';\nimport type {\n IFunctionTool,\n IToolResult,\n IToolExecutionContext,\n IParameterValidationResult,\n TToolExecutor,\n TToolParameters,\n IEventService,\n} from '@robota-sdk/agent-core';\nimport type { IToolSchema } from '@robota-sdk/agent-core';\nimport type { TUniversalValue } from '@robota-sdk/agent-core';\n\n// Import from Facade pattern modules for type safety\n\n/**\n * Function tool implementation\n * Wraps a JavaScript function as a tool with schema validation\n *\n * Implements IFunctionTool without extending AbstractTool to avoid\n * circular runtime dependency (tools → agents → tools).\n */\nexport class FunctionTool implements IFunctionTool {\n readonly schema: IToolSchema;\n readonly fn: TToolExecutor;\n private eventService: IEventService | undefined;\n\n constructor(schema: IToolSchema, fn: TToolExecutor) {\n this.schema = schema;\n this.fn = fn;\n this.validateConstructorInputs();\n }\n\n /**\n * Get tool name\n */\n getName(): string {\n return this.schema.name;\n }\n\n /**\n * Set EventService for post-construction injection.\n * Accepts EventService as-is without transformation.\n * Caller is responsible for providing properly configured EventService.\n */\n setEventService(eventService: IEventService | undefined): void {\n this.eventService = eventService;\n }\n\n /**\n * Execute the function tool\n */\n async execute(\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<IToolResult> {\n const toolName = this.schema.name;\n\n // Validate parameters before execution\n if (!this.validate(parameters)) {\n const errors = getValidationErrors(\n parameters,\n this.schema.parameters.required || [],\n this.schema.parameters.properties || {},\n this.schema.parameters.additionalProperties,\n );\n throw new ValidationError(`Invalid parameters for tool \"${toolName}\": ${errors.join(', ')}`);\n }\n\n // Execute the function\n const startTime = Date.now();\n let result: TUniversalValue;\n try {\n result = await this.fn(parameters, context);\n } catch (error) {\n if (error instanceof ToolExecutionError || error instanceof ValidationError) {\n throw error;\n }\n\n throw new ToolExecutionError(\n `Function tool execution failed: ${error instanceof Error ? error.message : String(error)}`,\n toolName,\n error instanceof Error ? error : new Error(String(error)),\n {\n parameterCount: Object.keys(parameters || {}).length,\n hasContext: !!context,\n },\n );\n }\n\n const executionTime = Date.now() - startTime;\n\n return {\n success: true,\n data: result,\n metadata: {\n executionTime,\n toolName,\n parameters,\n },\n };\n }\n\n /**\n * Validate parameters (simple boolean result)\n */\n validate(parameters: TToolParameters): boolean {\n return (\n getValidationErrors(\n parameters,\n this.schema.parameters.required || [],\n this.schema.parameters.properties || {},\n this.schema.parameters.additionalProperties,\n ).length === 0\n );\n }\n\n /**\n * Validate tool parameters with detailed result\n */\n validateParameters(parameters: TToolParameters): IParameterValidationResult {\n return validateToolParameters(\n parameters,\n this.schema.parameters.required || [],\n this.schema.parameters.properties || {},\n this.schema.parameters.additionalProperties,\n );\n }\n\n /**\n * Get tool description\n */\n getDescription(): string {\n return this.schema.description;\n }\n\n /**\n * Validate constructor inputs\n */\n private validateConstructorInputs(): void {\n if (!this.schema) {\n throw new ValidationError('Tool schema is required');\n }\n\n if (!this.fn || typeof this.fn !== 'function') {\n throw new ValidationError('Tool function is required and must be a function');\n }\n\n if (!this.schema.name) {\n throw new ValidationError('Tool schema must have a name');\n }\n }\n}\n\n/**\n * Helper function to create a function tool from a simple function\n */\nexport function createFunctionTool(\n name: string,\n description: string,\n parameters: IToolSchema['parameters'],\n fn: TToolExecutor,\n): FunctionTool {\n const schema: IToolSchema = {\n name,\n description,\n parameters,\n };\n\n return new FunctionTool(schema, fn);\n}\n\n/**\n * Helper function to create a function tool from Zod schema\n */\nexport function createZodFunctionTool(\n name: string,\n description: string,\n zodSchema: IZodSchema,\n fn: TToolExecutor,\n): FunctionTool {\n // Use comprehensive Zod to JSON schema conversion\n const parameters = zodToJsonSchema(zodSchema);\n\n const schema: IToolSchema = {\n name,\n description,\n parameters,\n };\n\n // Wrap the function with validation and ensure proper parameter handling\n const wrappedFn: TToolExecutor = async (\n parameters: TToolParameters,\n context?: IToolExecutionContext,\n ): Promise<TUniversalValue> => {\n // Use Zod for runtime validation\n const parseResult = zodSchema.safeParse(parameters);\n if (!parseResult.success) {\n throw new ValidationError(`Zod validation failed: ${parseResult.error}`);\n }\n\n const result = await fn((parseResult.data as TToolParameters) || parameters, context);\n // Ensure result is always a string for consistency with core package\n return typeof result === 'string' ? result : JSON.stringify(result);\n };\n\n return new FunctionTool(schema, wrappedFn);\n}\n\n// zodToJsonSchema function moved to Facade pattern schema-converter module\n","/**\n * BashTool — execute shell commands via child_process.spawn\n *\n * Returns TToolResult JSON string. Non-zero exit is returned as success:true\n * with exitCode set, matching Claude Code behaviour (the command ran, it just\n * exited non-zero — the LLM can decide what to do with that information).\n */\n\nimport { spawn } from 'node:child_process';\n\nimport { z } from 'zod';\n\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { FunctionTool } from '../implementations/function-tool';\nimport type { ISandboxToolOptions } from '../sandbox/types.js';\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst DEFAULT_TIMEOUT_MS = 120_000; // 2 minutes\n\nconst BashSchema = z.object({\n command: z.string().describe('The bash command to execute'),\n timeout: z\n .number()\n .optional()\n .describe('Optional timeout in milliseconds (max 600000). Default is 120000 (2 minutes)'),\n workingDirectory: z\n .string()\n .optional()\n .describe('Working directory for the command. Defaults to the current working directory'),\n});\n\ntype TBashArgs = z.infer<typeof BashSchema>;\n\n/**\n * Run a shell command and return stdout + stderr.\n * Resolves with the TToolResult JSON string.\n */\nasync function runBash(args: TBashArgs, options: ISandboxToolOptions = {}): Promise<string> {\n const { command, timeout: rawTimeout = DEFAULT_TIMEOUT_MS, workingDirectory } = args;\n const timeout = Math.min(rawTimeout, 600_000);\n if (options.sandboxClient) {\n try {\n const sandboxResult = await options.sandboxClient.run(command, {\n timeoutMs: timeout,\n workingDirectory,\n });\n const output = sandboxResult.stderr\n ? `${sandboxResult.stdout}\\nstderr:\\n${sandboxResult.stderr}`\n : sandboxResult.stdout;\n const result: TToolResult = {\n success: true,\n output,\n exitCode: sandboxResult.exitCode,\n };\n return JSON.stringify(result);\n } catch (err) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: err instanceof Error ? err.message : String(err),\n };\n return JSON.stringify(result);\n }\n }\n\n return new Promise<string>((resolve) => {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n let timedOut = false;\n let settled = false;\n\n const child = spawn('sh', ['-c', command], {\n cwd: workingDirectory ?? process.cwd(),\n env: process.env,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk);\n });\n\n child.stderr.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill('SIGTERM');\n // Resolve immediately on timeout — don't wait for close event.\n // The child process cleanup happens in the background.\n settle({\n success: false,\n output: Buffer.concat(stdoutChunks).toString('utf8'),\n error: `Command timed out after ${timeout}ms`,\n });\n }, timeout);\n\n function settle(result: TToolResult): void {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(JSON.stringify(result));\n }\n\n child.on('error', (err: Error) => {\n settle({\n success: false,\n output: '',\n error: err.message,\n });\n });\n\n child.on('close', (code: number | null) => {\n if (timedOut) {\n settle({\n success: false,\n output: Buffer.concat(stdoutChunks).toString('utf8'),\n error: `Command timed out after ${timeout}ms`,\n exitCode: code ?? undefined,\n });\n return;\n }\n\n const stdout = Buffer.concat(stdoutChunks).toString('utf8');\n const stderr = Buffer.concat(stderrChunks).toString('utf8');\n\n const exitCode = code ?? 0;\n const output = stderr ? `${stdout}\\nstderr:\\n${stderr}` : stdout;\n\n settle({\n success: true,\n output,\n exitCode,\n });\n });\n });\n}\n\n/**\n * Create a BashTool instance — register with Robota agent tools registry.\n */\nexport function createBashTool(options: ISandboxToolOptions = {}): FunctionTool {\n return createZodFunctionTool(\n 'Bash',\n 'Executes a given bash command and returns its output.\\n\\nThe working directory persists between commands, but shell state does not.\\n\\nIMPORTANT: Avoid using this tool to run `find`, `grep`, `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands. Instead, use the appropriate dedicated tool:\\n - File search: Use Glob (NOT find or ls)\\n - Content search: Use Grep (NOT grep or rg)\\n - Read files: Use Read (NOT cat/head/tail)\\n - Edit files: Use Edit (NOT sed/awk)\\n\\nFor simple commands, keep the description brief (5-10 words). For complex commands, include enough context to clarify what the command does.\\n\\nOutput is limited to 30,000 characters. Longer output will be middle-truncated.',\n BashSchema,\n async (params) => {\n // createZodFunctionTool passes validated params; cast is safe\n return runBash(params as TBashArgs, options);\n },\n );\n}\n\n/**\n * BashTool instance — register with Robota agent tools registry.\n */\nexport const bashTool = createBashTool();\n","import { resolve, sep } from 'node:path';\n\nimport type { TToolResult } from '../types/tool-result.js';\n\n/**\n * Returns a JSON-serialized TToolResult error when filePath is outside cwd.\n * Returns undefined when the path is within cwd or cwd is not set.\n */\nexport function checkPathWithinCwd(filePath: string, cwd: string | undefined): string | undefined {\n if (cwd === undefined) return undefined;\n\n const resolved = resolve(filePath);\n const cwdResolved = resolve(cwd);\n\n if (resolved !== cwdResolved && !resolved.startsWith(cwdResolved + sep)) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Access denied: \"${filePath}\" is outside the working directory`,\n };\n return JSON.stringify(result);\n }\n\n return undefined;\n}\n","/**\n * ReadTool — read a file and return its contents with line numbers (cat -n style).\n *\n * Supports offset/limit for partial reads. Detects binary files and refuses to\n * return their raw bytes. Default limit is 2000 lines.\n */\n\nimport { readFile, stat } from 'node:fs/promises';\n\nimport { z } from 'zod';\n\nimport { checkPathWithinCwd } from './path-guard.js';\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { FunctionTool } from '../implementations/function-tool';\nimport type { ISandboxToolOptions } from '../sandbox/types.js';\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst DEFAULT_LIMIT = 2000;\n\nconst ReadSchema = z.object({\n filePath: z.string().describe('The absolute path to the file to read'),\n offset: z\n .number()\n .optional()\n .describe(\n 'The line number to start reading from (1-based). Only provide if the file is too large to read at once',\n ),\n limit: z\n .number()\n .optional()\n .describe(\n `The number of lines to read (default: ${DEFAULT_LIMIT}). Only provide if the file is too large to read at once`,\n ),\n});\n\ntype TReadArgs = z.infer<typeof ReadSchema>;\n\n/**\n * Heuristic binary detection: scan the first 8 KB for null bytes.\n */\nfunction isBinary(buffer: Buffer): boolean {\n const checkLength = Math.min(buffer.length, 8192);\n for (let i = 0; i < checkLength; i++) {\n if (buffer[i] === 0) return true;\n }\n return false;\n}\n\n/**\n * Format lines with 1-based line numbers in cat -n style.\n * Pads line number to the width of the highest line number.\n */\nfunction formatWithLineNumbers(lines: string[], startLine: number): string {\n const lastLineNum = startLine + lines.length - 1;\n const width = String(lastLineNum).length;\n return lines\n .map((line, idx) => {\n const lineNum = String(startLine + idx).padStart(width, ' ');\n return `${lineNum}\\t${line}`;\n })\n .join('\\n');\n}\n\nfunction formatReadResult(\n filePath: string,\n content: string,\n startLine: number,\n limit: number,\n): string {\n const allLines = content.split('\\n');\n\n // Remove trailing empty line if file ends with newline (common in Unix files)\n if (allLines[allLines.length - 1] === '') {\n allLines.pop();\n }\n\n const zeroBasedStart = startLine - 1;\n const selectedLines = allLines.slice(zeroBasedStart, zeroBasedStart + limit);\n\n const output = formatWithLineNumbers(selectedLines, startLine);\n\n const totalLines = allLines.length;\n const returnedLines = selectedLines.length;\n const header =\n returnedLines < totalLines\n ? `[File: ${filePath} (lines ${startLine}-${startLine + returnedLines - 1} of ${totalLines})]\\n`\n : `[File: ${filePath} (${totalLines} lines)]\\n`;\n\n const result: TToolResult = {\n success: true,\n output: header + output,\n };\n return JSON.stringify(result);\n}\n\nasync function readFileTool(args: TReadArgs, options: ISandboxToolOptions = {}): Promise<string> {\n const { filePath, offset, limit = DEFAULT_LIMIT } = args;\n const startLine = offset !== undefined && offset > 0 ? offset : 1;\n\n if (options.sandboxClient) {\n try {\n const content = await options.sandboxClient.readFile(filePath);\n return formatReadResult(filePath, content, startLine, limit);\n } catch (err) {\n // allow-fallback: sandbox read failure → surface as TToolResult error\n const result: TToolResult = {\n success: false,\n output: '',\n error: err instanceof Error ? err.message : String(err),\n };\n return JSON.stringify(result);\n }\n }\n\n const pathError = checkPathWithinCwd(filePath, options.cwd);\n if (pathError !== undefined) return pathError;\n\n let fileStats: Awaited<ReturnType<typeof stat>> | undefined;\n try {\n fileStats = await stat(filePath);\n } catch (err) {\n // allow-fallback: stat failure means file not found → TToolResult error\n const result: TToolResult = {\n success: false,\n output: '',\n error: `File not found: ${filePath}`,\n };\n return JSON.stringify(result);\n }\n\n if (!fileStats.isFile()) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Path is not a file: ${filePath}`,\n };\n return JSON.stringify(result);\n }\n\n let buffer: Buffer;\n try {\n buffer = await readFile(filePath);\n } catch (err) {\n // allow-fallback: read failure → TToolResult error (permissions, locks)\n const result: TToolResult = {\n success: false,\n output: '',\n error: err instanceof Error ? err.message : String(err),\n };\n return JSON.stringify(result);\n }\n\n if (isBinary(buffer)) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Binary file not supported: ${filePath}`,\n };\n return JSON.stringify(result);\n }\n\n const content = buffer.toString('utf8');\n return formatReadResult(filePath, content, startLine, limit);\n}\n\n/**\n * Create a ReadTool instance — register with Robota agent tools registry.\n */\nexport function createReadTool(options: ISandboxToolOptions = {}): FunctionTool {\n return createZodFunctionTool(\n 'Read',\n 'Reads a file from the local filesystem.\\n\\nBy default, reads up to 2000 lines from the beginning of the file. You can optionally specify offset and limit for partial reads.\\n\\nResults are returned using cat -n format, with line numbers starting at 1.\\n\\nThe file_path parameter must be an absolute path, not a relative path.',\n ReadSchema,\n async (params) => {\n return readFileTool(params as TReadArgs, options);\n },\n );\n}\n\n/**\n * ReadTool instance — register with Robota agent tools registry.\n */\nexport const readTool = createReadTool();\n","import { randomBytes } from 'node:crypto';\nimport { chmod, mkdir, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\n\nconst TEMP_RANDOM_BYTES = 6;\nconst PRESERVED_MODE_BITS = 0o7777;\nconst MISSING_FILE_ERROR_CODE = 'ENOENT';\n\nfunction createTempFilePath(filePath: string): string {\n const dir = dirname(filePath);\n const name = basename(filePath);\n const suffix = randomBytes(TEMP_RANDOM_BYTES).toString('hex');\n return join(dir, `.${name}.robota-tmp-${process.pid}-${Date.now()}-${suffix}`);\n}\n\nasync function readExistingMode(filePath: string): Promise<number | undefined> {\n try {\n const fileStats = await stat(filePath);\n return fileStats.mode & PRESERVED_MODE_BITS;\n } catch (error) {\n if (error instanceof Error && hasErrorCode(error, MISSING_FILE_ERROR_CODE)) return undefined;\n throw error;\n }\n}\n\nfunction hasErrorCode(error: Error, code: string): boolean {\n return 'code' in error && error.code === code;\n}\n\nexport async function atomicWriteUtf8File(filePath: string, content: string): Promise<void> {\n const dir = dirname(filePath);\n await mkdir(dir, { recursive: true });\n\n const existingMode = await readExistingMode(filePath);\n const tempFilePath = createTempFilePath(filePath);\n try {\n await writeFile(tempFilePath, content, 'utf8');\n if (existingMode !== undefined) {\n await chmod(tempFilePath, existingMode);\n }\n await rename(tempFilePath, filePath);\n } catch (error) {\n await rm(tempFilePath, { force: true }).catch(() => undefined);\n throw error;\n }\n}\n","/**\n * WriteTool — write content to a file, auto-creating parent directories.\n */\n\nimport { z } from 'zod';\n\nimport { atomicWriteUtf8File } from './atomic-file-write.js';\nimport { checkPathWithinCwd } from './path-guard.js';\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { FunctionTool } from '../implementations/function-tool';\nimport type { ISandboxToolOptions } from '../sandbox/types.js';\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst WriteSchema = z.object({\n filePath: z.string().describe('The absolute path to the file to write'),\n content: z.string().describe('The content to write to the file'),\n});\n\ntype TWriteArgs = z.infer<typeof WriteSchema>;\n\nasync function writeFileTool(args: TWriteArgs, options: ISandboxToolOptions = {}): Promise<string> {\n const { filePath, content } = args;\n\n if (!options.sandboxClient) {\n const pathError = checkPathWithinCwd(filePath, options.cwd);\n if (pathError !== undefined) return pathError;\n }\n\n try {\n if (options.sandboxClient) {\n await options.sandboxClient.writeFile(filePath, content);\n } else {\n await atomicWriteUtf8File(filePath, content);\n }\n\n const result: TToolResult = {\n success: true,\n output: `Written ${Buffer.byteLength(content, 'utf8')} bytes to ${filePath}`,\n };\n return JSON.stringify(result);\n } catch (err) {\n // allow-fallback: write failure → TToolResult error (disk full, permissions)\n const result: TToolResult = {\n success: false,\n output: '',\n error: err instanceof Error ? err.message : String(err),\n };\n return JSON.stringify(result);\n }\n}\n\n/**\n * Create a WriteTool instance — register with Robota agent tools registry.\n */\nexport function createWriteTool(options: ISandboxToolOptions = {}): FunctionTool {\n return createZodFunctionTool(\n 'Write',\n 'Writes a file to the local filesystem. This will overwrite an existing file if one exists.\\n\\nALWAYS prefer the Edit tool for modifying existing files — it only sends the diff. Only use this tool to create new files or for complete rewrites.\\n\\nNEVER create documentation files (*.md) or README files unless explicitly requested by the user.',\n WriteSchema,\n async (params) => {\n return writeFileTool(params as TWriteArgs, options);\n },\n );\n}\n\n/**\n * WriteTool instance — register with Robota agent tools registry.\n */\nexport const writeTool = createWriteTool();\n","/**\n * EditTool — perform string-replace edits on a file.\n *\n * By default, requires the oldString to appear exactly once in the file\n * (ensuring surgical edits). Pass replaceAll:true to replace all occurrences.\n */\n\nimport { readFile } from 'node:fs/promises';\n\nimport { z } from 'zod';\n\nimport { atomicWriteUtf8File } from './atomic-file-write.js';\nimport { checkPathWithinCwd } from './path-guard.js';\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { FunctionTool } from '../implementations/function-tool';\nimport type { ISandboxToolOptions } from '../sandbox/types.js';\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst EditSchema = z.object({\n filePath: z.string().describe('The absolute path to the file to modify'),\n oldString: z\n .string()\n .describe('The text to replace (must be an exact match of existing content)'),\n newString: z.string().describe('The text to replace it with (must be different from old_string)'),\n replaceAll: z\n .boolean()\n .optional()\n .describe(\n 'Replace all occurrences of old_string (default: false). Useful for renaming variables',\n ),\n});\n\ntype TEditArgs = z.infer<typeof EditSchema>;\n\nasync function editFileTool(args: TEditArgs, options: ISandboxToolOptions = {}): Promise<string> {\n const { filePath, oldString, newString, replaceAll = false } = args;\n\n if (!options.sandboxClient) {\n const pathError = checkPathWithinCwd(filePath, options.cwd);\n if (pathError !== undefined) return pathError;\n }\n\n let content: string;\n try {\n content = options.sandboxClient\n ? await options.sandboxClient.readFile(filePath)\n : await readFile(filePath, 'utf8');\n } catch (err) {\n // allow-fallback: read failure before edit → TToolResult error (file not found)\n const result: TToolResult = {\n success: false,\n output: '',\n error: `File not found: ${filePath}`,\n };\n return JSON.stringify(result);\n }\n\n if (!content.includes(oldString)) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `oldString not found in file: ${filePath}`,\n };\n return JSON.stringify(result);\n }\n\n // Uniqueness check when not in replaceAll mode\n if (!replaceAll) {\n const firstIdx = content.indexOf(oldString);\n const lastIdx = content.lastIndexOf(oldString);\n if (firstIdx !== lastIdx) {\n const occurrences = content.split(oldString).length - 1;\n const result: TToolResult = {\n success: false,\n output: '',\n error:\n `oldString is not unique in file (found ${occurrences} occurrences). ` +\n 'Provide more context to make it unique, or use replaceAll:true.',\n };\n return JSON.stringify(result);\n }\n }\n\n const updated = replaceAll\n ? content.split(oldString).join(newString)\n : content.slice(0, content.indexOf(oldString)) +\n newString +\n content.slice(content.indexOf(oldString) + oldString.length);\n\n try {\n if (options.sandboxClient) {\n await options.sandboxClient.writeFile(filePath, updated);\n } else {\n await atomicWriteUtf8File(filePath, updated);\n }\n } catch (err) {\n // allow-fallback: write failure after edit → TToolResult error\n const result: TToolResult = {\n success: false,\n output: '',\n error: err instanceof Error ? err.message : String(err),\n };\n return JSON.stringify(result);\n }\n\n const count = replaceAll ? content.split(oldString).length - 1 : 1;\n // Calculate start line number from the original content\n const matchIdx = content.indexOf(oldString);\n const startLine = matchIdx >= 0 ? content.substring(0, matchIdx).split('\\n').length : 1;\n const result: TToolResult = {\n success: true,\n output: `Replaced ${count} occurrence(s) in ${filePath}`,\n startLine,\n };\n return JSON.stringify(result);\n}\n\n/**\n * Create an EditTool instance — register with Robota agent tools registry.\n */\nexport function createEditTool(options: ISandboxToolOptions = {}): FunctionTool {\n return createZodFunctionTool(\n 'Edit',\n 'Performs exact string replacements in files.\\n\\nYou must use the Read tool at least once before editing. When editing text from Read output, preserve the exact indentation.\\n\\nThe edit will FAIL if old_string is not unique in the file. Either provide more surrounding context to make it unique, or use replace_all to change every instance.\\n\\nALWAYS prefer editing existing files over creating new ones.',\n EditSchema,\n async (params) => {\n return editFileTool(params as TEditArgs, options);\n },\n );\n}\n\n/**\n * EditTool instance — register with Robota agent tools registry.\n */\nexport const editTool = createEditTool();\n","/**\n * GlobTool — fast file pattern search using fast-glob.\n *\n * Excludes node_modules and .git by default.\n * Results are sorted by modification time (most recently modified first).\n */\n\nimport { stat } from 'node:fs/promises';\nimport { resolve } from 'node:path';\n\nimport fg from 'fast-glob';\nimport pLimit from 'p-limit';\nimport { z } from 'zod';\n\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst DEFAULT_MAX_RESULTS = 1000;\n\nconst GlobSchema = z.object({\n pattern: z\n .string()\n .describe('The glob pattern to match files against (e.g. \"**/*.ts\", \"src/**/*.tsx\")'),\n path: z\n .string()\n .optional()\n .describe(\n 'The directory to search in. Defaults to the current working directory. Must be a valid directory path if provided',\n ),\n limit: z\n .number()\n .optional()\n .describe(\n 'Maximum number of results to return (default: 1000). Use a smaller limit to save context space',\n ),\n});\n\ntype TGlobArgs = z.infer<typeof GlobSchema>;\n\ninterface IFileWithMtime {\n path: string;\n mtime: number;\n}\n\nasync function globFileTool(args: TGlobArgs): Promise<string> {\n const { pattern, path: basePath } = args;\n const cwd = basePath ? resolve(basePath) : process.cwd();\n\n let matches: string[];\n try {\n matches = await fg(pattern, {\n cwd,\n ignore: ['**/node_modules/**', '**/.git/**'],\n dot: true,\n absolute: false,\n });\n } catch (err) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: err instanceof Error ? err.message : String(err),\n };\n return JSON.stringify(result);\n }\n\n // Sort by mtime (most recent first); cap concurrent stat calls to avoid I/O explosion\n const limit = pLimit(100);\n const withMtime: IFileWithMtime[] = await Promise.all(\n matches.map((p) =>\n limit(async () => {\n const absPath = resolve(cwd, p);\n try {\n const s = await stat(absPath);\n return { path: p, mtime: s.mtimeMs };\n } catch {\n // allow-fallback: stat failure on a matched path returns mtime=0 (sort-last), not a logic fallback\n return { path: p, mtime: 0 };\n }\n }),\n ),\n );\n\n withMtime.sort((a, b) => b.mtime - a.mtime);\n\n const maxResults = args.limit ?? DEFAULT_MAX_RESULTS;\n const totalMatches = withMtime.length;\n const truncated = totalMatches > maxResults;\n const limited = truncated ? withMtime.slice(0, maxResults) : withMtime;\n const sorted = limited.map((f) => f.path);\n\n let output = sorted.length > 0 ? sorted.join('\\n') : '(no matches)';\n if (truncated) {\n output += `\\n\\n[Showing ${maxResults} of ${totalMatches} matches. Use limit parameter to see more.]`;\n }\n\n const result: TToolResult = {\n success: true,\n output,\n };\n return JSON.stringify(result);\n}\n\n/**\n * GlobTool instance — register with Robota agent tools registry.\n */\nexport const globTool = createZodFunctionTool(\n 'Glob',\n \"Fast file pattern matching tool that works with any codebase size.\\n\\nSupports glob patterns like '**/*.js' or 'src/**/*.ts'. Returns matching file paths sorted by modification time.\\n\\nUse this tool when you need to find files by name patterns. When doing an open-ended search that may require multiple rounds, use the Agent tool instead.\\n\\nDefault limit is 1000 results. Use the limit parameter if you need fewer results to save context space.\",\n GlobSchema,\n async (params) => {\n return globFileTool(params as TGlobArgs);\n },\n);\n","/**\n * GrepTool — recursive regex content search.\n *\n * Supports two output modes:\n * - files_with_matches (default): return only file paths that contain a match\n * - content: return matching lines with optional context lines\n */\n\nimport { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\n\nimport { z } from 'zod';\n\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst GrepSchema = z.object({\n pattern: z.string().describe('The regular expression pattern to search for in file contents'),\n path: z\n .string()\n .optional()\n .describe('File or directory to search in. Defaults to the current working directory'),\n glob: z\n .string()\n .optional()\n .describe(\n 'Glob pattern to filter files (e.g. \"*.ts\", \"*.{ts,tsx}\"). Only files matching this pattern will be searched',\n ),\n contextLines: z\n .number()\n .optional()\n .describe(\n 'Number of context lines to show before and after each match. Only applies when outputMode is \"content\". Default: 0',\n ),\n outputMode: z\n .enum(['files_with_matches', 'content'])\n .optional()\n .describe(\n 'Output mode: \"files_with_matches\" shows only file paths (default), \"content\" shows matching lines with context',\n ),\n});\n\ntype TGrepArgs = z.infer<typeof GrepSchema>;\n\n/** Convert a simple glob to a RegExp for file name filtering. */\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '.+')\n .replace(/\\*/g, '[^/]*');\n return new RegExp(`^${escaped}$`);\n}\n\n/** Check if a file name matches an optional glob filter. */\nfunction matchesGlob(filename: string, glob: string | undefined): boolean {\n if (glob === undefined) return true;\n return globToRegex(glob).test(filename);\n}\n\n/** Gather all files under a directory recursively, excluding node_modules/.git. */\nasync function collectFiles(dirPath: string, glob: string | undefined): Promise<string[]> {\n const results: string[] = [];\n\n async function walk(current: string): Promise<void> {\n let entryNames: string[];\n try {\n entryNames = await readdir(current);\n } catch {\n return;\n }\n\n for (const name of entryNames) {\n if (name === 'node_modules' || name === '.git') continue;\n\n const fullPath = join(current, name);\n let fileStat: Awaited<ReturnType<typeof stat>>;\n try {\n fileStat = await stat(fullPath);\n } catch {\n continue;\n }\n\n if (fileStat.isDirectory()) {\n await walk(fullPath);\n } else if (fileStat.isFile()) {\n if (matchesGlob(name, glob)) {\n results.push(fullPath);\n }\n }\n }\n }\n\n await walk(dirPath);\n return results;\n}\n\n/** Search a single file for lines matching the regex. */\nfunction searchFile(\n content: string,\n filePath: string,\n regex: RegExp,\n contextLines: number,\n outputMode: 'files_with_matches' | 'content',\n): string[] {\n const lines = content.split('\\n');\n const matchingIndices: number[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n if (regex.test(lines[i])) {\n matchingIndices.push(i);\n }\n }\n\n if (matchingIndices.length === 0) return [];\n\n if (outputMode === 'files_with_matches') {\n return [filePath];\n }\n\n // content mode — include context lines\n const includedIndices = new Set<number>();\n for (const idx of matchingIndices) {\n for (\n let c = Math.max(0, idx - contextLines);\n c <= Math.min(lines.length - 1, idx + contextLines);\n c++\n ) {\n includedIndices.add(c);\n }\n }\n\n const outputLines: string[] = [];\n const sortedIndices = Array.from(includedIndices).sort((a, b) => a - b);\n\n let prevIdx: number | undefined;\n for (const idx of sortedIndices) {\n if (prevIdx !== undefined && idx > prevIdx + 1) {\n outputLines.push('--');\n }\n const lineNum = idx + 1;\n const marker = matchingIndices.includes(idx) ? ':' : '-';\n outputLines.push(`${filePath}:${lineNum}${marker}${lines[idx]}`);\n prevIdx = idx;\n }\n\n return outputLines;\n}\n\nasync function grepFileTool(args: TGrepArgs): Promise<string> {\n const {\n pattern,\n path: searchPath,\n glob,\n contextLines = 0,\n outputMode = 'files_with_matches',\n } = args;\n const targetPath = searchPath ? resolve(searchPath) : process.cwd();\n\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch (err) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Invalid regex pattern: ${pattern}`,\n };\n return JSON.stringify(result);\n }\n\n // Determine whether targetPath is a file or directory\n let targetStat: Awaited<ReturnType<typeof stat>>;\n try {\n targetStat = await stat(targetPath);\n } catch {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Path not found: ${targetPath}`,\n };\n return JSON.stringify(result);\n }\n\n let files: string[];\n if (targetStat.isFile()) {\n files = [targetPath];\n } else {\n files = await collectFiles(targetPath, glob);\n }\n\n const allOutputLines: string[] = [];\n\n for (const filePath of files) {\n let content: string;\n try {\n const buffer = await readFile(filePath);\n // Skip binary files\n const checkLen = Math.min(buffer.length, 8192);\n let hasBinary = false;\n for (let i = 0; i < checkLen; i++) {\n if (buffer[i] === 0) {\n hasBinary = true;\n break;\n }\n }\n if (hasBinary) continue;\n content = buffer.toString('utf8');\n } catch {\n continue;\n }\n\n const fileMatches = searchFile(content, filePath, regex, contextLines, outputMode);\n allOutputLines.push(...fileMatches);\n }\n\n const result: TToolResult = {\n success: true,\n output: allOutputLines.length > 0 ? allOutputLines.join('\\n') : '(no matches)',\n };\n return JSON.stringify(result);\n}\n\n/**\n * GrepTool instance — register with Robota agent tools registry.\n */\nexport const grepTool = createZodFunctionTool(\n 'Grep',\n \"A powerful search tool built on regex matching.\\n\\nSupports full regex syntax (e.g., 'log.*Error', 'function\\\\\\\\s+\\\\\\\\w+'). Filter files with glob parameter (e.g., '*.js', '**/*.tsx').\\n\\nOutput modes: 'content' shows matching lines with context, 'files_with_matches' shows only file paths (default), 'count' shows match counts.\\n\\nUse this tool for ALL search tasks. NEVER invoke grep or rg as a Bash command.\\n\\nUse head_limit to control result size and save context space.\",\n GrepSchema,\n async (params) => {\n return grepFileTool(params as TGrepArgs);\n },\n);\n","/**\n * WebFetchTool — fetch a URL and return its content as text.\n *\n * HTML is stripped to plain text for readability. Uses Node.js native fetch.\n * Output is capped at 30K chars (same as other tools).\n */\n\nimport { z } from 'zod';\n\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_RESPONSE_BYTES = 5_000_000; // 5 MB max download\n\nconst WebFetchSchema = z.object({\n url: z.string().describe('The URL to fetch'),\n headers: z.record(z.string()).optional().describe('Optional HTTP headers as key-value pairs'),\n});\n\ntype TWebFetchArgs = z.infer<typeof WebFetchSchema>;\n\n/** Strip HTML tags and decode common entities to produce readable text. */\nfunction htmlToText(html: string): string {\n return html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/ /g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nexport function classifyFetchError(err: unknown): string {\n if (!(err instanceof Error)) return String(err);\n\n if (err.name === 'AbortError') {\n return `Request timed out after ${DEFAULT_TIMEOUT_MS / 1000}s. The server did not respond in time.`;\n }\n\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') {\n return `Network error: DNS resolution failed for this host. The URL may be incorrect or the host does not exist. Do not retry with the same URL.`;\n }\n if (code === 'ECONNREFUSED') {\n return `Network error: Connection refused. The server is not accepting connections at this address. Do not retry with the same URL.`;\n }\n if (code === 'ECONNRESET') {\n return `Network error: Connection was reset by the server. The server may be temporarily unavailable.`;\n }\n if (code === 'ETIMEDOUT') {\n return `Network error: Connection timed out. The server is not reachable within the expected time.`;\n }\n if (code === 'CERT_HAS_EXPIRED' || code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE') {\n return `Network error: SSL certificate error (${code}). The server's certificate is invalid. Do not retry with the same URL.`;\n }\n\n return `Network error: ${err.message} Check that the URL is correct and the server is reachable.`;\n}\n\nasync function runWebFetch(args: TWebFetchArgs): Promise<string> {\n const { url, headers } = args;\n\n try {\n new URL(url);\n } catch {\n // allow-fallback: URL parse failure is a structured tool result, not a thrown error\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Invalid URL: \"${url}\". Fix the URL format before retrying.`,\n };\n return JSON.stringify(result);\n }\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const response = await fetch(url, {\n headers: {\n 'User-Agent': 'Robota-CLI/3.0',\n ...(headers ?? {}),\n },\n signal: controller.signal,\n redirect: 'follow',\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n const retryHint =\n response.status >= 500\n ? ' The server is temporarily unavailable — retrying may help.'\n : ' Do not retry with the same URL.';\n const result: TToolResult = {\n success: false,\n output: '',\n error: `HTTP ${response.status} ${response.statusText}.${retryHint}`,\n };\n return JSON.stringify(result);\n }\n\n const contentType = response.headers.get('content-type') ?? '';\n const buffer = await response.arrayBuffer();\n\n if (buffer.byteLength > MAX_RESPONSE_BYTES) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Response too large: ${buffer.byteLength} bytes (max ${MAX_RESPONSE_BYTES}). Consider fetching a more specific URL or a paginated endpoint.`,\n };\n return JSON.stringify(result);\n }\n\n let text = new TextDecoder().decode(buffer);\n\n // Strip HTML if content-type indicates HTML\n if (contentType.includes('html')) {\n text = htmlToText(text);\n }\n\n const result: TToolResult = { success: true, output: text };\n return JSON.stringify(result);\n } catch (err) {\n // allow-fallback: fetch errors are structured tool results returned to the LLM, not thrown\n const result: TToolResult = { success: false, output: '', error: classifyFetchError(err) };\n return JSON.stringify(result);\n }\n}\n\nexport const webFetchTool = createZodFunctionTool(\n 'WebFetch',\n 'Fetch a URL and return its content as text. HTML pages are converted to plain text.',\n WebFetchSchema,\n async (params) => runWebFetch(params as TWebFetchArgs),\n);\n","/**\n * WebSearchTool — search the web and return results.\n *\n * Uses Brave Search API when BRAVE_API_KEY is set.\n * Returns an error with setup instructions otherwise.\n */\n\nimport { z } from 'zod';\n\nimport { createZodFunctionTool } from '../implementations/function-tool';\n\nimport type { TToolResult } from '../types/tool-result.js';\n\nconst DEFAULT_LIMIT = 10;\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\nconst WebSearchSchema = z.object({\n query: z.string().describe('The search query'),\n limit: z\n .number()\n .optional()\n .describe(`Maximum number of results to return (default: ${DEFAULT_LIMIT})`),\n});\n\ntype TWebSearchArgs = z.infer<typeof WebSearchSchema>;\n\ninterface IBraveResult {\n title: string;\n url: string;\n description: string;\n}\n\ninterface IBraveResponse {\n web?: {\n results?: IBraveResult[];\n };\n}\n\nasync function runWebSearch(args: TWebSearchArgs): Promise<string> {\n const { query, limit = DEFAULT_LIMIT } = args;\n const apiKey = process.env['BRAVE_API_KEY'];\n\n if (!apiKey) {\n const result: TToolResult = {\n success: false,\n output: '',\n error:\n 'Web search requires BRAVE_API_KEY environment variable. ' +\n 'Get a free API key at https://brave.com/search/api/ (2,000 queries/month free).',\n };\n return JSON.stringify(result);\n }\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n const params = new URLSearchParams({\n q: query,\n count: String(Math.min(limit, 20)),\n });\n\n const response = await fetch(`https://api.search.brave.com/res/v1/web/search?${params}`, {\n headers: {\n Accept: 'application/json',\n 'Accept-Encoding': 'gzip',\n 'X-Subscription-Token': apiKey,\n },\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (!response.ok) {\n const result: TToolResult = {\n success: false,\n output: '',\n error: `Brave Search API error: HTTP ${response.status} ${response.statusText}`,\n };\n return JSON.stringify(result);\n }\n\n const data = (await response.json()) as IBraveResponse;\n const results = (data.web?.results ?? []).map((r) => ({\n title: r.title,\n url: r.url,\n snippet: r.description,\n }));\n\n const result: TToolResult = { success: true, output: JSON.stringify(results, null, 2) };\n return JSON.stringify(result);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const result: TToolResult = { success: false, output: '', error: message };\n return JSON.stringify(result);\n }\n}\n\nexport const webSearchTool = createZodFunctionTool(\n 'WebSearch',\n 'Search the web and return results with title, URL, and snippet.',\n WebSearchSchema,\n async (params) => runWebSearch(params as TWebSearchArgs),\n);\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-tools",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.71",
|
|
4
4
|
"description": "Tool registry and implementations for Robota SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node/index.js",
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/node/index.d.ts",
|
|
11
|
+
"source": "./src/index.ts",
|
|
12
|
+
"browser": {
|
|
13
|
+
"import": "./dist/browser/browser.js"
|
|
14
|
+
},
|
|
11
15
|
"node": {
|
|
12
16
|
"import": "./dist/node/index.js",
|
|
13
17
|
"require": "./dist/node/index.cjs"
|
|
@@ -18,31 +22,43 @@
|
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/woojubb/robota.git"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://robota.io/",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/woojubb/robota/issues"
|
|
32
|
+
},
|
|
21
33
|
"files": [
|
|
22
34
|
"dist"
|
|
23
35
|
],
|
|
24
36
|
"dependencies": {
|
|
25
37
|
"fast-glob": "^3.3.0",
|
|
38
|
+
"p-limit": "^7.3.0",
|
|
26
39
|
"zod": "^3.24.0"
|
|
27
40
|
},
|
|
28
41
|
"peerDependencies": {
|
|
29
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
42
|
+
"@robota-sdk/agent-core": "3.0.0-beta.71"
|
|
30
43
|
},
|
|
31
44
|
"devDependencies": {
|
|
32
45
|
"openapi-types": "^12.1.3",
|
|
33
46
|
"rimraf": "^5.0.5",
|
|
34
|
-
"
|
|
47
|
+
"tsdown": "^0.22.0",
|
|
35
48
|
"typescript": "^5.3.3",
|
|
36
49
|
"vitest": "^1.6.1",
|
|
37
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
50
|
+
"@robota-sdk/agent-core": "3.0.0-beta.71"
|
|
38
51
|
},
|
|
39
52
|
"license": "MIT",
|
|
40
53
|
"publishConfig": {
|
|
41
54
|
"access": "public"
|
|
42
55
|
},
|
|
43
56
|
"scripts": {
|
|
44
|
-
"build": "
|
|
57
|
+
"build": "tsdown",
|
|
58
|
+
"build:js": "tsdown --no-dts",
|
|
59
|
+
"build:types": "tsdown --dts",
|
|
45
60
|
"test": "vitest run --passWithNoTests",
|
|
61
|
+
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
46
62
|
"typecheck": "tsc --noEmit",
|
|
47
63
|
"lint": "eslint src/ --ext .ts,.tsx",
|
|
48
64
|
"lint:fix": "eslint src/ --ext .ts,.tsx --fix",
|