@funkai/agents 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.
- package/.generated/req.txt +1 -0
- package/.turbo/turbo-build.log +21 -0
- package/.turbo/turbo-test$colon$coverage.log +109 -0
- package/.turbo/turbo-test.log +141 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +16 -0
- package/ISSUES.md +540 -0
- package/LICENSE +21 -0
- package/README.md +128 -0
- package/banner.svg +97 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/core/agents/base/agent.ts.html +1705 -0
- package/coverage/lcov-report/core/agents/base/index.html +146 -0
- package/coverage/lcov-report/core/agents/base/output.ts.html +256 -0
- package/coverage/lcov-report/core/agents/base/utils.ts.html +694 -0
- package/coverage/lcov-report/core/agents/flow/engine.ts.html +928 -0
- package/coverage/lcov-report/core/agents/flow/flow-agent.ts.html +1462 -0
- package/coverage/lcov-report/core/agents/flow/index.html +146 -0
- package/coverage/lcov-report/core/agents/flow/messages.ts.html +508 -0
- package/coverage/lcov-report/core/agents/flow/steps/factory.ts.html +1975 -0
- package/coverage/lcov-report/core/agents/flow/steps/index.html +116 -0
- package/coverage/lcov-report/core/index.html +131 -0
- package/coverage/lcov-report/core/logger.ts.html +541 -0
- package/coverage/lcov-report/core/models/providers/index.html +116 -0
- package/coverage/lcov-report/core/models/providers/openai.ts.html +337 -0
- package/coverage/lcov-report/core/provider/index.html +131 -0
- package/coverage/lcov-report/core/provider/provider.ts.html +346 -0
- package/coverage/lcov-report/core/provider/usage.ts.html +376 -0
- package/coverage/lcov-report/core/tool.ts.html +577 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +221 -0
- package/coverage/lcov-report/lib/hooks.ts.html +262 -0
- package/coverage/lcov-report/lib/index.html +161 -0
- package/coverage/lcov-report/lib/middleware.ts.html +274 -0
- package/coverage/lcov-report/lib/runnable.ts.html +151 -0
- package/coverage/lcov-report/lib/trace.ts.html +520 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/utils/attempt.ts.html +199 -0
- package/coverage/lcov-report/utils/error.ts.html +421 -0
- package/coverage/lcov-report/utils/index.html +176 -0
- package/coverage/lcov-report/utils/resolve.ts.html +208 -0
- package/coverage/lcov-report/utils/result.ts.html +538 -0
- package/coverage/lcov-report/utils/zod.ts.html +178 -0
- package/coverage/lcov.info +1566 -0
- package/dist/index.d.mts +2883 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2312 -0
- package/dist/index.mjs.map +1 -0
- package/docs/core/agent.md +231 -0
- package/docs/core/hooks.md +95 -0
- package/docs/core/overview.md +87 -0
- package/docs/core/step.md +279 -0
- package/docs/core/tools.md +98 -0
- package/docs/core/workflow.md +235 -0
- package/docs/guides/create-agent.md +224 -0
- package/docs/guides/create-tool.md +137 -0
- package/docs/guides/create-workflow.md +374 -0
- package/docs/overview.md +244 -0
- package/docs/provider/models.md +55 -0
- package/docs/provider/overview.md +106 -0
- package/docs/provider/usage.md +100 -0
- package/docs/research/experimental-context.md +167 -0
- package/docs/research/gap-analysis.md +86 -0
- package/docs/research/prepare-step-and-active-tools.md +138 -0
- package/docs/research/sub-agent-model.md +249 -0
- package/docs/troubleshooting.md +60 -0
- package/logo.svg +17 -0
- package/models.config.json +18 -0
- package/package.json +60 -0
- package/scripts/generate-models.ts +324 -0
- package/src/core/agents/base/agent.test.ts +1522 -0
- package/src/core/agents/base/agent.ts +547 -0
- package/src/core/agents/base/output.test.ts +93 -0
- package/src/core/agents/base/output.ts +57 -0
- package/src/core/agents/base/types.test-d.ts +69 -0
- package/src/core/agents/base/types.ts +503 -0
- package/src/core/agents/base/utils.test.ts +397 -0
- package/src/core/agents/base/utils.ts +197 -0
- package/src/core/agents/flow/engine.test.ts +452 -0
- package/src/core/agents/flow/engine.ts +281 -0
- package/src/core/agents/flow/flow-agent.test.ts +1027 -0
- package/src/core/agents/flow/flow-agent.ts +473 -0
- package/src/core/agents/flow/messages.test.ts +198 -0
- package/src/core/agents/flow/messages.ts +141 -0
- package/src/core/agents/flow/steps/agent.test.ts +280 -0
- package/src/core/agents/flow/steps/agent.ts +87 -0
- package/src/core/agents/flow/steps/all.test.ts +300 -0
- package/src/core/agents/flow/steps/all.ts +73 -0
- package/src/core/agents/flow/steps/builder.ts +124 -0
- package/src/core/agents/flow/steps/each.test.ts +257 -0
- package/src/core/agents/flow/steps/each.ts +61 -0
- package/src/core/agents/flow/steps/factory.test-d.ts +50 -0
- package/src/core/agents/flow/steps/factory.test.ts +1025 -0
- package/src/core/agents/flow/steps/factory.ts +645 -0
- package/src/core/agents/flow/steps/map.test.ts +273 -0
- package/src/core/agents/flow/steps/map.ts +75 -0
- package/src/core/agents/flow/steps/race.test.ts +290 -0
- package/src/core/agents/flow/steps/race.ts +59 -0
- package/src/core/agents/flow/steps/reduce.test.ts +310 -0
- package/src/core/agents/flow/steps/reduce.ts +73 -0
- package/src/core/agents/flow/steps/result.ts +27 -0
- package/src/core/agents/flow/steps/step.test.ts +402 -0
- package/src/core/agents/flow/steps/step.ts +51 -0
- package/src/core/agents/flow/steps/while.test.ts +283 -0
- package/src/core/agents/flow/steps/while.ts +75 -0
- package/src/core/agents/flow/types.ts +348 -0
- package/src/core/logger.test.ts +163 -0
- package/src/core/logger.ts +152 -0
- package/src/core/models/index.test.ts +137 -0
- package/src/core/models/index.ts +152 -0
- package/src/core/models/providers/openai.ts +84 -0
- package/src/core/provider/provider.test.ts +128 -0
- package/src/core/provider/provider.ts +99 -0
- package/src/core/provider/types.ts +98 -0
- package/src/core/provider/usage.test.ts +304 -0
- package/src/core/provider/usage.ts +97 -0
- package/src/core/tool.test.ts +65 -0
- package/src/core/tool.ts +164 -0
- package/src/core/types.ts +66 -0
- package/src/index.ts +95 -0
- package/src/lib/context.test.ts +86 -0
- package/src/lib/context.ts +49 -0
- package/src/lib/hooks.test.ts +102 -0
- package/src/lib/hooks.ts +59 -0
- package/src/lib/middleware.test.ts +122 -0
- package/src/lib/middleware.ts +63 -0
- package/src/lib/runnable.test.ts +41 -0
- package/src/lib/runnable.ts +22 -0
- package/src/lib/trace.test.ts +291 -0
- package/src/lib/trace.ts +145 -0
- package/src/models/index.ts +123 -0
- package/src/models/providers/index.ts +15 -0
- package/src/models/providers/openai.ts +84 -0
- package/src/testing/context.ts +32 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/logger.ts +19 -0
- package/src/utils/attempt.test.ts +127 -0
- package/src/utils/attempt.ts +38 -0
- package/src/utils/error.test.ts +179 -0
- package/src/utils/error.ts +112 -0
- package/src/utils/resolve.test.ts +38 -0
- package/src/utils/resolve.ts +41 -0
- package/src/utils/result.test.ts +79 -0
- package/src/utils/result.ts +151 -0
- package/src/utils/zod.test.ts +69 -0
- package/src/utils/zod.ts +31 -0
- package/tsconfig.json +25 -0
- package/tsdown.config.ts +15 -0
- package/vitest.config.ts +46 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Research: Sub-Agent Model (Claude Code-style)
|
|
2
|
+
|
|
3
|
+
> **Date**: 2026-03-06
|
|
4
|
+
> **AI SDK Version**: `^6.0.111`
|
|
5
|
+
> **Status**: Core primitives exist; gaps identified for full sub-agent orchestration
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
Our agent SDK already supports basic sub-agent delegation — agents can be passed as `agents` in config and are auto-wrapped as tools. However, several capabilities needed for a full Claude Code-style sub-agent model are missing: context forwarding, dynamic spawning, shared memory, and result-to-context feedback.
|
|
10
|
+
|
|
11
|
+
## What Exists Today
|
|
12
|
+
|
|
13
|
+
### Agent-as-Tool Delegation (`utils.ts:39-96`)
|
|
14
|
+
|
|
15
|
+
Sub-agents are declared in `AgentConfig.agents` and auto-wrapped into AI SDK tools by `buildAITools()`:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
const parent = agent({
|
|
19
|
+
name: "orchestrator",
|
|
20
|
+
model: "anthropic/claude-sonnet-4",
|
|
21
|
+
tools: { search, readFile },
|
|
22
|
+
agents: { researcher, coder }, // auto-wrapped as callable tools
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Under the hood, each sub-agent becomes a tool:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// For typed sub-agents (with input schema):
|
|
30
|
+
tool({
|
|
31
|
+
description: `Delegate to ${toolName}`,
|
|
32
|
+
inputSchema: meta.inputSchema,
|
|
33
|
+
execute: async (input, { abortSignal }) => {
|
|
34
|
+
const r = await runnable.generate(input, { signal: abortSignal });
|
|
35
|
+
if (!r.ok) throw new Error(r.error.message);
|
|
36
|
+
return r.output;
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// For untyped sub-agents (simple mode):
|
|
41
|
+
tool({
|
|
42
|
+
description: `Delegate to ${toolName}`,
|
|
43
|
+
inputSchema: z.object({ prompt: z.string() }),
|
|
44
|
+
execute: async ({ prompt }, { abortSignal }) => {
|
|
45
|
+
const r = await runnable.generate(prompt, { signal: abortSignal });
|
|
46
|
+
if (!r.ok) throw new Error(r.error.message);
|
|
47
|
+
return r.output;
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Signal Propagation
|
|
53
|
+
|
|
54
|
+
`abortSignal` flows from parent to child automatically. If the parent is cancelled, child agents abort.
|
|
55
|
+
|
|
56
|
+
### RUNNABLE_META
|
|
57
|
+
|
|
58
|
+
Agents carry metadata via a symbol key (`RUNNABLE_META`) containing `name` and `inputSchema`. This allows `buildAITools` to create properly described tools without reflection.
|
|
59
|
+
|
|
60
|
+
### Workflow-Level Orchestration (`StepBuilder.$`)
|
|
61
|
+
|
|
62
|
+
The `$.agent()` step provides tracked sub-agent invocation within workflows:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const result = await $.agent({
|
|
66
|
+
id: "analyze",
|
|
67
|
+
agent: analyzerAgent,
|
|
68
|
+
input: { filePath: "..." },
|
|
69
|
+
config: { tools: extraTools },
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This records the agent call in the execution trace with input/output/usage.
|
|
74
|
+
|
|
75
|
+
## Gaps for Claude Code-style Sub-Agents
|
|
76
|
+
|
|
77
|
+
### Gap 1: No Context Forwarding to Sub-Agents
|
|
78
|
+
|
|
79
|
+
**Problem**: Sub-agents start fresh. They receive only the `input` argument — not the parent's conversation history, accumulated knowledge, or `experimental_context`.
|
|
80
|
+
|
|
81
|
+
**Claude Code behavior**: Sub-agents can be spawned with "access to current context" — they see the full conversation history before the tool call.
|
|
82
|
+
|
|
83
|
+
**Fix**: Modify `buildAITools` to optionally forward `experimental_context` to child agent calls. This requires:
|
|
84
|
+
|
|
85
|
+
1. Wiring `experimental_context` through (see [context research](./experimental-context.md))
|
|
86
|
+
2. The sub-agent tool wrapper accessing it via the AI SDK's second execute arg
|
|
87
|
+
3. A strategy for how to translate parent context into child agent input/system prompt
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Conceptual — context-aware sub-agent wrapper
|
|
91
|
+
execute: async (input, { abortSignal, experimental_context }) => {
|
|
92
|
+
const ctx = experimental_context as ParentContext;
|
|
93
|
+
const r = await runnable.generate(input, {
|
|
94
|
+
signal: abortSignal,
|
|
95
|
+
system: buildChildSystem(ctx), // inject parent context as system prompt
|
|
96
|
+
context: ctx, // or forward context directly
|
|
97
|
+
});
|
|
98
|
+
if (!r.ok) throw new Error(r.error.message);
|
|
99
|
+
return r.output;
|
|
100
|
+
};
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Gap 2: No Result-to-Context Feedback
|
|
104
|
+
|
|
105
|
+
**Problem**: When a sub-agent finishes, its output becomes a tool result string. There is no structured way to merge the child's findings back into the parent's context beyond what the model reads from the tool result.
|
|
106
|
+
|
|
107
|
+
**Claude Code behavior**: Sub-agent results are folded back into the parent's working context. The parent can reference findings from any sub-agent.
|
|
108
|
+
|
|
109
|
+
**Fix**: Use `prepareStep` + `experimental_context` to accumulate sub-agent results:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
prepareStep: async ({ steps, experimental_context }) => {
|
|
113
|
+
const ctx = experimental_context as AgentContext;
|
|
114
|
+
const lastStep = steps.at(-1);
|
|
115
|
+
const subAgentResults = (lastStep?.toolResults ?? [])
|
|
116
|
+
.filter((tr) => isSubAgentTool(tr.toolName))
|
|
117
|
+
.map((tr) => ({ agent: tr.toolName, result: tr.result }));
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
experimental_context: {
|
|
121
|
+
...ctx,
|
|
122
|
+
findings: [...ctx.findings, ...subAgentResults],
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Gap 3: No Dynamic Sub-Agent Spawning
|
|
129
|
+
|
|
130
|
+
**Problem**: Sub-agents must be declared at agent creation time via the `agents` config field. The set of available sub-agents is static.
|
|
131
|
+
|
|
132
|
+
**Claude Code behavior**: Spawns specialized agents on-demand based on task type (Explore agent, Plan agent, Bash agent, etc.).
|
|
133
|
+
|
|
134
|
+
**Fix**: Use `prepareStep` to dynamically modify the tools map:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
prepareStep: async ({ steps, experimental_context }) => {
|
|
138
|
+
const ctx = experimental_context as OrchestratorContext;
|
|
139
|
+
// Spawn a code reviewer sub-agent only after code has been written
|
|
140
|
+
if (ctx.codeWritten && !ctx.reviewerSpawned) {
|
|
141
|
+
return {
|
|
142
|
+
activeTools: [...defaultTools, "code-reviewer"],
|
|
143
|
+
experimental_context: { ...ctx, reviewerSpawned: true },
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {};
|
|
147
|
+
};
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This requires `prepareStep` support (see [prepareStep research](./prepare-step-and-active-tools.md)).
|
|
151
|
+
|
|
152
|
+
For truly dynamic agent creation (not just activation), the parent would need to construct new agent instances at runtime and inject them into the tools map. This is possible but requires a more significant extension to `buildAITools`.
|
|
153
|
+
|
|
154
|
+
### Gap 4: No Shared Memory Between Sibling Agents
|
|
155
|
+
|
|
156
|
+
**Problem**: Sub-agents are isolated. Sibling agents (agents at the same level) cannot read each other's outputs or share intermediate state.
|
|
157
|
+
|
|
158
|
+
**Claude Code behavior**: Agents share a task list, can read each other's outputs, and coordinate via messages.
|
|
159
|
+
|
|
160
|
+
**Fix options**:
|
|
161
|
+
|
|
162
|
+
1. **Via `experimental_context`**: The parent accumulates all sub-agent results in context, and when delegating to the next sub-agent, includes relevant prior results in its input/system prompt.
|
|
163
|
+
|
|
164
|
+
2. **External state store**: Provide a shared key-value store (or task list) as a tool available to all sub-agents. Each sub-agent can read/write to it.
|
|
165
|
+
|
|
166
|
+
3. **Message passing**: Add a `sendMessage` tool that sub-agents can use to post results to a shared channel the parent monitors.
|
|
167
|
+
|
|
168
|
+
Option 1 is the simplest and works with the AI SDK's existing primitives. Options 2 and 3 require custom tool implementations.
|
|
169
|
+
|
|
170
|
+
### Gap 5: No Per-Delegation Step Budget
|
|
171
|
+
|
|
172
|
+
**Problem**: When the parent delegates to a sub-agent, the child runs with its own `maxSteps` (default 20). The parent has no way to constrain how many steps a specific delegation can use.
|
|
173
|
+
|
|
174
|
+
**Claude Code behavior**: Sub-agents have configurable `max_turns` per invocation.
|
|
175
|
+
|
|
176
|
+
**Fix**: The `buildAITools` wrapper could accept a `maxSteps` override per delegation:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// In AgentConfig or via a wrapper
|
|
180
|
+
agents: {
|
|
181
|
+
researcher: { agent: researcherAgent, maxSteps: 10 },
|
|
182
|
+
coder: { agent: coderAgent, maxSteps: 30 },
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
And the tool wrapper would forward it:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
execute: async (input, { abortSignal }) => {
|
|
190
|
+
const r = await runnable.generate(input, {
|
|
191
|
+
signal: abortSignal,
|
|
192
|
+
maxSteps: delegationConfig.maxSteps,
|
|
193
|
+
});
|
|
194
|
+
// ...
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Architecture: Full Sub-Agent Model
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
┌──────────────────────────────────────────────────────┐
|
|
202
|
+
│ Orchestrator Agent │
|
|
203
|
+
│ │
|
|
204
|
+
│ experimental_context: { │
|
|
205
|
+
│ task: "...", │
|
|
206
|
+
│ findings: [], │
|
|
207
|
+
│ phase: "research", │
|
|
208
|
+
│ } │
|
|
209
|
+
│ │
|
|
210
|
+
│ prepareStep: ─► context management │
|
|
211
|
+
│ ─► active tool selection │
|
|
212
|
+
│ ─► model switching │
|
|
213
|
+
│ ─► message compression │
|
|
214
|
+
│ │
|
|
215
|
+
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
216
|
+
│ │Research │ │ Coder │ │Reviewer │ ◄─ sub-agents│
|
|
217
|
+
│ │Agent │ │ Agent │ │Agent │ │
|
|
218
|
+
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
219
|
+
│ │ │ │ │
|
|
220
|
+
│ ▼ ▼ ▼ │
|
|
221
|
+
│ Receives Receives Receives │
|
|
222
|
+
│ parent ctx parent ctx parent ctx │
|
|
223
|
+
│ + findings + findings + code │
|
|
224
|
+
│ │
|
|
225
|
+
│ Results flow back via tool results │
|
|
226
|
+
│ prepareStep accumulates into context │
|
|
227
|
+
└──────────────────────────────────────────────────────┘
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Implementation Priority
|
|
231
|
+
|
|
232
|
+
| Priority | Item | Dependency |
|
|
233
|
+
| -------- | --------------------------------------------------------- | ---------- |
|
|
234
|
+
| **P0** | Wire `prepareStep` through `AgentConfig`/`AgentOverrides` | None |
|
|
235
|
+
| **P0** | Wire `experimental_context` through | None |
|
|
236
|
+
| **P0** | Fix `tool()` execute to forward AI SDK options | None |
|
|
237
|
+
| **P1** | Context-aware sub-agent wrapper in `buildAITools` | P0 |
|
|
238
|
+
| **P1** | Per-delegation `maxSteps` | None |
|
|
239
|
+
| **P2** | Dynamic agent spawning via `prepareStep` | P0 |
|
|
240
|
+
| **P2** | Shared memory/state store tool | P1 |
|
|
241
|
+
|
|
242
|
+
## References
|
|
243
|
+
|
|
244
|
+
- [AI SDK 6 Blog Post](https://vercel.com/blog/ai-sdk-6)
|
|
245
|
+
- [Agents: Loop Control Docs](https://ai-sdk.dev/docs/agents/loop-control)
|
|
246
|
+
- [AI SDK Tool Calling Docs](https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling)
|
|
247
|
+
- [generateText API Reference](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-text)
|
|
248
|
+
- [GitHub Issue #10482 — experimental_context in prepareStep](https://github.com/vercel/ai/issues/10482)
|
|
249
|
+
- [GitHub Issue #6615 — prepareStep message modification](https://github.com/vercel/ai/issues/6615)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
## OPENROUTER_API_KEY not set
|
|
4
|
+
|
|
5
|
+
**Fix:** Set the `OPENROUTER_API_KEY` environment variable in your `.env` file or shell environment.
|
|
6
|
+
|
|
7
|
+
## Agent has `input` schema but no `prompt` function
|
|
8
|
+
|
|
9
|
+
**Fix:** Both `input` and `prompt` are required together. Provide both or omit both for simple mode.
|
|
10
|
+
|
|
11
|
+
## Agent has `prompt` function but no `input` schema
|
|
12
|
+
|
|
13
|
+
**Fix:** Both `input` and `prompt` are required together. Provide both or omit both for simple mode.
|
|
14
|
+
|
|
15
|
+
## Input validation failed
|
|
16
|
+
|
|
17
|
+
**Fix:** Check that all required fields are present and types match the Zod schema.
|
|
18
|
+
|
|
19
|
+
## Unknown model
|
|
20
|
+
|
|
21
|
+
**Fix:** Use `tryModel()` for safe lookup, or add the model to `models.config.json` and run `pnpm --filter=@pkg/agent-sdk generate:models`.
|
|
22
|
+
|
|
23
|
+
## StepResult access
|
|
24
|
+
|
|
25
|
+
**Fix:** Use `.value` on success, not direct property access. Always check `.ok` first.
|
|
26
|
+
|
|
27
|
+
## StreamResult output and messages are promises
|
|
28
|
+
|
|
29
|
+
**Fix:** `StreamResult.output` and `StreamResult.messages` are promises -- `await` them after the stream completes.
|
|
30
|
+
|
|
31
|
+
## `$.all` and `$.race` entries must be factory functions
|
|
32
|
+
|
|
33
|
+
**Fix:** Use `(signal) => fetchA(signal)`, not pre-started promises like `fetchA()`.
|
|
34
|
+
|
|
35
|
+
## Hook errors being swallowed
|
|
36
|
+
|
|
37
|
+
By design. Hook errors are caught and never propagate. Handle errors inside the hook itself if you need them to surface.
|
|
38
|
+
|
|
39
|
+
## Abort signal propagation
|
|
40
|
+
|
|
41
|
+
Signals propagate through the entire execution tree: agents, workflows, subagents, and `$.all`/`$.race` entries.
|
|
42
|
+
|
|
43
|
+
## Tool not being called by agent
|
|
44
|
+
|
|
45
|
+
**Fix:** Improve the tool's `description` and add `.describe()` annotations to `inputSchema` fields.
|
|
46
|
+
|
|
47
|
+
## Result type pattern matching
|
|
48
|
+
|
|
49
|
+
**Fix:** Always check `.ok` before accessing success fields. Use `result.error.code` on failure.
|
|
50
|
+
|
|
51
|
+
## Workflow output validation failed
|
|
52
|
+
|
|
53
|
+
**Fix:** Ensure the handler returns an object matching the `output` Zod schema exactly.
|
|
54
|
+
|
|
55
|
+
## References
|
|
56
|
+
|
|
57
|
+
- [Agent](core/agent.md)
|
|
58
|
+
- [Workflow](core/workflow.md)
|
|
59
|
+
- [Provider Overview](provider/overview.md)
|
|
60
|
+
- [Create an Agent](guides/create-agent.md)
|
package/logo.svg
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 140">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.text { font-family: 'SF Mono', 'Fira Code', 'JetBrains Mono', Consolas, monospace; }
|
|
5
|
+
.neon { fill: #a78bfa; }
|
|
6
|
+
</style>
|
|
7
|
+
</defs>
|
|
8
|
+
|
|
9
|
+
<g transform="translate(24, 28)">
|
|
10
|
+
<text class="text neon" font-size="13" y="0" xml:space="preserve"> █████╗ ██████╗ ███████╗███╗ ██╗████████╗███████╗</text>
|
|
11
|
+
<text class="text neon" font-size="13" y="16" xml:space="preserve">██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝██╔════╝</text>
|
|
12
|
+
<text class="text neon" font-size="13" y="32" xml:space="preserve">███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ███████╗</text>
|
|
13
|
+
<text class="text neon" font-size="13" y="48" xml:space="preserve">██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║</text>
|
|
14
|
+
<text class="text neon" font-size="13" y="64" xml:space="preserve">██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████║</text>
|
|
15
|
+
<text class="text neon" font-size="13" y="80" xml:space="preserve">╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝</text>
|
|
16
|
+
</g>
|
|
17
|
+
</svg>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openai": [
|
|
3
|
+
{ "id": "openai/gpt-5.2-codex", "category": "coding" },
|
|
4
|
+
{ "id": "openai/gpt-5.2", "category": "chat" },
|
|
5
|
+
{ "id": "openai/gpt-5.1", "category": "chat" },
|
|
6
|
+
{ "id": "openai/gpt-5", "category": "chat" },
|
|
7
|
+
{ "id": "openai/gpt-5-mini", "category": "chat" },
|
|
8
|
+
{ "id": "openai/gpt-5-nano", "category": "chat" },
|
|
9
|
+
{ "id": "openai/gpt-4.1", "category": "chat" },
|
|
10
|
+
{ "id": "openai/gpt-4.1-mini", "category": "chat" },
|
|
11
|
+
{ "id": "openai/gpt-4.1-nano", "category": "chat" },
|
|
12
|
+
{ "id": "openai/gpt-4o", "category": "chat" },
|
|
13
|
+
{ "id": "openai/gpt-4o-mini", "category": "chat" },
|
|
14
|
+
{ "id": "openai/o3", "category": "reasoning" },
|
|
15
|
+
{ "id": "openai/o3-mini", "category": "reasoning" },
|
|
16
|
+
{ "id": "openai/o4-mini", "category": "reasoning" }
|
|
17
|
+
]
|
|
18
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@funkai/agents",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Lightweight workflow and agent orchestration framework",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"agents",
|
|
8
|
+
"ai",
|
|
9
|
+
"ai-sdk",
|
|
10
|
+
"openrouter",
|
|
11
|
+
"orchestration",
|
|
12
|
+
"typescript",
|
|
13
|
+
"workflow"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/joggrdocs/funkai/tree/main/packages/agents#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/joggrdocs/funkai/issues"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/joggrdocs/funkai.git",
|
|
23
|
+
"directory": "packages/agents"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.mts",
|
|
29
|
+
"import": "./dist/index.mjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@openrouter/ai-sdk-provider": "^2.3.0",
|
|
34
|
+
"ai": "^6.0.116",
|
|
35
|
+
"es-toolkit": "^1.45.1",
|
|
36
|
+
"ts-pattern": "^5.9.0",
|
|
37
|
+
"type-fest": "^5.4.4",
|
|
38
|
+
"zod": "^4.3.6"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@ai-sdk/devtools": "^0.0.15",
|
|
42
|
+
"@openrouter/sdk": "^0.9.11",
|
|
43
|
+
"@types/node": "^25.5.0",
|
|
44
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
45
|
+
"tsdown": "^0.21.2",
|
|
46
|
+
"tsx": "^4.21.0",
|
|
47
|
+
"typescript": "^5.9.3",
|
|
48
|
+
"vitest": "^4.1.0"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=24.0.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"generate:models": "tsx scripts/generate-models.ts",
|
|
55
|
+
"build": "tsdown",
|
|
56
|
+
"typecheck": "tsc --noEmit",
|
|
57
|
+
"test": "vitest run --typecheck",
|
|
58
|
+
"test:coverage": "vitest run --coverage"
|
|
59
|
+
}
|
|
60
|
+
}
|