@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-contract-draft.js","names":[],"sources":["../../../src/goals/goal-contract-draft.ts"],"sourcesContent":["import type { UserMessage } from '@earendil-works/pi-ai';\nimport {
|
|
1
|
+
{"version":3,"file":"goal-contract-draft.js","names":[],"sources":["../../../src/goals/goal-contract-draft.ts"],"sourcesContent":["import type { UserMessage } from '@earendil-works/pi-ai';\n\nimport { getApiKey, resolveModel } from '../providers/index.js';\nimport { completeWithResolvedCredentials } from '../providers/model-call.js';\nimport type { GoalContractInput } from './types.js';\n\nconst MAX_ITEMS = 7;\n\nexport type GoalContractDraftInput = {\n title: string;\n context?: string;\n criteria?: string[];\n uiLocale?: 'en' | 'zh';\n modelRef?: string;\n signal?: AbortSignal;\n};\n\nexport type GoalContractDraftResult = {\n contract: GoalContractInput;\n generated: boolean;\n warning?: string;\n};\n\nfunction stringList(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n const seen = new Set<string>();\n const items: string[] = [];\n for (const item of value) {\n if (typeof item !== 'string') continue;\n const text = item.trim();\n const key = text.toLocaleLowerCase();\n if (!text || seen.has(key)) continue;\n seen.add(key);\n items.push(text);\n if (items.length >= MAX_ITEMS) break;\n }\n return items;\n}\n\nfunction extractText(content: unknown): string {\n if (!Array.isArray(content)) return '';\n return content\n .filter((block): block is { type: string; text?: unknown } => Boolean(block && typeof block === 'object'))\n .filter((block) => block.type === 'text' && typeof block.text === 'string')\n .map((block) => block.text as string)\n .join('')\n .trim();\n}\n\nfunction parseJson(raw: string): Record<string, unknown> | null {\n const text = raw.trim().replace(/^```(?:json)?\\s*/i, '').replace(/\\s*```$/, '');\n try {\n return JSON.parse(text) as Record<string, unknown>;\n } catch {\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start < 0 || end <= start) return null;\n try {\n return JSON.parse(text.slice(start, end + 1)) as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n}\n\nfunction fallbackContract(input: GoalContractDraftInput): GoalContractInput {\n const title = input.title.trim();\n const criteria = stringList(input.criteria);\n const isChinese = input.uiLocale === 'zh';\n return {\n objective: title,\n scopeBoundary: input.context?.trim() || undefined,\n criteria: criteria.length\n ? criteria\n : isChinese\n ? [\n `“${title}”具有清晰且可由用户验证的最终结果。`,\n `“${title}”在约定范围内完成所需工作。`,\n ]\n : [\n `${title} has a clear, user-verifiable outcome.`,\n `The required work for ${title} is complete within the stated scope.`,\n ],\n evidencePlan: [isChinese\n ? '提供可检查的测试结果、产物、链接或报告,以证明目标完成。'\n : 'Record an inspectable test result, artifact, link, or report that proves completion.'],\n };\n}\n\nfunction normalizedModelContract(data: Record<string, unknown>, fallback: GoalContractInput): GoalContractInput {\n const objective = typeof data.objective === 'string' && data.objective.trim()\n ? data.objective.trim()\n : fallback.objective;\n const scopeBoundary = typeof data.scopeBoundary === 'string' && data.scopeBoundary.trim()\n ? data.scopeBoundary.trim()\n : fallback.scopeBoundary;\n const criteria = stringList(data.criteria);\n const evidencePlan = stringList(data.evidencePlan);\n return {\n objective,\n scopeBoundary,\n criteria: criteria.length ? criteria : fallback.criteria,\n evidencePlan: evidencePlan.length ? evidencePlan : fallback.evidencePlan,\n };\n}\n\nexport async function draftGoalContract(input: GoalContractDraftInput): Promise<GoalContractDraftResult> {\n const fallback = fallbackContract(input);\n if (!input.modelRef?.trim()) {\n return {\n contract: fallback,\n generated: false,\n warning: input.uiLocale === 'zh' ? '未配置用于定义目标的模型,已生成可编辑的本地草案。' : 'No model is configured for goal drafting.',\n };\n }\n\n try {\n const model = resolveModel(input.modelRef.trim());\n const apiKey = await getApiKey(model.provider);\n const prompt = [\n 'Turn the explicitly requested persistent goal into a concise, measurable goal contract.',\n 'Preserve the user intent. Do not claim work is done. Do not include markdown or commentary.',\n 'Return only one JSON object with objective, scopeBoundary, criteria, and evidencePlan.',\n 'criteria and evidencePlan must each contain 1 to 7 concrete, observable strings.',\n 'The scope boundary must state material exclusions when possible.',\n input.uiLocale === 'zh' ? 'Return every string value in Simplified Chinese.' : 'Return every string value in English.',\n '',\n `Goal title: ${input.title.trim()}`,\n `Context: ${input.context?.trim() || '(none)'}`,\n `Existing acceptance criteria: ${stringList(input.criteria).join(' | ') || '(none)'}`,\n ].join('\\n');\n const message: UserMessage = { role: 'user', content: prompt, timestamp: Date.now() };\n const result = await completeWithResolvedCredentials(model, { messages: [message] }, {\n apiKey,\n maxTokens: 1200,\n temperature: 0,\n signal: input.signal,\n });\n const parsed = parseJson(extractText(result.content));\n if (!parsed) return {\n contract: fallback,\n generated: false,\n warning: input.uiLocale === 'zh' ? '模型未返回有效的目标契约,已生成可编辑的本地草案。' : 'The model did not return a valid goal contract.',\n };\n return { contract: normalizedModelContract(parsed, fallback), generated: true };\n } catch {\n return {\n contract: fallback,\n generated: false,\n warning: input.uiLocale === 'zh' ? '目标定义暂不可用,已生成可编辑的本地草案。' : 'Goal drafting is unavailable; a local draft was prepared instead.',\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getApiKey, init_providers, resolveModel } from "../providers/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { completeWithResolvedCredentials } from "../providers/model-call.js";
|
|
3
3
|
//#region src/goals/goal-evidence-review.ts
|
|
4
4
|
init_providers();
|
|
5
5
|
function extractText(content) {
|
|
@@ -40,7 +40,7 @@ async function reviewGoalEvidenceRequirement(input) {
|
|
|
40
40
|
try {
|
|
41
41
|
const model = resolveModel(input.modelRef.trim());
|
|
42
42
|
const apiKey = await getApiKey(model.provider);
|
|
43
|
-
const parsed = parseJson(extractText((await
|
|
43
|
+
const parsed = parseJson(extractText((await completeWithResolvedCredentials(model, { messages: [{
|
|
44
44
|
role: "user",
|
|
45
45
|
content: [
|
|
46
46
|
"Assess whether the linked evidence proves the single goal requirement.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-evidence-review.js","names":[],"sources":["../../../src/goals/goal-evidence-review.ts"],"sourcesContent":["import type { UserMessage } from '@earendil-works/pi-ai';\nimport {
|
|
1
|
+
{"version":3,"file":"goal-evidence-review.js","names":[],"sources":["../../../src/goals/goal-evidence-review.ts"],"sourcesContent":["import type { UserMessage } from '@earendil-works/pi-ai';\n\nimport { getApiKey, resolveModel } from '../providers/index.js';\nimport { completeWithResolvedCredentials } from '../providers/model-call.js';\nimport type { GoalEvidence, GoalEvidenceRequirement } from './types.js';\n\nexport type GoalEvidenceReviewVerdict = 'approved' | 'needs_more_evidence' | 'rejected';\n\nexport type GoalEvidenceReviewResult = {\n verdict: GoalEvidenceReviewVerdict;\n reason: string;\n confidence?: number;\n generated: boolean;\n warning?: string;\n};\n\nfunction extractText(content: unknown): string {\n if (!Array.isArray(content)) return '';\n return content\n .filter((block): block is { type: string; text?: unknown } => Boolean(block && typeof block === 'object'))\n .filter((block) => block.type === 'text' && typeof block.text === 'string')\n .map((block) => block.text as string)\n .join('')\n .trim();\n}\n\nfunction parseJson(raw: string): Record<string, unknown> | null {\n const text = raw.trim().replace(/^```(?:json)?\\s*/i, '').replace(/\\s*```$/, '');\n try {\n return JSON.parse(text) as Record<string, unknown>;\n } catch {\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start < 0 || end <= start) return null;\n try {\n return JSON.parse(text.slice(start, end + 1)) as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n}\n\nfunction localReview(requirement: GoalEvidenceRequirement, evidence: GoalEvidence[]): GoalEvidenceReviewResult {\n if (!evidence.length) {\n return {\n verdict: 'needs_more_evidence',\n reason: `No evidence is linked to the requirement: ${requirement.text}`,\n generated: false,\n };\n }\n return {\n verdict: 'needs_more_evidence',\n reason: `${evidence.length} evidence item(s) are linked. Configure a goal judge model to assess whether they prove this requirement, then approve the result manually.`,\n generated: false,\n warning: 'No model is configured for evidence review.',\n };\n}\n\nexport async function reviewGoalEvidenceRequirement(input: {\n requirement: GoalEvidenceRequirement;\n evidence: GoalEvidence[];\n modelRef?: string;\n signal?: AbortSignal;\n}): Promise<GoalEvidenceReviewResult> {\n const fallback = localReview(input.requirement, input.evidence);\n if (!input.modelRef?.trim() || input.evidence.length === 0) return fallback;\n try {\n const model = resolveModel(input.modelRef.trim());\n const apiKey = await getApiKey(model.provider);\n const prompt = [\n 'Assess whether the linked evidence proves the single goal requirement.',\n 'Be conservative: never infer facts that are absent from the supplied evidence.',\n 'Return only JSON with verdict (approved, needs_more_evidence, or rejected), reason, and confidence (0 to 1).',\n 'An approved result is advisory and still needs a human approval before goal completion.',\n '',\n `Requirement: ${input.requirement.text}`,\n 'Linked evidence:',\n ...input.evidence.map((item, index) => [\n `${index + 1}. kind=${item.kind}; title=${item.title}`,\n item.summary ? `summary=${item.summary}` : '',\n item.uri ? `uri=${item.uri}` : '',\n ].filter(Boolean).join('; ')),\n ].join('\\n');\n const message: UserMessage = { role: 'user', content: prompt, timestamp: Date.now() };\n const response = await completeWithResolvedCredentials(model, { messages: [message] }, {\n apiKey,\n maxTokens: 700,\n temperature: 0,\n signal: input.signal,\n });\n const parsed = parseJson(extractText(response.content));\n if (!parsed) return { ...fallback, warning: 'The model did not return a valid evidence review.' };\n const verdict = parsed.verdict;\n if (verdict !== 'approved' && verdict !== 'needs_more_evidence' && verdict !== 'rejected') {\n return { ...fallback, warning: 'The model returned an unsupported evidence verdict.' };\n }\n const reason = typeof parsed.reason === 'string' && parsed.reason.trim()\n ? parsed.reason.trim()\n : 'The model did not provide a review rationale.';\n const confidence = typeof parsed.confidence === 'number' && Number.isFinite(parsed.confidence)\n ? Math.min(1, Math.max(0, parsed.confidence))\n : undefined;\n return { verdict, reason, confidence, generated: true };\n } catch {\n return { ...fallback, warning: 'Evidence review is unavailable; manual approval remains available.' };\n }\n}\n"],"mappings":";;;gBAEgE;AAchE,SAAS,YAAY,SAA0B;AAC7C,KAAI,CAAC,MAAM,QAAQ,QAAQ,CAAE,QAAO;AACpC,QAAO,QACJ,QAAQ,UAAqD,QAAQ,SAAS,OAAO,UAAU,SAAS,CAAC,CACzG,QAAQ,UAAU,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,SAAS,CAC1E,KAAK,UAAU,MAAM,KAAe,CACpC,KAAK,GAAG,CACR,MAAM;;AAGX,SAAS,UAAU,KAA6C;CAC9D,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,qBAAqB,GAAG,CAAC,QAAQ,WAAW,GAAG;AAC/E,KAAI;AACF,SAAO,KAAK,MAAM,KAAK;SACjB;EACN,MAAM,QAAQ,KAAK,QAAQ,IAAI;EAC/B,MAAM,MAAM,KAAK,YAAY,IAAI;AACjC,MAAI,QAAQ,KAAK,OAAO,MAAO,QAAO;AACtC,MAAI;AACF,UAAO,KAAK,MAAM,KAAK,MAAM,OAAO,MAAM,EAAE,CAAC;UACvC;AACN,UAAO;;;;AAKb,SAAS,YAAY,aAAsC,UAAoD;AAC7G,KAAI,CAAC,SAAS,OACZ,QAAO;EACL,SAAS;EACT,QAAQ,6CAA6C,YAAY;EACjE,WAAW;EACZ;AAEH,QAAO;EACL,SAAS;EACT,QAAQ,GAAG,SAAS,OAAO;EAC3B,WAAW;EACX,SAAS;EACV;;AAGH,eAAsB,8BAA8B,OAKd;CACpC,MAAM,WAAW,YAAY,MAAM,aAAa,MAAM,SAAS;AAC/D,KAAI,CAAC,MAAM,UAAU,MAAM,IAAI,MAAM,SAAS,WAAW,EAAG,QAAO;AACnE,KAAI;EACF,MAAM,QAAQ,aAAa,MAAM,SAAS,MAAM,CAAC;EACjD,MAAM,SAAS,MAAM,UAAU,MAAM,SAAS;EAsB9C,MAAM,SAAS,UAAU,aAAY,MANd,gCAAgC,OAAO,EAAE,UAAU,CAAC;GAD5C,MAAM;GAAQ,SAd9B;IACb;IACA;IACA;IACA;IACA;IACA,gBAAgB,MAAM,YAAY;IAClC;IACA,GAAG,MAAM,SAAS,KAAK,MAAM,UAAU;KACrC,GAAG,QAAQ,EAAE,SAAS,KAAK,KAAK,UAAU,KAAK;KAC/C,KAAK,UAAU,WAAW,KAAK,YAAY;KAC3C,KAAK,MAAM,OAAO,KAAK,QAAQ;KAChC,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAK,CAAC;IAC9B,CAAC,KAAK,KACqD;GAAE,WAAW,KAAK,KAAK;GACD,CAAC,EAAE,EAAE;GACrF;GACA,WAAW;GACX,aAAa;GACb,QAAQ,MAAM;GACf,CAAC,EAC4C,QAAQ,CAAC;AACvD,MAAI,CAAC,OAAQ,QAAO;GAAE,GAAG;GAAU,SAAS;GAAqD;EACjG,MAAM,UAAU,OAAO;AACvB,MAAI,YAAY,cAAc,YAAY,yBAAyB,YAAY,WAC7E,QAAO;GAAE,GAAG;GAAU,SAAS;GAAuD;AAQxF,SAAO;GAAE;GAAS,QANH,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,MAAM,GACpE,OAAO,OAAO,MAAM,GACpB;GAIsB,YAHP,OAAO,OAAO,eAAe,YAAY,OAAO,SAAS,OAAO,WAAW,GAC1F,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,WAAW,CAAC,GAC3C,KAAA;GACkC,WAAW;GAAM;SACjD;AACN,SAAO;GAAE,GAAG;GAAU,SAAS;GAAsE"}
|
|
@@ -5,11 +5,11 @@ import { parseNoteMarkdown } from "./note-markdown.js";
|
|
|
5
5
|
import { changedFieldsFromPatch, emitActivity, previewText, systemActivityActor, systemActivitySource } from "../activity/emitter.js";
|
|
6
6
|
import { getDefaultModelSync, init_providers, resolveModel } from "../providers/index.js";
|
|
7
7
|
import { publishAutomationProductEvent } from "../automations/product-events.js";
|
|
8
|
+
import { completeWithResolvedCredentials } from "../providers/model-call.js";
|
|
8
9
|
import { NotesStore } from "./store.js";
|
|
9
10
|
import { partitionAttachmentsByReference } from "./note-attachment-sync.js";
|
|
10
11
|
import { buildNoteAgentContextArtifact, getCachedNoteAgentContextArtifact } from "./agent-context.js";
|
|
11
12
|
import { randomUUID } from "node:crypto";
|
|
12
|
-
import { complete } from "@earendil-works/pi-ai/compat";
|
|
13
13
|
//#region src/notes/service.ts
|
|
14
14
|
init_providers();
|
|
15
15
|
init_logger();
|
|
@@ -128,7 +128,7 @@ function buildCatalysisPrompt(note) {
|
|
|
128
128
|
async function buildAiCatalysisReport(note, config) {
|
|
129
129
|
const modelRef = getDefaultModelSync(config);
|
|
130
130
|
if (!modelRef) throw new Error("No global default model configured");
|
|
131
|
-
const response = await
|
|
131
|
+
const response = await completeWithResolvedCredentials(resolveModel(modelRef), { messages: [{
|
|
132
132
|
role: "user",
|
|
133
133
|
content: buildCatalysisPrompt(note),
|
|
134
134
|
timestamp: Date.now()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":[],"sources":["../../../src/notes/service.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { complete, type UserMessage } from '@earendil-works/pi-ai/compat';\n\nimport { changedFieldsFromPatch, emitActivity, previewText, systemActivityActor, systemActivitySource } from '../activity/emitter.js';\nimport { publishAutomationProductEvent } from '../automations/product-events.js';\nimport type { Config } from '../config/schema.js';\nimport { getDefaultModelSync, resolveModel } from '../providers/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { buildNoteAttachmentRef } from './attachment-ref.js';\nimport { partitionAttachmentsByReference } from './note-attachment-sync.js';\nimport { parseNoteMarkdown } from './note-markdown.js';\nimport { buildNoteAgentContextArtifact, getCachedNoteAgentContextArtifact } from './agent-context.js';\nimport { NotesStore } from './store.js';\nimport type {\n CaptureSource,\n CreateNoteParams,\n Note,\n NoteAiPatch,\n NoteAttachment,\n NoteCatalysisAction,\n NoteCatalysisMeta,\n NoteCatalysisReport,\n NoteIndexEntry,\n NoteKind,\n NoteSnapshot,\n NoteSnapshotEntry,\n NotesListQuery,\n SnapshotTrigger,\n} from './types.js';\n\nconst log = createLogger('NotesService');\nconst MAX_SNAPSHOTS_PER_NOTE = 50;\nconst SNAPSHOT_THROTTLE_MS = 60_000;\n\nfunction inferKind(markdown?: string, hasAttachments?: boolean, attachments?: NoteAttachment[]): NoteKind {\n if (hasAttachments && attachments?.length && attachments.every((item) => item.type === 'audio')) return 'voice';\n if (hasAttachments) return 'media';\n if (!markdown) return 'thought';\n const lower = markdown.toLowerCase();\n if (/^(todo|task|remind|buy|call|email|meet|finish|submit|send)\\b/i.test(lower) || /\\b(明天|今天|记得|别忘|待办|提醒)\\b/.test(markdown)) return 'todo';\n if (/^https?:\\/\\//.test(markdown.trim())) return 'bookmark';\n return 'thought';\n}\n\nfunction deriveDefaultTitle(markdown?: string): string | undefined {\n const normalized = parseNoteMarkdown(markdown ?? '').plainText.trim().replace(/\\s+/g, ' ');\n return normalized ? Array.from(normalized).slice(0, 10).join('') : undefined;\n}\n\nfunction splitMeaningfulLines(markdown?: string): string[] {\n return parseNoteMarkdown(markdown ?? '').plainText.split(/\\n|。|;|;/).map((line) => line.trim()).filter(Boolean);\n}\n\nfunction summarizeIdea(markdown?: string): string {\n const lines = splitMeaningfulLines(markdown);\n return lines.slice(0, 3).join(';').slice(0, 140);\n}\n\nfunction publishNoteEvent(\n type: 'note.created' | 'note.updated',\n note: Note,\n extra?: Record<string, unknown>,\n): void {\n publishAutomationProductEvent({\n type,\n source: 'notes',\n payload: {\n noteId: note.id,\n kind: note.kind,\n status: note.status,\n title: note.title,\n capturedVia: note.capturedVia,\n tagCount: note.tags?.length ?? 0,\n hasAttachments: Boolean(note.attachments?.length),\n ...extra,\n },\n });\n}\n\nfunction inferCatalysisStage(note: Note): NonNullable<NoteCatalysisMeta['stage']> {\n const text = `${note.title ?? ''}\\n${note.markdown}`;\n if (/上线|发布|launch|ship/i.test(text)) return 'shipped';\n if (/验证|访谈|用户|测试|validate/i.test(text)) return 'validating';\n if (/开发|实现|构建|build|mvp/i.test(text)) return 'developing';\n if (/想法|机会|问题|idea|seed/i.test(text)) return 'seed';\n return 'incubating';\n}\n\nfunction buildCatalysisReport(note: Note): NoteCatalysisReport {\n const summary = summarizeIdea(note.markdown || note.title);\n const title = note.title?.trim() || summary.slice(0, 28) || '未命名想法';\n const actions: NoteCatalysisAction[] = [\n { kind: 'research', text: `验证「${title}」的真实需求和目标用户` },\n { kind: 'task', text: `拆解「${title}」的最小可行下一步` },\n { kind: 'chat', text: `继续和 AI 讨论「${title}」的方案` },\n ];\n return {\n originalNoteId: note.id,\n generatedAt: Date.now(),\n title,\n valueHypothesis: summary || '这条笔记可能包含一个待澄清的想法。',\n targetUsers: ['待确认的核心用户'],\n keyQuestions: ['用户为什么现在需要它?', '最小可验证版本是什么?', '如何判断它值得继续投入?'],\n mvpPath: ['定义目标用户', '写出最小场景', '完成一次验证'],\n risks: ['需求不够明确', '执行路径过大'],\n nextActions: actions,\n confidence: summary ? 0.58 : 0.35,\n };\n}\n\nfunction normalizeAiCatalysisReport(note: Note, data: Record<string, unknown>): NoteCatalysisReport {\n const fallback = buildCatalysisReport(note);\n const stringArray = (value: unknown, fallbackValue: string[]) => Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string').slice(0, 12) : fallbackValue;\n const actions = Array.isArray(data.nextActions)\n ? data.nextActions.map((item): NoteCatalysisAction | null => {\n if (!item || typeof item !== 'object') return null;\n const row = item as { kind?: unknown; text?: unknown };\n const kind = row.kind === 'task' || row.kind === 'workflow' || row.kind === 'research' || row.kind === 'share' || row.kind === 'chat' ? row.kind : 'task';\n return typeof row.text === 'string' && row.text.trim() ? { kind, text: row.text.trim() } : null;\n }).filter((item): item is NoteCatalysisAction => Boolean(item)).slice(0, 12)\n : fallback.nextActions;\n return {\n originalNoteId: note.id,\n generatedAt: Date.now(),\n title: typeof data.title === 'string' && data.title.trim() ? data.title.trim() : fallback.title,\n valueHypothesis: typeof data.valueHypothesis === 'string' && data.valueHypothesis.trim() ? data.valueHypothesis.trim() : fallback.valueHypothesis,\n targetUsers: stringArray(data.targetUsers, fallback.targetUsers),\n keyQuestions: stringArray(data.keyQuestions, fallback.keyQuestions),\n mvpPath: stringArray(data.mvpPath, fallback.mvpPath),\n risks: stringArray(data.risks, fallback.risks),\n nextActions: actions,\n confidence: typeof data.confidence === 'number' ? Math.max(0, Math.min(1, data.confidence)) : fallback.confidence,\n };\n}\n\nfunction buildCatalysisPrompt(note: Note): string {\n const title = note.title?.trim() || '未命名笔记';\n const markdown = note.markdown.trim() || '(无正文)';\n return `请把下面的 Markdown 笔记催化成可执行的想法报告,输出 JSON:\\n{\\n \"title\": string,\\n \"valueHypothesis\": string,\\n \"targetUsers\": string[],\\n \"keyQuestions\": string[],\\n \"mvpPath\": string[],\\n \"risks\": string[],\\n \"nextActions\": [{\"text\": string, \"kind\": \"task\"|\"workflow\"|\"research\"|\"share\"|\"chat\"}],\\n \"confidence\": number\\n}\\n\\n标题:${title}\\n\\nMarkdown:\\n${markdown}`;\n}\n\nasync function buildAiCatalysisReport(note: Note, config?: Config): Promise<NoteCatalysisReport> {\n const modelRef = getDefaultModelSync(config);\n if (!modelRef) {\n throw new Error('No global default model configured');\n }\n const resolved = resolveModel(modelRef);\n const messages: UserMessage[] = [{ role: 'user', content: buildCatalysisPrompt(note), timestamp: Date.now() }];\n const response = await complete(resolved, { messages }, { temperature: 0.2 });\n let responseText = '';\n if (Array.isArray(response.content)) {\n for (const part of response.content) {\n if (part && typeof part === 'object' && (part as { type?: string }).type === 'text') {\n responseText += String((part as { text?: string }).text || '');\n }\n }\n }\n const raw = responseText.trim().replace(/^```json\\s*/i, '').replace(/```$/i, '').trim();\n return normalizeAiCatalysisReport(note, JSON.parse(raw) as Record<string, unknown>);\n}\n\nexport class NotesService {\n private lastSnapshotAt = new Map<string, number>();\n\n constructor(private readonly store = new NotesStore()) {}\n\n async initialize(): Promise<void> {\n await this.store.initialize();\n }\n\n async quickCapture(markdown: string, source: CaptureSource): Promise<Note> {\n const id = randomUUID();\n const now = Date.now();\n const note: Note = {\n id,\n title: deriveDefaultTitle(markdown),\n kind: inferKind(markdown),\n status: 'inbox',\n markdown,\n createdAt: now,\n updatedAt: now,\n capturedVia: source,\n remoteVersion: 1,\n localVersion: 1,\n };\n await this.store.addNote(note);\n emitActivity({\n type: 'note.created',\n primaryObject: { kind: 'note', id: note.id, title: note.title },\n actor: systemActivityActor(),\n source: systemActivitySource(),\n payload: {\n title: note.title,\n kind: note.kind,\n tags: note.tags,\n contentPreview: previewText(note.markdown),\n contentLength: note.markdown.length,\n },\n nowMs: note.createdAt,\n });\n log.debug({ id: note.id, kind: note.kind }, 'Quick capture');\n return note;\n }\n\n async createNote(params: CreateNoteParams): Promise<Note> {\n const id = randomUUID();\n const now = Date.now();\n const markdown = params.markdown ?? '';\n const note: Note = {\n id,\n title: params.title ?? deriveDefaultTitle(markdown),\n kind: params.kind ?? inferKind(markdown),\n status: 'inbox',\n markdown,\n attachments: [],\n createdAt: now,\n updatedAt: now,\n capturedVia: params.capturedVia,\n tags: params.tags,\n pinned: params.pinned,\n groupId: params.groupId,\n taskMeta: params.taskMeta,\n remoteVersion: 1,\n localVersion: 1,\n };\n await this.store.addNote(note);\n emitActivity({\n type: 'note.created',\n primaryObject: { kind: 'note', id: note.id, title: note.title },\n actor: systemActivityActor(),\n source: systemActivitySource(),\n payload: {\n title: note.title,\n kind: note.kind,\n tags: note.tags,\n contentPreview: previewText(note.markdown),\n contentLength: note.markdown.length,\n },\n nowMs: note.createdAt,\n });\n publishNoteEvent('note.created', note);\n log.debug({ id: note.id, kind: note.kind }, 'Note created');\n return note;\n }\n\n async getNote(id: string): Promise<Note | null> {\n return this.store.getNote(id);\n }\n\n async updateNote(id: string, patch: Partial<Note>, trigger: SnapshotTrigger = 'edit'): Promise<Note | null> {\n const existing = await this.store.getNote(id);\n if (!existing) return null;\n const contentTouched = patch.markdown !== undefined || patch.title !== undefined;\n if (contentTouched) await this.maybeSaveSnapshot(existing, trigger);\n\n const normalizedPatch: Partial<Note> = { ...patch };\n if (patch.markdown !== undefined) {\n normalizedPatch.kind = patch.kind ?? inferKind(patch.markdown, Boolean(existing.attachments?.length), existing.attachments);\n }\n if (contentTouched || patch.attachments) {\n normalizedPatch.remoteVersion = (existing.remoteVersion ?? 1) + 1;\n normalizedPatch.localVersion = patch.localVersion ?? (existing.localVersion ?? 1) + 1;\n }\n\n const updatedRaw = await this.store.updateNote(id, normalizedPatch);\n const updated = updatedRaw ? await this.reconcileAttachments(updatedRaw) : null;\n if (updated) {\n const changes = changedFieldsFromPatch(patch as Record<string, unknown>);\n emitActivity({\n type: existing.status !== updated.status ? 'note.status_changed' : 'note.updated',\n primaryObject: { kind: 'note', id: updated.id, title: updated.title },\n actor: systemActivityActor(),\n source: systemActivitySource(),\n payload: {\n changes,\n contentTouched,\n ...(existing.status !== updated.status ? { from: existing.status, to: updated.status } : {}),\n },\n nowMs: updated.updatedAt,\n });\n publishNoteEvent('note.updated', updated, {\n contentTouched,\n trigger,\n });\n }\n return updated;\n }\n\n private async reconcileAttachments(note: Note): Promise<Note> {\n const { kept, removed } = partitionAttachmentsByReference(note);\n if (removed.length === 0) return note;\n for (const attachment of removed) await this.store.deleteAttachmentFile(note.id, attachment.relativePath);\n log.debug({ noteId: note.id, removedIds: removed.map((attachment) => attachment.id) }, 'Pruned orphan note attachments');\n const hasAttachments = kept.length > 0;\n const updated = await this.store.updateNote(note.id, { attachments: kept, kind: inferKind(note.markdown, hasAttachments, kept) });\n return updated ?? { ...note, attachments: kept };\n }\n\n async syncNote(id: string, patch: Partial<Note>, baseRemoteVersion?: number): Promise<{ note: Note | null; conflict: boolean }> {\n const existing = await this.store.getNote(id);\n if (!existing) return { note: null, conflict: false };\n if (baseRemoteVersion !== undefined && existing.remoteVersion !== undefined && baseRemoteVersion < existing.remoteVersion) {\n return { note: existing, conflict: true };\n }\n const updated = await this.updateNote(id, patch, 'sync');\n return { note: updated, conflict: false };\n }\n\n async createAiEditPatch(id: string, instruction: string, markdownOverride?: string): Promise<{ message: string; patch: NoteAiPatch } | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const source = markdownOverride ?? note.markdown;\n const parsed = parseNoteMarkdown(source, id);\n const wantsTodos = /待办|todo|task|行动|提醒/i.test(instruction);\n const wantsSummary = /摘要|总结|summary|压缩/i.test(instruction);\n let generated = '';\n if (wantsTodos) {\n const lines = source.split(/\\n|。|;|;/).map((line) => line.trim()).filter(Boolean);\n generated = (lines.length ? lines : [parsed.plainText]).slice(0, 12).map((line) => `- [ ] ${line.replace(/^[-*\\d.\\s\\[\\]x]+/i, '').trim()}`).join('\\n');\n } else if (wantsSummary) {\n generated = `> [!SUMMARY]\\n> ${parsed.plainText.slice(0, 220)}`;\n } else {\n generated = `${source.trimEnd()}\\n\\n## AI 整理\\n\\n${instruction.trim()}`;\n }\n return {\n message: 'AI edit patch generated',\n patch: {\n id: randomUUID(),\n summary: instruction,\n operations: [{ type: 'replaceRange', from: 0, to: source.length, markdown: generated || source }],\n },\n };\n }\n\n async catalyzeNote(id: string, config?: Config): Promise<{ note: Note; report: NoteCatalysisReport } | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n let report: NoteCatalysisReport;\n try {\n report = await buildAiCatalysisReport(note, config);\n } catch (err) {\n log.warn({ err, noteId: id }, 'AI note catalysis failed; using local fallback report');\n report = buildCatalysisReport(note);\n }\n const updated = await this.updateNote(id, {\n aiDeep: {\n ...note.aiDeep,\n processedAt: Date.now(),\n catalysis: {\n status: 'catalyzed',\n stage: inferCatalysisStage(note),\n lastCatalyzedAt: Date.now(),\n confidence: report.confidence,\n report,\n ...note.aiDeep?.catalysis,\n },\n },\n ai: { ...note.ai, intent: note.ai?.intent ?? 'idea', summary: note.ai?.summary ?? report.valueHypothesis },\n status: note.status === 'inbox' ? 'processed' : note.status,\n }, 'ai_edit');\n return updated ? { note: updated, report } : null;\n }\n\n async recordCatalysisFeedback(id: string, feedback: 'helpful' | 'not_helpful' | 'neutral'): Promise<Note | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n return this.updateNote(id, { aiDeep: { ...note.aiDeep, processedAt: Date.now(), catalysis: { status: note.aiDeep?.catalysis?.status ?? 'catalyzed', ...note.aiDeep?.catalysis, feedback } } });\n }\n\n async linkNoteThread(id: string, sessionKey: string): Promise<Note | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const existingKeys = note.aiDeep?.catalysis?.linkedSessionKeys ?? [];\n return this.updateNote(id, {\n aiDeep: {\n ...note.aiDeep,\n processedAt: Date.now(),\n catalysis: {\n status: note.aiDeep?.catalysis?.status ?? 'none',\n ...note.aiDeep?.catalysis,\n sourceSessionKey: note.aiDeep?.catalysis?.sourceSessionKey ?? sessionKey,\n linkedSessionKeys: Array.from(new Set([...existingKeys, sessionKey])),\n },\n },\n }, 'sync');\n }\n\n async listNoteThreads(id: string): Promise<string[] | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n return Array.from(new Set([note.aiDeep?.catalysis?.sourceSessionKey, ...(note.aiDeep?.catalysis?.linkedSessionKeys ?? [])].filter((key): key is string => Boolean(key))));\n }\n\n async getAgentContextStatus(id: string, config?: Config, force = false): Promise<{ noteUpdatedAt: number; artifact: import('./agent-context.js').NoteAgentContextArtifact | null; stale: boolean } | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const cached = getCachedNoteAgentContextArtifact(id);\n if (!force && cached && cached.noteUpdatedAt === note.updatedAt) {\n return { noteUpdatedAt: note.updatedAt, artifact: cached, stale: false };\n }\n const artifact = await buildNoteAgentContextArtifact({ note, notesService: this, config, force });\n return { noteUpdatedAt: note.updatedAt, artifact, stale: false };\n }\n\n async appendTextToNote(id: string, content: string, heading = 'AI 讨论沉淀'): Promise<Note | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const trimmed = content.trim();\n if (!trimmed) return note;\n const current = note.markdown.trimEnd();\n const nextMarkdown = `${current}${current ? '\\n\\n' : ''}## ${heading}\\n\\n${trimmed}\\n`;\n return this.updateNote(id, { markdown: nextMarkdown }, 'ai_edit');\n }\n\n async deleteNote(id: string): Promise<boolean> {\n const removed = await this.store.deleteNote(id);\n if (removed) await this.store.deleteAllSnapshots(id);\n return removed;\n }\n\n async listNotes(query: NotesListQuery = {}): Promise<{ items: NoteIndexEntry[]; total: number; limit: number; offset: number; hasMore: boolean }> {\n return this.store.listNotes(query);\n }\n\n async addAttachment(noteId: string, file: { name: string; buffer: Buffer; mimeType: string; duration?: number }): Promise<NoteAttachment | null> {\n const note = await this.store.getNote(noteId);\n if (!note) return null;\n const { relativePath, size } = await this.store.saveAttachment(noteId, file.name, file.buffer);\n const attachment: NoteAttachment = {\n id: randomUUID(),\n type: file.mimeType.startsWith('image/') ? 'image' : file.mimeType.startsWith('audio/') ? 'audio' : file.mimeType.startsWith('video/') ? 'video' : 'file',\n mimeType: file.mimeType,\n fileName: file.name,\n size,\n relativePath,\n duration: file.duration,\n };\n const attachments = [...(note.attachments || []), attachment];\n const kind = note.kind === 'thought' && attachment.type === 'audio' ? 'voice' : note.kind === 'thought' ? 'media' : note.kind;\n await this.store.updateNote(noteId, { attachments, kind });\n return attachment;\n }\n\n async getAttachmentPath(noteId: string, attachmentId: string): Promise<{ filePath: string; mimeType: string; fileName: string } | null> {\n const note = await this.store.getNote(noteId);\n if (!note) return null;\n const attachment = note.attachments?.find((a) => a.id === attachmentId);\n if (!attachment) return null;\n return { filePath: this.store.resolveAttachmentPath(noteId, attachment.relativePath), mimeType: attachment.mimeType, fileName: attachment.fileName };\n }\n\n async listNoteHistory(noteId: string): Promise<NoteSnapshotEntry[]> { return this.store.listSnapshots(noteId); }\n async getNoteSnapshot(noteId: string, timestamp: number): Promise<NoteSnapshot | null> { return this.store.getSnapshot(noteId, timestamp); }\n\n async restoreNoteSnapshot(noteId: string, timestamp: number): Promise<Note | null> {\n const snapshot = await this.store.getSnapshot(noteId, timestamp);\n const existing = await this.store.getNote(noteId);\n if (!snapshot || !existing) return null;\n await this.maybeSaveSnapshot(existing, 'restore');\n this.lastSnapshotAt.set(noteId, Date.now());\n await this.store.pruneSnapshots(noteId, MAX_SNAPSHOTS_PER_NOTE);\n return this.store.updateNote(noteId, { title: snapshot.title, markdown: snapshot.markdown, tags: snapshot.tags, kind: snapshot.kind, status: snapshot.status });\n }\n\n async flush(): Promise<void> { await this.store.flush(); }\n async moveToGroup(noteId: string, groupId: string | null): Promise<Note | null> { return this.updateNote(noteId, { groupId: groupId ?? undefined }); }\n\n async createTask(title: string, source: CaptureSource, opts: { dueAt?: number; priority?: 'high' | 'medium' | 'low'; sourceSessionKey?: string; sourceNoteId?: string; groupId?: string } = {}): Promise<Note> {\n return this.createNote({\n title,\n markdown: `- [ ] ${title}`,\n kind: 'task',\n capturedVia: source,\n groupId: opts.groupId,\n taskMeta: { done: false, dueAt: opts.dueAt, priority: opts.priority, sourceSessionKey: opts.sourceSessionKey, sourceNoteId: opts.sourceNoteId },\n });\n }\n\n async toggleTaskDone(noteId: string): Promise<Note | null> {\n const note = await this.store.getNote(noteId);\n if (!note || note.kind !== 'task') return null;\n const done = !note.taskMeta?.done;\n const markdown = note.markdown.replace(/^- \\[[ xX]\\]/m, `- [${done ? 'x' : ' '}]`);\n return this.updateNote(noteId, { markdown, taskMeta: { ...note.taskMeta, done } });\n }\n\n async updateTaskMeta(noteId: string, patch: Partial<import('./types.js').NoteTaskMeta>): Promise<Note | null> {\n const note = await this.store.getNote(noteId);\n if (!note || note.kind !== 'task') return null;\n return this.updateNote(noteId, { taskMeta: { ...note.taskMeta, done: note.taskMeta?.done ?? false, ...patch } });\n }\n\n async recordOpen(noteId: string): Promise<Note | null> {\n return this.updateNote(noteId, { lastOpenedAt: Date.now() } as Partial<Note>);\n }\n\n private async maybeSaveSnapshot(note: Note, trigger: SnapshotTrigger): Promise<void> {\n if (trigger !== 'edit') {\n await this.store.saveSnapshot(note, trigger);\n this.lastSnapshotAt.set(note.id, Date.now());\n await this.store.pruneSnapshots(note.id, MAX_SNAPSHOTS_PER_NOTE);\n return;\n }\n const last = this.lastSnapshotAt.get(note.id) ?? 0;\n if (Date.now() - last < SNAPSHOT_THROTTLE_MS) return;\n await this.store.saveSnapshot(note, trigger);\n this.lastSnapshotAt.set(note.id, Date.now());\n await this.store.pruneSnapshots(note.id, MAX_SNAPSHOTS_PER_NOTE);\n }\n}\n\nexport { buildNoteAttachmentRef };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service.js","names":[],"sources":["../../../src/notes/service.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { type UserMessage } from '@earendil-works/pi-ai/compat';\n\nimport { changedFieldsFromPatch, emitActivity, previewText, systemActivityActor, systemActivitySource } from '../activity/emitter.js';\nimport { publishAutomationProductEvent } from '../automations/product-events.js';\nimport type { Config } from '../config/schema.js';\nimport { getDefaultModelSync, resolveModel } from '../providers/index.js';\nimport { completeWithResolvedCredentials } from '../providers/model-call.js';\nimport { createLogger } from '../utils/logger.js';\nimport { buildNoteAttachmentRef } from './attachment-ref.js';\nimport { partitionAttachmentsByReference } from './note-attachment-sync.js';\nimport { parseNoteMarkdown } from './note-markdown.js';\nimport { buildNoteAgentContextArtifact, getCachedNoteAgentContextArtifact } from './agent-context.js';\nimport { NotesStore } from './store.js';\nimport type {\n CaptureSource,\n CreateNoteParams,\n Note,\n NoteAiPatch,\n NoteAttachment,\n NoteCatalysisAction,\n NoteCatalysisMeta,\n NoteCatalysisReport,\n NoteIndexEntry,\n NoteKind,\n NoteSnapshot,\n NoteSnapshotEntry,\n NotesListQuery,\n SnapshotTrigger,\n} from './types.js';\n\nconst log = createLogger('NotesService');\nconst MAX_SNAPSHOTS_PER_NOTE = 50;\nconst SNAPSHOT_THROTTLE_MS = 60_000;\n\nfunction inferKind(markdown?: string, hasAttachments?: boolean, attachments?: NoteAttachment[]): NoteKind {\n if (hasAttachments && attachments?.length && attachments.every((item) => item.type === 'audio')) return 'voice';\n if (hasAttachments) return 'media';\n if (!markdown) return 'thought';\n const lower = markdown.toLowerCase();\n if (/^(todo|task|remind|buy|call|email|meet|finish|submit|send)\\b/i.test(lower) || /\\b(明天|今天|记得|别忘|待办|提醒)\\b/.test(markdown)) return 'todo';\n if (/^https?:\\/\\//.test(markdown.trim())) return 'bookmark';\n return 'thought';\n}\n\nfunction deriveDefaultTitle(markdown?: string): string | undefined {\n const normalized = parseNoteMarkdown(markdown ?? '').plainText.trim().replace(/\\s+/g, ' ');\n return normalized ? Array.from(normalized).slice(0, 10).join('') : undefined;\n}\n\nfunction splitMeaningfulLines(markdown?: string): string[] {\n return parseNoteMarkdown(markdown ?? '').plainText.split(/\\n|。|;|;/).map((line) => line.trim()).filter(Boolean);\n}\n\nfunction summarizeIdea(markdown?: string): string {\n const lines = splitMeaningfulLines(markdown);\n return lines.slice(0, 3).join(';').slice(0, 140);\n}\n\nfunction publishNoteEvent(\n type: 'note.created' | 'note.updated',\n note: Note,\n extra?: Record<string, unknown>,\n): void {\n publishAutomationProductEvent({\n type,\n source: 'notes',\n payload: {\n noteId: note.id,\n kind: note.kind,\n status: note.status,\n title: note.title,\n capturedVia: note.capturedVia,\n tagCount: note.tags?.length ?? 0,\n hasAttachments: Boolean(note.attachments?.length),\n ...extra,\n },\n });\n}\n\nfunction inferCatalysisStage(note: Note): NonNullable<NoteCatalysisMeta['stage']> {\n const text = `${note.title ?? ''}\\n${note.markdown}`;\n if (/上线|发布|launch|ship/i.test(text)) return 'shipped';\n if (/验证|访谈|用户|测试|validate/i.test(text)) return 'validating';\n if (/开发|实现|构建|build|mvp/i.test(text)) return 'developing';\n if (/想法|机会|问题|idea|seed/i.test(text)) return 'seed';\n return 'incubating';\n}\n\nfunction buildCatalysisReport(note: Note): NoteCatalysisReport {\n const summary = summarizeIdea(note.markdown || note.title);\n const title = note.title?.trim() || summary.slice(0, 28) || '未命名想法';\n const actions: NoteCatalysisAction[] = [\n { kind: 'research', text: `验证「${title}」的真实需求和目标用户` },\n { kind: 'task', text: `拆解「${title}」的最小可行下一步` },\n { kind: 'chat', text: `继续和 AI 讨论「${title}」的方案` },\n ];\n return {\n originalNoteId: note.id,\n generatedAt: Date.now(),\n title,\n valueHypothesis: summary || '这条笔记可能包含一个待澄清的想法。',\n targetUsers: ['待确认的核心用户'],\n keyQuestions: ['用户为什么现在需要它?', '最小可验证版本是什么?', '如何判断它值得继续投入?'],\n mvpPath: ['定义目标用户', '写出最小场景', '完成一次验证'],\n risks: ['需求不够明确', '执行路径过大'],\n nextActions: actions,\n confidence: summary ? 0.58 : 0.35,\n };\n}\n\nfunction normalizeAiCatalysisReport(note: Note, data: Record<string, unknown>): NoteCatalysisReport {\n const fallback = buildCatalysisReport(note);\n const stringArray = (value: unknown, fallbackValue: string[]) => Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string').slice(0, 12) : fallbackValue;\n const actions = Array.isArray(data.nextActions)\n ? data.nextActions.map((item): NoteCatalysisAction | null => {\n if (!item || typeof item !== 'object') return null;\n const row = item as { kind?: unknown; text?: unknown };\n const kind = row.kind === 'task' || row.kind === 'workflow' || row.kind === 'research' || row.kind === 'share' || row.kind === 'chat' ? row.kind : 'task';\n return typeof row.text === 'string' && row.text.trim() ? { kind, text: row.text.trim() } : null;\n }).filter((item): item is NoteCatalysisAction => Boolean(item)).slice(0, 12)\n : fallback.nextActions;\n return {\n originalNoteId: note.id,\n generatedAt: Date.now(),\n title: typeof data.title === 'string' && data.title.trim() ? data.title.trim() : fallback.title,\n valueHypothesis: typeof data.valueHypothesis === 'string' && data.valueHypothesis.trim() ? data.valueHypothesis.trim() : fallback.valueHypothesis,\n targetUsers: stringArray(data.targetUsers, fallback.targetUsers),\n keyQuestions: stringArray(data.keyQuestions, fallback.keyQuestions),\n mvpPath: stringArray(data.mvpPath, fallback.mvpPath),\n risks: stringArray(data.risks, fallback.risks),\n nextActions: actions,\n confidence: typeof data.confidence === 'number' ? Math.max(0, Math.min(1, data.confidence)) : fallback.confidence,\n };\n}\n\nfunction buildCatalysisPrompt(note: Note): string {\n const title = note.title?.trim() || '未命名笔记';\n const markdown = note.markdown.trim() || '(无正文)';\n return `请把下面的 Markdown 笔记催化成可执行的想法报告,输出 JSON:\\n{\\n \"title\": string,\\n \"valueHypothesis\": string,\\n \"targetUsers\": string[],\\n \"keyQuestions\": string[],\\n \"mvpPath\": string[],\\n \"risks\": string[],\\n \"nextActions\": [{\"text\": string, \"kind\": \"task\"|\"workflow\"|\"research\"|\"share\"|\"chat\"}],\\n \"confidence\": number\\n}\\n\\n标题:${title}\\n\\nMarkdown:\\n${markdown}`;\n}\n\nasync function buildAiCatalysisReport(note: Note, config?: Config): Promise<NoteCatalysisReport> {\n const modelRef = getDefaultModelSync(config);\n if (!modelRef) {\n throw new Error('No global default model configured');\n }\n const resolved = resolveModel(modelRef);\n const messages: UserMessage[] = [{ role: 'user', content: buildCatalysisPrompt(note), timestamp: Date.now() }];\n const response = await completeWithResolvedCredentials(resolved, { messages }, { temperature: 0.2 });\n let responseText = '';\n if (Array.isArray(response.content)) {\n for (const part of response.content) {\n if (part && typeof part === 'object' && (part as { type?: string }).type === 'text') {\n responseText += String((part as { text?: string }).text || '');\n }\n }\n }\n const raw = responseText.trim().replace(/^```json\\s*/i, '').replace(/```$/i, '').trim();\n return normalizeAiCatalysisReport(note, JSON.parse(raw) as Record<string, unknown>);\n}\n\nexport class NotesService {\n private lastSnapshotAt = new Map<string, number>();\n\n constructor(private readonly store = new NotesStore()) {}\n\n async initialize(): Promise<void> {\n await this.store.initialize();\n }\n\n async quickCapture(markdown: string, source: CaptureSource): Promise<Note> {\n const id = randomUUID();\n const now = Date.now();\n const note: Note = {\n id,\n title: deriveDefaultTitle(markdown),\n kind: inferKind(markdown),\n status: 'inbox',\n markdown,\n createdAt: now,\n updatedAt: now,\n capturedVia: source,\n remoteVersion: 1,\n localVersion: 1,\n };\n await this.store.addNote(note);\n emitActivity({\n type: 'note.created',\n primaryObject: { kind: 'note', id: note.id, title: note.title },\n actor: systemActivityActor(),\n source: systemActivitySource(),\n payload: {\n title: note.title,\n kind: note.kind,\n tags: note.tags,\n contentPreview: previewText(note.markdown),\n contentLength: note.markdown.length,\n },\n nowMs: note.createdAt,\n });\n log.debug({ id: note.id, kind: note.kind }, 'Quick capture');\n return note;\n }\n\n async createNote(params: CreateNoteParams): Promise<Note> {\n const id = randomUUID();\n const now = Date.now();\n const markdown = params.markdown ?? '';\n const note: Note = {\n id,\n title: params.title ?? deriveDefaultTitle(markdown),\n kind: params.kind ?? inferKind(markdown),\n status: 'inbox',\n markdown,\n attachments: [],\n createdAt: now,\n updatedAt: now,\n capturedVia: params.capturedVia,\n tags: params.tags,\n pinned: params.pinned,\n groupId: params.groupId,\n taskMeta: params.taskMeta,\n remoteVersion: 1,\n localVersion: 1,\n };\n await this.store.addNote(note);\n emitActivity({\n type: 'note.created',\n primaryObject: { kind: 'note', id: note.id, title: note.title },\n actor: systemActivityActor(),\n source: systemActivitySource(),\n payload: {\n title: note.title,\n kind: note.kind,\n tags: note.tags,\n contentPreview: previewText(note.markdown),\n contentLength: note.markdown.length,\n },\n nowMs: note.createdAt,\n });\n publishNoteEvent('note.created', note);\n log.debug({ id: note.id, kind: note.kind }, 'Note created');\n return note;\n }\n\n async getNote(id: string): Promise<Note | null> {\n return this.store.getNote(id);\n }\n\n async updateNote(id: string, patch: Partial<Note>, trigger: SnapshotTrigger = 'edit'): Promise<Note | null> {\n const existing = await this.store.getNote(id);\n if (!existing) return null;\n const contentTouched = patch.markdown !== undefined || patch.title !== undefined;\n if (contentTouched) await this.maybeSaveSnapshot(existing, trigger);\n\n const normalizedPatch: Partial<Note> = { ...patch };\n if (patch.markdown !== undefined) {\n normalizedPatch.kind = patch.kind ?? inferKind(patch.markdown, Boolean(existing.attachments?.length), existing.attachments);\n }\n if (contentTouched || patch.attachments) {\n normalizedPatch.remoteVersion = (existing.remoteVersion ?? 1) + 1;\n normalizedPatch.localVersion = patch.localVersion ?? (existing.localVersion ?? 1) + 1;\n }\n\n const updatedRaw = await this.store.updateNote(id, normalizedPatch);\n const updated = updatedRaw ? await this.reconcileAttachments(updatedRaw) : null;\n if (updated) {\n const changes = changedFieldsFromPatch(patch as Record<string, unknown>);\n emitActivity({\n type: existing.status !== updated.status ? 'note.status_changed' : 'note.updated',\n primaryObject: { kind: 'note', id: updated.id, title: updated.title },\n actor: systemActivityActor(),\n source: systemActivitySource(),\n payload: {\n changes,\n contentTouched,\n ...(existing.status !== updated.status ? { from: existing.status, to: updated.status } : {}),\n },\n nowMs: updated.updatedAt,\n });\n publishNoteEvent('note.updated', updated, {\n contentTouched,\n trigger,\n });\n }\n return updated;\n }\n\n private async reconcileAttachments(note: Note): Promise<Note> {\n const { kept, removed } = partitionAttachmentsByReference(note);\n if (removed.length === 0) return note;\n for (const attachment of removed) await this.store.deleteAttachmentFile(note.id, attachment.relativePath);\n log.debug({ noteId: note.id, removedIds: removed.map((attachment) => attachment.id) }, 'Pruned orphan note attachments');\n const hasAttachments = kept.length > 0;\n const updated = await this.store.updateNote(note.id, { attachments: kept, kind: inferKind(note.markdown, hasAttachments, kept) });\n return updated ?? { ...note, attachments: kept };\n }\n\n async syncNote(id: string, patch: Partial<Note>, baseRemoteVersion?: number): Promise<{ note: Note | null; conflict: boolean }> {\n const existing = await this.store.getNote(id);\n if (!existing) return { note: null, conflict: false };\n if (baseRemoteVersion !== undefined && existing.remoteVersion !== undefined && baseRemoteVersion < existing.remoteVersion) {\n return { note: existing, conflict: true };\n }\n const updated = await this.updateNote(id, patch, 'sync');\n return { note: updated, conflict: false };\n }\n\n async createAiEditPatch(id: string, instruction: string, markdownOverride?: string): Promise<{ message: string; patch: NoteAiPatch } | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const source = markdownOverride ?? note.markdown;\n const parsed = parseNoteMarkdown(source, id);\n const wantsTodos = /待办|todo|task|行动|提醒/i.test(instruction);\n const wantsSummary = /摘要|总结|summary|压缩/i.test(instruction);\n let generated = '';\n if (wantsTodos) {\n const lines = source.split(/\\n|。|;|;/).map((line) => line.trim()).filter(Boolean);\n generated = (lines.length ? lines : [parsed.plainText]).slice(0, 12).map((line) => `- [ ] ${line.replace(/^[-*\\d.\\s\\[\\]x]+/i, '').trim()}`).join('\\n');\n } else if (wantsSummary) {\n generated = `> [!SUMMARY]\\n> ${parsed.plainText.slice(0, 220)}`;\n } else {\n generated = `${source.trimEnd()}\\n\\n## AI 整理\\n\\n${instruction.trim()}`;\n }\n return {\n message: 'AI edit patch generated',\n patch: {\n id: randomUUID(),\n summary: instruction,\n operations: [{ type: 'replaceRange', from: 0, to: source.length, markdown: generated || source }],\n },\n };\n }\n\n async catalyzeNote(id: string, config?: Config): Promise<{ note: Note; report: NoteCatalysisReport } | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n let report: NoteCatalysisReport;\n try {\n report = await buildAiCatalysisReport(note, config);\n } catch (err) {\n log.warn({ err, noteId: id }, 'AI note catalysis failed; using local fallback report');\n report = buildCatalysisReport(note);\n }\n const updated = await this.updateNote(id, {\n aiDeep: {\n ...note.aiDeep,\n processedAt: Date.now(),\n catalysis: {\n status: 'catalyzed',\n stage: inferCatalysisStage(note),\n lastCatalyzedAt: Date.now(),\n confidence: report.confidence,\n report,\n ...note.aiDeep?.catalysis,\n },\n },\n ai: { ...note.ai, intent: note.ai?.intent ?? 'idea', summary: note.ai?.summary ?? report.valueHypothesis },\n status: note.status === 'inbox' ? 'processed' : note.status,\n }, 'ai_edit');\n return updated ? { note: updated, report } : null;\n }\n\n async recordCatalysisFeedback(id: string, feedback: 'helpful' | 'not_helpful' | 'neutral'): Promise<Note | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n return this.updateNote(id, { aiDeep: { ...note.aiDeep, processedAt: Date.now(), catalysis: { status: note.aiDeep?.catalysis?.status ?? 'catalyzed', ...note.aiDeep?.catalysis, feedback } } });\n }\n\n async linkNoteThread(id: string, sessionKey: string): Promise<Note | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const existingKeys = note.aiDeep?.catalysis?.linkedSessionKeys ?? [];\n return this.updateNote(id, {\n aiDeep: {\n ...note.aiDeep,\n processedAt: Date.now(),\n catalysis: {\n status: note.aiDeep?.catalysis?.status ?? 'none',\n ...note.aiDeep?.catalysis,\n sourceSessionKey: note.aiDeep?.catalysis?.sourceSessionKey ?? sessionKey,\n linkedSessionKeys: Array.from(new Set([...existingKeys, sessionKey])),\n },\n },\n }, 'sync');\n }\n\n async listNoteThreads(id: string): Promise<string[] | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n return Array.from(new Set([note.aiDeep?.catalysis?.sourceSessionKey, ...(note.aiDeep?.catalysis?.linkedSessionKeys ?? [])].filter((key): key is string => Boolean(key))));\n }\n\n async getAgentContextStatus(id: string, config?: Config, force = false): Promise<{ noteUpdatedAt: number; artifact: import('./agent-context.js').NoteAgentContextArtifact | null; stale: boolean } | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const cached = getCachedNoteAgentContextArtifact(id);\n if (!force && cached && cached.noteUpdatedAt === note.updatedAt) {\n return { noteUpdatedAt: note.updatedAt, artifact: cached, stale: false };\n }\n const artifact = await buildNoteAgentContextArtifact({ note, notesService: this, config, force });\n return { noteUpdatedAt: note.updatedAt, artifact, stale: false };\n }\n\n async appendTextToNote(id: string, content: string, heading = 'AI 讨论沉淀'): Promise<Note | null> {\n const note = await this.store.getNote(id);\n if (!note) return null;\n const trimmed = content.trim();\n if (!trimmed) return note;\n const current = note.markdown.trimEnd();\n const nextMarkdown = `${current}${current ? '\\n\\n' : ''}## ${heading}\\n\\n${trimmed}\\n`;\n return this.updateNote(id, { markdown: nextMarkdown }, 'ai_edit');\n }\n\n async deleteNote(id: string): Promise<boolean> {\n const removed = await this.store.deleteNote(id);\n if (removed) await this.store.deleteAllSnapshots(id);\n return removed;\n }\n\n async listNotes(query: NotesListQuery = {}): Promise<{ items: NoteIndexEntry[]; total: number; limit: number; offset: number; hasMore: boolean }> {\n return this.store.listNotes(query);\n }\n\n async addAttachment(noteId: string, file: { name: string; buffer: Buffer; mimeType: string; duration?: number }): Promise<NoteAttachment | null> {\n const note = await this.store.getNote(noteId);\n if (!note) return null;\n const { relativePath, size } = await this.store.saveAttachment(noteId, file.name, file.buffer);\n const attachment: NoteAttachment = {\n id: randomUUID(),\n type: file.mimeType.startsWith('image/') ? 'image' : file.mimeType.startsWith('audio/') ? 'audio' : file.mimeType.startsWith('video/') ? 'video' : 'file',\n mimeType: file.mimeType,\n fileName: file.name,\n size,\n relativePath,\n duration: file.duration,\n };\n const attachments = [...(note.attachments || []), attachment];\n const kind = note.kind === 'thought' && attachment.type === 'audio' ? 'voice' : note.kind === 'thought' ? 'media' : note.kind;\n await this.store.updateNote(noteId, { attachments, kind });\n return attachment;\n }\n\n async getAttachmentPath(noteId: string, attachmentId: string): Promise<{ filePath: string; mimeType: string; fileName: string } | null> {\n const note = await this.store.getNote(noteId);\n if (!note) return null;\n const attachment = note.attachments?.find((a) => a.id === attachmentId);\n if (!attachment) return null;\n return { filePath: this.store.resolveAttachmentPath(noteId, attachment.relativePath), mimeType: attachment.mimeType, fileName: attachment.fileName };\n }\n\n async listNoteHistory(noteId: string): Promise<NoteSnapshotEntry[]> { return this.store.listSnapshots(noteId); }\n async getNoteSnapshot(noteId: string, timestamp: number): Promise<NoteSnapshot | null> { return this.store.getSnapshot(noteId, timestamp); }\n\n async restoreNoteSnapshot(noteId: string, timestamp: number): Promise<Note | null> {\n const snapshot = await this.store.getSnapshot(noteId, timestamp);\n const existing = await this.store.getNote(noteId);\n if (!snapshot || !existing) return null;\n await this.maybeSaveSnapshot(existing, 'restore');\n this.lastSnapshotAt.set(noteId, Date.now());\n await this.store.pruneSnapshots(noteId, MAX_SNAPSHOTS_PER_NOTE);\n return this.store.updateNote(noteId, { title: snapshot.title, markdown: snapshot.markdown, tags: snapshot.tags, kind: snapshot.kind, status: snapshot.status });\n }\n\n async flush(): Promise<void> { await this.store.flush(); }\n async moveToGroup(noteId: string, groupId: string | null): Promise<Note | null> { return this.updateNote(noteId, { groupId: groupId ?? undefined }); }\n\n async createTask(title: string, source: CaptureSource, opts: { dueAt?: number; priority?: 'high' | 'medium' | 'low'; sourceSessionKey?: string; sourceNoteId?: string; groupId?: string } = {}): Promise<Note> {\n return this.createNote({\n title,\n markdown: `- [ ] ${title}`,\n kind: 'task',\n capturedVia: source,\n groupId: opts.groupId,\n taskMeta: { done: false, dueAt: opts.dueAt, priority: opts.priority, sourceSessionKey: opts.sourceSessionKey, sourceNoteId: opts.sourceNoteId },\n });\n }\n\n async toggleTaskDone(noteId: string): Promise<Note | null> {\n const note = await this.store.getNote(noteId);\n if (!note || note.kind !== 'task') return null;\n const done = !note.taskMeta?.done;\n const markdown = note.markdown.replace(/^- \\[[ xX]\\]/m, `- [${done ? 'x' : ' '}]`);\n return this.updateNote(noteId, { markdown, taskMeta: { ...note.taskMeta, done } });\n }\n\n async updateTaskMeta(noteId: string, patch: Partial<import('./types.js').NoteTaskMeta>): Promise<Note | null> {\n const note = await this.store.getNote(noteId);\n if (!note || note.kind !== 'task') return null;\n return this.updateNote(noteId, { taskMeta: { ...note.taskMeta, done: note.taskMeta?.done ?? false, ...patch } });\n }\n\n async recordOpen(noteId: string): Promise<Note | null> {\n return this.updateNote(noteId, { lastOpenedAt: Date.now() } as Partial<Note>);\n }\n\n private async maybeSaveSnapshot(note: Note, trigger: SnapshotTrigger): Promise<void> {\n if (trigger !== 'edit') {\n await this.store.saveSnapshot(note, trigger);\n this.lastSnapshotAt.set(note.id, Date.now());\n await this.store.pruneSnapshots(note.id, MAX_SNAPSHOTS_PER_NOTE);\n return;\n }\n const last = this.lastSnapshotAt.get(note.id) ?? 0;\n if (Date.now() - last < SNAPSHOT_THROTTLE_MS) return;\n await this.store.saveSnapshot(note, trigger);\n this.lastSnapshotAt.set(note.id, Date.now());\n await this.store.pruneSnapshots(note.id, MAX_SNAPSHOTS_PER_NOTE);\n }\n}\n\nexport { buildNoteAttachmentRef };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
//#region src/providers/constants.ts
|
|
3
|
+
var EXTENSION_PROVIDER_BASE_URL;
|
|
4
|
+
var init_constants = __esmMin((() => {
|
|
5
|
+
EXTENSION_PROVIDER_BASE_URL = "extension://provider-plugin";
|
|
6
|
+
}));
|
|
7
|
+
//#endregion
|
|
8
|
+
init_constants();
|
|
9
|
+
export { EXTENSION_PROVIDER_BASE_URL, init_constants };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/providers/constants.ts"],"sourcesContent":["/** Sentinel base URL: model is served by an extension {@link ProviderPluginRegistry} provider. */\nexport const EXTENSION_PROVIDER_BASE_URL = 'extension://provider-plugin';\n"],"mappings":";;;;AACa,+BAA8B"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import "./constants.js";
|
|
3
4
|
import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
|
|
4
5
|
import { init_providers } from "./index.js";
|
|
5
6
|
import { createAssistantMessageEventStream, streamSimple } from "@earendil-works/pi-ai/compat";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-stream-bridge.js","names":[],"sources":["../../../src/providers/extension-stream-bridge.ts"],"sourcesContent":["import {\n\tstreamSimple,\n\tcreateAssistantMessageEventStream,\n\ttype AssistantMessage,\n\ttype Model,\n\ttype Api,\n\ttype Context,\n\ttype SimpleStreamOptions,\n} from '@earendil-works/pi-ai/compat';\nimport type { StreamFn } from '@earendil-works/pi-agent-core';\nimport type { ProviderStreamParams } from '../extensions/types/providers.js';\nimport { getProviderRegistry } from './plugin-registry.js';\nimport { EXTENSION_PROVIDER_BASE_URL } from './index.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('ExtensionStreamBridge');\n\nfunction createPartialMessage(model: Model<Api>): AssistantMessage {\n\treturn {\n\t\trole: 'assistant',\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: 'stop',\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction parseToolArguments(raw: string | undefined): Record<string, unknown> {\n\tif (!raw?.trim()) return {};\n\ttry {\n\t\treturn JSON.parse(raw) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction collectExtraStreamOptions(options?: SimpleStreamOptions): Record<string, unknown> | undefined {\n\tif (!options) return undefined;\n\tconst knownOptionKeys = new Set([\n\t\t'temperature',\n\t\t'maxTokens',\n\t\t'signal',\n\t\t'apiKey',\n\t\t'transport',\n\t\t'cacheRetention',\n\t\t'sessionId',\n\t\t'onPayload',\n\t\t'onResponse',\n\t\t'headers',\n\t\t'timeoutMs',\n\t\t'maxRetries',\n\t\t'maxRetryDelayMs',\n\t\t'metadata',\n\t\t'reasoning',\n\t\t'thinkingBudgets',\n\t]);\n\tconst entries = Object.entries(options as Record<string, unknown>).filter(([key, value]) => {\n\t\treturn !knownOptionKeys.has(key) && value !== undefined;\n\t});\n\treturn entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\n/** Wraps {@link streamSimple} so extension-registered models use the plugin `createStream()` path. */\nexport function createExtensionAwareStreamFn(): StreamFn {\n\treturn ((model: Model<Api>, context: Context, options?: SimpleStreamOptions) => {\n\t\tif (model.baseUrl !== EXTENSION_PROVIDER_BASE_URL) {\n\t\t\treturn streamSimple(model, context, options);\n\t\t}\n\n\t\tconst plugin = getProviderRegistry().get(model.provider);\n\t\tif (!plugin) {\n\t\t\treturn streamSimple(model, context, options);\n\t\t}\n\n\t\tlog.info({ provider: model.provider, modelId: model.id }, 'Streaming via extension provider');\n\n\t\tconst stream = createAssistantMessageEventStream();\n\n\t\tconst params: ProviderStreamParams = {\n\t\t\tmodel: model.id,\n\t\t\tsystemPrompt: context.systemPrompt,\n\t\t\tmessages: context.messages as unknown as ProviderStreamParams['messages'],\n\t\t\ttools: context.tools as unknown as ProviderStreamParams['tools'],\n\t\t\ttemperature: options?.temperature,\n\t\t\tmaxTokens: options?.maxTokens,\n\t\t\tapiKey: options?.apiKey,\n\t\t\tsessionId: options?.sessionId,\n\t\t\treasoning: options?.reasoning,\n\t\t\theaders: options?.headers,\n\t\t\ttimeoutMs: options?.timeoutMs,\n\t\t\tmaxRetries: options?.maxRetries,\n\t\t\tmetadata: options?.metadata,\n\t\t\tcacheRetention: options?.cacheRetention,\n\t\t\ttransport: options?.transport,\n\t\t\tthinkingBudgets: options?.thinkingBudgets,\n\t\t\textra: collectExtraStreamOptions(options),\n\t\t\tsignal: options?.signal,\n\t\t};\n\n\t\tvoid (async () => {\n\t\t\tconst partial = createPartialMessage(model);\n\t\t\tlet textContentIndex = -1;\n\t\t\tlet hasStarted = false;\n\n\t\t\ttry {\n\t\t\t\tfor await (const chunk of plugin.createStream(params)) {\n\t\t\t\t\tif (options?.signal?.aborted) {\n\t\t\t\t\t\tpartial.stopReason = 'aborted';\n\t\t\t\t\t\tpartial.errorMessage = 'Request aborted';\n\t\t\t\t\t\tstream.push({ type: 'error', reason: 'aborted', error: partial });\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (chunk.type) {\n\t\t\t\t\t\tcase 'text': {\n\t\t\t\t\t\t\tif (!hasStarted) {\n\t\t\t\t\t\t\t\thasStarted = true;\n\t\t\t\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (textContentIndex === -1) {\n\t\t\t\t\t\t\t\ttextContentIndex = partial.content.length;\n\t\t\t\t\t\t\t\tpartial.content.push({ type: 'text', text: '' });\n\t\t\t\t\t\t\t\tstream.push({ type: 'text_start', contentIndex: textContentIndex, partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst textContent = partial.content[textContentIndex];\n\t\t\t\t\t\t\tif (textContent?.type === 'text' && chunk.text) {\n\t\t\t\t\t\t\t\ttextContent.text += chunk.text;\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: 'text_delta',\n\t\t\t\t\t\t\t\t\tcontentIndex: textContentIndex,\n\t\t\t\t\t\t\t\t\tdelta: chunk.text,\n\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'tool_call': {\n\t\t\t\t\t\t\tif (!hasStarted) {\n\t\t\t\t\t\t\t\thasStarted = true;\n\t\t\t\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (textContentIndex !== -1) {\n\t\t\t\t\t\t\t\tconst tc = partial.content[textContentIndex];\n\t\t\t\t\t\t\t\tif (tc?.type === 'text') {\n\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\ttype: 'text_end',\n\t\t\t\t\t\t\t\t\t\tcontentIndex: textContentIndex,\n\t\t\t\t\t\t\t\t\t\tcontent: tc.text,\n\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttextContentIndex = -1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (chunk.toolCall) {\n\t\t\t\t\t\t\t\tconst idx = partial.content.length;\n\t\t\t\t\t\t\t\tconst toolCall = {\n\t\t\t\t\t\t\t\t\ttype: 'toolCall' as const,\n\t\t\t\t\t\t\t\t\tid: chunk.toolCall.id,\n\t\t\t\t\t\t\t\t\tname: chunk.toolCall.name,\n\t\t\t\t\t\t\t\t\targuments: parseToolArguments(chunk.toolCall.arguments),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tpartial.content.push(toolCall);\n\t\t\t\t\t\t\t\tstream.push({ type: 'toolcall_start', contentIndex: idx, partial });\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: 'toolcall_delta',\n\t\t\t\t\t\t\t\t\tcontentIndex: idx,\n\t\t\t\t\t\t\t\t\tdelta: chunk.toolCall.arguments || '{}',\n\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tstream.push({ type: 'toolcall_end', contentIndex: idx, toolCall, partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'usage': {\n\t\t\t\t\t\t\tif (chunk.usage) {\n\t\t\t\t\t\t\t\tconst inputCost = (chunk.usage.input / 1_000_000) * (model.cost?.input ?? 0);\n\t\t\t\t\t\t\t\tconst outputCost = (chunk.usage.output / 1_000_000) * (model.cost?.output ?? 0);\n\t\t\t\t\t\t\t\tpartial.usage = {\n\t\t\t\t\t\t\t\t\tinput: chunk.usage.input,\n\t\t\t\t\t\t\t\t\toutput: chunk.usage.output,\n\t\t\t\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\t\t\ttotalTokens: chunk.usage.total ?? chunk.usage.input + chunk.usage.output,\n\t\t\t\t\t\t\t\t\tcost: {\n\t\t\t\t\t\t\t\t\t\tinput: inputCost,\n\t\t\t\t\t\t\t\t\t\toutput: outputCost,\n\t\t\t\t\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\t\t\t\ttotal: inputCost + outputCost,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'error': {\n\t\t\t\t\t\t\tif (!hasStarted) {\n\t\t\t\t\t\t\t\thasStarted = true;\n\t\t\t\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpartial.stopReason = 'error';\n\t\t\t\t\t\t\tpartial.errorMessage = chunk.error ?? 'Unknown extension provider error';\n\t\t\t\t\t\t\tstream.push({ type: 'error', reason: 'error', error: partial });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'done':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (textContentIndex !== -1) {\n\t\t\t\t\tconst tc = partial.content[textContentIndex];\n\t\t\t\t\tif (tc?.type === 'text') {\n\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\ttype: 'text_end',\n\t\t\t\t\t\t\tcontentIndex: textContentIndex,\n\t\t\t\t\t\t\tcontent: tc.text,\n\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!hasStarted) {\n\t\t\t\t\thasStarted = true;\n\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t}\n\n\t\t\t\tconst hasToolCalls = partial.content.some(c => c.type === 'toolCall');\n\t\t\t\tconst stopReason = hasToolCalls ? 'toolUse' : 'stop';\n\t\t\t\tpartial.stopReason = stopReason;\n\t\t\t\tstream.push({ type: 'done', reason: stopReason, message: partial });\n\t\t\t} catch (err) {\n\t\t\t\tif (!hasStarted) stream.push({ type: 'start', partial });\n\t\t\t\tpartial.stopReason = 'error';\n\t\t\t\tpartial.errorMessage = err instanceof Error ? err.message : String(err);\n\t\t\t\tstream.push({ type: 'error', reason: 'error', error: partial });\n\t\t\t}\n\t\t})();\n\n\t\treturn stream;\n\t}) as StreamFn;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extension-stream-bridge.js","names":[],"sources":["../../../src/providers/extension-stream-bridge.ts"],"sourcesContent":["import {\n\tstreamSimple,\n\tcreateAssistantMessageEventStream,\n\ttype AssistantMessage,\n\ttype Model,\n\ttype Api,\n\ttype Context,\n\ttype SimpleStreamOptions,\n} from '@earendil-works/pi-ai/compat';\nimport type { StreamFn } from '@earendil-works/pi-agent-core';\nimport type { ProviderStreamParams } from '../extensions/types/providers.js';\nimport { getProviderRegistry } from './plugin-registry.js';\nimport { EXTENSION_PROVIDER_BASE_URL } from './index.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('ExtensionStreamBridge');\n\nfunction createPartialMessage(model: Model<Api>): AssistantMessage {\n\treturn {\n\t\trole: 'assistant',\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: 'stop',\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction parseToolArguments(raw: string | undefined): Record<string, unknown> {\n\tif (!raw?.trim()) return {};\n\ttry {\n\t\treturn JSON.parse(raw) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction collectExtraStreamOptions(options?: SimpleStreamOptions): Record<string, unknown> | undefined {\n\tif (!options) return undefined;\n\tconst knownOptionKeys = new Set([\n\t\t'temperature',\n\t\t'maxTokens',\n\t\t'signal',\n\t\t'apiKey',\n\t\t'transport',\n\t\t'cacheRetention',\n\t\t'sessionId',\n\t\t'onPayload',\n\t\t'onResponse',\n\t\t'headers',\n\t\t'timeoutMs',\n\t\t'maxRetries',\n\t\t'maxRetryDelayMs',\n\t\t'metadata',\n\t\t'reasoning',\n\t\t'thinkingBudgets',\n\t]);\n\tconst entries = Object.entries(options as Record<string, unknown>).filter(([key, value]) => {\n\t\treturn !knownOptionKeys.has(key) && value !== undefined;\n\t});\n\treturn entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\n/** Wraps {@link streamSimple} so extension-registered models use the plugin `createStream()` path. */\nexport function createExtensionAwareStreamFn(): StreamFn {\n\treturn ((model: Model<Api>, context: Context, options?: SimpleStreamOptions) => {\n\t\tif (model.baseUrl !== EXTENSION_PROVIDER_BASE_URL) {\n\t\t\treturn streamSimple(model, context, options);\n\t\t}\n\n\t\tconst plugin = getProviderRegistry().get(model.provider);\n\t\tif (!plugin) {\n\t\t\treturn streamSimple(model, context, options);\n\t\t}\n\n\t\tlog.info({ provider: model.provider, modelId: model.id }, 'Streaming via extension provider');\n\n\t\tconst stream = createAssistantMessageEventStream();\n\n\t\tconst params: ProviderStreamParams = {\n\t\t\tmodel: model.id,\n\t\t\tsystemPrompt: context.systemPrompt,\n\t\t\tmessages: context.messages as unknown as ProviderStreamParams['messages'],\n\t\t\ttools: context.tools as unknown as ProviderStreamParams['tools'],\n\t\t\ttemperature: options?.temperature,\n\t\t\tmaxTokens: options?.maxTokens,\n\t\t\tapiKey: options?.apiKey,\n\t\t\tsessionId: options?.sessionId,\n\t\t\treasoning: options?.reasoning,\n\t\t\theaders: options?.headers,\n\t\t\ttimeoutMs: options?.timeoutMs,\n\t\t\tmaxRetries: options?.maxRetries,\n\t\t\tmetadata: options?.metadata,\n\t\t\tcacheRetention: options?.cacheRetention,\n\t\t\ttransport: options?.transport,\n\t\t\tthinkingBudgets: options?.thinkingBudgets,\n\t\t\textra: collectExtraStreamOptions(options),\n\t\t\tsignal: options?.signal,\n\t\t};\n\n\t\tvoid (async () => {\n\t\t\tconst partial = createPartialMessage(model);\n\t\t\tlet textContentIndex = -1;\n\t\t\tlet hasStarted = false;\n\n\t\t\ttry {\n\t\t\t\tfor await (const chunk of plugin.createStream(params)) {\n\t\t\t\t\tif (options?.signal?.aborted) {\n\t\t\t\t\t\tpartial.stopReason = 'aborted';\n\t\t\t\t\t\tpartial.errorMessage = 'Request aborted';\n\t\t\t\t\t\tstream.push({ type: 'error', reason: 'aborted', error: partial });\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (chunk.type) {\n\t\t\t\t\t\tcase 'text': {\n\t\t\t\t\t\t\tif (!hasStarted) {\n\t\t\t\t\t\t\t\thasStarted = true;\n\t\t\t\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (textContentIndex === -1) {\n\t\t\t\t\t\t\t\ttextContentIndex = partial.content.length;\n\t\t\t\t\t\t\t\tpartial.content.push({ type: 'text', text: '' });\n\t\t\t\t\t\t\t\tstream.push({ type: 'text_start', contentIndex: textContentIndex, partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst textContent = partial.content[textContentIndex];\n\t\t\t\t\t\t\tif (textContent?.type === 'text' && chunk.text) {\n\t\t\t\t\t\t\t\ttextContent.text += chunk.text;\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: 'text_delta',\n\t\t\t\t\t\t\t\t\tcontentIndex: textContentIndex,\n\t\t\t\t\t\t\t\t\tdelta: chunk.text,\n\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'tool_call': {\n\t\t\t\t\t\t\tif (!hasStarted) {\n\t\t\t\t\t\t\t\thasStarted = true;\n\t\t\t\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (textContentIndex !== -1) {\n\t\t\t\t\t\t\t\tconst tc = partial.content[textContentIndex];\n\t\t\t\t\t\t\t\tif (tc?.type === 'text') {\n\t\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\t\ttype: 'text_end',\n\t\t\t\t\t\t\t\t\t\tcontentIndex: textContentIndex,\n\t\t\t\t\t\t\t\t\t\tcontent: tc.text,\n\t\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttextContentIndex = -1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (chunk.toolCall) {\n\t\t\t\t\t\t\t\tconst idx = partial.content.length;\n\t\t\t\t\t\t\t\tconst toolCall = {\n\t\t\t\t\t\t\t\t\ttype: 'toolCall' as const,\n\t\t\t\t\t\t\t\t\tid: chunk.toolCall.id,\n\t\t\t\t\t\t\t\t\tname: chunk.toolCall.name,\n\t\t\t\t\t\t\t\t\targuments: parseToolArguments(chunk.toolCall.arguments),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tpartial.content.push(toolCall);\n\t\t\t\t\t\t\t\tstream.push({ type: 'toolcall_start', contentIndex: idx, partial });\n\t\t\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\t\t\ttype: 'toolcall_delta',\n\t\t\t\t\t\t\t\t\tcontentIndex: idx,\n\t\t\t\t\t\t\t\t\tdelta: chunk.toolCall.arguments || '{}',\n\t\t\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tstream.push({ type: 'toolcall_end', contentIndex: idx, toolCall, partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'usage': {\n\t\t\t\t\t\t\tif (chunk.usage) {\n\t\t\t\t\t\t\t\tconst inputCost = (chunk.usage.input / 1_000_000) * (model.cost?.input ?? 0);\n\t\t\t\t\t\t\t\tconst outputCost = (chunk.usage.output / 1_000_000) * (model.cost?.output ?? 0);\n\t\t\t\t\t\t\t\tpartial.usage = {\n\t\t\t\t\t\t\t\t\tinput: chunk.usage.input,\n\t\t\t\t\t\t\t\t\toutput: chunk.usage.output,\n\t\t\t\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\t\t\ttotalTokens: chunk.usage.total ?? chunk.usage.input + chunk.usage.output,\n\t\t\t\t\t\t\t\t\tcost: {\n\t\t\t\t\t\t\t\t\t\tinput: inputCost,\n\t\t\t\t\t\t\t\t\t\toutput: outputCost,\n\t\t\t\t\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\t\t\t\t\ttotal: inputCost + outputCost,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'error': {\n\t\t\t\t\t\t\tif (!hasStarted) {\n\t\t\t\t\t\t\t\thasStarted = true;\n\t\t\t\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tpartial.stopReason = 'error';\n\t\t\t\t\t\t\tpartial.errorMessage = chunk.error ?? 'Unknown extension provider error';\n\t\t\t\t\t\t\tstream.push({ type: 'error', reason: 'error', error: partial });\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'done':\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (textContentIndex !== -1) {\n\t\t\t\t\tconst tc = partial.content[textContentIndex];\n\t\t\t\t\tif (tc?.type === 'text') {\n\t\t\t\t\t\tstream.push({\n\t\t\t\t\t\t\ttype: 'text_end',\n\t\t\t\t\t\t\tcontentIndex: textContentIndex,\n\t\t\t\t\t\t\tcontent: tc.text,\n\t\t\t\t\t\t\tpartial,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!hasStarted) {\n\t\t\t\t\thasStarted = true;\n\t\t\t\t\tstream.push({ type: 'start', partial });\n\t\t\t\t}\n\n\t\t\t\tconst hasToolCalls = partial.content.some(c => c.type === 'toolCall');\n\t\t\t\tconst stopReason = hasToolCalls ? 'toolUse' : 'stop';\n\t\t\t\tpartial.stopReason = stopReason;\n\t\t\t\tstream.push({ type: 'done', reason: stopReason, message: partial });\n\t\t\t} catch (err) {\n\t\t\t\tif (!hasStarted) stream.push({ type: 'start', partial });\n\t\t\t\tpartial.stopReason = 'error';\n\t\t\t\tpartial.errorMessage = err instanceof Error ? err.message : String(err);\n\t\t\t\tstream.push({ type: 'error', reason: 'error', error: partial });\n\t\t\t}\n\t\t})();\n\n\t\treturn stream;\n\t}) as StreamFn;\n}\n"],"mappings":"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"}
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { type Model, type Api } from '@earendil-works/pi-ai/compat';
|
|
5
5
|
import { type Config } from '../config/schema.js';
|
|
6
|
+
import { type CredentialResolverOptions } from '../auth/credentials.js';
|
|
6
7
|
import type { ProviderModelDefinition } from '../extensions/types/providers.js';
|
|
8
|
+
export { EXTENSION_PROVIDER_BASE_URL } from './constants.js';
|
|
7
9
|
export { getApiKeyFromEnv, PROVIDER_ENV_MAP } from './env-keys.js';
|
|
8
|
-
/** Sentinel base URL: model is served by an extension {@link ProviderPluginRegistry} provider. */
|
|
9
|
-
export declare const EXTENSION_PROVIDER_BASE_URL = "extension://provider-plugin";
|
|
10
10
|
/** Map a plugin registry model to the pi-ai {@link Model} shape. */
|
|
11
11
|
export declare function pluginModelToModel(providerId: string, definition: ProviderModelDefinition): Model<Api>;
|
|
12
12
|
/**
|
|
@@ -23,7 +23,7 @@ export declare function getApiKeySync(provider: string): string | undefined;
|
|
|
23
23
|
export declare function resolveModel(ref: string): Model<Api>;
|
|
24
24
|
export declare function getModelsByProvider(provider: string): readonly Model<Api>[];
|
|
25
25
|
export declare function getAllProviders(): string[];
|
|
26
|
-
export declare function getApiKey(provider: string): Promise<string | undefined>;
|
|
26
|
+
export declare function getApiKey(provider: string, credentialOptions?: CredentialResolverOptions): Promise<string | undefined>;
|
|
27
27
|
/**
|
|
28
28
|
* Synchronous version for use in non-async contexts
|
|
29
29
|
* Only checks environment variables and registry, not credential system
|
|
@@ -4,6 +4,7 @@ import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync
|
|
|
4
4
|
import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
5
5
|
import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
|
|
6
6
|
import { CredentialResolver, hasCredentials, init_credentials, resolveApiKey } from "../auth/credentials.js";
|
|
7
|
+
import { EXTENSION_PROVIDER_BASE_URL, init_constants } from "./constants.js";
|
|
7
8
|
import { getSupplementalModels, init_model_supplements } from "./model-supplements.js";
|
|
8
9
|
import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
|
|
9
10
|
import { getModel, getModels, getProviders } from "@earendil-works/pi-ai/compat";
|
|
@@ -137,9 +138,9 @@ function getAllProviders() {
|
|
|
137
138
|
for (const plugin of getProviderRegistry().listAll()) providers.add(plugin.id);
|
|
138
139
|
return Array.from(providers);
|
|
139
140
|
}
|
|
140
|
-
async function getApiKey(provider) {
|
|
141
|
+
async function getApiKey(provider, credentialOptions) {
|
|
141
142
|
if (getProviderRegistry().has(provider)) return "extension-managed";
|
|
142
|
-
const credentialKey = await resolveApiKey(provider);
|
|
143
|
+
const credentialKey = await resolveApiKey(provider, credentialOptions);
|
|
143
144
|
if (credentialKey) return credentialKey;
|
|
144
145
|
const registryKey = getModelRegistry().getApiKey(provider);
|
|
145
146
|
if (registryKey) return registryKey;
|
|
@@ -303,16 +304,16 @@ function getDefaultModelSync(config) {
|
|
|
303
304
|
if (modelRef) return modelRef;
|
|
304
305
|
return "";
|
|
305
306
|
}
|
|
306
|
-
var
|
|
307
|
+
var OPENAI_CODEX_CANONICAL_BASE_URL, PROVIDER_META;
|
|
307
308
|
var init_providers = __esmMin((() => {
|
|
308
309
|
init_schema();
|
|
309
310
|
init_model_registry();
|
|
310
311
|
init_credentials();
|
|
311
312
|
init_sync_provider_auth();
|
|
312
313
|
init_env_keys();
|
|
314
|
+
init_constants();
|
|
313
315
|
init_model_supplements();
|
|
314
316
|
init_plugin_registry();
|
|
315
|
-
EXTENSION_PROVIDER_BASE_URL = "extension://provider-plugin";
|
|
316
317
|
OPENAI_CODEX_CANONICAL_BASE_URL = "https://chatgpt.com/backend-api/codex";
|
|
317
318
|
PROVIDER_META = {
|
|
318
319
|
"openai": {
|