runtimes/server-interface/agent.ts (107 lines of code) (raw):
import { CancellationToken } from '../protocol'
interface BaseSchema {
title?: string
description?: string
default?: any
examples?: any[]
$id?: string
$schema?: string
definitions?: Record<string, JSONSchema>
[extensionKeywords: string]: any
}
interface StringSchema extends BaseSchema {
type: 'string'
minLength?: number
maxLength?: number
pattern?: string
format?: string
enum?: string[]
}
interface NumberSchema extends BaseSchema {
type: 'number' | 'integer'
minimum?: number
maximum?: number
exclusiveMinimum?: number
exclusiveMaximum?: number
multipleOf?: number
enum?: number[]
}
interface BooleanSchema extends BaseSchema {
type: 'boolean'
enum?: boolean[]
}
interface ArraySchema extends BaseSchema {
type: 'array'
items: JSONSchema | JSONSchema[]
minItems?: number
maxItems?: number
uniqueItems?: boolean
additionalItems?: boolean | JSONSchema
}
export interface ObjectSchema extends BaseSchema {
type: 'object'
properties?: Record<string, JSONSchema>
required?: readonly string[]
additionalProperties?: boolean | JSONSchema
minProperties?: number
maxProperties?: number
patternProperties?: Record<string, JSONSchema>
dependencies?: Record<string, JSONSchema | string[]>
}
type JSONSchema = (StringSchema | NumberSchema | BooleanSchema | ArraySchema | ObjectSchema) & {
$ref?: string
allOf?: JSONSchema[]
anyOf?: JSONSchema[]
oneOf?: JSONSchema[]
not?: JSONSchema
}
type Primitive<T extends { type: string }> = T['type'] extends 'string'
? string
: T['type'] extends 'number'
? number
: T['type'] extends 'boolean'
? boolean
: T['type'] extends 'null'
? null
: never
type InferArray<T extends { type: 'array'; items: any }> = T['items'] extends { type: string }
? InferSchema<T['items']>[]
: never
type InferObject<T extends { type: 'object'; properties: Record<string, any> }> = T extends {
required: readonly string[]
}
? {
[K in keyof T['properties'] as K extends T['required'][number] ? K : never]: InferSchema<T['properties'][K]>
} & {
[K in keyof T['properties'] as K extends T['required'][number] ? never : K]?: InferSchema<T['properties'][K]>
}
: {
[K in keyof T['properties']]?: InferSchema<T['properties'][K]>
}
export type InferSchema<T> = T extends { type: 'array'; items: any }
? InferArray<T>
: T extends { type: 'object'; properties: Record<string, any> }
? InferObject<T>
: T extends { type: string }
? Primitive<T>
: never
export type ToolSpec = {
name: string
description: string
inputSchema: ObjectSchema
}
export type GetToolsOptions = {
format: 'bedrock' | 'mcp'
}
export type Tools = ToolSpec[]
export type BedrockTools = {
toolSpecification: Omit<ToolSpec, 'inputSchema'> & { inputSchema: { json: ToolSpec['inputSchema'] } }
}[]
export type Agent = {
/**
* Add a tool to the local tool repository. Tools with the same name will be overwritten.
*
* Tools should be called using `runTool`.
*
* @param spec Tool Specification
* @param handler The async method to execute when the tool is called
*/
addTool: <T extends InferSchema<S['inputSchema']>, S extends ToolSpec, R>(
spec: S,
handler: (input: T, token?: CancellationToken, updates?: WritableStream) => Promise<R>
) => void
/**
* Run a tool by name. This method will lookup the tool in the local tool repository and
* validate the input against the tool's schema.
*
* Throws an error if the tool is not found, or if validation fails.
*
* @param toolName The name of the tool to run
* @param input The input to the tool
* @returns The result of the tool execution
*/
runTool: (toolName: string, input: any, token?: CancellationToken, updates?: WritableStream) => Promise<any>
/**
* Get the list of tools in the local tool repository.
* @param options Options for the format of the output. Can be either 'bedrock' or 'mcp' (the default)
* @returns The tool repository in the requested output format
*/
getTools: <T extends GetToolsOptions>(options?: T) => T extends { format: 'bedrock' } ? BedrockTools : Tools
}