Skip to content
This repository was archived by the owner on Mar 25, 2026. It is now read-only.

Commit aa80901

Browse files
Docs updates (#343)
* Sandbox and runtime updates * Update the "why" for features * Tweaks * Tweaks * Tweaks * Tweaks * Updates * Clean up * Fixes * Add Community section and move Cookbook to top level - Create Community section with Snow Leopard example - Add `ExternalCard` component for external link cards - Move Cookbook from `Learn/` to top-level nav - Update internal links to Cookbook pages - Remove empty Learn section * Tweaks * Fixes * Update examples * Fix Bun links * Tweaks * Reorganize and add more info * Update AI commands * Tweaks
1 parent e21a167 commit aa80901

50 files changed

Lines changed: 2663 additions & 251 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

components/external-card.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { ExternalLink } from 'lucide-react';
2+
import type { ReactNode, CSSProperties } from 'react';
3+
4+
interface ExternalCardProps {
5+
href: string;
6+
title: string;
7+
icon?: ReactNode;
8+
children: ReactNode;
9+
style?: CSSProperties;
10+
className?: string;
11+
}
12+
13+
export function ExternalCard({ href, title, icon, children, style, className }: ExternalCardProps) {
14+
return (
15+
<a
16+
href={href}
17+
target="_blank"
18+
rel="noopener noreferrer"
19+
className={`not-prose block rounded-lg border p-4 shadow-md transition-colors ${className || 'bg-fd-card text-fd-card-foreground hover:bg-fd-accent/80'}`}
20+
style={style}
21+
>
22+
<div className="flex items-start gap-3">
23+
{icon && <div>{icon}</div>}
24+
<div className="flex-1">
25+
<div className="flex items-center gap-2 font-medium">
26+
{title}
27+
<ExternalLink className="h-3.5 w-3.5 opacity-60" />
28+
</div>
29+
<span className="mt-1 block text-sm opacity-80">{children}</span>
30+
</div>
31+
</div>
32+
</a>
33+
);
34+
}

content/Agents/creating-agents.mdx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,15 @@ All implement [StandardSchema](https://github.com/standard-schema/standard-schem
197197

198198
### Type Inference
199199

200-
TypeScript automatically infers types from your schemas:
200+
TypeScript automatically infers types from your schemas. Don't add explicit type annotations to handler parameters:
201+
202+
```typescript
203+
// Good: types inferred from schema
204+
handler: async (ctx, input) => { ... }
205+
206+
// Bad: explicit types can cause issues
207+
handler: async (ctx: AgentContext, input: MyInput) => { ... }
208+
```
201209

202210
```typescript
203211
const agent = createAgent('Search', {
@@ -364,6 +372,10 @@ handler: async (ctx, input) => {
364372

365373
## Next Steps
366374

375+
<Callout type="tip" title="AI-Assisted Development">
376+
The [OpenCode plugin](/Reference/CLI/opencode-plugin) provides AI-assisted development for full-stack Agentuity projects, including agents, routes, frontend, and deployment.
377+
</Callout>
378+
367379
- [Using the AI SDK](/Agents/ai-sdk-integration): Add LLM capabilities with generateText and streamText
368380
- [Managing State](/Agents/state-management): Persist data across requests with thread and session state
369381
- [Calling Other Agents](/Agents/calling-other-agents): Build multi-agent workflows

content/Agents/evaluations.mdx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ description: Automatically test and validate agent outputs for quality and compl
55

66
Evaluations (evals) are automated tests that run after your agent completes. They validate output quality, check compliance, and monitor performance without blocking agent responses.
77

8+
## Why Evals?
9+
10+
Most evaluation tools test the LLM: did the model respond appropriately? That's fine for chatbots, but agents aren't single LLM calls. They're entire runs with multiple model calls, tool executions, and orchestration working together.
11+
12+
Agent failures can happen anywhere in the run—a tool call that returned bad data, a state bug that corrupted context, and more. Testing just the LLM response misses most of this.
13+
14+
Agentuity evals test the whole run—every tool call, state change, and orchestration step. They run on every session in production, so you catch issues with real traffic.
15+
16+
**The result:**
17+
18+
- **Full-run evaluation**: Test the entire agent execution, not just LLM responses
19+
- **Production monitoring**: Once configured, evals run automatically on every session
20+
- **Async by default**: Evals don't block responses, so users aren't waiting
21+
- **Preset library**: Common checks (PII, safety, hallucination) available out of the box
22+
823
Evals come in two types: **binary** (pass/fail) for yes/no criteria, and **score** (0-1) for quality gradients.
924

1025
<Callout type="info" title="Where Scores Appear">
@@ -426,6 +441,37 @@ export const politenessCheck = agent.createEval(politeness({
426441

427442
All preset evals use a default model optimized for cost and speed. Override `model` when you need specific capabilities.
428443

444+
### Lifecycle Hooks
445+
446+
Preset evals support `onStart` and `onComplete` hooks for custom logic around eval execution:
447+
448+
```typescript
449+
import { politeness } from '@agentuity/evals';
450+
451+
export const politenessCheck = agent.createEval(politeness({
452+
onStart: async (ctx, input, output) => {
453+
ctx.logger.info('Starting politeness eval', {
454+
inputLength: input.request?.length,
455+
});
456+
},
457+
onComplete: async (ctx, result) => {
458+
// Track results in external monitoring
459+
if (!result.passed) {
460+
ctx.logger.warn('Politeness check failed', {
461+
score: result.score,
462+
reason: result.reason,
463+
});
464+
}
465+
},
466+
}));
467+
```
468+
469+
**Use cases for lifecycle hooks:**
470+
- Log eval execution for debugging
471+
- Send results to external monitoring systems
472+
- Track eval performance metrics
473+
- Trigger alerts on failures
474+
429475
### Schema Middleware
430476

431477
Preset evals expect a standard input/output format:

content/Agents/schema-libraries.mdx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,29 @@ type User = s.infer<typeof User>;
103103
// { name: string; age: number; role: 'admin' | 'user' }
104104
```
105105

106+
### JSON Schema Generation
107+
108+
Convert schemas to JSON Schema for use with LLM structured output:
109+
110+
```typescript
111+
import { s } from '@agentuity/schema';
112+
113+
const ResponseSchema = s.object({
114+
answer: s.string(),
115+
confidence: s.number(),
116+
});
117+
118+
// Generate JSON Schema
119+
const jsonSchema = s.toJSONSchema(ResponseSchema);
120+
121+
// Generate strict JSON Schema for LLM structured output
122+
const strictSchema = s.toJSONSchema(ResponseSchema, { strict: true });
123+
```
124+
125+
<Callout type="tip" title="Strict Mode for LLMs">
126+
Use `{ strict: true }` when generating schemas for LLM structured output (e.g., OpenAI's `response_format`). Strict mode ensures the schema is compatible with model constraints and produces more reliable outputs.
127+
</Callout>
128+
106129
<Callout type="info" title="When to Use">
107130
Use `@agentuity/schema` for simple validation needs. For advanced features like email validation, string length constraints, or complex transformations, consider Zod or Valibot.
108131
</Callout>

content/Agents/standalone-execution.mdx

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: Execute agents programmatically for cron jobs, bots, CLI tools, and
66
Sometimes your agent logic needs to run without an incoming HTTP request. `createAgentContext()` gives standalone code the same infrastructure that HTTP handlers get automatically: tracing, sessions, and storage access.
77

88
<Callout type="warning" title="Agentuity Runtime Only">
9-
`createAgentContext()` requires Agentuity's runtime initialization and only works within the Agentuity runtime (Discord bots, CLI tools, queue workers deployed alongside your agents). It will throw an error if called from external frameworks like Next.js or Express. To access storage from external backends, see [SDK Utilities for External Apps](/Learn/Cookbook/Patterns/server-utilities).
9+
`createAgentContext()` requires Agentuity's runtime initialization and only works within the Agentuity runtime (Discord bots, CLI tools, queue workers deployed alongside your agents). It will throw an error if called from external frameworks like Next.js or Express. To access storage from external backends, see [SDK Utilities for External Apps](/Cookbook/Patterns/server-utilities).
1010
</Callout>
1111

1212
## Basic Usage
@@ -16,10 +16,20 @@ import { createAgentContext } from '@agentuity/runtime';
1616
import chatAgent from '@agent/chat';
1717

1818
const ctx = createAgentContext();
19-
const result = await ctx.invoke(() => chatAgent.run({ message: 'Hello' }));
19+
const result = await ctx.run(chatAgent, { message: 'Hello' });
2020
```
2121

22-
The `invoke()` method executes your agent with full infrastructure support: tracing, session management, and access to all storage services.
22+
The `run()` method executes your agent with full infrastructure support: tracing, session management, and access to all storage services.
23+
24+
For agents that don't require input:
25+
26+
```typescript
27+
const result = await ctx.run(statusAgent);
28+
```
29+
30+
<Callout type="info" title="Legacy invoke() Method">
31+
The older `ctx.invoke(() => agent.run(input))` pattern still works but `ctx.run(agent, input)` is preferred for its cleaner syntax.
32+
</Callout>
2333

2434
## Options
2535

@@ -45,10 +55,7 @@ await createApp();
4555
// Run cleanup every hour
4656
cron.schedule('0 * * * *', async () => {
4757
const ctx = createAgentContext({ trigger: 'cron' });
48-
49-
await ctx.invoke(async () => {
50-
await cleanupAgent.run({ task: 'expired-sessions' });
51-
});
58+
await ctx.run(cleanupAgent, { task: 'expired-sessions' });
5259
});
5360
```
5461

@@ -58,35 +65,33 @@ For most scheduled tasks, use the [`cron()` middleware](/Routes/cron) instead. I
5865

5966
## Multiple Agents in Sequence
6067

61-
Run multiple agents within a single `invoke()` call to share the same session and tracing context:
68+
Run multiple agents in sequence with the same context:
6269

6370
```typescript
6471
const ctx = createAgentContext();
6572

66-
const result = await ctx.invoke(async () => {
67-
// First agent analyzes the input
68-
const analysis = await analyzeAgent.run({ text: userInput });
69-
70-
// Second agent generates response based on analysis
71-
const response = await respondAgent.run({
72-
analysis: analysis.summary,
73-
sentiment: analysis.sentiment,
74-
});
73+
// First agent analyzes the input
74+
const analysis = await ctx.run(analyzeAgent, { text: userInput });
7575

76-
return response;
76+
// Second agent generates response based on analysis
77+
const response = await ctx.run(respondAgent, {
78+
analysis: analysis.summary,
79+
sentiment: analysis.sentiment,
7780
});
7881
```
7982

83+
Each `ctx.run()` call gets its own session and tracing span, while sharing the logger, tracer, and app state.
84+
8085
## Reusing Contexts
8186

8287
Create a context once and reuse it for multiple invocations:
8388

8489
```typescript
8590
const ctx = createAgentContext({ trigger: 'websocket' });
8691

87-
// Each invoke() gets its own session and tracing span
92+
// Each run gets its own session and tracing span
8893
websocket.on('message', async (data) => {
89-
const result = await ctx.invoke(() => messageAgent.run(data));
94+
const result = await ctx.run(messageAgent, data);
9095
websocket.send(result);
9196
});
9297
```
@@ -104,6 +109,31 @@ Standalone contexts provide the same infrastructure as HTTP request handlers:
104109
- **Session events**: Start/complete events for observability
105110
</Callout>
106111

112+
## Detecting Context
113+
114+
Use `inAgentContext()` to check if code is running inside an agent handler with ambient context available:
115+
116+
```typescript
117+
import { inAgentContext, createAgentContext } from '@agentuity/runtime';
118+
import myAgent from '@agent/my-agent';
119+
120+
async function processRequest(data: unknown) {
121+
if (inAgentContext()) {
122+
// Inside an agent handler, ambient context is available
123+
// so agent.run() works directly without explicit context
124+
return myAgent.run(data);
125+
}
126+
127+
// Outside agent handler, create context first
128+
const ctx = createAgentContext();
129+
return ctx.run(myAgent, data);
130+
}
131+
```
132+
133+
This is useful for writing utility functions that work both inside agent handlers and in standalone scripts.
134+
135+
To check if the Agentuity runtime is initialized (but not necessarily inside a handler), use `isInsideAgentRuntime()` instead.
136+
107137
## Next Steps
108138

109139
- [Calling Other Agents](/Agents/calling-other-agents): Agent-to-agent communication patterns

content/Agents/streaming-responses.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ Streaming requires both: `schema.stream: true` in your agent (so the handler ret
5050

5151
Enable streaming by setting `stream: true` in your schema and returning a `textStream`:
5252

53+
<Callout type="info" title="AI SDK Integration">
54+
The `textStream` from AI SDK's `streamText()` works directly with Agentuity's streaming middleware. Return it from your handler without additional processing.
55+
</Callout>
56+
5357
```typescript
5458
import { createAgent } from '@agentuity/runtime';
5559
import { streamText } from 'ai';

content/Agents/workbench.mdx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ description: Use the built-in development UI to test agents, validate schemas, a
55

66
Workbench is a built-in UI for testing your agents during development. It automatically discovers your agents, displays their input/output schemas, and lets you execute them with real inputs.
77

8+
## Why Workbench?
9+
10+
Testing agents isn't like testing traditional APIs. You need to validate input schemas, see how responses format, test multi-turn conversations, and understand execution timing. Using `curl` or Postman means manually constructing JSON payloads and parsing responses.
11+
12+
Workbench understands your agents. It reads your schemas, generates test forms, maintains conversation threads, and shows execution metrics. When something goes wrong, you see exactly what the agent received and returned.
13+
14+
**Key capabilities:**
15+
16+
- **Schema-aware testing**: Input forms generated from your actual schemas
17+
- **Thread persistence**: Test multi-turn conversations without manual state tracking
18+
- **Execution metrics**: See token usage and response times for every request
19+
- **Quick iteration**: Test prompts display in the UI for one-click execution
20+
821
## Enabling Workbench
922

1023
Add a `workbench` section to your `agentuity.config.ts`:

content/Community/meta.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"title": "Community",
3+
"pages": ["overview"]
4+
}

content/Community/overview.mdx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: Community Examples
3+
description: Real-world integrations and tutorials built with Agentuity
4+
---
5+
6+
import { Cards } from 'fumadocs-ui/components/card';
7+
import { ExternalCard } from '@/components/external-card';
8+
9+
## From the Community
10+
11+
<Cards>
12+
<ExternalCard
13+
href="https://docs.snowleopard.ai/quickstarts/agentuity"
14+
title="Snow Leopard: Data Retrieval Agent"
15+
icon={
16+
<picture>
17+
<img src="/images/snow-leopard-icon.png" alt="Snow Leopard" width={28} height={28} />
18+
</picture>
19+
}
20+
className="bg-white text-[#2D2D2D] border-gray-200 hover:bg-gray-50 hover:border-[#2D2D2D] dark:bg-[#2D2D2D] dark:text-white dark:border-[#484848] dark:hover:bg-[#484848] dark:hover:border-[#9DEDEB]"
21+
>
22+
Answer questions about your SQL data. No MCP, ETL, or RAG required.
23+
</ExternalCard>
24+
</Cards>
25+
26+
## Share Your Work
27+
28+
Built something with Agentuity? We'd love to feature it.
29+
30+
- [Open a PR](https://github.com/agentuity/docs/pulls) to add your example
31+
- Or, [reach out on Discord](https://discord.gg/agentuity) to share what you've built

content/Frontend/react-hooks.mdx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,44 @@ function SearchResults({ query }: { query: string }) {
280280
}
281281
```
282282

283+
### Dynamic Path Parameters
284+
285+
For routes with path parameters (e.g., `/api/items/:itemId`), pass params at invocation time:
286+
287+
```tsx
288+
import { useAPI } from '@agentuity/react';
289+
290+
function ItemActions({ itemId }: { itemId: string }) {
291+
const { invoke: deleteItem, isLoading } = useAPI('DELETE /api/items/:itemId');
292+
const { invoke: updateItem } = useAPI('PUT /api/items/:itemId');
293+
294+
const handleDelete = async () => {
295+
await deleteItem(undefined, { params: { itemId } });
296+
};
297+
298+
const handleUpdate = async (name: string) => {
299+
await updateItem({ name }, { params: { itemId } });
300+
};
301+
302+
return (
303+
<div>
304+
<button onClick={() => handleUpdate('New Name')} disabled={isLoading}>
305+
Rename
306+
</button>
307+
<button onClick={handleDelete} disabled={isLoading}>
308+
Delete
309+
</button>
310+
</div>
311+
);
312+
}
313+
```
314+
315+
The second argument to `invoke()` accepts `params` for path parameter values (e.g., `{ params: { itemId: '123' } }`).
316+
317+
<Callout type="info" title="Query and Headers">
318+
To set `query` or `headers`, pass them when calling `useAPI()`, not to `invoke()`. For dynamic query parameters, see the [example above](#request-options).
319+
</Callout>
320+
283321
## Auth State with useAuth
284322

285323
Access authentication state for protected components or custom auth logic:

0 commit comments

Comments
 (0)