@agentrouter-top/relay-dsh-plugin-codex 0.2.2-agentrouter.1 → 0.2.2-agentrouter.3

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.
@@ -681,8 +681,11 @@ function newThreadConfig(bypassHookTrust) {
681
681
  };
682
682
  }
683
683
  var CodexSessionRuntime = class extends EventEmitter {
684
- constructor({ client, cwd = process.cwd(), codexHome }) {
684
+ constructor({ client, cwd = process.cwd(), codexHome, behaviorDefaults = "relay" }) {
685
685
  super();
686
+ if (!["relay", "native"].includes(behaviorDefaults)) throw new TypeError(`Unknown Codex behavior defaults: ${behaviorDefaults}`);
687
+ this.behaviorDefaults = behaviorDefaults;
688
+ this.defaultMultiAgentMode = behaviorDefaults === "native" ? void 0 : DEFAULT_MULTI_AGENT_MODE;
686
689
  this.client = client;
687
690
  this.cwd = cwd;
688
691
  this.codexHome = codexHome;
@@ -807,15 +810,15 @@ var CodexSessionRuntime = class extends EventEmitter {
807
810
  approvalPolicy,
808
811
  permissions: permissionProfile(selectedSandbox),
809
812
  runtimeWorkspaceRoots: selectedSandbox === "read-only" ? [] : [cwd],
810
- personality: ephemeral ? null : "friendly",
813
+ personality: this.behaviorDefaults === "native" ? void 0 : ephemeral ? null : "friendly",
811
814
  ephemeral: ephemeral ?? null,
812
- baseInstructions: baseInstructions ?? null,
815
+ baseInstructions: this.behaviorDefaults === "native" ? baseInstructions : baseInstructions ?? null,
813
816
  serviceName,
814
817
  threadSource,
815
818
  mockExperimentalField: null,
816
819
  experimentalRawEvents: !ephemeral,
817
820
  dynamicTools,
818
- developerInstructions: developerInstructions ?? null
821
+ developerInstructions: this.behaviorDefaults === "native" ? developerInstructions : developerInstructions ?? null
819
822
  }));
820
823
  const session = this.upsertThread(result.thread, {
821
824
  model: selectedModel,
@@ -828,7 +831,7 @@ var CodexSessionRuntime = class extends EventEmitter {
828
831
  this.recordNativeSettings(session, result, {
829
832
  model: selectedModel,
830
833
  effort: selectedEffort,
831
- multiAgentMode: DEFAULT_MULTI_AGENT_MODE
834
+ multiAgentMode: this.defaultMultiAgentMode
832
835
  });
833
836
  if (!session.ephemeral) this.selectedSessionId = session.id;
834
837
  this.emitChange();
@@ -851,8 +854,8 @@ var CodexSessionRuntime = class extends EventEmitter {
851
854
  approvalPolicy,
852
855
  permissions: permissionProfile(selectedSandbox),
853
856
  runtimeWorkspaceRoots: selectedSandbox === "read-only" ? [] : [cwd],
854
- baseInstructions: baseInstructions ?? null,
855
- developerInstructions: developerInstructions ?? null,
857
+ baseInstructions: this.behaviorDefaults === "native" ? baseInstructions : baseInstructions ?? null,
858
+ developerInstructions: this.behaviorDefaults === "native" ? developerInstructions : developerInstructions ?? null,
856
859
  ephemeral,
857
860
  threadSource
858
861
  }));
@@ -868,7 +871,7 @@ var CodexSessionRuntime = class extends EventEmitter {
868
871
  this.recordNativeSettings(session, result, {
869
872
  model: session.model,
870
873
  effort: session.effort,
871
- multiAgentMode: DEFAULT_MULTI_AGENT_MODE
874
+ multiAgentMode: this.defaultMultiAgentMode
872
875
  });
873
876
  if (!session.ephemeral) this.selectedSessionId = session.id;
874
877
  this.emitChange();
@@ -890,7 +893,7 @@ var CodexSessionRuntime = class extends EventEmitter {
890
893
  this.recordNativeSettings(session, result, {
891
894
  model: session.model,
892
895
  effort: session.effort,
893
- multiAgentMode: DEFAULT_MULTI_AGENT_MODE
896
+ multiAgentMode: this.defaultMultiAgentMode
894
897
  });
895
898
  if (result.thread.turns?.length > 0) session.turns = structuredClone(result.thread.turns);
896
899
  this.selectedSessionId = threadId;
@@ -913,7 +916,7 @@ var CodexSessionRuntime = class extends EventEmitter {
913
916
  await this.syncThreadSettings(session.id, {
914
917
  model: nextModel,
915
918
  effort: nextEffort,
916
- multiAgentMode: DEFAULT_MULTI_AGENT_MODE
919
+ multiAgentMode: this.defaultMultiAgentMode
917
920
  });
918
921
  Object.assign(session, {
919
922
  model: nextModel,
@@ -935,12 +938,12 @@ var CodexSessionRuntime = class extends EventEmitter {
935
938
  runtimeWorkspaceRoots: usePermissionProfile ? runtimeWorkspaceRoots(nextSandbox, workspaceRoots) : null,
936
939
  model: null,
937
940
  effort: null,
938
- multiAgentMode: DEFAULT_MULTI_AGENT_MODE,
941
+ multiAgentMode: this.defaultMultiAgentMode,
939
942
  summary: reasoningSummary === "none" ? "none" : "auto",
940
- personality: "friendly",
943
+ personality: this.behaviorDefaults === "native" ? void 0 : "friendly",
941
944
  responsesapiClientMetadata: { workspace_kind: "project" },
942
945
  outputSchema: null,
943
- collaborationMode: {
946
+ collaborationMode: this.behaviorDefaults === "native" ? void 0 : {
944
947
  mode: "default",
945
948
  settings: {
946
949
  model: nextModel,
@@ -1051,15 +1054,15 @@ var CodexSessionRuntime = class extends EventEmitter {
1051
1054
  });
1052
1055
  }
1053
1056
  async syncThreadSettings(threadId, settings) {
1054
- const next = normalizeThreadSettings(settings);
1057
+ const next = normalizeThreadSettings(settings, this.defaultMultiAgentMode);
1055
1058
  const current = this.appliedThreadSettings.get(threadId);
1056
1059
  if (current && sameThreadSettings(current, next)) return;
1057
- await this.client.request("thread/settings/update", {
1060
+ await this.client.request("thread/settings/update", compactObject({
1058
1061
  threadId,
1059
1062
  model: next.model,
1060
1063
  effort: next.effort,
1061
1064
  multiAgentMode: next.multiAgentMode
1062
- });
1065
+ }));
1063
1066
  this.appliedThreadSettings.set(threadId, next);
1064
1067
  }
1065
1068
  async releaseSession(threadId) {
@@ -1363,7 +1366,7 @@ var CodexSessionRuntime = class extends EventEmitter {
1363
1366
  if (!this.closed) this.emit("connectionStatus", this.status());
1364
1367
  }
1365
1368
  recordAppliedThreadSettings(threadId, settings) {
1366
- this.appliedThreadSettings.set(threadId, normalizeThreadSettings(settings));
1369
+ this.appliedThreadSettings.set(threadId, normalizeThreadSettings(settings, this.defaultMultiAgentMode));
1367
1370
  }
1368
1371
  recordNativeSettings(session, result, fallback = {}) {
1369
1372
  const settings = compactObject({
@@ -1550,15 +1553,15 @@ function turnInterruptionFailure(threadId, turnId, failures) {
1550
1553
  error.failures = failures;
1551
1554
  return error;
1552
1555
  }
1553
- function normalizeThreadSettings(settings = {}) {
1556
+ function normalizeThreadSettings(settings = {}, defaultMultiAgentMode) {
1554
1557
  return {
1555
1558
  model: settings.model ?? null,
1556
1559
  effort: settings.effort ?? null,
1557
- multiAgentMode: settings.multiAgentMode ?? DEFAULT_MULTI_AGENT_MODE
1560
+ multiAgentMode: settings.multiAgentMode ?? defaultMultiAgentMode
1558
1561
  };
1559
1562
  }
1560
1563
  function sameThreadSettings(left, right) {
1561
- return left.model === right.model && left.effort === right.effort && left.multiAgentMode === right.multiAgentMode;
1564
+ return left.model === right.model && left.effort === right.effort && (right.multiAgentMode === void 0 || left.multiAgentMode === right.multiAgentMode);
1562
1565
  }
1563
1566
  function summarizeTitle$1(text) {
1564
1567
  const normalized = text.replace(/\s+/g, " ").trim();
@@ -1598,7 +1601,8 @@ function createCodexExecutionPlugin(config = {}) {
1598
1601
  const runtime = new CodexSessionRuntime({
1599
1602
  client,
1600
1603
  cwd: config.cwd ?? process.cwd(),
1601
- codexHome: config.codexHome
1604
+ codexHome: config.codexHome,
1605
+ behaviorDefaults: config.behaviorDefaults
1602
1606
  });
1603
1607
  defer(() => runtime.close());
1604
1608
  const ready = runtime.initialize();
@@ -1748,6 +1752,16 @@ async function appendPersistedEvents(persistence, id, events) {
1748
1752
  }
1749
1753
  }
1750
1754
  //#endregion
1755
+ //#region kernel-policy.mjs
1756
+ /** Execution ownership, not a model-name or provider-brand allowlist. */
1757
+ function assertKernelRoute(codexSession, options) {
1758
+ if (options.purpose) return;
1759
+ if (codexSession === (options.provider === "relay-codex")) return;
1760
+ const error = /* @__PURE__ */ new Error(codexSession ? "Codex 内核只能使用 Codex 适配器的模型。请重新选择 Codex 模型;不会忽略当前选择或自动换用其他模型。" : "当前会话不是 Codex 内核,不能使用 Codex 适配器的模型。请新建 Codex 会话。既有会话的内核不会被替换。");
1761
+ error.code = "CODEX_KERNEL_MODEL_MISMATCH";
1762
+ throw error;
1763
+ }
1764
+ //#endregion
1751
1765
  //#region codex-activity-wire.mjs
1752
1766
  const CODEX_ACTIVITY_TOOL = "relay_codex_activity";
1753
1767
  //#endregion
@@ -2275,6 +2289,14 @@ var CodexDshAdapter = class extends LlmAdapter {
2275
2289
  servesAgent(agent) {
2276
2290
  return effectivePreset(agent.session) === CODEX_PRESET;
2277
2291
  }
2292
+ admitStepMessages(agent, decision) {
2293
+ if (!this.servesAgent(agent) || decision.kind !== "enter") return decision;
2294
+ const messages = decision.messages.filter((message) => acceptsCodexInputSource(message.source));
2295
+ return messages.length === decision.messages.length ? decision : {
2296
+ ...decision,
2297
+ messages
2298
+ };
2299
+ }
2278
2300
  detachAgent(sessionId) {
2279
2301
  const key = String(sessionId);
2280
2302
  this.agents.delete(key);
@@ -2621,6 +2643,7 @@ var CodexDshAdapter = class extends LlmAdapter {
2621
2643
  return binding ? this.activeTurnSignals.get(binding.rootThreadId) : void 0;
2622
2644
  }
2623
2645
  async *stream(options) {
2646
+ assertKernelRoute(true, options);
2624
2647
  if (options.purpose) {
2625
2648
  yield* this.streamAuxiliary(options);
2626
2649
  return;
@@ -2634,8 +2657,8 @@ var CodexDshAdapter = class extends LlmAdapter {
2634
2657
  const events = sessionEvents(agent.session);
2635
2658
  const nativePermissions = permissionConfiguration(events);
2636
2659
  const config = this.configure(sessionId, {
2637
- ...options.provider === "relay-codex" ? { model: options.model } : {},
2638
- ...options.provider === "relay-codex" ? { effort: options.reasoningEffort } : {},
2660
+ model: options.model,
2661
+ effort: options.reasoningEffort,
2639
2662
  ...nativePermissions,
2640
2663
  cwd: agent.session.header.cwd
2641
2664
  });
@@ -3482,7 +3505,7 @@ async function latestUserInput(messages, attachments, signal, codexHome) {
3482
3505
  for (let index = messages.length - 1; index >= 0; index -= 1) {
3483
3506
  const message = messages[index];
3484
3507
  if (message?.role !== "user") continue;
3485
- if (message.source?.kind !== "user" && !isRelayActivation(message.source)) continue;
3508
+ if (!acceptsCodexInputSource(message.source)) continue;
3486
3509
  const text = (message.content ?? []).filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
3487
3510
  const localImages = [];
3488
3511
  for (const block of message.content ?? []) {
@@ -3541,8 +3564,8 @@ function completeAuxiliaryItem(state, item) {
3541
3564
  if (item.type === "agentMessage") return completeTextItem(state, item.id, "text", item.text ?? "");
3542
3565
  return [];
3543
3566
  }
3544
- function isRelayActivation(source) {
3545
- return source?.kind === "plugin" && source.plugin === "relay";
3567
+ function acceptsCodexInputSource(source) {
3568
+ return source?.kind === "user" || source?.kind === "plugin" && source.plugin === "relay";
3546
3569
  }
3547
3570
  function compact(value) {
3548
3571
  return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0 && item !== null));
@@ -4987,11 +5010,18 @@ function createDshCodexPlugin(ctx, config = {}) {
4987
5010
  defer(ctx.on("llm/stream", (options, next) => {
4988
5011
  if (options.purpose || !options.sessionId) return next();
4989
5012
  const agent = ctx.agents.get(options.sessionId);
5013
+ if (agent) assertKernelRoute(adapter.servesAgent(agent), options);
4990
5014
  return agent && adapter.servesAgent(agent) ? adapter.stream(options) : next();
4991
5015
  }, {
4992
5016
  global: true,
4993
5017
  prepend: true
4994
5018
  }));
5019
+ defer(ctx.on("agent/pre-step", async ({ agent }, next) => {
5020
+ return adapter.admitStepMessages(agent, await next());
5021
+ }, {
5022
+ global: true,
5023
+ prepend: true
5024
+ }));
4995
5025
  defer(ctx.on("agent/created", ({ agent }) => {
4996
5026
  adapter.attachAgent(agent);
4997
5027
  }));
@@ -5126,7 +5156,8 @@ async function apply(ctx, config = {}) {
5126
5156
  requestTimeoutMs: config.codexRequestTimeoutMs,
5127
5157
  cwd: config.cwd,
5128
5158
  codexHome: launch.codexHome,
5129
- env: launch.env
5159
+ env: launch.env,
5160
+ behaviorDefaults: config.codexBehaviorDefaults
5130
5161
  }), createDshCodexPlugin(ctx, {
5131
5162
  ...config,
5132
5163
  codexHome: launch.codexHome