@acosmi/sdk-ts 1.0.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 (35) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +247 -0
  3. package/dist/browser/index.js +3950 -0
  4. package/dist/browser/index.js.map +1 -0
  5. package/dist/index.js +3950 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/node/adapters/anthropic.cjs +257 -0
  8. package/dist/node/adapters/anthropic.cjs.map +1 -0
  9. package/dist/node/adapters/anthropic.d.cts +39 -0
  10. package/dist/node/adapters/anthropic.d.ts +39 -0
  11. package/dist/node/adapters/anthropic.js +254 -0
  12. package/dist/node/adapters/anthropic.js.map +1 -0
  13. package/dist/node/adapters/openai.cjs +472 -0
  14. package/dist/node/adapters/openai.cjs.map +1 -0
  15. package/dist/node/adapters/openai.d.cts +64 -0
  16. package/dist/node/adapters/openai.d.ts +64 -0
  17. package/dist/node/adapters/openai.js +465 -0
  18. package/dist/node/adapters/openai.js.map +1 -0
  19. package/dist/node/index-C3Z_84Bv.d.cts +992 -0
  20. package/dist/node/index-C3Z_84Bv.d.ts +992 -0
  21. package/dist/node/index-nvLKgCm9.d.cts +147 -0
  22. package/dist/node/index-nvLKgCm9.d.ts +147 -0
  23. package/dist/node/index.cjs +4024 -0
  24. package/dist/node/index.cjs.map +1 -0
  25. package/dist/node/index.d.cts +791 -0
  26. package/dist/node/index.d.ts +791 -0
  27. package/dist/node/index.js +3950 -0
  28. package/dist/node/index.js.map +1 -0
  29. package/dist/node/sanitize/index.cjs +248 -0
  30. package/dist/node/sanitize/index.cjs.map +1 -0
  31. package/dist/node/sanitize/index.d.cts +1 -0
  32. package/dist/node/sanitize/index.d.ts +1 -0
  33. package/dist/node/sanitize/index.js +217 -0
  34. package/dist/node/sanitize/index.js.map +1 -0
  35. package/package.json +84 -0
@@ -0,0 +1,64 @@
1
+ import { P as ProviderAdapter, aj as ProviderFormat, M as ModelCapabilities, b as ChatRequest, e as ChatResponse, f as StreamEvent, A as AnthropicResponse } from '../index-C3Z_84Bv.cjs';
2
+
3
+ /** 实现 ProviderAdapter, 用于所有非 Anthropic 厂商 */
4
+ declare class OpenAIAdapter implements ProviderAdapter {
5
+ format(): ProviderFormat;
6
+ endpointSuffix(): string;
7
+ /**
8
+ * 构建 OpenAI 兼容格式请求体
9
+ * 不注入 Anthropic betas, 扩展字段 (thinking/effort/speed) 以通用 JSON 传递
10
+ */
11
+ buildRequestBody(_caps: ModelCapabilities, req: ChatRequest): Record<string, unknown>;
12
+ /**
13
+ * 解析 OpenAI 格式同步响应为 ChatResponse
14
+ * 兼容 APIResponse 包装 {"code":0,"data":{...}} 和裸 OpenAI JSON 两种格式
15
+ */
16
+ parseResponse(bodyInput: Uint8Array | string): ChatResponse;
17
+ /**
18
+ * 解析 OpenAI SSE 行
19
+ * [DONE] 标记流结束
20
+ */
21
+ parseStreamLine(eventType: string, data: string): {
22
+ event: StreamEvent;
23
+ done: boolean;
24
+ };
25
+ }
26
+ /**
27
+ * 把 Anthropic 心智模型的 thinking/effort 翻译成 OpenAI `reasoning_effort` 字段值
28
+ * 返回空串表示不设置
29
+ */
30
+ declare function resolveOpenAIReasoningEffort(req: ChatRequest): string;
31
+ /**
32
+ * 把 outputConfig 翻译成 OpenAI response_format
33
+ * 返回 null 表示不设置
34
+ */
35
+ declare function resolveOpenAIResponseFormat(req: ChatRequest): Record<string, unknown> | null;
36
+ /**
37
+ * 解析 OpenAI 格式响应并转换为 AnthropicResponse
38
+ * 用于 chatMessagesOpenAI 方法, 使 Hub 层无需感知 provider 差异
39
+ */
40
+ declare function parseOpenAIResponseToAnthropic(raw: string | Uint8Array): AnthropicResponse;
41
+ /**
42
+ * 将 OpenAI SSE chunks 转换为 Anthropic 兼容的 StreamEvent
43
+ * 有状态: 跨 chunk 追踪 block 索引
44
+ */
45
+ declare class OpenAIStreamConverter {
46
+ private messageStarted;
47
+ private thinkingStarted;
48
+ private thinkingStopped;
49
+ private textStarted;
50
+ /** OpenAI tool_call index → Anthropic block index */
51
+ private toolBlockIndex;
52
+ private blockIndex;
53
+ /**
54
+ * 将一行 OpenAI SSE data 转换为零或多个 Anthropic 格式 StreamEvent
55
+ * 返回 { events, done }
56
+ */
57
+ convert(data: string): {
58
+ events: StreamEvent[];
59
+ done: boolean;
60
+ };
61
+ }
62
+ declare function newOpenAIStreamConverter(): OpenAIStreamConverter;
63
+
64
+ export { OpenAIAdapter, OpenAIStreamConverter, newOpenAIStreamConverter, parseOpenAIResponseToAnthropic, resolveOpenAIReasoningEffort, resolveOpenAIResponseFormat };
@@ -0,0 +1,64 @@
1
+ import { P as ProviderAdapter, aj as ProviderFormat, M as ModelCapabilities, b as ChatRequest, e as ChatResponse, f as StreamEvent, A as AnthropicResponse } from '../index-C3Z_84Bv.js';
2
+
3
+ /** 实现 ProviderAdapter, 用于所有非 Anthropic 厂商 */
4
+ declare class OpenAIAdapter implements ProviderAdapter {
5
+ format(): ProviderFormat;
6
+ endpointSuffix(): string;
7
+ /**
8
+ * 构建 OpenAI 兼容格式请求体
9
+ * 不注入 Anthropic betas, 扩展字段 (thinking/effort/speed) 以通用 JSON 传递
10
+ */
11
+ buildRequestBody(_caps: ModelCapabilities, req: ChatRequest): Record<string, unknown>;
12
+ /**
13
+ * 解析 OpenAI 格式同步响应为 ChatResponse
14
+ * 兼容 APIResponse 包装 {"code":0,"data":{...}} 和裸 OpenAI JSON 两种格式
15
+ */
16
+ parseResponse(bodyInput: Uint8Array | string): ChatResponse;
17
+ /**
18
+ * 解析 OpenAI SSE 行
19
+ * [DONE] 标记流结束
20
+ */
21
+ parseStreamLine(eventType: string, data: string): {
22
+ event: StreamEvent;
23
+ done: boolean;
24
+ };
25
+ }
26
+ /**
27
+ * 把 Anthropic 心智模型的 thinking/effort 翻译成 OpenAI `reasoning_effort` 字段值
28
+ * 返回空串表示不设置
29
+ */
30
+ declare function resolveOpenAIReasoningEffort(req: ChatRequest): string;
31
+ /**
32
+ * 把 outputConfig 翻译成 OpenAI response_format
33
+ * 返回 null 表示不设置
34
+ */
35
+ declare function resolveOpenAIResponseFormat(req: ChatRequest): Record<string, unknown> | null;
36
+ /**
37
+ * 解析 OpenAI 格式响应并转换为 AnthropicResponse
38
+ * 用于 chatMessagesOpenAI 方法, 使 Hub 层无需感知 provider 差异
39
+ */
40
+ declare function parseOpenAIResponseToAnthropic(raw: string | Uint8Array): AnthropicResponse;
41
+ /**
42
+ * 将 OpenAI SSE chunks 转换为 Anthropic 兼容的 StreamEvent
43
+ * 有状态: 跨 chunk 追踪 block 索引
44
+ */
45
+ declare class OpenAIStreamConverter {
46
+ private messageStarted;
47
+ private thinkingStarted;
48
+ private thinkingStopped;
49
+ private textStarted;
50
+ /** OpenAI tool_call index → Anthropic block index */
51
+ private toolBlockIndex;
52
+ private blockIndex;
53
+ /**
54
+ * 将一行 OpenAI SSE data 转换为零或多个 Anthropic 格式 StreamEvent
55
+ * 返回 { events, done }
56
+ */
57
+ convert(data: string): {
58
+ events: StreamEvent[];
59
+ done: boolean;
60
+ };
61
+ }
62
+ declare function newOpenAIStreamConverter(): OpenAIStreamConverter;
63
+
64
+ export { OpenAIAdapter, OpenAIStreamConverter, newOpenAIStreamConverter, parseOpenAIResponseToAnthropic, resolveOpenAIReasoningEffort, resolveOpenAIResponseFormat };
@@ -0,0 +1,465 @@
1
+ // src/types.ts
2
+ var ThinkingOff = "off";
3
+ var ThinkingHigh = "high";
4
+ var ThinkingMax = "max";
5
+ var BusinessError = class extends Error {
6
+ code;
7
+ constructor(code, message) {
8
+ super(`API error (code=${code}): ${message}`);
9
+ this.name = "BusinessError";
10
+ this.code = code;
11
+ }
12
+ };
13
+ new OpenAIAdapter();
14
+
15
+ // src/adapters/openai.ts
16
+ var OpenAIAdapter = class {
17
+ format() {
18
+ return 1 /* OpenAI */;
19
+ }
20
+ endpointSuffix() {
21
+ return "/chat";
22
+ }
23
+ /**
24
+ * 构建 OpenAI 兼容格式请求体
25
+ * 不注入 Anthropic betas, 扩展字段 (thinking/effort/speed) 以通用 JSON 传递
26
+ */
27
+ buildRequestBody(_caps, req) {
28
+ const body = {};
29
+ if (req.rawMessages != null) {
30
+ body["messages"] = req.rawMessages;
31
+ } else if ((req.messages?.length ?? 0) > 0) {
32
+ body["messages"] = req.messages;
33
+ }
34
+ body["stream"] = req.stream === true;
35
+ if (req.max_tokens && req.max_tokens > 0) {
36
+ body["max_tokens"] = req.max_tokens;
37
+ }
38
+ if (req.system != null) {
39
+ body["system"] = req.system;
40
+ }
41
+ if (req.temperature != null) {
42
+ body["temperature"] = req.temperature;
43
+ }
44
+ if (req.tools != null) {
45
+ body["tools"] = req.tools;
46
+ }
47
+ const eff = resolveOpenAIReasoningEffort(req);
48
+ if (eff !== "") {
49
+ body["reasoning_effort"] = eff;
50
+ }
51
+ if (req.speed && req.speed !== "") {
52
+ body["speed"] = req.speed;
53
+ }
54
+ const rf = resolveOpenAIResponseFormat(req);
55
+ if (rf) {
56
+ body["response_format"] = rf;
57
+ }
58
+ if (req.metadata) {
59
+ body["metadata"] = req.metadata;
60
+ }
61
+ if (req.parallelToolCalls != null) {
62
+ body["parallel_tool_calls"] = req.parallelToolCalls;
63
+ }
64
+ if (req.extraBody) {
65
+ for (const [k, v] of Object.entries(req.extraBody)) {
66
+ body[k] = v;
67
+ }
68
+ }
69
+ if (req.stream === true) {
70
+ body["stream_options"] = { include_usage: true };
71
+ }
72
+ return body;
73
+ }
74
+ /**
75
+ * 解析 OpenAI 格式同步响应为 ChatResponse
76
+ * 兼容 APIResponse 包装 {"code":0,"data":{...}} 和裸 OpenAI JSON 两种格式
77
+ */
78
+ parseResponse(bodyInput) {
79
+ const bodyStr = typeof bodyInput === "string" ? bodyInput : new TextDecoder().decode(bodyInput);
80
+ let raw = bodyStr;
81
+ try {
82
+ const wrapper = JSON.parse(bodyStr);
83
+ if (wrapper.data != null && wrapper.data !== null) {
84
+ if ((wrapper.code ?? 0) !== 0) {
85
+ throw new BusinessError(wrapper.code ?? 0, wrapper.message ?? "");
86
+ }
87
+ raw = JSON.stringify(wrapper.data);
88
+ }
89
+ } catch (e) {
90
+ if (e instanceof BusinessError) throw e;
91
+ }
92
+ let oaiResp;
93
+ try {
94
+ oaiResp = JSON.parse(raw);
95
+ } catch (e) {
96
+ throw new Error(`decode openai response: ${e instanceof Error ? e.message : String(e)}`);
97
+ }
98
+ return convertOpenAIToChatResponse(oaiResp);
99
+ }
100
+ /**
101
+ * 解析 OpenAI SSE 行
102
+ * [DONE] 标记流结束
103
+ */
104
+ parseStreamLine(eventType, data) {
105
+ if (data === "[DONE]") {
106
+ return { event: { event: "", data: "" }, done: true };
107
+ }
108
+ try {
109
+ JSON.parse(data);
110
+ } catch (e) {
111
+ throw new Error(`parse openai stream chunk: ${e instanceof Error ? e.message : String(e)}`);
112
+ }
113
+ return { event: { event: eventType, data }, done: false };
114
+ }
115
+ };
116
+ function resolveOpenAIReasoningEffort(req) {
117
+ if (req.effort && req.effort.level !== "") {
118
+ switch (req.effort.level) {
119
+ case "low":
120
+ case "medium":
121
+ case "high":
122
+ return req.effort.level;
123
+ case "max":
124
+ return "high";
125
+ }
126
+ }
127
+ if (req.thinking) {
128
+ switch (req.thinking.level) {
129
+ case ThinkingHigh:
130
+ return "high";
131
+ case ThinkingMax:
132
+ return "high";
133
+ case ThinkingOff:
134
+ return "";
135
+ }
136
+ }
137
+ return "";
138
+ }
139
+ function resolveOpenAIResponseFormat(req) {
140
+ if (!req.outputConfig) return null;
141
+ switch (req.outputConfig.format) {
142
+ case "json_schema": {
143
+ const js = {};
144
+ if (req.outputConfig.schema != null) {
145
+ js["schema"] = req.outputConfig.schema;
146
+ }
147
+ js["strict"] = true;
148
+ return {
149
+ type: "json_schema",
150
+ json_schema: js
151
+ };
152
+ }
153
+ case "json_object":
154
+ return { type: "json_object" };
155
+ case "":
156
+ case void 0:
157
+ return null;
158
+ default:
159
+ return { type: req.outputConfig.format };
160
+ }
161
+ }
162
+ function convertOpenAIToChatResponse(oai) {
163
+ const resp = {
164
+ id: oai.id,
165
+ type: "message",
166
+ model: oai.model,
167
+ role: "assistant",
168
+ content: [],
169
+ stop_reason: "",
170
+ usage: {
171
+ input_tokens: oai.usage.prompt_tokens,
172
+ output_tokens: oai.usage.completion_tokens
173
+ },
174
+ tokenRemaining: -1,
175
+ callRemaining: -1,
176
+ modelTokenRemaining: -1,
177
+ modelTokenRemainingETU: -1
178
+ };
179
+ if (oai.choices.length > 0) {
180
+ const choice = oai.choices[0];
181
+ switch (choice.finish_reason) {
182
+ case "stop":
183
+ resp.stop_reason = "end_turn";
184
+ break;
185
+ case "tool_calls":
186
+ resp.stop_reason = "tool_use";
187
+ break;
188
+ case "length":
189
+ resp.stop_reason = "max_tokens";
190
+ break;
191
+ default:
192
+ resp.stop_reason = choice.finish_reason;
193
+ }
194
+ if (choice.message.reasoning_content && choice.message.reasoning_content !== "") {
195
+ resp.content.push({
196
+ type: "thinking",
197
+ thinking: choice.message.reasoning_content
198
+ });
199
+ }
200
+ if (choice.message.content && choice.message.content !== "") {
201
+ resp.content.push({
202
+ type: "text",
203
+ text: choice.message.content
204
+ });
205
+ }
206
+ for (const tc of choice.message.tool_calls ?? []) {
207
+ resp.content.push({
208
+ type: "tool_use",
209
+ id: tc.id,
210
+ name: tc.function.name,
211
+ // Anthropic 协议 input 是 raw JSON value; OpenAI 给的 arguments 是 string,
212
+ // Go 侧用 json.RawMessage(arguments) 直透(原始字节). TS 我们尝试解析:
213
+ input: tryParseJSON(tc.function.arguments)
214
+ });
215
+ }
216
+ }
217
+ return resp;
218
+ }
219
+ function tryParseJSON(s) {
220
+ try {
221
+ return JSON.parse(s);
222
+ } catch {
223
+ return s;
224
+ }
225
+ }
226
+ function parseOpenAIResponseToAnthropic(raw) {
227
+ const rawStr = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
228
+ let data = rawStr;
229
+ try {
230
+ const wrapper = JSON.parse(rawStr);
231
+ if (wrapper.data != null && wrapper.data !== null) {
232
+ if ((wrapper.code ?? 0) !== 0) {
233
+ throw new BusinessError(wrapper.code ?? 0, wrapper.message ?? "");
234
+ }
235
+ data = JSON.stringify(wrapper.data);
236
+ }
237
+ } catch (e) {
238
+ if (e instanceof BusinessError) throw e;
239
+ }
240
+ let oaiResp;
241
+ try {
242
+ oaiResp = JSON.parse(data);
243
+ } catch (e) {
244
+ throw new Error(`decode openai response: ${e instanceof Error ? e.message : String(e)}`);
245
+ }
246
+ const resp = {
247
+ id: oaiResp.id,
248
+ type: "message",
249
+ role: "assistant",
250
+ content: [],
251
+ model: oaiResp.model,
252
+ stop_reason: "",
253
+ usage: {
254
+ input_tokens: oaiResp.usage.prompt_tokens,
255
+ output_tokens: oaiResp.usage.completion_tokens
256
+ }
257
+ };
258
+ if (oaiResp.choices.length > 0) {
259
+ const choice = oaiResp.choices[0];
260
+ switch (choice.finish_reason) {
261
+ case "stop":
262
+ resp.stop_reason = "end_turn";
263
+ break;
264
+ case "tool_calls":
265
+ resp.stop_reason = "tool_use";
266
+ break;
267
+ case "length":
268
+ resp.stop_reason = "max_tokens";
269
+ break;
270
+ default:
271
+ resp.stop_reason = choice.finish_reason;
272
+ }
273
+ if (choice.message.reasoning_content && choice.message.reasoning_content !== "") {
274
+ resp.content.push({
275
+ type: "thinking",
276
+ thinking: choice.message.reasoning_content
277
+ });
278
+ }
279
+ if (choice.message.content && choice.message.content !== "") {
280
+ resp.content.push({
281
+ type: "text",
282
+ text: choice.message.content
283
+ });
284
+ }
285
+ for (const tc of choice.message.tool_calls ?? []) {
286
+ resp.content.push({
287
+ type: "tool_use",
288
+ id: tc.id,
289
+ name: tc.function.name,
290
+ input: tryParseJSON(tc.function.arguments)
291
+ });
292
+ }
293
+ }
294
+ return resp;
295
+ }
296
+ var OpenAIStreamConverter = class {
297
+ messageStarted = false;
298
+ thinkingStarted = false;
299
+ thinkingStopped = false;
300
+ textStarted = false;
301
+ /** OpenAI tool_call index → Anthropic block index */
302
+ toolBlockIndex = /* @__PURE__ */ new Map();
303
+ blockIndex = 0;
304
+ /**
305
+ * 将一行 OpenAI SSE data 转换为零或多个 Anthropic 格式 StreamEvent
306
+ * 返回 { events, done }
307
+ */
308
+ convert(data) {
309
+ if (data === "[DONE]") {
310
+ return { events: [], done: true };
311
+ }
312
+ let chunk;
313
+ try {
314
+ chunk = JSON.parse(data);
315
+ } catch (e) {
316
+ throw new Error(`parse openai stream chunk: ${e instanceof Error ? e.message : String(e)}`);
317
+ }
318
+ const events = [];
319
+ if (chunk.choices.length === 0) {
320
+ return { events, done: false };
321
+ }
322
+ const choice = chunk.choices[0];
323
+ if (!this.messageStarted) {
324
+ this.messageStarted = true;
325
+ const msgJSON = JSON.stringify({
326
+ type: "message_start",
327
+ message: {
328
+ id: chunk.id,
329
+ type: "message",
330
+ role: "assistant",
331
+ content: [],
332
+ model: ""
333
+ }
334
+ });
335
+ events.push({ event: "message_start", data: msgJSON });
336
+ }
337
+ if (choice.delta.reasoning_content && choice.delta.reasoning_content !== "") {
338
+ if (!this.thinkingStarted) {
339
+ this.thinkingStarted = true;
340
+ const blockJSON = JSON.stringify({
341
+ type: "content_block_start",
342
+ index: this.blockIndex,
343
+ content_block: { type: "thinking", thinking: "" }
344
+ });
345
+ events.push({ event: "content_block_start", data: blockJSON });
346
+ }
347
+ const deltaJSON = JSON.stringify({
348
+ type: "content_block_delta",
349
+ index: this.blockIndex,
350
+ delta: { type: "thinking_delta", thinking: choice.delta.reasoning_content }
351
+ });
352
+ events.push({ event: "content_block_delta", data: deltaJSON });
353
+ }
354
+ if (choice.delta.content && choice.delta.content !== "") {
355
+ if (this.thinkingStarted && !this.thinkingStopped) {
356
+ this.thinkingStopped = true;
357
+ const stopJSON = JSON.stringify({
358
+ type: "content_block_stop",
359
+ index: this.blockIndex
360
+ });
361
+ events.push({ event: "content_block_stop", data: stopJSON });
362
+ this.blockIndex++;
363
+ }
364
+ if (!this.textStarted) {
365
+ this.textStarted = true;
366
+ const blockJSON = JSON.stringify({
367
+ type: "content_block_start",
368
+ index: this.blockIndex,
369
+ content_block: { type: "text", text: "" }
370
+ });
371
+ events.push({ event: "content_block_start", data: blockJSON });
372
+ }
373
+ const deltaJSON = JSON.stringify({
374
+ type: "content_block_delta",
375
+ index: this.blockIndex,
376
+ delta: { type: "text_delta", text: choice.delta.content }
377
+ });
378
+ events.push({ event: "content_block_delta", data: deltaJSON });
379
+ }
380
+ for (const tc of choice.delta.tool_calls ?? []) {
381
+ if (!this.toolBlockIndex.has(tc.index)) {
382
+ if (this.textStarted) {
383
+ const stopJSON = JSON.stringify({
384
+ type: "content_block_stop",
385
+ index: this.blockIndex
386
+ });
387
+ events.push({ event: "content_block_stop", data: stopJSON });
388
+ this.blockIndex++;
389
+ this.textStarted = false;
390
+ }
391
+ this.toolBlockIndex.set(tc.index, this.blockIndex);
392
+ const blockJSON = JSON.stringify({
393
+ type: "content_block_start",
394
+ index: this.blockIndex,
395
+ content_block: {
396
+ type: "tool_use",
397
+ id: tc.id,
398
+ name: tc.function.name,
399
+ input: {}
400
+ }
401
+ });
402
+ events.push({ event: "content_block_start", data: blockJSON });
403
+ this.blockIndex++;
404
+ }
405
+ if (tc.function.arguments && tc.function.arguments !== "") {
406
+ const idx = this.toolBlockIndex.get(tc.index);
407
+ const deltaJSON = JSON.stringify({
408
+ type: "content_block_delta",
409
+ index: idx,
410
+ delta: {
411
+ type: "input_json_delta",
412
+ partial_json: tc.function.arguments
413
+ }
414
+ });
415
+ events.push({ event: "content_block_delta", data: deltaJSON });
416
+ }
417
+ }
418
+ if (choice.finish_reason != null && choice.finish_reason !== "") {
419
+ if (this.textStarted) {
420
+ const stopJSON2 = JSON.stringify({
421
+ type: "content_block_stop",
422
+ index: this.blockIndex
423
+ });
424
+ events.push({ event: "content_block_stop", data: stopJSON2 });
425
+ } else if (this.thinkingStarted && !this.thinkingStopped) {
426
+ const stopJSON2 = JSON.stringify({
427
+ type: "content_block_stop",
428
+ index: this.blockIndex
429
+ });
430
+ events.push({ event: "content_block_stop", data: stopJSON2 });
431
+ }
432
+ for (const idx of this.toolBlockIndex.values()) {
433
+ const stopJSON2 = JSON.stringify({
434
+ type: "content_block_stop",
435
+ index: idx
436
+ });
437
+ events.push({ event: "content_block_stop", data: stopJSON2 });
438
+ }
439
+ let stopReason = "end_turn";
440
+ switch (choice.finish_reason) {
441
+ case "tool_calls":
442
+ stopReason = "tool_use";
443
+ break;
444
+ case "length":
445
+ stopReason = "max_tokens";
446
+ break;
447
+ }
448
+ const deltaJSON = JSON.stringify({
449
+ type: "message_delta",
450
+ delta: { stop_reason: stopReason }
451
+ });
452
+ events.push({ event: "message_delta", data: deltaJSON });
453
+ const stopJSON = JSON.stringify({ type: "message_stop" });
454
+ events.push({ event: "message_stop", data: stopJSON });
455
+ }
456
+ return { events, done: false };
457
+ }
458
+ };
459
+ function newOpenAIStreamConverter() {
460
+ return new OpenAIStreamConverter();
461
+ }
462
+
463
+ export { OpenAIAdapter, OpenAIStreamConverter, newOpenAIStreamConverter, parseOpenAIResponseToAnthropic, resolveOpenAIReasoningEffort, resolveOpenAIResponseFormat };
464
+ //# sourceMappingURL=openai.js.map
465
+ //# sourceMappingURL=openai.js.map