@smartmemory/stratum 0.3.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/dist/cli/guard.js +91 -0
- package/dist/cli/guard.js.map +1 -0
- package/dist/cli/mcp_install.js +302 -0
- package/dist/cli/mcp_install.js.map +1 -0
- package/dist/cli/query_gate.js +316 -0
- package/dist/cli/query_gate.js.map +1 -0
- package/dist/cli/stratum.js +291 -0
- package/dist/cli/stratum.js.map +1 -0
- package/dist/connectors/background.js +531 -0
- package/dist/connectors/background.js.map +1 -0
- package/dist/connectors/base.js +12 -0
- package/dist/connectors/base.js.map +1 -0
- package/dist/connectors/claude-bg-worker.js +99 -0
- package/dist/connectors/claude-bg-worker.js.map +1 -0
- package/dist/connectors/claude.js +170 -0
- package/dist/connectors/claude.js.map +1 -0
- package/dist/connectors/codex.js +319 -0
- package/dist/connectors/codex.js.map +1 -0
- package/dist/connectors/index.js +7 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/proc_identity.js +90 -0
- package/dist/connectors/proc_identity.js.map +1 -0
- package/dist/connectors/runner.js +63 -0
- package/dist/connectors/runner.js.map +1 -0
- package/dist/contracts/events.json +65 -0
- package/dist/contracts/mcp-surface.json +215 -0
- package/dist/engine/checkpoint.js +50 -0
- package/dist/engine/checkpoint.js.map +1 -0
- package/dist/engine/engine.js +2356 -0
- package/dist/engine/engine.js.map +1 -0
- package/dist/engine/ledger.js +36 -0
- package/dist/engine/ledger.js.map +1 -0
- package/dist/engine/state.js +42 -0
- package/dist/engine/state.js.map +1 -0
- package/dist/eval/expr.js +679 -0
- package/dist/eval/expr.js.map +1 -0
- package/dist/eval/files.js +130 -0
- package/dist/eval/files.js.map +1 -0
- package/dist/guard/canonical.js +116 -0
- package/dist/guard/canonical.js.map +1 -0
- package/dist/guard/errors.js +80 -0
- package/dist/guard/errors.js.map +1 -0
- package/dist/guard/evidence.js +475 -0
- package/dist/guard/evidence.js.map +1 -0
- package/dist/guard/fingerprint.js +13 -0
- package/dist/guard/fingerprint.js.map +1 -0
- package/dist/guard/lock.js +360 -0
- package/dist/guard/lock.js.map +1 -0
- package/dist/guard/store.js +396 -0
- package/dist/guard/store.js.map +1 -0
- package/dist/guard/transition.js +477 -0
- package/dist/guard/transition.js.map +1 -0
- package/dist/ir/refs.js +69 -0
- package/dist/ir/refs.js.map +1 -0
- package/dist/ir/schema.js +123 -0
- package/dist/ir/schema.js.map +1 -0
- package/dist/ir/validate.js +595 -0
- package/dist/ir/validate.js.map +1 -0
- package/dist/judge/codex_judged.js +85 -0
- package/dist/judge/codex_judged.js.map +1 -0
- package/dist/judge/fixture_judged.js +62 -0
- package/dist/judge/fixture_judged.js.map +1 -0
- package/dist/judge/judged.js +89 -0
- package/dist/judge/judged.js.map +1 -0
- package/dist/judge/pricing.js +22 -0
- package/dist/judge/pricing.js.map +1 -0
- package/dist/mcp/contracts.js +162 -0
- package/dist/mcp/contracts.js.map +1 -0
- package/dist/mcp/main.js +7 -0
- package/dist/mcp/main.js.map +1 -0
- package/dist/mcp/server.js +370 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/migrate/check.js +164 -0
- package/dist/migrate/check.js.map +1 -0
- package/dist/parallel/certificate.js +37 -0
- package/dist/parallel/certificate.js.map +1 -0
- package/dist/parallel/evaluate.js +73 -0
- package/dist/parallel/evaluate.js.map +1 -0
- package/dist/speckit/compiler.js +162 -0
- package/dist/speckit/compiler.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { createReadStream } from "node:fs";
|
|
4
|
+
import { appendFile, mkdir, open, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { Worker } from "node:worker_threads";
|
|
9
|
+
import { finiteNonnegative, modelIdentity } from "./base.js";
|
|
10
|
+
import { codexCommand, defaultCodexModel } from "./codex.js";
|
|
11
|
+
import { procStartTime, processGroupId, processIdentityMatches } from "./proc_identity.js";
|
|
12
|
+
const claudeWorkerRegistry = new Map();
|
|
13
|
+
// Single serialization point for all terminal writes on a claude bg run.
|
|
14
|
+
// Only the first caller's doFinalize() executes; subsequent callers get the
|
|
15
|
+
// same promise. Registry deletion always happens via .finally().
|
|
16
|
+
function claimFinalization(entry, runId, doFinalize) {
|
|
17
|
+
if (entry.finalizationClaim !== null) {
|
|
18
|
+
return entry.finalizationClaim; // already claimed — another path owns the terminal record
|
|
19
|
+
}
|
|
20
|
+
entry.finalizationClaim = doFinalize()
|
|
21
|
+
.catch(() => { })
|
|
22
|
+
.finally(() => claudeWorkerRegistry.delete(runId));
|
|
23
|
+
return entry.finalizationClaim;
|
|
24
|
+
}
|
|
25
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
+
export const T2F5_DONE_SENTINEL = "__t2f5_done__";
|
|
27
|
+
export const T2F5_SHELL_WRAPPER = '"$@" > "$T2F5_OUT" 2> "$T2F5_ERR" < "$T2F5_IN"; rc=$?; ' +
|
|
28
|
+
'printf \'{"__t2f5_done__":%d}\\n\' "$rc" >> "$T2F5_OUT"; ' +
|
|
29
|
+
'exit "$rc"';
|
|
30
|
+
const RUN_ID = /^[0-9a-f]{12}$/;
|
|
31
|
+
const TEXT_CAP = 20_000;
|
|
32
|
+
// Bounds a single unterminated JSONL line so a runaway writer cannot grow the
|
|
33
|
+
// poller's memory without limit; oversized lines are dropped like malformed ones.
|
|
34
|
+
const MAX_LINE_BYTES = 5_000_000;
|
|
35
|
+
export function agentRunsRoot() {
|
|
36
|
+
return join(homedir(), ".stratum", "ts", "agent_runs");
|
|
37
|
+
}
|
|
38
|
+
export async function startBackgroundRun(options) {
|
|
39
|
+
// D11: explicit runtime validation — TypeScript casts at the MCP boundary do not
|
|
40
|
+
// protect callers that bypass the MCP surface.
|
|
41
|
+
const VALID_AGENTS = new Set(["claude", "codex"]);
|
|
42
|
+
const VALID_SANDBOX_MODES = new Set(["read-only", "workspace-write"]);
|
|
43
|
+
if (!VALID_AGENTS.has(options.agent)) {
|
|
44
|
+
throw new Error(`Unknown agent ${JSON.stringify(options.agent)}; must be "claude" or "codex"`);
|
|
45
|
+
}
|
|
46
|
+
if (options.sandboxMode !== undefined && !VALID_SANDBOX_MODES.has(options.sandboxMode)) {
|
|
47
|
+
throw new Error(`Unknown sandboxMode ${JSON.stringify(options.sandboxMode)}; must be "read-only" or "workspace-write"`);
|
|
48
|
+
}
|
|
49
|
+
if (options.budgeted)
|
|
50
|
+
throw new Error("background agent runs cannot debit run budgets yet");
|
|
51
|
+
if (options.agent === "claude") {
|
|
52
|
+
return startClaudeBackgroundRun(options);
|
|
53
|
+
}
|
|
54
|
+
// Codex path (D6: workspace-write is now allowed — guard removed)
|
|
55
|
+
const sandboxMode = options.sandboxMode ?? "read-only";
|
|
56
|
+
const registryRoot = options.registryRoot ?? agentRunsRoot();
|
|
57
|
+
const { runId, runDir } = await newRunDir(registryRoot);
|
|
58
|
+
const streamPath = join(runDir, "stream.jsonl");
|
|
59
|
+
const stderrPath = `${streamPath}.err`;
|
|
60
|
+
const inputPath = `${streamPath}.in`;
|
|
61
|
+
// Prompts and agent output are private to the invoking user (0600/0700).
|
|
62
|
+
await Promise.all([
|
|
63
|
+
writeFile(streamPath, "", { encoding: "utf8", mode: 0o600 }),
|
|
64
|
+
writeFile(stderrPath, "", { encoding: "utf8", mode: 0o600 }),
|
|
65
|
+
writeFile(inputPath, options.prompt, { encoding: "utf8", mode: 0o600 }),
|
|
66
|
+
]);
|
|
67
|
+
const model = options.model ?? defaultCodexModel();
|
|
68
|
+
const command = options.command ?? codexCommand(model, options.cwd, sandboxMode);
|
|
69
|
+
const env = {
|
|
70
|
+
...(options.env ?? process.env),
|
|
71
|
+
T2F5_OUT: streamPath,
|
|
72
|
+
T2F5_ERR: stderrPath,
|
|
73
|
+
T2F5_IN: inputPath,
|
|
74
|
+
};
|
|
75
|
+
delete env.ANTHROPIC_API_KEY;
|
|
76
|
+
delete env.CLAUDE_API_KEY;
|
|
77
|
+
delete env.CLAUDECODE;
|
|
78
|
+
// Stamped before spawn: durationMs is measured from here to the sentinel
|
|
79
|
+
// write, so identity-lookup latency never deflates it.
|
|
80
|
+
const createdAt = new Date().toISOString();
|
|
81
|
+
const child = spawn("sh", ["-c", T2F5_SHELL_WRAPPER, "sh", ...command], {
|
|
82
|
+
cwd: options.cwd,
|
|
83
|
+
env,
|
|
84
|
+
detached: true,
|
|
85
|
+
stdio: "ignore",
|
|
86
|
+
});
|
|
87
|
+
await new Promise((resolve, reject) => {
|
|
88
|
+
child.once("spawn", resolve);
|
|
89
|
+
child.once("error", reject);
|
|
90
|
+
});
|
|
91
|
+
const pid = child.pid;
|
|
92
|
+
if (pid === undefined)
|
|
93
|
+
throw new Error("durable wrapper did not expose a pid");
|
|
94
|
+
const startTime = await procStartTime(pid);
|
|
95
|
+
const meta = {
|
|
96
|
+
runId,
|
|
97
|
+
agent: "codex",
|
|
98
|
+
model,
|
|
99
|
+
cwd: options.cwd,
|
|
100
|
+
sandboxMode,
|
|
101
|
+
promptChars: options.prompt.length,
|
|
102
|
+
createdAt,
|
|
103
|
+
childPid: pid,
|
|
104
|
+
...(startTime ? { procStartTime: startTime } : {}),
|
|
105
|
+
streamPath,
|
|
106
|
+
stderrPath,
|
|
107
|
+
};
|
|
108
|
+
try {
|
|
109
|
+
await atomicWriteJson(join(runDir, "meta.json"), meta);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
// No metadata means the caller cannot discover or cancel this detached run.
|
|
113
|
+
// Kill the whole process group and wait for the wrapper to exit before rejecting.
|
|
114
|
+
await killDetachedProcessGroup(child, pid);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
child.unref();
|
|
118
|
+
return { status: "bg_started", runId, pid, streamPath };
|
|
119
|
+
}
|
|
120
|
+
async function startClaudeBackgroundRun(options) {
|
|
121
|
+
// D8: reject read-only for claude bg — claude.ts:43 hardcodes permissionMode:"acceptEdits"
|
|
122
|
+
// with no SDK enforcement path for sandboxMode:"read-only". Explicit rejection prevents
|
|
123
|
+
// a false read-only guarantee. Callers should omit sandboxMode or pass "workspace-write".
|
|
124
|
+
if (options.sandboxMode === "read-only") {
|
|
125
|
+
throw new Error("claude background runs with sandboxMode='read-only' are not supported in v1. " +
|
|
126
|
+
"Claude's permissionMode cannot be safely enforced via the SDK without a mapped " +
|
|
127
|
+
"tool restriction list. Omit sandboxMode or pass 'workspace-write' explicitly.");
|
|
128
|
+
}
|
|
129
|
+
const registryRoot = options.registryRoot ?? agentRunsRoot();
|
|
130
|
+
const { runId, runDir } = await newRunDir(registryRoot);
|
|
131
|
+
const streamPath = join(runDir, "stream.jsonl");
|
|
132
|
+
const stderrPath = `${streamPath}.err`;
|
|
133
|
+
const inputPath = `${streamPath}.in`;
|
|
134
|
+
await Promise.all([
|
|
135
|
+
writeFile(streamPath, "", { encoding: "utf8", mode: 0o600 }),
|
|
136
|
+
writeFile(stderrPath, "", { encoding: "utf8", mode: 0o600 }),
|
|
137
|
+
writeFile(inputPath, options.prompt, { encoding: "utf8", mode: 0o600 }),
|
|
138
|
+
]);
|
|
139
|
+
const model = options.model ?? process.env.CLAUDE_MODEL ?? "claude-sonnet-4-6";
|
|
140
|
+
// D4: default sandboxMode for claude bg = workspace-write (the primary use case)
|
|
141
|
+
const sandboxMode = options.sandboxMode ?? "workspace-write";
|
|
142
|
+
const workerInput = {
|
|
143
|
+
prompt: options.prompt,
|
|
144
|
+
connectorOptions: {
|
|
145
|
+
model,
|
|
146
|
+
cwd: options.cwd,
|
|
147
|
+
...(options.allowedTools !== undefined ? { allowedTools: options.allowedTools } : {}),
|
|
148
|
+
...(options.disallowedTools !== undefined ? { disallowedTools: options.disallowedTools } : {}),
|
|
149
|
+
...(options.env !== undefined ? { env: options.env } : {}),
|
|
150
|
+
},
|
|
151
|
+
streamPath,
|
|
152
|
+
stderrPath,
|
|
153
|
+
};
|
|
154
|
+
// Worker TypeScript loading: point to the .ts source file.
|
|
155
|
+
// The hooks file (--import) registers synchronous resolve/load hooks that:
|
|
156
|
+
// - remap "./foo.js" imports → "./foo.ts" for sibling source files
|
|
157
|
+
// - read .ts files via readFileSync + stripTypeScriptTypes (bypasses default loader)
|
|
158
|
+
// This enables the Worker to load TypeScript without a build step (test and production).
|
|
159
|
+
const hooksPath = fileURLToPath(new URL("./claude-bg-worker-hooks.mjs", import.meta.url));
|
|
160
|
+
const worker = new Worker(new URL("./claude-bg-worker.ts", import.meta.url), {
|
|
161
|
+
workerData: workerInput,
|
|
162
|
+
execArgv: ["--import", hooksPath],
|
|
163
|
+
});
|
|
164
|
+
const entry = { worker, cancelling: false, finalizationClaim: null };
|
|
165
|
+
claudeWorkerRegistry.set(runId, entry);
|
|
166
|
+
// D9 + D13: exit handler — guarded by cancelling flag AND claimFinalization lock.
|
|
167
|
+
// 'error' fires before 'exit' on worker exceptions, so the error handler atomically
|
|
168
|
+
// claims the finalizationClaim first; the exit handler then sees it non-null and
|
|
169
|
+
// discards its own doFinalize. This prevents duplicate sentinel writes.
|
|
170
|
+
worker.once("exit", () => {
|
|
171
|
+
if (entry.cancelling)
|
|
172
|
+
return; // cancel path owns finalization
|
|
173
|
+
void claimFinalization(entry, runId, () => writeSentinelIfAbsent(streamPath, 1));
|
|
174
|
+
});
|
|
175
|
+
// D9 + D13: error handler — absorbs uncaught worker exceptions. Without this listener
|
|
176
|
+
// Node.js emits an unhandledRejection and crashes the MCP process. Fires before 'exit'
|
|
177
|
+
// on worker exceptions so the null-check + set in claimFinalization is atomic — the
|
|
178
|
+
// exit handler that follows will see finalizationClaim !== null and discard its work.
|
|
179
|
+
worker.on("error", (err) => {
|
|
180
|
+
if (entry.cancelling)
|
|
181
|
+
return; // cancel path owns finalization
|
|
182
|
+
const errorLine = JSON.stringify({ type: "error", message: err.message.slice(0, 2000) }) + "\n";
|
|
183
|
+
const sentinelLine = JSON.stringify({ [T2F5_DONE_SENTINEL]: 1 }) + "\n";
|
|
184
|
+
// The WORKER writes its own rc=0 sentinel outside the parent's claim. A late
|
|
185
|
+
// stream/close error after a successful commit must not flip completion to rc=1
|
|
186
|
+
// (scanStream takes the LAST sentinel), so rescan inside the claim and defer to
|
|
187
|
+
// any terminal record the worker already committed (D13 exactly-once invariant).
|
|
188
|
+
void claimFinalization(entry, runId, async () => {
|
|
189
|
+
const scan = await scanStream(streamPath);
|
|
190
|
+
if (scan.exitCode !== undefined)
|
|
191
|
+
return; // worker's terminal record is authoritative
|
|
192
|
+
await appendFile(streamPath, errorLine + sentinelLine, { encoding: "utf8" });
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
const meta = {
|
|
196
|
+
runId,
|
|
197
|
+
agent: "claude",
|
|
198
|
+
model,
|
|
199
|
+
cwd: options.cwd,
|
|
200
|
+
sandboxMode,
|
|
201
|
+
promptChars: options.prompt.length,
|
|
202
|
+
createdAt: new Date().toISOString(),
|
|
203
|
+
streamPath,
|
|
204
|
+
stderrPath,
|
|
205
|
+
...(options.allowedTools !== undefined ? { allowedTools: options.allowedTools } : {}),
|
|
206
|
+
...(options.disallowedTools !== undefined ? { disallowedTools: options.disallowedTools } : {}),
|
|
207
|
+
};
|
|
208
|
+
try {
|
|
209
|
+
await atomicWriteJson(join(runDir, "meta.json"), meta);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
// Without meta.json the caller gets no runId handle — a still-running
|
|
213
|
+
// workspace-write worker would be uncontrollable. Kill it before rethrowing.
|
|
214
|
+
entry.cancelling = true; // suppress exit/error finalizers for this dead run
|
|
215
|
+
await worker.terminate().catch(() => { });
|
|
216
|
+
claudeWorkerRegistry.delete(runId);
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
return { status: "bg_started", runId, streamPath };
|
|
220
|
+
}
|
|
221
|
+
export async function pollBackgroundRun(runId, options = {}) {
|
|
222
|
+
const loaded = await loadMeta(runId, options.registryRoot ?? agentRunsRoot());
|
|
223
|
+
if (!loaded)
|
|
224
|
+
return { status: "not_found", runId };
|
|
225
|
+
const { streamPath, stderrPath } = loaded;
|
|
226
|
+
const scan = await scanStream(streamPath);
|
|
227
|
+
const text = capText(scan.text, streamPath);
|
|
228
|
+
if (loaded.meta.agent === "claude") {
|
|
229
|
+
// D10: liveness via in-memory registry (entry present = running; deleted = terminal).
|
|
230
|
+
// Registry deletion always happens AFTER sentinel write so poll never misses a sentinel.
|
|
231
|
+
if (scan.exitCode === undefined) {
|
|
232
|
+
if (claudeWorkerRegistry.has(runId)) {
|
|
233
|
+
return { status: "running", runId, textTail: text, eventsSeen: scan.eventsSeen, streamPath };
|
|
234
|
+
}
|
|
235
|
+
// Not in registry and no sentinel: worker died unexpectedly (MCP server restarted or
|
|
236
|
+
// process was killed externally). Poll surfaces this as an error boundary.
|
|
237
|
+
return {
|
|
238
|
+
status: "error", runId, reason: "child_died_without_sentinel", textTail: text,
|
|
239
|
+
stderrTail: await tailText(stderrPath), eventsSeen: scan.eventsSeen, streamPath,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const telemetry = await terminalTelemetry(loaded.meta, streamPath);
|
|
243
|
+
if (scan.exitCode === 0 && scan.error === undefined) {
|
|
244
|
+
return { status: "complete", runId, text, usage: scan.usage, exitCode: 0, telemetry };
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
status: "error", runId, exitCode: scan.exitCode, textTail: text,
|
|
248
|
+
stderrTail: await tailText(stderrPath), ...(scan.error ? { reason: scan.error } : {}), telemetry,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
// Codex path — unchanged:
|
|
252
|
+
if (scan.exitCode === undefined) {
|
|
253
|
+
if (await processIdentityMatches(loaded.meta.childPid, loaded.meta.procStartTime)) {
|
|
254
|
+
return { status: "running", runId, textTail: text, eventsSeen: scan.eventsSeen, streamPath };
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
status: "error", runId, reason: "child_died_without_sentinel", textTail: text,
|
|
258
|
+
stderrTail: await tailText(stderrPath), eventsSeen: scan.eventsSeen, streamPath,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const telemetry = await terminalTelemetry(loaded.meta, streamPath);
|
|
262
|
+
if (scan.exitCode === 0 && scan.error === undefined) {
|
|
263
|
+
return { status: "complete", runId, text, usage: scan.usage, exitCode: 0, telemetry };
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
status: "error", runId, exitCode: scan.exitCode, textTail: text,
|
|
267
|
+
stderrTail: await tailText(stderrPath), ...(scan.error ? { reason: scan.error } : {}), telemetry,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
export async function cancelBackgroundRun(runId, options = {}) {
|
|
271
|
+
const loaded = await loadMeta(runId, options.registryRoot ?? agentRunsRoot());
|
|
272
|
+
if (!loaded)
|
|
273
|
+
return { status: "not_found", runId };
|
|
274
|
+
if (loaded.meta.agent === "claude") {
|
|
275
|
+
// Initial scan: if sentinel already present, run already terminal.
|
|
276
|
+
const scan = await scanStream(loaded.streamPath);
|
|
277
|
+
if (scan.exitCode !== undefined) {
|
|
278
|
+
return { status: scan.exitCode === 0 && !scan.error ? "already_complete" : "already_error", runId };
|
|
279
|
+
}
|
|
280
|
+
const entry = claudeWorkerRegistry.get(runId);
|
|
281
|
+
if (!entry)
|
|
282
|
+
return { status: "not_found", runId }; // server restart — no worker to kill
|
|
283
|
+
// D9: claim before terminate so the exit handler's sentinel write is suppressed.
|
|
284
|
+
entry.cancelling = true;
|
|
285
|
+
// Death-confirmed: worker.terminate() returns a Promise that resolves when the thread
|
|
286
|
+
// is truly dead — equivalent to SIGTERM + await for a process.
|
|
287
|
+
await entry.worker.terminate();
|
|
288
|
+
// D11: rescan after terminate. The worker can commit its own rc=0 sentinel BETWEEN
|
|
289
|
+
// the initial scan above and the terminate() call (race: scan→worker writes→cancel
|
|
290
|
+
// terminates). Setting cancelling=true suppresses the exit handler, but does not
|
|
291
|
+
// undo a sentinel the worker already appended. Rescanning after death-confirmed
|
|
292
|
+
// terminate is the authoritative check.
|
|
293
|
+
const rescan = await scanStream(loaded.streamPath);
|
|
294
|
+
if (rescan.exitCode !== undefined) {
|
|
295
|
+
// Worker won the race. D13: route through claimFinalization() with a no-op doFinalize
|
|
296
|
+
// so registry deletion happens via the shared lock, guarding a concurrent second cancel.
|
|
297
|
+
void claimFinalization(entry, runId, () => Promise.resolve());
|
|
298
|
+
return { status: rescan.exitCode === 0 && !rescan.error ? "already_complete" : "already_error", runId };
|
|
299
|
+
}
|
|
300
|
+
// D14: before claiming rc=130 finalization, check whether an error/exit handler already
|
|
301
|
+
// claimed it before cancelling=true was set. Interleaving: worker throws → 'error' handler
|
|
302
|
+
// fires with cancelling=false → claims finalizationClaim (appendFile in-flight) → cancel
|
|
303
|
+
// starts → initial scan sees no sentinel (appendFile pending) → sets cancelling=true →
|
|
304
|
+
// terminate (worker dead) → rescan (still no sentinel) → reaches here.
|
|
305
|
+
// finalizationClaim is now non-null (error handler set it). Calling claimFinalization(rc=130)
|
|
306
|
+
// would return the error handler's promise with OUR doFinalize discarded — we'd return
|
|
307
|
+
// 'cancelled' while the committed sentinel is rc=1. Fix: if joined, await, rescan, return
|
|
308
|
+
// the actual outcome. Return 'cancelled' ONLY when we own the rc=130 record.
|
|
309
|
+
if (entry.finalizationClaim !== null) {
|
|
310
|
+
// Joined a pre-existing claim — await its I/O, then report the actual terminal outcome.
|
|
311
|
+
await entry.finalizationClaim;
|
|
312
|
+
const finalScan = await scanStream(loaded.streamPath);
|
|
313
|
+
if (finalScan.exitCode === 0 && !finalScan.error) {
|
|
314
|
+
return { status: "already_complete", runId };
|
|
315
|
+
}
|
|
316
|
+
return { status: "already_error", runId };
|
|
317
|
+
}
|
|
318
|
+
// We own the terminal record. D13: claimFinalization() prevents a concurrent second cancel
|
|
319
|
+
// from writing a second rc=130 sentinel (null-check + set is atomic at JS event-loop level).
|
|
320
|
+
// D10: sentinel written inside doFinalize before .finally() deletes the registry entry.
|
|
321
|
+
await claimFinalization(entry, runId, () => writeSentinelIfAbsent(loaded.streamPath, 130));
|
|
322
|
+
return { status: "cancelled", runId };
|
|
323
|
+
}
|
|
324
|
+
// Codex path — unchanged:
|
|
325
|
+
const scan = await scanStream(loaded.streamPath);
|
|
326
|
+
if (scan.exitCode !== undefined)
|
|
327
|
+
return { status: scan.exitCode === 0 && !scan.error ? "already_complete" : "already_error", runId };
|
|
328
|
+
const { childPid: pid, procStartTime: expected } = loaded.meta;
|
|
329
|
+
if (!await processIdentityMatches(pid, expected))
|
|
330
|
+
return { status: "already_error", runId };
|
|
331
|
+
if (await processGroupId(pid) !== pid)
|
|
332
|
+
return { status: "already_error", runId };
|
|
333
|
+
// Verify the start-time identity a second time immediately before the only signal.
|
|
334
|
+
if (!await processIdentityMatches(pid, expected))
|
|
335
|
+
return { status: "already_error", runId };
|
|
336
|
+
try {
|
|
337
|
+
process.kill(-pid, "SIGTERM");
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
return { status: "already_error", runId };
|
|
341
|
+
}
|
|
342
|
+
return { status: "cancelled", runId };
|
|
343
|
+
}
|
|
344
|
+
async function newRunDir(root) {
|
|
345
|
+
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
346
|
+
while (true) {
|
|
347
|
+
const runId = randomBytes(6).toString("hex");
|
|
348
|
+
const runDir = join(root, runId);
|
|
349
|
+
try {
|
|
350
|
+
await mkdir(runDir, { mode: 0o700 });
|
|
351
|
+
return { runId, runDir };
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
if (error.code !== "EEXIST")
|
|
355
|
+
throw error;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
async function atomicWriteJson(path, value) {
|
|
360
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
361
|
+
const temporary = `${path}.${process.pid}.tmp`;
|
|
362
|
+
await writeFile(temporary, JSON.stringify(value, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
363
|
+
await rename(temporary, path);
|
|
364
|
+
}
|
|
365
|
+
async function killDetachedProcessGroup(child, pid) {
|
|
366
|
+
const exited = child.exitCode !== null || child.signalCode !== null
|
|
367
|
+
? Promise.resolve()
|
|
368
|
+
: new Promise((resolve) => child.once("exit", () => resolve()));
|
|
369
|
+
try {
|
|
370
|
+
process.kill(-pid, "SIGKILL");
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
try {
|
|
374
|
+
child.kill("SIGKILL");
|
|
375
|
+
}
|
|
376
|
+
catch { /* already dead */ }
|
|
377
|
+
}
|
|
378
|
+
await exited;
|
|
379
|
+
}
|
|
380
|
+
async function loadMeta(runId, root) {
|
|
381
|
+
if (!RUN_ID.test(runId))
|
|
382
|
+
return undefined;
|
|
383
|
+
try {
|
|
384
|
+
const runDir = join(root, runId);
|
|
385
|
+
const raw = JSON.parse(await readFile(join(runDir, "meta.json"), "utf8"));
|
|
386
|
+
if (!isRecord(raw) || raw.runId !== runId || (raw.agent !== "codex" && raw.agent !== "claude"))
|
|
387
|
+
return undefined;
|
|
388
|
+
if (raw.agent === "codex" && typeof raw.childPid !== "number")
|
|
389
|
+
return undefined;
|
|
390
|
+
if (typeof raw.model !== "string")
|
|
391
|
+
return undefined;
|
|
392
|
+
// Read paths are derived from the validated run directory, never from the
|
|
393
|
+
// serialized record — a substituted meta.json cannot redirect poll reads.
|
|
394
|
+
const streamPath = join(runDir, "stream.jsonl");
|
|
395
|
+
return { meta: raw, streamPath, stderrPath: `${streamPath}.err` };
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
return undefined;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
async function scanStream(path) {
|
|
402
|
+
let text = "";
|
|
403
|
+
let inputTokens = 0;
|
|
404
|
+
let outputTokens = 0;
|
|
405
|
+
let exitCode;
|
|
406
|
+
let error;
|
|
407
|
+
let eventsSeen = 0;
|
|
408
|
+
for await (const record of completeJsonLines(path)) {
|
|
409
|
+
eventsSeen += 1;
|
|
410
|
+
if (Object.hasOwn(record, T2F5_DONE_SENTINEL)) {
|
|
411
|
+
const value = Number(record[T2F5_DONE_SENTINEL]);
|
|
412
|
+
exitCode = Number.isFinite(value) ? Math.trunc(value) : 1;
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
if (record.type === "error" && error === undefined)
|
|
416
|
+
error = typeof record.message === "string" ? record.message : "codex error";
|
|
417
|
+
if (record.type === "item.completed" && isRecord(record.item) && record.item.type === "agent_message" && typeof record.item.text === "string") {
|
|
418
|
+
text = (text + record.item.text).slice(-2 * TEXT_CAP);
|
|
419
|
+
}
|
|
420
|
+
if (record.type === "turn.completed" && isRecord(record.usage)) {
|
|
421
|
+
inputTokens += finiteNonnegative(record.usage.input_tokens);
|
|
422
|
+
outputTokens += finiteNonnegative(record.usage.output_tokens);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return { text, usage: { tokens: inputTokens + outputTokens }, ...(exitCode !== undefined ? { exitCode } : {}), ...(error ? { error } : {}), eventsSeen };
|
|
426
|
+
}
|
|
427
|
+
// Writes a sentinel to the stream only if none is present yet.
|
|
428
|
+
// Used by exit/error handlers. Cancel path calls this via claimFinalization().
|
|
429
|
+
async function writeSentinelIfAbsent(streamPath, exitCode) {
|
|
430
|
+
const scan = await scanStream(streamPath);
|
|
431
|
+
if (scan.exitCode !== undefined)
|
|
432
|
+
return; // already has a sentinel
|
|
433
|
+
const line = JSON.stringify({ [T2F5_DONE_SENTINEL]: exitCode }) + "\n";
|
|
434
|
+
await appendFile(streamPath, line, { encoding: "utf8" });
|
|
435
|
+
}
|
|
436
|
+
async function* completeJsonLines(path) {
|
|
437
|
+
let stream;
|
|
438
|
+
try {
|
|
439
|
+
stream = createReadStream(path);
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
let buffer = Buffer.alloc(0);
|
|
445
|
+
let discardingOversizedLine = false;
|
|
446
|
+
try {
|
|
447
|
+
for await (const chunk of stream) {
|
|
448
|
+
buffer = Buffer.concat([buffer, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)]);
|
|
449
|
+
let newline = buffer.indexOf(10);
|
|
450
|
+
while (newline >= 0) {
|
|
451
|
+
const line = discardingOversizedLine ? "" : buffer.subarray(0, newline).toString("utf8").trim();
|
|
452
|
+
discardingOversizedLine = false;
|
|
453
|
+
buffer = buffer.subarray(newline + 1);
|
|
454
|
+
if (line) {
|
|
455
|
+
try {
|
|
456
|
+
const value = JSON.parse(line);
|
|
457
|
+
if (isRecord(value))
|
|
458
|
+
yield value;
|
|
459
|
+
}
|
|
460
|
+
catch { /* malformed complete lines are ignored like the Python reader */ }
|
|
461
|
+
}
|
|
462
|
+
newline = buffer.indexOf(10);
|
|
463
|
+
}
|
|
464
|
+
if (buffer.length > MAX_LINE_BYTES) {
|
|
465
|
+
// Drop the oversized pending line (treated as malformed) so a writer
|
|
466
|
+
// that never emits a newline cannot grow this buffer unboundedly.
|
|
467
|
+
discardingOversizedLine = true;
|
|
468
|
+
buffer = Buffer.alloc(0);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
catch (readError) {
|
|
473
|
+
if (readError.code !== "ENOENT")
|
|
474
|
+
throw readError;
|
|
475
|
+
}
|
|
476
|
+
// A trailing partial line belongs to a live writer and is intentionally ignored.
|
|
477
|
+
}
|
|
478
|
+
function capText(text, streamPath, cap = TEXT_CAP) {
|
|
479
|
+
if (text.length <= cap)
|
|
480
|
+
return text;
|
|
481
|
+
const prefix = `[truncated, full stream at ${streamPath}]\n`;
|
|
482
|
+
const keep = Math.max(0, cap - prefix.length);
|
|
483
|
+
return keep === 0 ? prefix.slice(0, cap) : prefix + text.slice(-keep);
|
|
484
|
+
}
|
|
485
|
+
async function tailText(path) {
|
|
486
|
+
// Bounded read: only the final window of the file is ever brought into
|
|
487
|
+
// memory, so an arbitrarily large stderr file cannot exhaust the poller.
|
|
488
|
+
const window = 2 * TEXT_CAP;
|
|
489
|
+
let handle;
|
|
490
|
+
try {
|
|
491
|
+
handle = await open(path, "r");
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
return "";
|
|
495
|
+
}
|
|
496
|
+
try {
|
|
497
|
+
const size = (await handle.stat()).size;
|
|
498
|
+
const position = Math.max(0, size - window);
|
|
499
|
+
const length = size - position;
|
|
500
|
+
if (length === 0)
|
|
501
|
+
return "";
|
|
502
|
+
const buffer = Buffer.alloc(length);
|
|
503
|
+
await handle.read(buffer, 0, length, position);
|
|
504
|
+
return capText(buffer.toString("utf8").trim(), path);
|
|
505
|
+
}
|
|
506
|
+
catch {
|
|
507
|
+
return "";
|
|
508
|
+
}
|
|
509
|
+
finally {
|
|
510
|
+
await handle.close();
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
async function terminalTelemetry(meta, streamPath) {
|
|
514
|
+
// The sentinel line is the stream's last write, so its mtime marks the end
|
|
515
|
+
// of the run; createdAt marks the start. Both fall back to 0 if unreadable.
|
|
516
|
+
let durationMs = 0;
|
|
517
|
+
try {
|
|
518
|
+
const endedAt = (await stat(streamPath)).mtimeMs;
|
|
519
|
+
const startedAt = Date.parse(meta.createdAt);
|
|
520
|
+
if (Number.isFinite(startedAt))
|
|
521
|
+
durationMs = Math.max(0, Math.round(endedAt - startedAt));
|
|
522
|
+
}
|
|
523
|
+
catch { /* stream vanished between scan and stat — keep durationMs 0 */ }
|
|
524
|
+
return { durationMs, ...modelIdentity(meta.model) };
|
|
525
|
+
}
|
|
526
|
+
function isRecord(value) {
|
|
527
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
528
|
+
}
|
|
529
|
+
// Export registry for testing (internal use only)
|
|
530
|
+
export { claudeWorkerRegistry };
|
|
531
|
+
//# sourceMappingURL=background.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background.js","sourceRoot":"","sources":["../../src/connectors/background.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAe3F,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAE9D,yEAAyE;AACzE,4EAA4E;AAC5E,iEAAiE;AACjE,SAAS,iBAAiB,CACxB,KAAoB,EACpB,KAAa,EACb,UAA+B;IAE/B,IAAI,KAAK,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;QACrC,OAAO,KAAK,CAAC,iBAAiB,CAAC,CAAC,0DAA0D;IAC5F,CAAC;IACD,KAAK,CAAC,iBAAiB,GAAG,UAAU,EAAE;SACnC,KAAK,CAAC,GAAG,EAAE,GAAoE,CAAC,CAAC;SACjF,OAAO,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACrD,OAAO,KAAK,CAAC,iBAAiB,CAAC;AACjC,CAAC;AACD,gFAAgF;AAEhF,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAC7B,yDAAyD;IACzD,2DAA2D;IAC3D,YAAY,CAAC;AACf,MAAM,MAAM,GAAG,gBAAgB,CAAC;AAChC,MAAM,QAAQ,GAAG,MAAM,CAAC;AACxB,8EAA8E;AAC9E,kFAAkF;AAClF,MAAM,cAAc,GAAG,SAAS,CAAC;AAkDjC,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IAGzE,iFAAiF;IACjF,+CAA+C;IAC/C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,4CAA4C,CACvG,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAE5F,IAAI,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,kEAAkE;IAClE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,WAAW,CAAC;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,aAAa,EAAE,CAAC;IAC7D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,GAAG,UAAU,MAAM,CAAC;IACvC,MAAM,SAAS,GAAG,GAAG,UAAU,KAAK,CAAC;IACrC,yEAAyE;IACzE,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,SAAS,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAC5D,SAAS,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAC5D,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;KACxE,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,iBAAiB,EAAE,CAAC;IACnD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACjF,MAAM,GAAG,GAAsB;QAC7B,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;QAC/B,QAAQ,EAAE,UAAU;QACpB,QAAQ,EAAE,UAAU;QACpB,OAAO,EAAE,SAAS;KACnB,CAAC;IACF,OAAO,GAAG,CAAC,iBAAiB,CAAC;IAC7B,OAAO,GAAG,CAAC,cAAc,CAAC;IAC1B,OAAO,GAAG,CAAC,UAAU,CAAC;IACtB,yEAAyE;IACzE,uDAAuD;IACvD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,EAAE;QACtE,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG;QACH,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC/E,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAiB;QACzB,KAAK;QACL,KAAK,EAAE,OAAO;QACd,KAAK;QACL,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,WAAW;QACX,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;QAClC,SAAS;QACT,QAAQ,EAAE,GAAG;QACb,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,UAAU;QACV,UAAU;KACX,CAAC;IACF,IAAI,CAAC;QACH,MAAM,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4EAA4E;QAC5E,kFAAkF;QAClF,MAAM,wBAAwB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC3C,MAAM,KAAK,CAAC;IACd,CAAC;IACD,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AAC1D,CAAC;AAYD,KAAK,UAAU,wBAAwB,CAAC,OAAkC;IAGxE,2FAA2F;IAC3F,wFAAwF;IACxF,0FAA0F;IAC1F,IAAI,OAAO,CAAC,WAAW,KAAK,WAAW,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,+EAA+E;YAC/E,iFAAiF;YACjF,+EAA+E,CAChF,CAAC;IACJ,CAAC;IACD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,aAAa,EAAE,CAAC;IAC7D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,GAAG,UAAU,MAAM,CAAC;IACvC,MAAM,SAAS,GAAG,GAAG,UAAU,KAAK,CAAC;IACrC,MAAM,OAAO,CAAC,GAAG,CAAC;QAChB,SAAS,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAC5D,SAAS,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAC5D,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;KACxE,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,mBAAmB,CAAC;IAC/E,iFAAiF;IACjF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,iBAAiB,CAAC;IAC7D,MAAM,WAAW,GAAgB;QAC/B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,gBAAgB,EAAE;YAChB,KAAK;YACL,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrF,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9F,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3D;QACD,UAAU;QACV,UAAU;KACX,CAAC;IACF,2DAA2D;IAC3D,2EAA2E;IAC3E,qEAAqE;IACrE,uFAAuF;IACvF,yFAAyF;IACzF,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,8BAA8B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAC3E,UAAU,EAAE,WAAW;QACvB,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;KAClC,CAAC,CAAC;IACH,MAAM,KAAK,GAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;IACpF,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEvC,kFAAkF;IAClF,oFAAoF;IACpF,iFAAiF;IACjF,wEAAwE;IACxE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;QACvB,IAAI,KAAK,CAAC,UAAU;YAAE,OAAO,CAAC,gCAAgC;QAC9D,KAAK,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;IAEH,sFAAsF;IACtF,uFAAuF;IACvF,oFAAoF;IACpF,sFAAsF;IACtF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;QAChC,IAAI,KAAK,CAAC,UAAU;YAAE,OAAO,CAAC,gCAAgC;QAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QAChG,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QACxE,6EAA6E;QAC7E,gFAAgF;QAChF,gFAAgF;QAChF,iFAAiF;QACjF,KAAK,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;YAC1C,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,4CAA4C;YACrF,MAAM,UAAU,CAAC,UAAU,EAAE,SAAS,GAAG,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAkB;QAC1B,KAAK;QACL,KAAK,EAAE,QAAQ;QACf,KAAK;QACL,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,WAAW;QACX,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM;QAClC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU;QACV,UAAU;QACV,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/F,CAAC;IACF,IAAI,CAAC;QACH,MAAM,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,sEAAsE;QACtE,6EAA6E;QAC7E,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,mDAAmD;QAC5E,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAsB,CAAC,CAAC,CAAC;QAC7D,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAa,EAAE,UAA2B,EAAE;IAClF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,IAAI,aAAa,EAAE,CAAC,CAAC;IAC9E,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACnD,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAC1C,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAE5C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACnC,sFAAsF;QACtF,yFAAyF;QACzF,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;YAC/F,CAAC;YACD,qFAAqF;YACrF,2EAA2E;YAC3E,OAAO;gBACL,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,EAAE,QAAQ,EAAE,IAAI;gBAC7E,UAAU,EAAE,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU;aAChF,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACpD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC;QACxF,CAAC;QACD,OAAO;YACL,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI;YAC/D,UAAU,EAAE,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS;SACjG,CAAC;IACJ,CAAC;IAED,0BAA0B;IAC1B,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,MAAM,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAClF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;QAC/F,CAAC;QACD,OAAO;YACL,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,EAAE,QAAQ,EAAE,IAAI;YAC7E,UAAU,EAAE,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU;SAChF,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACnE,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACpD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC;IACxF,CAAC;IACD,OAAO;QACL,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI;QAC/D,UAAU,EAAE,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS;KACjG,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAAa,EAAE,UAA2B,EAAE;IACpF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,IAAI,aAAa,EAAE,CAAC,CAAC;IAC9E,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAEnD,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACnC,mEAAmE;QACnE,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC;QACtG,CAAC;QACD,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,qCAAqC;QAExF,iFAAiF;QACjF,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,sFAAsF;QACtF,+DAA+D;QAC/D,MAAM,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAE/B,mFAAmF;QACnF,mFAAmF;QACnF,iFAAiF;QACjF,gFAAgF;QAChF,wCAAwC;QACxC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAClC,sFAAsF;YACtF,yFAAyF;YACzF,KAAK,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC;QAC1G,CAAC;QAED,wFAAwF;QACxF,2FAA2F;QAC3F,yFAAyF;QACzF,uFAAuF;QACvF,uEAAuE;QACvE,8FAA8F;QAC9F,uFAAuF;QACvF,0FAA0F;QAC1F,6EAA6E;QAC7E,IAAI,KAAK,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACrC,wFAAwF;YACxF,MAAM,KAAK,CAAC,iBAAiB,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACtD,IAAI,SAAS,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;gBACjD,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC;YAC/C,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QAC5C,CAAC;QACD,2FAA2F;QAC3F,6FAA6F;QAC7F,wFAAwF;QACxF,MAAM,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3F,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED,0BAA0B;IAC1B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACjD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC;IACrI,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAC/D,IAAI,CAAC,MAAM,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IAC5F,IAAI,MAAM,cAAc,CAAC,GAAG,CAAC,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACjF,mFAAmF;IACnF,IAAI,CAAC,MAAM,sBAAsB,CAAC,GAAG,EAAE,QAAQ,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IAC5F,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IAAC,CAAC;IAC3F,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAY;IACnC,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC;YAAC,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACrF,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,KAAK,CAAC;QACtE,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,KAAc;IACzD,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IAC/C,MAAM,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9F,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,KAAmB,EAAE,GAAW;IACtE,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;QACjE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE;QACnB,CAAC,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACxE,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,MAAM,CAAC;AACf,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,KAAa,EAAE,IAAY;IACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjC,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACnF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,OAAO,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC;YAAE,OAAO,SAAS,CAAC;QACjH,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAChF,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACpD,0EAA0E;QAC1E,0EAA0E;QAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAChD,OAAO,EAAE,IAAI,EAAE,GAAmC,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,UAAU,MAAM,EAAE,CAAC;IACpG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IAGpC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,QAA4B,CAAC;IACjC,IAAI,KAAyB,CAAC;IAC9B,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,UAAU,IAAI,CAAC,CAAC;QAChB,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;YACjD,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,SAAS;QACX,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;QAChI,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9I,IAAI,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/D,WAAW,IAAI,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC5D,YAAY,IAAI,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,YAAY,EAAE,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC;AAC3J,CAAC;AAED,+DAA+D;AAC/D,+EAA+E;AAC/E,KAAK,UAAU,qBAAqB,CAAC,UAAkB,EAAE,QAAgB;IACvE,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,CAAC,yBAAyB;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC;IACvE,MAAM,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,iBAAiB,CAAC,IAAY;IAC5C,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QAAC,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO;IAAC,CAAC;IAC1D,IAAI,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,uBAAuB,GAAG,KAAK,CAAC;IACpC,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACtF,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACjC,OAAO,OAAO,IAAI,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,GAAG,uBAAuB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;gBAChG,uBAAuB,GAAG,KAAK,CAAC;gBAChC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;gBACtC,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,CAAC;wBACH,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACxC,IAAI,QAAQ,CAAC,KAAK,CAAC;4BAAE,MAAM,KAAK,CAAC;oBACnC,CAAC;oBAAC,MAAM,CAAC,CAAC,iEAAiE,CAAC,CAAC;gBAC/E,CAAC;gBACD,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,MAAM,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;gBACnC,qEAAqE;gBACrE,kEAAkE;gBAClE,uBAAuB,GAAG,IAAI,CAAC;gBAC/B,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACnB,IAAK,SAAmC,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,SAAS,CAAC;IAC9E,CAAC;IACD,iFAAiF;AACnF,CAAC;AAED,SAAS,OAAO,CAAC,IAAY,EAAE,UAAkB,EAAE,GAAG,GAAG,QAAQ;IAC/D,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,MAAM,GAAG,8BAA8B,UAAU,KAAK,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;AACxE,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAY;IAClC,uEAAuE;IACvE,yEAAyE;IACzE,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC;IAC5B,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;QAC/B,IAAI,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,IAAuB,EAAE,UAAkB;IAC1E,2EAA2E;IAC3E,4EAA4E;IAC5E,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC;IAC5F,CAAC;IAAC,MAAM,CAAC,CAAC,+DAA+D,CAAC,CAAC;IAC3E,OAAO,EAAE,UAAU,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,kDAAkD;AAClD,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function modelIdentity(modelId) {
|
|
2
|
+
const slash = modelId.indexOf("/");
|
|
3
|
+
if (slash < 0)
|
|
4
|
+
return { model: modelId };
|
|
5
|
+
const model = modelId.slice(0, slash);
|
|
6
|
+
const effort = modelId.slice(slash + 1);
|
|
7
|
+
return effort ? { model, effort } : { model };
|
|
8
|
+
}
|
|
9
|
+
export function finiteNonnegative(value) {
|
|
10
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/connectors/base.ts"],"names":[],"mappings":"AA+BA,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACvF,CAAC"}
|