@geminilight/mindos 0.7.2 → 0.7.4

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 (254) hide show
  1. package/_standalone/.mindos-build-version +1 -1
  2. package/_standalone/.next/BUILD_ID +1 -1
  3. package/_standalone/.next/app-path-routes-manifest.json +19 -19
  4. package/_standalone/.next/build-manifest.json +3 -3
  5. package/_standalone/.next/cache/.previewinfo +1 -1
  6. package/_standalone/.next/cache/.rscinfo +1 -1
  7. package/_standalone/.next/cache/config.json +3 -3
  8. package/_standalone/.next/prerender-manifest.json +3 -3
  9. package/_standalone/.next/react-loadable-manifest.json +4 -4
  10. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  11. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/_standalone/.next/server/app/_global-error.html +2 -2
  13. package/_standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  21. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  22. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  24. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  25. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  26. package/_standalone/.next/server/app/agents/page.js +1 -1
  27. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  28. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  29. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  31. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  32. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
  41. package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
  42. package/_standalone/.next/server/app/api/ask/route.js +4 -4
  43. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  44. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  45. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  46. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  47. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  49. package/_standalone/.next/server/app/api/channels/verify/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/connect/route_client-reference-manifest.js +1 -1
  51. package/_standalone/.next/server/app/api/embedding/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  53. package/_standalone/.next/server/app/api/extract-docx/route_client-reference-manifest.js +1 -1
  54. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  55. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  56. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  58. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  60. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  61. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  62. package/_standalone/.next/server/app/api/im/activity/route_client-reference-manifest.js +1 -1
  63. package/_standalone/.next/server/app/api/im/config/route_client-reference-manifest.js +1 -1
  64. package/_standalone/.next/server/app/api/im/feishu/long-connection/event/route_client-reference-manifest.js +1 -1
  65. package/_standalone/.next/server/app/api/im/feishu/long-connection/route_client-reference-manifest.js +1 -1
  66. package/_standalone/.next/server/app/api/im/status/route_client-reference-manifest.js +1 -1
  67. package/_standalone/.next/server/app/api/im/test/route_client-reference-manifest.js +1 -1
  68. package/_standalone/.next/server/app/api/im/webhook/feishu/route_client-reference-manifest.js +1 -1
  69. package/_standalone/.next/server/app/api/im/webhook-status/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/inbox/clip/route_client-reference-manifest.js +1 -1
  71. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/lint/route_client-reference-manifest.js +1 -1
  74. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  75. package/_standalone/.next/server/app/api/mcp/direct-tools/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  77. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  79. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/mcp/tools/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/obsidian/compat-report/route_client-reference-manifest.js +1 -1
  84. package/_standalone/.next/server/app/api/obsidian/import/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  87. package/_standalone/.next/server/app/api/search/prewarm/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  89. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  91. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  93. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  96. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  97. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/space-overview/route_client-reference-manifest.js +1 -1
  100. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  102. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  105. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  106. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  107. package/_standalone/.next/server/app/capture/history/page.js +1 -1
  108. package/_standalone/.next/server/app/capture/history/page.js.nft.json +1 -1
  109. package/_standalone/.next/server/app/capture/history/page_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/capture/page.js +1 -1
  111. package/_standalone/.next/server/app/capture/page.js.nft.json +1 -1
  112. package/_standalone/.next/server/app/capture/page_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/changelog/page.js +1 -1
  114. package/_standalone/.next/server/app/changelog/page.js.nft.json +1 -1
  115. package/_standalone/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  116. package/_standalone/.next/server/app/changes/page.js +1 -1
  117. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  118. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
  120. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  121. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  122. package/_standalone/.next/server/app/echo/page.js +1 -1
  123. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  124. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  125. package/_standalone/.next/server/app/explore/page.js +1 -1
  126. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  127. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  128. package/_standalone/.next/server/app/help/page.js +1 -1
  129. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  130. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  131. package/_standalone/.next/server/app/inbox/history/page.js +1 -1
  132. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
  133. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
  134. package/_standalone/.next/server/app/login/page.js +1 -1
  135. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  136. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  137. package/_standalone/.next/server/app/page.js +1 -1
  138. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  139. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  140. package/_standalone/.next/server/app/setup/page.js +1 -1
  141. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  142. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  143. package/_standalone/.next/server/app/todo/page.js +1 -1
  144. package/_standalone/.next/server/app/todo/page.js.nft.json +1 -1
  145. package/_standalone/.next/server/app/todo/page_client-reference-manifest.js +1 -1
  146. package/_standalone/.next/server/app/trash/page.js +2 -2
  147. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  148. package/_standalone/.next/server/app/view/[...path]/page.js +2 -2
  149. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  150. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  151. package/_standalone/.next/server/app/wiki/page.js +2 -0
  152. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -0
  153. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -0
  154. package/_standalone/.next/server/app-paths-manifest.json +19 -19
  155. package/_standalone/.next/server/chunks/2250.js +1 -1
  156. package/_standalone/.next/server/chunks/{1057.js → 3861.js} +2 -2
  157. package/_standalone/.next/server/chunks/4802.js +30 -30
  158. package/_standalone/.next/server/chunks/8388.js +1 -1
  159. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  160. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  161. package/_standalone/.next/server/pages/500.html +2 -2
  162. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  163. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  164. package/_standalone/.next/static/chunks/{5581-bae715e40d227b5f.js → 5581-beecbc4ca5625aa9.js} +2 -2
  165. package/_standalone/.next/static/chunks/6762.c871d0bf3f45ba87.js +1 -0
  166. package/_standalone/.next/static/chunks/{8064-e65acd2762132099.js → 8064-acac37daf946082b.js} +1 -1
  167. package/_standalone/.next/static/chunks/{3985.695651f6b5cd768c.js → 8984.91fb8cde1983c564.js} +2 -2
  168. package/_standalone/.next/static/chunks/app/{layout-0cf6f2a65f605a0d.js → layout-20faba3bc0af7cd2.js} +19 -19
  169. package/_standalone/.next/static/chunks/app/trash/page-0c2c67929b71ef71.js +1 -0
  170. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-fd06cc989103ebe7.js +1 -0
  171. package/_standalone/.next/static/chunks/app/view/[...path]/page-dba70888697ba910.js +12 -0
  172. package/_standalone/.next/static/chunks/app/wiki/page-9bc1fec84d343290.js +14 -0
  173. package/_standalone/.next/static/chunks/webpack-3c1d0331f1da64b8.js +1 -0
  174. package/_standalone/.next/trace +97 -97
  175. package/_standalone/MINDOS_ARCHITECTURE_DIAGRAM.md +488 -0
  176. package/_standalone/MINDOS_EXPLORATION_SUMMARY.md +229 -0
  177. package/_standalone/MINDOS_INFRASTRUCTURE_ANALYSIS.md +732 -0
  178. package/_standalone/__tests__/api/mcp-install.test.ts +8 -2
  179. package/_standalone/__tests__/core/embedding-provider.test.ts +78 -0
  180. package/_standalone/__tests__/skills/mindos-skill-copy-alignment.test.ts +10 -4
  181. package/_standalone/components/ask/AskHeader.tsx +25 -18
  182. package/_standalone/components/ask/SessionHistoryPanel.tsx +21 -12
  183. package/_standalone/components/settings/AiTab.tsx +3 -0
  184. package/_standalone/data/skills/mindos/SKILL.md +269 -0
  185. package/_standalone/data/skills/mindos/references/write-supplement.md +119 -0
  186. package/_standalone/data/skills/mindos-zh/SKILL.md +227 -0
  187. package/_standalone/data/skills/mindos-zh/references/write-supplement.md +119 -0
  188. package/app/__tests__/api/mcp-install.test.ts +8 -2
  189. package/app/__tests__/core/embedding-provider.test.ts +78 -0
  190. package/app/__tests__/skills/mindos-skill-copy-alignment.test.ts +10 -4
  191. package/app/app/api/ask/route.ts +14 -9
  192. package/app/app/view/[...path]/ViewPageClient.tsx +15 -12
  193. package/app/app/view/[...path]/not-found.tsx +9 -5
  194. package/app/components/ask/AskHeader.tsx +25 -18
  195. package/app/components/ask/SessionHistoryPanel.tsx +21 -12
  196. package/app/components/settings/AiTab.tsx +3 -0
  197. package/app/eslint.config.mjs +18 -0
  198. package/app/lib/core/embedding-provider.ts +12 -4
  199. package/app/lib/i18n/modules/settings.ts +2 -0
  200. package/app/package-lock.json +20214 -0
  201. package/app/tsconfig.tsbuildinfo +1 -0
  202. package/app/vitest.config.ts +14 -0
  203. package/assets/demo-flow-zh.html +622 -0
  204. package/assets/images/demo-flow-dark.png +0 -0
  205. package/assets/images/demo-flow-dark.webp +0 -0
  206. package/assets/images/demo-flow-light.png +0 -0
  207. package/assets/images/demo-flow-light.webp +0 -0
  208. package/assets/images/demo-flow-zh-dark.png +0 -0
  209. package/assets/images/demo-flow-zh-dark.webp +0 -0
  210. package/assets/images/demo-flow-zh-light.png +0 -0
  211. package/assets/images/demo-flow-zh-light.webp +0 -0
  212. package/assets/images/gui-sync-cv.png +0 -0
  213. package/assets/images/gui-sync-cv.webp +0 -0
  214. package/assets/images/mindos-chat.png +0 -0
  215. package/assets/images/mindos-chat.webp +0 -0
  216. package/assets/images/mindos-dashboard.png +0 -0
  217. package/assets/images/mindos-dashboard.webp +0 -0
  218. package/assets/images/mindos-echo.png +0 -0
  219. package/assets/images/mindos-echo.webp +0 -0
  220. package/assets/images/mindos-home.png +0 -0
  221. package/assets/images/mindos-home.webp +0 -0
  222. package/assets/images/wechat-qr.png +0 -0
  223. package/bin/lib/mcp-build.js +8 -0
  224. package/mcp/package-lock.json +2202 -0
  225. package/mcp/src/index.ts +783 -0
  226. package/package.json +13 -1
  227. package/.env.local.example +0 -38
  228. package/.playwright-cli/page-2026-04-12T12-26-53-393Z.yml +0 -6
  229. package/.playwright-cli/page-2026-04-12T12-27-20-256Z.yml +0 -120
  230. package/.syncinclude +0 -105
  231. package/MINDOS_SEARCH_DIAGRAM.txt +0 -243
  232. package/_standalone/.next/static/chunks/576.3cae31209383ddbd.js +0 -1
  233. package/_standalone/.next/static/chunks/app/trash/page-085f121c0815d542.js +0 -1
  234. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-2a6eec67e91eaaf9.js +0 -1
  235. package/_standalone/.next/static/chunks/app/view/[...path]/page-faeaf8c09c1c6d7c.js +0 -12
  236. package/_standalone/.next/static/chunks/webpack-a1bb35f2d540e463.js +0 -1
  237. package/scripts/build-runtime-archive.sh +0 -151
  238. package/scripts/fix-postcss-deps.cjs +0 -75
  239. package/scripts/gen-renderer-index.js +0 -64
  240. package/scripts/hooks/block-public-merge.sh +0 -42
  241. package/scripts/hooks/pre-merge-commit +0 -4
  242. package/scripts/hooks/pre-push +0 -37
  243. package/scripts/hooks/prepare-commit-msg +0 -12
  244. package/scripts/migrate-agent-audit-log.js +0 -170
  245. package/scripts/migrate-agent-diff.js +0 -146
  246. package/scripts/parse-syncinclude.sh +0 -92
  247. package/scripts/prepare-standalone.mjs +0 -83
  248. package/scripts/release.sh +0 -145
  249. package/scripts/setup.js +0 -1427
  250. package/scripts/test-oss-upload.sh +0 -100
  251. package/scripts/verify-standalone.mjs +0 -129
  252. package/scripts/write-build-stamp.js +0 -40
  253. /package/_standalone/.next/static/{q5RP_Mx8BrCfvVDnLpRRc → 0UlbV2rA2i4B-8YYg41wQ}/_buildManifest.js +0 -0
  254. /package/_standalone/.next/static/{q5RP_Mx8BrCfvVDnLpRRc → 0UlbV2rA2i4B-8YYg41wQ}/_ssgManifest.js +0 -0
@@ -847,8 +847,11 @@ export async function POST(req: NextRequest) {
847
847
  });
848
848
  acpSessionId = acpSession.id;
849
849
 
850
- // ── CRITICAL: Add 120s timeout to ACP agent execution ──
851
- const ACP_AGENT_TIMEOUT_MS = 120_000;
850
+ // ── CRITICAL: Add timeout to ACP agent execution ──
851
+ // Default 600s (10min), configurable via MINDOS_AGENT_TIMEOUT_MS env var
852
+ const ACP_AGENT_TIMEOUT_MS = process.env.MINDOS_AGENT_TIMEOUT_MS
853
+ ? parseInt(process.env.MINDOS_AGENT_TIMEOUT_MS, 10)
854
+ : 600_000;
852
855
  await withTimeout(
853
856
  promptStream(acpSessionId, lastUserContent, (update: AcpSessionUpdate) => {
854
857
  switch (update.type) {
@@ -918,7 +921,7 @@ export async function POST(req: NextRequest) {
918
921
  }
919
922
  }),
920
923
  ACP_AGENT_TIMEOUT_MS,
921
- 'ACP agent execution timeout after 120 seconds'
924
+ `ACP agent execution timeout after ${ACP_AGENT_TIMEOUT_MS / 1000} seconds`
922
925
  );
923
926
 
924
927
  lastAcpError = null;
@@ -998,15 +1001,17 @@ export async function POST(req: NextRequest) {
998
1001
 
999
1002
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
1000
1003
  try {
1001
- // ── CRITICAL: Add 120s timeout to agent execution ──
1002
- // Prevents indefinite hangs when tools are unresponsive.
1003
- // Each step is typically 2-5s, so 30 steps * 5s = 150s max.
1004
- // 120s timeout is conservative safety net for network delays + model latency.
1005
- const AGENT_TIMEOUT_MS = 120_000;
1004
+ // ── CRITICAL: Add timeout to agent execution ──
1005
+ // Prevents indefinite hangs when tools are unresponsive or API is slow.
1006
+ // Default 600s (10min) accommodates slow APIs, complex tool chains, and high-latency scenarios.
1007
+ // Configurable via MINDOS_AGENT_TIMEOUT_MS env var.
1008
+ const AGENT_TIMEOUT_MS = process.env.MINDOS_AGENT_TIMEOUT_MS
1009
+ ? parseInt(process.env.MINDOS_AGENT_TIMEOUT_MS, 10)
1010
+ : 600_000;
1006
1011
  await withTimeout(
1007
1012
  session.prompt(lastUserContent, lastUserImages ? { images: lastUserImages } : undefined),
1008
1013
  AGENT_TIMEOUT_MS,
1009
- 'Agent execution timeout after 120 seconds'
1014
+ `Agent execution timeout after ${AGENT_TIMEOUT_MS / 1000} seconds`
1010
1015
  );
1011
1016
  lastPromptError = null;
1012
1017
  break; // success
@@ -497,19 +497,22 @@ export default function ViewPageClient({
497
497
  <button
498
498
  key={m.id}
499
499
  onClick={() => {
500
- setMdViewMode(m.id);
501
- if (m.id === 'preview') {
502
- // Sync latest edit content to savedContent before switching
503
- const clean = twemojiToNative(editContent);
504
- setSavedContent(clean);
505
- if (clean !== savedContent) {
506
- saveAction(clean).catch(() => {});
500
+ // Use startTransition to mark state updates as non-urgent
501
+ startTransition(() => {
502
+ setMdViewMode(m.id);
503
+ if (m.id === 'preview') {
504
+ // Sync latest edit content to savedContent before switching
505
+ const clean = twemojiToNative(editContent);
506
+ setSavedContent(clean);
507
+ if (clean !== savedContent) {
508
+ saveAction(clean).catch(() => {});
509
+ }
510
+ setEditing(false);
511
+ } else if (!editing) {
512
+ setEditContent(savedContent);
513
+ setEditing(true);
507
514
  }
508
- setEditing(false);
509
- } else if (!editing) {
510
- setEditContent(savedContent);
511
- setEditing(true);
512
- }
515
+ });
513
516
  }}
514
517
  className={`flex items-center gap-1 px-2 py-1 rounded text-[11px] font-medium transition-colors ${
515
518
  mdViewMode === m.id
@@ -30,17 +30,21 @@ export default function ViewNotFound() {
30
30
  setCreating(true);
31
31
  try {
32
32
  const target = isMd && !filePath.includes('.') ? `${filePath}.md` : filePath;
33
- const res = await fetch('/api/files', {
34
- method: 'PUT',
33
+ const res = await fetch('/api/file', {
34
+ method: 'POST',
35
35
  headers: { 'Content-Type': 'application/json' },
36
- body: JSON.stringify({ path: target, content: '' }),
36
+ body: JSON.stringify({ op: 'create_file', path: target, content: '' }),
37
37
  });
38
38
  if (res.ok) {
39
39
  router.replace(`/view/${encodePath(target)}`);
40
40
  router.refresh();
41
+ } else {
42
+ // Show error to user instead of silent failure
43
+ const data = await res.json().catch(() => ({ error: 'Unknown error' }));
44
+ console.error('[not-found] Failed to create file:', data.error);
41
45
  }
42
- } catch {
43
- // silent user can retry
46
+ } catch (err) {
47
+ console.error('[not-found] Network error:', err);
44
48
  } finally {
45
49
  setCreating(false);
46
50
  }
@@ -1,4 +1,4 @@
1
- import { memo, useState, useRef, useEffect, useCallback } from 'react';
1
+ import { memo, useState, useRef, useEffect, useCallback, useTransition } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
  import { Sparkles, SquarePen, History, X, Maximize2, Minimize2, PanelRight, AppWindow, ChevronDown, Check, Trash2, Pencil, Pin, PinOff } from 'lucide-react';
4
4
  import { SaveSessionButton } from './SaveSessionInline';
@@ -38,6 +38,7 @@ export default memo(function AskHeader({
38
38
  messages,
39
39
  }: AskHeaderProps) {
40
40
  const { t } = useLocale();
41
+ const [isPending, startTransition] = useTransition();
41
42
  const iconSize = 14;
42
43
  const hasMultipleSessions = sessions && sessions.length >= 2;
43
44
  const headerButtonClass = isPanel
@@ -93,8 +94,10 @@ export default memo(function AskHeader({
93
94
  }, [renamingId]);
94
95
 
95
96
  const handleSelectSession = useCallback((id: string) => {
96
- onLoadSession?.(id);
97
- setSwitcherOpen(false);
97
+ startTransition(() => {
98
+ onLoadSession?.(id);
99
+ setSwitcherOpen(false);
100
+ });
98
101
  }, [onLoadSession]);
99
102
 
100
103
  const handleStartRename = useCallback((id: string, currentTitle: string) => {
@@ -103,10 +106,12 @@ export default memo(function AskHeader({
103
106
  }, []);
104
107
 
105
108
  const handleCommitRename = useCallback(() => {
106
- if (renamingId && onRenameSession && renameValue.trim()) {
107
- onRenameSession(renamingId, renameValue.trim());
108
- }
109
- setRenamingId(null);
109
+ startTransition(() => {
110
+ if (renamingId && onRenameSession && renameValue.trim()) {
111
+ onRenameSession(renamingId, renameValue.trim());
112
+ }
113
+ setRenamingId(null);
114
+ });
110
115
  }, [renamingId, renameValue, onRenameSession]);
111
116
 
112
117
  // Position dropdown below trigger
@@ -222,11 +227,13 @@ export default memo(function AskHeader({
222
227
  ref={switcherRef}
223
228
  type="button"
224
229
  onClick={() => {
225
- if (sessions && sessions.length >= 2) {
226
- setSwitcherOpen(v => !v);
227
- } else {
228
- onToggleHistory();
229
- }
230
+ startTransition(() => {
231
+ if (sessions && sessions.length >= 2) {
232
+ setSwitcherOpen(v => !v);
233
+ } else {
234
+ onToggleHistory();
235
+ }
236
+ });
230
237
  }}
231
238
  className={`flex items-center gap-1 min-w-0 text-sm font-medium text-[var(--amber)] hover:text-[var(--amber)]/80 hover:bg-muted/40 transition-colors ${titleTriggerClass}`}
232
239
  aria-expanded={switcherOpen}
@@ -249,32 +256,32 @@ export default memo(function AskHeader({
249
256
  )}
250
257
  {hideTitle && <div />}
251
258
  <div className="flex items-center gap-1 shrink-0">
252
- <button type="button" onClick={(e) => { e.stopPropagation(); onToggleHistory(); }} aria-pressed={showHistory} className={`${headerButtonClass} inline-flex items-center justify-center transition-colors ${showHistory ? 'bg-[var(--amber)]/10 text-[var(--amber)]' : 'text-muted-foreground hover:text-foreground hover:bg-muted'}`} title={t.hints.sessionHistory}>
259
+ <button type="button" onClick={(e) => { e.stopPropagation(); startTransition(() => onToggleHistory()); }} aria-pressed={showHistory} className={`${headerButtonClass} inline-flex items-center justify-center transition-colors ${showHistory ? 'bg-[var(--amber)]/10 text-[var(--amber)]' : 'text-muted-foreground hover:text-foreground hover:bg-muted'}`} title={t.hints.sessionHistory}>
253
260
  <History size={iconSize} />
254
261
  </button>
255
262
  {messages && messages.length > 0 && (
256
263
  <SaveSessionButton messages={messages} disabled={isLoading} />
257
264
  )}
258
- <button type="button" onClick={(e) => { e.stopPropagation(); onReset(); }} disabled={isLoading} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-40`} title={t.hints.newSession}>
265
+ <button type="button" onClick={(e) => { e.stopPropagation(); startTransition(() => onReset()); }} disabled={isLoading} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors disabled:opacity-40`} title={t.hints.newSession}>
259
266
  <SquarePen size={iconSize} />
260
267
  </button>
261
268
  {onMaximize && (
262
- <button type="button" onClick={(e) => { e.stopPropagation(); onMaximize(); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={maximized ? t.hints.restorePanel : t.hints.maximizePanel}>
269
+ <button type="button" onClick={(e) => { e.stopPropagation(); startTransition(() => onMaximize()); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={maximized ? t.hints.restorePanel : t.hints.maximizePanel}>
263
270
  {maximized ? <Minimize2 size={iconSize} /> : <Maximize2 size={iconSize} />}
264
271
  </button>
265
272
  )}
266
273
  {onDockToPanel && (
267
- <button type="button" onClick={(e) => { e.stopPropagation(); onDockToPanel(); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={t.hints.dockToSide ?? 'Dock to side panel'}>
274
+ <button type="button" onClick={(e) => { e.stopPropagation(); startTransition(() => onDockToPanel()); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={t.hints.dockToSide ?? 'Dock to side panel'}>
268
275
  <PanelRight size={iconSize} />
269
276
  </button>
270
277
  )}
271
278
  {onModeSwitch && (
272
- <button type="button" onClick={(e) => { e.stopPropagation(); onModeSwitch(); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={askMode === 'popup' ? t.hints.dockToSide : t.hints.openAsPopup}>
279
+ <button type="button" onClick={(e) => { e.stopPropagation(); startTransition(() => onModeSwitch()); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={askMode === 'popup' ? t.hints.dockToSide : t.hints.openAsPopup}>
273
280
  {askMode === 'popup' ? <PanelRight size={iconSize} /> : <AppWindow size={iconSize} />}
274
281
  </button>
275
282
  )}
276
283
  {onClose && (
277
- <button type="button" onClick={(e) => { e.stopPropagation(); onClose(); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={t.hints.closePanel} aria-label="Close">
284
+ <button type="button" onClick={(e) => { e.stopPropagation(); startTransition(() => onClose()); }} className={`${headerButtonClass} inline-flex items-center justify-center hover:bg-muted text-muted-foreground hover:text-foreground transition-colors`} title={t.hints.closePanel} aria-label="Close">
278
285
  <X size={iconSize} />
279
286
  </button>
280
287
  )}
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
3
+ import { useState, useRef, useEffect, useCallback, useMemo, useTransition } from 'react';
4
4
  import { Search, Trash2, Pencil, Pin, PinOff, FolderInput, MessageSquare, SquarePen, X } from 'lucide-react';
5
5
  import type { ChatSession } from '@/lib/types';
6
6
  import { sessionTitle } from '@/hooks/useAskSession';
@@ -60,6 +60,7 @@ export default function SessionHistoryPanel({
60
60
  onClose, onNewChat,
61
61
  }: SessionHistoryPanelProps) {
62
62
  const { t } = useLocale();
63
+ const [isPending, startTransition] = useTransition();
63
64
  const ask = t.ask;
64
65
  const [query, setQuery] = useState('');
65
66
  const [editingId, setEditingId] = useState<string | null>(null);
@@ -113,13 +114,17 @@ export default function SessionHistoryPanel({
113
114
  const totalCount = sessions.filter(s => s.messages.length > 0).length;
114
115
 
115
116
  const handleLoad = useCallback((id: string) => {
116
- onLoad(id);
117
- onClose();
117
+ startTransition(() => {
118
+ onLoad(id);
119
+ onClose();
120
+ });
118
121
  }, [onLoad, onClose]);
119
122
 
120
123
  const handleNewChat = useCallback(() => {
121
- onNewChat();
122
- onClose();
124
+ startTransition(() => {
125
+ onNewChat();
126
+ onClose();
127
+ });
123
128
  }, [onNewChat, onClose]);
124
129
 
125
130
  const startRename = useCallback((s: ChatSession) => {
@@ -128,10 +133,12 @@ export default function SessionHistoryPanel({
128
133
  }, []);
129
134
 
130
135
  const commitRename = useCallback(() => {
131
- if (editingId && editValue.trim()) {
132
- onRename(editingId, editValue.trim());
133
- }
134
- setEditingId(null);
136
+ startTransition(() => {
137
+ if (editingId && editValue.trim()) {
138
+ onRename(editingId, editValue.trim());
139
+ }
140
+ setEditingId(null);
141
+ });
135
142
  }, [editingId, editValue, onRename]);
136
143
 
137
144
  const handleClearAll = useCallback(() => {
@@ -141,9 +148,11 @@ export default function SessionHistoryPanel({
141
148
  clearTimer.current = setTimeout(() => setConfirmClearAll(false), 3000);
142
149
  return;
143
150
  }
144
- if (clearTimer.current) clearTimeout(clearTimer.current);
145
- onClearAll();
146
- setConfirmClearAll(false);
151
+ startTransition(() => {
152
+ if (clearTimer.current) clearTimeout(clearTimer.current);
153
+ onClearAll();
154
+ setConfirmClearAll(false);
155
+ });
147
156
  }, [confirmClearAll, onClearAll]);
148
157
 
149
158
  // Keyboard: Esc to close
@@ -804,6 +804,9 @@ function EmbeddingSearchCard({ data, setData, t }: {
804
804
  <X size={14} />
805
805
  <span>{downloadError ?? 'Download failed'}</span>
806
806
  </div>
807
+ <p className="text-xs text-muted-foreground">
808
+ {e.downloadFailedHint as string ?? 'If download keeps failing, try API mode or set HF_ENDPOINT=https://hf-mirror.com'}
809
+ </p>
807
810
  <button
808
811
  type="button"
809
812
  onClick={handleRetry}
@@ -0,0 +1,18 @@
1
+ import { defineConfig, globalIgnores } from "eslint/config";
2
+ import nextVitals from "eslint-config-next/core-web-vitals";
3
+ import nextTs from "eslint-config-next/typescript";
4
+
5
+ const eslintConfig = defineConfig([
6
+ ...nextVitals,
7
+ ...nextTs,
8
+ // Override default ignores of eslint-config-next.
9
+ globalIgnores([
10
+ // Default ignores of eslint-config-next:
11
+ ".next/**",
12
+ "out/**",
13
+ "build/**",
14
+ "next-env.d.ts",
15
+ ]),
16
+ ]);
17
+
18
+ export default eslintConfig;
@@ -166,15 +166,23 @@ async function loadLocalPipeline(modelId: string): Promise<any> {
166
166
  let timedOut = false;
167
167
  let lastError: Error | null = null;
168
168
  try {
169
- const { pipeline } = await import('@huggingface/transformers');
170
-
169
+ const { pipeline, env } = await import('@huggingface/transformers');
170
+
171
+ // Configure mirror for China network (only if HF_ENDPOINT env var is not set)
172
+ // Check both process.env and the transformers env object
173
+ if (!process.env.HF_ENDPOINT && !env.remoteHost) {
174
+ console.log('[embedding] Configuring hf-mirror.com for better connectivity in China');
175
+ env.remoteHost = 'https://hf-mirror.com';
176
+ env.remotePathTemplate = '{model}/resolve/{revision}/{fileName}';
177
+ }
178
+
171
179
  // Set up timeout to catch stuck downloads
172
180
  timer = setTimeout(() => {
173
181
  timedOut = true;
174
182
  }, DOWNLOAD_TIMEOUT_MS);
175
-
183
+
176
184
  console.log(`[embedding] Attempt ${attempt + 1}/${DOWNLOAD_MAX_RETRIES + 1}: Loading pipeline for ${modelId}...`);
177
-
185
+
178
186
  // Start download
179
187
  const downloadPromise = pipeline('feature-extraction', modelId, {
180
188
  dtype: 'fp32',
@@ -99,6 +99,7 @@ export const settingsEn = {
99
99
  starting: 'Starting download...',
100
100
  retry: 'Retry',
101
101
  modelReady: 'Model ready',
102
+ downloadFailedHint: 'If download keeps failing, try API mode or set HF_ENDPOINT=https://hf-mirror.com',
102
103
  baseUrl: 'Base URL',
103
104
  baseUrlHint: 'OpenAI-compatible embedding endpoint',
104
105
  apiKey: 'API Key',
@@ -673,6 +674,7 @@ export const settingsZh = {
673
674
  starting: '正在启动下载…',
674
675
  retry: '重试',
675
676
  modelReady: '模型就绪',
677
+ downloadFailedHint: '如果下载持续失败,可切换到 API 模式,或设置环境变量 HF_ENDPOINT=https://hf-mirror.com',
676
678
  baseUrl: 'Base URL',
677
679
  baseUrlHint: 'OpenAI 兼容的嵌入端点',
678
680
  apiKey: 'API Key',