@workglow/ai 0.0.126 → 0.1.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 (135) hide show
  1. package/README.md +214 -47
  2. package/dist/browser.js +569 -1274
  3. package/dist/browser.js.map +56 -61
  4. package/dist/bun.js +569 -1274
  5. package/dist/bun.js.map +56 -61
  6. package/dist/common.d.ts +3 -1
  7. package/dist/common.d.ts.map +1 -1
  8. package/dist/execution/DirectExecutionStrategy.d.ts +20 -0
  9. package/dist/execution/DirectExecutionStrategy.d.ts.map +1 -0
  10. package/dist/execution/IAiExecutionStrategy.d.ts +33 -0
  11. package/dist/execution/IAiExecutionStrategy.d.ts.map +1 -0
  12. package/dist/execution/QueuedExecutionStrategy.d.ts +50 -0
  13. package/dist/execution/QueuedExecutionStrategy.d.ts.map +1 -0
  14. package/dist/job/AiJob.d.ts +6 -0
  15. package/dist/job/AiJob.d.ts.map +1 -1
  16. package/dist/node.js +569 -1274
  17. package/dist/node.js.map +56 -61
  18. package/dist/provider/AiProvider.d.ts +16 -2
  19. package/dist/provider/AiProvider.d.ts.map +1 -1
  20. package/dist/provider/AiProviderRegistry.d.ts +20 -0
  21. package/dist/provider/AiProviderRegistry.d.ts.map +1 -1
  22. package/dist/provider/QueuedAiProvider.d.ts +23 -2
  23. package/dist/provider/QueuedAiProvider.d.ts.map +1 -1
  24. package/dist/task/BackgroundRemovalTask.d.ts +3 -3
  25. package/dist/task/BackgroundRemovalTask.d.ts.map +1 -1
  26. package/dist/task/ChunkRetrievalTask.d.ts +4 -4
  27. package/dist/task/ChunkRetrievalTask.d.ts.map +1 -1
  28. package/dist/task/ChunkToVectorTask.d.ts +4 -4
  29. package/dist/task/ChunkToVectorTask.d.ts.map +1 -1
  30. package/dist/task/ChunkVectorHybridSearchTask.d.ts +4 -4
  31. package/dist/task/ChunkVectorHybridSearchTask.d.ts.map +1 -1
  32. package/dist/task/ChunkVectorSearchTask.d.ts +4 -4
  33. package/dist/task/ChunkVectorSearchTask.d.ts.map +1 -1
  34. package/dist/task/ChunkVectorUpsertTask.d.ts +4 -4
  35. package/dist/task/ChunkVectorUpsertTask.d.ts.map +1 -1
  36. package/dist/task/ContextBuilderTask.d.ts +4 -4
  37. package/dist/task/ContextBuilderTask.d.ts.map +1 -1
  38. package/dist/task/CountTokensTask.d.ts +11 -29
  39. package/dist/task/CountTokensTask.d.ts.map +1 -1
  40. package/dist/task/DocumentEnricherTask.d.ts +4 -4
  41. package/dist/task/DocumentEnricherTask.d.ts.map +1 -1
  42. package/dist/task/DownloadModelTask.d.ts +5 -5
  43. package/dist/task/DownloadModelTask.d.ts.map +1 -1
  44. package/dist/task/FaceDetectorTask.d.ts +4 -4
  45. package/dist/task/FaceDetectorTask.d.ts.map +1 -1
  46. package/dist/task/FaceLandmarkerTask.d.ts +4 -4
  47. package/dist/task/FaceLandmarkerTask.d.ts.map +1 -1
  48. package/dist/task/GestureRecognizerTask.d.ts +4 -4
  49. package/dist/task/GestureRecognizerTask.d.ts.map +1 -1
  50. package/dist/task/HandLandmarkerTask.d.ts +4 -4
  51. package/dist/task/HandLandmarkerTask.d.ts.map +1 -1
  52. package/dist/task/HierarchicalChunkerTask.d.ts +4 -4
  53. package/dist/task/HierarchicalChunkerTask.d.ts.map +1 -1
  54. package/dist/task/HierarchyJoinTask.d.ts +4 -4
  55. package/dist/task/HierarchyJoinTask.d.ts.map +1 -1
  56. package/dist/task/ImageClassificationTask.d.ts +4 -4
  57. package/dist/task/ImageClassificationTask.d.ts.map +1 -1
  58. package/dist/task/ImageEmbeddingTask.d.ts +203 -89
  59. package/dist/task/ImageEmbeddingTask.d.ts.map +1 -1
  60. package/dist/task/ImageSegmentationTask.d.ts +4 -4
  61. package/dist/task/ImageSegmentationTask.d.ts.map +1 -1
  62. package/dist/task/ImageToTextTask.d.ts +4 -4
  63. package/dist/task/ImageToTextTask.d.ts.map +1 -1
  64. package/dist/task/ModelInfoTask.d.ts +5 -5
  65. package/dist/task/ModelInfoTask.d.ts.map +1 -1
  66. package/dist/task/ModelSearchTask.d.ts.map +1 -1
  67. package/dist/task/ObjectDetectionTask.d.ts +4 -4
  68. package/dist/task/ObjectDetectionTask.d.ts.map +1 -1
  69. package/dist/task/PoseLandmarkerTask.d.ts +4 -4
  70. package/dist/task/PoseLandmarkerTask.d.ts.map +1 -1
  71. package/dist/task/QueryExpanderTask.d.ts +4 -4
  72. package/dist/task/QueryExpanderTask.d.ts.map +1 -1
  73. package/dist/task/RerankerTask.d.ts +4 -4
  74. package/dist/task/RerankerTask.d.ts.map +1 -1
  75. package/dist/task/StructuralParserTask.d.ts +4 -4
  76. package/dist/task/StructuralParserTask.d.ts.map +1 -1
  77. package/dist/task/StructuredGenerationTask.d.ts +4 -4
  78. package/dist/task/StructuredGenerationTask.d.ts.map +1 -1
  79. package/dist/task/TextChunkerTask.d.ts +4 -4
  80. package/dist/task/TextChunkerTask.d.ts.map +1 -1
  81. package/dist/task/TextClassificationTask.d.ts +24 -62
  82. package/dist/task/TextClassificationTask.d.ts.map +1 -1
  83. package/dist/task/TextEmbeddingTask.d.ts +3 -3
  84. package/dist/task/TextEmbeddingTask.d.ts.map +1 -1
  85. package/dist/task/TextFillMaskTask.d.ts +29 -73
  86. package/dist/task/TextFillMaskTask.d.ts.map +1 -1
  87. package/dist/task/TextGenerationTask.d.ts +13 -32
  88. package/dist/task/TextGenerationTask.d.ts.map +1 -1
  89. package/dist/task/TextLanguageDetectionTask.d.ts +24 -62
  90. package/dist/task/TextLanguageDetectionTask.d.ts.map +1 -1
  91. package/dist/task/TextNamedEntityRecognitionTask.d.ts +29 -73
  92. package/dist/task/TextNamedEntityRecognitionTask.d.ts.map +1 -1
  93. package/dist/task/TextQuestionAnswerTask.d.ts +17 -45
  94. package/dist/task/TextQuestionAnswerTask.d.ts.map +1 -1
  95. package/dist/task/TextRewriterTask.d.ts +12 -31
  96. package/dist/task/TextRewriterTask.d.ts.map +1 -1
  97. package/dist/task/TextSummaryTask.d.ts +12 -31
  98. package/dist/task/TextSummaryTask.d.ts.map +1 -1
  99. package/dist/task/TextTranslationTask.d.ts +12 -31
  100. package/dist/task/TextTranslationTask.d.ts.map +1 -1
  101. package/dist/task/TopicSegmenterTask.d.ts +4 -4
  102. package/dist/task/TopicSegmenterTask.d.ts.map +1 -1
  103. package/dist/task/UnloadModelTask.d.ts +4 -4
  104. package/dist/task/UnloadModelTask.d.ts.map +1 -1
  105. package/dist/task/VectorQuantizeTask.d.ts +4 -4
  106. package/dist/task/VectorQuantizeTask.d.ts.map +1 -1
  107. package/dist/task/VectorSimilarityTask.d.ts +4 -4
  108. package/dist/task/VectorSimilarityTask.d.ts.map +1 -1
  109. package/dist/task/base/AiTask.d.ts +12 -31
  110. package/dist/task/base/AiTask.d.ts.map +1 -1
  111. package/dist/task/base/AiVisionTask.d.ts +7 -12
  112. package/dist/task/base/AiVisionTask.d.ts.map +1 -1
  113. package/dist/task/base/StreamingAiTask.d.ts +7 -4
  114. package/dist/task/base/StreamingAiTask.d.ts.map +1 -1
  115. package/dist/task/index.d.ts +1 -13
  116. package/dist/task/index.d.ts.map +1 -1
  117. package/dist/worker.d.ts +0 -2
  118. package/dist/worker.d.ts.map +1 -1
  119. package/dist/worker.js +220 -233
  120. package/dist/worker.js.map +7 -7
  121. package/package.json +11 -11
  122. package/dist/queue/createDefaultQueue.d.ts +0 -17
  123. package/dist/queue/createDefaultQueue.d.ts.map +0 -1
  124. package/dist/task/AgentTask.d.ts +0 -524
  125. package/dist/task/AgentTask.d.ts.map +0 -1
  126. package/dist/task/AgentTypes.d.ts +0 -181
  127. package/dist/task/AgentTypes.d.ts.map +0 -1
  128. package/dist/task/AgentUtils.d.ts +0 -50
  129. package/dist/task/AgentUtils.d.ts.map +0 -1
  130. package/dist/task/MessageConversion.d.ts +0 -52
  131. package/dist/task/MessageConversion.d.ts.map +0 -1
  132. package/dist/task/ToolCallingTask.d.ts +0 -385
  133. package/dist/task/ToolCallingTask.d.ts.map +0 -1
  134. package/dist/task/ToolCallingUtils.d.ts +0 -65
  135. package/dist/task/ToolCallingUtils.d.ts.map +0 -1
package/dist/worker.js CHANGED
@@ -7,14 +7,199 @@ import {
7
7
  // src/provider/AiProviderRegistry.ts
8
8
  import { globalServiceRegistry, WORKER_MANAGER } from "@workglow/util/worker";
9
9
 
10
+ // src/job/AiJob.ts
11
+ import {
12
+ AbortSignalJobError,
13
+ Job,
14
+ JobStatus,
15
+ PermanentJobError,
16
+ RetryableJobError
17
+ } from "@workglow/job-queue";
18
+ import { getLogger } from "@workglow/util/worker";
19
+ var DEFAULT_AI_TIMEOUT_MS = 120000;
20
+ var LOCAL_MODEL_DEFAULT_TIMEOUT_MS = 600000;
21
+ function resolveAiJobTimeoutMs(aiProvider, explicitMs) {
22
+ if (explicitMs !== undefined) {
23
+ return explicitMs;
24
+ }
25
+ if (aiProvider === "LOCAL_LLAMACPP") {
26
+ return LOCAL_MODEL_DEFAULT_TIMEOUT_MS;
27
+ }
28
+ if (aiProvider === "HF_TRANSFORMERS_ONNX" || aiProvider.startsWith("HF_TRANSFORMERS_ONNX")) {
29
+ return LOCAL_MODEL_DEFAULT_TIMEOUT_MS;
30
+ }
31
+ return DEFAULT_AI_TIMEOUT_MS;
32
+ }
33
+ function classifyProviderError(err, taskType, provider) {
34
+ if (err instanceof PermanentJobError || err instanceof RetryableJobError || err instanceof AbortSignalJobError) {
35
+ return err;
36
+ }
37
+ const message = err instanceof Error ? err.message : String(err);
38
+ const status = typeof err?.status === "number" ? err.status : typeof err?.statusCode === "number" ? err.statusCode : (() => {
39
+ const m = message.match(/\b([45]\d{2})\b/);
40
+ return m ? parseInt(m[1], 10) : undefined;
41
+ })();
42
+ if (err instanceof DOMException && err.name === "AbortError") {
43
+ return new AbortSignalJobError(`Provider call aborted for ${taskType} (${provider})`);
44
+ }
45
+ if (err instanceof DOMException && err.name === "TimeoutError") {
46
+ return new AbortSignalJobError(`Provider call timed out for ${taskType} (${provider})`);
47
+ }
48
+ if (message.includes("Pipeline download aborted") || message.includes("Operation aborted") || message.includes("operation was aborted") || message.includes("The operation was aborted")) {
49
+ return new AbortSignalJobError(`Provider call aborted for ${taskType} (${provider}): ${message}`);
50
+ }
51
+ if (message.startsWith("HFT_NULL_PROCESSOR:")) {
52
+ return new RetryableJobError(message);
53
+ }
54
+ if (status === 429) {
55
+ const retryAfterMatch = message.match(/retry.after[:\s]*(\d+)/i);
56
+ const retryMs = retryAfterMatch ? parseInt(retryAfterMatch[1], 10) * 1000 : 30000;
57
+ return new RetryableJobError(`Rate limited by ${provider} for ${taskType}: ${message}`, new Date(Date.now() + retryMs));
58
+ }
59
+ if (status === 401 || status === 403) {
60
+ return new PermanentJobError(`Authentication failed for ${provider} (${taskType}): ${message}`);
61
+ }
62
+ if (status === 400 || status === 404) {
63
+ return new PermanentJobError(`Invalid request to ${provider} for ${taskType}: ${message}`);
64
+ }
65
+ if (status && status >= 500) {
66
+ return new RetryableJobError(`Server error from ${provider} for ${taskType} (HTTP ${status}): ${message}`);
67
+ }
68
+ if (message.includes("ECONNREFUSED") || message.includes("ECONNRESET") || message.includes("ETIMEDOUT") || message.includes("fetch failed") || message.includes("network") || err instanceof TypeError && message.includes("fetch")) {
69
+ return new RetryableJobError(`Network error calling ${provider} for ${taskType}: ${message}`);
70
+ }
71
+ if (message.includes("timed out") || message.includes("timeout")) {
72
+ return new RetryableJobError(`Timeout calling ${provider} for ${taskType}: ${message}`);
73
+ }
74
+ return new PermanentJobError(`Provider ${provider} failed for ${taskType}: ${message}`);
75
+ }
76
+
77
+ class AiJob extends Job {
78
+ async execute(input, context) {
79
+ if (context.signal.aborted || this.status === JobStatus.ABORTING) {
80
+ throw new AbortSignalJobError("Abort signal aborted before execution of job");
81
+ }
82
+ let abortHandler;
83
+ try {
84
+ const abortPromise = new Promise((_resolve, reject) => {
85
+ const handler = () => {
86
+ reject(new AbortSignalJobError("Abort signal seen, ending job"));
87
+ };
88
+ context.signal.addEventListener("abort", handler, { once: true });
89
+ abortHandler = () => context.signal.removeEventListener("abort", handler);
90
+ });
91
+ const runFn = async () => {
92
+ const fn = getAiProviderRegistry().getDirectRunFn(input.aiProvider, input.taskType);
93
+ const model = input.taskInput.model;
94
+ if (context.signal.aborted) {
95
+ throw new AbortSignalJobError("Job aborted");
96
+ }
97
+ const timeoutMs = resolveAiJobTimeoutMs(input.aiProvider, input.timeoutMs);
98
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
99
+ const combinedSignal = AbortSignal.any([context.signal, timeoutSignal]);
100
+ return await fn(input.taskInput, model, context.updateProgress, combinedSignal, input.outputSchema);
101
+ };
102
+ const runFnPromise = runFn();
103
+ return await Promise.race([runFnPromise, abortPromise]);
104
+ } catch (err) {
105
+ throw classifyProviderError(err, input.taskType, input.aiProvider);
106
+ } finally {
107
+ if (abortHandler) {
108
+ abortHandler();
109
+ }
110
+ }
111
+ }
112
+ async* executeStream(input, context) {
113
+ if (context.signal.aborted || this.status === JobStatus.ABORTING) {
114
+ throw new AbortSignalJobError("Abort signal aborted before streaming execution of job");
115
+ }
116
+ const streamFn = getAiProviderRegistry().getStreamFn(input.aiProvider, input.taskType);
117
+ if (!streamFn) {
118
+ const result = await this.execute(input, context);
119
+ yield { type: "finish", data: result };
120
+ return;
121
+ }
122
+ const model = input.taskInput.model;
123
+ let lastFinishData;
124
+ const timeoutMs = resolveAiJobTimeoutMs(input.aiProvider, input.timeoutMs);
125
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
126
+ const combinedSignal = AbortSignal.any([context.signal, timeoutSignal]);
127
+ try {
128
+ for await (const event of streamFn(input.taskInput, model, combinedSignal, input.outputSchema)) {
129
+ if (event.type === "finish") {
130
+ lastFinishData = event.data;
131
+ }
132
+ yield event;
133
+ }
134
+ } catch (err) {
135
+ const logger = getLogger();
136
+ logger.warn(`AiJob: Stream error for ${input.taskType} (${input.aiProvider}): ${err instanceof Error ? err.message : String(err)}`);
137
+ if (lastFinishData === undefined) {
138
+ yield { type: "finish", data: {} };
139
+ }
140
+ throw classifyProviderError(err, input.taskType, input.aiProvider);
141
+ }
142
+ }
143
+ }
144
+
145
+ // src/execution/DirectExecutionStrategy.ts
146
+ class DirectExecutionStrategy {
147
+ async execute(jobInput, context, runnerId) {
148
+ const job = new AiJob({
149
+ queueName: jobInput.aiProvider,
150
+ jobRunId: runnerId,
151
+ input: jobInput
152
+ });
153
+ const cleanup = job.onJobProgress((progress, message, details) => {
154
+ context.updateProgress(progress, message, details);
155
+ });
156
+ try {
157
+ return await job.execute(jobInput, {
158
+ signal: context.signal,
159
+ updateProgress: context.updateProgress
160
+ });
161
+ } finally {
162
+ cleanup();
163
+ }
164
+ }
165
+ async* executeStream(jobInput, context, runnerId) {
166
+ const job = new AiJob({
167
+ queueName: jobInput.aiProvider,
168
+ jobRunId: runnerId,
169
+ input: jobInput
170
+ });
171
+ yield* job.executeStream(jobInput, {
172
+ signal: context.signal,
173
+ updateProgress: context.updateProgress
174
+ });
175
+ }
176
+ abort() {}
177
+ }
178
+
179
+ // src/provider/AiProviderRegistry.ts
10
180
  class AiProviderRegistry {
11
181
  runFnRegistry = new Map;
12
182
  streamFnRegistry = new Map;
13
183
  reactiveRunFnRegistry = new Map;
14
184
  providers = new Map;
185
+ strategyResolvers = new Map;
186
+ defaultStrategy;
15
187
  registerProvider(provider) {
16
188
  this.providers.set(provider.name, provider);
17
189
  }
190
+ unregisterProvider(name) {
191
+ this.providers.delete(name);
192
+ this.strategyResolvers.delete(name);
193
+ for (const [, providerMap] of this.runFnRegistry) {
194
+ providerMap.delete(name);
195
+ }
196
+ for (const [, providerMap] of this.streamFnRegistry) {
197
+ providerMap.delete(name);
198
+ }
199
+ for (const [, providerMap] of this.reactiveRunFnRegistry) {
200
+ providerMap.delete(name);
201
+ }
202
+ }
18
203
  getProvider(name) {
19
204
  return this.providers.get(name);
20
205
  }
@@ -24,6 +209,18 @@ class AiProviderRegistry {
24
209
  getInstalledProviderIds() {
25
210
  return [...this.providers.keys()].sort();
26
211
  }
212
+ registerStrategyResolver(providerName, resolver) {
213
+ this.strategyResolvers.set(providerName, resolver);
214
+ }
215
+ getStrategy(model) {
216
+ const resolver = this.strategyResolvers.get(model.provider);
217
+ if (resolver)
218
+ return resolver(model);
219
+ if (!this.defaultStrategy) {
220
+ this.defaultStrategy = new DirectExecutionStrategy;
221
+ }
222
+ return this.defaultStrategy;
223
+ }
27
224
  getProviderIdsForTask(taskType) {
28
225
  const taskMap = this.runFnRegistry.get(taskType);
29
226
  if (!taskMap)
@@ -89,15 +286,16 @@ class AiProviderRegistry {
89
286
  const taskTypeMap = this.runFnRegistry.get(taskType);
90
287
  const runFn = taskTypeMap?.get(modelProvider);
91
288
  if (!runFn) {
92
- throw new Error(`No run function found for task type ${taskType} and model provider ${modelProvider}`);
289
+ const installedProviders = this.getInstalledProviderIds();
290
+ const providersForTask = this.getProviderIdsForTask(taskType);
291
+ const hint = providersForTask.length > 0 ? ` Providers supporting "${taskType}": [${providersForTask.join(", ")}].` : installedProviders.length > 0 ? ` Installed providers: [${installedProviders.join(", ")}] (none support "${taskType}").` : " No providers are registered. Call provider.register() before running AI tasks.";
292
+ throw new Error(`No run function found for task type "${taskType}" and provider "${modelProvider}".${hint}`);
93
293
  }
94
294
  return runFn;
95
295
  }
96
296
  }
97
- var providerRegistry;
297
+ var providerRegistry = new AiProviderRegistry;
98
298
  function getAiProviderRegistry() {
99
- if (!providerRegistry)
100
- providerRegistry = new AiProviderRegistry;
101
299
  return providerRegistry;
102
300
  }
103
301
  function setAiProviderRegistry(pr) {
@@ -105,6 +303,16 @@ function setAiProviderRegistry(pr) {
105
303
  }
106
304
 
107
305
  // src/provider/AiProvider.ts
306
+ function resolveAiProviderGpuQueueConcurrency(concurrency) {
307
+ if (concurrency === undefined) {
308
+ return 1;
309
+ }
310
+ if (typeof concurrency === "number") {
311
+ return concurrency;
312
+ }
313
+ return concurrency.gpu ?? 1;
314
+ }
315
+
108
316
  class AiProvider {
109
317
  tasks;
110
318
  streamTasks;
@@ -164,7 +372,12 @@ class AiProvider {
164
372
  }
165
373
  }
166
374
  registry.registerProvider(this);
167
- await this.afterRegister(options);
375
+ try {
376
+ await this.afterRegister(options);
377
+ } catch (err) {
378
+ registry.unregisterProvider(this.name);
379
+ throw err;
380
+ }
168
381
  }
169
382
  registerOnWorkerServer(workerServer) {
170
383
  if (!this.tasks) {
@@ -188,228 +401,6 @@ class AiProvider {
188
401
  async dispose() {}
189
402
  async afterRegister(_options) {}
190
403
  }
191
- // src/task/ToolCallingUtils.ts
192
- import { getLogger } from "@workglow/util/worker";
193
- function buildToolDescription(tool) {
194
- let desc = tool.description;
195
- if (tool.outputSchema && typeof tool.outputSchema === "object") {
196
- desc += `
197
-
198
- Returns: ${JSON.stringify(tool.outputSchema)}`;
199
- }
200
- return desc;
201
- }
202
- function isAllowedToolName(name, allowedTools) {
203
- return allowedTools.some((t) => t.name === name);
204
- }
205
- function filterValidToolCalls(toolCalls, allowedTools) {
206
- return toolCalls.filter((tc) => {
207
- if (tc.name && isAllowedToolName(tc.name, allowedTools)) {
208
- return true;
209
- }
210
- getLogger().warn(`Filtered out tool call with unknown name "${tc.name ?? "(missing)"}"`, {
211
- callId: tc.id,
212
- toolName: tc.name
213
- });
214
- return false;
215
- });
216
- }
217
- // src/task/MessageConversion.ts
218
- function getInputMessages(input) {
219
- const messages = input.messages;
220
- if (!messages || messages.length === 0)
221
- return;
222
- return messages;
223
- }
224
- function toOpenAIMessages(input) {
225
- const messages = [];
226
- if (input.systemPrompt) {
227
- messages.push({ role: "system", content: input.systemPrompt });
228
- }
229
- const inputMessages = getInputMessages(input);
230
- if (!inputMessages) {
231
- if (!Array.isArray(input.prompt)) {
232
- messages.push({ role: "user", content: input.prompt });
233
- } else if (input.prompt.every((item) => typeof item === "string")) {
234
- messages.push({ role: "user", content: input.prompt.join(`
235
- `) });
236
- } else {
237
- const parts = [];
238
- for (const item of input.prompt) {
239
- if (typeof item === "string") {
240
- parts.push({ type: "text", text: item });
241
- } else {
242
- const b = item;
243
- if (b.type === "text") {
244
- parts.push({ type: "text", text: b.text });
245
- } else if (b.type === "image") {
246
- parts.push({
247
- type: "image_url",
248
- image_url: { url: `data:${b.mimeType};base64,${b.data}` }
249
- });
250
- } else if (b.type === "audio") {
251
- const format = b.mimeType.replace(/^audio\//, "");
252
- parts.push({
253
- type: "input_audio",
254
- input_audio: { data: b.data, format }
255
- });
256
- }
257
- }
258
- }
259
- messages.push({ role: "user", content: parts });
260
- }
261
- return messages;
262
- }
263
- for (const msg of inputMessages) {
264
- if (msg.role === "user") {
265
- if (typeof msg.content === "string") {
266
- messages.push({ role: "user", content: msg.content });
267
- } else if (Array.isArray(msg.content) && msg.content.length > 0 && typeof msg.content[0]?.type === "string") {
268
- const parts = [];
269
- for (const block of msg.content) {
270
- const b = block;
271
- if (b.type === "text") {
272
- parts.push({ type: "text", text: b.text });
273
- } else if (b.type === "image") {
274
- parts.push({
275
- type: "image_url",
276
- image_url: { url: `data:${b.mimeType};base64,${b.data}` }
277
- });
278
- } else if (b.type === "audio") {
279
- const format = b.mimeType.replace(/^audio\//, "");
280
- parts.push({
281
- type: "input_audio",
282
- input_audio: { data: b.data, format }
283
- });
284
- }
285
- }
286
- messages.push({ role: "user", content: parts });
287
- } else {
288
- try {
289
- messages.push({ role: "user", content: JSON.stringify(msg.content) });
290
- } catch {
291
- messages.push({ role: "user", content: String(msg.content) });
292
- }
293
- }
294
- } else if (msg.role === "assistant") {
295
- if (typeof msg.content === "string") {
296
- messages.push({ role: "assistant", content: msg.content.length > 0 ? msg.content : null });
297
- } else if (Array.isArray(msg.content)) {
298
- const textParts = msg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
299
- const toolCalls = msg.content.filter((b) => b.type === "tool_use").map((b) => ({
300
- id: b.id,
301
- type: "function",
302
- function: {
303
- name: b.name,
304
- arguments: JSON.stringify(b.input)
305
- }
306
- }));
307
- const entry = {
308
- role: "assistant",
309
- content: textParts.length > 0 ? textParts : null
310
- };
311
- if (toolCalls.length > 0) {
312
- entry.tool_calls = toolCalls;
313
- }
314
- messages.push(entry);
315
- }
316
- } else if (msg.role === "tool" && Array.isArray(msg.content)) {
317
- for (const block of msg.content) {
318
- const b = block;
319
- let content;
320
- if (typeof b.content === "string") {
321
- content = b.content;
322
- } else if (Array.isArray(b.content)) {
323
- const parts = [];
324
- for (const inner of b.content) {
325
- if (inner.type === "text") {
326
- parts.push({ type: "text", text: inner.text });
327
- } else if (inner.type === "image") {
328
- parts.push({
329
- type: "image_url",
330
- image_url: { url: `data:${inner.mimeType};base64,${inner.data}` }
331
- });
332
- }
333
- }
334
- content = parts;
335
- } else {
336
- content = "";
337
- }
338
- messages.push({
339
- role: "tool",
340
- content,
341
- tool_call_id: b.tool_use_id
342
- });
343
- }
344
- }
345
- }
346
- return messages;
347
- }
348
- function toTextFlatMessages(input) {
349
- const messages = [];
350
- if (input.systemPrompt) {
351
- messages.push({ role: "system", content: input.systemPrompt });
352
- }
353
- const inputMessages = getInputMessages(input);
354
- if (!inputMessages) {
355
- let promptContent;
356
- if (!Array.isArray(input.prompt)) {
357
- promptContent = input.prompt;
358
- } else {
359
- promptContent = input.prompt.map((item) => {
360
- if (typeof item === "string")
361
- return item;
362
- const b = item;
363
- return b.type === "text" ? b.text : "";
364
- }).filter((s) => s !== "").join(`
365
- `);
366
- }
367
- messages.push({ role: "user", content: promptContent });
368
- return messages;
369
- }
370
- for (const msg of inputMessages) {
371
- if (msg.role === "user") {
372
- let content = "";
373
- if (typeof msg.content === "string") {
374
- content = msg.content;
375
- } else if (Array.isArray(msg.content) && msg.content.length > 0 && typeof msg.content[0]?.type === "string") {
376
- content = msg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
377
- } else if (msg.content != null) {
378
- try {
379
- content = JSON.stringify(msg.content);
380
- } catch {
381
- content = String(msg.content);
382
- }
383
- }
384
- messages.push({ role: "user", content });
385
- } else if (msg.role === "assistant") {
386
- if (typeof msg.content === "string") {
387
- if (msg.content) {
388
- messages.push({ role: "assistant", content: msg.content });
389
- }
390
- } else if (Array.isArray(msg.content)) {
391
- const text = msg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
392
- if (text) {
393
- messages.push({ role: "assistant", content: text });
394
- }
395
- }
396
- } else if (msg.role === "tool" && Array.isArray(msg.content)) {
397
- for (const block of msg.content) {
398
- const b = block;
399
- let content;
400
- if (typeof b.content === "string") {
401
- content = b.content;
402
- } else if (Array.isArray(b.content)) {
403
- content = b.content.filter((inner) => inner.type === "text").map((inner) => inner.text).join("");
404
- } else {
405
- content = "";
406
- }
407
- messages.push({ role: "tool", content });
408
- }
409
- }
410
- }
411
- return messages;
412
- }
413
404
  // src/model/ModelSchema.ts
414
405
  var ModelConfigSchema = {
415
406
  type: "object",
@@ -452,13 +443,9 @@ var ModelRecordSchema = {
452
443
  };
453
444
  var ModelPrimaryKeyNames = ["model_id"];
454
445
  export {
455
- toTextFlatMessages,
456
- toOpenAIMessages,
457
446
  setAiProviderRegistry,
458
- isAllowedToolName,
447
+ resolveAiProviderGpuQueueConcurrency,
459
448
  getAiProviderRegistry,
460
- filterValidToolCalls,
461
- buildToolDescription,
462
449
  ModelRecordSchema,
463
450
  ModelPrimaryKeyNames,
464
451
  ModelConfigSchema,
@@ -466,4 +453,4 @@ export {
466
453
  AiProvider
467
454
  };
468
455
 
469
- //# debugId=A00532924041A69D64756E2164756E21
456
+ //# debugId=EA397FAD8CAF3E1B64756E2164756E21