@koda-sl/baker-bridge 0.23.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 +93 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/hono/agent.d.ts +24 -0
- package/dist/hono/agent.d.ts.map +1 -0
- package/dist/hono/agent.js +113 -0
- package/dist/hono/agent.js.map +1 -0
- package/dist/hono/attachments.d.ts +11 -0
- package/dist/hono/attachments.d.ts.map +1 -0
- package/dist/hono/attachments.js +43 -0
- package/dist/hono/attachments.js.map +1 -0
- package/dist/hono/callback.d.ts +5 -0
- package/dist/hono/callback.d.ts.map +1 -0
- package/dist/hono/callback.js +30 -0
- package/dist/hono/callback.js.map +1 -0
- package/dist/hono/convex.d.ts +2 -0
- package/dist/hono/convex.d.ts.map +1 -0
- package/dist/hono/convex.js +33 -0
- package/dist/hono/convex.js.map +1 -0
- package/dist/hono/env.d.ts +6 -0
- package/dist/hono/env.d.ts.map +1 -0
- package/dist/hono/env.js +11 -0
- package/dist/hono/env.js.map +1 -0
- package/dist/hono/server.d.ts +7 -0
- package/dist/hono/server.d.ts.map +1 -0
- package/dist/hono/server.js +158 -0
- package/dist/hono/server.js.map +1 -0
- package/dist/hono/types.d.ts +24 -0
- package/dist/hono/types.d.ts.map +1 -0
- package/dist/hono/types.js +2 -0
- package/dist/hono/types.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# @koda-sl/baker-bridge
|
|
2
|
+
|
|
3
|
+
> STATUS: WIP
|
|
4
|
+
|
|
5
|
+
Two exports:
|
|
6
|
+
|
|
7
|
+
- **`@koda-sl/baker-bridge/hono`** — HTTP server wrapping the Claude Agent SDK with SSE streaming and sync endpoints
|
|
8
|
+
- **`@koda-sl/baker-bridge/client`** — Lightweight client for the Baker API (zero dependencies, global `fetch` only)
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
This package is published to GitHub Packages. Configure your `.npmrc` first:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
@koda-sl:registry=https://npm.pkg.github.com
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Then install:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add @koda-sl/baker-bridge
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## `@koda-sl/baker-bridge/client`
|
|
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`).
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { fetchTags } from "@koda-sl/baker-bridge/client";
|
|
30
|
+
|
|
31
|
+
const tags = await fetchTags();
|
|
32
|
+
// TagResponse — array of Tag objects with Convex system fields
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Environment variables
|
|
36
|
+
|
|
37
|
+
| Variable | Description |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `BAKER_CONVEX_SITE_URL` | Convex site URL (e.g. `https://your-deployment.convex.site`) |
|
|
40
|
+
| `BAKER_API_KEY` | API key for Bearer auth (`bk_...`) |
|
|
41
|
+
|
|
42
|
+
### Exports
|
|
43
|
+
|
|
44
|
+
- `fetchTags()` — fetch all tags for the authenticated company
|
|
45
|
+
- `Tag`, `TagType`, `TAG_TYPES`, `TagResponse` — type re-exports
|
|
46
|
+
|
|
47
|
+
### Requirements
|
|
48
|
+
|
|
49
|
+
- Node 18+ (uses global `fetch`)
|
|
50
|
+
|
|
51
|
+
## `@koda-sl/baker-bridge/hono`
|
|
52
|
+
|
|
53
|
+
HTTP server wrapping the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk).
|
|
54
|
+
|
|
55
|
+
### CLI
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx @koda-sl/baker-bridge
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Programmatic
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { createServer } from "@koda-sl/baker-bridge/hono";
|
|
65
|
+
|
|
66
|
+
const server = createServer();
|
|
67
|
+
await server.start();
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Environment variables
|
|
71
|
+
|
|
72
|
+
| Variable | Description | Default |
|
|
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)_ |
|
|
78
|
+
|
|
79
|
+
### Endpoints
|
|
80
|
+
|
|
81
|
+
| Method | Path | Auth | Description |
|
|
82
|
+
|--------|------|------|-------------|
|
|
83
|
+
| `GET` | `/health` | None | Health check — returns `{ status, projectDir }` |
|
|
84
|
+
| `POST` | `/message` | Bearer token | SSE streaming chat |
|
|
85
|
+
| `POST` | `/message/async` | Bearer token | Fire-and-forget with Convex callback |
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# From monorepo root
|
|
91
|
+
pnpm --filter @koda-sl/baker-bridge dev # Watch mode with tsx
|
|
92
|
+
pnpm --filter @koda-sl/baker-bridge build # Compile to dist/
|
|
93
|
+
```
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,QAAA,MAAM,IAAI,UAAwB,CAAC;AACnC,QAAA,MAAM,OAAO,QAAU,CAAC;AAExB,iBAAS,UAAU,IAAI,IAAI,CAQ1B;AAED,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBnC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const args = process.argv.slice(2);
|
|
4
|
+
const command = args[0];
|
|
5
|
+
function printUsage() {
|
|
6
|
+
console.error("Usage: baker-bridge <command>");
|
|
7
|
+
console.error("");
|
|
8
|
+
console.error("Commands:");
|
|
9
|
+
console.error(" hono Start the Hono HTTP server");
|
|
10
|
+
console.error("");
|
|
11
|
+
console.error("Options:");
|
|
12
|
+
console.error(" --help Show this help message");
|
|
13
|
+
}
|
|
14
|
+
async function main() {
|
|
15
|
+
if (!command || command === "--help" || command === "-h") {
|
|
16
|
+
printUsage();
|
|
17
|
+
process.exit(command ? 0 : 1);
|
|
18
|
+
}
|
|
19
|
+
if (command === "hono") {
|
|
20
|
+
const { createServer } = await import("./hono/server.js");
|
|
21
|
+
const server = createServer();
|
|
22
|
+
await server.start();
|
|
23
|
+
process.on("SIGINT", () => server.stop());
|
|
24
|
+
process.on("SIGTERM", () => server.stop());
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
console.error(`Unknown command: ${command}`);
|
|
28
|
+
printUsage();
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
main().catch((error) => {
|
|
32
|
+
console.error("Fatal error:", error);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AAEA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAExB,SAAS,UAAU;IACjB,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IAC/C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3B,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAChE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACzD,UAAU,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAC7C,UAAU,EAAE,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { SDKMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
import type { ChatAttachment } from "./types.ts";
|
|
3
|
+
interface StreamCallbacks {
|
|
4
|
+
onMessage: (msg: SDKMessage) => void;
|
|
5
|
+
onInputRequest: (toolUseId: string, questions: unknown) => void;
|
|
6
|
+
onComplete: (costUsd: number, isError: boolean, errors?: string[]) => void;
|
|
7
|
+
}
|
|
8
|
+
declare class AgentSession {
|
|
9
|
+
readonly threadId: string;
|
|
10
|
+
private sessionId;
|
|
11
|
+
private pendingQuestions;
|
|
12
|
+
private handlerCtx;
|
|
13
|
+
private options;
|
|
14
|
+
constructor(threadId: string);
|
|
15
|
+
sendAndStream(content: string, callbacks: StreamCallbacks, attachments?: ChatAttachment[]): Promise<void>;
|
|
16
|
+
resolveQuestion(toolUseId: string, answers: Record<string, string>): boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get or create a session for a thread. All code paths (WS, async) MUST use
|
|
20
|
+
* this function so every message on the same thread hits the same session.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getOrCreateSession(threadId: string): AgentSession;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/hono/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAG1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAcjD,UAAU,eAAe;IACvB,SAAS,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAChE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC5E;AAUD,cAAM,YAAY;IAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,gBAAgB,CAAsC;IAC9D,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,OAAO,CAAU;gBAEb,QAAQ,EAAE,MAAM;IAMtB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC/G,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO;CAS7E;AAsED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CASjE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
import { buildAttachmentPromptSuffix, downloadAttachments } from "./attachments.js";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// AgentSession — wraps query() with resume for multi-turn
|
|
5
|
+
//
|
|
6
|
+
// One session per thread. The first message creates a fresh query().
|
|
7
|
+
// Subsequent messages create a new query() with `resume: sessionId`
|
|
8
|
+
// so the conversation context carries over between turns.
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
class AgentSession {
|
|
11
|
+
threadId;
|
|
12
|
+
sessionId;
|
|
13
|
+
pendingQuestions = new Map();
|
|
14
|
+
handlerCtx;
|
|
15
|
+
options;
|
|
16
|
+
constructor(threadId) {
|
|
17
|
+
this.threadId = threadId;
|
|
18
|
+
this.handlerCtx = { threadId, pendingQuestions: this.pendingQuestions, onInputRequest: null };
|
|
19
|
+
this.options = buildSessionOptions(this.handlerCtx);
|
|
20
|
+
}
|
|
21
|
+
async sendAndStream(content, callbacks, attachments) {
|
|
22
|
+
let costUsd = 0;
|
|
23
|
+
this.handlerCtx.onInputRequest = callbacks.onInputRequest;
|
|
24
|
+
try {
|
|
25
|
+
// Download attachments to local filesystem and append paths to prompt
|
|
26
|
+
let prompt = content;
|
|
27
|
+
if (attachments && attachments.length > 0) {
|
|
28
|
+
const paths = await downloadAttachments(attachments);
|
|
29
|
+
prompt += buildAttachmentPromptSuffix(paths);
|
|
30
|
+
}
|
|
31
|
+
const opts = this.sessionId ? { ...this.options, resume: this.sessionId } : this.options;
|
|
32
|
+
const q = query({ prompt, options: opts });
|
|
33
|
+
for await (const msg of q) {
|
|
34
|
+
// Capture session ID for resuming subsequent turns
|
|
35
|
+
if (msg.session_id) {
|
|
36
|
+
this.sessionId = msg.session_id;
|
|
37
|
+
}
|
|
38
|
+
callbacks.onMessage(msg);
|
|
39
|
+
if (msg.type === "result") {
|
|
40
|
+
costUsd = msg.total_cost_usd;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
callbacks.onComplete(costUsd, false);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
47
|
+
console.error("Agent session error:", message);
|
|
48
|
+
callbacks.onComplete(costUsd, true, [message]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
resolveQuestion(toolUseId, answers) {
|
|
52
|
+
const pending = this.pendingQuestions.get(toolUseId);
|
|
53
|
+
if (!pending) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
pending.resolve(answers);
|
|
57
|
+
this.pendingQuestions.delete(toolUseId);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Session registry — shared across WS and async paths
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
const sessions = new Map();
|
|
65
|
+
async function handleAskUserQuestion(input, toolUseID, ctx) {
|
|
66
|
+
// Notify the client about the pending question via WS
|
|
67
|
+
ctx.onInputRequest?.(toolUseID, input.questions);
|
|
68
|
+
const answers = await new Promise((resolve) => {
|
|
69
|
+
ctx.pendingQuestions.set(toolUseID, { resolve });
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
behavior: "allow",
|
|
73
|
+
updatedInput: { questions: input.questions, answers },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const toolHandlers = {
|
|
77
|
+
AskUserQuestion: handleAskUserQuestion,
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Build SDK options with settingSources, cwd, and canUseTool dispatcher.
|
|
81
|
+
* No permissionMode — the CLI routes every tool through canUseTool via
|
|
82
|
+
* --permission-prompt-tool stdio. Our callback returns "allow" for
|
|
83
|
+
* everything except AskUserQuestion (which awaits user answers).
|
|
84
|
+
*/
|
|
85
|
+
function buildSessionOptions(handlerCtx) {
|
|
86
|
+
return {
|
|
87
|
+
model: "claude-sonnet-4-6",
|
|
88
|
+
cwd: process.cwd(),
|
|
89
|
+
settingSources: ["project"],
|
|
90
|
+
includePartialMessages: true,
|
|
91
|
+
canUseTool: async (toolName, input, opts) => {
|
|
92
|
+
const handler = toolHandlers[toolName];
|
|
93
|
+
if (handler) {
|
|
94
|
+
return await handler(input, opts.toolUseID, handlerCtx);
|
|
95
|
+
}
|
|
96
|
+
return { behavior: "allow", updatedInput: input };
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get or create a session for a thread. All code paths (WS, async) MUST use
|
|
102
|
+
* this function so every message on the same thread hits the same session.
|
|
103
|
+
*/
|
|
104
|
+
export function getOrCreateSession(threadId) {
|
|
105
|
+
const existing = sessions.get(threadId);
|
|
106
|
+
if (existing) {
|
|
107
|
+
return existing;
|
|
108
|
+
}
|
|
109
|
+
const session = new AgentSession(threadId);
|
|
110
|
+
sessions.set(threadId, session);
|
|
111
|
+
return session;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/hono/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ChatAttachment } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Download attachments to the sandbox filesystem and return the local paths.
|
|
4
|
+
* The AI agent can then use its Read tool to view images or read documents.
|
|
5
|
+
*/
|
|
6
|
+
export declare function downloadAttachments(attachments: ChatAttachment[]): Promise<string[]>;
|
|
7
|
+
/**
|
|
8
|
+
* Build prompt suffix that tells the AI about downloaded attachments.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildAttachmentPromptSuffix(paths: string[]): string;
|
|
11
|
+
//# sourceMappingURL=attachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/hono/attachments.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4B1F;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAMnE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const ATTACHMENTS_DIR = "/tmp/attachments";
|
|
4
|
+
/**
|
|
5
|
+
* Download attachments to the sandbox filesystem and return the local paths.
|
|
6
|
+
* The AI agent can then use its Read tool to view images or read documents.
|
|
7
|
+
*/
|
|
8
|
+
export async function downloadAttachments(attachments) {
|
|
9
|
+
if (attachments.length === 0) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
await mkdir(ATTACHMENTS_DIR, { recursive: true });
|
|
13
|
+
const paths = [];
|
|
14
|
+
for (const att of attachments) {
|
|
15
|
+
const sanitized = att.filename.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
16
|
+
const localPath = join(ATTACHMENTS_DIR, `${Date.now()}-${sanitized}`);
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(att.url);
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
console.error(`Failed to download attachment ${att.filename}: ${response.status}`);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
24
|
+
await writeFile(localPath, buffer);
|
|
25
|
+
paths.push(localPath);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(`Failed to download attachment ${att.filename}:`, err);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return paths;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build prompt suffix that tells the AI about downloaded attachments.
|
|
35
|
+
*/
|
|
36
|
+
export function buildAttachmentPromptSuffix(paths) {
|
|
37
|
+
if (paths.length === 0) {
|
|
38
|
+
return "";
|
|
39
|
+
}
|
|
40
|
+
const fileList = paths.map((p) => `- ${p}`).join("\n");
|
|
41
|
+
return `\n\nThe user attached the following files. Use the Read tool to view them:\n${fileList}`;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/hono/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAE3C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,WAA6B;IACrE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAElD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,SAAS,EAAE,CAAC,CAAC;QAEtE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBACnF,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;YACzD,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAe;IACzD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,+EAA+E,QAAQ,EAAE,CAAC;AACnG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../src/hono/callback.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B9E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getOrCreateSession } from "./agent.js";
|
|
2
|
+
import { postToConvex } from "./convex.js";
|
|
3
|
+
export { postToConvex };
|
|
4
|
+
export async function processAsync(request) {
|
|
5
|
+
const { prompt, threadId, attachments } = request;
|
|
6
|
+
// Use the shared registry — same session across async and WS paths
|
|
7
|
+
const session = getOrCreateSession(threadId);
|
|
8
|
+
await session.sendAndStream(prompt, {
|
|
9
|
+
onMessage: (msg) => {
|
|
10
|
+
if (msg.type !== "stream_event") {
|
|
11
|
+
void postToConvex("/api/chat/event", { threadId, event: msg });
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
onInputRequest: () => {
|
|
15
|
+
// Input requests are posted to Convex inside canUseTool (AgentSession)
|
|
16
|
+
},
|
|
17
|
+
onComplete: async (costUsd, isError, errors) => {
|
|
18
|
+
const ok = await postToConvex("/api/chat/complete", {
|
|
19
|
+
threadId,
|
|
20
|
+
isError,
|
|
21
|
+
costUsd,
|
|
22
|
+
...(errors && { errors }),
|
|
23
|
+
});
|
|
24
|
+
if (!ok) {
|
|
25
|
+
console.error(`Thread ${threadId} completion callback failed — message may be stuck until cron cleanup`);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
}, attachments);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../src/hono/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAClD,mEAAmE;IACnE,MAAM,OAAO,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAE7C,MAAM,OAAO,CAAC,aAAa,CACzB,MAAM,EACN;QACE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YACjB,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBAChC,KAAK,YAAY,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QACD,cAAc,EAAE,GAAG,EAAE;YACnB,uEAAuE;QACzE,CAAC;QACD,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7C,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,oBAAoB,EAAE;gBAClD,QAAQ;gBACR,OAAO;gBACP,OAAO;gBACP,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;aAC1B,CAAC,CAAC;YACH,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,OAAO,CAAC,KAAK,CAAC,UAAU,QAAQ,uEAAuE,CAAC,CAAC;YAC3G,CAAC;QACH,CAAC;KACF,EACD,WAAW,CACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convex.d.ts","sourceRoot":"","sources":["../../src/hono/convex.ts"],"names":[],"mappings":"AAMA,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,SAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B7G"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { env } from "./env.js";
|
|
2
|
+
function delay(ms) {
|
|
3
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4
|
+
}
|
|
5
|
+
export async function postToConvex(path, body, retries = 3) {
|
|
6
|
+
for (let attempt = 0; attempt < retries; attempt++) {
|
|
7
|
+
try {
|
|
8
|
+
const res = await fetch(`${env.BAKER_CONVEX_SITE_URL}${path}`, {
|
|
9
|
+
method: "POST",
|
|
10
|
+
headers: {
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
Authorization: `Bearer ${env.BAKER_API_KEY}`,
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify(body),
|
|
15
|
+
});
|
|
16
|
+
if (res.ok) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (attempt < retries - 1) {
|
|
20
|
+
await delay(1000 * 2 ** attempt);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
console.error(`POST to Convex ${path} attempt ${attempt + 1} failed:`, err);
|
|
25
|
+
if (attempt < retries - 1) {
|
|
26
|
+
await delay(1000 * 2 ** attempt);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
console.error(`Failed to POST to Convex ${path} after ${retries} attempts`);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=convex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convex.js","sourceRoot":"","sources":["../../src/hono/convex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,IAA6B,EAAE,OAAO,GAAG,CAAC;IACzF,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,CAAC,qBAAqB,GAAG,IAAI,EAAE,EAAE;gBAC7D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,GAAG,CAAC,aAAa,EAAE;iBAC7C;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;gBACX,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,OAAO,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kBAAkB,IAAI,YAAY,OAAO,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAC5E,IAAI,OAAO,GAAG,OAAO,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,4BAA4B,IAAI,UAAU,OAAO,WAAW,CAAC,CAAC;IAC5E,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/hono/env.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,GAAG;;;;EAOd,CAAC"}
|
package/dist/hono/env.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createEnv } from "@t3-oss/env-core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export const env = createEnv({
|
|
4
|
+
server: {
|
|
5
|
+
AUTH_TOKEN: z.string().min(1),
|
|
6
|
+
BAKER_CONVEX_SITE_URL: z.url(),
|
|
7
|
+
BAKER_API_KEY: z.string().min(1),
|
|
8
|
+
},
|
|
9
|
+
runtimeEnv: process.env,
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/hono/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE;QACN,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7B,qBAAqB,EAAE,CAAC,CAAC,GAAG,EAAE;QAC9B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KACjC;IACD,UAAU,EAAE,OAAO,CAAC,GAAG;CACxB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/hono/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA0B5B,wBAAgB,YAAY;;iBA8HR,OAAO,CAAC,IAAI,CAAC;gBAUd,OAAO,CAAC,IAAI,CAAC;EAiB/B"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { serve } from "@hono/node-server";
|
|
2
|
+
import { createNodeWebSocket } from "@hono/node-ws";
|
|
3
|
+
import { Hono } from "hono";
|
|
4
|
+
import { bearerAuth } from "hono/bearer-auth";
|
|
5
|
+
import { cors } from "hono/cors";
|
|
6
|
+
import { getOrCreateSession } from "./agent.js";
|
|
7
|
+
import { postToConvex, processAsync } from "./callback.js";
|
|
8
|
+
import { env } from "./env.js";
|
|
9
|
+
/** Relay a non-streaming event to Convex (fire-and-forget) */
|
|
10
|
+
function relayToConvex(threadId, message) {
|
|
11
|
+
if (message.type === "stream_event") {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
void postToConvex("/api/chat/event", { threadId, event: message });
|
|
15
|
+
}
|
|
16
|
+
/** Signal stream completion to Convex */
|
|
17
|
+
function signalComplete(threadId, costUsd, isError, errors) {
|
|
18
|
+
void postToConvex("/api/chat/complete", {
|
|
19
|
+
threadId,
|
|
20
|
+
isError,
|
|
21
|
+
costUsd,
|
|
22
|
+
...(errors && { errors }),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function createServer() {
|
|
26
|
+
const port = 3000;
|
|
27
|
+
const host = "0.0.0.0";
|
|
28
|
+
const app = new Hono();
|
|
29
|
+
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
|
|
30
|
+
app.use("*", cors());
|
|
31
|
+
app.use("/message/*", bearerAuth({ token: env.AUTH_TOKEN }));
|
|
32
|
+
app.use("/answer-question", bearerAuth({ token: env.AUTH_TOKEN }));
|
|
33
|
+
app.get("/health", (c) => {
|
|
34
|
+
return c.json({ status: "ok", projectDir: process.cwd() });
|
|
35
|
+
});
|
|
36
|
+
// WebSocket endpoint — persistent bidirectional communication
|
|
37
|
+
app.get("/ws", upgradeWebSocket((c) => {
|
|
38
|
+
const token = c.req.query("token");
|
|
39
|
+
return {
|
|
40
|
+
onOpen(_event, ws) {
|
|
41
|
+
if (token !== env.AUTH_TOKEN) {
|
|
42
|
+
ws.close(4001, "Unauthorized");
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
onMessage(event, ws) {
|
|
46
|
+
let msg;
|
|
47
|
+
try {
|
|
48
|
+
msg = JSON.parse(typeof event.data === "string" ? event.data : "");
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
ws.send(JSON.stringify({ type: "error", error: "Invalid JSON" }));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
switch (msg.type) {
|
|
55
|
+
case "chat": {
|
|
56
|
+
const { threadId, content, attachments } = msg;
|
|
57
|
+
const session = getOrCreateSession(threadId);
|
|
58
|
+
session.sendAndStream(content, {
|
|
59
|
+
onMessage: (m) => {
|
|
60
|
+
try {
|
|
61
|
+
ws.send(JSON.stringify({ type: m.type, data: m }));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// WS may have closed — still relay to Convex
|
|
65
|
+
}
|
|
66
|
+
relayToConvex(threadId, m);
|
|
67
|
+
},
|
|
68
|
+
onInputRequest: (toolUseId, questions) => {
|
|
69
|
+
try {
|
|
70
|
+
ws.send(JSON.stringify({ type: "input_request", toolUseId, questions }));
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// WS may have closed — question is still registered in pendingQuestions
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
onComplete: (costUsd, isError, errors) => {
|
|
77
|
+
try {
|
|
78
|
+
ws.send(JSON.stringify({ type: "result", costUsd, isError, errors }));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// WS may have closed — still signal Convex
|
|
82
|
+
}
|
|
83
|
+
signalComplete(threadId, costUsd, isError, errors);
|
|
84
|
+
},
|
|
85
|
+
}, attachments);
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "answer": {
|
|
89
|
+
const session = getOrCreateSession(msg.threadId);
|
|
90
|
+
session.resolveQuestion(msg.toolUseId, msg.answers);
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
default:
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
onClose() {
|
|
98
|
+
// Don't destroy sessions — they persist for reconnection
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}));
|
|
102
|
+
// Async endpoint — returns 202 immediately, processes in background
|
|
103
|
+
app.post("/message/async", async (c) => {
|
|
104
|
+
const body = await c.req.json();
|
|
105
|
+
if (!body.prompt) {
|
|
106
|
+
return c.json({ error: "prompt is required" }, 400);
|
|
107
|
+
}
|
|
108
|
+
if (!body.threadId) {
|
|
109
|
+
return c.json({ error: "threadId is required" }, 400);
|
|
110
|
+
}
|
|
111
|
+
processAsync(body).catch((err) => {
|
|
112
|
+
console.error("Async processing failed:", err);
|
|
113
|
+
});
|
|
114
|
+
return c.json({ status: "accepted" }, 202);
|
|
115
|
+
});
|
|
116
|
+
// Resolve a pending AskUserQuestion — HTTP fallback for non-WS clients
|
|
117
|
+
app.post("/answer-question", async (c) => {
|
|
118
|
+
const body = await c.req.json();
|
|
119
|
+
if (!body.toolUseId) {
|
|
120
|
+
return c.json({ error: "toolUseId is required" }, 400);
|
|
121
|
+
}
|
|
122
|
+
if (body.threadId) {
|
|
123
|
+
const session = getOrCreateSession(body.threadId);
|
|
124
|
+
if (session.resolveQuestion(body.toolUseId, body.answers ?? {})) {
|
|
125
|
+
return c.json({ status: "ok" });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return c.json({ error: "No pending question with that ID" }, 404);
|
|
129
|
+
});
|
|
130
|
+
let server = null;
|
|
131
|
+
function start() {
|
|
132
|
+
return new Promise((resolve) => {
|
|
133
|
+
server = serve({ fetch: app.fetch, port, hostname: host }, () => {
|
|
134
|
+
console.warn(`Agent server listening on http://${host}:${port}`);
|
|
135
|
+
resolve();
|
|
136
|
+
});
|
|
137
|
+
injectWebSocket(server);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function stop() {
|
|
141
|
+
return new Promise((resolve, reject) => {
|
|
142
|
+
if (!server) {
|
|
143
|
+
resolve();
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
server.close((err) => {
|
|
147
|
+
if (err) {
|
|
148
|
+
reject(err);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
resolve();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return { app, start, stop };
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/hono/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAG/B,8DAA8D;AAC9D,SAAS,aAAa,CAAC,QAAgB,EAAE,OAAmB;IAC1D,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QACpC,OAAO;IACT,CAAC;IACD,KAAK,YAAY,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,yCAAyC;AACzC,SAAS,cAAc,CAAC,QAAgB,EAAE,OAAe,EAAE,OAAgB,EAAE,MAAiB;IAC5F,KAAK,YAAY,CAAC,oBAAoB,EAAE;QACtC,QAAQ;QACR,OAAO;QACP,OAAO;QACP,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;KAC1B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC;IAClB,MAAM,IAAI,GAAG,SAAS,CAAC;IAEvB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,GAAG,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAE3E,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACrB,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC7D,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAEnE,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACvB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAC9D,GAAG,CAAC,GAAG,CACL,KAAK,EACL,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE;QACrB,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEnC,OAAO;YACL,MAAM,CAAC,MAAM,EAAE,EAAE;gBACf,IAAI,KAAK,KAAK,GAAG,CAAC,UAAU,EAAE,CAAC;oBAC7B,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;YACD,SAAS,CAAC,KAAK,EAAE,EAAE;gBACjB,IAAI,GAAsB,CAAC;gBAC3B,IAAI,CAAC;oBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAsB,CAAC;gBAC1F,CAAC;gBAAC,MAAM,CAAC;oBACP,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;oBAClE,OAAO;gBACT,CAAC;gBAED,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;oBACjB,KAAK,MAAM,CAAC,CAAC,CAAC;wBACZ,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;wBAC/C,MAAM,OAAO,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;wBAE7C,OAAO,CAAC,aAAa,CACnB,OAAO,EACP;4BACE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;gCACf,IAAI,CAAC;oCACH,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gCACrD,CAAC;gCAAC,MAAM,CAAC;oCACP,6CAA6C;gCAC/C,CAAC;gCACD,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;4BAC7B,CAAC;4BACD,cAAc,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE;gCACvC,IAAI,CAAC;oCACH,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;gCAC3E,CAAC;gCAAC,MAAM,CAAC;oCACP,wEAAwE;gCAC1E,CAAC;4BACH,CAAC;4BACD,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;gCACvC,IAAI,CAAC;oCACH,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;gCACxE,CAAC;gCAAC,MAAM,CAAC;oCACP,2CAA2C;gCAC7C,CAAC;gCACD,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;4BACrD,CAAC;yBACF,EACD,WAAW,CACZ,CAAC;wBACF,MAAM;oBACR,CAAC;oBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;wBACd,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;wBACjD,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;wBACpD,MAAM;oBACR,CAAC;oBACD;wBACE,MAAM;gBACV,CAAC;YACH,CAAC;YACD,OAAO;gBACL,yDAAyD;YAC3D,CAAC;SACF,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEF,oEAAoE;IACpE,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAuB,CAAC;QAErD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YAC/B,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAA6E,CAAC;QAE3G,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;gBAChE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,GAAG,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAsB,IAAI,CAAC;IAErC,SAAS,KAAK;QACZ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE;gBAC9D,OAAO,CAAC,IAAI,CAAC,oCAAoC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;gBACjE,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YACH,eAAe,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,IAAI;QACX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,CAAC,GAAsB,EAAE,EAAE;gBACtC,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACN,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ChatAttachment {
|
|
2
|
+
url: string;
|
|
3
|
+
contentType: string;
|
|
4
|
+
filename: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WSChatMessage {
|
|
7
|
+
type: "chat";
|
|
8
|
+
threadId: string;
|
|
9
|
+
content: string;
|
|
10
|
+
attachments?: ChatAttachment[];
|
|
11
|
+
}
|
|
12
|
+
export interface WSAnswerMessage {
|
|
13
|
+
type: "answer";
|
|
14
|
+
threadId: string;
|
|
15
|
+
toolUseId: string;
|
|
16
|
+
answers: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
export type IncomingWSMessage = WSChatMessage | WSAnswerMessage;
|
|
19
|
+
export interface AsyncMessageRequest {
|
|
20
|
+
prompt: string;
|
|
21
|
+
threadId: string;
|
|
22
|
+
attachments?: ChatAttachment[];
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/hono/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,eAAe,CAAC;AAGhE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/hono/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@koda-sl/baker-bridge",
|
|
3
|
+
"version": "0.23.0",
|
|
4
|
+
"description": "HTTP server wrapping the Claude Agent SDK with SSE streaming and sync endpoints",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"baker-bridge": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
"./hono": {
|
|
11
|
+
"types": "./dist/hono/server.d.ts",
|
|
12
|
+
"default": "./dist/hono/server.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"dev": "tsx watch src/cli.ts",
|
|
21
|
+
"start": "node dist/cli.js",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"link:local": "bash scripts/link-local.sh",
|
|
24
|
+
"unlink:local": "bash scripts/unlink-local.sh"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.50",
|
|
28
|
+
"@hono/node-server": "^1.0.0",
|
|
29
|
+
"@hono/node-ws": "^1.3.0",
|
|
30
|
+
"@t3-oss/env-core": "^0.13.10",
|
|
31
|
+
"hono": "^4.0.0",
|
|
32
|
+
"zod": "^4.3.6"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "25.3.0",
|
|
36
|
+
"tsx": "^4.0.0",
|
|
37
|
+
"typescript": "^5.9.3"
|
|
38
|
+
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/koda-sl/baker.git",
|
|
42
|
+
"directory": "packages/bridge"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"registry": "https://registry.npmjs.org",
|
|
46
|
+
"access": "public"
|
|
47
|
+
}
|
|
48
|
+
}
|