@xopcai/xopc 0.0.126 → 0.0.127

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.
Files changed (191) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-C70vgt60.js → agent-avatar-dicebear-CgGgO4OV.js} +1 -1
  4. package/dist/gateway/static/root/assets/agents-k59l7NMb.js +2 -0
  5. package/dist/gateway/static/root/assets/{app-management-settings-panel-D9-HW6cy.js → app-management-settings-panel-DeQsTsyy.js} +1 -1
  6. package/dist/gateway/static/root/assets/{appearance-settings-BHlahIDL.js → appearance-settings-BnHQW7Hv.js} +1 -1
  7. package/dist/gateway/static/root/assets/{apps-page-BdJ1eQg3.js → apps-page-BG9b4abG.js} +1 -1
  8. package/dist/gateway/static/root/assets/{archive-plugin-B-aoIt0w.js → archive-plugin-5NXT7Zqv.js} +1 -1
  9. package/dist/gateway/static/root/assets/{attachment-load-BD0G0FD5.js → attachment-load-DghwhYe0.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automation-suggestion-card-iJRVI7aZ.js → automation-suggestion-card-DYmESgwl.js} +1 -1
  11. package/dist/gateway/static/root/assets/automations-page-De8mVutL.js +4 -0
  12. package/dist/gateway/static/root/assets/{binary-plugins-B0mNlVSz.js → binary-plugins-DSbPKdWX.js} +1 -1
  13. package/dist/gateway/static/root/assets/{block-editor-CJY9Lu5G.js → block-editor-CoZ-_np-.js} +27 -27
  14. package/dist/gateway/static/root/assets/browser-settings-page-C_ZRa4LF.js +8 -0
  15. package/dist/gateway/static/root/assets/{capability-presets-api-Bgc8ag55.js → capability-presets-api-hny224j-.js} +1 -1
  16. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-B1nIi0TC.js → capability-presets-settings-panel-Drc0qLsw.js} +1 -1
  17. package/dist/gateway/static/root/assets/{channel-recipient-api-0sauApoC.js → channel-recipient-api-DAlOHxKJ.js} +1 -1
  18. package/dist/gateway/static/root/assets/channels-settings-CA20zBV9.js +1 -0
  19. package/dist/gateway/static/root/assets/connectors-page-qMyMB5te.js +2 -0
  20. package/dist/gateway/static/root/assets/desktop-pet-XG6Vb_fZ.js +1 -0
  21. package/dist/gateway/static/root/assets/desktop-pet-settings-npJ0Oh5p.js +1 -0
  22. package/dist/gateway/static/root/assets/desktop-pet-sprite-DqZ6fbIj.js +1 -0
  23. package/dist/gateway/static/root/assets/directory-picker-path-field-BR2ItBuf.js +1 -0
  24. package/dist/gateway/static/root/assets/dreaming-settings-CkUZ997f.js +3 -0
  25. package/dist/gateway/static/root/assets/{extension-debug-page-BbyczVZ3.js → extension-debug-page-Tl0f1rNv.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-page-DLN1I3DR.js → extension-page-Ck7QuwE3.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-settings-page-D9VGHmYJ.js → extension-settings-page-3RMhQtZ3.js} +1 -1
  28. package/dist/gateway/static/root/assets/{fetch-5V96dUz3.js → fetch-pg2ErdAk.js} +1 -1
  29. package/dist/gateway/static/root/assets/{gateway-config-api-BtIzObwp.js → gateway-config-api-DbG97ia2.js} +1 -1
  30. package/dist/gateway/static/root/assets/gateway-settings-B8cyqKk-.js +1 -0
  31. package/dist/gateway/static/root/assets/{gateway-startup-retry-DEMad2wt.js → gateway-startup-retry-Yh8h3hkj.js} +1 -1
  32. package/dist/gateway/static/root/assets/{goal-create-dialog-4PcF6Sh6.js → goal-create-dialog-DmeW7Zz3.js} +1 -1
  33. package/dist/gateway/static/root/assets/goal-detail-page-DrTyGbVD.js +1 -0
  34. package/dist/gateway/static/root/assets/{goals-config-api-CVN7-pdM.js → goals-config-api-CxCWGIBB.js} +1 -1
  35. package/dist/gateway/static/root/assets/goals-page-DV1bJhIh.js +2 -0
  36. package/dist/gateway/static/root/assets/{goals-settings-IYCH3-Pi.js → goals-settings-9DrfOkP5.js} +1 -1
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-Cf_a2Bmz.js → heartbeat-settings-KaDpZrv0.js} +1 -1
  38. package/dist/gateway/static/root/assets/index-C2F0Clvm.js +256 -0
  39. package/dist/gateway/static/root/assets/index-COQSX5d_.css +1 -0
  40. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-lKTg6St7.js → keyboard-shortcuts-settings-CfQrt_Rb.js} +1 -1
  41. package/dist/gateway/static/root/assets/logs-page-C9dpiNTF.js +2 -0
  42. package/dist/gateway/static/root/assets/{markdown-split-Bv4k6iGJ.js → markdown-split-BwiMdCf_.js} +1 -1
  43. package/dist/gateway/static/root/assets/{media-plugins-Bbi8g3N8.js → media-plugins-DhoizyZv.js} +1 -1
  44. package/dist/gateway/static/root/assets/messages-DmnbiNxU.js +3 -0
  45. package/dist/gateway/static/root/assets/models-hub-panel-zdCdmBmH.js +2 -0
  46. package/dist/gateway/static/root/assets/notes-page-MpGeFfPt.js +1 -0
  47. package/dist/gateway/static/root/assets/notes-workbench-DYCM3yd2.js +2 -0
  48. package/dist/gateway/static/root/assets/{page-tabs-Cp395RYD.js → page-tabs-DDC2t4Z8.js} +1 -1
  49. package/dist/gateway/static/root/assets/{preview-open-alternatives-DqV5OM4m.js → preview-open-alternatives-BTmk-XDM.js} +1 -1
  50. package/dist/gateway/static/root/assets/project-detail-page-Cu0ElRnS.js +1 -0
  51. package/dist/gateway/static/root/assets/projects-page-DakNaUjZ.js +1 -0
  52. package/dist/gateway/static/root/assets/remote-access-hub-DYKjt7L9.js +1 -0
  53. package/dist/gateway/static/root/assets/{save-bar-controls-BItmzAzI.js → save-bar-controls-DqU-yKIh.js} +1 -1
  54. package/dist/gateway/static/root/assets/{schedule-field-BQ8IjjCn.js → schedule-field-CUttkoSB.js} +1 -1
  55. package/dist/gateway/static/root/assets/{schema-form-BRpD6x3d.js → schema-form-CVSQA9nI.js} +1 -1
  56. package/dist/gateway/static/root/assets/sessions-page-CcGHDsz1.js +1 -0
  57. package/dist/gateway/static/root/assets/settings-advanced-gate-CuFdeKNu.js +1 -0
  58. package/dist/gateway/static/root/assets/{settings-collapsible-section-BKSPQM4R.js → settings-collapsible-section-CK7ogS-P.js} +1 -1
  59. package/dist/gateway/static/root/assets/{settings-form-section-BmyfthNQ.js → settings-form-section-Bugp38Fa.js} +1 -1
  60. package/dist/gateway/static/root/assets/settings-page-0AJoUvxi.js +1 -0
  61. package/dist/gateway/static/root/assets/{settings-page-layout-Bls5tfbH.js → settings-page-layout-DBRWwdhh.js} +1 -1
  62. package/dist/gateway/static/root/assets/{setup-status-panel-kQEsTGAs.js → setup-status-panel-D6a_hEk7.js} +1 -1
  63. package/dist/gateway/static/root/assets/{share-preview-page-DbYZNAPb.js → share-preview-page-BtsuETKF.js} +1 -1
  64. package/dist/gateway/static/root/assets/shares-settings-CcEFT7S9.js +1 -0
  65. package/dist/gateway/static/root/assets/skill-reload-api-BcN_RuTD.js +1 -0
  66. package/dist/gateway/static/root/assets/skills-page-BbRZZZA5.js +2 -0
  67. package/dist/gateway/static/root/assets/{system-settings-panel-DKDAojWM.js → system-settings-panel-DJ6YuLqR.js} +1 -1
  68. package/dist/gateway/static/root/assets/{typed-models-lib-BCCV4Kkp.js → typed-models-lib-B0T7N8Km.js} +1 -1
  69. package/dist/gateway/static/root/assets/{use-channel-catalog-NBqg3iFY.js → use-channel-catalog-C6vrxdzZ.js} +1 -1
  70. package/dist/gateway/static/root/assets/{user-profile-settings-panel-suQ2x-LB.js → user-profile-settings-panel-DZ0nKMgj.js} +1 -1
  71. package/dist/gateway/static/root/assets/{utils-DPGVr3tS.js → utils-CehXcWAY.js} +1 -1
  72. package/dist/gateway/static/root/assets/voice-api-key-field-2QKflCx8.js +1 -0
  73. package/dist/gateway/static/root/assets/work-item-detail-page-DfJnuWq1.js +1 -0
  74. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BTkRVNAh.js → workflow-run-setup-panel-c4jeaohQ.js} +2 -2
  75. package/dist/gateway/static/root/assets/{workflow-start-dialog-DAImVtdO.js → workflow-start-dialog-ENRHjoqa.js} +1 -1
  76. package/dist/gateway/static/root/assets/workflows-page-BJwwFTm_.js +18 -0
  77. package/dist/gateway/static/root/index.html +5 -5
  78. package/dist/package.js +1 -1
  79. package/dist/src/agent/agent-instance-gateway.d.ts +5 -0
  80. package/dist/src/agent/agent-manager.d.ts +14 -0
  81. package/dist/src/agent/agent-manager.js +111 -2
  82. package/dist/src/agent/agent-manager.js.map +1 -1
  83. package/dist/src/agent/capabilities/definitions.d.ts +153 -0
  84. package/dist/src/agent/capabilities/definitions.js +156 -0
  85. package/dist/src/agent/capabilities/definitions.js.map +1 -0
  86. package/dist/src/agent/capabilities/index.d.ts +2 -0
  87. package/dist/src/agent/capabilities/index.js +3 -0
  88. package/dist/src/agent/capabilities/registry.d.ts +10 -0
  89. package/dist/src/agent/capabilities/registry.js +51 -0
  90. package/dist/src/agent/capabilities/registry.js.map +1 -0
  91. package/dist/src/agent/service/process-direct-one-shot.js +5 -3
  92. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  93. package/dist/src/agent/service/process-direct-streaming.js +4 -3
  94. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  95. package/dist/src/agent/service.d.ts +2 -0
  96. package/dist/src/agent/service.js +3 -0
  97. package/dist/src/agent/service.js.map +1 -1
  98. package/dist/src/agent/skills/parse-skill-metadata.js +9 -1
  99. package/dist/src/agent/skills/parse-skill-metadata.js.map +1 -1
  100. package/dist/src/agent/skills/skill-manager.d.ts +4 -0
  101. package/dist/src/agent/skills/skill-manager.js +17 -0
  102. package/dist/src/agent/skills/skill-manager.js.map +1 -1
  103. package/dist/src/agent/skills/types.d.ts +5 -0
  104. package/dist/src/agent/tools/desktop-pet-tool.d.ts +24 -0
  105. package/dist/src/agent/tools/desktop-pet-tool.js +90 -0
  106. package/dist/src/agent/tools/desktop-pet-tool.js.map +1 -0
  107. package/dist/src/agent/tools/factory.d.ts +2 -0
  108. package/dist/src/agent/tools/factory.js +17 -0
  109. package/dist/src/agent/tools/factory.js.map +1 -1
  110. package/dist/src/agent/tools/index.d.ts +1 -0
  111. package/dist/src/agent/tools/index.js +2 -1
  112. package/dist/src/automations/draft/automation-draft-service.js +1 -1
  113. package/dist/src/cli/commands/agent.js +2 -2
  114. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  115. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  116. package/dist/src/cli/commands/models.js +1 -1
  117. package/dist/src/cli/commands/onboard.js +1 -1
  118. package/dist/src/cli/commands/profile.js +1 -1
  119. package/dist/src/cli/commands/tunnel.js +1 -1
  120. package/dist/src/cli/commands/update.js +1 -1
  121. package/dist/src/cli/extension-cli-register.js +1 -1
  122. package/dist/src/config/index.js +1 -1
  123. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  124. package/dist/src/gateway/agent-builtin-tools.js +1 -0
  125. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  126. package/dist/src/gateway/hono/routes/commands-skills.js +7 -0
  127. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  128. package/dist/src/gateway/hono/routes/lazy-bundles.js +2 -1
  129. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  130. package/dist/src/gateway/hono/routes/projects.js +28 -0
  131. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  132. package/dist/src/gateway/run-loop.js +1 -1
  133. package/dist/src/gateway/service/run-gateway-agent.js +6 -2
  134. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  135. package/dist/src/mcp/channel-bridge.js +1 -1
  136. package/dist/src/pets/factory.d.ts +25 -0
  137. package/dist/src/pets/factory.js +327 -0
  138. package/dist/src/pets/factory.js.map +1 -0
  139. package/dist/src/pets/manifest.d.ts +2 -0
  140. package/dist/src/pets/manifest.js +16 -0
  141. package/dist/src/pets/manifest.js.map +1 -0
  142. package/dist/src/pets/validator.d.ts +12 -0
  143. package/dist/src/pets/validator.js +175 -0
  144. package/dist/src/pets/validator.js.map +1 -0
  145. package/dist/src/projects/project-service.d.ts +2 -0
  146. package/dist/src/projects/project-service.js +6 -0
  147. package/dist/src/projects/project-service.js.map +1 -1
  148. package/dist/src/projects/project-store.d.ts +1 -0
  149. package/dist/src/projects/project-store.js +14 -7
  150. package/dist/src/projects/project-store.js.map +1 -1
  151. package/dist/src/projects/types.d.ts +2 -0
  152. package/dist/src/session/session-title.js +22 -2
  153. package/dist/src/session/session-title.js.map +1 -1
  154. package/dist/src/storage/sqlite/migrations/025_project_pinned_at.sql +5 -0
  155. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  156. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  157. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  158. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  159. package/dist/src/storage/sqlite/schema.js +1 -1
  160. package/package.json +1 -1
  161. package/skills/creative/hatch-pet/SKILL.md +63 -0
  162. package/dist/gateway/static/root/assets/agents-DRYVahI-.js +0 -2
  163. package/dist/gateway/static/root/assets/automations-page-D8hYQbkl.js +0 -4
  164. package/dist/gateway/static/root/assets/browser-settings-page-CiWEO-Iy.js +0 -8
  165. package/dist/gateway/static/root/assets/channels-settings-BddPdqVo.js +0 -1
  166. package/dist/gateway/static/root/assets/connectors-page-Ba2GDhSE.js +0 -2
  167. package/dist/gateway/static/root/assets/directory-picker-path-field-CiEc4KmY.js +0 -1
  168. package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +0 -1
  169. package/dist/gateway/static/root/assets/dreaming-settings-4bvpk5wr.js +0 -3
  170. package/dist/gateway/static/root/assets/gateway-settings-KFsGGDhg.js +0 -1
  171. package/dist/gateway/static/root/assets/goal-detail-page-B482PSaG.js +0 -1
  172. package/dist/gateway/static/root/assets/goals-page-CUdgJuDn.js +0 -2
  173. package/dist/gateway/static/root/assets/index-CA2tR2vm.js +0 -256
  174. package/dist/gateway/static/root/assets/index-Ds3u0LOk.css +0 -1
  175. package/dist/gateway/static/root/assets/logs-page-BCporcNH.js +0 -2
  176. package/dist/gateway/static/root/assets/messages-C22hxE1N.js +0 -3
  177. package/dist/gateway/static/root/assets/models-hub-panel-D68Pyow7.js +0 -2
  178. package/dist/gateway/static/root/assets/notes-page-CuUMOiyv.js +0 -1
  179. package/dist/gateway/static/root/assets/notes-workbench-Dx2N5zTk.js +0 -2
  180. package/dist/gateway/static/root/assets/project-detail-page-sB8AzZi3.js +0 -1
  181. package/dist/gateway/static/root/assets/projects-page-LBnJqWK2.js +0 -1
  182. package/dist/gateway/static/root/assets/remote-access-hub-Dbj0o6SC.js +0 -1
  183. package/dist/gateway/static/root/assets/sessions-page-DhDZKspB.js +0 -1
  184. package/dist/gateway/static/root/assets/settings-advanced-gate-BvXLMNL6.js +0 -1
  185. package/dist/gateway/static/root/assets/settings-page-Cfm9UxAr.js +0 -1
  186. package/dist/gateway/static/root/assets/shares-settings-BtR4B0kn.js +0 -1
  187. package/dist/gateway/static/root/assets/skill-reload-api-CJNVOWoK.js +0 -1
  188. package/dist/gateway/static/root/assets/skills-page-DcWDHrt3.js +0 -2
  189. package/dist/gateway/static/root/assets/voice-api-key-field-DaJASKFP.js +0 -1
  190. package/dist/gateway/static/root/assets/work-item-detail-page-BrCZpAWh.js +0 -1
  191. package/dist/gateway/static/root/assets/workflows-page-vyJ8wSXm.js +0 -18
@@ -0,0 +1,153 @@
1
+ export type AgentCapabilityCategory = 'authoring' | 'research' | 'analysis' | 'assets';
2
+ export type AgentCapabilityActivationMode = 'explicit' | 'ui-entry' | 'workflow-scoped';
3
+ export type AgentCapabilityTtl = 'turn' | 'session' | 'until-complete';
4
+ export type AgentCapabilityActivationSource = 'skill' | 'ui' | 'workflow';
5
+ export type AgentCapabilitySessionStatus = 'collecting' | 'running' | 'complete';
6
+ export type AgentCapabilityPermissions = {
7
+ writesFiles?: boolean;
8
+ runsCode?: boolean;
9
+ usesBrowser?: boolean;
10
+ usesNetwork?: boolean;
11
+ requiresConfirm?: boolean;
12
+ };
13
+ export type AgentCapabilityDefinition = {
14
+ id: string;
15
+ label: string;
16
+ description: string;
17
+ category: AgentCapabilityCategory;
18
+ tools: readonly string[];
19
+ requiredSkills?: readonly string[];
20
+ promptHint?: string;
21
+ activation: {
22
+ mode: AgentCapabilityActivationMode;
23
+ ttl: AgentCapabilityTtl;
24
+ };
25
+ permissions: AgentCapabilityPermissions;
26
+ };
27
+ export type AgentCapabilitySessionState = {
28
+ id: string;
29
+ source: AgentCapabilityActivationSource;
30
+ activatedAt: number;
31
+ ttl: AgentCapabilityTtl;
32
+ status: AgentCapabilitySessionStatus;
33
+ };
34
+ export type AgentCapabilityCatalogEntry = AgentCapabilityDefinition & {
35
+ availableTools: string[];
36
+ unavailableTools: string[];
37
+ };
38
+ export declare const AGENT_CAPABILITY_DEFINITIONS: readonly [{
39
+ readonly id: "desktop-pet-authoring";
40
+ readonly label: "Desktop pet authoring";
41
+ readonly description: "Create, repair, and update local animated desktop pet packages.";
42
+ readonly category: "authoring";
43
+ readonly tools: readonly ["create_desktop_pet"];
44
+ readonly requiredSkills: readonly ["hatch-pet"];
45
+ readonly promptHint: "Use clarify when the pet concept is vague. Create or update the pet only after appearance, personality, and animation goals are clear.";
46
+ readonly activation: {
47
+ readonly mode: "explicit";
48
+ readonly ttl: "until-complete";
49
+ };
50
+ readonly permissions: {
51
+ readonly writesFiles: true;
52
+ };
53
+ }, {
54
+ readonly id: "automation-authoring";
55
+ readonly label: "Automation authoring";
56
+ readonly description: "Create and update reminders, monitors, recurring checks, and scheduled follow-ups.";
57
+ readonly category: "authoring";
58
+ readonly tools: readonly ["automation"];
59
+ readonly activation: {
60
+ readonly mode: "explicit";
61
+ readonly ttl: "until-complete";
62
+ };
63
+ readonly permissions: {
64
+ readonly writesFiles: true;
65
+ readonly requiresConfirm: true;
66
+ };
67
+ }, {
68
+ readonly id: "workflow-authoring";
69
+ readonly label: "Workflow authoring";
70
+ readonly description: "Design, validate, and run xopc workflows.";
71
+ readonly category: "authoring";
72
+ readonly tools: readonly ["workflow"];
73
+ readonly activation: {
74
+ readonly mode: "explicit";
75
+ readonly ttl: "until-complete";
76
+ };
77
+ readonly permissions: {
78
+ readonly writesFiles: true;
79
+ readonly runsCode: true;
80
+ readonly requiresConfirm: true;
81
+ };
82
+ }, {
83
+ readonly id: "extension-authoring";
84
+ readonly label: "Plugin and extension authoring";
85
+ readonly description: "Scaffold, inspect, and package xopc plugins or extensions.";
86
+ readonly category: "authoring";
87
+ readonly tools: readonly ["read_file", "write_file", "apply_patch", "list_dir", "grep", "find", "exec_command"];
88
+ readonly activation: {
89
+ readonly mode: "explicit";
90
+ readonly ttl: "until-complete";
91
+ };
92
+ readonly permissions: {
93
+ readonly writesFiles: true;
94
+ readonly runsCode: true;
95
+ readonly requiresConfirm: true;
96
+ };
97
+ }, {
98
+ readonly id: "skill-authoring";
99
+ readonly label: "Skill authoring";
100
+ readonly description: "Create, edit, inspect, and maintain xopc skills.";
101
+ readonly category: "authoring";
102
+ readonly tools: readonly ["skills_list", "skill_view", "skill_manage"];
103
+ readonly activation: {
104
+ readonly mode: "explicit";
105
+ readonly ttl: "until-complete";
106
+ };
107
+ readonly permissions: {
108
+ readonly writesFiles: true;
109
+ readonly requiresConfirm: true;
110
+ };
111
+ }, {
112
+ readonly id: "visual-asset-authoring";
113
+ readonly label: "Visual asset authoring";
114
+ readonly description: "Generate and inspect images, icons, sprites, and other visual assets.";
115
+ readonly category: "assets";
116
+ readonly tools: readonly ["image", "image_generate", "read_media", "send_media"];
117
+ readonly activation: {
118
+ readonly mode: "explicit";
119
+ readonly ttl: "session";
120
+ };
121
+ readonly permissions: {
122
+ readonly writesFiles: true;
123
+ readonly usesNetwork: true;
124
+ };
125
+ }, {
126
+ readonly id: "browser-research";
127
+ readonly label: "Browser research";
128
+ readonly description: "Perform deeper web research with search, extraction, fetch, and browser interaction.";
129
+ readonly category: "research";
130
+ readonly tools: readonly ["web_search", "web_fetch", "web_extract", "browser_use"];
131
+ readonly activation: {
132
+ readonly mode: "explicit";
133
+ readonly ttl: "turn";
134
+ };
135
+ readonly permissions: {
136
+ readonly usesBrowser: true;
137
+ readonly usesNetwork: true;
138
+ };
139
+ }, {
140
+ readonly id: "data-analysis";
141
+ readonly label: "Data analysis";
142
+ readonly description: "Analyze local structured data and produce derived tables, summaries, or artifacts.";
143
+ readonly category: "analysis";
144
+ readonly tools: readonly ["read_file", "write_file", "list_dir", "grep", "find"];
145
+ readonly activation: {
146
+ readonly mode: "explicit";
147
+ readonly ttl: "session";
148
+ };
149
+ readonly permissions: {
150
+ readonly writesFiles: true;
151
+ readonly runsCode: true;
152
+ };
153
+ }];
@@ -0,0 +1,156 @@
1
+ //#region src/agent/capabilities/definitions.ts
2
+ const AGENT_CAPABILITY_DEFINITIONS = [
3
+ {
4
+ id: "desktop-pet-authoring",
5
+ label: "Desktop pet authoring",
6
+ description: "Create, repair, and update local animated desktop pet packages.",
7
+ category: "authoring",
8
+ tools: ["create_desktop_pet"],
9
+ requiredSkills: ["hatch-pet"],
10
+ promptHint: "Use clarify when the pet concept is vague. Create or update the pet only after appearance, personality, and animation goals are clear.",
11
+ activation: {
12
+ mode: "explicit",
13
+ ttl: "until-complete"
14
+ },
15
+ permissions: { writesFiles: true }
16
+ },
17
+ {
18
+ id: "automation-authoring",
19
+ label: "Automation authoring",
20
+ description: "Create and update reminders, monitors, recurring checks, and scheduled follow-ups.",
21
+ category: "authoring",
22
+ tools: ["automation"],
23
+ activation: {
24
+ mode: "explicit",
25
+ ttl: "until-complete"
26
+ },
27
+ permissions: {
28
+ writesFiles: true,
29
+ requiresConfirm: true
30
+ }
31
+ },
32
+ {
33
+ id: "workflow-authoring",
34
+ label: "Workflow authoring",
35
+ description: "Design, validate, and run xopc workflows.",
36
+ category: "authoring",
37
+ tools: ["workflow"],
38
+ activation: {
39
+ mode: "explicit",
40
+ ttl: "until-complete"
41
+ },
42
+ permissions: {
43
+ writesFiles: true,
44
+ runsCode: true,
45
+ requiresConfirm: true
46
+ }
47
+ },
48
+ {
49
+ id: "extension-authoring",
50
+ label: "Plugin and extension authoring",
51
+ description: "Scaffold, inspect, and package xopc plugins or extensions.",
52
+ category: "authoring",
53
+ tools: [
54
+ "read_file",
55
+ "write_file",
56
+ "apply_patch",
57
+ "list_dir",
58
+ "grep",
59
+ "find",
60
+ "exec_command"
61
+ ],
62
+ activation: {
63
+ mode: "explicit",
64
+ ttl: "until-complete"
65
+ },
66
+ permissions: {
67
+ writesFiles: true,
68
+ runsCode: true,
69
+ requiresConfirm: true
70
+ }
71
+ },
72
+ {
73
+ id: "skill-authoring",
74
+ label: "Skill authoring",
75
+ description: "Create, edit, inspect, and maintain xopc skills.",
76
+ category: "authoring",
77
+ tools: [
78
+ "skills_list",
79
+ "skill_view",
80
+ "skill_manage"
81
+ ],
82
+ activation: {
83
+ mode: "explicit",
84
+ ttl: "until-complete"
85
+ },
86
+ permissions: {
87
+ writesFiles: true,
88
+ requiresConfirm: true
89
+ }
90
+ },
91
+ {
92
+ id: "visual-asset-authoring",
93
+ label: "Visual asset authoring",
94
+ description: "Generate and inspect images, icons, sprites, and other visual assets.",
95
+ category: "assets",
96
+ tools: [
97
+ "image",
98
+ "image_generate",
99
+ "read_media",
100
+ "send_media"
101
+ ],
102
+ activation: {
103
+ mode: "explicit",
104
+ ttl: "session"
105
+ },
106
+ permissions: {
107
+ writesFiles: true,
108
+ usesNetwork: true
109
+ }
110
+ },
111
+ {
112
+ id: "browser-research",
113
+ label: "Browser research",
114
+ description: "Perform deeper web research with search, extraction, fetch, and browser interaction.",
115
+ category: "research",
116
+ tools: [
117
+ "web_search",
118
+ "web_fetch",
119
+ "web_extract",
120
+ "browser_use"
121
+ ],
122
+ activation: {
123
+ mode: "explicit",
124
+ ttl: "turn"
125
+ },
126
+ permissions: {
127
+ usesBrowser: true,
128
+ usesNetwork: true
129
+ }
130
+ },
131
+ {
132
+ id: "data-analysis",
133
+ label: "Data analysis",
134
+ description: "Analyze local structured data and produce derived tables, summaries, or artifacts.",
135
+ category: "analysis",
136
+ tools: [
137
+ "read_file",
138
+ "write_file",
139
+ "list_dir",
140
+ "grep",
141
+ "find"
142
+ ],
143
+ activation: {
144
+ mode: "explicit",
145
+ ttl: "session"
146
+ },
147
+ permissions: {
148
+ writesFiles: true,
149
+ runsCode: true
150
+ }
151
+ }
152
+ ];
153
+ //#endregion
154
+ export { AGENT_CAPABILITY_DEFINITIONS };
155
+
156
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","names":[],"sources":["../../../../src/agent/capabilities/definitions.ts"],"sourcesContent":["export type AgentCapabilityCategory = 'authoring' | 'research' | 'analysis' | 'assets';\n\nexport type AgentCapabilityActivationMode = 'explicit' | 'ui-entry' | 'workflow-scoped';\n\nexport type AgentCapabilityTtl = 'turn' | 'session' | 'until-complete';\n\nexport type AgentCapabilityActivationSource = 'skill' | 'ui' | 'workflow';\n\nexport type AgentCapabilitySessionStatus = 'collecting' | 'running' | 'complete';\n\nexport type AgentCapabilityPermissions = {\n writesFiles?: boolean;\n runsCode?: boolean;\n usesBrowser?: boolean;\n usesNetwork?: boolean;\n requiresConfirm?: boolean;\n};\n\nexport type AgentCapabilityDefinition = {\n id: string;\n label: string;\n description: string;\n category: AgentCapabilityCategory;\n tools: readonly string[];\n requiredSkills?: readonly string[];\n promptHint?: string;\n activation: {\n mode: AgentCapabilityActivationMode;\n ttl: AgentCapabilityTtl;\n };\n permissions: AgentCapabilityPermissions;\n};\n\nexport type AgentCapabilitySessionState = {\n id: string;\n source: AgentCapabilityActivationSource;\n activatedAt: number;\n ttl: AgentCapabilityTtl;\n status: AgentCapabilitySessionStatus;\n};\n\nexport type AgentCapabilityCatalogEntry = AgentCapabilityDefinition & {\n availableTools: string[];\n unavailableTools: string[];\n};\n\nexport const AGENT_CAPABILITY_DEFINITIONS = [\n {\n id: 'desktop-pet-authoring',\n label: 'Desktop pet authoring',\n description: 'Create, repair, and update local animated desktop pet packages.',\n category: 'authoring',\n tools: ['create_desktop_pet'],\n requiredSkills: ['hatch-pet'],\n promptHint:\n 'Use clarify when the pet concept is vague. Create or update the pet only after appearance, personality, and animation goals are clear.',\n activation: { mode: 'explicit', ttl: 'until-complete' },\n permissions: { writesFiles: true },\n },\n {\n id: 'automation-authoring',\n label: 'Automation authoring',\n description: 'Create and update reminders, monitors, recurring checks, and scheduled follow-ups.',\n category: 'authoring',\n tools: ['automation'],\n activation: { mode: 'explicit', ttl: 'until-complete' },\n permissions: { writesFiles: true, requiresConfirm: true },\n },\n {\n id: 'workflow-authoring',\n label: 'Workflow authoring',\n description: 'Design, validate, and run xopc workflows.',\n category: 'authoring',\n tools: ['workflow'],\n activation: { mode: 'explicit', ttl: 'until-complete' },\n permissions: { writesFiles: true, runsCode: true, requiresConfirm: true },\n },\n {\n id: 'extension-authoring',\n label: 'Plugin and extension authoring',\n description: 'Scaffold, inspect, and package xopc plugins or extensions.',\n category: 'authoring',\n tools: ['read_file', 'write_file', 'apply_patch', 'list_dir', 'grep', 'find', 'exec_command'],\n activation: { mode: 'explicit', ttl: 'until-complete' },\n permissions: { writesFiles: true, runsCode: true, requiresConfirm: true },\n },\n {\n id: 'skill-authoring',\n label: 'Skill authoring',\n description: 'Create, edit, inspect, and maintain xopc skills.',\n category: 'authoring',\n tools: ['skills_list', 'skill_view', 'skill_manage'],\n activation: { mode: 'explicit', ttl: 'until-complete' },\n permissions: { writesFiles: true, requiresConfirm: true },\n },\n {\n id: 'visual-asset-authoring',\n label: 'Visual asset authoring',\n description: 'Generate and inspect images, icons, sprites, and other visual assets.',\n category: 'assets',\n tools: ['image', 'image_generate', 'read_media', 'send_media'],\n activation: { mode: 'explicit', ttl: 'session' },\n permissions: { writesFiles: true, usesNetwork: true },\n },\n {\n id: 'browser-research',\n label: 'Browser research',\n description: 'Perform deeper web research with search, extraction, fetch, and browser interaction.',\n category: 'research',\n tools: ['web_search', 'web_fetch', 'web_extract', 'browser_use'],\n activation: { mode: 'explicit', ttl: 'turn' },\n permissions: { usesBrowser: true, usesNetwork: true },\n },\n {\n id: 'data-analysis',\n label: 'Data analysis',\n description: 'Analyze local structured data and produce derived tables, summaries, or artifacts.',\n category: 'analysis',\n tools: ['read_file', 'write_file', 'list_dir', 'grep', 'find'],\n activation: { mode: 'explicit', ttl: 'session' },\n permissions: { writesFiles: true, runsCode: true },\n },\n] as const satisfies readonly AgentCapabilityDefinition[];\n"],"mappings":";AA8CA,MAAa,+BAA+B;CAC1C;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO,CAAC,qBAAqB;EAC7B,gBAAgB,CAAC,YAAY;EAC7B,YACE;EACF,YAAY;GAAE,MAAM;GAAY,KAAK;GAAkB;EACvD,aAAa,EAAE,aAAa,MAAM;EACnC;CACD;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO,CAAC,aAAa;EACrB,YAAY;GAAE,MAAM;GAAY,KAAK;GAAkB;EACvD,aAAa;GAAE,aAAa;GAAM,iBAAiB;GAAM;EAC1D;CACD;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO,CAAC,WAAW;EACnB,YAAY;GAAE,MAAM;GAAY,KAAK;GAAkB;EACvD,aAAa;GAAE,aAAa;GAAM,UAAU;GAAM,iBAAiB;GAAM;EAC1E;CACD;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO;GAAC;GAAa;GAAc;GAAe;GAAY;GAAQ;GAAQ;GAAe;EAC7F,YAAY;GAAE,MAAM;GAAY,KAAK;GAAkB;EACvD,aAAa;GAAE,aAAa;GAAM,UAAU;GAAM,iBAAiB;GAAM;EAC1E;CACD;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO;GAAC;GAAe;GAAc;GAAe;EACpD,YAAY;GAAE,MAAM;GAAY,KAAK;GAAkB;EACvD,aAAa;GAAE,aAAa;GAAM,iBAAiB;GAAM;EAC1D;CACD;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO;GAAC;GAAS;GAAkB;GAAc;GAAa;EAC9D,YAAY;GAAE,MAAM;GAAY,KAAK;GAAW;EAChD,aAAa;GAAE,aAAa;GAAM,aAAa;GAAM;EACtD;CACD;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO;GAAC;GAAc;GAAa;GAAe;GAAc;EAChE,YAAY;GAAE,MAAM;GAAY,KAAK;GAAQ;EAC7C,aAAa;GAAE,aAAa;GAAM,aAAa;GAAM;EACtD;CACD;EACE,IAAI;EACJ,OAAO;EACP,aAAa;EACb,UAAU;EACV,OAAO;GAAC;GAAa;GAAc;GAAY;GAAQ;GAAO;EAC9D,YAAY;GAAE,MAAM;GAAY,KAAK;GAAW;EAChD,aAAa;GAAE,aAAa;GAAM,UAAU;GAAM;EACnD;CACF"}
@@ -0,0 +1,2 @@
1
+ export { AGENT_CAPABILITY_DEFINITIONS, type AgentCapabilityActivationMode, type AgentCapabilityActivationSource, type AgentCapabilityCatalogEntry, type AgentCapabilityCategory, type AgentCapabilityDefinition, type AgentCapabilityPermissions, type AgentCapabilitySessionState, type AgentCapabilitySessionStatus, type AgentCapabilityTtl, } from './definitions.js';
2
+ export { createAgentCapabilitySessionState, getAgentCapability, getAgentCapabilityToolNames, listAgentCapabilities, resolveAgentCapabilityCatalog, } from './registry.js';
@@ -0,0 +1,3 @@
1
+ import { AGENT_CAPABILITY_DEFINITIONS } from "./definitions.js";
2
+ import { createAgentCapabilitySessionState, getAgentCapability, getAgentCapabilityToolNames, listAgentCapabilities, resolveAgentCapabilityCatalog } from "./registry.js";
3
+ export { AGENT_CAPABILITY_DEFINITIONS, createAgentCapabilitySessionState, getAgentCapability, getAgentCapabilityToolNames, listAgentCapabilities, resolveAgentCapabilityCatalog };
@@ -0,0 +1,10 @@
1
+ import { type AgentCapabilityActivationSource, type AgentCapabilityCatalogEntry, type AgentCapabilityDefinition, type AgentCapabilitySessionState } from './definitions.js';
2
+ export declare function listAgentCapabilities(): AgentCapabilityDefinition[];
3
+ export declare function getAgentCapability(id: string): AgentCapabilityDefinition | undefined;
4
+ export declare function getAgentCapabilityToolNames(ids: readonly string[]): string[];
5
+ export declare function resolveAgentCapabilityCatalog(options?: {
6
+ registeredToolNames?: readonly string[];
7
+ lazyToolNames?: readonly string[];
8
+ deniedToolNames?: readonly string[];
9
+ }): AgentCapabilityCatalogEntry[];
10
+ export declare function createAgentCapabilitySessionState(id: string, source: AgentCapabilityActivationSource, now?: number): AgentCapabilitySessionState | null;
@@ -0,0 +1,51 @@
1
+ import { AGENT_CAPABILITY_DEFINITIONS } from "./definitions.js";
2
+ //#region src/agent/capabilities/registry.ts
3
+ const definitionsById = new Map(AGENT_CAPABILITY_DEFINITIONS.map((definition) => [definition.id, definition]));
4
+ function listAgentCapabilities() {
5
+ return [...AGENT_CAPABILITY_DEFINITIONS];
6
+ }
7
+ function getAgentCapability(id) {
8
+ return definitionsById.get(id.trim());
9
+ }
10
+ function getAgentCapabilityToolNames(ids) {
11
+ const out = [];
12
+ const seen = /* @__PURE__ */ new Set();
13
+ for (const id of ids) {
14
+ const definition = getAgentCapability(id);
15
+ if (!definition) continue;
16
+ for (const toolName of definition.tools) {
17
+ if (seen.has(toolName)) continue;
18
+ seen.add(toolName);
19
+ out.push(toolName);
20
+ }
21
+ }
22
+ return out;
23
+ }
24
+ function resolveAgentCapabilityCatalog(options = {}) {
25
+ const available = new Set([...options.registeredToolNames ?? [], ...options.lazyToolNames ?? []]);
26
+ const denied = new Set(options.deniedToolNames ?? []);
27
+ return AGENT_CAPABILITY_DEFINITIONS.map((definition) => {
28
+ const availableTools = definition.tools.filter((toolName) => available.has(toolName) && !denied.has(toolName));
29
+ const unavailableTools = definition.tools.filter((toolName) => !availableTools.includes(toolName));
30
+ return {
31
+ ...definition,
32
+ availableTools,
33
+ unavailableTools
34
+ };
35
+ });
36
+ }
37
+ function createAgentCapabilitySessionState(id, source, now = Date.now()) {
38
+ const definition = getAgentCapability(id);
39
+ if (!definition) return null;
40
+ return {
41
+ id: definition.id,
42
+ source,
43
+ activatedAt: now,
44
+ ttl: definition.activation.ttl,
45
+ status: "collecting"
46
+ };
47
+ }
48
+ //#endregion
49
+ export { createAgentCapabilitySessionState, getAgentCapability, getAgentCapabilityToolNames, listAgentCapabilities, resolveAgentCapabilityCatalog };
50
+
51
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../../../src/agent/capabilities/registry.ts"],"sourcesContent":["import {\n AGENT_CAPABILITY_DEFINITIONS,\n type AgentCapabilityActivationSource,\n type AgentCapabilityCatalogEntry,\n type AgentCapabilityDefinition,\n type AgentCapabilitySessionState,\n} from './definitions.js';\n\nconst definitionsById: Map<string, AgentCapabilityDefinition> = new Map(\n AGENT_CAPABILITY_DEFINITIONS.map((definition) => [definition.id, definition]),\n);\n\nexport function listAgentCapabilities(): AgentCapabilityDefinition[] {\n return [...AGENT_CAPABILITY_DEFINITIONS];\n}\n\nexport function getAgentCapability(id: string): AgentCapabilityDefinition | undefined {\n return definitionsById.get(id.trim());\n}\n\nexport function getAgentCapabilityToolNames(ids: readonly string[]): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n for (const id of ids) {\n const definition = getAgentCapability(id);\n if (!definition) continue;\n for (const toolName of definition.tools) {\n if (seen.has(toolName)) continue;\n seen.add(toolName);\n out.push(toolName);\n }\n }\n return out;\n}\n\nexport function resolveAgentCapabilityCatalog(options: {\n registeredToolNames?: readonly string[];\n lazyToolNames?: readonly string[];\n deniedToolNames?: readonly string[];\n} = {}): AgentCapabilityCatalogEntry[] {\n const available = new Set([\n ...(options.registeredToolNames ?? []),\n ...(options.lazyToolNames ?? []),\n ]);\n const denied = new Set(options.deniedToolNames ?? []);\n return AGENT_CAPABILITY_DEFINITIONS.map((definition) => {\n const availableTools = definition.tools.filter((toolName) => available.has(toolName) && !denied.has(toolName));\n const unavailableTools = definition.tools.filter((toolName) => !availableTools.includes(toolName));\n return {\n ...definition,\n availableTools,\n unavailableTools,\n };\n });\n}\n\nexport function createAgentCapabilitySessionState(\n id: string,\n source: AgentCapabilityActivationSource,\n now = Date.now(),\n): AgentCapabilitySessionState | null {\n const definition = getAgentCapability(id);\n if (!definition) return null;\n return {\n id: definition.id,\n source,\n activatedAt: now,\n ttl: definition.activation.ttl,\n status: 'collecting',\n };\n}\n"],"mappings":";;AAQA,MAAM,kBAA0D,IAAI,IAClE,6BAA6B,KAAK,eAAe,CAAC,WAAW,IAAI,WAAW,CAAC,CAC9E;AAED,SAAgB,wBAAqD;AACnE,QAAO,CAAC,GAAG,6BAA6B;;AAG1C,SAAgB,mBAAmB,IAAmD;AACpF,QAAO,gBAAgB,IAAI,GAAG,MAAM,CAAC;;AAGvC,SAAgB,4BAA4B,KAAkC;CAC5E,MAAM,MAAgB,EAAE;CACxB,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,MAAM,MAAM,KAAK;EACpB,MAAM,aAAa,mBAAmB,GAAG;AACzC,MAAI,CAAC,WAAY;AACjB,OAAK,MAAM,YAAY,WAAW,OAAO;AACvC,OAAI,KAAK,IAAI,SAAS,CAAE;AACxB,QAAK,IAAI,SAAS;AAClB,OAAI,KAAK,SAAS;;;AAGtB,QAAO;;AAGT,SAAgB,8BAA8B,UAI1C,EAAE,EAAiC;CACrC,MAAM,YAAY,IAAI,IAAI,CACxB,GAAI,QAAQ,uBAAuB,EAAE,EACrC,GAAI,QAAQ,iBAAiB,EAAE,CAChC,CAAC;CACF,MAAM,SAAS,IAAI,IAAI,QAAQ,mBAAmB,EAAE,CAAC;AACrD,QAAO,6BAA6B,KAAK,eAAe;EACtD,MAAM,iBAAiB,WAAW,MAAM,QAAQ,aAAa,UAAU,IAAI,SAAS,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC;EAC9G,MAAM,mBAAmB,WAAW,MAAM,QAAQ,aAAa,CAAC,eAAe,SAAS,SAAS,CAAC;AAClG,SAAO;GACL,GAAG;GACH;GACA;GACD;GACD;;AAGJ,SAAgB,kCACd,IACA,QACA,MAAM,KAAK,KAAK,EACoB;CACpC,MAAM,aAAa,mBAAmB,GAAG;AACzC,KAAI,CAAC,WAAY,QAAO;AACxB,QAAO;EACL,IAAI,WAAW;EACf;EACA,aAAa;EACb,KAAK,WAAW,WAAW;EAC3B,QAAQ;EACT"}
@@ -42,8 +42,10 @@ async function runProcessDirect(deps, input) {
42
42
  });
43
43
  return slash.aggregatedText ?? "";
44
44
  }
45
+ const skillTurn = deps.agentManager.prepareSkillTurn(input.sessionKey, turnBody);
46
+ const textForDirect = skillTurn.text;
45
47
  const userMessage = await buildDirectUserMessageContent({
46
- content: turnBody.trimStart().startsWith("/skill:") ? deps.agentManager.expandSkillUserText(turnBody) : turnBody,
48
+ content: textForDirect,
47
49
  attachments: prepared,
48
50
  sessionKey: input.sessionKey,
49
51
  config: deps.config,
@@ -54,13 +56,13 @@ async function runProcessDirect(deps, input) {
54
56
  setPendingTranscriptUserMessage(input.sessionKey, pendingUserMessage);
55
57
  const result = await (async () => {
56
58
  try {
57
- return await runDirectAgentTurn({
59
+ return await deps.agentManager.withSkillCapabilities(input.sessionKey, skillTurn.activatedCapabilityNames, () => runDirectAgentTurn({
58
60
  ...deps,
59
61
  config: deps.config
60
62
  }, {
61
63
  sessionKey: input.sessionKey,
62
64
  userMessage
63
- });
65
+ }));
64
66
  } finally {
65
67
  clearPendingTranscriptUserMessage(input.sessionKey, pendingUserMessage);
66
68
  }
@@ -1 +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 '@earendil-works/pi-agent-core';\n\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport { initSessionTurn } from '../../session/index.js';\nimport {\n buildDirectUserMessageContent,\n} from './build-direct-message-content.js';\nimport type { ProcessDirectStreamLog } from './process-direct-streaming.js';\nimport type {\n InboundAttachmentInput,\n MediaRef,\n} from '../../channels/attachments/inbound-persist.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\nimport {\n clearPendingTranscriptUserMessage,\n setPendingTranscriptUserMessage,\n type TranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\nimport type { ReviewOutput } from '../../review/review-types.js';\n\nexport type RunProcessDirectDeps = {\n log: ProcessDirectStreamLog;\n config: Config;\n resolveSessionEndpoint: (sessionKey: string) => Promise<{ 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: AgentInstanceGateway;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: InboundAttachmentInput[],\n ) => Promise<MediaRef[] | undefined>;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n};\n\nfunction isReviewOutput(value: unknown): value is ReviewOutput {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nexport async function runProcessDirect(\n deps: RunProcessDirectDeps,\n input: {\n content: string;\n sessionKey: string;\n attachments?: InboundAttachmentInput[];\n thinking?: string;\n },\n): Promise<string> {\n const { channel, chatId } = await deps.resolveSessionEndpoint(input.sessionKey);\n deps.initSessionContext(input.sessionKey, channel, chatId);\n\n try {\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n const turn = await initSessionTurn({\n cfg: deps.config,\n sessionKey: input.sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n return turn.ackMessage;\n }\n turnBody = turn.bodyStripped;\n\n await hydratePerTurnState(deps, input.sessionKey, input.thinking);\n const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey: input.sessionKey, channel, chatId },\n turnBody,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n const trimmed = slash.aggregatedText.trim();\n if (trimmed) {\n await deps.sessionStore.appendTranscriptMessage(input.sessionKey, {\n role: 'assistant',\n content: isReviewOutput(slash.metadata?.review)\n ? [slash.metadata.review]\n : [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n ...(slash.metadata && Object.keys(slash.metadata).length > 0\n ? { metadata: slash.metadata }\n : {}),\n } as AgentMessage);\n }\n return slash.aggregatedText ?? '';\n }\n\n const textForDirect = turnBody.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(turnBody)\n : turnBody;\n const userMessage = 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 pendingUserMessage = userMessage as TranscriptUserMessage;\n setPendingTranscriptUserMessage(input.sessionKey, pendingUserMessage);\n\n const result = await (async () => {\n try {\n return await runDirectAgentTurn(\n { ...deps, config: deps.config },\n {\n sessionKey: input.sessionKey,\n userMessage,\n },\n );\n } finally {\n clearPendingTranscriptUserMessage(input.sessionKey, pendingUserMessage);\n }\n })();\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(input.sessionKey, result.lastAssistantText);\n }\n\n return result.lastAssistantText ?? '';\n } finally {\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":";;;;;;AAiDA,SAAS,eAAe,OAAuC;AAC7D,QAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,IAC9D,MAA6B,SAAS;;AAG9C,eAAsB,iBACpB,MACA,OAMiB;CACjB,MAAM,EAAE,SAAS,WAAW,MAAM,KAAK,uBAAuB,MAAM,WAAW;AAC/E,MAAK,mBAAmB,MAAM,YAAY,SAAS,OAAO;AAE1D,KAAI;EACF,IAAI,WAAW,MAAM;EACrB,IAAI,uBAAuB;EAC3B,MAAM,OAAO,MAAM,gBAAgB;GACjC,KAAK,KAAK;GACV,YAAY,MAAM;GAClB,MAAM,MAAM;GACZ,cAAc,KAAK;GACpB,CAAC;AACF,yBAAuB,KAAK;AAC5B,MAAI,KAAK,aAAa,KAAK,WACzB,QAAO,KAAK;AAEd,aAAW,KAAK;AAEhB,QAAM,oBAAoB,MAAM,MAAM,YAAY,MAAM,SAAS;EACjE,MAAM,WAAW,MAAM,KAAK,0BAA0B,MAAM,YAAY,MAAM,YAAY;EAE1F,MAAM,QAAQ,MAAM,mBAClB,MACA;GAAE,YAAY,MAAM;GAAY;GAAS;GAAQ,EACjD,UACA,EAAE,mBAAmB,sBAAsB,CAC5C;AACD,MAAI,MAAM,SAAS;GACjB,MAAM,UAAU,MAAM,eAAe,MAAM;AAC3C,OAAI,QACF,OAAM,KAAK,aAAa,wBAAwB,MAAM,YAAY;IAChE,MAAM;IACN,SAAS,eAAe,MAAM,UAAU,OAAO,GAC3C,CAAC,MAAM,SAAS,OAAO,GACvB,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAS,CAAC;IACrC,WAAW,KAAK,KAAK;IACrB,GAAI,MAAM,YAAY,OAAO,KAAK,MAAM,SAAS,CAAC,SAAS,IACvD,EAAE,UAAU,MAAM,UAAU,GAC5B,EAAE;IACP,CAAiB;AAEpB,UAAO,MAAM,kBAAkB;;EAMjC,MAAM,cAAc,MAAM,8BAA8B;GACtD,SAJoB,SAAS,WAAW,CAAC,WAAW,UAAU,GAC5D,KAAK,aAAa,oBAAoB,SAAS,GAC/C;GAGF,aAAa;GACb,YAAY,MAAM;GAClB,QAAQ,KAAK;GACb,cAAc,KAAK;GACnB,cAAc,KAAK;GACpB,CAAC;EAEF,MAAM,qBAAqB;AAC3B,kCAAgC,MAAM,YAAY,mBAAmB;EAErE,MAAM,SAAS,OAAO,YAAY;AAChC,OAAI;AACF,WAAO,MAAM,mBACX;KAAE,GAAG;KAAM,QAAQ,KAAK;KAAQ,EAChC;KACE,YAAY,MAAM;KAClB;KACD,CACF;aACO;AACR,sCAAkC,MAAM,YAAY,mBAAmB;;MAEvE;AAEJ,MAAI,OAAO,kBACT,MAAK,iBAAiB,MAAM,YAAY,OAAO,kBAAkB;AAGnE,SAAO,OAAO,qBAAqB;WAC3B;AACR,OAAK,yBAAyB"}
1
+ {"version":3,"file":"process-direct-one-shot.js","names":[],"sources":["../../../../src/agent/service/process-direct-one-shot.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\n\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { ModelManager } from '../models/index.js';\nimport type { SessionStore } from '../../session/index.js';\nimport type { Config } from '../../config/schema.js';\nimport { initSessionTurn } from '../../session/index.js';\nimport {\n buildDirectUserMessageContent,\n} from './build-direct-message-content.js';\nimport type { ProcessDirectStreamLog } from './process-direct-streaming.js';\nimport type {\n InboundAttachmentInput,\n MediaRef,\n} from '../../channels/attachments/inbound-persist.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\nimport {\n clearPendingTranscriptUserMessage,\n setPendingTranscriptUserMessage,\n type TranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\nimport type { ReviewOutput } from '../../review/review-types.js';\n\nexport type RunProcessDirectDeps = {\n log: ProcessDirectStreamLog;\n config: Config;\n resolveSessionEndpoint: (sessionKey: string) => Promise<{ 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: AgentInstanceGateway;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: InboundAttachmentInput[],\n ) => Promise<MediaRef[] | undefined>;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n};\n\nfunction isReviewOutput(value: unknown): value is ReviewOutput {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nexport async function runProcessDirect(\n deps: RunProcessDirectDeps,\n input: {\n content: string;\n sessionKey: string;\n attachments?: InboundAttachmentInput[];\n thinking?: string;\n },\n): Promise<string> {\n const { channel, chatId } = await deps.resolveSessionEndpoint(input.sessionKey);\n deps.initSessionContext(input.sessionKey, channel, chatId);\n\n try {\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n const turn = await initSessionTurn({\n cfg: deps.config,\n sessionKey: input.sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n return turn.ackMessage;\n }\n turnBody = turn.bodyStripped;\n\n await hydratePerTurnState(deps, input.sessionKey, input.thinking);\n const prepared = await deps.prepareInboundAttachments(input.sessionKey, input.attachments);\n\n const slash = await tryRunSlashCommand(\n deps,\n { sessionKey: input.sessionKey, channel, chatId },\n turnBody,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n const trimmed = slash.aggregatedText.trim();\n if (trimmed) {\n await deps.sessionStore.appendTranscriptMessage(input.sessionKey, {\n role: 'assistant',\n content: isReviewOutput(slash.metadata?.review)\n ? [slash.metadata.review]\n : [{ type: 'text', text: trimmed }],\n timestamp: Date.now(),\n ...(slash.metadata && Object.keys(slash.metadata).length > 0\n ? { metadata: slash.metadata }\n : {}),\n } as AgentMessage);\n }\n return slash.aggregatedText ?? '';\n }\n\n const skillTurn = deps.agentManager.prepareSkillTurn(input.sessionKey, turnBody);\n const textForDirect = skillTurn.text;\n const userMessage = 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 pendingUserMessage = userMessage as TranscriptUserMessage;\n setPendingTranscriptUserMessage(input.sessionKey, pendingUserMessage);\n\n const result = await (async () => {\n try {\n return await deps.agentManager.withSkillCapabilities(\n input.sessionKey,\n skillTurn.activatedCapabilityNames,\n () =>\n runDirectAgentTurn(\n { ...deps, config: deps.config },\n {\n sessionKey: input.sessionKey,\n userMessage,\n },\n ),\n );\n } finally {\n clearPendingTranscriptUserMessage(input.sessionKey, pendingUserMessage);\n }\n })();\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(input.sessionKey, result.lastAssistantText);\n }\n\n return result.lastAssistantText ?? '';\n } finally {\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":";;;;;;AAiDA,SAAS,eAAe,OAAuC;AAC7D,QAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,IAC9D,MAA6B,SAAS;;AAG9C,eAAsB,iBACpB,MACA,OAMiB;CACjB,MAAM,EAAE,SAAS,WAAW,MAAM,KAAK,uBAAuB,MAAM,WAAW;AAC/E,MAAK,mBAAmB,MAAM,YAAY,SAAS,OAAO;AAE1D,KAAI;EACF,IAAI,WAAW,MAAM;EACrB,IAAI,uBAAuB;EAC3B,MAAM,OAAO,MAAM,gBAAgB;GACjC,KAAK,KAAK;GACV,YAAY,MAAM;GAClB,MAAM,MAAM;GACZ,cAAc,KAAK;GACpB,CAAC;AACF,yBAAuB,KAAK;AAC5B,MAAI,KAAK,aAAa,KAAK,WACzB,QAAO,KAAK;AAEd,aAAW,KAAK;AAEhB,QAAM,oBAAoB,MAAM,MAAM,YAAY,MAAM,SAAS;EACjE,MAAM,WAAW,MAAM,KAAK,0BAA0B,MAAM,YAAY,MAAM,YAAY;EAE1F,MAAM,QAAQ,MAAM,mBAClB,MACA;GAAE,YAAY,MAAM;GAAY;GAAS;GAAQ,EACjD,UACA,EAAE,mBAAmB,sBAAsB,CAC5C;AACD,MAAI,MAAM,SAAS;GACjB,MAAM,UAAU,MAAM,eAAe,MAAM;AAC3C,OAAI,QACF,OAAM,KAAK,aAAa,wBAAwB,MAAM,YAAY;IAChE,MAAM;IACN,SAAS,eAAe,MAAM,UAAU,OAAO,GAC3C,CAAC,MAAM,SAAS,OAAO,GACvB,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAS,CAAC;IACrC,WAAW,KAAK,KAAK;IACrB,GAAI,MAAM,YAAY,OAAO,KAAK,MAAM,SAAS,CAAC,SAAS,IACvD,EAAE,UAAU,MAAM,UAAU,GAC5B,EAAE;IACP,CAAiB;AAEpB,UAAO,MAAM,kBAAkB;;EAGjC,MAAM,YAAY,KAAK,aAAa,iBAAiB,MAAM,YAAY,SAAS;EAChF,MAAM,gBAAgB,UAAU;EAChC,MAAM,cAAc,MAAM,8BAA8B;GACtD,SAAS;GACT,aAAa;GACb,YAAY,MAAM;GAClB,QAAQ,KAAK;GACb,cAAc,KAAK;GACnB,cAAc,KAAK;GACpB,CAAC;EAEF,MAAM,qBAAqB;AAC3B,kCAAgC,MAAM,YAAY,mBAAmB;EAErE,MAAM,SAAS,OAAO,YAAY;AAChC,OAAI;AACF,WAAO,MAAM,KAAK,aAAa,sBAC7B,MAAM,YACN,UAAU,gCAER,mBACE;KAAE,GAAG;KAAM,QAAQ,KAAK;KAAQ,EAChC;KACE,YAAY,MAAM;KAClB;KACD,CACF,CACJ;aACO;AACR,sCAAkC,MAAM,YAAY,mBAAmB;;MAEvE;AAEJ,MAAI,OAAO,kBACT,MAAK,iBAAiB,MAAM,YAAY,OAAO,kBAAkB;AAGnE,SAAO,OAAO,qBAAqB;WAC3B;AACR,OAAK,yBAAyB"}
@@ -165,7 +165,8 @@ async function* runProcessDirectStreaming(deps, input) {
165
165
  });
166
166
  return;
167
167
  }
168
- const textForAgent = mergedUserText.trimStart().startsWith("/skill:") ? deps.agentManager.expandSkillUserText(mergedUserText) : mergedUserText;
168
+ const skillTurn = deps.agentManager.prepareSkillTurn(sessionKey, mergedUserText);
169
+ const textForAgent = skillTurn.text;
169
170
  const userMessage = await deps.buildTranscriptUserMessage(textForAgent, prepared, sessionKey);
170
171
  let sourceEnrichedUserMessage = userMessage;
171
172
  let sourceImages;
@@ -190,7 +191,7 @@ async function* runProcessDirectStreaming(deps, input) {
190
191
  const pendingUserMessage = userMessage;
191
192
  setPendingTranscriptUserMessage(sessionKey, pendingUserMessage);
192
193
  try {
193
- const result = await runDirectAgentTurn({
194
+ const result = await deps.agentManager.withSkillCapabilities(sessionKey, skillTurn.activatedCapabilityNames, () => runDirectAgentTurn({
194
195
  sessionStore: deps.sessionStore,
195
196
  agentManager: deps.agentManager,
196
197
  modelManager: deps.modelManager,
@@ -206,7 +207,7 @@ async function* runProcessDirectStreaming(deps, input) {
206
207
  if (event.type === "error" && typeof event.content === "string") event.content = formatStreamError(event.content);
207
208
  pushVisible(event);
208
209
  }
209
- });
210
+ }));
210
211
  if (result.lastAssistantText) deps.onTurnComplete?.(sessionKey, result.lastAssistantText);
211
212
  if (!result.ok && result.errorMessage && !abortHandled) pushVisible({
212
213
  type: "error",
@@ -1 +1 @@
1
- {"version":3,"file":"process-direct-streaming.js","names":[],"sources":["../../../../src/agent/service/process-direct-streaming.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { ImageContent } from '@earendil-works/pi-ai';\n\nimport type { Config } from '../../config/schema.js';\nimport type { InboundAttachmentInput, MediaRef } from '../../channels/attachments/inbound-persist.js';\nimport { readAgentMessageContent } from '../memory/agent-message-access.js';\nimport {\n isVoiceLikeAttachment,\n mergeVoiceTranscriptsIntoUserText,\n mergeSttConfigFromAppConfig,\n} from '../../channels/attachments/voice-stt-webchat.js';\nimport {\n resolveEffectiveReasoningLevel,\n initSessionTurn,\n type SessionConfigStore,\n type SessionStore,\n} from '../../session/index.js';\nimport type { SessionContext } from '../session/index.js';\nimport { applyReasoningVisibilityToSseEvent } from '../streaming/reasoning-visibility-sse.js';\nimport type { ReasoningLevel } from '../transcript/thinking-types.js';\nimport { formatAgentRunErrorForClient } from '../client-error-format.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\nimport { injectSourceContextIntoUserMessage } from '../source-context/injector.js';\nimport { isSessionSourceBinding, type AgentSourceContextResolver } from '../source-context/types.js';\nimport type { ReviewOutput } from '../../review/review-types.js';\n\nimport { AsyncQueue } from './async-queue.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\nimport {\n clearPendingTranscriptUserMessage,\n setPendingTranscriptUserMessage,\n type TranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\n\nexport type DirectStreamInboundAttachment = InboundAttachmentInput;\n\nexport type ProcessDirectStreamLog = {\n info: (obj: Record<string, unknown>, msg: string) => void;\n warn: (obj: Record<string, unknown>, msg: string) => void;\n debug?: (obj: Record<string, unknown>, msg: string) => void;\n};\n\nexport interface ProcessDirectStreamingDeps {\n log: ProcessDirectStreamLog;\n resolveSessionEndpoint: (sessionKey: string) => Promise<{ channel: string; chatId: string }>;\n initDirectStreamingSession: (\n sessionKey: string,\n channel: string,\n chatId: string,\n ) => SessionContext;\n registerWebchatSsePublisher: (\n sessionKey: string,\n publisher: (event: { type: string; [key: string]: unknown }) => void,\n ) => void;\n unregisterWebchatSsePublisher: (sessionKey: string) => void;\n agentManager: AgentInstanceGateway;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n getConfig: () => Config | undefined;\n sessionConfigStore: SessionConfigStore;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<MediaRef[] | undefined>;\n buildTranscriptUserMessage: (\n content: string,\n prepared: MediaRef[] | undefined,\n sessionKey: string,\n ) => Promise<TranscriptUserMessage>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n /** Disk-only transcript sync (slash receipt already streamed as tokens). */\n reloadWebchatTranscript?: (sessionKey: string) => void;\n maybeEmitWebchatTts: (\n sessionKey: string,\n hadInboundVoice: boolean,\n ) => Promise<{ type: 'tts_audio'; uri: string; mimeType: string; name: string } | null>;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n sourceContextResolver?: AgentSourceContextResolver;\n}\n\nexport interface ProcessDirectStreamingInput {\n content: string;\n sessionKey?: string;\n attachments?: DirectStreamInboundAttachment[];\n thinking?: string;\n signal?: AbortSignal;\n runId?: string;\n}\n\nexport type ProcessDirectStreamingSseEvent = { type: string; [key: string]: unknown };\n\nfunction isReviewOutput(value: unknown): value is ReviewOutput {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nfunction makeAssistantReceiptMessage(text: string, metadata?: Record<string, unknown>): AgentMessage {\n const review = isReviewOutput(metadata?.review) ? metadata.review : undefined;\n return {\n role: 'assistant',\n content: review ? [review] : [{ type: 'text', text }],\n timestamp: Date.now(),\n ...(metadata && Object.keys(metadata).length > 0 ? { metadata } : {}),\n } as AgentMessage;\n}\n\nfunction pushAssistantReceipt(\n queue: AsyncQueue<ProcessDirectStreamingSseEvent>,\n text: string,\n runId?: string,\n metadata?: Record<string, unknown>,\n): void {\n const message = makeAssistantReceiptMessage(text, metadata);\n queue.push({ type: 'message_start', runId, message });\n queue.push({ type: 'message_update', runId, message });\n queue.push({ type: 'message_end', runId, message });\n}\n\nexport async function* runProcessDirectStreaming(\n deps: ProcessDirectStreamingDeps,\n input: ProcessDirectStreamingInput,\n): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n const sessionKey = input.sessionKey ?? 'agent:main:main';\n const { channel, chatId } = await deps.resolveSessionEndpoint(sessionKey);\n const context = deps.initDirectStreamingSession(sessionKey, channel, chatId);\n\n const queue = new AsyncQueue<ProcessDirectStreamingSseEvent>();\n let reasoningLevel: ReasoningLevel = 'stream';\n\n const pushVisible = (event: ProcessDirectStreamingSseEvent) => {\n const visible = applyReasoningVisibilityToSseEvent(event, reasoningLevel);\n if (visible !== null) {\n queue.push(visible);\n }\n };\n\n const formatStreamError = (raw: string): string => {\n let provider: string | undefined;\n let modelRef: string | undefined;\n try {\n const resolved = deps.modelManager.getResolvedModelForSession(sessionKey);\n provider = resolved.provider;\n modelRef = deps.modelManager.getModelForSession(sessionKey);\n } catch {\n /* ignore — format without provider context */\n }\n return formatAgentRunErrorForClient(raw, { provider, modelRef });\n };\n\n if (channel === 'webchat') {\n deps.registerWebchatSsePublisher(sessionKey, pushVisible);\n }\n\n const signal = input.signal;\n let userAborted = false;\n let abortHandled = false;\n let inboundVoice = false;\n let ranSlashCommand = false;\n let mergedUserText = input.content;\n let webchatSlashReceipt: string | undefined;\n let slashCommandMetadata: Record<string, unknown> | undefined;\n\n const taskPromise = (async () => {\n try {\n const cfg = deps.getConfig();\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n if (cfg) {\n const turn = await initSessionTurn({\n cfg,\n sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n ranSlashCommand = true;\n webchatSlashReceipt = turn.ackMessage;\n pushAssistantReceipt(queue, turn.ackMessage, input.runId);\n return;\n }\n turnBody = turn.bodyStripped;\n if (turn.isNewSession) {\n deps.log.debug(\n {\n sessionKey,\n sessionId: turn.sessionId,\n previousSessionId: turn.previousSessionId,\n resetTriggered: turn.resetTriggered,\n staleRollover: turn.staleRollover,\n },\n 'Session reset boundary at direct turn start',\n );\n }\n }\n\n await hydratePerTurnState(deps, sessionKey, input.thinking);\n {\n const defReason = 'stream' as ReasoningLevel;\n reasoningLevel = await resolveEffectiveReasoningLevel(deps.sessionConfigStore, sessionKey, defReason);\n }\n\n const prepared = await deps.prepareInboundAttachments(sessionKey, input.attachments);\n\n const sttCfg = mergeSttConfigFromAppConfig(deps.getConfig()?.tools?.media?.audio, deps.getConfig()?.tools?.media);\n const voiceMerge = await mergeVoiceTranscriptsIntoUserText(prepared, turnBody, sttCfg);\n mergedUserText = voiceMerge.text;\n inboundVoice = voiceMerge.inboundVoice;\n\n if (inboundVoice) {\n const transcriptParts = [\n voiceMerge.voiceTranscripts.filter(Boolean).join('\\n'),\n turnBody.trim(),\n ].filter(Boolean);\n const voiceMedia = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n uri: att.uri,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n media: voiceMedia,\n });\n }\n\n const armAbort = () => {\n if (abortHandled) {\n return;\n }\n abortHandled = true;\n userAborted = true;\n void abortEmbeddedRun(sessionKey);\n queue.close();\n };\n if (signal) {\n if (signal.aborted) {\n armAbort();\n return;\n }\n signal.addEventListener('abort', armAbort, { once: true });\n }\n\n const slash = await tryRunSlashCommand(\n deps,\n {\n sessionKey,\n channel,\n chatId,\n senderId: context.senderId,\n isGroup: context.isGroup,\n inboundMetadata: context.metadata,\n },\n mergedUserText,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n ranSlashCommand = true;\n slashCommandMetadata = slash.metadata;\n const text = slash.aggregatedText.trim();\n if (text) {\n webchatSlashReceipt = text;\n pushAssistantReceipt(queue, text, input.runId, slashCommandMetadata);\n } else if (channel === 'webchat') {\n webchatSlashReceipt =\n 'Command finished with no assistant text. If you used `/goal`, a follow-up turn may still be scheduled automatically.';\n pushAssistantReceipt(queue, webchatSlashReceipt, input.runId);\n }\n const workflowRun = slash.metadata?.workflowRun;\n if (workflowRun && typeof workflowRun === 'object') {\n queue.push({\n type: 'workflow_run_started',\n runId: input.runId,\n payload: { workflowRun },\n });\n }\n return;\n }\n\n const textForAgent = mergedUserText.trimStart().startsWith('/skill:')\n ? deps.agentManager.expandSkillUserText(mergedUserText)\n : mergedUserText;\n const userMessage = await deps.buildTranscriptUserMessage(textForAgent, prepared, sessionKey);\n let sourceEnrichedUserMessage: AgentMessage = userMessage;\n let sourceImages: ImageContent[] | undefined;\n if (deps.sourceContextResolver) {\n const metadata = await deps.sessionStore.getMetadata(sessionKey).catch(() => null);\n const sourceBinding = metadata?.customData && typeof metadata.customData === 'object'\n ? (metadata.customData as Record<string, unknown>).sourceBinding\n : undefined;\n if (isSessionSourceBinding(sourceBinding)) {\n const sourceContext = await deps.sourceContextResolver(sourceBinding, sessionKey);\n sourceEnrichedUserMessage = injectSourceContextIntoUserMessage(userMessage, sourceContext);\n sourceImages = sourceContext?.images;\n }\n }\n\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp ?? Date.now(),\n content: readAgentMessageContent(userMessage),\n media: userMessage.media,\n });\n if (textForAgent.trim()) {\n deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);\n }\n }\n\n const pendingUserMessage = userMessage as TranscriptUserMessage;\n setPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\n\n try {\n const result = await runDirectAgentTurn(\n {\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n config: deps.getConfig(),\n },\n {\n sessionKey,\n userMessage: sourceEnrichedUserMessage,\n abortSignal: signal,\n sourceImages,\n runId: input.runId,\n onEvent: (embeddedEvent) => {\n const event = { ...embeddedEvent };\n if (event.type === 'error' && typeof event.content === 'string') {\n event.content = formatStreamError(event.content);\n }\n pushVisible(event);\n },\n },\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(sessionKey, result.lastAssistantText);\n }\n if (!result.ok && result.errorMessage && !abortHandled) {\n pushVisible({ type: 'error', content: formatStreamError(result.errorMessage) });\n }\n } finally {\n clearPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\n }\n } catch (err) {\n if (!abortHandled) {\n const em = err instanceof Error ? err.message : String(err);\n pushVisible({ type: 'error', content: formatStreamError(em) });\n }\n } finally {\n if (!userAborted && channel === 'webchat') {\n try {\n const ttsAudioEvent = await deps.maybeEmitWebchatTts(sessionKey, inboundVoice);\n if (ttsAudioEvent) {\n queue.push(ttsAudioEvent);\n }\n } catch (ttsErr) {\n deps.log.warn({ err: ttsErr, sessionKey }, 'Failed to emit TTS audio before stream close');\n }\n }\n queue.close();\n }\n })();\n\n try {\n for await (const event of queue) {\n yield event;\n }\n await taskPromise;\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\n const userMsg = {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: mergedUserText }],\n timestamp: Date.now(),\n } as AgentMessage;\n await deps.sessionStore.appendTranscriptMessage(sessionKey, userMsg);\n if (webchatSlashReceipt?.trim()) {\n const assistantMsg = {\n role: 'assistant' as const,\n content: isReviewOutput(slashCommandMetadata?.review)\n ? [slashCommandMetadata.review]\n : [{ type: 'text' as const, text: webchatSlashReceipt.trim() }],\n timestamp: Date.now(),\n ...(slashCommandMetadata && Object.keys(slashCommandMetadata).length > 0\n ? { metadata: slashCommandMetadata }\n : {}),\n } as AgentMessage;\n await deps.sessionStore.appendTranscriptMessage(sessionKey, assistantMsg);\n }\n deps.reloadWebchatTranscript?.(sessionKey);\n } catch (err) {\n deps.log.warn({ err, sessionKey }, 'Failed to persist webchat slash command receipt');\n }\n }\n\n deps.recordPersistentGoalStreamOutcome?.(sessionKey, { skipPersistentGoalPostTurn: ranSlashCommand });\n } finally {\n if (channel === 'webchat') {\n deps.unregisterWebchatSsePublisher(sessionKey);\n }\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"process-direct-streaming.js","names":[],"sources":["../../../../src/agent/service/process-direct-streaming.ts"],"sourcesContent":["import type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { ImageContent } from '@earendil-works/pi-ai';\n\nimport type { Config } from '../../config/schema.js';\nimport type { InboundAttachmentInput, MediaRef } from '../../channels/attachments/inbound-persist.js';\nimport { readAgentMessageContent } from '../memory/agent-message-access.js';\nimport {\n isVoiceLikeAttachment,\n mergeVoiceTranscriptsIntoUserText,\n mergeSttConfigFromAppConfig,\n} from '../../channels/attachments/voice-stt-webchat.js';\nimport {\n resolveEffectiveReasoningLevel,\n initSessionTurn,\n type SessionConfigStore,\n type SessionStore,\n} from '../../session/index.js';\nimport type { SessionContext } from '../session/index.js';\nimport { applyReasoningVisibilityToSseEvent } from '../streaming/reasoning-visibility-sse.js';\nimport type { ReasoningLevel } from '../transcript/thinking-types.js';\nimport { formatAgentRunErrorForClient } from '../client-error-format.js';\nimport { abortEmbeddedRun } from '../embedded/runs.js';\nimport type { AgentInstanceGateway } from '../agent-instance-gateway.js';\nimport type { CommandHandler } from '../messaging/command-handler.js';\nimport type { ModelManager } from '../models/index.js';\nimport { injectSourceContextIntoUserMessage } from '../source-context/injector.js';\nimport { isSessionSourceBinding, type AgentSourceContextResolver } from '../source-context/types.js';\nimport type { ReviewOutput } from '../../review/review-types.js';\n\nimport { AsyncQueue } from './async-queue.js';\nimport {\n hydratePerTurnState,\n runDirectAgentTurn,\n tryRunSlashCommand,\n} from './direct-turn-helpers.js';\nimport {\n clearPendingTranscriptUserMessage,\n setPendingTranscriptUserMessage,\n type TranscriptUserMessage,\n} from '../inbound/attachment-pipeline.js';\n\nexport type DirectStreamInboundAttachment = InboundAttachmentInput;\n\nexport type ProcessDirectStreamLog = {\n info: (obj: Record<string, unknown>, msg: string) => void;\n warn: (obj: Record<string, unknown>, msg: string) => void;\n debug?: (obj: Record<string, unknown>, msg: string) => void;\n};\n\nexport interface ProcessDirectStreamingDeps {\n log: ProcessDirectStreamLog;\n resolveSessionEndpoint: (sessionKey: string) => Promise<{ channel: string; chatId: string }>;\n initDirectStreamingSession: (\n sessionKey: string,\n channel: string,\n chatId: string,\n ) => SessionContext;\n registerWebchatSsePublisher: (\n sessionKey: string,\n publisher: (event: { type: string; [key: string]: unknown }) => void,\n ) => void;\n unregisterWebchatSsePublisher: (sessionKey: string) => void;\n agentManager: AgentInstanceGateway;\n hydrateSessionWorkspaceFromStore: (sessionKey: string) => Promise<void>;\n hydrateSessionModelFromStore: (sessionKey: string) => Promise<void>;\n sessionStore: SessionStore;\n modelManager: ModelManager;\n applyResolvedThinkingLevel: (sessionKey: string, thinking?: string | null) => Promise<void>;\n getConfig: () => Config | undefined;\n sessionConfigStore: SessionConfigStore;\n commandHandler: Pick<CommandHandler, 'executeCommandAndAggregateReply'>;\n prepareInboundAttachments: (\n sessionKey: string,\n attachments?: DirectStreamInboundAttachment[],\n ) => Promise<MediaRef[] | undefined>;\n buildTranscriptUserMessage: (\n content: string,\n prepared: MediaRef[] | undefined,\n sessionKey: string,\n ) => Promise<TranscriptUserMessage>;\n recordPersistentGoalStreamOutcome?: (\n sessionKey: string,\n outcome: { skipPersistentGoalPostTurn: boolean },\n ) => void;\n onTurnComplete?: (sessionKey: string, lastAssistantText?: string) => void;\n enqueueProvisionalSessionTitle?: (sessionKey: string, userText: string) => void;\n /** Disk-only transcript sync (slash receipt already streamed as tokens). */\n reloadWebchatTranscript?: (sessionKey: string) => void;\n maybeEmitWebchatTts: (\n sessionKey: string,\n hadInboundVoice: boolean,\n ) => Promise<{ type: 'tts_audio'; uri: string; mimeType: string; name: string } | null>;\n endDirectRequestContext: () => void;\n resetSession: (sessionKey: string) => Promise<{ sessionId: string; previousSessionId: string } | null>;\n sourceContextResolver?: AgentSourceContextResolver;\n}\n\nexport interface ProcessDirectStreamingInput {\n content: string;\n sessionKey?: string;\n attachments?: DirectStreamInboundAttachment[];\n thinking?: string;\n signal?: AbortSignal;\n runId?: string;\n}\n\nexport type ProcessDirectStreamingSseEvent = { type: string; [key: string]: unknown };\n\nfunction isReviewOutput(value: unknown): value is ReviewOutput {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n && (value as { type?: unknown }).type === 'review';\n}\n\nfunction makeAssistantReceiptMessage(text: string, metadata?: Record<string, unknown>): AgentMessage {\n const review = isReviewOutput(metadata?.review) ? metadata.review : undefined;\n return {\n role: 'assistant',\n content: review ? [review] : [{ type: 'text', text }],\n timestamp: Date.now(),\n ...(metadata && Object.keys(metadata).length > 0 ? { metadata } : {}),\n } as AgentMessage;\n}\n\nfunction pushAssistantReceipt(\n queue: AsyncQueue<ProcessDirectStreamingSseEvent>,\n text: string,\n runId?: string,\n metadata?: Record<string, unknown>,\n): void {\n const message = makeAssistantReceiptMessage(text, metadata);\n queue.push({ type: 'message_start', runId, message });\n queue.push({ type: 'message_update', runId, message });\n queue.push({ type: 'message_end', runId, message });\n}\n\nexport async function* runProcessDirectStreaming(\n deps: ProcessDirectStreamingDeps,\n input: ProcessDirectStreamingInput,\n): AsyncGenerator<ProcessDirectStreamingSseEvent, void, unknown> {\n const sessionKey = input.sessionKey ?? 'agent:main:main';\n const { channel, chatId } = await deps.resolveSessionEndpoint(sessionKey);\n const context = deps.initDirectStreamingSession(sessionKey, channel, chatId);\n\n const queue = new AsyncQueue<ProcessDirectStreamingSseEvent>();\n let reasoningLevel: ReasoningLevel = 'stream';\n\n const pushVisible = (event: ProcessDirectStreamingSseEvent) => {\n const visible = applyReasoningVisibilityToSseEvent(event, reasoningLevel);\n if (visible !== null) {\n queue.push(visible);\n }\n };\n\n const formatStreamError = (raw: string): string => {\n let provider: string | undefined;\n let modelRef: string | undefined;\n try {\n const resolved = deps.modelManager.getResolvedModelForSession(sessionKey);\n provider = resolved.provider;\n modelRef = deps.modelManager.getModelForSession(sessionKey);\n } catch {\n /* ignore — format without provider context */\n }\n return formatAgentRunErrorForClient(raw, { provider, modelRef });\n };\n\n if (channel === 'webchat') {\n deps.registerWebchatSsePublisher(sessionKey, pushVisible);\n }\n\n const signal = input.signal;\n let userAborted = false;\n let abortHandled = false;\n let inboundVoice = false;\n let ranSlashCommand = false;\n let mergedUserText = input.content;\n let webchatSlashReceipt: string | undefined;\n let slashCommandMetadata: Record<string, unknown> | undefined;\n\n const taskPromise = (async () => {\n try {\n const cfg = deps.getConfig();\n let turnBody = input.content;\n let resetTriggeredAtInit = false;\n if (cfg) {\n const turn = await initSessionTurn({\n cfg,\n sessionKey,\n body: input.content,\n resetSession: deps.resetSession,\n });\n resetTriggeredAtInit = turn.resetTriggered;\n if (turn.bareReset && turn.ackMessage) {\n ranSlashCommand = true;\n webchatSlashReceipt = turn.ackMessage;\n pushAssistantReceipt(queue, turn.ackMessage, input.runId);\n return;\n }\n turnBody = turn.bodyStripped;\n if (turn.isNewSession) {\n deps.log.debug(\n {\n sessionKey,\n sessionId: turn.sessionId,\n previousSessionId: turn.previousSessionId,\n resetTriggered: turn.resetTriggered,\n staleRollover: turn.staleRollover,\n },\n 'Session reset boundary at direct turn start',\n );\n }\n }\n\n await hydratePerTurnState(deps, sessionKey, input.thinking);\n {\n const defReason = 'stream' as ReasoningLevel;\n reasoningLevel = await resolveEffectiveReasoningLevel(deps.sessionConfigStore, sessionKey, defReason);\n }\n\n const prepared = await deps.prepareInboundAttachments(sessionKey, input.attachments);\n\n const sttCfg = mergeSttConfigFromAppConfig(deps.getConfig()?.tools?.media?.audio, deps.getConfig()?.tools?.media);\n const voiceMerge = await mergeVoiceTranscriptsIntoUserText(prepared, turnBody, sttCfg);\n mergedUserText = voiceMerge.text;\n inboundVoice = voiceMerge.inboundVoice;\n\n if (inboundVoice) {\n const transcriptParts = [\n voiceMerge.voiceTranscripts.filter(Boolean).join('\\n'),\n turnBody.trim(),\n ].filter(Boolean);\n const voiceMedia = (prepared ?? []).filter(isVoiceLikeAttachment).map((att) => ({\n uri: att.uri,\n mimeType: att.mimeType,\n name: att.name,\n }));\n pushVisible({\n type: 'user_transcript',\n text: transcriptParts.join('\\n\\n'),\n media: voiceMedia,\n });\n }\n\n const armAbort = () => {\n if (abortHandled) {\n return;\n }\n abortHandled = true;\n userAborted = true;\n void abortEmbeddedRun(sessionKey);\n queue.close();\n };\n if (signal) {\n if (signal.aborted) {\n armAbort();\n return;\n }\n signal.addEventListener('abort', armAbort, { once: true });\n }\n\n const slash = await tryRunSlashCommand(\n deps,\n {\n sessionKey,\n channel,\n chatId,\n senderId: context.senderId,\n isGroup: context.isGroup,\n inboundMetadata: context.metadata,\n },\n mergedUserText,\n { skipResetCommands: resetTriggeredAtInit },\n );\n if (slash.matched) {\n ranSlashCommand = true;\n slashCommandMetadata = slash.metadata;\n const text = slash.aggregatedText.trim();\n if (text) {\n webchatSlashReceipt = text;\n pushAssistantReceipt(queue, text, input.runId, slashCommandMetadata);\n } else if (channel === 'webchat') {\n webchatSlashReceipt =\n 'Command finished with no assistant text. If you used `/goal`, a follow-up turn may still be scheduled automatically.';\n pushAssistantReceipt(queue, webchatSlashReceipt, input.runId);\n }\n const workflowRun = slash.metadata?.workflowRun;\n if (workflowRun && typeof workflowRun === 'object') {\n queue.push({\n type: 'workflow_run_started',\n runId: input.runId,\n payload: { workflowRun },\n });\n }\n return;\n }\n\n const skillTurn = deps.agentManager.prepareSkillTurn(sessionKey, mergedUserText);\n const textForAgent = skillTurn.text;\n const userMessage = await deps.buildTranscriptUserMessage(textForAgent, prepared, sessionKey);\n let sourceEnrichedUserMessage: AgentMessage = userMessage;\n let sourceImages: ImageContent[] | undefined;\n if (deps.sourceContextResolver) {\n const metadata = await deps.sessionStore.getMetadata(sessionKey).catch(() => null);\n const sourceBinding = metadata?.customData && typeof metadata.customData === 'object'\n ? (metadata.customData as Record<string, unknown>).sourceBinding\n : undefined;\n if (isSessionSourceBinding(sourceBinding)) {\n const sourceContext = await deps.sourceContextResolver(sourceBinding, sessionKey);\n sourceEnrichedUserMessage = injectSourceContextIntoUserMessage(userMessage, sourceContext);\n sourceImages = sourceContext?.images;\n }\n }\n\n if (channel === 'webchat') {\n pushVisible({\n type: 'user_message',\n timestamp: userMessage.timestamp ?? Date.now(),\n content: readAgentMessageContent(userMessage),\n media: userMessage.media,\n });\n if (textForAgent.trim()) {\n deps.enqueueProvisionalSessionTitle?.(sessionKey, textForAgent);\n }\n }\n\n const pendingUserMessage = userMessage as TranscriptUserMessage;\n setPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\n\n try {\n const result = await deps.agentManager.withSkillCapabilities(\n sessionKey,\n skillTurn.activatedCapabilityNames,\n () =>\n runDirectAgentTurn(\n {\n sessionStore: deps.sessionStore,\n agentManager: deps.agentManager,\n modelManager: deps.modelManager,\n config: deps.getConfig(),\n },\n {\n sessionKey,\n userMessage: sourceEnrichedUserMessage,\n abortSignal: signal,\n sourceImages,\n runId: input.runId,\n onEvent: (embeddedEvent) => {\n const event = { ...embeddedEvent };\n if (event.type === 'error' && typeof event.content === 'string') {\n event.content = formatStreamError(event.content);\n }\n pushVisible(event);\n },\n },\n ),\n );\n\n if (result.lastAssistantText) {\n deps.onTurnComplete?.(sessionKey, result.lastAssistantText);\n }\n if (!result.ok && result.errorMessage && !abortHandled) {\n pushVisible({ type: 'error', content: formatStreamError(result.errorMessage) });\n }\n } finally {\n clearPendingTranscriptUserMessage(sessionKey, pendingUserMessage);\n }\n } catch (err) {\n if (!abortHandled) {\n const em = err instanceof Error ? err.message : String(err);\n pushVisible({ type: 'error', content: formatStreamError(em) });\n }\n } finally {\n if (!userAborted && channel === 'webchat') {\n try {\n const ttsAudioEvent = await deps.maybeEmitWebchatTts(sessionKey, inboundVoice);\n if (ttsAudioEvent) {\n queue.push(ttsAudioEvent);\n }\n } catch (ttsErr) {\n deps.log.warn({ err: ttsErr, sessionKey }, 'Failed to emit TTS audio before stream close');\n }\n }\n queue.close();\n }\n })();\n\n try {\n for await (const event of queue) {\n yield event;\n }\n await taskPromise;\n\n if (channel === 'webchat' && ranSlashCommand) {\n try {\n const userMsg = {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: mergedUserText }],\n timestamp: Date.now(),\n } as AgentMessage;\n await deps.sessionStore.appendTranscriptMessage(sessionKey, userMsg);\n if (webchatSlashReceipt?.trim()) {\n const assistantMsg = {\n role: 'assistant' as const,\n content: isReviewOutput(slashCommandMetadata?.review)\n ? [slashCommandMetadata.review]\n : [{ type: 'text' as const, text: webchatSlashReceipt.trim() }],\n timestamp: Date.now(),\n ...(slashCommandMetadata && Object.keys(slashCommandMetadata).length > 0\n ? { metadata: slashCommandMetadata }\n : {}),\n } as AgentMessage;\n await deps.sessionStore.appendTranscriptMessage(sessionKey, assistantMsg);\n }\n deps.reloadWebchatTranscript?.(sessionKey);\n } catch (err) {\n deps.log.warn({ err, sessionKey }, 'Failed to persist webchat slash command receipt');\n }\n }\n\n deps.recordPersistentGoalStreamOutcome?.(sessionKey, { skipPersistentGoalPostTurn: ranSlashCommand });\n } finally {\n if (channel === 'webchat') {\n deps.unregisterWebchatSsePublisher(sessionKey);\n }\n deps.endDirectRequestContext();\n }\n}\n"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { TurnDispatcher } from './inbound/turn-dispatcher.js';
7
7
  import { SessionConfigService, SessionHydrator, SessionInspector } from './session/index.js';
8
8
  import { type AgentSkillAvailabilityPayload, type SkillCatalogEntry, type SkillCatalogSnapshot } from './agent-manager.js';
9
9
  import type { SkillMarkdownPreviewPayload } from './skills/types.js';
10
+ import type { AgentCapabilityCatalogEntry } from './capabilities/index.js';
10
11
  import type { AgentServiceConfig, StreamHandle } from './service.types.js';
11
12
  import { PersistentGoalService } from './goals/persistent-goal-service.js';
12
13
  import { type InboundAttachmentInput, type MediaRef } from '../channels/attachments/inbound-persist.js';
@@ -109,6 +110,7 @@ export declare class AgentService {
109
110
  getSkillCatalog(): SkillCatalogEntry[];
110
111
  getSkillCatalogSnapshot(): SkillCatalogSnapshot;
111
112
  getAgentSkillAvailability(agentId: string): AgentSkillAvailabilityPayload;
113
+ getCapabilityCatalog(sessionKey?: string): AgentCapabilityCatalogEntry[];
112
114
  getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null;
113
115
  refreshSkillsAfterDiskChange(): void;
114
116
  refreshSkillsAfterSkillConfigChange(): void;
@@ -517,6 +517,9 @@ var AgentService = class {
517
517
  getAgentSkillAvailability(agentId) {
518
518
  return this.agentManager.getAgentSkillAvailability(agentId);
519
519
  }
520
+ getCapabilityCatalog(sessionKey) {
521
+ return this.agentManager.getCapabilityCatalogForSession(sessionKey);
522
+ }
520
523
  getSkillMarkdownSource(skillName) {
521
524
  return this.agentManager.getSkillMarkdownSource(skillName);
522
525
  }