agent-pulse 1.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 +361 -0
- package/dist/agent.d.ts +8 -0
- package/dist/agent.js +83 -0
- package/dist/chain.d.ts +53 -0
- package/dist/chain.js +91 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +31 -0
- package/dist/providers/google.d.ts +8 -0
- package/dist/providers/google.js +277 -0
- package/dist/providers/grok.d.ts +8 -0
- package/dist/providers/grok.js +148 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.js +28 -0
- package/dist/providers/openai.d.ts +8 -0
- package/dist/providers/openai.js +152 -0
- package/dist/sse.d.ts +15 -0
- package/dist/sse.js +67 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.js +2 -0
- package/dist/utils/file-utils.d.ts +26 -0
- package/dist/utils/file-utils.js +128 -0
- package/dist/utils/image-utils.d.ts +9 -0
- package/dist/utils/image-utils.js +36 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Agent Pulse
|
|
2
|
+
|
|
3
|
+
**Agent Pulse** is a lightweight, native-first, event-driven framework for building agentic AI applications in JavaScript and TypeScript.
|
|
4
|
+
|
|
5
|
+
It is designed to be "Zero Boilerplate," getting you from install to running agent in seconds, while supporting powerful patterns like streaming, tool execution, and workflow chaining.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Native First**: Built directly on official SDKs (`@google/genai`, `openai`).
|
|
10
|
+
- **Tree-Shakeable**: Modular architecture allows you to import only what you need.
|
|
11
|
+
- **Event-Driven**: Emit `token` events for streaming and `response` events for logic.
|
|
12
|
+
- **Zero Boilerplate**: Simple `config`-based initialization.
|
|
13
|
+
- **Auto Tool Execution**: Automatically executes tools and returns results for "Intent Detection" patterns.
|
|
14
|
+
- **Provider Agnostic**: Easily switch between OpenAI, Google Gemini, and Grok by injecting different providers.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install agent-pulse
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
### 1. Setup Environment
|
|
24
|
+
Create a `.env` file with your API keys. You only need the key for the provider you intend to use.
|
|
25
|
+
|
|
26
|
+
```env
|
|
27
|
+
OPENAI_API_KEY=sk-...
|
|
28
|
+
GOOGLE_API_KEY=AIza...
|
|
29
|
+
GROK_API_KEY=...
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Basic Chat Bot (Streaming)
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { Agent, openAI } from 'agent-pulse';
|
|
36
|
+
import * as dotenv from 'dotenv';
|
|
37
|
+
dotenv.config();
|
|
38
|
+
|
|
39
|
+
// Instantiate the provider directly
|
|
40
|
+
const agent = new Agent({
|
|
41
|
+
name: 'my-bot',
|
|
42
|
+
provider: new openAI('gpt-4o'), // Or new google('gemini-1.5-pro'), new grok('grok-beta')
|
|
43
|
+
system: 'You are a helpful assistant.'
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Real-time typing effect
|
|
47
|
+
agent.on('token', (chunk) => {
|
|
48
|
+
process.stdout.write(chunk);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Final logic
|
|
52
|
+
agent.on('response', (result) => {
|
|
53
|
+
console.log('\nDone!', result.meta);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
await agent.run('Hello!');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 3. Chatbots & history (Multi-Turn)
|
|
60
|
+
|
|
61
|
+
To run a chatbot with memory, maintain a history array and pass it to `agent.run()`.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { Agent, openAI } from 'agent-pulse';
|
|
65
|
+
|
|
66
|
+
const agent = new Agent({
|
|
67
|
+
name: 'chatbot',
|
|
68
|
+
provider: new openAI('gpt-4o'),
|
|
69
|
+
system: 'You are a helpful assistant.'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const history = [
|
|
73
|
+
{ role: 'user', content: 'What is the capital of France?' },
|
|
74
|
+
{ role: 'assistant', content: 'The capital of France is Paris.' },
|
|
75
|
+
{ role: 'user', content: 'And what is its famous tower?' }
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const result = await agent.run(history);
|
|
79
|
+
console.log(result.content); // "The famous tower in Paris is the Eiffel Tower."
|
|
80
|
+
|
|
81
|
+
// To continue the conversation, append the new assistant response:
|
|
82
|
+
history.push({ role: 'assistant', content: result.content });
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Modular Imports & Providers
|
|
86
|
+
|
|
87
|
+
Agent Pulse exports aliases for common providers to make your code clean:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { Agent, openAI, google, grok } from 'agent-pulse';
|
|
91
|
+
|
|
92
|
+
// OpenAI
|
|
93
|
+
const bot1 = new Agent({
|
|
94
|
+
name: 'gpt-bot',
|
|
95
|
+
provider: new openAI('gpt-4o')
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Google Gemini
|
|
99
|
+
const bot2 = new Agent({
|
|
100
|
+
name: 'gemini-bot',
|
|
101
|
+
provider: new google('gemini-1.5-pro')
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// xAI / Grok
|
|
105
|
+
const bot3 = new Agent({
|
|
106
|
+
name: 'grok-bot',
|
|
107
|
+
provider: new grok('grok-beta')
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
You can also import the classes directly if you prefer:
|
|
112
|
+
```typescript
|
|
113
|
+
import { Agent, OpenAIProvider, GoogleProvider, GrokProvider } from 'agent-pulse';
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
| Option | Type | Description |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `name` | string | Unique identifier for debugging. |
|
|
121
|
+
| `provider` | LLMProvider | An instance of a provider class (e.g., `new OpenAIProvider(...)`). |
|
|
122
|
+
| `system` | string | System instructions. |
|
|
123
|
+
| `prompt` | string | Base prompt template (optional). |
|
|
124
|
+
| `files` | string[] | Array of file paths or content strings to include in context. |
|
|
125
|
+
| `tools` | Array | List of executable tools with Zod schemas. |
|
|
126
|
+
| `output_schema` | ZodSchema | Enforce structured JSON output (if supported by provider). |
|
|
127
|
+
| `saveFunction` | function | Async function to persist messages (`(msg) => Promise<void>`). |
|
|
128
|
+
|
|
129
|
+
## Events
|
|
130
|
+
|
|
131
|
+
Agent Pulse is built on `EventEmitter`. You can listen to the following events:
|
|
132
|
+
|
|
133
|
+
| Event Name | Description | Payload Structure |
|
|
134
|
+
| :--- | :--- | :--- |
|
|
135
|
+
| `start` | Fired when `agent.run()` is called. | `{ timestamp: number, inputContext: string\|any[] }` |
|
|
136
|
+
| `token` | Fired for each chunk of text generated (streaming). | `string` |
|
|
137
|
+
| `tool_start` | Fired before a tool is executed. | `{ tool: string, arguments: any }` |
|
|
138
|
+
| `tool_end` | Fired after a tool has executed. | `{ tool: string, result: any }` |
|
|
139
|
+
| `response` | Fired when generation is complete. | `AgentResponse` object |
|
|
140
|
+
| `error` | Fired when an error occurs. | `{ error_key: string, message: string, details?: any }` |
|
|
141
|
+
| `log` | General logging event. | `{ level: string, message: string }` |
|
|
142
|
+
|
|
143
|
+
## Response Structure & Token Usage
|
|
144
|
+
|
|
145
|
+
The `response` event and the `agent.run()` promise resolve to a standardized `AgentResponse` object:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
{
|
|
149
|
+
content: string | object, // The Markdown text or parsed JSON
|
|
150
|
+
usage: {
|
|
151
|
+
input_tokens: number,
|
|
152
|
+
output_tokens: number,
|
|
153
|
+
total_tokens: number
|
|
154
|
+
},
|
|
155
|
+
meta: {
|
|
156
|
+
model: string,
|
|
157
|
+
latency_ms: number
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
You can access token usage stats from the `usage` property.
|
|
163
|
+
|
|
164
|
+
## Error Codes
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
The `error` event payload contains an `error_key` to help you handle specific failure scenarios:
|
|
168
|
+
|
|
169
|
+
- `network_error`: Connection failures or timeouts.
|
|
170
|
+
- `auth_error`: Invalid API keys or permission issues.
|
|
171
|
+
- `json_error`: Failure parsing structured outputs.
|
|
172
|
+
- `execution_error`: General runtime errors during agent execution.
|
|
173
|
+
- `retry_error`: Max retries exceeded.
|
|
174
|
+
|
|
175
|
+
### Handling Errors
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
agent.on('error', (err) => {
|
|
179
|
+
console.error(`[${err.error_key}]`, err.message);
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Usage Examples
|
|
184
|
+
|
|
185
|
+
### 1. Tool Use & Intent Detection
|
|
186
|
+
|
|
187
|
+
Use tools to perform actions or structured data extraction. You can handle the results in two ways: via **events** (for monitoring/side-effects) or via **return values** (for control flow).
|
|
188
|
+
|
|
189
|
+
#### Option A: Control Flow (Async/Await)
|
|
190
|
+
Best for logic. The tool's return value becomes the agent's final response if the agent decides the task is complete.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { Agent, google } from 'agent-pulse';
|
|
194
|
+
import { z } from 'zod';
|
|
195
|
+
|
|
196
|
+
const summaryTool = {
|
|
197
|
+
name: 'summarize_trip_intent',
|
|
198
|
+
description: 'Call when you have destination and date.',
|
|
199
|
+
parameters: z.object({ destination: z.string(), date: z.string() }),
|
|
200
|
+
execute: async ({ destination, date }) => {
|
|
201
|
+
// Return a payload. The agent maps this to the final response.
|
|
202
|
+
return { type: 'INTENT_COMPLETE', payload: { destination, date } };
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const agent = new Agent({
|
|
207
|
+
name: 'intake',
|
|
208
|
+
provider: new google('gemini-1.5-pro'),
|
|
209
|
+
tools: [summaryTool]
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Await the result directly
|
|
213
|
+
const result = await agent.run("I want to go to Paris next week.");
|
|
214
|
+
|
|
215
|
+
if (result.content?.type === 'INTENT_COMPLETE') {
|
|
216
|
+
console.log("✅ Intent Detected via Return:", result.content.payload);
|
|
217
|
+
// Proceed with your app logic...
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### Option B: Events (Side Effects)
|
|
222
|
+
Best for logging, UI updates, or real-time monitoring.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// Listen to 'tool_start' and 'tool_end' for visibility
|
|
226
|
+
agent.on('tool_start', (evt) => {
|
|
227
|
+
console.log(`[UI] ⏳ Executing tool: ${evt.tool}...`);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
agent.on('tool_end', (evt) => {
|
|
231
|
+
console.log(`[UI] ✔️ Tool finished:`, evt.result);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
await agent.run("I want to go to Tokyo.");
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 2. File Input
|
|
238
|
+
|
|
239
|
+
Pass file content context to the agent.
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { Agent, openAI } from 'agent-pulse';
|
|
243
|
+
|
|
244
|
+
const agent = new Agent({
|
|
245
|
+
name: 'analyst',
|
|
246
|
+
provider: new openAI('gpt-4o'),
|
|
247
|
+
// You can pass file paths (if handled by environment) or load content yourself
|
|
248
|
+
files: ['/path/to/data.txt']
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 3. Structured Output (JSON)
|
|
253
|
+
|
|
254
|
+
Enforce a specific JSON schema for the response.
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { Agent, google } from 'agent-pulse';
|
|
258
|
+
import { z } from 'zod';
|
|
259
|
+
|
|
260
|
+
const recipeSchema = z.object({
|
|
261
|
+
title: z.string(),
|
|
262
|
+
ingredients: z.array(z.string()),
|
|
263
|
+
steps: z.array(z.string())
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
const agent = new Agent({
|
|
267
|
+
name: 'chef',
|
|
268
|
+
provider: new google('gemini-1.5-pro'),
|
|
269
|
+
output_schema: recipeSchema
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
agent.on('response', (result) => {
|
|
273
|
+
// result.content will be a typed object
|
|
274
|
+
console.log("Recipe:", result.content);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
await agent.run("How do I make pancakes?");
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 4. Server-Side Streaming (SSE)
|
|
281
|
+
|
|
282
|
+
Bridge agent events to a Server-Sent Events stream for frontend consumption (e.g., in Express).
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import { Agent, openAI, bridgeToSSE, setupSSEHeaders } from 'agent-pulse';
|
|
286
|
+
import express from 'express';
|
|
287
|
+
|
|
288
|
+
const app = express();
|
|
289
|
+
|
|
290
|
+
app.get('/chat', async (req, res) => {
|
|
291
|
+
setupSSEHeaders(res);
|
|
292
|
+
|
|
293
|
+
const agent = new Agent({
|
|
294
|
+
name: 'web-bot',
|
|
295
|
+
provider: new openAI('gpt-4o')
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Connect agent events to the response stream
|
|
299
|
+
bridgeToSSE(res, agent);
|
|
300
|
+
|
|
301
|
+
await agent.run(req.query.prompt);
|
|
302
|
+
// Response ends automatically after agent finishes
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### 5. Google Search Grounding
|
|
307
|
+
|
|
308
|
+
Enable real-time search results and citations with Google models.
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
import { Agent, google } from 'agent-pulse';
|
|
312
|
+
|
|
313
|
+
const agent = new Agent({
|
|
314
|
+
name: 'researcher',
|
|
315
|
+
provider: new google('gemini-2.5-flash-lite'),
|
|
316
|
+
config: {
|
|
317
|
+
googleSearch: true
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
agent.on('response', (result) => {
|
|
322
|
+
// Access citation metadata
|
|
323
|
+
if (result.meta.groundingMetadata) {
|
|
324
|
+
console.log('Sources:', result.meta.groundingMetadata);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
await agent.run("Who won the Super Bowl in 2024?");
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Extensibility: Custom Providers
|
|
332
|
+
|
|
333
|
+
To add a new provider (e.g. Anthropic, Mistral), create a class that implements the `LLMProvider` interface.
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
import { LLMProvider, AgentResponse } from 'agent-pulse/types';
|
|
337
|
+
|
|
338
|
+
export class MyProvider implements LLMProvider {
|
|
339
|
+
constructor(private modelName: string) {}
|
|
340
|
+
|
|
341
|
+
async generate(system, prompt, files, tools, config, schema, onToken) {
|
|
342
|
+
// Implement generation logic
|
|
343
|
+
// Call onToken(chunk) for streaming
|
|
344
|
+
// Return Promise<AgentResponse>
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Usage
|
|
349
|
+
const agent = new Agent({
|
|
350
|
+
name: 'custom-bot',
|
|
351
|
+
provider: new MyProvider('my-model')
|
|
352
|
+
});
|
|
353
|
+
```
|
|
354
|
+
# To locally link the package
|
|
355
|
+
|
|
356
|
+
1. Run `npm link` in the agent-pulse directory
|
|
357
|
+
2. Run `npm link agent-pulse --legacy-peer-deps` in your project directory
|
|
358
|
+
|
|
359
|
+
## License
|
|
360
|
+
|
|
361
|
+
MIT
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { AgentConfig, AgentResponse } from './types';
|
|
3
|
+
export declare class Agent extends EventEmitter {
|
|
4
|
+
private config;
|
|
5
|
+
private provider;
|
|
6
|
+
constructor(config: AgentConfig);
|
|
7
|
+
run(inputContext: string | any[]): Promise<AgentResponse>;
|
|
8
|
+
}
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Agent = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
class Agent extends events_1.EventEmitter {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
super();
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.provider = config.provider;
|
|
10
|
+
}
|
|
11
|
+
async run(inputContext) {
|
|
12
|
+
this.emit('start', { timestamp: Date.now(), inputContext });
|
|
13
|
+
const startTime = Date.now();
|
|
14
|
+
// Persistence: Save User Message if input is a string (new message)
|
|
15
|
+
if (typeof inputContext === 'string' && this.config.saveFunction) {
|
|
16
|
+
try {
|
|
17
|
+
await this.config.saveFunction({ role: 'user', content: inputContext });
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
console.error("Failed to save user message:", err);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Normalize input context
|
|
24
|
+
let finalPrompt;
|
|
25
|
+
if (Array.isArray(inputContext)) {
|
|
26
|
+
finalPrompt = inputContext;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const prompt = typeof inputContext === 'string' ? inputContext : String(inputContext);
|
|
30
|
+
finalPrompt = this.config.prompt ? `${this.config.prompt}\n\n${prompt}` : prompt;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const response = await this.provider.generate(this.config.system, finalPrompt, this.config.files, this.config.tools, this.config.config, this.config.output_schema, (token) => this.emit('token', token));
|
|
34
|
+
// Handle Tool Execution
|
|
35
|
+
if (response.tool_calls && this.config.tools) {
|
|
36
|
+
for (const call of response.tool_calls) {
|
|
37
|
+
const tool = this.config.tools.find(t => t.name === call.name);
|
|
38
|
+
if (tool) {
|
|
39
|
+
try {
|
|
40
|
+
// Execute the tool
|
|
41
|
+
// Note: In this lightweight framework, we return the tool result as the final content.
|
|
42
|
+
// This supports the "Intent Detection" pattern where the goal is to trigger an action, not just chat.
|
|
43
|
+
this.emit('tool_start', { tool: tool.name, arguments: call.arguments });
|
|
44
|
+
const result = await tool.execute(call.arguments);
|
|
45
|
+
this.emit('tool_end', { tool: tool.name, result });
|
|
46
|
+
response.content = result;
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
console.error(`Error executing tool ${tool.name}:`, e);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Add latency to meta
|
|
55
|
+
response.meta.latency_ms = Date.now() - startTime;
|
|
56
|
+
// Persistence: Save Assistant Response
|
|
57
|
+
if (this.config.saveFunction) {
|
|
58
|
+
try {
|
|
59
|
+
await this.config.saveFunction({
|
|
60
|
+
role: 'assistant',
|
|
61
|
+
content: response.content,
|
|
62
|
+
usage: response.usage,
|
|
63
|
+
meta: response.meta
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error("Failed to save assistant response:", err);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
this.emit('response', response);
|
|
71
|
+
return response;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
this.emit('error', {
|
|
75
|
+
error_key: 'execution_error',
|
|
76
|
+
message: error.message || String(error),
|
|
77
|
+
details: error
|
|
78
|
+
});
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.Agent = Agent;
|
package/dist/chain.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Agent } from './agent';
|
|
2
|
+
import { AgentResponse } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for a single agent in the chain
|
|
5
|
+
*/
|
|
6
|
+
export interface ChainStep {
|
|
7
|
+
agent: Agent;
|
|
8
|
+
input: string | any[] | ((previousResults: AgentResponse[]) => string | any[] | any);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Result of executing a chain of agents
|
|
12
|
+
*/
|
|
13
|
+
export interface ChainResult {
|
|
14
|
+
results: AgentResponse[];
|
|
15
|
+
totalLatency: number;
|
|
16
|
+
totalTokens: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Chains multiple agents to run sequentially.
|
|
20
|
+
* Each agent waits for the previous one to complete before starting.
|
|
21
|
+
*
|
|
22
|
+
* @param steps - Array of chain steps, each containing an agent and its input
|
|
23
|
+
* @returns Promise that resolves with all agent responses
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const result = await chain([
|
|
28
|
+
* { agent: chatBot, input: 'Hello' },
|
|
29
|
+
* { agent: planner, input: (results) => results[0].content },
|
|
30
|
+
* { agent: executor, input: (results) => JSON.stringify(results[1].content) }
|
|
31
|
+
* ]);
|
|
32
|
+
*
|
|
33
|
+
* console.log(result.results[0].content); // First agent output
|
|
34
|
+
* console.log(result.results[1].content); // Second agent output
|
|
35
|
+
* console.log(result.totalTokens); // Total tokens used
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function chain(steps: ChainStep[]): Promise<ChainResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Simplified chain function that accepts just agents and uses previous output as next input.
|
|
41
|
+
* The first agent must be provided with an initial input separately.
|
|
42
|
+
*
|
|
43
|
+
* @param agents - Array of agents to chain
|
|
44
|
+
* @param initialInput - Input for the first agent
|
|
45
|
+
* @returns Promise that resolves with all agent responses
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const result = await simpleChain([chatBot, planner, executor], 'Hello');
|
|
50
|
+
* // Each agent receives the previous agent's content as input
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function simpleChain(agents: Agent[], initialInput: string | any[]): Promise<ChainResult>;
|
package/dist/chain.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.chain = chain;
|
|
4
|
+
exports.simpleChain = simpleChain;
|
|
5
|
+
/**
|
|
6
|
+
* Chains multiple agents to run sequentially.
|
|
7
|
+
* Each agent waits for the previous one to complete before starting.
|
|
8
|
+
*
|
|
9
|
+
* @param steps - Array of chain steps, each containing an agent and its input
|
|
10
|
+
* @returns Promise that resolves with all agent responses
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const result = await chain([
|
|
15
|
+
* { agent: chatBot, input: 'Hello' },
|
|
16
|
+
* { agent: planner, input: (results) => results[0].content },
|
|
17
|
+
* { agent: executor, input: (results) => JSON.stringify(results[1].content) }
|
|
18
|
+
* ]);
|
|
19
|
+
*
|
|
20
|
+
* console.log(result.results[0].content); // First agent output
|
|
21
|
+
* console.log(result.results[1].content); // Second agent output
|
|
22
|
+
* console.log(result.totalTokens); // Total tokens used
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
async function chain(steps) {
|
|
26
|
+
const results = [];
|
|
27
|
+
let totalLatency = 0;
|
|
28
|
+
let totalTokens = 0;
|
|
29
|
+
for (const step of steps) {
|
|
30
|
+
// Determine the input for this agent
|
|
31
|
+
let input;
|
|
32
|
+
if (typeof step.input === 'function') {
|
|
33
|
+
input = step.input(results);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
input = step.input;
|
|
37
|
+
}
|
|
38
|
+
// Run the agent and wait for completion
|
|
39
|
+
const response = await new Promise((resolve, reject) => {
|
|
40
|
+
// Set up one-time listeners
|
|
41
|
+
const onResponse = (res) => {
|
|
42
|
+
cleanup();
|
|
43
|
+
resolve(res);
|
|
44
|
+
};
|
|
45
|
+
const onError = (error) => {
|
|
46
|
+
cleanup();
|
|
47
|
+
reject(error);
|
|
48
|
+
};
|
|
49
|
+
const cleanup = () => {
|
|
50
|
+
step.agent.removeListener('response', onResponse);
|
|
51
|
+
step.agent.removeListener('error', onError);
|
|
52
|
+
};
|
|
53
|
+
step.agent.once('response', onResponse);
|
|
54
|
+
step.agent.once('error', onError);
|
|
55
|
+
// Start the agent
|
|
56
|
+
step.agent.run(input).catch(reject);
|
|
57
|
+
});
|
|
58
|
+
// Collect results
|
|
59
|
+
results.push(response);
|
|
60
|
+
totalLatency += response.meta.latency_ms || 0;
|
|
61
|
+
totalTokens += response.usage?.total_tokens || 0;
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
results,
|
|
65
|
+
totalLatency,
|
|
66
|
+
totalTokens
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Simplified chain function that accepts just agents and uses previous output as next input.
|
|
71
|
+
* The first agent must be provided with an initial input separately.
|
|
72
|
+
*
|
|
73
|
+
* @param agents - Array of agents to chain
|
|
74
|
+
* @param initialInput - Input for the first agent
|
|
75
|
+
* @returns Promise that resolves with all agent responses
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const result = await simpleChain([chatBot, planner, executor], 'Hello');
|
|
80
|
+
* // Each agent receives the previous agent's content as input
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
async function simpleChain(agents, initialInput) {
|
|
84
|
+
const steps = agents.map((agent, index) => ({
|
|
85
|
+
agent,
|
|
86
|
+
input: index === 0
|
|
87
|
+
? initialInput
|
|
88
|
+
: (results) => results[index - 1].content
|
|
89
|
+
}));
|
|
90
|
+
return chain(steps);
|
|
91
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './agent';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export * from './providers';
|
|
4
|
+
export * from './sse';
|
|
5
|
+
export * from './chain';
|
|
6
|
+
export { OpenAIProvider as openAI } from './providers';
|
|
7
|
+
export { GoogleProvider as google } from './providers';
|
|
8
|
+
export { GrokProvider as xai, GrokProvider as grok } from './providers';
|
|
9
|
+
export * from './utils/image-utils';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.grok = exports.xai = exports.google = exports.openAI = void 0;
|
|
18
|
+
__exportStar(require("./agent"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
20
|
+
__exportStar(require("./providers"), exports); // Export classes directly
|
|
21
|
+
__exportStar(require("./sse"), exports);
|
|
22
|
+
__exportStar(require("./chain"), exports);
|
|
23
|
+
// Aliases for better DX and modular imports
|
|
24
|
+
var providers_1 = require("./providers");
|
|
25
|
+
Object.defineProperty(exports, "openAI", { enumerable: true, get: function () { return providers_1.OpenAIProvider; } });
|
|
26
|
+
var providers_2 = require("./providers");
|
|
27
|
+
Object.defineProperty(exports, "google", { enumerable: true, get: function () { return providers_2.GoogleProvider; } });
|
|
28
|
+
var providers_3 = require("./providers");
|
|
29
|
+
Object.defineProperty(exports, "xai", { enumerable: true, get: function () { return providers_3.GrokProvider; } });
|
|
30
|
+
Object.defineProperty(exports, "grok", { enumerable: true, get: function () { return providers_3.GrokProvider; } });
|
|
31
|
+
__exportStar(require("./utils/image-utils"), exports);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LLMProvider, AgentTool, AgentResponse } from '../types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare class GoogleProvider implements LLMProvider {
|
|
4
|
+
private client;
|
|
5
|
+
private model;
|
|
6
|
+
constructor(model: string);
|
|
7
|
+
generate(system: string | undefined, prompt: string | any[], files: string[] | undefined, tools: AgentTool[] | undefined, config: Record<string, any> | undefined, output_schema: z.ZodType<any> | undefined, onToken: (token: string) => void): Promise<AgentResponse>;
|
|
8
|
+
}
|