@geminilight/mindos 0.6.56 → 0.6.58
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 +21 -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 +8 -8
- package/_standalone/.next/routes-manifest.json +12 -0
- 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 +2 -2
- 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 +2 -6
- 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.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.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/custom/detect/route.js +1 -0
- package/_standalone/.next/server/app/api/agents/custom/detect/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app/api/agents/custom/route.js +1 -0
- package/_standalone/.next/server/app/api/agents/custom/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app/api/ask/route.js +5 -5
- package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
- 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.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/export/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.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js.nft.json +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.js.nft.json +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.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js.nft.json +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/inbox/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route.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.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/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +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/route.js.nft.json +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.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.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.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js.nft.json +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.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.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.js +1 -1
- package/_standalone/.next/server/app/api/skills/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.js.nft.json +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.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
- 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 +1 -1
- package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +21 -19
- package/_standalone/.next/server/chunks/1550.js +1 -1
- package/_standalone/.next/server/chunks/1750.js +1 -1
- package/_standalone/.next/server/chunks/{2190.js → 3484.js} +1 -1
- package/_standalone/.next/server/chunks/530.js +30 -30
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/6793.js +52 -0
- package/_standalone/.next/server/chunks/8388.js +3 -3
- package/_standalone/.next/server/chunks/953.js +2 -2
- 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/2ksXveDzEcnCMRIElDkLq/_buildManifest.js +1 -0
- package/_standalone/.next/static/chunks/1053-fe009233cff06e72.js +29 -0
- package/_standalone/.next/static/chunks/1477.33df3cce509578c2.js +1 -0
- package/_standalone/.next/static/chunks/{1814.b08e9fb85dd3b13c.js → 1814.a7c127b2c73d1f70.js} +1 -1
- package/_standalone/.next/static/chunks/2549-e63cf57fa927a41d.js +1 -0
- package/_standalone/.next/static/chunks/{1007.c11404e50b39d165.js → 2647.e0b67d0c432ad7e7.js} +10 -10
- package/_standalone/.next/static/chunks/{2872.c8c8593be1ba4735.js → 2872.045858d00bd8307f.js} +2 -2
- package/_standalone/.next/static/chunks/362.3978790a2e636c3c.js +2 -0
- package/_standalone/.next/static/chunks/3637.38c4f28d8f698e0e.js +1 -0
- package/_standalone/.next/static/chunks/54a60aa6.7a74f547ec1bdd5a.js +79 -0
- package/_standalone/.next/static/chunks/6087.4b6102dc0bcd07a7.js +1 -0
- package/_standalone/.next/static/chunks/6878-e2c5459e1c608f89.js +1 -0
- package/_standalone/.next/static/chunks/7249-fa98ca10e9a10f39.js +11 -0
- package/_standalone/.next/static/chunks/8252-e5ae7ced3a41e0ed.js +1 -0
- package/_standalone/.next/static/chunks/{8753-ea9db680b0f70f25.js → 8658-16ff58b75ae37fbb.js} +1 -1
- package/_standalone/.next/static/chunks/{7322-d67d05067544864c.js → 9274-296ab35f9f09e42e.js} +1 -1
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/_global-error/page-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-7bdeab5af8e4f5f2.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/page-5d1446665ddb3801.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/raw/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/[segment]/{page-6710da1f581b2854.js → page-b0103509ce34444b.js} +4 -4
- package/_standalone/.next/static/chunks/app/echo/page-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/{layout-d5f28933c5e14d74.js → layout-7e02ddf4144b01f1.js} +11 -11
- package/_standalone/.next/static/chunks/app/loading-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/page-6a6a12bd6d6812d0.js +7 -0
- package/_standalone/.next/static/chunks/app/setup/{page-9a81fa4d82c6351b.js → page-99fcfc460fa29733.js} +1 -1
- package/_standalone/.next/static/chunks/app/trash/page-54cbd5c98d9de69b.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-ca7bdcbf27f88a46.js +12 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2f4705aa66819b86.js +1 -0
- package/_standalone/.next/static/chunks/webpack-2c19436659aa657b.js +1 -0
- package/_standalone/.next/static/css/fd84c8316ead16eb.css +1 -0
- package/_standalone/.next/trace +64 -64
- package/_standalone/.next/types/routes.d.ts +3 -1
- package/_standalone/.next/types/validator.ts +18 -0
- package/_standalone/__tests__/api/mcp-install.test.ts +3 -2
- package/_standalone/__tests__/ask/non-streaming-api.test.ts +281 -0
- package/_standalone/__tests__/core/skill-install-logic.test.ts +1 -0
- package/_standalone/components/Editor.tsx +124 -6
- package/_standalone/components/MarkdownView.tsx +3 -1
- package/_standalone/components/WysiwygEditor.tsx +90 -0
- package/_standalone/components/agents/AgentsOverviewSection.tsx +100 -8
- package/_standalone/components/agents/CustomAgentModal.tsx +637 -0
- package/_standalone/components/settings/types.ts +4 -0
- package/_standalone/data/skills/mindos/SKILL.md +14 -9
- package/_standalone/data/skills/mindos-zh/SKILL.md +13 -4
- package/_standalone/hooks/useEditorImageUpload.ts +113 -0
- package/_standalone/lib/image.ts +47 -0
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/agents/custom/detect/route.ts +31 -0
- package/app/app/api/agents/custom/route.ts +158 -0
- package/app/app/api/ask/route.ts +171 -10
- package/app/app/api/file/import/route.ts +42 -0
- package/app/app/api/mcp/agents/route.ts +62 -8
- package/app/app/api/settings/list-models/route.ts +16 -2
- package/app/app/api/settings/route.ts +9 -0
- package/app/app/api/settings/test-key/route.ts +13 -1
- package/app/components/Editor.tsx +124 -6
- package/app/components/MarkdownView.tsx +3 -1
- package/app/components/WysiwygEditor.tsx +90 -0
- package/app/components/agents/AgentDetailContent.tsx +74 -1
- package/app/components/agents/AgentsContentPage.tsx +76 -1
- package/app/components/agents/AgentsOverviewSection.tsx +100 -8
- package/app/components/agents/CustomAgentModal.tsx +637 -0
- package/app/components/settings/types.ts +4 -0
- package/app/data/skills/mindos/SKILL.md +14 -9
- package/app/data/skills/mindos-zh/SKILL.md +13 -4
- package/app/hooks/useEditorImageUpload.ts +113 -0
- package/app/lib/agent/model.ts +7 -1
- package/app/lib/agent/providers.ts +31 -6
- package/app/lib/core/organize.ts +1 -1
- package/app/lib/core/tree.ts +1 -1
- package/app/lib/custom-agents.ts +322 -0
- package/app/lib/fs.ts +1 -1
- package/app/lib/i18n/modules/panels.ts +104 -0
- package/app/lib/image.ts +47 -0
- package/app/lib/mcp-agents.ts +10 -0
- package/app/lib/settings.ts +4 -0
- package/bin/commands/start.js +5 -4
- package/bin/commands/update.js +6 -2
- package/bin/lib/gateway.js +6 -2
- package/bin/lib/mcp-agents.js +10 -0
- package/mcp/dist/index.cjs +1 -1
- package/mcp/src/index.ts +6 -1
- package/package.json +1 -1
- package/skills/mindos/SKILL.md +10 -4
- package/skills/mindos-max/SKILL.md +191 -0
- package/skills/mindos-max-workspace/evals/evals.json +23 -0
- package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/eval_metadata.json +11 -0
- package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/old_skill/grading.json +28 -0
- package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/old_skill/outputs/transcript.md +203 -0
- package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/with_skill/grading.json +28 -0
- package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/with_skill/outputs/transcript.md +271 -0
- package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/eval_metadata.json +11 -0
- package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/old_skill/grading.json +28 -0
- package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/old_skill/outputs/transcript.md +121 -0
- package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/with_skill/grading.json +28 -0
- package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/with_skill/outputs/transcript.md +168 -0
- package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/eval_metadata.json +11 -0
- package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/old_skill/grading.json +28 -0
- package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/old_skill/outputs/transcript.md +143 -0
- package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/with_skill/grading.json +28 -0
- package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/with_skill/outputs/transcript.md +233 -0
- package/skills/mindos-max-workspace/skill-snapshot/mindos-original/SKILL.md +165 -0
- package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/README.md +12 -0
- package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/post-task-hooks.md +27 -0
- package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/preference-capture.md +41 -0
- package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/sop-template.md +74 -0
- package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/write-supplement.md +119 -0
- package/skills/mindos-max-zh/SKILL.md +192 -0
- package/skills/mindos-zh/SKILL.md +11 -3
- package/_standalone/.next/server/chunks/7543.js +0 -52
- package/_standalone/.next/static/3gMJ8EaZfDgHmB0NR0Q4T/_buildManifest.js +0 -1
- package/_standalone/.next/static/chunks/1053-2874859f7caefa0f.js +0 -29
- package/_standalone/.next/static/chunks/1880-7abf971bcfd2389b.js +0 -11
- package/_standalone/.next/static/chunks/254-32719a9bea2e74f0.js +0 -1
- package/_standalone/.next/static/chunks/362.a77be2f206db7b19.js +0 -1
- package/_standalone/.next/static/chunks/3637.0541ac2d0ea7de1f.js +0 -1
- package/_standalone/.next/static/chunks/54a60aa6.b97ba5e6900c089b.js +0 -79
- package/_standalone/.next/static/chunks/6087.0c32d26d0262c8e7.js +0 -1
- package/_standalone/.next/static/chunks/7035-2af69391c7b1ad95.js +0 -1
- package/_standalone/.next/static/chunks/8131.5e0bdb36bb91f212.js +0 -1
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/_global-error/page-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-f006a70f6889eb56.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-bd522e428e3acb78.js +0 -5
- package/_standalone/.next/static/chunks/app/api/a2a/agents/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/raw/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/page-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/loading-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/page-45140253e07a135a.js +0 -7
- package/_standalone/.next/static/chunks/app/trash/page-c7f14311f040009e.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-62cfae628e31d411.js +0 -12
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e240db6d5049d336.js +0 -1
- package/_standalone/.next/static/chunks/webpack-521ae5a2ddf0e396.js +0 -1
- package/_standalone/.next/static/css/66f8a81e4eda06d4.css +0 -1
- /package/_standalone/.next/static/{3gMJ8EaZfDgHmB0NR0Q4T → 2ksXveDzEcnCMRIElDkLq}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const dynamic = 'force-dynamic';
|
|
2
|
+
|
|
3
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
4
|
+
import { detectBaseDir } from '@/lib/custom-agents';
|
|
5
|
+
|
|
6
|
+
/** POST — Auto-detect config files in a baseDir. */
|
|
7
|
+
export async function POST(req: NextRequest) {
|
|
8
|
+
try {
|
|
9
|
+
const body = await req.json();
|
|
10
|
+
const { baseDir } = body as { baseDir?: string };
|
|
11
|
+
|
|
12
|
+
if (!baseDir?.trim()) {
|
|
13
|
+
return NextResponse.json({ error: 'baseDir is required' }, { status: 400 });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const dir = baseDir.trim();
|
|
17
|
+
|
|
18
|
+
// Security: restrict to home directory only
|
|
19
|
+
if (!dir.startsWith('~/')) {
|
|
20
|
+
return NextResponse.json(
|
|
21
|
+
{ error: 'baseDir must start with ~/ (e.g. ~/.qclaw/)' },
|
|
22
|
+
{ status: 400 },
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const result = detectBaseDir(dir);
|
|
27
|
+
return NextResponse.json(result);
|
|
28
|
+
} catch (err) {
|
|
29
|
+
return NextResponse.json({ error: String(err) }, { status: 500 });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
export const dynamic = 'force-dynamic';
|
|
2
|
+
|
|
3
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
4
|
+
import { MCP_AGENTS } from '@/lib/mcp-agents';
|
|
5
|
+
import {
|
|
6
|
+
loadCustomAgents,
|
|
7
|
+
saveCustomAgents,
|
|
8
|
+
inferDefaults,
|
|
9
|
+
slugify,
|
|
10
|
+
generateUniqueKey,
|
|
11
|
+
validateCustomAgentInput,
|
|
12
|
+
type CustomAgentDef,
|
|
13
|
+
} from '@/lib/custom-agents';
|
|
14
|
+
|
|
15
|
+
/** POST — Create a new custom agent. */
|
|
16
|
+
export async function POST(req: NextRequest) {
|
|
17
|
+
try {
|
|
18
|
+
const body = await req.json();
|
|
19
|
+
const { name, baseDir, ...overrides } = body as Partial<CustomAgentDef> & { name?: string; baseDir?: string };
|
|
20
|
+
|
|
21
|
+
if (!name?.trim() || !baseDir?.trim()) {
|
|
22
|
+
return NextResponse.json({ error: 'name and baseDir are required' }, { status: 400 });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const customs = loadCustomAgents();
|
|
26
|
+
const existingKeys = new Set([
|
|
27
|
+
...Object.keys(MCP_AGENTS),
|
|
28
|
+
...customs.map(c => c.key),
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
const key = overrides.key && !existingKeys.has(overrides.key)
|
|
32
|
+
? overrides.key
|
|
33
|
+
: generateUniqueKey(name.trim(), existingKeys);
|
|
34
|
+
|
|
35
|
+
const error = validateCustomAgentInput({ name, baseDir, key }, existingKeys);
|
|
36
|
+
if (error) {
|
|
37
|
+
return NextResponse.json({ error }, { status: 400 });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const defaults = inferDefaults(name.trim(), baseDir.trim());
|
|
41
|
+
const agent: CustomAgentDef = {
|
|
42
|
+
...defaults,
|
|
43
|
+
key,
|
|
44
|
+
...(overrides.global && { global: overrides.global }),
|
|
45
|
+
...(overrides.project !== undefined && { project: overrides.project }),
|
|
46
|
+
...(overrides.configKey && { configKey: overrides.configKey }),
|
|
47
|
+
...(overrides.format && { format: overrides.format }),
|
|
48
|
+
...(overrides.preferredTransport && { preferredTransport: overrides.preferredTransport }),
|
|
49
|
+
...(overrides.presenceDirs && { presenceDirs: overrides.presenceDirs }),
|
|
50
|
+
...(overrides.presenceCli && { presenceCli: overrides.presenceCli }),
|
|
51
|
+
...(overrides.globalNestedKey && { globalNestedKey: overrides.globalNestedKey }),
|
|
52
|
+
...(overrides.skillDir && { skillDir: overrides.skillDir }),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
customs.push(agent);
|
|
56
|
+
saveCustomAgents(customs);
|
|
57
|
+
|
|
58
|
+
return NextResponse.json({ agent }, { status: 201 });
|
|
59
|
+
} catch (err) {
|
|
60
|
+
return NextResponse.json({ error: String(err) }, { status: 500 });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** PUT — Update an existing custom agent. */
|
|
65
|
+
export async function PUT(req: NextRequest) {
|
|
66
|
+
try {
|
|
67
|
+
const body = await req.json();
|
|
68
|
+
const { key, ...updates } = body as Partial<CustomAgentDef> & { key: string };
|
|
69
|
+
|
|
70
|
+
if (!key) {
|
|
71
|
+
return NextResponse.json({ error: 'key is required' }, { status: 400 });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const customs = loadCustomAgents();
|
|
75
|
+
const idx = customs.findIndex(c => c.key === key);
|
|
76
|
+
|
|
77
|
+
if (idx === -1) {
|
|
78
|
+
return NextResponse.json({ error: `Custom agent "${key}" not found` }, { status: 404 });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const existing = customs[idx];
|
|
82
|
+
|
|
83
|
+
// Validate enum fields
|
|
84
|
+
if (updates.format && !['json', 'toml'].includes(updates.format)) {
|
|
85
|
+
return NextResponse.json({ error: 'format must be "json" or "toml"' }, { status: 400 });
|
|
86
|
+
}
|
|
87
|
+
if (updates.preferredTransport && !['stdio', 'http'].includes(updates.preferredTransport)) {
|
|
88
|
+
return NextResponse.json({ error: 'preferredTransport must be "stdio" or "http"' }, { status: 400 });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Validate baseDir if changed
|
|
92
|
+
if (updates.baseDir) {
|
|
93
|
+
const dir = updates.baseDir.trim();
|
|
94
|
+
if (!dir.startsWith('~/') && !dir.startsWith('/')) {
|
|
95
|
+
return NextResponse.json({ error: 'baseDir must be an absolute path' }, { status: 400 });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const updated: CustomAgentDef = {
|
|
100
|
+
...existing,
|
|
101
|
+
...(updates.name && { name: updates.name }),
|
|
102
|
+
...(updates.baseDir && { baseDir: updates.baseDir }),
|
|
103
|
+
...(updates.global && { global: updates.global }),
|
|
104
|
+
...(updates.project !== undefined && { project: updates.project }),
|
|
105
|
+
...(updates.configKey && { configKey: updates.configKey }),
|
|
106
|
+
...(updates.format && { format: updates.format }),
|
|
107
|
+
...(updates.preferredTransport && { preferredTransport: updates.preferredTransport }),
|
|
108
|
+
...(updates.presenceCli !== undefined && { presenceCli: updates.presenceCli || undefined }),
|
|
109
|
+
...(updates.globalNestedKey !== undefined && { globalNestedKey: updates.globalNestedKey || undefined }),
|
|
110
|
+
...(updates.skillDir !== undefined && { skillDir: updates.skillDir || undefined }),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// Update presenceDirs: explicit override takes priority, then baseDir-derived default
|
|
114
|
+
if (updates.presenceDirs) {
|
|
115
|
+
updated.presenceDirs = updates.presenceDirs;
|
|
116
|
+
} else if (updates.baseDir) {
|
|
117
|
+
updated.presenceDirs = [updates.baseDir.endsWith('/') ? updates.baseDir : updates.baseDir + '/'];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Update skillDir default when baseDir changes and no explicit skillDir
|
|
121
|
+
if (!updates.skillDir && updates.baseDir) {
|
|
122
|
+
const bd = updates.baseDir.endsWith('/') ? updates.baseDir : updates.baseDir + '/';
|
|
123
|
+
updated.skillDir = bd + 'skills/';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
customs[idx] = updated;
|
|
127
|
+
saveCustomAgents(customs);
|
|
128
|
+
|
|
129
|
+
return NextResponse.json({ agent: updated });
|
|
130
|
+
} catch (err) {
|
|
131
|
+
return NextResponse.json({ error: String(err) }, { status: 500 });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** DELETE — Remove a custom agent. */
|
|
136
|
+
export async function DELETE(req: NextRequest) {
|
|
137
|
+
try {
|
|
138
|
+
const body = await req.json();
|
|
139
|
+
const { key } = body as { key: string };
|
|
140
|
+
|
|
141
|
+
if (!key) {
|
|
142
|
+
return NextResponse.json({ error: 'key is required' }, { status: 400 });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const customs = loadCustomAgents();
|
|
146
|
+
const filtered = customs.filter(c => c.key !== key);
|
|
147
|
+
|
|
148
|
+
if (filtered.length === customs.length) {
|
|
149
|
+
return NextResponse.json({ error: `Custom agent "${key}" not found` }, { status: 404 });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
saveCustomAgents(filtered);
|
|
153
|
+
|
|
154
|
+
return NextResponse.json({ removed: key });
|
|
155
|
+
} catch (err) {
|
|
156
|
+
return NextResponse.json({ error: String(err) }, { status: 500 });
|
|
157
|
+
}
|
|
158
|
+
}
|
package/app/app/api/ask/route.ts
CHANGED
|
@@ -405,6 +405,143 @@ function toPiCustomToolDefinitions(tools: AgentTool<any>[]): ToolDefinition<any,
|
|
|
405
405
|
// Non-streaming fallback for proxies that don't support stream + tools
|
|
406
406
|
// ---------------------------------------------------------------------------
|
|
407
407
|
|
|
408
|
+
/**
|
|
409
|
+
* Reassemble SSE chunks (from proxies that ignore stream:false) into a
|
|
410
|
+
* single OpenAI-style chat completion response.
|
|
411
|
+
*
|
|
412
|
+
* SSE format: data: {"choices":[{"delta":{"content":"He"}}]}
|
|
413
|
+
* Output: {"choices":[{"message":{"role":"assistant","content":"Hello!"},"finish_reason":"stop"}]}
|
|
414
|
+
*/
|
|
415
|
+
function reassembleSSE(sseText: string): any {
|
|
416
|
+
const lines = sseText.split('\n');
|
|
417
|
+
let content = '';
|
|
418
|
+
let role = 'assistant';
|
|
419
|
+
let finishReason = 'stop';
|
|
420
|
+
const toolCalls: Map<number, { id: string; type: string; function: { name: string; arguments: string } }> = new Map();
|
|
421
|
+
|
|
422
|
+
for (const line of lines) {
|
|
423
|
+
const trimmed = line.trim();
|
|
424
|
+
if (!trimmed.startsWith('data:')) continue;
|
|
425
|
+
const payload = trimmed.slice(5).trim();
|
|
426
|
+
if (payload === '[DONE]') break;
|
|
427
|
+
|
|
428
|
+
let chunk: any;
|
|
429
|
+
try {
|
|
430
|
+
chunk = JSON.parse(payload);
|
|
431
|
+
} catch {
|
|
432
|
+
continue; // skip unparseable lines
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const delta = chunk?.choices?.[0]?.delta;
|
|
436
|
+
if (!delta) continue;
|
|
437
|
+
|
|
438
|
+
if (delta.role) role = delta.role;
|
|
439
|
+
if (delta.content) content += delta.content;
|
|
440
|
+
if (chunk.choices[0].finish_reason) finishReason = chunk.choices[0].finish_reason;
|
|
441
|
+
|
|
442
|
+
// Accumulate tool calls (they arrive in incremental deltas)
|
|
443
|
+
if (delta.tool_calls) {
|
|
444
|
+
for (const tc of delta.tool_calls) {
|
|
445
|
+
const idx = tc.index ?? 0;
|
|
446
|
+
const existing = toolCalls.get(idx);
|
|
447
|
+
if (!existing) {
|
|
448
|
+
toolCalls.set(idx, {
|
|
449
|
+
id: tc.id ?? '',
|
|
450
|
+
type: tc.type ?? 'function',
|
|
451
|
+
function: {
|
|
452
|
+
name: tc.function?.name ?? '',
|
|
453
|
+
arguments: tc.function?.arguments ?? '',
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
} else {
|
|
457
|
+
if (tc.id) existing.id = tc.id;
|
|
458
|
+
if (tc.function?.name) existing.function.name += tc.function.name;
|
|
459
|
+
if (tc.function?.arguments) existing.function.arguments += tc.function.arguments;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const message: any = { role, content: content || null };
|
|
466
|
+
if (toolCalls.size > 0) {
|
|
467
|
+
message.tool_calls = Array.from(toolCalls.values());
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
return {
|
|
471
|
+
choices: [{ message, finish_reason: finishReason }],
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Convert pi-ai format messages to OpenAI API format.
|
|
477
|
+
* pi-ai messages have nested structures; OpenAI format is flatter with tool_calls array.
|
|
478
|
+
*/
|
|
479
|
+
function piMessagesToOpenAI(piMessages: any[]): any[] {
|
|
480
|
+
return piMessages.map(msg => {
|
|
481
|
+
const role = msg.role;
|
|
482
|
+
|
|
483
|
+
// Skip system role (will be added separately)
|
|
484
|
+
if (role === 'system') return null;
|
|
485
|
+
|
|
486
|
+
// Pass through user messages (simple string content)
|
|
487
|
+
if (role === 'user') {
|
|
488
|
+
return {
|
|
489
|
+
role: 'user',
|
|
490
|
+
content: typeof msg.content === 'string' ? msg.content : msg.content,
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Assistant messages: flatten content array into text + tool_calls
|
|
495
|
+
if (role === 'assistant') {
|
|
496
|
+
const content = msg.content;
|
|
497
|
+
let textContent = '';
|
|
498
|
+
const toolCalls: any[] = [];
|
|
499
|
+
|
|
500
|
+
if (Array.isArray(content)) {
|
|
501
|
+
for (const part of content) {
|
|
502
|
+
if (part.type === 'text' && part.text) {
|
|
503
|
+
textContent += part.text;
|
|
504
|
+
} else if (part.type === 'toolCall') {
|
|
505
|
+
toolCalls.push({
|
|
506
|
+
id: part.id ?? `call_${Date.now()}`,
|
|
507
|
+
type: 'function',
|
|
508
|
+
function: {
|
|
509
|
+
name: part.name ?? 'unknown',
|
|
510
|
+
arguments: JSON.stringify(part.arguments ?? {}),
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const result: any = { role: 'assistant' };
|
|
518
|
+
// Always include content (even if empty) for tool-call-only messages
|
|
519
|
+
// OpenAI API may handle this differently, but it's safer to include empty string
|
|
520
|
+
result.content = textContent || '';
|
|
521
|
+
if (toolCalls.length > 0) result.tool_calls = toolCalls;
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Tool result messages
|
|
526
|
+
if (role === 'toolResult') {
|
|
527
|
+
const contentText = Array.isArray(msg.content)
|
|
528
|
+
? msg.content
|
|
529
|
+
.filter((c: any) => c.type === 'text')
|
|
530
|
+
.map((c: any) => c.text ?? '')
|
|
531
|
+
.join('\n')
|
|
532
|
+
: String(msg.content ?? '');
|
|
533
|
+
|
|
534
|
+
return {
|
|
535
|
+
role: 'tool',
|
|
536
|
+
tool_call_id: msg.toolCallId ?? 'unknown',
|
|
537
|
+
content: contentText,
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return null;
|
|
542
|
+
}).filter(Boolean);
|
|
543
|
+
}
|
|
544
|
+
|
|
408
545
|
/**
|
|
409
546
|
* Mini agent loop using non-streaming OpenAI-compatible API.
|
|
410
547
|
* Used when a proxy silently breaks stream+tools by returning plain text.
|
|
@@ -415,7 +552,7 @@ async function runNonStreamingFallback(opts: {
|
|
|
415
552
|
apiKey: string;
|
|
416
553
|
model: string;
|
|
417
554
|
systemPrompt: string;
|
|
418
|
-
historyMessages:
|
|
555
|
+
historyMessages: any[];
|
|
419
556
|
userContent: string;
|
|
420
557
|
tools: AgentTool<any>[];
|
|
421
558
|
send: (event: MindOSSSEvent) => void;
|
|
@@ -433,9 +570,12 @@ async function runNonStreamingFallback(opts: {
|
|
|
433
570
|
},
|
|
434
571
|
}));
|
|
435
572
|
|
|
436
|
-
|
|
573
|
+
// Convert pi-ai format messages to OpenAI format
|
|
574
|
+
const openaiMessages = piMessagesToOpenAI(historyMessages);
|
|
575
|
+
|
|
576
|
+
const messages: { role: string; content?: unknown; tool_calls?: unknown; tool_call_id?: string }[] = [
|
|
437
577
|
{ role: 'system', content: systemPrompt },
|
|
438
|
-
...
|
|
578
|
+
...openaiMessages,
|
|
439
579
|
{ role: 'user', content: userContent },
|
|
440
580
|
];
|
|
441
581
|
|
|
@@ -447,6 +587,9 @@ async function runNonStreamingFallback(opts: {
|
|
|
447
587
|
if (signal.aborted) throw new Error('Request aborted');
|
|
448
588
|
step++;
|
|
449
589
|
|
|
590
|
+
// Use stream:true and parse SSE ourselves.
|
|
591
|
+
// Many proxies ignore stream:false (returning SSE with empty choices or broken JSON).
|
|
592
|
+
// Using stream:true is the most universally compatible approach.
|
|
450
593
|
const resp = await fetch(endpoint, {
|
|
451
594
|
method: 'POST',
|
|
452
595
|
headers: {
|
|
@@ -458,7 +601,7 @@ async function runNonStreamingFallback(opts: {
|
|
|
458
601
|
messages,
|
|
459
602
|
tools: openaiTools.length > 0 ? openaiTools : undefined,
|
|
460
603
|
tool_choice: openaiTools.length > 0 ? 'auto' : undefined,
|
|
461
|
-
stream:
|
|
604
|
+
stream: true,
|
|
462
605
|
}),
|
|
463
606
|
signal,
|
|
464
607
|
});
|
|
@@ -468,11 +611,28 @@ async function runNonStreamingFallback(opts: {
|
|
|
468
611
|
throw new Error(`Non-streaming API error ${resp.status}: ${errText.slice(0, 200)}`);
|
|
469
612
|
}
|
|
470
613
|
|
|
471
|
-
|
|
614
|
+
// Read the full response body (SSE or JSON)
|
|
615
|
+
const rawText = await resp.text();
|
|
616
|
+
const trimmed = rawText.trimStart();
|
|
617
|
+
|
|
618
|
+
let data: any;
|
|
619
|
+
if (trimmed.startsWith('data:')) {
|
|
620
|
+
// Response is SSE — reassemble chunks into a single OpenAI response
|
|
621
|
+
data = reassembleSSE(trimmed);
|
|
622
|
+
} else {
|
|
623
|
+
// Some endpoints might still return plain JSON even with stream:true
|
|
624
|
+
try {
|
|
625
|
+
data = JSON.parse(rawText);
|
|
626
|
+
} catch {
|
|
627
|
+
throw new Error(`API returned invalid response: ${rawText.slice(0, 200)}`);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
472
631
|
const choice = data?.choices?.[0];
|
|
473
632
|
if (!choice) throw new Error('Empty response from API');
|
|
474
633
|
|
|
475
|
-
|
|
634
|
+
// reassembleSSE always produces .message; standard JSON may use .message or .delta
|
|
635
|
+
const msg = choice.message ?? choice.delta ?? {};
|
|
476
636
|
const finishReason: string = choice.finish_reason ?? 'stop';
|
|
477
637
|
|
|
478
638
|
// Emit text content in chunks to simulate streaming appearance
|
|
@@ -1185,11 +1345,12 @@ export async function POST(req: NextRequest) {
|
|
|
1185
1345
|
if (lastPromptError) throw lastPromptError;
|
|
1186
1346
|
|
|
1187
1347
|
metrics.recordRequest(Date.now() - requestStartTime);
|
|
1188
|
-
if (!hasContent && lastModelError) {
|
|
1189
|
-
// No content received —
|
|
1190
|
-
//
|
|
1348
|
+
if (!hasContent && (lastModelError || (baseUrl && provider === 'openai'))) {
|
|
1349
|
+
// No content received — either a model error or proxy compatibility issue.
|
|
1350
|
+
// For OpenAI-compatible endpoints with custom baseUrl, always try the fallback
|
|
1351
|
+
// even without an explicit error (some proxies silently return empty responses).
|
|
1191
1352
|
if (baseUrl && provider === 'openai') {
|
|
1192
|
-
send({ type: 'status', message: t.proxyCompatDetecting });
|
|
1353
|
+
send({ type: 'status', message: lastModelError ? t.proxyCompatDetecting : t.proxyCompatMode });
|
|
1193
1354
|
try {
|
|
1194
1355
|
await runNonStreamingFallback({
|
|
1195
1356
|
baseUrl,
|
|
@@ -15,6 +15,19 @@ import { invalidateCache } from '@/lib/fs';
|
|
|
15
15
|
const MAX_FILES = 20;
|
|
16
16
|
const MAX_CONTENT_LENGTH = 5 * 1024 * 1024;
|
|
17
17
|
|
|
18
|
+
/** File extensions that are binary and should be written as raw buffers, not text. */
|
|
19
|
+
const BINARY_EXTENSIONS = new Set([
|
|
20
|
+
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.ico',
|
|
21
|
+
'.mp3', '.wav', '.m4a', '.ogg', '.flac', '.aac',
|
|
22
|
+
'.mp4', '.webm', '.mov', '.mkv',
|
|
23
|
+
'.pdf',
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
function isBinaryFile(name: string): boolean {
|
|
27
|
+
const ext = path.extname(name).toLowerCase();
|
|
28
|
+
return BINARY_EXTENSIONS.has(ext);
|
|
29
|
+
}
|
|
30
|
+
|
|
18
31
|
type ConflictMode = 'skip' | 'rename' | 'overwrite';
|
|
19
32
|
|
|
20
33
|
interface ImportRequest {
|
|
@@ -136,6 +149,35 @@ export async function POST(req: NextRequest) {
|
|
|
136
149
|
|
|
137
150
|
const sanitized = sanitizeFileName(entry.name);
|
|
138
151
|
const encoding = entry.encoding === 'base64' ? 'base64' : 'text';
|
|
152
|
+
|
|
153
|
+
// Binary files (images, audio, video, PDF): write raw buffer, skip text conversion
|
|
154
|
+
if (encoding === 'base64' && isBinaryFile(sanitized)) {
|
|
155
|
+
const buf = Buffer.from(entry.content, 'base64');
|
|
156
|
+
|
|
157
|
+
let relPath = targetSpaceNorm
|
|
158
|
+
? path.posix.join(targetSpaceNorm, sanitized)
|
|
159
|
+
: sanitized;
|
|
160
|
+
|
|
161
|
+
const { relPath: finalRel, resolved, skipped: skipReason } = resolveUniquePath(
|
|
162
|
+
mindRoot,
|
|
163
|
+
relPath,
|
|
164
|
+
conflict,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (skipReason) {
|
|
168
|
+
skipped.push({ name: entry.name, reason: skipReason });
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
fs.mkdirSync(path.dirname(resolved), { recursive: true });
|
|
173
|
+
fs.writeFileSync(resolved, buf);
|
|
174
|
+
|
|
175
|
+
created.push({ original: entry.name, path: finalRel });
|
|
176
|
+
createdPaths.push(finalRel);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Text files: decode and convert to markdown
|
|
139
181
|
const raw = decodeFileContent(encoding, entry.content, sanitized);
|
|
140
182
|
const convertResult = convertToMarkdown(sanitized, raw);
|
|
141
183
|
|
|
@@ -3,8 +3,10 @@ import os from 'os';
|
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { NextResponse } from 'next/server';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
6
7
|
import {
|
|
7
8
|
MCP_AGENTS,
|
|
9
|
+
expandHome,
|
|
8
10
|
detectInstalled,
|
|
9
11
|
detectAgentPresence,
|
|
10
12
|
detectAgentRuntimeSignals,
|
|
@@ -12,6 +14,7 @@ import {
|
|
|
12
14
|
detectAgentInstalledSkills,
|
|
13
15
|
resolveSkillWorkspaceProfile,
|
|
14
16
|
} from '@/lib/mcp-agents';
|
|
17
|
+
import { getAllAgents, loadCustomAgents, scanCustomAgentSkills } from '@/lib/custom-agents';
|
|
15
18
|
import { readSettings } from '@/lib/settings';
|
|
16
19
|
import { scanSkillDirs } from '@/lib/pi-integration/skills';
|
|
17
20
|
import { getMindRoot } from '@/lib/fs';
|
|
@@ -59,13 +62,62 @@ function enrichMindOsAgent(agent: Record<string, unknown>) {
|
|
|
59
62
|
|
|
60
63
|
export async function GET() {
|
|
61
64
|
try {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
65
|
+
const allAgents = getAllAgents();
|
|
66
|
+
const customDefs = loadCustomAgents();
|
|
67
|
+
const customKeySet = new Set(customDefs.map(c => c.key));
|
|
68
|
+
const customByKey = Object.fromEntries(customDefs.map(c => [c.key, c]));
|
|
69
|
+
|
|
70
|
+
const agents = Object.entries(allAgents).map(([key, agent]) => {
|
|
71
|
+
const isCustom = customKeySet.has(key) && !(key in MCP_AGENTS);
|
|
72
|
+
|
|
73
|
+
// Built-in agents: use standard detection. Custom agents: detect using their AgentDef directly.
|
|
74
|
+
let present: boolean;
|
|
75
|
+
let status: { installed: boolean; scope?: string; transport?: string; configPath?: string; url?: string };
|
|
76
|
+
|
|
77
|
+
if (isCustom) {
|
|
78
|
+
present = agent.presenceDirs?.some((d: string) => fs.existsSync(expandHome(d))) ?? false;
|
|
79
|
+
if (agent.presenceCli) {
|
|
80
|
+
try {
|
|
81
|
+
execSync(
|
|
82
|
+
process.platform === 'win32' ? `where ${agent.presenceCli}` : `which ${agent.presenceCli}`,
|
|
83
|
+
{ stdio: 'pipe' },
|
|
84
|
+
);
|
|
85
|
+
present = true;
|
|
86
|
+
} catch { /* not in PATH */ }
|
|
87
|
+
}
|
|
88
|
+
status = { installed: false };
|
|
89
|
+
const globalPath = expandHome(agent.global);
|
|
90
|
+
try {
|
|
91
|
+
if (fs.existsSync(globalPath)) {
|
|
92
|
+
const raw = fs.readFileSync(globalPath, 'utf-8');
|
|
93
|
+
const parsed = JSON.parse(raw);
|
|
94
|
+
const configObj = agent.globalNestedKey
|
|
95
|
+
? agent.globalNestedKey.split('.').reduce((o: Record<string, unknown>, k: string) => (o?.[k] as Record<string, unknown>) ?? {}, parsed)
|
|
96
|
+
: parsed;
|
|
97
|
+
const servers = configObj?.[agent.key] ?? {};
|
|
98
|
+
if (servers && typeof servers === 'object' && 'mindos' in servers) {
|
|
99
|
+
status = { installed: true, scope: 'global', configPath: globalPath };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch { /* config not parseable */ }
|
|
103
|
+
} else {
|
|
104
|
+
present = detectAgentPresence(key);
|
|
105
|
+
status = detectInstalled(key);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const skillProfile = isCustom
|
|
109
|
+
? { mode: 'additional' as const, skillAgentName: key, workspacePath: expandHome(customByKey[key]?.skillDir || agent.presenceDirs?.[0] + 'skills/') }
|
|
110
|
+
: resolveSkillWorkspaceProfile(key);
|
|
111
|
+
const runtime = isCustom
|
|
112
|
+
? { hiddenRootPath: '', hiddenRootPresent: false, conversationSignal: false, usageSignal: false, lastActivityAt: undefined }
|
|
113
|
+
: detectAgentRuntimeSignals(key);
|
|
114
|
+
const configuredMcp = isCustom
|
|
115
|
+
? { servers: [] as string[], sources: [] as string[] }
|
|
116
|
+
: detectAgentConfiguredMcpServers(key);
|
|
117
|
+
const installedSkills = isCustom
|
|
118
|
+
? scanCustomAgentSkills(customByKey[key])
|
|
119
|
+
: detectAgentInstalledSkills(key);
|
|
120
|
+
|
|
69
121
|
return {
|
|
70
122
|
key,
|
|
71
123
|
name: agent.name,
|
|
@@ -74,7 +126,7 @@ export async function GET() {
|
|
|
74
126
|
scope: status.scope,
|
|
75
127
|
transport: status.transport,
|
|
76
128
|
configPath: status.configPath,
|
|
77
|
-
url: status.url,
|
|
129
|
+
url: status.url,
|
|
78
130
|
hasProjectScope: !!agent.project,
|
|
79
131
|
hasGlobalScope: !!agent.global,
|
|
80
132
|
preferredTransport: agent.preferredTransport,
|
|
@@ -97,6 +149,8 @@ export async function GET() {
|
|
|
97
149
|
installedSkillNames: installedSkills.skills,
|
|
98
150
|
installedSkillCount: installedSkills.skills.length,
|
|
99
151
|
installedSkillSourcePath: installedSkills.sourcePath,
|
|
152
|
+
isCustom,
|
|
153
|
+
customBaseDir: isCustom ? customByKey[key]?.baseDir : undefined,
|
|
100
154
|
};
|
|
101
155
|
});
|
|
102
156
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export const dynamic = 'force-dynamic';
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
|
+
import { getModels as piGetModels } from '@mariozechner/pi-ai';
|
|
3
4
|
import { effectiveAiConfig } from '@/lib/settings';
|
|
4
|
-
import { type ProviderId, isProviderId, PROVIDER_PRESETS, getDefaultBaseUrl } from '@/lib/agent/providers';
|
|
5
|
+
import { type ProviderId, isProviderId, PROVIDER_PRESETS, toPiProvider, getDefaultBaseUrl } from '@/lib/agent/providers';
|
|
5
6
|
|
|
6
7
|
const TIMEOUT = 10_000;
|
|
7
8
|
|
|
@@ -19,8 +20,11 @@ export async function POST(req: NextRequest) {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const preset = PROVIDER_PRESETS[provider as ProviderId];
|
|
23
|
+
|
|
24
|
+
// Providers without remote list-models API: return static list from pi-ai registry
|
|
22
25
|
if (!preset.supportsListModels) {
|
|
23
|
-
|
|
26
|
+
const models = getRegistryModels(provider as ProviderId);
|
|
27
|
+
return NextResponse.json({ ok: true, models });
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
const cfg = effectiveAiConfig(provider as ProviderId);
|
|
@@ -52,6 +56,16 @@ export async function POST(req: NextRequest) {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
/** Return model IDs from pi-ai's static registry for providers without a remote /models API. */
|
|
60
|
+
function getRegistryModels(provider: ProviderId): string[] {
|
|
61
|
+
try {
|
|
62
|
+
const models = piGetModels(toPiProvider(provider) as any);
|
|
63
|
+
return models.map((m: any) => m.id as string).filter(Boolean).sort();
|
|
64
|
+
} catch {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
55
69
|
async function fetchModels(provider: ProviderId, apiKey: string, baseUrl: string, signal: AbortSignal): Promise<string[]> {
|
|
56
70
|
if (provider === 'anthropic') {
|
|
57
71
|
return fetchAnthropicModels(apiKey, signal);
|
|
@@ -124,6 +124,15 @@ export async function POST(req: NextRequest) {
|
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
writeSettings(next);
|
|
127
|
+
// Clear proxy compat cache when AI config changes — stale cache causes
|
|
128
|
+
// the non-streaming fallback to be used even when streaming would work.
|
|
129
|
+
if (JSON.stringify(next.ai) !== JSON.stringify(current.ai)) {
|
|
130
|
+
const { readSettings: rs, writeSettings: ws } = await import('@/lib/settings');
|
|
131
|
+
const s = rs();
|
|
132
|
+
if (s.baseUrlCompat && Object.keys(s.baseUrlCompat).length > 0) {
|
|
133
|
+
ws({ ...s, baseUrlCompat: {} });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
127
136
|
if (next.mindRoot !== current.mindRoot) invalidateCache();
|
|
128
137
|
return NextResponse.json({ ok: true });
|
|
129
138
|
} catch (err) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const dynamic = 'force-dynamic';
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
3
|
import { complete } from '@mariozechner/pi-ai';
|
|
4
|
-
import { effectiveAiConfig } from '@/lib/settings';
|
|
4
|
+
import { effectiveAiConfig, readBaseUrlCompat, writeSettings, readSettings } from '@/lib/settings';
|
|
5
5
|
import { getModelConfig } from '@/lib/agent/model';
|
|
6
6
|
import { type ProviderId, isProviderId } from '@/lib/agent/providers';
|
|
7
7
|
|
|
@@ -84,6 +84,18 @@ export async function POST(req: NextRequest) {
|
|
|
84
84
|
signal: ctrl.signal,
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
// Clear stale proxy compat cache for this baseUrl on successful test.
|
|
88
|
+
// Prevents stale 'non-streaming' cache from forcing the fallback path.
|
|
89
|
+
if (baseUrl) {
|
|
90
|
+
const compat = readBaseUrlCompat();
|
|
91
|
+
if (compat[baseUrl]) {
|
|
92
|
+
const s = readSettings();
|
|
93
|
+
const updated = { ...(s.baseUrlCompat ?? {}) };
|
|
94
|
+
delete updated[baseUrl];
|
|
95
|
+
writeSettings({ ...s, baseUrlCompat: updated });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
return NextResponse.json({ ok: true, latency: Date.now() - start });
|
|
88
100
|
} catch (e) {
|
|
89
101
|
return NextResponse.json({ ok: false, ...classifyPiAiError(e) });
|