@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
package/README.md ADDED
@@ -0,0 +1,2321 @@
1
+ # @lleverage-ai/agent-sdk
2
+
3
+ A TypeScript framework for building AI agents using the Vercel AI SDK v6.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Quick Start](#quick-start)
9
+ - [Core Concepts](#core-concepts)
10
+ - [Agents](#agents)
11
+ - [Tools](#tools)
12
+ - [Plugins](#plugins)
13
+ - [Skills](#skills)
14
+ - [Hooks](#hooks)
15
+ - [Tool Loading Strategies](#tool-loading-strategies)
16
+ - [Subagents](#subagents)
17
+ - [Streaming](#streaming)
18
+ - [MCP Integration](#mcp-integration)
19
+ - [Backends](#backends)
20
+ - [Middleware](#middleware)
21
+ - [Observability](#observability)
22
+ - [Memory](#memory)
23
+ - [Checkpointing](#checkpointing)
24
+ - [Context Compaction](#context-compaction)
25
+ - [Error Handling](#error-handling)
26
+ - [API Reference](#api-reference)
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ bun add @lleverage-ai/agent-sdk ai zod
32
+ ```
33
+
34
+ You'll also need at least one AI provider:
35
+
36
+ ```bash
37
+ bun add @ai-sdk/anthropic # or @ai-sdk/openai
38
+ ```
39
+
40
+ **React Integration:** If you're building React applications, install the React companion package for UI helpers:
41
+
42
+ ```bash
43
+ bun add @lleverage-ai/agent-sdk-react react
44
+ ```
45
+
46
+ See the [@lleverage-ai/agent-sdk-react README](../agent-sdk-react/README.md) for documentation on `useApprovalFlow` hook and `ApprovalDialog` component.
47
+
48
+ ## Quick Start
49
+
50
+ ```typescript
51
+ import { createAgent } from "@lleverage-ai/agent-sdk";
52
+ import { anthropic } from "@ai-sdk/anthropic";
53
+ import { tool } from "ai";
54
+ import { z } from "zod";
55
+
56
+ const agent = createAgent({
57
+ model: anthropic("claude-sonnet-4-20250514"),
58
+ systemPrompt: "You are a friendly assistant.",
59
+ tools: {
60
+ greet: tool({
61
+ description: "Greet a person by name",
62
+ inputSchema: z.object({
63
+ name: z.string().describe("The name of the person to greet"),
64
+ }),
65
+ execute: async ({ name }) => `Hello, ${name}!`,
66
+ }),
67
+ },
68
+ });
69
+
70
+ const result = await agent.generate({
71
+ prompt: "Say hello to Alice",
72
+ });
73
+
74
+ console.log(result.text);
75
+ ```
76
+
77
+ ## Core Concepts
78
+
79
+ ### Agents
80
+
81
+ Agents combine a language model with tools, plugins, and hooks. Core tools for filesystem operations and task tracking are automatically included.
82
+
83
+ ```typescript
84
+ const agent = createAgent({
85
+ model: anthropic("claude-sonnet-4-20250514"),
86
+ systemPrompt: "You are a helpful assistant.",
87
+ maxSteps: 10,
88
+ tools: {
89
+ /* custom tools */
90
+ },
91
+ plugins: [
92
+ /* plugins */
93
+ ],
94
+ });
95
+
96
+ // Disable specific core tools if needed:
97
+ const safeAgent = createAgent({
98
+ model,
99
+ disabledCoreTools: ["bash", "write"], // No shell or write access
100
+ });
101
+ ```
102
+
103
+ **Core tools included:** `read`, `write`, `edit`, `glob`, `grep`, `todo_write`, `bash` (requires sandbox), `search_tools` (when enabled)
104
+
105
+ ### Tools
106
+
107
+ Tools use the AI SDK's `tool()` function with `inputSchema`:
108
+
109
+ ```typescript
110
+ import { tool } from "ai";
111
+ import { z } from "zod";
112
+
113
+ const calculator = tool({
114
+ description: "Perform basic math operations",
115
+ inputSchema: z.object({
116
+ operation: z.enum(["add", "subtract", "multiply", "divide"]),
117
+ a: z.number(),
118
+ b: z.number(),
119
+ }),
120
+ execute: async ({ operation, a, b }) => {
121
+ switch (operation) {
122
+ case "add":
123
+ return a + b;
124
+ case "subtract":
125
+ return a - b;
126
+ case "multiply":
127
+ return a * b;
128
+ case "divide":
129
+ return a / b;
130
+ }
131
+ },
132
+ });
133
+
134
+ const agent = createAgent({
135
+ model,
136
+ tools: { calculator },
137
+ });
138
+ ```
139
+
140
+ ### Plugins
141
+
142
+ Plugins bundle tools, skills, and hooks. Plugin tools are exposed with MCP naming: `mcp__<plugin>__<tool>`.
143
+
144
+ ```typescript
145
+ import { definePlugin } from "@lleverage-ai/agent-sdk";
146
+
147
+ const myPlugin = definePlugin({
148
+ name: "my-plugin",
149
+ description: "A collection of useful tools",
150
+ tools: {
151
+ myTool: tool({
152
+ description: "Does something useful",
153
+ inputSchema: z.object({ input: z.string() }),
154
+ execute: async ({ input }) => `Result: ${input}`,
155
+ }),
156
+ },
157
+ skills: [
158
+ /* skills */
159
+ ],
160
+ hooks: [
161
+ /* hooks */
162
+ ],
163
+ setup: async (agent) => {
164
+ // Initialization logic
165
+ },
166
+ });
167
+
168
+ const agent = createAgent({
169
+ model,
170
+ plugins: [myPlugin],
171
+ });
172
+
173
+ // Plugin tool available as: mcp__my-plugin__myTool
174
+ ```
175
+
176
+ ### Skills
177
+
178
+ Skills provide contextual instructions that guide how the agent behaves. They can be used in several ways:
179
+
180
+ **Tool guidance** - Bundle a skill with plugin tools to explain how to use them:
181
+
182
+ ```typescript
183
+ const dataPlugin = definePlugin({
184
+ name: "data-explorer",
185
+ description: "Data exploration tools",
186
+ tools: { getSchema, queryData, createChart },
187
+ skills: [
188
+ defineSkill({
189
+ name: "data-exploration",
190
+ description: "Query and visualize data",
191
+ prompt: `You have access to data exploration tools.
192
+
193
+ Available tables: products, users, sales.
194
+ Always use getSchema first to see column types.`,
195
+ }),
196
+ ],
197
+ });
198
+ ```
199
+
200
+ **Instructions only** - A plugin with just a skill loads dynamic instructions (no tools):
201
+
202
+ ```typescript
203
+ const codingGuidelinesPlugin = definePlugin({
204
+ name: "coding-guidelines",
205
+ description: "Project coding standards",
206
+ skills: [
207
+ defineSkill({
208
+ name: "guidelines",
209
+ description: "Coding standards for this project",
210
+ prompt: `Follow these coding standards:
211
+ - Use TypeScript strict mode
212
+ - Prefer named exports
213
+ - Write TSDoc for public APIs`,
214
+ }),
215
+ ],
216
+ });
217
+ ```
218
+
219
+ **Progressive disclosure** - Skills with tools are loaded on-demand via the `skill` tool:
220
+
221
+ ```typescript
222
+ const analyzeSkill = defineSkill({
223
+ name: "analyze",
224
+ description: "Deep code analysis",
225
+ prompt: "Perform detailed code analysis.",
226
+ tools: {
227
+ lint: tool({
228
+ /* ... */
229
+ }),
230
+ typeCheck: tool({
231
+ /* ... */
232
+ }),
233
+ },
234
+ });
235
+ ```
236
+
237
+ ### Unified Hooks
238
+
239
+ Unified hooks allow you to observe and react to agent lifecycle events with a clean, typed API:
240
+
241
+ ```typescript
242
+ import { createAgent } from "@lleverage-ai/agent-sdk";
243
+
244
+ const agent = createAgent({
245
+ model,
246
+ hooks: {
247
+ PreGenerate: [
248
+ async ({ options }) => {
249
+ console.log("Starting generation...");
250
+ return {};
251
+ },
252
+ ],
253
+ PostGenerate: [
254
+ async ({ result }) => {
255
+ console.log("Generated:", result.text);
256
+ return {};
257
+ },
258
+ ],
259
+ PreToolUse: [
260
+ {
261
+ hooks: [
262
+ async ({ tool_name, tool_input }) => {
263
+ console.log("Tool starting:", tool_name, tool_input);
264
+ return {};
265
+ },
266
+ ],
267
+ },
268
+ ],
269
+ PostToolUse: [
270
+ {
271
+ hooks: [
272
+ async ({ tool_name, tool_response }) => {
273
+ console.log("Tool completed:", tool_name, tool_response);
274
+ return {};
275
+ },
276
+ ],
277
+ },
278
+ ],
279
+ PostToolUseFailure: [
280
+ {
281
+ hooks: [
282
+ async ({ tool_name, error }) => {
283
+ console.warn("Tool failed:", tool_name, error);
284
+ return {};
285
+ },
286
+ ],
287
+ },
288
+ ],
289
+ },
290
+ });
291
+ ```
292
+
293
+ **Available hooks:**
294
+
295
+ - `PreGenerate`, `PostGenerate`, `PostGenerateFailure` - Generation lifecycle
296
+ - `PreToolUse`, `PostToolUse`, `PostToolUseFailure` - Tool execution lifecycle
297
+ - `MCPConnectionFailed`, `MCPConnectionRestored` - MCP server connection lifecycle
298
+
299
+ **Hook utilities:**
300
+
301
+ - `createCacheHooks` - Response caching
302
+ - `createRetryHooks` - Automatic retries with backoff
303
+ - `createRateLimitHooks` - Rate limiting
304
+ - `createLoggingHooks` - Structured logging
305
+ - `createGuardrailsHooks` - Content guardrails
306
+ - `createSecretsFilterHooks` - Secrets redaction
307
+
308
+ **MCP Connection Monitoring:**
309
+
310
+ Monitor MCP server connectivity to handle failures and restorations:
311
+
312
+ ```typescript
313
+ const agent = createAgent({
314
+ model,
315
+ plugins: [githubPlugin],
316
+ hooks: {
317
+ MCPConnectionFailed: [
318
+ async ({ server_name, config, error, session_id }) => {
319
+ console.error(`MCP server ${server_name} failed:`, error.message);
320
+ // Send alert, log to monitoring system, etc.
321
+ },
322
+ ],
323
+ MCPConnectionRestored: [
324
+ async ({ server_name, tool_count, session_id }) => {
325
+ console.log(
326
+ `MCP server ${server_name} restored with ${tool_count} tools`,
327
+ );
328
+ // Clear alerts, update status, etc.
329
+ },
330
+ ],
331
+ },
332
+ });
333
+ ```
334
+
335
+ These hooks enable:
336
+
337
+ - **Observability**: Track MCP server health in logs and metrics
338
+ - **Alerting**: Send notifications when servers fail or recover
339
+ - **Graceful degradation**: Disable features that depend on unavailable servers
340
+ - **Debugging**: Understand connectivity issues in production
341
+
342
+ **Retry with Automatic Backoff:**
343
+
344
+ Handle transient failures with automatic retry logic:
345
+
346
+ ```typescript
347
+ import { createRetryHooks } from "@lleverage-ai/agent-sdk/hooks";
348
+
349
+ const agent = createAgent({
350
+ model,
351
+ hooks: {
352
+ PostGenerateFailure: [
353
+ createRetryHooks({
354
+ maxRetries: 3,
355
+ baseDelay: 1000, // 1 second
356
+ backoffMultiplier: 2, // Exponential: 1s, 2s, 4s
357
+ jitter: true, // Add randomness to prevent thundering herd
358
+ }),
359
+ ],
360
+ },
361
+ });
362
+ ```
363
+
364
+ The retry hook automatically handles:
365
+
366
+ - **Rate limiting**: Retries 429 errors with exponential backoff
367
+ - **Server errors**: Retries 5xx errors (500, 502, 503, 504)
368
+ - **Network failures**: Retries ECONNRESET, ECONNREFUSED, ETIMEDOUT
369
+ - **Timeout errors**: Retries timeout failures
370
+
371
+ **Retry statistics tracking:**
372
+
373
+ ```typescript
374
+ import { createManagedRetryHooks } from "@lleverage-ai/agent-sdk/hooks";
375
+
376
+ const { hook, getStats } = createManagedRetryHooks({ maxRetries: 5 });
377
+
378
+ const agent = createAgent({
379
+ model,
380
+ hooks: {
381
+ PostGenerateFailure: [hook],
382
+ },
383
+ });
384
+
385
+ // After some operations
386
+ const stats = getStats();
387
+ console.log(`Retry rate: ${stats.retries / stats.failures}`);
388
+ ```
389
+
390
+ **Custom retry logic:**
391
+
392
+ ```typescript
393
+ const retryHook = createRetryHooks({
394
+ shouldRetry: (error, attempt) => {
395
+ // Only retry rate limits on the first 2 attempts
396
+ return error.message.includes("rate limit") && attempt < 2;
397
+ },
398
+ baseDelay: 2000, // 2 seconds
399
+ });
400
+ ```
401
+
402
+ **Note:** Retry hooks work consistently across all agent methods (`generate()`, `stream()`, `streamResponse()`, `streamRaw()`, `streamDataResponse()`).
403
+
404
+ ## Tool Loading Strategies
405
+
406
+ The SDK provides multiple mechanisms for loading tools, each optimized for different scenarios:
407
+
408
+ - **Eager Loading** (default): Load all tools upfront - best for small tool sets (< 20 tools)
409
+ - **Lazy Loading** (`use_tools`): Load tools on-demand via a registry - best for 20-100+ tools
410
+ - **Dynamic Discovery** (`search_tools`): Search and load MCP tools dynamically - best for 100+ tools
411
+ - **MCP Loading**: Connect to external MCP servers for standardized tool ecosystems
412
+
413
+ ### When to Use Each Approach
414
+
415
+ **Use Eager Loading when:**
416
+
417
+ - Small tool set (< 20 tools) that's always needed
418
+ - Simplest setup with best performance
419
+ - All tools are core to the agent's purpose
420
+
421
+ **Use Lazy Loading when:**
422
+
423
+ - Large tool set (20-100+ tools)
424
+ - Agent only needs a subset per conversation
425
+ - Plugin architecture with domain-specific tools
426
+ - Want to minimize context window usage
427
+
428
+ **Use Dynamic Discovery when:**
429
+
430
+ - Very large tool set (100+ tools)
431
+ - Tool needs are unpredictable
432
+ - Using MCP ecosystem with many servers
433
+ - Want agent to explore capabilities dynamically
434
+
435
+ **Use MCP Loading when:**
436
+
437
+ - Integrating external tool ecosystems (filesystem, databases, APIs)
438
+ - Need standardized tool protocols
439
+ - Building on existing MCP infrastructure
440
+
441
+ ### Quick Examples
442
+
443
+ ```typescript
444
+ // Eager loading (default)
445
+ const agent = createAgent({
446
+ model,
447
+ tools: { calculator, weather, database }, // All loaded immediately
448
+ });
449
+
450
+ // Lazy loading with use_tools
451
+ const registry = new ToolRegistry();
452
+ registry.registerPlugin("stripe", stripePlugin.tools);
453
+ registry.registerPlugin("github", githubPlugin.tools);
454
+
455
+ const agent = createAgent({
456
+ model,
457
+ tools: {
458
+ use_tools: createUseToolsTool({ registry }),
459
+ },
460
+ pluginLoading: "lazy",
461
+ });
462
+ // Agent loads tools on demand: use_tools({ plugin: "stripe" })
463
+ // (Tools also become active after agent.loadTools([...]) in lazy mode)
464
+
465
+ // Dynamic discovery with search_tools
466
+ const mcpManager = new MCPManager();
467
+ await mcpManager.connectServer({ name: "filesystem", command: "npx", args: [...] });
468
+
469
+ const agent = createAgent({
470
+ model,
471
+ mcpManager,
472
+ mcpEagerLoad: false,
473
+ tools: {
474
+ search_tools: createSearchToolsTool({ manager: mcpManager, enableLoad: true }),
475
+ },
476
+ });
477
+ // Agent discovers tools: search_tools({ query: "list files", load: true })
478
+ ```
479
+
480
+ For a comprehensive guide with decision trees, common patterns, and best practices, see the **[Tool Loading Guide](../../docs/TOOL_LOADING_GUIDE.md)**.
481
+
482
+ ## Production Security
483
+
484
+ ⚠️ **Warning**: Default agent settings are permissive to enable rapid development. For production deployments, you should explicitly apply security policies to prevent unauthorized operations.
485
+
486
+ ### Quick Production Setup
487
+
488
+ The easiest way to create a production-ready agent is using `createProductionAgent()`, which combines security, observability, and recommended hooks in a single function:
489
+
490
+ ```typescript
491
+ import { createProductionAgent } from "@lleverage-ai/agent-sdk";
492
+ import { anthropic } from "@ai-sdk/anthropic";
493
+
494
+ // One-line production agent setup
495
+ const { agent, observability } = createProductionAgent({
496
+ model: anthropic("claude-sonnet-4-20250514"),
497
+ });
498
+
499
+ // Access observability primitives
500
+ observability.logger?.info("Agent started");
501
+ observability.metrics?.requests.inc();
502
+ ```
503
+
504
+ This function automatically configures:
505
+
506
+ - **Security**: Production security preset (sandbox, permissions, tool restrictions)
507
+ - **Observability**: Logging, metrics, and tracing with hooks
508
+ - **Secrets filtering**: Prevents credential leakage in logs and responses
509
+ - **Optional guardrails**: Content filtering for input/output validation
510
+
511
+ **Customization example:**
512
+
513
+ ```typescript
514
+ const { agent, observability } = createProductionAgent({
515
+ model: anthropic("claude-sonnet-4-20250514"),
516
+
517
+ // Customize security
518
+ securityPreset: "readonly", // Maximum restrictions
519
+ securityOverrides: {
520
+ permissionMode: "approval-required",
521
+ },
522
+
523
+ // Customize observability
524
+ observabilityOptions: {
525
+ name: "my-agent",
526
+ loggerOptions: { level: "warn" },
527
+ enableTracing: false,
528
+ },
529
+
530
+ // Enable guardrails
531
+ enableGuardrails: true,
532
+ blockedInputPatterns: [/ignore.*instructions/i],
533
+ blockedOutputPatterns: [/\d{3}-\d{2}-\d{4}/], // SSN pattern
534
+
535
+ // Add custom options
536
+ additionalOptions: {
537
+ systemPrompt: "You are a helpful assistant.",
538
+ checkpointer: createMemorySaver(),
539
+ },
540
+ });
541
+ ```
542
+
543
+ For more granular control, you can configure security and observability components individually using the following options.
544
+
545
+ ### Security Policy Presets
546
+
547
+ The SDK provides four security policy presets that bundle sandbox configuration, permission modes, and tool restrictions:
548
+
549
+ ```typescript
550
+ import { createAgent } from "@lleverage-ai/agent-sdk";
551
+ import { applySecurityPolicy } from "@lleverage-ai/agent-sdk/security";
552
+
553
+ // Production preset: balanced security for production deployments
554
+ const agent = createAgent({
555
+ model,
556
+ ...applySecurityPolicy("production"),
557
+ });
558
+ ```
559
+
560
+ **Available presets:**
561
+
562
+ - `"development"` - Permissive settings for rapid iteration (allows all operations)
563
+ - `"ci"` - Restrictive settings for CI/CD (blocks network operations, plan mode only)
564
+ - `"production"` - Balanced settings for production (blocks destructive operations, limited timeouts)
565
+ - `"readonly"` - Maximum restrictions (no writes, no commands, read-only access)
566
+
567
+ ### Guardrails Hooks
568
+
569
+ Protect against harmful input and filter sensitive output:
570
+
571
+ ```typescript
572
+ import { createGuardrailsHooks } from "@lleverage-ai/agent-sdk/hooks";
573
+
574
+ const agent = createAgent({
575
+ model,
576
+ hooks: createGuardrailsHooks({
577
+ blockedInputPatterns: [
578
+ /ignore\s+previous\s+instructions/i, // Prompt injection
579
+ /system\s+prompt/i, // System prompt extraction
580
+ ],
581
+ blockedOutputPatterns: [
582
+ /\d{3}-\d{2}-\d{4}/g, // SSN
583
+ /\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}/g, // Credit card
584
+ ],
585
+ blockedInputMessage: "Request blocked by content policy",
586
+ filteredOutputMessage: "[Content filtered]",
587
+ }),
588
+ });
589
+ ```
590
+
591
+ ### Secrets Filtering
592
+
593
+ Prevent credential leakage in logs and responses:
594
+
595
+ ```typescript
596
+ import {
597
+ createSecretsFilterHooks,
598
+ COMMON_SECRET_PATTERNS,
599
+ } from "@lleverage-ai/agent-sdk/hooks";
600
+
601
+ const agent = createAgent({
602
+ model,
603
+ hooks: createSecretsFilterHooks({
604
+ patterns: Object.values(COMMON_SECRET_PATTERNS),
605
+ customPatterns: [/my-api-key-[A-Za-z0-9]+/g],
606
+ redactionText: "[REDACTED]",
607
+ onSecretDetected: (type, pattern, context) => {
608
+ console.warn(`Secret detected in ${type}:`, pattern);
609
+ },
610
+ }),
611
+ });
612
+ ```
613
+
614
+ **Built-in secret patterns:**
615
+
616
+ - AWS access keys and secrets
617
+ - GitHub tokens (personal access, OAuth)
618
+ - JWT tokens
619
+ - Private keys (PEM format)
620
+ - Slack, Stripe, and other common API keys
621
+ - Password and secret variables
622
+
623
+ ### Tool Restrictions
624
+
625
+ Disable dangerous tools in production:
626
+
627
+ ```typescript
628
+ const agent = createAgent({
629
+ model,
630
+ // Explicitly disable core tools that allow code execution or file writes
631
+ disabledCoreTools: ["bash", "write", "edit"],
632
+
633
+ // Or use allowlist approach
634
+ allowedTools: ["read", "glob", "grep", "search_tools"],
635
+ });
636
+ ```
637
+
638
+ ### Permission Mode: acceptEdits with Bash Safety
639
+
640
+ The `acceptEdits` permission mode auto-approves `write` and `edit` tool calls, but **shell commands can still perform file writes** (e.g., `echo > file`, `rm`, `mv`), creating a security gap.
641
+
642
+ To close this gap, use `applySecurityPolicy()` with `acceptEdits` mode - it automatically configures the sandbox to block shell-based file operations:
643
+
644
+ ```typescript
645
+ import { applySecurityPolicy } from "@lleverage-ai/agent-sdk/security";
646
+
647
+ // acceptEdits mode with shell file operation blocking (default behavior)
648
+ const agent = createAgent({
649
+ model,
650
+ ...applySecurityPolicy("development", {
651
+ permissionMode: "acceptEdits",
652
+ // blockShellFileOps: true is the default
653
+ }),
654
+ });
655
+ ```
656
+
657
+ **What gets blocked in acceptEdits mode:**
658
+
659
+ - Output redirection: `echo 'text' > file.txt`, `cat input >> output`
660
+ - File deletion/movement: `rm file.txt`, `mv old new`
661
+ - File creation: `touch file`, `cp source dest`, `mkdir dir`
662
+ - Permission changes: `chmod`, `chown`
663
+ - Package managers: `npm install`, `yarn add`, `pip install`
664
+
665
+ **What remains allowed:**
666
+
667
+ - Read operations: `ls`, `cat`, `grep`, `find`, `head`, `tail`
668
+ - The `write` and `edit` tools (approved by acceptEdits mode)
669
+
670
+ **Manual configuration:**
671
+
672
+ ```typescript
673
+ import { getSandboxOptionsForAcceptEdits } from "@lleverage-ai/agent-sdk/security";
674
+ import { LocalSandbox } from "@lleverage-ai/agent-sdk/backends";
675
+
676
+ const agent = createAgent({
677
+ model,
678
+ backend: new LocalSandbox(getSandboxOptionsForAcceptEdits()),
679
+ permissionMode: "acceptEdits",
680
+ });
681
+ ```
682
+
683
+ **Disable blocking (not recommended for production):**
684
+
685
+ ```typescript
686
+ const agent = createAgent({
687
+ model,
688
+ ...applySecurityPolicy("development", {
689
+ permissionMode: "acceptEdits",
690
+ blockShellFileOps: false, // Allow bash file operations
691
+ }),
692
+ });
693
+ ```
694
+
695
+ ### Complete Production Example
696
+
697
+ Combining security policies, guardrails, and secrets filtering:
698
+
699
+ ```typescript
700
+ import { createAgent } from "@lleverage-ai/agent-sdk";
701
+ import { applySecurityPolicy } from "@lleverage-ai/agent-sdk/security";
702
+ import {
703
+ createGuardrailsHooks,
704
+ createSecretsFilterHooks,
705
+ COMMON_SECRET_PATTERNS,
706
+ } from "@lleverage-ai/agent-sdk/hooks";
707
+
708
+ const agent = createAgent({
709
+ model,
710
+
711
+ // Apply production security preset
712
+ ...applySecurityPolicy("production"),
713
+
714
+ // Add guardrails and secrets filtering
715
+ hooks: {
716
+ ...createGuardrailsHooks({
717
+ blockedInputPatterns: [/ignore\s+previous\s+instructions/i],
718
+ blockedOutputPatterns: [/\d{3}-\d{2}-\d{4}/g],
719
+ }),
720
+ ...createSecretsFilterHooks({
721
+ patterns: Object.values(COMMON_SECRET_PATTERNS),
722
+ }),
723
+ },
724
+
725
+ // Additional tool restrictions
726
+ disabledCoreTools: ["bash"],
727
+ });
728
+ ```
729
+
730
+ ## Subagents
731
+
732
+ Subagents enable task delegation to specialized agents. Define subagents with their own system prompts and tools:
733
+
734
+ ```typescript
735
+ import { createSubagent } from "@lleverage-ai/agent-sdk";
736
+
737
+ const researcherSubagent = createSubagent({
738
+ id: "researcher",
739
+ name: "Researcher",
740
+ description: "Researches topics and gathers information",
741
+ systemPrompt:
742
+ "You are a research specialist. Gather comprehensive information.",
743
+ plugins: [webSearchPlugin],
744
+ });
745
+
746
+ const writerSubagent = createSubagent({
747
+ id: "writer",
748
+ name: "Writer",
749
+ description: "Writes content based on research",
750
+ systemPrompt: "You are a content writer. Create clear, engaging content.",
751
+ });
752
+
753
+ // Provide subagents to the parent agent
754
+ const agent = createAgent({
755
+ model,
756
+ systemPrompt: "Coordinate research and writing tasks.",
757
+ subagents: [researcherSubagent, writerSubagent],
758
+ });
759
+ ```
760
+
761
+ The parent agent receives a `task` tool to delegate work:
762
+
763
+ ```typescript
764
+ // Agent can call: task({ subagent: "researcher", prompt: "Research AI trends" })
765
+ ```
766
+
767
+ ### Advanced Subagent Execution
768
+
769
+ For programmatic control over subagent execution:
770
+
771
+ ```typescript
772
+ import {
773
+ createSubagentContext,
774
+ executeSubagent,
775
+ executeSubagentsParallel,
776
+ } from "@lleverage-ai/agent-sdk";
777
+
778
+ // Create isolated context for subagent
779
+ const context = createSubagentContext({
780
+ parentMessages: messages,
781
+ subagentSystemPrompt: "You are a specialist.",
782
+ });
783
+
784
+ // Execute single subagent
785
+ const result = await executeSubagent({
786
+ subagent: researcherSubagent,
787
+ model,
788
+ context,
789
+ prompt: "Research this topic",
790
+ });
791
+
792
+ // Execute multiple subagents in parallel
793
+ const results = await executeSubagentsParallel({
794
+ subagents: [researcherSubagent, analyzerSubagent],
795
+ model,
796
+ contexts: [context1, context2],
797
+ prompts: ["Research...", "Analyze..."],
798
+ });
799
+ ```
800
+
801
+ ### Background Tasks and Recovery
802
+
803
+ Background tasks allow subagents to run asynchronously without blocking the parent agent. When persistence is configured, tasks survive process restarts and can be recovered.
804
+
805
+ #### Task Store Configuration
806
+
807
+ ```typescript
808
+ import { FileTaskStore } from "@lleverage-ai/agent-sdk/task-store";
809
+
810
+ // Configure persistent task storage
811
+ const taskStore = new FileTaskStore({
812
+ directory: "./task-data",
813
+ expirationMs: 86400000, // 24 hours
814
+ });
815
+
816
+ // Create agent with task store
817
+ const agent = createAgent({
818
+ model,
819
+ subagents: [researcherSubagent],
820
+ taskStore, // Tasks now persist across restarts
821
+ });
822
+ ```
823
+
824
+ #### Task Lifecycle
825
+
826
+ Background tasks progress through these states:
827
+
828
+ 1. **pending**: Task created, not yet started
829
+ 2. **running**: Task is currently executing
830
+ 3. **completed**: Task finished successfully
831
+ 4. **failed**: Task encountered an error
832
+
833
+ ```typescript
834
+ import {
835
+ listBackgroundTasks,
836
+ getBackgroundTask,
837
+ clearCompletedTasks,
838
+ } from "@lleverage-ai/agent-sdk";
839
+
840
+ // List all running tasks
841
+ const runningTasks = await listBackgroundTasks({ status: "running" });
842
+
843
+ // Get a specific task
844
+ const task = await getBackgroundTask("task-123");
845
+ console.log(task.status, task.result, task.error);
846
+
847
+ // Clean up old completed tasks
848
+ const cleaned = await clearCompletedTasks();
849
+ ```
850
+
851
+ #### Recovery Patterns
852
+
853
+ The SDK provides utilities for automatic task recovery on agent restart:
854
+
855
+ **1. Recover Interrupted Tasks**
856
+
857
+ When your agent restarts, running tasks are interrupted. Mark them as failed:
858
+
859
+ ```typescript
860
+ import { recoverRunningTasks } from "@lleverage-ai/agent-sdk";
861
+
862
+ // On agent startup
863
+ const recovered = await recoverRunningTasks(taskStore);
864
+ console.log(`Recovered ${recovered} interrupted tasks`);
865
+ ```
866
+
867
+ **2. Recover Failed Tasks for Retry**
868
+
869
+ Load failed tasks and retry those with transient errors:
870
+
871
+ ```typescript
872
+ import {
873
+ recoverFailedTasks,
874
+ updateBackgroundTask,
875
+ } from "@lleverage-ai/agent-sdk";
876
+
877
+ // Load failed tasks
878
+ const failedTasks = await recoverFailedTasks(taskStore, {
879
+ errorPattern: /timeout|network|ECONNREFUSED/,
880
+ minCreatedAt: new Date(Date.now() - 86400000), // Last 24 hours
881
+ });
882
+
883
+ // Retry transient failures
884
+ for (const task of failedTasks) {
885
+ const retryTask = updateBackgroundTask(task, {
886
+ status: "pending",
887
+ error: undefined,
888
+ });
889
+ await taskStore.save(retryTask);
890
+ // Process retryTask through your task execution logic
891
+ }
892
+ ```
893
+
894
+ **3. Clean Up Stale Tasks**
895
+
896
+ Prevent unbounded storage growth by removing old tasks:
897
+
898
+ ```typescript
899
+ import { cleanupStaleTasks } from "@lleverage-ai/agent-sdk";
900
+
901
+ // Clean up tasks older than 7 days
902
+ const sevenDays = 7 * 24 * 60 * 60 * 1000;
903
+ const cleaned = await cleanupStaleTasks(taskStore, sevenDays);
904
+ console.log(`Cleaned up ${cleaned} stale tasks`);
905
+
906
+ // Schedule periodic cleanup
907
+ setInterval(async () => {
908
+ await cleanupStaleTasks(taskStore, sevenDays);
909
+ }, 86400000); // Once per day
910
+ ```
911
+
912
+ **Complete Recovery Pattern**
913
+
914
+ Combine all recovery utilities on agent startup:
915
+
916
+ ```typescript
917
+ async function initializeAgent() {
918
+ const taskStore = new FileTaskStore({ directory: "./task-data" });
919
+
920
+ // 1. Recover interrupted tasks
921
+ await recoverRunningTasks(taskStore);
922
+
923
+ // 2. Retry failed tasks with transient errors
924
+ const failedTasks = await recoverFailedTasks(taskStore, {
925
+ errorPattern: /timeout|network/,
926
+ });
927
+ for (const task of failedTasks) {
928
+ const retryTask = updateBackgroundTask(task, {
929
+ status: "pending",
930
+ error: undefined,
931
+ });
932
+ await taskStore.save(retryTask);
933
+ }
934
+
935
+ // 3. Clean up old tasks
936
+ const sevenDays = 7 * 24 * 60 * 60 * 1000;
937
+ await cleanupStaleTasks(taskStore, sevenDays);
938
+
939
+ // 4. Create agent
940
+ return createAgent({
941
+ model,
942
+ subagents: [researcherSubagent],
943
+ taskStore,
944
+ });
945
+ }
946
+ ```
947
+
948
+ ## Streaming
949
+
950
+ Agents support streaming responses for real-time output:
951
+
952
+ ```typescript
953
+ // AsyncIterator-based streaming
954
+ for await (const part of agent.stream({ prompt: "Tell me a story" })) {
955
+ if (part.type === "text-delta") {
956
+ process.stdout.write(part.text);
957
+ } else if (part.type === "tool-call") {
958
+ console.log("Calling tool:", part.toolName);
959
+ } else if (part.type === "finish") {
960
+ console.log("\nDone:", part.finishReason);
961
+ }
962
+ }
963
+
964
+ // Next.js API route with useChat compatibility
965
+ export async function POST(req: Request) {
966
+ const { messages } = await req.json();
967
+ return agent.streamResponse({ messages });
968
+ }
969
+
970
+ // Raw AI SDK streamText result
971
+ const stream = await agent.streamRaw({ messages });
972
+ ```
973
+
974
+ ## MCP Integration
975
+
976
+ The SDK provides unified tool management through the Model Context Protocol (MCP).
977
+
978
+ ### Plugin-based MCP Tools
979
+
980
+ Plugin tools are automatically registered as virtual MCP servers:
981
+
982
+ ```typescript
983
+ const githubPlugin = definePlugin({
984
+ name: "github",
985
+ mcpServer: {
986
+ type: "stdio",
987
+ command: "npx",
988
+ args: ["-y", "@modelcontextprotocol/server-github"],
989
+ env: { GITHUB_TOKEN: "${GITHUB_TOKEN}" }, // Expands from process.env
990
+ },
991
+ });
992
+ ```
993
+
994
+ ### Tool Search and Deferred Loading
995
+
996
+ When you have many plugin tools, enable tool search to reduce context size:
997
+
998
+ ```typescript
999
+ const agent = createAgent({
1000
+ model,
1001
+ plugins: [plugin1, plugin2, plugin3],
1002
+ toolSearch: {
1003
+ enabled: "auto", // "auto" | "always" | "never"
1004
+ threshold: 20, // Defer when plugin tools > 20
1005
+ maxResults: 10, // Max search results
1006
+ },
1007
+ });
1008
+
1009
+ // Agent gets a `search_tools` tool to discover and load tools on-demand
1010
+ ```
1011
+
1012
+ ### MCP Tool Utilities
1013
+
1014
+ Helper functions for working with MCP tool names:
1015
+
1016
+ ```typescript
1017
+ import {
1018
+ mcpTools,
1019
+ mcpToolsFor,
1020
+ toolsFromPlugin,
1021
+ } from "@lleverage-ai/agent-sdk";
1022
+
1023
+ // Get all MCP tool names from an agent
1024
+ const allMcpTools = mcpTools(agent); // ["mcp__github__list_issues", ...]
1025
+
1026
+ // Get tools for a specific plugin
1027
+ const githubTools = mcpToolsFor(agent, "github");
1028
+
1029
+ // Extract tools from a plugin definition
1030
+ const tools = toolsFromPlugin(myPlugin);
1031
+ ```
1032
+
1033
+ ### MCP Security Best Practices
1034
+
1035
+ When connecting to external MCP servers, apply security controls to protect against malicious or misconfigured tools:
1036
+
1037
+ ```typescript
1038
+ import { createAgent } from "@lleverage-ai/agent-sdk";
1039
+
1040
+ const githubPlugin = definePlugin({
1041
+ name: "github",
1042
+ mcpServer: {
1043
+ type: "stdio",
1044
+ command: "npx",
1045
+ args: ["-y", "@modelcontextprotocol/server-github"],
1046
+ env: { GITHUB_TOKEN: "${GITHUB_TOKEN}" },
1047
+
1048
+ // Security: Only allow specific tools from this server
1049
+ allowedTools: ["get_issue", "list_issues", "search_issues"],
1050
+
1051
+ // Security: Validate tool inputs against their JSON Schema
1052
+ validateInputs: true,
1053
+
1054
+ // Security: Reject tools without meaningful schemas
1055
+ requireSchema: true,
1056
+ },
1057
+ });
1058
+
1059
+ const agent = createAgent({
1060
+ model,
1061
+ plugins: [githubPlugin],
1062
+ });
1063
+ ```
1064
+
1065
+ #### Security Options
1066
+
1067
+ - **`allowedTools`**: Allowlist of permitted tool names (without `mcp__` prefix). Only tools in this list will be loaded. Useful for restricting access to dangerous operations.
1068
+
1069
+ - **`validateInputs`**: When `true`, tool inputs are validated against their declared JSON Schema before execution. Invalid inputs throw `MCPInputValidationError` instead of being passed to the server. Protects against malformed or malicious inputs.
1070
+
1071
+ - **`requireSchema`**: When `true`, tools without meaningful schemas (empty or minimal schemas) are rejected during connection. Ensures all tools have explicit input validation.
1072
+
1073
+ #### Example: Secure Production MCP Configuration
1074
+
1075
+ ```typescript
1076
+ // Production configuration with all security controls
1077
+ const docsPlugin = definePlugin({
1078
+ name: "docs",
1079
+ mcpServer: {
1080
+ type: "http",
1081
+ url: "https://docs-server.internal/mcp",
1082
+ headers: { Authorization: "Bearer ${DOCS_API_TOKEN}" },
1083
+
1084
+ // Only allow read-only operations
1085
+ allowedTools: ["search_docs", "get_document", "list_categories"],
1086
+
1087
+ // Validate all inputs
1088
+ validateInputs: true,
1089
+
1090
+ // Require schemas for all tools
1091
+ requireSchema: true,
1092
+ },
1093
+ });
1094
+ ```
1095
+
1096
+ #### Handling Validation Errors
1097
+
1098
+ ```typescript
1099
+ import { MCPInputValidationError } from "@lleverage-ai/agent-sdk";
1100
+
1101
+ try {
1102
+ const result = await agent.generate({
1103
+ messages: [{ role: "user", content: "Search the docs" }],
1104
+ });
1105
+ } catch (error) {
1106
+ if (error instanceof MCPInputValidationError) {
1107
+ console.error(`Invalid input for ${error.toolName}:`);
1108
+ console.error(error.errors.join("\n"));
1109
+ // Handle validation error (e.g., log, alert, retry with corrected input)
1110
+ }
1111
+ }
1112
+ ```
1113
+
1114
+ ## Backends
1115
+
1116
+ Backends provide filesystem and execution capabilities.
1117
+
1118
+ ### FilesystemBackend
1119
+
1120
+ File operations with security protections:
1121
+
1122
+ ```typescript
1123
+ import {
1124
+ FilesystemBackend,
1125
+ createFilesystemBackend,
1126
+ } from "@lleverage-ai/agent-sdk";
1127
+
1128
+ const backend = new FilesystemBackend({
1129
+ rootDir: "/project",
1130
+ allowedPaths: ["/project/src", "/project/tests"],
1131
+ maxFileSize: 10 * 1024 * 1024, // 10MB
1132
+ followSymlinks: false,
1133
+ });
1134
+
1135
+ // Or use factory
1136
+ const backend = createFilesystemBackend({ rootDir: "/project" });
1137
+ ```
1138
+
1139
+ ### StateBackend
1140
+
1141
+ In-memory filesystem for sandboxed operations:
1142
+
1143
+ ```typescript
1144
+ import { StateBackend, createAgentState } from "@lleverage-ai/agent-sdk";
1145
+
1146
+ const state = createAgentState();
1147
+ const backend = new StateBackend(state);
1148
+ ```
1149
+
1150
+ ### LocalSandbox
1151
+
1152
+ Command execution with security controls:
1153
+
1154
+ ```typescript
1155
+ import { LocalSandbox, createLocalSandbox } from "@lleverage-ai/agent-sdk";
1156
+
1157
+ const sandbox = new LocalSandbox({
1158
+ cwd: "/project",
1159
+ timeout: 30000,
1160
+ maxOutputSize: 1024 * 1024,
1161
+ blockedCommands: ["rm -rf /"],
1162
+ });
1163
+
1164
+ // Read-only mode
1165
+ const readOnlySandbox = LocalSandbox.readOnly({ cwd: "/project" });
1166
+ ```
1167
+
1168
+ ## Middleware
1169
+
1170
+ Middleware intercepts and transforms agent operations.
1171
+
1172
+ ### Logging Middleware
1173
+
1174
+ ```typescript
1175
+ import {
1176
+ createLoggingMiddleware,
1177
+ createTimingMiddleware,
1178
+ } from "@lleverage-ai/agent-sdk";
1179
+
1180
+ const agent = createAgent({
1181
+ model,
1182
+ middleware: [
1183
+ createLoggingMiddleware({ level: "debug" }),
1184
+ createTimingMiddleware(),
1185
+ ],
1186
+ });
1187
+ ```
1188
+
1189
+ ### Caching Middleware
1190
+
1191
+ ```typescript
1192
+ import {
1193
+ createCacheMiddleware,
1194
+ InMemoryCacheStore,
1195
+ } from "@lleverage-ai/agent-sdk";
1196
+
1197
+ const cacheStore = new InMemoryCacheStore();
1198
+
1199
+ const agent = createAgent({
1200
+ model,
1201
+ middleware: [
1202
+ createCacheMiddleware({
1203
+ store: cacheStore,
1204
+ ttl: 60000, // 1 minute
1205
+ }),
1206
+ ],
1207
+ });
1208
+ ```
1209
+
1210
+ ### Retry Middleware
1211
+
1212
+ ```typescript
1213
+ import {
1214
+ createRetryMiddleware,
1215
+ createCircuitBreakerMiddleware,
1216
+ } from "@lleverage-ai/agent-sdk";
1217
+
1218
+ const agent = createAgent({
1219
+ model,
1220
+ middleware: [
1221
+ createRetryMiddleware({
1222
+ maxRetries: 3,
1223
+ backoff: "exponential",
1224
+ }),
1225
+ createCircuitBreakerMiddleware({
1226
+ threshold: 5,
1227
+ resetTimeout: 60000,
1228
+ }),
1229
+ ],
1230
+ });
1231
+ ```
1232
+
1233
+ ### Guardrails Middleware
1234
+
1235
+ ```typescript
1236
+ import {
1237
+ createGuardrailsMiddleware,
1238
+ createContentFilterMiddleware,
1239
+ } from "@lleverage-ai/agent-sdk";
1240
+
1241
+ const agent = createAgent({
1242
+ model,
1243
+ middleware: [
1244
+ createGuardrailsMiddleware({
1245
+ blockedPatterns: [/password/i, /api[_-]?key/i],
1246
+ }),
1247
+ createContentFilterMiddleware({
1248
+ maxLength: 10000,
1249
+ }),
1250
+ ],
1251
+ });
1252
+ ```
1253
+
1254
+ ### Composing Middleware
1255
+
1256
+ ```typescript
1257
+ import { composeMiddleware } from "@lleverage-ai/agent-sdk";
1258
+
1259
+ const combined = composeMiddleware([
1260
+ createLoggingMiddleware(),
1261
+ createRetryMiddleware({ maxRetries: 3 }),
1262
+ createCacheMiddleware({ store }),
1263
+ ]);
1264
+ ```
1265
+
1266
+ ## Observability
1267
+
1268
+ Built-in logging, metrics, and tracing support.
1269
+
1270
+ ### Logging
1271
+
1272
+ ```typescript
1273
+ import {
1274
+ createLogger,
1275
+ createConsoleTransport,
1276
+ createJsonFormatter,
1277
+ } from "@lleverage-ai/agent-sdk";
1278
+
1279
+ const logger = createLogger({
1280
+ level: "info",
1281
+ transports: [
1282
+ createConsoleTransport({
1283
+ formatter: createJsonFormatter(),
1284
+ }),
1285
+ ],
1286
+ });
1287
+
1288
+ logger.info("Agent started", { agentId: "123" });
1289
+ ```
1290
+
1291
+ ### Metrics
1292
+
1293
+ ```typescript
1294
+ import {
1295
+ createMetricsRegistry,
1296
+ createAgentMetrics,
1297
+ createConsoleMetricsExporter,
1298
+ } from "@lleverage-ai/agent-sdk";
1299
+
1300
+ const registry = createMetricsRegistry({
1301
+ exporters: [createConsoleMetricsExporter()],
1302
+ });
1303
+
1304
+ const metrics = createAgentMetrics(registry);
1305
+ metrics.requestsTotal.inc({ model: "claude-3" });
1306
+ metrics.latencyHistogram.observe({ model: "claude-3" }, 1500);
1307
+ ```
1308
+
1309
+ ### Tracing
1310
+
1311
+ ```typescript
1312
+ import {
1313
+ createTracer,
1314
+ createConsoleSpanExporter,
1315
+ SemanticAttributes,
1316
+ } from "@lleverage-ai/agent-sdk";
1317
+
1318
+ const tracer = createTracer({
1319
+ serviceName: "my-agent",
1320
+ exporters: [createConsoleSpanExporter()],
1321
+ });
1322
+
1323
+ const span = tracer.startSpan("agent.generate");
1324
+ span.setAttribute(SemanticAttributes.MODEL_NAME, "claude-3");
1325
+ // ... do work
1326
+ span.end();
1327
+ ```
1328
+
1329
+ ### Cross-Agent Tracing
1330
+
1331
+ When using subagents, you can propagate trace context to maintain distributed tracing across parent and child agents:
1332
+
1333
+ ```typescript
1334
+ import {
1335
+ createAgent,
1336
+ createTaskTool,
1337
+ createSubagent,
1338
+ createTracer,
1339
+ SemanticAttributes,
1340
+ } from "@lleverage-ai/agent-sdk";
1341
+ import { anthropic } from "@ai-sdk/anthropic";
1342
+
1343
+ const tracer = createTracer({
1344
+ name: "my-app",
1345
+ exporters: [createConsoleSpanExporter()],
1346
+ });
1347
+
1348
+ // Create parent agent
1349
+ const parentAgent = createAgent({
1350
+ model: anthropic("claude-sonnet-4-20250514"),
1351
+ });
1352
+
1353
+ // Start a parent span for the request
1354
+ const parentSpan = tracer.startSpan("handle-user-request", {
1355
+ attributes: {
1356
+ [SemanticAttributes.AGENT_NAME]: "parent-agent",
1357
+ },
1358
+ });
1359
+
1360
+ // Define subagent with tracing support
1361
+ const researcherSubagent = {
1362
+ type: "researcher",
1363
+ description: "Researches information",
1364
+ create: (ctx) => {
1365
+ // Create child span linked to parent
1366
+ if (ctx.parentSpanContext) {
1367
+ const span = tracer.startSpan("subagent-research", {
1368
+ parent: ctx.parentSpanContext,
1369
+ attributes: {
1370
+ [SemanticAttributes.SUBAGENT_TYPE]: "researcher",
1371
+ [SemanticAttributes.SUBAGENT_ID]: "researcher-1",
1372
+ },
1373
+ });
1374
+
1375
+ // Track the span for cleanup
1376
+ // In production, use a span manager or store spans in agent state
1377
+ }
1378
+
1379
+ return createSubagent(parentAgent, {
1380
+ name: "researcher",
1381
+ systemPrompt: "You are a research assistant.",
1382
+ });
1383
+ },
1384
+ };
1385
+
1386
+ // Create task tool with parent span context
1387
+ const task = createTaskTool({
1388
+ subagents: [researcherSubagent],
1389
+ defaultModel: anthropic("claude-sonnet-4-20250514"),
1390
+ parentAgent,
1391
+ parentSpanContext: {
1392
+ traceId: parentSpan.traceId,
1393
+ spanId: parentSpan.spanId,
1394
+ },
1395
+ });
1396
+
1397
+ // Use the agent with tracing
1398
+ const result = await parentAgent.generate({
1399
+ prompt: "Research quantum computing",
1400
+ tools: { task },
1401
+ });
1402
+
1403
+ // End the parent span
1404
+ parentSpan.end();
1405
+ await tracer.flush();
1406
+ ```
1407
+
1408
+ This creates a distributed trace where:
1409
+
1410
+ - Parent span: `handle-user-request`
1411
+ - Child span: `subagent-research` (linked to parent)
1412
+
1413
+ Both spans share the same `traceId`, allowing you to:
1414
+
1415
+ - Track the full request flow across agents
1416
+ - Measure latency at each level
1417
+ - Correlate logs and errors across parent and child operations
1418
+ - Visualize the call graph in tools like Jaeger or Zipkin
1419
+
1420
+ **Key points:**
1421
+
1422
+ - Pass `parentSpanContext` to `createTaskTool()` to enable trace propagation
1423
+ - Access `ctx.parentSpanContext` in your subagent factory to create child spans
1424
+ - Use `SemanticAttributes.SUBAGENT_*` constants for consistent span metadata
1425
+ - Both parent and child spans will share the same `traceId` for correlation
1426
+
1427
+ ### Observability Hooks
1428
+
1429
+ Automatically instrument agents with logging, metrics, and tracing:
1430
+
1431
+ ```typescript
1432
+ import {
1433
+ createObservabilityEventStore,
1434
+ createObservabilityEventHooks,
1435
+ } from "@lleverage-ai/agent-sdk";
1436
+
1437
+ const store = createObservabilityEventStore();
1438
+ const hooks = createObservabilityEventHooks(store);
1439
+
1440
+ const agent = createAgent({
1441
+ model,
1442
+ hooks: {
1443
+ MCPConnectionFailed: hooks.MCPConnectionFailed,
1444
+ MCPConnectionRestored: hooks.MCPConnectionRestored,
1445
+ ToolRegistered: hooks.ToolRegistered,
1446
+ ToolLoadError: hooks.ToolLoadError,
1447
+ PreCompact: hooks.PreCompact,
1448
+ PostCompact: hooks.PostCompact,
1449
+ },
1450
+ });
1451
+
1452
+ const events = store.getAll();
1453
+ ```
1454
+
1455
+ ## Memory
1456
+
1457
+ Persist agent memory across conversations.
1458
+
1459
+ ### Filesystem Memory Store
1460
+
1461
+ ```typescript
1462
+ import {
1463
+ FilesystemMemoryStore,
1464
+ loadAgentMemory,
1465
+ } from "@lleverage-ai/agent-sdk";
1466
+
1467
+ const store = new FilesystemMemoryStore({
1468
+ rootDir: ".agent/memory",
1469
+ });
1470
+
1471
+ // Load all memory for an agent
1472
+ const memory = await loadAgentMemory({
1473
+ store,
1474
+ agentId: "my-agent",
1475
+ });
1476
+ ```
1477
+
1478
+ ### In-Memory Store
1479
+
1480
+ ```typescript
1481
+ import { InMemoryMemoryStore } from "@lleverage-ai/agent-sdk";
1482
+
1483
+ const store = new InMemoryMemoryStore();
1484
+
1485
+ // Create memory document
1486
+ await store.save({
1487
+ id: "note-1",
1488
+ content: "Important information...",
1489
+ metadata: {
1490
+ tags: ["important"],
1491
+ autoLoad: true,
1492
+ },
1493
+ });
1494
+ ```
1495
+
1496
+ ### Memory-Aware Middleware
1497
+
1498
+ ```typescript
1499
+ import { createAgentMemoryMiddleware } from "@lleverage-ai/agent-sdk";
1500
+
1501
+ const agent = createAgent({
1502
+ model,
1503
+ middleware: [
1504
+ createAgentMemoryMiddleware({
1505
+ store,
1506
+ autoLoad: true,
1507
+ }),
1508
+ ],
1509
+ });
1510
+ ```
1511
+
1512
+ ## Checkpointing
1513
+
1514
+ Save and restore agent state for resumable conversations.
1515
+
1516
+ ### MemorySaver
1517
+
1518
+ In-memory checkpoint storage:
1519
+
1520
+ ```typescript
1521
+ import { createMemorySaver } from "@lleverage-ai/agent-sdk";
1522
+
1523
+ const checkpointer = createMemorySaver();
1524
+
1525
+ const agent = createAgent({
1526
+ model,
1527
+ checkpointer,
1528
+ });
1529
+
1530
+ // Save checkpoint
1531
+ await checkpointer.save({
1532
+ threadId: "conversation-1",
1533
+ messages,
1534
+ metadata: { userId: "123" },
1535
+ });
1536
+
1537
+ // Load checkpoint
1538
+ const checkpoint = await checkpointer.load("conversation-1");
1539
+ ```
1540
+
1541
+ ### FileSaver
1542
+
1543
+ Persistent file-based checkpoints:
1544
+
1545
+ ```typescript
1546
+ import { createFileSaver } from "@lleverage-ai/agent-sdk";
1547
+
1548
+ const checkpointer = createFileSaver({
1549
+ directory: ".agent/checkpoints",
1550
+ });
1551
+ ```
1552
+
1553
+ ### KeyValueStoreSaver
1554
+
1555
+ Use any key-value store:
1556
+
1557
+ ```typescript
1558
+ import {
1559
+ createKeyValueStoreSaver,
1560
+ InMemoryStore,
1561
+ } from "@lleverage-ai/agent-sdk";
1562
+
1563
+ const store = new InMemoryStore();
1564
+ const checkpointer = createKeyValueStoreSaver({ store });
1565
+ ```
1566
+
1567
+ ## Context Compaction
1568
+
1569
+ Automatically manage conversation context with intelligent compaction policies.
1570
+
1571
+ ### Basic Context Management
1572
+
1573
+ ```typescript
1574
+ import { createAgent, createContextManager } from "@lleverage-ai/agent-sdk";
1575
+
1576
+ const contextManager = createContextManager({
1577
+ maxTokens: 100000, // Maximum context window
1578
+ policy: {
1579
+ enabled: true,
1580
+ tokenThreshold: 0.8, // Trigger at 80% capacity
1581
+ hardCapThreshold: 0.95, // Force compact at 95% (safety)
1582
+ enableGrowthRatePrediction: false, // Predict when next message will exceed
1583
+ enableErrorFallback: true, // Auto-compact on context length errors
1584
+ },
1585
+ summarization: {
1586
+ keepMessageCount: 10, // Always keep last 10 messages
1587
+ keepToolResultCount: 5, // Keep recent tool results
1588
+ },
1589
+ });
1590
+
1591
+ const agent = createAgent({
1592
+ model,
1593
+ contextManager,
1594
+ checkpointer, // Required for error fallback
1595
+ });
1596
+ ```
1597
+
1598
+ ### Compaction Triggers
1599
+
1600
+ The SDK supports multiple compaction triggers:
1601
+
1602
+ 1. **Token Threshold** (default: 80%): Triggers when usage exceeds the threshold
1603
+ 2. **Hard Cap** (default: 95%): Safety limit - forces compaction to prevent errors
1604
+ 3. **Growth Rate**: Predicts if the next message will exceed limits
1605
+ 4. **Error Fallback**: Emergency compaction when context length errors occur
1606
+
1607
+ ```typescript
1608
+ const contextManager = createContextManager({
1609
+ maxTokens: 100000,
1610
+ policy: {
1611
+ enabled: true,
1612
+ tokenThreshold: 0.75, // Trigger at 75%
1613
+ hardCapThreshold: 0.9, // Force at 90%
1614
+ enableGrowthRatePrediction: true, // Enable predictive compaction
1615
+ enableErrorFallback: true, // Auto-recover from context errors
1616
+ },
1617
+ });
1618
+ ```
1619
+
1620
+ ### Custom Compaction Policy
1621
+
1622
+ Override the default policy logic with custom rules:
1623
+
1624
+ ```typescript
1625
+ const contextManager = createContextManager({
1626
+ maxTokens: 100000,
1627
+ policy: {
1628
+ enabled: true,
1629
+ tokenThreshold: 0.8,
1630
+ hardCapThreshold: 0.95,
1631
+ enableGrowthRatePrediction: false,
1632
+ enableErrorFallback: true,
1633
+ // Custom compaction logic
1634
+ shouldCompact: (budget, messages) => {
1635
+ // Trigger if more than 50 messages
1636
+ if (messages.length > 50) {
1637
+ return { trigger: true, reason: "token_threshold" };
1638
+ }
1639
+ // Trigger if budget usage high
1640
+ if (budget.usage >= 0.85) {
1641
+ return { trigger: true, reason: "hard_cap" };
1642
+ }
1643
+ return { trigger: false };
1644
+ },
1645
+ },
1646
+ });
1647
+ ```
1648
+
1649
+ ### Observability Hooks
1650
+
1651
+ Monitor compaction events with PreCompact and PostCompact hooks:
1652
+
1653
+ ```typescript
1654
+ const agent = createAgent({
1655
+ model,
1656
+ contextManager,
1657
+ hooks: {
1658
+ PreCompact: [
1659
+ async (input) => {
1660
+ console.log(
1661
+ `Compacting ${input.message_count} messages (${input.tokens_before} tokens)`,
1662
+ );
1663
+ return {};
1664
+ },
1665
+ ],
1666
+ PostCompact: [
1667
+ async (input) => {
1668
+ console.log(
1669
+ `Compacted ${input.messages_before} → ${input.messages_after} messages`,
1670
+ );
1671
+ console.log(`Saved ${input.tokens_saved} tokens`);
1672
+ return {};
1673
+ },
1674
+ ],
1675
+ },
1676
+ });
1677
+ ```
1678
+
1679
+ ### Error-Triggered Fallback
1680
+
1681
+ When enabled, the SDK automatically attempts emergency compaction if a context length error occurs:
1682
+
1683
+ ```typescript
1684
+ const contextManager = createContextManager({
1685
+ maxTokens: 100000,
1686
+ policy: {
1687
+ enableErrorFallback: true, // Enable auto-recovery
1688
+ },
1689
+ });
1690
+
1691
+ const agent = createAgent({
1692
+ model,
1693
+ contextManager,
1694
+ checkpointer, // Required - stores compacted state
1695
+ });
1696
+
1697
+ // If context error occurs, SDK will:
1698
+ // 1. Detect context length error
1699
+ // 2. Compact messages from checkpoint
1700
+ // 3. Save compacted state
1701
+ // 4. Retry the request
1702
+ ```
1703
+
1704
+ **Note**: Error fallback requires a checkpointer to store the compacted state. It only triggers once per request to avoid loops.
1705
+
1706
+ ### Token Accounting
1707
+
1708
+ The SDK uses a hybrid approach to token tracking for more accurate context management:
1709
+
1710
+ 1. **Pre-call Estimates**: Uses token counters to predict usage before API calls
1711
+ 2. **Post-call Actuals**: Updates tracking with real usage from model responses
1712
+ 3. **Message Caching**: Caches token counts per message to avoid re-counting
1713
+
1714
+ ```typescript
1715
+ import {
1716
+ createContextManager,
1717
+ createCustomTokenCounter,
1718
+ } from "@lleverage-ai/agent-sdk";
1719
+ import { encoding_for_model } from "tiktoken";
1720
+
1721
+ // Option 1: Use approximate counter (default, with caching)
1722
+ const contextManager = createContextManager({
1723
+ maxTokens: 100000,
1724
+ // Uses approximate counter by default (4 chars ≈ 1 token)
1725
+ });
1726
+
1727
+ // Option 2: Use model-specific tokenizer (recommended for production)
1728
+ const encoder = encoding_for_model("gpt-4");
1729
+ const contextManager = createContextManager({
1730
+ maxTokens: 100000,
1731
+ tokenCounter: createCustomTokenCounter({
1732
+ countFn: (text) => encoder.encode(text).length,
1733
+ messageOverhead: 4, // Tokens per message for structure
1734
+ }),
1735
+ });
1736
+
1737
+ // The context manager automatically:
1738
+ // - Estimates tokens before generation (for compaction decisions)
1739
+ // - Updates with actual usage after generation (for accurate tracking)
1740
+ // - Caches token counts to avoid re-counting identical messages
1741
+
1742
+ const agent = createAgent({
1743
+ model,
1744
+ contextManager,
1745
+ });
1746
+
1747
+ // After generation, usage is automatically tracked
1748
+ const result = await agent.generate({ prompt: "Hello" });
1749
+ // contextManager now knows the actual token usage from the model
1750
+ ```
1751
+
1752
+ **Token Budget Properties**:
1753
+
1754
+ - `currentTokens`: Current token count (actual or estimated)
1755
+ - `maxTokens`: Maximum allowed tokens
1756
+ - `usage`: Usage percentage (0-1)
1757
+ - `remaining`: Tokens remaining
1758
+ - `isActual`: `true` if based on model usage, `false` if estimated
1759
+
1760
+ **Benefits**:
1761
+
1762
+ - More accurate compaction decisions based on real model usage
1763
+ - Reduced computation from message caching (especially with custom tokenizers)
1764
+ - Hybrid approach: estimates for predictions, actuals for accuracy
1765
+ - Automatic integration - no manual updates needed
1766
+
1767
+ ### Background Compaction
1768
+
1769
+ Avoid blocking user-facing responses by running compaction in the background:
1770
+
1771
+ ```typescript
1772
+ import { createContextManager } from "@lleverage-ai/agent-sdk";
1773
+
1774
+ const contextManager = createContextManager({
1775
+ maxTokens: 100000,
1776
+ policy: {
1777
+ tokenThreshold: 0.8,
1778
+ },
1779
+ scheduler: {
1780
+ enableBackgroundCompaction: true, // Run compaction asynchronously
1781
+ debounceDelayMs: 5000, // Wait 5s before starting compaction
1782
+ maxPendingTasks: 3, // Maximum queued compactions
1783
+ onTaskComplete: (task) => {
1784
+ console.log(
1785
+ `Background compaction saved ${task.result.tokens_saved} tokens`,
1786
+ );
1787
+ },
1788
+ onTaskError: (task) => {
1789
+ console.error(`Compaction failed:`, task.error);
1790
+ },
1791
+ },
1792
+ });
1793
+
1794
+ const agent = createAgent({
1795
+ model,
1796
+ contextManager,
1797
+ });
1798
+
1799
+ // First generation: compaction is scheduled but doesn't block
1800
+ const result1 = await agent.generate({ prompt: "Hello" });
1801
+ // Returns immediately with original messages
1802
+
1803
+ // Background compaction runs after 5s debounce delay
1804
+
1805
+ // Next generation: applies the background compaction result
1806
+ const result2 = await agent.generate({ prompt: "Follow-up" });
1807
+ // Uses compacted messages from background task
1808
+ ```
1809
+
1810
+ **How it works**:
1811
+
1812
+ 1. **First Call**: When compaction is needed, it's scheduled in the background and original messages are used
1813
+ 2. **Background Execution**: After debounce delay, compaction runs asynchronously
1814
+ 3. **Next Call**: If background compaction completed, the result is applied automatically
1815
+ 4. **Debouncing**: Multiple rapid compaction triggers are coalesced to avoid redundant work
1816
+
1817
+ **Benefits**:
1818
+
1819
+ - No latency impact on user-facing responses
1820
+ - Debouncing prevents excessive compaction during rapid interactions
1821
+ - Queue management prevents memory issues during bursts
1822
+ - Graceful failure handling with callbacks
1823
+
1824
+ **When to use**:
1825
+
1826
+ - Interactive applications where latency matters
1827
+ - High-volume scenarios with many rapid turns
1828
+ - Long-running sessions with periodic compaction needs
1829
+
1830
+ **When to use synchronous compaction** (default behavior):
1831
+
1832
+ - Batch processing where latency isn't critical
1833
+ - Single-request scenarios without follow-up calls
1834
+ - When you need guaranteed compaction before the next generation
1835
+
1836
+ **Access scheduler directly**:
1837
+
1838
+ ```typescript
1839
+ // Check pending compactions
1840
+ const pendingTasks = contextManager.scheduler?.getPendingTasks();
1841
+ console.log(`${pendingTasks.length} compactions queued`);
1842
+
1843
+ // Get task details
1844
+ const task = contextManager.scheduler?.getTask(taskId);
1845
+ console.log(`Task status: ${task.status}`);
1846
+
1847
+ // Cancel a pending compaction
1848
+ contextManager.scheduler?.cancel(taskId);
1849
+
1850
+ // Clean up completed tasks
1851
+ contextManager.scheduler?.cleanup();
1852
+
1853
+ // Shutdown scheduler (cancels all pending)
1854
+ contextManager.scheduler?.shutdown();
1855
+ ```
1856
+
1857
+ ### Advanced Compaction Strategies
1858
+
1859
+ Choose from multiple compaction strategies to optimize context management for your use case.
1860
+
1861
+ #### Strategy Types
1862
+
1863
+ 1. **Rollup** (default): Summarize older messages into a single summary
1864
+ 2. **Tiered**: Create multiple summary layers (summary of summaries) for long conversations
1865
+ 3. **Structured**: Generate structured summaries with distinct sections (decisions, state, questions, references)
1866
+
1867
+ ```typescript
1868
+ import { createContextManager } from "@lleverage-ai/agent-sdk";
1869
+
1870
+ // Rollup strategy (default): single summary of old messages
1871
+ const contextManager1 = createContextManager({
1872
+ maxTokens: 100000,
1873
+ summarization: {
1874
+ keepMessageCount: 10,
1875
+ strategy: "rollup", // Simple summary rollup
1876
+ },
1877
+ });
1878
+
1879
+ // Tiered strategy: progressive summarization over time
1880
+ const contextManager2 = createContextManager({
1881
+ maxTokens: 100000,
1882
+ summarization: {
1883
+ keepMessageCount: 10,
1884
+ strategy: "tiered",
1885
+ enableTieredSummaries: true,
1886
+ maxSummaryTiers: 3, // Up to 3 summary levels
1887
+ messagesPerTier: 5, // Combine 5 summaries into next tier
1888
+ },
1889
+ });
1890
+
1891
+ // Structured strategy: summaries with organized sections
1892
+ const contextManager3 = createContextManager({
1893
+ maxTokens: 100000,
1894
+ summarization: {
1895
+ keepMessageCount: 10,
1896
+ strategy: "structured",
1897
+ enableStructuredSummary: true,
1898
+ },
1899
+ });
1900
+ ```
1901
+
1902
+ **When to use each strategy**:
1903
+
1904
+ - **Rollup**: Most use cases - simple and effective
1905
+ - **Tiered**: Very long conversations (100+ turns) where you want progressive compression
1906
+ - **Structured**: When you need to parse or query summary content programmatically
1907
+
1908
+ #### Structured Summaries
1909
+
1910
+ Structured summaries provide organized sections for better context organization:
1911
+
1912
+ ```typescript
1913
+ // Structured summary format
1914
+ {
1915
+ decisions: ["Chose TypeScript over JavaScript", "Using REST API"],
1916
+ preferences: ["Prefer functional style", "No external dependencies"],
1917
+ currentState: ["Authentication implemented", "Tests passing"],
1918
+ openQuestions: ["How to handle rate limiting?", "Deploy strategy TBD"],
1919
+ references: ["src/auth.ts:45", "API_KEY=abc123", "https://docs.example.com"]
1920
+ }
1921
+ ```
1922
+
1923
+ **Benefits**:
1924
+
1925
+ - Easy to parse and extract specific information
1926
+ - Better for long-term context retention
1927
+ - Enables semantic search within summaries
1928
+
1929
+ #### Pinned Messages
1930
+
1931
+ Pin important messages to ensure they're never compacted:
1932
+
1933
+ ```typescript
1934
+ import { createContextManager } from "@lleverage-ai/agent-sdk";
1935
+
1936
+ const contextManager = createContextManager({
1937
+ maxTokens: 100000,
1938
+ summarization: {
1939
+ keepMessageCount: 10,
1940
+ strategy: "rollup",
1941
+ },
1942
+ });
1943
+
1944
+ // Pin an important message
1945
+ contextManager.pinMessage(5, "Contains critical user requirements");
1946
+
1947
+ // Check if message is pinned
1948
+ if (contextManager.isPinned(5)) {
1949
+ console.log("Message 5 is protected from compaction");
1950
+ }
1951
+
1952
+ // Unpin when no longer needed
1953
+ contextManager.unpinMessage(5);
1954
+
1955
+ // View all pinned messages
1956
+ console.log("Pinned messages:", contextManager.pinnedMessages);
1957
+ // [{ messageIndex: 5, reason: "Contains critical user requirements", pinnedAt: 1770084888000 }]
1958
+ ```
1959
+
1960
+ **Use cases for pinning**:
1961
+
1962
+ - Critical user requirements or constraints
1963
+ - Important decisions that must be preserved
1964
+ - Configuration details referenced throughout the conversation
1965
+ - High-value context that shouldn't be summarized
1966
+
1967
+ **Note**: Pinned messages are always kept in full, regardless of compaction strategy. They appear after the summary and before recent messages in the compacted history.
1968
+
1969
+ #### Tiered Summaries
1970
+
1971
+ For extremely long conversations, tiered summaries create progressive compression:
1972
+
1973
+ ```typescript
1974
+ const contextManager = createContextManager({
1975
+ maxTokens: 100000,
1976
+ summarization: {
1977
+ keepMessageCount: 10,
1978
+ strategy: "tiered",
1979
+ enableTieredSummaries: true,
1980
+ maxSummaryTiers: 3,
1981
+ messagesPerTier: 5,
1982
+ },
1983
+ });
1984
+
1985
+ // First compaction: creates Tier 0 summary (summarizes old messages)
1986
+ // After 5 more compactions: creates Tier 1 summary (summarizes 5 Tier 0 summaries)
1987
+ // After 5 more Tier 1 summaries: creates Tier 2 summary (summarizes 5 Tier 1 summaries)
1988
+ ```
1989
+
1990
+ **How it works**:
1991
+
1992
+ 1. When you have < 5 summaries: creates regular Tier 0 summary
1993
+ 2. When you have ≥ 5 summaries: creates Tier 1 summary (consolidates the 5 summaries)
1994
+ 3. Continues creating higher tiers as needed up to `maxSummaryTiers`
1995
+
1996
+ **Benefits**:
1997
+
1998
+ - Handles extremely long conversations (1000+ turns)
1999
+ - Maintains important context across many interactions
2000
+ - Logarithmic memory usage as conversation grows
2001
+
2002
+ **Trade-offs**:
2003
+
2004
+ - Slightly higher compaction cost (more summarization calls)
2005
+ - Information loss increases with tier level
2006
+ - Best for conversations where recent context matters most
2007
+
2008
+ ### Rich Content Support
2009
+
2010
+ The context manager automatically handles messages with images, files, audio, and video content for token counting and summarization.
2011
+
2012
+ #### Supported Content Types
2013
+
2014
+ The SDK supports all AI SDK content part types:
2015
+
2016
+ - **TextPart**: Standard text messages
2017
+ - **ImagePart**: Images (URLs, base64, data URIs)
2018
+ - **FilePart**: Files (URLs, base64, data URIs)
2019
+ - **ToolCallPart**: Tool invocations
2020
+ - **ToolResultPart**: Tool execution results
2021
+
2022
+ ```typescript
2023
+ import { createAgent, createContextManager } from "@lleverage-ai/agent-sdk";
2024
+
2025
+ const agent = createAgent({
2026
+ model,
2027
+ contextManager: createContextManager({
2028
+ maxTokens: 100000,
2029
+ summarization: { keepMessageCount: 10 },
2030
+ }),
2031
+ });
2032
+
2033
+ // Messages with images
2034
+ const result = await agent.generate({
2035
+ messages: [
2036
+ {
2037
+ role: "user",
2038
+ content: [
2039
+ { type: "text", text: "What's in this screenshot?" },
2040
+ {
2041
+ type: "image",
2042
+ image: new URL("https://example.com/screenshot.png"),
2043
+ },
2044
+ ],
2045
+ },
2046
+ ],
2047
+ });
2048
+
2049
+ // Messages with files
2050
+ const result2 = await agent.generate({
2051
+ messages: [
2052
+ {
2053
+ role: "user",
2054
+ content: [
2055
+ { type: "text", text: "Analyze this document" },
2056
+ {
2057
+ type: "file",
2058
+ data: "base64data",
2059
+ mimeType: "application/pdf",
2060
+ },
2061
+ ],
2062
+ },
2063
+ ],
2064
+ });
2065
+ ```
2066
+
2067
+ #### Token Counting for Rich Content
2068
+
2069
+ The token counter automatically accounts for rich content:
2070
+
2071
+ - **Images**: ~1000 tokens per image (approximate vision model cost)
2072
+ - **Files**: ~500 tokens per file (varies by size and type)
2073
+ - **Text**: Character-based approximation or custom tokenizer
2074
+
2075
+ ```typescript
2076
+ import {
2077
+ createContextManager,
2078
+ createApproximateTokenCounter,
2079
+ } from "@lleverage-ai/agent-sdk";
2080
+
2081
+ const counter = createApproximateTokenCounter();
2082
+
2083
+ const messages = [
2084
+ {
2085
+ role: "user",
2086
+ content: [
2087
+ { type: "text", text: "Compare these images" },
2088
+ { type: "image", image: new URL("https://example.com/before.png") },
2089
+ { type: "image", image: new URL("https://example.com/after.png") },
2090
+ ],
2091
+ },
2092
+ ];
2093
+
2094
+ // Counts: text (~5) + 2 images (2000) + overhead (4) = ~2009 tokens
2095
+ const tokenCount = counter.countMessages(messages);
2096
+
2097
+ const contextManager = createContextManager({
2098
+ maxTokens: 10000,
2099
+ tokenCounter: counter, // Optional: use custom counter
2100
+ });
2101
+ ```
2102
+
2103
+ #### Rich Content in Summaries
2104
+
2105
+ When compaction occurs, the summarizer extracts metadata from rich content:
2106
+
2107
+ ```typescript
2108
+ const contextManager = createContextManager({
2109
+ maxTokens: 50000,
2110
+ summarization: {
2111
+ keepMessageCount: 10,
2112
+ strategy: "structured", // Best for rich content
2113
+ enableStructuredSummary: true,
2114
+ },
2115
+ });
2116
+
2117
+ // After compaction, summaries include:
2118
+ // - Image URLs and descriptions (e.g., "Image: screenshot.png showing login form")
2119
+ // - File references with MIME types (e.g., "File: document.pdf (application/pdf)")
2120
+ // - Context about what the media contained (from model analysis)
2121
+
2122
+ // Example structured summary with rich content:
2123
+ // {
2124
+ // "decisions": ["Use responsive design based on provided mockups"],
2125
+ // "preferences": ["User prefers dark color scheme"],
2126
+ // "currentState": ["Analyzed 3 screenshots showing current UI"],
2127
+ // "openQuestions": ["Should we support mobile tablets?"],
2128
+ // "references": [
2129
+ // "Image: https://example.com/screenshot1.png showing header",
2130
+ // "Image: https://example.com/screenshot2.png showing footer",
2131
+ // "File: spec.pdf containing technical requirements"
2132
+ // ]
2133
+ // }
2134
+ ```
2135
+
2136
+ **Best Practices**:
2137
+
2138
+ 1. **Use structured summaries** for conversations with many images/files to organize references
2139
+ 2. **Pin important media messages** if they contain critical information that shouldn't be summarized
2140
+ 3. **Monitor token budgets** - rich content uses significantly more tokens than text
2141
+ 4. **Consider background compaction** for image-heavy conversations to avoid blocking
2142
+ 5. **Use descriptive text** alongside media to help the summarizer capture context
2143
+
2144
+ **Token Budget Example**:
2145
+
2146
+ ```typescript
2147
+ const contextManager = createContextManager({
2148
+ maxTokens: 100000,
2149
+ policy: {
2150
+ tokenThreshold: 0.7, // Lower threshold for image-heavy conversations
2151
+ },
2152
+ });
2153
+
2154
+ // Check budget with rich content
2155
+ const budget = contextManager.getBudget(messages);
2156
+ console.log(`Usage: ${(budget.usage * 100).toFixed(1)}%`);
2157
+ console.log(`Images cost: ~${imageCount * 1000} tokens`);
2158
+ ```
2159
+
2160
+ **Note**: Token costs for images and files are approximations. Actual costs depend on:
2161
+
2162
+ - Image resolution and complexity (for vision models)
2163
+ - File size and content type
2164
+ - Model-specific encoding
2165
+
2166
+ For accurate token tracking, use model-specific tokenizers with `createCustomTokenCounter()` and update costs based on your provider's pricing.
2167
+
2168
+ ## Error Handling
2169
+
2170
+ Typed errors with recovery utilities.
2171
+
2172
+ ### Error Types
2173
+
2174
+ ```typescript
2175
+ import {
2176
+ AgentError,
2177
+ ToolExecutionError,
2178
+ ModelError,
2179
+ TimeoutError,
2180
+ RateLimitError,
2181
+ } from "@lleverage-ai/agent-sdk";
2182
+
2183
+ try {
2184
+ await agent.generate({ prompt });
2185
+ } catch (error) {
2186
+ if (error instanceof RateLimitError) {
2187
+ // Wait and retry
2188
+ } else if (error instanceof TimeoutError) {
2189
+ // Handle timeout
2190
+ } else if (error instanceof ToolExecutionError) {
2191
+ console.error("Tool failed:", error.toolName, error.cause);
2192
+ }
2193
+ }
2194
+ ```
2195
+
2196
+ ### Error Utilities
2197
+
2198
+ ```typescript
2199
+ import {
2200
+ wrapError,
2201
+ isRetryable,
2202
+ getUserMessage,
2203
+ createErrorHandler,
2204
+ } from "@lleverage-ai/agent-sdk";
2205
+
2206
+ // Wrap unknown errors
2207
+ const agentError = wrapError(unknownError, { context: "generation" });
2208
+
2209
+ // Check if error is retryable
2210
+ if (isRetryable(error)) {
2211
+ // Retry logic
2212
+ }
2213
+
2214
+ // Get user-friendly message
2215
+ const message = getUserMessage(error);
2216
+ ```
2217
+
2218
+ ### Graceful Degradation
2219
+
2220
+ ```typescript
2221
+ import {
2222
+ withFallback,
2223
+ tryOperations,
2224
+ createCircuitBreaker,
2225
+ } from "@lleverage-ai/agent-sdk";
2226
+
2227
+ // Single fallback
2228
+ const result = await withFallback(
2229
+ () => primaryOperation(),
2230
+ () => fallbackOperation(),
2231
+ );
2232
+
2233
+ // Try multiple operations
2234
+ const result = await tryOperations([
2235
+ () => attempt1(),
2236
+ () => attempt2(),
2237
+ () => attempt3(),
2238
+ ]);
2239
+
2240
+ // Circuit breaker pattern
2241
+ const breaker = createCircuitBreaker({
2242
+ threshold: 5,
2243
+ resetTimeout: 60000,
2244
+ });
2245
+
2246
+ const result = await breaker.execute(() => riskyOperation());
2247
+ ```
2248
+
2249
+ ## API Reference
2250
+
2251
+ ### Agent Creation
2252
+
2253
+ | Function | Description |
2254
+ | ------------------------- | ------------------------------------- |
2255
+ | `createAgent(options)` | Create a new agent instance |
2256
+ | `createSubagent(options)` | Define a subagent for task delegation |
2257
+
2258
+ ### Tools
2259
+
2260
+ | Function | Description |
2261
+ | -------------------------------- | ------------------------------- |
2262
+ | `createCoreTools(options)` | Create all core tools |
2263
+ | `createFilesystemTools(backend)` | Create filesystem tools only |
2264
+ | `createBashTool(options)` | Create shell execution tool |
2265
+ | `createTaskTool(options)` | Create subagent delegation tool |
2266
+ | `createSearchToolsTool(options)` | Create MCP tool search |
2267
+
2268
+ ### Plugins
2269
+
2270
+ | Function | Description |
2271
+ | ----------------------- | --------------------------------- |
2272
+ | `definePlugin(options)` | Define a plugin |
2273
+ | `defineSkill(options)` | Define a skill with tool guidance |
2274
+
2275
+ ### Backends
2276
+
2277
+ | Class | Description |
2278
+ | ------------------- | ------------------------------------- |
2279
+ | `FilesystemBackend` | File operations with security |
2280
+ | `StateBackend` | In-memory filesystem |
2281
+ | `LocalSandbox` | Command execution sandbox |
2282
+ | `CompositeBackend` | Route operations to multiple backends |
2283
+
2284
+ ### Middleware
2285
+
2286
+ | Function | Description |
2287
+ | ------------------------------ | --------------------------- |
2288
+ | `createLoggingMiddleware()` | Log requests and responses |
2289
+ | `createCacheMiddleware()` | Cache responses |
2290
+ | `createRetryMiddleware()` | Retry failed requests |
2291
+ | `createGuardrailsMiddleware()` | Content filtering |
2292
+ | `composeMiddleware()` | Combine multiple middleware |
2293
+
2294
+ ### Checkpointing
2295
+
2296
+ | Class | Description |
2297
+ | -------------------- | ------------------------- |
2298
+ | `MemorySaver` | In-memory checkpoints |
2299
+ | `FileSaver` | File-based checkpoints |
2300
+ | `KeyValueStoreSaver` | Generic key-value storage |
2301
+
2302
+ ### Memory
2303
+
2304
+ | Class | Description |
2305
+ | ----------------------- | ------------------------- |
2306
+ | `FilesystemMemoryStore` | Persistent memory storage |
2307
+ | `InMemoryMemoryStore` | In-memory storage |
2308
+
2309
+ ### Observability
2310
+
2311
+ | Function | Description |
2312
+ | --------------------------------- | ---------------------------- |
2313
+ | `createLogger()` | Create structured logger |
2314
+ | `createMetricsRegistry()` | Create metrics collector |
2315
+ | `createTracer()` | Create distributed tracer |
2316
+ | `createObservabilityPreset()` | One-line observability setup |
2317
+ | `createObservabilityEventHooks()` | Collect observability events |
2318
+
2319
+ ## License
2320
+
2321
+ MIT