@openrouter/agent 0.1.0

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 (98) hide show
  1. package/README.md +367 -0
  2. package/esm/api-shape-helpers/claude-message.d.ts +218 -0
  3. package/esm/api-shape-helpers/claude-message.d.ts.map +1 -0
  4. package/esm/api-shape-helpers/claude-message.js +6 -0
  5. package/esm/api-shape-helpers/claude-message.js.map +1 -0
  6. package/esm/index.d.ts +22 -0
  7. package/esm/index.d.ts.map +1 -0
  8. package/esm/index.js +27 -0
  9. package/esm/index.js.map +1 -0
  10. package/esm/inner-loop/call-model.d.ts +67 -0
  11. package/esm/inner-loop/call-model.d.ts.map +1 -0
  12. package/esm/inner-loop/call-model.js +116 -0
  13. package/esm/inner-loop/call-model.js.map +1 -0
  14. package/esm/lib/anthropic-compat.d.ts +51 -0
  15. package/esm/lib/anthropic-compat.d.ts.map +1 -0
  16. package/esm/lib/anthropic-compat.js +216 -0
  17. package/esm/lib/anthropic-compat.js.map +1 -0
  18. package/esm/lib/anthropic-compat.test.d.ts +2 -0
  19. package/esm/lib/anthropic-compat.test.d.ts.map +1 -0
  20. package/esm/lib/anthropic-compat.test.js +668 -0
  21. package/esm/lib/anthropic-compat.test.js.map +1 -0
  22. package/esm/lib/async-params.d.ts +107 -0
  23. package/esm/lib/async-params.d.ts.map +1 -0
  24. package/esm/lib/async-params.js +94 -0
  25. package/esm/lib/async-params.js.map +1 -0
  26. package/esm/lib/chat-compat.d.ts +46 -0
  27. package/esm/lib/chat-compat.d.ts.map +1 -0
  28. package/esm/lib/chat-compat.js +111 -0
  29. package/esm/lib/chat-compat.js.map +1 -0
  30. package/esm/lib/chat-compat.test.d.ts +2 -0
  31. package/esm/lib/chat-compat.test.d.ts.map +1 -0
  32. package/esm/lib/chat-compat.test.js +405 -0
  33. package/esm/lib/chat-compat.test.js.map +1 -0
  34. package/esm/lib/claude-constants.d.ts +22 -0
  35. package/esm/lib/claude-constants.d.ts.map +1 -0
  36. package/esm/lib/claude-constants.js +20 -0
  37. package/esm/lib/claude-constants.js.map +1 -0
  38. package/esm/lib/claude-type-guards.d.ts +10 -0
  39. package/esm/lib/claude-type-guards.d.ts.map +1 -0
  40. package/esm/lib/claude-type-guards.js +68 -0
  41. package/esm/lib/claude-type-guards.js.map +1 -0
  42. package/esm/lib/conversation-state.d.ts +61 -0
  43. package/esm/lib/conversation-state.d.ts.map +1 -0
  44. package/esm/lib/conversation-state.js +230 -0
  45. package/esm/lib/conversation-state.js.map +1 -0
  46. package/esm/lib/model-result.d.ts +370 -0
  47. package/esm/lib/model-result.d.ts.map +1 -0
  48. package/esm/lib/model-result.js +1483 -0
  49. package/esm/lib/model-result.js.map +1 -0
  50. package/esm/lib/next-turn-params.d.ts +30 -0
  51. package/esm/lib/next-turn-params.d.ts.map +1 -0
  52. package/esm/lib/next-turn-params.js +129 -0
  53. package/esm/lib/next-turn-params.js.map +1 -0
  54. package/esm/lib/reusable-stream.d.ts +39 -0
  55. package/esm/lib/reusable-stream.d.ts.map +1 -0
  56. package/esm/lib/reusable-stream.js +192 -0
  57. package/esm/lib/reusable-stream.js.map +1 -0
  58. package/esm/lib/stop-conditions.d.ts +80 -0
  59. package/esm/lib/stop-conditions.d.ts.map +1 -0
  60. package/esm/lib/stop-conditions.js +104 -0
  61. package/esm/lib/stop-conditions.js.map +1 -0
  62. package/esm/lib/stream-transformers.d.ts +109 -0
  63. package/esm/lib/stream-transformers.d.ts.map +1 -0
  64. package/esm/lib/stream-transformers.js +856 -0
  65. package/esm/lib/stream-transformers.js.map +1 -0
  66. package/esm/lib/stream-type-guards.d.ts +29 -0
  67. package/esm/lib/stream-type-guards.d.ts.map +1 -0
  68. package/esm/lib/stream-type-guards.js +85 -0
  69. package/esm/lib/stream-type-guards.js.map +1 -0
  70. package/esm/lib/tool-context.d.ts +68 -0
  71. package/esm/lib/tool-context.d.ts.map +1 -0
  72. package/esm/lib/tool-context.js +188 -0
  73. package/esm/lib/tool-context.js.map +1 -0
  74. package/esm/lib/tool-event-broadcaster.d.ts +44 -0
  75. package/esm/lib/tool-event-broadcaster.d.ts.map +1 -0
  76. package/esm/lib/tool-event-broadcaster.js +162 -0
  77. package/esm/lib/tool-event-broadcaster.js.map +1 -0
  78. package/esm/lib/tool-executor.d.ts +73 -0
  79. package/esm/lib/tool-executor.d.ts.map +1 -0
  80. package/esm/lib/tool-executor.js +267 -0
  81. package/esm/lib/tool-executor.js.map +1 -0
  82. package/esm/lib/tool-orchestrator.d.ts +50 -0
  83. package/esm/lib/tool-orchestrator.d.ts.map +1 -0
  84. package/esm/lib/tool-orchestrator.js +180 -0
  85. package/esm/lib/tool-orchestrator.js.map +1 -0
  86. package/esm/lib/tool-types.d.ts +572 -0
  87. package/esm/lib/tool-types.d.ts.map +1 -0
  88. package/esm/lib/tool-types.js +80 -0
  89. package/esm/lib/tool-types.js.map +1 -0
  90. package/esm/lib/tool.d.ts +108 -0
  91. package/esm/lib/tool.d.ts.map +1 -0
  92. package/esm/lib/tool.js +84 -0
  93. package/esm/lib/tool.js.map +1 -0
  94. package/esm/lib/turn-context.d.ts +50 -0
  95. package/esm/lib/turn-context.d.ts.map +1 -0
  96. package/esm/lib/turn-context.js +61 -0
  97. package/esm/lib/turn-context.js.map +1 -0
  98. package/package.json +125 -0
package/README.md ADDED
@@ -0,0 +1,367 @@
1
+ # OpenRouter Agent (Beta)
2
+
3
+ Agent toolkit for building AI applications with [OpenRouter](https://openrouter.ai) — tool orchestration, streaming, multi-turn conversations, and format compatibility.
4
+
5
+ > [!IMPORTANT]
6
+ > This SDK is currently in beta. There may be breaking changes between versions.
7
+ > We recommend pinning to a specific version in your `package.json`.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ # npm
13
+ npm install @openrouter/agent
14
+
15
+ # pnpm
16
+ pnpm add @openrouter/agent
17
+
18
+ # bun
19
+ bun add @openrouter/agent
20
+
21
+ # yarn
22
+ yarn add @openrouter/agent
23
+ ```
24
+
25
+ > [!NOTE]
26
+ > This package is ESM-only. If you are using CommonJS, you can use `await import('@openrouter/agent')`.
27
+
28
+ ## Quick Start
29
+
30
+ ```typescript
31
+ import OpenRouter from '@openrouter/sdk';
32
+ import { callModel, tool } from '@openrouter/agent';
33
+ import { z } from 'zod';
34
+
35
+ const client = new OpenRouter({ apiKey: 'YOUR_API_KEY' });
36
+
37
+ const weatherTool = tool({
38
+ name: 'get_weather',
39
+ description: 'Get the current weather for a location',
40
+ inputSchema: z.object({ location: z.string() }),
41
+ execute: async ({ location }) => ({
42
+ temperature: 72,
43
+ condition: 'sunny',
44
+ location,
45
+ }),
46
+ });
47
+
48
+ const result = callModel(client, {
49
+ model: 'openai/gpt-4o',
50
+ input: 'What is the weather in San Francisco?',
51
+ tools: [weatherTool] as const,
52
+ });
53
+
54
+ // Get the final text response (tools are auto-executed)
55
+ const text = await result.getText();
56
+ console.log(text);
57
+ ```
58
+
59
+ ## Features
60
+
61
+ ### Multiple Response Consumption Patterns
62
+
63
+ `callModel` returns a `ModelResult` that supports many ways to consume the response — all usable concurrently on the same result:
64
+
65
+ ```typescript
66
+ const result = callModel(client, { model, input, tools });
67
+
68
+ // Await the final text
69
+ const text = await result.getText();
70
+
71
+ // Await the full response with usage data
72
+ const response = await result.getResponse();
73
+ console.log(response.usage); // { inputTokens, outputTokens, cost, ... }
74
+
75
+ // Stream text deltas
76
+ for await (const delta of result.getTextStream()) {
77
+ process.stdout.write(delta);
78
+ }
79
+
80
+ // Stream reasoning deltas
81
+ for await (const delta of result.getReasoningStream()) {
82
+ process.stdout.write(delta);
83
+ }
84
+
85
+ // Stream tool execution events
86
+ for await (const event of result.getToolStream()) {
87
+ console.log(event);
88
+ }
89
+
90
+ // Stream structured tool calls
91
+ for await (const toolCall of result.getToolCallsStream()) {
92
+ console.log(toolCall.name, toolCall.input);
93
+ }
94
+
95
+ // Get all tool calls after completion
96
+ const toolCalls = await result.getToolCalls();
97
+ ```
98
+
99
+ ### Tool Types
100
+
101
+ The `tool()` factory creates type-safe tools with full Zod schema inference. Three tool types are supported:
102
+
103
+ **Regular tools** — automatically executed by the agent loop:
104
+
105
+ ```typescript
106
+ const searchTool = tool({
107
+ name: 'search',
108
+ description: 'Search the web',
109
+ inputSchema: z.object({ query: z.string() }),
110
+ outputSchema: z.object({ results: z.array(z.string()) }),
111
+ execute: async ({ query }) => {
112
+ const results = await performSearch(query);
113
+ return { results };
114
+ },
115
+ });
116
+ ```
117
+
118
+ **Generator tools** — stream intermediate events during execution:
119
+
120
+ ```typescript
121
+ const analysisTool = tool({
122
+ name: 'analyze',
123
+ inputSchema: z.object({ data: z.string() }),
124
+ eventSchema: z.object({ progress: z.number() }),
125
+ outputSchema: z.object({ summary: z.string() }),
126
+ execute: async function* ({ data }) {
127
+ yield { progress: 0.5 };
128
+ // ... processing ...
129
+ return { summary: 'Analysis complete' };
130
+ },
131
+ });
132
+ ```
133
+
134
+ **Manual tools** — reported to the model but not auto-executed (for human-in-the-loop flows):
135
+
136
+ ```typescript
137
+ const confirmTool = tool({
138
+ name: 'confirm_action',
139
+ inputSchema: z.object({ action: z.string() }),
140
+ execute: false,
141
+ });
142
+ ```
143
+
144
+ ### Stop Conditions
145
+
146
+ Control when the agent loop stops executing tools:
147
+
148
+ ```typescript
149
+ import { callModel, stepCountIs, hasToolCall, maxTokensUsed, maxCost } from '@openrouter/agent';
150
+
151
+ const result = callModel(client, {
152
+ model: 'openai/gpt-4o',
153
+ input: 'Research this topic thoroughly',
154
+ tools: [searchTool, summarizeTool] as const,
155
+ // Single condition
156
+ stopWhen: stepCountIs(10),
157
+ // Or combine multiple (stops when ANY condition is met)
158
+ stopWhen: [stepCountIs(10), maxCost(0.50), hasToolCall('summarize')],
159
+ });
160
+ ```
161
+
162
+ Built-in stop conditions:
163
+
164
+ | Condition | Description |
165
+ |---|---|
166
+ | `stepCountIs(n)` | Stop after `n` tool execution steps (default: 5) |
167
+ | `hasToolCall(name)` | Stop when a specific tool is called |
168
+ | `maxTokensUsed(n)` | Stop when total tokens exceed a threshold |
169
+ | `maxCost(dollars)` | Stop when total cost exceeds a dollar amount |
170
+ | `finishReasonIs(reason)` | Stop on a specific finish reason |
171
+
172
+ ### Tool Approval
173
+
174
+ Gate tool execution with approval checks for sensitive operations:
175
+
176
+ ```typescript
177
+ const deleteTool = tool({
178
+ name: 'delete_record',
179
+ inputSchema: z.object({ id: z.string() }),
180
+ requireApproval: true, // Always require approval
181
+ execute: async ({ id }) => { /* ... */ },
182
+ });
183
+
184
+ // Or use a function for conditional approval
185
+ const writeTool = tool({
186
+ name: 'write_file',
187
+ inputSchema: z.object({ path: z.string(), content: z.string() }),
188
+ requireApproval: ({ path }) => path.startsWith('/etc'),
189
+ execute: async ({ path, content }) => { /* ... */ },
190
+ });
191
+
192
+ // Handle approvals at the callModel level
193
+ const result = callModel(client, {
194
+ model: 'openai/gpt-4o',
195
+ input: 'Delete record abc-123',
196
+ tools: [deleteTool] as const,
197
+ approveToolCalls: async (toolCalls) => {
198
+ // Return IDs of approved tool calls
199
+ return toolCalls.map(tc => tc.id);
200
+ },
201
+ });
202
+ ```
203
+
204
+ ### Tool Context
205
+
206
+ Provide typed context data to tools without passing it through the model:
207
+
208
+ ```typescript
209
+ const dbTool = tool({
210
+ name: 'query_db',
211
+ inputSchema: z.object({ sql: z.string() }),
212
+ contextSchema: z.object({ connectionString: z.string() }),
213
+ execute: async ({ sql }, ctx) => {
214
+ const db = connect(ctx?.context.connectionString);
215
+ return db.query(sql);
216
+ },
217
+ });
218
+
219
+ const result = callModel(client, {
220
+ model: 'openai/gpt-4o',
221
+ input: 'List all users',
222
+ tools: [dbTool] as const,
223
+ context: {
224
+ query_db: { connectionString: 'postgres://localhost/mydb' },
225
+ },
226
+ });
227
+ ```
228
+
229
+ ### Shared Context
230
+
231
+ Share mutable state across all tools in a conversation:
232
+
233
+ ```typescript
234
+ const result = callModel(client, {
235
+ model: 'openai/gpt-4o',
236
+ input: 'Process these items',
237
+ tools: [toolA, toolB] as const,
238
+ sharedContextSchema: z.object({ processedIds: z.array(z.string()) }),
239
+ context: {
240
+ shared: { processedIds: [] },
241
+ },
242
+ });
243
+ ```
244
+
245
+ ### Conversation State Management
246
+
247
+ Persist multi-turn conversations with full state tracking:
248
+
249
+ ```typescript
250
+ import { createInitialState, callModel } from '@openrouter/agent';
251
+
252
+ // Start a conversation
253
+ let state = createInitialState();
254
+
255
+ // First turn
256
+ const result1 = callModel(client, {
257
+ model: 'openai/gpt-4o',
258
+ input: 'Search for TypeScript best practices',
259
+ tools: [searchTool] as const,
260
+ state,
261
+ });
262
+
263
+ // State is updated with messages, tool calls, and metadata
264
+ state = (await result1.getResponse()).state;
265
+
266
+ // Continue the conversation
267
+ const result2 = callModel(client, {
268
+ model: 'openai/gpt-4o',
269
+ input: 'Now summarize what you found',
270
+ tools: [searchTool] as const,
271
+ state,
272
+ });
273
+ ```
274
+
275
+ ### Dynamic Parameters Between Turns
276
+
277
+ Adjust model parameters dynamically based on tool execution:
278
+
279
+ ```typescript
280
+ const searchTool = tool({
281
+ name: 'search',
282
+ inputSchema: z.object({ query: z.string() }),
283
+ nextTurnParams: {
284
+ temperature: (input) => input.query.includes('creative') ? 0.9 : 0.1,
285
+ maxOutputTokens: () => 2000,
286
+ },
287
+ execute: async ({ query }) => { /* ... */ },
288
+ });
289
+ ```
290
+
291
+ ### Format Compatibility
292
+
293
+ Convert between OpenRouter and other message formats:
294
+
295
+ ```typescript
296
+ import { toClaudeMessage, fromClaudeMessages } from '@openrouter/agent';
297
+ import { toChatMessage, fromChatMessages } from '@openrouter/agent';
298
+
299
+ // Anthropic Claude format
300
+ const claudeMsg = toClaudeMessage(openRouterMessage);
301
+ const orMessages = fromClaudeMessages(claudeMessages);
302
+
303
+ // Standard Chat format
304
+ const chatMsg = toChatMessage(openRouterMessage);
305
+ const orMessages2 = fromChatMessages(chatMessages);
306
+ ```
307
+
308
+ ## Subpath Exports
309
+
310
+ For tree-shaking or targeted imports, the package provides granular subpath exports:
311
+
312
+ ```typescript
313
+ import { callModel } from '@openrouter/agent/call-model';
314
+ import { tool } from '@openrouter/agent/tool';
315
+ import { ModelResult } from '@openrouter/agent/model-result';
316
+ import { stepCountIs, maxCost } from '@openrouter/agent/stop-conditions';
317
+ import { toClaudeMessage } from '@openrouter/agent/anthropic-compat';
318
+ import { toChatMessage } from '@openrouter/agent/chat-compat';
319
+ import { ToolContextStore } from '@openrouter/agent/tool-context';
320
+ import { ToolEventBroadcaster } from '@openrouter/agent/tool-event-broadcaster';
321
+ import { createInitialState } from '@openrouter/agent/conversation-state';
322
+ ```
323
+
324
+ ## Development
325
+
326
+ ```bash
327
+ # Install dependencies
328
+ pnpm install
329
+
330
+ # Build
331
+ pnpm build
332
+
333
+ # Run unit tests
334
+ pnpm test
335
+
336
+ # Run end-to-end tests (requires OPENROUTER_API_KEY in .env)
337
+ pnpm test:e2e
338
+
339
+ # Type check
340
+ pnpm typecheck
341
+
342
+ # Lint
343
+ pnpm lint
344
+ ```
345
+
346
+ ### Running Tests
347
+
348
+ Create a `.env` file with your OpenRouter API key:
349
+
350
+ ```env
351
+ OPENROUTER_API_KEY=sk-or-...
352
+ ```
353
+
354
+ Then run:
355
+
356
+ ```bash
357
+ pnpm test # Unit tests
358
+ pnpm test:e2e # Integration tests (requires API key)
359
+ ```
360
+
361
+ ## Documentation
362
+
363
+ Full `callModel` documentation is available at [openrouter.ai/docs/sdks/typescript/call-model](https://openrouter.ai/docs/sdks/typescript/call-model/overview).
364
+
365
+ ## License
366
+
367
+ Apache-2.0
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Reason why the model stopped generating.
3
+ */
4
+ export type ClaudeStopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | 'pause_turn' | 'refusal';
5
+ /**
6
+ * Character-level citation location within a document.
7
+ */
8
+ export type ClaudeCitationCharLocation = {
9
+ type: 'char_location';
10
+ cited_text: string;
11
+ document_index: number;
12
+ document_title: string;
13
+ file_id: string;
14
+ start_char_index: number;
15
+ end_char_index: number;
16
+ };
17
+ /**
18
+ * Page-level citation location within a document.
19
+ */
20
+ export type ClaudeCitationPageLocation = {
21
+ type: 'page_location';
22
+ cited_text: string;
23
+ document_index: number;
24
+ document_title: string;
25
+ file_id: string;
26
+ start_page_number: number;
27
+ end_page_number: number;
28
+ };
29
+ /**
30
+ * Content block citation location within a document.
31
+ */
32
+ export type ClaudeCitationContentBlockLocation = {
33
+ type: 'content_block_location';
34
+ cited_text: string;
35
+ document_index: number;
36
+ document_title: string;
37
+ file_id: string;
38
+ start_block_index: number;
39
+ end_block_index: number;
40
+ };
41
+ /**
42
+ * Web search result citation location.
43
+ */
44
+ export type ClaudeCitationWebSearchResultLocation = {
45
+ type: 'web_search_result_location';
46
+ cited_text: string;
47
+ title: string;
48
+ url: string;
49
+ encrypted_index: string;
50
+ };
51
+ /**
52
+ * Search result citation location.
53
+ */
54
+ export type ClaudeCitationSearchResultLocation = {
55
+ type: 'search_result_location';
56
+ cited_text: string;
57
+ title: string;
58
+ source: string;
59
+ start_block_index: number;
60
+ end_block_index: number;
61
+ search_result_index: number;
62
+ };
63
+ /**
64
+ * Union of all text citation types.
65
+ */
66
+ export type ClaudeTextCitation = ClaudeCitationCharLocation | ClaudeCitationPageLocation | ClaudeCitationContentBlockLocation | ClaudeCitationWebSearchResultLocation | ClaudeCitationSearchResultLocation;
67
+ /**
68
+ * Text content block.
69
+ */
70
+ export type ClaudeTextBlock = {
71
+ type: 'text';
72
+ text: string;
73
+ citations?: ClaudeTextCitation[];
74
+ };
75
+ /**
76
+ * Extended thinking content block.
77
+ */
78
+ export type ClaudeThinkingBlock = {
79
+ type: 'thinking';
80
+ thinking: string;
81
+ signature: string;
82
+ };
83
+ /**
84
+ * Redacted thinking content block.
85
+ */
86
+ export type ClaudeRedactedThinkingBlock = {
87
+ type: 'redacted_thinking';
88
+ data: string;
89
+ };
90
+ /**
91
+ * Tool use content block.
92
+ */
93
+ export type ClaudeToolUseBlock = {
94
+ type: 'tool_use';
95
+ id: string;
96
+ name: string;
97
+ input: Record<string, unknown>;
98
+ };
99
+ /**
100
+ * Server-side tool use content block (e.g., web_search).
101
+ */
102
+ export type ClaudeServerToolUseBlock = {
103
+ type: 'server_tool_use';
104
+ id: string;
105
+ name: 'web_search';
106
+ input: Record<string, unknown>;
107
+ };
108
+ /**
109
+ * Union of all content block types.
110
+ */
111
+ export type ClaudeContentBlock = ClaudeTextBlock | ClaudeThinkingBlock | ClaudeRedactedThinkingBlock | ClaudeToolUseBlock | ClaudeServerToolUseBlock;
112
+ /**
113
+ * Token usage information.
114
+ */
115
+ export type ClaudeUsage = {
116
+ input_tokens: number;
117
+ output_tokens: number;
118
+ cache_creation_input_tokens?: number;
119
+ cache_read_input_tokens?: number;
120
+ };
121
+ /**
122
+ * Claude Message response format compatible with the Anthropic SDK.
123
+ * This represents a complete assistant response from the Claude API.
124
+ */
125
+ export type ClaudeMessage = {
126
+ id: string;
127
+ type: 'message';
128
+ role: 'assistant';
129
+ model: string;
130
+ content: ClaudeContentBlock[];
131
+ stop_reason: ClaudeStopReason | null;
132
+ stop_sequence?: string | null;
133
+ usage: ClaudeUsage;
134
+ /** Unmappable content preserved for lossless round-trips */
135
+ unsupported_content?: UnsupportedContent[];
136
+ };
137
+ /**
138
+ * Cache control for prompt caching.
139
+ */
140
+ export type ClaudeCacheControl = {
141
+ type: 'ephemeral';
142
+ };
143
+ /**
144
+ * Text content block parameter for input.
145
+ */
146
+ export type ClaudeTextBlockParam = {
147
+ type: 'text';
148
+ text: string;
149
+ cache_control?: ClaudeCacheControl | null;
150
+ };
151
+ /**
152
+ * Base64-encoded image source.
153
+ */
154
+ export type ClaudeBase64ImageSource = {
155
+ type: 'base64';
156
+ media_type: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp';
157
+ data: string;
158
+ };
159
+ /**
160
+ * URL-based image source.
161
+ */
162
+ export type ClaudeURLImageSource = {
163
+ type: 'url';
164
+ url: string;
165
+ };
166
+ /**
167
+ * Image content block parameter for input.
168
+ */
169
+ export type ClaudeImageBlockParam = {
170
+ type: 'image';
171
+ source: ClaudeBase64ImageSource | ClaudeURLImageSource;
172
+ cache_control?: ClaudeCacheControl | null;
173
+ };
174
+ /**
175
+ * Tool use content block parameter for input (when passing assistant's tool use back).
176
+ */
177
+ export type ClaudeToolUseBlockParam = {
178
+ type: 'tool_use';
179
+ id: string;
180
+ name: string;
181
+ input: Record<string, unknown>;
182
+ cache_control?: ClaudeCacheControl | null;
183
+ };
184
+ /**
185
+ * Tool result content block parameter for input.
186
+ */
187
+ export type ClaudeToolResultBlockParam = {
188
+ type: 'tool_result';
189
+ tool_use_id: string;
190
+ content: string | Array<ClaudeTextBlockParam | ClaudeImageBlockParam>;
191
+ is_error?: boolean;
192
+ cache_control?: ClaudeCacheControl | null;
193
+ };
194
+ /**
195
+ * Union of all input content block types.
196
+ */
197
+ export type ClaudeContentBlockParam = ClaudeTextBlockParam | ClaudeImageBlockParam | ClaudeToolUseBlockParam | ClaudeToolResultBlockParam;
198
+ /**
199
+ * Claude MessageParam input format compatible with the Anthropic SDK.
200
+ * This represents a message in a conversation for the Claude API.
201
+ */
202
+ export type ClaudeMessageParam = {
203
+ role: 'user' | 'assistant';
204
+ content: string | Array<ClaudeContentBlockParam>;
205
+ };
206
+ /**
207
+ * Container for content that cannot be mapped to Claude's native format.
208
+ * Preserves information for round-trip conversions.
209
+ */
210
+ export type UnsupportedContent = {
211
+ /** Original type from source format (e.g., "image_generation_call", "refusal") */
212
+ original_type: string;
213
+ /** Complete original data structure */
214
+ data: Record<string, unknown>;
215
+ /** Optional explanation of why this couldn't be mapped */
216
+ reason?: string;
217
+ };
218
+ //# sourceMappingURL=claude-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-message.d.ts","sourceRoot":"","sources":["../../src/api-shape-helpers/claude-message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /*
2
+ * Types copied from @anthropic-ai/sdk for ClaudeMessage format.
3
+ * These types represent the Anthropic Claude API message response structure.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=claude-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-message.js","sourceRoot":"","sources":["../../src/api-shape-helpers/claude-message.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/esm/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ export type { CallModelInput, CallModelInputWithState, ResolvedCallModelInput, } from './lib/async-params.js';
2
+ export type { GetResponseOptions } from './lib/model-result.js';
3
+ export type { StreamableOutputItem } from './lib/stream-transformers.js';
4
+ export type { ContextInput } from './lib/tool-context.js';
5
+ export type { ChatStreamEvent, ConversationState, ConversationStatus, HasApprovalTools, InferToolEvent, InferToolEventsUnion, InferToolInput, InferToolOutput, InferToolOutputsUnion, ManualTool, NextTurnParamsContext, NextTurnParamsFunctions, ParsedToolCall, PartialResponse, ResponseStreamEvent, ResponseStreamEvent as EnhancedResponseStreamEvent, StateAccessor, StepResult, StopCondition, StopWhen, Tool, ToolApprovalCheck, ToolCallOutputEvent, ToolExecutionResult, ToolExecutionResultUnion, ToolHasApproval, ToolPreliminaryResultEvent, ToolResultEvent, ToolStreamEvent, ToolWithExecute, ToolWithGenerator, TurnContext, TurnEndEvent, TurnStartEvent, TypedToolCall, TypedToolCallUnion, UnsentToolResult, Warning, } from './lib/tool-types.js';
6
+ export { callModel } from './inner-loop/call-model.js';
7
+ export { fromClaudeMessages, toClaudeMessage } from './lib/anthropic-compat.js';
8
+ export { hasAsyncFunctions, resolveAsyncFunctions } from './lib/async-params.js';
9
+ export { fromChatMessages, toChatMessage } from './lib/chat-compat.js';
10
+ export { ClaudeContentBlockType, NonClaudeMessageRole } from './lib/claude-constants.js';
11
+ export { isClaudeStyleMessages } from './lib/claude-type-guards.js';
12
+ export { appendToMessages, createInitialState, createRejectedResult, createUnsentResult, generateConversationId, partitionToolCalls, toolRequiresApproval, updateState, } from './lib/conversation-state.js';
13
+ export { ModelResult } from './lib/model-result.js';
14
+ export { applyNextTurnParamsToRequest, buildNextTurnParamsContext, executeNextTurnParamsFunctions, } from './lib/next-turn-params.js';
15
+ export { finishReasonIs, hasToolCall, isStopConditionMet, maxCost, maxTokensUsed, stepCountIs, } from './lib/stop-conditions.js';
16
+ export { extractUnsupportedContent, getUnsupportedContentSummary, hasUnsupportedContent, } from './lib/stream-transformers.js';
17
+ export { tool } from './lib/tool.js';
18
+ export { buildToolExecuteContext, ToolContextStore } from './lib/tool-context.js';
19
+ export { ToolEventBroadcaster } from './lib/tool-event-broadcaster.js';
20
+ export { hasApprovalRequiredTools, hasExecuteFunction, isGeneratorTool, isRegularExecuteTool, isToolCallOutputEvent, isToolPreliminaryResultEvent, isToolResultEvent, isTurnEndEvent, isTurnStartEvent, ToolType, toolHasApprovalConfigured, } from './lib/tool-types.js';
21
+ export { buildTurnContext, normalizeInputToArray } from './lib/turn-context.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,cAAc,EACd,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,UAAU,EACV,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,mBAAmB,IAAI,2BAA2B,EAClD,aAAa,EACb,UAAU,EACV,aAAa,EACb,QAAQ,EACR,IAAI,EACJ,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,0BAA0B,EAC1B,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,OAAO,GACR,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,GACZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,4BAA4B,EAC5B,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC"}
package/esm/index.js ADDED
@@ -0,0 +1,27 @@
1
+ // Message format compatibility helpers
2
+ // High-level model calling
3
+ export { callModel } from './inner-loop/call-model.js';
4
+ export { fromClaudeMessages, toClaudeMessage } from './lib/anthropic-compat.js';
5
+ export { hasAsyncFunctions, resolveAsyncFunctions } from './lib/async-params.js';
6
+ export { fromChatMessages, toChatMessage } from './lib/chat-compat.js';
7
+ // Claude constants and type guards
8
+ export { ClaudeContentBlockType, NonClaudeMessageRole } from './lib/claude-constants.js';
9
+ export { isClaudeStyleMessages } from './lib/claude-type-guards.js';
10
+ // Conversation state helpers
11
+ export { appendToMessages, createInitialState, createRejectedResult, createUnsentResult, generateConversationId, partitionToolCalls, toolRequiresApproval, updateState, } from './lib/conversation-state.js';
12
+ export { ModelResult } from './lib/model-result.js';
13
+ // Next turn params helpers
14
+ export { applyNextTurnParamsToRequest, buildNextTurnParamsContext, executeNextTurnParamsFunctions, } from './lib/next-turn-params.js';
15
+ // Stop condition helpers
16
+ export { finishReasonIs, hasToolCall, isStopConditionMet, maxCost, maxTokensUsed, stepCountIs, } from './lib/stop-conditions.js';
17
+ export { extractUnsupportedContent, getUnsupportedContentSummary, hasUnsupportedContent, } from './lib/stream-transformers.js';
18
+ // Tool creation helpers
19
+ export { tool } from './lib/tool.js';
20
+ // Tool context helpers
21
+ export { buildToolExecuteContext, ToolContextStore } from './lib/tool-context.js';
22
+ // Real-time tool event broadcasting
23
+ export { ToolEventBroadcaster } from './lib/tool-event-broadcaster.js';
24
+ export { hasApprovalRequiredTools, hasExecuteFunction, isGeneratorTool, isRegularExecuteTool, isToolCallOutputEvent, isToolPreliminaryResultEvent, isToolResultEvent, isTurnEndEvent, isTurnStartEvent, ToolType, toolHasApprovalConfigured, } from './lib/tool-types.js';
25
+ // Turn context helpers
26
+ export { buildTurnContext, normalizeInputToArray } from './lib/turn-context.js';
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AAmDvC,2BAA2B;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvE,mCAAmC;AACnC,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,6BAA6B;AAC7B,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,GACZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,2BAA2B;AAC3B,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AACnC,yBAAyB;AACzB,OAAO,EACL,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,aAAa,EACb,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,wBAAwB;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,uBAAuB;AACvB,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAClF,oCAAoC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,4BAA4B,EAC5B,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,uBAAuB;AACvB,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC"}