@agentrouter-top/relay-dsh-plugin-codex 0.2.2-agentrouter.5 → 0.2.2-agentrouter.7
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/codex-activity-wire.mjs +5 -0
- package/docs/image-generation-presentation.md +19 -0
- package/docs/image-motion.md +19 -0
- package/lib/client.js +315 -39
- package/lib/client.js.map +1 -1
- package/lib/host-plugin.js +24 -5
- package/lib/host-plugin.js.map +1 -1
- package/package.json +4 -2
package/codex-activity-wire.mjs
CHANGED
|
@@ -12,5 +12,10 @@ export function readActivityPayload(value) {
|
|
|
12
12
|
for (const key of ["summary", "input", "output", "exitCode", "commandActions"]) {
|
|
13
13
|
if (activity[key] !== undefined && typeof activity[key] !== "string") return null;
|
|
14
14
|
}
|
|
15
|
+
if (activity.imageGeneration !== undefined) {
|
|
16
|
+
const image = activity.imageGeneration;
|
|
17
|
+
if (activity.type !== "imageGeneration" || !image || typeof image !== "object" || image.version !== 1
|
|
18
|
+
|| (image.attachmentId !== undefined && (typeof image.attachmentId !== "string" || !image.attachmentId))) return null;
|
|
19
|
+
}
|
|
15
20
|
return value;
|
|
16
21
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Image generation presentation v1
|
|
2
|
+
|
|
3
|
+
Relay projects native Codex `imageGeneration` item start/completion into a dot-matrix
|
|
4
|
+
waiting frame. This is not a partial image, estimated progress, or a new image tool.
|
|
5
|
+
Only a successful attachment import associates `activity.imageGeneration.attachmentId`
|
|
6
|
+
with the existing DSH image block. Projection matches that exact ID within the same
|
|
7
|
+
DSH step, keeps the generation key, and consumes only the matched image occurrence.
|
|
8
|
+
Parallel images cannot be paired by arrival order. Old activity without this optional
|
|
9
|
+
version-1 metadata, MCP images and image-view results keep their existing renderers.
|
|
10
|
+
|
|
11
|
+
The enhanced Codex process projection owns the frame. Native/fallback DSH transcripts
|
|
12
|
+
retain their tool and image rows. Failure/interruption stops the animation without
|
|
13
|
+
adding a warning badge; existing actual turn errors remain available. Reduced-motion
|
|
14
|
+
uses a static dot field. The final result uses DSH's public `renderMessageImages`, so
|
|
15
|
+
the independent Viewer plugin continues to handle viewing and downloading.
|
|
16
|
+
|
|
17
|
+
No Codex prompt, gateway, credentials, tool implementation, Desktop code, or session
|
|
18
|
+
history is modified. Image URLs and private filesystem paths are not added to the
|
|
19
|
+
presentation metadata.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Image generation motion
|
|
2
|
+
|
|
3
|
+
Relay owns the approved iridescent dot field and the native-image reveal. This
|
|
4
|
+
is an indeterminate status, not server progress. No model, tool, authentication,
|
|
5
|
+
attachment import, Viewer or Desktop behavior is changed.
|
|
6
|
+
|
|
7
|
+
The pending card is 4:3 and at most 480 px wide. Six interpolated colors and a
|
|
8
|
+
soft moving ribbon replace the grey grid. Light/dark mode comes exclusively
|
|
9
|
+
from the public DSH theme service. No host DOM probing or additional dependency.
|
|
10
|
+
Canvas updates are imperative, at most about 33 paints per second, DPR capped
|
|
11
|
+
at 2. Hidden/offscreen/reduced-motion frames do not animate; completion, failure,
|
|
12
|
+
interruption and unmount dispose subscriptions. Document/media listeners are
|
|
13
|
+
shared across pending images.
|
|
14
|
+
|
|
15
|
+
Generated frames stay mounted when process details collapse. Completion fades
|
|
16
|
+
the field into DSH's native image renderer without duplicate attachments. The
|
|
17
|
+
actual result keeps its native aspect ratio and Viewer actions. History opens
|
|
18
|
+
immediately without replaying the animation. Design-preview palette/demo
|
|
19
|
+
controls and synthetic images are not shipped.
|
package/lib/client.js
CHANGED
|
@@ -193,13 +193,13 @@ window.__ModuleLoader__.load({
|
|
|
193
193
|
}
|
|
194
194
|
//#endregion
|
|
195
195
|
//#region \0relay-css-module:.\src\client\AdvancedDebug.module.css.mjs
|
|
196
|
-
const css$
|
|
197
|
-
const tagId$
|
|
198
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
196
|
+
const css$4 = ".Y4qSZW_section{width:100%;max-width:780px;color:var(--dsw-alias-label-primary)}.Y4qSZW_settingRow{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;gap:20px;min-height:58px;padding:8px 0;display:flex}.Y4qSZW_statusRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:flex-start;gap:10px;min-height:70px;padding:10px 0;display:flex}.Y4qSZW_statusDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:8px;height:8px;margin-top:6px}.Y4qSZW_statusRow[data-codex-status=connected] .Y4qSZW_statusDot{background:#27a65b}.Y4qSZW_statusRow[data-codex-status=connection-failed] .Y4qSZW_statusDot,.Y4qSZW_statusRow[data-codex-status=unavailable] .Y4qSZW_statusDot,.Y4qSZW_statusRow[data-codex-status=rebind-required] .Y4qSZW_statusDot{background:#d94841}.Y4qSZW_settingCopy code{color:var(--dsw-alias-label-tertiary);font-size:11px}.Y4qSZW_statusBadge{border-radius:999px;padding:2px 7px;font-size:11px;font-weight:600;line-height:16px}.Y4qSZW_statusError{color:#d94841;background:#d9484124}.Y4qSZW_statusRebind{color:#a95d00;background:#c26a0029}.Y4qSZW_settingCopy{flex-direction:column;gap:2px;min-width:0;display:flex}.Y4qSZW_settingCopy strong{font-size:14px;font-weight:500;line-height:20px}.Y4qSZW_settingCopy span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.Y4qSZW_switch{cursor:pointer;flex:none;width:36px;height:20px;display:inline-flex;position:relative}.Y4qSZW_switch input{opacity:0;width:1px;height:1px;position:absolute}.Y4qSZW_switch span{background:var(--dsw-alias-fill-l2);border-radius:10px;width:100%;transition:background-color .12s}.Y4qSZW_switch span:after{background:var(--dsw-alias-bg-layer-1);content:\"\";border-radius:50%;width:16px;height:16px;transition:transform .12s;position:absolute;top:2px;left:2px;box-shadow:0 1px 3px #0003}.Y4qSZW_switch input:checked+span{background:var(--dsw-alias-state-business-primary)}.Y4qSZW_switch input:checked+span:after{transform:translate(16px)}.Y4qSZW_switch input:focus-visible+span{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}.Y4qSZW_marker{display:none}[data-relay-simple-conversation=true] [role=tablist]{display:none}";
|
|
197
|
+
const tagId$4 = "@agentrouter-top/relay-dsh-plugin-codex/AdvancedDebug.module.css";
|
|
198
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
199
199
|
const tag = document.createElement("style");
|
|
200
200
|
tag.dataset.plugin = "@agentrouter-top/relay-dsh-plugin-codex";
|
|
201
|
-
tag.dataset.pluginCss = tagId$
|
|
202
|
-
tag.textContent = css$
|
|
201
|
+
tag.dataset.pluginCss = tagId$4;
|
|
202
|
+
tag.textContent = css$4;
|
|
203
203
|
document.head.appendChild(tag);
|
|
204
204
|
}
|
|
205
205
|
var AdvancedDebug_module_css_default = {
|
|
@@ -34889,6 +34889,10 @@ window.__ModuleLoader__.load({
|
|
|
34889
34889
|
"exitCode",
|
|
34890
34890
|
"commandActions"
|
|
34891
34891
|
]) if (activity[key] !== void 0 && typeof activity[key] !== "string") return null;
|
|
34892
|
+
if (activity.imageGeneration !== void 0) {
|
|
34893
|
+
const image = activity.imageGeneration;
|
|
34894
|
+
if (activity.type !== "imageGeneration" || !image || typeof image !== "object" || image.version !== 1 || image.attachmentId !== void 0 && (typeof image.attachmentId !== "string" || !image.attachmentId)) return null;
|
|
34895
|
+
}
|
|
34892
34896
|
return value;
|
|
34893
34897
|
}
|
|
34894
34898
|
//#endregion
|
|
@@ -35213,13 +35217,13 @@ window.__ModuleLoader__.load({
|
|
|
35213
35217
|
}
|
|
35214
35218
|
//#endregion
|
|
35215
35219
|
//#region \0relay-css-module:.\src\client\CodexActivityView.module.css.mjs
|
|
35216
|
-
const css$
|
|
35217
|
-
const tagId$
|
|
35218
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
35220
|
+
const css$3 = ".jIHzgW_activity{width:min(100%,960px);color:var(--dsw-alias-label-secondary)}.jIHzgW_row{gap:8px;min-width:0;max-width:100%}.jIHzgW_title{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;font-size:14px;line-height:24px;overflow:hidden}.jIHzgW_summary{min-width:0;color:var(--dsw-alias-label-tertiary);flex:1;align-items:center;gap:8px;font-size:13px;line-height:20px;display:flex}.jIHzgW_summary :first-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.jIHzgW_detail{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-background-container,#f6f6f7);color:var(--dsw-alias-label-secondary);border-radius:8px;margin:8px 0 12px 28px;overflow:hidden}.jIHzgW_detailBlock{min-width:0}.jIHzgW_detailLabel{color:var(--dsw-alias-label-tertiary);padding:10px 12px 0;font-size:13px;line-height:18px}.jIHzgW_detail pre{max-height:360px;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-markdown-code-block-small);white-space:pre-wrap;word-break:break-word;margin:0;padding:10px 12px 12px;overflow:auto}.jIHzgW_provenance{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;padding:10px 12px 0;font-size:12px;line-height:18px;overflow:hidden}.jIHzgW_footer{border-top:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-tertiary);justify-content:space-between;gap:12px;padding:8px 12px;font-size:13px;line-height:18px;display:flex}";
|
|
35221
|
+
const tagId$3 = "@agentrouter-top/relay-dsh-plugin-codex/CodexActivityView.module.css";
|
|
35222
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
35219
35223
|
const tag = document.createElement("style");
|
|
35220
35224
|
tag.dataset.plugin = "@agentrouter-top/relay-dsh-plugin-codex";
|
|
35221
|
-
tag.dataset.pluginCss = tagId$
|
|
35222
|
-
tag.textContent = css$
|
|
35225
|
+
tag.dataset.pluginCss = tagId$3;
|
|
35226
|
+
tag.textContent = css$3;
|
|
35223
35227
|
document.head.appendChild(tag);
|
|
35224
35228
|
}
|
|
35225
35229
|
var CodexActivityView_module_css_default = {
|
|
@@ -35236,31 +35240,31 @@ window.__ModuleLoader__.load({
|
|
|
35236
35240
|
//#endregion
|
|
35237
35241
|
//#region src/client/process-presence.ts
|
|
35238
35242
|
const mounted = /* @__PURE__ */ new Map();
|
|
35239
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
35240
|
-
const subscribe = (listener) => {
|
|
35241
|
-
listeners.add(listener);
|
|
35243
|
+
const listeners$1 = /* @__PURE__ */ new Set();
|
|
35244
|
+
const subscribe$1 = (listener) => {
|
|
35245
|
+
listeners$1.add(listener);
|
|
35242
35246
|
return () => {
|
|
35243
|
-
listeners.delete(listener);
|
|
35247
|
+
listeners$1.delete(listener);
|
|
35244
35248
|
};
|
|
35245
35249
|
};
|
|
35246
|
-
const notify = () => {
|
|
35247
|
-
for (const listener of listeners) listener();
|
|
35250
|
+
const notify$1 = () => {
|
|
35251
|
+
for (const listener of listeners$1) listener();
|
|
35248
35252
|
};
|
|
35249
35253
|
const keyOf = (sessionId, turn) => JSON.stringify([sessionId, turn]);
|
|
35250
35254
|
/** Suppression is reversible and only active after the replacement mounts. */
|
|
35251
35255
|
function mountProcess(sessionId, turn) {
|
|
35252
35256
|
const key = keyOf(sessionId, turn);
|
|
35253
35257
|
mounted.set(key, (mounted.get(key) ?? 0) + 1);
|
|
35254
|
-
notify();
|
|
35258
|
+
notify$1();
|
|
35255
35259
|
return () => {
|
|
35256
35260
|
const count = (mounted.get(key) ?? 1) - 1;
|
|
35257
35261
|
if (count === 0) mounted.delete(key);
|
|
35258
35262
|
else mounted.set(key, count);
|
|
35259
|
-
notify();
|
|
35263
|
+
notify$1();
|
|
35260
35264
|
};
|
|
35261
35265
|
}
|
|
35262
35266
|
function useProcessPresence(sessionId, turn) {
|
|
35263
|
-
return (0, react.useSyncExternalStore)(subscribe, () => mounted.has(keyOf(sessionId, turn)), () => false);
|
|
35267
|
+
return (0, react.useSyncExternalStore)(subscribe$1, () => mounted.has(keyOf(sessionId, turn)), () => false);
|
|
35264
35268
|
}
|
|
35265
35269
|
//#endregion
|
|
35266
35270
|
//#region src/client/compatible-chat.ts
|
|
@@ -35722,6 +35726,24 @@ window.__ModuleLoader__.load({
|
|
|
35722
35726
|
const last = text.at(-1);
|
|
35723
35727
|
return last ? [last] : [];
|
|
35724
35728
|
}
|
|
35729
|
+
/** Place each generated attachment in its original generation frame. Never guess
|
|
35730
|
+
* by filename, nearest activity, or cross-turn order. Legacy/MCP images stay native. */
|
|
35731
|
+
function imageGenerationFrames(segments) {
|
|
35732
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
35733
|
+
const frames = /* @__PURE__ */ new Map();
|
|
35734
|
+
for (const segment of segments) {
|
|
35735
|
+
const generation = segment.activity?.imageGeneration;
|
|
35736
|
+
if (segment.kind !== "activity" || generation?.version !== 1) continue;
|
|
35737
|
+
const image = generation.attachmentId ? segments.find((candidate) => candidate.kind === "image" && candidate.step === segment.step && !consumed.has(candidate.key) && candidate.attachment?.attachmentId === generation.attachmentId) : void 0;
|
|
35738
|
+
if (image) consumed.add(image.key);
|
|
35739
|
+
frames.set(segment.key, {
|
|
35740
|
+
...segment,
|
|
35741
|
+
kind: "image",
|
|
35742
|
+
attachment: image?.attachment
|
|
35743
|
+
});
|
|
35744
|
+
}
|
|
35745
|
+
return segments.filter((segment) => !consumed.has(segment.key)).map((segment) => frames.get(segment.key) ?? segment);
|
|
35746
|
+
}
|
|
35725
35747
|
const codexProcessDefinition = {
|
|
35726
35748
|
kind: "relay-codex-process",
|
|
35727
35749
|
target: "chat",
|
|
@@ -35906,6 +35928,241 @@ window.__ModuleLoader__.load({
|
|
|
35906
35928
|
return value.length > 15 ? `${value.slice(0, 8)}...${value.slice(-4)}` : value;
|
|
35907
35929
|
}
|
|
35908
35930
|
//#endregion
|
|
35931
|
+
//#region src/client/image-motion.ts
|
|
35932
|
+
const palette = [
|
|
35933
|
+
[
|
|
35934
|
+
49,
|
|
35935
|
+
190,
|
|
35936
|
+
217
|
|
35937
|
+
],
|
|
35938
|
+
[
|
|
35939
|
+
88,
|
|
35940
|
+
140,
|
|
35941
|
+
246
|
|
35942
|
+
],
|
|
35943
|
+
[
|
|
35944
|
+
161,
|
|
35945
|
+
113,
|
|
35946
|
+
237
|
|
35947
|
+
],
|
|
35948
|
+
[
|
|
35949
|
+
237,
|
|
35950
|
+
132,
|
|
35951
|
+
188
|
|
35952
|
+
],
|
|
35953
|
+
[
|
|
35954
|
+
245,
|
|
35955
|
+
189,
|
|
35956
|
+
121
|
|
35957
|
+
],
|
|
35958
|
+
[
|
|
35959
|
+
78,
|
|
35960
|
+
202,
|
|
35961
|
+
214
|
|
35962
|
+
]
|
|
35963
|
+
];
|
|
35964
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
35965
|
+
let reduced;
|
|
35966
|
+
const notify = () => {
|
|
35967
|
+
for (const listener of listeners) listener();
|
|
35968
|
+
};
|
|
35969
|
+
function subscribe(listener) {
|
|
35970
|
+
if (!listeners.size) {
|
|
35971
|
+
reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)");
|
|
35972
|
+
reduced?.addEventListener("change", notify);
|
|
35973
|
+
document.addEventListener("visibilitychange", notify);
|
|
35974
|
+
}
|
|
35975
|
+
listeners.add(listener);
|
|
35976
|
+
return () => {
|
|
35977
|
+
listeners.delete(listener);
|
|
35978
|
+
if (!listeners.size) {
|
|
35979
|
+
reduced?.removeEventListener("change", notify);
|
|
35980
|
+
document.removeEventListener("visibilitychange", notify);
|
|
35981
|
+
reduced = void 0;
|
|
35982
|
+
}
|
|
35983
|
+
};
|
|
35984
|
+
}
|
|
35985
|
+
/** One bounded canvas timeline; no per-frame React state or host DOM inspection. */
|
|
35986
|
+
function mountImageMotion(canvas, dark) {
|
|
35987
|
+
const ctx = canvas.getContext("2d");
|
|
35988
|
+
if (!ctx) return () => {};
|
|
35989
|
+
let width = 0, height = 0, points = [];
|
|
35990
|
+
let clock = 1.6, last = 0, lastPaint = 0, raf = 0, disposed = false;
|
|
35991
|
+
let visible = typeof IntersectionObserver === "undefined";
|
|
35992
|
+
const colorAt = (position) => {
|
|
35993
|
+
const offset = (position % 1 + 1) % 1 * palette.length;
|
|
35994
|
+
const i = Math.floor(offset), f = offset - i;
|
|
35995
|
+
return palette[i].map((channel, index) => {
|
|
35996
|
+
const value = channel + (palette[(i + 1) % palette.length][index] - channel) * f;
|
|
35997
|
+
return Math.round(dark ? value + (255 - value) * .16 : value);
|
|
35998
|
+
}).join(",");
|
|
35999
|
+
};
|
|
36000
|
+
const draw = () => {
|
|
36001
|
+
if (!width || !height) return;
|
|
36002
|
+
ctx.clearRect(0, 0, width, height);
|
|
36003
|
+
const t = clock;
|
|
36004
|
+
for (let i = 0; i < 3; i++) {
|
|
36005
|
+
const x = width * (.25 + i * .24 + .045 * Math.sin(t * .43 + i));
|
|
36006
|
+
const y = height * (.43 + .075 * Math.sin(t * .6 + i));
|
|
36007
|
+
const glow = ctx.createRadialGradient(x, y, 0, x, y, width * .31);
|
|
36008
|
+
const rgb = colorAt(i * .28 - t * .045);
|
|
36009
|
+
glow.addColorStop(0, `rgba(${rgb},${dark ? .105 : .066})`);
|
|
36010
|
+
glow.addColorStop(1, `rgba(${rgb},0)`);
|
|
36011
|
+
ctx.fillStyle = glow;
|
|
36012
|
+
ctx.fillRect(0, 0, width, height);
|
|
36013
|
+
}
|
|
36014
|
+
for (const p of points) {
|
|
36015
|
+
if (p.edge < .002) continue;
|
|
36016
|
+
const u = p.nx * .93 + p.ny * .24, v = p.ny * .95 - p.nx * .22;
|
|
36017
|
+
const spine = .2 * Math.sin(u * 3.3 - t * .8) + .14 * Math.sin(t * .42);
|
|
36018
|
+
const main = Math.exp(-Math.pow((v - spine) / .21, 2));
|
|
36019
|
+
const echo = Math.exp(-Math.pow((v - spine + .43) / .29, 2));
|
|
36020
|
+
const travel = .59 + .41 * Math.sin(u * 4.2 - t * 1.12 + p.ny * .7);
|
|
36021
|
+
const swell = .8 + .2 * Math.sin(t * .62 + u * 1.9);
|
|
36022
|
+
const energy = (main * (.7 + .3 * travel) + echo * .3) * swell;
|
|
36023
|
+
const alpha = (.022 + energy * (dark ? .86 : .79)) * p.edge;
|
|
36024
|
+
const radius = .53 + energy * .9;
|
|
36025
|
+
const dx = Math.sin(p.ny * 4.1 + t * .61) * .7 * energy;
|
|
36026
|
+
const dy = Math.cos(p.nx * 3.2 - t * .5) * 1.02 * energy;
|
|
36027
|
+
ctx.fillStyle = `rgba(${colorAt((u + 1) * .39 + p.ny * .08 - t * .045)},${alpha.toFixed(3)})`;
|
|
36028
|
+
ctx.beginPath();
|
|
36029
|
+
ctx.arc(p.x + dx, p.y + dy, radius, 0, Math.PI * 2);
|
|
36030
|
+
ctx.fill();
|
|
36031
|
+
if (energy > .6) {
|
|
36032
|
+
ctx.fillStyle = `rgba(255,255,255,${((energy - .6) * p.edge * (dark ? .65 : .32)).toFixed(3)})`;
|
|
36033
|
+
ctx.beginPath();
|
|
36034
|
+
ctx.arc(p.x + dx, p.y + dy, radius * .4, 0, Math.PI * 2);
|
|
36035
|
+
ctx.fill();
|
|
36036
|
+
}
|
|
36037
|
+
}
|
|
36038
|
+
};
|
|
36039
|
+
const canAnimate = () => !disposed && visible && width > 0 && height > 0 && !document.hidden && !reduced?.matches;
|
|
36040
|
+
const tick = (now) => {
|
|
36041
|
+
raf = 0;
|
|
36042
|
+
if (!canAnimate()) {
|
|
36043
|
+
last = 0;
|
|
36044
|
+
return;
|
|
36045
|
+
}
|
|
36046
|
+
if (last) clock += Math.min((now - last) / 1e3, .07);
|
|
36047
|
+
last = now;
|
|
36048
|
+
if (now - lastPaint >= 30) {
|
|
36049
|
+
draw();
|
|
36050
|
+
lastPaint = now;
|
|
36051
|
+
}
|
|
36052
|
+
raf = requestAnimationFrame(tick);
|
|
36053
|
+
};
|
|
36054
|
+
const sync = () => {
|
|
36055
|
+
cancelAnimationFrame(raf);
|
|
36056
|
+
raf = 0;
|
|
36057
|
+
last = 0;
|
|
36058
|
+
if (canAnimate()) raf = requestAnimationFrame(tick);
|
|
36059
|
+
};
|
|
36060
|
+
const resize = () => {
|
|
36061
|
+
if (disposed) return;
|
|
36062
|
+
const rect = canvas.getBoundingClientRect(), ratio = Math.min(window.devicePixelRatio || 1, 2);
|
|
36063
|
+
width = rect.width;
|
|
36064
|
+
height = rect.height;
|
|
36065
|
+
canvas.width = Math.round(width * ratio);
|
|
36066
|
+
canvas.height = Math.round(height * ratio);
|
|
36067
|
+
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
|
|
36068
|
+
const spacing = width < 400 ? 7.4 : 8.4, inset = 22;
|
|
36069
|
+
points = [];
|
|
36070
|
+
for (let y = inset; y < height - 48; y += spacing) for (let x = inset; x < width - inset; x += spacing) {
|
|
36071
|
+
const nx = (x - width * .5) / (width * .47), ny = (y - height * .43) / (height * .42);
|
|
36072
|
+
points.push({
|
|
36073
|
+
x,
|
|
36074
|
+
y,
|
|
36075
|
+
nx,
|
|
36076
|
+
ny,
|
|
36077
|
+
edge: Math.pow(Math.max(0, 1 - nx ** 4 - ny ** 4), 1.2)
|
|
36078
|
+
});
|
|
36079
|
+
}
|
|
36080
|
+
draw();
|
|
36081
|
+
sync();
|
|
36082
|
+
};
|
|
36083
|
+
const unsubscribe = subscribe(sync);
|
|
36084
|
+
const resizer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(resize);
|
|
36085
|
+
const intersection = typeof IntersectionObserver === "undefined" ? void 0 : new IntersectionObserver((entries) => {
|
|
36086
|
+
if (disposed) return;
|
|
36087
|
+
visible = entries.some((entry) => entry.isIntersecting);
|
|
36088
|
+
sync();
|
|
36089
|
+
});
|
|
36090
|
+
resizer?.observe(canvas);
|
|
36091
|
+
intersection?.observe(canvas);
|
|
36092
|
+
resize();
|
|
36093
|
+
return () => {
|
|
36094
|
+
disposed = true;
|
|
36095
|
+
cancelAnimationFrame(raf);
|
|
36096
|
+
unsubscribe();
|
|
36097
|
+
resizer?.disconnect();
|
|
36098
|
+
intersection?.disconnect();
|
|
36099
|
+
};
|
|
36100
|
+
}
|
|
36101
|
+
//#endregion
|
|
36102
|
+
//#region \0relay-css-module:.\src\client\CodexImageGeneration.module.css.mjs
|
|
36103
|
+
const css$2 = ".gSdKhG_frame{--image-well:#f7f8ff;--image-accent:#6f77a7;border-radius:24px;width:min(100%,480px);min-width:0;position:relative;overflow:hidden}.gSdKhG_frame[data-color-scheme=dark]{--image-well:#1a2238;--image-accent:#b9c5fa}.gSdKhG_placeholder{box-sizing:border-box;aspect-ratio:4/3;background:var(--image-well);color:var(--image-accent);border:1px solid var(--dsw-alias-border-l2,#e6e8f2);border-radius:inherit;place-items:end center;transition:opacity 1.2s,filter 1.2s,transform 1.6s,visibility 0s 1.2s;display:grid;position:relative;overflow:hidden}.gSdKhG_field{pointer-events:none;width:100%;height:100%;position:absolute;inset:0}.gSdKhG_label{z-index:1;text-align:center;gap:6px;margin:0 16px 26px;font-size:13px;line-height:20px;display:grid}.gSdKhG_subtitle{opacity:.75;font-size:11px}.gSdKhG_result{min-width:0}.gSdKhG_frame[data-state=ready] .gSdKhG_placeholder{aspect-ratio:auto;opacity:0;filter:blur(5px);visibility:hidden;pointer-events:none;position:absolute;inset:0;transform:scale(1.025)}.gSdKhG_frame[data-reveal] .gSdKhG_result{animation:1.6s both gSdKhG_codex-image-reveal}.gSdKhG_frame[data-state=stopped] .gSdKhG_field{opacity:.4}@keyframes gSdKhG_codex-image-reveal{0%{opacity:0;transform:scale(1.035)}to{opacity:1;transform:scale(1)}}@media (prefers-reduced-motion:reduce){.gSdKhG_placeholder{transition:none}.gSdKhG_frame[data-reveal] .gSdKhG_result{animation:none}}";
|
|
36104
|
+
const tagId$2 = "@agentrouter-top/relay-dsh-plugin-codex/CodexImageGeneration.module.css";
|
|
36105
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
36106
|
+
const tag = document.createElement("style");
|
|
36107
|
+
tag.dataset.plugin = "@agentrouter-top/relay-dsh-plugin-codex";
|
|
36108
|
+
tag.dataset.pluginCss = tagId$2;
|
|
36109
|
+
tag.textContent = css$2;
|
|
36110
|
+
document.head.appendChild(tag);
|
|
36111
|
+
}
|
|
36112
|
+
var CodexImageGeneration_module_css_default = {
|
|
36113
|
+
"codex-image-reveal": "gSdKhG_codex-image-reveal",
|
|
36114
|
+
"field": "gSdKhG_field",
|
|
36115
|
+
"frame": "gSdKhG_frame",
|
|
36116
|
+
"label": "gSdKhG_label",
|
|
36117
|
+
"placeholder": "gSdKhG_placeholder",
|
|
36118
|
+
"result": "gSdKhG_result",
|
|
36119
|
+
"subtitle": "gSdKhG_subtitle"
|
|
36120
|
+
};
|
|
36121
|
+
//#endregion
|
|
36122
|
+
//#region src/client/CodexImageGeneration.tsx
|
|
36123
|
+
const ImageColorScheme = (0, react.createContext)("light");
|
|
36124
|
+
function CodexImageGeneration({ segment, running, renderMessageImages }) {
|
|
36125
|
+
const pending = !segment.attachment && running && segment.activity?.status !== "error";
|
|
36126
|
+
const scheme = (0, react.useContext)(ImageColorScheme);
|
|
36127
|
+
const canvas = (0, react.useRef)(null);
|
|
36128
|
+
const beganWithPlaceholder = (0, react.useRef)(!segment.attachment).current;
|
|
36129
|
+
(0, react.useEffect)(() => {
|
|
36130
|
+
if (pending && canvas.current) return mountImageMotion(canvas.current, scheme === "dark");
|
|
36131
|
+
}, [pending, scheme]);
|
|
36132
|
+
const label = pending ? "正在生成图片" : "图片生成已结束,未提供可显示的图片";
|
|
36133
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36134
|
+
className: CodexImageGeneration_module_css_default.frame,
|
|
36135
|
+
"data-codex-image-generation": segment.key,
|
|
36136
|
+
"data-color-scheme": scheme,
|
|
36137
|
+
"data-reveal": beganWithPlaceholder && Boolean(segment.attachment) || void 0,
|
|
36138
|
+
"data-state": segment.attachment ? "ready" : pending ? "generating" : "stopped",
|
|
36139
|
+
"aria-busy": pending,
|
|
36140
|
+
children: [segment.attachment && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36141
|
+
className: CodexImageGeneration_module_css_default.result,
|
|
36142
|
+
children: renderMessageImages({
|
|
36143
|
+
images: [{ attachment: segment.attachment }],
|
|
36144
|
+
align: "start"
|
|
36145
|
+
})
|
|
36146
|
+
}), beganWithPlaceholder && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36147
|
+
className: CodexImageGeneration_module_css_default.placeholder,
|
|
36148
|
+
"aria-hidden": Boolean(segment.attachment) || void 0,
|
|
36149
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("canvas", {
|
|
36150
|
+
ref: canvas,
|
|
36151
|
+
className: CodexImageGeneration_module_css_default.field,
|
|
36152
|
+
"aria-hidden": "true"
|
|
36153
|
+
}), !segment.attachment && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36154
|
+
className: CodexImageGeneration_module_css_default.label,
|
|
36155
|
+
role: "status",
|
|
36156
|
+
"aria-live": "polite",
|
|
36157
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label }), pending && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36158
|
+
className: CodexImageGeneration_module_css_default.subtitle,
|
|
36159
|
+
children: "图像即将在这里呈现"
|
|
36160
|
+
})]
|
|
36161
|
+
})]
|
|
36162
|
+
})]
|
|
36163
|
+
});
|
|
36164
|
+
}
|
|
36165
|
+
//#endregion
|
|
35909
36166
|
//#region src/client/process-files.ts
|
|
35910
36167
|
function codexProducedFileMentions(segments, openFile, native) {
|
|
35911
36168
|
const paths = /* @__PURE__ */ new Set();
|
|
@@ -35953,7 +36210,7 @@ window.__ModuleLoader__.load({
|
|
|
35953
36210
|
}
|
|
35954
36211
|
//#endregion
|
|
35955
36212
|
//#region \0relay-css-module:.\src\client\CodexProcessView.module.css.mjs
|
|
35956
|
-
const css$1 = "._06p8sG_process{width:100%;min-width:0;color:var(--dsw-alias-label-secondary)}._06p8sG_processToggle,._06p8sG_groupToggle{min-width:0;max-width:100%;min-height:28px;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:2px 0;font-size:14px;line-height:24px;display:flex}._06p8sG_processToggle{margin-bottom:16px}._06p8sG_processToggle:focus-visible,._06p8sG_groupToggle:focus-visible{outline:2px solid var(--dsw-static-deepseek-500,#416aff);outline-offset:3px;border-radius:4px}._06p8sG_groupToggle>svg{flex:none}._06p8sG_groupTitle{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._06p8sG_count{flex-shrink:0;font-size:12px}._06p8sG_flow,._06p8sG_answer{flex-direction:column;gap:20px;min-width:0;display:flex}._06p8sG_flow[hidden]{display:none}._06p8sG_flow{border-top:1px solid var(--dsw-alias-border-l2);padding-top:16px}._06p8sG_answer{color:var(--dsw-alias-label-primary)}._06p8sG_flow:not([hidden])+._06p8sG_answer{margin-top:24px}._06p8sG_prose{min-width:0;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}._06p8sG_prose p{margin:0 0 12px}._06p8sG_prose p:last-child{margin-bottom:0}._06p8sG_activities{flex-direction:column;gap:8px;min-width:0;padding:8px 0 0 20px;display:flex}._06p8sG_reasoning{overflow-wrap:anywhere;margin:8px 0 0 24px;font-size:13px}._06p8sG_error{color:var(--dsw-alias-state-error-primary,#b42318)}._06p8sG_spinner{animation:1.4s linear infinite _06p8sG_codex-spin}@keyframes _06p8sG_codex-spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){._06p8sG_spinner{animation:none}}[data-chat-flow-kind=assistant-step]:has(>[data-slot]>[data-codex-native-assistant]){display:none}[data-chat-flow-kind=tool-call]:has(>[data-slot]>[data-chat-call-id]>[data-slot]>[data-codex-grouped-call]){display:none}[data-chat-flow-kind=context]:has(>[data-slot]>[data-codex-internal-context]){display:none}[data-chat-flow-kind=relay-codex-process]:has(>[data-slot]>[data-codex-process-fallback]){display:none}[data-chat-flow]:has([data-codex-process-turn][data-status=running])>[role=status][aria-live=polite]{display:none}";
|
|
36213
|
+
const css$1 = "._06p8sG_process{width:100%;min-width:0;color:var(--dsw-alias-label-secondary)}._06p8sG_processToggle,._06p8sG_groupToggle{min-width:0;max-width:100%;min-height:28px;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:center;gap:8px;padding:2px 0;font-size:14px;line-height:24px;display:flex}._06p8sG_processToggle{margin-bottom:16px}._06p8sG_processToggle:focus-visible,._06p8sG_groupToggle:focus-visible{outline:2px solid var(--dsw-static-deepseek-500,#416aff);outline-offset:3px;border-radius:4px}._06p8sG_groupToggle>svg{flex:none}._06p8sG_groupTitle{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._06p8sG_count{flex-shrink:0;font-size:12px}._06p8sG_flow,._06p8sG_answer{flex-direction:column;gap:20px;min-width:0;display:flex}._06p8sG_flow[hidden]{display:none}._06p8sG_flow{border-top:1px solid var(--dsw-alias-border-l2);padding-top:16px}._06p8sG_flow[data-images-only]{border-top:0;padding-top:0}._06p8sG_flow>[hidden]{display:none}._06p8sG_answer{color:var(--dsw-alias-label-primary)}._06p8sG_flow:not([hidden])+._06p8sG_answer{margin-top:24px}._06p8sG_prose{min-width:0;color:var(--dsw-alias-label-primary);overflow-wrap:anywhere}._06p8sG_prose p{margin:0 0 12px}._06p8sG_prose p:last-child{margin-bottom:0}._06p8sG_activities{flex-direction:column;gap:8px;min-width:0;padding:8px 0 0 20px;display:flex}._06p8sG_reasoning{overflow-wrap:anywhere;margin:8px 0 0 24px;font-size:13px}._06p8sG_error{color:var(--dsw-alias-state-error-primary,#b42318)}._06p8sG_spinner{animation:1.4s linear infinite _06p8sG_codex-spin}@keyframes _06p8sG_codex-spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){._06p8sG_spinner{animation:none}}[data-chat-flow-kind=assistant-step]:has(>[data-slot]>[data-codex-native-assistant]){display:none}[data-chat-flow-kind=tool-call]:has(>[data-slot]>[data-chat-call-id]>[data-slot]>[data-codex-grouped-call]){display:none}[data-chat-flow-kind=context]:has(>[data-slot]>[data-codex-internal-context]){display:none}[data-chat-flow-kind=relay-codex-process]:has(>[data-slot]>[data-codex-process-fallback]){display:none}[data-chat-flow]:has([data-codex-process-turn][data-status=running])>[role=status][aria-live=polite]{display:none}";
|
|
35957
36214
|
const tagId$1 = "@agentrouter-top/relay-dsh-plugin-codex/CodexProcessView.module.css";
|
|
35958
36215
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
35959
36216
|
const tag = document.createElement("style");
|
|
@@ -36058,13 +36315,15 @@ window.__ModuleLoader__.load({
|
|
|
36058
36315
|
};
|
|
36059
36316
|
}, [state.status]);
|
|
36060
36317
|
const answerKeys = new Set(codexProcessAnswerSegments(state).map((segment) => segment.key));
|
|
36061
|
-
const
|
|
36062
|
-
const
|
|
36063
|
-
const
|
|
36318
|
+
const segments = imageGenerationFrames(state.segments);
|
|
36319
|
+
const finalIndex = segments.findIndex((segment) => answerKeys.has(segment.key));
|
|
36320
|
+
const process = finalIndex < 0 ? segments : segments.slice(0, finalIndex);
|
|
36321
|
+
const answer = finalIndex < 0 ? [] : segments.slice(finalIndex);
|
|
36064
36322
|
const deliverables = process.filter((segment) => segment.kind === "image");
|
|
36323
|
+
const persistentImages = deliverables.some((segment) => segment.activity?.imageGeneration);
|
|
36065
36324
|
const hasProcess = process.some((segment) => segment.kind !== "text" || Boolean(segment.text?.trim()));
|
|
36066
36325
|
const open = expanded ?? (state.status === "running" || answer.length === 0 && deliverables.length === 0);
|
|
36067
|
-
const visibleAnswer = [...open ? [] : deliverables, ...answer];
|
|
36326
|
+
const visibleAnswer = [...open || persistentImages ? [] : deliverables, ...answer];
|
|
36068
36327
|
const seconds = Math.max(0, Math.floor(((state.endedAt ?? now) - state.startedAt) / 1e3));
|
|
36069
36328
|
const elapsed = seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
|
|
36070
36329
|
const status = state.status === "running" ? "Working" : state.status === "error" ? "Stopped" : "Worked";
|
|
@@ -36086,22 +36345,23 @@ window.__ModuleLoader__.load({
|
|
|
36086
36345
|
] }), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ChevronDown, { size: 15 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ChevronRight, { size: 15 })]
|
|
36087
36346
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36088
36347
|
className: CodexProcessView_module_css_default.flow,
|
|
36089
|
-
hidden: !open,
|
|
36348
|
+
hidden: !open && !persistentImages,
|
|
36090
36349
|
"data-codex-process-content": true,
|
|
36091
|
-
|
|
36092
|
-
|
|
36093
|
-
|
|
36094
|
-
|
|
36095
|
-
|
|
36096
|
-
|
|
36097
|
-
|
|
36098
|
-
|
|
36099
|
-
|
|
36350
|
+
"data-images-only": !open && persistentImages || void 0,
|
|
36351
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProcessItems, {
|
|
36352
|
+
segments: process,
|
|
36353
|
+
renderMessageImages,
|
|
36354
|
+
running: state.status === "running",
|
|
36355
|
+
showImages: open || persistentImages,
|
|
36356
|
+
collapseProcess: !open
|
|
36357
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36358
|
+
hidden: !open,
|
|
36359
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningSummary, { segments: process }), state.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36100
36360
|
className: CodexProcessView_module_css_default.error,
|
|
36101
36361
|
role: "status",
|
|
36102
36362
|
children: state.error
|
|
36103
|
-
})
|
|
36104
|
-
]
|
|
36363
|
+
})]
|
|
36364
|
+
})]
|
|
36105
36365
|
})] }), visibleAnswer.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36106
36366
|
className: CodexProcessView_module_css_default.answer,
|
|
36107
36367
|
"data-codex-final-answer": true,
|
|
@@ -36114,11 +36374,19 @@ window.__ModuleLoader__.load({
|
|
|
36114
36374
|
})]
|
|
36115
36375
|
});
|
|
36116
36376
|
}
|
|
36117
|
-
function ProcessItems({ segments, renderMessageImages, running, fileMentions, showImages = true }) {
|
|
36118
|
-
return groupProcessSegments(segments).map((item) => "activities" in item ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
36377
|
+
function ProcessItems({ segments, renderMessageImages, running, fileMentions, showImages = true, collapseProcess = false }) {
|
|
36378
|
+
return groupProcessSegments(segments).map((item) => "activities" in item ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36379
|
+
hidden: collapseProcess,
|
|
36380
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActivityGroup, { segments: item.activities })
|
|
36381
|
+
}, item.key) : item.activity?.imageGeneration ? showImages ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexImageGeneration, {
|
|
36382
|
+
segment: item,
|
|
36383
|
+
running,
|
|
36384
|
+
renderMessageImages
|
|
36385
|
+
}, item.key) : null : item.kind === "image" && item.attachment ? showImages ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderMessageImages({
|
|
36119
36386
|
images: [{ attachment: item.attachment }],
|
|
36120
36387
|
align: "start"
|
|
36121
36388
|
}) }, item.key) : null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36389
|
+
hidden: collapseProcess,
|
|
36122
36390
|
className: CodexProcessView_module_css_default.prose,
|
|
36123
36391
|
"data-codex-commentary": item.phase !== "final_answer" || void 0,
|
|
36124
36392
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MarkdownText, {
|
|
@@ -36221,10 +36489,18 @@ window.__ModuleLoader__.load({
|
|
|
36221
36489
|
conversationEvents(ctx).register(codexProcessDefinition);
|
|
36222
36490
|
installContextPresentation(ctx, debug);
|
|
36223
36491
|
ctx.slots.inject("conversation.chat.node", () => {
|
|
36492
|
+
const subscribeTheme = (listener) => ctx.on("theme/change", listener);
|
|
36493
|
+
const getScheme = () => ctx.theme.getTheme().active.colorScheme;
|
|
36224
36494
|
const disposeProcess = ctx.slots.register({
|
|
36225
36495
|
name: "conversation.chat.node",
|
|
36226
36496
|
key: "relay-codex-process"
|
|
36227
|
-
},
|
|
36497
|
+
}, function ThemedCodexProcess(props) {
|
|
36498
|
+
const scheme = (0, react.useSyncExternalStore)(subscribeTheme, getScheme, getScheme);
|
|
36499
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageColorScheme.Provider, {
|
|
36500
|
+
value: scheme,
|
|
36501
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexProcessView, { ...props })
|
|
36502
|
+
});
|
|
36503
|
+
});
|
|
36228
36504
|
let previous;
|
|
36229
36505
|
let disposeAssistant;
|
|
36230
36506
|
const reconcile = () => {
|