@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.
- package/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +19 -19
- package/_standalone/.next/build-manifest.json +3 -3
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/react-loadable-manifest.json +4 -4
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +1 -1
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +1 -1
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +4 -4
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/channels/verify/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/connect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/embedding/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-docx/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/feishu/long-connection/event/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/feishu/long-connection/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/test/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/webhook/feishu/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/im/webhook-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/clip/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/lint/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/direct-tools/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/tools/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/obsidian/compat-report/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/obsidian/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/prewarm/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/space-overview/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/capture/history/page.js +1 -1
- package/_standalone/.next/server/app/capture/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/capture/history/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/capture/page.js +1 -1
- package/_standalone/.next/server/app/capture/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/capture/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changelog/page.js +1 -1
- package/_standalone/.next/server/app/changelog/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +1 -1
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +1 -1
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +1 -1
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +1 -1
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +1 -1
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +1 -1
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +1 -1
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/todo/page.js +1 -1
- package/_standalone/.next/server/app/todo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/todo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +2 -2
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +2 -2
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/wiki/page.js +2 -0
- package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -0
- package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app-paths-manifest.json +19 -19
- package/_standalone/.next/server/chunks/2250.js +1 -1
- package/_standalone/.next/server/chunks/{1057.js → 3861.js} +2 -2
- package/_standalone/.next/server/chunks/4802.js +30 -30
- package/_standalone/.next/server/chunks/8388.js +1 -1
- package/_standalone/.next/server/middleware-build-manifest.js +1 -1
- package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/chunks/{5581-bae715e40d227b5f.js → 5581-beecbc4ca5625aa9.js} +2 -2
- package/_standalone/.next/static/chunks/6762.c871d0bf3f45ba87.js +1 -0
- package/_standalone/.next/static/chunks/{8064-e65acd2762132099.js → 8064-acac37daf946082b.js} +1 -1
- package/_standalone/.next/static/chunks/{3985.695651f6b5cd768c.js → 8984.91fb8cde1983c564.js} +2 -2
- package/_standalone/.next/static/chunks/app/{layout-0cf6f2a65f605a0d.js → layout-20faba3bc0af7cd2.js} +19 -19
- package/_standalone/.next/static/chunks/app/trash/page-0c2c67929b71ef71.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/not-found-fd06cc989103ebe7.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-dba70888697ba910.js +12 -0
- package/_standalone/.next/static/chunks/app/wiki/page-9bc1fec84d343290.js +14 -0
- package/_standalone/.next/static/chunks/webpack-3c1d0331f1da64b8.js +1 -0
- package/_standalone/.next/trace +97 -97
- package/_standalone/MINDOS_ARCHITECTURE_DIAGRAM.md +488 -0
- package/_standalone/MINDOS_EXPLORATION_SUMMARY.md +229 -0
- package/_standalone/MINDOS_INFRASTRUCTURE_ANALYSIS.md +732 -0
- package/_standalone/__tests__/api/mcp-install.test.ts +8 -2
- package/_standalone/__tests__/core/embedding-provider.test.ts +78 -0
- package/_standalone/__tests__/skills/mindos-skill-copy-alignment.test.ts +10 -4
- package/_standalone/components/ask/AskHeader.tsx +25 -18
- package/_standalone/components/ask/SessionHistoryPanel.tsx +21 -12
- package/_standalone/components/settings/AiTab.tsx +3 -0
- package/_standalone/data/skills/mindos/SKILL.md +269 -0
- package/_standalone/data/skills/mindos/references/write-supplement.md +119 -0
- package/_standalone/data/skills/mindos-zh/SKILL.md +227 -0
- package/_standalone/data/skills/mindos-zh/references/write-supplement.md +119 -0
- package/app/__tests__/api/mcp-install.test.ts +8 -2
- package/app/__tests__/core/embedding-provider.test.ts +78 -0
- package/app/__tests__/skills/mindos-skill-copy-alignment.test.ts +10 -4
- package/app/app/api/ask/route.ts +14 -9
- package/app/app/view/[...path]/ViewPageClient.tsx +15 -12
- package/app/app/view/[...path]/not-found.tsx +9 -5
- package/app/components/ask/AskHeader.tsx +25 -18
- package/app/components/ask/SessionHistoryPanel.tsx +21 -12
- package/app/components/settings/AiTab.tsx +3 -0
- package/app/eslint.config.mjs +18 -0
- package/app/lib/core/embedding-provider.ts +12 -4
- package/app/lib/i18n/modules/settings.ts +2 -0
- package/app/package-lock.json +20214 -0
- package/app/tsconfig.tsbuildinfo +1 -0
- package/app/vitest.config.ts +14 -0
- package/assets/demo-flow-zh.html +622 -0
- package/assets/images/demo-flow-dark.png +0 -0
- package/assets/images/demo-flow-dark.webp +0 -0
- package/assets/images/demo-flow-light.png +0 -0
- package/assets/images/demo-flow-light.webp +0 -0
- package/assets/images/demo-flow-zh-dark.png +0 -0
- package/assets/images/demo-flow-zh-dark.webp +0 -0
- package/assets/images/demo-flow-zh-light.png +0 -0
- package/assets/images/demo-flow-zh-light.webp +0 -0
- package/assets/images/gui-sync-cv.png +0 -0
- package/assets/images/gui-sync-cv.webp +0 -0
- package/assets/images/mindos-chat.png +0 -0
- package/assets/images/mindos-chat.webp +0 -0
- package/assets/images/mindos-dashboard.png +0 -0
- package/assets/images/mindos-dashboard.webp +0 -0
- package/assets/images/mindos-echo.png +0 -0
- package/assets/images/mindos-echo.webp +0 -0
- package/assets/images/mindos-home.png +0 -0
- package/assets/images/mindos-home.webp +0 -0
- package/assets/images/wechat-qr.png +0 -0
- package/bin/lib/mcp-build.js +8 -0
- package/mcp/package-lock.json +2202 -0
- package/mcp/src/index.ts +783 -0
- package/package.json +13 -1
- package/.env.local.example +0 -38
- package/.playwright-cli/page-2026-04-12T12-26-53-393Z.yml +0 -6
- package/.playwright-cli/page-2026-04-12T12-27-20-256Z.yml +0 -120
- package/.syncinclude +0 -105
- package/MINDOS_SEARCH_DIAGRAM.txt +0 -243
- package/_standalone/.next/static/chunks/576.3cae31209383ddbd.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-085f121c0815d542.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/not-found-2a6eec67e91eaaf9.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-faeaf8c09c1c6d7c.js +0 -12
- package/_standalone/.next/static/chunks/webpack-a1bb35f2d540e463.js +0 -1
- package/scripts/build-runtime-archive.sh +0 -151
- package/scripts/fix-postcss-deps.cjs +0 -75
- package/scripts/gen-renderer-index.js +0 -64
- package/scripts/hooks/block-public-merge.sh +0 -42
- package/scripts/hooks/pre-merge-commit +0 -4
- package/scripts/hooks/pre-push +0 -37
- package/scripts/hooks/prepare-commit-msg +0 -12
- package/scripts/migrate-agent-audit-log.js +0 -170
- package/scripts/migrate-agent-diff.js +0 -146
- package/scripts/parse-syncinclude.sh +0 -92
- package/scripts/prepare-standalone.mjs +0 -83
- package/scripts/release.sh +0 -145
- package/scripts/setup.js +0 -1427
- package/scripts/test-oss-upload.sh +0 -100
- package/scripts/verify-standalone.mjs +0 -129
- package/scripts/write-build-stamp.js +0 -40
- /package/_standalone/.next/static/{q5RP_Mx8BrCfvVDnLpRRc → 0UlbV2rA2i4B-8YYg41wQ}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{q5RP_Mx8BrCfvVDnLpRRc → 0UlbV2rA2i4B-8YYg41wQ}/_ssgManifest.js +0 -0
package/app/app/api/ask/route.ts
CHANGED
|
@@ -847,8 +847,11 @@ export async function POST(req: NextRequest) {
|
|
|
847
847
|
});
|
|
848
848
|
acpSessionId = acpSession.id;
|
|
849
849
|
|
|
850
|
-
// ── CRITICAL: Add
|
|
851
|
-
|
|
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
|
-
|
|
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
|
|
1002
|
-
// Prevents indefinite hangs when tools are unresponsive.
|
|
1003
|
-
//
|
|
1004
|
-
//
|
|
1005
|
-
const AGENT_TIMEOUT_MS =
|
|
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
|
-
|
|
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
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
-
|
|
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/
|
|
34
|
-
method: '
|
|
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
|
-
|
|
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
|
-
|
|
97
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
117
|
-
|
|
117
|
+
startTransition(() => {
|
|
118
|
+
onLoad(id);
|
|
119
|
+
onClose();
|
|
120
|
+
});
|
|
118
121
|
}, [onLoad, onClose]);
|
|
119
122
|
|
|
120
123
|
const handleNewChat = useCallback(() => {
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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',
|