@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/AGENTROUTER-FORK.md
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Upstream: https://github.com/yangbobo2021/relay-dsh-plugin-codex.git @ 75918b3e06880df25375154321109f364124a544 (MIT).
|
|
4
4
|
|
|
5
|
-
Changes: version 1 generic codexHome/codexEnv launch interface, Codex 0.153.4, and package/build identity. No agent protocol, model picker, effort controls or tool implementation replaced.
|
|
5
|
+
Changes: version 1 generic codexHome/codexEnv launch interface, optional codexBehaviorDefaults=native (see docs/behavior-defaults.md), DSH pre-step context admission (see docs/context-admission.md), Codex 0.153.4, and package/build identity. No agent protocol, model picker, effort controls or tool implementation replaced.
|
|
6
6
|
|
|
7
7
|
Sources and checksummed contributions: https://github.com/Maybank01/agentrouter-dsh-plugins/tree/main/upstream/relay-codex
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Optional native behavior defaults
|
|
2
|
+
|
|
3
|
+
The public DSH host configuration accepts `codexBehaviorDefaults: "native"`.
|
|
4
|
+
Omitting it (or setting `"relay"`) preserves upstream Relay behavior. Unknown
|
|
5
|
+
values fail activation. This is independent of `codexExecutionMode`.
|
|
6
|
+
|
|
7
|
+
For a Codex-native agent that can still use DSH plugin tools, compose:
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
codexExecutionGuidance: false
|
|
11
|
+
codexBehaviorDefaults: native
|
|
12
|
+
# codexExecutionMode remains enhanced (the default).
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This omits Relay's fixed personality, collaboration mode and multi-agent mode
|
|
16
|
+
from ordinary thread/turn requests and from model/effort synchronization. It
|
|
17
|
+
does not replace these overrides with empty strings or null, and does not remove
|
|
18
|
+
Codex's own instructions, native mode defaults, AGENTS.md or Skills. Model/effort
|
|
19
|
+
choices, tool schemas, attachment context, permissions and cancellation stay on
|
|
20
|
+
their existing paths. Native configuration may itself select a personality or
|
|
21
|
+
mode; this switch does not force a different one.
|
|
22
|
+
|
|
23
|
+
With execution guidance disabled, ordinary conversations add no Relay developer
|
|
24
|
+
instructions and do not forward the combined DSH `options.system`. Plugin tool
|
|
25
|
+
descriptions/results still carry their necessary knowledge. This is **not** an
|
|
26
|
+
automatic bridge for all DSH preset prompts or plugin context messages. A future
|
|
27
|
+
knowledge/mode bridge needs explicit source and session scope, not a heuristic
|
|
28
|
+
that classifies arbitrary system text as knowledge. Do not use this option to
|
|
29
|
+
claim that unbridged DSH prompt contributions already reach Codex.
|
|
30
|
+
|
|
31
|
+
Explicit instructions supplied by a caller still work (including separate,
|
|
32
|
+
read-only auxiliary title/compaction threads); absent instruction fields are
|
|
33
|
+
omitted. User files and existing conversation history are never rewritten.
|
|
34
|
+
Previously injected guidance can remain in a resumed/forked conversation: use
|
|
35
|
+
a new conversation to evaluate the new defaults.
|
|
36
|
+
|
|
37
|
+
Implementation: `apply(ctx, config)` passes `behaviorDefaults` through the
|
|
38
|
+
existing execution plugin to `CodexSessionRuntime`. There is no Desktop API,
|
|
39
|
+
provider policy, extra AgentLoop or tool implementation here.
|
|
40
|
+
|
|
41
|
+
Protocol semantics: [official OpenAI App Server documentation](https://learn.chatgpt.com/docs/app-server).
|
|
42
|
+
In particular, `collaborationMode.settings.developer_instructions: null` selects
|
|
43
|
+
the mode's built-in instructions; it does not clear them.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Codex context admission
|
|
2
|
+
|
|
3
|
+
Relay uses DSH's public `agent/pre-step` waterfall to align newly recorded
|
|
4
|
+
context messages with the adapter's existing native-input source policy.
|
|
5
|
+
For the effective `relay-codex` preset, it awaits downstream decisions and
|
|
6
|
+
DSH's runtime snapshot, then removes messages from unsupported sources before
|
|
7
|
+
the loop appends them as `user/message` events. DSH's ordinary chat/trajectory
|
|
8
|
+
views therefore no longer label these unforwarded messages as injected.
|
|
9
|
+
|
|
10
|
+
Both admission and native input selection use the same source predicate:
|
|
11
|
+
user input and Relay's existing `source.plugin = "relay"` activation messages
|
|
12
|
+
are supported. Arbitrary DSH system/preset/plugin knowledge is still **not**
|
|
13
|
+
automatically bridged. This fix does not enable more prompt injection, change
|
|
14
|
+
the existing latest-input selection, or classify text heuristically.
|
|
15
|
+
|
|
16
|
+
The hook preserves accepted message identities/attachments, upstream rejection
|
|
17
|
+
decisions, request-series metadata and normal empty-step semantics. It follows
|
|
18
|
+
the effective preset after switching and leaves other agents untouched. It is
|
|
19
|
+
disposed with Relay. No Desktop/private API or extra plugin is needed, and
|
|
20
|
+
AgentRouter's authentication and Codex Home composition do not implement it.
|
|
21
|
+
|
|
22
|
+
This is admission for submission, not a receipt from the model: a later failed
|
|
23
|
+
network request is still a failed request. Historical session events and native
|
|
24
|
+
thread history are not rewritten; old misleading rows can remain in old chats.
|
|
25
|
+
The DSH assembled request header is not a native Codex prompt dump. Native
|
|
26
|
+
permissions, tools, behavior defaults and auxiliary requests keep their existing
|
|
27
|
+
paths. A future knowledge bridge must update this same admission/input contract.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Kernel/model consistency
|
|
2
|
+
|
|
3
|
+
Relay's `relay-codex` preset owns Codex execution. Primary calls from that
|
|
4
|
+
preset must explicitly select the `relay-codex` model route. Selecting another
|
|
5
|
+
route is an error, not permission to silently use the native default. A
|
|
6
|
+
non-Codex session cannot select the Codex route either. Auxiliary calls with
|
|
7
|
+
an explicit purpose retain their existing behavior.
|
|
8
|
+
|
|
9
|
+
This is a route-ownership check, not a GPT/DeepSeek model-name allowlist.
|
|
10
|
+
Native model and effort catalogs, permissions, tools and history stay upstream
|
|
11
|
+
owned. Product-only preset visibility and provider activation belong to the
|
|
12
|
+
deployment's ordinary DSH plugin/profile composition, not this generic adapter.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Codex transcript presentation
|
|
2
|
+
|
|
3
|
+
Relay hides the `permission` command row and the DSH `request/header.system`
|
|
4
|
+
chat row for sessions whose effective preset is `relay-codex`. This includes
|
|
5
|
+
replayed and failed turns; it does not depend on a successful Codex response.
|
|
6
|
+
The primary adapter does not forward DSH's `options.system` to Codex. Native
|
|
7
|
+
Codex instructions, explicitly admitted plugin context, and task-specific
|
|
8
|
+
auxiliary instructions are not affected by this presentation rule.
|
|
9
|
+
|
|
10
|
+
This uses the public `conversation.chat.commandview` permission specialization
|
|
11
|
+
and a leaf shadow of `conversation.chat.node/system-prompt`. Other commands,
|
|
12
|
+
tool approvals, turn errors and the original event log remain unchanged.
|
|
13
|
+
Other or unknown presets retain a permission disclosure built from the public
|
|
14
|
+
DSH primitive and the original system-prompt renderer. DSH does not export its
|
|
15
|
+
generic command card; Relay does not copy it or claim its child slots.
|
|
16
|
+
|
|
17
|
+
No Desktop patch, private DOM mutation, log deletion, authentication change or
|
|
18
|
+
permission-policy change is involved. Removing Relay restores native renderers.
|
|
19
|
+
Changes to the native system-prompt leaf contract fail open. If the primary
|
|
20
|
+
adapter starts forwarding system prompts in future, update this policy with it.
|
package/lib/client.js
CHANGED
|
@@ -36319,6 +36319,82 @@ window.__ModuleLoader__.load({
|
|
|
36319
36319
|
});
|
|
36320
36320
|
}
|
|
36321
36321
|
//#endregion
|
|
36322
|
+
//#region src/client/transcript-presentation.tsx
|
|
36323
|
+
function isCodexSession(state, sessionId) {
|
|
36324
|
+
return sessionPreset(state.byId[sessionId]) === "relay-codex";
|
|
36325
|
+
}
|
|
36326
|
+
/** Only the permission command seat is ours; all other commands stay with DSH. */
|
|
36327
|
+
function PermissionTranscriptRow({ sessionId, useSessions, node, t }) {
|
|
36328
|
+
const codex = useSessions((state) => isCodexSession(state, sessionId));
|
|
36329
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
36330
|
+
if (codex) return null;
|
|
36331
|
+
const failed = node.outcome?.kind === "error";
|
|
36332
|
+
const summary = node.outcome?.text ?? t(node.outcome === null ? "row.running" : failed ? "row.failed" : "ok");
|
|
36333
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.DisclosureRow, {
|
|
36334
|
+
title: "permission",
|
|
36335
|
+
open,
|
|
36336
|
+
expandable: true,
|
|
36337
|
+
expandOnRowClick: true,
|
|
36338
|
+
icon: failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "error" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconApiOutline14, { size: 14 }),
|
|
36339
|
+
onToggle: () => setOpen((value) => !value),
|
|
36340
|
+
keepContentWhenOpen: true,
|
|
36341
|
+
collapsedContent: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36342
|
+
style: {
|
|
36343
|
+
marginInlineStart: 8,
|
|
36344
|
+
whiteSpace: "pre-wrap"
|
|
36345
|
+
},
|
|
36346
|
+
children: summary
|
|
36347
|
+
}),
|
|
36348
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
36349
|
+
style: {
|
|
36350
|
+
whiteSpace: "pre-wrap",
|
|
36351
|
+
overflowWrap: "anywhere"
|
|
36352
|
+
},
|
|
36353
|
+
children: [node.args, summary].filter(Boolean).join("\n")
|
|
36354
|
+
})
|
|
36355
|
+
});
|
|
36356
|
+
}
|
|
36357
|
+
/** Presentation only: keep request headers, permission events and approvals intact. */
|
|
36358
|
+
function installTranscriptPresentation(ctx) {
|
|
36359
|
+
ctx.slots.inject("conversation.chat.commandview", () => {
|
|
36360
|
+
const locale = ctx.slots.entries("conversation.chat.node").find((entry) => entry.children?.["conversation.chat.commandview"])?.locale;
|
|
36361
|
+
if (locale !== "chat" && locale !== "conversation") return () => {};
|
|
36362
|
+
return ctx.slots.register({
|
|
36363
|
+
name: "conversation.chat.commandview",
|
|
36364
|
+
key: "permission",
|
|
36365
|
+
priority: -20,
|
|
36366
|
+
locale
|
|
36367
|
+
}, PermissionTranscriptRow);
|
|
36368
|
+
});
|
|
36369
|
+
ctx.slots.inject("conversation.chat.node", () => {
|
|
36370
|
+
let previous;
|
|
36371
|
+
let dispose;
|
|
36372
|
+
const reconcile = () => {
|
|
36373
|
+
const original = ctx.slots.entries("conversation.chat.node").find((entry) => entry.options.key === "system-prompt" && (entry.options.priority ?? 0) >= 0);
|
|
36374
|
+
if (original === previous) return;
|
|
36375
|
+
dispose?.();
|
|
36376
|
+
dispose = void 0;
|
|
36377
|
+
previous = original;
|
|
36378
|
+
if (!original || original.children || original.store || original.inject || original.locale !== "chat" && original.locale !== "conversation") return;
|
|
36379
|
+
const Original = original.component;
|
|
36380
|
+
dispose = ctx.slots.register({
|
|
36381
|
+
name: "conversation.chat.node",
|
|
36382
|
+
key: "system-prompt",
|
|
36383
|
+
priority: -20,
|
|
36384
|
+
locale: original.locale
|
|
36385
|
+
}, function CodexRequestPromptBoundary(props) {
|
|
36386
|
+
return props.useSessions((state) => isCodexSession(state, props.sessionId)) ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Original, { ...props });
|
|
36387
|
+
});
|
|
36388
|
+
};
|
|
36389
|
+
const unsubscribe = ctx.slots.subscribe("conversation.chat.node", reconcile);
|
|
36390
|
+
reconcile();
|
|
36391
|
+
return () => {
|
|
36392
|
+
unsubscribe();
|
|
36393
|
+
dispose?.();
|
|
36394
|
+
};
|
|
36395
|
+
});
|
|
36396
|
+
}
|
|
36397
|
+
//#endregion
|
|
36322
36398
|
//#region src/client/codex-activity.ts
|
|
36323
36399
|
const codexActivityDefinition = {
|
|
36324
36400
|
kind: "relay-codex-activity",
|
|
@@ -37092,6 +37168,7 @@ window.__ModuleLoader__.load({
|
|
|
37092
37168
|
return withConversationRuntime(ctx, (inner) => {
|
|
37093
37169
|
applyActivityPresentation(inner);
|
|
37094
37170
|
installProcessPresentation(inner, advancedDebug);
|
|
37171
|
+
installTranscriptPresentation(inner);
|
|
37095
37172
|
return installModelSelection(inner, "relay-codex", "relay-codex", "relay-claude");
|
|
37096
37173
|
});
|
|
37097
37174
|
}
|