@ycodium-ai/agent-codex 0.2.3078 → 0.2.3082

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.
Files changed (2) hide show
  1. package/dist/index.js +45 -65
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -573,39 +573,15 @@ function codexExecLaunchArgs(launchArgs) {
573
573
  }
574
574
  return execArgs;
575
575
  }
576
- function hasConfiguredMcpServer(appServerArgs) {
577
- return appServerArgs.some((arg) => arg.includes("mcp_servers."));
578
- }
579
- var BUILTIN_MCP_SERVER_NAME = "ycodium";
580
- function codexBearerTokenEnvVar(name) {
581
- return name === BUILTIN_MCP_SERVER_NAME ? "YCODIUM_MCP_BEARER_TOKEN" : `YCODIUM_MCP_TOKEN_${name.toUpperCase().replaceAll(/[^A-Z0-9]/g, "_")}`;
582
- }
583
- function codexMcpLaunchConfig(servers) {
584
- const args = [];
585
- const environment = {};
586
- const toml = (value) => JSON.stringify(value);
587
- for (const server of servers) {
588
- const key = `mcp_servers.${server.name}`;
589
- if (server.transport.type === "stdio") {
590
- args.push("-c", `${key}.command=${toml(server.transport.command)}`);
591
- const commandArgs = server.transport.args ?? [];
592
- if (commandArgs.length > 0) {
593
- args.push("-c", `${key}.args=[${commandArgs.map(toml).join(",")}]`);
594
- }
595
- for (const [name, value] of Object.entries(server.transport.env ?? {})) {
596
- args.push("-c", `${key}.env.${name}=${toml(value)}`);
597
- }
598
- continue;
599
- }
600
- args.push("-c", `${key}.url=${server.transport.url}`);
601
- const bearer = server.transport.headers?.["Authorization"]?.replace(/^Bearer\s+/, "");
602
- if (bearer) {
603
- const envVar = codexBearerTokenEnvVar(server.name);
604
- environment[envVar] = bearer;
605
- args.push("-c", `${key}.bearer_token_env_var=${toml(envVar)}`);
606
- }
607
- }
608
- return { args, environment };
576
+ function codexMcpThreadConfig(servers) {
577
+ return {
578
+ mcp_servers: Object.fromEntries(
579
+ servers.map(({ name, transport }) => [
580
+ name,
581
+ transport.type === "stdio" ? { command: transport.command, args: transport.args ?? [], env: transport.env ?? {} } : { url: transport.url, http_headers: transport.headers ?? {} }
582
+ ])
583
+ )
584
+ };
609
585
  }
610
586
  function modelIdFromSelection(selection) {
611
587
  if (typeof selection !== "object" || selection === null || Array.isArray(selection)) {
@@ -669,8 +645,7 @@ function buildCodexSpawnEnv(input) {
669
645
  return mergeLaunchEnv({
670
646
  accountHome: input.layout.effectiveHomePath !== void 0 ? { CODEX_HOME: input.layout.effectiveHomePath } : {},
671
647
  instanceTable,
672
- handOverrides: input.crushApiKeys ? CRUSHED_API_KEYS : {},
673
- launch: input.launchEnv
648
+ handOverrides: input.crushApiKeys ? CRUSHED_API_KEYS : {}
674
649
  });
675
650
  }
676
651
  function nativeLoginSpawnEnv(processEnv, isolatedHome) {
@@ -689,13 +664,9 @@ async function spawnCodexAppServer(input) {
689
664
  const env = input.env ?? buildCodexSpawnEnv({
690
665
  recipe: input.recipe,
691
666
  layout: input.layout,
692
- ...input.launchEnv === void 0 ? {} : { launchEnv: input.launchEnv },
693
667
  crushApiKeys: shouldCrushApiKeys(input.recipe.authMode)
694
668
  });
695
- const args = input.args ?? [
696
- ...codexSpawnArgs(input.recipe, input.layout),
697
- ...input.extraArgs ?? []
698
- ];
669
+ const args = input.args ?? codexSpawnArgs(input.recipe, input.layout);
699
670
  const handle = await input.host.process.spawn({
700
671
  program: input.recipe.binaryPath,
701
672
  args,
@@ -3150,6 +3121,7 @@ var CodexSessionRuntime = class {
3150
3121
  /** 这个会话见过的主额度快照(按字段合并),额度用尽停轮时点名窗口用。 */
3151
3122
  rateLimits;
3152
3123
  appServerArgs;
3124
+ hasConfiguredMcpServer;
3153
3125
  host;
3154
3126
  attachments;
3155
3127
  rpc;
@@ -3192,6 +3164,7 @@ var CodexSessionRuntime = class {
3192
3164
  this.runtimeMode = input.runtimeMode;
3193
3165
  this.nativeModeId = input.nativeModeId;
3194
3166
  this.appServerArgs = appServerArgs;
3167
+ this.hasConfiguredMcpServer = (input.mcpServers?.length ?? 0) > 0;
3195
3168
  this.grants = grants ?? createApprovalGrantStore();
3196
3169
  this.declineRelay = declineRelay ?? createDeclineReasonRelay();
3197
3170
  const createdAt = nowIso();
@@ -3711,21 +3684,14 @@ var CodexSessionRuntime = class {
3711
3684
  }
3712
3685
  throw lastError instanceof Error ? lastError : new Error(String(lastError));
3713
3686
  }
3714
- threadConfigParams() {
3715
- const config = this.#threadConfig();
3716
- return {
3717
- approvalPolicy: config.approvalPolicy,
3718
- sandbox: config.sandbox,
3719
- approvalsReviewer: config.approvalsReviewer,
3720
- cwd: this.cwd
3721
- };
3722
- }
3723
3687
  async openThread(input) {
3724
3688
  const resume = input.discardResumeCursor === true ? void 0 : parseCodexResumeCursor(input.resumeCursor);
3725
3689
  const requestedModel = modelIdFromSelection(input.modelSelection);
3726
3690
  const startParams = {
3727
- ...this.threadConfigParams(),
3728
- ...requestedModel ? { model: requestedModel } : {}
3691
+ ...this.#threadConfig(),
3692
+ cwd: this.cwd,
3693
+ ...requestedModel ? { model: requestedModel } : {},
3694
+ ...this.hasConfiguredMcpServer ? { config: codexMcpThreadConfig(input.mcpServers ?? []) } : {}
3729
3695
  };
3730
3696
  const result = resume ? await this.withActiveWriterRecovery(
3731
3697
  () => this.rpc.request("thread/resume", { threadId: resume.threadId, ...startParams }, 0),
@@ -3762,7 +3728,7 @@ var CodexSessionRuntime = class {
3762
3728
  return mode;
3763
3729
  }
3764
3730
  developerInstructions(input, mode) {
3765
- const tools = hasConfiguredMcpServer(this.appServerArgs);
3731
+ const tools = this.hasConfiguredMcpServer;
3766
3732
  const model = this.model ?? DEFAULT_MODEL;
3767
3733
  const effort = modelSelectionStringOption(input.modelSelection, "reasoningEffort") ?? DEFAULT_TEXT_GENERATION_REASONING_EFFORT;
3768
3734
  return buildCodexDeveloperInstructions(mode, { model, reasoningEffort: effort }, tools, tools);
@@ -3799,7 +3765,7 @@ var CodexSessionRuntime = class {
3799
3765
  }
3800
3766
  async sendTurn(input) {
3801
3767
  if (!this.nativeThreadId) throw new Error("codex session has no native thread");
3802
- if (hasConfiguredMcpServer(this.appServerArgs)) {
3768
+ if (this.hasConfiguredMcpServer) {
3803
3769
  await this.rpc.request("config/mcpServer/reload", void 0, 0).catch((error) => {
3804
3770
  this.host.log.warn("refreshing the codex MCP tool list before a turn failed", {
3805
3771
  threadId: this.threadId,
@@ -4179,17 +4145,35 @@ async function readRolloutModel(input, rolloutPath, sameDirectory) {
4179
4145
  }
4180
4146
 
4181
4147
  // src/mcpOAuth.ts
4148
+ function codexMcpOAuthLaunchConfig(name, transport) {
4149
+ const key = `mcp_servers.${name}`;
4150
+ const args = ["-c", `${key}.url=${transport.url}`];
4151
+ const environment = {};
4152
+ const bearer = transport.headers?.["Authorization"]?.replace(/^Bearer\s+/, "");
4153
+ if (bearer) {
4154
+ const envVar = name === "ycodium" ? "YCODIUM_MCP_BEARER_TOKEN" : `YCODIUM_MCP_TOKEN_${name.toUpperCase().replaceAll(/[^A-Z0-9]/g, "_")}`;
4155
+ environment[envVar] = bearer;
4156
+ args.push("-c", `${key}.bearer_token_env_var=${JSON.stringify(envVar)}`);
4157
+ }
4158
+ return { args, environment };
4159
+ }
4182
4160
  async function startCodexMcpOAuth(input) {
4183
4161
  if (input.recipe.binaryPath.length === 0) {
4184
4162
  throw new Error("Codex program path is not configured");
4185
4163
  }
4186
- const mcp = codexMcpLaunchConfig([input.server]);
4187
- const env = buildCodexSpawnEnv({
4188
- recipe: input.recipe,
4189
- layout: input.layout,
4190
- launchEnv: { ...input.processEnv, ...mcp.environment },
4191
- crushApiKeys: shouldCrushApiKeys(input.recipe.authMode)
4192
- });
4164
+ if (input.server.transport.type === "stdio") {
4165
+ throw new Error(`MCP OAuth needs an http server: ${input.server.name}`);
4166
+ }
4167
+ const mcp = codexMcpOAuthLaunchConfig(input.server.name, input.server.transport);
4168
+ const env = {
4169
+ ...buildCodexSpawnEnv({
4170
+ recipe: input.recipe,
4171
+ layout: input.layout,
4172
+ crushApiKeys: shouldCrushApiKeys(input.recipe.authMode)
4173
+ }),
4174
+ ...input.processEnv,
4175
+ ...mcp.environment
4176
+ };
4193
4177
  const { handle } = await spawnCodexAppServer({
4194
4178
  host: input.host,
4195
4179
  recipe: input.recipe,
@@ -5906,15 +5890,11 @@ var createCodexInstance = (config, host, attachments, cache) => {
5906
5890
  threads.delete(input.threadId);
5907
5891
  }
5908
5892
  const layout = layoutFor(recipe);
5909
- const mcp = codexMcpLaunchConfig(input.mcpServers ?? []);
5910
5893
  const { handle, args } = await spawnCodexAppServer({
5911
5894
  host,
5912
5895
  recipe,
5913
5896
  layout,
5914
- cwd,
5915
- extraArgs: mcp.args,
5916
- // MCP 那几个变量是宿主挑好的 server 带来的,铺在最终层:实例表盖不得。
5917
- launchEnv: mcp.environment
5897
+ cwd
5918
5898
  });
5919
5899
  trackHandle(handle, [recipe.binaryPath, ...args].join(" "), input.threadId);
5920
5900
  let runtime;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-codex",
3
- "version": "0.2.3078",
3
+ "version": "0.2.3082",
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.3078",
32
+ "@ycodium-ai/plugin-api": "0.2.0",
33
33
  "ycodium-executor-testing": "0.0.0"
34
34
  },
35
35
  "ycodium": {