@ycodium-ai/agent-codex 0.2.3488 → 0.2.3506
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +81 -116
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -2455,49 +2455,30 @@ async function spawnCodexAppServer(input) {
|
|
|
2455
2455
|
}
|
|
2456
2456
|
|
|
2457
2457
|
// src/cliVersion.ts
|
|
2458
|
+
import {
|
|
2459
|
+
runProcessOperation,
|
|
2460
|
+
isOperationCleanupError
|
|
2461
|
+
} from "@ycodium-ai/plugin-api/process-operation";
|
|
2458
2462
|
var CODEX_VERSION_TIMEOUT_MS = 15e3;
|
|
2459
2463
|
var VERSION_PATTERN = /(?<![\d.])(\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?)/;
|
|
2460
|
-
async function collect(stream) {
|
|
2461
|
-
const chunks = [];
|
|
2462
|
-
for await (const chunk of stream) {
|
|
2463
|
-
chunks.push(Buffer.from(chunk));
|
|
2464
|
-
if (Buffer.concat(chunks).length > 64 * 1024) break;
|
|
2465
|
-
}
|
|
2466
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
2467
|
-
}
|
|
2468
2464
|
async function readCodexCliVersion(input) {
|
|
2465
|
+
input.signal?.throwIfAborted();
|
|
2469
2466
|
if (input.recipe.binaryPath.length === 0) return null;
|
|
2470
|
-
let handle;
|
|
2471
2467
|
try {
|
|
2472
|
-
|
|
2468
|
+
const { stdout, stderr, exitCode } = await runProcessOperation(input.host, {
|
|
2473
2469
|
program: input.recipe.binaryPath,
|
|
2474
2470
|
args: ["--version"],
|
|
2475
|
-
owner: { bindingId: input.host.bindingId }
|
|
2471
|
+
owner: { bindingId: input.host.bindingId },
|
|
2472
|
+
signal: input.signal,
|
|
2473
|
+
timeoutMs: CODEX_VERSION_TIMEOUT_MS,
|
|
2474
|
+
maxOutputBytes: 64 * 1024
|
|
2476
2475
|
});
|
|
2477
|
-
} catch {
|
|
2478
|
-
return null;
|
|
2479
|
-
}
|
|
2480
|
-
const collected = Promise.all([collect(handle.stdout), collect(handle.stderr), handle.exited]);
|
|
2481
|
-
let timer;
|
|
2482
|
-
const timeout = new Promise((resolve4) => {
|
|
2483
|
-
timer = setTimeout(() => resolve4("timeout"), CODEX_VERSION_TIMEOUT_MS);
|
|
2484
|
-
timer.unref?.();
|
|
2485
|
-
});
|
|
2486
|
-
try {
|
|
2487
|
-
const settled = await Promise.race([collected, timeout]);
|
|
2488
|
-
if (settled === "timeout") {
|
|
2489
|
-
collected.catch(() => void 0);
|
|
2490
|
-
return null;
|
|
2491
|
-
}
|
|
2492
|
-
const [stdout, stderr, exitCode] = settled;
|
|
2493
2476
|
if (exitCode !== 0) return null;
|
|
2494
|
-
return VERSION_PATTERN.exec(
|
|
2495
|
-
|
|
2496
|
-
|
|
2477
|
+
return VERSION_PATTERN.exec(stdout + "\n" + stderr)?.[1] ?? null;
|
|
2478
|
+
} catch (error) {
|
|
2479
|
+
if (isOperationCleanupError(error)) throw error;
|
|
2480
|
+
input.signal?.throwIfAborted();
|
|
2497
2481
|
return null;
|
|
2498
|
-
} finally {
|
|
2499
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
2500
|
-
await handle.kill("SIGTERM").catch(() => void 0);
|
|
2501
2482
|
}
|
|
2502
2483
|
}
|
|
2503
2484
|
|
|
@@ -6392,6 +6373,10 @@ import * as NodePath9 from "node:path";
|
|
|
6392
6373
|
import {
|
|
6393
6374
|
mergeLaunchEnv as mergeLaunchEnv2
|
|
6394
6375
|
} from "@ycodium-ai/plugin-api/executor";
|
|
6376
|
+
import {
|
|
6377
|
+
OperationCleanupError,
|
|
6378
|
+
runProcessOperation as runProcessOperation2
|
|
6379
|
+
} from "@ycodium-ai/plugin-api/process-operation";
|
|
6395
6380
|
var CODEX_TIMEOUT_MS = 18e4;
|
|
6396
6381
|
var EARLIER_CONTENT_TRUNCATION_MARKER = "[Earlier content truncated]\n\n";
|
|
6397
6382
|
function limitSection(value, maxChars) {
|
|
@@ -6544,98 +6529,78 @@ function absoluteImagePaths(attachments) {
|
|
|
6544
6529
|
}
|
|
6545
6530
|
return paths;
|
|
6546
6531
|
}
|
|
6547
|
-
async function collectStream(stream) {
|
|
6548
|
-
const decoder = new TextDecoder();
|
|
6549
|
-
let out = "";
|
|
6550
|
-
for await (const chunk of stream) out += decoder.decode(chunk, { stream: true });
|
|
6551
|
-
return out;
|
|
6552
|
-
}
|
|
6553
6532
|
function createCodexTextGeneration(input) {
|
|
6554
6533
|
const run = async (operation, cwd, prompt, schema, modelSelection, imagePaths, signal) => {
|
|
6555
6534
|
if (input.recipe.binaryPath.length === 0) {
|
|
6556
6535
|
throw new Error("Codex CLI is required but not available on PATH.");
|
|
6557
6536
|
}
|
|
6537
|
+
signal?.throwIfAborted();
|
|
6558
6538
|
const tmp = await NodeFSP5.mkdtemp(NodePath9.join(NodeOS3.tmpdir(), "ycodium-codex-tg-"));
|
|
6559
|
-
|
|
6560
|
-
const outputPath = NodePath9.join(tmp, "output.json");
|
|
6561
|
-
await NodeFSP5.writeFile(schemaPath, JSON.stringify(schema));
|
|
6562
|
-
await NodeFSP5.writeFile(outputPath, "");
|
|
6563
|
-
const reasoningEffort = modelSelectionStringOption(modelSelection, "reasoningEffort") ?? DEFAULT_TEXT_GENERATION_REASONING_EFFORT;
|
|
6564
|
-
const serviceTier = modelSelectionStringOption(modelSelection, "serviceTier");
|
|
6565
|
-
const model = modelIdFromSelection(modelSelection) ?? "gpt-5.6-luna";
|
|
6566
|
-
const env = mergeLaunchEnv2({
|
|
6567
|
-
accountHome: input.layout.effectiveHomePath ? { CODEX_HOME: input.layout.effectiveHomePath } : input.recipe.homePath.trim() ? { CODEX_HOME: expandHomePath(input.recipe.homePath) } : {},
|
|
6568
|
-
instanceTable: input.recipe.environment
|
|
6569
|
-
});
|
|
6570
|
-
const args = [
|
|
6571
|
-
"exec",
|
|
6572
|
-
...codexExecLaunchArgs(input.recipe.launchArgs),
|
|
6573
|
-
"--ephemeral",
|
|
6574
|
-
"--skip-git-repo-check",
|
|
6575
|
-
"-s",
|
|
6576
|
-
"read-only",
|
|
6577
|
-
"--model",
|
|
6578
|
-
model,
|
|
6579
|
-
"--config",
|
|
6580
|
-
`model_reasoning_effort="${reasoningEffort}"`,
|
|
6581
|
-
...serviceTier ? ["--config", `service_tier="${serviceTier}"`] : [],
|
|
6582
|
-
"--output-schema",
|
|
6583
|
-
schemaPath,
|
|
6584
|
-
"--output-last-message",
|
|
6585
|
-
outputPath,
|
|
6586
|
-
...imagePaths.flatMap((imagePath) => ["--image", imagePath]),
|
|
6587
|
-
"-"
|
|
6588
|
-
];
|
|
6589
|
-
const handle = await input.host.process.spawn({
|
|
6590
|
-
program: input.recipe.binaryPath,
|
|
6591
|
-
args,
|
|
6592
|
-
cwd: operation === "summarizeTurn" ? tmp : cwd,
|
|
6593
|
-
env,
|
|
6594
|
-
owner: { bindingId: input.host.bindingId }
|
|
6595
|
-
});
|
|
6596
|
-
const onAbort = () => {
|
|
6597
|
-
void handle.kill("SIGTERM").catch(() => void 0);
|
|
6598
|
-
};
|
|
6599
|
-
signal?.addEventListener("abort", onAbort);
|
|
6600
|
-
let timer;
|
|
6539
|
+
let safeToRemove = true;
|
|
6601
6540
|
try {
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6541
|
+
const schemaPath = NodePath9.join(tmp, "schema.json");
|
|
6542
|
+
const outputPath = NodePath9.join(tmp, "output.json");
|
|
6543
|
+
await NodeFSP5.writeFile(schemaPath, JSON.stringify(schema));
|
|
6544
|
+
await NodeFSP5.writeFile(outputPath, "");
|
|
6545
|
+
const reasoningEffort = modelSelectionStringOption(modelSelection, "reasoningEffort") ?? DEFAULT_TEXT_GENERATION_REASONING_EFFORT;
|
|
6546
|
+
const serviceTier = modelSelectionStringOption(modelSelection, "serviceTier");
|
|
6547
|
+
const model = modelIdFromSelection(modelSelection) ?? "gpt-5.6-luna";
|
|
6548
|
+
const env = mergeLaunchEnv2({
|
|
6549
|
+
accountHome: input.layout.effectiveHomePath ? { CODEX_HOME: input.layout.effectiveHomePath } : input.recipe.homePath.trim() ? { CODEX_HOME: expandHomePath(input.recipe.homePath) } : {},
|
|
6550
|
+
instanceTable: input.recipe.environment
|
|
6551
|
+
});
|
|
6552
|
+
const args = [
|
|
6553
|
+
"exec",
|
|
6554
|
+
...codexExecLaunchArgs(input.recipe.launchArgs),
|
|
6555
|
+
"--ephemeral",
|
|
6556
|
+
"--skip-git-repo-check",
|
|
6557
|
+
"-s",
|
|
6558
|
+
"read-only",
|
|
6559
|
+
"--model",
|
|
6560
|
+
model,
|
|
6561
|
+
"--config",
|
|
6562
|
+
`model_reasoning_effort="${reasoningEffort}"`,
|
|
6563
|
+
...serviceTier ? ["--config", `service_tier="${serviceTier}"`] : [],
|
|
6564
|
+
"--output-schema",
|
|
6565
|
+
schemaPath,
|
|
6566
|
+
"--output-last-message",
|
|
6567
|
+
outputPath,
|
|
6568
|
+
...imagePaths.flatMap((imagePath) => ["--image", imagePath]),
|
|
6569
|
+
"-"
|
|
6570
|
+
];
|
|
6627
6571
|
try {
|
|
6628
|
-
|
|
6572
|
+
const { stdout, stderr, exitCode } = await runProcessOperation2(input.host, {
|
|
6573
|
+
program: input.recipe.binaryPath,
|
|
6574
|
+
args,
|
|
6575
|
+
cwd: operation === "summarizeTurn" ? tmp : cwd,
|
|
6576
|
+
env,
|
|
6577
|
+
owner: { bindingId: input.host.bindingId },
|
|
6578
|
+
signal,
|
|
6579
|
+
timeoutMs: CODEX_TIMEOUT_MS,
|
|
6580
|
+
input: prompt
|
|
6581
|
+
});
|
|
6582
|
+
if (exitCode !== 0) {
|
|
6583
|
+
const detail = stderr.trim() || stdout.trim();
|
|
6584
|
+
throw new Error(
|
|
6585
|
+
detail.length > 0 ? `Codex CLI command failed: ${detail}` : `Codex CLI command failed with code ${String(exitCode)}.`
|
|
6586
|
+
);
|
|
6587
|
+
}
|
|
6588
|
+
const raw = await NodeFSP5.readFile(outputPath, "utf8");
|
|
6589
|
+
let parsed;
|
|
6590
|
+
try {
|
|
6591
|
+
parsed = JSON.parse(raw);
|
|
6592
|
+
} catch (cause) {
|
|
6593
|
+
throw new Error("Codex returned invalid structured output.", { cause });
|
|
6594
|
+
}
|
|
6595
|
+
if (!isRecord2(parsed)) throw new Error("Codex returned invalid structured output.");
|
|
6596
|
+
return parsed;
|
|
6629
6597
|
} catch (cause) {
|
|
6630
|
-
|
|
6598
|
+
if (cause instanceof OperationCleanupError) safeToRemove = false;
|
|
6599
|
+
throw cause;
|
|
6631
6600
|
}
|
|
6632
|
-
if (!isRecord2(parsed)) throw new Error("Codex returned invalid structured output.");
|
|
6633
|
-
return parsed;
|
|
6634
6601
|
} finally {
|
|
6635
|
-
if (
|
|
6636
|
-
|
|
6637
|
-
await NodeFSP5.rm(tmp, { recursive: true, force: true }).catch(() => void 0);
|
|
6638
|
-
void operation;
|
|
6602
|
+
if (safeToRemove)
|
|
6603
|
+
await NodeFSP5.rm(tmp, { recursive: true, force: true }).catch(() => void 0);
|
|
6639
6604
|
}
|
|
6640
6605
|
};
|
|
6641
6606
|
return {
|
|
@@ -7637,7 +7602,7 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
7637
7602
|
...CODEX_NATIVE_MODE_REPORT
|
|
7638
7603
|
};
|
|
7639
7604
|
},
|
|
7640
|
-
readCliVersion: () => readCodexCliVersion({ recipe, host }),
|
|
7605
|
+
readCliVersion: (signal) => readCodexCliVersion({ recipe, host, ...signal ? { signal } : {} }),
|
|
7641
7606
|
// 有意不处理 input.readOnlyDirectories:codex 的沙箱只限制写入,读不受限,
|
|
7642
7607
|
// 附件目录本来就能读,无需放行。
|
|
7643
7608
|
startSession: async (input, signal) => {
|
|
@@ -7955,7 +7920,7 @@ var executors = [
|
|
|
7955
7920
|
];
|
|
7956
7921
|
var index_default = definePlugin({
|
|
7957
7922
|
id: "agent-codex",
|
|
7958
|
-
apiVersion:
|
|
7923
|
+
apiVersion: 42,
|
|
7959
7924
|
executors,
|
|
7960
7925
|
activate(ctx) {
|
|
7961
7926
|
capturedAttachments = ctx.attachments;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/agent-codex",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3506",
|
|
4
4
|
"description": "Codex executor: Codex CLI over the app-server JSON-RPC protocol.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"tailwindcss": "^4.0.0",
|
|
30
30
|
"typescript": "~6.0.3",
|
|
31
31
|
"vite-plus": "0.2.2",
|
|
32
|
-
"
|
|
33
|
-
"ycodium-
|
|
34
|
-
"ycodium-
|
|
32
|
+
"ycodium-executor-testing": "0.0.0",
|
|
33
|
+
"@ycodium-ai/plugin-api": "0.2.3506",
|
|
34
|
+
"ycodium-jsonl-stream": "0.0.0"
|
|
35
35
|
},
|
|
36
36
|
"ycodium": {
|
|
37
37
|
"plugin": "./dist/index.js",
|