@seqyuan/annovibe 0.8.65 → 0.8.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +3 -3
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/required-server-files.js +1 -1
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/_not-found.html +1 -1
  18. package/.next/server/app/_not-found.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  24. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  25. package/.next/server/app/api/agent/runtime/route.js +1 -1
  26. package/.next/server/app/api/im/cancel/route.js +1 -1
  27. package/.next/server/app/api/im/gateway-status/route.js +3 -1
  28. package/.next/server/app/api/im/gateway-token/route.js +3 -1
  29. package/.next/server/app/api/im/project/route.js +3 -1
  30. package/.next/server/app/api/im/projects/route.js +3 -1
  31. package/.next/server/app/api/im/session-ids/route.js +1 -1
  32. package/.next/server/app/api/im/turn/route.js +4 -2
  33. package/.next/server/app/api/internal/runtime/route.js +1 -1
  34. package/.next/server/app/api/models-config/test/route.js +1 -1
  35. package/.next/server/app/api/version/route.js +1 -1
  36. package/.next/server/app/index.html +1 -1
  37. package/.next/server/app/index.rsc +2 -2
  38. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  39. package/.next/server/app/index.segments/_full.segment.rsc +2 -2
  40. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  41. package/.next/server/app/index.segments/_index.segment.rsc +1 -1
  42. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  43. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  44. package/.next/server/app/login.html +1 -1
  45. package/.next/server/app/login.rsc +1 -1
  46. package/.next/server/app/login.segments/_full.segment.rsc +1 -1
  47. package/.next/server/app/login.segments/_head.segment.rsc +1 -1
  48. package/.next/server/app/login.segments/_index.segment.rsc +1 -1
  49. package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
  50. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  51. package/.next/server/app/login.segments/login.segment.rsc +1 -1
  52. package/.next/server/app/page.js +3 -3
  53. package/.next/server/app/page_client-reference-manifest.js +1 -1
  54. package/.next/server/app/smoke/page_client-reference-manifest.js +1 -1
  55. package/.next/server/app/smoke.html +1 -1
  56. package/.next/server/app/smoke.rsc +1 -1
  57. package/.next/server/app/smoke.segments/_full.segment.rsc +1 -1
  58. package/.next/server/app/smoke.segments/_head.segment.rsc +1 -1
  59. package/.next/server/app/smoke.segments/_index.segment.rsc +1 -1
  60. package/.next/server/app/smoke.segments/_tree.segment.rsc +1 -1
  61. package/.next/server/app/smoke.segments/smoke/__PAGE__.segment.rsc +1 -1
  62. package/.next/server/app/smoke.segments/smoke.segment.rsc +1 -1
  63. package/.next/server/app-paths-manifest.json +3 -3
  64. package/.next/server/chunks/1761.js +1 -0
  65. package/.next/server/chunks/4741.js +1 -1
  66. package/.next/server/middleware-build-manifest.js +1 -1
  67. package/.next/server/middleware.js +1 -1
  68. package/.next/server/next-font-manifest.js +1 -1
  69. package/.next/server/next-font-manifest.json +1 -1
  70. package/.next/server/pages/404.html +1 -1
  71. package/.next/server/pages/500.html +1 -1
  72. package/.next/server/server-reference-manifest.json +1 -1
  73. package/.next/static/chunks/app/{page-ef274c19b774b6e8.js → page-b520597ccd6ee848.js} +3 -3
  74. package/bin/annovibe-im-gateway.js +80 -23
  75. package/package.json +3 -3
  76. /package/.next/static/{gYvnLqalIPArJaeJwBKwI → loesu0nFGu4lXnhvPK1si}/_buildManifest.js +0 -0
  77. /package/.next/static/{gYvnLqalIPArJaeJwBKwI → loesu0nFGu4lXnhvPK1si}/_ssgManifest.js +0 -0
@@ -86,27 +86,41 @@ function getBaseUrl() {
86
86
  return `http://127.0.0.1:${getAnnovibePort()}`;
87
87
  }
88
88
 
89
- function readGatewayToken() {
90
- const statePath = path.join(getAgentDir(), "im", "gateway.json");
89
+ function getGatewayStatePath() {
90
+ return path.join(getAgentDir(), "im", "gateway.json");
91
+ }
92
+
93
+ function readGatewayState() {
91
94
  try {
92
- const state = JSON.parse(fs.readFileSync(statePath, "utf8"));
93
- return typeof state.token === "string" ? state.token.trim() : "";
95
+ return JSON.parse(fs.readFileSync(getGatewayStatePath(), "utf8"));
94
96
  } catch {
95
- return "";
97
+ return {};
96
98
  }
97
99
  }
98
100
 
101
+ function readGatewayToken() {
102
+ const state = readGatewayState();
103
+ return typeof state.token === "string" ? state.token.trim() : "";
104
+ }
105
+
106
+ function writeGatewayState(patch) {
107
+ const statePath = getGatewayStatePath();
108
+ try { fs.mkdirSync(path.dirname(statePath), { recursive: true }); } catch {}
109
+ const state = readGatewayState();
110
+ fs.writeFileSync(statePath, JSON.stringify({ ...state, ...patch }, null, 2), "utf8");
111
+ }
112
+
99
113
  // ── HTTP helpers ────────────────────────────────────────────────────
100
114
 
101
115
  function getToken() {
102
116
  return process.env.ANNOVIBE_GATEWAY_TOKEN?.trim() || readGatewayToken();
103
117
  }
104
118
 
105
- function requestJson(method, pathname, body) {
119
+ function requestJsonRaw(method, pathname, body, options = {}) {
106
120
  const url = new URL(pathname, getBaseUrl());
107
121
  const payload = body === undefined ? undefined : JSON.stringify(body);
108
122
  const lib = url.protocol === "https:" ? https : http;
109
- const token = getToken();
123
+ const token = options.skipAuth ? "" : getToken();
110
124
 
111
125
  return new Promise((resolve, reject) => {
112
126
  const req = lib.request(
@@ -143,6 +157,10 @@ function requestJson(method, pathname, body) {
143
157
  });
144
158
  }
145
159
 
160
+ function requestJson(method, pathname, body) {
161
+ return requestJsonRaw(method, pathname, body);
162
+ }
163
+
146
164
  function formatImApiError(statusCode, message) {
147
165
  if (statusCode === 401) {
148
166
  return `${message}. Ensure annovibe is running in this Linux account and gateway token is synced (restart annovibe-im-gateway after saving IM settings).`;
@@ -153,6 +171,18 @@ function formatImApiError(statusCode, message) {
153
171
  return message;
154
172
  }
155
173
 
174
+ async function syncGatewayTokenFromServer() {
175
+ try {
176
+ const payload = await requestJsonRaw("GET", "/api/im/gateway-token", undefined, { skipAuth: true });
177
+ const serverToken = typeof payload.token === "string" ? payload.token.trim() : "";
178
+ if (!serverToken || readGatewayToken() === serverToken) return;
179
+ writeGatewayState({ token: serverToken });
180
+ console.error("[im] synced gateway token from annovibe server");
181
+ } catch (error) {
182
+ console.error(`[im] could not sync gateway token: ${String(error)}`);
183
+ }
184
+ }
185
+
156
186
  /**
157
187
  * Consume SSE turn stream, yielding deltas and status changes to callbacks.
158
188
  */
@@ -546,8 +576,42 @@ class ProjectWeComBridge {
546
576
  };
547
577
 
548
578
  try {
579
+ let lastPushAt = 0;
580
+ let pendingText = null;
581
+ let pushTimer = null;
582
+ let pushChain = Promise.resolve();
583
+ const pushIntervalMs = 300;
584
+
585
+ const pushImmediate = async (text) => {
586
+ pushChain = pushChain.then(() => pushText(text));
587
+ await pushChain;
588
+ lastPushAt = Date.now();
589
+ };
590
+
591
+ const schedulePush = (text) => {
592
+ pendingText = text;
593
+ const now = Date.now();
594
+ if (now - lastPushAt >= pushIntervalMs) {
595
+ void flushPush();
596
+ return;
597
+ }
598
+ if (pushTimer) return;
599
+ pushTimer = setTimeout(() => { void flushPush(); }, pushIntervalMs - (now - lastPushAt));
600
+ };
601
+
602
+ const flushPush = async () => {
603
+ if (pushTimer) {
604
+ clearTimeout(pushTimer);
605
+ pushTimer = null;
606
+ }
607
+ const text = pendingText;
608
+ if (text === null) return;
609
+ pendingText = null;
610
+ await pushImmediate(text);
611
+ };
612
+
549
613
  // Start processing
550
- await pushText("(working 1s)");
614
+ await pushImmediate("(working 1s)");
551
615
 
552
616
  refreshTimer = setInterval(() => {
553
617
  if (toolsRunning) {
@@ -565,8 +629,7 @@ class ProjectWeComBridge {
565
629
  onDelta(text) {
566
630
  toolsRunning = false;
567
631
  lastText = text;
568
- // Schedule push — debounced by WeCom rate limits via replyStream
569
- void pushText(text).catch(() => undefined);
632
+ schedulePush(text);
570
633
  },
571
634
  },
572
635
  );
@@ -578,6 +641,8 @@ class ProjectWeComBridge {
578
641
  : "No reply from annovibe.";
579
642
  const cleaned = cleanImReplyText(lastText || rawReply);
580
643
  const finishTextStr = cleaned || "No reply from annovibe.";
644
+ if (pushTimer) clearTimeout(pushTimer);
645
+ pendingText = null;
581
646
  await finishText(finishTextStr);
582
647
  } catch (error) {
583
648
  if (refreshTimer) clearInterval(refreshTimer);
@@ -597,21 +662,14 @@ class ImGateway {
597
662
  console.error("[im] Annovibe IM Gateway starting...");
598
663
 
599
664
  // Write gateway state
600
- const imDir = path.join(getAgentDir(), "im");
601
- try { fs.mkdirSync(imDir, { recursive: true }); } catch {}
602
- const token = crypto.randomBytes(32).toString("hex");
603
- fs.writeFileSync(
604
- path.join(imDir, "gateway.json"),
605
- JSON.stringify({
606
- token,
607
- startedAt: new Date().toISOString(),
608
- pid: process.pid,
609
- }, null, 2),
610
- );
665
+ const token = readGatewayToken() || crypto.randomBytes(32).toString("hex");
666
+ writeGatewayState({ token, startedAt: new Date().toISOString(), pid: process.pid });
611
667
 
612
668
  console.error(`[im] Gateway token: ${token.slice(0, 8)}...`);
613
669
  console.error(`[im] Annovibe port: ${getAnnovibePort()}`);
614
670
 
671
+ await syncGatewayTokenFromServer();
672
+
615
673
  // Start config poll
616
674
  await this.refreshProjects();
617
675
  this.pollTimer = setInterval(() => this.refreshProjects(), 30000);
@@ -657,8 +715,7 @@ class ImGateway {
657
715
  this.bridges.clear();
658
716
 
659
717
  try {
660
- const statePath = path.join(getAgentDir(), "im", "gateway.json");
661
- fs.writeFileSync(statePath, JSON.stringify({ token: "" }, null, 2));
718
+ writeGatewayState({ token: "" });
662
719
  } catch {}
663
720
  }
664
721
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seqyuan/annovibe",
3
- "version": "0.8.65",
3
+ "version": "0.8.67",
4
4
  "description": "AI-native bioinformatics workspace by Annoroad",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -34,8 +34,8 @@
34
34
  "release": "npm version patch --no-git-tag-version && npm run build && npm run pack:check && npm publish --access public"
35
35
  },
36
36
  "dependencies": {
37
- "@earendil-works/pi-ai": "^0.75.5",
38
- "@earendil-works/pi-coding-agent": "^0.75.5",
37
+ "@earendil-works/pi-ai": "^0.80.2",
38
+ "@earendil-works/pi-coding-agent": "^0.80.2",
39
39
  "@seqyuan/kernel-lite-core": "^0.2.1",
40
40
  "@seqyuan/pi-kernel-plot": "^0.2.1",
41
41
  "bcryptjs": "^3.0.3",