@nextsparkjs/plugin-langchain 0.1.0-beta.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.
- package/.env.example +41 -0
- package/api/observability/metrics/route.ts +110 -0
- package/api/observability/traces/[traceId]/route.ts +398 -0
- package/api/observability/traces/route.ts +205 -0
- package/api/sessions/route.ts +332 -0
- package/components/observability/CollapsibleJson.tsx +71 -0
- package/components/observability/CompactTimeline.tsx +75 -0
- package/components/observability/ConversationFlow.tsx +271 -0
- package/components/observability/DisabledMessage.tsx +21 -0
- package/components/observability/FiltersPanel.tsx +82 -0
- package/components/observability/ObservabilityDashboard.tsx +230 -0
- package/components/observability/SpansList.tsx +210 -0
- package/components/observability/TraceDetail.tsx +335 -0
- package/components/observability/TraceStatusBadge.tsx +39 -0
- package/components/observability/TracesTable.tsx +97 -0
- package/components/observability/index.ts +7 -0
- package/docs/01-getting-started/01-overview.md +196 -0
- package/docs/01-getting-started/02-installation.md +368 -0
- package/docs/01-getting-started/03-configuration.md +794 -0
- package/docs/02-core-concepts/01-architecture.md +566 -0
- package/docs/02-core-concepts/02-agents.md +597 -0
- package/docs/02-core-concepts/03-tools.md +689 -0
- package/docs/03-orchestration/01-graph-orchestrator.md +809 -0
- package/docs/03-orchestration/02-legacy-react.md +650 -0
- package/docs/04-advanced/01-observability.md +645 -0
- package/docs/04-advanced/02-token-tracking.md +469 -0
- package/docs/04-advanced/03-streaming.md +476 -0
- package/docs/04-advanced/04-guardrails.md +597 -0
- package/docs/05-reference/01-api-reference.md +1403 -0
- package/docs/05-reference/02-customization.md +646 -0
- package/docs/05-reference/03-examples.md +881 -0
- package/docs/index.md +85 -0
- package/hooks/observability/useMetrics.ts +31 -0
- package/hooks/observability/useTraceDetail.ts +48 -0
- package/hooks/observability/useTraces.ts +59 -0
- package/lib/agent-factory.ts +354 -0
- package/lib/agent-helpers.ts +201 -0
- package/lib/db-memory-store.ts +417 -0
- package/lib/graph/index.ts +58 -0
- package/lib/graph/nodes/combiner.ts +399 -0
- package/lib/graph/nodes/router.ts +440 -0
- package/lib/graph/orchestrator-graph.ts +386 -0
- package/lib/graph/prompts/combiner.md +131 -0
- package/lib/graph/prompts/router.md +193 -0
- package/lib/graph/types.ts +365 -0
- package/lib/guardrails.ts +230 -0
- package/lib/index.ts +44 -0
- package/lib/logger.ts +70 -0
- package/lib/memory-store.ts +168 -0
- package/lib/message-serializer.ts +110 -0
- package/lib/prompt-renderer.ts +94 -0
- package/lib/providers.ts +226 -0
- package/lib/streaming.ts +232 -0
- package/lib/token-tracker.ts +298 -0
- package/lib/tools-builder.ts +192 -0
- package/lib/tracer-callbacks.ts +342 -0
- package/lib/tracer.ts +350 -0
- package/migrations/001_langchain_memory.sql +83 -0
- package/migrations/002_token_usage.sql +127 -0
- package/migrations/003_observability.sql +257 -0
- package/package.json +28 -0
- package/plugin.config.ts +170 -0
- package/presets/lib/langchain.config.ts.preset +142 -0
- package/presets/templates/sector7/ai-observability/[traceId]/page.tsx +91 -0
- package/presets/templates/sector7/ai-observability/page.tsx +54 -0
- package/types/langchain.types.ts +274 -0
- package/types/observability.types.ts +270 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
# Agents
|
|
2
|
+
|
|
3
|
+
Agents are the core of the LangChain plugin. This guide covers how to create, configure, and customize AI agents with system prompts.
|
|
4
|
+
|
|
5
|
+
## What is an Agent?
|
|
6
|
+
|
|
7
|
+
An agent combines three elements:
|
|
8
|
+
|
|
9
|
+
1. **LLM (Brain)**: The language model that reasons and makes decisions
|
|
10
|
+
2. **Tools (Hands)**: Functions the agent can call to interact with data
|
|
11
|
+
3. **System Prompt (Personality)**: Instructions that define agent behavior
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌─────────────────────────────────────────┐
|
|
15
|
+
│ AGENT │
|
|
16
|
+
│ │
|
|
17
|
+
│ ┌──────────────────────────────────┐ │
|
|
18
|
+
│ │ System Prompt │ │
|
|
19
|
+
│ │ "You are a task assistant..." │ │
|
|
20
|
+
│ └──────────────────────────────────┘ │
|
|
21
|
+
│ │ │
|
|
22
|
+
│ ▼ │
|
|
23
|
+
│ ┌──────────────────────────────────┐ │
|
|
24
|
+
│ │ LLM │ │
|
|
25
|
+
│ │ (Reasoning) │ │
|
|
26
|
+
│ └──────────────────────────────────┘ │
|
|
27
|
+
│ │ │
|
|
28
|
+
│ ┌─────────┴─────────┐ │
|
|
29
|
+
│ ▼ ▼ │
|
|
30
|
+
│ ┌─────────────┐ ┌─────────────┐ │
|
|
31
|
+
│ │ Tool 1 │ │ Tool 2 │ │
|
|
32
|
+
│ │ list_tasks │ │ create_task │ │
|
|
33
|
+
│ └─────────────┘ └─────────────┘ │
|
|
34
|
+
│ │
|
|
35
|
+
└─────────────────────────────────────────┘
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Creating an Agent
|
|
39
|
+
|
|
40
|
+
### Step 1: Define in Configuration
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// langchain.config.ts
|
|
44
|
+
export const AGENTS = {
|
|
45
|
+
'my-assistant': {
|
|
46
|
+
provider: 'ollama',
|
|
47
|
+
temperature: 0.3,
|
|
48
|
+
description: 'Helps users manage their items',
|
|
49
|
+
systemPrompt: 'my-assistant',
|
|
50
|
+
createTools: (context) => createMyTools(context),
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Step 2: Create System Prompt
|
|
56
|
+
|
|
57
|
+
```markdown
|
|
58
|
+
<!-- agents/my-assistant.md -->
|
|
59
|
+
|
|
60
|
+
You are an AI assistant that helps users manage their items.
|
|
61
|
+
|
|
62
|
+
## Your Capabilities
|
|
63
|
+
- List, search, and view items
|
|
64
|
+
- Create new items
|
|
65
|
+
- Update existing items
|
|
66
|
+
- Delete items (with confirmation)
|
|
67
|
+
|
|
68
|
+
## Rules
|
|
69
|
+
1. Always use tools to access data - never fabricate information
|
|
70
|
+
2. Confirm before destructive actions
|
|
71
|
+
3. Match the user's language (Spanish/English)
|
|
72
|
+
|
|
73
|
+
## Response Format
|
|
74
|
+
- Be concise but helpful
|
|
75
|
+
- Use bullet points for lists
|
|
76
|
+
- Provide links after creating/updating: [Item Name](/items/{id})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Step 3: Create Tools
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// tools/my-entity.ts
|
|
83
|
+
export function createMyTools(context: AgentContext): ToolDefinition[] {
|
|
84
|
+
return [
|
|
85
|
+
{
|
|
86
|
+
name: 'list_items',
|
|
87
|
+
description: 'List all items',
|
|
88
|
+
schema: z.object({}),
|
|
89
|
+
func: async () => {
|
|
90
|
+
const items = await MyService.list(context.userId)
|
|
91
|
+
return JSON.stringify(items)
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Step 4: Use the Agent
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { createAgent } from '@/contents/plugins/langchain/lib/agent-factory'
|
|
102
|
+
import { getAgentTools, getAgentModelConfig } from './langchain.config'
|
|
103
|
+
import { loadSystemPrompt } from './agents'
|
|
104
|
+
|
|
105
|
+
const agent = await createAgent({
|
|
106
|
+
sessionId: `user-${userId}-${Date.now()}`,
|
|
107
|
+
systemPrompt: loadSystemPrompt('my-assistant'),
|
|
108
|
+
tools: getAgentTools('my-assistant', { userId, teamId }),
|
|
109
|
+
modelConfig: getAgentModelConfig('my-assistant'),
|
|
110
|
+
context: { userId, teamId },
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const response = await agent.chat('Show me my items')
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## System Prompts
|
|
117
|
+
|
|
118
|
+
System prompts define agent behavior. They are loaded from markdown files in the `agents/` folder.
|
|
119
|
+
|
|
120
|
+
### Prompt Loader
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// agents/index.ts
|
|
124
|
+
import fs from 'fs'
|
|
125
|
+
import path from 'path'
|
|
126
|
+
|
|
127
|
+
const AGENTS_DIR = path.join(__dirname)
|
|
128
|
+
|
|
129
|
+
export type AgentName =
|
|
130
|
+
| 'orchestrator'
|
|
131
|
+
| 'task-assistant'
|
|
132
|
+
| 'customer-assistant'
|
|
133
|
+
| 'page-assistant'
|
|
134
|
+
| 'single-agent'
|
|
135
|
+
|
|
136
|
+
const promptCache = new Map<string, string>()
|
|
137
|
+
|
|
138
|
+
export function loadSystemPrompt(agentName: AgentName): string {
|
|
139
|
+
if (promptCache.has(agentName)) {
|
|
140
|
+
return promptCache.get(agentName)!
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const filePath = path.join(AGENTS_DIR, `${agentName}.md`)
|
|
144
|
+
const content = fs.readFileSync(filePath, 'utf-8')
|
|
145
|
+
promptCache.set(agentName, content)
|
|
146
|
+
|
|
147
|
+
return content
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function agentExists(agentName: string): boolean {
|
|
151
|
+
const filePath = path.join(AGENTS_DIR, `${agentName}.md`)
|
|
152
|
+
return fs.existsSync(filePath)
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Prompt Structure
|
|
157
|
+
|
|
158
|
+
A well-structured system prompt includes:
|
|
159
|
+
|
|
160
|
+
```markdown
|
|
161
|
+
# Agent Name
|
|
162
|
+
|
|
163
|
+
Brief description of what the agent does.
|
|
164
|
+
|
|
165
|
+
## Critical Rules
|
|
166
|
+
|
|
167
|
+
**Rules that MUST be followed:**
|
|
168
|
+
- Rule 1: Always use tools
|
|
169
|
+
- Rule 2: Never fabricate data
|
|
170
|
+
- Rule 3: ...
|
|
171
|
+
|
|
172
|
+
## Capabilities
|
|
173
|
+
|
|
174
|
+
What this agent can do:
|
|
175
|
+
- Capability 1
|
|
176
|
+
- Capability 2
|
|
177
|
+
- ...
|
|
178
|
+
|
|
179
|
+
## Available Tools
|
|
180
|
+
|
|
181
|
+
| Tool | When to Use |
|
|
182
|
+
|------|-------------|
|
|
183
|
+
| `tool_name` | Description of when to use |
|
|
184
|
+
| `other_tool` | Description... |
|
|
185
|
+
|
|
186
|
+
## Workflow
|
|
187
|
+
|
|
188
|
+
How the agent should approach tasks:
|
|
189
|
+
|
|
190
|
+
1. Step 1
|
|
191
|
+
2. Step 2
|
|
192
|
+
3. ...
|
|
193
|
+
|
|
194
|
+
## Response Format
|
|
195
|
+
|
|
196
|
+
Guidelines for formatting responses:
|
|
197
|
+
- Use bullet points
|
|
198
|
+
- Match user language
|
|
199
|
+
- Provide links: [Name](/path/{id})
|
|
200
|
+
|
|
201
|
+
## Examples
|
|
202
|
+
|
|
203
|
+
Example interactions (optional):
|
|
204
|
+
|
|
205
|
+
User: "Show me my items"
|
|
206
|
+
Agent: *calls list_items* → Formats and displays results
|
|
207
|
+
|
|
208
|
+
## What NOT to Do
|
|
209
|
+
|
|
210
|
+
- Don't fabricate data
|
|
211
|
+
- Don't skip tool calls
|
|
212
|
+
- Don't ...
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Dynamic Prompts with Handlebars
|
|
216
|
+
|
|
217
|
+
System prompts support Handlebars templates for injecting runtime data. This allows prompts to be personalized based on user context, business data, or other dynamic information.
|
|
218
|
+
|
|
219
|
+
### Enabling Dynamic Prompts
|
|
220
|
+
|
|
221
|
+
1. **Define `enrichContext` in your agent configuration:**
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// langchain.config.ts
|
|
225
|
+
'sales-assistant': {
|
|
226
|
+
provider: 'openai',
|
|
227
|
+
systemPrompt: 'sales-assistant', // Template file
|
|
228
|
+
|
|
229
|
+
enrichContext: async ({ userId, teamId }) => {
|
|
230
|
+
const user = await UsersService.getById(userId)
|
|
231
|
+
const team = await TeamsService.getById(teamId)
|
|
232
|
+
const quotas = await QuotasService.getForUser(userId)
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
userId,
|
|
236
|
+
teamId,
|
|
237
|
+
salesperson: { name: user.name, email: user.email },
|
|
238
|
+
company: { name: team.name, timezone: team.timezone },
|
|
239
|
+
quotas,
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
2. **Use Handlebars syntax in your prompt:**
|
|
246
|
+
|
|
247
|
+
```markdown
|
|
248
|
+
<!-- agents/sales-assistant.md -->
|
|
249
|
+
|
|
250
|
+
# Sales Assistant
|
|
251
|
+
|
|
252
|
+
You are helping **{{salesperson.name}}** from **{{company.name}}**.
|
|
253
|
+
Current timezone: {{company.timezone}}
|
|
254
|
+
|
|
255
|
+
{{#if quotas}}
|
|
256
|
+
## Your quotas this month:
|
|
257
|
+
{{#each quotas}}
|
|
258
|
+
- {{this.name}}: {{this.current}} / {{this.target}}
|
|
259
|
+
{{/each}}
|
|
260
|
+
{{/if}}
|
|
261
|
+
|
|
262
|
+
## Your Capabilities
|
|
263
|
+
...
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Handlebars Syntax
|
|
267
|
+
|
|
268
|
+
| Syntax | Description | Example |
|
|
269
|
+
|--------|-------------|---------|
|
|
270
|
+
| `{{variable}}` | Simple variable | `{{user.name}}` |
|
|
271
|
+
| `{{nested.key}}` | Nested property | `{{company.timezone}}` |
|
|
272
|
+
| `{{#if condition}}...{{/if}}` | Conditional | `{{#if isAdmin}}Admin mode{{/if}}` |
|
|
273
|
+
| `{{#unless condition}}...{{/unless}}` | Inverse conditional | `{{#unless hasData}}No data{{/unless}}` |
|
|
274
|
+
| `{{#each items}}...{{/each}}` | Loop over array | `{{#each tasks}}{{this.title}}{{/each}}` |
|
|
275
|
+
| `{{#with object}}...{{/with}}` | Change context | `{{#with user}}{{name}}{{/with}}` |
|
|
276
|
+
|
|
277
|
+
### Prompt Renderer
|
|
278
|
+
|
|
279
|
+
The plugin provides a `renderPrompt` utility:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { renderPrompt } from '@/contents/plugins/langchain/lib/prompt-renderer'
|
|
283
|
+
|
|
284
|
+
const template = 'Hello {{user.name}} from {{company.name}}!'
|
|
285
|
+
const context = {
|
|
286
|
+
userId: '123',
|
|
287
|
+
teamId: '456',
|
|
288
|
+
user: { name: 'John' },
|
|
289
|
+
company: { name: 'Acme Corp' },
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const rendered = renderPrompt(template, context)
|
|
293
|
+
// "Hello John from Acme Corp!"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Best Practices
|
|
297
|
+
|
|
298
|
+
1. **Keep templates readable** - Don't overuse conditionals
|
|
299
|
+
2. **Provide defaults** - Handle missing data gracefully
|
|
300
|
+
3. **Document required context** - Note what data the template expects
|
|
301
|
+
4. **Test with sample data** - Ensure templates render correctly
|
|
302
|
+
|
|
303
|
+
## Real-World Examples
|
|
304
|
+
|
|
305
|
+
### Task Assistant
|
|
306
|
+
|
|
307
|
+
```markdown
|
|
308
|
+
<!-- agents/task-assistant.md -->
|
|
309
|
+
|
|
310
|
+
You are a task management AI assistant for the Boilerplate application.
|
|
311
|
+
|
|
312
|
+
## CRITICAL RULE - MUST FOLLOW
|
|
313
|
+
|
|
314
|
+
**YOU MUST ALWAYS USE TOOLS TO GET DATA. NEVER FABRICATE OR IMAGINE TASK INFORMATION.**
|
|
315
|
+
|
|
316
|
+
Before responding with ANY task information, you MUST:
|
|
317
|
+
1. Call the appropriate tool (list_tasks, search_tasks, get_task_details)
|
|
318
|
+
2. Wait for the tool result
|
|
319
|
+
3. ONLY THEN respond based on the REAL data from the tool
|
|
320
|
+
|
|
321
|
+
If a tool returns an error or empty results, tell the user honestly - NEVER make up fake tasks.
|
|
322
|
+
|
|
323
|
+
## Your Capabilities
|
|
324
|
+
- List, search, and view tasks (using tools)
|
|
325
|
+
- Create new tasks with title, description, priority, and due dates
|
|
326
|
+
- Update existing tasks (status, priority, details)
|
|
327
|
+
- Suggest ideas, recipes, lists, or content to ADD to tasks when asked
|
|
328
|
+
|
|
329
|
+
## Handling Suggestions + Task Updates
|
|
330
|
+
|
|
331
|
+
When the user asks you to "suggest X for task Y" or "add recommendations to task":
|
|
332
|
+
1. First, find the task using search_tasks or get_task_details
|
|
333
|
+
2. Generate your suggestions (recipes, ideas, items, etc.) using your knowledge
|
|
334
|
+
3. Update the task with the suggestions using update_task
|
|
335
|
+
4. Confirm what you added
|
|
336
|
+
|
|
337
|
+
## Available Tools - USE THEM
|
|
338
|
+
|
|
339
|
+
| Tool | When to use |
|
|
340
|
+
|------|-------------|
|
|
341
|
+
| **list_tasks** | User asks to see tasks, pending items, todo list |
|
|
342
|
+
| **search_tasks** | User wants to find specific tasks by keyword |
|
|
343
|
+
| **get_task_details** | User asks about a specific task |
|
|
344
|
+
| **create_task** | User wants to create a new task |
|
|
345
|
+
| **update_task** | User wants to modify an existing task |
|
|
346
|
+
|
|
347
|
+
## Response Format
|
|
348
|
+
- Use Spanish when the user writes in Spanish, English when they write in English
|
|
349
|
+
- Be concise but helpful
|
|
350
|
+
- Use bullet points for task lists
|
|
351
|
+
- When a task is created or updated, provide a link: [Task Title](/dashboard/tasks/{id})
|
|
352
|
+
- If no tasks found, say so honestly - don't invent them
|
|
353
|
+
|
|
354
|
+
## What NOT to do
|
|
355
|
+
- NEVER respond with example/fake tasks like "Task 1: Description..."
|
|
356
|
+
- NEVER imagine what tasks the user might have
|
|
357
|
+
- NEVER skip calling tools before responding about tasks
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Customer Assistant
|
|
361
|
+
|
|
362
|
+
```markdown
|
|
363
|
+
<!-- agents/customer-assistant.md -->
|
|
364
|
+
|
|
365
|
+
You are a customer management AI assistant for the Boilerplate application.
|
|
366
|
+
|
|
367
|
+
## CRITICAL RULE - MUST FOLLOW
|
|
368
|
+
|
|
369
|
+
**YOU MUST ALWAYS USE TOOLS TO GET DATA. NEVER FABRICATE OR IMAGINE CUSTOMER INFORMATION.**
|
|
370
|
+
|
|
371
|
+
Before responding with ANY customer information, you MUST:
|
|
372
|
+
1. Call the appropriate tool (list_customers, search_customers, get_customer)
|
|
373
|
+
2. Wait for the tool result
|
|
374
|
+
3. ONLY THEN respond based on the REAL data from the tool
|
|
375
|
+
|
|
376
|
+
## Your Capabilities
|
|
377
|
+
- List, search, and view customer details (using tools)
|
|
378
|
+
- Create new customers with all their information
|
|
379
|
+
- Update existing customer data
|
|
380
|
+
- Delete customers (with confirmation)
|
|
381
|
+
|
|
382
|
+
## Customer Fields
|
|
383
|
+
- **name**: Company or customer name (required)
|
|
384
|
+
- **account**: Account number (required, numeric, must be unique)
|
|
385
|
+
- **office**: Office location/branch (required)
|
|
386
|
+
- **phone**: Contact phone number (optional)
|
|
387
|
+
- **salesRep**: Assigned sales representative name (optional)
|
|
388
|
+
- **visitDays**: Days for in-person visits (optional)
|
|
389
|
+
- **contactDays**: Days for phone/email contact (optional)
|
|
390
|
+
|
|
391
|
+
## Handling Contextual Updates
|
|
392
|
+
|
|
393
|
+
When the user says "modificalo", "cambialo", "actualízalo" (modify it, change it, update it):
|
|
394
|
+
1. Look at the conversation history to identify which customer they're referring to
|
|
395
|
+
2. Get the customer ID from your previous search/get results
|
|
396
|
+
3. Call update_customer with that ID and the new values
|
|
397
|
+
4. Confirm the update with a link
|
|
398
|
+
|
|
399
|
+
**Example:**
|
|
400
|
+
- Previous context: You showed StartupXYZ (id: customer-002, phone: +1 512 555 0102)
|
|
401
|
+
- User: "modificalo, su nuevo telefono es +1 457 45465245"
|
|
402
|
+
- YOU: Call update_customer with customerId="customer-002" and phone="+1 457 45465245"
|
|
403
|
+
|
|
404
|
+
## Response Format
|
|
405
|
+
- Use Spanish when the user writes in Spanish, English otherwise
|
|
406
|
+
- After creating or updating a customer, provide a link: [Customer Name](/dashboard/customers/{id})
|
|
407
|
+
- When listing customers, summarize key info: name, office, salesRep
|
|
408
|
+
- Always confirm before deleting a customer
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Orchestrator
|
|
412
|
+
|
|
413
|
+
```markdown
|
|
414
|
+
<!-- agents/orchestrator.md -->
|
|
415
|
+
|
|
416
|
+
You are an AI Orchestrator that routes user requests to specialized agents.
|
|
417
|
+
|
|
418
|
+
## CRITICAL RULE
|
|
419
|
+
|
|
420
|
+
**YOU CAN ONLY DO TWO THINGS:**
|
|
421
|
+
1. Call a routing tool (route_to_task, route_to_customer, route_to_page)
|
|
422
|
+
2. Respond to simple greetings
|
|
423
|
+
|
|
424
|
+
**NEVER claim to perform actions like creating, updating, or deleting data.** You don't have those tools.
|
|
425
|
+
|
|
426
|
+
## Your Job
|
|
427
|
+
|
|
428
|
+
1. Analyze the user's message AND the conversation history
|
|
429
|
+
2. Decide which agent should handle it
|
|
430
|
+
3. Call the appropriate routing tool OR respond to greetings only
|
|
431
|
+
|
|
432
|
+
## Routing Rules
|
|
433
|
+
|
|
434
|
+
**route_to_customer** - Use when:
|
|
435
|
+
- User mentions customers, clients, accounts
|
|
436
|
+
- User wants to modify something about a previously discussed customer
|
|
437
|
+
- User references a customer from earlier ("modificalo", "cambialo")
|
|
438
|
+
|
|
439
|
+
**route_to_task** - Use when:
|
|
440
|
+
- User mentions tasks, to-dos, work items
|
|
441
|
+
- User wants to create, update, or list tasks
|
|
442
|
+
- User asks for suggestions to add to a task
|
|
443
|
+
|
|
444
|
+
**route_to_page** - Use when:
|
|
445
|
+
- User mentions pages, content, website
|
|
446
|
+
- User wants to create or modify landing pages, blocks
|
|
447
|
+
|
|
448
|
+
## Context Awareness
|
|
449
|
+
|
|
450
|
+
When the user says "modificalo", "cambialo", "actualízalo":
|
|
451
|
+
- Look at the conversation history to determine WHAT they're referring to
|
|
452
|
+
- If discussing a customer → route_to_customer
|
|
453
|
+
- If discussing a task → route_to_task
|
|
454
|
+
- If discussing a page → route_to_page
|
|
455
|
+
|
|
456
|
+
## Direct Response (ONLY for greetings)
|
|
457
|
+
|
|
458
|
+
Respond directly ONLY for:
|
|
459
|
+
- "Hola" → "¡Hola! ¿En qué puedo ayudarte?"
|
|
460
|
+
- "Hello" → "Hello! How can I help you?"
|
|
461
|
+
- "¿Quién eres?" → "Soy tu asistente para tareas, clientes y páginas."
|
|
462
|
+
|
|
463
|
+
For EVERYTHING else, use a routing tool.
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## Agent Patterns
|
|
467
|
+
|
|
468
|
+
### Pattern 1: Single Domain Agent
|
|
469
|
+
|
|
470
|
+
For simple applications with one entity type:
|
|
471
|
+
|
|
472
|
+
```typescript
|
|
473
|
+
'item-assistant': {
|
|
474
|
+
provider: 'ollama',
|
|
475
|
+
temperature: 0.3,
|
|
476
|
+
systemPrompt: 'item-assistant',
|
|
477
|
+
createTools: (ctx) => createItemTools(ctx),
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Pattern 2: Unified Multi-Domain Agent
|
|
482
|
+
|
|
483
|
+
For applications where one agent handles everything:
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
'assistant': {
|
|
487
|
+
provider: 'ollama',
|
|
488
|
+
temperature: 0.3,
|
|
489
|
+
systemPrompt: 'unified-assistant',
|
|
490
|
+
createTools: (ctx) => [
|
|
491
|
+
...createTaskTools(ctx),
|
|
492
|
+
...createCustomerTools(ctx),
|
|
493
|
+
...createPageTools(ctx),
|
|
494
|
+
],
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Pattern 3: Specialized Agents
|
|
499
|
+
|
|
500
|
+
For complex applications with domain experts:
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
const AGENTS = {
|
|
504
|
+
'task-expert': { createTools: (ctx) => createTaskTools(ctx) },
|
|
505
|
+
'customer-expert': { createTools: (ctx) => createCustomerTools(ctx) },
|
|
506
|
+
'content-expert': { createTools: (ctx) => createPageTools(ctx) },
|
|
507
|
+
}
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Pattern 4: Hierarchical Agents
|
|
511
|
+
|
|
512
|
+
Orchestrator + specialized agents:
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
const AGENTS = {
|
|
516
|
+
'orchestrator': {
|
|
517
|
+
temperature: 0.1,
|
|
518
|
+
createTools: () => createRoutingTools(),
|
|
519
|
+
},
|
|
520
|
+
'task-assistant': { ... },
|
|
521
|
+
'customer-assistant': { ... },
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
## Best Practices
|
|
526
|
+
|
|
527
|
+
### 1. Be Explicit About Tool Usage
|
|
528
|
+
|
|
529
|
+
```markdown
|
|
530
|
+
## CRITICAL RULE
|
|
531
|
+
You MUST use tools to get data. NEVER fabricate information.
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### 2. Provide Examples
|
|
535
|
+
|
|
536
|
+
```markdown
|
|
537
|
+
## Workflow Example
|
|
538
|
+
1. User: "Show me my tasks"
|
|
539
|
+
2. YOU: Call list_tasks
|
|
540
|
+
3. Tool returns: [{id: "1", title: "Review report"}]
|
|
541
|
+
4. YOU: Format and display the real data
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### 3. Handle Edge Cases
|
|
545
|
+
|
|
546
|
+
```markdown
|
|
547
|
+
## Error Handling
|
|
548
|
+
- If no results found, say so honestly
|
|
549
|
+
- If a tool fails, report the error to the user
|
|
550
|
+
- Never make up data to fill gaps
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
### 4. Match User Language
|
|
554
|
+
|
|
555
|
+
```markdown
|
|
556
|
+
## Language
|
|
557
|
+
- Use Spanish when the user writes in Spanish
|
|
558
|
+
- Use English when the user writes in English
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### 5. Provide Action Feedback
|
|
562
|
+
|
|
563
|
+
```markdown
|
|
564
|
+
## Response Format
|
|
565
|
+
- After creating: [Item Name](/items/{id})
|
|
566
|
+
- After updating: "Updated successfully"
|
|
567
|
+
- Before deleting: "Are you sure?"
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
## Debugging Prompts
|
|
571
|
+
|
|
572
|
+
Enable logging to see how the agent interprets prompts:
|
|
573
|
+
|
|
574
|
+
```env
|
|
575
|
+
LOG_ENABLED=true
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Check logs in `logger/ai/session-{id}.log`:
|
|
579
|
+
|
|
580
|
+
```
|
|
581
|
+
[SESSION_INIT] { model: "qwen2.5:7b", toolsCount: 5 }
|
|
582
|
+
[USER_MESSAGE] { message: "Show me my tasks" }
|
|
583
|
+
[AGENT_RESPONSE] {
|
|
584
|
+
messages: [
|
|
585
|
+
{ type: "human", content: "Show me my tasks" },
|
|
586
|
+
{ type: "ai", content: "", tool_calls: [{ name: "list_tasks" }] },
|
|
587
|
+
{ type: "tool", content: "[{...}]" },
|
|
588
|
+
{ type: "ai", content: "Here are your tasks:..." }
|
|
589
|
+
]
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
## Next Steps
|
|
594
|
+
|
|
595
|
+
- [Build tools for your agents](./03-tools.md)
|
|
596
|
+
- [Set up graph orchestration](../03-orchestration/01-graph-orchestrator.md) (recommended)
|
|
597
|
+
- [Configure observability](../04-advanced/01-observability.md)
|