@koda-sl/baker-bridge 0.23.0 → 0.24.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 +90 -51
- package/package.json +17 -3
package/README.md
CHANGED
|
@@ -1,88 +1,115 @@
|
|
|
1
1
|
# @koda-sl/baker-bridge
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
HTTP server wrapping the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) with WebSocket, SSE streaming, and async endpoints. Designed for running Claude Code as a headless agent with real-time bidirectional communication and Convex callback relay.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
This package is published to GitHub Packages. Configure your `.npmrc` first:
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
@koda-sl:registry=https://npm.pkg.github.com
|
|
7
|
+
```bash
|
|
8
|
+
npm install @koda-sl/baker-bridge
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @koda-sl/baker-bridge
|
|
16
11
|
```
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### CLI
|
|
19
16
|
|
|
20
17
|
```bash
|
|
21
|
-
|
|
18
|
+
npx @koda-sl/baker-bridge hono
|
|
22
19
|
```
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Typed client for the Baker Convex HTTP API. No Hono/Agent SDK dependencies — safe to import anywhere. Reads `BAKER_CONVEX_SITE_URL` and `BAKER_API_KEY` from env (validated at import time via `t3-env`).
|
|
21
|
+
### Programmatic
|
|
27
22
|
|
|
28
23
|
```ts
|
|
29
|
-
import {
|
|
24
|
+
import { createServer } from "@koda-sl/baker-bridge/hono";
|
|
30
25
|
|
|
31
|
-
const
|
|
32
|
-
|
|
26
|
+
const server = createServer();
|
|
27
|
+
await server.start();
|
|
28
|
+
// Server listening on http://0.0.0.0:3000
|
|
33
29
|
```
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
## Environment Variables
|
|
36
32
|
|
|
37
33
|
| Variable | Description |
|
|
38
34
|
|---|---|
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
35
|
+
| `AUTH_TOKEN` | Bearer token for authenticating requests |
|
|
36
|
+
| `BAKER_CONVEX_SITE_URL` | Convex site URL for callback relay (e.g. `https://your-deployment.convex.site`) |
|
|
37
|
+
| `BAKER_API_KEY` | API key for Convex callbacks (`bk_...`) |
|
|
38
|
+
| `ANTHROPIC_API_KEY` | Anthropic API key (required by the Agent SDK) |
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
All variables are validated at startup via `@t3-oss/env-core` + `zod`.
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
- `Tag`, `TagType`, `TAG_TYPES`, `TagResponse` — type re-exports
|
|
42
|
+
## Endpoints
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
| Method | Path | Auth | Description |
|
|
45
|
+
|--------|------|------|-------------|
|
|
46
|
+
| `GET` | `/health` | None | Health check — returns `{ status, projectDir }` |
|
|
47
|
+
| `GET` | `/ws` | Query param `?token=` | WebSocket — persistent bidirectional chat |
|
|
48
|
+
| `POST` | `/message/async` | Bearer token | Fire-and-forget with Convex callback |
|
|
49
|
+
| `POST` | `/answer-question` | Bearer token | Resolve a pending `AskUserQuestion` tool call |
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
## WebSocket Protocol
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
Connect to `/ws?token=<AUTH_TOKEN>` for real-time bidirectional communication.
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
### Client to Server
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
**Chat message:**
|
|
56
58
|
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"type": "chat",
|
|
62
|
+
"threadId": "thread_abc123",
|
|
63
|
+
"content": "Build a landing page for our new product",
|
|
64
|
+
"attachments": [
|
|
65
|
+
{ "url": "https://...", "contentType": "image/png", "filename": "mockup.png" }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
59
68
|
```
|
|
60
69
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```ts
|
|
64
|
-
import { createServer } from "@koda-sl/baker-bridge/hono";
|
|
70
|
+
**Answer a pending question:**
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"type": "answer",
|
|
75
|
+
"threadId": "thread_abc123",
|
|
76
|
+
"toolUseId": "tool_xyz",
|
|
77
|
+
"answers": { "question_key": "user response" }
|
|
78
|
+
}
|
|
68
79
|
```
|
|
69
80
|
|
|
70
|
-
###
|
|
81
|
+
### Server to Client
|
|
71
82
|
|
|
72
|
-
|
|
73
|
-
|---|---|---|
|
|
74
|
-
| `AUTH_TOKEN` | Bearer token for auth | _(required)_ |
|
|
75
|
-
| `BAKER_CONVEX_SITE_URL` | Convex site URL for callbacks | _(required)_ |
|
|
76
|
-
| `BAKER_API_KEY` | API key for Convex callbacks | _(required)_ |
|
|
77
|
-
| `ANTHROPIC_API_KEY` | Anthropic API key (required by the SDK) | _(from env)_ |
|
|
83
|
+
The server sends Claude Agent SDK events as they stream:
|
|
78
84
|
|
|
79
|
-
|
|
85
|
+
- `{ type: "assistant", data: ... }` — assistant message chunks
|
|
86
|
+
- `{ type: "tool_use", data: ... }` — tool invocations
|
|
87
|
+
- `{ type: "input_request", toolUseId, questions }` — agent needs user input
|
|
88
|
+
- `{ type: "result", costUsd, isError, errors? }` — turn complete
|
|
80
89
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
All non-streaming events are also relayed to Convex via `POST /api/chat/event`.
|
|
91
|
+
|
|
92
|
+
## Async Endpoint
|
|
93
|
+
|
|
94
|
+
For server-to-server dispatch where you don't need real-time streaming. Returns `202 Accepted` immediately and processes in the background. Results are delivered via Convex callbacks.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
curl -X POST http://localhost:3000/message/async \
|
|
98
|
+
-H "Authorization: Bearer $AUTH_TOKEN" \
|
|
99
|
+
-H "Content-Type: application/json" \
|
|
100
|
+
-d '{"threadId": "thread_abc123", "prompt": "Analyze the campaign performance"}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
On completion, the bridge calls:
|
|
104
|
+
- `POST /api/chat/event` — each SDK event (excluding stream events)
|
|
105
|
+
- `POST /api/chat/complete` — final callback with `{ threadId, isError, costUsd, errors? }`
|
|
106
|
+
|
|
107
|
+
## Architecture
|
|
108
|
+
|
|
109
|
+
- **One session per thread** — `getOrCreateSession(threadId)` ensures all messages on the same thread share an `AgentSession`, whether they arrive via WebSocket or the async endpoint.
|
|
110
|
+
- **Multi-turn via resume** — the first message creates a fresh `query()`. Subsequent messages resume with the `sessionId` so conversation context carries over.
|
|
111
|
+
- **Attachment handling** — file URLs are downloaded to `/tmp/attachments` and appended to the prompt so the agent can use its `Read` tool to view them.
|
|
112
|
+
- **Convex relay** — all SDK events (except `stream_event`) are posted to the Convex backend with exponential backoff retry (3 attempts).
|
|
86
113
|
|
|
87
114
|
## Development
|
|
88
115
|
|
|
@@ -91,3 +118,15 @@ await server.start();
|
|
|
91
118
|
pnpm --filter @koda-sl/baker-bridge dev # Watch mode with tsx
|
|
92
119
|
pnpm --filter @koda-sl/baker-bridge build # Compile to dist/
|
|
93
120
|
```
|
|
121
|
+
|
|
122
|
+
### Local linking
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pnpm --filter @koda-sl/baker-bridge link:local # Build + link for local testing
|
|
126
|
+
pnpm --filter @koda-sl/baker-bridge unlink:local # Remove link, restore registry version
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Requirements
|
|
130
|
+
|
|
131
|
+
- Node.js 18+
|
|
132
|
+
- `ANTHROPIC_API_KEY` with access to the Claude Agent SDK
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koda-sl/baker-bridge",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "HTTP server wrapping the Claude Agent SDK with SSE streaming and
|
|
3
|
+
"version": "0.24.0",
|
|
4
|
+
"description": "HTTP server wrapping the Claude Agent SDK with SSE streaming, WebSocket, and async endpoints",
|
|
5
|
+
"license": "MIT",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|
|
7
8
|
"baker-bridge": "dist/cli.js"
|
|
@@ -15,8 +16,21 @@
|
|
|
15
16
|
"files": [
|
|
16
17
|
"dist"
|
|
17
18
|
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"claude",
|
|
24
|
+
"agent-sdk",
|
|
25
|
+
"hono",
|
|
26
|
+
"sse",
|
|
27
|
+
"websocket",
|
|
28
|
+
"ai-agent",
|
|
29
|
+
"baker"
|
|
30
|
+
],
|
|
18
31
|
"scripts": {
|
|
19
|
-
"
|
|
32
|
+
"clean": "rm -rf dist",
|
|
33
|
+
"build": "rm -rf dist && tsc",
|
|
20
34
|
"dev": "tsx watch src/cli.ts",
|
|
21
35
|
"start": "node dist/cli.js",
|
|
22
36
|
"typecheck": "tsc --noEmit",
|