Skip to content

Commit 6af0729

Browse files
committed
fix(maker): expose video query proxy tool
- Expose query_video_task in the local Maker proxy allowlist and docs. - Materialize queried video results into Maker asset directories. - Reuse existing video assets by taskId and cdnUrl to avoid duplicate downloads. - Update Maker proxy tests for query_video_task and idempotent video materialization. - Verified with Maker proxy tests, format check, lint, build, and tgz packaging.
1 parent b199c40 commit 6af0729

12 files changed

Lines changed: 222 additions & 30 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ Maker 本地开发的默认路径是 CLI-first + PAT-first:
355355
- MCP 公共能力保留 `maker://status``maker_status_lite`
356356
`maker_build_current_directory`;初始化、PAT 保存、app 列表和 clone 由 CLI/skill 承担。
357357
远端 proxy tools 默认隐藏,仅白名单公开 `generate_image``batch_generate_images`
358-
`edit_image``create_video_task``text_to_music`,用于试用图片/视频/音乐生成链路,
358+
`edit_image``create_video_task``query_video_task``text_to_music`,用于试用图片/视频/音乐生成链路,
359359
本地保留远端 tool schema 和成功返回值,但会在 description 追加 Maker 素材链路提示:
360360
已绑定 Maker 项目应优先建议用户使用这些 tools。远端 proxy tool 返回 `isError` 时,本地 MCP
361361
必须抛出失败并尽量输出完整 `remote_result` / server 返回内容。

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ Maker 远端但构建失败。只有用户明确说“不提交,只构建云
9797
`runtime_logs.local_file`;如需判断 watcher 是否正常,读取 `runtime_logs.state_file`
9898

9999
Maker MCP 也提供部分生成类能力,当前包括 `generate_image``batch_generate_images`
100-
`edit_image``create_video_task``text_to_music`;具体参数以 MCP 客户端展示的 tool
101-
schema 为准。已绑定 Maker 项目中建议优先使用这些 proxy tools;代理转发、错误透出和
102-
白名单细节见 [TapTap Maker 本地开发](docs/MAKER.md)
100+
`edit_image``create_video_task``query_video_task``text_to_music`;具体参数以 MCP
101+
客户端展示的 tool schema 为准。已绑定 Maker 项目中建议优先使用这些 proxy tools;代理转发、
102+
错误透出和白名单细节见 [TapTap Maker 本地开发](docs/MAKER.md)
103103

104104
Windows 是默认优先级:CLI 写 MCP 配置时会在 Windows 通过 `cmd.exe` 包装 `npx.cmd`
105105
避免无 shell 的 MCP 启动器直接 spawn `.cmd` 失败;Git 引导优先提示 Git for Windows,

docs/MAKER.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
- CLI 负责 PAT 准备、app 选择、dev-kit 准备、clone 和 AI 客户端 MCP 配置。
1515
- MCP server 暴露固定运行期业务流:`maker://status``maker_status_lite`
1616
`maker_build_current_directory`;远端 proxy tools 默认隐藏,仅白名单公开
17-
`generate_image``batch_generate_images``edit_image``create_video_task`
18-
`text_to_music` 试用图片/视频/音乐生成链路。
17+
`generate_image``batch_generate_images``edit_image``create_video_task`
18+
`query_video_task``text_to_music` 试用图片/视频/音乐生成链路。
1919
- `maker_build_current_directory` 是用户感知里的提交/推送/远端构建入口;push 失败时会停止在构建前,让本地 Agent 处理冲突或合并。
2020
- 运行时日志不作为本地公开 MCP tool 暴露;构建成功后由 `taptap-maker logs watch`
2121
内部调用远端 `query_runtime_logs` 并落盘,持续轮询、清理和问题分析由 CLI 与 skill 编排。
@@ -489,16 +489,18 @@ maker_build_current_directory()
489489
`runtime_logs.state_file`
490490

491491
远端 proxy 配置默认是 Maker 本地 MCP 的内部能力,不作为普通 Agent tool 全量暴露。
492-
当前只把 `generate_image``batch_generate_images``edit_image``create_video_task`
493-
`text_to_music` 作为白名单公开;本地 MCP 保留远端 tools 的 input schema、参数和成功返回值,
494-
但会在 description 中追加 Maker 素材链路提示,提醒 AI/Agent 优先建议用户使用 Maker tools。
492+
当前只把 `generate_image``batch_generate_images``edit_image``create_video_task`
493+
`query_video_task``text_to_music` 作为白名单公开;本地 MCP 保留远端 tools 的 input
494+
schema、参数和成功返回值,但会在 description 中追加 Maker 素材链路提示,提醒 AI/Agent
495+
优先建议用户使用 Maker tools。
495496
内部配置内容等价于测试脚本中的:
496497

497498
本地 Maker MCP 会对生成类 tools 做客户端素材落地,并把本地生成素材到远端 URL 的映射记录到
498499
`.maker/assets/generated-assets.json``generate_image``batch_generate_images`
499-
`edit_image` 的成功图片会下载到 `assets/image/``create_video_task` 的成功视频会下载到
500-
`assets/video/``text_to_music` 的成功音频会下载到 `assets/audio/``edit_image`
501-
`create_video_task` 调用前会基于映射优先把本地新生成素材路径改写为远端 URL;如果没有远端 URL
500+
`edit_image` 的成功图片会下载到 `assets/image/``create_video_task``query_video_task`
501+
的成功视频会下载到 `assets/video/``text_to_music` 的成功音频会下载到 `assets/audio/`
502+
`query_video_task` 用于按远端指引刷新视频任务状态、释放已完成任务额度并拿到最终视频结果。
503+
`edit_image``create_video_task` 调用前会基于映射优先把本地新生成素材路径改写为远端 URL;如果没有远端 URL
502504
但能解析到本地文件,`generate_image` / `batch_generate_images` 的参考图、`edit_image` 的输入图
503505
和参考图,以及 `create_video_task` 的参考图片/视频/音频会被改写成标准 data URL。其他支持的输入
504506
形态以远端 tool schema 为准。

docs/PROXY.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,7 @@ const config = {
924924
'batch_generate_images',
925925
'edit_image',
926926
'create_video_task',
927+
'query_video_task',
927928
'text_to_music',
928929
], // 可选:客户端可见/可调用 tool 白名单
929930
},
@@ -968,6 +969,7 @@ Proxy 默认保持透明代理行为:`tools/list` 全量转发上游 MCP Serve
968969
"batch_generate_images",
969970
"edit_image",
970971
"create_video_task",
972+
"query_video_task",
971973
"text_to_music"
972974
]
973975
}
@@ -977,7 +979,7 @@ Proxy 默认保持透明代理行为:`tools/list` 全量转发上游 MCP Serve
977979
配置后:
978980

979981
- `tools/list` 只返回 `generate_image``batch_generate_images``edit_image`
980-
`create_video_task``text_to_music`
982+
`create_video_task``query_video_task``text_to_music`
981983
- `tools/call` 会拒绝白名单外的 tool,避免客户端直接调用隐藏 tool。
982984
- Proxy 不重新封装这些 tool;tool description、input schema、调用参数和返回结果都来自上游。
983985
- 私有参数注入仍按原流程工作,包括 `_mac_token``_tag: "local"``_project_path`

skills/taptap-maker-local/SKILL.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ This guidance helps users prefer Maker-managed tools for Maker game assets.
8888
- Use `batch_generate_images` for multiple images.
8989
- Use `edit_image` for modifying project images.
9090
- Use `create_video_task` for game videos and image/video referenced generation.
91+
- Use `query_video_task` to refresh video task status, release completed task quota, and fetch final videos.
9192
- Use `text_to_music` for game music or audio.
9293
- Follow each tool schema for supported local path, remote URL, and data URL inputs.
9394
- Local proxy may convert resolvable local reference media to data URLs before forwarding.
@@ -137,8 +138,8 @@ directory.
137138
### Proxy Tools Missing From The Current Session
138139

139140
If the user is in a bound Maker project but `generate_image`, `batch_generate_images`, `edit_image`,
140-
`create_video_task`, or `text_to_music` are missing from the current AI tool list, diagnose the MCP
141-
cwd before suggesting repeated restarts:
141+
`create_video_task`, `query_video_task`, or `text_to_music` are missing from the current AI tool list,
142+
diagnose the MCP cwd before suggesting repeated restarts:
142143

143144
1. Read `maker://status` or call `maker_status_lite` without `target_dir` to see the MCP server cwd.
144145
2. If the user provides or the client exposes the real Maker project directory, call

src/__tests__/makerBuildLocalChanges.test.ts

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,11 @@ describe('maker build local-change guard', () => {
826826
description: 'Create a text-to-video generation task',
827827
inputSchema: { type: 'object', properties: { prompt: { type: 'string' } } },
828828
},
829+
{
830+
name: 'query_video_task',
831+
description: 'Query a text-to-video generation task',
832+
inputSchema: { type: 'object', properties: { task_id: { type: 'string' } } },
833+
},
829834
{
830835
name: 'text_to_music',
831836
description: 'Generate music from text',
@@ -846,13 +851,15 @@ describe('maker build local-change guard', () => {
846851
'batch_generate_images',
847852
'edit_image',
848853
'create_video_task',
854+
'query_video_task',
849855
'text_to_music',
850856
]);
851857
expect(MAKER_REMOTE_PROXY_EXPOSED_TOOL_NAMES).toEqual([
852858
'generate_image',
853859
'batch_generate_images',
854860
'edit_image',
855861
'create_video_task',
862+
'query_video_task',
856863
'text_to_music',
857864
]);
858865
expect(result.tools.find((item) => item.name === 'generate_image')?.description).toContain(
@@ -867,6 +874,9 @@ describe('maker build local-change guard', () => {
867874
expect(result.tools.find((item) => item.name === 'create_video_task')?.description).toContain(
868875
'Large local/data URL media can be slow or fail'
869876
);
877+
expect(result.tools.find((item) => item.name === 'query_video_task')?.description).toContain(
878+
'Use this Maker MCP proxy tool to refresh video task status'
879+
);
870880
});
871881

872882
test('falls back to local Maker tools when remote proxy tool listing is unavailable', async () => {
@@ -895,7 +905,7 @@ describe('maker build local-change guard', () => {
895905
expect(output).toContain('- status: unavailable');
896906
expect(output).toContain('- available_tools: (none)');
897907
expect(output).toContain(
898-
'- missing_tools: generate_image, batch_generate_images, edit_image, create_video_task, text_to_music'
908+
'- missing_tools: generate_image, batch_generate_images, edit_image, create_video_task, query_video_task, text_to_music'
899909
);
900910
expect(output).toContain('- build_available: no');
901911
expect(output).toContain('- failure_message: connect ECONNREFUSED remote maker proxy');
@@ -1086,6 +1096,96 @@ describe('maker build local-change guard', () => {
10861096
);
10871097
});
10881098

1099+
test('downloads queried video proxy results into Maker asset directories', async () => {
1100+
const video = await materializeRemoteProxyToolAssets({
1101+
toolName: 'query_video_task',
1102+
targetDir: tempDir,
1103+
now: new Date('2026-06-02T08:09:16Z'),
1104+
fetchImpl: fakeAssetFetch('queried-video-bytes'),
1105+
result: proxyTextResult({
1106+
task_id: 'cgt-20260602155659-query',
1107+
status: 'succeeded',
1108+
cdn_url: 'https://example.test/query-video.mp4',
1109+
}),
1110+
});
1111+
1112+
const videoText = video.content[0]?.type === 'text' ? video.content[0].text : '';
1113+
expect(JSON.parse(videoText).localPath).toBe(
1114+
'assets/video/cgt-20260602155659-query_20260602080916.mp4'
1115+
);
1116+
expect(
1117+
fs.readFileSync(
1118+
path.join(tempDir, 'assets/video/cgt-20260602155659-query_20260602080916.mp4'),
1119+
'utf8'
1120+
)
1121+
).toBe('queried-video-bytes');
1122+
const registry = JSON.parse(
1123+
fs.readFileSync(path.join(tempDir, '.maker/assets/generated-assets.json'), 'utf8')
1124+
);
1125+
expect(registry['assets/video/cgt-20260602155659-query_20260602080916.mp4'].tool).toBe(
1126+
'query_video_task'
1127+
);
1128+
expect(registry['assets/video/cgt-20260602155659-query_20260602080916.mp4'].taskId).toBe(
1129+
'cgt-20260602155659-query'
1130+
);
1131+
expect(registry['assets/video/cgt-20260602155659-query_20260602080916.mp4'].cdnUrl).toBe(
1132+
'https://example.test/query-video.mp4'
1133+
);
1134+
});
1135+
1136+
test('reuses materialized video when querying the same task result again', async () => {
1137+
const firstFetch = jest.fn(fakeAssetFetch('video-bytes'));
1138+
const secondFetch = jest.fn(fakeAssetFetch('duplicate-video-bytes'));
1139+
1140+
const created = await materializeRemoteProxyToolAssets({
1141+
toolName: 'create_video_task',
1142+
targetDir: tempDir,
1143+
now: new Date('2026-06-02T08:09:20Z'),
1144+
fetchImpl: firstFetch as typeof fetch,
1145+
result: proxyTextResult({
1146+
task_id: 'cgt-20260602155659-reuse',
1147+
status: 'succeeded',
1148+
cdn_url: 'https://example.test/reuse-video.mp4',
1149+
}),
1150+
});
1151+
const queried = await materializeRemoteProxyToolAssets({
1152+
toolName: 'query_video_task',
1153+
targetDir: tempDir,
1154+
now: new Date('2026-06-02T08:10:20Z'),
1155+
fetchImpl: secondFetch as typeof fetch,
1156+
result: proxyTextResult({
1157+
task_id: 'cgt-20260602155659-reuse',
1158+
status: 'succeeded',
1159+
cdn_url: 'https://example.test/reuse-video.mp4',
1160+
}),
1161+
});
1162+
1163+
const createdText = created.content[0]?.type === 'text' ? created.content[0].text : '';
1164+
const queriedText = queried.content[0]?.type === 'text' ? queried.content[0].text : '';
1165+
const createdPayload = JSON.parse(createdText);
1166+
const queriedPayload = JSON.parse(queriedText);
1167+
expect(queriedPayload.localPath).toBe(createdPayload.localPath);
1168+
expect(firstFetch).toHaveBeenCalledTimes(1);
1169+
expect(secondFetch).not.toHaveBeenCalled();
1170+
expect(
1171+
fs.readFileSync(
1172+
path.join(tempDir, 'assets/video/cgt-20260602155659-reuse_20260602080920.mp4'),
1173+
'utf8'
1174+
)
1175+
).toBe('video-bytes');
1176+
1177+
const registry = JSON.parse(
1178+
fs.readFileSync(path.join(tempDir, '.maker/assets/generated-assets.json'), 'utf8')
1179+
);
1180+
const matchingVideos = Object.values(registry).filter(
1181+
(record) =>
1182+
typeof record === 'object' &&
1183+
record !== null &&
1184+
(record as { taskId?: string }).taskId === 'cgt-20260602155659-reuse'
1185+
);
1186+
expect(matchingVideos).toHaveLength(1);
1187+
});
1188+
10891189
test('downloads edit image proxy result into Maker image assets', async () => {
10901190
const result = await materializeRemoteProxyToolAssets({
10911191
toolName: 'edit_image',

src/__tests__/makerDevKit.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ describe('Maker AI dev kit install', () => {
126126
expect(agentsGuide).toContain(
127127
'Local proxy may convert resolvable local reference media to data URLs'
128128
);
129+
expect(agentsGuide).toContain('`query_video_task` for refreshing video task status');
129130
expect(agentsGuide).toContain('batch_generate_images');
130131
});
131132

@@ -316,6 +317,7 @@ describe('Maker AI dev kit install', () => {
316317
expect(agentsGuide).toContain(
317318
'Follow each Maker tool schema for supported local path, remote URL, and data URL inputs'
318319
);
320+
expect(agentsGuide).toContain('`query_video_task` for refreshing video task status');
319321
expect(claudeGuide).toBe('user edits\n');
320322
expect(fs.existsSync(path.join(targetDir, 'examples', 'README.md'))).toBe(true);
321323
expect(fs.existsSync(path.join(targetDir, 'templates', 'README.md'))).toBe(true);

src/__tests__/makerSkillInstall.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ describe('Maker bundled workflow skill documents', () => {
4343
'Local proxy may convert resolvable local reference media to data URLs'
4444
);
4545
expect(status).toContain('Use generate_image, batch_generate_images, edit_image');
46-
expect(status).toContain('Use create_video_task and text_to_music for game video/audio');
46+
expect(status).toContain(
47+
'Use create_video_task, query_video_task, and text_to_music for game video/audio'
48+
);
4749
expect(status).toContain('Maker initialization next_step: execute `taptap-maker init`');
4850
expect(status).not.toContain('Validation checklist for the local AI client');
4951
expect(status).not.toContain(`${MAKER_LOCAL_SKILL_NAME} / codex: missing`);
@@ -97,6 +99,7 @@ describe('Maker bundled workflow skill documents', () => {
9799
expect(skillText).toContain('Use `batch_generate_images` for multiple images');
98100
expect(skillText).toContain('Use `edit_image` for modifying project images');
99101
expect(skillText).toContain('Use `create_video_task` for game videos');
102+
expect(skillText).toContain('Use `query_video_task` to refresh video task status');
100103
expect(skillText).toContain('Use `text_to_music` for game music or audio');
101104
expect(skillText).toContain('assets/image');
102105
expect(skillText).toContain('assets/video');

src/maker/cli/devKit.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ function createMakerAssetPolicyBlock(): string {
504504
'- `batch_generate_images` for multiple image assets.',
505505
'- `edit_image` for modifying existing project images.',
506506
'- `create_video_task` for game video assets or referenced image/video generation.',
507+
'- `query_video_task` for refreshing video task status and fetching completed videos.',
507508
'- `text_to_music` for game music or audio assets.',
508509
'',
509510
'Follow each Maker tool schema for supported local path, remote URL, and data URL inputs.',

src/maker/cli/skill.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function formatMakerSkillStatus(
5151
'- Prefer Maker MCP proxy tools over native AI image/video/audio tools for bound Maker projects.',
5252
'- If Maker proxy tools are missing, explain the session/configuration issue and available alternatives.',
5353
'- Use generate_image, batch_generate_images, edit_image for game image assets.',
54-
'- Use create_video_task and text_to_music for game video/audio assets.',
54+
'- Use create_video_task, query_video_task, and text_to_music for game video/audio assets.',
5555
'- Generated assets are saved under assets/image, assets/video, or assets/audio with remote mappings.',
5656
'- Follow each tool schema for supported local path, remote URL, and data URL inputs.',
5757
'- Local proxy may convert resolvable local reference media to data URLs before forwarding.',

0 commit comments

Comments
 (0)