@mcoda/codali 0.1.134 → 0.1.135-codali.4

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.
Files changed (230) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/ORCHESTRATION.md +387 -0
  3. package/README.md +103 -1
  4. package/config/alternate-local.example.json +49 -0
  5. package/config/docdex-runtime.json +21 -0
  6. package/config/orchestration.schema.json +548 -0
  7. package/config/raijin-suku.example.json +172 -0
  8. package/config/terminal-long-scenarios.v1.json +70 -0
  9. package/dist/agents/RoleResolution.d.ts.map +1 -1
  10. package/dist/agents/RoleResolution.js +4 -4
  11. package/dist/api/CodaliApi.d.ts +16 -0
  12. package/dist/api/CodaliApi.d.ts.map +1 -1
  13. package/dist/api/CodaliApi.js +39 -10
  14. package/dist/cli/AskCommand.d.ts +3 -0
  15. package/dist/cli/AskCommand.d.ts.map +1 -1
  16. package/dist/cli/AskCommand.js +76 -13
  17. package/dist/cli/RunCommand.d.ts +4 -0
  18. package/dist/cli/RunCommand.d.ts.map +1 -1
  19. package/dist/cli/RunCommand.js +110 -24
  20. package/dist/cli/TerminalCommand.d.ts +35 -0
  21. package/dist/cli/TerminalCommand.d.ts.map +1 -0
  22. package/dist/cli/TerminalCommand.js +616 -0
  23. package/dist/cli/TerminalCredentials.d.ts +3 -0
  24. package/dist/cli/TerminalCredentials.d.ts.map +1 -0
  25. package/dist/cli/TerminalCredentials.js +89 -0
  26. package/dist/cli/TerminalInput.d.ts +24 -0
  27. package/dist/cli/TerminalInput.d.ts.map +1 -0
  28. package/dist/cli/TerminalInput.js +98 -0
  29. package/dist/cli/TerminalText.d.ts +10 -0
  30. package/dist/cli/TerminalText.d.ts.map +1 -0
  31. package/dist/cli/TerminalText.js +53 -0
  32. package/dist/cli.d.ts.map +1 -1
  33. package/dist/cli.js +33 -4
  34. package/dist/cognitive/ConfiguredPipeline.d.ts +34 -0
  35. package/dist/cognitive/ConfiguredPipeline.d.ts.map +1 -0
  36. package/dist/cognitive/ConfiguredPipeline.js +50 -0
  37. package/dist/cognitive/ValidationRunner.d.ts +4 -0
  38. package/dist/cognitive/ValidationRunner.d.ts.map +1 -1
  39. package/dist/cognitive/ValidationRunner.js +18 -41
  40. package/dist/config/NodeOrchestration.d.ts +21 -0
  41. package/dist/config/NodeOrchestration.d.ts.map +1 -0
  42. package/dist/config/NodeOrchestration.js +54 -0
  43. package/dist/config/OrchestrationConfig.d.ts +100 -0
  44. package/dist/config/OrchestrationConfig.d.ts.map +1 -0
  45. package/dist/config/OrchestrationConfig.js +245 -0
  46. package/dist/connectors/mcp/McpClient.d.ts +3 -1
  47. package/dist/connectors/mcp/McpClient.d.ts.map +1 -1
  48. package/dist/connectors/mcp/McpClient.js +3 -2
  49. package/dist/connectors/mcp/McpServerRegistry.d.ts +2 -2
  50. package/dist/connectors/mcp/McpServerRegistry.d.ts.map +1 -1
  51. package/dist/connectors/mcp/McpServerRegistry.js +39 -16
  52. package/dist/connectors/mcp/McpToolAdapter.js +2 -2
  53. package/dist/connectors/media/ConfiguredMediaTools.d.ts +6 -0
  54. package/dist/connectors/media/ConfiguredMediaTools.d.ts.map +1 -0
  55. package/dist/connectors/media/ConfiguredMediaTools.js +41 -0
  56. package/dist/connectors/media/ImageGenerationTool.js +3 -3
  57. package/dist/connectors/media/MediaArtifactReceipt.d.ts +5 -0
  58. package/dist/connectors/media/MediaArtifactReceipt.d.ts.map +1 -0
  59. package/dist/connectors/media/MediaArtifactReceipt.js +65 -0
  60. package/dist/connectors/media/MediaJobStore.d.ts +68 -0
  61. package/dist/connectors/media/MediaJobStore.d.ts.map +1 -0
  62. package/dist/connectors/media/MediaJobStore.js +199 -0
  63. package/dist/connectors/media/MediaJobWorker.d.ts +2 -0
  64. package/dist/connectors/media/MediaJobWorker.d.ts.map +1 -0
  65. package/dist/connectors/media/MediaJobWorker.js +65 -0
  66. package/dist/connectors/media/RemoteMediaJob.d.ts +6 -0
  67. package/dist/connectors/media/RemoteMediaJob.d.ts.map +1 -0
  68. package/dist/connectors/media/RemoteMediaJob.js +80 -0
  69. package/dist/docdex/DocdexClient.d.ts +18 -1
  70. package/dist/docdex/DocdexClient.d.ts.map +1 -1
  71. package/dist/docdex/DocdexClient.js +135 -19
  72. package/dist/docdex/ManagedDocdex.d.ts +29 -0
  73. package/dist/docdex/ManagedDocdex.d.ts.map +1 -0
  74. package/dist/docdex/ManagedDocdex.js +215 -0
  75. package/dist/docdex/ManagedRuntime.d.ts +28 -0
  76. package/dist/docdex/ManagedRuntime.d.ts.map +1 -0
  77. package/dist/docdex/ManagedRuntime.js +212 -0
  78. package/dist/eval/EvaluationProcess.d.ts +13 -0
  79. package/dist/eval/EvaluationProcess.d.ts.map +1 -0
  80. package/dist/eval/EvaluationProcess.js +76 -0
  81. package/dist/eval/LongWorkflowJourney.d.ts +34 -0
  82. package/dist/eval/LongWorkflowJourney.d.ts.map +1 -0
  83. package/dist/eval/LongWorkflowJourney.js +243 -0
  84. package/dist/eval/PlanningCorpus.d.ts +45 -0
  85. package/dist/eval/PlanningCorpus.d.ts.map +1 -0
  86. package/dist/eval/PlanningCorpus.js +189 -0
  87. package/dist/eval/PlanningCorpusRunner.d.ts +13 -0
  88. package/dist/eval/PlanningCorpusRunner.d.ts.map +1 -0
  89. package/dist/eval/PlanningCorpusRunner.js +89 -0
  90. package/dist/eval/TerminalCorpusRunner.d.ts +36 -0
  91. package/dist/eval/TerminalCorpusRunner.d.ts.map +1 -0
  92. package/dist/eval/TerminalCorpusRunner.js +222 -0
  93. package/dist/eval/TerminalTaskCorpus.d.ts +26 -0
  94. package/dist/eval/TerminalTaskCorpus.d.ts.map +1 -0
  95. package/dist/eval/TerminalTaskCorpus.js +105 -0
  96. package/dist/eval/TerminalWorkflowCorpus.d.ts +11 -0
  97. package/dist/eval/TerminalWorkflowCorpus.d.ts.map +1 -0
  98. package/dist/eval/TerminalWorkflowCorpus.js +116 -0
  99. package/dist/eval/fixtures/TerminalRecoveryJourney.d.ts +4 -0
  100. package/dist/eval/fixtures/TerminalRecoveryJourney.d.ts.map +1 -0
  101. package/dist/eval/fixtures/TerminalRecoveryJourney.js +132 -0
  102. package/dist/gateway/CodaliGateway.d.ts +2 -0
  103. package/dist/gateway/CodaliGateway.d.ts.map +1 -1
  104. package/dist/gateway/CodaliGateway.js +11 -1
  105. package/dist/gateway/ConfiguredGateway.d.ts +23 -0
  106. package/dist/gateway/ConfiguredGateway.d.ts.map +1 -0
  107. package/dist/gateway/ConfiguredGateway.js +44 -0
  108. package/dist/gateway/GatewayTracer.d.ts +1 -1
  109. package/dist/gateway/GatewayTracer.d.ts.map +1 -1
  110. package/dist/gateway/GatewayTracer.js +2 -27
  111. package/dist/index.d.ts +23 -0
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +12 -0
  114. package/dist/permissions/PermissionGate.d.ts +44 -0
  115. package/dist/permissions/PermissionGate.d.ts.map +1 -0
  116. package/dist/permissions/PermissionGate.js +97 -0
  117. package/dist/providers/ConfiguredEmbeddings.d.ts +43 -0
  118. package/dist/providers/ConfiguredEmbeddings.d.ts.map +1 -0
  119. package/dist/providers/ConfiguredEmbeddings.js +87 -0
  120. package/dist/providers/ConfiguredModelScope.d.ts +69 -0
  121. package/dist/providers/ConfiguredModelScope.d.ts.map +1 -0
  122. package/dist/providers/ConfiguredModelScope.js +113 -0
  123. package/dist/providers/ConfiguredProvider.d.ts +79 -0
  124. package/dist/providers/ConfiguredProvider.d.ts.map +1 -0
  125. package/dist/providers/ConfiguredProvider.js +238 -0
  126. package/dist/providers/ModelServiceError.d.ts +10 -0
  127. package/dist/providers/ModelServiceError.d.ts.map +1 -0
  128. package/dist/providers/ModelServiceError.js +45 -0
  129. package/dist/providers/MswarmWorkerProvider.d.ts.map +1 -1
  130. package/dist/providers/MswarmWorkerProvider.js +4 -0
  131. package/dist/providers/OpenAiCompatibleProvider.d.ts.map +1 -1
  132. package/dist/providers/OpenAiCompatibleProvider.js +91 -50
  133. package/dist/providers/ProviderTypes.d.ts +12 -0
  134. package/dist/providers/ProviderTypes.d.ts.map +1 -1
  135. package/dist/runtime/CodaliJobRuntime.d.ts +6 -0
  136. package/dist/runtime/CodaliJobRuntime.d.ts.map +1 -1
  137. package/dist/runtime/CodaliJobRuntime.js +36 -1
  138. package/dist/runtime/CodaliRuntime.d.ts +28 -0
  139. package/dist/runtime/CodaliRuntime.d.ts.map +1 -1
  140. package/dist/runtime/CodaliRuntime.js +69 -1
  141. package/dist/runtime/CompletionReport.d.ts +5 -0
  142. package/dist/runtime/CompletionReport.d.ts.map +1 -0
  143. package/dist/runtime/CompletionReport.js +12 -0
  144. package/dist/runtime/ProgressTracker.d.ts +17 -0
  145. package/dist/runtime/ProgressTracker.d.ts.map +1 -0
  146. package/dist/runtime/ProgressTracker.js +27 -0
  147. package/dist/runtime/RequestedTestEvidence.d.ts +12 -0
  148. package/dist/runtime/RequestedTestEvidence.d.ts.map +1 -0
  149. package/dist/runtime/RequestedTestEvidence.js +16 -0
  150. package/dist/runtime/RequiredRetrieval.d.ts +13 -0
  151. package/dist/runtime/RequiredRetrieval.d.ts.map +1 -0
  152. package/dist/runtime/RequiredRetrieval.js +25 -0
  153. package/dist/runtime/ReviewSource.d.ts +6 -0
  154. package/dist/runtime/ReviewSource.d.ts.map +1 -0
  155. package/dist/runtime/ReviewSource.js +38 -0
  156. package/dist/runtime/Runner.d.ts +7 -0
  157. package/dist/runtime/Runner.d.ts.map +1 -1
  158. package/dist/runtime/Runner.js +215 -171
  159. package/dist/runtime/SecretRedaction.d.ts +11 -0
  160. package/dist/runtime/SecretRedaction.d.ts.map +1 -0
  161. package/dist/runtime/SecretRedaction.js +85 -0
  162. package/dist/runtime/SessionController.d.ts +148 -0
  163. package/dist/runtime/SessionController.d.ts.map +1 -0
  164. package/dist/runtime/SessionController.js +1357 -0
  165. package/dist/runtime/StructuralEvidence.d.ts +22 -0
  166. package/dist/runtime/StructuralEvidence.d.ts.map +1 -0
  167. package/dist/runtime/StructuralEvidence.js +87 -0
  168. package/dist/runtime/TaskReviewContext.d.ts +34 -0
  169. package/dist/runtime/TaskReviewContext.d.ts.map +1 -0
  170. package/dist/runtime/TaskReviewContext.js +34 -0
  171. package/dist/runtime/ValidationOutput.d.ts +5 -0
  172. package/dist/runtime/ValidationOutput.d.ts.map +1 -0
  173. package/dist/runtime/ValidationOutput.js +32 -0
  174. package/dist/runtime/VerificationCommand.d.ts +5 -0
  175. package/dist/runtime/VerificationCommand.d.ts.map +1 -0
  176. package/dist/runtime/VerificationCommand.js +76 -0
  177. package/dist/runtime/WorkStatusPage.d.ts +15 -0
  178. package/dist/runtime/WorkStatusPage.d.ts.map +1 -0
  179. package/dist/runtime/WorkStatusPage.js +58 -0
  180. package/dist/runtime/WorkspaceLedger.d.ts +13 -0
  181. package/dist/runtime/WorkspaceLedger.d.ts.map +1 -0
  182. package/dist/runtime/WorkspaceLedger.js +145 -0
  183. package/dist/runtime/WorkspaceLock.d.ts.map +1 -1
  184. package/dist/runtime/WorkspaceLock.js +20 -17
  185. package/dist/runtime/WorkspaceSnapshot.d.ts +13 -0
  186. package/dist/runtime/WorkspaceSnapshot.d.ts.map +1 -0
  187. package/dist/runtime/WorkspaceSnapshot.js +88 -0
  188. package/dist/session/AtomicState.d.ts +13 -0
  189. package/dist/session/AtomicState.d.ts.map +1 -0
  190. package/dist/session/AtomicState.js +123 -0
  191. package/dist/session/SessionStoragePath.d.ts +15 -0
  192. package/dist/session/SessionStoragePath.d.ts.map +1 -0
  193. package/dist/session/SessionStoragePath.js +89 -0
  194. package/dist/session/SessionStore.d.ts +9 -0
  195. package/dist/session/SessionStore.d.ts.map +1 -1
  196. package/dist/session/SessionStore.js +181 -47
  197. package/dist/session/WorkState.d.ts +23 -0
  198. package/dist/session/WorkState.d.ts.map +1 -0
  199. package/dist/session/WorkState.js +367 -0
  200. package/dist/session/WorkTypes.d.ts +94 -0
  201. package/dist/session/WorkTypes.d.ts.map +1 -0
  202. package/dist/session/WorkTypes.js +1 -0
  203. package/dist/tools/ToolRegistry.d.ts +2 -0
  204. package/dist/tools/ToolRegistry.d.ts.map +1 -1
  205. package/dist/tools/ToolRegistry.js +12 -2
  206. package/dist/tools/ToolTypes.d.ts +16 -0
  207. package/dist/tools/ToolTypes.d.ts.map +1 -1
  208. package/dist/tools/docdex/DocdexTools.d.ts +2 -0
  209. package/dist/tools/docdex/DocdexTools.d.ts.map +1 -1
  210. package/dist/tools/docdex/DocdexTools.js +17 -2
  211. package/dist/tools/filesystem/FileTools.d.ts.map +1 -1
  212. package/dist/tools/filesystem/FileTools.js +30 -10
  213. package/dist/tools/shell/AsyncProcess.d.ts +19 -0
  214. package/dist/tools/shell/AsyncProcess.d.ts.map +1 -0
  215. package/dist/tools/shell/AsyncProcess.js +94 -0
  216. package/dist/tools/shell/DarwinRuntimeLibraries.d.ts +13 -0
  217. package/dist/tools/shell/DarwinRuntimeLibraries.d.ts.map +1 -0
  218. package/dist/tools/shell/DarwinRuntimeLibraries.js +130 -0
  219. package/dist/tools/shell/HostToolchain.d.ts +19 -0
  220. package/dist/tools/shell/HostToolchain.d.ts.map +1 -0
  221. package/dist/tools/shell/HostToolchain.js +266 -0
  222. package/dist/tools/shell/IsolatedExecutor.d.ts +15 -0
  223. package/dist/tools/shell/IsolatedExecutor.d.ts.map +1 -0
  224. package/dist/tools/shell/IsolatedExecutor.js +138 -0
  225. package/dist/tools/shell/ShellTool.d.ts.map +1 -1
  226. package/dist/tools/shell/ShellTool.js +9 -29
  227. package/dist/tools/shell/ShellWorkingDirectory.d.ts +3 -0
  228. package/dist/tools/shell/ShellWorkingDirectory.d.ts.map +1 -0
  229. package/dist/tools/shell/ShellWorkingDirectory.js +30 -0
  230. package/package.json +27 -24
@@ -0,0 +1,215 @@
1
+ import { createServer } from "node:http";
2
+ import { spawn } from "node:child_process";
3
+ import { promises as fs } from "node:fs";
4
+ import { createHash, randomBytes } from "node:crypto";
5
+ import { registerSecretValue, StreamingSecretRedactor } from "../runtime/SecretRedaction.js";
6
+ import path from "node:path";
7
+ import { setTimeout as delay } from "node:timers/promises";
8
+ import { DocdexClient } from "./DocdexClient.js";
9
+ import { runtimeFileHash } from "./ManagedRuntime.js";
10
+ const listen = (server) => new Promise((resolve, reject) => {
11
+ server.once("error", reject);
12
+ server.listen(0, "127.0.0.1", () => { server.removeListener("error", reject); resolve(server.address().port); });
13
+ });
14
+ const closeServer = async (server) => {
15
+ if (!server)
16
+ return;
17
+ server.closeAllConnections();
18
+ await new Promise(resolve => server.close(() => resolve()));
19
+ };
20
+ /** A private Docdex process whose inference is routed through the owning controller. */
21
+ export class ManagedDocdex {
22
+ constructor(options) {
23
+ this.options = options;
24
+ this.diagnostic = "";
25
+ this.activeRequests = 0;
26
+ this.lifetime = new AbortController();
27
+ }
28
+ async start() {
29
+ this.options.signal?.throwIfAborted();
30
+ if (this.child || this.bridge)
31
+ throw new Error("Managed Docdex already started");
32
+ if (this.options.binarySha256 && (!this.options.binary || await runtimeFileHash(this.options.binary) !== this.options.binarySha256))
33
+ throw new Error("Managed Docdex runtime checksum mismatch; run codali doctor before continuing");
34
+ const { embeddings } = this.options;
35
+ const root = path.join(this.options.stateRoot, embeddings.space.id);
36
+ await embeddings.pin(root);
37
+ await fs.mkdir(root, { recursive: true, mode: 0o700 });
38
+ this.launchDirectory = await fs.mkdtemp(path.join(root, "launch-"));
39
+ const capability = randomBytes(32).toString("hex");
40
+ const authToken = randomBytes(32).toString("hex");
41
+ registerSecretValue(capability);
42
+ registerSecretValue(authToken);
43
+ const model = `codali-embedding-${embeddings.space.id}`;
44
+ const signal = AbortSignal.any([this.lifetime.signal, ...(this.options.signal ? [this.options.signal] : [])]);
45
+ const prefix = `/${capability}`;
46
+ this.bridge = createServer(async (request, response) => {
47
+ const send = (status, body) => { response.writeHead(status, { "content-type": "application/json" }); response.end(JSON.stringify(body)); };
48
+ if (request.headers.origin || !request.url?.startsWith(`${prefix}/`)) {
49
+ send(403, { error: "forbidden" });
50
+ return;
51
+ }
52
+ if (this.activeRequests >= 2) {
53
+ send(429, { error: "managed inference busy" });
54
+ return;
55
+ }
56
+ this.activeRequests++;
57
+ const requestAbort = new AbortController();
58
+ const onClose = () => { if (!response.writableEnded)
59
+ requestAbort.abort(); };
60
+ response.once("close", onClose);
61
+ try {
62
+ const route = request.url.slice(prefix.length);
63
+ if (request.method === "GET" && route === "/api/version") {
64
+ send(200, { version: "codali-managed-v1" });
65
+ return;
66
+ }
67
+ if (request.method === "GET" && route === "/api/tags") {
68
+ send(200, { models: [{ name: "configured-docdex-helper", model: "configured-docdex-helper" }] });
69
+ return;
70
+ }
71
+ if (request.method !== "POST") {
72
+ send(405, { error: "method not allowed" });
73
+ return;
74
+ }
75
+ let bytes = 0;
76
+ const chunks = [];
77
+ for await (const chunk of request) {
78
+ bytes += chunk.length;
79
+ if (bytes > 1048576) {
80
+ send(413, { error: "request too large" });
81
+ return;
82
+ }
83
+ chunks.push(Buffer.from(chunk));
84
+ }
85
+ const body = JSON.parse(Buffer.concat(chunks).toString());
86
+ const requestSignal = AbortSignal.any([signal, requestAbort.signal]);
87
+ if (route === "/v1/embeddings") {
88
+ if (body.model !== model || !["query", "document"].includes(String(body.input_type))) {
89
+ send(400, { error: "managed embedding identity and input_type are required" });
90
+ return;
91
+ }
92
+ const input = typeof body.input === "string" ? [body.input] : body.input;
93
+ if (!Array.isArray(input) || input.some(text => typeof text !== "string")) {
94
+ send(400, { error: "invalid embedding input" });
95
+ return;
96
+ }
97
+ const vectors = await embeddings.embed(input, body.input_type, requestSignal);
98
+ send(200, { object: "list", model, data: vectors.map((embedding, index) => ({ object: "embedding", index, embedding })) });
99
+ return;
100
+ }
101
+ if (body.model !== "configured-docdex-helper") {
102
+ send(400, { error: "undeclared inference model" });
103
+ return;
104
+ }
105
+ if (route === "/api/show") {
106
+ send(200, { capabilities: ["completion"], model_info: { "general.architecture": "managed" } });
107
+ return;
108
+ }
109
+ if (!["/api/chat", "/api/generate"].includes(route)) {
110
+ send(404, { error: "unsupported managed inference operation" });
111
+ return;
112
+ }
113
+ const messages = route === "/api/generate" && typeof body.prompt === "string"
114
+ ? [{ role: "user", content: body.prompt }] : body.messages;
115
+ if (!Array.isArray(messages) || messages.length > 128 || messages.some(message => !message || !["system", "user", "assistant"].includes(message.role) || typeof message.content !== "string")) {
116
+ send(400, { error: "invalid inference messages" });
117
+ return;
118
+ }
119
+ const result = await this.options.provider.generate({ messages, signal: requestSignal, stream: false, maxTokens: 2048 });
120
+ send(200, { model: "configured-docdex-helper", created_at: new Date().toISOString(), done: true,
121
+ message: { role: "assistant", content: result.message.content }, response: result.message.content,
122
+ ...(result.usage ? { prompt_eval_count: result.usage.inputTokens, eval_count: result.usage.outputTokens } : {}) });
123
+ }
124
+ catch {
125
+ if (!response.headersSent)
126
+ send(502, { error: "Managed inference failed; consult the owning session receipts" });
127
+ }
128
+ finally {
129
+ this.activeRequests--;
130
+ response.removeListener("close", onClose);
131
+ }
132
+ });
133
+ try {
134
+ const bridgePort = await listen(this.bridge);
135
+ const bridgeBase = `http://127.0.0.1:${bridgePort}${prefix}`;
136
+ const reservation = createServer();
137
+ const port = await listen(reservation);
138
+ await closeServer(reservation);
139
+ const configPath = path.join(this.launchDirectory, "config.toml");
140
+ const repositoryState = path.join(root, "repositories", createHash("sha256").update(path.resolve(this.options.workspaceRoot)).digest("hex"));
141
+ const config = `[core]\nglobal_state_dir = ${JSON.stringify(root)}\n[server]\nhttp_bind_addr = "127.0.0.1:${port}"\n[llm]\nprovider = "ollama"\nbase_url = ${JSON.stringify(bridgeBase)}\ndefault_model = "configured-docdex-helper"\nembedding_model = ${JSON.stringify(model)}\n[llm.delegation]\nenabled = false\nauto_enable = false\n[memory]\nenabled = true\n[memory.profile]\nembedding_model = "hash-embed-v1"\nembedding_dim = 768\n[memory.conversations]\nenabled = true\nauto_capture = false\n[memory.personal_preferences]\nenabled = false\n[memory.user_memory_sync]\nenabled = false\n`;
142
+ await fs.writeFile(configPath, config, { mode: 0o600, flag: "wx" });
143
+ const env = {};
144
+ for (const key of ["PATH", "HOME", "USER", "LOGNAME", "LANG", "TMPDIR", "SystemRoot"])
145
+ if (process.env[key])
146
+ env[key] = process.env[key];
147
+ Object.assign(env, { DOCDEX_CONFIG_PATH: configPath, DOCDEX_AUTH_TOKEN: authToken,
148
+ DOCDEX_DAEMON_LOCK_PATH: path.join(this.launchDirectory, "daemon.lock"),
149
+ DOCDEX_MANAGED_INSTANCE: "1",
150
+ DOCDEX_HTTP_BASE_URL: `http://127.0.0.1:${port}`,
151
+ DOCDEX_EMBEDDING_PROVIDER: "llama-cpp", DOCDEX_EMBEDDING_BASE_URL: `${bridgeBase}/v1`, DOCDEX_EMBEDDING_MODEL: model,
152
+ DOCDEX_PROFILE_EMBEDDING_PROVIDER: "hash", DOCDEX_PROFILE_EMBEDDING_MODEL: "hash-embed-v1",
153
+ DOCDEX_PROFILE_STATE_DIR: path.join(this.options.stateRoot, "global-profile"),
154
+ DOCDEX_EMBEDDING_SEND_PURPOSE: "1", DOCDEX_EMBEDDING_STRICT: "1", DOCDEX_WEB_ENABLED: this.options.allowWeb ? "1" : "0",
155
+ DOCDEX_DISABLE_METRICS: "1", DOCDEX_WORKSPACE_METADATA: "0" });
156
+ this.child = spawn(this.options.binary ?? "docdexd", ["serve", "--repo", this.options.workspaceRoot, "--state-dir", repositoryState,
157
+ "--workspace-metadata=false", "--host", "127.0.0.1", "--port", String(port), "--enable-memory=true", "--enable-mcp", "--mcp-ipc", "off", "--preflight-check=false", "--log", "warn"], { env, stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
158
+ let startError;
159
+ this.child.on("error", error => { startError = error; });
160
+ const diagnosticRedactor = new StreamingSecretRedactor();
161
+ const output = (chunk) => { this.diagnostic = (this.diagnostic + diagnosticRedactor.write(chunk.toString())).slice(-4000); };
162
+ this.child.stdout?.on("data", output);
163
+ this.child.stderr?.on("data", output);
164
+ this.abort = () => { this.child?.kill("SIGTERM"); };
165
+ signal.addEventListener("abort", this.abort, { once: true });
166
+ const baseUrl = `http://127.0.0.1:${port}`;
167
+ const deadline = Date.now() + (this.options.startupTimeoutMs ?? 90000);
168
+ this.options.onStatus?.("Starting private Docdex with configured embedding space");
169
+ while (true) {
170
+ signal.throwIfAborted();
171
+ if (startError || this.child.exitCode !== null || this.child.signalCode !== null)
172
+ throw new Error(`Managed Docdex failed to start: ${startError?.message ?? this.diagnostic}`);
173
+ try {
174
+ const response = await fetch(`${baseUrl}/v1/capabilities`, { headers: { authorization: `Bearer ${authToken}` }, signal: AbortSignal.any([signal, AbortSignal.timeout(1500)]) });
175
+ if (response.ok) {
176
+ const capabilities = await response.json();
177
+ if (!["workspace_metadata_control", "embedding_input_type", "strict_repo_embeddings", "deterministic_profile_embeddings"].every(key => capabilities.managed_clients?.[key]))
178
+ throw new Error("Managed Docdex capabilities missing");
179
+ return new DocdexClient({ baseUrl, repoRoot: this.options.workspaceRoot, authToken, localSearchOnly: true, timeoutMs: 30000, signal: () => signal });
180
+ }
181
+ }
182
+ catch (error) {
183
+ if (error instanceof Error && error.message === "Managed Docdex capabilities missing")
184
+ throw error;
185
+ }
186
+ if (Date.now() >= deadline)
187
+ throw new Error(`Managed Docdex startup timed out: ${this.diagnostic}`);
188
+ await delay(200, undefined, { signal });
189
+ }
190
+ }
191
+ catch (error) {
192
+ await this.close();
193
+ throw error;
194
+ }
195
+ }
196
+ async close() {
197
+ this.lifetime.abort();
198
+ const child = this.child;
199
+ this.child = undefined;
200
+ if (child && child.exitCode === null && child.signalCode === null) {
201
+ const exited = new Promise(resolve => child.once("exit", () => resolve()));
202
+ child.kill("SIGTERM");
203
+ await Promise.race([exited, delay(3000)]);
204
+ if (child.exitCode === null && child.signalCode === null) {
205
+ child.kill("SIGKILL");
206
+ await Promise.race([exited, delay(1000)]);
207
+ }
208
+ }
209
+ await closeServer(this.bridge);
210
+ this.bridge = undefined;
211
+ if (this.launchDirectory)
212
+ await fs.rm(this.launchDirectory, { recursive: true, force: true });
213
+ this.launchDirectory = undefined;
214
+ }
215
+ }
@@ -0,0 +1,28 @@
1
+ export interface ManagedRuntimeIdentity {
2
+ binary: string;
3
+ binarySha256: string;
4
+ version: string;
5
+ }
6
+ export interface ManagedRuntimeArtifact {
7
+ url: string;
8
+ archiveSha256: string;
9
+ binarySha256: string;
10
+ }
11
+ export interface ManagedRuntimeManifest {
12
+ schemaVersion: 1;
13
+ version?: string;
14
+ artifacts: Record<string, ManagedRuntimeArtifact>;
15
+ }
16
+ export declare const runtimeFileHash: (file: string) => Promise<string>;
17
+ /** No daemon, repo initialization, model request or global configuration access. */
18
+ export declare const inspectManagedDocdexRuntime: (binary: string, expectedSha256?: string, signal?: AbortSignal, redirected?: boolean) => Promise<ManagedRuntimeIdentity>;
19
+ export declare const runtimePlatformKey: () => string;
20
+ export declare const validateRuntimeManifest: (value: unknown) => ManagedRuntimeManifest;
21
+ /** Content-addressed private install. A failed upgrade leaves existing versions untouched. */
22
+ export declare const ensureManagedDocdexRuntime: (options?: {
23
+ binary?: string;
24
+ stateRoot?: string;
25
+ manifest?: ManagedRuntimeManifest;
26
+ signal?: AbortSignal;
27
+ }) => Promise<ManagedRuntimeIdentity>;
28
+ //# sourceMappingURL=ManagedRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManagedRuntime.d.ts","sourceRoot":"","sources":["../../src/docdex/ManagedRuntime.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,sBAAsB;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAAE;AAClG,MAAM,WAAW,sBAAsB;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;CAAE;AACrG,MAAM,WAAW,sBAAsB;IAAG,aAAa,EAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAAE;AAalI,eAAO,MAAM,eAAe,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,MAAM,CAKlE,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,2BAA2B,GAAU,QAAQ,MAAM,EAAE,iBAAiB,MAAM,EAAE,SAAS,WAAW,EAAE,oBAAkB,KAAG,OAAO,CAAC,sBAAsB,CA0BnK,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAO,MAOrC,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,OAAO,OAAO,KAAG,sBAUxD,CAAC;AAkBF,8FAA8F;AAC9F,eAAO,MAAM,0BAA0B,GAAU,UAAS;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,KAAG,OAAO,CAAC,sBAAsB,CAkD/L,CAAC"}
@@ -0,0 +1,212 @@
1
+ import { createHash } from "node:crypto";
2
+ import { createReadStream, promises as fs } from "node:fs";
3
+ import { execFile } from "node:child_process";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { withStateLock } from "../session/AtomicState.js";
7
+ const FEATURES = ["workspace_metadata_control", "embedding_input_type", "strict_repo_embeddings", "deterministic_profile_embeddings"];
8
+ const MAX_ARCHIVE_BYTES = 128 * 1024 * 1024;
9
+ const MAX_BINARY_BYTES = 256 * 1024 * 1024;
10
+ const cleanEnvironment = () => {
11
+ const env = {};
12
+ for (const key of ["PATH", "HOME", "USER", "LOGNAME", "TMPDIR", "SystemRoot"])
13
+ if (process.env[key])
14
+ env[key] = process.env[key];
15
+ return env;
16
+ };
17
+ const execute = (command, args, options) => new Promise((resolve, reject) => {
18
+ execFile(command, args, { ...options, env: cleanEnvironment(), encoding: "buffer", timeout: 30000, maxBuffer: options.maxBuffer ?? 64 * 1024, windowsHide: true }, (error, stdout) => {
19
+ if (error)
20
+ reject(new Error(`Docdex runtime command failed (${path.basename(command)}): ${error.code ?? "unknown"}`));
21
+ else
22
+ resolve(stdout);
23
+ });
24
+ });
25
+ export const runtimeFileHash = async (file) => {
26
+ const stat = await fs.lstat(file);
27
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.size > MAX_BINARY_BYTES)
28
+ throw new Error("Docdex runtime must be a bounded regular file");
29
+ const hash = createHash("sha256");
30
+ for await (const chunk of createReadStream(file))
31
+ hash.update(chunk);
32
+ return hash.digest("hex");
33
+ };
34
+ /** No daemon, repo initialization, model request or global configuration access. */
35
+ export const inspectManagedDocdexRuntime = async (binary, expectedSha256, signal, redirected = false) => {
36
+ let resolved = binary;
37
+ if (!path.isAbsolute(binary)) {
38
+ if (binary.includes(path.sep))
39
+ throw new Error("Docdex binary must be an absolute path or a PATH command");
40
+ resolved = "";
41
+ for (const directory of (process.env.PATH ?? "").split(path.delimiter).filter(path.isAbsolute)) {
42
+ const candidate = path.join(directory, binary);
43
+ try {
44
+ await fs.access(candidate, fs.constants.X_OK);
45
+ resolved = candidate;
46
+ break;
47
+ }
48
+ catch { /* next trusted PATH entry */ }
49
+ }
50
+ if (!resolved)
51
+ throw new Error("No compatible Docdex runtime found on PATH");
52
+ }
53
+ resolved = await fs.realpath(resolved);
54
+ const binarySha256 = await runtimeFileHash(resolved);
55
+ if (expectedSha256 && expectedSha256 !== binarySha256)
56
+ throw new Error("Docdex runtime checksum mismatch");
57
+ const cwd = await fs.mkdtemp(path.join(os.tmpdir(), "codali-runtime-probe-"));
58
+ try {
59
+ const info = JSON.parse((await execute(resolved, ["runtime-info"], { cwd, signal })).toString());
60
+ if (info.schema_version !== 1 || typeof info.version !== "string" || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(info.version) || !FEATURES.every(feature => info.managed_clients?.[feature] === true))
61
+ throw new Error("Docdex runtime lacks required managed-client capabilities");
62
+ if (typeof info.executable !== "string" || !path.isAbsolute(info.executable))
63
+ throw new Error("Docdex runtime did not identify its native executable");
64
+ const native = await fs.realpath(info.executable);
65
+ if (native !== resolved) {
66
+ if (redirected || expectedSha256)
67
+ throw new Error("Docdex runtime executable changed during qualification");
68
+ return inspectManagedDocdexRuntime(native, undefined, signal, true);
69
+ }
70
+ return { binary: resolved, binarySha256, version: info.version };
71
+ }
72
+ finally {
73
+ await fs.rm(cwd, { recursive: true, force: true });
74
+ }
75
+ };
76
+ export const runtimePlatformKey = () => {
77
+ if (process.platform === "darwin")
78
+ return `darwin-${process.arch}`;
79
+ if (process.platform === "linux") {
80
+ const report = process.report?.getReport();
81
+ return `linux-${process.arch}-${report?.header?.glibcVersionRuntime ? "gnu" : "musl"}`;
82
+ }
83
+ throw new Error(`Managed Codali runtime is not qualified for ${process.platform}-${process.arch}`);
84
+ };
85
+ export const validateRuntimeManifest = (value) => {
86
+ const manifest = value;
87
+ if (!manifest || manifest.schemaVersion !== 1 || !manifest.artifacts || typeof manifest.artifacts !== "object" || Array.isArray(manifest.artifacts))
88
+ throw new Error("Invalid Docdex runtime manifest");
89
+ if (manifest.version !== undefined && (typeof manifest.version !== "string" || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(manifest.version)))
90
+ throw new Error("Invalid Docdex release version");
91
+ for (const [platform, artifact] of Object.entries(manifest.artifacts)) {
92
+ if (!/^(linux-(x64|arm64)-(gnu|musl)|darwin-(x64|arm64))$/.test(platform) || !manifest.version || !artifact || typeof artifact.url !== "string" || typeof artifact.archiveSha256 !== "string" || typeof artifact.binarySha256 !== "string" || !/^[a-f0-9]{64}$/.test(artifact.archiveSha256) || !/^[a-f0-9]{64}$/.test(artifact.binarySha256))
93
+ throw new Error("Invalid pinned Docdex artifact");
94
+ const url = new URL(artifact.url);
95
+ if (url.origin !== "https://github.com" || url.username || url.password || url.search || url.hash || !url.pathname.startsWith(`/bekirdag/docdex/releases/download/v${manifest.version}/`) || !url.pathname.endsWith(".tar.gz"))
96
+ throw new Error("Docdex artifact must come from the pinned publisher release");
97
+ }
98
+ return manifest;
99
+ };
100
+ const download = async (artifact, destination, signal) => {
101
+ const response = await fetch(artifact.url, { signal: AbortSignal.any([AbortSignal.timeout(120000), ...(signal ? [signal] : [])]), credentials: "omit", referrerPolicy: "no-referrer" });
102
+ if (!response.ok || !response.body)
103
+ throw new Error(`Docdex runtime download failed (${response.status})`);
104
+ if (response.url && new URL(response.url).protocol !== "https:")
105
+ throw new Error("Insecure Docdex download redirect");
106
+ if (Number(response.headers.get("content-length")) > MAX_ARCHIVE_BYTES) {
107
+ await response.body.cancel();
108
+ throw new Error("Docdex runtime archive exceeds the download limit");
109
+ }
110
+ const handle = await fs.open(destination, "wx", 0o600);
111
+ const hash = createHash("sha256");
112
+ let bytes = 0;
113
+ try {
114
+ for await (const chunk of response.body) {
115
+ bytes += chunk.length;
116
+ if (bytes > MAX_ARCHIVE_BYTES)
117
+ throw new Error("Docdex runtime archive exceeds the download limit");
118
+ hash.update(chunk);
119
+ await handle.writeFile(chunk);
120
+ }
121
+ await handle.sync();
122
+ if (hash.digest("hex") !== artifact.archiveSha256)
123
+ throw new Error("Docdex runtime archive checksum mismatch");
124
+ }
125
+ finally {
126
+ await handle.close();
127
+ }
128
+ };
129
+ /** Content-addressed private install. A failed upgrade leaves existing versions untouched. */
130
+ export const ensureManagedDocdexRuntime = async (options = {}) => {
131
+ if (options.binary)
132
+ return inspectManagedDocdexRuntime(options.binary, undefined, options.signal);
133
+ const manifest = validateRuntimeManifest(options.manifest ?? JSON.parse(await fs.readFile(new URL("../../config/docdex-runtime.json", import.meta.url), "utf8")));
134
+ const artifact = manifest.artifacts[runtimePlatformKey()];
135
+ if (!artifact) {
136
+ throw new Error("This build has no qualified Docdex release for this platform. Supply --docdex-binary with a compatible runtime or install a qualified Codali release.");
137
+ }
138
+ const root = path.resolve(options.stateRoot ?? path.join(os.homedir(), ".local", "state", "codali", "runtimes", "docdex"));
139
+ await fs.mkdir(root, { recursive: true, mode: 0o700 });
140
+ const rootStat = await fs.lstat(root);
141
+ if (!rootStat.isDirectory() || rootStat.isSymbolicLink() || rootStat.mode & 0o077 || (process.getuid && rootStat.uid !== process.getuid()))
142
+ throw new Error("Docdex runtime directory must be private and owned by the current user");
143
+ const destination = path.join(root, artifact.binarySha256);
144
+ return withStateLock(path.join(root, "install"), async () => {
145
+ options.signal?.throwIfAborted();
146
+ // The OS-owned lock is released after a killed installer. Only its private
147
+ // staging directories are disposable; committed versions are never pruned.
148
+ for (const entry of await fs.readdir(root, { withFileTypes: true })) {
149
+ if (/^\.install-[A-Za-z0-9]+$/.test(entry.name) && entry.isDirectory())
150
+ await fs.rm(path.join(root, entry.name), { recursive: true });
151
+ }
152
+ let cached = false;
153
+ try {
154
+ const directory = await fs.lstat(destination);
155
+ if (!directory.isDirectory() || directory.isSymbolicLink() || directory.mode & 0o077 || (process.getuid && directory.uid !== process.getuid()))
156
+ throw new Error("Docdex cached release must be a private directory");
157
+ cached = true;
158
+ }
159
+ catch (error) {
160
+ if (error.code !== "ENOENT")
161
+ throw error;
162
+ }
163
+ if (cached) {
164
+ if (await runtimeFileHash(path.join(destination, "docdexd")) !== artifact.binarySha256)
165
+ throw new Error("Docdex runtime checksum mismatch");
166
+ const info = await inspectManagedDocdexRuntime(path.join(destination, "docdexd"), artifact.binarySha256, options.signal);
167
+ if (info.version !== manifest.version)
168
+ throw new Error("Docdex runtime version does not match the manifest");
169
+ return info;
170
+ }
171
+ const staging = await fs.mkdtemp(path.join(root, ".install-"));
172
+ try {
173
+ const archive = path.join(staging, "runtime.tar.gz");
174
+ await download(artifact, archive, options.signal);
175
+ // Extract only the single pinned member to bytes, never paths from
176
+ // an archive. No package lifecycle scripts or machine-wide installers run.
177
+ const bytes = await execute("tar", ["-xOf", archive, "docdexd"], { cwd: staging, signal: options.signal, maxBuffer: MAX_BINARY_BYTES });
178
+ if (createHash("sha256").update(bytes).digest("hex") !== artifact.binarySha256)
179
+ throw new Error("Docdex extracted binary checksum mismatch");
180
+ const binary = path.join(staging, "docdexd");
181
+ const handle = await fs.open(binary, "wx", 0o700);
182
+ try {
183
+ await handle.writeFile(bytes);
184
+ await handle.sync();
185
+ }
186
+ finally {
187
+ await handle.close();
188
+ }
189
+ const info = await inspectManagedDocdexRuntime(binary, artifact.binarySha256, options.signal);
190
+ if (info.version !== manifest.version)
191
+ throw new Error("Docdex runtime version does not match the manifest");
192
+ options.signal?.throwIfAborted();
193
+ await fs.unlink(archive);
194
+ await fs.rename(staging, destination);
195
+ const directory = await fs.open(root, "r");
196
+ try {
197
+ await directory.sync();
198
+ }
199
+ catch (error) {
200
+ if (!["EINVAL", "ENOTSUP"].includes(error.code ?? ""))
201
+ throw error;
202
+ }
203
+ finally {
204
+ await directory.close();
205
+ }
206
+ return { ...info, binary: await fs.realpath(path.join(destination, "docdexd")) };
207
+ }
208
+ finally {
209
+ await fs.rm(staging, { recursive: true, force: true });
210
+ }
211
+ }, 180000);
212
+ };
@@ -0,0 +1,13 @@
1
+ import type { OrchestrationConfig } from "../config/OrchestrationConfig.js";
2
+ /** A trusted evaluator child runs the CLI itself, so it needs only the declared
3
+ * provider credentials. This is never used for model-requested shell tools. */
4
+ export declare function evaluationEnvironment(config: OrchestrationConfig): NodeJS.ProcessEnv;
5
+ export declare function runEvaluationProcess(options: {
6
+ file: string;
7
+ args: string[];
8
+ cwd: string;
9
+ config: OrchestrationConfig;
10
+ timeoutMs: number;
11
+ signal?: AbortSignal;
12
+ }): Promise<void>;
13
+ //# sourceMappingURL=EvaluationProcess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvaluationProcess.d.ts","sourceRoot":"","sources":["../../src/eval/EvaluationProcess.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;+EAC+E;AAC/E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAAC,UAAU,CAQpF;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BtL"}
@@ -0,0 +1,76 @@
1
+ import { spawn } from "node:child_process";
2
+ import os from "node:os";
3
+ import { safeProcessEnvironment } from "../tools/shell/AsyncProcess.js";
4
+ /** A trusted evaluator child runs the CLI itself, so it needs only the declared
5
+ * provider credentials. This is never used for model-requested shell tools. */
6
+ export function evaluationEnvironment(config) {
7
+ const env = { ...safeProcessEnvironment(), HOME: os.homedir() };
8
+ for (const provider of Object.values(config.providers)) {
9
+ if (!provider.credentialRef?.startsWith("env:"))
10
+ continue;
11
+ const key = provider.credentialRef.slice(4);
12
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) && process.env[key] !== undefined)
13
+ env[key] = process.env[key];
14
+ }
15
+ return env;
16
+ }
17
+ export async function runEvaluationProcess(options) {
18
+ options.signal?.throwIfAborted();
19
+ if (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1)
20
+ throw new Error("Invalid evaluator deadline");
21
+ await new Promise((resolve, reject) => {
22
+ const child = spawn(process.execPath, [options.file, ...options.args], { cwd: options.cwd, env: evaluationEnvironment(options.config),
23
+ detached: process.platform !== "win32", stdio: ["ignore", "pipe", "pipe"] });
24
+ let output = "";
25
+ let bytes = 0;
26
+ let failure;
27
+ let escalation;
28
+ const kill = (signal) => {
29
+ if (!child.pid)
30
+ return;
31
+ try {
32
+ if (process.platform !== "win32")
33
+ process.kill(-child.pid, signal);
34
+ else
35
+ child.kill(signal);
36
+ }
37
+ catch (error) {
38
+ if (error.code !== "ESRCH")
39
+ child.kill(signal);
40
+ }
41
+ };
42
+ const stop = () => { kill("SIGTERM"); escalation ?? (escalation = setTimeout(() => kill("SIGKILL"), 3000)); escalation.unref(); };
43
+ const timeout = setTimeout(() => { failure = new Error("Evaluation stage deadline exceeded"); stop(); }, options.timeoutMs);
44
+ const capture = (chunk) => {
45
+ bytes += chunk.length;
46
+ if (bytes <= 131072)
47
+ output += chunk.toString("utf8");
48
+ else {
49
+ failure ?? (failure = new Error("Evaluation stage output exceeded its bound"));
50
+ stop();
51
+ }
52
+ };
53
+ child.stdout.on("data", capture);
54
+ child.stderr.on("data", capture);
55
+ options.signal?.addEventListener("abort", stop, { once: true });
56
+ if (options.signal?.aborted)
57
+ stop();
58
+ child.once("error", error => { failure = error; });
59
+ child.once("close", (code, signal) => {
60
+ clearTimeout(timeout);
61
+ if (escalation)
62
+ clearTimeout(escalation);
63
+ options.signal?.removeEventListener("abort", stop);
64
+ if (process.platform !== "win32")
65
+ kill("SIGKILL");
66
+ if (options.signal?.aborted)
67
+ reject(options.signal.reason ?? new Error("Evaluation cancelled"));
68
+ else if (failure)
69
+ reject(failure);
70
+ else if (code !== 0 || signal)
71
+ reject(new Error(output.slice(-8000) || `Evaluation exited ${code ?? signal}`));
72
+ else
73
+ resolve();
74
+ });
75
+ });
76
+ }
@@ -0,0 +1,34 @@
1
+ import type { WorkState } from "../session/WorkTypes.js";
2
+ export declare const LONG_WORKFLOW_VERSION = "long-workflows-v2";
3
+ export declare const longWorkflowScenarios: readonly [{
4
+ readonly id: "data-delivery";
5
+ readonly objective: "Deliver a reliable data-processing toolkit with exact money totals, validated imports, CSV export and additive record migration.";
6
+ readonly modules: readonly ["invoice-cents", "jsonl-import", "csv-export", "additive-record-migration"];
7
+ }, {
8
+ readonly id: "service-adapters";
9
+ readonly objective: "Deliver a service-adapter toolkit with safe headers, bounded async execution, locale fallback and interval reservations.";
10
+ readonly modules: readonly ["header-normalization", "async-worker-pool", "locale-fallback", "interval-reservation"];
11
+ }, {
12
+ readonly id: "billing-audit";
13
+ readonly objective: "Deliver a billing-readiness package: source-backed duplicate-submit and tenant-isolation reports, exact invoice totals and a data-preserving migration.";
14
+ readonly modules: readonly ["investigate-duplicate-submit", "investigate-tenant-key", "invoice-cents", "additive-record-migration"];
15
+ }, {
16
+ readonly id: "localized-export";
17
+ readonly objective: "Deliver localized export adapters with CSV correctness, normalized headers and a source-backed fictional render-service upgrade report.";
18
+ readonly modules: readonly ["locale-fallback", "csv-export", "header-normalization", "research-pinned-upgrade"];
19
+ }];
20
+ export type LongWorkflowScenario = typeof longWorkflowScenarios[number];
21
+ export declare const longWorkflowHash: () => string;
22
+ export declare function longWorkflowPrompt(scenario: LongWorkflowScenario): string;
23
+ /** One invocation is one OS process in the parent runner. Stage 2 deliberately
24
+ * checkpoints after a verified task, never during a pending side effect. */
25
+ export declare function runLongWorkflowStage(descriptorPath: string, stage: number): Promise<void>;
26
+ export declare function gradeLongWorkflowState(objective: string, state: WorkState, initial?: WorkState): string[];
27
+ export declare function runLongWorkflowJourney(options: {
28
+ configPath: string;
29
+ outputRoot: string;
30
+ scenarioId: string;
31
+ signal?: AbortSignal;
32
+ onProgress?: (event: Record<string, unknown>) => void;
33
+ }): Promise<void>;
34
+ //# sourceMappingURL=LongWorkflowJourney.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LongWorkflowJourney.d.ts","sourceRoot":"","sources":["../../src/eval/LongWorkflowJourney.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzD,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AACzD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;EAKxB,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAExE,eAAO,MAAM,gBAAgB,cAAiN,CAAC;AAI/O,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,CAGzE;AAMD;4EAC4E;AAC5E,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD/F;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,EAAE,CA2BzG;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDhN"}