@godspeedai/cognate-protocol-connect-bun 0.1.1 → 0.2.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 +82 -5
- package/package.json +3 -3
- package/src/index.ts +14 -3
package/README.md
CHANGED
|
@@ -1,9 +1,86 @@
|
|
|
1
1
|
# @godspeedai/cognate-protocol-connect-bun
|
|
2
2
|
|
|
3
|
-
Serves the Connect
|
|
3
|
+
Serves a Cognate `RuntimeService` over the Connect protocol on `Bun.serve` — with authentication, payload limits, and deadlines already wired — and provides the matching fetch-based client transport.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- `connectTransport(baseUrl, { useBinaryFormat })` — connect-web fetch transport, usable from Bun and browsers.
|
|
7
|
-
- `devTokenAuthenticator` / `devToken` — `Bearer <tenant>:<principal>`; development only, not an authentication system.
|
|
5
|
+
**When to use this package:** you expose a Cognate runtime over HTTP, or you call one from Bun, and you want the transport handled. It composes [`@godspeedai/cognate-protocol-connect`](https://www.npmjs.com/package/@godspeedai/cognate-protocol-connect) (the transport-neutral route mapping); install this one when your server is Bun. For a different HTTP host, use `@godspeedai/cognate-protocol-connect` directly and register its routes on your own router.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
bun add @godspeedai/cognate-protocol-connect-bun
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires [Bun](https://bun.sh) >= 1.4.0 (the server is a `Bun.serve` transport). Depends on `@connectrpc/connect`, `@connectrpc/connect-web`, and `@godspeedai/cognate-protocol-connect`.
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
Serve a runtime and call it from a second process:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { createRuntime } from "@godspeedai/cognate-runtime-bun";
|
|
21
|
+
import { devTokenAuthenticator, serveRuntime } from "@godspeedai/cognate-protocol-connect-bun";
|
|
22
|
+
|
|
23
|
+
const runtime = await createRuntime({
|
|
24
|
+
store: "./app.sqlite",
|
|
25
|
+
agents: [/* your AgentDefinitions */],
|
|
26
|
+
policy, // kernel invocation policy
|
|
27
|
+
actions, // action authorization
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const server = serveRuntime({
|
|
31
|
+
service: runtime.service,
|
|
32
|
+
authenticate: devTokenAuthenticator, // dev helper; bring your own for production
|
|
33
|
+
port: 3000,
|
|
34
|
+
limits: { maxBodyBytes: 1_048_576, maxJsonDepth: 32, defaultDeadlineMs: 30_000 },
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
console.log(server.url); // http://127.0.0.1:3000
|
|
38
|
+
await server.stop();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
On the client side, build a transport and a remote `RuntimeService`:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { createRemoteRuntimeService } from "@godspeedai/cognate-protocol-connect";
|
|
45
|
+
import { connectTransport, devToken } from "@godspeedai/cognate-protocol-connect-bun";
|
|
46
|
+
|
|
47
|
+
const service = createRemoteRuntimeService(
|
|
48
|
+
connectTransport("http://127.0.0.1:3000", { useBinaryFormat: false }),
|
|
49
|
+
devToken, // (caller) => "tenant:principal" Bearer token
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const caller = { actor: { id: "alice", kind: "user" }, tenant: "tenant-a" };
|
|
53
|
+
const run = await service.startRun(caller, { agent: "agent.echo", input: { text: "hi" } });
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Request handling
|
|
57
|
+
|
|
58
|
+
Every request passes through the same gate, in order:
|
|
59
|
+
|
|
60
|
+
1. **Authentication** — `authenticate(headers)` resolves the caller; no caller means HTTP 401 with the Connect code `unauthenticated`.
|
|
61
|
+
2. **Body size** — a declared `content-length` over `maxBodyBytes` (default 1 MiB) is rejected with `resource_exhausted`.
|
|
62
|
+
3. **JSON depth** — values nested deeper than `maxJsonDepth` (default 32) are rejected with `invalid_argument`; malformed messages likewise.
|
|
63
|
+
4. **Deadline** — unary calls without a shorter client deadline are bounded by `defaultDeadlineMs` (default 30 s); an overrun surfaces as `deadline_exceeded`.
|
|
64
|
+
|
|
65
|
+
Errors are returned as Connect JSON (`{ code, message }`), and `ServiceError` codes from your service round-trip to Connect codes and back exactly.
|
|
66
|
+
|
|
67
|
+
## Development tokens
|
|
68
|
+
|
|
69
|
+
`devTokenAuthenticator` accepts `Authorization: Bearer <tenant>:<principalId>` and `devToken` renders a caller back to that form. They exist for development and tests — **this is not an authentication system**; swap in your own `authenticate` before exposing the server to anything real.
|
|
70
|
+
|
|
71
|
+
## Limitations
|
|
72
|
+
|
|
73
|
+
- HTTP/1.1 only, supporting unary and server-streaming calls; the protocol defines no client-streaming or bidirectional methods.
|
|
74
|
+
- The body-size check uses the declared `content-length` header.
|
|
75
|
+
- `serveRuntime` binds an ephemeral port when `port` is omitted; read the actual address from `server.url`.
|
|
76
|
+
|
|
77
|
+
## Related packages
|
|
78
|
+
|
|
79
|
+
- [`@godspeedai/cognate-protocol-connect`](https://www.npmjs.com/package/@godspeedai/cognate-protocol-connect) — the transport-neutral route mapping and remote client this package builds on.
|
|
80
|
+
- [`@godspeedai/cognate-runtime-bun`](https://www.npmjs.com/package/@godspeedai/cognate-runtime-bun) — the runtime whose `.service` you serve.
|
|
81
|
+
- [`@godspeedai/cognate-ag-ui`](https://www.npmjs.com/package/@godspeedai/cognate-ag-ui) — an SSE endpoint for AG-UI clients that rides on the same service.
|
|
82
|
+
- [`@godspeedai/cognate`](https://www.npmjs.com/package/@godspeedai/cognate) — the SDK umbrella.
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
Apache-2.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godspeedai/cognate-protocol-connect-bun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Serves the Connect runtime service on Bun.serve with authentication, payload limits, and deadlines; provides a fetch transport.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
".": "./src/index.ts"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@godspeedai/cognate-protocol-connect": "^0.
|
|
26
|
-
"@godspeedai/cognate-runtime-api": "^0.
|
|
25
|
+
"@godspeedai/cognate-protocol-connect": "^0.2.0",
|
|
26
|
+
"@godspeedai/cognate-runtime-api": "^0.2.0",
|
|
27
27
|
"@connectrpc/connect": "2.2.0",
|
|
28
28
|
"@connectrpc/connect-web": "2.2.0"
|
|
29
29
|
},
|
package/src/index.ts
CHANGED
|
@@ -80,7 +80,12 @@ export function serveRuntime(options: ServeOptions): RuntimeServer {
|
|
|
80
80
|
request = new Request(request.url, { method: request.method, headers, body: request.body ?? undefined, duplex: request.body ? "half" : undefined } as RequestInit);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
const response = await connectFetch(request);
|
|
84
|
+
// Bun's fetch caches repeated identical unary POST responses (DEBT-027); the header protects
|
|
85
|
+
// every client — including hand-rolled createConnectTransport calls without a fetch override.
|
|
86
|
+
const headers = new Headers(response.headers);
|
|
87
|
+
headers.set("cache-control", "no-store");
|
|
88
|
+
return new Response(response.body, { status: response.status, headers });
|
|
84
89
|
},
|
|
85
90
|
});
|
|
86
91
|
|
|
@@ -92,9 +97,15 @@ export function serveRuntime(options: ServeOptions): RuntimeServer {
|
|
|
92
97
|
};
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
/** A fetch-based Connect transport usable from Bun and browsers.
|
|
100
|
+
/** A fetch-based Connect transport usable from Bun and browsers.
|
|
101
|
+
*
|
|
102
|
+
* Bun's fetch caches repeated identical unary POST responses (observed on Bun 1.4.0: a client
|
|
103
|
+
* re-reading a projection kept receiving its first response until the cache entry was bypassed;
|
|
104
|
+
* recorded as DEBT-027), so this helper defaults to `cache: "no-store"` — a Bun runtime has no HTTP
|
|
105
|
+
* cache to benefit from anyway. Pass `fetch` explicitly to override. */
|
|
96
106
|
export function connectTransport(baseUrl: string, options?: { readonly useBinaryFormat?: boolean }): Transport {
|
|
97
|
-
|
|
107
|
+
const fetchNoCache = ((input: RequestInfo | URL, init?: RequestInit) => fetch(input, { ...init, cache: "no-store" })) as typeof globalThis.fetch;
|
|
108
|
+
return createConnectTransport({ baseUrl, useBinaryFormat: options?.useBinaryFormat ?? false, fetch: fetchNoCache });
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
/** Test/dev authenticator: `Bearer <tenant>:<principalId>`. Not for production use. */
|