dsh-modellix 0.1.1 → 0.2.1
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/CHANGELOG.md +60 -0
- package/README.md +107 -167
- package/README.zh-CN.md +105 -165
- package/cordis.patch.yml +0 -13
- package/docs/assets/chat-media-generation-en.webp +0 -0
- package/docs/assets/chat-media-generation-zh.webp +0 -0
- package/docs/assets/design-results-drawer-en.webp +0 -0
- package/docs/assets/design-results-drawer-zh.webp +0 -0
- package/docs/assets/llm-model-selector-en.webp +0 -0
- package/docs/assets/llm-model-selector-zh.webp +0 -0
- package/docs/assets/media-players-en.webp +0 -0
- package/docs/assets/media-players-zh.webp +0 -0
- package/docs/assets/settings-ready-en.webp +0 -0
- package/docs/assets/settings-ready-zh.webp +0 -0
- package/docs/assets/web-tools-auto-en.webp +0 -0
- package/docs/assets/web-tools-auto-zh.webp +0 -0
- package/docs/en-US/LOCAL_USAGE.md +20 -16
- package/docs/en-US/RELEASE_CHECKLIST.md +270 -0
- package/docs/en-US/USER_GUIDE.md +186 -394
- package/docs/zh-CN/LOCAL_USAGE.md +20 -16
- package/docs/zh-CN/RELEASE_CHECKLIST.md +270 -0
- package/docs/zh-CN/USER_GUIDE.md +185 -393
- package/lib/client.d.ts +18 -4
- package/lib/client.js +1271 -454
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +166 -112
- package/lib/index.js +1008 -197
- package/lib/index.js.map +1 -1
- package/package.json +72 -48
- package/docs/assets/design-desktop-en.webp +0 -0
- package/docs/assets/design-desktop-zh.webp +0 -0
- package/docs/assets/design-proposal-en.webp +0 -0
- package/docs/assets/design-proposal-zh.webp +0 -0
- package/docs/assets/design-results-media-en.webp +0 -0
- package/docs/assets/design-results-media-zh.webp +0 -0
- package/docs/assets/web-tools-en.webp +0 -0
- package/docs/assets/web-tools-zh.webp +0 -0
package/lib/client.js
CHANGED
|
@@ -342,6 +342,8 @@ function parseModel(value) {
|
|
|
342
342
|
"audio",
|
|
343
343
|
"unknown"
|
|
344
344
|
], "model.kind"),
|
|
345
|
+
...model.taskType === void 0 ? {} : { taskType: readable(model.taskType, "model.taskType", 64) },
|
|
346
|
+
...model.description === void 0 ? {} : { description: readable(model.description, "model.description", MAX_SHORT_TEXT) },
|
|
345
347
|
featured: boolean(model.featured, "model.featured"),
|
|
346
348
|
available: boolean(model.available, "model.available"),
|
|
347
349
|
unavailableReason: model.unavailableReason === null ? null : oneOf(model.unavailableReason, DESIGN_MODEL_UNAVAILABLE_CODES, "model.unavailableReason")
|
|
@@ -440,7 +442,7 @@ function parseJob(value) {
|
|
|
440
442
|
createdAt: isoTimestamp(job.createdAt, "job.createdAt"),
|
|
441
443
|
updatedAt: isoTimestamp(job.updatedAt, "job.updatedAt"),
|
|
442
444
|
resources: array(job.resources, "job.resources", MAX_RESOURCES).map(parseResource),
|
|
443
|
-
diagnostic: job.diagnostic === null ? null : parseDiagnostic(job.diagnostic)
|
|
445
|
+
diagnostic: job.diagnostic === null ? null : parseDiagnostic$1(job.diagnostic)
|
|
444
446
|
};
|
|
445
447
|
}
|
|
446
448
|
function parseResource(value) {
|
|
@@ -457,7 +459,7 @@ function parseResource(value) {
|
|
|
457
459
|
expiresAt: resource.expiresAt === null ? null : isoTimestamp(resource.expiresAt, "resource.expiresAt")
|
|
458
460
|
};
|
|
459
461
|
}
|
|
460
|
-
function parseDiagnostic(value) {
|
|
462
|
+
function parseDiagnostic$1(value) {
|
|
461
463
|
const diagnostic = object(value, "diagnostic");
|
|
462
464
|
if (Object.hasOwn(diagnostic, "message")) throw new ModellixClientContractError("diagnostic must use a stable code instead of Host prose");
|
|
463
465
|
return {
|
|
@@ -1926,8 +1928,28 @@ function DesignResultPreview({ resource, t }) {
|
|
|
1926
1928
|
});
|
|
1927
1929
|
}
|
|
1928
1930
|
//#endregion
|
|
1931
|
+
//#region src/client/result-tabs.ts
|
|
1932
|
+
/** Implements the WAI-ARIA Tabs arrow/Home/End keyboard pattern. */
|
|
1933
|
+
function handleResultTabKeyDown(event) {
|
|
1934
|
+
if (![
|
|
1935
|
+
"ArrowLeft",
|
|
1936
|
+
"ArrowRight",
|
|
1937
|
+
"Home",
|
|
1938
|
+
"End"
|
|
1939
|
+
].includes(event.key)) return;
|
|
1940
|
+
const tabs = [...event.currentTarget.querySelectorAll("[role=\"tab\"]:not([disabled])")];
|
|
1941
|
+
if (tabs.length === 0) return;
|
|
1942
|
+
const active = tabs.findIndex((tab) => tab === event.target);
|
|
1943
|
+
if (active < 0) return;
|
|
1944
|
+
const next = event.key === "Home" ? tabs[0] : event.key === "End" ? tabs.at(-1) : tabs[(active + (event.key === "ArrowRight" ? 1 : -1) + tabs.length) % tabs.length];
|
|
1945
|
+
if (next === void 0) return;
|
|
1946
|
+
event.preventDefault();
|
|
1947
|
+
next.focus();
|
|
1948
|
+
next.click();
|
|
1949
|
+
}
|
|
1950
|
+
//#endregion
|
|
1929
1951
|
//#region src/client/DesignView.tsx
|
|
1930
|
-
function ModellixDesignView({ controller, settingsController, t }) {
|
|
1952
|
+
function ModellixDesignView({ advancedEditorOpen = true, controller, settingsController, onAddUrl, t }) {
|
|
1931
1953
|
const state = useResourceState(controller.store);
|
|
1932
1954
|
const settingsState = useResourceState(settingsController.store);
|
|
1933
1955
|
const snapshot = state.data;
|
|
@@ -2069,307 +2091,294 @@ function ModellixDesignView({ controller, settingsController, t }) {
|
|
|
2069
2091
|
className: "mdlx-design",
|
|
2070
2092
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2071
2093
|
className: "mdlx-design-shell",
|
|
2072
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
})
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
onChange: (event) => setModelQuery(event.currentTarget.value)
|
|
2130
|
-
}),
|
|
2131
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2132
|
-
className: "mdlx-select",
|
|
2133
|
-
value: modelKind,
|
|
2134
|
-
"aria-label": t("modelCategoryLabel"),
|
|
2135
|
-
disabled: interactionBusy || !snapshot.enabled,
|
|
2136
|
-
onChange: (event) => {
|
|
2137
|
-
setModelKind(event.currentTarget.value);
|
|
2138
|
-
},
|
|
2139
|
-
children: [
|
|
2140
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2141
|
-
value: "all",
|
|
2142
|
-
children: t("modelCategoryAll")
|
|
2143
|
-
}),
|
|
2144
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2145
|
-
value: "image",
|
|
2146
|
-
children: t("modelCategoryImage")
|
|
2147
|
-
}),
|
|
2148
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2149
|
-
value: "video",
|
|
2150
|
-
children: t("modelCategoryVideo")
|
|
2151
|
-
}),
|
|
2152
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2153
|
-
value: "audio",
|
|
2154
|
-
children: t("modelCategoryAudio")
|
|
2155
|
-
})
|
|
2156
|
-
]
|
|
2157
|
-
}),
|
|
2158
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2094
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2095
|
+
id: "mdlx-design-editor",
|
|
2096
|
+
className: "mdlx-design-editor",
|
|
2097
|
+
hidden: !advancedEditorOpen,
|
|
2098
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2099
|
+
className: "mdlx-design-pane",
|
|
2100
|
+
"aria-label": t("advancedEditor"),
|
|
2101
|
+
children: [
|
|
2102
|
+
!snapshot.enabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2103
|
+
className: "mdlx-info",
|
|
2104
|
+
children: t("designDisabled")
|
|
2105
|
+
}),
|
|
2106
|
+
!snapshot.credentialReady && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2107
|
+
className: "mdlx-info",
|
|
2108
|
+
children: [
|
|
2109
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("keyRequired") }),
|
|
2110
|
+
settings?.credential.writable === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2111
|
+
type: "button",
|
|
2112
|
+
variant: "primary",
|
|
2113
|
+
onClick: () => credentialDialogs.openCredential(credentialDialogOwner),
|
|
2114
|
+
children: t("configureToContinue")
|
|
2115
|
+
}),
|
|
2116
|
+
settings?.credential.source === "env" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2117
|
+
className: "mdlx-muted",
|
|
2118
|
+
children: t("envReadonly")
|
|
2119
|
+
})
|
|
2120
|
+
]
|
|
2121
|
+
}),
|
|
2122
|
+
snapshot.notice !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2123
|
+
className: "mdlx-info",
|
|
2124
|
+
role: "status",
|
|
2125
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [t("notice"), ": "] }), t(designNoticeMessageKey(snapshot.notice))]
|
|
2126
|
+
}),
|
|
2127
|
+
draft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2128
|
+
className: "mdlx-card",
|
|
2129
|
+
"aria-labelledby": "mdlx-assistant-title",
|
|
2130
|
+
children: [
|
|
2131
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2132
|
+
className: "mdlx-heading",
|
|
2133
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2134
|
+
id: "mdlx-assistant-title",
|
|
2135
|
+
children: t("assistantTitle")
|
|
2136
|
+
})
|
|
2137
|
+
}),
|
|
2138
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
2139
|
+
id: "mdlx-assistant-instruction",
|
|
2140
|
+
className: "mdlx-textarea mdlx-textarea-small",
|
|
2141
|
+
value: instruction,
|
|
2142
|
+
maxLength: 8e3,
|
|
2143
|
+
placeholder: t("assistantPlaceholder"),
|
|
2144
|
+
"aria-labelledby": "mdlx-assistant-title",
|
|
2145
|
+
disabled: interactionBusy,
|
|
2146
|
+
onChange: (event) => setInstruction(event.currentTarget.value)
|
|
2147
|
+
}),
|
|
2148
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2149
|
+
className: "mdlx-actions",
|
|
2150
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2159
2151
|
type: "button",
|
|
2160
2152
|
variant: "outline",
|
|
2161
|
-
disabled: interactionBusy ||
|
|
2162
|
-
"aria-busy": state.pending === "
|
|
2153
|
+
disabled: interactionBusy || instruction.trim().length === 0,
|
|
2154
|
+
"aria-busy": state.pending === "propose",
|
|
2163
2155
|
onClick: () => {
|
|
2164
|
-
|
|
2156
|
+
const request = instruction.trim();
|
|
2157
|
+
if (request === "") return;
|
|
2158
|
+
controller.propose(request, parameters).then((accepted) => {
|
|
2159
|
+
if (accepted) setInstruction("");
|
|
2160
|
+
});
|
|
2165
2161
|
},
|
|
2166
|
-
children: state.pending === "
|
|
2162
|
+
children: state.pending === "propose" ? t("proposing") : t("propose")
|
|
2167
2163
|
})
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
value: snapshot.selectedModelId ?? "",
|
|
2174
|
-
"aria-describedby": selectedModel?.available === false ? "mdlx-design-model-status" : void 0,
|
|
2175
|
-
disabled: interactionBusy || !snapshot.enabled || snapshot.models.length === 0,
|
|
2176
|
-
onChange: (event) => {
|
|
2177
|
-
const modelId = event.currentTarget.value;
|
|
2178
|
-
if (modelId !== "") controller.selectModel(modelId);
|
|
2179
|
-
},
|
|
2180
|
-
children: [
|
|
2181
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2182
|
-
value: "",
|
|
2183
|
-
disabled: true,
|
|
2184
|
-
children: t("chooseModel")
|
|
2185
|
-
}),
|
|
2186
|
-
snapshot.selectedModelId !== null && !visibleModels.some((model) => model.id === snapshot.selectedModelId) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2187
|
-
value: snapshot.selectedModelId,
|
|
2188
|
-
disabled: selectedModel?.available === false,
|
|
2189
|
-
children: snapshot.models.find((model) => model.id === snapshot.selectedModelId)?.label ?? snapshot.selectedModelId
|
|
2190
|
-
}),
|
|
2191
|
-
visibleModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
2192
|
-
value: model.id,
|
|
2193
|
-
disabled: !model.available,
|
|
2194
|
-
children: [model.label, model.featured ? " ★" : ""]
|
|
2195
|
-
}, model.id))
|
|
2196
|
-
]
|
|
2197
|
-
}),
|
|
2198
|
-
selectedModel?.available === false && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2199
|
-
id: "mdlx-design-model-status",
|
|
2200
|
-
className: "mdlx-error",
|
|
2201
|
-
role: "status",
|
|
2202
|
-
children: selectedModel.unavailableReason === null ? t("modelUnavailable") : t(designModelUnavailableMessageKey(selectedModel.unavailableReason))
|
|
2203
|
-
}),
|
|
2204
|
-
snapshot.models.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2205
|
-
className: "mdlx-help",
|
|
2206
|
-
children: t("noModels")
|
|
2207
|
-
}) : visibleModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2208
|
-
className: "mdlx-help",
|
|
2209
|
-
children: t("noMatchingModels")
|
|
2210
|
-
})
|
|
2211
|
-
]
|
|
2212
|
-
}),
|
|
2213
|
-
draft !== null && promptPath !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2214
|
-
className: "mdlx-field",
|
|
2215
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2216
|
-
className: "mdlx-label",
|
|
2217
|
-
htmlFor: "mdlx-design-prompt",
|
|
2164
|
+
})
|
|
2165
|
+
]
|
|
2166
|
+
}),
|
|
2167
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2168
|
+
className: "mdlx-field",
|
|
2218
2169
|
children: [
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2170
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
2171
|
+
className: "mdlx-label",
|
|
2172
|
+
htmlFor: "mdlx-design-model",
|
|
2173
|
+
children: t("modelLabel")
|
|
2174
|
+
}),
|
|
2175
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2176
|
+
className: "mdlx-model-tools",
|
|
2177
|
+
children: [
|
|
2178
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
2179
|
+
className: "mdlx-input",
|
|
2180
|
+
value: modelQuery,
|
|
2181
|
+
maxLength: 512,
|
|
2182
|
+
placeholder: t("modelSearchPlaceholder"),
|
|
2183
|
+
"aria-label": t("modelSearchLabel"),
|
|
2184
|
+
disabled: interactionBusy || !snapshot.enabled,
|
|
2185
|
+
onChange: (event) => setModelQuery(event.currentTarget.value)
|
|
2186
|
+
}),
|
|
2187
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2188
|
+
className: "mdlx-select",
|
|
2189
|
+
value: modelKind,
|
|
2190
|
+
"aria-label": t("modelCategoryLabel"),
|
|
2191
|
+
disabled: interactionBusy || !snapshot.enabled,
|
|
2192
|
+
onChange: (event) => {
|
|
2193
|
+
setModelKind(event.currentTarget.value);
|
|
2194
|
+
},
|
|
2195
|
+
children: [
|
|
2196
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2197
|
+
value: "all",
|
|
2198
|
+
children: t("modelCategoryAll")
|
|
2199
|
+
}),
|
|
2200
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2201
|
+
value: "image",
|
|
2202
|
+
children: t("modelCategoryImage")
|
|
2203
|
+
}),
|
|
2204
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2205
|
+
value: "video",
|
|
2206
|
+
children: t("modelCategoryVideo")
|
|
2207
|
+
}),
|
|
2208
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2209
|
+
value: "audio",
|
|
2210
|
+
children: t("modelCategoryAudio")
|
|
2211
|
+
})
|
|
2212
|
+
]
|
|
2213
|
+
}),
|
|
2214
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2215
|
+
type: "button",
|
|
2216
|
+
variant: "outline",
|
|
2217
|
+
disabled: interactionBusy || !snapshot.enabled || !snapshot.credentialReady,
|
|
2218
|
+
"aria-busy": state.pending === "refresh-design",
|
|
2219
|
+
onClick: () => {
|
|
2220
|
+
controller.refreshCatalog();
|
|
2221
|
+
},
|
|
2222
|
+
children: state.pending === "refresh-design" ? t("modelRefreshing") : t("modelRefresh")
|
|
2223
|
+
})
|
|
2224
|
+
]
|
|
2225
|
+
}),
|
|
2226
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2227
|
+
id: "mdlx-design-model",
|
|
2228
|
+
className: "mdlx-select",
|
|
2229
|
+
value: snapshot.selectedModelId ?? "",
|
|
2230
|
+
"aria-describedby": selectedModel?.available === false ? "mdlx-design-model-status" : void 0,
|
|
2231
|
+
disabled: interactionBusy || !snapshot.enabled || snapshot.models.length === 0,
|
|
2232
|
+
onChange: (event) => {
|
|
2233
|
+
const modelId = event.currentTarget.value;
|
|
2234
|
+
if (modelId !== "") controller.selectModel(modelId);
|
|
2235
|
+
},
|
|
2236
|
+
children: [
|
|
2237
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2238
|
+
value: "",
|
|
2239
|
+
disabled: true,
|
|
2240
|
+
children: t("chooseModel")
|
|
2241
|
+
}),
|
|
2242
|
+
snapshot.selectedModelId !== null && !visibleModels.some((model) => model.id === snapshot.selectedModelId) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2243
|
+
value: snapshot.selectedModelId,
|
|
2244
|
+
disabled: selectedModel?.available === false,
|
|
2245
|
+
children: snapshot.models.find((model) => model.id === snapshot.selectedModelId)?.label ?? snapshot.selectedModelId
|
|
2246
|
+
}),
|
|
2247
|
+
visibleModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
2248
|
+
value: model.id,
|
|
2249
|
+
disabled: !model.available,
|
|
2250
|
+
children: [model.label, model.featured ? " ★" : ""]
|
|
2251
|
+
}, model.id))
|
|
2252
|
+
]
|
|
2253
|
+
}),
|
|
2254
|
+
selectedModel?.available === false && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2255
|
+
id: "mdlx-design-model-status",
|
|
2256
|
+
className: "mdlx-error",
|
|
2257
|
+
role: "status",
|
|
2258
|
+
children: selectedModel.unavailableReason === null ? t("modelUnavailable") : t(designModelUnavailableMessageKey(selectedModel.unavailableReason))
|
|
2259
|
+
}),
|
|
2260
|
+
snapshot.models.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2261
|
+
className: "mdlx-help",
|
|
2262
|
+
children: t("noModels")
|
|
2263
|
+
}) : visibleModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2264
|
+
className: "mdlx-help",
|
|
2265
|
+
children: t("noMatchingModels")
|
|
2224
2266
|
})
|
|
2225
2267
|
]
|
|
2226
|
-
}),
|
|
2227
|
-
|
|
2228
|
-
className: "mdlx-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
className: "mdlx-parameter-list",
|
|
2247
|
-
children: [requiredFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignParameterField, {
|
|
2248
|
-
field,
|
|
2249
|
-
value: parameters[field.path],
|
|
2250
|
-
invalid: invalidFields.has(field.path),
|
|
2268
|
+
}),
|
|
2269
|
+
draft !== null && promptPath !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2270
|
+
className: "mdlx-field",
|
|
2271
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2272
|
+
className: "mdlx-label",
|
|
2273
|
+
htmlFor: "mdlx-design-prompt",
|
|
2274
|
+
children: [
|
|
2275
|
+
t("promptLabel"),
|
|
2276
|
+
" ",
|
|
2277
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2278
|
+
className: "mdlx-required",
|
|
2279
|
+
children: t("required")
|
|
2280
|
+
})
|
|
2281
|
+
]
|
|
2282
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
2283
|
+
id: "mdlx-design-prompt",
|
|
2284
|
+
className: "mdlx-textarea",
|
|
2285
|
+
value: promptValue,
|
|
2286
|
+
maxLength: fieldAtPath(draft.fields, promptPath)?.maxLength ?? void 0,
|
|
2287
|
+
placeholder: t("promptPlaceholder"),
|
|
2251
2288
|
disabled: interactionBusy,
|
|
2252
|
-
onChange: (
|
|
2253
|
-
onValidityChange: (valid) => setFieldValidity(field.path, valid),
|
|
2254
|
-
t
|
|
2255
|
-
}, field.path)), optionalFields.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
2256
|
-
className: "mdlx-advanced",
|
|
2257
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("advancedParameters", { count: optionalFields.length }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2258
|
-
className: "mdlx-parameter-list",
|
|
2259
|
-
children: optionalFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignParameterField, {
|
|
2260
|
-
field,
|
|
2261
|
-
value: parameters[field.path],
|
|
2262
|
-
invalid: invalidFields.has(field.path),
|
|
2263
|
-
disabled: interactionBusy,
|
|
2264
|
-
onChange: (value) => updateParameter(field.path, value),
|
|
2265
|
-
onValidityChange: (valid) => setFieldValidity(field.path, valid),
|
|
2266
|
-
t
|
|
2267
|
-
}, field.path))
|
|
2268
|
-
})]
|
|
2289
|
+
onChange: (event) => updateParameter(promptPath, event.currentTarget.value)
|
|
2269
2290
|
})]
|
|
2270
|
-
})
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
children: [
|
|
2276
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2291
|
+
}),
|
|
2292
|
+
draft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2293
|
+
className: "mdlx-design-scroll",
|
|
2294
|
+
"aria-labelledby": "mdlx-parameters-title",
|
|
2295
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2277
2296
|
className: "mdlx-heading",
|
|
2278
|
-
children:
|
|
2279
|
-
id: "mdlx-
|
|
2280
|
-
children: t("
|
|
2281
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2282
|
-
id: "mdlx-assistant-paid-notice",
|
|
2283
|
-
className: "mdlx-help",
|
|
2284
|
-
children: t("assistantPaidNotice")
|
|
2285
|
-
})]
|
|
2286
|
-
}),
|
|
2287
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
2288
|
-
id: "mdlx-assistant-instruction",
|
|
2289
|
-
className: "mdlx-textarea mdlx-textarea-small",
|
|
2290
|
-
value: instruction,
|
|
2291
|
-
maxLength: 8e3,
|
|
2292
|
-
placeholder: t("assistantPlaceholder"),
|
|
2293
|
-
"aria-labelledby": "mdlx-assistant-title",
|
|
2294
|
-
"aria-describedby": "mdlx-assistant-paid-notice",
|
|
2295
|
-
disabled: interactionBusy,
|
|
2296
|
-
onChange: (event) => setInstruction(event.currentTarget.value)
|
|
2297
|
-
}),
|
|
2298
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2299
|
-
className: "mdlx-actions",
|
|
2300
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2301
|
-
type: "button",
|
|
2302
|
-
variant: "outline",
|
|
2303
|
-
disabled: interactionBusy || instruction.trim().length === 0,
|
|
2304
|
-
"aria-busy": state.pending === "propose",
|
|
2305
|
-
onClick: () => {
|
|
2306
|
-
const request = instruction.trim();
|
|
2307
|
-
if (request === "") return;
|
|
2308
|
-
controller.propose(request, parameters).then((accepted) => {
|
|
2309
|
-
if (accepted) setInstruction("");
|
|
2310
|
-
});
|
|
2311
|
-
},
|
|
2312
|
-
children: state.pending === "propose" ? t("proposing") : t("propose")
|
|
2297
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2298
|
+
id: "mdlx-parameters-title",
|
|
2299
|
+
children: t("parametersTitle")
|
|
2313
2300
|
})
|
|
2314
|
-
})
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2301
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2302
|
+
className: "mdlx-parameter-list",
|
|
2303
|
+
children: [requiredFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignParameterField, {
|
|
2304
|
+
field,
|
|
2305
|
+
value: parameters[field.path],
|
|
2306
|
+
invalid: invalidFields.has(field.path),
|
|
2307
|
+
disabled: interactionBusy,
|
|
2308
|
+
onChange: (value) => updateParameter(field.path, value),
|
|
2309
|
+
onValidityChange: (valid) => setFieldValidity(field.path, valid),
|
|
2310
|
+
t
|
|
2311
|
+
}, field.path)), optionalFields.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
2312
|
+
className: "mdlx-advanced",
|
|
2313
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("advancedParameters", { count: optionalFields.length }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2314
|
+
className: "mdlx-parameter-list",
|
|
2315
|
+
children: optionalFields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignParameterField, {
|
|
2316
|
+
field,
|
|
2317
|
+
value: parameters[field.path],
|
|
2318
|
+
invalid: invalidFields.has(field.path),
|
|
2319
|
+
disabled: interactionBusy,
|
|
2320
|
+
onChange: (value) => updateParameter(field.path, value),
|
|
2321
|
+
onValidityChange: (valid) => setFieldValidity(field.path, valid),
|
|
2322
|
+
t
|
|
2323
|
+
}, field.path))
|
|
2324
|
+
})]
|
|
2325
|
+
})]
|
|
2326
|
+
})]
|
|
2327
|
+
}),
|
|
2328
|
+
snapshot.proposal !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProposalCard, {
|
|
2329
|
+
snapshot,
|
|
2330
|
+
parameters,
|
|
2331
|
+
controller,
|
|
2332
|
+
t
|
|
2333
|
+
}),
|
|
2334
|
+
draft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2335
|
+
className: "mdlx-generate-block",
|
|
2336
|
+
children: [
|
|
2337
|
+
missingRequired && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2338
|
+
className: "mdlx-error",
|
|
2339
|
+
children: t("requiredMissing")
|
|
2340
|
+
}),
|
|
2341
|
+
invalidFields.size > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2342
|
+
className: "mdlx-error",
|
|
2343
|
+
children: t("parametersInvalid")
|
|
2344
|
+
}),
|
|
2345
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2346
|
+
className: "mdlx-actions",
|
|
2347
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2348
|
+
type: "button",
|
|
2349
|
+
variant: snapshot.credentialReady && snapshot.proposal === null ? "primary" : "outline",
|
|
2350
|
+
disabled: !canGenerate,
|
|
2351
|
+
"aria-busy": submitting,
|
|
2352
|
+
onClick: () => {
|
|
2353
|
+
controller.submit(parameters);
|
|
2354
|
+
},
|
|
2355
|
+
children: submitting ? t("generating") : t("generate")
|
|
2356
|
+
})
|
|
2349
2357
|
})
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2358
|
+
]
|
|
2359
|
+
}),
|
|
2360
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorNotice, {
|
|
2361
|
+
code: state.errorCode,
|
|
2362
|
+
t
|
|
2363
|
+
}),
|
|
2364
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(BusyStatus, {
|
|
2365
|
+
busy: interactionBusy,
|
|
2366
|
+
text: operationText(state.pending, t)
|
|
2367
|
+
}),
|
|
2368
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2369
|
+
className: "mdlx-live",
|
|
2370
|
+
role: "status",
|
|
2371
|
+
"aria-live": "polite",
|
|
2372
|
+
children: outcomeAnnouncement
|
|
2373
|
+
})
|
|
2374
|
+
]
|
|
2375
|
+
})
|
|
2368
2376
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignResults, {
|
|
2369
2377
|
snapshot,
|
|
2370
2378
|
dateLocale: t("dateLocale"),
|
|
2371
2379
|
dialogCoordinator: credentialDialogs,
|
|
2372
2380
|
dialog: credentialDialog,
|
|
2381
|
+
...onAddUrl === void 0 ? {} : { onAddUrl },
|
|
2373
2382
|
t
|
|
2374
2383
|
})]
|
|
2375
2384
|
}), settings !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CredentialModal, {
|
|
@@ -2612,125 +2621,167 @@ function ProposalCard({ snapshot, parameters, controller, t }) {
|
|
|
2612
2621
|
]
|
|
2613
2622
|
});
|
|
2614
2623
|
}
|
|
2615
|
-
function DesignResults({ snapshot, dateLocale, dialogCoordinator, dialog, t }) {
|
|
2616
|
-
const
|
|
2617
|
-
|
|
2618
|
-
const succeeded = [];
|
|
2619
|
-
const diagnostics = [];
|
|
2620
|
-
for (const job of snapshot.jobs) if (job.status === "running") running.push(job);
|
|
2621
|
-
else if (job.status === "succeeded") succeeded.push(job);
|
|
2622
|
-
else diagnostics.push(job);
|
|
2623
|
-
return {
|
|
2624
|
-
running,
|
|
2625
|
-
succeeded,
|
|
2626
|
-
diagnostics
|
|
2627
|
-
};
|
|
2628
|
-
}, [snapshot.jobs]);
|
|
2624
|
+
function DesignResults({ snapshot, dateLocale, dialogCoordinator, dialog, onAddUrl, t }) {
|
|
2625
|
+
const [open, setOpen] = (0, react.useState)(true);
|
|
2626
|
+
const jobs = (0, react.useMemo)(() => [...snapshot.jobs].sort((left, right) => Date.parse(right.createdAt) - Date.parse(left.createdAt)), [snapshot.jobs]);
|
|
2629
2627
|
const empty = snapshot.jobs.length === 0;
|
|
2630
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
2631
|
-
className: "mdlx-design-pane",
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2628
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
2629
|
+
className: "mdlx-design-pane mdlx-results-disclosure",
|
|
2630
|
+
open,
|
|
2631
|
+
onToggle: (event) => setOpen(event.currentTarget.open),
|
|
2632
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
|
|
2633
|
+
className: "mdlx-results-summary",
|
|
2634
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2636
2635
|
id: "mdlx-results-title",
|
|
2637
2636
|
children: t("resultsTitle")
|
|
2638
|
-
})
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
})
|
|
2643
|
-
className: "mdlx-
|
|
2644
|
-
children:
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
t
|
|
2652
|
-
}),
|
|
2653
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResultSection, {
|
|
2654
|
-
title: t("succeededTitle"),
|
|
2655
|
-
jobs: groups.succeeded,
|
|
2656
|
-
dateLocale,
|
|
2657
|
-
dialogCoordinator,
|
|
2658
|
-
dialog,
|
|
2659
|
-
t
|
|
2660
|
-
}),
|
|
2661
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResultSection, {
|
|
2662
|
-
title: t("diagnosticsTitle"),
|
|
2663
|
-
jobs: groups.diagnostics,
|
|
2637
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2638
|
+
className: "mdlx-muted",
|
|
2639
|
+
children: t("resultsCount", { count: jobs.length })
|
|
2640
|
+
})]
|
|
2641
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2642
|
+
className: "mdlx-results-body",
|
|
2643
|
+
children: empty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2644
|
+
className: "mdlx-empty",
|
|
2645
|
+
children: t("noResults")
|
|
2646
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
2647
|
+
className: "mdlx-result-list",
|
|
2648
|
+
children: jobs.map((job) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResultCard, {
|
|
2649
|
+
job,
|
|
2664
2650
|
dateLocale,
|
|
2665
2651
|
dialogCoordinator,
|
|
2666
2652
|
dialog,
|
|
2653
|
+
...onAddUrl === void 0 ? {} : { onAddUrl },
|
|
2667
2654
|
t
|
|
2668
|
-
})
|
|
2669
|
-
|
|
2670
|
-
})]
|
|
2671
|
-
});
|
|
2672
|
-
}
|
|
2673
|
-
function ResultSection({ title, jobs, dateLocale, dialogCoordinator, dialog, t }) {
|
|
2674
|
-
if (jobs.length === 0) return null;
|
|
2675
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2676
|
-
className: "mdlx-result-section",
|
|
2677
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: title }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
2678
|
-
className: "mdlx-result-list",
|
|
2679
|
-
children: jobs.map((job) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResultCard, {
|
|
2680
|
-
job,
|
|
2681
|
-
dateLocale,
|
|
2682
|
-
dialogCoordinator,
|
|
2683
|
-
dialog,
|
|
2684
|
-
t
|
|
2685
|
-
}, job.jobId))
|
|
2655
|
+
}, job.jobId))
|
|
2656
|
+
})
|
|
2686
2657
|
})]
|
|
2687
2658
|
});
|
|
2688
2659
|
}
|
|
2689
|
-
function ResultCard({ job, dateLocale, dialogCoordinator, dialog, t }) {
|
|
2660
|
+
function ResultCard({ job, dateLocale, dialogCoordinator, dialog, onAddUrl, t }) {
|
|
2661
|
+
const [open, setOpen] = (0, react.useState)(true);
|
|
2662
|
+
const [tab, setTab] = (0, react.useState)("preview");
|
|
2663
|
+
const [activeIndex, setActiveIndex] = (0, react.useState)(0);
|
|
2664
|
+
const tabId = (0, react.useId)();
|
|
2690
2665
|
const status = jobStatus(job.status, t);
|
|
2691
2666
|
const created = formatTime(job.createdAt, dateLocale);
|
|
2692
|
-
|
|
2667
|
+
const dot = job.status === "succeeded" ? "done" : job.status === "running" ? "ongoing" : job.status === "failed" ? "error" : "warning";
|
|
2668
|
+
const resources = job.status === "expired" ? [] : job.resources;
|
|
2669
|
+
const succeeded = job.status === "succeeded";
|
|
2670
|
+
const resourceIndex = resources.length === 0 ? 0 : activeIndex % resources.length;
|
|
2671
|
+
const currentResource = resources[resourceIndex];
|
|
2672
|
+
const activeTabId = `${tabId}-${tab}-tab`;
|
|
2673
|
+
const activePanelId = `${tabId}-${tab}-panel`;
|
|
2674
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
2693
2675
|
className: "mdlx-result-card",
|
|
2694
|
-
children:
|
|
2695
|
-
|
|
2696
|
-
|
|
2676
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
2677
|
+
className: "mdlx-result-disclosure",
|
|
2678
|
+
open,
|
|
2679
|
+
onToggle: (event) => setOpen(event.currentTarget.open),
|
|
2680
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
|
|
2681
|
+
className: "mdlx-result-card-summary",
|
|
2697
2682
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2698
|
-
className: "mdlx-
|
|
2699
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
2683
|
+
className: "mdlx-result-head",
|
|
2684
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2685
|
+
className: "mdlx-status-copy",
|
|
2686
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: dot }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: status })]
|
|
2687
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2688
|
+
className: "mdlx-muted",
|
|
2689
|
+
children: t("jobCreated", { time: created })
|
|
2690
|
+
})]
|
|
2700
2691
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2701
2692
|
className: "mdlx-muted",
|
|
2702
|
-
children: t("
|
|
2693
|
+
children: t("jobModel", { model: job.modelId })
|
|
2703
2694
|
})]
|
|
2704
|
-
}),
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2695
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2696
|
+
className: "mdlx-result-card-body",
|
|
2697
|
+
children: [succeeded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2698
|
+
className: "mdlx-result-tabs",
|
|
2699
|
+
role: "tablist",
|
|
2700
|
+
"aria-label": t("resultViewLabel"),
|
|
2701
|
+
onKeyDown: handleResultTabKeyDown,
|
|
2702
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2703
|
+
id: `${tabId}-preview-tab`,
|
|
2704
|
+
type: "button",
|
|
2705
|
+
role: "tab",
|
|
2706
|
+
"aria-controls": `${tabId}-preview-panel`,
|
|
2707
|
+
"aria-selected": tab === "preview",
|
|
2708
|
+
tabIndex: tab === "preview" ? 0 : -1,
|
|
2709
|
+
className: "mdlx-result-tab",
|
|
2710
|
+
onClick: () => setTab("preview"),
|
|
2711
|
+
children: t("previewTab")
|
|
2712
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2713
|
+
id: `${tabId}-json-tab`,
|
|
2714
|
+
type: "button",
|
|
2715
|
+
role: "tab",
|
|
2716
|
+
"aria-controls": `${tabId}-json-panel`,
|
|
2717
|
+
"aria-selected": tab === "json",
|
|
2718
|
+
tabIndex: tab === "json" ? 0 : -1,
|
|
2719
|
+
className: "mdlx-result-tab",
|
|
2720
|
+
onClick: () => setTab("json"),
|
|
2721
|
+
children: t("jsonTab")
|
|
2722
|
+
})]
|
|
2723
|
+
}), tab === "preview" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2724
|
+
id: activePanelId,
|
|
2725
|
+
role: "tabpanel",
|
|
2726
|
+
"aria-labelledby": activeTabId,
|
|
2727
|
+
className: "mdlx-result-panel",
|
|
2728
|
+
children: currentResource === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2729
|
+
className: "mdlx-empty mdlx-empty-compact",
|
|
2730
|
+
children: t("noPreview")
|
|
2731
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResultResource, {
|
|
2732
|
+
resource: currentResource,
|
|
2733
|
+
dateLocale,
|
|
2734
|
+
dialogCoordinator,
|
|
2735
|
+
dialog,
|
|
2736
|
+
...onAddUrl === void 0 ? {} : { onAddUrl },
|
|
2737
|
+
t
|
|
2738
|
+
}), resources.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2739
|
+
className: "mdlx-resource-nav",
|
|
2740
|
+
"aria-label": t("resourceNavigation"),
|
|
2741
|
+
children: [
|
|
2742
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2743
|
+
type: "button",
|
|
2744
|
+
variant: "outline",
|
|
2745
|
+
onClick: () => setActiveIndex((resourceIndex - 1 + resources.length) % resources.length),
|
|
2746
|
+
children: t("previousResource")
|
|
2747
|
+
}),
|
|
2748
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2749
|
+
className: "mdlx-muted",
|
|
2750
|
+
children: t("resourcePosition", {
|
|
2751
|
+
current: resourceIndex + 1,
|
|
2752
|
+
total: resources.length
|
|
2753
|
+
})
|
|
2754
|
+
}),
|
|
2755
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2756
|
+
type: "button",
|
|
2757
|
+
variant: "outline",
|
|
2758
|
+
onClick: () => setActiveIndex((resourceIndex + 1) % resources.length),
|
|
2759
|
+
children: t("nextResource")
|
|
2760
|
+
})
|
|
2761
|
+
]
|
|
2762
|
+
})] })
|
|
2763
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
2764
|
+
id: activePanelId,
|
|
2765
|
+
role: "tabpanel",
|
|
2766
|
+
"aria-labelledby": activeTabId,
|
|
2767
|
+
className: "mdlx-result-json",
|
|
2768
|
+
children: JSON.stringify(job, null, 2)
|
|
2769
|
+
})] }), job.diagnostic !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2770
|
+
className: "mdlx-error",
|
|
2771
|
+
children: [
|
|
2772
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
2773
|
+
className: "mdlx-code",
|
|
2774
|
+
children: job.diagnostic.code
|
|
2775
|
+
}),
|
|
2776
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t(designDiagnosticMessageKey(job.diagnostic.code)) }),
|
|
2777
|
+
job.diagnostic.retryable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("diagnosticRetryable") })
|
|
2778
|
+
]
|
|
2779
|
+
})]
|
|
2780
|
+
})]
|
|
2781
|
+
})
|
|
2731
2782
|
});
|
|
2732
2783
|
}
|
|
2733
|
-
function ResultResource({ resource, dateLocale, dialogCoordinator, dialog, t }) {
|
|
2784
|
+
function ResultResource({ resource, dateLocale, dialogCoordinator, dialog, onAddUrl, t }) {
|
|
2734
2785
|
const imageDialogOwner = `design-image:${(0, react.useId)()}`;
|
|
2735
2786
|
const imageSurfaceOpen = useExternalDialogGate(dialog.activeOwner === imageDialogOwner);
|
|
2736
2787
|
const imageDialogRef = (0, react.useRef)(null);
|
|
@@ -2746,29 +2797,34 @@ function ResultResource({ resource, dateLocale, dialogCoordinator, dialog, t })
|
|
|
2746
2797
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
2747
2798
|
className: "mdlx-resource",
|
|
2748
2799
|
children: [
|
|
2749
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2800
|
+
resource.kind === "image" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2801
|
+
type: "button",
|
|
2802
|
+
className: "mdlx-image-preview-button",
|
|
2803
|
+
"aria-label": t("openImage"),
|
|
2804
|
+
onClick: () => dialogCoordinator.open(imageDialogOwner),
|
|
2805
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignResultPreview, {
|
|
2806
|
+
resource,
|
|
2807
|
+
t
|
|
2808
|
+
})
|
|
2809
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignResultPreview, {
|
|
2750
2810
|
resource,
|
|
2751
2811
|
t
|
|
2752
2812
|
}),
|
|
2753
2813
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2754
2814
|
className: "mdlx-actions mdlx-actions-start",
|
|
2755
|
-
children: [
|
|
2815
|
+
children: [onAddUrl !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2756
2816
|
type: "button",
|
|
2757
|
-
|
|
2758
|
-
onClick: () =>
|
|
2759
|
-
children: t("
|
|
2760
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
2817
|
+
variant: "outline",
|
|
2818
|
+
onClick: () => onAddUrl(resource.url),
|
|
2819
|
+
children: t("addUrlToChat")
|
|
2820
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2761
2821
|
className: "mdlx-safe-link",
|
|
2762
2822
|
href: resource.downloadUrl,
|
|
2763
2823
|
target: "_blank",
|
|
2764
2824
|
rel: "noopener noreferrer",
|
|
2765
2825
|
referrerPolicy: "no-referrer",
|
|
2766
2826
|
download: true,
|
|
2767
|
-
children:
|
|
2768
|
-
t("download"),
|
|
2769
|
-
" ",
|
|
2770
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRightUpOutline14, { size: 14 })
|
|
2771
|
-
]
|
|
2827
|
+
children: t("download")
|
|
2772
2828
|
})]
|
|
2773
2829
|
}),
|
|
2774
2830
|
resource.expiresAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -2779,7 +2835,6 @@ function ResultResource({ resource, dateLocale, dialogCoordinator, dialog, t })
|
|
|
2779
2835
|
}), resource.kind === "image" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
2780
2836
|
open: imageSurfaceOpen,
|
|
2781
2837
|
title: t("imageViewerTitle"),
|
|
2782
|
-
closeLabel: t("close"),
|
|
2783
2838
|
onClose: closeImage,
|
|
2784
2839
|
headless: true,
|
|
2785
2840
|
className: "mdlx-modal mdlx-image-modal",
|
|
@@ -2810,18 +2865,14 @@ function ResultResource({ resource, dateLocale, dialogCoordinator, dialog, t })
|
|
|
2810
2865
|
"data-mdlx-initial-focus": "",
|
|
2811
2866
|
onClick: closeImage,
|
|
2812
2867
|
children: t("close")
|
|
2813
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
2868
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2814
2869
|
className: "mdlx-safe-link",
|
|
2815
2870
|
href: resource.downloadUrl,
|
|
2816
2871
|
target: "_blank",
|
|
2817
2872
|
rel: "noopener noreferrer",
|
|
2818
2873
|
referrerPolicy: "no-referrer",
|
|
2819
2874
|
download: true,
|
|
2820
|
-
children:
|
|
2821
|
-
t("download"),
|
|
2822
|
-
" ",
|
|
2823
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRightUpOutline14, { size: 14 })
|
|
2824
|
-
]
|
|
2875
|
+
children: t("download")
|
|
2825
2876
|
})]
|
|
2826
2877
|
})
|
|
2827
2878
|
]
|
|
@@ -2862,12 +2913,726 @@ function formatTime(value, locale) {
|
|
|
2862
2913
|
}).format(new Date(value));
|
|
2863
2914
|
}
|
|
2864
2915
|
//#endregion
|
|
2916
|
+
//#region src/client/DesignDrawer.tsx
|
|
2917
|
+
const MODELLIX_DESIGN_SPLIT_MEDIA_QUERY = "(min-width: 1280px)";
|
|
2918
|
+
const MODELLIX_DRAWER_EXIT_MS = 180;
|
|
2919
|
+
const MODELLIX_ADVANCED_EDITOR_ENTRY_HIDDEN = true;
|
|
2920
|
+
function isSplitViewport() {
|
|
2921
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(min-width: 1280px)").matches;
|
|
2922
|
+
}
|
|
2923
|
+
var DesignDrawerController = class {
|
|
2924
|
+
#rpc;
|
|
2925
|
+
#layout;
|
|
2926
|
+
#isSplitViewport;
|
|
2927
|
+
#listeners = /* @__PURE__ */ new Set();
|
|
2928
|
+
#controllers = /* @__PURE__ */ new Map();
|
|
2929
|
+
#watchedJobs = /* @__PURE__ */ new Map();
|
|
2930
|
+
#mediaCardClaims = /* @__PURE__ */ new Map();
|
|
2931
|
+
#mediaCardListeners = /* @__PURE__ */ new Set();
|
|
2932
|
+
#sessionReferences = /* @__PURE__ */ new Map();
|
|
2933
|
+
#sessionReleaseTimers = /* @__PURE__ */ new Map();
|
|
2934
|
+
#mediaCardVersion = 0;
|
|
2935
|
+
#mediaCardOrder = 0;
|
|
2936
|
+
#snapshot = {
|
|
2937
|
+
open: false,
|
|
2938
|
+
sessionId: null,
|
|
2939
|
+
controller: null,
|
|
2940
|
+
draft: "",
|
|
2941
|
+
inputActions: null
|
|
2942
|
+
};
|
|
2943
|
+
#trigger = null;
|
|
2944
|
+
#splitActive = false;
|
|
2945
|
+
constructor(rpc, layout, splitViewport = isSplitViewport) {
|
|
2946
|
+
this.#rpc = rpc;
|
|
2947
|
+
this.#layout = layout;
|
|
2948
|
+
this.#isSplitViewport = splitViewport;
|
|
2949
|
+
}
|
|
2950
|
+
subscribe = (listener) => {
|
|
2951
|
+
this.#listeners.add(listener);
|
|
2952
|
+
return () => this.#listeners.delete(listener);
|
|
2953
|
+
};
|
|
2954
|
+
getSnapshot = () => this.#snapshot;
|
|
2955
|
+
subscribeMediaCards = (listener) => {
|
|
2956
|
+
this.#mediaCardListeners.add(listener);
|
|
2957
|
+
return () => this.#mediaCardListeners.delete(listener);
|
|
2958
|
+
};
|
|
2959
|
+
getMediaCardVersion = () => this.#mediaCardVersion;
|
|
2960
|
+
claimMediaCard(sessionId, jobId, callId, operation) {
|
|
2961
|
+
const key = `${sessionId}\n${jobId}`;
|
|
2962
|
+
const claims = this.#mediaCardClaims.get(key) ?? /* @__PURE__ */ new Map();
|
|
2963
|
+
if (claims.has(callId)) return () => void 0;
|
|
2964
|
+
claims.set(callId, {
|
|
2965
|
+
operation,
|
|
2966
|
+
order: this.#mediaCardOrder++
|
|
2967
|
+
});
|
|
2968
|
+
this.#mediaCardClaims.set(key, claims);
|
|
2969
|
+
this.#publishMediaCards();
|
|
2970
|
+
return () => {
|
|
2971
|
+
const current = this.#mediaCardClaims.get(key);
|
|
2972
|
+
if (current?.delete(callId) !== true) return;
|
|
2973
|
+
if (current.size === 0) this.#mediaCardClaims.delete(key);
|
|
2974
|
+
this.#publishMediaCards();
|
|
2975
|
+
};
|
|
2976
|
+
}
|
|
2977
|
+
isMediaCardPrimary(sessionId, jobId, callId, operation) {
|
|
2978
|
+
const claims = this.#mediaCardClaims.get(`${sessionId}\n${jobId}`);
|
|
2979
|
+
if (claims === void 0 || claims.size === 0) return true;
|
|
2980
|
+
let primaryCallId = callId;
|
|
2981
|
+
let primary = {
|
|
2982
|
+
operation,
|
|
2983
|
+
order: Number.MAX_SAFE_INTEGER
|
|
2984
|
+
};
|
|
2985
|
+
for (const [candidateCallId, candidate] of claims) if (compareMediaCardClaims(candidate, primary) < 0) {
|
|
2986
|
+
primaryCallId = candidateCallId;
|
|
2987
|
+
primary = candidate;
|
|
2988
|
+
}
|
|
2989
|
+
return primaryCallId === callId;
|
|
2990
|
+
}
|
|
2991
|
+
controllerForSession(sessionId) {
|
|
2992
|
+
const existing = this.#controllers.get(sessionId);
|
|
2993
|
+
if (existing !== void 0) return existing;
|
|
2994
|
+
const controller = new DesignController(this.#rpc, sessionId);
|
|
2995
|
+
this.#controllers.set(sessionId, controller);
|
|
2996
|
+
return controller;
|
|
2997
|
+
}
|
|
2998
|
+
retainSession(sessionId) {
|
|
2999
|
+
const pendingRelease = this.#sessionReleaseTimers.get(sessionId);
|
|
3000
|
+
if (pendingRelease !== void 0) {
|
|
3001
|
+
window.clearTimeout(pendingRelease);
|
|
3002
|
+
this.#sessionReleaseTimers.delete(sessionId);
|
|
3003
|
+
}
|
|
3004
|
+
this.#sessionReferences.set(sessionId, (this.#sessionReferences.get(sessionId) ?? 0) + 1);
|
|
3005
|
+
let retained = true;
|
|
3006
|
+
return () => {
|
|
3007
|
+
if (!retained) return;
|
|
3008
|
+
retained = false;
|
|
3009
|
+
const remaining = Math.max(0, (this.#sessionReferences.get(sessionId) ?? 1) - 1);
|
|
3010
|
+
if (remaining > 0) {
|
|
3011
|
+
this.#sessionReferences.set(sessionId, remaining);
|
|
3012
|
+
return;
|
|
3013
|
+
}
|
|
3014
|
+
this.#sessionReferences.delete(sessionId);
|
|
3015
|
+
const timer = window.setTimeout(() => {
|
|
3016
|
+
this.#sessionReleaseTimers.delete(sessionId);
|
|
3017
|
+
if ((this.#sessionReferences.get(sessionId) ?? 0) === 0) this.releaseSession(sessionId);
|
|
3018
|
+
}, 0);
|
|
3019
|
+
this.#sessionReleaseTimers.set(sessionId, timer);
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
watchJob(sessionId, jobId, initialStatus) {
|
|
3023
|
+
if (initialStatus !== "running") return () => void 0;
|
|
3024
|
+
const key = `${sessionId}\n${jobId}`;
|
|
3025
|
+
const existing = this.#watchedJobs.get(key);
|
|
3026
|
+
if (existing !== void 0) {
|
|
3027
|
+
existing.references += 1;
|
|
3028
|
+
return () => this.#releaseJobWatch(key, existing);
|
|
3029
|
+
}
|
|
3030
|
+
const controller = this.controllerForSession(sessionId);
|
|
3031
|
+
const watched = {
|
|
3032
|
+
references: 1,
|
|
3033
|
+
timer: null,
|
|
3034
|
+
stopped: false,
|
|
3035
|
+
unsubscribeStore: () => void 0
|
|
3036
|
+
};
|
|
3037
|
+
const liveStatus = () => controller.store.getSnapshot().data?.jobs.find((job) => job.jobId === jobId)?.status;
|
|
3038
|
+
const stopWhenTerminal = () => {
|
|
3039
|
+
const status = liveStatus();
|
|
3040
|
+
if (status === void 0 || status === "running") return;
|
|
3041
|
+
watched.stopped = true;
|
|
3042
|
+
if (watched.timer !== null) window.clearTimeout(watched.timer);
|
|
3043
|
+
watched.timer = null;
|
|
3044
|
+
};
|
|
3045
|
+
const poll = async () => {
|
|
3046
|
+
watched.timer = null;
|
|
3047
|
+
if (watched.stopped) return;
|
|
3048
|
+
await controller.load();
|
|
3049
|
+
stopWhenTerminal();
|
|
3050
|
+
if (!watched.stopped && watched.references > 0) watched.timer = window.setTimeout(() => {
|
|
3051
|
+
poll();
|
|
3052
|
+
}, 5e3);
|
|
3053
|
+
};
|
|
3054
|
+
watched.unsubscribeStore = controller.store.subscribe(stopWhenTerminal);
|
|
3055
|
+
this.#watchedJobs.set(key, watched);
|
|
3056
|
+
watched.timer = window.setTimeout(() => {
|
|
3057
|
+
poll();
|
|
3058
|
+
}, 0);
|
|
3059
|
+
return () => this.#releaseJobWatch(key, watched);
|
|
3060
|
+
}
|
|
3061
|
+
open(sessionId, inputActions, draft, trigger) {
|
|
3062
|
+
const controller = this.controllerForSession(sessionId);
|
|
3063
|
+
this.#trigger = trigger;
|
|
3064
|
+
this.#syncSplit(this.#isSplitViewport());
|
|
3065
|
+
this.#publish({
|
|
3066
|
+
open: true,
|
|
3067
|
+
sessionId,
|
|
3068
|
+
controller,
|
|
3069
|
+
draft,
|
|
3070
|
+
inputActions
|
|
3071
|
+
});
|
|
3072
|
+
}
|
|
3073
|
+
close(restoreFocus = true) {
|
|
3074
|
+
if (!this.#snapshot.open) return;
|
|
3075
|
+
this.#syncSplit(false);
|
|
3076
|
+
this.#publish({
|
|
3077
|
+
...this.#snapshot,
|
|
3078
|
+
open: false
|
|
3079
|
+
});
|
|
3080
|
+
if (restoreFocus) queueMicrotask(() => this.#trigger?.focus());
|
|
3081
|
+
}
|
|
3082
|
+
setSplitMode(enabled) {
|
|
3083
|
+
if (!this.#snapshot.open) return;
|
|
3084
|
+
this.#syncSplit(enabled);
|
|
3085
|
+
}
|
|
3086
|
+
updateSession(sessionId, inputActions, draft) {
|
|
3087
|
+
if (this.#snapshot.sessionId !== sessionId) return;
|
|
3088
|
+
this.#publish({
|
|
3089
|
+
...this.#snapshot,
|
|
3090
|
+
inputActions,
|
|
3091
|
+
draft
|
|
3092
|
+
});
|
|
3093
|
+
}
|
|
3094
|
+
releaseSession(sessionId) {
|
|
3095
|
+
if (this.#snapshot.sessionId !== sessionId) return;
|
|
3096
|
+
this.#syncSplit(false);
|
|
3097
|
+
this.#trigger = null;
|
|
3098
|
+
this.#publish({
|
|
3099
|
+
open: false,
|
|
3100
|
+
sessionId: null,
|
|
3101
|
+
controller: null,
|
|
3102
|
+
draft: "",
|
|
3103
|
+
inputActions: null
|
|
3104
|
+
});
|
|
3105
|
+
}
|
|
3106
|
+
#releaseJobWatch(key, watched) {
|
|
3107
|
+
if (this.#watchedJobs.get(key) !== watched) return;
|
|
3108
|
+
watched.references -= 1;
|
|
3109
|
+
if (watched.references > 0) return;
|
|
3110
|
+
watched.stopped = true;
|
|
3111
|
+
if (watched.timer !== null) window.clearTimeout(watched.timer);
|
|
3112
|
+
watched.unsubscribeStore();
|
|
3113
|
+
this.#watchedJobs.delete(key);
|
|
3114
|
+
}
|
|
3115
|
+
appendUrl(url) {
|
|
3116
|
+
const actions = this.#snapshot.inputActions;
|
|
3117
|
+
if (actions === null) return;
|
|
3118
|
+
const current = this.#snapshot.draft;
|
|
3119
|
+
const next = `${current}${current === "" || /\s$/u.test(current) ? "" : "\n"}${url}`;
|
|
3120
|
+
actions.setDraft(next);
|
|
3121
|
+
this.#publish({
|
|
3122
|
+
...this.#snapshot,
|
|
3123
|
+
draft: next
|
|
3124
|
+
});
|
|
3125
|
+
}
|
|
3126
|
+
#publish(snapshot) {
|
|
3127
|
+
this.#snapshot = snapshot;
|
|
3128
|
+
for (const listener of this.#listeners) listener();
|
|
3129
|
+
}
|
|
3130
|
+
#publishMediaCards() {
|
|
3131
|
+
this.#mediaCardVersion += 1;
|
|
3132
|
+
for (const listener of this.#mediaCardListeners) listener();
|
|
3133
|
+
}
|
|
3134
|
+
#syncSplit(enabled) {
|
|
3135
|
+
if (enabled === this.#splitActive) return;
|
|
3136
|
+
if (enabled) {
|
|
3137
|
+
this.#layout.closeDetails();
|
|
3138
|
+
this.#layout.openDetails();
|
|
3139
|
+
} else this.#layout.closeDetails();
|
|
3140
|
+
this.#splitActive = enabled;
|
|
3141
|
+
}
|
|
3142
|
+
};
|
|
3143
|
+
function compareMediaCardClaims(left, right) {
|
|
3144
|
+
return (left.operation === "generate" ? 0 : 1) - (right.operation === "generate" ? 0 : 1) || left.order - right.order;
|
|
3145
|
+
}
|
|
3146
|
+
function ModellixDesignLauncher({ drawer, inputActions, sessionId, t, useInput }) {
|
|
3147
|
+
const draft = useInput((state) => state.draft);
|
|
3148
|
+
const snapshot = (0, react.useSyncExternalStore)(drawer.subscribe, drawer.getSnapshot, drawer.getSnapshot);
|
|
3149
|
+
const active = snapshot.open && snapshot.sessionId === String(sessionId);
|
|
3150
|
+
(0, react.useEffect)(() => {
|
|
3151
|
+
drawer.updateSession(String(sessionId), inputActions, draft);
|
|
3152
|
+
}, [
|
|
3153
|
+
draft,
|
|
3154
|
+
drawer,
|
|
3155
|
+
inputActions,
|
|
3156
|
+
sessionId
|
|
3157
|
+
]);
|
|
3158
|
+
(0, react.useEffect)(() => drawer.retainSession(String(sessionId)), [drawer, sessionId]);
|
|
3159
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3160
|
+
type: "button",
|
|
3161
|
+
variant: "outline",
|
|
3162
|
+
className: "mdlx-design-launcher",
|
|
3163
|
+
"aria-label": t("designTitle"),
|
|
3164
|
+
"aria-expanded": active,
|
|
3165
|
+
"aria-controls": "mdlx-design-drawer",
|
|
3166
|
+
onClick: (event) => {
|
|
3167
|
+
if (active) drawer.close();
|
|
3168
|
+
else drawer.open(String(sessionId), inputActions, draft, event.currentTarget);
|
|
3169
|
+
},
|
|
3170
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3171
|
+
className: "mdlx-launcher-label",
|
|
3172
|
+
children: t("designTitle")
|
|
3173
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3174
|
+
className: "mdlx-launcher-compact",
|
|
3175
|
+
"aria-hidden": "true",
|
|
3176
|
+
children: "M"
|
|
3177
|
+
})]
|
|
3178
|
+
});
|
|
3179
|
+
}
|
|
3180
|
+
function ModellixDesignDrawer({ drawer, settingsController, t }) {
|
|
3181
|
+
const snapshot = (0, react.useSyncExternalStore)(drawer.subscribe, drawer.getSnapshot, drawer.getSnapshot);
|
|
3182
|
+
const [retainedSnapshot, setRetainedSnapshot] = (0, react.useState)(snapshot.open && snapshot.controller !== null ? snapshot : null);
|
|
3183
|
+
const [advancedEditorOpen, setAdvancedEditorOpen] = (0, react.useState)(false);
|
|
3184
|
+
(0, react.useEffect)(() => {
|
|
3185
|
+
if (snapshot.open && snapshot.controller !== null) setRetainedSnapshot(snapshot);
|
|
3186
|
+
}, [
|
|
3187
|
+
snapshot.controller,
|
|
3188
|
+
snapshot.open,
|
|
3189
|
+
snapshot.sessionId
|
|
3190
|
+
]);
|
|
3191
|
+
(0, react.useEffect)(() => {
|
|
3192
|
+
if (snapshot.open || retainedSnapshot === null) return;
|
|
3193
|
+
const timer = window.setTimeout(() => setRetainedSnapshot(null), MODELLIX_DRAWER_EXIT_MS);
|
|
3194
|
+
return () => window.clearTimeout(timer);
|
|
3195
|
+
}, [retainedSnapshot, snapshot.open]);
|
|
3196
|
+
(0, react.useEffect)(() => {
|
|
3197
|
+
setAdvancedEditorOpen(false);
|
|
3198
|
+
}, [snapshot.sessionId]);
|
|
3199
|
+
(0, react.useEffect)(() => {
|
|
3200
|
+
if (!snapshot.open || typeof window.matchMedia !== "function") return;
|
|
3201
|
+
const media = window.matchMedia(MODELLIX_DESIGN_SPLIT_MEDIA_QUERY);
|
|
3202
|
+
const sync = () => drawer.setSplitMode(media.matches);
|
|
3203
|
+
sync();
|
|
3204
|
+
media.addEventListener("change", sync);
|
|
3205
|
+
return () => media.removeEventListener("change", sync);
|
|
3206
|
+
}, [drawer, snapshot.open]);
|
|
3207
|
+
const presentedSnapshot = snapshot.open && snapshot.controller !== null ? snapshot : retainedSnapshot;
|
|
3208
|
+
if (presentedSnapshot === null || presentedSnapshot.controller === null) return null;
|
|
3209
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3210
|
+
className: "mdlx-design-drawer-viewport",
|
|
3211
|
+
"data-closing": !snapshot.open || void 0,
|
|
3212
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
3213
|
+
id: "mdlx-design-drawer",
|
|
3214
|
+
className: "mdlx-design-drawer",
|
|
3215
|
+
"aria-labelledby": "mdlx-design-drawer-title",
|
|
3216
|
+
onKeyDown: (event) => {
|
|
3217
|
+
if (event.key === "Escape") {
|
|
3218
|
+
event.preventDefault();
|
|
3219
|
+
drawer.close();
|
|
3220
|
+
}
|
|
3221
|
+
},
|
|
3222
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
3223
|
+
className: "mdlx-drawer-header",
|
|
3224
|
+
"data-editor-open": advancedEditorOpen || void 0,
|
|
3225
|
+
children: [
|
|
3226
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3227
|
+
type: "button",
|
|
3228
|
+
variant: "ghost",
|
|
3229
|
+
size: "sm",
|
|
3230
|
+
className: "mdlx-drawer-close",
|
|
3231
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 16 }),
|
|
3232
|
+
"aria-label": `${t("close")} ${t("designTitle")}`,
|
|
3233
|
+
onClick: () => drawer.close()
|
|
3234
|
+
}),
|
|
3235
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3236
|
+
className: "mdlx-heading",
|
|
3237
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
3238
|
+
id: "mdlx-design-drawer-title",
|
|
3239
|
+
children: t("designTitle")
|
|
3240
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3241
|
+
className: "mdlx-muted",
|
|
3242
|
+
children: t("designDescription")
|
|
3243
|
+
})]
|
|
3244
|
+
}),
|
|
3245
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3246
|
+
className: "mdlx-drawer-header-reveal",
|
|
3247
|
+
hidden: MODELLIX_ADVANCED_EDITOR_ENTRY_HIDDEN,
|
|
3248
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3249
|
+
type: "button",
|
|
3250
|
+
variant: "outline",
|
|
3251
|
+
className: "mdlx-drawer-editor-toggle",
|
|
3252
|
+
"aria-controls": "mdlx-design-editor",
|
|
3253
|
+
"aria-expanded": advancedEditorOpen,
|
|
3254
|
+
onClick: (event) => {
|
|
3255
|
+
const next = !advancedEditorOpen;
|
|
3256
|
+
setAdvancedEditorOpen(next);
|
|
3257
|
+
if (!next && event.detail > 0) event.currentTarget.blur();
|
|
3258
|
+
},
|
|
3259
|
+
children: t("advancedEditor")
|
|
3260
|
+
}) })
|
|
3261
|
+
})
|
|
3262
|
+
]
|
|
3263
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3264
|
+
className: "mdlx-drawer-body",
|
|
3265
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModellixDesignView, {
|
|
3266
|
+
advancedEditorOpen,
|
|
3267
|
+
controller: presentedSnapshot.controller,
|
|
3268
|
+
settingsController,
|
|
3269
|
+
onAddUrl: (url) => drawer.appendUrl(url),
|
|
3270
|
+
t
|
|
3271
|
+
})
|
|
3272
|
+
})]
|
|
3273
|
+
})
|
|
3274
|
+
});
|
|
3275
|
+
}
|
|
3276
|
+
//#endregion
|
|
3277
|
+
//#region src/client/MediaToolView.tsx
|
|
3278
|
+
function ModellixMediaToolView({ block, drawer, inputActions, sessionId, t, useInput }) {
|
|
3279
|
+
const draft = useInput((state) => state.draft);
|
|
3280
|
+
const [tab, setTab] = (0, react.useState)("preview");
|
|
3281
|
+
const [activeIndex, setActiveIndex] = (0, react.useState)(0);
|
|
3282
|
+
const [imageOpen, setImageOpen] = (0, react.useState)(false);
|
|
3283
|
+
const tabId = (0, react.useId)();
|
|
3284
|
+
const imageDialogRef = (0, react.useRef)(null);
|
|
3285
|
+
const isResultBlock = "kind" in block && block.kind === "tool-result";
|
|
3286
|
+
const parsedResult = isResultBlock ? parseMediaToolResult(block.meta) : null;
|
|
3287
|
+
const liveState = useResourceState(drawer.controllerForSession(String(sessionId)).store);
|
|
3288
|
+
const trackedJobId = mediaToolJobId(parsedResult);
|
|
3289
|
+
const operation = parsedResult?.operation;
|
|
3290
|
+
const callId = "callId" in block && typeof block.callId === "string" ? block.callId : `${String(sessionId)}:${trackedJobId ?? "pending"}`;
|
|
3291
|
+
(0, react.useSyncExternalStore)(drawer.subscribeMediaCards, drawer.getMediaCardVersion, drawer.getMediaCardVersion);
|
|
3292
|
+
const parsedStatus = mediaToolStatus(parsedResult);
|
|
3293
|
+
const result = resolveLiveMediaToolResult(parsedResult, trackedJobId === void 0 ? void 0 : liveState.data?.jobs.find((job) => job.jobId === trackedJobId), t);
|
|
3294
|
+
(0, react.useEffect)(() => trackedJobId === void 0 ? void 0 : drawer.watchJob(String(sessionId), trackedJobId, parsedStatus), [
|
|
3295
|
+
drawer,
|
|
3296
|
+
parsedStatus,
|
|
3297
|
+
sessionId,
|
|
3298
|
+
trackedJobId
|
|
3299
|
+
]);
|
|
3300
|
+
(0, react.useEffect)(() => trackedJobId === void 0 || operation === void 0 ? void 0 : drawer.claimMediaCard(String(sessionId), trackedJobId, callId, operation), [
|
|
3301
|
+
callId,
|
|
3302
|
+
drawer,
|
|
3303
|
+
operation,
|
|
3304
|
+
sessionId,
|
|
3305
|
+
trackedJobId
|
|
3306
|
+
]);
|
|
3307
|
+
const resources = result?.operation === "get_result" ? result.job?.resources ?? [] : result?.resources ?? [];
|
|
3308
|
+
const resourceIndex = resources.length === 0 ? 0 : activeIndex % resources.length;
|
|
3309
|
+
const current = resources[resourceIndex];
|
|
3310
|
+
const imageSurfaceOpen = useExternalDialogGate(imageOpen && current?.kind === "image");
|
|
3311
|
+
const closeImage = (0, react.useCallback)(() => setImageOpen(false), []);
|
|
3312
|
+
useDialogA11y({
|
|
3313
|
+
open: imageSurfaceOpen,
|
|
3314
|
+
container: imageDialogRef,
|
|
3315
|
+
initialFocusSelector: "[data-mdlx-initial-focus]",
|
|
3316
|
+
mandatory: false,
|
|
3317
|
+
onEscape: closeImage
|
|
3318
|
+
});
|
|
3319
|
+
(0, react.useEffect)(() => setImageOpen(false), [current?.url]);
|
|
3320
|
+
if (trackedJobId !== void 0 && operation !== void 0 && !drawer.isMediaCardPrimary(String(sessionId), trackedJobId, callId, operation)) return null;
|
|
3321
|
+
if (!isResultBlock) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3322
|
+
className: "mdlx-tool-result mdlx-muted",
|
|
3323
|
+
role: "status",
|
|
3324
|
+
children: t("generating")
|
|
3325
|
+
});
|
|
3326
|
+
if (result === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3327
|
+
className: "mdlx-tool-result mdlx-muted",
|
|
3328
|
+
role: "status",
|
|
3329
|
+
children: t("noPreview")
|
|
3330
|
+
});
|
|
3331
|
+
const status = result.operation === "get_result" ? result.job?.status : result.status;
|
|
3332
|
+
const modelId = result.operation === "get_result" ? result.job?.modelId : result.modelId;
|
|
3333
|
+
const diagnostic = result.operation === "get_result" ? result.job?.diagnostic : result.diagnostic;
|
|
3334
|
+
const succeeded = status === "succeeded";
|
|
3335
|
+
const activeTabId = `${tabId}-${tab}-tab`;
|
|
3336
|
+
const activePanelId = `${tabId}-${tab}-panel`;
|
|
3337
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
3338
|
+
className: "mdlx-tool-result",
|
|
3339
|
+
children: [
|
|
3340
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3341
|
+
className: "mdlx-result-head",
|
|
3342
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: result.found === false ? t("resultNotFound") : mediaStatusLabel(status, t) }), modelId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3343
|
+
className: "mdlx-muted",
|
|
3344
|
+
children: modelId
|
|
3345
|
+
})]
|
|
3346
|
+
}),
|
|
3347
|
+
succeeded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3348
|
+
className: "mdlx-result-tabs",
|
|
3349
|
+
role: "tablist",
|
|
3350
|
+
"aria-label": t("resultViewLabel"),
|
|
3351
|
+
onKeyDown: handleResultTabKeyDown,
|
|
3352
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3353
|
+
id: `${tabId}-preview-tab`,
|
|
3354
|
+
type: "button",
|
|
3355
|
+
role: "tab",
|
|
3356
|
+
"aria-controls": `${tabId}-preview-panel`,
|
|
3357
|
+
"aria-selected": tab === "preview",
|
|
3358
|
+
tabIndex: tab === "preview" ? 0 : -1,
|
|
3359
|
+
className: "mdlx-result-tab",
|
|
3360
|
+
onClick: () => setTab("preview"),
|
|
3361
|
+
children: t("previewTab")
|
|
3362
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3363
|
+
id: `${tabId}-json-tab`,
|
|
3364
|
+
type: "button",
|
|
3365
|
+
role: "tab",
|
|
3366
|
+
"aria-controls": `${tabId}-json-panel`,
|
|
3367
|
+
"aria-selected": tab === "json",
|
|
3368
|
+
tabIndex: tab === "json" ? 0 : -1,
|
|
3369
|
+
className: "mdlx-result-tab",
|
|
3370
|
+
onClick: () => setTab("json"),
|
|
3371
|
+
children: t("jsonTab")
|
|
3372
|
+
})]
|
|
3373
|
+
}), tab === "json" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
3374
|
+
id: activePanelId,
|
|
3375
|
+
role: "tabpanel",
|
|
3376
|
+
"aria-labelledby": activeTabId,
|
|
3377
|
+
className: "mdlx-result-json",
|
|
3378
|
+
children: JSON.stringify(result, null, 2)
|
|
3379
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3380
|
+
id: activePanelId,
|
|
3381
|
+
role: "tabpanel",
|
|
3382
|
+
"aria-labelledby": activeTabId,
|
|
3383
|
+
className: "mdlx-result-panel",
|
|
3384
|
+
children: current === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3385
|
+
className: "mdlx-empty mdlx-empty-compact",
|
|
3386
|
+
children: t("noPreview")
|
|
3387
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3388
|
+
current.kind === "image" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3389
|
+
type: "button",
|
|
3390
|
+
className: "mdlx-image-preview-button",
|
|
3391
|
+
"aria-label": t("openImage"),
|
|
3392
|
+
onClick: () => setImageOpen(true),
|
|
3393
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignResultPreview, {
|
|
3394
|
+
resource: toWireResource(current, resourceIndex),
|
|
3395
|
+
t
|
|
3396
|
+
})
|
|
3397
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignResultPreview, {
|
|
3398
|
+
resource: toWireResource(current, resourceIndex),
|
|
3399
|
+
t
|
|
3400
|
+
}),
|
|
3401
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3402
|
+
className: "mdlx-actions mdlx-actions-start",
|
|
3403
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3404
|
+
type: "button",
|
|
3405
|
+
variant: "outline",
|
|
3406
|
+
onClick: () => {
|
|
3407
|
+
const separator = draft === "" || /\s$/u.test(draft) ? "" : "\n";
|
|
3408
|
+
inputActions.setDraft(`${draft}${separator}${current.url}`);
|
|
3409
|
+
},
|
|
3410
|
+
children: t("addUrlToChat")
|
|
3411
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
3412
|
+
className: "mdlx-safe-link",
|
|
3413
|
+
href: current.url,
|
|
3414
|
+
target: "_blank",
|
|
3415
|
+
rel: "noopener noreferrer",
|
|
3416
|
+
referrerPolicy: "no-referrer",
|
|
3417
|
+
download: true,
|
|
3418
|
+
children: t("download")
|
|
3419
|
+
})]
|
|
3420
|
+
}),
|
|
3421
|
+
resources.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3422
|
+
className: "mdlx-resource-nav",
|
|
3423
|
+
"aria-label": t("resourceNavigation"),
|
|
3424
|
+
children: [
|
|
3425
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3426
|
+
type: "button",
|
|
3427
|
+
variant: "outline",
|
|
3428
|
+
onClick: () => setActiveIndex((resourceIndex - 1 + resources.length) % resources.length),
|
|
3429
|
+
children: t("previousResource")
|
|
3430
|
+
}),
|
|
3431
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3432
|
+
className: "mdlx-muted",
|
|
3433
|
+
children: t("resourcePosition", {
|
|
3434
|
+
current: resourceIndex + 1,
|
|
3435
|
+
total: resources.length
|
|
3436
|
+
})
|
|
3437
|
+
}),
|
|
3438
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3439
|
+
type: "button",
|
|
3440
|
+
variant: "outline",
|
|
3441
|
+
onClick: () => setActiveIndex((resourceIndex + 1) % resources.length),
|
|
3442
|
+
children: t("nextResource")
|
|
3443
|
+
})
|
|
3444
|
+
]
|
|
3445
|
+
})
|
|
3446
|
+
] })
|
|
3447
|
+
})] }),
|
|
3448
|
+
diagnostic !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3449
|
+
className: "mdlx-error",
|
|
3450
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
3451
|
+
className: "mdlx-code",
|
|
3452
|
+
children: diagnostic.code
|
|
3453
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: diagnostic.message })]
|
|
3454
|
+
})
|
|
3455
|
+
]
|
|
3456
|
+
}), succeeded && current?.kind === "image" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
3457
|
+
open: imageSurfaceOpen,
|
|
3458
|
+
title: t("imageViewerTitle"),
|
|
3459
|
+
onClose: closeImage,
|
|
3460
|
+
headless: true,
|
|
3461
|
+
className: "mdlx-modal mdlx-image-modal",
|
|
3462
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3463
|
+
ref: imageDialogRef,
|
|
3464
|
+
className: "mdlx-modal-content",
|
|
3465
|
+
"data-mdlx-dialog-surface": "",
|
|
3466
|
+
tabIndex: -1,
|
|
3467
|
+
children: [
|
|
3468
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3469
|
+
className: "mdlx-heading",
|
|
3470
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
3471
|
+
className: "mdlx-modal-title",
|
|
3472
|
+
children: t("imageViewerTitle")
|
|
3473
|
+
})
|
|
3474
|
+
}),
|
|
3475
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
3476
|
+
className: "mdlx-image-full",
|
|
3477
|
+
src: current.url,
|
|
3478
|
+
alt: t("generatedPreview"),
|
|
3479
|
+
referrerPolicy: "no-referrer"
|
|
3480
|
+
}),
|
|
3481
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3482
|
+
className: "mdlx-actions",
|
|
3483
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3484
|
+
type: "button",
|
|
3485
|
+
variant: "outline",
|
|
3486
|
+
"data-mdlx-initial-focus": "",
|
|
3487
|
+
onClick: closeImage,
|
|
3488
|
+
children: t("close")
|
|
3489
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
3490
|
+
className: "mdlx-safe-link",
|
|
3491
|
+
href: current.url,
|
|
3492
|
+
target: "_blank",
|
|
3493
|
+
rel: "noopener noreferrer",
|
|
3494
|
+
referrerPolicy: "no-referrer",
|
|
3495
|
+
download: true,
|
|
3496
|
+
children: t("download")
|
|
3497
|
+
})]
|
|
3498
|
+
})
|
|
3499
|
+
]
|
|
3500
|
+
})
|
|
3501
|
+
})] });
|
|
3502
|
+
}
|
|
3503
|
+
function mediaToolJobId(result) {
|
|
3504
|
+
return result?.operation === "get_result" ? result.job?.jobId : result?.jobId;
|
|
3505
|
+
}
|
|
3506
|
+
function mediaToolStatus(result) {
|
|
3507
|
+
return result?.operation === "get_result" ? result.job?.status : result?.status;
|
|
3508
|
+
}
|
|
3509
|
+
function resolveLiveMediaToolResult(result, liveJob, t) {
|
|
3510
|
+
if (result === null || liveJob === void 0) return result;
|
|
3511
|
+
const resources = liveJob.resources.map((resource) => ({
|
|
3512
|
+
kind: resource.kind,
|
|
3513
|
+
url: resource.url,
|
|
3514
|
+
...resource.expiresAt === null ? {} : { expiresAt: resource.expiresAt }
|
|
3515
|
+
}));
|
|
3516
|
+
const diagnostic = liveJob.diagnostic === null ? void 0 : {
|
|
3517
|
+
code: liveJob.diagnostic.code,
|
|
3518
|
+
message: t(designDiagnosticMessageKey(liveJob.diagnostic.code))
|
|
3519
|
+
};
|
|
3520
|
+
if (result.operation === "generate") {
|
|
3521
|
+
const { diagnostic: _staleDiagnostic, ...withoutDiagnostic } = result;
|
|
3522
|
+
return {
|
|
3523
|
+
...withoutDiagnostic,
|
|
3524
|
+
status: liveJob.status,
|
|
3525
|
+
modelId: liveJob.modelId,
|
|
3526
|
+
resources,
|
|
3527
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3528
|
+
};
|
|
3529
|
+
}
|
|
3530
|
+
return {
|
|
3531
|
+
...result,
|
|
3532
|
+
found: true,
|
|
3533
|
+
job: {
|
|
3534
|
+
jobId: liveJob.jobId,
|
|
3535
|
+
modelId: liveJob.modelId,
|
|
3536
|
+
status: liveJob.status,
|
|
3537
|
+
resources,
|
|
3538
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3539
|
+
}
|
|
3540
|
+
};
|
|
3541
|
+
}
|
|
3542
|
+
function parseMediaToolResult(value) {
|
|
3543
|
+
const root = record(value);
|
|
3544
|
+
if (root === null || root.service !== "media" || root.operation !== "generate" && root.operation !== "get_result") return null;
|
|
3545
|
+
if (root.operation === "generate") {
|
|
3546
|
+
const status = safeText(root.status, 64);
|
|
3547
|
+
const modelId = safeText(root.modelId, 256);
|
|
3548
|
+
const jobId = safeText(root.jobId, 256);
|
|
3549
|
+
const diagnostic = parseDiagnostic(root.diagnostic);
|
|
3550
|
+
return {
|
|
3551
|
+
operation: "generate",
|
|
3552
|
+
...status === void 0 ? {} : { status },
|
|
3553
|
+
...modelId === void 0 ? {} : { modelId },
|
|
3554
|
+
...jobId === void 0 ? {} : { jobId },
|
|
3555
|
+
resources: parseResources(root.resources),
|
|
3556
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3557
|
+
};
|
|
3558
|
+
}
|
|
3559
|
+
const job = record(root.job);
|
|
3560
|
+
const diagnostic = job === null ? void 0 : parseDiagnostic(job.diagnostic);
|
|
3561
|
+
return {
|
|
3562
|
+
operation: "get_result",
|
|
3563
|
+
found: root.found === true,
|
|
3564
|
+
...job === null ? {} : { job: {
|
|
3565
|
+
jobId: safeText(job.jobId, 256) ?? "",
|
|
3566
|
+
modelId: safeText(job.modelId, 256) ?? "",
|
|
3567
|
+
status: safeText(job.status, 64) ?? "",
|
|
3568
|
+
resources: parseResources(job.resources),
|
|
3569
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3570
|
+
} }
|
|
3571
|
+
};
|
|
3572
|
+
}
|
|
3573
|
+
function parseResources(value) {
|
|
3574
|
+
if (!Array.isArray(value)) return [];
|
|
3575
|
+
const resources = [];
|
|
3576
|
+
for (const candidate of value.slice(0, 32)) {
|
|
3577
|
+
const resource = record(candidate);
|
|
3578
|
+
if (resource === null || resource.kind !== "image" && resource.kind !== "video" && resource.kind !== "audio" || typeof resource.url !== "string") continue;
|
|
3579
|
+
let url;
|
|
3580
|
+
try {
|
|
3581
|
+
url = safeResourceHref(resource.url);
|
|
3582
|
+
} catch {
|
|
3583
|
+
continue;
|
|
3584
|
+
}
|
|
3585
|
+
const expiresAt = safeText(resource.expiresAt, 128);
|
|
3586
|
+
resources.push({
|
|
3587
|
+
kind: resource.kind,
|
|
3588
|
+
url,
|
|
3589
|
+
...expiresAt === void 0 ? {} : { expiresAt }
|
|
3590
|
+
});
|
|
3591
|
+
}
|
|
3592
|
+
return resources;
|
|
3593
|
+
}
|
|
3594
|
+
function parseDiagnostic(value) {
|
|
3595
|
+
const diagnostic = record(value);
|
|
3596
|
+
if (diagnostic === null) return void 0;
|
|
3597
|
+
const code = safeText(diagnostic.code, 128);
|
|
3598
|
+
const message = safeText(diagnostic.message, 1024);
|
|
3599
|
+
return code === void 0 || message === void 0 ? void 0 : {
|
|
3600
|
+
code,
|
|
3601
|
+
message
|
|
3602
|
+
};
|
|
3603
|
+
}
|
|
3604
|
+
function safeText(value, maximum) {
|
|
3605
|
+
return typeof value === "string" && value.length > 0 && value.length <= maximum ? value : void 0;
|
|
3606
|
+
}
|
|
3607
|
+
function record(value) {
|
|
3608
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
3609
|
+
}
|
|
3610
|
+
function mediaStatusLabel(status, t) {
|
|
3611
|
+
switch (status) {
|
|
3612
|
+
case "running": return t("running");
|
|
3613
|
+
case "succeeded": return t("succeeded");
|
|
3614
|
+
case "failed": return t("failed");
|
|
3615
|
+
case "canceled": return t("canceled");
|
|
3616
|
+
case "expired": return t("expired");
|
|
3617
|
+
case "submit-unknown": return t("unknown");
|
|
3618
|
+
default: return t("unknown");
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
function toWireResource(resource, index) {
|
|
3622
|
+
return {
|
|
3623
|
+
id: `tool-resource-${String(index)}`,
|
|
3624
|
+
kind: resource.kind,
|
|
3625
|
+
url: resource.url,
|
|
3626
|
+
downloadUrl: resource.url,
|
|
3627
|
+
expiresAt: resource.expiresAt ?? null
|
|
3628
|
+
};
|
|
3629
|
+
}
|
|
3630
|
+
//#endregion
|
|
2865
3631
|
//#region src/client/locales.ts
|
|
2866
3632
|
const MODELLIX_LOCALE_NAMESPACE = "modellix";
|
|
2867
3633
|
const zh = {
|
|
2868
3634
|
dateLocale: "zh-CN",
|
|
2869
3635
|
nav: "Modellix",
|
|
2870
|
-
designTab: "Design",
|
|
2871
3636
|
onboardingTitle: "连接 Modellix",
|
|
2872
3637
|
onboardingDescription: "输入一个 Modellix API Key,即可启用 Design、LLM 模型和 Web Tools。",
|
|
2873
3638
|
keyLabel: "Modellix API Key",
|
|
@@ -2884,7 +3649,7 @@ const zh = {
|
|
|
2884
3649
|
serviceLlm: "LLM 模型",
|
|
2885
3650
|
serviceLlmDescription: "在 Harness 中快速切换 Modellix 支持的模型。",
|
|
2886
3651
|
serviceWeb: "Web Tools",
|
|
2887
|
-
serviceWebDescription: "
|
|
3652
|
+
serviceWebDescription: "提供可自动调用的 Modellix 网页搜索与读取工具。",
|
|
2888
3653
|
settingsTitle: "Modellix",
|
|
2889
3654
|
settingsDescription: "一个 API Key,统一使用 Design、LLM 与 Web Tools。",
|
|
2890
3655
|
credentialTitle: "API Key",
|
|
@@ -2927,13 +3692,13 @@ const zh = {
|
|
|
2927
3692
|
errorGeneric: "暂时无法完成操作,请重试。",
|
|
2928
3693
|
errorConflict: "配置已在其他位置更新,请刷新后重试。",
|
|
2929
3694
|
errorKeyInvalid: "这个 API Key 无效,请检查后重新输入。",
|
|
2930
|
-
errorBilling: "
|
|
3695
|
+
errorBilling: "当前请求无法完成,请在 Modellix 控制台查看账户状态。",
|
|
2931
3696
|
errorRateLimited: "请求过于频繁,请稍后手动重试。",
|
|
2932
3697
|
errorOffline: "当前无法连接 Modellix,请检查网络后重试。",
|
|
2933
3698
|
errorTimeout: "Modellix 响应超时,请稍后手动重试。",
|
|
2934
3699
|
errorServer: "Modellix 服务暂时不可用,请稍后手动重试。",
|
|
2935
3700
|
errorPolicy: "当前账户或环境策略不允许此操作。",
|
|
2936
|
-
errorSubmitUnknown: "
|
|
3701
|
+
errorSubmitUnknown: "提交结果未知。请先查看结果列表,不要重复提交。",
|
|
2937
3702
|
errorAssetExpired: "结果资源已过期,无法继续访问。",
|
|
2938
3703
|
errorDesignSchema: "模型参数定义已变化或无法解析,请刷新模型后重试。",
|
|
2939
3704
|
designTitle: "Modellix Design",
|
|
@@ -2953,11 +3718,11 @@ const zh = {
|
|
|
2953
3718
|
promptPlaceholder: "描述画面、视频动作或要合成的声音…",
|
|
2954
3719
|
parametersTitle: "参数",
|
|
2955
3720
|
advancedParameters: "高级参数({count})",
|
|
3721
|
+
advancedEditor: "高级参数编辑器",
|
|
2956
3722
|
required: "必填",
|
|
2957
3723
|
optional: "可选",
|
|
2958
3724
|
requiredMissing: "请填写所有必填参数后再生成。",
|
|
2959
3725
|
assistantTitle: "用对话调整参数",
|
|
2960
|
-
assistantPaidNotice: "发送后会使用同一个 Modellix Key 调用固定 LLM 生成参数提议,可能产生费用;不会自动生成媒体。",
|
|
2961
3726
|
assistantPlaceholder: "例如:改成 16:9,生成 8 秒视频,风格更电影化",
|
|
2962
3727
|
propose: "生成参数提议",
|
|
2963
3728
|
proposing: "正在分析…",
|
|
@@ -2969,7 +3734,6 @@ const zh = {
|
|
|
2969
3734
|
conflicts: "需要先解决冲突",
|
|
2970
3735
|
generate: "确认并生成",
|
|
2971
3736
|
generating: "正在提交…",
|
|
2972
|
-
paidNotice: "生成是计费操作;每次点击只提交一次,不会自动重试。",
|
|
2973
3737
|
designDisabled: "Design 已关闭,可在 Modellix 设置中重新开启。",
|
|
2974
3738
|
keyRequired: "请先在 Modellix 设置中配置 API Key。",
|
|
2975
3739
|
noModels: "当前没有可用模型,请稍后刷新。",
|
|
@@ -2983,9 +3747,17 @@ const zh = {
|
|
|
2983
3747
|
designNoticeCatalogUnavailable: "Modellix Design 模型目录暂时不可用,请稍后刷新。",
|
|
2984
3748
|
designNoticeCredentialReloaded: "API Key 已更改,Design 模型和参数已重新加载。",
|
|
2985
3749
|
resultsTitle: "结果",
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
3750
|
+
resultsCount: "{count} 条",
|
|
3751
|
+
resultViewLabel: "结果视图",
|
|
3752
|
+
previewTab: "预览",
|
|
3753
|
+
jsonTab: "JSON",
|
|
3754
|
+
noPreview: "当前还没有可预览的媒体结果。",
|
|
3755
|
+
resultNotFound: "未找到对应的生成任务。",
|
|
3756
|
+
resourceNavigation: "媒体结果导航",
|
|
3757
|
+
previousResource: "上一项",
|
|
3758
|
+
nextResource: "下一项",
|
|
3759
|
+
resourcePosition: "第 {current} / {total} 项",
|
|
3760
|
+
addUrlToChat: "添加 URL 到对话框",
|
|
2989
3761
|
noResults: "还没有生成记录。确认参数并生成后,结果会显示在这里。",
|
|
2990
3762
|
running: "生成中",
|
|
2991
3763
|
succeeded: "已完成",
|
|
@@ -2993,10 +3765,10 @@ const zh = {
|
|
|
2993
3765
|
canceled: "已取消",
|
|
2994
3766
|
unknown: "提交结果未知",
|
|
2995
3767
|
expired: "结果已过期",
|
|
2996
|
-
openImage: "
|
|
3768
|
+
openImage: "放大图片",
|
|
2997
3769
|
imageViewerTitle: "生成图片",
|
|
2998
3770
|
close: "关闭",
|
|
2999
|
-
download: "
|
|
3771
|
+
download: "下载",
|
|
3000
3772
|
expiresAt: "有效期至 {time}",
|
|
3001
3773
|
invalidJson: "请输入有效的 JSON。",
|
|
3002
3774
|
invalidParameter: "此参数不符合当前模型的约束。",
|
|
@@ -3007,9 +3779,9 @@ const zh = {
|
|
|
3007
3779
|
generatedAudioPreview: "生成音频结果预览",
|
|
3008
3780
|
jobModel: "模型:{model}",
|
|
3009
3781
|
jobCreated: "创建于 {time}",
|
|
3010
|
-
diagnosticRetryable: "
|
|
3782
|
+
diagnosticRetryable: "插件会继续尝试安全的只读状态查询,但绝不会自动重复生成提交。",
|
|
3011
3783
|
diagnosticCredentialChanged: "此任务属于更早的 API Key,无法继续刷新。",
|
|
3012
|
-
diagnosticSubmitUnknown: "
|
|
3784
|
+
diagnosticSubmitUnknown: "生成提交结果未知,请先检查结果列表,不要重复提交。",
|
|
3013
3785
|
diagnosticGenerationFailed: "生成任务未完成。",
|
|
3014
3786
|
diagnosticResultUnavailable: "生成已完成,但没有可用的结果资源。",
|
|
3015
3787
|
diagnosticCredentialRejected: "刷新任务时 Modellix 拒绝了当前 API Key。",
|
|
@@ -3028,7 +3800,6 @@ const zh = {
|
|
|
3028
3800
|
const en = {
|
|
3029
3801
|
dateLocale: "en-US",
|
|
3030
3802
|
nav: "Modellix",
|
|
3031
|
-
designTab: "Design",
|
|
3032
3803
|
onboardingTitle: "Connect Modellix",
|
|
3033
3804
|
onboardingDescription: "Enter one Modellix API Key to enable Design, LLM models, and Web Tools.",
|
|
3034
3805
|
keyLabel: "Modellix API Key",
|
|
@@ -3045,7 +3816,7 @@ const en = {
|
|
|
3045
3816
|
serviceLlm: "LLM models",
|
|
3046
3817
|
serviceLlmDescription: "Quickly switch between Modellix models in Harness.",
|
|
3047
3818
|
serviceWeb: "Web Tools",
|
|
3048
|
-
serviceWebDescription: "Provide Modellix
|
|
3819
|
+
serviceWebDescription: "Provide automatic Modellix Web Search and Web Fetch tools.",
|
|
3049
3820
|
settingsTitle: "Modellix",
|
|
3050
3821
|
settingsDescription: "One API Key for Design, LLM, and Web Tools.",
|
|
3051
3822
|
credentialTitle: "API Key",
|
|
@@ -3088,13 +3859,13 @@ const en = {
|
|
|
3088
3859
|
errorGeneric: "The operation could not be completed. Try again.",
|
|
3089
3860
|
errorConflict: "Settings changed elsewhere. Refresh and try again.",
|
|
3090
3861
|
errorKeyInvalid: "This API Key is invalid. Check it and enter it again.",
|
|
3091
|
-
errorBilling: "
|
|
3862
|
+
errorBilling: "This request cannot be completed. Check the account status in the Modellix console.",
|
|
3092
3863
|
errorRateLimited: "Too many requests. Wait before retrying manually.",
|
|
3093
3864
|
errorOffline: "Modellix cannot be reached. Check the network and try again.",
|
|
3094
3865
|
errorTimeout: "Modellix timed out. Retry manually later.",
|
|
3095
3866
|
errorServer: "Modellix is temporarily unavailable. Retry manually later.",
|
|
3096
3867
|
errorPolicy: "The current account or environment policy does not allow this operation.",
|
|
3097
|
-
errorSubmitUnknown: "The submission outcome is unknown. Check Results before submitting
|
|
3868
|
+
errorSubmitUnknown: "The submission outcome is unknown. Check Results before submitting again.",
|
|
3098
3869
|
errorAssetExpired: "This result resource has expired and is no longer available.",
|
|
3099
3870
|
errorDesignSchema: "The model parameter definition changed or could not be parsed. Refresh the model and try again.",
|
|
3100
3871
|
designTitle: "Modellix Design",
|
|
@@ -3114,11 +3885,11 @@ const en = {
|
|
|
3114
3885
|
promptPlaceholder: "Describe the image, video motion, or sound…",
|
|
3115
3886
|
parametersTitle: "Parameters",
|
|
3116
3887
|
advancedParameters: "Advanced parameters ({count})",
|
|
3888
|
+
advancedEditor: "Advanced parameter editor",
|
|
3117
3889
|
required: "Required",
|
|
3118
3890
|
optional: "Optional",
|
|
3119
3891
|
requiredMissing: "Complete every required parameter before generating.",
|
|
3120
3892
|
assistantTitle: "Adjust parameters by chat",
|
|
3121
|
-
assistantPaidNotice: "Sending calls a fixed LLM with the same Modellix Key to propose parameter changes and may incur a charge. It never starts media generation.",
|
|
3122
3893
|
assistantPlaceholder: "For example: make it 16:9, eight seconds, and more cinematic",
|
|
3123
3894
|
propose: "Propose parameter changes",
|
|
3124
3895
|
proposing: "Analyzing…",
|
|
@@ -3130,7 +3901,6 @@ const en = {
|
|
|
3130
3901
|
conflicts: "Resolve conflicts before applying",
|
|
3131
3902
|
generate: "Confirm and generate",
|
|
3132
3903
|
generating: "Submitting…",
|
|
3133
|
-
paidNotice: "Generation is billed. Each click submits once and is never retried automatically.",
|
|
3134
3904
|
designDisabled: "Design is disabled. Enable it in Modellix settings.",
|
|
3135
3905
|
keyRequired: "Configure a Modellix API Key in settings first.",
|
|
3136
3906
|
noModels: "No model is currently available. Refresh and try again.",
|
|
@@ -3144,9 +3914,17 @@ const en = {
|
|
|
3144
3914
|
designNoticeCatalogUnavailable: "The Modellix Design model catalog is temporarily unavailable. Refresh it later.",
|
|
3145
3915
|
designNoticeCredentialReloaded: "The API Key changed, so the Design model and parameters were reloaded.",
|
|
3146
3916
|
resultsTitle: "Results",
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3917
|
+
resultsCount: "{count} item(s)",
|
|
3918
|
+
resultViewLabel: "Result view",
|
|
3919
|
+
previewTab: "Preview",
|
|
3920
|
+
jsonTab: "JSON",
|
|
3921
|
+
noPreview: "No media preview is available yet.",
|
|
3922
|
+
resultNotFound: "The requested generation task was not found.",
|
|
3923
|
+
resourceNavigation: "Media result navigation",
|
|
3924
|
+
previousResource: "Previous",
|
|
3925
|
+
nextResource: "Next",
|
|
3926
|
+
resourcePosition: "{current} of {total}",
|
|
3927
|
+
addUrlToChat: "Add URL to chat",
|
|
3150
3928
|
noResults: "No generations yet. Confirm parameters and generate to see results here.",
|
|
3151
3929
|
running: "Running",
|
|
3152
3930
|
succeeded: "Succeeded",
|
|
@@ -3154,10 +3932,10 @@ const en = {
|
|
|
3154
3932
|
canceled: "Canceled",
|
|
3155
3933
|
unknown: "Submission outcome unknown",
|
|
3156
3934
|
expired: "Result expired",
|
|
3157
|
-
openImage: "
|
|
3935
|
+
openImage: "Enlarge image",
|
|
3158
3936
|
imageViewerTitle: "Generated image",
|
|
3159
3937
|
close: "Close",
|
|
3160
|
-
download: "Download
|
|
3938
|
+
download: "Download",
|
|
3161
3939
|
expiresAt: "Available until {time}",
|
|
3162
3940
|
invalidJson: "Enter valid JSON.",
|
|
3163
3941
|
invalidParameter: "This value does not satisfy the current model constraints.",
|
|
@@ -3168,9 +3946,9 @@ const en = {
|
|
|
3168
3946
|
generatedAudioPreview: "Generated audio result preview",
|
|
3169
3947
|
jobModel: "Model: {model}",
|
|
3170
3948
|
jobCreated: "Created {time}",
|
|
3171
|
-
diagnosticRetryable: "The plugin will continue safe read-only status checks, but it never repeats a
|
|
3949
|
+
diagnosticRetryable: "The plugin will continue safe read-only status checks, but it never repeats a generation submission automatically.",
|
|
3172
3950
|
diagnosticCredentialChanged: "This task belongs to an earlier API Key and cannot be refreshed.",
|
|
3173
|
-
diagnosticSubmitUnknown: "The generation submission outcome is unknown. Check Results before submitting
|
|
3951
|
+
diagnosticSubmitUnknown: "The generation submission outcome is unknown. Check Results before submitting again.",
|
|
3174
3952
|
diagnosticGenerationFailed: "The generation did not complete.",
|
|
3175
3953
|
diagnosticResultUnavailable: "The generation completed without a usable result resource.",
|
|
3176
3954
|
diagnosticCredentialRejected: "Modellix rejected the current API Key while refreshing this task.",
|
|
@@ -3461,7 +4239,6 @@ function RemoveCredentialDialog({ open, busy, errorCode, onClose, onConfirm, t,
|
|
|
3461
4239
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
3462
4240
|
open: surfaceOpen,
|
|
3463
4241
|
title: t("removeTitle"),
|
|
3464
|
-
closeLabel: t("cancel"),
|
|
3465
4242
|
onClose,
|
|
3466
4243
|
headless: true,
|
|
3467
4244
|
className: "mdlx-modal mdlx-modal-confirm",
|
|
@@ -3527,7 +4304,7 @@ function llmHealthText(health, t) {
|
|
|
3527
4304
|
//#endregion
|
|
3528
4305
|
//#region src/client/styles.ts
|
|
3529
4306
|
const MODELLIX_CLIENT_CSS = String.raw`
|
|
3530
|
-
.mdlx-settings,.mdlx-design,.mdlx-modal-content{font-family:var(--dsw-font-family,inherit);color:var(--dsw-alias-label-primary);box-sizing:border-box}.mdlx-settings *,.mdlx-design *,.mdlx-modal-content *{box-sizing:border-box}
|
|
4307
|
+
.mdlx-settings,.mdlx-design,.mdlx-design-drawer,.mdlx-tool-result,.mdlx-modal-content{font-family:var(--dsw-font-family,inherit);color:var(--dsw-alias-label-primary);box-sizing:border-box}.mdlx-settings *,.mdlx-design *,.mdlx-design-drawer *,.mdlx-tool-result *,.mdlx-modal-content *{box-sizing:border-box}
|
|
3531
4308
|
.mdlx-settings{width:min(100%,760px);min-width:0;display:grid;gap:12px;padding:4px}
|
|
3532
4309
|
.mdlx-heading{display:grid;gap:4px;min-width:0;margin:0 0 8px}.mdlx-heading h2,.mdlx-heading h3,.mdlx-heading p{margin:0;overflow-wrap:anywhere}
|
|
3533
4310
|
.mdlx-heading h2{font-size:20px;line-height:28px;font-weight:500}.mdlx-heading h3{font-size:15px;line-height:22px;font-weight:600}
|
|
@@ -3536,7 +4313,7 @@ const MODELLIX_CLIENT_CSS = String.raw`
|
|
|
3536
4313
|
.mdlx-card-head,.mdlx-status-row,.mdlx-actions,.mdlx-result-head{display:flex;align-items:center;gap:12px;min-width:0;justify-content:space-between;flex-wrap:wrap}
|
|
3537
4314
|
.mdlx-card-head>.mdlx-heading{margin-bottom:0}
|
|
3538
4315
|
.mdlx-status-copy{display:flex;align-items:center;gap:8px;min-width:0}.mdlx-status-copy span{overflow-wrap:anywhere}
|
|
3539
|
-
.mdlx-actions{justify-content:flex-end}.mdlx-actions>*{min-width:0;max-width:100%}.mdlx-actions-start{justify-content:flex-start}.mdlx-grow{flex:1 1 auto}.mdlx-settings button,.mdlx-design button,.mdlx-modal-content button{height:auto;min-height:36px}
|
|
4316
|
+
.mdlx-actions{justify-content:flex-end}.mdlx-actions>*{min-width:0;max-width:100%}.mdlx-actions-start{justify-content:flex-start}.mdlx-grow{flex:1 1 auto}.mdlx-settings button,.mdlx-design button,.mdlx-design-drawer button,.mdlx-tool-result button,.mdlx-modal-content button{height:auto;min-height:36px}
|
|
3540
4317
|
.mdlx-service-list{display:grid;gap:8px}.mdlx-switch-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:16px;align-items:center;padding:12px;border-radius:12px;border:1px solid var(--dsw-alias-border-l2)}
|
|
3541
4318
|
.mdlx-switch-copy{display:grid;gap:2px;min-width:0}.mdlx-switch-copy strong{font-size:14px;font-weight:500;overflow-wrap:anywhere}.mdlx-switch-copy span{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;overflow-wrap:anywhere}
|
|
3542
4319
|
.mdlx-switch-target{display:inline-flex;width:24px;height:24px;align-items:center;justify-content:center;justify-self:center}.mdlx-switch{width:24px;height:24px;accent-color:var(--dsw-alias-brand-primary);cursor:pointer}.mdlx-switch:disabled{cursor:not-allowed}
|
|
@@ -3553,25 +4330,28 @@ const MODELLIX_CLIENT_CSS = String.raw`
|
|
|
3553
4330
|
.mdlx-link-button{appearance:none;border:0;padding:0;background:transparent;font:inherit;cursor:pointer}
|
|
3554
4331
|
.mdlx-modal{box-sizing:border-box;width:min(600px,calc(100vw - 48px));max-height:calc(100dvh - 48px);padding:0!important;gap:0!important;border-radius:24px!important;box-shadow:var(--dsw-shadow-lv3)!important;overflow:auto;overscroll-behavior:contain}.mdlx-modal-confirm{width:min(380px,calc(100vw - 48px))}.mdlx-modal-content{width:100%;min-width:0;padding:28px;display:grid;gap:20px;outline:none}.mdlx-modal-content>.mdlx-heading{margin-bottom:0}.mdlx-modal-title{font-size:20px;line-height:28px;font-weight:500;margin:0;overflow-wrap:anywhere}.mdlx-modal-description{font-size:14px;line-height:22px;color:var(--dsw-alias-label-secondary);margin:0;overflow-wrap:anywhere}
|
|
3555
4332
|
.mdlx-design{container-type:inline-size;height:100%;min-height:0;box-sizing:border-box;padding:16px;padding-bottom:max(16px,env(safe-area-inset-bottom));scroll-padding-block-end:max(24px,env(safe-area-inset-bottom));overflow:auto;background:var(--dsw-alias-bg-base)}
|
|
3556
|
-
.mdlx-design-shell{width:100%;min-height:100%;display:grid;grid-template-columns:minmax(
|
|
4333
|
+
.mdlx-design-shell{width:100%;min-height:100%;display:grid;grid-template-columns:minmax(0,1fr);align-content:start;gap:12px}.mdlx-design-pane{min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-1);padding:16px;display:flex;flex-direction:column;gap:16px;overflow-wrap:anywhere}
|
|
4334
|
+
.mdlx-design-launcher{height:32px!important;min-height:32px!important;padding:6px 12px!important;border-radius:18px!important;font-size:13px!important;font-weight:400!important;line-height:20px!important}.mdlx-design-launcher .mdlx-launcher-compact{display:none}.mdlx-design-drawer-viewport{position:fixed;inset:0 0 0 auto;width:360px;max-width:100vw;overflow:hidden;pointer-events:none}.mdlx-design-drawer{position:absolute;inset:0 0 0 auto;width:360px;min-width:360px;display:grid;grid-template-rows:auto minmax(0,1fr);border-inline-start:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);box-shadow:var(--dsw-shadow-lv2);pointer-events:auto;transform:translateX(0);opacity:1;transition:transform 180ms ease-out,opacity 180ms ease-out}@starting-style{.mdlx-design-drawer{transform:translateX(100%);opacity:.72}}.mdlx-design-drawer-viewport[data-closing="true"] .mdlx-design-drawer{transform:translateX(100%);opacity:.72;pointer-events:none}.mdlx-drawer-header{position:relative;display:grid;gap:0;padding:16px 60px 16px 16px;border-bottom:1px solid var(--dsw-alias-border-l2)}.mdlx-drawer-header>.mdlx-heading{margin:0}.mdlx-drawer-close{position:absolute!important;inset-block-start:12px;inset-inline-end:12px;width:36px!important;min-width:36px!important;height:36px!important;min-height:36px!important;padding:0!important;border-radius:50%!important;justify-content:center}.mdlx-drawer-header-reveal{display:grid;grid-template-rows:0fr;opacity:0;margin-top:0;transition:grid-template-rows 160ms ease,opacity 120ms ease,margin-top 160ms ease}.mdlx-drawer-header-reveal[hidden]{display:none!important}.mdlx-drawer-header-reveal>div{min-height:0;overflow:hidden}.mdlx-drawer-header:hover .mdlx-drawer-header-reveal,.mdlx-drawer-header:focus-within .mdlx-drawer-header-reveal,.mdlx-drawer-header[data-editor-open="true"] .mdlx-drawer-header-reveal{grid-template-rows:1fr;opacity:1;margin-top:12px}.mdlx-drawer-editor-toggle{justify-self:start}.mdlx-drawer-body{min-height:0;overflow:hidden}.mdlx-drawer-body>.mdlx-design{padding:12px}.mdlx-design-editor{display:grid;gap:12px}.mdlx-design-editor[hidden]{display:none}.mdlx-results-summary{cursor:pointer;min-height:40px;display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:15px;font-weight:600;overflow-wrap:anywhere}.mdlx-results-disclosure{display:block}.mdlx-results-summary{margin:-4px 0;padding:4px 0}.mdlx-results-body{padding-top:12px}
|
|
3557
4335
|
.mdlx-design-scroll{display:grid;gap:16px;min-height:0}.mdlx-parameter-list{display:grid;gap:12px}.mdlx-parameter{display:grid;gap:6px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:12px}
|
|
3558
4336
|
.mdlx-advanced{display:grid;gap:12px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:12px}.mdlx-advanced>summary{cursor:pointer;font-size:14px;font-weight:500;min-height:24px;overflow-wrap:anywhere}
|
|
3559
4337
|
.mdlx-proposal{display:grid;gap:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;padding:12px;background:var(--dsw-alias-bg-layer-2)}
|
|
3560
4338
|
.mdlx-generate-block{display:grid;gap:8px;min-width:0}.mdlx-generate-block>p{margin:0}
|
|
3561
4339
|
.mdlx-change-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}.mdlx-change{display:grid;grid-template-columns:minmax(100px,.4fr) minmax(0,1fr);gap:8px;min-width:0;font-size:13px}.mdlx-change>*{min-width:0;overflow-wrap:anywhere}.mdlx-code{font-family:var(--ds-font-family-code,monospace);font-size:12px;overflow-wrap:anywhere}
|
|
3562
4340
|
.mdlx-result-section{display:grid;gap:10px}.mdlx-result-section h3{margin:0;font-size:14px;font-weight:600}.mdlx-result-list{display:grid;gap:12px;margin:0;padding:0;list-style:none}
|
|
3563
|
-
.mdlx-result-card{display:
|
|
3564
|
-
.mdlx-resource-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px}.mdlx-resource{display:grid;gap:8px;min-width:0}.mdlx-media{display:block;width:100%;max-height:
|
|
3565
|
-
.mdlx-media-audio{min-height:48px}.mdlx-empty{display:grid;place-items:center;min-height:160px;text-align:center;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px;padding:24px}
|
|
4341
|
+
.mdlx-result-card{display:block;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2);overflow:hidden}.mdlx-result-disclosure{display:block}.mdlx-result-card-summary{position:relative;display:grid;gap:8px;min-height:72px;padding:12px 44px 12px 12px;cursor:pointer;list-style:none}.mdlx-result-card-summary::-webkit-details-marker{display:none}.mdlx-result-card-summary::after{content:"";position:absolute;inset-block-start:18px;inset-inline-end:18px;width:8px;height:8px;border-inline-end:2px solid currentColor;border-block-end:2px solid currentColor;transform:rotate(-45deg);transition:transform 160ms ease}.mdlx-result-disclosure[open]>.mdlx-result-card-summary::after{transform:rotate(45deg)}.mdlx-result-card-body{display:grid;gap:12px;padding:0 12px 12px}
|
|
4342
|
+
.mdlx-result-tabs{display:flex;align-items:center;gap:4px;border-bottom:1px solid var(--dsw-alias-border-l2)}.mdlx-result-tab{appearance:none;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);font:inherit;padding:8px 12px;cursor:pointer}.mdlx-result-tab[aria-selected="true"]{border-bottom-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary);font-weight:600}.mdlx-result-panel{display:grid;gap:12px;min-width:0}.mdlx-result-json{max-height:320px;margin:0;padding:12px;border-radius:12px;background:var(--dsw-alias-markdown-code-block,var(--dsw-alias-bg-layer-3));font-family:var(--ds-font-family-code,monospace);font-size:12px;line-height:18px;white-space:pre-wrap;overflow:auto;overflow-wrap:anywhere}.mdlx-resource-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px}.mdlx-resource{display:grid;gap:8px;min-width:0}.mdlx-resource-nav{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap}.mdlx-media{display:block;width:100%;max-height:420px;object-fit:contain;border-radius:12px;background:var(--dsw-alias-bg-layer-3)}.mdlx-image-preview-button{appearance:none;width:100%;padding:0;border:0;border-radius:12px;background:transparent;cursor:zoom-in}.mdlx-image-preview-button>.mdlx-media{pointer-events:none}
|
|
4343
|
+
.mdlx-media-audio{min-height:48px}.mdlx-empty{display:grid;place-items:center;min-height:160px;text-align:center;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:20px;padding:24px}.mdlx-empty-compact{min-height:96px}.mdlx-tool-result{display:grid;gap:12px;margin:4px 0 4px 4px;padding:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}
|
|
3566
4344
|
.mdlx-image-modal{width:min(1000px,calc(100vw - 48px))}.mdlx-image-full{display:block;width:100%;max-height:calc(100dvh - 220px);object-fit:contain;border-radius:12px;background:var(--dsw-alias-bg-layer-3)}
|
|
3567
4345
|
.mdlx-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}
|
|
3568
|
-
.mdlx-input{height:auto;min-height:40px}.mdlx-input:focus-within,.mdlx-textarea:focus-visible,.mdlx-select:focus-visible,.mdlx-native-input:focus-visible,.mdlx-switch:focus-visible,.mdlx-safe-link:focus-visible,.mdlx-modal-content:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
4346
|
+
.mdlx-input{height:auto;min-height:40px}.mdlx-input:focus-within,.mdlx-textarea:focus-visible,.mdlx-select:focus-visible,.mdlx-native-input:focus-visible,.mdlx-switch:focus-visible,.mdlx-safe-link:focus-visible,.mdlx-modal-content:focus-visible,.mdlx-result-tab:focus-visible,.mdlx-image-preview-button:focus-visible,.mdlx-drawer-editor-toggle:focus-visible,.mdlx-results-summary:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.mdlx-result-card-summary:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}
|
|
4347
|
+
@media (min-width:1280px){.mdlx-design-drawer{box-shadow:none}}
|
|
3569
4348
|
@media (max-width:768px){.mdlx-design{padding:12px;padding-bottom:max(12px,env(safe-area-inset-bottom))}.mdlx-design-shell{grid-template-columns:minmax(0,1fr)}.mdlx-design-pane{padding:12px}.mdlx-resource-list{grid-template-columns:minmax(0,1fr)}}
|
|
3570
4349
|
@container (max-width:992px){.mdlx-design-shell{grid-template-columns:minmax(0,1fr)}.mdlx-design-pane{padding:12px}.mdlx-resource-list{grid-template-columns:minmax(0,1fr)}}
|
|
3571
|
-
@media (max-width:560px){.mdlx-modal{width:calc(100vw - 48px)}.mdlx-modal-content{padding:24px}.mdlx-input-row,.mdlx-model-tools{grid-template-columns:minmax(0,1fr)}.mdlx-input-row>button,.mdlx-model-tools button,.mdlx-actions button{width:100%;min-width:0;justify-self:stretch}.mdlx-actions{display:grid;grid-template-columns:minmax(0,1fr)}.mdlx-switch-row{grid-template-columns:minmax(0,1fr) 48px}.mdlx-change{grid-template-columns:minmax(0,1fr)}}
|
|
3572
|
-
@media (
|
|
3573
|
-
@media (
|
|
3574
|
-
@media (
|
|
4350
|
+
@media (max-width:560px){.mdlx-design-launcher{width:40px;min-width:40px;padding-inline:0!important}.mdlx-design-launcher .mdlx-launcher-label{display:none}.mdlx-design-launcher .mdlx-launcher-compact{display:inline}.mdlx-modal{width:calc(100vw - 48px)}.mdlx-modal-content{padding:24px}.mdlx-input-row,.mdlx-model-tools{grid-template-columns:minmax(0,1fr)}.mdlx-input-row>button,.mdlx-model-tools button,.mdlx-actions button{width:100%;min-width:0;justify-self:stretch}.mdlx-actions{display:grid;grid-template-columns:minmax(0,1fr)}.mdlx-switch-row{grid-template-columns:minmax(0,1fr) 48px}.mdlx-change{grid-template-columns:minmax(0,1fr)}.mdlx-design-drawer-viewport,.mdlx-design-drawer{width:100vw;min-width:0}.mdlx-drawer-header{padding:12px 56px 12px 12px}.mdlx-drawer-close{inset-block-start:8px;inset-inline-end:8px}.mdlx-resource-nav{display:grid;grid-template-columns:1fr}.mdlx-resource-nav>*{width:100%;text-align:center}}
|
|
4351
|
+
@media (max-width:360px){.mdlx-design-launcher{position:fixed!important;inset-block-start:92px;inset-inline-end:12px;z-index:10;width:48px;min-width:48px;height:48px;min-height:48px!important;padding:0!important;border-radius:50%!important}}
|
|
4352
|
+
@media (pointer:coarse){.mdlx-design-launcher{height:48px!important;min-height:48px!important}.mdlx-drawer-header-reveal{grid-template-rows:1fr;opacity:1;margin-top:12px}.mdlx-switch-row,.mdlx-switch-target,.mdlx-safe-link{min-width:48px;min-height:48px}.mdlx-settings button,.mdlx-design button,.mdlx-design-drawer button,.mdlx-tool-result button,.mdlx-modal-content button{min-height:48px}.mdlx-input,.mdlx-select,.mdlx-native-input,.mdlx-advanced>summary{min-height:48px}}
|
|
4353
|
+
@media (prefers-reduced-motion:reduce){.mdlx-design-drawer-viewport,.mdlx-design-drawer,.mdlx-settings *,.mdlx-design *,.mdlx-design-drawer *,.mdlx-tool-result *,.mdlx-modal-content *{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
|
|
4354
|
+
@media (forced-colors:active){.mdlx-modal,.mdlx-design-drawer{border:1px solid CanvasText;box-shadow:none!important}.mdlx-card,.mdlx-switch-row,.mdlx-design-pane,.mdlx-result-card,.mdlx-tool-result,.mdlx-proposal,.mdlx-error,.mdlx-info{forced-color-adjust:auto;border:1px solid CanvasText}.mdlx-input,.mdlx-textarea,.mdlx-select,.mdlx-native-input{border-color:CanvasText}.mdlx-safe-link{color:LinkText}.mdlx-input:focus-within,.mdlx-textarea:focus-visible,.mdlx-select:focus-visible,.mdlx-native-input:focus-visible,.mdlx-switch:focus-visible,.mdlx-safe-link:focus-visible,.mdlx-modal-content:focus-visible,.mdlx-result-tab:focus-visible,.mdlx-image-preview-button:focus-visible,.mdlx-drawer-editor-toggle:focus-visible,.mdlx-results-summary:focus-visible,.mdlx-result-card-summary:focus-visible{outline-color:Highlight}}
|
|
3575
4355
|
`;
|
|
3576
4356
|
function installModellixClientStyles(target = typeof document === "undefined" ? void 0 : document) {
|
|
3577
4357
|
if (target === void 0) return () => void 0;
|
|
@@ -3589,6 +4369,11 @@ const MODELLIX_CLIENT_SLOTS = Object.freeze([
|
|
|
3589
4369
|
id: "modellix.credential-recovery",
|
|
3590
4370
|
order: 10
|
|
3591
4371
|
},
|
|
4372
|
+
{
|
|
4373
|
+
name: "shell.overlay",
|
|
4374
|
+
id: "modellix.design-drawer",
|
|
4375
|
+
order: 20
|
|
4376
|
+
},
|
|
3592
4377
|
{
|
|
3593
4378
|
name: "settings.onboarding",
|
|
3594
4379
|
id: "modellix.onboarding",
|
|
@@ -3600,9 +4385,19 @@ const MODELLIX_CLIENT_SLOTS = Object.freeze([
|
|
|
3600
4385
|
order: 30
|
|
3601
4386
|
},
|
|
3602
4387
|
{
|
|
3603
|
-
name: "conversation.
|
|
3604
|
-
id: "modellix.design",
|
|
4388
|
+
name: "conversation.session.header.utilities",
|
|
4389
|
+
id: "modellix.design-launcher",
|
|
3605
4390
|
order: 20
|
|
4391
|
+
},
|
|
4392
|
+
{
|
|
4393
|
+
name: "tool.call.toolview",
|
|
4394
|
+
key: "modellix_media_generate",
|
|
4395
|
+
priority: 20
|
|
4396
|
+
},
|
|
4397
|
+
{
|
|
4398
|
+
name: "tool.call.toolview",
|
|
4399
|
+
key: "modellix_media_get_result",
|
|
4400
|
+
priority: 20
|
|
3606
4401
|
}
|
|
3607
4402
|
]);
|
|
3608
4403
|
//#endregion
|
|
@@ -3610,7 +4405,8 @@ const MODELLIX_CLIENT_SLOTS = Object.freeze([
|
|
|
3610
4405
|
const inject = [
|
|
3611
4406
|
"slots",
|
|
3612
4407
|
"locale",
|
|
3613
|
-
"connection"
|
|
4408
|
+
"connection",
|
|
4409
|
+
"layout"
|
|
3614
4410
|
];
|
|
3615
4411
|
function apply(ctx) {
|
|
3616
4412
|
ctx.effect(() => ctx.locale.register(MODELLIX_LOCALE_NAMESPACE, {
|
|
@@ -3621,6 +4417,7 @@ function apply(ctx) {
|
|
|
3621
4417
|
const t = ctx.locale.bind(MODELLIX_LOCALE_NAMESPACE);
|
|
3622
4418
|
const rpc = new ModellixRpcClient(ctx.connection.rpc);
|
|
3623
4419
|
const settingsController = new SettingsController(rpc);
|
|
4420
|
+
const designDrawer = new DesignDrawerController(rpc, ctx.layout);
|
|
3624
4421
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
3625
4422
|
name: "shell.overlay",
|
|
3626
4423
|
id: "modellix.credential-recovery",
|
|
@@ -3628,6 +4425,16 @@ function apply(ctx) {
|
|
|
3628
4425
|
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
3629
4426
|
inject: () => ({ controller: settingsController })
|
|
3630
4427
|
}, CredentialRecoveryOverlay));
|
|
4428
|
+
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
4429
|
+
name: "shell.overlay",
|
|
4430
|
+
id: "modellix.design-drawer",
|
|
4431
|
+
order: 20,
|
|
4432
|
+
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
4433
|
+
inject: () => ({
|
|
4434
|
+
drawer: designDrawer,
|
|
4435
|
+
settingsController
|
|
4436
|
+
})
|
|
4437
|
+
}, ModellixDesignDrawer));
|
|
3631
4438
|
ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
3632
4439
|
name: "settings.onboarding",
|
|
3633
4440
|
id: "modellix.onboarding",
|
|
@@ -3643,17 +4450,27 @@ function apply(ctx) {
|
|
|
3643
4450
|
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
3644
4451
|
inject: () => ({ controller: settingsController })
|
|
3645
4452
|
}, ModellixSettingsSection));
|
|
3646
|
-
ctx.slots.inject("conversation.
|
|
3647
|
-
name: "conversation.
|
|
3648
|
-
id: "modellix.design",
|
|
4453
|
+
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
4454
|
+
name: "conversation.session.header.utilities",
|
|
4455
|
+
id: "modellix.design-launcher",
|
|
3649
4456
|
order: 20,
|
|
3650
|
-
label: () => t("designTab"),
|
|
3651
4457
|
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
3652
|
-
inject: (
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
4458
|
+
inject: () => ({ drawer: designDrawer })
|
|
4459
|
+
}, ModellixDesignLauncher));
|
|
4460
|
+
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
4461
|
+
name: "tool.call.toolview",
|
|
4462
|
+
key: "modellix_media_generate",
|
|
4463
|
+
priority: 20,
|
|
4464
|
+
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
4465
|
+
inject: () => ({ drawer: designDrawer })
|
|
4466
|
+
}, ModellixMediaToolView));
|
|
4467
|
+
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
4468
|
+
name: "tool.call.toolview",
|
|
4469
|
+
key: "modellix_media_get_result",
|
|
4470
|
+
priority: 20,
|
|
4471
|
+
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
4472
|
+
inject: () => ({ drawer: designDrawer })
|
|
4473
|
+
}, ModellixMediaToolView));
|
|
3657
4474
|
}
|
|
3658
4475
|
//#endregion
|
|
3659
4476
|
exports.MODELLIX_CLIENT_SLOTS = MODELLIX_CLIENT_SLOTS;
|