#!/usr/bin/env node /** * 验证容器是否已上报会话级 `task` 字段(2026-11-11) * * 用途:App 顶栏要显示「本会话在做什么」,依赖 `currentSessions[].task`。 * 这个脚本直接回读云端,比看容器自述可靠。 * * 用法:node scripts/verify-session-task.mjs */ import { readFileSync } from 'node:fs'; import { homedir } from 'node:os'; import { join } from 'node:path'; const F = 'https://server.fmode.cn/api/functions'; const AGENT = 'agent-node-lj-test'; const tok = JSON.parse(readFileSync(join(homedir(), '.fmode/config/user.json'), 'utf8')).sessionToken; const r = await fetch(F, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'xlosi3m46q', token: tok, params: { agentId: AGENT } }), }); const j = await r.json(); const a = j.agent ?? j.result ?? j; const ex = typeof a.extra === 'string' ? JSON.parse(a.extra) : a.extra; const list = ex?.currentSessions ?? []; console.log('=== 容器上报的 currentSessions ===\n'); if (!list.length) { console.log('⚠️ 列表为空 —— 容器可能没有活动会话,先发一条消息再跑本脚本'); process.exit(1); } for (const s of list) { console.log(` status = ${s.status}`); console.log(` key = ${s.sessionKey}`); console.log(` userId = ${s.userId ?? '(无)'}`); console.log(` task = ${s.task ?? '(无)'}`); console.log(` 字段 = ${Object.keys(s).sort().join(', ')}`); console.log(''); } console.log('=== 判定 ==='); const hasField = list.some((s) => 'task' in s); const running = list.filter((s) => s.status === 'running'); const runningWithTask = running.filter((s) => typeof s.task === 'string' && s.task.trim()); console.log(`有 task 字段的条目:${list.filter((s) => 'task' in s).length} / ${list.length}`); console.log(`running 条目:${running.length},其中带 task:${runningWithTask.length}`); if (!hasField) { console.log('\n❌ 未发现 task 字段 —— 容器还没改完,或没重启 gateway'); process.exit(1); } if (running.length && !runningWithTask.length) { console.log('\n⚠️ 有 running 会话但没带 task —— 容器需要修'); process.exit(1); } console.log('\n✅ task 字段已就绪,App 顶栏可以显示本会话任务名'); if (runningWithTask[0]) console.log(` 示例:${runningWithTask[0].task}`);