@mindscraft/branch-video-agent-cli 0.3.3 → 0.3.5
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 +42 -26
- package/dist/commands/aiGateway.js +55 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ AIHub 导入公共库示例:
|
|
|
116
116
|
|
|
117
117
|
`character search` 只返回已经人工添加 `accepted_for_reuse` 标签的角色资产;新入库资产默认未验收,需要在角色资产库页面验收后才会被 Agent 二次复用。
|
|
118
118
|
|
|
119
|
-
AI Gateway 图片生成示例:
|
|
119
|
+
AI Gateway 图片生成示例:
|
|
120
120
|
|
|
121
121
|
```powershell
|
|
122
122
|
@'
|
|
@@ -124,40 +124,56 @@ AI Gateway 图片生成示例:
|
|
|
124
124
|
"model": "doubao-seedream-5-0-260128",
|
|
125
125
|
"prompt": "3D 卡通风格,穿白大褂的喵星人科学老师在实验室讲解电路"
|
|
126
126
|
}
|
|
127
|
-
'@ | npm exec --yes --package=@mindscraft/branch-video-agent-cli branch-video-agent -- ai-gateway image-generate -- --raw
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
AI Gateway 视频生成并等待示例:
|
|
131
|
-
|
|
132
|
-
```powershell
|
|
133
|
-
@'
|
|
134
|
-
{
|
|
135
|
-
"model": "doubao-seedance-2-0-260128",
|
|
136
|
-
"input": {
|
|
137
|
-
"prompt": "镜头推进到实验台,卡通猫老师点亮一个小灯泡"
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
'@ | npm exec --yes --package=@mindscraft/branch-video-agent-cli branch-video-agent -- ai-gateway video-create -- --wait --raw
|
|
127
|
+
'@ | npm exec --yes --package=@mindscraft/branch-video-agent-cli branch-video-agent -- ai-gateway image-generate -- --raw
|
|
141
128
|
```
|
|
142
129
|
|
|
143
|
-
AI Gateway
|
|
130
|
+
AI Gateway Banana Pro 同步生成示例(实际模型值为 `gemini-3-pro-image-preview`):
|
|
144
131
|
|
|
145
132
|
```powershell
|
|
146
133
|
@'
|
|
147
134
|
{
|
|
148
|
-
"model": "
|
|
149
|
-
"
|
|
150
|
-
"
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
135
|
+
"model": "gemini-3-pro-image-preview",
|
|
136
|
+
"prompt": "一幅写实风格的山水画,远处有云雾缭绕的山峰",
|
|
137
|
+
"size": "16:9",
|
|
138
|
+
"image_size_ratios": "2K",
|
|
139
|
+
"output_format": "image/png"
|
|
154
140
|
}
|
|
155
|
-
'@ | npm exec --yes --package=@mindscraft/branch-video-agent-cli branch-video-agent -- ai-gateway
|
|
141
|
+
'@ | npm exec --yes --package=@mindscraft/branch-video-agent-cli branch-video-agent -- ai-gateway image-generate -- --raw
|
|
156
142
|
```
|
|
157
143
|
|
|
158
|
-
`
|
|
159
|
-
|
|
160
|
-
|
|
144
|
+
Banana Pro 图片编辑继续使用 `ai-gateway image-edit`,请求体为 JSON,`image` 是 HTTP(S) URL 字符串数组;GPT Image 2 编辑仍使用 multipart 文件描述。Banana Pro 当前只支持同步调用,不使用 `--wait`。响应通常包含 `data[].b64_json`,不要把完整 base64 写进 Agent 回复或持久化日志。
|
|
145
|
+
|
|
146
|
+
AI Gateway 视频生成并等待示例:
|
|
147
|
+
|
|
148
|
+
```powershell
|
|
149
|
+
@'
|
|
150
|
+
{
|
|
151
|
+
"model": "doubao-seedance-2-0-260128",
|
|
152
|
+
"input": {
|
|
153
|
+
"prompt": "镜头推进到实验台,卡通猫老师点亮一个小灯泡"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
'@ | npm exec --yes --package=@mindscraft/branch-video-agent-cli branch-video-agent -- ai-gateway video-create -- --wait --raw
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
AI Gateway Seed Audio 音频生成并等待示例:
|
|
160
|
+
|
|
161
|
+
```powershell
|
|
162
|
+
@'
|
|
163
|
+
{
|
|
164
|
+
"model": "seed-audio-1.0",
|
|
165
|
+
"text_prompt": "温柔的女声朗读:欢迎使用豆包语音合成服务。背景加入轻柔科技感铺底音乐。",
|
|
166
|
+
"audio_config": {
|
|
167
|
+
"format": "mp3",
|
|
168
|
+
"sample_rate": 24000
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
'@ | npm exec --yes --package=@mindscraft/branch-video-agent-cli branch-video-agent -- ai-gateway seed-audio-create -- --wait --raw
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`tts-create` / `tts-get` 是 Seed Audio 的历史兼容别名;新脚本优先使用 `seed-audio-create` / `seed-audio-get`。
|
|
175
|
+
|
|
176
|
+
## 在仓库内构建发布包
|
|
161
177
|
|
|
162
178
|
从仓库根目录执行:
|
|
163
179
|
|
|
@@ -43,6 +43,39 @@ function extractFailureMessage(value) {
|
|
|
43
43
|
|| record.error
|
|
44
44
|
|| 'AI Gateway task failed');
|
|
45
45
|
}
|
|
46
|
+
function isJsonRecord(value) {
|
|
47
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
48
|
+
}
|
|
49
|
+
function isHttpUrl(value) {
|
|
50
|
+
return typeof value === 'string' && /^https?:\/\//i.test(value);
|
|
51
|
+
}
|
|
52
|
+
function extractMusicAudioUrl(value) {
|
|
53
|
+
if (Array.isArray(value)) {
|
|
54
|
+
for (const item of value) {
|
|
55
|
+
const audioUrl = extractMusicAudioUrl(item);
|
|
56
|
+
if (audioUrl)
|
|
57
|
+
return audioUrl;
|
|
58
|
+
}
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
if (!isJsonRecord(value))
|
|
62
|
+
return '';
|
|
63
|
+
for (const key of ['audioUrl', 'streamAudioUrl']) {
|
|
64
|
+
if (isHttpUrl(value[key]))
|
|
65
|
+
return String(value[key]);
|
|
66
|
+
}
|
|
67
|
+
for (const item of Object.values(value)) {
|
|
68
|
+
const audioUrl = extractMusicAudioUrl(item);
|
|
69
|
+
if (audioUrl)
|
|
70
|
+
return audioUrl;
|
|
71
|
+
}
|
|
72
|
+
return '';
|
|
73
|
+
}
|
|
74
|
+
function withStableMusicAudioUrl(data, audioUrl) {
|
|
75
|
+
return isJsonRecord(data)
|
|
76
|
+
? { ...data, audioUrl }
|
|
77
|
+
: { status: data, audioUrl };
|
|
78
|
+
}
|
|
46
79
|
async function waitForGatewayTask(context, submit, poll) {
|
|
47
80
|
const startedAt = context.runtime.now();
|
|
48
81
|
while (context.runtime.now() - startedAt <= context.flags.timeoutMs) {
|
|
@@ -65,6 +98,8 @@ async function waitForGatewayTask(context, submit, poll) {
|
|
|
65
98
|
throw new CliCommandError('AI Gateway wait timed out', 'TIMEOUT', { submit });
|
|
66
99
|
}
|
|
67
100
|
function normalizeImageEditPayload(payload) {
|
|
101
|
+
if (payload.model === 'gemini-3-pro-image-preview')
|
|
102
|
+
return payload;
|
|
68
103
|
if (payload.fields || payload.files)
|
|
69
104
|
return payload;
|
|
70
105
|
const files = {};
|
|
@@ -191,7 +226,18 @@ export const aiGatewayCommands = {
|
|
|
191
226
|
}
|
|
192
227
|
const taskId = extractTaskId(result.data);
|
|
193
228
|
const queryOperation = normalizeOperation(getOptionalString(context.payload, 'queryOperation') || inferMusicQueryOperation(operation));
|
|
194
|
-
|
|
229
|
+
const waitResult = await waitForGatewayTask(context, result.data, () => getMusicStatus(context, queryOperation, taskId));
|
|
230
|
+
if (queryOperation !== 'query')
|
|
231
|
+
return waitResult;
|
|
232
|
+
const statusData = isJsonRecord(waitResult.data) ? waitResult.data.status : undefined;
|
|
233
|
+
const audioUrl = extractMusicAudioUrl(statusData);
|
|
234
|
+
if (!audioUrl) {
|
|
235
|
+
throw new CliCommandError('AI Gateway music task completed without an audio URL', 'VALIDATION_ERROR', waitResult.data, waitResult.requestId || null);
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
...waitResult,
|
|
239
|
+
data: withStableMusicAudioUrl(waitResult.data, audioUrl),
|
|
240
|
+
};
|
|
195
241
|
},
|
|
196
242
|
'music-get': async ({ client, payload }) => {
|
|
197
243
|
const id = getRequiredString(payload, 'id');
|
|
@@ -200,6 +246,14 @@ export const aiGatewayCommands = {
|
|
|
200
246
|
method: 'GET',
|
|
201
247
|
query: { id },
|
|
202
248
|
});
|
|
249
|
+
const status = extractStatus(result.data);
|
|
250
|
+
const audioUrl = extractMusicAudioUrl(result.data);
|
|
251
|
+
if (gatewaySuccessStatuses.has(status) && operation === 'query' && !audioUrl) {
|
|
252
|
+
throw new CliCommandError('AI Gateway music task completed without an audio URL', 'VALIDATION_ERROR', result.data, result.requestId);
|
|
253
|
+
}
|
|
254
|
+
if (audioUrl) {
|
|
255
|
+
return { data: withStableMusicAudioUrl(result.data, audioUrl), requestId: result.requestId };
|
|
256
|
+
}
|
|
203
257
|
return { data: result.data, requestId: result.requestId };
|
|
204
258
|
},
|
|
205
259
|
};
|