concevent-ai-agent-sdk 1.0.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +516 -2
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +151 -66
- package/dist/core/agent.js.map +1 -1
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +4 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/logger.d.ts +2 -0
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +8 -0
- package/dist/core/logger.js.map +1 -1
- package/dist/core/middleware.d.ts +55 -0
- package/dist/core/middleware.d.ts.map +1 -0
- package/dist/core/middleware.js +125 -0
- package/dist/core/middleware.js.map +1 -0
- package/dist/core/orchestrator.d.ts +31 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +206 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/response-format.d.ts +44 -0
- package/dist/core/response-format.d.ts.map +1 -0
- package/dist/core/response-format.js +107 -0
- package/dist/core/response-format.js.map +1 -0
- package/dist/core/retry.d.ts +76 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/retry.js +164 -0
- package/dist/core/retry.js.map +1 -0
- package/dist/core/summarization.d.ts.map +1 -1
- package/dist/core/summarization.js +21 -3
- package/dist/core/summarization.js.map +1 -1
- package/dist/core/tool-executor.d.ts +6 -5
- package/dist/core/tool-executor.d.ts.map +1 -1
- package/dist/core/tool-executor.js +36 -11
- package/dist/core/tool-executor.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types/config.d.ts +88 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +4 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/events.d.ts +24 -1
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/dist/types/index.d.ts +5 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/middleware.d.ts +115 -0
- package/dist/types/middleware.d.ts.map +1 -0
- package/dist/types/middleware.js +2 -0
- package/dist/types/middleware.js.map +1 -0
- package/dist/types/orchestrator.d.ts +61 -0
- package/dist/types/orchestrator.d.ts.map +1 -0
- package/dist/types/orchestrator.js +2 -0
- package/dist/types/orchestrator.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,9 @@ A framework-agnostic AI Agent SDK for building intelligent conversational agents
|
|
|
13
13
|
- ⛔ **Abort Support** - Cancel ongoing requests with AbortController
|
|
14
14
|
- 🔄 **Retry Logic** - Built-in retry mechanism for resilient operations
|
|
15
15
|
- 📝 **Reasoning Support** - Access model reasoning/thinking outputs
|
|
16
|
+
- 🔌 **Middleware System** - Extensible plugin architecture for logging, sanitization, and more
|
|
17
|
+
- 📋 **Structured Output** - JSON schema validation with Zod for type-safe responses
|
|
18
|
+
- 🎭 **Multi-Agent Orchestration** - Route tasks to specialized sub-agents based on their capabilities
|
|
16
19
|
|
|
17
20
|
## Installation
|
|
18
21
|
|
|
@@ -89,7 +92,11 @@ console.log(result.message);
|
|
|
89
92
|
- [Parallel Tool Execution](#parallel-tool-execution)
|
|
90
93
|
- [Conversation Summarization](#conversation-summarization)
|
|
91
94
|
- [Error Handling](#error-handling)
|
|
95
|
+
- [Retry Configuration](#retry-configuration)
|
|
96
|
+
- [Structured Output](#structured-output)
|
|
92
97
|
- [Abort Requests](#abort-requests)
|
|
98
|
+
- [Middleware](#middleware)
|
|
99
|
+
- [Multi-Agent Orchestration](#multi-agent-orchestration)
|
|
93
100
|
|
|
94
101
|
---
|
|
95
102
|
|
|
@@ -140,6 +147,9 @@ const agent = createAgent(config: AgentConfig): Agent;
|
|
|
140
147
|
| `summarization` | `SummarizationConfig` | ❌ | `{ enabled: true }` | Summarization settings |
|
|
141
148
|
| `parallelToolExecution` | `ParallelExecutionConfig` | ❌ | `{ maxConcurrency: 5 }` | Parallel tool execution settings |
|
|
142
149
|
| `errorMessages` | `ErrorMessages` | ❌ | Default messages | Custom error messages |
|
|
150
|
+
| `retry` | `RetryConfig` | ❌ | `{ maxAttempts: 3 }` | Retry configuration for API failures and validation retries |
|
|
151
|
+
| `responseFormat` | `ResponseFormatConfig` | ❌ | `undefined` (text) | Structured output format (text, json_object, json_schema) |
|
|
152
|
+
| `middleware` | `Middleware[]` | ❌ | `[]` | Middleware array for intercepting agent behavior |
|
|
143
153
|
|
|
144
154
|
#### SummarizationConfig
|
|
145
155
|
|
|
@@ -159,6 +169,31 @@ interface ParallelExecutionConfig {
|
|
|
159
169
|
}
|
|
160
170
|
```
|
|
161
171
|
|
|
172
|
+
#### RetryConfig
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
interface RetryConfig {
|
|
176
|
+
maxAttempts?: number; // Default: 3 - Total attempts including initial (also used for validation retries)
|
|
177
|
+
baseDelayMs?: number; // Default: 1000 - Initial delay before first retry
|
|
178
|
+
maxDelayMs?: number; // Default: 30000 - Maximum delay cap
|
|
179
|
+
backoffMultiplier?: number; // Default: 2 - Exponential backoff multiplier
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### ResponseFormatConfig
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
type ResponseFormatConfig =
|
|
187
|
+
| { type: 'text' } // Default free-form text
|
|
188
|
+
| { type: 'json_object' } // JSON without validation
|
|
189
|
+
| {
|
|
190
|
+
type: 'json_schema';
|
|
191
|
+
schema: ZodType<unknown>; // Zod schema for validation
|
|
192
|
+
name?: string; // Schema name (default: 'response')
|
|
193
|
+
strict?: boolean; // Strict mode (default: true)
|
|
194
|
+
};
|
|
195
|
+
```
|
|
196
|
+
|
|
162
197
|
#### Example with Full Configuration
|
|
163
198
|
|
|
164
199
|
```typescript
|
|
@@ -231,8 +266,9 @@ const result = await agent.chat(
|
|
|
231
266
|
**Returns:** `AgentResult`
|
|
232
267
|
|
|
233
268
|
```typescript
|
|
234
|
-
interface AgentResult {
|
|
269
|
+
interface AgentResult<T = unknown> {
|
|
235
270
|
message: string; // Final response message
|
|
271
|
+
parsedResponse?: T; // Parsed/validated response (when using json_schema)
|
|
236
272
|
reasoning?: {
|
|
237
273
|
// Model's reasoning (if available)
|
|
238
274
|
text?: string;
|
|
@@ -429,6 +465,7 @@ interface AgentCallbacks {
|
|
|
429
465
|
onSummarizationStart?: (originalMessageCount: number) => void;
|
|
430
466
|
onSummarizationEnd?: (summary: string, tokensEstimate: number) => void;
|
|
431
467
|
onIterationStart?: (iteration: number, maxIterations: number) => void;
|
|
468
|
+
onRetry?: (attempt: number, maxAttempts: number, error: Error, delayMs: number) => void;
|
|
432
469
|
onError?: (error: {
|
|
433
470
|
code: string;
|
|
434
471
|
message: string;
|
|
@@ -907,7 +944,7 @@ await agent.chat("Do something", context, {
|
|
|
907
944
|
| ----------------------- | --------------------------- | ----------- |
|
|
908
945
|
| `API_KEY_REQUIRED` | API key not provided | No |
|
|
909
946
|
| `MODEL_REQUIRED` | Model name not provided | No |
|
|
910
|
-
| `EMPTY_RESPONSE` | API returned empty response |
|
|
947
|
+
| `EMPTY_RESPONSE` | API returned empty response | Yes |
|
|
911
948
|
| `REQUEST_ABORTED` | Request was aborted | No |
|
|
912
949
|
| `NO_RESPONSE` | No response from API | No |
|
|
913
950
|
| `NO_RESPONSE_MESSAGE` | Response missing message | No |
|
|
@@ -916,6 +953,181 @@ await agent.chat("Do something", context, {
|
|
|
916
953
|
| `SUMMARIZATION_FAILED` | Summarization failed | Yes |
|
|
917
954
|
| `GENERIC_ERROR` | Unknown error occurred | No |
|
|
918
955
|
|
|
956
|
+
### Retry Configuration
|
|
957
|
+
|
|
958
|
+
The SDK includes automatic retry logic with exponential backoff and jitter for handling transient API failures (e.g., rate limits, network errors).
|
|
959
|
+
|
|
960
|
+
#### Configuration
|
|
961
|
+
|
|
962
|
+
```typescript
|
|
963
|
+
const agent = createAgent({
|
|
964
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
965
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
966
|
+
systemPrompts: ["You are a helpful assistant."],
|
|
967
|
+
tools: [],
|
|
968
|
+
retry: {
|
|
969
|
+
maxAttempts: 5, // Total attempts including initial (default: 3)
|
|
970
|
+
baseDelayMs: 1000, // Initial delay before first retry (default: 1000)
|
|
971
|
+
maxDelayMs: 30000, // Maximum delay cap (default: 30000)
|
|
972
|
+
backoffMultiplier: 2, // Exponential multiplier (default: 2)
|
|
973
|
+
},
|
|
974
|
+
});
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
#### How It Works
|
|
978
|
+
|
|
979
|
+
1. **Exponential Backoff**: Delay doubles with each retry attempt
|
|
980
|
+
2. **Jitter**: Random ±25% variation prevents thundering herd problems
|
|
981
|
+
3. **Retry-After Support**: Honors server-provided `Retry-After` headers
|
|
982
|
+
4. **Abort Integration**: Respects abort signals during retry delays
|
|
983
|
+
|
|
984
|
+
**Delay Calculation:**
|
|
985
|
+
```
|
|
986
|
+
delay = min(baseDelayMs * (backoffMultiplier ^ attempt), maxDelayMs) * jitter
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
For example, with defaults (base=1000ms, multiplier=2, max=30000ms):
|
|
990
|
+
- Retry 1: ~1000ms (±250ms jitter)
|
|
991
|
+
- Retry 2: ~2000ms (±500ms jitter)
|
|
992
|
+
- Retry 3: ~4000ms (±1000ms jitter)
|
|
993
|
+
|
|
994
|
+
#### Retry Callback
|
|
995
|
+
|
|
996
|
+
Monitor retry attempts using the `onRetry` callback:
|
|
997
|
+
|
|
998
|
+
```typescript
|
|
999
|
+
await agent.chat("Hello", context, {
|
|
1000
|
+
onRetry: (attempt, maxAttempts, error, delayMs) => {
|
|
1001
|
+
console.log(`Retry ${attempt}/${maxAttempts} after ${delayMs}ms`);
|
|
1002
|
+
console.log(`Error: ${error.message}`);
|
|
1003
|
+
},
|
|
1004
|
+
});
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
#### Retryable Errors
|
|
1008
|
+
|
|
1009
|
+
The following HTTP status codes trigger automatic retries:
|
|
1010
|
+
- `408` - Request Timeout
|
|
1011
|
+
- `429` - Too Many Requests (Rate Limited)
|
|
1012
|
+
- `500` - Internal Server Error
|
|
1013
|
+
- `502` - Bad Gateway
|
|
1014
|
+
- `503` - Service Unavailable
|
|
1015
|
+
- `504` - Gateway Timeout
|
|
1016
|
+
|
|
1017
|
+
### Structured Output
|
|
1018
|
+
|
|
1019
|
+
The SDK supports structured JSON output with automatic Zod schema validation. This ensures type-safe responses from the AI model.
|
|
1020
|
+
|
|
1021
|
+
#### Response Format Types
|
|
1022
|
+
|
|
1023
|
+
| Type | Description | Validation |
|
|
1024
|
+
|------|-------------|------------|
|
|
1025
|
+
| `text` | Default free-form text response | None |
|
|
1026
|
+
| `json_object` | Forces JSON response | JSON parsing only |
|
|
1027
|
+
| `json_schema` | Forces JSON with schema validation | Zod schema validation |
|
|
1028
|
+
|
|
1029
|
+
#### Basic JSON Mode
|
|
1030
|
+
|
|
1031
|
+
Force the model to return valid JSON without schema validation:
|
|
1032
|
+
|
|
1033
|
+
```typescript
|
|
1034
|
+
const agent = createAgent({
|
|
1035
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
1036
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
1037
|
+
systemPrompts: ["Return responses as JSON objects."],
|
|
1038
|
+
tools: [],
|
|
1039
|
+
responseFormat: { type: "json_object" },
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
const result = await agent.chat("List 3 colors", context);
|
|
1043
|
+
// result.message: '{"colors": ["red", "blue", "green"]}'
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
#### Schema-Validated JSON
|
|
1047
|
+
|
|
1048
|
+
Define a Zod schema for type-safe, validated responses:
|
|
1049
|
+
|
|
1050
|
+
```typescript
|
|
1051
|
+
import { z } from "zod";
|
|
1052
|
+
|
|
1053
|
+
// Define the expected response structure
|
|
1054
|
+
const WeatherSchema = z.object({
|
|
1055
|
+
location: z.string(),
|
|
1056
|
+
temperature: z.number(),
|
|
1057
|
+
unit: z.enum(["celsius", "fahrenheit"]),
|
|
1058
|
+
conditions: z.array(z.string()),
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1061
|
+
type WeatherResponse = z.infer<typeof WeatherSchema>;
|
|
1062
|
+
|
|
1063
|
+
const agent = createAgent({
|
|
1064
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
1065
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
1066
|
+
systemPrompts: ["You provide weather information."],
|
|
1067
|
+
tools: [],
|
|
1068
|
+
responseFormat: {
|
|
1069
|
+
type: "json_schema",
|
|
1070
|
+
schema: WeatherSchema,
|
|
1071
|
+
name: "WeatherResponse", // Optional: schema name for API
|
|
1072
|
+
strict: true, // Optional: strict mode (default: true)
|
|
1073
|
+
},
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
const result = await agent.chat("Weather in Tokyo", context);
|
|
1077
|
+
|
|
1078
|
+
// Access typed, validated response
|
|
1079
|
+
const weather = result.parsedResponse as WeatherResponse;
|
|
1080
|
+
console.log(weather.temperature); // Typed as number
|
|
1081
|
+
console.log(weather.conditions); // Typed as string[]
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
#### Validation Retries
|
|
1085
|
+
|
|
1086
|
+
When schema validation fails, the SDK can automatically retry with error feedback. This uses the same `retry` configuration as API failures:
|
|
1087
|
+
|
|
1088
|
+
```typescript
|
|
1089
|
+
const agent = createAgent({
|
|
1090
|
+
// ... config
|
|
1091
|
+
responseFormat: {
|
|
1092
|
+
type: "json_schema",
|
|
1093
|
+
schema: MySchema,
|
|
1094
|
+
},
|
|
1095
|
+
retry: { maxAttempts: 3 }, // 3 total attempts (2 validation retries)
|
|
1096
|
+
});
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
When validation fails:
|
|
1100
|
+
1. The SDK captures the Zod validation error
|
|
1101
|
+
2. Sends the error details back to the model as feedback
|
|
1102
|
+
3. Model attempts to generate a corrected response
|
|
1103
|
+
4. Process repeats until validation passes or retries exhausted
|
|
1104
|
+
|
|
1105
|
+
#### Custom Error Messages
|
|
1106
|
+
|
|
1107
|
+
Customize validation error messages:
|
|
1108
|
+
|
|
1109
|
+
```typescript
|
|
1110
|
+
const agent = createAgent({
|
|
1111
|
+
// ... config
|
|
1112
|
+
errorMessages: {
|
|
1113
|
+
jsonParseError: "Failed to parse JSON response",
|
|
1114
|
+
responseSchemaValidationFailed: "Response didn't match expected format",
|
|
1115
|
+
},
|
|
1116
|
+
});
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
#### AgentResult with Parsed Response
|
|
1120
|
+
|
|
1121
|
+
When using `json_schema` format, `AgentResult` includes the validated data:
|
|
1122
|
+
|
|
1123
|
+
```typescript
|
|
1124
|
+
interface AgentResult<T = unknown> {
|
|
1125
|
+
message: string; // Raw JSON string
|
|
1126
|
+
parsedResponse?: T; // Parsed & validated object (only with json_schema)
|
|
1127
|
+
// ... other fields
|
|
1128
|
+
}
|
|
1129
|
+
```
|
|
1130
|
+
|
|
919
1131
|
### Abort Requests
|
|
920
1132
|
|
|
921
1133
|
Cancel ongoing requests using the abort functionality.
|
|
@@ -1030,6 +1242,288 @@ async function sendMessage(message: string) {
|
|
|
1030
1242
|
|
|
1031
1243
|
> **Note:** The SDK handles summarization automatically when context limits are approached. The summarized history is included in `result.conversationHistory`, so clients always receive the properly managed history state.
|
|
1032
1244
|
|
|
1245
|
+
### Middleware
|
|
1246
|
+
|
|
1247
|
+
Middleware allows you to intercept and modify the agent's execution flow at key points. Use middleware for logging, analytics, rate limiting, input sanitization, and output filtering.
|
|
1248
|
+
|
|
1249
|
+
#### Middleware Interface
|
|
1250
|
+
|
|
1251
|
+
```typescript
|
|
1252
|
+
import type { Middleware } from "concevent-ai-agent-sdk";
|
|
1253
|
+
|
|
1254
|
+
interface Middleware {
|
|
1255
|
+
name: string;
|
|
1256
|
+
beforeChat?: (ctx: BeforeChatContext) => Promise<string>;
|
|
1257
|
+
afterChat?: (ctx: AfterChatContext) => Promise<AgentResult>;
|
|
1258
|
+
beforeToolCall?: (ctx: BeforeToolCallContext) => Promise<ToolCall>;
|
|
1259
|
+
afterToolCall?: (ctx: AfterToolCallContext) => Promise<FunctionCallResult>;
|
|
1260
|
+
onError?: (ctx: ErrorContext) => Promise<void>;
|
|
1261
|
+
}
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
#### Middleware Hooks
|
|
1265
|
+
|
|
1266
|
+
| Hook | When Called | Can Modify |
|
|
1267
|
+
|------|-------------|------------|
|
|
1268
|
+
| `beforeChat` | Before chat processing begins | User message |
|
|
1269
|
+
| `afterChat` | After chat completes successfully | AgentResult |
|
|
1270
|
+
| `beforeToolCall` | Before each tool executes | ToolCall args |
|
|
1271
|
+
| `afterToolCall` | After each tool executes | FunctionCallResult |
|
|
1272
|
+
| `onError` | When an error occurs | Observation only |
|
|
1273
|
+
|
|
1274
|
+
#### Creating Middleware
|
|
1275
|
+
|
|
1276
|
+
```typescript
|
|
1277
|
+
import { createAgent } from "concevent-ai-agent-sdk";
|
|
1278
|
+
import type { Middleware } from "concevent-ai-agent-sdk";
|
|
1279
|
+
|
|
1280
|
+
// Logging middleware
|
|
1281
|
+
const loggingMiddleware: Middleware = {
|
|
1282
|
+
name: "logging",
|
|
1283
|
+
beforeChat: async (ctx) => {
|
|
1284
|
+
console.log(`[${new Date().toISOString()}] Chat started:`, ctx.message);
|
|
1285
|
+
return ctx.message;
|
|
1286
|
+
},
|
|
1287
|
+
afterChat: async (ctx) => {
|
|
1288
|
+
console.log(`[${new Date().toISOString()}] Chat completed:`, ctx.result.message);
|
|
1289
|
+
return ctx.result;
|
|
1290
|
+
},
|
|
1291
|
+
beforeToolCall: async (ctx) => {
|
|
1292
|
+
console.log(`[${new Date().toISOString()}] Tool call:`, ctx.toolCall.name);
|
|
1293
|
+
return ctx.toolCall;
|
|
1294
|
+
},
|
|
1295
|
+
onError: async (ctx) => {
|
|
1296
|
+
console.error(`[${new Date().toISOString()}] Error:`, ctx.error.code, ctx.error.message);
|
|
1297
|
+
},
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
// Input sanitization middleware
|
|
1301
|
+
const sanitizationMiddleware: Middleware = {
|
|
1302
|
+
name: "sanitization",
|
|
1303
|
+
beforeChat: async (ctx) => {
|
|
1304
|
+
// Remove potentially harmful content from user input
|
|
1305
|
+
const sanitized = ctx.message.replace(/<script[^>]*>.*?<\/script>/gi, "");
|
|
1306
|
+
return sanitized;
|
|
1307
|
+
},
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1310
|
+
// Rate limiting middleware
|
|
1311
|
+
const rateLimitMiddleware: Middleware = {
|
|
1312
|
+
name: "rate-limit",
|
|
1313
|
+
beforeChat: async (ctx) => {
|
|
1314
|
+
const userId = ctx.toolContext.userId;
|
|
1315
|
+
if (await isRateLimited(userId)) {
|
|
1316
|
+
throw new Error("Rate limit exceeded. Please try again later.");
|
|
1317
|
+
}
|
|
1318
|
+
return ctx.message;
|
|
1319
|
+
},
|
|
1320
|
+
};
|
|
1321
|
+
|
|
1322
|
+
// Output filtering middleware
|
|
1323
|
+
const outputFilterMiddleware: Middleware = {
|
|
1324
|
+
name: "output-filter",
|
|
1325
|
+
afterChat: async (ctx) => {
|
|
1326
|
+
// Remove sensitive data from responses
|
|
1327
|
+
const filteredMessage = ctx.result.message.replace(/\b\d{3}-\d{2}-\d{4}\b/g, "[REDACTED]");
|
|
1328
|
+
return { ...ctx.result, message: filteredMessage };
|
|
1329
|
+
},
|
|
1330
|
+
afterToolCall: async (ctx) => {
|
|
1331
|
+
// Filter sensitive data from tool results
|
|
1332
|
+
if (typeof ctx.result.result === "object" && ctx.result.result !== null) {
|
|
1333
|
+
const filtered = JSON.parse(
|
|
1334
|
+
JSON.stringify(ctx.result.result).replace(/"password":\s*"[^"]*"/g, '"password": "[REDACTED]"')
|
|
1335
|
+
);
|
|
1336
|
+
return { ...ctx.result, result: filtered };
|
|
1337
|
+
}
|
|
1338
|
+
return ctx.result;
|
|
1339
|
+
},
|
|
1340
|
+
};
|
|
1341
|
+
```
|
|
1342
|
+
|
|
1343
|
+
#### Registering Middleware
|
|
1344
|
+
|
|
1345
|
+
Middleware is registered via the `middleware` property in `AgentConfig`. Middleware executes in registration order (first in array = first executed).
|
|
1346
|
+
|
|
1347
|
+
```typescript
|
|
1348
|
+
const agent = createAgent({
|
|
1349
|
+
apiKey: process.env.API_KEY!,
|
|
1350
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
1351
|
+
systemPrompts: ["You are a helpful assistant."],
|
|
1352
|
+
tools: myTools,
|
|
1353
|
+
middleware: [
|
|
1354
|
+
loggingMiddleware, // Executes first
|
|
1355
|
+
sanitizationMiddleware, // Executes second
|
|
1356
|
+
rateLimitMiddleware, // Executes third
|
|
1357
|
+
outputFilterMiddleware, // Executes fourth
|
|
1358
|
+
],
|
|
1359
|
+
});
|
|
1360
|
+
```
|
|
1361
|
+
|
|
1362
|
+
#### Middleware Context
|
|
1363
|
+
|
|
1364
|
+
Each middleware hook receives a context object with relevant information:
|
|
1365
|
+
|
|
1366
|
+
```typescript
|
|
1367
|
+
// BeforeChatContext & AfterChatContext
|
|
1368
|
+
interface MiddlewareContext {
|
|
1369
|
+
message: string; // The user's input message
|
|
1370
|
+
history: ChatMessage[]; // Current conversation history
|
|
1371
|
+
toolContext: ToolExecutorContext; // userId, timezone, abortSignal
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
// BeforeToolCallContext (extends MiddlewareContext)
|
|
1375
|
+
interface BeforeToolCallContext extends MiddlewareContext {
|
|
1376
|
+
toolCall: ToolCall; // The tool call to be executed
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
// AfterToolCallContext (extends BeforeToolCallContext)
|
|
1380
|
+
interface AfterToolCallContext extends BeforeToolCallContext {
|
|
1381
|
+
result: FunctionCallResult; // The tool execution result
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
// AfterChatContext (extends MiddlewareContext)
|
|
1385
|
+
interface AfterChatContext extends MiddlewareContext {
|
|
1386
|
+
result: AgentResult; // The chat result
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
// ErrorContext (extends MiddlewareContext)
|
|
1390
|
+
interface ErrorContext extends MiddlewareContext {
|
|
1391
|
+
error: AgentError; // The error that occurred
|
|
1392
|
+
}
|
|
1393
|
+
```
|
|
1394
|
+
|
|
1395
|
+
#### Error Handling in Middleware
|
|
1396
|
+
|
|
1397
|
+
- If a middleware hook throws an error, the error propagates and stops the chain
|
|
1398
|
+
- `onError` hooks are called for observation only and do not affect the error flow
|
|
1399
|
+
- Errors in `onError` hooks are logged but do not throw
|
|
1400
|
+
|
|
1401
|
+
### Multi-Agent Orchestration
|
|
1402
|
+
|
|
1403
|
+
The SDK supports multi-agent orchestration, allowing you to create specialized agents and have an orchestrator agent route tasks to them based on their capabilities.
|
|
1404
|
+
|
|
1405
|
+
#### Creating an Orchestrator
|
|
1406
|
+
|
|
1407
|
+
```typescript
|
|
1408
|
+
import { createAgent, createOrchestratorAgent } from "concevent-ai-agent-sdk";
|
|
1409
|
+
import type { AgentDefinition } from "concevent-ai-agent-sdk";
|
|
1410
|
+
|
|
1411
|
+
// Create specialized sub-agents
|
|
1412
|
+
const codeAgent = createAgent({
|
|
1413
|
+
apiKey: process.env.API_KEY!,
|
|
1414
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
1415
|
+
systemPrompts: ["You are an expert programmer. Write clean, efficient code."],
|
|
1416
|
+
tools: codingTools,
|
|
1417
|
+
});
|
|
1418
|
+
|
|
1419
|
+
const researchAgent = createAgent({
|
|
1420
|
+
apiKey: process.env.API_KEY!,
|
|
1421
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
1422
|
+
systemPrompts: ["You are a research specialist. Find accurate information."],
|
|
1423
|
+
tools: researchTools,
|
|
1424
|
+
});
|
|
1425
|
+
|
|
1426
|
+
const dataAgent = createAgent({
|
|
1427
|
+
apiKey: process.env.API_KEY!,
|
|
1428
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
1429
|
+
systemPrompts: ["You are a data analyst. Analyze data and provide insights."],
|
|
1430
|
+
tools: analysisTools,
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
// Define sub-agents with descriptions
|
|
1434
|
+
const subAgents: AgentDefinition[] = [
|
|
1435
|
+
{
|
|
1436
|
+
agent: codeAgent,
|
|
1437
|
+
name: "code_expert",
|
|
1438
|
+
description: "Handles coding tasks: writing, reviewing, and debugging code",
|
|
1439
|
+
parallel: true, // Can run in parallel with other parallel agents
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
agent: researchAgent,
|
|
1443
|
+
name: "researcher",
|
|
1444
|
+
description: "Researches topics, finds documentation, and gathers information",
|
|
1445
|
+
parallel: true,
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
agent: dataAgent,
|
|
1449
|
+
name: "data_analyst",
|
|
1450
|
+
description: "Analyzes data, creates visualizations, and provides statistical insights",
|
|
1451
|
+
},
|
|
1452
|
+
];
|
|
1453
|
+
|
|
1454
|
+
// Create the orchestrator
|
|
1455
|
+
const orchestrator = createOrchestratorAgent({
|
|
1456
|
+
apiKey: process.env.API_KEY!,
|
|
1457
|
+
model: "anthropic/claude-3.5-sonnet",
|
|
1458
|
+
systemPrompts: ["Additional instructions for the orchestrator..."],
|
|
1459
|
+
subAgents,
|
|
1460
|
+
});
|
|
1461
|
+
```
|
|
1462
|
+
|
|
1463
|
+
#### Using the Orchestrator
|
|
1464
|
+
|
|
1465
|
+
The orchestrator automatically routes requests to appropriate sub-agents:
|
|
1466
|
+
|
|
1467
|
+
```typescript
|
|
1468
|
+
// The orchestrator decides which sub-agent(s) to use
|
|
1469
|
+
const result = await orchestrator.chat(
|
|
1470
|
+
"Research the best sorting algorithms and implement quicksort in TypeScript",
|
|
1471
|
+
{ userId: "user-123", timezone: "UTC" },
|
|
1472
|
+
{
|
|
1473
|
+
// Track sub-agent delegation
|
|
1474
|
+
onSubAgentStart: (data) => {
|
|
1475
|
+
console.log(`Delegating to ${data.agentName}: ${data.message}`);
|
|
1476
|
+
},
|
|
1477
|
+
onSubAgentComplete: (data) => {
|
|
1478
|
+
console.log(`${data.agentName} completed in ${data.result.iterations} iterations`);
|
|
1479
|
+
},
|
|
1480
|
+
// Standard callbacks also work
|
|
1481
|
+
onToolCallStart: (calls) => {
|
|
1482
|
+
console.log("Tool calls:", calls.map(c => c.name));
|
|
1483
|
+
},
|
|
1484
|
+
}
|
|
1485
|
+
);
|
|
1486
|
+
```
|
|
1487
|
+
|
|
1488
|
+
#### OrchestratorConfig
|
|
1489
|
+
|
|
1490
|
+
| Property | Type | Required | Default | Description |
|
|
1491
|
+
|-----------------|---------------------|----------|-------------------|----------------------------------------------|
|
|
1492
|
+
| `apiKey` | `string` | ✅ | - | API key for the orchestrator |
|
|
1493
|
+
| `model` | `string` | ✅ | - | Model for the orchestrator |
|
|
1494
|
+
| `systemPrompts` | `string[]` | ✅ | - | Additional prompts (orchestrator prompt auto-injected) |
|
|
1495
|
+
| `subAgents` | `AgentDefinition[]` | ✅ | - | Array of sub-agent definitions |
|
|
1496
|
+
| *(other)* | - | - | Same as AgentConfig | All other AgentConfig options except `tools` |
|
|
1497
|
+
|
|
1498
|
+
#### AgentDefinition
|
|
1499
|
+
|
|
1500
|
+
```typescript
|
|
1501
|
+
interface AgentDefinition {
|
|
1502
|
+
agent: Agent; // The agent instance
|
|
1503
|
+
name: string; // Unique name (used as tool name)
|
|
1504
|
+
description: string; // Describes capabilities (helps routing)
|
|
1505
|
+
parallel?: boolean; // Can run in parallel (default: false)
|
|
1506
|
+
}
|
|
1507
|
+
```
|
|
1508
|
+
|
|
1509
|
+
#### OrchestratorAgent Interface
|
|
1510
|
+
|
|
1511
|
+
```typescript
|
|
1512
|
+
interface OrchestratorAgent extends Agent {
|
|
1513
|
+
getSubAgents(): AgentDefinition[]; // Returns registered sub-agents
|
|
1514
|
+
}
|
|
1515
|
+
```
|
|
1516
|
+
|
|
1517
|
+
#### Key Concepts
|
|
1518
|
+
|
|
1519
|
+
1. **Stateless Delegation**: Sub-agents have their history cleared before each delegation. The orchestrator must include all necessary context in the delegated message.
|
|
1520
|
+
|
|
1521
|
+
2. **Parallel Execution**: Sub-agents marked with `parallel: true` can be called concurrently when the orchestrator needs multiple specialists.
|
|
1522
|
+
|
|
1523
|
+
3. **No Nested Orchestrators**: Sub-agents cannot themselves be orchestrators. This prevents infinite delegation loops.
|
|
1524
|
+
|
|
1525
|
+
4. **Automatic Routing**: The orchestrator's LLM decides which sub-agent(s) to use based on their descriptions and the user's request.
|
|
1526
|
+
|
|
1033
1527
|
---
|
|
1034
1528
|
|
|
1035
1529
|
## Exports Summary
|
|
@@ -1039,6 +1533,7 @@ async function sendMessage(message: string) {
|
|
|
1039
1533
|
```typescript
|
|
1040
1534
|
// Functions
|
|
1041
1535
|
export { createAgent } from "./core/agent";
|
|
1536
|
+
export { createOrchestratorAgent } from "./core/orchestrator";
|
|
1042
1537
|
export { createEvent } from "./types/events";
|
|
1043
1538
|
|
|
1044
1539
|
// Constants
|
|
@@ -1053,6 +1548,8 @@ export type {
|
|
|
1053
1548
|
ToolExecutorContext,
|
|
1054
1549
|
ToolDefinition,
|
|
1055
1550
|
AgentConfig,
|
|
1551
|
+
ParallelExecutionConfig,
|
|
1552
|
+
RetryConfig,
|
|
1056
1553
|
UsageMetadata,
|
|
1057
1554
|
AgentResult,
|
|
1058
1555
|
ToolCallStartData,
|
|
@@ -1061,11 +1558,28 @@ export type {
|
|
|
1061
1558
|
AgentEventType,
|
|
1062
1559
|
ThinkingEventData,
|
|
1063
1560
|
UsageUpdateEventData,
|
|
1561
|
+
RetryEventData,
|
|
1064
1562
|
ErrorEventData,
|
|
1065
1563
|
CompleteEventData,
|
|
1066
1564
|
MessageDeltaEventData,
|
|
1067
1565
|
ReasoningDeltaEventData,
|
|
1068
1566
|
AgentEvent,
|
|
1567
|
+
ResponseFormatConfig,
|
|
1568
|
+
// Middleware types
|
|
1569
|
+
Middleware,
|
|
1570
|
+
MiddlewareContext,
|
|
1571
|
+
BeforeChatContext,
|
|
1572
|
+
AfterChatContext,
|
|
1573
|
+
BeforeToolCallContext,
|
|
1574
|
+
AfterToolCallContext,
|
|
1575
|
+
ErrorContext,
|
|
1576
|
+
// Orchestrator types
|
|
1577
|
+
AgentDefinition,
|
|
1578
|
+
OrchestratorConfig,
|
|
1579
|
+
OrchestratorAgent,
|
|
1580
|
+
SubAgentStartData,
|
|
1581
|
+
SubAgentCompleteData,
|
|
1582
|
+
OrchestratorCallbacks,
|
|
1069
1583
|
} from "./types";
|
|
1070
1584
|
```
|
|
1071
1585
|
|
package/dist/core/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/core/agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,aAAa,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/core/agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,aAAa,EAId,MAAM,mBAAmB,CAAC;AAqD3B,MAAM,WAAW,KAAK;IACpB,IAAI,CACF,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,EAC5B,SAAS,CAAC,EAAE,cAAc,GACzB,OAAO,CAAC,WAAW,CAAC,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,UAAU,IAAI,WAAW,EAAE,CAAC;IAC5B,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IACzC,YAAY,IAAI,IAAI,CAAC;IACrB,aAAa,IAAI,aAAa,CAAC;CAChC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CA8pBtD"}
|