@rexvane/piweb 0.3.21 → 0.3.23
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +9 -6
- package/.next/build-manifest.json +5 -5
- package/.next/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +7 -7
- package/.next/react-loadable-manifest.json +18 -11
- package/.next/required-server-files.js +16 -1
- package/.next/required-server-files.json +16 -1
- package/.next/routes-manifest.json +20 -0
- package/.next/server/app/_global-error/page.js +2 -2
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.meta +8 -0
- package/.next/server/app/_global-error.rsc +15 -11
- package/.next/server/app/_global-error.segments/_full.segment.rsc +15 -11
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +20 -16
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +3 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.meta +8 -0
- package/.next/server/app/_not-found.rsc +17 -13
- package/.next/server/app/_not-found.segments/_full.segment.rsc +17 -13
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +24 -20
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +4 -2
- package/.next/server/app/api/agent/[id]/events/route.js +2 -2
- package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/[id]/route.js +1 -1
- package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/[id]/side-chat/route.js +5 -0
- package/.next/server/app/api/agent/[id]/side-chat/route.js.nft.json +1 -0
- package/.next/server/app/api/agent/[id]/side-chat/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/agent/[id]/tree/route.js +1 -1
- package/.next/server/app/api/agent/[id]/tree/route.js.nft.json +1 -1
- package/.next/server/app/api/agent/new/route.js +1 -1
- package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js +1 -1
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/files/route.js +1 -1
- package/.next/server/app/api/files/route.js.nft.json +1 -1
- package/.next/server/app/api/fs/route.js +1 -1
- package/.next/server/app/api/fs/route.js.nft.json +1 -1
- package/.next/server/app/api/git/route.js +4 -4
- package/.next/server/app/api/git/route.js.nft.json +1 -1
- package/.next/server/app/api/github/route.js +5 -0
- package/.next/server/app/api/github/route.js.nft.json +1 -0
- package/.next/server/app/api/github/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/growth/route.js +1 -1
- package/.next/server/app/api/growth/route.js.nft.json +1 -1
- package/.next/server/app/api/health/route.js +1 -1
- package/.next/server/app/api/health/route.js.nft.json +1 -1
- package/.next/server/app/api/models/defaults/route.js +1 -0
- package/.next/server/app/api/models/defaults/route.js.nft.json +1 -0
- package/.next/server/app/api/models/defaults/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models/route.js +1 -1
- package/.next/server/app/api/models/route.js.nft.json +1 -1
- package/.next/server/app/api/pi-settings/route.js +1 -1
- package/.next/server/app/api/pi-settings/route.js.nft.json +1 -1
- package/.next/server/app/api/plugins/route.js +1 -1
- package/.next/server/app/api/plugins/route.js.nft.json +1 -1
- package/.next/server/app/api/prompts/route.js +1 -1
- package/.next/server/app/api/prompts/route.js.nft.json +1 -1
- package/.next/server/app/api/remote/route.js +4 -4
- package/.next/server/app/api/remote/route.js.nft.json +1 -1
- package/.next/server/app/api/security/route.js +1 -1
- package/.next/server/app/api/security/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/import/route.js +2 -2
- package/.next/server/app/api/sessions/import/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/route.js +1 -1
- package/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +2 -2
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/update/route.js +2 -2
- package/.next/server/app/api/update/route.js.nft.json +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/api/version/route.js.nft.json +1 -1
- package/.next/server/app/api/web-auth/route.js +2 -2
- package/.next/server/app/api/web-auth/route.js.nft.json +1 -1
- package/.next/server/app/api/workspaces/route.js +1 -1
- package/.next/server/app/api/workspaces/route.js.nft.json +1 -1
- package/.next/server/app/icon.svg/route.js +1 -1
- package/.next/server/app/icon.svg/route.js.nft.json +1 -1
- package/.next/server/app/icon.svg.meta +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.meta +8 -0
- package/.next/server/app/index.rsc +20 -13
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +26 -19
- package/.next/server/app/index.segments/_full.segment.rsc +20 -13
- package/.next/server/app/index.segments/_tree.segment.rsc +4 -2
- package/.next/server/app/login/page.js +1 -1
- package/.next/server/app/login/page.js.nft.json +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +1 -1
- package/.next/server/app/login.meta +8 -0
- package/.next/server/app/login.rsc +23 -17
- package/.next/server/app/login.segments/_full.segment.rsc +23 -17
- package/.next/server/app/login.segments/_tree.segment.rsc +4 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +30 -24
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +9 -6
- package/.next/server/chunks/1813.js +23 -0
- package/.next/server/chunks/2430.js +377 -0
- package/.next/server/chunks/2970.js +305 -0
- package/.next/server/chunks/3421.js +1 -0
- package/.next/server/chunks/3924.js +6 -0
- package/.next/server/chunks/4807.js +1 -0
- package/.next/server/chunks/538.js +1 -1
- package/.next/server/chunks/5393.js +1 -0
- package/.next/server/chunks/5802.js +2 -0
- package/.next/server/chunks/6229.js +1 -0
- package/.next/server/chunks/7496.js +1 -0
- package/.next/server/chunks/7662.js +2 -0
- package/.next/server/chunks/8686.js +1 -0
- package/.next/server/chunks/{593.js → 974.js} +1 -1
- package/.next/server/chunks/{920.js → 9920.js} +2 -2
- package/.next/server/functions-config-manifest.json +2 -1
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/instrumentation.js.nft.json +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/middleware.js +185 -23
- package/.next/server/middleware.js.nft.json +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/preview-props.json +5 -0
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/server/webpack-runtime.js +1 -1
- package/.next/static/chunks/2716.44fdf1b21454b961.js +1 -0
- package/.next/static/chunks/316-698d10eb465bd8ef.js +1 -0
- package/.next/static/chunks/3794-0978865cda773008.js +52 -0
- package/.next/static/chunks/4673.e261707dce391be7.js +1 -0
- package/.next/static/chunks/4686-0cd87513f9ea3538.js +1 -0
- package/.next/static/chunks/4778.eddd3a5813f85824.js +1 -0
- package/.next/static/chunks/4bd1b696-e199e788e58acf79.js +1 -0
- package/.next/static/chunks/{5173.91ddb803785009f8.js → 5173.dfd1cbb795b9a21c.js} +1 -1
- package/.next/static/chunks/618.949981da99be7182.js +4 -0
- package/.next/static/chunks/7411.5f79671208209b13.js +1 -0
- package/.next/static/chunks/app/_global-error/page-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/events/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/side-chat/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/agent/[id]/tree/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/agent/new/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/config/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/files/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/fs/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/git/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/github/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/growth/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/health/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/models/defaults/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/models/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/pi-settings/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/plugins/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/prompts/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/remote/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/security/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/export/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/sessions/import/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/sessions/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/skills/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/update/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/version/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/web-auth/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/api/workspaces/route-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/app/page-dc3cb41d91c7432e.js +1 -0
- package/.next/static/chunks/framework-47b723d27f4a4963.js +1 -0
- package/.next/static/chunks/main-5403f0764579e5fe.js +5 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-cbaaee0d7aacb85a.js +1 -0
- package/.next/static/chunks/webpack-2ac3d76b81895f5b.js +1 -0
- package/.next/static/css/9fc559c2c4ad1d0f.css +1 -0
- package/.next/static/css/c6e2227c36ec2fd6.css +1 -0
- package/.next/static/css/{2959bd6b626b7ffe.css → f15a853af8b5127f.css} +1 -1
- package/.next/static/hYPL1-dmhKFjLS3f5yoqN/_buildManifest.js +1 -0
- package/.next/types/app/api/agent/[id]/events/route.ts +3 -1
- package/.next/types/app/api/agent/[id]/route.ts +3 -1
- package/.next/types/app/api/agent/[id]/side-chat/route.ts +355 -0
- package/.next/types/app/api/agent/[id]/tree/route.ts +3 -1
- package/.next/types/app/api/agent/new/route.ts +3 -1
- package/.next/types/app/api/config/route.ts +3 -1
- package/.next/types/app/api/files/route.ts +3 -1
- package/.next/types/app/api/fs/route.ts +3 -1
- package/.next/types/app/api/git/route.ts +3 -1
- package/.next/types/app/api/github/route.ts +355 -0
- package/.next/types/app/api/growth/route.ts +3 -1
- package/.next/types/app/api/health/route.ts +3 -1
- package/.next/types/app/api/models/defaults/route.ts +355 -0
- package/.next/types/app/api/models/route.ts +3 -1
- package/.next/types/app/api/pi-settings/route.ts +3 -1
- package/.next/types/app/api/plugins/route.ts +3 -1
- package/.next/types/app/api/prompts/route.ts +3 -1
- package/.next/types/app/api/remote/route.ts +3 -1
- package/.next/types/app/api/security/route.ts +3 -1
- package/.next/types/app/api/sessions/[id]/export/route.ts +3 -1
- package/.next/types/app/api/sessions/[id]/route.ts +3 -1
- package/.next/types/app/api/sessions/import/route.ts +3 -1
- package/.next/types/app/api/sessions/route.ts +3 -1
- package/.next/types/app/api/skills/route.ts +3 -1
- package/.next/types/app/api/update/route.ts +3 -1
- package/.next/types/app/api/version/route.ts +3 -1
- package/.next/types/app/api/web-auth/route.ts +3 -1
- package/.next/types/app/api/workspaces/route.ts +3 -1
- package/.next/types/app/layout.ts +4 -1
- package/.next/types/app/login/page.ts +4 -1
- package/.next/types/app/page.ts +4 -1
- package/.next/types/cache-life.d.ts +11 -43
- package/.next/types/routes.d.ts +4 -1
- package/.next/types/validator.ts +86 -2
- package/next.config.ts +2 -0
- package/package.json +8 -2
- package/scripts/release.mjs +3 -7
- package/scripts/runtime/check-installed.mjs +66 -0
- package/scripts/runtime/pi-packages.mjs +51 -0
- package/scripts/verify-package.mjs +29 -7
- package/src/app/api/agent/[id]/side-chat/route.ts +77 -0
- package/src/app/api/files/route.ts +5 -2
- package/src/app/api/github/route.ts +26 -0
- package/src/app/api/models/defaults/route.ts +18 -0
- package/src/app/api/models/route.ts +24 -1
- package/src/app/globals.css +1748 -0
- package/src/components/AppShell.tsx +145 -43
- package/src/components/ChatInput.tsx +264 -79
- package/src/components/ChatWindow.tsx +13 -23
- package/src/components/ContextMeter.tsx +213 -144
- package/src/components/DrawerPanel.tsx +1 -1
- package/src/components/FileViewer.tsx +89 -8
- package/src/components/GitPanel.tsx +110 -40
- package/src/components/GrowthTree.tsx +30 -5
- package/src/components/ModelSelector.tsx +21 -5
- package/src/components/ProjectPanel.tsx +55 -30
- package/src/components/PromptPanel.tsx +2 -4
- package/src/components/ProviderSetupModal.module.css +20 -0
- package/src/components/ProviderSetupModal.tsx +134 -29
- package/src/components/SettingsPanel.tsx +252 -27
- package/src/components/TrajectoryView.tsx +4 -6
- package/src/components/chat/reading-anchor.ts +81 -0
- package/src/components/composer/ComposerImages.tsx +326 -0
- package/src/components/side-chat/SideChatPanel.module.css +131 -0
- package/src/components/side-chat/SideChatPanel.tsx +189 -0
- package/src/components/side-chat/icons.tsx +8 -0
- package/src/components/side-chat/request-history.ts +29 -0
- package/src/components/side-chat/store.ts +248 -0
- package/src/hooks/useFileViewer.ts +6 -4
- package/src/hooks/useGrowth.ts +3 -0
- package/src/hooks/usePiWeb.ts +12 -2
- package/src/hooks/useWorkspaceFiles.ts +93 -0
- package/src/i18n.tsx +150 -2
- package/src/lib/agent-manager.ts +135 -104
- package/src/lib/files-service.ts +166 -3
- package/src/lib/format.ts +56 -0
- package/src/lib/git-service.ts +45 -13
- package/src/lib/github-identity.ts +245 -0
- package/src/lib/growth-service.ts +6 -2
- package/src/lib/hero-model-memory.ts +28 -0
- package/src/lib/model-defaults.ts +105 -0
- package/src/lib/model-draft.ts +257 -9
- package/src/lib/model-endpoint.ts +23 -0
- package/src/lib/model-files.ts +33 -0
- package/src/lib/models-service.ts +240 -78
- package/src/lib/path-security.ts +24 -32
- package/src/lib/pi.ts +27 -2
- package/src/lib/process-format.ts +3 -2
- package/src/lib/session/metrics.ts +31 -0
- package/src/lib/session-reader.ts +1 -1
- package/src/lib/side-chat/context.ts +123 -0
- package/src/lib/side-chat/service.ts +191 -0
- package/src/lib/side-chat/types.ts +61 -0
- package/src/lib/thinking-level.ts +39 -0
- package/src/lib/trajectory.ts +17 -3
- package/src/lib/types.ts +12 -1
- package/src/lib/update-service.ts +4 -6
- package/src/lib/workspace-index.ts +270 -0
- package/.next/server/chunks/229.js +0 -1
- package/.next/server/chunks/393.js +0 -1
- package/.next/server/chunks/421.js +0 -1
- package/.next/server/chunks/430.js +0 -193
- package/.next/server/chunks/496.js +0 -1
- package/.next/server/chunks/662.js +0 -2
- package/.next/server/chunks/686.js +0 -1
- package/.next/server/chunks/741.js +0 -165
- package/.next/server/chunks/802.js +0 -2
- package/.next/server/chunks/807.js +0 -1
- package/.next/server/chunks/813.js +0 -1
- package/.next/server/chunks/924.js +0 -6
- package/.next/static/chunks/2716.7ad073038e94a802.js +0 -1
- package/.next/static/chunks/316-5ea443ee6b512aa9.js +0 -1
- package/.next/static/chunks/3794-3679f1c05160977c.js +0 -52
- package/.next/static/chunks/4673.8a5a9e6855350e34.js +0 -1
- package/.next/static/chunks/4686-882531aef1d2e250.js +0 -1
- package/.next/static/chunks/4778.305dc6abb9889627.js +0 -1
- package/.next/static/chunks/4bd1b696-93bf506b236d6248.js +0 -1
- package/.next/static/chunks/618.ee5d5bf1c647e483.js +0 -4
- package/.next/static/chunks/839.bfd2db36483faa3e.js +0 -1
- package/.next/static/chunks/app/_global-error/page-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/events/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/agent/[id]/tree/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/agent/new/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/config/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/files/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/fs/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/git/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/growth/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/health/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/models/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/pi-settings/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/plugins/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/prompts/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/remote/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/security/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/export/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/sessions/import/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/sessions/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/skills/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/update/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/version/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/web-auth/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/api/workspaces/route-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/app/page-c04af72e549695bd.js +0 -1
- package/.next/static/chunks/framework-c4e651fe89edfa91.js +0 -1
- package/.next/static/chunks/main-6159b22a8cb0b7c5.js +0 -5
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-b179d9f7f6f2daf9.js +0 -1
- package/.next/static/chunks/webpack-9b4bb574e5817654.js +0 -1
- package/.next/static/css/ea27b9e30f76303f.css +0 -1
- package/.next/static/sNX5GQkOWuK5YEID1hT-C/_buildManifest.js +0 -1
- /package/.next/static/{sNX5GQkOWuK5YEID1hT-C → hYPL1-dmhKFjLS3f5yoqN}/_ssgManifest.js +0 -0
package/src/i18n.tsx
CHANGED
|
@@ -38,13 +38,42 @@ const zh = {
|
|
|
38
38
|
capacityFields: "容量",
|
|
39
39
|
contextWindowLabel: "上下文窗口",
|
|
40
40
|
maxTokensLabel: "最大输出",
|
|
41
|
-
capacityHint: "
|
|
41
|
+
capacityHint: "留空按 pi 缺省(128K / 16K)· 支持 256K / 2M 写法",
|
|
42
|
+
// 模型能力(视觉)与配置体检
|
|
43
|
+
visionLabel: "视觉",
|
|
44
|
+
visionHint: "该模型能否接收图片。未声明时 pi 按纯文本处理:你贴的截图会被换成一行占位文字(提示语还会说成「模型不支持图像」)",
|
|
45
|
+
visionUnset: "未声明",
|
|
46
|
+
visionInputText: "文本",
|
|
47
|
+
visionInputTextHint: "pi 总是接受文本输入;贴图能不能发由「图片」决定",
|
|
48
|
+
visionInputImage: "图片",
|
|
49
|
+
visionInputImageHint: "勾上表示该模型能收图(写进 models.json 的 input);不勾则按纯文本处理",
|
|
50
|
+
visionOn: "有视觉",
|
|
51
|
+
visionOff: "纯文本",
|
|
52
|
+
imagePreview: "点击放大预览",
|
|
53
|
+
imageViewer: "图片预览",
|
|
54
|
+
imageClearAll: "清空图片",
|
|
55
|
+
imagePrev: "上一张",
|
|
56
|
+
imageNext: "下一张",
|
|
57
|
+
chipExpandMore: "展开 {n}",
|
|
58
|
+
chipCollapse: "收起",
|
|
59
|
+
modelAuditTitle: "{n} 个模型没写能力字段",
|
|
60
|
+
modelAuditDesc: "没写的字段,pi 会按上下文 {ctx}、输出上限 {out}、纯文本处理。端点没报的值不会替你猜:照模型的真实规格填上(支持 256K / 1M 写法),保存时只补空着的格子,已写的值不改。",
|
|
61
|
+
modelAuditColModel: "模型",
|
|
62
|
+
modelAuditColContext: "上下文",
|
|
63
|
+
modelAuditColOutput: "输出上限",
|
|
64
|
+
modelAuditColVision: "视觉",
|
|
65
|
+
modelAuditVisionQuick: "视觉一起设:",
|
|
66
|
+
modelAuditVisionOn: "都有视觉",
|
|
67
|
+
modelAuditVisionOff: "都是纯文本",
|
|
68
|
+
modelAuditSave: "保存 {n} 个模型",
|
|
69
|
+
modelAuditSaveIdle: "填好后保存",
|
|
42
70
|
capacityInvalid: "第 {n} 行:容量需为数字(可用 K/M)",
|
|
43
71
|
discoverEmpty: "远端没有返回可识别的模型",
|
|
44
72
|
candidateTitle: "发现 {count} 个模型,勾选要添加的",
|
|
45
73
|
candidateAll: "全选",
|
|
46
74
|
candidatePicked: "已选 {n} 个",
|
|
47
75
|
candidateAdopt: "添加 {n} 个",
|
|
76
|
+
candidateInCatalog: "已在目录中",
|
|
48
77
|
runningTool: "Running {name}…",
|
|
49
78
|
thinkingLive: "Thinking",
|
|
50
79
|
stepRunning: "Running",
|
|
@@ -127,6 +156,10 @@ const zh = {
|
|
|
127
156
|
gitNoChanges: "工作区干净,没有变更",
|
|
128
157
|
gitStatusUnknown: "Git 状态读取失败,无法确认是否有变更",
|
|
129
158
|
gitRecentCommits: "最近提交",
|
|
159
|
+
gitStagingArea: "暂存区",
|
|
160
|
+
gitWorkingTree: "工作区",
|
|
161
|
+
gitGithubAccount: "GitHub 账号",
|
|
162
|
+
gitGithubUnknown: "未识别到 GitHub 账号",
|
|
130
163
|
toolNoOutput: "无输出",
|
|
131
164
|
toolFailed: "失败",
|
|
132
165
|
thinkingClamped: "当前模型不支持「{requested}」,已改为「{level}」",
|
|
@@ -285,6 +318,11 @@ const zh = {
|
|
|
285
318
|
extensionStatus: "扩展状态",
|
|
286
319
|
contextUsed: "上下文已用",
|
|
287
320
|
contextUnknown: "上下文用量未知",
|
|
321
|
+
contextEstimated: "上下文估算",
|
|
322
|
+
contextMeasured: "上下文用量",
|
|
323
|
+
contextBackground: "Main Conversation",
|
|
324
|
+
contextApiInput: "最近请求输入(API)",
|
|
325
|
+
contextChars: "字符",
|
|
288
326
|
contextSystem: "系统提示词",
|
|
289
327
|
contextMessages: "对话消息",
|
|
290
328
|
contextTools: "工具",
|
|
@@ -326,6 +364,20 @@ const zh = {
|
|
|
326
364
|
contextColdHint: "会话还没启动,System Prompt 和工具定义要启动后才算得出",
|
|
327
365
|
contextCountNow: "现在统计",
|
|
328
366
|
contextCounting: "统计中…",
|
|
367
|
+
contextWindowEdit: "修改",
|
|
368
|
+
contextWindowBuiltin: "pi 内置目录:{value}",
|
|
369
|
+
contextWindowUseBuiltin: "填入",
|
|
370
|
+
contextWindowScope: "改的是这个模型的全局配置(models.json),pi 终端和其它会话一起生效",
|
|
371
|
+
contextWindowOverBuiltin: "比内置目录大:超过模型实际上限时,请求会被上游拒绝(400)",
|
|
372
|
+
contextWindowNoBuiltin: "填模型实际支持的上限;填大了,请求会被上游拒绝(400)",
|
|
373
|
+
contextWindowInvalid: "填正整数,可带 K / M(如 200K)",
|
|
374
|
+
// @ 文件引用(输入 @ 弹候选)
|
|
375
|
+
mentionFiles: "@ 引用文件 / 文件夹",
|
|
376
|
+
mentionHint: "↑↓ 选择 · Enter 引用 · Esc 关闭",
|
|
377
|
+
mentionNoMatch: "没有匹配的文件",
|
|
378
|
+
mentionTruncated: "候选已截断",
|
|
379
|
+
mentionDiskSource: "目录遍历",
|
|
380
|
+
mentionDiskSourceHint: "当前工作区不是 git 仓库(或没装 git):候选来自目录遍历,会跳过 node_modules、构建产物等目录;列为 git 仓库后候选会自动按 .gitignore 过滤",
|
|
329
381
|
// 统计条
|
|
330
382
|
turns: "轮次",
|
|
331
383
|
toolCalls: "工具调用",
|
|
@@ -416,6 +468,21 @@ const zh = {
|
|
|
416
468
|
drawerPanel: "右侧抽屉",
|
|
417
469
|
drawerSections: "抽屉入口",
|
|
418
470
|
drawerPrompts: "提示词",
|
|
471
|
+
sideChat: "旁聊",
|
|
472
|
+
sideChatModel: "旁聊模型",
|
|
473
|
+
sideChatFollowMain: "跟随主会话",
|
|
474
|
+
sideChatNew: "新旁聊",
|
|
475
|
+
sideChatHistory: "旁聊记录",
|
|
476
|
+
sideChatMessages: "旁聊消息",
|
|
477
|
+
sideChatQuestion: "旁聊提问",
|
|
478
|
+
sideChatPlaceholder: "读到哪里有疑问,就在这里问…",
|
|
479
|
+
sideChatEmpty: "边读边问,主会话停在原处",
|
|
480
|
+
sideChatHint: "参考主会话,问答独立。记录仅保存在此浏览器。",
|
|
481
|
+
sideChatPickSession: "打开一个主会话后,就可以旁聊",
|
|
482
|
+
sideChatAnswering: "正在回答…",
|
|
483
|
+
sideChatContextTruncated: "背景较长,本次仅参考了部分主会话或旁聊记录。",
|
|
484
|
+
sideChatLengthLimited: "已达到本次输出上限,可以继续追问。",
|
|
485
|
+
sideChatStorageFailed: "浏览器未能保存旁聊记录,请先保留需要的内容。",
|
|
419
486
|
setPlugins: "插件",
|
|
420
487
|
setRemote: "远程连接",
|
|
421
488
|
remoteBuiltin: "内置插件",
|
|
@@ -507,10 +574,14 @@ const zh = {
|
|
|
507
574
|
allowPrivateDiscovery: "允许本机/私网",
|
|
508
575
|
allowPrivateHint: "模型地址指向本机或私有网络(如 Ollama、LM Studio、one-api 本地网关)时勾选,本次探测放行;发消息不受此限制",
|
|
509
576
|
discoveringModels: "获取中...",
|
|
577
|
+
autoDiscovering: "正在自动识别模型…",
|
|
578
|
+
autoDiscovered: "已自动识别 {n} 个模型(端点报了容量与视觉的已一并填好)",
|
|
579
|
+
autoDiscoverFailed: "自动识别失败,可点「获取可用模型」重试",
|
|
510
580
|
usingDefaultModels: "正在使用 Pi SDK 默认模型 · {count} 个",
|
|
511
581
|
customModelsRequired: "至少添加一个可发送的模型 ID",
|
|
512
582
|
modelCatalogEmptyBuiltin: "未添加覆盖模型;模型选择器会继续实时使用 Pi SDK 的官方模型目录。",
|
|
513
583
|
modelCatalogEmptyCustom: "模型选择器中将不显示任何模型;请至少添加一个模型 ID。",
|
|
584
|
+
catalogOverrideHint: "与内置目录同 ID 的行只覆盖填写的字段,推理、价格、思考档位等沿用内置值。",
|
|
514
585
|
addModel: "添加模型",
|
|
515
586
|
modelId: "模型 ID",
|
|
516
587
|
createProvider: "创建提供方",
|
|
@@ -668,6 +739,9 @@ const zh = {
|
|
|
668
739
|
viewerNotInSnapshot: "此文件不在快照里(超过 1MB 或被排除),显示磁盘上的当前内容",
|
|
669
740
|
viewerLoadFailed: "加载失败",
|
|
670
741
|
viewerEmpty: "从左侧树里选择一个文件",
|
|
742
|
+
viewerOpenFolder: "打开文件夹预览",
|
|
743
|
+
viewerDirHint: "文件夹:共 {n} 项(已按 .gitignore 过滤)",
|
|
744
|
+
viewerDirMore: "加载更多",
|
|
671
745
|
// 流式输出
|
|
672
746
|
streamStyleTitle: "流式输出样式",
|
|
673
747
|
streamStyleDesc: "回答逐字出现的方式;改完立刻生效,正在流出的回答也一并换",
|
|
@@ -723,13 +797,42 @@ const en: Dict = {
|
|
|
723
797
|
capacityFields: "Capacities",
|
|
724
798
|
contextWindowLabel: "Context window",
|
|
725
799
|
maxTokensLabel: "Max output",
|
|
726
|
-
capacityHint: "blank = default · 256K / 2M accepted",
|
|
800
|
+
capacityHint: "blank = pi default (128K / 16K) · 256K / 2M accepted",
|
|
801
|
+
// model capability (vision) and config checkup
|
|
802
|
+
visionLabel: "Vision",
|
|
803
|
+
visionHint: "Whether this model accepts images. Left unset, pi treats it as text-only and replaces pasted screenshots with a placeholder line.",
|
|
804
|
+
visionUnset: "Not declared",
|
|
805
|
+
visionInputText: "Text",
|
|
806
|
+
visionInputTextHint: "pi always accepts text; whether images can be sent is decided by the Image box",
|
|
807
|
+
visionInputImage: "Image",
|
|
808
|
+
visionInputImageHint: "Checked means this model accepts images (written into models.json input); unchecked is treated as text-only",
|
|
809
|
+
visionOn: "Vision",
|
|
810
|
+
visionOff: "Text only",
|
|
811
|
+
imagePreview: "Click to preview",
|
|
812
|
+
imageViewer: "Image preview",
|
|
813
|
+
imageClearAll: "Clear images",
|
|
814
|
+
imagePrev: "Previous image",
|
|
815
|
+
imageNext: "Next image",
|
|
816
|
+
chipExpandMore: "Show {n} more",
|
|
817
|
+
chipCollapse: "Collapse",
|
|
818
|
+
modelAuditTitle: "{n} models don't declare their capabilities",
|
|
819
|
+
modelAuditDesc: "For fields left out, pi assumes a {ctx} context window, {out} max output and text-only input. Values the endpoint didn't report are never guessed: fill in the model's real limits (256K / 1M accepted). Saving only fills empty cells and never changes values already set.",
|
|
820
|
+
modelAuditColModel: "Model",
|
|
821
|
+
modelAuditColContext: "Context",
|
|
822
|
+
modelAuditColOutput: "Max output",
|
|
823
|
+
modelAuditColVision: "Vision",
|
|
824
|
+
modelAuditVisionQuick: "Set vision for all:",
|
|
825
|
+
modelAuditVisionOn: "All vision",
|
|
826
|
+
modelAuditVisionOff: "All text only",
|
|
827
|
+
modelAuditSave: "Save {n} models",
|
|
828
|
+
modelAuditSaveIdle: "Fill in, then save",
|
|
727
829
|
capacityInvalid: "Row {n}: capacity must be a number (K/M ok)",
|
|
728
830
|
discoverEmpty: "No recognizable models returned",
|
|
729
831
|
candidateTitle: "Found {count} models — pick ones to add",
|
|
730
832
|
candidateAll: "Select all",
|
|
731
833
|
candidatePicked: "{n} selected",
|
|
732
834
|
candidateAdopt: "Add {n}",
|
|
835
|
+
candidateInCatalog: "Already in catalog",
|
|
733
836
|
runningTool: "Running {name}…",
|
|
734
837
|
thinkingLive: "Thinking",
|
|
735
838
|
stepRunning: "Running",
|
|
@@ -812,6 +915,10 @@ const en: Dict = {
|
|
|
812
915
|
gitNoChanges: "Working tree clean",
|
|
813
916
|
gitStatusUnknown: "Git status unavailable; changes could not be determined",
|
|
814
917
|
gitRecentCommits: "Recent commits",
|
|
918
|
+
gitStagingArea: "Staging area",
|
|
919
|
+
gitWorkingTree: "Working tree",
|
|
920
|
+
gitGithubAccount: "GitHub account",
|
|
921
|
+
gitGithubUnknown: "No GitHub account detected",
|
|
815
922
|
toolNoOutput: "no output",
|
|
816
923
|
toolFailed: "failed",
|
|
817
924
|
thinkingClamped: "This model does not support \"{requested}\"; using \"{level}\" instead",
|
|
@@ -968,6 +1075,11 @@ const en: Dict = {
|
|
|
968
1075
|
extensionStatus: "Extension status",
|
|
969
1076
|
contextUsed: "context used",
|
|
970
1077
|
contextUnknown: "Context usage unknown",
|
|
1078
|
+
contextEstimated: "estimated context usage",
|
|
1079
|
+
contextMeasured: "context usage",
|
|
1080
|
+
contextBackground: "Main Conversation",
|
|
1081
|
+
contextApiInput: "Last request input (API)",
|
|
1082
|
+
contextChars: "chars",
|
|
971
1083
|
contextSystem: "System prompt",
|
|
972
1084
|
contextMessages: "Messages",
|
|
973
1085
|
contextTools: "Tools",
|
|
@@ -1009,6 +1121,20 @@ const en: Dict = {
|
|
|
1009
1121
|
contextColdHint: "Session not started yet — System Prompt and tool definitions are counted once it starts",
|
|
1010
1122
|
contextCountNow: "Count now",
|
|
1011
1123
|
contextCounting: "Counting…",
|
|
1124
|
+
contextWindowEdit: "Edit",
|
|
1125
|
+
contextWindowBuiltin: "pi built-in catalog: {value}",
|
|
1126
|
+
contextWindowUseBuiltin: "Use",
|
|
1127
|
+
contextWindowScope: "Changes this model's global config (models.json); the pi terminal and other sessions use it too",
|
|
1128
|
+
contextWindowOverBuiltin: "Larger than the built-in catalog: requests past the model's real limit are rejected upstream (400)",
|
|
1129
|
+
contextWindowNoBuiltin: "Enter the model's real limit; a larger value gets requests rejected upstream (400)",
|
|
1130
|
+
contextWindowInvalid: "Enter a positive integer; K / M allowed (e.g. 200K)",
|
|
1131
|
+
// @ file references (type @ to open the picker)
|
|
1132
|
+
mentionFiles: "@ reference files / folders",
|
|
1133
|
+
mentionHint: "↑↓ select · Enter reference · Esc close",
|
|
1134
|
+
mentionNoMatch: "No matching files",
|
|
1135
|
+
mentionTruncated: "list truncated",
|
|
1136
|
+
mentionDiskSource: "directory scan",
|
|
1137
|
+
mentionDiskSourceHint: "This workspace is not a git repository (or git is missing): candidates come from a directory scan that skips node_modules and build output; in a git repository they follow .gitignore automatically",
|
|
1012
1138
|
turns: "turns",
|
|
1013
1139
|
toolCalls: "tool calls",
|
|
1014
1140
|
cost: "cost",
|
|
@@ -1094,6 +1220,21 @@ const en: Dict = {
|
|
|
1094
1220
|
drawerPanel: "Drawer",
|
|
1095
1221
|
drawerSections: "Drawer sections",
|
|
1096
1222
|
drawerPrompts: "Prompts",
|
|
1223
|
+
sideChat: "Side chat",
|
|
1224
|
+
sideChatModel: "Side-chat model",
|
|
1225
|
+
sideChatFollowMain: "Follow main chat",
|
|
1226
|
+
sideChatNew: "New side chat",
|
|
1227
|
+
sideChatHistory: "Side-chat history",
|
|
1228
|
+
sideChatMessages: "Side-chat messages",
|
|
1229
|
+
sideChatQuestion: "Side-chat question",
|
|
1230
|
+
sideChatPlaceholder: "Ask about anything you're reading…",
|
|
1231
|
+
sideChatEmpty: "Ask as you read. Keep your place.",
|
|
1232
|
+
sideChatHint: "Uses the main chat as background. Separate answers, saved only in this browser.",
|
|
1233
|
+
sideChatPickSession: "Open a main conversation to start a side chat",
|
|
1234
|
+
sideChatAnswering: "Answering…",
|
|
1235
|
+
sideChatContextTruncated: "The background is long; this answer uses part of the main or side-chat history.",
|
|
1236
|
+
sideChatLengthLimited: "This answer reached its output limit. You can ask it to continue.",
|
|
1237
|
+
sideChatStorageFailed: "Your browser could not save the side chat. Keep a copy of anything you need.",
|
|
1097
1238
|
setPlugins: "Plugins",
|
|
1098
1239
|
setRemote: "Remote access",
|
|
1099
1240
|
remoteBuiltin: "Built-in plugin",
|
|
@@ -1185,10 +1326,14 @@ const en: Dict = {
|
|
|
1185
1326
|
allowPrivateDiscovery: "Allow local/private",
|
|
1186
1327
|
allowPrivateHint: "Check this when the model address points to loopback or a private network (Ollama, LM Studio, one-api gateways) to allow this probe; chat requests are not affected",
|
|
1187
1328
|
discoveringModels: "Fetching...",
|
|
1329
|
+
autoDiscovering: "Detecting models…",
|
|
1330
|
+
autoDiscovered: "Detected {n} models (capacity and vision filled in where the endpoint reports them)",
|
|
1331
|
+
autoDiscoverFailed: "Automatic detection failed — use the button to retry",
|
|
1188
1332
|
usingDefaultModels: "Using Pi SDK default models · {count}",
|
|
1189
1333
|
customModelsRequired: "Add at least one model ID that can be sent",
|
|
1190
1334
|
modelCatalogEmptyBuiltin: "No model overrides. The model selector will continue using Pi SDK's live official catalog.",
|
|
1191
1335
|
modelCatalogEmptyCustom: "No models will appear in the selector. Add at least one model ID.",
|
|
1336
|
+
catalogOverrideHint: "Rows matching a built-in model ID only override the fields you fill in; reasoning, pricing and thinking levels stay built-in.",
|
|
1192
1337
|
addModel: "Add model",
|
|
1193
1338
|
modelId: "Model ID",
|
|
1194
1339
|
createProvider: "Create provider",
|
|
@@ -1345,6 +1490,9 @@ const en: Dict = {
|
|
|
1345
1490
|
viewerNotInSnapshot: "Not in the snapshot (over 1MB or excluded); showing the current content from disk",
|
|
1346
1491
|
viewerLoadFailed: "Failed to load",
|
|
1347
1492
|
viewerEmpty: "Pick a file from the tree on the left",
|
|
1493
|
+
viewerOpenFolder: "Preview folder",
|
|
1494
|
+
viewerDirHint: "Folder: {n} items (ignored files hidden)",
|
|
1495
|
+
viewerDirMore: "Load more",
|
|
1348
1496
|
// Streaming text
|
|
1349
1497
|
streamStyleTitle: "Streaming text",
|
|
1350
1498
|
streamStyleDesc: "How the answer appears while it arrives; applies to the stream already running",
|
package/src/lib/agent-manager.ts
CHANGED
|
@@ -25,17 +25,18 @@ import {
|
|
|
25
25
|
SessionManager,
|
|
26
26
|
createAgentSession,
|
|
27
27
|
getModelRuntime,
|
|
28
|
+
refreshModelRuntime,
|
|
28
29
|
openSessionManager,
|
|
29
30
|
} from "./pi";
|
|
30
31
|
import { createExtensionUiBridge, type ExtensionUiBridge } from "./extension-ui";
|
|
31
32
|
import { createGrowthTracker, GROWTH_TRACKER_VERSION, type GrowthTracker } from "./growth-tracker";
|
|
32
33
|
import { userTurnsFromEntries } from "./growth-turns";
|
|
34
|
+
import { projectedContextUsage } from "./session/metrics";
|
|
33
35
|
import { TrajLedger, buildTrajectoryFromEntries, toTrajTokens } from "./trajectory";
|
|
34
36
|
import { startArchivedSessionRetention } from "./session-retention";
|
|
35
37
|
import { sanitizeToolOutput } from "./text-sanitize";
|
|
36
38
|
import { BoundaryError } from "./path-security";
|
|
37
|
-
import {
|
|
38
|
-
import { getPiSettings } from "./pi-settings";
|
|
39
|
+
import { newSessionThinkingLevel } from "./thinking-level";
|
|
39
40
|
import { getGrowthInitConsent, setGrowthInitConsent } from "./workspace-store";
|
|
40
41
|
import { clampThinkingLevel, getSupportedThinkingLevels } from "@earendil-works/pi-ai";
|
|
41
42
|
import type {
|
|
@@ -67,6 +68,8 @@ interface Managed {
|
|
|
67
68
|
viewerGraceUntil?: number;
|
|
68
69
|
/** 本轮已排队推送上下文分项(publishContextBreakdown 合并同一轮的多次触发) */
|
|
69
70
|
breakdownQueued?: boolean;
|
|
71
|
+
/** 首次运行后 pi 才会把系统分段持久化,届时用它把分类从差分换成投影口径,只换一次 */
|
|
72
|
+
breakdownProjected?: boolean;
|
|
70
73
|
buffer: { seq: number; json: string }[];
|
|
71
74
|
seq: number;
|
|
72
75
|
/**
|
|
@@ -349,36 +352,58 @@ function reapplyDesiredLevel(m: Managed, session: AgentSession): void {
|
|
|
349
352
|
if (target !== session.thinkingLevel) session.setThinkingLevel(target as never);
|
|
350
353
|
}
|
|
351
354
|
|
|
355
|
+
/**
|
|
356
|
+
* 新会话页选定模型后的思考档位:与界面显示的生效值同一规则(每模型覆盖 → 设置默认 → medium,再按模型能力钳制)。
|
|
357
|
+
* SDK 切换模型时会沿用会话原来的档位,新会话不能沿用:那个档位是 SDK 按它自己的初始模型定的。
|
|
358
|
+
*/
|
|
359
|
+
function applyNewSessionThinking(m: Managed, session: AgentSession): void {
|
|
360
|
+
const model = session.model;
|
|
361
|
+
if (!model) return;
|
|
362
|
+
const settings = getSettingsManager(m.cwd);
|
|
363
|
+
const level = newSessionThinkingLevel({
|
|
364
|
+
supported: session.getAvailableThinkingLevels() as unknown as string[],
|
|
365
|
+
modelOverride: settings.getModelThinkingLevel(model.provider, model.id),
|
|
366
|
+
defaultLevel: settings.getDefaultThinkingLevel(),
|
|
367
|
+
});
|
|
368
|
+
if (level !== session.thinkingLevel) session.setThinkingLevel(level as never);
|
|
369
|
+
}
|
|
370
|
+
|
|
352
371
|
function publishTraj(m: Managed): void {
|
|
353
372
|
for (const entry of m.ledger.drainDirty()) {
|
|
354
373
|
publish(m, { type: "traj", entry, ts: Date.now() });
|
|
355
374
|
}
|
|
356
375
|
}
|
|
357
376
|
|
|
358
|
-
function timingStats(m: Managed): Pick<WebStats, "llmMs" | "toolMs" | "ttftMs" | "ttftSteps" | "decodeMs" | "decodeTokens"> {
|
|
377
|
+
function timingStats(m: Managed): Pick<WebStats, "llmMs" | "toolMs" | "ttftMs" | "ttftSteps" | "decodeMs" | "decodeTokens" | "llmTimedSteps" | "toolTimedCalls" | "decodeSteps"> {
|
|
359
378
|
let llmMs = 0;
|
|
360
379
|
let toolMs = 0;
|
|
361
380
|
let ttftMs = 0;
|
|
362
381
|
let ttftSteps = 0;
|
|
363
382
|
let decodeMs = 0;
|
|
364
383
|
let decodeTokens = 0;
|
|
384
|
+
let llmTimedSteps = 0;
|
|
385
|
+
let toolTimedCalls = 0;
|
|
386
|
+
let decodeSteps = 0;
|
|
365
387
|
for (const entry of m.ledger.entries) {
|
|
366
388
|
if (entry.kind === "tool") {
|
|
389
|
+
if (entry.timing?.durationMs !== undefined) toolTimedCalls++;
|
|
367
390
|
toolMs += Math.max(0, entry.timing?.durationMs ?? 0);
|
|
368
391
|
continue;
|
|
369
392
|
}
|
|
370
393
|
if (entry.kind !== "message") continue;
|
|
394
|
+
if (entry.timing?.durationMs !== undefined) llmTimedSteps++;
|
|
371
395
|
llmMs += Math.max(0, entry.timing?.durationMs ?? 0);
|
|
372
396
|
if (entry.timing?.ttftMs !== undefined) {
|
|
373
397
|
ttftMs += Math.max(0, entry.timing.ttftMs);
|
|
374
398
|
ttftSteps += 1;
|
|
375
399
|
}
|
|
376
|
-
if (entry.timing?.decodeMs
|
|
377
|
-
|
|
400
|
+
if ((entry.timing?.decodeMs ?? 0) > 0 && entry.tokens?.output !== undefined) {
|
|
401
|
+
decodeSteps++;
|
|
402
|
+
decodeMs += Math.max(0, entry.timing?.decodeMs ?? 0);
|
|
378
403
|
decodeTokens += Math.max(0, entry.tokens.output);
|
|
379
404
|
}
|
|
380
405
|
}
|
|
381
|
-
return { llmMs, toolMs, ttftMs, ttftSteps, decodeMs, decodeTokens };
|
|
406
|
+
return { llmMs, toolMs, ttftMs, ttftSteps, decodeMs, decodeTokens, llmTimedSteps, toolTimedCalls, decodeSteps };
|
|
382
407
|
}
|
|
383
408
|
|
|
384
409
|
function sessionStats(m: Managed): WebStats | null {
|
|
@@ -415,7 +440,7 @@ function coldSessionStats(m: Managed): WebStats {
|
|
|
415
440
|
cost += Number(usage.cost?.total ?? 0);
|
|
416
441
|
};
|
|
417
442
|
for (const entry of m.sm.getEntries() as any[]) {
|
|
418
|
-
if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) addUsage(entry.usage);
|
|
443
|
+
if ((entry.type === "usage" || entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) addUsage(entry.usage);
|
|
419
444
|
if (entry.type !== "message" || !entry.message) continue;
|
|
420
445
|
totalMessages += 1;
|
|
421
446
|
const message = entry.message;
|
|
@@ -497,7 +522,14 @@ function translate(m: Managed, evt: AgentSessionEvent): void {
|
|
|
497
522
|
// the browser receives the durable entry ID without reordering later tool events.
|
|
498
523
|
deferPublish(m, () => {
|
|
499
524
|
const msg = projectMessage(m, raw);
|
|
500
|
-
if (msg.role === "assistant")
|
|
525
|
+
if (msg.role === "assistant") {
|
|
526
|
+
msg.endedAt = now;
|
|
527
|
+
// 首次回复结束后 pi 已把系统分段写进会话文件,此时分类能读到投影(比 systemPrompt 差分精确)
|
|
528
|
+
if (!m.breakdownProjected) {
|
|
529
|
+
m.breakdownProjected = true;
|
|
530
|
+
publishContextBreakdown(m);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
501
533
|
const usage = usageEvent(m);
|
|
502
534
|
return usage
|
|
503
535
|
? [{ type: "message", message: msg, phase: "end", ts: now }, usage]
|
|
@@ -597,8 +629,8 @@ function translate(m: Managed, evt: AgentSessionEvent): void {
|
|
|
597
629
|
else publish(m, { type: "model", thinkingLevel: (evt as any).level, ts: now });
|
|
598
630
|
break;
|
|
599
631
|
case "auto_retry_start":
|
|
600
|
-
//
|
|
601
|
-
// 不再走 error
|
|
632
|
+
// 重试是流程内通知:发一条结构化 retry 事件(界面聚合成「重试 n/max」一行),
|
|
633
|
+
// 不再走 error 通道,免得每次尝试都多出一条报错。
|
|
602
634
|
publish(m, {
|
|
603
635
|
type: "retry",
|
|
604
636
|
attempt: Number((evt as any).attempt) || 0,
|
|
@@ -607,6 +639,13 @@ function translate(m: Managed, evt: AgentSessionEvent): void {
|
|
|
607
639
|
ts: now,
|
|
608
640
|
});
|
|
609
641
|
break;
|
|
642
|
+
case "auto_retry_end":
|
|
643
|
+
// 重试收尾:SDK 成功/最终失败/被中止都会发这条,而重试成功后的这轮对话
|
|
644
|
+
// agent_settled 之前界面上还留着「重试 1/5 terminated」那一行(用户看到的
|
|
645
|
+
// 就是「已经恢复了还显示错误」)。这里显式发一条清除事件,重试区间一结束
|
|
646
|
+
// 就收掉这行;真失败时紧随其后的 assistant error 消息会照常出错误块。
|
|
647
|
+
publish(m, { type: "retry_end", attempt: Number((evt as any).attempt) || 0, ts: now });
|
|
648
|
+
break;
|
|
610
649
|
default:
|
|
611
650
|
break;
|
|
612
651
|
}
|
|
@@ -742,13 +781,9 @@ const SKILLS_SECTION_START = "The following skills provide specialized instructi
|
|
|
742
781
|
const SKILLS_SECTION_END = "</available_skills>";
|
|
743
782
|
|
|
744
783
|
/**
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
* 冷会话(只浏览历史、不冷启动 agent)拿不到组装后的 system prompt 和工具定义,这三项为 0、标 cold;
|
|
750
|
-
* Memory / Skills / Compacted / Buffer 不依赖 agent,照常从发现缓存、会话文件和设置里算,
|
|
751
|
-
* 不能因为没启动就整块归零(那样弹窗只剩消息几类)。
|
|
784
|
+
* 当前上下文的字符分类,优先读 SDK 投影中的系统分段、工具 schema 与摘要。
|
|
785
|
+
* 旧客户端仍可读取字符/4 的估算字段;新客户端仅将字符数作为分类数据。
|
|
786
|
+
* 没有持久化系统消息且尚未启动的会话,资源来自发现缓存并标记 cold。
|
|
752
787
|
*/
|
|
753
788
|
async function buildContextBreakdown(m: Managed, resources: ContextResource[]): Promise<ContextBreakdown> {
|
|
754
789
|
const session = m.session;
|
|
@@ -758,64 +793,56 @@ async function buildContextBreakdown(m: Managed, resources: ContextResource[]):
|
|
|
758
793
|
};
|
|
759
794
|
// Memory:AGENTS.md 等注入文件(contextResources 的 project 部分)
|
|
760
795
|
const memoryText = resources.filter((r) => r.source === "project").map((r) => r.content).join("\n\n");
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
796
|
+
// 字符分项只读取当前投影中的内容。历史压缩摘要、未激活工具不混入当前统计。
|
|
797
|
+
const characters = { systemPrompt: 0, systemTools: 0, customTools: 0, memory: 0, skills: 0, compacted: 0 };
|
|
798
|
+
try {
|
|
799
|
+
const messages = m.sm.buildSessionProjection().messages as any[];
|
|
800
|
+
const system = messages.findLast((message) => message.role === "system");
|
|
801
|
+
if (system) {
|
|
802
|
+
const contentChars = typeof system.content === "string" ? system.content.length : textOf(system.content).length;
|
|
803
|
+
characters.memory = system.sections?.project_context?.length ?? 0;
|
|
804
|
+
characters.skills = system.sections?.skills?.length ?? 0;
|
|
805
|
+
characters.systemPrompt = contentChars + Object.entries(system.sections ?? {})
|
|
806
|
+
.filter(([key]) => key !== "project_context" && key !== "skills")
|
|
807
|
+
.reduce((sum, [, value]) => sum + (typeof value === "string" ? value.length : 0), 0);
|
|
808
|
+
const builtinNames = new Set(session
|
|
809
|
+
? session.getAllTools().filter((tool: any) => tool.sourceInfo?.source === "builtin").map((tool) => tool.name)
|
|
810
|
+
: ["read", "bash", "edit", "write", "grep", "find", "ls"]);
|
|
811
|
+
for (const tool of system.toolsAdded ?? []) {
|
|
812
|
+
characters[builtinNames.has(tool.name) ? "systemTools" : "customTools"] += JSON.stringify(tool).length;
|
|
776
813
|
}
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
814
|
+
delete breakdown.cold;
|
|
815
|
+
} else if (session) {
|
|
816
|
+
const prompt = session.systemPrompt ?? "";
|
|
817
|
+
characters.memory = memoryText.length;
|
|
818
|
+
const start = prompt.indexOf(SKILLS_SECTION_START);
|
|
819
|
+
const end = prompt.indexOf(SKILLS_SECTION_END);
|
|
820
|
+
characters.skills = start >= 0 && end > start ? prompt.slice(start, end + SKILLS_SECTION_END.length).length : 0;
|
|
821
|
+
characters.systemPrompt = Math.max(0, prompt.length - characters.memory - characters.skills);
|
|
822
|
+
const active = new Set(session.getActiveToolNames());
|
|
823
|
+
for (const tool of session.getAllTools().filter((tool) => active.has(tool.name))) {
|
|
824
|
+
const size = JSON.stringify({ name: tool.name, description: tool.description, parameters: tool.parameters }).length;
|
|
825
|
+
characters[(tool as any).sourceInfo?.source === "builtin" ? "systemTools" : "customTools"] += size;
|
|
789
826
|
}
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
} else {
|
|
794
|
-
// 冷会话:技能段用发现缓存里的清单按 SDK 同一个格式化函数估算(启动后改用实际 prompt 里的那段)
|
|
795
|
-
try {
|
|
827
|
+
} else {
|
|
828
|
+
// 初次启动前只能读到待注入的资源,界面保留 cold 提示。
|
|
829
|
+
characters.memory = memoryText.length;
|
|
796
830
|
const loader = peekResourceLoader(m.cwd) ?? getResourceLoader(m.cwd);
|
|
797
|
-
|
|
798
|
-
} catch {
|
|
799
|
-
/* 发现缓存还没好则跳过 */
|
|
831
|
+
characters.skills = formatSkillsForPrompt(loader.getSkills().skills).trim().length;
|
|
800
832
|
}
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
try {
|
|
804
|
-
const entries = m.sm.getEntries() as unknown as { type?: string; summary?: string }[];
|
|
805
|
-
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
806
|
-
const entry = entries[i];
|
|
807
|
-
if (entry?.type === "compaction" && typeof entry.summary === "string") {
|
|
808
|
-
breakdown.compacted = estimateTokensOf(entry.summary);
|
|
809
|
-
break;
|
|
810
|
-
}
|
|
833
|
+
for (const message of messages) {
|
|
834
|
+
if (message.role === "compactionSummary" || message.role === "branchSummary") characters.compacted += message.summary?.length ?? 0;
|
|
811
835
|
}
|
|
836
|
+
breakdown.characters = characters;
|
|
837
|
+
// 保留旧客户端的估算字段,当前客户端直接展示实际字符数。
|
|
838
|
+
for (const key of Object.keys(characters) as Array<keyof typeof characters>) breakdown[key] = Math.ceil(characters[key] / 4);
|
|
812
839
|
} catch {
|
|
813
|
-
/*
|
|
840
|
+
/* 投影不可用时不给字符分项,不能从旧 token 估算反推字符数。 */
|
|
814
841
|
}
|
|
815
|
-
// auto-compact
|
|
842
|
+
// auto-compact 预留读本工作区、当前模型实际使用的设置。
|
|
816
843
|
try {
|
|
817
|
-
const
|
|
818
|
-
if (
|
|
844
|
+
const compaction = getSettingsManager(m.cwd).getCompactionSettings(session?.model);
|
|
845
|
+
if (compaction.enabled) breakdown.autoCompactBuffer = compaction.reserveTokens;
|
|
819
846
|
} catch {
|
|
820
847
|
/* 设置读取失败则保持 0 */
|
|
821
848
|
}
|
|
@@ -1208,11 +1235,7 @@ async function reloadManagedResources(m: Managed): Promise<boolean> {
|
|
|
1208
1235
|
m.resourceReloadPending = false;
|
|
1209
1236
|
try {
|
|
1210
1237
|
await m.session.reload();
|
|
1211
|
-
|
|
1212
|
-
// 会话手里还是旧对象。按 provider/id 从(已就地刷新的)共享 runtime 取一次新的。
|
|
1213
|
-
const current = m.session.model;
|
|
1214
|
-
const fresh = current && m.session.modelRuntime.getModel(current.provider, current.id);
|
|
1215
|
-
if (fresh && fresh !== current) m.session.agent.state.model = fresh;
|
|
1238
|
+
swapCurrentModelObject(m.session);
|
|
1216
1239
|
return true;
|
|
1217
1240
|
} catch (err) {
|
|
1218
1241
|
publish(m, { type: "error", message: `重载扩展失败:${String((err as Error)?.message ?? err)}`, ts: Date.now() });
|
|
@@ -1222,6 +1245,32 @@ async function reloadManagedResources(m: Managed): Promise<boolean> {
|
|
|
1222
1245
|
}
|
|
1223
1246
|
}
|
|
1224
1247
|
|
|
1248
|
+
/**
|
|
1249
|
+
* SDK 的 reload 不会换当前模型对象:models.json 改了 baseUrl / contextWindow 后,会话手里还是旧对象。
|
|
1250
|
+
* 按 provider/id 从(已就地刷新的)共享 runtime 取一次新的。
|
|
1251
|
+
*/
|
|
1252
|
+
function swapCurrentModelObject(session: AgentSession): void {
|
|
1253
|
+
const current = session.model;
|
|
1254
|
+
const fresh = current && session.modelRuntime.getModel(current.provider, current.id);
|
|
1255
|
+
if (fresh && fresh !== current) session.agent.state.model = fresh;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* 共享目录刷新后,给正在用这个模型的会话换上新模型对象(上下文窗口等字段跟着变),再推一次用量让圆环当场更新。
|
|
1260
|
+
* 运行中的会话也换:SDK 在扩展注册 provider 时同样会中途替换 agent.state.model,已发出的请求不受影响。
|
|
1261
|
+
*/
|
|
1262
|
+
export function refreshSessionModels(provider: string, id: string): number {
|
|
1263
|
+
let n = 0;
|
|
1264
|
+
for (const m of sessions.values()) {
|
|
1265
|
+
const current = m.session?.model;
|
|
1266
|
+
if (!m.session || current?.provider !== provider || current.id !== id) continue;
|
|
1267
|
+
swapCurrentModelObject(m.session);
|
|
1268
|
+
publishUsage(m);
|
|
1269
|
+
n += 1;
|
|
1270
|
+
}
|
|
1271
|
+
return n;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1225
1274
|
export async function reloadSessionsForCwd(cwd?: string): Promise<number> {
|
|
1226
1275
|
const key = (p: string) => (process.platform === "win32" ? p.replace(/\\/g, "/").toLowerCase() : p.replace(/\\/g, "/"));
|
|
1227
1276
|
let n = 0;
|
|
@@ -1325,42 +1374,13 @@ export async function buildSnapshot(m: Managed): Promise<WebSnapshot> {
|
|
|
1325
1374
|
const usage = session.getContextUsage() ?? null;
|
|
1326
1375
|
contextUsage = usage ? { tokens: usage.tokens, contextWindow: usage.contextWindow, percent: usage.percent } : null;
|
|
1327
1376
|
} else if (model) {
|
|
1328
|
-
//
|
|
1329
|
-
// 上下文规模)除以模型窗口估算,避免上下文计量永远显示 0% / —
|
|
1377
|
+
// 冷会话也使用当前分支投影,包含最后一次 API 用量之后的用户消息和工具输出。
|
|
1330
1378
|
try {
|
|
1331
1379
|
const rt = await getModelRuntime();
|
|
1332
1380
|
const modelMeta = (rt.getModels(model.provider) as any[]).find((x) => String(x.id) === model.id);
|
|
1333
|
-
|
|
1334
|
-
let lastTurnTokens = 0;
|
|
1335
|
-
// 与 SDK getContextUsage 同一条规则:最近一次压缩之后还没有新的助手回复时,上下文大小未知(不能拿压缩前的用量充数)
|
|
1336
|
-
const entries = m.sm.getEntries() as Array<{ type?: string; message?: { role?: string; stopReason?: string } }>;
|
|
1337
|
-
let compactedSinceLastAssistant = false;
|
|
1338
|
-
for (let i = entries.length - 1; i >= 0; i--) {
|
|
1339
|
-
const e = entries[i];
|
|
1340
|
-
if (e.type === "compaction" || e.type === "branch_summary") {
|
|
1341
|
-
compactedSinceLastAssistant = true;
|
|
1342
|
-
break;
|
|
1343
|
-
}
|
|
1344
|
-
if (e.type === "message" && e.message?.role === "assistant" && e.message.stopReason !== "error" && e.message.stopReason !== "aborted") break;
|
|
1345
|
-
}
|
|
1346
|
-
for (let i = messages.length - 1; i >= 0 && !compactedSinceLastAssistant; i--) {
|
|
1347
|
-
const msg = messages[i];
|
|
1348
|
-
if (msg.role === "assistant" && msg.usage) {
|
|
1349
|
-
lastTurnTokens =
|
|
1350
|
-
Number(msg.usage.input ?? 0) +
|
|
1351
|
-
Number(msg.usage.cacheRead ?? 0) +
|
|
1352
|
-
Number(msg.usage.cacheWrite ?? 0) +
|
|
1353
|
-
Number(msg.usage.output ?? 0);
|
|
1354
|
-
break;
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
if (window > 0 && lastTurnTokens > 0) {
|
|
1358
|
-
contextUsage = { tokens: lastTurnTokens, contextWindow: window, percent: (lastTurnTokens / window) * 100 };
|
|
1359
|
-
} else if (window > 0) {
|
|
1360
|
-
contextUsage = { tokens: null, contextWindow: window, percent: null };
|
|
1361
|
-
}
|
|
1381
|
+
contextUsage = projectedContextUsage(m.sm.buildSessionProjection(), m.sm.getBranch(), Number(modelMeta?.contextWindow ?? 0));
|
|
1362
1382
|
} catch {
|
|
1363
|
-
/*
|
|
1383
|
+
/* 模型或投影不可用时用量未知。 */
|
|
1364
1384
|
}
|
|
1365
1385
|
}
|
|
1366
1386
|
|
|
@@ -1600,6 +1620,8 @@ export async function execute(m: Managed, cmd: AgentCommand): Promise<CommandRes
|
|
|
1600
1620
|
if (!model) return { ok: false, error: `unknown model ${cmd.provider}/${cmd.modelId}` };
|
|
1601
1621
|
await session.setModel(model, { persist: false });
|
|
1602
1622
|
reapplyDesiredLevel(m, session);
|
|
1623
|
+
// 新会话页选的模型(fresh):思考档位按新会话的规则定;之后显式选的档位仍会覆盖
|
|
1624
|
+
if (cmd.fresh === true && !m.desiredThinkingLevel) applyNewSessionThinking(m, session);
|
|
1603
1625
|
publishModelState(m, session);
|
|
1604
1626
|
return { ok: true, data: { thinkingLevel: session.thinkingLevel, thinkingLevels: session.getAvailableThinkingLevels() } };
|
|
1605
1627
|
}
|
|
@@ -1712,8 +1734,17 @@ export async function execute(m: Managed, cmd: AgentCommand): Promise<CommandRes
|
|
|
1712
1734
|
}
|
|
1713
1735
|
case "reload": {
|
|
1714
1736
|
if (isManagedBusy(m)) return { ok: false, error: "session is busy" };
|
|
1737
|
+
// /reload:先就地刷新共享的模型目录(models.json / auth.json 可能是手改的);其它会话手里的
|
|
1738
|
+
// 模型对象跟着换新,忙着的等本轮结束再换;本会话重载资源后再换一次
|
|
1739
|
+
await refreshModelRuntime();
|
|
1740
|
+
for (const other of sessions.values()) {
|
|
1741
|
+
if (other === m || !other.session) continue;
|
|
1742
|
+
if (isManagedBusy(other)) other.resourceReloadPending = true;
|
|
1743
|
+
else swapCurrentModelObject(other.session);
|
|
1744
|
+
}
|
|
1715
1745
|
const session = await ensureSession(m);
|
|
1716
1746
|
await session.reload();
|
|
1747
|
+
swapCurrentModelObject(session);
|
|
1717
1748
|
return { ok: true };
|
|
1718
1749
|
}
|
|
1719
1750
|
case "fork": {
|