@agentrouter-top/relay-dsh-plugin-codex 0.2.2-agentrouter.3 → 0.2.2-agentrouter.5
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/docs/presentation-policy.md +29 -0
- package/docs/quiet-activity.md +17 -0
- package/lib/client.js +268 -33
- package/lib/client.js.map +1 -1
- package/package.json +14 -4
- package/presentation-api.d.mts +20 -0
- package/presentation-api.mjs +25 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Optional Codex presentation policy, version 1
|
|
2
|
+
|
|
3
|
+
Relay owns Codex event projection, process/transcript presentation, kernel labels,
|
|
4
|
+
blank-session preset selection and the native model seat guard. Integration
|
|
5
|
+
plugins configure the browser Cordis service `relayCodexPresentation`; they do
|
|
6
|
+
not render Codex components. Types are exported from the `./presentation` subpath.
|
|
7
|
+
|
|
8
|
+
Wait for the service with `ctx.inject(['relayCodexPresentation'], ...)`, check
|
|
9
|
+
`version === 1`, then call `configure({ kernelMode: 'codex-only', hideFeedback:
|
|
10
|
+
true, hideStatistics: true })`. Register the returned disposer with the owner's
|
|
11
|
+
lifecycle. Only one configuration owner is accepted. Dispose before reconfiguring.
|
|
12
|
+
Without configuration Relay retains its upstream coexistence UI.
|
|
13
|
+
|
|
14
|
+
`kernelMode` defaults to `coexist`. `codex-only` enables the Codex label/settings,
|
|
15
|
+
selects Codex only for blank sessions through the public preset transaction, and
|
|
16
|
+
guards the existing DSH model picker. The integrating host remains responsible
|
|
17
|
+
for enforcing its execution policy. Existing sessions/presets are not deleted or
|
|
18
|
+
retargeted. Model catalogs and effort controls remain upstream implementations.
|
|
19
|
+
|
|
20
|
+
`hideFeedback` and `hideStatistics` default to false. They shadow only the native
|
|
21
|
+
feedback/statistics public leaf slots for the rendered Codex session. Other
|
|
22
|
+
kernels and other plugins' entries remain unchanged. Changed/unknown leaf
|
|
23
|
+
contracts are left visible. Unloading or disposing restores native entries.
|
|
24
|
+
|
|
25
|
+
The current DSH turn-tail component has no separate public switch for its copy,
|
|
26
|
+
branch, timing and timestamp actions. Version 1 does **not** hide that parent:
|
|
27
|
+
it also owns deliverable child slots. No private DOM/CSS manipulation, event
|
|
28
|
+
rewriting or DSH component fork is used. Files, errors, approvals and history are
|
|
29
|
+
unaffected. Account credentials and runtime launch options never enter this API.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Quiet Codex activity presentation
|
|
2
|
+
|
|
3
|
+
Individual tool attempts do not raise user-facing failure warnings. Relay uses
|
|
4
|
+
neutral action labels for failed/nonzero-exit activities, with no warning
|
|
5
|
+
triangle, failed counter, error dot or outcome badge. Active work still shows
|
|
6
|
+
its progress indicator. No failure is relabelled as success.
|
|
7
|
+
|
|
8
|
+
Expanding a row still exposes its original input, output, provenance and exit
|
|
9
|
+
code. This is a rendering policy only: native App Server results, DSH events,
|
|
10
|
+
permissions, approvals, retries and saved history are unchanged. Codex continues
|
|
11
|
+
to receive the real result and decide how to proceed. Turn-level errors and
|
|
12
|
+
requests that require user action remain visible on their existing paths.
|
|
13
|
+
|
|
14
|
+
This policy covers Relay's grouped process, native-tool fallback and legacy
|
|
15
|
+
activity row. It uses Relay components and public DSH UI primitives only; the
|
|
16
|
+
AgentRouter main plugin merely pins the updated Relay package. No Desktop or
|
|
17
|
+
other kernel renderer is modified.
|
package/lib/client.js
CHANGED
|
@@ -32123,7 +32123,7 @@ window.__ModuleLoader__.load({
|
|
|
32123
32123
|
key: "1qoq8a"
|
|
32124
32124
|
}]
|
|
32125
32125
|
]);
|
|
32126
|
-
|
|
32126
|
+
createLucideIcon("triangle-alert", [
|
|
32127
32127
|
["path", {
|
|
32128
32128
|
d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
|
|
32129
32129
|
key: "wmoenq"
|
|
@@ -34871,7 +34871,6 @@ window.__ModuleLoader__.load({
|
|
|
34871
34871
|
exports.LoaderCircle = LoaderCircle;
|
|
34872
34872
|
exports.Search = Search;
|
|
34873
34873
|
exports.Terminal = Terminal;
|
|
34874
|
-
exports.TriangleAlert = TriangleAlert;
|
|
34875
34874
|
exports.Wrench = Wrench;
|
|
34876
34875
|
})))();
|
|
34877
34876
|
const CODEX_ACTIVITY_TOOL = "relay_codex_activity";
|
|
@@ -35142,10 +35141,10 @@ window.__ModuleLoader__.load({
|
|
|
35142
35141
|
function summarizeParts(parts) {
|
|
35143
35142
|
const groups = /* @__PURE__ */ new Map();
|
|
35144
35143
|
for (const part of parts) {
|
|
35144
|
+
const displayState = part.state === "error" || part.state === "exited" ? "attempt" : part.state;
|
|
35145
35145
|
const key = JSON.stringify([
|
|
35146
35146
|
part.category,
|
|
35147
|
-
|
|
35148
|
-
part.exitCode,
|
|
35147
|
+
displayState,
|
|
35149
35148
|
part.category === "unknown" ? part.label : null
|
|
35150
35149
|
]);
|
|
35151
35150
|
const group = groups.get(key) ?? [];
|
|
@@ -35184,17 +35183,15 @@ window.__ModuleLoader__.load({
|
|
|
35184
35183
|
if (part.label) {
|
|
35185
35184
|
const suffix = {
|
|
35186
35185
|
running: " (running)",
|
|
35187
|
-
error: " (failed)",
|
|
35188
35186
|
unknown: " (status unknown)"
|
|
35189
35187
|
}[part.state] ?? "";
|
|
35190
35188
|
return `${short(part.label, 120)}${part.count > 1 ? ` (${part.count} activities)` : ""}${suffix}`;
|
|
35191
35189
|
}
|
|
35192
|
-
const [present, past,
|
|
35190
|
+
const [present, past, , neutral] = verbs[part.category];
|
|
35193
35191
|
const subject = short(part.subject);
|
|
35194
35192
|
if (part.state === "running") return `${present} ${subject}`;
|
|
35195
35193
|
if (part.state === "completed") return `${past} ${subject}`;
|
|
35196
|
-
if (part.state === "error") return
|
|
35197
|
-
if (part.state === "exited") return `${neutral} exited ${part.exitCode}: ${subject}`;
|
|
35194
|
+
if (part.state === "error" || part.state === "exited") return `${neutral}: ${subject}`;
|
|
35198
35195
|
return `${neutral} (status unknown): ${subject}`;
|
|
35199
35196
|
}
|
|
35200
35197
|
function basename(path) {
|
|
@@ -35789,11 +35786,6 @@ window.__ModuleLoader__.load({
|
|
|
35789
35786
|
};
|
|
35790
35787
|
//#endregion
|
|
35791
35788
|
//#region src/client/CodexActivityView.tsx
|
|
35792
|
-
function dotState(status) {
|
|
35793
|
-
if (status === "running") return "ongoing";
|
|
35794
|
-
if (status === "error") return "error";
|
|
35795
|
-
return "done";
|
|
35796
|
-
}
|
|
35797
35789
|
function ActivityIcon({ category }) {
|
|
35798
35790
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(category === "read" ? import_lucide_react.BookOpen : category === "search" || category === "webSearch" ? import_lucide_react.Search : category === "listFiles" ? import_lucide_react.FolderOpen : category === "edit" ? import_lucide_react.FilePenLine : category === "image" || category === "imageGeneration" ? import_lucide_react.Image : category === "plan" ? import_lucide_react.ListChecks : category === "command" ? import_lucide_react.Terminal : import_lucide_react.Wrench, {
|
|
35799
35791
|
size: 16,
|
|
@@ -35864,8 +35856,8 @@ window.__ModuleLoader__.load({
|
|
|
35864
35856
|
expandOnRowClick: true,
|
|
35865
35857
|
collapsedContent: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
35866
35858
|
className: CodexActivityView_module_css_default.summary,
|
|
35867
|
-
children: activity.status
|
|
35868
|
-
state:
|
|
35859
|
+
children: activity.status === "running" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
|
|
35860
|
+
state: "ongoing",
|
|
35869
35861
|
size: 8
|
|
35870
35862
|
}) : null
|
|
35871
35863
|
}),
|
|
@@ -35892,10 +35884,10 @@ window.__ModuleLoader__.load({
|
|
|
35892
35884
|
label: "Output",
|
|
35893
35885
|
text: activity.output
|
|
35894
35886
|
}) : null] }),
|
|
35895
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
35887
|
+
activity.exitCode !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
35896
35888
|
className: CodexActivityView_module_css_default.footer,
|
|
35897
|
-
children:
|
|
35898
|
-
})
|
|
35889
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["exit ", activity.exitCode] })
|
|
35890
|
+
}) : null
|
|
35899
35891
|
]
|
|
35900
35892
|
})
|
|
35901
35893
|
})
|
|
@@ -35910,11 +35902,6 @@ window.__ModuleLoader__.load({
|
|
|
35910
35902
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: text })]
|
|
35911
35903
|
});
|
|
35912
35904
|
}
|
|
35913
|
-
function statusLabel(status) {
|
|
35914
|
-
if (status === "running") return "Running";
|
|
35915
|
-
if (status === "error") return "Failed";
|
|
35916
|
-
return "Success";
|
|
35917
|
-
}
|
|
35918
35905
|
function shortId(value) {
|
|
35919
35906
|
return value.length > 15 ? `${value.slice(0, 8)}...${value.slice(-4)}` : value;
|
|
35920
35907
|
}
|
|
@@ -36146,7 +36133,6 @@ window.__ModuleLoader__.load({
|
|
|
36146
36133
|
const [open, setOpen] = (0, react.useState)(false);
|
|
36147
36134
|
const activities = segments.flatMap((segment) => segment.activity ? [segment.activity] : []);
|
|
36148
36135
|
const active = activities.filter((activity) => activity.status === "running");
|
|
36149
|
-
const failed = activities.filter((activity) => activity.status === "error").length;
|
|
36150
36136
|
const current = active.at(-1);
|
|
36151
36137
|
const representative = current ?? activities.at(-1);
|
|
36152
36138
|
if (!representative) return null;
|
|
@@ -36179,15 +36165,6 @@ window.__ModuleLoader__.load({
|
|
|
36179
36165
|
className: CodexProcessView_module_css_default.count,
|
|
36180
36166
|
children: [active.length, " running"]
|
|
36181
36167
|
}),
|
|
36182
|
-
failed > 0 && current && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
36183
|
-
className: CodexProcessView_module_css_default.error,
|
|
36184
|
-
children: [failed, " failed"]
|
|
36185
|
-
}),
|
|
36186
|
-
failed > 0 && !current && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.TriangleAlert, {
|
|
36187
|
-
size: 14,
|
|
36188
|
-
className: CodexProcessView_module_css_default.error,
|
|
36189
|
-
"aria-label": "Failed"
|
|
36190
|
-
}),
|
|
36191
36168
|
open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ChevronDown, { size: 14 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ChevronRight, { size: 14 })
|
|
36192
36169
|
]
|
|
36193
36170
|
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -36395,6 +36372,263 @@ window.__ModuleLoader__.load({
|
|
|
36395
36372
|
});
|
|
36396
36373
|
}
|
|
36397
36374
|
//#endregion
|
|
36375
|
+
//#region presentation-api.mjs
|
|
36376
|
+
/** Public, optional browser presentation policy. No account/runtime configuration. */
|
|
36377
|
+
function createPresentationController(install) {
|
|
36378
|
+
let active;
|
|
36379
|
+
return {
|
|
36380
|
+
service: Object.freeze({
|
|
36381
|
+
version: 1,
|
|
36382
|
+
configure(options = {}) {
|
|
36383
|
+
if (active) throw new Error("Relay Codex presentation already has a configuration owner");
|
|
36384
|
+
const { kernelMode = "coexist", hideFeedback = false, hideStatistics = false } = options;
|
|
36385
|
+
if (!["coexist", "codex-only"].includes(kernelMode) || typeof hideFeedback !== "boolean" || typeof hideStatistics !== "boolean" || Object.keys(options).some((key) => ![
|
|
36386
|
+
"kernelMode",
|
|
36387
|
+
"hideFeedback",
|
|
36388
|
+
"hideStatistics"
|
|
36389
|
+
].includes(key))) throw new TypeError("Unsupported Relay Codex presentation policy");
|
|
36390
|
+
const remove = install(Object.freeze({
|
|
36391
|
+
kernelMode,
|
|
36392
|
+
hideFeedback,
|
|
36393
|
+
hideStatistics
|
|
36394
|
+
}));
|
|
36395
|
+
const release = () => {
|
|
36396
|
+
if (active !== release) return;
|
|
36397
|
+
active = void 0;
|
|
36398
|
+
remove();
|
|
36399
|
+
};
|
|
36400
|
+
active = release;
|
|
36401
|
+
return release;
|
|
36402
|
+
}
|
|
36403
|
+
}),
|
|
36404
|
+
dispose: () => active?.()
|
|
36405
|
+
};
|
|
36406
|
+
}
|
|
36407
|
+
//#endregion
|
|
36408
|
+
//#region src/client/kernel-presentation.tsx
|
|
36409
|
+
const CODEX_PRESET = "relay-codex";
|
|
36410
|
+
const UNSUPPORTED_KERNEL = "当前会话不是 Codex 内核。此客户端暂不支持执行,请新建 Codex 会话;原会话和历史记录会保留。";
|
|
36411
|
+
const isCodex = (session) => sessionPreset(session) === CODEX_PRESET;
|
|
36412
|
+
function KernelSection() {
|
|
36413
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
36414
|
+
style: {
|
|
36415
|
+
maxWidth: 600,
|
|
36416
|
+
lineHeight: 1.7
|
|
36417
|
+
},
|
|
36418
|
+
"aria-label": "执行内核",
|
|
36419
|
+
children: [
|
|
36420
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: "执行内核" }),
|
|
36421
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "当前产品仅支持 Codex App Server。" }),
|
|
36422
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "模型、思考强度、工具和执行行为由 Codex 适配器提供。原生 DSH / DeepSeek 内核暂不提供执行入口。" }),
|
|
36423
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "已有预设、自建预设和会话没有被删除;非 Codex 历史仍可查看。通用插件的共存模式不限制宿主的其他内核。" })
|
|
36424
|
+
]
|
|
36425
|
+
});
|
|
36426
|
+
}
|
|
36427
|
+
function KernelLabel({ sessionId, useSessions }) {
|
|
36428
|
+
const codex = useSessions((state) => isCodex(state.byId[sessionId]));
|
|
36429
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36430
|
+
role: "status",
|
|
36431
|
+
"data-relay-codex-kernel": codex ? "codex" : "unsupported",
|
|
36432
|
+
style: {
|
|
36433
|
+
fontSize: 12,
|
|
36434
|
+
lineHeight: 1.4,
|
|
36435
|
+
maxWidth: "min(65vw, 440px)",
|
|
36436
|
+
whiteSpace: "normal"
|
|
36437
|
+
},
|
|
36438
|
+
title: codex ? "Codex App Server 执行内核" : UNSUPPORTED_KERNEL,
|
|
36439
|
+
children: codex ? "Codex" : "非 Codex 内核 · 当前不支持执行,请新建 Codex 会话"
|
|
36440
|
+
});
|
|
36441
|
+
}
|
|
36442
|
+
function KernelModelSeat({ Upstream, ...props }) {
|
|
36443
|
+
return props.useSessions((state) => isCodex(state.byId[props.sessionId])) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Upstream, { ...props }) : null;
|
|
36444
|
+
}
|
|
36445
|
+
function installModelSeatGuard(ctx) {
|
|
36446
|
+
const slot = "conversation.input.model";
|
|
36447
|
+
let source, release;
|
|
36448
|
+
const reconcile = () => {
|
|
36449
|
+
const next = ctx.slots.entries(slot).find((entry) => entry.locale === "model" && (entry.options.priority ?? 0) === 0);
|
|
36450
|
+
if (next === source) return;
|
|
36451
|
+
source = next;
|
|
36452
|
+
const previous = release;
|
|
36453
|
+
release = void 0;
|
|
36454
|
+
previous?.();
|
|
36455
|
+
if (!next?.inject || next.children || next.store) return;
|
|
36456
|
+
const original = next.inject;
|
|
36457
|
+
release = ctx.slots.register({
|
|
36458
|
+
name: slot,
|
|
36459
|
+
priority: -50,
|
|
36460
|
+
locale: "model",
|
|
36461
|
+
inject: (sessionId) => {
|
|
36462
|
+
const face = original(sessionId);
|
|
36463
|
+
return {
|
|
36464
|
+
...face,
|
|
36465
|
+
Upstream: next.component,
|
|
36466
|
+
select: (selection) => isCodex(ctx.sessions.list.getSnapshot().byId[sessionId]) ? face.select(selection) : Promise.resolve(false)
|
|
36467
|
+
};
|
|
36468
|
+
}
|
|
36469
|
+
}, KernelModelSeat);
|
|
36470
|
+
};
|
|
36471
|
+
const stop = ctx.slots.subscribe(slot, reconcile);
|
|
36472
|
+
reconcile();
|
|
36473
|
+
return () => {
|
|
36474
|
+
stop();
|
|
36475
|
+
release?.();
|
|
36476
|
+
};
|
|
36477
|
+
}
|
|
36478
|
+
function CodexSeat({ useSessions, selectCodex }) {
|
|
36479
|
+
const session = useSessions((state) => state.current === void 0 ? void 0 : state.byId[state.current]);
|
|
36480
|
+
const id = session?.id;
|
|
36481
|
+
const preset = sessionPreset(session), blank = session?.blank;
|
|
36482
|
+
const [failure, setFailure] = (0, react.useState)();
|
|
36483
|
+
const [attempt, setAttempt] = (0, react.useState)(0);
|
|
36484
|
+
(0, react.useEffect)(() => {
|
|
36485
|
+
if (!id || !blank || preset === CODEX_PRESET) return;
|
|
36486
|
+
let stopped = false;
|
|
36487
|
+
setFailure(void 0);
|
|
36488
|
+
selectCodex(id).then((message) => {
|
|
36489
|
+
if (!stopped && message) setFailure({
|
|
36490
|
+
id,
|
|
36491
|
+
message
|
|
36492
|
+
});
|
|
36493
|
+
}).catch((error) => {
|
|
36494
|
+
if (!stopped) setFailure({
|
|
36495
|
+
id,
|
|
36496
|
+
message: error instanceof Error ? error.message : "无法选择 Codex 预设,请重试。"
|
|
36497
|
+
});
|
|
36498
|
+
});
|
|
36499
|
+
return () => {
|
|
36500
|
+
stopped = true;
|
|
36501
|
+
};
|
|
36502
|
+
}, [
|
|
36503
|
+
id,
|
|
36504
|
+
blank,
|
|
36505
|
+
preset,
|
|
36506
|
+
selectCodex,
|
|
36507
|
+
attempt
|
|
36508
|
+
]);
|
|
36509
|
+
const error = preset !== CODEX_PRESET && failure?.id === id ? failure?.message : void 0;
|
|
36510
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
36511
|
+
style: {
|
|
36512
|
+
fontSize: 13,
|
|
36513
|
+
maxWidth: "60vw"
|
|
36514
|
+
},
|
|
36515
|
+
"aria-label": "Codex 执行内核",
|
|
36516
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36517
|
+
role: "status",
|
|
36518
|
+
children: !id || preset === CODEX_PRESET ? "Codex" : error ? "Codex 未就绪" : "正在准备 Codex…"
|
|
36519
|
+
}), error && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
36520
|
+
role: "alert",
|
|
36521
|
+
children: [
|
|
36522
|
+
error,
|
|
36523
|
+
" ",
|
|
36524
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36525
|
+
type: "button",
|
|
36526
|
+
onClick: () => setAttempt((value) => value + 1),
|
|
36527
|
+
children: "重试"
|
|
36528
|
+
})
|
|
36529
|
+
]
|
|
36530
|
+
})]
|
|
36531
|
+
});
|
|
36532
|
+
}
|
|
36533
|
+
/** Opt-in single-kernel product UI. Never retarget or delete existing history. */
|
|
36534
|
+
function installExclusiveKernelPresentation(ctx) {
|
|
36535
|
+
const selectCodex = async (id) => {
|
|
36536
|
+
const session = ctx.sessions.list.getSnapshot().byId[id];
|
|
36537
|
+
if (!session?.blank || isCodex(session)) return;
|
|
36538
|
+
const result = await ctx.remote.agentPresets.select(id, CODEX_PRESET);
|
|
36539
|
+
return result.ok ? void 0 : `${result.error.code}: ${result.error.message}`;
|
|
36540
|
+
};
|
|
36541
|
+
const releases = [];
|
|
36542
|
+
const dispose = () => {
|
|
36543
|
+
while (releases.length) releases.pop()();
|
|
36544
|
+
};
|
|
36545
|
+
try {
|
|
36546
|
+
releases.push(ctx.slots.inject("conversation.input.model", () => installModelSeatGuard(ctx)));
|
|
36547
|
+
releases.push(ctx.slots.inject("conversation.hero.agentPreset", () => ctx.slots.register({
|
|
36548
|
+
name: "conversation.hero.agentPreset",
|
|
36549
|
+
priority: -50,
|
|
36550
|
+
inject: () => ({ selectCodex })
|
|
36551
|
+
}, CodexSeat)));
|
|
36552
|
+
releases.push(ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
36553
|
+
name: "settings.section",
|
|
36554
|
+
id: "relay-codex-kernels",
|
|
36555
|
+
order: 20,
|
|
36556
|
+
label: () => "执行内核"
|
|
36557
|
+
}, KernelSection)));
|
|
36558
|
+
releases.push(ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
36559
|
+
name: "conversation.session.header.actions",
|
|
36560
|
+
id: "relay-codex-kernel",
|
|
36561
|
+
order: -10
|
|
36562
|
+
}, KernelLabel)));
|
|
36563
|
+
return dispose;
|
|
36564
|
+
} catch (error) {
|
|
36565
|
+
dispose();
|
|
36566
|
+
throw error;
|
|
36567
|
+
}
|
|
36568
|
+
}
|
|
36569
|
+
//#endregion
|
|
36570
|
+
//#region src/client/presentation.tsx
|
|
36571
|
+
function NativeNonCodexLeaf({ Upstream, ...props }) {
|
|
36572
|
+
return props.useSessions((state) => sessionPreset(state.byId[props.sessionId]) === "relay-codex") ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Upstream, { ...props });
|
|
36573
|
+
}
|
|
36574
|
+
/** Shadow only a known public leaf. Parent ownership and unrelated entries stay intact. */
|
|
36575
|
+
function hideNativeLeaf(ctx, name, id) {
|
|
36576
|
+
return ctx.slots.inject(name, () => {
|
|
36577
|
+
let source, release;
|
|
36578
|
+
const reconcile = () => {
|
|
36579
|
+
const next = ctx.slots.entries(name).find((entry) => entry.options.id === id && (entry.options.priority ?? 0) === 0);
|
|
36580
|
+
if (next === source) return;
|
|
36581
|
+
source = next;
|
|
36582
|
+
const previous = release;
|
|
36583
|
+
release = void 0;
|
|
36584
|
+
previous?.();
|
|
36585
|
+
if (!next || next.children || next.store) return;
|
|
36586
|
+
if (name === "conversation.composer.dock" && next.inject) return;
|
|
36587
|
+
if (next.locale !== void 0 && next.locale !== "chat" && next.locale !== "conversation" && next.locale !== "feedback") return;
|
|
36588
|
+
const originalInject = next.inject;
|
|
36589
|
+
release = ctx.slots.register({
|
|
36590
|
+
name,
|
|
36591
|
+
id,
|
|
36592
|
+
priority: -50,
|
|
36593
|
+
order: next.options.order,
|
|
36594
|
+
locale: next.locale,
|
|
36595
|
+
inject: (sessionId) => ({
|
|
36596
|
+
...originalInject?.(sessionId),
|
|
36597
|
+
Upstream: next.component
|
|
36598
|
+
})
|
|
36599
|
+
}, NativeNonCodexLeaf);
|
|
36600
|
+
};
|
|
36601
|
+
const stop = ctx.slots.subscribe(name, reconcile);
|
|
36602
|
+
reconcile();
|
|
36603
|
+
return () => {
|
|
36604
|
+
stop();
|
|
36605
|
+
release?.();
|
|
36606
|
+
};
|
|
36607
|
+
});
|
|
36608
|
+
}
|
|
36609
|
+
function installPresentationPolicy(ctx, options) {
|
|
36610
|
+
const releases = [];
|
|
36611
|
+
const dispose = () => {
|
|
36612
|
+
while (releases.length) releases.pop()();
|
|
36613
|
+
};
|
|
36614
|
+
try {
|
|
36615
|
+
if (options.kernelMode === "codex-only") releases.push(installExclusiveKernelPresentation(ctx));
|
|
36616
|
+
if (options.hideStatistics) releases.push(hideNativeLeaf(ctx, "conversation.composer.dock", "stats"));
|
|
36617
|
+
if (options.hideFeedback) releases.push(hideNativeLeaf(ctx, "conversation.chat.assistant-actions", "feedback"));
|
|
36618
|
+
return dispose;
|
|
36619
|
+
} catch (error) {
|
|
36620
|
+
dispose();
|
|
36621
|
+
throw error;
|
|
36622
|
+
}
|
|
36623
|
+
}
|
|
36624
|
+
function installPresentationService(ctx) {
|
|
36625
|
+
ctx.inject(["remote", "remote.agentPresets"], (scope) => {
|
|
36626
|
+
const controller = createPresentationController((options) => installPresentationPolicy(scope, options));
|
|
36627
|
+
scope.effect(() => controller.dispose, "relay-codex: optional presentation policy");
|
|
36628
|
+
scope.provide("relayCodexPresentation", controller.service);
|
|
36629
|
+
});
|
|
36630
|
+
}
|
|
36631
|
+
//#endregion
|
|
36398
36632
|
//#region src/client/codex-activity.ts
|
|
36399
36633
|
const codexActivityDefinition = {
|
|
36400
36634
|
kind: "relay-codex-activity",
|
|
@@ -37161,6 +37395,7 @@ window.__ModuleLoader__.load({
|
|
|
37161
37395
|
"connection"
|
|
37162
37396
|
];
|
|
37163
37397
|
function apply(ctx) {
|
|
37398
|
+
installPresentationService(ctx);
|
|
37164
37399
|
const advancedDebug = applyAdvancedDebug(ctx);
|
|
37165
37400
|
applyWorkspaceImport(ctx);
|
|
37166
37401
|
applySessionOpenSync(ctx);
|