AI会话任务修复:P1 review状态独立映射+前端待确认提示,P2 移除next_run_at列+删除firePrompt死代码
This commit is contained in:
1 parent
c5678797b2
commit
d1fa66c865
4 files changed
+20
-28
No files matched your search
@@ -443,3 +443,12 @@
|
||||
## 俊希用例收尾:验收表标注 + 提交(17:32)
|
||||
- 用例文档验收汇总表 TC-09 行标注「✅ 界面模拟点击已实测 PASS(安全模式)」,真实触发任务需 `--confirm`
|
||||
- 提交链:86ca4ca(初版用例)→ f320eb4(数据判定+脚本)→ 30fff47(日志)→ ffbdc87(验收表标注);已 push origin main,HEAD=ffbdc87 与远程一致
|
||||
|
||||
## AI会话任务链路审计 + P1/P2 修复(17:35-17:50)
|
||||
- 用户要求:①先检查所有功能调用 AI 会话任务的代码是否正确;②P1 P2 需要修复;③核对「AI 任务执行时对应按钮是否处于处理中状态」的状态代码
|
||||
- **审计结论(链路整体正确)**:后端 3 接口(/api/run POST 写 automations、/api/run/status GET 轮询、/api/ai/topics AI选题)+ 前端 executeTask/confirmRun/confirmSaveAccount/confirmAiScript 4 函数 + 7 个调用点(账号列表 AI写脚本/周榜分析/首页关注/账号详情改写+提炼/改写页/分镜生成/复盘评分)逐字段核对;automations 写入与既有任务一致(model=deepseek-v4-flash、permission_mode=fullAccess、owner_status=confirmed、once+now、cwds=D:/AgentSkill/mcn-workshop)
|
||||
- **P1 修复(假等待)**:实测「导入指令」任务 status=PENDING_REVIEW、result_success=0、thread_title=`Automation prompt interrupted: user_cancel`(被中断/待确认)→ server.js `/api/run/status` 将 PENDING_REVIEW 从 pending 拆为独立 `review` 状态;app.js executeTask 新增 `finished` 标志 + review 分支(toast「⏸ 任务待确认,请到左侧会话栏确认执行」+ 停止轮询)+ 30min 超时提示「⏳ 任务仍在执行,请到左侧会话栏查看进度」
|
||||
- **P2 修复两处**:①server.js `/api/run` INSERT 去掉 next_run_at 列(原写 Date.now() 毫秒,与既有任务全 None 不符,执行器用 scheduled_at/created_at),17 列→16 列;②data-pages.js 删除 firePrompt 死代码(L49-65,无调用者,executeTask 已取代)
|
||||
- **按钮处理中状态核对(正确)**:executeTask 内 btn.disabled=true + innerHTML='执行中…' + classList.add('btn-busy');失败/完成/超时/review 均 restore(disabled=false + 原 innerHTML + 移除 btn-busy)→ 无遗漏
|
||||
- **验证通过(17:47)**:新服务启动(node PID 34480,HTTP 200);`/api/run/status?id=automation-1787881991955` 返回 `state:"review"`(修复前映射 pending)→ P1 生效;三文件语法检查通过
|
||||
- git:本地 commit 本轮修复(按新策略暂不 push,攒到半天统一推)
|
||||
@@ -38,6 +38,7 @@ async function executeTask(opts) {
|
||||
const restore = () => { if (btn) { btn.disabled = false; btn.innerHTML = oldText; btn.classList.remove('btn-busy'); } };
|
||||
if (btn) { btn.disabled = true; btn.innerHTML = '执行中…'; btn.classList.add('btn-busy'); }
|
||||
let taskId = null;
|
||||
let finished = false;
|
||||
try {
|
||||
const d = await api('/api/run', {
|
||||
method: 'POST',
|
||||
@@ -58,12 +59,14 @@ async function executeTask(opts) {
|
||||
await new Promise((r) => setTimeout(r, 5000));
|
||||
let s = null;
|
||||
try { s = await api('/api/run/status?id=' + encodeURIComponent(taskId)); } catch (e) { continue; }
|
||||
if (!s || s.state === 'notfound') break;
|
||||
if (s.state === 'done') { showToast('✅ 任务执行完成,页面已自动刷新'); refreshCurrentPage(); break; }
|
||||
if (s.state === 'error') { showToast('❌ 任务执行失败' + (s.error ? ':' + s.error : '')); break; }
|
||||
if (!s || s.state === 'notfound') { finished = true; break; }
|
||||
if (s.state === 'done') { finished = true; showToast('✅ 任务执行完成,页面已自动刷新'); refreshCurrentPage(); break; }
|
||||
if (s.state === 'error') { finished = true; showToast('❌ 任务执行失败' + (s.error ? ':' + s.error : '')); break; }
|
||||
if (s.state === 'review') { finished = true; showToast('⏸ 任务待确认,请到左侧会话栏确认执行'); break; }
|
||||
// queued / pending / running → 继续等待
|
||||
}
|
||||
restore();
|
||||
if (!finished) showToast('⏳ 任务仍在执行,请到左侧会话栏查看进度');
|
||||
}
|
||||
|
||||
// 通用确认弹窗:确认后执行 AI 任务(opts: title/desc/target/url/prompt/label/btn/afterText)
|
||||
|
||||
@@ -44,26 +44,6 @@ function bindBack(container) {
|
||||
}));
|
||||
}
|
||||
|
||||
/* 触发 AI 任务:提交 WorkBuddy Automation 一次性任务,WorkBuddy 自动执行,左侧会话栏可见 */
|
||||
let _lastFireTs = 0;
|
||||
async function firePrompt(prompt, label) {
|
||||
const nowTs = Date.now();
|
||||
if (nowTs - _lastFireTs < 5000) { showToast('⏳ 任务刚提交,请在左侧会话栏查看执行'); return false; }
|
||||
_lastFireTs = nowTs;
|
||||
try {
|
||||
const d = await api('/api/run', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ prompt, name: label || '工作台任务' }),
|
||||
});
|
||||
showToast('✅ ' + (d.message || '任务已提交,请在左侧会话栏查看执行'));
|
||||
return true;
|
||||
} catch (e) {
|
||||
showToast('❌ 任务提交失败: ' + e.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* AI写脚本 确认弹窗:按账号是否有设定动态文案;选题输入区(手输 / AI 结合人设生成)→ 确认后执行创作任务 */
|
||||
async function confirmAiScript(accountName, btn) {
|
||||
// 判断账号是否有有效设定(persona 非空且非测试占位):有 →「基于当前账号设定」,无 →「先进行账号设定分析」
|
||||
|
||||
@@ -371,9 +371,9 @@ const server = http.createServer((req, res) => {
|
||||
const scheduledAt = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
||||
const uidRow = db.prepare("SELECT user_id FROM sessions WHERE user_id IS NOT NULL AND user_id <> '' ORDER BY created_at DESC LIMIT 1").get();
|
||||
const ownerUserId = uidRow ? uidRow.user_id : '';
|
||||
db.prepare(`INSERT INTO automations (id,name,prompt,status,schedule_type,next_run_at,scheduled_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.trim(), 'ACTIVE', 'once', now, scheduledAt, '', JSON.stringify([cwd]), now, now, '[]', '[]', 'deepseek-v4-flash', 'fullAccess', ownerUserId, 'confirmed');
|
||||
db.prepare(`INSERT INTO automations (id,name,prompt,status,schedule_type,scheduled_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.trim(), 'ACTIVE', 'once', scheduledAt, '', JSON.stringify([cwd]), now, now, '[]', '[]', 'deepseek-v4-flash', 'fullAccess', ownerUserId, 'confirmed');
|
||||
db.close();
|
||||
log('已提交 AI 任务: ' + id + (name ? ' (' + name + ')' : ''));
|
||||
return sendJSON(200, { ok: true, id, message: '任务已提交,请在左侧会话栏查看执行' });
|
||||
@@ -401,10 +401,10 @@ const server = http.createServer((req, res) => {
|
||||
else if (runs) {
|
||||
const s = String(runs.status || '').toUpperCase();
|
||||
if (s === 'IN_PROGRESS') state = 'running';
|
||||
else if (s === 'PENDING_REVIEW') state = 'pending';
|
||||
else if (s === 'PENDING_REVIEW') state = 'review'; // 任务停在「待用户确认/已中断」,前端应提示而非假装执行中
|
||||
else if (['DONE', 'COMPLETED', 'SUCCESS', 'FINISHED'].includes(s)) state = 'done';
|
||||
else if (['ERROR', 'CANCELLED', 'FAILED', 'INTERRUPTED'].includes(s)) state = 'error';
|
||||
else state = 'pending';
|
||||
else state = 'pending'; // ACCEPTED / QUEUED / PENDING 等 = 排队等待执行
|
||||
}
|
||||
return sendJSON(200, { ok: true, id, state, error: (st && st.last_error) || null });
|
||||
} catch (e) {
|
||||
|
||||
Reference in new issue
Block a user