@schlessera/brain-ui-server 0.4.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/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/agent/backend.d.ts +30 -0
- package/dist/agent/backend.d.ts.map +1 -0
- package/dist/agent/backend.js +226 -0
- package/dist/agent/backend.js.map +1 -0
- package/dist/app.d.ts +27 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +116 -0
- package/dist/app.js.map +1 -0
- package/dist/brain/client.d.ts +43 -0
- package/dist/brain/client.d.ts.map +1 -0
- package/dist/brain/client.js +154 -0
- package/dist/brain/client.js.map +1 -0
- package/dist/brain/types.d.ts +41 -0
- package/dist/brain/types.d.ts.map +1 -0
- package/dist/brain/types.js +2 -0
- package/dist/brain/types.js.map +1 -0
- package/dist/cron/scheduler.d.ts +9 -0
- package/dist/cron/scheduler.d.ts.map +1 -0
- package/dist/cron/scheduler.js +58 -0
- package/dist/cron/scheduler.js.map +1 -0
- package/dist/db/client.d.ts +10 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +73 -0
- package/dist/db/client.js.map +1 -0
- package/dist/files/walker.d.ts +63 -0
- package/dist/files/walker.d.ts.map +1 -0
- package/dist/files/walker.js +416 -0
- package/dist/files/walker.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +59 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +246 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/passkeys.d.ts +36 -0
- package/dist/middleware/passkeys.d.ts.map +1 -0
- package/dist/middleware/passkeys.js +427 -0
- package/dist/middleware/passkeys.js.map +1 -0
- package/dist/middleware/tailscale.d.ts +31 -0
- package/dist/middleware/tailscale.d.ts.map +1 -0
- package/dist/middleware/tailscale.js +64 -0
- package/dist/middleware/tailscale.js.map +1 -0
- package/dist/render/template.d.ts +7 -0
- package/dist/render/template.d.ts.map +1 -0
- package/dist/render/template.js +112 -0
- package/dist/render/template.js.map +1 -0
- package/dist/routes/brain.d.ts +155 -0
- package/dist/routes/brain.d.ts.map +1 -0
- package/dist/routes/brain.js +250 -0
- package/dist/routes/brain.js.map +1 -0
- package/dist/routes/files.d.ts +89 -0
- package/dist/routes/files.d.ts.map +1 -0
- package/dist/routes/files.js +91 -0
- package/dist/routes/files.js.map +1 -0
- package/dist/routes/health.d.ts +37 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +27 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/providers.d.ts +33 -0
- package/dist/routes/providers.d.ts.map +1 -0
- package/dist/routes/providers.js +9 -0
- package/dist/routes/providers.js.map +1 -0
- package/dist/routes/render.d.ts +25 -0
- package/dist/routes/render.d.ts.map +1 -0
- package/dist/routes/render.js +47 -0
- package/dist/routes/render.js.map +1 -0
- package/dist/routes/sessions.d.ts +79 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +37 -0
- package/dist/routes/sessions.js.map +1 -0
- package/dist/routes/voice.d.ts +92 -0
- package/dist/routes/voice.d.ts.map +1 -0
- package/dist/routes/voice.js +64 -0
- package/dist/routes/voice.js.map +1 -0
- package/dist/voice/deepgram-token.d.ts +5 -0
- package/dist/voice/deepgram-token.d.ts.map +1 -0
- package/dist/voice/deepgram-token.js +63 -0
- package/dist/voice/deepgram-token.js.map +1 -0
- package/dist/voice/keyterm-builder.d.ts +18 -0
- package/dist/voice/keyterm-builder.d.ts.map +1 -0
- package/dist/voice/keyterm-builder.js +391 -0
- package/dist/voice/keyterm-builder.js.map +1 -0
- package/dist/voice/speech-providers.d.ts +25 -0
- package/dist/voice/speech-providers.d.ts.map +1 -0
- package/dist/voice/speech-providers.js +104 -0
- package/dist/voice/speech-providers.js.map +1 -0
- package/dist/ws/attachments.d.ts +10 -0
- package/dist/ws/attachments.d.ts.map +1 -0
- package/dist/ws/attachments.js +63 -0
- package/dist/ws/attachments.js.map +1 -0
- package/dist/ws/bridge.d.ts +7 -0
- package/dist/ws/bridge.d.ts.map +1 -0
- package/dist/ws/bridge.js +86 -0
- package/dist/ws/bridge.js.map +1 -0
- package/dist/ws/clients.d.ts +20 -0
- package/dist/ws/clients.d.ts.map +1 -0
- package/dist/ws/clients.js +48 -0
- package/dist/ws/clients.js.map +1 -0
- package/dist/ws/connection.d.ts +8 -0
- package/dist/ws/connection.d.ts.map +1 -0
- package/dist/ws/connection.js +116 -0
- package/dist/ws/connection.js.map +1 -0
- package/dist/ws/dispatch.d.ts +5 -0
- package/dist/ws/dispatch.d.ts.map +1 -0
- package/dist/ws/dispatch.js +139 -0
- package/dist/ws/dispatch.js.map +1 -0
- package/dist/ws/frames.d.ts +17 -0
- package/dist/ws/frames.d.ts.map +1 -0
- package/dist/ws/frames.js +37 -0
- package/dist/ws/frames.js.map +1 -0
- package/dist/ws/handler.d.ts +34 -0
- package/dist/ws/handler.d.ts.map +1 -0
- package/dist/ws/handler.js +33 -0
- package/dist/ws/handler.js.map +1 -0
- package/dist/ws/history.d.ts +17 -0
- package/dist/ws/history.d.ts.map +1 -0
- package/dist/ws/history.js +45 -0
- package/dist/ws/history.js.map +1 -0
- package/dist/ws/host.d.ts +40 -0
- package/dist/ws/host.d.ts.map +1 -0
- package/dist/ws/host.js +49 -0
- package/dist/ws/host.js.map +1 -0
- package/dist/ws/routing.d.ts +12 -0
- package/dist/ws/routing.d.ts.map +1 -0
- package/dist/ws/routing.js +31 -0
- package/dist/ws/routing.js.map +1 -0
- package/dist/ws/run-session.d.ts +17 -0
- package/dist/ws/run-session.d.ts.map +1 -0
- package/dist/ws/run-session.js +160 -0
- package/dist/ws/run-session.js.map +1 -0
- package/dist/ws/session-catalog.d.ts +25 -0
- package/dist/ws/session-catalog.d.ts.map +1 -0
- package/dist/ws/session-catalog.js +45 -0
- package/dist/ws/session-catalog.js.map +1 -0
- package/dist/ws/shrink.d.ts +34 -0
- package/dist/ws/shrink.d.ts.map +1 -0
- package/dist/ws/shrink.js +91 -0
- package/dist/ws/shrink.js.map +1 -0
- package/dist/ws/turns.d.ts +77 -0
- package/dist/ws/turns.d.ts.map +1 -0
- package/dist/ws/turns.js +89 -0
- package/dist/ws/turns.js.map +1 -0
- package/migrations/001_initial.sql +29 -0
- package/migrations/002_session_provider.sql +1 -0
- package/migrations/003_session_backend.sql +5 -0
- package/migrations/004_drop_gemini_backend.sql +20 -0
- package/migrations/005_passkey_credentials.sql +18 -0
- package/package.json +72 -0
- package/src/agent/backend.ts +308 -0
- package/src/app.ts +159 -0
- package/src/brain/client.ts +186 -0
- package/src/brain/types.ts +44 -0
- package/src/cron/scheduler.ts +80 -0
- package/src/db/client.ts +85 -0
- package/src/files/walker.ts +418 -0
- package/src/index.ts +39 -0
- package/src/middleware/auth.ts +321 -0
- package/src/middleware/passkeys.ts +510 -0
- package/src/middleware/tailscale.ts +81 -0
- package/src/render/template.ts +124 -0
- package/src/routes/brain.ts +305 -0
- package/src/routes/files.ts +99 -0
- package/src/routes/health.ts +29 -0
- package/src/routes/providers.ts +9 -0
- package/src/routes/render.ts +68 -0
- package/src/routes/sessions.ts +49 -0
- package/src/routes/voice.ts +80 -0
- package/src/voice/deepgram-token.ts +80 -0
- package/src/voice/keyterm-builder.ts +426 -0
- package/src/voice/speech-providers.ts +111 -0
- package/src/ws/attachments.ts +86 -0
- package/src/ws/bridge.ts +139 -0
- package/src/ws/clients.ts +57 -0
- package/src/ws/connection.ts +132 -0
- package/src/ws/dispatch.ts +162 -0
- package/src/ws/frames.ts +42 -0
- package/src/ws/handler.ts +50 -0
- package/src/ws/history.ts +51 -0
- package/src/ws/host.ts +69 -0
- package/src/ws/routing.ts +43 -0
- package/src/ws/run-session.ts +192 -0
- package/src/ws/session-catalog.ts +97 -0
- package/src/ws/shrink.ts +95 -0
- package/src/ws/turns.ts +151 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { listDirectory, readFileContent, resolveAncestors, resolveForRaw, buildWikilinkMap, NotFoundError, PathEscapeError, TooLargeError, } from "../files/walker.js";
|
|
3
|
+
let wikilinkCache = null;
|
|
4
|
+
const WIKILINK_TTL_MS = 30_000;
|
|
5
|
+
function errorResponse(err) {
|
|
6
|
+
if (err instanceof PathEscapeError) {
|
|
7
|
+
return { body: { error: "invalid_path" }, status: 400 };
|
|
8
|
+
}
|
|
9
|
+
if (err instanceof NotFoundError) {
|
|
10
|
+
return { body: { error: "not_found" }, status: 404 };
|
|
11
|
+
}
|
|
12
|
+
if (err instanceof TooLargeError) {
|
|
13
|
+
return { body: { error: "file_too_large", size: err.size }, status: 413 };
|
|
14
|
+
}
|
|
15
|
+
console.error("[files]", err);
|
|
16
|
+
return { body: { error: err instanceof Error ? err.message : "internal_error" }, status: 500 };
|
|
17
|
+
}
|
|
18
|
+
export const filesRoutes = new Hono()
|
|
19
|
+
.get("/files/tree", async (c) => {
|
|
20
|
+
const path = c.req.query("path") ?? "";
|
|
21
|
+
try {
|
|
22
|
+
const entries = await listDirectory(path);
|
|
23
|
+
return c.json({ path, entries });
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const { body, status } = errorResponse(err);
|
|
27
|
+
return c.json(body, status);
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
.get("/files/content", async (c) => {
|
|
31
|
+
const path = c.req.query("path");
|
|
32
|
+
if (!path)
|
|
33
|
+
return c.json({ error: "missing_path" }, 400);
|
|
34
|
+
const raw = c.req.query("raw") === "1";
|
|
35
|
+
try {
|
|
36
|
+
if (raw) {
|
|
37
|
+
const { abs, mime, size } = await resolveForRaw(path);
|
|
38
|
+
const file = Bun.file(abs);
|
|
39
|
+
return new Response(file, {
|
|
40
|
+
status: 200,
|
|
41
|
+
headers: {
|
|
42
|
+
"Content-Type": mime,
|
|
43
|
+
"Content-Length": String(size),
|
|
44
|
+
"Content-Disposition": "inline",
|
|
45
|
+
"X-Content-Type-Options": "nosniff",
|
|
46
|
+
"Content-Security-Policy": "default-src 'none'; img-src 'self' data:; style-src 'unsafe-inline'",
|
|
47
|
+
"Cache-Control": "private, max-age=0, must-revalidate",
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const result = await readFileContent(path);
|
|
52
|
+
return c.json({ path, ...result });
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const { body, status } = errorResponse(err);
|
|
56
|
+
return c.json(body, status);
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
.get("/files/resolve", async (c) => {
|
|
60
|
+
const path = c.req.query("path");
|
|
61
|
+
if (!path)
|
|
62
|
+
return c.json({ error: "missing_path" }, 400);
|
|
63
|
+
try {
|
|
64
|
+
const result = await resolveAncestors(path);
|
|
65
|
+
return c.json({ path, ...result });
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const { body, status } = errorResponse(err);
|
|
69
|
+
return c.json(body, status);
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
.get("/files/wikilinks", async (c) => {
|
|
73
|
+
const refresh = c.req.query("refresh") === "1";
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
try {
|
|
76
|
+
if (refresh || !wikilinkCache || now - wikilinkCache.generatedAt > WIKILINK_TTL_MS) {
|
|
77
|
+
const map = await buildWikilinkMap();
|
|
78
|
+
wikilinkCache = { generatedAt: now, map };
|
|
79
|
+
}
|
|
80
|
+
return c.json({
|
|
81
|
+
generatedAt: wikilinkCache.generatedAt,
|
|
82
|
+
count: Object.keys(wikilinkCache.map).length,
|
|
83
|
+
slugs: wikilinkCache.map,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
const { body, status } = errorResponse(err);
|
|
88
|
+
return c.json(body, status);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/routes/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const healthRoutes: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
2
|
+
"/health": {
|
|
3
|
+
$get: {
|
|
4
|
+
input: {};
|
|
5
|
+
output: {
|
|
6
|
+
status: string;
|
|
7
|
+
uptime: number;
|
|
8
|
+
timestamp: string;
|
|
9
|
+
};
|
|
10
|
+
outputFormat: "json";
|
|
11
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
}, "/", "/health">;
|
|
15
|
+
export declare const statusRoutes: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
16
|
+
"/status": {
|
|
17
|
+
$get: {
|
|
18
|
+
input: {};
|
|
19
|
+
output: {
|
|
20
|
+
healthy: true;
|
|
21
|
+
uptime: number;
|
|
22
|
+
version: string;
|
|
23
|
+
cronJobs: {
|
|
24
|
+
name: string;
|
|
25
|
+
lastRunAt: any;
|
|
26
|
+
lastStatus: any;
|
|
27
|
+
lastDurationMs: any;
|
|
28
|
+
lastError: any;
|
|
29
|
+
}[];
|
|
30
|
+
activeSession: boolean;
|
|
31
|
+
};
|
|
32
|
+
outputFormat: "json";
|
|
33
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
}, "/", "/status">;
|
|
37
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,YAAY;;;;;;;;;;;;;kBAMvB,CAAC;AAKH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;kBAQvB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { getCronStatus } from "../cron/scheduler.js";
|
|
3
|
+
import { isTurnActive } from "../ws/handler.js";
|
|
4
|
+
const startTime = Date.now();
|
|
5
|
+
// Public liveness probe. Deliberately minimal: no version/commit, no cron
|
|
6
|
+
// detail, no session oracle — this route sits in front of the auth guard and
|
|
7
|
+
// is reachable by anyone on the origin.
|
|
8
|
+
export const healthRoutes = new Hono().get("/health", (c) => {
|
|
9
|
+
return c.json({
|
|
10
|
+
status: "healthy",
|
|
11
|
+
uptime: Date.now() - startTime,
|
|
12
|
+
timestamp: new Date().toISOString(),
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
// Operational status. Registered BEHIND the auth guard: it exposes the git SHA,
|
|
16
|
+
// cron job errors (raw stderr with filesystem paths), and whether a turn is
|
|
17
|
+
// active — none of which should be readable unauthenticated.
|
|
18
|
+
export const statusRoutes = new Hono().get("/status", (c) => {
|
|
19
|
+
return c.json({
|
|
20
|
+
healthy: true,
|
|
21
|
+
uptime: Date.now() - startTime,
|
|
22
|
+
version: process.env.SOURCE_COMMIT ?? "dev",
|
|
23
|
+
cronJobs: getCronStatus(),
|
|
24
|
+
activeSession: isTurnActive(),
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAE7B,0EAA0E;AAC1E,6EAA6E;AAC7E,wCAAwC;AACxC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;IAC1D,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;QAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAChF,4EAA4E;AAC5E,6DAA6D;AAC7D,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;IAC1D,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;QAC9B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,KAAK;QAC3C,QAAQ,EAAE,aAAa,EAAE;QACzB,aAAa,EAAE,YAAY,EAAE;KAC9B,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const providerRoutes: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
2
|
+
"/providers": {
|
|
3
|
+
$get: {
|
|
4
|
+
input: {};
|
|
5
|
+
output: {
|
|
6
|
+
providers: {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
vendor?: string | undefined;
|
|
10
|
+
backendId?: string | undefined;
|
|
11
|
+
}[];
|
|
12
|
+
backends: {
|
|
13
|
+
[x: string]: {
|
|
14
|
+
id: string;
|
|
15
|
+
capabilities: {
|
|
16
|
+
resume: boolean;
|
|
17
|
+
permissions: boolean;
|
|
18
|
+
thinking: boolean;
|
|
19
|
+
attachments: boolean;
|
|
20
|
+
askUser: boolean;
|
|
21
|
+
costReporting: boolean;
|
|
22
|
+
concurrentSessions: boolean;
|
|
23
|
+
followUp: boolean;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
outputFormat: "json";
|
|
29
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}, "/", "/providers">;
|
|
33
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/routes/providers.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAKzB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { getBackendsInfo, listAllProviders } from "../agent/backend.js";
|
|
3
|
+
export const providerRoutes = new Hono().get("/providers", async (c) => {
|
|
4
|
+
return c.json({
|
|
5
|
+
providers: await listAllProviders(),
|
|
6
|
+
backends: await getBackendsInfo(),
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/routes/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAExE,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACrE,OAAO,CAAC,CAAC,IAAI,CAAC;QACZ,SAAS,EAAE,MAAM,gBAAgB,EAAE;QACnC,QAAQ,EAAE,MAAM,eAAe,EAAE;KAClC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rendering seam. The deployment owns the actual renderer process (e.g. the
|
|
3
|
+
* network-denied headless Chrome in @schlessera/brain-render-puppeteer) and
|
|
4
|
+
* injects these two functions via `createApp({ renderer })` — the package
|
|
5
|
+
* itself never spawns a browser.
|
|
6
|
+
*/
|
|
7
|
+
export interface AppRenderer {
|
|
8
|
+
renderPng(options: {
|
|
9
|
+
html: string;
|
|
10
|
+
}): Promise<Buffer | Uint8Array>;
|
|
11
|
+
renderPdf(options: {
|
|
12
|
+
html: string;
|
|
13
|
+
}): Promise<Buffer | Uint8Array>;
|
|
14
|
+
}
|
|
15
|
+
export declare function createRenderRoutes(renderer?: AppRenderer): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
16
|
+
"/render": {
|
|
17
|
+
$post: {
|
|
18
|
+
input: {};
|
|
19
|
+
output: {};
|
|
20
|
+
outputFormat: string;
|
|
21
|
+
status: import("hono/utils/http-status").StatusCode;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}, "/", "/render">;
|
|
25
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/routes/render.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACnE,SAAS,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;CACpE;AASD,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,WAAW;;;;;;;;;mBA0CxD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { buildHtmlDocument } from "../render/template.js";
|
|
4
|
+
const MAX_CONTENT_BYTES = 512 * 1024;
|
|
5
|
+
const bodySchema = z.object({
|
|
6
|
+
content: z.string().min(1).max(MAX_CONTENT_BYTES),
|
|
7
|
+
contentType: z.enum(["markdown", "html"]),
|
|
8
|
+
format: z.enum(["png", "pdf"]),
|
|
9
|
+
title: z.string().max(200).optional(),
|
|
10
|
+
});
|
|
11
|
+
export function createRenderRoutes(renderer) {
|
|
12
|
+
return new Hono().post("/render", async (c) => {
|
|
13
|
+
if (!renderer) {
|
|
14
|
+
return c.json({ error: "render_unavailable", detail: "This deployment has no renderer configured" }, 501);
|
|
15
|
+
}
|
|
16
|
+
let parsed;
|
|
17
|
+
try {
|
|
18
|
+
parsed = bodySchema.parse(await c.req.json());
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
return c.json({ error: "invalid_request", detail: err instanceof Error ? err.message : "bad body" }, 400);
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const html = buildHtmlDocument(parsed);
|
|
25
|
+
const buf = parsed.format === "png"
|
|
26
|
+
? await renderer.renderPng({ html })
|
|
27
|
+
: await renderer.renderPdf({ html });
|
|
28
|
+
const filename = (parsed.title ?? "share")
|
|
29
|
+
.replace(/[^a-z0-9_.-]+/gi, "_")
|
|
30
|
+
.slice(0, 60) || "share";
|
|
31
|
+
return new Response(new Uint8Array(buf), {
|
|
32
|
+
status: 200,
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": parsed.format === "png" ? "image/png" : "application/pdf",
|
|
35
|
+
"Content-Length": String(buf.byteLength),
|
|
36
|
+
"Content-Disposition": `inline; filename="${filename}.${parsed.format}"`,
|
|
37
|
+
"Cache-Control": "private, max-age=0, must-revalidate",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
console.error("[render]", err);
|
|
43
|
+
return c.json({ error: "render_failed", detail: err instanceof Error ? err.message : String(err) }, 500);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/routes/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export declare const sessionRoutes: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
2
|
+
"/sessions": {
|
|
3
|
+
$get: {
|
|
4
|
+
input: {};
|
|
5
|
+
output: {
|
|
6
|
+
sessions: {
|
|
7
|
+
backendId: string;
|
|
8
|
+
id: string;
|
|
9
|
+
title: string | null;
|
|
10
|
+
createdAt: number;
|
|
11
|
+
lastActiveAt: number;
|
|
12
|
+
totalCostUsd: number;
|
|
13
|
+
numTurns: number;
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
outputFormat: "json";
|
|
17
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
18
|
+
} | {
|
|
19
|
+
input: {};
|
|
20
|
+
output: {
|
|
21
|
+
error: string;
|
|
22
|
+
};
|
|
23
|
+
outputFormat: "json";
|
|
24
|
+
status: 500;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
} & {
|
|
28
|
+
"/sessions/:id": {
|
|
29
|
+
$get: {
|
|
30
|
+
input: {
|
|
31
|
+
param: {
|
|
32
|
+
id: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
output: {
|
|
36
|
+
id: string;
|
|
37
|
+
messages: {
|
|
38
|
+
role: "user" | "assistant";
|
|
39
|
+
content: string;
|
|
40
|
+
thinking?: string | undefined;
|
|
41
|
+
toolCalls: {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
input: {
|
|
45
|
+
[x: string]: import("hono/utils/types").JSONValue;
|
|
46
|
+
};
|
|
47
|
+
output?: string | undefined;
|
|
48
|
+
isError?: boolean | undefined;
|
|
49
|
+
}[];
|
|
50
|
+
parts?: ({
|
|
51
|
+
kind: "thinking";
|
|
52
|
+
text: string;
|
|
53
|
+
} | {
|
|
54
|
+
kind: "text";
|
|
55
|
+
text: string;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "tool";
|
|
58
|
+
toolIndex: number;
|
|
59
|
+
})[] | undefined;
|
|
60
|
+
attachmentCount?: number | undefined;
|
|
61
|
+
}[];
|
|
62
|
+
};
|
|
63
|
+
outputFormat: "json";
|
|
64
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
65
|
+
} | {
|
|
66
|
+
input: {
|
|
67
|
+
param: {
|
|
68
|
+
id: string;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
output: {
|
|
72
|
+
error: string;
|
|
73
|
+
};
|
|
74
|
+
outputFormat: "json";
|
|
75
|
+
status: 500;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
}, "/", "/sessions/:id">;
|
|
79
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAqCtB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { getBackendForSession, getBackends } from "../agent/backend.js";
|
|
3
|
+
import { getDb } from "../db/client.js";
|
|
4
|
+
function getStoredBackendId(sessionId) {
|
|
5
|
+
const row = getDb()
|
|
6
|
+
.query("SELECT backend_id AS backendId FROM sessions WHERE id = ?")
|
|
7
|
+
.get(sessionId);
|
|
8
|
+
return row?.backendId ?? null;
|
|
9
|
+
}
|
|
10
|
+
export const sessionRoutes = new Hono()
|
|
11
|
+
.get("/sessions", async (c) => {
|
|
12
|
+
try {
|
|
13
|
+
const backends = await getBackends();
|
|
14
|
+
const sessions = (await Promise.all(backends.map(async (backend) => (await backend.listSessions()).map((session) => ({
|
|
15
|
+
...session,
|
|
16
|
+
backendId: backend.id,
|
|
17
|
+
})))))
|
|
18
|
+
.flat()
|
|
19
|
+
.sort((a, b) => b.lastActiveAt - a.lastActiveAt);
|
|
20
|
+
return c.json({ sessions });
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
return c.json({ error: err instanceof Error ? err.message : "Failed to list sessions" }, 500);
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
.get("/sessions/:id", async (c) => {
|
|
27
|
+
const id = c.req.param("id");
|
|
28
|
+
try {
|
|
29
|
+
const backend = await getBackendForSession(getStoredBackendId(id));
|
|
30
|
+
const messages = await backend.getHistory(id);
|
|
31
|
+
return c.json({ id, messages });
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
return c.json({ error: err instanceof Error ? err.message : "Failed to get session" }, 500);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,MAAM,GAAG,GAAG,KAAK,EAAE;SAChB,KAAK,CAAC,2DAA2D,CAAC;SAClE,GAAG,CAAC,SAAS,CAAwC,CAAC;IACzD,OAAO,GAAG,EAAE,SAAS,IAAI,IAAI,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,IAAI,EAAE;KACpC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC5B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,CACf,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAC7B,CAAC,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC/C,GAAG,OAAO;YACV,SAAS,EAAE,OAAO,CAAC,EAAE;SACtB,CAAC,CAAC,CACJ,CACF,CACF;aACE,IAAI,EAAE;aACN,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,EAAE,EACzE,GAAG,CACJ,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;KAED,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE,EACvE,GAAG,CACJ,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export declare const voiceRoutes: import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
|
|
2
|
+
"/voice/session": {
|
|
3
|
+
$post: {
|
|
4
|
+
input: {};
|
|
5
|
+
output: {
|
|
6
|
+
providerId: string;
|
|
7
|
+
url: string;
|
|
8
|
+
token?: string | undefined;
|
|
9
|
+
params?: {
|
|
10
|
+
[x: string]: string;
|
|
11
|
+
} | undefined;
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
capabilities: {
|
|
14
|
+
streaming: boolean;
|
|
15
|
+
interimResults: boolean;
|
|
16
|
+
keyterms: boolean;
|
|
17
|
+
endpointing: boolean;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
outputFormat: "json";
|
|
21
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
22
|
+
} | {
|
|
23
|
+
input: {};
|
|
24
|
+
output: {
|
|
25
|
+
error: string;
|
|
26
|
+
};
|
|
27
|
+
outputFormat: "json";
|
|
28
|
+
status: 500;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
} & {
|
|
32
|
+
"/voice/token": {
|
|
33
|
+
$post: {
|
|
34
|
+
input: {};
|
|
35
|
+
output: {
|
|
36
|
+
token: string;
|
|
37
|
+
expiresAt: number;
|
|
38
|
+
};
|
|
39
|
+
outputFormat: "json";
|
|
40
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
41
|
+
} | {
|
|
42
|
+
input: {};
|
|
43
|
+
output: {
|
|
44
|
+
error: string;
|
|
45
|
+
};
|
|
46
|
+
outputFormat: "json";
|
|
47
|
+
status: 500;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
} & {
|
|
51
|
+
"/voice/keyterms": {
|
|
52
|
+
$get: {
|
|
53
|
+
input: {};
|
|
54
|
+
output: {
|
|
55
|
+
keyterms: string[];
|
|
56
|
+
generatedAt: number;
|
|
57
|
+
count: number;
|
|
58
|
+
};
|
|
59
|
+
outputFormat: "json";
|
|
60
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
61
|
+
} | {
|
|
62
|
+
input: {};
|
|
63
|
+
output: {
|
|
64
|
+
error: string;
|
|
65
|
+
};
|
|
66
|
+
outputFormat: "json";
|
|
67
|
+
status: 500;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
} & {
|
|
71
|
+
"/voice/overrides": {
|
|
72
|
+
$get: {
|
|
73
|
+
input: {};
|
|
74
|
+
output: {
|
|
75
|
+
overrides: {
|
|
76
|
+
match: string;
|
|
77
|
+
replacement: string;
|
|
78
|
+
}[];
|
|
79
|
+
};
|
|
80
|
+
outputFormat: "json";
|
|
81
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
82
|
+
} | {
|
|
83
|
+
input: {};
|
|
84
|
+
output: {
|
|
85
|
+
error: string;
|
|
86
|
+
};
|
|
87
|
+
outputFormat: "json";
|
|
88
|
+
status: 500;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
}, "/", "/voice/overrides">;
|
|
92
|
+
//# sourceMappingURL=voice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../src/routes/voice.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAqEpB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { mintDeepgramToken } from "../voice/deepgram-token.js";
|
|
3
|
+
import { getKeyterms } from "../voice/keyterm-builder.js";
|
|
4
|
+
import { pickSpeechProvider } from "../voice/speech-providers.js";
|
|
5
|
+
export const voiceRoutes = new Hono()
|
|
6
|
+
.post("/voice/session", async (c) => {
|
|
7
|
+
try {
|
|
8
|
+
const provider = pickSpeechProvider();
|
|
9
|
+
// Only fetch domain keyterms when the provider can use them.
|
|
10
|
+
const keyterms = provider.capabilities.keyterms
|
|
11
|
+
? getKeyterms(false).keyterms
|
|
12
|
+
: [];
|
|
13
|
+
const session = await provider.createSession({ keyterms });
|
|
14
|
+
const body = {
|
|
15
|
+
providerId: provider.id,
|
|
16
|
+
url: session.url,
|
|
17
|
+
...(session.token !== undefined ? { token: session.token } : {}),
|
|
18
|
+
...(session.params !== undefined ? { params: session.params } : {}),
|
|
19
|
+
expiresAt: session.expiresAt,
|
|
20
|
+
capabilities: provider.capabilities,
|
|
21
|
+
};
|
|
22
|
+
return c.json(body);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
return c.json({ error: err instanceof Error ? err.message : "Voice session failed" }, 500);
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
// Deprecated alias, kept for client transition. Returns the old token shape
|
|
29
|
+
// by minting a Deepgram token directly; new clients use /voice/session.
|
|
30
|
+
.post("/voice/token", async (c) => {
|
|
31
|
+
try {
|
|
32
|
+
const { token, expiresAt } = await mintDeepgramToken(60);
|
|
33
|
+
const body = { token, expiresAt };
|
|
34
|
+
return c.json(body);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
return c.json({ error: err instanceof Error ? err.message : "Token mint failed" }, 500);
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.get("/voice/keyterms", async (c) => {
|
|
41
|
+
const force = c.req.query("rebuild") === "1";
|
|
42
|
+
try {
|
|
43
|
+
const cache = getKeyterms(force);
|
|
44
|
+
const body = {
|
|
45
|
+
keyterms: cache.keyterms,
|
|
46
|
+
generatedAt: cache.generatedAt,
|
|
47
|
+
count: cache.count,
|
|
48
|
+
};
|
|
49
|
+
return c.json(body);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return c.json({ error: err instanceof Error ? err.message : "Keyterms failed" }, 500);
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
.get("/voice/overrides", async (c) => {
|
|
56
|
+
try {
|
|
57
|
+
const cache = getKeyterms(false);
|
|
58
|
+
return c.json({ overrides: cache.overrides });
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
return c.json({ error: err instanceof Error ? err.message : "Overrides failed" }, 500);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=voice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.js","sourceRoot":"","sources":["../../src/routes/voice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deepgram-token.d.ts","sourceRoot":"","sources":["../../src/voice/deepgram-token.ts"],"names":[],"mappings":"AAkCA,wBAAsB,iBAAiB,CAAC,UAAU,SAAK,GAAG,OAAO,CAAC;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CA0CD"}
|