hybrid 1.2.5 → 1.2.7

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 CHANGED
@@ -1,167 +1,66 @@
1
- # Hybrid Agent Framework
2
-
3
- A flexible framework for building AI agents with plugin-based HTTP server extensions.
4
-
5
- ## Features
6
-
7
- - **AI Agent Core**: Built on AI SDK 5 with streaming and tool support
8
- - **Plugin System**: Extensible HTTP server with Hono integration
9
- - **XMTP Integration**: Built-in XMTP messaging capabilities
10
- - **Blockchain Events**: Ponder integration for blockchain event handling
11
- - **TypeScript First**: Full type safety and modern TypeScript patterns
12
-
13
- ## Quick Start
14
-
15
- ```typescript
16
- import { Agent, XMTPPlugin, PonderPlugin } from "hybrid"
17
-
18
- // Create an agent
19
- const agent = new Agent({
20
- name: "my-agent",
21
- model: "gpt-4",
22
- instructions: "You are a helpful AI assistant."
23
- })
24
-
25
- // Start the server with plugins
26
- await agent.listen({
27
- port: "3000",
28
- filter: async ({ message }) => {
29
- console.log("Received message:", message)
30
- return true // Accept all messages
31
- },
32
- plugins: [
33
- XMTPPlugin(),
34
- PonderPlugin()
35
- ]
36
- })
37
- ```
38
-
39
- ## Plugin System
40
-
41
- The framework uses a plugin-based architecture that allows you to extend the agent's HTTP server with additional functionality.
42
-
43
- ### Built-in Plugins
44
-
45
- - **XMTPPlugin**: Provides XMTP messaging capabilities
46
- - **PonderPlugin**: Handles blockchain events via Ponder
47
-
48
- ### Creating Custom Plugins
49
-
50
- ```typescript
51
- import type { Plugin } from "hybrid"
52
- import { Hono } from "hono"
53
-
54
- function MyCustomPlugin(): Plugin {
55
- return {
56
- name: "my-custom",
57
- description: "My custom functionality",
58
- apply: (app) => {
59
- app.get("/custom", (c) => c.json({ message: "Hello from custom plugin!" }))
60
- }
61
- }
62
- }
63
-
64
- // Use the plugin
65
- const agent = new Agent({
66
- name: "my-agent",
67
- model: "gpt-4",
68
- instructions: "You are a helpful AI assistant."
69
- })
70
-
71
- // Start server with plugins
72
- await agent.listen({
73
- port: "3000",
74
- plugins: [
75
- XMTPPlugin(),
76
- PonderPlugin(),
77
- MyCustomPlugin()
78
- ]
79
- })
80
- ```
1
+ # Hybrid - Typescript Framework for building commerce-connected AI Agents.
81
2
 
82
- ### Plugin Registry
3
+ An open-source agent framework for building conversational AI agents on XMTP.
83
4
 
84
- You can also register plugins dynamically:
5
+ Hybrid makes it easy for developers to create intelligent agents that can understand natural language, process messages, and respond through XMTP's decentralized messaging protocol.
85
6
 
86
- ```typescript
87
- // Register a plugin after agent creation
88
- agent.use(MyCustomPlugin())
7
+ See [http://hybriddev.com](http://hybrid.dev) for more information.
89
8
 
90
- // Check registered plugins
91
- console.log(`Agent has ${agent.plugins.size} plugins`)
9
+ ## 📦 Quickstart
92
10
 
93
- // Get a specific plugin
94
- const plugin = agent.plugins.get("my-custom")
11
+ Getting started with Hybrid is simple:
95
12
 
96
- // Check if a plugin is registered
97
- if (agent.plugins.has("xmtp")) {
98
- console.log("XMTP plugin is registered")
99
- }
100
- ```
13
+ ### 1. Initialize your project
101
14
 
102
- ### Plugin Context
103
-
104
- Plugins receive a context object with the agent instance:
105
-
106
- ```typescript
107
- function MyPlugin(): Plugin {
108
- return {
109
- name: "my-plugin",
110
- description: "My plugin",
111
- apply: (app, context) => {
112
- if (context) {
113
- console.log(`Plugin applied to agent: ${context.agent.name}`)
114
- }
115
-
116
- app.get("/my-endpoint", (c) => c.json({ message: "Hello!" }))
117
- }
118
- }
119
- }
15
+ ```bash
16
+ npm create hybrid my-agent
17
+ cd my-agent
120
18
  ```
121
19
 
122
- ## Architecture
20
+ This creates all the necessary files and configuration for your agent.
123
21
 
124
- The framework consists of several core components:
22
+ ### 2. Get your OpenRouter API key
23
+
24
+ Visit [OpenRouter](https://openrouter.ai/keys), create an account and generate an API key
125
25
 
126
- - **Agent**: Main AI agent with streaming and tool support
127
- - **Plugin System**: Extensible HTTP server architecture with Hono
128
- - **Tool System**: AI SDK compatible tool framework
129
- - **Server**: Hono-based HTTP server with plugin support
26
+ Add it to your `.env` file:
130
27
 
131
- ### Plugin Lifecycle
28
+ ```env
29
+ OPENROUTER_API_KEY=your_openrouter_api_key_here
30
+ ```
132
31
 
133
- 1. **Registration**: Plugins are registered during agent creation or via `agent.use()`
134
- 2. **Application**: When `agent.listen()` is called, all plugins are applied to the Hono app
135
- 3. **Execution**: Plugins can add routes, middleware, and other functionality to the app
32
+ ### 3. Generate XMTP keys
136
33
 
137
- ## Examples
34
+ ```bash
35
+ hybrid keys
36
+ ```
138
37
 
139
- See the `examples/` directory for complete usage examples:
38
+ or automatically add it to your `.env` file:
140
39
 
141
- - `plugin-usage.ts`: Comprehensive plugin usage examples
142
- - Basic plugin registration
143
- - Dynamic plugin registration
144
- - Custom plugin creation
145
- - Plugin registry inspection
146
- - Server startup with plugins
40
+ ```bash
41
+ hybrid keys --write
42
+ ```
147
43
 
148
- ## Development
44
+ ### 4. Register your wallet with XMTP
149
45
 
150
46
  ```bash
151
- # Install dependencies
152
- pnpm install
47
+ hybrid register
48
+ ```
153
49
 
154
- # Build the package
155
- pnpm build
50
+ This generates secure wallet and encryption keys for your XMTP agent.
156
51
 
157
- # Run tests
158
- pnpm test
52
+ ### 5. Register your wallet with XMTP
159
53
 
160
- # Type check
161
- pnpm typecheck
54
+ ```bash
55
+ hybrid register
162
56
  ```
163
57
 
164
- ## License
58
+ ### 6. Start developing
59
+
60
+ ```bash
61
+ hybrid dev
62
+ ```
165
63
 
166
- MIT
64
+ Your agent will start listening for XMTP messages and you're ready to build!
167
65
 
66
+ Go to [https://xmtp.chat/dm/](https://xmtp.chat/dm/) and send a message to your agent.
package/README.md.old ADDED
@@ -0,0 +1,167 @@
1
+ # Hybrid Agent Framework
2
+
3
+ A flexible framework for building AI agents with plugin-based HTTP server extensions.
4
+
5
+ ## Features
6
+
7
+ - **AI Agent Core**: Built on AI SDK 5 with streaming and tool support
8
+ - **Plugin System**: Extensible HTTP server with Hono integration
9
+ - **XMTP Integration**: Built-in XMTP messaging capabilities
10
+ - **Blockchain Events**: Ponder integration for blockchain event handling
11
+ - **TypeScript First**: Full type safety and modern TypeScript patterns
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { Agent, XMTPPlugin, PonderPlugin } from "hybrid"
17
+
18
+ // Create an agent
19
+ const agent = new Agent({
20
+ name: "my-agent",
21
+ model: "gpt-4",
22
+ instructions: "You are a helpful AI assistant."
23
+ })
24
+
25
+ // Start the server with plugins
26
+ await agent.listen({
27
+ port: "3000",
28
+ filter: async ({ message }) => {
29
+ console.log("Received message:", message)
30
+ return true // Accept all messages
31
+ },
32
+ plugins: [
33
+ XMTPPlugin(),
34
+ PonderPlugin()
35
+ ]
36
+ })
37
+ ```
38
+
39
+ ## Plugin System
40
+
41
+ The framework uses a plugin-based architecture that allows you to extend the agent's HTTP server with additional functionality.
42
+
43
+ ### Built-in Plugins
44
+
45
+ - **XMTPPlugin**: Provides XMTP messaging capabilities
46
+ - **PonderPlugin**: Handles blockchain events via Ponder
47
+
48
+ ### Creating Custom Plugins
49
+
50
+ ```typescript
51
+ import type { Plugin } from "hybrid"
52
+ import { Hono } from "hono"
53
+
54
+ function MyCustomPlugin(): Plugin {
55
+ return {
56
+ name: "my-custom",
57
+ description: "My custom functionality",
58
+ apply: (app) => {
59
+ app.get("/custom", (c) => c.json({ message: "Hello from custom plugin!" }))
60
+ }
61
+ }
62
+ }
63
+
64
+ // Use the plugin
65
+ const agent = new Agent({
66
+ name: "my-agent",
67
+ model: "gpt-4",
68
+ instructions: "You are a helpful AI assistant."
69
+ })
70
+
71
+ // Start server with plugins
72
+ await agent.listen({
73
+ port: "3000",
74
+ plugins: [
75
+ XMTPPlugin(),
76
+ PonderPlugin(),
77
+ MyCustomPlugin()
78
+ ]
79
+ })
80
+ ```
81
+
82
+ ### Plugin Registry
83
+
84
+ You can also register plugins dynamically:
85
+
86
+ ```typescript
87
+ // Register a plugin after agent creation
88
+ agent.use(MyCustomPlugin())
89
+
90
+ // Check registered plugins
91
+ console.log(`Agent has ${agent.plugins.size} plugins`)
92
+
93
+ // Get a specific plugin
94
+ const plugin = agent.plugins.get("my-custom")
95
+
96
+ // Check if a plugin is registered
97
+ if (agent.plugins.has("xmtp")) {
98
+ console.log("XMTP plugin is registered")
99
+ }
100
+ ```
101
+
102
+ ### Plugin Context
103
+
104
+ Plugins receive a context object with the agent instance:
105
+
106
+ ```typescript
107
+ function MyPlugin(): Plugin {
108
+ return {
109
+ name: "my-plugin",
110
+ description: "My plugin",
111
+ apply: (app, context) => {
112
+ if (context) {
113
+ console.log(`Plugin applied to agent: ${context.agent.name}`)
114
+ }
115
+
116
+ app.get("/my-endpoint", (c) => c.json({ message: "Hello!" }))
117
+ }
118
+ }
119
+ }
120
+ ```
121
+
122
+ ## Architecture
123
+
124
+ The framework consists of several core components:
125
+
126
+ - **Agent**: Main AI agent with streaming and tool support
127
+ - **Plugin System**: Extensible HTTP server architecture with Hono
128
+ - **Tool System**: AI SDK compatible tool framework
129
+ - **Server**: Hono-based HTTP server with plugin support
130
+
131
+ ### Plugin Lifecycle
132
+
133
+ 1. **Registration**: Plugins are registered during agent creation or via `agent.use()`
134
+ 2. **Application**: When `agent.listen()` is called, all plugins are applied to the Hono app
135
+ 3. **Execution**: Plugins can add routes, middleware, and other functionality to the app
136
+
137
+ ## Examples
138
+
139
+ See the `examples/` directory for complete usage examples:
140
+
141
+ - `plugin-usage.ts`: Comprehensive plugin usage examples
142
+ - Basic plugin registration
143
+ - Dynamic plugin registration
144
+ - Custom plugin creation
145
+ - Plugin registry inspection
146
+ - Server startup with plugins
147
+
148
+ ## Development
149
+
150
+ ```bash
151
+ # Install dependencies
152
+ pnpm install
153
+
154
+ # Build the package
155
+ pnpm build
156
+
157
+ # Run tests
158
+ pnpm test
159
+
160
+ # Type check
161
+ pnpm typecheck
162
+ ```
163
+
164
+ ## License
165
+
166
+ MIT
167
+
package/dist/index.cjs CHANGED
@@ -120,8 +120,24 @@ function generateXMTPToolsToken(payload) {
120
120
  var BG_STARTED = Symbol("BG_STARTED");
121
121
  var BG_STATE = Symbol("BG_STATE");
122
122
  var BG_STOP = Symbol("BG_STOP");
123
- function sleep(ms) {
124
- return new Promise((r) => setTimeout(r, ms));
123
+ function sleep(ms, signal) {
124
+ return new Promise((resolve, reject) => {
125
+ if (signal?.aborted) {
126
+ reject(new Error("AbortError"));
127
+ return;
128
+ }
129
+ const timeout = setTimeout(resolve, ms);
130
+ if (signal) {
131
+ signal.addEventListener(
132
+ "abort",
133
+ () => {
134
+ clearTimeout(timeout);
135
+ reject(new Error("AbortError"));
136
+ },
137
+ { once: true }
138
+ );
139
+ }
140
+ });
125
141
  }
126
142
  function createBackgroundMessageProcessor(opts) {
127
143
  if (!opts?.agent || !opts?.xmtpClient) {
@@ -294,10 +310,18 @@ function createBackgroundMessageProcessor(opts) {
294
310
  );
295
311
  }
296
312
  }
297
- await sleep(nextDelay);
313
+ try {
314
+ await sleep(nextDelay, signal);
315
+ } catch (error) {
316
+ if (error instanceof Error && error.name === "AbortError") {
317
+ break;
318
+ }
319
+ throw error;
320
+ }
298
321
  }
299
322
  try {
300
323
  if (state.listenerRunning) {
324
+ console.log("[XMTP Background] Stopping message listener...");
301
325
  await listener.stop();
302
326
  }
303
327
  } catch (error) {
@@ -392,11 +416,51 @@ async function listen({
392
416
  app.notFound((c) => {
393
417
  return c.json({ error: "Not found" }, 404);
394
418
  });
395
- (0, import_node_server.serve)({
396
- fetch: app.fetch,
397
- port: Number.parseInt(port || "8454")
419
+ const httpPort = Number.parseInt(port || "8454");
420
+ const shutdown = async () => {
421
+ console.log("Waiting for graceful termination...");
422
+ try {
423
+ stopBackground();
424
+ } catch (error) {
425
+ console.error("Error stopping background processor:", error);
426
+ }
427
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
428
+ };
429
+ process.once("SIGINT", async () => {
430
+ await shutdown();
431
+ process.exit(0);
432
+ });
433
+ process.once("SIGTERM", async () => {
434
+ await shutdown();
435
+ process.exit(0);
436
+ });
437
+ process.on("uncaughtException", async (error) => {
438
+ console.error("Uncaught exception:", error);
439
+ await shutdown();
440
+ process.exit(1);
398
441
  });
399
- console.log(`\u2705 XMTP Tools HTTP Server running`);
442
+ process.on("unhandledRejection", async (reason) => {
443
+ console.error("Unhandled rejection:", reason);
444
+ await shutdown();
445
+ process.exit(1);
446
+ });
447
+ try {
448
+ (0, import_node_server.serve)({
449
+ fetch: app.fetch,
450
+ port: httpPort
451
+ });
452
+ console.log(`\u2705 XMTP Tools HTTP Server running on port ${httpPort}`);
453
+ } catch (error) {
454
+ if (error.code === "EADDRINUSE") {
455
+ console.error(
456
+ `\u274C Port ${httpPort} is already in use. Please stop the existing server or use a different port.`
457
+ );
458
+ process.exit(1);
459
+ } else {
460
+ console.error("Server error:", error);
461
+ process.exit(1);
462
+ }
463
+ }
400
464
  }
401
465
 
402
466
  // src/core/plugin.ts