@llumiverse/drivers 0.24.0 → 0.25.0-dev.20260204.110528Z

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 (224) hide show
  1. package/package.json +3 -3
  2. package/lib/cjs/adobe/firefly.js +0 -120
  3. package/lib/cjs/adobe/firefly.js.map +0 -1
  4. package/lib/cjs/azure/azure_foundry.js +0 -432
  5. package/lib/cjs/azure/azure_foundry.js.map +0 -1
  6. package/lib/cjs/bedrock/converse.js +0 -285
  7. package/lib/cjs/bedrock/converse.js.map +0 -1
  8. package/lib/cjs/bedrock/index.js +0 -1091
  9. package/lib/cjs/bedrock/index.js.map +0 -1
  10. package/lib/cjs/bedrock/nova-image-payload.js +0 -207
  11. package/lib/cjs/bedrock/nova-image-payload.js.map +0 -1
  12. package/lib/cjs/bedrock/payloads.js +0 -3
  13. package/lib/cjs/bedrock/payloads.js.map +0 -1
  14. package/lib/cjs/bedrock/s3.js +0 -107
  15. package/lib/cjs/bedrock/s3.js.map +0 -1
  16. package/lib/cjs/bedrock/twelvelabs.js +0 -87
  17. package/lib/cjs/bedrock/twelvelabs.js.map +0 -1
  18. package/lib/cjs/groq/index.js +0 -323
  19. package/lib/cjs/groq/index.js.map +0 -1
  20. package/lib/cjs/huggingface_ie.js +0 -201
  21. package/lib/cjs/huggingface_ie.js.map +0 -1
  22. package/lib/cjs/index.js +0 -31
  23. package/lib/cjs/index.js.map +0 -1
  24. package/lib/cjs/mistral/index.js +0 -173
  25. package/lib/cjs/mistral/index.js.map +0 -1
  26. package/lib/cjs/mistral/types.js +0 -83
  27. package/lib/cjs/mistral/types.js.map +0 -1
  28. package/lib/cjs/openai/azure_openai.js +0 -72
  29. package/lib/cjs/openai/azure_openai.js.map +0 -1
  30. package/lib/cjs/openai/index.js +0 -665
  31. package/lib/cjs/openai/index.js.map +0 -1
  32. package/lib/cjs/openai/openai.js +0 -21
  33. package/lib/cjs/openai/openai.js.map +0 -1
  34. package/lib/cjs/openai/openai_compatible.js +0 -62
  35. package/lib/cjs/openai/openai_compatible.js.map +0 -1
  36. package/lib/cjs/openai/openai_format.js +0 -131
  37. package/lib/cjs/openai/openai_format.js.map +0 -1
  38. package/lib/cjs/package.json +0 -3
  39. package/lib/cjs/replicate.js +0 -275
  40. package/lib/cjs/replicate.js.map +0 -1
  41. package/lib/cjs/test-driver/TestErrorCompletionStream.js +0 -20
  42. package/lib/cjs/test-driver/TestErrorCompletionStream.js.map +0 -1
  43. package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js +0 -24
  44. package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js.map +0 -1
  45. package/lib/cjs/test-driver/index.js +0 -109
  46. package/lib/cjs/test-driver/index.js.map +0 -1
  47. package/lib/cjs/test-driver/utils.js +0 -30
  48. package/lib/cjs/test-driver/utils.js.map +0 -1
  49. package/lib/cjs/togetherai/index.js +0 -126
  50. package/lib/cjs/togetherai/index.js.map +0 -1
  51. package/lib/cjs/togetherai/interfaces.js +0 -3
  52. package/lib/cjs/togetherai/interfaces.js.map +0 -1
  53. package/lib/cjs/vertexai/debug.js +0 -12
  54. package/lib/cjs/vertexai/debug.js.map +0 -1
  55. package/lib/cjs/vertexai/embeddings/embeddings-image.js +0 -27
  56. package/lib/cjs/vertexai/embeddings/embeddings-image.js.map +0 -1
  57. package/lib/cjs/vertexai/embeddings/embeddings-text.js +0 -23
  58. package/lib/cjs/vertexai/embeddings/embeddings-text.js.map +0 -1
  59. package/lib/cjs/vertexai/index.js +0 -576
  60. package/lib/cjs/vertexai/index.js.map +0 -1
  61. package/lib/cjs/vertexai/models/claude.js +0 -485
  62. package/lib/cjs/vertexai/models/claude.js.map +0 -1
  63. package/lib/cjs/vertexai/models/gemini.js +0 -871
  64. package/lib/cjs/vertexai/models/gemini.js.map +0 -1
  65. package/lib/cjs/vertexai/models/imagen.js +0 -303
  66. package/lib/cjs/vertexai/models/imagen.js.map +0 -1
  67. package/lib/cjs/vertexai/models/llama.js +0 -183
  68. package/lib/cjs/vertexai/models/llama.js.map +0 -1
  69. package/lib/cjs/vertexai/models.js +0 -35
  70. package/lib/cjs/vertexai/models.js.map +0 -1
  71. package/lib/cjs/watsonx/index.js +0 -161
  72. package/lib/cjs/watsonx/index.js.map +0 -1
  73. package/lib/cjs/watsonx/interfaces.js +0 -3
  74. package/lib/cjs/watsonx/interfaces.js.map +0 -1
  75. package/lib/cjs/xai/index.js +0 -65
  76. package/lib/cjs/xai/index.js.map +0 -1
  77. package/lib/esm/adobe/firefly.js +0 -116
  78. package/lib/esm/adobe/firefly.js.map +0 -1
  79. package/lib/esm/azure/azure_foundry.js +0 -426
  80. package/lib/esm/azure/azure_foundry.js.map +0 -1
  81. package/lib/esm/bedrock/converse.js +0 -278
  82. package/lib/esm/bedrock/converse.js.map +0 -1
  83. package/lib/esm/bedrock/index.js +0 -1087
  84. package/lib/esm/bedrock/index.js.map +0 -1
  85. package/lib/esm/bedrock/nova-image-payload.js +0 -203
  86. package/lib/esm/bedrock/nova-image-payload.js.map +0 -1
  87. package/lib/esm/bedrock/payloads.js +0 -2
  88. package/lib/esm/bedrock/payloads.js.map +0 -1
  89. package/lib/esm/bedrock/s3.js +0 -99
  90. package/lib/esm/bedrock/s3.js.map +0 -1
  91. package/lib/esm/bedrock/twelvelabs.js +0 -84
  92. package/lib/esm/bedrock/twelvelabs.js.map +0 -1
  93. package/lib/esm/groq/index.js +0 -316
  94. package/lib/esm/groq/index.js.map +0 -1
  95. package/lib/esm/huggingface_ie.js +0 -197
  96. package/lib/esm/huggingface_ie.js.map +0 -1
  97. package/lib/esm/index.js +0 -15
  98. package/lib/esm/index.js.map +0 -1
  99. package/lib/esm/mistral/index.js +0 -169
  100. package/lib/esm/mistral/index.js.map +0 -1
  101. package/lib/esm/mistral/types.js +0 -80
  102. package/lib/esm/mistral/types.js.map +0 -1
  103. package/lib/esm/openai/azure_openai.js +0 -68
  104. package/lib/esm/openai/azure_openai.js.map +0 -1
  105. package/lib/esm/openai/index.js +0 -660
  106. package/lib/esm/openai/index.js.map +0 -1
  107. package/lib/esm/openai/openai.js +0 -14
  108. package/lib/esm/openai/openai.js.map +0 -1
  109. package/lib/esm/openai/openai_compatible.js +0 -55
  110. package/lib/esm/openai/openai_compatible.js.map +0 -1
  111. package/lib/esm/openai/openai_format.js +0 -127
  112. package/lib/esm/openai/openai_format.js.map +0 -1
  113. package/lib/esm/replicate.js +0 -268
  114. package/lib/esm/replicate.js.map +0 -1
  115. package/lib/esm/test-driver/TestErrorCompletionStream.js +0 -16
  116. package/lib/esm/test-driver/TestErrorCompletionStream.js.map +0 -1
  117. package/lib/esm/test-driver/TestValidationErrorCompletionStream.js +0 -20
  118. package/lib/esm/test-driver/TestValidationErrorCompletionStream.js.map +0 -1
  119. package/lib/esm/test-driver/index.js +0 -91
  120. package/lib/esm/test-driver/index.js.map +0 -1
  121. package/lib/esm/test-driver/utils.js +0 -25
  122. package/lib/esm/test-driver/utils.js.map +0 -1
  123. package/lib/esm/togetherai/index.js +0 -122
  124. package/lib/esm/togetherai/index.js.map +0 -1
  125. package/lib/esm/togetherai/interfaces.js +0 -2
  126. package/lib/esm/togetherai/interfaces.js.map +0 -1
  127. package/lib/esm/vertexai/debug.js +0 -6
  128. package/lib/esm/vertexai/debug.js.map +0 -1
  129. package/lib/esm/vertexai/embeddings/embeddings-image.js +0 -24
  130. package/lib/esm/vertexai/embeddings/embeddings-image.js.map +0 -1
  131. package/lib/esm/vertexai/embeddings/embeddings-text.js +0 -20
  132. package/lib/esm/vertexai/embeddings/embeddings-text.js.map +0 -1
  133. package/lib/esm/vertexai/index.js +0 -571
  134. package/lib/esm/vertexai/index.js.map +0 -1
  135. package/lib/esm/vertexai/models/claude.js +0 -479
  136. package/lib/esm/vertexai/models/claude.js.map +0 -1
  137. package/lib/esm/vertexai/models/gemini.js +0 -866
  138. package/lib/esm/vertexai/models/gemini.js.map +0 -1
  139. package/lib/esm/vertexai/models/imagen.js +0 -299
  140. package/lib/esm/vertexai/models/imagen.js.map +0 -1
  141. package/lib/esm/vertexai/models/llama.js +0 -179
  142. package/lib/esm/vertexai/models/llama.js.map +0 -1
  143. package/lib/esm/vertexai/models.js +0 -32
  144. package/lib/esm/vertexai/models.js.map +0 -1
  145. package/lib/esm/watsonx/index.js +0 -157
  146. package/lib/esm/watsonx/index.js.map +0 -1
  147. package/lib/esm/watsonx/interfaces.js +0 -2
  148. package/lib/esm/watsonx/interfaces.js.map +0 -1
  149. package/lib/esm/xai/index.js +0 -58
  150. package/lib/esm/xai/index.js.map +0 -1
  151. package/lib/types/adobe/firefly.d.ts +0 -30
  152. package/lib/types/adobe/firefly.d.ts.map +0 -1
  153. package/lib/types/azure/azure_foundry.d.ts +0 -52
  154. package/lib/types/azure/azure_foundry.d.ts.map +0 -1
  155. package/lib/types/bedrock/converse.d.ts +0 -9
  156. package/lib/types/bedrock/converse.d.ts.map +0 -1
  157. package/lib/types/bedrock/index.d.ts +0 -68
  158. package/lib/types/bedrock/index.d.ts.map +0 -1
  159. package/lib/types/bedrock/nova-image-payload.d.ts +0 -74
  160. package/lib/types/bedrock/nova-image-payload.d.ts.map +0 -1
  161. package/lib/types/bedrock/payloads.d.ts +0 -12
  162. package/lib/types/bedrock/payloads.d.ts.map +0 -1
  163. package/lib/types/bedrock/s3.d.ts +0 -23
  164. package/lib/types/bedrock/s3.d.ts.map +0 -1
  165. package/lib/types/bedrock/twelvelabs.d.ts +0 -50
  166. package/lib/types/bedrock/twelvelabs.d.ts.map +0 -1
  167. package/lib/types/groq/index.d.ts +0 -27
  168. package/lib/types/groq/index.d.ts.map +0 -1
  169. package/lib/types/huggingface_ie.d.ts +0 -35
  170. package/lib/types/huggingface_ie.d.ts.map +0 -1
  171. package/lib/types/index.d.ts +0 -15
  172. package/lib/types/index.d.ts.map +0 -1
  173. package/lib/types/mistral/index.d.ts +0 -25
  174. package/lib/types/mistral/index.d.ts.map +0 -1
  175. package/lib/types/mistral/types.d.ts +0 -132
  176. package/lib/types/mistral/types.d.ts.map +0 -1
  177. package/lib/types/openai/azure_openai.d.ts +0 -25
  178. package/lib/types/openai/azure_openai.d.ts.map +0 -1
  179. package/lib/types/openai/index.d.ts +0 -31
  180. package/lib/types/openai/index.d.ts.map +0 -1
  181. package/lib/types/openai/openai.d.ts +0 -15
  182. package/lib/types/openai/openai.d.ts.map +0 -1
  183. package/lib/types/openai/openai_compatible.d.ts +0 -26
  184. package/lib/types/openai/openai_compatible.d.ts.map +0 -1
  185. package/lib/types/openai/openai_format.d.ts +0 -21
  186. package/lib/types/openai/openai_format.d.ts.map +0 -1
  187. package/lib/types/replicate.d.ts +0 -48
  188. package/lib/types/replicate.d.ts.map +0 -1
  189. package/lib/types/test-driver/TestErrorCompletionStream.d.ts +0 -9
  190. package/lib/types/test-driver/TestErrorCompletionStream.d.ts.map +0 -1
  191. package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts +0 -9
  192. package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts.map +0 -1
  193. package/lib/types/test-driver/index.d.ts +0 -24
  194. package/lib/types/test-driver/index.d.ts.map +0 -1
  195. package/lib/types/test-driver/utils.d.ts +0 -5
  196. package/lib/types/test-driver/utils.d.ts.map +0 -1
  197. package/lib/types/togetherai/index.d.ts +0 -23
  198. package/lib/types/togetherai/index.d.ts.map +0 -1
  199. package/lib/types/togetherai/interfaces.d.ts +0 -96
  200. package/lib/types/togetherai/interfaces.d.ts.map +0 -1
  201. package/lib/types/vertexai/debug.d.ts +0 -2
  202. package/lib/types/vertexai/debug.d.ts.map +0 -1
  203. package/lib/types/vertexai/embeddings/embeddings-image.d.ts +0 -11
  204. package/lib/types/vertexai/embeddings/embeddings-image.d.ts.map +0 -1
  205. package/lib/types/vertexai/embeddings/embeddings-text.d.ts +0 -10
  206. package/lib/types/vertexai/embeddings/embeddings-text.d.ts.map +0 -1
  207. package/lib/types/vertexai/index.d.ts +0 -65
  208. package/lib/types/vertexai/index.d.ts.map +0 -1
  209. package/lib/types/vertexai/models/claude.d.ts +0 -28
  210. package/lib/types/vertexai/models/claude.d.ts.map +0 -1
  211. package/lib/types/vertexai/models/gemini.d.ts +0 -18
  212. package/lib/types/vertexai/models/gemini.d.ts.map +0 -1
  213. package/lib/types/vertexai/models/imagen.d.ts +0 -75
  214. package/lib/types/vertexai/models/imagen.d.ts.map +0 -1
  215. package/lib/types/vertexai/models/llama.d.ts +0 -20
  216. package/lib/types/vertexai/models/llama.d.ts.map +0 -1
  217. package/lib/types/vertexai/models.d.ts +0 -15
  218. package/lib/types/vertexai/models.d.ts.map +0 -1
  219. package/lib/types/watsonx/index.d.ts +0 -27
  220. package/lib/types/watsonx/index.d.ts.map +0 -1
  221. package/lib/types/watsonx/interfaces.d.ts +0 -65
  222. package/lib/types/watsonx/interfaces.d.ts.map +0 -1
  223. package/lib/types/xai/index.d.ts +0 -18
  224. package/lib/types/xai/index.d.ts.map +0 -1
@@ -1,665 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseOpenAIDriver = void 0;
4
- exports.collectTools = collectTools;
5
- const core_1 = require("@llumiverse/core");
6
- const openai_format_js_1 = require("./openai_format.js");
7
- // Helper function to convert string to CompletionResult[]
8
- function textToCompletionResult(text) {
9
- return text ? [{ type: "text", value: text }] : [];
10
- }
11
- //TODO: Do we need a list?, replace with if statements and modernize?
12
- const supportFineTunning = new Set([
13
- "gpt-3.5-turbo-1106",
14
- "gpt-3.5-turbo-0613",
15
- "babbage-002",
16
- "davinci-002",
17
- "gpt-4-0613"
18
- ]);
19
- class BaseOpenAIDriver extends core_1.AbstractDriver {
20
- constructor(opts) {
21
- super(opts);
22
- this.formatPrompt = openai_format_js_1.formatOpenAILikeMultimodalPrompt;
23
- }
24
- extractDataFromResponse(_options, result) {
25
- const tokenInfo = mapUsage(result.usage);
26
- const tools = collectTools(result.output);
27
- const data = extractTextFromResponse(result);
28
- if (!data && !tools) {
29
- this.logger.error({ result }, "[OpenAI] Response is not valid");
30
- throw new Error("Response is not valid: no data");
31
- }
32
- return {
33
- result: textToCompletionResult(data || ''),
34
- token_usage: tokenInfo,
35
- finish_reason: responseFinishReason(result, tools),
36
- tool_use: tools,
37
- };
38
- }
39
- async requestTextCompletionStream(prompt, options) {
40
- if (options.model_options?._option_id !== "openai-text" && options.model_options?._option_id !== "openai-thinking") {
41
- this.logger.warn({ options: options.model_options }, "Invalid model options");
42
- }
43
- // Include conversation history (same as non-streaming)
44
- const conversation = updateConversation(options.conversation, prompt);
45
- const toolDefs = getToolDefinitions(options.tools);
46
- const useTools = toolDefs ? (0, core_1.supportsToolUse)(options.model, this.provider, true) : false;
47
- convertRoles(prompt, options.model);
48
- const model_options = options.model_options;
49
- insert_image_detail(prompt, model_options?.image_detail ?? "auto");
50
- let parsedSchema = undefined;
51
- let strictMode = false;
52
- if (options.result_schema && supportsSchema(options.model)) {
53
- try {
54
- parsedSchema = openAISchemaFormat(options.result_schema);
55
- strictMode = true;
56
- }
57
- catch (e) {
58
- parsedSchema = limitedSchemaFormat(options.result_schema);
59
- strictMode = false;
60
- }
61
- }
62
- const reasoning = model_options?.reasoning_effort ? { effort: model_options.reasoning_effort } : undefined;
63
- const stream = await this.service.responses.create({
64
- stream: true,
65
- model: options.model,
66
- input: conversation,
67
- reasoning,
68
- temperature: model_options?.temperature,
69
- top_p: model_options?.top_p,
70
- max_output_tokens: model_options?.max_tokens,
71
- tools: useTools ? toolDefs : undefined,
72
- text: parsedSchema ? {
73
- format: {
74
- type: "json_schema",
75
- name: "format_output",
76
- schema: parsedSchema,
77
- strict: strictMode,
78
- }
79
- } : undefined,
80
- });
81
- return mapResponseStream(stream);
82
- }
83
- async requestTextCompletion(prompt, options) {
84
- if (options.model_options?._option_id !== "openai-text" && options.model_options?._option_id !== "openai-thinking") {
85
- this.logger.warn({ options: options.model_options }, "Invalid model options");
86
- }
87
- convertRoles(prompt, options.model);
88
- const model_options = options.model_options;
89
- insert_image_detail(prompt, model_options?.image_detail ?? "auto");
90
- const toolDefs = getToolDefinitions(options.tools);
91
- const useTools = toolDefs ? (0, core_1.supportsToolUse)(options.model, this.provider) : false;
92
- let conversation = updateConversation(options.conversation, prompt);
93
- let parsedSchema = undefined;
94
- let strictMode = false;
95
- if (options.result_schema && supportsSchema(options.model)) {
96
- try {
97
- parsedSchema = openAISchemaFormat(options.result_schema);
98
- strictMode = true;
99
- }
100
- catch (e) {
101
- parsedSchema = limitedSchemaFormat(options.result_schema);
102
- strictMode = false;
103
- }
104
- }
105
- const reasoning = model_options?.reasoning_effort ? { effort: model_options.reasoning_effort } : undefined;
106
- const res = await this.service.responses.create({
107
- stream: false,
108
- model: options.model,
109
- input: conversation,
110
- reasoning,
111
- temperature: model_options?.temperature,
112
- top_p: model_options?.top_p,
113
- max_output_tokens: model_options?.max_tokens, //TODO: use max_tokens for older models, currently relying on OpenAI to handle it
114
- tools: useTools ? toolDefs : undefined,
115
- text: parsedSchema ? {
116
- format: {
117
- type: "json_schema",
118
- name: "format_output",
119
- schema: parsedSchema,
120
- strict: strictMode,
121
- }
122
- } : undefined,
123
- });
124
- const completion = this.extractDataFromResponse(options, res);
125
- if (options.include_original_response) {
126
- completion.original_response = res;
127
- }
128
- conversation = updateConversation(conversation, createAssistantMessageFromCompletion(completion));
129
- // Increment turn counter for deferred stripping
130
- conversation = (0, core_1.incrementConversationTurn)(conversation);
131
- // Strip large base64 image data based on options.stripImagesAfterTurns
132
- const currentTurn = (0, core_1.getConversationMeta)(conversation).turnNumber;
133
- const stripOptions = {
134
- keepForTurns: options.stripImagesAfterTurns ?? Infinity,
135
- currentTurn,
136
- textMaxTokens: options.stripTextMaxTokens
137
- };
138
- let processedConversation = (0, core_1.stripBase64ImagesFromConversation)(conversation, stripOptions);
139
- // Truncate large text content if configured
140
- processedConversation = (0, core_1.truncateLargeTextInConversation)(processedConversation, stripOptions);
141
- completion.conversation = processedConversation;
142
- return completion;
143
- }
144
- canStream(_options) {
145
- if (_options.model.includes("o1")
146
- && !(_options.model.includes("mini") || _options.model.includes("preview"))) {
147
- //o1 full does not support streaming
148
- //TODO: Update when OpenAI adds support for streaming, last check 16/02/2025
149
- return Promise.resolve(false);
150
- }
151
- return Promise.resolve(true);
152
- }
153
- /**
154
- * Build conversation context after streaming completion.
155
- * Reconstructs the assistant message from accumulated results and applies stripping.
156
- */
157
- buildStreamingConversation(prompt, result, toolUse, options) {
158
- // Build assistant message from accumulated CompletionResult[]
159
- const completionResults = result;
160
- const textContent = completionResultsToText(completionResults);
161
- // Start with the conversation from options or the prompt
162
- let conversation = updateConversation(options.conversation, prompt);
163
- // Add assistant message as EasyInputMessage
164
- if (textContent) {
165
- const assistantMessage = {
166
- role: 'assistant',
167
- content: textContent,
168
- };
169
- conversation = updateConversation(conversation, [assistantMessage]);
170
- }
171
- // Add function calls as separate items (Response API format)
172
- if (toolUse && toolUse.length > 0) {
173
- const functionCalls = toolUse.map(t => ({
174
- type: 'function_call',
175
- call_id: t.id,
176
- name: t.tool_name,
177
- arguments: typeof t.tool_input === 'string' ? t.tool_input : JSON.stringify(t.tool_input ?? {}),
178
- }));
179
- conversation = updateConversation(conversation, functionCalls);
180
- }
181
- // Increment turn counter
182
- conversation = (0, core_1.incrementConversationTurn)(conversation);
183
- // Apply stripping based on options
184
- const currentTurn = (0, core_1.getConversationMeta)(conversation).turnNumber;
185
- const stripOptions = {
186
- keepForTurns: options.stripImagesAfterTurns ?? Infinity,
187
- currentTurn,
188
- textMaxTokens: options.stripTextMaxTokens
189
- };
190
- let processedConversation = (0, core_1.stripBase64ImagesFromConversation)(conversation, stripOptions);
191
- processedConversation = (0, core_1.truncateLargeTextInConversation)(processedConversation, stripOptions);
192
- return processedConversation;
193
- }
194
- createTrainingPrompt(options) {
195
- if (options.model.includes("gpt")) {
196
- return super.createTrainingPrompt(options);
197
- }
198
- else {
199
- // babbage, davinci not yet implemented
200
- throw new Error("Unsupported model for training: " + options.model);
201
- }
202
- }
203
- async startTraining(dataset, options) {
204
- const url = await dataset.getURL();
205
- const file = await this.service.files.create({
206
- file: await fetch(url),
207
- purpose: "fine-tune",
208
- });
209
- const job = await this.service.fineTuning.jobs.create({
210
- training_file: file.id,
211
- model: options.model,
212
- hyperparameters: options.params
213
- });
214
- return jobInfo(job);
215
- }
216
- async cancelTraining(jobId) {
217
- const job = await this.service.fineTuning.jobs.cancel(jobId);
218
- return jobInfo(job);
219
- }
220
- async getTrainingJob(jobId) {
221
- const job = await this.service.fineTuning.jobs.retrieve(jobId);
222
- return jobInfo(job);
223
- }
224
- // ========= management API =============
225
- async validateConnection() {
226
- try {
227
- await this.service.models.list();
228
- return true;
229
- }
230
- catch (error) {
231
- return false;
232
- }
233
- }
234
- listTrainableModels() {
235
- return this._listModels((m) => supportFineTunning.has(m.id));
236
- }
237
- async listModels() {
238
- return this._listModels();
239
- }
240
- async _listModels(filter) {
241
- let result = (await this.service.models.list()).data;
242
- //Some of these use the completions API instead of the chat completions API.
243
- //Others are for non-text input modalities. Therefore common to both.
244
- const wordBlacklist = ["embed", "whisper", "transcribe", "audio", "moderation", "tts",
245
- "realtime", "dall-e", "babbage", "davinci", "codex", "o1-pro", "computer-use", "sora"];
246
- //OpenAI has very little information, filtering based on name.
247
- result = result.filter((m) => {
248
- return !wordBlacklist.some((word) => m.id.includes(word));
249
- });
250
- const models = filter ? result.filter(filter) : result;
251
- const aiModels = models.map((m) => {
252
- const modelCapability = (0, core_1.getModelCapabilities)(m.id, "openai");
253
- let owner = m.owned_by;
254
- if (owner == "system") {
255
- owner = "openai";
256
- }
257
- return {
258
- id: m.id,
259
- name: m.id,
260
- provider: this.provider,
261
- owner: owner,
262
- type: m.object === "model" ? core_1.ModelType.Text : core_1.ModelType.Unknown,
263
- can_stream: true,
264
- is_multimodal: m.id.includes("gpt-4"),
265
- input_modalities: (0, core_1.modelModalitiesToArray)(modelCapability.input),
266
- output_modalities: (0, core_1.modelModalitiesToArray)(modelCapability.output),
267
- tool_support: modelCapability.tool_support,
268
- };
269
- }).sort((a, b) => a.id.localeCompare(b.id));
270
- return aiModels;
271
- }
272
- async generateEmbeddings({ text, image, model = "text-embedding-3-small" }) {
273
- if (image) {
274
- throw new Error("Image embeddings not supported by OpenAI");
275
- }
276
- if (!text) {
277
- throw new Error("No text provided");
278
- }
279
- const res = await this.service.embeddings.create({
280
- input: text,
281
- model: model,
282
- });
283
- const embeddings = res.data[0].embedding;
284
- if (!embeddings || embeddings.length === 0) {
285
- throw new Error("No embedding found");
286
- }
287
- return { values: embeddings, model };
288
- }
289
- }
290
- exports.BaseOpenAIDriver = BaseOpenAIDriver;
291
- function jobInfo(job) {
292
- //validating_files`, `queued`, `running`, `succeeded`, `failed`, or `cancelled`.
293
- const jobStatus = job.status;
294
- let status = core_1.TrainingJobStatus.running;
295
- let details;
296
- if (jobStatus === 'succeeded') {
297
- status = core_1.TrainingJobStatus.succeeded;
298
- }
299
- else if (jobStatus === 'failed') {
300
- status = core_1.TrainingJobStatus.failed;
301
- details = job.error ? `${job.error.code} - ${job.error.message} ${job.error.param ? " [" + job.error.param + "]" : ""}` : "error";
302
- }
303
- else if (jobStatus === 'cancelled') {
304
- status = core_1.TrainingJobStatus.cancelled;
305
- }
306
- else {
307
- status = core_1.TrainingJobStatus.running;
308
- details = jobStatus;
309
- }
310
- return {
311
- id: job.id,
312
- model: job.fine_tuned_model || undefined,
313
- status,
314
- details
315
- };
316
- }
317
- function mapUsage(usage) {
318
- if (!usage) {
319
- return undefined;
320
- }
321
- return {
322
- prompt: usage.input_tokens,
323
- result: usage.output_tokens,
324
- total: usage.total_tokens,
325
- };
326
- }
327
- function completionResultsToText(completionResults) {
328
- if (!completionResults) {
329
- return '';
330
- }
331
- return completionResults
332
- .map(r => {
333
- switch (r.type) {
334
- case 'text':
335
- return r.value;
336
- case 'json':
337
- return typeof r.value === 'string' ? r.value : JSON.stringify(r.value);
338
- case 'image':
339
- // Skip images in conversation - they're in the result
340
- return '';
341
- default:
342
- return String(r.value || '');
343
- }
344
- })
345
- .join('');
346
- }
347
- function createAssistantMessageFromCompletion(completion) {
348
- const textContent = completionResultsToText(completion.result);
349
- const result = [];
350
- // Add assistant text message if present
351
- if (textContent) {
352
- const assistantMessage = {
353
- role: 'assistant',
354
- content: textContent,
355
- };
356
- result.push(assistantMessage);
357
- }
358
- // Add function calls as separate items (Response API format)
359
- if (completion.tool_use && completion.tool_use.length > 0) {
360
- for (const t of completion.tool_use) {
361
- const functionCall = {
362
- type: 'function_call',
363
- call_id: t.id,
364
- name: t.tool_name,
365
- arguments: typeof t.tool_input === 'string'
366
- ? t.tool_input
367
- : JSON.stringify(t.tool_input ?? {}),
368
- };
369
- result.push(functionCall);
370
- }
371
- }
372
- return result;
373
- }
374
- function mapResponseStream(stream) {
375
- const toolCallMetadata = new Map();
376
- return {
377
- async *[Symbol.asyncIterator]() {
378
- for await (const event of stream) {
379
- if (event.type === 'response.output_item.added' && event.item.type === 'function_call') {
380
- const syntheticId = `tool_${event.output_index}`;
381
- const actualId = event.item.id ?? event.item.call_id;
382
- if (actualId) {
383
- toolCallMetadata.set(actualId, { syntheticId, name: event.item.name });
384
- }
385
- const toolUse = {
386
- id: syntheticId,
387
- _actual_id: actualId,
388
- tool_name: event.item.name,
389
- tool_input: '',
390
- };
391
- yield {
392
- result: [],
393
- tool_use: [toolUse],
394
- };
395
- }
396
- else if (event.type === 'response.function_call_arguments.delta') {
397
- const metadata = toolCallMetadata.get(event.item_id);
398
- const syntheticId = metadata?.syntheticId ?? `tool_${event.output_index}`;
399
- const toolUse = {
400
- id: syntheticId,
401
- _actual_id: event.item_id,
402
- tool_name: metadata?.name ?? '',
403
- tool_input: event.delta,
404
- };
405
- yield {
406
- result: [],
407
- tool_use: [toolUse],
408
- };
409
- }
410
- // Note: We don't emit response.function_call_arguments.done because the arguments were already
411
- // streamed via delta events. Emitting it again would duplicate the tool_input content.
412
- // We only update the metadata to ensure the tool name is captured.
413
- else if (event.type === 'response.function_call_arguments.done') {
414
- // Just update metadata, don't yield (arguments already accumulated from delta events)
415
- const metadata = toolCallMetadata.get(event.item_id);
416
- const syntheticId = metadata?.syntheticId ?? `tool_${event.output_index}`;
417
- const tool_name = metadata?.name ?? event.name ?? '';
418
- if (event.item_id) {
419
- toolCallMetadata.set(event.item_id, { syntheticId, name: tool_name });
420
- }
421
- }
422
- else if (event.type === 'response.output_text.delta') {
423
- yield {
424
- result: textToCompletionResult(event.delta),
425
- };
426
- }
427
- // Note: We don't emit response.output_text.done because the text was already
428
- // streamed via delta events. Emitting it again would duplicate the content.
429
- else if (event.type === 'response.completed' || event.type === 'response.incomplete' || event.type === 'response.failed') {
430
- const finalTools = collectTools(event.response.output);
431
- yield {
432
- result: [],
433
- finish_reason: responseFinishReason(event.response, finalTools),
434
- token_usage: mapUsage(event.response.usage),
435
- };
436
- }
437
- }
438
- }
439
- };
440
- }
441
- function insert_image_detail(items, detail_level) {
442
- if (detail_level === "auto" || detail_level === "low" || detail_level === "high") {
443
- for (const item of items) {
444
- // Check if it's an EasyInputMessage or Message with content array
445
- if ('role' in item && 'content' in item && item.role !== 'assistant') {
446
- const content = item.content;
447
- if (Array.isArray(content)) {
448
- for (const part of content) {
449
- if (typeof part === 'object' && part.type === 'input_image') {
450
- part.detail = detail_level;
451
- }
452
- }
453
- }
454
- }
455
- }
456
- }
457
- return items;
458
- }
459
- function convertRoles(items, model) {
460
- //New openai models use developer role instead of system
461
- if (model.includes("o1") || model.includes("o3")) {
462
- if (model.includes("o1-mini") || model.includes("o1-preview")) {
463
- //o1-mini and o1-preview support neither system nor developer
464
- for (const item of items) {
465
- if ('role' in item && item.role === 'system') {
466
- item.role = 'user';
467
- }
468
- }
469
- }
470
- else {
471
- //Models newer than o1 use developer role
472
- for (const item of items) {
473
- if ('role' in item && item.role === 'system') {
474
- item.role = 'developer';
475
- }
476
- }
477
- }
478
- }
479
- return items;
480
- }
481
- //Structured output support is typically aligned with tool use support
482
- //Not true for realtime models, which do not support structured output, but do support tool use.
483
- function supportsSchema(model) {
484
- const realtimeModel = model.includes("realtime");
485
- if (realtimeModel) {
486
- return false;
487
- }
488
- return (0, core_1.supportsToolUse)(model, "openai");
489
- }
490
- function getToolDefinitions(tools) {
491
- return tools ? tools.map(getToolDefinition) : undefined;
492
- }
493
- function getToolDefinition(toolDef) {
494
- let parsedSchema = undefined;
495
- let strictMode = false;
496
- if (toolDef.input_schema) {
497
- try {
498
- parsedSchema = openAISchemaFormat(toolDef.input_schema);
499
- strictMode = true;
500
- }
501
- catch (e) {
502
- parsedSchema = limitedSchemaFormat(toolDef.input_schema);
503
- strictMode = false;
504
- }
505
- }
506
- return {
507
- type: "function",
508
- name: toolDef.name,
509
- description: toolDef.description,
510
- parameters: parsedSchema ?? null,
511
- strict: strictMode,
512
- };
513
- }
514
- function updateConversation(conversation, items) {
515
- if (!items) {
516
- // Unwrap array if wrapped, otherwise treat as array
517
- const unwrapped = (0, core_1.unwrapConversationArray)(conversation);
518
- return unwrapped ?? (conversation || []);
519
- }
520
- if (!conversation) {
521
- return items;
522
- }
523
- // Unwrap array if wrapped, otherwise treat as array
524
- const unwrapped = (0, core_1.unwrapConversationArray)(conversation);
525
- const convArray = unwrapped ?? conversation;
526
- return [...convArray, ...items];
527
- }
528
- function collectTools(output) {
529
- if (!output) {
530
- return undefined;
531
- }
532
- const tools = [];
533
- for (const item of output) {
534
- if (item.type === 'function_call') {
535
- const id = item.call_id || item.id;
536
- if (!id) {
537
- continue;
538
- }
539
- tools.push({
540
- id,
541
- tool_name: item.name ?? '',
542
- tool_input: safeJsonParse(item.arguments),
543
- });
544
- }
545
- }
546
- return tools.length > 0 ? tools : undefined;
547
- }
548
- //For strict mode false
549
- function limitedSchemaFormat(schema) {
550
- const formattedSchema = { ...schema };
551
- // Defaults not supported
552
- delete formattedSchema.default;
553
- // OpenAI requires type field even in non-strict mode
554
- // If no type is specified, default to 'object' for properties with format/editor hints,
555
- // otherwise 'string' as a safe fallback
556
- if (!formattedSchema.type && formattedSchema.description) {
557
- // Properties with format: "document" or editor hints are typically objects
558
- if (formattedSchema.format === 'document' || formattedSchema.editor) {
559
- formattedSchema.type = 'object';
560
- }
561
- else {
562
- formattedSchema.type = 'string';
563
- }
564
- }
565
- if (formattedSchema?.properties) {
566
- // Process each property recursively
567
- for (const propName of Object.keys(formattedSchema.properties)) {
568
- const property = formattedSchema.properties[propName];
569
- // Recursively process properties
570
- formattedSchema.properties[propName] = limitedSchemaFormat(property);
571
- // Process arrays with items of type object
572
- if (property?.type === 'array' && property.items && property.items?.type === 'object') {
573
- formattedSchema.properties[propName] = {
574
- ...property,
575
- items: limitedSchemaFormat(property.items),
576
- };
577
- }
578
- }
579
- }
580
- return formattedSchema;
581
- }
582
- //For strict mode true
583
- function openAISchemaFormat(schema, nesting = 0) {
584
- if (nesting > 5) {
585
- throw new Error("OpenAI schema nesting too deep");
586
- }
587
- const formattedSchema = { ...schema };
588
- // Defaults not supported
589
- delete formattedSchema.default;
590
- // Additional properties not supported, required to be set.
591
- if (formattedSchema?.type === "object") {
592
- formattedSchema.additionalProperties = false;
593
- }
594
- if (formattedSchema?.properties) {
595
- // Set all properties as required
596
- formattedSchema.required = Object.keys(formattedSchema.properties);
597
- // Process each property recursively
598
- for (const propName of Object.keys(formattedSchema.properties)) {
599
- const property = formattedSchema.properties[propName];
600
- // OpenAI strict mode requires all properties to have a type
601
- if (!property?.type) {
602
- throw new Error(`Property '${propName}' is missing required 'type' field for OpenAI strict mode`);
603
- }
604
- // Recursively process properties
605
- formattedSchema.properties[propName] = openAISchemaFormat(property, nesting + 1);
606
- // Process arrays with items of type object
607
- if (property?.type === 'array' && property.items && property.items?.type === 'object') {
608
- formattedSchema.properties[propName] = {
609
- ...property,
610
- items: openAISchemaFormat(property.items, nesting + 1),
611
- };
612
- }
613
- }
614
- }
615
- if (formattedSchema?.type === 'object' && (!formattedSchema?.properties || Object.keys(formattedSchema?.properties ?? {}).length == 0)) {
616
- //If no properties are defined, then additionalProperties: true was set or the object would be empty.
617
- //OpenAI does not support this on structured output/ strict mode.
618
- throw new Error("OpenAI does not support empty objects or objects with additionalProperties set to true");
619
- }
620
- return formattedSchema;
621
- }
622
- function extractTextFromResponse(response) {
623
- if (response.output_text) {
624
- return response.output_text;
625
- }
626
- const collected = [];
627
- for (const item of response.output ?? []) {
628
- if (item.type === 'message') {
629
- const text = item.content
630
- .map(part => part.type === 'output_text' ? part.text : '')
631
- .join('');
632
- if (text) {
633
- collected.push(text);
634
- }
635
- }
636
- }
637
- return collected.join("\n");
638
- }
639
- function responseFinishReason(response, tools) {
640
- if (tools && tools.length > 0) {
641
- return "tool_use";
642
- }
643
- if (response.status === 'incomplete') {
644
- if (response.incomplete_details?.reason === 'max_output_tokens') {
645
- return 'length';
646
- }
647
- return response.incomplete_details?.reason ?? 'incomplete';
648
- }
649
- if (response.status && response.status !== 'completed') {
650
- return response.status;
651
- }
652
- return 'stop';
653
- }
654
- function safeJsonParse(value) {
655
- if (typeof value !== 'string') {
656
- return value;
657
- }
658
- try {
659
- return JSON.parse(value);
660
- }
661
- catch {
662
- return value;
663
- }
664
- }
665
- //# sourceMappingURL=index.js.map