@xopcai/xopc 0.0.140 → 0.0.142
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DtONoxBN.js → agent-avatar-dicebear-BawPxiu5.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CyvCIHnB.js +2 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BRBxLECY.js → app-management-settings-panel-81xd1p9R.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-ChvyuSEt.js → appearance-settings-DYeQsYU8.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-DgHWTnjs.js → apps-page-DK_Vx6nl.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-CdIoagem.js → archive-plugin-D_oa7oti.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-Ch411Kht.js → attachment-load-Cd-bwI2N.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-SVq27yw2.js → automation-suggestion-card-B1LV3YYv.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-fzrovqhv.js +4 -0
- package/dist/gateway/static/root/assets/{binary-plugins-D8cV-emn.js → binary-plugins-O8svLKWw.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CXDkby6y.js → block-editor-Dhj5f4Bx.js} +47 -47
- package/dist/gateway/static/root/assets/browser-settings-page-BDn-n-UB.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-DLxI--Ge.js → capability-presets-api-dJy1Eqgx.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-DKyRbnlH.js → capability-presets-settings-panel-Co5ipo_Q.js} +1 -1
- package/dist/gateway/static/root/assets/{channel-recipient-api-DllrPmp-.js → channel-recipient-api-Bfuhp2ty.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BWlpaxg9.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-D_jkIZLV.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-BcekbW4q.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-Bz9ommjr.js → desktop-pet-DFMfIb5F.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BnLgxgoR.js → desktop-pet-settings-BJCUuL8Y.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-DLsCwFaf.js → directory-picker-path-field-BrYt1gAr.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-BzkF1-XT.js → dreaming-settings-BN1Z2mIo.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-CdERvf3L.js → extension-debug-page-Bh630pLD.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-D1fz474Z.js → extension-page-B-1KxvVy.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DoQMkNOK.js → extension-settings-page-BF9NACI3.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-BID89uCH.js → fetch-B1WtuprY.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-Rygo8UAs.js → gateway-config-api-De2N821l.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-kb8KIeQL.js → gateway-settings-DN9sNREz.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BkrLLlpE.js → gateway-startup-retry-nEujFSDj.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-BpoQW8cD.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-CBRSPd0b.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-BuY6-l0a.js → goals-config-api-DUy3eEse.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BCcBi407.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DoH5fZWo.js → goals-settings-pkTXzXkh.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BqDs48B-.js → heartbeat-settings-ezsufgLQ.js} +1 -1
- package/dist/gateway/static/root/assets/{index-CrPRlGMg.js → index-DcUaXYeb.js} +65 -65
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CVIwwM15.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-DQtTRXtj.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-CSt32FWE.js → markdown-split-B_6us9j7.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-ByItHxBj.js → media-plugins-D_fryIyj.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BXNELNBa.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-BP2M9n6Q.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-CspveYaO.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-BHwzJ0OC.js +2 -0
- package/dist/gateway/static/root/assets/{page-tabs-DOfMaq_L.js → page-tabs-D_8jGlqx.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BArxASu7.js → preview-open-alternatives-BBLMK8Mp.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-Dy3rsobs.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-CWKpPE0L.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CqNRyXEo.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BRxlkhG8.js → save-bar-controls-DVS3FR5r.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-BzM1iyOc.js → schedule-field-D6vKd6-T.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-ChVcm0DX.js → schema-form-BPy4lbIh.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-MEME7ivF.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-JVd0qaSF.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-BcD9xrvY.js → settings-collapsible-section-WzdikxPt.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Cu30CXVl.js → settings-form-section-CvfzhBV-.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-Cfd37IYb.js → settings-loading-skeleton-BxR-Ulhi.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-EINHyzLo.js → settings-page-DYEbB1EV.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-C15zixct.js → settings-page-layout-CKefvbYi.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-Bu7SdpD4.js → setup-status-panel-dWN8BJ3z.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CjjAFV-v.js → share-preview-page-D8foINzP.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-Tgbv1s7G.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-D_YK0b_Z.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DGytfoZK.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-DlQMtzPf.js → system-settings-panel-BokgAgf7.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-BS1BwExE.js → typed-models-lib-BwHlNL3L.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-EA4hfbsP.js → use-channel-catalog-DR11ap3A.js} +1 -1
- package/dist/gateway/static/root/assets/{user-profile-settings-panel-B7RCdmSp.js → user-profile-settings-panel-8YtygcJp.js} +1 -1
- package/dist/gateway/static/root/assets/{utils-BrhEgVaa.js → utils-BKUWB-TT.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BVH71EFf.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-JeTE7XNM.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-CL_rnAUB.js +3 -0
- package/dist/gateway/static/root/assets/{workflow-start-dialog-BZCY7N42.js → workflow-start-dialog-_u8Uc1ze.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-ixgk_y1l.js +18 -0
- package/dist/gateway/static/root/index.html +4 -4
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +13 -21
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/run-background-review.js +1 -0
- package/dist/src/agent/background-review/run-background-review.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.js +5 -5
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/xopc-auth-storage.d.ts +4 -3
- package/dist/src/agent/embedded/xopc-auth-storage.js +6 -6
- package/dist/src/agent/embedded/xopc-auth-storage.js.map +1 -1
- package/dist/src/agent/embedded/xopc-stream-bridge.js +1 -0
- package/dist/src/agent/embedded/xopc-stream-bridge.js.map +1 -1
- package/dist/src/agent/goals/checklist-judge.js +3 -3
- package/dist/src/agent/goals/checklist-judge.js.map +1 -1
- package/dist/src/agent/goals/judge.js +2 -2
- package/dist/src/agent/goals/judge.js.map +1 -1
- package/dist/src/agent/image/understanding/pi-ai-provider.js +2 -2
- package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
- package/dist/src/agent/memory/access-policy.d.ts +12 -0
- package/dist/src/agent/memory/access-policy.js +44 -0
- package/dist/src/agent/memory/access-policy.js.map +1 -0
- package/dist/src/agent/memory/builtin-provider.d.ts +4 -1
- package/dist/src/agent/memory/builtin-provider.js +51 -16
- package/dist/src/agent/memory/builtin-provider.js.map +1 -1
- package/dist/src/agent/memory/compaction.js +2 -2
- package/dist/src/agent/memory/compaction.js.map +1 -1
- package/dist/src/agent/memory/context/planner.d.ts +1 -0
- package/dist/src/agent/memory/context/planner.js +9 -5
- package/dist/src/agent/memory/context/planner.js.map +1 -1
- package/dist/src/agent/memory/create-memory-manager.d.ts +1 -1
- package/dist/src/agent/memory/create-memory-manager.js +8 -5
- package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
- package/dist/src/agent/memory/dreaming/config.d.ts +2 -0
- package/dist/src/agent/memory/dreaming/config.js +13 -1
- package/dist/src/agent/memory/dreaming/config.js.map +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +2 -0
- package/dist/src/agent/memory/dreaming/deep-promotion.js +24 -3
- package/dist/src/agent/memory/dreaming/deep-promotion.js.map +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.d.ts +1 -0
- package/dist/src/agent/memory/dreaming/light-sweep.js +184 -16
- package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
- package/dist/src/agent/memory/dreaming/promotion-lifecycle.d.ts +30 -0
- package/dist/src/agent/memory/dreaming/promotion-lifecycle.js +85 -0
- package/dist/src/agent/memory/dreaming/promotion-lifecycle.js.map +1 -0
- package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +4 -0
- package/dist/src/agent/memory/dreaming/rem-patterns.js +76 -53
- package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.d.ts +10 -0
- package/dist/src/agent/memory/dreaming/short-term-store.js +157 -79
- package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
- package/dist/src/agent/memory/manager.d.ts +7 -0
- package/dist/src/agent/memory/manager.js +31 -6
- package/dist/src/agent/memory/manager.js.map +1 -1
- package/dist/src/agent/memory/memory-config.d.ts +1 -1
- package/dist/src/agent/memory/memory-config.js +3 -3
- package/dist/src/agent/memory/memory-config.js.map +1 -1
- package/dist/src/agent/memory/sensitivity.d.ts +3 -0
- package/dist/src/agent/memory/sensitivity.js +13 -0
- package/dist/src/agent/memory/sensitivity.js.map +1 -0
- package/dist/src/agent/memory/understanding/service.js +10 -14
- package/dist/src/agent/memory/understanding/service.js.map +1 -1
- package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -0
- package/dist/src/agent/memory/user-context-coordinator.js +2 -0
- package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js +8 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/service/btw-query.d.ts +4 -0
- package/dist/src/agent/service/btw-query.js +94 -13
- package/dist/src/agent/service/btw-query.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +9 -1
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +3 -12
- package/dist/src/agent/tools/dreaming-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.js +14 -2
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/memory-tool.d.ts +3 -0
- package/dist/src/agent/tools/memory-tool.js +6 -3
- package/dist/src/agent/tools/memory-tool.js.map +1 -1
- package/dist/src/agent/tools/session-search-tool.js +2 -2
- package/dist/src/agent/tools/session-search-tool.js.map +1 -1
- package/dist/src/agent/tools/web-extract.js +2 -2
- package/dist/src/agent/tools/web-extract.js.map +1 -1
- package/dist/src/agent/workspace-runtime/registry.d.ts +6 -6
- package/dist/src/agent/workspace-runtime/registry.js +19 -12
- package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
- package/dist/src/agent-manifest/schema.d.ts +4 -0
- package/dist/src/agent-manifest/schema.js +2 -1
- package/dist/src/agent-manifest/schema.js.map +1 -1
- package/dist/src/agent-runtime/index.js +1 -1
- package/dist/src/agent-runtime/runtime-profile.js +1 -1
- package/dist/src/ai-assist/text-assist.d.ts +2 -1
- package/dist/src/ai-assist/text-assist.js +10 -23
- package/dist/src/ai-assist/text-assist.js.map +1 -1
- package/dist/src/auth/credentials.js +5 -2
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/oauth/github-copilot.d.ts +3 -4
- package/dist/src/auth/oauth/github-copilot.js +66 -2
- package/dist/src/auth/oauth/github-copilot.js.map +1 -0
- package/dist/src/auth/oauth/index.js +2 -2
- package/dist/src/automations/draft/automation-draft-service.js +3 -3
- package/dist/src/automations/draft/automation-draft-service.js.map +1 -1
- package/dist/src/chat-commands/builtins/review.js +22 -5
- package/dist/src/chat-commands/builtins/review.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +4 -0
- package/dist/src/config/schema.d.ts +4 -0
- package/dist/src/gateway/hono/lib/config-payload.d.ts +2 -0
- package/dist/src/gateway/hono/routes/dreaming.js +28 -21
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/memory.js +16 -4
- package/dist/src/gateway/hono/routes/memory.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -0
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +2 -2
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/goals/goal-contract-draft.js +2 -2
- package/dist/src/goals/goal-contract-draft.js.map +1 -1
- package/dist/src/goals/goal-evidence-review.js +2 -2
- package/dist/src/goals/goal-evidence-review.js.map +1 -1
- package/dist/src/notes/service.js +2 -2
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/providers/constants.d.ts +2 -0
- package/dist/src/providers/constants.js +11 -0
- package/dist/src/providers/constants.js.map +1 -0
- package/dist/src/providers/extension-stream-bridge.js +1 -0
- package/dist/src/providers/extension-stream-bridge.js.map +1 -1
- package/dist/src/providers/index.d.ts +3 -3
- package/dist/src/providers/index.js +5 -4
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/model-call.d.ts +17 -0
- package/dist/src/providers/model-call.js +60 -0
- package/dist/src/providers/model-call.js.map +1 -0
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/storage/sqlite/fts.d.ts +6 -0
- package/dist/src/storage/sqlite/fts.js +70 -1
- package/dist/src/storage/sqlite/fts.js.map +1 -1
- package/dist/src/storage/sqlite/memory-index-repository.js +16 -7
- package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
- package/dist/src/storage/sqlite/memory-records-repository.d.ts +18 -0
- package/dist/src/storage/sqlite/memory-records-repository.js +55 -8
- package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
- package/dist/src/voice/tts/summarize.js +2 -2
- package/dist/src/voice/tts/summarize.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-service.js +2 -2
- package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -1
- package/package.json +5 -5
- package/dist/gateway/static/root/assets/agents-Dl9EWnUh.js +0 -2
- package/dist/gateway/static/root/assets/automations-page-CFt5Ik4q.js +0 -4
- package/dist/gateway/static/root/assets/browser-settings-page-ColJPwer.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-BDLHV3Jx.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-EUwWYx8l.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CA752gY8.js +0 -2
- package/dist/gateway/static/root/assets/goal-create-dialog-DVAHnifk.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-BuOEQZn_.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-WV4cHvD-.js +0 -2
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-D51yogNZ.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-CL22jleU.js +0 -7
- package/dist/gateway/static/root/assets/messages-DbNQuFdA.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-BkV9hDc-.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-BK9yydrL.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-Dd0v-hK2.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-DSPhB3do.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-C-fZk1f7.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BGaVc3t7.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DbnzgQOP.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CuDBoz5k.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-06IYvwDt.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-0ODH0DXl.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-3W2-wDyO.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-BPn1ZEga.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-BQGTTsz1.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-na-N4jZ6.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-CjeVDs4h.js +0 -18
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export { githubCopilotOAuthProvider, getGitHubCopilotBaseUrl, loginGitHubCopilot, normalizeDomain, refreshGitHubCopilotToken, } from '@earendil-works/pi-ai/oauth';
|
|
1
|
+
/** GitHub Copilot OAuth adapter for pi-ai's provider-auth API. */
|
|
2
|
+
import type { OAuthProviderInterface } from './types.js';
|
|
3
|
+
export declare const githubCopilotOAuthProvider: OAuthProviderInterface;
|
|
@@ -1,2 +1,66 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { githubCopilotProvider } from "@earendil-works/pi-ai/providers/github-copilot";
|
|
2
|
+
//#region src/auth/oauth/github-copilot.ts
|
|
3
|
+
/** GitHub Copilot OAuth adapter for pi-ai's provider-auth API. */
|
|
4
|
+
function getCopilotOAuth() {
|
|
5
|
+
const oauth = githubCopilotProvider().auth.oauth;
|
|
6
|
+
if (!oauth) throw new Error("GitHub Copilot OAuth is unavailable");
|
|
7
|
+
return oauth;
|
|
8
|
+
}
|
|
9
|
+
function toPiCredential(credentials) {
|
|
10
|
+
return {
|
|
11
|
+
...credentials,
|
|
12
|
+
type: "oauth"
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function fromPiCredential({ type: _type, ...credentials }) {
|
|
16
|
+
return credentials;
|
|
17
|
+
}
|
|
18
|
+
function toAuthInteraction(callbacks) {
|
|
19
|
+
return {
|
|
20
|
+
signal: callbacks.signal,
|
|
21
|
+
async prompt(prompt) {
|
|
22
|
+
if (prompt.type === "select") return await callbacks.onSelect({
|
|
23
|
+
message: prompt.message,
|
|
24
|
+
options: [...prompt.options].map(({ id, label }) => ({
|
|
25
|
+
id,
|
|
26
|
+
label
|
|
27
|
+
}))
|
|
28
|
+
}) ?? "";
|
|
29
|
+
return callbacks.onPrompt({
|
|
30
|
+
message: prompt.message,
|
|
31
|
+
placeholder: prompt.placeholder
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
notify(event) {
|
|
35
|
+
if (event.type === "auth_url") callbacks.onAuth({
|
|
36
|
+
url: event.url,
|
|
37
|
+
instructions: event.instructions
|
|
38
|
+
});
|
|
39
|
+
else if (event.type === "device_code") callbacks.onDeviceCode({
|
|
40
|
+
userCode: event.userCode,
|
|
41
|
+
verificationUri: event.verificationUri,
|
|
42
|
+
intervalSeconds: event.intervalSeconds,
|
|
43
|
+
expiresInSeconds: event.expiresInSeconds
|
|
44
|
+
});
|
|
45
|
+
else if (event.type === "progress" || event.type === "info") callbacks.onProgress?.(event.message);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const githubCopilotOAuthProvider = {
|
|
50
|
+
id: "github-copilot",
|
|
51
|
+
name: "GitHub Copilot",
|
|
52
|
+
usesCallbackServer: false,
|
|
53
|
+
async login(callbacks) {
|
|
54
|
+
return fromPiCredential(await getCopilotOAuth().login(toAuthInteraction(callbacks)));
|
|
55
|
+
},
|
|
56
|
+
async refreshToken(credentials) {
|
|
57
|
+
return fromPiCredential(await getCopilotOAuth().refresh(toPiCredential(credentials)));
|
|
58
|
+
},
|
|
59
|
+
getApiKey(credentials) {
|
|
60
|
+
return credentials.access;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
export { githubCopilotOAuthProvider };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=github-copilot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-copilot.js","names":[],"sources":["../../../../src/auth/oauth/github-copilot.ts"],"sourcesContent":["/** GitHub Copilot OAuth adapter for pi-ai's provider-auth API. */\n\nimport { githubCopilotProvider } from '@earendil-works/pi-ai/providers/github-copilot';\nimport type { AuthInteraction, OAuthAuth, OAuthCredential } from '@earendil-works/pi-ai';\n\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from './types.js';\n\nfunction getCopilotOAuth(): OAuthAuth {\n const oauth = githubCopilotProvider().auth.oauth;\n if (!oauth) {\n throw new Error('GitHub Copilot OAuth is unavailable');\n }\n return oauth;\n}\n\nfunction toPiCredential(credentials: OAuthCredentials): OAuthCredential {\n return { ...credentials, type: 'oauth' };\n}\n\nfunction fromPiCredential({ type: _type, ...credentials }: OAuthCredential): OAuthCredentials {\n return credentials;\n}\n\nfunction toAuthInteraction(callbacks: OAuthLoginCallbacks): AuthInteraction {\n return {\n signal: callbacks.signal,\n async prompt(prompt) {\n if (prompt.type === 'select') {\n return (await callbacks.onSelect({\n message: prompt.message,\n options: [...prompt.options].map(({ id, label }) => ({ id, label })),\n })) ?? '';\n }\n return callbacks.onPrompt({\n message: prompt.message,\n placeholder: prompt.placeholder,\n });\n },\n notify(event) {\n if (event.type === 'auth_url') {\n callbacks.onAuth({ url: event.url, instructions: event.instructions });\n } else if (event.type === 'device_code') {\n callbacks.onDeviceCode({\n userCode: event.userCode,\n verificationUri: event.verificationUri,\n intervalSeconds: event.intervalSeconds,\n expiresInSeconds: event.expiresInSeconds,\n });\n } else if (event.type === 'progress' || event.type === 'info') {\n callbacks.onProgress?.(event.message);\n }\n },\n };\n}\n\nexport const githubCopilotOAuthProvider: OAuthProviderInterface = {\n id: 'github-copilot',\n name: 'GitHub Copilot',\n usesCallbackServer: false,\n async login(callbacks) {\n return fromPiCredential(await getCopilotOAuth().login(toAuthInteraction(callbacks)));\n },\n async refreshToken(credentials) {\n return fromPiCredential(await getCopilotOAuth().refresh(toPiCredential(credentials)));\n },\n getApiKey(credentials) {\n return credentials.access;\n },\n};\n"],"mappings":";;;AAOA,SAAS,kBAA6B;CACpC,MAAM,QAAQ,uBAAuB,CAAC,KAAK;AAC3C,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,sCAAsC;AAExD,QAAO;;AAGT,SAAS,eAAe,aAAgD;AACtE,QAAO;EAAE,GAAG;EAAa,MAAM;EAAS;;AAG1C,SAAS,iBAAiB,EAAE,MAAM,OAAO,GAAG,eAAkD;AAC5F,QAAO;;AAGT,SAAS,kBAAkB,WAAiD;AAC1E,QAAO;EACL,QAAQ,UAAU;EAClB,MAAM,OAAO,QAAQ;AACnB,OAAI,OAAO,SAAS,SAClB,QAAQ,MAAM,UAAU,SAAS;IAC/B,SAAS,OAAO;IAChB,SAAS,CAAC,GAAG,OAAO,QAAQ,CAAC,KAAK,EAAE,IAAI,aAAa;KAAE;KAAI;KAAO,EAAE;IACrE,CAAC,IAAK;AAET,UAAO,UAAU,SAAS;IACxB,SAAS,OAAO;IAChB,aAAa,OAAO;IACrB,CAAC;;EAEJ,OAAO,OAAO;AACZ,OAAI,MAAM,SAAS,WACjB,WAAU,OAAO;IAAE,KAAK,MAAM;IAAK,cAAc,MAAM;IAAc,CAAC;YAC7D,MAAM,SAAS,cACxB,WAAU,aAAa;IACrB,UAAU,MAAM;IAChB,iBAAiB,MAAM;IACvB,iBAAiB,MAAM;IACvB,kBAAkB,MAAM;IACzB,CAAC;YACO,MAAM,SAAS,cAAc,MAAM,SAAS,OACrD,WAAU,aAAa,MAAM,QAAQ;;EAG1C;;AAGH,MAAa,6BAAqD;CAChE,IAAI;CACJ,MAAM;CACN,oBAAoB;CACpB,MAAM,MAAM,WAAW;AACrB,SAAO,iBAAiB,MAAM,iBAAiB,CAAC,MAAM,kBAAkB,UAAU,CAAC,CAAC;;CAEtF,MAAM,aAAa,aAAa;AAC9B,SAAO,iBAAiB,MAAM,iBAAiB,CAAC,QAAQ,eAAe,YAAY,CAAC,CAAC;;CAEvF,UAAU,aAAa;AACrB,SAAO,YAAY;;CAEtB"}
|
|
@@ -2,10 +2,10 @@ import { anthropicOAuthProvider, loginAnthropic, refreshAnthropicToken } from ".
|
|
|
2
2
|
import { minimaxOAuthProvider } from "./minimax.js";
|
|
3
3
|
import { minimaxCnOAuthProvider } from "./minimax-cn.js";
|
|
4
4
|
import { kimiCodingOAuthProvider } from "./kimi-coding.js";
|
|
5
|
-
import {
|
|
5
|
+
import { githubCopilotOAuthProvider } from "./github-copilot.js";
|
|
6
6
|
import { geminiCliOAuthProvider, loginGeminiCli, refreshGoogleCloudToken } from "./google-oauth/google-gemini-cli.js";
|
|
7
7
|
import "./google-gemini-cli.js";
|
|
8
8
|
import { antigravityOAuthProvider, loginAntigravity, refreshAntigravityToken } from "./google-oauth/google-antigravity.js";
|
|
9
9
|
import "./google-antigravity.js";
|
|
10
10
|
import { loginOpenAICodex, openaiCodexOAuthProvider, refreshOpenAICodexToken } from "./openai-codex.js";
|
|
11
|
-
export { anthropicOAuthProvider,
|
|
11
|
+
export { anthropicOAuthProvider, githubCopilotOAuthProvider, antigravityOAuthProvider as googleAntigravityOAuthProvider, geminiCliOAuthProvider as googleGeminiCliOAuthProvider, kimiCodingOAuthProvider, loginAnthropic, loginAntigravity, loginGeminiCli, loginOpenAICodex, minimaxCnOAuthProvider, minimaxOAuthProvider, openaiCodexOAuthProvider, refreshAnthropicToken, refreshAntigravityToken, refreshGoogleCloudToken, refreshOpenAICodexToken };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
4
|
+
import { completeWithResolvedCredentials } from "../../providers/model-call.js";
|
|
4
5
|
import { resolveDraftModelRef } from "../../workflows/draft/workflow-draft-service.js";
|
|
5
6
|
import { buildAutomationDraftPrompt, buildAutomationDraftRepairPrompt, buildAutomationRunRepairPrompt, buildAutomationRunRepairRetryPrompt } from "./automation-draft-prompt.js";
|
|
6
7
|
import { buildAutomationDraftResponse, parseGeneratedAutomationDraft, parseGeneratedAutomationRepairDraft } from "./automation-draft-validator.js";
|
|
7
|
-
import { complete } from "@earendil-works/pi-ai/compat";
|
|
8
8
|
//#region src/automations/draft/automation-draft-service.ts
|
|
9
9
|
init_providers();
|
|
10
10
|
init_logger();
|
|
@@ -27,7 +27,7 @@ var AutomationDraftService = class {
|
|
|
27
27
|
let lastText = "";
|
|
28
28
|
let lastIssues = [];
|
|
29
29
|
for (let attempt = 0; attempt <= maxRepairAttempts; attempt += 1) {
|
|
30
|
-
lastText = extractText(await
|
|
30
|
+
lastText = extractText(await completeWithResolvedCredentials(model, { messages: [{
|
|
31
31
|
role: "user",
|
|
32
32
|
content: messageContent,
|
|
33
33
|
timestamp: Date.now()
|
|
@@ -80,7 +80,7 @@ var AutomationDraftService = class {
|
|
|
80
80
|
let lastText = "";
|
|
81
81
|
let lastIssues = [];
|
|
82
82
|
for (let attempt = 0; attempt <= maxRepairAttempts; attempt += 1) {
|
|
83
|
-
lastText = extractText(await
|
|
83
|
+
lastText = extractText(await completeWithResolvedCredentials(model, { messages: [{
|
|
84
84
|
role: "user",
|
|
85
85
|
content: messageContent,
|
|
86
86
|
timestamp: Date.now()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automation-draft-service.js","names":[],"sources":["../../../../src/automations/draft/automation-draft-service.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"automation-draft-service.js","names":[],"sources":["../../../../src/automations/draft/automation-draft-service.ts"],"sourcesContent":["import { type UserMessage } from '@earendil-works/pi-ai/compat';\n\nimport type { Config } from '../../config/schema.js';\nimport { resolveModel } from '../../providers/index.js';\nimport { completeWithResolvedCredentials } from '../../providers/model-call.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { resolveDraftModelRef } from '../../workflows/draft/workflow-draft-service.js';\nimport {\n buildAutomationDraftPrompt,\n buildAutomationDraftRepairPrompt,\n buildAutomationRunRepairPrompt,\n buildAutomationRunRepairRetryPrompt,\n type AutomationDraftRepairIssue,\n} from './automation-draft-prompt.js';\nimport type {\n AutomationDraftResponse,\n AutomationRepairDraftResponse,\n CreateAutomationDraftRequest,\n CreateAutomationRepairDraftRequest,\n} from './automation-draft.types.js';\nimport {\n buildAutomationDraftResponse,\n parseGeneratedAutomationDraft,\n parseGeneratedAutomationRepairDraft,\n} from './automation-draft-validator.js';\n\nconst log = createLogger('AutomationDraft');\nconst DEFAULT_MAX_REPAIR_ATTEMPTS = 2;\n\nexport interface AutomationDraftServiceOptions {\n config: Config;\n maxRepairAttempts?: number;\n}\n\nexport class AutomationDraftService {\n constructor(private readonly options: AutomationDraftServiceOptions) {}\n\n async createDraft(request: CreateAutomationDraftRequest, signal?: AbortSignal): Promise<AutomationDraftResponse> {\n const prompt = request.prompt.trim();\n if (!prompt) throw new Error('prompt is required');\n\n const modelRef = resolveDraftModelRef(this.options.config, request.agentId);\n const model = resolveModel(modelRef);\n const maxRepairAttempts = this.options.maxRepairAttempts ?? DEFAULT_MAX_REPAIR_ATTEMPTS;\n let messageContent = buildAutomationDraftPrompt({ prompt, language: request.language });\n let lastText = '';\n let lastIssues: AutomationDraftRepairIssue[] = [];\n\n for (let attempt = 0; attempt <= maxRepairAttempts; attempt += 1) {\n const userMsg: UserMessage = {\n role: 'user',\n content: messageContent,\n timestamp: Date.now(),\n };\n const result = await completeWithResolvedCredentials(\n model,\n { messages: [userMsg] },\n { maxTokens: 2048, temperature: attempt === 0 ? 0.2 : 0.1, signal },\n );\n lastText = extractText(result);\n try {\n const draft = parseGeneratedAutomationDraft(lastText);\n return buildAutomationDraftResponse(draft, attempt);\n } catch (err) {\n lastIssues = [{\n source: 'validation',\n severity: 'error',\n message: err instanceof Error ? err.message : String(err),\n }];\n }\n\n if (attempt >= maxRepairAttempts) break;\n log.warn(\n { modelRef, attempt: attempt + 1, issueCount: lastIssues.length, preview: lastText.slice(0, 500) },\n 'Automation draft validation failed; asking model to repair',\n );\n messageContent = buildAutomationDraftRepairPrompt({\n prompt,\n language: request.language,\n previousOutput: lastText,\n issues: lastIssues,\n });\n }\n\n const message = `Unable to generate a valid automation draft after ${maxRepairAttempts + 1} attempts`;\n log.warn({ modelRef, issues: lastIssues, preview: lastText.slice(0, 500) }, message);\n throw new Error(message);\n }\n\n async createRepairDraft(\n request: CreateAutomationRepairDraftRequest,\n signal?: AbortSignal,\n ): Promise<AutomationRepairDraftResponse> {\n const modelRef = resolveDraftModelRef(this.options.config, request.agentId);\n const model = resolveModel(modelRef);\n const maxRepairAttempts = this.options.maxRepairAttempts ?? DEFAULT_MAX_REPAIR_ATTEMPTS;\n let messageContent = buildAutomationRunRepairPrompt({\n language: request.language,\n automation: request.automation,\n run: request.run,\n events: request.events,\n });\n let lastText = '';\n let lastIssues: AutomationDraftRepairIssue[] = [];\n\n for (let attempt = 0; attempt <= maxRepairAttempts; attempt += 1) {\n const userMsg: UserMessage = {\n role: 'user',\n content: messageContent,\n timestamp: Date.now(),\n };\n const result = await completeWithResolvedCredentials(\n model,\n { messages: [userMsg] },\n { maxTokens: 2048, temperature: attempt === 0 ? 0.15 : 0.05, signal },\n );\n lastText = extractText(result);\n try {\n return parseGeneratedAutomationRepairDraft(lastText, attempt);\n } catch (err) {\n lastIssues = [{\n source: 'validation',\n severity: 'error',\n message: err instanceof Error ? err.message : String(err),\n }];\n }\n\n if (attempt >= maxRepairAttempts) break;\n log.warn(\n { modelRef, attempt: attempt + 1, issueCount: lastIssues.length, preview: lastText.slice(0, 500) },\n 'Automation repair draft validation failed; asking model to repair',\n );\n messageContent = buildAutomationRunRepairRetryPrompt({\n language: request.language,\n previousOutput: lastText,\n issues: lastIssues,\n });\n }\n\n const message = `Unable to generate a valid automation repair draft after ${maxRepairAttempts + 1} attempts`;\n log.warn({ modelRef, issues: lastIssues, preview: lastText.slice(0, 500) }, message);\n throw new Error(message);\n }\n}\n\nfunction extractText(result: unknown): string {\n const content = (result as { content?: unknown }).content;\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content.map((item) => {\n if (item && typeof item === 'object' && (item as { type?: string }).type === 'text') {\n return String((item as { text?: string }).text ?? '');\n }\n return '';\n }).join('');\n }\n return '';\n}\n"],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { formatReviewMarkdown } from "../../review/review-types.js";
|
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
8
8
|
//#region src/chat-commands/builtins/review.ts
|
|
9
9
|
const MAX_DIFF_CHARS = 6e4;
|
|
10
|
-
const REVIEW_JUDGE_MAX_TOKENS =
|
|
10
|
+
const REVIEW_JUDGE_MAX_TOKENS = 16384;
|
|
11
11
|
async function emitToolStart(ctx, toolCallId, toolName, args) {
|
|
12
12
|
await ctx.emitEvent?.({
|
|
13
13
|
type: "tool_execution_start",
|
|
@@ -31,6 +31,19 @@ async function emitToolEnd(ctx, toolCallId, toolName, resultText, details, isErr
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
+
async function emitToolTextDelta(ctx, toolCallId, toolName, delta) {
|
|
35
|
+
if (!delta) return;
|
|
36
|
+
await ctx.emitEvent?.({
|
|
37
|
+
type: "tool_execution_update",
|
|
38
|
+
toolCallId,
|
|
39
|
+
toolName,
|
|
40
|
+
args: {},
|
|
41
|
+
partialResult: { content: [{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: delta
|
|
44
|
+
}] }
|
|
45
|
+
});
|
|
46
|
+
}
|
|
34
47
|
function truncateForPrompt(text) {
|
|
35
48
|
if (text.length <= MAX_DIFF_CHARS) return {
|
|
36
49
|
text,
|
|
@@ -102,9 +115,12 @@ function previewText(text, max = 500) {
|
|
|
102
115
|
const trimmed = text.trim();
|
|
103
116
|
return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;
|
|
104
117
|
}
|
|
105
|
-
function
|
|
118
|
+
async function reviewModelRef(ctx) {
|
|
119
|
+
const sessionOverride = await ctx.getSessionConfigStore?.()?.get(ctx.sessionKey).then((config) => config?.modelOverride?.trim()).catch(() => void 0);
|
|
120
|
+
if (sessionOverride) return sessionOverride;
|
|
106
121
|
try {
|
|
107
|
-
|
|
122
|
+
const profile = resolveEffectiveAgentProfileForSession(ctx.config, ctx.sessionKey);
|
|
123
|
+
return profile.manifest.models.roles.review?.model?.trim() || profile.primaryModelRef;
|
|
108
124
|
} catch {
|
|
109
125
|
return;
|
|
110
126
|
}
|
|
@@ -174,7 +190,7 @@ async function buildReview(ctx, args) {
|
|
|
174
190
|
truncated,
|
|
175
191
|
instructions
|
|
176
192
|
});
|
|
177
|
-
const reviewerModelRef =
|
|
193
|
+
const reviewerModelRef = await reviewModelRef(ctx);
|
|
178
194
|
const judgeToolCallId = `review_judge_${randomUUID()}`;
|
|
179
195
|
await emitToolStart(ctx, judgeToolCallId, "review.model_judge", {
|
|
180
196
|
target,
|
|
@@ -184,7 +200,8 @@ async function buildReview(ctx, args) {
|
|
|
184
200
|
});
|
|
185
201
|
const answer = ctx.btwQuery ? await ctx.btwQuery(prompt, {
|
|
186
202
|
maxTokens: REVIEW_JUDGE_MAX_TOKENS,
|
|
187
|
-
|
|
203
|
+
includeSessionContext: false,
|
|
204
|
+
onTextDelta: (delta) => emitToolTextDelta(ctx, judgeToolCallId, "review.model_judge", delta),
|
|
188
205
|
...reviewerModelRef ? { modelRef: reviewerModelRef } : {}
|
|
189
206
|
}) : {
|
|
190
207
|
text: "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.js","names":[],"sources":["../../../../src/chat-commands/builtins/review.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { CommandDefinition, CommandContext } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { effectiveWorkspacePathForSession } from '../../session/session-workspace.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport { getProjectForSession } from '../../projects/workspace.js';\nimport {\n buildReviewDiffBundle,\n parseReviewTargetArgs,\n resolveGitRoot,\n} from '../../review/review-git.js';\nimport {\n formatReviewMarkdown,\n type ReviewFinding,\n type ReviewOutput,\n type ReviewPriority,\n} from '../../review/review-types.js';\n\nconst MAX_DIFF_CHARS = 60_000;\nconst REVIEW_JUDGE_MAX_TOKENS = 8_192;\n\nasync function emitToolStart(\n ctx: CommandContext,\n toolCallId: string,\n toolName: string,\n args: Record<string, unknown>,\n): Promise<void> {\n await ctx.emitEvent?.({\n type: 'tool_execution_start',\n toolCallId,\n toolName,\n args,\n });\n}\n\nasync function emitToolEnd(\n ctx: CommandContext,\n toolCallId: string,\n toolName: string,\n resultText: string,\n details?: Record<string, unknown>,\n isError = false,\n): Promise<void> {\n await ctx.emitEvent?.({\n type: 'tool_execution_end',\n toolCallId,\n toolName,\n isError,\n result: {\n content: [{ type: 'text', text: resultText }],\n ...(details ? { details } : {}),\n },\n });\n}\n\nfunction truncateForPrompt(text: string): { text: string; truncated: boolean } {\n if (text.length <= MAX_DIFF_CHARS) return { text, truncated: false };\n return {\n text: text.slice(0, MAX_DIFF_CHARS) + '\\n\\n[diff truncated]',\n truncated: true,\n };\n}\n\nfunction extractJsonObject(raw: string): unknown {\n const fenced = raw.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n const text = (fenced?.[1] ?? raw).trim();\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start < 0 || end <= start) throw new Error('review response did not contain JSON');\n return JSON.parse(text.slice(start, end + 1));\n}\n\nfunction priorityFrom(raw: unknown): ReviewPriority {\n const n = typeof raw === 'number' ? raw : Number.parseInt(String(raw ?? ''), 10);\n if (n === 0 || n === 1 || n === 2 || n === 3) return n;\n return 2;\n}\n\nfunction numberFrom(raw: unknown): number | undefined {\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\nfunction stringFrom(raw: unknown): string {\n return typeof raw === 'string' ? raw.trim() : '';\n}\n\nfunction parseReviewJson(raw: string, target: string): ReviewOutput {\n const parsed = extractJsonObject(raw);\n const rec = parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? parsed as Record<string, unknown>\n : {};\n const rawFindings = Array.isArray(rec.findings) ? rec.findings : [];\n const findings: ReviewFinding[] = rawFindings\n .map((item) => {\n const f = item && typeof item === 'object' && !Array.isArray(item)\n ? item as Record<string, unknown>\n : {};\n const loc = f.code_location && typeof f.code_location === 'object'\n ? f.code_location as Record<string, unknown>\n : {};\n const range = loc.line_range && typeof loc.line_range === 'object'\n ? loc.line_range as Record<string, unknown>\n : {};\n const title = stringFrom(f.title);\n const body = stringFrom(f.body);\n if (!title && !body) return undefined;\n const finding: ReviewFinding = {\n title: title || body.slice(0, 80),\n body,\n priority: priorityFrom(f.priority),\n };\n const confidenceScore = numberFrom(f.confidence_score ?? f.confidenceScore);\n const filePath = stringFrom(loc.file_path ?? f.filePath);\n const lineStart = numberFrom(range.start ?? f.lineStart);\n const lineEnd = numberFrom(range.end ?? f.lineEnd);\n if (confidenceScore !== undefined) finding.confidenceScore = confidenceScore;\n if (filePath) finding.filePath = filePath;\n if (lineStart !== undefined) finding.lineStart = lineStart;\n if (lineEnd !== undefined) finding.lineEnd = lineEnd;\n return finding;\n })\n .filter((item): item is ReviewFinding => Boolean(item));\n\n const correctness = stringFrom(rec.overall_correctness ?? rec.overallCorrectness);\n const overallCorrectness =\n correctness === 'patch is correct' || correctness === 'patch is incorrect'\n ? correctness\n : 'unknown';\n return {\n type: 'review',\n target,\n summary: stringFrom(rec.summary) || `${findings.length} finding${findings.length === 1 ? '' : 's'}`,\n findings,\n overallCorrectness,\n overallExplanation: stringFrom(rec.overall_explanation ?? rec.overallExplanation),\n overallConfidenceScore: numberFrom(rec.overall_confidence_score ?? rec.overallConfidenceScore),\n generatedAt: Date.now(),\n source: 'model',\n };\n}\n\nfunction previewText(text: string, max = 500): string {\n const trimmed = text.trim();\n return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;\n}\n\nfunction reviewDefaultModelRef(ctx: CommandContext): string | undefined {\n try {\n return resolveEffectiveAgentProfileForSession(ctx.config, ctx.sessionKey).primaryModelRef;\n } catch {\n return undefined;\n }\n}\n\nfunction buildReviewPrompt(params: {\n target: string;\n status: string;\n stat: string;\n diff: string;\n truncated: boolean;\n instructions: string;\n}): string {\n return [\n 'You are a senior code reviewer. Review the provided git diff for correctness bugs only.',\n 'Prioritize concrete regressions, broken behavior, missing required tests for changed behavior, data loss, security issues, and runtime/type errors.',\n 'Do not mention style, broad refactors, praise, or speculative improvements.',\n 'Return strict JSON only with this shape:',\n '{\"findings\":[{\"title\":\"...\",\"body\":\"...\",\"priority\":1,\"confidence_score\":0.9,\"code_location\":{\"file_path\":\"path\",\"line_range\":{\"start\":12,\"end\":12}}}],\"overall_correctness\":\"patch is correct\",\"overall_explanation\":\"...\",\"overall_confidence_score\":0.8,\"summary\":\"...\"}',\n 'Use priority 0 for release-blocking, 1 for high, 2 for medium, 3 for low.',\n params.instructions ? `Extra reviewer instructions: ${params.instructions}` : '',\n `Target: ${params.target}`,\n params.truncated ? 'The diff was truncated; only report findings supported by visible lines.' : '',\n 'Git status:',\n params.status || '(clean)',\n 'Diff stat:',\n params.stat || '(none)',\n 'Diff:',\n params.diff || '(none)',\n ].filter(Boolean).join('\\n\\n');\n}\n\nasync function resolveWorkspace(ctx: CommandContext): Promise<string> {\n const sessionConfigStore = ctx.getSessionConfigStore?.();\n const sessionConfig = sessionConfigStore\n ? await sessionConfigStore.get(ctx.sessionKey).catch(() => null)\n : null;\n return effectiveWorkspacePathForSession(\n ctx.config,\n ctx.sessionKey,\n sessionConfig,\n getProjectForSession(ctx.sessionKey),\n );\n}\n\nasync function buildReview(ctx: CommandContext, args: string): Promise<ReviewOutput> {\n const workspace = await resolveWorkspace(ctx);\n const cwd = await resolveGitRoot(workspace);\n const reviewTarget = parseReviewTargetArgs(args);\n const prepareToolCallId = `review_prepare_${randomUUID()}`;\n await emitToolStart(ctx, prepareToolCallId, 'review.prepare_diff', {\n target: args.trim() || 'uncommitted',\n cwd,\n });\n let bundle: Awaited<ReturnType<typeof buildReviewDiffBundle>>;\n try {\n bundle = await buildReviewDiffBundle(cwd, reviewTarget);\n await emitToolEnd(\n ctx,\n prepareToolCallId,\n 'review.prepare_diff',\n [\n `Target: ${bundle.targetLabel}`,\n bundle.stat.trim() ? `Changed files:\\n${bundle.stat.trim()}` : 'No diff stat.',\n ].join('\\n\\n'),\n {\n target: bundle.targetLabel,\n status: bundle.status,\n stat: bundle.stat,\n },\n );\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n await emitToolEnd(ctx, prepareToolCallId, 'review.prepare_diff', em, { cwd }, true);\n throw err;\n }\n const { text: diff, truncated } = truncateForPrompt(bundle.diff);\n const target = bundle.targetLabel;\n const instructions = reviewTarget.instructions ?? '';\n\n if (!bundle.status.trim() && !bundle.diff.trim()) {\n return {\n type: 'review',\n target,\n summary: 'Working tree is clean.',\n findings: [],\n overallCorrectness: 'patch is correct',\n overallExplanation: 'No uncommitted changes were found to review.',\n generatedAt: Date.now(),\n source: 'local',\n };\n }\n\n const prompt = buildReviewPrompt({\n target,\n status: bundle.status,\n stat: bundle.stat,\n diff,\n truncated,\n instructions,\n });\n const reviewerModelRef = reviewDefaultModelRef(ctx);\n const judgeToolCallId = `review_judge_${randomUUID()}`;\n await emitToolStart(ctx, judgeToolCallId, 'review.model_judge', {\n target,\n diffChars: diff.length,\n truncated,\n ...(reviewerModelRef ? { modelRef: reviewerModelRef } : {}),\n });\n const answer = ctx.btwQuery\n ? await ctx.btwQuery(prompt, {\n maxTokens: REVIEW_JUDGE_MAX_TOKENS,\n temperature: 0.1,\n ...(reviewerModelRef ? { modelRef: reviewerModelRef } : {}),\n })\n : { text: '', error: 'Review model query is not available in this command context.' };\n let judgeFailure = answer.error\n ? { reason: `Reviewer model error: ${answer.error}` }\n : answer.text\n ? undefined\n : { reason: 'Reviewer model returned no text.' };\n if (answer?.text && !answer.error) {\n try {\n const parsed = parseReviewJson(answer.text, target);\n await emitToolEnd(\n ctx,\n judgeToolCallId,\n 'review.model_judge',\n parsed.summary || `${parsed.findings.length} findings`,\n {\n target,\n findings: parsed.findings.length,\n overallCorrectness: parsed.overallCorrectness,\n },\n );\n return parsed;\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n judgeFailure = {\n reason: `Reviewer model output could not be parsed: ${em}`,\n };\n }\n }\n\n const reason = judgeFailure?.reason ?? 'Reviewer model output could not be parsed.';\n const fallback: ReviewOutput = {\n type: 'review',\n target,\n summary: 'Review model did not complete; returned a local diff summary.',\n findings: [],\n overallCorrectness: 'unknown',\n overallExplanation: [\n reason,\n bundle.stat.trim() ? `Changed files:\\n${bundle.stat.trim()}` : 'No textual diff stat was available.',\n ].join('\\n\\n'),\n generatedAt: Date.now(),\n source: 'local',\n };\n await emitToolEnd(\n ctx,\n judgeToolCallId,\n 'review.model_judge',\n fallback.summary,\n {\n target,\n findings: 0,\n overallCorrectness: fallback.overallCorrectness,\n fallback: true,\n reason,\n ...(answer.text ? { responsePreview: previewText(answer.text) } : {}),\n },\n true,\n );\n return fallback;\n}\n\nconst reviewCommand: CommandDefinition = {\n id: 'coding.review',\n name: 'review',\n description: 'Review current workspace changes for correctness issues',\n category: 'tool',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/review', '/review focus on auth and persistence'],\n handler: async (ctx: CommandContext, args: string) => {\n await ctx.setTyping(true);\n const review = await buildReview(ctx, args);\n return {\n content: formatReviewMarkdown(review),\n success: true,\n metadata: { review },\n };\n },\n};\n\nexport function registerReviewCommand(): void {\n commandRegistry.register(reviewCommand);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"review.js","names":[],"sources":["../../../../src/chat-commands/builtins/review.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type { CommandDefinition, CommandContext } from '../types.js';\nimport { commandRegistry } from '../registry.js';\nimport { effectiveWorkspacePathForSession } from '../../session/session-workspace.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport { getProjectForSession } from '../../projects/workspace.js';\nimport {\n buildReviewDiffBundle,\n parseReviewTargetArgs,\n resolveGitRoot,\n} from '../../review/review-git.js';\nimport {\n formatReviewMarkdown,\n type ReviewFinding,\n type ReviewOutput,\n type ReviewPriority,\n} from '../../review/review-types.js';\n\nconst MAX_DIFF_CHARS = 60_000;\nconst REVIEW_JUDGE_MAX_TOKENS = 16_384;\n\nasync function emitToolStart(\n ctx: CommandContext,\n toolCallId: string,\n toolName: string,\n args: Record<string, unknown>,\n): Promise<void> {\n await ctx.emitEvent?.({\n type: 'tool_execution_start',\n toolCallId,\n toolName,\n args,\n });\n}\n\nasync function emitToolEnd(\n ctx: CommandContext,\n toolCallId: string,\n toolName: string,\n resultText: string,\n details?: Record<string, unknown>,\n isError = false,\n): Promise<void> {\n await ctx.emitEvent?.({\n type: 'tool_execution_end',\n toolCallId,\n toolName,\n isError,\n result: {\n content: [{ type: 'text', text: resultText }],\n ...(details ? { details } : {}),\n },\n });\n}\n\nasync function emitToolTextDelta(\n ctx: CommandContext,\n toolCallId: string,\n toolName: string,\n delta: string,\n): Promise<void> {\n if (!delta) return;\n await ctx.emitEvent?.({\n type: 'tool_execution_update',\n toolCallId,\n toolName,\n args: {},\n partialResult: {\n content: [{ type: 'text', text: delta }],\n },\n });\n}\n\nfunction truncateForPrompt(text: string): { text: string; truncated: boolean } {\n if (text.length <= MAX_DIFF_CHARS) return { text, truncated: false };\n return {\n text: text.slice(0, MAX_DIFF_CHARS) + '\\n\\n[diff truncated]',\n truncated: true,\n };\n}\n\nfunction extractJsonObject(raw: string): unknown {\n const fenced = raw.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n const text = (fenced?.[1] ?? raw).trim();\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start < 0 || end <= start) throw new Error('review response did not contain JSON');\n return JSON.parse(text.slice(start, end + 1));\n}\n\nfunction priorityFrom(raw: unknown): ReviewPriority {\n const n = typeof raw === 'number' ? raw : Number.parseInt(String(raw ?? ''), 10);\n if (n === 0 || n === 1 || n === 2 || n === 3) return n;\n return 2;\n}\n\nfunction numberFrom(raw: unknown): number | undefined {\n return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;\n}\n\nfunction stringFrom(raw: unknown): string {\n return typeof raw === 'string' ? raw.trim() : '';\n}\n\nfunction parseReviewJson(raw: string, target: string): ReviewOutput {\n const parsed = extractJsonObject(raw);\n const rec = parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? parsed as Record<string, unknown>\n : {};\n const rawFindings = Array.isArray(rec.findings) ? rec.findings : [];\n const findings: ReviewFinding[] = rawFindings\n .map((item) => {\n const f = item && typeof item === 'object' && !Array.isArray(item)\n ? item as Record<string, unknown>\n : {};\n const loc = f.code_location && typeof f.code_location === 'object'\n ? f.code_location as Record<string, unknown>\n : {};\n const range = loc.line_range && typeof loc.line_range === 'object'\n ? loc.line_range as Record<string, unknown>\n : {};\n const title = stringFrom(f.title);\n const body = stringFrom(f.body);\n if (!title && !body) return undefined;\n const finding: ReviewFinding = {\n title: title || body.slice(0, 80),\n body,\n priority: priorityFrom(f.priority),\n };\n const confidenceScore = numberFrom(f.confidence_score ?? f.confidenceScore);\n const filePath = stringFrom(loc.file_path ?? f.filePath);\n const lineStart = numberFrom(range.start ?? f.lineStart);\n const lineEnd = numberFrom(range.end ?? f.lineEnd);\n if (confidenceScore !== undefined) finding.confidenceScore = confidenceScore;\n if (filePath) finding.filePath = filePath;\n if (lineStart !== undefined) finding.lineStart = lineStart;\n if (lineEnd !== undefined) finding.lineEnd = lineEnd;\n return finding;\n })\n .filter((item): item is ReviewFinding => Boolean(item));\n\n const correctness = stringFrom(rec.overall_correctness ?? rec.overallCorrectness);\n const overallCorrectness =\n correctness === 'patch is correct' || correctness === 'patch is incorrect'\n ? correctness\n : 'unknown';\n return {\n type: 'review',\n target,\n summary: stringFrom(rec.summary) || `${findings.length} finding${findings.length === 1 ? '' : 's'}`,\n findings,\n overallCorrectness,\n overallExplanation: stringFrom(rec.overall_explanation ?? rec.overallExplanation),\n overallConfidenceScore: numberFrom(rec.overall_confidence_score ?? rec.overallConfidenceScore),\n generatedAt: Date.now(),\n source: 'model',\n };\n}\n\nfunction previewText(text: string, max = 500): string {\n const trimmed = text.trim();\n return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;\n}\n\nasync function reviewModelRef(ctx: CommandContext): Promise<string | undefined> {\n const sessionOverride = await ctx.getSessionConfigStore?.()\n ?.get(ctx.sessionKey)\n .then((config) => config?.modelOverride?.trim())\n .catch(() => undefined);\n if (sessionOverride) return sessionOverride;\n\n try {\n const profile = resolveEffectiveAgentProfileForSession(ctx.config, ctx.sessionKey);\n return profile.manifest.models.roles.review?.model?.trim() || profile.primaryModelRef;\n } catch {\n return undefined;\n }\n}\n\nfunction buildReviewPrompt(params: {\n target: string;\n status: string;\n stat: string;\n diff: string;\n truncated: boolean;\n instructions: string;\n}): string {\n return [\n 'You are a senior code reviewer. Review the provided git diff for correctness bugs only.',\n 'Prioritize concrete regressions, broken behavior, missing required tests for changed behavior, data loss, security issues, and runtime/type errors.',\n 'Do not mention style, broad refactors, praise, or speculative improvements.',\n 'Return strict JSON only with this shape:',\n '{\"findings\":[{\"title\":\"...\",\"body\":\"...\",\"priority\":1,\"confidence_score\":0.9,\"code_location\":{\"file_path\":\"path\",\"line_range\":{\"start\":12,\"end\":12}}}],\"overall_correctness\":\"patch is correct\",\"overall_explanation\":\"...\",\"overall_confidence_score\":0.8,\"summary\":\"...\"}',\n 'Use priority 0 for release-blocking, 1 for high, 2 for medium, 3 for low.',\n params.instructions ? `Extra reviewer instructions: ${params.instructions}` : '',\n `Target: ${params.target}`,\n params.truncated ? 'The diff was truncated; only report findings supported by visible lines.' : '',\n 'Git status:',\n params.status || '(clean)',\n 'Diff stat:',\n params.stat || '(none)',\n 'Diff:',\n params.diff || '(none)',\n ].filter(Boolean).join('\\n\\n');\n}\n\nasync function resolveWorkspace(ctx: CommandContext): Promise<string> {\n const sessionConfigStore = ctx.getSessionConfigStore?.();\n const sessionConfig = sessionConfigStore\n ? await sessionConfigStore.get(ctx.sessionKey).catch(() => null)\n : null;\n return effectiveWorkspacePathForSession(\n ctx.config,\n ctx.sessionKey,\n sessionConfig,\n getProjectForSession(ctx.sessionKey),\n );\n}\n\nasync function buildReview(ctx: CommandContext, args: string): Promise<ReviewOutput> {\n const workspace = await resolveWorkspace(ctx);\n const cwd = await resolveGitRoot(workspace);\n const reviewTarget = parseReviewTargetArgs(args);\n const prepareToolCallId = `review_prepare_${randomUUID()}`;\n await emitToolStart(ctx, prepareToolCallId, 'review.prepare_diff', {\n target: args.trim() || 'uncommitted',\n cwd,\n });\n let bundle: Awaited<ReturnType<typeof buildReviewDiffBundle>>;\n try {\n bundle = await buildReviewDiffBundle(cwd, reviewTarget);\n await emitToolEnd(\n ctx,\n prepareToolCallId,\n 'review.prepare_diff',\n [\n `Target: ${bundle.targetLabel}`,\n bundle.stat.trim() ? `Changed files:\\n${bundle.stat.trim()}` : 'No diff stat.',\n ].join('\\n\\n'),\n {\n target: bundle.targetLabel,\n status: bundle.status,\n stat: bundle.stat,\n },\n );\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n await emitToolEnd(ctx, prepareToolCallId, 'review.prepare_diff', em, { cwd }, true);\n throw err;\n }\n const { text: diff, truncated } = truncateForPrompt(bundle.diff);\n const target = bundle.targetLabel;\n const instructions = reviewTarget.instructions ?? '';\n\n if (!bundle.status.trim() && !bundle.diff.trim()) {\n return {\n type: 'review',\n target,\n summary: 'Working tree is clean.',\n findings: [],\n overallCorrectness: 'patch is correct',\n overallExplanation: 'No uncommitted changes were found to review.',\n generatedAt: Date.now(),\n source: 'local',\n };\n }\n\n const prompt = buildReviewPrompt({\n target,\n status: bundle.status,\n stat: bundle.stat,\n diff,\n truncated,\n instructions,\n });\n const reviewerModelRef = await reviewModelRef(ctx);\n const judgeToolCallId = `review_judge_${randomUUID()}`;\n await emitToolStart(ctx, judgeToolCallId, 'review.model_judge', {\n target,\n diffChars: diff.length,\n truncated,\n ...(reviewerModelRef ? { modelRef: reviewerModelRef } : {}),\n });\n const answer = ctx.btwQuery\n ? await ctx.btwQuery(prompt, {\n maxTokens: REVIEW_JUDGE_MAX_TOKENS,\n includeSessionContext: false,\n onTextDelta: (delta) => emitToolTextDelta(ctx, judgeToolCallId, 'review.model_judge', delta),\n ...(reviewerModelRef ? { modelRef: reviewerModelRef } : {}),\n })\n : { text: '', error: 'Review model query is not available in this command context.' };\n let judgeFailure = answer.error\n ? { reason: `Reviewer model error: ${answer.error}` }\n : answer.text\n ? undefined\n : { reason: 'Reviewer model returned no text.' };\n if (answer?.text && !answer.error) {\n try {\n const parsed = parseReviewJson(answer.text, target);\n await emitToolEnd(\n ctx,\n judgeToolCallId,\n 'review.model_judge',\n parsed.summary || `${parsed.findings.length} findings`,\n {\n target,\n findings: parsed.findings.length,\n overallCorrectness: parsed.overallCorrectness,\n },\n );\n return parsed;\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n judgeFailure = {\n reason: `Reviewer model output could not be parsed: ${em}`,\n };\n }\n }\n\n const reason = judgeFailure?.reason ?? 'Reviewer model output could not be parsed.';\n const fallback: ReviewOutput = {\n type: 'review',\n target,\n summary: 'Review model did not complete; returned a local diff summary.',\n findings: [],\n overallCorrectness: 'unknown',\n overallExplanation: [\n reason,\n bundle.stat.trim() ? `Changed files:\\n${bundle.stat.trim()}` : 'No textual diff stat was available.',\n ].join('\\n\\n'),\n generatedAt: Date.now(),\n source: 'local',\n };\n await emitToolEnd(\n ctx,\n judgeToolCallId,\n 'review.model_judge',\n fallback.summary,\n {\n target,\n findings: 0,\n overallCorrectness: fallback.overallCorrectness,\n fallback: true,\n reason,\n ...(answer.text ? { responsePreview: previewText(answer.text) } : {}),\n },\n true,\n );\n return fallback;\n}\n\nconst reviewCommand: CommandDefinition = {\n id: 'coding.review',\n name: 'review',\n description: 'Review current workspace changes for correctness issues',\n category: 'tool',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/review', '/review focus on auth and persistence'],\n handler: async (ctx: CommandContext, args: string) => {\n await ctx.setTyping(true);\n const review = await buildReview(ctx, args);\n return {\n content: formatReviewMarkdown(review),\n success: true,\n metadata: { review },\n };\n },\n};\n\nexport function registerReviewCommand(): void {\n commandRegistry.register(reviewCommand);\n}\n"],"mappings":"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"}
|
|
@@ -112,6 +112,10 @@ export type BtwQueryOptions = {
|
|
|
112
112
|
maxTokens?: number;
|
|
113
113
|
temperature?: number;
|
|
114
114
|
modelRef?: string;
|
|
115
|
+
/** Run as an isolated one-shot task instead of adding recent session history. */
|
|
116
|
+
includeSessionContext?: boolean;
|
|
117
|
+
/** Receives visible model text as it arrives for rich command surfaces. */
|
|
118
|
+
onTextDelta?: (delta: string) => void | Promise<void>;
|
|
115
119
|
};
|
|
116
120
|
export interface CommandContext {
|
|
117
121
|
/** Unified session key */
|
|
@@ -188,6 +188,7 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
188
188
|
compaction: z.ZodDefault<z.ZodBoolean>;
|
|
189
189
|
maxAgeDays: z.ZodOptional<z.ZodNumber>;
|
|
190
190
|
maxItems: z.ZodOptional<z.ZodNumber>;
|
|
191
|
+
maxChars: z.ZodOptional<z.ZodNumber>;
|
|
191
192
|
}, z.core.$strict>>;
|
|
192
193
|
privacy: z.ZodOptional<z.ZodObject<{
|
|
193
194
|
crossAgentSharing: z.ZodDefault<z.ZodEnum<{
|
|
@@ -422,6 +423,7 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
422
423
|
compaction: z.ZodDefault<z.ZodBoolean>;
|
|
423
424
|
maxAgeDays: z.ZodOptional<z.ZodNumber>;
|
|
424
425
|
maxItems: z.ZodOptional<z.ZodNumber>;
|
|
426
|
+
maxChars: z.ZodOptional<z.ZodNumber>;
|
|
425
427
|
}, z.core.$strict>>;
|
|
426
428
|
privacy: z.ZodOptional<z.ZodObject<{
|
|
427
429
|
crossAgentSharing: z.ZodDefault<z.ZodEnum<{
|
|
@@ -1876,6 +1878,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
1876
1878
|
compaction: z.ZodDefault<z.ZodBoolean>;
|
|
1877
1879
|
maxAgeDays: z.ZodOptional<z.ZodNumber>;
|
|
1878
1880
|
maxItems: z.ZodOptional<z.ZodNumber>;
|
|
1881
|
+
maxChars: z.ZodOptional<z.ZodNumber>;
|
|
1879
1882
|
}, z.core.$strict>>;
|
|
1880
1883
|
privacy: z.ZodOptional<z.ZodObject<{
|
|
1881
1884
|
crossAgentSharing: z.ZodDefault<z.ZodEnum<{
|
|
@@ -2110,6 +2113,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
2110
2113
|
compaction: z.ZodDefault<z.ZodBoolean>;
|
|
2111
2114
|
maxAgeDays: z.ZodOptional<z.ZodNumber>;
|
|
2112
2115
|
maxItems: z.ZodOptional<z.ZodNumber>;
|
|
2116
|
+
maxChars: z.ZodOptional<z.ZodNumber>;
|
|
2113
2117
|
}, z.core.$strict>>;
|
|
2114
2118
|
privacy: z.ZodOptional<z.ZodObject<{
|
|
2115
2119
|
crossAgentSharing: z.ZodDefault<z.ZodEnum<{
|
|
@@ -110,6 +110,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
|
|
|
110
110
|
compaction: boolean;
|
|
111
111
|
maxAgeDays?: number;
|
|
112
112
|
maxItems?: number;
|
|
113
|
+
maxChars?: number;
|
|
113
114
|
};
|
|
114
115
|
privacy?: {
|
|
115
116
|
crossAgentSharing: "allow" | "deny" | "readOnly";
|
|
@@ -251,6 +252,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
|
|
|
251
252
|
compaction: boolean;
|
|
252
253
|
maxAgeDays?: number;
|
|
253
254
|
maxItems?: number;
|
|
255
|
+
maxChars?: number;
|
|
254
256
|
};
|
|
255
257
|
privacy?: {
|
|
256
258
|
crossAgentSharing: "allow" | "deny" | "readOnly";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { init_agent_scope, normalizeAgentId, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
|
|
2
2
|
import { DREAMING_DIR_RELATIVE, DREAMING_LAST_RUN_RELATIVE, SHORT_TERM_PROMOTION_LOCK_RELATIVE, SHORT_TERM_RECALL_STORE_RELATIVE } from "../../../agent/memory/dreaming/constants.js";
|
|
3
|
-
import { loadDreamingStore,
|
|
3
|
+
import { clearStaleDreamingLock, loadDreamingStore, resetDreamingStore } from "../../../agent/memory/dreaming/short-term-store.js";
|
|
4
4
|
import { resolveDreamingAgentScope } from "../../../agent/memory/dreaming/scope.js";
|
|
5
5
|
import { parseDreamingLastRunFile } from "../../../agent/memory/dreaming/last-run.js";
|
|
6
6
|
import { runDreamingDeepPromotion } from "../../../agent/memory/dreaming/deep-promotion.js";
|
|
@@ -207,15 +207,22 @@ function registerDreamingRoutes(authenticated, deps) {
|
|
|
207
207
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
208
208
|
});
|
|
209
209
|
const result = requestedPhase === "light" ? await runLightSweep({
|
|
210
|
+
workspaceDir: scope.workspaceDir,
|
|
210
211
|
dreamingRoot: scope.memoriesDir,
|
|
211
212
|
config: dreaming.phases.light
|
|
212
213
|
}) : requestedPhase === "rem" ? await runRemPatterns({
|
|
214
|
+
agentId: scope.agentId,
|
|
215
|
+
workspaceDir: scope.workspaceDir,
|
|
213
216
|
dreamingRoot: scope.memoriesDir,
|
|
214
|
-
config: dreaming.phases.rem
|
|
217
|
+
config: dreaming.phases.rem,
|
|
218
|
+
sensitiveWritePolicy: scope.memory.privacy?.sensitiveWritePolicy,
|
|
219
|
+
promotionWritePolicy: dreaming.promotionWritePolicy.decision
|
|
215
220
|
}) : await runDreamingDeepPromotion({
|
|
221
|
+
agentId: scope.agentId,
|
|
216
222
|
workspaceDir: scope.workspaceDir,
|
|
217
223
|
dreamingRoot: scope.memoriesDir,
|
|
218
|
-
config: dreaming.phases.deep
|
|
224
|
+
config: dreaming.phases.deep,
|
|
225
|
+
sensitiveWritePolicy: scope.memory.privacy?.sensitiveWritePolicy
|
|
219
226
|
});
|
|
220
227
|
service.emit("dreaming.phase.end", {
|
|
221
228
|
agentId: scope.agentId,
|
|
@@ -270,15 +277,7 @@ function registerDreamingRoutes(authenticated, deps) {
|
|
|
270
277
|
error: { message: "Invalid action" }
|
|
271
278
|
}, 400);
|
|
272
279
|
if (action === "reset_store") {
|
|
273
|
-
|
|
274
|
-
version: 1,
|
|
275
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
276
|
-
entries: {}
|
|
277
|
-
};
|
|
278
|
-
await saveDreamingStore({
|
|
279
|
-
dreamingRoot: scope.memoriesDir,
|
|
280
|
-
store: next
|
|
281
|
-
});
|
|
280
|
+
await resetDreamingStore({ dreamingRoot: scope.memoriesDir });
|
|
282
281
|
return c.json({
|
|
283
282
|
ok: true,
|
|
284
283
|
payload: {
|
|
@@ -289,15 +288,23 @@ function registerDreamingRoutes(authenticated, deps) {
|
|
|
289
288
|
});
|
|
290
289
|
}
|
|
291
290
|
const lockPath = path.join(scope.memoriesDir, SHORT_TERM_PROMOTION_LOCK_RELATIVE);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
291
|
+
try {
|
|
292
|
+
const cleared = await clearStaleDreamingLock(scope.memoriesDir);
|
|
293
|
+
return c.json({
|
|
294
|
+
ok: true,
|
|
295
|
+
payload: {
|
|
296
|
+
agentId: scope.agentId,
|
|
297
|
+
cleared,
|
|
298
|
+
lockPath
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
} catch (err) {
|
|
302
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
303
|
+
return c.json({
|
|
304
|
+
ok: false,
|
|
305
|
+
error: { message }
|
|
306
|
+
}, 409);
|
|
307
|
+
}
|
|
301
308
|
});
|
|
302
309
|
authenticated.get("/api/dreaming/events", async (c) => {
|
|
303
310
|
const cfg = service.currentConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dreaming.js","names":[],"sources":["../../../../../src/gateway/hono/routes/dreaming.ts"],"sourcesContent":["import type { Hono } from 'hono';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { type Config } from '../../../config/schema.js';\nimport { normalizeAgentId, resolveDefaultAgentId } from '../../../agent/agent-scope.js';\nimport {\n DREAMING_DIR_RELATIVE,\n DREAMING_LAST_RUN_RELATIVE,\n SHORT_TERM_PROMOTION_LOCK_RELATIVE,\n SHORT_TERM_RECALL_STORE_RELATIVE,\n type DreamingPhaseId,\n} from '../../../agent/memory/dreaming/constants.js';\nimport { readDreamingEvents } from '../../../agent/memory/dreaming/events.js';\nimport { previewDreamingDeepPromotion } from '../../../agent/memory/dreaming/preview.js';\nimport { runLightSweep } from '../../../agent/memory/dreaming/light-sweep.js';\nimport { runDreamingDeepPromotion } from '../../../agent/memory/dreaming/deep-promotion.js';\nimport { runRemPatterns } from '../../../agent/memory/dreaming/rem-patterns.js';\nimport { parseDreamingLastRunFile, type DreamingDeepLastRun } from '../../../agent/memory/dreaming/last-run.js';\nimport { resolveDreamingAgentScope, type DreamingAgentScope } from '../../../agent/memory/dreaming/scope.js';\nimport {\n loadDreamingStore,\n saveDreamingStore,\n type DreamingStore,\n} from '../../../agent/memory/dreaming/short-term-store.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction requestedAgentIdFrom(c: { req: { query(name: string): string | undefined } }, body?: unknown): string | undefined {\n const fromBody = isRecord(body) && typeof body.agentId === 'string' ? body.agentId : undefined;\n return fromBody ?? c.req.query('agentId');\n}\n\nfunction hasEnabledAgent(cfg: Config, agentId: string): boolean {\n const normalized = normalizeAgentId(agentId);\n return cfg.agents.list.some((agent) => agent.enabled !== false && normalizeAgentId(agent.id) === normalized);\n}\n\nfunction resolveRouteScope(cfg: Config, requestedAgentId?: string): DreamingAgentScope {\n const agentId = normalizeAgentId(requestedAgentId || resolveDefaultAgentId(cfg));\n if (!hasEnabledAgent(cfg, agentId)) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n return resolveDreamingAgentScope(cfg, agentId);\n}\n\nasync function readLockInfo(dreamingRoot: string): Promise<\n | { locked: false }\n | { locked: true; path: string; content: string; mtimeMs?: number }\n> {\n const lockPath = path.join(dreamingRoot, SHORT_TERM_PROMOTION_LOCK_RELATIVE);\n try {\n const [content, st] = await Promise.all([fs.readFile(lockPath, 'utf-8'), fs.stat(lockPath)]);\n return {\n locked: true,\n path: SHORT_TERM_PROMOTION_LOCK_RELATIVE,\n content: content.trim(),\n mtimeMs: st.mtimeMs,\n };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return { locked: false };\n return { locked: true, path: SHORT_TERM_PROMOTION_LOCK_RELATIVE, content: 'unknown', mtimeMs: undefined };\n }\n}\n\nasync function readLastRun(\n dreamingRoot: string,\n): Promise<\n | { exists: false }\n | {\n exists: true;\n path: string;\n raw: unknown;\n record: DreamingDeepLastRun | null;\n parseError: string | null;\n }\n> {\n const fullPath = path.join(dreamingRoot, DREAMING_LAST_RUN_RELATIVE);\n try {\n const text = await fs.readFile(fullPath, 'utf-8');\n let raw: unknown;\n try {\n raw = JSON.parse(text) as unknown;\n } catch (parseErr) {\n return {\n exists: true,\n path: DREAMING_LAST_RUN_RELATIVE,\n raw: null,\n record: null,\n parseError: parseErr instanceof Error ? parseErr.message : String(parseErr),\n };\n }\n const record = parseDreamingLastRunFile(raw);\n return {\n exists: true,\n path: DREAMING_LAST_RUN_RELATIVE,\n raw,\n record,\n parseError: record ? null : 'Invalid or unsupported last-run.json (expected v2 deep record).',\n };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return { exists: false };\n return {\n exists: true,\n path: DREAMING_LAST_RUN_RELATIVE,\n raw: null,\n record: null,\n parseError: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nasync function readPhaseLastRun(\n dreamingRoot: string,\n filename: string,\n): Promise<{ exists: false } | { exists: true; path: string; raw: unknown }> {\n const relPath = path.join(DREAMING_DIR_RELATIVE, filename);\n const fullPath = path.join(dreamingRoot, relPath);\n try {\n const text = await fs.readFile(fullPath, 'utf-8');\n const raw = JSON.parse(text) as unknown;\n return { exists: true, path: relPath, raw };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return { exists: false };\n return { exists: false };\n }\n}\n\nfunction storeStats(store: DreamingStore): {\n version: number;\n updatedAt: string;\n entryCount: number;\n promotedCount: number;\n lastPromotedAt: string | null;\n} {\n const entries = Object.values(store.entries ?? {});\n const promoted = entries.filter((e) => typeof e.promotedAt === 'string' && e.promotedAt.trim());\n const lastPromotedAt = promoted\n .map((e) => e.promotedAt!)\n .sort((a, b) => (a < b ? 1 : a > b ? -1 : 0))[0];\n return {\n version: store.version,\n updatedAt: store.updatedAt,\n entryCount: entries.length,\n promotedCount: promoted.length,\n lastPromotedAt: lastPromotedAt ?? null,\n };\n}\n\nexport function registerDreamingRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/dreaming', async (c) => {\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, c.req.query('agentId'));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n const { store } = await loadDreamingStore({ dreamingRoot: scope.memoriesDir });\n const lock = await readLockInfo(scope.memoriesDir);\n\n // Read all three phase last-run files in parallel.\n const [lastRun, lightLastRun, remLastRun] = await Promise.all([\n readLastRun(scope.memoriesDir),\n readPhaseLastRun(scope.memoriesDir, 'last-run-light.json'),\n readPhaseLastRun(scope.memoriesDir, 'last-run-rem.json'),\n ]);\n\n return c.json({\n ok: true,\n payload: {\n agentId: scope.agentId,\n memory: scope.memory,\n workspaceDir: scope.workspaceDir,\n memoriesDir: scope.memoriesDir,\n config: scope.config,\n storePath: path.join(scope.memoriesDir, SHORT_TERM_RECALL_STORE_RELATIVE),\n store: storeStats(store),\n lock,\n lastRun,\n lightLastRun,\n remLastRun,\n },\n });\n });\n\n authenticated.get('/api/dreaming/preview', async (c) => {\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, c.req.query('agentId'));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n\n const rawLimit = c.req.query('limit');\n const limit = rawLimit ? Number(rawLimit) : 20;\n\n const preview = await previewDreamingDeepPromotion({\n workspaceDir: scope.workspaceDir,\n dreamingRoot: scope.memoriesDir,\n config: scope.config.deep,\n limit: Number.isFinite(limit) ? limit : 20,\n });\n\n return c.json({ ok: true, payload: preview });\n });\n\n authenticated.post('/api/dreaming/run', async (c) => {\n let body: unknown;\n try { body = await c.req.json(); } catch { body = {}; }\n const requestedPhase: DreamingPhaseId =\n isRecord(body) && typeof body.phase === 'string' && ['light', 'deep', 'rem'].includes(body.phase)\n ? (body.phase as DreamingPhaseId)\n : 'deep';\n\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, requestedAgentIdFrom(c, body));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n const dreaming = scope.config;\n if (!dreaming.enabled || !dreaming.phases[requestedPhase].enabled) {\n return c.json({\n ok: false,\n error: { message: `Dreaming ${requestedPhase} phase is disabled in config. Enable it first.` },\n }, 400);\n }\n\n try {\n service.emit('dreaming.phase.start', {\n agentId: scope.agentId,\n phase: requestedPhase,\n timestamp: new Date().toISOString(),\n });\n\n const result =\n requestedPhase === 'light'\n ? await runLightSweep({ dreamingRoot: scope.memoriesDir, config: dreaming.phases.light })\n : requestedPhase === 'rem'\n ? await runRemPatterns({ dreamingRoot: scope.memoriesDir, config: dreaming.phases.rem })\n : await runDreamingDeepPromotion({\n workspaceDir: scope.workspaceDir,\n dreamingRoot: scope.memoriesDir,\n config: dreaming.phases.deep,\n });\n\n service.emit('dreaming.phase.end', {\n agentId: scope.agentId,\n phase: requestedPhase,\n ok: true,\n timestamp: new Date().toISOString(),\n });\n\n return c.json({ ok: true, payload: { agentId: scope.agentId, phase: requestedPhase, result } });\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n service.emit('dreaming.phase.end', {\n agentId: scope.agentId,\n phase: requestedPhase,\n ok: false,\n error: em,\n timestamp: new Date().toISOString(),\n });\n return c.json({ ok: false, error: { message: em || 'Failed to trigger job' } }, 400);\n }\n });\n\n authenticated.post('/api/dreaming/action', async (c) => {\n const cfg = service.currentConfig as Config;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n body = {};\n }\n const action = isRecord(body) && typeof body.action === 'string' ? body.action.trim() : '';\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, requestedAgentIdFrom(c, body));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n\n if (action !== 'reset_store' && action !== 'clear_lock') {\n return c.json({ ok: false, error: { message: 'Invalid action' } }, 400);\n }\n\n if (action === 'reset_store') {\n const nowIso = new Date().toISOString();\n const next: DreamingStore = { version: 1, updatedAt: nowIso, entries: {} };\n await saveDreamingStore({ dreamingRoot: scope.memoriesDir, store: next });\n return c.json({\n ok: true,\n payload: { agentId: scope.agentId, reset: true, storePath: path.join(scope.memoriesDir, SHORT_TERM_RECALL_STORE_RELATIVE) },\n });\n }\n\n const lockPath = path.join(scope.memoriesDir, SHORT_TERM_PROMOTION_LOCK_RELATIVE);\n await fs.unlink(lockPath).catch(() => undefined);\n return c.json({\n ok: true,\n payload: { agentId: scope.agentId, cleared: true, lockPath },\n });\n });\n\n authenticated.get('/api/dreaming/events', async (c) => {\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, c.req.query('agentId'));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n\n const rawLimit = c.req.query('limit');\n const limit = rawLimit ? Math.min(Math.max(Number(rawLimit) || 50, 1), 200) : 50;\n\n const events = await readDreamingEvents(scope.memoriesDir, limit);\n return c.json({ ok: true, payload: { agentId: scope.agentId, events } });\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dreaming.js","names":[],"sources":["../../../../../src/gateway/hono/routes/dreaming.ts"],"sourcesContent":["import type { Hono } from 'hono';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { type Config } from '../../../config/schema.js';\nimport { normalizeAgentId, resolveDefaultAgentId } from '../../../agent/agent-scope.js';\nimport {\n DREAMING_DIR_RELATIVE,\n DREAMING_LAST_RUN_RELATIVE,\n SHORT_TERM_PROMOTION_LOCK_RELATIVE,\n SHORT_TERM_RECALL_STORE_RELATIVE,\n type DreamingPhaseId,\n} from '../../../agent/memory/dreaming/constants.js';\nimport { readDreamingEvents } from '../../../agent/memory/dreaming/events.js';\nimport { previewDreamingDeepPromotion } from '../../../agent/memory/dreaming/preview.js';\nimport { runLightSweep } from '../../../agent/memory/dreaming/light-sweep.js';\nimport { runDreamingDeepPromotion } from '../../../agent/memory/dreaming/deep-promotion.js';\nimport { runRemPatterns } from '../../../agent/memory/dreaming/rem-patterns.js';\nimport { parseDreamingLastRunFile, type DreamingDeepLastRun } from '../../../agent/memory/dreaming/last-run.js';\nimport { resolveDreamingAgentScope, type DreamingAgentScope } from '../../../agent/memory/dreaming/scope.js';\nimport {\n clearStaleDreamingLock,\n loadDreamingStore,\n resetDreamingStore,\n type DreamingStore,\n} from '../../../agent/memory/dreaming/short-term-store.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction requestedAgentIdFrom(c: { req: { query(name: string): string | undefined } }, body?: unknown): string | undefined {\n const fromBody = isRecord(body) && typeof body.agentId === 'string' ? body.agentId : undefined;\n return fromBody ?? c.req.query('agentId');\n}\n\nfunction hasEnabledAgent(cfg: Config, agentId: string): boolean {\n const normalized = normalizeAgentId(agentId);\n return cfg.agents.list.some((agent) => agent.enabled !== false && normalizeAgentId(agent.id) === normalized);\n}\n\nfunction resolveRouteScope(cfg: Config, requestedAgentId?: string): DreamingAgentScope {\n const agentId = normalizeAgentId(requestedAgentId || resolveDefaultAgentId(cfg));\n if (!hasEnabledAgent(cfg, agentId)) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n return resolveDreamingAgentScope(cfg, agentId);\n}\n\nasync function readLockInfo(dreamingRoot: string): Promise<\n | { locked: false }\n | { locked: true; path: string; content: string; mtimeMs?: number }\n> {\n const lockPath = path.join(dreamingRoot, SHORT_TERM_PROMOTION_LOCK_RELATIVE);\n try {\n const [content, st] = await Promise.all([fs.readFile(lockPath, 'utf-8'), fs.stat(lockPath)]);\n return {\n locked: true,\n path: SHORT_TERM_PROMOTION_LOCK_RELATIVE,\n content: content.trim(),\n mtimeMs: st.mtimeMs,\n };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return { locked: false };\n return { locked: true, path: SHORT_TERM_PROMOTION_LOCK_RELATIVE, content: 'unknown', mtimeMs: undefined };\n }\n}\n\nasync function readLastRun(\n dreamingRoot: string,\n): Promise<\n | { exists: false }\n | {\n exists: true;\n path: string;\n raw: unknown;\n record: DreamingDeepLastRun | null;\n parseError: string | null;\n }\n> {\n const fullPath = path.join(dreamingRoot, DREAMING_LAST_RUN_RELATIVE);\n try {\n const text = await fs.readFile(fullPath, 'utf-8');\n let raw: unknown;\n try {\n raw = JSON.parse(text) as unknown;\n } catch (parseErr) {\n return {\n exists: true,\n path: DREAMING_LAST_RUN_RELATIVE,\n raw: null,\n record: null,\n parseError: parseErr instanceof Error ? parseErr.message : String(parseErr),\n };\n }\n const record = parseDreamingLastRunFile(raw);\n return {\n exists: true,\n path: DREAMING_LAST_RUN_RELATIVE,\n raw,\n record,\n parseError: record ? null : 'Invalid or unsupported last-run.json (expected v2 deep record).',\n };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return { exists: false };\n return {\n exists: true,\n path: DREAMING_LAST_RUN_RELATIVE,\n raw: null,\n record: null,\n parseError: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nasync function readPhaseLastRun(\n dreamingRoot: string,\n filename: string,\n): Promise<{ exists: false } | { exists: true; path: string; raw: unknown }> {\n const relPath = path.join(DREAMING_DIR_RELATIVE, filename);\n const fullPath = path.join(dreamingRoot, relPath);\n try {\n const text = await fs.readFile(fullPath, 'utf-8');\n const raw = JSON.parse(text) as unknown;\n return { exists: true, path: relPath, raw };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | undefined)?.code;\n if (code === 'ENOENT') return { exists: false };\n return { exists: false };\n }\n}\n\nfunction storeStats(store: DreamingStore): {\n version: number;\n updatedAt: string;\n entryCount: number;\n promotedCount: number;\n lastPromotedAt: string | null;\n} {\n const entries = Object.values(store.entries ?? {});\n const promoted = entries.filter((e) => typeof e.promotedAt === 'string' && e.promotedAt.trim());\n const lastPromotedAt = promoted\n .map((e) => e.promotedAt!)\n .sort((a, b) => (a < b ? 1 : a > b ? -1 : 0))[0];\n return {\n version: store.version,\n updatedAt: store.updatedAt,\n entryCount: entries.length,\n promotedCount: promoted.length,\n lastPromotedAt: lastPromotedAt ?? null,\n };\n}\n\nexport function registerDreamingRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service } = deps;\n\n authenticated.get('/api/dreaming', async (c) => {\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, c.req.query('agentId'));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n const { store } = await loadDreamingStore({ dreamingRoot: scope.memoriesDir });\n const lock = await readLockInfo(scope.memoriesDir);\n\n // Read all three phase last-run files in parallel.\n const [lastRun, lightLastRun, remLastRun] = await Promise.all([\n readLastRun(scope.memoriesDir),\n readPhaseLastRun(scope.memoriesDir, 'last-run-light.json'),\n readPhaseLastRun(scope.memoriesDir, 'last-run-rem.json'),\n ]);\n\n return c.json({\n ok: true,\n payload: {\n agentId: scope.agentId,\n memory: scope.memory,\n workspaceDir: scope.workspaceDir,\n memoriesDir: scope.memoriesDir,\n config: scope.config,\n storePath: path.join(scope.memoriesDir, SHORT_TERM_RECALL_STORE_RELATIVE),\n store: storeStats(store),\n lock,\n lastRun,\n lightLastRun,\n remLastRun,\n },\n });\n });\n\n authenticated.get('/api/dreaming/preview', async (c) => {\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, c.req.query('agentId'));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n\n const rawLimit = c.req.query('limit');\n const limit = rawLimit ? Number(rawLimit) : 20;\n\n const preview = await previewDreamingDeepPromotion({\n workspaceDir: scope.workspaceDir,\n dreamingRoot: scope.memoriesDir,\n config: scope.config.deep,\n limit: Number.isFinite(limit) ? limit : 20,\n });\n\n return c.json({ ok: true, payload: preview });\n });\n\n authenticated.post('/api/dreaming/run', async (c) => {\n let body: unknown;\n try { body = await c.req.json(); } catch { body = {}; }\n const requestedPhase: DreamingPhaseId =\n isRecord(body) && typeof body.phase === 'string' && ['light', 'deep', 'rem'].includes(body.phase)\n ? (body.phase as DreamingPhaseId)\n : 'deep';\n\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, requestedAgentIdFrom(c, body));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n const dreaming = scope.config;\n if (!dreaming.enabled || !dreaming.phases[requestedPhase].enabled) {\n return c.json({\n ok: false,\n error: { message: `Dreaming ${requestedPhase} phase is disabled in config. Enable it first.` },\n }, 400);\n }\n\n try {\n service.emit('dreaming.phase.start', {\n agentId: scope.agentId,\n phase: requestedPhase,\n timestamp: new Date().toISOString(),\n });\n\n const result =\n requestedPhase === 'light'\n ? await runLightSweep({\n workspaceDir: scope.workspaceDir,\n dreamingRoot: scope.memoriesDir,\n config: dreaming.phases.light,\n })\n : requestedPhase === 'rem'\n ? await runRemPatterns({\n agentId: scope.agentId,\n workspaceDir: scope.workspaceDir,\n dreamingRoot: scope.memoriesDir,\n config: dreaming.phases.rem,\n sensitiveWritePolicy: scope.memory.privacy?.sensitiveWritePolicy,\n promotionWritePolicy: dreaming.promotionWritePolicy.decision,\n })\n : await runDreamingDeepPromotion({\n agentId: scope.agentId,\n workspaceDir: scope.workspaceDir,\n dreamingRoot: scope.memoriesDir,\n config: dreaming.phases.deep,\n sensitiveWritePolicy: scope.memory.privacy?.sensitiveWritePolicy,\n });\n\n service.emit('dreaming.phase.end', {\n agentId: scope.agentId,\n phase: requestedPhase,\n ok: true,\n timestamp: new Date().toISOString(),\n });\n\n return c.json({ ok: true, payload: { agentId: scope.agentId, phase: requestedPhase, result } });\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n service.emit('dreaming.phase.end', {\n agentId: scope.agentId,\n phase: requestedPhase,\n ok: false,\n error: em,\n timestamp: new Date().toISOString(),\n });\n return c.json({ ok: false, error: { message: em || 'Failed to trigger job' } }, 400);\n }\n });\n\n authenticated.post('/api/dreaming/action', async (c) => {\n const cfg = service.currentConfig as Config;\n\n let body: unknown;\n try {\n body = await c.req.json();\n } catch {\n body = {};\n }\n const action = isRecord(body) && typeof body.action === 'string' ? body.action.trim() : '';\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, requestedAgentIdFrom(c, body));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n\n if (action !== 'reset_store' && action !== 'clear_lock') {\n return c.json({ ok: false, error: { message: 'Invalid action' } }, 400);\n }\n\n if (action === 'reset_store') {\n await resetDreamingStore({ dreamingRoot: scope.memoriesDir });\n return c.json({\n ok: true,\n payload: { agentId: scope.agentId, reset: true, storePath: path.join(scope.memoriesDir, SHORT_TERM_RECALL_STORE_RELATIVE) },\n });\n }\n\n const lockPath = path.join(scope.memoriesDir, SHORT_TERM_PROMOTION_LOCK_RELATIVE);\n try {\n const cleared = await clearStaleDreamingLock(scope.memoriesDir);\n return c.json({\n ok: true,\n payload: { agentId: scope.agentId, cleared, lockPath },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 409);\n }\n });\n\n authenticated.get('/api/dreaming/events', async (c) => {\n const cfg = service.currentConfig as Config;\n let scope: DreamingAgentScope;\n try {\n scope = resolveRouteScope(cfg, c.req.query('agentId'));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return c.json({ ok: false, error: { message } }, 404);\n }\n\n const rawLimit = c.req.query('limit');\n const limit = rawLimit ? Math.min(Math.max(Number(rawLimit) || 50, 1), 200) : 50;\n\n const events = await readDreamingEvents(scope.memoriesDir, limit);\n return c.json({ ok: true, payload: { agentId: scope.agentId, events } });\n });\n}\n"],"mappings":"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"}
|