@covro/covro 0.0.0-stage → 0.1.0-dev.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/LICENSE +21 -0
- package/README.md +173 -2
- package/README.zh-CN.md +174 -0
- package/bin/covro.mjs +8 -0
- package/dist/cli/control.js +66 -0
- package/dist/cli/control.js.map +7 -0
- package/dist/cli/daemon.js +118 -0
- package/dist/cli/daemon.js.map +7 -0
- package/dist/cli/main.js +152 -0
- package/dist/cli/main.js.map +7 -0
- package/dist/cli/paths.js +60 -0
- package/dist/cli/paths.js.map +7 -0
- package/dist/cli/service.js +87 -0
- package/dist/cli/service.js.map +7 -0
- package/dist/codex/adapter.js +1195 -0
- package/dist/codex/adapter.js.map +7 -0
- package/dist/codex/auto-review.js +102 -0
- package/dist/codex/auto-review.js.map +7 -0
- package/dist/codex/compatibility.js +7 -0
- package/dist/codex/compatibility.js.map +7 -0
- package/dist/codex/mapping.js +210 -0
- package/dist/codex/mapping.js.map +7 -0
- package/dist/codex/permissions.js +51 -0
- package/dist/codex/permissions.js.map +7 -0
- package/dist/codex/thread-title-policy.js +52 -0
- package/dist/codex/thread-title-policy.js.map +7 -0
- package/dist/codex/thread-titles.js +259 -0
- package/dist/codex/thread-titles.js.map +7 -0
- package/dist/codex/transport.js +236 -0
- package/dist/codex/transport.js.map +7 -0
- package/dist/codex/turn-token-usage.js +46 -0
- package/dist/codex/turn-token-usage.js.map +7 -0
- package/dist/codex/types.js +1 -0
- package/dist/codex/types.js.map +7 -0
- package/dist/drizzle/0000_past_wildside.sql +45 -0
- package/dist/drizzle/0001_shocking_ender_wiggin.sql +2 -0
- package/dist/drizzle/0002_allow_parallel_threads.sql +1 -0
- package/dist/drizzle/0003_project_registrations.sql +11 -0
- package/dist/drizzle/0004_turn_usage.sql +6 -0
- package/dist/drizzle/meta/0000_snapshot.json +309 -0
- package/dist/drizzle/meta/0001_snapshot.json +323 -0
- package/dist/drizzle/meta/0002_snapshot.json +315 -0
- package/dist/drizzle/meta/0003_snapshot.json +381 -0
- package/dist/drizzle/meta/0004_snapshot.json +420 -0
- package/dist/drizzle/meta/_journal.json +41 -0
- package/dist/server/auth.js +47 -0
- package/dist/server/auth.js.map +7 -0
- package/dist/server/compaction.js +40 -0
- package/dist/server/compaction.js.map +7 -0
- package/dist/server/config-store.js +147 -0
- package/dist/server/config-store.js.map +7 -0
- package/dist/server/config.js +124 -0
- package/dist/server/config.js.map +7 -0
- package/dist/server/db/index.js +21 -0
- package/dist/server/db/index.js.map +7 -0
- package/dist/server/db/migrate.js +26 -0
- package/dist/server/db/migrate.js.map +7 -0
- package/dist/server/db/operations.js +201 -0
- package/dist/server/db/operations.js.map +7 -0
- package/dist/server/db/schema.js +99 -0
- package/dist/server/db/schema.js.map +7 -0
- package/dist/server/db/turn-usage.js +31 -0
- package/dist/server/db/turn-usage.js.map +7 -0
- package/dist/server/events.js +123 -0
- package/dist/server/events.js.map +7 -0
- package/dist/server/http.js +305 -0
- package/dist/server/http.js.map +7 -0
- package/dist/server/images.js +49 -0
- package/dist/server/images.js.map +7 -0
- package/dist/server/instance-lock.js +25 -0
- package/dist/server/instance-lock.js.map +7 -0
- package/dist/server/local-files.js +100 -0
- package/dist/server/local-files.js.map +7 -0
- package/dist/server/main.js +125 -0
- package/dist/server/main.js.map +7 -0
- package/dist/server/markdown.js +28 -0
- package/dist/server/markdown.js.map +7 -0
- package/dist/server/projection.js +348 -0
- package/dist/server/projection.js.map +7 -0
- package/dist/server/projects.js +230 -0
- package/dist/server/projects.js.map +7 -0
- package/dist/server/service.js +1221 -0
- package/dist/server/service.js.map +7 -0
- package/dist/server/snapshot.js +98 -0
- package/dist/server/snapshot.js.map +7 -0
- package/dist/server/thread-export.js +97 -0
- package/dist/server/thread-export.js.map +7 -0
- package/dist/server/websocket.js +126 -0
- package/dist/server/websocket.js.map +7 -0
- package/dist/shared/async-questions.js +39 -0
- package/dist/shared/async-questions.js.map +7 -0
- package/dist/shared/codex-compatibility.js +56 -0
- package/dist/shared/codex-compatibility.js.map +7 -0
- package/dist/shared/elicitation.js +314 -0
- package/dist/shared/elicitation.js.map +7 -0
- package/dist/shared/errors.js +24 -0
- package/dist/shared/errors.js.map +7 -0
- package/dist/shared/gateway-config.js +1 -0
- package/dist/shared/gateway-config.js.map +7 -0
- package/dist/shared/images.js +21 -0
- package/dist/shared/images.js.map +7 -0
- package/dist/shared/package.js +5 -0
- package/dist/shared/package.js.map +7 -0
- package/dist/shared/permissions.js +63 -0
- package/dist/shared/permissions.js.map +7 -0
- package/dist/shared/thread-name.js +14 -0
- package/dist/shared/thread-name.js.map +7 -0
- package/dist/shared/thread-summary.js +24 -0
- package/dist/shared/thread-summary.js.map +7 -0
- package/dist/shared/types.js +1 -0
- package/dist/shared/types.js.map +7 -0
- package/dist/shared/updates.js +7 -0
- package/dist/shared/updates.js.map +7 -0
- package/dist/shared/validation.js +116 -0
- package/dist/shared/validation.js.map +7 -0
- package/dist/shared/versions.js +36 -0
- package/dist/shared/versions.js.map +7 -0
- package/dist/update-worker.cjs +21968 -0
- package/dist/updates/files.js +54 -0
- package/dist/updates/files.js.map +7 -0
- package/dist/updates/manager.js +315 -0
- package/dist/updates/manager.js.map +7 -0
- package/dist/updates/registry.js +71 -0
- package/dist/updates/registry.js.map +7 -0
- package/dist/updates/transaction.js +96 -0
- package/dist/updates/transaction.js.map +7 -0
- package/dist/updates/worker.js +345 -0
- package/dist/updates/worker.js.map +7 -0
- package/dist/web/assets/index-BW9afH_Y.js +83 -0
- package/dist/web/assets/index-L3S1ZiO0.css +1 -0
- package/dist/web/covro.svg +6 -0
- package/dist/web/index.html +15 -0
- package/package.json +88 -4
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { AppError } from "../shared/errors.js";
|
|
3
|
+
const DEFAULT_MAX_LINE_BYTES = 64 * 1024 * 1024;
|
|
4
|
+
class CodexError extends AppError {
|
|
5
|
+
constructor(code, message, uncertain = false, rpcCode, diagnostics) {
|
|
6
|
+
super(code, message, 503, { uncertain, rpcCode, ...diagnostics });
|
|
7
|
+
this.uncertain = uncertain;
|
|
8
|
+
this.rpcCode = rpcCode;
|
|
9
|
+
this.name = "CodexError";
|
|
10
|
+
}
|
|
11
|
+
uncertain;
|
|
12
|
+
rpcCode;
|
|
13
|
+
}
|
|
14
|
+
class JsonLineReader {
|
|
15
|
+
constructor(consume, maxBytes = DEFAULT_MAX_LINE_BYTES) {
|
|
16
|
+
this.consume = consume;
|
|
17
|
+
this.maxBytes = maxBytes;
|
|
18
|
+
}
|
|
19
|
+
consume;
|
|
20
|
+
maxBytes;
|
|
21
|
+
parts = [];
|
|
22
|
+
size = 0;
|
|
23
|
+
decoder = new TextDecoder("utf-8", { fatal: true });
|
|
24
|
+
push(chunk) {
|
|
25
|
+
let start = 0;
|
|
26
|
+
while (start < chunk.length) {
|
|
27
|
+
const newline = chunk.indexOf(10, start);
|
|
28
|
+
const end = newline < 0 ? chunk.length : newline;
|
|
29
|
+
const part = chunk.subarray(start, end);
|
|
30
|
+
this.size += part.length;
|
|
31
|
+
if (this.size > this.maxBytes) {
|
|
32
|
+
const receivedBytes = this.size;
|
|
33
|
+
this.parts = [];
|
|
34
|
+
this.size = 0;
|
|
35
|
+
throw new CodexError(
|
|
36
|
+
"PROTOCOL_ERROR",
|
|
37
|
+
`Codex JSONL message exceeds the configured limit (received at least ${receivedBytes} bytes; limit ${this.maxBytes} bytes)`,
|
|
38
|
+
true,
|
|
39
|
+
void 0,
|
|
40
|
+
{ receivedBytes, maxLineBytes: this.maxBytes }
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
if (part.length) this.parts.push(part);
|
|
44
|
+
if (newline < 0) break;
|
|
45
|
+
this.flush();
|
|
46
|
+
start = newline + 1;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
finish() {
|
|
50
|
+
if (this.size) this.flush();
|
|
51
|
+
}
|
|
52
|
+
flush() {
|
|
53
|
+
const bytes = Buffer.concat(this.parts, this.size);
|
|
54
|
+
this.parts = [];
|
|
55
|
+
this.size = 0;
|
|
56
|
+
try {
|
|
57
|
+
const line = this.decoder.decode(bytes).trim();
|
|
58
|
+
if (line) this.consume(JSON.parse(line));
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (error instanceof CodexError) throw error;
|
|
61
|
+
throw new CodexError("PROTOCOL_ERROR", "Invalid UTF-8 or JSON from Codex", true);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class RpcTransport extends EventEmitter {
|
|
66
|
+
constructor(input, output, options = {}) {
|
|
67
|
+
super();
|
|
68
|
+
this.input = input;
|
|
69
|
+
this.options = options;
|
|
70
|
+
this.reader = new JsonLineReader((value) => this.receive(value), options.maxLineBytes);
|
|
71
|
+
output.on("data", (chunk) => {
|
|
72
|
+
if (this.failure) return;
|
|
73
|
+
try {
|
|
74
|
+
this.reader.push(chunk);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
this.fail(asCodexError(error));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
output.on("end", () => {
|
|
80
|
+
if (this.failure) return;
|
|
81
|
+
try {
|
|
82
|
+
this.reader.finish();
|
|
83
|
+
} catch (error) {
|
|
84
|
+
this.fail(asCodexError(error));
|
|
85
|
+
}
|
|
86
|
+
this.fail(new CodexError("CODEX_UNAVAILABLE", "Codex stdout reached EOF", true));
|
|
87
|
+
});
|
|
88
|
+
output.on(
|
|
89
|
+
"close",
|
|
90
|
+
() => this.fail(new CodexError("CODEX_UNAVAILABLE", "Codex stdout closed", true))
|
|
91
|
+
);
|
|
92
|
+
output.on(
|
|
93
|
+
"error",
|
|
94
|
+
(error) => this.fail(new CodexError("CODEX_UNAVAILABLE", error.message, true))
|
|
95
|
+
);
|
|
96
|
+
input.on(
|
|
97
|
+
"error",
|
|
98
|
+
(error) => this.fail(new CodexError("CODEX_UNAVAILABLE", error.message, true))
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
input;
|
|
102
|
+
options;
|
|
103
|
+
pending = /* @__PURE__ */ new Map();
|
|
104
|
+
nextId = 0;
|
|
105
|
+
failure;
|
|
106
|
+
reader;
|
|
107
|
+
request(method, params, id = this.nextId++) {
|
|
108
|
+
if (this.failure) return Promise.reject(this.failure);
|
|
109
|
+
if (this.pending.has(id))
|
|
110
|
+
return Promise.reject(new CodexError("PROTOCOL_ERROR", "Duplicate outgoing RPC id"));
|
|
111
|
+
if (this.pending.size >= (this.options.maxPending ?? 256))
|
|
112
|
+
return Promise.reject(new CodexError("CODEX_BUSY", "Too many pending Codex requests"));
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
const timer = setTimeout(() => {
|
|
115
|
+
this.pending.delete(id);
|
|
116
|
+
reject(
|
|
117
|
+
new CodexError(
|
|
118
|
+
"RESULT_UNKNOWN",
|
|
119
|
+
`Codex ${method} acknowledgement timed out; it may have executed`,
|
|
120
|
+
true
|
|
121
|
+
)
|
|
122
|
+
);
|
|
123
|
+
}, this.options.timeoutMs ?? 3e4);
|
|
124
|
+
this.pending.set(id, { method, resolve: (result) => resolve(result), reject, timer });
|
|
125
|
+
void this.write({ id, method, params }).catch((error) => {
|
|
126
|
+
const pending = this.pending.get(id);
|
|
127
|
+
if (!pending) return;
|
|
128
|
+
clearTimeout(pending.timer);
|
|
129
|
+
this.pending.delete(id);
|
|
130
|
+
pending.reject(asCodexError(error));
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
notify(method, params) {
|
|
135
|
+
return this.write({ method, ...params === void 0 ? {} : { params } });
|
|
136
|
+
}
|
|
137
|
+
respond(id, result) {
|
|
138
|
+
return this.write({ id, result });
|
|
139
|
+
}
|
|
140
|
+
reject(id, code, message) {
|
|
141
|
+
return this.write({ id, error: { code, message } });
|
|
142
|
+
}
|
|
143
|
+
fail(error) {
|
|
144
|
+
if (this.failure) return;
|
|
145
|
+
error = new CodexError(error.code, error.message, error.uncertain, error.rpcCode, {
|
|
146
|
+
...isRecord(error.details) ? error.details : {},
|
|
147
|
+
pendingRequests: [...this.pending].map(([id, pending]) => ({ id, method: pending.method }))
|
|
148
|
+
});
|
|
149
|
+
this.failure = error;
|
|
150
|
+
for (const pending of this.pending.values()) {
|
|
151
|
+
clearTimeout(pending.timer);
|
|
152
|
+
pending.reject(error);
|
|
153
|
+
}
|
|
154
|
+
this.pending.clear();
|
|
155
|
+
this.emit("failure", error);
|
|
156
|
+
}
|
|
157
|
+
async write(message) {
|
|
158
|
+
if (this.failure) throw this.failure;
|
|
159
|
+
const data = JSON.stringify(message) + "\n";
|
|
160
|
+
if (this.input.destroyed || !this.input.writable)
|
|
161
|
+
throw new CodexError("CODEX_UNAVAILABLE", "Codex stdin is closed", true);
|
|
162
|
+
if (this.input.writableLength + Buffer.byteLength(data) > (this.options.maxWriteBytes ?? 4 * 1024 * 1024)) {
|
|
163
|
+
throw new CodexError("CODEX_BUSY", "Codex stdin buffer limit reached");
|
|
164
|
+
}
|
|
165
|
+
await new Promise((resolve, reject) => {
|
|
166
|
+
const timer = setTimeout(() => {
|
|
167
|
+
const error = new CodexError("RESULT_UNKNOWN", "Codex stdin write timed out", true);
|
|
168
|
+
this.fail(error);
|
|
169
|
+
reject(error);
|
|
170
|
+
}, this.options.timeoutMs ?? 3e4);
|
|
171
|
+
this.input.write(data, (error) => {
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
if (error) reject(new CodexError("CODEX_UNAVAILABLE", error.message, true));
|
|
174
|
+
else resolve();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
receive(value) {
|
|
179
|
+
if (!isRecord(value))
|
|
180
|
+
throw new CodexError("PROTOCOL_ERROR", "Codex sent a non-object RPC message", true);
|
|
181
|
+
const hasId = Object.hasOwn(value, "id");
|
|
182
|
+
if (hasId && !isRpcId(value.id))
|
|
183
|
+
throw new CodexError("PROTOCOL_ERROR", "Codex sent an invalid RPC id", true);
|
|
184
|
+
if (typeof value.method === "string") {
|
|
185
|
+
if (Object.hasOwn(value, "result") || Object.hasOwn(value, "error"))
|
|
186
|
+
throw new CodexError("PROTOCOL_ERROR", "Codex mixed a method and RPC result", true);
|
|
187
|
+
if (hasId) this.emit("request", value);
|
|
188
|
+
else this.emit("notification", value);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (!hasId || Object.hasOwn(value, "result") === Object.hasOwn(value, "error"))
|
|
192
|
+
throw new CodexError("PROTOCOL_ERROR", "Unrecognized Codex RPC message", true);
|
|
193
|
+
const pending = this.pending.get(value.id);
|
|
194
|
+
if (!pending) return;
|
|
195
|
+
this.pending.delete(value.id);
|
|
196
|
+
clearTimeout(pending.timer);
|
|
197
|
+
if (Object.hasOwn(value, "error")) {
|
|
198
|
+
if (!isRecord(value.error) || typeof value.error.message !== "string" || typeof value.error.code !== "number") {
|
|
199
|
+
const error = new CodexError("PROTOCOL_ERROR", "Malformed Codex RPC error", true);
|
|
200
|
+
pending.reject(error);
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
pending.reject(
|
|
204
|
+
new CodexError(
|
|
205
|
+
value.error.code === -32601 ? "PROTOCOL_INCOMPATIBLE" : "CODEX_REQUEST_FAILED",
|
|
206
|
+
value.error.message,
|
|
207
|
+
false,
|
|
208
|
+
value.error.code
|
|
209
|
+
)
|
|
210
|
+
);
|
|
211
|
+
} else pending.resolve(value.result);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function isRecord(value) {
|
|
215
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
216
|
+
}
|
|
217
|
+
function isRpcId(value) {
|
|
218
|
+
return typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
219
|
+
}
|
|
220
|
+
function asCodexError(error) {
|
|
221
|
+
return error instanceof CodexError ? error : new CodexError(
|
|
222
|
+
"CODEX_UNAVAILABLE",
|
|
223
|
+
error instanceof Error ? error.message : String(error),
|
|
224
|
+
true
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
export {
|
|
228
|
+
CodexError,
|
|
229
|
+
DEFAULT_MAX_LINE_BYTES,
|
|
230
|
+
JsonLineReader,
|
|
231
|
+
RpcTransport,
|
|
232
|
+
asCodexError,
|
|
233
|
+
isRecord,
|
|
234
|
+
isRpcId
|
|
235
|
+
};
|
|
236
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/codex/transport.ts"],
|
|
4
|
+
"sourcesContent": ["import { EventEmitter } from 'node:events';\nimport { AppError } from '../shared/errors.js';\nimport type { Readable, Writable } from 'node:stream';\n\nexport type RpcId = string | number;\nexport type RpcNotification = { method: string; params?: unknown };\nexport type RpcServerRequest = RpcNotification & { id: RpcId };\nexport const DEFAULT_MAX_LINE_BYTES = 64 * 1024 * 1024;\nexport class CodexError extends AppError {\n constructor(\n code: string,\n message: string,\n public readonly uncertain = false,\n public readonly rpcCode?: number,\n diagnostics?: Record<string, unknown>,\n ) {\n super(code, message, 503, { uncertain, rpcCode, ...diagnostics });\n this.name = 'CodexError';\n }\n}\n\n/** Buffers at most one bounded line. Decoding the complete byte sequence preserves split UTF-8. */\nexport class JsonLineReader {\n private parts: Buffer[] = [];\n private size = 0;\n private readonly decoder = new TextDecoder('utf-8', { fatal: true });\n constructor(\n private readonly consume: (value: unknown) => void,\n private readonly maxBytes = DEFAULT_MAX_LINE_BYTES,\n ) {}\n push(chunk: Buffer): void {\n let start = 0;\n while (start < chunk.length) {\n const newline = chunk.indexOf(10, start);\n const end = newline < 0 ? chunk.length : newline;\n const part = chunk.subarray(start, end);\n this.size += part.length;\n if (this.size > this.maxBytes) {\n const receivedBytes = this.size;\n this.parts = [];\n this.size = 0;\n throw new CodexError(\n 'PROTOCOL_ERROR',\n `Codex JSONL message exceeds the configured limit (received at least ${receivedBytes} bytes; limit ${this.maxBytes} bytes)`,\n true,\n undefined,\n { receivedBytes, maxLineBytes: this.maxBytes },\n );\n }\n if (part.length) this.parts.push(part);\n if (newline < 0) break;\n this.flush();\n start = newline + 1;\n }\n }\n finish(): void {\n if (this.size) this.flush();\n }\n private flush(): void {\n const bytes = Buffer.concat(this.parts, this.size);\n this.parts = [];\n this.size = 0;\n try {\n const line = this.decoder.decode(bytes).trim();\n if (line) this.consume(JSON.parse(line) as unknown);\n } catch (error) {\n if (error instanceof CodexError) throw error;\n throw new CodexError('PROTOCOL_ERROR', 'Invalid UTF-8 or JSON from Codex', true);\n }\n }\n}\n\ntype Pending = {\n method: string;\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout;\n};\nexport type TransportOptions = {\n timeoutMs?: number;\n maxLineBytes?: number;\n maxPending?: number;\n maxWriteBytes?: number;\n};\n\n/** RPC receipt deadlines do not cancel upstream turns. A timeout always reports an uncertain outcome. */\nexport class RpcTransport extends EventEmitter {\n private readonly pending = new Map<RpcId, Pending>();\n private nextId = 0;\n private failure?: CodexError;\n private readonly reader: JsonLineReader;\n constructor(\n private readonly input: Writable,\n output: Readable,\n private readonly options: TransportOptions = {},\n ) {\n super();\n this.reader = new JsonLineReader((value) => this.receive(value), options.maxLineBytes);\n output.on('data', (chunk: Buffer) => {\n if (this.failure) return;\n try {\n this.reader.push(chunk);\n } catch (error) {\n this.fail(asCodexError(error));\n }\n });\n output.on('end', () => {\n if (this.failure) return;\n try {\n this.reader.finish();\n } catch (error) {\n this.fail(asCodexError(error));\n }\n this.fail(new CodexError('CODEX_UNAVAILABLE', 'Codex stdout reached EOF', true));\n });\n output.on('close', () =>\n this.fail(new CodexError('CODEX_UNAVAILABLE', 'Codex stdout closed', true)),\n );\n output.on('error', (error) =>\n this.fail(new CodexError('CODEX_UNAVAILABLE', error.message, true)),\n );\n input.on('error', (error) =>\n this.fail(new CodexError('CODEX_UNAVAILABLE', error.message, true)),\n );\n }\n request<T>(method: string, params: unknown, id: RpcId = this.nextId++): Promise<T> {\n if (this.failure) return Promise.reject(this.failure);\n if (this.pending.has(id))\n return Promise.reject(new CodexError('PROTOCOL_ERROR', 'Duplicate outgoing RPC id'));\n if (this.pending.size >= (this.options.maxPending ?? 256))\n return Promise.reject(new CodexError('CODEX_BUSY', 'Too many pending Codex requests'));\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(\n new CodexError(\n 'RESULT_UNKNOWN',\n `Codex ${method} acknowledgement timed out; it may have executed`,\n true,\n ),\n );\n }, this.options.timeoutMs ?? 30_000);\n this.pending.set(id, { method, resolve: (result) => resolve(result as T), reject, timer });\n void this.write({ id, method, params }).catch((error: unknown) => {\n const pending = this.pending.get(id);\n if (!pending) return;\n clearTimeout(pending.timer);\n this.pending.delete(id);\n pending.reject(asCodexError(error));\n });\n });\n }\n notify(method: string, params?: unknown): Promise<void> {\n return this.write({ method, ...(params === undefined ? {} : { params }) });\n }\n respond(id: RpcId, result: unknown): Promise<void> {\n return this.write({ id, result });\n }\n reject(id: RpcId, code: number, message: string): Promise<void> {\n return this.write({ id, error: { code, message } });\n }\n fail(error: CodexError): void {\n if (this.failure) return;\n error = new CodexError(error.code, error.message, error.uncertain, error.rpcCode, {\n ...(isRecord(error.details) ? error.details : {}),\n pendingRequests: [...this.pending].map(([id, pending]) => ({ id, method: pending.method })),\n });\n this.failure = error;\n for (const pending of this.pending.values()) {\n clearTimeout(pending.timer);\n pending.reject(error);\n }\n this.pending.clear();\n this.emit('failure', error);\n }\n private async write(message: unknown): Promise<void> {\n if (this.failure) throw this.failure;\n const data = JSON.stringify(message) + '\\n';\n if (this.input.destroyed || !this.input.writable)\n throw new CodexError('CODEX_UNAVAILABLE', 'Codex stdin is closed', true);\n if (\n this.input.writableLength + Buffer.byteLength(data) >\n (this.options.maxWriteBytes ?? 4 * 1024 * 1024)\n ) {\n throw new CodexError('CODEX_BUSY', 'Codex stdin buffer limit reached');\n }\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n const error = new CodexError('RESULT_UNKNOWN', 'Codex stdin write timed out', true);\n this.fail(error);\n reject(error);\n }, this.options.timeoutMs ?? 30_000);\n this.input.write(data, (error) => {\n clearTimeout(timer);\n if (error) reject(new CodexError('CODEX_UNAVAILABLE', error.message, true));\n else resolve();\n });\n });\n }\n private receive(value: unknown): void {\n if (!isRecord(value))\n throw new CodexError('PROTOCOL_ERROR', 'Codex sent a non-object RPC message', true);\n const hasId = Object.hasOwn(value, 'id');\n if (hasId && !isRpcId(value.id))\n throw new CodexError('PROTOCOL_ERROR', 'Codex sent an invalid RPC id', true);\n if (typeof value.method === 'string') {\n if (Object.hasOwn(value, 'result') || Object.hasOwn(value, 'error'))\n throw new CodexError('PROTOCOL_ERROR', 'Codex mixed a method and RPC result', true);\n if (hasId) this.emit('request', value as RpcServerRequest);\n else this.emit('notification', value as RpcNotification);\n return;\n }\n if (!hasId || Object.hasOwn(value, 'result') === Object.hasOwn(value, 'error'))\n throw new CodexError('PROTOCOL_ERROR', 'Unrecognized Codex RPC message', true);\n const pending = this.pending.get(value.id as RpcId);\n if (!pending) return; // Late receipts after a timeout must never cause a prompt to be resent.\n this.pending.delete(value.id as RpcId);\n clearTimeout(pending.timer);\n if (Object.hasOwn(value, 'error')) {\n if (\n !isRecord(value.error) ||\n typeof value.error.message !== 'string' ||\n typeof value.error.code !== 'number'\n ) {\n const error = new CodexError('PROTOCOL_ERROR', 'Malformed Codex RPC error', true);\n pending.reject(error);\n throw error;\n }\n pending.reject(\n new CodexError(\n value.error.code === -32601 ? 'PROTOCOL_INCOMPATIBLE' : 'CODEX_REQUEST_FAILED',\n value.error.message,\n false,\n value.error.code,\n ),\n );\n } else pending.resolve(value.result);\n }\n}\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\nexport function isRpcId(value: unknown): value is RpcId {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n}\nexport function asCodexError(error: unknown): CodexError {\n return error instanceof CodexError\n ? error\n : new CodexError(\n 'CODEX_UNAVAILABLE',\n error instanceof Error ? error.message : String(error),\n true,\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
class TurnTokenUsage {
|
|
2
|
+
threads = /* @__PURE__ */ new Map();
|
|
3
|
+
clear() {
|
|
4
|
+
this.threads.clear();
|
|
5
|
+
}
|
|
6
|
+
created(threadId) {
|
|
7
|
+
if (!this.threads.has(threadId)) this.threads.set(threadId, { total: 0 });
|
|
8
|
+
}
|
|
9
|
+
started(threadId, turnId) {
|
|
10
|
+
const state = this.threads.get(threadId) ?? {};
|
|
11
|
+
if (state.active?.id === turnId) return;
|
|
12
|
+
state.active = { id: turnId, baseline: state.total, invalid: false };
|
|
13
|
+
this.threads.set(threadId, state);
|
|
14
|
+
}
|
|
15
|
+
updated(threadId, turnId, total) {
|
|
16
|
+
const state = this.threads.get(threadId) ?? {};
|
|
17
|
+
const active = state.active;
|
|
18
|
+
if (active && active.id !== turnId) return;
|
|
19
|
+
if (!Number.isSafeInteger(total) || total < 0) {
|
|
20
|
+
if (active) active.invalid = true;
|
|
21
|
+
delete state.total;
|
|
22
|
+
} else {
|
|
23
|
+
if (active) {
|
|
24
|
+
if (state.total !== void 0 && total < state.total) active.invalid = true;
|
|
25
|
+
if (active.baseline !== void 0) active.outputTokens = total - active.baseline;
|
|
26
|
+
}
|
|
27
|
+
state.total = total;
|
|
28
|
+
}
|
|
29
|
+
this.threads.set(threadId, state);
|
|
30
|
+
}
|
|
31
|
+
compacted(threadId, turnId) {
|
|
32
|
+
const active = this.threads.get(threadId)?.active;
|
|
33
|
+
if (active?.id === turnId) active.invalid = true;
|
|
34
|
+
}
|
|
35
|
+
completed(threadId, turnId) {
|
|
36
|
+
const state = this.threads.get(threadId);
|
|
37
|
+
if (state?.active?.id !== turnId) return void 0;
|
|
38
|
+
const active = state.active;
|
|
39
|
+
delete state.active;
|
|
40
|
+
return active.invalid ? void 0 : active.outputTokens;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
TurnTokenUsage
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=turn-token-usage.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/codex/turn-token-usage.ts"],
|
|
4
|
+
"sourcesContent": ["/** Thread usage is cumulative; `last` describes one model response, not one turn. */\nexport class TurnTokenUsage {\n private readonly threads = new Map<\n string,\n {\n total?: number;\n active?: { id: string; baseline?: number; outputTokens?: number; invalid: boolean };\n }\n >();\n\n clear(): void {\n this.threads.clear();\n }\n\n created(threadId: string): void {\n if (!this.threads.has(threadId)) this.threads.set(threadId, { total: 0 });\n }\n\n started(threadId: string, turnId: string): void {\n const state = this.threads.get(threadId) ?? {};\n if (state.active?.id === turnId) return;\n state.active = { id: turnId, baseline: state.total, invalid: false };\n this.threads.set(threadId, state);\n }\n\n updated(threadId: string, turnId: string, total: number): void {\n const state = this.threads.get(threadId) ?? {};\n const active = state.active;\n // A replay of another turn's usage must not become this turn's baseline or result.\n if (active && active.id !== turnId) return;\n if (!Number.isSafeInteger(total) || total < 0) {\n if (active) active.invalid = true;\n delete state.total;\n } else {\n if (active) {\n if (state.total !== undefined && total < state.total) active.invalid = true;\n if (active.baseline !== undefined) active.outputTokens = total - active.baseline;\n }\n state.total = total;\n }\n this.threads.set(threadId, state);\n }\n\n compacted(threadId: string, turnId: string): void {\n const active = this.threads.get(threadId)?.active;\n // Compaction can replace cumulative counters. Do not subtract across that reset.\n if (active?.id === turnId) active.invalid = true;\n }\n\n completed(threadId: string, turnId: string): number | undefined {\n const state = this.threads.get(threadId);\n if (state?.active?.id !== turnId) return undefined;\n const active = state.active;\n delete state.active;\n return active.invalid ? undefined : active.outputTokens;\n }\n}\n"],
|
|
5
|
+
"mappings": "AACO,MAAM,eAAe;AAAA,EACT,UAAU,oBAAI,IAM7B;AAAA,EAEF,QAAc;AACZ,SAAK,QAAQ,MAAM;AAAA,EACrB;AAAA,EAEA,QAAQ,UAAwB;AAC9B,QAAI,CAAC,KAAK,QAAQ,IAAI,QAAQ,EAAG,MAAK,QAAQ,IAAI,UAAU,EAAE,OAAO,EAAE,CAAC;AAAA,EAC1E;AAAA,EAEA,QAAQ,UAAkB,QAAsB;AAC9C,UAAM,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,CAAC;AAC7C,QAAI,MAAM,QAAQ,OAAO,OAAQ;AACjC,UAAM,SAAS,EAAE,IAAI,QAAQ,UAAU,MAAM,OAAO,SAAS,MAAM;AACnE,SAAK,QAAQ,IAAI,UAAU,KAAK;AAAA,EAClC;AAAA,EAEA,QAAQ,UAAkB,QAAgB,OAAqB;AAC7D,UAAM,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,CAAC;AAC7C,UAAM,SAAS,MAAM;AAErB,QAAI,UAAU,OAAO,OAAO,OAAQ;AACpC,QAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG;AAC7C,UAAI,OAAQ,QAAO,UAAU;AAC7B,aAAO,MAAM;AAAA,IACf,OAAO;AACL,UAAI,QAAQ;AACV,YAAI,MAAM,UAAU,UAAa,QAAQ,MAAM,MAAO,QAAO,UAAU;AACvE,YAAI,OAAO,aAAa,OAAW,QAAO,eAAe,QAAQ,OAAO;AAAA,MAC1E;AACA,YAAM,QAAQ;AAAA,IAChB;AACA,SAAK,QAAQ,IAAI,UAAU,KAAK;AAAA,EAClC;AAAA,EAEA,UAAU,UAAkB,QAAsB;AAChD,UAAM,SAAS,KAAK,QAAQ,IAAI,QAAQ,GAAG;AAE3C,QAAI,QAAQ,OAAO,OAAQ,QAAO,UAAU;AAAA,EAC9C;AAAA,EAEA,UAAU,UAAkB,QAAoC;AAC9D,UAAM,QAAQ,KAAK,QAAQ,IAAI,QAAQ;AACvC,QAAI,OAAO,QAAQ,OAAO,OAAQ,QAAO;AACzC,UAAM,SAAS,MAAM;AACrB,WAAO,MAAM;AACb,WAAO,OAAO,UAAU,SAAY,OAAO;AAAA,EAC7C;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
CREATE TABLE `execution_markers` (
|
|
2
|
+
`operation_id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`thread_id` text NOT NULL,
|
|
4
|
+
`turn_id` text,
|
|
5
|
+
`workspace_key` text NOT NULL,
|
|
6
|
+
`codex_epoch` text NOT NULL,
|
|
7
|
+
`state` text NOT NULL,
|
|
8
|
+
`created_at` integer NOT NULL,
|
|
9
|
+
`ended_at` integer,
|
|
10
|
+
`reconciled_at` integer,
|
|
11
|
+
`reconciliation_operation_id` text,
|
|
12
|
+
FOREIGN KEY (`operation_id`) REFERENCES `operations`(`client_operation_id`) ON UPDATE no action ON DELETE no action,
|
|
13
|
+
FOREIGN KEY (`reconciliation_operation_id`) REFERENCES `operations`(`client_operation_id`) ON UPDATE no action ON DELETE no action,
|
|
14
|
+
CONSTRAINT "execution_markers_state_check" CHECK("execution_markers"."state" in ('active', 'unknown', 'terminal', 'reconciled'))
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
CREATE UNIQUE INDEX `execution_markers_active_thread` ON `execution_markers` (`thread_id`) WHERE "execution_markers"."ended_at" is null;--> statement-breakpoint
|
|
18
|
+
CREATE UNIQUE INDEX `execution_markers_active_workspace` ON `execution_markers` (`workspace_key`) WHERE "execution_markers"."ended_at" is null;--> statement-breakpoint
|
|
19
|
+
CREATE TABLE `operations` (
|
|
20
|
+
`client_operation_id` text PRIMARY KEY NOT NULL,
|
|
21
|
+
`kind` text NOT NULL,
|
|
22
|
+
`target` text NOT NULL,
|
|
23
|
+
`request_digest` text NOT NULL,
|
|
24
|
+
`state` text NOT NULL,
|
|
25
|
+
`result` text,
|
|
26
|
+
`error` text,
|
|
27
|
+
`created_at` integer NOT NULL,
|
|
28
|
+
`updated_at` integer NOT NULL,
|
|
29
|
+
CONSTRAINT "operations_state_check" CHECK("operations"."state" in ('accepted', 'dispatching', 'acknowledged', 'failed', 'unknown'))
|
|
30
|
+
);
|
|
31
|
+
--> statement-breakpoint
|
|
32
|
+
CREATE INDEX `operations_state_idx` ON `operations` (`state`);--> statement-breakpoint
|
|
33
|
+
CREATE TABLE `preferences` (
|
|
34
|
+
`key` text PRIMARY KEY NOT NULL,
|
|
35
|
+
`value` text NOT NULL
|
|
36
|
+
);
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
CREATE TABLE `thread_links` (
|
|
39
|
+
`thread_id` text PRIMARY KEY NOT NULL,
|
|
40
|
+
`project_id` text NOT NULL,
|
|
41
|
+
`cwd` text NOT NULL,
|
|
42
|
+
`source` text NOT NULL,
|
|
43
|
+
`managed_epoch` text,
|
|
44
|
+
`updated_at` integer NOT NULL
|
|
45
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
DROP INDEX `execution_markers_active_workspace`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
CREATE TABLE `project_registrations` (
|
|
2
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
3
|
+
`name` text NOT NULL,
|
|
4
|
+
`path` text NOT NULL,
|
|
5
|
+
`canonical_root` text,
|
|
6
|
+
`removed_at` integer,
|
|
7
|
+
`created_at` integer NOT NULL,
|
|
8
|
+
`updated_at` integer NOT NULL
|
|
9
|
+
);
|
|
10
|
+
--> statement-breakpoint
|
|
11
|
+
ALTER TABLE `operations` ADD `project_id` text;
|