sneakoscope 2.0.4 → 2.0.6
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 +18 -11
- 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 +78 -8
- package/dist/cli/install-helpers.js +23 -0
- package/dist/commands/codex-app.js +25 -3
- package/dist/commands/doctor.js +33 -4
- package/dist/commands/mad-sks.js +2 -2
- package/dist/core/agents/agent-orchestrator.js +22 -3
- package/dist/core/agents/agent-proof-evidence.js +59 -2
- package/dist/core/agents/agent-roster.js +35 -6
- package/dist/core/agents/agent-schema.js +1 -1
- package/dist/core/agents/agent-worker-pipeline.js +9 -1
- package/dist/core/agents/native-worker-backend-router.js +50 -10
- 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-app.js +124 -2
- package/dist/core/codex-control/codex-control-proof.js +4 -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/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 +65 -19
- package/dist/core/commands/naruto-command.js +124 -8
- package/dist/core/commands/run-command.js +1 -1
- package/dist/core/doctor/doctor-readiness-matrix.js +21 -2
- package/dist/core/fsx.js +1 -1
- package/dist/core/hooks-runtime.js +2 -233
- package/dist/core/init.js +8 -8
- 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 +6 -1
- 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 +134 -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/finalize-pipeline-result.js +58 -0
- package/dist/core/pipeline/gpt-final-required.js +12 -0
- package/dist/core/pipeline-internals/runtime-core.js +1 -1
- package/dist/core/ppt.js +31 -8
- package/dist/core/product-design-app-server.js +410 -0
- package/dist/core/product-design-plugin.js +139 -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 +12 -12
- 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-thread-runtime-choice-check.js +10 -0
- package/dist/scripts/local-collab-all-pipelines-final-gpt-check.js +21 -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 +39 -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-readonly-routing-check.js +116 -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 +13 -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/product-design-auto-install-check.js +119 -0
- package/dist/scripts/product-design-plugin-routing-check.js +101 -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 +16 -2
- package/dist/scripts/release-provenance-check.js +21 -0
- package/dist/scripts/release-real-check.js +5 -0
- package/dist/scripts/zellij-worker-pane-manager-check.js +1 -1
- package/package.json +36 -4
- 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,197 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { packageRoot, runProcess, which } from '../fsx.js';
|
|
4
|
+
import { translatePythonCodexSdkEvents } from './python-codex-sdk-event-translator.js';
|
|
5
|
+
export async function detectPythonCodexSdkCapability() {
|
|
6
|
+
const python = await resolvePythonCodexSdkPython();
|
|
7
|
+
if (!python.path)
|
|
8
|
+
return capability(false, null, '', ['python_missing'], null, 'Install Python >= 3.10 and install the Codex Python SDK.');
|
|
9
|
+
const pyOk = parsePythonVersion(python.versionText) >= 3.10;
|
|
10
|
+
const probes = [];
|
|
11
|
+
let detected = null;
|
|
12
|
+
if (pyOk) {
|
|
13
|
+
for (const candidate of PYTHON_CODEX_SDK_CANDIDATES) {
|
|
14
|
+
const importProbe = await runProcess(python.path, ['-c', `import ${candidate.importName}; print("ok")`], { timeoutMs: 5000, maxOutputBytes: 4096 })
|
|
15
|
+
.catch((err) => ({ code: 1, stdout: '', stderr: err.message || String(err) }));
|
|
16
|
+
probes.push({
|
|
17
|
+
package_name: candidate.packageName,
|
|
18
|
+
import_name: candidate.importName,
|
|
19
|
+
ok: importProbe.code === 0,
|
|
20
|
+
stderr: String(importProbe.stderr || '').slice(-500)
|
|
21
|
+
});
|
|
22
|
+
if (importProbe.code === 0) {
|
|
23
|
+
detected = candidate;
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const blockers = [
|
|
29
|
+
...(pyOk ? [] : ['python_version_below_3_10']),
|
|
30
|
+
...(detected ? [] : ['python_codex_sdk_unavailable'])
|
|
31
|
+
];
|
|
32
|
+
return capability(blockers.length === 0, python.path, python.versionText, blockers, detected, blockers.length ? setupAction(python.path) : null, probes);
|
|
33
|
+
}
|
|
34
|
+
export async function runPythonCodexSdkTask(input, opts = {}) {
|
|
35
|
+
const cap = await detectPythonCodexSdkCapability();
|
|
36
|
+
if (!cap.ok && process.env.SKS_PYTHON_CODEX_SDK_FAKE !== '1') {
|
|
37
|
+
return { ok: false, events: [], translatedEvents: [], finalResponse: '', blockers: cap.blockers, capability: cap };
|
|
38
|
+
}
|
|
39
|
+
const python = opts.pythonBin || cap.python_bin || await which('python3') || 'python3';
|
|
40
|
+
const request = {
|
|
41
|
+
schema: 'sks.python-codex-sdk-request.v1',
|
|
42
|
+
route: input.route,
|
|
43
|
+
thread_policy: input.requestedScopeContract?.resume_thread_id ? 'resume' : 'new',
|
|
44
|
+
sandbox: mapSandbox(input.sandboxPolicy),
|
|
45
|
+
cwd: input.cwd,
|
|
46
|
+
model: typeof opts.config?.model === 'string' ? opts.config.model : '',
|
|
47
|
+
model_reasoning_effort: typeof opts.config?.model_reasoning_effort === 'string' ? opts.config.model_reasoning_effort : 'minimal',
|
|
48
|
+
prompt: input.prompt,
|
|
49
|
+
output_schema: input.outputSchema || {}
|
|
50
|
+
};
|
|
51
|
+
const events = await runPythonRunner(python, request, opts.env);
|
|
52
|
+
const translatedEvents = translatePythonCodexSdkEvents(events);
|
|
53
|
+
const last = [...events].reverse().find((event) => event?.event === 'turn_completed');
|
|
54
|
+
const errors = events.filter((event) => event?.event === 'error').map((event) => String(event.message || 'python_codex_sdk_error'));
|
|
55
|
+
return {
|
|
56
|
+
ok: errors.length === 0 && Boolean(last),
|
|
57
|
+
events,
|
|
58
|
+
translatedEvents,
|
|
59
|
+
finalResponse: String(last?.final_response || ''),
|
|
60
|
+
threadId: String(events.find((event) => event?.thread_id)?.thread_id || ''),
|
|
61
|
+
turnId: String(last?.turn_id || ''),
|
|
62
|
+
blockers: errors,
|
|
63
|
+
capability: cap
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function runPythonRunner(python, request, envOverride) {
|
|
67
|
+
const runner = path.join(packageRoot(), 'pytools', 'codex_sdk_runner.py');
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const child = spawn(python, [runner], {
|
|
70
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
71
|
+
env: envOverride ? { ...process.env, ...envOverride } : process.env,
|
|
72
|
+
detached: process.platform !== 'win32'
|
|
73
|
+
});
|
|
74
|
+
const events = [];
|
|
75
|
+
let stderr = '';
|
|
76
|
+
let timedOut = false;
|
|
77
|
+
const timeoutMs = Number(process.env.SKS_PYTHON_CODEX_SDK_TIMEOUT_MS || 120000);
|
|
78
|
+
const timer = setTimeout(() => {
|
|
79
|
+
timedOut = true;
|
|
80
|
+
events.push({ event: 'error', retryable: true, message: `python_codex_sdk_timeout:${timeoutMs}` });
|
|
81
|
+
terminatePythonRunner(child);
|
|
82
|
+
}, timeoutMs);
|
|
83
|
+
timer.unref?.();
|
|
84
|
+
child.stdout.setEncoding('utf8');
|
|
85
|
+
child.stderr.setEncoding('utf8');
|
|
86
|
+
child.stdout.on('data', (chunk) => {
|
|
87
|
+
for (const line of String(chunk).split(/\n/).filter(Boolean)) {
|
|
88
|
+
try {
|
|
89
|
+
events.push(JSON.parse(line));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
events.push({ event: 'error', retryable: false, message: `invalid_python_jsonl:${line.slice(0, 200)}` });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
child.stderr.on('data', (chunk) => { stderr += String(chunk); });
|
|
97
|
+
child.on('error', reject);
|
|
98
|
+
child.on('close', () => {
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
if (stderr.trim())
|
|
101
|
+
events.push({ event: 'stderr', message: stderr.slice(-1000) });
|
|
102
|
+
if (timedOut && !events.some((event) => String(event?.message || '').startsWith('python_codex_sdk_timeout:'))) {
|
|
103
|
+
events.push({ event: 'error', retryable: true, message: `python_codex_sdk_timeout:${timeoutMs}` });
|
|
104
|
+
}
|
|
105
|
+
resolve(events);
|
|
106
|
+
});
|
|
107
|
+
child.stdin.end(JSON.stringify(request));
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
function terminatePythonRunner(child) {
|
|
111
|
+
if (!child.pid)
|
|
112
|
+
return;
|
|
113
|
+
try {
|
|
114
|
+
if (process.platform !== 'win32')
|
|
115
|
+
process.kill(-child.pid, 'SIGTERM');
|
|
116
|
+
else
|
|
117
|
+
child.kill('SIGTERM');
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
try {
|
|
121
|
+
child.kill('SIGTERM');
|
|
122
|
+
}
|
|
123
|
+
catch { }
|
|
124
|
+
}
|
|
125
|
+
setTimeout(() => {
|
|
126
|
+
try {
|
|
127
|
+
if (process.platform !== 'win32')
|
|
128
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
129
|
+
else
|
|
130
|
+
child.kill('SIGKILL');
|
|
131
|
+
}
|
|
132
|
+
catch { }
|
|
133
|
+
}, 5000).unref?.();
|
|
134
|
+
}
|
|
135
|
+
function mapSandbox(value) {
|
|
136
|
+
if (value === 'workspace-write')
|
|
137
|
+
return 'workspace_write';
|
|
138
|
+
if (value === 'full-access')
|
|
139
|
+
return 'full_access';
|
|
140
|
+
return 'read_only';
|
|
141
|
+
}
|
|
142
|
+
function parsePythonVersion(text) {
|
|
143
|
+
const match = text.match(/Python\s+(\d+)\.(\d+)/i);
|
|
144
|
+
return match ? Number(`${match[1]}.${match[2]}`) : 0;
|
|
145
|
+
}
|
|
146
|
+
async function resolvePythonCodexSdkPython() {
|
|
147
|
+
const requested = [
|
|
148
|
+
process.env.SKS_PYTHON_CODEX_SDK_PYTHON,
|
|
149
|
+
process.env.PYTHON
|
|
150
|
+
].filter((value) => Boolean(value && value.trim()));
|
|
151
|
+
const candidates = [...requested, 'python3.12', 'python3.11', 'python3.10', 'python3', 'python'];
|
|
152
|
+
const seen = new Set();
|
|
153
|
+
const probes = [];
|
|
154
|
+
for (const candidate of candidates) {
|
|
155
|
+
const resolved = candidate.includes('/') ? candidate : await which(candidate);
|
|
156
|
+
if (!resolved || seen.has(resolved))
|
|
157
|
+
continue;
|
|
158
|
+
seen.add(resolved);
|
|
159
|
+
const version = await runProcess(resolved, ['--version'], { timeoutMs: 5000, maxOutputBytes: 4096 })
|
|
160
|
+
.catch((err) => ({ code: 1, stdout: '', stderr: err.message || String(err) }));
|
|
161
|
+
const versionText = `${version.stdout || ''}${version.stderr || ''}`.trim();
|
|
162
|
+
probes.push({ path: resolved, versionText, score: parsePythonVersion(versionText) });
|
|
163
|
+
}
|
|
164
|
+
const supported = probes.find((probe) => probe.score >= 3.10);
|
|
165
|
+
return supported || probes[0] || { path: null, versionText: '' };
|
|
166
|
+
}
|
|
167
|
+
const PYTHON_CODEX_SDK_CANDIDATES = [
|
|
168
|
+
{ packageName: 'codex-app-server', importName: 'codex_app_server', source: 'developers.openai.com/codex/sdk' },
|
|
169
|
+
{ packageName: 'openai-codex', importName: 'openai_codex', source: 'sks-2.0.5-directive' },
|
|
170
|
+
{ packageName: 'openai-codex-sdk', importName: 'openai_codex_sdk', source: 'pypi-wheel' }
|
|
171
|
+
];
|
|
172
|
+
function setupAction(pythonBin) {
|
|
173
|
+
return [
|
|
174
|
+
`Install the current Codex Python SDK in \`${pythonBin}\`.`,
|
|
175
|
+
'Preferred official source install: from the Codex repository root run `cd sdk/python && python -m pip install -e .`.',
|
|
176
|
+
`If using the published wrapper package, run \`${pythonBin} -m pip install openai-codex-sdk\`.`,
|
|
177
|
+
`If your environment provides the directive package, run \`${pythonBin} -m pip install openai-codex\`.`
|
|
178
|
+
].join(' ');
|
|
179
|
+
}
|
|
180
|
+
function capability(ok, pythonBin, versionText, blockers, detected, setupActionValue, probes = []) {
|
|
181
|
+
const selected = detected || PYTHON_CODEX_SDK_CANDIDATES[0] || { packageName: 'codex-app-server', importName: 'codex_app_server', source: 'developers.openai.com/codex/sdk' };
|
|
182
|
+
return {
|
|
183
|
+
schema: 'sks.python-codex-sdk-capability.v1',
|
|
184
|
+
ok,
|
|
185
|
+
python_bin: pythonBin,
|
|
186
|
+
python_version: versionText,
|
|
187
|
+
package_name: selected.packageName,
|
|
188
|
+
import_name: selected.importName,
|
|
189
|
+
source: selected.source,
|
|
190
|
+
supported_packages: PYTHON_CODEX_SDK_CANDIDATES.map((candidate) => candidate.packageName),
|
|
191
|
+
supported_imports: PYTHON_CODEX_SDK_CANDIDATES.map((candidate) => candidate.importName),
|
|
192
|
+
import_probes: probes,
|
|
193
|
+
setup_action: setupActionValue,
|
|
194
|
+
blockers
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=python-codex-sdk-adapter.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function translatePythonCodexSdkEvents(events = []) {
|
|
2
|
+
return events.map((event, index) => ({
|
|
3
|
+
schema: 'sks.python-codex-sdk-event.v1',
|
|
4
|
+
index,
|
|
5
|
+
event_type: String(event?.event || 'unknown'),
|
|
6
|
+
thread_id: event?.thread_id ? String(event.thread_id) : null,
|
|
7
|
+
turn_id: event?.turn_id ? String(event.turn_id) : null,
|
|
8
|
+
status: event?.status ? String(event.status) : null,
|
|
9
|
+
retryable: event?.retryable === true,
|
|
10
|
+
message: event?.message ? String(event.message) : null,
|
|
11
|
+
final_response: event?.final_response ? String(event.final_response) : null
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=python-codex-sdk-event-translator.js.map
|