@brainpilot/backend-core 0.0.1
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/dist/app.d.ts +31 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +197 -0
- package/dist/app.js.map +1 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +161 -0
- package/dist/config.js.map +1 -0
- package/dist/create-orchestrator.d.ts +17 -0
- package/dist/create-orchestrator.d.ts.map +1 -0
- package/dist/create-orchestrator.js +35 -0
- package/dist/create-orchestrator.js.map +1 -0
- package/dist/docker-orchestrator.d.ts +75 -0
- package/dist/docker-orchestrator.d.ts.map +1 -0
- package/dist/docker-orchestrator.js +159 -0
- package/dist/docker-orchestrator.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/local-orchestrator.d.ts +74 -0
- package/dist/local-orchestrator.d.ts.map +1 -0
- package/dist/local-orchestrator.js +225 -0
- package/dist/local-orchestrator.js.map +1 -0
- package/dist/orchestrator.d.ts +51 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +39 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/runtime-client.d.ts +54 -0
- package/dist/runtime-client.d.ts.map +1 -0
- package/dist/runtime-client.js +67 -0
- package/dist/runtime-client.js.map +1 -0
- package/dist/runtime-paths.d.ts +8 -0
- package/dist/runtime-paths.d.ts.map +1 -0
- package/dist/runtime-paths.js +10 -0
- package/dist/runtime-paths.js.map +1 -0
- package/dist/server.d.ts +25 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +54 -0
- package/dist/server.js.map +1 -0
- package/dist/static-orchestrator.d.ts +37 -0
- package/dist/static-orchestrator.d.ts.map +1 -0
- package/dist/static-orchestrator.js +50 -0
- package/dist/static-orchestrator.js.map +1 -0
- package/package.json +41 -0
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hono app — the host-side lightweight backend (§10, §11A).
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - REST routes the SPA needs → forwarded to the runtime via RuntimeClient
|
|
6
|
+
* (byte passthrough, 修正4: no parsing, no state).
|
|
7
|
+
* - SSE route → byte-pipes the runtime's event stream to the client.
|
|
8
|
+
* - Local config routes (settings/providers) → read/write on-disk config
|
|
9
|
+
* (NOT proxied; backend owns this, §11A.2).
|
|
10
|
+
* - Static serving of the web build (@brainpilot/web dist) with SPA fallback.
|
|
11
|
+
* - Health endpoint.
|
|
12
|
+
*
|
|
13
|
+
* The app is mounted under `/api` for the proxied/local routes (the SPA calls
|
|
14
|
+
* `API_BASE = "/api"`), with static assets served at the root.
|
|
15
|
+
*/
|
|
16
|
+
import { Hono } from "hono";
|
|
17
|
+
import type { Orchestrator } from "./orchestrator.js";
|
|
18
|
+
export interface CreateAppOptions {
|
|
19
|
+
orchestrator: Orchestrator;
|
|
20
|
+
/** Data dir for local config routes. Default `./brainpilot`. */
|
|
21
|
+
dataDir?: string;
|
|
22
|
+
/** Web build dir to serve. Default `$BP_WEB_ROOT` or `packages/web/dist`. */
|
|
23
|
+
webRoot?: string;
|
|
24
|
+
/** Injectable fetch for the runtime client (tests). */
|
|
25
|
+
fetchFn?: typeof fetch;
|
|
26
|
+
/** Disable static serving (tests that only exercise the API). */
|
|
27
|
+
serveWeb?: boolean;
|
|
28
|
+
env?: Record<string, string | undefined>;
|
|
29
|
+
}
|
|
30
|
+
export declare function createApp(options: CreateAppOptions): Hono;
|
|
31
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOtD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAWD,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CA4IzD"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hono app — the host-side lightweight backend (§10, §11A).
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - REST routes the SPA needs → forwarded to the runtime via RuntimeClient
|
|
6
|
+
* (byte passthrough, 修正4: no parsing, no state).
|
|
7
|
+
* - SSE route → byte-pipes the runtime's event stream to the client.
|
|
8
|
+
* - Local config routes (settings/providers) → read/write on-disk config
|
|
9
|
+
* (NOT proxied; backend owns this, §11A.2).
|
|
10
|
+
* - Static serving of the web build (@brainpilot/web dist) with SPA fallback.
|
|
11
|
+
* - Health endpoint.
|
|
12
|
+
*
|
|
13
|
+
* The app is mounted under `/api` for the proxied/local routes (the SPA calls
|
|
14
|
+
* `API_BASE = "/api"`), with static assets served at the root.
|
|
15
|
+
*/
|
|
16
|
+
import { Hono } from "hono";
|
|
17
|
+
import { serveStatic } from "@hono/node-server/serve-static";
|
|
18
|
+
import { RuntimeClient } from "./runtime-client.js";
|
|
19
|
+
import { readLocalSettings, writeLocalSettings, resolveProvider, } from "./config.js";
|
|
20
|
+
/** Headers that must not be copied verbatim onto an SSE passthrough. */
|
|
21
|
+
const HOP_BY_HOP = new Set([
|
|
22
|
+
"connection",
|
|
23
|
+
"keep-alive",
|
|
24
|
+
"transfer-encoding",
|
|
25
|
+
"content-encoding",
|
|
26
|
+
"content-length",
|
|
27
|
+
]);
|
|
28
|
+
export function createApp(options) {
|
|
29
|
+
const dataDir = options.dataDir ?? process.env.BP_DATA_DIR ?? "./brainpilot";
|
|
30
|
+
const webRoot = options.webRoot ?? process.env.BP_WEB_ROOT ?? "packages/web/dist";
|
|
31
|
+
const orchestrator = options.orchestrator;
|
|
32
|
+
const env = options.env;
|
|
33
|
+
// Lazily-created runtime client, bound to the ensured runtime's baseUrl.
|
|
34
|
+
let client = null;
|
|
35
|
+
async function getClient() {
|
|
36
|
+
const handle = await orchestrator.ensureRuntime();
|
|
37
|
+
if (!client || client._baseUrl !== handle.baseUrl) {
|
|
38
|
+
client = new RuntimeClient({ baseUrl: handle.baseUrl, fetchFn: options.fetchFn });
|
|
39
|
+
client._baseUrl = handle.baseUrl;
|
|
40
|
+
}
|
|
41
|
+
return client;
|
|
42
|
+
}
|
|
43
|
+
const app = new Hono();
|
|
44
|
+
const api = new Hono();
|
|
45
|
+
// ---- Health (backend-local; does not require runtime) ----------------
|
|
46
|
+
api.get("/health", (c) => c.json({ status: "ok" }));
|
|
47
|
+
api.get("/version", (c) => c.json({ name: "@brainpilot/backend-core", version: "0.1.0" }));
|
|
48
|
+
// ---- Sessions (proxied to runtime) -----------------------------------
|
|
49
|
+
api.get("/sessions", forward("listSessions"));
|
|
50
|
+
api.post("/sessions", forward("createSession", { withBody: true }));
|
|
51
|
+
api.get("/sessions/:id", forward("getSession", { idParam: "id" }));
|
|
52
|
+
api.put("/sessions/:id", forwardRename());
|
|
53
|
+
api.delete("/sessions/:id", forward("deleteSession", { idParam: "id" }));
|
|
54
|
+
api.get("/sessions/:id/state", forward("getSessionState", { idParam: "id" }));
|
|
55
|
+
api.post("/sessions/:id/messages", forward("sendMessage", { idParam: "id", withBody: true }));
|
|
56
|
+
api.post("/sessions/:id/interrupt", forward("interrupt", { idParam: "id", withBody: true }));
|
|
57
|
+
api.get("/sessions/:id/agents", forward("listAgents", { idParam: "id" }));
|
|
58
|
+
api.post("/sessions/:id/evict", forward("evictSession", { idParam: "id", withBody: true }));
|
|
59
|
+
// ---- SSE byte passthrough (修正4) ------------------------------------
|
|
60
|
+
// Canonical protocol path `/sse/:id` (RUNTIME_ROUTES.sessionEvents) plus the
|
|
61
|
+
// SPA's `/sessions/:id/sse` and the `/sessions/:id/events` alias.
|
|
62
|
+
api.get("/sse/:id", sseHandler);
|
|
63
|
+
api.get("/sessions/:id/sse", sseHandler);
|
|
64
|
+
api.get("/sessions/:id/events", sseHandler);
|
|
65
|
+
// ---- Local config routes (NOT proxied; §11A.2) -----------------------
|
|
66
|
+
api.get("/settings", async (c) => {
|
|
67
|
+
const settings = await readLocalSettings({ dataDir, env });
|
|
68
|
+
return c.json(settings);
|
|
69
|
+
});
|
|
70
|
+
api.put("/settings", async (c) => {
|
|
71
|
+
const body = await safeJson(c);
|
|
72
|
+
await writeLocalSettings(dataDir, {
|
|
73
|
+
model: typeof body.model === "string" ? body.model : undefined,
|
|
74
|
+
apiKey: typeof body.api_key === "string" ? body.api_key : (typeof body.apiKey === "string" ? body.apiKey : undefined),
|
|
75
|
+
baseUrl: typeof body.base_url === "string" ? body.base_url : (typeof body.baseUrl === "string" ? body.baseUrl : undefined),
|
|
76
|
+
});
|
|
77
|
+
return c.json(await readLocalSettings({ dataDir, env }));
|
|
78
|
+
});
|
|
79
|
+
// Provider profiles: single-user open-source mode exposes the resolved
|
|
80
|
+
// provider as one active profile (sourced from the §11A.2 priority chain).
|
|
81
|
+
api.get("/provider/profiles", async (c) => {
|
|
82
|
+
const resolved = await resolveProvider({ dataDir, env });
|
|
83
|
+
return c.json(resolved.apiKey ? [providerProfile(resolved)] : []);
|
|
84
|
+
});
|
|
85
|
+
api.get("/provider/profiles/active", async (c) => {
|
|
86
|
+
const resolved = await resolveProvider({ dataDir, env });
|
|
87
|
+
return c.json(resolved.apiKey ? providerProfile(resolved) : null);
|
|
88
|
+
});
|
|
89
|
+
// Mount the API under /api (the SPA's API_BASE).
|
|
90
|
+
app.route("/api", api);
|
|
91
|
+
// ---- Static web serving with SPA fallback ----------------------------
|
|
92
|
+
if (options.serveWeb !== false) {
|
|
93
|
+
app.use("/*", serveStatic({ root: webRoot }));
|
|
94
|
+
// SPA fallback: any unmatched GET that isn't /api returns index.html.
|
|
95
|
+
app.get("/*", serveStatic({ path: `${webRoot}/index.html` }));
|
|
96
|
+
}
|
|
97
|
+
return app;
|
|
98
|
+
// ---------------- helpers ----------------
|
|
99
|
+
function forward(route, opts = {}) {
|
|
100
|
+
return async (c) => {
|
|
101
|
+
const rc = await getClient();
|
|
102
|
+
const params = {};
|
|
103
|
+
if (opts.idParam)
|
|
104
|
+
params.id = c.req.param(opts.idParam) ?? "";
|
|
105
|
+
const body = opts.withBody ? await c.req.text() : undefined;
|
|
106
|
+
const headers = {};
|
|
107
|
+
const ct = c.req.header("content-type");
|
|
108
|
+
if (ct)
|
|
109
|
+
headers["content-type"] = ct;
|
|
110
|
+
const upstream = await rc.forward(route, {
|
|
111
|
+
params,
|
|
112
|
+
body: body && body.length > 0 ? body : undefined,
|
|
113
|
+
headers,
|
|
114
|
+
});
|
|
115
|
+
return relay(c, upstream);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// The SPA's PUT /sessions/:id (rename) has no dedicated runtime route in
|
|
119
|
+
// §15.4; forward it to the runtime's getSession path with PUT semantics via
|
|
120
|
+
// a raw forward so the runtime can handle/ignore it. We reuse sendMessage's
|
|
121
|
+
// session path shape but keep method PUT by hitting getSession's path.
|
|
122
|
+
function forwardRename() {
|
|
123
|
+
return async (c) => {
|
|
124
|
+
const rc = await getClient();
|
|
125
|
+
const id = c.req.param("id") ?? "";
|
|
126
|
+
const body = await c.req.text();
|
|
127
|
+
// getSession route path is `/sessions/:id`; issue a PUT against it.
|
|
128
|
+
const url = rc.urlFor("getSession", { id });
|
|
129
|
+
const upstream = await (options.fetchFn ?? fetch)(url, {
|
|
130
|
+
method: "PUT",
|
|
131
|
+
headers: { "content-type": c.req.header("content-type") ?? "application/json" },
|
|
132
|
+
body: body && body.length > 0 ? body : undefined,
|
|
133
|
+
});
|
|
134
|
+
return relay(c, upstream);
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
async function sseHandler(c) {
|
|
138
|
+
const rc = await getClient();
|
|
139
|
+
const id = c.req.param("id") ?? "";
|
|
140
|
+
const upstream = await rc.openSse(id, {
|
|
141
|
+
query: c.req.query("token") ? `token=${encodeURIComponent(c.req.query("token"))}` : undefined,
|
|
142
|
+
});
|
|
143
|
+
// 修正4: do not parse the stream — relay the byte body untouched.
|
|
144
|
+
const headers = new Headers();
|
|
145
|
+
upstream.headers.forEach((value, key) => {
|
|
146
|
+
if (!HOP_BY_HOP.has(key.toLowerCase()))
|
|
147
|
+
headers.set(key, value);
|
|
148
|
+
});
|
|
149
|
+
if (!headers.has("content-type"))
|
|
150
|
+
headers.set("content-type", "text/event-stream");
|
|
151
|
+
headers.set("cache-control", "no-cache");
|
|
152
|
+
headers.set("connection", "keep-alive");
|
|
153
|
+
return new Response(upstream.body, { status: upstream.status, headers });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Relay a runtime Response to the client, preserving status + safe headers. */
|
|
157
|
+
function relay(c, upstream) {
|
|
158
|
+
const headers = new Headers();
|
|
159
|
+
upstream.headers.forEach((value, key) => {
|
|
160
|
+
if (!HOP_BY_HOP.has(key.toLowerCase()))
|
|
161
|
+
headers.set(key, value);
|
|
162
|
+
});
|
|
163
|
+
return new Response(upstream.body, { status: upstream.status, headers });
|
|
164
|
+
}
|
|
165
|
+
async function safeJson(c) {
|
|
166
|
+
try {
|
|
167
|
+
const v = await c.req.json();
|
|
168
|
+
return v && typeof v === "object" ? v : {};
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function providerProfile(resolved) {
|
|
175
|
+
const now = Date.now();
|
|
176
|
+
const masked = resolved.apiKey
|
|
177
|
+
? resolved.apiKey.length <= 8
|
|
178
|
+
? "****"
|
|
179
|
+
: `${resolved.apiKey.slice(0, 4)}…${resolved.apiKey.slice(-4)}`
|
|
180
|
+
: "";
|
|
181
|
+
return {
|
|
182
|
+
id: "local",
|
|
183
|
+
name: "Local",
|
|
184
|
+
base_url: resolved.baseUrl ?? "",
|
|
185
|
+
models: resolved.model ? [resolved.model] : [],
|
|
186
|
+
icon: "circle",
|
|
187
|
+
icon_color: "#111111",
|
|
188
|
+
notes: "",
|
|
189
|
+
is_active: true,
|
|
190
|
+
api_key_masked: masked,
|
|
191
|
+
created_at: now,
|
|
192
|
+
updated_at: now,
|
|
193
|
+
health_status: "unknown",
|
|
194
|
+
model_health: [],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface ResolvedProvider {
|
|
2
|
+
/** API key, if any layer supplied one. */
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
/** Base URL override, if any. */
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
/** Model id, if any. */
|
|
7
|
+
model?: string;
|
|
8
|
+
/** Which layer the apiKey came from (for diagnostics). */
|
|
9
|
+
source?: "env" | "bp_template" | "config" | "dotenv";
|
|
10
|
+
}
|
|
11
|
+
export interface ConfigPaths {
|
|
12
|
+
dataDir: string;
|
|
13
|
+
bpTemplateSettings: string;
|
|
14
|
+
brainpilotConfig: string;
|
|
15
|
+
dotenv: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function configPaths(dataDir: string): ConfigPaths;
|
|
18
|
+
/** Minimal .env parser (KEY=VALUE per line, `#` comments, optional quotes). */
|
|
19
|
+
export declare function parseDotenv(file: string): Promise<Record<string, string>>;
|
|
20
|
+
export interface ResolveProviderOptions {
|
|
21
|
+
dataDir: string;
|
|
22
|
+
env?: Record<string, string | undefined>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the effective provider config by walking the priority chain. The
|
|
26
|
+
* apiKey's `source` reflects the FIRST layer that supplied it; baseUrl/model
|
|
27
|
+
* are likewise taken from the highest layer that supplies each.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveProvider(options: ResolveProviderOptions): Promise<ResolvedProvider>;
|
|
30
|
+
/** Masked, frontend-facing settings (never leak the raw key). */
|
|
31
|
+
export interface LocalSettings {
|
|
32
|
+
model: string;
|
|
33
|
+
apiKey: string;
|
|
34
|
+
baseUrl: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function readLocalSettings(options: ResolveProviderOptions): Promise<LocalSettings>;
|
|
37
|
+
/**
|
|
38
|
+
* Persist a settings patch to `bp_template/settings.json` (the user-editable
|
|
39
|
+
* template layer). Merges with existing content.
|
|
40
|
+
*/
|
|
41
|
+
export declare function writeLocalSettings(dataDir: string, patch: Partial<{
|
|
42
|
+
model: string;
|
|
43
|
+
apiKey: string;
|
|
44
|
+
baseUrl: string;
|
|
45
|
+
}>): Promise<void>;
|
|
46
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,MAAM,CAAC,EAAE,KAAK,GAAG,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACtD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAOxD;AAYD,+EAA+E;AAC/E,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwB/E;AAmBD,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAiD3B;AAED,iEAAiE;AACjE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,aAAa,CAAC,CAOxB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GACjE,OAAO,CAAC,IAAI,CAAC,CAWf"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local config resolution — backend-LOCAL settings/provider routes (§11A.2).
|
|
3
|
+
* These are NOT proxied to the runtime; the backend owns the on-disk config
|
|
4
|
+
* tree under the data dir (`./brainpilot/` by default).
|
|
5
|
+
*
|
|
6
|
+
* Provider/key priority (§11A.2 要点 2), highest first:
|
|
7
|
+
* 1. real environment variables (ANTHROPIC_API_KEY, etc.)
|
|
8
|
+
* 2. bp_template/settings.json
|
|
9
|
+
* 3. brainpilot.config.json
|
|
10
|
+
* 4. .env (lowest — fallback)
|
|
11
|
+
*/
|
|
12
|
+
import { promises as fs } from "node:fs";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
export function configPaths(dataDir) {
|
|
15
|
+
return {
|
|
16
|
+
dataDir,
|
|
17
|
+
bpTemplateSettings: path.join(dataDir, "bp_template", "settings.json"),
|
|
18
|
+
brainpilotConfig: path.join(dataDir, "brainpilot.config.json"),
|
|
19
|
+
dotenv: path.join(dataDir, ".env"),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
async function readJsonSafe(file) {
|
|
23
|
+
try {
|
|
24
|
+
const text = await fs.readFile(file, "utf8");
|
|
25
|
+
const parsed = JSON.parse(text);
|
|
26
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Minimal .env parser (KEY=VALUE per line, `#` comments, optional quotes). */
|
|
33
|
+
export async function parseDotenv(file) {
|
|
34
|
+
let text;
|
|
35
|
+
try {
|
|
36
|
+
text = await fs.readFile(file, "utf8");
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
const out = {};
|
|
42
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
43
|
+
const line = rawLine.trim();
|
|
44
|
+
if (!line || line.startsWith("#"))
|
|
45
|
+
continue;
|
|
46
|
+
const eq = line.indexOf("=");
|
|
47
|
+
if (eq < 0)
|
|
48
|
+
continue;
|
|
49
|
+
const key = line.slice(0, eq).trim();
|
|
50
|
+
let value = line.slice(eq + 1).trim();
|
|
51
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
52
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
53
|
+
value = value.slice(1, -1);
|
|
54
|
+
}
|
|
55
|
+
if (key)
|
|
56
|
+
out[key] = value;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
function pickString(obj, ...keys) {
|
|
61
|
+
if (!obj)
|
|
62
|
+
return undefined;
|
|
63
|
+
for (const k of keys) {
|
|
64
|
+
const v = obj[k];
|
|
65
|
+
if (typeof v === "string" && v.length > 0)
|
|
66
|
+
return v;
|
|
67
|
+
}
|
|
68
|
+
// Nested `provider` object support (settings.json may nest).
|
|
69
|
+
const provider = obj.provider;
|
|
70
|
+
if (provider && typeof provider === "object") {
|
|
71
|
+
for (const k of keys) {
|
|
72
|
+
const v = provider[k];
|
|
73
|
+
if (typeof v === "string" && v.length > 0)
|
|
74
|
+
return v;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the effective provider config by walking the priority chain. The
|
|
81
|
+
* apiKey's `source` reflects the FIRST layer that supplied it; baseUrl/model
|
|
82
|
+
* are likewise taken from the highest layer that supplies each.
|
|
83
|
+
*/
|
|
84
|
+
export async function resolveProvider(options) {
|
|
85
|
+
const env = options.env ?? process.env;
|
|
86
|
+
const paths = configPaths(options.dataDir);
|
|
87
|
+
const templateSettings = await readJsonSafe(paths.bpTemplateSettings);
|
|
88
|
+
const config = await readJsonSafe(paths.brainpilotConfig);
|
|
89
|
+
const dotenv = await parseDotenv(paths.dotenv);
|
|
90
|
+
// Layer values, highest priority first.
|
|
91
|
+
const envKey = env.ANTHROPIC_API_KEY || env.BP_API_KEY || env.OPENAI_API_KEY || undefined;
|
|
92
|
+
const templateKey = pickString(templateSettings, "apiKey", "api_key");
|
|
93
|
+
const configKey = pickString(config, "apiKey", "api_key");
|
|
94
|
+
const dotenvKey = dotenv.ANTHROPIC_API_KEY || dotenv.BP_API_KEY || dotenv.OPENAI_API_KEY || undefined;
|
|
95
|
+
let apiKey;
|
|
96
|
+
let source;
|
|
97
|
+
if (envKey) {
|
|
98
|
+
apiKey = envKey;
|
|
99
|
+
source = "env";
|
|
100
|
+
}
|
|
101
|
+
else if (templateKey) {
|
|
102
|
+
apiKey = templateKey;
|
|
103
|
+
source = "bp_template";
|
|
104
|
+
}
|
|
105
|
+
else if (configKey) {
|
|
106
|
+
apiKey = configKey;
|
|
107
|
+
source = "config";
|
|
108
|
+
}
|
|
109
|
+
else if (dotenvKey) {
|
|
110
|
+
apiKey = dotenvKey;
|
|
111
|
+
source = "dotenv";
|
|
112
|
+
}
|
|
113
|
+
const baseUrl = env.ANTHROPIC_BASE_URL ||
|
|
114
|
+
env.BP_BASE_URL ||
|
|
115
|
+
pickString(templateSettings, "baseUrl", "base_url") ||
|
|
116
|
+
pickString(config, "baseUrl", "base_url") ||
|
|
117
|
+
dotenv.ANTHROPIC_BASE_URL ||
|
|
118
|
+
dotenv.BP_BASE_URL ||
|
|
119
|
+
undefined;
|
|
120
|
+
const model = env.BP_MODEL ||
|
|
121
|
+
pickString(templateSettings, "model") ||
|
|
122
|
+
pickString(config, "model") ||
|
|
123
|
+
dotenv.BP_MODEL ||
|
|
124
|
+
undefined;
|
|
125
|
+
return { apiKey, baseUrl, model, source };
|
|
126
|
+
}
|
|
127
|
+
function maskKey(key) {
|
|
128
|
+
if (!key)
|
|
129
|
+
return "";
|
|
130
|
+
if (key.length <= 8)
|
|
131
|
+
return "****";
|
|
132
|
+
return `${key.slice(0, 4)}…${key.slice(-4)}`;
|
|
133
|
+
}
|
|
134
|
+
export async function readLocalSettings(options) {
|
|
135
|
+
const resolved = await resolveProvider(options);
|
|
136
|
+
return {
|
|
137
|
+
model: resolved.model ?? "",
|
|
138
|
+
apiKey: maskKey(resolved.apiKey),
|
|
139
|
+
baseUrl: resolved.baseUrl ?? "",
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Persist a settings patch to `bp_template/settings.json` (the user-editable
|
|
144
|
+
* template layer). Merges with existing content.
|
|
145
|
+
*/
|
|
146
|
+
export async function writeLocalSettings(dataDir, patch) {
|
|
147
|
+
const file = configPaths(dataDir).bpTemplateSettings;
|
|
148
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
149
|
+
const existing = (await readJsonSafe(file)) ?? {};
|
|
150
|
+
const next = { ...existing };
|
|
151
|
+
if (patch.model !== undefined)
|
|
152
|
+
next.model = patch.model;
|
|
153
|
+
if (patch.apiKey !== undefined)
|
|
154
|
+
next.apiKey = patch.apiKey;
|
|
155
|
+
if (patch.baseUrl !== undefined)
|
|
156
|
+
next.baseUrl = patch.baseUrl;
|
|
157
|
+
const tmp = `${file}.tmp`;
|
|
158
|
+
await fs.writeFile(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
159
|
+
await fs.rename(tmp, file); // atomic write (§16.4 fix)
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createOrchestrator — factory picking Local / Static / Docker based on env/options.
|
|
3
|
+
*/
|
|
4
|
+
import { type Orchestrator, type OrchestratorMode } from "./orchestrator.js";
|
|
5
|
+
import { type LocalOrchestratorOptions } from "./local-orchestrator.js";
|
|
6
|
+
import { type StaticOrchestratorOptions } from "./static-orchestrator.js";
|
|
7
|
+
import { type DockerOrchestratorOptions } from "./docker-orchestrator.js";
|
|
8
|
+
export interface CreateOrchestratorOptions {
|
|
9
|
+
/** Force a mode; otherwise resolved from env (BP_ORCHESTRATOR / BP_RUNTIME_URL / BP_MODE). */
|
|
10
|
+
mode?: OrchestratorMode;
|
|
11
|
+
local?: LocalOrchestratorOptions;
|
|
12
|
+
static?: Partial<StaticOrchestratorOptions>;
|
|
13
|
+
docker?: DockerOrchestratorOptions;
|
|
14
|
+
env?: Record<string, string | undefined>;
|
|
15
|
+
}
|
|
16
|
+
export declare function createOrchestrator(options?: CreateOrchestratorOptions): Orchestrator;
|
|
17
|
+
//# sourceMappingURL=create-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-orchestrator.d.ts","sourceRoot":"","sources":["../src/create-orchestrator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAGlC,MAAM,WAAW,yBAAyB;IACxC,8FAA8F;IAC9F,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,KAAK,CAAC,EAAE,wBAAwB,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC5C,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAED,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,YAAY,CA4Bd"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createOrchestrator — factory picking Local / Static / Docker based on env/options.
|
|
3
|
+
*/
|
|
4
|
+
import { resolveOrchestratorMode, } from "./orchestrator.js";
|
|
5
|
+
import { LocalProcessOrchestrator, } from "./local-orchestrator.js";
|
|
6
|
+
import { StaticRuntimeOrchestrator, } from "./static-orchestrator.js";
|
|
7
|
+
import { DockerOrchestrator, } from "./docker-orchestrator.js";
|
|
8
|
+
import { runtimeArtifactPaths } from "./runtime-paths.js";
|
|
9
|
+
export function createOrchestrator(options = {}) {
|
|
10
|
+
const env = options.env ?? process.env;
|
|
11
|
+
const mode = options.mode ?? resolveOrchestratorMode(env);
|
|
12
|
+
if (mode === "docker") {
|
|
13
|
+
return new DockerOrchestrator(options.docker);
|
|
14
|
+
}
|
|
15
|
+
if (mode === "static") {
|
|
16
|
+
const baseUrl = options.static?.baseUrl ?? env.BP_RUNTIME_URL ?? "";
|
|
17
|
+
return new StaticRuntimeOrchestrator({ ...options.static, baseUrl });
|
|
18
|
+
}
|
|
19
|
+
// Default a fatal handler so an exhausted crash-loop is at least surfaced
|
|
20
|
+
// (§11A.5 / §7 L4) instead of the runtime silently disappearing.
|
|
21
|
+
// Derive log/pid paths from BP_DATA_DIR so logs/status/down can observe the runtime child.
|
|
22
|
+
const dataDir = options.local?.dataDir ?? env.BP_DATA_DIR ?? "./brainpilot";
|
|
23
|
+
const artifacts = runtimeArtifactPaths(dataDir);
|
|
24
|
+
const local = {
|
|
25
|
+
onFatal: (err) => {
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
27
|
+
console.error("[orchestrator] runtime fatal:", err.message);
|
|
28
|
+
},
|
|
29
|
+
runtimeLogFile: artifacts.runtimeLog,
|
|
30
|
+
runtimePidFile: artifacts.runtimePid,
|
|
31
|
+
...options.local,
|
|
32
|
+
};
|
|
33
|
+
return new LocalProcessOrchestrator(local);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=create-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-orchestrator.js","sourceRoot":"","sources":["../src/create-orchestrator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,uBAAuB,GAGxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,wBAAwB,GAEzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,yBAAyB,GAE1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,kBAAkB,GAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAW1D,MAAM,UAAU,kBAAkB,CAChC,UAAqC,EAAE;IAEvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAE1D,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,IAAI,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;QACpE,OAAO,IAAI,yBAAyB,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,0EAA0E;IAC1E,iEAAiE;IACjE,2FAA2F;IAC3F,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,OAAO,IAAI,GAAG,CAAC,WAAW,IAAI,cAAc,CAAC;IAC5E,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,KAAK,GAA6B;QACtC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACf,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QACD,cAAc,EAAE,SAAS,CAAC,UAAU;QACpC,cAAc,EAAE,SAAS,CAAC,UAAU;QACpC,GAAG,OAAO,CAAC,KAAK;KACjB,CAAC;IACF,OAAO,IAAI,wBAAwB,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DockerOrchestrator — `docker run` the `brainpilot-sandbox` image over the mapped host port.
|
|
3
|
+
* dockerode is loaded lazily via dynamic import (免 Docker install never pulls dockerode + gRPC/protobuf); the public API uses the local DockerLike, not dockerode types.
|
|
4
|
+
*/
|
|
5
|
+
import type { EnsureRuntimeOptions, Orchestrator, RuntimeHandle } from "./orchestrator.js";
|
|
6
|
+
/** Minimal container surface we use from dockerode. */
|
|
7
|
+
export interface DockerContainerLike {
|
|
8
|
+
start(): Promise<unknown>;
|
|
9
|
+
stop(opts?: {
|
|
10
|
+
t?: number;
|
|
11
|
+
}): Promise<unknown>;
|
|
12
|
+
remove(opts?: {
|
|
13
|
+
force?: boolean;
|
|
14
|
+
}): Promise<unknown>;
|
|
15
|
+
}
|
|
16
|
+
/** Minimal dockerode surface we use. */
|
|
17
|
+
export interface DockerLike {
|
|
18
|
+
createContainer(spec: unknown): Promise<DockerContainerLike>;
|
|
19
|
+
pull(image: string, cb: (err: Error | null, stream: NodeJS.ReadableStream | undefined) => void): void;
|
|
20
|
+
modem: {
|
|
21
|
+
followProgress(stream: NodeJS.ReadableStream, onFinished: (err: Error | null) => void): void;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Lazily import dockerode and return its default constructor. */
|
|
25
|
+
export type DockerLoader = () => Promise<{
|
|
26
|
+
default: new () => DockerLike;
|
|
27
|
+
}>;
|
|
28
|
+
export interface DockerOrchestratorOptions {
|
|
29
|
+
/** Image to run. Default `brainpilot-sandbox:latest`. */
|
|
30
|
+
image?: string;
|
|
31
|
+
/** Container-internal runtime port. Default 8081. */
|
|
32
|
+
containerPort?: number;
|
|
33
|
+
/** Host port to map to. Default = containerPort. */
|
|
34
|
+
hostPort?: number;
|
|
35
|
+
host?: string;
|
|
36
|
+
/** Host data dir bind-mounted to the container's BP_DATA_DIR. */
|
|
37
|
+
dataDir?: string;
|
|
38
|
+
/** Container path BP_DATA_DIR points at. Default `/root/.bp-root`. */
|
|
39
|
+
containerDataDir?: string;
|
|
40
|
+
/** Injectable dockerode-like instance (for tests / advanced callers). */
|
|
41
|
+
docker?: DockerLike;
|
|
42
|
+
/** Injectable lazy loader (for tests). Defaults to dynamic import("dockerode"). */
|
|
43
|
+
dockerLoader?: DockerLoader;
|
|
44
|
+
/** Extra env passed to the container. */
|
|
45
|
+
env?: Record<string, string>;
|
|
46
|
+
healthProbe?: (baseUrl: string) => Promise<boolean>;
|
|
47
|
+
healthTimeoutMs?: number;
|
|
48
|
+
sleep?: (ms: number) => Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
export declare class DockerOrchestrator implements Orchestrator {
|
|
51
|
+
private docker;
|
|
52
|
+
private readonly dockerLoader;
|
|
53
|
+
private readonly image;
|
|
54
|
+
private readonly containerPort;
|
|
55
|
+
private readonly hostPort;
|
|
56
|
+
private readonly host;
|
|
57
|
+
private readonly containerDataDir;
|
|
58
|
+
private readonly healthProbe;
|
|
59
|
+
private readonly healthTimeoutMs;
|
|
60
|
+
private readonly sleep;
|
|
61
|
+
private dataDir?;
|
|
62
|
+
private env;
|
|
63
|
+
private container;
|
|
64
|
+
constructor(options?: DockerOrchestratorOptions);
|
|
65
|
+
/** Resolve a dockerode-like instance, loading dockerode lazily on first use. */
|
|
66
|
+
private getDocker;
|
|
67
|
+
get baseUrl(): string;
|
|
68
|
+
ensureRuntime(opts?: EnsureRuntimeOptions): Promise<RuntimeHandle>;
|
|
69
|
+
/** Pull `this.image`, resolving once the pull stream finishes. */
|
|
70
|
+
private pullImage;
|
|
71
|
+
health(): Promise<boolean>;
|
|
72
|
+
stopRuntime(): Promise<void>;
|
|
73
|
+
private waitForHealth;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=docker-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-orchestrator.d.ts","sourceRoot":"","sources":["../src/docker-orchestrator.ts"],"names":[],"mappings":"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"}
|