hono-agents 0.0.0-00ba881

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 ADDED
@@ -0,0 +1,109 @@
1
+ # hono-agents
2
+
3
+ 🔥 Hono ⨉ 🧠 Cloudflare Agents
4
+
5
+ Add intelligent, stateful AI agents to your Hono app. Create persistent AI agents that can think, communicate, and evolve over time, all integrated seamlessly with your Hono application.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install agents hono hono-agents
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { Hono } from "hono";
17
+ import { Agent } from "agents";
18
+ import { agentsMiddleware } from "hono-agents";
19
+
20
+ // Define your agent classes
21
+ export class ChatAgent extends Agent {
22
+ async onRequest(request) {
23
+ return new Response("Ready to assist with chat.");
24
+ }
25
+ }
26
+
27
+ export class AssistantAgent extends Agent {
28
+ async onRequest(request) {
29
+ return new Response("I'm your AI assistant.");
30
+ }
31
+ }
32
+
33
+ // Basic setup
34
+ const app = new Hono();
35
+ app.use("*", agentsMiddleware());
36
+
37
+ // or with authentication
38
+ app.use(
39
+ "*",
40
+ agentsMiddleware({
41
+ options: {
42
+ onBeforeConnect: async (req) => {
43
+ const token = req.headers.get("authorization");
44
+ // validate token
45
+ if (!token) return new Response("Unauthorized", { status: 401 });
46
+ }
47
+ }
48
+ })
49
+ );
50
+
51
+ // With error handling
52
+ app.use("*", agentsMiddleware({ onError: (error) => console.error(error) }));
53
+
54
+ // With custom routing
55
+ app.use(
56
+ "*",
57
+ agentsMiddleware({
58
+ options: {
59
+ prefix: "agents" // Handles /agents/* routes only
60
+ }
61
+ })
62
+ );
63
+
64
+ export default app;
65
+ ```
66
+
67
+ ## Configuration
68
+
69
+ To properly configure your Cloudflare Workers project to use agents, add bindings to your `wrangler.jsonc` file:
70
+
71
+ ```json
72
+ {
73
+ "durable_objects": {
74
+ "bindings": [
75
+ { "name": "ChatAgent", "class_name": "ChatAgent" },
76
+ { "name": "AssistantAgent", "class_name": "AssistantAgent" }
77
+ ]
78
+ },
79
+ "migrations": [
80
+ {
81
+ "tag": "v1",
82
+ "new_sqlite_classes": ["ChatAgent", "AssistantAgent"]
83
+ }
84
+ ]
85
+ }
86
+ ```
87
+
88
+ ## How It Works
89
+
90
+ The `agentsMiddleware` function:
91
+
92
+ 1. Detects whether the incoming request is a WebSocket connection or standard HTTP request
93
+ 2. Routes the request to the appropriate agent
94
+ 3. Handles WebSocket upgrades for persistent connections
95
+ 4. Provides error handling and custom routing options
96
+
97
+ Agents can:
98
+
99
+ - Maintain state across requests
100
+ - Handle both HTTP and WebSocket connections
101
+ - Schedule tasks for future execution
102
+ - Communicate with AI services
103
+ - Integrate seamlessly with React applications
104
+
105
+ ## License
106
+
107
+ Learn more about Cloudflare Agents at https://www.npmjs.com/package/agents
108
+
109
+ ISC
@@ -0,0 +1,22 @@
1
+ import * as hono from "hono";
2
+ import { Env } from "hono";
3
+ import { AgentOptions } from "agents";
4
+
5
+ /**
6
+ * Configuration options for the Cloudflare Agents middleware
7
+ */
8
+ type AgentMiddlewareContext<E extends Env> = {
9
+ /** Cloudflare Agents-specific configuration options */
10
+ options?: AgentOptions<E>;
11
+ /** Optional error handler for caught errors */
12
+ onError?: (error: Error) => void;
13
+ };
14
+ /**
15
+ * Creates a middleware for handling Cloudflare Agents WebSocket and HTTP requests
16
+ * Processes both WebSocket upgrades and standard HTTP requests, delegating them to Cloudflare Agents
17
+ */
18
+ declare function agentsMiddleware<E extends Env = Env>(
19
+ ctx?: AgentMiddlewareContext<E>
20
+ ): hono.MiddlewareHandler<Env, string, {}>;
21
+
22
+ export { agentsMiddleware };
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ // src/index.ts
2
+ import { routeAgentRequest } from "agents";
3
+ import { env } from "hono/adapter";
4
+ import { createMiddleware } from "hono/factory";
5
+ function agentsMiddleware(ctx) {
6
+ return createMiddleware(async (c, next) => {
7
+ try {
8
+ const handler = isWebSocketUpgrade(c) ? handleWebSocketUpgrade : handleHttpRequest;
9
+ const response = await handler(c, ctx?.options);
10
+ return response === null ? await next() : response;
11
+ } catch (error) {
12
+ if (ctx?.onError) {
13
+ ctx.onError(error);
14
+ return next();
15
+ }
16
+ throw error;
17
+ }
18
+ });
19
+ }
20
+ function isWebSocketUpgrade(c) {
21
+ return c.req.header("upgrade")?.toLowerCase() === "websocket";
22
+ }
23
+ async function handleWebSocketUpgrade(c, options) {
24
+ const response = await routeAgentRequest(
25
+ c.req.raw,
26
+ env(c),
27
+ options
28
+ );
29
+ if (!response?.webSocket) {
30
+ return null;
31
+ }
32
+ return new Response(null, {
33
+ status: 101,
34
+ webSocket: response.webSocket
35
+ });
36
+ }
37
+ async function handleHttpRequest(c, options) {
38
+ return routeAgentRequest(c.req.raw, env(c), options);
39
+ }
40
+ export {
41
+ agentsMiddleware
42
+ };
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { AgentOptions } from \"agents\";\nimport { routeAgentRequest } from \"agents\";\nimport type { Context, Env } from \"hono\";\nimport { env } from \"hono/adapter\";\nimport { createMiddleware } from \"hono/factory\";\n\n/**\n * Configuration options for the Cloudflare Agents middleware\n */\ntype AgentMiddlewareContext<E extends Env> = {\n /** Cloudflare Agents-specific configuration options */\n options?: AgentOptions<E>;\n /** Optional error handler for caught errors */\n onError?: (error: Error) => void;\n};\n\n/**\n * Creates a middleware for handling Cloudflare Agents WebSocket and HTTP requests\n * Processes both WebSocket upgrades and standard HTTP requests, delegating them to Cloudflare Agents\n */\nexport function agentsMiddleware<E extends Env = Env>(\n ctx?: AgentMiddlewareContext<E>\n) {\n return createMiddleware<Env>(async (c, next) => {\n try {\n const handler = isWebSocketUpgrade(c)\n ? handleWebSocketUpgrade\n : handleHttpRequest;\n\n const response = await handler(c, ctx?.options);\n\n return response === null ? await next() : response;\n } catch (error) {\n if (ctx?.onError) {\n ctx.onError(error as Error);\n return next();\n }\n throw error;\n }\n });\n}\n\n/**\n * Checks if the incoming request is a WebSocket upgrade request\n * Looks for the 'upgrade' header with a value of 'websocket' (case-insensitive)\n */\nfunction isWebSocketUpgrade(c: Context): boolean {\n return c.req.header(\"upgrade\")?.toLowerCase() === \"websocket\";\n}\n\n/**\n * Handles WebSocket upgrade requests\n * Returns a WebSocket upgrade response if successful, null otherwise\n */\nasync function handleWebSocketUpgrade<E extends Env>(\n c: Context<E>,\n options?: AgentOptions<E>\n) {\n const response = await routeAgentRequest(\n c.req.raw,\n env(c) satisfies Env,\n options\n );\n\n if (!response?.webSocket) {\n return null;\n }\n\n return new Response(null, {\n status: 101,\n webSocket: response.webSocket\n });\n}\n\n/**\n * Handles standard HTTP requests\n * Forwards the request to Cloudflare Agents and returns the response\n */\nasync function handleHttpRequest<E extends Env>(\n c: Context<E>,\n options?: AgentOptions<E>\n) {\n return routeAgentRequest(c.req.raw, env(c) satisfies Env, options);\n}\n"],"mappings":";AACA,SAAS,yBAAyB;AAElC,SAAS,WAAW;AACpB,SAAS,wBAAwB;AAgB1B,SAAS,iBACd,KACA;AACA,SAAO,iBAAsB,OAAO,GAAG,SAAS;AAC9C,QAAI;AACF,YAAM,UAAU,mBAAmB,CAAC,IAChC,yBACA;AAEJ,YAAM,WAAW,MAAM,QAAQ,GAAG,KAAK,OAAO;AAE9C,aAAO,aAAa,OAAO,MAAM,KAAK,IAAI;AAAA,IAC5C,SAAS,OAAO;AACd,UAAI,KAAK,SAAS;AAChB,YAAI,QAAQ,KAAc;AAC1B,eAAO,KAAK;AAAA,MACd;AACA,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AACH;AAMA,SAAS,mBAAmB,GAAqB;AAC/C,SAAO,EAAE,IAAI,OAAO,SAAS,GAAG,YAAY,MAAM;AACpD;AAMA,eAAe,uBACb,GACA,SACA;AACA,QAAM,WAAW,MAAM;AAAA,IACrB,EAAE,IAAI;AAAA,IACN,IAAI,CAAC;AAAA,IACL;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,WAAW;AACxB,WAAO;AAAA,EACT;AAEA,SAAO,IAAI,SAAS,MAAM;AAAA,IACxB,QAAQ;AAAA,IACR,WAAW,SAAS;AAAA,EACtB,CAAC;AACH;AAMA,eAAe,kBACb,GACA,SACA;AACA,SAAO,kBAAkB,EAAE,IAAI,KAAK,IAAI,CAAC,GAAiB,OAAO;AACnE;","names":[]}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "author": "Cloudflare Inc.",
3
+ "bugs": {
4
+ "url": "https://github.com/cloudflare/agents/issues"
5
+ },
6
+ "description": "Add Cloudflare Agents to your Hono app",
7
+ "devDependencies": {
8
+ "agents": "0.0.0-00ba881",
9
+ "hono": "^4.9.7"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.js",
18
+ "require": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "keywords": [
26
+ "cloudflare",
27
+ "agents",
28
+ "hono"
29
+ ],
30
+ "license": "MIT",
31
+ "main": "src/index.ts",
32
+ "name": "hono-agents",
33
+ "peerDependencies": {
34
+ "agents": "0.0.0-00ba881",
35
+ "hono": "^4.6.17"
36
+ },
37
+ "repository": {
38
+ "directory": "packages/hono-agents",
39
+ "type": "git",
40
+ "url": "git+https://github.com/cloudflare/agents.git"
41
+ },
42
+ "scripts": {
43
+ "build": "tsx ./scripts/build.ts",
44
+ "test": "echo \"Error: no test specified\" && exit 1"
45
+ },
46
+ "type": "module",
47
+ "types": "dist/index.d.ts",
48
+ "version": "0.0.0-00ba881"
49
+ }
package/src/index.ts ADDED
@@ -0,0 +1,84 @@
1
+ import type { AgentOptions } from "agents";
2
+ import { routeAgentRequest } from "agents";
3
+ import type { Context, Env } from "hono";
4
+ import { env } from "hono/adapter";
5
+ import { createMiddleware } from "hono/factory";
6
+
7
+ /**
8
+ * Configuration options for the Cloudflare Agents middleware
9
+ */
10
+ type AgentMiddlewareContext<E extends Env> = {
11
+ /** Cloudflare Agents-specific configuration options */
12
+ options?: AgentOptions<E>;
13
+ /** Optional error handler for caught errors */
14
+ onError?: (error: Error) => void;
15
+ };
16
+
17
+ /**
18
+ * Creates a middleware for handling Cloudflare Agents WebSocket and HTTP requests
19
+ * Processes both WebSocket upgrades and standard HTTP requests, delegating them to Cloudflare Agents
20
+ */
21
+ export function agentsMiddleware<E extends Env = Env>(
22
+ ctx?: AgentMiddlewareContext<E>
23
+ ) {
24
+ return createMiddleware<Env>(async (c, next) => {
25
+ try {
26
+ const handler = isWebSocketUpgrade(c)
27
+ ? handleWebSocketUpgrade
28
+ : handleHttpRequest;
29
+
30
+ const response = await handler(c, ctx?.options);
31
+
32
+ return response === null ? await next() : response;
33
+ } catch (error) {
34
+ if (ctx?.onError) {
35
+ ctx.onError(error as Error);
36
+ return next();
37
+ }
38
+ throw error;
39
+ }
40
+ });
41
+ }
42
+
43
+ /**
44
+ * Checks if the incoming request is a WebSocket upgrade request
45
+ * Looks for the 'upgrade' header with a value of 'websocket' (case-insensitive)
46
+ */
47
+ function isWebSocketUpgrade(c: Context): boolean {
48
+ return c.req.header("upgrade")?.toLowerCase() === "websocket";
49
+ }
50
+
51
+ /**
52
+ * Handles WebSocket upgrade requests
53
+ * Returns a WebSocket upgrade response if successful, null otherwise
54
+ */
55
+ async function handleWebSocketUpgrade<E extends Env>(
56
+ c: Context<E>,
57
+ options?: AgentOptions<E>
58
+ ) {
59
+ const response = await routeAgentRequest(
60
+ c.req.raw,
61
+ env(c) satisfies Env,
62
+ options
63
+ );
64
+
65
+ if (!response?.webSocket) {
66
+ return null;
67
+ }
68
+
69
+ return new Response(null, {
70
+ status: 101,
71
+ webSocket: response.webSocket
72
+ });
73
+ }
74
+
75
+ /**
76
+ * Handles standard HTTP requests
77
+ * Forwards the request to Cloudflare Agents and returns the response
78
+ */
79
+ async function handleHttpRequest<E extends Env>(
80
+ c: Context<E>,
81
+ options?: AgentOptions<E>
82
+ ) {
83
+ return routeAgentRequest(c.req.raw, env(c) satisfies Env, options);
84
+ }