@providerprotocol/ai 0.0.1

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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/dist/anthropic/index.d.ts +41 -0
  4. package/dist/anthropic/index.js +500 -0
  5. package/dist/anthropic/index.js.map +1 -0
  6. package/dist/chunk-CUCRF5W6.js +136 -0
  7. package/dist/chunk-CUCRF5W6.js.map +1 -0
  8. package/dist/chunk-FTFX2VET.js +424 -0
  9. package/dist/chunk-FTFX2VET.js.map +1 -0
  10. package/dist/chunk-QUUX4G7U.js +117 -0
  11. package/dist/chunk-QUUX4G7U.js.map +1 -0
  12. package/dist/chunk-Y6Q7JCNP.js +39 -0
  13. package/dist/chunk-Y6Q7JCNP.js.map +1 -0
  14. package/dist/google/index.d.ts +69 -0
  15. package/dist/google/index.js +517 -0
  16. package/dist/google/index.js.map +1 -0
  17. package/dist/http/index.d.ts +61 -0
  18. package/dist/http/index.js +43 -0
  19. package/dist/http/index.js.map +1 -0
  20. package/dist/index.d.ts +792 -0
  21. package/dist/index.js +898 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/openai/index.d.ts +204 -0
  24. package/dist/openai/index.js +1340 -0
  25. package/dist/openai/index.js.map +1 -0
  26. package/dist/provider-CUJWjgNl.d.ts +192 -0
  27. package/dist/retry-I2661_rv.d.ts +118 -0
  28. package/package.json +88 -0
  29. package/src/anthropic/index.ts +3 -0
  30. package/src/core/image.ts +188 -0
  31. package/src/core/llm.ts +619 -0
  32. package/src/core/provider.ts +92 -0
  33. package/src/google/index.ts +3 -0
  34. package/src/http/errors.ts +112 -0
  35. package/src/http/fetch.ts +210 -0
  36. package/src/http/index.ts +31 -0
  37. package/src/http/keys.ts +136 -0
  38. package/src/http/retry.ts +205 -0
  39. package/src/http/sse.ts +136 -0
  40. package/src/index.ts +32 -0
  41. package/src/openai/index.ts +9 -0
  42. package/src/providers/anthropic/index.ts +17 -0
  43. package/src/providers/anthropic/llm.ts +196 -0
  44. package/src/providers/anthropic/transform.ts +452 -0
  45. package/src/providers/anthropic/types.ts +213 -0
  46. package/src/providers/google/index.ts +17 -0
  47. package/src/providers/google/llm.ts +203 -0
  48. package/src/providers/google/transform.ts +487 -0
  49. package/src/providers/google/types.ts +214 -0
  50. package/src/providers/openai/index.ts +151 -0
  51. package/src/providers/openai/llm.completions.ts +201 -0
  52. package/src/providers/openai/llm.responses.ts +211 -0
  53. package/src/providers/openai/transform.completions.ts +628 -0
  54. package/src/providers/openai/transform.responses.ts +718 -0
  55. package/src/providers/openai/types.ts +711 -0
  56. package/src/types/content.ts +133 -0
  57. package/src/types/errors.ts +85 -0
  58. package/src/types/index.ts +105 -0
  59. package/src/types/llm.ts +211 -0
  60. package/src/types/messages.ts +182 -0
  61. package/src/types/provider.ts +195 -0
  62. package/src/types/schema.ts +58 -0
  63. package/src/types/stream.ts +146 -0
  64. package/src/types/thread.ts +226 -0
  65. package/src/types/tool.ts +88 -0
  66. package/src/types/turn.ts +118 -0
  67. package/src/utils/id.ts +28 -0
@@ -0,0 +1,195 @@
1
+ import type { UPPError } from './errors.ts';
2
+
3
+ /**
4
+ * API key strategy interface for managing multiple keys
5
+ */
6
+ export interface KeyStrategy {
7
+ /** Get the next API key to use */
8
+ getKey(): string | Promise<string>;
9
+ }
10
+
11
+ /**
12
+ * Retry strategy interface
13
+ */
14
+ export interface RetryStrategy {
15
+ /**
16
+ * Called when a request fails with a retryable error.
17
+ * @param error - The error that occurred
18
+ * @param attempt - The attempt number (1 = first retry)
19
+ * @returns Delay in ms before retrying, or null to stop retrying
20
+ */
21
+ onRetry(error: UPPError, attempt: number): number | null | Promise<number | null>;
22
+
23
+ /**
24
+ * Called before each request. Can be used to implement pre-emptive rate limiting.
25
+ * Returns delay in ms to wait before making the request, or 0 to proceed immediately.
26
+ */
27
+ beforeRequest?(): number | Promise<number>;
28
+
29
+ /**
30
+ * Reset the strategy state (e.g., after a successful request)
31
+ */
32
+ reset?(): void;
33
+ }
34
+
35
+ /**
36
+ * Provider configuration for infrastructure/connection settings
37
+ */
38
+ export interface ProviderConfig {
39
+ /**
40
+ * API key - string, async function, or key strategy
41
+ * @example 'sk-xxx'
42
+ * @example () => fetchKeyFromVault()
43
+ * @example new RoundRobinKeys(['sk-1', 'sk-2'])
44
+ */
45
+ apiKey?: string | (() => string | Promise<string>) | KeyStrategy;
46
+
47
+ /** Override the base API URL (for proxies, local models) */
48
+ baseUrl?: string;
49
+
50
+ /** Request timeout in milliseconds */
51
+ timeout?: number;
52
+
53
+ /** Custom fetch implementation (for logging, caching, custom TLS) */
54
+ fetch?: typeof fetch;
55
+
56
+ /** API version override */
57
+ apiVersion?: string;
58
+
59
+ /** Retry strategy for handling failures and rate limits */
60
+ retryStrategy?: RetryStrategy;
61
+ }
62
+
63
+ /**
64
+ * A reference to a model, created by a provider factory
65
+ *
66
+ * @typeParam TOptions - Provider-specific options type
67
+ */
68
+ export interface ModelReference<TOptions = unknown> {
69
+ /** The model identifier */
70
+ readonly modelId: string;
71
+
72
+ /** The provider that created this reference */
73
+ readonly provider: Provider<TOptions>;
74
+ }
75
+
76
+ // Forward declarations for handler types (defined in llm.ts)
77
+ // We use 'any' here since the full types are circular
78
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
+ export interface LLMHandler<TParams = any> {
80
+ /** Bind model ID to create executable model */
81
+ bind(modelId: string): BoundLLMModel<TParams>;
82
+
83
+ /**
84
+ * Internal: Set the parent provider reference.
85
+ * Called by createProvider() after the provider is constructed.
86
+ * This allows bind() to return models with the correct provider reference.
87
+ * @internal
88
+ */
89
+ _setProvider?(provider: LLMProvider<TParams>): void;
90
+ }
91
+
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ export interface EmbeddingHandler<TParams = any> {
94
+ /** Supported input types */
95
+ readonly supportedInputs: ('text' | 'image')[];
96
+ /** Bind model ID to create executable model */
97
+ bind(modelId: string): BoundEmbeddingModel<TParams>;
98
+
99
+ /**
100
+ * Internal: Set the parent provider reference.
101
+ * @internal
102
+ */
103
+ _setProvider?(provider: EmbeddingProvider<TParams>): void;
104
+ }
105
+
106
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
+ export interface ImageHandler<TParams = any> {
108
+ /** Bind model ID to create executable model */
109
+ bind(modelId: string): BoundImageModel<TParams>;
110
+
111
+ /**
112
+ * Internal: Set the parent provider reference.
113
+ * @internal
114
+ */
115
+ _setProvider?(provider: ImageProvider<TParams>): void;
116
+ }
117
+
118
+ // Forward declarations for bound models
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ export interface BoundLLMModel<TParams = any> {
121
+ readonly modelId: string;
122
+ readonly provider: LLMProvider<TParams>;
123
+ // Methods defined in llm.ts
124
+ }
125
+
126
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
+ export interface BoundEmbeddingModel<TParams = any> {
128
+ readonly modelId: string;
129
+ readonly provider: EmbeddingProvider<TParams>;
130
+ readonly maxBatchSize: number;
131
+ readonly maxInputLength: number;
132
+ readonly dimensions: number;
133
+ }
134
+
135
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
+ export interface BoundImageModel<TParams = any> {
137
+ readonly modelId: string;
138
+ readonly provider: ImageProvider<TParams>;
139
+ }
140
+
141
+ /**
142
+ * A provider factory function with metadata and modality handlers.
143
+ *
144
+ * @typeParam TOptions - Provider-specific options passed to the factory function
145
+ */
146
+ export interface Provider<TOptions = unknown> {
147
+ /** Create a model reference, optionally with provider-specific options */
148
+ (modelId: string, options?: TOptions): ModelReference<TOptions>;
149
+
150
+ /** Provider name */
151
+ readonly name: string;
152
+
153
+ /** Provider version */
154
+ readonly version: string;
155
+
156
+ /** Supported modalities */
157
+ readonly modalities: {
158
+ llm?: LLMHandler;
159
+ embedding?: EmbeddingHandler;
160
+ image?: ImageHandler;
161
+ };
162
+ }
163
+
164
+ /**
165
+ * Provider with LLM modality
166
+ *
167
+ * @typeParam TParams - Model-specific parameters type
168
+ * @typeParam TOptions - Provider-specific options type
169
+ */
170
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
171
+ export type LLMProvider<TParams = any, TOptions = unknown> = Provider<TOptions> & {
172
+ readonly modalities: { llm: LLMHandler<TParams> };
173
+ };
174
+
175
+ /**
176
+ * Provider with Embedding modality
177
+ *
178
+ * @typeParam TParams - Model-specific parameters type
179
+ * @typeParam TOptions - Provider-specific options type
180
+ */
181
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
182
+ export type EmbeddingProvider<TParams = any, TOptions = unknown> = Provider<TOptions> & {
183
+ readonly modalities: { embedding: EmbeddingHandler<TParams> };
184
+ };
185
+
186
+ /**
187
+ * Provider with Image modality
188
+ *
189
+ * @typeParam TParams - Model-specific parameters type
190
+ * @typeParam TOptions - Provider-specific options type
191
+ */
192
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
+ export type ImageProvider<TParams = any, TOptions = unknown> = Provider<TOptions> & {
194
+ readonly modalities: { image: ImageHandler<TParams> };
195
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * JSON Schema types for tool parameters and structured outputs
3
+ */
4
+
5
+ export type JSONSchemaPropertyType =
6
+ | 'string'
7
+ | 'number'
8
+ | 'integer'
9
+ | 'boolean'
10
+ | 'array'
11
+ | 'object'
12
+ | 'null';
13
+
14
+ /**
15
+ * JSON Schema property definition
16
+ */
17
+ export interface JSONSchemaProperty {
18
+ type: JSONSchemaPropertyType;
19
+ description?: string;
20
+ enum?: unknown[];
21
+ const?: unknown;
22
+ default?: unknown;
23
+
24
+ // String-specific
25
+ minLength?: number;
26
+ maxLength?: number;
27
+ pattern?: string;
28
+ format?: 'email' | 'uri' | 'date' | 'date-time' | 'uuid';
29
+
30
+ // Number-specific
31
+ minimum?: number;
32
+ maximum?: number;
33
+ exclusiveMinimum?: number;
34
+ exclusiveMaximum?: number;
35
+ multipleOf?: number;
36
+
37
+ // Array-specific
38
+ items?: JSONSchemaProperty;
39
+ minItems?: number;
40
+ maxItems?: number;
41
+ uniqueItems?: boolean;
42
+
43
+ // Object-specific
44
+ properties?: Record<string, JSONSchemaProperty>;
45
+ required?: string[];
46
+ additionalProperties?: boolean;
47
+ }
48
+
49
+ /**
50
+ * JSON Schema for tool parameters or structured outputs
51
+ */
52
+ export interface JSONSchema {
53
+ type: 'object';
54
+ properties: Record<string, JSONSchemaProperty>;
55
+ required?: string[];
56
+ additionalProperties?: boolean;
57
+ description?: string;
58
+ }
@@ -0,0 +1,146 @@
1
+ import type { Turn } from './turn.ts';
2
+
3
+ /**
4
+ * Stream event types
5
+ */
6
+ export type StreamEventType =
7
+ | 'text_delta'
8
+ | 'reasoning_delta'
9
+ | 'image_delta'
10
+ | 'audio_delta'
11
+ | 'video_delta'
12
+ | 'tool_call_delta'
13
+ | 'message_start'
14
+ | 'message_stop'
15
+ | 'content_block_start'
16
+ | 'content_block_stop';
17
+
18
+ /**
19
+ * Event delta data (type-specific)
20
+ */
21
+ export interface EventDelta {
22
+ text?: string;
23
+ data?: Uint8Array;
24
+ toolCallId?: string;
25
+ toolName?: string;
26
+ argumentsJson?: string;
27
+ }
28
+
29
+ /**
30
+ * A streaming event
31
+ */
32
+ export interface StreamEvent {
33
+ /** Event type */
34
+ type: StreamEventType;
35
+
36
+ /** Index of the content block this event belongs to */
37
+ index: number;
38
+
39
+ /** Event data (type-specific) */
40
+ delta: EventDelta;
41
+ }
42
+
43
+ /**
44
+ * Stream result - async iterable that also provides final turn
45
+ */
46
+ export interface StreamResult<TData = unknown>
47
+ extends AsyncIterable<StreamEvent> {
48
+ /**
49
+ * Get the complete Turn after streaming finishes.
50
+ * Resolves when the stream completes.
51
+ */
52
+ readonly turn: Promise<Turn<TData>>;
53
+
54
+ /** Abort the stream */
55
+ abort(): void;
56
+ }
57
+
58
+ /**
59
+ * Create a stream result from an async generator and completion promise
60
+ */
61
+ export function createStreamResult<TData = unknown>(
62
+ generator: AsyncGenerator<StreamEvent, void, unknown>,
63
+ turnPromise: Promise<Turn<TData>>,
64
+ abortController: AbortController
65
+ ): StreamResult<TData> {
66
+ return {
67
+ [Symbol.asyncIterator]() {
68
+ return generator;
69
+ },
70
+ turn: turnPromise,
71
+ abort() {
72
+ abortController.abort();
73
+ },
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Create a text delta event
79
+ */
80
+ export function textDelta(text: string, index = 0): StreamEvent {
81
+ return {
82
+ type: 'text_delta',
83
+ index,
84
+ delta: { text },
85
+ };
86
+ }
87
+
88
+ /**
89
+ * Create a tool call delta event
90
+ */
91
+ export function toolCallDelta(
92
+ toolCallId: string,
93
+ toolName: string,
94
+ argumentsJson: string,
95
+ index = 0
96
+ ): StreamEvent {
97
+ return {
98
+ type: 'tool_call_delta',
99
+ index,
100
+ delta: { toolCallId, toolName, argumentsJson },
101
+ };
102
+ }
103
+
104
+ /**
105
+ * Create a message start event
106
+ */
107
+ export function messageStart(): StreamEvent {
108
+ return {
109
+ type: 'message_start',
110
+ index: 0,
111
+ delta: {},
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Create a message stop event
117
+ */
118
+ export function messageStop(): StreamEvent {
119
+ return {
120
+ type: 'message_stop',
121
+ index: 0,
122
+ delta: {},
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Create a content block start event
128
+ */
129
+ export function contentBlockStart(index: number): StreamEvent {
130
+ return {
131
+ type: 'content_block_start',
132
+ index,
133
+ delta: {},
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Create a content block stop event
139
+ */
140
+ export function contentBlockStop(index: number): StreamEvent {
141
+ return {
142
+ type: 'content_block_stop',
143
+ index,
144
+ delta: {},
145
+ };
146
+ }
@@ -0,0 +1,226 @@
1
+ import { generateId } from '../utils/id.ts';
2
+ import {
3
+ Message,
4
+ UserMessage,
5
+ AssistantMessage,
6
+ ToolResultMessage,
7
+ } from './messages.ts';
8
+ import type { MessageType, MessageMetadata } from './messages.ts';
9
+ import type { ContentBlock, UserContent, AssistantContent } from './content.ts';
10
+ import type { Turn } from './turn.ts';
11
+ import type { ToolCall, ToolResult } from './tool.ts';
12
+
13
+ /**
14
+ * Serialized message format
15
+ */
16
+ export interface MessageJSON {
17
+ id: string;
18
+ type: MessageType;
19
+ content: ContentBlock[];
20
+ toolCalls?: ToolCall[];
21
+ results?: ToolResult[];
22
+ metadata?: MessageMetadata;
23
+ timestamp: string;
24
+ }
25
+
26
+ /**
27
+ * Serialized thread format
28
+ */
29
+ export interface ThreadJSON {
30
+ id: string;
31
+ messages: MessageJSON[];
32
+ createdAt: string;
33
+ updatedAt: string;
34
+ }
35
+
36
+ /**
37
+ * Thread - A utility class for managing conversation history
38
+ * Users control their own history; Thread is optional
39
+ */
40
+ export class Thread {
41
+ /** Unique thread identifier */
42
+ readonly id: string;
43
+
44
+ /** Internal message storage */
45
+ private _messages: Message[];
46
+
47
+ /** Creation timestamp */
48
+ private _createdAt: Date;
49
+
50
+ /** Last update timestamp */
51
+ private _updatedAt: Date;
52
+
53
+ /**
54
+ * Create a new thread, optionally with initial messages
55
+ */
56
+ constructor(messages?: Message[]) {
57
+ this.id = generateId();
58
+ this._messages = messages ? [...messages] : [];
59
+ this._createdAt = new Date();
60
+ this._updatedAt = new Date();
61
+ }
62
+
63
+ /** All messages in the thread (readonly) */
64
+ get messages(): readonly Message[] {
65
+ return this._messages;
66
+ }
67
+
68
+ /** Number of messages */
69
+ get length(): number {
70
+ return this._messages.length;
71
+ }
72
+
73
+ /**
74
+ * Append messages from a turn
75
+ */
76
+ append(turn: Turn): this {
77
+ this._messages.push(...turn.messages);
78
+ this._updatedAt = new Date();
79
+ return this;
80
+ }
81
+
82
+ /**
83
+ * Add raw messages
84
+ */
85
+ push(...messages: Message[]): this {
86
+ this._messages.push(...messages);
87
+ this._updatedAt = new Date();
88
+ return this;
89
+ }
90
+
91
+ /**
92
+ * Add a user message
93
+ */
94
+ user(content: string | UserContent[]): this {
95
+ this._messages.push(new UserMessage(content));
96
+ this._updatedAt = new Date();
97
+ return this;
98
+ }
99
+
100
+ /**
101
+ * Add an assistant message
102
+ */
103
+ assistant(content: string | AssistantContent[]): this {
104
+ this._messages.push(new AssistantMessage(content));
105
+ this._updatedAt = new Date();
106
+ return this;
107
+ }
108
+
109
+ /**
110
+ * Get messages by type
111
+ */
112
+ filter(type: MessageType): Message[] {
113
+ return this._messages.filter((m) => m.type === type);
114
+ }
115
+
116
+ /**
117
+ * Get the last N messages
118
+ */
119
+ tail(count: number): Message[] {
120
+ return this._messages.slice(-count);
121
+ }
122
+
123
+ /**
124
+ * Create a new thread with a subset of messages
125
+ */
126
+ slice(start?: number, end?: number): Thread {
127
+ return new Thread(this._messages.slice(start, end));
128
+ }
129
+
130
+ /**
131
+ * Clear all messages
132
+ */
133
+ clear(): this {
134
+ this._messages = [];
135
+ this._updatedAt = new Date();
136
+ return this;
137
+ }
138
+
139
+ /**
140
+ * Convert to plain message array
141
+ */
142
+ toMessages(): Message[] {
143
+ return [...this._messages];
144
+ }
145
+
146
+ /**
147
+ * Serialize to JSON
148
+ */
149
+ toJSON(): ThreadJSON {
150
+ return {
151
+ id: this.id,
152
+ messages: this._messages.map((m) => this.messageToJSON(m)),
153
+ createdAt: this._createdAt.toISOString(),
154
+ updatedAt: this._updatedAt.toISOString(),
155
+ };
156
+ }
157
+
158
+ /**
159
+ * Deserialize from JSON
160
+ */
161
+ static fromJSON(json: ThreadJSON): Thread {
162
+ const messages = json.messages.map((m) => Thread.messageFromJSON(m));
163
+ const thread = new Thread(messages);
164
+ // Override the generated id with the serialized one
165
+ (thread as { id: string }).id = json.id;
166
+ thread._createdAt = new Date(json.createdAt);
167
+ thread._updatedAt = new Date(json.updatedAt);
168
+ return thread;
169
+ }
170
+
171
+ /**
172
+ * Iterate over messages
173
+ */
174
+ [Symbol.iterator](): Iterator<Message> {
175
+ return this._messages[Symbol.iterator]();
176
+ }
177
+
178
+ /**
179
+ * Convert a message to JSON
180
+ */
181
+ private messageToJSON(m: Message): MessageJSON {
182
+ const base: MessageJSON = {
183
+ id: m.id,
184
+ type: m.type,
185
+ content: [],
186
+ metadata: m.metadata,
187
+ timestamp: m.timestamp.toISOString(),
188
+ };
189
+
190
+ if (m instanceof UserMessage) {
191
+ base.content = m.content;
192
+ } else if (m instanceof AssistantMessage) {
193
+ base.content = m.content;
194
+ base.toolCalls = m.toolCalls;
195
+ } else if (m instanceof ToolResultMessage) {
196
+ base.results = m.results;
197
+ }
198
+
199
+ return base;
200
+ }
201
+
202
+ /**
203
+ * Reconstruct a message from JSON
204
+ */
205
+ private static messageFromJSON(json: MessageJSON): Message {
206
+ const options = {
207
+ id: json.id,
208
+ metadata: json.metadata,
209
+ };
210
+
211
+ switch (json.type) {
212
+ case 'user':
213
+ return new UserMessage(json.content as UserContent[], options);
214
+ case 'assistant':
215
+ return new AssistantMessage(
216
+ json.content as AssistantContent[],
217
+ json.toolCalls,
218
+ options
219
+ );
220
+ case 'tool_result':
221
+ return new ToolResultMessage(json.results ?? [], options);
222
+ default:
223
+ throw new Error(`Unknown message type: ${json.type}`);
224
+ }
225
+ }
226
+ }
@@ -0,0 +1,88 @@
1
+ import type { JSONSchema } from './schema.ts';
2
+
3
+ /**
4
+ * Tool call requested by the model
5
+ */
6
+ export interface ToolCall {
7
+ toolCallId: string;
8
+ toolName: string;
9
+ arguments: Record<string, unknown>;
10
+ }
11
+
12
+ /**
13
+ * Result of tool execution
14
+ */
15
+ export interface ToolResult {
16
+ toolCallId: string;
17
+ result: unknown;
18
+ isError?: boolean;
19
+ }
20
+
21
+ /**
22
+ * Tool definition
23
+ */
24
+ export interface Tool<TParams = unknown, TResult = unknown> {
25
+ /** Tool name (must be unique within a llm() instance) */
26
+ name: string;
27
+
28
+ /** Human-readable description for the model */
29
+ description: string;
30
+
31
+ /** JSON Schema defining parameters */
32
+ parameters: JSONSchema;
33
+
34
+ /** Tool execution function */
35
+ run(params: TParams): TResult | Promise<TResult>;
36
+
37
+ /** Optional approval handler for sensitive operations */
38
+ approval?(params: TParams): boolean | Promise<boolean>;
39
+ }
40
+
41
+ /**
42
+ * Strategy for tool execution
43
+ */
44
+ export interface ToolUseStrategy {
45
+ /** Maximum tool execution rounds (default: 10) */
46
+ maxIterations?: number;
47
+
48
+ /** Called when the model requests a tool call */
49
+ onToolCall?(tool: Tool, params: unknown): void | Promise<void>;
50
+
51
+ /** Called before tool execution, return false to skip */
52
+ onBeforeCall?(tool: Tool, params: unknown): boolean | Promise<boolean>;
53
+
54
+ /** Called after tool execution */
55
+ onAfterCall?(tool: Tool, params: unknown, result: unknown): void | Promise<void>;
56
+
57
+ /** Called on tool execution error */
58
+ onError?(tool: Tool, params: unknown, error: Error): void | Promise<void>;
59
+
60
+ /** Called when max iterations reached */
61
+ onMaxIterations?(iterations: number): void | Promise<void>;
62
+ }
63
+
64
+ /**
65
+ * Record of a tool execution
66
+ */
67
+ export interface ToolExecution {
68
+ /** The tool that was called */
69
+ toolName: string;
70
+
71
+ /** Tool call ID */
72
+ toolCallId: string;
73
+
74
+ /** Arguments passed to the tool */
75
+ arguments: Record<string, unknown>;
76
+
77
+ /** Result returned by the tool */
78
+ result: unknown;
79
+
80
+ /** Whether the tool execution resulted in an error */
81
+ isError: boolean;
82
+
83
+ /** Execution duration in milliseconds */
84
+ duration: number;
85
+
86
+ /** Whether approval was required and granted */
87
+ approved?: boolean;
88
+ }