将 `tools.ts` 拆分为按功能划分的独立文件,并存放于 `tools/` 目录下,同时更新导入路径;优化 agent 系统提示语,移除冗余的「美图 Agent」前缀。
51 lines
2.7 KiB
TypeScript
51 lines
2.7 KiB
TypeScript
import path from 'path';
|
||
import os from 'os';
|
||
import fs from 'fs';
|
||
import { execSync } from 'child_process';
|
||
import { PIPELINE_SCRIPT, PROJECT_ROOT } from './shared';
|
||
import type { ToolDefinition } from './types';
|
||
|
||
export const createManifest: ToolDefinition = {
|
||
name: 'create_manifest',
|
||
description: '初始化新的 manifest.json,调用 pipeline.js init 创建输出目录和项目骨架。这是视频创作 pipeline 的起点。',
|
||
input_schema: {
|
||
type: 'object',
|
||
properties: {
|
||
accountId: { type: 'string', description: '账号ID,决定模型、参考图等配置来源' },
|
||
mode: { type: 'string', description: '创作模式: single (单图模式) 或 framePair (首尾帧模式)' },
|
||
items: { type: 'string', description: '分镜数据 JSON 数组字符串。每个元素需包含 shotDesc (分镜描述) 和 script (旁白文案),可选 imagePrompt、videoPrompt、directorRef、keyword、duration' },
|
||
imageModel: { type: 'string', description: '生图模型(可选,默认继承账号配置): gemini, mj, gpt-image, kling' },
|
||
videoModel: { type: 'string', description: '视频模型(可选,默认继承账号配置): veo3-fast, veo3-fast-frames, kling, grok' },
|
||
format: { type: 'string', description: '画幅(可选,默认继承账号配置): 9:16, 16:9, 1:1' },
|
||
},
|
||
required: ['accountId', 'mode', 'items'],
|
||
},
|
||
execute: async (params) => {
|
||
const { accountId, mode, items, imageModel, videoModel, format } = params as Record<string, string>;
|
||
// Validate items JSON
|
||
let parsed: unknown;
|
||
try { parsed = JSON.parse(items); } catch { return '错误: items 不是合法的 JSON 字符串'; }
|
||
if (!Array.isArray(parsed) || (parsed as unknown[]).length === 0) return '错误: items 必须是非空 JSON 数组';
|
||
// Write items to temp file to avoid shell escaping issues
|
||
const tmpFile = path.join(os.tmpdir(), `pipeline-items-${Date.now()}.json`);
|
||
fs.writeFileSync(tmpFile, items, 'utf-8');
|
||
try {
|
||
const args = [
|
||
`"${PIPELINE_SCRIPT}"`, 'init',
|
||
`--account "${accountId}"`,
|
||
`--mode ${mode}`,
|
||
`--items-file "${tmpFile}"`,
|
||
imageModel ? `--image-model ${imageModel}` : '',
|
||
videoModel ? `--video-model ${videoModel}` : '',
|
||
format ? `--format ${format}` : '',
|
||
].filter(Boolean).join(' ');
|
||
const output = execSync(`node ${args}`, { cwd: PROJECT_ROOT, encoding: 'utf-8' });
|
||
const match = output.match(/Manifest 已创建: (.+)/);
|
||
const manifestPath = match ? match[1].trim() : '(unable to parse path)';
|
||
return `Manifest 已创建: ${manifestPath}\n\n${output}`;
|
||
} finally {
|
||
try { fs.unlinkSync(tmpFile); } catch { /* ignore */ }
|
||
}
|
||
},
|
||
};
|