@ycodium-ai/agent-codex 0.2.3254 → 0.2.3265
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 +95 -19
- 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
|
|
|
@@ -5920,9 +5982,14 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
5920
5982
|
let version = null;
|
|
5921
5983
|
try {
|
|
5922
5984
|
try {
|
|
5923
|
-
({ handle } = await spawnCodexAppServer({
|
|
5985
|
+
({ handle } = await spawnCodexAppServer({
|
|
5986
|
+
host,
|
|
5987
|
+
recipe,
|
|
5988
|
+
layout,
|
|
5989
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
5990
|
+
}));
|
|
5924
5991
|
} catch (error) {
|
|
5925
|
-
|
|
5992
|
+
throwIfCodexSpawnControlled(error);
|
|
5926
5993
|
host.log.warn("codex binary could not be started", {
|
|
5927
5994
|
program: recipe.binaryPath,
|
|
5928
5995
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -5935,19 +6002,26 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
5935
6002
|
};
|
|
5936
6003
|
}
|
|
5937
6004
|
trackHandle(handle, `${recipe.binaryPath} (probe)`);
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
6005
|
+
const spawned = handle;
|
|
6006
|
+
return await raceAbort(
|
|
6007
|
+
(async () => {
|
|
6008
|
+
rpc = await createCodexRpcClient(spawned, {
|
|
6009
|
+
onNotification: () => void 0,
|
|
6010
|
+
onServerRequest: () => void 0,
|
|
6011
|
+
onStderrLine: () => void 0
|
|
6012
|
+
});
|
|
6013
|
+
version = codexVersionFromInitialize(
|
|
6014
|
+
await rpc.request("initialize", CODEX_INITIALIZE_PARAMS)
|
|
6015
|
+
);
|
|
6016
|
+
await rpc.notify("initialized");
|
|
6017
|
+
const models = input.listModels ? await listCodexModels(rpc) : void 0;
|
|
6018
|
+
return { version, models, skills: await listCodexSkills(rpc), spawnFailed: null };
|
|
6019
|
+
})(),
|
|
6020
|
+
input.signal
|
|
5945
6021
|
);
|
|
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
6022
|
} catch (error) {
|
|
5950
|
-
if (error instanceof
|
|
6023
|
+
if (error instanceof ExecutorSpawnRefusedError2) throw error;
|
|
6024
|
+
if (input.signal?.aborted) throw error;
|
|
5951
6025
|
return { version, models: void 0, skills: void 0, spawnFailed: null };
|
|
5952
6026
|
} finally {
|
|
5953
6027
|
await rpc?.close().catch(() => void 0);
|
|
@@ -5962,7 +6036,7 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
5962
6036
|
try {
|
|
5963
6037
|
({ handle } = await spawnCodexAppServer({ host, recipe, layout }));
|
|
5964
6038
|
} catch (error) {
|
|
5965
|
-
if (error instanceof
|
|
6039
|
+
if (error instanceof ExecutorSpawnRefusedError2) {
|
|
5966
6040
|
const borrowed = [...threads.values()].find((entry) => !entry.closing);
|
|
5967
6041
|
if (borrowed !== void 0) return await run(borrowed.rpc);
|
|
5968
6042
|
}
|
|
@@ -6008,7 +6082,7 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
6008
6082
|
return booked.closing;
|
|
6009
6083
|
};
|
|
6010
6084
|
const instance = {
|
|
6011
|
-
probe: async () => {
|
|
6085
|
+
probe: async (signal) => {
|
|
6012
6086
|
if (recipe.binaryPath.length === 0) {
|
|
6013
6087
|
return {
|
|
6014
6088
|
installed: false,
|
|
@@ -6020,7 +6094,8 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
6020
6094
|
}
|
|
6021
6095
|
const connectionError = codexApiConnectionError(recipe, recipe.environment);
|
|
6022
6096
|
const { version, models, skills, spawnFailed } = await probeAppServer({
|
|
6023
|
-
listModels: connectionError === null
|
|
6097
|
+
listModels: connectionError === null,
|
|
6098
|
+
...signal === void 0 ? {} : { signal }
|
|
6024
6099
|
});
|
|
6025
6100
|
if (spawnFailed !== null) {
|
|
6026
6101
|
return {
|
|
@@ -6054,6 +6129,7 @@ var createCodexInstance = (config, host, attachments, cache) => {
|
|
|
6054
6129
|
...CODEX_NATIVE_MODE_REPORT
|
|
6055
6130
|
};
|
|
6056
6131
|
},
|
|
6132
|
+
readCliVersion: () => readCodexCliVersion({ recipe, host }),
|
|
6057
6133
|
// 有意不处理 input.readOnlyDirectories:codex 的沙箱只限制写入,读不受限,
|
|
6058
6134
|
// 附件目录本来就能读,无需放行。
|
|
6059
6135
|
startSession: async (input, signal) => {
|
|
@@ -6387,7 +6463,7 @@ var executors = [
|
|
|
6387
6463
|
];
|
|
6388
6464
|
var index_default = definePlugin({
|
|
6389
6465
|
id: "agent-codex",
|
|
6390
|
-
apiVersion:
|
|
6466
|
+
apiVersion: 31,
|
|
6391
6467
|
executors,
|
|
6392
6468
|
activate(ctx) {
|
|
6393
6469
|
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.3265",
|
|
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.3265",
|
|
33
33
|
"ycodium-executor-testing": "0.0.0"
|
|
34
34
|
},
|
|
35
35
|
"ycodium": {
|