freebeat-mcp 0.4.2 → 0.4.3
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/README.md +17 -4
- package/dist/capabilities/agents/register.js +5 -0
- package/dist/capabilities/agents/register.js.map +1 -1
- package/dist/capabilities/agents/tools/generate-agent-videos.js +7 -5
- package/dist/capabilities/agents/tools/generate-agent-videos.js.map +1 -1
- package/dist/capabilities/agents/tools/video-session.d.ts +4 -0
- package/dist/capabilities/agents/tools/video-session.js +29 -0
- package/dist/capabilities/agents/tools/video-session.js.map +1 -0
- package/dist/capabilities/tasks/tools/get-task-result.js +1 -1
- package/dist/capabilities/tasks/tools/get-task-result.js.map +1 -1
- package/dist/capabilities/tasks/tools/get-task-status.js +1 -1
- package/dist/capabilities/tasks/tools/get-task-status.js.map +1 -1
- package/dist/core/video-session.d.ts +283 -0
- package/dist/core/video-session.js +192 -0
- package/dist/core/video-session.js.map +1 -0
- package/dist/services/freebeat-api.d.ts +15 -0
- package/dist/services/freebeat-api.js +109 -36
- package/dist/services/freebeat-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const CO_CREATE_DESCRIPTION = "On freebeat.ai a person creates a video by chatting with a director agent and seeing what it made. In auto mode the agent makes the creative decisions and delivers the film; otherwise it pauses where a person's taste matters. Through these tools you stand where that person stands: read the agent's words and work, and say anything the person could type there, including approval, changes, direction, or handing the rest to auto. Decide whether and how to involve the user from their intent. Credit consent is given when the video starts; continuing this session needs no new consent. Relay any credit notice the agent reports. ";
|
|
3
|
+
export const autoModeSchema = z.boolean().describe("true: let the director agent make creative decisions and deliver the film. false: co-create through get_video_session and send_video_agent_message when it pauses for creative input. Choose from the user's request, or discuss the choice when needed.");
|
|
4
|
+
export const videoTaskIdSchema = z.string().max(500).regex(/^(music_video|dance|lyric_video):.+/)
|
|
5
|
+
.describe("The task_id from generate_music_video, generate_dance_video, or generate_lyric_video.");
|
|
6
|
+
const stageStatusSchema = z.enum(["not_started", "queued", "running", "retrying", "pending_review", "approved", "complete", "completed", "failed", "cancelled", "warning", "unknown"]);
|
|
7
|
+
const fieldSchema = z.object({ path: z.string().max(500), value: z.union([z.string().max(4000), z.number().finite(), z.boolean()]) });
|
|
8
|
+
const mediaSchema = z.object({ path: z.string().max(500), url: z.string().max(2048) });
|
|
9
|
+
const displaySchema = { fields: z.array(fieldSchema).max(400), media: z.array(mediaSchema).max(100) };
|
|
10
|
+
export const videoSessionSchema = z.object({
|
|
11
|
+
task_id: videoTaskIdSchema,
|
|
12
|
+
session_url: z.string(),
|
|
13
|
+
status: z.enum(["running", "waiting_for_user", "idle"]),
|
|
14
|
+
auto_mode: z.boolean().nullable(),
|
|
15
|
+
current_stage: z.string().max(120).nullable(),
|
|
16
|
+
stages: z.array(z.object({ name: z.string().max(120), status: stageStatusSchema })).max(64),
|
|
17
|
+
waiting_for: z.array(z.object({ ...displaySchema })).max(20),
|
|
18
|
+
messages: z.array(z.object({ role: z.enum(["user", "assistant"]), parts: z.array(z.object({
|
|
19
|
+
type: z.string().max(80), ...displaySchema,
|
|
20
|
+
})).max(40) })).max(20),
|
|
21
|
+
artifacts: z.array(z.object({
|
|
22
|
+
type: z.string().max(120), version: z.number().finite().optional(), is_latest: z.boolean().optional(),
|
|
23
|
+
...displaySchema,
|
|
24
|
+
})).max(24),
|
|
25
|
+
truncated: z.boolean(),
|
|
26
|
+
});
|
|
27
|
+
export function record(value) {
|
|
28
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
29
|
+
}
|
|
30
|
+
// Match the website's structural text boundary before treating assistant text as visible content.
|
|
31
|
+
export function creatorFacingText(value) {
|
|
32
|
+
let text = value.trimStart();
|
|
33
|
+
if (/^\[reasoning\]/i.test(text) && !/<\/mm:think>/i.test(text))
|
|
34
|
+
return undefined;
|
|
35
|
+
text = text.replace(/(?:^|\n\n)\[reasoning\][\s\S]*?<\/mm:think>\s*/gi, "")
|
|
36
|
+
.replace(/(?:^|\n\n)\[(?:summary|clarification|support needed)\][^\n]*(?=\n\n|$)/gi, "")
|
|
37
|
+
.replace(/^\[assistant text compacted:[^\n]+\]\n[^\n]*\n\n/, "").trim();
|
|
38
|
+
if (/^\[reasoning\]/i.test(text) && !/<\/mm:think>/i.test(text))
|
|
39
|
+
return undefined;
|
|
40
|
+
if (!text || text.startsWith("{") || /^Updated todo list to\s+/i.test(text) ||
|
|
41
|
+
/^##\s*SESSION INTENT\b/i.test(text) || (/##\s*ARTIFACTS\b/i.test(text) && /##\s*NEXT STEPS\b/i.test(text)))
|
|
42
|
+
return undefined;
|
|
43
|
+
if (text.startsWith("[")) {
|
|
44
|
+
try {
|
|
45
|
+
JSON.parse(text);
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
if (/"[\w-]+"\s*:/.test(text))
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return text;
|
|
54
|
+
}
|
|
55
|
+
// Artifacts are the agent's work product and pass through whole; only credentials, diagnostics and raw upstream data never do.
|
|
56
|
+
const hiddenKey = (key) => /(^|_)(token|secret|passw(or)?d|api_?key|authori[sz]ation|cookie|credentials?|signature|metadata|debug|trace|traceback|stack_?trace)$/i.test(key) ||
|
|
57
|
+
/(Token|Secret|Password|ApiKey|Authorization|Cookie|Credentials?|Signature|Metadata|Debug|Trace)$/.test(key) || /^(provider|raw)(_|[A-Z])/.test(key);
|
|
58
|
+
const mediaFields = new Set(`url src href public_url publicUrl preview_url previewUrl thumbnail_url thumbnailUrl cover_url coverUrl
|
|
59
|
+
image_url imageUrl video_url videoUrl audio_url audioUrl result_url resultUrl final_video_url finalVideoUrl grid_image_url gridImageUrl subject_photo_uri
|
|
60
|
+
object_key objectKey payload_ref payloadRef preview_object_key previewObjectKey image_urls imageUrls storyboard_cover_image_url storyboardCoverImageUrl cover_image_url coverImageUrl`.split(/\s+/));
|
|
61
|
+
const mediaContainers = new Set(["image", "video", "audio", "thumbnail", "grid_image", "frame", "cover"]);
|
|
62
|
+
export function projectVideoSession(taskId, sessionUrl, host, rawState, rawMessages, rawAssets) {
|
|
63
|
+
let remaining = 60_000;
|
|
64
|
+
let truncated = false;
|
|
65
|
+
const take = (value, max) => {
|
|
66
|
+
const length = Math.min(max, remaining);
|
|
67
|
+
if (value.length > length)
|
|
68
|
+
truncated = true;
|
|
69
|
+
const text = value.slice(0, length);
|
|
70
|
+
remaining -= text.length;
|
|
71
|
+
return text;
|
|
72
|
+
};
|
|
73
|
+
const limit = (items, max) => {
|
|
74
|
+
if (items.length > max)
|
|
75
|
+
truncated = true;
|
|
76
|
+
return items.slice(0, max);
|
|
77
|
+
};
|
|
78
|
+
const display = (raw) => {
|
|
79
|
+
const fields = [];
|
|
80
|
+
const media = [];
|
|
81
|
+
const visit = (value, path, depth, isMedia = false) => {
|
|
82
|
+
if (depth > 10 || remaining <= 0 || fields.length >= 400 || media.length >= 100) {
|
|
83
|
+
truncated = true;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (Array.isArray(value)) {
|
|
87
|
+
limit(value, 64).forEach((item, i) => visit(item, `${path}[${i}]`, depth + 1, isMedia));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (typeof value === "string" || typeof value === "boolean" || typeof value === "number") {
|
|
91
|
+
if (remaining < path.length + 100) {
|
|
92
|
+
truncated = true;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
remaining -= path.length + 100;
|
|
96
|
+
}
|
|
97
|
+
if (typeof value === "string") {
|
|
98
|
+
if (isMedia || /^https?:\/\/\S+$/i.test(value)) {
|
|
99
|
+
try {
|
|
100
|
+
const url = new URL(value, host);
|
|
101
|
+
if (!/^https?:$/.test(url.protocol) || url.username || url.password || url.href.length > 2048)
|
|
102
|
+
return;
|
|
103
|
+
if (url.href.length > remaining) {
|
|
104
|
+
truncated = true;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
media.push({ path: path.slice(0, 500), url: take(url.href, 2048) });
|
|
108
|
+
}
|
|
109
|
+
catch { /* Invalid media has no viewable URL. */ }
|
|
110
|
+
}
|
|
111
|
+
else if (value.trim())
|
|
112
|
+
fields.push({ path: path.slice(0, 500), value: take(value, 4000) });
|
|
113
|
+
}
|
|
114
|
+
else if (typeof value === "boolean" || (typeof value === "number" && Number.isFinite(value))) {
|
|
115
|
+
fields.push({ path: path.slice(0, 500), value });
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
for (const [key, child] of Object.entries(record(value))) {
|
|
119
|
+
if (!hiddenKey(key))
|
|
120
|
+
visit(child, path ? `${path}.${key}` : key, depth + 1, mediaFields.has(key) || mediaContainers.has(key));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
visit(raw, "", 0);
|
|
125
|
+
return { fields, media };
|
|
126
|
+
};
|
|
127
|
+
const state = record(rawState);
|
|
128
|
+
const thread = record(rawMessages);
|
|
129
|
+
const pipeline = record(state.pipeline_state);
|
|
130
|
+
const stages = limit(Object.entries(record(pipeline.stages)), 64).map(([name, status]) => ({
|
|
131
|
+
name: take(name, 120), status: stageStatusSchema.safeParse(status).success ? status : "unknown",
|
|
132
|
+
}));
|
|
133
|
+
const rawMessageList = Array.isArray(thread.messages) ? thread.messages : [];
|
|
134
|
+
if (rawMessageList.length > 20)
|
|
135
|
+
truncated = true;
|
|
136
|
+
remaining -= 24_000;
|
|
137
|
+
const messages = rawMessageList.slice(-20).reverse().flatMap(value => {
|
|
138
|
+
const message = record(value);
|
|
139
|
+
if (message.role !== "user" && message.role !== "assistant")
|
|
140
|
+
return [];
|
|
141
|
+
// Reasoning and tool-call parts are the agent's internals; text, files and data parts are what the page shows.
|
|
142
|
+
const parts = (Array.isArray(message.parts) ? message.parts : []).map(record).filter(part => typeof part.type === "string" && (part.type === "text" || part.type === "file" || part.type.startsWith("data-")));
|
|
143
|
+
if (parts.length > 40)
|
|
144
|
+
truncated = true;
|
|
145
|
+
return [{ role: message.role, parts: parts.slice(-40).reverse().flatMap(part => {
|
|
146
|
+
if (typeof part.type !== "string")
|
|
147
|
+
return [];
|
|
148
|
+
let payload = part.type === "text" || part.type === "file" ? Object.fromEntries(Object.entries(part).filter(([key]) => key !== "type")) : record(part.data);
|
|
149
|
+
if (message.role === "assistant" && ["text", "data-assistant-note"].includes(part.type)) {
|
|
150
|
+
const text = typeof payload.text === "string" ? creatorFacingText(payload.text) : undefined;
|
|
151
|
+
if (!text)
|
|
152
|
+
return [];
|
|
153
|
+
payload = { text };
|
|
154
|
+
}
|
|
155
|
+
return [{ type: part.type.slice(0, 80), ...display(payload) }];
|
|
156
|
+
}).reverse() }];
|
|
157
|
+
}).reverse();
|
|
158
|
+
remaining += 24_000;
|
|
159
|
+
const running = Boolean(state.active_run_id || thread.active_run_id);
|
|
160
|
+
const latest = messages.at(-1);
|
|
161
|
+
const pending = stages.some(stage => stage.status === "pending_review") ||
|
|
162
|
+
(Array.isArray(pipeline.reconciled_pending) && pipeline.reconciled_pending.length > 0);
|
|
163
|
+
const rawAssetList = Array.isArray(record(rawAssets).assets) ? record(rawAssets).assets : [];
|
|
164
|
+
// Once the agent stops, the next word is the person's, also after a film: they can approve it or ask for changes.
|
|
165
|
+
const waiting = !running && (pending || (latest?.role === "assistant" && latest.parts.some(part => part.fields.length || part.media.length)));
|
|
166
|
+
const latestRequest = [...messages].reverse().find(message => message.role === "assistant" && message.parts.some(part => ["text", "data-assistant-note", "data-review-request", "data-credit-notice"].includes(part.type) && (part.fields.length || part.media.length)));
|
|
167
|
+
const waitingFor = waiting && latestRequest ? latestRequest.parts.filter(part => ["text", "data-assistant-note", "data-review-request", "data-credit-notice"].includes(part.type)).slice(-20).map(({ fields, media }) => ({ fields, media })) : [];
|
|
168
|
+
// The agents list assets by type name; keep the current, newest ones when the bound applies.
|
|
169
|
+
const recency = (value) => {
|
|
170
|
+
const asset = record(value);
|
|
171
|
+
return [asset.is_latest === true ? 1 : 0, Date.parse(String(asset.created_at ?? record(asset.payload).created_at ?? "")) || 0];
|
|
172
|
+
};
|
|
173
|
+
const artifacts = limit([...rawAssetList].sort((a, b) => {
|
|
174
|
+
const [latestA, timeA] = recency(a), [latestB, timeB] = recency(b);
|
|
175
|
+
return latestB - latestA || timeB - timeA;
|
|
176
|
+
}), 24).map(value => {
|
|
177
|
+
const asset = record(value);
|
|
178
|
+
return {
|
|
179
|
+
type: take(typeof asset.asset_type === "string" ? asset.asset_type : "unknown", 120),
|
|
180
|
+
version: typeof asset.version === "number" && Number.isFinite(asset.version) ? asset.version : undefined,
|
|
181
|
+
is_latest: typeof asset.is_latest === "boolean" ? asset.is_latest : undefined,
|
|
182
|
+
...display({ ...record(asset.payload), ...(typeof asset.preview_url === "string" ? { preview_url: asset.preview_url } : {}) }),
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
return videoSessionSchema.parse({
|
|
186
|
+
task_id: taskId, session_url: sessionUrl, status: running ? "running" : waiting ? "waiting_for_user" : "idle",
|
|
187
|
+
auto_mode: typeof state.auto_mode === "boolean" ? state.auto_mode : null,
|
|
188
|
+
current_stage: typeof pipeline.current === "string" ? take(pipeline.current, 120) : null,
|
|
189
|
+
stages, waiting_for: waitingFor, messages, artifacts, truncated,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=video-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"video-session.js","sourceRoot":"","sources":["../../src/core/video-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,qBAAqB,GAAG,snBAAsnB,CAAC;AAE5pB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,0PAA0P,CAAC,CAAC;AAC/S,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,qCAAqC,CAAC;KAC9F,QAAQ,CAAC,uFAAuF,CAAC,CAAC;AAErG,MAAM,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AACvL,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AACtI,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvF,MAAM,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;AACtG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,iBAAiB;IAC1B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,kBAAkB,EAAE,MAAM,CAAC,CAAC;IACvD,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACjC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC7C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC3F,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5D,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YACxF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,aAAa;SAC3C,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACvB,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QACrG,GAAG,aAAa;KACjB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACX,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE;CACvB,CAAC,CAAC;AAGH,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7G,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;IAC7B,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAClF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kDAAkD,EAAE,EAAE,CAAC;SACxE,OAAO,CAAC,0EAA0E,EAAE,EAAE,CAAC;SACvF,OAAO,CAAC,kDAAkD,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1E,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAClF,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC;QACvE,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAClI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO,SAAS,CAAC;QAAC,CAAC;QAC3C,MAAM,CAAC;YAAC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO,SAAS,CAAC;QAAC,CAAC;IAC5D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+HAA+H;AAC/H,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,uIAAuI,CAAC,IAAI,CAAC,GAAG,CAAC;IAClL,kGAAkG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvJ,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;;sLAE0J,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACrM,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1G,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,UAAkB,EAAE,IAAY,EAAE,QAAiB,EAAE,WAAoB,EAAE,SAAkB;IAC/I,IAAI,SAAS,GAAG,MAAM,CAAC;IACvB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM;YAAE,SAAS,GAAG,IAAI,CAAC;QAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACpC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAI,KAAU,EAAE,GAAW,EAAE,EAAE;QAC3C,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG;YAAE,SAAS,GAAG,IAAI,CAAC;QACzC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,GAAY,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAkC,EAAE,CAAC;QACjD,MAAM,KAAK,GAAkC,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,CAAC,KAAc,EAAE,IAAY,EAAE,KAAa,EAAE,OAAO,GAAG,KAAK,EAAE,EAAE;YAC7E,IAAI,KAAK,GAAG,EAAE,IAAI,SAAS,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBAAC,SAAS,GAAG,IAAI,CAAC;gBAAC,OAAO;YAAC,CAAC;YAC9G,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;gBAAC,OAAO;YAAC,CAAC;YAC9H,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACzF,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;oBAAC,SAAS,GAAG,IAAI,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBAChE,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;YACjC,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,OAAO,IAAI,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC/C,IAAI,CAAC;wBACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;wBACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI;4BAAE,OAAO;wBACtG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;4BAAC,SAAS,GAAG,IAAI,CAAC;4BAAC,OAAO;wBAAC,CAAC;wBAC9D,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;oBACtE,CAAC;oBAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;gBACtD,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,EAAE;oBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAC/F,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC/F,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBACzD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;wBAAE,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChI,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QACF,KAAK,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACzF,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAA2C,CAAC,CAAC,CAAC,SAAkB;KAC9I,CAAC,CAAC,CAAC;IACJ,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,IAAI,cAAc,CAAC,MAAM,GAAG,EAAE;QAAE,SAAS,GAAG,IAAI,CAAC;IACjD,SAAS,IAAI,MAAM,CAAC;IACpB,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACnE,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW;YAAE,OAAO,EAAE,CAAC;QACvE,+GAA+G;QAC/G,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC1F,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpH,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;YAAE,SAAS,GAAG,IAAI,CAAC;QACxC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;oBAC7E,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;wBAAE,OAAO,EAAE,CAAC;oBAC7C,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC5J,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBACxF,MAAM,IAAI,GAAG,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;wBAC5F,IAAI,CAAC,IAAI;4BAAE,OAAO,EAAE,CAAC;wBACrB,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC;oBACrB,CAAC;oBACD,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACjE,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACb,SAAS,IAAI,MAAM,CAAC;IACpB,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,gBAAgB,CAAC;QACrE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,QAAQ,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzF,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,kHAAkH;IAClH,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC9I,MAAM,aAAa,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtH,CAAC,MAAM,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAClJ,MAAM,UAAU,GAAG,OAAO,IAAI,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC9E,CAAC,MAAM,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CACjG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,6FAA6F;IAC7F,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjI,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtD,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACnE,OAAO,OAAO,GAAG,OAAO,IAAI,KAAK,GAAG,KAAK,CAAC;IAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAClB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC;YACpF,OAAO,EAAE,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACxG,SAAS,EAAE,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAC7E,GAAG,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;SAC/H,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,kBAAkB,CAAC,KAAK,CAAC;QAC9B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM;QAC7G,SAAS,EAAE,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;QACxE,aAAa,EAAE,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;QACxF,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS;KAChE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type VideoSession } from "../core/video-session.js";
|
|
1
2
|
import { type TaskFailure, type TaskBilling } from "../core/task-outcome.js";
|
|
2
3
|
import type { Readable } from "node:stream";
|
|
3
4
|
import { z } from "zod";
|
|
@@ -276,6 +277,7 @@ export type GenerateTextParams = PaidOptions & {
|
|
|
276
277
|
};
|
|
277
278
|
export type CreateAgentVideoParams = PaidOptions & {
|
|
278
279
|
product: AgentProduct;
|
|
280
|
+
auto_mode: boolean;
|
|
279
281
|
music_id: number | string;
|
|
280
282
|
prompt?: string;
|
|
281
283
|
start_ms?: number;
|
|
@@ -1079,6 +1081,19 @@ export declare class FreebeatApiClient {
|
|
|
1079
1081
|
generateMusic(params: GenerateMusicParams): Promise<TaskStartResponse>;
|
|
1080
1082
|
agentSessionUrl(product: AgentProduct, flowUuid: string): string;
|
|
1081
1083
|
createAgentVideo(params: CreateAgentVideoParams): Promise<AgentTaskStartResponse | MusicPreparationResponse>;
|
|
1084
|
+
private videoTask;
|
|
1085
|
+
private postVideoAgentMessage;
|
|
1086
|
+
getVideoSession(taskId: string): Promise<VideoSession>;
|
|
1087
|
+
sendVideoAgentMessage(params: {
|
|
1088
|
+
task_id: string;
|
|
1089
|
+
message: string;
|
|
1090
|
+
auto_mode?: boolean;
|
|
1091
|
+
}): Promise<{
|
|
1092
|
+
message: string;
|
|
1093
|
+
auto_mode?: boolean | undefined;
|
|
1094
|
+
task_id: string;
|
|
1095
|
+
delivery: "accepted";
|
|
1096
|
+
}>;
|
|
1082
1097
|
private getAgentTaskStatus;
|
|
1083
1098
|
generateSingingVideo(params: GenerateSingingVideoParams): Promise<TaskStartResponse>;
|
|
1084
1099
|
private prepareLipSyncRequest;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeTaskStatus, upstreamTaskStatusSchema } from "../core/task-status.js";
|
|
2
2
|
import { normalizeCreativeResult } from "../core/task-result.js";
|
|
3
|
+
import { projectVideoSession, record } from "../core/video-session.js";
|
|
3
4
|
import { taskOutcome } from "../core/task-outcome.js";
|
|
4
5
|
import { randomUUID } from "node:crypto";
|
|
5
6
|
import axios from "axios";
|
|
@@ -254,6 +255,19 @@ function agentCreditNoticeText(value, depth = 0) {
|
|
|
254
255
|
}
|
|
255
256
|
return undefined;
|
|
256
257
|
}
|
|
258
|
+
// Only the newest message can be the active run's reply; an older reply's progress belongs to a finished run.
|
|
259
|
+
function agentProgressMessage(messages) {
|
|
260
|
+
const reply = messages.at(-1)?.role === "assistant" ? messages.at(-1) : undefined;
|
|
261
|
+
const data = [...(reply?.parts ?? [])].reverse().find((part) => part.type === "data-stage-progress")?.data;
|
|
262
|
+
const label = typeof data?.label === "string" ? data.label.trim() : "";
|
|
263
|
+
const percent = ["running", "retrying"].includes(String(data?.status)) && typeof data?.progress === "number"
|
|
264
|
+
? ` (${Math.round(data.progress)}% of this step)` : "";
|
|
265
|
+
return [
|
|
266
|
+
"The Freebeat agent is working.",
|
|
267
|
+
label && `Latest step: ${label}${percent}.`,
|
|
268
|
+
"Full videos usually take 15-60 minutes; poll again later.",
|
|
269
|
+
].filter(Boolean).join(" ");
|
|
270
|
+
}
|
|
257
271
|
function musicModelCapabilities(model, pricing) {
|
|
258
272
|
const parameters = pricing.find(group => group.generationType === 7)?.parameters ?? [];
|
|
259
273
|
const parameter = (code) => parameters.find(item => item.code === code);
|
|
@@ -714,37 +728,14 @@ export class FreebeatApiClient {
|
|
|
714
728
|
openWatermark: !params.remove_watermark,
|
|
715
729
|
enablePublic: false,
|
|
716
730
|
resolution,
|
|
717
|
-
autoExecEnabled:
|
|
731
|
+
autoExecEnabled: params.auto_mode,
|
|
718
732
|
type: product.sessionType,
|
|
719
733
|
...product.createFields,
|
|
720
734
|
}, agentSessionSchema, "createAgentVideo");
|
|
721
735
|
const flowUuid = session.flowUuid;
|
|
722
736
|
const sessionUrl = this.agentSessionUrl(params.product, flowUuid);
|
|
723
|
-
const clientRunId = randomUUID();
|
|
724
737
|
try {
|
|
725
|
-
|
|
726
|
-
thread_id: flowUuid,
|
|
727
|
-
message: {
|
|
728
|
-
id: clientRunId,
|
|
729
|
-
role: "user",
|
|
730
|
-
parts: [
|
|
731
|
-
...(params.image_urls ?? []).map((url) => ({
|
|
732
|
-
type: "file",
|
|
733
|
-
mediaType: imageMediaType(url),
|
|
734
|
-
url,
|
|
735
|
-
})),
|
|
736
|
-
{ type: "text", text: prompt },
|
|
737
|
-
],
|
|
738
|
-
},
|
|
739
|
-
business_id: flowUuid,
|
|
740
|
-
multitask_strategy: "enqueue",
|
|
741
|
-
metadata: {
|
|
742
|
-
client_run_id: clientRunId,
|
|
743
|
-
...(params.product === "dance" ? { agent_kind: "dance" } : {}),
|
|
744
|
-
},
|
|
745
|
-
}, { responseType: "stream", headers: { Accept: "text/event-stream, application/json" } });
|
|
746
|
-
// The run is queued server-side; the plugin polls instead of holding the stream open.
|
|
747
|
-
response.data?.destroy?.();
|
|
738
|
+
await this.postVideoAgentMessage(params.product, flowUuid, prompt, params.image_urls);
|
|
748
739
|
}
|
|
749
740
|
catch {
|
|
750
741
|
throw new AppError(`The ${params.product} session was created but the agent start could not be confirmed. Open ${sessionUrl} to continue.`, "API_ERROR");
|
|
@@ -757,6 +748,73 @@ export class FreebeatApiClient {
|
|
|
757
748
|
session_url: sessionUrl,
|
|
758
749
|
};
|
|
759
750
|
}
|
|
751
|
+
videoTask(taskId) {
|
|
752
|
+
const task = decodeCreativeTaskId(taskId);
|
|
753
|
+
if (!task || !Object.hasOwn(AGENT_PRODUCTS, task.kind)) {
|
|
754
|
+
throw new AppError("Use a task_id from generate_music_video, generate_dance_video, or generate_lyric_video.", "INVALID_PARAMS");
|
|
755
|
+
}
|
|
756
|
+
const product = task.kind;
|
|
757
|
+
return { product, threadId: task.rawId, url: `${this.agentEndpoints[product]}/v1/threads/${encodeURIComponent(task.rawId)}` };
|
|
758
|
+
}
|
|
759
|
+
async postVideoAgentMessage(product, threadId, message, imageUrls = []) {
|
|
760
|
+
const clientRunId = randomUUID();
|
|
761
|
+
const response = await this.agentClient.post(`${this.agentEndpoints[product]}/v1/chat`, {
|
|
762
|
+
thread_id: threadId,
|
|
763
|
+
message: { id: clientRunId, role: "user", parts: [
|
|
764
|
+
...imageUrls.map(url => ({ type: "file", mediaType: imageMediaType(url), url })),
|
|
765
|
+
{ type: "text", text: message },
|
|
766
|
+
] },
|
|
767
|
+
business_id: threadId,
|
|
768
|
+
multitask_strategy: "enqueue",
|
|
769
|
+
metadata: { client_run_id: clientRunId, ...(product === "dance" ? { agent_kind: "dance" } : {}) },
|
|
770
|
+
}, { responseType: "stream", headers: { Accept: "text/event-stream, application/json" } });
|
|
771
|
+
// The run persists before the SSE response; disconnecting does not cancel it.
|
|
772
|
+
response.data?.destroy?.();
|
|
773
|
+
}
|
|
774
|
+
async getVideoSession(taskId) {
|
|
775
|
+
const task = this.videoTask(taskId);
|
|
776
|
+
// Like the website, a failed state read (its auto-mode lookup can be down) still shows the conversation and artifacts.
|
|
777
|
+
const [state, messages, assets] = await Promise.all([
|
|
778
|
+
this.agentClient.get(`${task.url}/state`).then(response => response.data, () => ({})),
|
|
779
|
+
this.agentClient.get(`${task.url}/messages`, { params: { limit: 20 } }),
|
|
780
|
+
this.agentClient.get(`${task.url}/assets`),
|
|
781
|
+
]);
|
|
782
|
+
if (!Array.isArray(record(messages.data).messages) || !Array.isArray(record(assets.data).assets)) {
|
|
783
|
+
throw new AppError("Freebeat could not read the video session. Retry get_video_session before sending another message.", "INVALID_RESPONSE");
|
|
784
|
+
}
|
|
785
|
+
return projectVideoSession(taskId, this.agentSessionUrl(task.product, task.threadId), this.agentEndpoints[task.product], state, messages.data, assets.data);
|
|
786
|
+
}
|
|
787
|
+
async sendVideoAgentMessage(params) {
|
|
788
|
+
const task = this.videoTask(params.task_id);
|
|
789
|
+
// Like the website, which locks its chat box while a run is active: a queued message would start paid work nobody reviewed.
|
|
790
|
+
const thread = agentMessagesSchema.safeParse((await this.agentClient.get(`${task.url}/messages`, { params: { limit: 1 } })).data);
|
|
791
|
+
if (!thread.success)
|
|
792
|
+
throw new AppError("Freebeat could not read the video session. Read get_video_session before sending.", "INVALID_RESPONSE");
|
|
793
|
+
if (thread.data.active_run_id) {
|
|
794
|
+
throw new AppError("The agent is still working, so this message was not sent and the auto setting was not changed. Poll get_task_status and send it once the agent is no longer running.", "TASK_NOT_COMPLETED");
|
|
795
|
+
}
|
|
796
|
+
let autoMode;
|
|
797
|
+
if (params.auto_mode !== undefined) {
|
|
798
|
+
const response = await this.agentClient.patch(`${task.url}/auto-mode`, { enabled: params.auto_mode });
|
|
799
|
+
const parsed = z.object({ auto_mode: z.boolean() }).safeParse(response.data);
|
|
800
|
+
if (!parsed.success)
|
|
801
|
+
throw new AppError("Freebeat could not confirm the auto setting. Read get_video_session before continuing.", "INVALID_RESPONSE");
|
|
802
|
+
autoMode = parsed.data.auto_mode;
|
|
803
|
+
}
|
|
804
|
+
try {
|
|
805
|
+
await this.postVideoAgentMessage(task.product, task.threadId, params.message);
|
|
806
|
+
}
|
|
807
|
+
catch (error) {
|
|
808
|
+
if (axios.isAxiosError(error) && error.response?.status === 409) {
|
|
809
|
+
throw new AppError("Freebeat did not accept this message. Read get_video_session before trying again; an optional auto setting may already have changed.", "API_ERROR");
|
|
810
|
+
}
|
|
811
|
+
throw new AppError("Message delivery could not be confirmed. Read get_video_session before resending to avoid duplicate work; an optional auto setting may already have changed.", "API_ERROR");
|
|
812
|
+
}
|
|
813
|
+
return {
|
|
814
|
+
task_id: params.task_id, delivery: "accepted", ...(autoMode === undefined ? {} : { auto_mode: autoMode }),
|
|
815
|
+
message: "Freebeat accepted the message and the agent is starting on it. Poll get_task_status for progress and read get_video_session for the agent's response and current auto setting.",
|
|
816
|
+
};
|
|
817
|
+
}
|
|
760
818
|
async getAgentTaskStatus(product, flowUuid) {
|
|
761
819
|
const config = AGENT_PRODUCTS[product];
|
|
762
820
|
const threadUrl = `${this.agentEndpoints[product]}/v1/threads/${encodeURIComponent(flowUuid)}`;
|
|
@@ -771,12 +829,28 @@ export class FreebeatApiClient {
|
|
|
771
829
|
const threadOutcome = taskOutcome(thread.data);
|
|
772
830
|
Object.assign(base, threadOutcome);
|
|
773
831
|
if (thread.data.active_run_id) {
|
|
774
|
-
return {
|
|
775
|
-
...base,
|
|
776
|
-
status: "running",
|
|
777
|
-
message: "The Freebeat agent is working. Full videos usually take 15-60 minutes; poll again later.",
|
|
778
|
-
};
|
|
832
|
+
return { ...base, status: "running", message: agentProgressMessage(thread.data.messages) };
|
|
779
833
|
}
|
|
834
|
+
const lastAssistant = [...thread.data.messages].reverse().find((message) => message.role === "assistant" && message.parts.some(part => ["data-credit-notice", "data-review-request", "data-assistant-note"].includes(String(part.type)) || (part.type === "text" && typeof part.text === "string" && part.text.trim())));
|
|
835
|
+
const agentWords = (lastAssistant?.parts ?? []).flatMap((part) => {
|
|
836
|
+
const data = record(part.data);
|
|
837
|
+
return part.type === "text" ? [part.text] : part.type === "data-assistant-note" ? [data.text]
|
|
838
|
+
: part.type === "data-review-request" ? [data.title, data.message] : [];
|
|
839
|
+
}).filter((text) => typeof text === "string" && text.trim() !== "").join("\n");
|
|
840
|
+
const waitingForPerson = () => ({
|
|
841
|
+
...base,
|
|
842
|
+
status: "action_required",
|
|
843
|
+
message: [
|
|
844
|
+
"The Freebeat agent is waiting for the person's input; this is not a failure.",
|
|
845
|
+
agentWords,
|
|
846
|
+
"Read get_video_session with this task_id to see the agent's work and request; use send_video_agent_message to answer.",
|
|
847
|
+
].filter(Boolean).join("\n"),
|
|
848
|
+
});
|
|
849
|
+
// A stage awaiting review outranks an older finished film: the person asked for a change and the agent waits on it.
|
|
850
|
+
const stages = await this.agentClient.get(`${threadUrl}/state`)
|
|
851
|
+
.then((response) => record(record(record(response.data).pipeline_state).stages), () => ({}));
|
|
852
|
+
if (Object.values(stages).includes("pending_review"))
|
|
853
|
+
return waitingForPerson();
|
|
780
854
|
const assets = agentAssetListSchema.safeParse((await this.agentClient.get(`${threadUrl}/assets`, { params: { type: config.finalAssetType } })).data);
|
|
781
855
|
if (!assets.success)
|
|
782
856
|
throw new AppError("Unexpected agent assets response.", "INVALID_RESPONSE");
|
|
@@ -847,7 +921,6 @@ export class FreebeatApiClient {
|
|
|
847
921
|
return { ...base, status: "completed", result_payload: JSON.stringify({ video_url: rendered.video_url }) };
|
|
848
922
|
}
|
|
849
923
|
}
|
|
850
|
-
const lastAssistant = [...thread.data.messages].reverse().find((message) => message.role === "assistant" && message.parts.some(part => part.type === "data-credit-notice" || (part.type === "text" && typeof part.text === "string" && part.text.trim())));
|
|
851
924
|
if (!lastAssistant) {
|
|
852
925
|
return {
|
|
853
926
|
...base,
|
|
@@ -856,10 +929,10 @@ export class FreebeatApiClient {
|
|
|
856
929
|
};
|
|
857
930
|
}
|
|
858
931
|
const creditNotice = lastAssistant.parts.find((part) => part.type === "data-credit-notice");
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
932
|
+
const upstream = record(thread.data);
|
|
933
|
+
if (!creditNotice && (upstream.error ?? upstream.errorMsg ?? upstream.errorMessage) === undefined)
|
|
934
|
+
return waitingForPerson();
|
|
935
|
+
const agentMessage = agentWords;
|
|
863
936
|
const noticeData = creditNotice?.data && typeof creditNotice.data === "object" ? creditNotice.data : {};
|
|
864
937
|
const noticeDetail = noticeData.detail && typeof noticeData.detail === "object" ? noticeData.detail : {};
|
|
865
938
|
const noticeMessage = (typeof noticeData.message === "string" ? noticeData.message : undefined)
|
|
@@ -876,7 +949,7 @@ export class FreebeatApiClient {
|
|
|
876
949
|
typeof noticeData.title === "string" ? noticeData.title : undefined,
|
|
877
950
|
noticeMessage,
|
|
878
951
|
agentMessage !== outcome.failure?.reason ? agentMessage : undefined,
|
|
879
|
-
|
|
952
|
+
"Read get_video_session with this task_id to see the agent's work and request; use send_video_agent_message to continue the conversation.",
|
|
880
953
|
].filter(Boolean).join("\n"),
|
|
881
954
|
};
|
|
882
955
|
}
|