dsh-modellix 0.1.1 → 0.2.0
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 +43 -0
- package/README.md +101 -166
- package/README.zh-CN.md +99 -164
- 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 +17 -15
- package/docs/en-US/RELEASE_CHECKLIST.md +270 -0
- package/docs/en-US/USER_GUIDE.md +183 -395
- package/docs/zh-CN/LOCAL_USAGE.md +17 -15
- package/docs/zh-CN/RELEASE_CHECKLIST.md +270 -0
- package/docs/zh-CN/USER_GUIDE.md +182 -394
- package/lib/client.d.ts +16 -2
- package/lib/client.js +1272 -452
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +159 -109
- package/lib/index.js +995 -192
- package/lib/index.js.map +1 -1
- package/package.json +7 -2
- 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", {
|
|
@@ -2810,18 +2866,14 @@ function ResultResource({ resource, dateLocale, dialogCoordinator, dialog, t })
|
|
|
2810
2866
|
"data-mdlx-initial-focus": "",
|
|
2811
2867
|
onClick: closeImage,
|
|
2812
2868
|
children: t("close")
|
|
2813
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
2869
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2814
2870
|
className: "mdlx-safe-link",
|
|
2815
2871
|
href: resource.downloadUrl,
|
|
2816
2872
|
target: "_blank",
|
|
2817
2873
|
rel: "noopener noreferrer",
|
|
2818
2874
|
referrerPolicy: "no-referrer",
|
|
2819
2875
|
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
|
-
]
|
|
2876
|
+
children: t("download")
|
|
2825
2877
|
})]
|
|
2826
2878
|
})
|
|
2827
2879
|
]
|
|
@@ -2862,12 +2914,727 @@ function formatTime(value, locale) {
|
|
|
2862
2914
|
}).format(new Date(value));
|
|
2863
2915
|
}
|
|
2864
2916
|
//#endregion
|
|
2917
|
+
//#region src/client/DesignDrawer.tsx
|
|
2918
|
+
const MODELLIX_DESIGN_SPLIT_MEDIA_QUERY = "(min-width: 1280px)";
|
|
2919
|
+
const MODELLIX_DRAWER_EXIT_MS = 180;
|
|
2920
|
+
const MODELLIX_ADVANCED_EDITOR_ENTRY_HIDDEN = true;
|
|
2921
|
+
function isSplitViewport() {
|
|
2922
|
+
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(min-width: 1280px)").matches;
|
|
2923
|
+
}
|
|
2924
|
+
var DesignDrawerController = class {
|
|
2925
|
+
#rpc;
|
|
2926
|
+
#layout;
|
|
2927
|
+
#isSplitViewport;
|
|
2928
|
+
#listeners = /* @__PURE__ */ new Set();
|
|
2929
|
+
#controllers = /* @__PURE__ */ new Map();
|
|
2930
|
+
#watchedJobs = /* @__PURE__ */ new Map();
|
|
2931
|
+
#mediaCardClaims = /* @__PURE__ */ new Map();
|
|
2932
|
+
#mediaCardListeners = /* @__PURE__ */ new Set();
|
|
2933
|
+
#sessionReferences = /* @__PURE__ */ new Map();
|
|
2934
|
+
#sessionReleaseTimers = /* @__PURE__ */ new Map();
|
|
2935
|
+
#mediaCardVersion = 0;
|
|
2936
|
+
#mediaCardOrder = 0;
|
|
2937
|
+
#snapshot = {
|
|
2938
|
+
open: false,
|
|
2939
|
+
sessionId: null,
|
|
2940
|
+
controller: null,
|
|
2941
|
+
draft: "",
|
|
2942
|
+
inputActions: null
|
|
2943
|
+
};
|
|
2944
|
+
#trigger = null;
|
|
2945
|
+
#splitActive = false;
|
|
2946
|
+
constructor(rpc, layout, splitViewport = isSplitViewport) {
|
|
2947
|
+
this.#rpc = rpc;
|
|
2948
|
+
this.#layout = layout;
|
|
2949
|
+
this.#isSplitViewport = splitViewport;
|
|
2950
|
+
}
|
|
2951
|
+
subscribe = (listener) => {
|
|
2952
|
+
this.#listeners.add(listener);
|
|
2953
|
+
return () => this.#listeners.delete(listener);
|
|
2954
|
+
};
|
|
2955
|
+
getSnapshot = () => this.#snapshot;
|
|
2956
|
+
subscribeMediaCards = (listener) => {
|
|
2957
|
+
this.#mediaCardListeners.add(listener);
|
|
2958
|
+
return () => this.#mediaCardListeners.delete(listener);
|
|
2959
|
+
};
|
|
2960
|
+
getMediaCardVersion = () => this.#mediaCardVersion;
|
|
2961
|
+
claimMediaCard(sessionId, jobId, callId, operation) {
|
|
2962
|
+
const key = `${sessionId}\n${jobId}`;
|
|
2963
|
+
const claims = this.#mediaCardClaims.get(key) ?? /* @__PURE__ */ new Map();
|
|
2964
|
+
if (claims.has(callId)) return () => void 0;
|
|
2965
|
+
claims.set(callId, {
|
|
2966
|
+
operation,
|
|
2967
|
+
order: this.#mediaCardOrder++
|
|
2968
|
+
});
|
|
2969
|
+
this.#mediaCardClaims.set(key, claims);
|
|
2970
|
+
this.#publishMediaCards();
|
|
2971
|
+
return () => {
|
|
2972
|
+
const current = this.#mediaCardClaims.get(key);
|
|
2973
|
+
if (current?.delete(callId) !== true) return;
|
|
2974
|
+
if (current.size === 0) this.#mediaCardClaims.delete(key);
|
|
2975
|
+
this.#publishMediaCards();
|
|
2976
|
+
};
|
|
2977
|
+
}
|
|
2978
|
+
isMediaCardPrimary(sessionId, jobId, callId, operation) {
|
|
2979
|
+
const claims = this.#mediaCardClaims.get(`${sessionId}\n${jobId}`);
|
|
2980
|
+
if (claims === void 0 || claims.size === 0) return true;
|
|
2981
|
+
let primaryCallId = callId;
|
|
2982
|
+
let primary = {
|
|
2983
|
+
operation,
|
|
2984
|
+
order: Number.MAX_SAFE_INTEGER
|
|
2985
|
+
};
|
|
2986
|
+
for (const [candidateCallId, candidate] of claims) if (compareMediaCardClaims(candidate, primary) < 0) {
|
|
2987
|
+
primaryCallId = candidateCallId;
|
|
2988
|
+
primary = candidate;
|
|
2989
|
+
}
|
|
2990
|
+
return primaryCallId === callId;
|
|
2991
|
+
}
|
|
2992
|
+
controllerForSession(sessionId) {
|
|
2993
|
+
const existing = this.#controllers.get(sessionId);
|
|
2994
|
+
if (existing !== void 0) return existing;
|
|
2995
|
+
const controller = new DesignController(this.#rpc, sessionId);
|
|
2996
|
+
this.#controllers.set(sessionId, controller);
|
|
2997
|
+
return controller;
|
|
2998
|
+
}
|
|
2999
|
+
retainSession(sessionId) {
|
|
3000
|
+
const pendingRelease = this.#sessionReleaseTimers.get(sessionId);
|
|
3001
|
+
if (pendingRelease !== void 0) {
|
|
3002
|
+
window.clearTimeout(pendingRelease);
|
|
3003
|
+
this.#sessionReleaseTimers.delete(sessionId);
|
|
3004
|
+
}
|
|
3005
|
+
this.#sessionReferences.set(sessionId, (this.#sessionReferences.get(sessionId) ?? 0) + 1);
|
|
3006
|
+
let retained = true;
|
|
3007
|
+
return () => {
|
|
3008
|
+
if (!retained) return;
|
|
3009
|
+
retained = false;
|
|
3010
|
+
const remaining = Math.max(0, (this.#sessionReferences.get(sessionId) ?? 1) - 1);
|
|
3011
|
+
if (remaining > 0) {
|
|
3012
|
+
this.#sessionReferences.set(sessionId, remaining);
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
3015
|
+
this.#sessionReferences.delete(sessionId);
|
|
3016
|
+
const timer = window.setTimeout(() => {
|
|
3017
|
+
this.#sessionReleaseTimers.delete(sessionId);
|
|
3018
|
+
if ((this.#sessionReferences.get(sessionId) ?? 0) === 0) this.releaseSession(sessionId);
|
|
3019
|
+
}, 0);
|
|
3020
|
+
this.#sessionReleaseTimers.set(sessionId, timer);
|
|
3021
|
+
};
|
|
3022
|
+
}
|
|
3023
|
+
watchJob(sessionId, jobId, initialStatus) {
|
|
3024
|
+
if (initialStatus !== "running") return () => void 0;
|
|
3025
|
+
const key = `${sessionId}\n${jobId}`;
|
|
3026
|
+
const existing = this.#watchedJobs.get(key);
|
|
3027
|
+
if (existing !== void 0) {
|
|
3028
|
+
existing.references += 1;
|
|
3029
|
+
return () => this.#releaseJobWatch(key, existing);
|
|
3030
|
+
}
|
|
3031
|
+
const controller = this.controllerForSession(sessionId);
|
|
3032
|
+
const watched = {
|
|
3033
|
+
references: 1,
|
|
3034
|
+
timer: null,
|
|
3035
|
+
stopped: false,
|
|
3036
|
+
unsubscribeStore: () => void 0
|
|
3037
|
+
};
|
|
3038
|
+
const liveStatus = () => controller.store.getSnapshot().data?.jobs.find((job) => job.jobId === jobId)?.status;
|
|
3039
|
+
const stopWhenTerminal = () => {
|
|
3040
|
+
const status = liveStatus();
|
|
3041
|
+
if (status === void 0 || status === "running") return;
|
|
3042
|
+
watched.stopped = true;
|
|
3043
|
+
if (watched.timer !== null) window.clearTimeout(watched.timer);
|
|
3044
|
+
watched.timer = null;
|
|
3045
|
+
};
|
|
3046
|
+
const poll = async () => {
|
|
3047
|
+
watched.timer = null;
|
|
3048
|
+
if (watched.stopped) return;
|
|
3049
|
+
await controller.load();
|
|
3050
|
+
stopWhenTerminal();
|
|
3051
|
+
if (!watched.stopped && watched.references > 0) watched.timer = window.setTimeout(() => {
|
|
3052
|
+
poll();
|
|
3053
|
+
}, 5e3);
|
|
3054
|
+
};
|
|
3055
|
+
watched.unsubscribeStore = controller.store.subscribe(stopWhenTerminal);
|
|
3056
|
+
this.#watchedJobs.set(key, watched);
|
|
3057
|
+
watched.timer = window.setTimeout(() => {
|
|
3058
|
+
poll();
|
|
3059
|
+
}, 0);
|
|
3060
|
+
return () => this.#releaseJobWatch(key, watched);
|
|
3061
|
+
}
|
|
3062
|
+
open(sessionId, inputActions, draft, trigger) {
|
|
3063
|
+
const controller = this.controllerForSession(sessionId);
|
|
3064
|
+
this.#trigger = trigger;
|
|
3065
|
+
this.#syncSplit(this.#isSplitViewport());
|
|
3066
|
+
this.#publish({
|
|
3067
|
+
open: true,
|
|
3068
|
+
sessionId,
|
|
3069
|
+
controller,
|
|
3070
|
+
draft,
|
|
3071
|
+
inputActions
|
|
3072
|
+
});
|
|
3073
|
+
}
|
|
3074
|
+
close(restoreFocus = true) {
|
|
3075
|
+
if (!this.#snapshot.open) return;
|
|
3076
|
+
this.#syncSplit(false);
|
|
3077
|
+
this.#publish({
|
|
3078
|
+
...this.#snapshot,
|
|
3079
|
+
open: false
|
|
3080
|
+
});
|
|
3081
|
+
if (restoreFocus) queueMicrotask(() => this.#trigger?.focus());
|
|
3082
|
+
}
|
|
3083
|
+
setSplitMode(enabled) {
|
|
3084
|
+
if (!this.#snapshot.open) return;
|
|
3085
|
+
this.#syncSplit(enabled);
|
|
3086
|
+
}
|
|
3087
|
+
updateSession(sessionId, inputActions, draft) {
|
|
3088
|
+
if (this.#snapshot.sessionId !== sessionId) return;
|
|
3089
|
+
this.#publish({
|
|
3090
|
+
...this.#snapshot,
|
|
3091
|
+
inputActions,
|
|
3092
|
+
draft
|
|
3093
|
+
});
|
|
3094
|
+
}
|
|
3095
|
+
releaseSession(sessionId) {
|
|
3096
|
+
if (this.#snapshot.sessionId !== sessionId) return;
|
|
3097
|
+
this.#syncSplit(false);
|
|
3098
|
+
this.#trigger = null;
|
|
3099
|
+
this.#publish({
|
|
3100
|
+
open: false,
|
|
3101
|
+
sessionId: null,
|
|
3102
|
+
controller: null,
|
|
3103
|
+
draft: "",
|
|
3104
|
+
inputActions: null
|
|
3105
|
+
});
|
|
3106
|
+
}
|
|
3107
|
+
#releaseJobWatch(key, watched) {
|
|
3108
|
+
if (this.#watchedJobs.get(key) !== watched) return;
|
|
3109
|
+
watched.references -= 1;
|
|
3110
|
+
if (watched.references > 0) return;
|
|
3111
|
+
watched.stopped = true;
|
|
3112
|
+
if (watched.timer !== null) window.clearTimeout(watched.timer);
|
|
3113
|
+
watched.unsubscribeStore();
|
|
3114
|
+
this.#watchedJobs.delete(key);
|
|
3115
|
+
}
|
|
3116
|
+
appendUrl(url) {
|
|
3117
|
+
const actions = this.#snapshot.inputActions;
|
|
3118
|
+
if (actions === null) return;
|
|
3119
|
+
const current = this.#snapshot.draft;
|
|
3120
|
+
const next = `${current}${current === "" || /\s$/u.test(current) ? "" : "\n"}${url}`;
|
|
3121
|
+
actions.setDraft(next);
|
|
3122
|
+
this.#publish({
|
|
3123
|
+
...this.#snapshot,
|
|
3124
|
+
draft: next
|
|
3125
|
+
});
|
|
3126
|
+
}
|
|
3127
|
+
#publish(snapshot) {
|
|
3128
|
+
this.#snapshot = snapshot;
|
|
3129
|
+
for (const listener of this.#listeners) listener();
|
|
3130
|
+
}
|
|
3131
|
+
#publishMediaCards() {
|
|
3132
|
+
this.#mediaCardVersion += 1;
|
|
3133
|
+
for (const listener of this.#mediaCardListeners) listener();
|
|
3134
|
+
}
|
|
3135
|
+
#syncSplit(enabled) {
|
|
3136
|
+
if (enabled === this.#splitActive) return;
|
|
3137
|
+
if (enabled) {
|
|
3138
|
+
this.#layout.closeDetails();
|
|
3139
|
+
this.#layout.openDetails();
|
|
3140
|
+
} else this.#layout.closeDetails();
|
|
3141
|
+
this.#splitActive = enabled;
|
|
3142
|
+
}
|
|
3143
|
+
};
|
|
3144
|
+
function compareMediaCardClaims(left, right) {
|
|
3145
|
+
return (left.operation === "generate" ? 0 : 1) - (right.operation === "generate" ? 0 : 1) || left.order - right.order;
|
|
3146
|
+
}
|
|
3147
|
+
function ModellixDesignLauncher({ drawer, inputActions, sessionId, t, useInput }) {
|
|
3148
|
+
const draft = useInput((state) => state.draft);
|
|
3149
|
+
const snapshot = (0, react.useSyncExternalStore)(drawer.subscribe, drawer.getSnapshot, drawer.getSnapshot);
|
|
3150
|
+
const active = snapshot.open && snapshot.sessionId === String(sessionId);
|
|
3151
|
+
(0, react.useEffect)(() => {
|
|
3152
|
+
drawer.updateSession(String(sessionId), inputActions, draft);
|
|
3153
|
+
}, [
|
|
3154
|
+
draft,
|
|
3155
|
+
drawer,
|
|
3156
|
+
inputActions,
|
|
3157
|
+
sessionId
|
|
3158
|
+
]);
|
|
3159
|
+
(0, react.useEffect)(() => drawer.retainSession(String(sessionId)), [drawer, sessionId]);
|
|
3160
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3161
|
+
type: "button",
|
|
3162
|
+
variant: "outline",
|
|
3163
|
+
className: "mdlx-design-launcher",
|
|
3164
|
+
"aria-label": t("designTitle"),
|
|
3165
|
+
"aria-expanded": active,
|
|
3166
|
+
"aria-controls": "mdlx-design-drawer",
|
|
3167
|
+
onClick: (event) => {
|
|
3168
|
+
if (active) drawer.close();
|
|
3169
|
+
else drawer.open(String(sessionId), inputActions, draft, event.currentTarget);
|
|
3170
|
+
},
|
|
3171
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3172
|
+
className: "mdlx-launcher-label",
|
|
3173
|
+
children: t("designTitle")
|
|
3174
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3175
|
+
className: "mdlx-launcher-compact",
|
|
3176
|
+
"aria-hidden": "true",
|
|
3177
|
+
children: "M"
|
|
3178
|
+
})]
|
|
3179
|
+
});
|
|
3180
|
+
}
|
|
3181
|
+
function ModellixDesignDrawer({ drawer, settingsController, t }) {
|
|
3182
|
+
const snapshot = (0, react.useSyncExternalStore)(drawer.subscribe, drawer.getSnapshot, drawer.getSnapshot);
|
|
3183
|
+
const [retainedSnapshot, setRetainedSnapshot] = (0, react.useState)(snapshot.open && snapshot.controller !== null ? snapshot : null);
|
|
3184
|
+
const [advancedEditorOpen, setAdvancedEditorOpen] = (0, react.useState)(false);
|
|
3185
|
+
(0, react.useEffect)(() => {
|
|
3186
|
+
if (snapshot.open && snapshot.controller !== null) setRetainedSnapshot(snapshot);
|
|
3187
|
+
}, [
|
|
3188
|
+
snapshot.controller,
|
|
3189
|
+
snapshot.open,
|
|
3190
|
+
snapshot.sessionId
|
|
3191
|
+
]);
|
|
3192
|
+
(0, react.useEffect)(() => {
|
|
3193
|
+
if (snapshot.open || retainedSnapshot === null) return;
|
|
3194
|
+
const timer = window.setTimeout(() => setRetainedSnapshot(null), MODELLIX_DRAWER_EXIT_MS);
|
|
3195
|
+
return () => window.clearTimeout(timer);
|
|
3196
|
+
}, [retainedSnapshot, snapshot.open]);
|
|
3197
|
+
(0, react.useEffect)(() => {
|
|
3198
|
+
setAdvancedEditorOpen(false);
|
|
3199
|
+
}, [snapshot.sessionId]);
|
|
3200
|
+
(0, react.useEffect)(() => {
|
|
3201
|
+
if (!snapshot.open || typeof window.matchMedia !== "function") return;
|
|
3202
|
+
const media = window.matchMedia(MODELLIX_DESIGN_SPLIT_MEDIA_QUERY);
|
|
3203
|
+
const sync = () => drawer.setSplitMode(media.matches);
|
|
3204
|
+
sync();
|
|
3205
|
+
media.addEventListener("change", sync);
|
|
3206
|
+
return () => media.removeEventListener("change", sync);
|
|
3207
|
+
}, [drawer, snapshot.open]);
|
|
3208
|
+
const presentedSnapshot = snapshot.open && snapshot.controller !== null ? snapshot : retainedSnapshot;
|
|
3209
|
+
if (presentedSnapshot === null || presentedSnapshot.controller === null) return null;
|
|
3210
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3211
|
+
className: "mdlx-design-drawer-viewport",
|
|
3212
|
+
"data-closing": !snapshot.open || void 0,
|
|
3213
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
3214
|
+
id: "mdlx-design-drawer",
|
|
3215
|
+
className: "mdlx-design-drawer",
|
|
3216
|
+
"aria-labelledby": "mdlx-design-drawer-title",
|
|
3217
|
+
onKeyDown: (event) => {
|
|
3218
|
+
if (event.key === "Escape") {
|
|
3219
|
+
event.preventDefault();
|
|
3220
|
+
drawer.close();
|
|
3221
|
+
}
|
|
3222
|
+
},
|
|
3223
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
3224
|
+
className: "mdlx-drawer-header",
|
|
3225
|
+
"data-editor-open": advancedEditorOpen || void 0,
|
|
3226
|
+
children: [
|
|
3227
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3228
|
+
type: "button",
|
|
3229
|
+
variant: "ghost",
|
|
3230
|
+
size: "sm",
|
|
3231
|
+
className: "mdlx-drawer-close",
|
|
3232
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 16 }),
|
|
3233
|
+
"aria-label": `${t("close")} ${t("designTitle")}`,
|
|
3234
|
+
onClick: () => drawer.close()
|
|
3235
|
+
}),
|
|
3236
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3237
|
+
className: "mdlx-heading",
|
|
3238
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
3239
|
+
id: "mdlx-design-drawer-title",
|
|
3240
|
+
children: t("designTitle")
|
|
3241
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3242
|
+
className: "mdlx-muted",
|
|
3243
|
+
children: t("designDescription")
|
|
3244
|
+
})]
|
|
3245
|
+
}),
|
|
3246
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3247
|
+
className: "mdlx-drawer-header-reveal",
|
|
3248
|
+
hidden: MODELLIX_ADVANCED_EDITOR_ENTRY_HIDDEN,
|
|
3249
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3250
|
+
type: "button",
|
|
3251
|
+
variant: "outline",
|
|
3252
|
+
className: "mdlx-drawer-editor-toggle",
|
|
3253
|
+
"aria-controls": "mdlx-design-editor",
|
|
3254
|
+
"aria-expanded": advancedEditorOpen,
|
|
3255
|
+
onClick: (event) => {
|
|
3256
|
+
const next = !advancedEditorOpen;
|
|
3257
|
+
setAdvancedEditorOpen(next);
|
|
3258
|
+
if (!next && event.detail > 0) event.currentTarget.blur();
|
|
3259
|
+
},
|
|
3260
|
+
children: t("advancedEditor")
|
|
3261
|
+
}) })
|
|
3262
|
+
})
|
|
3263
|
+
]
|
|
3264
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3265
|
+
className: "mdlx-drawer-body",
|
|
3266
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModellixDesignView, {
|
|
3267
|
+
advancedEditorOpen,
|
|
3268
|
+
controller: presentedSnapshot.controller,
|
|
3269
|
+
settingsController,
|
|
3270
|
+
onAddUrl: (url) => drawer.appendUrl(url),
|
|
3271
|
+
t
|
|
3272
|
+
})
|
|
3273
|
+
})]
|
|
3274
|
+
})
|
|
3275
|
+
});
|
|
3276
|
+
}
|
|
3277
|
+
//#endregion
|
|
3278
|
+
//#region src/client/MediaToolView.tsx
|
|
3279
|
+
function ModellixMediaToolView({ block, drawer, inputActions, sessionId, t, useInput }) {
|
|
3280
|
+
const draft = useInput((state) => state.draft);
|
|
3281
|
+
const [tab, setTab] = (0, react.useState)("preview");
|
|
3282
|
+
const [activeIndex, setActiveIndex] = (0, react.useState)(0);
|
|
3283
|
+
const [imageOpen, setImageOpen] = (0, react.useState)(false);
|
|
3284
|
+
const tabId = (0, react.useId)();
|
|
3285
|
+
const imageDialogRef = (0, react.useRef)(null);
|
|
3286
|
+
const isResultBlock = "kind" in block && block.kind === "tool-result";
|
|
3287
|
+
const parsedResult = isResultBlock ? parseMediaToolResult(block.meta) : null;
|
|
3288
|
+
const liveState = useResourceState(drawer.controllerForSession(String(sessionId)).store);
|
|
3289
|
+
const trackedJobId = mediaToolJobId(parsedResult);
|
|
3290
|
+
const operation = parsedResult?.operation;
|
|
3291
|
+
const callId = "callId" in block && typeof block.callId === "string" ? block.callId : `${String(sessionId)}:${trackedJobId ?? "pending"}`;
|
|
3292
|
+
(0, react.useSyncExternalStore)(drawer.subscribeMediaCards, drawer.getMediaCardVersion, drawer.getMediaCardVersion);
|
|
3293
|
+
const parsedStatus = mediaToolStatus(parsedResult);
|
|
3294
|
+
const result = resolveLiveMediaToolResult(parsedResult, trackedJobId === void 0 ? void 0 : liveState.data?.jobs.find((job) => job.jobId === trackedJobId), t);
|
|
3295
|
+
(0, react.useEffect)(() => trackedJobId === void 0 ? void 0 : drawer.watchJob(String(sessionId), trackedJobId, parsedStatus), [
|
|
3296
|
+
drawer,
|
|
3297
|
+
parsedStatus,
|
|
3298
|
+
sessionId,
|
|
3299
|
+
trackedJobId
|
|
3300
|
+
]);
|
|
3301
|
+
(0, react.useEffect)(() => trackedJobId === void 0 || operation === void 0 ? void 0 : drawer.claimMediaCard(String(sessionId), trackedJobId, callId, operation), [
|
|
3302
|
+
callId,
|
|
3303
|
+
drawer,
|
|
3304
|
+
operation,
|
|
3305
|
+
sessionId,
|
|
3306
|
+
trackedJobId
|
|
3307
|
+
]);
|
|
3308
|
+
const resources = result?.operation === "get_result" ? result.job?.resources ?? [] : result?.resources ?? [];
|
|
3309
|
+
const resourceIndex = resources.length === 0 ? 0 : activeIndex % resources.length;
|
|
3310
|
+
const current = resources[resourceIndex];
|
|
3311
|
+
const imageSurfaceOpen = useExternalDialogGate(imageOpen && current?.kind === "image");
|
|
3312
|
+
const closeImage = (0, react.useCallback)(() => setImageOpen(false), []);
|
|
3313
|
+
useDialogA11y({
|
|
3314
|
+
open: imageSurfaceOpen,
|
|
3315
|
+
container: imageDialogRef,
|
|
3316
|
+
initialFocusSelector: "[data-mdlx-initial-focus]",
|
|
3317
|
+
mandatory: false,
|
|
3318
|
+
onEscape: closeImage
|
|
3319
|
+
});
|
|
3320
|
+
(0, react.useEffect)(() => setImageOpen(false), [current?.url]);
|
|
3321
|
+
if (trackedJobId !== void 0 && operation !== void 0 && !drawer.isMediaCardPrimary(String(sessionId), trackedJobId, callId, operation)) return null;
|
|
3322
|
+
if (!isResultBlock) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3323
|
+
className: "mdlx-tool-result mdlx-muted",
|
|
3324
|
+
role: "status",
|
|
3325
|
+
children: t("generating")
|
|
3326
|
+
});
|
|
3327
|
+
if (result === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3328
|
+
className: "mdlx-tool-result mdlx-muted",
|
|
3329
|
+
role: "status",
|
|
3330
|
+
children: t("noPreview")
|
|
3331
|
+
});
|
|
3332
|
+
const status = result.operation === "get_result" ? result.job?.status : result.status;
|
|
3333
|
+
const modelId = result.operation === "get_result" ? result.job?.modelId : result.modelId;
|
|
3334
|
+
const diagnostic = result.operation === "get_result" ? result.job?.diagnostic : result.diagnostic;
|
|
3335
|
+
const succeeded = status === "succeeded";
|
|
3336
|
+
const activeTabId = `${tabId}-${tab}-tab`;
|
|
3337
|
+
const activePanelId = `${tabId}-${tab}-panel`;
|
|
3338
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
3339
|
+
className: "mdlx-tool-result",
|
|
3340
|
+
children: [
|
|
3341
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3342
|
+
className: "mdlx-result-head",
|
|
3343
|
+
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", {
|
|
3344
|
+
className: "mdlx-muted",
|
|
3345
|
+
children: modelId
|
|
3346
|
+
})]
|
|
3347
|
+
}),
|
|
3348
|
+
succeeded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3349
|
+
className: "mdlx-result-tabs",
|
|
3350
|
+
role: "tablist",
|
|
3351
|
+
"aria-label": t("resultViewLabel"),
|
|
3352
|
+
onKeyDown: handleResultTabKeyDown,
|
|
3353
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3354
|
+
id: `${tabId}-preview-tab`,
|
|
3355
|
+
type: "button",
|
|
3356
|
+
role: "tab",
|
|
3357
|
+
"aria-controls": `${tabId}-preview-panel`,
|
|
3358
|
+
"aria-selected": tab === "preview",
|
|
3359
|
+
tabIndex: tab === "preview" ? 0 : -1,
|
|
3360
|
+
className: "mdlx-result-tab",
|
|
3361
|
+
onClick: () => setTab("preview"),
|
|
3362
|
+
children: t("previewTab")
|
|
3363
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3364
|
+
id: `${tabId}-json-tab`,
|
|
3365
|
+
type: "button",
|
|
3366
|
+
role: "tab",
|
|
3367
|
+
"aria-controls": `${tabId}-json-panel`,
|
|
3368
|
+
"aria-selected": tab === "json",
|
|
3369
|
+
tabIndex: tab === "json" ? 0 : -1,
|
|
3370
|
+
className: "mdlx-result-tab",
|
|
3371
|
+
onClick: () => setTab("json"),
|
|
3372
|
+
children: t("jsonTab")
|
|
3373
|
+
})]
|
|
3374
|
+
}), tab === "json" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
3375
|
+
id: activePanelId,
|
|
3376
|
+
role: "tabpanel",
|
|
3377
|
+
"aria-labelledby": activeTabId,
|
|
3378
|
+
className: "mdlx-result-json",
|
|
3379
|
+
children: JSON.stringify(result, null, 2)
|
|
3380
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3381
|
+
id: activePanelId,
|
|
3382
|
+
role: "tabpanel",
|
|
3383
|
+
"aria-labelledby": activeTabId,
|
|
3384
|
+
className: "mdlx-result-panel",
|
|
3385
|
+
children: current === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3386
|
+
className: "mdlx-empty mdlx-empty-compact",
|
|
3387
|
+
children: t("noPreview")
|
|
3388
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3389
|
+
current.kind === "image" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3390
|
+
type: "button",
|
|
3391
|
+
className: "mdlx-image-preview-button",
|
|
3392
|
+
"aria-label": t("openImage"),
|
|
3393
|
+
onClick: () => setImageOpen(true),
|
|
3394
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignResultPreview, {
|
|
3395
|
+
resource: toWireResource(current, resourceIndex),
|
|
3396
|
+
t
|
|
3397
|
+
})
|
|
3398
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DesignResultPreview, {
|
|
3399
|
+
resource: toWireResource(current, resourceIndex),
|
|
3400
|
+
t
|
|
3401
|
+
}),
|
|
3402
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3403
|
+
className: "mdlx-actions mdlx-actions-start",
|
|
3404
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3405
|
+
type: "button",
|
|
3406
|
+
variant: "outline",
|
|
3407
|
+
onClick: () => {
|
|
3408
|
+
const separator = draft === "" || /\s$/u.test(draft) ? "" : "\n";
|
|
3409
|
+
inputActions.setDraft(`${draft}${separator}${current.url}`);
|
|
3410
|
+
},
|
|
3411
|
+
children: t("addUrlToChat")
|
|
3412
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
3413
|
+
className: "mdlx-safe-link",
|
|
3414
|
+
href: current.url,
|
|
3415
|
+
target: "_blank",
|
|
3416
|
+
rel: "noopener noreferrer",
|
|
3417
|
+
referrerPolicy: "no-referrer",
|
|
3418
|
+
download: true,
|
|
3419
|
+
children: t("download")
|
|
3420
|
+
})]
|
|
3421
|
+
}),
|
|
3422
|
+
resources.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3423
|
+
className: "mdlx-resource-nav",
|
|
3424
|
+
"aria-label": t("resourceNavigation"),
|
|
3425
|
+
children: [
|
|
3426
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3427
|
+
type: "button",
|
|
3428
|
+
variant: "outline",
|
|
3429
|
+
onClick: () => setActiveIndex((resourceIndex - 1 + resources.length) % resources.length),
|
|
3430
|
+
children: t("previousResource")
|
|
3431
|
+
}),
|
|
3432
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3433
|
+
className: "mdlx-muted",
|
|
3434
|
+
children: t("resourcePosition", {
|
|
3435
|
+
current: resourceIndex + 1,
|
|
3436
|
+
total: resources.length
|
|
3437
|
+
})
|
|
3438
|
+
}),
|
|
3439
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3440
|
+
type: "button",
|
|
3441
|
+
variant: "outline",
|
|
3442
|
+
onClick: () => setActiveIndex((resourceIndex + 1) % resources.length),
|
|
3443
|
+
children: t("nextResource")
|
|
3444
|
+
})
|
|
3445
|
+
]
|
|
3446
|
+
})
|
|
3447
|
+
] })
|
|
3448
|
+
})] }),
|
|
3449
|
+
diagnostic !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3450
|
+
className: "mdlx-error",
|
|
3451
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
3452
|
+
className: "mdlx-code",
|
|
3453
|
+
children: diagnostic.code
|
|
3454
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: diagnostic.message })]
|
|
3455
|
+
})
|
|
3456
|
+
]
|
|
3457
|
+
}), succeeded && current?.kind === "image" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
3458
|
+
open: imageSurfaceOpen,
|
|
3459
|
+
title: t("imageViewerTitle"),
|
|
3460
|
+
closeLabel: t("close"),
|
|
3461
|
+
onClose: closeImage,
|
|
3462
|
+
headless: true,
|
|
3463
|
+
className: "mdlx-modal mdlx-image-modal",
|
|
3464
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3465
|
+
ref: imageDialogRef,
|
|
3466
|
+
className: "mdlx-modal-content",
|
|
3467
|
+
"data-mdlx-dialog-surface": "",
|
|
3468
|
+
tabIndex: -1,
|
|
3469
|
+
children: [
|
|
3470
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3471
|
+
className: "mdlx-heading",
|
|
3472
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
3473
|
+
className: "mdlx-modal-title",
|
|
3474
|
+
children: t("imageViewerTitle")
|
|
3475
|
+
})
|
|
3476
|
+
}),
|
|
3477
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
3478
|
+
className: "mdlx-image-full",
|
|
3479
|
+
src: current.url,
|
|
3480
|
+
alt: t("generatedPreview"),
|
|
3481
|
+
referrerPolicy: "no-referrer"
|
|
3482
|
+
}),
|
|
3483
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3484
|
+
className: "mdlx-actions",
|
|
3485
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3486
|
+
type: "button",
|
|
3487
|
+
variant: "outline",
|
|
3488
|
+
"data-mdlx-initial-focus": "",
|
|
3489
|
+
onClick: closeImage,
|
|
3490
|
+
children: t("close")
|
|
3491
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
3492
|
+
className: "mdlx-safe-link",
|
|
3493
|
+
href: current.url,
|
|
3494
|
+
target: "_blank",
|
|
3495
|
+
rel: "noopener noreferrer",
|
|
3496
|
+
referrerPolicy: "no-referrer",
|
|
3497
|
+
download: true,
|
|
3498
|
+
children: t("download")
|
|
3499
|
+
})]
|
|
3500
|
+
})
|
|
3501
|
+
]
|
|
3502
|
+
})
|
|
3503
|
+
})] });
|
|
3504
|
+
}
|
|
3505
|
+
function mediaToolJobId(result) {
|
|
3506
|
+
return result?.operation === "get_result" ? result.job?.jobId : result?.jobId;
|
|
3507
|
+
}
|
|
3508
|
+
function mediaToolStatus(result) {
|
|
3509
|
+
return result?.operation === "get_result" ? result.job?.status : result?.status;
|
|
3510
|
+
}
|
|
3511
|
+
function resolveLiveMediaToolResult(result, liveJob, t) {
|
|
3512
|
+
if (result === null || liveJob === void 0) return result;
|
|
3513
|
+
const resources = liveJob.resources.map((resource) => ({
|
|
3514
|
+
kind: resource.kind,
|
|
3515
|
+
url: resource.url,
|
|
3516
|
+
...resource.expiresAt === null ? {} : { expiresAt: resource.expiresAt }
|
|
3517
|
+
}));
|
|
3518
|
+
const diagnostic = liveJob.diagnostic === null ? void 0 : {
|
|
3519
|
+
code: liveJob.diagnostic.code,
|
|
3520
|
+
message: t(designDiagnosticMessageKey(liveJob.diagnostic.code))
|
|
3521
|
+
};
|
|
3522
|
+
if (result.operation === "generate") {
|
|
3523
|
+
const { diagnostic: _staleDiagnostic, ...withoutDiagnostic } = result;
|
|
3524
|
+
return {
|
|
3525
|
+
...withoutDiagnostic,
|
|
3526
|
+
status: liveJob.status,
|
|
3527
|
+
modelId: liveJob.modelId,
|
|
3528
|
+
resources,
|
|
3529
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3530
|
+
};
|
|
3531
|
+
}
|
|
3532
|
+
return {
|
|
3533
|
+
...result,
|
|
3534
|
+
found: true,
|
|
3535
|
+
job: {
|
|
3536
|
+
jobId: liveJob.jobId,
|
|
3537
|
+
modelId: liveJob.modelId,
|
|
3538
|
+
status: liveJob.status,
|
|
3539
|
+
resources,
|
|
3540
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3541
|
+
}
|
|
3542
|
+
};
|
|
3543
|
+
}
|
|
3544
|
+
function parseMediaToolResult(value) {
|
|
3545
|
+
const root = record(value);
|
|
3546
|
+
if (root === null || root.service !== "media" || root.operation !== "generate" && root.operation !== "get_result") return null;
|
|
3547
|
+
if (root.operation === "generate") {
|
|
3548
|
+
const status = safeText(root.status, 64);
|
|
3549
|
+
const modelId = safeText(root.modelId, 256);
|
|
3550
|
+
const jobId = safeText(root.jobId, 256);
|
|
3551
|
+
const diagnostic = parseDiagnostic(root.diagnostic);
|
|
3552
|
+
return {
|
|
3553
|
+
operation: "generate",
|
|
3554
|
+
...status === void 0 ? {} : { status },
|
|
3555
|
+
...modelId === void 0 ? {} : { modelId },
|
|
3556
|
+
...jobId === void 0 ? {} : { jobId },
|
|
3557
|
+
resources: parseResources(root.resources),
|
|
3558
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3559
|
+
};
|
|
3560
|
+
}
|
|
3561
|
+
const job = record(root.job);
|
|
3562
|
+
const diagnostic = job === null ? void 0 : parseDiagnostic(job.diagnostic);
|
|
3563
|
+
return {
|
|
3564
|
+
operation: "get_result",
|
|
3565
|
+
found: root.found === true,
|
|
3566
|
+
...job === null ? {} : { job: {
|
|
3567
|
+
jobId: safeText(job.jobId, 256) ?? "",
|
|
3568
|
+
modelId: safeText(job.modelId, 256) ?? "",
|
|
3569
|
+
status: safeText(job.status, 64) ?? "",
|
|
3570
|
+
resources: parseResources(job.resources),
|
|
3571
|
+
...diagnostic === void 0 ? {} : { diagnostic }
|
|
3572
|
+
} }
|
|
3573
|
+
};
|
|
3574
|
+
}
|
|
3575
|
+
function parseResources(value) {
|
|
3576
|
+
if (!Array.isArray(value)) return [];
|
|
3577
|
+
const resources = [];
|
|
3578
|
+
for (const candidate of value.slice(0, 32)) {
|
|
3579
|
+
const resource = record(candidate);
|
|
3580
|
+
if (resource === null || resource.kind !== "image" && resource.kind !== "video" && resource.kind !== "audio" || typeof resource.url !== "string") continue;
|
|
3581
|
+
let url;
|
|
3582
|
+
try {
|
|
3583
|
+
url = safeResourceHref(resource.url);
|
|
3584
|
+
} catch {
|
|
3585
|
+
continue;
|
|
3586
|
+
}
|
|
3587
|
+
const expiresAt = safeText(resource.expiresAt, 128);
|
|
3588
|
+
resources.push({
|
|
3589
|
+
kind: resource.kind,
|
|
3590
|
+
url,
|
|
3591
|
+
...expiresAt === void 0 ? {} : { expiresAt }
|
|
3592
|
+
});
|
|
3593
|
+
}
|
|
3594
|
+
return resources;
|
|
3595
|
+
}
|
|
3596
|
+
function parseDiagnostic(value) {
|
|
3597
|
+
const diagnostic = record(value);
|
|
3598
|
+
if (diagnostic === null) return void 0;
|
|
3599
|
+
const code = safeText(diagnostic.code, 128);
|
|
3600
|
+
const message = safeText(diagnostic.message, 1024);
|
|
3601
|
+
return code === void 0 || message === void 0 ? void 0 : {
|
|
3602
|
+
code,
|
|
3603
|
+
message
|
|
3604
|
+
};
|
|
3605
|
+
}
|
|
3606
|
+
function safeText(value, maximum) {
|
|
3607
|
+
return typeof value === "string" && value.length > 0 && value.length <= maximum ? value : void 0;
|
|
3608
|
+
}
|
|
3609
|
+
function record(value) {
|
|
3610
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
3611
|
+
}
|
|
3612
|
+
function mediaStatusLabel(status, t) {
|
|
3613
|
+
switch (status) {
|
|
3614
|
+
case "running": return t("running");
|
|
3615
|
+
case "succeeded": return t("succeeded");
|
|
3616
|
+
case "failed": return t("failed");
|
|
3617
|
+
case "canceled": return t("canceled");
|
|
3618
|
+
case "expired": return t("expired");
|
|
3619
|
+
case "submit-unknown": return t("unknown");
|
|
3620
|
+
default: return t("unknown");
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
function toWireResource(resource, index) {
|
|
3624
|
+
return {
|
|
3625
|
+
id: `tool-resource-${String(index)}`,
|
|
3626
|
+
kind: resource.kind,
|
|
3627
|
+
url: resource.url,
|
|
3628
|
+
downloadUrl: resource.url,
|
|
3629
|
+
expiresAt: resource.expiresAt ?? null
|
|
3630
|
+
};
|
|
3631
|
+
}
|
|
3632
|
+
//#endregion
|
|
2865
3633
|
//#region src/client/locales.ts
|
|
2866
3634
|
const MODELLIX_LOCALE_NAMESPACE = "modellix";
|
|
2867
3635
|
const zh = {
|
|
2868
3636
|
dateLocale: "zh-CN",
|
|
2869
3637
|
nav: "Modellix",
|
|
2870
|
-
designTab: "Design",
|
|
2871
3638
|
onboardingTitle: "连接 Modellix",
|
|
2872
3639
|
onboardingDescription: "输入一个 Modellix API Key,即可启用 Design、LLM 模型和 Web Tools。",
|
|
2873
3640
|
keyLabel: "Modellix API Key",
|
|
@@ -2884,7 +3651,7 @@ const zh = {
|
|
|
2884
3651
|
serviceLlm: "LLM 模型",
|
|
2885
3652
|
serviceLlmDescription: "在 Harness 中快速切换 Modellix 支持的模型。",
|
|
2886
3653
|
serviceWeb: "Web Tools",
|
|
2887
|
-
serviceWebDescription: "
|
|
3654
|
+
serviceWebDescription: "提供可自动调用的 Modellix 网页搜索与读取工具。",
|
|
2888
3655
|
settingsTitle: "Modellix",
|
|
2889
3656
|
settingsDescription: "一个 API Key,统一使用 Design、LLM 与 Web Tools。",
|
|
2890
3657
|
credentialTitle: "API Key",
|
|
@@ -2927,13 +3694,13 @@ const zh = {
|
|
|
2927
3694
|
errorGeneric: "暂时无法完成操作,请重试。",
|
|
2928
3695
|
errorConflict: "配置已在其他位置更新,请刷新后重试。",
|
|
2929
3696
|
errorKeyInvalid: "这个 API Key 无效,请检查后重新输入。",
|
|
2930
|
-
errorBilling: "
|
|
3697
|
+
errorBilling: "当前请求无法完成,请在 Modellix 控制台查看账户状态。",
|
|
2931
3698
|
errorRateLimited: "请求过于频繁,请稍后手动重试。",
|
|
2932
3699
|
errorOffline: "当前无法连接 Modellix,请检查网络后重试。",
|
|
2933
3700
|
errorTimeout: "Modellix 响应超时,请稍后手动重试。",
|
|
2934
3701
|
errorServer: "Modellix 服务暂时不可用,请稍后手动重试。",
|
|
2935
3702
|
errorPolicy: "当前账户或环境策略不允许此操作。",
|
|
2936
|
-
errorSubmitUnknown: "
|
|
3703
|
+
errorSubmitUnknown: "提交结果未知。请先查看结果列表,不要重复提交。",
|
|
2937
3704
|
errorAssetExpired: "结果资源已过期,无法继续访问。",
|
|
2938
3705
|
errorDesignSchema: "模型参数定义已变化或无法解析,请刷新模型后重试。",
|
|
2939
3706
|
designTitle: "Modellix Design",
|
|
@@ -2953,11 +3720,11 @@ const zh = {
|
|
|
2953
3720
|
promptPlaceholder: "描述画面、视频动作或要合成的声音…",
|
|
2954
3721
|
parametersTitle: "参数",
|
|
2955
3722
|
advancedParameters: "高级参数({count})",
|
|
3723
|
+
advancedEditor: "高级参数编辑器",
|
|
2956
3724
|
required: "必填",
|
|
2957
3725
|
optional: "可选",
|
|
2958
3726
|
requiredMissing: "请填写所有必填参数后再生成。",
|
|
2959
3727
|
assistantTitle: "用对话调整参数",
|
|
2960
|
-
assistantPaidNotice: "发送后会使用同一个 Modellix Key 调用固定 LLM 生成参数提议,可能产生费用;不会自动生成媒体。",
|
|
2961
3728
|
assistantPlaceholder: "例如:改成 16:9,生成 8 秒视频,风格更电影化",
|
|
2962
3729
|
propose: "生成参数提议",
|
|
2963
3730
|
proposing: "正在分析…",
|
|
@@ -2969,7 +3736,6 @@ const zh = {
|
|
|
2969
3736
|
conflicts: "需要先解决冲突",
|
|
2970
3737
|
generate: "确认并生成",
|
|
2971
3738
|
generating: "正在提交…",
|
|
2972
|
-
paidNotice: "生成是计费操作;每次点击只提交一次,不会自动重试。",
|
|
2973
3739
|
designDisabled: "Design 已关闭,可在 Modellix 设置中重新开启。",
|
|
2974
3740
|
keyRequired: "请先在 Modellix 设置中配置 API Key。",
|
|
2975
3741
|
noModels: "当前没有可用模型,请稍后刷新。",
|
|
@@ -2983,9 +3749,17 @@ const zh = {
|
|
|
2983
3749
|
designNoticeCatalogUnavailable: "Modellix Design 模型目录暂时不可用,请稍后刷新。",
|
|
2984
3750
|
designNoticeCredentialReloaded: "API Key 已更改,Design 模型和参数已重新加载。",
|
|
2985
3751
|
resultsTitle: "结果",
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
3752
|
+
resultsCount: "{count} 条",
|
|
3753
|
+
resultViewLabel: "结果视图",
|
|
3754
|
+
previewTab: "预览",
|
|
3755
|
+
jsonTab: "JSON",
|
|
3756
|
+
noPreview: "当前还没有可预览的媒体结果。",
|
|
3757
|
+
resultNotFound: "未找到对应的生成任务。",
|
|
3758
|
+
resourceNavigation: "媒体结果导航",
|
|
3759
|
+
previousResource: "上一项",
|
|
3760
|
+
nextResource: "下一项",
|
|
3761
|
+
resourcePosition: "第 {current} / {total} 项",
|
|
3762
|
+
addUrlToChat: "添加 URL 到对话框",
|
|
2989
3763
|
noResults: "还没有生成记录。确认参数并生成后,结果会显示在这里。",
|
|
2990
3764
|
running: "生成中",
|
|
2991
3765
|
succeeded: "已完成",
|
|
@@ -2993,10 +3767,10 @@ const zh = {
|
|
|
2993
3767
|
canceled: "已取消",
|
|
2994
3768
|
unknown: "提交结果未知",
|
|
2995
3769
|
expired: "结果已过期",
|
|
2996
|
-
openImage: "
|
|
3770
|
+
openImage: "放大图片",
|
|
2997
3771
|
imageViewerTitle: "生成图片",
|
|
2998
3772
|
close: "关闭",
|
|
2999
|
-
download: "
|
|
3773
|
+
download: "下载",
|
|
3000
3774
|
expiresAt: "有效期至 {time}",
|
|
3001
3775
|
invalidJson: "请输入有效的 JSON。",
|
|
3002
3776
|
invalidParameter: "此参数不符合当前模型的约束。",
|
|
@@ -3007,9 +3781,9 @@ const zh = {
|
|
|
3007
3781
|
generatedAudioPreview: "生成音频结果预览",
|
|
3008
3782
|
jobModel: "模型:{model}",
|
|
3009
3783
|
jobCreated: "创建于 {time}",
|
|
3010
|
-
diagnosticRetryable: "
|
|
3784
|
+
diagnosticRetryable: "插件会继续尝试安全的只读状态查询,但绝不会自动重复生成提交。",
|
|
3011
3785
|
diagnosticCredentialChanged: "此任务属于更早的 API Key,无法继续刷新。",
|
|
3012
|
-
diagnosticSubmitUnknown: "
|
|
3786
|
+
diagnosticSubmitUnknown: "生成提交结果未知,请先检查结果列表,不要重复提交。",
|
|
3013
3787
|
diagnosticGenerationFailed: "生成任务未完成。",
|
|
3014
3788
|
diagnosticResultUnavailable: "生成已完成,但没有可用的结果资源。",
|
|
3015
3789
|
diagnosticCredentialRejected: "刷新任务时 Modellix 拒绝了当前 API Key。",
|
|
@@ -3028,7 +3802,6 @@ const zh = {
|
|
|
3028
3802
|
const en = {
|
|
3029
3803
|
dateLocale: "en-US",
|
|
3030
3804
|
nav: "Modellix",
|
|
3031
|
-
designTab: "Design",
|
|
3032
3805
|
onboardingTitle: "Connect Modellix",
|
|
3033
3806
|
onboardingDescription: "Enter one Modellix API Key to enable Design, LLM models, and Web Tools.",
|
|
3034
3807
|
keyLabel: "Modellix API Key",
|
|
@@ -3045,7 +3818,7 @@ const en = {
|
|
|
3045
3818
|
serviceLlm: "LLM models",
|
|
3046
3819
|
serviceLlmDescription: "Quickly switch between Modellix models in Harness.",
|
|
3047
3820
|
serviceWeb: "Web Tools",
|
|
3048
|
-
serviceWebDescription: "Provide Modellix
|
|
3821
|
+
serviceWebDescription: "Provide automatic Modellix Web Search and Web Fetch tools.",
|
|
3049
3822
|
settingsTitle: "Modellix",
|
|
3050
3823
|
settingsDescription: "One API Key for Design, LLM, and Web Tools.",
|
|
3051
3824
|
credentialTitle: "API Key",
|
|
@@ -3088,13 +3861,13 @@ const en = {
|
|
|
3088
3861
|
errorGeneric: "The operation could not be completed. Try again.",
|
|
3089
3862
|
errorConflict: "Settings changed elsewhere. Refresh and try again.",
|
|
3090
3863
|
errorKeyInvalid: "This API Key is invalid. Check it and enter it again.",
|
|
3091
|
-
errorBilling: "
|
|
3864
|
+
errorBilling: "This request cannot be completed. Check the account status in the Modellix console.",
|
|
3092
3865
|
errorRateLimited: "Too many requests. Wait before retrying manually.",
|
|
3093
3866
|
errorOffline: "Modellix cannot be reached. Check the network and try again.",
|
|
3094
3867
|
errorTimeout: "Modellix timed out. Retry manually later.",
|
|
3095
3868
|
errorServer: "Modellix is temporarily unavailable. Retry manually later.",
|
|
3096
3869
|
errorPolicy: "The current account or environment policy does not allow this operation.",
|
|
3097
|
-
errorSubmitUnknown: "The submission outcome is unknown. Check Results before submitting
|
|
3870
|
+
errorSubmitUnknown: "The submission outcome is unknown. Check Results before submitting again.",
|
|
3098
3871
|
errorAssetExpired: "This result resource has expired and is no longer available.",
|
|
3099
3872
|
errorDesignSchema: "The model parameter definition changed or could not be parsed. Refresh the model and try again.",
|
|
3100
3873
|
designTitle: "Modellix Design",
|
|
@@ -3114,11 +3887,11 @@ const en = {
|
|
|
3114
3887
|
promptPlaceholder: "Describe the image, video motion, or sound…",
|
|
3115
3888
|
parametersTitle: "Parameters",
|
|
3116
3889
|
advancedParameters: "Advanced parameters ({count})",
|
|
3890
|
+
advancedEditor: "Advanced parameter editor",
|
|
3117
3891
|
required: "Required",
|
|
3118
3892
|
optional: "Optional",
|
|
3119
3893
|
requiredMissing: "Complete every required parameter before generating.",
|
|
3120
3894
|
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
3895
|
assistantPlaceholder: "For example: make it 16:9, eight seconds, and more cinematic",
|
|
3123
3896
|
propose: "Propose parameter changes",
|
|
3124
3897
|
proposing: "Analyzing…",
|
|
@@ -3130,7 +3903,6 @@ const en = {
|
|
|
3130
3903
|
conflicts: "Resolve conflicts before applying",
|
|
3131
3904
|
generate: "Confirm and generate",
|
|
3132
3905
|
generating: "Submitting…",
|
|
3133
|
-
paidNotice: "Generation is billed. Each click submits once and is never retried automatically.",
|
|
3134
3906
|
designDisabled: "Design is disabled. Enable it in Modellix settings.",
|
|
3135
3907
|
keyRequired: "Configure a Modellix API Key in settings first.",
|
|
3136
3908
|
noModels: "No model is currently available. Refresh and try again.",
|
|
@@ -3144,9 +3916,17 @@ const en = {
|
|
|
3144
3916
|
designNoticeCatalogUnavailable: "The Modellix Design model catalog is temporarily unavailable. Refresh it later.",
|
|
3145
3917
|
designNoticeCredentialReloaded: "The API Key changed, so the Design model and parameters were reloaded.",
|
|
3146
3918
|
resultsTitle: "Results",
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3919
|
+
resultsCount: "{count} item(s)",
|
|
3920
|
+
resultViewLabel: "Result view",
|
|
3921
|
+
previewTab: "Preview",
|
|
3922
|
+
jsonTab: "JSON",
|
|
3923
|
+
noPreview: "No media preview is available yet.",
|
|
3924
|
+
resultNotFound: "The requested generation task was not found.",
|
|
3925
|
+
resourceNavigation: "Media result navigation",
|
|
3926
|
+
previousResource: "Previous",
|
|
3927
|
+
nextResource: "Next",
|
|
3928
|
+
resourcePosition: "{current} of {total}",
|
|
3929
|
+
addUrlToChat: "Add URL to chat",
|
|
3150
3930
|
noResults: "No generations yet. Confirm parameters and generate to see results here.",
|
|
3151
3931
|
running: "Running",
|
|
3152
3932
|
succeeded: "Succeeded",
|
|
@@ -3154,10 +3934,10 @@ const en = {
|
|
|
3154
3934
|
canceled: "Canceled",
|
|
3155
3935
|
unknown: "Submission outcome unknown",
|
|
3156
3936
|
expired: "Result expired",
|
|
3157
|
-
openImage: "
|
|
3937
|
+
openImage: "Enlarge image",
|
|
3158
3938
|
imageViewerTitle: "Generated image",
|
|
3159
3939
|
close: "Close",
|
|
3160
|
-
download: "Download
|
|
3940
|
+
download: "Download",
|
|
3161
3941
|
expiresAt: "Available until {time}",
|
|
3162
3942
|
invalidJson: "Enter valid JSON.",
|
|
3163
3943
|
invalidParameter: "This value does not satisfy the current model constraints.",
|
|
@@ -3168,9 +3948,9 @@ const en = {
|
|
|
3168
3948
|
generatedAudioPreview: "Generated audio result preview",
|
|
3169
3949
|
jobModel: "Model: {model}",
|
|
3170
3950
|
jobCreated: "Created {time}",
|
|
3171
|
-
diagnosticRetryable: "The plugin will continue safe read-only status checks, but it never repeats a
|
|
3951
|
+
diagnosticRetryable: "The plugin will continue safe read-only status checks, but it never repeats a generation submission automatically.",
|
|
3172
3952
|
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
|
|
3953
|
+
diagnosticSubmitUnknown: "The generation submission outcome is unknown. Check Results before submitting again.",
|
|
3174
3954
|
diagnosticGenerationFailed: "The generation did not complete.",
|
|
3175
3955
|
diagnosticResultUnavailable: "The generation completed without a usable result resource.",
|
|
3176
3956
|
diagnosticCredentialRejected: "Modellix rejected the current API Key while refreshing this task.",
|
|
@@ -3527,7 +4307,7 @@ function llmHealthText(health, t) {
|
|
|
3527
4307
|
//#endregion
|
|
3528
4308
|
//#region src/client/styles.ts
|
|
3529
4309
|
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}
|
|
4310
|
+
.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
4311
|
.mdlx-settings{width:min(100%,760px);min-width:0;display:grid;gap:12px;padding:4px}
|
|
3532
4312
|
.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
4313
|
.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 +4316,7 @@ const MODELLIX_CLIENT_CSS = String.raw`
|
|
|
3536
4316
|
.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
4317
|
.mdlx-card-head>.mdlx-heading{margin-bottom:0}
|
|
3538
4318
|
.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}
|
|
4319
|
+
.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
4320
|
.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
4321
|
.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
4322
|
.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 +4333,28 @@ const MODELLIX_CLIENT_CSS = String.raw`
|
|
|
3553
4333
|
.mdlx-link-button{appearance:none;border:0;padding:0;background:transparent;font:inherit;cursor:pointer}
|
|
3554
4334
|
.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
4335
|
.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(
|
|
4336
|
+
.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}
|
|
4337
|
+
.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
4338
|
.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
4339
|
.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
4340
|
.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
4341
|
.mdlx-generate-block{display:grid;gap:8px;min-width:0}.mdlx-generate-block>p{margin:0}
|
|
3561
4342
|
.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
4343
|
.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}
|
|
4344
|
+
.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}
|
|
4345
|
+
.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}
|
|
4346
|
+
.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
4347
|
.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
4348
|
.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}
|
|
4349
|
+
.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}
|
|
4350
|
+
@media (min-width:1280px){.mdlx-design-drawer{box-shadow:none}}
|
|
3569
4351
|
@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
4352
|
@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 (
|
|
4353
|
+
@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}}
|
|
4354
|
+
@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}}
|
|
4355
|
+
@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}}
|
|
4356
|
+
@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}}
|
|
4357
|
+
@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
4358
|
`;
|
|
3576
4359
|
function installModellixClientStyles(target = typeof document === "undefined" ? void 0 : document) {
|
|
3577
4360
|
if (target === void 0) return () => void 0;
|
|
@@ -3589,6 +4372,11 @@ const MODELLIX_CLIENT_SLOTS = Object.freeze([
|
|
|
3589
4372
|
id: "modellix.credential-recovery",
|
|
3590
4373
|
order: 10
|
|
3591
4374
|
},
|
|
4375
|
+
{
|
|
4376
|
+
name: "shell.overlay",
|
|
4377
|
+
id: "modellix.design-drawer",
|
|
4378
|
+
order: 20
|
|
4379
|
+
},
|
|
3592
4380
|
{
|
|
3593
4381
|
name: "settings.onboarding",
|
|
3594
4382
|
id: "modellix.onboarding",
|
|
@@ -3600,9 +4388,19 @@ const MODELLIX_CLIENT_SLOTS = Object.freeze([
|
|
|
3600
4388
|
order: 30
|
|
3601
4389
|
},
|
|
3602
4390
|
{
|
|
3603
|
-
name: "conversation.
|
|
3604
|
-
id: "modellix.design",
|
|
4391
|
+
name: "conversation.session.header.utilities",
|
|
4392
|
+
id: "modellix.design-launcher",
|
|
3605
4393
|
order: 20
|
|
4394
|
+
},
|
|
4395
|
+
{
|
|
4396
|
+
name: "tool.call.toolview",
|
|
4397
|
+
key: "modellix_media_generate",
|
|
4398
|
+
priority: 20
|
|
4399
|
+
},
|
|
4400
|
+
{
|
|
4401
|
+
name: "tool.call.toolview",
|
|
4402
|
+
key: "modellix_media_get_result",
|
|
4403
|
+
priority: 20
|
|
3606
4404
|
}
|
|
3607
4405
|
]);
|
|
3608
4406
|
//#endregion
|
|
@@ -3610,7 +4408,8 @@ const MODELLIX_CLIENT_SLOTS = Object.freeze([
|
|
|
3610
4408
|
const inject = [
|
|
3611
4409
|
"slots",
|
|
3612
4410
|
"locale",
|
|
3613
|
-
"connection"
|
|
4411
|
+
"connection",
|
|
4412
|
+
"layout"
|
|
3614
4413
|
];
|
|
3615
4414
|
function apply(ctx) {
|
|
3616
4415
|
ctx.effect(() => ctx.locale.register(MODELLIX_LOCALE_NAMESPACE, {
|
|
@@ -3621,6 +4420,7 @@ function apply(ctx) {
|
|
|
3621
4420
|
const t = ctx.locale.bind(MODELLIX_LOCALE_NAMESPACE);
|
|
3622
4421
|
const rpc = new ModellixRpcClient(ctx.connection.rpc);
|
|
3623
4422
|
const settingsController = new SettingsController(rpc);
|
|
4423
|
+
const designDrawer = new DesignDrawerController(rpc, ctx.layout);
|
|
3624
4424
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
3625
4425
|
name: "shell.overlay",
|
|
3626
4426
|
id: "modellix.credential-recovery",
|
|
@@ -3628,6 +4428,16 @@ function apply(ctx) {
|
|
|
3628
4428
|
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
3629
4429
|
inject: () => ({ controller: settingsController })
|
|
3630
4430
|
}, CredentialRecoveryOverlay));
|
|
4431
|
+
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
4432
|
+
name: "shell.overlay",
|
|
4433
|
+
id: "modellix.design-drawer",
|
|
4434
|
+
order: 20,
|
|
4435
|
+
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
4436
|
+
inject: () => ({
|
|
4437
|
+
drawer: designDrawer,
|
|
4438
|
+
settingsController
|
|
4439
|
+
})
|
|
4440
|
+
}, ModellixDesignDrawer));
|
|
3631
4441
|
ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
3632
4442
|
name: "settings.onboarding",
|
|
3633
4443
|
id: "modellix.onboarding",
|
|
@@ -3643,17 +4453,27 @@ function apply(ctx) {
|
|
|
3643
4453
|
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
3644
4454
|
inject: () => ({ controller: settingsController })
|
|
3645
4455
|
}, ModellixSettingsSection));
|
|
3646
|
-
ctx.slots.inject("conversation.
|
|
3647
|
-
name: "conversation.
|
|
3648
|
-
id: "modellix.design",
|
|
4456
|
+
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
4457
|
+
name: "conversation.session.header.utilities",
|
|
4458
|
+
id: "modellix.design-launcher",
|
|
3649
4459
|
order: 20,
|
|
3650
|
-
label: () => t("designTab"),
|
|
3651
4460
|
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
3652
|
-
inject: (
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
4461
|
+
inject: () => ({ drawer: designDrawer })
|
|
4462
|
+
}, ModellixDesignLauncher));
|
|
4463
|
+
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
4464
|
+
name: "tool.call.toolview",
|
|
4465
|
+
key: "modellix_media_generate",
|
|
4466
|
+
priority: 20,
|
|
4467
|
+
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
4468
|
+
inject: () => ({ drawer: designDrawer })
|
|
4469
|
+
}, ModellixMediaToolView));
|
|
4470
|
+
ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
|
|
4471
|
+
name: "tool.call.toolview",
|
|
4472
|
+
key: "modellix_media_get_result",
|
|
4473
|
+
priority: 20,
|
|
4474
|
+
locale: MODELLIX_LOCALE_NAMESPACE,
|
|
4475
|
+
inject: () => ({ drawer: designDrawer })
|
|
4476
|
+
}, ModellixMediaToolView));
|
|
3657
4477
|
}
|
|
3658
4478
|
//#endregion
|
|
3659
4479
|
exports.MODELLIX_CLIENT_SLOTS = MODELLIX_CLIENT_SLOTS;
|