sensorium-mcp 3.1.0-refactor.0 → 3.1.0-refactor.10

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 (178) hide show
  1. package/Install-Sensorium.ps1 +113 -20
  2. package/dist/config/agent-settings.d.ts +7 -0
  3. package/dist/config/agent-settings.d.ts.map +1 -1
  4. package/dist/config/agent-settings.js +14 -0
  5. package/dist/config/agent-settings.js.map +1 -1
  6. package/dist/dashboard/log-parser.d.ts +3 -0
  7. package/dist/dashboard/log-parser.d.ts.map +1 -1
  8. package/dist/dashboard/log-parser.js +38 -4
  9. package/dist/dashboard/log-parser.js.map +1 -1
  10. package/dist/dashboard/routes/claude.d.ts.map +1 -1
  11. package/dist/dashboard/routes/claude.js +9 -1
  12. package/dist/dashboard/routes/claude.js.map +1 -1
  13. package/dist/dashboard/routes/threads.js +1 -1
  14. package/dist/dashboard/routes/threads.js.map +1 -1
  15. package/dist/dashboard/spa.html +11 -11
  16. package/dist/data/memory/bootstrap.d.ts +7 -0
  17. package/dist/data/memory/bootstrap.d.ts.map +1 -1
  18. package/dist/data/memory/bootstrap.js +45 -16
  19. package/dist/data/memory/bootstrap.js.map +1 -1
  20. package/dist/data/memory/consolidation.d.ts +9 -4
  21. package/dist/data/memory/consolidation.d.ts.map +1 -1
  22. package/dist/data/memory/consolidation.js +24 -12
  23. package/dist/data/memory/consolidation.js.map +1 -1
  24. package/dist/data/memory/index.d.ts +1 -2
  25. package/dist/data/memory/index.d.ts.map +1 -1
  26. package/dist/data/memory/index.js +1 -2
  27. package/dist/data/memory/index.js.map +1 -1
  28. package/dist/data/memory/migration-runner.d.ts +24 -1
  29. package/dist/data/memory/migration-runner.d.ts.map +1 -1
  30. package/dist/data/memory/migration-runner.js +85 -1
  31. package/dist/data/memory/migration-runner.js.map +1 -1
  32. package/dist/data/memory/narrative.d.ts.map +1 -1
  33. package/dist/data/memory/narrative.js +5 -1
  34. package/dist/data/memory/narrative.js.map +1 -1
  35. package/dist/data/memory/note-archival.d.ts +29 -4
  36. package/dist/data/memory/note-archival.d.ts.map +1 -1
  37. package/dist/data/memory/note-archival.js +55 -26
  38. package/dist/data/memory/note-archival.js.map +1 -1
  39. package/dist/data/memory/reflection-dedup.js +2 -2
  40. package/dist/data/memory/reflection-dedup.js.map +1 -1
  41. package/dist/data/memory/reflection.d.ts.map +1 -1
  42. package/dist/data/memory/reflection.js +7 -3
  43. package/dist/data/memory/reflection.js.map +1 -1
  44. package/dist/data/memory/schema-ddl.d.ts +1 -1
  45. package/dist/data/memory/schema-ddl.d.ts.map +1 -1
  46. package/dist/data/memory/schema-ddl.js +8 -8
  47. package/dist/data/memory/semantic-notes.d.ts +30 -2
  48. package/dist/data/memory/semantic-notes.d.ts.map +1 -1
  49. package/dist/data/memory/semantic-notes.js +94 -13
  50. package/dist/data/memory/semantic-notes.js.map +1 -1
  51. package/dist/data/memory/semantic-search.d.ts.map +1 -1
  52. package/dist/data/memory/semantic-search.js +6 -4
  53. package/dist/data/memory/semantic-search.js.map +1 -1
  54. package/dist/data/memory/thread-registry.d.ts.map +1 -1
  55. package/dist/data/memory/thread-registry.js +20 -4
  56. package/dist/data/memory/thread-registry.js.map +1 -1
  57. package/dist/data/memory/topic-shift.js +2 -2
  58. package/dist/data/memory/topic-shift.js.map +1 -1
  59. package/dist/index.js +19 -9
  60. package/dist/index.js.map +1 -1
  61. package/dist/integrations/openai/chat.d.ts +7 -1
  62. package/dist/integrations/openai/chat.d.ts.map +1 -1
  63. package/dist/integrations/openai/chat.js +19 -2
  64. package/dist/integrations/openai/chat.js.map +1 -1
  65. package/dist/integrations/openai/speech.d.ts +4 -1
  66. package/dist/integrations/openai/speech.d.ts.map +1 -1
  67. package/dist/integrations/openai/speech.js +6 -1
  68. package/dist/integrations/openai/speech.js.map +1 -1
  69. package/dist/integrations/telegram/types.d.ts +9 -0
  70. package/dist/integrations/telegram/types.d.ts.map +1 -1
  71. package/dist/lib/markdown.d.ts +0 -13
  72. package/dist/lib/markdown.d.ts.map +1 -1
  73. package/dist/lib/markdown.js +45 -0
  74. package/dist/lib/markdown.js.map +1 -1
  75. package/dist/lib/usage-metering/index.d.ts +13 -0
  76. package/dist/lib/usage-metering/index.d.ts.map +1 -0
  77. package/dist/lib/usage-metering/index.js +10 -0
  78. package/dist/lib/usage-metering/index.js.map +1 -0
  79. package/dist/lib/usage-metering/meter.d.ts +34 -0
  80. package/dist/lib/usage-metering/meter.d.ts.map +1 -0
  81. package/dist/lib/usage-metering/meter.js +28 -0
  82. package/dist/lib/usage-metering/meter.js.map +1 -0
  83. package/dist/lib/usage-metering/pricing.d.ts +39 -0
  84. package/dist/lib/usage-metering/pricing.d.ts.map +1 -0
  85. package/dist/lib/usage-metering/pricing.js +49 -0
  86. package/dist/lib/usage-metering/pricing.js.map +1 -0
  87. package/dist/lib/usage-metering/sink.d.ts +24 -0
  88. package/dist/lib/usage-metering/sink.d.ts.map +1 -0
  89. package/dist/lib/usage-metering/sink.js +56 -0
  90. package/dist/lib/usage-metering/sink.js.map +1 -0
  91. package/dist/server/factory.js +12 -9
  92. package/dist/server/factory.js.map +1 -1
  93. package/dist/server/http-server.d.ts +1 -0
  94. package/dist/server/http-server.d.ts.map +1 -1
  95. package/dist/server/http-server.js +45 -3
  96. package/dist/server/http-server.js.map +1 -1
  97. package/dist/services/background-runner.d.ts.map +1 -1
  98. package/dist/services/background-runner.js +11 -1
  99. package/dist/services/background-runner.js.map +1 -1
  100. package/dist/services/claude-spawn.service.d.ts.map +1 -1
  101. package/dist/services/claude-spawn.service.js +78 -4
  102. package/dist/services/claude-spawn.service.js.map +1 -1
  103. package/dist/services/codex-spawn.service.d.ts.map +1 -1
  104. package/dist/services/codex-spawn.service.js.map +1 -1
  105. package/dist/services/consolidation.service.d.ts.map +1 -1
  106. package/dist/services/consolidation.service.js +51 -35
  107. package/dist/services/consolidation.service.js.map +1 -1
  108. package/dist/services/copilot-spawn.service.d.ts.map +1 -1
  109. package/dist/services/copilot-spawn.service.js +8 -1
  110. package/dist/services/copilot-spawn.service.js.map +1 -1
  111. package/dist/services/dispatcher/broker.d.ts +6 -0
  112. package/dist/services/dispatcher/broker.d.ts.map +1 -1
  113. package/dist/services/dispatcher/broker.js.map +1 -1
  114. package/dist/services/dispatcher/poller.d.ts.map +1 -1
  115. package/dist/services/dispatcher/poller.js +15 -0
  116. package/dist/services/dispatcher/poller.js.map +1 -1
  117. package/dist/services/keeper.service.d.ts.map +1 -1
  118. package/dist/services/keeper.service.js +97 -1
  119. package/dist/services/keeper.service.js.map +1 -1
  120. package/dist/services/memory-pruning.service.d.ts.map +1 -1
  121. package/dist/services/memory-pruning.service.js +3 -1
  122. package/dist/services/memory-pruning.service.js.map +1 -1
  123. package/dist/services/process.service.d.ts +51 -0
  124. package/dist/services/process.service.d.ts.map +1 -1
  125. package/dist/services/process.service.js +247 -7
  126. package/dist/services/process.service.js.map +1 -1
  127. package/dist/services/spawn-common.d.ts.map +1 -1
  128. package/dist/services/spawn-common.js +9 -2
  129. package/dist/services/spawn-common.js.map +1 -1
  130. package/dist/services/thread-config.service.d.ts.map +1 -1
  131. package/dist/services/thread-config.service.js +1 -1
  132. package/dist/services/thread-config.service.js.map +1 -1
  133. package/dist/services/thread-health.service.d.ts +19 -1
  134. package/dist/services/thread-health.service.d.ts.map +1 -1
  135. package/dist/services/thread-health.service.js +74 -4
  136. package/dist/services/thread-health.service.js.map +1 -1
  137. package/dist/services/thread-lifecycle.service.d.ts.map +1 -1
  138. package/dist/services/thread-lifecycle.service.js +5 -0
  139. package/dist/services/thread-lifecycle.service.js.map +1 -1
  140. package/dist/services/worker-cleanup.service.d.ts +12 -0
  141. package/dist/services/worker-cleanup.service.d.ts.map +1 -1
  142. package/dist/services/worker-cleanup.service.js +281 -70
  143. package/dist/services/worker-cleanup.service.js.map +1 -1
  144. package/dist/sessions/mcp-registry.d.ts +6 -0
  145. package/dist/sessions/mcp-registry.d.ts.map +1 -1
  146. package/dist/sessions/mcp-registry.js +8 -0
  147. package/dist/sessions/mcp-registry.js.map +1 -1
  148. package/dist/tools/defs/session-defs.d.ts.map +1 -1
  149. package/dist/tools/defs/session-defs.js +20 -2
  150. package/dist/tools/defs/session-defs.js.map +1 -1
  151. package/dist/tools/delegate-tool.d.ts.map +1 -1
  152. package/dist/tools/delegate-tool.js +84 -4
  153. package/dist/tools/delegate-tool.js.map +1 -1
  154. package/dist/tools/memory-tools.d.ts +1 -1
  155. package/dist/tools/memory-tools.d.ts.map +1 -1
  156. package/dist/tools/memory-tools.js +4 -4
  157. package/dist/tools/memory-tools.js.map +1 -1
  158. package/dist/tools/utility-tools.d.ts.map +1 -1
  159. package/dist/tools/utility-tools.js +1 -1
  160. package/dist/tools/utility-tools.js.map +1 -1
  161. package/dist/tools/wait/drive-handler.js +1 -1
  162. package/dist/tools/wait/drive-handler.js.map +1 -1
  163. package/dist/tools/wait/media-processor.d.ts.map +1 -1
  164. package/dist/tools/wait/media-processor.js +2 -2
  165. package/dist/tools/wait/media-processor.js.map +1 -1
  166. package/dist/tools/wait/message-delivery.d.ts +10 -0
  167. package/dist/tools/wait/message-delivery.d.ts.map +1 -1
  168. package/dist/tools/wait/message-delivery.js +48 -1
  169. package/dist/tools/wait/message-delivery.js.map +1 -1
  170. package/dist/tools/wait/poll-loop.d.ts.map +1 -1
  171. package/dist/tools/wait/poll-loop.js +18 -0
  172. package/dist/tools/wait/poll-loop.js.map +1 -1
  173. package/package.json +3 -2
  174. package/templates/swarm.default.md +4 -1
  175. package/dist/data/memory/topic-index.d.ts +0 -20
  176. package/dist/data/memory/topic-index.d.ts.map +0 -1
  177. package/dist/data/memory/topic-index.js +0 -91
  178. package/dist/data/memory/topic-index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/integrations/openai/chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/integrations/openai/chat.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAShE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAuB,EACvB,MAAc,EACd,OAUC;IAED,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,aAAa,CAAC;IAC9C,MAAM,IAAI,GAA4B;QACpC,KAAK;QACL,QAAQ;QACR,qBAAqB,EAAE,OAAO,EAAE,SAAS,IAAI,GAAG;QAChD,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,CAAC;KACvC,CAAC;IACF,IAAI,OAAO,EAAE,cAAc,EAAE,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAChD,CAAC;IACD,MAAM,WAAW,GAAG,CAAC,CAAC;IACtB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,SAAS,IAAI,MAAM,CAAC,CAAC;QACjF,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4CAA4C,EAAE;gBACzE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,MAAM,EAAE;iBAClC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBACtD,IAAI,OAAO,GAAG,WAAW,GAAG,CAAC,EAAE,CAAC;oBAC9B,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC3E,MAAM,OAAO,GACX,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC;wBACvE,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;oBACtB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;oBACjD,SAAS;gBACX,CAAC;YACH,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACtF,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAGlC,CAAC;YACF,WAAW,CAAC;gBACV,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,MAAM;gBACrC,KAAK;gBACL,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa;gBACvC,gBAAgB,EAAE,IAAI,CAAC,KAAK,EAAE,iBAAiB;gBAC/C,QAAQ,EAAE,OAAO,EAAE,QAAQ;aAC5B,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;QACnD,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC5D,CAAC;AAED,6EAA6E;AAE7E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,MAAc,EACd,QAAiB;IAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,sCAAsC,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,MAAM,EAAE;aAClC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,wBAAwB;gBAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,6BAA6B;aAC1D,CAAC;YACF,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAGlC,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;QAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,WAAW,CAAC;YACV,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,wBAAwB;YAC/B,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa;YACvC,QAAQ;SACT,CAAC,CAAC;QACH,OAAO,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,4EAA4E;AAE5E,yFAAyF;AACzF,MAAM,UAAU,gBAAgB,CAAC,CAAe,EAAE,CAAe;IAC/D,IAAI,GAAG,GAAG,CAAC,EACT,KAAK,GAAG,CAAC,EACT,KAAK,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;AACvC,CAAC"}
@@ -21,7 +21,10 @@ export declare function textToSpeech(text: string, apiKey: string, voice?: TTSVo
21
21
  *
22
22
  * @param audioBuffer Raw audio content (OGG Opus from Telegram voice messages).
23
23
  * @param apiKey Fallback API key (used when TRANSCRIPTION_API_KEY is unset).
24
+ * @param filename Upload filename (extension drives Whisper's format sniffing).
25
+ * @param audioSeconds Clip duration, when known — used for cost metering only.
26
+ * @param threadId Originating thread, when known — used for usage attribution only.
24
27
  * @returns The transcribed text (empty string if no speech detected).
25
28
  */
26
- export declare function transcribeAudio(audioBuffer: Buffer, apiKey: string, filename?: string): Promise<string>;
29
+ export declare function transcribeAudio(audioBuffer: Buffer, apiKey: string, filename?: string, audioSeconds?: number, threadId?: number): Promise<string>;
27
30
  //# sourceMappingURL=speech.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"speech.d.ts","sourceRoot":"","sources":["../../../src/integrations/openai/speech.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,6BAA6B;AAC7B,eAAO,MAAM,UAAU,gEAAiE,CAAC;AACzF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,QAAiB,GACvB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAoB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
1
+ {"version":3,"file":"speech.d.ts","sourceRoot":"","sources":["../../../src/integrations/openai/speech.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,6BAA6B;AAC7B,eAAO,MAAM,UAAU,gEAAiE,CAAC;AACzF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,QAAiB,GACvB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAoB,EAC9B,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAkCjB"}
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Extracted from openai.ts for modular decomposition (Phase 3B).
5
5
  */
6
+ import { recordUsage } from "../../lib/usage-metering/index.js";
6
7
  // ─── TTS ──────────────────────────────────────────────────────────────────
7
8
  /** Valid TTS voice names. */
8
9
  export const TTS_VOICES = ["alloy", "echo", "fable", "onyx", "nova", "shimmer"];
@@ -42,9 +43,12 @@ export async function textToSpeech(text, apiKey, voice = "nova") {
42
43
  *
43
44
  * @param audioBuffer Raw audio content (OGG Opus from Telegram voice messages).
44
45
  * @param apiKey Fallback API key (used when TRANSCRIPTION_API_KEY is unset).
46
+ * @param filename Upload filename (extension drives Whisper's format sniffing).
47
+ * @param audioSeconds Clip duration, when known — used for cost metering only.
48
+ * @param threadId Originating thread, when known — used for usage attribution only.
45
49
  * @returns The transcribed text (empty string if no speech detected).
46
50
  */
47
- export async function transcribeAudio(audioBuffer, apiKey, filename = "voice.ogg") {
51
+ export async function transcribeAudio(audioBuffer, apiKey, filename = "voice.ogg", audioSeconds, threadId) {
48
52
  const baseUrl = (process.env.TRANSCRIPTION_BASE_URL || "https://api.openai.com/v1").replace(/\/+$/, "");
49
53
  const key = process.env.TRANSCRIPTION_API_KEY || apiKey;
50
54
  const model = process.env.TRANSCRIPTION_MODEL || "whisper-1";
@@ -65,6 +69,7 @@ export async function transcribeAudio(audioBuffer, apiKey, filename = "voice.ogg
65
69
  const errText = await response.text().catch(() => response.statusText);
66
70
  throw new Error(`Whisper transcription failed (${model} @ ${baseUrl}): ${response.status} ${errText}`);
67
71
  }
72
+ recordUsage({ category: "transcription", model, audioSeconds, threadId });
68
73
  const result = (await response.json());
69
74
  return result.text ?? "";
70
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"speech.js","sourceRoot":"","sources":["../../../src/integrations/openai/speech.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"speech.js","sourceRoot":"","sources":["../../../src/integrations/openai/speech.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAEhE,6EAA6E;AAE7E,6BAA6B;AAC7B,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAU,CAAC;AAGzF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,MAAc,EACd,QAAkB,MAAM;IAExB,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,wCAAwC,EAAE;QACrE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,MAAM,EAAE;SAClC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK,EAAE,OAAO;YACd,KAAK,EAAE,IAAI;YACX,KAAK;YACL,eAAe,EAAE,MAAM;SACxB,CAAC;QACF,MAAM;KACP,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAmB,EACnB,MAAc,EACd,WAAmB,WAAW,EAC9B,YAAqB,EACrB,QAAiB;IAEjB,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,2BAA2B,CAAC,CAAC,OAAO,CACzF,MAAM,EACN,EAAE,CACH,CAAC;IACF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,MAAM,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,WAAW,CAAC;IAE7D,qEAAqE;IACrE,0CAA0C;IAC1C,oEAAoE;IACpE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3E,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAEhC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,uBAAuB,EAAE;QAC9D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,GAAG,EAAE,EAAE;QAC3C,IAAI,EAAE,QAAQ;QACd,MAAM;KACP,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CACb,iCAAiC,KAAK,MAAM,OAAO,MAAM,QAAQ,CAAC,MAAM,IAAI,OAAO,EAAE,CACtF,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE1E,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAsB,CAAC;IAC5D,OAAO,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;AAC3B,CAAC"}
@@ -41,6 +41,15 @@ export interface TelegramMessage {
41
41
  forum_topic_edited?: {
42
42
  name?: string;
43
43
  };
44
+ /**
45
+ * Present when the operator replies to a message with part of it selected
46
+ * (Telegram's "quote" feature). `text` is the exact excerpt they highlighted.
47
+ */
48
+ quote?: {
49
+ text: string;
50
+ position?: number;
51
+ is_manual?: boolean;
52
+ };
44
53
  }
45
54
  export interface PhotoSize {
46
55
  file_id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/integrations/telegram/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/integrations/telegram/types.ts"],"names":[],"mappings":"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"}
@@ -4,19 +4,6 @@
4
4
  * Converts standard Markdown to Telegram MarkdownV2, working around
5
5
  * several telegramify-markdown limitations.
6
6
  */
7
- /**
8
- * Convert standard Markdown to Telegram MarkdownV2.
9
- *
10
- * Works around several telegramify-markdown limitations:
11
- * 1. Fenced code blocks are emitted as single-backtick inline code instead
12
- * of triple-backtick blocks → pre-extract, re-insert after conversion.
13
- * 2. Markdown tables contain `|` which is a MarkdownV2 reserved character;
14
- * telegramify-markdown does not handle tables → pre-extract and wrap in
15
- * a plain code block so the table layout is preserved.
16
- * 3. Blockquotes with 'escape' strategy produce double-escaped characters
17
- * (e.g. `\\.` instead of `\.`) → pre-convert `> text` to `▎ text`
18
- * (a common Telegram convention) so the library never sees blockquotes.
19
- */
20
7
  export declare function convertMarkdown(markdown: string): string;
21
8
  /**
22
9
  * Split a message into chunks that fit Telegram's 4096-char limit.
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyExD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,MAAM,EAAE,CAelE"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwDH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyFxD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,MAAM,EAAE,CAelE"}
@@ -19,7 +19,38 @@ const telegramifyMarkdown = esmRequire("telegramify-markdown");
19
19
  * 3. Blockquotes with 'escape' strategy produce double-escaped characters
20
20
  * (e.g. `\\.` instead of `\.`) → pre-convert `> text` to `▎ text`
21
21
  * (a common Telegram convention) so the library never sees blockquotes.
22
+ * 4. `\` is itself a MarkdownV2 reserved character but the library leaves it
23
+ * bare, so Telegram eats it as an escape lead-in and Windows paths lose
24
+ * every separator → protect literal backslashes across the conversion.
22
25
  */
26
+ /**
27
+ * Base stand-in for a literal `\` while telegramify-markdown runs. Must survive the
28
+ * library untouched — hence plain uppercase ASCII, which nothing escapes.
29
+ *
30
+ * The token is lengthened per call until it does not occur in the input (see
31
+ * {@link uniqueToken}): a message that legitimately contains this word — a paste of
32
+ * this very file, for instance — would otherwise have it rewritten to `\\`.
33
+ */
34
+ const BACKSLASH_PLACEHOLDER_BASE = "BACKSLASHPLACEHOLDERX";
35
+ /** Extend `base` with `X`s until it appears nowhere in `source`. */
36
+ function uniqueToken(base, source) {
37
+ let token = base;
38
+ while (source.includes(token))
39
+ token += "X";
40
+ return token;
41
+ }
42
+ /**
43
+ * Backslashes we leave alone because they are a deliberate Markdown escape rather
44
+ * than a path separator.
45
+ *
46
+ * Restricted to the *inline formatting* delimiters. The wider MarkdownV2 reserved
47
+ * set (`.`, `-`, `+`, `=`, `|`, `{`, `}`, `>`, `#`) is only meaningful in Telegram's
48
+ * OUTPUT encoding, not in the standard Markdown we are given as INPUT — but those
49
+ * characters follow a separator constantly in real paths (`.\dist`, `..\..\src`,
50
+ * `C:\src\.git`). Treating `\.` as an escape swallowed the separator and reproduced
51
+ * the exact bug this protection exists to fix.
52
+ */
53
+ const DELIBERATE_ESCAPE_TARGETS = /\\(?![_*[\]()~`!\\])/g;
23
54
  export function convertMarkdown(markdown) {
24
55
  const blocks = [];
25
56
  const placeholder = (i) => `CODEBLOCKPLACEHOLDER${i}END`;
@@ -68,8 +99,22 @@ export function convertMarkdown(markdown) {
68
99
  });
69
100
  // 3. Convert Markdown blockquotes to ▎ prefix lines.
70
101
  preprocessed = preprocessed.replace(/^>\s?(.*)$/gm, "▎ $1");
102
+ // 3b. Protect literal backslashes. telegramify-markdown escapes every
103
+ // MarkdownV2 reserved character except `\` itself, so a Windows path
104
+ // reaches Telegram as `C:\src\lib` — and Telegram's parser reads each
105
+ // `\x` as an escape sequence and swallows the separator ("C:srclib").
106
+ // Only backslashes that are NOT a deliberate Markdown escape are
107
+ // protected, so `\*literal star\*` keeps working.
108
+ const backslashToken = uniqueToken(BACKSLASH_PLACEHOLDER_BASE, markdown);
109
+ preprocessed = preprocessed.replace(DELIBERATE_ESCAPE_TARGETS, backslashToken);
71
110
  // 4. Convert the rest with telegramify-markdown.
72
111
  let converted = telegramifyMarkdown(preprocessed, "escape");
112
+ // 4b. Restore protected backslashes as MarkdownV2-escaped literals. This MUST
113
+ // happen before the code-block and table re-insertion below: those splice
114
+ // raw user content back in, already carrying their own escaping, and a
115
+ // later sweep for the token would rewrite any literal occurrence inside
116
+ // them (a code block quoting this file, say) into a stray `\\`.
117
+ converted = converted.replaceAll(backslashToken, "\\\\");
73
118
  // 5. Re-insert code blocks in MarkdownV2 format.
74
119
  converted = converted.replace(/CODEBLOCKPLACEHOLDER(\d+)END/g, (_m, idx) => {
75
120
  const { lang, code } = blocks[parseInt(idx, 10)];
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Token-usage meter — public surface.
3
+ *
4
+ * Call sites import ONLY `recordUsage` from here (DIP). The pricing table and
5
+ * sink are internal details that can change without touching any call site.
6
+ */
7
+ export { recordUsage } from "./meter.js";
8
+ export type { UsageEvent, UsageEventInput } from "./meter.js";
9
+ export { costOf, MODEL_PRICES } from "./pricing.js";
10
+ export type { ModelPrice, Priceable } from "./pricing.js";
11
+ export type { UsageSink } from "./sink.js";
12
+ export { JsonlUsageSink } from "./sink.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/usage-metering/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Token-usage meter — public surface.
3
+ *
4
+ * Call sites import ONLY `recordUsage` from here (DIP). The pricing table and
5
+ * sink are internal details that can change without touching any call site.
6
+ */
7
+ export { recordUsage } from "./meter.js";
8
+ export { costOf, MODEL_PRICES } from "./pricing.js";
9
+ export { JsonlUsageSink } from "./sink.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/usage-metering/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Token/cost meter (SRP): it ONLY meters. It computes cost via the pricing
3
+ * module and appends one record via a sink. It never throws into the caller —
4
+ * telemetry must not be able to break a real OpenAI call.
5
+ *
6
+ * Call sites depend on {@link recordUsage} alone (DIP) — not on the pricing
7
+ * table or the sink implementation.
8
+ */
9
+ import { type UsageSink } from "./sink.js";
10
+ /** One metered OpenAI call. */
11
+ export interface UsageEvent {
12
+ /** Logical bucket: "chat" | "embedding" | "consolidation" | "transcription" … */
13
+ category: string;
14
+ /** Model id as sent to the provider (drives pricing). */
15
+ model: string;
16
+ /** Prompt/input tokens (chat, embeddings). */
17
+ promptTokens?: number;
18
+ /** Completion/output tokens (chat). */
19
+ completionTokens?: number;
20
+ /** Audio length in seconds (transcription). */
21
+ audioSeconds?: number;
22
+ /** Originating thread, when known. */
23
+ threadId?: number;
24
+ /** Epoch ms; stamped by {@link recordUsage}. */
25
+ timestamp: number;
26
+ }
27
+ /** Everything a caller supplies — the meter stamps {@link UsageEvent.timestamp}. */
28
+ export type UsageEventInput = Omit<UsageEvent, "timestamp">;
29
+ /**
30
+ * Record one usage event: compute its cost and append it via the sink.
31
+ * Best-effort — wrapped in try/catch so it NEVER throws into the caller.
32
+ */
33
+ export declare function recordUsage(event: UsageEventInput, sink?: UsageSink): void;
34
+ //# sourceMappingURL=meter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meter.d.ts","sourceRoot":"","sources":["../../../src/lib/usage-metering/meter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3D,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB,iFAAiF;IACjF,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,oFAAoF;AACpF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAK5D;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,GAAE,SAAuB,GAAG,IAAI,CASvF"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Token/cost meter (SRP): it ONLY meters. It computes cost via the pricing
3
+ * module and appends one record via a sink. It never throws into the caller —
4
+ * telemetry must not be able to break a real OpenAI call.
5
+ *
6
+ * Call sites depend on {@link recordUsage} alone (DIP) — not on the pricing
7
+ * table or the sink implementation.
8
+ */
9
+ import { costOf } from "./pricing.js";
10
+ import { JsonlUsageSink } from "./sink.js";
11
+ /** The default JSONL sink; overridable (e.g. in tests) via the 2nd arg. */
12
+ const defaultSink = new JsonlUsageSink();
13
+ /**
14
+ * Record one usage event: compute its cost and append it via the sink.
15
+ * Best-effort — wrapped in try/catch so it NEVER throws into the caller.
16
+ */
17
+ export function recordUsage(event, sink = defaultSink) {
18
+ try {
19
+ const timestamp = Date.now();
20
+ const costUsd = costOf(event);
21
+ const record = { ...event, timestamp, time: new Date(timestamp).toISOString(), costUsd };
22
+ sink.write(JSON.stringify(record));
23
+ }
24
+ catch {
25
+ /* best-effort telemetry — swallow everything */
26
+ }
27
+ }
28
+ //# sourceMappingURL=meter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meter.js","sourceRoot":"","sources":["../../../src/lib/usage-metering/meter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,cAAc,EAAkB,MAAM,WAAW,CAAC;AAuB3D,2EAA2E;AAC3E,MAAM,WAAW,GAAc,IAAI,cAAc,EAAE,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAsB,EAAE,OAAkB,WAAW;IAC/E,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC;QACzF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;AACH,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Per-model price table + a pure cost function (Open/Closed).
3
+ *
4
+ * Adding a model or provider is a TABLE edit here — never a change to the meter
5
+ * or the call sites. Prices are list rates; keep them in one place so a rate
6
+ * change is a one-line diff.
7
+ *
8
+ * Units:
9
+ * - inputPerMTok / outputPerMTok : USD per 1,000,000 tokens
10
+ * - audioPerMinute : USD per minute of audio (Whisper family)
11
+ */
12
+ export interface ModelPrice {
13
+ /** USD per 1M prompt/input tokens. */
14
+ inputPerMTok?: number;
15
+ /** USD per 1M completion/output tokens. */
16
+ outputPerMTok?: number;
17
+ /** USD per minute of transcribed audio. */
18
+ audioPerMinute?: number;
19
+ }
20
+ /**
21
+ * List prices as of 2026-07. Sources:
22
+ * - OpenAI gpt-4o / gpt-4o-mini / text-embedding-3-small / whisper-1: openai.com/pricing
23
+ * - Groq whisper-large-v3: $0.111/hr (groq.com/pricing)
24
+ */
25
+ export declare const MODEL_PRICES: Record<string, ModelPrice>;
26
+ /** Minimal shape needed to price a call — a subset of {@link UsageEvent}. */
27
+ export interface Priceable {
28
+ model: string;
29
+ promptTokens?: number;
30
+ completionTokens?: number;
31
+ audioSeconds?: number;
32
+ }
33
+ /**
34
+ * Pure cost in USD for one usage event. Unknown models (absent from the table)
35
+ * cost 0 — pricing is best-effort telemetry, never a hard dependency. Missing
36
+ * token/audio fields simply contribute nothing.
37
+ */
38
+ export declare function costOf(event: Priceable): number;
39
+ //# sourceMappingURL=pricing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../../src/lib/usage-metering/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAUnD,CAAC;AAEF,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAc/C"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Per-model price table + a pure cost function (Open/Closed).
3
+ *
4
+ * Adding a model or provider is a TABLE edit here — never a change to the meter
5
+ * or the call sites. Prices are list rates; keep them in one place so a rate
6
+ * change is a one-line diff.
7
+ *
8
+ * Units:
9
+ * - inputPerMTok / outputPerMTok : USD per 1,000,000 tokens
10
+ * - audioPerMinute : USD per minute of audio (Whisper family)
11
+ */
12
+ /**
13
+ * List prices as of 2026-07. Sources:
14
+ * - OpenAI gpt-4o / gpt-4o-mini / text-embedding-3-small / whisper-1: openai.com/pricing
15
+ * - Groq whisper-large-v3: $0.111/hr (groq.com/pricing)
16
+ */
17
+ export const MODEL_PRICES = {
18
+ // OpenAI chat
19
+ "gpt-4o": { inputPerMTok: 2.5, outputPerMTok: 10 },
20
+ "gpt-4o-mini": { inputPerMTok: 0.15, outputPerMTok: 0.6 },
21
+ // OpenAI embeddings (input only)
22
+ "text-embedding-3-small": { inputPerMTok: 0.02 },
23
+ // OpenAI transcription — $0.006/min
24
+ "whisper-1": { audioPerMinute: 0.006 },
25
+ // Groq transcription — $0.111/hr → per minute
26
+ "whisper-large-v3": { audioPerMinute: 0.111 / 60 },
27
+ };
28
+ /**
29
+ * Pure cost in USD for one usage event. Unknown models (absent from the table)
30
+ * cost 0 — pricing is best-effort telemetry, never a hard dependency. Missing
31
+ * token/audio fields simply contribute nothing.
32
+ */
33
+ export function costOf(event) {
34
+ const price = MODEL_PRICES[event.model];
35
+ if (!price)
36
+ return 0;
37
+ let usd = 0;
38
+ if (price.inputPerMTok && event.promptTokens) {
39
+ usd += (event.promptTokens / 1_000_000) * price.inputPerMTok;
40
+ }
41
+ if (price.outputPerMTok && event.completionTokens) {
42
+ usd += (event.completionTokens / 1_000_000) * price.outputPerMTok;
43
+ }
44
+ if (price.audioPerMinute && event.audioSeconds) {
45
+ usd += (event.audioSeconds / 60) * price.audioPerMinute;
46
+ }
47
+ return usd;
48
+ }
49
+ //# sourceMappingURL=pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../../src/lib/usage-metering/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAA+B;IACtD,cAAc;IACd,QAAQ,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE;IAClD,aAAa,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE;IACzD,iCAAiC;IACjC,wBAAwB,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;IAChD,oCAAoC;IACpC,WAAW,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE;IACtC,8CAA8C;IAC9C,kBAAkB,EAAE,EAAE,cAAc,EAAE,KAAK,GAAG,EAAE,EAAE;CACnD,CAAC;AAUF;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,KAAgB;IACrC,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IACrB,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QAC7C,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC;IAC/D,CAAC;IACD,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QAClD,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC;IACpE,CAAC;IACD,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QAC/C,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,cAAc,CAAC;IAC1D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Usage sink (ISP + DIP): the meter depends only on this one tiny method, so
3
+ * swapping the JSONL file for a DB, HTTP endpoint, or UI stream later is a
4
+ * one-class change with no meter or call-site edits.
5
+ */
6
+ export interface UsageSink {
7
+ /** Append one already-serialized record. Implementations must not throw. */
8
+ write(line: string): void;
9
+ }
10
+ /**
11
+ * Default sink: appends one JSONL line per event to
12
+ * `<data>/logs/usage/usage-YYYYMMDD.jsonl` (one file per day). Best-effort —
13
+ * any filesystem error is swallowed so telemetry never breaks a real call.
14
+ */
15
+ export declare class JsonlUsageSink implements UsageSink {
16
+ private readonly dir;
17
+ /** Dirs already `mkdir`-ed this process, so we hit the FS once, not per write. */
18
+ private readonly ensured;
19
+ constructor(dir?: string);
20
+ /** Create the target dir at most once per process; swallow any FS error. */
21
+ private ensureDir;
22
+ write(line: string): void;
23
+ }
24
+ //# sourceMappingURL=sink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../../src/lib/usage-metering/sink.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAaD;;;;GAIG;AACH,qBAAa,cAAe,YAAW,SAAS;IAIlC,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEhB,GAAG,GAAE,MAAkB;IAEpD,4EAA4E;IAC5E,OAAO,CAAC,SAAS;IAWjB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAU1B"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Usage sink (ISP + DIP): the meter depends only on this one tiny method, so
3
+ * swapping the JSONL file for a DB, HTTP endpoint, or UI stream later is a
4
+ * one-class change with no meter or call-site edits.
5
+ */
6
+ import { mkdirSync } from "node:fs";
7
+ import { appendFile } from "node:fs/promises";
8
+ import { homedir } from "node:os";
9
+ import { join } from "node:path";
10
+ /** Base data dir, matching the pattern used across the app (see process.service.ts). */
11
+ const USAGE_DIR = join(homedir(), ".remote-copilot-mcp", "logs", "usage");
12
+ /** Local YYYYMMDD for daily-rotated filenames. */
13
+ function dayStamp(d) {
14
+ const y = d.getFullYear();
15
+ const m = String(d.getMonth() + 1).padStart(2, "0");
16
+ const day = String(d.getDate()).padStart(2, "0");
17
+ return `${y}${m}${day}`;
18
+ }
19
+ /**
20
+ * Default sink: appends one JSONL line per event to
21
+ * `<data>/logs/usage/usage-YYYYMMDD.jsonl` (one file per day). Best-effort —
22
+ * any filesystem error is swallowed so telemetry never breaks a real call.
23
+ */
24
+ export class JsonlUsageSink {
25
+ dir;
26
+ /** Dirs already `mkdir`-ed this process, so we hit the FS once, not per write. */
27
+ ensured = new Set();
28
+ constructor(dir = USAGE_DIR) {
29
+ this.dir = dir;
30
+ }
31
+ /** Create the target dir at most once per process; swallow any FS error. */
32
+ ensureDir() {
33
+ if (this.ensured.has(this.dir))
34
+ return true;
35
+ try {
36
+ mkdirSync(this.dir, { recursive: true });
37
+ this.ensured.add(this.dir);
38
+ return true;
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ write(line) {
45
+ if (!this.ensureDir())
46
+ return;
47
+ const file = join(this.dir, `usage-${dayStamp(new Date())}.jsonl`);
48
+ // Fire-and-forget: no synchronous FS on the hot path. Ordering within the
49
+ // file is best-effort. The .catch() no-ops so a rejected write never
50
+ // surfaces as an unhandled rejection or reaches the caller.
51
+ void appendFile(file, line + "\n").catch(() => {
52
+ /* best-effort telemetry — never throw into the caller */
53
+ });
54
+ }
55
+ }
56
+ //# sourceMappingURL=sink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink.js","sourceRoot":"","sources":["../../../src/lib/usage-metering/sink.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAOjC,wFAAwF;AACxF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,qBAAqB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1E,kDAAkD;AAClD,SAAS,QAAQ,CAAC,CAAO;IACvB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,cAAc;IAII;IAH7B,kFAAkF;IACjE,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAE7C,YAA6B,MAAc,SAAS;QAAvB,QAAG,GAAH,GAAG,CAAoB;IAAG,CAAC;IAExD,4EAA4E;IACpE,SAAS;QACf,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5C,IAAI,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAY;QAChB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC;QACnE,0EAA0E;QAC1E,qEAAqE;QACrE,4DAA4D;QAC5D,KAAK,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YAC5C,yDAAyD;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -424,20 +424,23 @@ function createMcpServer(telegram, telegramChatId, getMemoryDb, threadLifecycle,
424
424
  return handleStartThread(safeArgs, delegateCtx);
425
425
  },
426
426
  send_message_to_thread: async (typedArgs) => {
427
- // Counts as an operator-facing send for auto-forward purposes: the agent
428
- // deliberately routed its output somewhere, so its stdout is not "lost".
429
- // Only on success — a failed route means the output really was lost.
430
- const result = await handleSendMessageToThreadFile({
427
+ // Does NOT count as an operator-facing send: this routes output to another
428
+ // thread's topic, not the operator's view of THIS thread. An orchestrator
429
+ // that delegates to a worker AND writes its status for the operator as
430
+ // plain stdout in the same turn must still have that status auto-forwarded
431
+ // to its own topic — otherwise the operator sees the thread go silent.
432
+ return handleSendMessageToThreadFile({
431
433
  ...typedArgs,
432
434
  _callerThreadId: currentThreadId,
433
435
  });
434
- if (!result.isError)
435
- operatorSendsThisTurn++;
436
- return result;
437
436
  },
438
- get_threads_health: () => {
437
+ get_threads_health: (typedArgs) => {
439
438
  try {
440
- const markdown = getThreadsHealth(getMemoryDb);
439
+ const markdown = getThreadsHealth(getMemoryDb, {
440
+ status: typedArgs?.status,
441
+ includeDead: typedArgs?.includeDead,
442
+ limit: typedArgs?.limit,
443
+ });
441
444
  return { content: [{ type: "text", text: markdown }] };
442
445
  }
443
446
  catch (err) {