antechamber 1.0.41 → 2.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/CHANGELOG.md +97 -0
- package/README.md +88 -141
- package/bin/opencode-antechamber +14 -4
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/commands/context.d.ts +5 -2
- package/dist/commands/context.js +8 -4
- package/dist/commands/doctor.js +4 -3
- package/dist/commands/setup.js +9 -28
- package/dist/config.d.ts +6 -2
- package/dist/config.js +18 -4
- package/dist/latency.d.ts +10 -0
- package/dist/latency.js +115 -0
- package/dist/misc-routes.js +2 -10
- package/dist/route-services.d.ts +0 -2
- package/dist/routes-v1.d.ts +1 -1
- package/dist/routes-v1.js +29 -418
- package/dist/routes-v2.js +1 -1
- package/dist/self-update.d.ts +2 -1
- package/dist/self-update.js +5 -1
- package/dist/server.d.ts +1 -3
- package/dist/server.js +9 -12
- package/dist/session-store.d.ts +12 -10
- package/dist/session-store.js +238 -128
- package/dist/session-tree.js +2 -2
- package/dist/sse.d.ts +0 -2
- package/dist/sse.js +13 -46
- package/dist/tool-map.js +1 -3
- package/dist/work-status.js +1 -1
- package/extensions/antechamber/README.md +100 -0
- package/extensions/antechamber/bin/opencode-antechamber +42 -0
- package/extensions/{omo-dag/docs/DESIGN.md → antechamber/docs/GRAPH.md} +5 -5
- package/extensions/{omo-work/docs/DESIGN.md → antechamber/docs/WORK.md} +3 -3
- package/extensions/antechamber/package.json +60 -0
- package/extensions/{omo-dag → antechamber}/panel/index.html +8 -1
- package/extensions/antechamber/panel/main.js +261 -0
- package/extensions/antechamber/runtime/launcher.js +201 -0
- package/extensions/antechamber/service/main.js +884 -0
- package/package.json +75 -26
- package/extensions/omo-compat/README.md +0 -48
- package/extensions/omo-compat/icon.svg +0 -1
- package/extensions/omo-compat/package.json +0 -43
- package/extensions/omo-dag/README.md +0 -167
- package/extensions/omo-dag/package.json +0 -33
- package/extensions/omo-dag/panel/main.js +0 -176
- package/extensions/omo-dag/service/main.js +0 -457
- package/extensions/omo-work/README.md +0 -88
- package/extensions/omo-work/package.json +0 -30
- package/extensions/omo-work/service/main.js +0 -149
- /package/extensions/{omo-dag → antechamber}/icon.svg +0 -0
- /package/extensions/{omo-work → antechamber}/status/index.html +0 -0
- /package/extensions/{omo-work → antechamber}/status/main.js +0 -0
package/dist/config.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { homedir } from "node:os";
|
|
3
|
-
import { basename, join } from "node:path";
|
|
4
|
+
import { basename, dirname, join } from "node:path";
|
|
4
5
|
/** Environment variable prefix for all antechamber settings. */
|
|
5
6
|
export const ENV_PREFIX = "ANTECHAMBER_";
|
|
6
7
|
/** Prefix used before the project was renamed; still honoured as a fallback. */
|
|
@@ -30,9 +31,22 @@ export function defaultStateDir(home = homedir(), exists = existsSync) {
|
|
|
30
31
|
return legacy;
|
|
31
32
|
return current;
|
|
32
33
|
}
|
|
33
|
-
/**
|
|
34
|
-
export function
|
|
35
|
-
|
|
34
|
+
/** The OmO that antechamber's package.json pins, when it is installed beside antechamber. */
|
|
35
|
+
export function bundledOmo() {
|
|
36
|
+
try {
|
|
37
|
+
return join(dirname(createRequire(import.meta.url).resolve("omo-ai/package.json")), "bin", "omo.js");
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Agent executable spawned per session: the pinned OmO by default, else `omo` on PATH, plain pi when configured. */
|
|
44
|
+
export function agentBinary(env = process.env, bundled = bundledOmo) {
|
|
45
|
+
return envSetting("PI_BINARY", env) ?? bundled() ?? "omo";
|
|
46
|
+
}
|
|
47
|
+
/** Set by the OpenChamber extension's launcher: the extension, not npm, installs and updates antechamber. */
|
|
48
|
+
export function managedByExtension(env = process.env) {
|
|
49
|
+
return envSetting("MANAGED", env) === "openchamber-extension";
|
|
36
50
|
}
|
|
37
51
|
/** True when the configured backend is upstream pi rather than OmO. */
|
|
38
52
|
export function isPlainPi(env = process.env) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Operator diagnostics. Route labels contain only literals and parameter names. */
|
|
2
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
3
|
+
export declare class LatencyMonitor {
|
|
4
|
+
private readonly lagThreshold;
|
|
5
|
+
private readonly requestThreshold;
|
|
6
|
+
private timer;
|
|
7
|
+
start(): void;
|
|
8
|
+
stop(): void;
|
|
9
|
+
request(req: IncomingMessage, res: ServerResponse, handle: () => Promise<void>): Promise<void>;
|
|
10
|
+
}
|
package/dist/latency.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { performance } from "node:perf_hooks";
|
|
2
|
+
import { envSetting } from "./config.js";
|
|
3
|
+
const SAMPLE_MS = 100;
|
|
4
|
+
// The router uses explicit path comparisons rather than a routing framework. Unknown
|
|
5
|
+
// paths get a constant label so neither identifiers nor query credentials enter logs.
|
|
6
|
+
const ROUTE_PATTERNS = `
|
|
7
|
+
/ /health /global/health /global/upgrade /event /global/event
|
|
8
|
+
/session /session/status /project /project/current /config /global/config /provider
|
|
9
|
+
/config/providers /experimental/session /question /permission /lsp /formatter
|
|
10
|
+
/command /path /vcs /agent /file /file/content /file/status /find /find/file /find/symbol
|
|
11
|
+
/provider/auth /auth/:providerID /provider/:providerID/oauth/authorize /provider/:providerID/oauth/callback
|
|
12
|
+
/question/:requestID/reply /question/:requestID/reject /permission/:requestID/reply
|
|
13
|
+
/api/info /api/location /api/config /api/provider /api/model /api/model/default
|
|
14
|
+
/api/agent /api/agent/:agentID /api/command /api/skill /api/debug/location
|
|
15
|
+
/api/credential /api/credential/:credentialID /api/credential/:credentialID/activate
|
|
16
|
+
/api/integration/:integrationID /api/integration/:integrationID/connect/key
|
|
17
|
+
/api/integration/:integrationID/connect/external /api/integration/:integrationID/connect/oauth
|
|
18
|
+
/api/integration/:integrationID/connect/command /api/integration/:integrationID/connect/oauth/:flowID
|
|
19
|
+
/api/integration/:integrationID/connect/command/:flowID
|
|
20
|
+
/api/integration/:integrationID/connect/oauth/:flowID/complete
|
|
21
|
+
/api/plugin /api/plugin/check /api/plugin/update /api/experimental/generate /api/experimental/generate/text
|
|
22
|
+
/api/shell /api/shell/:shellID /api/shell/:shellID/output /api/websearch/provider
|
|
23
|
+
/api/experimental/session/stats /api/experimental/usage/limits /api/experimental/fs/watch
|
|
24
|
+
/api/fs/find /api/project /api/project/:projectID /api/permission/request /api/question/request
|
|
25
|
+
/api/permission/saved /api/permission/saved/:permissionID /api/form /api/vcs/init /api/vcs
|
|
26
|
+
/api/session /api/session/active /api/event /api/global/event/ws
|
|
27
|
+
/api/experimental/session/:sessionID/instructions/entries/:entryID
|
|
28
|
+
/antechamber/work-status/:sessionID
|
|
29
|
+
`
|
|
30
|
+
.trim()
|
|
31
|
+
.split(/\s+/);
|
|
32
|
+
for (const prefix of ["", "/api"]) {
|
|
33
|
+
const base = `${prefix}/session/:sessionID`;
|
|
34
|
+
ROUTE_PATTERNS.push(base, `${base}/message/:messageID`);
|
|
35
|
+
for (const action of [
|
|
36
|
+
"diff",
|
|
37
|
+
"children",
|
|
38
|
+
"todo",
|
|
39
|
+
"message",
|
|
40
|
+
"prompt_async",
|
|
41
|
+
"abort",
|
|
42
|
+
"fork",
|
|
43
|
+
"revert",
|
|
44
|
+
"unrevert",
|
|
45
|
+
"summarize",
|
|
46
|
+
"shell",
|
|
47
|
+
"command",
|
|
48
|
+
"share",
|
|
49
|
+
"generate",
|
|
50
|
+
"background",
|
|
51
|
+
"move",
|
|
52
|
+
"view",
|
|
53
|
+
"compact",
|
|
54
|
+
"prompt",
|
|
55
|
+
"synthetic",
|
|
56
|
+
"context",
|
|
57
|
+
"interrupt",
|
|
58
|
+
"revert/stage",
|
|
59
|
+
"revert/commit",
|
|
60
|
+
"agent",
|
|
61
|
+
"model",
|
|
62
|
+
"form",
|
|
63
|
+
"question",
|
|
64
|
+
"permission",
|
|
65
|
+
"inbox",
|
|
66
|
+
])
|
|
67
|
+
ROUTE_PATTERNS.push(`${base}/${action}`);
|
|
68
|
+
for (const resource of ["form", "question", "permission"])
|
|
69
|
+
for (const suffix of ["", "/reply", "/reject"])
|
|
70
|
+
ROUTE_PATTERNS.push(`${base}/${resource}/:requestID${suffix}`);
|
|
71
|
+
}
|
|
72
|
+
const routes = ROUTE_PATTERNS.map((pattern) => ({
|
|
73
|
+
pattern,
|
|
74
|
+
match: new RegExp(`^${pattern.replace(/:[A-Za-z]+/g, "[^/]+")}$`),
|
|
75
|
+
}));
|
|
76
|
+
function routePattern(req) {
|
|
77
|
+
const path = new URL(req.url ?? "/", "http://localhost").pathname.replace(/\/+$/, "") || "/";
|
|
78
|
+
return routes.find((route) => route.match.test(path))?.pattern ?? "unmatched";
|
|
79
|
+
}
|
|
80
|
+
function threshold(name, fallback) {
|
|
81
|
+
const value = Number(envSetting(name));
|
|
82
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
83
|
+
}
|
|
84
|
+
export class LatencyMonitor {
|
|
85
|
+
lagThreshold = threshold("EVENT_LOOP_LAG_MS", 250);
|
|
86
|
+
requestThreshold = threshold("SLOW_REQUEST_MS", 1000);
|
|
87
|
+
timer;
|
|
88
|
+
start() {
|
|
89
|
+
let expected = performance.now() + SAMPLE_MS;
|
|
90
|
+
this.timer = setInterval(() => {
|
|
91
|
+
const now = performance.now();
|
|
92
|
+
const lag = now - expected;
|
|
93
|
+
expected = now + SAMPLE_MS;
|
|
94
|
+
if (lag > this.lagThreshold)
|
|
95
|
+
console.warn(`[latency] event-loop-lag duration_ms=${Math.round(lag)} threshold_ms=${this.lagThreshold}`);
|
|
96
|
+
}, SAMPLE_MS);
|
|
97
|
+
this.timer.unref();
|
|
98
|
+
}
|
|
99
|
+
stop() {
|
|
100
|
+
clearInterval(this.timer);
|
|
101
|
+
this.timer = undefined;
|
|
102
|
+
}
|
|
103
|
+
async request(req, res, handle) {
|
|
104
|
+
const start = performance.now();
|
|
105
|
+
try {
|
|
106
|
+
await handle();
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
// SSE handlers return after setup; connection lifetime is not request latency.
|
|
110
|
+
const duration = performance.now() - start;
|
|
111
|
+
if (duration > this.requestThreshold)
|
|
112
|
+
console.warn(`[latency] slow-request method=${req.method ?? "GET"} route=${routePattern(req)} status=${res.statusCode} duration_ms=${Math.round(duration)}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
package/dist/misc-routes.js
CHANGED
|
@@ -42,18 +42,10 @@ async function confinedDirectory(root, path) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
export async function miscRoute(method, path, url, directory) {
|
|
45
|
-
if (method === "GET" && ["/skill", "/
|
|
45
|
+
if (method === "GET" && ["/skill", "/formatter"].includes(path)) {
|
|
46
46
|
return { status: 200, body: [] };
|
|
47
47
|
}
|
|
48
|
-
if (
|
|
49
|
-
return { status: 200, body: {} };
|
|
50
|
-
if ((method === "PUT" && /^\/auth\/[^/]+$/.test(path)) ||
|
|
51
|
-
(method === "POST" && /^\/provider\/[^/]+\/oauth\/(authorize|callback)$/.test(path)) ||
|
|
52
|
-
(method === "PATCH" && path === "/config")) {
|
|
53
|
-
return unsupported("Not supported with OmO; configure providers in OmO");
|
|
54
|
-
}
|
|
55
|
-
if ((["POST", "DELETE"].includes(method) && /^\/mcp\/[^/]+\/(connect|disconnect|auth)$/.test(path)) ||
|
|
56
|
-
(method === "POST" && path === "/experimental/control-plane/move-session")) {
|
|
48
|
+
if (["POST", "DELETE"].includes(method) && /^\/mcp\/[^/]+\/(connect|disconnect|auth)$/.test(path)) {
|
|
57
49
|
return unsupported("Not supported with OmO; configure MCP and session directories in OmO");
|
|
58
50
|
}
|
|
59
51
|
if (method !== "GET" || !["/file", "/find/file"].includes(path))
|
package/dist/route-services.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ import type { Catalog } from "./catalog.js";
|
|
|
5
5
|
import type { ModelSelection } from "./thinking-levels.js";
|
|
6
6
|
import type { OCEvent, OCMessageWithParts, OCPromptPart } from "./types.js";
|
|
7
7
|
import type { TodoUpdated } from "./todo-bridge.js";
|
|
8
|
-
import type { SelfUpdateResult } from "./self-update.js";
|
|
9
8
|
import type { FileWatchRegistry } from "./file-watch.js";
|
|
10
9
|
import type { getCommands } from "./session-commands.js";
|
|
11
10
|
import type { TextGeneration } from "./text-generation.js";
|
|
@@ -16,7 +15,6 @@ export interface RouteServices {
|
|
|
16
15
|
readonly body: (req: IncomingMessage) => Promise<unknown>;
|
|
17
16
|
readonly catalog: (directory?: string, refresh?: boolean) => Promise<Catalog>;
|
|
18
17
|
readonly broadcast: (directory: string, event: OCEvent | TodoUpdated) => void;
|
|
19
|
-
readonly selfUpdate: () => Promise<SelfUpdateResult>;
|
|
20
18
|
readonly fileWatches: FileWatchRegistry;
|
|
21
19
|
readonly commands: (directory: string) => ReturnType<typeof getCommands>;
|
|
22
20
|
readonly vcsBranch: (directory: string) => Promise<string | undefined>;
|
package/dist/routes-v1.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Unprefixed compatibility routes retained for evidenced or uncertain callers. */
|
|
2
2
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
3
3
|
import { type RouteServices } from "./route-services.js";
|
|
4
4
|
export declare function handleV1(services: RouteServices, req: IncomingMessage, res: ServerResponse, url: URL, path: string, method: string, directory: string): Promise<void>;
|