@xopcai/xopc 0.0.110 → 0.0.112
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/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/update-offset-store.js +1 -1
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/apple-touch-icon.png +0 -0
- package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +41 -0
- package/dist/gateway/static/root/assets/agent-avatar-dicebear-EhRp-ZMa.js +1 -0
- package/dist/gateway/static/root/assets/agent-browser-settings-page-H4foVCiS.js +6 -0
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-DDNw2oNU.js +1 -0
- package/dist/gateway/static/root/assets/agents-E_X2kzS1.js +71 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-BIy7KEsM.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-DGQG8NwA.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-BZLvInLr.js +1 -0
- package/dist/gateway/static/root/assets/archive-plugin-uuQPupqx.js +1 -0
- package/dist/gateway/static/root/assets/attachment-load-DBkv0cAv.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-DxxN_VAR.js +2 -0
- package/dist/gateway/static/root/assets/block-editor-CwnUlRmO.js +180 -0
- package/dist/gateway/static/root/assets/channels-settings-BHvUKlzw.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-BD-NcD5d.js +3 -0
- package/dist/gateway/static/root/assets/config-reload-event-Bjh2zoKp.js +1 -0
- package/dist/gateway/static/root/assets/connectors-settings-VBzXcEXL.js +2 -0
- package/dist/gateway/static/root/assets/cron-api-C5DoipZA.js +1 -0
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-BLTpdm34.js +3 -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-DSVhXTPq.js +1 -0
- package/dist/gateway/static/root/assets/extension-debug-page-BDHA9o_e.js +1 -0
- package/dist/gateway/static/root/assets/{extension-page-W1wiG38F.js → extension-page-DmDLVSPE.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-1124aHw_.js +1 -0
- package/dist/gateway/static/root/assets/fetch-DOe56Wmy.js +1 -0
- package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +2 -0
- package/dist/gateway/static/root/assets/format-interval-label-tsMSvBSR.js +1 -0
- package/dist/gateway/static/root/assets/gateway-config-api-CsD4FC9D.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-HQ8FBhY2.js +1 -0
- package/dist/gateway/static/root/assets/gateway-startup-retry-C1zg7pH3.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-BG3Onph0.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-DgeKn8zL.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-B5nI6lgz.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-config-api-CIv42nJD.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-DFcVuJ3M.js +1 -0
- package/dist/gateway/static/root/assets/html-workspace-editor-CQLWDiwE.js +1 -0
- package/dist/gateway/static/root/assets/index-5A_ZaABy.css +1 -0
- package/dist/gateway/static/root/assets/index-BTmbp2AU.js +121 -0
- package/dist/gateway/static/root/assets/interval-presets-DGP3S7OB.js +1 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-fETaDYQP.js +1 -0
- package/dist/gateway/static/root/assets/locale-store-DjbfSsfA.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-B1-b27lK.js +2 -0
- package/dist/gateway/static/root/assets/markdown-editor-AssmZFx4.js +2 -0
- package/dist/gateway/static/root/assets/markdown-split-CgeBJMOD.js +1 -0
- package/dist/gateway/static/root/assets/media-plugins-C30GzlV2.js +1 -0
- package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +134 -0
- package/dist/gateway/static/root/assets/messages-BUUfPaZ9.js +3 -0
- package/dist/gateway/static/root/assets/middleware-Pd0e8Igk.js +1 -0
- package/dist/gateway/static/root/assets/models-hub-panel-DPcTS1-u.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-xeGb4owe.js +2 -0
- package/dist/gateway/static/root/assets/note-image-lightbox-t1g0qZYh.js +1 -0
- package/dist/gateway/static/root/assets/note-time-hm6JO_Wi.js +1 -0
- package/dist/gateway/static/root/assets/notes-page-C_TdnKBe.js +1 -0
- package/dist/gateway/static/root/assets/preview-open-alternatives-DeWp9x5g.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BtkPmJIN.js +1 -0
- package/dist/gateway/static/root/assets/save-bar-controls-BOaAOJI3.js +1 -0
- package/dist/gateway/static/root/assets/schedule-field-BLWLKqgw.js +1 -0
- package/dist/gateway/static/root/assets/schema-form-plqRFYT8.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-DOUjxzJm.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-qK_bnTrw.js +1 -0
- package/dist/gateway/static/root/assets/settings-collapsible-section-BP5zRrDI.js +1 -0
- package/dist/gateway/static/root/assets/settings-form-section-Bv8MZplG.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-DmDfE1ww.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-BEFwNcIZ.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-4OX1YCgp.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-CbKmJZot.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-YdtnUHtK.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DwW1IzQ0.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-CGy4f_s2.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-BMuMvzl_.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-CjGHnDvN.js +1 -0
- package/dist/gateway/static/root/assets/use-settings-tab-guard-BMMFa0oA.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-DnRbhMNq.js +1 -0
- package/dist/gateway/static/root/assets/voice-player-store-D5vzWwls.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-page.utils-EYg_xBQS.js → workflow-page.utils-tjGpRVnw.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-DqqHKGj2.js +18 -0
- package/dist/gateway/static/root/favicon-16x16.png +0 -0
- package/dist/gateway/static/root/favicon-32x32.png +0 -0
- package/dist/gateway/static/root/favicon.ico +0 -0
- package/dist/gateway/static/root/favicon.svg +14 -12
- package/dist/gateway/static/root/index.html +18 -15
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +28 -2
- package/dist/src/agent/agent-manager.js +82 -11
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/context/workspace-state.js +1 -1
- package/dist/src/agent/context/workspace.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 +3 -16
- 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 +3 -2
- 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 +70 -25
- 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/image/load-image-media.js +2 -2
- package/dist/src/agent/ipc/inbox.js +3 -3
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/memory-flush.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/messaging/command-handler.d.ts +7 -0
- package/dist/src/agent/messaging/command-handler.js +11 -2
- package/dist/src/agent/messaging/command-handler.js.map +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/memory/index.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- 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/reconcile-dreaming-cron.js +8 -5
- package/dist/src/agent/service/reconcile-dreaming-cron.js.map +1 -1
- package/dist/src/agent/service.d.ts +2 -1
- package/dist/src/agent/service.js +30 -6
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +12 -0
- package/dist/src/agent/session/session-config-service.d.ts +8 -0
- package/dist/src/agent/session/session-config-service.js +20 -0
- package/dist/src/agent/session/session-config-service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +2 -2
- package/dist/src/agent/skills/filesystem-watcher.d.ts +19 -0
- package/dist/src/agent/skills/filesystem-watcher.js +182 -0
- package/dist/src/agent/skills/filesystem-watcher.js.map +1 -0
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +30 -36
- package/dist/src/agent/skills/hub-pull.js.map +1 -1
- package/dist/src/agent/skills/index.js +82 -38
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/installer.js +2 -2
- package/dist/src/agent/skills/managed-store.d.ts +19 -0
- package/dist/src/agent/skills/managed-store.js +97 -38
- package/dist/src/agent/skills/managed-store.js.map +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.d.ts +16 -6
- package/dist/src/agent/skills/skill-manager.js +79 -24
- package/dist/src/agent/skills/skill-manager.js.map +1 -1
- package/dist/src/agent/skills/skill-view-path.js +1 -1
- package/dist/src/agent/skills/test-framework.js +1 -1
- package/dist/src/agent/skills/types.d.ts +11 -0
- package/dist/src/agent/skills/watcher.js +1 -1
- package/dist/src/agent/starter-agents.js +1 -1
- package/dist/src/agent/tools/cronjob-tool.d.ts +8 -3
- package/dist/src/agent/tools/cronjob-tool.js +82 -24
- package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +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 +17 -4
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/find.js +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/grep.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- 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/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.d.ts +1 -0
- package/dist/src/agent/tools/workflow-tool.js +11 -3
- 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/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workspace-runtime/registry.d.ts +5 -0
- package/dist/src/agent/workspace-runtime/registry.js +7 -0
- package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
- package/dist/src/ai-assist/text-assist.d.ts +39 -0
- package/dist/src/ai-assist/text-assist.js +234 -0
- package/dist/src/ai-assist/text-assist.js.map +1 -0
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/profiles/store.js +2 -2
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +4 -4
- package/dist/src/browser/providers/cloakbrowser.js +5 -5
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +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/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/agent-edit.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +3 -3
- 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/system.js +11 -4
- package/dist/src/chat-commands/builtins/system.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 +6 -0
- package/dist/src/chat-commands/context.js +12 -0
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +7 -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/config.js +1 -1
- package/dist/src/cli/commands/cron.js +55 -16
- package/dist/src/cli/commands/cron.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +2 -83
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-create.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +2 -2
- package/dist/src/cli/commands/extension-marketplace.js +2 -2
- package/dist/src/cli/commands/extension-pack.js +2 -2
- package/dist/src/cli/commands/extension.js +3 -3
- package/dist/src/cli/commands/gateway/logs.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/image.js +1 -1
- package/dist/src/cli/commands/init.js +2 -2
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +11 -5
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/skills-test.js +1 -1
- package/dist/src/cli/templates.js +1 -1
- package/dist/src/cli/utils/gateway-client.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/agent-typed-models.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +8 -8
- package/dist/src/config/loader.js +4 -4
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/paths.js +1 -1
- package/dist/src/config/profile.js +1 -1
- package/dist/src/config/reload.js +1 -1
- package/dist/src/config/schema.d.ts +115 -2
- package/dist/src/config/schema.js +63 -7
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +14 -1
- package/dist/src/config/web-patch.js +45 -8
- package/dist/src/config/web-patch.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.d.ts +2 -0
- package/dist/src/cron/executor.js +126 -70
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/index.d.ts +1 -1
- package/dist/src/cron/index.js +3 -3
- package/dist/src/cron/job-content.js +1 -0
- package/dist/src/cron/job-content.js.map +1 -1
- package/dist/src/cron/run-log-store.d.ts +1 -0
- package/dist/src/cron/run-log-store.js +4 -2
- package/dist/src/cron/run-log-store.js.map +1 -1
- package/dist/src/cron/schedule.d.ts +10 -0
- package/dist/src/cron/schedule.js +85 -0
- package/dist/src/cron/schedule.js.map +1 -0
- package/dist/src/cron/service.d.ts +34 -77
- package/dist/src/cron/service.js +327 -264
- package/dist/src/cron/service.js.map +1 -1
- package/dist/src/cron/types.d.ts +97 -49
- package/dist/src/cron/validation.d.ts +374 -86
- package/dist/src/cron/validation.js +156 -129
- package/dist/src/cron/validation.js.map +1 -1
- package/dist/src/cron/workflow-run-completion.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +2 -2
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/install.js +2 -2
- package/dist/src/extensions/loader.js +2 -2
- package/dist/src/extensions/lockfile.js +3 -3
- package/dist/src/extensions/security.js +1 -1
- package/dist/src/extensions/update.js +2 -2
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/chat-stream/mapper.d.ts +1 -0
- package/dist/src/gateway/chat-stream/mapper.js +6 -2
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +2 -0
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.d.ts +14 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth-async.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/ai-assist.d.ts +3 -0
- package/dist/src/gateway/hono/routes/ai-assist.js +66 -0
- package/dist/src/gateway/hono/routes/ai-assist.js.map +1 -0
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +7 -0
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/cron.js +24 -5
- package/dist/src/gateway/hono/routes/cron.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- 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 +90 -3
- package/dist/src/gateway/hono/routes/home.js.map +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +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/shares.js +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +8 -4
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +2 -2
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -0
- package/dist/src/gateway/service/agent-runner.js +8 -4
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +22 -10
- package/dist/src/gateway/service/marketplace-service.js +46 -5
- package/dist/src/gateway/service/marketplace-service.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 +79 -6
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +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/i18n/goals-bundle.js +1 -1
- package/dist/src/i18n/index.js +1 -1
- package/dist/src/i18n/share-tool-bundle.js +2 -2
- package/dist/src/infra/brew.js +1 -1
- package/dist/src/infra/package-json.js +1 -1
- package/dist/src/infra/package-update-steps.js +1 -1
- package/dist/src/infra/path-env.js +2 -2
- package/dist/src/infra/restart.js +1 -1
- package/dist/src/infra/stable-node-path.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +2 -2
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +1 -1
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/media/store.js +1 -1
- package/dist/src/notes/agent-context.js +1 -1
- package/dist/src/notes/service.js +1 -1
- package/dist/src/notes/store.js +2 -2
- package/dist/src/project-trust/trust-store.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +1 -1
- package/dist/src/providers/model-registry.js +4 -4
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/resolve-session.js +3 -3
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.js +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/storage/sqlite/connection.js +1 -1
- package/dist/src/storage/sqlite/cron-job-repository.d.ts +6 -0
- package/dist/src/storage/sqlite/cron-job-repository.js +70 -0
- package/dist/src/storage/sqlite/cron-job-repository.js.map +1 -0
- package/dist/src/storage/sqlite/cron-run-repository.js +0 -1
- package/dist/src/storage/sqlite/cron-run-repository.js.map +1 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -0
- package/dist/src/storage/sqlite/index.js +2 -1
- package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
- 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/009_cron_jobs.sql +24 -0
- package/dist/src/storage/sqlite/migrations/discover.js +1 -1
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +4 -4
- 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 +2 -2
- package/dist/src/storage/sqlite/schema.sql +188 -0
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/extension-host/load-extensions.js +1 -1
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-command-formatters.js +4 -4
- package/dist/src/tui/tui-commands.js +2 -2
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +6 -6
- package/dist/src/tunnel/frpc-binary.js +4 -4
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/utils/logger/streams.js +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/domain/run.d.ts +1 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
- package/dist/src/workflows/engine/projector.js +23 -14
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +1 -0
- package/dist/src/workflows/engine/workflow-engine.js +36 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +7 -3
- 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 +8 -1
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/dist/src/workflows/store/event-store.js +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 +15 -22
- package/dist/src/workflows/store/run-store.js.map +1 -1
- package/package.json +10 -5
- 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/gateway/static/root/favicon-16.png +0 -0
- package/dist/gateway/static/root/favicon-32.png +0 -0
- 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/src/cron/persistence.d.ts +0 -62
- package/dist/src/cron/persistence.js +0 -188
- package/dist/src/cron/persistence.js.map +0 -1
- /package/dist/gateway/static/root/assets/{note-detail-page-D4ZIVQbk.css → block-editor-D4ZIVQbk.css} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checklist-judge.js","names":[],"sources":["../../../../src/agent/goals/checklist-judge.ts"],"sourcesContent":["import type { UserMessage } from '@earendil-works/pi-ai';\nimport { complete } from '@earendil-works/pi-ai';\n\nimport { resolveModel } from '../../providers/index.js';\n\nimport {\n DEFAULT_JUDGE_TIMEOUT_MS,\n extractAssistantText,\n getAssistantMessageErrorReason,\n resolveGoalJudgeApiKey,\n stripCodeFences,\n truncateGoalText,\n} from './judge.js';\nimport type { GoalUiLocale } from './goal-locale.js';\nimport {\n goalUiLocaleOrFallback,\n judgeReasonText,\n judgeResponseLanguageNote,\n JUDGE_REASON_EN,\n localizeJudgeReasonText,\n} from './goal-locale.js';\n\nconst GOAL_TRUNC = 4000;\nconst RESPONSE_SNIPPET = 4000;\nconst HISTORY_TRUNC = 24_000;\n\nconst DECOMPOSE_SYSTEM = (\n 'You break a user goal into an EXTREMELY detailed checklist of concrete, verifiable completion criteria. ' +\n 'Bias toward more items. Each item is one factual statement about finished work.\\n\\n' +\n 'Reply ONLY with a single JSON object on one line:\\n' +\n '{\"items\":[{\"text\":\"...\"},...]}\\n' +\n 'Use at least 3 items when the goal warrants it.'\n);\n\nconst DECOMPOSE_USER = 'Goal:\\n{goal}\\n\\nReturn JSON only.';\n\nconst EVALUATE_CHECKLIST_SYSTEM = (\n 'You evaluate an autonomous agent\\'s progress on a goal with a numbered checklist.\\n' +\n 'For each pending item, decide if evidence in the agent snippet and/or history excerpt shows it is satisfied.\\n' +\n 'Flip pending→completed only with clear evidence; pending→impossible only if truly unachievable here.\\n' +\n 'Do not regress completed/impossible items — omit them from updates.\\n\\n' +\n 'Reply ONLY with one JSON object on one line. Field \"updates\" is an array of ' +\n '{\"index\": <1-based number>, \"status\": \"completed\" or \"impossible\", \"evidence\": \"short citation\"}. ' +\n 'Field \"new_items\" is an array of {\"text\": \"...\"} for missing criteria. ' +\n 'Field \"reason\" is one sentence. updates and new_items may be empty arrays.'\n);\n\nfunction extractJsonObject(raw: string): Record<string, unknown> | null {\n if (!raw?.trim()) return null;\n const text = stripCodeFences(raw);\n try {\n const data = JSON.parse(text) as unknown;\n return data && typeof data === 'object' && !Array.isArray(data) ? (data as Record<string, unknown>) : null;\n } catch {\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start === -1 || end <= start) return null;\n try {\n const data = JSON.parse(text.slice(start, end + 1)) as unknown;\n return data && typeof data === 'object' && !Array.isArray(data) ? (data as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n }\n}\n\nexport type DecomposeChecklistResult = {\n items: { text: string }[];\n parseFailed: boolean;\n errorReason?: string;\n};\n\nexport async function decomposeGoalChecklist(opts: {\n goal: string;\n judgeModelRef: string;\n signal?: AbortSignal;\n judgeTimeoutMs?: number;\n uiLocale?: GoalUiLocale;\n}): Promise<DecomposeChecklistResult> {\n const locale = goalUiLocaleOrFallback(opts.uiLocale);\n const goal = opts.goal.trim();\n if (!goal)\n return { items: [], parseFailed: false, errorReason: judgeReasonText('empty_goal', locale) };\n\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(opts.judgeModelRef);\n } catch {\n return {\n items: [],\n parseFailed: false,\n errorReason: judgeReasonText('judge_model_not_configured', locale),\n };\n }\n\n const timeoutMs =\n typeof opts.judgeTimeoutMs === 'number' && Number.isFinite(opts.judgeTimeoutMs)\n ? Math.max(5_000, Math.min(120_000, Math.floor(opts.judgeTimeoutMs)))\n : DEFAULT_JUDGE_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const merged = opts.signal ? AbortSignal.any([opts.signal, controller.signal]) : controller.signal;\n\n try {\n const user: UserMessage = {\n role: 'user',\n content:\n `${DECOMPOSE_SYSTEM}\\n\\n${DECOMPOSE_USER.replace('{goal}', truncateGoalText(goal, GOAL_TRUNC))}` +\n judgeResponseLanguageNote(locale),\n timestamp: Date.now(),\n };\n const apiKey = await resolveGoalJudgeApiKey(model);\n const result = await complete(\n model,\n { messages: [user] },\n { apiKey, maxTokens: 2000, temperature: 0, signal: merged },\n );\n const errorReason = getAssistantMessageErrorReason(result);\n if (errorReason) {\n return {\n items: [],\n parseFailed: false,\n errorReason: judgeReasonText('decompose_call_failed', locale),\n };\n }\n\n const text = extractAssistantText(result.content);\n const data = extractJsonObject(text);\n if (!data)\n return {\n items: [],\n parseFailed: true,\n errorReason: judgeReasonText('decompose_reply_not_json', locale),\n };\n const rawItems = data.items ?? data.checklist;\n if (!Array.isArray(rawItems))\n return {\n items: [],\n parseFailed: true,\n errorReason: judgeReasonText('missing_items_array', locale),\n };\n const items: { text: string }[] = [];\n for (const row of rawItems) {\n if (typeof row === 'string') {\n const t = row.trim();\n if (t) items.push({ text: t });\n } else if (row && typeof row === 'object' && !Array.isArray(row)) {\n const t = String((row as { text?: string }).text ?? '').trim();\n if (t) items.push({ text: t });\n }\n }\n if (!items.length)\n return { items: [], parseFailed: true, errorReason: judgeReasonText('empty_checklist', locale) };\n return { items, parseFailed: false };\n } catch {\n return {\n items: [],\n parseFailed: false,\n errorReason: judgeReasonText('decompose_call_failed', locale),\n };\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport type ChecklistJudgeUpdate = {\n index: number;\n status: 'completed' | 'impossible';\n evidence?: string | null;\n};\n\nexport type ChecklistEvaluateParsed = {\n updates: ChecklistJudgeUpdate[];\n newItems: { text: string }[];\n reason: string;\n};\n\nexport type EvaluateChecklistResult = {\n parsed: ChecklistEvaluateParsed;\n parseFailed: boolean;\n};\n\nexport async function evaluateGoalChecklistJudge(opts: {\n goal: string;\n numberedChecklist: string;\n lastResponse: string;\n historyExcerpt: string;\n judgeModelRef: string;\n signal?: AbortSignal;\n judgeTimeoutMs?: number;\n uiLocale?: GoalUiLocale;\n}): Promise<EvaluateChecklistResult> {\n const locale = goalUiLocaleOrFallback(opts.uiLocale);\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(opts.judgeModelRef);\n } catch {\n return {\n parsed: {\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_model_not_configured', locale),\n },\n parseFailed: false,\n };\n }\n\n const userBody =\n `Goal:\\n${truncateGoalText(opts.goal, 2000)}\\n\\n` +\n `Current checklist (1-based indices):\\n${opts.numberedChecklist}\\n\\n` +\n `Agent's most recent response (snippet):\\n${truncateGoalText(opts.lastResponse, RESPONSE_SNIPPET)}\\n\\n` +\n `Recent conversation excerpt (JSON or text, may be truncated):\\n` +\n `${truncateGoalText(opts.historyExcerpt, HISTORY_TRUNC) || '(none)'}`;\n\n const timeoutMs =\n typeof opts.judgeTimeoutMs === 'number' && Number.isFinite(opts.judgeTimeoutMs)\n ? Math.max(5_000, Math.min(120_000, Math.floor(opts.judgeTimeoutMs)))\n : DEFAULT_JUDGE_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const merged = opts.signal ? AbortSignal.any([opts.signal, controller.signal]) : controller.signal;\n\n try {\n const user: UserMessage = {\n role: 'user',\n content: `${EVALUATE_CHECKLIST_SYSTEM}\\n\\n${userBody}` + judgeResponseLanguageNote(locale),\n timestamp: Date.now(),\n };\n const apiKey = await resolveGoalJudgeApiKey(model);\n const result = await complete(\n model,\n { messages: [user] },\n { apiKey, maxTokens: 1500, temperature: 0, signal: merged },\n );\n const errorReason = getAssistantMessageErrorReason(result);\n if (errorReason) {\n return {\n parsed: {\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_call_failed', locale),\n },\n parseFailed: false,\n };\n }\n\n const text = extractAssistantText(result.content);\n const data = extractJsonObject(text);\n if (!data) {\n return {\n parsed: {\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_reply_not_json', locale),\n },\n parseFailed: true,\n };\n }\n const updatesRaw = data.updates;\n const newRaw = data.new_items ?? data.newItems;\n const trimmed = typeof data.reason === 'string' ? data.reason.trim() : '';\n const inner = trimmed || JUDGE_REASON_EN.no_reason_provided;\n const reason = localizeJudgeReasonText(inner, locale);\n const updates: ChecklistJudgeUpdate[] = [];\n if (Array.isArray(updatesRaw)) {\n for (const u of updatesRaw) {\n if (!u || typeof u !== 'object' || Array.isArray(u)) continue;\n const rec = u as Record<string, unknown>;\n const idx1 = Number(rec.index);\n if (!Number.isFinite(idx1)) continue;\n const idx0 = Math.floor(idx1) - 1;\n const st = String(rec.status ?? '').trim().toLowerCase();\n if (st !== 'completed' && st !== 'impossible') continue;\n const evidence = typeof rec.evidence === 'string' ? rec.evidence : null;\n updates.push({ index: idx0, status: st, evidence });\n }\n }\n const newItems: { text: string }[] = [];\n if (Array.isArray(newRaw)) {\n for (const row of newRaw) {\n if (typeof row === 'string') {\n const t = row.trim();\n if (t) newItems.push({ text: t });\n } else if (row && typeof row === 'object' && !Array.isArray(row)) {\n const t = String((row as { text?: string }).text ?? '').trim();\n if (t) newItems.push({ text: t });\n }\n }\n }\n return {\n parsed: {\n updates,\n newItems,\n reason: reason || judgeReasonText('no_reason_provided', locale),\n },\n parseFailed: false,\n };\n } catch {\n return {\n parsed: {\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_call_failed', locale),\n },\n parseFailed: false,\n };\n } finally {\n clearTimeout(timer);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"checklist-judge.js","names":[],"sources":["../../../../src/agent/goals/checklist-judge.ts"],"sourcesContent":["import type { UserMessage } from '@earendil-works/pi-ai';\nimport { complete } from '@earendil-works/pi-ai';\n\nimport { resolveModel } from '../../providers/index.js';\n\nimport {\n DEFAULT_JUDGE_TIMEOUT_MS,\n extractAssistantText,\n getAssistantMessageErrorReason,\n resolveGoalJudgeApiKey,\n stripCodeFences,\n truncateGoalText,\n} from './judge.js';\nimport type { GoalUiLocale } from './goal-locale.js';\nimport {\n goalUiLocaleOrFallback,\n judgeReasonText,\n judgeResponseLanguageNote,\n JUDGE_REASON_EN,\n localizeJudgeReasonText,\n} from './goal-locale.js';\n\nconst GOAL_TRUNC = 4000;\nconst RESPONSE_SNIPPET = 4000;\nconst HISTORY_TRUNC = 24_000;\n\nconst DECOMPOSE_SYSTEM = (\n 'You break a user goal into an EXTREMELY detailed checklist of concrete, verifiable completion criteria. ' +\n 'Bias toward more items. Each item is one factual statement about finished work.\\n\\n' +\n 'Reply ONLY with a single JSON object on one line:\\n' +\n '{\"items\":[{\"text\":\"...\"},...]}\\n' +\n 'Use at least 3 items when the goal warrants it.'\n);\n\nconst DECOMPOSE_USER = 'Goal:\\n{goal}\\n\\nReturn JSON only.';\n\nconst EVALUATE_CHECKLIST_SYSTEM = (\n 'You evaluate an autonomous agent\\'s progress on a goal with a numbered checklist.\\n' +\n 'For each pending item, decide if evidence in the agent snippet and/or history excerpt shows it is satisfied.\\n' +\n 'Flip pending→completed only with clear evidence; pending→impossible only if truly unachievable here.\\n' +\n 'Do not regress completed/impossible items — omit them from updates.\\n\\n' +\n 'Reply ONLY with one JSON object on one line:\\n' +\n '{\"verdict\":\"continue|done|blocked|needs_input\",\"confidence\":0.0,\"reason\":\"...\",' +\n '\"nextAction\":\"...\",\"missingEvidence\":[\"...\"],\"userQuestion\":\"...\",' +\n '\"updates\":[{\"index\":1,\"status\":\"completed|impossible\",\"evidence\":\"short citation\"}],' +\n '\"new_items\":[{\"text\":\"...\"}]}\\n' +\n 'Use verdict=done only when all checklist criteria are complete/impossible. ' +\n 'Use needs_input when the next step requires user input. Use blocked when external progress is impossible.'\n);\n\nfunction extractJsonObject(raw: string): Record<string, unknown> | null {\n if (!raw?.trim()) return null;\n const text = stripCodeFences(raw);\n try {\n const data = JSON.parse(text) as unknown;\n return data && typeof data === 'object' && !Array.isArray(data) ? (data as Record<string, unknown>) : null;\n } catch {\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start === -1 || end <= start) return null;\n try {\n const data = JSON.parse(text.slice(start, end + 1)) as unknown;\n return data && typeof data === 'object' && !Array.isArray(data) ? (data as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n }\n}\n\nexport type DecomposeChecklistResult = {\n items: { text: string }[];\n parseFailed: boolean;\n errorReason?: string;\n};\n\nexport async function decomposeGoalChecklist(opts: {\n goal: string;\n judgeModelRef: string;\n signal?: AbortSignal;\n judgeTimeoutMs?: number;\n uiLocale?: GoalUiLocale;\n}): Promise<DecomposeChecklistResult> {\n const locale = goalUiLocaleOrFallback(opts.uiLocale);\n const goal = opts.goal.trim();\n if (!goal)\n return { items: [], parseFailed: false, errorReason: judgeReasonText('empty_goal', locale) };\n\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(opts.judgeModelRef);\n } catch {\n return {\n items: [],\n parseFailed: false,\n errorReason: judgeReasonText('judge_model_not_configured', locale),\n };\n }\n\n const timeoutMs =\n typeof opts.judgeTimeoutMs === 'number' && Number.isFinite(opts.judgeTimeoutMs)\n ? Math.max(5_000, Math.min(120_000, Math.floor(opts.judgeTimeoutMs)))\n : DEFAULT_JUDGE_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const merged = opts.signal ? AbortSignal.any([opts.signal, controller.signal]) : controller.signal;\n\n try {\n const user: UserMessage = {\n role: 'user',\n content:\n `${DECOMPOSE_SYSTEM}\\n\\n${DECOMPOSE_USER.replace('{goal}', truncateGoalText(goal, GOAL_TRUNC))}` +\n judgeResponseLanguageNote(locale),\n timestamp: Date.now(),\n };\n const apiKey = await resolveGoalJudgeApiKey(model);\n const result = await complete(\n model,\n { messages: [user] },\n { apiKey, maxTokens: 2000, temperature: 0, signal: merged },\n );\n const errorReason = getAssistantMessageErrorReason(result);\n if (errorReason) {\n return {\n items: [],\n parseFailed: false,\n errorReason: judgeReasonText('decompose_call_failed', locale),\n };\n }\n\n const text = extractAssistantText(result.content);\n const data = extractJsonObject(text);\n if (!data)\n return {\n items: [],\n parseFailed: true,\n errorReason: judgeReasonText('decompose_reply_not_json', locale),\n };\n const rawItems = data.items ?? data.checklist;\n if (!Array.isArray(rawItems))\n return {\n items: [],\n parseFailed: true,\n errorReason: judgeReasonText('missing_items_array', locale),\n };\n const items: { text: string }[] = [];\n for (const row of rawItems) {\n if (typeof row === 'string') {\n const t = row.trim();\n if (t) items.push({ text: t });\n } else if (row && typeof row === 'object' && !Array.isArray(row)) {\n const t = String((row as { text?: string }).text ?? '').trim();\n if (t) items.push({ text: t });\n }\n }\n if (!items.length)\n return { items: [], parseFailed: true, errorReason: judgeReasonText('empty_checklist', locale) };\n return { items, parseFailed: false };\n } catch {\n return {\n items: [],\n parseFailed: false,\n errorReason: judgeReasonText('decompose_call_failed', locale),\n };\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport type ChecklistJudgeUpdate = {\n index: number;\n status: 'completed' | 'impossible';\n evidence?: string | null;\n};\n\nexport type ChecklistEvaluateParsed = {\n verdict: 'continue' | 'done' | 'blocked' | 'needs_input';\n confidence: number;\n updates: ChecklistJudgeUpdate[];\n newItems: { text: string }[];\n reason: string;\n nextAction?: string;\n missingEvidence?: string[];\n userQuestion?: string;\n};\n\nexport type EvaluateChecklistResult = {\n parsed: ChecklistEvaluateParsed;\n parseFailed: boolean;\n};\n\nexport async function evaluateGoalChecklistJudge(opts: {\n goal: string;\n numberedChecklist: string;\n lastResponse: string;\n historyExcerpt: string;\n judgeModelRef: string;\n signal?: AbortSignal;\n judgeTimeoutMs?: number;\n uiLocale?: GoalUiLocale;\n}): Promise<EvaluateChecklistResult> {\n const locale = goalUiLocaleOrFallback(opts.uiLocale);\n let model: ReturnType<typeof resolveModel>;\n try {\n model = resolveModel(opts.judgeModelRef);\n } catch {\n return {\n parsed: {\n verdict: 'continue',\n confidence: 0,\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_model_not_configured', locale),\n },\n parseFailed: false,\n };\n }\n\n const userBody =\n `Goal:\\n${truncateGoalText(opts.goal, 2000)}\\n\\n` +\n `Current checklist (1-based indices):\\n${opts.numberedChecklist}\\n\\n` +\n `Agent's most recent response (snippet):\\n${truncateGoalText(opts.lastResponse, RESPONSE_SNIPPET)}\\n\\n` +\n `Recent conversation excerpt (JSON or text, may be truncated):\\n` +\n `${truncateGoalText(opts.historyExcerpt, HISTORY_TRUNC) || '(none)'}`;\n\n const timeoutMs =\n typeof opts.judgeTimeoutMs === 'number' && Number.isFinite(opts.judgeTimeoutMs)\n ? Math.max(5_000, Math.min(120_000, Math.floor(opts.judgeTimeoutMs)))\n : DEFAULT_JUDGE_TIMEOUT_MS;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const merged = opts.signal ? AbortSignal.any([opts.signal, controller.signal]) : controller.signal;\n\n try {\n const user: UserMessage = {\n role: 'user',\n content: `${EVALUATE_CHECKLIST_SYSTEM}\\n\\n${userBody}` + judgeResponseLanguageNote(locale),\n timestamp: Date.now(),\n };\n const apiKey = await resolveGoalJudgeApiKey(model);\n const result = await complete(\n model,\n { messages: [user] },\n { apiKey, maxTokens: 1500, temperature: 0, signal: merged },\n );\n const errorReason = getAssistantMessageErrorReason(result);\n if (errorReason) {\n return {\n parsed: {\n verdict: 'continue',\n confidence: 0,\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_call_failed', locale),\n },\n parseFailed: false,\n };\n }\n\n const text = extractAssistantText(result.content);\n const data = extractJsonObject(text);\n if (!data) {\n return {\n parsed: {\n verdict: 'continue',\n confidence: 0,\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_reply_not_json', locale),\n },\n parseFailed: true,\n };\n }\n const updatesRaw = data.updates;\n const newRaw = data.new_items ?? data.newItems;\n const verdictRaw = String(data.verdict ?? '').trim().toLowerCase();\n const verdict =\n verdictRaw === 'done' || verdictRaw === 'blocked' || verdictRaw === 'needs_input'\n ? verdictRaw\n : 'continue';\n const confidenceRaw = Number(data.confidence);\n const confidence = Number.isFinite(confidenceRaw) ? Math.max(0, Math.min(1, confidenceRaw)) : 0;\n const nextAction = typeof data.nextAction === 'string' ? data.nextAction.trim() : undefined;\n const userQuestion = typeof data.userQuestion === 'string' ? data.userQuestion.trim() : undefined;\n const missingEvidenceRaw = data.missingEvidence ?? data.missing_evidence;\n const trimmed = typeof data.reason === 'string' ? data.reason.trim() : '';\n const inner = trimmed || JUDGE_REASON_EN.no_reason_provided;\n const reason = localizeJudgeReasonText(inner, locale);\n const updates: ChecklistJudgeUpdate[] = [];\n if (Array.isArray(updatesRaw)) {\n for (const u of updatesRaw) {\n if (!u || typeof u !== 'object' || Array.isArray(u)) continue;\n const rec = u as Record<string, unknown>;\n const idx1 = Number(rec.index);\n if (!Number.isFinite(idx1)) continue;\n const idx0 = Math.floor(idx1) - 1;\n const st = String(rec.status ?? '').trim().toLowerCase();\n if (st !== 'completed' && st !== 'impossible') continue;\n const evidence = typeof rec.evidence === 'string' ? rec.evidence : null;\n updates.push({ index: idx0, status: st, evidence });\n }\n }\n const newItems: { text: string }[] = [];\n if (Array.isArray(newRaw)) {\n for (const row of newRaw) {\n if (typeof row === 'string') {\n const t = row.trim();\n if (t) newItems.push({ text: t });\n } else if (row && typeof row === 'object' && !Array.isArray(row)) {\n const t = String((row as { text?: string }).text ?? '').trim();\n if (t) newItems.push({ text: t });\n }\n }\n }\n const missingEvidence: string[] = [];\n if (Array.isArray(missingEvidenceRaw)) {\n for (const item of missingEvidenceRaw) {\n if (typeof item === 'string' && item.trim()) missingEvidence.push(item.trim());\n }\n }\n return {\n parsed: {\n verdict,\n confidence,\n updates,\n newItems,\n reason: reason || judgeReasonText('no_reason_provided', locale),\n ...(nextAction ? { nextAction } : {}),\n ...(missingEvidence.length ? { missingEvidence } : {}),\n ...(userQuestion ? { userQuestion } : {}),\n },\n parseFailed: false,\n };\n } catch {\n return {\n parsed: {\n verdict: 'continue',\n confidence: 0,\n updates: [],\n newItems: [],\n reason: judgeReasonText('judge_call_failed', locale),\n },\n parseFailed: false,\n };\n } finally {\n clearTimeout(timer);\n }\n}\n"],"mappings":"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"}
|
|
@@ -10,9 +10,13 @@ export type GoalPostTurnDecision = {
|
|
|
10
10
|
newState: PersistentGoalState | null;
|
|
11
11
|
shouldContinue: boolean;
|
|
12
12
|
continuationPrompt: string | null;
|
|
13
|
-
verdict: 'done' | 'continue' | 'skipped' | 'inactive' | 'decompose';
|
|
13
|
+
verdict: 'done' | 'continue' | 'blocked' | 'needs_input' | 'skipped' | 'inactive' | 'decompose';
|
|
14
14
|
reason: string;
|
|
15
15
|
message: string;
|
|
16
|
+
confidence?: number;
|
|
17
|
+
missingEvidence?: string[];
|
|
18
|
+
userQuestion?: string;
|
|
19
|
+
completedChecklistItemIndexes?: number[];
|
|
16
20
|
};
|
|
17
21
|
/**
|
|
18
22
|
* Hermes `GoalManager.evaluate_after_turn` equivalent (minus SessionDB I/O).
|
|
@@ -118,6 +118,8 @@ async function evaluateAfterTurnHermesLike(state, lastResponse, judgeModelRef, s
|
|
|
118
118
|
}
|
|
119
119
|
next.lastVerdict = "continue";
|
|
120
120
|
next.lastReason = evalResult.parsed.reason;
|
|
121
|
+
const completedChecklistItemIndexes = evalResult.parsed.updates.filter((update) => update.status === "completed" || update.status === "impossible").map((update) => update.index);
|
|
122
|
+
const continuationPrompt = evalResult.parsed.nextAction?.trim() || buildContinuationPromptFromState(next, locale);
|
|
121
123
|
if (!evalResult.parseFailed && allChecklistTerminal(next.checklist ?? [])) {
|
|
122
124
|
next.status = "done";
|
|
123
125
|
next.lastVerdict = "done";
|
|
@@ -127,7 +129,27 @@ async function evaluateAfterTurnHermesLike(state, lastResponse, judgeModelRef, s
|
|
|
127
129
|
continuationPrompt: null,
|
|
128
130
|
verdict: "done",
|
|
129
131
|
reason: evalResult.parsed.reason,
|
|
130
|
-
message: copy.goalAchieved(evalResult.parsed.reason)
|
|
132
|
+
message: copy.goalAchieved(evalResult.parsed.reason),
|
|
133
|
+
confidence: evalResult.parsed.confidence,
|
|
134
|
+
missingEvidence: evalResult.parsed.missingEvidence,
|
|
135
|
+
userQuestion: evalResult.parsed.userQuestion,
|
|
136
|
+
completedChecklistItemIndexes
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (!evalResult.parseFailed && (evalResult.parsed.verdict === "blocked" || evalResult.parsed.verdict === "needs_input")) {
|
|
140
|
+
next.status = "paused";
|
|
141
|
+
next.pausedReason = evalResult.parsed.reason;
|
|
142
|
+
return {
|
|
143
|
+
newState: next,
|
|
144
|
+
shouldContinue: false,
|
|
145
|
+
continuationPrompt: null,
|
|
146
|
+
verdict: evalResult.parsed.verdict,
|
|
147
|
+
reason: evalResult.parsed.reason,
|
|
148
|
+
message: evalResult.parsed.verdict === "needs_input" ? `Goal needs input: ${evalResult.parsed.userQuestion || evalResult.parsed.reason}` : `Goal blocked: ${evalResult.parsed.reason}`,
|
|
149
|
+
confidence: evalResult.parsed.confidence,
|
|
150
|
+
missingEvidence: evalResult.parsed.missingEvidence,
|
|
151
|
+
userQuestion: evalResult.parsed.userQuestion,
|
|
152
|
+
completedChecklistItemIndexes
|
|
131
153
|
};
|
|
132
154
|
}
|
|
133
155
|
const parseStorm = pauseIfParseStorm(evalResult.parsed.reason);
|
|
@@ -139,10 +161,14 @@ async function evaluateAfterTurnHermesLike(state, lastResponse, judgeModelRef, s
|
|
|
139
161
|
return {
|
|
140
162
|
newState: next,
|
|
141
163
|
shouldContinue: true,
|
|
142
|
-
continuationPrompt
|
|
164
|
+
continuationPrompt,
|
|
143
165
|
verdict: "continue",
|
|
144
166
|
reason: evalResult.parsed.reason,
|
|
145
|
-
message: copy.continuingWithProgress(next.turnsUsed, next.maxTurns, progressSuffix, evalResult.parsed.reason)
|
|
167
|
+
message: copy.continuingWithProgress(next.turnsUsed, next.maxTurns, progressSuffix, evalResult.parsed.reason),
|
|
168
|
+
confidence: evalResult.parsed.confidence,
|
|
169
|
+
missingEvidence: evalResult.parsed.missingEvidence,
|
|
170
|
+
userQuestion: evalResult.parsed.userQuestion,
|
|
171
|
+
completedChecklistItemIndexes
|
|
146
172
|
};
|
|
147
173
|
}
|
|
148
174
|
const j = await judgeGoalHermesStyle(state.goal, lastResponse, judgeModelRef, signal, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate-turn.js","names":[],"sources":["../../../../src/agent/goals/evaluate-turn.ts"],"sourcesContent":["import type { GoalsConfig } from '../../config/schema.js';\n\nimport { decomposeGoalChecklist, evaluateGoalChecklistJudge } from './checklist-judge.js';\nimport { allChecklistTerminal, checklistCounts } from './checklist-types.js';\nimport {\n buildContinuationPromptFromState,\n checklistProgressSuffix,\n CONTINUATION_PROMPT_TEMPLATE_EN,\n CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN,\n goalEvaluateUserCopy,\n resolveGoalUiLocale,\n type GoalUiLocale,\n} from './goal-locale.js';\nimport { judgeGoalHermesStyle } from './judge.js';\nimport {\n applyJudgeChecklistUpdates,\n mergeDecomposedChecklistItems,\n renderChecklistNumbered,\n type PersistentGoalState,\n} from './state.js';\n\n/** Hermes `CONTINUATION_PROMPT_TEMPLATE` (English; parity / tests). */\nexport const CONTINUATION_PROMPT_TEMPLATE = CONTINUATION_PROMPT_TEMPLATE_EN;\n\n/** Hermes `CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE` (English; parity / tests). */\nexport const CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE = CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN;\n\nexport type GoalsEvaluateConfigSlice = Pick<\n GoalsConfig,\n 'checklistMode' | 'maxConsecutiveParseFailures' | 'judgeTimeoutMs' | 'checklistHistoryChars'\n>;\n\nexport type GoalPostTurnDecision = {\n newState: PersistentGoalState | null;\n shouldContinue: boolean;\n continuationPrompt: string | null;\n verdict: 'done' | 'continue' | 'skipped' | 'inactive' | 'decompose';\n reason: string;\n message: string;\n};\n\nfunction cloneState(s: PersistentGoalState): PersistentGoalState {\n return {\n ...s,\n checklist: s.checklist?.map((it) => ({ ...it })),\n };\n}\n\n/**\n * Hermes `GoalManager.evaluate_after_turn` equivalent (minus SessionDB I/O).\n */\nexport async function evaluateAfterTurnHermesLike(\n state: PersistentGoalState,\n lastResponse: string,\n judgeModelRef: string,\n signal?: AbortSignal,\n opts?: { goalsSlice?: Partial<GoalsEvaluateConfigSlice>; historyExcerpt?: string; uiLocale?: GoalUiLocale },\n): Promise<GoalPostTurnDecision> {\n const locale = opts?.uiLocale ?? resolveGoalUiLocale(state);\n const copy = goalEvaluateUserCopy(locale);\n\n if (state.status !== 'active') {\n return {\n newState: state,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'inactive',\n reason: 'no active goal',\n message: '',\n };\n }\n\n const slice = opts?.goalsSlice;\n const checklistMode = slice?.checklistMode !== false;\n const maxParseFailures = slice?.maxConsecutiveParseFailures ?? 3;\n const judgeTimeoutMs = slice?.judgeTimeoutMs;\n\n const next = cloneState(state);\n next.turnsUsed += 1;\n next.lastTurnAt = Date.now();\n\n const bumpParse = () => {\n next.consecutiveParseFailures = (next.consecutiveParseFailures ?? 0) + 1;\n };\n const resetParse = () => {\n next.consecutiveParseFailures = 0;\n };\n\n const pauseIfParseStorm = (reason: string): GoalPostTurnDecision | null => {\n const n = next.consecutiveParseFailures ?? 0;\n if (n < maxParseFailures) return null;\n next.status = 'paused';\n next.pausedReason = `judge parse failures (${n} consecutive)`;\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'continue',\n reason,\n message: copy.pauseParse(n),\n };\n };\n\n const pauseIfBudget = (reason: string): GoalPostTurnDecision | null => {\n if (next.turnsUsed < next.maxTurns) return null;\n next.status = 'paused';\n next.pausedReason = `turn budget exhausted (${next.turnsUsed}/${next.maxTurns})`;\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'continue',\n reason,\n message: copy.pauseBudget(next.turnsUsed, next.maxTurns),\n };\n };\n\n // ── Phase A: decompose (once per goal when checklist mode is on) ──\n if (checklistMode && !next.decomposed) {\n const dec = await decomposeGoalChecklist({\n goal: next.goal,\n judgeModelRef,\n signal,\n judgeTimeoutMs,\n uiLocale: locale,\n });\n next.decomposed = true;\n if (!dec.parseFailed && dec.items.length > 0) {\n const prior = next.checklist ?? [];\n next.checklist = mergeDecomposedChecklistItems(prior, dec.items);\n const mergedCount = next.checklist.length;\n next.lastVerdict = 'decompose';\n next.lastReason = copy.decomposedReason(mergedCount);\n resetParse();\n const budgetEarly = pauseIfBudget(next.lastReason);\n if (budgetEarly) return budgetEarly;\n return {\n newState: next,\n shouldContinue: true,\n continuationPrompt: buildContinuationPromptFromState(next, locale),\n verdict: 'decompose',\n reason: next.lastReason ?? '',\n message: copy.checklistReady(mergedCount),\n };\n }\n next.lastReason = dec.errorReason\n ? copy.decomposeFallbackReason(dec.errorReason)\n : copy.noChecklistFallback();\n }\n\n // ── Phase B: checklist judge ──\n const checklist = next.checklist ?? [];\n if (checklist.length > 0) {\n const evalResult = await evaluateGoalChecklistJudge({\n goal: next.goal,\n numberedChecklist: renderChecklistNumbered(checklist),\n lastResponse,\n historyExcerpt: opts?.historyExcerpt ?? '',\n judgeModelRef,\n signal,\n judgeTimeoutMs,\n uiLocale: locale,\n });\n\n if (evalResult.parseFailed) {\n bumpParse();\n } else {\n resetParse();\n next.checklist = applyJudgeChecklistUpdates(checklist, {\n updates: evalResult.parsed.updates,\n newItems: evalResult.parsed.newItems,\n });\n }\n\n next.lastVerdict = 'continue';\n next.lastReason = evalResult.parsed.reason;\n\n if (!evalResult.parseFailed && allChecklistTerminal(next.checklist ?? [])) {\n next.status = 'done';\n next.lastVerdict = 'done';\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'done',\n reason: evalResult.parsed.reason,\n message: copy.goalAchieved(evalResult.parsed.reason),\n };\n }\n\n const parseStorm = pauseIfParseStorm(evalResult.parsed.reason);\n if (parseStorm) return parseStorm;\n\n const budget = pauseIfBudget(evalResult.parsed.reason);\n if (budget) return budget;\n\n const { total, completed, impossible } = checklistCounts(next.checklist ?? []);\n const done = completed + impossible;\n const progressSuffix = checklistProgressSuffix(done, total, locale);\n\n return {\n newState: next,\n shouldContinue: true,\n continuationPrompt: buildContinuationPromptFromState(next, locale),\n verdict: 'continue',\n reason: evalResult.parsed.reason,\n message: copy.continuingWithProgress(\n next.turnsUsed,\n next.maxTurns,\n progressSuffix,\n evalResult.parsed.reason,\n ),\n };\n }\n\n // ── Freeform judge (no checklist) ──\n const j = await judgeGoalHermesStyle(state.goal, lastResponse, judgeModelRef, signal, {\n judgeTimeoutMs,\n uiLocale: locale,\n });\n next.lastVerdict = j.verdict === 'skipped' ? 'skipped' : j.verdict;\n next.lastReason = j.reason;\n\n if (j.parseFailed) bumpParse();\n else resetParse();\n\n if (j.verdict === 'done') {\n next.status = 'done';\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'done',\n reason: j.reason,\n message: copy.goalAchieved(j.reason),\n };\n }\n\n const parseStorm = pauseIfParseStorm(j.reason);\n if (parseStorm) return parseStorm;\n\n const budget = pauseIfBudget(j.reason);\n if (budget) return budget;\n\n return {\n newState: next,\n shouldContinue: true,\n continuationPrompt: buildContinuationPromptFromState(next, locale),\n verdict: 'continue',\n reason: j.reason,\n message: copy.continuing(next.turnsUsed, next.maxTurns, j.reason),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"evaluate-turn.js","names":[],"sources":["../../../../src/agent/goals/evaluate-turn.ts"],"sourcesContent":["import type { GoalsConfig } from '../../config/schema.js';\n\nimport { decomposeGoalChecklist, evaluateGoalChecklistJudge } from './checklist-judge.js';\nimport { allChecklistTerminal, checklistCounts } from './checklist-types.js';\nimport {\n buildContinuationPromptFromState,\n checklistProgressSuffix,\n CONTINUATION_PROMPT_TEMPLATE_EN,\n CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN,\n goalEvaluateUserCopy,\n resolveGoalUiLocale,\n type GoalUiLocale,\n} from './goal-locale.js';\nimport { judgeGoalHermesStyle } from './judge.js';\nimport {\n applyJudgeChecklistUpdates,\n mergeDecomposedChecklistItems,\n renderChecklistNumbered,\n type PersistentGoalState,\n} from './state.js';\n\n/** Hermes `CONTINUATION_PROMPT_TEMPLATE` (English; parity / tests). */\nexport const CONTINUATION_PROMPT_TEMPLATE = CONTINUATION_PROMPT_TEMPLATE_EN;\n\n/** Hermes `CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE` (English; parity / tests). */\nexport const CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE = CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN;\n\nexport type GoalsEvaluateConfigSlice = Pick<\n GoalsConfig,\n 'checklistMode' | 'maxConsecutiveParseFailures' | 'judgeTimeoutMs' | 'checklistHistoryChars'\n>;\n\nexport type GoalPostTurnDecision = {\n newState: PersistentGoalState | null;\n shouldContinue: boolean;\n continuationPrompt: string | null;\n verdict: 'done' | 'continue' | 'blocked' | 'needs_input' | 'skipped' | 'inactive' | 'decompose';\n reason: string;\n message: string;\n confidence?: number;\n missingEvidence?: string[];\n userQuestion?: string;\n completedChecklistItemIndexes?: number[];\n};\n\nfunction cloneState(s: PersistentGoalState): PersistentGoalState {\n return {\n ...s,\n checklist: s.checklist?.map((it) => ({ ...it })),\n };\n}\n\n/**\n * Hermes `GoalManager.evaluate_after_turn` equivalent (minus SessionDB I/O).\n */\nexport async function evaluateAfterTurnHermesLike(\n state: PersistentGoalState,\n lastResponse: string,\n judgeModelRef: string,\n signal?: AbortSignal,\n opts?: { goalsSlice?: Partial<GoalsEvaluateConfigSlice>; historyExcerpt?: string; uiLocale?: GoalUiLocale },\n): Promise<GoalPostTurnDecision> {\n const locale = opts?.uiLocale ?? resolveGoalUiLocale(state);\n const copy = goalEvaluateUserCopy(locale);\n\n if (state.status !== 'active') {\n return {\n newState: state,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'inactive',\n reason: 'no active goal',\n message: '',\n };\n }\n\n const slice = opts?.goalsSlice;\n const checklistMode = slice?.checklistMode !== false;\n const maxParseFailures = slice?.maxConsecutiveParseFailures ?? 3;\n const judgeTimeoutMs = slice?.judgeTimeoutMs;\n\n const next = cloneState(state);\n next.turnsUsed += 1;\n next.lastTurnAt = Date.now();\n\n const bumpParse = () => {\n next.consecutiveParseFailures = (next.consecutiveParseFailures ?? 0) + 1;\n };\n const resetParse = () => {\n next.consecutiveParseFailures = 0;\n };\n\n const pauseIfParseStorm = (reason: string): GoalPostTurnDecision | null => {\n const n = next.consecutiveParseFailures ?? 0;\n if (n < maxParseFailures) return null;\n next.status = 'paused';\n next.pausedReason = `judge parse failures (${n} consecutive)`;\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'continue',\n reason,\n message: copy.pauseParse(n),\n };\n };\n\n const pauseIfBudget = (reason: string): GoalPostTurnDecision | null => {\n if (next.turnsUsed < next.maxTurns) return null;\n next.status = 'paused';\n next.pausedReason = `turn budget exhausted (${next.turnsUsed}/${next.maxTurns})`;\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'continue',\n reason,\n message: copy.pauseBudget(next.turnsUsed, next.maxTurns),\n };\n };\n\n // ── Phase A: decompose (once per goal when checklist mode is on) ──\n if (checklistMode && !next.decomposed) {\n const dec = await decomposeGoalChecklist({\n goal: next.goal,\n judgeModelRef,\n signal,\n judgeTimeoutMs,\n uiLocale: locale,\n });\n next.decomposed = true;\n if (!dec.parseFailed && dec.items.length > 0) {\n const prior = next.checklist ?? [];\n next.checklist = mergeDecomposedChecklistItems(prior, dec.items);\n const mergedCount = next.checklist.length;\n next.lastVerdict = 'decompose';\n next.lastReason = copy.decomposedReason(mergedCount);\n resetParse();\n const budgetEarly = pauseIfBudget(next.lastReason);\n if (budgetEarly) return budgetEarly;\n return {\n newState: next,\n shouldContinue: true,\n continuationPrompt: buildContinuationPromptFromState(next, locale),\n verdict: 'decompose',\n reason: next.lastReason ?? '',\n message: copy.checklistReady(mergedCount),\n };\n }\n next.lastReason = dec.errorReason\n ? copy.decomposeFallbackReason(dec.errorReason)\n : copy.noChecklistFallback();\n }\n\n // ── Phase B: checklist judge ──\n const checklist = next.checklist ?? [];\n if (checklist.length > 0) {\n const evalResult = await evaluateGoalChecklistJudge({\n goal: next.goal,\n numberedChecklist: renderChecklistNumbered(checklist),\n lastResponse,\n historyExcerpt: opts?.historyExcerpt ?? '',\n judgeModelRef,\n signal,\n judgeTimeoutMs,\n uiLocale: locale,\n });\n\n if (evalResult.parseFailed) {\n bumpParse();\n } else {\n resetParse();\n next.checklist = applyJudgeChecklistUpdates(checklist, {\n updates: evalResult.parsed.updates,\n newItems: evalResult.parsed.newItems,\n });\n }\n\n next.lastVerdict = 'continue';\n next.lastReason = evalResult.parsed.reason;\n\n const completedChecklistItemIndexes = evalResult.parsed.updates\n .filter((update) => update.status === 'completed' || update.status === 'impossible')\n .map((update) => update.index);\n const structuredNextAction = evalResult.parsed.nextAction?.trim();\n const continuationPrompt = structuredNextAction || buildContinuationPromptFromState(next, locale);\n\n if (!evalResult.parseFailed && allChecklistTerminal(next.checklist ?? [])) {\n next.status = 'done';\n next.lastVerdict = 'done';\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'done',\n reason: evalResult.parsed.reason,\n message: copy.goalAchieved(evalResult.parsed.reason),\n confidence: evalResult.parsed.confidence,\n missingEvidence: evalResult.parsed.missingEvidence,\n userQuestion: evalResult.parsed.userQuestion,\n completedChecklistItemIndexes,\n };\n }\n\n if (!evalResult.parseFailed && (evalResult.parsed.verdict === 'blocked' || evalResult.parsed.verdict === 'needs_input')) {\n next.status = 'paused';\n next.pausedReason = evalResult.parsed.reason;\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: evalResult.parsed.verdict,\n reason: evalResult.parsed.reason,\n message: evalResult.parsed.verdict === 'needs_input'\n ? `Goal needs input: ${evalResult.parsed.userQuestion || evalResult.parsed.reason}`\n : `Goal blocked: ${evalResult.parsed.reason}`,\n confidence: evalResult.parsed.confidence,\n missingEvidence: evalResult.parsed.missingEvidence,\n userQuestion: evalResult.parsed.userQuestion,\n completedChecklistItemIndexes,\n };\n }\n\n const parseStorm = pauseIfParseStorm(evalResult.parsed.reason);\n if (parseStorm) return parseStorm;\n\n const budget = pauseIfBudget(evalResult.parsed.reason);\n if (budget) return budget;\n\n const { total, completed, impossible } = checklistCounts(next.checklist ?? []);\n const done = completed + impossible;\n const progressSuffix = checklistProgressSuffix(done, total, locale);\n\n return {\n newState: next,\n shouldContinue: true,\n continuationPrompt,\n verdict: 'continue',\n reason: evalResult.parsed.reason,\n message: copy.continuingWithProgress(\n next.turnsUsed,\n next.maxTurns,\n progressSuffix,\n evalResult.parsed.reason,\n ),\n confidence: evalResult.parsed.confidence,\n missingEvidence: evalResult.parsed.missingEvidence,\n userQuestion: evalResult.parsed.userQuestion,\n completedChecklistItemIndexes,\n };\n }\n\n // ── Freeform judge (no checklist) ──\n const j = await judgeGoalHermesStyle(state.goal, lastResponse, judgeModelRef, signal, {\n judgeTimeoutMs,\n uiLocale: locale,\n });\n next.lastVerdict = j.verdict === 'skipped' ? 'skipped' : j.verdict;\n next.lastReason = j.reason;\n\n if (j.parseFailed) bumpParse();\n else resetParse();\n\n if (j.verdict === 'done') {\n next.status = 'done';\n return {\n newState: next,\n shouldContinue: false,\n continuationPrompt: null,\n verdict: 'done',\n reason: j.reason,\n message: copy.goalAchieved(j.reason),\n };\n }\n\n const parseStorm = pauseIfParseStorm(j.reason);\n if (parseStorm) return parseStorm;\n\n const budget = pauseIfBudget(j.reason);\n if (budget) return budget;\n\n return {\n newState: next,\n shouldContinue: true,\n continuationPrompt: buildContinuationPromptFromState(next, locale),\n verdict: 'continue',\n reason: j.reason,\n message: copy.continuing(next.turnsUsed, next.maxTurns, j.reason),\n };\n}\n"],"mappings":"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"}
|
|
@@ -24,5 +24,3 @@ export declare function judgeFreeformBuiltinMessages(locale: GoalUiLocale): {
|
|
|
24
24
|
export declare function checklistProgressSuffix(done: number, total: number, locale: GoalUiLocale): string;
|
|
25
25
|
export type GoalEvaluateUserCopyPack = ReturnType<typeof goalsEvaluateCopy>;
|
|
26
26
|
export declare function goalEvaluateUserCopy(locale: GoalUiLocale): GoalEvaluateUserCopyPack;
|
|
27
|
-
/** Persist `uiLocale` on the standing goal when the gateway console language is known. */
|
|
28
|
-
export declare function mergePersistentGoalUiLocale(customData: Record<string, unknown> | undefined, locale: GoalUiLocale | undefined): Record<string, unknown> | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { checklistCounts } from "./checklist-types.js";
|
|
2
|
+
import { renderChecklistPlain } from "./state.js";
|
|
1
3
|
import { formatI18n } from "../../i18n/format.js";
|
|
2
4
|
import { SERVER_LOCALES, isServerLocale, normalizeServerLocale, serverLocaleOrFallback } from "../../i18n/locale.js";
|
|
3
|
-
import { checklistCounts } from "./checklist-types.js";
|
|
4
|
-
import { PERSISTENT_GOAL_CUSTOM_KEY, mergeCustomDataPatch, readPersistentGoal, renderChecklistPlain, serializePersistentGoal } from "./state.js";
|
|
5
5
|
import { JUDGE_REASON_EN, goalsChecklistProgressSuffix, goalsContinuationChecklistTemplate, goalsContinuationPlainTemplate, goalsEvaluateCopy, goalsJudgeReason, goalsJudgeResponseLanguageNote } from "../../i18n/goals-bundle.js";
|
|
6
6
|
//#region src/agent/goals/goal-locale.ts
|
|
7
7
|
const GOAL_UI_LOCALES = SERVER_LOCALES;
|
|
@@ -57,20 +57,7 @@ function checklistProgressSuffix(done, total, locale) {
|
|
|
57
57
|
function goalEvaluateUserCopy(locale) {
|
|
58
58
|
return goalsEvaluateCopy(goalUiLocaleOrFallback(locale));
|
|
59
59
|
}
|
|
60
|
-
/** Persist `uiLocale` on the standing goal when the gateway console language is known. */
|
|
61
|
-
function mergePersistentGoalUiLocale(customData, locale) {
|
|
62
|
-
if (!locale) return customData;
|
|
63
|
-
const canonical = goalUiLocaleOrFallback(locale);
|
|
64
|
-
const g = readPersistentGoal(customData);
|
|
65
|
-
if (!g || g.status === "cleared") return customData;
|
|
66
|
-
if (g.uiLocale === canonical) return customData;
|
|
67
|
-
const next = {
|
|
68
|
-
...g,
|
|
69
|
-
uiLocale: canonical
|
|
70
|
-
};
|
|
71
|
-
return mergeCustomDataPatch(customData ?? {}, { [PERSISTENT_GOAL_CUSTOM_KEY]: serializePersistentGoal(next) });
|
|
72
|
-
}
|
|
73
60
|
//#endregion
|
|
74
|
-
export { CONTINUATION_PROMPT_TEMPLATE_EN, CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN, DEFAULT_GOAL_UI_LOCALE, GOAL_UI_LOCALES, JUDGE_REASON_EN, buildContinuationPromptFromState, checklistProgressSuffix, goalEvaluateUserCopy, goalUiLocaleOrFallback, isGoalUiLocale, judgeFreeformBuiltinMessages, judgeReasonText, judgeResponseLanguageNote, localizeJudgeReasonText,
|
|
61
|
+
export { CONTINUATION_PROMPT_TEMPLATE_EN, CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN, DEFAULT_GOAL_UI_LOCALE, GOAL_UI_LOCALES, JUDGE_REASON_EN, buildContinuationPromptFromState, checklistProgressSuffix, goalEvaluateUserCopy, goalUiLocaleOrFallback, isGoalUiLocale, judgeFreeformBuiltinMessages, judgeReasonText, judgeResponseLanguageNote, localizeJudgeReasonText, normalizeGoalUiLocale, resolveGoalUiLocale };
|
|
75
62
|
|
|
76
63
|
//# sourceMappingURL=goal-locale.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-locale.js","names":[],"sources":["../../../../src/agent/goals/goal-locale.ts"],"sourcesContent":["import { checklistCounts } from './checklist-types.js';\nimport {\n
|
|
1
|
+
{"version":3,"file":"goal-locale.js","names":[],"sources":["../../../../src/agent/goals/goal-locale.ts"],"sourcesContent":["import { checklistCounts } from './checklist-types.js';\nimport {\n renderChecklistPlain,\n type PersistentGoalState,\n} from './state.js';\n\nimport { formatI18n } from '../../i18n/format.js';\nimport {\n goalsChecklistProgressSuffix,\n goalsContinuationChecklistTemplate,\n goalsContinuationPlainTemplate,\n goalsEvaluateCopy,\n goalsJudgeReason,\n goalsJudgeResponseLanguageNote,\n JUDGE_REASON_EN,\n type JudgeReasonId,\n} from '../../i18n/goals-bundle.js';\nimport {\n DEFAULT_SERVER_LOCALE,\n normalizeServerLocale,\n SERVER_LOCALES,\n type ServerLocale,\n serverLocaleOrFallback,\n isServerLocale,\n} from '../../i18n/locale.js';\n\n// ── Goal-facing aliases (persistent goal uses same locale set as server i18n) ──\n\nexport const GOAL_UI_LOCALES = SERVER_LOCALES;\nexport type GoalUiLocale = ServerLocale;\nexport const DEFAULT_GOAL_UI_LOCALE = DEFAULT_SERVER_LOCALE;\n\nexport const isGoalUiLocale = isServerLocale;\nexport const normalizeGoalUiLocale = normalizeServerLocale;\nexport const goalUiLocaleOrFallback = serverLocaleOrFallback;\n\nexport function resolveGoalUiLocale(state: PersistentGoalState | undefined | null): GoalUiLocale {\n return goalUiLocaleOrFallback(state?.uiLocale);\n}\n\n// ── Hermes-style English continuation (tests / parity; sourced from server i18n JSON) ──\n\nexport const CONTINUATION_PROMPT_TEMPLATE_EN = goalsContinuationPlainTemplate('en');\nexport const CONTINUATION_PROMPT_WITH_CHECKLIST_TEMPLATE_EN = goalsContinuationChecklistTemplate('en');\n\nexport function buildContinuationPromptFromState(state: PersistentGoalState, locale: GoalUiLocale): string {\n const L = goalUiLocaleOrFallback(locale);\n const cl = state.checklist ?? [];\n if (cl.length) {\n const plain = renderChecklistPlain(cl);\n const { total, completed, impossible } = checklistCounts(cl);\n const done = completed + impossible;\n const tpl = goalsContinuationChecklistTemplate(L);\n return formatI18n(tpl, {\n goal: state.goal,\n done,\n total,\n checklist: plain,\n });\n }\n return formatI18n(goalsContinuationPlainTemplate(L), { goal: state.goal });\n}\n\nexport function judgeResponseLanguageNote(locale: GoalUiLocale): string {\n return goalsJudgeResponseLanguageNote(goalUiLocaleOrFallback(locale));\n}\n\nexport { JUDGE_REASON_EN, type JudgeReasonId };\n\nconst JUDGE_REASON_ID_BY_EN = new Map<string, JudgeReasonId>(\n (Object.entries(JUDGE_REASON_EN) as [JudgeReasonId, string][]).map(([id, s]) => [s, id]),\n);\n\nexport function judgeReasonText(id: JudgeReasonId, locale: GoalUiLocale): string {\n return goalsJudgeReason(id, goalUiLocaleOrFallback(locale));\n}\n\nexport function localizeJudgeReasonText(reason: string, locale: GoalUiLocale): string {\n const id = JUDGE_REASON_ID_BY_EN.get(reason);\n if (!id) return reason;\n return judgeReasonText(id, locale);\n}\n\nexport function judgeFreeformBuiltinMessages(locale: GoalUiLocale) {\n const L = goalUiLocaleOrFallback(locale);\n return {\n emptyGoal: judgeReasonText('empty_goal', L),\n emptyResponse: judgeReasonText('empty_response', L),\n noModel: judgeReasonText('judge_model_not_configured', L),\n callFailed: judgeReasonText('judge_call_failed', L),\n };\n}\n\nexport function checklistProgressSuffix(done: number, total: number, locale: GoalUiLocale): string {\n return goalsChecklistProgressSuffix(done, total, goalUiLocaleOrFallback(locale));\n}\n\nexport type GoalEvaluateUserCopyPack = ReturnType<typeof goalsEvaluateCopy>;\n\nexport function goalEvaluateUserCopy(locale: GoalUiLocale): GoalEvaluateUserCopyPack {\n return goalsEvaluateCopy(goalUiLocaleOrFallback(locale));\n}\n"],"mappings":";;;;;;AA4BA,MAAa,kBAAkB;AAE/B,MAAa,yBAAA;AAEb,MAAa,iBAAiB;AAC9B,MAAa,wBAAwB;AACrC,MAAa,yBAAyB;AAEtC,SAAgB,oBAAoB,OAA6D;AAC/F,QAAO,uBAAuB,OAAO,SAAS;;AAKhD,MAAa,kCAAkC,+BAA+B,KAAK;AACnF,MAAa,iDAAiD,mCAAmC,KAAK;AAEtG,SAAgB,iCAAiC,OAA4B,QAA8B;CACzG,MAAM,IAAI,uBAAuB,OAAO;CACxC,MAAM,KAAK,MAAM,aAAa,EAAE;AAChC,KAAI,GAAG,QAAQ;EACb,MAAM,QAAQ,qBAAqB,GAAG;EACtC,MAAM,EAAE,OAAO,WAAW,eAAe,gBAAgB,GAAG;EAC5D,MAAM,OAAO,YAAY;AAEzB,SAAO,WADK,mCAAmC,EAC1B,EAAE;GACrB,MAAM,MAAM;GACZ;GACA;GACA,WAAW;GACZ,CAAC;;AAEJ,QAAO,WAAW,+BAA+B,EAAE,EAAE,EAAE,MAAM,MAAM,MAAM,CAAC;;AAG5E,SAAgB,0BAA0B,QAA8B;AACtE,QAAO,+BAA+B,uBAAuB,OAAO,CAAC;;AAKvE,MAAM,wBAAwB,IAAI,IAC/B,OAAO,QAAQ,gBAAgB,CAA+B,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,GAAG,CAAC,CACzF;AAED,SAAgB,gBAAgB,IAAmB,QAA8B;AAC/E,QAAO,iBAAiB,IAAI,uBAAuB,OAAO,CAAC;;AAG7D,SAAgB,wBAAwB,QAAgB,QAA8B;CACpF,MAAM,KAAK,sBAAsB,IAAI,OAAO;AAC5C,KAAI,CAAC,GAAI,QAAO;AAChB,QAAO,gBAAgB,IAAI,OAAO;;AAGpC,SAAgB,6BAA6B,QAAsB;CACjE,MAAM,IAAI,uBAAuB,OAAO;AACxC,QAAO;EACL,WAAW,gBAAgB,cAAc,EAAE;EAC3C,eAAe,gBAAgB,kBAAkB,EAAE;EACnD,SAAS,gBAAgB,8BAA8B,EAAE;EACzD,YAAY,gBAAgB,qBAAqB,EAAE;EACpD;;AAGH,SAAgB,wBAAwB,MAAc,OAAe,QAA8B;AACjG,QAAO,6BAA6B,MAAM,OAAO,uBAAuB,OAAO,CAAC;;AAKlF,SAAgB,qBAAqB,QAAgD;AACnF,QAAO,kBAAkB,uBAAuB,OAAO,CAAC"}
|
|
@@ -20,6 +20,7 @@ import type { MessageBus } from '../../infra/bus/index.js';
|
|
|
20
20
|
import type { ModelManager } from '../models/index.js';
|
|
21
21
|
import type { SessionStore } from '../../session/store.js';
|
|
22
22
|
import type { SessionStateBag } from '../session/index.js';
|
|
23
|
+
import type { GoalWithDetails } from '../../goals/types.js';
|
|
23
24
|
import type { PersistentGoalApis } from './persistent-goal-apis.js';
|
|
24
25
|
export interface PersistentGoalRouting {
|
|
25
26
|
sessionKey: string;
|
|
@@ -50,6 +51,14 @@ export interface PersistentGoalServiceOptions {
|
|
|
50
51
|
onSessionMetadataUpdated?: (sessionKey: string) => void;
|
|
51
52
|
/** Push an assistant token + transcript refresh into a live webchat stream. */
|
|
52
53
|
notifyWebchatTranscriptAppend: (sessionKey: string, assistantText: string) => void;
|
|
54
|
+
/** Gateway: durable goal status changed after post-turn judge. */
|
|
55
|
+
onGoalStatusUpdated?: (payload: {
|
|
56
|
+
goalId: string;
|
|
57
|
+
sessionKey: string;
|
|
58
|
+
previousStatus: string;
|
|
59
|
+
status: string;
|
|
60
|
+
goal: GoalWithDetails;
|
|
61
|
+
}) => void;
|
|
53
62
|
}
|
|
54
63
|
export declare class PersistentGoalService {
|
|
55
64
|
private readonly opts;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
|
|
2
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
|
|
4
4
|
import { handlePersistentGoalPostTurn } from "./post-turn.js";
|
|
5
5
|
//#region src/agent/goals/persistent-goal-service.ts
|
|
6
6
|
init_session_key();
|
|
@@ -121,7 +121,8 @@ var PersistentGoalService = class {
|
|
|
121
121
|
skipPersistentGoalPostTurn: payload.skipPersistentGoalPostTurn ?? false,
|
|
122
122
|
config: this.opts.getConfig(),
|
|
123
123
|
runtimeSessionModelRef,
|
|
124
|
-
publishVerdictToChannel: publishVerdict
|
|
124
|
+
publishVerdictToChannel: publishVerdict,
|
|
125
|
+
onGoalStatusUpdated: this.opts.onGoalStatusUpdated
|
|
125
126
|
});
|
|
126
127
|
}
|
|
127
128
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistent-goal-service.js","names":["parseRoutingSessionKey"],"sources":["../../../../src/agent/goals/persistent-goal-service.ts"],"sourcesContent":["/**\n * PersistentGoalService — owns the \"/goal\" runtime: continuation scheduling,\n * the `PersistentGoalApis` bag that command handlers receive, and the post-turn\n * verdict hook called from `OutboundCoordinator`.\n *\n * Previously this logic was scattered across `AgentService`:\n * - `setPersistentGoalWebchatContinuationScheduler` + a private callback field\n * - `schedulePersistentGoalContinuation` (bus vs webchat fork)\n * - `getPersistentGoalApisForCommand` (~40-line API factory)\n * - `recordPersistentGoalStreamOutcome` / `takePersistentGoalStreamOutcome`\n * - the `/goal` half of `emitSessionTurnComplete` (delegated to\n * `handlePersistentGoalPostTurn`)\n *\n * Concentrating it here gives the rest of `AgentService` a cleaner surface\n * (one collaborator instead of five methods) and makes the goal runtime\n * unit-testable in isolation.\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { SessionStateBag } from '../session/index.js';\nimport { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { PersistentGoalApis } from './persistent-goal-apis.js';\nimport { handlePersistentGoalPostTurn } from './post-turn.js';\n\nconst log = createLogger('PersistentGoalService');\n\nexport interface PersistentGoalRouting {\n sessionKey: string;\n channel: string;\n chatId: string;\n inboundMetadata?: Record<string, unknown>;\n}\n\nexport interface SessionTurnCompletionForGoal {\n sessionKey: string;\n channel: string;\n chatId: string;\n assistantPlainText: string;\n aborted: boolean;\n streamError?: string;\n skipPersistentGoalPostTurn?: boolean;\n outboundMetadata?: Record<string, unknown>;\n}\n\nexport interface PersistentGoalServiceOptions {\n bus: MessageBus;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n sessionState: SessionStateBag;\n /** Effective config snapshot accessor. */\n getConfig: () => Config | undefined;\n /** Resolve the workspace directory for `appendAssistantReceipt` writes. */\n getResolvedWorkspaceForSession: (sessionKey: string) => string;\n /** Notify the gateway UI after a metadata change (replaces the in-bag emit). */\n onSessionMetadataUpdated?: (sessionKey: string) => void;\n /** Push an assistant token + transcript refresh into a live webchat stream. */\n notifyWebchatTranscriptAppend: (sessionKey: string, assistantText: string) => void;\n}\n\nexport class PersistentGoalService {\n private readonly opts: PersistentGoalServiceOptions;\n /** Gateway only: webchat continuations bypass the bus and reuse `runGatewayAgent`. */\n private webchatContinuationScheduler?: (sessionKey: string, message: string) => void;\n\n constructor(opts: PersistentGoalServiceOptions) {\n this.opts = opts;\n }\n\n /** Register the gateway-side webchat continuation hook (set from `web-agent` wiring). */\n setWebchatContinuationScheduler(\n fn: ((sessionKey: string, message: string) => void) | undefined,\n ): void {\n this.webchatContinuationScheduler = fn;\n }\n\n /**\n * Continue a session after `/goal` decides the previous turn needs follow-up.\n * Webchat sessions go through the scheduler; bus-driven channels re-publish the\n * follow-up message as an inbound bus event so the existing inbound loop picks it up.\n */\n scheduleContinuation(\n sessionKey: string,\n message: string,\n routing: { channel: string; chatId: string; inboundMetadata?: Record<string, unknown> },\n ): void {\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed?.source === 'webchat' && this.webchatContinuationScheduler) {\n this.webchatContinuationScheduler(sessionKey, message);\n return;\n }\n queueMicrotask(() => {\n void this.opts.bus\n .publishInbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n sender_id: 'persistent-goal',\n content: message,\n metadata: { sessionKey, ...routing.inboundMetadata },\n })\n .catch((err) => {\n log.warn({ err, sessionKey }, 'Persistent goal: publishInbound failed');\n });\n });\n }\n\n /** Build the per-command `PersistentGoalApis` bag (transcript writers + scheduler closures). */\n buildApisForRouting(routing: PersistentGoalRouting): PersistentGoalApis {\n return {\n getSessionMetadata: (k) => this.opts.sessionStore.getMetadata(k),\n updateSessionMetadata: async (k, u) => {\n await this.opts.sessionStore.updateMetadata(k, u);\n this.opts.onSessionMetadataUpdated?.(k);\n },\n loadMessages: (k) => this.opts.sessionStore.loadMessages(k),\n appendAssistantReceipt: async (k, text) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n await this.opts.sessionStore.appendTranscriptMessage(k, {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n } as AgentMessage);\n this.opts.notifyWebchatTranscriptAppend(k, trimmed);\n },\n scheduleContinuation: (sk, msg) => {\n this.scheduleContinuation(sk, msg, {\n channel: routing.channel,\n chatId: routing.chatId,\n inboundMetadata: routing.inboundMetadata,\n });\n },\n inboundConcurrentDepth: (sk) => this.opts.sessionState.getInboundTurnDepth(sk),\n };\n }\n\n recordStreamOutcome(sessionKey: string, outcome: { skipPersistentGoalPostTurn: boolean }): void {\n this.opts.sessionState.recordPersistentGoalStreamOutcome(sessionKey, outcome);\n }\n\n takeStreamOutcome(sessionKey: string): { skipPersistentGoalPostTurn: boolean } | undefined {\n return this.opts.sessionState.takePersistentGoalStreamOutcome(sessionKey);\n }\n\n /**\n * Run the `/goal` post-turn verdict for a completed user turn (called from\n * `OutboundCoordinator.emitSessionTurnComplete`).\n */\n async runPostTurn(payload: SessionTurnCompletionForGoal): Promise<void> {\n const apis = this.buildApisForRouting({\n sessionKey: payload.sessionKey,\n channel: payload.channel,\n chatId: payload.chatId,\n inboundMetadata: payload.outboundMetadata,\n });\n\n const src = parseRoutingSessionKey(payload.sessionKey)?.source;\n const isWebchat = src === 'webchat';\n const publishVerdict =\n !isWebchat && payload.channel !== 'cli'\n ? async (text: string) => {\n await this.opts.bus.publishOutbound({\n channel: payload.channel,\n chat_id: payload.chatId,\n content: text,\n type: 'message',\n metadata: {\n accountId: payload.outboundMetadata?.accountId,\n threadId: payload.outboundMetadata?.threadId,\n },\n });\n }\n : undefined;\n\n let runtimeSessionModelRef: string | undefined;\n try {\n runtimeSessionModelRef = this.opts.modelManager.getModelForSession(payload.sessionKey);\n } catch {\n runtimeSessionModelRef = undefined;\n }\n\n await handlePersistentGoalPostTurn({\n apis,\n sessionKey: payload.sessionKey,\n assistantPlainText: payload.assistantPlainText,\n aborted: payload.aborted,\n ...(payload.streamError !== undefined ? { streamError: payload.streamError } : {}),\n skipPersistentGoalPostTurn: payload.skipPersistentGoalPostTurn ?? false,\n config: this.opts.getConfig(),\n runtimeSessionModelRef,\n publishVerdictToChannel: publishVerdict,\n });\n }\n}\n"],"mappings":";;;;;kBAyByF;aACpC;AAIrD,MAAM,MAAM,aAAa,wBAAwB;AAmCjD,IAAa,wBAAb,MAAmC;CACjC;;CAEA;CAEA,YAAY,MAAoC;AAC9C,OAAK,OAAO;;;CAId,gCACE,IACM;AACN,OAAK,+BAA+B;;;;;;;CAQtC,qBACE,YACA,SACA,SACM;AAEN,MADeA,gBAAuB,WAC5B,EAAE,WAAW,aAAa,KAAK,8BAA8B;AACrE,QAAK,6BAA6B,YAAY,QAAQ;AACtD;;AAEF,uBAAqB;AACd,QAAK,KAAK,IACZ,eAAe;IACd,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,WAAW;IACX,SAAS;IACT,UAAU;KAAE;KAAY,GAAG,QAAQ;KAAiB;IACrD,CAAC,CACD,OAAO,QAAQ;AACd,QAAI,KAAK;KAAE;KAAK;KAAY,EAAE,yCAAyC;KACvE;IACJ;;;CAIJ,oBAAoB,SAAoD;AACtE,SAAO;GACL,qBAAqB,MAAM,KAAK,KAAK,aAAa,YAAY,EAAE;GAChE,uBAAuB,OAAO,GAAG,MAAM;AACrC,UAAM,KAAK,KAAK,aAAa,eAAe,GAAG,EAAE;AACjD,SAAK,KAAK,2BAA2B,EAAE;;GAEzC,eAAe,MAAM,KAAK,KAAK,aAAa,aAAa,EAAE;GAC3D,wBAAwB,OAAO,GAAG,SAAS;IACzC,MAAM,UAAU,KAAK,MAAM;AAC3B,QAAI,CAAC,QAAS;AACd,UAAM,KAAK,KAAK,aAAa,wBAAwB,GAAG;KACtD,MAAM;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAS,CAAC;KAC1C,WAAW,KAAK,KAAK;KACtB,CAAiB;AAClB,SAAK,KAAK,8BAA8B,GAAG,QAAQ;;GAErD,uBAAuB,IAAI,QAAQ;AACjC,SAAK,qBAAqB,IAAI,KAAK;KACjC,SAAS,QAAQ;KACjB,QAAQ,QAAQ;KAChB,iBAAiB,QAAQ;KAC1B,CAAC;;GAEJ,yBAAyB,OAAO,KAAK,KAAK,aAAa,oBAAoB,GAAG;GAC/E;;CAGH,oBAAoB,YAAoB,SAAwD;AAC9F,OAAK,KAAK,aAAa,kCAAkC,YAAY,QAAQ;;CAG/E,kBAAkB,YAAyE;AACzF,SAAO,KAAK,KAAK,aAAa,gCAAgC,WAAW;;;;;;CAO3E,MAAM,YAAY,SAAsD;EACtE,MAAM,OAAO,KAAK,oBAAoB;GACpC,YAAY,QAAQ;GACpB,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,iBAAiB,QAAQ;GAC1B,CAAC;EAIF,MAAM,iBACJ,EAHUA,gBAAuB,QAAQ,WAAW,EAAE,WAC9B,cAEV,QAAQ,YAAY,QAC9B,OAAO,SAAiB;AACtB,SAAM,KAAK,KAAK,IAAI,gBAAgB;IAClC,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,SAAS;IACT,MAAM;IACN,UAAU;KACR,WAAW,QAAQ,kBAAkB;KACrC,UAAU,QAAQ,kBAAkB;KACrC;IACF,CAAC;MAEJ,KAAA;EAEN,IAAI;AACJ,MAAI;AACF,4BAAyB,KAAK,KAAK,aAAa,mBAAmB,QAAQ,WAAW;UAChF;AACN,4BAAyB,KAAA;;AAG3B,QAAM,6BAA6B;GACjC;GACA,YAAY,QAAQ;GACpB,oBAAoB,QAAQ;GAC5B,SAAS,QAAQ;GACjB,GAAI,QAAQ,gBAAgB,KAAA,IAAY,EAAE,aAAa,QAAQ,aAAa,GAAG,EAAE;GACjF,4BAA4B,QAAQ,8BAA8B;GAClE,QAAQ,KAAK,KAAK,WAAW;GAC7B;GACA,yBAAyB;GAC1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"persistent-goal-service.js","names":["parseRoutingSessionKey"],"sources":["../../../../src/agent/goals/persistent-goal-service.ts"],"sourcesContent":["/**\n * PersistentGoalService — owns the \"/goal\" runtime: continuation scheduling,\n * the `PersistentGoalApis` bag that command handlers receive, and the post-turn\n * verdict hook called from `OutboundCoordinator`.\n *\n * Previously this logic was scattered across `AgentService`:\n * - `setPersistentGoalWebchatContinuationScheduler` + a private callback field\n * - `schedulePersistentGoalContinuation` (bus vs webchat fork)\n * - `getPersistentGoalApisForCommand` (~40-line API factory)\n * - `recordPersistentGoalStreamOutcome` / `takePersistentGoalStreamOutcome`\n * - the `/goal` half of `emitSessionTurnComplete` (delegated to\n * `handlePersistentGoalPostTurn`)\n *\n * Concentrating it here gives the rest of `AgentService` a cleaner surface\n * (one collaborator instead of five methods) and makes the goal runtime\n * unit-testable in isolation.\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport type { MessageBus } from '../../infra/bus/index.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/store.js';\nimport type { SessionStateBag } from '../session/index.js';\nimport type { GoalWithDetails } from '../../goals/types.js';\nimport { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type { PersistentGoalApis } from './persistent-goal-apis.js';\nimport { handlePersistentGoalPostTurn } from './post-turn.js';\n\nconst log = createLogger('PersistentGoalService');\n\nexport interface PersistentGoalRouting {\n sessionKey: string;\n channel: string;\n chatId: string;\n inboundMetadata?: Record<string, unknown>;\n}\n\nexport interface SessionTurnCompletionForGoal {\n sessionKey: string;\n channel: string;\n chatId: string;\n assistantPlainText: string;\n aborted: boolean;\n streamError?: string;\n skipPersistentGoalPostTurn?: boolean;\n outboundMetadata?: Record<string, unknown>;\n}\n\nexport interface PersistentGoalServiceOptions {\n bus: MessageBus;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n sessionState: SessionStateBag;\n /** Effective config snapshot accessor. */\n getConfig: () => Config | undefined;\n /** Resolve the workspace directory for `appendAssistantReceipt` writes. */\n getResolvedWorkspaceForSession: (sessionKey: string) => string;\n /** Notify the gateway UI after a metadata change (replaces the in-bag emit). */\n onSessionMetadataUpdated?: (sessionKey: string) => void;\n /** Push an assistant token + transcript refresh into a live webchat stream. */\n notifyWebchatTranscriptAppend: (sessionKey: string, assistantText: string) => void;\n /** Gateway: durable goal status changed after post-turn judge. */\n onGoalStatusUpdated?: (payload: {\n goalId: string;\n sessionKey: string;\n previousStatus: string;\n status: string;\n goal: GoalWithDetails;\n }) => void;\n}\n\nexport class PersistentGoalService {\n private readonly opts: PersistentGoalServiceOptions;\n /** Gateway only: webchat continuations bypass the bus and reuse `runGatewayAgent`. */\n private webchatContinuationScheduler?: (sessionKey: string, message: string) => void;\n\n constructor(opts: PersistentGoalServiceOptions) {\n this.opts = opts;\n }\n\n /** Register the gateway-side webchat continuation hook (set from `web-agent` wiring). */\n setWebchatContinuationScheduler(\n fn: ((sessionKey: string, message: string) => void) | undefined,\n ): void {\n this.webchatContinuationScheduler = fn;\n }\n\n /**\n * Continue a session after `/goal` decides the previous turn needs follow-up.\n * Webchat sessions go through the scheduler; bus-driven channels re-publish the\n * follow-up message as an inbound bus event so the existing inbound loop picks it up.\n */\n scheduleContinuation(\n sessionKey: string,\n message: string,\n routing: { channel: string; chatId: string; inboundMetadata?: Record<string, unknown> },\n ): void {\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed?.source === 'webchat' && this.webchatContinuationScheduler) {\n this.webchatContinuationScheduler(sessionKey, message);\n return;\n }\n queueMicrotask(() => {\n void this.opts.bus\n .publishInbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n sender_id: 'persistent-goal',\n content: message,\n metadata: { sessionKey, ...routing.inboundMetadata },\n })\n .catch((err) => {\n log.warn({ err, sessionKey }, 'Persistent goal: publishInbound failed');\n });\n });\n }\n\n /** Build the per-command `PersistentGoalApis` bag (transcript writers + scheduler closures). */\n buildApisForRouting(routing: PersistentGoalRouting): PersistentGoalApis {\n return {\n getSessionMetadata: (k) => this.opts.sessionStore.getMetadata(k),\n updateSessionMetadata: async (k, u) => {\n await this.opts.sessionStore.updateMetadata(k, u);\n this.opts.onSessionMetadataUpdated?.(k);\n },\n loadMessages: (k) => this.opts.sessionStore.loadMessages(k),\n appendAssistantReceipt: async (k, text) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n await this.opts.sessionStore.appendTranscriptMessage(k, {\n role: 'assistant',\n content: [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n } as AgentMessage);\n this.opts.notifyWebchatTranscriptAppend(k, trimmed);\n },\n scheduleContinuation: (sk, msg) => {\n this.scheduleContinuation(sk, msg, {\n channel: routing.channel,\n chatId: routing.chatId,\n inboundMetadata: routing.inboundMetadata,\n });\n },\n inboundConcurrentDepth: (sk) => this.opts.sessionState.getInboundTurnDepth(sk),\n };\n }\n\n recordStreamOutcome(sessionKey: string, outcome: { skipPersistentGoalPostTurn: boolean }): void {\n this.opts.sessionState.recordPersistentGoalStreamOutcome(sessionKey, outcome);\n }\n\n takeStreamOutcome(sessionKey: string): { skipPersistentGoalPostTurn: boolean } | undefined {\n return this.opts.sessionState.takePersistentGoalStreamOutcome(sessionKey);\n }\n\n /**\n * Run the `/goal` post-turn verdict for a completed user turn (called from\n * `OutboundCoordinator.emitSessionTurnComplete`).\n */\n async runPostTurn(payload: SessionTurnCompletionForGoal): Promise<void> {\n const apis = this.buildApisForRouting({\n sessionKey: payload.sessionKey,\n channel: payload.channel,\n chatId: payload.chatId,\n inboundMetadata: payload.outboundMetadata,\n });\n\n const src = parseRoutingSessionKey(payload.sessionKey)?.source;\n const isWebchat = src === 'webchat';\n const publishVerdict =\n !isWebchat && payload.channel !== 'cli'\n ? async (text: string) => {\n await this.opts.bus.publishOutbound({\n channel: payload.channel,\n chat_id: payload.chatId,\n content: text,\n type: 'message',\n metadata: {\n accountId: payload.outboundMetadata?.accountId,\n threadId: payload.outboundMetadata?.threadId,\n },\n });\n }\n : undefined;\n\n let runtimeSessionModelRef: string | undefined;\n try {\n runtimeSessionModelRef = this.opts.modelManager.getModelForSession(payload.sessionKey);\n } catch {\n runtimeSessionModelRef = undefined;\n }\n\n await handlePersistentGoalPostTurn({\n apis,\n sessionKey: payload.sessionKey,\n assistantPlainText: payload.assistantPlainText,\n aborted: payload.aborted,\n ...(payload.streamError !== undefined ? { streamError: payload.streamError } : {}),\n skipPersistentGoalPostTurn: payload.skipPersistentGoalPostTurn ?? false,\n config: this.opts.getConfig(),\n runtimeSessionModelRef,\n publishVerdictToChannel: publishVerdict,\n onGoalStatusUpdated: this.opts.onGoalStatusUpdated,\n });\n }\n}\n"],"mappings":";;;;;kBA0ByF;aACpC;AAIrD,MAAM,MAAM,aAAa,wBAAwB;AA2CjD,IAAa,wBAAb,MAAmC;CACjC;;CAEA;CAEA,YAAY,MAAoC;AAC9C,OAAK,OAAO;;;CAId,gCACE,IACM;AACN,OAAK,+BAA+B;;;;;;;CAQtC,qBACE,YACA,SACA,SACM;AAEN,MADeA,gBAAuB,WAC5B,EAAE,WAAW,aAAa,KAAK,8BAA8B;AACrE,QAAK,6BAA6B,YAAY,QAAQ;AACtD;;AAEF,uBAAqB;AACd,QAAK,KAAK,IACZ,eAAe;IACd,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,WAAW;IACX,SAAS;IACT,UAAU;KAAE;KAAY,GAAG,QAAQ;KAAiB;IACrD,CAAC,CACD,OAAO,QAAQ;AACd,QAAI,KAAK;KAAE;KAAK;KAAY,EAAE,yCAAyC;KACvE;IACJ;;;CAIJ,oBAAoB,SAAoD;AACtE,SAAO;GACL,qBAAqB,MAAM,KAAK,KAAK,aAAa,YAAY,EAAE;GAChE,uBAAuB,OAAO,GAAG,MAAM;AACrC,UAAM,KAAK,KAAK,aAAa,eAAe,GAAG,EAAE;AACjD,SAAK,KAAK,2BAA2B,EAAE;;GAEzC,eAAe,MAAM,KAAK,KAAK,aAAa,aAAa,EAAE;GAC3D,wBAAwB,OAAO,GAAG,SAAS;IACzC,MAAM,UAAU,KAAK,MAAM;AAC3B,QAAI,CAAC,QAAS;AACd,UAAM,KAAK,KAAK,aAAa,wBAAwB,GAAG;KACtD,MAAM;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM;MAAS,CAAC;KAC1C,WAAW,KAAK,KAAK;KACtB,CAAiB;AAClB,SAAK,KAAK,8BAA8B,GAAG,QAAQ;;GAErD,uBAAuB,IAAI,QAAQ;AACjC,SAAK,qBAAqB,IAAI,KAAK;KACjC,SAAS,QAAQ;KACjB,QAAQ,QAAQ;KAChB,iBAAiB,QAAQ;KAC1B,CAAC;;GAEJ,yBAAyB,OAAO,KAAK,KAAK,aAAa,oBAAoB,GAAG;GAC/E;;CAGH,oBAAoB,YAAoB,SAAwD;AAC9F,OAAK,KAAK,aAAa,kCAAkC,YAAY,QAAQ;;CAG/E,kBAAkB,YAAyE;AACzF,SAAO,KAAK,KAAK,aAAa,gCAAgC,WAAW;;;;;;CAO3E,MAAM,YAAY,SAAsD;EACtE,MAAM,OAAO,KAAK,oBAAoB;GACpC,YAAY,QAAQ;GACpB,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,iBAAiB,QAAQ;GAC1B,CAAC;EAIF,MAAM,iBACJ,EAHUA,gBAAuB,QAAQ,WAAW,EAAE,WAC9B,cAEV,QAAQ,YAAY,QAC9B,OAAO,SAAiB;AACtB,SAAM,KAAK,KAAK,IAAI,gBAAgB;IAClC,SAAS,QAAQ;IACjB,SAAS,QAAQ;IACjB,SAAS;IACT,MAAM;IACN,UAAU;KACR,WAAW,QAAQ,kBAAkB;KACrC,UAAU,QAAQ,kBAAkB;KACrC;IACF,CAAC;MAEJ,KAAA;EAEN,IAAI;AACJ,MAAI;AACF,4BAAyB,KAAK,KAAK,aAAa,mBAAmB,QAAQ,WAAW;UAChF;AACN,4BAAyB,KAAA;;AAG3B,QAAM,6BAA6B;GACjC;GACA,YAAY,QAAQ;GACpB,oBAAoB,QAAQ;GAC5B,SAAS,QAAQ;GACjB,GAAI,QAAQ,gBAAgB,KAAA,IAAY,EAAE,aAAa,QAAQ,aAAa,GAAG,EAAE;GACjF,4BAA4B,QAAQ,8BAA8B;GAClE,QAAQ,KAAK,KAAK,WAAW;GAC7B;GACA,yBAAyB;GACzB,qBAAqB,KAAK,KAAK;GAChC,CAAC"}
|
|
@@ -13,4 +13,11 @@ export declare function handlePersistentGoalPostTurn(opts: {
|
|
|
13
13
|
signal?: AbortSignal;
|
|
14
14
|
/** Hermes-style: verdict line also sent as a normal outbound message (non-webchat). */
|
|
15
15
|
publishVerdictToChannel?: (text: string) => Promise<void>;
|
|
16
|
+
onGoalStatusUpdated?: (payload: {
|
|
17
|
+
goalId: string;
|
|
18
|
+
sessionKey: string;
|
|
19
|
+
previousStatus: string;
|
|
20
|
+
status: string;
|
|
21
|
+
goal: import('../../goals/types.js').GoalWithDetails;
|
|
22
|
+
}) => void;
|
|
16
23
|
}): Promise<void>;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
2
|
-
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
3
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
4
2
|
import { init_logger } from "../../utils/logger.js";
|
|
5
|
-
import {
|
|
3
|
+
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
6
4
|
import { resolveGoalUiLocale } from "./goal-locale.js";
|
|
5
|
+
import { resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
6
|
+
import { GoalService } from "../../goals/goal-service.js";
|
|
7
7
|
import { evaluateAfterTurnHermesLike } from "./evaluate-turn.js";
|
|
8
|
-
import
|
|
8
|
+
import "../../goals/index.js";
|
|
9
9
|
//#region src/agent/goals/post-turn.ts
|
|
10
10
|
init_schema();
|
|
11
11
|
init_logger();
|
|
12
12
|
const log = createLogger("PersistentGoal");
|
|
13
|
+
const goalService = new GoalService();
|
|
13
14
|
function buildHistoryExcerpt(messages, maxChars) {
|
|
14
15
|
if (maxChars <= 0) return "";
|
|
15
16
|
try {
|
|
@@ -35,13 +36,32 @@ async function appendAssistantLine(apis, sessionKey, text) {
|
|
|
35
36
|
await apis.appendAssistantReceipt(sessionKey, text);
|
|
36
37
|
}
|
|
37
38
|
async function handlePersistentGoalPostTurn(opts) {
|
|
38
|
-
const { apis, sessionKey, assistantPlainText, aborted, streamError, skipPersistentGoalPostTurn, config, runtimeSessionModelRef, signal, publishVerdictToChannel } = opts;
|
|
39
|
+
const { apis, sessionKey, assistantPlainText, aborted, streamError, skipPersistentGoalPostTurn, config, runtimeSessionModelRef, signal, publishVerdictToChannel, onGoalStatusUpdated } = opts;
|
|
39
40
|
if (skipPersistentGoalPostTurn) return;
|
|
40
41
|
if (aborted || streamError) return;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if (!await apis.getSessionMetadata(sessionKey)) return;
|
|
43
|
+
const goal = goalService.getActiveForSession(sessionKey);
|
|
44
|
+
if (!goal || goal.status !== "active") return;
|
|
45
|
+
const state = {
|
|
46
|
+
goal: goal.title,
|
|
47
|
+
status: "active",
|
|
48
|
+
turnsUsed: goal.turnsUsed,
|
|
49
|
+
maxTurns: goal.maxTurns,
|
|
50
|
+
createdAt: goal.createdAt,
|
|
51
|
+
lastTurnAt: goal.updatedAt,
|
|
52
|
+
lastReason: goal.blockedReason,
|
|
53
|
+
judgeModelRef: goal.judgeModelRef,
|
|
54
|
+
decomposed: goal.checklist.length > 0 ? true : void 0,
|
|
55
|
+
uiLocale: goal.uiLocale,
|
|
56
|
+
checklist: goal.checklist.map((it) => ({
|
|
57
|
+
text: it.text,
|
|
58
|
+
status: it.status,
|
|
59
|
+
addedBy: it.addedBy,
|
|
60
|
+
addedAt: it.addedAt,
|
|
61
|
+
completedAt: it.completedAt,
|
|
62
|
+
evidence: it.evidenceSummary
|
|
63
|
+
}))
|
|
64
|
+
};
|
|
45
65
|
const judgeRef = resolveJudgeModelRef(config, sessionKey, state.judgeModelRef, runtimeSessionModelRef);
|
|
46
66
|
if (!judgeRef) {
|
|
47
67
|
log.warn({ sessionKey }, "Persistent goal: no judge model ref; skipping post-turn");
|
|
@@ -63,23 +83,48 @@ async function handlePersistentGoalPostTurn(opts) {
|
|
|
63
83
|
historyExcerpt,
|
|
64
84
|
uiLocale: resolveGoalUiLocale(state)
|
|
65
85
|
});
|
|
66
|
-
const baseCustom = { ...meta.customData };
|
|
67
86
|
if (decision.newState) {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
const ns = decision.newState;
|
|
88
|
+
const completedChecklistItemIds = decision.completedChecklistItemIndexes?.map((index) => goal.checklist[index]?.id).filter((id) => typeof id === "string" && id.length > 0);
|
|
89
|
+
try {
|
|
90
|
+
const updatedGoal = goalService.syncPostTurnState({
|
|
91
|
+
goalId: goal.id,
|
|
92
|
+
sessionKey,
|
|
93
|
+
source: "chat",
|
|
94
|
+
status: ns.status === "done" ? "done" : decision.verdict === "blocked" ? "blocked" : decision.verdict === "needs_input" ? "needs_input" : ns.status === "paused" ? "paused" : "active",
|
|
95
|
+
turnsUsed: ns.turnsUsed,
|
|
96
|
+
maxTurns: ns.maxTurns,
|
|
97
|
+
reason: ns.pausedReason ?? decision.reason,
|
|
98
|
+
nextAction: decision.continuationPrompt ?? void 0,
|
|
99
|
+
assistantPreview: assistantPlainText,
|
|
100
|
+
verdict: decision.verdict === "done" ? "done" : decision.verdict === "decompose" ? "decompose" : decision.verdict === "blocked" ? "blocked" : decision.verdict === "needs_input" ? "needs_input" : "continue",
|
|
101
|
+
confidence: decision.confidence,
|
|
102
|
+
missingEvidence: decision.missingEvidence,
|
|
103
|
+
userQuestion: decision.userQuestion,
|
|
104
|
+
completedChecklistItemIds,
|
|
105
|
+
checklist: ns.checklist?.map((it) => ({
|
|
106
|
+
text: it.text,
|
|
107
|
+
status: it.status,
|
|
108
|
+
addedBy: it.addedBy,
|
|
109
|
+
addedAt: it.addedAt,
|
|
110
|
+
completedAt: it.completedAt,
|
|
111
|
+
evidenceSummary: it.evidence
|
|
112
|
+
}))
|
|
113
|
+
});
|
|
114
|
+
if (updatedGoal && updatedGoal.status !== goal.status) onGoalStatusUpdated?.({
|
|
115
|
+
goalId: goal.id,
|
|
116
|
+
sessionKey,
|
|
117
|
+
previousStatus: goal.status,
|
|
118
|
+
status: updatedGoal.status,
|
|
119
|
+
goal: updatedGoal
|
|
120
|
+
});
|
|
121
|
+
} catch (err) {
|
|
122
|
+
log.warn({
|
|
123
|
+
err,
|
|
124
|
+
sessionKey,
|
|
125
|
+
goalId: goal.id
|
|
126
|
+
}, `Persistent goal: SQLite goal update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
127
|
+
}
|
|
83
128
|
}
|
|
84
129
|
if (decision.message) if (publishVerdictToChannel) try {
|
|
85
130
|
await publishVerdictToChannel(decision.message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post-turn.js","names":[],"sources":["../../../../src/agent/goals/post-turn.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport { createLogger } from '../../utils/logger.js';\n\nimport { evaluateAfterTurnHermesLike } from './evaluate-turn.js';\nimport { appendGoalRun } from './goal-run-store.js';\nimport { resolveGoalUiLocale } from './goal-locale.js';\nimport type { PersistentGoalApis } from './persistent-goal-apis.js';\nimport {\n PERSISTENT_GOAL_CUSTOM_KEY,\n mergeCustomDataPatch,\n readPersistentGoal,\n serializePersistentGoal,\n} from './state.js';\n\nconst log = createLogger('PersistentGoal');\n\nfunction buildHistoryExcerpt(messages: AgentMessage[], maxChars: number): string {\n if (maxChars <= 0) return '';\n try {\n const raw = JSON.stringify(messages);\n if (raw.length <= maxChars) return raw;\n return raw.slice(-maxChars);\n } catch {\n return '';\n }\n}\n\nfunction resolveJudgeModelRef(\n config: Config | undefined,\n sessionKey: string,\n storedJudge?: string,\n runtimeSessionModelRef?: string,\n): string | undefined {\n const fromCfg = config?.goals?.judgeModelRef?.trim();\n if (fromCfg) return fromCfg;\n if (storedJudge?.trim()) return storedJudge.trim();\n if (config) {\n const profile = resolveEffectiveAgentProfileForSession(config, sessionKey);\n if (profile.primaryModelRef?.trim()) return profile.primaryModelRef.trim();\n }\n if (runtimeSessionModelRef?.trim()) return runtimeSessionModelRef.trim();\n if (config) return getAgentDefaultModelRef(config);\n return undefined;\n}\n\nasync function appendAssistantLine(apis: PersistentGoalApis, sessionKey: string, text: string): Promise<void> {\n await apis.appendAssistantReceipt(sessionKey, text);\n}\n\nexport async function handlePersistentGoalPostTurn(opts: {\n apis: PersistentGoalApis;\n sessionKey: string;\n assistantPlainText: string;\n aborted: boolean;\n streamError?: string;\n skipPersistentGoalPostTurn: boolean;\n config: Config | undefined;\n /** Active session model (overrides, per-agent defaults) when goals/global defaults are unset. */\n runtimeSessionModelRef?: string;\n signal?: AbortSignal;\n /** Hermes-style: verdict line also sent as a normal outbound message (non-webchat). */\n publishVerdictToChannel?: (text: string) => Promise<void>;\n}): Promise<void> {\n const {\n apis,\n sessionKey,\n assistantPlainText,\n aborted,\n streamError,\n skipPersistentGoalPostTurn,\n config,\n runtimeSessionModelRef,\n signal,\n publishVerdictToChannel,\n } = opts;\n\n if (skipPersistentGoalPostTurn) return;\n if (aborted || streamError) return;\n\n const meta = await apis.getSessionMetadata(sessionKey);\n if (!meta) return;\n\n const state = readPersistentGoal(meta.customData as Record<string, unknown> | undefined);\n if (!state || state.status !== 'active') return;\n\n const judgeRef = resolveJudgeModelRef(config, sessionKey, state.judgeModelRef, runtimeSessionModelRef);\n if (!judgeRef) {\n log.warn({ sessionKey }, 'Persistent goal: no judge model ref; skipping post-turn');\n return;\n }\n\n const goalsCfg = config?.goals;\n const historyCap = goalsCfg?.checklistHistoryChars ?? 24_000;\n let historyExcerpt = '';\n try {\n const msgs = await apis.loadMessages(sessionKey);\n historyExcerpt = buildHistoryExcerpt(msgs, historyCap);\n } catch (err) {\n log.debug(\n { err, sessionKey },\n `Persistent goal: could not load messages for judge context: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n const decision = await evaluateAfterTurnHermesLike(state, assistantPlainText, judgeRef, signal, {\n goalsSlice: goalsCfg,\n historyExcerpt,\n uiLocale: resolveGoalUiLocale(state),\n });\n\n const baseCustom = { ...(meta.customData as Record<string, unknown> | undefined) };\n\n if (decision.newState) {\n const merged = mergeCustomDataPatch(baseCustom, {\n [PERSISTENT_GOAL_CUSTOM_KEY]: serializePersistentGoal(decision.newState),\n });\n await apis.updateSessionMetadata(sessionKey, { customData: merged });\n }\n\n if (config) {\n try {\n await appendGoalRun({\n config,\n sessionKey,\n decision,\n assistantPlainText,\n });\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: goal run append failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n if (decision.message) {\n if (publishVerdictToChannel) {\n try {\n await publishVerdictToChannel(decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: channel verdict send failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n } else {\n try {\n await appendAssistantLine(apis, sessionKey, decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: failed to append status message: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n if (decision.shouldContinue && decision.continuationPrompt) {\n apis.scheduleContinuation(sessionKey, decision.continuationPrompt);\n }\n}\n"],"mappings":";;;;;;;;;aAGiE;aAEZ;AAarD,MAAM,MAAM,aAAa,iBAAiB;AAE1C,SAAS,oBAAoB,UAA0B,UAA0B;AAC/E,KAAI,YAAY,EAAG,QAAO;AAC1B,KAAI;EACF,MAAM,MAAM,KAAK,UAAU,SAAS;AACpC,MAAI,IAAI,UAAU,SAAU,QAAO;AACnC,SAAO,IAAI,MAAM,CAAC,SAAS;SACrB;AACN,SAAO;;;AAIX,SAAS,qBACP,QACA,YACA,aACA,wBACoB;CACpB,MAAM,UAAU,QAAQ,OAAO,eAAe,MAAM;AACpD,KAAI,QAAS,QAAO;AACpB,KAAI,aAAa,MAAM,CAAE,QAAO,YAAY,MAAM;AAClD,KAAI,QAAQ;EACV,MAAM,UAAU,uCAAuC,QAAQ,WAAW;AAC1E,MAAI,QAAQ,iBAAiB,MAAM,CAAE,QAAO,QAAQ,gBAAgB,MAAM;;AAE5E,KAAI,wBAAwB,MAAM,CAAE,QAAO,uBAAuB,MAAM;AACxE,KAAI,OAAQ,QAAO,wBAAwB,OAAO;;AAIpD,eAAe,oBAAoB,MAA0B,YAAoB,MAA6B;AAC5G,OAAM,KAAK,uBAAuB,YAAY,KAAK;;AAGrD,eAAsB,6BAA6B,MAajC;CAChB,MAAM,EACJ,MACA,YACA,oBACA,SACA,aACA,4BACA,QACA,wBACA,QACA,4BACE;AAEJ,KAAI,2BAA4B;AAChC,KAAI,WAAW,YAAa;CAE5B,MAAM,OAAO,MAAM,KAAK,mBAAmB,WAAW;AACtD,KAAI,CAAC,KAAM;CAEX,MAAM,QAAQ,mBAAmB,KAAK,WAAkD;AACxF,KAAI,CAAC,SAAS,MAAM,WAAW,SAAU;CAEzC,MAAM,WAAW,qBAAqB,QAAQ,YAAY,MAAM,eAAe,uBAAuB;AACtG,KAAI,CAAC,UAAU;AACb,MAAI,KAAK,EAAE,YAAY,EAAE,0DAA0D;AACnF;;CAGF,MAAM,WAAW,QAAQ;CACzB,MAAM,aAAa,UAAU,yBAAyB;CACtD,IAAI,iBAAiB;AACrB,KAAI;AAEF,mBAAiB,oBAAoB,MADlB,KAAK,aAAa,WAAW,EACL,WAAW;UAC/C,KAAK;AACZ,MAAI,MACF;GAAE;GAAK;GAAY,EACnB,+DAA+D,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAChH;;CAGH,MAAM,WAAW,MAAM,4BAA4B,OAAO,oBAAoB,UAAU,QAAQ;EAC9F,YAAY;EACZ;EACA,UAAU,oBAAoB,MAAM;EACrC,CAAC;CAEF,MAAM,aAAa,EAAE,GAAI,KAAK,YAAoD;AAElF,KAAI,SAAS,UAAU;EACrB,MAAM,SAAS,qBAAqB,YAAY,GAC7C,6BAA6B,wBAAwB,SAAS,SAAS,EACzE,CAAC;AACF,QAAM,KAAK,sBAAsB,YAAY,EAAE,YAAY,QAAQ,CAAC;;AAGtE,KAAI,OACF,KAAI;AACF,QAAM,cAAc;GAClB;GACA;GACA;GACA;GACD,CAAC;UACK,KAAK;AACZ,MAAI,KACF;GAAE;GAAK;GAAY,EACnB,4CAA4C,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAC7F;;AAIL,KAAI,SAAS,QACX,KAAI,wBACF,KAAI;AACF,QAAM,wBAAwB,SAAS,QAAQ;UACxC,KAAK;AACZ,MAAI,KACF;GAAE;GAAK;GAAY,EACnB,iDAAiD,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAClG;;KAGH,KAAI;AACF,QAAM,oBAAoB,MAAM,YAAY,SAAS,QAAQ;UACtD,KAAK;AACZ,MAAI,KACF;GAAE;GAAK;GAAY,EACnB,qDAAqD,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GACtG;;AAKP,KAAI,SAAS,kBAAkB,SAAS,mBACtC,MAAK,qBAAqB,YAAY,SAAS,mBAAmB"}
|
|
1
|
+
{"version":3,"file":"post-turn.js","names":[],"sources":["../../../../src/agent/goals/post-turn.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { Config } from '../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { resolveEffectiveAgentProfileForSession } from '../../config/agent-profile.js';\nimport { GoalService } from '../../goals/index.js';\nimport { createLogger } from '../../utils/logger.js';\n\nimport { evaluateAfterTurnHermesLike } from './evaluate-turn.js';\nimport { resolveGoalUiLocale } from './goal-locale.js';\nimport type { PersistentGoalApis } from './persistent-goal-apis.js';\nimport type { PersistentGoalState } from './state.js';\n\nconst log = createLogger('PersistentGoal');\nconst goalService = new GoalService();\n\nfunction buildHistoryExcerpt(messages: AgentMessage[], maxChars: number): string {\n if (maxChars <= 0) return '';\n try {\n const raw = JSON.stringify(messages);\n if (raw.length <= maxChars) return raw;\n return raw.slice(-maxChars);\n } catch {\n return '';\n }\n}\n\nfunction resolveJudgeModelRef(\n config: Config | undefined,\n sessionKey: string,\n storedJudge?: string,\n runtimeSessionModelRef?: string,\n): string | undefined {\n const fromCfg = config?.goals?.judgeModelRef?.trim();\n if (fromCfg) return fromCfg;\n if (storedJudge?.trim()) return storedJudge.trim();\n if (config) {\n const profile = resolveEffectiveAgentProfileForSession(config, sessionKey);\n if (profile.primaryModelRef?.trim()) return profile.primaryModelRef.trim();\n }\n if (runtimeSessionModelRef?.trim()) return runtimeSessionModelRef.trim();\n if (config) return getAgentDefaultModelRef(config);\n return undefined;\n}\n\nasync function appendAssistantLine(apis: PersistentGoalApis, sessionKey: string, text: string): Promise<void> {\n await apis.appendAssistantReceipt(sessionKey, text);\n}\n\nexport async function handlePersistentGoalPostTurn(opts: {\n apis: PersistentGoalApis;\n sessionKey: string;\n assistantPlainText: string;\n aborted: boolean;\n streamError?: string;\n skipPersistentGoalPostTurn: boolean;\n config: Config | undefined;\n /** Active session model (overrides, per-agent defaults) when goals/global defaults are unset. */\n runtimeSessionModelRef?: string;\n signal?: AbortSignal;\n /** Hermes-style: verdict line also sent as a normal outbound message (non-webchat). */\n publishVerdictToChannel?: (text: string) => Promise<void>;\n onGoalStatusUpdated?: (payload: {\n goalId: string;\n sessionKey: string;\n previousStatus: string;\n status: string;\n goal: import('../../goals/types.js').GoalWithDetails;\n }) => void;\n}): Promise<void> {\n const {\n apis,\n sessionKey,\n assistantPlainText,\n aborted,\n streamError,\n skipPersistentGoalPostTurn,\n config,\n runtimeSessionModelRef,\n signal,\n publishVerdictToChannel,\n onGoalStatusUpdated,\n } = opts;\n\n if (skipPersistentGoalPostTurn) return;\n if (aborted || streamError) return;\n\n const meta = await apis.getSessionMetadata(sessionKey);\n if (!meta) return;\n\n const goal = goalService.getActiveForSession(sessionKey);\n if (!goal || goal.status !== 'active') return;\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((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n completedAt: it.completedAt,\n evidence: it.evidenceSummary,\n })),\n };\n\n const judgeRef = resolveJudgeModelRef(config, sessionKey, state.judgeModelRef, runtimeSessionModelRef);\n if (!judgeRef) {\n log.warn({ sessionKey }, 'Persistent goal: no judge model ref; skipping post-turn');\n return;\n }\n\n const goalsCfg = config?.goals;\n const historyCap = goalsCfg?.checklistHistoryChars ?? 24_000;\n let historyExcerpt = '';\n try {\n const msgs = await apis.loadMessages(sessionKey);\n historyExcerpt = buildHistoryExcerpt(msgs, historyCap);\n } catch (err) {\n log.debug(\n { err, sessionKey },\n `Persistent goal: could not load messages for judge context: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n const decision = await evaluateAfterTurnHermesLike(state, assistantPlainText, judgeRef, signal, {\n goalsSlice: goalsCfg,\n historyExcerpt,\n uiLocale: resolveGoalUiLocale(state),\n });\n\n if (decision.newState) {\n const ns = 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 try {\n const updatedGoal = goalService.syncPostTurnState({\n goalId: goal.id,\n sessionKey,\n source: 'chat',\n status: ns.status === 'done'\n ? 'done'\n : decision.verdict === 'blocked'\n ? 'blocked'\n : decision.verdict === 'needs_input'\n ? 'needs_input'\n : ns.status === 'paused'\n ? 'paused'\n : 'active',\n turnsUsed: ns.turnsUsed,\n maxTurns: ns.maxTurns,\n reason: ns.pausedReason ?? decision.reason,\n nextAction: decision.continuationPrompt ?? undefined,\n assistantPreview: assistantPlainText,\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: ns.checklist?.map((it) => ({\n text: it.text,\n status: it.status,\n addedBy: it.addedBy,\n addedAt: it.addedAt,\n completedAt: it.completedAt,\n evidenceSummary: it.evidence,\n })),\n });\n if (updatedGoal && updatedGoal.status !== goal.status) {\n onGoalStatusUpdated?.({\n goalId: goal.id,\n sessionKey,\n previousStatus: goal.status,\n status: updatedGoal.status,\n goal: updatedGoal,\n });\n }\n } catch (err) {\n log.warn(\n { err, sessionKey, goalId: goal.id },\n `Persistent goal: SQLite goal update failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n if (decision.message) {\n if (publishVerdictToChannel) {\n try {\n await publishVerdictToChannel(decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: channel verdict send failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n } else {\n try {\n await appendAssistantLine(apis, sessionKey, decision.message);\n } catch (err) {\n log.warn(\n { err, sessionKey },\n `Persistent goal: failed to append status message: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n if (decision.shouldContinue && decision.continuationPrompt) {\n apis.scheduleContinuation(sessionKey, decision.continuationPrompt);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { type ChecklistItemStatus, type GoalChecklistItem } from './checklist-types.js';
|
|
2
2
|
import type { ServerLocale as GoalUiLocale } from '../../i18n/locale.js';
|
|
3
|
-
/** Persisted under `SessionMetadata.customData.persistentGoal`. */
|
|
4
|
-
export declare const PERSISTENT_GOAL_CUSTOM_KEY = "persistentGoal";
|
|
5
3
|
export type PersistentGoalStatus = 'active' | 'paused' | 'done' | 'cleared';
|
|
6
4
|
export interface PersistentGoalState {
|
|
7
5
|
goal: string;
|
|
@@ -25,8 +23,6 @@ export interface PersistentGoalState {
|
|
|
25
23
|
export declare function defaultMaxTurns(cfg: {
|
|
26
24
|
maxTurns?: number;
|
|
27
25
|
} | undefined): number;
|
|
28
|
-
export declare function readPersistentGoal(customData: Record<string, unknown> | undefined): PersistentGoalState | null;
|
|
29
|
-
export declare function serializePersistentGoal(s: PersistentGoalState): Record<string, unknown>;
|
|
30
26
|
/** Render checklist for continuation prompt (Hermes-style, no numbers in body). */
|
|
31
27
|
export declare function renderChecklistPlain(items: GoalChecklistItem[]): string;
|
|
32
28
|
/** Numbered checklist for judge user prompts (1-based indices). */
|
|
@@ -48,4 +44,3 @@ export declare function applyJudgeChecklistUpdates(items: GoalChecklistItem[], p
|
|
|
48
44
|
text: string;
|
|
49
45
|
}[];
|
|
50
46
|
}): GoalChecklistItem[];
|
|
51
|
-
export declare function mergeCustomDataPatch(existingCustom: Record<string, unknown> | undefined, patch: Record<string, unknown>): Record<string, unknown>;
|