ask-ljtest.mjs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #!/usr/bin/env node
  2. /**
  3. * 向 agent-node-lj-test 分批发短问题(长问题容器会处理失败)
  4. */
  5. import { readFileSync } from 'node:fs';
  6. import { homedir } from 'node:os';
  7. import { join } from 'node:path';
  8. const F = 'https://server.fmode.cn/api/functions';
  9. const TARGET = 'agent-node-lj-test'; // 🔴 只问这个,不是 app-lj-test-v1
  10. const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
  11. const t = JSON.parse(readFileSync(join(homedir(), '.fmode/config/user.json'), 'utf8'))?.sessionToken;
  12. async function provision(id) {
  13. const r = await fetch(F, { method: 'POST', headers: { 'Content-Type': 'application/json' },
  14. body: JSON.stringify({ id: 'RP5Ht55NeX', token: t, params: { agentId: id } }) });
  15. const j = await r.json();
  16. const d = j.result ?? j;
  17. if (!d?.accessToken) throw new Error('provision 失败');
  18. return d;
  19. }
  20. /** 分批发:每条都很短,避免容器处理不了长消息 */
  21. const QUESTIONS = [
  22. '你的回复是分几条消息发,还是攒成一整段才发?简短回答。',
  23. '你的回复会挂 Matrix thread 吗?就是 m.relates_to 里的 rel_type=m.thread。会还是不会?',
  24. 'display.tool_progress 和 display.interim_assistant_messages 现在是什么值?',
  25. ];
  26. async function main() {
  27. const prov = await provision(TARGET);
  28. const agent = await provision(TARGET);
  29. console.log('目标容器:', TARGET, '| agentMxId:', agent.agentMxId);
  30. console.log('用户:', prov.userMxId);
  31. const mx = await import('matrix-js-sdk');
  32. const c = mx.createClient({ baseUrl: prov.homeserver, accessToken: prov.accessToken, userId: prov.userMxId });
  33. const room = (await c.createRoom({ invite: [agent.agentMxId], name: `ask-${Date.now()}`, preset: mx.Preset.TrustedPrivateChat })).room_id;
  34. console.log('房间:', room);
  35. const hs = prov.homeserver.replace(/\/$/, '');
  36. const auth = { Authorization: `Bearer ${prov.accessToken}` };
  37. for (let i = 0; i < 30; i++) {
  38. await sleep(3000);
  39. const r = await fetch(`${hs}/_matrix/client/v3/rooms/${encodeURIComponent(room)}/joined_members`, { headers: auth }).catch(() => null);
  40. const j = r ? await r.json().catch(() => ({})) : {};
  41. if ((j.joined ?? {})[agent.agentMxId]) { console.log('容器已进房'); break; }
  42. }
  43. const seen = new Set();
  44. for (const [i, q] of QUESTIONS.entries()) {
  45. console.log(`\n===== 问题 ${i + 1} =====`);
  46. console.log(q);
  47. const sent = await c.sendEvent(room, 'm.room.message', { msgtype: 'm.text', body: q, 'm.mentions': { user_ids: [agent.agentMxId] } });
  48. seen.add(sent.event_id);
  49. const deadline = Date.now() + 180_000;
  50. let got = false;
  51. while (Date.now() < deadline && !got) {
  52. await sleep(6000);
  53. try {
  54. const r = await fetch(`${hs}/_matrix/client/v3/rooms/${encodeURIComponent(room)}/messages?dir=b&limit=30`, { headers: auth });
  55. const j = await r.json();
  56. for (const ev of (j.chunk ?? []).reverse()) {
  57. if (ev.type !== 'm.room.message' || seen.has(ev.event_id) || ev.sender === prov.userMxId) continue;
  58. seen.add(ev.event_id);
  59. const b = String(ev.content?.body ?? '');
  60. console.log(` → 容器(${b.length}字):`, b.slice(0, 500).replace(/\n/g, ' '));
  61. if (!/^[*·•]?\s*(🐍|💻|🔎|📖|✍️)/.test(b.trim())) got = true;
  62. }
  63. } catch { /* ignore */ }
  64. }
  65. if (!got) console.log(' ⚠️ 180 秒内无文字回复');
  66. }
  67. console.log('\n房间保留:', room);
  68. c.stopClient();
  69. }
  70. main().catch((e) => { console.error('失败:', e.message); process.exit(1); });