@geminilight/mindos 0.6.67 → 0.6.70
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 +26 -25
- 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 +7 -7
- package/_standalone/.next/routes-manifest.json +6 -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 +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.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.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.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route.js.nft.json +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.js.nft.json +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 +17 -17
- 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/channels/verify/route.js +1 -0
- package/_standalone/.next/server/app/api/channels/verify/route.js.nft.json +1 -0
- package/_standalone/.next/server/app/api/channels/verify/route_client-reference-manifest.js +1 -0
- package/_standalone/.next/server/app/api/connect/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.js +2 -2
- 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/im/config/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/inbox/clip/route.js.nft.json +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.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/lint/route.js.nft.json +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.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/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.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_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_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.js +2 -2
- package/_standalone/.next/server/app/api/space-overview/route.js.nft.json +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.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/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/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 +26 -25
- package/_standalone/.next/server/chunks/3437.js +2 -2
- package/_standalone/.next/server/chunks/5299.js +1 -0
- package/_standalone/.next/server/chunks/6022.js +39 -39
- package/_standalone/.next/server/chunks/6133.js +54 -0
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/8326.js +1 -0
- package/_standalone/.next/server/chunks/8388.js +5 -3
- package/_standalone/.next/server/chunks/953.js +6 -4
- package/_standalone/.next/server/chunks/9938.js +24 -0
- 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/1814.8a1fef15856dce84.js +1 -0
- package/_standalone/.next/static/chunks/2654-e07c692d6c99f25b.js +1 -0
- package/_standalone/.next/static/chunks/{2935.7d75923daaf448d3.js → 2935.9b08eeade3644806.js} +1 -1
- package/_standalone/.next/static/chunks/3269.a7343771e3f0ff58.js +48 -0
- package/_standalone/.next/static/chunks/3637.2b2697198968d83f.js +1 -0
- package/_standalone/.next/static/chunks/{5550-b7c97fc13628db15.js → 4327-d70a8d457e2d03fe.js} +1 -1
- package/_standalone/.next/static/chunks/48-c88ea6a2a45f15b4.js +28 -0
- package/_standalone/.next/static/chunks/5581-6d403608b5dfb20b.js +29 -0
- package/_standalone/.next/static/chunks/6902-edc5c487c696bd0b.js +3 -0
- package/_standalone/.next/static/chunks/808.72eb7bdd399e9a24.js +1 -0
- package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/_global-error/{page-e0c1e2c67572781c.js → page-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/agents/page-3dc2bf2f6bc7334c.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-e0c1e2c67572781c.js → route-930dfa67e2789df5.js} +1 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/a2a/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/config/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/install/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/acp/session/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/agents/custom/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/auth/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/backlinks/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/changes/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/channels/verify/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/connect/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/export/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/import/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/raw/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/file/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/files/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/git/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/graph/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/health/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/im/config/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/im/status/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/im/test/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/clip/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/inbox/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/init/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/lint/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/direct-tools/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/tools/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/monitoring/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/recent-files/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/restart/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/search/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/setup/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/skills/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/space-overview/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/sync/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/tree-version/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/uninstall/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-check/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/update-status/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/api/workflows/route-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/changes/page-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-75a6330292613587.js +157 -0
- package/_standalone/.next/static/chunks/app/echo/page-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/{layout-9bb19a959ffb87ac.js → layout-8aa53b34ef34a246.js} +28 -28
- package/_standalone/.next/static/chunks/app/loading-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/{page-c3be6477dbcf182d.js → page-318332501426ef5b.js} +1 -1
- package/_standalone/.next/static/chunks/app/trash/page-17bd5aedcfea9b65.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/page-d5c37c41c556013d.js +12 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-930dfa67e2789df5.js +1 -0
- package/_standalone/.next/static/chunks/webpack-1c2d44f6d86f3986.js +1 -0
- package/_standalone/.next/static/css/a8cadde78aea8585.css +1 -0
- package/_standalone/.next/static/ixCTELNH6V05Z00pC6ZMO/_buildManifest.js +1 -0
- package/_standalone/.next/trace +72 -71
- package/_standalone/.next/types/routes.d.ts +2 -1
- package/_standalone/.next/types/validator.ts +9 -0
- 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__/acp/agent-descriptors.test.ts +101 -3
- package/_standalone/__tests__/acp/registry.test.ts +34 -5
- package/_standalone/__tests__/acp/session.test.ts +346 -167
- package/_standalone/__tests__/agent/provider-endpoints.test.ts +70 -0
- package/_standalone/__tests__/api/channels-verify.test.ts +75 -0
- package/_standalone/__tests__/api/extract-pdf.test.ts +265 -0
- package/_standalone/__tests__/api/test-key.test.ts +15 -3
- package/_standalone/__tests__/channel-mgmt.test.js +11 -0
- package/_standalone/__tests__/components/breadcrumb-header-ux.test.ts +14 -0
- package/_standalone/__tests__/components/header-toc-vertical-alignment.test.ts +23 -0
- package/_standalone/__tests__/components/table-of-contents-header-layout.test.ts +15 -0
- package/_standalone/__tests__/components/view-page-header-layout.test.ts +13 -0
- package/_standalone/__tests__/components/view-page-header-scroll-stability.test.ts +34 -0
- package/_standalone/__tests__/core/hybrid-search.test.ts +109 -0
- package/_standalone/components/Breadcrumb.tsx +10 -10
- package/_standalone/components/FindInPage.tsx +1 -1
- package/_standalone/components/MarkdownView.tsx +4 -0
- package/_standalone/components/Panel.tsx +17 -10
- package/_standalone/components/TableOfContents.tsx +9 -9
- package/_standalone/components/agents/AgentsContentChannelDetail.tsx +168 -54
- package/_standalone/components/agents/AgentsContentChannels.tsx +22 -22
- package/_standalone/components/ask/AskContent.tsx +68 -28
- package/_standalone/components/ask/AskHeader.tsx +6 -2
- package/_standalone/components/ask/ProviderModelCapsule.tsx +11 -9
- package/_standalone/components/ask/SessionHistoryPanel.tsx +398 -0
- package/_standalone/components/panels/AgentsPanel.tsx +8 -1
- package/_standalone/components/settings/AiTab.tsx +5 -1
- package/_standalone/components/settings/KnowledgeTab.tsx +92 -1
- package/_standalone/components/settings/McpConnectGuides.tsx +4 -0
- package/_standalone/components/settings/McpPortSection.tsx +207 -0
- package/_standalone/components/settings/McpTab.tsx +1 -5
- package/_standalone/components/settings/TestButton.tsx +1 -0
- package/_standalone/components/settings/{ServerPortsCard.tsx → WebPortSection.tsx} +66 -151
- package/_standalone/components/settings/types.ts +12 -0
- package/_standalone/components/settings/useCustomProviderForm.ts +2 -2
- package/_standalone/data/skills/mindos/SKILL.md +45 -1
- package/_standalone/hooks/useAcpDetection.ts +1 -1
- package/_standalone/hooks/useAcpRegistry.ts +1 -1
- package/_standalone/hooks/useFileImport.ts +7 -2
- package/_standalone/hooks/useFileUpload.ts +17 -10
- package/_standalone/lib/acp/index.ts +4 -6
- package/_standalone/lib/acp/types.ts +0 -29
- package/_standalone/lib/im/platforms.ts +6 -2
- package/_standalone/lib/pdf-extract.ts +6 -2
- package/_standalone/package-lock.json +12 -2
- package/_standalone/package.json +2 -1
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/MINDOS_ARCHITECTURE_DIAGRAM.md +488 -0
- package/app/MINDOS_EXPLORATION_SUMMARY.md +229 -0
- package/app/MINDOS_INFRASTRUCTURE_ANALYSIS.md +732 -0
- package/app/app/api/acp/detect/route.ts +9 -15
- package/app/app/api/channels/verify/route.ts +54 -0
- package/app/app/api/extract-pdf/route.ts +17 -3
- package/app/app/api/settings/list-models/route.ts +40 -44
- package/app/app/api/settings/route.ts +16 -0
- package/app/app/api/settings/test-key/route.ts +5 -2
- package/app/app/view/[...path]/ViewPageClient.tsx +1 -1
- package/app/components/Breadcrumb.tsx +10 -10
- package/app/components/DirView.tsx +1 -1
- package/app/components/FindInPage.tsx +1 -1
- package/app/components/InboxView.tsx +2 -2
- package/app/components/MarkdownView.tsx +4 -0
- package/app/components/Panel.tsx +17 -10
- package/app/components/TableOfContents.tsx +9 -9
- package/app/components/agents/AgentsContentChannelDetail.tsx +168 -54
- package/app/components/agents/AgentsContentChannels.tsx +22 -22
- package/app/components/ask/AskContent.tsx +68 -28
- package/app/components/ask/AskHeader.tsx +6 -2
- package/app/components/ask/ProviderModelCapsule.tsx +11 -9
- package/app/components/ask/SessionHistoryPanel.tsx +398 -0
- package/app/components/panels/AgentsPanel.tsx +8 -1
- package/app/components/settings/AiTab.tsx +5 -1
- package/app/components/settings/KnowledgeTab.tsx +92 -1
- package/app/components/settings/McpConnectGuides.tsx +4 -0
- package/app/components/settings/McpPortSection.tsx +207 -0
- package/app/components/settings/McpTab.tsx +1 -5
- package/app/components/settings/TestButton.tsx +1 -0
- package/app/components/settings/{ServerPortsCard.tsx → WebPortSection.tsx} +66 -151
- package/app/components/settings/types.ts +12 -0
- package/app/components/settings/useCustomProviderForm.ts +2 -2
- package/app/data/skills/mindos/SKILL.md +45 -1
- package/app/hooks/useAcpDetection.ts +1 -1
- package/app/hooks/useAcpRegistry.ts +1 -1
- package/app/hooks/useFileImport.ts +7 -2
- package/app/hooks/useFileUpload.ts +17 -10
- package/app/lib/acp/agent-descriptors.ts +69 -29
- package/app/lib/acp/index.ts +4 -6
- package/app/lib/acp/registry.ts +43 -47
- package/app/lib/acp/session.ts +253 -517
- package/app/lib/acp/subprocess.ts +249 -414
- package/app/lib/acp/types.ts +0 -29
- package/app/lib/agent/model.ts +20 -4
- package/app/lib/agent/non-streaming.ts +37 -20
- package/app/lib/agent/providers.ts +31 -0
- package/app/lib/agent/tools.ts +5 -3
- package/app/lib/core/embedding-index.ts +285 -0
- package/app/lib/core/embedding-provider.ts +164 -0
- package/app/lib/core/hybrid-search.ts +160 -0
- package/app/lib/core/search.ts +11 -21
- package/app/lib/i18n/modules/ai-chat.ts +26 -0
- package/app/lib/i18n/modules/panels.ts +14 -0
- package/app/lib/i18n/modules/settings.ts +2 -0
- package/app/lib/im/platforms.ts +6 -2
- package/app/lib/im/verify.ts +94 -0
- package/app/lib/pdf-extract.ts +6 -2
- package/app/lib/settings.ts +23 -0
- package/app/package.json +2 -1
- package/bin/cli.js +3 -1
- package/bin/commands/channel.js +342 -0
- package/bin/commands/update.js +11 -4
- package/bin/lib/build.js +34 -16
- package/bin/lib/channel-config.js +168 -0
- package/bin/lib/channel-constants.js +88 -0
- package/bin/lib/channel-mgmt.js +244 -0
- package/bin/lib/channel-prompts.js +72 -0
- package/bin/lib/channel-validate.js +57 -0
- package/bin/lib/safe-rm.js +165 -0
- package/package.json +1 -1
- package/skills/mindos/SKILL.md +45 -1
- package/_standalone/.next/server/chunks/1750.js +0 -1
- package/_standalone/.next/server/chunks/8947.js +0 -52
- package/_standalone/.next/static/0JtsgqDZLSJ6MrIZIV6gC/_buildManifest.js +0 -1
- package/_standalone/.next/static/chunks/1814.a79b84d37df75c43.js +0 -1
- package/_standalone/.next/static/chunks/3637.38c4f28d8f698e0e.js +0 -1
- package/_standalone/.next/static/chunks/4351-9ab695985bb808ad.js +0 -1
- package/_standalone/.next/static/chunks/476.463546c195b89cce.js +0 -48
- package/_standalone/.next/static/chunks/5133-3779d65f4fdfb041.js +0 -30
- package/_standalone/.next/static/chunks/5581-4dd3d32f6e8606ec.js +0 -29
- package/_standalone/.next/static/chunks/5998.7bd28de9747440b5.js +0 -1
- package/_standalone/.next/static/chunks/app/agents/page-4c0637183e46c8d3.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/a2a/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/config/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/detect/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/install/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/registry/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/acp/session/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agent-activity/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/copy-skill/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/agents/custom/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/auth/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/backlinks/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/bootstrap/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/changes/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/connect/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/export/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/import/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/raw/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/file/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/files/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/git/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/graph/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/health/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/im/config/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/im/status/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/im/test/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/clip/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/inbox/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/init/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/lint/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/direct-tools/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/status/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/tools/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/monitoring/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/recent-files/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/restart/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/search/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/ls/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/setup/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/skills/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/space-overview/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/sync/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/tree-version/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/uninstall/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-check/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/update-status/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/api/workflows/route-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/changes/page-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-5333ab47257fab7f.js +0 -159
- package/_standalone/.next/static/chunks/app/echo/page-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/loading-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-bebb28bf472cf691.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/loading-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/app/view/[...path]/page-dd5698f3df138835.js +0 -12
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e0c1e2c67572781c.js +0 -1
- package/_standalone/.next/static/chunks/webpack-043f40ef7816d8c4.js +0 -1
- package/_standalone/.next/static/css/8b1f248d6540e52f.css +0 -1
- package/_standalone/lib/core/__tests__/synonym-dict.test.ts +0 -82
- package/app/lib/core/__tests__/synonym-dict.test.ts +0 -82
- package/app/lib/core/synonym-dict.ts +0 -139
- /package/_standalone/.next/static/{0JtsgqDZLSJ6MrIZIV6gC → ixCTELNH6V05Z00pC6ZMO}/_ssgManifest.js +0 -0
package/app/lib/acp/session.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ACP Session Manager — High-level session lifecycle for ACP agents.
|
|
3
|
-
*
|
|
4
|
-
* Implements
|
|
3
|
+
* Uses @agentclientprotocol/sdk for all protocol handling.
|
|
4
|
+
* Implements: initialize → session/new → session/prompt → session/cancel → close.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type {
|
|
8
|
+
ClientSideConnection,
|
|
9
|
+
SessionNotification,
|
|
10
|
+
SessionUpdate,
|
|
11
|
+
} from '@agentclientprotocol/sdk';
|
|
7
12
|
import type {
|
|
8
13
|
AcpSession,
|
|
9
14
|
AcpSessionState,
|
|
@@ -19,28 +24,34 @@ import type {
|
|
|
19
24
|
AcpContentBlock,
|
|
20
25
|
} from './types';
|
|
21
26
|
import {
|
|
22
|
-
|
|
23
|
-
sendAndWait,
|
|
24
|
-
sendMessage,
|
|
25
|
-
onMessage,
|
|
26
|
-
onNotification,
|
|
27
|
+
spawnAndConnect,
|
|
27
28
|
killAgent,
|
|
28
|
-
|
|
29
|
-
type AcpProcess,
|
|
29
|
+
type AcpConnection,
|
|
30
30
|
} from './subprocess';
|
|
31
31
|
import { findAcpAgent } from './registry';
|
|
32
32
|
|
|
33
|
+
/* ── Version ───────────────────────────────────────────────────────────── */
|
|
34
|
+
|
|
35
|
+
let _cachedVersion = '';
|
|
36
|
+
function getMindosVersion(): string {
|
|
37
|
+
if (!_cachedVersion) {
|
|
38
|
+
try { _cachedVersion = require('../../package.json').version ?? '0.0.0'; } catch { _cachedVersion = '0.0.0'; }
|
|
39
|
+
}
|
|
40
|
+
return _cachedVersion;
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
/* ── State ─────────────────────────────────────────────────────────────── */
|
|
34
44
|
|
|
35
45
|
const sessions = new Map<string, AcpSession>();
|
|
36
|
-
const
|
|
37
|
-
|
|
46
|
+
const sessionConnections = new Map<string, AcpConnection>();
|
|
47
|
+
|
|
48
|
+
const MAX_SESSIONS_PER_AGENT = 3;
|
|
49
|
+
const MAX_TOTAL_SESSIONS = 10;
|
|
38
50
|
|
|
39
51
|
/* ── Public API — Session Lifecycle ───────────────────────────────────── */
|
|
40
52
|
|
|
41
53
|
/**
|
|
42
54
|
* Create a new ACP session by spawning an agent process.
|
|
43
|
-
* Full ACP lifecycle: spawn → initialize → authenticate (if needed) → session/new.
|
|
44
55
|
*/
|
|
45
56
|
export async function createSession(
|
|
46
57
|
agentId: string,
|
|
@@ -50,7 +61,6 @@ export async function createSession(
|
|
|
50
61
|
if (!entry) {
|
|
51
62
|
throw new Error(`ACP agent not found in registry: ${agentId}`);
|
|
52
63
|
}
|
|
53
|
-
|
|
54
64
|
return createSessionFromEntry(entry, options);
|
|
55
65
|
}
|
|
56
66
|
|
|
@@ -61,95 +71,67 @@ export async function createSessionFromEntry(
|
|
|
61
71
|
entry: AcpRegistryEntry,
|
|
62
72
|
options?: { env?: Record<string, string>; cwd?: string },
|
|
63
73
|
): Promise<AcpSession> {
|
|
64
|
-
|
|
74
|
+
checkSessionLimits(entry.id);
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const unsubApproval = installAutoApproval(proc);
|
|
76
|
+
const sessionCwd = options?.cwd ?? process.cwd();
|
|
77
|
+
const conn = spawnAndConnect(entry, options);
|
|
69
78
|
|
|
70
79
|
let agentCapabilities: AcpAgentCapabilities | undefined;
|
|
71
80
|
let authMethods: AcpAuthMethod[] | undefined;
|
|
72
81
|
|
|
73
|
-
// Phase 1: Initialize
|
|
82
|
+
// Phase 1: Initialize
|
|
74
83
|
try {
|
|
75
|
-
const
|
|
84
|
+
const initResult = await conn.connection.initialize({
|
|
76
85
|
protocolVersion: 1,
|
|
77
|
-
|
|
86
|
+
clientCapabilities: {
|
|
78
87
|
fs: { readTextFile: true, writeTextFile: true },
|
|
79
88
|
terminal: true,
|
|
80
89
|
},
|
|
81
|
-
clientInfo: { name: 'mindos', version:
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (response.error) {
|
|
85
|
-
unsubApproval();
|
|
86
|
-
killAgent(proc);
|
|
87
|
-
throw new Error(`initialize failed: ${response.error.message}`);
|
|
88
|
-
}
|
|
90
|
+
clientInfo: { name: 'mindos', version: getMindosVersion() },
|
|
91
|
+
});
|
|
89
92
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (initResult) {
|
|
93
|
-
agentCapabilities = parseAgentCapabilities(initResult.agentCapabilities);
|
|
94
|
-
authMethods = parseAuthMethods(initResult.authMethods);
|
|
95
|
-
}
|
|
93
|
+
agentCapabilities = parseAgentCapabilities(initResult.agentCapabilities);
|
|
94
|
+
authMethods = parseAuthMethods(initResult.authMethods);
|
|
96
95
|
} catch (err) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
throw err;
|
|
96
|
+
killAgent(conn.process);
|
|
97
|
+
throw new Error(`initialize failed: ${(err as Error).message}`);
|
|
100
98
|
}
|
|
101
99
|
|
|
102
100
|
// Phase 2: Authenticate (if agent declares auth methods)
|
|
103
101
|
if (authMethods && authMethods.length > 0) {
|
|
104
102
|
try {
|
|
105
|
-
|
|
106
|
-
methodId: authMethods[0].id,
|
|
107
|
-
}, 15_000);
|
|
108
|
-
|
|
109
|
-
if (authResponse.error) {
|
|
110
|
-
// Authentication failed — non-fatal, log and continue
|
|
111
|
-
console.warn(`ACP authenticate warning for ${entry.id}: ${authResponse.error.message}`);
|
|
112
|
-
}
|
|
103
|
+
await conn.connection.authenticate({ methodId: authMethods[0].id });
|
|
113
104
|
} catch {
|
|
114
|
-
// Best-effort auth
|
|
105
|
+
// Best-effort auth
|
|
115
106
|
}
|
|
116
107
|
}
|
|
117
108
|
|
|
118
|
-
// Phase 3: session/new
|
|
109
|
+
// Phase 3: session/new
|
|
119
110
|
let modes: AcpMode[] | undefined;
|
|
120
111
|
let configOptions: AcpConfigOption[] | undefined;
|
|
121
112
|
let agentSessionId: string | undefined;
|
|
122
113
|
|
|
123
114
|
try {
|
|
124
|
-
const
|
|
125
|
-
cwd:
|
|
115
|
+
const newResult = await conn.connection.newSession({
|
|
116
|
+
cwd: sessionCwd,
|
|
126
117
|
mcpServers: [],
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
if (/auth/i.test(errMsg)) {
|
|
132
|
-
unsubApproval();
|
|
133
|
-
killAgent(proc);
|
|
134
|
-
throw new Error(`${entry.id}: ${errMsg}`);
|
|
135
|
-
}
|
|
136
|
-
console.warn(`ACP session/new warning for ${entry.id}: ${errMsg}`);
|
|
137
|
-
} else {
|
|
138
|
-
const newResult = newResponse.result as Record<string, unknown> | undefined;
|
|
139
|
-
if (newResult) {
|
|
140
|
-
// The agent assigns its own sessionId — we MUST use it for all future RPC calls
|
|
141
|
-
if (typeof newResult.sessionId === 'string') {
|
|
142
|
-
agentSessionId = newResult.sessionId;
|
|
143
|
-
}
|
|
144
|
-
modes = parseModes(newResult.modes);
|
|
145
|
-
configOptions = parseConfigOptions(newResult.configOptions);
|
|
146
|
-
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (typeof newResult.sessionId === 'string') {
|
|
121
|
+
agentSessionId = newResult.sessionId;
|
|
147
122
|
}
|
|
123
|
+
modes = parseModes(newResult.modes);
|
|
124
|
+
configOptions = parseConfigOptions(newResult.configOptions);
|
|
148
125
|
} catch (sessionErr) {
|
|
149
|
-
|
|
126
|
+
const msg = (sessionErr as Error).message ?? '';
|
|
127
|
+
if (/auth/i.test(msg)) {
|
|
128
|
+
killAgent(conn.process);
|
|
129
|
+
throw new Error(`${entry.id}: ${msg}`);
|
|
130
|
+
}
|
|
131
|
+
// Non-auth errors: log and continue (session may still be usable)
|
|
132
|
+
console.warn(`ACP session/new warning for ${entry.id}: ${msg}`);
|
|
150
133
|
}
|
|
151
134
|
|
|
152
|
-
// Reap stale sessions lazily on each new session creation
|
|
153
135
|
reapStaleSessions();
|
|
154
136
|
|
|
155
137
|
const sessionId = `ses-${entry.id}-${Date.now()}`;
|
|
@@ -168,14 +150,12 @@ export async function createSessionFromEntry(
|
|
|
168
150
|
};
|
|
169
151
|
|
|
170
152
|
sessions.set(sessionId, session);
|
|
171
|
-
|
|
172
|
-
autoApprovalCleanups.set(sessionId, unsubApproval);
|
|
153
|
+
sessionConnections.set(sessionId, conn);
|
|
173
154
|
return session;
|
|
174
155
|
}
|
|
175
156
|
|
|
176
157
|
/**
|
|
177
158
|
* Load/resume an existing session on an agent.
|
|
178
|
-
* Requires agent to declare `loadSession` capability.
|
|
179
159
|
*/
|
|
180
160
|
export async function loadSession(
|
|
181
161
|
agentId: string,
|
|
@@ -187,71 +167,45 @@ export async function loadSession(
|
|
|
187
167
|
throw new Error(`ACP agent not found in registry: ${agentId}`);
|
|
188
168
|
}
|
|
189
169
|
|
|
190
|
-
const
|
|
191
|
-
const
|
|
170
|
+
const loadCwd = options?.cwd ?? process.cwd();
|
|
171
|
+
const conn = spawnAndConnect(entry, options);
|
|
192
172
|
|
|
193
173
|
let agentCapabilities: AcpAgentCapabilities | undefined;
|
|
194
174
|
|
|
195
|
-
// Initialize
|
|
196
175
|
try {
|
|
197
|
-
const
|
|
176
|
+
const initResult = await conn.connection.initialize({
|
|
198
177
|
protocolVersion: 1,
|
|
199
|
-
|
|
178
|
+
clientCapabilities: {
|
|
200
179
|
fs: { readTextFile: true, writeTextFile: true },
|
|
201
180
|
terminal: true,
|
|
202
181
|
},
|
|
203
|
-
clientInfo: { name: 'mindos', version:
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (initResponse.error) {
|
|
207
|
-
unsubApproval();
|
|
208
|
-
killAgent(proc);
|
|
209
|
-
throw new Error(`initialize failed: ${initResponse.error.message}`);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const initResult = initResponse.result as Record<string, unknown> | undefined;
|
|
213
|
-
if (initResult) {
|
|
214
|
-
agentCapabilities = parseAgentCapabilities(initResult.agentCapabilities);
|
|
215
|
-
}
|
|
182
|
+
clientInfo: { name: 'mindos', version: getMindosVersion() },
|
|
183
|
+
});
|
|
184
|
+
agentCapabilities = parseAgentCapabilities(initResult.agentCapabilities);
|
|
216
185
|
} catch (err) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
throw err;
|
|
186
|
+
killAgent(conn.process);
|
|
187
|
+
throw new Error(`initialize failed: ${(err as Error).message}`);
|
|
220
188
|
}
|
|
221
189
|
|
|
222
|
-
// Check if agent supports loadSession
|
|
223
190
|
if (!agentCapabilities?.loadSession) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
throw new Error(`Agent ${agentId} does not support session/load (loadSession capability not declared)`);
|
|
191
|
+
killAgent(conn.process);
|
|
192
|
+
throw new Error(`Agent ${agentId} does not support session/load`);
|
|
227
193
|
}
|
|
228
194
|
|
|
229
|
-
// session/load — resume the existing session
|
|
230
195
|
let modes: AcpMode[] | undefined;
|
|
231
196
|
let configOptions: AcpConfigOption[] | undefined;
|
|
232
197
|
|
|
233
198
|
try {
|
|
234
|
-
const
|
|
199
|
+
const loadResult = await conn.connection.loadSession({
|
|
235
200
|
sessionId: existingSessionId,
|
|
236
|
-
cwd:
|
|
201
|
+
cwd: loadCwd,
|
|
237
202
|
mcpServers: [],
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
unsubApproval();
|
|
242
|
-
killAgent(proc);
|
|
243
|
-
throw new Error(`session/load failed: ${loadResponse.error.message}`);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const loadResult = loadResponse.result as Record<string, unknown> | undefined;
|
|
247
|
-
if (loadResult) {
|
|
248
|
-
modes = parseModes(loadResult.modes);
|
|
249
|
-
configOptions = parseConfigOptions(loadResult.configOptions);
|
|
250
|
-
}
|
|
203
|
+
});
|
|
204
|
+
modes = parseModes(loadResult.modes);
|
|
205
|
+
configOptions = parseConfigOptions(loadResult.configOptions);
|
|
251
206
|
} catch (err) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
throw err;
|
|
207
|
+
killAgent(conn.process);
|
|
208
|
+
throw new Error(`session/load failed: ${(err as Error).message}`);
|
|
255
209
|
}
|
|
256
210
|
|
|
257
211
|
const session: AcpSession = {
|
|
@@ -268,65 +222,52 @@ export async function loadSession(
|
|
|
268
222
|
};
|
|
269
223
|
|
|
270
224
|
sessions.set(existingSessionId, session);
|
|
271
|
-
|
|
272
|
-
autoApprovalCleanups.set(existingSessionId, unsubApproval);
|
|
225
|
+
sessionConnections.set(existingSessionId, conn);
|
|
273
226
|
return session;
|
|
274
227
|
}
|
|
275
228
|
|
|
276
229
|
/**
|
|
277
230
|
* List resumable sessions from the agent.
|
|
278
|
-
* Requires agent to declare `sessionCapabilities.list`.
|
|
279
231
|
*/
|
|
280
232
|
export async function listSessions(
|
|
281
233
|
sessionId: string,
|
|
282
234
|
options?: { cursor?: string; cwd?: string },
|
|
283
235
|
): Promise<{ sessions: AcpSessionInfo[]; nextCursor?: string }> {
|
|
284
|
-
const { session,
|
|
236
|
+
const { session, conn } = getSessionAndConn(sessionId);
|
|
285
237
|
|
|
286
238
|
if (!session.agentCapabilities?.sessionCapabilities?.list) {
|
|
287
239
|
throw new Error('Agent does not support session/list');
|
|
288
240
|
}
|
|
289
241
|
|
|
290
|
-
const
|
|
242
|
+
const result = await conn.connection.listSessions({
|
|
291
243
|
...(options?.cursor ? { cursor: options.cursor } : {}),
|
|
292
244
|
...(options?.cwd ? { cwd: options.cwd } : {}),
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if (response.error) {
|
|
296
|
-
throw new Error(`session/list failed: ${response.error.message}`);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const result = response.result as Record<string, unknown> | undefined;
|
|
300
|
-
const rawSessions = Array.isArray(result?.sessions) ? result.sessions : [];
|
|
245
|
+
});
|
|
301
246
|
|
|
302
247
|
return {
|
|
303
|
-
sessions:
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
};
|
|
311
|
-
}),
|
|
312
|
-
nextCursor: typeof result?.nextCursor === 'string' ? result.nextCursor : undefined,
|
|
248
|
+
sessions: (result.sessions ?? []).map(s => ({
|
|
249
|
+
sessionId: s.sessionId ?? '',
|
|
250
|
+
title: s.title ?? undefined,
|
|
251
|
+
cwd: s.cwd ?? undefined,
|
|
252
|
+
updatedAt: s.updatedAt ?? undefined,
|
|
253
|
+
})),
|
|
254
|
+
nextCursor: result.nextCursor ?? undefined,
|
|
313
255
|
};
|
|
314
256
|
}
|
|
315
257
|
|
|
316
258
|
/* ── Public API — Prompt ──────────────────────────────────────────────── */
|
|
317
259
|
|
|
260
|
+
const PROMPT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
261
|
+
|
|
318
262
|
/**
|
|
319
|
-
* Send a prompt
|
|
320
|
-
*
|
|
321
|
-
* for agents like Gemini CLI that send text via streaming notifications, not in the
|
|
322
|
-
* final JSON-RPC response).
|
|
323
|
-
* For streaming, use promptStream() instead.
|
|
263
|
+
* Send a prompt and collect the full response.
|
|
264
|
+
* Text arrives via session/update notifications (handled by SDK → Client.sessionUpdate).
|
|
324
265
|
*/
|
|
325
266
|
export async function prompt(
|
|
326
267
|
sessionId: string,
|
|
327
268
|
text: string,
|
|
328
269
|
): Promise<AcpPromptResponse> {
|
|
329
|
-
const { session,
|
|
270
|
+
const { session, conn } = getSessionAndConn(sessionId);
|
|
330
271
|
|
|
331
272
|
if (session.state === 'active') {
|
|
332
273
|
throw new Error(`Session ${sessionId} is busy processing another prompt`);
|
|
@@ -335,62 +276,48 @@ export async function prompt(
|
|
|
335
276
|
updateSessionState(session, 'active');
|
|
336
277
|
const wireSessionId = session.agentSessionId ?? sessionId;
|
|
337
278
|
|
|
338
|
-
// Collect text from streaming notifications while sendAndWait waits for the final response
|
|
339
279
|
let notificationText = '';
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const update = parseNotificationToUpdate(sessionId, notif.params);
|
|
343
|
-
if (!update) return;
|
|
280
|
+
conn.callbacks.onSessionUpdate = (params) => {
|
|
281
|
+
const update = sdkNotificationToUpdate(sessionId, params);
|
|
344
282
|
if ((update.type === 'agent_message_chunk' || update.type === 'text') && update.text) {
|
|
345
283
|
notificationText += update.text;
|
|
346
284
|
}
|
|
347
|
-
}
|
|
285
|
+
};
|
|
348
286
|
|
|
349
287
|
try {
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
if (response.error) {
|
|
359
|
-
updateSessionState(session, 'error');
|
|
360
|
-
throw new Error(`session/prompt error: ${response.error.message}`);
|
|
361
|
-
}
|
|
288
|
+
const result = await withTimeout(
|
|
289
|
+
conn.connection.prompt({
|
|
290
|
+
sessionId: wireSessionId,
|
|
291
|
+
prompt: [{ type: 'text', text }] satisfies AcpContentBlock[],
|
|
292
|
+
}),
|
|
293
|
+
PROMPT_TIMEOUT_MS,
|
|
294
|
+
`Prompt timed out after ${PROMPT_TIMEOUT_MS / 1000}s`,
|
|
295
|
+
);
|
|
362
296
|
|
|
363
297
|
updateSessionState(session, 'idle');
|
|
364
|
-
const result = response.result as Record<string, unknown>;
|
|
365
|
-
const responseText = typeof result?.text === 'string' ? result.text : '';
|
|
366
298
|
return {
|
|
367
299
|
sessionId,
|
|
368
|
-
text: notificationText ||
|
|
300
|
+
text: notificationText || '',
|
|
369
301
|
done: true,
|
|
370
|
-
stopReason:
|
|
371
|
-
toolCalls: result?.toolCalls as AcpPromptResponse['toolCalls'],
|
|
372
|
-
metadata: result?.metadata as AcpPromptResponse['metadata'],
|
|
302
|
+
stopReason: result.stopReason as AcpStopReason,
|
|
373
303
|
};
|
|
374
304
|
} catch (err) {
|
|
375
|
-
unsubNotify();
|
|
376
305
|
updateSessionState(session, 'error');
|
|
377
306
|
throw err;
|
|
307
|
+
} finally {
|
|
308
|
+
conn.callbacks.onSessionUpdate = undefined;
|
|
378
309
|
}
|
|
379
310
|
}
|
|
380
311
|
|
|
381
312
|
/**
|
|
382
313
|
* Send a prompt and receive streaming updates via callback.
|
|
383
|
-
* Handles both:
|
|
384
|
-
* 1. JSON-RPC notifications (session/update) — the standard ACP streaming mechanism
|
|
385
|
-
* 2. JSON-RPC responses with update data — backward compat for older agents
|
|
386
|
-
* Returns the final aggregated response.
|
|
387
314
|
*/
|
|
388
315
|
export async function promptStream(
|
|
389
316
|
sessionId: string,
|
|
390
317
|
text: string,
|
|
391
318
|
onUpdate: (update: AcpSessionUpdate) => void,
|
|
392
319
|
): Promise<AcpPromptResponse> {
|
|
393
|
-
const { session,
|
|
320
|
+
const { session, conn } = getSessionAndConn(sessionId);
|
|
394
321
|
|
|
395
322
|
if (session.state === 'active') {
|
|
396
323
|
throw new Error(`Session ${sessionId} is busy processing another prompt`);
|
|
@@ -399,246 +326,116 @@ export async function promptStream(
|
|
|
399
326
|
updateSessionState(session, 'active');
|
|
400
327
|
const wireSessionId = session.agentSessionId ?? sessionId;
|
|
401
328
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
let promptRpcId: string;
|
|
407
|
-
|
|
408
|
-
const settle = (fn: () => void) => {
|
|
409
|
-
if (settled) return;
|
|
410
|
-
settled = true;
|
|
411
|
-
cleanup();
|
|
412
|
-
fn();
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
// ── 1. Notifications: primary streaming channel ──
|
|
416
|
-
const unsubNotify = onNotification(proc, (notif) => {
|
|
417
|
-
if (settled) return;
|
|
418
|
-
if (notif.method !== 'session/update' || !notif.params) return;
|
|
419
|
-
|
|
420
|
-
const update = parseNotificationToUpdate(sessionId, notif.params);
|
|
421
|
-
if (!update) return;
|
|
422
|
-
|
|
423
|
-
onUpdate(update);
|
|
329
|
+
let aggregatedText = '';
|
|
330
|
+
conn.callbacks.onSessionUpdate = (params) => {
|
|
331
|
+
const update = sdkNotificationToUpdate(sessionId, params);
|
|
332
|
+
onUpdate(update);
|
|
424
333
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
settle(() => {
|
|
433
|
-
updateSessionState(session, 'error');
|
|
434
|
-
reject(new Error(update.error ?? 'Unknown ACP error'));
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
if (update.type === 'done') {
|
|
438
|
-
settle(() => {
|
|
439
|
-
updateSessionState(session, 'idle');
|
|
440
|
-
resolve({ sessionId, text: aggregatedText, done: true, stopReason });
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
});
|
|
444
|
-
|
|
445
|
-
// ── 2. Responses: completion signal + legacy streaming fallback ──
|
|
446
|
-
const unsubMsg = onMessage(proc, (msg) => {
|
|
447
|
-
if (settled) return;
|
|
448
|
-
|
|
449
|
-
// Final response — matches the RPC ID of our prompt request
|
|
450
|
-
if (String(msg.id) === promptRpcId) {
|
|
451
|
-
if (msg.error) {
|
|
452
|
-
settle(() => {
|
|
453
|
-
updateSessionState(session, 'error');
|
|
454
|
-
reject(new Error(`session/prompt error: ${msg.error!.message}`));
|
|
455
|
-
});
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
const result = msg.result as Record<string, unknown> | undefined;
|
|
459
|
-
if (result?.stopReason) stopReason = parseStopReason(result.stopReason);
|
|
460
|
-
const responseText = typeof result?.text === 'string' ? result.text : '';
|
|
461
|
-
if (responseText && !aggregatedText) aggregatedText = responseText;
|
|
462
|
-
|
|
463
|
-
onUpdate({ sessionId, type: 'done' });
|
|
464
|
-
settle(() => {
|
|
465
|
-
updateSessionState(session, 'idle');
|
|
466
|
-
resolve({ sessionId, text: aggregatedText, done: true, stopReason });
|
|
467
|
-
});
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// Legacy: responses with update-like result (for agents that stream via responses)
|
|
472
|
-
if (msg.result && typeof msg.result === 'object') {
|
|
473
|
-
const raw = msg.result as Record<string, unknown>;
|
|
474
|
-
const update = parseSessionUpdate(sessionId, raw);
|
|
475
|
-
onUpdate(update);
|
|
476
|
-
if ((update.type === 'agent_message_chunk' || update.type === 'text') && update.text) {
|
|
477
|
-
aggregatedText += update.text;
|
|
478
|
-
}
|
|
479
|
-
if (update.type === 'done') {
|
|
480
|
-
if (raw.stopReason) stopReason = parseStopReason(raw.stopReason);
|
|
481
|
-
settle(() => {
|
|
482
|
-
updateSessionState(session, 'idle');
|
|
483
|
-
resolve({ sessionId, text: aggregatedText, done: true, stopReason });
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
if (update.type === 'error') {
|
|
487
|
-
settle(() => {
|
|
488
|
-
updateSessionState(session, 'error');
|
|
489
|
-
reject(new Error(update.error ?? 'Unknown ACP error'));
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
// ── 3. Process exit guard ──
|
|
496
|
-
const onExit = () => {
|
|
497
|
-
settle(() => {
|
|
498
|
-
updateSessionState(session, 'error');
|
|
499
|
-
reject(new Error('ACP agent process exited unexpectedly during prompt'));
|
|
500
|
-
});
|
|
501
|
-
};
|
|
502
|
-
proc.proc.once('exit', onExit);
|
|
503
|
-
|
|
504
|
-
const cleanup = () => {
|
|
505
|
-
unsubNotify();
|
|
506
|
-
unsubMsg();
|
|
507
|
-
proc.proc.removeListener('exit', onExit);
|
|
508
|
-
};
|
|
334
|
+
if ((update.type === 'agent_message_chunk' || update.type === 'text') && update.text) {
|
|
335
|
+
aggregatedText += update.text;
|
|
336
|
+
}
|
|
337
|
+
if (update.type === 'config_option_update' && update.configOptions) {
|
|
338
|
+
session.configOptions = update.configOptions;
|
|
339
|
+
}
|
|
340
|
+
};
|
|
509
341
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
342
|
+
try {
|
|
343
|
+
const result = await withTimeout(
|
|
344
|
+
conn.connection.prompt({
|
|
513
345
|
sessionId: wireSessionId,
|
|
514
346
|
prompt: [{ type: 'text', text }] satisfies AcpContentBlock[],
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
347
|
+
}),
|
|
348
|
+
PROMPT_TIMEOUT_MS,
|
|
349
|
+
`Prompt timed out after ${PROMPT_TIMEOUT_MS / 1000}s`,
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
onUpdate({ sessionId, type: 'done' });
|
|
353
|
+
updateSessionState(session, 'idle');
|
|
354
|
+
return {
|
|
355
|
+
sessionId,
|
|
356
|
+
text: aggregatedText,
|
|
357
|
+
done: true,
|
|
358
|
+
stopReason: result.stopReason as AcpStopReason,
|
|
359
|
+
};
|
|
360
|
+
} catch (err) {
|
|
361
|
+
updateSessionState(session, 'error');
|
|
362
|
+
throw err;
|
|
363
|
+
} finally {
|
|
364
|
+
conn.callbacks.onSessionUpdate = undefined;
|
|
365
|
+
}
|
|
525
366
|
}
|
|
526
367
|
|
|
527
368
|
/* ── Public API — Session Control ─────────────────────────────────────── */
|
|
528
369
|
|
|
529
|
-
/**
|
|
530
|
-
* Cancel the current prompt turn on a session.
|
|
531
|
-
*/
|
|
532
370
|
export async function cancelPrompt(sessionId: string): Promise<void> {
|
|
533
|
-
const { session,
|
|
534
|
-
|
|
371
|
+
const { session, conn } = getSessionAndConn(sessionId);
|
|
535
372
|
if (session.state !== 'active') return;
|
|
536
373
|
|
|
537
374
|
const wireSessionId = session.agentSessionId ?? sessionId;
|
|
538
375
|
try {
|
|
539
|
-
await
|
|
376
|
+
await conn.connection.cancel({ sessionId: wireSessionId });
|
|
540
377
|
} catch {
|
|
541
378
|
// Best-effort cancel
|
|
542
379
|
}
|
|
543
|
-
|
|
544
380
|
updateSessionState(session, 'idle');
|
|
545
381
|
}
|
|
546
382
|
|
|
547
|
-
/**
|
|
548
|
-
* Set the operating mode for a session.
|
|
549
|
-
*/
|
|
550
383
|
export async function setMode(sessionId: string, modeId: string): Promise<void> {
|
|
551
|
-
const { session,
|
|
552
|
-
|
|
384
|
+
const { session, conn } = getSessionAndConn(sessionId);
|
|
553
385
|
const wireSessionId = session.agentSessionId ?? sessionId;
|
|
554
|
-
|
|
555
|
-
sessionId: wireSessionId,
|
|
556
|
-
modeId,
|
|
557
|
-
}, 10_000);
|
|
558
|
-
|
|
559
|
-
if (response.error) {
|
|
560
|
-
throw new Error(`session/set_mode failed: ${response.error.message}`);
|
|
561
|
-
}
|
|
562
|
-
|
|
386
|
+
await conn.connection.setSessionMode({ sessionId: wireSessionId, modeId });
|
|
563
387
|
session.lastActivityAt = new Date().toISOString();
|
|
564
388
|
}
|
|
565
389
|
|
|
566
|
-
/**
|
|
567
|
-
* Set a configuration option for a session.
|
|
568
|
-
*/
|
|
569
390
|
export async function setConfigOption(
|
|
570
391
|
sessionId: string,
|
|
571
392
|
configId: string,
|
|
572
393
|
value: string,
|
|
573
394
|
): Promise<AcpConfigOption[]> {
|
|
574
|
-
const { session,
|
|
575
|
-
|
|
395
|
+
const { session, conn } = getSessionAndConn(sessionId);
|
|
576
396
|
const wireSessionId = session.agentSessionId ?? sessionId;
|
|
577
|
-
|
|
397
|
+
|
|
398
|
+
const result = await conn.connection.setSessionConfigOption({
|
|
578
399
|
sessionId: wireSessionId,
|
|
579
400
|
configId,
|
|
580
401
|
value,
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
if (response.error) {
|
|
584
|
-
throw new Error(`session/set_config_option failed: ${response.error.message}`);
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
const result = response.result as Record<string, unknown> | undefined;
|
|
588
|
-
const configOptions = parseConfigOptions(result?.configOptions);
|
|
589
|
-
if (configOptions) {
|
|
590
|
-
session.configOptions = configOptions;
|
|
591
|
-
}
|
|
402
|
+
});
|
|
592
403
|
|
|
404
|
+
const configOptions = parseConfigOptions(result.configOptions);
|
|
405
|
+
if (configOptions) session.configOptions = configOptions;
|
|
593
406
|
session.lastActivityAt = new Date().toISOString();
|
|
594
407
|
return session.configOptions ?? [];
|
|
595
408
|
}
|
|
596
409
|
|
|
597
|
-
/**
|
|
598
|
-
* Close a session and terminate the subprocess.
|
|
599
|
-
*/
|
|
600
410
|
export async function closeSession(sessionId: string): Promise<void> {
|
|
601
411
|
const session = sessions.get(sessionId);
|
|
602
|
-
const
|
|
412
|
+
const conn = sessionConnections.get(sessionId);
|
|
603
413
|
|
|
604
|
-
if (
|
|
414
|
+
if (conn?.process.alive) {
|
|
605
415
|
const wireSessionId = session?.agentSessionId ?? sessionId;
|
|
606
416
|
try {
|
|
607
|
-
await
|
|
417
|
+
await conn.connection.unstable_closeSession({ sessionId: wireSessionId });
|
|
608
418
|
} catch {
|
|
609
|
-
// Best-effort
|
|
419
|
+
// Best-effort — many agents don't support session/close
|
|
610
420
|
}
|
|
611
|
-
killAgent(
|
|
421
|
+
killAgent(conn.process);
|
|
612
422
|
}
|
|
613
423
|
|
|
614
424
|
sessions.delete(sessionId);
|
|
615
|
-
|
|
616
|
-
const cleanup = autoApprovalCleanups.get(sessionId);
|
|
617
|
-
if (cleanup) {
|
|
618
|
-
cleanup();
|
|
619
|
-
autoApprovalCleanups.delete(sessionId);
|
|
620
|
-
}
|
|
425
|
+
sessionConnections.delete(sessionId);
|
|
621
426
|
}
|
|
622
427
|
|
|
623
428
|
/* ── Public API — Queries ─────────────────────────────────────────────── */
|
|
624
429
|
|
|
625
|
-
/**
|
|
626
|
-
* Get a session by its ID.
|
|
627
|
-
*/
|
|
628
430
|
export function getSession(sessionId: string): AcpSession | undefined {
|
|
629
431
|
return sessions.get(sessionId);
|
|
630
432
|
}
|
|
631
433
|
|
|
632
|
-
/**
|
|
633
|
-
* Get all active sessions.
|
|
634
|
-
*/
|
|
635
434
|
export function getActiveSessions(): AcpSession[] {
|
|
435
|
+
reapStaleSessions();
|
|
636
436
|
return [...sessions.values()];
|
|
637
437
|
}
|
|
638
438
|
|
|
639
|
-
/**
|
|
640
|
-
* Close all active sessions. Used for cleanup.
|
|
641
|
-
*/
|
|
642
439
|
export async function closeAllSessions(): Promise<void> {
|
|
643
440
|
const ids = [...sessions.keys()];
|
|
644
441
|
await Promise.allSettled(ids.map(id => closeSession(id)));
|
|
@@ -646,17 +443,17 @@ export async function closeAllSessions(): Promise<void> {
|
|
|
646
443
|
|
|
647
444
|
/* ── Internal — Session helpers ───────────────────────────────────────── */
|
|
648
445
|
|
|
649
|
-
function
|
|
446
|
+
function getSessionAndConn(sessionId: string): { session: AcpSession; conn: AcpConnection } {
|
|
650
447
|
const session = sessions.get(sessionId);
|
|
651
448
|
if (!session) throw new Error(`Session not found: ${sessionId}`);
|
|
652
449
|
|
|
653
|
-
const
|
|
654
|
-
if (!
|
|
450
|
+
const conn = sessionConnections.get(sessionId);
|
|
451
|
+
if (!conn?.process.alive) {
|
|
655
452
|
updateSessionState(session, 'error');
|
|
656
453
|
throw new Error(`Session process is dead: ${sessionId}`);
|
|
657
454
|
}
|
|
658
455
|
|
|
659
|
-
return { session,
|
|
456
|
+
return { session, conn };
|
|
660
457
|
}
|
|
661
458
|
|
|
662
459
|
function updateSessionState(session: AcpSession, state: AcpSessionState): void {
|
|
@@ -664,13 +461,97 @@ function updateSessionState(session: AcpSession, state: AcpSessionState): void {
|
|
|
664
461
|
session.lastActivityAt = new Date().toISOString();
|
|
665
462
|
}
|
|
666
463
|
|
|
667
|
-
|
|
464
|
+
function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {
|
|
465
|
+
return new Promise((resolve, reject) => {
|
|
466
|
+
const timer = setTimeout(() => reject(new Error(message)), ms);
|
|
467
|
+
promise.then(
|
|
468
|
+
(v) => { clearTimeout(timer); resolve(v); },
|
|
469
|
+
(e) => { clearTimeout(timer); reject(e); },
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* ── Internal — SDK notification → MindOS update ──────────────────────── */
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Convert SDK SessionNotification to MindOS AcpSessionUpdate.
|
|
478
|
+
* The SDK validates and parses the JSON-RPC notification;
|
|
479
|
+
* we just reshape the typed data for our UI layer.
|
|
480
|
+
*/
|
|
481
|
+
function sdkNotificationToUpdate(
|
|
482
|
+
sessionId: string,
|
|
483
|
+
params: SessionNotification,
|
|
484
|
+
): AcpSessionUpdate {
|
|
485
|
+
const update = params.update as SessionUpdate & Record<string, unknown>;
|
|
486
|
+
const type = update.sessionUpdate as AcpSessionUpdate['type'];
|
|
487
|
+
const base: AcpSessionUpdate = { sessionId, type };
|
|
488
|
+
|
|
489
|
+
switch (type) {
|
|
490
|
+
case 'agent_message_chunk':
|
|
491
|
+
case 'user_message_chunk':
|
|
492
|
+
case 'agent_thought_chunk': {
|
|
493
|
+
const content = (update as Record<string, unknown>).content as Record<string, unknown> | undefined;
|
|
494
|
+
if (content?.type === 'text' && typeof content.text === 'string') {
|
|
495
|
+
base.text = content.text;
|
|
496
|
+
} else if (content?.type === 'thinking' && typeof content.text === 'string') {
|
|
497
|
+
base.text = content.text;
|
|
498
|
+
}
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
case 'tool_call':
|
|
503
|
+
case 'tool_call_update': {
|
|
504
|
+
const tc = update as Record<string, unknown>;
|
|
505
|
+
base.toolCall = {
|
|
506
|
+
toolCallId: String(tc.toolCallId ?? ''),
|
|
507
|
+
title: typeof tc.title === 'string' ? tc.title : undefined,
|
|
508
|
+
status: (tc.status as 'pending' | 'in_progress' | 'completed' | 'failed') ?? 'pending',
|
|
509
|
+
kind: tc.kind as AcpSessionUpdate['toolCall'] extends { kind: infer K } ? K : undefined,
|
|
510
|
+
rawInput: typeof tc.rawInput === 'string' ? tc.rawInput : undefined,
|
|
511
|
+
rawOutput: typeof tc.rawOutput === 'string' ? tc.rawOutput : undefined,
|
|
512
|
+
};
|
|
513
|
+
break;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
case 'plan': {
|
|
517
|
+
const planData = update as Record<string, unknown>;
|
|
518
|
+
if (Array.isArray(planData.entries)) {
|
|
519
|
+
base.plan = { entries: planData.entries as AcpSessionUpdate['plan'] extends { entries: infer E } ? E : never };
|
|
520
|
+
}
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
case 'available_commands_update':
|
|
525
|
+
base.availableCommands = Array.isArray((update as Record<string, unknown>).availableCommands)
|
|
526
|
+
? (update as Record<string, unknown>).availableCommands as unknown[]
|
|
527
|
+
: undefined;
|
|
528
|
+
break;
|
|
529
|
+
|
|
530
|
+
case 'current_mode_update':
|
|
531
|
+
base.currentModeId = typeof (update as Record<string, unknown>).currentModeId === 'string'
|
|
532
|
+
? (update as Record<string, unknown>).currentModeId as string
|
|
533
|
+
: undefined;
|
|
534
|
+
break;
|
|
535
|
+
|
|
536
|
+
case 'config_option_update':
|
|
537
|
+
base.configOptions = parseConfigOptions((update as Record<string, unknown>).configOptions);
|
|
538
|
+
break;
|
|
539
|
+
|
|
540
|
+
case 'session_info_update': {
|
|
541
|
+
const info = update as Record<string, unknown>;
|
|
542
|
+
base.sessionInfo = {
|
|
543
|
+
title: typeof info.title === 'string' ? info.title : undefined,
|
|
544
|
+
updatedAt: typeof info.updatedAt === 'string' ? info.updatedAt : undefined,
|
|
545
|
+
};
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
668
549
|
|
|
669
|
-
|
|
670
|
-
const valid: AcpStopReason[] = ['end_turn', 'max_tokens', 'max_turn_requests', 'refusal', 'cancelled'];
|
|
671
|
-
return valid.includes(raw as AcpStopReason) ? (raw as AcpStopReason) : 'end_turn';
|
|
550
|
+
return base;
|
|
672
551
|
}
|
|
673
552
|
|
|
553
|
+
/* ── Internal — Parsers ───────────────────────────────────────────────── */
|
|
554
|
+
|
|
674
555
|
function parseAgentCapabilities(raw: unknown): AcpAgentCapabilities | undefined {
|
|
675
556
|
if (!raw || typeof raw !== 'object') return undefined;
|
|
676
557
|
const obj = raw as Record<string, unknown>;
|
|
@@ -695,7 +576,6 @@ function parseAuthMethods(raw: unknown): AcpAuthMethod[] | undefined {
|
|
|
695
576
|
}
|
|
696
577
|
|
|
697
578
|
function parseModes(raw: unknown): AcpMode[] | undefined {
|
|
698
|
-
// Handle nested format: { availableModes: [...], currentModeId: "..." }
|
|
699
579
|
if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
|
|
700
580
|
const obj = raw as Record<string, unknown>;
|
|
701
581
|
if (Array.isArray(obj.availableModes)) {
|
|
@@ -731,160 +611,16 @@ function parseConfigOptions(raw: unknown): AcpConfigOption[] | undefined {
|
|
|
731
611
|
.filter(o => o.configId);
|
|
732
612
|
}
|
|
733
613
|
|
|
734
|
-
|
|
735
|
-
function parseSessionUpdate(sessionId: string, raw: Record<string, unknown>): AcpSessionUpdate {
|
|
736
|
-
const type = raw.type as AcpSessionUpdate['type'] ?? 'text';
|
|
737
|
-
|
|
738
|
-
const base: AcpSessionUpdate = { sessionId, type };
|
|
739
|
-
|
|
740
|
-
switch (type) {
|
|
741
|
-
case 'agent_message_chunk':
|
|
742
|
-
case 'user_message_chunk':
|
|
743
|
-
case 'agent_thought_chunk':
|
|
744
|
-
case 'text':
|
|
745
|
-
base.text = typeof raw.text === 'string' ? raw.text
|
|
746
|
-
: typeof raw.content === 'string' ? raw.content
|
|
747
|
-
: undefined;
|
|
748
|
-
break;
|
|
614
|
+
/* ── Internal — Session limits ─────────────────────────────────────────── */
|
|
749
615
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
base.toolCall = raw.toolCall as AcpSessionUpdate['toolCall'];
|
|
754
|
-
} else {
|
|
755
|
-
base.toolCall = {
|
|
756
|
-
toolCallId: String(raw.toolCallId ?? ''),
|
|
757
|
-
title: typeof raw.title === 'string' ? raw.title : undefined,
|
|
758
|
-
kind: raw.kind as AcpSessionUpdate['toolCall'] extends { kind: infer K } ? K : undefined,
|
|
759
|
-
status: (raw.status as 'pending' | 'in_progress' | 'completed' | 'failed') ?? 'pending',
|
|
760
|
-
rawInput: typeof raw.rawInput === 'string' ? raw.rawInput : undefined,
|
|
761
|
-
rawOutput: typeof raw.rawOutput === 'string' ? raw.rawOutput : undefined,
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
break;
|
|
765
|
-
|
|
766
|
-
case 'plan':
|
|
767
|
-
if (raw.entries && Array.isArray(raw.entries)) {
|
|
768
|
-
base.plan = { entries: raw.entries as AcpSessionUpdate['plan'] extends { entries: infer E } ? E : never };
|
|
769
|
-
} else if (raw.plan && typeof raw.plan === 'object') {
|
|
770
|
-
base.plan = raw.plan as AcpSessionUpdate['plan'];
|
|
771
|
-
}
|
|
772
|
-
break;
|
|
773
|
-
|
|
774
|
-
case 'available_commands_update':
|
|
775
|
-
base.availableCommands = Array.isArray(raw.availableCommands) ? raw.availableCommands : undefined;
|
|
776
|
-
break;
|
|
777
|
-
|
|
778
|
-
case 'current_mode_update':
|
|
779
|
-
base.currentModeId = typeof raw.currentModeId === 'string' ? raw.currentModeId : undefined;
|
|
780
|
-
break;
|
|
781
|
-
|
|
782
|
-
case 'config_option_update':
|
|
783
|
-
base.configOptions = parseConfigOptions(raw.configOptions);
|
|
784
|
-
break;
|
|
785
|
-
|
|
786
|
-
case 'session_info_update':
|
|
787
|
-
base.sessionInfo = {
|
|
788
|
-
title: typeof raw.title === 'string' ? raw.title : undefined,
|
|
789
|
-
updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt : undefined,
|
|
790
|
-
};
|
|
791
|
-
break;
|
|
792
|
-
|
|
793
|
-
case 'error':
|
|
794
|
-
base.error = typeof raw.error === 'string' ? raw.error : String(raw.message ?? 'Unknown error');
|
|
795
|
-
break;
|
|
796
|
-
|
|
797
|
-
case 'done':
|
|
798
|
-
break;
|
|
799
|
-
|
|
800
|
-
case 'tool_result':
|
|
801
|
-
base.toolResult = raw.toolResult as AcpSessionUpdate['toolResult'];
|
|
802
|
-
break;
|
|
616
|
+
function checkSessionLimits(agentId: string): void {
|
|
617
|
+
if (sessions.size >= MAX_TOTAL_SESSIONS) {
|
|
618
|
+
throw new Error(`Maximum concurrent sessions (${MAX_TOTAL_SESSIONS}) reached. Close existing sessions first.`);
|
|
803
619
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/**
|
|
809
|
-
* Parse a JSON-RPC notification's `params` into a typed AcpSessionUpdate.
|
|
810
|
-
* Gemini CLI notification format:
|
|
811
|
-
* { sessionId: "...", update: { sessionUpdate: "agent_message_chunk", content: { type: "text", text: "..." } } }
|
|
812
|
-
*/
|
|
813
|
-
function parseNotificationToUpdate(
|
|
814
|
-
sessionId: string,
|
|
815
|
-
params: Record<string, unknown>,
|
|
816
|
-
): AcpSessionUpdate | null {
|
|
817
|
-
const updateObj = params.update as Record<string, unknown> | undefined;
|
|
818
|
-
if (!updateObj) return null;
|
|
819
|
-
|
|
820
|
-
const updateType = (updateObj.sessionUpdate ?? updateObj.type) as AcpSessionUpdate['type'] | undefined;
|
|
821
|
-
if (!updateType) return null;
|
|
822
|
-
|
|
823
|
-
const base: AcpSessionUpdate = { sessionId, type: updateType };
|
|
824
|
-
|
|
825
|
-
// Extract text from content block
|
|
826
|
-
const content = updateObj.content as Record<string, unknown> | undefined;
|
|
827
|
-
if (content) {
|
|
828
|
-
if (content.type === 'text' && typeof content.text === 'string') {
|
|
829
|
-
base.text = content.text;
|
|
830
|
-
} else if (content.type === 'thinking' && typeof content.text === 'string') {
|
|
831
|
-
base.text = content.text;
|
|
832
|
-
}
|
|
620
|
+
const agentCount = [...sessions.values()].filter(s => s.agentId === agentId).length;
|
|
621
|
+
if (agentCount >= MAX_SESSIONS_PER_AGENT) {
|
|
622
|
+
throw new Error(`Maximum concurrent sessions for agent "${agentId}" (${MAX_SESSIONS_PER_AGENT}) reached.`);
|
|
833
623
|
}
|
|
834
|
-
|
|
835
|
-
// Direct text fields (some agents use flat format)
|
|
836
|
-
if (!base.text) {
|
|
837
|
-
if (typeof updateObj.text === 'string') base.text = updateObj.text;
|
|
838
|
-
else if (typeof updateObj.content === 'string') base.text = updateObj.content;
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
switch (updateType) {
|
|
842
|
-
case 'tool_call':
|
|
843
|
-
case 'tool_call_update':
|
|
844
|
-
if (updateObj.toolCall && typeof updateObj.toolCall === 'object') {
|
|
845
|
-
base.toolCall = updateObj.toolCall as AcpSessionUpdate['toolCall'];
|
|
846
|
-
} else {
|
|
847
|
-
base.toolCall = {
|
|
848
|
-
toolCallId: String(updateObj.toolCallId ?? ''),
|
|
849
|
-
title: typeof updateObj.title === 'string' ? updateObj.title : undefined,
|
|
850
|
-
status: (updateObj.status as 'pending' | 'in_progress' | 'completed' | 'failed') ?? 'pending',
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
break;
|
|
854
|
-
|
|
855
|
-
case 'plan':
|
|
856
|
-
if (updateObj.plan && typeof updateObj.plan === 'object') {
|
|
857
|
-
base.plan = updateObj.plan as AcpSessionUpdate['plan'];
|
|
858
|
-
} else if (Array.isArray(updateObj.entries)) {
|
|
859
|
-
base.plan = { entries: updateObj.entries as AcpSessionUpdate['plan'] extends { entries: infer E } ? E : never };
|
|
860
|
-
}
|
|
861
|
-
break;
|
|
862
|
-
|
|
863
|
-
case 'error':
|
|
864
|
-
base.error = typeof updateObj.error === 'string'
|
|
865
|
-
? updateObj.error
|
|
866
|
-
: typeof updateObj.message === 'string'
|
|
867
|
-
? updateObj.message
|
|
868
|
-
: 'Unknown error';
|
|
869
|
-
break;
|
|
870
|
-
|
|
871
|
-
case 'config_option_update':
|
|
872
|
-
base.configOptions = parseConfigOptions(updateObj.configOptions);
|
|
873
|
-
break;
|
|
874
|
-
|
|
875
|
-
case 'current_mode_update':
|
|
876
|
-
base.currentModeId = typeof updateObj.currentModeId === 'string' ? updateObj.currentModeId : undefined;
|
|
877
|
-
break;
|
|
878
|
-
|
|
879
|
-
case 'session_info_update':
|
|
880
|
-
base.sessionInfo = {
|
|
881
|
-
title: typeof updateObj.title === 'string' ? updateObj.title : undefined,
|
|
882
|
-
updatedAt: typeof updateObj.updatedAt === 'string' ? updateObj.updatedAt : undefined,
|
|
883
|
-
};
|
|
884
|
-
break;
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
return base;
|
|
888
624
|
}
|
|
889
625
|
|
|
890
626
|
/* ── Internal — Session reaping ───────────────────────────────────────── */
|