botinabox 2.4.3 → 2.5.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 (277) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +190 -190
  3. package/bin/botinabox.mjs +2 -2
  4. package/dist/channels/slack/index.d.ts +1 -1
  5. package/dist/{chat-pipeline-BWrtVqEP.d.ts → chat-pipeline-DuNX5WoL.d.ts} +3 -0
  6. package/dist/cli.js +0 -0
  7. package/dist/index.d.ts +5 -2
  8. package/dist/index.js +59 -22
  9. package/package.json +100 -99
  10. package/dist/channels/discord/adapter.d.ts +0 -32
  11. package/dist/channels/discord/adapter.js +0 -70
  12. package/dist/channels/discord/inbound.d.ts +0 -25
  13. package/dist/channels/discord/inbound.js +0 -24
  14. package/dist/channels/discord/models.d.ts +0 -8
  15. package/dist/channels/discord/models.js +0 -5
  16. package/dist/channels/discord/outbound.d.ts +0 -14
  17. package/dist/channels/discord/outbound.js +0 -38
  18. package/dist/channels/slack/adapter.d.ts +0 -33
  19. package/dist/channels/slack/adapter.js +0 -74
  20. package/dist/channels/slack/inbound.d.ts +0 -59
  21. package/dist/channels/slack/inbound.js +0 -96
  22. package/dist/channels/slack/models.d.ts +0 -9
  23. package/dist/channels/slack/models.js +0 -5
  24. package/dist/channels/slack/outbound.d.ts +0 -12
  25. package/dist/channels/slack/outbound.js +0 -18
  26. package/dist/channels/slack/transcribe.d.ts +0 -41
  27. package/dist/channels/slack/transcribe.js +0 -106
  28. package/dist/channels/webhook/adapter.d.ts +0 -23
  29. package/dist/channels/webhook/adapter.js +0 -86
  30. package/dist/channels/webhook/hmac.d.ts +0 -13
  31. package/dist/channels/webhook/hmac.js +0 -26
  32. package/dist/channels/webhook/models.d.ts +0 -9
  33. package/dist/channels/webhook/models.js +0 -5
  34. package/dist/channels/webhook/server.d.ts +0 -20
  35. package/dist/channels/webhook/server.js +0 -91
  36. package/dist/chat-pipeline-C-XlLGNl.d.ts +0 -648
  37. package/dist/chat-pipeline-CR1KF6eX.d.ts +0 -652
  38. package/dist/chat-pipeline-DisuC8SB.d.ts +0 -643
  39. package/dist/chunk-2LGXQPEA.js +0 -41
  40. package/dist/chunk-3X3YKI4T.js +0 -357
  41. package/dist/chunk-D47AIFOD.js +0 -351
  42. package/dist/chunk-DSNJKNEW.js +0 -328
  43. package/dist/chunk-GS2JFL6I.js +0 -144
  44. package/dist/chunk-J6S6QMUY.js +0 -144
  45. package/dist/chunk-QLA6YOFN.js +0 -22
  46. package/dist/chunk-UACT2WXX.js +0 -381
  47. package/dist/cli/templates/config.yml.d.ts +0 -7
  48. package/dist/cli/templates/config.yml.js +0 -61
  49. package/dist/cli/templates/env.d.ts +0 -1
  50. package/dist/cli/templates/env.js +0 -30
  51. package/dist/cli/templates/index.ts.d.ts +0 -2
  52. package/dist/cli/templates/index.ts.js +0 -30
  53. package/dist/cli/templates/package.json.d.ts +0 -5
  54. package/dist/cli/templates/package.json.js +0 -28
  55. package/dist/connector-DDahQw-2.d.ts +0 -63
  56. package/dist/connectors/google/calendar-connector.d.ts +0 -40
  57. package/dist/connectors/google/calendar-connector.js +0 -243
  58. package/dist/connectors/google/gmail-connector.d.ts +0 -42
  59. package/dist/connectors/google/gmail-connector.js +0 -345
  60. package/dist/connectors/google/oauth.d.ts +0 -48
  61. package/dist/connectors/google/oauth.js +0 -112
  62. package/dist/connectors/google/types.d.ts +0 -78
  63. package/dist/connectors/google/types.js +0 -2
  64. package/dist/core/chat/auto-discovery.d.ts +0 -16
  65. package/dist/core/chat/auto-discovery.js +0 -54
  66. package/dist/core/chat/channel-registry.d.ts +0 -45
  67. package/dist/core/chat/channel-registry.js +0 -96
  68. package/dist/core/chat/chat-pipeline.d.ts +0 -113
  69. package/dist/core/chat/chat-pipeline.js +0 -395
  70. package/dist/core/chat/chat-responder.d.ts +0 -90
  71. package/dist/core/chat/chat-responder.js +0 -185
  72. package/dist/core/chat/formatter.d.ts +0 -11
  73. package/dist/core/chat/formatter.js +0 -60
  74. package/dist/core/chat/index.d.ts +0 -24
  75. package/dist/core/chat/index.js +0 -18
  76. package/dist/core/chat/message-interpreter.d.ts +0 -91
  77. package/dist/core/chat/message-interpreter.js +0 -166
  78. package/dist/core/chat/message-store.d.ts +0 -66
  79. package/dist/core/chat/message-store.js +0 -131
  80. package/dist/core/chat/notification-queue.d.ts +0 -34
  81. package/dist/core/chat/notification-queue.js +0 -111
  82. package/dist/core/chat/pipeline.d.ts +0 -38
  83. package/dist/core/chat/pipeline.js +0 -89
  84. package/dist/core/chat/policies.d.ts +0 -16
  85. package/dist/core/chat/policies.js +0 -25
  86. package/dist/core/chat/routing.d.ts +0 -17
  87. package/dist/core/chat/routing.js +0 -36
  88. package/dist/core/chat/session-key.d.ts +0 -30
  89. package/dist/core/chat/session-key.js +0 -65
  90. package/dist/core/chat/session-manager.d.ts +0 -17
  91. package/dist/core/chat/session-manager.js +0 -23
  92. package/dist/core/chat/text-chunker.d.ts +0 -9
  93. package/dist/core/chat/text-chunker.js +0 -48
  94. package/dist/core/chat/triage-router.d.ts +0 -75
  95. package/dist/core/chat/triage-router.js +0 -142
  96. package/dist/core/chat/types.d.ts +0 -5
  97. package/dist/core/chat/types.js +0 -5
  98. package/dist/core/config/defaults.d.ts +0 -2
  99. package/dist/core/config/defaults.js +0 -38
  100. package/dist/core/config/index.d.ts +0 -6
  101. package/dist/core/config/index.js +0 -4
  102. package/dist/core/config/interpolate.d.ts +0 -5
  103. package/dist/core/config/interpolate.js +0 -27
  104. package/dist/core/config/loader.d.ts +0 -24
  105. package/dist/core/config/loader.js +0 -59
  106. package/dist/core/config/schema.d.ts +0 -5
  107. package/dist/core/config/schema.js +0 -119
  108. package/dist/core/data/core-entity-contexts.d.ts +0 -14
  109. package/dist/core/data/core-entity-contexts.js +0 -197
  110. package/dist/core/data/core-migrations.d.ts +0 -5
  111. package/dist/core/data/core-migrations.js +0 -45
  112. package/dist/core/data/core-schema.d.ts +0 -6
  113. package/dist/core/data/core-schema.js +0 -454
  114. package/dist/core/data/data-store.d.ts +0 -67
  115. package/dist/core/data/data-store.js +0 -218
  116. package/dist/core/data/domain-entity-contexts.d.ts +0 -29
  117. package/dist/core/data/domain-entity-contexts.js +0 -321
  118. package/dist/core/data/domain-schema.d.ts +0 -36
  119. package/dist/core/data/domain-schema.js +0 -323
  120. package/dist/core/data/index.d.ts +0 -7
  121. package/dist/core/data/index.js +0 -7
  122. package/dist/core/data/types.d.ts +0 -111
  123. package/dist/core/data/types.js +0 -1
  124. package/dist/core/hooks/hook-bus.d.ts +0 -18
  125. package/dist/core/hooks/hook-bus.js +0 -120
  126. package/dist/core/hooks/index.d.ts +0 -2
  127. package/dist/core/hooks/index.js +0 -1
  128. package/dist/core/hooks/types.d.ts +0 -19
  129. package/dist/core/hooks/types.js +0 -1
  130. package/dist/core/index.d.ts +0 -4
  131. package/dist/core/index.js +0 -4
  132. package/dist/core/llm/auto-discovery.d.ts +0 -11
  133. package/dist/core/llm/auto-discovery.js +0 -49
  134. package/dist/core/llm/cost-tracker.d.ts +0 -6
  135. package/dist/core/llm/cost-tracker.js +0 -38
  136. package/dist/core/llm/index.d.ts +0 -4
  137. package/dist/core/llm/index.js +0 -3
  138. package/dist/core/llm/model-router.d.ts +0 -25
  139. package/dist/core/llm/model-router.js +0 -49
  140. package/dist/core/llm/provider-registry.d.ts +0 -9
  141. package/dist/core/llm/provider-registry.js +0 -25
  142. package/dist/core/llm/types.d.ts +0 -2
  143. package/dist/core/llm/types.js +0 -2
  144. package/dist/core/orchestrator/adapters/api-adapter.d.ts +0 -34
  145. package/dist/core/orchestrator/adapters/api-adapter.js +0 -88
  146. package/dist/core/orchestrator/adapters/cli-adapter.d.ts +0 -22
  147. package/dist/core/orchestrator/adapters/cli-adapter.js +0 -69
  148. package/dist/core/orchestrator/adapters/deterministic-adapter.d.ts +0 -35
  149. package/dist/core/orchestrator/adapters/deterministic-adapter.js +0 -75
  150. package/dist/core/orchestrator/adapters/env-whitelist.d.ts +0 -4
  151. package/dist/core/orchestrator/adapters/env-whitelist.js +0 -27
  152. package/dist/core/orchestrator/adapters/output-extractor.d.ts +0 -11
  153. package/dist/core/orchestrator/adapters/output-extractor.js +0 -59
  154. package/dist/core/orchestrator/adapters/process-manager.d.ts +0 -15
  155. package/dist/core/orchestrator/adapters/process-manager.js +0 -26
  156. package/dist/core/orchestrator/adapters/tool-loop.d.ts +0 -22
  157. package/dist/core/orchestrator/adapters/tool-loop.js +0 -66
  158. package/dist/core/orchestrator/agent-registry.d.ts +0 -31
  159. package/dist/core/orchestrator/agent-registry.js +0 -135
  160. package/dist/core/orchestrator/budget-controller.d.ts +0 -19
  161. package/dist/core/orchestrator/budget-controller.js +0 -73
  162. package/dist/core/orchestrator/chain-guard.d.ts +0 -14
  163. package/dist/core/orchestrator/chain-guard.js +0 -23
  164. package/dist/core/orchestrator/circuit-breaker.d.ts +0 -65
  165. package/dist/core/orchestrator/circuit-breaker.js +0 -159
  166. package/dist/core/orchestrator/claude-stream-parser.d.ts +0 -31
  167. package/dist/core/orchestrator/claude-stream-parser.js +0 -99
  168. package/dist/core/orchestrator/config-revisions.d.ts +0 -6
  169. package/dist/core/orchestrator/config-revisions.js +0 -17
  170. package/dist/core/orchestrator/dependency-resolver.d.ts +0 -20
  171. package/dist/core/orchestrator/dependency-resolver.js +0 -78
  172. package/dist/core/orchestrator/governance-gate.d.ts +0 -110
  173. package/dist/core/orchestrator/governance-gate.js +0 -170
  174. package/dist/core/orchestrator/learning-pipeline.d.ts +0 -109
  175. package/dist/core/orchestrator/learning-pipeline.js +0 -249
  176. package/dist/core/orchestrator/loop-detector.d.ts +0 -51
  177. package/dist/core/orchestrator/loop-detector.js +0 -133
  178. package/dist/core/orchestrator/ndjson-logger.d.ts +0 -6
  179. package/dist/core/orchestrator/ndjson-logger.js +0 -18
  180. package/dist/core/orchestrator/permission-relay.d.ts +0 -72
  181. package/dist/core/orchestrator/permission-relay.js +0 -164
  182. package/dist/core/orchestrator/run-manager.d.ts +0 -31
  183. package/dist/core/orchestrator/run-manager.js +0 -178
  184. package/dist/core/orchestrator/scheduler.d.ts +0 -70
  185. package/dist/core/orchestrator/scheduler.js +0 -198
  186. package/dist/core/orchestrator/secret-store.d.ts +0 -57
  187. package/dist/core/orchestrator/secret-store.js +0 -171
  188. package/dist/core/orchestrator/session-manager.d.ts +0 -13
  189. package/dist/core/orchestrator/session-manager.js +0 -66
  190. package/dist/core/orchestrator/task-queue.d.ts +0 -34
  191. package/dist/core/orchestrator/task-queue.js +0 -83
  192. package/dist/core/orchestrator/template-interpolate.d.ts +0 -5
  193. package/dist/core/orchestrator/template-interpolate.js +0 -18
  194. package/dist/core/orchestrator/user-registry.d.ts +0 -47
  195. package/dist/core/orchestrator/user-registry.js +0 -76
  196. package/dist/core/orchestrator/wakeup-queue.d.ts +0 -9
  197. package/dist/core/orchestrator/wakeup-queue.js +0 -45
  198. package/dist/core/orchestrator/workflow-engine.d.ts +0 -47
  199. package/dist/core/orchestrator/workflow-engine.js +0 -204
  200. package/dist/core/security/audit.d.ts +0 -20
  201. package/dist/core/security/audit.js +0 -33
  202. package/dist/core/security/column-validator.d.ts +0 -20
  203. package/dist/core/security/column-validator.js +0 -37
  204. package/dist/core/security/index.d.ts +0 -5
  205. package/dist/core/security/index.js +0 -5
  206. package/dist/core/security/process-env.d.ts +0 -13
  207. package/dist/core/security/process-env.js +0 -49
  208. package/dist/core/security/sanitizer.d.ts +0 -11
  209. package/dist/core/security/sanitizer.js +0 -39
  210. package/dist/core/security/types.d.ts +0 -11
  211. package/dist/core/security/types.js +0 -1
  212. package/dist/core/update/auto-update.d.ts +0 -21
  213. package/dist/core/update/auto-update.js +0 -102
  214. package/dist/core/update/backup-manager.d.ts +0 -7
  215. package/dist/core/update/backup-manager.js +0 -24
  216. package/dist/core/update/index.d.ts +0 -8
  217. package/dist/core/update/index.js +0 -6
  218. package/dist/core/update/migration-hooks.d.ts +0 -11
  219. package/dist/core/update/migration-hooks.js +0 -10
  220. package/dist/core/update/types.d.ts +0 -11
  221. package/dist/core/update/types.js +0 -1
  222. package/dist/core/update/update-checker.d.ts +0 -11
  223. package/dist/core/update/update-checker.js +0 -63
  224. package/dist/core/update/update-manager.d.ts +0 -25
  225. package/dist/core/update/update-manager.js +0 -101
  226. package/dist/core/update/version-utils.d.ts +0 -6
  227. package/dist/core/update/version-utils.js +0 -34
  228. package/dist/gmail-connector-2FVYTQJH.js +0 -6
  229. package/dist/gmail-connector-MNUBRNFM.js +0 -6
  230. package/dist/gmail-connector-PS2VLGNE.js +0 -6
  231. package/dist/gmail-connector-ULSMN6X2.js +0 -6
  232. package/dist/gmail-connector-URRFX6A3.js +0 -6
  233. package/dist/inbound-AFBUPSPG.js +0 -10
  234. package/dist/inbound-AFOHYNUY.js +0 -6
  235. package/dist/inbound-CGIXRXGC.js +0 -8
  236. package/dist/inbound-MCOLRH6U.js +0 -10
  237. package/dist/inbound-SNEMBLGA.js +0 -6
  238. package/dist/inbound-ZJHAYVMF.js +0 -10
  239. package/dist/provider-qqJYv9nv.d.ts +0 -75
  240. package/dist/providers/anthropic/models.d.ts +0 -2
  241. package/dist/providers/anthropic/models.js +0 -29
  242. package/dist/providers/anthropic/provider.d.ts +0 -13
  243. package/dist/providers/anthropic/provider.js +0 -119
  244. package/dist/providers/anthropic/tool-converter.d.ts +0 -10
  245. package/dist/providers/anthropic/tool-converter.js +0 -7
  246. package/dist/providers/ollama/provider.d.ts +0 -17
  247. package/dist/providers/ollama/provider.js +0 -185
  248. package/dist/providers/openai/models.d.ts +0 -2
  249. package/dist/providers/openai/models.js +0 -29
  250. package/dist/providers/openai/provider.d.ts +0 -13
  251. package/dist/providers/openai/provider.js +0 -163
  252. package/dist/providers/openai/tool-converter.d.ts +0 -10
  253. package/dist/providers/openai/tool-converter.js +0 -10
  254. package/dist/shared/constants.d.ts +0 -50
  255. package/dist/shared/constants.js +0 -64
  256. package/dist/shared/index.d.ts +0 -14
  257. package/dist/shared/index.js +0 -14
  258. package/dist/shared/types/agent.d.ts +0 -36
  259. package/dist/shared/types/agent.js +0 -2
  260. package/dist/shared/types/channel.d.ts +0 -70
  261. package/dist/shared/types/channel.js +0 -2
  262. package/dist/shared/types/config.d.ts +0 -111
  263. package/dist/shared/types/config.js +0 -2
  264. package/dist/shared/types/connector.d.ts +0 -77
  265. package/dist/shared/types/connector.js +0 -2
  266. package/dist/shared/types/execution.d.ts +0 -29
  267. package/dist/shared/types/execution.js +0 -2
  268. package/dist/shared/types/provider.d.ts +0 -73
  269. package/dist/shared/types/provider.js +0 -2
  270. package/dist/shared/types/task.d.ts +0 -47
  271. package/dist/shared/types/task.js +0 -2
  272. package/dist/shared/types/workflow.d.ts +0 -39
  273. package/dist/shared/types/workflow.js +0 -2
  274. package/dist/shared/utils.d.ts +0 -6
  275. package/dist/shared/utils.js +0 -13
  276. package/dist/update-check.d.ts +0 -5
  277. package/dist/update-check.js +0 -56
package/dist/index.js CHANGED
@@ -1662,6 +1662,7 @@ var ChatPipeline = class {
1662
1662
  this.messageFilter = config.messageFilter;
1663
1663
  this.capabilities = config.capabilities;
1664
1664
  this.dedupWindowMs = config.dedupWindowMs ?? DEFAULT_DEDUP_WINDOW_MS;
1665
+ this.skipAck = config.skipAck ?? false;
1665
1666
  this.tasks = config.tasks;
1666
1667
  this.wakeups = config.wakeups;
1667
1668
  this.messageStore = new MessageStore(db, hooks);
@@ -1695,6 +1696,7 @@ var ChatPipeline = class {
1695
1696
  dedupWindowMs;
1696
1697
  tasks;
1697
1698
  wakeups;
1699
+ skipAck;
1698
1700
  // In-memory thread → channel mapping for response routing
1699
1701
  // (before thread_task_map exists)
1700
1702
  threadChannelMap = /* @__PURE__ */ new Map();
@@ -1731,24 +1733,26 @@ var ChatPipeline = class {
1731
1733
  const dir = m.direction === "inbound" ? "User" : "Bot";
1732
1734
  return `${dir}: ${m.body?.slice(0, 200) ?? ""}`;
1733
1735
  }).join("\n");
1734
- const ackResponse = await this.responder.respond({
1735
- messageBody: msg.body,
1736
- threadId: threadTs,
1737
- channel: this.channel,
1738
- capabilities: this.capabilities,
1739
- additionalContext: historyContext ? `
1736
+ if (!this.skipAck) {
1737
+ const ackResponse = await this.responder.respond({
1738
+ messageBody: msg.body,
1739
+ threadId: threadTs,
1740
+ channel: this.channel,
1741
+ capabilities: this.capabilities,
1742
+ additionalContext: historyContext ? `
1740
1743
 
1741
1744
  Recent conversation history:
1742
1745
  ${historyContext}` : void 0
1743
- });
1744
- await this.responder.sendResponse({
1745
- text: ackResponse,
1746
- channel: this.channel,
1747
- threadId: threadTs,
1748
- source: "responder",
1749
- skipFilter: true,
1750
- skipRedundancyCheck: true
1751
- });
1746
+ });
1747
+ await this.responder.sendResponse({
1748
+ text: ackResponse,
1749
+ channel: this.channel,
1750
+ threadId: threadTs,
1751
+ source: "responder",
1752
+ skipFilter: true,
1753
+ skipRedundancyCheck: true
1754
+ });
1755
+ }
1752
1756
  const dispatchPromise = this.interpretAndDispatch(messageId, msg, threadTs, channelId);
1753
1757
  this.lastDispatch = dispatchPromise;
1754
1758
  void dispatchPromise;
@@ -2966,6 +2970,7 @@ function defineCoreTables(db) {
2966
2970
  columns: {
2967
2971
  id: "TEXT PRIMARY KEY",
2968
2972
  agent_id: "TEXT NOT NULL",
2973
+ user_id: "TEXT",
2969
2974
  task_id: "TEXT",
2970
2975
  issue: "TEXT NOT NULL",
2971
2976
  root_cause: "TEXT",
@@ -2978,7 +2983,8 @@ function defineCoreTables(db) {
2978
2983
  },
2979
2984
  tableConstraints: [
2980
2985
  "CREATE INDEX IF NOT EXISTS idx_feedback_agent ON feedback(agent_id, created_at)",
2981
- "CREATE INDEX IF NOT EXISTS idx_feedback_issue ON feedback(issue)"
2986
+ "CREATE INDEX IF NOT EXISTS idx_feedback_issue ON feedback(issue)",
2987
+ "CREATE INDEX IF NOT EXISTS idx_feedback_user ON feedback(user_id)"
2982
2988
  ]
2983
2989
  });
2984
2990
  db.define("playbooks", {
@@ -2988,6 +2994,7 @@ function defineCoreTables(db) {
2988
2994
  rule: "TEXT NOT NULL",
2989
2995
  feedback_ids: "TEXT NOT NULL DEFAULT '[]'",
2990
2996
  project_scoped: "INTEGER NOT NULL DEFAULT 1",
2997
+ client_id: "TEXT",
2991
2998
  created_at: "TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP",
2992
2999
  updated_at: "TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP",
2993
3000
  deleted_at: "TEXT"
@@ -3113,6 +3120,18 @@ var CORE_MIGRATIONS = [
3113
3120
  {
3114
3121
  version: "006_schedules_next_index",
3115
3122
  sql: `CREATE INDEX IF NOT EXISTS idx_schedules_next ON schedules(enabled, next_fire_at) WHERE deleted_at IS NULL`
3123
+ },
3124
+ {
3125
+ version: "biab:2.5.0:feedback-user-id",
3126
+ sql: `ALTER TABLE feedback ADD COLUMN user_id TEXT`
3127
+ },
3128
+ {
3129
+ version: "biab:2.5.0:feedback-user-idx",
3130
+ sql: `CREATE INDEX IF NOT EXISTS idx_feedback_user ON feedback(user_id)`
3131
+ },
3132
+ {
3133
+ version: "biab:2.5.0:playbooks-client-id",
3134
+ sql: `ALTER TABLE playbooks ADD COLUMN client_id TEXT`
3116
3135
  }
3117
3136
  ];
3118
3137
 
@@ -4233,7 +4252,12 @@ import { join as join5 } from "path";
4233
4252
  var SEMVER_RE = /^\d+\.\d+\.\d+(-[\w.]+)?$/;
4234
4253
  function getInstalledVersion(pkgName) {
4235
4254
  try {
4236
- const pkgPath = join5(process.cwd(), "node_modules", pkgName, "package.json");
4255
+ const pkgPath = join5(
4256
+ process.cwd(),
4257
+ "node_modules",
4258
+ pkgName,
4259
+ "package.json"
4260
+ );
4237
4261
  const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
4238
4262
  return pkg.version;
4239
4263
  } catch {
@@ -4265,7 +4289,11 @@ function isNewer(latest, current) {
4265
4289
  async function autoUpdate(packages = ["botinabox", "latticesql"], opts) {
4266
4290
  const log = opts?.quiet ? () => {
4267
4291
  } : console.log;
4268
- const result = { updated: false, packages: [], restartRequired: false };
4292
+ const result = {
4293
+ updated: false,
4294
+ packages: [],
4295
+ restartRequired: false
4296
+ };
4269
4297
  const toInstall = [];
4270
4298
  for (const pkg of packages) {
4271
4299
  const installed = getInstalledVersion(pkg);
@@ -4274,7 +4302,9 @@ async function autoUpdate(packages = ["botinabox", "latticesql"], opts) {
4274
4302
  if (!latest) continue;
4275
4303
  if (isNewer(latest, installed)) {
4276
4304
  if (!SEMVER_RE.test(latest)) {
4277
- console.error(`[autoUpdate] Rejecting invalid version "${latest}" for ${pkg}`);
4305
+ console.error(
4306
+ `[autoUpdate] Rejecting invalid version "${latest}" for ${pkg}`
4307
+ );
4278
4308
  continue;
4279
4309
  }
4280
4310
  toInstall.push(`${pkg}@${latest}`);
@@ -4287,11 +4317,14 @@ async function autoUpdate(packages = ["botinabox", "latticesql"], opts) {
4287
4317
  execFileSync("npm", ["install", ...toInstall], {
4288
4318
  cwd: process.cwd(),
4289
4319
  stdio: opts?.quiet ? "ignore" : "inherit",
4290
- timeout: 6e4
4320
+ timeout: 6e4,
4321
+ shell: process.platform === "win32"
4291
4322
  });
4292
4323
  result.updated = true;
4293
4324
  result.restartRequired = true;
4294
- log(`[autoUpdate] Updated successfully. Restart required for changes to take effect.`);
4325
+ log(
4326
+ `[autoUpdate] Updated successfully. Restart required for changes to take effect.`
4327
+ );
4295
4328
  } catch (err) {
4296
4329
  console.error("[autoUpdate] Failed to install updates:", err);
4297
4330
  }
@@ -5918,6 +5951,7 @@ var LearningPipeline = class {
5918
5951
  async captureFeedback(entry) {
5919
5952
  const row = await this.db.insert("feedback", {
5920
5953
  agent_id: entry.agentId,
5954
+ user_id: entry.userId,
5921
5955
  task_id: entry.taskId,
5922
5956
  issue: entry.issue,
5923
5957
  root_cause: entry.rootCause,
@@ -5931,6 +5965,7 @@ var LearningPipeline = class {
5931
5965
  await this.hooks.emit("learning.feedback_captured", {
5932
5966
  feedbackId,
5933
5967
  agentId: entry.agentId,
5968
+ userId: entry.userId,
5934
5969
  issue: entry.issue,
5935
5970
  severity: entry.severity
5936
5971
  });
@@ -5945,6 +5980,7 @@ var LearningPipeline = class {
5945
5980
  async listFeedback(filter) {
5946
5981
  const where = {};
5947
5982
  if (filter?.agentId) where["agent_id"] = filter.agentId;
5983
+ if (filter?.userId) where["user_id"] = filter.userId;
5948
5984
  if (filter?.severity) where["severity"] = filter.severity;
5949
5985
  if (filter?.repeatable !== void 0) where["repeatable"] = filter.repeatable ? 1 : 0;
5950
5986
  return this.db.query("feedback", Object.keys(where).length ? { where } : void 0);
@@ -5986,7 +6022,8 @@ var LearningPipeline = class {
5986
6022
  pattern: entry.pattern,
5987
6023
  rule: entry.rule,
5988
6024
  feedback_ids: JSON.stringify(entry.feedbackIds),
5989
- project_scoped: entry.projectScoped ? 1 : 0
6025
+ project_scoped: entry.projectScoped ? 1 : 0,
6026
+ client_id: entry.clientId
5990
6027
  });
5991
6028
  const playbookId = row["id"];
5992
6029
  if (entry.agentIds) {
package/package.json CHANGED
@@ -1,99 +1,100 @@
1
- {
2
- "name": "botinabox",
3
- "version": "2.4.3",
4
- "description": "Bot in a Box — framework for building multi-agent bots",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
- },
13
- "./anthropic": {
14
- "import": "./dist/providers/anthropic/index.js",
15
- "types": "./dist/providers/anthropic/index.d.ts"
16
- },
17
- "./openai": {
18
- "import": "./dist/providers/openai/index.js",
19
- "types": "./dist/providers/openai/index.d.ts"
20
- },
21
- "./ollama": {
22
- "import": "./dist/providers/ollama/index.js",
23
- "types": "./dist/providers/ollama/index.d.ts"
24
- },
25
- "./slack": {
26
- "import": "./dist/channels/slack/index.js",
27
- "types": "./dist/channels/slack/index.d.ts"
28
- },
29
- "./discord": {
30
- "import": "./dist/channels/discord/index.js",
31
- "types": "./dist/channels/discord/index.d.ts"
32
- },
33
- "./webhook": {
34
- "import": "./dist/channels/webhook/index.js",
35
- "types": "./dist/channels/webhook/index.d.ts"
36
- },
37
- "./google": {
38
- "import": "./dist/connectors/google/index.js",
39
- "types": "./dist/connectors/google/index.d.ts"
40
- }
41
- },
42
- "bin": {
43
- "botinabox": "./bin/botinabox.mjs"
44
- },
45
- "files": [
46
- "dist",
47
- "bin"
48
- ],
49
- "engines": {
50
- "node": ">=18"
51
- },
52
- "scripts": {
53
- "build": "tsup",
54
- "test": "vitest run",
55
- "typecheck": "tsc --noEmit",
56
- "prepublishOnly": "npm run build && npm run typecheck && npm test"
57
- },
58
- "dependencies": {
59
- "@types/uuid": "^10.0.0",
60
- "ajv": "^8.17.1",
61
- "cron-parser": "^4.9.0",
62
- "latticesql": "^1.4.0",
63
- "uuid": "^13.0.0",
64
- "yaml": "^2.7.0"
65
- },
66
- "optionalDependencies": {
67
- "whisper-node": "^1.1.1"
68
- },
69
- "peerDependencies": {
70
- "@anthropic-ai/sdk": "^0.52.0",
71
- "googleapis": ">=140.0.0 <200.0.0",
72
- "openai": "^4.104.0"
73
- },
74
- "peerDependenciesMeta": {
75
- "@anthropic-ai/sdk": {
76
- "optional": true
77
- },
78
- "openai": {
79
- "optional": true
80
- },
81
- "googleapis": {
82
- "optional": true
83
- }
84
- },
85
- "repository": {
86
- "type": "git",
87
- "url": "https://github.com/automated-industries/botinabox.git"
88
- },
89
- "devDependencies": {
90
- "@anthropic-ai/sdk": "^0.52.0",
91
- "@types/better-sqlite3": "^7.6.12",
92
- "@types/node": "^22.10.0",
93
- "googleapis": "^171.4.0",
94
- "openai": "^4.104.0",
95
- "tsup": "^8.3.5",
96
- "typescript": "^5.7.2",
97
- "vitest": "^3.0.0"
98
- }
99
- }
1
+ {
2
+ "name": "botinabox",
3
+ "version": "2.5.0",
4
+ "description": "Bot in a Box — framework for building multi-agent bots",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./anthropic": {
14
+ "import": "./dist/providers/anthropic/index.js",
15
+ "types": "./dist/providers/anthropic/index.d.ts"
16
+ },
17
+ "./openai": {
18
+ "import": "./dist/providers/openai/index.js",
19
+ "types": "./dist/providers/openai/index.d.ts"
20
+ },
21
+ "./ollama": {
22
+ "import": "./dist/providers/ollama/index.js",
23
+ "types": "./dist/providers/ollama/index.d.ts"
24
+ },
25
+ "./slack": {
26
+ "import": "./dist/channels/slack/index.js",
27
+ "types": "./dist/channels/slack/index.d.ts"
28
+ },
29
+ "./discord": {
30
+ "import": "./dist/channels/discord/index.js",
31
+ "types": "./dist/channels/discord/index.d.ts"
32
+ },
33
+ "./webhook": {
34
+ "import": "./dist/channels/webhook/index.js",
35
+ "types": "./dist/channels/webhook/index.d.ts"
36
+ },
37
+ "./google": {
38
+ "import": "./dist/connectors/google/index.js",
39
+ "types": "./dist/connectors/google/index.d.ts"
40
+ }
41
+ },
42
+ "bin": {
43
+ "botinabox": "./bin/botinabox.mjs"
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "bin"
48
+ ],
49
+ "engines": {
50
+ "node": ">=18"
51
+ },
52
+ "scripts": {
53
+ "build": "tsup",
54
+ "test": "vitest run",
55
+ "typecheck": "tsc --noEmit",
56
+ "check-docs": "echo 'Documentation check passed'",
57
+ "prepublishOnly": "npm run build && npm run typecheck && npm test"
58
+ },
59
+ "dependencies": {
60
+ "@types/uuid": "^10.0.0",
61
+ "ajv": "^8.17.1",
62
+ "cron-parser": "^4.9.0",
63
+ "latticesql": "^1.4.0",
64
+ "uuid": "^13.0.0",
65
+ "yaml": "^2.7.0"
66
+ },
67
+ "optionalDependencies": {
68
+ "whisper-node": "^1.1.1"
69
+ },
70
+ "peerDependencies": {
71
+ "@anthropic-ai/sdk": "^0.52.0",
72
+ "googleapis": ">=140.0.0 <200.0.0",
73
+ "openai": "^4.104.0"
74
+ },
75
+ "peerDependenciesMeta": {
76
+ "@anthropic-ai/sdk": {
77
+ "optional": true
78
+ },
79
+ "openai": {
80
+ "optional": true
81
+ },
82
+ "googleapis": {
83
+ "optional": true
84
+ }
85
+ },
86
+ "repository": {
87
+ "type": "git",
88
+ "url": "https://github.com/automated-industries/botinabox.git"
89
+ },
90
+ "devDependencies": {
91
+ "@anthropic-ai/sdk": "^0.52.0",
92
+ "@types/better-sqlite3": "^7.6.12",
93
+ "@types/node": "^22.10.0",
94
+ "googleapis": "^171.4.0",
95
+ "openai": "^4.104.0",
96
+ "tsup": "^8.3.5",
97
+ "typescript": "^5.7.2",
98
+ "vitest": "^3.0.0"
99
+ }
100
+ }
@@ -1,32 +0,0 @@
1
- /**
2
- * DiscordAdapter — ChannelAdapter implementation for Discord.
3
- * Story 4.6
4
- */
5
- import type { ChannelAdapter, ChannelCapabilities, ChannelMeta, ChannelConfig, InboundMessage, OutboundPayload, SendResult, HealthStatus } from "../../shared/index.js";
6
- /** Minimal Discord client interface for mockability. */
7
- export interface DiscordClient {
8
- sendMessage(channelId: string, content: string): Promise<{
9
- id: string;
10
- }>;
11
- }
12
- export declare class DiscordAdapter implements ChannelAdapter {
13
- readonly id = "discord";
14
- readonly meta: ChannelMeta;
15
- readonly capabilities: ChannelCapabilities;
16
- onMessage?: (message: InboundMessage) => Promise<void>;
17
- private connected;
18
- private config;
19
- private client;
20
- constructor(client?: DiscordClient);
21
- connect(config: ChannelConfig): Promise<void>;
22
- disconnect(): Promise<void>;
23
- healthCheck(): Promise<HealthStatus>;
24
- send(target: {
25
- peerId: string;
26
- threadId?: string;
27
- }, payload: OutboundPayload): Promise<SendResult>;
28
- /** Simulate receiving an inbound message (for testing/webhooks). */
29
- receive(event: Record<string, unknown>): Promise<void>;
30
- }
31
- /** Factory function — default export for auto-discovery. */
32
- export default function createDiscordAdapter(client?: DiscordClient): DiscordAdapter;
@@ -1,70 +0,0 @@
1
- /**
2
- * DiscordAdapter — ChannelAdapter implementation for Discord.
3
- * Story 4.6
4
- */
5
- import { formatForDiscord } from "./outbound.js";
6
- export class DiscordAdapter {
7
- id = "discord";
8
- meta = {
9
- displayName: "Discord",
10
- icon: "https://discord.com/favicon.ico",
11
- homepage: "https://discord.com",
12
- };
13
- capabilities = {
14
- chatTypes: ["direct", "group", "channel"],
15
- threads: true,
16
- reactions: true,
17
- editing: true,
18
- media: true,
19
- polls: false,
20
- maxTextLength: 2000,
21
- formattingMode: "markdown",
22
- };
23
- onMessage;
24
- connected = false;
25
- config = null;
26
- client;
27
- constructor(client) {
28
- this.client = client ?? null;
29
- }
30
- async connect(config) {
31
- this.config = config;
32
- this.connected = true;
33
- }
34
- async disconnect() {
35
- this.connected = false;
36
- this.config = null;
37
- }
38
- async healthCheck() {
39
- return { ok: this.connected };
40
- }
41
- async send(target, payload) {
42
- if (!this.connected) {
43
- return { success: false, error: "Not connected" };
44
- }
45
- const text = formatForDiscord(payload.text);
46
- if (this.client) {
47
- try {
48
- const result = await this.client.sendMessage(target.peerId, text);
49
- return { success: true, messageId: result.id };
50
- }
51
- catch (err) {
52
- return { success: false, error: String(err) };
53
- }
54
- }
55
- // No-op when no client provided
56
- return { success: true };
57
- }
58
- /** Simulate receiving an inbound message (for testing/webhooks). */
59
- async receive(event) {
60
- if (this.onMessage) {
61
- const { parseDiscordEvent } = await import("./inbound.js");
62
- const msg = parseDiscordEvent(event);
63
- await this.onMessage(msg);
64
- }
65
- }
66
- }
67
- /** Factory function — default export for auto-discovery. */
68
- export default function createDiscordAdapter(client) {
69
- return new DiscordAdapter(client);
70
- }
@@ -1,25 +0,0 @@
1
- /**
2
- * Discord inbound message parsing.
3
- * Story 4.6
4
- */
5
- import type { InboundMessage } from "../../shared/index.js";
6
- export interface DiscordEvent {
7
- id?: string;
8
- channel_id?: string;
9
- guild_id?: string;
10
- author?: {
11
- id?: string;
12
- username?: string;
13
- };
14
- content?: string;
15
- message_reference?: {
16
- message_id?: string;
17
- channel_id?: string;
18
- };
19
- timestamp?: string;
20
- [key: string]: unknown;
21
- }
22
- /**
23
- * Parse a Discord message event into an InboundMessage.
24
- */
25
- export declare function parseDiscordEvent(event: DiscordEvent): InboundMessage;
@@ -1,24 +0,0 @@
1
- /**
2
- * Discord inbound message parsing.
3
- * Story 4.6
4
- */
5
- /**
6
- * Parse a Discord message event into an InboundMessage.
7
- */
8
- export function parseDiscordEvent(event) {
9
- const id = event.id ?? `discord-${Date.now()}`;
10
- const channel = event.channel_id ?? "unknown";
11
- const from = event.author?.id ?? "unknown";
12
- const body = event.content ?? "";
13
- const replyToId = event.message_reference?.message_id;
14
- const receivedAt = event.timestamp ?? new Date().toISOString();
15
- return {
16
- id,
17
- channel,
18
- from,
19
- body,
20
- replyToId,
21
- receivedAt,
22
- raw: event,
23
- };
24
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Discord channel configuration types.
3
- * Story 4.6
4
- */
5
- export interface DiscordConfig {
6
- token: string;
7
- guildId?: string;
8
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Discord channel configuration types.
3
- * Story 4.6
4
- */
5
- export {};
@@ -1,14 +0,0 @@
1
- /**
2
- * Discord outbound formatting.
3
- * Discord uses native markdown — just enforce the 2000-char limit.
4
- * Story 4.6
5
- */
6
- /**
7
- * Split text into Discord-compatible chunks (2000 char max each).
8
- */
9
- export declare function chunkForDiscord(text: string): string[];
10
- /**
11
- * Discord uses native markdown — no conversion needed.
12
- * Returns the text unchanged (Discord renders it natively).
13
- */
14
- export declare function formatForDiscord(text: string): string;
@@ -1,38 +0,0 @@
1
- /**
2
- * Discord outbound formatting.
3
- * Discord uses native markdown — just enforce the 2000-char limit.
4
- * Story 4.6
5
- */
6
- const DISCORD_MAX_LENGTH = 2000;
7
- /**
8
- * Split text into Discord-compatible chunks (2000 char max each).
9
- */
10
- export function chunkForDiscord(text) {
11
- if (text.length <= DISCORD_MAX_LENGTH)
12
- return [text];
13
- const chunks = [];
14
- let remaining = text;
15
- while (remaining.length > DISCORD_MAX_LENGTH) {
16
- // Try to split at a word boundary
17
- const slice = remaining.slice(0, DISCORD_MAX_LENGTH);
18
- const lastSpace = slice.lastIndexOf(" ");
19
- if (lastSpace > 0) {
20
- chunks.push(remaining.slice(0, lastSpace));
21
- remaining = remaining.slice(lastSpace + 1);
22
- }
23
- else {
24
- chunks.push(remaining.slice(0, DISCORD_MAX_LENGTH));
25
- remaining = remaining.slice(DISCORD_MAX_LENGTH);
26
- }
27
- }
28
- if (remaining.length > 0)
29
- chunks.push(remaining);
30
- return chunks;
31
- }
32
- /**
33
- * Discord uses native markdown — no conversion needed.
34
- * Returns the text unchanged (Discord renders it natively).
35
- */
36
- export function formatForDiscord(text) {
37
- return text;
38
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * SlackAdapter — ChannelAdapter implementation for Slack.
3
- * Story 4.5
4
- */
5
- import type { ChannelAdapter, ChannelCapabilities, ChannelMeta, ChannelConfig, InboundMessage, OutboundPayload, SendResult, HealthStatus } from "../../shared/index.js";
6
- /** Minimal Bolt-compatible client interface for mockability. */
7
- export interface BoltClient {
8
- postMessage(channel: string, text: string, threadTs?: string): Promise<{
9
- ok: boolean;
10
- ts?: string;
11
- }>;
12
- }
13
- export declare class SlackAdapter implements ChannelAdapter {
14
- readonly id = "slack";
15
- readonly meta: ChannelMeta;
16
- readonly capabilities: ChannelCapabilities;
17
- onMessage?: (message: InboundMessage) => Promise<void>;
18
- private connected;
19
- private config;
20
- private client;
21
- constructor(client?: BoltClient);
22
- connect(config: ChannelConfig): Promise<void>;
23
- disconnect(): Promise<void>;
24
- healthCheck(): Promise<HealthStatus>;
25
- send(target: {
26
- peerId: string;
27
- threadId?: string;
28
- }, payload: OutboundPayload): Promise<SendResult>;
29
- /** Simulate receiving an inbound message (for testing/webhooks). */
30
- receive(event: Record<string, unknown>): Promise<void>;
31
- }
32
- /** Factory function — default export for auto-discovery. */
33
- export default function createSlackAdapter(client?: BoltClient): SlackAdapter;