@lleverage-ai/agent-sdk 0.0.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 (327) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2321 -0
  3. package/dist/agent.d.ts +52 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +2122 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/backend.d.ts +378 -0
  8. package/dist/backend.d.ts.map +1 -0
  9. package/dist/backend.js +71 -0
  10. package/dist/backend.js.map +1 -0
  11. package/dist/backends/composite.d.ts +258 -0
  12. package/dist/backends/composite.d.ts.map +1 -0
  13. package/dist/backends/composite.js +437 -0
  14. package/dist/backends/composite.js.map +1 -0
  15. package/dist/backends/filesystem.d.ts +268 -0
  16. package/dist/backends/filesystem.d.ts.map +1 -0
  17. package/dist/backends/filesystem.js +623 -0
  18. package/dist/backends/filesystem.js.map +1 -0
  19. package/dist/backends/index.d.ts +14 -0
  20. package/dist/backends/index.d.ts.map +1 -0
  21. package/dist/backends/index.js +14 -0
  22. package/dist/backends/index.js.map +1 -0
  23. package/dist/backends/persistent.d.ts +312 -0
  24. package/dist/backends/persistent.d.ts.map +1 -0
  25. package/dist/backends/persistent.js +519 -0
  26. package/dist/backends/persistent.js.map +1 -0
  27. package/dist/backends/sandbox.d.ts +315 -0
  28. package/dist/backends/sandbox.d.ts.map +1 -0
  29. package/dist/backends/sandbox.js +490 -0
  30. package/dist/backends/sandbox.js.map +1 -0
  31. package/dist/backends/state.d.ts +225 -0
  32. package/dist/backends/state.d.ts.map +1 -0
  33. package/dist/backends/state.js +396 -0
  34. package/dist/backends/state.js.map +1 -0
  35. package/dist/checkpointer/file-saver.d.ts +182 -0
  36. package/dist/checkpointer/file-saver.d.ts.map +1 -0
  37. package/dist/checkpointer/file-saver.js +298 -0
  38. package/dist/checkpointer/file-saver.js.map +1 -0
  39. package/dist/checkpointer/index.d.ts +40 -0
  40. package/dist/checkpointer/index.d.ts.map +1 -0
  41. package/dist/checkpointer/index.js +40 -0
  42. package/dist/checkpointer/index.js.map +1 -0
  43. package/dist/checkpointer/kv-saver.d.ts +142 -0
  44. package/dist/checkpointer/kv-saver.d.ts.map +1 -0
  45. package/dist/checkpointer/kv-saver.js +176 -0
  46. package/dist/checkpointer/kv-saver.js.map +1 -0
  47. package/dist/checkpointer/memory-saver.d.ts +158 -0
  48. package/dist/checkpointer/memory-saver.d.ts.map +1 -0
  49. package/dist/checkpointer/memory-saver.js +222 -0
  50. package/dist/checkpointer/memory-saver.js.map +1 -0
  51. package/dist/checkpointer/types.d.ts +353 -0
  52. package/dist/checkpointer/types.d.ts.map +1 -0
  53. package/dist/checkpointer/types.js +159 -0
  54. package/dist/checkpointer/types.js.map +1 -0
  55. package/dist/context-manager.d.ts +627 -0
  56. package/dist/context-manager.d.ts.map +1 -0
  57. package/dist/context-manager.js +1039 -0
  58. package/dist/context-manager.js.map +1 -0
  59. package/dist/context.d.ts +57 -0
  60. package/dist/context.d.ts.map +1 -0
  61. package/dist/context.js +76 -0
  62. package/dist/context.js.map +1 -0
  63. package/dist/errors/index.d.ts +611 -0
  64. package/dist/errors/index.d.ts.map +1 -0
  65. package/dist/errors/index.js +1023 -0
  66. package/dist/errors/index.js.map +1 -0
  67. package/dist/generation-helpers.d.ts +126 -0
  68. package/dist/generation-helpers.d.ts.map +1 -0
  69. package/dist/generation-helpers.js +181 -0
  70. package/dist/generation-helpers.js.map +1 -0
  71. package/dist/hooks/audit.d.ts +210 -0
  72. package/dist/hooks/audit.d.ts.map +1 -0
  73. package/dist/hooks/audit.js +305 -0
  74. package/dist/hooks/audit.js.map +1 -0
  75. package/dist/hooks/cache.d.ts +180 -0
  76. package/dist/hooks/cache.d.ts.map +1 -0
  77. package/dist/hooks/cache.js +273 -0
  78. package/dist/hooks/cache.js.map +1 -0
  79. package/dist/hooks/guardrails.d.ts +145 -0
  80. package/dist/hooks/guardrails.d.ts.map +1 -0
  81. package/dist/hooks/guardrails.js +326 -0
  82. package/dist/hooks/guardrails.js.map +1 -0
  83. package/dist/hooks/index.d.ts +18 -0
  84. package/dist/hooks/index.d.ts.map +1 -0
  85. package/dist/hooks/index.js +32 -0
  86. package/dist/hooks/index.js.map +1 -0
  87. package/dist/hooks/logging.d.ts +193 -0
  88. package/dist/hooks/logging.d.ts.map +1 -0
  89. package/dist/hooks/logging.js +345 -0
  90. package/dist/hooks/logging.js.map +1 -0
  91. package/dist/hooks/parallel-guardrails.d.ts +268 -0
  92. package/dist/hooks/parallel-guardrails.d.ts.map +1 -0
  93. package/dist/hooks/parallel-guardrails.js +416 -0
  94. package/dist/hooks/parallel-guardrails.js.map +1 -0
  95. package/dist/hooks/rate-limit.d.ts +305 -0
  96. package/dist/hooks/rate-limit.d.ts.map +1 -0
  97. package/dist/hooks/rate-limit.js +372 -0
  98. package/dist/hooks/rate-limit.js.map +1 -0
  99. package/dist/hooks/retry.d.ts +144 -0
  100. package/dist/hooks/retry.d.ts.map +1 -0
  101. package/dist/hooks/retry.js +210 -0
  102. package/dist/hooks/retry.js.map +1 -0
  103. package/dist/hooks/secrets.d.ts +174 -0
  104. package/dist/hooks/secrets.d.ts.map +1 -0
  105. package/dist/hooks/secrets.js +306 -0
  106. package/dist/hooks/secrets.js.map +1 -0
  107. package/dist/hooks.d.ts +229 -0
  108. package/dist/hooks.d.ts.map +1 -0
  109. package/dist/hooks.js +352 -0
  110. package/dist/hooks.js.map +1 -0
  111. package/dist/index.d.ts +97 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +182 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/mcp/env.d.ts +25 -0
  116. package/dist/mcp/env.d.ts.map +1 -0
  117. package/dist/mcp/env.js +18 -0
  118. package/dist/mcp/env.js.map +1 -0
  119. package/dist/mcp/index.d.ts +16 -0
  120. package/dist/mcp/index.d.ts.map +1 -0
  121. package/dist/mcp/index.js +17 -0
  122. package/dist/mcp/index.js.map +1 -0
  123. package/dist/mcp/manager.d.ts +184 -0
  124. package/dist/mcp/manager.d.ts.map +1 -0
  125. package/dist/mcp/manager.js +446 -0
  126. package/dist/mcp/manager.js.map +1 -0
  127. package/dist/mcp/types.d.ts +58 -0
  128. package/dist/mcp/types.d.ts.map +1 -0
  129. package/dist/mcp/types.js +7 -0
  130. package/dist/mcp/types.js.map +1 -0
  131. package/dist/mcp/validation.d.ts +119 -0
  132. package/dist/mcp/validation.d.ts.map +1 -0
  133. package/dist/mcp/validation.js +407 -0
  134. package/dist/mcp/validation.js.map +1 -0
  135. package/dist/mcp/virtual-server.d.ts +78 -0
  136. package/dist/mcp/virtual-server.d.ts.map +1 -0
  137. package/dist/mcp/virtual-server.js +137 -0
  138. package/dist/mcp/virtual-server.js.map +1 -0
  139. package/dist/memory/filesystem-store.d.ts +217 -0
  140. package/dist/memory/filesystem-store.d.ts.map +1 -0
  141. package/dist/memory/filesystem-store.js +343 -0
  142. package/dist/memory/filesystem-store.js.map +1 -0
  143. package/dist/memory/index.d.ts +46 -0
  144. package/dist/memory/index.d.ts.map +1 -0
  145. package/dist/memory/index.js +46 -0
  146. package/dist/memory/index.js.map +1 -0
  147. package/dist/memory/loader.d.ts +396 -0
  148. package/dist/memory/loader.d.ts.map +1 -0
  149. package/dist/memory/loader.js +419 -0
  150. package/dist/memory/loader.js.map +1 -0
  151. package/dist/memory/permissions.d.ts +282 -0
  152. package/dist/memory/permissions.d.ts.map +1 -0
  153. package/dist/memory/permissions.js +297 -0
  154. package/dist/memory/permissions.js.map +1 -0
  155. package/dist/memory/rules.d.ts +249 -0
  156. package/dist/memory/rules.d.ts.map +1 -0
  157. package/dist/memory/rules.js +362 -0
  158. package/dist/memory/rules.js.map +1 -0
  159. package/dist/memory/store.d.ts +286 -0
  160. package/dist/memory/store.d.ts.map +1 -0
  161. package/dist/memory/store.js +263 -0
  162. package/dist/memory/store.js.map +1 -0
  163. package/dist/middleware/apply.d.ts +73 -0
  164. package/dist/middleware/apply.d.ts.map +1 -0
  165. package/dist/middleware/apply.js +219 -0
  166. package/dist/middleware/apply.js.map +1 -0
  167. package/dist/middleware/context.d.ts +33 -0
  168. package/dist/middleware/context.d.ts.map +1 -0
  169. package/dist/middleware/context.js +176 -0
  170. package/dist/middleware/context.js.map +1 -0
  171. package/dist/middleware/index.d.ts +31 -0
  172. package/dist/middleware/index.d.ts.map +1 -0
  173. package/dist/middleware/index.js +32 -0
  174. package/dist/middleware/index.js.map +1 -0
  175. package/dist/middleware/logging.d.ts +137 -0
  176. package/dist/middleware/logging.d.ts.map +1 -0
  177. package/dist/middleware/logging.js +374 -0
  178. package/dist/middleware/logging.js.map +1 -0
  179. package/dist/middleware/types.d.ts +183 -0
  180. package/dist/middleware/types.d.ts.map +1 -0
  181. package/dist/middleware/types.js +11 -0
  182. package/dist/middleware/types.js.map +1 -0
  183. package/dist/observability/events.d.ts +183 -0
  184. package/dist/observability/events.d.ts.map +1 -0
  185. package/dist/observability/events.js +305 -0
  186. package/dist/observability/events.js.map +1 -0
  187. package/dist/observability/index.d.ts +55 -0
  188. package/dist/observability/index.d.ts.map +1 -0
  189. package/dist/observability/index.js +87 -0
  190. package/dist/observability/index.js.map +1 -0
  191. package/dist/observability/logger.d.ts +318 -0
  192. package/dist/observability/logger.d.ts.map +1 -0
  193. package/dist/observability/logger.js +436 -0
  194. package/dist/observability/logger.js.map +1 -0
  195. package/dist/observability/metrics.d.ts +341 -0
  196. package/dist/observability/metrics.d.ts.map +1 -0
  197. package/dist/observability/metrics.js +490 -0
  198. package/dist/observability/metrics.js.map +1 -0
  199. package/dist/observability/preset.d.ts +161 -0
  200. package/dist/observability/preset.d.ts.map +1 -0
  201. package/dist/observability/preset.js +133 -0
  202. package/dist/observability/preset.js.map +1 -0
  203. package/dist/observability/streaming.d.ts +113 -0
  204. package/dist/observability/streaming.d.ts.map +1 -0
  205. package/dist/observability/streaming.js +114 -0
  206. package/dist/observability/streaming.js.map +1 -0
  207. package/dist/observability/tracing.d.ts +378 -0
  208. package/dist/observability/tracing.d.ts.map +1 -0
  209. package/dist/observability/tracing.js +539 -0
  210. package/dist/observability/tracing.js.map +1 -0
  211. package/dist/plugins.d.ts +55 -0
  212. package/dist/plugins.d.ts.map +1 -0
  213. package/dist/plugins.js +63 -0
  214. package/dist/plugins.js.map +1 -0
  215. package/dist/presets/index.d.ts +7 -0
  216. package/dist/presets/index.d.ts.map +1 -0
  217. package/dist/presets/index.js +7 -0
  218. package/dist/presets/index.js.map +1 -0
  219. package/dist/presets/production.d.ts +262 -0
  220. package/dist/presets/production.d.ts.map +1 -0
  221. package/dist/presets/production.js +295 -0
  222. package/dist/presets/production.js.map +1 -0
  223. package/dist/security/index.d.ts +179 -0
  224. package/dist/security/index.d.ts.map +1 -0
  225. package/dist/security/index.js +323 -0
  226. package/dist/security/index.js.map +1 -0
  227. package/dist/subagents/advanced.d.ts +413 -0
  228. package/dist/subagents/advanced.d.ts.map +1 -0
  229. package/dist/subagents/advanced.js +396 -0
  230. package/dist/subagents/advanced.js.map +1 -0
  231. package/dist/subagents/index.d.ts +14 -0
  232. package/dist/subagents/index.d.ts.map +1 -0
  233. package/dist/subagents/index.js +15 -0
  234. package/dist/subagents/index.js.map +1 -0
  235. package/dist/subagents.d.ts +73 -0
  236. package/dist/subagents.d.ts.map +1 -0
  237. package/dist/subagents.js +213 -0
  238. package/dist/subagents.js.map +1 -0
  239. package/dist/task-store/file-store.d.ts +76 -0
  240. package/dist/task-store/file-store.d.ts.map +1 -0
  241. package/dist/task-store/file-store.js +190 -0
  242. package/dist/task-store/file-store.js.map +1 -0
  243. package/dist/task-store/index.d.ts +11 -0
  244. package/dist/task-store/index.d.ts.map +1 -0
  245. package/dist/task-store/index.js +10 -0
  246. package/dist/task-store/index.js.map +1 -0
  247. package/dist/task-store/kv-store.d.ts +140 -0
  248. package/dist/task-store/kv-store.d.ts.map +1 -0
  249. package/dist/task-store/kv-store.js +169 -0
  250. package/dist/task-store/kv-store.js.map +1 -0
  251. package/dist/task-store/memory-store.d.ts +66 -0
  252. package/dist/task-store/memory-store.d.ts.map +1 -0
  253. package/dist/task-store/memory-store.js +125 -0
  254. package/dist/task-store/memory-store.js.map +1 -0
  255. package/dist/task-store/types.d.ts +235 -0
  256. package/dist/task-store/types.d.ts.map +1 -0
  257. package/dist/task-store/types.js +110 -0
  258. package/dist/task-store/types.js.map +1 -0
  259. package/dist/testing/assertions.d.ts +401 -0
  260. package/dist/testing/assertions.d.ts.map +1 -0
  261. package/dist/testing/assertions.js +630 -0
  262. package/dist/testing/assertions.js.map +1 -0
  263. package/dist/testing/index.d.ts +343 -0
  264. package/dist/testing/index.d.ts.map +1 -0
  265. package/dist/testing/index.js +360 -0
  266. package/dist/testing/index.js.map +1 -0
  267. package/dist/testing/mock-agent.d.ts +214 -0
  268. package/dist/testing/mock-agent.d.ts.map +1 -0
  269. package/dist/testing/mock-agent.js +448 -0
  270. package/dist/testing/mock-agent.js.map +1 -0
  271. package/dist/testing/recorder.d.ts +288 -0
  272. package/dist/testing/recorder.d.ts.map +1 -0
  273. package/dist/testing/recorder.js +499 -0
  274. package/dist/testing/recorder.js.map +1 -0
  275. package/dist/tools/execute.d.ts +104 -0
  276. package/dist/tools/execute.d.ts.map +1 -0
  277. package/dist/tools/execute.js +191 -0
  278. package/dist/tools/execute.js.map +1 -0
  279. package/dist/tools/factory.d.ts +260 -0
  280. package/dist/tools/factory.d.ts.map +1 -0
  281. package/dist/tools/factory.js +241 -0
  282. package/dist/tools/factory.js.map +1 -0
  283. package/dist/tools/filesystem.d.ts +215 -0
  284. package/dist/tools/filesystem.d.ts.map +1 -0
  285. package/dist/tools/filesystem.js +311 -0
  286. package/dist/tools/filesystem.js.map +1 -0
  287. package/dist/tools/index.d.ts +33 -0
  288. package/dist/tools/index.d.ts.map +1 -0
  289. package/dist/tools/index.js +33 -0
  290. package/dist/tools/index.js.map +1 -0
  291. package/dist/tools/search.d.ts +59 -0
  292. package/dist/tools/search.d.ts.map +1 -0
  293. package/dist/tools/search.js +94 -0
  294. package/dist/tools/search.js.map +1 -0
  295. package/dist/tools/skills.d.ts +354 -0
  296. package/dist/tools/skills.d.ts.map +1 -0
  297. package/dist/tools/skills.js +413 -0
  298. package/dist/tools/skills.js.map +1 -0
  299. package/dist/tools/task.d.ts +272 -0
  300. package/dist/tools/task.d.ts.map +1 -0
  301. package/dist/tools/task.js +521 -0
  302. package/dist/tools/task.js.map +1 -0
  303. package/dist/tools/todos.d.ts +131 -0
  304. package/dist/tools/todos.d.ts.map +1 -0
  305. package/dist/tools/todos.js +120 -0
  306. package/dist/tools/todos.js.map +1 -0
  307. package/dist/tools/tool-registry.d.ts +424 -0
  308. package/dist/tools/tool-registry.d.ts.map +1 -0
  309. package/dist/tools/tool-registry.js +607 -0
  310. package/dist/tools/tool-registry.js.map +1 -0
  311. package/dist/tools/user-interaction.d.ts +116 -0
  312. package/dist/tools/user-interaction.d.ts.map +1 -0
  313. package/dist/tools/user-interaction.js +147 -0
  314. package/dist/tools/user-interaction.js.map +1 -0
  315. package/dist/tools/utils.d.ts +124 -0
  316. package/dist/tools/utils.d.ts.map +1 -0
  317. package/dist/tools/utils.js +189 -0
  318. package/dist/tools/utils.js.map +1 -0
  319. package/dist/tools.d.ts +74 -0
  320. package/dist/tools.d.ts.map +1 -0
  321. package/dist/tools.js +73 -0
  322. package/dist/tools.js.map +1 -0
  323. package/dist/types.d.ts +2421 -0
  324. package/dist/types.d.ts.map +1 -0
  325. package/dist/types.js +55 -0
  326. package/dist/types.js.map +1 -0
  327. package/package.json +81 -0
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Composite backend that routes operations to different backends based on path prefixes.
3
+ *
4
+ * CompositeBackend allows you to combine multiple backends, routing operations to
5
+ * the appropriate backend based on the file path. This enables scenarios like:
6
+ * - Memory files from a StateBackend
7
+ * - Persistent files from a PersistentBackend
8
+ * - Real filesystem access for specific directories
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const state = createAgentState();
13
+ * const backend = new CompositeBackend(
14
+ * new StateBackend(state), // Default for unmatched paths
15
+ * {
16
+ * '/memories/': new PersistentBackend({ store }),
17
+ * '/workspace/': new FilesystemBackend({ rootDir: './workspace' }),
18
+ * }
19
+ * );
20
+ *
21
+ * // Routes to PersistentBackend
22
+ * await backend.write('/memories/user-prefs.json', '{}');
23
+ *
24
+ * // Routes to FilesystemBackend
25
+ * await backend.read('/workspace/src/index.ts');
26
+ *
27
+ * // Routes to StateBackend (default)
28
+ * await backend.write('/scratch/notes.txt', 'temp notes');
29
+ * ```
30
+ *
31
+ * @packageDocumentation
32
+ */
33
+ import type { BackendProtocol, EditResult, FileData, FileInfo, GrepMatch, WriteResult } from "../backend.js";
34
+ /**
35
+ * Configuration for routing paths to backends.
36
+ *
37
+ * Keys are path prefixes (should start with '/' and optionally end with '/').
38
+ * Values are the backends that handle those paths.
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const routes: RouteConfig = {
43
+ * '/memories/': persistentBackend,
44
+ * '/cache/': stateBackend,
45
+ * '/project/': filesystemBackend,
46
+ * };
47
+ * ```
48
+ *
49
+ * @category Backend
50
+ */
51
+ export type RouteConfig = Record<string, BackendProtocol>;
52
+ /**
53
+ * Options for creating a CompositeBackend.
54
+ *
55
+ * @category Backend
56
+ */
57
+ export interface CompositeBackendOptions {
58
+ /**
59
+ * The default backend for paths that don't match any route.
60
+ */
61
+ defaultBackend: BackendProtocol;
62
+ /**
63
+ * Route configuration mapping path prefixes to backends.
64
+ */
65
+ routes: RouteConfig;
66
+ }
67
+ /**
68
+ * A backend that routes operations to different backends based on path prefixes.
69
+ *
70
+ * Routes are matched by longest-prefix first. For example, if you have routes for
71
+ * `/memories/` and `/memories/archived/`, a path like `/memories/archived/old.txt`
72
+ * will route to the `/memories/archived/` backend.
73
+ *
74
+ * For aggregate operations (glob, grep), results are collected from all backends
75
+ * and merged together.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const backend = new CompositeBackend(
80
+ * new StateBackend(state),
81
+ * {
82
+ * '/memories/': new PersistentBackend({ store }),
83
+ * '/project/': new FilesystemBackend({ rootDir: './project' }),
84
+ * }
85
+ * );
86
+ *
87
+ * // Write to different backends based on path
88
+ * await backend.write('/memories/notes.md', '# Notes'); // PersistentBackend
89
+ * await backend.write('/project/src/app.ts', '...'); // FilesystemBackend
90
+ * await backend.write('/temp/scratch.txt', '...'); // StateBackend (default)
91
+ *
92
+ * // Glob across all backends
93
+ * const allFiles = await backend.globInfo('**\/*.ts');
94
+ * ```
95
+ *
96
+ * @category Backend
97
+ */
98
+ export declare class CompositeBackend implements BackendProtocol {
99
+ private readonly defaultBackend;
100
+ private readonly routes;
101
+ /**
102
+ * Create a new CompositeBackend.
103
+ *
104
+ * @param defaultBackend - Backend for paths that don't match any route
105
+ * @param routes - Map of path prefixes to backends
106
+ */
107
+ constructor(defaultBackend: BackendProtocol, routes: RouteConfig);
108
+ /**
109
+ * List files and directories at the given path.
110
+ *
111
+ * Routes to the appropriate backend based on path prefix.
112
+ *
113
+ * @param path - Directory path to list
114
+ * @returns Array of file/directory info
115
+ */
116
+ lsInfo(path: string): Promise<FileInfo[]>;
117
+ /**
118
+ * Read file content with optional line numbers.
119
+ *
120
+ * @param filePath - Path to the file to read
121
+ * @param offset - Starting line offset (0-indexed)
122
+ * @param limit - Maximum number of lines to read
123
+ * @returns Formatted content with line numbers
124
+ */
125
+ read(filePath: string, offset?: number, limit?: number): Promise<string>;
126
+ /**
127
+ * Read raw file content as FileData.
128
+ *
129
+ * @param filePath - Path to the file to read
130
+ * @returns Raw file data with content and timestamps
131
+ */
132
+ readRaw(filePath: string): Promise<FileData>;
133
+ /**
134
+ * Search for pattern matches using regex across all backends.
135
+ *
136
+ * Results are aggregated from all backends. Each backend's grep
137
+ * is limited to its own path scope.
138
+ *
139
+ * @param pattern - Regular expression pattern to search for
140
+ * @param path - Directory to search in (defaults to root)
141
+ * @param glob - Glob pattern to filter files
142
+ * @returns Array of matches from all backends
143
+ */
144
+ grepRaw(pattern: string, path?: string | null, glob?: string | null): Promise<GrepMatch[]>;
145
+ /**
146
+ * Find files matching a glob pattern across all backends.
147
+ *
148
+ * Results are aggregated from all backends that could contain
149
+ * matching files.
150
+ *
151
+ * @param pattern - Glob pattern
152
+ * @param path - Base directory for the search
153
+ * @returns Array of matching file info from all backends
154
+ */
155
+ globInfo(pattern: string, path?: string): Promise<FileInfo[]>;
156
+ /**
157
+ * Create or overwrite a file.
158
+ *
159
+ * Routes to the appropriate backend based on path prefix.
160
+ *
161
+ * @param filePath - Path for the new file
162
+ * @param content - Content to write
163
+ * @returns Result indicating success or failure
164
+ */
165
+ write(filePath: string, content: string): Promise<WriteResult>;
166
+ /**
167
+ * Edit a file by replacing text.
168
+ *
169
+ * Routes to the appropriate backend based on path prefix.
170
+ *
171
+ * @param filePath - Path to the file to edit
172
+ * @param oldString - Text to find and replace
173
+ * @param newString - Replacement text
174
+ * @param replaceAll - If true, replace all occurrences
175
+ * @returns Result indicating success or failure
176
+ */
177
+ edit(filePath: string, oldString: string, newString: string, replaceAll?: boolean): Promise<EditResult>;
178
+ /**
179
+ * Get the backend that handles a specific path.
180
+ *
181
+ * Useful for debugging or when you need direct access to a specific backend.
182
+ *
183
+ * @param path - Path to check
184
+ * @returns The backend that handles this path
185
+ */
186
+ getBackendForPath(path: string): BackendProtocol;
187
+ /**
188
+ * Get all configured routes.
189
+ *
190
+ * @returns Array of route configurations sorted by prefix length (longest first)
191
+ */
192
+ getRoutes(): Array<{
193
+ prefix: string;
194
+ backend: BackendProtocol;
195
+ }>;
196
+ /**
197
+ * Get the default backend.
198
+ *
199
+ * @returns The default backend for unmatched paths
200
+ */
201
+ getDefaultBackend(): BackendProtocol;
202
+ /**
203
+ * Normalize a route prefix.
204
+ * @internal
205
+ */
206
+ private normalizePrefix;
207
+ /**
208
+ * Normalize a path.
209
+ * @internal
210
+ */
211
+ private normalizePath;
212
+ /**
213
+ * Find the matching route for a path using longest-prefix matching.
214
+ * @internal
215
+ */
216
+ private findMatchingRoute;
217
+ /**
218
+ * Resolve which backend handles a path and return the relative path.
219
+ * @internal
220
+ */
221
+ private resolveBackend;
222
+ /**
223
+ * Convert a composite path to a relative path for the backend.
224
+ * @internal
225
+ */
226
+ private toRelativePath;
227
+ /**
228
+ * Convert a backend-relative path to a composite path.
229
+ * @internal
230
+ */
231
+ private toCompositePath;
232
+ /**
233
+ * Check if parentPath is a parent of (or equal to) childPath.
234
+ * @internal
235
+ */
236
+ private isParentPath;
237
+ }
238
+ /**
239
+ * Create a CompositeBackend from options.
240
+ *
241
+ * @param options - Configuration options
242
+ * @returns A new CompositeBackend
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * const backend = createCompositeBackend({
247
+ * defaultBackend: new StateBackend(state),
248
+ * routes: {
249
+ * '/memories/': persistentBackend,
250
+ * '/workspace/': filesystemBackend,
251
+ * },
252
+ * });
253
+ * ```
254
+ *
255
+ * @category Backend
256
+ */
257
+ export declare function createCompositeBackend(options: CompositeBackendOptions): CompositeBackend;
258
+ //# sourceMappingURL=composite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../../src/backends/composite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,WAAW,EACZ,MAAM,eAAe,CAAC;AAMvB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,cAAc,EAAE,eAAe,CAAC;IAEhC;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;CACrB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsD;IAE7E;;;;;OAKG;gBACS,cAAc,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW;IAYhE;;;;;;;OAOG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAgB/C;;;;;;;OAOG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK9E;;;;;OAKG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKlD;;;;;;;;;;OAUG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAyDhG;;;;;;;;;OASG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAoDnE;;;;;;;;OAQG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAepE;;;;;;;;;;OAUG;IACG,IAAI,CACR,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,OAAO,GACnB,OAAO,CAAC,UAAU,CAAC;IAmBtB;;;;;;;OAOG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAIhD;;;;OAIG;IACH,SAAS,IAAI,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,CAAC;IAIhE;;;;OAIG;IACH,iBAAiB,IAAI,eAAe;IAQpC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAQvB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAOrB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAmBtB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAkBtB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAavB;;;OAGG;IACH,OAAO,CAAC,YAAY;CAgBrB;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CAEzF"}
@@ -0,0 +1,437 @@
1
+ /**
2
+ * Composite backend that routes operations to different backends based on path prefixes.
3
+ *
4
+ * CompositeBackend allows you to combine multiple backends, routing operations to
5
+ * the appropriate backend based on the file path. This enables scenarios like:
6
+ * - Memory files from a StateBackend
7
+ * - Persistent files from a PersistentBackend
8
+ * - Real filesystem access for specific directories
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const state = createAgentState();
13
+ * const backend = new CompositeBackend(
14
+ * new StateBackend(state), // Default for unmatched paths
15
+ * {
16
+ * '/memories/': new PersistentBackend({ store }),
17
+ * '/workspace/': new FilesystemBackend({ rootDir: './workspace' }),
18
+ * }
19
+ * );
20
+ *
21
+ * // Routes to PersistentBackend
22
+ * await backend.write('/memories/user-prefs.json', '{}');
23
+ *
24
+ * // Routes to FilesystemBackend
25
+ * await backend.read('/workspace/src/index.ts');
26
+ *
27
+ * // Routes to StateBackend (default)
28
+ * await backend.write('/scratch/notes.txt', 'temp notes');
29
+ * ```
30
+ *
31
+ * @packageDocumentation
32
+ */
33
+ // =============================================================================
34
+ // Composite Backend Implementation
35
+ // =============================================================================
36
+ /**
37
+ * A backend that routes operations to different backends based on path prefixes.
38
+ *
39
+ * Routes are matched by longest-prefix first. For example, if you have routes for
40
+ * `/memories/` and `/memories/archived/`, a path like `/memories/archived/old.txt`
41
+ * will route to the `/memories/archived/` backend.
42
+ *
43
+ * For aggregate operations (glob, grep), results are collected from all backends
44
+ * and merged together.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const backend = new CompositeBackend(
49
+ * new StateBackend(state),
50
+ * {
51
+ * '/memories/': new PersistentBackend({ store }),
52
+ * '/project/': new FilesystemBackend({ rootDir: './project' }),
53
+ * }
54
+ * );
55
+ *
56
+ * // Write to different backends based on path
57
+ * await backend.write('/memories/notes.md', '# Notes'); // PersistentBackend
58
+ * await backend.write('/project/src/app.ts', '...'); // FilesystemBackend
59
+ * await backend.write('/temp/scratch.txt', '...'); // StateBackend (default)
60
+ *
61
+ * // Glob across all backends
62
+ * const allFiles = await backend.globInfo('**\/*.ts');
63
+ * ```
64
+ *
65
+ * @category Backend
66
+ */
67
+ export class CompositeBackend {
68
+ defaultBackend;
69
+ routes;
70
+ /**
71
+ * Create a new CompositeBackend.
72
+ *
73
+ * @param defaultBackend - Backend for paths that don't match any route
74
+ * @param routes - Map of path prefixes to backends
75
+ */
76
+ constructor(defaultBackend, routes) {
77
+ this.defaultBackend = defaultBackend;
78
+ // Sort routes by prefix length descending for longest-prefix matching
79
+ this.routes = Object.entries(routes)
80
+ .map(([prefix, backend]) => ({
81
+ prefix: this.normalizePrefix(prefix),
82
+ backend,
83
+ }))
84
+ .sort((a, b) => b.prefix.length - a.prefix.length);
85
+ }
86
+ /**
87
+ * List files and directories at the given path.
88
+ *
89
+ * Routes to the appropriate backend based on path prefix.
90
+ *
91
+ * @param path - Directory path to list
92
+ * @returns Array of file/directory info
93
+ */
94
+ async lsInfo(path) {
95
+ const { backend, relativePath } = this.resolveBackend(path);
96
+ const results = await backend.lsInfo(relativePath);
97
+ // Map paths back to composite paths
98
+ const route = this.findMatchingRoute(path);
99
+ if (route) {
100
+ return results.map((info) => ({
101
+ ...info,
102
+ path: this.toCompositePath(info.path, route.prefix),
103
+ }));
104
+ }
105
+ return results;
106
+ }
107
+ /**
108
+ * Read file content with optional line numbers.
109
+ *
110
+ * @param filePath - Path to the file to read
111
+ * @param offset - Starting line offset (0-indexed)
112
+ * @param limit - Maximum number of lines to read
113
+ * @returns Formatted content with line numbers
114
+ */
115
+ async read(filePath, offset, limit) {
116
+ const { backend, relativePath } = this.resolveBackend(filePath);
117
+ return backend.read(relativePath, offset, limit);
118
+ }
119
+ /**
120
+ * Read raw file content as FileData.
121
+ *
122
+ * @param filePath - Path to the file to read
123
+ * @returns Raw file data with content and timestamps
124
+ */
125
+ async readRaw(filePath) {
126
+ const { backend, relativePath } = this.resolveBackend(filePath);
127
+ return backend.readRaw(relativePath);
128
+ }
129
+ /**
130
+ * Search for pattern matches using regex across all backends.
131
+ *
132
+ * Results are aggregated from all backends. Each backend's grep
133
+ * is limited to its own path scope.
134
+ *
135
+ * @param pattern - Regular expression pattern to search for
136
+ * @param path - Directory to search in (defaults to root)
137
+ * @param glob - Glob pattern to filter files
138
+ * @returns Array of matches from all backends
139
+ */
140
+ async grepRaw(pattern, path, glob) {
141
+ const searchPath = path ?? "/";
142
+ // Collect results from all relevant backends
143
+ const allMatches = [];
144
+ // Check if path targets a specific backend
145
+ const route = this.findMatchingRoute(searchPath);
146
+ if (route) {
147
+ // Single backend search
148
+ const relativePath = this.toRelativePath(searchPath, route.prefix);
149
+ const results = await route.backend.grepRaw(pattern, relativePath, glob);
150
+ const matches = typeof results === "string" ? [] : results;
151
+ allMatches.push(...matches.map((m) => ({
152
+ ...m,
153
+ path: this.toCompositePath(m.path, route.prefix),
154
+ })));
155
+ }
156
+ else {
157
+ // Search across all backends
158
+ const searchPromises = [];
159
+ // Search default backend
160
+ searchPromises.push(Promise.resolve(this.defaultBackend.grepRaw(pattern, searchPath, glob))
161
+ .then((results) => (typeof results === "string" ? [] : results))
162
+ .catch(() => []));
163
+ // Search each routed backend if the search path is a parent of the route
164
+ for (const { prefix, backend } of this.routes) {
165
+ if (this.isParentPath(searchPath, prefix)) {
166
+ const relativePath = searchPath === "/" ? "/" : this.toRelativePath(prefix, searchPath);
167
+ searchPromises.push(Promise.resolve(backend.grepRaw(pattern, relativePath, glob))
168
+ .then((results) => (typeof results === "string" ? [] : results))
169
+ .then((matches) => matches.map((m) => ({
170
+ ...m,
171
+ path: this.toCompositePath(m.path, prefix),
172
+ })))
173
+ .catch(() => []));
174
+ }
175
+ }
176
+ const allResults = await Promise.all(searchPromises);
177
+ for (const results of allResults) {
178
+ allMatches.push(...results);
179
+ }
180
+ }
181
+ return allMatches;
182
+ }
183
+ /**
184
+ * Find files matching a glob pattern across all backends.
185
+ *
186
+ * Results are aggregated from all backends that could contain
187
+ * matching files.
188
+ *
189
+ * @param pattern - Glob pattern
190
+ * @param path - Base directory for the search
191
+ * @returns Array of matching file info from all backends
192
+ */
193
+ async globInfo(pattern, path) {
194
+ const searchPath = path ?? "/";
195
+ // Collect results from all relevant backends
196
+ const allFiles = [];
197
+ // Check if path targets a specific backend
198
+ const route = this.findMatchingRoute(searchPath);
199
+ if (route) {
200
+ // Single backend search
201
+ const relativePath = this.toRelativePath(searchPath, route.prefix);
202
+ const results = await route.backend.globInfo(pattern, relativePath);
203
+ allFiles.push(...results.map((f) => ({
204
+ ...f,
205
+ path: this.toCompositePath(f.path, route.prefix),
206
+ })));
207
+ }
208
+ else {
209
+ // Search across all backends
210
+ const searchPromises = [];
211
+ // Search default backend
212
+ searchPromises.push(Promise.resolve(this.defaultBackend.globInfo(pattern, searchPath)).catch(() => []));
213
+ // Search each routed backend if the search path is a parent of the route
214
+ for (const { prefix, backend } of this.routes) {
215
+ if (this.isParentPath(searchPath, prefix)) {
216
+ searchPromises.push(Promise.resolve(backend.globInfo(pattern, "/"))
217
+ .then((files) => files.map((f) => ({
218
+ ...f,
219
+ path: this.toCompositePath(f.path, prefix),
220
+ })))
221
+ .catch(() => []));
222
+ }
223
+ }
224
+ const allResults = await Promise.all(searchPromises);
225
+ for (const results of allResults) {
226
+ allFiles.push(...results);
227
+ }
228
+ }
229
+ return allFiles;
230
+ }
231
+ /**
232
+ * Create or overwrite a file.
233
+ *
234
+ * Routes to the appropriate backend based on path prefix.
235
+ *
236
+ * @param filePath - Path for the new file
237
+ * @param content - Content to write
238
+ * @returns Result indicating success or failure
239
+ */
240
+ async write(filePath, content) {
241
+ const { backend, relativePath } = this.resolveBackend(filePath);
242
+ const result = await backend.write(relativePath, content);
243
+ // Map the path back if needed
244
+ if (result.path) {
245
+ const route = this.findMatchingRoute(filePath);
246
+ if (route) {
247
+ result.path = this.toCompositePath(result.path, route.prefix);
248
+ }
249
+ }
250
+ return result;
251
+ }
252
+ /**
253
+ * Edit a file by replacing text.
254
+ *
255
+ * Routes to the appropriate backend based on path prefix.
256
+ *
257
+ * @param filePath - Path to the file to edit
258
+ * @param oldString - Text to find and replace
259
+ * @param newString - Replacement text
260
+ * @param replaceAll - If true, replace all occurrences
261
+ * @returns Result indicating success or failure
262
+ */
263
+ async edit(filePath, oldString, newString, replaceAll) {
264
+ const { backend, relativePath } = this.resolveBackend(filePath);
265
+ const result = await backend.edit(relativePath, oldString, newString, replaceAll);
266
+ // Map the path back if needed
267
+ if (result.path) {
268
+ const route = this.findMatchingRoute(filePath);
269
+ if (route) {
270
+ result.path = this.toCompositePath(result.path, route.prefix);
271
+ }
272
+ }
273
+ return result;
274
+ }
275
+ // ===========================================================================
276
+ // Public Utility Methods
277
+ // ===========================================================================
278
+ /**
279
+ * Get the backend that handles a specific path.
280
+ *
281
+ * Useful for debugging or when you need direct access to a specific backend.
282
+ *
283
+ * @param path - Path to check
284
+ * @returns The backend that handles this path
285
+ */
286
+ getBackendForPath(path) {
287
+ return this.resolveBackend(path).backend;
288
+ }
289
+ /**
290
+ * Get all configured routes.
291
+ *
292
+ * @returns Array of route configurations sorted by prefix length (longest first)
293
+ */
294
+ getRoutes() {
295
+ return [...this.routes];
296
+ }
297
+ /**
298
+ * Get the default backend.
299
+ *
300
+ * @returns The default backend for unmatched paths
301
+ */
302
+ getDefaultBackend() {
303
+ return this.defaultBackend;
304
+ }
305
+ // ===========================================================================
306
+ // Private Helpers
307
+ // ===========================================================================
308
+ /**
309
+ * Normalize a route prefix.
310
+ * @internal
311
+ */
312
+ normalizePrefix(prefix) {
313
+ let normalized = prefix.startsWith("/") ? prefix : `/${prefix}`;
314
+ if (!normalized.endsWith("/")) {
315
+ normalized += "/";
316
+ }
317
+ return normalized;
318
+ }
319
+ /**
320
+ * Normalize a path.
321
+ * @internal
322
+ */
323
+ normalizePath(path) {
324
+ let normalized = path.startsWith("/") ? path : `/${path}`;
325
+ // Collapse multiple slashes
326
+ normalized = normalized.replace(/\/+/g, "/");
327
+ return normalized;
328
+ }
329
+ /**
330
+ * Find the matching route for a path using longest-prefix matching.
331
+ * @internal
332
+ */
333
+ findMatchingRoute(path) {
334
+ const normalizedPath = this.normalizePath(path);
335
+ // Ensure we match with trailing slash for prefix matching
336
+ const pathWithSlash = normalizedPath.endsWith("/") ? normalizedPath : `${normalizedPath}/`;
337
+ // Routes are already sorted by length descending
338
+ for (const route of this.routes) {
339
+ if (pathWithSlash.startsWith(route.prefix) || normalizedPath === route.prefix.slice(0, -1)) {
340
+ return route;
341
+ }
342
+ }
343
+ return undefined;
344
+ }
345
+ /**
346
+ * Resolve which backend handles a path and return the relative path.
347
+ * @internal
348
+ */
349
+ resolveBackend(path) {
350
+ const route = this.findMatchingRoute(path);
351
+ if (route) {
352
+ return {
353
+ backend: route.backend,
354
+ relativePath: this.toRelativePath(path, route.prefix),
355
+ };
356
+ }
357
+ return {
358
+ backend: this.defaultBackend,
359
+ relativePath: this.normalizePath(path),
360
+ };
361
+ }
362
+ /**
363
+ * Convert a composite path to a relative path for the backend.
364
+ * @internal
365
+ */
366
+ toRelativePath(compositePath, prefix) {
367
+ const normalizedPath = this.normalizePath(compositePath);
368
+ // If path equals prefix (without trailing slash), return root
369
+ if (normalizedPath === prefix.slice(0, -1)) {
370
+ return "/";
371
+ }
372
+ // Remove the prefix
373
+ if (normalizedPath.startsWith(prefix)) {
374
+ const relative = normalizedPath.slice(prefix.length);
375
+ return relative.startsWith("/") ? relative : `/${relative}`;
376
+ }
377
+ // Path doesn't start with prefix, return as-is
378
+ return normalizedPath;
379
+ }
380
+ /**
381
+ * Convert a backend-relative path to a composite path.
382
+ * @internal
383
+ */
384
+ toCompositePath(relativePath, prefix) {
385
+ const normalizedRelative = this.normalizePath(relativePath);
386
+ // If relative path is root, return prefix without trailing slash
387
+ if (normalizedRelative === "/") {
388
+ return prefix.slice(0, -1);
389
+ }
390
+ // Combine prefix and relative path
391
+ const combined = prefix + normalizedRelative.slice(1);
392
+ return combined;
393
+ }
394
+ /**
395
+ * Check if parentPath is a parent of (or equal to) childPath.
396
+ * @internal
397
+ */
398
+ isParentPath(parentPath, childPath) {
399
+ const normalizedParent = this.normalizePath(parentPath);
400
+ const normalizedChild = this.normalizePath(childPath);
401
+ // Root is parent of everything
402
+ if (normalizedParent === "/") {
403
+ return true;
404
+ }
405
+ // Check if child starts with parent
406
+ const parentWithSlash = normalizedParent.endsWith("/")
407
+ ? normalizedParent
408
+ : `${normalizedParent}/`;
409
+ return normalizedChild.startsWith(parentWithSlash) || normalizedChild === normalizedParent;
410
+ }
411
+ }
412
+ // =============================================================================
413
+ // Factory Function
414
+ // =============================================================================
415
+ /**
416
+ * Create a CompositeBackend from options.
417
+ *
418
+ * @param options - Configuration options
419
+ * @returns A new CompositeBackend
420
+ *
421
+ * @example
422
+ * ```typescript
423
+ * const backend = createCompositeBackend({
424
+ * defaultBackend: new StateBackend(state),
425
+ * routes: {
426
+ * '/memories/': persistentBackend,
427
+ * '/workspace/': filesystemBackend,
428
+ * },
429
+ * });
430
+ * ```
431
+ *
432
+ * @category Backend
433
+ */
434
+ export function createCompositeBackend(options) {
435
+ return new CompositeBackend(options.defaultBackend, options.routes);
436
+ }
437
+ //# sourceMappingURL=composite.js.map