@302ai/media-studio-core 0.1.0-beta.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.
- package/LICENSE +190 -0
- package/README.md +213 -0
- package/dist/client/auth.d.ts +13 -0
- package/dist/client/auth.js +34 -0
- package/dist/client/chat.d.ts +14 -0
- package/dist/client/chat.js +89 -0
- package/dist/client/client.d.ts +20 -0
- package/dist/client/client.js +34 -0
- package/dist/client/session.d.ts +33 -0
- package/dist/client/session.js +91 -0
- package/dist/client/sessions.d.ts +54 -0
- package/dist/client/sessions.js +213 -0
- package/dist/client/types.d.ts +45 -0
- package/dist/client/types.js +9 -0
- package/dist/events.d.ts +90 -0
- package/dist/format/tool-formatter.d.ts +31 -0
- package/dist/format/tool-formatter.js +395 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +24 -0
- package/dist/media/media-result.d.ts +21 -0
- package/dist/media/media-result.js +134 -0
- package/dist/media.d.ts +16 -0
- package/dist/sessions/types.d.ts +375 -0
- package/dist/sessions/types.js +129 -0
- package/dist/stream/events.d.ts +90 -0
- package/dist/stream/events.js +54 -0
- package/dist/stream/stream.d.ts +58 -0
- package/dist/stream/stream.js +325 -0
- package/dist/transport/errors.d.ts +30 -0
- package/dist/transport/errors.js +47 -0
- package/dist/transport/types.d.ts +44 -0
- package/dist/transport/types.js +1 -0
- package/dist/transport/upstream.d.ts +8 -0
- package/dist/transport/upstream.js +63 -0
- package/package.json +52 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { isObject } from "es-toolkit/compat";
|
|
2
|
+
import { isString } from "es-toolkit/predicate";
|
|
3
|
+
const ASPECT_RATIO_PATTERN = /aspect_ratio:\s*([^\s,;]+)/i;
|
|
4
|
+
const MODEL_PATTERN = /(?:^|\n)\s*-\s*model:\s*([^\s,;]+)/i;
|
|
5
|
+
const DURATION_PATTERN = /(?:^|\n)\s*-\s*duration:\s*([^\s,;]+)/i;
|
|
6
|
+
const OPERATION_PATTERN = /(?:^|\n)\s*-\s*operation:\s*([^\s,;]+)/i;
|
|
7
|
+
const CREATE_TOOL_META = {
|
|
8
|
+
image_create: { category: "image", defaultLabel: "Generating image" },
|
|
9
|
+
video_create: { category: "video", defaultLabel: "Generating video" },
|
|
10
|
+
tts_create: { category: "speech", defaultLabel: "Synthesizing speech" },
|
|
11
|
+
sfx_create: { category: "sfx", defaultLabel: "Generating sound effects" },
|
|
12
|
+
stt_transcribe: { category: "stt", defaultLabel: "Transcribing audio" },
|
|
13
|
+
three_d_create: { category: "3d", defaultLabel: "Generating 3D model" },
|
|
14
|
+
song_create: { category: "song", defaultLabel: "Generating song" },
|
|
15
|
+
};
|
|
16
|
+
const MODEL_TOOL_NAMES = new Set([
|
|
17
|
+
"model_list",
|
|
18
|
+
"model_params",
|
|
19
|
+
"models_3d",
|
|
20
|
+
"stt_models",
|
|
21
|
+
"tts_providers",
|
|
22
|
+
"tts_voices",
|
|
23
|
+
"tts_refresh",
|
|
24
|
+
]);
|
|
25
|
+
function isRecord(value) {
|
|
26
|
+
return isObject(value);
|
|
27
|
+
}
|
|
28
|
+
function truncate(str, maxLen) {
|
|
29
|
+
if (str.length <= maxLen)
|
|
30
|
+
return str;
|
|
31
|
+
return `${str.slice(0, maxLen)}...`;
|
|
32
|
+
}
|
|
33
|
+
function getDisplayFileName(filePath) {
|
|
34
|
+
if (!filePath)
|
|
35
|
+
return "";
|
|
36
|
+
return filePath.split(/[/\\]/).pop() || filePath;
|
|
37
|
+
}
|
|
38
|
+
function extractFromPrompt(prompt, pattern) {
|
|
39
|
+
if (!isString(prompt))
|
|
40
|
+
return undefined;
|
|
41
|
+
const match = pattern.exec(prompt);
|
|
42
|
+
return match?.[1];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 1:1 normalization parity with main project's `normalizeMcpToolName`.
|
|
46
|
+
* Strips `tool-` prefix, lowercases, resolves MCP namespaces (`mcp__server__name`),
|
|
47
|
+
* and trims trailing `output` suffix.
|
|
48
|
+
*/
|
|
49
|
+
export function normalizeMcpToolName(toolName) {
|
|
50
|
+
const raw = toolName.startsWith("tool-") ? toolName.slice(5) : toolName;
|
|
51
|
+
const lower = raw.toLowerCase();
|
|
52
|
+
const separatorIndex = lower.lastIndexOf("__");
|
|
53
|
+
let normalized = separatorIndex >= 0 ? lower.slice(separatorIndex + 2) : lower;
|
|
54
|
+
if (normalized.endsWith("output") && normalized !== "output") {
|
|
55
|
+
normalized = normalized.slice(0, -6);
|
|
56
|
+
}
|
|
57
|
+
return normalized;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Parses and formats a tool call into a structured milestone and dynamic action label.
|
|
61
|
+
* Fully aligned 1:1 with the main project's tool renderer hierarchy.
|
|
62
|
+
*/
|
|
63
|
+
export function formatToolMilestone(toolName, args) {
|
|
64
|
+
const normalized = normalizeMcpToolName(toolName);
|
|
65
|
+
const input = isRecord(args) ? args : {};
|
|
66
|
+
// 1. Agent dispatch (Agent / task)
|
|
67
|
+
if (normalized === "agent" || normalized === "task") {
|
|
68
|
+
const subagentType = isString(input.subagent_type)
|
|
69
|
+
? input.subagent_type
|
|
70
|
+
: "subagent";
|
|
71
|
+
const description = isString(input.description) ? input.description : "";
|
|
72
|
+
const model = isString(input.model)
|
|
73
|
+
? input.model
|
|
74
|
+
: extractFromPrompt(input.prompt, MODEL_PATTERN);
|
|
75
|
+
const aspectRatio = isString(input.aspect_ratio)
|
|
76
|
+
? input.aspect_ratio
|
|
77
|
+
: extractFromPrompt(input.prompt, ASPECT_RATIO_PATTERN);
|
|
78
|
+
const duration = isString(input.duration)
|
|
79
|
+
? input.duration
|
|
80
|
+
: extractFromPrompt(input.prompt, DURATION_PATTERN);
|
|
81
|
+
const operation = isString(input.operation)
|
|
82
|
+
? input.operation
|
|
83
|
+
: extractFromPrompt(input.prompt, OPERATION_PATTERN);
|
|
84
|
+
const descPart = description ? `: ${description}` : "";
|
|
85
|
+
const tags = [];
|
|
86
|
+
if (model)
|
|
87
|
+
tags.push(`model: ${model}`);
|
|
88
|
+
if (aspectRatio)
|
|
89
|
+
tags.push(aspectRatio);
|
|
90
|
+
if (duration)
|
|
91
|
+
tags.push(duration);
|
|
92
|
+
const tagsPart = tags.length > 0 ? ` (${tags.join(", ")})` : "";
|
|
93
|
+
const opPart = operation ? ` <${operation.toUpperCase()}>` : "";
|
|
94
|
+
const milestoneLine = `[step] Dispatched ${subagentType}${descPart}${tagsPart}${opPart}`;
|
|
95
|
+
const actionLabel = model
|
|
96
|
+
? `Executing ${subagentType} (${model})...`
|
|
97
|
+
: `Executing ${subagentType}...`;
|
|
98
|
+
return {
|
|
99
|
+
rawName: toolName,
|
|
100
|
+
normalizedName: normalized,
|
|
101
|
+
category: "agent",
|
|
102
|
+
milestoneLine,
|
|
103
|
+
actionLabel,
|
|
104
|
+
details: {
|
|
105
|
+
subagentType,
|
|
106
|
+
description: description || undefined,
|
|
107
|
+
model,
|
|
108
|
+
aspectRatio,
|
|
109
|
+
duration,
|
|
110
|
+
operation,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
// 2. Multimodal Creation family (image_create, video_create, song_create, etc.)
|
|
115
|
+
if (normalized in CREATE_TOOL_META) {
|
|
116
|
+
const meta = CREATE_TOOL_META[normalized];
|
|
117
|
+
const model = isString(input.model)
|
|
118
|
+
? input.model
|
|
119
|
+
: extractFromPrompt(input.prompt, MODEL_PATTERN);
|
|
120
|
+
const aspectRatio = isString(input.aspect_ratio)
|
|
121
|
+
? input.aspect_ratio
|
|
122
|
+
: extractFromPrompt(input.prompt, ASPECT_RATIO_PATTERN);
|
|
123
|
+
const duration = isString(input.duration)
|
|
124
|
+
? input.duration
|
|
125
|
+
: typeof input.duration === "number"
|
|
126
|
+
? `${input.duration}s`
|
|
127
|
+
: isString(input.seconds)
|
|
128
|
+
? `${input.seconds}s`
|
|
129
|
+
: extractFromPrompt(input.prompt, DURATION_PATTERN);
|
|
130
|
+
const resolution = isString(input.resolution)
|
|
131
|
+
? input.resolution
|
|
132
|
+
: isString(input.size)
|
|
133
|
+
? input.size
|
|
134
|
+
: undefined;
|
|
135
|
+
const voice = isString(input.voice)
|
|
136
|
+
? input.voice
|
|
137
|
+
: isString(input.speaker)
|
|
138
|
+
? input.speaker
|
|
139
|
+
: undefined;
|
|
140
|
+
let operation = isString(input.operation)
|
|
141
|
+
? input.operation
|
|
142
|
+
: extractFromPrompt(input.prompt, OPERATION_PATTERN);
|
|
143
|
+
if (!operation) {
|
|
144
|
+
if (input.image)
|
|
145
|
+
operation = "i2i";
|
|
146
|
+
else if (input.video)
|
|
147
|
+
operation = "v2v";
|
|
148
|
+
}
|
|
149
|
+
const specs = [];
|
|
150
|
+
if (aspectRatio)
|
|
151
|
+
specs.push(aspectRatio);
|
|
152
|
+
if (duration)
|
|
153
|
+
specs.push(duration);
|
|
154
|
+
if (resolution)
|
|
155
|
+
specs.push(resolution);
|
|
156
|
+
if (voice)
|
|
157
|
+
specs.push(`voice: ${voice}`);
|
|
158
|
+
const modelPart = model ? ` (model: ${model})` : "";
|
|
159
|
+
const opPart = operation ? ` <${operation.toUpperCase()}>` : "";
|
|
160
|
+
const specsPart = specs.length > 0 ? ` [${specs.join(", ")}]` : "";
|
|
161
|
+
const milestoneLine = `[step] Executing ${normalized}${modelPart}${opPart}${specsPart}`;
|
|
162
|
+
const actionLabel = model
|
|
163
|
+
? `${meta.defaultLabel} (${model})...`
|
|
164
|
+
: `${meta.defaultLabel}...`;
|
|
165
|
+
return {
|
|
166
|
+
rawName: toolName,
|
|
167
|
+
normalizedName: normalized,
|
|
168
|
+
category: "create",
|
|
169
|
+
milestoneLine,
|
|
170
|
+
actionLabel,
|
|
171
|
+
details: {
|
|
172
|
+
model,
|
|
173
|
+
aspectRatio,
|
|
174
|
+
duration,
|
|
175
|
+
resolution,
|
|
176
|
+
voice,
|
|
177
|
+
operation,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
// 3. Model & Capability Discovery tools
|
|
182
|
+
if (MODEL_TOOL_NAMES.has(normalized)) {
|
|
183
|
+
const kind = isString(input.kind) ? input.kind : undefined;
|
|
184
|
+
const model = isString(input.model) ? input.model : undefined;
|
|
185
|
+
let milestoneLine = `[step] Querying models (${normalized})...`;
|
|
186
|
+
let actionLabel = "Querying models...";
|
|
187
|
+
if (normalized === "model_list") {
|
|
188
|
+
milestoneLine = kind
|
|
189
|
+
? `[step] Querying available models (${kind})...`
|
|
190
|
+
: "[step] Querying available models...";
|
|
191
|
+
actionLabel = kind
|
|
192
|
+
? `Querying available models (${kind})...`
|
|
193
|
+
: "Querying available models...";
|
|
194
|
+
}
|
|
195
|
+
else if (normalized === "model_params" && model) {
|
|
196
|
+
milestoneLine = `[step] Querying parameters for model: ${model}...`;
|
|
197
|
+
actionLabel = `Inspecting model ${model}...`;
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
rawName: toolName,
|
|
201
|
+
normalizedName: normalized,
|
|
202
|
+
category: "model",
|
|
203
|
+
milestoneLine,
|
|
204
|
+
actionLabel,
|
|
205
|
+
details: {
|
|
206
|
+
model,
|
|
207
|
+
target: kind,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// 4. Search & Fetch tools
|
|
212
|
+
if (normalized === "web_search") {
|
|
213
|
+
const query = isString(input.query)
|
|
214
|
+
? input.query
|
|
215
|
+
: isString(input.q)
|
|
216
|
+
? input.q
|
|
217
|
+
: "";
|
|
218
|
+
const queryPart = query ? `: ${query}` : "";
|
|
219
|
+
return {
|
|
220
|
+
rawName: toolName,
|
|
221
|
+
normalizedName: normalized,
|
|
222
|
+
category: "search",
|
|
223
|
+
milestoneLine: `[step] Searching web${queryPart}`,
|
|
224
|
+
actionLabel: query
|
|
225
|
+
? `Searching web: ${truncate(query, 25)}...`
|
|
226
|
+
: "Searching web...",
|
|
227
|
+
details: { query: query || undefined },
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (normalized === "web_fetch" || normalized === "download_file") {
|
|
231
|
+
const url = isString(input.url) ? input.url : "";
|
|
232
|
+
const target = url ? ` ${url}` : "";
|
|
233
|
+
return {
|
|
234
|
+
rawName: toolName,
|
|
235
|
+
normalizedName: normalized,
|
|
236
|
+
category: "search",
|
|
237
|
+
milestoneLine: `[step] ${normalized === "download_file" ? "Downloading file" : "Fetching URL"}${target}`,
|
|
238
|
+
actionLabel: normalized === "download_file"
|
|
239
|
+
? "Downloading file..."
|
|
240
|
+
: "Fetching web content...",
|
|
241
|
+
details: { target: url || undefined },
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
if (normalized === "document_parse") {
|
|
245
|
+
const target = isString(input.file_path)
|
|
246
|
+
? input.file_path
|
|
247
|
+
: isString(input.url)
|
|
248
|
+
? input.url
|
|
249
|
+
: "";
|
|
250
|
+
const display = getDisplayFileName(target);
|
|
251
|
+
return {
|
|
252
|
+
rawName: toolName,
|
|
253
|
+
normalizedName: normalized,
|
|
254
|
+
category: "search",
|
|
255
|
+
milestoneLine: display
|
|
256
|
+
? `[step] Parsing document: ${display}`
|
|
257
|
+
: "[step] Parsing document...",
|
|
258
|
+
actionLabel: display ? `Parsing ${display}...` : "Parsing document...",
|
|
259
|
+
details: { target: target || undefined },
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
if (normalized === "image_analyze" || normalized === "video_analyze") {
|
|
263
|
+
const mediaType = normalized === "image_analyze" ? "image" : "video";
|
|
264
|
+
return {
|
|
265
|
+
rawName: toolName,
|
|
266
|
+
normalizedName: normalized,
|
|
267
|
+
category: "search",
|
|
268
|
+
milestoneLine: `[step] Analyzing ${mediaType}...`,
|
|
269
|
+
actionLabel: `Analyzing ${mediaType}...`,
|
|
270
|
+
details: {},
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
if (normalized === "song_lyrics") {
|
|
274
|
+
const title = isString(input.title)
|
|
275
|
+
? input.title
|
|
276
|
+
: isString(input.query)
|
|
277
|
+
? input.query
|
|
278
|
+
: "";
|
|
279
|
+
return {
|
|
280
|
+
rawName: toolName,
|
|
281
|
+
normalizedName: normalized,
|
|
282
|
+
category: "search",
|
|
283
|
+
milestoneLine: title
|
|
284
|
+
? `[step] Searching lyrics: ${title}`
|
|
285
|
+
: "[step] Searching song lyrics...",
|
|
286
|
+
actionLabel: "Searching song lyrics...",
|
|
287
|
+
details: { query: title || undefined },
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
// 5. File & Shell tools
|
|
291
|
+
if (normalized === "read" ||
|
|
292
|
+
normalized === "read_file" ||
|
|
293
|
+
normalized === "view_file") {
|
|
294
|
+
const path = isString(input.file_path)
|
|
295
|
+
? input.file_path
|
|
296
|
+
: isString(input.path)
|
|
297
|
+
? input.path
|
|
298
|
+
: "";
|
|
299
|
+
const display = getDisplayFileName(path);
|
|
300
|
+
return {
|
|
301
|
+
rawName: toolName,
|
|
302
|
+
normalizedName: normalized,
|
|
303
|
+
category: "file",
|
|
304
|
+
milestoneLine: display
|
|
305
|
+
? `[step] Reading file: ${display}`
|
|
306
|
+
: "[step] Reading file...",
|
|
307
|
+
actionLabel: display ? `Reading ${display}...` : "Reading file...",
|
|
308
|
+
details: { target: path || undefined },
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
if (normalized === "write" ||
|
|
312
|
+
normalized === "write_file" ||
|
|
313
|
+
normalized === "write_to_file" ||
|
|
314
|
+
normalized === "create_file") {
|
|
315
|
+
const path = isString(input.file_path)
|
|
316
|
+
? input.file_path
|
|
317
|
+
: isString(input.path)
|
|
318
|
+
? input.path
|
|
319
|
+
: "";
|
|
320
|
+
const display = getDisplayFileName(path);
|
|
321
|
+
return {
|
|
322
|
+
rawName: toolName,
|
|
323
|
+
normalizedName: normalized,
|
|
324
|
+
category: "file",
|
|
325
|
+
milestoneLine: display
|
|
326
|
+
? `[step] Writing file: ${display}`
|
|
327
|
+
: "[step] Writing file...",
|
|
328
|
+
actionLabel: display ? `Writing ${display}...` : "Writing file...",
|
|
329
|
+
details: { target: path || undefined },
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
if (normalized === "edit" ||
|
|
333
|
+
normalized === "edit_file" ||
|
|
334
|
+
normalized === "replace_file_content" ||
|
|
335
|
+
normalized === "multi_replace_file_content") {
|
|
336
|
+
const path = isString(input.file_path)
|
|
337
|
+
? input.file_path
|
|
338
|
+
: isString(input.path)
|
|
339
|
+
? input.path
|
|
340
|
+
: "";
|
|
341
|
+
const display = getDisplayFileName(path);
|
|
342
|
+
return {
|
|
343
|
+
rawName: toolName,
|
|
344
|
+
normalizedName: normalized,
|
|
345
|
+
category: "file",
|
|
346
|
+
milestoneLine: display
|
|
347
|
+
? `[step] Editing file: ${display}`
|
|
348
|
+
: "[step] Editing file...",
|
|
349
|
+
actionLabel: display ? `Editing ${display}...` : "Editing file...",
|
|
350
|
+
details: { target: path || undefined },
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
if (normalized === "bash") {
|
|
354
|
+
const cmd = isString(input.command) ? input.command : "";
|
|
355
|
+
return {
|
|
356
|
+
rawName: toolName,
|
|
357
|
+
normalizedName: normalized,
|
|
358
|
+
category: "bash",
|
|
359
|
+
milestoneLine: cmd
|
|
360
|
+
? `[step] Running bash: ${truncate(cmd, 40)}`
|
|
361
|
+
: "[step] Running bash command...",
|
|
362
|
+
actionLabel: "Running bash command...",
|
|
363
|
+
details: { target: cmd || undefined },
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
// 6. Skill tools
|
|
367
|
+
if (normalized === "skill" || normalized === "skill_created") {
|
|
368
|
+
const skillName = isString(input.skill_name)
|
|
369
|
+
? input.skill_name
|
|
370
|
+
: isString(input.name)
|
|
371
|
+
? input.name
|
|
372
|
+
: "";
|
|
373
|
+
return {
|
|
374
|
+
rawName: toolName,
|
|
375
|
+
normalizedName: normalized,
|
|
376
|
+
category: "skill",
|
|
377
|
+
milestoneLine: skillName
|
|
378
|
+
? `[step] Using skill: ${skillName}`
|
|
379
|
+
: "[step] Using skill...",
|
|
380
|
+
actionLabel: skillName
|
|
381
|
+
? `Executing skill ${skillName}...`
|
|
382
|
+
: "Executing skill...",
|
|
383
|
+
details: { target: skillName || undefined },
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
// 7. Generic Fallback
|
|
387
|
+
return {
|
|
388
|
+
rawName: toolName,
|
|
389
|
+
normalizedName: normalized,
|
|
390
|
+
category: "other",
|
|
391
|
+
milestoneLine: `[step] Calling ${normalized}...`,
|
|
392
|
+
actionLabel: `Working on ${normalized}...`,
|
|
393
|
+
details: {},
|
|
394
|
+
};
|
|
395
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @302ai/media-studio-core
|
|
3
|
+
* Official client SDK and isomorphic core for 302 AI Media Studio.
|
|
4
|
+
*/
|
|
5
|
+
export * from "./client/auth.js";
|
|
6
|
+
export * from "./client/chat.js";
|
|
7
|
+
export * from "./client/client.js";
|
|
8
|
+
export * from "./client/session.js";
|
|
9
|
+
export * from "./client/sessions.js";
|
|
10
|
+
export * from "./client/types.js";
|
|
11
|
+
export * from "./format/tool-formatter.js";
|
|
12
|
+
export * from "./media/media-result.js";
|
|
13
|
+
export * from "./sessions/types.js";
|
|
14
|
+
export * from "./stream/events.js";
|
|
15
|
+
export * from "./stream/stream.js";
|
|
16
|
+
export * from "./transport/errors.js";
|
|
17
|
+
export * from "./transport/types.js";
|
|
18
|
+
export * from "./transport/upstream.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @302ai/media-studio-core
|
|
3
|
+
* Official client SDK and isomorphic core for 302 AI Media Studio.
|
|
4
|
+
*/
|
|
5
|
+
// Client Layer
|
|
6
|
+
export * from "./client/auth.js";
|
|
7
|
+
export * from "./client/chat.js";
|
|
8
|
+
export * from "./client/client.js";
|
|
9
|
+
export * from "./client/session.js";
|
|
10
|
+
export * from "./client/sessions.js";
|
|
11
|
+
export * from "./client/types.js";
|
|
12
|
+
// Format & Tool Milestone Layer
|
|
13
|
+
export * from "./format/tool-formatter.js";
|
|
14
|
+
// Media Domain Layer
|
|
15
|
+
export * from "./media/media-result.js";
|
|
16
|
+
// Sessions Layer
|
|
17
|
+
export * from "./sessions/types.js";
|
|
18
|
+
// Streaming & Events Layer
|
|
19
|
+
export * from "./stream/events.js";
|
|
20
|
+
export * from "./stream/stream.js";
|
|
21
|
+
export * from "./transport/errors.js";
|
|
22
|
+
// Transport Layer
|
|
23
|
+
export * from "./transport/types.js";
|
|
24
|
+
export * from "./transport/upstream.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const MediaResultSchema: z.ZodObject<{
|
|
3
|
+
status: z.ZodOptional<z.ZodString>;
|
|
4
|
+
domain: z.ZodOptional<z.ZodString>;
|
|
5
|
+
operation: z.ZodOptional<z.ZodString>;
|
|
6
|
+
modelUsed: z.ZodOptional<z.ZodString>;
|
|
7
|
+
taskId: z.ZodOptional<z.ZodString>;
|
|
8
|
+
resultUrl: z.ZodOptional<z.ZodString>;
|
|
9
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type MediaResult = z.infer<typeof MediaResultSchema>;
|
|
12
|
+
/**
|
|
13
|
+
* Extracts a structured media result from a tool output string or object. Returns null unless
|
|
14
|
+
* the output contains media task completion identifiers (`task_id` or `result_url`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractMediaResult(output: unknown): MediaResult | null;
|
|
17
|
+
/**
|
|
18
|
+
* Merges an incoming MediaResult into an existing list of media results,
|
|
19
|
+
* deduplicating by resultUrl or taskId and enriching missing fields.
|
|
20
|
+
*/
|
|
21
|
+
export declare function addOrMergeMediaResult(assets: MediaResult[], incoming: MediaResult): void;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { isObject } from "es-toolkit/compat";
|
|
2
|
+
import { isString } from "es-toolkit/predicate";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
export const MediaResultSchema = z.object({
|
|
5
|
+
status: z.string().optional(),
|
|
6
|
+
domain: z.string().optional(),
|
|
7
|
+
operation: z.string().optional(),
|
|
8
|
+
modelUsed: z.string().optional(),
|
|
9
|
+
taskId: z.string().optional(),
|
|
10
|
+
resultUrl: z.string().optional(),
|
|
11
|
+
prompt: z.string().optional(),
|
|
12
|
+
});
|
|
13
|
+
function parseKeyValueLines(output) {
|
|
14
|
+
const fields = new Map();
|
|
15
|
+
for (const line of output.split("\n")) {
|
|
16
|
+
const trimmed = line.trim().replace(/^- /, "").trim();
|
|
17
|
+
const eq = trimmed.indexOf("=");
|
|
18
|
+
if (eq <= 0)
|
|
19
|
+
continue;
|
|
20
|
+
const key = trimmed.slice(0, eq).trim();
|
|
21
|
+
let value = trimmed.slice(eq + 1).trim();
|
|
22
|
+
if (value.length >= 2 && value.startsWith('"') && value.endsWith('"')) {
|
|
23
|
+
value = value.slice(1, -1);
|
|
24
|
+
}
|
|
25
|
+
if (key)
|
|
26
|
+
fields.set(key, value);
|
|
27
|
+
}
|
|
28
|
+
return fields;
|
|
29
|
+
}
|
|
30
|
+
function isRecord(value) {
|
|
31
|
+
return isObject(value);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extracts a structured media result from a tool output string or object. Returns null unless
|
|
35
|
+
* the output contains media task completion identifiers (`task_id` or `result_url`).
|
|
36
|
+
*/
|
|
37
|
+
export function extractMediaResult(output) {
|
|
38
|
+
if (isRecord(output)) {
|
|
39
|
+
const target = isRecord(output.data) ? output.data : output;
|
|
40
|
+
const taskId = isString(target.task_id)
|
|
41
|
+
? target.task_id
|
|
42
|
+
: isString(target.taskId)
|
|
43
|
+
? target.taskId
|
|
44
|
+
: undefined;
|
|
45
|
+
const resultUrl = isString(target.result_url)
|
|
46
|
+
? target.result_url
|
|
47
|
+
: isString(target.resultUrl)
|
|
48
|
+
? target.resultUrl
|
|
49
|
+
: isString(target.url)
|
|
50
|
+
? target.url
|
|
51
|
+
: isString(target.image_path)
|
|
52
|
+
? target.image_path
|
|
53
|
+
: undefined;
|
|
54
|
+
if (!taskId && !resultUrl)
|
|
55
|
+
return null;
|
|
56
|
+
const domain = isString(target.domain)
|
|
57
|
+
? target.domain
|
|
58
|
+
: isString(target.type)
|
|
59
|
+
? target.type
|
|
60
|
+
: undefined;
|
|
61
|
+
return {
|
|
62
|
+
...(isString(target.status) ? { status: target.status } : {}),
|
|
63
|
+
...(domain ? { domain } : {}),
|
|
64
|
+
...(isString(target.operation) ? { operation: target.operation } : {}),
|
|
65
|
+
...(isString(target.model_used)
|
|
66
|
+
? { modelUsed: target.model_used }
|
|
67
|
+
: isString(target.modelUsed)
|
|
68
|
+
? { modelUsed: target.modelUsed }
|
|
69
|
+
: isString(target.model)
|
|
70
|
+
? { modelUsed: target.model }
|
|
71
|
+
: {}),
|
|
72
|
+
...(taskId ? { taskId } : {}),
|
|
73
|
+
...(resultUrl ? { resultUrl } : {}),
|
|
74
|
+
...(isString(target.prompt) ? { prompt: target.prompt } : {}),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (!isString(output))
|
|
78
|
+
return null;
|
|
79
|
+
const fields = parseKeyValueLines(output);
|
|
80
|
+
const taskId = fields.get("task_id");
|
|
81
|
+
const resultUrl = fields.get("result_url") ?? fields.get("image_path");
|
|
82
|
+
if (!taskId && !resultUrl)
|
|
83
|
+
return null;
|
|
84
|
+
const status = fields.get("status");
|
|
85
|
+
const domain = fields.get("domain");
|
|
86
|
+
const operation = fields.get("operation");
|
|
87
|
+
const modelUsed = fields.get("model_used");
|
|
88
|
+
const prompt = fields.get("prompt");
|
|
89
|
+
return {
|
|
90
|
+
...(status ? { status } : {}),
|
|
91
|
+
...(domain ? { domain } : {}),
|
|
92
|
+
...(operation ? { operation } : {}),
|
|
93
|
+
...(modelUsed ? { modelUsed } : {}),
|
|
94
|
+
...(taskId ? { taskId } : {}),
|
|
95
|
+
...(resultUrl ? { resultUrl } : {}),
|
|
96
|
+
...(prompt ? { prompt } : {}),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Merges an incoming MediaResult into an existing list of media results,
|
|
101
|
+
* deduplicating by resultUrl or taskId and enriching missing fields.
|
|
102
|
+
*/
|
|
103
|
+
export function addOrMergeMediaResult(assets, incoming) {
|
|
104
|
+
const existing = assets.find((a) => (a.resultUrl &&
|
|
105
|
+
incoming.resultUrl &&
|
|
106
|
+
a.resultUrl === incoming.resultUrl) ||
|
|
107
|
+
(a.taskId && incoming.taskId && a.taskId === incoming.taskId));
|
|
108
|
+
if (existing) {
|
|
109
|
+
if (!existing.modelUsed && incoming.modelUsed) {
|
|
110
|
+
existing.modelUsed = incoming.modelUsed;
|
|
111
|
+
}
|
|
112
|
+
if (!existing.taskId && incoming.taskId) {
|
|
113
|
+
existing.taskId = incoming.taskId;
|
|
114
|
+
}
|
|
115
|
+
if (!existing.resultUrl && incoming.resultUrl) {
|
|
116
|
+
existing.resultUrl = incoming.resultUrl;
|
|
117
|
+
}
|
|
118
|
+
if (!existing.domain && incoming.domain) {
|
|
119
|
+
existing.domain = incoming.domain;
|
|
120
|
+
}
|
|
121
|
+
if (!existing.prompt && incoming.prompt) {
|
|
122
|
+
existing.prompt = incoming.prompt;
|
|
123
|
+
}
|
|
124
|
+
if (!existing.status && incoming.status) {
|
|
125
|
+
existing.status = incoming.status;
|
|
126
|
+
}
|
|
127
|
+
if (!existing.operation && incoming.operation) {
|
|
128
|
+
existing.operation = incoming.operation;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
assets.push({ ...incoming });
|
|
133
|
+
}
|
|
134
|
+
}
|
package/dist/media.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const MediaResultSchema: z.ZodObject<{
|
|
3
|
+
status: z.ZodOptional<z.ZodString>;
|
|
4
|
+
domain: z.ZodOptional<z.ZodString>;
|
|
5
|
+
operation: z.ZodOptional<z.ZodString>;
|
|
6
|
+
modelUsed: z.ZodOptional<z.ZodString>;
|
|
7
|
+
taskId: z.ZodOptional<z.ZodString>;
|
|
8
|
+
resultUrl: z.ZodOptional<z.ZodString>;
|
|
9
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type MediaResult = z.infer<typeof MediaResultSchema>;
|
|
12
|
+
/**
|
|
13
|
+
* Extracts a structured media result from a tool output string. Returns null unless
|
|
14
|
+
* the output contains media task completion identifiers (`task_id` or `result_url`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractMediaResult(output: unknown): MediaResult | null;
|