@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.
@@ -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
  }