@apholdings/jensen-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 (168) hide show
  1. package/README.md +1201 -0
  2. package/bedrock-provider.d.ts +1 -0
  3. package/bedrock-provider.js +1 -0
  4. package/dist/api-registry.d.ts +20 -0
  5. package/dist/api-registry.d.ts.map +1 -0
  6. package/dist/api-registry.js +44 -0
  7. package/dist/api-registry.js.map +1 -0
  8. package/dist/bedrock-provider.d.ts +5 -0
  9. package/dist/bedrock-provider.d.ts.map +1 -0
  10. package/dist/bedrock-provider.js +6 -0
  11. package/dist/bedrock-provider.js.map +1 -0
  12. package/dist/cli.d.ts +3 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +116 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/env-api-keys.d.ts +9 -0
  17. package/dist/env-api-keys.d.ts.map +1 -0
  18. package/dist/env-api-keys.js +107 -0
  19. package/dist/env-api-keys.js.map +1 -0
  20. package/dist/index.d.ts +23 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +21 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/models.d.ts +24 -0
  25. package/dist/models.d.ts.map +1 -0
  26. package/dist/models.generated.d.ts +13793 -0
  27. package/dist/models.generated.d.ts.map +1 -0
  28. package/dist/models.generated.js +13589 -0
  29. package/dist/models.generated.js.map +1 -0
  30. package/dist/models.js +55 -0
  31. package/dist/models.js.map +1 -0
  32. package/dist/oauth.d.ts +2 -0
  33. package/dist/oauth.d.ts.map +1 -0
  34. package/dist/oauth.js +2 -0
  35. package/dist/oauth.js.map +1 -0
  36. package/dist/providers/amazon-bedrock.d.ts +15 -0
  37. package/dist/providers/amazon-bedrock.d.ts.map +1 -0
  38. package/dist/providers/amazon-bedrock.js +600 -0
  39. package/dist/providers/amazon-bedrock.js.map +1 -0
  40. package/dist/providers/anthropic.d.ts +33 -0
  41. package/dist/providers/anthropic.d.ts.map +1 -0
  42. package/dist/providers/anthropic.js +732 -0
  43. package/dist/providers/anthropic.js.map +1 -0
  44. package/dist/providers/azure-openai-responses.d.ts +15 -0
  45. package/dist/providers/azure-openai-responses.d.ts.map +1 -0
  46. package/dist/providers/azure-openai-responses.js +187 -0
  47. package/dist/providers/azure-openai-responses.js.map +1 -0
  48. package/dist/providers/github-copilot-headers.d.ts +8 -0
  49. package/dist/providers/github-copilot-headers.d.ts.map +1 -0
  50. package/dist/providers/github-copilot-headers.js +29 -0
  51. package/dist/providers/github-copilot-headers.js.map +1 -0
  52. package/dist/providers/google-gemini-cli.d.ts +74 -0
  53. package/dist/providers/google-gemini-cli.d.ts.map +1 -0
  54. package/dist/providers/google-gemini-cli.js +757 -0
  55. package/dist/providers/google-gemini-cli.js.map +1 -0
  56. package/dist/providers/google-shared.d.ts +65 -0
  57. package/dist/providers/google-shared.d.ts.map +1 -0
  58. package/dist/providers/google-shared.js +300 -0
  59. package/dist/providers/google-shared.js.map +1 -0
  60. package/dist/providers/google-vertex.d.ts +15 -0
  61. package/dist/providers/google-vertex.d.ts.map +1 -0
  62. package/dist/providers/google-vertex.js +392 -0
  63. package/dist/providers/google-vertex.js.map +1 -0
  64. package/dist/providers/google.d.ts +13 -0
  65. package/dist/providers/google.d.ts.map +1 -0
  66. package/dist/providers/google.js +355 -0
  67. package/dist/providers/google.js.map +1 -0
  68. package/dist/providers/mistral.d.ts +22 -0
  69. package/dist/providers/mistral.d.ts.map +1 -0
  70. package/dist/providers/mistral.js +498 -0
  71. package/dist/providers/mistral.js.map +1 -0
  72. package/dist/providers/openai-codex-responses.d.ts +9 -0
  73. package/dist/providers/openai-codex-responses.d.ts.map +1 -0
  74. package/dist/providers/openai-codex-responses.js +704 -0
  75. package/dist/providers/openai-codex-responses.js.map +1 -0
  76. package/dist/providers/openai-completions.d.ts +15 -0
  77. package/dist/providers/openai-completions.d.ts.map +1 -0
  78. package/dist/providers/openai-completions.js +704 -0
  79. package/dist/providers/openai-completions.js.map +1 -0
  80. package/dist/providers/openai-responses-shared.d.ts +17 -0
  81. package/dist/providers/openai-responses-shared.d.ts.map +1 -0
  82. package/dist/providers/openai-responses-shared.js +449 -0
  83. package/dist/providers/openai-responses-shared.js.map +1 -0
  84. package/dist/providers/openai-responses.d.ts +13 -0
  85. package/dist/providers/openai-responses.d.ts.map +1 -0
  86. package/dist/providers/openai-responses.js +201 -0
  87. package/dist/providers/openai-responses.js.map +1 -0
  88. package/dist/providers/register-builtins.d.ts +11 -0
  89. package/dist/providers/register-builtins.d.ts.map +1 -0
  90. package/dist/providers/register-builtins.js +138 -0
  91. package/dist/providers/register-builtins.js.map +1 -0
  92. package/dist/providers/simple-options.d.ts +8 -0
  93. package/dist/providers/simple-options.d.ts.map +1 -0
  94. package/dist/providers/simple-options.js +35 -0
  95. package/dist/providers/simple-options.js.map +1 -0
  96. package/dist/providers/transform-messages.d.ts +8 -0
  97. package/dist/providers/transform-messages.d.ts.map +1 -0
  98. package/dist/providers/transform-messages.js +155 -0
  99. package/dist/providers/transform-messages.js.map +1 -0
  100. package/dist/stream.d.ts +8 -0
  101. package/dist/stream.d.ts.map +1 -0
  102. package/dist/stream.js +27 -0
  103. package/dist/stream.js.map +1 -0
  104. package/dist/types.d.ts +285 -0
  105. package/dist/types.d.ts.map +1 -0
  106. package/dist/types.js +2 -0
  107. package/dist/types.js.map +1 -0
  108. package/dist/utils/event-stream.d.ts +21 -0
  109. package/dist/utils/event-stream.d.ts.map +1 -0
  110. package/dist/utils/event-stream.js +81 -0
  111. package/dist/utils/event-stream.js.map +1 -0
  112. package/dist/utils/hash.d.ts +3 -0
  113. package/dist/utils/hash.d.ts.map +1 -0
  114. package/dist/utils/hash.js +14 -0
  115. package/dist/utils/hash.js.map +1 -0
  116. package/dist/utils/json-parse.d.ts +9 -0
  117. package/dist/utils/json-parse.d.ts.map +1 -0
  118. package/dist/utils/json-parse.js +29 -0
  119. package/dist/utils/json-parse.js.map +1 -0
  120. package/dist/utils/oauth/anthropic.d.ts +17 -0
  121. package/dist/utils/oauth/anthropic.d.ts.map +1 -0
  122. package/dist/utils/oauth/anthropic.js +104 -0
  123. package/dist/utils/oauth/anthropic.js.map +1 -0
  124. package/dist/utils/oauth/github-copilot.d.ts +30 -0
  125. package/dist/utils/oauth/github-copilot.d.ts.map +1 -0
  126. package/dist/utils/oauth/github-copilot.js +292 -0
  127. package/dist/utils/oauth/github-copilot.js.map +1 -0
  128. package/dist/utils/oauth/google-antigravity.d.ts +26 -0
  129. package/dist/utils/oauth/google-antigravity.d.ts.map +1 -0
  130. package/dist/utils/oauth/google-antigravity.js +373 -0
  131. package/dist/utils/oauth/google-antigravity.js.map +1 -0
  132. package/dist/utils/oauth/google-gemini-cli.d.ts +26 -0
  133. package/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -0
  134. package/dist/utils/oauth/google-gemini-cli.js +478 -0
  135. package/dist/utils/oauth/google-gemini-cli.js.map +1 -0
  136. package/dist/utils/oauth/index.d.ts +61 -0
  137. package/dist/utils/oauth/index.d.ts.map +1 -0
  138. package/dist/utils/oauth/index.js +131 -0
  139. package/dist/utils/oauth/index.js.map +1 -0
  140. package/dist/utils/oauth/openai-codex.d.ts +34 -0
  141. package/dist/utils/oauth/openai-codex.d.ts.map +1 -0
  142. package/dist/utils/oauth/openai-codex.js +380 -0
  143. package/dist/utils/oauth/openai-codex.js.map +1 -0
  144. package/dist/utils/oauth/pkce.d.ts +13 -0
  145. package/dist/utils/oauth/pkce.d.ts.map +1 -0
  146. package/dist/utils/oauth/pkce.js +31 -0
  147. package/dist/utils/oauth/pkce.js.map +1 -0
  148. package/dist/utils/oauth/types.d.ts +47 -0
  149. package/dist/utils/oauth/types.d.ts.map +1 -0
  150. package/dist/utils/oauth/types.js +2 -0
  151. package/dist/utils/oauth/types.js.map +1 -0
  152. package/dist/utils/overflow.d.ts +52 -0
  153. package/dist/utils/overflow.d.ts.map +1 -0
  154. package/dist/utils/overflow.js +117 -0
  155. package/dist/utils/overflow.js.map +1 -0
  156. package/dist/utils/sanitize-unicode.d.ts +22 -0
  157. package/dist/utils/sanitize-unicode.d.ts.map +1 -0
  158. package/dist/utils/sanitize-unicode.js +26 -0
  159. package/dist/utils/sanitize-unicode.js.map +1 -0
  160. package/dist/utils/typebox-helpers.d.ts +17 -0
  161. package/dist/utils/typebox-helpers.d.ts.map +1 -0
  162. package/dist/utils/typebox-helpers.js +21 -0
  163. package/dist/utils/typebox-helpers.js.map +1 -0
  164. package/dist/utils/validation.d.ts +18 -0
  165. package/dist/utils/validation.d.ts.map +1 -0
  166. package/dist/utils/validation.js +72 -0
  167. package/dist/utils/validation.js.map +1 -0
  168. package/package.json +80 -0
@@ -0,0 +1,201 @@
1
+ import OpenAI from "openai";
2
+ import { getEnvApiKey } from "../env-api-keys.js";
3
+ import { supportsXhigh } from "../models.js";
4
+ import { AssistantMessageEventStream } from "../utils/event-stream.js";
5
+ import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
6
+ import { convertResponsesMessages, convertResponsesTools, processResponsesStream } from "./openai-responses-shared.js";
7
+ import { buildBaseOptions, clampReasoning } from "./simple-options.js";
8
+ const OPENAI_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode"]);
9
+ /**
10
+ * Resolve cache retention preference.
11
+ * Defaults to "short" and uses PI_CACHE_RETENTION for backward compatibility.
12
+ */
13
+ function resolveCacheRetention(cacheRetention) {
14
+ if (cacheRetention) {
15
+ return cacheRetention;
16
+ }
17
+ if (typeof process !== "undefined" && process.env.PI_CACHE_RETENTION === "long") {
18
+ return "long";
19
+ }
20
+ return "short";
21
+ }
22
+ /**
23
+ * Get prompt cache retention based on cacheRetention and base URL.
24
+ * Only applies to direct OpenAI API calls (api.openai.com).
25
+ */
26
+ function getPromptCacheRetention(baseUrl, cacheRetention) {
27
+ if (cacheRetention !== "long") {
28
+ return undefined;
29
+ }
30
+ if (baseUrl.includes("api.openai.com")) {
31
+ return "24h";
32
+ }
33
+ return undefined;
34
+ }
35
+ /**
36
+ * Generate function for OpenAI Responses API
37
+ */
38
+ export const streamOpenAIResponses = (model, context, options) => {
39
+ const stream = new AssistantMessageEventStream();
40
+ // Start async processing
41
+ (async () => {
42
+ const output = {
43
+ role: "assistant",
44
+ content: [],
45
+ api: model.api,
46
+ provider: model.provider,
47
+ model: model.id,
48
+ usage: {
49
+ input: 0,
50
+ output: 0,
51
+ cacheRead: 0,
52
+ cacheWrite: 0,
53
+ totalTokens: 0,
54
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
55
+ },
56
+ stopReason: "stop",
57
+ timestamp: Date.now(),
58
+ };
59
+ try {
60
+ // Create OpenAI client
61
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
62
+ const client = createClient(model, context, apiKey, options?.headers);
63
+ let params = buildParams(model, context, options);
64
+ const nextParams = await options?.onPayload?.(params, model);
65
+ if (nextParams !== undefined) {
66
+ params = nextParams;
67
+ }
68
+ const openaiStream = await client.responses.create(params, options?.signal ? { signal: options.signal } : undefined);
69
+ stream.push({ type: "start", partial: output });
70
+ await processResponsesStream(openaiStream, output, stream, model, {
71
+ serviceTier: options?.serviceTier,
72
+ applyServiceTierPricing,
73
+ });
74
+ if (options?.signal?.aborted) {
75
+ throw new Error("Request was aborted");
76
+ }
77
+ if (output.stopReason === "aborted" || output.stopReason === "error") {
78
+ throw new Error("An unknown error occurred");
79
+ }
80
+ stream.push({ type: "done", reason: output.stopReason, message: output });
81
+ stream.end();
82
+ }
83
+ catch (error) {
84
+ for (const block of output.content)
85
+ delete block.index;
86
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
87
+ output.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
88
+ stream.push({ type: "error", reason: output.stopReason, error: output });
89
+ stream.end();
90
+ }
91
+ })();
92
+ return stream;
93
+ };
94
+ export const streamSimpleOpenAIResponses = (model, context, options) => {
95
+ const apiKey = options?.apiKey || getEnvApiKey(model.provider);
96
+ if (!apiKey) {
97
+ throw new Error(`No API key for provider: ${model.provider}`);
98
+ }
99
+ const base = buildBaseOptions(model, options, apiKey);
100
+ const reasoningEffort = supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning);
101
+ return streamOpenAIResponses(model, context, {
102
+ ...base,
103
+ reasoningEffort,
104
+ });
105
+ };
106
+ function createClient(model, context, apiKey, optionsHeaders) {
107
+ if (!apiKey) {
108
+ if (!process.env.OPENAI_API_KEY) {
109
+ throw new Error("OpenAI API key is required. Set OPENAI_API_KEY environment variable or pass it as an argument.");
110
+ }
111
+ apiKey = process.env.OPENAI_API_KEY;
112
+ }
113
+ const headers = { ...model.headers };
114
+ if (model.provider === "github-copilot") {
115
+ const hasImages = hasCopilotVisionInput(context.messages);
116
+ const copilotHeaders = buildCopilotDynamicHeaders({
117
+ messages: context.messages,
118
+ hasImages,
119
+ });
120
+ Object.assign(headers, copilotHeaders);
121
+ }
122
+ // Merge options headers last so they can override defaults
123
+ if (optionsHeaders) {
124
+ Object.assign(headers, optionsHeaders);
125
+ }
126
+ return new OpenAI({
127
+ apiKey,
128
+ baseURL: model.baseUrl,
129
+ dangerouslyAllowBrowser: true,
130
+ defaultHeaders: headers,
131
+ });
132
+ }
133
+ function buildParams(model, context, options) {
134
+ const messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);
135
+ const cacheRetention = resolveCacheRetention(options?.cacheRetention);
136
+ const params = {
137
+ model: model.id,
138
+ input: messages,
139
+ stream: true,
140
+ prompt_cache_key: cacheRetention === "none" ? undefined : options?.sessionId,
141
+ prompt_cache_retention: getPromptCacheRetention(model.baseUrl, cacheRetention),
142
+ store: false,
143
+ };
144
+ if (options?.maxTokens) {
145
+ params.max_output_tokens = options?.maxTokens;
146
+ }
147
+ if (options?.temperature !== undefined) {
148
+ params.temperature = options?.temperature;
149
+ }
150
+ if (options?.serviceTier !== undefined) {
151
+ params.service_tier = options.serviceTier;
152
+ }
153
+ if (context.tools) {
154
+ params.tools = convertResponsesTools(context.tools);
155
+ }
156
+ if (model.reasoning) {
157
+ if (options?.reasoningEffort || options?.reasoningSummary) {
158
+ params.reasoning = {
159
+ effort: options?.reasoningEffort || "medium",
160
+ summary: options?.reasoningSummary || "auto",
161
+ };
162
+ params.include = ["reasoning.encrypted_content"];
163
+ }
164
+ else {
165
+ if (model.name.startsWith("gpt-5")) {
166
+ // Jesus Christ, see https://community.openai.com/t/need-reasoning-false-option-for-gpt-5/1351588/7
167
+ messages.push({
168
+ role: "developer",
169
+ content: [
170
+ {
171
+ type: "input_text",
172
+ text: "# Juice: 0 !important",
173
+ },
174
+ ],
175
+ });
176
+ }
177
+ }
178
+ }
179
+ return params;
180
+ }
181
+ function getServiceTierCostMultiplier(serviceTier) {
182
+ switch (serviceTier) {
183
+ case "flex":
184
+ return 0.5;
185
+ case "priority":
186
+ return 2;
187
+ default:
188
+ return 1;
189
+ }
190
+ }
191
+ function applyServiceTierPricing(usage, serviceTier) {
192
+ const multiplier = getServiceTierCostMultiplier(serviceTier);
193
+ if (multiplier === 1)
194
+ return;
195
+ usage.cost.input *= multiplier;
196
+ usage.cost.output *= multiplier;
197
+ usage.cost.cacheRead *= multiplier;
198
+ usage.cost.cacheWrite *= multiplier;
199
+ usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
200
+ }
201
+ //# sourceMappingURL=openai-responses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../../src/providers/openai-responses.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenAI from \"openai\";\nimport type { ResponseCreateParamsStreaming } from \"openai/resources/responses/responses.js\";\nimport { getEnvApiKey } from \"../env-api-keys.js\";\nimport { supportsXhigh } from \"../models.js\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tCacheRetention,\n\tContext,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tUsage,\n} from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.js\";\nimport { convertResponsesMessages, convertResponsesTools, processResponsesStream } from \"./openai-responses-shared.js\";\nimport { buildBaseOptions, clampReasoning } from \"./simple-options.js\";\n\nconst OPENAI_TOOL_CALL_PROVIDERS = new Set([\"openai\", \"openai-codex\", \"opencode\"]);\n\n/**\n * Resolve cache retention preference.\n * Defaults to \"short\" and uses PI_CACHE_RETENTION for backward compatibility.\n */\nfunction resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\tif (typeof process !== \"undefined\" && process.env.PI_CACHE_RETENTION === \"long\") {\n\t\treturn \"long\";\n\t}\n\treturn \"short\";\n}\n\n/**\n * Get prompt cache retention based on cacheRetention and base URL.\n * Only applies to direct OpenAI API calls (api.openai.com).\n */\nfunction getPromptCacheRetention(baseUrl: string, cacheRetention: CacheRetention): \"24h\" | undefined {\n\tif (cacheRetention !== \"long\") {\n\t\treturn undefined;\n\t}\n\tif (baseUrl.includes(\"api.openai.com\")) {\n\t\treturn \"24h\";\n\t}\n\treturn undefined;\n}\n\n// OpenAI Responses-specific options\nexport interface OpenAIResponsesOptions extends StreamOptions {\n\treasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\treasoningSummary?: \"auto\" | \"detailed\" | \"concise\" | null;\n\tserviceTier?: ResponseCreateParamsStreaming[\"service_tier\"];\n}\n\n/**\n * Generate function for OpenAI Responses API\n */\nexport const streamOpenAIResponses: StreamFunction<\"openai-responses\", OpenAIResponsesOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: OpenAIResponsesOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t// Start async processing\n\t(async () => {\n\t\tconst output: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [],\n\t\t\tapi: model.api as Api,\n\t\t\tprovider: model.provider,\n\t\t\tmodel: model.id,\n\t\t\tusage: {\n\t\t\t\tinput: 0,\n\t\t\t\toutput: 0,\n\t\t\t\tcacheRead: 0,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 0,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t\tstopReason: \"stop\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\ttry {\n\t\t\t// Create OpenAI client\n\t\t\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider) || \"\";\n\t\t\tconst client = createClient(model, context, apiKey, options?.headers);\n\t\t\tlet params = buildParams(model, context, options);\n\t\t\tconst nextParams = await options?.onPayload?.(params, model);\n\t\t\tif (nextParams !== undefined) {\n\t\t\t\tparams = nextParams as ResponseCreateParamsStreaming;\n\t\t\t}\n\t\t\tconst openaiStream = await client.responses.create(\n\t\t\t\tparams,\n\t\t\t\toptions?.signal ? { signal: options.signal } : undefined,\n\t\t\t);\n\t\t\tstream.push({ type: \"start\", partial: output });\n\n\t\t\tawait processResponsesStream(openaiStream, output, stream, model, {\n\t\t\t\tserviceTier: options?.serviceTier,\n\t\t\t\tapplyServiceTierPricing,\n\t\t\t});\n\n\t\t\tif (options?.signal?.aborted) {\n\t\t\t\tthrow new Error(\"Request was aborted\");\n\t\t\t}\n\n\t\t\tif (output.stopReason === \"aborted\" || output.stopReason === \"error\") {\n\t\t\t\tthrow new Error(\"An unknown error occurred\");\n\t\t\t}\n\n\t\t\tstream.push({ type: \"done\", reason: output.stopReason, message: output });\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\tfor (const block of output.content) delete (block as { index?: number }).index;\n\t\t\toutput.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimpleOpenAIResponses: StreamFunction<\"openai-responses\", SimpleStreamOptions> = (\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = buildBaseOptions(model, options, apiKey);\n\tconst reasoningEffort = supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning);\n\n\treturn streamOpenAIResponses(model, context, {\n\t\t...base,\n\t\treasoningEffort,\n\t} satisfies OpenAIResponsesOptions);\n};\n\nfunction createClient(\n\tmodel: Model<\"openai-responses\">,\n\tcontext: Context,\n\tapiKey?: string,\n\toptionsHeaders?: Record<string, string>,\n) {\n\tif (!apiKey) {\n\t\tif (!process.env.OPENAI_API_KEY) {\n\t\t\tthrow new Error(\n\t\t\t\t\"OpenAI API key is required. Set OPENAI_API_KEY environment variable or pass it as an argument.\",\n\t\t\t);\n\t\t}\n\t\tapiKey = process.env.OPENAI_API_KEY;\n\t}\n\n\tconst headers = { ...model.headers };\n\tif (model.provider === \"github-copilot\") {\n\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\tconst copilotHeaders = buildCopilotDynamicHeaders({\n\t\t\tmessages: context.messages,\n\t\t\thasImages,\n\t\t});\n\t\tObject.assign(headers, copilotHeaders);\n\t}\n\n\t// Merge options headers last so they can override defaults\n\tif (optionsHeaders) {\n\t\tObject.assign(headers, optionsHeaders);\n\t}\n\n\treturn new OpenAI({\n\t\tapiKey,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: headers,\n\t});\n}\n\nfunction buildParams(model: Model<\"openai-responses\">, context: Context, options?: OpenAIResponsesOptions) {\n\tconst messages = convertResponsesMessages(model, context, OPENAI_TOOL_CALL_PROVIDERS);\n\n\tconst cacheRetention = resolveCacheRetention(options?.cacheRetention);\n\tconst params: ResponseCreateParamsStreaming = {\n\t\tmodel: model.id,\n\t\tinput: messages,\n\t\tstream: true,\n\t\tprompt_cache_key: cacheRetention === \"none\" ? undefined : options?.sessionId,\n\t\tprompt_cache_retention: getPromptCacheRetention(model.baseUrl, cacheRetention),\n\t\tstore: false,\n\t};\n\n\tif (options?.maxTokens) {\n\t\tparams.max_output_tokens = options?.maxTokens;\n\t}\n\n\tif (options?.temperature !== undefined) {\n\t\tparams.temperature = options?.temperature;\n\t}\n\n\tif (options?.serviceTier !== undefined) {\n\t\tparams.service_tier = options.serviceTier;\n\t}\n\n\tif (context.tools) {\n\t\tparams.tools = convertResponsesTools(context.tools);\n\t}\n\n\tif (model.reasoning) {\n\t\tif (options?.reasoningEffort || options?.reasoningSummary) {\n\t\t\tparams.reasoning = {\n\t\t\t\teffort: options?.reasoningEffort || \"medium\",\n\t\t\t\tsummary: options?.reasoningSummary || \"auto\",\n\t\t\t};\n\t\t\tparams.include = [\"reasoning.encrypted_content\"];\n\t\t} else {\n\t\t\tif (model.name.startsWith(\"gpt-5\")) {\n\t\t\t\t// Jesus Christ, see https://community.openai.com/t/need-reasoning-false-option-for-gpt-5/1351588/7\n\t\t\t\tmessages.push({\n\t\t\t\t\trole: \"developer\",\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"input_text\",\n\t\t\t\t\t\t\ttext: \"# Juice: 0 !important\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn params;\n}\n\nfunction getServiceTierCostMultiplier(serviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined): number {\n\tswitch (serviceTier) {\n\t\tcase \"flex\":\n\t\t\treturn 0.5;\n\t\tcase \"priority\":\n\t\t\treturn 2;\n\t\tdefault:\n\t\t\treturn 1;\n\t}\n}\n\nfunction applyServiceTierPricing(usage: Usage, serviceTier: ResponseCreateParamsStreaming[\"service_tier\"] | undefined) {\n\tconst multiplier = getServiceTierCostMultiplier(serviceTier);\n\tif (multiplier === 1) return;\n\n\tusage.cost.input *= multiplier;\n\tusage.cost.output *= multiplier;\n\tusage.cost.cacheRead *= multiplier;\n\tusage.cost.cacheWrite *= multiplier;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { AssistantMessageEvent, Context, Model, SimpleStreamOptions } from "../types.js";
2
+ import type { BedrockOptions } from "./amazon-bedrock.js";
3
+ interface BedrockProviderModule {
4
+ streamBedrock: (model: Model<"bedrock-converse-stream">, context: Context, options?: BedrockOptions) => AsyncIterable<AssistantMessageEvent>;
5
+ streamSimpleBedrock: (model: Model<"bedrock-converse-stream">, context: Context, options?: SimpleStreamOptions) => AsyncIterable<AssistantMessageEvent>;
6
+ }
7
+ export declare function setBedrockProviderModule(module: BedrockProviderModule): void;
8
+ export declare function registerBuiltInApiProviders(): void;
9
+ export declare function resetApiProviders(): void;
10
+ export {};
11
+ //# sourceMappingURL=register-builtins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-builtins.d.ts","sourceRoot":"","sources":["../../src/providers/register-builtins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,qBAAqB,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEhH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAW1D,UAAU,qBAAqB;IAC9B,aAAa,EAAE,CACd,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,EACvC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,cAAc,KACpB,aAAa,CAAC,qBAAqB,CAAC,CAAC;IAC1C,mBAAmB,EAAE,CACpB,KAAK,EAAE,KAAK,CAAC,yBAAyB,CAAC,EACvC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,KACzB,aAAa,CAAC,qBAAqB,CAAC,CAAC;CAC1C;AASD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAE5E;AAkFD,wBAAgB,2BAA2B,IAAI,IAAI,CA4DlD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC","sourcesContent":["import { clearApiProviders, registerApiProvider } from \"../api-registry.js\";\nimport type { AssistantMessage, AssistantMessageEvent, Context, Model, SimpleStreamOptions } from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport type { BedrockOptions } from \"./amazon-bedrock.js\";\nimport { streamAnthropic, streamSimpleAnthropic } from \"./anthropic.js\";\nimport { streamAzureOpenAIResponses, streamSimpleAzureOpenAIResponses } from \"./azure-openai-responses.js\";\nimport { streamGoogle, streamSimpleGoogle } from \"./google.js\";\nimport { streamGoogleGeminiCli, streamSimpleGoogleGeminiCli } from \"./google-gemini-cli.js\";\nimport { streamGoogleVertex, streamSimpleGoogleVertex } from \"./google-vertex.js\";\nimport { streamMistral, streamSimpleMistral } from \"./mistral.js\";\nimport { streamOpenAICodexResponses, streamSimpleOpenAICodexResponses } from \"./openai-codex-responses.js\";\nimport { streamOpenAICompletions, streamSimpleOpenAICompletions } from \"./openai-completions.js\";\nimport { streamOpenAIResponses, streamSimpleOpenAIResponses } from \"./openai-responses.js\";\n\ninterface BedrockProviderModule {\n\tstreamBedrock: (\n\t\tmodel: Model<\"bedrock-converse-stream\">,\n\t\tcontext: Context,\n\t\toptions?: BedrockOptions,\n\t) => AsyncIterable<AssistantMessageEvent>;\n\tstreamSimpleBedrock: (\n\t\tmodel: Model<\"bedrock-converse-stream\">,\n\t\tcontext: Context,\n\t\toptions?: SimpleStreamOptions,\n\t) => AsyncIterable<AssistantMessageEvent>;\n}\n\ntype DynamicImport = (specifier: string) => Promise<unknown>;\n\nconst dynamicImport: DynamicImport = (specifier) => import(specifier);\nconst BEDROCK_PROVIDER_SPECIFIER = \"./amazon-\" + \"bedrock.js\";\n\nlet bedrockProviderModuleOverride: BedrockProviderModule | undefined;\n\nexport function setBedrockProviderModule(module: BedrockProviderModule): void {\n\tbedrockProviderModuleOverride = module;\n}\n\nasync function loadBedrockProviderModule(): Promise<BedrockProviderModule> {\n\tif (bedrockProviderModuleOverride) {\n\t\treturn bedrockProviderModuleOverride;\n\t}\n\tconst module = await dynamicImport(BEDROCK_PROVIDER_SPECIFIER);\n\treturn module as BedrockProviderModule;\n}\n\nfunction forwardStream(target: AssistantMessageEventStream, source: AsyncIterable<AssistantMessageEvent>): void {\n\t(async () => {\n\t\tfor await (const event of source) {\n\t\t\ttarget.push(event);\n\t\t}\n\t\ttarget.end();\n\t})();\n}\n\nfunction createLazyLoadErrorMessage(model: Model<\"bedrock-converse-stream\">, error: unknown): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: \"bedrock-converse-stream\",\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"error\",\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction streamBedrockLazy(\n\tmodel: Model<\"bedrock-converse-stream\">,\n\tcontext: Context,\n\toptions?: BedrockOptions,\n): AssistantMessageEventStream {\n\tconst outer = new AssistantMessageEventStream();\n\n\tloadBedrockProviderModule()\n\t\t.then((module) => {\n\t\t\tconst inner = module.streamBedrock(model, context, options);\n\t\t\tforwardStream(outer, inner);\n\t\t})\n\t\t.catch((error) => {\n\t\t\tconst message = createLazyLoadErrorMessage(model, error);\n\t\t\touter.push({ type: \"error\", reason: \"error\", error: message });\n\t\t\touter.end(message);\n\t\t});\n\n\treturn outer;\n}\n\nfunction streamSimpleBedrockLazy(\n\tmodel: Model<\"bedrock-converse-stream\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream {\n\tconst outer = new AssistantMessageEventStream();\n\n\tloadBedrockProviderModule()\n\t\t.then((module) => {\n\t\t\tconst inner = module.streamSimpleBedrock(model, context, options);\n\t\t\tforwardStream(outer, inner);\n\t\t})\n\t\t.catch((error) => {\n\t\t\tconst message = createLazyLoadErrorMessage(model, error);\n\t\t\touter.push({ type: \"error\", reason: \"error\", error: message });\n\t\t\touter.end(message);\n\t\t});\n\n\treturn outer;\n}\n\nexport function registerBuiltInApiProviders(): void {\n\tregisterApiProvider({\n\t\tapi: \"anthropic-messages\",\n\t\tstream: streamAnthropic,\n\t\tstreamSimple: streamSimpleAnthropic,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"openai-completions\",\n\t\tstream: streamOpenAICompletions,\n\t\tstreamSimple: streamSimpleOpenAICompletions,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"mistral-conversations\",\n\t\tstream: streamMistral,\n\t\tstreamSimple: streamSimpleMistral,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"openai-responses\",\n\t\tstream: streamOpenAIResponses,\n\t\tstreamSimple: streamSimpleOpenAIResponses,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"azure-openai-responses\",\n\t\tstream: streamAzureOpenAIResponses,\n\t\tstreamSimple: streamSimpleAzureOpenAIResponses,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"openai-codex-responses\",\n\t\tstream: streamOpenAICodexResponses,\n\t\tstreamSimple: streamSimpleOpenAICodexResponses,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"google-generative-ai\",\n\t\tstream: streamGoogle,\n\t\tstreamSimple: streamSimpleGoogle,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"google-gemini-cli\",\n\t\tstream: streamGoogleGeminiCli,\n\t\tstreamSimple: streamSimpleGoogleGeminiCli,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"google-vertex\",\n\t\tstream: streamGoogleVertex,\n\t\tstreamSimple: streamSimpleGoogleVertex,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"bedrock-converse-stream\",\n\t\tstream: streamBedrockLazy,\n\t\tstreamSimple: streamSimpleBedrockLazy,\n\t});\n}\n\nexport function resetApiProviders(): void {\n\tclearApiProviders();\n\tregisterBuiltInApiProviders();\n}\n\nregisterBuiltInApiProviders();\n"]}
@@ -0,0 +1,138 @@
1
+ import { clearApiProviders, registerApiProvider } from "../api-registry.js";
2
+ import { AssistantMessageEventStream } from "../utils/event-stream.js";
3
+ import { streamAnthropic, streamSimpleAnthropic } from "./anthropic.js";
4
+ import { streamAzureOpenAIResponses, streamSimpleAzureOpenAIResponses } from "./azure-openai-responses.js";
5
+ import { streamGoogle, streamSimpleGoogle } from "./google.js";
6
+ import { streamGoogleGeminiCli, streamSimpleGoogleGeminiCli } from "./google-gemini-cli.js";
7
+ import { streamGoogleVertex, streamSimpleGoogleVertex } from "./google-vertex.js";
8
+ import { streamMistral, streamSimpleMistral } from "./mistral.js";
9
+ import { streamOpenAICodexResponses, streamSimpleOpenAICodexResponses } from "./openai-codex-responses.js";
10
+ import { streamOpenAICompletions, streamSimpleOpenAICompletions } from "./openai-completions.js";
11
+ import { streamOpenAIResponses, streamSimpleOpenAIResponses } from "./openai-responses.js";
12
+ const dynamicImport = (specifier) => import(specifier);
13
+ const BEDROCK_PROVIDER_SPECIFIER = "./amazon-" + "bedrock.js";
14
+ let bedrockProviderModuleOverride;
15
+ export function setBedrockProviderModule(module) {
16
+ bedrockProviderModuleOverride = module;
17
+ }
18
+ async function loadBedrockProviderModule() {
19
+ if (bedrockProviderModuleOverride) {
20
+ return bedrockProviderModuleOverride;
21
+ }
22
+ const module = await dynamicImport(BEDROCK_PROVIDER_SPECIFIER);
23
+ return module;
24
+ }
25
+ function forwardStream(target, source) {
26
+ (async () => {
27
+ for await (const event of source) {
28
+ target.push(event);
29
+ }
30
+ target.end();
31
+ })();
32
+ }
33
+ function createLazyLoadErrorMessage(model, error) {
34
+ return {
35
+ role: "assistant",
36
+ content: [],
37
+ api: "bedrock-converse-stream",
38
+ provider: model.provider,
39
+ model: model.id,
40
+ usage: {
41
+ input: 0,
42
+ output: 0,
43
+ cacheRead: 0,
44
+ cacheWrite: 0,
45
+ totalTokens: 0,
46
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
47
+ },
48
+ stopReason: "error",
49
+ errorMessage: error instanceof Error ? error.message : String(error),
50
+ timestamp: Date.now(),
51
+ };
52
+ }
53
+ function streamBedrockLazy(model, context, options) {
54
+ const outer = new AssistantMessageEventStream();
55
+ loadBedrockProviderModule()
56
+ .then((module) => {
57
+ const inner = module.streamBedrock(model, context, options);
58
+ forwardStream(outer, inner);
59
+ })
60
+ .catch((error) => {
61
+ const message = createLazyLoadErrorMessage(model, error);
62
+ outer.push({ type: "error", reason: "error", error: message });
63
+ outer.end(message);
64
+ });
65
+ return outer;
66
+ }
67
+ function streamSimpleBedrockLazy(model, context, options) {
68
+ const outer = new AssistantMessageEventStream();
69
+ loadBedrockProviderModule()
70
+ .then((module) => {
71
+ const inner = module.streamSimpleBedrock(model, context, options);
72
+ forwardStream(outer, inner);
73
+ })
74
+ .catch((error) => {
75
+ const message = createLazyLoadErrorMessage(model, error);
76
+ outer.push({ type: "error", reason: "error", error: message });
77
+ outer.end(message);
78
+ });
79
+ return outer;
80
+ }
81
+ export function registerBuiltInApiProviders() {
82
+ registerApiProvider({
83
+ api: "anthropic-messages",
84
+ stream: streamAnthropic,
85
+ streamSimple: streamSimpleAnthropic,
86
+ });
87
+ registerApiProvider({
88
+ api: "openai-completions",
89
+ stream: streamOpenAICompletions,
90
+ streamSimple: streamSimpleOpenAICompletions,
91
+ });
92
+ registerApiProvider({
93
+ api: "mistral-conversations",
94
+ stream: streamMistral,
95
+ streamSimple: streamSimpleMistral,
96
+ });
97
+ registerApiProvider({
98
+ api: "openai-responses",
99
+ stream: streamOpenAIResponses,
100
+ streamSimple: streamSimpleOpenAIResponses,
101
+ });
102
+ registerApiProvider({
103
+ api: "azure-openai-responses",
104
+ stream: streamAzureOpenAIResponses,
105
+ streamSimple: streamSimpleAzureOpenAIResponses,
106
+ });
107
+ registerApiProvider({
108
+ api: "openai-codex-responses",
109
+ stream: streamOpenAICodexResponses,
110
+ streamSimple: streamSimpleOpenAICodexResponses,
111
+ });
112
+ registerApiProvider({
113
+ api: "google-generative-ai",
114
+ stream: streamGoogle,
115
+ streamSimple: streamSimpleGoogle,
116
+ });
117
+ registerApiProvider({
118
+ api: "google-gemini-cli",
119
+ stream: streamGoogleGeminiCli,
120
+ streamSimple: streamSimpleGoogleGeminiCli,
121
+ });
122
+ registerApiProvider({
123
+ api: "google-vertex",
124
+ stream: streamGoogleVertex,
125
+ streamSimple: streamSimpleGoogleVertex,
126
+ });
127
+ registerApiProvider({
128
+ api: "bedrock-converse-stream",
129
+ stream: streamBedrockLazy,
130
+ streamSimple: streamSimpleBedrockLazy,
131
+ });
132
+ }
133
+ export function resetApiProviders() {
134
+ clearApiProviders();
135
+ registerBuiltInApiProviders();
136
+ }
137
+ registerBuiltInApiProviders();
138
+ //# sourceMappingURL=register-builtins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-builtins.js","sourceRoot":"","sources":["../../src/providers/register-builtins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAC3G,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAC3G,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACjG,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAiB3F,MAAM,aAAa,GAAkB,CAAC,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACtE,MAAM,0BAA0B,GAAG,WAAW,GAAG,YAAY,CAAC;AAE9D,IAAI,6BAAgE,CAAC;AAErE,MAAM,UAAU,wBAAwB,CAAC,MAA6B,EAAQ;IAC7E,6BAA6B,GAAG,MAAM,CAAC;AAAA,CACvC;AAED,KAAK,UAAU,yBAAyB,GAAmC;IAC1E,IAAI,6BAA6B,EAAE,CAAC;QACnC,OAAO,6BAA6B,CAAC;IACtC,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,0BAA0B,CAAC,CAAC;IAC/D,OAAO,MAA+B,CAAC;AAAA,CACvC;AAED,SAAS,aAAa,CAAC,MAAmC,EAAE,MAA4C,EAAQ;IAC/G,CAAC,KAAK,IAAI,EAAE,CAAC;QACZ,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,CAAC;IAAA,CACb,CAAC,EAAE,CAAC;AAAA,CACL;AAED,SAAS,0BAA0B,CAAC,KAAuC,EAAE,KAAc,EAAoB;IAC9G,OAAO;QACN,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,EAAE;QACX,GAAG,EAAE,yBAAyB;QAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,EAAE;QACf,KAAK,EAAE;YACN,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,CAAC;YACd,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;SACpE;QACD,UAAU,EAAE,OAAO;QACnB,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QACpE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACrB,CAAC;AAAA,CACF;AAED,SAAS,iBAAiB,CACzB,KAAuC,EACvC,OAAgB,EAChB,OAAwB,EACM;IAC9B,MAAM,KAAK,GAAG,IAAI,2BAA2B,EAAE,CAAC;IAEhD,yBAAyB,EAAE;SACzB,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5D,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAAA,CAC5B,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/D,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAAA,CACnB,CAAC,CAAC;IAEJ,OAAO,KAAK,CAAC;AAAA,CACb;AAED,SAAS,uBAAuB,CAC/B,KAAuC,EACvC,OAAgB,EAChB,OAA6B,EACC;IAC9B,MAAM,KAAK,GAAG,IAAI,2BAA2B,EAAE,CAAC;IAEhD,yBAAyB,EAAE;SACzB,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAClE,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAAA,CAC5B,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/D,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAAA,CACnB,CAAC,CAAC;IAEJ,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,UAAU,2BAA2B,GAAS;IACnD,mBAAmB,CAAC;QACnB,GAAG,EAAE,oBAAoB;QACzB,MAAM,EAAE,eAAe;QACvB,YAAY,EAAE,qBAAqB;KACnC,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,oBAAoB;QACzB,MAAM,EAAE,uBAAuB;QAC/B,YAAY,EAAE,6BAA6B;KAC3C,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,uBAAuB;QAC5B,MAAM,EAAE,aAAa;QACrB,YAAY,EAAE,mBAAmB;KACjC,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,kBAAkB;QACvB,MAAM,EAAE,qBAAqB;QAC7B,YAAY,EAAE,2BAA2B;KACzC,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,wBAAwB;QAC7B,MAAM,EAAE,0BAA0B;QAClC,YAAY,EAAE,gCAAgC;KAC9C,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,wBAAwB;QAC7B,MAAM,EAAE,0BAA0B;QAClC,YAAY,EAAE,gCAAgC;KAC9C,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,sBAAsB;QAC3B,MAAM,EAAE,YAAY;QACpB,YAAY,EAAE,kBAAkB;KAChC,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,mBAAmB;QACxB,MAAM,EAAE,qBAAqB;QAC7B,YAAY,EAAE,2BAA2B;KACzC,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,eAAe;QACpB,MAAM,EAAE,kBAAkB;QAC1B,YAAY,EAAE,wBAAwB;KACtC,CAAC,CAAC;IAEH,mBAAmB,CAAC;QACnB,GAAG,EAAE,yBAAyB;QAC9B,MAAM,EAAE,iBAAiB;QACzB,YAAY,EAAE,uBAAuB;KACrC,CAAC,CAAC;AAAA,CACH;AAED,MAAM,UAAU,iBAAiB,GAAS;IACzC,iBAAiB,EAAE,CAAC;IACpB,2BAA2B,EAAE,CAAC;AAAA,CAC9B;AAED,2BAA2B,EAAE,CAAC","sourcesContent":["import { clearApiProviders, registerApiProvider } from \"../api-registry.js\";\nimport type { AssistantMessage, AssistantMessageEvent, Context, Model, SimpleStreamOptions } from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\nimport type { BedrockOptions } from \"./amazon-bedrock.js\";\nimport { streamAnthropic, streamSimpleAnthropic } from \"./anthropic.js\";\nimport { streamAzureOpenAIResponses, streamSimpleAzureOpenAIResponses } from \"./azure-openai-responses.js\";\nimport { streamGoogle, streamSimpleGoogle } from \"./google.js\";\nimport { streamGoogleGeminiCli, streamSimpleGoogleGeminiCli } from \"./google-gemini-cli.js\";\nimport { streamGoogleVertex, streamSimpleGoogleVertex } from \"./google-vertex.js\";\nimport { streamMistral, streamSimpleMistral } from \"./mistral.js\";\nimport { streamOpenAICodexResponses, streamSimpleOpenAICodexResponses } from \"./openai-codex-responses.js\";\nimport { streamOpenAICompletions, streamSimpleOpenAICompletions } from \"./openai-completions.js\";\nimport { streamOpenAIResponses, streamSimpleOpenAIResponses } from \"./openai-responses.js\";\n\ninterface BedrockProviderModule {\n\tstreamBedrock: (\n\t\tmodel: Model<\"bedrock-converse-stream\">,\n\t\tcontext: Context,\n\t\toptions?: BedrockOptions,\n\t) => AsyncIterable<AssistantMessageEvent>;\n\tstreamSimpleBedrock: (\n\t\tmodel: Model<\"bedrock-converse-stream\">,\n\t\tcontext: Context,\n\t\toptions?: SimpleStreamOptions,\n\t) => AsyncIterable<AssistantMessageEvent>;\n}\n\ntype DynamicImport = (specifier: string) => Promise<unknown>;\n\nconst dynamicImport: DynamicImport = (specifier) => import(specifier);\nconst BEDROCK_PROVIDER_SPECIFIER = \"./amazon-\" + \"bedrock.js\";\n\nlet bedrockProviderModuleOverride: BedrockProviderModule | undefined;\n\nexport function setBedrockProviderModule(module: BedrockProviderModule): void {\n\tbedrockProviderModuleOverride = module;\n}\n\nasync function loadBedrockProviderModule(): Promise<BedrockProviderModule> {\n\tif (bedrockProviderModuleOverride) {\n\t\treturn bedrockProviderModuleOverride;\n\t}\n\tconst module = await dynamicImport(BEDROCK_PROVIDER_SPECIFIER);\n\treturn module as BedrockProviderModule;\n}\n\nfunction forwardStream(target: AssistantMessageEventStream, source: AsyncIterable<AssistantMessageEvent>): void {\n\t(async () => {\n\t\tfor await (const event of source) {\n\t\t\ttarget.push(event);\n\t\t}\n\t\ttarget.end();\n\t})();\n}\n\nfunction createLazyLoadErrorMessage(model: Model<\"bedrock-converse-stream\">, error: unknown): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: \"bedrock-converse-stream\",\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"error\",\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction streamBedrockLazy(\n\tmodel: Model<\"bedrock-converse-stream\">,\n\tcontext: Context,\n\toptions?: BedrockOptions,\n): AssistantMessageEventStream {\n\tconst outer = new AssistantMessageEventStream();\n\n\tloadBedrockProviderModule()\n\t\t.then((module) => {\n\t\t\tconst inner = module.streamBedrock(model, context, options);\n\t\t\tforwardStream(outer, inner);\n\t\t})\n\t\t.catch((error) => {\n\t\t\tconst message = createLazyLoadErrorMessage(model, error);\n\t\t\touter.push({ type: \"error\", reason: \"error\", error: message });\n\t\t\touter.end(message);\n\t\t});\n\n\treturn outer;\n}\n\nfunction streamSimpleBedrockLazy(\n\tmodel: Model<\"bedrock-converse-stream\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream {\n\tconst outer = new AssistantMessageEventStream();\n\n\tloadBedrockProviderModule()\n\t\t.then((module) => {\n\t\t\tconst inner = module.streamSimpleBedrock(model, context, options);\n\t\t\tforwardStream(outer, inner);\n\t\t})\n\t\t.catch((error) => {\n\t\t\tconst message = createLazyLoadErrorMessage(model, error);\n\t\t\touter.push({ type: \"error\", reason: \"error\", error: message });\n\t\t\touter.end(message);\n\t\t});\n\n\treturn outer;\n}\n\nexport function registerBuiltInApiProviders(): void {\n\tregisterApiProvider({\n\t\tapi: \"anthropic-messages\",\n\t\tstream: streamAnthropic,\n\t\tstreamSimple: streamSimpleAnthropic,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"openai-completions\",\n\t\tstream: streamOpenAICompletions,\n\t\tstreamSimple: streamSimpleOpenAICompletions,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"mistral-conversations\",\n\t\tstream: streamMistral,\n\t\tstreamSimple: streamSimpleMistral,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"openai-responses\",\n\t\tstream: streamOpenAIResponses,\n\t\tstreamSimple: streamSimpleOpenAIResponses,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"azure-openai-responses\",\n\t\tstream: streamAzureOpenAIResponses,\n\t\tstreamSimple: streamSimpleAzureOpenAIResponses,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"openai-codex-responses\",\n\t\tstream: streamOpenAICodexResponses,\n\t\tstreamSimple: streamSimpleOpenAICodexResponses,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"google-generative-ai\",\n\t\tstream: streamGoogle,\n\t\tstreamSimple: streamSimpleGoogle,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"google-gemini-cli\",\n\t\tstream: streamGoogleGeminiCli,\n\t\tstreamSimple: streamSimpleGoogleGeminiCli,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"google-vertex\",\n\t\tstream: streamGoogleVertex,\n\t\tstreamSimple: streamSimpleGoogleVertex,\n\t});\n\n\tregisterApiProvider({\n\t\tapi: \"bedrock-converse-stream\",\n\t\tstream: streamBedrockLazy,\n\t\tstreamSimple: streamSimpleBedrockLazy,\n\t});\n}\n\nexport function resetApiProviders(): void {\n\tclearApiProviders();\n\tregisterBuiltInApiProviders();\n}\n\nregisterBuiltInApiProviders();\n"]}
@@ -0,0 +1,8 @@
1
+ import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from "../types.js";
2
+ export declare function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions;
3
+ export declare function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, "xhigh"> | undefined;
4
+ export declare function adjustMaxTokensForThinking(baseMaxTokens: number, modelMaxTokens: number, reasoningLevel: ThinkingLevel, customBudgets?: ThinkingBudgets): {
5
+ maxTokens: number;
6
+ thinkingBudget: number;
7
+ };
8
+ //# sourceMappingURL=simple-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-options.d.ts","sourceRoot":"","sources":["../../src/providers/simple-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAElH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAajH;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,SAAS,CAE7G;AAED,wBAAgB,0BAA0B,CACzC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,aAAa,EAC7B,aAAa,CAAC,EAAE,eAAe,GAC7B;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAmB/C","sourcesContent":["import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from \"../types.js\";\n\nexport function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions {\n\treturn {\n\t\ttemperature: options?.temperature,\n\t\tmaxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),\n\t\tsignal: options?.signal,\n\t\tapiKey: apiKey || options?.apiKey,\n\t\tcacheRetention: options?.cacheRetention,\n\t\tsessionId: options?.sessionId,\n\t\theaders: options?.headers,\n\t\tonPayload: options?.onPayload,\n\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\tmetadata: options?.metadata,\n\t};\n}\n\nexport function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, \"xhigh\"> | undefined {\n\treturn effort === \"xhigh\" ? \"high\" : effort;\n}\n\nexport function adjustMaxTokensForThinking(\n\tbaseMaxTokens: number,\n\tmodelMaxTokens: number,\n\treasoningLevel: ThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): { maxTokens: number; thinkingBudget: number } {\n\tconst defaultBudgets: ThinkingBudgets = {\n\t\tminimal: 1024,\n\t\tlow: 2048,\n\t\tmedium: 8192,\n\t\thigh: 16384,\n\t};\n\tconst budgets = { ...defaultBudgets, ...customBudgets };\n\n\tconst minOutputTokens = 1024;\n\tconst level = clampReasoning(reasoningLevel)!;\n\tlet thinkingBudget = budgets[level]!;\n\tconst maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n\n\tif (maxTokens <= thinkingBudget) {\n\t\tthinkingBudget = Math.max(0, maxTokens - minOutputTokens);\n\t}\n\n\treturn { maxTokens, thinkingBudget };\n}\n"]}
@@ -0,0 +1,35 @@
1
+ export function buildBaseOptions(model, options, apiKey) {
2
+ return {
3
+ temperature: options?.temperature,
4
+ maxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),
5
+ signal: options?.signal,
6
+ apiKey: apiKey || options?.apiKey,
7
+ cacheRetention: options?.cacheRetention,
8
+ sessionId: options?.sessionId,
9
+ headers: options?.headers,
10
+ onPayload: options?.onPayload,
11
+ maxRetryDelayMs: options?.maxRetryDelayMs,
12
+ metadata: options?.metadata,
13
+ };
14
+ }
15
+ export function clampReasoning(effort) {
16
+ return effort === "xhigh" ? "high" : effort;
17
+ }
18
+ export function adjustMaxTokensForThinking(baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {
19
+ const defaultBudgets = {
20
+ minimal: 1024,
21
+ low: 2048,
22
+ medium: 8192,
23
+ high: 16384,
24
+ };
25
+ const budgets = { ...defaultBudgets, ...customBudgets };
26
+ const minOutputTokens = 1024;
27
+ const level = clampReasoning(reasoningLevel);
28
+ let thinkingBudget = budgets[level];
29
+ const maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
30
+ if (maxTokens <= thinkingBudget) {
31
+ thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
32
+ }
33
+ return { maxTokens, thinkingBudget };
34
+ }
35
+ //# sourceMappingURL=simple-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-options.js","sourceRoot":"","sources":["../../src/providers/simple-options.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,KAAiB,EAAE,OAA6B,EAAE,MAAe,EAAiB;IAClH,OAAO;QACN,WAAW,EAAE,OAAO,EAAE,WAAW;QACjC,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC;QACjE,MAAM,EAAE,OAAO,EAAE,MAAM;QACvB,MAAM,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM;QACjC,cAAc,EAAE,OAAO,EAAE,cAAc;QACvC,SAAS,EAAE,OAAO,EAAE,SAAS;QAC7B,OAAO,EAAE,OAAO,EAAE,OAAO;QACzB,SAAS,EAAE,OAAO,EAAE,SAAS;QAC7B,eAAe,EAAE,OAAO,EAAE,eAAe;QACzC,QAAQ,EAAE,OAAO,EAAE,QAAQ;KAC3B,CAAC;AAAA,CACF;AAED,MAAM,UAAU,cAAc,CAAC,MAAiC,EAA+C;IAC9G,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAAA,CAC5C;AAED,MAAM,UAAU,0BAA0B,CACzC,aAAqB,EACrB,cAAsB,EACtB,cAA6B,EAC7B,aAA+B,EACiB;IAChD,MAAM,cAAc,GAAoB;QACvC,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,KAAK;KACX,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,aAAa,EAAE,CAAC;IAExD,MAAM,eAAe,GAAG,IAAI,CAAC;IAC7B,MAAM,KAAK,GAAG,cAAc,CAAC,cAAc,CAAE,CAAC;IAC9C,IAAI,cAAc,GAAG,OAAO,CAAC,KAAK,CAAE,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,cAAc,EAAE,cAAc,CAAC,CAAC;IAE3E,IAAI,SAAS,IAAI,cAAc,EAAE,CAAC;QACjC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AAAA,CACrC","sourcesContent":["import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from \"../types.js\";\n\nexport function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions {\n\treturn {\n\t\ttemperature: options?.temperature,\n\t\tmaxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),\n\t\tsignal: options?.signal,\n\t\tapiKey: apiKey || options?.apiKey,\n\t\tcacheRetention: options?.cacheRetention,\n\t\tsessionId: options?.sessionId,\n\t\theaders: options?.headers,\n\t\tonPayload: options?.onPayload,\n\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\tmetadata: options?.metadata,\n\t};\n}\n\nexport function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, \"xhigh\"> | undefined {\n\treturn effort === \"xhigh\" ? \"high\" : effort;\n}\n\nexport function adjustMaxTokensForThinking(\n\tbaseMaxTokens: number,\n\tmodelMaxTokens: number,\n\treasoningLevel: ThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): { maxTokens: number; thinkingBudget: number } {\n\tconst defaultBudgets: ThinkingBudgets = {\n\t\tminimal: 1024,\n\t\tlow: 2048,\n\t\tmedium: 8192,\n\t\thigh: 16384,\n\t};\n\tconst budgets = { ...defaultBudgets, ...customBudgets };\n\n\tconst minOutputTokens = 1024;\n\tconst level = clampReasoning(reasoningLevel)!;\n\tlet thinkingBudget = budgets[level]!;\n\tconst maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n\n\tif (maxTokens <= thinkingBudget) {\n\t\tthinkingBudget = Math.max(0, maxTokens - minOutputTokens);\n\t}\n\n\treturn { maxTokens, thinkingBudget };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { Api, AssistantMessage, Message, Model } from "../types.js";
2
+ /**
3
+ * Normalize tool call ID for cross-provider compatibility.
4
+ * OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
5
+ * Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).
6
+ */
7
+ export declare function transformMessages<TApi extends Api>(messages: Message[], model: Model<TApi>, normalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string): Message[];
8
+ //# sourceMappingURL=transform-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform-messages.d.ts","sourceRoot":"","sources":["../../src/providers/transform-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAA+B,MAAM,aAAa,CAAC;AAEtG;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,SAAS,GAAG,EACjD,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAClB,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,gBAAgB,KAAK,MAAM,GACxF,OAAO,EAAE,CAgKX","sourcesContent":["import type { Api, AssistantMessage, Message, Model, ToolCall, ToolResultMessage } from \"../types.js\";\n\n/**\n * Normalize tool call ID for cross-provider compatibility.\n * OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.\n * Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).\n */\nexport function transformMessages<TApi extends Api>(\n\tmessages: Message[],\n\tmodel: Model<TApi>,\n\tnormalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string,\n): Message[] {\n\t// Build a map of original tool call IDs to normalized IDs\n\tconst toolCallIdMap = new Map<string, string>();\n\n\t// First pass: transform messages (thinking blocks, tool call ID normalization)\n\tconst transformed = messages.map((msg) => {\n\t\t// User messages pass through unchanged\n\t\tif (msg.role === \"user\") {\n\t\t\treturn msg;\n\t\t}\n\n\t\t// Handle toolResult messages - normalize toolCallId if we have a mapping\n\t\tif (msg.role === \"toolResult\") {\n\t\t\tconst normalizedId = toolCallIdMap.get(msg.toolCallId);\n\t\t\tif (normalizedId && normalizedId !== msg.toolCallId) {\n\t\t\t\treturn { ...msg, toolCallId: normalizedId };\n\t\t\t}\n\t\t\treturn msg;\n\t\t}\n\n\t\t// Assistant messages need transformation check\n\t\tif (msg.role === \"assistant\") {\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tconst isSameModel =\n\t\t\t\tassistantMsg.provider === model.provider &&\n\t\t\t\tassistantMsg.api === model.api &&\n\t\t\t\tassistantMsg.model === model.id;\n\n\t\t\tconst transformedContent = assistantMsg.content.flatMap((block) => {\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\t// Redacted thinking is opaque encrypted content, only valid for the same model.\n\t\t\t\t\t// Drop it for cross-model to avoid API errors.\n\t\t\t\t\tif (block.redacted) {\n\t\t\t\t\t\treturn isSameModel ? block : [];\n\t\t\t\t\t}\n\t\t\t\t\t// For same model: keep thinking blocks with signatures (needed for replay)\n\t\t\t\t\t// even if the thinking text is empty (OpenAI encrypted reasoning)\n\t\t\t\t\tif (isSameModel && block.thinkingSignature) return block;\n\t\t\t\t\t// Skip empty thinking blocks, convert others to plain text\n\t\t\t\t\tif (!block.thinking || block.thinking.trim() === \"\") return [];\n\t\t\t\t\tif (isSameModel) return block;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: block.thinking,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tif (isSameModel) return block;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: block.text,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (block.type === \"toolCall\") {\n\t\t\t\t\tconst toolCall = block as ToolCall;\n\t\t\t\t\tlet normalizedToolCall: ToolCall = toolCall;\n\n\t\t\t\t\tif (!isSameModel && toolCall.thoughtSignature) {\n\t\t\t\t\t\tnormalizedToolCall = { ...toolCall };\n\t\t\t\t\t\tdelete (normalizedToolCall as { thoughtSignature?: string }).thoughtSignature;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!isSameModel && normalizeToolCallId) {\n\t\t\t\t\t\tconst normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);\n\t\t\t\t\t\tif (normalizedId !== toolCall.id) {\n\t\t\t\t\t\t\ttoolCallIdMap.set(toolCall.id, normalizedId);\n\t\t\t\t\t\t\tnormalizedToolCall = { ...normalizedToolCall, id: normalizedId };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn normalizedToolCall;\n\t\t\t\t}\n\n\t\t\t\treturn block;\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\t...assistantMsg,\n\t\t\t\tcontent: transformedContent,\n\t\t\t};\n\t\t}\n\t\treturn msg;\n\t});\n\n\t// Second pass: insert synthetic empty tool results for orphaned tool calls\n\t// This preserves thinking signatures and satisfies API requirements\n\tconst result: Message[] = [];\n\tlet pendingToolCalls: ToolCall[] = [];\n\tlet existingToolResultIds = new Set<string>();\n\n\tfor (let i = 0; i < transformed.length; i++) {\n\t\tconst msg = transformed[i];\n\n\t\tif (msg.role === \"assistant\") {\n\t\t\t// If we have pending orphaned tool calls from a previous assistant, insert synthetic results now\n\t\t\tif (pendingToolCalls.length > 0) {\n\t\t\t\tfor (const tc of pendingToolCalls) {\n\t\t\t\t\tif (!existingToolResultIds.has(tc.id)) {\n\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\trole: \"toolResult\",\n\t\t\t\t\t\t\ttoolCallId: tc.id,\n\t\t\t\t\t\t\ttoolName: tc.name,\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No result provided\" }],\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t} as ToolResultMessage);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpendingToolCalls = [];\n\t\t\t\texistingToolResultIds = new Set();\n\t\t\t}\n\n\t\t\t// Skip errored/aborted assistant messages entirely.\n\t\t\t// These are incomplete turns that shouldn't be replayed:\n\t\t\t// - May have partial content (reasoning without message, incomplete tool calls)\n\t\t\t// - Replaying them can cause API errors (e.g., OpenAI \"reasoning without following item\")\n\t\t\t// - The model should retry from the last valid state\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Track tool calls from this assistant message\n\t\t\tconst toolCalls = assistantMsg.content.filter((b) => b.type === \"toolCall\") as ToolCall[];\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tpendingToolCalls = toolCalls;\n\t\t\t\texistingToolResultIds = new Set();\n\t\t\t}\n\n\t\t\tresult.push(msg);\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\texistingToolResultIds.add(msg.toolCallId);\n\t\t\tresult.push(msg);\n\t\t} else if (msg.role === \"user\") {\n\t\t\t// User message interrupts tool flow - insert synthetic results for orphaned calls\n\t\t\tif (pendingToolCalls.length > 0) {\n\t\t\t\tfor (const tc of pendingToolCalls) {\n\t\t\t\t\tif (!existingToolResultIds.has(tc.id)) {\n\t\t\t\t\t\tresult.push({\n\t\t\t\t\t\t\trole: \"toolResult\",\n\t\t\t\t\t\t\ttoolCallId: tc.id,\n\t\t\t\t\t\t\ttoolName: tc.name,\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No result provided\" }],\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t} as ToolResultMessage);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpendingToolCalls = [];\n\t\t\t\texistingToolResultIds = new Set();\n\t\t\t}\n\t\t\tresult.push(msg);\n\t\t} else {\n\t\t\tresult.push(msg);\n\t\t}\n\t}\n\n\treturn result;\n}\n"]}