@ycodium-ai/agent-codex 0.2.3254 → 0.2.3269
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 +130 -20
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -439,7 +439,15 @@ var probeCodexAccount = (accountPath) => {
|
|
|
439
439
|
import * as NodeProcess from "node:process";
|
|
440
440
|
import {
|
|
441
441
|
describeExecutorSpawnFailure,
|
|
442
|
-
ExecutorSpawnRefusedError
|
|
442
|
+
ExecutorSpawnRefusedError as ExecutorSpawnRefusedError2,
|
|
443
|
+
raceAbort
|
|
444
|
+
} from "@ycodium-ai/plugin-api/executor";
|
|
445
|
+
|
|
446
|
+
// src/appServerLaunch.ts
|
|
447
|
+
import {
|
|
448
|
+
ExecutorSpawnAbortedError,
|
|
449
|
+
ExecutorSpawnRefusedError,
|
|
450
|
+
throwIfExecutorSpawnAborted
|
|
443
451
|
} from "@ycodium-ai/plugin-api/executor";
|
|
444
452
|
|
|
445
453
|
// src/connection.ts
|
|
@@ -661,8 +669,14 @@ function shouldCrushApiKeys(authMode) {
|
|
|
661
669
|
}
|
|
662
670
|
|
|
663
671
|
// src/appServerLaunch.ts
|
|
672
|
+
function throwIfCodexSpawnControlled(error) {
|
|
673
|
+
if (error instanceof ExecutorSpawnRefusedError || error instanceof ExecutorSpawnAbortedError) {
|
|
674
|
+
throw error;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
664
677
|
async function spawnCodexAppServer(input) {
|
|
665
678
|
await materializeCodexShadowHome(input.layout, input.host.log);
|
|
679
|
+
throwIfExecutorSpawnAborted(input.signal);
|
|
666
680
|
const env = input.env ?? buildCodexSpawnEnv({
|
|
667
681
|
recipe: input.recipe,
|
|
668
682
|
layout: input.layout,
|
|
@@ -674,11 +688,59 @@ async function spawnCodexAppServer(input) {
|
|
|
674
688
|
args,
|
|
675
689
|
owner: { bindingId: input.host.bindingId },
|
|
676
690
|
...input.cwd === void 0 ? {} : { cwd: input.cwd },
|
|
677
|
-
...input.env !== void 0 || Object.keys(env).length > 0 ? { env } : {}
|
|
691
|
+
...input.env !== void 0 || Object.keys(env).length > 0 ? { env } : {},
|
|
692
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
678
693
|
});
|
|
679
694
|
return { handle, args };
|
|
680
695
|
}
|
|
681
696
|
|
|
697
|
+
// src/cliVersion.ts
|
|
698
|
+
var CODEX_VERSION_TIMEOUT_MS = 15e3;
|
|
699
|
+
var VERSION_PATTERN = /(?<![\d.])(\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?)/;
|
|
700
|
+
async function collect(stream) {
|
|
701
|
+
const chunks = [];
|
|
702
|
+
for await (const chunk of stream) {
|
|
703
|
+
chunks.push(Buffer.from(chunk));
|
|
704
|
+
if (Buffer.concat(chunks).length > 64 * 1024) break;
|
|
705
|
+
}
|
|
706
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
707
|
+
}
|
|
708
|
+
async function readCodexCliVersion(input) {
|
|
709
|
+
if (input.recipe.binaryPath.length === 0) return null;
|
|
710
|
+
let handle;
|
|
711
|
+
try {
|
|
712
|
+
handle = await input.host.process.spawn({
|
|
713
|
+
program: input.recipe.binaryPath,
|
|
714
|
+
args: ["--version"],
|
|
715
|
+
owner: { bindingId: input.host.bindingId }
|
|
716
|
+
});
|
|
717
|
+
} catch {
|
|
718
|
+
return null;
|
|
719
|
+
}
|
|
720
|
+
const collected = Promise.all([collect(handle.stdout), collect(handle.stderr), handle.exited]);
|
|
721
|
+
let timer;
|
|
722
|
+
const timeout = new Promise((resolve2) => {
|
|
723
|
+
timer = setTimeout(() => resolve2("timeout"), CODEX_VERSION_TIMEOUT_MS);
|
|
724
|
+
timer.unref?.();
|
|
725
|
+
});
|
|
726
|
+
try {
|
|
727
|
+
const settled = await Promise.race([collected, timeout]);
|
|
728
|
+
if (settled === "timeout") {
|
|
729
|
+
collected.catch(() => void 0);
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
const [stdout, stderr, exitCode] = settled;
|
|
733
|
+
if (exitCode !== 0) return null;
|
|
734
|
+
return VERSION_PATTERN.exec(`${stdout}
|
|
735
|
+
${stderr}`)?.[1] ?? null;
|
|
736
|
+
} catch {
|
|
737
|
+
return null;
|
|
738
|
+
} finally {
|
|
739
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
740
|
+
await handle.kill("SIGTERM").catch(() => void 0);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
682
744
|
// src/failureCategory.ts
|
|
683
745
|
var codexProcessExitCategory = (session) => session !== void 0 && !session.stopRequested && typeof session.nativeThreadId === "string" && session.nativeThreadId.length > 0 ? "transport" : void 0;
|
|
684
746
|
|
|
@@ -1800,6 +1862,29 @@ function toCanonicalUserInputAnswers(answers) {
|
|
|
1800
1862
|
);
|
|
1801
1863
|
}
|
|
1802
1864
|
|
|
1865
|
+
// src/windowsSandbox.ts
|
|
1866
|
+
function windowsSandboxWarnings(input) {
|
|
1867
|
+
const item = isRecord3(input.params) ? input.params["item"] : void 0;
|
|
1868
|
+
if (!isRecord3(item) || item["type"] !== "commandExecution" || item["source"] !== "unifiedExecStartup" || item["status"] !== "failed" || item["processId"] !== null || item["exitCode"] !== -1 || item["durationMs"] !== 0)
|
|
1869
|
+
return [];
|
|
1870
|
+
const output = item["aggregatedOutput"];
|
|
1871
|
+
if (typeof output !== "string" || !/^Failed to create unified exec process: (?:CreateProcessWithLogonW failed: \d+\b|orchestrator_helper_launch_canceled: ShellExecuteExW failed to launch setup helper: \d+\b)/.test(
|
|
1872
|
+
output
|
|
1873
|
+
))
|
|
1874
|
+
return [];
|
|
1875
|
+
return [
|
|
1876
|
+
baseEvent({
|
|
1877
|
+
type: "runtime.warning",
|
|
1878
|
+
threadId: input.threadId,
|
|
1879
|
+
turnId: input.turnId,
|
|
1880
|
+
itemId: input.itemId,
|
|
1881
|
+
providerInstanceId: input.providerInstanceId,
|
|
1882
|
+
method: "item/completed",
|
|
1883
|
+
payload: { code: "codex-windows-sandbox", message: output, detail: output }
|
|
1884
|
+
})
|
|
1885
|
+
];
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1803
1888
|
// src/usage/codexQuota.ts
|
|
1804
1889
|
var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
1805
1890
|
var asFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
@@ -2497,7 +2582,18 @@ function mapNotificationToEvents(input) {
|
|
|
2497
2582
|
})
|
|
2498
2583
|
] : [];
|
|
2499
2584
|
const asyncQuestions = canonical === "assistant_message" && itemId ? toAsyncQuestions(params) : void 0;
|
|
2500
|
-
if (!asyncQuestions)
|
|
2585
|
+
if (!asyncQuestions)
|
|
2586
|
+
return [
|
|
2587
|
+
completed,
|
|
2588
|
+
...produced,
|
|
2589
|
+
...windowsSandboxWarnings({
|
|
2590
|
+
params,
|
|
2591
|
+
threadId,
|
|
2592
|
+
turnId,
|
|
2593
|
+
itemId,
|
|
2594
|
+
providerInstanceId
|
|
2595
|
+
})
|
|
2596
|
+
];
|
|
2501
2597
|
return [
|
|
2502
2598
|
completed,
|
|
2503
2599
|
baseEvent({
|
|
@@ -5920,9 +6016,14 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
5920
6016
|
let version = null;
|
|
5921
6017
|
try {
|
|
5922
6018
|
try {
|
|
5923
|
-
({ handle } = await spawnCodexAppServer({
|
|
6019
|
+
({ handle } = await spawnCodexAppServer({
|
|
6020
|
+
host,
|
|
6021
|
+
recipe,
|
|
6022
|
+
layout,
|
|
6023
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
6024
|
+
}));
|
|
5924
6025
|
} catch (error) {
|
|
5925
|
-
|
|
6026
|
+
throwIfCodexSpawnControlled(error);
|
|
5926
6027
|
host.log.warn("codex binary could not be started", {
|
|
5927
6028
|
program: recipe.binaryPath,
|
|
5928
6029
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -5935,19 +6036,26 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
5935
6036
|
};
|
|
5936
6037
|
}
|
|
5937
6038
|
trackHandle(handle, `${recipe.binaryPath} (probe)`);
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
6039
|
+
const spawned = handle;
|
|
6040
|
+
return await raceAbort(
|
|
6041
|
+
(async () => {
|
|
6042
|
+
rpc = await createCodexRpcClient(spawned, {
|
|
6043
|
+
onNotification: () => void 0,
|
|
6044
|
+
onServerRequest: () => void 0,
|
|
6045
|
+
onStderrLine: () => void 0
|
|
6046
|
+
});
|
|
6047
|
+
version = codexVersionFromInitialize(
|
|
6048
|
+
await rpc.request("initialize", CODEX_INITIALIZE_PARAMS)
|
|
6049
|
+
);
|
|
6050
|
+
await rpc.notify("initialized");
|
|
6051
|
+
const models = input.listModels ? await listCodexModels(rpc) : void 0;
|
|
6052
|
+
return { version, models, skills: await listCodexSkills(rpc), spawnFailed: null };
|
|
6053
|
+
})(),
|
|
6054
|
+
input.signal
|
|
5945
6055
|
);
|
|
5946
|
-
await rpc.notify("initialized");
|
|
5947
|
-
const models = input.listModels ? await listCodexModels(rpc) : void 0;
|
|
5948
|
-
return { version, models, skills: await listCodexSkills(rpc), spawnFailed: null };
|
|
5949
6056
|
} catch (error) {
|
|
5950
|
-
if (error instanceof
|
|
6057
|
+
if (error instanceof ExecutorSpawnRefusedError2) throw error;
|
|
6058
|
+
if (input.signal?.aborted) throw error;
|
|
5951
6059
|
return { version, models: void 0, skills: void 0, spawnFailed: null };
|
|
5952
6060
|
} finally {
|
|
5953
6061
|
await rpc?.close().catch(() => void 0);
|
|
@@ -5962,7 +6070,7 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
5962
6070
|
try {
|
|
5963
6071
|
({ handle } = await spawnCodexAppServer({ host, recipe, layout }));
|
|
5964
6072
|
} catch (error) {
|
|
5965
|
-
if (error instanceof
|
|
6073
|
+
if (error instanceof ExecutorSpawnRefusedError2) {
|
|
5966
6074
|
const borrowed = [...threads.values()].find((entry) => !entry.closing);
|
|
5967
6075
|
if (borrowed !== void 0) return await run(borrowed.rpc);
|
|
5968
6076
|
}
|
|
@@ -6008,7 +6116,7 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
6008
6116
|
return booked.closing;
|
|
6009
6117
|
};
|
|
6010
6118
|
const instance = {
|
|
6011
|
-
probe: async () => {
|
|
6119
|
+
probe: async (signal) => {
|
|
6012
6120
|
if (recipe.binaryPath.length === 0) {
|
|
6013
6121
|
return {
|
|
6014
6122
|
installed: false,
|
|
@@ -6020,7 +6128,8 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
6020
6128
|
}
|
|
6021
6129
|
const connectionError = codexApiConnectionError(recipe, recipe.environment);
|
|
6022
6130
|
const { version, models, skills, spawnFailed } = await probeAppServer({
|
|
6023
|
-
listModels: connectionError === null
|
|
6131
|
+
listModels: connectionError === null,
|
|
6132
|
+
...signal === void 0 ? {} : { signal }
|
|
6024
6133
|
});
|
|
6025
6134
|
if (spawnFailed !== null) {
|
|
6026
6135
|
return {
|
|
@@ -6054,6 +6163,7 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
6054
6163
|
...CODEX_NATIVE_MODE_REPORT
|
|
6055
6164
|
};
|
|
6056
6165
|
},
|
|
6166
|
+
readCliVersion: () => readCodexCliVersion({ recipe, host }),
|
|
6057
6167
|
// 有意不处理 input.readOnlyDirectories:codex 的沙箱只限制写入,读不受限,
|
|
6058
6168
|
// 附件目录本来就能读,无需放行。
|
|
6059
6169
|
startSession: async (input, signal) => {
|
|
@@ -6387,7 +6497,7 @@ var executors = [
|
|
|
6387
6497
|
];
|
|
6388
6498
|
var index_default = definePlugin({
|
|
6389
6499
|
id: "agent-codex",
|
|
6390
|
-
apiVersion:
|
|
6500
|
+
apiVersion: 31,
|
|
6391
6501
|
executors,
|
|
6392
6502
|
activate(ctx) {
|
|
6393
6503
|
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.3269",
|
|
4
4
|
"description": "Codex executor: Codex CLI over the app-server JSON-RPC protocol.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"tailwindcss": "^4.0.0",
|
|
30
30
|
"typescript": "~6.0.3",
|
|
31
31
|
"vite-plus": "0.2.2",
|
|
32
|
-
"@ycodium-ai/plugin-api": "0.2.
|
|
32
|
+
"@ycodium-ai/plugin-api": "0.2.0",
|
|
33
33
|
"ycodium-executor-testing": "0.0.0"
|
|
34
34
|
},
|
|
35
35
|
"ycodium": {
|