botinabox 2.4.3 → 2.5.1

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 (276) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +190 -190
  3. package/bin/botinabox.mjs +1 -1
  4. package/dist/cli.js +0 -0
  5. package/dist/connectors/google/index.d.ts +67 -1
  6. package/dist/connectors/google/index.js +240 -0
  7. package/dist/index.js +19 -5
  8. package/package.json +100 -99
  9. package/dist/channels/discord/adapter.d.ts +0 -32
  10. package/dist/channels/discord/adapter.js +0 -70
  11. package/dist/channels/discord/inbound.d.ts +0 -25
  12. package/dist/channels/discord/inbound.js +0 -24
  13. package/dist/channels/discord/models.d.ts +0 -8
  14. package/dist/channels/discord/models.js +0 -5
  15. package/dist/channels/discord/outbound.d.ts +0 -14
  16. package/dist/channels/discord/outbound.js +0 -38
  17. package/dist/channels/slack/adapter.d.ts +0 -33
  18. package/dist/channels/slack/adapter.js +0 -74
  19. package/dist/channels/slack/inbound.d.ts +0 -59
  20. package/dist/channels/slack/inbound.js +0 -96
  21. package/dist/channels/slack/models.d.ts +0 -9
  22. package/dist/channels/slack/models.js +0 -5
  23. package/dist/channels/slack/outbound.d.ts +0 -12
  24. package/dist/channels/slack/outbound.js +0 -18
  25. package/dist/channels/slack/transcribe.d.ts +0 -41
  26. package/dist/channels/slack/transcribe.js +0 -106
  27. package/dist/channels/webhook/adapter.d.ts +0 -23
  28. package/dist/channels/webhook/adapter.js +0 -86
  29. package/dist/channels/webhook/hmac.d.ts +0 -13
  30. package/dist/channels/webhook/hmac.js +0 -26
  31. package/dist/channels/webhook/models.d.ts +0 -9
  32. package/dist/channels/webhook/models.js +0 -5
  33. package/dist/channels/webhook/server.d.ts +0 -20
  34. package/dist/channels/webhook/server.js +0 -91
  35. package/dist/chat-pipeline-C-XlLGNl.d.ts +0 -648
  36. package/dist/chat-pipeline-CR1KF6eX.d.ts +0 -652
  37. package/dist/chat-pipeline-DisuC8SB.d.ts +0 -643
  38. package/dist/chunk-2LGXQPEA.js +0 -41
  39. package/dist/chunk-3X3YKI4T.js +0 -357
  40. package/dist/chunk-D47AIFOD.js +0 -351
  41. package/dist/chunk-DSNJKNEW.js +0 -328
  42. package/dist/chunk-GS2JFL6I.js +0 -144
  43. package/dist/chunk-J6S6QMUY.js +0 -144
  44. package/dist/chunk-QLA6YOFN.js +0 -22
  45. package/dist/chunk-UACT2WXX.js +0 -381
  46. package/dist/cli/templates/config.yml.d.ts +0 -7
  47. package/dist/cli/templates/config.yml.js +0 -61
  48. package/dist/cli/templates/env.d.ts +0 -1
  49. package/dist/cli/templates/env.js +0 -30
  50. package/dist/cli/templates/index.ts.d.ts +0 -2
  51. package/dist/cli/templates/index.ts.js +0 -30
  52. package/dist/cli/templates/package.json.d.ts +0 -5
  53. package/dist/cli/templates/package.json.js +0 -28
  54. package/dist/connector-DDahQw-2.d.ts +0 -63
  55. package/dist/connectors/google/calendar-connector.d.ts +0 -40
  56. package/dist/connectors/google/calendar-connector.js +0 -243
  57. package/dist/connectors/google/gmail-connector.d.ts +0 -42
  58. package/dist/connectors/google/gmail-connector.js +0 -345
  59. package/dist/connectors/google/oauth.d.ts +0 -48
  60. package/dist/connectors/google/oauth.js +0 -112
  61. package/dist/connectors/google/types.d.ts +0 -78
  62. package/dist/connectors/google/types.js +0 -2
  63. package/dist/core/chat/auto-discovery.d.ts +0 -16
  64. package/dist/core/chat/auto-discovery.js +0 -54
  65. package/dist/core/chat/channel-registry.d.ts +0 -45
  66. package/dist/core/chat/channel-registry.js +0 -96
  67. package/dist/core/chat/chat-pipeline.d.ts +0 -113
  68. package/dist/core/chat/chat-pipeline.js +0 -395
  69. package/dist/core/chat/chat-responder.d.ts +0 -90
  70. package/dist/core/chat/chat-responder.js +0 -185
  71. package/dist/core/chat/formatter.d.ts +0 -11
  72. package/dist/core/chat/formatter.js +0 -60
  73. package/dist/core/chat/index.d.ts +0 -24
  74. package/dist/core/chat/index.js +0 -18
  75. package/dist/core/chat/message-interpreter.d.ts +0 -91
  76. package/dist/core/chat/message-interpreter.js +0 -166
  77. package/dist/core/chat/message-store.d.ts +0 -66
  78. package/dist/core/chat/message-store.js +0 -131
  79. package/dist/core/chat/notification-queue.d.ts +0 -34
  80. package/dist/core/chat/notification-queue.js +0 -111
  81. package/dist/core/chat/pipeline.d.ts +0 -38
  82. package/dist/core/chat/pipeline.js +0 -89
  83. package/dist/core/chat/policies.d.ts +0 -16
  84. package/dist/core/chat/policies.js +0 -25
  85. package/dist/core/chat/routing.d.ts +0 -17
  86. package/dist/core/chat/routing.js +0 -36
  87. package/dist/core/chat/session-key.d.ts +0 -30
  88. package/dist/core/chat/session-key.js +0 -65
  89. package/dist/core/chat/session-manager.d.ts +0 -17
  90. package/dist/core/chat/session-manager.js +0 -23
  91. package/dist/core/chat/text-chunker.d.ts +0 -9
  92. package/dist/core/chat/text-chunker.js +0 -48
  93. package/dist/core/chat/triage-router.d.ts +0 -75
  94. package/dist/core/chat/triage-router.js +0 -142
  95. package/dist/core/chat/types.d.ts +0 -5
  96. package/dist/core/chat/types.js +0 -5
  97. package/dist/core/config/defaults.d.ts +0 -2
  98. package/dist/core/config/defaults.js +0 -38
  99. package/dist/core/config/index.d.ts +0 -6
  100. package/dist/core/config/index.js +0 -4
  101. package/dist/core/config/interpolate.d.ts +0 -5
  102. package/dist/core/config/interpolate.js +0 -27
  103. package/dist/core/config/loader.d.ts +0 -24
  104. package/dist/core/config/loader.js +0 -59
  105. package/dist/core/config/schema.d.ts +0 -5
  106. package/dist/core/config/schema.js +0 -119
  107. package/dist/core/data/core-entity-contexts.d.ts +0 -14
  108. package/dist/core/data/core-entity-contexts.js +0 -197
  109. package/dist/core/data/core-migrations.d.ts +0 -5
  110. package/dist/core/data/core-migrations.js +0 -45
  111. package/dist/core/data/core-schema.d.ts +0 -6
  112. package/dist/core/data/core-schema.js +0 -454
  113. package/dist/core/data/data-store.d.ts +0 -67
  114. package/dist/core/data/data-store.js +0 -218
  115. package/dist/core/data/domain-entity-contexts.d.ts +0 -29
  116. package/dist/core/data/domain-entity-contexts.js +0 -321
  117. package/dist/core/data/domain-schema.d.ts +0 -36
  118. package/dist/core/data/domain-schema.js +0 -323
  119. package/dist/core/data/index.d.ts +0 -7
  120. package/dist/core/data/index.js +0 -7
  121. package/dist/core/data/types.d.ts +0 -111
  122. package/dist/core/data/types.js +0 -1
  123. package/dist/core/hooks/hook-bus.d.ts +0 -18
  124. package/dist/core/hooks/hook-bus.js +0 -120
  125. package/dist/core/hooks/index.d.ts +0 -2
  126. package/dist/core/hooks/index.js +0 -1
  127. package/dist/core/hooks/types.d.ts +0 -19
  128. package/dist/core/hooks/types.js +0 -1
  129. package/dist/core/index.d.ts +0 -4
  130. package/dist/core/index.js +0 -4
  131. package/dist/core/llm/auto-discovery.d.ts +0 -11
  132. package/dist/core/llm/auto-discovery.js +0 -49
  133. package/dist/core/llm/cost-tracker.d.ts +0 -6
  134. package/dist/core/llm/cost-tracker.js +0 -38
  135. package/dist/core/llm/index.d.ts +0 -4
  136. package/dist/core/llm/index.js +0 -3
  137. package/dist/core/llm/model-router.d.ts +0 -25
  138. package/dist/core/llm/model-router.js +0 -49
  139. package/dist/core/llm/provider-registry.d.ts +0 -9
  140. package/dist/core/llm/provider-registry.js +0 -25
  141. package/dist/core/llm/types.d.ts +0 -2
  142. package/dist/core/llm/types.js +0 -2
  143. package/dist/core/orchestrator/adapters/api-adapter.d.ts +0 -34
  144. package/dist/core/orchestrator/adapters/api-adapter.js +0 -88
  145. package/dist/core/orchestrator/adapters/cli-adapter.d.ts +0 -22
  146. package/dist/core/orchestrator/adapters/cli-adapter.js +0 -69
  147. package/dist/core/orchestrator/adapters/deterministic-adapter.d.ts +0 -35
  148. package/dist/core/orchestrator/adapters/deterministic-adapter.js +0 -75
  149. package/dist/core/orchestrator/adapters/env-whitelist.d.ts +0 -4
  150. package/dist/core/orchestrator/adapters/env-whitelist.js +0 -27
  151. package/dist/core/orchestrator/adapters/output-extractor.d.ts +0 -11
  152. package/dist/core/orchestrator/adapters/output-extractor.js +0 -59
  153. package/dist/core/orchestrator/adapters/process-manager.d.ts +0 -15
  154. package/dist/core/orchestrator/adapters/process-manager.js +0 -26
  155. package/dist/core/orchestrator/adapters/tool-loop.d.ts +0 -22
  156. package/dist/core/orchestrator/adapters/tool-loop.js +0 -66
  157. package/dist/core/orchestrator/agent-registry.d.ts +0 -31
  158. package/dist/core/orchestrator/agent-registry.js +0 -135
  159. package/dist/core/orchestrator/budget-controller.d.ts +0 -19
  160. package/dist/core/orchestrator/budget-controller.js +0 -73
  161. package/dist/core/orchestrator/chain-guard.d.ts +0 -14
  162. package/dist/core/orchestrator/chain-guard.js +0 -23
  163. package/dist/core/orchestrator/circuit-breaker.d.ts +0 -65
  164. package/dist/core/orchestrator/circuit-breaker.js +0 -159
  165. package/dist/core/orchestrator/claude-stream-parser.d.ts +0 -31
  166. package/dist/core/orchestrator/claude-stream-parser.js +0 -99
  167. package/dist/core/orchestrator/config-revisions.d.ts +0 -6
  168. package/dist/core/orchestrator/config-revisions.js +0 -17
  169. package/dist/core/orchestrator/dependency-resolver.d.ts +0 -20
  170. package/dist/core/orchestrator/dependency-resolver.js +0 -78
  171. package/dist/core/orchestrator/governance-gate.d.ts +0 -110
  172. package/dist/core/orchestrator/governance-gate.js +0 -170
  173. package/dist/core/orchestrator/learning-pipeline.d.ts +0 -109
  174. package/dist/core/orchestrator/learning-pipeline.js +0 -249
  175. package/dist/core/orchestrator/loop-detector.d.ts +0 -51
  176. package/dist/core/orchestrator/loop-detector.js +0 -133
  177. package/dist/core/orchestrator/ndjson-logger.d.ts +0 -6
  178. package/dist/core/orchestrator/ndjson-logger.js +0 -18
  179. package/dist/core/orchestrator/permission-relay.d.ts +0 -72
  180. package/dist/core/orchestrator/permission-relay.js +0 -164
  181. package/dist/core/orchestrator/run-manager.d.ts +0 -31
  182. package/dist/core/orchestrator/run-manager.js +0 -178
  183. package/dist/core/orchestrator/scheduler.d.ts +0 -70
  184. package/dist/core/orchestrator/scheduler.js +0 -198
  185. package/dist/core/orchestrator/secret-store.d.ts +0 -57
  186. package/dist/core/orchestrator/secret-store.js +0 -171
  187. package/dist/core/orchestrator/session-manager.d.ts +0 -13
  188. package/dist/core/orchestrator/session-manager.js +0 -66
  189. package/dist/core/orchestrator/task-queue.d.ts +0 -34
  190. package/dist/core/orchestrator/task-queue.js +0 -83
  191. package/dist/core/orchestrator/template-interpolate.d.ts +0 -5
  192. package/dist/core/orchestrator/template-interpolate.js +0 -18
  193. package/dist/core/orchestrator/user-registry.d.ts +0 -47
  194. package/dist/core/orchestrator/user-registry.js +0 -76
  195. package/dist/core/orchestrator/wakeup-queue.d.ts +0 -9
  196. package/dist/core/orchestrator/wakeup-queue.js +0 -45
  197. package/dist/core/orchestrator/workflow-engine.d.ts +0 -47
  198. package/dist/core/orchestrator/workflow-engine.js +0 -204
  199. package/dist/core/security/audit.d.ts +0 -20
  200. package/dist/core/security/audit.js +0 -33
  201. package/dist/core/security/column-validator.d.ts +0 -20
  202. package/dist/core/security/column-validator.js +0 -37
  203. package/dist/core/security/index.d.ts +0 -5
  204. package/dist/core/security/index.js +0 -5
  205. package/dist/core/security/process-env.d.ts +0 -13
  206. package/dist/core/security/process-env.js +0 -49
  207. package/dist/core/security/sanitizer.d.ts +0 -11
  208. package/dist/core/security/sanitizer.js +0 -39
  209. package/dist/core/security/types.d.ts +0 -11
  210. package/dist/core/security/types.js +0 -1
  211. package/dist/core/update/auto-update.d.ts +0 -21
  212. package/dist/core/update/auto-update.js +0 -102
  213. package/dist/core/update/backup-manager.d.ts +0 -7
  214. package/dist/core/update/backup-manager.js +0 -24
  215. package/dist/core/update/index.d.ts +0 -8
  216. package/dist/core/update/index.js +0 -6
  217. package/dist/core/update/migration-hooks.d.ts +0 -11
  218. package/dist/core/update/migration-hooks.js +0 -10
  219. package/dist/core/update/types.d.ts +0 -11
  220. package/dist/core/update/types.js +0 -1
  221. package/dist/core/update/update-checker.d.ts +0 -11
  222. package/dist/core/update/update-checker.js +0 -63
  223. package/dist/core/update/update-manager.d.ts +0 -25
  224. package/dist/core/update/update-manager.js +0 -101
  225. package/dist/core/update/version-utils.d.ts +0 -6
  226. package/dist/core/update/version-utils.js +0 -34
  227. package/dist/gmail-connector-2FVYTQJH.js +0 -6
  228. package/dist/gmail-connector-MNUBRNFM.js +0 -6
  229. package/dist/gmail-connector-PS2VLGNE.js +0 -6
  230. package/dist/gmail-connector-ULSMN6X2.js +0 -6
  231. package/dist/gmail-connector-URRFX6A3.js +0 -6
  232. package/dist/inbound-AFBUPSPG.js +0 -10
  233. package/dist/inbound-AFOHYNUY.js +0 -6
  234. package/dist/inbound-CGIXRXGC.js +0 -8
  235. package/dist/inbound-MCOLRH6U.js +0 -10
  236. package/dist/inbound-SNEMBLGA.js +0 -6
  237. package/dist/inbound-ZJHAYVMF.js +0 -10
  238. package/dist/provider-qqJYv9nv.d.ts +0 -75
  239. package/dist/providers/anthropic/models.d.ts +0 -2
  240. package/dist/providers/anthropic/models.js +0 -29
  241. package/dist/providers/anthropic/provider.d.ts +0 -13
  242. package/dist/providers/anthropic/provider.js +0 -119
  243. package/dist/providers/anthropic/tool-converter.d.ts +0 -10
  244. package/dist/providers/anthropic/tool-converter.js +0 -7
  245. package/dist/providers/ollama/provider.d.ts +0 -17
  246. package/dist/providers/ollama/provider.js +0 -185
  247. package/dist/providers/openai/models.d.ts +0 -2
  248. package/dist/providers/openai/models.js +0 -29
  249. package/dist/providers/openai/provider.d.ts +0 -13
  250. package/dist/providers/openai/provider.js +0 -163
  251. package/dist/providers/openai/tool-converter.d.ts +0 -10
  252. package/dist/providers/openai/tool-converter.js +0 -10
  253. package/dist/shared/constants.d.ts +0 -50
  254. package/dist/shared/constants.js +0 -64
  255. package/dist/shared/index.d.ts +0 -14
  256. package/dist/shared/index.js +0 -14
  257. package/dist/shared/types/agent.d.ts +0 -36
  258. package/dist/shared/types/agent.js +0 -2
  259. package/dist/shared/types/channel.d.ts +0 -70
  260. package/dist/shared/types/channel.js +0 -2
  261. package/dist/shared/types/config.d.ts +0 -111
  262. package/dist/shared/types/config.js +0 -2
  263. package/dist/shared/types/connector.d.ts +0 -77
  264. package/dist/shared/types/connector.js +0 -2
  265. package/dist/shared/types/execution.d.ts +0 -29
  266. package/dist/shared/types/execution.js +0 -2
  267. package/dist/shared/types/provider.d.ts +0 -73
  268. package/dist/shared/types/provider.js +0 -2
  269. package/dist/shared/types/task.d.ts +0 -47
  270. package/dist/shared/types/task.js +0 -2
  271. package/dist/shared/types/workflow.d.ts +0 -39
  272. package/dist/shared/types/workflow.js +0 -2
  273. package/dist/shared/utils.d.ts +0 -6
  274. package/dist/shared/utils.js +0 -13
  275. package/dist/update-check.d.ts +0 -5
  276. package/dist/update-check.js +0 -56
@@ -1,171 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- import { scryptSync, createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
3
- const ENC_PREFIX = "enc:";
4
- const ALGORITHM = "aes-256-gcm";
5
- const IV_LEN = 12;
6
- const TAG_LEN = 16;
7
- function deriveEncKey(masterKey) {
8
- return scryptSync(masterKey, "botinabox-secrets-v1", 32);
9
- }
10
- function encryptValue(plaintext, key) {
11
- const iv = randomBytes(IV_LEN);
12
- const cipher = createCipheriv(ALGORITHM, key, iv);
13
- const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
14
- const tag = cipher.getAuthTag();
15
- return ENC_PREFIX + Buffer.concat([iv, tag, encrypted]).toString("base64");
16
- }
17
- function decryptValue(ciphertext, key) {
18
- if (!ciphertext.startsWith(ENC_PREFIX))
19
- return ciphertext; // plaintext passthrough for migration
20
- const buf = Buffer.from(ciphertext.slice(ENC_PREFIX.length), "base64");
21
- const iv = buf.subarray(0, IV_LEN);
22
- const tag = buf.subarray(IV_LEN, IV_LEN + TAG_LEN);
23
- const data = buf.subarray(IV_LEN + TAG_LEN);
24
- const decipher = createDecipheriv(ALGORITHM, key, iv);
25
- decipher.setAuthTag(tag);
26
- return decipher.update(data).toString("utf8") + decipher.final("utf8");
27
- }
28
- export class SecretStore {
29
- db;
30
- hooks;
31
- encKey;
32
- /**
33
- * @param db - DataStore instance
34
- * @param hooks - HookBus instance
35
- * @param encryptionKey - Optional master key for encrypting secrets at rest.
36
- * When provided, all new secrets are encrypted with AES-256-GCM.
37
- * Existing plaintext secrets are read transparently (passthrough on decrypt).
38
- */
39
- constructor(db, hooks, encryptionKey) {
40
- this.db = db;
41
- this.hooks = hooks;
42
- this.encKey = encryptionKey ? deriveEncKey(encryptionKey) : null;
43
- }
44
- async set(input) {
45
- const id = uuidv4();
46
- const data = { ...input, id };
47
- if (this.encKey && data.value) {
48
- data.value = encryptValue(data.value, this.encKey);
49
- }
50
- await this.db.insert("secrets", data);
51
- await this.hooks.emit("secret.created", { name: input.name });
52
- const inserted = await this.db.get("secrets", id);
53
- return this._toMeta(inserted);
54
- }
55
- async get(name, environment = "production") {
56
- const rows = await this.db.query("secrets", {
57
- where: { name, environment },
58
- filters: [{ col: "deleted_at", op: "isNull" }],
59
- limit: 1,
60
- });
61
- if (rows.length === 0)
62
- return null;
63
- await this.hooks.emit("secret.accessed", { name, environment });
64
- const raw = rows[0].value ?? null;
65
- if (raw && this.encKey)
66
- return decryptValue(raw, this.encKey);
67
- return raw;
68
- }
69
- async getMeta(name, environment = "production") {
70
- const rows = await this.db.query("secrets", {
71
- where: { name, environment },
72
- filters: [{ col: "deleted_at", op: "isNull" }],
73
- limit: 1,
74
- });
75
- return rows.length > 0 ? this._toMeta(rows[0]) : null;
76
- }
77
- async list() {
78
- const rows = await this.db.query("secrets", {
79
- filters: [{ col: "deleted_at", op: "isNull" }],
80
- orderBy: "name",
81
- });
82
- return rows.map((r) => this._toMeta(r));
83
- }
84
- async rotate(name, newValue, environment = "production") {
85
- const rows = await this.db.query("secrets", {
86
- where: { name, environment },
87
- filters: [{ col: "deleted_at", op: "isNull" }],
88
- limit: 1,
89
- });
90
- if (rows.length === 0)
91
- throw new Error(`Secret "${name}" not found`);
92
- const storedValue = this.encKey ? encryptValue(newValue, this.encKey) : newValue;
93
- await this.db.update("secrets", rows[0].id, {
94
- value: storedValue,
95
- updated_at: new Date().toISOString(),
96
- });
97
- await this.hooks.emit("secret.rotated", { name, environment });
98
- }
99
- async delete(name, environment = "production") {
100
- const rows = await this.db.query("secrets", {
101
- where: { name, environment },
102
- filters: [{ col: "deleted_at", op: "isNull" }],
103
- limit: 1,
104
- });
105
- if (rows.length === 0)
106
- return;
107
- await this.db.update("secrets", rows[0].id, {
108
- deleted_at: new Date().toISOString(),
109
- });
110
- await this.hooks.emit("secret.deleted", { name, environment });
111
- }
112
- // ── Cursor persistence helpers ──────────────────────────────────
113
- /**
114
- * Load a sync cursor by key. Returns undefined if not found.
115
- * Cursors are stored as secrets with type='sync_cursor'.
116
- */
117
- async loadCursor(key) {
118
- const name = `sync-cursor:${key}`;
119
- const rows = await this.db.query("secrets", {
120
- where: { name },
121
- filters: [{ col: "deleted_at", op: "isNull" }],
122
- limit: 1,
123
- });
124
- const raw = rows[0]?.value ?? undefined;
125
- if (raw && this.encKey)
126
- return decryptValue(raw, this.encKey);
127
- return raw;
128
- }
129
- /**
130
- * Persist a sync cursor by key. Creates or updates the secret.
131
- */
132
- async saveCursor(key, value) {
133
- const name = `sync-cursor:${key}`;
134
- const storedValue = this.encKey ? encryptValue(value, this.encKey) : value;
135
- const rows = await this.db.query("secrets", {
136
- where: { name },
137
- filters: [{ col: "deleted_at", op: "isNull" }],
138
- limit: 1,
139
- });
140
- if (rows.length > 0) {
141
- await this.db.update("secrets", rows[0].id, {
142
- value: storedValue,
143
- updated_at: new Date().toISOString(),
144
- });
145
- }
146
- else {
147
- await this.db.insert("secrets", {
148
- id: uuidv4(),
149
- name,
150
- type: "sync_cursor",
151
- value: storedValue,
152
- });
153
- }
154
- }
155
- _toMeta(row) {
156
- return {
157
- id: row.id,
158
- org_id: row.org_id ?? null,
159
- name: row.name,
160
- type: row.type,
161
- environment: row.environment,
162
- location: row.location ?? null,
163
- description: row.description ?? null,
164
- rotation_schedule: row.rotation_schedule ?? null,
165
- expires_at: row.expires_at ?? null,
166
- notes: row.notes ?? null,
167
- created_at: row.created_at,
168
- updated_at: row.updated_at,
169
- };
170
- }
171
- }
@@ -1,13 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- export declare class SessionManager {
3
- private db;
4
- constructor(db: DataStore);
5
- save(agentId: string, channelId: string, peerId: string, params: Record<string, unknown>): Promise<string>;
6
- load(agentId: string, channelId: string, peerId: string): Promise<Record<string, unknown> | undefined>;
7
- clear(agentId: string, channelId: string, peerId: string): Promise<void>;
8
- shouldClear(session: Record<string, unknown>, opts: {
9
- maxRuns?: number;
10
- maxAgeHours?: number;
11
- }): Promise<boolean>;
12
- private _find;
13
- }
@@ -1,66 +0,0 @@
1
- export class SessionManager {
2
- db;
3
- constructor(db) {
4
- this.db = db;
5
- }
6
- async save(agentId, channelId, peerId, params) {
7
- const existing = await this._find(agentId, channelId, peerId);
8
- if (existing) {
9
- await this.db.update('sessions', { id: existing['id'] }, {
10
- context: JSON.stringify(params),
11
- last_message_at: new Date().toISOString(),
12
- message_count: (existing['message_count'] ?? 0) + 1,
13
- });
14
- return existing['id'];
15
- }
16
- else {
17
- const row = await this.db.insert('sessions', {
18
- agent_id: agentId,
19
- channel: channelId,
20
- peer_id: peerId,
21
- context: JSON.stringify(params),
22
- last_message_at: new Date().toISOString(),
23
- message_count: 1,
24
- });
25
- return row['id'];
26
- }
27
- }
28
- async load(agentId, channelId, peerId) {
29
- const session = await this._find(agentId, channelId, peerId);
30
- if (!session)
31
- return undefined;
32
- const context = session['context']
33
- ? JSON.parse(session['context'])
34
- : {};
35
- return { ...session, ...context };
36
- }
37
- async clear(agentId, channelId, peerId) {
38
- const session = await this._find(agentId, channelId, peerId);
39
- if (session) {
40
- await this.db.delete('sessions', { id: session['id'] });
41
- }
42
- }
43
- async shouldClear(session, opts) {
44
- if (opts.maxRuns !== undefined) {
45
- const messageCount = session['message_count'] ?? 0;
46
- if (messageCount > opts.maxRuns)
47
- return true;
48
- }
49
- if (opts.maxAgeHours !== undefined) {
50
- const createdAt = session['created_at'];
51
- if (createdAt) {
52
- const ageMs = Date.now() - new Date(createdAt).getTime();
53
- const ageHours = ageMs / (1000 * 60 * 60);
54
- if (ageHours > opts.maxAgeHours)
55
- return true;
56
- }
57
- }
58
- return false;
59
- }
60
- async _find(agentId, channelId, peerId) {
61
- const rows = await this.db.query('sessions', {
62
- where: { agent_id: agentId, channel: channelId, peer_id: peerId },
63
- });
64
- return rows[0] ?? undefined;
65
- }
66
- }
@@ -1,34 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- import type { HookBus } from '../hooks/hook-bus.js';
3
- import { MAX_CHAIN_DEPTH } from './chain-guard.js';
4
- export { MAX_CHAIN_DEPTH };
5
- export declare class TaskQueue {
6
- private db;
7
- private hooks;
8
- private config?;
9
- private pollTimer;
10
- private readonly pollIntervalMs;
11
- private readonly staleThresholdMs;
12
- constructor(db: DataStore, hooks: HookBus, config?: {
13
- pollIntervalMs?: number;
14
- staleThresholdMs?: number;
15
- } | undefined);
16
- create(task: {
17
- title: string;
18
- description?: string;
19
- assignee_id?: string;
20
- priority?: number;
21
- chain_depth?: number;
22
- chain_origin_id?: string;
23
- [key: string]: unknown;
24
- }): Promise<string>;
25
- update(id: string, changes: Record<string, unknown>): Promise<void>;
26
- get(id: string): Promise<Record<string, unknown> | undefined>;
27
- list(filter?: {
28
- status?: string;
29
- assignee_id?: string;
30
- }): Promise<Record<string, unknown>[]>;
31
- startPolling(): void;
32
- stopPolling(): void;
33
- private poll;
34
- }
@@ -1,83 +0,0 @@
1
- import { MAX_CHAIN_DEPTH, checkChainDepth } from './chain-guard.js';
2
- export { MAX_CHAIN_DEPTH };
3
- export class TaskQueue {
4
- db;
5
- hooks;
6
- config;
7
- pollTimer = null;
8
- pollIntervalMs;
9
- staleThresholdMs;
10
- constructor(db, hooks, config) {
11
- this.db = db;
12
- this.hooks = hooks;
13
- this.config = config;
14
- this.pollIntervalMs = config?.pollIntervalMs ?? 30_000;
15
- this.staleThresholdMs = config?.staleThresholdMs ?? 5 * 60 * 1_000;
16
- }
17
- async create(task) {
18
- const depth = task.chain_depth ?? 0;
19
- checkChainDepth(depth, MAX_CHAIN_DEPTH);
20
- const row = await this.db.insert('tasks', {
21
- title: task.title,
22
- description: task.description,
23
- assignee_id: task.assignee_id,
24
- priority: task.priority ?? 5,
25
- chain_depth: depth,
26
- chain_origin_id: task.chain_origin_id,
27
- status: 'todo',
28
- ...Object.fromEntries(Object.entries(task).filter(([k]) => !['title', 'description', 'assignee_id', 'priority', 'chain_depth', 'chain_origin_id', 'status'].includes(k))),
29
- });
30
- const taskId = row['id'];
31
- // Non-blocking: let callers do setup (e.g. insert related records) before
32
- // hook handlers (like execution engines) run.
33
- void this.hooks.emit('task.created', { taskId, title: task.title });
34
- return taskId;
35
- }
36
- async update(id, changes) {
37
- await this.db.update('tasks', { id }, {
38
- ...changes,
39
- updated_at: new Date().toISOString(),
40
- });
41
- }
42
- async get(id) {
43
- return (await this.db.get('tasks', { id })) ?? undefined;
44
- }
45
- async list(filter) {
46
- const where = {};
47
- if (filter?.status)
48
- where['status'] = filter.status;
49
- if (filter?.assignee_id)
50
- where['assignee_id'] = filter.assignee_id;
51
- return await this.db.query('tasks', Object.keys(where).length ? { where } : undefined);
52
- }
53
- startPolling() {
54
- if (this.pollTimer)
55
- return;
56
- this.pollTimer = setInterval(() => {
57
- void this.poll();
58
- }, this.pollIntervalMs);
59
- }
60
- stopPolling() {
61
- if (this.pollTimer) {
62
- clearInterval(this.pollTimer);
63
- this.pollTimer = null;
64
- }
65
- }
66
- async poll() {
67
- // Find tasks with status='todo', assignee_id NOT NULL
68
- const todoTasks = (await this.db.query('tasks', { where: { status: 'todo' } }))
69
- .filter((t) => t['assignee_id'] != null);
70
- // Check which have no active run
71
- const activeTasks = new Set((await this.db.query('runs', { where: { status: 'running' } })).map((r) => r['task_id']));
72
- const eligible = todoTasks
73
- .filter((t) => !activeTasks.has(t['id']))
74
- .sort((a, b) => a['priority'] - b['priority']);
75
- for (const task of eligible) {
76
- await this.hooks.emit('agent.wakeup', {
77
- agentId: task['assignee_id'],
78
- taskId: task['id'],
79
- source: 'poll',
80
- });
81
- }
82
- }
83
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Simple template interpolation for workflow step templates.
3
- * Supports {{key}} and {{steps.stepId.output}} patterns.
4
- */
5
- export declare function interpolate(template: string, context: Record<string, unknown>): string;
@@ -1,18 +0,0 @@
1
- /**
2
- * Simple template interpolation for workflow step templates.
3
- * Supports {{key}} and {{steps.stepId.output}} patterns.
4
- */
5
- export function interpolate(template, context) {
6
- return template.replace(/\{\{([^}]+)\}\}/g, (_match, path) => {
7
- const parts = path.trim().split('.');
8
- let value = context;
9
- for (const part of parts) {
10
- if (value == null || typeof value !== 'object')
11
- return '';
12
- value = value[part];
13
- }
14
- if (value == null)
15
- return '';
16
- return String(value);
17
- });
18
- }
@@ -1,47 +0,0 @@
1
- import type { DataStore } from "../data/data-store.js";
2
- import type { HookBus } from "../hooks/hook-bus.js";
3
- export interface UserInput {
4
- id?: string;
5
- org_id?: string;
6
- name: string;
7
- email?: string;
8
- role?: string;
9
- title?: string;
10
- external_id?: string;
11
- channel?: string;
12
- timezone?: string;
13
- preferences?: string;
14
- notes?: string;
15
- }
16
- export interface User {
17
- id: string;
18
- org_id: string | null;
19
- name: string;
20
- email: string | null;
21
- role: string | null;
22
- title: string | null;
23
- external_id: string | null;
24
- channel: string | null;
25
- timezone: string | null;
26
- preferences: string;
27
- notes: string | null;
28
- created_at: string;
29
- updated_at: string;
30
- deleted_at: string | null;
31
- }
32
- export declare class UserRegistry {
33
- private readonly db;
34
- private readonly hooks;
35
- constructor(db: DataStore, hooks: HookBus);
36
- register(input: UserInput): Promise<User>;
37
- getById(id: string): Promise<User | null>;
38
- getByEmail(email: string): Promise<User | null>;
39
- resolveByIdentity(channel: string, externalId: string): Promise<User | null>;
40
- resolveOrCreate(externalId: string, channel: string, defaults?: Partial<UserInput>): Promise<User>;
41
- list(filter?: {
42
- role?: string;
43
- org_id?: string;
44
- }): Promise<User[]>;
45
- update(id: string, changes: Partial<UserInput>): Promise<void>;
46
- addIdentity(userId: string, channel: string, externalId: string, displayName?: string): Promise<void>;
47
- }
@@ -1,76 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- export class UserRegistry {
3
- db;
4
- hooks;
5
- constructor(db, hooks) {
6
- this.db = db;
7
- this.hooks = hooks;
8
- }
9
- async register(input) {
10
- const id = input.id ?? uuidv4();
11
- await this.db.insert("users", { ...input, id });
12
- const user = await this.db.get("users", id);
13
- await this.hooks.emit("user.created", { user });
14
- return user;
15
- }
16
- async getById(id) {
17
- const row = await this.db.get("users", id);
18
- return row ?? null;
19
- }
20
- async getByEmail(email) {
21
- const rows = await this.db.query("users", {
22
- where: { email },
23
- filters: [{ col: "deleted_at", op: "isNull" }],
24
- limit: 1,
25
- });
26
- return rows.length > 0 ? rows[0] : null;
27
- }
28
- async resolveByIdentity(channel, externalId) {
29
- const identities = await this.db.query("user_identities", {
30
- where: { channel, external_id: externalId },
31
- limit: 1,
32
- });
33
- if (identities.length === 0)
34
- return null;
35
- return this.getById(identities[0].user_id);
36
- }
37
- async resolveOrCreate(externalId, channel, defaults) {
38
- const existing = await this.resolveByIdentity(channel, externalId);
39
- if (existing)
40
- return existing;
41
- const user = await this.register({
42
- name: defaults?.name ?? externalId,
43
- external_id: externalId,
44
- channel,
45
- ...defaults,
46
- });
47
- await this.addIdentity(user.id, channel, externalId);
48
- return user;
49
- }
50
- async list(filter) {
51
- const where = {};
52
- const filters = [{ col: "deleted_at", op: "isNull" }];
53
- if (filter?.role)
54
- where.role = filter.role;
55
- if (filter?.org_id)
56
- where.org_id = filter.org_id;
57
- const rows = await this.db.query("users", { where, filters });
58
- return rows;
59
- }
60
- async update(id, changes) {
61
- await this.db.update("users", id, {
62
- ...changes,
63
- updated_at: new Date().toISOString(),
64
- });
65
- }
66
- async addIdentity(userId, channel, externalId, displayName) {
67
- await this.db.insert("user_identities", {
68
- id: uuidv4(),
69
- user_id: userId,
70
- channel,
71
- external_id: externalId,
72
- display_name: displayName ?? null,
73
- verified: 0,
74
- });
75
- }
76
- }
@@ -1,9 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- export declare class WakeupQueue {
3
- private db;
4
- constructor(db: DataStore);
5
- enqueue(agentId: string, source: string, context?: Record<string, unknown>): Promise<string>;
6
- coalesce(agentId: string, context?: Record<string, unknown>): Promise<void>;
7
- getNext(agentId: string): Promise<Record<string, unknown> | undefined>;
8
- markFired(wakeupId: string, runId: string): Promise<void>;
9
- }
@@ -1,45 +0,0 @@
1
- export class WakeupQueue {
2
- db;
3
- constructor(db) {
4
- this.db = db;
5
- }
6
- async enqueue(agentId, source, context) {
7
- const row = await this.db.insert('wakeups', {
8
- agent_id: agentId,
9
- scheduled_at: new Date().toISOString(),
10
- context: context ? JSON.stringify({ source, ...context }) : JSON.stringify({ source }),
11
- });
12
- return row['id'];
13
- }
14
- async coalesce(agentId, context) {
15
- // Find existing queued wakeup (no fired_at) for agent
16
- const existing = (await this.db.query('wakeups', {
17
- where: { agent_id: agentId },
18
- })).filter((w) => w['fired_at'] == null);
19
- if (existing.length === 0)
20
- return;
21
- // Merge context into oldest queued wakeup
22
- const wakeup = existing[0];
23
- const currentCtx = wakeup['context']
24
- ? JSON.parse(wakeup['context'])
25
- : {};
26
- const merged = { ...currentCtx, ...(context ?? {}) };
27
- await this.db.update('wakeups', { id: wakeup['id'] }, {
28
- context: JSON.stringify(merged),
29
- });
30
- }
31
- async getNext(agentId) {
32
- const queued = (await this.db.query('wakeups', {
33
- where: { agent_id: agentId },
34
- }))
35
- .filter((w) => w['fired_at'] == null)
36
- .sort((a, b) => a['scheduled_at'].localeCompare(b['scheduled_at']));
37
- return queued[0] ?? undefined;
38
- }
39
- async markFired(wakeupId, runId) {
40
- await this.db.update('wakeups', { id: wakeupId }, {
41
- fired_at: new Date().toISOString(),
42
- run_id: runId,
43
- });
44
- }
45
- }
@@ -1,47 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- import type { HookBus } from '../hooks/hook-bus.js';
3
- import type { TaskQueue } from './task-queue.js';
4
- export interface WorkflowStep {
5
- id: string;
6
- name: string;
7
- agentSlug?: string;
8
- taskTemplate: {
9
- title: string;
10
- description: string;
11
- };
12
- dependsOn?: string[];
13
- onComplete?: 'next' | 'parallel' | 'end';
14
- onFail?: 'abort' | 'skip' | 'retry';
15
- }
16
- export interface WorkflowDefinition {
17
- name: string;
18
- description?: string;
19
- steps: WorkflowStep[];
20
- trigger?: {
21
- type: 'task_completed' | 'event' | 'schedule' | 'manual';
22
- filter?: Record<string, unknown>;
23
- };
24
- }
25
- export declare class WorkflowEngine {
26
- private db;
27
- private hooks;
28
- private taskQueue;
29
- constructor(db: DataStore, hooks: HookBus, taskQueue: TaskQueue);
30
- /**
31
- * Define/register a workflow.
32
- */
33
- define(slug: string, def: WorkflowDefinition): Promise<void>;
34
- /**
35
- * Start a workflow run.
36
- */
37
- start(workflowSlug: string, context: Record<string, unknown>): Promise<string>;
38
- /**
39
- * Called when a task with workflow_run_id completes.
40
- */
41
- onStepCompleted(taskId: string, output: string): Promise<void>;
42
- /**
43
- * Mark a workflow run as failed.
44
- */
45
- onStepFailed(taskId: string, error: string): Promise<void>;
46
- private _createStepTask;
47
- }