@runflow-ai/sdk 1.0.24 → 1.0.27
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/README.md +1540 -395
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +9 -0
- package/dist/core/agent.js.map +1 -1
- package/dist/core/api-client.d.ts +6 -2
- package/dist/core/api-client.d.ts.map +1 -1
- package/dist/core/api-client.js +32 -1
- package/dist/core/api-client.js.map +1 -1
- package/dist/core/helpers/agent-memory.d.ts.map +1 -1
- package/dist/core/helpers/agent-memory.js +13 -2
- package/dist/core/helpers/agent-memory.js.map +1 -1
- package/dist/memory/memory-manager.d.ts +21 -41
- package/dist/memory/memory-manager.d.ts.map +1 -1
- package/dist/memory/memory-manager.js +85 -101
- package/dist/memory/memory-manager.js.map +1 -1
- package/dist/providers/runflow/memory-provider.d.ts +6 -2
- package/dist/providers/runflow/memory-provider.d.ts.map +1 -1
- package/dist/providers/runflow/memory-provider.js +14 -2
- package/dist/providers/runflow/memory-provider.js.map +1 -1
- package/dist/providers/types.d.ts +7 -4
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/types/all-types.d.ts +10 -5
- package/dist/types/all-types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,76 +1,111 @@
|
|
|
1
|
-
# 🚀 Runflow SDK
|
|
1
|
+
# 🚀 Runflow SDK
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **A powerful TypeScript-first framework for building intelligent AI agents and multi-agent systems**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Runflow SDK is a comprehensive, type-safe framework for building AI agents, complex workflows, and multi-agent systems. Designed to be simple to use yet powerful enough for advanced use cases.
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/@runflow-ai/sdk)
|
|
7
|
+
[](https://www.npmjs.com/package/@runflow-ai/sdk)
|
|
8
8
|
[](https://opensource.org/licenses/MIT)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
[](https://nodejs.org/)
|
|
11
|
+
|
|
12
|
+
## ✨ Features
|
|
13
|
+
|
|
14
|
+
- 🤖 **Intelligent Agents** - Create agents with LLM, tools, memory, and RAG capabilities
|
|
15
|
+
- 🔧 **Type-Safe Tools** - Build custom tools with Zod schema validation
|
|
16
|
+
- 🔌 **Built-in Connectors** - HubSpot, Twilio, Email, Slack integrations out of the box
|
|
17
|
+
- 🌊 **Workflows** - Orchestrate complex multi-step processes with conditional logic
|
|
18
|
+
- 🧠 **Memory Management** - Persistent conversation history with automatic summarization
|
|
19
|
+
- 📚 **Agentic RAG** - LLM-driven semantic search in vector knowledge bases
|
|
20
|
+
- 👥 **Multi-Agent Systems** - Supervisor pattern with automatic agent routing
|
|
21
|
+
- 🔍 **Full Observability** - Automatic tracing with cost tracking and performance metrics
|
|
22
|
+
- 📡 **Streaming Support** - Real-time streaming responses with memory persistence
|
|
23
|
+
- 🎨 **Multi-Modal** - Support for text and images (vision models)
|
|
24
|
+
- 🔄 **Multiple Providers** - OpenAI, Anthropic (Claude), and AWS Bedrock
|
|
25
|
+
|
|
26
|
+
## 📑 Table of Contents
|
|
27
|
+
|
|
28
|
+
- [Installation](#-installation)
|
|
13
29
|
- [Quick Start](#-quick-start)
|
|
14
|
-
- [
|
|
30
|
+
- [Core Concepts](#-core-concepts)
|
|
15
31
|
- [Agents](#agents)
|
|
16
|
-
- [Context Management](#context-management
|
|
32
|
+
- [Context Management](#context-management)
|
|
17
33
|
- [Memory](#memory)
|
|
18
34
|
- [Tools](#tools)
|
|
19
35
|
- [Connectors](#connectors)
|
|
20
36
|
- [Workflows](#workflows)
|
|
21
|
-
- [RAG
|
|
37
|
+
- [Knowledge (RAG)](#knowledge-rag)
|
|
22
38
|
- [LLM Standalone](#llm-standalone)
|
|
23
39
|
- [Observability](#observability)
|
|
24
|
-
- [
|
|
25
|
-
- [
|
|
26
|
-
- [
|
|
40
|
+
- [Advanced Examples](#-advanced-examples)
|
|
41
|
+
- [Real-World Use Cases](#-real-world-use-cases)
|
|
42
|
+
- [Customer Support Agent with RAG](#1-customer-support-agent-with-rag)
|
|
43
|
+
- [Sales Automation with Multi-Step Workflow](#2-sales-automation-with-multi-step-workflow)
|
|
44
|
+
- [Intelligent Collections Agent (WhatsApp)](#3-intelligent-collections-agent-whatsapp)
|
|
45
|
+
- [Customer Onboarding Assistant](#4-customer-onboarding-assistant)
|
|
46
|
+
- [Feedback Analysis System](#5-feedback-analysis-system)
|
|
47
|
+
- [Multi-Agent System (Supervisor Pattern)](#6-multi-agent-system-supervisor-pattern)
|
|
48
|
+
- [Configuration](#-configuration)
|
|
27
49
|
- [API Reference](#-api-reference)
|
|
50
|
+
- [TypeScript Types](#-typescript-types)
|
|
28
51
|
- [Providers](#-providers)
|
|
29
|
-
- [
|
|
52
|
+
- [Troubleshooting](#-troubleshooting)
|
|
53
|
+
- [Contributing](#-contributing)
|
|
54
|
+
- [License](#-license)
|
|
30
55
|
|
|
31
56
|
---
|
|
32
57
|
|
|
33
|
-
## 📦
|
|
58
|
+
## 📦 Installation
|
|
34
59
|
|
|
35
60
|
```bash
|
|
36
61
|
npm install @runflow-ai/sdk
|
|
37
|
-
#
|
|
62
|
+
# or
|
|
38
63
|
yarn add @runflow-ai/sdk
|
|
64
|
+
# or
|
|
65
|
+
pnpm add @runflow-ai/sdk
|
|
39
66
|
```
|
|
40
67
|
|
|
41
|
-
###
|
|
68
|
+
### Requirements
|
|
42
69
|
|
|
43
70
|
- **Node.js**: >= 22.0.0
|
|
44
|
-
- **TypeScript**: >= 5.0.0 (
|
|
45
|
-
- **Zod**: ^3.22.0 (
|
|
71
|
+
- **TypeScript**: >= 5.0.0 (recommended)
|
|
72
|
+
- **Zod**: ^3.22.0 (included as dependency)
|
|
46
73
|
|
|
47
74
|
---
|
|
48
75
|
|
|
49
76
|
## 🚀 Quick Start
|
|
50
77
|
|
|
51
|
-
|
|
78
|
+
> **Note on Parameters:**
|
|
79
|
+
> - `message` is **required** (the user's message)
|
|
80
|
+
> - `companyId` is **optional** (for multi-tenant applications - your end-user's company ID)
|
|
81
|
+
> - `sessionId` is **optional** but recommended (maintains conversation history)
|
|
82
|
+
> - `userId` is **optional** (for user identification)
|
|
83
|
+
> - All other fields are optional and can be set via `Runflow.identify()` or environment variables
|
|
84
|
+
|
|
85
|
+
### Simple Agent
|
|
52
86
|
|
|
53
87
|
```typescript
|
|
54
88
|
import { Agent, openai } from '@runflow-ai/sdk';
|
|
55
89
|
|
|
56
|
-
//
|
|
90
|
+
// Create a basic agent
|
|
57
91
|
const agent = new Agent({
|
|
58
92
|
name: 'Support Agent',
|
|
59
93
|
instructions: 'You are a helpful customer support assistant.',
|
|
60
94
|
model: openai('gpt-4o'),
|
|
61
95
|
});
|
|
62
96
|
|
|
63
|
-
//
|
|
97
|
+
// Process a message
|
|
64
98
|
const result = await agent.process({
|
|
65
|
-
message: 'I need help with my order',
|
|
66
|
-
|
|
67
|
-
|
|
99
|
+
message: 'I need help with my order', // Required
|
|
100
|
+
sessionId: 'session_456', // Optional: For conversation history
|
|
101
|
+
userId: 'user_789', // Optional: User identifier
|
|
102
|
+
companyId: 'company_123', // Optional: For multi-tenant apps
|
|
68
103
|
});
|
|
69
104
|
|
|
70
105
|
console.log(result.message);
|
|
71
106
|
```
|
|
72
107
|
|
|
73
|
-
### Agent
|
|
108
|
+
### Agent with Memory
|
|
74
109
|
|
|
75
110
|
```typescript
|
|
76
111
|
import { Agent, openai } from '@runflow-ai/sdk';
|
|
@@ -80,35 +115,32 @@ const agent = new Agent({
|
|
|
80
115
|
instructions: 'You are a helpful assistant with memory.',
|
|
81
116
|
model: openai('gpt-4o'),
|
|
82
117
|
memory: {
|
|
83
|
-
type: 'conversation',
|
|
84
118
|
maxTurns: 10,
|
|
85
119
|
},
|
|
86
120
|
});
|
|
87
121
|
|
|
88
|
-
//
|
|
122
|
+
// First interaction
|
|
89
123
|
await agent.process({
|
|
90
124
|
message: 'My name is John',
|
|
91
|
-
|
|
92
|
-
sessionId: 'session_456',
|
|
125
|
+
sessionId: 'session_456', // Same session for conversation continuity
|
|
93
126
|
});
|
|
94
127
|
|
|
95
|
-
//
|
|
128
|
+
// Second interaction - agent remembers the name
|
|
96
129
|
const result = await agent.process({
|
|
97
130
|
message: 'What is my name?',
|
|
98
|
-
|
|
99
|
-
sessionId: 'session_456',
|
|
131
|
+
sessionId: 'session_456', // Same session
|
|
100
132
|
});
|
|
101
133
|
|
|
102
134
|
console.log(result.message); // "Your name is John"
|
|
103
135
|
```
|
|
104
136
|
|
|
105
|
-
### Agent
|
|
137
|
+
### Agent with Tools
|
|
106
138
|
|
|
107
139
|
```typescript
|
|
108
140
|
import { Agent, openai, createTool } from '@runflow-ai/sdk';
|
|
109
141
|
import { z } from 'zod';
|
|
110
142
|
|
|
111
|
-
//
|
|
143
|
+
// Create a custom tool
|
|
112
144
|
const weatherTool = createTool({
|
|
113
145
|
id: 'get-weather',
|
|
114
146
|
description: 'Get current weather for a location',
|
|
@@ -116,7 +148,7 @@ const weatherTool = createTool({
|
|
|
116
148
|
location: z.string(),
|
|
117
149
|
}),
|
|
118
150
|
execute: async ({ context }) => {
|
|
119
|
-
//
|
|
151
|
+
// Fetch weather data
|
|
120
152
|
return {
|
|
121
153
|
temperature: 22,
|
|
122
154
|
condition: 'Sunny',
|
|
@@ -125,7 +157,7 @@ const weatherTool = createTool({
|
|
|
125
157
|
},
|
|
126
158
|
});
|
|
127
159
|
|
|
128
|
-
//
|
|
160
|
+
// Create agent with tool
|
|
129
161
|
const agent = new Agent({
|
|
130
162
|
name: 'Weather Agent',
|
|
131
163
|
instructions: 'You help users check the weather.',
|
|
@@ -137,28 +169,54 @@ const agent = new Agent({
|
|
|
137
169
|
|
|
138
170
|
const result = await agent.process({
|
|
139
171
|
message: 'What is the weather in São Paulo?',
|
|
140
|
-
companyId: 'company_123',
|
|
141
172
|
});
|
|
142
173
|
|
|
143
174
|
console.log(result.message);
|
|
144
175
|
```
|
|
145
176
|
|
|
177
|
+
### Agent with RAG (Knowledge Base)
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { Agent, openai } from '@runflow-ai/sdk';
|
|
181
|
+
|
|
182
|
+
const agent = new Agent({
|
|
183
|
+
name: 'Support Agent',
|
|
184
|
+
instructions: 'You are a helpful support agent.',
|
|
185
|
+
model: openai('gpt-4o'),
|
|
186
|
+
rag: {
|
|
187
|
+
vectorStore: 'support-docs',
|
|
188
|
+
k: 5,
|
|
189
|
+
threshold: 0.7,
|
|
190
|
+
searchPrompt: `Use searchKnowledge tool when user asks about:
|
|
191
|
+
- Technical problems
|
|
192
|
+
- Process questions
|
|
193
|
+
- Specific information`,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Agent automatically has 'searchKnowledge' tool
|
|
198
|
+
// LLM decides when to use it (not always searching - more efficient!)
|
|
199
|
+
const result = await agent.process({
|
|
200
|
+
message: 'How do I reset my password?',
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
146
204
|
---
|
|
147
205
|
|
|
148
|
-
## 🎯
|
|
206
|
+
## 🎯 Core Concepts
|
|
149
207
|
|
|
150
208
|
### Agents
|
|
151
209
|
|
|
152
|
-
|
|
210
|
+
**Agents** are the fundamental building blocks of the Runflow SDK. Each agent is configured with:
|
|
153
211
|
|
|
154
|
-
- **Name**:
|
|
155
|
-
- **Instructions**:
|
|
156
|
-
- **Model**:
|
|
157
|
-
- **Tools**:
|
|
158
|
-
- **Memory**:
|
|
159
|
-
- **RAG**:
|
|
212
|
+
- **Name**: Agent identifier
|
|
213
|
+
- **Instructions**: Behavior instructions (system prompt)
|
|
214
|
+
- **Model**: LLM model to use (OpenAI, Anthropic, Bedrock)
|
|
215
|
+
- **Tools**: Available tools for the agent
|
|
216
|
+
- **Memory**: Memory configuration
|
|
217
|
+
- **RAG**: Knowledge base search configuration
|
|
160
218
|
|
|
161
|
-
####
|
|
219
|
+
#### Complete Agent Configuration
|
|
162
220
|
|
|
163
221
|
```typescript
|
|
164
222
|
import { Agent, anthropic } from '@runflow-ai/sdk';
|
|
@@ -169,46 +227,55 @@ const agent = new Agent({
|
|
|
169
227
|
- Always be polite and helpful
|
|
170
228
|
- Solve problems efficiently
|
|
171
229
|
- Use tools when needed`,
|
|
172
|
-
|
|
173
|
-
//
|
|
230
|
+
|
|
231
|
+
// Model
|
|
174
232
|
model: anthropic('claude-3-5-sonnet-20241022'),
|
|
175
|
-
|
|
176
|
-
//
|
|
233
|
+
|
|
234
|
+
// Model configuration
|
|
177
235
|
modelConfig: {
|
|
178
236
|
temperature: 0.7,
|
|
179
237
|
maxTokens: 4000,
|
|
180
238
|
topP: 0.9,
|
|
239
|
+
frequencyPenalty: 0,
|
|
240
|
+
presencePenalty: 0,
|
|
181
241
|
},
|
|
182
|
-
|
|
183
|
-
//
|
|
242
|
+
|
|
243
|
+
// Memory
|
|
184
244
|
memory: {
|
|
185
|
-
type: 'conversation',
|
|
186
245
|
maxTurns: 20,
|
|
187
246
|
summarizeAfter: 50,
|
|
247
|
+
summarizePrompt: 'Create a concise summary highlighting key points and decisions',
|
|
248
|
+
summarizeModel: openai('gpt-4o-mini'), // Cheaper model for summaries
|
|
188
249
|
},
|
|
189
|
-
|
|
190
|
-
// RAG
|
|
250
|
+
|
|
251
|
+
// RAG (Agentic - LLM decides when to search)
|
|
191
252
|
rag: {
|
|
192
253
|
vectorStore: 'support-docs',
|
|
193
|
-
autoSearch: true,
|
|
194
254
|
k: 5,
|
|
195
255
|
threshold: 0.7,
|
|
256
|
+
searchPrompt: 'Use for technical questions',
|
|
196
257
|
},
|
|
197
|
-
|
|
258
|
+
|
|
198
259
|
// Tools
|
|
199
260
|
tools: {
|
|
200
261
|
createTicket: ticketTool,
|
|
201
262
|
searchOrders: orderTool,
|
|
202
263
|
},
|
|
203
|
-
|
|
264
|
+
|
|
265
|
+
// Tool iteration limit
|
|
266
|
+
maxToolIterations: 10,
|
|
267
|
+
|
|
204
268
|
// Streaming
|
|
205
269
|
streaming: {
|
|
206
270
|
enabled: true,
|
|
207
271
|
},
|
|
272
|
+
|
|
273
|
+
// Debug mode
|
|
274
|
+
debug: true,
|
|
208
275
|
});
|
|
209
276
|
```
|
|
210
277
|
|
|
211
|
-
####
|
|
278
|
+
#### Supported Models
|
|
212
279
|
|
|
213
280
|
```typescript
|
|
214
281
|
import { openai, anthropic, bedrock } from '@runflow-ai/sdk';
|
|
@@ -216,54 +283,128 @@ import { openai, anthropic, bedrock } from '@runflow-ai/sdk';
|
|
|
216
283
|
// OpenAI
|
|
217
284
|
const gpt4 = openai('gpt-4o');
|
|
218
285
|
const gpt4mini = openai('gpt-4o-mini');
|
|
286
|
+
const gpt4turbo = openai('gpt-4-turbo');
|
|
219
287
|
const gpt35 = openai('gpt-3.5-turbo');
|
|
220
288
|
|
|
221
|
-
// Anthropic
|
|
289
|
+
// Anthropic (Claude)
|
|
222
290
|
const claude35 = anthropic('claude-3-5-sonnet-20241022');
|
|
223
|
-
const
|
|
291
|
+
const claude3opus = anthropic('claude-3-opus-20240229');
|
|
292
|
+
const claude3sonnet = anthropic('claude-3-sonnet-20240229');
|
|
293
|
+
const claude3haiku = anthropic('claude-3-haiku-20240307');
|
|
224
294
|
|
|
225
295
|
// AWS Bedrock
|
|
226
296
|
const claudeBedrock = bedrock('anthropic.claude-3-sonnet-20240229-v1:0');
|
|
227
297
|
const titan = bedrock('amazon.titan-text-express-v1');
|
|
228
298
|
```
|
|
229
299
|
|
|
230
|
-
|
|
300
|
+
#### Agent Methods
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
// Process a message
|
|
304
|
+
const result = await agent.process(input: AgentInput): Promise<AgentOutput>;
|
|
305
|
+
|
|
306
|
+
// Stream a message
|
|
307
|
+
const stream = await agent.processStream(input: AgentInput): AsyncIterable<ChunkType>;
|
|
308
|
+
|
|
309
|
+
// Simple generation (without full agent context)
|
|
310
|
+
const response = await agent.generate(input: string | Message[]): Promise<{ text: string }>;
|
|
311
|
+
|
|
312
|
+
// Streaming generation
|
|
313
|
+
const stream = await agent.generateStream(prompt: string): AsyncIterable<ChunkType>;
|
|
314
|
+
|
|
315
|
+
// Generation with tools
|
|
316
|
+
const response = await agent.generateWithTools(input): Promise<{ text: string }>;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
#### Multi-Agent Systems (Supervisor Pattern)
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
const supervisor = new Agent({
|
|
323
|
+
name: 'Supervisor',
|
|
324
|
+
instructions: 'Route tasks to appropriate agents.',
|
|
325
|
+
model: openai('gpt-4o'),
|
|
326
|
+
agents: {
|
|
327
|
+
support: {
|
|
328
|
+
name: 'Support Agent',
|
|
329
|
+
instructions: 'Handle support requests.',
|
|
330
|
+
model: openai('gpt-4o-mini'),
|
|
331
|
+
},
|
|
332
|
+
sales: {
|
|
333
|
+
name: 'Sales Agent',
|
|
334
|
+
instructions: 'Handle sales inquiries.',
|
|
335
|
+
model: openai('gpt-4o-mini'),
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
// Supervisor automatically routes to the appropriate agent
|
|
341
|
+
await supervisor.process({
|
|
342
|
+
message: 'I want to buy your product',
|
|
343
|
+
sessionId: 'session_123',
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
#### Debug Mode
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
const agent = new Agent({
|
|
351
|
+
name: 'Debug Agent',
|
|
352
|
+
instructions: 'Help users',
|
|
353
|
+
model: openai('gpt-4o'),
|
|
354
|
+
|
|
355
|
+
// Simple debug (all logs enabled)
|
|
356
|
+
debug: true,
|
|
357
|
+
|
|
358
|
+
// Or detailed debug configuration
|
|
359
|
+
debug: {
|
|
360
|
+
enabled: true,
|
|
361
|
+
logMessages: true, // Log messages
|
|
362
|
+
logLLMCalls: true, // Log LLM API calls
|
|
363
|
+
logToolCalls: true, // Log tool executions
|
|
364
|
+
logRAG: true, // Log RAG searches
|
|
365
|
+
logMemory: true, // Log memory operations
|
|
366
|
+
truncateAt: 1000, // Truncate logs at N characters
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### Context Management
|
|
231
374
|
|
|
232
|
-
|
|
375
|
+
The **Runflow Context** is a global singleton that manages execution information and user identification. It allows you to identify once and all agents/workflows automatically use this context.
|
|
233
376
|
|
|
234
|
-
####
|
|
377
|
+
#### Basic Usage
|
|
235
378
|
|
|
236
379
|
```typescript
|
|
237
380
|
import { Runflow, Agent, openai } from '@runflow-ai/sdk';
|
|
238
381
|
|
|
239
|
-
//
|
|
382
|
+
// Identify user by phone (WhatsApp)
|
|
240
383
|
Runflow.identify({
|
|
241
384
|
type: 'phone',
|
|
242
385
|
value: '+5511999999999',
|
|
243
386
|
});
|
|
244
387
|
|
|
245
|
-
// Agent
|
|
388
|
+
// Agent automatically uses the context
|
|
246
389
|
const agent = new Agent({
|
|
247
390
|
name: 'WhatsApp Bot',
|
|
248
391
|
instructions: 'You are a helpful assistant.',
|
|
249
392
|
model: openai('gpt-4o'),
|
|
250
393
|
memory: {
|
|
251
|
-
type: 'conversation',
|
|
252
394
|
maxTurns: 10,
|
|
253
395
|
},
|
|
254
396
|
});
|
|
255
397
|
|
|
256
|
-
//
|
|
398
|
+
// Memory is automatically bound to the phone number
|
|
257
399
|
await agent.process({
|
|
258
400
|
message: 'Hello!',
|
|
259
|
-
companyId: 'company_123',
|
|
260
401
|
});
|
|
261
402
|
```
|
|
262
403
|
|
|
263
|
-
####
|
|
404
|
+
#### Identification Types
|
|
264
405
|
|
|
265
406
|
```typescript
|
|
266
|
-
// WhatsApp/SMS (
|
|
407
|
+
// WhatsApp/SMS (by phone)
|
|
267
408
|
Runflow.identify({
|
|
268
409
|
type: 'phone',
|
|
269
410
|
value: '+5511999999999',
|
|
@@ -282,14 +423,14 @@ Runflow.identify({
|
|
|
282
423
|
userId: 'user@example.com',
|
|
283
424
|
});
|
|
284
425
|
|
|
285
|
-
// Custom (
|
|
426
|
+
// Custom (order, ticket, etc)
|
|
286
427
|
Runflow.identify({
|
|
287
428
|
type: 'order',
|
|
288
429
|
value: 'order_456',
|
|
289
430
|
userId: 'customer_789',
|
|
290
431
|
});
|
|
291
432
|
|
|
292
|
-
//
|
|
433
|
+
// With custom threadId
|
|
293
434
|
Runflow.identify({
|
|
294
435
|
type: 'phone',
|
|
295
436
|
value: '+5511999999999',
|
|
@@ -300,10 +441,14 @@ Runflow.identify({
|
|
|
300
441
|
#### State Management
|
|
301
442
|
|
|
302
443
|
```typescript
|
|
303
|
-
// Get
|
|
444
|
+
// Get complete state
|
|
304
445
|
const state = Runflow.getState();
|
|
305
446
|
|
|
306
|
-
//
|
|
447
|
+
// Get specific value
|
|
448
|
+
const threadId = Runflow.get('threadId');
|
|
449
|
+
const entityType = Runflow.get('entityType');
|
|
450
|
+
|
|
451
|
+
// Set custom state (advanced)
|
|
307
452
|
Runflow.setState({
|
|
308
453
|
entityType: 'custom',
|
|
309
454
|
entityValue: 'xyz',
|
|
@@ -312,15 +457,17 @@ Runflow.setState({
|
|
|
312
457
|
metadata: { custom: 'data' },
|
|
313
458
|
});
|
|
314
459
|
|
|
315
|
-
//
|
|
460
|
+
// Clear state (useful for testing)
|
|
316
461
|
Runflow.clearState();
|
|
317
462
|
```
|
|
318
463
|
|
|
464
|
+
---
|
|
465
|
+
|
|
319
466
|
### Memory
|
|
320
467
|
|
|
321
|
-
|
|
468
|
+
The **Memory** system intelligently manages conversation history.
|
|
322
469
|
|
|
323
|
-
#### Memory
|
|
470
|
+
#### Memory Integrated in Agent
|
|
324
471
|
|
|
325
472
|
```typescript
|
|
326
473
|
const agent = new Agent({
|
|
@@ -328,91 +475,140 @@ const agent = new Agent({
|
|
|
328
475
|
instructions: 'You remember everything.',
|
|
329
476
|
model: openai('gpt-4o'),
|
|
330
477
|
memory: {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
478
|
+
maxTurns: 20, // Limit turns
|
|
479
|
+
maxTokens: 4000, // Limit tokens
|
|
480
|
+
summarizeAfter: 50, // Summarize after N turns
|
|
481
|
+
summarizePrompt: 'Create a concise summary with key facts and action items',
|
|
482
|
+
summarizeModel: openai('gpt-4o-mini'), // Cheaper model for summaries
|
|
335
483
|
},
|
|
336
484
|
});
|
|
337
485
|
```
|
|
338
486
|
|
|
339
|
-
#### Memory
|
|
487
|
+
#### Standalone Memory Manager
|
|
340
488
|
|
|
341
489
|
```typescript
|
|
342
490
|
import { Memory } from '@runflow-ai/sdk';
|
|
343
491
|
|
|
344
|
-
//
|
|
345
|
-
|
|
346
|
-
sessionId: 'session_123',
|
|
347
|
-
maxTurns: 10,
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
// Append mensagens
|
|
351
|
-
await memory.append({
|
|
492
|
+
// Using static methods (most common - 99% of cases)
|
|
493
|
+
await Memory.append({
|
|
352
494
|
role: 'user',
|
|
353
495
|
content: 'Hello!',
|
|
354
496
|
timestamp: new Date(),
|
|
355
497
|
});
|
|
356
498
|
|
|
357
|
-
await
|
|
499
|
+
await Memory.append({
|
|
358
500
|
role: 'assistant',
|
|
359
501
|
content: 'Hi! How can I help you?',
|
|
360
502
|
timestamp: new Date(),
|
|
361
503
|
});
|
|
362
504
|
|
|
363
|
-
// Get
|
|
364
|
-
const history = await
|
|
505
|
+
// Get formatted history
|
|
506
|
+
const history = await Memory.getFormatted();
|
|
365
507
|
console.log(history);
|
|
366
508
|
|
|
367
|
-
// Get
|
|
368
|
-
const recent = await
|
|
509
|
+
// Get recent messages
|
|
510
|
+
const recent = await Memory.getRecent(5); // Last 5 turns
|
|
369
511
|
|
|
370
|
-
//
|
|
371
|
-
const results = await
|
|
512
|
+
// Search in memory
|
|
513
|
+
const results = await Memory.search('order');
|
|
372
514
|
|
|
373
|
-
//
|
|
374
|
-
await
|
|
515
|
+
// Check if memory exists
|
|
516
|
+
const exists = await Memory.exists();
|
|
517
|
+
|
|
518
|
+
// Get full memory data
|
|
519
|
+
const data = await Memory.get();
|
|
520
|
+
|
|
521
|
+
// Clear memory
|
|
522
|
+
await Memory.clear();
|
|
375
523
|
```
|
|
376
524
|
|
|
377
|
-
#### Memory
|
|
525
|
+
#### Memory with Runflow Context
|
|
378
526
|
|
|
379
527
|
```typescript
|
|
380
528
|
import { Runflow, Memory } from '@runflow-ai/sdk';
|
|
381
529
|
|
|
382
|
-
//
|
|
530
|
+
// Identify user
|
|
383
531
|
Runflow.identify({
|
|
384
532
|
type: 'phone',
|
|
385
533
|
value: '+5511999999999',
|
|
386
534
|
});
|
|
387
535
|
|
|
388
|
-
// Memory
|
|
389
|
-
|
|
390
|
-
maxTurns: 10,
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
// Memória é vinculada ao telefone automaticamente
|
|
394
|
-
await memory.append({
|
|
536
|
+
// Memory automatically uses the context
|
|
537
|
+
await Memory.append({
|
|
395
538
|
role: 'user',
|
|
396
539
|
content: 'My order number is 12345',
|
|
397
540
|
timestamp: new Date(),
|
|
398
541
|
});
|
|
542
|
+
|
|
543
|
+
// Memory is automatically bound to the phone number
|
|
399
544
|
```
|
|
400
545
|
|
|
401
546
|
#### Custom Memory Key
|
|
402
547
|
|
|
403
548
|
```typescript
|
|
404
|
-
//
|
|
549
|
+
// Create memory with custom key
|
|
405
550
|
const memory = new Memory({
|
|
406
551
|
memoryKey: 'custom_key_123',
|
|
407
552
|
maxTurns: 10,
|
|
408
553
|
});
|
|
554
|
+
|
|
555
|
+
// Now use instance methods
|
|
556
|
+
await memory.append({ role: 'user', content: 'Hello', timestamp: new Date() });
|
|
557
|
+
const history = await memory.getFormatted();
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
#### Cross-Session Access
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
// Access memory from different sessions (admin, analytics, etc)
|
|
564
|
+
const dataUser1 = await Memory.get('phone:+5511999999999');
|
|
565
|
+
const dataUser2 = await Memory.get('email:user@example.com');
|
|
566
|
+
|
|
567
|
+
// Search across multiple sessions
|
|
568
|
+
const results = await Promise.all([
|
|
569
|
+
Memory.search('bug', 'user:123'),
|
|
570
|
+
Memory.search('bug', 'user:456'),
|
|
571
|
+
Memory.search('bug', 'user:789'),
|
|
572
|
+
]);
|
|
573
|
+
|
|
574
|
+
// Get recent from specific session
|
|
575
|
+
const recent = await Memory.getRecent(5, 'session:abc123');
|
|
576
|
+
|
|
577
|
+
// Clear specific session
|
|
578
|
+
await Memory.clear('phone:+5511999999999');
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
#### Custom Summarization
|
|
582
|
+
|
|
583
|
+
```typescript
|
|
584
|
+
// Agent with custom summarization
|
|
585
|
+
const agent = new Agent({
|
|
586
|
+
name: 'Smart Agent',
|
|
587
|
+
model: openai('gpt-4o'),
|
|
588
|
+
memory: {
|
|
589
|
+
summarizeAfter: 30,
|
|
590
|
+
summarizePrompt: `Summarize in 3 bullet points:
|
|
591
|
+
- Main issue discussed
|
|
592
|
+
- Solution provided
|
|
593
|
+
- Next steps`,
|
|
594
|
+
summarizeModel: anthropic('claude-3-haiku'), // Fast & cheap
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
// Manual summarization with custom prompt
|
|
599
|
+
const summary = await Memory.summarize({
|
|
600
|
+
prompt: 'Extract only the key decisions from this conversation',
|
|
601
|
+
model: openai('gpt-4o-mini'),
|
|
602
|
+
});
|
|
409
603
|
```
|
|
410
604
|
|
|
605
|
+
---
|
|
606
|
+
|
|
411
607
|
### Tools
|
|
412
608
|
|
|
413
|
-
**Tools**
|
|
609
|
+
**Tools** are functions that agents can call to perform specific actions. The SDK uses Zod for type-safe validation.
|
|
414
610
|
|
|
415
|
-
####
|
|
611
|
+
#### Create Basic Tool
|
|
416
612
|
|
|
417
613
|
```typescript
|
|
418
614
|
import { createTool } from '@runflow-ai/sdk';
|
|
@@ -429,10 +625,10 @@ const weatherTool = createTool({
|
|
|
429
625
|
temperature: z.number(),
|
|
430
626
|
condition: z.string(),
|
|
431
627
|
}),
|
|
432
|
-
execute: async ({ context, runflow }) => {
|
|
433
|
-
//
|
|
628
|
+
execute: async ({ context, runflow, projectId }) => {
|
|
629
|
+
// Implement logic
|
|
434
630
|
const weather = await fetchWeather(context.location);
|
|
435
|
-
|
|
631
|
+
|
|
436
632
|
return {
|
|
437
633
|
temperature: weather.temp,
|
|
438
634
|
condition: weather.condition,
|
|
@@ -441,7 +637,7 @@ const weatherTool = createTool({
|
|
|
441
637
|
});
|
|
442
638
|
```
|
|
443
639
|
|
|
444
|
-
#### Tool
|
|
640
|
+
#### Tool with Runflow API
|
|
445
641
|
|
|
446
642
|
```typescript
|
|
447
643
|
const searchDocsTool = createTool({
|
|
@@ -451,12 +647,12 @@ const searchDocsTool = createTool({
|
|
|
451
647
|
query: z.string(),
|
|
452
648
|
}),
|
|
453
649
|
execute: async ({ context, runflow }) => {
|
|
454
|
-
//
|
|
650
|
+
// Use Runflow API for vector search
|
|
455
651
|
const results = await runflow.vectorSearch(context.query, {
|
|
456
652
|
vectorStore: 'docs',
|
|
457
653
|
k: 5,
|
|
458
654
|
});
|
|
459
|
-
|
|
655
|
+
|
|
460
656
|
return {
|
|
461
657
|
results: results.results.map(r => r.content),
|
|
462
658
|
};
|
|
@@ -464,7 +660,7 @@ const searchDocsTool = createTool({
|
|
|
464
660
|
});
|
|
465
661
|
```
|
|
466
662
|
|
|
467
|
-
#### Tool
|
|
663
|
+
#### Tool with Connector
|
|
468
664
|
|
|
469
665
|
```typescript
|
|
470
666
|
const createTicketTool = createTool({
|
|
@@ -476,7 +672,7 @@ const createTicketTool = createTool({
|
|
|
476
672
|
priority: z.enum(['low', 'medium', 'high']),
|
|
477
673
|
}),
|
|
478
674
|
execute: async ({ context, runflow }) => {
|
|
479
|
-
//
|
|
675
|
+
// Use connector
|
|
480
676
|
const ticket = await runflow.connector(
|
|
481
677
|
'hubspot',
|
|
482
678
|
'tickets',
|
|
@@ -487,22 +683,31 @@ const createTicketTool = createTool({
|
|
|
487
683
|
priority: context.priority,
|
|
488
684
|
}
|
|
489
685
|
);
|
|
490
|
-
|
|
686
|
+
|
|
491
687
|
return { ticketId: ticket.id };
|
|
492
688
|
},
|
|
493
689
|
});
|
|
494
690
|
```
|
|
495
691
|
|
|
692
|
+
#### Tool Execution Context
|
|
693
|
+
|
|
694
|
+
The `execute` function receives:
|
|
695
|
+
- `context`: Validated input parameters (from `inputSchema`)
|
|
696
|
+
- `runflow`: Runflow API client for vector search, connectors, memory
|
|
697
|
+
- `projectId`: Current project ID
|
|
698
|
+
|
|
699
|
+
---
|
|
700
|
+
|
|
496
701
|
### Connectors
|
|
497
702
|
|
|
498
|
-
**Connectors**
|
|
703
|
+
**Connectors** are pre-configured integrations with external services (HubSpot, Twilio, Email, Slack).
|
|
499
704
|
|
|
500
|
-
####
|
|
705
|
+
#### Create Connector Tool
|
|
501
706
|
|
|
502
707
|
```typescript
|
|
503
708
|
import { createConnectorTool } from '@runflow-ai/sdk';
|
|
504
709
|
|
|
505
|
-
// HubSpot -
|
|
710
|
+
// HubSpot - Create contact
|
|
506
711
|
const createContact = createConnectorTool(
|
|
507
712
|
'hubspot',
|
|
508
713
|
'contacts',
|
|
@@ -516,7 +721,7 @@ const createContact = createConnectorTool(
|
|
|
516
721
|
}
|
|
517
722
|
);
|
|
518
723
|
|
|
519
|
-
// Twilio -
|
|
724
|
+
// Twilio - Send WhatsApp
|
|
520
725
|
const sendWhatsApp = createConnectorTool(
|
|
521
726
|
'twilio',
|
|
522
727
|
'messages',
|
|
@@ -528,7 +733,7 @@ const sendWhatsApp = createConnectorTool(
|
|
|
528
733
|
}
|
|
529
734
|
);
|
|
530
735
|
|
|
531
|
-
// Email -
|
|
736
|
+
// Email - Send email
|
|
532
737
|
const sendEmail = createConnectorTool(
|
|
533
738
|
'email',
|
|
534
739
|
'messages',
|
|
@@ -540,9 +745,22 @@ const sendEmail = createConnectorTool(
|
|
|
540
745
|
html: 'boolean?',
|
|
541
746
|
}
|
|
542
747
|
);
|
|
748
|
+
|
|
749
|
+
// Slack - Send message
|
|
750
|
+
const sendSlack = createConnectorTool(
|
|
751
|
+
'slack',
|
|
752
|
+
'messages',
|
|
753
|
+
'send',
|
|
754
|
+
{
|
|
755
|
+
channel: 'string',
|
|
756
|
+
message: 'string',
|
|
757
|
+
username: 'string?',
|
|
758
|
+
iconEmoji: 'string?',
|
|
759
|
+
}
|
|
760
|
+
);
|
|
543
761
|
```
|
|
544
762
|
|
|
545
|
-
####
|
|
763
|
+
#### Use Built-in Shortcuts
|
|
546
764
|
|
|
547
765
|
```typescript
|
|
548
766
|
import { hubspot, twilio, email, slack } from '@runflow-ai/sdk';
|
|
@@ -552,52 +770,58 @@ const agent = new Agent({
|
|
|
552
770
|
instructions: 'You help customers.',
|
|
553
771
|
model: openai('gpt-4o'),
|
|
554
772
|
tools: {
|
|
773
|
+
// Built-in connector shortcuts
|
|
555
774
|
createContact: hubspot.createContact(),
|
|
775
|
+
getContact: hubspot.getContact(),
|
|
776
|
+
createTicket: hubspot.createTicket(),
|
|
556
777
|
sendWhatsApp: twilio.sendWhatsApp(),
|
|
778
|
+
sendSMS: twilio.sendSMS(),
|
|
557
779
|
sendEmail: email.send(),
|
|
558
780
|
sendSlack: slack.sendMessage(),
|
|
559
781
|
},
|
|
560
782
|
});
|
|
561
783
|
```
|
|
562
784
|
|
|
563
|
-
####
|
|
785
|
+
#### Parameter Types
|
|
564
786
|
|
|
565
787
|
```typescript
|
|
566
788
|
const tool = createConnectorTool('service', 'resource', 'action', {
|
|
567
|
-
//
|
|
789
|
+
// Basic types
|
|
568
790
|
name: 'string',
|
|
569
791
|
age: 'number',
|
|
570
792
|
active: 'boolean',
|
|
571
|
-
|
|
572
|
-
|
|
793
|
+
createdAt: 'date',
|
|
794
|
+
|
|
795
|
+
// Optional (append ?)
|
|
573
796
|
nickname: 'string?',
|
|
574
797
|
score: 'number?',
|
|
575
|
-
|
|
576
|
-
//
|
|
798
|
+
|
|
799
|
+
// Special validations
|
|
577
800
|
email: 'email',
|
|
578
801
|
website: 'url',
|
|
579
|
-
|
|
580
|
-
|
|
802
|
+
|
|
581
803
|
// Enum
|
|
582
804
|
priority: { enum: ['low', 'medium', 'high'] },
|
|
583
|
-
|
|
805
|
+
|
|
584
806
|
// Arrays
|
|
585
807
|
tags: { array: 'string' },
|
|
586
808
|
scores: { array: 'number' },
|
|
587
809
|
});
|
|
588
810
|
```
|
|
589
811
|
|
|
812
|
+
---
|
|
813
|
+
|
|
590
814
|
### Workflows
|
|
591
815
|
|
|
592
|
-
**Workflows**
|
|
816
|
+
**Workflows** orchestrate multiple agents, functions, and connectors in sequence.
|
|
593
817
|
|
|
594
|
-
#### Workflow
|
|
818
|
+
#### Basic Workflow
|
|
595
819
|
|
|
596
820
|
```typescript
|
|
597
821
|
import { createWorkflow, Agent, openai } from '@runflow-ai/sdk';
|
|
598
822
|
import { z } from 'zod';
|
|
599
823
|
|
|
600
|
-
//
|
|
824
|
+
// Define input/output schemas
|
|
601
825
|
const inputSchema = z.object({
|
|
602
826
|
customerEmail: z.string().email(),
|
|
603
827
|
issueDescription: z.string(),
|
|
@@ -609,7 +833,7 @@ const outputSchema = z.object({
|
|
|
609
833
|
emailSent: z.boolean(),
|
|
610
834
|
});
|
|
611
835
|
|
|
612
|
-
//
|
|
836
|
+
// Create agents
|
|
613
837
|
const analyzerAgent = new Agent({
|
|
614
838
|
name: 'Issue Analyzer',
|
|
615
839
|
instructions: 'Analyze customer issues and categorize them.',
|
|
@@ -622,7 +846,7 @@ const responderAgent = new Agent({
|
|
|
622
846
|
model: openai('gpt-4o'),
|
|
623
847
|
});
|
|
624
848
|
|
|
625
|
-
//
|
|
849
|
+
// Create workflow
|
|
626
850
|
const workflow = createWorkflow({
|
|
627
851
|
id: 'support-workflow',
|
|
628
852
|
name: 'Support Ticket Workflow',
|
|
@@ -647,7 +871,7 @@ const workflow = createWorkflow({
|
|
|
647
871
|
})
|
|
648
872
|
.build();
|
|
649
873
|
|
|
650
|
-
//
|
|
874
|
+
// Execute workflow
|
|
651
875
|
const result = await workflow.execute({
|
|
652
876
|
customerEmail: 'customer@example.com',
|
|
653
877
|
issueDescription: 'My order has not arrived',
|
|
@@ -656,7 +880,7 @@ const result = await workflow.execute({
|
|
|
656
880
|
console.log(result);
|
|
657
881
|
```
|
|
658
882
|
|
|
659
|
-
#### Workflow
|
|
883
|
+
#### Workflow with Parallel Steps
|
|
660
884
|
|
|
661
885
|
```typescript
|
|
662
886
|
const workflow = createWorkflow({
|
|
@@ -669,7 +893,7 @@ const workflow = createWorkflow({
|
|
|
669
893
|
createAgentStep('agent2', agent2),
|
|
670
894
|
createAgentStep('agent3', agent3),
|
|
671
895
|
], {
|
|
672
|
-
waitForAll: true, //
|
|
896
|
+
waitForAll: true, // Wait for all to complete
|
|
673
897
|
})
|
|
674
898
|
.function('merge', async (input, context) => {
|
|
675
899
|
// Merge results
|
|
@@ -680,7 +904,7 @@ const workflow = createWorkflow({
|
|
|
680
904
|
.build();
|
|
681
905
|
```
|
|
682
906
|
|
|
683
|
-
#### Workflow
|
|
907
|
+
#### Workflow with Conditional Steps
|
|
684
908
|
|
|
685
909
|
```typescript
|
|
686
910
|
const workflow = createWorkflow({
|
|
@@ -707,7 +931,7 @@ const workflow = createWorkflow({
|
|
|
707
931
|
.build();
|
|
708
932
|
```
|
|
709
933
|
|
|
710
|
-
#### Workflow
|
|
934
|
+
#### Workflow with Retry
|
|
711
935
|
|
|
712
936
|
```typescript
|
|
713
937
|
const workflow = createWorkflow({
|
|
@@ -726,7 +950,7 @@ const workflow = createWorkflow({
|
|
|
726
950
|
},
|
|
727
951
|
retryConfig: {
|
|
728
952
|
maxAttempts: 3,
|
|
729
|
-
backoff: 'exponential',
|
|
953
|
+
backoff: 'exponential', // 'fixed', 'exponential', 'linear'
|
|
730
954
|
delay: 1000,
|
|
731
955
|
retryableErrors: ['timeout', 'network'],
|
|
732
956
|
},
|
|
@@ -734,11 +958,43 @@ const workflow = createWorkflow({
|
|
|
734
958
|
.build();
|
|
735
959
|
```
|
|
736
960
|
|
|
737
|
-
|
|
961
|
+
#### Workflow Step Types
|
|
962
|
+
|
|
963
|
+
```typescript
|
|
964
|
+
import {
|
|
965
|
+
createAgentStep,
|
|
966
|
+
createFunctionStep,
|
|
967
|
+
createConnectorStep
|
|
968
|
+
} from '@runflow-ai/sdk';
|
|
969
|
+
|
|
970
|
+
// Agent step
|
|
971
|
+
const agentStep = createAgentStep('step-id', agent, {
|
|
972
|
+
promptTemplate: 'Process: {{input.data}}',
|
|
973
|
+
});
|
|
974
|
+
|
|
975
|
+
// Function step
|
|
976
|
+
const functionStep = createFunctionStep('step-id', async (input, context) => {
|
|
977
|
+
// Custom logic
|
|
978
|
+
return { result: 'processed' };
|
|
979
|
+
});
|
|
980
|
+
|
|
981
|
+
// Connector step
|
|
982
|
+
const connectorStep = createConnectorStep(
|
|
983
|
+
'step-id',
|
|
984
|
+
'hubspot',
|
|
985
|
+
'contacts',
|
|
986
|
+
'create',
|
|
987
|
+
{ email: '{{input.email}}' }
|
|
988
|
+
);
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
---
|
|
992
|
+
|
|
993
|
+
### Knowledge (RAG)
|
|
738
994
|
|
|
739
|
-
|
|
995
|
+
The **Knowledge** module (also called RAG) manages semantic search in vector knowledge bases.
|
|
740
996
|
|
|
741
|
-
#### Knowledge
|
|
997
|
+
#### Standalone Knowledge Manager
|
|
742
998
|
|
|
743
999
|
```typescript
|
|
744
1000
|
import { Knowledge } from '@runflow-ai/sdk';
|
|
@@ -749,7 +1005,7 @@ const knowledge = new Knowledge({
|
|
|
749
1005
|
threshold: 0.7,
|
|
750
1006
|
});
|
|
751
1007
|
|
|
752
|
-
//
|
|
1008
|
+
// Basic search
|
|
753
1009
|
const results = await knowledge.search('How to reset password?');
|
|
754
1010
|
|
|
755
1011
|
results.forEach(result => {
|
|
@@ -757,7 +1013,7 @@ results.forEach(result => {
|
|
|
757
1013
|
console.log('Score:', result.score);
|
|
758
1014
|
});
|
|
759
1015
|
|
|
760
|
-
// Get context
|
|
1016
|
+
// Get formatted context for LLM
|
|
761
1017
|
const context = await knowledge.getContext('password reset', { k: 3 });
|
|
762
1018
|
console.log(context);
|
|
763
1019
|
```
|
|
@@ -788,7 +1044,9 @@ const results = await knowledge.multiQuery(
|
|
|
788
1044
|
);
|
|
789
1045
|
```
|
|
790
1046
|
|
|
791
|
-
####
|
|
1047
|
+
#### Agentic RAG in Agent
|
|
1048
|
+
|
|
1049
|
+
When RAG is configured in an agent, the SDK automatically creates a `searchKnowledge` tool that the LLM can decide when to use. This is more efficient than always searching, as the LLM only searches when necessary.
|
|
792
1050
|
|
|
793
1051
|
```typescript
|
|
794
1052
|
const agent = new Agent({
|
|
@@ -799,49 +1057,80 @@ const agent = new Agent({
|
|
|
799
1057
|
vectorStore: 'support-docs',
|
|
800
1058
|
k: 5,
|
|
801
1059
|
threshold: 0.7,
|
|
802
|
-
|
|
803
|
-
//
|
|
1060
|
+
|
|
1061
|
+
// Custom search prompt - guides when to search
|
|
804
1062
|
searchPrompt: `Use searchKnowledge tool when user asks about:
|
|
805
1063
|
- Technical problems
|
|
806
1064
|
- Process questions
|
|
807
1065
|
- Specific information
|
|
808
1066
|
|
|
809
1067
|
Don't use for greetings or casual chat.`,
|
|
810
|
-
|
|
1068
|
+
|
|
811
1069
|
toolDescription: 'Search in support documentation for solutions',
|
|
812
1070
|
},
|
|
813
1071
|
});
|
|
814
1072
|
|
|
815
|
-
// Agent
|
|
816
|
-
// LLM
|
|
1073
|
+
// Agent automatically has 'searchKnowledge' tool
|
|
1074
|
+
// LLM decides when to search (not always - more efficient!)
|
|
817
1075
|
const result = await agent.process({
|
|
818
1076
|
message: 'How do I reset my password?',
|
|
819
|
-
companyId: 'company_123',
|
|
820
1077
|
});
|
|
821
1078
|
```
|
|
822
1079
|
|
|
1080
|
+
#### Multiple Vector Stores
|
|
1081
|
+
|
|
1082
|
+
```typescript
|
|
1083
|
+
const agent = new Agent({
|
|
1084
|
+
name: 'Advanced Support Agent',
|
|
1085
|
+
instructions: 'Help users with multiple knowledge bases.',
|
|
1086
|
+
model: openai('gpt-4o'),
|
|
1087
|
+
rag: {
|
|
1088
|
+
vectorStores: [
|
|
1089
|
+
{
|
|
1090
|
+
id: 'support-docs',
|
|
1091
|
+
name: 'Support Documentation',
|
|
1092
|
+
description: 'General support articles',
|
|
1093
|
+
threshold: 0.7,
|
|
1094
|
+
k: 5,
|
|
1095
|
+
searchPrompt: 'Use search_support-docs when user has technical problems or questions',
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
id: 'api-docs',
|
|
1099
|
+
name: 'API Documentation',
|
|
1100
|
+
description: 'Technical API reference',
|
|
1101
|
+
threshold: 0.8,
|
|
1102
|
+
k: 3,
|
|
1103
|
+
searchPrompt: 'Use search_api-docs when user asks about API endpoints or integration',
|
|
1104
|
+
},
|
|
1105
|
+
],
|
|
1106
|
+
},
|
|
1107
|
+
});
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
---
|
|
1111
|
+
|
|
823
1112
|
### LLM Standalone
|
|
824
1113
|
|
|
825
|
-
|
|
1114
|
+
The **LLM** module allows you to use language models directly without creating agents.
|
|
826
1115
|
|
|
827
|
-
####
|
|
1116
|
+
#### Basic Usage
|
|
828
1117
|
|
|
829
1118
|
```typescript
|
|
830
1119
|
import { LLM } from '@runflow-ai/sdk';
|
|
831
1120
|
|
|
832
|
-
//
|
|
1121
|
+
// Create LLM
|
|
833
1122
|
const llm = LLM.openai('gpt-4o', {
|
|
834
1123
|
temperature: 0.7,
|
|
835
1124
|
maxTokens: 2000,
|
|
836
1125
|
});
|
|
837
1126
|
|
|
838
|
-
//
|
|
1127
|
+
// Generate response
|
|
839
1128
|
const response = await llm.generate('What is the capital of Brazil?');
|
|
840
1129
|
console.log(response.text);
|
|
841
1130
|
console.log('Tokens:', response.usage);
|
|
842
1131
|
```
|
|
843
1132
|
|
|
844
|
-
####
|
|
1133
|
+
#### With Messages
|
|
845
1134
|
|
|
846
1135
|
```typescript
|
|
847
1136
|
const response = await llm.generate([
|
|
@@ -850,7 +1139,7 @@ const response = await llm.generate([
|
|
|
850
1139
|
]);
|
|
851
1140
|
```
|
|
852
1141
|
|
|
853
|
-
####
|
|
1142
|
+
#### With System Prompt
|
|
854
1143
|
|
|
855
1144
|
```typescript
|
|
856
1145
|
const response = await llm.generate(
|
|
@@ -882,7 +1171,7 @@ import { LLM } from '@runflow-ai/sdk';
|
|
|
882
1171
|
// OpenAI
|
|
883
1172
|
const gpt4 = LLM.openai('gpt-4o', { temperature: 0.7 });
|
|
884
1173
|
|
|
885
|
-
// Anthropic
|
|
1174
|
+
// Anthropic (Claude)
|
|
886
1175
|
const claude = LLM.anthropic('claude-3-5-sonnet-20241022', {
|
|
887
1176
|
temperature: 0.9,
|
|
888
1177
|
maxTokens: 4000,
|
|
@@ -894,39 +1183,42 @@ const bedrock = LLM.bedrock('anthropic.claude-3-sonnet-20240229-v1:0', {
|
|
|
894
1183
|
});
|
|
895
1184
|
```
|
|
896
1185
|
|
|
1186
|
+
---
|
|
1187
|
+
|
|
897
1188
|
### Observability
|
|
898
1189
|
|
|
899
|
-
|
|
1190
|
+
The **Observability** system automatically collects execution traces for analysis and debugging.
|
|
900
1191
|
|
|
901
|
-
####
|
|
1192
|
+
#### Automatic Tracing (Agent)
|
|
902
1193
|
|
|
903
1194
|
```typescript
|
|
904
|
-
// Traces
|
|
1195
|
+
// Traces are collected automatically
|
|
905
1196
|
const agent = new Agent({
|
|
906
1197
|
name: 'Support Agent',
|
|
907
1198
|
instructions: 'Help customers.',
|
|
908
1199
|
model: openai('gpt-4o'),
|
|
909
1200
|
});
|
|
910
1201
|
|
|
911
|
-
//
|
|
1202
|
+
// Each execution automatically generates traces
|
|
912
1203
|
await agent.process({
|
|
913
1204
|
message: 'Help me',
|
|
914
|
-
companyId: 'company_123',
|
|
915
|
-
sessionId: 'session_456',
|
|
916
|
-
executionId: 'exec_123',
|
|
917
|
-
threadId: 'thread_789',
|
|
1205
|
+
companyId: 'company_123', // Optional
|
|
1206
|
+
sessionId: 'session_456', // Optional
|
|
1207
|
+
executionId: 'exec_123', // Optional
|
|
1208
|
+
threadId: 'thread_789', // Optional
|
|
918
1209
|
});
|
|
919
1210
|
```
|
|
920
1211
|
|
|
921
|
-
####
|
|
1212
|
+
#### Manual Tracing
|
|
922
1213
|
|
|
923
1214
|
```typescript
|
|
924
1215
|
import { createTraceCollector } from '@runflow-ai/sdk';
|
|
925
1216
|
|
|
926
|
-
//
|
|
1217
|
+
// Create collector
|
|
927
1218
|
const collector = createTraceCollector(apiClient, 'project_123', {
|
|
928
1219
|
batchSize: 10,
|
|
929
1220
|
flushInterval: 5000,
|
|
1221
|
+
maxRetries: 3,
|
|
930
1222
|
});
|
|
931
1223
|
|
|
932
1224
|
// Start span
|
|
@@ -938,14 +1230,18 @@ const span = collector.startSpan('custom_operation', {
|
|
|
938
1230
|
span.setInput({ data: 'input' });
|
|
939
1231
|
|
|
940
1232
|
try {
|
|
941
|
-
//
|
|
1233
|
+
// Execute operation
|
|
942
1234
|
const result = await doSomething();
|
|
943
|
-
|
|
1235
|
+
|
|
944
1236
|
span.setOutput(result);
|
|
945
1237
|
span.setCosts({
|
|
946
1238
|
tokens: { input: 100, output: 50, total: 150 },
|
|
947
|
-
costs: {
|
|
948
|
-
|
|
1239
|
+
costs: {
|
|
1240
|
+
inputCost: 0.003,
|
|
1241
|
+
outputCost: 0.002,
|
|
1242
|
+
totalCost: 0.005,
|
|
1243
|
+
currency: 'USD'
|
|
1244
|
+
},
|
|
949
1245
|
});
|
|
950
1246
|
} catch (error) {
|
|
951
1247
|
span.setError(error);
|
|
@@ -953,172 +1249,51 @@ try {
|
|
|
953
1249
|
|
|
954
1250
|
span.finish();
|
|
955
1251
|
|
|
956
|
-
//
|
|
1252
|
+
// Force flush
|
|
957
1253
|
await collector.flush();
|
|
958
1254
|
```
|
|
959
1255
|
|
|
960
|
-
#### Decorator
|
|
1256
|
+
#### Decorator for Auto-Tracing
|
|
961
1257
|
|
|
962
1258
|
```typescript
|
|
963
1259
|
import { traced } from '@runflow-ai/sdk';
|
|
964
1260
|
|
|
965
1261
|
class MyService {
|
|
966
1262
|
private traceCollector: TraceCollector;
|
|
967
|
-
|
|
1263
|
+
|
|
968
1264
|
@traced('my_operation', { agentName: 'My Agent' })
|
|
969
1265
|
async myMethod(input: any) {
|
|
970
|
-
//
|
|
1266
|
+
// Automatically traced
|
|
971
1267
|
return processData(input);
|
|
972
1268
|
}
|
|
973
1269
|
}
|
|
974
1270
|
```
|
|
975
1271
|
|
|
976
|
-
#### Traces
|
|
977
|
-
|
|
978
|
-
```typescript
|
|
979
|
-
// .env
|
|
980
|
-
RUNFLOW_LOCAL_TRACES=true
|
|
981
|
-
|
|
982
|
-
// Traces serão salvos em .runflow/traces.json
|
|
983
|
-
// Formato estruturado por executionId para análise
|
|
984
|
-
```
|
|
985
|
-
|
|
986
|
-
---
|
|
987
|
-
|
|
988
|
-
## 🏗️ Arquitetura
|
|
989
|
-
|
|
990
|
-
### Estrutura do SDK
|
|
991
|
-
|
|
992
|
-
```
|
|
993
|
-
@runflow-ai/sdk/
|
|
994
|
-
├── core/ # Núcleo do SDK
|
|
995
|
-
│ ├── agent.ts # Classe Agent principal
|
|
996
|
-
│ ├── api-client.ts # Cliente da API Runflow
|
|
997
|
-
│ ├── context.ts # Runflow singleton (context management)
|
|
998
|
-
│ └── models.ts # Model providers (openai, anthropic, bedrock)
|
|
999
|
-
│
|
|
1000
|
-
├── tools/ # Sistema de Tools
|
|
1001
|
-
│ └── tool-creator.ts # Factory para criar tools
|
|
1002
|
-
│
|
|
1003
|
-
├── connectors/ # Sistema de Connectors
|
|
1004
|
-
│ ├── connector-creator.ts
|
|
1005
|
-
│ └── built-in/ # HubSpot, Twilio, Email, Slack
|
|
1006
|
-
│
|
|
1007
|
-
├── workflows/ # Sistema de Workflows
|
|
1008
|
-
│ └── workflow.ts # Workflow engine + builder
|
|
1009
|
-
│
|
|
1010
|
-
├── memory/ # Sistema de Memory
|
|
1011
|
-
│ └── memory-manager.ts
|
|
1012
|
-
│
|
|
1013
|
-
├── knowledge/ # Sistema de RAG
|
|
1014
|
-
│ └── knowledge-manager.ts
|
|
1015
|
-
│
|
|
1016
|
-
├── llm/ # LLM Standalone
|
|
1017
|
-
│ └── llm-manager.ts
|
|
1018
|
-
│
|
|
1019
|
-
├── observability/ # Sistema de Traces
|
|
1020
|
-
│ └── trace-collector.ts
|
|
1021
|
-
│
|
|
1022
|
-
├── providers/ # Provider interfaces
|
|
1023
|
-
│ ├── types.ts # MemoryProvider, KnowledgeProvider, LLMProvider
|
|
1024
|
-
│ └── runflow/ # Implementações padrão
|
|
1025
|
-
│
|
|
1026
|
-
└── types/ # TypeScript types
|
|
1027
|
-
└── all-types.ts # Todos os tipos do SDK
|
|
1028
|
-
```
|
|
1029
|
-
|
|
1030
|
-
### Fluxo de Execução
|
|
1031
|
-
|
|
1032
|
-
```
|
|
1033
|
-
1. Developer cria Agent/Workflow
|
|
1034
|
-
2. SDK configura API Client (auto ou injetado)
|
|
1035
|
-
3. Agent.process() é chamado
|
|
1036
|
-
4. Context é resolvido (Runflow.identify() ou input direto)
|
|
1037
|
-
5. Memory é carregada (se configurado)
|
|
1038
|
-
6. RAG busca contexto (se configurado)
|
|
1039
|
-
7. LLM é chamado com prompt + context
|
|
1040
|
-
8. Tools são executadas (se chamadas)
|
|
1041
|
-
9. Response é gerada
|
|
1042
|
-
10. Memory é salva (se configurado)
|
|
1043
|
-
11. Traces são coletados (automático)
|
|
1044
|
-
12. Output é retornado
|
|
1045
|
-
```
|
|
1046
|
-
|
|
1047
|
-
### Multi-Agent Pattern
|
|
1048
|
-
|
|
1049
|
-
```typescript
|
|
1050
|
-
// Supervisor Pattern (automático)
|
|
1051
|
-
const agent = new Agent({
|
|
1052
|
-
name: 'Supervisor',
|
|
1053
|
-
instructions: 'Route tasks to appropriate agents.',
|
|
1054
|
-
model: openai('gpt-4o'),
|
|
1055
|
-
agents: {
|
|
1056
|
-
support: {
|
|
1057
|
-
name: 'Support Agent',
|
|
1058
|
-
instructions: 'Handle support requests.',
|
|
1059
|
-
model: openai('gpt-4o-mini'),
|
|
1060
|
-
},
|
|
1061
|
-
sales: {
|
|
1062
|
-
name: 'Sales Agent',
|
|
1063
|
-
instructions: 'Handle sales inquiries.',
|
|
1064
|
-
model: openai('gpt-4o-mini'),
|
|
1065
|
-
},
|
|
1066
|
-
},
|
|
1067
|
-
});
|
|
1068
|
-
|
|
1069
|
-
// Supervisor decide automaticamente qual agent usar
|
|
1070
|
-
await agent.process({
|
|
1071
|
-
message: 'I want to buy your product',
|
|
1072
|
-
companyId: 'company_123',
|
|
1073
|
-
});
|
|
1074
|
-
```
|
|
1075
|
-
|
|
1076
|
-
---
|
|
1077
|
-
|
|
1078
|
-
## 🔧 Configuração
|
|
1079
|
-
|
|
1080
|
-
### Variáveis de Ambiente
|
|
1272
|
+
#### Local Traces (Development)
|
|
1081
1273
|
|
|
1082
1274
|
```bash
|
|
1083
|
-
#
|
|
1084
|
-
RUNFLOW_API_URL=http://localhost:3001
|
|
1085
|
-
RUNFLOW_API_KEY=your_api_key_here
|
|
1086
|
-
RUNFLOW_TENANT_ID=your_tenant_id
|
|
1087
|
-
RUNFLOW_AGENT_ID=your_agent_id
|
|
1088
|
-
|
|
1089
|
-
# Execution Context (opcional - geralmente vem da engine)
|
|
1090
|
-
RUNFLOW_EXECUTION_ID=exec_123
|
|
1091
|
-
RUNFLOW_THREAD_ID=thread_456
|
|
1092
|
-
RUNFLOW_TENANT_ID=company_123
|
|
1093
|
-
|
|
1094
|
-
# Development
|
|
1095
|
-
RUNFLOW_ENV=development
|
|
1275
|
+
# .env
|
|
1096
1276
|
RUNFLOW_LOCAL_TRACES=true
|
|
1097
1277
|
```
|
|
1098
1278
|
|
|
1099
|
-
|
|
1279
|
+
Traces will be saved to `.runflow/traces.json` in a structured format organized by `executionId` for analysis.
|
|
1100
1280
|
|
|
1101
|
-
|
|
1102
|
-
{
|
|
1103
|
-
"agentId": "your_agent_id",
|
|
1104
|
-
"tenantId": "your_tenant_id",
|
|
1105
|
-
"apiKey": "your_api_key",
|
|
1106
|
-
"apiUrl": "http://localhost:3001"
|
|
1107
|
-
}
|
|
1108
|
-
```
|
|
1281
|
+
#### Trace Types
|
|
1109
1282
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1283
|
+
The SDK supports various trace types:
|
|
1284
|
+
- `agent_execution` - Full agent processing
|
|
1285
|
+
- `workflow_execution` - Workflow processing
|
|
1286
|
+
- `workflow_step` - Individual workflow step
|
|
1287
|
+
- `tool_call` - Tool execution
|
|
1288
|
+
- `llm_call` - LLM API call
|
|
1289
|
+
- `vector_search` - Vector search operation
|
|
1290
|
+
- `memory_operation` - Memory access
|
|
1291
|
+
- `connector_call` - Connector execution
|
|
1292
|
+
- `streaming_session` - Streaming response
|
|
1118
1293
|
|
|
1119
1294
|
---
|
|
1120
1295
|
|
|
1121
|
-
##
|
|
1296
|
+
## 🏗️ Advanced Examples
|
|
1122
1297
|
|
|
1123
1298
|
### Multi-Modal (Images)
|
|
1124
1299
|
|
|
@@ -1131,7 +1306,6 @@ const agent = new Agent({
|
|
|
1131
1306
|
|
|
1132
1307
|
await agent.process({
|
|
1133
1308
|
message: 'What is in this image?',
|
|
1134
|
-
companyId: 'company_123',
|
|
1135
1309
|
messages: [
|
|
1136
1310
|
{
|
|
1137
1311
|
role: 'user',
|
|
@@ -1147,7 +1321,7 @@ await agent.process({
|
|
|
1147
1321
|
});
|
|
1148
1322
|
```
|
|
1149
1323
|
|
|
1150
|
-
### Streaming
|
|
1324
|
+
### Streaming with Memory
|
|
1151
1325
|
|
|
1152
1326
|
```typescript
|
|
1153
1327
|
const agent = new Agent({
|
|
@@ -1155,7 +1329,6 @@ const agent = new Agent({
|
|
|
1155
1329
|
instructions: 'You are helpful.',
|
|
1156
1330
|
model: openai('gpt-4o'),
|
|
1157
1331
|
memory: {
|
|
1158
|
-
type: 'conversation',
|
|
1159
1332
|
maxTurns: 10,
|
|
1160
1333
|
},
|
|
1161
1334
|
streaming: {
|
|
@@ -1165,7 +1338,6 @@ const agent = new Agent({
|
|
|
1165
1338
|
|
|
1166
1339
|
const stream = await agent.processStream({
|
|
1167
1340
|
message: 'Tell me a story',
|
|
1168
|
-
companyId: 'company_123',
|
|
1169
1341
|
sessionId: 'session_123',
|
|
1170
1342
|
});
|
|
1171
1343
|
|
|
@@ -1183,26 +1355,33 @@ import { Memory, MemoryProvider } from '@runflow-ai/sdk';
|
|
|
1183
1355
|
|
|
1184
1356
|
class RedisMemoryProvider implements MemoryProvider {
|
|
1185
1357
|
async get(key: string): Promise<MemoryData> {
|
|
1186
|
-
// Implementar com Redis
|
|
1187
1358
|
const data = await redis.get(key);
|
|
1188
1359
|
return JSON.parse(data);
|
|
1189
1360
|
}
|
|
1190
|
-
|
|
1361
|
+
|
|
1191
1362
|
async set(key: string, data: MemoryData): Promise<void> {
|
|
1192
1363
|
await redis.set(key, JSON.stringify(data));
|
|
1193
1364
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1365
|
+
|
|
1366
|
+
async append(key: string, message: MemoryMessage): Promise<void> {
|
|
1367
|
+
const data = await this.get(key);
|
|
1368
|
+
data.messages.push(message);
|
|
1369
|
+
await this.set(key, data);
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
async clear(key: string): Promise<void> {
|
|
1373
|
+
await redis.del(key);
|
|
1374
|
+
}
|
|
1196
1375
|
}
|
|
1197
1376
|
|
|
1198
|
-
//
|
|
1377
|
+
// Use custom provider
|
|
1199
1378
|
const memory = new Memory({
|
|
1200
1379
|
provider: new RedisMemoryProvider(),
|
|
1201
1380
|
maxTurns: 10,
|
|
1202
1381
|
});
|
|
1203
1382
|
```
|
|
1204
1383
|
|
|
1205
|
-
### Complex Workflow
|
|
1384
|
+
### Complex E-Commerce Workflow
|
|
1206
1385
|
|
|
1207
1386
|
```typescript
|
|
1208
1387
|
const workflow = createWorkflow({
|
|
@@ -1217,7 +1396,7 @@ const workflow = createWorkflow({
|
|
|
1217
1396
|
.agent('analyzer', analyzerAgent, {
|
|
1218
1397
|
promptTemplate: 'Analyze customer query: {{input.query}}',
|
|
1219
1398
|
})
|
|
1220
|
-
|
|
1399
|
+
|
|
1221
1400
|
// 2. Load customer data in parallel
|
|
1222
1401
|
.parallel([
|
|
1223
1402
|
createFunctionStep('load-profile', async (input, ctx) => {
|
|
@@ -1230,7 +1409,7 @@ const workflow = createWorkflow({
|
|
|
1230
1409
|
return await searchProducts(ctx.stepResults.get('analyzer').text);
|
|
1231
1410
|
}),
|
|
1232
1411
|
])
|
|
1233
|
-
|
|
1412
|
+
|
|
1234
1413
|
// 3. Conditional: Sales vs Support
|
|
1235
1414
|
.condition(
|
|
1236
1415
|
'route',
|
|
@@ -1251,7 +1430,7 @@ const workflow = createWorkflow({
|
|
|
1251
1430
|
}),
|
|
1252
1431
|
]
|
|
1253
1432
|
)
|
|
1254
|
-
|
|
1433
|
+
|
|
1255
1434
|
// 4. Send response
|
|
1256
1435
|
.agent('responder', responderAgent, {
|
|
1257
1436
|
promptTemplate: 'Create final response based on context',
|
|
@@ -1266,50 +1445,658 @@ const result = await workflow.execute({
|
|
|
1266
1445
|
|
|
1267
1446
|
---
|
|
1268
1447
|
|
|
1269
|
-
##
|
|
1448
|
+
## 💡 Real-World Use Cases
|
|
1449
|
+
|
|
1450
|
+
Complete, production-ready examples showcasing the platform's potential.
|
|
1270
1451
|
|
|
1271
|
-
###
|
|
1452
|
+
### 1. Customer Support Agent with RAG
|
|
1453
|
+
|
|
1454
|
+
A sophisticated support agent that searches documentation, remembers context, and creates tickets in HubSpot.
|
|
1272
1455
|
|
|
1273
1456
|
```typescript
|
|
1274
|
-
|
|
1275
|
-
|
|
1457
|
+
import { Agent, openai, createTool } from '@runflow-ai/sdk';
|
|
1458
|
+
import { hubspotConnector } from '@runflow-ai/sdk/connectors';
|
|
1459
|
+
import { z } from 'zod';
|
|
1276
1460
|
|
|
1277
|
-
//
|
|
1278
|
-
|
|
1279
|
-
|
|
1461
|
+
// Create a support agent with memory and RAG
|
|
1462
|
+
const supportAgent = new Agent({
|
|
1463
|
+
name: 'Customer Support AI',
|
|
1464
|
+
instructions: `You are a helpful customer support agent.
|
|
1465
|
+
- Search the knowledge base for relevant information
|
|
1466
|
+
- Remember previous conversations
|
|
1467
|
+
- Create tickets for complex issues
|
|
1468
|
+
- Always be professional and empathetic`,
|
|
1280
1469
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1470
|
+
model: openai('gpt-4o'),
|
|
1471
|
+
|
|
1472
|
+
// Remember conversation history
|
|
1473
|
+
memory: {
|
|
1474
|
+
maxTurns: 20,
|
|
1475
|
+
summarizeAfter: 10,
|
|
1476
|
+
summarizePrompt: 'Summarize key customer issues and resolutions',
|
|
1477
|
+
},
|
|
1478
|
+
|
|
1479
|
+
// Search in documentation
|
|
1480
|
+
knowledge: {
|
|
1481
|
+
vectorStore: 'support-docs',
|
|
1482
|
+
k: 5,
|
|
1483
|
+
threshold: 0.7,
|
|
1484
|
+
},
|
|
1485
|
+
|
|
1486
|
+
// Available tools
|
|
1487
|
+
tools: {
|
|
1488
|
+
createTicket: hubspotConnector.tickets.create,
|
|
1489
|
+
searchOrders: createTool({
|
|
1490
|
+
id: 'search-orders',
|
|
1491
|
+
description: 'Search customer orders',
|
|
1492
|
+
inputSchema: z.object({
|
|
1493
|
+
customerId: z.string(),
|
|
1494
|
+
}),
|
|
1495
|
+
execute: async ({ context }) => {
|
|
1496
|
+
const orders = await fetchOrders(context.input.customerId);
|
|
1497
|
+
return { orders };
|
|
1498
|
+
},
|
|
1499
|
+
}),
|
|
1500
|
+
},
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
// Handle customer message
|
|
1504
|
+
const result = await supportAgent.process({
|
|
1505
|
+
message: 'My order #12345 has not arrived yet',
|
|
1506
|
+
sessionId: 'session_xyz', // For conversation history
|
|
1507
|
+
userId: 'user_123', // For user identification
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
console.log(result.message);
|
|
1511
|
+
// Agent searches docs, retrieves order info, and provides solution
|
|
1512
|
+
```
|
|
1513
|
+
|
|
1514
|
+
### 2. Sales Automation with Multi-Step Workflow
|
|
1515
|
+
|
|
1516
|
+
Automate lead qualification, deal creation, and team notifications using workflows.
|
|
1517
|
+
|
|
1518
|
+
```typescript
|
|
1519
|
+
import { createWorkflow, Agent, openai } from '@runflow-ai/sdk';
|
|
1520
|
+
import { hubspotConnector, slackConnector } from '@runflow-ai/sdk/connectors';
|
|
1521
|
+
import { z } from 'zod';
|
|
1522
|
+
|
|
1523
|
+
// Qualification agent
|
|
1524
|
+
const qualifierAgent = new Agent({
|
|
1525
|
+
name: 'Lead Qualifier',
|
|
1526
|
+
instructions: 'Analyze lead data and assign a score (1-10) with reasoning.',
|
|
1527
|
+
model: openai('gpt-4o-mini'),
|
|
1528
|
+
});
|
|
1529
|
+
|
|
1530
|
+
// Sales copy agent
|
|
1531
|
+
const copywriterAgent = new Agent({
|
|
1532
|
+
name: 'Sales Copywriter',
|
|
1533
|
+
instructions: 'Write a personalized email for the lead based on their profile.',
|
|
1534
|
+
model: openai('gpt-4o'),
|
|
1535
|
+
});
|
|
1536
|
+
|
|
1537
|
+
// Complete workflow
|
|
1538
|
+
const salesWorkflow = createWorkflow({
|
|
1539
|
+
id: 'lead-to-deal',
|
|
1540
|
+
inputSchema: z.object({
|
|
1541
|
+
leadEmail: z.string().email(),
|
|
1542
|
+
leadName: z.string(),
|
|
1543
|
+
company: z.string(),
|
|
1544
|
+
notes: z.string(),
|
|
1545
|
+
}),
|
|
1546
|
+
outputSchema: z.any(),
|
|
1547
|
+
})
|
|
1548
|
+
// Step 1: Qualify the lead
|
|
1549
|
+
.agent('qualify', qualifierAgent, {
|
|
1550
|
+
promptTemplate: `Analyze this lead:
|
|
1551
|
+
Name: {{input.leadName}}
|
|
1552
|
+
Company: {{input.company}}
|
|
1553
|
+
Notes: {{input.notes}}
|
|
1554
|
+
|
|
1555
|
+
Provide score (1-10) and reasoning.`,
|
|
1556
|
+
})
|
|
1557
|
+
|
|
1558
|
+
// Step 2: Conditional - Only proceed if score >= 7
|
|
1559
|
+
.condition(
|
|
1560
|
+
'check-score',
|
|
1561
|
+
(ctx) => {
|
|
1562
|
+
const score = parseInt(ctx.stepResults.get('qualify').text.match(/\d+/)?.[0] || '0');
|
|
1563
|
+
return score >= 7;
|
|
1564
|
+
},
|
|
1565
|
+
// High quality lead path
|
|
1566
|
+
[
|
|
1567
|
+
// Create contact in HubSpot
|
|
1568
|
+
{
|
|
1569
|
+
id: 'create-contact',
|
|
1570
|
+
type: 'connector',
|
|
1571
|
+
config: {
|
|
1572
|
+
connector: 'hubspot',
|
|
1573
|
+
resource: 'contacts',
|
|
1574
|
+
action: 'create',
|
|
1575
|
+
parameters: {
|
|
1576
|
+
email: '{{input.leadEmail}}',
|
|
1577
|
+
firstname: '{{input.leadName}}',
|
|
1578
|
+
company: '{{input.company}}',
|
|
1579
|
+
lifecyclestage: 'lead',
|
|
1580
|
+
},
|
|
1581
|
+
},
|
|
1582
|
+
},
|
|
1583
|
+
|
|
1584
|
+
// Create deal
|
|
1585
|
+
{
|
|
1586
|
+
id: 'create-deal',
|
|
1587
|
+
type: 'connector',
|
|
1588
|
+
config: {
|
|
1589
|
+
connector: 'hubspot',
|
|
1590
|
+
resource: 'deals',
|
|
1591
|
+
action: 'create',
|
|
1592
|
+
parameters: {
|
|
1593
|
+
dealname: 'Deal - {{input.company}}',
|
|
1594
|
+
amount: 5000,
|
|
1595
|
+
dealstage: 'qualifiedtobuy',
|
|
1596
|
+
pipeline: 'default',
|
|
1597
|
+
hubspot_owner_id: '12345',
|
|
1598
|
+
},
|
|
1599
|
+
},
|
|
1600
|
+
},
|
|
1601
|
+
|
|
1602
|
+
// Generate personalized email
|
|
1603
|
+
{
|
|
1604
|
+
id: 'write-email',
|
|
1605
|
+
type: 'agent',
|
|
1606
|
+
config: {
|
|
1607
|
+
agent: copywriterAgent,
|
|
1608
|
+
promptTemplate: `Write a personalized sales email for:
|
|
1609
|
+
Name: {{input.leadName}}
|
|
1610
|
+
Company: {{input.company}}
|
|
1611
|
+
Qualification: {{qualify.text}}`,
|
|
1612
|
+
},
|
|
1613
|
+
},
|
|
1614
|
+
|
|
1615
|
+
// Notify sales team on Slack
|
|
1616
|
+
{
|
|
1617
|
+
id: 'notify-team',
|
|
1618
|
+
type: 'connector',
|
|
1619
|
+
config: {
|
|
1620
|
+
connector: 'slack',
|
|
1621
|
+
resource: 'messages',
|
|
1622
|
+
action: 'send',
|
|
1623
|
+
parameters: {
|
|
1624
|
+
channel: '#sales',
|
|
1625
|
+
text: `🎯 New qualified lead: *{{input.leadName}}* from *{{input.company}}*\nScore: High\nDeal created: {{create-deal.id}}`,
|
|
1626
|
+
},
|
|
1627
|
+
},
|
|
1628
|
+
},
|
|
1629
|
+
],
|
|
1630
|
+
// Low quality lead path
|
|
1631
|
+
[
|
|
1632
|
+
{
|
|
1633
|
+
id: 'log-rejected',
|
|
1634
|
+
type: 'function',
|
|
1635
|
+
config: {
|
|
1636
|
+
execute: async (input, ctx) => {
|
|
1637
|
+
console.log(`Lead ${input.leadName} rejected - Low score`);
|
|
1638
|
+
return { rejected: true };
|
|
1639
|
+
},
|
|
1640
|
+
},
|
|
1641
|
+
},
|
|
1642
|
+
]
|
|
1643
|
+
)
|
|
1644
|
+
.build();
|
|
1645
|
+
|
|
1646
|
+
// Execute workflow
|
|
1647
|
+
const result = await salesWorkflow.execute({
|
|
1648
|
+
leadEmail: 'john@techcorp.com',
|
|
1649
|
+
leadName: 'John Smith',
|
|
1650
|
+
company: 'TechCorp Inc',
|
|
1651
|
+
notes: 'Interested in enterprise plan. Budget: $10k/month. Timeline: Q1 2025.',
|
|
1652
|
+
});
|
|
1653
|
+
|
|
1654
|
+
console.log('Workflow completed:', result);
|
|
1655
|
+
```
|
|
1656
|
+
|
|
1657
|
+
### 3. Intelligent Collections Agent (WhatsApp)
|
|
1658
|
+
|
|
1659
|
+
Automate debt collection with personalized WhatsApp messages using context-aware AI.
|
|
1660
|
+
|
|
1661
|
+
```typescript
|
|
1662
|
+
import { Agent, openai, Runflow } from '@runflow-ai/sdk';
|
|
1663
|
+
import { twilioConnector } from '@runflow-ai/sdk/connectors';
|
|
1664
|
+
import { z } from 'zod';
|
|
1665
|
+
|
|
1666
|
+
// Collections agent with empathy and context
|
|
1667
|
+
const collectionsAgent = new Agent({
|
|
1668
|
+
name: 'Collections AI',
|
|
1669
|
+
instructions: `You are an empathetic debt collection agent.
|
|
1670
|
+
- Analyze customer history and payment patterns
|
|
1671
|
+
- Create personalized, respectful messages
|
|
1672
|
+
- Offer payment plan options
|
|
1673
|
+
- Never be aggressive or rude`,
|
|
1674
|
+
|
|
1675
|
+
model: openai('gpt-4o'),
|
|
1676
|
+
|
|
1677
|
+
memory: {
|
|
1678
|
+
maxTurns: 10,
|
|
1679
|
+
},
|
|
1680
|
+
|
|
1681
|
+
tools: {
|
|
1682
|
+
sendWhatsApp: twilioConnector.whatsapp.send,
|
|
1683
|
+
getPaymentHistory: createTool({
|
|
1684
|
+
id: 'get-payment-history',
|
|
1685
|
+
description: 'Get customer payment history',
|
|
1686
|
+
inputSchema: z.object({
|
|
1687
|
+
customerId: z.string(),
|
|
1688
|
+
}),
|
|
1689
|
+
execute: async ({ context }) => {
|
|
1690
|
+
const history = await fetchPaymentHistory(context.input.customerId);
|
|
1691
|
+
return { history };
|
|
1692
|
+
},
|
|
1693
|
+
}),
|
|
1694
|
+
},
|
|
1695
|
+
});
|
|
1696
|
+
|
|
1697
|
+
// Process overdue invoice
|
|
1698
|
+
async function processOverdueInvoice(invoice: any) {
|
|
1699
|
+
// Set customer context
|
|
1700
|
+
Runflow.identify({
|
|
1701
|
+
type: 'customer',
|
|
1702
|
+
value: invoice.customerId,
|
|
1703
|
+
userId: invoice.customerId,
|
|
1704
|
+
});
|
|
1705
|
+
|
|
1706
|
+
const result = await collectionsAgent.process({
|
|
1707
|
+
message: `Create a personalized WhatsApp message for customer ${invoice.customerName}.
|
|
1708
|
+
Invoice: ${invoice.id}
|
|
1709
|
+
Amount: $${invoice.amount}
|
|
1710
|
+
Days overdue: ${invoice.daysOverdue}
|
|
1711
|
+
Previous payment history: Check using the tool.
|
|
1712
|
+
|
|
1713
|
+
If history is good, offer a payment plan. Send via WhatsApp.`,
|
|
1714
|
+
sessionId: `collection_${invoice.id}`,
|
|
1715
|
+
});
|
|
1716
|
+
|
|
1717
|
+
console.log('Collection message sent:', result);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
// Batch process overdue invoices
|
|
1721
|
+
const overdueInvoices = await fetchOverdueInvoices();
|
|
1722
|
+
for (const invoice of overdueInvoices) {
|
|
1723
|
+
await processOverdueInvoice(invoice);
|
|
1724
|
+
}
|
|
1725
|
+
```
|
|
1726
|
+
|
|
1727
|
+
### 4. Customer Onboarding Assistant
|
|
1728
|
+
|
|
1729
|
+
Guide new users through onboarding with an interactive, multi-turn conversation.
|
|
1730
|
+
|
|
1731
|
+
```typescript
|
|
1732
|
+
import { Agent, openai } from '@runflow-ai/sdk';
|
|
1733
|
+
import { emailConnector, slackConnector } from '@runflow-ai/sdk/connectors';
|
|
1734
|
+
|
|
1735
|
+
const onboardingAgent = new Agent({
|
|
1736
|
+
name: 'Onboarding Assistant',
|
|
1737
|
+
instructions: `You are an onboarding specialist.
|
|
1738
|
+
- Guide users step by step
|
|
1739
|
+
- Celebrate their progress
|
|
1740
|
+
- Provide helpful resources
|
|
1741
|
+
- Detect when they're stuck and offer help
|
|
1742
|
+
- Track completion of onboarding steps`,
|
|
1743
|
+
|
|
1744
|
+
model: openai('gpt-4o'),
|
|
1745
|
+
|
|
1746
|
+
memory: {
|
|
1747
|
+
maxTurns: 50, // Long conversation
|
|
1748
|
+
summarizeAfter: 20,
|
|
1749
|
+
summarizePrompt: 'Summarize onboarding progress, completed steps, and next actions',
|
|
1750
|
+
},
|
|
1751
|
+
|
|
1752
|
+
knowledge: {
|
|
1753
|
+
vectorStore: 'onboarding-docs',
|
|
1754
|
+
k: 3,
|
|
1755
|
+
},
|
|
1756
|
+
|
|
1757
|
+
tools: {
|
|
1758
|
+
sendEmail: emailConnector.messages.send,
|
|
1759
|
+
notifyTeam: slackConnector.messages.send,
|
|
1760
|
+
markStepComplete: createTool({
|
|
1761
|
+
id: 'mark-step-complete',
|
|
1762
|
+
description: 'Mark an onboarding step as complete',
|
|
1763
|
+
inputSchema: z.object({
|
|
1764
|
+
stepName: z.string(),
|
|
1765
|
+
userId: z.string(),
|
|
1766
|
+
}),
|
|
1767
|
+
execute: async ({ context }) => {
|
|
1768
|
+
await updateOnboardingProgress(
|
|
1769
|
+
context.input.userId,
|
|
1770
|
+
context.input.stepName
|
|
1771
|
+
);
|
|
1772
|
+
return { success: true };
|
|
1773
|
+
},
|
|
1774
|
+
}),
|
|
1775
|
+
},
|
|
1776
|
+
});
|
|
1777
|
+
|
|
1778
|
+
// Interactive onboarding session
|
|
1779
|
+
const sessionId = `onboarding_user_${userId}`;
|
|
1780
|
+
|
|
1781
|
+
// Step 1
|
|
1782
|
+
await onboardingAgent.process({
|
|
1783
|
+
message: 'Start onboarding for new user',
|
|
1784
|
+
sessionId,
|
|
1785
|
+
userId,
|
|
1786
|
+
});
|
|
1787
|
+
|
|
1788
|
+
// User responds
|
|
1789
|
+
await onboardingAgent.process({
|
|
1790
|
+
message: 'I want to create my first agent',
|
|
1791
|
+
sessionId,
|
|
1792
|
+
userId,
|
|
1793
|
+
});
|
|
1794
|
+
|
|
1795
|
+
// Agent guides through agent creation...
|
|
1796
|
+
```
|
|
1797
|
+
|
|
1798
|
+
### 5. Feedback Analysis System
|
|
1799
|
+
|
|
1800
|
+
Collect customer feedback, analyze sentiment, and create actionable tickets.
|
|
1801
|
+
|
|
1802
|
+
```typescript
|
|
1803
|
+
import { createWorkflow, Agent, openai } from '@runflow-ai/sdk';
|
|
1804
|
+
import { hubspotConnector, slackConnector } from '@runflow-ai/sdk/connectors';
|
|
1805
|
+
import { z } from 'zod';
|
|
1806
|
+
|
|
1807
|
+
// Sentiment analyzer
|
|
1808
|
+
const sentimentAgent = new Agent({
|
|
1809
|
+
name: 'Sentiment Analyzer',
|
|
1810
|
+
instructions: 'Analyze feedback sentiment (positive/neutral/negative) and extract key themes.',
|
|
1811
|
+
model: openai('gpt-4o-mini'),
|
|
1812
|
+
});
|
|
1813
|
+
|
|
1814
|
+
// Action recommender
|
|
1815
|
+
const actionAgent = new Agent({
|
|
1816
|
+
name: 'Action Recommender',
|
|
1817
|
+
instructions: 'Recommend specific actions based on feedback analysis.',
|
|
1818
|
+
model: openai('gpt-4o'),
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1821
|
+
const feedbackWorkflow = createWorkflow({
|
|
1822
|
+
id: 'feedback-analysis',
|
|
1823
|
+
inputSchema: z.object({
|
|
1824
|
+
feedback: z.string(),
|
|
1825
|
+
customerEmail: z.string(),
|
|
1826
|
+
customerName: z.string(),
|
|
1827
|
+
source: z.string(),
|
|
1828
|
+
}),
|
|
1829
|
+
outputSchema: z.any(),
|
|
1830
|
+
})
|
|
1831
|
+
// Analyze sentiment
|
|
1832
|
+
.agent('analyze', sentimentAgent, {
|
|
1833
|
+
promptTemplate: 'Analyze: {{input.feedback}}',
|
|
1834
|
+
})
|
|
1835
|
+
|
|
1836
|
+
// Recommend actions
|
|
1837
|
+
.agent('recommend', actionAgent, {
|
|
1838
|
+
promptTemplate: `Feedback: {{input.feedback}}
|
|
1839
|
+
Sentiment: {{analyze.text}}
|
|
1840
|
+
|
|
1841
|
+
What actions should we take?`,
|
|
1842
|
+
})
|
|
1843
|
+
|
|
1844
|
+
// Conditional: Create ticket if negative
|
|
1845
|
+
.condition(
|
|
1846
|
+
'check-negative',
|
|
1847
|
+
(ctx) => ctx.stepResults.get('analyze').text.toLowerCase().includes('negative'),
|
|
1848
|
+
// Negative feedback path
|
|
1849
|
+
[
|
|
1850
|
+
{
|
|
1851
|
+
id: 'create-ticket',
|
|
1852
|
+
type: 'connector',
|
|
1853
|
+
config: {
|
|
1854
|
+
connector: 'hubspot',
|
|
1855
|
+
resource: 'tickets',
|
|
1856
|
+
action: 'create',
|
|
1857
|
+
parameters: {
|
|
1858
|
+
subject: 'Negative Feedback - {{input.customerName}}',
|
|
1859
|
+
content: '{{input.feedback}}\n\nAnalysis: {{analyze.text}}\n\nRecommended actions: {{recommend.text}}',
|
|
1860
|
+
priority: 'high',
|
|
1861
|
+
category: 'feedback',
|
|
1862
|
+
},
|
|
1863
|
+
},
|
|
1864
|
+
},
|
|
1865
|
+
{
|
|
1866
|
+
id: 'alert-team',
|
|
1867
|
+
type: 'connector',
|
|
1868
|
+
config: {
|
|
1869
|
+
connector: 'slack',
|
|
1870
|
+
resource: 'messages',
|
|
1871
|
+
action: 'send',
|
|
1872
|
+
parameters: {
|
|
1873
|
+
channel: '#customer-success',
|
|
1874
|
+
text: `⚠️ Negative feedback from *{{input.customerName}}*\nTicket created: {{create-ticket.id}}`,
|
|
1875
|
+
},
|
|
1876
|
+
},
|
|
1877
|
+
},
|
|
1878
|
+
],
|
|
1879
|
+
// Positive/neutral feedback path
|
|
1880
|
+
[
|
|
1881
|
+
{
|
|
1882
|
+
id: 'log-positive',
|
|
1883
|
+
type: 'function',
|
|
1884
|
+
config: {
|
|
1885
|
+
execute: async (input, ctx) => {
|
|
1886
|
+
console.log('Positive feedback logged');
|
|
1887
|
+
return { logged: true };
|
|
1888
|
+
},
|
|
1889
|
+
},
|
|
1890
|
+
},
|
|
1891
|
+
]
|
|
1892
|
+
)
|
|
1893
|
+
.build();
|
|
1894
|
+
|
|
1895
|
+
// Process feedback
|
|
1896
|
+
const result = await feedbackWorkflow.execute({
|
|
1897
|
+
feedback: 'The support team was unhelpful and the product is buggy',
|
|
1898
|
+
customerEmail: 'unhappy@customer.com',
|
|
1899
|
+
customerName: 'Jane Doe',
|
|
1900
|
+
source: 'email',
|
|
1901
|
+
});
|
|
1902
|
+
```
|
|
1903
|
+
|
|
1904
|
+
### 6. Multi-Agent System (Supervisor Pattern)
|
|
1905
|
+
|
|
1906
|
+
Route requests to specialized agents based on intent.
|
|
1907
|
+
|
|
1908
|
+
```typescript
|
|
1909
|
+
import { Agent, openai } from '@runflow-ai/sdk';
|
|
1910
|
+
|
|
1911
|
+
// Specialized agents
|
|
1912
|
+
const salesAgent = new Agent({
|
|
1913
|
+
name: 'Sales Specialist',
|
|
1914
|
+
instructions: 'You are a sales expert. Help with pricing, demos, and purchasing.',
|
|
1915
|
+
model: openai('gpt-4o'),
|
|
1916
|
+
tools: { /* sales tools */ },
|
|
1917
|
+
});
|
|
1918
|
+
|
|
1919
|
+
const supportAgent = new Agent({
|
|
1920
|
+
name: 'Technical Support',
|
|
1921
|
+
instructions: 'You are a technical support expert. Help with technical issues.',
|
|
1922
|
+
model: openai('gpt-4o'),
|
|
1923
|
+
knowledge: { vectorStore: 'tech-docs', k: 5 },
|
|
1924
|
+
});
|
|
1925
|
+
|
|
1926
|
+
const billingAgent = new Agent({
|
|
1927
|
+
name: 'Billing Specialist',
|
|
1928
|
+
instructions: 'You handle billing, invoices, and payment issues.',
|
|
1929
|
+
model: openai('gpt-4o'),
|
|
1930
|
+
tools: { /* billing tools */ },
|
|
1931
|
+
});
|
|
1932
|
+
|
|
1933
|
+
// Supervisor agent
|
|
1934
|
+
const supervisorAgent = new Agent({
|
|
1935
|
+
name: 'Supervisor',
|
|
1936
|
+
instructions: `You route customer requests to the right specialist:
|
|
1937
|
+
- Sales: pricing, demos, purchasing
|
|
1938
|
+
- Support: technical issues, bugs
|
|
1939
|
+
- Billing: invoices, payments, subscriptions
|
|
1940
|
+
|
|
1941
|
+
Analyze the request and respond with: ROUTE_TO: [sales|support|billing]`,
|
|
1942
|
+
model: openai('gpt-4o-mini'),
|
|
1943
|
+
});
|
|
1944
|
+
|
|
1945
|
+
// Routing function
|
|
1946
|
+
async function handleCustomerRequest(message: string, context: any) {
|
|
1947
|
+
// 1. Supervisor analyzes intent
|
|
1948
|
+
const routing = await supervisorAgent.process({
|
|
1949
|
+
message: `Analyze this request: "${message}"`,
|
|
1950
|
+
...context,
|
|
1951
|
+
});
|
|
1952
|
+
|
|
1953
|
+
// 2. Extract route
|
|
1954
|
+
const route = routing.message.match(/ROUTE_TO: (\w+)/)?.[1] || 'support';
|
|
1955
|
+
|
|
1956
|
+
// 3. Route to specialist
|
|
1957
|
+
const agents = {
|
|
1958
|
+
sales: salesAgent,
|
|
1959
|
+
support: supportAgent,
|
|
1960
|
+
billing: billingAgent,
|
|
1961
|
+
};
|
|
1962
|
+
|
|
1963
|
+
const specialistAgent = agents[route];
|
|
1964
|
+
|
|
1965
|
+
// 4. Specialist handles request
|
|
1966
|
+
const result = await specialistAgent.process({
|
|
1967
|
+
message,
|
|
1968
|
+
...context,
|
|
1969
|
+
});
|
|
1970
|
+
|
|
1971
|
+
return {
|
|
1972
|
+
route,
|
|
1973
|
+
response: result.message,
|
|
1974
|
+
};
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// Example usage
|
|
1978
|
+
const result = await handleCustomerRequest(
|
|
1979
|
+
'I want to upgrade to the enterprise plan',
|
|
1980
|
+
{
|
|
1981
|
+
sessionId: 'session_456',
|
|
1982
|
+
userId: 'user_789',
|
|
1983
|
+
}
|
|
1984
|
+
);
|
|
1985
|
+
|
|
1986
|
+
console.log(`Routed to: ${result.route}`);
|
|
1987
|
+
console.log(`Response: ${result.response}`);
|
|
1988
|
+
```
|
|
1989
|
+
|
|
1990
|
+
---
|
|
1991
|
+
|
|
1992
|
+
## 🔧 Configuration
|
|
1993
|
+
|
|
1994
|
+
### Environment Variables
|
|
1995
|
+
|
|
1996
|
+
```bash
|
|
1997
|
+
# API Configuration
|
|
1998
|
+
RUNFLOW_API_URL=http://localhost:3001
|
|
1999
|
+
RUNFLOW_API_KEY=your_api_key_here
|
|
2000
|
+
RUNFLOW_TENANT_ID=your_tenant_id
|
|
2001
|
+
RUNFLOW_AGENT_ID=your_agent_id
|
|
2002
|
+
|
|
2003
|
+
# Execution Context (optional - usually comes from engine)
|
|
2004
|
+
RUNFLOW_EXECUTION_ID=exec_123
|
|
2005
|
+
RUNFLOW_THREAD_ID=thread_456
|
|
2006
|
+
|
|
2007
|
+
# Development
|
|
2008
|
+
RUNFLOW_ENV=development
|
|
2009
|
+
RUNFLOW_LOCAL_TRACES=true
|
|
2010
|
+
NODE_ENV=development
|
|
2011
|
+
```
|
|
2012
|
+
|
|
2013
|
+
### Configuration File (.runflow/rf.json)
|
|
2014
|
+
|
|
2015
|
+
```json
|
|
2016
|
+
{
|
|
2017
|
+
"agentId": "your_agent_id",
|
|
2018
|
+
"tenantId": "your_tenant_id",
|
|
2019
|
+
"apiKey": "your_api_key",
|
|
2020
|
+
"apiUrl": "http://localhost:3001"
|
|
2021
|
+
}
|
|
2022
|
+
```
|
|
2023
|
+
|
|
2024
|
+
The SDK automatically searches for `.runflow/rf.json` in the current directory and parent directories.
|
|
2025
|
+
|
|
2026
|
+
**Configuration Priority:**
|
|
2027
|
+
|
|
2028
|
+
1. Explicit config in code
|
|
2029
|
+
2. `.runflow/rf.json`
|
|
2030
|
+
3. Environment variables
|
|
2031
|
+
4. Defaults
|
|
2032
|
+
|
|
2033
|
+
### Manual API Client Configuration
|
|
2034
|
+
|
|
2035
|
+
```typescript
|
|
2036
|
+
import { createRunflowAPIClient, Agent, openai } from '@runflow-ai/sdk';
|
|
2037
|
+
|
|
2038
|
+
const apiClient = createRunflowAPIClient({
|
|
2039
|
+
apiUrl: 'https://api.runflow.ai',
|
|
2040
|
+
apiKey: 'your_api_key',
|
|
2041
|
+
tenantId: 'your_tenant_id',
|
|
2042
|
+
agentId: 'your_agent_id',
|
|
2043
|
+
});
|
|
2044
|
+
|
|
2045
|
+
// Inject into agent
|
|
2046
|
+
const agent = new Agent({
|
|
2047
|
+
name: 'My Agent',
|
|
2048
|
+
instructions: 'Help users',
|
|
2049
|
+
model: openai('gpt-4o'),
|
|
2050
|
+
});
|
|
2051
|
+
|
|
2052
|
+
agent._setAPIClient(apiClient);
|
|
2053
|
+
```
|
|
2054
|
+
|
|
2055
|
+
---
|
|
2056
|
+
|
|
2057
|
+
## 📖 API Reference
|
|
2058
|
+
|
|
2059
|
+
### Main Exports
|
|
2060
|
+
|
|
2061
|
+
```typescript
|
|
2062
|
+
// Core
|
|
2063
|
+
import { Agent, Runflow, openai, anthropic, bedrock } from '@runflow-ai/sdk';
|
|
2064
|
+
|
|
2065
|
+
// Tools & Connectors
|
|
2066
|
+
import { createTool, createConnectorTool } from '@runflow-ai/sdk';
|
|
2067
|
+
import { hubspot, twilio, email, slack } from '@runflow-ai/sdk';
|
|
2068
|
+
|
|
2069
|
+
// Workflows
|
|
2070
|
+
import {
|
|
2071
|
+
Workflow,
|
|
2072
|
+
createWorkflow,
|
|
2073
|
+
createStep,
|
|
2074
|
+
createAgentStep,
|
|
2075
|
+
createFunctionStep,
|
|
1288
2076
|
createConnectorStep,
|
|
2077
|
+
WorkflowBuilder,
|
|
1289
2078
|
} from '@runflow-ai/sdk';
|
|
1290
2079
|
|
|
1291
2080
|
// Standalone Modules
|
|
1292
|
-
|
|
2081
|
+
import { Memory, Knowledge, RAG, LLM } from '@runflow-ai/sdk';
|
|
1293
2082
|
|
|
1294
2083
|
// Observability
|
|
1295
|
-
|
|
1296
|
-
createTraceCollector,
|
|
1297
|
-
RunflowTraceCollector,
|
|
1298
|
-
|
|
2084
|
+
import {
|
|
2085
|
+
createTraceCollector,
|
|
2086
|
+
RunflowTraceCollector,
|
|
2087
|
+
RunflowTraceSpan,
|
|
2088
|
+
traced
|
|
1299
2089
|
} from '@runflow-ai/sdk';
|
|
1300
2090
|
|
|
1301
|
-
//
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
MemoryConfig,
|
|
1311
|
-
TraceData,
|
|
1312
|
-
// ... etc
|
|
2091
|
+
// API Client
|
|
2092
|
+
import { createRunflowAPIClient } from '@runflow-ai/sdk';
|
|
2093
|
+
|
|
2094
|
+
// Providers
|
|
2095
|
+
import {
|
|
2096
|
+
MemoryProvider,
|
|
2097
|
+
KnowledgeProvider,
|
|
2098
|
+
LLMProvider,
|
|
2099
|
+
RunflowMemoryProvider,
|
|
1313
2100
|
} from '@runflow-ai/sdk';
|
|
1314
2101
|
```
|
|
1315
2102
|
|
|
@@ -1318,18 +2105,17 @@ export type {
|
|
|
1318
2105
|
```typescript
|
|
1319
2106
|
// Core
|
|
1320
2107
|
import { Agent } from '@runflow-ai/sdk/core';
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
import { openai, anthropic, bedrock } from '@runflow-ai/sdk/models';
|
|
2108
|
+
import { Runflow } from '@runflow-ai/sdk/core';
|
|
2109
|
+
import { openai, anthropic, bedrock } from '@runflow-ai/sdk/core';
|
|
1324
2110
|
|
|
1325
2111
|
// Tools
|
|
1326
2112
|
import { createTool } from '@runflow-ai/sdk/tools';
|
|
1327
2113
|
|
|
1328
2114
|
// Connectors
|
|
1329
|
-
import { createConnectorTool, hubspot } from '@runflow-ai/sdk/connectors';
|
|
2115
|
+
import { createConnectorTool, hubspot, twilio, email, slack } from '@runflow-ai/sdk/connectors';
|
|
1330
2116
|
|
|
1331
2117
|
// Workflows
|
|
1332
|
-
import { createWorkflow } from '@runflow-ai/sdk/workflows';
|
|
2118
|
+
import { createWorkflow, WorkflowBuilder } from '@runflow-ai/sdk/workflows';
|
|
1333
2119
|
|
|
1334
2120
|
// Memory
|
|
1335
2121
|
import { Memory } from '@runflow-ai/sdk/memory';
|
|
@@ -1341,22 +2127,261 @@ import { Knowledge, RAG } from '@runflow-ai/sdk/knowledge';
|
|
|
1341
2127
|
import { LLM } from '@runflow-ai/sdk/llm';
|
|
1342
2128
|
|
|
1343
2129
|
// Observability
|
|
1344
|
-
import { createTraceCollector } from '@runflow-ai/sdk/observability';
|
|
2130
|
+
import { createTraceCollector, traced } from '@runflow-ai/sdk/observability';
|
|
1345
2131
|
|
|
1346
2132
|
// Types
|
|
1347
|
-
import type { AgentConfig } from '@runflow-ai/sdk/types';
|
|
2133
|
+
import type { AgentConfig, AgentInput, AgentOutput } from '@runflow-ai/sdk/types';
|
|
1348
2134
|
|
|
1349
2135
|
// Providers
|
|
1350
|
-
import type { MemoryProvider } from '@runflow-ai/sdk/providers';
|
|
2136
|
+
import type { MemoryProvider, KnowledgeProvider, LLMProvider } from '@runflow-ai/sdk/providers';
|
|
2137
|
+
```
|
|
2138
|
+
|
|
2139
|
+
---
|
|
2140
|
+
|
|
2141
|
+
## 📝 TypeScript Types
|
|
2142
|
+
|
|
2143
|
+
### Core Types
|
|
2144
|
+
|
|
2145
|
+
```typescript
|
|
2146
|
+
interface AgentInput {
|
|
2147
|
+
message: string;
|
|
2148
|
+
companyId: string;
|
|
2149
|
+
userId?: string;
|
|
2150
|
+
sessionId?: string;
|
|
2151
|
+
executionId?: string;
|
|
2152
|
+
threadId?: string;
|
|
2153
|
+
entityType?: string;
|
|
2154
|
+
entityValue?: string;
|
|
2155
|
+
channel?: string;
|
|
2156
|
+
messages?: Message[];
|
|
2157
|
+
metadata?: Record<string, any>;
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
interface AgentOutput {
|
|
2161
|
+
message: string;
|
|
2162
|
+
metadata?: Record<string, any>;
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
interface AgentConfig {
|
|
2166
|
+
name: string;
|
|
2167
|
+
instructions: string;
|
|
2168
|
+
model: ModelProvider;
|
|
2169
|
+
modelConfig?: ModelConfig;
|
|
2170
|
+
tools?: Record<string, RunflowTool>;
|
|
2171
|
+
maxToolIterations?: number;
|
|
2172
|
+
rag?: RAGConfig;
|
|
2173
|
+
memory?: MemoryConfig;
|
|
2174
|
+
streaming?: StreamingConfig;
|
|
2175
|
+
agents?: Record<string, AgentConfig>;
|
|
2176
|
+
debug?: boolean | DebugConfig;
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
interface ModelConfig {
|
|
2180
|
+
temperature?: number;
|
|
2181
|
+
maxTokens?: number;
|
|
2182
|
+
topP?: number;
|
|
2183
|
+
frequencyPenalty?: number;
|
|
2184
|
+
presencePenalty?: number;
|
|
2185
|
+
stop?: string[];
|
|
2186
|
+
seed?: number;
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
interface DebugConfig {
|
|
2190
|
+
enabled: boolean;
|
|
2191
|
+
logMessages?: boolean;
|
|
2192
|
+
logLLMCalls?: boolean;
|
|
2193
|
+
logToolCalls?: boolean;
|
|
2194
|
+
logRAG?: boolean;
|
|
2195
|
+
logMemory?: boolean;
|
|
2196
|
+
truncateAt?: number;
|
|
2197
|
+
}
|
|
2198
|
+
```
|
|
2199
|
+
|
|
2200
|
+
### Memory Types
|
|
2201
|
+
|
|
2202
|
+
```typescript
|
|
2203
|
+
interface MemoryConfig {
|
|
2204
|
+
type?: 'conversation' | 'entity' | 'summary' | 'hybrid'; // Optional - reserved for future
|
|
2205
|
+
maxTurns?: number; // Max conversation turns to keep
|
|
2206
|
+
maxTokens?: number; // Max tokens to keep
|
|
2207
|
+
summarizeAfter?: number; // Trigger summary after N turns
|
|
2208
|
+
summarizePrompt?: string; // Custom prompt for summarization
|
|
2209
|
+
summarizeModel?: ModelProvider; // Custom model for summarization (e.g., gpt-4o-mini)
|
|
2210
|
+
memoryKey?: string; // Custom memory key
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
interface MemoryData {
|
|
2214
|
+
sessionId: string;
|
|
2215
|
+
messages: MemoryMessage[];
|
|
2216
|
+
entities: Record<string, any>;
|
|
2217
|
+
summary?: string;
|
|
2218
|
+
metadata: {
|
|
2219
|
+
createdAt: Date;
|
|
2220
|
+
updatedAt: Date;
|
|
2221
|
+
totalTurns: number;
|
|
2222
|
+
totalTokens: number;
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
interface MemoryMessage {
|
|
2227
|
+
role: 'user' | 'assistant' | 'system';
|
|
2228
|
+
content: string;
|
|
2229
|
+
timestamp: Date;
|
|
2230
|
+
metadata?: {
|
|
2231
|
+
toolsUsed?: string[];
|
|
2232
|
+
ragUsed?: boolean;
|
|
2233
|
+
model?: string;
|
|
2234
|
+
tokens?: number;
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
```
|
|
2238
|
+
|
|
2239
|
+
### RAG Types
|
|
2240
|
+
|
|
2241
|
+
```typescript
|
|
2242
|
+
interface RAGConfig {
|
|
2243
|
+
vectorStore?: string;
|
|
2244
|
+
vectorStores?: Array<{
|
|
2245
|
+
id: string;
|
|
2246
|
+
name: string;
|
|
2247
|
+
threshold?: number;
|
|
2248
|
+
k?: number;
|
|
2249
|
+
description?: string;
|
|
2250
|
+
searchPrompt?: string; // Individual guidance for this KB
|
|
2251
|
+
}>;
|
|
2252
|
+
threshold?: number;
|
|
2253
|
+
k?: number;
|
|
2254
|
+
searchPrompt?: string; // Global search guidance
|
|
2255
|
+
toolDescription?: string;
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
interface SearchResult {
|
|
2259
|
+
content: string;
|
|
2260
|
+
score: number;
|
|
2261
|
+
metadata?: Record<string, any>;
|
|
2262
|
+
}
|
|
2263
|
+
```
|
|
2264
|
+
|
|
2265
|
+
### Tool Types
|
|
2266
|
+
|
|
2267
|
+
```typescript
|
|
2268
|
+
interface ToolConfig<TInput = any, TOutput = any> {
|
|
2269
|
+
id: string;
|
|
2270
|
+
description: string;
|
|
2271
|
+
inputSchema: z.ZodSchema<TInput>;
|
|
2272
|
+
outputSchema?: z.ZodSchema<TOutput>;
|
|
2273
|
+
execute: (params: {
|
|
2274
|
+
context: TInput;
|
|
2275
|
+
runflow: RunflowAPIClient;
|
|
2276
|
+
projectId: string;
|
|
2277
|
+
}) => Promise<TOutput>;
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
interface RunflowTool {
|
|
2281
|
+
id: string;
|
|
2282
|
+
name?: string;
|
|
2283
|
+
description: string;
|
|
2284
|
+
parameters: Record<string, ToolParameter>;
|
|
2285
|
+
execute: (params: any, context: ToolContext) => Promise<any>;
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
interface ToolContext {
|
|
2289
|
+
projectId: string;
|
|
2290
|
+
companyId: string;
|
|
2291
|
+
userId?: string;
|
|
2292
|
+
sessionId?: string;
|
|
2293
|
+
runflowAPI: RunflowAPIClient;
|
|
2294
|
+
}
|
|
2295
|
+
```
|
|
2296
|
+
|
|
2297
|
+
### Workflow Types
|
|
2298
|
+
|
|
2299
|
+
```typescript
|
|
2300
|
+
interface WorkflowConfig {
|
|
2301
|
+
id: string;
|
|
2302
|
+
name?: string;
|
|
2303
|
+
description?: string;
|
|
2304
|
+
inputSchema: z.ZodSchema;
|
|
2305
|
+
outputSchema: z.ZodSchema;
|
|
2306
|
+
steps: WorkflowStep[];
|
|
2307
|
+
options?: WorkflowOptions;
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
interface WorkflowStep {
|
|
2311
|
+
id: string;
|
|
2312
|
+
name?: string;
|
|
2313
|
+
description?: string;
|
|
2314
|
+
type: 'agent' | 'function' | 'connector' | 'condition' | 'parallel';
|
|
2315
|
+
config: StepConfig;
|
|
2316
|
+
inputTransform?: (previousOutput: any, workflowInput: any) => any;
|
|
2317
|
+
outputTransform?: (stepOutput: any) => any;
|
|
2318
|
+
condition?: (context: WorkflowContext) => boolean;
|
|
2319
|
+
retryConfig?: RetryConfig;
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
interface RetryConfig {
|
|
2323
|
+
maxAttempts: number;
|
|
2324
|
+
backoff: 'fixed' | 'exponential' | 'linear';
|
|
2325
|
+
delay: number;
|
|
2326
|
+
retryableErrors?: string[];
|
|
2327
|
+
}
|
|
2328
|
+
```
|
|
2329
|
+
|
|
2330
|
+
### Trace Types
|
|
2331
|
+
|
|
2332
|
+
```typescript
|
|
2333
|
+
interface TraceData {
|
|
2334
|
+
traceId: string;
|
|
2335
|
+
parentTraceId?: string;
|
|
2336
|
+
projectId: string;
|
|
2337
|
+
executionId?: string;
|
|
2338
|
+
threadId?: string;
|
|
2339
|
+
type: TraceType;
|
|
2340
|
+
operation: string;
|
|
2341
|
+
input: any;
|
|
2342
|
+
output?: any;
|
|
2343
|
+
status: 'success' | 'error' | 'timeout' | 'cancelled';
|
|
2344
|
+
error?: string;
|
|
2345
|
+
startTime: Date;
|
|
2346
|
+
endTime?: Date;
|
|
2347
|
+
duration: number;
|
|
2348
|
+
metadata: TraceMetadata;
|
|
2349
|
+
costs?: TraceCosts;
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
type TraceType =
|
|
2353
|
+
| 'agent_execution'
|
|
2354
|
+
| 'workflow_execution'
|
|
2355
|
+
| 'workflow_step'
|
|
2356
|
+
| 'tool_call'
|
|
2357
|
+
| 'connector_call'
|
|
2358
|
+
| 'vector_search'
|
|
2359
|
+
| 'memory_operation'
|
|
2360
|
+
| 'llm_call'
|
|
2361
|
+
| 'streaming_session';
|
|
2362
|
+
|
|
2363
|
+
interface TraceCosts {
|
|
2364
|
+
tokens?: {
|
|
2365
|
+
input: number;
|
|
2366
|
+
output: number;
|
|
2367
|
+
total: number;
|
|
2368
|
+
};
|
|
2369
|
+
costs?: {
|
|
2370
|
+
inputCost: number;
|
|
2371
|
+
outputCost: number;
|
|
2372
|
+
totalCost: number;
|
|
2373
|
+
currency: string;
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
1351
2376
|
```
|
|
1352
2377
|
|
|
1353
2378
|
---
|
|
1354
2379
|
|
|
1355
2380
|
## 🔌 Providers
|
|
1356
2381
|
|
|
1357
|
-
|
|
2382
|
+
The SDK supports **pluggable providers** for memory, knowledge, and LLM.
|
|
1358
2383
|
|
|
1359
|
-
### Memory
|
|
2384
|
+
### Memory Provider Interface
|
|
1360
2385
|
|
|
1361
2386
|
```typescript
|
|
1362
2387
|
interface MemoryProvider {
|
|
@@ -1369,15 +2394,16 @@ interface MemoryProvider {
|
|
|
1369
2394
|
}
|
|
1370
2395
|
```
|
|
1371
2396
|
|
|
1372
|
-
### Knowledge
|
|
2397
|
+
### Knowledge Provider Interface
|
|
1373
2398
|
|
|
1374
2399
|
```typescript
|
|
1375
2400
|
interface KnowledgeProvider {
|
|
1376
2401
|
search(query: string, options: SearchOptions): Promise<SearchResult[]>;
|
|
2402
|
+
embed?(text: string): Promise<number[]>;
|
|
1377
2403
|
}
|
|
1378
2404
|
```
|
|
1379
2405
|
|
|
1380
|
-
### LLM
|
|
2406
|
+
### LLM Provider Interface
|
|
1381
2407
|
|
|
1382
2408
|
```typescript
|
|
1383
2409
|
interface LLMProvider {
|
|
@@ -1386,22 +2412,142 @@ interface LLMProvider {
|
|
|
1386
2412
|
}
|
|
1387
2413
|
```
|
|
1388
2414
|
|
|
2415
|
+
### Built-in Providers
|
|
2416
|
+
|
|
2417
|
+
```typescript
|
|
2418
|
+
import { RunflowMemoryProvider } from '@runflow-ai/sdk';
|
|
2419
|
+
|
|
2420
|
+
// Use Runflow's built-in memory provider
|
|
2421
|
+
const memory = new Memory({
|
|
2422
|
+
provider: new RunflowMemoryProvider(apiClient),
|
|
2423
|
+
maxTurns: 10,
|
|
2424
|
+
});
|
|
2425
|
+
```
|
|
2426
|
+
|
|
1389
2427
|
---
|
|
1390
2428
|
|
|
1391
|
-
##
|
|
2429
|
+
## 🔍 Troubleshooting
|
|
2430
|
+
|
|
2431
|
+
### Common Issues
|
|
2432
|
+
|
|
2433
|
+
#### API Client Not Configured
|
|
1392
2434
|
|
|
1393
|
-
|
|
2435
|
+
```
|
|
2436
|
+
Error: Runflow API Client is not configured
|
|
2437
|
+
```
|
|
2438
|
+
|
|
2439
|
+
**Solution:** Ensure you have either:
|
|
2440
|
+
1. Environment variables set (`RUNFLOW_API_KEY`, `RUNFLOW_TENANT_ID`)
|
|
2441
|
+
2. A `.runflow/rf.json` file
|
|
2442
|
+
3. Manually configured the API client
|
|
2443
|
+
|
|
2444
|
+
```typescript
|
|
2445
|
+
import { createRunflowAPIClient, Agent, openai } from '@runflow-ai/sdk';
|
|
2446
|
+
|
|
2447
|
+
const apiClient = createRunflowAPIClient({
|
|
2448
|
+
apiKey: 'your_api_key',
|
|
2449
|
+
tenantId: 'your_tenant_id',
|
|
2450
|
+
});
|
|
2451
|
+
|
|
2452
|
+
const agent = new Agent({
|
|
2453
|
+
name: 'My Agent',
|
|
2454
|
+
instructions: 'Help users',
|
|
2455
|
+
model: openai('gpt-4o'),
|
|
2456
|
+
});
|
|
1394
2457
|
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
3. Commit suas mudanças (`git commit -m 'Add amazing feature'`)
|
|
1398
|
-
4. Push para a branch (`git push origin feature/amazing-feature`)
|
|
1399
|
-
5. Abra um Pull Request
|
|
2458
|
+
agent._setAPIClient(apiClient);
|
|
2459
|
+
```
|
|
1400
2460
|
|
|
1401
|
-
|
|
2461
|
+
#### Memory Not Persisting
|
|
2462
|
+
|
|
2463
|
+
**Issue:** Memory is not persisting between sessions
|
|
2464
|
+
|
|
2465
|
+
**Solution:** Ensure you're passing the same `sessionId` or using `Runflow.identify()` consistently:
|
|
2466
|
+
|
|
2467
|
+
```typescript
|
|
2468
|
+
// Use Runflow.identify() for automatic session management
|
|
2469
|
+
Runflow.identify({
|
|
2470
|
+
type: 'phone',
|
|
2471
|
+
value: '+5511999999999',
|
|
2472
|
+
});
|
|
2473
|
+
|
|
2474
|
+
// OR pass sessionId explicitly
|
|
2475
|
+
await agent.process({
|
|
2476
|
+
message: 'Hello',
|
|
2477
|
+
sessionId: 'session_456', // Same session ID
|
|
2478
|
+
});
|
|
2479
|
+
```
|
|
2480
|
+
|
|
2481
|
+
#### Tool Not Being Called
|
|
2482
|
+
|
|
2483
|
+
**Issue:** Agent is not calling tools even when it should
|
|
2484
|
+
|
|
2485
|
+
**Solution:**
|
|
2486
|
+
1. Make sure tool descriptions are clear and specific
|
|
2487
|
+
2. Use `debug: true` to see what the agent is doing
|
|
2488
|
+
3. Check that `maxToolIterations` is not set too low
|
|
2489
|
+
|
|
2490
|
+
```typescript
|
|
2491
|
+
const agent = new Agent({
|
|
2492
|
+
name: 'My Agent',
|
|
2493
|
+
instructions: 'You MUST use the weather tool when users ask about weather.',
|
|
2494
|
+
model: openai('gpt-4o'),
|
|
2495
|
+
tools: {
|
|
2496
|
+
weather: weatherTool,
|
|
2497
|
+
},
|
|
2498
|
+
maxToolIterations: 10, // Default
|
|
2499
|
+
debug: true, // Enable debug logging
|
|
2500
|
+
});
|
|
2501
|
+
```
|
|
2502
|
+
|
|
2503
|
+
#### RAG Not Finding Results
|
|
2504
|
+
|
|
2505
|
+
**Issue:** Knowledge base search returns no results
|
|
2506
|
+
|
|
2507
|
+
**Solution:**
|
|
2508
|
+
1. Check `threshold` value (lower = more results)
|
|
2509
|
+
2. Increase `k` value for more results
|
|
2510
|
+
3. Verify vector store name is correct
|
|
2511
|
+
|
|
2512
|
+
```typescript
|
|
2513
|
+
rag: {
|
|
2514
|
+
vectorStore: 'support-docs', // Verify this exists
|
|
2515
|
+
k: 10, // Increase for more results
|
|
2516
|
+
threshold: 0.5, // Lower for more lenient matching
|
|
2517
|
+
}
|
|
2518
|
+
```
|
|
2519
|
+
|
|
2520
|
+
#### TypeScript Errors
|
|
2521
|
+
|
|
2522
|
+
**Issue:** TypeScript errors when using the SDK
|
|
2523
|
+
|
|
2524
|
+
**Solution:** Make sure you're using TypeScript >= 5.0.0 and have proper types:
|
|
1402
2525
|
|
|
1403
2526
|
```bash
|
|
1404
|
-
|
|
2527
|
+
npm install --save-dev typescript@^5.0.0
|
|
2528
|
+
```
|
|
2529
|
+
|
|
2530
|
+
```typescript
|
|
2531
|
+
// Use proper type imports
|
|
2532
|
+
import type { AgentConfig, AgentInput, AgentOutput } from '@runflow-ai/sdk';
|
|
2533
|
+
```
|
|
2534
|
+
|
|
2535
|
+
---
|
|
2536
|
+
|
|
2537
|
+
## 🤝 Contributing
|
|
2538
|
+
|
|
2539
|
+
Contributions are welcome! Please:
|
|
2540
|
+
|
|
2541
|
+
1. Fork the project
|
|
2542
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
2543
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
2544
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
2545
|
+
5. Open a Pull Request
|
|
2546
|
+
|
|
2547
|
+
### Local Development
|
|
2548
|
+
|
|
2549
|
+
```bash
|
|
2550
|
+
# Install dependencies
|
|
1405
2551
|
npm install
|
|
1406
2552
|
|
|
1407
2553
|
# Build
|
|
@@ -1410,32 +2556,32 @@ npm run build
|
|
|
1410
2556
|
# Watch mode
|
|
1411
2557
|
npm run dev
|
|
1412
2558
|
|
|
1413
|
-
#
|
|
2559
|
+
# Tests
|
|
1414
2560
|
npm test
|
|
1415
2561
|
|
|
1416
|
-
#
|
|
2562
|
+
# Validate before publishing
|
|
1417
2563
|
npm run validate
|
|
1418
2564
|
```
|
|
1419
2565
|
|
|
1420
2566
|
---
|
|
1421
2567
|
|
|
1422
|
-
## 📄
|
|
2568
|
+
## 📄 License
|
|
1423
2569
|
|
|
1424
|
-
MIT License -
|
|
2570
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
1425
2571
|
|
|
1426
2572
|
---
|
|
1427
2573
|
|
|
1428
2574
|
## 🔗 Links
|
|
1429
2575
|
|
|
1430
2576
|
- **Homepage**: https://runflow.ai
|
|
1431
|
-
- **
|
|
2577
|
+
- **Documentation**: https://docs.runflow.ai
|
|
1432
2578
|
- **GitHub**: https://github.com/runflow-ai/runflow-sdk
|
|
1433
2579
|
- **NPM**: https://www.npmjs.com/package/@runflow-ai/sdk
|
|
1434
2580
|
- **Discord**: https://discord.gg/runflow
|
|
1435
2581
|
|
|
1436
2582
|
---
|
|
1437
2583
|
|
|
1438
|
-
## 💡
|
|
2584
|
+
## 💡 Support
|
|
1439
2585
|
|
|
1440
2586
|
- 📧 Email: support@runflow.ai
|
|
1441
2587
|
- 💬 Discord: https://discord.gg/runflow
|
|
@@ -1443,5 +2589,4 @@ MIT License - veja [LICENSE](LICENSE) para detalhes.
|
|
|
1443
2589
|
|
|
1444
2590
|
---
|
|
1445
2591
|
|
|
1446
|
-
**
|
|
1447
|
-
|
|
2592
|
+
**Built with ❤️ by the Runflow team**
|