agent-world 0.13.0 → 0.15.0

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 (263) hide show
  1. package/README.md +90 -17
  2. package/dist/cli/commands.d.ts +7 -1
  3. package/dist/cli/commands.js +27 -10
  4. package/dist/cli/hitl.d.ts +4 -1
  5. package/dist/cli/hitl.js +55 -20
  6. package/dist/cli/index.js +249 -97
  7. package/dist/cli/system-events.d.ts +27 -0
  8. package/dist/cli/system-events.js +63 -0
  9. package/dist/core/activity-tracker.d.ts +26 -0
  10. package/dist/core/activity-tracker.d.ts.map +1 -1
  11. package/dist/core/activity-tracker.js +21 -4
  12. package/dist/core/activity-tracker.js.map +1 -1
  13. package/dist/core/anthropic-direct.d.ts +2 -0
  14. package/dist/core/anthropic-direct.d.ts.map +1 -1
  15. package/dist/core/anthropic-direct.js +43 -1
  16. package/dist/core/anthropic-direct.js.map +1 -1
  17. package/dist/core/chat-constants.d.ts +12 -0
  18. package/dist/core/chat-constants.d.ts.map +1 -1
  19. package/dist/core/chat-constants.js +5 -0
  20. package/dist/core/chat-constants.js.map +1 -1
  21. package/dist/core/create-agent-tool.d.ts +5 -0
  22. package/dist/core/create-agent-tool.d.ts.map +1 -1
  23. package/dist/core/create-agent-tool.js +57 -34
  24. package/dist/core/create-agent-tool.js.map +1 -1
  25. package/dist/core/events/index.d.ts +5 -2
  26. package/dist/core/events/index.d.ts.map +1 -1
  27. package/dist/core/events/index.js +5 -2
  28. package/dist/core/events/index.js.map +1 -1
  29. package/dist/core/events/memory-manager.d.ts +26 -1
  30. package/dist/core/events/memory-manager.d.ts.map +1 -1
  31. package/dist/core/events/memory-manager.js +877 -72
  32. package/dist/core/events/memory-manager.js.map +1 -1
  33. package/dist/core/events/orchestrator.d.ts +8 -0
  34. package/dist/core/events/orchestrator.d.ts.map +1 -1
  35. package/dist/core/events/orchestrator.js +203 -36
  36. package/dist/core/events/orchestrator.js.map +1 -1
  37. package/dist/core/events/persistence.d.ts +21 -14
  38. package/dist/core/events/persistence.d.ts.map +1 -1
  39. package/dist/core/events/persistence.js +100 -35
  40. package/dist/core/events/persistence.js.map +1 -1
  41. package/dist/core/events/publishers.d.ts +13 -7
  42. package/dist/core/events/publishers.d.ts.map +1 -1
  43. package/dist/core/events/publishers.js +53 -37
  44. package/dist/core/events/publishers.js.map +1 -1
  45. package/dist/core/events/subscribers.d.ts +17 -14
  46. package/dist/core/events/subscribers.d.ts.map +1 -1
  47. package/dist/core/events/subscribers.js +61 -148
  48. package/dist/core/events/subscribers.js.map +1 -1
  49. package/dist/core/events/title-scheduler.d.ts +27 -0
  50. package/dist/core/events/title-scheduler.d.ts.map +1 -0
  51. package/dist/core/events/title-scheduler.js +135 -0
  52. package/dist/core/events/title-scheduler.js.map +1 -0
  53. package/dist/core/events/tool-bridge-logging.d.ts +4 -1
  54. package/dist/core/events/tool-bridge-logging.d.ts.map +1 -1
  55. package/dist/core/events/tool-bridge-logging.js +112 -13
  56. package/dist/core/events/tool-bridge-logging.js.map +1 -1
  57. package/dist/core/events-metadata.d.ts.map +1 -1
  58. package/dist/core/events-metadata.js +8 -4
  59. package/dist/core/events-metadata.js.map +1 -1
  60. package/dist/core/export.d.ts +1 -1
  61. package/dist/core/export.d.ts.map +1 -1
  62. package/dist/core/export.js +2 -15
  63. package/dist/core/export.js.map +1 -1
  64. package/dist/core/feature-path-logging.d.ts +50 -0
  65. package/dist/core/feature-path-logging.d.ts.map +1 -0
  66. package/dist/core/feature-path-logging.js +130 -0
  67. package/dist/core/feature-path-logging.js.map +1 -0
  68. package/dist/core/file-tools.d.ts +57 -1
  69. package/dist/core/file-tools.d.ts.map +1 -1
  70. package/dist/core/file-tools.js +329 -29
  71. package/dist/core/file-tools.js.map +1 -1
  72. package/dist/core/google-direct.d.ts +6 -1
  73. package/dist/core/google-direct.d.ts.map +1 -1
  74. package/dist/core/google-direct.js +76 -7
  75. package/dist/core/google-direct.js.map +1 -1
  76. package/dist/core/heartbeat.d.ts +34 -0
  77. package/dist/core/heartbeat.d.ts.map +1 -0
  78. package/dist/core/heartbeat.js +153 -0
  79. package/dist/core/heartbeat.js.map +1 -0
  80. package/dist/core/hitl-tool.d.ts +6 -12
  81. package/dist/core/hitl-tool.d.ts.map +1 -1
  82. package/dist/core/hitl-tool.js +66 -88
  83. package/dist/core/hitl-tool.js.map +1 -1
  84. package/dist/core/hitl.d.ts +61 -4
  85. package/dist/core/hitl.d.ts.map +1 -1
  86. package/dist/core/hitl.js +324 -60
  87. package/dist/core/hitl.js.map +1 -1
  88. package/dist/core/index.d.ts +11 -7
  89. package/dist/core/index.d.ts.map +1 -1
  90. package/dist/core/index.js +10 -6
  91. package/dist/core/index.js.map +1 -1
  92. package/dist/core/llm-manager.d.ts +15 -0
  93. package/dist/core/llm-manager.d.ts.map +1 -1
  94. package/dist/core/llm-manager.js +325 -40
  95. package/dist/core/llm-manager.js.map +1 -1
  96. package/dist/core/load-skill-tool.d.ts +36 -3
  97. package/dist/core/load-skill-tool.d.ts.map +1 -1
  98. package/dist/core/load-skill-tool.js +807 -93
  99. package/dist/core/load-skill-tool.js.map +1 -1
  100. package/dist/core/logger.d.ts +14 -0
  101. package/dist/core/logger.d.ts.map +1 -1
  102. package/dist/core/logger.js +15 -0
  103. package/dist/core/logger.js.map +1 -1
  104. package/dist/core/managers.d.ts +18 -50
  105. package/dist/core/managers.d.ts.map +1 -1
  106. package/dist/core/managers.js +340 -502
  107. package/dist/core/managers.js.map +1 -1
  108. package/dist/core/mcp-server-registry.d.ts +16 -1
  109. package/dist/core/mcp-server-registry.d.ts.map +1 -1
  110. package/dist/core/mcp-server-registry.js +162 -12
  111. package/dist/core/mcp-server-registry.js.map +1 -1
  112. package/dist/core/message-cutoff.d.ts +29 -0
  113. package/dist/core/message-cutoff.d.ts.map +1 -0
  114. package/dist/core/message-cutoff.js +63 -0
  115. package/dist/core/message-cutoff.js.map +1 -0
  116. package/dist/core/message-edit-manager.d.ts +54 -0
  117. package/dist/core/message-edit-manager.d.ts.map +1 -0
  118. package/dist/core/message-edit-manager.js +602 -0
  119. package/dist/core/message-edit-manager.js.map +1 -0
  120. package/dist/core/message-prep.d.ts +2 -0
  121. package/dist/core/message-prep.d.ts.map +1 -1
  122. package/dist/core/message-prep.js +39 -12
  123. package/dist/core/message-prep.js.map +1 -1
  124. package/dist/core/message-processing-control.d.ts +1 -0
  125. package/dist/core/message-processing-control.d.ts.map +1 -1
  126. package/dist/core/message-processing-control.js +23 -6
  127. package/dist/core/message-processing-control.js.map +1 -1
  128. package/dist/core/openai-direct.d.ts +9 -3
  129. package/dist/core/openai-direct.d.ts.map +1 -1
  130. package/dist/core/openai-direct.js +267 -33
  131. package/dist/core/openai-direct.js.map +1 -1
  132. package/dist/core/optional-tracers/opik-runtime.d.ts +32 -0
  133. package/dist/core/optional-tracers/opik-runtime.d.ts.map +1 -0
  134. package/dist/core/optional-tracers/opik-runtime.js +141 -0
  135. package/dist/core/optional-tracers/opik-runtime.js.map +1 -0
  136. package/dist/core/queue-manager.d.ts +84 -0
  137. package/dist/core/queue-manager.d.ts.map +1 -0
  138. package/dist/core/queue-manager.js +814 -0
  139. package/dist/core/queue-manager.js.map +1 -0
  140. package/dist/core/reasoning-controls.d.ts +30 -0
  141. package/dist/core/reasoning-controls.d.ts.map +1 -0
  142. package/dist/core/reasoning-controls.js +118 -0
  143. package/dist/core/reasoning-controls.js.map +1 -0
  144. package/dist/core/reliability-config.d.ts +82 -0
  145. package/dist/core/reliability-config.d.ts.map +1 -0
  146. package/dist/core/reliability-config.js +106 -0
  147. package/dist/core/reliability-config.js.map +1 -0
  148. package/dist/core/reliability-runtime.d.ts +53 -0
  149. package/dist/core/reliability-runtime.d.ts.map +1 -0
  150. package/dist/core/reliability-runtime.js +92 -0
  151. package/dist/core/reliability-runtime.js.map +1 -0
  152. package/dist/core/security/guardrails.d.ts +21 -0
  153. package/dist/core/security/guardrails.d.ts.map +1 -0
  154. package/dist/core/security/guardrails.js +111 -0
  155. package/dist/core/security/guardrails.js.map +1 -0
  156. package/dist/core/send-message-tool.d.ts +79 -0
  157. package/dist/core/send-message-tool.d.ts.map +1 -0
  158. package/dist/core/send-message-tool.js +222 -0
  159. package/dist/core/send-message-tool.js.map +1 -0
  160. package/dist/core/shell-cmd-tool.d.ts +82 -1
  161. package/dist/core/shell-cmd-tool.d.ts.map +1 -1
  162. package/dist/core/shell-cmd-tool.js +854 -42
  163. package/dist/core/shell-cmd-tool.js.map +1 -1
  164. package/dist/core/skill-registry.d.ts +2 -0
  165. package/dist/core/skill-registry.d.ts.map +1 -1
  166. package/dist/core/skill-registry.js +52 -2
  167. package/dist/core/skill-registry.js.map +1 -1
  168. package/dist/core/storage/eventStorage/fileEventStorage.d.ts +5 -0
  169. package/dist/core/storage/eventStorage/fileEventStorage.d.ts.map +1 -1
  170. package/dist/core/storage/eventStorage/fileEventStorage.js +61 -0
  171. package/dist/core/storage/eventStorage/fileEventStorage.js.map +1 -1
  172. package/dist/core/storage/eventStorage/memoryEventStorage.d.ts +5 -0
  173. package/dist/core/storage/eventStorage/memoryEventStorage.d.ts.map +1 -1
  174. package/dist/core/storage/eventStorage/memoryEventStorage.js +34 -0
  175. package/dist/core/storage/eventStorage/memoryEventStorage.js.map +1 -1
  176. package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts +1 -0
  177. package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts.map +1 -1
  178. package/dist/core/storage/eventStorage/sqliteEventStorage.js +19 -2
  179. package/dist/core/storage/eventStorage/sqliteEventStorage.js.map +1 -1
  180. package/dist/core/storage/eventStorage/types.d.ts +6 -0
  181. package/dist/core/storage/eventStorage/types.d.ts.map +1 -1
  182. package/dist/core/storage/eventStorage/types.js +1 -0
  183. package/dist/core/storage/eventStorage/types.js.map +1 -1
  184. package/dist/core/storage/eventStorage/validation.d.ts.map +1 -1
  185. package/dist/core/storage/eventStorage/validation.js +2 -1
  186. package/dist/core/storage/eventStorage/validation.js.map +1 -1
  187. package/dist/core/storage/github-world-import.d.ts +84 -0
  188. package/dist/core/storage/github-world-import.d.ts.map +1 -0
  189. package/dist/core/storage/github-world-import.js +365 -0
  190. package/dist/core/storage/github-world-import.js.map +1 -0
  191. package/dist/core/storage/memory-storage.d.ts +19 -8
  192. package/dist/core/storage/memory-storage.d.ts.map +1 -1
  193. package/dist/core/storage/memory-storage.js +147 -49
  194. package/dist/core/storage/memory-storage.js.map +1 -1
  195. package/dist/core/storage/queue-storage.d.ts +1 -0
  196. package/dist/core/storage/queue-storage.d.ts.map +1 -1
  197. package/dist/core/storage/queue-storage.js +3 -2
  198. package/dist/core/storage/queue-storage.js.map +1 -1
  199. package/dist/core/storage/sqlite-storage.d.ts +14 -9
  200. package/dist/core/storage/sqlite-storage.d.ts.map +1 -1
  201. package/dist/core/storage/sqlite-storage.js +131 -154
  202. package/dist/core/storage/sqlite-storage.js.map +1 -1
  203. package/dist/core/storage/storage-factory.d.ts +3 -0
  204. package/dist/core/storage/storage-factory.d.ts.map +1 -1
  205. package/dist/core/storage/storage-factory.js +175 -89
  206. package/dist/core/storage/storage-factory.js.map +1 -1
  207. package/dist/core/storage/world-storage.d.ts +1 -1
  208. package/dist/core/storage/world-storage.d.ts.map +1 -1
  209. package/dist/core/storage/world-storage.js +5 -1
  210. package/dist/core/storage/world-storage.js.map +1 -1
  211. package/dist/core/storage-init.d.ts +11 -0
  212. package/dist/core/storage-init.d.ts.map +1 -0
  213. package/dist/core/storage-init.js +122 -0
  214. package/dist/core/storage-init.js.map +1 -0
  215. package/dist/core/subscription.d.ts +8 -1
  216. package/dist/core/subscription.d.ts.map +1 -1
  217. package/dist/core/subscription.js +130 -23
  218. package/dist/core/subscription.js.map +1 -1
  219. package/dist/core/tool-approval.d.ts +45 -0
  220. package/dist/core/tool-approval.d.ts.map +1 -0
  221. package/dist/core/tool-approval.js +223 -0
  222. package/dist/core/tool-approval.js.map +1 -0
  223. package/dist/core/tool-execution-envelope.d.ts +87 -0
  224. package/dist/core/tool-execution-envelope.d.ts.map +1 -0
  225. package/dist/core/tool-execution-envelope.js +168 -0
  226. package/dist/core/tool-execution-envelope.js.map +1 -0
  227. package/dist/core/tool-utils.d.ts +7 -2
  228. package/dist/core/tool-utils.d.ts.map +1 -1
  229. package/dist/core/tool-utils.js +81 -17
  230. package/dist/core/tool-utils.js.map +1 -1
  231. package/dist/core/types.d.ts +67 -19
  232. package/dist/core/types.d.ts.map +1 -1
  233. package/dist/core/types.js +3 -0
  234. package/dist/core/types.js.map +1 -1
  235. package/dist/core/utils.d.ts +7 -0
  236. package/dist/core/utils.d.ts.map +1 -1
  237. package/dist/core/utils.js +71 -21
  238. package/dist/core/utils.js.map +1 -1
  239. package/dist/core/web-fetch-tool.d.ts +72 -0
  240. package/dist/core/web-fetch-tool.d.ts.map +1 -0
  241. package/dist/core/web-fetch-tool.js +491 -0
  242. package/dist/core/web-fetch-tool.js.map +1 -0
  243. package/dist/core/world-registry.d.ts +84 -0
  244. package/dist/core/world-registry.d.ts.map +1 -0
  245. package/dist/core/world-registry.js +247 -0
  246. package/dist/core/world-registry.js.map +1 -0
  247. package/dist/public/assets/index-Be-1xtV-.js +104 -0
  248. package/dist/public/assets/index-tsDdiXDU.css +1 -0
  249. package/dist/public/index.html +2 -2
  250. package/dist/public/mcp-sandbox-proxy.html +148 -0
  251. package/dist/server/api.js +260 -18
  252. package/dist/server/error-response.d.ts +27 -0
  253. package/dist/server/error-response.js +77 -0
  254. package/dist/server/index.d.ts +2 -1
  255. package/dist/server/index.js +6 -2
  256. package/dist/server/sse-handler.d.ts +11 -1
  257. package/dist/server/sse-handler.js +194 -34
  258. package/migrations/0015_add_message_queue.sql +36 -0
  259. package/migrations/0016_add_world_heartbeat.sql +13 -0
  260. package/migrations/0017_add_title_provenance.sql +7 -0
  261. package/package.json +31 -10
  262. package/dist/public/assets/index-BW41BxMy.css +0 -1
  263. package/dist/public/assets/index-kO6UJFwK.js +0 -96
@@ -7,26 +7,28 @@
7
7
  * Features:
8
8
  * - Agent message subscription with automatic response processing
9
9
  * - Tool message subscription with security checks
10
- * - World message subscription for title generation (idle and no-activity user-message fallback)
11
- * - World activity listener for chat title updates on idle
12
- * - In-flight title generation guard to avoid duplicate concurrent updates per chat
10
+ * - World message subscription: idempotent wrapper for world-level message listeners.
11
+ * - World activity listener: idempotent wrapper no-op when setupEventPersistence has run;
12
+ * standalone fallback path delegates idle-title logic to title-scheduler.ts.
13
13
  *
14
14
  * Dependencies (Layer 6):
15
15
  * - types.ts (Layer 1)
16
16
  * - publishers.ts (Layer 3)
17
- * - persistence.ts, memory-manager.ts (Layer 4)
17
+ * - persistence.ts, memory-manager.ts, title-scheduler.ts (Layer 4)
18
18
  * - orchestrator.ts (Layer 5)
19
19
  * - utils.ts, logger.ts
20
- * - storage (runtime)
21
20
  *
22
21
  * Changes:
23
- * - 2026-02-20: Publish chat-title update notifications as structured `system` events (`chat-title-updated`).
24
- * - 2026-02-13: Added no-activity user-message fallback title scheduling to cover edited chats with no agent response.
25
- * - 2026-02-13: Switched title commit path to compare-and-set storage update to avoid concurrent overwrite races.
26
- * - 2026-02-13: Added conditional commit checks and in-flight dedupe for idle title updates.
27
- * - 2026-02-13: Made idle title updates chat-scoped with captured `targetChatId` to prevent cross-session renames.
28
- * - 2026-02-08: Removed legacy manual tool-intervention request handling from message subscription
29
- * - 2025-11-09: Extracted from events.ts for modular architecture
22
+ * - 2026-03-10: Removed standalone world-message title scheduling so idle activity is the sole
23
+ * automatic chat-title trigger.
24
+ * - 2026-03-06: Removed `world.currentChatId` fallback from world-message title scheduling; chat-scoped handlers now require explicit `event.chatId`.
25
+ * - 2026-03-03: Removed private title-scheduling logic (moved to title-scheduler.ts Layer 4).
26
+ * subscribeWorldToMessages and setupWorldActivityListener are now idempotent wrappers that
27
+ * short-circuit when setupEventPersistence has already registered a combined handler.
28
+ * - 2026-02-28: Made world message subscription idempotent.
29
+ * - 2026-02-22: Persist incoming human messages to agent memory even when agents do not respond.
30
+ * - 2026-02-20: Publish chat-title update notifications as structured `system` events.
31
+ * - 2025-11-09: Extracted from events.ts for modular architecture.
30
32
  */
31
33
  import type { World, Agent } from '../types.js';
32
34
  /**
@@ -38,7 +40,8 @@ export declare function subscribeAgentToMessages(world: World, agent: Agent): ()
38
40
  */
39
41
  export declare function subscribeWorldToMessages(world: World): () => void;
40
42
  /**
41
- * Setup world activity listener for chat title updates
42
- * Triggers title generation when world becomes idle (pendingOperations === 0)
43
+ * Setup world activity listener for idle-triggered chat title updates.
44
+ * Idempotent returns existing cleanup handle if setupEventPersistence already registered
45
+ * a combined 'world' handler for this world.
43
46
  */
44
47
  export declare function setupWorldActivityListener(world: World): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"subscribers.d.ts","sourceRoot":"","sources":["../../../core/events/subscribers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EACV,KAAK,EACL,KAAK,EAGN,MAAM,aAAa,CAAC;AA+LrB;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,IAAI,CA6E/E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,IAAI,CAWjE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,IAAI,CAyBnE"}
1
+ {"version":3,"file":"subscribers.d.ts","sourceRoot":"","sources":["../../../core/events/subscribers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EACV,KAAK,EACL,KAAK,EAEN,MAAM,aAAa,CAAC;AAkErB;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,IAAI,CA4F/E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,IAAI,CAmBjE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,IAAI,CAsBnE"}
@@ -7,54 +7,37 @@
7
7
  * Features:
8
8
  * - Agent message subscription with automatic response processing
9
9
  * - Tool message subscription with security checks
10
- * - World message subscription for title generation (idle and no-activity user-message fallback)
11
- * - World activity listener for chat title updates on idle
12
- * - In-flight title generation guard to avoid duplicate concurrent updates per chat
10
+ * - World message subscription: idempotent wrapper for world-level message listeners.
11
+ * - World activity listener: idempotent wrapper no-op when setupEventPersistence has run;
12
+ * standalone fallback path delegates idle-title logic to title-scheduler.ts.
13
13
  *
14
14
  * Dependencies (Layer 6):
15
15
  * - types.ts (Layer 1)
16
16
  * - publishers.ts (Layer 3)
17
- * - persistence.ts, memory-manager.ts (Layer 4)
17
+ * - persistence.ts, memory-manager.ts, title-scheduler.ts (Layer 4)
18
18
  * - orchestrator.ts (Layer 5)
19
19
  * - utils.ts, logger.ts
20
- * - storage (runtime)
21
20
  *
22
21
  * Changes:
23
- * - 2026-02-20: Publish chat-title update notifications as structured `system` events (`chat-title-updated`).
24
- * - 2026-02-13: Added no-activity user-message fallback title scheduling to cover edited chats with no agent response.
25
- * - 2026-02-13: Switched title commit path to compare-and-set storage update to avoid concurrent overwrite races.
26
- * - 2026-02-13: Added conditional commit checks and in-flight dedupe for idle title updates.
27
- * - 2026-02-13: Made idle title updates chat-scoped with captured `targetChatId` to prevent cross-session renames.
28
- * - 2026-02-08: Removed legacy manual tool-intervention request handling from message subscription
29
- * - 2025-11-09: Extracted from events.ts for modular architecture
22
+ * - 2026-03-10: Removed standalone world-message title scheduling so idle activity is the sole
23
+ * automatic chat-title trigger.
24
+ * - 2026-03-06: Removed `world.currentChatId` fallback from world-message title scheduling; chat-scoped handlers now require explicit `event.chatId`.
25
+ * - 2026-03-03: Removed private title-scheduling logic (moved to title-scheduler.ts Layer 4).
26
+ * subscribeWorldToMessages and setupWorldActivityListener are now idempotent wrappers that
27
+ * short-circuit when setupEventPersistence has already registered a combined handler.
28
+ * - 2026-02-28: Made world message subscription idempotent.
29
+ * - 2026-02-22: Persist incoming human messages to agent memory even when agents do not respond.
30
+ * - 2026-02-20: Publish chat-title update notifications as structured `system` events.
31
+ * - 2025-11-09: Extracted from events.ts for modular architecture.
30
32
  */
31
33
  import { parseMessageContent } from '../message-prep.js';
32
34
  import { extractParagraphBeginningMentions } from '../utils.js';
33
35
  import { createCategoryLogger } from '../logger.js';
34
- import { createStorageWithWrappers } from '../storage/storage-factory.js';
35
- import { publishEvent, subscribeToMessages } from './publishers.js';
36
- import { saveIncomingMessageToMemory, resetLLMCallCountIfNeeded, generateChatTitleFromMessages } from './memory-manager.js';
36
+ import { subscribeToMessages } from './publishers.js';
37
+ import { saveIncomingMessageToMemory, resetLLMCallCountIfNeeded } from './memory-manager.js';
37
38
  import { processAgentMessage, shouldAgentRespond } from './orchestrator.js';
38
- import { isDefaultChatTitle, NEW_CHAT_TITLE } from '../chat-constants.js';
39
+ import { isHumanSender, runIdleTitleUpdate, clearWorldTitleTimers } from './title-scheduler.js';
39
40
  const loggerAgent = createCategoryLogger('agent');
40
- const loggerChatTitle = createCategoryLogger('chattitle');
41
- const titleGenerationInFlight = new Set();
42
- const titleGenerationTimers = new Map();
43
- // Storage wrapper instance - initialized lazily
44
- let storageWrappers = null;
45
- async function getStorageWrappers() {
46
- if (!storageWrappers) {
47
- storageWrappers = await createStorageWithWrappers();
48
- }
49
- return storageWrappers;
50
- }
51
- function getTitleGenerationKey(worldId, chatId) {
52
- return `${worldId}:${chatId}`;
53
- }
54
- function isHumanSender(sender) {
55
- const normalized = String(sender ?? '').trim().toLowerCase();
56
- return normalized === 'human' || normalized.startsWith('user');
57
- }
58
41
  function toMentionToken(value) {
59
42
  return String(value || '')
60
43
  .trim()
@@ -96,91 +79,19 @@ function applyMainAgentMentionRouting(world, messageEvent) {
96
79
  content: `@${mainAgent} ${messageEvent.content || ''}`.trim()
97
80
  };
98
81
  }
99
- function scheduleNoActivityTitleUpdate(world, chatId, content) {
100
- const key = getTitleGenerationKey(world.id, chatId);
101
- const existingTimer = titleGenerationTimers.get(key);
102
- if (existingTimer) {
103
- clearTimeout(existingTimer);
104
- }
105
- const timer = setTimeout(async () => {
106
- titleGenerationTimers.delete(key);
107
- if (world.isProcessing) {
108
- return;
109
- }
110
- await tryGenerateAndApplyTitle(world, chatId, content, 'message-no-activity');
111
- }, 120);
112
- titleGenerationTimers.set(key, timer);
113
- }
114
- async function commitChatTitleIfDefault(world, chatId, nextTitle) {
115
- const storage = await getStorageWrappers();
116
- if (typeof storage.updateChatNameIfCurrent === 'function') {
117
- return storage.updateChatNameIfCurrent(world.id, chatId, NEW_CHAT_TITLE, nextTitle);
118
- }
119
- // Legacy fallback when storage backend does not provide compare-and-set helper.
120
- const persistedChat = await storage.loadChatData(world.id, chatId);
121
- if (!persistedChat || !isDefaultChatTitle(persistedChat.name)) {
122
- return false;
123
- }
124
- const updated = await storage.updateChatData(world.id, chatId, { name: nextTitle });
125
- return !!updated;
126
- }
127
- async function tryGenerateAndApplyTitle(world, targetChatId, content, source) {
128
- const inFlightKey = getTitleGenerationKey(world.id, targetChatId);
129
- if (titleGenerationInFlight.has(inFlightKey)) {
130
- loggerChatTitle.debug('Skipping title update because generation is already in flight', {
131
- worldId: world.id,
132
- chatId: targetChatId,
133
- source
134
- });
135
- return;
136
- }
137
- const chat = world.chats.get(targetChatId);
138
- if (!chat || !isDefaultChatTitle(chat.name)) {
139
- return;
140
- }
141
- titleGenerationInFlight.add(inFlightKey);
142
- try {
143
- const title = await generateChatTitleFromMessages(world, content, targetChatId);
144
- if (!title) {
145
- return;
146
- }
147
- // Re-check in-memory state before commit.
148
- const currentChat = world.chats.get(targetChatId);
149
- if (!currentChat || !isDefaultChatTitle(currentChat.name)) {
150
- loggerChatTitle.debug('Skipping title commit because in-memory chat title is no longer default', {
151
- worldId: world.id,
152
- chatId: targetChatId,
153
- source,
154
- currentName: currentChat?.name
155
- });
156
- return;
157
- }
158
- const committed = await commitChatTitleIfDefault(world, targetChatId, title);
159
- if (!committed) {
160
- loggerChatTitle.debug('Skipping title commit because persisted chat title no longer matches default', {
161
- worldId: world.id,
162
- chatId: targetChatId,
163
- source
164
- });
165
- return;
166
- }
167
- currentChat.name = title;
168
- publishEvent(world, 'system', {
169
- eventType: 'chat-title-updated',
170
- chatId: targetChatId,
171
- title,
172
- source,
173
- message: `Chat title updated: ${title}`,
174
- }, targetChatId);
175
- }
176
- finally {
177
- titleGenerationInFlight.delete(inFlightKey);
178
- }
179
- }
180
82
  /**
181
83
  * Agent subscription with automatic message processing
182
84
  */
183
85
  export function subscribeAgentToMessages(world, agent) {
86
+ const existingUnsubscribe = world._agentUnsubscribers?.get(agent.id);
87
+ if (typeof existingUnsubscribe === 'function') {
88
+ try {
89
+ existingUnsubscribe();
90
+ }
91
+ catch {
92
+ // Best-effort cleanup before rebinding the same agent listener.
93
+ }
94
+ }
184
95
  const handler = async (messageEvent) => {
185
96
  const routedMessageEvent = applyMainAgentMentionRouting(world, messageEvent);
186
97
  loggerAgent.debug('[subscribeAgentToMessages] ENTRY - Agent received message', {
@@ -222,12 +133,17 @@ export function subscribeAgentToMessages(world, agent) {
222
133
  }
223
134
  // Reset LLM call count if needed (for human/system messages)
224
135
  await resetLLMCallCountIfNeeded(world, agent, routedMessageEvent);
136
+ const isIncomingHumanMessage = isHumanSender(routedMessageEvent.sender);
137
+ if (isIncomingHumanMessage) {
138
+ await saveIncomingMessageToMemory(world, agent, routedMessageEvent);
139
+ }
225
140
  // Process message if agent should respond
226
141
  loggerAgent.debug('Checking if agent should respond', { agentId: agent.id, sender: routedMessageEvent.sender });
227
142
  const shouldRespond = await shouldAgentRespond(world, agent, routedMessageEvent);
228
143
  if (shouldRespond) {
229
- // Save incoming messages to agent memory only when they plan to respond
230
- await saveIncomingMessageToMemory(world, agent, routedMessageEvent);
144
+ if (!isIncomingHumanMessage) {
145
+ await saveIncomingMessageToMemory(world, agent, routedMessageEvent);
146
+ }
231
147
  loggerAgent.debug('Agent will respond - processing message', { agentId: agent.id, sender: routedMessageEvent.sender });
232
148
  await processAgentMessage(world, agent, routedMessageEvent);
233
149
  }
@@ -250,46 +166,43 @@ export function subscribeAgentToMessages(world, agent) {
250
166
  * Subscribe world to messages with cleanup function
251
167
  */
252
168
  export function subscribeWorldToMessages(world) {
253
- return subscribeToMessages(world, async (event) => {
254
- const targetChatId = event.chatId ?? world.currentChatId ?? null;
255
- if (!targetChatId)
256
- return;
257
- if (!isHumanSender(event.sender))
258
- return;
259
- const chat = world.chats.get(targetChatId);
260
- if (!chat || !isDefaultChatTitle(chat.name))
261
- return;
262
- scheduleNoActivityTitleUpdate(world, targetChatId, event.content || '');
169
+ if (typeof world._worldMessagesUnsubscriber === 'function') {
170
+ return world._worldMessagesUnsubscriber;
171
+ }
172
+ const unsubscribe = subscribeToMessages(world, (_event) => {
173
+ return;
263
174
  });
175
+ const trackedUnsubscribe = () => {
176
+ unsubscribe();
177
+ clearWorldTitleTimers(world.id);
178
+ if (world._worldMessagesUnsubscriber === trackedUnsubscribe) {
179
+ world._worldMessagesUnsubscriber = undefined;
180
+ }
181
+ };
182
+ world._worldMessagesUnsubscriber = trackedUnsubscribe;
183
+ return trackedUnsubscribe;
264
184
  }
265
185
  /**
266
- * Setup world activity listener for chat title updates
267
- * Triggers title generation when world becomes idle (pendingOperations === 0)
186
+ * Setup world activity listener for idle-triggered chat title updates.
187
+ * Idempotent returns existing cleanup handle if setupEventPersistence already registered
188
+ * a combined 'world' handler for this world.
268
189
  */
269
190
  export function setupWorldActivityListener(world) {
191
+ if (typeof world._activityListenerCleanup === 'function') {
192
+ return world._activityListenerCleanup;
193
+ }
194
+ // Standalone fallback: persistence is disabled, attach a lightweight idle handler.
270
195
  const handler = async (event) => {
271
- // Only update title when world becomes idle (all agents done)
272
- if (event.type === 'idle' && event.pendingOperations === 0) {
273
- const targetChatId = world.currentChatId;
274
- if (!targetChatId)
275
- return;
276
- try {
277
- await tryGenerateAndApplyTitle(world, targetChatId, '', 'idle');
278
- }
279
- catch (err) {
280
- loggerChatTitle.warn('Activity-based title update failed', { error: err instanceof Error ? err.message : err });
281
- }
282
- }
196
+ await runIdleTitleUpdate(world, event);
283
197
  };
284
198
  world.eventEmitter.on('world', handler);
285
- return () => {
199
+ const cleanup = () => {
286
200
  world.eventEmitter.off('world', handler);
287
- for (const [key, timer] of titleGenerationTimers.entries()) {
288
- if (!key.startsWith(`${world.id}:`)) {
289
- continue;
290
- }
291
- clearTimeout(timer);
292
- titleGenerationTimers.delete(key);
201
+ clearWorldTitleTimers(world.id);
202
+ if (world._activityListenerCleanup === cleanup) {
203
+ world._activityListenerCleanup = undefined;
293
204
  }
294
205
  };
206
+ world._activityListenerCleanup = cleanup;
207
+ return cleanup;
295
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"subscribers.js","sourceRoot":"","sources":["../../../core/events/subscribers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAQH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EACL,YAAY,EACZ,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1E,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAClD,MAAM,eAAe,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;AAC1D,MAAM,uBAAuB,GAAG,IAAI,GAAG,EAAU,CAAC;AAClD,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAyC,CAAC;AAE/E,gDAAgD;AAChD,IAAI,eAAe,GAAsB,IAAI,CAAC;AAC9C,KAAK,UAAU,kBAAkB;IAC/B,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,eAAe,GAAG,MAAM,yBAAyB,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,eAAgB,CAAC;AAC1B,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe,EAAE,MAAc;IAC5D,OAAO,GAAG,OAAO,IAAI,MAAM,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,aAAa,CAAC,MAAe;IACpC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7D,OAAO,UAAU,KAAK,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SACvB,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,4BAA4B,CAAC,KAAY;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAEpD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1C,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,UAAU,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;YACzF,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,4BAA4B,CAAC,KAAY,EAAE,YAA+B;IACjF,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QACxC,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,SAAS,GAAG,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACtD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,QAAQ,GAAG,iCAAiC,CAAC,YAAY,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC/E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO;QACL,GAAG,YAAY;QACf,OAAO,EAAE,IAAI,SAAS,IAAI,YAAY,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE;KAC9D,CAAC;AACJ,CAAC;AAED,SAAS,6BAA6B,CAAC,KAAY,EAAE,MAAc,EAAE,OAAe;IAClF,MAAM,GAAG,GAAG,qBAAqB,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrD,IAAI,aAAa,EAAE,CAAC;QAClB,YAAY,CAAC,aAAa,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;QAClC,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,MAAM,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,CAAC,CAAC;IAChF,CAAC,EAAE,GAAG,CAAC,CAAC;IAER,qBAAqB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,KAAY,EACZ,MAAc,EACd,SAAiB;IAEjB,MAAM,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAE3C,IAAI,OAAO,OAAO,CAAC,uBAAuB,KAAK,UAAU,EAAE,CAAC;QAC1D,OAAO,OAAO,CAAC,uBAAuB,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;IACtF,CAAC;IAED,gFAAgF;IAChF,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACnE,IAAI,CAAC,aAAa,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACpF,OAAO,CAAC,CAAC,OAAO,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,KAAY,EACZ,YAAoB,EACpB,OAAe,EACf,MAAsC;IAEtC,MAAM,WAAW,GAAG,qBAAqB,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IAClE,IAAI,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7C,eAAe,CAAC,KAAK,CAAC,+DAA+D,EAAE;YACrF,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,MAAM,EAAE,YAAY;YACpB,MAAM;SACP,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAChF,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,0CAA0C;QAC1C,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,CAAC,WAAW,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,eAAe,CAAC,KAAK,CAAC,yEAAyE,EAAE;gBAC/F,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,MAAM,EAAE,YAAY;gBACpB,MAAM;gBACN,WAAW,EAAE,WAAW,EAAE,IAAI;aAC/B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QAC7E,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,eAAe,CAAC,KAAK,CAAC,8EAA8E,EAAE;gBACpG,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,MAAM,EAAE,YAAY;gBACpB,MAAM;aACP,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,WAAW,CAAC,IAAI,GAAG,KAAK,CAAC;QACzB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE;YAC5B,SAAS,EAAE,oBAAoB;YAC/B,MAAM,EAAE,YAAY;YACpB,KAAK;YACL,MAAM;YACN,OAAO,EAAE,uBAAuB,KAAK,EAAE;SACxC,EAAE,YAAY,CAAC,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,uBAAuB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAY,EAAE,KAAY;IACjE,MAAM,OAAO,GAAG,KAAK,EAAE,YAA+B,EAAE,EAAE;QACxD,MAAM,kBAAkB,GAAG,4BAA4B,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAE7E,WAAW,CAAC,KAAK,CAAC,2DAA2D,EAAE;YAC7E,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,MAAM,EAAE,kBAAkB,CAAC,MAAM;YACjC,SAAS,EAAE,kBAAkB,CAAC,SAAS;YACvC,cAAc,EAAE,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;SAC9D,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC;YAClC,WAAW,CAAC,KAAK,CAAC,oCAAoC,EAAE;gBACtD,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,MAAM,EAAE,kBAAkB,CAAC,MAAM;gBACjC,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC,CAAC;QACL,CAAC;QAED,yCAAyC;QACzC,sDAAsD;QACtD,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,mBAAmB,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE1G,WAAW,CAAC,KAAK,CAAC,sDAAsD,EAAE;YACxE,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,UAAU,EAAE,aAAa,CAAC,IAAI;YAC9B,aAAa;YACb,UAAU,EAAE,aAAa,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;YAClF,aAAa,EAAE,aAAa,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,aAAa,CAAC,YAAY;SAC7E,CAAC,CAAC;QAEH,mFAAmF;QACnF,gFAAgF;QAChF,IAAI,aAAa,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAClC,WAAW,CAAC,KAAK,CAAC,4EAA4E,EAAE;gBAC9F,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,UAAU,EAAE,aAAa,CAAC,YAAY;aACvC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,uCAAuC;QACvC,IAAI,kBAAkB,CAAC,MAAM,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;YAC3C,WAAW,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/G,OAAO;QACT,CAAC;QAED,6DAA6D;QAC7D,MAAM,yBAAyB,CAAC,KAAK,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;QAElE,0CAA0C;QAC1C,WAAW,CAAC,KAAK,CAAC,kCAAkC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC;QAChH,MAAM,aAAa,GAAG,MAAM,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;QAEjF,IAAI,aAAa,EAAE,CAAC;YAClB,wEAAwE;YACxE,MAAM,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;YAEpE,WAAW,CAAC,KAAK,CAAC,yCAAyC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,EAAE,CAAC,CAAC;YACvH,MAAM,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,KAAK,CAAC,kEAAkE,EAAE;gBACpF,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,MAAM,EAAE,kBAAkB,CAAC,MAAM;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAExD,0EAA0E;IAC1E,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;QAC/B,KAAK,CAAC,mBAAmB,GAAG,IAAI,GAAG,EAAE,CAAC;IACxC,CAAC;IACD,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;IAErD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAY;IACnD,OAAO,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAwB,EAAE,EAAE;QACnE,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC;QACjE,IAAI,CAAC,YAAY;YAAE,OAAO;QAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,OAAO;QAEzC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO;QAEpD,6BAA6B,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAY;IACrD,MAAM,OAAO,GAAG,KAAK,EAAE,KAAU,EAAE,EAAE;QACnC,8DAA8D;QAC9D,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,EAAE,CAAC;YAC3D,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC;YACzC,IAAI,CAAC,YAAY;gBAAE,OAAO;YAC1B,IAAI,CAAC;gBACH,MAAM,wBAAwB,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;YAClE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,eAAe,CAAC,IAAI,CAAC,oCAAoC,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAClH,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACxC,OAAO,GAAG,EAAE;QACV,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,qBAAqB,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YACD,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"subscribers.js","sourceRoot":"","sources":["../../../core/events/subscribers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Title Scheduler Module
3
+ *
4
+ * Purpose:
5
+ * - Encapsulate all chat-title auto-generation logic (Layer 4).
6
+ * - Previously embedded in subscribers.ts (Layer 6); extracted so persistence.ts (Layer 4) can
7
+ * call title-scheduling directly without a cross-layer import violation.
8
+ *
9
+ * Key Features:
10
+ * - Idle-triggered title generation on world activity events.
11
+ * - In-flight deduplication and compare-and-set storage commit.
12
+ * - World teardown cleanup helper that preserves the listener contract.
13
+ *
14
+ * Implementation Notes:
15
+ * - All state (in-flight set, storage cache) is module-level to preserve
16
+ * singleton semantics previously in subscribers.ts.
17
+ *
18
+ * Recent Changes:
19
+ * - 2026-03-10: Removed the human-message debounce trigger so idle activity is the sole
20
+ * automatic chat-title generation entry point.
21
+ * - 2026-03-03: Extracted from subscribers.ts to eliminate duplicate world-level EventEmitter
22
+ * listeners (persistence + activity + title-scheduler each had their own handler per channel).
23
+ */
24
+ import type { World } from '../types.js';
25
+ export declare function isHumanSender(sender?: string): boolean;
26
+ export declare function runIdleTitleUpdate(world: World, event: any): Promise<void>;
27
+ export declare function clearWorldTitleTimers(worldId: string): void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"title-scheduler.d.ts","sourceRoot":"","sources":["../../../core/events/title-scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,aAAa,CAAC;AAuBrD,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAGtD;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE3D"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Title Scheduler Module
3
+ *
4
+ * Purpose:
5
+ * - Encapsulate all chat-title auto-generation logic (Layer 4).
6
+ * - Previously embedded in subscribers.ts (Layer 6); extracted so persistence.ts (Layer 4) can
7
+ * call title-scheduling directly without a cross-layer import violation.
8
+ *
9
+ * Key Features:
10
+ * - Idle-triggered title generation on world activity events.
11
+ * - In-flight deduplication and compare-and-set storage commit.
12
+ * - World teardown cleanup helper that preserves the listener contract.
13
+ *
14
+ * Implementation Notes:
15
+ * - All state (in-flight set, storage cache) is module-level to preserve
16
+ * singleton semantics previously in subscribers.ts.
17
+ *
18
+ * Recent Changes:
19
+ * - 2026-03-10: Removed the human-message debounce trigger so idle activity is the sole
20
+ * automatic chat-title generation entry point.
21
+ * - 2026-03-03: Extracted from subscribers.ts to eliminate duplicate world-level EventEmitter
22
+ * listeners (persistence + activity + title-scheduler each had their own handler per channel).
23
+ */
24
+ import { createCategoryLogger } from '../logger.js';
25
+ import { createStorageWithWrappers } from '../storage/storage-factory.js';
26
+ import { generateChatTitleFromMessages } from './memory-manager.js';
27
+ import { publishEvent } from './publishers.js';
28
+ import { isDefaultChatTitle, NEW_CHAT_TITLE, TITLE_PROVENANCE_AUTO } from '../chat-constants.js';
29
+ const loggerChatTitle = createCategoryLogger('chattitle');
30
+ const titleGenerationInFlight = new Set();
31
+ let storageWrappers = null;
32
+ async function getStorageWrappers() {
33
+ if (!storageWrappers) {
34
+ storageWrappers = await createStorageWithWrappers();
35
+ }
36
+ return storageWrappers;
37
+ }
38
+ function getTitleGenerationKey(worldId, chatId) {
39
+ return `${worldId}:${chatId}`;
40
+ }
41
+ export function isHumanSender(sender) {
42
+ const normalized = String(sender ?? '').trim().toLowerCase();
43
+ return normalized === 'human' || normalized === 'world' || normalized.startsWith('user');
44
+ }
45
+ export async function runIdleTitleUpdate(world, event) {
46
+ if (event.type !== 'idle' || event.pendingOperations !== 0) {
47
+ return;
48
+ }
49
+ const targetChatIdRaw = typeof event?.chatId === 'string' ? event.chatId.trim() : '';
50
+ const targetChatId = targetChatIdRaw || null;
51
+ if (!targetChatId) {
52
+ loggerChatTitle.debug('Skipping idle title update due to missing chatId on activity event', {
53
+ worldId: world.id,
54
+ eventType: event?.type,
55
+ pendingOperations: event?.pendingOperations
56
+ });
57
+ return;
58
+ }
59
+ try {
60
+ await tryGenerateAndApplyTitle(world, targetChatId, '', 'idle');
61
+ }
62
+ catch (err) {
63
+ loggerChatTitle.warn('Activity-based title update failed', { error: err instanceof Error ? err.message : err });
64
+ }
65
+ }
66
+ export function clearWorldTitleTimers(worldId) {
67
+ void worldId;
68
+ }
69
+ async function commitChatTitleIfDefault(world, chatId, nextTitle) {
70
+ const storage = await getStorageWrappers();
71
+ if (typeof storage.updateChatNameIfCurrent === 'function') {
72
+ return storage.updateChatNameIfCurrent(world.id, chatId, NEW_CHAT_TITLE, nextTitle, TITLE_PROVENANCE_AUTO);
73
+ }
74
+ // Legacy fallback when storage backend does not provide compare-and-set helper.
75
+ const persistedChat = await storage.loadChatData(world.id, chatId);
76
+ if (!persistedChat || !isDefaultChatTitle(persistedChat.name)) {
77
+ return false;
78
+ }
79
+ const updated = await storage.updateChatData(world.id, chatId, { name: nextTitle, titleProvenance: TITLE_PROVENANCE_AUTO });
80
+ return !!updated;
81
+ }
82
+ async function tryGenerateAndApplyTitle(world, targetChatId, content, source) {
83
+ const inFlightKey = getTitleGenerationKey(world.id, targetChatId);
84
+ if (titleGenerationInFlight.has(inFlightKey)) {
85
+ loggerChatTitle.debug('Skipping title update because generation is already in flight', {
86
+ worldId: world.id,
87
+ chatId: targetChatId,
88
+ source
89
+ });
90
+ return;
91
+ }
92
+ const chat = world.chats.get(targetChatId);
93
+ if (!chat || !isDefaultChatTitle(chat.name)) {
94
+ return;
95
+ }
96
+ titleGenerationInFlight.add(inFlightKey);
97
+ try {
98
+ const title = await generateChatTitleFromMessages(world, content, targetChatId);
99
+ if (!title) {
100
+ return;
101
+ }
102
+ // Re-check in-memory state before commit.
103
+ const currentChat = world.chats.get(targetChatId);
104
+ if (!currentChat || !isDefaultChatTitle(currentChat.name)) {
105
+ loggerChatTitle.debug('Skipping title commit because in-memory chat title is no longer default', {
106
+ worldId: world.id,
107
+ chatId: targetChatId,
108
+ source,
109
+ currentName: currentChat?.name
110
+ });
111
+ return;
112
+ }
113
+ const committed = await commitChatTitleIfDefault(world, targetChatId, title);
114
+ if (!committed) {
115
+ loggerChatTitle.debug('Skipping title commit because persisted chat title no longer matches default', {
116
+ worldId: world.id,
117
+ chatId: targetChatId,
118
+ source
119
+ });
120
+ return;
121
+ }
122
+ currentChat.name = title;
123
+ currentChat.titleProvenance = TITLE_PROVENANCE_AUTO;
124
+ publishEvent(world, 'system', {
125
+ eventType: 'chat-title-updated',
126
+ chatId: targetChatId,
127
+ title,
128
+ source,
129
+ message: `Chat title updated: ${title}`,
130
+ }, targetChatId);
131
+ }
132
+ finally {
133
+ titleGenerationInFlight.delete(inFlightKey);
134
+ }
135
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"title-scheduler.js","sourceRoot":"","sources":["../../../core/events/title-scheduler.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,8 @@
6
6
  * memory-manager to trace request/result/error handoff payloads.
7
7
  *
8
8
  * Key Features:
9
- * - Console-level bridge logs gated by `LOG_LLM_TOOL_BRIDGE` env var
9
+ * - Structured bridge logs through the core logger (`llm.tool.bridge`) for realtime log streaming
10
+ * - LOG_LLM_TOOL_BRIDGE supports explicit levels (`trace|debug|info|warn|error`) and boolean aliases (`1|true|on` => debug)
10
11
  * - Simplified output showing only type, tool name, and truncated content (100-200 chars)
11
12
  * - Safe JSON serialization with fallback to `String()`
12
13
  *
@@ -15,6 +16,8 @@
15
16
  * - Filters verbose metadata, keeps only essential debugging fields
16
17
  *
17
18
  * Changes:
19
+ * - 2026-02-28: Added canonical feature-path category emission (`tool.call.*`, `tool.continuation`) while preserving legacy bridge logging behavior.
20
+ * - 2026-02-27: Replaced ad-hoc `[LLM↔TOOLS]` console logging with structured category logger events.
18
21
  * - 2026-02-16: Extracted shared tool-bridge logging utilities from orchestrator
19
22
  * and memory-manager into a dedicated module.
20
23
  * - 2026-02-17: Simplified logToolBridge to show only type, tool name, and truncated
@@ -1 +1 @@
1
- {"version":3,"file":"tool-bridge-logging.d.ts","sourceRoot":"","sources":["../../../core/events/tool-bridge-logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAM9D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAQpD;AAcD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CA6BvE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAU3D"}
1
+ {"version":3,"file":"tool-bridge-logging.d.ts","sourceRoot":"","sources":["../../../core/events/tool-bridge-logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAmHH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAM9D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAcD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAoCvE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAU3D"}