sneakoscope 2.0.2 → 2.0.5
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/README.md +12 -8
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +86 -8
- package/dist/commands/doctor.js +14 -0
- package/dist/core/agents/agent-orchestrator.js +70 -4
- package/dist/core/agents/agent-patch-proof.js +5 -0
- package/dist/core/agents/agent-proof-evidence.js +61 -0
- package/dist/core/agents/agent-roster.js +35 -6
- package/dist/core/agents/agent-schema.js +1 -1
- package/dist/core/agents/native-worker-backend-router.js +31 -9
- package/dist/core/agents/ollama-worker-config.js +164 -15
- package/dist/core/codex/codex-0-137-compat.js +119 -0
- package/dist/core/codex-control/codex-control-proof.js +4 -1
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +20 -0
- package/dist/core/codex-control/codex-output-schemas.js +5 -1
- package/dist/core/codex-control/codex-sdk-capability.js +1 -1
- package/dist/core/codex-control/codex-task-runner.js +329 -5
- package/dist/core/codex-control/gpt-final-arbiter.js +160 -0
- package/dist/core/codex-control/gpt-final-context-compressor.js +17 -0
- package/dist/core/codex-control/gpt-final-proof-pack.js +120 -0
- package/dist/core/codex-control/gpt-final-review-schema.js +71 -0
- package/dist/core/codex-control/python-codex-sdk-adapter.js +197 -0
- package/dist/core/codex-control/python-codex-sdk-event-translator.js +14 -0
- package/dist/core/commands/local-model-command.js +79 -18
- package/dist/core/commands/naruto-command.js +195 -12
- package/dist/core/commands/run-command.js +6 -2
- package/dist/core/doctor/doctor-readiness-matrix.js +34 -0
- package/dist/core/feature-fixtures.js +4 -0
- package/dist/core/fsx.js +1 -1
- package/dist/core/git-simple.js +143 -4
- package/dist/core/local-llm/local-collaboration-policy.js +93 -0
- package/dist/core/local-llm/local-llm-backpressure.js +20 -0
- package/dist/core/local-llm/local-llm-capability.js +29 -0
- package/dist/core/local-llm/local-llm-client.js +100 -0
- package/dist/core/local-llm/local-llm-config.js +20 -0
- package/dist/core/local-llm/local-llm-context-cache.js +21 -0
- package/dist/core/local-llm/local-llm-control-adapter.js +101 -0
- package/dist/core/local-llm/local-llm-json-repair.js +52 -0
- package/dist/core/local-llm/local-llm-metrics.js +42 -0
- package/dist/core/local-llm/local-llm-ollama-client.js +67 -0
- package/dist/core/local-llm/local-llm-openai-compatible-client.js +30 -0
- package/dist/core/local-llm/local-llm-prompt-cache.js +12 -0
- package/dist/core/local-llm/local-llm-scheduler.js +29 -0
- package/dist/core/local-llm/local-llm-schema-enforcer.js +15 -0
- package/dist/core/local-llm/local-llm-smoke.js +83 -0
- package/dist/core/local-llm/local-llm-warmup.js +20 -0
- package/dist/core/local-llm/local-worker-eligibility.js +27 -0
- package/dist/core/naruto/hardware-capacity-probe.js +36 -0
- package/dist/core/naruto/naruto-active-pool.js +118 -0
- package/dist/core/naruto/naruto-backpressure.js +13 -0
- package/dist/core/naruto/naruto-concurrency-governor.js +65 -0
- package/dist/core/naruto/naruto-finalizer.js +18 -0
- package/dist/core/naruto/naruto-generation-scheduler.js +18 -0
- package/dist/core/naruto/naruto-gpt-final-pack.js +49 -0
- package/dist/core/naruto/naruto-parallel-patch-apply.js +95 -0
- package/dist/core/naruto/naruto-patch-transaction-batch.js +42 -0
- package/dist/core/naruto/naruto-role-policy.js +107 -0
- package/dist/core/naruto/naruto-verification-dag.js +42 -0
- package/dist/core/naruto/naruto-verification-pool.js +18 -0
- package/dist/core/naruto/naruto-work-graph.js +198 -0
- package/dist/core/naruto/naruto-work-item.js +40 -0
- package/dist/core/naruto/naruto-work-stealing.js +11 -0
- package/dist/core/naruto/resource-pressure-monitor.js +32 -0
- package/dist/core/pipeline/final-gpt-patch-stage.js +31 -0
- package/dist/core/pipeline/final-gpt-review-stage.js +5 -0
- package/dist/core/pipeline/finalize-pipeline-result.js +58 -0
- package/dist/core/pipeline/gpt-final-required.js +12 -0
- package/dist/core/prompt/prompt-placeholder-guard.js +30 -0
- package/dist/core/router/capability-card.js +13 -0
- package/dist/core/router/route-cache.js +3 -0
- package/dist/core/router/ultra-router.js +2 -1
- package/dist/core/routes.js +4 -4
- package/dist/core/safety/mutation-guard.js +2 -0
- package/dist/core/update-check.js +60 -25
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-lane-runtime.js +2 -2
- package/dist/core/zellij/zellij-naruto-dashboard.js +36 -0
- package/dist/core/zellij/zellij-worker-pane-manager.js +4 -4
- package/dist/scripts/blackbox-command-import-smoke.js +10 -1
- package/dist/scripts/check-package-boundary.js +12 -3
- package/dist/scripts/codex-0-137-compat-check.js +27 -0
- package/dist/scripts/codex-environment-scoped-approvals-check.js +10 -0
- package/dist/scripts/codex-plugin-list-json-check.js +8 -0
- package/dist/scripts/codex-sdk-team-naruto-agent-pipeline-check.js +2 -1
- package/dist/scripts/codex-thread-runtime-choice-check.js +10 -0
- package/dist/scripts/gpt-final-arbiter-check.js +63 -0
- package/dist/scripts/gpt-final-arbiter-performance-check.js +36 -0
- package/dist/scripts/local-collab-all-pipelines-final-gpt-check.js +21 -0
- package/dist/scripts/local-collab-gpt-final-availability-check.js +58 -0
- package/dist/scripts/local-collab-no-local-only-final-check.js +27 -0
- package/dist/scripts/local-collab-policy-check.js +17 -0
- package/dist/scripts/local-llm-all-pipelines-check.js +11 -0
- package/dist/scripts/local-llm-cache-performance-check.js +10 -0
- package/dist/scripts/local-llm-capability-check.js +14 -0
- package/dist/scripts/local-llm-smoke-check.js +23 -0
- package/dist/scripts/local-llm-structured-output-check.js +11 -0
- package/dist/scripts/local-llm-throughput-check.js +10 -0
- package/dist/scripts/local-llm-tool-call-repair-check.js +10 -0
- package/dist/scripts/local-llm-warmup-check.js +11 -0
- package/dist/scripts/naruto-active-pool-check.js +27 -0
- package/dist/scripts/naruto-concurrency-governor-check.js +52 -0
- package/dist/scripts/naruto-gpt-final-pack-check.js +34 -0
- package/dist/scripts/naruto-parallel-patch-apply-check.js +41 -0
- package/dist/scripts/naruto-real-local-gpt-final-smoke.js +16 -0
- package/dist/scripts/naruto-role-distribution-check.js +23 -0
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +6 -0
- package/dist/scripts/naruto-verification-pool-check.js +36 -0
- package/dist/scripts/naruto-work-graph-check.js +24 -0
- package/dist/scripts/naruto-zellij-massive-ui-check.js +23 -0
- package/dist/scripts/prompt-placeholder-guard-check.js +33 -0
- package/dist/scripts/python-codex-sdk-all-pipelines-check.js +47 -0
- package/dist/scripts/python-codex-sdk-capability-check.js +75 -0
- package/dist/scripts/python-codex-sdk-sandbox-policy-check.js +10 -0
- package/dist/scripts/python-codex-sdk-stream-bridge-check.js +12 -0
- package/dist/scripts/release-parallel-check.js +1 -1
- package/dist/scripts/release-real-check.js +5 -0
- package/dist/scripts/zellij-worker-pane-manager-check.js +1 -1
- package/package.json +38 -4
- package/schemas/local-llm/local-collaboration-policy.schema.json +57 -0
- package/schemas/local-llm/local-model-config.schema.json +74 -0
- package/schemas/naruto/naruto-concurrency-governor.schema.json +21 -0
- package/schemas/naruto/naruto-work-graph.schema.json +22 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
1
2
|
import path from 'node:path';
|
|
2
|
-
import { appendJsonl, ensureDir, nowIso, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
import { appendJsonl, ensureDir, nowIso, packageRoot, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
3
4
|
import { validateJsonSchemaRecursive } from '../json-schema-validator.js';
|
|
4
5
|
import { resolveCodexOutputSchema } from './codex-output-schemas.js';
|
|
5
6
|
import { detectCodexSdkCapability } from './codex-sdk-capability.js';
|
|
@@ -12,6 +13,9 @@ import { recordCodexThread } from './codex-thread-registry.js';
|
|
|
12
13
|
import { runWithCodexReliabilityShield } from './codex-reliability-shield.js';
|
|
13
14
|
import { routeCodexTask } from '../router/ultra-router.js';
|
|
14
15
|
import { writeUltraRouterProof } from '../router/router-proof.js';
|
|
16
|
+
import { readLocalModelConfig } from '../agents/ollama-worker-config.js';
|
|
17
|
+
import { runLocalLlmTask } from '../local-llm/local-llm-control-adapter.js';
|
|
18
|
+
import { detectPythonCodexSdkCapability, runPythonCodexSdkTask } from './python-codex-sdk-adapter.js';
|
|
15
19
|
export async function runCodexTask(input) {
|
|
16
20
|
const root = path.resolve(input.mutationLedgerRoot);
|
|
17
21
|
await ensureDir(root);
|
|
@@ -19,13 +23,22 @@ export async function runCodexTask(input) {
|
|
|
19
23
|
const routerDecision = routeCodexTask(input);
|
|
20
24
|
const task = { ...input, tier: input.tier || routerDecision.tier, outputSchema: schema };
|
|
21
25
|
await writeUltraRouterProof(root, { task, decision: routerDecision });
|
|
26
|
+
const selectedBackend = selectCodexControlBackend(task, routerDecision);
|
|
27
|
+
if (selectedBackend === 'local-llm')
|
|
28
|
+
return runLocalControlTask(root, task, schema, routerDecision);
|
|
29
|
+
if (selectedBackend === 'python-codex-sdk')
|
|
30
|
+
return runPythonControlTask(root, task, schema, routerDecision);
|
|
22
31
|
const capability = await detectCodexSdkCapability();
|
|
23
32
|
const sandbox = mapCodexSdkSandboxPolicy(task);
|
|
24
33
|
const runtime = codexSdkRuntimePolicies(task);
|
|
34
|
+
const bundledCodex = resolveBundledCodexBinary();
|
|
35
|
+
if (bundledCodex && !runtime.env.env.SKS_PYTHON_CODEX_SDK_CODEX_BIN)
|
|
36
|
+
runtime.env.env.SKS_PYTHON_CODEX_SDK_CODEX_BIN = bundledCodex;
|
|
25
37
|
if (runtime.env.env.HOME)
|
|
26
38
|
await ensureDir(runtime.env.env.HOME);
|
|
27
39
|
if (runtime.env.env.CODEX_HOME)
|
|
28
40
|
await ensureDir(runtime.env.env.CODEX_HOME);
|
|
41
|
+
await ensurePythonCodexLbConfig(runtime.env.env, runtime.config);
|
|
29
42
|
const fakeAllowed = fakeCodexSdkAllowed();
|
|
30
43
|
const blockers = [
|
|
31
44
|
...(capability.ok || fakeAllowed ? [] : capability.blockers),
|
|
@@ -84,6 +97,7 @@ export async function runCodexTask(input) {
|
|
|
84
97
|
const result = {
|
|
85
98
|
ok: finalBlockers.length === 0,
|
|
86
99
|
backend: 'codex-sdk',
|
|
100
|
+
backend_family: fakeAllowed ? 'fake' : 'remote-gpt',
|
|
87
101
|
sdkThreadId: String(adapterResult?.sdkThreadId || ''),
|
|
88
102
|
sdkRunId: adapterResult?.sdkRunId ? String(adapterResult.sdkRunId) : null,
|
|
89
103
|
streamEventCount: events.length,
|
|
@@ -99,6 +113,8 @@ export async function runCodexTask(input) {
|
|
|
99
113
|
translatedEventCount: translatedEvents.length
|
|
100
114
|
};
|
|
101
115
|
await recordCodexThread(root, {
|
|
116
|
+
backend: result.backend,
|
|
117
|
+
backend_family: result.backend_family,
|
|
102
118
|
route: task.route,
|
|
103
119
|
mission_id: task.missionId,
|
|
104
120
|
work_item_id: task.workItemId || null,
|
|
@@ -126,7 +142,213 @@ export async function runCodexTask(input) {
|
|
|
126
142
|
});
|
|
127
143
|
return result;
|
|
128
144
|
}
|
|
129
|
-
function
|
|
145
|
+
async function runPythonControlTask(root, task, schema, routerDecision) {
|
|
146
|
+
const capability = await detectPythonCodexSdkCapability();
|
|
147
|
+
const runtime = codexSdkRuntimePolicies(task);
|
|
148
|
+
if (runtime.env.env.HOME)
|
|
149
|
+
await ensureDir(runtime.env.env.HOME);
|
|
150
|
+
if (runtime.env.env.CODEX_HOME)
|
|
151
|
+
await ensureDir(runtime.env.env.CODEX_HOME);
|
|
152
|
+
const fakeAllowed = process.env.SKS_PYTHON_CODEX_SDK_FAKE === '1';
|
|
153
|
+
const adapterResult = capability.ok || fakeAllowed
|
|
154
|
+
? await runPythonCodexSdkTask(task, { env: runtime.env.env, config: runtime.config })
|
|
155
|
+
: { ok: false, events: [], translatedEvents: [], finalResponse: '', threadId: '', turnId: '', blockers: capability.blockers, capability };
|
|
156
|
+
const events = Array.isArray(adapterResult.events) ? adapterResult.events : [];
|
|
157
|
+
const translatedEvents = Array.isArray(adapterResult.translatedEvents) ? adapterResult.translatedEvents : [];
|
|
158
|
+
for (const event of translatedEvents)
|
|
159
|
+
await appendJsonl(path.join(root, 'python-codex-sdk-events.jsonl'), event);
|
|
160
|
+
const structuredOutput = parseStructuredOutput(adapterResult.finalResponse || '');
|
|
161
|
+
const validation = structuredOutput ? validateJsonSchemaRecursive(structuredOutput, schema) : { ok: false, issues: ['structured_output_missing'] };
|
|
162
|
+
const finalBlockers = [
|
|
163
|
+
...(adapterResult.blockers || []),
|
|
164
|
+
...(events.length > 0 ? [] : ['python_codex_sdk_event_stream_missing']),
|
|
165
|
+
...(validation.ok ? [] : ['python_codex_sdk_structured_output_invalid', ...validation.issues.map((issue) => `schema:${issue}`)])
|
|
166
|
+
];
|
|
167
|
+
const workerResult = normalizeWorkerResult(structuredOutput, task, finalBlockers, validation.ok, 'python-codex-sdk');
|
|
168
|
+
const workerResultPath = path.join(root, 'python-codex-sdk-worker-result.json');
|
|
169
|
+
await writeJsonAtomic(workerResultPath, workerResult);
|
|
170
|
+
const patchEnvelopePath = Array.isArray(workerResult.patch_envelopes) && workerResult.patch_envelopes.length
|
|
171
|
+
? path.join(root, 'python-codex-sdk-patch-envelope.json')
|
|
172
|
+
: null;
|
|
173
|
+
if (patchEnvelopePath) {
|
|
174
|
+
await writeJsonAtomic(patchEnvelopePath, {
|
|
175
|
+
schema: 'sks.python-codex-sdk-patch-envelope.v1',
|
|
176
|
+
generated_at: nowIso(),
|
|
177
|
+
ok: true,
|
|
178
|
+
envelope_count: workerResult.patch_envelopes.length,
|
|
179
|
+
envelopes: workerResult.patch_envelopes
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const pythonSdkProofPath = path.join(root, 'python-codex-sdk-proof.json');
|
|
183
|
+
await writeJsonAtomic(pythonSdkProofPath, {
|
|
184
|
+
schema: 'sks.python-codex-sdk-proof.v1',
|
|
185
|
+
generated_at: nowIso(),
|
|
186
|
+
ok: finalBlockers.length === 0,
|
|
187
|
+
backend: 'python-codex-sdk',
|
|
188
|
+
backend_family: fakeAllowed ? 'fake' : 'python-sdk',
|
|
189
|
+
package_name: capability.package_name,
|
|
190
|
+
import_name: capability.import_name,
|
|
191
|
+
python_bin: capability.python_bin,
|
|
192
|
+
python_version: capability.python_version,
|
|
193
|
+
sandbox: task.sandboxPolicy,
|
|
194
|
+
thread_id: adapterResult.threadId || '',
|
|
195
|
+
turn_id: adapterResult.turnId || '',
|
|
196
|
+
stream_event_count: events.length,
|
|
197
|
+
structured_output_valid: validation.ok,
|
|
198
|
+
worker_result_path: workerResultPath,
|
|
199
|
+
blockers: finalBlockers
|
|
200
|
+
});
|
|
201
|
+
const result = {
|
|
202
|
+
ok: finalBlockers.length === 0,
|
|
203
|
+
backend: 'python-codex-sdk',
|
|
204
|
+
backend_family: fakeAllowed ? 'fake' : 'python-sdk',
|
|
205
|
+
sdkThreadId: String(adapterResult.threadId || ''),
|
|
206
|
+
sdkRunId: adapterResult.turnId ? String(adapterResult.turnId) : null,
|
|
207
|
+
streamEventCount: events.length,
|
|
208
|
+
structuredOutputValid: validation.ok,
|
|
209
|
+
workerResultPath,
|
|
210
|
+
patchEnvelopePath,
|
|
211
|
+
pythonSdkProofPath,
|
|
212
|
+
blockers: finalBlockers,
|
|
213
|
+
reliabilityShield: {},
|
|
214
|
+
ultraRouterDecision: routerDecision,
|
|
215
|
+
outputSchemaId: task.outputSchemaId,
|
|
216
|
+
finalResponse: adapterResult.finalResponse || '',
|
|
217
|
+
eventTypes: events.map((event) => String(event?.event || event?.type || 'unknown')),
|
|
218
|
+
translatedEventCount: translatedEvents.length
|
|
219
|
+
};
|
|
220
|
+
await recordCodexThread(root, {
|
|
221
|
+
backend: result.backend,
|
|
222
|
+
backend_family: result.backend_family,
|
|
223
|
+
route: task.route,
|
|
224
|
+
mission_id: task.missionId,
|
|
225
|
+
work_item_id: task.workItemId || null,
|
|
226
|
+
slot_id: task.slotId || null,
|
|
227
|
+
generation_index: task.generationIndex ?? null,
|
|
228
|
+
session_id: task.sessionId || null,
|
|
229
|
+
zellij_pane_id: task.zellijPaneId || null,
|
|
230
|
+
sdk_thread_id: result.sdkThreadId,
|
|
231
|
+
sdk_run_id: result.sdkRunId,
|
|
232
|
+
stream_event_count: result.streamEventCount,
|
|
233
|
+
output_schema_id: task.outputSchemaId,
|
|
234
|
+
structured_output_valid: result.structuredOutputValid,
|
|
235
|
+
worker_result_path: result.workerResultPath
|
|
236
|
+
});
|
|
237
|
+
await writeCodexControlProof(root, {
|
|
238
|
+
task,
|
|
239
|
+
result,
|
|
240
|
+
capability: capability,
|
|
241
|
+
sandbox: { ok: true, sandbox_policy: task.sandboxPolicy, python_sandbox: mapPythonSandbox(task.sandboxPolicy), blockers: [] },
|
|
242
|
+
envProof: { ...runtime.env.proof, python_bin: capability.python_bin, python_version: capability.python_version },
|
|
243
|
+
config: { ...runtime.config, backend: 'python-codex-sdk', package_name: capability.package_name, import_name: capability.import_name },
|
|
244
|
+
reliabilityShield: null,
|
|
245
|
+
routerDecision: routerDecision,
|
|
246
|
+
translatedEvents
|
|
247
|
+
});
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
async function runLocalControlTask(root, task, schema, routerDecision) {
|
|
251
|
+
const config = await readLocalModelConfig();
|
|
252
|
+
const adapterResult = await runLocalLlmTask(task, { config, outputSchema: schema });
|
|
253
|
+
for (const event of adapterResult.events || [])
|
|
254
|
+
await appendJsonl(path.join(root, 'local-llm-events.jsonl'), event);
|
|
255
|
+
const structuredOutput = adapterResult.structuredOutput;
|
|
256
|
+
const validation = structuredOutput ? validateJsonSchemaRecursive(structuredOutput, schema) : { ok: false, issues: ['structured_output_missing'] };
|
|
257
|
+
const finalBlockers = [
|
|
258
|
+
...(adapterResult.blockers || []),
|
|
259
|
+
...(Array.isArray(adapterResult.events) && adapterResult.events.length > 0 ? [] : ['local_llm_event_stream_missing']),
|
|
260
|
+
...(validation.ok ? [] : ['local_llm_structured_output_invalid', ...validation.issues.map((issue) => `schema:${issue}`)])
|
|
261
|
+
];
|
|
262
|
+
const workerResult = normalizeWorkerResult(structuredOutput, task, finalBlockers, validation.ok, 'local-llm');
|
|
263
|
+
const workerResultPath = path.join(root, 'local-llm-worker-result.json');
|
|
264
|
+
await writeJsonAtomic(workerResultPath, workerResult);
|
|
265
|
+
const patchEnvelopePath = Array.isArray(workerResult.patch_envelopes) && workerResult.patch_envelopes.length
|
|
266
|
+
? path.join(root, 'local-llm-patch-envelope.json')
|
|
267
|
+
: null;
|
|
268
|
+
if (patchEnvelopePath) {
|
|
269
|
+
await writeJsonAtomic(patchEnvelopePath, {
|
|
270
|
+
schema: 'sks.local-llm-patch-envelope.v1',
|
|
271
|
+
generated_at: nowIso(),
|
|
272
|
+
ok: true,
|
|
273
|
+
envelope_count: workerResult.patch_envelopes.length,
|
|
274
|
+
envelopes: workerResult.patch_envelopes,
|
|
275
|
+
requires_gpt_final: true
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
const localLlmProofPath = path.join(root, 'local-llm-proof.json');
|
|
279
|
+
await writeJsonAtomic(localLlmProofPath, adapterResult.proof);
|
|
280
|
+
const result = {
|
|
281
|
+
ok: finalBlockers.length === 0,
|
|
282
|
+
backend: 'local-llm',
|
|
283
|
+
backend_family: 'local-llm',
|
|
284
|
+
sdkThreadId: '',
|
|
285
|
+
sdkRunId: null,
|
|
286
|
+
streamEventCount: adapterResult.events?.length || 0,
|
|
287
|
+
structuredOutputValid: validation.ok,
|
|
288
|
+
workerResultPath,
|
|
289
|
+
patchEnvelopePath,
|
|
290
|
+
localLlmProofPath,
|
|
291
|
+
blockers: finalBlockers,
|
|
292
|
+
reliabilityShield: {},
|
|
293
|
+
ultraRouterDecision: routerDecision,
|
|
294
|
+
outputSchemaId: task.outputSchemaId,
|
|
295
|
+
finalResponse: adapterResult.finalResponse || '',
|
|
296
|
+
eventTypes: (adapterResult.events || []).map((event) => String(event?.type || 'unknown')),
|
|
297
|
+
translatedEventCount: adapterResult.events?.length || 0,
|
|
298
|
+
localLlmRequestId: adapterResult.requestId
|
|
299
|
+
};
|
|
300
|
+
await recordCodexThread(root, {
|
|
301
|
+
backend: result.backend,
|
|
302
|
+
backend_family: result.backend_family,
|
|
303
|
+
route: task.route,
|
|
304
|
+
mission_id: task.missionId,
|
|
305
|
+
work_item_id: task.workItemId || null,
|
|
306
|
+
slot_id: task.slotId || null,
|
|
307
|
+
generation_index: task.generationIndex ?? null,
|
|
308
|
+
session_id: task.sessionId || null,
|
|
309
|
+
zellij_pane_id: task.zellijPaneId || null,
|
|
310
|
+
sdk_thread_id: null,
|
|
311
|
+
sdk_run_id: null,
|
|
312
|
+
local_llm_request_id: adapterResult.requestId,
|
|
313
|
+
stream_event_count: result.streamEventCount,
|
|
314
|
+
output_schema_id: task.outputSchemaId,
|
|
315
|
+
structured_output_valid: result.structuredOutputValid,
|
|
316
|
+
worker_result_path: result.workerResultPath
|
|
317
|
+
});
|
|
318
|
+
await writeCodexControlProof(root, {
|
|
319
|
+
task,
|
|
320
|
+
result,
|
|
321
|
+
capability: config.capability,
|
|
322
|
+
sandbox: { ok: task.sandboxPolicy !== 'full-access', sandbox_policy: task.sandboxPolicy, blockers: task.sandboxPolicy === 'full-access' ? ['local_llm_full_access_blocked'] : [] },
|
|
323
|
+
envProof: { provider: config.provider, endpoint: config.base_url },
|
|
324
|
+
config: { provider: config.provider, model: config.model, endpoint: config.base_url, status: config.status },
|
|
325
|
+
reliabilityShield: null,
|
|
326
|
+
routerDecision: routerDecision,
|
|
327
|
+
translatedEvents: adapterResult.events || []
|
|
328
|
+
});
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
function selectCodexControlBackend(input, routerDecision) {
|
|
332
|
+
const prefs = Array.isArray(input.backendPreference) ? input.backendPreference : [];
|
|
333
|
+
for (const pref of prefs) {
|
|
334
|
+
if (pref === 'python-codex-sdk')
|
|
335
|
+
return 'python-codex-sdk';
|
|
336
|
+
if (pref === 'codex-sdk')
|
|
337
|
+
return 'codex-sdk';
|
|
338
|
+
if (pref === 'local-llm' && input.tier === 'worker')
|
|
339
|
+
return 'local-llm';
|
|
340
|
+
}
|
|
341
|
+
if (input.localLlmPolicy?.mode === 'disabled')
|
|
342
|
+
return 'codex-sdk';
|
|
343
|
+
if (input.allowLocalLlm === true && input.tier === 'worker' && routerDecision?.selected_profile === 'local-llm-worker')
|
|
344
|
+
return 'local-llm';
|
|
345
|
+
if (input.allowLocalLlm === true && input.tier === 'worker' && input.localLlmPolicy?.mode === 'local_only')
|
|
346
|
+
return 'local-llm';
|
|
347
|
+
if (input.allowLocalLlm === true && input.tier === 'worker' && input.localLlmPolicy?.mode === 'local_preferred')
|
|
348
|
+
return 'local-llm';
|
|
349
|
+
return 'codex-sdk';
|
|
350
|
+
}
|
|
351
|
+
function normalizeWorkerResult(value, input, blockers, structuredOutputValid, backend = 'codex-sdk') {
|
|
130
352
|
const status = blockers.length ? 'blocked' : normalizeStatus(value?.status);
|
|
131
353
|
return {
|
|
132
354
|
...value,
|
|
@@ -135,9 +357,9 @@ function normalizeWorkerResult(value, input, blockers, structuredOutputValid) {
|
|
|
135
357
|
session_id: String(value?.session_id || input.sessionId || input.workItemId || 'codex-sdk-session'),
|
|
136
358
|
persona_id: String(value?.persona_id || value?.agent_id || input.slotId || 'codex-sdk-worker'),
|
|
137
359
|
task_slice_id: String(value?.task_slice_id || input.workItemId || ''),
|
|
138
|
-
backend
|
|
360
|
+
backend,
|
|
139
361
|
status,
|
|
140
|
-
summary: String(value?.summary || (blockers.length ?
|
|
362
|
+
summary: String(value?.summary || (blockers.length ? `${backend} task blocked.` : `${backend} task completed.`)),
|
|
141
363
|
findings: Array.isArray(value?.findings) ? value.findings : [],
|
|
142
364
|
proposed_changes: Array.isArray(value?.proposed_changes) ? value.proposed_changes : [],
|
|
143
365
|
changed_files: Array.isArray(value?.changed_files) ? value.changed_files : [],
|
|
@@ -145,7 +367,7 @@ function normalizeWorkerResult(value, input, blockers, structuredOutputValid) {
|
|
|
145
367
|
artifacts: Array.isArray(value?.artifacts) ? value.artifacts : [],
|
|
146
368
|
blockers,
|
|
147
369
|
confidence: String(value?.confidence || (structuredOutputValid ? 'verified_partial' : 'blocked')),
|
|
148
|
-
handoff_notes: String(value?.handoff_notes ||
|
|
370
|
+
handoff_notes: String(value?.handoff_notes || `${backend} Control Plane produced this worker result.`),
|
|
149
371
|
unverified: Array.isArray(value?.unverified) ? value.unverified : [],
|
|
150
372
|
writes: Array.isArray(value?.writes) ? value.writes : [],
|
|
151
373
|
patch_envelopes: Array.isArray(value?.patch_envelopes) ? value.patch_envelopes : [],
|
|
@@ -157,4 +379,106 @@ function normalizeWorkerResult(value, input, blockers, structuredOutputValid) {
|
|
|
157
379
|
function normalizeStatus(value) {
|
|
158
380
|
return value === 'failed' || value === 'blocked' || value === 'done' ? value : 'done';
|
|
159
381
|
}
|
|
382
|
+
function mapPythonSandbox(value) {
|
|
383
|
+
if (value === 'workspace-write')
|
|
384
|
+
return 'workspace_write';
|
|
385
|
+
if (value === 'full-access')
|
|
386
|
+
return 'full_access';
|
|
387
|
+
return 'read_only';
|
|
388
|
+
}
|
|
389
|
+
function parseStructuredOutput(text) {
|
|
390
|
+
const trimmed = String(text || '').trim();
|
|
391
|
+
if (!trimmed)
|
|
392
|
+
return null;
|
|
393
|
+
try {
|
|
394
|
+
return JSON.parse(trimmed);
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
const start = trimmed.indexOf('{');
|
|
398
|
+
const end = trimmed.lastIndexOf('}');
|
|
399
|
+
if (start >= 0 && end > start) {
|
|
400
|
+
try {
|
|
401
|
+
return JSON.parse(trimmed.slice(start, end + 1));
|
|
402
|
+
}
|
|
403
|
+
catch { }
|
|
404
|
+
}
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
async function ensurePythonCodexLbConfig(env, config) {
|
|
409
|
+
const codexHome = env.CODEX_HOME;
|
|
410
|
+
const lbBaseUrl = normalizeCodexLbBaseUrl(env.CODEX_LB_BASE_URL);
|
|
411
|
+
if (!codexHome || !lbBaseUrl || !env.CODEX_LB_API_KEY)
|
|
412
|
+
return;
|
|
413
|
+
const model = String(config.model || env.SKS_CODEX_MODEL || env.CODEX_MODEL || 'gpt-5.5');
|
|
414
|
+
const text = [
|
|
415
|
+
`model = ${tomlQuote(model)}`,
|
|
416
|
+
'model_provider = "codex-lb"',
|
|
417
|
+
'service_tier = "fast"',
|
|
418
|
+
'model_reasoning_effort = "minimal"',
|
|
419
|
+
'approval_policy = "never"',
|
|
420
|
+
'',
|
|
421
|
+
'[model_providers.codex-lb]',
|
|
422
|
+
'name = "OpenAI"',
|
|
423
|
+
`base_url = ${tomlQuote(lbBaseUrl)}`,
|
|
424
|
+
'wire_api = "responses"',
|
|
425
|
+
'env_key = "CODEX_LB_API_KEY"',
|
|
426
|
+
'supports_websockets = true',
|
|
427
|
+
'requires_openai_auth = false',
|
|
428
|
+
''
|
|
429
|
+
].join('\n');
|
|
430
|
+
await writeTextAtomic(path.join(codexHome, 'config.toml'), text);
|
|
431
|
+
}
|
|
432
|
+
function normalizeCodexLbBaseUrl(value) {
|
|
433
|
+
let host = String(value || '').trim();
|
|
434
|
+
if (!host)
|
|
435
|
+
return '';
|
|
436
|
+
if (!/^[a-z][a-z0-9+.-]*:\/\//i.test(host))
|
|
437
|
+
host = `https://${host}`;
|
|
438
|
+
host = host.replace(/\/+$/, '');
|
|
439
|
+
return /\/backend-api\/codex$/i.test(host) ? host : `${host}/backend-api/codex`;
|
|
440
|
+
}
|
|
441
|
+
function tomlQuote(value) {
|
|
442
|
+
return JSON.stringify(value);
|
|
443
|
+
}
|
|
444
|
+
function resolveBundledCodexBinary() {
|
|
445
|
+
const platform = process.platform;
|
|
446
|
+
const arch = process.arch;
|
|
447
|
+
const pkg = platform === 'darwin' && arch === 'arm64'
|
|
448
|
+
? '@openai/codex-darwin-arm64'
|
|
449
|
+
: platform === 'darwin' && arch === 'x64'
|
|
450
|
+
? '@openai/codex-darwin-x64'
|
|
451
|
+
: platform === 'linux' && arch === 'arm64'
|
|
452
|
+
? '@openai/codex-linux-arm64'
|
|
453
|
+
: platform === 'linux' && arch === 'x64'
|
|
454
|
+
? '@openai/codex-linux-x64'
|
|
455
|
+
: platform === 'win32' && arch === 'x64'
|
|
456
|
+
? '@openai/codex-win32-x64'
|
|
457
|
+
: platform === 'win32' && arch === 'arm64'
|
|
458
|
+
? '@openai/codex-win32-arm64'
|
|
459
|
+
: '';
|
|
460
|
+
if (!pkg)
|
|
461
|
+
return '';
|
|
462
|
+
const binary = platform === 'win32' ? 'codex.exe' : 'codex';
|
|
463
|
+
const candidates = [
|
|
464
|
+
path.join(packageRoot(), 'node_modules', pkg, 'vendor', nativeTargetTriple(platform, arch), 'bin', binary),
|
|
465
|
+
path.join(packageRoot(), 'node_modules', pkg, 'vendor', nativeTargetTriple(platform, arch), 'codex', binary)
|
|
466
|
+
];
|
|
467
|
+
return candidates.find((candidate) => fs.existsSync(candidate)) || '';
|
|
468
|
+
}
|
|
469
|
+
function nativeTargetTriple(platform, arch) {
|
|
470
|
+
if (platform === 'darwin' && arch === 'arm64')
|
|
471
|
+
return 'aarch64-apple-darwin';
|
|
472
|
+
if (platform === 'darwin' && arch === 'x64')
|
|
473
|
+
return 'x86_64-apple-darwin';
|
|
474
|
+
if (platform === 'linux' && arch === 'arm64')
|
|
475
|
+
return 'aarch64-unknown-linux-musl';
|
|
476
|
+
if (platform === 'linux' && arch === 'x64')
|
|
477
|
+
return 'x86_64-unknown-linux-musl';
|
|
478
|
+
if (platform === 'win32' && arch === 'arm64')
|
|
479
|
+
return 'aarch64-pc-windows-msvc';
|
|
480
|
+
if (platform === 'win32' && arch === 'x64')
|
|
481
|
+
return 'x86_64-pc-windows-msvc';
|
|
482
|
+
return '';
|
|
483
|
+
}
|
|
160
484
|
//# sourceMappingURL=codex-task-runner.js.map
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { nowIso, readJson, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
import { validateJsonSchemaRecursive } from '../json-schema-validator.js';
|
|
4
|
+
import { evaluateLocalCollaborationFinalGate, resolveLocalCollaborationPolicy } from '../local-llm/local-collaboration-policy.js';
|
|
5
|
+
import { runCodexTask } from './codex-control-plane.js';
|
|
6
|
+
import { GPT_FINAL_ARBITER_INPUT_SCHEMA, GPT_FINAL_ARBITER_RESULT_SCHEMA_ID, gptFinalArbiterResultSchema, normalizeGptFinalArbiterResult } from './gpt-final-review-schema.js';
|
|
7
|
+
import { compressGptFinalContext } from './gpt-final-context-compressor.js';
|
|
8
|
+
export const GPT_FINAL_ARBITER_RUN_SCHEMA = 'sks.gpt-final-arbiter-run.v1';
|
|
9
|
+
export async function runGptFinalArbiter(input, opts = {}) {
|
|
10
|
+
const started = Date.now();
|
|
11
|
+
const cwd = path.resolve(opts.cwd || process.cwd());
|
|
12
|
+
const root = path.resolve(opts.mutationLedgerRoot || path.join(cwd, '.sneakoscope', 'tmp', 'gpt-final-arbiter', safeName(input.mission_id || 'mission')));
|
|
13
|
+
const policy = resolveLocalCollaborationPolicy({ mode: input.local_mode });
|
|
14
|
+
const compressed = compressGptFinalContext(input);
|
|
15
|
+
if (policy.local_only_draft) {
|
|
16
|
+
return finalize(root, input, policy, compressed, blockedResult('needs_gpt_final_review', 'Local-only draft mode cannot produce final accepted proof.'), started, opts);
|
|
17
|
+
}
|
|
18
|
+
if (opts.forceUnavailable || process.env.SKS_GPT_FINAL_ARBITER_UNAVAILABLE === '1') {
|
|
19
|
+
return finalize(root, input, policy, compressed, blockedResult('gpt_final_arbiter_unavailable', 'GPT final arbiter backend is unavailable.'), started, opts);
|
|
20
|
+
}
|
|
21
|
+
let codexTask = null;
|
|
22
|
+
let parsed = null;
|
|
23
|
+
try {
|
|
24
|
+
codexTask = await runCodexTask({
|
|
25
|
+
route: String(input.route || '$Pipeline'),
|
|
26
|
+
tier: 'orchestrator',
|
|
27
|
+
missionId: String(input.mission_id || ''),
|
|
28
|
+
workItemId: 'gpt-final-arbiter',
|
|
29
|
+
slotId: 'gpt-final-arbiter',
|
|
30
|
+
generationIndex: 1,
|
|
31
|
+
sessionId: `gpt-final-${safeName(input.mission_id || 'mission')}`,
|
|
32
|
+
cwd,
|
|
33
|
+
prompt: buildArbiterPrompt(input, compressed),
|
|
34
|
+
inputFiles: [],
|
|
35
|
+
inputImages: [],
|
|
36
|
+
outputSchemaId: GPT_FINAL_ARBITER_RESULT_SCHEMA_ID,
|
|
37
|
+
outputSchema: gptFinalArbiterResultSchema,
|
|
38
|
+
sandboxPolicy: 'read-only',
|
|
39
|
+
requestedScopeContract: {
|
|
40
|
+
id: `gpt-final:${input.mission_id || 'mission'}`,
|
|
41
|
+
route: String(input.route || '$Pipeline'),
|
|
42
|
+
read_only: true,
|
|
43
|
+
allowed_paths: [],
|
|
44
|
+
write_paths: [],
|
|
45
|
+
user_confirmed_full_access: false,
|
|
46
|
+
mad_sks_authorized: process.env.SKS_MAD_SKS_ACTIVE === '1'
|
|
47
|
+
},
|
|
48
|
+
mutationLedgerRoot: root,
|
|
49
|
+
reliabilityPolicy: {
|
|
50
|
+
maxEmptyResultRetries: 1,
|
|
51
|
+
timeoutClass: 'standard'
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
parsed = parseFinalResponse(codexTask.finalResponse);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return finalize(root, input, policy, compressed, blockedResult('gpt_final_arbiter_unavailable', error instanceof Error ? error.message : String(error)), started, opts);
|
|
58
|
+
}
|
|
59
|
+
const normalized = normalizeGptFinalArbiterResult(parsed);
|
|
60
|
+
const validation = validateJsonSchemaRecursive(normalized, gptFinalArbiterResultSchema);
|
|
61
|
+
const taskBlockers = Array.isArray(codexTask?.blockers) ? codexTask.blockers.map(String) : [];
|
|
62
|
+
const result = {
|
|
63
|
+
...normalized,
|
|
64
|
+
blockers: [
|
|
65
|
+
...normalized.blockers,
|
|
66
|
+
...(codexTask?.ok === true ? [] : ['gpt_final_arbiter_unavailable']),
|
|
67
|
+
...taskBlockers,
|
|
68
|
+
...(validation.ok ? [] : ['gpt_final_result_schema_invalid', ...validation.issues.map((issue) => `schema:${issue}`)])
|
|
69
|
+
]
|
|
70
|
+
};
|
|
71
|
+
return finalize(root, input, policy, compressed, result, started, opts, codexTask);
|
|
72
|
+
}
|
|
73
|
+
function finalize(root, input, policy, compressed, result, started, opts, codexTask) {
|
|
74
|
+
const latencyMs = Math.max(0, Date.now() - started);
|
|
75
|
+
const gate = evaluateLocalCollaborationFinalGate({
|
|
76
|
+
policy,
|
|
77
|
+
localParticipated: true,
|
|
78
|
+
gptFinalStatus: result.status,
|
|
79
|
+
gptFinalAvailable: !result.blockers.includes('gpt_final_arbiter_unavailable'),
|
|
80
|
+
gptFinalBackend: codexTask ? 'codex-sdk' : null,
|
|
81
|
+
applyPatches: false
|
|
82
|
+
});
|
|
83
|
+
const artifact = {
|
|
84
|
+
schema: GPT_FINAL_ARBITER_RUN_SCHEMA,
|
|
85
|
+
generated_at: nowIso(),
|
|
86
|
+
ok: gate.ok && result.blockers.length === 0,
|
|
87
|
+
input_schema: input.schema || GPT_FINAL_ARBITER_INPUT_SCHEMA,
|
|
88
|
+
route: input.route,
|
|
89
|
+
mission_id: input.mission_id,
|
|
90
|
+
local_mode: policy.mode,
|
|
91
|
+
backend: codexTask ? 'codex-sdk' : 'unavailable',
|
|
92
|
+
backend_family: codexTask ? 'remote-gpt' : 'none',
|
|
93
|
+
local_outputs_count: Array.isArray(input.local_outputs) ? input.local_outputs.length : 0,
|
|
94
|
+
proof_pack: compressed.proof_pack,
|
|
95
|
+
latency_budget: {
|
|
96
|
+
...compressed.latency_budget,
|
|
97
|
+
latency_ms: latencyMs
|
|
98
|
+
},
|
|
99
|
+
result,
|
|
100
|
+
final_gate: gate,
|
|
101
|
+
codex_task: codexTask ? {
|
|
102
|
+
ok: codexTask.ok === true,
|
|
103
|
+
sdk_thread_id: codexTask.sdkThreadId || null,
|
|
104
|
+
sdk_run_id: codexTask.sdkRunId || null,
|
|
105
|
+
stream_event_count: codexTask.streamEventCount || 0,
|
|
106
|
+
structured_output_valid: codexTask.structuredOutputValid === true,
|
|
107
|
+
worker_result_path: codexTask.workerResultPath || null,
|
|
108
|
+
blockers: codexTask.blockers || []
|
|
109
|
+
} : null,
|
|
110
|
+
blockers: [
|
|
111
|
+
...result.blockers,
|
|
112
|
+
...gate.blockers,
|
|
113
|
+
...compressed.blockers
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
artifact.ok = artifact.blockers.length === 0 && (result.status === 'approved' || result.status === 'modified');
|
|
117
|
+
if (opts.writeArtifact !== false)
|
|
118
|
+
return writeArtifact(root, artifact);
|
|
119
|
+
return artifact;
|
|
120
|
+
}
|
|
121
|
+
async function writeArtifact(root, artifact) {
|
|
122
|
+
await writeJsonAtomic(path.join(root, 'gpt-final-arbiter.json'), artifact);
|
|
123
|
+
return artifact;
|
|
124
|
+
}
|
|
125
|
+
function blockedResult(blocker, summary) {
|
|
126
|
+
return normalizeGptFinalArbiterResult({
|
|
127
|
+
status: 'needs_more_work',
|
|
128
|
+
summary,
|
|
129
|
+
blockers: [blocker],
|
|
130
|
+
confidence: 'low',
|
|
131
|
+
required_followup_work: [{ blocker }]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function parseFinalResponse(value) {
|
|
135
|
+
if (typeof value !== 'string')
|
|
136
|
+
return value || {};
|
|
137
|
+
try {
|
|
138
|
+
return JSON.parse(value);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return {};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function buildArbiterPrompt(input, compressed) {
|
|
145
|
+
return [
|
|
146
|
+
'You are the GPT Final Arbiter for an SKS local collaboration run.',
|
|
147
|
+
'Local model outputs are drafts only. Review the proof pack, candidate diff, patch envelopes, verification results, side effects, mutation ledger, and rollback plan.',
|
|
148
|
+
'Approve or modify only when the candidate is safe and supported. Reject unsafe local patches. Return only the requested structured JSON schema.',
|
|
149
|
+
JSON.stringify({
|
|
150
|
+
route: input.route,
|
|
151
|
+
mission_id: input.mission_id,
|
|
152
|
+
local_mode: input.local_mode,
|
|
153
|
+
proof_pack: compressed.proof_pack
|
|
154
|
+
})
|
|
155
|
+
].join('\n');
|
|
156
|
+
}
|
|
157
|
+
function safeName(value) {
|
|
158
|
+
return String(value || 'unknown').replace(/[^a-zA-Z0-9_.-]+/g, '-').slice(0, 80);
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=gpt-final-arbiter.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { buildGptFinalLatencyBudgetReport, buildGptFinalProofPack } from './gpt-final-proof-pack.js';
|
|
2
|
+
export function compressGptFinalContext(input, opts = {}) {
|
|
3
|
+
const proofPack = buildGptFinalProofPack(input, opts);
|
|
4
|
+
const latencyBudget = buildGptFinalLatencyBudgetReport({
|
|
5
|
+
workerCount: proofPack.worker_count,
|
|
6
|
+
tokenBudgetEstimate: proofPack.token_budget_estimate,
|
|
7
|
+
latencyMs: opts.latencyMs ?? null
|
|
8
|
+
});
|
|
9
|
+
return {
|
|
10
|
+
schema: 'sks.gpt-final-context-compressor.v1',
|
|
11
|
+
ok: latencyBudget.ok,
|
|
12
|
+
proof_pack: proofPack,
|
|
13
|
+
latency_budget: latencyBudget,
|
|
14
|
+
blockers: latencyBudget.ok ? [] : ['gpt_final_context_budget_exceeded']
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=gpt-final-context-compressor.js.map
|