@aeye/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +568 -0
- package/dist/agent.d.ts +85 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +81 -0
- package/dist/agent.js.map +1 -0
- package/dist/common.d.ts +161 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +456 -0
- package/dist/common.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/prompt.d.ts +327 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +947 -0
- package/dist/prompt.js.map +1 -0
- package/dist/tool.d.ts +139 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +162 -0
- package/dist/tool.js.map +1 -0
- package/dist/types.d.ts +545 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
# @aeye/core
|
|
2
|
+
|
|
3
|
+
Core primitives for building AI agents, tools, and prompts with TypeScript. Provides a type-safe, composable framework for creating sophisticated AI applications with structured inputs/outputs, tool calling, and context management.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **🎯 Type-Safe Components** - Prompts, Tools, and Agents with full TypeScript support
|
|
8
|
+
- **🔧 Tool Calling** - Native support for function/tool calling with schema validation
|
|
9
|
+
- **📝 Template-Based Prompts** - Handlebars templates for dynamic prompt generation
|
|
10
|
+
- **✅ Schema Validation** - Zod integration for structured inputs and outputs
|
|
11
|
+
- **🌊 Streaming Support** - First-class streaming for real-time AI responses
|
|
12
|
+
- **🔄 Composable Architecture** - Tools can use other tools, prompts can use tools, agents orchestrate everything
|
|
13
|
+
- **📊 Context Management** - Type-safe context threading and automatic token window management
|
|
14
|
+
- **🎛️ Flexible Execution** - Sequential, parallel, or immediate tool execution modes
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @aeye/core zod handlebars
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Core Concepts
|
|
23
|
+
|
|
24
|
+
### Components
|
|
25
|
+
|
|
26
|
+
All AI primitives implement the `Component` interface:
|
|
27
|
+
|
|
28
|
+
- **Prompt** - Generates AI responses with optional tool usage and structured outputs
|
|
29
|
+
- **Tool** - Extends AI capabilities with custom functions and external integrations
|
|
30
|
+
- **Agent** - Orchestrates complex workflows combining prompts and tools
|
|
31
|
+
|
|
32
|
+
### Context & Metadata
|
|
33
|
+
|
|
34
|
+
- **Context (`TContext`)** - Application-specific data threaded through operations (user, db, etc.)
|
|
35
|
+
- **Metadata (`TMetadata`)** - Execution settings for AI requests (model, temperature, etc.)
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Basic Prompt
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { Prompt } from '@aeye/core';
|
|
43
|
+
import z from 'zod';
|
|
44
|
+
|
|
45
|
+
const summarizer = new Prompt({
|
|
46
|
+
name: 'summarize',
|
|
47
|
+
description: 'Summarizes text concisely',
|
|
48
|
+
content: 'Summarize the following text:\n\n{{text}}',
|
|
49
|
+
|
|
50
|
+
// Transform input
|
|
51
|
+
input: (input: { text: string }) => ({ text: input.text }),
|
|
52
|
+
|
|
53
|
+
// Define output schema
|
|
54
|
+
schema: z.object({
|
|
55
|
+
summary: z.string().describe('A concise summary'),
|
|
56
|
+
keyPoints: z.array(z.string()).describe('Main points')
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Execute with a context that has an executor
|
|
61
|
+
const result = await summarizer.get(
|
|
62
|
+
'result',
|
|
63
|
+
{ text: 'Long article text...' },
|
|
64
|
+
{
|
|
65
|
+
execute: yourAIExecutor, // Executor function from a provider
|
|
66
|
+
messages: []
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
console.log(result.summary);
|
|
71
|
+
console.log(result.keyPoints);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Creating Tools
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { Tool } from '@aeye/core';
|
|
78
|
+
import z from 'zod';
|
|
79
|
+
|
|
80
|
+
const weatherTool = new Tool({
|
|
81
|
+
name: 'getWeather',
|
|
82
|
+
description: 'Get current weather for a location',
|
|
83
|
+
instructions: 'Use this tool to get weather data',
|
|
84
|
+
|
|
85
|
+
schema: z.object({
|
|
86
|
+
location: z.string().describe('City name or coordinates'),
|
|
87
|
+
units: z.enum(['celsius', 'fahrenheit']).default('celsius')
|
|
88
|
+
}),
|
|
89
|
+
|
|
90
|
+
call: async (input, refs, ctx) => {
|
|
91
|
+
const response = await fetch(
|
|
92
|
+
`https://api.weather.com/v1/${input.location}`
|
|
93
|
+
);
|
|
94
|
+
const data = await response.json();
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
temperature: data.temp,
|
|
98
|
+
condition: data.condition,
|
|
99
|
+
humidity: data.humidity
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Prompts with Tools
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const travelAdvisor = new Prompt({
|
|
109
|
+
name: 'travelAdvisor',
|
|
110
|
+
description: 'Provides travel advice based on weather',
|
|
111
|
+
content: `You are a travel advisor. Help plan a trip to {{destination}}.
|
|
112
|
+
|
|
113
|
+
Use the weather tool to check current conditions, then provide:
|
|
114
|
+
- What to pack
|
|
115
|
+
- Activities to do
|
|
116
|
+
- Best times to visit`,
|
|
117
|
+
|
|
118
|
+
input: (input: { destination: string }) => ({
|
|
119
|
+
destination: input.destination
|
|
120
|
+
}),
|
|
121
|
+
|
|
122
|
+
tools: [weatherTool],
|
|
123
|
+
|
|
124
|
+
schema: z.object({
|
|
125
|
+
recommendations: z.array(z.string()),
|
|
126
|
+
packingList: z.array(z.string()),
|
|
127
|
+
weatherNotes: z.string()
|
|
128
|
+
})
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// The AI will automatically call weatherTool if needed
|
|
132
|
+
const advice = await travelAdvisor.get(
|
|
133
|
+
'result',
|
|
134
|
+
{ destination: 'Paris' },
|
|
135
|
+
{ execute: yourAIExecutor, messages: [] }
|
|
136
|
+
);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Streaming Responses
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Stream content only
|
|
143
|
+
for await (const chunk of summarizer.get(
|
|
144
|
+
'streamContent',
|
|
145
|
+
{ text: 'Long text...' },
|
|
146
|
+
{ stream: yourAIStreamer, messages: [] }
|
|
147
|
+
)) {
|
|
148
|
+
process.stdout.write(chunk);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Stream all events (including tool calls)
|
|
152
|
+
for await (const event of summarizer.get(
|
|
153
|
+
'stream',
|
|
154
|
+
{ text: 'Long text...' },
|
|
155
|
+
{ stream: yourAIStreamer, messages: [] }
|
|
156
|
+
)) {
|
|
157
|
+
if (event.type === 'textPartial') {
|
|
158
|
+
console.log('Text:', event.content);
|
|
159
|
+
} else if (event.type === 'toolStart') {
|
|
160
|
+
console.log('Tool started:', event.tool.name);
|
|
161
|
+
} else if (event.type === 'toolOutput') {
|
|
162
|
+
console.log('Tool result:', event.result);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Building Agents
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { Agent } from '@aeye/core';
|
|
171
|
+
|
|
172
|
+
const researchAgent = new Agent({
|
|
173
|
+
name: 'researcher',
|
|
174
|
+
description: 'Conducts research on topics',
|
|
175
|
+
|
|
176
|
+
refs: [searchTool, summarizeTool, analyzeTool],
|
|
177
|
+
|
|
178
|
+
call: async (input: { topic: string }, [search, summarize, analyze], ctx) => {
|
|
179
|
+
// Step 1: Search for information
|
|
180
|
+
const searchResults = await search.run(
|
|
181
|
+
{ query: input.topic, limit: 5 },
|
|
182
|
+
ctx
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// Step 2: Summarize findings
|
|
186
|
+
const summaries = [];
|
|
187
|
+
for (const result of searchResults) {
|
|
188
|
+
const summary = await summarize.get(
|
|
189
|
+
'result',
|
|
190
|
+
{ text: result.content },
|
|
191
|
+
ctx
|
|
192
|
+
);
|
|
193
|
+
summaries.push(summary);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Step 3: Analyze and synthesize
|
|
197
|
+
const analysis = await analyze.get(
|
|
198
|
+
'result',
|
|
199
|
+
{ topic: input.topic, sources: summaries },
|
|
200
|
+
ctx
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
return analysis;
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const research = await researchAgent.run(
|
|
208
|
+
{ topic: 'Quantum Computing' },
|
|
209
|
+
{ execute: yourAIExecutor, messages: [] }
|
|
210
|
+
);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Prompt Modes
|
|
214
|
+
|
|
215
|
+
The `get` method supports different execution modes:
|
|
216
|
+
|
|
217
|
+
| Mode | Description | Returns |
|
|
218
|
+
|------|-------------|---------|
|
|
219
|
+
| `'result'` | Get final structured output | `TOutput` |
|
|
220
|
+
| `'tools'` | Get tool call results | `PromptToolOutput[]` |
|
|
221
|
+
| `'stream'` | Stream all events | `AsyncGenerator<PromptEvent>` |
|
|
222
|
+
| `'streamTools'` | Stream tool outputs | `AsyncGenerator<PromptToolOutput>` |
|
|
223
|
+
| `'streamContent'` | Stream text content only | `AsyncGenerator<string>` |
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
// Get structured result
|
|
227
|
+
const result = await prompt.get('result', input, ctx);
|
|
228
|
+
|
|
229
|
+
// Get tool outputs only
|
|
230
|
+
const tools = await prompt.get('tools', input, ctx);
|
|
231
|
+
|
|
232
|
+
// Stream everything
|
|
233
|
+
for await (const event of prompt.get('stream', input, ctx)) {
|
|
234
|
+
// Handle different event types
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Tool Execution Modes
|
|
239
|
+
|
|
240
|
+
Control how tools are executed:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
const prompt = new Prompt({
|
|
244
|
+
name: 'multi-tool',
|
|
245
|
+
description: 'Uses multiple tools',
|
|
246
|
+
content: 'Analyze the data',
|
|
247
|
+
tools: [tool1, tool2, tool3],
|
|
248
|
+
|
|
249
|
+
// Tool execution mode
|
|
250
|
+
toolExecution: 'parallel', // 'sequential' | 'parallel' | 'immediate'
|
|
251
|
+
|
|
252
|
+
// Retry configuration
|
|
253
|
+
toolRetries: 2, // Retry failed tools
|
|
254
|
+
toolIterations: 3, // Max iterations for tool calls
|
|
255
|
+
toolsMax: 5, // Max total tool calls
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
- **`sequential`** - Wait for each tool to finish before continuing
|
|
260
|
+
- **`parallel`** - Start all tools at once, wait for all to complete
|
|
261
|
+
- **`immediate`** - Start tools immediately as they're available
|
|
262
|
+
|
|
263
|
+
## Advanced Features
|
|
264
|
+
|
|
265
|
+
### Context-Aware Tools
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
const contextTool = new Tool({
|
|
269
|
+
name: 'contextAware',
|
|
270
|
+
description: 'A context-aware tool',
|
|
271
|
+
instructions: 'Use this tool...',
|
|
272
|
+
|
|
273
|
+
// Schema can depend on context
|
|
274
|
+
schema: (ctx) => {
|
|
275
|
+
if (ctx.userRole === 'admin') {
|
|
276
|
+
return z.object({
|
|
277
|
+
action: z.enum(['read', 'write', 'delete'])
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return z.object({
|
|
281
|
+
action: z.enum(['read'])
|
|
282
|
+
});
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
// Check if tool is applicable
|
|
286
|
+
applicable: (ctx) => {
|
|
287
|
+
return ctx.isAuthenticated === true;
|
|
288
|
+
},
|
|
289
|
+
|
|
290
|
+
call: async (input, refs, ctx) => {
|
|
291
|
+
// Implementation with context access
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Custom Validation
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
const validatedTool = new Tool({
|
|
300
|
+
name: 'placeOrder',
|
|
301
|
+
description: 'Place an order',
|
|
302
|
+
|
|
303
|
+
schema: z.object({
|
|
304
|
+
itemId: z.string(),
|
|
305
|
+
quantity: z.number().min(1)
|
|
306
|
+
}),
|
|
307
|
+
|
|
308
|
+
// Additional validation beyond schema
|
|
309
|
+
validate: async (input, ctx) => {
|
|
310
|
+
const inventory = await checkInventory(input.itemId);
|
|
311
|
+
if (inventory < input.quantity) {
|
|
312
|
+
throw new Error(`Only ${inventory} items available`);
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
call: async (input, refs, ctx) => {
|
|
317
|
+
// Place order
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Event Tracking
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { withEvents } from '@aeye/core';
|
|
326
|
+
|
|
327
|
+
const runner = withEvents({
|
|
328
|
+
onStatus: (instance) => {
|
|
329
|
+
console.log(`${instance.component.name}: ${instance.status}`);
|
|
330
|
+
if (instance.status === 'completed') {
|
|
331
|
+
const duration = instance.completed - instance.started;
|
|
332
|
+
console.log(`Took ${duration}ms`);
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
|
|
336
|
+
onPromptEvent: (instance, event) => {
|
|
337
|
+
if (event.type === 'usage') {
|
|
338
|
+
console.log('Tokens used:', event.usage);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
const result = await prompt.get(
|
|
344
|
+
'result',
|
|
345
|
+
{ text: 'Hello' },
|
|
346
|
+
{
|
|
347
|
+
execute: yourAIExecutor,
|
|
348
|
+
messages: [],
|
|
349
|
+
runner
|
|
350
|
+
}
|
|
351
|
+
);
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Token Management
|
|
355
|
+
|
|
356
|
+
Automatic conversation trimming when token limits are reached:
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
const context = {
|
|
360
|
+
execute: yourAIExecutor,
|
|
361
|
+
messages: conversationHistory,
|
|
362
|
+
|
|
363
|
+
// Token configuration
|
|
364
|
+
defaultCompletionTokens: 2048,
|
|
365
|
+
|
|
366
|
+
// Custom token estimation
|
|
367
|
+
estimateTokens: (message) => {
|
|
368
|
+
return message.content.length / 4; // Rough estimate
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// Prompt will automatically trim messages if needed
|
|
373
|
+
const result = await prompt.get('result', { text: 'Query' }, context);
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Dynamic Reconfiguration
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
const adaptivePrompt = new Prompt({
|
|
380
|
+
name: 'adaptive',
|
|
381
|
+
description: 'Adapts based on execution stats',
|
|
382
|
+
content: 'Solve: {{problem}}',
|
|
383
|
+
schema: z.object({ solution: z.string() }),
|
|
384
|
+
|
|
385
|
+
// Adjust configuration during execution
|
|
386
|
+
reconfig: (stats, ctx) => {
|
|
387
|
+
// If tools are failing, change strategy
|
|
388
|
+
if (stats.toolCallErrors > 3) {
|
|
389
|
+
return {
|
|
390
|
+
config: { toolsOneAtATime: true },
|
|
391
|
+
maxIterations: 2
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
return {};
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## API Reference
|
|
400
|
+
|
|
401
|
+
### Prompt
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
class Prompt<TContext, TMetadata, TName, TInput, TOutput, TTools>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Constructor Options:**
|
|
408
|
+
- `name: string` - Unique identifier
|
|
409
|
+
- `description: string` - Purpose description
|
|
410
|
+
- `content: string` - Handlebars template
|
|
411
|
+
- `input?: Function` - Transform input for template
|
|
412
|
+
- `schema?: ZodType | Function` - Output schema
|
|
413
|
+
- `config?: Partial<Request> | Function` - AI request config
|
|
414
|
+
- `tools?: Tool[]` - Available tools
|
|
415
|
+
- `toolExecution?: 'sequential' | 'parallel' | 'immediate'`
|
|
416
|
+
- `toolRetries?: number` - Retry failed tools
|
|
417
|
+
- `toolIterations?: number` - Max tool call iterations
|
|
418
|
+
- `outputRetries?: number` - Retry invalid outputs
|
|
419
|
+
- `metadata?: TMetadata` - Execution metadata
|
|
420
|
+
- `validate?: Function` - Post-validation hook
|
|
421
|
+
- `applicable?: Function` - Applicability check
|
|
422
|
+
|
|
423
|
+
**Methods:**
|
|
424
|
+
- `get(input, mode, ctx)` - Execute and retrieve output
|
|
425
|
+
- `run(input, ctx)` - Execute with full streaming
|
|
426
|
+
- `applicable(ctx)` - Check if prompt can run
|
|
427
|
+
|
|
428
|
+
### Tool
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
class Tool<TContext, TMetadata, TName, TParams, TOutput, TRefs>
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**Constructor Options:**
|
|
435
|
+
- `name: string` - Unique identifier
|
|
436
|
+
- `description: string` - Purpose description
|
|
437
|
+
- `instructions?: string` - Handlebars usage instructions
|
|
438
|
+
- `schema: ZodType | Function` - Input schema
|
|
439
|
+
- `refs?: Component[]` - Referenced components
|
|
440
|
+
- `call: Function` - Implementation
|
|
441
|
+
- `validate?: Function` - Post-validation hook
|
|
442
|
+
- `applicable?: Function` - Applicability check
|
|
443
|
+
|
|
444
|
+
**Methods:**
|
|
445
|
+
- `run(input, ctx)` - Execute the tool
|
|
446
|
+
- `compile(ctx)` - Generate tool definition for AI
|
|
447
|
+
- `parse(ctx, args)` - Parse and validate arguments
|
|
448
|
+
- `applicable(ctx)` - Check if tool can run
|
|
449
|
+
|
|
450
|
+
### Agent
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
class Agent<TContext, TMetadata, TName, TInput, TOutput, TRefs>
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**Constructor Options:**
|
|
457
|
+
- `name: string` - Unique identifier
|
|
458
|
+
- `description: string` - Purpose description
|
|
459
|
+
- `refs?: Component[]` - Referenced components
|
|
460
|
+
- `call: Function` - Implementation with refs
|
|
461
|
+
- `applicable?: Function` - Applicability check
|
|
462
|
+
|
|
463
|
+
**Methods:**
|
|
464
|
+
- `run(input, ctx)` - Execute the agent
|
|
465
|
+
- `applicable(ctx)` - Check if agent can run
|
|
466
|
+
|
|
467
|
+
## Context Structure
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
interface Context<TContext, TMetadata> {
|
|
471
|
+
// Required: AI execution
|
|
472
|
+
execute?: Executor<TContext, TMetadata>;
|
|
473
|
+
stream?: Streamer<TContext, TMetadata>;
|
|
474
|
+
|
|
475
|
+
// Messages
|
|
476
|
+
messages: Message[];
|
|
477
|
+
|
|
478
|
+
// Token management
|
|
479
|
+
defaultCompletionTokens?: number;
|
|
480
|
+
estimateTokens?: (message: Message) => number;
|
|
481
|
+
|
|
482
|
+
// Execution control
|
|
483
|
+
signal?: AbortSignal;
|
|
484
|
+
runner?: Events;
|
|
485
|
+
|
|
486
|
+
// User context (TContext) spreads here
|
|
487
|
+
[key: string]: any;
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Request Configuration
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
interface Request {
|
|
495
|
+
messages: Message[];
|
|
496
|
+
temperature?: number; // 0-2
|
|
497
|
+
topP?: number; // 0-1
|
|
498
|
+
maxTokens?: number;
|
|
499
|
+
stop?: string | string[];
|
|
500
|
+
tools?: ToolDefinition[];
|
|
501
|
+
toolChoice?: 'auto' | 'required' | 'none' | { tool: string };
|
|
502
|
+
responseFormat?: 'text' | 'json' | ResponseFormat;
|
|
503
|
+
// ... more options
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Best Practices
|
|
508
|
+
|
|
509
|
+
1. **Type Safety** - Use TypeScript generics for context and metadata
|
|
510
|
+
2. **Schema Validation** - Use Zod for robust input/output validation
|
|
511
|
+
3. **Error Handling** - Wrap component execution in try-catch blocks
|
|
512
|
+
4. **Token Management** - Provide `estimateTokens` for accurate trimming
|
|
513
|
+
5. **Tool Organization** - Group related tools in agents
|
|
514
|
+
6. **Testing** - Unit test tools and prompts independently
|
|
515
|
+
7. **Documentation** - Document template variables and schemas
|
|
516
|
+
8. **Context Minimization** - Pass only necessary data in context
|
|
517
|
+
9. **Streaming** - Use streaming for better UX with long responses
|
|
518
|
+
10. **Validation** - Use `validate` hooks for business logic validation
|
|
519
|
+
|
|
520
|
+
## Examples
|
|
521
|
+
|
|
522
|
+
See the `src/__tests__` directory for comprehensive examples:
|
|
523
|
+
|
|
524
|
+
- **prompt-core-features.test.ts** - Basic prompt usage
|
|
525
|
+
- **prompt-streaming-tool-events.test.ts** - Streaming and events
|
|
526
|
+
- **tool.test.ts** - Tool creation and usage
|
|
527
|
+
- **agent.test.ts** - Agent orchestration
|
|
528
|
+
- **context-propagation.test.ts** - Context handling
|
|
529
|
+
|
|
530
|
+
## TypeScript Support
|
|
531
|
+
|
|
532
|
+
Full type inference across component hierarchies:
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
// Types are automatically inferred
|
|
536
|
+
const prompt = new Prompt({
|
|
537
|
+
name: 'example',
|
|
538
|
+
schema: z.object({ result: z.string() })
|
|
539
|
+
// ...
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
// TypeScript knows the output type
|
|
543
|
+
const output = await prompt.get({}); // { result: string }
|
|
544
|
+
|
|
545
|
+
// Tool parameters are type-safe
|
|
546
|
+
const tool = new Tool({
|
|
547
|
+
name: 'math',
|
|
548
|
+
schema: z.object({ a: z.number(), b: z.number() }),
|
|
549
|
+
call: (input, refs, ctx) => {
|
|
550
|
+
// input is typed as { a: number, b: number }
|
|
551
|
+
return input.a + input.b;
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
## Contributing
|
|
557
|
+
|
|
558
|
+
Contributions are welcome! See the main [@aeye repository](https://github.com/ClickerMonkey/aeye) for contribution guidelines.
|
|
559
|
+
|
|
560
|
+
## License
|
|
561
|
+
|
|
562
|
+
MIT © [ClickerMonkey](https://github.com/ClickerMonkey)
|
|
563
|
+
|
|
564
|
+
## Links
|
|
565
|
+
|
|
566
|
+
- [GitHub Repository](https://github.com/ClickerMonkey/aeye)
|
|
567
|
+
- [Documentation](https://github.com/ClickerMonkey/aeye/tree/main/packages/core)
|
|
568
|
+
- [Issue Tracker](https://github.com/ClickerMonkey/aeye/issues)
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { AnyComponent, Component, ComponentCompatible, Context, OptionalParams, Tuple } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for creating an Agent component.
|
|
4
|
+
* Agents orchestrate complex workflows by composing other components (tools, prompts, and agents).
|
|
5
|
+
*
|
|
6
|
+
* @template TContext - The context type needed for the agent's operation.
|
|
7
|
+
* @template TMetadata - The metadata type needed during execution/streaming.
|
|
8
|
+
* @template TName - The name of the agent, typed for inference in parent components.
|
|
9
|
+
* @template TInput - The input parameters type for the agent.
|
|
10
|
+
* @template TOutput - The output type for the agent.
|
|
11
|
+
* @template TRefs - References to other components that this agent depends on.
|
|
12
|
+
*/
|
|
13
|
+
export interface AgentInput<TContext = {}, TMetadata = {}, TName extends string = string, TInput extends object = {}, TOutput = string, TRefs extends Tuple<AnyComponent> = []> {
|
|
14
|
+
/** The unique name of the agent */
|
|
15
|
+
name: TName;
|
|
16
|
+
/** Brief description of the agent's purpose (informational only) */
|
|
17
|
+
description: string;
|
|
18
|
+
/** References to other components (tools, prompts, agents) that this agent utilizes */
|
|
19
|
+
refs: TRefs;
|
|
20
|
+
/** The function that implements the agent's behavior */
|
|
21
|
+
call: (input: TInput, refs: TRefs, ctx: Context<TContext, TMetadata>) => TOutput;
|
|
22
|
+
/** Optional function to determine if the component is applicable in the given context */
|
|
23
|
+
applicable?: (ctx: Context<TContext, TMetadata>) => boolean | Promise<boolean>;
|
|
24
|
+
/** Optional way to explicitly declare the types used in this component */
|
|
25
|
+
types?: {
|
|
26
|
+
input?: TInput;
|
|
27
|
+
output?: TOutput;
|
|
28
|
+
context?: TContext;
|
|
29
|
+
metadata?: TMetadata;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* An Agent component that orchestrates complex workflows by composing other AI components.
|
|
34
|
+
* Agents can utilize tools, prompts, and other agents to accomplish sophisticated tasks.
|
|
35
|
+
*
|
|
36
|
+
* @template TContext - The context type needed for the agent's operation.
|
|
37
|
+
* @template TMetadata - The metadata type needed during execution/streaming.
|
|
38
|
+
* @template TName - The name of the agent, typed for inference in parent components.
|
|
39
|
+
* @template TInput - The input parameters type for the agent.
|
|
40
|
+
* @template TOutput - The output type for the agent.
|
|
41
|
+
* @template TRefs - References to other components that this agent depends on.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const researchAgent = new Agent({
|
|
45
|
+
* name: 'researcher',
|
|
46
|
+
* description: 'Conducts research using multiple tools',
|
|
47
|
+
* refs: [searchTool, summarizeTool, analyzePrompt],
|
|
48
|
+
* call: async (input, [search, summarize, analyze], ctx) => {
|
|
49
|
+
* const results = await search.run({ query: input.topic }, ctx);
|
|
50
|
+
* const summary = await summarize.get({ text: results });
|
|
51
|
+
* return analyze.get({ summary, topic: input.topic });
|
|
52
|
+
* }
|
|
53
|
+
* });
|
|
54
|
+
*/
|
|
55
|
+
export declare class Agent<TContext = {}, TMetadata = {}, TName extends string = string, TInput extends object = {}, TOutput = string, TRefs extends Tuple<ComponentCompatible<TContext, TMetadata>> = []> implements Component<TContext, TMetadata, TName, TInput, TOutput, TRefs> {
|
|
56
|
+
input: AgentInput<TContext, TMetadata, TName, TInput, TOutput, TRefs>;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new Agent instance.
|
|
59
|
+
*
|
|
60
|
+
* @param input - The agent input configuration.
|
|
61
|
+
*/
|
|
62
|
+
constructor(input: AgentInput<TContext, TMetadata, TName, TInput, TOutput, TRefs>);
|
|
63
|
+
get kind(): 'agent';
|
|
64
|
+
get name(): TName;
|
|
65
|
+
get description(): string;
|
|
66
|
+
get refs(): TRefs;
|
|
67
|
+
/**
|
|
68
|
+
* Executes the agent with the provided context and input.
|
|
69
|
+
* If a custom runner is provided in the context, it will be used instead of direct execution.
|
|
70
|
+
*
|
|
71
|
+
* @param input - The input parameters for the agent.
|
|
72
|
+
* @param ctx - The execution context.
|
|
73
|
+
* @returns The output of the agent's operation.
|
|
74
|
+
*/
|
|
75
|
+
run<TRuntimeContext extends TContext, TRuntimeMetadata extends TMetadata, TCoreContext extends Context<TRuntimeContext, TRuntimeMetadata>>(...[inputMaybe, contextMaybe]: OptionalParams<[TInput, TCoreContext]>): TOutput;
|
|
76
|
+
/**
|
|
77
|
+
* Determines whether the agent is applicable in the given context.
|
|
78
|
+
* By default, checks if any of its referenced components are applicable.
|
|
79
|
+
*
|
|
80
|
+
* @param ctx - The context to check applicability against.
|
|
81
|
+
* @returns A promise that resolves to true if the agent is applicable, false otherwise.
|
|
82
|
+
*/
|
|
83
|
+
applicable<TRuntimeContext extends TContext, TRuntimeMetadata extends TMetadata, TCoreContext extends Context<TRuntimeContext, TRuntimeMetadata>>(...[contextMaybe]: OptionalParams<[TCoreContext]>): Promise<boolean>;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEvG;;;;;;;;;;GAUG;AACH,MAAM,WAAW,UAAU,CACzB,QAAQ,GAAG,EAAE,EACb,SAAS,GAAG,EAAE,EACd,KAAK,SAAS,MAAM,GAAG,MAAM,EAC7B,MAAM,SAAS,MAAM,GAAG,EAAE,EAC1B,OAAO,GAAG,MAAM,EAChB,KAAK,SAAS,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;IAEtC,mCAAmC;IACnC,IAAI,EAAE,KAAK,CAAC;IACZ,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,IAAI,EAAE,KAAK,CAAC;IACZ,wDAAwD;IACxD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,OAAO,CAAC;IACjF,yFAAyF;IACzF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/E,0EAA0E;IAC1E,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;QACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;KACtB,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,KAAK,CAChB,QAAQ,GAAG,EAAE,EACb,SAAS,GAAG,EAAE,EACd,KAAK,SAAS,MAAM,GAAG,MAAM,EAC7B,MAAM,SAAS,MAAM,GAAG,EAAE,EAC1B,OAAO,GAAG,MAAM,EAChB,KAAK,SAAS,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAClE,YAAW,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IAQ/D,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IAN9E;;;;OAIG;gBAEM,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IAG9E,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,IAAI,IAAI,IAAI,KAAK,CAEhB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,IAAI,IAAI,KAAK,CAEhB;IAED;;;;;;;OAOG;IACH,GAAG,CACD,eAAe,SAAS,QAAQ,EAChC,gBAAgB,SAAS,SAAS,EAClC,YAAY,SAAS,OAAO,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAC/D,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE,cAAc,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,GAAG,OAAO;IAUjF;;;;;;OAMG;IACG,UAAU,CACd,eAAe,SAAS,QAAQ,EAChC,gBAAgB,SAAS,SAAS,EAClC,YAAY,SAAS,OAAO,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAC/D,GAAG,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAevE"}
|