@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.
- package/AGENTROUTER-FORK.md +1 -1
- package/docs/behavior-defaults.md +43 -0
- package/docs/context-admission.md +27 -0
- package/docs/kernel-policy.md +12 -0
- package/docs/transcript-presentation.md +20 -0
- package/lib/client.js +77 -0
- package/lib/client.js.map +1 -1
- package/lib/host-plugin.js +58 -27
- package/lib/host-plugin.js.map +1 -1
- package/package.json +8 -3
package/lib/host-plugin.js
CHANGED
|
@@ -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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 ??
|
|
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
|
-
|
|
2638
|
-
|
|
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 (
|
|
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
|
|
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
|