fourmis-agents-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +309 -0
  3. package/dist/agent-loop.d.ts +36 -0
  4. package/dist/agent-loop.d.ts.map +1 -0
  5. package/dist/agent-loop.js +387 -0
  6. package/dist/agents/index.d.ts +8 -0
  7. package/dist/agents/index.d.ts.map +1 -0
  8. package/dist/agents/index.js +2309 -0
  9. package/dist/agents/task-manager.d.ts +14 -0
  10. package/dist/agents/task-manager.d.ts.map +1 -0
  11. package/dist/agents/task-manager.js +67 -0
  12. package/dist/agents/tools.d.ts +24 -0
  13. package/dist/agents/tools.d.ts.map +1 -0
  14. package/dist/agents/tools.js +2257 -0
  15. package/dist/agents/types.d.ts +22 -0
  16. package/dist/agents/types.d.ts.map +1 -0
  17. package/dist/agents/types.js +1 -0
  18. package/dist/api.d.ts +35 -0
  19. package/dist/api.d.ts.map +1 -0
  20. package/dist/api.js +2983 -0
  21. package/dist/auth/login-openai.d.ts +10 -0
  22. package/dist/auth/login-openai.d.ts.map +1 -0
  23. package/dist/auth/login-openai.js +316 -0
  24. package/dist/auth/openai-oauth.d.ts +45 -0
  25. package/dist/auth/openai-oauth.d.ts.map +1 -0
  26. package/dist/auth/openai-oauth.js +308 -0
  27. package/dist/hooks.d.ts +71 -0
  28. package/dist/hooks.d.ts.map +1 -0
  29. package/dist/hooks.js +87 -0
  30. package/dist/index.d.ts +27 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +3025 -0
  33. package/dist/mcp/client.d.ts +24 -0
  34. package/dist/mcp/client.d.ts.map +1 -0
  35. package/dist/mcp/client.js +176 -0
  36. package/dist/mcp/index.d.ts +8 -0
  37. package/dist/mcp/index.d.ts.map +1 -0
  38. package/dist/mcp/index.js +203 -0
  39. package/dist/mcp/server.d.ts +25 -0
  40. package/dist/mcp/server.d.ts.map +1 -0
  41. package/dist/mcp/server.js +42 -0
  42. package/dist/mcp/types.d.ts +47 -0
  43. package/dist/mcp/types.d.ts.map +1 -0
  44. package/dist/mcp/types.js +1 -0
  45. package/dist/permissions.d.ts +29 -0
  46. package/dist/permissions.d.ts.map +1 -0
  47. package/dist/permissions.js +157 -0
  48. package/dist/providers/anthropic.d.ts +26 -0
  49. package/dist/providers/anthropic.d.ts.map +1 -0
  50. package/dist/providers/anthropic.js +382 -0
  51. package/dist/providers/openai.d.ts +42 -0
  52. package/dist/providers/openai.d.ts.map +1 -0
  53. package/dist/providers/openai.js +871 -0
  54. package/dist/providers/registry.d.ts +11 -0
  55. package/dist/providers/registry.d.ts.map +1 -0
  56. package/dist/providers/registry.js +1118 -0
  57. package/dist/providers/types.d.ts +79 -0
  58. package/dist/providers/types.d.ts.map +1 -0
  59. package/dist/providers/types.js +1 -0
  60. package/dist/query.d.ts +9 -0
  61. package/dist/query.d.ts.map +1 -0
  62. package/dist/query.js +36 -0
  63. package/dist/settings.d.ts +28 -0
  64. package/dist/settings.d.ts.map +1 -0
  65. package/dist/settings.js +143 -0
  66. package/dist/tools/bash.d.ts +6 -0
  67. package/dist/tools/bash.d.ts.map +1 -0
  68. package/dist/tools/bash.js +88 -0
  69. package/dist/tools/edit.d.ts +6 -0
  70. package/dist/tools/edit.d.ts.map +1 -0
  71. package/dist/tools/edit.js +108 -0
  72. package/dist/tools/glob.d.ts +6 -0
  73. package/dist/tools/glob.d.ts.map +1 -0
  74. package/dist/tools/glob.js +70 -0
  75. package/dist/tools/grep.d.ts +7 -0
  76. package/dist/tools/grep.d.ts.map +1 -0
  77. package/dist/tools/grep.js +183 -0
  78. package/dist/tools/index.d.ts +18 -0
  79. package/dist/tools/index.d.ts.map +1 -0
  80. package/dist/tools/index.js +595 -0
  81. package/dist/tools/mcp-resources.d.ts +8 -0
  82. package/dist/tools/mcp-resources.d.ts.map +1 -0
  83. package/dist/tools/mcp-resources.js +87 -0
  84. package/dist/tools/presets.d.ts +6 -0
  85. package/dist/tools/presets.d.ts.map +1 -0
  86. package/dist/tools/presets.js +32 -0
  87. package/dist/tools/read.d.ts +6 -0
  88. package/dist/tools/read.d.ts.map +1 -0
  89. package/dist/tools/read.js +81 -0
  90. package/dist/tools/registry.d.ts +31 -0
  91. package/dist/tools/registry.d.ts.map +1 -0
  92. package/dist/tools/registry.js +52 -0
  93. package/dist/tools/write.d.ts +6 -0
  94. package/dist/tools/write.d.ts.map +1 -0
  95. package/dist/tools/write.js +62 -0
  96. package/dist/types.d.ts +201 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +39 -0
  99. package/dist/utils/cost.d.ts +35 -0
  100. package/dist/utils/cost.d.ts.map +1 -0
  101. package/dist/utils/cost.js +176 -0
  102. package/dist/utils/system-prompt.d.ts +11 -0
  103. package/dist/utils/system-prompt.d.ts.map +1 -0
  104. package/dist/utils/system-prompt.js +89 -0
  105. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 jcanizalez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,309 @@
1
+ # fourmis-agents-sdk
2
+
3
+ Multi-provider AI agent SDK with direct API access and in-process tool execution.
4
+
5
+ > **Requires [Bun](https://bun.sh) v1.0+** — this SDK uses Bun-native APIs (`Bun.spawn`, `Bun.Glob`, `Bun.build`) and is not compatible with Node.js.
6
+
7
+ A TypeScript library that gives you coding agents on **any LLM provider** — same `query()` API, same streaming events, same tool capabilities — without being locked to a single vendor.
8
+
9
+ ## Why?
10
+
11
+ The [Anthropic Agent SDK](https://github.com/anthropics/claude-agent-sdk-typescript) is excellent but:
12
+ - **Claude-only** — spawns a Claude Code subprocess, no other providers
13
+ - **Opaque** — the agent loop runs inside the subprocess
14
+ - **~12s startup overhead** per query (subprocess spawn)
15
+
16
+ `fourmis-agents-sdk` provides:
17
+ - **Multi-provider** — Anthropic (direct API) and OpenAI out of the box, extensible via `registerProvider()`
18
+ - **Transparent agent loop** — you control the execution cycle
19
+ - **No subprocess overhead** — direct API calls, <100ms startup
20
+ - **In-process tool execution** — 6 built-in coding tools
21
+
22
+ ## Quick Start
23
+
24
+ ```ts
25
+ import { query } from "fourmis-agents-sdk";
26
+
27
+ const conversation = query({
28
+ prompt: "Read package.json and tell me the project name",
29
+ options: {
30
+ provider: "anthropic",
31
+ model: "claude-sonnet-4-5-20250929",
32
+ cwd: "./my-project",
33
+ tools: "coding", // preset: Bash, Read, Write, Edit, Glob, Grep
34
+ maxTurns: 5,
35
+ },
36
+ });
37
+
38
+ for await (const msg of conversation) {
39
+ if (msg.type === "text") process.stdout.write(msg.text);
40
+ if (msg.type === "tool_use") console.log(`\n[tool] ${msg.name}`);
41
+ if (msg.type === "result") console.log(`\nDone: $${msg.costUsd}`);
42
+ }
43
+ ```
44
+
45
+ ## Features
46
+
47
+ ### Providers
48
+
49
+ Two built-in providers, with an extensible registry:
50
+
51
+ | Provider | Auth | Models |
52
+ |----------|------|--------|
53
+ | `anthropic` | `ANTHROPIC_API_KEY` | Claude Sonnet, Opus, Haiku |
54
+ | `openai` | `OPENAI_API_KEY` or Codex OAuth | GPT-4o, o3, etc. |
55
+
56
+ ```ts
57
+ // Use OpenAI instead
58
+ query({ prompt: "...", options: { provider: "openai", model: "gpt-4o" } });
59
+
60
+ // Register a custom provider
61
+ import { registerProvider } from "fourmis-agents-sdk";
62
+ registerProvider("my-provider", myAdapter);
63
+ ```
64
+
65
+ ### Tools
66
+
67
+ 6 built-in tools with 3 presets:
68
+
69
+ | Tool | Description |
70
+ |------|-------------|
71
+ | `Bash` | Shell command execution via `Bun.spawn()` |
72
+ | `Read` | File reading with line numbers |
73
+ | `Write` | File creation/overwriting |
74
+ | `Edit` | String replacement with uniqueness check |
75
+ | `Glob` | File pattern matching |
76
+ | `Grep` | Regex content search |
77
+
78
+ ```ts
79
+ // Presets
80
+ tools: "coding" // All 6: Bash, Read, Write, Edit, Glob, Grep
81
+ tools: "readonly" // Read, Glob, Grep
82
+ tools: "minimal" // Read, Write, Edit, Glob, Grep
83
+
84
+ // Custom list
85
+ tools: ["Read", "Glob", "Grep"]
86
+
87
+ // Filter tools
88
+ allowedTools: ["Read", "Bash"]
89
+ disallowedTools: ["Bash"]
90
+ ```
91
+
92
+ ### Hooks
93
+
94
+ Lifecycle callbacks for observing and intervening at key points in the agent loop:
95
+
96
+ | Event | When |
97
+ |-------|------|
98
+ | `PreToolUse` | Before a tool executes — can deny or modify input |
99
+ | `PostToolUse` | After a tool succeeds — can append context |
100
+ | `PostToolUseFailure` | After a tool fails or is denied |
101
+ | `SessionStart` / `SessionEnd` | Session lifecycle |
102
+ | `Stop` | Before the agent returns its final result |
103
+ | `Notification` | Informational events |
104
+ | `SubagentStart` / `SubagentStop` | Subagent lifecycle |
105
+ | `PreCompact` | Before context compaction |
106
+ | `PermissionRequest` | When a permission decision is needed |
107
+ | `UserPromptSubmit` | When a user prompt is submitted |
108
+
109
+ ```ts
110
+ query({
111
+ prompt: "...",
112
+ options: {
113
+ hooks: {
114
+ PreToolUse: [{
115
+ matcher: "Bash", // regex matched against tool name
116
+ hooks: [async (input) => {
117
+ console.log("Running:", input.tool_input);
118
+ return {}; // or { permissionDecision: "deny" }
119
+ }],
120
+ }],
121
+ },
122
+ },
123
+ });
124
+ ```
125
+
126
+ ### MCP (Model Context Protocol)
127
+
128
+ Connect to external MCP servers to extend the agent with additional tools. Supports 4 transport types:
129
+
130
+ ```ts
131
+ query({
132
+ prompt: "...",
133
+ options: {
134
+ mcpServers: {
135
+ // stdio
136
+ myServer: { command: "node", args: ["server.js"] },
137
+ // SSE
138
+ remote: { type: "sse", url: "http://localhost:3000/sse" },
139
+ // HTTP
140
+ httpServer: { type: "http", url: "http://localhost:3000" },
141
+ // In-process SDK server
142
+ inProc: { type: "sdk", name: "myTools", instance: myMcpServer },
143
+ },
144
+ },
145
+ });
146
+ ```
147
+
148
+ Create in-process MCP servers with Zod-typed tools:
149
+
150
+ ```ts
151
+ import { createMcpServer, mcpTool } from "fourmis-agents-sdk";
152
+ import { z } from "zod";
153
+
154
+ const server = createMcpServer({
155
+ name: "my-tools",
156
+ tools: [
157
+ mcpTool("greet", "Say hello", z.object({ name: z.string() }), async ({ name }) => ({
158
+ content: [{ type: "text", text: `Hello, ${name}!` }],
159
+ })),
160
+ ],
161
+ });
162
+ ```
163
+
164
+ ### Subagents
165
+
166
+ Define specialized agents that the main agent can spawn via the `Task` tool:
167
+
168
+ ```ts
169
+ query({
170
+ prompt: "Refactor the auth module",
171
+ options: {
172
+ agents: {
173
+ researcher: {
174
+ description: "Reads code and answers questions",
175
+ prompt: "You are a code researcher. Read files and answer questions.",
176
+ tools: ["Read", "Glob", "Grep"],
177
+ model: "claude-haiku-4-5-20251001",
178
+ },
179
+ coder: {
180
+ description: "Writes and edits code",
181
+ prompt: "You are a code editor.",
182
+ tools: ["Read", "Write", "Edit", "Glob", "Grep"],
183
+ provider: "openai", // can use a different provider per agent
184
+ },
185
+ },
186
+ },
187
+ });
188
+ ```
189
+
190
+ Subagents run as background tasks managed by a `TaskManager` and expose `Task`, `TaskOutput`, and `TaskStop` tools to the parent agent.
191
+
192
+ ### Permissions
193
+
194
+ 6 permission modes control what the agent can do:
195
+
196
+ | Mode | Behavior |
197
+ |------|----------|
198
+ | `default` | Allow all (host app handles permissions) |
199
+ | `bypassPermissions` | Allow everything unconditionally |
200
+ | `acceptEdits` | Auto-approve read + file edit tools |
201
+ | `plan` | Read-only tools only |
202
+ | `delegate` | Team coordination tools only |
203
+ | `dontAsk` | Deny anything not in the allow list |
204
+
205
+ ```ts
206
+ query({
207
+ prompt: "...",
208
+ options: {
209
+ permissionMode: "acceptEdits",
210
+ permissions: {
211
+ allow: ["Read", "Glob", "Grep", { toolName: "Bash", ruleContent: "npm test" }],
212
+ deny: ["Bash"],
213
+ },
214
+ // Or provide a custom callback
215
+ canUseTool: async (toolName, input, options) => {
216
+ return { behavior: "allow" };
217
+ },
218
+ },
219
+ });
220
+ ```
221
+
222
+ ### Settings Files
223
+
224
+ Load permissions from `.claude/settings*.json` files (compatible with Claude Code's format):
225
+
226
+ ```ts
227
+ query({
228
+ prompt: "...",
229
+ options: {
230
+ settingSources: ["user", "project", "local"],
231
+ // Loads from:
232
+ // ~/.claude/settings.json (user-wide)
233
+ // <cwd>/.claude/settings.json (project, shared)
234
+ // <cwd>/.claude/settings.local.json (personal, gitignored)
235
+ },
236
+ });
237
+ ```
238
+
239
+ ## Configuration Reference
240
+
241
+ All options passed via `QueryOptions`:
242
+
243
+ ```ts
244
+ query({
245
+ prompt: "...",
246
+ options: {
247
+ // Provider
248
+ provider: "anthropic", // "anthropic" | "openai" | custom
249
+ apiKey: "sk-...", // Override env var
250
+ baseUrl: "https://...", // Custom endpoint
251
+
252
+ // Core
253
+ model: "claude-sonnet-4-5-20250929",
254
+ cwd: "/path/to/project",
255
+ systemPrompt: "You are...",
256
+ maxTurns: 10, // Default: 10
257
+ maxBudgetUsd: 5, // Default: $5
258
+ maxThinkingTokens: 10000,
259
+
260
+ // Tools
261
+ tools: "coding", // Preset name or string[]
262
+ allowedTools: ["Read"], // Whitelist
263
+ disallowedTools: ["Bash"], // Blacklist
264
+
265
+ // Permissions
266
+ permissionMode: "default",
267
+ canUseTool: async () => ({ behavior: "allow" }),
268
+ permissions: { allow: [...], deny: [...] },
269
+ settingSources: ["user", "project", "local"],
270
+
271
+ // Streaming
272
+ includeStreamEvents: false, // Emit text_delta/thinking_delta events
273
+
274
+ // Hooks, MCP, Subagents (see sections above)
275
+ hooks: { ... },
276
+ mcpServers: { ... },
277
+ agents: { ... },
278
+
279
+ // Debug
280
+ debug: false,
281
+ signal: abortController.signal,
282
+ env: { PATH: "..." },
283
+ },
284
+ });
285
+ ```
286
+
287
+ ## Message Types
288
+
289
+ The query yields `AgentMessage` events:
290
+
291
+ | Type | Description |
292
+ |------|-------------|
293
+ | `init` | Session started — includes model, provider, tools, cwd |
294
+ | `text` | Assistant text output |
295
+ | `tool_use` | Tool invocation (name, input) |
296
+ | `tool_result` | Tool result (content, isError) |
297
+ | `stream` | Streaming delta (text or thinking) — only with `includeStreamEvents: true` |
298
+ | `result` (success) | Final result with cost, duration, usage stats |
299
+ | `result` (error) | Error result (execution error, max turns, max budget) |
300
+ | `status` | Status update |
301
+
302
+ ## Runtime
303
+
304
+ Built for [Bun](https://bun.sh). Uses `Bun.spawn()` for the Bash tool and `Bun.Glob` for pattern matching.
305
+
306
+ ```sh
307
+ bun add fourmis-agents-sdk
308
+ bun test
309
+ ```
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Agent loop — the core LLM ↔ tool execution engine.
3
+ *
4
+ * AsyncGenerator that orchestrates:
5
+ * 1. Call LLM via provider adapter
6
+ * 2. Stream text deltas as AgentMessage events
7
+ * 3. Collect tool calls
8
+ * 4. Execute tools with permission checks
9
+ * 5. Feed results back to LLM
10
+ * 6. Repeat until done or limits reached
11
+ */
12
+ import type { AgentMessage } from "./types.js";
13
+ import type { ProviderAdapter } from "./providers/types.js";
14
+ import type { ToolRegistry } from "./tools/registry.js";
15
+ import type { PermissionManager } from "./permissions.js";
16
+ import type { HookManager } from "./hooks.js";
17
+ import type { McpClientManager } from "./mcp/client.js";
18
+ export type AgentLoopOptions = {
19
+ provider: ProviderAdapter;
20
+ model: string;
21
+ systemPrompt: string;
22
+ tools: ToolRegistry;
23
+ permissions: PermissionManager;
24
+ cwd: string;
25
+ sessionId: string;
26
+ maxTurns: number;
27
+ maxBudgetUsd: number;
28
+ includeStreamEvents: boolean;
29
+ signal: AbortSignal;
30
+ env?: Record<string, string>;
31
+ debug?: boolean;
32
+ hooks?: HookManager;
33
+ mcpClient?: McpClientManager;
34
+ };
35
+ export declare function agentLoop(prompt: string, options: AgentLoopOptions): AsyncGenerator<AgentMessage>;
36
+ //# sourceMappingURL=agent-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,YAAY,EAGb,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,eAAe,EAAmD,MAAM,sBAAsB,CAAC;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,MAAM,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B,CAAC;AAEF,wBAAuB,SAAS,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,GACxB,cAAc,CAAC,YAAY,CAAC,CA4W9B"}