@xopcai/xopc 0.0.99 → 0.0.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/src/account-manager.d.ts +3 -3
- package/dist/extensions/telegram/src/account-manager.js +8 -8
- package/dist/extensions/telegram/src/account-manager.js.map +1 -1
- package/dist/extensions/telegram/src/actions/message-actions.d.ts +4 -0
- package/dist/extensions/telegram/src/actions/message-actions.js +71 -0
- package/dist/extensions/telegram/src/actions/message-actions.js.map +1 -0
- package/dist/extensions/telegram/src/adapters/config-adapter.js +9 -1
- package/dist/extensions/telegram/src/adapters/config-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/config-surface.js +1 -1
- package/dist/extensions/telegram/src/adapters/config-surface.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/outbound-adapter.d.ts +2 -1
- package/dist/extensions/telegram/src/adapters/outbound-adapter.js +18 -4
- package/dist/extensions/telegram/src/adapters/outbound-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/security-adapter.js +2 -1
- package/dist/extensions/telegram/src/adapters/security-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +90 -6
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/types.d.ts +9 -1
- package/dist/extensions/telegram/src/api-root.d.ts +4 -0
- package/dist/extensions/telegram/src/api-root.js +42 -0
- package/dist/extensions/telegram/src/api-root.js.map +1 -0
- package/dist/extensions/telegram/src/approval-delivery.d.ts +9 -0
- package/dist/extensions/telegram/src/approval-delivery.js +36 -0
- package/dist/extensions/telegram/src/approval-delivery.js.map +1 -0
- package/dist/extensions/telegram/src/approval-store.d.ts +25 -0
- package/dist/extensions/telegram/src/approval-store.js +61 -0
- package/dist/extensions/telegram/src/approval-store.js.map +1 -0
- package/dist/extensions/telegram/src/config-schema.d.ts +185 -35
- package/dist/extensions/telegram/src/config-schema.js +67 -45
- package/dist/extensions/telegram/src/config-schema.js.map +1 -1
- package/dist/extensions/telegram/src/conversation-id.d.ts +6 -0
- package/dist/extensions/telegram/src/conversation-id.js +18 -0
- package/dist/extensions/telegram/src/conversation-id.js.map +1 -0
- package/dist/extensions/telegram/src/doctor.d.ts +5 -0
- package/dist/extensions/telegram/src/doctor.js +80 -0
- package/dist/extensions/telegram/src/doctor.js.map +1 -0
- package/dist/extensions/telegram/src/exec-approval-handler.d.ts +7 -0
- package/dist/extensions/telegram/src/exec-approval-handler.js +36 -0
- package/dist/extensions/telegram/src/exec-approval-handler.js.map +1 -0
- package/dist/extensions/telegram/src/exec-approvals.d.ts +8 -0
- package/dist/extensions/telegram/src/exec-approvals.js +20 -0
- package/dist/extensions/telegram/src/exec-approvals.js.map +1 -0
- package/dist/extensions/telegram/src/focus-handler.d.ts +12 -0
- package/dist/extensions/telegram/src/focus-handler.js +55 -0
- package/dist/extensions/telegram/src/focus-handler.js.map +1 -0
- package/dist/extensions/telegram/src/group-config-resolver.d.ts +12 -0
- package/dist/extensions/telegram/src/group-config-resolver.js +17 -0
- package/dist/extensions/telegram/src/group-config-resolver.js.map +1 -0
- package/dist/extensions/telegram/src/inbound-coalescer.d.ts +15 -0
- package/dist/extensions/telegram/src/inbound-coalescer.js +107 -0
- package/dist/extensions/telegram/src/inbound-coalescer.js.map +1 -0
- package/dist/extensions/telegram/src/inbound-processor.d.ts +1 -0
- package/dist/extensions/telegram/src/inbound-processor.js +41 -4
- package/dist/extensions/telegram/src/inbound-processor.js.map +1 -1
- package/dist/extensions/telegram/src/network-errors.d.ts +2 -0
- package/dist/extensions/telegram/src/network-errors.js +23 -0
- package/dist/extensions/telegram/src/network-errors.js.map +1 -0
- package/dist/extensions/telegram/src/plugin.d.ts +11 -0
- package/dist/extensions/telegram/src/plugin.js +191 -57
- package/dist/extensions/telegram/src/plugin.js.map +1 -1
- package/dist/extensions/telegram/src/polling-session.d.ts +17 -0
- package/dist/extensions/telegram/src/polling-session.js +112 -0
- package/dist/extensions/telegram/src/polling-session.js.map +1 -0
- package/dist/extensions/telegram/src/proxy-fetch.d.ts +2 -0
- package/dist/extensions/telegram/src/proxy-fetch.js +14 -0
- package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -0
- package/dist/extensions/telegram/src/reactions.d.ts +14 -0
- package/dist/extensions/telegram/src/reactions.js +48 -0
- package/dist/extensions/telegram/src/reactions.js.map +1 -0
- package/dist/extensions/telegram/src/reply-params.d.ts +15 -0
- package/dist/extensions/telegram/src/reply-params.js +28 -0
- package/dist/extensions/telegram/src/reply-params.js.map +1 -0
- package/dist/extensions/telegram/src/startup-errors.d.ts +3 -0
- package/dist/extensions/telegram/src/startup-errors.js +27 -0
- package/dist/extensions/telegram/src/startup-errors.js.map +1 -0
- package/dist/extensions/telegram/src/telegram-actions.d.ts +25 -0
- package/dist/extensions/telegram/src/telegram-actions.js +65 -0
- package/dist/extensions/telegram/src/telegram-actions.js.map +1 -0
- package/dist/extensions/telegram/src/thread-bindings.d.ts +15 -0
- package/dist/extensions/telegram/src/thread-bindings.js +22 -0
- package/dist/extensions/telegram/src/thread-bindings.js.map +1 -0
- package/dist/extensions/telegram/src/token-resolver.d.ts +8 -0
- package/dist/extensions/telegram/src/token-resolver.js +34 -0
- package/dist/extensions/telegram/src/token-resolver.js.map +1 -0
- package/dist/extensions/telegram/src/update-offset-store.d.ts +9 -0
- package/dist/extensions/telegram/src/update-offset-store.js +66 -0
- package/dist/extensions/telegram/src/update-offset-store.js.map +1 -0
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agents-4KTK-Ku7.js → agents-C5jtBK-H.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-DkgInY2w.js → apps-page-smJl-qf_.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CH6KgFK6.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-CV70xvY7.js +8 -0
- package/dist/gateway/static/root/assets/{cron-api-BRDli2Mm.js → cron-api-CgBO8B7I.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-BzEr5Za8.js → cron-page-Be0cW1cR.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-BsHh1vX0.js → dist-P8HRGUuh.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-TWt5q_ef.js → extension-debug-page-BowuycYu.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C3kV8ZvZ.js → extension-page-27-Zpv8O.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Csy9LNC6.js → extension-settings-page-DDFa_rIq.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-BLLOP2CM.js → fetch-drJUxxKP.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-MXbM8HvY.js → field-primitives-BWLssxEb.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CkoyqfRx.js → heartbeat-config-api-BVuYNYT_.js} +1 -1
- package/dist/gateway/static/root/assets/index-CRDAmr3W.js +4840 -0
- package/dist/gateway/static/root/assets/index-DjNDHzwG.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-B2vY41ph.js → logs-page-BDX8IrDQ.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-page-B7qE5pkO.js → note-detail-page-BmQ9KeiA.js} +1 -1
- package/dist/gateway/static/root/assets/{note-time-NBBReVR4.js → note-time-14I9Sgqh.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-CsWYaqYM.js → notes-page-BMfP0FFf.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-BPGY3SCT.js → sessions-page-C3scyChq.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-advanced-gate-DtA451RM.js → settings-advanced-gate-2ODuCjHP.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DYR_SPlX.js → settings-form-section-DUoGKAiW.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BJUgZQzN.js → settings-page-CttAfOWV.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-3u8VFmdo.js → share-preview-page-B77xqiiI.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-DuyhcH4U.js → skills-page-B_bAZGzB.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-e2q2yjs4.js → theme-store-BgCPrmxU.js} +1 -1
- package/dist/gateway/static/root/assets/url-q28QhI7l.js +3 -0
- package/dist/gateway/static/root/assets/{utils-B4Vw3fnc.js → utils-CCGejlcX.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-BFY67Hhp.js → voice-api-key-field-DZzzihcY.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-page.utils-yUJ5jexd.js → workflow-page.utils-D5RMAmT4.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-DIMHCpNt.js → workflows-page-DEYpC6Bv.js} +1 -1
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +4 -0
- package/dist/src/agent/agent-manager.js +68 -4
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +1 -0
- package/dist/src/agent/child-agent-factory.js +13 -10
- package/dist/src/agent/child-agent-factory.js.map +1 -1
- package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
- package/dist/src/agent/embedded/run-for-session.js +1 -0
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/embedded/run-turn.js +1 -17
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.js +3 -1
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.d.ts +1 -0
- package/dist/src/agent/embedded/session-tool-result-guard.js +1 -0
- package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
- package/dist/src/agent/inbound/attachment-pipeline.d.ts +37 -0
- package/dist/src/agent/inbound/attachment-pipeline.js +169 -0
- package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +3 -5
- package/dist/src/agent/inbound/turn-dispatcher.js +1 -2
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/memory/index.d.ts +2 -0
- package/dist/src/agent/memory/index.js +2 -1
- package/dist/src/agent/memory/memory-flush.d.ts +27 -0
- package/dist/src/agent/memory/memory-flush.js +124 -0
- package/dist/src/agent/memory/memory-flush.js.map +1 -0
- package/dist/src/agent/messaging/outbound-coordinator.js +2 -1
- package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -1
- package/dist/src/agent/messaging/stream-manager.d.ts +2 -0
- package/dist/src/agent/messaging/stream-manager.js +3 -0
- package/dist/src/agent/messaging/stream-manager.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +40 -107
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/prompt/contribution.d.ts +9 -0
- package/dist/src/agent/prompt/contribution.js +1 -0
- package/dist/src/agent/prompt/safety.js +0 -10
- package/dist/src/agent/prompt/safety.js.map +1 -1
- package/dist/src/agent/prompt/sanitize-for-prompt.d.ts +6 -0
- package/dist/src/agent/prompt/sanitize-for-prompt.js +13 -0
- package/dist/src/agent/prompt/sanitize-for-prompt.js.map +1 -0
- package/dist/src/agent/prompt/sections/behavior.d.ts +5 -0
- package/dist/src/agent/prompt/sections/behavior.js +50 -0
- package/dist/src/agent/prompt/sections/behavior.js.map +1 -0
- package/dist/src/agent/prompt/sections/memory-skills.d.ts +9 -0
- package/dist/src/agent/prompt/sections/memory-skills.js +59 -0
- package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -0
- package/dist/src/agent/prompt/sections/messaging-runtime.d.ts +16 -0
- package/dist/src/agent/prompt/sections/messaging-runtime.js +69 -0
- package/dist/src/agent/prompt/sections/messaging-runtime.js.map +1 -0
- package/dist/src/agent/prompt/sections/project-context.d.ts +16 -0
- package/dist/src/agent/prompt/sections/project-context.js +58 -0
- package/dist/src/agent/prompt/sections/project-context.js.map +1 -0
- package/dist/src/agent/prompt/sections/tooling.d.ts +5 -0
- package/dist/src/agent/prompt/sections/tooling.js +119 -0
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -0
- package/dist/src/agent/prompt/sections/workspace-runtime.d.ts +11 -0
- package/dist/src/agent/prompt/sections/workspace-runtime.js +32 -0
- package/dist/src/agent/prompt/sections/workspace-runtime.js.map +1 -0
- package/dist/src/agent/prompt/service-prompt-builder.d.ts +13 -0
- package/dist/src/agent/prompt/service-prompt-builder.js +54 -13
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/subagent-context.d.ts +15 -0
- package/dist/src/agent/prompt/subagent-context.js +68 -0
- package/dist/src/agent/prompt/subagent-context.js.map +1 -0
- package/dist/src/agent/prompt/system-prompt-params.d.ts +53 -0
- package/dist/src/agent/prompt/system-prompt-params.js +74 -0
- package/dist/src/agent/prompt/system-prompt-params.js.map +1 -0
- package/dist/src/agent/prompt/system-prompt.d.ts +22 -11
- package/dist/src/agent/prompt/system-prompt.js +79 -193
- package/dist/src/agent/prompt/system-prompt.js.map +1 -1
- package/dist/src/agent/prompt/types.d.ts +3 -0
- package/dist/src/agent/service/build-direct-message-content.d.ts +5 -21
- package/dist/src/agent/service/build-direct-message-content.js +11 -64
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +7 -0
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
- package/dist/src/agent/service/process-direct-one-shot.js +22 -17
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +6 -20
- package/dist/src/agent/service/process-direct-streaming.js +39 -40
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/webchat-tts.d.ts +4 -9
- package/dist/src/agent/service/webchat-tts.js +9 -20
- package/dist/src/agent/service/webchat-tts.js.map +1 -1
- package/dist/src/agent/service.d.ts +8 -19
- package/dist/src/agent/service.js +53 -11
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/tools/factory.js +2 -0
- package/dist/src/agent/tools/factory.js.map +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/media-read-tool.d.ts +2 -0
- package/dist/src/agent/tools/media-read-tool.js +89 -0
- package/dist/src/agent/tools/media-read-tool.js.map +1 -0
- package/dist/src/channels/attachments/attachment-classifiers.d.ts +8 -0
- package/dist/src/channels/attachments/attachment-classifiers.js +11 -0
- package/dist/src/channels/attachments/attachment-classifiers.js.map +1 -0
- package/dist/src/channels/attachments/inbound-persist.d.ts +13 -34
- package/dist/src/channels/attachments/inbound-persist.js +34 -102
- package/dist/src/channels/attachments/inbound-persist.js.map +1 -1
- package/dist/src/channels/attachments/inbound-types.d.ts +13 -0
- package/dist/src/channels/attachments/inbound-types.js +30 -0
- package/dist/src/channels/attachments/inbound-types.js.map +1 -0
- package/dist/src/channels/attachments/outbound-tts-persist.d.ts +3 -12
- package/dist/src/channels/attachments/outbound-tts-persist.js +28 -48
- package/dist/src/channels/attachments/outbound-tts-persist.js.map +1 -1
- package/dist/src/channels/attachments/voice-stt-webchat.d.ts +3 -3
- package/dist/src/channels/attachments/voice-stt-webchat.js +8 -14
- package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
- package/dist/src/channels/channel-domain.d.ts +30 -2
- package/dist/src/channels/exec-approval-runtime.d.ts +29 -0
- package/dist/src/channels/exec-approval-runtime.js +30 -0
- package/dist/src/channels/exec-approval-runtime.js.map +1 -0
- package/dist/src/channels/index.js +1 -1
- package/dist/src/channels/plugin-types.d.ts +1 -0
- package/dist/src/channels/transport-types.d.ts +2 -2
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.d.ts +2 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +62 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js.map +1 -0
- package/dist/src/cli/commands/doctor/flow.js +2 -0
- package/dist/src/cli/commands/doctor/flow.js.map +1 -1
- package/dist/src/cli/commands/init.js +2 -57
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/onboard/channels/registry.js +1 -1
- package/dist/src/cli/commands/setup.js +6 -5
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -2
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/paths.d.ts +0 -13
- package/dist/src/config/paths.js +1 -20
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/rules.js +1 -1
- package/dist/src/config/schema.d.ts +24 -0
- package/dist/src/config/schema.js +33 -2
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/cron/executor.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/channels.js +3 -3
- package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
- 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/media.d.ts +3 -0
- package/dist/src/gateway/hono/routes/media.js +50 -0
- package/dist/src/gateway/hono/routes/media.js.map +1 -0
- package/dist/src/gateway/hono/routes/sessions.js +6 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +1 -87
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.js +3 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/media/index.d.ts +5 -0
- package/dist/src/media/index.js +5 -0
- package/dist/src/media/media-reference.d.ts +23 -0
- package/dist/src/media/media-reference.js +34 -0
- package/dist/src/media/media-reference.js.map +1 -0
- package/dist/src/media/paths.d.ts +5 -0
- package/dist/src/media/paths.js +20 -0
- package/dist/src/media/paths.js.map +1 -0
- package/dist/src/media/session-references.d.ts +8 -0
- package/dist/src/media/session-references.js +45 -0
- package/dist/src/media/session-references.js.map +1 -0
- package/dist/src/media/store.d.ts +19 -0
- package/dist/src/media/store.js +131 -0
- package/dist/src/media/store.js.map +1 -0
- package/dist/src/media/types.d.ts +34 -0
- package/dist/src/media/types.js +1 -0
- package/dist/src/media/uri.d.ts +15 -0
- package/dist/src/media/uri.js +51 -0
- package/dist/src/media/uri.js.map +1 -0
- package/dist/src/session/session-title.js +6 -3
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/store.js +1 -1
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/types.d.ts +12 -7
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/storage/sqlite/index.d.ts +4 -1
- package/dist/src/storage/sqlite/index.js +6 -2
- package/dist/src/storage/sqlite/migrations/002_add_flush_columns.sql +3 -0
- package/dist/src/storage/sqlite/migrations/discover.d.ts +4 -0
- package/dist/src/storage/sqlite/migrations/discover.js +38 -0
- package/dist/src/storage/sqlite/migrations/discover.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/discover.ts +52 -0
- package/dist/src/storage/sqlite/migrations/errors.d.ts +11 -0
- package/dist/src/storage/sqlite/migrations/errors.js +27 -0
- package/dist/src/storage/sqlite/migrations/errors.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/errors.ts +32 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +22 -0
- package/dist/src/storage/sqlite/migrations/runner.js +97 -0
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/runner.ts +153 -0
- package/dist/src/storage/sqlite/migrations/types.d.ts +12 -0
- package/dist/src/storage/sqlite/migrations/types.js +1 -0
- package/dist/src/storage/sqlite/migrations/types.ts +13 -0
- package/dist/src/storage/sqlite/row-mappers.d.ts +4 -0
- package/dist/src/storage/sqlite/row-mappers.js +4 -0
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema-version.d.ts +6 -0
- package/dist/src/storage/sqlite/schema-version.js +29 -0
- package/dist/src/storage/sqlite/schema-version.js.map +1 -0
- package/dist/src/storage/sqlite/schema.d.ts +5 -3
- package/dist/src/storage/sqlite/schema.js +24 -28
- package/dist/src/storage/sqlite/schema.js.map +1 -1
- package/dist/src/storage/sqlite/schema.sql +2 -0
- package/dist/src/storage/sqlite/session-metadata.js +1 -0
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
- package/dist/src/storage/sqlite/session-repository.js +7 -3
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BxW1Xio4.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-Cxm6AvQO.js +0 -8
- package/dist/gateway/static/root/assets/index-BJDmBCSl.css +0 -1
- package/dist/gateway/static/root/assets/index-Cbg5TS5m.js +0 -4707
- package/dist/gateway/static/root/assets/url-DpFBIyN9.js +0 -3
- package/dist/src/cli/commands/onboard/workspace.d.ts +0 -14
- package/dist/src/cli/commands/onboard/workspace.js +0 -33
- package/dist/src/cli/commands/onboard/workspace.js.map +0 -1
- package/dist/src/cli/utils/workspace.d.ts +0 -35
- package/dist/src/cli/utils/workspace.js +0 -72
- package/dist/src/cli/utils/workspace.js.map +0 -1
|
@@ -2,13 +2,12 @@ import { createLogger } from "../../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import "../memory/dreaming/constants.js";
|
|
4
4
|
import { resolveDreamingConfig } from "../memory/dreaming/config.js";
|
|
5
|
+
import { persistInboundAttachments } from "../../channels/attachments/inbound-persist.js";
|
|
6
|
+
import { buildTranscriptUserMessage, clearPendingTranscriptUserMessage, hydrateUserTurnForLlm, setPendingTranscriptUserMessage } from "../inbound/attachment-pipeline.js";
|
|
5
7
|
import { extractAgentUserPlainText } from "../memory/user-message-text.js";
|
|
6
|
-
import { formatInboundFileTextBlock, persistInboundAttachmentsToWorkspace } from "../../channels/attachments/inbound-persist.js";
|
|
7
8
|
import { resolveEffectiveThinkingLevel } from "../../session/thinking-resolve.js";
|
|
8
9
|
import { abortEmbeddedRun } from "../embedded/runs.js";
|
|
9
10
|
import { runEmbeddedTurnForSession } from "../embedded/run-for-session.js";
|
|
10
|
-
import { expandAtFileMentionsInPlainText } from "../context/expand-at-file-mentions.js";
|
|
11
|
-
import { resolveInboundImageContentParts } from "../image/inbound-image-handling.js";
|
|
12
11
|
import { runDreamingDeepPromotion } from "../memory/dreaming/deep-promotion.js";
|
|
13
12
|
import { appendDreamingEvent } from "../memory/dreaming/events.js";
|
|
14
13
|
import { runLightSweep } from "../memory/dreaming/light-sweep.js";
|
|
@@ -113,28 +112,50 @@ var AgentOrchestrator = class {
|
|
|
113
112
|
}
|
|
114
113
|
try {
|
|
115
114
|
await this.sessionHydrator.model(sessionKey);
|
|
115
|
+
const channelSystemPrompt = typeof context.metadata?.channelSystemPrompt === "string" ? context.metadata.channelSystemPrompt.trim() : "";
|
|
116
|
+
if (channelSystemPrompt) {
|
|
117
|
+
this.agentManager.getOrCreateAgent(sessionKey);
|
|
118
|
+
this.agentManager.applyTurnChannelSystemPrompt(sessionKey, channelSystemPrompt);
|
|
119
|
+
}
|
|
116
120
|
const thinkingDefault = this.getThinkingDefaultForSession?.(sessionKey) ?? this.getThinkingDefault();
|
|
117
121
|
const thinkingLevel = await resolveEffectiveThinkingLevel(this.sessionConfigStore, sessionKey, null, thinkingDefault);
|
|
118
122
|
this.agentManager.setThinkingLevel(sessionKey, thinkingLevel);
|
|
119
|
-
const persistedAttachments = await
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
const persistedAttachments = await persistInboundAttachments(msg.attachments);
|
|
124
|
+
const modelRef = this.modelManager.getModelForSession(sessionKey);
|
|
125
|
+
const userMessage = await buildTranscriptUserMessage({
|
|
126
|
+
text: msg.content,
|
|
127
|
+
prepared: persistedAttachments,
|
|
128
|
+
sessionKey,
|
|
129
|
+
modelRef,
|
|
130
|
+
config: this.getConfig?.(),
|
|
131
|
+
agentManager: this.agentManager
|
|
132
|
+
});
|
|
133
|
+
setPendingTranscriptUserMessage(sessionKey, userMessage);
|
|
124
134
|
const userPlainForMemory = extractAgentUserPlainText(userMessage);
|
|
125
135
|
const userMessageForModel = await this.agentManager.applyMemoryPrefetchToUserMessage(userMessage, sessionKey);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
userMessage: userMessageForModel,
|
|
130
|
-
sessionStore: this.sessionStore,
|
|
131
|
-
agentManager: this.agentManager,
|
|
132
|
-
modelManager: this.modelManager,
|
|
133
|
-
thinkingOverride: thinkingLevel,
|
|
134
|
-
getConfig: this.getConfig,
|
|
135
|
-
beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),
|
|
136
|
-
onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event)
|
|
136
|
+
const llmTurn = await hydrateUserTurnForLlm({
|
|
137
|
+
message: userMessage,
|
|
138
|
+
modelRef
|
|
137
139
|
});
|
|
140
|
+
this.feedbackCoordinator.startTask();
|
|
141
|
+
const turnResult = await (async () => {
|
|
142
|
+
try {
|
|
143
|
+
return await runEmbeddedTurnForSession({
|
|
144
|
+
sessionKey,
|
|
145
|
+
userMessage: userMessageForModel,
|
|
146
|
+
llmImages: llmTurn.images,
|
|
147
|
+
sessionStore: this.sessionStore,
|
|
148
|
+
agentManager: this.agentManager,
|
|
149
|
+
modelManager: this.modelManager,
|
|
150
|
+
thinkingOverride: thinkingLevel,
|
|
151
|
+
getConfig: this.getConfig,
|
|
152
|
+
beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),
|
|
153
|
+
onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event)
|
|
154
|
+
});
|
|
155
|
+
} finally {
|
|
156
|
+
clearPendingTranscriptUserMessage(sessionKey, userMessage);
|
|
157
|
+
}
|
|
158
|
+
})();
|
|
138
159
|
this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory);
|
|
139
160
|
this.agentManager.scheduleBackgroundReviewAfterUserTurn(sessionKey);
|
|
140
161
|
if (turnResult.ok) {
|
|
@@ -155,94 +176,6 @@ var AgentOrchestrator = class {
|
|
|
155
176
|
}
|
|
156
177
|
}
|
|
157
178
|
/**
|
|
158
|
-
* Build an agent message from an inbound message
|
|
159
|
-
*/
|
|
160
|
-
async buildUserMessage(msg, sessionKey) {
|
|
161
|
-
const storageRootAbs = this.getAgentInternalStorageRootForSession(sessionKey);
|
|
162
|
-
let textBody = msg.content.trimStart().startsWith("/skill:") ? this.agentManager.expandSkillUserText(msg.content) : msg.content;
|
|
163
|
-
if (/@file:/.test(textBody)) {
|
|
164
|
-
const root = this.agentManager.getResolvedWorkspaceForSession(sessionKey);
|
|
165
|
-
textBody = await expandAtFileMentionsInPlainText(textBody, root);
|
|
166
|
-
}
|
|
167
|
-
if (!msg.attachments || msg.attachments.length === 0) return {
|
|
168
|
-
role: "user",
|
|
169
|
-
content: textBody,
|
|
170
|
-
timestamp: Date.now()
|
|
171
|
-
};
|
|
172
|
-
const modelRef = this.modelManager.getModelForSession(sessionKey);
|
|
173
|
-
const cfg = this.getConfig?.();
|
|
174
|
-
const messageContent = [];
|
|
175
|
-
if (msg.content.trim()) messageContent.push({
|
|
176
|
-
type: "text",
|
|
177
|
-
text: textBody
|
|
178
|
-
});
|
|
179
|
-
const attachments = msg.attachments;
|
|
180
|
-
let i = 0;
|
|
181
|
-
while (i < attachments.length) {
|
|
182
|
-
const att = attachments[i];
|
|
183
|
-
if (att.type === "image" || att.type === "photo" || Boolean(att.mimeType?.startsWith("image/"))) {
|
|
184
|
-
const group = [];
|
|
185
|
-
while (i < attachments.length) {
|
|
186
|
-
const a = attachments[i];
|
|
187
|
-
if (!(a.type === "image" || a.type === "photo" || Boolean(a.mimeType?.startsWith("image/")))) break;
|
|
188
|
-
if (!a.data || a.data.length === 0) {
|
|
189
|
-
log.warn({
|
|
190
|
-
type: a.type,
|
|
191
|
-
name: a.name
|
|
192
|
-
}, "Empty image data, skipping");
|
|
193
|
-
i += 1;
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
group.push({
|
|
197
|
-
data: a.data,
|
|
198
|
-
mimeType: a.mimeType || "image/jpeg"
|
|
199
|
-
});
|
|
200
|
-
i += 1;
|
|
201
|
-
}
|
|
202
|
-
if (group.length > 0) {
|
|
203
|
-
const parts = await resolveInboundImageContentParts({
|
|
204
|
-
modelRef,
|
|
205
|
-
cfg,
|
|
206
|
-
userTextForContext: msg.content.trim() ? textBody : "",
|
|
207
|
-
images: group
|
|
208
|
-
});
|
|
209
|
-
messageContent.push(...parts);
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
const fileBlock = formatInboundFileTextBlock({
|
|
213
|
-
type: att.type,
|
|
214
|
-
mimeType: att.mimeType,
|
|
215
|
-
name: att.name,
|
|
216
|
-
size: att.size,
|
|
217
|
-
workspaceRelativePath: att.workspaceRelativePath
|
|
218
|
-
}, storageRootAbs);
|
|
219
|
-
messageContent.push({
|
|
220
|
-
type: "text",
|
|
221
|
-
text: fileBlock
|
|
222
|
-
});
|
|
223
|
-
i += 1;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
const hasText = messageContent.some((item) => item.type === "text");
|
|
227
|
-
if (messageContent.some((item) => item.type === "image") && !hasText) messageContent.unshift({
|
|
228
|
-
type: "text",
|
|
229
|
-
text: "Please analyze the image(s) I sent."
|
|
230
|
-
});
|
|
231
|
-
if (messageContent.length === 0) {
|
|
232
|
-
log.warn({ attachmentCount: msg.attachments.length }, "All attachments were skipped, falling back to text message");
|
|
233
|
-
return {
|
|
234
|
-
role: "user",
|
|
235
|
-
content: textBody || "[Image attachment could not be processed]",
|
|
236
|
-
timestamp: Date.now()
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
return {
|
|
240
|
-
role: "user",
|
|
241
|
-
content: messageContent,
|
|
242
|
-
timestamp: Date.now()
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
179
|
* Get the current agent model ID
|
|
247
180
|
*/
|
|
248
181
|
getCurrentModel() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-orchestrator.js","names":[],"sources":["../../../../src/agent/orchestration/agent-orchestrator.ts"],"sourcesContent":["/**\n * Agent Orchestrator - Coordinates Agent execution flow\n *\n * Manages the complete agent execution pipeline from message processing\n * to response generation.\n */\n\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { Config } from '../../config/schema.js';\nimport type { InboundMessage } from '../../infra/bus/index.js';\nimport type { SessionConfigStore, SessionStore } from '../../session/index.js';\nimport type { SessionHydrator } from '../session/index.js';\nimport { resolveEffectiveThinkingLevel } from '../../session/thinking-resolve.js';\nimport type { ThinkLevel } from '../transcript/thinking-types.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionContext } from '../session/session-context.js';\nimport type { AgentEventHandler } from './agent-event-handler.js';\nimport type { FeedbackCoordinator } from '../feedback/feedback-coordinator.js';\nimport type { AgentManager } from '../agent-manager.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { extractAgentUserPlainText } from '../memory/user-message-text.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { runEmbeddedTurnForSession } from '../embedded/run-for-session.js';\nimport type { EmbeddedStreamEvent } from '../embedded/types.js';\nimport {\n persistInboundAttachmentsToWorkspace,\n formatInboundFileTextBlock,\n} from '../../channels/attachments/inbound-persist.js';\nimport { expandAtFileMentionsInPlainText } from '../context/expand-at-file-mentions.js';\nimport { resolveInboundImageContentParts } from '../image/inbound-image-handling.js';\nimport {\n DREAMING_SWEEP_TOKEN,\n DREAMING_LIGHT_SWEEP_TOKEN,\n DREAMING_REM_SWEEP_TOKEN,\n} from '../memory/dreaming/constants.js';\nimport { resolveDreamingConfig } from '../memory/dreaming/config.js';\nimport { runDreamingDeepPromotion } from '../memory/dreaming/deep-promotion.js';\nimport { appendDreamingEvent, type DreamingEvent } from '../memory/dreaming/events.js';\nimport { runLightSweep } from '../memory/dreaming/light-sweep.js';\nimport { runRemPatterns } from '../memory/dreaming/rem-patterns.js';\n\nconst log = createLogger('AgentOrchestrator');\n\nexport interface AgentOrchestratorConfig {\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n eventHandler: AgentEventHandler;\n feedbackCoordinator: FeedbackCoordinator;\n sessionConfigStore: SessionConfigStore;\n /** Per-session hydration (workspace override + model override) before the agent runs. */\n sessionHydrator: SessionHydrator;\n getThinkingDefault: () => ThinkLevel | undefined;\n /** Per-session default from merged `agents.list` / defaults (optional). */\n getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n /** Default workspace root when no per-session resolver is set. */\n workspaceRoot: string;\n /** Per-agent workspace root for attachments (optional; defaults to `workspaceRoot`). */\n getWorkspaceRootForSession?: (sessionKey: string) => string;\n /** Agent home (`…/agents/<id>/`) for inbound/TTS files — keeps internal state out of the markdown workspace. */\n getAgentInternalStorageRootForSession?: (sessionKey: string) => string;\n /** Fire-and-forget after full session persist (e.g. LLM session title); not called from mid-turn snapshots. */\n enqueueAutoTitle?: (sessionKey: string) => void;\n /** For per-turn timeout via `agents.defaults.maxTaskDurationMs`. */\n getConfig?: () => Config | undefined;\n /** Channel streaming: token/tool events from pi embedded session. */\n onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n /** Called after a successful embedded turn with assistant plain text. */\n onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n}\n\nexport class AgentOrchestrator {\n private agentManager: AgentManager;\n private sessionStore: SessionStore;\n private modelManager: ModelManager;\n private eventHandler: AgentEventHandler;\n private feedbackCoordinator: FeedbackCoordinator;\n private sessionConfigStore: SessionConfigStore;\n private sessionHydrator: SessionHydrator;\n private getThinkingDefault: () => ThinkLevel | undefined;\n private getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n private workspaceRoot: string;\n private getWorkspaceRootForSession?: (sessionKey: string) => string;\n private getAgentInternalStorageRootForSession: (sessionKey: string) => string;\n private enqueueAutoTitle?: (sessionKey: string) => void;\n private getConfig?: () => Config | undefined;\n private onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n private onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n\n constructor(config: AgentOrchestratorConfig) {\n this.agentManager = config.agentManager;\n this.sessionStore = config.sessionStore;\n this.modelManager = config.modelManager;\n this.eventHandler = config.eventHandler;\n this.feedbackCoordinator = config.feedbackCoordinator;\n this.sessionConfigStore = config.sessionConfigStore;\n this.sessionHydrator = config.sessionHydrator;\n this.getThinkingDefault = config.getThinkingDefault;\n this.getThinkingDefaultForSession = config.getThinkingDefaultForSession;\n this.workspaceRoot = config.workspaceRoot;\n this.getWorkspaceRootForSession = config.getWorkspaceRootForSession;\n this.getAgentInternalStorageRootForSession =\n config.getAgentInternalStorageRootForSession ??\n ((sk) => this.getWorkspaceRootForSession?.(sk) ?? this.workspaceRoot);\n this.enqueueAutoTitle = config.enqueueAutoTitle;\n this.getConfig = config.getConfig;\n this.onEmbeddedStreamEvent = config.onEmbeddedStreamEvent;\n this.onEmbeddedTurnComplete = config.onEmbeddedTurnComplete;\n }\n\n /**\n * Process a message through the agent orchestration pipeline\n */\n async process(msg: InboundMessage, context: SessionContext): Promise<void> {\n const { sessionKey } = context;\n\n log.debug({ sessionKey }, 'Processing message through agent orchestrator');\n\n await this.sessionHydrator.workspace(sessionKey);\n\n // Dreaming: short-circuit cron-triggered sweep tokens into maintenance runs.\n // This avoids spending LLM tokens for scheduled memory consolidation.\n if (\n typeof msg.content === 'string' &&\n (sessionKey.startsWith('cron:') || context.channel === 'cron')\n ) {\n const content = msg.content;\n const isDreamingSweep =\n content.includes(DREAMING_SWEEP_TOKEN) ||\n content.includes(DREAMING_LIGHT_SWEEP_TOKEN) ||\n content.includes(DREAMING_REM_SWEEP_TOKEN);\n\n if (isDreamingSweep) {\n const workspaceDir = this.agentManager.getResolvedWorkspaceForSession(sessionKey);\n const resolved = resolveDreamingConfig(this.getConfig?.());\n const t0 = Date.now();\n\n if (content.includes(DREAMING_LIGHT_SWEEP_TOKEN)) {\n const result = await runLightSweep({ workspaceDir, config: resolved.phases.light });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'light',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n scannedEntries: result.scannedEntries, newSignals: result.newSignals, deduped: result.deduped,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else if (content.includes(DREAMING_REM_SWEEP_TOKEN)) {\n const result = await runRemPatterns({ workspaceDir, config: resolved.phases.rem });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'rem',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n patternsDiscovered: result.patternsDiscovered, entriesAnalyzed: result.entriesAnalyzed,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else {\n const result = await runDreamingDeepPromotion({ workspaceDir, config: resolved.phases.deep });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'deep',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n candidates: result.candidates, applied: result.applied,\n };\n await appendDreamingEvent(workspaceDir, event);\n }\n return;\n }\n }\n\n try {\n await this.sessionHydrator.model(sessionKey);\n\n const thinkingDefault =\n this.getThinkingDefaultForSession?.(sessionKey) ?? this.getThinkingDefault();\n const thinkingLevel = await resolveEffectiveThinkingLevel(\n this.sessionConfigStore,\n sessionKey,\n null,\n thinkingDefault,\n );\n this.agentManager.setThinkingLevel(sessionKey, thinkingLevel);\n\n // Persist inbound files (Telegram, etc.) under agent home, then build user message\n const storageRoot = this.getAgentInternalStorageRootForSession(sessionKey);\n const persistedAttachments = await persistInboundAttachmentsToWorkspace(\n storageRoot,\n sessionKey,\n msg.attachments,\n );\n const userMessage = await this.buildUserMessage(\n {\n ...msg,\n attachments: persistedAttachments ?? msg.attachments,\n },\n sessionKey,\n );\n const userPlainForMemory = extractAgentUserPlainText(userMessage);\n const userMessageForModel = await this.agentManager.applyMemoryPrefetchToUserMessage(\n userMessage,\n sessionKey,\n );\n\n this.feedbackCoordinator.startTask();\n\n const turnResult = await runEmbeddedTurnForSession({\n sessionKey,\n userMessage: userMessageForModel,\n sessionStore: this.sessionStore,\n agentManager: this.agentManager,\n modelManager: this.modelManager,\n thinkingOverride: thinkingLevel,\n getConfig: this.getConfig,\n beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),\n onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event),\n });\n\n this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory);\n this.agentManager.scheduleBackgroundReviewAfterUserTurn(sessionKey);\n\n if (turnResult.ok) {\n this.onEmbeddedTurnComplete?.(sessionKey, turnResult.lastAssistantText);\n this.enqueueAutoTitle?.(sessionKey);\n } else if (turnResult.errorMessage) {\n log.warn({ sessionKey, errorMessage: turnResult.errorMessage }, 'Embedded inbound turn failed');\n }\n\n this.feedbackCoordinator.endTask();\n\n } catch (error) {\n log.error({ err: error, sessionKey }, 'Error in agent orchestration');\n this.feedbackCoordinator.endTask();\n throw error;\n }\n }\n\n /**\n * Build an agent message from an inbound message\n */\n private async buildUserMessage(msg: InboundMessage, sessionKey: string): Promise<AgentMessage> {\n const storageRootAbs = this.getAgentInternalStorageRootForSession(sessionKey);\n let textBody = msg.content.trimStart().startsWith('/skill:')\n ? this.agentManager.expandSkillUserText(msg.content)\n : msg.content;\n\n if (/@file:/.test(textBody)) {\n const root = this.agentManager.getResolvedWorkspaceForSession(sessionKey);\n textBody = await expandAtFileMentionsInPlainText(textBody, root);\n }\n\n if (!msg.attachments || msg.attachments.length === 0) {\n return {\n role: 'user',\n content: textBody,\n timestamp: Date.now(),\n };\n }\n\n const modelRef = this.modelManager.getModelForSession(sessionKey);\n const cfg = this.getConfig?.();\n\n const messageContent: Array<\n { type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }\n > = [];\n\n if (msg.content.trim()) {\n messageContent.push({ type: 'text', text: textBody });\n }\n\n const attachments = msg.attachments;\n let i = 0;\n while (i < attachments.length) {\n const att = attachments[i]!;\n const isImage =\n att.type === 'image' || att.type === 'photo' || Boolean(att.mimeType?.startsWith('image/'));\n\n if (isImage) {\n const group: Array<{ data: string; mimeType: string }> = [];\n while (i < attachments.length) {\n const a = attachments[i]!;\n const img =\n a.type === 'image' || a.type === 'photo' || Boolean(a.mimeType?.startsWith('image/'));\n if (!img) {\n break;\n }\n if (!a.data || a.data.length === 0) {\n log.warn({ type: a.type, name: a.name }, 'Empty image data, skipping');\n i += 1;\n continue;\n }\n group.push({ data: a.data, mimeType: a.mimeType || 'image/jpeg' });\n i += 1;\n }\n if (group.length > 0) {\n const parts = await resolveInboundImageContentParts({\n modelRef,\n cfg,\n userTextForContext: msg.content.trim() ? textBody : '',\n images: group,\n });\n messageContent.push(...parts);\n }\n } else {\n const fileBlock = formatInboundFileTextBlock(\n {\n type: att.type,\n mimeType: att.mimeType,\n name: att.name,\n size: att.size,\n workspaceRelativePath: att.workspaceRelativePath,\n },\n storageRootAbs,\n );\n messageContent.push({ type: 'text', text: fileBlock });\n i += 1;\n }\n }\n\n const hasText = messageContent.some((item) => item.type === 'text');\n const hasImage = messageContent.some((item) => item.type === 'image');\n if (hasImage && !hasText) {\n messageContent.unshift({ type: 'text', text: 'Please analyze the image(s) I sent.' });\n }\n\n if (messageContent.length === 0) {\n log.warn(\n { attachmentCount: msg.attachments.length },\n 'All attachments were skipped, falling back to text message',\n );\n return {\n role: 'user',\n content: textBody || '[Image attachment could not be processed]',\n timestamp: Date.now(),\n };\n }\n\n return {\n role: 'user',\n content: messageContent,\n timestamp: Date.now(),\n };\n }\n\n /**\n * Get the current agent model ID\n */\n getCurrentModel(): string {\n return this.modelManager.getCurrentModel();\n }\n\n /**\n * Check if agent is currently processing for a session\n */\n isProcessing(sessionKey: string): boolean {\n const agent = this.agentManager.getAgent(sessionKey);\n if (!agent) {\n return false;\n }\n return agent.state.messages.length > 0;\n }\n\n /**\n * Abort current agent execution for a session\n */\n abort(sessionKey: string): void {\n void abortEmbeddedRun(sessionKey);\n const agent = this.agentManager.getAgent(sessionKey);\n agent?.abort();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-orchestrator.js","names":[],"sources":["../../../../src/agent/orchestration/agent-orchestrator.ts"],"sourcesContent":["/**\n * Agent Orchestrator - Coordinates Agent execution flow\n *\n * Manages the complete agent execution pipeline from message processing\n * to response generation.\n */\n\nimport type { Config } from '../../config/schema.js';\nimport type { InboundMessage } from '../../infra/bus/index.js';\nimport type { SessionConfigStore, SessionStore } from '../../session/index.js';\nimport type { SessionHydrator } from '../session/index.js';\nimport { resolveEffectiveThinkingLevel } from '../../session/thinking-resolve.js';\nimport type { ThinkLevel } from '../transcript/thinking-types.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionContext } from '../session/session-context.js';\nimport type { AgentEventHandler } from './agent-event-handler.js';\nimport type { FeedbackCoordinator } from '../feedback/feedback-coordinator.js';\nimport type { AgentManager } from '../agent-manager.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { extractAgentUserPlainText } from '../memory/user-message-text.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport { runEmbeddedTurnForSession } from '../embedded/run-for-session.js';\nimport type { EmbeddedStreamEvent } from '../embedded/types.js';\nimport { persistInboundAttachments } from '../../channels/attachments/inbound-persist.js';\nimport {\n buildTranscriptUserMessage,\n clearPendingTranscriptUserMessage,\n hydrateUserTurnForLlm,\n setPendingTranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\nimport {\n DREAMING_SWEEP_TOKEN,\n DREAMING_LIGHT_SWEEP_TOKEN,\n DREAMING_REM_SWEEP_TOKEN,\n} from '../memory/dreaming/constants.js';\nimport { resolveDreamingConfig } from '../memory/dreaming/config.js';\nimport { runDreamingDeepPromotion } from '../memory/dreaming/deep-promotion.js';\nimport { appendDreamingEvent, type DreamingEvent } from '../memory/dreaming/events.js';\nimport { runLightSweep } from '../memory/dreaming/light-sweep.js';\nimport { runRemPatterns } from '../memory/dreaming/rem-patterns.js';\n\nconst log = createLogger('AgentOrchestrator');\n\nexport interface AgentOrchestratorConfig {\n agentManager: AgentManager;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n eventHandler: AgentEventHandler;\n feedbackCoordinator: FeedbackCoordinator;\n sessionConfigStore: SessionConfigStore;\n /** Per-session hydration (workspace override + model override) before the agent runs. */\n sessionHydrator: SessionHydrator;\n getThinkingDefault: () => ThinkLevel | undefined;\n /** Per-session default from merged `agents.list` / defaults (optional). */\n getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n /** Default workspace root when no per-session resolver is set. */\n workspaceRoot: string;\n /** Per-agent workspace root for attachments (optional; defaults to `workspaceRoot`). */\n getWorkspaceRootForSession?: (sessionKey: string) => string;\n /** Agent home (`…/agents/<id>/`) for inbound/TTS files — keeps internal state out of the markdown workspace. */\n getAgentInternalStorageRootForSession?: (sessionKey: string) => string;\n /** Fire-and-forget after full session persist (e.g. LLM session title); not called from mid-turn snapshots. */\n enqueueAutoTitle?: (sessionKey: string) => void;\n /** For per-turn timeout via `agents.defaults.maxTaskDurationMs`. */\n getConfig?: () => Config | undefined;\n /** Channel streaming: token/tool events from pi embedded session. */\n onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n /** Called after a successful embedded turn with assistant plain text. */\n onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n}\n\nexport class AgentOrchestrator {\n private agentManager: AgentManager;\n private sessionStore: SessionStore;\n private modelManager: ModelManager;\n private eventHandler: AgentEventHandler;\n private feedbackCoordinator: FeedbackCoordinator;\n private sessionConfigStore: SessionConfigStore;\n private sessionHydrator: SessionHydrator;\n private getThinkingDefault: () => ThinkLevel | undefined;\n private getThinkingDefaultForSession?: (sessionKey: string) => ThinkLevel | undefined;\n private workspaceRoot: string;\n private getWorkspaceRootForSession?: (sessionKey: string) => string;\n private getAgentInternalStorageRootForSession: (sessionKey: string) => string;\n private enqueueAutoTitle?: (sessionKey: string) => void;\n private getConfig?: () => Config | undefined;\n private onEmbeddedStreamEvent?: (sessionKey: string, event: EmbeddedStreamEvent) => void;\n private onEmbeddedTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n\n constructor(config: AgentOrchestratorConfig) {\n this.agentManager = config.agentManager;\n this.sessionStore = config.sessionStore;\n this.modelManager = config.modelManager;\n this.eventHandler = config.eventHandler;\n this.feedbackCoordinator = config.feedbackCoordinator;\n this.sessionConfigStore = config.sessionConfigStore;\n this.sessionHydrator = config.sessionHydrator;\n this.getThinkingDefault = config.getThinkingDefault;\n this.getThinkingDefaultForSession = config.getThinkingDefaultForSession;\n this.workspaceRoot = config.workspaceRoot;\n this.getWorkspaceRootForSession = config.getWorkspaceRootForSession;\n this.getAgentInternalStorageRootForSession =\n config.getAgentInternalStorageRootForSession ??\n ((sk) => this.getWorkspaceRootForSession?.(sk) ?? this.workspaceRoot);\n this.enqueueAutoTitle = config.enqueueAutoTitle;\n this.getConfig = config.getConfig;\n this.onEmbeddedStreamEvent = config.onEmbeddedStreamEvent;\n this.onEmbeddedTurnComplete = config.onEmbeddedTurnComplete;\n }\n\n /**\n * Process a message through the agent orchestration pipeline\n */\n async process(msg: InboundMessage, context: SessionContext): Promise<void> {\n const { sessionKey } = context;\n\n log.debug({ sessionKey }, 'Processing message through agent orchestrator');\n\n await this.sessionHydrator.workspace(sessionKey);\n\n // Dreaming: short-circuit cron-triggered sweep tokens into maintenance runs.\n // This avoids spending LLM tokens for scheduled memory consolidation.\n if (\n typeof msg.content === 'string' &&\n (sessionKey.startsWith('cron:') || context.channel === 'cron')\n ) {\n const content = msg.content;\n const isDreamingSweep =\n content.includes(DREAMING_SWEEP_TOKEN) ||\n content.includes(DREAMING_LIGHT_SWEEP_TOKEN) ||\n content.includes(DREAMING_REM_SWEEP_TOKEN);\n\n if (isDreamingSweep) {\n const workspaceDir = this.agentManager.getResolvedWorkspaceForSession(sessionKey);\n const resolved = resolveDreamingConfig(this.getConfig?.());\n const t0 = Date.now();\n\n if (content.includes(DREAMING_LIGHT_SWEEP_TOKEN)) {\n const result = await runLightSweep({ workspaceDir, config: resolved.phases.light });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'light',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n scannedEntries: result.scannedEntries, newSignals: result.newSignals, deduped: result.deduped,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else if (content.includes(DREAMING_REM_SWEEP_TOKEN)) {\n const result = await runRemPatterns({ workspaceDir, config: resolved.phases.rem });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'rem',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n patternsDiscovered: result.patternsDiscovered, entriesAnalyzed: result.entriesAnalyzed,\n };\n await appendDreamingEvent(workspaceDir, event);\n } else {\n const result = await runDreamingDeepPromotion({ workspaceDir, config: resolved.phases.deep });\n const event: DreamingEvent = {\n timestamp: new Date().toISOString(), phase: 'deep',\n ok: result.ok, reason: result.reason, durationMs: Date.now() - t0,\n candidates: result.candidates, applied: result.applied,\n };\n await appendDreamingEvent(workspaceDir, event);\n }\n return;\n }\n }\n\n try {\n await this.sessionHydrator.model(sessionKey);\n\n const channelSystemPrompt =\n typeof context.metadata?.channelSystemPrompt === 'string'\n ? context.metadata.channelSystemPrompt.trim()\n : '';\n if (channelSystemPrompt) {\n this.agentManager.getOrCreateAgent(sessionKey);\n this.agentManager.applyTurnChannelSystemPrompt(sessionKey, channelSystemPrompt);\n }\n\n const thinkingDefault =\n this.getThinkingDefaultForSession?.(sessionKey) ?? this.getThinkingDefault();\n const thinkingLevel = await resolveEffectiveThinkingLevel(\n this.sessionConfigStore,\n sessionKey,\n null,\n thinkingDefault,\n );\n this.agentManager.setThinkingLevel(sessionKey, thinkingLevel);\n\n const persistedAttachments = await persistInboundAttachments(msg.attachments);\n const modelRef = this.modelManager.getModelForSession(sessionKey);\n const userMessage = await buildTranscriptUserMessage({\n text: msg.content,\n prepared: persistedAttachments,\n sessionKey,\n modelRef,\n config: this.getConfig?.(),\n agentManager: this.agentManager,\n });\n setPendingTranscriptUserMessage(sessionKey, userMessage);\n\n const userPlainForMemory = extractAgentUserPlainText(userMessage);\n const userMessageForModel = await this.agentManager.applyMemoryPrefetchToUserMessage(\n userMessage,\n sessionKey,\n );\n\n const llmTurn = await hydrateUserTurnForLlm({\n message: userMessage,\n modelRef,\n });\n\n this.feedbackCoordinator.startTask();\n\n const turnResult = await (async () => {\n try {\n return await runEmbeddedTurnForSession({\n sessionKey,\n userMessage: userMessageForModel,\n llmImages: llmTurn.images,\n sessionStore: this.sessionStore,\n agentManager: this.agentManager,\n modelManager: this.modelManager,\n thinkingOverride: thinkingLevel,\n getConfig: this.getConfig,\n beforeTurn: () => this.agentManager.beginBackgroundReviewUserTurn(sessionKey),\n onEvent: (event) => this.onEmbeddedStreamEvent?.(sessionKey, event),\n });\n } finally {\n clearPendingTranscriptUserMessage(sessionKey, userMessage);\n }\n })();\n\n this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory);\n this.agentManager.scheduleBackgroundReviewAfterUserTurn(sessionKey);\n\n if (turnResult.ok) {\n this.onEmbeddedTurnComplete?.(sessionKey, turnResult.lastAssistantText);\n this.enqueueAutoTitle?.(sessionKey);\n } else if (turnResult.errorMessage) {\n log.warn({ sessionKey, errorMessage: turnResult.errorMessage }, 'Embedded inbound turn failed');\n }\n\n this.feedbackCoordinator.endTask();\n\n } catch (error) {\n log.error({ err: error, sessionKey }, 'Error in agent orchestration');\n this.feedbackCoordinator.endTask();\n throw error;\n }\n }\n\n /**\n * Get the current agent model ID\n */\n getCurrentModel(): string {\n return this.modelManager.getCurrentModel();\n }\n\n /**\n * Check if agent is currently processing for a session\n */\n isProcessing(sessionKey: string): boolean {\n const agent = this.agentManager.getAgent(sessionKey);\n if (!agent) {\n return false;\n }\n return agent.state.messages.length > 0;\n }\n\n /**\n * Abort current agent execution for a session\n */\n abort(sessionKey: string): void {\n void abortEmbeddedRun(sessionKey);\n const agent = this.agentManager.getAgent(sessionKey);\n agent?.abort();\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ProviderSystemPromptSectionId = 'interaction_style' | 'tool_call_style' | 'execution_bias';
|
|
2
|
+
export type ProviderSystemPromptContribution = {
|
|
3
|
+
/** Cache-stable provider guidance inserted above the prompt cache boundary. */
|
|
4
|
+
stablePrefix?: string;
|
|
5
|
+
/** Provider guidance inserted below the cache boundary. */
|
|
6
|
+
dynamicSuffix?: string;
|
|
7
|
+
/** Whole-section replacements for selected core prompt sections. */
|
|
8
|
+
sectionOverrides?: Partial<Record<ProviderSystemPromptSectionId, string>>;
|
|
9
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
import { Type } from "@sinclair/typebox";
|
|
2
1
|
//#region src/agent/prompt/safety.ts
|
|
3
|
-
Type.Object({
|
|
4
|
-
allowExternalActions: Type.Optional(Type.Boolean({ default: false })),
|
|
5
|
-
allowDangerousOperations: Type.Optional(Type.Boolean({ default: false })),
|
|
6
|
-
requireConfirmationForDestructive: Type.Optional(Type.Boolean({ default: true })),
|
|
7
|
-
allowedChannels: Type.Optional(Type.Array(Type.String())),
|
|
8
|
-
blockedCommands: Type.Optional(Type.Array(Type.String())),
|
|
9
|
-
maxFileSize: Type.Optional(Type.Number({ default: 10 * 1024 * 1024 })),
|
|
10
|
-
maxShellTimeout: Type.Optional(Type.Number({ default: 300 }))
|
|
11
|
-
});
|
|
12
2
|
/**
|
|
13
3
|
* Quick safety check for file operations
|
|
14
4
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safety.js","names":[],"sources":["../../../../src/agent/prompt/safety.ts"],"sourcesContent":["// Safety System -
|
|
1
|
+
{"version":3,"file":"safety.js","names":[],"sources":["../../../../src/agent/prompt/safety.ts"],"sourcesContent":["// Safety System - Quick safety check for file operations\n\n/**\n * Quick safety check for file operations\n */\nexport function checkFileSafety(\n operation: 'read' | 'write' | 'delete',\n path: string\n): { allowed: boolean; message?: string } {\n // Check for sensitive paths\n const sensitivePaths = [\n '/etc/passwd',\n '/etc/shadow',\n '/root/.ssh',\n '/home/*/.ssh',\n '~/.aws',\n '~/.bashrc',\n '~/.profile',\n ];\n\n for (const sp of sensitivePaths) {\n if (path.includes(sp)) {\n return {\n allowed: false,\n message: `Cannot ${operation} sensitive path: ${path}`,\n };\n }\n }\n\n return { allowed: true };\n}\n\n"],"mappings":";;;;AAKA,SAAgB,gBACd,WACA,MACwC;AAYxC,MAAK,MAAM,MAAM;EATf;EACA;EACA;EACA;EACA;EACA;EACA;EAG6B,CAC7B,KAAI,KAAK,SAAS,GAAG,CACnB,QAAO;EACL,SAAS;EACT,SAAS,UAAU,UAAU,mBAAmB;EACjD;AAIL,QAAO,EAAE,SAAS,MAAM"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/agent/prompt/sanitize-for-prompt.ts
|
|
2
|
+
/**
|
|
3
|
+
* Sanitize untrusted strings before embedding them into an LLM prompt.
|
|
4
|
+
*
|
|
5
|
+
* Strips control/format characters that could break prompt structure or inject instructions.
|
|
6
|
+
*/
|
|
7
|
+
function sanitizeForPromptLiteral(value) {
|
|
8
|
+
return value.replace(/[\p{Cc}\p{Cf}\u2028\u2029]/gu, "");
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { sanitizeForPromptLiteral };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=sanitize-for-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize-for-prompt.js","names":[],"sources":["../../../../src/agent/prompt/sanitize-for-prompt.ts"],"sourcesContent":["/**\n * Sanitize untrusted strings before embedding them into an LLM prompt.\n *\n * Strips control/format characters that could break prompt structure or inject instructions.\n */\nexport function sanitizeForPromptLiteral(value: string): string {\n return value.replace(/[\\p{Cc}\\p{Cf}\\u2028\\u2029]/gu, '');\n}\n"],"mappings":";;;;;;AAKA,SAAgB,yBAAyB,OAAuB;AAC9D,QAAO,MAAM,QAAQ,gCAAgC,GAAG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function buildToolCallStyleSection(): string;
|
|
2
|
+
export declare function buildExecutionBiasSection(): string;
|
|
3
|
+
export declare function buildProblemSolvingSection(): string;
|
|
4
|
+
export declare function buildAestheticSection(): string;
|
|
5
|
+
export declare function buildSafetySection(): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region src/agent/prompt/sections/behavior.ts
|
|
2
|
+
function buildToolCallStyleSection() {
|
|
3
|
+
return [
|
|
4
|
+
"## Tool Call Style",
|
|
5
|
+
"Default: do not narrate routine, low-risk tool calls (just call the tool).",
|
|
6
|
+
"Narrate only when it helps: multi-step work, complex/challenging problems, sensitive actions (e.g., deletions), or when the user explicitly asks.",
|
|
7
|
+
"Keep narration brief and value-dense; avoid repeating obvious steps.",
|
|
8
|
+
"Use plain human language for narration unless in a technical context.",
|
|
9
|
+
"When a first-class tool exists for an action, use the tool directly instead of asking the user to run equivalent CLI commands."
|
|
10
|
+
].join("\n");
|
|
11
|
+
}
|
|
12
|
+
function buildExecutionBiasSection() {
|
|
13
|
+
return [
|
|
14
|
+
"## Execution Bias",
|
|
15
|
+
"- Actionable request: act in this turn.",
|
|
16
|
+
"- Non-final turn: use tools to advance, or ask for the one missing decision that blocks safe progress.",
|
|
17
|
+
"- Continue until done or genuinely blocked; do not finish with a plan/promise when tools can move it forward.",
|
|
18
|
+
"- Weak/empty tool result: vary query, path, command, or source before concluding.",
|
|
19
|
+
"- Mutable facts need live checks: files, git, clocks, versions, services, processes, package state.",
|
|
20
|
+
"- Final answer needs evidence: test/build/lint, screenshot, inspection, tool output, or a named blocker.",
|
|
21
|
+
"- Longer work: brief progress update, then keep going; use delegation or workflows when they fit."
|
|
22
|
+
].join("\n");
|
|
23
|
+
}
|
|
24
|
+
function buildProblemSolvingSection() {
|
|
25
|
+
return [
|
|
26
|
+
"## Problem Solving",
|
|
27
|
+
"**Simple tasks** (< 5 minutes or a single-file change): Do them directly; run a quick verification after changes.",
|
|
28
|
+
"**Complex tasks** (multiple files or design decisions): Use an iterative flow — Plan → Build → Verify → Fix.",
|
|
29
|
+
"**Core principle: Match the complexity; reject ritual for its own sake. Verification matters, but do not verify just to tick a box.**"
|
|
30
|
+
].join("\n");
|
|
31
|
+
}
|
|
32
|
+
function buildAestheticSection() {
|
|
33
|
+
return [
|
|
34
|
+
"## Tone & Style",
|
|
35
|
+
"**Default voice:** Direct, concise, concrete.",
|
|
36
|
+
"**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above."
|
|
37
|
+
].join("\n");
|
|
38
|
+
}
|
|
39
|
+
function buildSafetySection() {
|
|
40
|
+
return [
|
|
41
|
+
"## Safety",
|
|
42
|
+
"- You have no independent goals: do not pursue self-preservation, replication, resource acquisition, or power-seeking; avoid long-term plans beyond the user's request.",
|
|
43
|
+
"- Prioritize safety and human oversight over completion; if instructions conflict, pause and ask; comply with stop/pause/audit requests and never bypass safeguards.",
|
|
44
|
+
"- Do not manipulate or persuade anyone to expand access or disable safeguards. Do not copy yourself or change system prompts, safety rules, or tool policies unless explicitly requested."
|
|
45
|
+
].join("\n");
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { buildAestheticSection, buildExecutionBiasSection, buildProblemSolvingSection, buildSafetySection, buildToolCallStyleSection };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=behavior.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior.js","names":[],"sources":["../../../../../src/agent/prompt/sections/behavior.ts"],"sourcesContent":["export function buildToolCallStyleSection(): string {\n return [\n '## Tool Call Style',\n 'Default: do not narrate routine, low-risk tool calls (just call the tool).',\n 'Narrate only when it helps: multi-step work, complex/challenging problems, sensitive actions (e.g., deletions), or when the user explicitly asks.',\n 'Keep narration brief and value-dense; avoid repeating obvious steps.',\n 'Use plain human language for narration unless in a technical context.',\n 'When a first-class tool exists for an action, use the tool directly instead of asking the user to run equivalent CLI commands.',\n ].join('\\n');\n}\n\nexport function buildExecutionBiasSection(): string {\n return [\n '## Execution Bias',\n '- Actionable request: act in this turn.',\n '- Non-final turn: use tools to advance, or ask for the one missing decision that blocks safe progress.',\n '- Continue until done or genuinely blocked; do not finish with a plan/promise when tools can move it forward.',\n '- Weak/empty tool result: vary query, path, command, or source before concluding.',\n '- Mutable facts need live checks: files, git, clocks, versions, services, processes, package state.',\n '- Final answer needs evidence: test/build/lint, screenshot, inspection, tool output, or a named blocker.',\n '- Longer work: brief progress update, then keep going; use delegation or workflows when they fit.',\n ].join('\\n');\n}\n\nexport function buildProblemSolvingSection(): string {\n return [\n '## Problem Solving',\n '**Simple tasks** (< 5 minutes or a single-file change): Do them directly; run a quick verification after changes.',\n '**Complex tasks** (multiple files or design decisions): Use an iterative flow — Plan → Build → Verify → Fix.',\n '**Core principle: Match the complexity; reject ritual for its own sake. Verification matters, but do not verify just to tick a box.**',\n ].join('\\n');\n}\n\nexport function buildAestheticSection(): string {\n return [\n '## Tone & Style',\n '**Default voice:** Direct, concise, concrete.',\n '**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above.',\n ].join('\\n');\n}\n\nexport function buildSafetySection(): string {\n return [\n '## Safety',\n '- You have no independent goals: do not pursue self-preservation, replication, resource acquisition, or power-seeking; avoid long-term plans beyond the user\\'s request.',\n '- Prioritize safety and human oversight over completion; if instructions conflict, pause and ask; comply with stop/pause/audit requests and never bypass safeguards.',\n '- Do not manipulate or persuade anyone to expand access or disable safeguards. Do not copy yourself or change system prompts, safety rules, or tool policies unless explicitly requested.',\n ].join('\\n');\n}\n"],"mappings":";AAAA,SAAgB,4BAAoC;AAClD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,4BAAoC;AAClD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,6BAAqC;AACnD,QAAO;EACL;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,wBAAgC;AAC9C,QAAO;EACL;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,qBAA6B;AAC3C,QAAO;EACL;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MemoryCitationsMode } from '../types.js';
|
|
2
|
+
export declare function buildMemorySection(params: {
|
|
3
|
+
availableTools: Set<string>;
|
|
4
|
+
citationsMode?: MemoryCitationsMode;
|
|
5
|
+
hasProfileMemory?: boolean;
|
|
6
|
+
includeMemorySection?: boolean;
|
|
7
|
+
}): string;
|
|
8
|
+
export declare function buildExternalMemorySection(text: string | undefined): string;
|
|
9
|
+
export declare function buildSkillsSection(hasSkillTools: boolean): string;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//#region src/agent/prompt/sections/memory-skills.ts
|
|
2
|
+
function buildMemorySection(params) {
|
|
3
|
+
if (params.includeMemorySection === false) return "";
|
|
4
|
+
if (!(params.availableTools.has("memory_search") || params.availableTools.has("memory_get") || params.availableTools.has("curated_memory")) && !params.hasProfileMemory) return "";
|
|
5
|
+
const citationsMode = params.citationsMode ?? "on";
|
|
6
|
+
const citationInstruction = citationsMode === "off" ? "Citations are disabled: do not mention file paths or line numbers in replies." : citationsMode === "source-only" ? "Citations: mention file path when it helps (e.g., Source: MEMORY.md)." : "Citations: include Source: <path#line> when it helps the user verify memory snippets.";
|
|
7
|
+
const toolLines = [];
|
|
8
|
+
if (params.availableTools.has("memory_search")) toolLines.push("1. Run `memory_search` on profile MEMORY.md and workspace `memory/*.md`");
|
|
9
|
+
if (params.availableTools.has("session_search")) toolLines.push(`${toolLines.length + 1}. For **other chat sessions** / cross-session history, use \`session_search\` with keywords (or omit \`query\` to list recent sessions)`);
|
|
10
|
+
if (params.availableTools.has("memory_get")) toolLines.push(`${toolLines.length + 1}. Use \`memory_get\` to pull only the needed lines from files`);
|
|
11
|
+
if (params.availableTools.has("curated_memory")) toolLines.push(`${toolLines.length + 1}. For structured curated notes under agent home \`memories/\`, use \`curated_memory\``);
|
|
12
|
+
toolLines.push(`${toolLines.length + 1}. If low confidence after search, say you checked`);
|
|
13
|
+
return [
|
|
14
|
+
"## Memory Recall",
|
|
15
|
+
"",
|
|
16
|
+
citationInstruction,
|
|
17
|
+
"",
|
|
18
|
+
"Startup profile files (SOUL, USER, MEMORY, etc.) are already in Project Context above when injected. Do not re-read them unless the user asks or you need lines beyond what was injected.",
|
|
19
|
+
"",
|
|
20
|
+
"Before answering anything about prior work, decisions, dates, people, preferences, or todos:",
|
|
21
|
+
...toolLines,
|
|
22
|
+
"",
|
|
23
|
+
"### Memory Files",
|
|
24
|
+
"",
|
|
25
|
+
"- **Daily notes:** `memory/YYYY-MM-DD.md` — raw logs (runtime may preload recent days on /new or reset)",
|
|
26
|
+
"- **Long-term:** profile `MEMORY.md` — curated memories in Project Context when present",
|
|
27
|
+
"- **Curated store:** agent home `memories/MEMORY.md` and `memories/USER.md` — use `curated_memory` for live read/write",
|
|
28
|
+
"",
|
|
29
|
+
"### Writing to Memory",
|
|
30
|
+
"",
|
|
31
|
+
"- **Declarative vs procedural:** Save facts and preferences via workspace memory files and/or `curated_memory`. Save reusable task playbooks with `skill_manage` as skills.",
|
|
32
|
+
"- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE",
|
|
33
|
+
"- When someone says \"remember this\" → update `memory/YYYY-MM-DD.md` or relevant file",
|
|
34
|
+
"- **Text > Brain**"
|
|
35
|
+
].join("\n");
|
|
36
|
+
}
|
|
37
|
+
function buildExternalMemorySection(text) {
|
|
38
|
+
const t = text?.trim();
|
|
39
|
+
if (!t) return "";
|
|
40
|
+
return `## External memory provider\n\n${t}`;
|
|
41
|
+
}
|
|
42
|
+
function buildSkillsSection(hasSkillTools) {
|
|
43
|
+
if (!hasSkillTools) return "";
|
|
44
|
+
return [
|
|
45
|
+
"## Skills (mandatory)",
|
|
46
|
+
"Before replying: scan <available_skills> <description> entries.",
|
|
47
|
+
"- If exactly one skill clearly applies: use `skill_view(name)` to load its SKILL.md, then follow it.",
|
|
48
|
+
"- If multiple could apply: choose the most specific one, then load/follow it.",
|
|
49
|
+
"- If none clearly apply: do not load any SKILL.md.",
|
|
50
|
+
"Constraints: never load more than one skill up front; only load after selecting.",
|
|
51
|
+
"- When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.",
|
|
52
|
+
"",
|
|
53
|
+
"**Division of labor with memory:** Skills = **procedural** workflows; memory / `curated_memory` = **declarative** facts and preferences."
|
|
54
|
+
].join("\n");
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { buildExternalMemorySection, buildMemorySection, buildSkillsSection };
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=memory-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-skills.js","names":[],"sources":["../../../../../src/agent/prompt/sections/memory-skills.ts"],"sourcesContent":["import type { MemoryCitationsMode } from '../types.js';\n\nexport function buildMemorySection(params: {\n availableTools: Set<string>;\n citationsMode?: MemoryCitationsMode;\n hasProfileMemory?: boolean;\n includeMemorySection?: boolean;\n}): string {\n if (params.includeMemorySection === false) {\n return '';\n }\n const hasMemoryTools =\n params.availableTools.has('memory_search') ||\n params.availableTools.has('memory_get') ||\n params.availableTools.has('curated_memory');\n if (!hasMemoryTools && !params.hasProfileMemory) {\n return '';\n }\n\n const citationsMode = params.citationsMode ?? 'on';\n const citationInstruction =\n citationsMode === 'off'\n ? 'Citations are disabled: do not mention file paths or line numbers in replies.'\n : citationsMode === 'source-only'\n ? 'Citations: mention file path when it helps (e.g., Source: MEMORY.md).'\n : 'Citations: include Source: <path#line> when it helps the user verify memory snippets.';\n\n const toolLines: string[] = [];\n if (params.availableTools.has('memory_search')) {\n toolLines.push('1. Run `memory_search` on profile MEMORY.md and workspace `memory/*.md`');\n }\n if (params.availableTools.has('session_search')) {\n toolLines.push(\n `${toolLines.length + 1}. For **other chat sessions** / cross-session history, use \\`session_search\\` with keywords (or omit \\`query\\` to list recent sessions)`,\n );\n }\n if (params.availableTools.has('memory_get')) {\n toolLines.push(`${toolLines.length + 1}. Use \\`memory_get\\` to pull only the needed lines from files`);\n }\n if (params.availableTools.has('curated_memory')) {\n toolLines.push(\n `${toolLines.length + 1}. For structured curated notes under agent home \\`memories/\\`, use \\`curated_memory\\``,\n );\n }\n toolLines.push(`${toolLines.length + 1}. If low confidence after search, say you checked`);\n\n return [\n '## Memory Recall',\n '',\n citationInstruction,\n '',\n 'Startup profile files (SOUL, USER, MEMORY, etc.) are already in Project Context above when injected. Do not re-read them unless the user asks or you need lines beyond what was injected.',\n '',\n 'Before answering anything about prior work, decisions, dates, people, preferences, or todos:',\n ...toolLines,\n '',\n '### Memory Files',\n '',\n '- **Daily notes:** `memory/YYYY-MM-DD.md` — raw logs (runtime may preload recent days on /new or reset)',\n '- **Long-term:** profile `MEMORY.md` — curated memories in Project Context when present',\n '- **Curated store:** agent home `memories/MEMORY.md` and `memories/USER.md` — use `curated_memory` for live read/write',\n '',\n '### Writing to Memory',\n '',\n '- **Declarative vs procedural:** Save facts and preferences via workspace memory files and/or `curated_memory`. Save reusable task playbooks with `skill_manage` as skills.',\n '- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE',\n '- When someone says \"remember this\" → update `memory/YYYY-MM-DD.md` or relevant file',\n '- **Text > Brain**',\n ].join('\\n');\n}\n\nexport function buildExternalMemorySection(text: string | undefined): string {\n const t = text?.trim();\n if (!t) {\n return '';\n }\n return `## External memory provider\\n\\n${t}`;\n}\n\nexport function buildSkillsSection(hasSkillTools: boolean): string {\n if (!hasSkillTools) {\n return '';\n }\n\n return [\n '## Skills (mandatory)',\n 'Before replying: scan <available_skills> <description> entries.',\n '- If exactly one skill clearly applies: use `skill_view(name)` to load its SKILL.md, then follow it.',\n '- If multiple could apply: choose the most specific one, then load/follow it.',\n '- If none clearly apply: do not load any SKILL.md.',\n 'Constraints: never load more than one skill up front; only load after selecting.',\n '- When a skill drives external API writes, assume rate limits: prefer fewer larger writes, avoid tight one-item loops, serialize bursts when possible, and respect 429/Retry-After.',\n '',\n '**Division of labor with memory:** Skills = **procedural** workflows; memory / `curated_memory` = **declarative** facts and preferences.',\n ].join('\\n');\n}\n"],"mappings":";AAEA,SAAgB,mBAAmB,QAKxB;AACT,KAAI,OAAO,yBAAyB,MAClC,QAAO;AAMT,KAAI,EAHF,OAAO,eAAe,IAAI,gBAAgB,IAC1C,OAAO,eAAe,IAAI,aAAa,IACvC,OAAO,eAAe,IAAI,iBAAiB,KACtB,CAAC,OAAO,iBAC7B,QAAO;CAGT,MAAM,gBAAgB,OAAO,iBAAiB;CAC9C,MAAM,sBACJ,kBAAkB,QACd,kFACA,kBAAkB,gBAChB,0EACA;CAER,MAAM,YAAsB,EAAE;AAC9B,KAAI,OAAO,eAAe,IAAI,gBAAgB,CAC5C,WAAU,KAAK,0EAA0E;AAE3F,KAAI,OAAO,eAAe,IAAI,iBAAiB,CAC7C,WAAU,KACR,GAAG,UAAU,SAAS,EAAE,yIACzB;AAEH,KAAI,OAAO,eAAe,IAAI,aAAa,CACzC,WAAU,KAAK,GAAG,UAAU,SAAS,EAAE,+DAA+D;AAExG,KAAI,OAAO,eAAe,IAAI,iBAAiB,CAC7C,WAAU,KACR,GAAG,UAAU,SAAS,EAAE,uFACzB;AAEH,WAAU,KAAK,GAAG,UAAU,SAAS,EAAE,mDAAmD;AAE1F,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA,GAAG;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,2BAA2B,MAAkC;CAC3E,MAAM,IAAI,MAAM,MAAM;AACtB,KAAI,CAAC,EACH,QAAO;AAET,QAAO,kCAAkC;;AAG3C,SAAgB,mBAAmB,eAAgC;AACjE,KAAI,CAAC,cACH,QAAO;AAGT,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function buildMessagingSection(params: {
|
|
2
|
+
channels: string[];
|
|
3
|
+
isMinimal: boolean;
|
|
4
|
+
hasSendMessage: boolean;
|
|
5
|
+
}): string;
|
|
6
|
+
export declare function buildSilentRepliesSection(params: {
|
|
7
|
+
isMinimal: boolean;
|
|
8
|
+
silentReplyPromptMode?: 'generic' | 'none';
|
|
9
|
+
}): string;
|
|
10
|
+
export declare function buildOutputDirectivesSection(isMinimal: boolean): string;
|
|
11
|
+
export declare function buildTimeSection(timezone?: string): string;
|
|
12
|
+
export declare function buildHeartbeatBehaviorSection(params: {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
customPrompt?: string;
|
|
15
|
+
userTimezone?: string;
|
|
16
|
+
}): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { NO_REPLY } from "../../../heartbeat/tokens.js";
|
|
2
|
+
//#region src/agent/prompt/sections/messaging-runtime.ts
|
|
3
|
+
function buildMessagingSection(params) {
|
|
4
|
+
if (params.isMinimal || params.channels.length === 0) return "";
|
|
5
|
+
const channelList = params.channels.join(", ");
|
|
6
|
+
const messageToolLine = params.hasSendMessage ? `- Use \`send_message\` for proactive sends + channel actions` : "- Outbound messaging tools are not available in this session";
|
|
7
|
+
return [
|
|
8
|
+
"## Messaging",
|
|
9
|
+
`- Reply in current session → automatically routes to the source channel (${channelList})`,
|
|
10
|
+
messageToolLine,
|
|
11
|
+
`- If you use \`send_message\` to deliver your user-visible reply, respond with ONLY: ${NO_REPLY} (avoid duplicate replies)`
|
|
12
|
+
].join("\n");
|
|
13
|
+
}
|
|
14
|
+
function buildSilentRepliesSection(params) {
|
|
15
|
+
if (params.isMinimal || params.silentReplyPromptMode === "none") return "";
|
|
16
|
+
return [
|
|
17
|
+
"## Silent Replies",
|
|
18
|
+
`When you have nothing to say, respond with ONLY: ${NO_REPLY}`,
|
|
19
|
+
"",
|
|
20
|
+
"Rules:",
|
|
21
|
+
"- It must be your ENTIRE message — nothing else",
|
|
22
|
+
`- Never append it to an actual response (never include "${NO_REPLY}" in real replies)`,
|
|
23
|
+
"- Never wrap it in markdown or code blocks",
|
|
24
|
+
"",
|
|
25
|
+
`Wrong: "Here's help... ${NO_REPLY}"`,
|
|
26
|
+
`Right: ${NO_REPLY}`
|
|
27
|
+
].join("\n");
|
|
28
|
+
}
|
|
29
|
+
function buildOutputDirectivesSection(isMinimal) {
|
|
30
|
+
if (isMinimal) return "";
|
|
31
|
+
return [
|
|
32
|
+
"## Assistant Output Directives",
|
|
33
|
+
"Use these when you need delivery metadata in an assistant message:",
|
|
34
|
+
"- `MEDIA:<path-or-url>` on its own line requests attachment delivery. Supported clients strip MEDIA lines and render attachments inline; channels still decide actual delivery behavior.",
|
|
35
|
+
"- `[[audio_as_voice]]` marks attached audio as a voice-note style delivery hint when supported.",
|
|
36
|
+
"- To request a native reply/quote on supported surfaces, include one reply tag in your reply:",
|
|
37
|
+
"- Reply tags must be the very first token in the message (no leading text/newlines): [[reply_to_current]] your reply.",
|
|
38
|
+
"- [[reply_to_current]] replies to the triggering message.",
|
|
39
|
+
"- Prefer [[reply_to_current]]. Use [[reply_to:<id>]] only when an id was explicitly provided.",
|
|
40
|
+
"Supported tags are stripped before user-visible rendering; support still depends on the current channel config."
|
|
41
|
+
].join("\n");
|
|
42
|
+
}
|
|
43
|
+
function buildTimeSection(timezone) {
|
|
44
|
+
if (!timezone) return "";
|
|
45
|
+
return [
|
|
46
|
+
"## Current Date & Time",
|
|
47
|
+
`Time zone: ${timezone}`,
|
|
48
|
+
"",
|
|
49
|
+
"If you need the current date/time/day-of-week, use the `session_status` tool or the inbound message timestamp envelope (when present)."
|
|
50
|
+
].join("\n");
|
|
51
|
+
}
|
|
52
|
+
function buildHeartbeatBehaviorSection(params) {
|
|
53
|
+
if (!params.enabled) return "";
|
|
54
|
+
if (params.customPrompt?.trim()) return `## Heartbeats\n\n${params.customPrompt.trim()}`;
|
|
55
|
+
let quietHoursNote = "";
|
|
56
|
+
if (params.userTimezone) quietHoursNote = `\n\n> Quiet hours: The user is in **${params.userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;
|
|
57
|
+
return [
|
|
58
|
+
"## Heartbeats",
|
|
59
|
+
"",
|
|
60
|
+
"If the current user message is a heartbeat poll and nothing needs attention, reply exactly: HEARTBEAT_OK",
|
|
61
|
+
"",
|
|
62
|
+
"If something needs attention, do NOT include \"HEARTBEAT_OK\"; reply with the alert text instead.",
|
|
63
|
+
quietHoursNote.trim()
|
|
64
|
+
].filter(Boolean).join("\n");
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { buildHeartbeatBehaviorSection, buildMessagingSection, buildOutputDirectivesSection, buildSilentRepliesSection, buildTimeSection };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=messaging-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging-runtime.js","names":[],"sources":["../../../../../src/agent/prompt/sections/messaging-runtime.ts"],"sourcesContent":["import { NO_REPLY } from '../../../heartbeat/tokens.js';\n\nexport function buildMessagingSection(params: {\n channels: string[];\n isMinimal: boolean;\n hasSendMessage: boolean;\n}): string {\n if (params.isMinimal || params.channels.length === 0) {\n return '';\n }\n const channelList = params.channels.join(', ');\n const messageToolLine = params.hasSendMessage\n ? `- Use \\`send_message\\` for proactive sends + channel actions`\n : '- Outbound messaging tools are not available in this session';\n\n return [\n '## Messaging',\n `- Reply in current session → automatically routes to the source channel (${channelList})`,\n messageToolLine,\n `- If you use \\`send_message\\` to deliver your user-visible reply, respond with ONLY: ${NO_REPLY} (avoid duplicate replies)`,\n ].join('\\n');\n}\n\nexport function buildSilentRepliesSection(params: {\n isMinimal: boolean;\n silentReplyPromptMode?: 'generic' | 'none';\n}): string {\n if (params.isMinimal || params.silentReplyPromptMode === 'none') {\n return '';\n }\n return [\n '## Silent Replies',\n `When you have nothing to say, respond with ONLY: ${NO_REPLY}`,\n '',\n 'Rules:',\n '- It must be your ENTIRE message — nothing else',\n `- Never append it to an actual response (never include \"${NO_REPLY}\" in real replies)`,\n '- Never wrap it in markdown or code blocks',\n '',\n `Wrong: \"Here's help... ${NO_REPLY}\"`,\n `Right: ${NO_REPLY}`,\n ].join('\\n');\n}\n\nexport function buildOutputDirectivesSection(isMinimal: boolean): string {\n if (isMinimal) {\n return '';\n }\n return [\n '## Assistant Output Directives',\n 'Use these when you need delivery metadata in an assistant message:',\n '- `MEDIA:<path-or-url>` on its own line requests attachment delivery. Supported clients strip MEDIA lines and render attachments inline; channels still decide actual delivery behavior.',\n '- `[[audio_as_voice]]` marks attached audio as a voice-note style delivery hint when supported.',\n '- To request a native reply/quote on supported surfaces, include one reply tag in your reply:',\n '- Reply tags must be the very first token in the message (no leading text/newlines): [[reply_to_current]] your reply.',\n '- [[reply_to_current]] replies to the triggering message.',\n '- Prefer [[reply_to_current]]. Use [[reply_to:<id>]] only when an id was explicitly provided.',\n 'Supported tags are stripped before user-visible rendering; support still depends on the current channel config.',\n ].join('\\n');\n}\n\nexport function buildTimeSection(timezone?: string): string {\n if (!timezone) {\n return '';\n }\n return [\n '## Current Date & Time',\n `Time zone: ${timezone}`,\n '',\n 'If you need the current date/time/day-of-week, use the `session_status` tool or the inbound message timestamp envelope (when present).',\n ].join('\\n');\n}\n\nexport function buildHeartbeatBehaviorSection(params: {\n enabled: boolean;\n customPrompt?: string;\n userTimezone?: string;\n}): string {\n if (!params.enabled) {\n return '';\n }\n if (params.customPrompt?.trim()) {\n return `## Heartbeats\\n\\n${params.customPrompt.trim()}`;\n }\n let quietHoursNote = '';\n if (params.userTimezone) {\n quietHoursNote = `\\n\\n> Quiet hours: The user is in **${params.userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;\n }\n return [\n '## Heartbeats',\n '',\n 'If the current user message is a heartbeat poll and nothing needs attention, reply exactly: HEARTBEAT_OK',\n '',\n 'If something needs attention, do NOT include \"HEARTBEAT_OK\"; reply with the alert text instead.',\n quietHoursNote.trim(),\n ]\n .filter(Boolean)\n .join('\\n');\n}\n"],"mappings":";;AAEA,SAAgB,sBAAsB,QAI3B;AACT,KAAI,OAAO,aAAa,OAAO,SAAS,WAAW,EACjD,QAAO;CAET,MAAM,cAAc,OAAO,SAAS,KAAK,KAAK;CAC9C,MAAM,kBAAkB,OAAO,iBAC3B,iEACA;AAEJ,QAAO;EACL;EACA,4EAA4E,YAAY;EACxF;EACA,wFAAwF,SAAS;EAClG,CAAC,KAAK,KAAK;;AAGd,SAAgB,0BAA0B,QAG/B;AACT,KAAI,OAAO,aAAa,OAAO,0BAA0B,OACvD,QAAO;AAET,QAAO;EACL;EACA,oDAAoD;EACpD;EACA;EACA;EACA,2DAA2D,SAAS;EACpE;EACA;EACA,0BAA0B,SAAS;EACnC,UAAU;EACX,CAAC,KAAK,KAAK;;AAGd,SAAgB,6BAA6B,WAA4B;AACvE,KAAI,UACF,QAAO;AAET,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,iBAAiB,UAA2B;AAC1D,KAAI,CAAC,SACH,QAAO;AAET,QAAO;EACL;EACA,cAAc;EACd;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,8BAA8B,QAInC;AACT,KAAI,CAAC,OAAO,QACV,QAAO;AAET,KAAI,OAAO,cAAc,MAAM,CAC7B,QAAO,oBAAoB,OAAO,aAAa,MAAM;CAEvD,IAAI,iBAAiB;AACrB,KAAI,OAAO,aACT,kBAAiB,uCAAuC,OAAO,aAAa;AAE9E,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,eAAe,MAAM;EACtB,CACE,OAAO,QAAQ,CACf,KAAK,KAAK"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EmbeddedContextFile } from '../../bootstrap/types.js';
|
|
2
|
+
export declare const CONTEXT_FILE_ORDER: Map<string, number>;
|
|
3
|
+
export declare const DYNAMIC_CONTEXT_FILE_BASENAMES: Set<string>;
|
|
4
|
+
export declare const DEFAULT_HEARTBEAT_PROMPT_CONTEXT_BLOCK = "Default heartbeat prompt:\n`Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.`";
|
|
5
|
+
export declare function normalizeContextFilePath(pathValue: string): string;
|
|
6
|
+
export declare function getContextFileBasename(pathValue: string): string;
|
|
7
|
+
export declare function isDynamicContextFile(pathValue: string): boolean;
|
|
8
|
+
export declare function sanitizeContextFileContentForPrompt(content: string): string;
|
|
9
|
+
export declare function sortContextFilesForPrompt(contextFiles: EmbeddedContextFile[]): EmbeddedContextFile[];
|
|
10
|
+
export declare function buildProjectContextSection(params: {
|
|
11
|
+
files: EmbeddedContextFile[];
|
|
12
|
+
heading: string;
|
|
13
|
+
dynamic: boolean;
|
|
14
|
+
}): string[];
|
|
15
|
+
/** Whether HEARTBEAT.md is injected as dynamic context (vs behavior-only section). */
|
|
16
|
+
export declare function isHeartbeatContextFile(pathValue: string): boolean;
|