_dispatch_251_shell.cjs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. // 251 langgraph dispatch via opencode SHELL channel (bypasses agent LLM, per B-94/R101)
  2. // Auth: opencode:IwinTrue@123
  3. const BASE = process.env.OPENCODE_251_BASE || 'http://192.168.16.251:4096';
  4. const AUTH = 'Basic ' + Buffer.from('opencode:' + (process.env.OPENCODE_SERVER_PASSWORD || 'IwinTrue@123')).toString('base64');
  5. const PROJECT_ID = '527b7036bd8d16188784528603a9b79a1d95c9fb';
  6. const capMs = parseInt(process.env.DISPATCH_CAP_MS || '420000', 10);
  7. const CMD = "cd /sc-data/cfc/cfc-langgraph && git pull --ff-only 2>&1 | tail -3 ; timeout 600 .venv/bin/python -m pytest tests --ignore=tests/qna --ignore=tests/test_chat.py -q ; echo EXIT=$?";
  8. async function j(url, opt) {
  9. const r = await fetch(url, Object.assign({ headers: { 'Authorization': AUTH, 'Content-Type': 'application/json' } }, opt));
  10. const t = await r.text();
  11. try { return { status: r.status, json: JSON.parse(t) }; } catch { return { status: r.status, text: t }; }
  12. }
  13. async function main() {
  14. const cr = await j(BASE + '/api/session', { method: 'POST', body: JSON.stringify({ title: 'lg-shell-' + Date.now(), model: { id: 'deepseek3.2', providerID: 'axon' }, projectID: PROJECT_ID }) });
  15. const sid = (cr.json.data && cr.json.data.id) || cr.json.id;
  16. if (!sid) throw new Error('no session: ' + JSON.stringify(cr.json).slice(0,200));
  17. console.log('SESSION_ID', sid);
  18. const sr = await j(BASE + '/api/session/' + sid + '/shell', { method: 'POST', body: JSON.stringify({ command: CMD }) });
  19. console.log('SHELL_CREATE', sr.status);
  20. // find shell id
  21. let shellId = null;
  22. for (let i = 0; i < 10 && !shellId; i++) {
  23. const gl = await j(BASE + '/api/shell');
  24. const arr = (gl.json && (gl.json.data || gl.json)) || [];
  25. if (Array.isArray(arr) && arr.length) { shellId = arr[arr.length - 1].id; break; }
  26. await new Promise(r => setTimeout(r, 1500));
  27. }
  28. if (!shellId) throw new Error('no shell id');
  29. console.log('SHELL_ID', shellId);
  30. const start = Date.now();
  31. let last = '';
  32. while (Date.now() - start < capMs) {
  33. await new Promise(r => setTimeout(r, 4000));
  34. const st = await j(BASE + '/api/shell/' + shellId);
  35. const status = (st.json && (st.json.data && st.json.data.status || st.json.status)) || '?';
  36. if (status !== last) { console.log('SHELL_STATUS', status); last = status; }
  37. if (status && status !== 'running') {
  38. const out = await j(BASE + '/api/shell/' + shellId + '/output');
  39. const o = (out.json && out.json.data && out.json.data.output) || '';
  40. console.log('OUTPUT_BEGIN');
  41. console.log(o.slice(-4000));
  42. console.log('OUTPUT_END');
  43. return;
  44. }
  45. }
  46. console.log('SHELL_TIMEOUT after ' + capMs + 'ms');
  47. }
  48. main().catch(e => { console.error('ERR', e.message); process.exit(1); });