R64-R70: 工作台迭代—视频解析执行状态跨刷新/找不到MCP根因修复/全量排查需MCP功能挂connector/刷新功能强制重新获取/自定义选题创作改名原创选题创作+系列UI微调(cdp-verify回归脚本)

This commit is contained in:
maogeigei committed 2026-09-04 17:57:15 +08:00
1 parent b805b77315
commit 1a5d319bfc
17 files changed
+745 -65

No files matched your search

@@ -288,7 +288,10 @@ function wbDb() {
// 创建一次性后台任务(08-31 实测约定:scheduled_at 与 next_run_at 均取 +5s 未来,调度器按 next_run_at 扫描拾取;
// 模型跟随用户最近活跃手动会话选择,兜底 'auto')——逻辑与 /api/run 完全一致,供更新榜单等新入口复用
function createOnceAutomation(name, prompt, skillsArr) {
// 09-04 connectorIdsArr:任务会话要用的「用户连接器」configId 列表(如 ['custom-mcp:myai-mcp-production'])——
// 宿主会话 register(connectorIds) 只注入列出的连接器,空数组=不注入任何连接器(后台任务「找不到 MCP」根因),
// 依赖 MCP 的任务(视频解析等)必须显式挂载;纯脚本类任务(榜单更新)保持 [] 即可
function createOnceAutomation(name, prompt, skillsArr, connectorIdsArr) {
const db = wbDb();
try {
const now = Date.now();
@@ -304,7 +307,7 @@ function createOnceAutomation(name, prompt, skillsArr) {
const modelId = (modelRow && modelRow.model) ? modelRow.model : 'auto';
db.prepare(`INSERT INTO automations (id,name,prompt,status,schedule_type,scheduled_at,next_run_at,rrule,cwds,created_at,updated_at,skills_json,connector_ids_json,model_id,permission_mode,owner_user_id,owner_status)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`)
.run(id, name, prompt, 'ACTIVE', 'once', scheduledAt, nextRunAt, '', JSON.stringify([cwd]), now, now, JSON.stringify(Array.isArray(skillsArr) ? skillsArr : []), '[]', modelId, 'fullAccess', ownerUserId, 'confirmed');
.run(id, name, prompt, 'ACTIVE', 'once', scheduledAt, nextRunAt, '', JSON.stringify([cwd]), now, now, JSON.stringify(Array.isArray(skillsArr) ? skillsArr : []), JSON.stringify(Array.isArray(connectorIdsArr) ? connectorIdsArr : []), modelId, 'fullAccess', ownerUserId, 'confirmed');
return { id };
} finally {
db.close();
@@ -553,20 +556,20 @@ const server = http.createServer((req, res) => {
if (dshGuard()) return;
return dshOk(200, dsh.listRewrites(qInt('videoId', 0)));
}
if (p === '/api/dsh/custom-scripts') { /* 09-02 v25:自定义选题(无视频载体)脚本列表 */
if (p === '/api/dsh/custom-scripts') { /* 09-02 v25:原创选题(无视频载体)脚本列表 */
if (dshGuard()) return;
return dshOk(200, dsh.listCustomScripts({ page: qInt('page', 1), pageSize: qInt('pageSize', 20), search: String(q.get('search') || ''), days: String(q.get('days') || ''), account: String(q.get('account') || '') }));
}
if (p === '/api/dsh/rewrite-stats') { /* 09-02 v25:AI写脚本 tab 徽标计数(参考选题/自定义选题),可传 account 按账号统计 */
if (p === '/api/dsh/rewrite-stats') { /* 09-02 v25:AI写脚本 tab 徽标计数(参考选题/原创选题),可传 account 按账号统计 */
if (dshGuard()) return;
return dshOk(200, dsh.getRewriteStats(String(q.get('account') || '')));
}
if (p === '/api/dsh/custom-script') { /* 自定义选题脚本全文(查看弹窗) */
if (p === '/api/dsh/custom-script') { /* 原创选题脚本全文(查看弹窗) */
if (dshGuard()) return;
try { return dshOk(200, { script: dsh.getCustomScript(qInt('id', 0)) }); }
catch (e) { return sendErr(404, e.message); }
}
if (p === '/api/dsh/script-save' && req.method === 'POST') { /* AI创作任务完成回调写库(参考选题传 videoId;自定义选题省略→video_id 空) */
if (p === '/api/dsh/script-save' && req.method === 'POST') { /* AI创作任务完成回调写库(参考选题传 videoId;原创选题省略→video_id 空) */
if (dshGuard()) return;
let body = '';
req.on('data', (c) => { body += c; if (body.length > 2e6) req.destroy(); });
@@ -654,8 +657,14 @@ const server = http.createServer((req, res) => {
req.on('data', (c) => { body += c; if (body.length > 1e6) req.destroy(); });
req.on('end', () => {
try {
const { prompt, name, skills } = JSON.parse(body || '{}');
const { prompt, name, skills, connectorIds } = JSON.parse(body || '{}');
if (!prompt || typeof prompt !== 'string' || !prompt.trim()) return sendErr(400, 'prompt 不能为空');
// 09-04 连接器级挂载:connector_ids_json 填「用户连接器」configId 数组(如 custom-mcp:myai-mcp-production)。
// 宿主会话 register(connectorIds) 白名单注入;空数组=不注入任何连接器 → 依赖 MCP 的任务会「找不到 MCP」。
// 仅放行合法 configId 形态(connector:/custom-mcp:/裸名),其余丢弃
const connArr = Array.isArray(connectorIds)
? connectorIds.filter((c) => typeof c === 'string' && /^[A-Za-z0-9:_-]{1,120}$/.test(c.trim())).map((c) => c.trim())
: [];
// 09-01 参数级技能挂载:skills_json 是 automations 表原生字段(default '[]'),
// 客户端调度器创建会话时按该字段挂载技能;前端传技能名数组(如 ['短视频工作台'])即完成任务级技能绑定
// 09-03 模型跟随用户选择:原 model_id 钉死 'deepseek-v4-flash'(绕过用户模型选择,全任务跑 flash)。
@@ -696,7 +705,7 @@ const server = http.createServer((req, res) => {
const modelId = (modelRow && modelRow.model) ? modelRow.model : 'auto';
db.prepare(`INSERT INTO automations (id,name,prompt,status,schedule_type,scheduled_at,next_run_at,rrule,cwds,created_at,updated_at,skills_json,connector_ids_json,model_id,permission_mode,owner_user_id,owner_status)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`)
.run(id, name || '工作台任务', finalPrompt, 'ACTIVE', 'once', scheduledAt, nextRunAt, '', JSON.stringify([cwd]), now, now, JSON.stringify(skillsArr), '[]', modelId, 'fullAccess', ownerUserId, 'confirmed');
.run(id, name || '工作台任务', finalPrompt, 'ACTIVE', 'once', scheduledAt, nextRunAt, '', JSON.stringify([cwd]), now, now, JSON.stringify(skillsArr), JSON.stringify(connArr), modelId, 'fullAccess', ownerUserId, 'confirmed');
db.close();
log('已提交 AI 任务: ' + id + (name ? ' (' + name + ')' : ''));
return sendJSON(200, { ok: true, id, message: '任务已提交,请在左侧会话栏查看执行' });