@openrouter/sdk 0.3.7 → 0.3.11

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 (42) hide show
  1. package/.zed/settings.json +10 -0
  2. package/_speakeasy/.github/action-inputs-config.json +53 -0
  3. package/_speakeasy/.github/action-security-config.json +88 -0
  4. package/esm/funcs/call-model.d.ts +94 -9
  5. package/esm/funcs/call-model.js +102 -120
  6. package/esm/index.d.ts +20 -8
  7. package/esm/index.js +20 -7
  8. package/esm/lib/anthropic-compat.d.ts +6 -2
  9. package/esm/lib/anthropic-compat.js +117 -98
  10. package/esm/lib/async-params.d.ts +53 -0
  11. package/esm/lib/async-params.js +76 -0
  12. package/esm/lib/chat-compat.js +4 -0
  13. package/esm/lib/claude-constants.d.ts +22 -0
  14. package/esm/lib/claude-constants.js +20 -0
  15. package/esm/lib/claude-type-guards.d.ts +10 -0
  16. package/esm/lib/claude-type-guards.js +70 -0
  17. package/esm/lib/config.d.ts +4 -2
  18. package/esm/lib/config.js +2 -2
  19. package/esm/lib/model-result.d.ts +18 -25
  20. package/esm/lib/model-result.js +137 -176
  21. package/esm/lib/next-turn-params.d.ts +30 -0
  22. package/esm/lib/next-turn-params.js +129 -0
  23. package/esm/lib/reusable-stream.js +10 -10
  24. package/esm/lib/stop-conditions.d.ts +80 -0
  25. package/esm/lib/stop-conditions.js +104 -0
  26. package/esm/lib/stream-transformers.d.ts +3 -3
  27. package/esm/lib/stream-transformers.js +311 -260
  28. package/esm/lib/stream-type-guards.d.ts +29 -0
  29. package/esm/lib/stream-type-guards.js +109 -0
  30. package/esm/lib/tool-executor.d.ts +9 -7
  31. package/esm/lib/tool-executor.js +7 -1
  32. package/esm/lib/tool-orchestrator.d.ts +7 -7
  33. package/esm/lib/tool-orchestrator.js +38 -10
  34. package/esm/lib/tool-types.d.ts +163 -29
  35. package/esm/lib/tool-types.js +6 -0
  36. package/esm/lib/tool.d.ts +99 -0
  37. package/esm/lib/tool.js +71 -0
  38. package/esm/lib/turn-context.d.ts +50 -0
  39. package/esm/lib/turn-context.js +59 -0
  40. package/esm/sdk/sdk.d.ts +3 -9
  41. package/jsr.json +1 -1
  42. package/package.json +6 -3
@@ -0,0 +1,10 @@
1
+ {
2
+ "tab_size": 2,
3
+ "project_name": "@openrouter/sdk",
4
+ "formatter": {
5
+ "language_server": {
6
+ "name": "eslint"
7
+ }
8
+ },
9
+ "language_servers": ["!biome", "..."]
10
+ }
@@ -0,0 +1,53 @@
1
+ [
2
+ {
3
+ "name": "mode",
4
+ "validation_regex": "/^(direct|pr)$/.source",
5
+ "validation_message": "Must be `direct` or `pr`"
6
+ },
7
+ {
8
+ "name": "speakeasy_version",
9
+ "validation_regex": "/^[\\w.\\-]+$/.source",
10
+ "validation_message": "Letters, numbers, or .-_ only"
11
+ },
12
+ {
13
+ "name": "openapi_doc_location",
14
+ "validation_regex": "/^((https?):\\/\\/([\\w\\-]+\\.)+\\w+(\\/.*)?|[\\w.\\-\\/]+)$/i.source",
15
+ "validation_message": "Must be a valid server URL or file path containing letters, numbers, or .-_/ only"
16
+ },
17
+ {
18
+ "name": "openapi_doc_auth_header",
19
+ "validation_regex": "/^[A-Za-z\\-]+$/.source",
20
+ "validation_message": "Letters or - only"
21
+ },
22
+ {
23
+ "name": "create_release"
24
+ },
25
+ {
26
+ "name": "publish_python",
27
+ "language": "python"
28
+ },
29
+ {
30
+ "name": "publish_typescript",
31
+ "language": "typescript"
32
+ },
33
+ {
34
+ "name": "publish_java",
35
+ "language": "java"
36
+ },
37
+ {
38
+ "name": "publish_php",
39
+ "language": "php"
40
+ },
41
+ {
42
+ "name": "publish_ruby",
43
+ "language": "ruby"
44
+ },
45
+ {
46
+ "name": "publish_csharp",
47
+ "language": "csharp"
48
+ },
49
+ {
50
+ "name": "publish_terraform",
51
+ "language": "terraform"
52
+ }
53
+ ]
@@ -0,0 +1,88 @@
1
+ [
2
+ {
3
+ "name": "pypi_token",
4
+ "secret_name": "PYPI_TOKEN",
5
+ "validation_regex": "/^[\\w.\\-]+$/.source",
6
+ "validation_message": "Letters, numbers, or .-_ only",
7
+ "language": "python"
8
+ },
9
+ {
10
+ "name": "npm_token",
11
+ "secret_name": "NPM_TOKEN",
12
+ "validation_regex": "/^[\\w.\\-]+$/.source",
13
+ "validation_message": "Letters, numbers, or .-_ only",
14
+ "language": "typescript"
15
+ },
16
+ {
17
+ "name": "packagist_username",
18
+ "validation_regex": "/^[\\w.\\-]+$/.source",
19
+ "validation_message": "Letters, numbers, or .-_ only",
20
+ "language": "php"
21
+ },
22
+ {
23
+ "name": "packagist_token",
24
+ "validation_regex": "/^[\\w.\\-]+$/.source",
25
+ "validation_message": "Letters, numbers, or .-_ only",
26
+ "language": "php"
27
+ },
28
+ {
29
+ "name": "openapi_doc_auth_token",
30
+ "secret_name": "SPEC_TOKEN",
31
+ "validation_regex": "/^[\\w.\\-]+$/.source",
32
+ "validation_message": "Letters, numbers, or .-_ only"
33
+ },
34
+ {
35
+ "name": "speakeasy_api_key",
36
+ "secret_name": "SPEAKEASY_API_KEY",
37
+ "validation_regex": "/^[\\w.\\-]+$/.source",
38
+ "validation_message": "Letters, numbers, or .-_ only"
39
+ },
40
+ {
41
+ "name": "ossrh_username",
42
+ "secret_name": "MAVEN_USERNAME",
43
+ "validation_regex": "/^[\\w.\\-]+$/.source",
44
+ "validation_message": "Letters, numbers, or .-_ only",
45
+ "language": "java"
46
+ },
47
+ {
48
+ "name": "ossrh_password",
49
+ "secret_name": "MAVEN_PASSWORD",
50
+ "language": "java"
51
+ },
52
+ {
53
+ "name": "java_gpg_secret_key",
54
+ "validation_regex": "/^[\\w.\\-\\t \\r\\n]+$/.source",
55
+ "validation_message": "Letters, numbers, tabs, spaces, newlines, or .-_ only",
56
+ "language": "java"
57
+ },
58
+ {
59
+ "name": "java_gpg_passphrase",
60
+ "language": "java"
61
+ },
62
+ {
63
+ "name": "terraform_gpg_secret_key",
64
+ "secret_name": "TERRAFORM_GPG_SECRET_KEY",
65
+ "validation_regex": "/^[\\w.\\-\\t \\r\\n]+$/.source",
66
+ "validation_message": "Letters, numbers, tabs, spaces, newlines, or .-_ only",
67
+ "language": "terraform"
68
+ },
69
+ {
70
+ "name": "terraform_gpg_passphrase",
71
+ "secret_name": "TERRAFORM_GPG_PASSPHRASE",
72
+ "language": "terraform"
73
+ },
74
+ {
75
+ "name": "rubygems_auth_token",
76
+ "secret_name": "RUBYGEMS_AUTH_TOKEN",
77
+ "language": "ruby"
78
+ },
79
+ {
80
+ "name": "nuget_api_key",
81
+ "secret_name": "NUGET_API_KEY",
82
+ "language": "csharp"
83
+ },
84
+ {
85
+ "name": "slack_webhook_url",
86
+ "secret_name": "SLACK_WEBHOOK_URL"
87
+ }
88
+ ]
@@ -1,8 +1,9 @@
1
- import type { OpenRouterCore } from "../core.js";
2
- import type { RequestOptions } from "../lib/sdks.js";
3
- import type { Tool, MaxToolRounds } from "../lib/tool-types.js";
4
- import type * as models from "../models/index.js";
5
- import { ModelResult } from "../lib/model-result.js";
1
+ import type { OpenRouterCore } from '../core.js';
2
+ import type { CallModelInput } from '../lib/async-params.js';
3
+ import type { RequestOptions } from '../lib/sdks.js';
4
+ import type { Tool } from '../lib/tool-types.js';
5
+ import { ModelResult } from '../lib/model-result.js';
6
+ export type { CallModelInput } from '../lib/async-params.js';
6
7
  /**
7
8
  * Get a response with multiple consumption patterns
8
9
  *
@@ -25,9 +26,93 @@ import { ModelResult } from "../lib/model-result.js";
25
26
  * For message format conversion, use the helper functions:
26
27
  * - `fromChatMessages()` / `toChatMessage()` for OpenAI chat format
27
28
  * - `fromClaudeMessages()` / `toClaudeMessage()` for Anthropic Claude format
29
+ *
30
+ * **Async Function Support:**
31
+ *
32
+ * Any field in CallModelInput can be a function that computes the value dynamically
33
+ * based on the conversation context. You can mix static values and functions in the
34
+ * same request. Functions are resolved before EVERY turn, allowing parameters to
35
+ * adapt as the conversation progresses.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // Mix static and dynamic values
40
+ * const result = callModel(client, {
41
+ * model: 'gpt-4', // static
42
+ * temperature: (ctx) => Math.min(ctx.numberOfTurns * 0.2, 1.0), // dynamic
43
+ * input: [{ type: 'text', text: 'Hello' }], // static
44
+ * });
45
+ * ```
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Switch models based on conversation length
50
+ * const result = callModel(client, {
51
+ * model: (ctx) => ctx.numberOfTurns > 3 ? 'gpt-4' : 'gpt-3.5-turbo',
52
+ * input: [{ type: 'text', text: 'Complex question' }],
53
+ * });
54
+ * ```
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // Use async functions to fetch dynamic values
59
+ * const result = callModel(client, {
60
+ * model: 'gpt-4',
61
+ * instructions: async (ctx) => {
62
+ * const userPrefs = await fetchUserPreferences();
63
+ * return `You are a helpful assistant. User preferences: ${userPrefs}`;
64
+ * },
65
+ * input: [{ type: 'text', text: 'Help me' }],
66
+ * });
67
+ * ```
68
+ *
69
+ * Async functions receive `TurnContext` with:
70
+ * - `numberOfTurns`: Current turn number (0-indexed, 0 = initial request)
71
+ * - `messageHistory`: Current conversation messages
72
+ * - `model`: Current model selection (if set)
73
+ * - `models`: Current models array (if set)
74
+ *
75
+ * **Execution Order:**
76
+ * Functions are resolved at the START of each turn in this order:
77
+ * 1. Async functions (parallel resolution)
78
+ * 2. Tool execution (if tools called by model)
79
+ * 3. nextTurnParams functions (if defined on tools)
80
+ * 4. API request with resolved values
81
+ *
82
+ * **Stop Conditions:**
83
+ *
84
+ * Control when tool execution stops using the `stopWhen` parameter:
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * // Stop after 3 steps
89
+ * stopWhen: stepCountIs(3)
90
+ *
91
+ * // Stop when a specific tool is called
92
+ * stopWhen: hasToolCall('finalizeResults')
93
+ *
94
+ * // Multiple conditions (OR logic - stops if ANY is true)
95
+ * stopWhen: [
96
+ * stepCountIs(10), // Safety: max 10 steps
97
+ * maxCost(0.50), // Budget: max $0.50
98
+ * hasToolCall('finalize') // Logic: stop when finalize called
99
+ * ]
100
+ *
101
+ * // Custom condition with full step history
102
+ * stopWhen: ({ steps }) => {
103
+ * const totalCalls = steps.reduce((sum, s) => sum + s.toolCalls.length, 0);
104
+ * return totalCalls >= 20; // Stop after 20 total tool calls
105
+ * }
106
+ * ```
107
+ *
108
+ * Available helper functions:
109
+ * - `stepCountIs(n)` - Stop after n steps
110
+ * - `hasToolCall(name)` - Stop when tool is called
111
+ * - `maxTokensUsed(n)` - Stop when token usage exceeds n
112
+ * - `maxCost(n)` - Stop when cost exceeds n dollars
113
+ * - `finishReasonIs(reason)` - Stop on specific finish reason
114
+ *
115
+ * Default: `stepCountIs(5)` if not specified
28
116
  */
29
- export declare function callModel(client: OpenRouterCore, request: Omit<models.OpenResponsesRequest, "stream" | "tools"> & {
30
- tools?: Tool[];
31
- maxToolRounds?: MaxToolRounds;
32
- }, options?: RequestOptions): ModelResult;
117
+ export declare function callModel<TTools extends readonly Tool[]>(client: OpenRouterCore, request: CallModelInput<TTools>, options?: RequestOptions): ModelResult<TTools>;
33
118
  //# sourceMappingURL=call-model.d.ts.map
@@ -1,103 +1,5 @@
1
- import { ModelResult } from "../lib/model-result.js";
2
- import { convertToolsToAPIFormat } from "../lib/tool-executor.js";
3
- /**
4
- * Checks if a message looks like a Claude-style message
5
- */
6
- function isClaudeStyleMessage(msg) {
7
- if (!msg || typeof msg !== 'object')
8
- return false;
9
- // Check if it has a role field that's user or assistant
10
- const role = msg.role;
11
- if (role !== 'user' && role !== 'assistant')
12
- return false;
13
- // Check if content is an array with Claude-style content blocks
14
- if (Array.isArray(msg.content)) {
15
- return msg.content.some((block) => block &&
16
- typeof block === 'object' &&
17
- block.type &&
18
- // Claude content block types (not OpenRouter types)
19
- (block.type === 'text' || block.type === 'image' || block.type === 'tool_use' || block.type === 'tool_result'));
20
- }
21
- return false;
22
- }
23
- /**
24
- * Converts Claude-style content blocks to OpenRouter format
25
- */
26
- function convertClaudeContentBlock(block) {
27
- if (!block || typeof block !== 'object' || !('type' in block)) {
28
- return null;
29
- }
30
- switch (block.type) {
31
- case 'text': {
32
- const textBlock = block;
33
- return {
34
- type: 'input_text',
35
- text: textBlock.text,
36
- };
37
- }
38
- case 'image': {
39
- const imageBlock = block;
40
- if (imageBlock.source.type === 'url') {
41
- return {
42
- type: 'input_image',
43
- detail: 'auto',
44
- imageUrl: imageBlock.source.url,
45
- };
46
- }
47
- else if (imageBlock.source.type === 'base64') {
48
- const dataUri = `data:${imageBlock.source.media_type};base64,${imageBlock.source.data}`;
49
- return {
50
- type: 'input_image',
51
- detail: 'auto',
52
- imageUrl: dataUri,
53
- };
54
- }
55
- return null;
56
- }
57
- case 'tool_use':
58
- case 'tool_result':
59
- // tool_use and tool_result are not handled here as they map to different input types
60
- return null;
61
- default:
62
- return null;
63
- }
64
- }
65
- /**
66
- * Converts a Claude-style message to OpenRouter EasyInputMessage format
67
- */
68
- function convertClaudeMessage(msg) {
69
- const { role, content } = msg;
70
- if (typeof content === 'string') {
71
- return {
72
- role: role === 'user' ? 'user' : 'assistant',
73
- content,
74
- };
75
- }
76
- // Convert array of content blocks
77
- const convertedBlocks = [];
78
- for (const block of content) {
79
- const converted = convertClaudeContentBlock(block);
80
- if (converted) {
81
- convertedBlocks.push(converted);
82
- }
83
- }
84
- // If all blocks were text, concatenate them into a string
85
- const allText = convertedBlocks.every(b => b.type === 'input_text');
86
- if (allText) {
87
- const text = convertedBlocks
88
- .map(b => b.text)
89
- .join('');
90
- return {
91
- role: role === 'user' ? 'user' : 'assistant',
92
- content: text,
93
- };
94
- }
95
- // Otherwise, return as array
96
- return {
97
- role: role === 'user' ? 'user' : 'assistant',
98
- content: convertedBlocks,
99
- };
100
- }
1
+ import { ModelResult } from '../lib/model-result.js';
2
+ import { convertToolsToAPIFormat } from '../lib/tool-executor.js';
101
3
  /**
102
4
  * Get a response with multiple consumption patterns
103
5
  *
@@ -120,36 +22,116 @@ function convertClaudeMessage(msg) {
120
22
  * For message format conversion, use the helper functions:
121
23
  * - `fromChatMessages()` / `toChatMessage()` for OpenAI chat format
122
24
  * - `fromClaudeMessages()` / `toClaudeMessage()` for Anthropic Claude format
25
+ *
26
+ * **Async Function Support:**
27
+ *
28
+ * Any field in CallModelInput can be a function that computes the value dynamically
29
+ * based on the conversation context. You can mix static values and functions in the
30
+ * same request. Functions are resolved before EVERY turn, allowing parameters to
31
+ * adapt as the conversation progresses.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // Mix static and dynamic values
36
+ * const result = callModel(client, {
37
+ * model: 'gpt-4', // static
38
+ * temperature: (ctx) => Math.min(ctx.numberOfTurns * 0.2, 1.0), // dynamic
39
+ * input: [{ type: 'text', text: 'Hello' }], // static
40
+ * });
41
+ * ```
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * // Switch models based on conversation length
46
+ * const result = callModel(client, {
47
+ * model: (ctx) => ctx.numberOfTurns > 3 ? 'gpt-4' : 'gpt-3.5-turbo',
48
+ * input: [{ type: 'text', text: 'Complex question' }],
49
+ * });
50
+ * ```
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * // Use async functions to fetch dynamic values
55
+ * const result = callModel(client, {
56
+ * model: 'gpt-4',
57
+ * instructions: async (ctx) => {
58
+ * const userPrefs = await fetchUserPreferences();
59
+ * return `You are a helpful assistant. User preferences: ${userPrefs}`;
60
+ * },
61
+ * input: [{ type: 'text', text: 'Help me' }],
62
+ * });
63
+ * ```
64
+ *
65
+ * Async functions receive `TurnContext` with:
66
+ * - `numberOfTurns`: Current turn number (0-indexed, 0 = initial request)
67
+ * - `messageHistory`: Current conversation messages
68
+ * - `model`: Current model selection (if set)
69
+ * - `models`: Current models array (if set)
70
+ *
71
+ * **Execution Order:**
72
+ * Functions are resolved at the START of each turn in this order:
73
+ * 1. Async functions (parallel resolution)
74
+ * 2. Tool execution (if tools called by model)
75
+ * 3. nextTurnParams functions (if defined on tools)
76
+ * 4. API request with resolved values
77
+ *
78
+ * **Stop Conditions:**
79
+ *
80
+ * Control when tool execution stops using the `stopWhen` parameter:
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * // Stop after 3 steps
85
+ * stopWhen: stepCountIs(3)
86
+ *
87
+ * // Stop when a specific tool is called
88
+ * stopWhen: hasToolCall('finalizeResults')
89
+ *
90
+ * // Multiple conditions (OR logic - stops if ANY is true)
91
+ * stopWhen: [
92
+ * stepCountIs(10), // Safety: max 10 steps
93
+ * maxCost(0.50), // Budget: max $0.50
94
+ * hasToolCall('finalize') // Logic: stop when finalize called
95
+ * ]
96
+ *
97
+ * // Custom condition with full step history
98
+ * stopWhen: ({ steps }) => {
99
+ * const totalCalls = steps.reduce((sum, s) => sum + s.toolCalls.length, 0);
100
+ * return totalCalls >= 20; // Stop after 20 total tool calls
101
+ * }
102
+ * ```
103
+ *
104
+ * Available helper functions:
105
+ * - `stepCountIs(n)` - Stop after n steps
106
+ * - `hasToolCall(name)` - Stop when tool is called
107
+ * - `maxTokensUsed(n)` - Stop when token usage exceeds n
108
+ * - `maxCost(n)` - Stop when cost exceeds n dollars
109
+ * - `finishReasonIs(reason)` - Stop on specific finish reason
110
+ *
111
+ * Default: `stepCountIs(5)` if not specified
123
112
  */
124
113
  export function callModel(client, request, options) {
125
- const { tools, maxToolRounds, ...apiRequest } = request;
126
- // Auto-convert Claude-style messages if detected
127
- let processedInput = apiRequest.input;
128
- if (Array.isArray(apiRequest.input)) {
129
- const hasClaudeMessages = apiRequest.input.some(isClaudeStyleMessage);
130
- if (hasClaudeMessages) {
131
- processedInput = apiRequest.input.map((msg) => {
132
- if (isClaudeStyleMessage(msg)) {
133
- return convertClaudeMessage(msg);
134
- }
135
- return msg;
136
- });
137
- }
138
- }
139
- // Convert tools to API format and extract enhanced tools if present
114
+ const { tools, stopWhen, ...apiRequest } = request;
115
+ // Convert tools to API format - no cast needed now that convertToolsToAPIFormat accepts readonly
140
116
  const apiTools = tools ? convertToolsToAPIFormat(tools) : undefined;
141
- // Build the request with converted tools and input
117
+ // Build the request with converted tools
118
+ // Note: async functions are resolved later in ModelResult.executeToolsIfNeeded()
119
+ // The request can have async fields (functions) or sync fields, and the tools are converted to API format
142
120
  const finalRequest = {
143
121
  ...apiRequest,
144
- ...(processedInput !== undefined && { input: processedInput }),
145
- ...(apiTools !== undefined && { tools: apiTools }),
146
122
  };
123
+ if (apiTools !== undefined) {
124
+ finalRequest['tools'] = apiTools;
125
+ }
147
126
  return new ModelResult({
148
127
  client,
149
128
  request: finalRequest,
150
129
  options: options ?? {},
151
- tools: tools ?? [],
152
- ...(maxToolRounds !== undefined && { maxToolRounds }),
130
+ // Preserve the exact TTools type instead of widening to Tool[]
131
+ tools: tools,
132
+ ...(stopWhen !== undefined && {
133
+ stopWhen,
134
+ }),
153
135
  });
154
136
  }
155
137
  //# sourceMappingURL=call-model.js.map
package/esm/index.d.ts CHANGED
@@ -1,9 +1,21 @@
1
- export * from "./lib/config.js";
2
- export * as files from "./lib/files.js";
3
- export { HTTPClient } from "./lib/http.js";
4
- export type { Fetcher, HTTPClientOptions } from "./lib/http.js";
5
- export * from "./sdk/sdk.js";
6
- export { fromClaudeMessages, toClaudeMessage } from "./lib/anthropic-compat.js";
7
- export { fromChatMessages, toChatMessage } from "./lib/chat-compat.js";
8
- export { extractUnsupportedContent, hasUnsupportedContent, getUnsupportedContentSummary } from "./lib/stream-transformers.js";
1
+ export type { CallModelInput, FieldOrAsyncFunction, ResolvedCallModelInput, } from './lib/async-params.js';
2
+ export type { Fetcher, HTTPClientOptions } from './lib/http.js';
3
+ export type { ChatStreamEvent, ResponseStreamEvent as EnhancedResponseStreamEvent, InferToolEvent, InferToolEventsUnion, InferToolInput, InferToolOutput, ManualTool, NextTurnParamsContext, NextTurnParamsFunctions, ParsedToolCall, StepResult, StopCondition, StopWhen, Tool, ToolExecutionResult, ToolExecutionResultUnion, ToolPreliminaryResultEvent, ToolStreamEvent, ToolWithExecute, ToolWithGenerator, TurnContext, TypedToolCall, TypedToolCallUnion, Warning, } from './lib/tool-types.js';
4
+ export type { BuildTurnContextOptions } from './lib/turn-context.js';
5
+ export type { ClaudeBase64ImageSource, ClaudeCacheControl, ClaudeCitationCharLocation, ClaudeCitationContentBlockLocation, ClaudeCitationPageLocation, ClaudeCitationSearchResultLocation, ClaudeCitationWebSearchResultLocation, ClaudeContentBlock, ClaudeContentBlockParam, ClaudeImageBlockParam, ClaudeMessage, ClaudeMessageParam, ClaudeRedactedThinkingBlock, ClaudeServerToolUseBlock, ClaudeStopReason, ClaudeTextBlock, ClaudeTextBlockParam, ClaudeTextCitation, ClaudeThinkingBlock, ClaudeToolResultBlockParam, ClaudeToolUseBlock, ClaudeToolUseBlockParam, ClaudeURLImageSource, ClaudeUsage, } from './models/claude-message.js';
6
+ export { fromClaudeMessages, toClaudeMessage } from './lib/anthropic-compat.js';
7
+ export { hasAsyncFunctions, resolveAsyncFunctions, } from './lib/async-params.js';
8
+ export { fromChatMessages, toChatMessage } from './lib/chat-compat.js';
9
+ export { ClaudeContentBlockType, NonClaudeMessageRole } from './lib/claude-constants.js';
10
+ export { isClaudeStyleMessages } from './lib/claude-type-guards.js';
11
+ export * from './lib/config.js';
12
+ export * as files from './lib/files.js';
13
+ export { HTTPClient } from './lib/http.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 { hasExecuteFunction, isGeneratorTool, isRegularExecuteTool, isToolPreliminaryResultEvent, ToolType, } from './lib/tool-types.js';
19
+ export { buildTurnContext, normalizeInputToArray } from './lib/turn-context.js';
20
+ export * from './sdk/sdk.js';
9
21
  //# sourceMappingURL=index.d.ts.map
package/esm/index.js CHANGED
@@ -1,12 +1,25 @@
1
1
  /*
2
2
  * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
3
3
  */
4
- export * from "./lib/config.js";
5
- export * as files from "./lib/files.js";
6
- export { HTTPClient } from "./lib/http.js";
7
- export * from "./sdk/sdk.js";
8
4
  // Message format compatibility helpers
9
- export { fromClaudeMessages, toClaudeMessage } from "./lib/anthropic-compat.js";
10
- export { fromChatMessages, toChatMessage } from "./lib/chat-compat.js";
11
- export { extractUnsupportedContent, hasUnsupportedContent, getUnsupportedContentSummary } from "./lib/stream-transformers.js";
5
+ export { fromClaudeMessages, toClaudeMessage } from './lib/anthropic-compat.js';
6
+ export { hasAsyncFunctions, resolveAsyncFunctions, } from './lib/async-params.js';
7
+ export { fromChatMessages, toChatMessage } from './lib/chat-compat.js';
8
+ // Claude constants and type guards
9
+ export { ClaudeContentBlockType, NonClaudeMessageRole } from './lib/claude-constants.js';
10
+ export { isClaudeStyleMessages } from './lib/claude-type-guards.js';
11
+ export * from './lib/config.js';
12
+ export * as files from './lib/files.js';
13
+ export { HTTPClient } from './lib/http.js';
14
+ // Next turn params helpers
15
+ export { applyNextTurnParamsToRequest, buildNextTurnParamsContext, executeNextTurnParamsFunctions, } from './lib/next-turn-params.js';
16
+ // Stop condition helpers
17
+ export { finishReasonIs, hasToolCall, isStopConditionMet, maxCost, maxTokensUsed, stepCountIs, } from './lib/stop-conditions.js';
18
+ export { extractUnsupportedContent, getUnsupportedContentSummary, hasUnsupportedContent, } from './lib/stream-transformers.js';
19
+ // Tool creation helpers
20
+ export { tool } from './lib/tool.js';
21
+ export { hasExecuteFunction, isGeneratorTool, isRegularExecuteTool, isToolPreliminaryResultEvent, ToolType, } from './lib/tool-types.js';
22
+ // Turn context helpers
23
+ export { buildTurnContext, normalizeInputToArray } from './lib/turn-context.js';
24
+ export * from './sdk/sdk.js';
12
25
  //# sourceMappingURL=index.js.map
@@ -1,11 +1,15 @@
1
- import type * as models from "../models/index.js";
2
- import { convertToClaudeMessage } from "./stream-transformers.js";
1
+ import type * as models from '../models/index.js';
2
+ import { convertToClaudeMessage } from './stream-transformers.js';
3
3
  /**
4
4
  * Convert Anthropic Claude-style messages to OpenResponses input format.
5
5
  *
6
6
  * This function transforms ClaudeMessageParam[] (Anthropic SDK format) to
7
7
  * OpenResponsesInput format that can be passed directly to callModel().
8
8
  *
9
+ * Note: Some Claude features are lost in conversion as OpenRouter doesn't support them:
10
+ * - cache_control on content blocks
11
+ * - is_error flag on tool_result blocks
12
+ *
9
13
  * @example
10
14
  * ```typescript
11
15
  * import { fromClaudeMessages } from '@openrouter/sdk';