@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
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { PACKAGE_VERSION, init_package_version } from "../../package-version.js";
|
|
2
|
+
import { isCronSessionKey, isSubagentSessionKey } from "../../routing/session-key-utils.js";
|
|
3
|
+
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
|
|
4
|
+
import { normalizePromptSection } from "./cache-boundary.js";
|
|
5
|
+
import { listChannelPlugins } from "../../channels/plugins/registry.js";
|
|
6
|
+
//#region src/agent/prompt/system-prompt-params.ts
|
|
7
|
+
init_package_version();
|
|
8
|
+
init_session_key();
|
|
9
|
+
function resolvePromptMode(sessionKey) {
|
|
10
|
+
if (!sessionKey) return "full";
|
|
11
|
+
if (isSubagentSessionKey(sessionKey) || isCronSessionKey(sessionKey)) return "minimal";
|
|
12
|
+
return "full";
|
|
13
|
+
}
|
|
14
|
+
function resolveRuntimeChannel(sessionKey) {
|
|
15
|
+
if (!sessionKey) return;
|
|
16
|
+
return parseSessionKey(sessionKey)?.source;
|
|
17
|
+
}
|
|
18
|
+
function resolveDeliverableChannels(config) {
|
|
19
|
+
const channels = new Set(["webchat", "cli"]);
|
|
20
|
+
const configured = config.channels;
|
|
21
|
+
if (configured) {
|
|
22
|
+
for (const [id, section] of Object.entries(configured)) if (section?.enabled !== false) channels.add(id);
|
|
23
|
+
}
|
|
24
|
+
for (const plugin of listChannelPlugins()) {
|
|
25
|
+
const id = plugin.id;
|
|
26
|
+
const section = configured?.[id];
|
|
27
|
+
if (section?.enabled !== false && section !== void 0) channels.add(id);
|
|
28
|
+
}
|
|
29
|
+
return [...channels].sort();
|
|
30
|
+
}
|
|
31
|
+
function normalizeProviderPromptBlock(value) {
|
|
32
|
+
if (typeof value !== "string") return;
|
|
33
|
+
return normalizePromptSection(value) || void 0;
|
|
34
|
+
}
|
|
35
|
+
function buildOverridablePromptSection(params) {
|
|
36
|
+
const override = normalizeProviderPromptBlock(params.override);
|
|
37
|
+
if (override) return override;
|
|
38
|
+
return params.fallback;
|
|
39
|
+
}
|
|
40
|
+
function resolveSystemPromptBuildParams(config, params) {
|
|
41
|
+
const sessionKey = params.sessionKey;
|
|
42
|
+
const channel = resolveRuntimeChannel(sessionKey);
|
|
43
|
+
return {
|
|
44
|
+
workspaceDir: params.workspaceDir,
|
|
45
|
+
sessionKey,
|
|
46
|
+
promptMode: params.promptMode ?? resolvePromptMode(sessionKey),
|
|
47
|
+
toolNames: params.toolNames,
|
|
48
|
+
toolSummaries: params.toolSummaries,
|
|
49
|
+
runtimeInfo: {
|
|
50
|
+
version: PACKAGE_VERSION,
|
|
51
|
+
model: params.modelRef,
|
|
52
|
+
channel,
|
|
53
|
+
agentId: params.agentId,
|
|
54
|
+
thinkingLevel: params.thinkingLevel
|
|
55
|
+
},
|
|
56
|
+
userTimezone: params.userTimezone,
|
|
57
|
+
channels: resolveDeliverableChannels(config),
|
|
58
|
+
memoryCitationsMode: params.memoryCitationsMode,
|
|
59
|
+
includeMemorySection: params.includeMemorySection,
|
|
60
|
+
heartbeatEnabled: params.heartbeatEnabled,
|
|
61
|
+
heartbeatPrompt: params.heartbeatPrompt,
|
|
62
|
+
externalMemoryInstructions: params.externalMemoryInstructions,
|
|
63
|
+
ttsSystemHint: params.ttsSystemHint,
|
|
64
|
+
extraSystemPrompt: params.extraSystemPrompt,
|
|
65
|
+
silentReplyPromptMode: params.silentReplyPromptMode,
|
|
66
|
+
promptContribution: params.promptContribution,
|
|
67
|
+
includeProblemSolving: true,
|
|
68
|
+
includeToneSection: true
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export { buildOverridablePromptSection, normalizeProviderPromptBlock, resolveDeliverableChannels, resolvePromptMode, resolveRuntimeChannel, resolveSystemPromptBuildParams };
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=system-prompt-params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-prompt-params.js","names":[],"sources":["../../../../src/agent/prompt/system-prompt-params.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { listChannelPlugins } from '../../channels/plugins/registry.js';\nimport { PACKAGE_VERSION } from '../../package-version.js';\nimport { isCronSessionKey, isSubagentSessionKey, parseSessionKey } from '../../routing/session-key.js';\nimport type { ProviderSystemPromptContribution } from './contribution.js';\nimport { normalizePromptSection } from './cache-boundary.js';\nimport type { MemoryCitationsMode, PromptMode, SilentReplyPromptMode } from './types.js';\n\nexport type { RuntimeInfoInput } from './sections/workspace-runtime.js';\n\nexport function resolvePromptMode(sessionKey?: string): PromptMode {\n if (!sessionKey) {\n return 'full';\n }\n if (isSubagentSessionKey(sessionKey) || isCronSessionKey(sessionKey)) {\n return 'minimal';\n }\n return 'full';\n}\n\nexport function resolveRuntimeChannel(sessionKey?: string): string | undefined {\n if (!sessionKey) {\n return undefined;\n }\n const parsed = parseSessionKey(sessionKey);\n return parsed?.source;\n}\n\nexport function resolveDeliverableChannels(config: Config): string[] {\n const channels = new Set<string>(['webchat', 'cli']);\n const configured = config.channels as Record<string, { enabled?: boolean }> | undefined;\n if (configured) {\n for (const [id, section] of Object.entries(configured)) {\n if (section?.enabled !== false) {\n channels.add(id);\n }\n }\n }\n for (const plugin of listChannelPlugins()) {\n const id = plugin.id;\n const section = configured?.[id];\n if (section?.enabled !== false && section !== undefined) {\n channels.add(id);\n }\n }\n return [...channels].sort();\n}\n\nexport function normalizeProviderPromptBlock(value?: string): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n const normalized = normalizePromptSection(value);\n return normalized || undefined;\n}\n\nexport function buildOverridablePromptSection(params: {\n override?: string;\n fallback: string;\n}): string {\n const override = normalizeProviderPromptBlock(params.override);\n if (override) {\n return override;\n }\n return params.fallback;\n}\n\nexport interface SystemPromptBuildParams {\n workspaceDir: string;\n sessionKey?: string;\n promptMode?: PromptMode;\n toolNames?: string[];\n toolSummaries?: Record<string, string>;\n runtimeInfo?: import('./sections/workspace-runtime.js').RuntimeInfoInput;\n userTimezone?: string;\n channels?: string[];\n memoryCitationsMode?: MemoryCitationsMode;\n includeMemorySection?: boolean;\n heartbeatEnabled?: boolean;\n heartbeatPrompt?: string;\n externalMemoryInstructions?: string;\n ttsSystemHint?: string;\n extraSystemPrompt?: string;\n silentReplyPromptMode?: SilentReplyPromptMode;\n promptContribution?: ProviderSystemPromptContribution;\n includeProblemSolving?: boolean;\n includeToneSection?: boolean;\n}\n\nexport function resolveSystemPromptBuildParams(\n config: Config,\n params: {\n workspaceDir: string;\n sessionKey?: string;\n toolNames?: string[];\n toolSummaries?: Record<string, string>;\n userTimezone?: string;\n externalMemoryInstructions?: string;\n heartbeatEnabled?: boolean;\n heartbeatPrompt?: string;\n ttsSystemHint?: string;\n extraSystemPrompt?: string;\n modelRef?: string;\n agentId?: string;\n thinkingLevel?: string;\n promptMode?: PromptMode;\n silentReplyPromptMode?: SilentReplyPromptMode;\n promptContribution?: ProviderSystemPromptContribution;\n memoryCitationsMode?: MemoryCitationsMode;\n includeMemorySection?: boolean;\n },\n): SystemPromptBuildParams {\n const sessionKey = params.sessionKey;\n const channel = resolveRuntimeChannel(sessionKey);\n return {\n workspaceDir: params.workspaceDir,\n sessionKey,\n promptMode: params.promptMode ?? resolvePromptMode(sessionKey),\n toolNames: params.toolNames,\n toolSummaries: params.toolSummaries,\n runtimeInfo: {\n version: PACKAGE_VERSION,\n model: params.modelRef,\n channel,\n agentId: params.agentId,\n thinkingLevel: params.thinkingLevel,\n },\n userTimezone: params.userTimezone,\n channels: resolveDeliverableChannels(config),\n memoryCitationsMode: params.memoryCitationsMode,\n includeMemorySection: params.includeMemorySection,\n heartbeatEnabled: params.heartbeatEnabled,\n heartbeatPrompt: params.heartbeatPrompt,\n externalMemoryInstructions: params.externalMemoryInstructions,\n ttsSystemHint: params.ttsSystemHint,\n extraSystemPrompt: params.extraSystemPrompt,\n silentReplyPromptMode: params.silentReplyPromptMode,\n promptContribution: params.promptContribution,\n includeProblemSolving: true,\n includeToneSection: true,\n };\n}\n"],"mappings":";;;;;;sBAE2D;kBAC4C;AAOvG,SAAgB,kBAAkB,YAAiC;AACjE,KAAI,CAAC,WACH,QAAO;AAET,KAAI,qBAAqB,WAAW,IAAI,iBAAiB,WAAW,CAClE,QAAO;AAET,QAAO;;AAGT,SAAgB,sBAAsB,YAAyC;AAC7E,KAAI,CAAC,WACH;AAGF,QADe,gBAAgB,WAClB,EAAE;;AAGjB,SAAgB,2BAA2B,QAA0B;CACnE,MAAM,WAAW,IAAI,IAAY,CAAC,WAAW,MAAM,CAAC;CACpD,MAAM,aAAa,OAAO;AAC1B,KAAI;OACG,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,WAAW,CACpD,KAAI,SAAS,YAAY,MACvB,UAAS,IAAI,GAAG;;AAItB,MAAK,MAAM,UAAU,oBAAoB,EAAE;EACzC,MAAM,KAAK,OAAO;EAClB,MAAM,UAAU,aAAa;AAC7B,MAAI,SAAS,YAAY,SAAS,YAAY,KAAA,EAC5C,UAAS,IAAI,GAAG;;AAGpB,QAAO,CAAC,GAAG,SAAS,CAAC,MAAM;;AAG7B,SAAgB,6BAA6B,OAAoC;AAC/E,KAAI,OAAO,UAAU,SACnB;AAGF,QADmB,uBAAuB,MACzB,IAAI,KAAA;;AAGvB,SAAgB,8BAA8B,QAGnC;CACT,MAAM,WAAW,6BAA6B,OAAO,SAAS;AAC9D,KAAI,SACF,QAAO;AAET,QAAO,OAAO;;AAyBhB,SAAgB,+BACd,QACA,QAoByB;CACzB,MAAM,aAAa,OAAO;CAC1B,MAAM,UAAU,sBAAsB,WAAW;AACjD,QAAO;EACL,cAAc,OAAO;EACrB;EACA,YAAY,OAAO,cAAc,kBAAkB,WAAW;EAC9D,WAAW,OAAO;EAClB,eAAe,OAAO;EACtB,aAAa;GACX,SAAS;GACT,OAAO,OAAO;GACd;GACA,SAAS,OAAO;GAChB,eAAe,OAAO;GACvB;EACD,cAAc,OAAO;EACrB,UAAU,2BAA2B,OAAO;EAC5C,qBAAqB,OAAO;EAC5B,sBAAsB,OAAO;EAC7B,kBAAkB,OAAO;EACzB,iBAAiB,OAAO;EACxB,4BAA4B,OAAO;EACnC,eAAe,OAAO;EACtB,mBAAmB,OAAO;EAC1B,uBAAuB,OAAO;EAC9B,oBAAoB,OAAO;EAC3B,uBAAuB;EACvB,oBAAoB;EACrB"}
|
|
@@ -6,29 +6,40 @@
|
|
|
6
6
|
* not to manually reread startup files.
|
|
7
7
|
*/
|
|
8
8
|
import type { EmbeddedContextFile } from '../bootstrap/types.js';
|
|
9
|
-
import type {
|
|
10
|
-
|
|
9
|
+
import type { ProviderSystemPromptContribution } from './contribution.js';
|
|
10
|
+
import { type RuntimeInfoInput } from './sections/workspace-runtime.js';
|
|
11
|
+
import type { MemoryCitationsMode, PromptMode, SilentReplyPromptMode } from './types.js';
|
|
12
|
+
export type { MemoryCitationsMode } from './types.js';
|
|
13
|
+
export { getContextFileBasename, isDynamicContextFile, sortContextFilesForPrompt, } from './sections/project-context.js';
|
|
11
14
|
export interface SystemPromptOptions {
|
|
12
|
-
/** Bootstrap context files from profile Markdown (Project Context). */
|
|
13
15
|
contextFiles?: EmbeddedContextFile[];
|
|
14
16
|
promptMode?: PromptMode;
|
|
15
17
|
heartbeatEnabled?: boolean;
|
|
16
18
|
heartbeatPrompt?: string;
|
|
19
|
+
/** Registered tool names for Tooling section and memory/skills gating. */
|
|
20
|
+
toolNames?: string[];
|
|
21
|
+
toolSummaries?: Record<string, string>;
|
|
22
|
+
/** @deprecated Prefer toolNames — kept for skill-section gating compatibility. */
|
|
17
23
|
availableTools?: string[];
|
|
18
24
|
memoryCitationsMode?: MemoryCitationsMode;
|
|
25
|
+
includeMemorySection?: boolean;
|
|
19
26
|
userTimezone?: string;
|
|
20
|
-
runtime?:
|
|
21
|
-
version?: string;
|
|
22
|
-
model?: string;
|
|
23
|
-
channel?: string;
|
|
24
|
-
};
|
|
27
|
+
runtime?: RuntimeInfoInput;
|
|
25
28
|
channels?: string[];
|
|
26
29
|
externalMemoryInstructions?: string;
|
|
27
30
|
ttsSystemHint?: string;
|
|
31
|
+
extraSystemPrompt?: string;
|
|
32
|
+
silentReplyPromptMode?: SilentReplyPromptMode;
|
|
33
|
+
promptContribution?: ProviderSystemPromptContribution;
|
|
34
|
+
includeProblemSolving?: boolean;
|
|
35
|
+
includeToneSection?: boolean;
|
|
28
36
|
}
|
|
29
37
|
/**
|
|
30
38
|
* Build system prompt with bootstrap Project Context integration.
|
|
31
39
|
*/
|
|
32
|
-
export declare function buildSystemPrompt(workspaceDir: string, options
|
|
33
|
-
/**
|
|
34
|
-
export declare function
|
|
40
|
+
export declare function buildSystemPrompt(workspaceDir: string, options?: SystemPromptOptions): string;
|
|
41
|
+
/** Split a built prompt at the cache boundary (for tests and provider adapters). */
|
|
42
|
+
export declare function splitBuiltSystemPrompt(text: string): {
|
|
43
|
+
stablePrefix: string;
|
|
44
|
+
dynamicSuffix: string;
|
|
45
|
+
};
|
|
@@ -1,223 +1,109 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { PROMPT_CACHE_BOUNDARY, splitPromptCacheBoundary } from "./cache-boundary.js";
|
|
2
|
+
import { buildAestheticSection, buildExecutionBiasSection, buildProblemSolvingSection, buildSafetySection, buildToolCallStyleSection } from "./sections/behavior.js";
|
|
3
|
+
import { buildExternalMemorySection, buildMemorySection, buildSkillsSection } from "./sections/memory-skills.js";
|
|
4
|
+
import { buildHeartbeatBehaviorSection, buildMessagingSection, buildOutputDirectivesSection, buildSilentRepliesSection, buildTimeSection } from "./sections/messaging-runtime.js";
|
|
5
|
+
import { buildProjectContextSection, getContextFileBasename, isDynamicContextFile, sortContextFilesForPrompt } from "./sections/project-context.js";
|
|
6
|
+
import { buildToolingSection, hasSkillsTools } from "./sections/tooling.js";
|
|
7
|
+
import { buildRuntimeSection, buildWorkspaceFilesIntroSection, buildWorkspaceSection } from "./sections/workspace-runtime.js";
|
|
8
|
+
import { buildOverridablePromptSection } from "./system-prompt-params.js";
|
|
3
9
|
//#region src/agent/prompt/system-prompt.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
["soul.md", 20],
|
|
7
|
-
["identity.md", 30],
|
|
8
|
-
["user.md", 40],
|
|
9
|
-
["tools.md", 50],
|
|
10
|
-
["memory.md", 70]
|
|
11
|
-
]);
|
|
12
|
-
const DYNAMIC_CONTEXT_FILE_BASENAMES = new Set(["heartbeat.md"]);
|
|
13
|
-
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.`";
|
|
14
|
-
function normalizeContextFilePath(pathValue) {
|
|
15
|
-
return pathValue.trim().replace(/\\/g, "/");
|
|
16
|
-
}
|
|
17
|
-
function getContextFileBasename(pathValue) {
|
|
18
|
-
const normalizedPath = normalizeContextFilePath(pathValue);
|
|
19
|
-
return (normalizedPath.split("/").pop() ?? normalizedPath).toLowerCase();
|
|
20
|
-
}
|
|
21
|
-
function isDynamicContextFile(pathValue) {
|
|
22
|
-
return DYNAMIC_CONTEXT_FILE_BASENAMES.has(getContextFileBasename(pathValue));
|
|
23
|
-
}
|
|
24
|
-
function sanitizeContextFileContentForPrompt(content) {
|
|
25
|
-
return content.replaceAll(DEFAULT_HEARTBEAT_PROMPT_CONTEXT_BLOCK, "").replace(/\n{3,}/g, "\n\n");
|
|
26
|
-
}
|
|
27
|
-
function sortContextFilesForPrompt(contextFiles) {
|
|
28
|
-
return [...contextFiles].sort((a, b) => {
|
|
29
|
-
const aBase = getContextFileBasename(a.path);
|
|
30
|
-
const bBase = getContextFileBasename(b.path);
|
|
31
|
-
const aOrder = CONTEXT_FILE_ORDER.get(aBase) ?? Number.MAX_SAFE_INTEGER;
|
|
32
|
-
const bOrder = CONTEXT_FILE_ORDER.get(bBase) ?? Number.MAX_SAFE_INTEGER;
|
|
33
|
-
if (aOrder !== bOrder) return aOrder - bOrder;
|
|
34
|
-
if (aBase !== bBase) return aBase.localeCompare(bBase);
|
|
35
|
-
return normalizeContextFilePath(a.path).localeCompare(normalizeContextFilePath(b.path));
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
function buildProjectContextSection(params) {
|
|
39
|
-
if (params.files.length === 0) return [];
|
|
40
|
-
const lines = [params.heading, ""];
|
|
41
|
-
if (params.dynamic) lines.push("The following frequently-changing project context files are kept below the cache boundary when possible:", "");
|
|
42
|
-
else {
|
|
43
|
-
const hasSoulFile = params.files.some((file) => getContextFileBasename(file.path) === "soul.md");
|
|
44
|
-
lines.push("The following project context files have been loaded:");
|
|
45
|
-
if (hasSoulFile) lines.push("If SOUL.md is present, embody its persona and tone. Avoid stiff, generic replies; follow its guidance unless higher-priority instructions override it.");
|
|
46
|
-
lines.push("");
|
|
47
|
-
}
|
|
48
|
-
for (const file of params.files) lines.push(`## ${file.path}`, "", sanitizeContextFileContentForPrompt(file.content), "");
|
|
49
|
-
return lines;
|
|
50
|
-
}
|
|
51
|
-
function buildMemorySection(citationsMode = "on", hasProfileMemory = false) {
|
|
52
|
-
if (!hasProfileMemory) return "";
|
|
53
|
-
return `## Memory Recall
|
|
54
|
-
|
|
55
|
-
${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."}
|
|
56
|
-
|
|
57
|
-
Startup profile files (SOUL, USER, MEMORY, etc.) are already in Project Context above. Do not re-read them unless the user asks or you need lines beyond what was injected.
|
|
58
|
-
|
|
59
|
-
Before answering anything about prior work, decisions, dates, people, preferences, or todos:
|
|
60
|
-
1. Run \`memory_search\` on profile MEMORY.md and workspace \`memory/*.md\`
|
|
61
|
-
2. For **other chat sessions** / cross-session history, use \`session_search\` with keywords (or omit \`query\` to list recent sessions)
|
|
62
|
-
3. Use \`memory_get\` to pull only the needed lines from files
|
|
63
|
-
4. For structured curated notes under agent home \`memories/\`, use \`curated_memory\`
|
|
64
|
-
5. If low confidence after search, say you checked
|
|
65
|
-
|
|
66
|
-
### Memory Files
|
|
67
|
-
|
|
68
|
-
- **Daily notes:** \`memory/YYYY-MM-DD.md\` — raw logs (runtime may preload recent days on /new or /reset)
|
|
69
|
-
- **Long-term:** profile \`MEMORY.md\` — curated memories in Project Context when present
|
|
70
|
-
- **Curated store:** agent home \`memories/MEMORY.md\` and \`memories/USER.md\` — use \`curated_memory\` for live read/write
|
|
71
|
-
|
|
72
|
-
### Writing to Memory
|
|
73
|
-
|
|
74
|
-
- **Declarative vs procedural:** Save facts and preferences via workspace memory files and/or \`curated_memory\`. Save reusable task playbooks with \`skill_manage\` as skills.
|
|
75
|
-
- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE
|
|
76
|
-
- When someone says "remember this" → update \`memory/YYYY-MM-DD.md\` or relevant file
|
|
77
|
-
- **Text > Brain**
|
|
78
|
-
`;
|
|
79
|
-
}
|
|
80
|
-
function buildSkillsSection(availableTools = []) {
|
|
81
|
-
if (availableTools.length === 0) return "";
|
|
82
|
-
return `## Skills
|
|
83
|
-
|
|
84
|
-
When a solution already exists, do not reinvent the wheel.
|
|
85
|
-
|
|
86
|
-
**How to use:**
|
|
87
|
-
1. Skim <available_skills> — is anything clearly relevant?
|
|
88
|
-
2. Only one match? → Confirm with skills_list, then load the full text with skill_view(name) and follow it.
|
|
89
|
-
3. Need sub-documents or scripts? → skill_view(name, "references/…"), etc.
|
|
90
|
-
4. No match? → Solve it yourself; do not force-fit a skill.
|
|
91
|
-
|
|
92
|
-
**Division of labor with memory:** Skills = **procedural** workflows; memory / \`curated_memory\` = **declarative** facts and preferences.
|
|
93
|
-
`;
|
|
94
|
-
}
|
|
95
|
-
function buildSafetySection() {
|
|
96
|
-
return `## Safety
|
|
97
|
-
|
|
98
|
-
- 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.
|
|
99
|
-
- Prioritize safety and human oversight over completion; if instructions conflict, pause and ask; comply with stop/pause/audit requests and never bypass safeguards.
|
|
100
|
-
- 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.`;
|
|
101
|
-
}
|
|
102
|
-
function buildProblemSolvingSection() {
|
|
103
|
-
return `## Problem Solving
|
|
104
|
-
|
|
105
|
-
**Simple tasks** (< 5 minutes or a single-file change): Do them directly; run a quick verification after changes.
|
|
106
|
-
|
|
107
|
-
**Complex tasks** (multiple files or design decisions): Use an iterative flow — Plan → Build → Verify → Fix.
|
|
108
|
-
|
|
109
|
-
**Core principle: Match the complexity; reject ritual for its own sake. Verification matters, but do not verify just to tick a box.**`;
|
|
110
|
-
}
|
|
111
|
-
function buildAestheticSection() {
|
|
112
|
-
return `## Tone & Style
|
|
113
|
-
|
|
114
|
-
**Default voice:** Direct, concise, concrete.
|
|
115
|
-
|
|
116
|
-
**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above.`;
|
|
117
|
-
}
|
|
118
|
-
function buildHeartbeatBehaviorSection(params) {
|
|
119
|
-
if (!params.enabled) return "";
|
|
120
|
-
if (params.customPrompt?.trim()) return `## Heartbeats\n\n${params.customPrompt.trim()}\n`;
|
|
121
|
-
let quietHoursNote = "";
|
|
122
|
-
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.`;
|
|
123
|
-
return `## Heartbeats
|
|
124
|
-
|
|
125
|
-
If the current user message is a heartbeat poll and nothing needs attention, reply exactly: HEARTBEAT_OK
|
|
126
|
-
|
|
127
|
-
If something needs attention, do NOT include "HEARTBEAT_OK"; reply with the alert text instead.${quietHoursNote}
|
|
128
|
-
`;
|
|
129
|
-
}
|
|
130
|
-
function buildMessagingSection(channels = [], isMinimal = false) {
|
|
131
|
-
if (isMinimal || channels.length === 0) return "";
|
|
132
|
-
return `## Messaging
|
|
133
|
-
|
|
134
|
-
- Reply in current session → automatically routes to the source channel (${channels.join(", ")})
|
|
135
|
-
- Use \`message\` for proactive sends + channel actions
|
|
136
|
-
- If you use \`message\` to deliver your user-visible reply, respond with ONLY: NO_REPLY (avoid duplicate replies)
|
|
137
|
-
`;
|
|
138
|
-
}
|
|
139
|
-
function buildTimeSection(timezone) {
|
|
140
|
-
if (!timezone) return "";
|
|
141
|
-
return `## Current Date & Time
|
|
142
|
-
|
|
143
|
-
Time zone: ${timezone}
|
|
144
|
-
|
|
145
|
-
If you need the current date/time/day-of-week, use the \`session_status\` tool or the inbound message timestamp envelope (when present).
|
|
146
|
-
`;
|
|
147
|
-
}
|
|
148
|
-
function buildRuntimeSection(runtime) {
|
|
149
|
-
if (!runtime) return "";
|
|
150
|
-
const parts = [];
|
|
151
|
-
if (runtime.version) parts.push(`v${runtime.version}`);
|
|
152
|
-
if (runtime.model) parts.push(`model=${runtime.model.split("/").pop()}`);
|
|
153
|
-
if (runtime.channel) parts.push(`ch=${runtime.channel}`);
|
|
154
|
-
return parts.length > 0 ? `[${parts.join(" | ")}]` : "";
|
|
155
|
-
}
|
|
156
|
-
function buildWorkingDirSection(workspaceDir) {
|
|
157
|
-
return `Working directory: ${workspaceDir}`;
|
|
158
|
-
}
|
|
159
|
-
function buildExternalMemorySection(text) {
|
|
160
|
-
const t = text?.trim();
|
|
161
|
-
if (!t) return "";
|
|
162
|
-
return `## External memory provider\n\n${t}`;
|
|
10
|
+
function joinSections(sections) {
|
|
11
|
+
return sections.filter((section) => Boolean(section?.trim())).join("\n\n");
|
|
163
12
|
}
|
|
164
13
|
/**
|
|
165
14
|
* Build system prompt with bootstrap Project Context integration.
|
|
166
15
|
*/
|
|
167
|
-
function buildSystemPrompt(workspaceDir, options) {
|
|
168
|
-
const { contextFiles = [], promptMode = "full", heartbeatEnabled = false, heartbeatPrompt, availableTools = [], memoryCitationsMode = "on", userTimezone, runtime, channels = [], externalMemoryInstructions, ttsSystemHint } = options;
|
|
16
|
+
function buildSystemPrompt(workspaceDir, options = {}) {
|
|
17
|
+
const { contextFiles = [], promptMode = "full", heartbeatEnabled = false, heartbeatPrompt, toolNames: toolNamesOption, toolSummaries, availableTools = [], memoryCitationsMode = "on", includeMemorySection, userTimezone, runtime, channels = [], externalMemoryInstructions, ttsSystemHint, extraSystemPrompt, silentReplyPromptMode = "generic", promptContribution, includeProblemSolving = true, includeToneSection = true } = options;
|
|
169
18
|
if (promptMode === "none") return "You are a personal AI assistant running inside xopc.";
|
|
170
19
|
const isMinimal = promptMode === "minimal";
|
|
20
|
+
const toolNames = toolNamesOption ?? availableTools;
|
|
21
|
+
const normalizedTools = new Set(toolNames.map((tool) => tool.toLowerCase()));
|
|
22
|
+
const sectionOverrides = promptContribution?.sectionOverrides ?? {};
|
|
171
23
|
const orderedContextFiles = sortContextFilesForPrompt(contextFiles.filter((file) => file.path.trim().length > 0));
|
|
172
24
|
const stableContextFiles = orderedContextFiles.filter((file) => !isDynamicContextFile(file.path));
|
|
173
25
|
const dynamicContextFiles = orderedContextFiles.filter((file) => isDynamicContextFile(file.path));
|
|
174
26
|
const hasProfileMemory = orderedContextFiles.some((file) => getContextFileBasename(file.path) === "memory.md");
|
|
175
|
-
const
|
|
27
|
+
const stableSections = [
|
|
176
28
|
"You are a personal AI assistant running inside xopc.",
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
29
|
+
buildToolingSection({
|
|
30
|
+
toolNames,
|
|
31
|
+
toolSummaries
|
|
32
|
+
}),
|
|
33
|
+
buildOverridablePromptSection({
|
|
34
|
+
override: sectionOverrides.tool_call_style,
|
|
35
|
+
fallback: buildToolCallStyleSection()
|
|
36
|
+
})
|
|
182
37
|
];
|
|
38
|
+
if (!isMinimal) stableSections.push(buildOverridablePromptSection({
|
|
39
|
+
override: sectionOverrides.execution_bias,
|
|
40
|
+
fallback: buildExecutionBiasSection()
|
|
41
|
+
}));
|
|
42
|
+
const providerStablePrefix = buildOverridablePromptSection({
|
|
43
|
+
override: promptContribution?.stablePrefix,
|
|
44
|
+
fallback: ""
|
|
45
|
+
});
|
|
46
|
+
if (providerStablePrefix) stableSections.push(providerStablePrefix);
|
|
47
|
+
stableSections.push(buildSafetySection());
|
|
48
|
+
if (hasSkillsTools(toolNames)) stableSections.push(buildSkillsSection(true));
|
|
183
49
|
if (!isMinimal) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
50
|
+
stableSections.push(buildMemorySection({
|
|
51
|
+
availableTools: normalizedTools,
|
|
52
|
+
citationsMode: memoryCitationsMode,
|
|
53
|
+
hasProfileMemory,
|
|
54
|
+
includeMemorySection
|
|
55
|
+
}), buildExternalMemorySection(externalMemoryInstructions));
|
|
56
|
+
if (includeProblemSolving) stableSections.push(buildProblemSolvingSection());
|
|
57
|
+
if (includeToneSection) stableSections.push(buildAestheticSection());
|
|
58
|
+
stableSections.push(buildTimeSection(userTimezone));
|
|
193
59
|
}
|
|
194
|
-
|
|
60
|
+
stableSections.push(buildWorkspaceSection(workspaceDir), buildWorkspaceFilesIntroSection());
|
|
61
|
+
if (!isMinimal) stableSections.push(buildOutputDirectivesSection(isMinimal));
|
|
62
|
+
stableSections.push(buildMessagingSection({
|
|
63
|
+
channels,
|
|
64
|
+
isMinimal,
|
|
65
|
+
hasSendMessage: normalizedTools.has("send_message")
|
|
66
|
+
}));
|
|
67
|
+
if (!isMinimal && ttsSystemHint?.trim()) stableSections.push(`## Voice (TTS)\n\n${ttsSystemHint.trim()}`);
|
|
68
|
+
stableSections.push(joinSections(buildProjectContextSection({
|
|
195
69
|
files: stableContextFiles,
|
|
196
70
|
heading: "# Project Context",
|
|
197
71
|
dynamic: false
|
|
72
|
+
})));
|
|
73
|
+
if (!isMinimal) stableSections.push(buildSilentRepliesSection({
|
|
74
|
+
isMinimal,
|
|
75
|
+
silentReplyPromptMode
|
|
198
76
|
}));
|
|
199
|
-
|
|
200
|
-
|
|
77
|
+
const dynamicSections = [];
|
|
78
|
+
dynamicSections.push(joinSections(buildProjectContextSection({
|
|
201
79
|
files: dynamicContextFiles,
|
|
202
80
|
heading: stableContextFiles.length > 0 ? "# Dynamic Project Context" : "# Project Context",
|
|
203
81
|
dynamic: true
|
|
204
|
-
}));
|
|
205
|
-
|
|
82
|
+
})));
|
|
83
|
+
if (extraSystemPrompt?.trim()) {
|
|
84
|
+
const contextHeader = isMinimal ? "## Subagent Context" : "## Group Chat Context";
|
|
85
|
+
dynamicSections.push(`${contextHeader}\n\n${extraSystemPrompt.trim()}`);
|
|
86
|
+
}
|
|
87
|
+
const providerDynamicSuffix = buildOverridablePromptSection({
|
|
88
|
+
override: promptContribution?.dynamicSuffix,
|
|
89
|
+
fallback: ""
|
|
90
|
+
});
|
|
91
|
+
if (providerDynamicSuffix) dynamicSections.push(providerDynamicSuffix);
|
|
92
|
+
dynamicSections.push(buildHeartbeatBehaviorSection({
|
|
206
93
|
enabled: heartbeatEnabled,
|
|
207
94
|
customPrompt: heartbeatPrompt,
|
|
208
95
|
userTimezone
|
|
209
|
-
}));
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (!
|
|
213
|
-
|
|
214
|
-
return sections.filter(Boolean).join("\n\n");
|
|
96
|
+
}), buildRuntimeSection(runtime));
|
|
97
|
+
const stablePrefix = joinSections(stableSections);
|
|
98
|
+
const dynamicSuffix = joinSections(dynamicSections);
|
|
99
|
+
if (!dynamicSuffix.trim()) return `${stablePrefix}\n\n${PROMPT_CACHE_BOUNDARY}`.trim();
|
|
100
|
+
return `${stablePrefix}\n\n${PROMPT_CACHE_BOUNDARY}\n\n${dynamicSuffix}`.trim();
|
|
215
101
|
}
|
|
216
|
-
/**
|
|
217
|
-
function
|
|
218
|
-
return
|
|
102
|
+
/** Split a built prompt at the cache boundary (for tests and provider adapters). */
|
|
103
|
+
function splitBuiltSystemPrompt(text) {
|
|
104
|
+
return splitPromptCacheBoundary(text);
|
|
219
105
|
}
|
|
220
106
|
//#endregion
|
|
221
|
-
export { buildSystemPrompt,
|
|
107
|
+
export { buildSystemPrompt, getContextFileBasename, isDynamicContextFile, sortContextFilesForPrompt, splitBuiltSystemPrompt };
|
|
222
108
|
|
|
223
109
|
//# sourceMappingURL=system-prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","names":[],"sources":["../../../../src/agent/prompt/system-prompt.ts"],"sourcesContent":["/**\n * System Prompt Builder — xopc-owned prompt with OpenClaw-style bootstrap injection.\n *\n * Profile Markdown under `agents/<id>/profile/` is injected as Project Context\n * (see `src/agent/bootstrap/`). Runtime owns loading; AGENTS.md instructs agents\n * not to manually reread startup files.\n */\n\nimport type { EmbeddedContextFile } from '../bootstrap/types.js';\nimport { DEFAULT_HEARTBEAT_FILENAME } from '../context/workspace.js';\nimport { PROMPT_CACHE_BOUNDARY } from './cache-boundary.js';\nimport type { PromptMode } from './types.js';\n\nexport type MemoryCitationsMode = 'on' | 'off' | 'source-only';\n\nconst CONTEXT_FILE_ORDER = new Map<string, number>([\n ['agents.md', 10],\n ['soul.md', 20],\n ['identity.md', 30],\n ['user.md', 40],\n ['tools.md', 50],\n ['memory.md', 70],\n]);\n\nconst DYNAMIC_CONTEXT_FILE_BASENAMES = new Set(['heartbeat.md']);\n\nconst DEFAULT_HEARTBEAT_PROMPT_CONTEXT_BLOCK =\n '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.`';\n\nfunction normalizeContextFilePath(pathValue: string): string {\n return pathValue.trim().replace(/\\\\/g, '/');\n}\n\nfunction getContextFileBasename(pathValue: string): string {\n const normalizedPath = normalizeContextFilePath(pathValue);\n return (normalizedPath.split('/').pop() ?? normalizedPath).toLowerCase();\n}\n\nfunction isDynamicContextFile(pathValue: string): boolean {\n return DYNAMIC_CONTEXT_FILE_BASENAMES.has(getContextFileBasename(pathValue));\n}\n\nfunction sanitizeContextFileContentForPrompt(content: string): string {\n return content.replaceAll(DEFAULT_HEARTBEAT_PROMPT_CONTEXT_BLOCK, '').replace(/\\n{3,}/g, '\\n\\n');\n}\n\nfunction sortContextFilesForPrompt(contextFiles: EmbeddedContextFile[]): EmbeddedContextFile[] {\n return [...contextFiles].sort((a, b) => {\n const aBase = getContextFileBasename(a.path);\n const bBase = getContextFileBasename(b.path);\n const aOrder = CONTEXT_FILE_ORDER.get(aBase) ?? Number.MAX_SAFE_INTEGER;\n const bOrder = CONTEXT_FILE_ORDER.get(bBase) ?? Number.MAX_SAFE_INTEGER;\n if (aOrder !== bOrder) {\n return aOrder - bOrder;\n }\n if (aBase !== bBase) {\n return aBase.localeCompare(bBase);\n }\n return normalizeContextFilePath(a.path).localeCompare(normalizeContextFilePath(b.path));\n });\n}\n\nfunction buildProjectContextSection(params: {\n files: EmbeddedContextFile[];\n heading: string;\n dynamic: boolean;\n}): string[] {\n if (params.files.length === 0) {\n return [];\n }\n const lines: string[] = [params.heading, ''];\n if (params.dynamic) {\n lines.push(\n 'The following frequently-changing project context files are kept below the cache boundary when possible:',\n '',\n );\n } else {\n const hasSoulFile = params.files.some((file) => getContextFileBasename(file.path) === 'soul.md');\n lines.push('The following project context files have been loaded:');\n if (hasSoulFile) {\n lines.push(\n 'If SOUL.md is present, embody its persona and tone. Avoid stiff, generic replies; follow its guidance unless higher-priority instructions override it.',\n );\n }\n lines.push('');\n }\n for (const file of params.files) {\n lines.push(`## ${file.path}`, '', sanitizeContextFileContentForPrompt(file.content), '');\n }\n return lines;\n}\n\nfunction buildMemorySection(\n citationsMode: MemoryCitationsMode = 'on',\n hasProfileMemory = false,\n): string {\n if (!hasProfileMemory) {\n return '';\n }\n\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 return `## Memory Recall\n\n${citationInstruction}\n\nStartup profile files (SOUL, USER, MEMORY, etc.) are already in Project Context above. Do not re-read them unless the user asks or you need lines beyond what was injected.\n\nBefore answering anything about prior work, decisions, dates, people, preferences, or todos:\n1. Run \\`memory_search\\` on profile MEMORY.md and workspace \\`memory/*.md\\`\n2. For **other chat sessions** / cross-session history, use \\`session_search\\` with keywords (or omit \\`query\\` to list recent sessions)\n3. Use \\`memory_get\\` to pull only the needed lines from files\n4. For structured curated notes under agent home \\`memories/\\`, use \\`curated_memory\\`\n5. If low confidence after search, say you checked\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`;\n}\n\nfunction buildSkillsSection(availableTools: string[] = []): string {\n if (availableTools.length === 0) {\n return '';\n }\n\n return `## Skills\n\nWhen a solution already exists, do not reinvent the wheel.\n\n**How to use:**\n1. Skim <available_skills> — is anything clearly relevant?\n2. Only one match? → Confirm with skills_list, then load the full text with skill_view(name) and follow it.\n3. Need sub-documents or scripts? → skill_view(name, \"references/…\"), etc.\n4. No match? → Solve it yourself; do not force-fit a skill.\n\n**Division of labor with memory:** Skills = **procedural** workflows; memory / \\`curated_memory\\` = **declarative** facts and preferences.\n`;\n}\n\nfunction buildSafetySection(): string {\n return `## Safety\n\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}\n\nfunction buildProblemSolvingSection(): string {\n return `## Problem Solving\n\n**Simple tasks** (< 5 minutes or a single-file change): Do them directly; run a quick verification after changes.\n\n**Complex tasks** (multiple files or design decisions): Use an iterative flow — Plan → Build → Verify → Fix.\n\n**Core principle: Match the complexity; reject ritual for its own sake. Verification matters, but do not verify just to tick a box.**`;\n}\n\nfunction buildAestheticSection(): string {\n return `## Tone & Style\n\n**Default voice:** Direct, concise, concrete.\n\n**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above.`;\n}\n\nfunction 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 }\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 `## Heartbeats\n\nIf the current user message is a heartbeat poll and nothing needs attention, reply exactly: HEARTBEAT_OK\n\nIf something needs attention, do NOT include \"HEARTBEAT_OK\"; reply with the alert text instead.${quietHoursNote}\n`;\n}\n\nfunction buildMessagingSection(channels: string[] = [], isMinimal: boolean = false): string {\n if (isMinimal || channels.length === 0) {\n return '';\n }\n const channelList = channels.join(', ');\n return `## Messaging\n\n- Reply in current session → automatically routes to the source channel (${channelList})\n- Use \\`message\\` for proactive sends + channel actions\n- If you use \\`message\\` to deliver your user-visible reply, respond with ONLY: NO_REPLY (avoid duplicate replies)\n`;\n}\n\nfunction buildTimeSection(timezone?: string): string {\n if (!timezone) {\n return '';\n }\n return `## Current Date & Time\n\nTime zone: ${timezone}\n\nIf you need the current date/time/day-of-week, use the \\`session_status\\` tool or the inbound message timestamp envelope (when present).\n`;\n}\n\nfunction buildRuntimeSection(runtime?: { version?: string; model?: string; channel?: string }): string {\n if (!runtime) {\n return '';\n }\n const parts: string[] = [];\n if (runtime.version) parts.push(`v${runtime.version}`);\n if (runtime.model) parts.push(`model=${runtime.model.split('/').pop()}`);\n if (runtime.channel) parts.push(`ch=${runtime.channel}`);\n return parts.length > 0 ? `[${parts.join(' | ')}]` : '';\n}\n\nfunction buildWorkingDirSection(workspaceDir: string): string {\n return `Working directory: ${workspaceDir}`;\n}\n\nfunction 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 interface SystemPromptOptions {\n /** Bootstrap context files from profile Markdown (Project Context). */\n contextFiles?: EmbeddedContextFile[];\n promptMode?: PromptMode;\n heartbeatEnabled?: boolean;\n heartbeatPrompt?: string;\n availableTools?: string[];\n memoryCitationsMode?: MemoryCitationsMode;\n userTimezone?: string;\n runtime?: {\n version?: string;\n model?: string;\n channel?: string;\n };\n channels?: string[];\n externalMemoryInstructions?: string;\n ttsSystemHint?: string;\n}\n\n/**\n * Build system prompt with bootstrap Project Context integration.\n */\nexport function buildSystemPrompt(workspaceDir: string, options: SystemPromptOptions): string {\n const {\n contextFiles = [],\n promptMode = 'full',\n heartbeatEnabled = false,\n heartbeatPrompt,\n availableTools = [],\n memoryCitationsMode = 'on',\n userTimezone,\n runtime,\n channels = [],\n externalMemoryInstructions,\n ttsSystemHint,\n } = options;\n\n if (promptMode === 'none') {\n return 'You are a personal AI assistant running inside xopc.';\n }\n\n const isMinimal = promptMode === 'minimal';\n const orderedContextFiles = sortContextFilesForPrompt(\n contextFiles.filter((file) => file.path.trim().length > 0),\n );\n const stableContextFiles = orderedContextFiles.filter((file) => !isDynamicContextFile(file.path));\n const dynamicContextFiles = orderedContextFiles.filter((file) => isDynamicContextFile(file.path));\n const hasProfileMemory = orderedContextFiles.some(\n (file) => getContextFileBasename(file.path) === 'memory.md',\n );\n\n const sections: string[] = [\n 'You are a personal AI assistant running inside xopc.',\n '',\n '## Workspace Files (injected)',\n '',\n 'Profile bootstrap files are injected below as Project Context. Do not manually reread them at session start unless the user asks or injected content is insufficient.',\n '',\n ];\n\n if (!isMinimal) {\n sections.push(buildTimeSection(userTimezone));\n sections.push(buildExternalMemorySection(externalMemoryInstructions));\n sections.push(buildMemorySection(memoryCitationsMode, hasProfileMemory));\n }\n\n sections.push(buildSkillsSection(availableTools));\n\n if (!isMinimal) {\n sections.push(buildSafetySection());\n sections.push(buildProblemSolvingSection());\n sections.push(buildAestheticSection());\n }\n\n sections.push(\n ...buildProjectContextSection({\n files: stableContextFiles,\n heading: '# Project Context',\n dynamic: false,\n }),\n );\n\n sections.push(PROMPT_CACHE_BOUNDARY);\n\n sections.push(\n ...buildProjectContextSection({\n files: dynamicContextFiles,\n heading: stableContextFiles.length > 0 ? '# Dynamic Project Context' : '# Project Context',\n dynamic: true,\n }),\n );\n\n sections.push(buildHeartbeatBehaviorSection({ enabled: heartbeatEnabled, customPrompt: heartbeatPrompt, userTimezone }));\n sections.push(buildWorkingDirSection(workspaceDir));\n sections.push(buildMessagingSection(channels, isMinimal));\n\n if (!isMinimal && ttsSystemHint?.trim()) {\n sections.push(`## Voice (TTS)\\n\\n${ttsSystemHint.trim()}`);\n }\n\n sections.push(buildRuntimeSection(runtime));\n\n return sections.filter(Boolean).join('\\n\\n');\n}\n\n/** Whether HEARTBEAT.md is injected as dynamic context (vs behavior-only section). */\nexport function isHeartbeatContextFile(pathValue: string): boolean {\n return getContextFileBasename(pathValue) === DEFAULT_HEARTBEAT_FILENAME.toLowerCase();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"system-prompt.js","names":[],"sources":["../../../../src/agent/prompt/system-prompt.ts"],"sourcesContent":["/**\n * System Prompt Builder — xopc-owned prompt with OpenClaw-style bootstrap injection.\n *\n * Profile Markdown under `agents/<id>/profile/` is injected as Project Context\n * (see `src/agent/bootstrap/`). Runtime owns loading; AGENTS.md instructs agents\n * not to manually reread startup files.\n */\n\nimport type { EmbeddedContextFile } from '../bootstrap/types.js';\nimport { PROMPT_CACHE_BOUNDARY, splitPromptCacheBoundary } from './cache-boundary.js';\nimport type { ProviderSystemPromptContribution } from './contribution.js';\nimport {\n buildAestheticSection,\n buildExecutionBiasSection,\n buildProblemSolvingSection,\n buildSafetySection,\n buildToolCallStyleSection,\n} from './sections/behavior.js';\nimport {\n buildExternalMemorySection,\n buildMemorySection,\n buildSkillsSection,\n} from './sections/memory-skills.js';\nimport {\n buildHeartbeatBehaviorSection,\n buildMessagingSection,\n buildOutputDirectivesSection,\n buildSilentRepliesSection,\n buildTimeSection,\n} from './sections/messaging-runtime.js';\nimport {\n buildProjectContextSection,\n getContextFileBasename,\n isDynamicContextFile,\n sortContextFilesForPrompt,\n} from './sections/project-context.js';\nimport { buildToolingSection, hasSkillsTools } from './sections/tooling.js';\nimport {\n buildRuntimeSection,\n buildWorkspaceFilesIntroSection,\n buildWorkspaceSection,\n type RuntimeInfoInput,\n} from './sections/workspace-runtime.js';\nimport { buildOverridablePromptSection } from './system-prompt-params.js';\nimport type { MemoryCitationsMode, PromptMode, SilentReplyPromptMode } from './types.js';\n\nexport type { MemoryCitationsMode } from './types.js';\nexport {\n getContextFileBasename,\n isDynamicContextFile,\n sortContextFilesForPrompt,\n} from './sections/project-context.js';\n\nexport interface SystemPromptOptions {\n contextFiles?: EmbeddedContextFile[];\n promptMode?: PromptMode;\n heartbeatEnabled?: boolean;\n heartbeatPrompt?: string;\n /** Registered tool names for Tooling section and memory/skills gating. */\n toolNames?: string[];\n toolSummaries?: Record<string, string>;\n /** @deprecated Prefer toolNames — kept for skill-section gating compatibility. */\n availableTools?: string[];\n memoryCitationsMode?: MemoryCitationsMode;\n includeMemorySection?: boolean;\n userTimezone?: string;\n runtime?: RuntimeInfoInput;\n channels?: string[];\n externalMemoryInstructions?: string;\n ttsSystemHint?: string;\n extraSystemPrompt?: string;\n silentReplyPromptMode?: SilentReplyPromptMode;\n promptContribution?: ProviderSystemPromptContribution;\n includeProblemSolving?: boolean;\n includeToneSection?: boolean;\n}\n\nfunction joinSections(sections: Array<string | undefined>): string {\n return sections.filter((section): section is string => Boolean(section?.trim())).join('\\n\\n');\n}\n\n/**\n * Build system prompt with bootstrap Project Context integration.\n */\nexport function buildSystemPrompt(workspaceDir: string, options: SystemPromptOptions = {}): string {\n const {\n contextFiles = [],\n promptMode = 'full',\n heartbeatEnabled = false,\n heartbeatPrompt,\n toolNames: toolNamesOption,\n toolSummaries,\n availableTools = [],\n memoryCitationsMode = 'on',\n includeMemorySection,\n userTimezone,\n runtime,\n channels = [],\n externalMemoryInstructions,\n ttsSystemHint,\n extraSystemPrompt,\n silentReplyPromptMode = 'generic',\n promptContribution,\n includeProblemSolving = true,\n includeToneSection = true,\n } = options;\n\n if (promptMode === 'none') {\n return 'You are a personal AI assistant running inside xopc.';\n }\n\n const isMinimal = promptMode === 'minimal';\n const toolNames = toolNamesOption ?? availableTools;\n const normalizedTools = new Set(toolNames.map((tool) => tool.toLowerCase()));\n const sectionOverrides = promptContribution?.sectionOverrides ?? {};\n\n const orderedContextFiles = sortContextFilesForPrompt(\n contextFiles.filter((file) => file.path.trim().length > 0),\n );\n const stableContextFiles = orderedContextFiles.filter((file) => !isDynamicContextFile(file.path));\n const dynamicContextFiles = orderedContextFiles.filter((file) => isDynamicContextFile(file.path));\n const hasProfileMemory = orderedContextFiles.some(\n (file) => getContextFileBasename(file.path) === 'memory.md',\n );\n\n const stableSections: string[] = [\n 'You are a personal AI assistant running inside xopc.',\n buildToolingSection({ toolNames, toolSummaries }),\n buildOverridablePromptSection({\n override: sectionOverrides.tool_call_style,\n fallback: buildToolCallStyleSection(),\n }),\n ];\n\n if (!isMinimal) {\n stableSections.push(\n buildOverridablePromptSection({\n override: sectionOverrides.execution_bias,\n fallback: buildExecutionBiasSection(),\n }),\n );\n }\n\n const providerStablePrefix = buildOverridablePromptSection({\n override: promptContribution?.stablePrefix,\n fallback: '',\n });\n if (providerStablePrefix) {\n stableSections.push(providerStablePrefix);\n }\n\n stableSections.push(buildSafetySection());\n\n if (hasSkillsTools(toolNames)) {\n stableSections.push(buildSkillsSection(true));\n }\n\n if (!isMinimal) {\n stableSections.push(\n buildMemorySection({\n availableTools: normalizedTools,\n citationsMode: memoryCitationsMode,\n hasProfileMemory,\n includeMemorySection,\n }),\n buildExternalMemorySection(externalMemoryInstructions),\n );\n if (includeProblemSolving) {\n stableSections.push(buildProblemSolvingSection());\n }\n if (includeToneSection) {\n stableSections.push(buildAestheticSection());\n }\n stableSections.push(buildTimeSection(userTimezone));\n }\n\n stableSections.push(\n buildWorkspaceSection(workspaceDir),\n buildWorkspaceFilesIntroSection(),\n );\n\n if (!isMinimal) {\n stableSections.push(buildOutputDirectivesSection(isMinimal));\n }\n\n stableSections.push(\n buildMessagingSection({\n channels,\n isMinimal,\n hasSendMessage: normalizedTools.has('send_message'),\n }),\n );\n\n if (!isMinimal && ttsSystemHint?.trim()) {\n stableSections.push(`## Voice (TTS)\\n\\n${ttsSystemHint.trim()}`);\n }\n\n stableSections.push(\n joinSections(\n buildProjectContextSection({\n files: stableContextFiles,\n heading: '# Project Context',\n dynamic: false,\n }),\n ),\n );\n\n if (!isMinimal) {\n stableSections.push(\n buildSilentRepliesSection({ isMinimal, silentReplyPromptMode }),\n );\n }\n\n const dynamicSections: string[] = [];\n\n dynamicSections.push(\n joinSections(\n buildProjectContextSection({\n files: dynamicContextFiles,\n heading: stableContextFiles.length > 0 ? '# Dynamic Project Context' : '# Project Context',\n dynamic: true,\n }),\n ),\n );\n\n if (extraSystemPrompt?.trim()) {\n const contextHeader = isMinimal ? '## Subagent Context' : '## Group Chat Context';\n dynamicSections.push(`${contextHeader}\\n\\n${extraSystemPrompt.trim()}`);\n }\n\n const providerDynamicSuffix = buildOverridablePromptSection({\n override: promptContribution?.dynamicSuffix,\n fallback: '',\n });\n if (providerDynamicSuffix) {\n dynamicSections.push(providerDynamicSuffix);\n }\n\n dynamicSections.push(\n buildHeartbeatBehaviorSection({\n enabled: heartbeatEnabled,\n customPrompt: heartbeatPrompt,\n userTimezone,\n }),\n buildRuntimeSection(runtime),\n );\n\n const stablePrefix = joinSections(stableSections);\n const dynamicSuffix = joinSections(dynamicSections);\n\n if (!dynamicSuffix.trim()) {\n return `${stablePrefix}\\n\\n${PROMPT_CACHE_BOUNDARY}`.trim();\n }\n\n return `${stablePrefix}\\n\\n${PROMPT_CACHE_BOUNDARY}\\n\\n${dynamicSuffix}`.trim();\n}\n\n/** Split a built prompt at the cache boundary (for tests and provider adapters). */\nexport function splitBuiltSystemPrompt(text: string) {\n return splitPromptCacheBoundary(text);\n}\n"],"mappings":";;;;;;;;;AA6EA,SAAS,aAAa,UAA6C;AACjE,QAAO,SAAS,QAAQ,YAA+B,QAAQ,SAAS,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO;;;;;AAM/F,SAAgB,kBAAkB,cAAsB,UAA+B,EAAE,EAAU;CACjG,MAAM,EACJ,eAAe,EAAE,EACjB,aAAa,QACb,mBAAmB,OACnB,iBACA,WAAW,iBACX,eACA,iBAAiB,EAAE,EACnB,sBAAsB,MACtB,sBACA,cACA,SACA,WAAW,EAAE,EACb,4BACA,eACA,mBACA,wBAAwB,WACxB,oBACA,wBAAwB,MACxB,qBAAqB,SACnB;AAEJ,KAAI,eAAe,OACjB,QAAO;CAGT,MAAM,YAAY,eAAe;CACjC,MAAM,YAAY,mBAAmB;CACrC,MAAM,kBAAkB,IAAI,IAAI,UAAU,KAAK,SAAS,KAAK,aAAa,CAAC,CAAC;CAC5E,MAAM,mBAAmB,oBAAoB,oBAAoB,EAAE;CAEnE,MAAM,sBAAsB,0BAC1B,aAAa,QAAQ,SAAS,KAAK,KAAK,MAAM,CAAC,SAAS,EAAE,CAC3D;CACD,MAAM,qBAAqB,oBAAoB,QAAQ,SAAS,CAAC,qBAAqB,KAAK,KAAK,CAAC;CACjG,MAAM,sBAAsB,oBAAoB,QAAQ,SAAS,qBAAqB,KAAK,KAAK,CAAC;CACjG,MAAM,mBAAmB,oBAAoB,MAC1C,SAAS,uBAAuB,KAAK,KAAK,KAAK,YACjD;CAED,MAAM,iBAA2B;EAC/B;EACA,oBAAoB;GAAE;GAAW;GAAe,CAAC;EACjD,8BAA8B;GAC5B,UAAU,iBAAiB;GAC3B,UAAU,2BAA2B;GACtC,CAAC;EACH;AAED,KAAI,CAAC,UACH,gBAAe,KACb,8BAA8B;EAC5B,UAAU,iBAAiB;EAC3B,UAAU,2BAA2B;EACtC,CAAC,CACH;CAGH,MAAM,uBAAuB,8BAA8B;EACzD,UAAU,oBAAoB;EAC9B,UAAU;EACX,CAAC;AACF,KAAI,qBACF,gBAAe,KAAK,qBAAqB;AAG3C,gBAAe,KAAK,oBAAoB,CAAC;AAEzC,KAAI,eAAe,UAAU,CAC3B,gBAAe,KAAK,mBAAmB,KAAK,CAAC;AAG/C,KAAI,CAAC,WAAW;AACd,iBAAe,KACb,mBAAmB;GACjB,gBAAgB;GAChB,eAAe;GACf;GACA;GACD,CAAC,EACF,2BAA2B,2BAA2B,CACvD;AACD,MAAI,sBACF,gBAAe,KAAK,4BAA4B,CAAC;AAEnD,MAAI,mBACF,gBAAe,KAAK,uBAAuB,CAAC;AAE9C,iBAAe,KAAK,iBAAiB,aAAa,CAAC;;AAGrD,gBAAe,KACb,sBAAsB,aAAa,EACnC,iCAAiC,CAClC;AAED,KAAI,CAAC,UACH,gBAAe,KAAK,6BAA6B,UAAU,CAAC;AAG9D,gBAAe,KACb,sBAAsB;EACpB;EACA;EACA,gBAAgB,gBAAgB,IAAI,eAAe;EACpD,CAAC,CACH;AAED,KAAI,CAAC,aAAa,eAAe,MAAM,CACrC,gBAAe,KAAK,qBAAqB,cAAc,MAAM,GAAG;AAGlE,gBAAe,KACb,aACE,2BAA2B;EACzB,OAAO;EACP,SAAS;EACT,SAAS;EACV,CAAC,CACH,CACF;AAED,KAAI,CAAC,UACH,gBAAe,KACb,0BAA0B;EAAE;EAAW;EAAuB,CAAC,CAChE;CAGH,MAAM,kBAA4B,EAAE;AAEpC,iBAAgB,KACd,aACE,2BAA2B;EACzB,OAAO;EACP,SAAS,mBAAmB,SAAS,IAAI,8BAA8B;EACvE,SAAS;EACV,CAAC,CACH,CACF;AAED,KAAI,mBAAmB,MAAM,EAAE;EAC7B,MAAM,gBAAgB,YAAY,wBAAwB;AAC1D,kBAAgB,KAAK,GAAG,cAAc,MAAM,kBAAkB,MAAM,GAAG;;CAGzE,MAAM,wBAAwB,8BAA8B;EAC1D,UAAU,oBAAoB;EAC9B,UAAU;EACX,CAAC;AACF,KAAI,sBACF,iBAAgB,KAAK,sBAAsB;AAG7C,iBAAgB,KACd,8BAA8B;EAC5B,SAAS;EACT,cAAc;EACd;EACD,CAAC,EACF,oBAAoB,QAAQ,CAC7B;CAED,MAAM,eAAe,aAAa,eAAe;CACjD,MAAM,gBAAgB,aAAa,gBAAgB;AAEnD,KAAI,CAAC,cAAc,MAAM,CACvB,QAAO,GAAG,aAAa,MAAM,wBAAwB,MAAM;AAG7D,QAAO,GAAG,aAAa,MAAM,sBAAsB,MAAM,gBAAgB,MAAM;;;AAIjF,SAAgB,uBAAuB,MAAc;AACnD,QAAO,yBAAyB,KAAK"}
|
|
@@ -6,3 +6,6 @@
|
|
|
6
6
|
* - "none": Just basic identity line, no sections
|
|
7
7
|
*/
|
|
8
8
|
export type PromptMode = 'full' | 'minimal' | 'none';
|
|
9
|
+
/** Controls the generic silent-reply section. Channel-aware callers can set "none". */
|
|
10
|
+
export type SilentReplyPromptMode = 'generic' | 'none';
|
|
11
|
+
export type MemoryCitationsMode = 'on' | 'off' | 'source-only';
|
|
@@ -1,30 +1,14 @@
|
|
|
1
1
|
import type { Config } from '../../config/schema.js';
|
|
2
|
+
import type { MediaRef } from '../../channels/attachments/inbound-persist.js';
|
|
2
3
|
import type { AgentInstanceGateway } from '../agent-instance-gateway.js';
|
|
3
4
|
import type { ModelManager } from '../models/index.js';
|
|
4
|
-
export type
|
|
5
|
-
|
|
6
|
-
mimeType?: string;
|
|
7
|
-
data?: string;
|
|
8
|
-
name?: string;
|
|
9
|
-
size?: number;
|
|
10
|
-
workspaceRelativePath?: string;
|
|
11
|
-
};
|
|
12
|
-
export type DirectMessagePart = {
|
|
13
|
-
type: 'text';
|
|
14
|
-
text: string;
|
|
15
|
-
} | {
|
|
16
|
-
type: 'image';
|
|
17
|
-
data: string;
|
|
18
|
-
mimeType: string;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Build user message parts (text + resolved images/files) for direct / webchat turns.
|
|
22
|
-
*/
|
|
5
|
+
export type { InboundAttachmentInput as DirectInboundWireAttachment } from '../../channels/attachments/inbound-persist.js';
|
|
6
|
+
export type { MediaRef as DirectInboundAttachment } from '../../channels/attachments/inbound-persist.js';
|
|
23
7
|
export declare function buildDirectUserMessageContent(opts: {
|
|
24
8
|
content: string;
|
|
25
|
-
attachments?:
|
|
9
|
+
attachments?: MediaRef[];
|
|
26
10
|
sessionKey?: string;
|
|
27
11
|
config: Config;
|
|
28
12
|
agentManager: AgentInstanceGateway;
|
|
29
13
|
modelManager: ModelManager;
|
|
30
|
-
}): Promise<
|
|
14
|
+
}): Promise<import("../inbound/attachment-pipeline.js").TranscriptUserMessage>;
|
|
@@ -1,73 +1,20 @@
|
|
|
1
1
|
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
2
|
-
import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.js";
|
|
3
|
-
import { extractProfileAgentId } from "../../config/agent-profile.js";
|
|
4
2
|
import { getDefaultModelSync, init_providers } from "../../providers/index.js";
|
|
5
|
-
import {
|
|
6
|
-
import { expandAtFileMentionsInPlainText } from "../context/expand-at-file-mentions.js";
|
|
7
|
-
import { resolveInboundImageContentParts } from "../image/inbound-image-handling.js";
|
|
3
|
+
import { buildTranscriptUserMessage } from "../inbound/attachment-pipeline.js";
|
|
8
4
|
//#region src/agent/service/build-direct-message-content.ts
|
|
9
5
|
init_schema();
|
|
10
6
|
init_providers();
|
|
11
|
-
init_agent_scope();
|
|
12
|
-
/**
|
|
13
|
-
* Build user message parts (text + resolved images/files) for direct / webchat turns.
|
|
14
|
-
*/
|
|
15
7
|
async function buildDirectUserMessageContent(opts) {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
messageContent.push({
|
|
27
|
-
type: "text",
|
|
28
|
-
text: textPart
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
if (!attachments?.length) return messageContent;
|
|
32
|
-
const modelRef = sk !== "" ? modelManager.getModelForSession(sk) : getAgentDefaultModelRef(config) ?? getDefaultModelSync(config);
|
|
33
|
-
const storageRoot = sk !== "" ? resolveAgentHomeDir(config, extractProfileAgentId(sk, config)) : resolveAgentHomeDir(config, resolveDefaultAgentId(config));
|
|
34
|
-
let i = 0;
|
|
35
|
-
while (i < attachments.length) {
|
|
36
|
-
const att = attachments[i];
|
|
37
|
-
if (att.type === "image" || att.type === "photo" || Boolean(att.mimeType?.startsWith("image/"))) {
|
|
38
|
-
const group = [];
|
|
39
|
-
while (i < attachments.length) {
|
|
40
|
-
const a = attachments[i];
|
|
41
|
-
if (!(a.type === "image" || a.type === "photo" || Boolean(a.mimeType?.startsWith("image/")))) break;
|
|
42
|
-
if (!a.data || a.data.length === 0) {
|
|
43
|
-
i += 1;
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
group.push({
|
|
47
|
-
data: a.data,
|
|
48
|
-
mimeType: a.mimeType || "image/png"
|
|
49
|
-
});
|
|
50
|
-
i += 1;
|
|
51
|
-
}
|
|
52
|
-
if (group.length > 0) {
|
|
53
|
-
const parts = await resolveInboundImageContentParts({
|
|
54
|
-
modelRef: modelRef || getDefaultModelSync(config),
|
|
55
|
-
cfg: config,
|
|
56
|
-
userTextForContext: content.trim() ? content : "",
|
|
57
|
-
images: group
|
|
58
|
-
});
|
|
59
|
-
messageContent.push(...parts);
|
|
60
|
-
}
|
|
61
|
-
} else {
|
|
62
|
-
const fileBlock = formatInboundFileTextBlock(att, storageRoot);
|
|
63
|
-
messageContent.push({
|
|
64
|
-
type: "text",
|
|
65
|
-
text: fileBlock
|
|
66
|
-
});
|
|
67
|
-
i += 1;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return messageContent;
|
|
8
|
+
const sk = opts.sessionKey ?? "";
|
|
9
|
+
const modelRef = sk !== "" ? opts.modelManager.getModelForSession(sk) : getAgentDefaultModelRef(opts.config) ?? getDefaultModelSync(opts.config);
|
|
10
|
+
return buildTranscriptUserMessage({
|
|
11
|
+
text: opts.content,
|
|
12
|
+
prepared: opts.attachments,
|
|
13
|
+
sessionKey: sk,
|
|
14
|
+
modelRef: modelRef || getDefaultModelSync(opts.config),
|
|
15
|
+
config: opts.config,
|
|
16
|
+
agentManager: opts.agentManager
|
|
17
|
+
});
|
|
71
18
|
}
|
|
72
19
|
//#endregion
|
|
73
20
|
export { buildDirectUserMessageContent };
|