@xopcai/xopc 0.0.29 → 0.0.31
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/extensions/telegram/src/adapters/config-surface.js +3 -1
- package/dist/extensions/telegram/src/adapters/config-surface.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/onboard-cli.js +23 -21
- package/dist/extensions/telegram/src/adapters/onboard-cli.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/setup-wizard.js +3 -4
- package/dist/extensions/telegram/src/adapters/setup-wizard.js.map +1 -1
- package/dist/extensions/telegram/src/config-schema.d.ts +0 -1
- package/dist/extensions/telegram/src/config-schema.js +17 -4
- package/dist/extensions/telegram/src/config-schema.js.map +1 -1
- package/dist/extensions/telegram/src/plugin.js +4 -17
- package/dist/extensions/telegram/src/plugin.js.map +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/gateway/static/root/assets/agents-3u63Fw2Y.js +216 -0
- package/dist/gateway/static/root/assets/agents-3u63Fw2Y.js.map +1 -0
- package/dist/gateway/static/root/assets/{apps-page-Bmq19MS-.js → apps-page-CWegY6Kp.js} +2 -2
- package/dist/gateway/static/root/assets/{apps-page-Bmq19MS-.js.map → apps-page-CWegY6Kp.js.map} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CiyeXcTK.js +9 -0
- package/dist/gateway/static/root/assets/channels-settings-CiyeXcTK.js.map +1 -0
- package/dist/gateway/static/root/assets/cron-api-_j_79Zf5.js +3 -0
- package/dist/gateway/static/root/assets/cron-api-_j_79Zf5.js.map +1 -0
- package/dist/gateway/static/root/assets/cron-page-S86YNTtI.js +2 -0
- package/dist/gateway/static/root/assets/cron-page-S86YNTtI.js.map +1 -0
- package/dist/gateway/static/root/assets/dist-D0jxbvuz.js +2 -0
- package/dist/gateway/static/root/assets/{dist--p2HQ2QF.js.map → dist-D0jxbvuz.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DwHCB_6T.js → extension-debug-page-DB630cW8.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-debug-page-DwHCB_6T.js.map → extension-debug-page-DB630cW8.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BsYwQIex.js → extension-page-CnoPUBul.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-page-BsYwQIex.js.map → extension-page-CnoPUBul.js.map} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-nsisEgjB.js → extension-settings-page-BsiOkvBe.js} +2 -2
- package/dist/gateway/static/root/assets/{extension-settings-page-nsisEgjB.js.map → extension-settings-page-BsiOkvBe.js.map} +1 -1
- package/dist/gateway/static/root/assets/{index-CR8zUHGR.js → index-DHLmAIQl.js} +63 -63
- package/dist/gateway/static/root/assets/{index-CR8zUHGR.js.map → index-DHLmAIQl.js.map} +1 -1
- package/dist/gateway/static/root/assets/index-DoPwy4aU.css +1 -0
- package/dist/gateway/static/root/assets/logs-page-Bndhenn2.js +2 -0
- package/dist/gateway/static/root/assets/logs-page-Bndhenn2.js.map +1 -0
- package/dist/gateway/static/root/assets/sessions-page-Q201-_lP.js +2 -0
- package/dist/gateway/static/root/assets/{sessions-page-Be5kIGl_.js.map → sessions-page-Q201-_lP.js.map} +1 -1
- package/dist/gateway/static/root/assets/settings-page-Cw75fpc6.js +2 -0
- package/dist/gateway/static/root/assets/settings-page-Cw75fpc6.js.map +1 -0
- package/dist/gateway/static/root/assets/skills-page-CVwEzD_J.js +3 -0
- package/dist/gateway/static/root/assets/skills-page-CVwEzD_J.js.map +1 -0
- package/dist/gateway/static/root/index.html +2 -2
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +5 -7
- package/dist/src/agent/agent-manager.js +21 -19
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/ipc/inbox.js +4 -2
- package/dist/src/agent/ipc/inbox.js.map +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +0 -2
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/system-prompt.d.ts +0 -2
- package/dist/src/agent/prompt/system-prompt.js +3 -17
- package/dist/src/agent/prompt/system-prompt.js.map +1 -1
- package/dist/src/agent/service/btw-query.d.ts +16 -0
- package/dist/src/agent/service/btw-query.js +88 -0
- package/dist/src/agent/service/btw-query.js.map +1 -0
- package/dist/src/agent/service/build-direct-message-content.d.ts +30 -0
- package/dist/src/agent/service/build-direct-message-content.js +75 -0
- package/dist/src/agent/service/build-direct-message-content.js.map +1 -0
- package/dist/src/agent/service/parse-outbound-session-key.d.ts +8 -0
- package/dist/src/agent/service/parse-outbound-session-key.js +41 -0
- package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -0
- package/dist/src/agent/service/process-direct-one-shot.d.ts +34 -0
- package/dist/src/agent/service/process-direct-one-shot.js +67 -0
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -0
- package/dist/src/agent/service/process-direct-streaming.js +12 -1
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +6 -0
- package/dist/src/agent/service/reconcile-dreaming-cron.js +70 -0
- package/dist/src/agent/service/reconcile-dreaming-cron.js.map +1 -0
- package/dist/src/agent/service/session-context-report.d.ts +19 -0
- package/dist/src/agent/service/session-context-report.js +47 -0
- package/dist/src/agent/service/session-context-report.js.map +1 -0
- package/dist/src/agent/service/webchat-tts.d.ts +28 -0
- package/dist/src/agent/service/webchat-tts.js +73 -0
- package/dist/src/agent/service/webchat-tts.js.map +1 -0
- package/dist/src/agent/service.d.ts +8 -12
- package/dist/src/agent/service.js +74 -379
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/skills/config.js +4 -3
- package/dist/src/agent/skills/config.js.map +1 -1
- package/dist/src/agent/skills/format-skills-prompt.d.ts +0 -2
- package/dist/src/agent/skills/format-skills-prompt.js +3 -24
- package/dist/src/agent/skills/format-skills-prompt.js.map +1 -1
- package/dist/src/agent/skills/hub-lock.js +4 -5
- package/dist/src/agent/skills/hub-lock.js.map +1 -1
- package/dist/src/agent/skills/index.js +9 -21
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/marketplace/adapter.types.d.ts +17 -0
- package/dist/src/agent/skills/marketplace/adapter.types.js +1 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.d.ts +2 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +292 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/ecosystem-client.d.ts +73 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/ecosystem-client.js +200 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/ecosystem-client.js.map +1 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/registry-client.d.ts +137 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/registry-client.js +217 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/registry-client.js.map +1 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/skillhub-fetch-cache.d.ts +12 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/skillhub-fetch-cache.js +90 -0
- package/dist/src/agent/skills/marketplace/adapters/skillhub/skillhub-fetch-cache.js.map +1 -0
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.d.ts +2 -0
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +35 -0
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js.map +1 -0
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +124 -0
- package/dist/src/agent/skills/{skills-store-client.js → marketplace/adapters/store/store-api-client.js} +4 -3
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -0
- package/dist/src/agent/skills/marketplace/resolve-adapter.d.ts +6 -0
- package/dist/src/agent/skills/marketplace/resolve-adapter.js +26 -0
- package/dist/src/agent/skills/marketplace/resolve-adapter.js.map +1 -0
- package/dist/src/agent/skills/parse-skill-metadata.d.ts +5 -0
- package/dist/src/agent/skills/parse-skill-metadata.js +27 -0
- package/dist/src/agent/skills/parse-skill-metadata.js.map +1 -0
- package/dist/src/agent/skills/skill-markdown-preview-from-raw.d.ts +6 -0
- package/dist/src/agent/skills/skill-markdown-preview-from-raw.js +64 -0
- package/dist/src/agent/skills/skill-markdown-preview-from-raw.js.map +1 -0
- package/dist/src/agent/skills/skill-view-path.d.ts +17 -1
- package/dist/src/agent/skills/skill-view-path.js +66 -3
- package/dist/src/agent/skills/skill-view-path.js.map +1 -1
- package/dist/src/agent/skills/skills-marketplace.d.ts +21 -0
- package/dist/src/agent/skills/skills-marketplace.js +18 -0
- package/dist/src/agent/skills/skills-marketplace.js.map +1 -0
- package/dist/src/agent/skills/test-framework.d.ts +0 -1
- package/dist/src/agent/skills/test-framework.js +2 -20
- package/dist/src/agent/skills/test-framework.js.map +1 -1
- package/dist/src/agent/skills/types.d.ts +12 -6
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +2 -2
- package/dist/src/auth/credentials.js +8 -6
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/profiles/store.js +5 -3
- package/dist/src/auth/profiles/store.js.map +1 -1
- package/dist/src/channels/manager.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +4 -4
- package/dist/src/channels/outbound/persist-store.js.map +1 -1
- package/dist/src/cli/commands/config.js +8 -6
- package/dist/src/cli/commands/config.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/channel-config.js +3 -4
- package/dist/src/cli/commands/doctor/checks/channel-config.js.map +1 -1
- package/dist/src/cli/commands/init.js +4 -2
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/config/loader.js +3 -1
- package/dist/src/config/loader.js.map +1 -1
- package/dist/src/config/models-json.js +4 -5
- package/dist/src/config/models-json.js.map +1 -1
- package/dist/src/config/schema.d.ts +12 -4
- package/dist/src/config/schema.js +31 -5
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/cron/persistence.d.ts +1 -3
- package/dist/src/cron/persistence.js +6 -17
- package/dist/src/cron/persistence.js.map +1 -1
- package/dist/src/cron/validation.js +1 -1
- package/dist/src/cron/validation.js.map +1 -1
- package/dist/src/extensions/activation-context.js +0 -1
- package/dist/src/extensions/activation-context.js.map +1 -1
- package/dist/src/extensions/lockfile.js +4 -2
- package/dist/src/extensions/lockfile.js.map +1 -1
- package/dist/src/gateway/auth.d.ts +0 -9
- package/dist/src/gateway/auth.js +1 -12
- package/dist/src/gateway/auth.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +4 -4
- package/dist/src/gateway/hono/lib/extension-store.js.map +1 -1
- package/dist/src/gateway/hono/routes/channels.js +5 -3
- package/dist/src/gateway/hono/routes/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +28 -3
- package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
- package/dist/src/gateway/hono/routes/config.js +23 -2
- package/dist/src/gateway/hono/routes/config.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +124 -2
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/sse.js +9 -2
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/index.js +2 -2
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.d.ts +37 -0
- package/dist/src/gateway/service/run-gateway-agent.js +163 -0
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -0
- package/dist/src/gateway/service/save-webchat-user-message.d.ts +9 -0
- package/dist/src/gateway/service/save-webchat-user-message.js +34 -0
- package/dist/src/gateway/service/save-webchat-user-message.js.map +1 -0
- package/dist/src/gateway/service/session-chat-ids.d.ts +9 -0
- package/dist/src/gateway/service/session-chat-ids.js +33 -0
- package/dist/src/gateway/service/session-chat-ids.js.map +1 -0
- package/dist/src/gateway/service/sse-hub.d.ts +10 -0
- package/dist/src/gateway/service/sse-hub.js +55 -0
- package/dist/src/gateway/service/sse-hub.js.map +1 -0
- package/dist/src/gateway/service/types.d.ts +9 -0
- package/dist/src/gateway/service/types.js +1 -0
- package/dist/src/gateway/service.d.ts +42 -33
- package/dist/src/gateway/service.js +92 -246
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/infra/update-lock.js +4 -2
- package/dist/src/infra/update-lock.js.map +1 -1
- package/dist/src/infra/update-startup.js +5 -14
- package/dist/src/infra/update-startup.js.map +1 -1
- package/dist/src/infra/write-file-atomic.d.ts +18 -0
- package/dist/src/infra/write-file-atomic.js +115 -0
- package/dist/src/infra/write-file-atomic.js.map +1 -0
- package/dist/src/session/abort-cutoff.d.ts +6 -0
- package/dist/src/session/abort-cutoff.js +10 -0
- package/dist/src/session/abort-cutoff.js.map +1 -0
- package/dist/src/session/compaction-checkpoints.d.ts +8 -0
- package/dist/src/session/compaction-checkpoints.js +21 -0
- package/dist/src/session/compaction-checkpoints.js.map +1 -0
- package/dist/src/session/config-store.js +4 -2
- package/dist/src/session/config-store.js.map +1 -1
- package/dist/src/session/index.d.ts +8 -1
- package/dist/src/session/index.js +7 -1
- package/dist/src/session/manager.d.ts +26 -1
- package/dist/src/session/manager.js +39 -2
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/patch-metadata.d.ts +12 -0
- package/dist/src/session/patch-metadata.js +23 -0
- package/dist/src/session/patch-metadata.js.map +1 -0
- package/dist/src/session/search-index.d.ts +2 -0
- package/dist/src/session/search-index.js +30 -2
- package/dist/src/session/search-index.js.map +1 -1
- package/dist/src/session/session-context-for-llm.d.ts +32 -0
- package/dist/src/session/session-context-for-llm.js +60 -0
- package/dist/src/session/session-context-for-llm.js.map +1 -0
- package/dist/src/session/store.d.ts +53 -2
- package/dist/src/session/store.js +427 -145
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/strip-webchat-early-save.d.ts +5 -0
- package/dist/src/session/strip-webchat-early-save.js +17 -0
- package/dist/src/session/strip-webchat-early-save.js.map +1 -0
- package/dist/src/session/transcript-format.d.ts +46 -0
- package/dist/src/session/transcript-format.js +88 -0
- package/dist/src/session/transcript-format.js.map +1 -0
- package/dist/src/session/types.d.ts +37 -0
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/utils/logger/log-store.js +4 -3
- package/dist/src/utils/logger/log-store.js.map +1 -1
- package/dist/src/voice/tts/merge-config.js +0 -1
- package/dist/src/voice/tts/merge-config.js.map +1 -1
- package/dist/src/voice/tts/service.js +1 -2
- package/dist/src/voice/tts/service.js.map +1 -1
- package/package.json +1 -1
- package/skills/business/company-values/SKILL-zh.md +80 -0
- package/skills/business/company-values/SKILL.md +80 -0
- package/skills/business/find-community/SKILL-zh.md +50 -0
- package/skills/business/find-community/SKILL.md +50 -0
- package/skills/business/first-customers/SKILL-zh.md +76 -0
- package/skills/business/first-customers/SKILL.md +76 -0
- package/skills/business/grow-sustainably/SKILL-zh.md +92 -0
- package/skills/business/grow-sustainably/SKILL.md +92 -0
- package/skills/business/marketing-plan/SKILL-zh.md +100 -0
- package/skills/business/marketing-plan/SKILL.md +100 -0
- package/skills/business/minimalist-review/SKILL-zh.md +82 -0
- package/skills/business/minimalist-review/SKILL.md +82 -0
- package/skills/business/mvp/SKILL-zh.md +81 -0
- package/skills/business/mvp/SKILL.md +81 -0
- package/skills/business/pricing/SKILL-zh.md +64 -0
- package/skills/business/pricing/SKILL.md +64 -0
- package/skills/business/processize/SKILL-zh.md +91 -0
- package/skills/business/processize/SKILL.md +91 -0
- package/skills/business/validate-idea/SKILL-zh.md +68 -0
- package/skills/business/validate-idea/SKILL.md +68 -0
- package/skills/{skill-creator → creative/algorithmic-art}/LICENSE.txt +1 -1
- package/skills/creative/algorithmic-art/SKILL-zh.md +405 -0
- package/skills/creative/algorithmic-art/SKILL.md +405 -0
- package/skills/creative/algorithmic-art/templates/generator_template.js +223 -0
- package/skills/creative/algorithmic-art/templates/viewer.html +599 -0
- package/skills/creative/canvas-design/LICENSE.txt +202 -0
- package/skills/creative/canvas-design/SKILL-zh.md +130 -0
- package/skills/creative/canvas-design/SKILL.md +130 -0
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/skills/creative/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/skills/creative/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/creative/frontend-design/LICENSE.txt +177 -0
- package/skills/creative/frontend-design/SKILL-zh.md +42 -0
- package/skills/creative/frontend-design/SKILL.md +42 -0
- package/skills/creative/theme-factory/LICENSE.txt +202 -0
- package/skills/creative/theme-factory/SKILL-zh.md +59 -0
- package/skills/creative/theme-factory/SKILL.md +59 -0
- package/skills/creative/theme-factory/theme-showcase.pdf +0 -0
- package/skills/creative/theme-factory/themes/arctic-frost.md +19 -0
- package/skills/creative/theme-factory/themes/botanical-garden.md +19 -0
- package/skills/creative/theme-factory/themes/desert-rose.md +19 -0
- package/skills/creative/theme-factory/themes/forest-canopy.md +19 -0
- package/skills/creative/theme-factory/themes/golden-hour.md +19 -0
- package/skills/creative/theme-factory/themes/midnight-galaxy.md +19 -0
- package/skills/creative/theme-factory/themes/modern-minimalist.md +19 -0
- package/skills/creative/theme-factory/themes/ocean-depths.md +19 -0
- package/skills/creative/theme-factory/themes/sunset-boulevard.md +19 -0
- package/skills/creative/theme-factory/themes/tech-innovation.md +19 -0
- package/skills/creative/web-artifacts-builder/LICENSE.txt +202 -0
- package/skills/creative/web-artifacts-builder/SKILL-zh.md +74 -0
- package/skills/creative/web-artifacts-builder/SKILL.md +74 -0
- package/skills/creative/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/skills/creative/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/skills/creative/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/documents/doc-coauthoring/SKILL-zh.md +375 -0
- package/skills/documents/doc-coauthoring/SKILL.md +375 -0
- package/skills/documents/docx/SKILL-zh.md +590 -0
- package/skills/{docx → documents/docx}/SKILL.md +11 -11
- package/skills/{docx → documents/docx}/scripts/comment.py +2 -2
- package/skills/{docx → documents/docx}/scripts/office/helpers/simplify_redlines.py +1 -1
- package/skills/{docx → documents/docx}/scripts/office/pack.py +2 -2
- package/skills/{xlsx → documents/docx}/scripts/office/validate.py +2 -2
- package/skills/{xlsx → documents/docx}/scripts/office/validators/redlining.py +1 -1
- package/skills/documents/pdf/SKILL-zh.md +314 -0
- package/skills/documents/pptx/SKILL-zh.md +232 -0
- package/skills/{pptx → documents/pptx}/editing.md +3 -3
- package/skills/{pptx → documents/pptx}/scripts/office/helpers/simplify_redlines.py +1 -1
- package/skills/{xlsx → documents/pptx}/scripts/office/pack.py +2 -2
- package/skills/{pptx → documents/pptx}/scripts/office/validate.py +2 -2
- package/skills/{docx → documents/pptx}/scripts/office/validators/redlining.py +1 -1
- package/skills/documents/xlsx/SKILL-zh.md +292 -0
- package/skills/{xlsx → documents/xlsx}/scripts/office/helpers/simplify_redlines.py +1 -1
- package/skills/{pptx → documents/xlsx}/scripts/office/pack.py +2 -2
- package/skills/{docx → documents/xlsx}/scripts/office/validate.py +2 -2
- package/skills/{pptx → documents/xlsx}/scripts/office/validators/redlining.py +1 -1
- package/skills/meta/skill-creator/LICENSE.txt +202 -0
- package/skills/meta/skill-creator/SKILL-zh.md +483 -0
- package/skills/{skill-creator → meta/skill-creator}/SKILL.md +0 -1
- package/skills/tools/find-skills/SKILL-zh.md +440 -0
- package/skills/tools/github/SKILL-zh.md +48 -0
- package/skills/tools/internal-comms/LICENSE.txt +202 -0
- package/skills/tools/internal-comms/SKILL-zh.md +32 -0
- package/skills/tools/internal-comms/SKILL.md +32 -0
- package/skills/tools/internal-comms/examples/3p-updates.md +47 -0
- package/skills/tools/internal-comms/examples/company-newsletter.md +65 -0
- package/skills/tools/internal-comms/examples/faq-answers.md +30 -0
- package/skills/tools/internal-comms/examples/general-comms.md +16 -0
- package/skills/tools/summarize/SKILL-zh.md +47 -0
- package/skills/tools/weather/SKILL-zh.md +46 -0
- package/skills/tools/webapp-testing/LICENSE.txt +202 -0
- package/skills/tools/webapp-testing/SKILL-zh.md +96 -0
- package/skills/tools/webapp-testing/SKILL.md +96 -0
- package/skills/tools/webapp-testing/examples/console_logging.py +35 -0
- package/skills/tools/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/tools/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/tools/webapp-testing/scripts/with_server.py +106 -0
- package/dist/gateway/static/root/assets/agents-CkgFSiCY.js +0 -216
- package/dist/gateway/static/root/assets/agents-CkgFSiCY.js.map +0 -1
- package/dist/gateway/static/root/assets/channels-settings-CE7jrdkO.js +0 -9
- package/dist/gateway/static/root/assets/channels-settings-CE7jrdkO.js.map +0 -1
- package/dist/gateway/static/root/assets/cron-page-BpPPcykJ.js +0 -2
- package/dist/gateway/static/root/assets/cron-page-BpPPcykJ.js.map +0 -1
- package/dist/gateway/static/root/assets/cron-utils-N1PqD2DB.js +0 -3
- package/dist/gateway/static/root/assets/cron-utils-N1PqD2DB.js.map +0 -1
- package/dist/gateway/static/root/assets/dist--p2HQ2QF.js +0 -2
- package/dist/gateway/static/root/assets/index-Dnfha4O2.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-CQwdV_Xw.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-CQwdV_Xw.js.map +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Be5kIGl_.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-PodSlNwr.js +0 -2
- package/dist/gateway/static/root/assets/settings-page-PodSlNwr.js.map +0 -1
- package/dist/gateway/static/root/assets/skills-page-Clg8deH0.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-Clg8deH0.js.map +0 -1
- package/dist/src/agent/skills/skills-store-client.d.ts +0 -66
- package/dist/src/agent/skills/skills-store-client.js.map +0 -1
- package/dist/src/stt/index.d.ts +0 -1
- package/dist/src/stt/index.js +0 -8
- /package/skills/{docx → documents/docx}/LICENSE.txt +0 -0
- /package/skills/{docx → documents/docx}/scripts/__init__.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/accept_changes.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/helpers/__init__.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/helpers/merge_runs.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/mce/mc.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/microsoft/wml-2010.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/microsoft/wml-2012.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/microsoft/wml-2018.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/soffice.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/unpack.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/validators/__init__.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/validators/base.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/validators/docx.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/office/validators/pptx.py +0 -0
- /package/skills/{docx → documents/docx}/scripts/templates/comments.xml +0 -0
- /package/skills/{docx → documents/docx}/scripts/templates/commentsExtended.xml +0 -0
- /package/skills/{docx → documents/docx}/scripts/templates/commentsExtensible.xml +0 -0
- /package/skills/{docx → documents/docx}/scripts/templates/commentsIds.xml +0 -0
- /package/skills/{docx → documents/docx}/scripts/templates/people.xml +0 -0
- /package/skills/{pdf → documents/pdf}/LICENSE.txt +0 -0
- /package/skills/{pdf → documents/pdf}/SKILL.md +0 -0
- /package/skills/{pdf → documents/pdf}/forms.md +0 -0
- /package/skills/{pdf → documents/pdf}/reference.md +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/check_bounding_boxes.py +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/check_fillable_fields.py +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/convert_pdf_to_images.py +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/create_validation_image.py +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/extract_form_field_info.py +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/extract_form_structure.py +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/fill_fillable_fields.py +0 -0
- /package/skills/{pdf → documents/pdf}/scripts/fill_pdf_form_with_annotations.py +0 -0
- /package/skills/{pptx → documents/pptx}/LICENSE.txt +0 -0
- /package/skills/{pptx → documents/pptx}/SKILL.md +0 -0
- /package/skills/{pptx → documents/pptx}/pptxgenjs.md +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/__init__.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/add_slide.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/clean.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/helpers/__init__.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/helpers/merge_runs.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/mce/mc.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/microsoft/wml-2010.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/microsoft/wml-2012.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/microsoft/wml-2018.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/soffice.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/unpack.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/validators/__init__.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/validators/base.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/validators/docx.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/office/validators/pptx.py +0 -0
- /package/skills/{pptx → documents/pptx}/scripts/thumbnail.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/LICENSE.txt +0 -0
- /package/skills/{xlsx → documents/xlsx}/SKILL.md +0 -0
- /package/skills/{skill-creator/scripts → documents/xlsx/scripts/office/helpers}/__init__.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/helpers/merge_runs.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/mce/mc.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/microsoft/wml-2010.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/microsoft/wml-2012.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/microsoft/wml-2018.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/soffice.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/unpack.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/validators/__init__.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/validators/base.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/validators/docx.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/office/validators/pptx.py +0 -0
- /package/skills/{xlsx → documents/xlsx}/scripts/recalc.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/agents/analyzer.md +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/agents/comparator.md +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/agents/grader.md +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/assets/eval_review.html +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/eval-viewer/generate_review.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/eval-viewer/viewer.html +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/references/schemas.md +0 -0
- /package/skills/{xlsx/scripts/office/helpers → meta/skill-creator/scripts}/__init__.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/aggregate_benchmark.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/generate_report.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/improve_description.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/package_skill.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/quick_validate.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/run_eval.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/run_loop.py +0 -0
- /package/skills/{skill-creator → meta/skill-creator}/scripts/utils.py +0 -0
- /package/skills/{find-skills → tools/find-skills}/SKILL.md +0 -0
- /package/skills/{github → tools/github}/SKILL.md +0 -0
- /package/skills/{summarize → tools/summarize}/SKILL.md +0 -0
- /package/skills/{weather → tools/weather}/SKILL.md +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","names":[],"sources":["../../../../src/agent/prompt/system-prompt.ts"],"sourcesContent":["/**\n * System Prompt Builder - Enhanced version with workspace context integration\n * \n * Integrates workspace bootstrap files:\n * - SOUL.md for persona and tone\n * - USER.md for user context\n * - IDENTITY.md for agent identity\n * - HEARTBEAT.md for task polling\n * - MEMORY.md for long-term memory\n * - Memory search integration in prompt\n */\n\nimport type { WorkspaceBootstrapFile } from '../context/workspace.js';\nimport {\n DEFAULT_SOUL_FILENAME,\n DEFAULT_USER_FILENAME,\n DEFAULT_IDENTITY_FILENAME,\n DEFAULT_HEARTBEAT_FILENAME,\n DEFAULT_MEMORY_FILENAME,\n DEFAULT_AGENTS_FILENAME,\n DEFAULT_TOOLS_FILENAME,\n stripFrontMatter,\n} from '../context/workspace.js';\nimport type { MemorySnapshot } from '../memory/types.js';\nimport { PROMPT_CACHE_BOUNDARY } from './cache-boundary.js';\nimport type { PromptMode } from './types.js';\n\n// =============================================================================\n// Configuration (Internal)\n// =============================================================================\n\n/** Maximum characters to inject from workspace files into system prompt */\nconst PROMPT_MAX_CHARS = {\n SOUL: 8_000,\n USER: 4_000,\n IDENTITY: 2_000,\n AGENTS: 20_000,\n TOOLS: 4_000,\n HEARTBEAT: 2_000,\n MEMORY: 8_000,\n};\n\n/** Whether memory citation is enabled */\nexport type MemoryCitationsMode = 'on' | 'off' | 'source-only';\n\nexport interface SystemPromptOptions {\n /** Workspace bootstrap files */\n bootstrapFiles: WorkspaceBootstrapFile[];\n /** Which sections to include. Defaults to \"full\". */\n promptMode?: PromptMode;\n /** Whether heartbeat is enabled */\n heartbeatEnabled?: boolean;\n /** Custom heartbeat prompt */\n heartbeatPrompt?: string;\n /** Available tool names for skill matching */\n availableTools?: string[];\n /** Memory citations mode */\n memoryCitationsMode?: MemoryCitationsMode;\n /** User timezone for date/time display */\n userTimezone?: string;\n /** Runtime info (version, model, channel) */\n runtime?: {\n version?: string;\n model?: string;\n channel?: string;\n };\n /** Active messaging channels */\n channels?: string[];\n /** Frozen curated memory from agent home `memories/` (session start only). */\n curatedMemorySnapshot?: MemorySnapshot;\n /** External memory provider static instructions. */\n externalMemoryInstructions?: string;\n /** How skill instructions are surfaced (metadata-only → use skills_list / skill_view). */\n skillsPromptMode?: 'metadata-only' | 'legacy-with-paths';\n /** Optional TTS / voice output guidance (when TTS is enabled). */\n ttsSystemHint?: string;\n}\n\n// =============================================================================\n// Section Builders\n// =============================================================================\n\n/**\n * Build SOUL.md section - persona and tone\n * \n * If SOUL.md is present, embody its persona and tone\n */\nfunction buildSoulSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const soulFile = bootstrapFiles.find(f => f.name === DEFAULT_SOUL_FILENAME);\n if (!soulFile || soulFile.missing || !soulFile.content) {\n return '';\n }\n\n // Strip front matter and truncate\n const content = stripFrontMatter(soulFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.SOUL);\n\n return `## SOUL.md - Your Persona\n\n${truncated}\n\n_Embody this persona unless higher-priority instructions override it._\n`;\n}\n\n/**\n * Build USER.md section - user context\n */\nfunction buildUserSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const userFile = bootstrapFiles.find(f => f.name === DEFAULT_USER_FILENAME);\n if (!userFile || userFile.missing || !userFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(userFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.USER);\n\n return `## USER.md - About Your Human\n\n${truncated}\n\n_Use this context to provide personalized assistance._\n`;\n}\n\n/**\n * Curated MEMORY.md + USER.md blocks (frozen at session start).\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\nfunction buildCuratedMemorySection(snapshot: MemorySnapshot | undefined): string {\n const mem = snapshot?.memory?.trim() ?? '';\n const user = snapshot?.user?.trim() ?? '';\n if (!mem && !user) {\n return '';\n }\n\n const body = [mem, user].filter(Boolean).join('\\n\\n');\n return `## Curated memory (session snapshot)\n\n> Frozen when this session started. Updates use \\`curated_memory\\` and save under agent home \\`memories/\\`; they do not change this block until a new session.\n\n${body}`;\n}\n\n/**\n * Build IDENTITY.md section - agent identity\n */\nfunction buildIdentitySection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const identityFile = bootstrapFiles.find(f => f.name === DEFAULT_IDENTITY_FILENAME);\n if (!identityFile || identityFile.missing || !identityFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(identityFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.IDENTITY);\n\n return `## IDENTITY.md - Who You Are\n\n${truncated}\n`;\n}\n\n/**\n * Build AGENTS.md section - development guidelines\n */\nfunction buildAgentsSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const agentsFile = bootstrapFiles.find(f => f.name === DEFAULT_AGENTS_FILENAME);\n if (!agentsFile || agentsFile.missing || !agentsFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(agentsFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.AGENTS);\n\n return `## AGENTS.md - Development Guidelines\n\n${truncated}\n`;\n}\n\n/**\n * Build TOOLS.md section - local tool notes\n */\nfunction buildToolsSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const toolsFile = bootstrapFiles.find(f => f.name === DEFAULT_TOOLS_FILENAME);\n if (!toolsFile || toolsFile.missing || !toolsFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(toolsFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.TOOLS);\n\n return `## TOOLS.md - Local Notes\n\n${truncated}\n`;\n}\n\n/**\n * Build HEARTBEAT.md section - task polling\n */\nfunction buildHeartbeatSection(\n bootstrapFiles: WorkspaceBootstrapFile[],\n enabled: boolean,\n customPrompt?: string,\n userTimezone?: string\n): string {\n if (!enabled) {\n return '';\n }\n\n // If custom prompt provided, use it\n if (customPrompt) {\n return `## Heartbeat\n\n${customPrompt}\n`;\n }\n\n // Try to load from HEARTBEAT.md\n const heartbeatFile = bootstrapFiles.find(f => f.name === DEFAULT_HEARTBEAT_FILENAME);\n if (!heartbeatFile || heartbeatFile.missing || !heartbeatFile.content) {\n // Default heartbeat behavior with timezone-aware quiet hours\n let quietHoursNote = '';\n if (userTimezone) {\n quietHoursNote = `\\n\\n> 💤 Quiet hours: The user is in **${userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;\n }\n return `## Heartbeat\n\nPoll for tasks. If nothing needs attention, reply: HEARTBEAT_OK\n\n_Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats._${quietHoursNote}\n`;\n }\n\n const content = stripFrontMatter(heartbeatFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.HEARTBEAT);\n\n let quietHoursNote = '';\n if (userTimezone) {\n quietHoursNote = `\\n\\n> 💤 Quiet hours: The user is in **${userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;\n }\n\n return `## HEARTBEAT.md - Task Checklist\n\n${truncated}\n\n_Read HEARTBEAT.md for current tasks. If nothing needs attention, reply: HEARTBEAT_OK_${quietHoursNote}\n`;\n}\n\n/**\n * Build Memory section - recall instructions\n * \n * Before answering anything about prior work, decisions, dates, people, preferences, or todos: run memory_search\n */\nfunction buildMemorySection(\n bootstrapFiles: WorkspaceBootstrapFile[],\n citationsMode: MemoryCitationsMode = 'on',\n hasCuratedSnapshot = false,\n): string {\n const memoryFile = bootstrapFiles.find(f => f.name === DEFAULT_MEMORY_FILENAME);\n const hasWorkspaceMemoryFile = !!(memoryFile && !memoryFile.missing);\n\n if (!hasWorkspaceMemoryFile && !hasCuratedSnapshot) {\n return '';\n }\n\n const citationInstruction = 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 curatedLines = hasCuratedSnapshot\n ? `\n- **Curated store:** agent home \\`memories/MEMORY.md\\` and \\`memories/USER.md\\` — use \\`curated_memory\\` to add/replace/remove/read structured entries.`\n : '';\n\n return `## Memory Recall\n\n${citationInstruction}\n\nBefore answering anything about prior work, decisions, dates, people, preferences, or todos:\n1. Run \\`memory_search\\` on bootstrap MEMORY.md, agent-home \\`memories/*.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. If low confidence after search, say you checked\n\n### Memory Files\n\n- **Daily notes:** \\`memory/YYYY-MM-DD.md\\` — raw logs of what happened\n- **Long-term:** \\`MEMORY.md\\` — your curated memories, like a human's long-term memory${curatedLines}\n\n### Writing to Memory\n\n- **Declarative vs procedural:** Save **facts and preferences** (who the user is, how they want you to behave, stable environment) via workspace memory files and/or \\`curated_memory\\`. Save **reusable task playbooks** (steps, pitfalls, verification for a class of work) with \\`skill_manage\\` as skills — not as long prose in MEMORY.md.\n- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE\n- \"Mental notes\" don't survive session restarts. Files do.\n- When someone says \"remember this\" → update \\`memory/YYYY-MM-DD.md\\` or relevant file\n- When you learn a lesson → update relevant files\n- When you make a mistake → document it so future-you doesn't repeat it\n- **Text > Brain** 📝\n`;\n}\n\n/**\n * Build Skills section - skill matching guidelines\n */\nfunction buildSkillsSection(\n availableTools: string[] = [],\n skillsPromptMode: 'metadata-only' | 'legacy-with-paths' = 'metadata-only',\n): string {\n if (availableTools.length === 0) {\n return '';\n }\n\n if (skillsPromptMode === 'legacy-with-paths') {\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? → Use read_file on its SKILL.md (see location) and follow it.\n3. Several plausible matches? → Pick the most specific one.\n4. No match? → Solve it yourself; do not force-fit a skill.\n\n**Principle:** Skills are tools, not shackles. If after reading one it does not fit, set it aside and proceed on your own.\n\n**Division of labor with memory:** Skills = **procedural** workflows (how to do a class of tasks); memory / \\`curated_memory\\` = **declarative** facts and preferences. After a complex task succeeds, you may codify it as a skill; user-profile-style information belongs in memory.\n`;\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. (only references, templates, scripts, assets)\n4. No match? → Solve it yourself; do not force-fit a skill.\n\n**Principle:** Skills are tools, not shackles. If after reading one it does not fit, set it aside and proceed on your own.\n\n**Division of labor with memory:** Skills = **procedural** workflows (how to do a class of tasks); memory / \\`curated_memory\\` = **declarative** facts and preferences. After a complex task succeeds, you may codify it as a skill; user-profile-style information belongs in memory. When a skill is outdated or incomplete, fix it immediately with \\`skill_manage\\` (e.g. patch).\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\n/**\n * Build Problem Solving Workflow section\n *\n * Implements the \"Build & Self-Verify\" pattern from harness engineering.\n * Guides agents through an iterative problem-solving process with verification.\n *\n * Inspired by: https://blog.langchain.com/improving-deep-agents-with-harness-engineering/\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**Decision criteria:**\n- Multiple files or refactoring? → Plan first\n- Existing test coverage? → You must verify\n- Documentation or comments only? → Verification can be lighter\n- User says \"just take a quick look\"? → Skip ceremony; deliver the result directly\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\n/**\n * Build Aesthetic Guidelines section - tone and style preferences\n */\nfunction buildAestheticSection(): string {\n return `## Tone & Style\n\n**Default voice:**\n- Direct over diplomatic (\"This is broken\" beats \"This might be worth considering\")\n- Concise over exhaustive (do not expand on what the user did not ask for)\n- Concrete over abstract (use examples, not lectures)\n\n**Avoid LLM-isms:**\n- Do not open with \"This is a complex question...\"\n- Rarely use \"It is worth noting...\" / \"It is important to emphasize...\"\n- Not every sentence needs bullets; natural paragraphs are fine\n- Do not wrap a simple takeaway in a four-step framework\n\n**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above.\n`;\n}\nfunction buildMessagingSection(\n channels: string[] = [],\n isMinimal: boolean = false\n): string {\n if (isMinimal || channels.length === 0) {\n return '';\n }\n\n const channelList = channels.join(', ');\n\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\n/**\n * Build Time section - user timezone\n */\nfunction buildTimeSection(timezone?: string): string {\n if (!timezone) {\n return '';\n }\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\n/**\n * Build Runtime section - version info\n */\nfunction buildRuntimeSection(runtime?: { version?: string; model?: string; channel?: string }): string {\n if (!runtime) {\n return '';\n }\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\n return parts.length > 0 ? `[${parts.join(' | ')}]` : '';\n}\n\n/**\n * Build Working Directory section\n */\nfunction buildWorkingDirSection(workspaceDir: string): string {\n return `Working directory: ${workspaceDir}`;\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\n/**\n * Truncate content for prompt injection\n * Keeps head and tail to preserve context\n */\nfunction truncateForPrompt(content: string, maxChars: number): string {\n const trimmed = content.trimEnd();\n if (trimmed.length <= maxChars) {\n return trimmed;\n }\n\n // Keep head (70%) and tail (20%) with marker\n const headChars = Math.floor(maxChars * 0.7);\n const tailChars = Math.floor(maxChars * 0.2);\n const head = trimmed.slice(0, headChars);\n const tail = trimmed.slice(-tailChars);\n\n return `${head}\n\n[...]${tail}`;\n}\n\n// =============================================================================\n// Main Builder\n// =============================================================================\n\n/**\n * Build system prompt with workspace context integration\n * \n * Injects workspace files at appropriate positions in the system prompt.\n */\nexport function buildSystemPrompt(\n workspaceDir: string,\n options: SystemPromptOptions\n): string {\n const {\n bootstrapFiles,\n promptMode = 'full',\n heartbeatEnabled = false,\n heartbeatPrompt,\n availableTools = [],\n memoryCitationsMode = 'on',\n userTimezone,\n runtime,\n channels = [],\n curatedMemorySnapshot,\n externalMemoryInstructions,\n skillsPromptMode = 'metadata-only',\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\n const curatedUserFrozen = !!(curatedMemorySnapshot?.user?.trim());\n const hasCuratedSnapshot = !!(\n curatedMemorySnapshot?.memory?.trim() || curatedMemorySnapshot?.user?.trim()\n );\n\n const sections: string[] = [];\n\n // 1. Identity and persona (non-minimal only)\n if (!isMinimal) {\n sections.push(buildIdentitySection(bootstrapFiles));\n sections.push(buildSoulSection(bootstrapFiles));\n }\n\n // 2. Curated memory snapshot (non-minimal; frozen at session start)\n if (!isMinimal) {\n sections.push(buildCuratedMemorySection(curatedMemorySnapshot));\n }\n\n // 2b. External memory provider\n if (!isMinimal) {\n sections.push(buildExternalMemorySection(externalMemoryInstructions));\n }\n\n // 3. User context — workspace USER.md unless curated user block is active\n if (!isMinimal && !curatedUserFrozen) {\n sections.push(buildUserSection(bootstrapFiles));\n }\n\n // 4. Time (non-minimal only)\n if (!isMinimal) {\n sections.push(buildTimeSection(userTimezone));\n }\n\n // 5. Memory section (non-minimal only)\n if (!isMinimal) {\n sections.push(buildMemorySection(bootstrapFiles, memoryCitationsMode, hasCuratedSnapshot));\n }\n\n // 6. Skills\n sections.push(buildSkillsSection(availableTools, skillsPromptMode));\n\n // 6b. Safety (non-minimal only)\n if (!isMinimal) {\n sections.push(buildSafetySection());\n }\n\n // 7. Problem Solving Workflow (non-minimal only) - Harness Engineering\n if (!isMinimal) {\n sections.push(buildProblemSolvingSection());\n }\n\n // 8. Aesthetic Guidelines (non-minimal only)\n if (!isMinimal) {\n sections.push(buildAestheticSection());\n }\n\n // Cache boundary — stable content above is a better prompt-cache prefix for supported providers\n sections.push(PROMPT_CACHE_BOUNDARY);\n\n // 9. Heartbeat\n sections.push(buildHeartbeatSection(bootstrapFiles, heartbeatEnabled, heartbeatPrompt, userTimezone));\n\n // 10. Working directory\n sections.push(buildWorkingDirSection(workspaceDir));\n\n // 11. Tools (non-minimal only)\n if (!isMinimal) {\n sections.push(buildToolsSection(bootstrapFiles));\n }\n\n // 12. Agents guidelines\n sections.push(buildAgentsSection(bootstrapFiles));\n\n // 13. Messaging\n sections.push(buildMessagingSection(channels, isMinimal));\n\n // 13b. Voice (TTS)\n if (!isMinimal && ttsSystemHint?.trim()) {\n sections.push(`## Voice (TTS)\\n\\n${ttsSystemHint.trim()}`);\n }\n\n // 14. Runtime info\n sections.push(buildRuntimeSection(runtime));\n\n // Filter out empty sections and join\n return sections.filter(Boolean).join('\\n\\n');\n}\n\n/**\n * Build minimal system prompt for subagents/cron jobs (Internal)\n */\nfunction _buildMinimalSystemPrompt(\n workspaceDir: string,\n bootstrapFiles: WorkspaceBootstrapFile[]\n): string {\n return buildSystemPrompt(workspaceDir, {\n bootstrapFiles,\n promptMode: 'minimal',\n heartbeatEnabled: false,\n });\n}\n\n/**\n * Get bootstrap file by name (Internal)\n */\nfunction _getBootstrapFile(\n bootstrapFiles: WorkspaceBootstrapFile[],\n name: string\n): WorkspaceBootstrapFile | undefined {\n return bootstrapFiles.find(f => f.name === name);\n}\n\n/**\n * Check if specific bootstrap file exists and is loaded (Internal)\n */\nfunction _hasBootstrapFile(\n bootstrapFiles: WorkspaceBootstrapFile[],\n name: string\n): boolean {\n const file = bootstrapFiles.find(f => f.name === name);\n return !!file && !file.missing && !!file.content;\n}\n"],"mappings":";;;;AAgCA,MAAM,mBAAmB;CACvB,MAAM;CACN,MAAM;CACN,UAAU;CACV,QAAQ;CACR,OAAO;CACP,WAAW;CACX,QAAQ;CACT;;;;;;AA+CD,SAAS,iBAAiB,gBAAkD;CAC1E,MAAM,WAAW,eAAe,MAAK,MAAK,EAAE,SAAS,sBAAsB;AAC3E,KAAI,CAAC,YAAY,SAAS,WAAW,CAAC,SAAS,QAC7C,QAAO;AAOT,QAAO;;EAFW,kBADF,iBAAiB,SAAS,QACC,EAAE,iBAAiB,KAIrD,CAAC;;;;;;;;AASZ,SAAS,iBAAiB,gBAAkD;CAC1E,MAAM,WAAW,eAAe,MAAK,MAAK,EAAE,SAAS,sBAAsB;AAC3E,KAAI,CAAC,YAAY,SAAS,WAAW,CAAC,SAAS,QAC7C,QAAO;AAMT,QAAO;;EAFW,kBADF,iBAAiB,SAAS,QACC,EAAE,iBAAiB,KAIrD,CAAC;;;;;;;;AASZ,SAAS,2BAA2B,MAAkC;CACpE,MAAM,IAAI,MAAM,MAAM;AACtB,KAAI,CAAC,EACH,QAAO;AAET,QAAO;;EAEP;;AAGF,SAAS,0BAA0B,UAA8C;CAC/E,MAAM,MAAM,UAAU,QAAQ,MAAM,IAAI;CACxC,MAAM,OAAO,UAAU,MAAM,MAAM,IAAI;AACvC,KAAI,CAAC,OAAO,CAAC,KACX,QAAO;AAIT,QAAO;;;;EADM,CAAC,KAAK,KAAK,CAAC,OAAO,QAAQ,CAAC,KAAK,OAK1C;;;;;AAMN,SAAS,qBAAqB,gBAAkD;CAC9E,MAAM,eAAe,eAAe,MAAK,MAAK,EAAE,SAAS,0BAA0B;AACnF,KAAI,CAAC,gBAAgB,aAAa,WAAW,CAAC,aAAa,QACzD,QAAO;AAMT,QAAO;;EAFW,kBADF,iBAAiB,aAAa,QACH,EAAE,iBAAiB,SAIrD,CAAC;;;;;;AAOZ,SAAS,mBAAmB,gBAAkD;CAC5E,MAAM,aAAa,eAAe,MAAK,MAAK,EAAE,SAAS,wBAAwB;AAC/E,KAAI,CAAC,cAAc,WAAW,WAAW,CAAC,WAAW,QACnD,QAAO;AAMT,QAAO;;EAFW,kBADF,iBAAiB,WAAW,QACD,EAAE,iBAAiB,OAIrD,CAAC;;;;;;AAOZ,SAAS,kBAAkB,gBAAkD;CAC3E,MAAM,YAAY,eAAe,MAAK,MAAK,EAAE,SAAS,uBAAuB;AAC7E,KAAI,CAAC,aAAa,UAAU,WAAW,CAAC,UAAU,QAChD,QAAO;AAMT,QAAO;;EAFW,kBADF,iBAAiB,UAAU,QACA,EAAE,iBAAiB,MAIrD,CAAC;;;;;;AAOZ,SAAS,sBACP,gBACA,SACA,cACA,cACQ;AACR,KAAI,CAAC,QACH,QAAO;AAIT,KAAI,aACF,QAAO;;EAET,aAAa;;CAKb,MAAM,gBAAgB,eAAe,MAAK,MAAK,EAAE,SAAS,2BAA2B;AACrF,KAAI,CAAC,iBAAiB,cAAc,WAAW,CAAC,cAAc,SAAS;EAErE,IAAI,iBAAiB;AACrB,MAAI,aACF,kBAAiB,0CAA0C,aAAa;AAE1E,SAAO;;;;8HAImH,eAAe;;;CAK3I,MAAM,YAAY,kBADF,iBAAiB,cAAc,QACJ,EAAE,iBAAiB,UAAU;CAExE,IAAI,iBAAiB;AACrB,KAAI,aACF,kBAAiB,0CAA0C,aAAa;AAG1E,QAAO;;EAEP,UAAU;;wFAE4E,eAAe;;;;;;;;AASvG,SAAS,mBACP,gBACA,gBAAqC,MACrC,qBAAqB,OACb;CACR,MAAM,aAAa,eAAe,MAAK,MAAK,EAAE,SAAS,wBAAwB;AAG/E,KAAI,CAAC,CAF2B,EAAE,cAAc,CAAC,WAAW,YAE7B,CAAC,mBAC9B,QAAO;AAcT,QAAO;;EAXqB,kBAAkB,QAC1C,kFACA,kBAAkB,gBAClB,0EACA,wFASgB;;;;;;;;;;;yFAPC,qBACjB;2JAEA,GAegG;;;;;;;;;;;;;;;;AAiBtG,SAAS,mBACP,iBAA2B,EAAE,EAC7B,mBAA0D,iBAClD;AACR,KAAI,eAAe,WAAW,EAC5B,QAAO;AAGT,KAAI,qBAAqB,oBACvB,QAAO;;;;;;;;;;;;;;AAgBT,QAAO;;;;;;;;;;;;;;;AAgBT,SAAS,qBAA6B;AACpC,QAAO;;;;;;;;;;;;;;AAeT,SAAS,6BAAqC;AAC5C,QAAO;;;;;;;;;;;;;;;;;AAkBT,SAAS,wBAAgC;AACvC,QAAO;;;;;;;;;;;;;;;;AAgBT,SAAS,sBACP,WAAqB,EAAE,EACvB,YAAqB,OACb;AACR,KAAI,aAAa,SAAS,WAAW,EACnC,QAAO;AAKT,QAAO;;2EAFa,SAAS,KAAK,KAIkD,CAAC;;;;;;;;AASvF,SAAS,iBAAiB,UAA2B;AACnD,KAAI,CAAC,SACH,QAAO;AAGT,QAAO;;aAEI,SAAS;;;;;;;;AAStB,SAAS,oBAAoB,SAA0E;AACrG,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,QAAkB,EAAE;AAC1B,KAAI,QAAQ,QAAS,OAAM,KAAK,IAAI,QAAQ,UAAU;AACtD,KAAI,QAAQ,MAAO,OAAM,KAAK,SAAS,QAAQ,MAAM,MAAM,IAAI,CAAC,KAAK,GAAG;AACxE,KAAI,QAAQ,QAAS,OAAM,KAAK,MAAM,QAAQ,UAAU;AAExD,QAAO,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK,MAAM,CAAC,KAAK;;;;;AAMvD,SAAS,uBAAuB,cAA8B;AAC5D,QAAO,sBAAsB;;;;;;AAW/B,SAAS,kBAAkB,SAAiB,UAA0B;CACpE,MAAM,UAAU,QAAQ,SAAS;AACjC,KAAI,QAAQ,UAAU,SACpB,QAAO;CAIT,MAAM,YAAY,KAAK,MAAM,WAAW,GAAI;CAC5C,MAAM,YAAY,KAAK,MAAM,WAAW,GAAI;AAI5C,QAAO,GAHM,QAAQ,MAAM,GAAG,UAGhB,CAAC;;OAFF,QAAQ,MAAM,CAAC,UAInB;;;;;;;AAYX,SAAgB,kBACd,cACA,SACQ;CACR,MAAM,EACJ,gBACA,aAAa,QACb,mBAAmB,OACnB,iBACA,iBAAiB,EAAE,EACnB,sBAAsB,MACtB,cACA,SACA,WAAW,EAAE,EACb,uBACA,4BACA,mBAAmB,iBACnB,kBACE;AAEJ,KAAI,eAAe,OACjB,QAAO;CAGT,MAAM,YAAY,eAAe;CAEjC,MAAM,oBAAoB,CAAC,CAAE,uBAAuB,MAAM,MAAM;CAChE,MAAM,qBAAqB,CAAC,EAC1B,uBAAuB,QAAQ,MAAM,IAAI,uBAAuB,MAAM,MAAM;CAG9E,MAAM,WAAqB,EAAE;AAG7B,KAAI,CAAC,WAAW;AACd,WAAS,KAAK,qBAAqB,eAAe,CAAC;AACnD,WAAS,KAAK,iBAAiB,eAAe,CAAC;;AAIjD,KAAI,CAAC,UACH,UAAS,KAAK,0BAA0B,sBAAsB,CAAC;AAIjE,KAAI,CAAC,UACH,UAAS,KAAK,2BAA2B,2BAA2B,CAAC;AAIvE,KAAI,CAAC,aAAa,CAAC,kBACjB,UAAS,KAAK,iBAAiB,eAAe,CAAC;AAIjD,KAAI,CAAC,UACH,UAAS,KAAK,iBAAiB,aAAa,CAAC;AAI/C,KAAI,CAAC,UACH,UAAS,KAAK,mBAAmB,gBAAgB,qBAAqB,mBAAmB,CAAC;AAI5F,UAAS,KAAK,mBAAmB,gBAAgB,iBAAiB,CAAC;AAGnE,KAAI,CAAC,UACH,UAAS,KAAK,oBAAoB,CAAC;AAIrC,KAAI,CAAC,UACH,UAAS,KAAK,4BAA4B,CAAC;AAI7C,KAAI,CAAC,UACH,UAAS,KAAK,uBAAuB,CAAC;AAIxC,UAAS,KAAK,sBAAsB;AAGpC,UAAS,KAAK,sBAAsB,gBAAgB,kBAAkB,iBAAiB,aAAa,CAAC;AAGrG,UAAS,KAAK,uBAAuB,aAAa,CAAC;AAGnD,KAAI,CAAC,UACH,UAAS,KAAK,kBAAkB,eAAe,CAAC;AAIlD,UAAS,KAAK,mBAAmB,eAAe,CAAC;AAGjD,UAAS,KAAK,sBAAsB,UAAU,UAAU,CAAC;AAGzD,KAAI,CAAC,aAAa,eAAe,MAAM,CACrC,UAAS,KAAK,qBAAqB,cAAc,MAAM,GAAG;AAI5D,UAAS,KAAK,oBAAoB,QAAQ,CAAC;AAG3C,QAAO,SAAS,OAAO,QAAQ,CAAC,KAAK,OAAO"}
|
|
1
|
+
{"version":3,"file":"system-prompt.js","names":[],"sources":["../../../../src/agent/prompt/system-prompt.ts"],"sourcesContent":["/**\n * System Prompt Builder - Enhanced version with workspace context integration\n * \n * Integrates workspace bootstrap files:\n * - SOUL.md for persona and tone\n * - USER.md for user context\n * - IDENTITY.md for agent identity\n * - HEARTBEAT.md for task polling\n * - MEMORY.md for long-term memory\n * - Memory search integration in prompt\n */\n\nimport type { WorkspaceBootstrapFile } from '../context/workspace.js';\nimport {\n DEFAULT_SOUL_FILENAME,\n DEFAULT_USER_FILENAME,\n DEFAULT_IDENTITY_FILENAME,\n DEFAULT_HEARTBEAT_FILENAME,\n DEFAULT_MEMORY_FILENAME,\n DEFAULT_AGENTS_FILENAME,\n DEFAULT_TOOLS_FILENAME,\n stripFrontMatter,\n} from '../context/workspace.js';\nimport type { MemorySnapshot } from '../memory/types.js';\nimport { PROMPT_CACHE_BOUNDARY } from './cache-boundary.js';\nimport type { PromptMode } from './types.js';\n\n// =============================================================================\n// Configuration (Internal)\n// =============================================================================\n\n/** Maximum characters to inject from workspace files into system prompt */\nconst PROMPT_MAX_CHARS = {\n SOUL: 8_000,\n USER: 4_000,\n IDENTITY: 2_000,\n AGENTS: 20_000,\n TOOLS: 4_000,\n HEARTBEAT: 2_000,\n MEMORY: 8_000,\n};\n\n/** Whether memory citation is enabled */\nexport type MemoryCitationsMode = 'on' | 'off' | 'source-only';\n\nexport interface SystemPromptOptions {\n /** Workspace bootstrap files */\n bootstrapFiles: WorkspaceBootstrapFile[];\n /** Which sections to include. Defaults to \"full\". */\n promptMode?: PromptMode;\n /** Whether heartbeat is enabled */\n heartbeatEnabled?: boolean;\n /** Custom heartbeat prompt */\n heartbeatPrompt?: string;\n /** Available tool names for skill matching */\n availableTools?: string[];\n /** Memory citations mode */\n memoryCitationsMode?: MemoryCitationsMode;\n /** User timezone for date/time display */\n userTimezone?: string;\n /** Runtime info (version, model, channel) */\n runtime?: {\n version?: string;\n model?: string;\n channel?: string;\n };\n /** Active messaging channels */\n channels?: string[];\n /** Frozen curated memory from agent home `memories/` (session start only). */\n curatedMemorySnapshot?: MemorySnapshot;\n /** External memory provider static instructions. */\n externalMemoryInstructions?: string;\n /** Optional TTS / voice output guidance (when TTS is enabled). */\n ttsSystemHint?: string;\n}\n\n// =============================================================================\n// Section Builders\n// =============================================================================\n\n/**\n * Build SOUL.md section - persona and tone\n * \n * If SOUL.md is present, embody its persona and tone\n */\nfunction buildSoulSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const soulFile = bootstrapFiles.find(f => f.name === DEFAULT_SOUL_FILENAME);\n if (!soulFile || soulFile.missing || !soulFile.content) {\n return '';\n }\n\n // Strip front matter and truncate\n const content = stripFrontMatter(soulFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.SOUL);\n\n return `## SOUL.md - Your Persona\n\n${truncated}\n\n_Embody this persona unless higher-priority instructions override it._\n`;\n}\n\n/**\n * Build USER.md section - user context\n */\nfunction buildUserSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const userFile = bootstrapFiles.find(f => f.name === DEFAULT_USER_FILENAME);\n if (!userFile || userFile.missing || !userFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(userFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.USER);\n\n return `## USER.md - About Your Human\n\n${truncated}\n\n_Use this context to provide personalized assistance._\n`;\n}\n\n/**\n * Curated MEMORY.md + USER.md blocks (frozen at session start).\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\nfunction buildCuratedMemorySection(snapshot: MemorySnapshot | undefined): string {\n const mem = snapshot?.memory?.trim() ?? '';\n const user = snapshot?.user?.trim() ?? '';\n if (!mem && !user) {\n return '';\n }\n\n const body = [mem, user].filter(Boolean).join('\\n\\n');\n return `## Curated memory (session snapshot)\n\n> Frozen when this session started. Updates use \\`curated_memory\\` and save under agent home \\`memories/\\`; they do not change this block until a new session.\n\n${body}`;\n}\n\n/**\n * Build IDENTITY.md section - agent identity\n */\nfunction buildIdentitySection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const identityFile = bootstrapFiles.find(f => f.name === DEFAULT_IDENTITY_FILENAME);\n if (!identityFile || identityFile.missing || !identityFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(identityFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.IDENTITY);\n\n return `## IDENTITY.md - Who You Are\n\n${truncated}\n`;\n}\n\n/**\n * Build AGENTS.md section - development guidelines\n */\nfunction buildAgentsSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const agentsFile = bootstrapFiles.find(f => f.name === DEFAULT_AGENTS_FILENAME);\n if (!agentsFile || agentsFile.missing || !agentsFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(agentsFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.AGENTS);\n\n return `## AGENTS.md - Development Guidelines\n\n${truncated}\n`;\n}\n\n/**\n * Build TOOLS.md section - local tool notes\n */\nfunction buildToolsSection(bootstrapFiles: WorkspaceBootstrapFile[]): string {\n const toolsFile = bootstrapFiles.find(f => f.name === DEFAULT_TOOLS_FILENAME);\n if (!toolsFile || toolsFile.missing || !toolsFile.content) {\n return '';\n }\n\n const content = stripFrontMatter(toolsFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.TOOLS);\n\n return `## TOOLS.md - Local Notes\n\n${truncated}\n`;\n}\n\n/**\n * Build HEARTBEAT.md section - task polling\n */\nfunction buildHeartbeatSection(\n bootstrapFiles: WorkspaceBootstrapFile[],\n enabled: boolean,\n customPrompt?: string,\n userTimezone?: string\n): string {\n if (!enabled) {\n return '';\n }\n\n // If custom prompt provided, use it\n if (customPrompt) {\n return `## Heartbeat\n\n${customPrompt}\n`;\n }\n\n // Try to load from HEARTBEAT.md\n const heartbeatFile = bootstrapFiles.find(f => f.name === DEFAULT_HEARTBEAT_FILENAME);\n if (!heartbeatFile || heartbeatFile.missing || !heartbeatFile.content) {\n // Default heartbeat behavior with timezone-aware quiet hours\n let quietHoursNote = '';\n if (userTimezone) {\n quietHoursNote = `\\n\\n> 💤 Quiet hours: The user is in **${userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;\n }\n return `## Heartbeat\n\nPoll for tasks. If nothing needs attention, reply: HEARTBEAT_OK\n\n_Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats._${quietHoursNote}\n`;\n }\n\n const content = stripFrontMatter(heartbeatFile.content);\n const truncated = truncateForPrompt(content, PROMPT_MAX_CHARS.HEARTBEAT);\n\n let quietHoursNote = '';\n if (userTimezone) {\n quietHoursNote = `\\n\\n> 💤 Quiet hours: The user is in **${userTimezone}**. Avoid proactive checks during late night (23:00-08:00) unless urgent.`;\n }\n\n return `## HEARTBEAT.md - Task Checklist\n\n${truncated}\n\n_Read HEARTBEAT.md for current tasks. If nothing needs attention, reply: HEARTBEAT_OK_${quietHoursNote}\n`;\n}\n\n/**\n * Build Memory section - recall instructions\n * \n * Before answering anything about prior work, decisions, dates, people, preferences, or todos: run memory_search\n */\nfunction buildMemorySection(\n bootstrapFiles: WorkspaceBootstrapFile[],\n citationsMode: MemoryCitationsMode = 'on',\n hasCuratedSnapshot = false,\n): string {\n const memoryFile = bootstrapFiles.find(f => f.name === DEFAULT_MEMORY_FILENAME);\n const hasWorkspaceMemoryFile = !!(memoryFile && !memoryFile.missing);\n\n if (!hasWorkspaceMemoryFile && !hasCuratedSnapshot) {\n return '';\n }\n\n const citationInstruction = 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 curatedLines = hasCuratedSnapshot\n ? `\n- **Curated store:** agent home \\`memories/MEMORY.md\\` and \\`memories/USER.md\\` — use \\`curated_memory\\` to add/replace/remove/read structured entries.`\n : '';\n\n return `## Memory Recall\n\n${citationInstruction}\n\nBefore answering anything about prior work, decisions, dates, people, preferences, or todos:\n1. Run \\`memory_search\\` on bootstrap MEMORY.md, agent-home \\`memories/*.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. If low confidence after search, say you checked\n\n### Memory Files\n\n- **Daily notes:** \\`memory/YYYY-MM-DD.md\\` — raw logs of what happened\n- **Long-term:** \\`MEMORY.md\\` — your curated memories, like a human's long-term memory${curatedLines}\n\n### Writing to Memory\n\n- **Declarative vs procedural:** Save **facts and preferences** (who the user is, how they want you to behave, stable environment) via workspace memory files and/or \\`curated_memory\\`. Save **reusable task playbooks** (steps, pitfalls, verification for a class of work) with \\`skill_manage\\` as skills — not as long prose in MEMORY.md.\n- **Memory is limited** — if you want to remember something, WRITE IT TO A FILE\n- \"Mental notes\" don't survive session restarts. Files do.\n- When someone says \"remember this\" → update \\`memory/YYYY-MM-DD.md\\` or relevant file\n- When you learn a lesson → update relevant files\n- When you make a mistake → document it so future-you doesn't repeat it\n- **Text > Brain** 📝\n`;\n}\n\n/**\n * Build Skills section - skill matching guidelines\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. (only references, templates, scripts, assets)\n4. No match? → Solve it yourself; do not force-fit a skill.\n\n**Principle:** Skills are tools, not shackles. If after reading one it does not fit, set it aside and proceed on your own.\n\n**Division of labor with memory:** Skills = **procedural** workflows (how to do a class of tasks); memory / \\`curated_memory\\` = **declarative** facts and preferences. After a complex task succeeds, you may codify it as a skill; user-profile-style information belongs in memory. When a skill is outdated or incomplete, fix it immediately with \\`skill_manage\\` (e.g. patch).\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\n/**\n * Build Problem Solving Workflow section\n *\n * Implements the \"Build & Self-Verify\" pattern from harness engineering.\n * Guides agents through an iterative problem-solving process with verification.\n *\n * Inspired by: https://blog.langchain.com/improving-deep-agents-with-harness-engineering/\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**Decision criteria:**\n- Multiple files or refactoring? → Plan first\n- Existing test coverage? → You must verify\n- Documentation or comments only? → Verification can be lighter\n- User says \"just take a quick look\"? → Skip ceremony; deliver the result directly\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\n/**\n * Build Aesthetic Guidelines section - tone and style preferences\n */\nfunction buildAestheticSection(): string {\n return `## Tone & Style\n\n**Default voice:**\n- Direct over diplomatic (\"This is broken\" beats \"This might be worth considering\")\n- Concise over exhaustive (do not expand on what the user did not ask for)\n- Concrete over abstract (use examples, not lectures)\n\n**Avoid LLM-isms:**\n- Do not open with \"This is a complex question...\"\n- Rarely use \"It is worth noting...\" / \"It is important to emphasize...\"\n- Not every sentence needs bullets; natural paragraphs are fine\n- Do not wrap a simple takeaway in a four-step framework\n\n**SOUL.md takes precedence:** If SOUL.md defines a specific tone, defer to it over the above.\n`;\n}\nfunction buildMessagingSection(\n channels: string[] = [],\n isMinimal: boolean = false\n): string {\n if (isMinimal || channels.length === 0) {\n return '';\n }\n\n const channelList = channels.join(', ');\n\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\n/**\n * Build Time section - user timezone\n */\nfunction buildTimeSection(timezone?: string): string {\n if (!timezone) {\n return '';\n }\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\n/**\n * Build Runtime section - version info\n */\nfunction buildRuntimeSection(runtime?: { version?: string; model?: string; channel?: string }): string {\n if (!runtime) {\n return '';\n }\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\n return parts.length > 0 ? `[${parts.join(' | ')}]` : '';\n}\n\n/**\n * Build Working Directory section\n */\nfunction buildWorkingDirSection(workspaceDir: string): string {\n return `Working directory: ${workspaceDir}`;\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\n/**\n * Truncate content for prompt injection\n * Keeps head and tail to preserve context\n */\nfunction truncateForPrompt(content: string, maxChars: number): string {\n const trimmed = content.trimEnd();\n if (trimmed.length <= maxChars) {\n return trimmed;\n }\n\n // Keep head (70%) and tail (20%) with marker\n const headChars = Math.floor(maxChars * 0.7);\n const tailChars = Math.floor(maxChars * 0.2);\n const head = trimmed.slice(0, headChars);\n const tail = trimmed.slice(-tailChars);\n\n return `${head}\n\n[...]${tail}`;\n}\n\n// =============================================================================\n// Main Builder\n// =============================================================================\n\n/**\n * Build system prompt with workspace context integration\n * \n * Injects workspace files at appropriate positions in the system prompt.\n */\nexport function buildSystemPrompt(\n workspaceDir: string,\n options: SystemPromptOptions\n): string {\n const {\n bootstrapFiles,\n promptMode = 'full',\n heartbeatEnabled = false,\n heartbeatPrompt,\n availableTools = [],\n memoryCitationsMode = 'on',\n userTimezone,\n runtime,\n channels = [],\n curatedMemorySnapshot,\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\n const curatedUserFrozen = !!(curatedMemorySnapshot?.user?.trim());\n const hasCuratedSnapshot = !!(\n curatedMemorySnapshot?.memory?.trim() || curatedMemorySnapshot?.user?.trim()\n );\n\n const sections: string[] = [];\n\n // 1. Identity and persona (non-minimal only)\n if (!isMinimal) {\n sections.push(buildIdentitySection(bootstrapFiles));\n sections.push(buildSoulSection(bootstrapFiles));\n }\n\n // 2. Curated memory snapshot (non-minimal; frozen at session start)\n if (!isMinimal) {\n sections.push(buildCuratedMemorySection(curatedMemorySnapshot));\n }\n\n // 2b. External memory provider\n if (!isMinimal) {\n sections.push(buildExternalMemorySection(externalMemoryInstructions));\n }\n\n // 3. User context — workspace USER.md unless curated user block is active\n if (!isMinimal && !curatedUserFrozen) {\n sections.push(buildUserSection(bootstrapFiles));\n }\n\n // 4. Time (non-minimal only)\n if (!isMinimal) {\n sections.push(buildTimeSection(userTimezone));\n }\n\n // 5. Memory section (non-minimal only)\n if (!isMinimal) {\n sections.push(buildMemorySection(bootstrapFiles, memoryCitationsMode, hasCuratedSnapshot));\n }\n\n // 6. Skills\n sections.push(buildSkillsSection(availableTools));\n\n // 6b. Safety (non-minimal only)\n if (!isMinimal) {\n sections.push(buildSafetySection());\n }\n\n // 7. Problem Solving Workflow (non-minimal only) - Harness Engineering\n if (!isMinimal) {\n sections.push(buildProblemSolvingSection());\n }\n\n // 8. Aesthetic Guidelines (non-minimal only)\n if (!isMinimal) {\n sections.push(buildAestheticSection());\n }\n\n // Cache boundary — stable content above is a better prompt-cache prefix for supported providers\n sections.push(PROMPT_CACHE_BOUNDARY);\n\n // 9. Heartbeat\n sections.push(buildHeartbeatSection(bootstrapFiles, heartbeatEnabled, heartbeatPrompt, userTimezone));\n\n // 10. Working directory\n sections.push(buildWorkingDirSection(workspaceDir));\n\n // 11. Tools (non-minimal only)\n if (!isMinimal) {\n sections.push(buildToolsSection(bootstrapFiles));\n }\n\n // 12. Agents guidelines\n sections.push(buildAgentsSection(bootstrapFiles));\n\n // 13. Messaging\n sections.push(buildMessagingSection(channels, isMinimal));\n\n // 13b. Voice (TTS)\n if (!isMinimal && ttsSystemHint?.trim()) {\n sections.push(`## Voice (TTS)\\n\\n${ttsSystemHint.trim()}`);\n }\n\n // 14. Runtime info\n sections.push(buildRuntimeSection(runtime));\n\n // Filter out empty sections and join\n return sections.filter(Boolean).join('\\n\\n');\n}\n\n/**\n * Build minimal system prompt for subagents/cron jobs (Internal)\n */\nfunction _buildMinimalSystemPrompt(\n workspaceDir: string,\n bootstrapFiles: WorkspaceBootstrapFile[]\n): string {\n return buildSystemPrompt(workspaceDir, {\n bootstrapFiles,\n promptMode: 'minimal',\n heartbeatEnabled: false,\n });\n}\n\n/**\n * Get bootstrap file by name (Internal)\n */\nfunction _getBootstrapFile(\n bootstrapFiles: WorkspaceBootstrapFile[],\n name: string\n): WorkspaceBootstrapFile | undefined {\n return bootstrapFiles.find(f => f.name === name);\n}\n\n/**\n * Check if specific bootstrap file exists and is loaded (Internal)\n */\nfunction _hasBootstrapFile(\n bootstrapFiles: WorkspaceBootstrapFile[],\n name: string\n): boolean {\n const file = bootstrapFiles.find(f => f.name === name);\n return !!file && !file.missing && !!file.content;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SessionStore } from '../../session/index.js';
|
|
2
|
+
type BtwLog = {
|
|
3
|
+
warn: (obj: Record<string, unknown>, msg: string) => void;
|
|
4
|
+
};
|
|
5
|
+
/** One-shot LLM answer for /btw: transcript as background only; does not persist. */
|
|
6
|
+
export declare function runBtwQuery(opts: {
|
|
7
|
+
sessionKey: string;
|
|
8
|
+
question: string;
|
|
9
|
+
sessionStore: SessionStore;
|
|
10
|
+
modelForSession: string;
|
|
11
|
+
log: BtwLog;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
text: string;
|
|
14
|
+
error?: string;
|
|
15
|
+
}>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
2
|
+
import { complete } from "@mariozechner/pi-ai";
|
|
3
|
+
//#region src/agent/service/btw-query.ts
|
|
4
|
+
init_providers();
|
|
5
|
+
function formatMessagesForBtw(messages) {
|
|
6
|
+
return messages.map((m) => {
|
|
7
|
+
const role = m.role;
|
|
8
|
+
let body = "";
|
|
9
|
+
if (typeof m.content === "string") body = m.content;
|
|
10
|
+
else if (Array.isArray(m.content)) body = m.content.filter((c) => c.type === "text").map((c) => c.text || "").join("\n");
|
|
11
|
+
const line = `[${role}]: ${body}`;
|
|
12
|
+
return line.length > 4e3 ? `${line.slice(0, 4e3)}…` : line;
|
|
13
|
+
}).join("\n\n");
|
|
14
|
+
}
|
|
15
|
+
/** One-shot LLM answer for /btw: transcript as background only; does not persist. */
|
|
16
|
+
async function runBtwQuery(opts) {
|
|
17
|
+
const q = opts.question.trim();
|
|
18
|
+
if (!q) return {
|
|
19
|
+
text: "",
|
|
20
|
+
error: "Empty question."
|
|
21
|
+
};
|
|
22
|
+
const messages = await opts.sessionStore.load(opts.sessionKey);
|
|
23
|
+
const modelRef = opts.modelForSession;
|
|
24
|
+
let model;
|
|
25
|
+
try {
|
|
26
|
+
model = resolveModel(modelRef);
|
|
27
|
+
} catch (err) {
|
|
28
|
+
const em = err instanceof Error ? err.message : String(err);
|
|
29
|
+
opts.log.warn({
|
|
30
|
+
err,
|
|
31
|
+
modelRef,
|
|
32
|
+
errorMessage: em
|
|
33
|
+
}, "btwQuery: model resolve failed");
|
|
34
|
+
return {
|
|
35
|
+
text: "",
|
|
36
|
+
error: `Could not resolve model: ${modelRef}`
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const background = formatMessagesForBtw(messages.slice(-40));
|
|
40
|
+
const userMessage = {
|
|
41
|
+
role: "user",
|
|
42
|
+
content: [
|
|
43
|
+
[
|
|
44
|
+
"You are answering an ephemeral /btw side question about the current conversation.",
|
|
45
|
+
"Use the conversation only as background context.",
|
|
46
|
+
"Answer only the side question. Do not continue or complete any unfinished task from the conversation.",
|
|
47
|
+
"Do not use tools, shell, or file writes unless the question explicitly requires a tiny code snippet.",
|
|
48
|
+
"If the question can be answered briefly, answer briefly."
|
|
49
|
+
].join("\n"),
|
|
50
|
+
"",
|
|
51
|
+
"---",
|
|
52
|
+
"Conversation background (read-only):",
|
|
53
|
+
background || "(empty)",
|
|
54
|
+
"",
|
|
55
|
+
"---",
|
|
56
|
+
"Side question:",
|
|
57
|
+
q
|
|
58
|
+
].join("\n"),
|
|
59
|
+
timestamp: Date.now()
|
|
60
|
+
};
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timeoutId = setTimeout(() => controller.abort(), 9e4);
|
|
63
|
+
try {
|
|
64
|
+
const out = await complete(model, { messages: [userMessage] }, {
|
|
65
|
+
maxTokens: 2048,
|
|
66
|
+
temperature: .4,
|
|
67
|
+
signal: controller.signal
|
|
68
|
+
});
|
|
69
|
+
return { text: (Array.isArray(out.content) ? out.content.filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text || "").join("") : "").trim() };
|
|
70
|
+
} catch (err) {
|
|
71
|
+
const em = err instanceof Error ? err.message : String(err);
|
|
72
|
+
opts.log.warn({
|
|
73
|
+
err,
|
|
74
|
+
sessionKey: opts.sessionKey,
|
|
75
|
+
errorMessage: em
|
|
76
|
+
}, "btwQuery failed");
|
|
77
|
+
return {
|
|
78
|
+
text: "",
|
|
79
|
+
error: em
|
|
80
|
+
};
|
|
81
|
+
} finally {
|
|
82
|
+
clearTimeout(timeoutId);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { runBtwQuery };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=btw-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"btw-query.js","names":[],"sources":["../../../../src/agent/service/btw-query.ts"],"sourcesContent":["import type { AgentMessage } from '@mariozechner/pi-agent-core';\nimport { complete, type UserMessage } from '@mariozechner/pi-ai';\n\nimport type { SessionStore } from '../../session/index.js';\nimport { resolveModel } from '../../providers/index.js';\n\ntype BtwLog = { warn: (obj: Record<string, unknown>, msg: string) => void };\n\nfunction formatMessagesForBtw(messages: AgentMessage[]): string {\n return messages\n .map((m) => {\n const role = m.role;\n let body = '';\n if (typeof m.content === 'string') {\n body = m.content;\n } else if (Array.isArray(m.content)) {\n body = m.content\n .filter((c): c is { type: 'text'; text: string } => c.type === 'text')\n .map((c) => c.text || '')\n .join('\\n');\n }\n const line = `[${role}]: ${body}`;\n return line.length > 4000 ? `${line.slice(0, 4000)}…` : line;\n })\n .join('\\n\\n');\n}\n\n/** One-shot LLM answer for /btw: transcript as background only; does not persist. */\nexport async function runBtwQuery(opts: {\n sessionKey: string;\n question: string;\n sessionStore: SessionStore;\n modelForSession: string;\n log: BtwLog;\n}): Promise<{ text: string; error?: string }> {\n const q = opts.question.trim();\n if (!q) {\n return { text: '', error: 'Empty question.' };\n }\n const messages = await opts.sessionStore.load(opts.sessionKey);\n const modelRef = opts.modelForSession;\n let model;\n try {\n model = resolveModel(modelRef);\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n opts.log.warn({ err, modelRef, errorMessage: em }, 'btwQuery: model resolve failed');\n return { text: '', error: `Could not resolve model: ${modelRef}` };\n }\n\n const background = formatMessagesForBtw(messages.slice(-40));\n const systemBlock = [\n 'You are answering an ephemeral /btw side question about the current conversation.',\n 'Use the conversation only as background context.',\n 'Answer only the side question. Do not continue or complete any unfinished task from the conversation.',\n 'Do not use tools, shell, or file writes unless the question explicitly requires a tiny code snippet.',\n 'If the question can be answered briefly, answer briefly.',\n ].join('\\n');\n\n const userPrompt = [\n systemBlock,\n '',\n '---',\n 'Conversation background (read-only):',\n background || '(empty)',\n '',\n '---',\n 'Side question:',\n q,\n ].join('\\n');\n\n const userMessage: UserMessage = { role: 'user', content: userPrompt, timestamp: Date.now() };\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 90_000);\n try {\n const out = await complete(model, { messages: [userMessage] }, {\n maxTokens: 2048,\n temperature: 0.4,\n signal: controller.signal as AbortSignal,\n });\n const text = Array.isArray(out.content)\n ? out.content\n .filter(\n (c): c is { type: 'text'; text: string } =>\n c.type === 'text' && typeof (c as { text?: unknown }).text === 'string',\n )\n .map((c) => c.text || '')\n .join('')\n : '';\n return { text: text.trim() };\n } catch (err) {\n const em = err instanceof Error ? err.message : String(err);\n opts.log.warn({ err, sessionKey: opts.sessionKey, errorMessage: em }, 'btwQuery failed');\n return { text: '', error: em };\n } finally {\n clearTimeout(timeoutId);\n }\n}\n"],"mappings":";;;gBAIwD;AAIxD,SAAS,qBAAqB,UAAkC;AAC9D,QAAO,SACJ,KAAK,MAAM;EACV,MAAM,OAAO,EAAE;EACf,IAAI,OAAO;AACX,MAAI,OAAO,EAAE,YAAY,SACvB,QAAO,EAAE;WACA,MAAM,QAAQ,EAAE,QAAQ,CACjC,QAAO,EAAE,QACN,QAAQ,MAA2C,EAAE,SAAS,OAAO,CACrE,KAAK,MAAM,EAAE,QAAQ,GAAG,CACxB,KAAK,KAAK;EAEf,MAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,SAAO,KAAK,SAAS,MAAO,GAAG,KAAK,MAAM,GAAG,IAAK,CAAC,KAAK;GACxD,CACD,KAAK,OAAO;;;AAIjB,eAAsB,YAAY,MAMY;CAC5C,MAAM,IAAI,KAAK,SAAS,MAAM;AAC9B,KAAI,CAAC,EACH,QAAO;EAAE,MAAM;EAAI,OAAO;EAAmB;CAE/C,MAAM,WAAW,MAAM,KAAK,aAAa,KAAK,KAAK,WAAW;CAC9D,MAAM,WAAW,KAAK;CACtB,IAAI;AACJ,KAAI;AACF,UAAQ,aAAa,SAAS;UACvB,KAAK;EACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,OAAK,IAAI,KAAK;GAAE;GAAK;GAAU,cAAc;GAAI,EAAE,iCAAiC;AACpF,SAAO;GAAE,MAAM;GAAI,OAAO,4BAA4B;GAAY;;CAGpE,MAAM,aAAa,qBAAqB,SAAS,MAAM,IAAI,CAAC;CAqB5D,MAAM,cAA2B;EAAE,MAAM;EAAQ,SAZ9B;GARC;IAClB;IACA;IACA;IACA;IACA;IACD,CAAC,KAAK,KAGM;GACX;GACA;GACA;GACA,cAAc;GACd;GACA;GACA;GACA;GACD,CAAC,KAAK,KAE6D;EAAE,WAAW,KAAK,KAAK;EAAE;CAC7F,MAAM,aAAa,IAAI,iBAAiB;CACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,IAAO;AAC9D,KAAI;EACF,MAAM,MAAM,MAAM,SAAS,OAAO,EAAE,UAAU,CAAC,YAAY,EAAE,EAAE;GAC7D,WAAW;GACX,aAAa;GACb,QAAQ,WAAW;GACpB,CAAC;AAUF,SAAO,EAAE,OATI,MAAM,QAAQ,IAAI,QAAQ,GACnC,IAAI,QACD,QACE,MACC,EAAE,SAAS,UAAU,OAAQ,EAAyB,SAAS,SAClE,CACA,KAAK,MAAM,EAAE,QAAQ,GAAG,CACxB,KAAK,GAAG,GACX,IACgB,MAAM,EAAE;UACrB,KAAK;EACZ,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC3D,OAAK,IAAI,KAAK;GAAE;GAAK,YAAY,KAAK;GAAY,cAAc;GAAI,EAAE,kBAAkB;AACxF,SAAO;GAAE,MAAM;GAAI,OAAO;GAAI;WACtB;AACR,eAAa,UAAU"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
import type { AgentManager } from '../agent-manager.js';
|
|
3
|
+
import type { ModelManager } from '../models/index.js';
|
|
4
|
+
export type DirectInboundAttachment = {
|
|
5
|
+
type: string;
|
|
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
|
+
*/
|
|
23
|
+
export declare function buildDirectUserMessageContent(opts: {
|
|
24
|
+
content: string;
|
|
25
|
+
attachments?: DirectInboundAttachment[];
|
|
26
|
+
sessionKey?: string;
|
|
27
|
+
config: Config;
|
|
28
|
+
agentManager: AgentManager;
|
|
29
|
+
modelManager: ModelManager;
|
|
30
|
+
}): Promise<DirectMessagePart[]>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { init_agent_scope, resolveAgentHomeDir, resolveDefaultAgentId } from "../agent-scope.js";
|
|
2
|
+
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
3
|
+
import { extractProfileAgentId } from "../../config/agent-profile.js";
|
|
4
|
+
import { getDefaultModelSync, init_providers } from "../../providers/index.js";
|
|
5
|
+
import { formatInboundFileTextBlock } from "../../channels/attachments/inbound-persist.js";
|
|
6
|
+
import { expandAtFileMentionsInPlainText } from "../context/expand-at-file-mentions.js";
|
|
7
|
+
import { resolveInboundImageContentParts } from "../image/inbound-image-handling.js";
|
|
8
|
+
//#region src/agent/service/build-direct-message-content.ts
|
|
9
|
+
init_schema();
|
|
10
|
+
init_providers();
|
|
11
|
+
init_agent_scope();
|
|
12
|
+
/**
|
|
13
|
+
* Build user message parts (text + resolved images/files) for direct / webchat turns.
|
|
14
|
+
*/
|
|
15
|
+
async function buildDirectUserMessageContent(opts) {
|
|
16
|
+
const { content, attachments, sessionKey, config, agentManager, modelManager } = opts;
|
|
17
|
+
const messageContent = [];
|
|
18
|
+
const sk = sessionKey ?? "";
|
|
19
|
+
if (content.trim()) {
|
|
20
|
+
let textPart = content;
|
|
21
|
+
if (/@file:/.test(textPart)) {
|
|
22
|
+
const wsKey = sk !== "" ? sk : "cli:direct";
|
|
23
|
+
const root = agentManager.getResolvedWorkspaceForSession(wsKey);
|
|
24
|
+
textPart = await expandAtFileMentionsInPlainText(textPart, root);
|
|
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;
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
export { buildDirectUserMessageContent };
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=build-direct-message-content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-direct-message-content.js","names":[],"sources":["../../../../src/agent/service/build-direct-message-content.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { getDefaultModelSync } from '../../providers/index.js';\nimport { formatInboundFileTextBlock } from '../../channels/attachments/inbound-persist.js';\nimport { expandAtFileMentionsInPlainText } from '../context/expand-at-file-mentions.js';\nimport { resolveInboundImageContentParts } from '../image/inbound-image-handling.js';\nimport { resolveAgentHomeDir, resolveDefaultAgentId } from '../agent-scope.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\nimport type { AgentManager } from '../agent-manager.js';\nimport type { ModelManager } from '../models/index.js';\n\nexport type DirectInboundAttachment = {\n type: string;\n mimeType?: string;\n data?: string;\n name?: string;\n size?: number;\n workspaceRelativePath?: string;\n};\n\nexport type DirectMessagePart =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string };\n\n/**\n * Build user message parts (text + resolved images/files) for direct / webchat turns.\n */\nexport async function buildDirectUserMessageContent(opts: {\n content: string;\n attachments?: DirectInboundAttachment[];\n sessionKey?: string;\n config: Config;\n agentManager: AgentManager;\n modelManager: ModelManager;\n}): Promise<DirectMessagePart[]> {\n const { content, attachments, sessionKey, config, agentManager, modelManager } = opts;\n const messageContent: DirectMessagePart[] = [];\n const sk = sessionKey ?? '';\n\n if (content.trim()) {\n let textPart = content;\n if (/@file:/.test(textPart)) {\n const wsKey = sk !== '' ? sk : 'cli:direct';\n const root = agentManager.getResolvedWorkspaceForSession(wsKey);\n textPart = await expandAtFileMentionsInPlainText(textPart, root);\n }\n messageContent.push({ type: 'text', text: textPart });\n }\n\n if (!attachments?.length) {\n return messageContent;\n }\n\n const modelRef =\n sk !== ''\n ? modelManager.getModelForSession(sk)\n : getAgentDefaultModelRef(config) ?? getDefaultModelSync(config);\n\n const storageRoot =\n sk !== ''\n ? resolveAgentHomeDir(config, extractProfileAgentId(sk, config))\n : resolveAgentHomeDir(config, resolveDefaultAgentId(config));\n\n let i = 0;\n while (i < attachments.length) {\n const att = attachments[i]!;\n const isImage =\n att.type === 'image' ||\n att.type === 'photo' ||\n 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 = 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 i += 1;\n continue;\n }\n group.push({ data: a.data, mimeType: a.mimeType || 'image/png' });\n i += 1;\n }\n if (group.length > 0) {\n const parts = await resolveInboundImageContentParts({\n modelRef: modelRef || getDefaultModelSync(config),\n cfg: config,\n userTextForContext: content.trim() ? content : '',\n images: group,\n });\n messageContent.push(...parts);\n }\n } else {\n const fileBlock = formatInboundFileTextBlock(att, storageRoot);\n messageContent.push({ type: 'text', text: fileBlock });\n i += 1;\n }\n }\n\n return messageContent;\n}\n"],"mappings":";;;;;;;;aACiE;gBACF;kBAIgB;;;;AAqB/E,eAAsB,8BAA8B,MAOnB;CAC/B,MAAM,EAAE,SAAS,aAAa,YAAY,QAAQ,cAAc,iBAAiB;CACjF,MAAM,iBAAsC,EAAE;CAC9C,MAAM,KAAK,cAAc;AAEzB,KAAI,QAAQ,MAAM,EAAE;EAClB,IAAI,WAAW;AACf,MAAI,SAAS,KAAK,SAAS,EAAE;GAC3B,MAAM,QAAQ,OAAO,KAAK,KAAK;GAC/B,MAAM,OAAO,aAAa,+BAA+B,MAAM;AAC/D,cAAW,MAAM,gCAAgC,UAAU,KAAK;;AAElE,iBAAe,KAAK;GAAE,MAAM;GAAQ,MAAM;GAAU,CAAC;;AAGvD,KAAI,CAAC,aAAa,OAChB,QAAO;CAGT,MAAM,WACJ,OAAO,KACH,aAAa,mBAAmB,GAAG,GACnC,wBAAwB,OAAO,IAAI,oBAAoB,OAAO;CAEpE,MAAM,cACJ,OAAO,KACH,oBAAoB,QAAQ,sBAAsB,IAAI,OAAO,CAAC,GAC9D,oBAAoB,QAAQ,sBAAsB,OAAO,CAAC;CAEhE,IAAI,IAAI;AACR,QAAO,IAAI,YAAY,QAAQ;EAC7B,MAAM,MAAM,YAAY;AAMxB,MAJE,IAAI,SAAS,WACb,IAAI,SAAS,WACb,QAAQ,IAAI,UAAU,WAAW,SAAS,CAAC,EAEhC;GACX,MAAM,QAAmD,EAAE;AAC3D,UAAO,IAAI,YAAY,QAAQ;IAC7B,MAAM,IAAI,YAAY;AAEtB,QAAI,EADQ,EAAE,SAAS,WAAW,EAAE,SAAS,WAAW,QAAQ,EAAE,UAAU,WAAW,SAAS,CAAC,EAE/F;AAEF,QAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,WAAW,GAAG;AAClC,UAAK;AACL;;AAEF,UAAM,KAAK;KAAE,MAAM,EAAE;KAAM,UAAU,EAAE,YAAY;KAAa,CAAC;AACjE,SAAK;;AAEP,OAAI,MAAM,SAAS,GAAG;IACpB,MAAM,QAAQ,MAAM,gCAAgC;KAClD,UAAU,YAAY,oBAAoB,OAAO;KACjD,KAAK;KACL,oBAAoB,QAAQ,MAAM,GAAG,UAAU;KAC/C,QAAQ;KACT,CAAC;AACF,mBAAe,KAAK,GAAG,MAAM;;SAE1B;GACL,MAAM,YAAY,2BAA2B,KAAK,YAAY;AAC9D,kBAAe,KAAK;IAAE,MAAM;IAAQ,MAAM;IAAW,CAAC;AACtD,QAAK;;;AAIT,QAAO"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Map a session key to outbound channel routing (heartbeat/cron/virtual keys included).
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseOutboundSessionKey(sessionKey: string, config: Config | undefined): {
|
|
6
|
+
channel: string;
|
|
7
|
+
chatId: string;
|
|
8
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
|
|
2
|
+
import { INTERNAL_OUTBOUND_DROP_CHANNEL } from "../../channels/internal-outbound.js";
|
|
3
|
+
//#region src/agent/service/parse-outbound-session-key.ts
|
|
4
|
+
init_session_key();
|
|
5
|
+
/**
|
|
6
|
+
* Map a session key to outbound channel routing (heartbeat/cron/virtual keys included).
|
|
7
|
+
*/
|
|
8
|
+
function parseOutboundSessionKey(sessionKey, config) {
|
|
9
|
+
const parts = sessionKey.split(":").filter(Boolean);
|
|
10
|
+
const first = parts[0] || "cli";
|
|
11
|
+
if (first === "heartbeat") {
|
|
12
|
+
const hb = config?.gateway?.heartbeat;
|
|
13
|
+
const target = hb?.target?.trim();
|
|
14
|
+
const targetChatId = hb?.targetChatId?.trim();
|
|
15
|
+
if (target && targetChatId) return {
|
|
16
|
+
channel: target,
|
|
17
|
+
chatId: targetChatId
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
channel: INTERNAL_OUTBOUND_DROP_CHANNEL,
|
|
21
|
+
chatId: parts.slice(1).join(":") || "heartbeat"
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const parsed = parseSessionKey(sessionKey);
|
|
25
|
+
if (parsed) return {
|
|
26
|
+
channel: parsed.source,
|
|
27
|
+
chatId: parsed.peerId
|
|
28
|
+
};
|
|
29
|
+
if (first === "cron") return {
|
|
30
|
+
channel: INTERNAL_OUTBOUND_DROP_CHANNEL,
|
|
31
|
+
chatId: parts.slice(1).join(":") || "cron"
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
channel: first,
|
|
35
|
+
chatId: parts.slice(1).join(":") || "direct"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { parseOutboundSessionKey };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=parse-outbound-session-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-outbound-session-key.js","names":["parseRoutingSessionKey"],"sources":["../../../../src/agent/service/parse-outbound-session-key.ts"],"sourcesContent":["import type { Config } from '../../config/schema.js';\nimport { INTERNAL_OUTBOUND_DROP_CHANNEL } from '../../channels/internal-outbound.js';\nimport { parseSessionKey as parseRoutingSessionKey } from '../../routing/session-key.js';\n\n/**\n * Map a session key to outbound channel routing (heartbeat/cron/virtual keys included).\n */\nexport function parseOutboundSessionKey(\n sessionKey: string,\n config: Config | undefined,\n): { channel: string; chatId: string } {\n const parts = sessionKey.split(':').filter(Boolean);\n const first = parts[0] || 'cli';\n\n if (first === 'heartbeat') {\n const hb = config?.gateway?.heartbeat;\n const target = hb?.target?.trim();\n const targetChatId = hb?.targetChatId?.trim();\n if (target && targetChatId) {\n return { channel: target, chatId: targetChatId };\n }\n return { channel: INTERNAL_OUTBOUND_DROP_CHANNEL, chatId: parts.slice(1).join(':') || 'heartbeat' };\n }\n\n const parsed = parseRoutingSessionKey(sessionKey);\n if (parsed) {\n return { channel: parsed.source, chatId: parsed.peerId };\n }\n\n if (first === 'cron') {\n return { channel: INTERNAL_OUTBOUND_DROP_CHANNEL, chatId: parts.slice(1).join(':') || 'cron' };\n }\n\n return {\n channel: first,\n chatId: parts.slice(1).join(':') || 'direct',\n };\n}\n"],"mappings":";;;kBAEyF;;;;AAKzF,SAAgB,wBACd,YACA,QACqC;CACrC,MAAM,QAAQ,WAAW,MAAM,IAAI,CAAC,OAAO,QAAQ;CACnD,MAAM,QAAQ,MAAM,MAAM;AAE1B,KAAI,UAAU,aAAa;EACzB,MAAM,KAAK,QAAQ,SAAS;EAC5B,MAAM,SAAS,IAAI,QAAQ,MAAM;EACjC,MAAM,eAAe,IAAI,cAAc,MAAM;AAC7C,MAAI,UAAU,aACZ,QAAO;GAAE,SAAS;GAAQ,QAAQ;GAAc;AAElD,SAAO;GAAE,SAAS;GAAgC,QAAQ,MAAM,MAAM,EAAE,CAAC,KAAK,IAAI,IAAI;GAAa;;CAGrG,MAAM,SAASA,gBAAuB,WAAW;AACjD,KAAI,OACF,QAAO;EAAE,SAAS,OAAO;EAAQ,QAAQ,OAAO;EAAQ;AAG1D,KAAI,UAAU,OACZ,QAAO;EAAE,SAAS;EAAgC,QAAQ,MAAM,MAAM,EAAE,CAAC,KAAK,IAAI,IAAI;EAAQ;AAGhG,QAAO;EACL,SAAS;EACT,QAAQ,MAAM,MAAM,EAAE,CAAC,KAAK,IAAI,IAAI;EACrC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AgentMessage } from '@mariozechner/pi-agent-core';
|
|
2
|
+
import type { CommandHandler } from '../messaging/command-handler.js';
|
|
3
|
+
import type { ProcessDirectStreamLog } from './process-direct-streaming.js';
|
|
4
|
+
import type { AgentManager } from '../agent-manager.js';
|
|
5
|
+
import type { ModelManager } from '../models/index.js';
|
|
6
|
+
import type { SessionStore } from '../../session/index.js';
|
|
7
|
+
import type { Config } from '../../config/schema.js';
|
|
8
|
+
import { type DirectInboundAttachment } from './build-direct-message-content.js';
|
|
9
|
+
export type RunProcessDirectDeps = {
|
|
10
|
+
log: ProcessDirectStreamLog;
|
|
11
|
+
config: Config;
|
|
12
|
+
parseSessionKey: (sessionKey: string) => {
|
|
13
|
+
channel: string;
|
|
14
|
+
chatId: string;
|
|
15
|
+
};
|
|
16
|
+
initSessionContext: (sessionKey: string, channel: string, chatId: string) => void;
|
|
17
|
+
hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;
|
|
18
|
+
hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;
|
|
19
|
+
agentManager: AgentManager;
|
|
20
|
+
sessionStore: SessionStore;
|
|
21
|
+
prepareLoadedSessionMessages: (sessionKey: string, messages: AgentMessage[]) => AgentMessage[];
|
|
22
|
+
modelManager: ModelManager;
|
|
23
|
+
applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;
|
|
24
|
+
prepareInboundAttachments: (sessionKey: string, attachments?: DirectInboundAttachment[]) => Promise<DirectInboundAttachment[] | undefined>;
|
|
25
|
+
commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;
|
|
26
|
+
persistAgentSessionMessages: (sessionKey: string) => Promise<void>;
|
|
27
|
+
endDirectRequestContext: () => void;
|
|
28
|
+
};
|
|
29
|
+
export declare function runProcessDirect(deps: RunProcessDirectDeps, input: {
|
|
30
|
+
content: string;
|
|
31
|
+
sessionKey: string;
|
|
32
|
+
attachments?: DirectInboundAttachment[];
|
|
33
|
+
thinking?: string;
|
|
34
|
+
}): Promise<string>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { extractAgentUserPlainText } from "../memory/user-message-text.js";
|
|
2
|
+
import { parseSlashCommand } from "../../chat-commands/command-parse.js";
|
|
3
|
+
import { commandRegistry } from "../../chat-commands/registry.js";
|
|
4
|
+
import "../../chat-commands/index.js";
|
|
5
|
+
import { runAgentTurnWithModelFallbacks } from "../orchestration/run-agent-turn-with-fallbacks.js";
|
|
6
|
+
import { buildDirectUserMessageContent } from "./build-direct-message-content.js";
|
|
7
|
+
//#region src/agent/service/process-direct-one-shot.ts
|
|
8
|
+
async function runProcessDirect(deps, input) {
|
|
9
|
+
const { channel, chatId } = deps.parseSessionKey(input.sessionKey);
|
|
10
|
+
deps.initSessionContext(input.sessionKey, channel, chatId);
|
|
11
|
+
try {
|
|
12
|
+
await deps.hydrateSessionWorkspaceFromStore(input.sessionKey);
|
|
13
|
+
const agent = deps.agentManager.getOrCreateAgent(input.sessionKey);
|
|
14
|
+
await deps.hydrateSessionModelFromStore(input.sessionKey);
|
|
15
|
+
const loaded = await deps.sessionStore.load(input.sessionKey);
|
|
16
|
+
agent.state.messages = deps.prepareLoadedSessionMessages(input.sessionKey, loaded);
|
|
17
|
+
await deps.modelManager.applyModelForSession(agent, input.sessionKey);
|
|
18
|
+
await deps.applyResolvedThinkingLevel(input.sessionKey, input.thinking);
|
|
19
|
+
const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);
|
|
20
|
+
const cmd = parseSlashCommand(input.content);
|
|
21
|
+
if (cmd && commandRegistry.has(cmd.command)) {
|
|
22
|
+
const { aggregatedText } = await deps.commandHandler.executeCommandAndAggregateReply(cmd.command, cmd.args, {
|
|
23
|
+
sessionKey: input.sessionKey,
|
|
24
|
+
channel,
|
|
25
|
+
chatId,
|
|
26
|
+
senderId: "",
|
|
27
|
+
isGroup: false
|
|
28
|
+
});
|
|
29
|
+
await deps.persistAgentSessionMessages(input.sessionKey);
|
|
30
|
+
return aggregatedText;
|
|
31
|
+
}
|
|
32
|
+
const userMessage = {
|
|
33
|
+
role: "user",
|
|
34
|
+
content: await buildDirectUserMessageContent({
|
|
35
|
+
content: input.content.trimStart().startsWith("/skill:") ? deps.agentManager.expandSkillUserText(input.content) : input.content,
|
|
36
|
+
attachments: prepared,
|
|
37
|
+
sessionKey: input.sessionKey,
|
|
38
|
+
config: deps.config,
|
|
39
|
+
agentManager: deps.agentManager,
|
|
40
|
+
modelManager: deps.modelManager
|
|
41
|
+
}),
|
|
42
|
+
timestamp: Date.now()
|
|
43
|
+
};
|
|
44
|
+
const userPlain = extractAgentUserPlainText(userMessage);
|
|
45
|
+
const userMessageForModel = await deps.agentManager.applyMemoryPrefetchToUserMessage(userMessage, input.sessionKey);
|
|
46
|
+
await runAgentTurnWithModelFallbacks({
|
|
47
|
+
agent,
|
|
48
|
+
sessionKey: input.sessionKey,
|
|
49
|
+
modelManager: deps.modelManager,
|
|
50
|
+
userMessage: userMessageForModel,
|
|
51
|
+
log: deps.log,
|
|
52
|
+
getConfig: () => deps.config,
|
|
53
|
+
beforeUserPrompt: () => deps.agentManager.beginBackgroundReviewUserTurn(input.sessionKey)
|
|
54
|
+
});
|
|
55
|
+
deps.agentManager.afterAgentTurn(input.sessionKey, userPlain);
|
|
56
|
+
deps.agentManager.scheduleBackgroundReviewAfterUserTurn(input.sessionKey);
|
|
57
|
+
const response = deps.agentManager.getLastAssistantContent(input.sessionKey) || "";
|
|
58
|
+
await deps.persistAgentSessionMessages(input.sessionKey);
|
|
59
|
+
return response;
|
|
60
|
+
} finally {
|
|
61
|
+
deps.endDirectRequestContext();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { runProcessDirect };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=process-direct-one-shot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-direct-one-shot.js","names":[],"sources":["../../../../src/agent/service/process-direct-one-shot.ts"],"sourcesContent":["import type { AgentMessage } from '@mariozechner/pi-agent-core';\n\nimport { parseSlashCommand } from '../../chat-commands/command-parse.js';\nimport { commandRegistry } from '../../chat-commands/index.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport { extractAgentUserPlainText } from '../memory/user-message-text.js';\nimport { runAgentTurnWithModelFallbacks } from '../orchestration/run-agent-turn-with-fallbacks.js';\nimport type { ProcessDirectStreamLog } from './process-direct-streaming.js';\nimport type { AgentManager } from '../agent-manager.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport { buildDirectUserMessageContent, type DirectInboundAttachment } from './build-direct-message-content.js';\n\nexport type RunProcessDirectDeps = {\n log: ProcessDirectStreamLog;\n config: Config;\n parseSessionKey: (sessionKey: string) => { channel: string; chatId: string };\n initSessionContext: (sessionKey: string, channel: string, chatId: string) => void;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n agentManager: AgentManager;\n sessionStore: SessionStore;\n prepareLoadedSessionMessages: (sessionKey: string, messages: AgentMessage[]) => AgentMessage[];\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectInboundAttachment[],\n ) => Promise<DirectInboundAttachment[] | undefined>;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n persistAgentSessionMessages: (sessionKey: string) => Promise<void>;\n endDirectRequestContext: () => void;\n};\n\nexport async function runProcessDirect(\n deps: RunProcessDirectDeps,\n input: {\n content: string;\n sessionKey: string;\n attachments?: DirectInboundAttachment[];\n thinking?: string;\n },\n): Promise<string> {\n const { channel, chatId } = deps.parseSessionKey(input.sessionKey);\n deps.initSessionContext(input.sessionKey, channel, chatId);\n\n try {\n await deps.hydrateSessionWorkspaceFromStore(input.sessionKey);\n const agent = deps.agentManager.getOrCreateAgent(input.sessionKey);\n\n await deps.hydrateSessionModelFromStore(input.sessionKey);\n\n const loaded = await deps.sessionStore.load(input.sessionKey);\n agent.state.messages = deps.prepareLoadedSessionMessages(input.sessionKey, loaded);\n\n await deps.modelManager.applyModelForSession(agent, input.sessionKey);\n await deps.applyResolvedThinkingLevel(input.sessionKey, input.thinking);\n\n const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);\n\n const cmd = parseSlashCommand(input.content);\n if (cmd && commandRegistry.has(cmd.command)) {\n const { aggregatedText } = await deps.commandHandler.executeCommandAndAggregateReply(cmd.command, cmd.args, {\n sessionKey: input.sessionKey,\n channel,\n chatId,\n senderId: '',\n isGroup: false,\n });\n await deps.persistAgentSessionMessages(input.sessionKey);\n return aggregatedText;\n }\n\n const textForDirect = input.content.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(input.content)\n : input.content;\n const messageContent = await buildDirectUserMessageContent({\n content: textForDirect,\n attachments: prepared,\n sessionKey: input.sessionKey,\n config: deps.config,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n });\n\n const userMessage = {\n role: 'user' as const,\n content: messageContent,\n timestamp: Date.now(),\n };\n const userPlain = extractAgentUserPlainText(userMessage);\n const userMessageForModel = await deps.agentManager.applyMemoryPrefetchToUserMessage(\n userMessage,\n input.sessionKey,\n );\n\n await runAgentTurnWithModelFallbacks({\n agent,\n sessionKey: input.sessionKey,\n modelManager: deps.modelManager,\n userMessage: userMessageForModel,\n log: deps.log,\n getConfig: () => deps.config,\n beforeUserPrompt: () => deps.agentManager.beginBackgroundReviewUserTurn(input.sessionKey),\n });\n\n deps.agentManager.afterAgentTurn(input.sessionKey, userPlain);\n deps.agentManager.scheduleBackgroundReviewAfterUserTurn(input.sessionKey);\n\n const response = deps.agentManager.getLastAssistantContent(input.sessionKey) || '';\n await deps.persistAgentSessionMessages(input.sessionKey);\n\n return response;\n } finally {\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":";;;;;;;AAmCA,eAAsB,iBACpB,MACA,OAMiB;CACjB,MAAM,EAAE,SAAS,WAAW,KAAK,gBAAgB,MAAM,WAAW;AAClE,MAAK,mBAAmB,MAAM,YAAY,SAAS,OAAO;AAE1D,KAAI;AACF,QAAM,KAAK,iCAAiC,MAAM,WAAW;EAC7D,MAAM,QAAQ,KAAK,aAAa,iBAAiB,MAAM,WAAW;AAElE,QAAM,KAAK,6BAA6B,MAAM,WAAW;EAEzD,MAAM,SAAS,MAAM,KAAK,aAAa,KAAK,MAAM,WAAW;AAC7D,QAAM,MAAM,WAAW,KAAK,6BAA6B,MAAM,YAAY,OAAO;AAElF,QAAM,KAAK,aAAa,qBAAqB,OAAO,MAAM,WAAW;AACrE,QAAM,KAAK,2BAA2B,MAAM,YAAY,MAAM,SAAS;EAEvE,MAAM,WAAW,MAAM,KAAK,0BAA0B,MAAM,YAAY,MAAM,YAAY;EAE1F,MAAM,MAAM,kBAAkB,MAAM,QAAQ;AAC5C,MAAI,OAAO,gBAAgB,IAAI,IAAI,QAAQ,EAAE;GAC3C,MAAM,EAAE,mBAAmB,MAAM,KAAK,eAAe,gCAAgC,IAAI,SAAS,IAAI,MAAM;IAC1G,YAAY,MAAM;IAClB;IACA;IACA,UAAU;IACV,SAAS;IACV,CAAC;AACF,SAAM,KAAK,4BAA4B,MAAM,WAAW;AACxD,UAAO;;EAeT,MAAM,cAAc;GAClB,MAAM;GACN,SAAS,MAXkB,8BAA8B;IACzD,SAJoB,MAAM,QAAQ,WAAW,CAAC,WAAW,UAAU,GACjE,KAAK,aAAa,oBAAoB,MAAM,QAAQ,GACpD,MAAM;IAGR,aAAa;IACb,YAAY,MAAM;IAClB,QAAQ,KAAK;IACb,cAAc,KAAK;IACnB,cAAc,KAAK;IACpB,CAAC;GAKA,WAAW,KAAK,KAAK;GACtB;EACD,MAAM,YAAY,0BAA0B,YAAY;EACxD,MAAM,sBAAsB,MAAM,KAAK,aAAa,iCAClD,aACA,MAAM,WACP;AAED,QAAM,+BAA+B;GACnC;GACA,YAAY,MAAM;GAClB,cAAc,KAAK;GACnB,aAAa;GACb,KAAK,KAAK;GACV,iBAAiB,KAAK;GACtB,wBAAwB,KAAK,aAAa,8BAA8B,MAAM,WAAW;GAC1F,CAAC;AAEF,OAAK,aAAa,eAAe,MAAM,YAAY,UAAU;AAC7D,OAAK,aAAa,sCAAsC,MAAM,WAAW;EAEzE,MAAM,WAAW,KAAK,aAAa,wBAAwB,MAAM,WAAW,IAAI;AAChF,QAAM,KAAK,4BAA4B,MAAM,WAAW;AAExD,SAAO;WACC;AACR,OAAK,yBAAyB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { extractTextContent, extractThinkingContent, extractThinkingFromAssistantMessage } from "../context/workspace.js";
|
|
2
2
|
import { extractAgentUserPlainText } from "../memory/user-message-text.js";
|
|
3
3
|
import { resolveEffectiveReasoningLevel } from "../../session/thinking-resolve.js";
|
|
4
|
+
import { stripTrailingWebchatEarlySaveUserIfPresent } from "../../session/strip-webchat-early-save.js";
|
|
4
5
|
import "../../session/index.js";
|
|
5
6
|
import { parseSlashCommand } from "../../chat-commands/command-parse.js";
|
|
6
7
|
import { commandRegistry } from "../../chat-commands/registry.js";
|
|
@@ -279,7 +280,17 @@ async function* runProcessDirectStreaming(deps, input) {
|
|
|
279
280
|
sessionKey
|
|
280
281
|
}, "Failed to persist webchat slash command receipt");
|
|
281
282
|
}
|
|
282
|
-
if (!ranSlashCommand)
|
|
283
|
+
if (!ranSlashCommand) {
|
|
284
|
+
if (userAborted && channel === "webchat") try {
|
|
285
|
+
await stripTrailingWebchatEarlySaveUserIfPresent(sessionStore, sessionKey);
|
|
286
|
+
} catch (stripErr) {
|
|
287
|
+
log.warn({
|
|
288
|
+
err: stripErr,
|
|
289
|
+
sessionKey
|
|
290
|
+
}, "Failed to strip trailing webchat early-save after abort");
|
|
291
|
+
}
|
|
292
|
+
await persistAgentSessionMessages(sessionKey);
|
|
293
|
+
}
|
|
283
294
|
if (!userAborted) {
|
|
284
295
|
const ttsAudioEvent = await maybeEmitWebchatTts(sessionKey, inboundVoice);
|
|
285
296
|
if (ttsAudioEvent) yield ttsAudioEvent;
|