@iinm/plain-agent 1.8.3 → 1.8.4

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 (86) hide show
  1. package/README.md +2 -2
  2. package/bin/plain +1 -1
  3. package/config/config.predefined.json +1 -1
  4. package/config/prompts.predefined/shortcuts/configure.md +1 -1
  5. package/dist/main.mjs +473 -0
  6. package/dist/main.mjs.map +7 -0
  7. package/package.json +5 -7
  8. package/src/agent.d.ts +0 -52
  9. package/src/agent.mjs +0 -204
  10. package/src/agentLoop.mjs +0 -419
  11. package/src/agentState.mjs +0 -41
  12. package/src/claudeCodePlugin.mjs +0 -164
  13. package/src/cliArgs.mjs +0 -175
  14. package/src/cliBatch.mjs +0 -147
  15. package/src/cliCommands.mjs +0 -283
  16. package/src/cliCompleter.mjs +0 -227
  17. package/src/cliCost.mjs +0 -309
  18. package/src/cliFormatter.mjs +0 -413
  19. package/src/cliInteractive.mjs +0 -529
  20. package/src/cliInterruptTransform.mjs +0 -51
  21. package/src/cliMuteTransform.mjs +0 -26
  22. package/src/cliPasteTransform.mjs +0 -183
  23. package/src/config.d.ts +0 -36
  24. package/src/config.mjs +0 -197
  25. package/src/context/loadAgentRoles.mjs +0 -283
  26. package/src/context/loadPrompts.mjs +0 -324
  27. package/src/context/loadUserMessageContext.mjs +0 -147
  28. package/src/costTracker.mjs +0 -210
  29. package/src/env.mjs +0 -44
  30. package/src/main.mjs +0 -279
  31. package/src/mcpClient.mjs +0 -351
  32. package/src/mcpIntegration.mjs +0 -160
  33. package/src/model.d.ts +0 -109
  34. package/src/modelCaller.mjs +0 -32
  35. package/src/modelDefinition.d.ts +0 -92
  36. package/src/prompt.mjs +0 -138
  37. package/src/providers/anthropic.d.ts +0 -248
  38. package/src/providers/anthropic.mjs +0 -587
  39. package/src/providers/bedrock.d.ts +0 -249
  40. package/src/providers/bedrock.mjs +0 -700
  41. package/src/providers/gemini.d.ts +0 -208
  42. package/src/providers/gemini.mjs +0 -754
  43. package/src/providers/openai.d.ts +0 -281
  44. package/src/providers/openai.mjs +0 -544
  45. package/src/providers/openaiCompatible.d.ts +0 -147
  46. package/src/providers/openaiCompatible.mjs +0 -652
  47. package/src/providers/platform/awsSigV4.mjs +0 -184
  48. package/src/providers/platform/azure.mjs +0 -42
  49. package/src/providers/platform/bedrock.mjs +0 -78
  50. package/src/providers/platform/googleCloud.mjs +0 -34
  51. package/src/subagent.mjs +0 -265
  52. package/src/tmpfile.mjs +0 -27
  53. package/src/tool.d.ts +0 -74
  54. package/src/toolExecutor.mjs +0 -236
  55. package/src/toolInputValidator.mjs +0 -183
  56. package/src/toolUseApprover.mjs +0 -99
  57. package/src/tools/askURL.mjs +0 -209
  58. package/src/tools/askWeb.mjs +0 -208
  59. package/src/tools/compactContext.d.ts +0 -4
  60. package/src/tools/compactContext.mjs +0 -87
  61. package/src/tools/delegateToSubagent.d.ts +0 -4
  62. package/src/tools/delegateToSubagent.mjs +0 -48
  63. package/src/tools/execCommand.d.ts +0 -22
  64. package/src/tools/execCommand.mjs +0 -200
  65. package/src/tools/patchFile.d.ts +0 -4
  66. package/src/tools/patchFile.mjs +0 -133
  67. package/src/tools/reportAsSubagent.d.ts +0 -3
  68. package/src/tools/reportAsSubagent.mjs +0 -44
  69. package/src/tools/tmuxCommand.d.ts +0 -14
  70. package/src/tools/tmuxCommand.mjs +0 -194
  71. package/src/tools/writeFile.d.ts +0 -4
  72. package/src/tools/writeFile.mjs +0 -56
  73. package/src/usageStore.mjs +0 -167
  74. package/src/utils/evalJSONConfig.mjs +0 -72
  75. package/src/utils/matchValue.d.ts +0 -6
  76. package/src/utils/matchValue.mjs +0 -40
  77. package/src/utils/noThrow.mjs +0 -31
  78. package/src/utils/notify.mjs +0 -29
  79. package/src/utils/parseFileRange.mjs +0 -18
  80. package/src/utils/readFileRange.mjs +0 -33
  81. package/src/utils/retryOnError.mjs +0 -41
  82. package/src/voiceInput.mjs +0 -61
  83. package/src/voiceInputGemini.mjs +0 -105
  84. package/src/voiceInputOpenAI.mjs +0 -104
  85. package/src/voiceInputSession.mjs +0 -543
  86. package/src/voiceToggleKey.mjs +0 -62
@@ -1,544 +0,0 @@
1
- /**
2
- * @import { ModelInput, Message, AssistantMessage, ModelOutput, PartialMessageContent } from "../model"
3
- * @import { OpenAIFunctionToolCall, OpenAIInputImage, OpenAIInputItem, OpenAIModelConfig, OpenAIOutputItem, OpenAIOutputMessage, OpenAIReasoning, OpenAIRequest, OpenAIStreamEvent, OpenAIToolFunction } from "./openai"
4
- * @import { ToolDefinition } from "../tool"
5
- */
6
-
7
- import { styleText } from "node:util";
8
- import { noThrow } from "../utils/noThrow.mjs";
9
- import { getAzureAccessToken } from "./platform/azure.mjs";
10
-
11
- /**
12
- * @param {import("../modelDefinition").PlatformConfig} platformConfig
13
- * @param {OpenAIModelConfig} modelConfig
14
- * @param {ModelInput} input
15
- * @param {number} retryCount
16
- * @returns {Promise<ModelOutput | Error>}
17
- */
18
- export async function callOpenAIModel(
19
- platformConfig,
20
- modelConfig,
21
- input,
22
- retryCount = 0,
23
- ) {
24
- return await noThrow(async () => {
25
- const messages = convertGenericMessageToOpenAIFormat(input.messages);
26
- const tools = convertGenericeToolDefinitionToOpenAIFormat(
27
- input.tools || [],
28
- );
29
-
30
- const { model, ...baseModelConfig } = modelConfig;
31
-
32
- /** @type {OpenAIRequest} */
33
- const request = {
34
- ...baseModelConfig,
35
- model: model,
36
- input: messages,
37
- tools: tools.length ? tools : undefined,
38
- stream: true,
39
- };
40
-
41
- const apiKey = await (async () => {
42
- switch (platformConfig.name) {
43
- case "openai":
44
- case "openai-compatible":
45
- return platformConfig.apiKey;
46
- case "azure":
47
- return getAzureAccessToken(
48
- platformConfig.azureConfigDir
49
- ? {
50
- azureConfigDir: platformConfig.azureConfigDir,
51
- }
52
- : undefined,
53
- );
54
- default:
55
- throw new Error(`Unsupported platform: ${platformConfig.name}`);
56
- }
57
- })();
58
-
59
- const response = await fetch(`${platformConfig.baseURL}/v1/responses`, {
60
- method: "POST",
61
- headers: {
62
- ...platformConfig.customHeaders,
63
- "Content-Type": "application/json",
64
- Authorization: `Bearer ${apiKey}`,
65
- },
66
- body: JSON.stringify(request),
67
- signal: AbortSignal.timeout(8 * 60 * 1000),
68
- });
69
-
70
- const retryInterval = Math.min(2 * 2 ** retryCount, 16);
71
- if (response.status === 429 || response.status >= 500) {
72
- console.error(
73
- styleText(
74
- "yellow",
75
- `OpenAI rate limit exceeded. Retry in ${retryInterval} seconds...`,
76
- ),
77
- );
78
- await new Promise((resolve) => setTimeout(resolve, retryInterval * 1000));
79
- return callOpenAIModel(
80
- platformConfig,
81
- modelConfig,
82
- input,
83
- retryCount + 1,
84
- );
85
- }
86
-
87
- if (response.status !== 200) {
88
- throw new Error(
89
- `Failed to call OpenAI model: status=${response.status}, body=${await response.text()}`,
90
- );
91
- }
92
-
93
- if (!response.body) {
94
- throw new Error("Response body is empty");
95
- }
96
-
97
- const reader = response.body.getReader();
98
-
99
- /** @type {OpenAIStreamEvent[]} */
100
- const streamEvents = [];
101
- for await (const streamEvent of readOpenAIStreamData(reader)) {
102
- streamEvents.push(streamEvent);
103
- const partialContent =
104
- convertOpenAIStreamDataToAgentPartialContent(streamEvent);
105
- if (input.onPartialMessageContent && partialContent) {
106
- input.onPartialMessageContent(partialContent);
107
- }
108
- }
109
-
110
- const lastEvent = streamEvents.at(-1);
111
- if (lastEvent?.type !== "response.completed") {
112
- const lastEventTrimmed =
113
- lastEvent?.type === "response.failed"
114
- ? {
115
- type: lastEvent.type,
116
- response: { error: lastEvent.response.error },
117
- }
118
- : lastEvent;
119
- console.error(
120
- styleText(
121
- "yellow",
122
- `OpenAI stream did not complete: ${JSON.stringify(lastEventTrimmed)}. Retry in ${retryInterval} seconds...`,
123
- ),
124
- );
125
- await new Promise((resolve) => setTimeout(resolve, retryInterval * 1000));
126
- return callOpenAIModel(
127
- platformConfig,
128
- modelConfig,
129
- input,
130
- retryCount + 1,
131
- );
132
- }
133
-
134
- return {
135
- message: convertOpenAIAssistantMessageToGenericFormat(
136
- lastEvent.response.output,
137
- ),
138
- providerTokenUsage: lastEvent.response.usage,
139
- };
140
- });
141
- }
142
-
143
- /**
144
- * @param {Message[]} genericMessages
145
- * @returns {OpenAIInputItem[]}
146
- */
147
- function convertGenericMessageToOpenAIFormat(genericMessages) {
148
- /** @type {OpenAIInputItem[]} */
149
- const openAIInputItems = [];
150
- for (const genericMessage of genericMessages) {
151
- switch (genericMessage.role) {
152
- case "system": {
153
- openAIInputItems.push({
154
- role: "system",
155
- content: genericMessage.content.map((part) => ({
156
- type: "input_text",
157
- text: part.text,
158
- })),
159
- });
160
- break;
161
- }
162
- case "user": {
163
- const toolResults = genericMessage.content.filter(
164
- (part) => part.type === "tool_result",
165
- );
166
- const userContentParts = genericMessage.content.filter(
167
- (part) => part.type === "text" || part.type === "image",
168
- );
169
-
170
- // Tool Results
171
- let imageIndex = 0;
172
- for (const result of toolResults) {
173
- const toolResultContentString = result.content
174
- .map((part) => {
175
- switch (part.type) {
176
- case "text":
177
- return part.text;
178
- case "image":
179
- imageIndex += 1;
180
- return `(Image [${imageIndex}] omitted. See next message from user.)`;
181
- default:
182
- throw new Error(
183
- `Unsupported content part: ${JSON.stringify(part)}`,
184
- );
185
- }
186
- })
187
- .join("\n\n");
188
- openAIInputItems.push({
189
- type: "function_call_output",
190
- call_id: result.toolUseId,
191
- output: toolResultContentString,
192
- });
193
- }
194
-
195
- /** @type {OpenAIInputImage[]} */
196
- const imageInputs = [];
197
- for (const result of toolResults) {
198
- for (const part of result.content) {
199
- if (part.type === "image") {
200
- imageInputs.push({
201
- type: "input_image",
202
- image_url: `data:${part.mimeType};base64,${part.data}`,
203
- detail: "auto",
204
- });
205
- }
206
- }
207
- }
208
-
209
- if (imageInputs.length) {
210
- openAIInputItems.push({
211
- role: "user",
212
- content: imageInputs,
213
- });
214
- }
215
-
216
- // User Input Parts
217
- if (userContentParts.length) {
218
- openAIInputItems.push({
219
- role: "user",
220
- content: userContentParts.map((part) => {
221
- if (part.type === "text") {
222
- return { type: "input_text", text: part.text };
223
- }
224
- if (part.type === "image") {
225
- return {
226
- type: "input_image",
227
- image_url: `data:${part.mimeType};base64,${part.data}`,
228
- };
229
- }
230
- throw new Error(
231
- `Unsupported content part: ${JSON.stringify(part)}`,
232
- );
233
- }),
234
- });
235
- }
236
-
237
- break;
238
- }
239
- case "assistant": {
240
- // if (!genericMessage.provider?.source) {
241
- // throw new Error(
242
- // "Original message is required for assistant role but not provided.",
243
- // );
244
- // }
245
- // const source = /** @type {OpenAIOutputItem[]} */ (
246
- // genericMessage.provider.source
247
- // );
248
- // openAIInputItems.push(...source);
249
-
250
- for (const part of genericMessage.content) {
251
- if (part.type === "thinking") {
252
- openAIInputItems.push(
253
- /** @type {OpenAIReasoning} */ ({
254
- type: "reasoning",
255
- ...part.provider?.fields,
256
- }),
257
- );
258
- }
259
- if (part.type === "tool_use") {
260
- openAIInputItems.push(
261
- /** @type {OpenAIFunctionToolCall} */ ({
262
- type: "function_call",
263
- name: part.toolName,
264
- arguments: JSON.stringify(part.input),
265
- call_id: part.toolUseId,
266
- ...part.provider?.fields,
267
- }),
268
- );
269
- }
270
- if (part.type === "text") {
271
- const itemId = /** @type {string | undefined} */ (
272
- part.provider?.fields?.id
273
- );
274
- const item = /** @type {OpenAIOutputMessage | undefined} */ (
275
- openAIInputItems.find(
276
- (item) =>
277
- "id" in item && item.id === itemId && item.type === "message",
278
- )
279
- );
280
-
281
- if (item) {
282
- item.content.push({
283
- type: "output_text",
284
- text: part.text,
285
- });
286
- } else {
287
- openAIInputItems.push(
288
- /** @type {OpenAIOutputMessage} */ ({
289
- type: "message",
290
- role: "assistant",
291
- content: [
292
- {
293
- type: "output_text",
294
- text: part.text,
295
- },
296
- ],
297
- ...part.provider?.fields,
298
- }),
299
- );
300
- }
301
- }
302
- }
303
- }
304
- }
305
- }
306
-
307
- return openAIInputItems;
308
- }
309
-
310
- /**
311
- * @param {ToolDefinition[]} genericToolDefs
312
- * @returns {OpenAIToolFunction[]}
313
- */
314
- function convertGenericeToolDefinitionToOpenAIFormat(genericToolDefs) {
315
- /** @type {OpenAIToolFunction[]} */
316
- const openAIToolDefs = [];
317
- for (const toolDef of genericToolDefs) {
318
- openAIToolDefs.push({
319
- type: "function",
320
- name: toolDef.name,
321
- description: toolDef.description,
322
- parameters: toolDef.inputSchema,
323
- });
324
- }
325
-
326
- return openAIToolDefs;
327
- }
328
-
329
- /**
330
- * @param {OpenAIOutputItem[]} openAIOutputItems
331
- * @returns {AssistantMessage}
332
- */
333
- function convertOpenAIAssistantMessageToGenericFormat(openAIOutputItems) {
334
- /** @type {AssistantMessage["content"]} */
335
- const content = [];
336
- for (const item of openAIOutputItems) {
337
- if (item.type === "reasoning") {
338
- content.push({
339
- type: "thinking",
340
- thinking: item.summary.at(0)?.text ?? "",
341
- provider: {
342
- fields: {
343
- id: item.id,
344
- encrypted_content: item.encrypted_content,
345
- summary: item.summary,
346
- },
347
- },
348
- });
349
- }
350
-
351
- if (item.type === "message") {
352
- for (const part of item.content) {
353
- if (part.type === "output_text") {
354
- content.push({
355
- type: "text",
356
- text: part.text,
357
- provider: {
358
- fields: {
359
- id: item.id,
360
- },
361
- },
362
- });
363
- }
364
- }
365
- }
366
-
367
- if (item.type === "function_call") {
368
- content.push({
369
- type: "tool_use",
370
- toolUseId: item.call_id,
371
- toolName: item.name,
372
- input: JSON.parse(item.arguments),
373
- provider: {
374
- fields: {
375
- id: item.id,
376
- },
377
- },
378
- });
379
- }
380
- }
381
-
382
- return {
383
- role: "assistant",
384
- content,
385
-
386
- // provider: {
387
- // source: openAIOutputItems,
388
- // },
389
- };
390
- }
391
-
392
- /**
393
- * @param {OpenAIStreamEvent} streamEvent
394
- * @returns {PartialMessageContent | undefined}
395
- */
396
- function convertOpenAIStreamDataToAgentPartialContent(streamEvent) {
397
- // thinking
398
- if (streamEvent.type === "response.output_item.added") {
399
- if (streamEvent.item.type === "reasoning") {
400
- return {
401
- type: "thinking",
402
- position: "start",
403
- };
404
- }
405
- }
406
-
407
- if (streamEvent.type === "response.reasoning_summary_part.added") {
408
- return {
409
- type: "thinking",
410
- position: "delta",
411
- content: streamEvent.part.text,
412
- };
413
- }
414
-
415
- if (streamEvent.type === "response.reasoning_summary_text.delta") {
416
- return {
417
- type: "thinking",
418
- position: "delta",
419
- content: streamEvent.delta,
420
- };
421
- }
422
-
423
- if (streamEvent.type === "response.output_item.done") {
424
- if (streamEvent.item.type === "reasoning") {
425
- return {
426
- type: "thinking",
427
- position: "stop",
428
- };
429
- }
430
- }
431
-
432
- // text
433
- if (streamEvent.type === "response.content_part.added") {
434
- if (streamEvent.part.type === "output_text") {
435
- return {
436
- type: "text",
437
- position: "start",
438
- content: streamEvent.part.text,
439
- };
440
- }
441
- if (streamEvent.part.type === "refusal") {
442
- return {
443
- type: "refusal",
444
- position: "start",
445
- content: streamEvent.part.refusal,
446
- };
447
- }
448
- }
449
-
450
- if (streamEvent.type === "response.output_text.delta") {
451
- return {
452
- type: "text",
453
- position: "delta",
454
- content: streamEvent.delta,
455
- };
456
- }
457
-
458
- if (streamEvent.type === "response.content_part.done") {
459
- if (streamEvent.part.type === "output_text") {
460
- return {
461
- type: "text",
462
- position: "stop",
463
- };
464
- }
465
- if (streamEvent.part.type === "refusal") {
466
- return {
467
- type: "refusal",
468
- position: "stop",
469
- };
470
- }
471
- }
472
-
473
- // tool use
474
- if (streamEvent.type === "response.output_item.added") {
475
- if (streamEvent.item.type === "function_call") {
476
- return {
477
- type: "tool_use",
478
- position: "start",
479
- content: streamEvent.item.arguments,
480
- };
481
- }
482
- }
483
-
484
- if (streamEvent.type === "response.function_call_arguments.delta") {
485
- return {
486
- type: "tool_use",
487
- position: "delta",
488
- content: streamEvent.delta,
489
- };
490
- }
491
-
492
- if (streamEvent.type === "response.output_item.done") {
493
- if (streamEvent.item.type === "function_call") {
494
- return {
495
- type: "tool_use",
496
- position: "stop",
497
- };
498
- }
499
- }
500
- }
501
-
502
- /**
503
- * @param {ReadableStreamDefaultReader<Uint8Array>} reader
504
- */
505
- async function* readOpenAIStreamData(reader) {
506
- let buffer = new Uint8Array();
507
-
508
- while (true) {
509
- const { done, value } = await reader.read();
510
- if (done) {
511
- break;
512
- }
513
-
514
- const nextBuffer = new Uint8Array(buffer.length + value.length);
515
- nextBuffer.set(buffer);
516
- nextBuffer.set(value, buffer.length);
517
- buffer = nextBuffer;
518
-
519
- const lineFeed = "\n".charCodeAt(0);
520
- const dataEndIndices = [];
521
- for (let i = 0; i < buffer.length - 1; i++) {
522
- if (buffer[i] === lineFeed && buffer[i + 1] === lineFeed) {
523
- dataEndIndices.push(i);
524
- }
525
- }
526
-
527
- for (let i = 0; i < dataEndIndices.length; i++) {
528
- const dataStartIndex = i === 0 ? 0 : dataEndIndices[i - 1] + 2;
529
- const dataEndIndex = dataEndIndices[i];
530
- const data = buffer.slice(dataStartIndex, dataEndIndex);
531
- const decodedData = new TextDecoder().decode(data);
532
- if (decodedData.startsWith("event: ")) {
533
- const eventDate = decodedData.split("\n").slice(1).join("\n");
534
- /** @type {OpenAIStreamEvent} */
535
- const parsedData = JSON.parse(eventDate.slice("data: ".length));
536
- yield parsedData;
537
- }
538
- }
539
-
540
- if (dataEndIndices.length) {
541
- buffer = buffer.slice(dataEndIndices[dataEndIndices.length - 1] + 2);
542
- }
543
- }
544
- }
@@ -1,147 +0,0 @@
1
- /* Model */
2
- export type OpenAICompatibleModelConfig =
3
- | {
4
- model: string;
5
- temperature?: number;
6
- }
7
- | {
8
- model: string;
9
- reasoning_effort?: "low" | "medium" | "high";
10
- };
11
-
12
- /* Request */
13
- export type OpenAIChatCompletionRequest = {
14
- model?: string;
15
- messages: OpenAIMessage[];
16
- tools?: OpenAIToolDefinition[];
17
- stream?: boolean;
18
- temperature?: number;
19
- reasoning_effort?: "low" | "medium" | "high";
20
- stream_options?: {
21
- include_usage: boolean;
22
- };
23
- };
24
-
25
- /* Output */
26
- export type OpenAIChatCompletion = {
27
- id: string;
28
- object: string;
29
- created: number;
30
- model: string;
31
- choices: OpenIAChatCompletionChoice[];
32
- usage: OpenAIChatCompletionUsage;
33
- };
34
-
35
- export type OpenIAChatCompletionChoice = {
36
- index: number;
37
- message: OpenAIAssistantMessage;
38
- finish_reason: string;
39
- };
40
-
41
- /* Message */
42
- export type OpenAIMessage =
43
- | OpenAISystemMessage
44
- | OpenAIUserMessage
45
- | OpenAIAssistantMessage
46
- | OpenAIToolMessage;
47
-
48
- export type OpenAISystemMessage = {
49
- role: "system";
50
- content: OpenAIMessageContentText[];
51
- };
52
-
53
- export type OpenAIUserMessage = {
54
- role: "user";
55
- content: (OpenAIMessageContentText | OpenAIMessageContentImage)[];
56
- };
57
-
58
- export type OpenAIAssistantMessage = {
59
- role: "assistant";
60
- reasoning_content?: string;
61
- content?: string;
62
- tool_calls?: OpenAIMessageToolCall[];
63
- };
64
-
65
- export type OpenAIToolMessage = {
66
- role: "tool";
67
- content: string;
68
- tool_call_id: string;
69
- };
70
-
71
- export type OpenAIMessageContentText = {
72
- type: "text";
73
- text: string;
74
- };
75
-
76
- export type OpenAIMessageContentImage = {
77
- type: "image_url";
78
- image_url: {
79
- url: string;
80
- };
81
- };
82
-
83
- export type OpenAIMessageToolCall = {
84
- id: string;
85
- type: "function";
86
- function: OpenAIToolCallFunction;
87
- };
88
-
89
- export type OpenAIToolCallFunction = {
90
- name: string;
91
- arguments: string;
92
- };
93
-
94
- /* Usage */
95
- export type OpenAIChatCompletionUsage = {
96
- prompt_tokens: number;
97
- completion_tokens: number;
98
- total_tokens: number;
99
- prompt_tokens_details: Record<string, number>;
100
- completion_tokens_details: Record<string, number>;
101
- };
102
-
103
- /* Tool */
104
- export type OpenAIToolDefinition = {
105
- type: "function";
106
- function: {
107
- name: string;
108
- description: string;
109
- parameters: Record<string, unknown>;
110
- };
111
- };
112
-
113
- /* Streaming Data */
114
- export type OpenAIStreamData = {
115
- id: string;
116
- object: string;
117
- created: number;
118
- model: string;
119
- service_tier?: string;
120
- system_fingerprint?: string;
121
- choices: OpenAIStreamDataChoice[];
122
- usage?: OpenAIChatCompletionUsage;
123
- };
124
-
125
- export type OpenAIStreamDataChoice = {
126
- index: number;
127
- delta: OpenAIStreamDataDelta;
128
- finish_reason: string;
129
- };
130
-
131
- export type OpenAIStreamDataDelta = {
132
- role?: "assistant";
133
- reasoning_content?: string;
134
- content?: string;
135
- refusal?: unknown;
136
- tool_calls?: OpenAIStreamDataToolCall[];
137
- };
138
-
139
- export type OpenAIStreamDataToolCall = {
140
- index: number;
141
- id?: string;
142
- type?: string;
143
- function?: {
144
- name?: string;
145
- arguments: string;
146
- };
147
- };