@xopcai/xopc 0.0.110 → 0.0.111
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/README.md +46 -4
- package/README.zh-CN.md +46 -4
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +41 -0
- package/dist/gateway/static/root/assets/agent-avatar-dicebear-zlx9l5Yp.js +1 -0
- package/dist/gateway/static/root/assets/agent-browser-settings-page-B-0zGjt8.js +6 -0
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-Bz7JWjRM.js +1 -0
- package/dist/gateway/static/root/assets/agents-DwDnJlXT.js +71 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-DaQwdeCq.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-D2zv6r3P.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-BIppe_jj.js +1 -0
- package/dist/gateway/static/root/assets/archive-plugin-DEmu8eH7.js +1 -0
- package/dist/gateway/static/root/assets/attachment-load-B98lJoN5.js +2 -0
- package/dist/gateway/static/root/assets/{attachment-preview-renderer-CybMSIoS.js → attachment-preview-renderer-DonnL2dL.js} +1 -1
- package/dist/gateway/static/root/assets/binary-plugins-CL9QKmyo.js +2 -0
- package/dist/gateway/static/root/assets/block-editor-BOAhMAhT.js +180 -0
- package/dist/gateway/static/root/assets/channels-settings-Br8iRnXp.js +1 -0
- package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +1 -0
- package/dist/gateway/static/root/assets/code-editor-dZTY2dRW.js +1 -0
- package/dist/gateway/static/root/assets/config-api-0o1WYdz2.js +3 -0
- package/dist/gateway/static/root/assets/connectors-settings-DDvHo9in.js +2 -0
- package/dist/gateway/static/root/assets/cron-api-Dj_UZKST.js +1 -0
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-Dv7GII9G.js +1 -0
- package/dist/gateway/static/root/assets/cron-schedule-picker-DH10KgD6.js +1 -0
- package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +1 -0
- package/dist/gateway/static/root/assets/dist-CkobR7mk.js +1 -0
- package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +1 -0
- package/dist/gateway/static/root/assets/dreaming-scene-BHMRVEUS.js +4585 -0
- package/dist/gateway/static/root/assets/dreaming-settings-L2rgZDQl.js +1 -0
- package/dist/gateway/static/root/assets/extension-debug-page-Cjx6pZVz.js +1 -0
- package/dist/gateway/static/root/assets/{extension-page-W1wiG38F.js → extension-page-BSPNL90V.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-m_UQYkVc.js +1 -0
- package/dist/gateway/static/root/assets/fetch-Bs7in_4F.js +1 -0
- package/dist/gateway/static/root/assets/format-interval-label-CftJ5uXu.js +1 -0
- package/dist/gateway/static/root/assets/gateway-config-api-Clfck-hW.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-CS177xni.js +1 -0
- package/dist/gateway/static/root/assets/gateway-startup-retry-BkjVJc38.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-kqJue0sE.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-C0FujUB5.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-CJnzNSDo.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-config-api-Cp7CPuIn.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-ifSI1Wbh.js +1 -0
- package/dist/gateway/static/root/assets/html-workspace-editor-CQLWDiwE.js +1 -0
- package/dist/gateway/static/root/assets/index-COkF54xv.js +121 -0
- package/dist/gateway/static/root/assets/index-DIaSNGEO.css +1 -0
- package/dist/gateway/static/root/assets/interval-presets-B29Ss_2y.js +2 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings--MI1rYl7.js +1 -0
- package/dist/gateway/static/root/assets/locale-store-DjbfSsfA.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-BwrVNlyW.js +2 -0
- package/dist/gateway/static/root/assets/markdown-editor-AssmZFx4.js +2 -0
- package/dist/gateway/static/root/assets/markdown-split-B_oc9lJe.js +1 -0
- package/dist/gateway/static/root/assets/media-plugins-DLPvB5H3.js +1 -0
- package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +134 -0
- package/dist/gateway/static/root/assets/messages-Csef1aW7.js +3 -0
- package/dist/gateway/static/root/assets/middleware-Pd0e8Igk.js +1 -0
- package/dist/gateway/static/root/assets/models-hub-panel-DHGiTIvf.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-BM7zlDiT.js +2 -0
- package/dist/gateway/static/root/assets/note-image-lightbox-rSqAgOi9.js +1 -0
- package/dist/gateway/static/root/assets/note-time-hm6JO_Wi.js +1 -0
- package/dist/gateway/static/root/assets/notes-page-C9ACGEty.js +1 -0
- package/dist/gateway/static/root/assets/preview-open-alternatives-Bw_N2oZi.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BhcWIKuM.js +1 -0
- package/dist/gateway/static/root/assets/save-bar-controls-CNP2jmw0.js +1 -0
- package/dist/gateway/static/root/assets/schedule-field-BPAWui3P.js +1 -0
- package/dist/gateway/static/root/assets/schedule-summary-B-hdSRdR.js +1 -0
- package/dist/gateway/static/root/assets/schema-form-CDPzua9q.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-DzkpSDZr.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BYS-rpzn.js +1 -0
- package/dist/gateway/static/root/assets/settings-collapsible-section-C9bff85B.js +1 -0
- package/dist/gateway/static/root/assets/settings-form-section-BsrK7TBF.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-DWK4Zo7s.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-DJiksNu4.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-DnutoY_S.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-6oRgJMpn.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CU9i0nJV.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-ERbdWENm.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-qP1JDtDd.js +1 -0
- package/dist/gateway/static/root/assets/theme-store-CD2wtgZV.js +1 -0
- package/dist/gateway/static/root/assets/use-agent-defaults-form-D3FGVLZb.js +1 -0
- package/dist/gateway/static/root/assets/use-blob-object-url-D4BFuzZB.js +1 -0
- package/dist/gateway/static/root/assets/use-channel-catalog-C4mg1hjD.js +1 -0
- package/dist/gateway/static/root/assets/use-settings-tab-guard-F6C0mpJt.js +1 -0
- package/dist/gateway/static/root/assets/vendor-codemirror-CNP1wPe7.js +45 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-BnDDb6qO.js +1 -0
- package/dist/gateway/static/root/assets/voice-player-store-B2EwIhtY.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-page.utils-EYg_xBQS.js → workflow-page.utils-CRB7WX9l.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-2Fptr0je.js +18 -0
- package/dist/gateway/static/root/index.html +12 -10
- package/dist/package.js +1 -1
- package/dist/src/agent/goals/checklist-judge.d.ts +5 -0
- package/dist/src/agent/goals/checklist-judge.js +26 -2
- package/dist/src/agent/goals/checklist-judge.js.map +1 -1
- package/dist/src/agent/goals/evaluate-turn.d.ts +5 -1
- package/dist/src/agent/goals/evaluate-turn.js +29 -3
- package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.d.ts +0 -2
- package/dist/src/agent/goals/goal-locale.js +2 -15
- package/dist/src/agent/goals/goal-locale.js.map +1 -1
- package/dist/src/agent/goals/persistent-goal-service.d.ts +9 -0
- package/dist/src/agent/goals/persistent-goal-service.js +2 -1
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- package/dist/src/agent/goals/post-turn.d.ts +7 -0
- package/dist/src/agent/goals/post-turn.js +68 -23
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/goals/state.d.ts +0 -5
- package/dist/src/agent/goals/state.js +1 -96
- package/dist/src/agent/goals/state.js.map +1 -1
- package/dist/src/agent/messaging/command-handler.d.ts +4 -0
- package/dist/src/agent/messaging/command-handler.js +6 -2
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +2 -0
- package/dist/src/agent/service/direct-turn-helpers.js +3 -2
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +10 -1
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.js +20 -1
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +8 -0
- package/dist/src/agent/tools/cronjob-tool.d.ts +2 -0
- package/dist/src/agent/tools/cronjob-tool.js +27 -4
- package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
- package/dist/src/agent/tools/edit.d.ts +2 -0
- package/dist/src/agent/tools/edit.js +10 -0
- package/dist/src/agent/tools/edit.js.map +1 -1
- package/dist/src/agent/tools/factory.js +16 -3
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/goal-evidence-recorder.d.ts +6 -0
- package/dist/src/agent/tools/goal-evidence-recorder.js +34 -0
- package/dist/src/agent/tools/goal-evidence-recorder.js.map +1 -0
- package/dist/src/agent/tools/goal-tool.d.ts +19 -0
- package/dist/src/agent/tools/goal-tool.js +101 -0
- package/dist/src/agent/tools/goal-tool.js.map +1 -0
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/shell.d.ts +2 -0
- package/dist/src/agent/tools/shell.js +17 -2
- package/dist/src/agent/tools/shell.js.map +1 -1
- package/dist/src/agent/tools/workflow-tool.d.ts +1 -0
- package/dist/src/agent/tools/workflow-tool.js +10 -2
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/write.d.ts +2 -0
- package/dist/src/agent/tools/write.js +11 -0
- package/dist/src/agent/tools/write.js.map +1 -1
- package/dist/src/channels/attachments/inbound-persist.d.ts +7 -0
- package/dist/src/channels/attachments/inbound-persist.js +20 -2
- package/dist/src/channels/attachments/inbound-persist.js.map +1 -1
- package/dist/src/chat-commands/builtins/goal.d.ts +1 -1
- package/dist/src/chat-commands/builtins/goal.js +55 -97
- package/dist/src/chat-commands/builtins/goal.js.map +1 -1
- package/dist/src/chat-commands/builtins/subgoal.d.ts +1 -1
- package/dist/src/chat-commands/builtins/subgoal.js +49 -108
- package/dist/src/chat-commands/builtins/subgoal.js.map +1 -1
- package/dist/src/chat-commands/builtins/workflow.js +132 -8
- package/dist/src/chat-commands/builtins/workflow.js.map +1 -1
- package/dist/src/chat-commands/context.d.ts +3 -0
- package/dist/src/chat-commands/context.js +5 -0
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +5 -0
- package/dist/src/cli/command-catalog.js +43 -0
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +4 -0
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/goal.d.ts +4 -0
- package/dist/src/cli/commands/goal.js +213 -0
- package/dist/src/cli/commands/goal.js.map +1 -0
- package/dist/src/cli/commands/onboard.js +11 -5
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/schema.d.ts +115 -0
- package/dist/src/config/schema.js +63 -4
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +14 -0
- package/dist/src/config/web-patch.js +45 -6
- package/dist/src/config/web-patch.js.map +1 -1
- package/dist/src/cron/executor.d.ts +2 -0
- package/dist/src/cron/executor.js +25 -0
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/job-content.js +1 -0
- package/dist/src/cron/job-content.js.map +1 -1
- package/dist/src/cron/types.d.ts +19 -1
- package/dist/src/cron/validation.d.ts +20 -0
- package/dist/src/cron/validation.js +7 -0
- package/dist/src/cron/validation.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +14 -0
- package/dist/src/gateway/hono/routes/goals.d.ts +1 -1
- package/dist/src/gateway/hono/routes/goals.js +670 -173
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +5 -0
- package/dist/src/gateway/hono/routes/home.js +88 -3
- package/dist/src/gateway/hono/routes/home.js.map +1 -1
- package/dist/src/gateway/hono/routes/notes.js +20 -14
- package/dist/src/gateway/hono/routes/notes.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +6 -2
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -0
- package/dist/src/gateway/service/agent-runner.js +6 -2
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/run-gateway-agent.d.ts +3 -0
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service.d.ts +8 -0
- package/dist/src/gateway/service.js +69 -2
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-notifications.d.ts +29 -0
- package/dist/src/goals/goal-notifications.js +154 -0
- package/dist/src/goals/goal-notifications.js.map +1 -0
- package/dist/src/goals/goal-queue-store.d.ts +16 -0
- package/dist/src/goals/goal-queue-store.js +131 -0
- package/dist/src/goals/goal-queue-store.js.map +1 -0
- package/dist/src/goals/goal-queue-types.d.ts +31 -0
- package/dist/src/goals/goal-queue-types.js +1 -0
- package/dist/src/goals/goal-runner.d.ts +17 -0
- package/dist/src/goals/goal-runner.js +127 -0
- package/dist/src/goals/goal-runner.js.map +1 -0
- package/dist/src/goals/goal-service.d.ts +77 -0
- package/dist/src/goals/goal-service.js +261 -0
- package/dist/src/goals/goal-service.js.map +1 -0
- package/dist/src/goals/goal-store.d.ts +38 -0
- package/dist/src/goals/goal-store.js +404 -0
- package/dist/src/goals/goal-store.js.map +1 -0
- package/dist/src/goals/goal-workflow-judge.d.ts +13 -0
- package/dist/src/goals/goal-workflow-judge.js +147 -0
- package/dist/src/goals/goal-workflow-judge.js.map +1 -0
- package/dist/src/goals/index.d.ts +10 -0
- package/dist/src/goals/index.js +7 -0
- package/dist/src/goals/types.d.ts +119 -0
- package/dist/src/goals/types.js +1 -0
- package/dist/src/storage/sqlite/migrations/006_add_goals.sql +108 -0
- package/dist/src/storage/sqlite/migrations/007_goal_run_judge_schema.sql +4 -0
- package/dist/src/storage/sqlite/migrations/008_goal_queue_workflow_runs.sql +53 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +163 -0
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/workflows/domain/run.d.ts +1 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +5 -1
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +7 -0
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/dist/src/workflows/store/run-index-store.d.ts +8 -0
- package/dist/src/workflows/store/run-index-store.js +58 -0
- package/dist/src/workflows/store/run-index-store.js.map +1 -0
- package/dist/src/workflows/store/run-store.d.ts +2 -0
- package/dist/src/workflows/store/run-store.js +14 -21
- package/dist/src/workflows/store/run-store.js.map +1 -1
- package/package.json +9 -3
- package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +0 -41
- package/dist/gateway/static/root/assets/agents-CFFioJCI.js +0 -78
- package/dist/gateway/static/root/assets/apps-page-BYDmkbzG.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-CsbDaMvd.js +0 -1
- package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +0 -1
- package/dist/gateway/static/root/assets/copy-Dv6d4Dvw.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-Apk-7p4p.js +0 -1
- package/dist/gateway/static/root/assets/dist-DmGDgpy2.js +0 -1
- package/dist/gateway/static/root/assets/extension-debug-page-pxFC-tUa.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-COXSv6xP.js +0 -1
- package/dist/gateway/static/root/assets/fetch-CFdKBnE6.js +0 -1
- package/dist/gateway/static/root/assets/gateway-startup-retry-DdngdObI.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-config-api-DcmAMYmN.js +0 -1
- package/dist/gateway/static/root/assets/index-C_2yKRJX.js +0 -4845
- package/dist/gateway/static/root/assets/index-DI5_GsZt.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-DvTWUOzd.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-CZbdugWZ.js +0 -180
- package/dist/gateway/static/root/assets/note-time-RdyBZxj3.js +0 -1
- package/dist/gateway/static/root/assets/notes-page-mEAwy3e1.js +0 -1
- package/dist/gateway/static/root/assets/schema-form-DEvdni_r.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BsgffzV4.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-t6v8Dwb8.js +0 -2
- package/dist/gateway/static/root/assets/settings-form-section-BoYYZmJG.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-ClIthYF8.js +0 -3
- package/dist/gateway/static/root/assets/share-preview-page-Dd9et7KD.js +0 -2
- package/dist/gateway/static/root/assets/skills-page-DEXtxyfQ.js +0 -2
- package/dist/gateway/static/root/assets/theme-store-BZozwAeK.js +0 -1
- package/dist/gateway/static/root/assets/url-DQRqHuL-.js +0 -3
- package/dist/gateway/static/root/assets/vendor-codemirror-DYoKfS8f.js +0 -45
- package/dist/gateway/static/root/assets/voice-api-key-field-CNrKzQrf.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-EMZkzJNN.js +0 -18
- package/dist/src/agent/goals/checklist-user.d.ts +0 -24
- package/dist/src/agent/goals/checklist-user.js +0 -92
- package/dist/src/agent/goals/checklist-user.js.map +0 -1
- package/dist/src/agent/goals/goal-run-store.d.ts +0 -19
- package/dist/src/agent/goals/goal-run-store.js +0 -138
- package/dist/src/agent/goals/goal-run-store.js.map +0 -1
- package/dist/src/agent/goals/goal-run-types.d.ts +0 -28
- package/dist/src/agent/goals/goal-run-types.js +0 -6
- package/dist/src/agent/goals/goal-run-types.js.map +0 -1
- package/dist/src/agent/goals/patch-from-user-action.d.ts +0 -20
- package/dist/src/agent/goals/patch-from-user-action.js +0 -103
- package/dist/src/agent/goals/patch-from-user-action.js.map +0 -1
- /package/dist/gateway/static/root/assets/{note-detail-page-D4ZIVQbk.css → block-editor-D4ZIVQbk.css} +0 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/goals/goal-store.ts
|
|
4
|
+
function goalFromRow(row) {
|
|
5
|
+
return {
|
|
6
|
+
id: row.goal_id,
|
|
7
|
+
title: row.title,
|
|
8
|
+
description: row.description ?? void 0,
|
|
9
|
+
status: row.status,
|
|
10
|
+
agentId: row.agent_id,
|
|
11
|
+
priority: row.priority,
|
|
12
|
+
deadlineAt: row.deadline_at ?? void 0,
|
|
13
|
+
createdAt: row.created_at,
|
|
14
|
+
updatedAt: row.updated_at,
|
|
15
|
+
completedAt: row.completed_at ?? void 0,
|
|
16
|
+
archivedAt: row.archived_at ?? void 0,
|
|
17
|
+
activeSessionKey: row.active_session_key ?? void 0,
|
|
18
|
+
currentRunId: row.current_run_id ?? void 0,
|
|
19
|
+
nextAction: row.next_action ?? void 0,
|
|
20
|
+
blockedReason: row.blocked_reason ?? void 0,
|
|
21
|
+
judgeModelRef: row.judge_model_ref ?? void 0,
|
|
22
|
+
maxTurns: row.max_turns,
|
|
23
|
+
turnsUsed: row.turns_used,
|
|
24
|
+
uiLocale: row.ui_locale === "en" || row.ui_locale === "zh" ? row.ui_locale : void 0,
|
|
25
|
+
source: row.source
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function checklistFromRow(row) {
|
|
29
|
+
return {
|
|
30
|
+
id: row.item_id,
|
|
31
|
+
goalId: row.goal_id,
|
|
32
|
+
text: row.text,
|
|
33
|
+
status: row.status,
|
|
34
|
+
addedBy: row.added_by,
|
|
35
|
+
addedAt: row.added_at,
|
|
36
|
+
completedAt: row.completed_at ?? void 0,
|
|
37
|
+
evidenceSummary: row.evidence_summary ?? void 0,
|
|
38
|
+
sortOrder: row.sort_order
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function runFromRow(row) {
|
|
42
|
+
return {
|
|
43
|
+
id: row.run_id,
|
|
44
|
+
goalId: row.goal_id,
|
|
45
|
+
sessionKey: row.session_key,
|
|
46
|
+
source: row.source,
|
|
47
|
+
status: row.status,
|
|
48
|
+
startedAt: row.started_at,
|
|
49
|
+
finishedAt: row.finished_at ?? void 0,
|
|
50
|
+
verdict: row.verdict ? row.verdict : void 0,
|
|
51
|
+
reason: row.reason ?? void 0,
|
|
52
|
+
nextAction: row.next_action ?? void 0,
|
|
53
|
+
assistantPreview: row.assistant_preview ?? void 0,
|
|
54
|
+
checklistProgress: row.checklist_done != null && row.checklist_total != null ? {
|
|
55
|
+
done: row.checklist_done,
|
|
56
|
+
total: row.checklist_total
|
|
57
|
+
} : void 0,
|
|
58
|
+
confidence: row.confidence ?? void 0,
|
|
59
|
+
missingEvidence: parseJsonStringArray(row.missing_evidence_json),
|
|
60
|
+
userQuestion: row.user_question ?? void 0,
|
|
61
|
+
completedChecklistItemIds: parseJsonStringArray(row.completed_checklist_item_ids_json)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function parseJsonField(raw) {
|
|
65
|
+
if (!raw) return void 0;
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(raw);
|
|
68
|
+
} catch {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function parseJsonStringArray(raw) {
|
|
73
|
+
const value = parseJsonField(raw);
|
|
74
|
+
if (!Array.isArray(value)) return void 0;
|
|
75
|
+
const rows = value.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
76
|
+
return rows.length ? rows : void 0;
|
|
77
|
+
}
|
|
78
|
+
function eventFromRow(row) {
|
|
79
|
+
return {
|
|
80
|
+
id: row.event_id,
|
|
81
|
+
goalId: row.goal_id,
|
|
82
|
+
runId: row.run_id ?? void 0,
|
|
83
|
+
kind: row.kind,
|
|
84
|
+
message: row.message,
|
|
85
|
+
data: parseJsonField(row.data_json),
|
|
86
|
+
createdAt: row.created_at
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function evidenceFromRow(row) {
|
|
90
|
+
return {
|
|
91
|
+
id: row.evidence_id,
|
|
92
|
+
goalId: row.goal_id,
|
|
93
|
+
runId: row.run_id ?? void 0,
|
|
94
|
+
kind: row.kind,
|
|
95
|
+
title: row.title,
|
|
96
|
+
summary: row.summary ?? void 0,
|
|
97
|
+
uri: row.uri ?? void 0,
|
|
98
|
+
data: parseJsonField(row.data_json),
|
|
99
|
+
createdAt: row.created_at
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function clampLimit(n, fallback) {
|
|
103
|
+
return Math.min(500, Math.max(1, Math.floor(n ?? fallback)));
|
|
104
|
+
}
|
|
105
|
+
function insertGoalEvent(db, input) {
|
|
106
|
+
const event = {
|
|
107
|
+
id: randomUUID(),
|
|
108
|
+
goalId: input.goalId,
|
|
109
|
+
runId: input.runId,
|
|
110
|
+
kind: input.kind,
|
|
111
|
+
message: input.message,
|
|
112
|
+
data: input.data,
|
|
113
|
+
createdAt: input.createdAt ?? Date.now()
|
|
114
|
+
};
|
|
115
|
+
db.prepare(`INSERT INTO goal_events (event_id, goal_id, run_id, kind, message, data_json, created_at)
|
|
116
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.goalId, event.runId ?? null, event.kind, event.message, event.data === void 0 ? null : JSON.stringify(event.data), event.createdAt);
|
|
117
|
+
return event;
|
|
118
|
+
}
|
|
119
|
+
var GoalStore = class {
|
|
120
|
+
create(input) {
|
|
121
|
+
const now = Date.now();
|
|
122
|
+
const goal = {
|
|
123
|
+
id: randomUUID(),
|
|
124
|
+
title: input.title.trim(),
|
|
125
|
+
description: input.description?.trim() || void 0,
|
|
126
|
+
status: "active",
|
|
127
|
+
agentId: input.agentId,
|
|
128
|
+
priority: input.priority ?? "normal",
|
|
129
|
+
deadlineAt: input.deadlineAt,
|
|
130
|
+
createdAt: now,
|
|
131
|
+
updatedAt: now,
|
|
132
|
+
activeSessionKey: input.sessionKey,
|
|
133
|
+
judgeModelRef: input.judgeModelRef?.trim() || void 0,
|
|
134
|
+
maxTurns: Math.max(1, Math.min(500, Math.floor(input.maxTurns))),
|
|
135
|
+
turnsUsed: 0,
|
|
136
|
+
uiLocale: input.uiLocale,
|
|
137
|
+
source: input.source ?? "chat"
|
|
138
|
+
};
|
|
139
|
+
runSqliteWriteTransaction((db) => {
|
|
140
|
+
db.prepare(`INSERT INTO goals (
|
|
141
|
+
goal_id, title, description, status, agent_id, priority, deadline_at,
|
|
142
|
+
created_at, updated_at, active_session_key, judge_model_ref,
|
|
143
|
+
max_turns, turns_used, ui_locale, source
|
|
144
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(goal.id, goal.title, goal.description ?? null, goal.status, goal.agentId, goal.priority, goal.deadlineAt ?? null, goal.createdAt, goal.updatedAt, goal.activeSessionKey ?? null, goal.judgeModelRef ?? null, goal.maxTurns, goal.turnsUsed, goal.uiLocale ?? null, goal.source);
|
|
145
|
+
if (goal.activeSessionKey) db.prepare(`INSERT OR REPLACE INTO goal_session_links (goal_id, session_key, linked_at)
|
|
146
|
+
VALUES (?, ?, ?)`).run(goal.id, goal.activeSessionKey, now);
|
|
147
|
+
insertGoalEvent(db, {
|
|
148
|
+
goalId: goal.id,
|
|
149
|
+
kind: "created",
|
|
150
|
+
message: "Goal created",
|
|
151
|
+
createdAt: now
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
return goal;
|
|
155
|
+
}
|
|
156
|
+
get(goalId) {
|
|
157
|
+
const row = getSqliteDatabase().prepare(`SELECT * FROM goals WHERE goal_id = ?`).get(goalId);
|
|
158
|
+
return row ? goalFromRow(row) : null;
|
|
159
|
+
}
|
|
160
|
+
getActiveForSession(sessionKey) {
|
|
161
|
+
const row = getSqliteDatabase().prepare(`SELECT * FROM goals
|
|
162
|
+
WHERE active_session_key = ?
|
|
163
|
+
AND status IN ('active', 'paused', 'blocked', 'needs_input', 'done')
|
|
164
|
+
ORDER BY updated_at DESC
|
|
165
|
+
LIMIT 1`).get(sessionKey);
|
|
166
|
+
return row ? goalFromRow(row) : null;
|
|
167
|
+
}
|
|
168
|
+
list(query = {}) {
|
|
169
|
+
const conditions = [];
|
|
170
|
+
const params = [];
|
|
171
|
+
if (query.status) {
|
|
172
|
+
const statuses = Array.isArray(query.status) ? query.status : [query.status];
|
|
173
|
+
conditions.push(`status IN (${statuses.map(() => "?").join(", ")})`);
|
|
174
|
+
params.push(...statuses);
|
|
175
|
+
}
|
|
176
|
+
if (query.agentId) {
|
|
177
|
+
conditions.push(`agent_id = ?`);
|
|
178
|
+
params.push(query.agentId);
|
|
179
|
+
}
|
|
180
|
+
if (query.sessionKey) {
|
|
181
|
+
conditions.push(`goal_id IN (SELECT goal_id FROM goal_session_links WHERE session_key = ?)`);
|
|
182
|
+
params.push(query.sessionKey);
|
|
183
|
+
}
|
|
184
|
+
const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
185
|
+
const limit = clampLimit(query.limit, 50);
|
|
186
|
+
const offset = Math.max(0, Math.floor(query.offset ?? 0));
|
|
187
|
+
return getSqliteDatabase().prepare(`SELECT * FROM goals ${where} ORDER BY updated_at DESC LIMIT ? OFFSET ?`).all(...params, limit, offset).map(goalFromRow);
|
|
188
|
+
}
|
|
189
|
+
update(goalId, patch) {
|
|
190
|
+
const before = this.get(goalId);
|
|
191
|
+
if (!before) return null;
|
|
192
|
+
const next = {
|
|
193
|
+
...before,
|
|
194
|
+
...patch,
|
|
195
|
+
updatedAt: Date.now()
|
|
196
|
+
};
|
|
197
|
+
runSqliteWriteTransaction((db) => {
|
|
198
|
+
db.prepare(`UPDATE goals SET
|
|
199
|
+
title = ?, description = ?, status = ?, priority = ?, deadline_at = ?,
|
|
200
|
+
updated_at = ?, completed_at = ?, archived_at = ?, active_session_key = ?,
|
|
201
|
+
current_run_id = ?, next_action = ?, blocked_reason = ?, judge_model_ref = ?,
|
|
202
|
+
max_turns = ?, turns_used = ?, ui_locale = ?
|
|
203
|
+
WHERE goal_id = ?`).run(next.title, next.description ?? null, next.status, next.priority, next.deadlineAt ?? null, next.updatedAt, next.completedAt ?? null, next.archivedAt ?? null, next.activeSessionKey ?? null, next.currentRunId ?? null, next.nextAction ?? null, next.blockedReason ?? null, next.judgeModelRef ?? null, next.maxTurns, next.turnsUsed, next.uiLocale ?? null, goalId);
|
|
204
|
+
if (next.activeSessionKey) db.prepare(`INSERT OR REPLACE INTO goal_session_links (goal_id, session_key, linked_at)
|
|
205
|
+
VALUES (?, ?, ?)`).run(goalId, next.activeSessionKey, next.updatedAt);
|
|
206
|
+
});
|
|
207
|
+
return this.get(goalId);
|
|
208
|
+
}
|
|
209
|
+
listChecklist(goalId) {
|
|
210
|
+
return getSqliteDatabase().prepare(`SELECT * FROM goal_checklist_items WHERE goal_id = ? ORDER BY sort_order ASC, added_at ASC`).all(goalId).map(checklistFromRow);
|
|
211
|
+
}
|
|
212
|
+
addChecklistItem(input) {
|
|
213
|
+
return runSqliteWriteTransaction((db) => {
|
|
214
|
+
const maxRow = db.prepare(`SELECT COALESCE(MAX(sort_order), 0) AS max_sort FROM goal_checklist_items WHERE goal_id = ?`).get(input.goalId);
|
|
215
|
+
const now = Date.now();
|
|
216
|
+
const item = {
|
|
217
|
+
id: randomUUID(),
|
|
218
|
+
goalId: input.goalId,
|
|
219
|
+
text: input.text.trim(),
|
|
220
|
+
status: input.status ?? "pending",
|
|
221
|
+
addedBy: input.addedBy,
|
|
222
|
+
addedAt: now,
|
|
223
|
+
sortOrder: maxRow.max_sort + 1
|
|
224
|
+
};
|
|
225
|
+
db.prepare(`INSERT INTO goal_checklist_items (
|
|
226
|
+
item_id, goal_id, text, status, added_by, added_at, sort_order
|
|
227
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(item.id, item.goalId, item.text, item.status, item.addedBy, item.addedAt, item.sortOrder);
|
|
228
|
+
insertGoalEvent(db, {
|
|
229
|
+
goalId: input.goalId,
|
|
230
|
+
kind: "checklist_added",
|
|
231
|
+
message: item.text,
|
|
232
|
+
data: {
|
|
233
|
+
itemId: item.id,
|
|
234
|
+
addedBy: item.addedBy
|
|
235
|
+
},
|
|
236
|
+
createdAt: now
|
|
237
|
+
});
|
|
238
|
+
return item;
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
updateChecklistItem(itemId, patch) {
|
|
242
|
+
return runSqliteWriteTransaction((db) => {
|
|
243
|
+
const row = db.prepare(`SELECT * FROM goal_checklist_items WHERE item_id = ?`).get(itemId);
|
|
244
|
+
if (!row) return null;
|
|
245
|
+
const before = checklistFromRow(row);
|
|
246
|
+
const status = patch.status ?? before.status;
|
|
247
|
+
const completedAt = status === "completed" || status === "impossible" ? before.completedAt ?? Date.now() : null;
|
|
248
|
+
db.prepare(`UPDATE goal_checklist_items SET text = ?, status = ?, completed_at = ?, evidence_summary = ?
|
|
249
|
+
WHERE item_id = ?`).run(patch.text?.trim() || before.text, status, completedAt, patch.evidenceSummary ?? before.evidenceSummary ?? null, itemId);
|
|
250
|
+
insertGoalEvent(db, {
|
|
251
|
+
goalId: before.goalId,
|
|
252
|
+
kind: "checklist_updated",
|
|
253
|
+
message: patch.text?.trim() || before.text,
|
|
254
|
+
data: {
|
|
255
|
+
itemId,
|
|
256
|
+
status
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
return checklistFromRow(db.prepare(`SELECT * FROM goal_checklist_items WHERE item_id = ?`).get(itemId));
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
removeChecklistItem(itemId) {
|
|
263
|
+
return runSqliteWriteTransaction((db) => {
|
|
264
|
+
const row = db.prepare(`SELECT goal_id, text FROM goal_checklist_items WHERE item_id = ?`).get(itemId);
|
|
265
|
+
if (!row) return false;
|
|
266
|
+
db.prepare(`DELETE FROM goal_checklist_items WHERE item_id = ?`).run(itemId);
|
|
267
|
+
insertGoalEvent(db, {
|
|
268
|
+
goalId: row.goal_id,
|
|
269
|
+
kind: "checklist_removed",
|
|
270
|
+
message: row.text,
|
|
271
|
+
data: { itemId }
|
|
272
|
+
});
|
|
273
|
+
return true;
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
clearChecklist(goalId) {
|
|
277
|
+
runSqliteWriteTransaction((db) => {
|
|
278
|
+
db.prepare(`DELETE FROM goal_checklist_items WHERE goal_id = ?`).run(goalId);
|
|
279
|
+
insertGoalEvent(db, {
|
|
280
|
+
goalId,
|
|
281
|
+
kind: "checklist_cleared",
|
|
282
|
+
message: "Checklist cleared"
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
replaceChecklist(goalId, items) {
|
|
287
|
+
return runSqliteWriteTransaction((db) => {
|
|
288
|
+
db.prepare(`DELETE FROM goal_checklist_items WHERE goal_id = ?`).run(goalId);
|
|
289
|
+
const now = Date.now();
|
|
290
|
+
const next = [];
|
|
291
|
+
for (let i = 0; i < items.length; i++) {
|
|
292
|
+
const raw = items[i];
|
|
293
|
+
const item = {
|
|
294
|
+
id: randomUUID(),
|
|
295
|
+
goalId,
|
|
296
|
+
text: raw.text.trim(),
|
|
297
|
+
status: raw.status,
|
|
298
|
+
addedBy: raw.addedBy,
|
|
299
|
+
addedAt: raw.addedAt ?? now,
|
|
300
|
+
completedAt: raw.completedAt,
|
|
301
|
+
evidenceSummary: raw.evidenceSummary,
|
|
302
|
+
sortOrder: i + 1
|
|
303
|
+
};
|
|
304
|
+
if (!item.text) continue;
|
|
305
|
+
db.prepare(`INSERT INTO goal_checklist_items (
|
|
306
|
+
item_id, goal_id, text, status, added_by, added_at, completed_at, evidence_summary, sort_order
|
|
307
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(item.id, item.goalId, item.text, item.status, item.addedBy, item.addedAt, item.completedAt ?? null, item.evidenceSummary ?? null, item.sortOrder);
|
|
308
|
+
next.push(item);
|
|
309
|
+
}
|
|
310
|
+
insertGoalEvent(db, {
|
|
311
|
+
goalId,
|
|
312
|
+
kind: "checklist_replaced",
|
|
313
|
+
message: `Checklist replaced (${next.length} items)`
|
|
314
|
+
});
|
|
315
|
+
return next;
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
appendRun(run) {
|
|
319
|
+
const record = {
|
|
320
|
+
id: run.id ?? randomUUID(),
|
|
321
|
+
goalId: run.goalId,
|
|
322
|
+
sessionKey: run.sessionKey,
|
|
323
|
+
source: run.source,
|
|
324
|
+
status: run.status,
|
|
325
|
+
startedAt: run.startedAt ?? Date.now(),
|
|
326
|
+
finishedAt: run.finishedAt,
|
|
327
|
+
verdict: run.verdict,
|
|
328
|
+
reason: run.reason,
|
|
329
|
+
nextAction: run.nextAction,
|
|
330
|
+
assistantPreview: run.assistantPreview,
|
|
331
|
+
checklistProgress: run.checklistProgress
|
|
332
|
+
};
|
|
333
|
+
runSqliteWriteTransaction((db) => {
|
|
334
|
+
db.prepare(`INSERT INTO goal_runs (
|
|
335
|
+
run_id, goal_id, session_key, source, status, started_at, finished_at,
|
|
336
|
+
verdict, reason, next_action, assistant_preview, checklist_done, checklist_total,
|
|
337
|
+
confidence, missing_evidence_json, user_question, completed_checklist_item_ids_json
|
|
338
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(record.id, record.goalId, record.sessionKey, record.source, record.status, record.startedAt, record.finishedAt ?? null, record.verdict ?? null, record.reason ?? null, record.nextAction ?? null, record.assistantPreview ?? null, record.checklistProgress?.done ?? null, record.checklistProgress?.total ?? null, record.confidence ?? null, record.missingEvidence ? JSON.stringify(record.missingEvidence) : null, record.userQuestion ?? null, record.completedChecklistItemIds ? JSON.stringify(record.completedChecklistItemIds) : null);
|
|
339
|
+
db.prepare(`UPDATE goals SET current_run_id = ?, updated_at = ? WHERE goal_id = ?`).run(record.id, record.finishedAt ?? record.startedAt, record.goalId);
|
|
340
|
+
insertGoalEvent(db, {
|
|
341
|
+
goalId: record.goalId,
|
|
342
|
+
runId: record.id,
|
|
343
|
+
kind: "run_recorded",
|
|
344
|
+
message: record.reason ?? record.status,
|
|
345
|
+
data: {
|
|
346
|
+
verdict: record.verdict,
|
|
347
|
+
status: record.status,
|
|
348
|
+
confidence: record.confidence,
|
|
349
|
+
missingEvidence: record.missingEvidence,
|
|
350
|
+
userQuestion: record.userQuestion,
|
|
351
|
+
completedChecklistItemIds: record.completedChecklistItemIds
|
|
352
|
+
},
|
|
353
|
+
createdAt: record.finishedAt ?? record.startedAt
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
return record;
|
|
357
|
+
}
|
|
358
|
+
listRuns(goalId, limit) {
|
|
359
|
+
return getSqliteDatabase().prepare(`SELECT * FROM goal_runs WHERE goal_id = ? ORDER BY started_at DESC LIMIT ?`).all(goalId, clampLimit(limit, 50)).map(runFromRow);
|
|
360
|
+
}
|
|
361
|
+
listRunsForSession(sessionKey, limit) {
|
|
362
|
+
return getSqliteDatabase().prepare(`SELECT * FROM goal_runs WHERE session_key = ? ORDER BY started_at DESC LIMIT ?`).all(sessionKey, clampLimit(limit, 50)).map(runFromRow);
|
|
363
|
+
}
|
|
364
|
+
listEvents(goalId, limit) {
|
|
365
|
+
return getSqliteDatabase().prepare(`SELECT * FROM goal_events WHERE goal_id = ? ORDER BY created_at DESC LIMIT ?`).all(goalId, clampLimit(limit, 100)).map(eventFromRow);
|
|
366
|
+
}
|
|
367
|
+
addEvidence(input) {
|
|
368
|
+
const evidence = {
|
|
369
|
+
id: input.id ?? randomUUID(),
|
|
370
|
+
goalId: input.goalId,
|
|
371
|
+
runId: input.runId,
|
|
372
|
+
kind: input.kind,
|
|
373
|
+
title: input.title,
|
|
374
|
+
summary: input.summary,
|
|
375
|
+
uri: input.uri,
|
|
376
|
+
data: input.data,
|
|
377
|
+
createdAt: input.createdAt ?? Date.now()
|
|
378
|
+
};
|
|
379
|
+
runSqliteWriteTransaction((db) => {
|
|
380
|
+
db.prepare(`INSERT INTO goal_evidence (
|
|
381
|
+
evidence_id, goal_id, run_id, kind, title, summary, uri, data_json, created_at
|
|
382
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(evidence.id, evidence.goalId, evidence.runId ?? null, evidence.kind, evidence.title, evidence.summary ?? null, evidence.uri ?? null, evidence.data === void 0 ? null : JSON.stringify(evidence.data), evidence.createdAt);
|
|
383
|
+
insertGoalEvent(db, {
|
|
384
|
+
goalId: evidence.goalId,
|
|
385
|
+
runId: evidence.runId,
|
|
386
|
+
kind: "evidence_added",
|
|
387
|
+
message: evidence.title,
|
|
388
|
+
data: {
|
|
389
|
+
evidenceId: evidence.id,
|
|
390
|
+
kind: evidence.kind
|
|
391
|
+
},
|
|
392
|
+
createdAt: evidence.createdAt
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
return evidence;
|
|
396
|
+
}
|
|
397
|
+
listEvidence(goalId, limit) {
|
|
398
|
+
return getSqliteDatabase().prepare(`SELECT * FROM goal_evidence WHERE goal_id = ? ORDER BY created_at DESC LIMIT ?`).all(goalId, clampLimit(limit, 100)).map(evidenceFromRow);
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
//#endregion
|
|
402
|
+
export { GoalStore };
|
|
403
|
+
|
|
404
|
+
//# sourceMappingURL=goal-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-store.js","names":[],"sources":["../../../src/goals/goal-store.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { getSqliteDatabase, runSqliteWriteTransaction } from '../storage/sqlite/transaction.js';\nimport type {\n CreateGoalInput,\n Goal,\n GoalChecklistAddedBy,\n GoalChecklistItem,\n GoalChecklistStatus,\n GoalEvent,\n GoalEvidence,\n GoalListQuery,\n GoalPriority,\n GoalRun,\n GoalRunStatus,\n GoalRunVerdict,\n GoalSource,\n GoalStatus,\n} from './types.js';\n\ntype GoalRow = {\n goal_id: string;\n title: string;\n description: string | null;\n status: string;\n agent_id: string;\n priority: string;\n deadline_at: number | null;\n created_at: number;\n updated_at: number;\n completed_at: number | null;\n archived_at: number | null;\n active_session_key: string | null;\n current_run_id: string | null;\n next_action: string | null;\n blocked_reason: string | null;\n judge_model_ref: string | null;\n max_turns: number;\n turns_used: number;\n ui_locale: string | null;\n source: string;\n};\n\ntype ChecklistRow = {\n item_id: string;\n goal_id: string;\n text: string;\n status: string;\n added_by: string;\n added_at: number;\n completed_at: number | null;\n evidence_summary: string | null;\n sort_order: number;\n};\n\ntype GoalRunRow = {\n run_id: string;\n goal_id: string;\n session_key: string;\n source: string;\n status: string;\n started_at: number;\n finished_at: number | null;\n verdict: string | null;\n reason: string | null;\n next_action: string | null;\n assistant_preview: string | null;\n checklist_done: number | null;\n checklist_total: number | null;\n confidence: number | null;\n missing_evidence_json: string | null;\n user_question: string | null;\n completed_checklist_item_ids_json: string | null;\n};\n\ntype EventRow = {\n event_id: string;\n goal_id: string;\n run_id: string | null;\n kind: string;\n message: string;\n data_json: string | null;\n created_at: number;\n};\n\ntype EvidenceRow = {\n evidence_id: string;\n goal_id: string;\n run_id: string | null;\n kind: GoalEvidence['kind'];\n title: string;\n summary: string | null;\n uri: string | null;\n data_json: string | null;\n created_at: number;\n};\n\nfunction goalFromRow(row: GoalRow): Goal {\n return {\n id: row.goal_id,\n title: row.title,\n description: row.description ?? undefined,\n status: row.status as GoalStatus,\n agentId: row.agent_id,\n priority: row.priority as GoalPriority,\n deadlineAt: row.deadline_at ?? undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n completedAt: row.completed_at ?? undefined,\n archivedAt: row.archived_at ?? undefined,\n activeSessionKey: row.active_session_key ?? undefined,\n currentRunId: row.current_run_id ?? undefined,\n nextAction: row.next_action ?? undefined,\n blockedReason: row.blocked_reason ?? undefined,\n judgeModelRef: row.judge_model_ref ?? undefined,\n maxTurns: row.max_turns,\n turnsUsed: row.turns_used,\n uiLocale: row.ui_locale === 'en' || row.ui_locale === 'zh' ? row.ui_locale : undefined,\n source: row.source as GoalSource,\n };\n}\n\nfunction checklistFromRow(row: ChecklistRow): GoalChecklistItem {\n return {\n id: row.item_id,\n goalId: row.goal_id,\n text: row.text,\n status: row.status as GoalChecklistStatus,\n addedBy: row.added_by as GoalChecklistAddedBy,\n addedAt: row.added_at,\n completedAt: row.completed_at ?? undefined,\n evidenceSummary: row.evidence_summary ?? undefined,\n sortOrder: row.sort_order,\n };\n}\n\nfunction runFromRow(row: GoalRunRow): GoalRun {\n return {\n id: row.run_id,\n goalId: row.goal_id,\n sessionKey: row.session_key,\n source: row.source as GoalSource,\n status: row.status as GoalRunStatus,\n startedAt: row.started_at,\n finishedAt: row.finished_at ?? undefined,\n verdict: row.verdict ? (row.verdict as GoalRunVerdict) : undefined,\n reason: row.reason ?? undefined,\n nextAction: row.next_action ?? undefined,\n assistantPreview: row.assistant_preview ?? undefined,\n checklistProgress:\n row.checklist_done != null && row.checklist_total != null\n ? { done: row.checklist_done, total: row.checklist_total }\n : undefined,\n confidence: row.confidence ?? undefined,\n missingEvidence: parseJsonStringArray(row.missing_evidence_json),\n userQuestion: row.user_question ?? undefined,\n completedChecklistItemIds: parseJsonStringArray(row.completed_checklist_item_ids_json),\n };\n}\n\nfunction parseJsonField(raw: string | null): unknown {\n if (!raw) return undefined;\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return undefined;\n }\n}\n\nfunction parseJsonStringArray(raw: string | null): string[] | undefined {\n const value = parseJsonField(raw);\n if (!Array.isArray(value)) return undefined;\n const rows = value.filter((item): item is string => typeof item === 'string' && item.trim().length > 0);\n return rows.length ? rows : undefined;\n}\n\nfunction eventFromRow(row: EventRow): GoalEvent {\n return {\n id: row.event_id,\n goalId: row.goal_id,\n runId: row.run_id ?? undefined,\n kind: row.kind,\n message: row.message,\n data: parseJsonField(row.data_json),\n createdAt: row.created_at,\n };\n}\n\nfunction evidenceFromRow(row: EvidenceRow): GoalEvidence {\n return {\n id: row.evidence_id,\n goalId: row.goal_id,\n runId: row.run_id ?? undefined,\n kind: row.kind,\n title: row.title,\n summary: row.summary ?? undefined,\n uri: row.uri ?? undefined,\n data: parseJsonField(row.data_json),\n createdAt: row.created_at,\n };\n}\n\nfunction clampLimit(n: number | undefined, fallback: number): number {\n return Math.min(500, Math.max(1, Math.floor(n ?? fallback)));\n}\n\nfunction insertGoalEvent(db: ReturnType<typeof getSqliteDatabase>, input: {\n goalId: string;\n runId?: string;\n kind: string;\n message: string;\n data?: unknown;\n createdAt?: number;\n}): GoalEvent {\n const event: GoalEvent = {\n id: randomUUID(),\n goalId: input.goalId,\n runId: input.runId,\n kind: input.kind,\n message: input.message,\n data: input.data,\n createdAt: input.createdAt ?? Date.now(),\n };\n db.prepare(\n `INSERT INTO goal_events (event_id, goal_id, run_id, kind, message, data_json, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n event.id,\n event.goalId,\n event.runId ?? null,\n event.kind,\n event.message,\n event.data === undefined ? null : JSON.stringify(event.data),\n event.createdAt,\n );\n return event;\n}\n\nexport class GoalStore {\n create(input: CreateGoalInput): Goal {\n const now = Date.now();\n const goal: Goal = {\n id: randomUUID(),\n title: input.title.trim(),\n description: input.description?.trim() || undefined,\n status: 'active',\n agentId: input.agentId,\n priority: input.priority ?? 'normal',\n deadlineAt: input.deadlineAt,\n createdAt: now,\n updatedAt: now,\n activeSessionKey: input.sessionKey,\n judgeModelRef: input.judgeModelRef?.trim() || undefined,\n maxTurns: Math.max(1, Math.min(500, Math.floor(input.maxTurns))),\n turnsUsed: 0,\n uiLocale: input.uiLocale,\n source: input.source ?? 'chat',\n };\n\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO goals (\n goal_id, title, description, status, agent_id, priority, deadline_at,\n created_at, updated_at, active_session_key, judge_model_ref,\n max_turns, turns_used, ui_locale, source\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n goal.id,\n goal.title,\n goal.description ?? null,\n goal.status,\n goal.agentId,\n goal.priority,\n goal.deadlineAt ?? null,\n goal.createdAt,\n goal.updatedAt,\n goal.activeSessionKey ?? null,\n goal.judgeModelRef ?? null,\n goal.maxTurns,\n goal.turnsUsed,\n goal.uiLocale ?? null,\n goal.source,\n );\n if (goal.activeSessionKey) {\n db.prepare(\n `INSERT OR REPLACE INTO goal_session_links (goal_id, session_key, linked_at)\n VALUES (?, ?, ?)`,\n ).run(goal.id, goal.activeSessionKey, now);\n }\n insertGoalEvent(db, { goalId: goal.id, kind: 'created', message: 'Goal created', createdAt: now });\n });\n\n return goal;\n }\n\n get(goalId: string): Goal | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM goals WHERE goal_id = ?`)\n .get(goalId) as GoalRow | undefined;\n return row ? goalFromRow(row) : null;\n }\n\n getActiveForSession(sessionKey: string): Goal | null {\n const row = getSqliteDatabase()\n .prepare(\n `SELECT * FROM goals\n WHERE active_session_key = ?\n AND status IN ('active', 'paused', 'blocked', 'needs_input', 'done')\n ORDER BY updated_at DESC\n LIMIT 1`,\n )\n .get(sessionKey) as GoalRow | undefined;\n return row ? goalFromRow(row) : null;\n }\n\n list(query: GoalListQuery = {}): Goal[] {\n const conditions: string[] = [];\n const params: Array<string | number> = [];\n if (query.status) {\n const statuses = Array.isArray(query.status) ? query.status : [query.status];\n conditions.push(`status IN (${statuses.map(() => '?').join(', ')})`);\n params.push(...statuses);\n }\n if (query.agentId) {\n conditions.push(`agent_id = ?`);\n params.push(query.agentId);\n }\n if (query.sessionKey) {\n conditions.push(`goal_id IN (SELECT goal_id FROM goal_session_links WHERE session_key = ?)`);\n params.push(query.sessionKey);\n }\n const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';\n const limit = clampLimit(query.limit, 50);\n const offset = Math.max(0, Math.floor(query.offset ?? 0));\n const rows = getSqliteDatabase()\n .prepare(`SELECT * FROM goals ${where} ORDER BY updated_at DESC LIMIT ? OFFSET ?`)\n .all(...params, limit, offset) as GoalRow[];\n return rows.map(goalFromRow);\n }\n\n update(goalId: string, patch: Partial<Pick<\n Goal,\n | 'title'\n | 'description'\n | 'status'\n | 'priority'\n | 'deadlineAt'\n | 'completedAt'\n | 'archivedAt'\n | 'activeSessionKey'\n | 'currentRunId'\n | 'nextAction'\n | 'blockedReason'\n | 'judgeModelRef'\n | 'maxTurns'\n | 'turnsUsed'\n | 'uiLocale'\n >>): Goal | null {\n const before = this.get(goalId);\n if (!before) return null;\n const next = { ...before, ...patch, updatedAt: Date.now() };\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `UPDATE goals SET\n title = ?, description = ?, status = ?, priority = ?, deadline_at = ?,\n updated_at = ?, completed_at = ?, archived_at = ?, active_session_key = ?,\n current_run_id = ?, next_action = ?, blocked_reason = ?, judge_model_ref = ?,\n max_turns = ?, turns_used = ?, ui_locale = ?\n WHERE goal_id = ?`,\n ).run(\n next.title,\n next.description ?? null,\n next.status,\n next.priority,\n next.deadlineAt ?? null,\n next.updatedAt,\n next.completedAt ?? null,\n next.archivedAt ?? null,\n next.activeSessionKey ?? null,\n next.currentRunId ?? null,\n next.nextAction ?? null,\n next.blockedReason ?? null,\n next.judgeModelRef ?? null,\n next.maxTurns,\n next.turnsUsed,\n next.uiLocale ?? null,\n goalId,\n );\n if (next.activeSessionKey) {\n db.prepare(\n `INSERT OR REPLACE INTO goal_session_links (goal_id, session_key, linked_at)\n VALUES (?, ?, ?)`,\n ).run(goalId, next.activeSessionKey, next.updatedAt);\n }\n });\n return this.get(goalId);\n }\n\n listChecklist(goalId: string): GoalChecklistItem[] {\n const rows = getSqliteDatabase()\n .prepare(`SELECT * FROM goal_checklist_items WHERE goal_id = ? ORDER BY sort_order ASC, added_at ASC`)\n .all(goalId) as ChecklistRow[];\n return rows.map(checklistFromRow);\n }\n\n addChecklistItem(input: {\n goalId: string;\n text: string;\n addedBy: GoalChecklistAddedBy;\n status?: GoalChecklistStatus;\n }): GoalChecklistItem {\n return runSqliteWriteTransaction((db) => {\n const maxRow = db\n .prepare(`SELECT COALESCE(MAX(sort_order), 0) AS max_sort FROM goal_checklist_items WHERE goal_id = ?`)\n .get(input.goalId) as { max_sort: number };\n const now = Date.now();\n const item: GoalChecklistItem = {\n id: randomUUID(),\n goalId: input.goalId,\n text: input.text.trim(),\n status: input.status ?? 'pending',\n addedBy: input.addedBy,\n addedAt: now,\n sortOrder: maxRow.max_sort + 1,\n };\n db.prepare(\n `INSERT INTO goal_checklist_items (\n item_id, goal_id, text, status, added_by, added_at, sort_order\n ) VALUES (?, ?, ?, ?, ?, ?, ?)`,\n ).run(item.id, item.goalId, item.text, item.status, item.addedBy, item.addedAt, item.sortOrder);\n insertGoalEvent(db, {\n goalId: input.goalId,\n kind: 'checklist_added',\n message: item.text,\n data: { itemId: item.id, addedBy: item.addedBy },\n createdAt: now,\n });\n return item;\n });\n }\n\n updateChecklistItem(\n itemId: string,\n patch: Partial<Pick<GoalChecklistItem, 'text' | 'status' | 'evidenceSummary'>>,\n ): GoalChecklistItem | null {\n return runSqliteWriteTransaction((db) => {\n const row = db\n .prepare(`SELECT * FROM goal_checklist_items WHERE item_id = ?`)\n .get(itemId) as ChecklistRow | undefined;\n if (!row) return null;\n const before = checklistFromRow(row);\n const status = patch.status ?? before.status;\n const completedAt =\n status === 'completed' || status === 'impossible'\n ? (before.completedAt ?? Date.now())\n : null;\n db.prepare(\n `UPDATE goal_checklist_items SET text = ?, status = ?, completed_at = ?, evidence_summary = ?\n WHERE item_id = ?`,\n ).run(\n patch.text?.trim() || before.text,\n status,\n completedAt,\n patch.evidenceSummary ?? before.evidenceSummary ?? null,\n itemId,\n );\n insertGoalEvent(db, {\n goalId: before.goalId,\n kind: 'checklist_updated',\n message: patch.text?.trim() || before.text,\n data: { itemId, status },\n });\n const next = db\n .prepare(`SELECT * FROM goal_checklist_items WHERE item_id = ?`)\n .get(itemId) as ChecklistRow;\n return checklistFromRow(next);\n });\n }\n\n removeChecklistItem(itemId: string): boolean {\n return runSqliteWriteTransaction((db) => {\n const row = db\n .prepare(`SELECT goal_id, text FROM goal_checklist_items WHERE item_id = ?`)\n .get(itemId) as { goal_id: string; text: string } | undefined;\n if (!row) return false;\n db.prepare(`DELETE FROM goal_checklist_items WHERE item_id = ?`).run(itemId);\n insertGoalEvent(db, {\n goalId: row.goal_id,\n kind: 'checklist_removed',\n message: row.text,\n data: { itemId },\n });\n return true;\n });\n }\n\n clearChecklist(goalId: string): void {\n runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM goal_checklist_items WHERE goal_id = ?`).run(goalId);\n insertGoalEvent(db, { goalId, kind: 'checklist_cleared', message: 'Checklist cleared' });\n });\n }\n\n replaceChecklist(goalId: string, items: Array<{\n text: string;\n status: GoalChecklistStatus;\n addedBy: GoalChecklistAddedBy;\n addedAt?: number;\n completedAt?: number;\n evidenceSummary?: string;\n }>): GoalChecklistItem[] {\n return runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM goal_checklist_items WHERE goal_id = ?`).run(goalId);\n const now = Date.now();\n const next: GoalChecklistItem[] = [];\n for (let i = 0; i < items.length; i++) {\n const raw = items[i]!;\n const item: GoalChecklistItem = {\n id: randomUUID(),\n goalId,\n text: raw.text.trim(),\n status: raw.status,\n addedBy: raw.addedBy,\n addedAt: raw.addedAt ?? now,\n completedAt: raw.completedAt,\n evidenceSummary: raw.evidenceSummary,\n sortOrder: i + 1,\n };\n if (!item.text) continue;\n db.prepare(\n `INSERT INTO goal_checklist_items (\n item_id, goal_id, text, status, added_by, added_at, completed_at, evidence_summary, sort_order\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n item.id,\n item.goalId,\n item.text,\n item.status,\n item.addedBy,\n item.addedAt,\n item.completedAt ?? null,\n item.evidenceSummary ?? null,\n item.sortOrder,\n );\n next.push(item);\n }\n insertGoalEvent(db, {\n goalId,\n kind: 'checklist_replaced',\n message: `Checklist replaced (${next.length} items)`,\n });\n return next;\n });\n }\n\n appendRun(run: Omit<GoalRun, 'id' | 'startedAt'> & { id?: string; startedAt?: number }): GoalRun {\n const record: GoalRun = {\n id: run.id ?? randomUUID(),\n goalId: run.goalId,\n sessionKey: run.sessionKey,\n source: run.source,\n status: run.status,\n startedAt: run.startedAt ?? Date.now(),\n finishedAt: run.finishedAt,\n verdict: run.verdict,\n reason: run.reason,\n nextAction: run.nextAction,\n assistantPreview: run.assistantPreview,\n checklistProgress: run.checklistProgress,\n };\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO goal_runs (\n run_id, goal_id, session_key, source, status, started_at, finished_at,\n verdict, reason, next_action, assistant_preview, checklist_done, checklist_total,\n confidence, missing_evidence_json, user_question, completed_checklist_item_ids_json\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n record.id,\n record.goalId,\n record.sessionKey,\n record.source,\n record.status,\n record.startedAt,\n record.finishedAt ?? null,\n record.verdict ?? null,\n record.reason ?? null,\n record.nextAction ?? null,\n record.assistantPreview ?? null,\n record.checklistProgress?.done ?? null,\n record.checklistProgress?.total ?? null,\n record.confidence ?? null,\n record.missingEvidence ? JSON.stringify(record.missingEvidence) : null,\n record.userQuestion ?? null,\n record.completedChecklistItemIds ? JSON.stringify(record.completedChecklistItemIds) : null,\n );\n db.prepare(`UPDATE goals SET current_run_id = ?, updated_at = ? WHERE goal_id = ?`).run(\n record.id,\n record.finishedAt ?? record.startedAt,\n record.goalId,\n );\n insertGoalEvent(db, {\n goalId: record.goalId,\n runId: record.id,\n kind: 'run_recorded',\n message: record.reason ?? record.status,\n data: {\n verdict: record.verdict,\n status: record.status,\n confidence: record.confidence,\n missingEvidence: record.missingEvidence,\n userQuestion: record.userQuestion,\n completedChecklistItemIds: record.completedChecklistItemIds,\n },\n createdAt: record.finishedAt ?? record.startedAt,\n });\n });\n return record;\n }\n\n listRuns(goalId: string, limit?: number): GoalRun[] {\n const rows = getSqliteDatabase()\n .prepare(`SELECT * FROM goal_runs WHERE goal_id = ? ORDER BY started_at DESC LIMIT ?`)\n .all(goalId, clampLimit(limit, 50)) as GoalRunRow[];\n return rows.map(runFromRow);\n }\n\n listRunsForSession(sessionKey: string, limit?: number): GoalRun[] {\n const rows = getSqliteDatabase()\n .prepare(`SELECT * FROM goal_runs WHERE session_key = ? ORDER BY started_at DESC LIMIT ?`)\n .all(sessionKey, clampLimit(limit, 50)) as GoalRunRow[];\n return rows.map(runFromRow);\n }\n\n listEvents(goalId: string, limit?: number): GoalEvent[] {\n const rows = getSqliteDatabase()\n .prepare(`SELECT * FROM goal_events WHERE goal_id = ? ORDER BY created_at DESC LIMIT ?`)\n .all(goalId, clampLimit(limit, 100)) as EventRow[];\n return rows.map(eventFromRow);\n }\n\n addEvidence(input: Omit<GoalEvidence, 'id' | 'createdAt'> & { id?: string; createdAt?: number }): GoalEvidence {\n const evidence: GoalEvidence = {\n id: input.id ?? randomUUID(),\n goalId: input.goalId,\n runId: input.runId,\n kind: input.kind,\n title: input.title,\n summary: input.summary,\n uri: input.uri,\n data: input.data,\n createdAt: input.createdAt ?? Date.now(),\n };\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO goal_evidence (\n evidence_id, goal_id, run_id, kind, title, summary, uri, data_json, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n evidence.id,\n evidence.goalId,\n evidence.runId ?? null,\n evidence.kind,\n evidence.title,\n evidence.summary ?? null,\n evidence.uri ?? null,\n evidence.data === undefined ? null : JSON.stringify(evidence.data),\n evidence.createdAt,\n );\n insertGoalEvent(db, {\n goalId: evidence.goalId,\n runId: evidence.runId,\n kind: 'evidence_added',\n message: evidence.title,\n data: { evidenceId: evidence.id, kind: evidence.kind },\n createdAt: evidence.createdAt,\n });\n });\n return evidence;\n }\n\n listEvidence(goalId: string, limit?: number): GoalEvidence[] {\n const rows = getSqliteDatabase()\n .prepare(`SELECT * FROM goal_evidence WHERE goal_id = ? ORDER BY created_at DESC LIMIT ?`)\n .all(goalId, clampLimit(limit, 100)) as EvidenceRow[];\n return rows.map(evidenceFromRow);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Config } from '../config/schema.js';
|
|
2
|
+
import type { WorkflowRunView } from '../workflows/domain/index.js';
|
|
3
|
+
export interface GoalWorkflowJudgeInput {
|
|
4
|
+
config: Config | undefined;
|
|
5
|
+
view: WorkflowRunView;
|
|
6
|
+
sessionKey: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class GoalWorkflowJudge {
|
|
9
|
+
private readonly goals;
|
|
10
|
+
handleTerminalWorkflowRun(input: GoalWorkflowJudgeInput): Promise<void>;
|
|
11
|
+
private markBlockedFromFailedWorkflow;
|
|
12
|
+
private recordWorkflowEvidence;
|
|
13
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
2
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
3
|
+
import { init_logger } from "../utils/logger.js";
|
|
4
|
+
import { renderWorkflowText } from "../agent/workflow/snapshot.js";
|
|
5
|
+
import { runViewToSnapshot } from "../workflows/service/run-view-to-snapshot.js";
|
|
6
|
+
import { GoalService } from "./goal-service.js";
|
|
7
|
+
import { resolveGoalUiLocale } from "../agent/goals/goal-locale.js";
|
|
8
|
+
import { evaluateAfterTurnHermesLike } from "../agent/goals/evaluate-turn.js";
|
|
9
|
+
//#region src/goals/goal-workflow-judge.ts
|
|
10
|
+
init_schema();
|
|
11
|
+
init_logger();
|
|
12
|
+
const log = createLogger("GoalWorkflowJudge");
|
|
13
|
+
var GoalWorkflowJudge = class {
|
|
14
|
+
goals = new GoalService();
|
|
15
|
+
async handleTerminalWorkflowRun(input) {
|
|
16
|
+
const goalId = input.view.run.metadata?.goalId?.trim();
|
|
17
|
+
if (!goalId) return;
|
|
18
|
+
const goal = this.goals.get(goalId);
|
|
19
|
+
if (!goal) return;
|
|
20
|
+
const resultText = renderWorkflowText(runViewToSnapshot(input.view), input.view.run.status === "succeeded", { showResultPreviews: true });
|
|
21
|
+
if (input.view.run.status !== "succeeded") {
|
|
22
|
+
this.markBlockedFromFailedWorkflow({
|
|
23
|
+
goalId,
|
|
24
|
+
sessionKey: input.sessionKey,
|
|
25
|
+
view: input.view,
|
|
26
|
+
resultText
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const judgeModelRef = input.config?.goals?.judgeModelRef?.trim() || goal.judgeModelRef?.trim() || (input.config ? getAgentDefaultModelRef(input.config) : void 0);
|
|
31
|
+
if (!judgeModelRef) {
|
|
32
|
+
log.warn({
|
|
33
|
+
goalId,
|
|
34
|
+
workflowRunId: input.view.run.id
|
|
35
|
+
}, "Workflow goal judge skipped: no judge model");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const state = {
|
|
39
|
+
goal: goal.title,
|
|
40
|
+
status: "active",
|
|
41
|
+
turnsUsed: goal.turnsUsed,
|
|
42
|
+
maxTurns: goal.maxTurns,
|
|
43
|
+
createdAt: goal.createdAt,
|
|
44
|
+
lastTurnAt: goal.updatedAt,
|
|
45
|
+
lastReason: goal.blockedReason,
|
|
46
|
+
judgeModelRef: goal.judgeModelRef,
|
|
47
|
+
decomposed: goal.checklist.length > 0 ? true : void 0,
|
|
48
|
+
uiLocale: goal.uiLocale,
|
|
49
|
+
checklist: goal.checklist.map((item) => ({
|
|
50
|
+
text: item.text,
|
|
51
|
+
status: item.status,
|
|
52
|
+
addedBy: item.addedBy,
|
|
53
|
+
addedAt: item.addedAt,
|
|
54
|
+
completedAt: item.completedAt,
|
|
55
|
+
evidence: item.evidenceSummary
|
|
56
|
+
}))
|
|
57
|
+
};
|
|
58
|
+
const decision = await evaluateAfterTurnHermesLike(state, resultText, judgeModelRef, void 0, {
|
|
59
|
+
goalsSlice: input.config?.goals,
|
|
60
|
+
historyExcerpt: resultText,
|
|
61
|
+
uiLocale: resolveGoalUiLocale(state)
|
|
62
|
+
});
|
|
63
|
+
if (!decision.newState) return;
|
|
64
|
+
const next = decision.newState;
|
|
65
|
+
const completedChecklistItemIds = decision.completedChecklistItemIndexes?.map((index) => goal.checklist[index]?.id).filter((id) => typeof id === "string" && id.length > 0);
|
|
66
|
+
const updatedGoal = this.goals.syncPostTurnState({
|
|
67
|
+
goalId,
|
|
68
|
+
sessionKey: input.sessionKey,
|
|
69
|
+
source: "workflow",
|
|
70
|
+
status: next.status === "done" ? "done" : decision.verdict === "blocked" ? "blocked" : decision.verdict === "needs_input" ? "needs_input" : next.status === "paused" ? "paused" : "active",
|
|
71
|
+
turnsUsed: next.turnsUsed,
|
|
72
|
+
maxTurns: next.maxTurns,
|
|
73
|
+
reason: next.pausedReason ?? decision.reason,
|
|
74
|
+
nextAction: decision.continuationPrompt ?? void 0,
|
|
75
|
+
assistantPreview: resultText,
|
|
76
|
+
verdict: decision.verdict === "done" ? "done" : decision.verdict === "decompose" ? "decompose" : decision.verdict === "blocked" ? "blocked" : decision.verdict === "needs_input" ? "needs_input" : "continue",
|
|
77
|
+
confidence: decision.confidence,
|
|
78
|
+
missingEvidence: decision.missingEvidence,
|
|
79
|
+
userQuestion: decision.userQuestion,
|
|
80
|
+
completedChecklistItemIds,
|
|
81
|
+
checklist: next.checklist?.map((item) => ({
|
|
82
|
+
text: item.text,
|
|
83
|
+
status: item.status,
|
|
84
|
+
addedBy: item.addedBy,
|
|
85
|
+
addedAt: item.addedAt,
|
|
86
|
+
completedAt: item.completedAt,
|
|
87
|
+
evidenceSummary: item.evidence
|
|
88
|
+
}))
|
|
89
|
+
});
|
|
90
|
+
this.recordWorkflowEvidence({
|
|
91
|
+
goalId,
|
|
92
|
+
runId: updatedGoal?.currentRunId,
|
|
93
|
+
view: input.view,
|
|
94
|
+
summary: decision.reason || `Workflow ${input.view.run.definitionId} succeeded`
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
markBlockedFromFailedWorkflow(input) {
|
|
98
|
+
const current = this.goals.get(input.goalId);
|
|
99
|
+
const reason = input.view.run.error?.message || `Workflow ${input.view.run.definitionId} finished with status ${input.view.run.status}`;
|
|
100
|
+
const goal = this.goals.syncPostTurnState({
|
|
101
|
+
goalId: input.goalId,
|
|
102
|
+
sessionKey: input.sessionKey,
|
|
103
|
+
source: "workflow",
|
|
104
|
+
status: "blocked",
|
|
105
|
+
turnsUsed: (current?.turnsUsed ?? 0) + 1,
|
|
106
|
+
maxTurns: current?.maxTurns ?? 10,
|
|
107
|
+
verdict: "blocked",
|
|
108
|
+
reason,
|
|
109
|
+
nextAction: `Investigate workflow ${input.view.run.id} failure.`,
|
|
110
|
+
assistantPreview: input.resultText
|
|
111
|
+
});
|
|
112
|
+
this.recordWorkflowEvidence({
|
|
113
|
+
goalId: input.goalId,
|
|
114
|
+
runId: goal?.currentRunId,
|
|
115
|
+
view: input.view,
|
|
116
|
+
summary: reason
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
recordWorkflowEvidence(input) {
|
|
120
|
+
this.goals.addEvidence({
|
|
121
|
+
goalId: input.goalId,
|
|
122
|
+
runId: input.runId,
|
|
123
|
+
kind: "artifact",
|
|
124
|
+
title: `Workflow ${input.view.run.definitionId} ${input.view.run.status}`,
|
|
125
|
+
summary: input.summary,
|
|
126
|
+
uri: `workflow:${input.view.run.id}`,
|
|
127
|
+
data: {
|
|
128
|
+
workflowRunId: input.view.run.id,
|
|
129
|
+
status: input.view.run.status,
|
|
130
|
+
metrics: input.view.run.metrics
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
for (const artifact of input.view.artifacts) this.goals.addEvidence({
|
|
134
|
+
goalId: input.goalId,
|
|
135
|
+
runId: input.runId,
|
|
136
|
+
kind: "artifact",
|
|
137
|
+
title: artifact.title || artifact.name,
|
|
138
|
+
summary: `${artifact.mimeType} · ${artifact.sizeBytes} bytes`,
|
|
139
|
+
uri: `workflow:${input.view.run.id}:artifact:${artifact.id}`,
|
|
140
|
+
data: artifact
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
//#endregion
|
|
145
|
+
export { GoalWorkflowJudge };
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=goal-workflow-judge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-workflow-judge.js","names":[],"sources":["../../../src/goals/goal-workflow-judge.ts"],"sourcesContent":["import type { Config } from '../config/schema.js';\nimport { getAgentDefaultModelRef } from '../config/schema.js';\nimport { renderWorkflowText } from '../agent/workflow/snapshot.js';\nimport { evaluateAfterTurnHermesLike } from '../agent/goals/evaluate-turn.js';\nimport { resolveGoalUiLocale } from '../agent/goals/goal-locale.js';\nimport type { PersistentGoalState } from '../agent/goals/state.js';\nimport type { WorkflowRunView } from '../workflows/domain/index.js';\nimport { runViewToSnapshot } from '../workflows/service/run-view-to-snapshot.js';\nimport { createLogger } from '../utils/logger.js';\n\nimport { GoalService } from './goal-service.js';\n\nconst log = createLogger('GoalWorkflowJudge');\n\nexport interface GoalWorkflowJudgeInput {\n config: Config | undefined;\n view: WorkflowRunView;\n sessionKey: string;\n}\n\nexport class GoalWorkflowJudge {\n private readonly goals = new GoalService();\n\n async handleTerminalWorkflowRun(input: GoalWorkflowJudgeInput): Promise<void> {\n const goalId = input.view.run.metadata?.goalId?.trim();\n if (!goalId) return;\n\n const goal = this.goals.get(goalId);\n if (!goal) return;\n\n const resultText = renderWorkflowText(\n runViewToSnapshot(input.view),\n input.view.run.status === 'succeeded',\n { showResultPreviews: true },\n );\n\n if (input.view.run.status !== 'succeeded') {\n this.markBlockedFromFailedWorkflow({\n goalId,\n sessionKey: input.sessionKey,\n view: input.view,\n resultText,\n });\n return;\n }\n\n const judgeModelRef = input.config?.goals?.judgeModelRef?.trim()\n || goal.judgeModelRef?.trim()\n || (input.config ? getAgentDefaultModelRef(input.config) : undefined);\n if (!judgeModelRef) {\n log.warn({ goalId, workflowRunId: input.view.run.id }, 'Workflow goal judge skipped: no judge model');\n return;\n }\n\n const state: PersistentGoalState = {\n goal: goal.title,\n status: 'active',\n turnsUsed: goal.turnsUsed,\n maxTurns: goal.maxTurns,\n createdAt: goal.createdAt,\n lastTurnAt: goal.updatedAt,\n lastReason: goal.blockedReason,\n judgeModelRef: goal.judgeModelRef,\n decomposed: goal.checklist.length > 0 ? true : undefined,\n uiLocale: goal.uiLocale,\n checklist: goal.checklist.map((item) => ({\n text: item.text,\n status: item.status,\n addedBy: item.addedBy,\n addedAt: item.addedAt,\n completedAt: item.completedAt,\n evidence: item.evidenceSummary,\n })),\n };\n\n const decision = await evaluateAfterTurnHermesLike(state, resultText, judgeModelRef, undefined, {\n goalsSlice: input.config?.goals,\n historyExcerpt: resultText,\n uiLocale: resolveGoalUiLocale(state),\n });\n\n if (!decision.newState) return;\n const next = decision.newState;\n const completedChecklistItemIds = decision.completedChecklistItemIndexes\n ?.map((index) => goal.checklist[index]?.id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0);\n\n const updatedGoal = this.goals.syncPostTurnState({\n goalId,\n sessionKey: input.sessionKey,\n source: 'workflow',\n status: next.status === 'done'\n ? 'done'\n : decision.verdict === 'blocked'\n ? 'blocked'\n : decision.verdict === 'needs_input'\n ? 'needs_input'\n : next.status === 'paused'\n ? 'paused'\n : 'active',\n turnsUsed: next.turnsUsed,\n maxTurns: next.maxTurns,\n reason: next.pausedReason ?? decision.reason,\n nextAction: decision.continuationPrompt ?? undefined,\n assistantPreview: resultText,\n verdict: decision.verdict === 'done'\n ? 'done'\n : decision.verdict === 'decompose'\n ? 'decompose'\n : decision.verdict === 'blocked'\n ? 'blocked'\n : decision.verdict === 'needs_input'\n ? 'needs_input'\n : 'continue',\n confidence: decision.confidence,\n missingEvidence: decision.missingEvidence,\n userQuestion: decision.userQuestion,\n completedChecklistItemIds,\n checklist: next.checklist?.map((item) => ({\n text: item.text,\n status: item.status,\n addedBy: item.addedBy,\n addedAt: item.addedAt,\n completedAt: item.completedAt,\n evidenceSummary: item.evidence,\n })),\n });\n\n this.recordWorkflowEvidence({\n goalId,\n runId: updatedGoal?.currentRunId,\n view: input.view,\n summary: decision.reason || `Workflow ${input.view.run.definitionId} succeeded`,\n });\n }\n\n private markBlockedFromFailedWorkflow(input: {\n goalId: string;\n sessionKey: string;\n view: WorkflowRunView;\n resultText: string;\n }): void {\n const current = this.goals.get(input.goalId);\n const reason = input.view.run.error?.message\n || `Workflow ${input.view.run.definitionId} finished with status ${input.view.run.status}`;\n const goal = this.goals.syncPostTurnState({\n goalId: input.goalId,\n sessionKey: input.sessionKey,\n source: 'workflow',\n status: 'blocked',\n turnsUsed: (current?.turnsUsed ?? 0) + 1,\n maxTurns: current?.maxTurns ?? 10,\n verdict: 'blocked',\n reason,\n nextAction: `Investigate workflow ${input.view.run.id} failure.`,\n assistantPreview: input.resultText,\n });\n this.recordWorkflowEvidence({\n goalId: input.goalId,\n runId: goal?.currentRunId,\n view: input.view,\n summary: reason,\n });\n }\n\n private recordWorkflowEvidence(input: {\n goalId: string;\n runId?: string;\n view: WorkflowRunView;\n summary: string;\n }): void {\n this.goals.addEvidence({\n goalId: input.goalId,\n runId: input.runId,\n kind: 'artifact',\n title: `Workflow ${input.view.run.definitionId} ${input.view.run.status}`,\n summary: input.summary,\n uri: `workflow:${input.view.run.id}`,\n data: {\n workflowRunId: input.view.run.id,\n status: input.view.run.status,\n metrics: input.view.run.metrics,\n },\n });\n for (const artifact of input.view.artifacts) {\n this.goals.addEvidence({\n goalId: input.goalId,\n runId: input.runId,\n kind: 'artifact',\n title: artifact.title || artifact.name,\n summary: `${artifact.mimeType} · ${artifact.sizeBytes} bytes`,\n uri: `workflow:${input.view.run.id}:artifact:${artifact.id}`,\n data: artifact,\n });\n }\n }\n}\n"],"mappings":";;;;;;;;;aAC8D;aAOZ;AAIlD,MAAM,MAAM,aAAa,oBAAoB;AAQ7C,IAAa,oBAAb,MAA+B;CAC7B,QAAyB,IAAI,aAAa;CAE1C,MAAM,0BAA0B,OAA8C;EAC5E,MAAM,SAAS,MAAM,KAAK,IAAI,UAAU,QAAQ,MAAM;AACtD,MAAI,CAAC,OAAQ;EAEb,MAAM,OAAO,KAAK,MAAM,IAAI,OAAO;AACnC,MAAI,CAAC,KAAM;EAEX,MAAM,aAAa,mBACjB,kBAAkB,MAAM,KAAK,EAC7B,MAAM,KAAK,IAAI,WAAW,aAC1B,EAAE,oBAAoB,MAAM,CAC7B;AAED,MAAI,MAAM,KAAK,IAAI,WAAW,aAAa;AACzC,QAAK,8BAA8B;IACjC;IACA,YAAY,MAAM;IAClB,MAAM,MAAM;IACZ;IACD,CAAC;AACF;;EAGF,MAAM,gBAAgB,MAAM,QAAQ,OAAO,eAAe,MAAM,IAC3D,KAAK,eAAe,MAAM,KACzB,MAAM,SAAS,wBAAwB,MAAM,OAAO,GAAG,KAAA;AAC7D,MAAI,CAAC,eAAe;AAClB,OAAI,KAAK;IAAE;IAAQ,eAAe,MAAM,KAAK,IAAI;IAAI,EAAE,8CAA8C;AACrG;;EAGF,MAAM,QAA6B;GACjC,MAAM,KAAK;GACX,QAAQ;GACR,WAAW,KAAK;GAChB,UAAU,KAAK;GACf,WAAW,KAAK;GAChB,YAAY,KAAK;GACjB,YAAY,KAAK;GACjB,eAAe,KAAK;GACpB,YAAY,KAAK,UAAU,SAAS,IAAI,OAAO,KAAA;GAC/C,UAAU,KAAK;GACf,WAAW,KAAK,UAAU,KAAK,UAAU;IACvC,MAAM,KAAK;IACX,QAAQ,KAAK;IACb,SAAS,KAAK;IACd,SAAS,KAAK;IACd,aAAa,KAAK;IAClB,UAAU,KAAK;IAChB,EAAE;GACJ;EAED,MAAM,WAAW,MAAM,4BAA4B,OAAO,YAAY,eAAe,KAAA,GAAW;GAC9F,YAAY,MAAM,QAAQ;GAC1B,gBAAgB;GAChB,UAAU,oBAAoB,MAAM;GACrC,CAAC;AAEF,MAAI,CAAC,SAAS,SAAU;EACxB,MAAM,OAAO,SAAS;EACtB,MAAM,4BAA4B,SAAS,+BACvC,KAAK,UAAU,KAAK,UAAU,QAAQ,GAAG,CAC1C,QAAQ,OAAqB,OAAO,OAAO,YAAY,GAAG,SAAS,EAAE;EAExE,MAAM,cAAc,KAAK,MAAM,kBAAkB;GAC/C;GACA,YAAY,MAAM;GAClB,QAAQ;GACR,QAAQ,KAAK,WAAW,SACpB,SACA,SAAS,YAAY,YACnB,YACA,SAAS,YAAY,gBACnB,gBACA,KAAK,WAAW,WACd,WACA;GACV,WAAW,KAAK;GAChB,UAAU,KAAK;GACf,QAAQ,KAAK,gBAAgB,SAAS;GACtC,YAAY,SAAS,sBAAsB,KAAA;GAC3C,kBAAkB;GAClB,SAAS,SAAS,YAAY,SAC1B,SACA,SAAS,YAAY,cACnB,cACA,SAAS,YAAY,YACnB,YACA,SAAS,YAAY,gBACnB,gBACA;GACV,YAAY,SAAS;GACrB,iBAAiB,SAAS;GAC1B,cAAc,SAAS;GACvB;GACA,WAAW,KAAK,WAAW,KAAK,UAAU;IACxC,MAAM,KAAK;IACX,QAAQ,KAAK;IACb,SAAS,KAAK;IACd,SAAS,KAAK;IACd,aAAa,KAAK;IAClB,iBAAiB,KAAK;IACvB,EAAE;GACJ,CAAC;AAEF,OAAK,uBAAuB;GAC1B;GACA,OAAO,aAAa;GACpB,MAAM,MAAM;GACZ,SAAS,SAAS,UAAU,YAAY,MAAM,KAAK,IAAI,aAAa;GACrE,CAAC;;CAGJ,8BAAsC,OAK7B;EACP,MAAM,UAAU,KAAK,MAAM,IAAI,MAAM,OAAO;EAC5C,MAAM,SAAS,MAAM,KAAK,IAAI,OAAO,WAChC,YAAY,MAAM,KAAK,IAAI,aAAa,wBAAwB,MAAM,KAAK,IAAI;EACpF,MAAM,OAAO,KAAK,MAAM,kBAAkB;GACxC,QAAQ,MAAM;GACd,YAAY,MAAM;GAClB,QAAQ;GACR,QAAQ;GACR,YAAY,SAAS,aAAa,KAAK;GACvC,UAAU,SAAS,YAAY;GAC/B,SAAS;GACT;GACA,YAAY,wBAAwB,MAAM,KAAK,IAAI,GAAG;GACtD,kBAAkB,MAAM;GACzB,CAAC;AACF,OAAK,uBAAuB;GAC1B,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,MAAM,MAAM;GACZ,SAAS;GACV,CAAC;;CAGJ,uBAA+B,OAKtB;AACP,OAAK,MAAM,YAAY;GACrB,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,MAAM;GACN,OAAO,YAAY,MAAM,KAAK,IAAI,aAAa,GAAG,MAAM,KAAK,IAAI;GACjE,SAAS,MAAM;GACf,KAAK,YAAY,MAAM,KAAK,IAAI;GAChC,MAAM;IACJ,eAAe,MAAM,KAAK,IAAI;IAC9B,QAAQ,MAAM,KAAK,IAAI;IACvB,SAAS,MAAM,KAAK,IAAI;IACzB;GACF,CAAC;AACF,OAAK,MAAM,YAAY,MAAM,KAAK,UAChC,MAAK,MAAM,YAAY;GACrB,QAAQ,MAAM;GACd,OAAO,MAAM;GACb,MAAM;GACN,OAAO,SAAS,SAAS,SAAS;GAClC,SAAS,GAAG,SAAS,SAAS,KAAK,SAAS,UAAU;GACtD,KAAK,YAAY,MAAM,KAAK,IAAI,GAAG,YAAY,SAAS;GACxD,MAAM;GACP,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { GoalService, normalizeGoalUiLocale } from './goal-service.js';
|
|
2
|
+
export { GoalStore } from './goal-store.js';
|
|
3
|
+
export { GoalRunner } from './goal-runner.js';
|
|
4
|
+
export { GoalQueueStore } from './goal-queue-store.js';
|
|
5
|
+
export { GoalNotificationService } from './goal-notifications.js';
|
|
6
|
+
export { GoalWorkflowJudge } from './goal-workflow-judge.js';
|
|
7
|
+
export type * from './types.js';
|
|
8
|
+
export type * from './goal-queue-types.js';
|
|
9
|
+
export type * from './goal-notifications.js';
|
|
10
|
+
export type * from './goal-workflow-judge.js';
|