@revealui/ai 0.2.8 → 0.2.9

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 (206) hide show
  1. package/README.md +2 -2
  2. package/dist/a2a/card.d.ts +1 -1
  3. package/dist/a2a/card.d.ts.map +1 -1
  4. package/dist/a2a/card.js +4 -4
  5. package/dist/a2a/handler.d.ts +4 -4
  6. package/dist/a2a/handler.js +5 -5
  7. package/dist/a2a/index.d.ts +1 -1
  8. package/dist/a2a/index.js +1 -1
  9. package/dist/audit/emitter.d.ts +1 -1
  10. package/dist/audit/emitter.js +2 -2
  11. package/dist/audit/index.d.ts +2 -2
  12. package/dist/audit/index.js +2 -2
  13. package/dist/audit/store.d.ts +2 -2
  14. package/dist/audit/store.js +2 -2
  15. package/dist/client/errors.d.ts +13 -0
  16. package/dist/client/errors.d.ts.map +1 -0
  17. package/dist/client/errors.js +28 -0
  18. package/dist/client/hooks/useAgentContext.d.ts.map +1 -1
  19. package/dist/client/hooks/useAgentContext.js +6 -5
  20. package/dist/client/hooks/useAgentStream.d.ts +2 -2
  21. package/dist/client/hooks/useAgentStream.js +3 -3
  22. package/dist/client/hooks/useEpisodicMemory.d.ts.map +1 -1
  23. package/dist/client/hooks/useEpisodicMemory.js +6 -5
  24. package/dist/client/hooks/useWorkingMemory.d.ts.map +1 -1
  25. package/dist/client/hooks/useWorkingMemory.js +7 -6
  26. package/dist/embeddings/index.d.ts +1 -1
  27. package/dist/embeddings/index.js +4 -4
  28. package/dist/inference/context-budget.d.ts +1 -1
  29. package/dist/inference/context-budget.js +4 -4
  30. package/dist/inference/index.d.ts +1 -1
  31. package/dist/inference/index.js +1 -1
  32. package/dist/inference/runRag.d.ts +3 -3
  33. package/dist/inference/runRag.d.ts.map +1 -1
  34. package/dist/inference/runRag.js +1 -1
  35. package/dist/inference/task-decomposer.d.ts +1 -1
  36. package/dist/inference/task-decomposer.d.ts.map +1 -1
  37. package/dist/inference/task-decomposer.js +3 -3
  38. package/dist/inference/tool-result-compressor.d.ts +1 -1
  39. package/dist/inference/tool-result-compressor.js +1 -1
  40. package/dist/ingestion/{cms-indexer.d.ts → admin-indexer.d.ts} +12 -12
  41. package/dist/ingestion/admin-indexer.d.ts.map +1 -0
  42. package/dist/ingestion/{cms-indexer.js → admin-indexer.js} +9 -9
  43. package/dist/ingestion/bm25.d.ts +1 -1
  44. package/dist/ingestion/bm25.js +1 -1
  45. package/dist/ingestion/file-parsers.d.ts +1 -1
  46. package/dist/ingestion/file-parsers.d.ts.map +1 -1
  47. package/dist/ingestion/file-parsers.js +36 -17
  48. package/dist/ingestion/hybrid-search.d.ts +1 -1
  49. package/dist/ingestion/hybrid-search.js +1 -1
  50. package/dist/ingestion/index.d.ts +1 -1
  51. package/dist/ingestion/index.d.ts.map +1 -1
  52. package/dist/ingestion/index.js +1 -1
  53. package/dist/ingestion/rag-vector-service.d.ts +1 -1
  54. package/dist/ingestion/rag-vector-service.js +1 -1
  55. package/dist/ingestion/reranker.d.ts +1 -1
  56. package/dist/ingestion/reranker.js +1 -1
  57. package/dist/ingestion/text-splitter.d.ts +1 -1
  58. package/dist/ingestion/text-splitter.js +2 -2
  59. package/dist/llm/client.d.ts +7 -10
  60. package/dist/llm/client.d.ts.map +1 -1
  61. package/dist/llm/client.js +10 -34
  62. package/dist/llm/key-validator.d.ts +1 -1
  63. package/dist/llm/key-validator.js +8 -8
  64. package/dist/llm/providers/base.d.ts +2 -2
  65. package/dist/llm/providers/groq.d.ts +2 -2
  66. package/dist/llm/providers/groq.d.ts.map +1 -1
  67. package/dist/llm/providers/groq.js +2 -2
  68. package/dist/llm/providers/inference-snaps.d.ts +5 -5
  69. package/dist/llm/providers/inference-snaps.d.ts.map +1 -1
  70. package/dist/llm/providers/inference-snaps.js +4 -4
  71. package/dist/llm/providers/ollama.d.ts +2 -2
  72. package/dist/llm/providers/ollama.d.ts.map +1 -1
  73. package/dist/llm/providers/ollama.js +1 -1
  74. package/dist/llm/providers/openai-compat.d.ts +2 -2
  75. package/dist/llm/providers/openai-compat.js +5 -5
  76. package/dist/llm/providers/vultr.js +1 -1
  77. package/dist/llm/server.d.ts +0 -1
  78. package/dist/llm/server.d.ts.map +1 -1
  79. package/dist/llm/server.js +0 -1
  80. package/dist/llm/token-counter.d.ts.map +1 -1
  81. package/dist/llm/token-counter.js +11 -8
  82. package/dist/llm/workspace-provider-config.d.ts +1 -1
  83. package/dist/llm/workspace-provider-config.d.ts.map +1 -1
  84. package/dist/llm/workspace-provider-config.js +1 -1
  85. package/dist/memory/crdt/or-set.d.ts +12 -0
  86. package/dist/memory/crdt/or-set.d.ts.map +1 -1
  87. package/dist/memory/crdt/or-set.js +27 -0
  88. package/dist/memory/index.d.ts +1 -0
  89. package/dist/memory/index.d.ts.map +1 -1
  90. package/dist/memory/index.js +1 -0
  91. package/dist/memory/persistence/crdt-persistence.d.ts +21 -1
  92. package/dist/memory/persistence/crdt-persistence.d.ts.map +1 -1
  93. package/dist/memory/persistence/crdt-persistence.js +67 -0
  94. package/dist/memory/preferences/user-preferences-manager.d.ts.map +1 -1
  95. package/dist/memory/preferences/user-preferences-manager.js +11 -1
  96. package/dist/memory/stores/episodic-memory.js +2 -2
  97. package/dist/memory/stores/working-memory.d.ts +7 -2
  98. package/dist/memory/stores/working-memory.d.ts.map +1 -1
  99. package/dist/memory/stores/working-memory.js +31 -17
  100. package/dist/memory/sync/index.d.ts +2 -0
  101. package/dist/memory/sync/index.d.ts.map +1 -0
  102. package/dist/memory/sync/index.js +1 -0
  103. package/dist/memory/sync/sync-manager.d.ts +104 -0
  104. package/dist/memory/sync/sync-manager.d.ts.map +1 -0
  105. package/dist/memory/sync/sync-manager.js +137 -0
  106. package/dist/memory/utils/validation.js +1 -1
  107. package/dist/memory/vector/vector-memory-service.d.ts +1 -1
  108. package/dist/memory/vector/vector-memory-service.js +1 -1
  109. package/dist/orchestration/agent.d.ts +2 -2
  110. package/dist/orchestration/defaults.d.ts +1 -1
  111. package/dist/orchestration/defaults.js +1 -1
  112. package/dist/orchestration/orchestrator.d.ts +3 -3
  113. package/dist/orchestration/orchestrator.js +3 -3
  114. package/dist/orchestration/runtime.d.ts +1 -1
  115. package/dist/orchestration/runtime.js +1 -1
  116. package/dist/orchestration/streaming-runtime.d.ts +2 -2
  117. package/dist/orchestration/streaming-runtime.js +2 -2
  118. package/dist/orchestration/ticket-agent.d.ts +11 -11
  119. package/dist/orchestration/ticket-agent.d.ts.map +1 -1
  120. package/dist/orchestration/ticket-agent.js +10 -10
  121. package/dist/skills/catalog/vercel-catalog.d.ts.map +1 -1
  122. package/dist/skills/catalog/vercel-catalog.js +7 -4
  123. package/dist/skills/loader/github-loader.d.ts.map +1 -1
  124. package/dist/skills/loader/github-loader.js +2 -0
  125. package/dist/skills/loader/local-loader.js +1 -1
  126. package/dist/skills/loader/vercel-loader.d.ts.map +1 -1
  127. package/dist/skills/loader/vercel-loader.js +2 -0
  128. package/dist/skills/parser/skill-md-parser.js +2 -2
  129. package/dist/skills/registry/skill-registry.js +1 -1
  130. package/dist/templates/prompt-spec.js +1 -1
  131. package/dist/templates/skill-spec.js +1 -1
  132. package/dist/tools/{cms → admin}/collection-tools.d.ts +2 -2
  133. package/dist/tools/admin/collection-tools.d.ts.map +1 -0
  134. package/dist/tools/{cms → admin}/collection-tools.js +8 -8
  135. package/dist/tools/{cms → admin}/factory.d.ts +11 -11
  136. package/dist/tools/admin/factory.d.ts.map +1 -0
  137. package/dist/tools/{cms → admin}/factory.js +4 -4
  138. package/dist/tools/{cms → admin}/global-tools.d.ts +1 -1
  139. package/dist/tools/admin/global-tools.d.ts.map +1 -0
  140. package/dist/tools/{cms → admin}/global-tools.js +4 -4
  141. package/dist/tools/{cms → admin}/index.d.ts +4 -4
  142. package/dist/tools/admin/index.d.ts.map +1 -0
  143. package/dist/tools/{cms → admin}/index.js +3 -3
  144. package/dist/tools/{cms → admin}/media-tools.d.ts +1 -1
  145. package/dist/tools/admin/media-tools.d.ts.map +1 -0
  146. package/dist/tools/{cms → admin}/media-tools.js +4 -4
  147. package/dist/tools/{cms → admin}/user-tools.d.ts +1 -1
  148. package/dist/tools/admin/user-tools.d.ts.map +1 -0
  149. package/dist/tools/{cms → admin}/user-tools.js +1 -1
  150. package/dist/tools/coding/file-edit.d.ts +1 -1
  151. package/dist/tools/coding/file-edit.js +2 -2
  152. package/dist/tools/coding/file-glob.d.ts +1 -1
  153. package/dist/tools/coding/file-glob.d.ts.map +1 -1
  154. package/dist/tools/coding/file-glob.js +2 -1
  155. package/dist/tools/coding/file-grep.d.ts +1 -1
  156. package/dist/tools/coding/file-grep.d.ts.map +1 -1
  157. package/dist/tools/coding/file-grep.js +2 -1
  158. package/dist/tools/coding/file-read.d.ts +1 -1
  159. package/dist/tools/coding/file-read.d.ts.map +1 -1
  160. package/dist/tools/coding/file-read.js +15 -9
  161. package/dist/tools/coding/file-write.d.ts +1 -1
  162. package/dist/tools/coding/file-write.js +1 -1
  163. package/dist/tools/coding/git-ops.d.ts +1 -1
  164. package/dist/tools/coding/git-ops.d.ts.map +1 -1
  165. package/dist/tools/coding/git-ops.js +5 -7
  166. package/dist/tools/coding/index.d.ts +1 -1
  167. package/dist/tools/coding/index.d.ts.map +1 -1
  168. package/dist/tools/coding/lint-fix.d.ts +1 -1
  169. package/dist/tools/coding/lint-fix.d.ts.map +1 -1
  170. package/dist/tools/coding/lint-fix.js +8 -4
  171. package/dist/tools/coding/project-context.d.ts +1 -1
  172. package/dist/tools/coding/project-context.d.ts.map +1 -1
  173. package/dist/tools/coding/project-context.js +25 -24
  174. package/dist/tools/coding/safety.d.ts +1 -1
  175. package/dist/tools/coding/safety.d.ts.map +1 -1
  176. package/dist/tools/coding/shell-exec.d.ts +1 -1
  177. package/dist/tools/coding/shell-exec.js +1 -1
  178. package/dist/tools/coding/test-runner.d.ts +1 -1
  179. package/dist/tools/coding/test-runner.d.ts.map +1 -1
  180. package/dist/tools/coding/test-runner.js +12 -7
  181. package/dist/tools/deduplicator.js +1 -1
  182. package/dist/tools/document-summarizer.js +2 -2
  183. package/dist/tools/memory/store-memory.d.ts +1 -1
  184. package/dist/tools/memory/store-memory.js +2 -2
  185. package/dist/tools/ticket-tools.d.ts +2 -2
  186. package/dist/tools/ticket-tools.js +3 -3
  187. package/dist/tools/web/duck-duck-go.d.ts +3 -3
  188. package/dist/tools/web/duck-duck-go.js +4 -4
  189. package/dist/tools/web/exa.d.ts +1 -1
  190. package/dist/tools/web/exa.js +1 -1
  191. package/dist/tools/web/scraper.js +1 -1
  192. package/dist/tools/web/tavily.d.ts +2 -2
  193. package/dist/tools/web/tavily.js +2 -2
  194. package/dist/tools/web/types.d.ts +2 -2
  195. package/dist/tools/web/types.js +2 -2
  196. package/package.json +20 -15
  197. package/dist/ingestion/cms-indexer.d.ts.map +0 -1
  198. package/dist/llm/providers/bitnet.d.ts +0 -28
  199. package/dist/llm/providers/bitnet.d.ts.map +0 -1
  200. package/dist/llm/providers/bitnet.js +0 -36
  201. package/dist/tools/cms/collection-tools.d.ts.map +0 -1
  202. package/dist/tools/cms/factory.d.ts.map +0 -1
  203. package/dist/tools/cms/global-tools.d.ts.map +0 -1
  204. package/dist/tools/cms/index.d.ts.map +0 -1
  205. package/dist/tools/cms/media-tools.d.ts.map +0 -1
  206. package/dist/tools/cms/user-tools.d.ts.map +0 -1
@@ -7,6 +7,9 @@
7
7
  import { randomUUID } from 'node:crypto';
8
8
  import { agentContexts, crdtOperations } from '@revealui/db/schema';
9
9
  import { and, eq, gte } from 'drizzle-orm';
10
+ import { LWWRegister } from '../crdt/lww-register.js';
11
+ import { ORSet } from '../crdt/or-set.js';
12
+ import { PNCounter } from '../crdt/pn-counter.js';
10
13
  import { findAgentContextById } from '../utils/sql-helpers.js';
11
14
  // =============================================================================
12
15
  // CRDT Persistence
@@ -198,4 +201,68 @@ export class CRDTPersistence {
198
201
  }
199
202
  return result;
200
203
  }
204
+ /**
205
+ * Rebuilds CRDT state by replaying operations from the log.
206
+ *
207
+ * @param crdtId - CRDT instance identifier
208
+ * @param crdtType - Type of CRDT to rebuild
209
+ * @param nodeId - Node ID for the rebuilt CRDT
210
+ * @param since - Optional timestamp to replay from (defaults to 0 = all)
211
+ * @returns Rebuilt CRDT instance, or null if no operations found
212
+ */
213
+ async replayOperations(crdtId, crdtType, nodeId, since = 0) {
214
+ const operations = await this.getOperationsSince(crdtId, since);
215
+ if (operations.length === 0) {
216
+ return null;
217
+ }
218
+ if (crdtType === 'lww_register') {
219
+ const register = new LWWRegister(nodeId, null, 0);
220
+ for (const op of operations) {
221
+ if (op.operationType === 'set') {
222
+ register.set(op.payload.value, op.timestamp);
223
+ }
224
+ }
225
+ return register;
226
+ }
227
+ if (crdtType === 'or_set') {
228
+ const set = new ORSet(nodeId);
229
+ for (const op of operations) {
230
+ if (op.operationType === 'add') {
231
+ set.add(op.payload.value);
232
+ }
233
+ else if (op.operationType === 'remove' && typeof op.payload.tag === 'string') {
234
+ set.remove(op.payload.tag);
235
+ }
236
+ }
237
+ return set;
238
+ }
239
+ if (crdtType === 'pn_counter') {
240
+ const counter = new PNCounter(nodeId);
241
+ for (const op of operations) {
242
+ if (op.operationType === 'increment') {
243
+ counter.increment(typeof op.payload.delta === 'number' ? op.payload.delta : 1);
244
+ }
245
+ else if (op.operationType === 'decrement') {
246
+ counter.decrement(typeof op.payload.delta === 'number' ? op.payload.delta : 1);
247
+ }
248
+ }
249
+ return counter;
250
+ }
251
+ return null;
252
+ }
253
+ /**
254
+ * Deletes operations older than a timestamp (for cleanup after compaction).
255
+ *
256
+ * @param crdtId - CRDT instance identifier
257
+ * @param before - Unix timestamp (milliseconds) - delete operations older than this
258
+ * @returns Number of operations deleted
259
+ */
260
+ async deleteOperationsBefore(crdtId, before) {
261
+ const { lt } = await import('drizzle-orm');
262
+ const result = await this.db
263
+ .delete(crdtOperations)
264
+ .where(and(eq(crdtOperations.crdtId, crdtId), lt(crdtOperations.timestamp, before)))
265
+ .returning();
266
+ return result.length;
267
+ }
201
268
  }
@@ -1 +1 @@
1
- {"version":3,"file":"user-preferences-manager.d.ts","sourceRoot":"","sources":["../../../src/memory/preferences/user-preferences-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAe5E;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,MAAM,CAAkD;IAEhE;;;;;;OAMG;gBACS,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ;IAcxD;;;;OAIG;IACH,cAAc,IAAI,eAAe;IAIjC;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAsB1D;;;;OAIG;IACH,cAAc,CAAC,WAAW,EAAE,eAAe,GAAG,IAAI;IAUlD;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAgBnC;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAiChD;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,sBAAsB,GAAG,sBAAsB;IAM5D;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoF3B;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+E3B;;;;OAIG;IACH,MAAM,IAAI,eAAe,CAAC,eAAe,CAAC;IAI1C;;;;;;;;OAQG;IACH,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,eAAe,CAAC,eAAe,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,QAAQ,GACX,sBAAsB;IAMzB;;;;OAIG;IACH,KAAK,IAAI,sBAAsB;IAI/B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,SAAS,IAAI,MAAM;CAGpB"}
1
+ {"version":3,"file":"user-preferences-manager.d.ts","sourceRoot":"","sources":["../../../src/memory/preferences/user-preferences-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAe5E;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,MAAM,CAAkD;IAEhE;;;;;;OAMG;gBACS,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ;IAcxD;;;;OAIG;IACH,cAAc,IAAI,eAAe;IAIjC;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAsB1D;;;;OAIG;IACH,cAAc,CAAC,WAAW,EAAE,eAAe,GAAG,IAAI;IAUlD;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAkBnC;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAyChD;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,sBAAsB,GAAG,sBAAsB;IAM5D;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoF3B;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+E3B;;;;OAIG;IACH,MAAM,IAAI,eAAe,CAAC,eAAe,CAAC;IAI1C;;;;;;;;OAQG;IACH,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,eAAe,CAAC,eAAe,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,QAAQ,GACX,sBAAsB;IAMzB;;;;OAIG;IACH,KAAK,IAAI,sBAAsB;IAI/B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,SAAS,IAAI,MAAM;CAGpB"}
@@ -114,7 +114,10 @@ export class UserPreferencesManager {
114
114
  const keys = key.split('.');
115
115
  let value = prefs;
116
116
  for (const k of keys) {
117
- if (value && typeof value === 'object' && k in value) {
117
+ // Guard against prototype pollution reads
118
+ if (k === '__proto__' || k === 'constructor' || k === 'prototype')
119
+ return undefined;
120
+ if (value && typeof value === 'object' && Object.hasOwn(value, k)) {
118
121
  value = value[k];
119
122
  }
120
123
  else {
@@ -138,6 +141,13 @@ export class UserPreferencesManager {
138
141
  throw new ValidationError(`Invalid preference key: "${key}"`);
139
142
  }
140
143
  const parentKeys = keys.slice(0, -1);
144
+ // Guard against prototype pollution
145
+ const ForbiddenKeys = new Set(['__proto__', 'constructor', 'prototype']);
146
+ for (const k of keys) {
147
+ if (ForbiddenKeys.has(k)) {
148
+ throw new ValidationError(`Forbidden preference key segment: "${k}"`);
149
+ }
150
+ }
141
151
  // Navigate to parent object in cloned structure
142
152
  let parent = prefs;
143
153
  for (const k of parentKeys) {
@@ -268,9 +268,9 @@ export class EpisodicMemory {
268
268
  }
269
269
  catch (error) {
270
270
  // Embedding generation failed (e.g. embedding service unavailable).
271
- // Return empty resultsdo NOT fall back to getAll(), which would dump the
271
+ // Return empty results - do NOT fall back to getAll(), which would dump the
272
272
  // entire memory store into agent context regardless of relevance.
273
- void (error instanceof Error ? error.message : String(error)); // Semantic search failedreturn empty results
273
+ void (error instanceof Error ? error.message : String(error)); // Semantic search failed - return empty results
274
274
  return [];
275
275
  }
276
276
  }
@@ -12,6 +12,7 @@ import type { AgentDefinition } from '@revealui/contracts/agents';
12
12
  import { type LWWRegisterData } from '../crdt/lww-register.js';
13
13
  import { type ORSetData } from '../crdt/or-set.js';
14
14
  import type { CRDTPersistence } from '../persistence/crdt-persistence.js';
15
+ import type { SyncManager } from '../sync/sync-manager.js';
15
16
  export interface SessionState {
16
17
  status: 'active' | 'paused' | 'completed';
17
18
  focus?: {
@@ -56,19 +57,23 @@ export declare class WorkingMemory {
56
57
  private sessionId;
57
58
  private nodeId;
58
59
  private persistence?;
60
+ private syncManager?;
59
61
  /**
60
62
  * Creates a new WorkingMemory instance.
61
63
  *
62
64
  * @param sessionId - Unique session identifier
63
65
  * @param nodeId - Unique node identifier (for CRDT operations)
64
66
  * @param persistence - Optional persistence adapter
67
+ * @param syncManager - Optional sync manager for operation logging
65
68
  */
66
- constructor(sessionId: string, nodeId: string, persistence?: CRDTPersistence);
69
+ constructor(sessionId: string, nodeId: string, persistence?: CRDTPersistence, syncManager?: SyncManager);
67
70
  /**
68
71
  * Sets the entire context object.
69
72
  *
70
73
  * @param context - Context data to set
71
74
  */
75
+ /** Logs a CRDT operation to the sync manager (fire-and-forget). */
76
+ private logOp;
72
77
  /**
73
78
  * Sets the entire context object.
74
79
  *
@@ -199,7 +204,7 @@ export declare class WorkingMemory {
199
204
  * @param persistence - Optional persistence adapter
200
205
  * @returns New WorkingMemory instance
201
206
  */
202
- static fromData(data: WorkingMemoryData, persistence?: CRDTPersistence): WorkingMemory;
207
+ static fromData(data: WorkingMemoryData, persistence?: CRDTPersistence, syncManager?: SyncManager): WorkingMemory;
203
208
  /**
204
209
  * Creates a copy of this WorkingMemory.
205
210
  *
@@ -1 +1 @@
1
- {"version":3,"file":"working-memory.d.ts","sourceRoot":"","sources":["../../../src/memory/stores/working-memory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"working-memory.d.ts","sourceRoot":"","sources":["../../../src/memory/stores/working-memory.ts"],"names":[],"mappings":"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"}
@@ -36,17 +36,20 @@ export class WorkingMemory {
36
36
  sessionId;
37
37
  nodeId;
38
38
  persistence;
39
+ syncManager;
39
40
  /**
40
41
  * Creates a new WorkingMemory instance.
41
42
  *
42
43
  * @param sessionId - Unique session identifier
43
44
  * @param nodeId - Unique node identifier (for CRDT operations)
44
45
  * @param persistence - Optional persistence adapter
46
+ * @param syncManager - Optional sync manager for operation logging
45
47
  */
46
- constructor(sessionId, nodeId, persistence) {
48
+ constructor(sessionId, nodeId, persistence, syncManager) {
47
49
  this.sessionId = sessionId;
48
50
  this.nodeId = nodeId;
49
51
  this.persistence = persistence;
52
+ this.syncManager = syncManager;
50
53
  // Initialize CRDTs
51
54
  this.context = new LWWRegister(nodeId, {});
52
55
  this.sessionState = new LWWRegister(nodeId, {
@@ -59,6 +62,13 @@ export class WorkingMemory {
59
62
  *
60
63
  * @param context - Context data to set
61
64
  */
65
+ /** Logs a CRDT operation to the sync manager (fire-and-forget). */
66
+ logOp(crdtType, operationType, payload) {
67
+ if (!this.syncManager)
68
+ return;
69
+ const crdtId = `working-memory:${this.sessionId}`;
70
+ void this.syncManager.logOperation(crdtId, crdtType, operationType, payload);
71
+ }
62
72
  /**
63
73
  * Sets the entire context object.
64
74
  *
@@ -72,6 +82,7 @@ export class WorkingMemory {
72
82
  */
73
83
  setContext(context) {
74
84
  this.context.set(context);
85
+ this.logOp('lww_register', 'set', { value: context, key: 'context' });
75
86
  }
76
87
  /**
77
88
  * Gets the current context.
@@ -89,10 +100,9 @@ export class WorkingMemory {
89
100
  */
90
101
  updateContext(updates) {
91
102
  const current = this.context.get();
92
- this.context.set({
93
- ...current,
94
- ...updates,
95
- });
103
+ const merged = { ...current, ...updates };
104
+ this.context.set(merged);
105
+ this.logOp('lww_register', 'set', { value: merged, key: 'context' });
96
106
  }
97
107
  /**
98
108
  * Gets a specific context value.
@@ -131,10 +141,9 @@ export class WorkingMemory {
131
141
  */
132
142
  setContextValue(key, value) {
133
143
  const current = this.context.get();
134
- this.context.set({
135
- ...current,
136
- [key]: value,
137
- });
144
+ const updated = { ...current, [key]: value };
145
+ this.context.set(updated);
146
+ this.logOp('lww_register', 'set', { value: updated, key: 'context' });
138
147
  }
139
148
  /**
140
149
  * Adds an agent to the active agents set.
@@ -143,7 +152,9 @@ export class WorkingMemory {
143
152
  * @returns Unique tag for this agent addition
144
153
  */
145
154
  addAgent(agent) {
146
- return this.activeAgents.add(agent);
155
+ const tag = this.activeAgents.add(agent);
156
+ this.logOp('or_set', 'add', { value: agent, tag });
157
+ return tag;
147
158
  }
148
159
  /**
149
160
  * Removes an agent by tag.
@@ -152,7 +163,11 @@ export class WorkingMemory {
152
163
  * @returns true if agent was removed
153
164
  */
154
165
  removeAgent(tag) {
155
- return this.activeAgents.remove(tag);
166
+ const removed = this.activeAgents.remove(tag);
167
+ if (removed) {
168
+ this.logOp('or_set', 'remove', { tag });
169
+ }
170
+ return removed;
156
171
  }
157
172
  /**
158
173
  * Removes an agent by ID (removes all instances).
@@ -201,10 +216,9 @@ export class WorkingMemory {
201
216
  */
202
217
  updateSessionState(state) {
203
218
  const current = this.sessionState.get();
204
- this.sessionState.set({
205
- ...current,
206
- ...state,
207
- });
219
+ const merged = { ...current, ...state };
220
+ this.sessionState.set(merged);
221
+ this.logOp('lww_register', 'set', { value: merged, key: 'sessionState' });
208
222
  }
209
223
  /**
210
224
  * Gets the current session state.
@@ -297,8 +311,8 @@ export class WorkingMemory {
297
311
  * @param persistence - Optional persistence adapter
298
312
  * @returns New WorkingMemory instance
299
313
  */
300
- static fromData(data, persistence) {
301
- const memory = new WorkingMemory(data.sessionId, data.nodeId, persistence);
314
+ static fromData(data, persistence, syncManager) {
315
+ const memory = new WorkingMemory(data.sessionId, data.nodeId, persistence, syncManager);
302
316
  memory.context = LWWRegister.fromData(data.context);
303
317
  memory.sessionState = LWWRegister.fromData(data.sessionState);
304
318
  memory.activeAgents = ORSet.fromData(data.activeAgents);
@@ -0,0 +1,2 @@
1
+ export { type SyncDelta, SyncManager, type SyncResult, type SyncState } from './sync-manager.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/memory/sync/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1 @@
1
+ export { SyncManager } from './sync-manager.js';
@@ -0,0 +1,104 @@
1
+ /**
2
+ * CRDT Sync Manager
3
+ *
4
+ * Coordinates state synchronization between distributed nodes.
5
+ * Supports both full-state merge and delta-based sync via the operation log.
6
+ *
7
+ * Architecture:
8
+ * - State-based sync: serialize → transfer → merge (simple, higher bandwidth)
9
+ * - Op-based sync: log ops → transfer deltas → replay (efficient, requires op log)
10
+ * - Anti-entropy: periodic full-state reconciliation to catch missed ops
11
+ *
12
+ * Transport-agnostic: the SyncManager produces/consumes serialized payloads.
13
+ * The actual transport (HTTP, WebSocket, message queue) is the caller's concern.
14
+ */
15
+ import type { LWWRegisterData } from '../crdt/lww-register.js';
16
+ import type { ORSetData } from '../crdt/or-set.js';
17
+ import type { PNCounterData } from '../crdt/pn-counter.js';
18
+ import type { CRDTOperationPayload, CRDTPersistence, CRDTType } from '../persistence/crdt-persistence.js';
19
+ import type { WorkingMemory } from '../stores/working-memory.js';
20
+ export interface SyncState {
21
+ /** CRDT instance identifier */
22
+ crdtId: string;
23
+ /** Node that produced this state */
24
+ sourceNodeId: string;
25
+ /** Timestamp of this state snapshot */
26
+ timestamp: number;
27
+ /** Serialized CRDT states (composite) */
28
+ states: Record<string, LWWRegisterData<unknown> | ORSetData<unknown> | PNCounterData>;
29
+ }
30
+ export interface SyncDelta {
31
+ /** CRDT instance identifier */
32
+ crdtId: string;
33
+ /** Node that produced these operations */
34
+ sourceNodeId: string;
35
+ /** Operations since last sync point */
36
+ operations: CRDTOperationPayload[];
37
+ /** Timestamp of the last synced operation (for next delta request) */
38
+ lastSyncTimestamp: number;
39
+ }
40
+ export interface SyncResult {
41
+ /** Whether state changed as a result of sync */
42
+ changed: boolean;
43
+ /** Number of operations applied */
44
+ operationsApplied: number;
45
+ /** Number of conflicts resolved */
46
+ conflictsResolved: number;
47
+ /** Timestamp to use for next delta sync */
48
+ syncTimestamp: number;
49
+ }
50
+ export declare class SyncManager {
51
+ private nodeId;
52
+ private persistence;
53
+ /** Tracks the last sync timestamp per remote node */
54
+ private syncPoints;
55
+ constructor(nodeId: string, persistence: CRDTPersistence);
56
+ /**
57
+ * Produces a full-state snapshot for transfer to another node.
58
+ * The receiving node calls `mergeRemoteState()` with this payload.
59
+ */
60
+ getLocalState(crdtId: string): Promise<SyncState>;
61
+ /**
62
+ * Merges a remote node's full state into local state.
63
+ * Uses CRDT merge semantics - order doesn't matter, result is deterministic.
64
+ *
65
+ * @returns WorkingMemory with merged state (caller decides whether to persist)
66
+ */
67
+ mergeRemoteWorkingMemory(local: WorkingMemory, remote: WorkingMemory): {
68
+ merged: WorkingMemory;
69
+ changed: boolean;
70
+ };
71
+ /**
72
+ * Produces a delta payload (operations since a timestamp) for efficient sync.
73
+ * The receiving node calls `applyDelta()` with this payload.
74
+ */
75
+ getDelta(crdtId: string, since: number): Promise<SyncDelta>;
76
+ /**
77
+ * Applies a delta from a remote node by replaying operations.
78
+ * Logs each remote operation locally for future delta requests from other nodes.
79
+ */
80
+ applyDelta(delta: SyncDelta): Promise<SyncResult>;
81
+ /**
82
+ * Logs a local operation to the persistence layer.
83
+ * Called by memory stores when they mutate CRDT state.
84
+ */
85
+ logOperation(crdtId: string, crdtType: CRDTType, operationType: CRDTOperationPayload['operationType'], payload: Record<string, unknown>): Promise<void>;
86
+ /**
87
+ * Gets the last sync timestamp for a remote node.
88
+ * Used to request only new operations on the next sync.
89
+ */
90
+ getSyncPoint(remoteNodeId: string): number;
91
+ /**
92
+ * Sets the sync point for a remote node (e.g., after initial full-state sync).
93
+ */
94
+ setSyncPoint(remoteNodeId: string, timestamp: number): void;
95
+ /**
96
+ * Gets all tracked sync points.
97
+ */
98
+ getAllSyncPoints(): Map<string, number>;
99
+ /**
100
+ * Gets this manager's node ID.
101
+ */
102
+ getNodeId(): string;
103
+ }
104
+ //# sourceMappingURL=sync-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-manager.d.ts","sourceRoot":"","sources":["../../../src/memory/sync/sync-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACT,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAMjE,MAAM,WAAW,SAAS;IACxB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC;CACvF;AAED,MAAM,WAAW,SAAS;IACxB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,uCAAuC;IACvC,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,sEAAsE;IACtE,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;IACjB,mCAAmC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAkB;IACrC,qDAAqD;IACrD,OAAO,CAAC,UAAU,CAAkC;gBAExC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe;IAKxD;;;OAGG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAmBvD;;;;;OAKG;IACH,wBAAwB,CACtB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,aAAa,GACpB;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAgB9C;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAYjE;;;OAGG;IACG,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAyBvD;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,oBAAoB,CAAC,eAAe,CAAC,EACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC;IAWhB;;;OAGG;IACH,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAI1C;;OAEG;IACH,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAI3D;;OAEG;IACH,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIvC;;OAEG;IACH,SAAS,IAAI,MAAM;CAGpB"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * CRDT Sync Manager
3
+ *
4
+ * Coordinates state synchronization between distributed nodes.
5
+ * Supports both full-state merge and delta-based sync via the operation log.
6
+ *
7
+ * Architecture:
8
+ * - State-based sync: serialize → transfer → merge (simple, higher bandwidth)
9
+ * - Op-based sync: log ops → transfer deltas → replay (efficient, requires op log)
10
+ * - Anti-entropy: periodic full-state reconciliation to catch missed ops
11
+ *
12
+ * Transport-agnostic: the SyncManager produces/consumes serialized payloads.
13
+ * The actual transport (HTTP, WebSocket, message queue) is the caller's concern.
14
+ */
15
+ // =============================================================================
16
+ // SyncManager
17
+ // =============================================================================
18
+ export class SyncManager {
19
+ nodeId;
20
+ persistence;
21
+ /** Tracks the last sync timestamp per remote node */
22
+ syncPoints = new Map();
23
+ constructor(nodeId, persistence) {
24
+ this.nodeId = nodeId;
25
+ this.persistence = persistence;
26
+ }
27
+ /**
28
+ * Produces a full-state snapshot for transfer to another node.
29
+ * The receiving node calls `mergeRemoteState()` with this payload.
30
+ */
31
+ async getLocalState(crdtId) {
32
+ const states = await this.persistence.loadCompositeState(crdtId);
33
+ const stateRecord = {};
34
+ for (const [key, data] of states) {
35
+ stateRecord[key] = data;
36
+ }
37
+ return {
38
+ crdtId,
39
+ sourceNodeId: this.nodeId,
40
+ timestamp: Date.now(),
41
+ states: stateRecord,
42
+ };
43
+ }
44
+ /**
45
+ * Merges a remote node's full state into local state.
46
+ * Uses CRDT merge semantics - order doesn't matter, result is deterministic.
47
+ *
48
+ * @returns WorkingMemory with merged state (caller decides whether to persist)
49
+ */
50
+ mergeRemoteWorkingMemory(local, remote) {
51
+ const localData = local.toData();
52
+ const remoteData = remote.toData();
53
+ // Quick equality check - if timestamps match, nothing changed
54
+ if (localData.context.timestamp === remoteData.context.timestamp &&
55
+ localData.sessionState.timestamp === remoteData.sessionState.timestamp) {
56
+ return { merged: local, changed: false };
57
+ }
58
+ const merged = local.merge(remote);
59
+ return { merged, changed: true };
60
+ }
61
+ /**
62
+ * Produces a delta payload (operations since a timestamp) for efficient sync.
63
+ * The receiving node calls `applyDelta()` with this payload.
64
+ */
65
+ async getDelta(crdtId, since) {
66
+ const operations = await this.persistence.getOperationsSince(crdtId, since);
67
+ return {
68
+ crdtId,
69
+ sourceNodeId: this.nodeId,
70
+ operations,
71
+ lastSyncTimestamp: operations.length > 0 ? (operations[operations.length - 1]?.timestamp ?? since) : since,
72
+ };
73
+ }
74
+ /**
75
+ * Applies a delta from a remote node by replaying operations.
76
+ * Logs each remote operation locally for future delta requests from other nodes.
77
+ */
78
+ async applyDelta(delta) {
79
+ let applied = 0;
80
+ for (const op of delta.operations) {
81
+ // Skip operations from our own node (already applied locally)
82
+ if (op.nodeId === this.nodeId) {
83
+ continue;
84
+ }
85
+ // Log the remote operation locally
86
+ await this.persistence.appendOperation(op);
87
+ applied++;
88
+ }
89
+ // Update sync point for this remote node
90
+ this.syncPoints.set(delta.sourceNodeId, delta.lastSyncTimestamp);
91
+ return {
92
+ changed: applied > 0,
93
+ operationsApplied: applied,
94
+ conflictsResolved: 0, // CRDTs resolve conflicts automatically
95
+ syncTimestamp: delta.lastSyncTimestamp,
96
+ };
97
+ }
98
+ /**
99
+ * Logs a local operation to the persistence layer.
100
+ * Called by memory stores when they mutate CRDT state.
101
+ */
102
+ async logOperation(crdtId, crdtType, operationType, payload) {
103
+ await this.persistence.appendOperation({
104
+ crdtId,
105
+ crdtType,
106
+ operationType,
107
+ payload,
108
+ nodeId: this.nodeId,
109
+ timestamp: Date.now(),
110
+ });
111
+ }
112
+ /**
113
+ * Gets the last sync timestamp for a remote node.
114
+ * Used to request only new operations on the next sync.
115
+ */
116
+ getSyncPoint(remoteNodeId) {
117
+ return this.syncPoints.get(remoteNodeId) ?? 0;
118
+ }
119
+ /**
120
+ * Sets the sync point for a remote node (e.g., after initial full-state sync).
121
+ */
122
+ setSyncPoint(remoteNodeId, timestamp) {
123
+ this.syncPoints.set(remoteNodeId, timestamp);
124
+ }
125
+ /**
126
+ * Gets all tracked sync points.
127
+ */
128
+ getAllSyncPoints() {
129
+ return new Map(this.syncPoints);
130
+ }
131
+ /**
132
+ * Gets this manager's node ID.
133
+ */
134
+ getNodeId() {
135
+ return this.nodeId;
136
+ }
137
+ }
@@ -118,7 +118,7 @@ export function estimateObjectSize(obj) {
118
118
  const type = typeof obj;
119
119
  if (type === 'string') {
120
120
  // UTF-16 char units × 2 bytes each. This over-estimates multi-byte UTF-8 code
121
- // points but is intentionally conservativethe limit stays tighter than the
121
+ // points but is intentionally conservative - the limit stays tighter than the
122
122
  // real in-process memory cost, which is what we want for a safety bound.
123
123
  return obj.length * 2 + 8;
124
124
  }
@@ -41,7 +41,7 @@ export declare class VectorMemoryService {
41
41
  /**
42
42
  * Search for similar memories using vector similarity.
43
43
  *
44
- * @param queryEmbedding - Query embedding vector (768 dimensionsOllama nomic-embed-text)
44
+ * @param queryEmbedding - Query embedding vector (768 dimensions - Ollama nomic-embed-text)
45
45
  * @param options - Search options (filtering, limits, etc.)
46
46
  * @returns Array of memories with similarity scores, sorted by similarity (highest first)
47
47
  *
@@ -42,7 +42,7 @@ export class VectorMemoryService {
42
42
  /**
43
43
  * Search for similar memories using vector similarity.
44
44
  *
45
- * @param queryEmbedding - Query embedding vector (768 dimensionsOllama nomic-embed-text)
45
+ * @param queryEmbedding - Query embedding vector (768 dimensions - Ollama nomic-embed-text)
46
46
  * @param options - Search options (filtering, limits, etc.)
47
47
  * @returns Array of memories with similarity scores, sorted by similarity (highest first)
48
48
  *
@@ -22,7 +22,7 @@ export interface AgentConfig {
22
22
  webSearchProvider?: WebSearchProvider;
23
23
  /**
24
24
  * Capability tags used by AgentOrchestrator.findBestAgent() for routing.
25
- * Example: ['cms', 'search', 'ticket', 'summarize']
25
+ * Example: ['admin', 'search', 'ticket', 'summarize']
26
26
  */
27
27
  capabilities?: string[];
28
28
  }
@@ -70,7 +70,7 @@ export interface Agent {
70
70
  */
71
71
  tools: Tool[];
72
72
  /**
73
- * Memory system (optionalagents without memory skip episodic recall)
73
+ * Memory system (optional - agents without memory skip episodic recall)
74
74
  */
75
75
  memory?: EpisodicMemory;
76
76
  /**
@@ -15,7 +15,7 @@ import type { Tool } from '../tools/base.js';
15
15
  export declare const WORKSPACE_AGENT_DEFAULT_TOOLS: Tool[];
16
16
  /**
17
17
  * Returns the workspace agent default tool set, optionally merged with
18
- * additional tools (e.g. CMS tools, MCP-discovered tools).
18
+ * additional tools (e.g. admin tools, MCP-discovered tools).
19
19
  */
20
20
  export declare function getWorkspaceAgentTools(additionalTools?: Tool[]): Tool[];
21
21
  //# sourceMappingURL=defaults.d.ts.map
@@ -15,7 +15,7 @@ import { webSearchTool } from '../tools/web/index.js';
15
15
  export const WORKSPACE_AGENT_DEFAULT_TOOLS = [webSearchTool];
16
16
  /**
17
17
  * Returns the workspace agent default tool set, optionally merged with
18
- * additional tools (e.g. CMS tools, MCP-discovered tools).
18
+ * additional tools (e.g. admin tools, MCP-discovered tools).
19
19
  */
20
20
  export function getWorkspaceAgentTools(additionalTools = []) {
21
21
  return [...WORKSPACE_AGENT_DEFAULT_TOOLS, ...additionalTools];
@@ -51,11 +51,11 @@ export declare class AgentOrchestrator {
51
51
  * Find the best agent for a task.
52
52
  *
53
53
  * Routing priority:
54
- * 1. Capability intersectionagent whose AgentConfig.capabilities overlaps
54
+ * 1. Capability intersection - agent whose AgentConfig.capabilities overlaps
55
55
  * with task.requiredCapabilities (highest-overlap agent wins)
56
- * 2. Tool-name substring matchagent has a tool whose name includes the
56
+ * 2. Tool-name substring match - agent has a tool whose name includes the
57
57
  * task type string (legacy fallback)
58
- * 3. First registered agentlast-resort fallback
58
+ * 3. First registered agent - last-resort fallback
59
59
  */
60
60
  private findBestAgent;
61
61
  /**