dsh-image-gen 0.2.2 → 0.2.4
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/README.en.md +172 -172
- package/README.md +182 -182
- package/README.zh-CN.md +172 -172
- package/lib/client.js +282 -50
- package/lib/client.js.map +1 -1
- package/lib/types/client/image-ref.d.ts +8 -0
- package/lib/types/client/image-result-node.d.ts +53 -0
- package/lib/types/client/index.d.ts +13 -1
- package/package.json +133 -133
- package/skills/install-dsh-image-gen/SKILL.md +22 -22
package/lib/client.js
CHANGED
|
@@ -52,7 +52,7 @@ window.__ModuleLoader__.load({
|
|
|
52
52
|
}
|
|
53
53
|
if (!isRecord(value) || Object.keys(value).length === 0) throw new Error("ComfyUI workflow must be a non-empty API-format JSON object");
|
|
54
54
|
if (!Object.values(value).some((node) => {
|
|
55
|
-
const inputs = record(node)?.inputs;
|
|
55
|
+
const inputs = record$1(node)?.inputs;
|
|
56
56
|
return inputs !== void 0 && containsPromptPlaceholder(inputs);
|
|
57
57
|
})) throw new Error(`ComfyUI workflow must contain ${COMFYUI_PROMPT_PLACEHOLDER} in a text input`);
|
|
58
58
|
return value;
|
|
@@ -65,7 +65,7 @@ window.__ModuleLoader__.load({
|
|
|
65
65
|
function isRecord(value) {
|
|
66
66
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
67
67
|
}
|
|
68
|
-
function record(value) {
|
|
68
|
+
function record$1(value) {
|
|
69
69
|
return isRecord(value) ? value : void 0;
|
|
70
70
|
}
|
|
71
71
|
//#endregion
|
|
@@ -928,8 +928,146 @@ window.__ModuleLoader__.load({
|
|
|
928
928
|
}
|
|
929
929
|
}
|
|
930
930
|
//#endregion
|
|
931
|
+
//#region lib/types/client/image-ref.js
|
|
932
|
+
/**
|
|
933
|
+
* Extract the verified durable image attachment from a completed tool result block.
|
|
934
|
+
* Supports legacy rc.2 `resultView.content` and modern DSH `block.content`.
|
|
935
|
+
*/
|
|
936
|
+
function imageRef(block) {
|
|
937
|
+
if (!("kind" in block)) return void 0;
|
|
938
|
+
const fromResultView = block.resultView?.card === "generic" ? block.resultView.content?.find((item) => item.type === "image") : void 0;
|
|
939
|
+
if (fromResultView?.type === "image") return fromResultView.attachment;
|
|
940
|
+
const fromBlockContent = Array.isArray(block.content) ? block.content.find((item) => item.type === "image") : void 0;
|
|
941
|
+
if (fromBlockContent?.type === "image") return fromBlockContent.attachment;
|
|
942
|
+
}
|
|
943
|
+
//#endregion
|
|
944
|
+
//#region lib/types/client/image-result-node.js
|
|
945
|
+
const IMAGE_RESULT_NODE_KIND = "dsh-image-result";
|
|
946
|
+
/** One image result row per Turn, re-anchored to Turn end after the final answer settles. */
|
|
947
|
+
const imageResultDefinition = {
|
|
948
|
+
kind: IMAGE_RESULT_NODE_KIND,
|
|
949
|
+
target: "chat",
|
|
950
|
+
match: (event) => {
|
|
951
|
+
const turn = eventTurn(event);
|
|
952
|
+
if (turn === void 0) return null;
|
|
953
|
+
if (event.type === "turn/start") return {
|
|
954
|
+
id: String(turn),
|
|
955
|
+
role: "start"
|
|
956
|
+
};
|
|
957
|
+
if (event.type === "turn/end") return {
|
|
958
|
+
id: String(turn),
|
|
959
|
+
role: "update"
|
|
960
|
+
};
|
|
961
|
+
if (event.type === "assistant/message") return {
|
|
962
|
+
id: String(turn),
|
|
963
|
+
role: "update"
|
|
964
|
+
};
|
|
965
|
+
if (event.type === "tool/result" && imageResultFromMeta(event.data.meta) !== void 0) return {
|
|
966
|
+
id: String(turn),
|
|
967
|
+
role: "update"
|
|
968
|
+
};
|
|
969
|
+
return null;
|
|
970
|
+
},
|
|
971
|
+
start: (_context, match) => {
|
|
972
|
+
const turn = eventTurn(match.event);
|
|
973
|
+
if (match.event.type !== "turn/start" || turn === void 0) throw new Error("dsh-image-result start requires turn/start");
|
|
974
|
+
return {
|
|
975
|
+
turn,
|
|
976
|
+
results: []
|
|
977
|
+
};
|
|
978
|
+
},
|
|
979
|
+
update: (context, match) => {
|
|
980
|
+
if (match.event.type === "turn/end") return {
|
|
981
|
+
...context.state,
|
|
982
|
+
endSeq: match.event.seq
|
|
983
|
+
};
|
|
984
|
+
if (match.event.type === "assistant/message") return {
|
|
985
|
+
...context.state,
|
|
986
|
+
answerSeq: match.event.seq
|
|
987
|
+
};
|
|
988
|
+
if (match.event.type !== "tool/result") return context.state;
|
|
989
|
+
const result = imageResultFromMeta(match.event.data.meta);
|
|
990
|
+
if (result === void 0) return context.state;
|
|
991
|
+
if (context.state.results.some((candidate) => candidate.attachment.attachmentId === result.attachment.attachmentId)) return context.state;
|
|
992
|
+
return {
|
|
993
|
+
...context.state,
|
|
994
|
+
results: [...context.state.results, {
|
|
995
|
+
...result,
|
|
996
|
+
seq: match.event.seq
|
|
997
|
+
}]
|
|
998
|
+
};
|
|
999
|
+
},
|
|
1000
|
+
buildViewNode: (context) => {
|
|
1001
|
+
const state = context.state;
|
|
1002
|
+
const last = state?.results.at(-1);
|
|
1003
|
+
if (state === void 0 || last === void 0) return null;
|
|
1004
|
+
const location = context.matches.at(-1)?.location ?? context.start?.location ?? { kind: "unresolved" };
|
|
1005
|
+
return {
|
|
1006
|
+
key: context.key,
|
|
1007
|
+
kind: IMAGE_RESULT_NODE_KIND,
|
|
1008
|
+
id: context.id,
|
|
1009
|
+
target: "chat",
|
|
1010
|
+
anchorSeq: state.answerSeq ?? state.endSeq ?? last.seq,
|
|
1011
|
+
location,
|
|
1012
|
+
visibility: "visible",
|
|
1013
|
+
data: {
|
|
1014
|
+
turn: state.turn,
|
|
1015
|
+
results: state.results.map(({ seq: _seq, ...result }) => result)
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
};
|
|
1020
|
+
/** Parse the plugin-owned durable presentation metadata from a Tool result event. */
|
|
1021
|
+
function imageResultFromMeta(value) {
|
|
1022
|
+
const meta = record(value);
|
|
1023
|
+
if (meta?.kind !== "dsh-image-gen") return void 0;
|
|
1024
|
+
const attachment = imageAttachment(meta.attachment);
|
|
1025
|
+
if (attachment === void 0) return void 0;
|
|
1026
|
+
return {
|
|
1027
|
+
attachment,
|
|
1028
|
+
prompt: stringValue(meta.prompt, "Generated Image"),
|
|
1029
|
+
provider: stringValue(meta.provider, "google"),
|
|
1030
|
+
model: stringValue(meta.model, ""),
|
|
1031
|
+
output: stringValue(meta.output, ""),
|
|
1032
|
+
...typeof meta.savedTo === "string" ? { savedTo: meta.savedTo } : {}
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
function eventTurn(event) {
|
|
1036
|
+
const turn = event.data.turn;
|
|
1037
|
+
return typeof turn === "number" && Number.isSafeInteger(turn) && turn >= 0 ? turn : void 0;
|
|
1038
|
+
}
|
|
1039
|
+
function imageAttachment(value) {
|
|
1040
|
+
const candidate = record(value);
|
|
1041
|
+
if (candidate === void 0 || typeof candidate.attachmentId !== "string" || !isImageMediaType(candidate.mediaType) || !positiveInteger(candidate.bytes) || !positiveInteger(candidate.width) || !positiveInteger(candidate.height)) return void 0;
|
|
1042
|
+
const original = record(candidate.originalDimensions);
|
|
1043
|
+
if (candidate.originalDimensions !== void 0 && (original === void 0 || !positiveInteger(original.width) || !positiveInteger(original.height))) return void 0;
|
|
1044
|
+
return {
|
|
1045
|
+
attachmentId: candidate.attachmentId,
|
|
1046
|
+
mediaType: candidate.mediaType,
|
|
1047
|
+
bytes: candidate.bytes,
|
|
1048
|
+
width: candidate.width,
|
|
1049
|
+
height: candidate.height,
|
|
1050
|
+
...typeof candidate.name === "string" ? { name: candidate.name } : {},
|
|
1051
|
+
...original === void 0 ? {} : { originalDimensions: {
|
|
1052
|
+
width: original.width,
|
|
1053
|
+
height: original.height
|
|
1054
|
+
} }
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1057
|
+
function isImageMediaType(value) {
|
|
1058
|
+
return value === "image/png" || value === "image/jpeg" || value === "image/webp" || value === "image/gif";
|
|
1059
|
+
}
|
|
1060
|
+
function positiveInteger(value) {
|
|
1061
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
1062
|
+
}
|
|
1063
|
+
function stringValue(value, fallback) {
|
|
1064
|
+
return typeof value === "string" ? value : fallback;
|
|
1065
|
+
}
|
|
1066
|
+
function record(value) {
|
|
1067
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1068
|
+
}
|
|
1069
|
+
//#endregion
|
|
931
1070
|
//#region lib/types/client/index.js
|
|
932
|
-
/** Web settings and generated-image cards contributed by the Bundle. */
|
|
933
1071
|
const KEY_REF = {
|
|
934
1072
|
google: "GEMINI_API_KEY",
|
|
935
1073
|
openai: "OPENAI_API_KEY",
|
|
@@ -982,6 +1120,7 @@ window.__ModuleLoader__.load({
|
|
|
982
1120
|
loading: "正在加载图片…",
|
|
983
1121
|
loadFailed: "图片读取失败 ({status})",
|
|
984
1122
|
generatedTitle: "已生成图片",
|
|
1123
|
+
resultShown: "图片结果已显示在对话中",
|
|
985
1124
|
copyImg: "复制图片",
|
|
986
1125
|
download: "下载图片",
|
|
987
1126
|
openNewTab: "新标签页打开",
|
|
@@ -1033,6 +1172,7 @@ window.__ModuleLoader__.load({
|
|
|
1033
1172
|
loading: "Loading image…",
|
|
1034
1173
|
loadFailed: "Failed to load image ({status})",
|
|
1035
1174
|
generatedTitle: "Generated image",
|
|
1175
|
+
resultShown: "Image result is shown in the conversation",
|
|
1036
1176
|
copyImg: "Copy Image",
|
|
1037
1177
|
download: "Download Image",
|
|
1038
1178
|
openNewTab: "Open in new tab",
|
|
@@ -1074,6 +1214,7 @@ window.__ModuleLoader__.load({
|
|
|
1074
1214
|
.dsh-ig-save:disabled{opacity:.4;cursor:default}
|
|
1075
1215
|
|
|
1076
1216
|
.dsh-ig-result{display:grid;gap:10px;max-width:520px}
|
|
1217
|
+
.dsh-ig-promoted-results{display:grid;gap:16px}
|
|
1077
1218
|
.dsh-ig-result-title{font-size:14px;font-weight:600}
|
|
1078
1219
|
.dsh-ig-container{position:relative;display:inline-block;width:fit-content;max-width:100%;justify-self:start;border-radius:12px;overflow:hidden;line-height:0}
|
|
1079
1220
|
.dsh-ig-container:hover .dsh-ig-toolbar{opacity:1;pointer-events:auto}
|
|
@@ -1145,8 +1286,8 @@ window.__ModuleLoader__.load({
|
|
|
1145
1286
|
/** Required browser services. */
|
|
1146
1287
|
const inject = [
|
|
1147
1288
|
"slots",
|
|
1289
|
+
"connection",
|
|
1148
1290
|
"remote",
|
|
1149
|
-
"remote.credentials",
|
|
1150
1291
|
"settingsScope",
|
|
1151
1292
|
"locale"
|
|
1152
1293
|
];
|
|
@@ -1154,7 +1295,7 @@ window.__ModuleLoader__.load({
|
|
|
1154
1295
|
function apply(ctx) {
|
|
1155
1296
|
const scope = ctx.settingsScope.bind({ namespace: IMAGE_GENERATION_NAMESPACE });
|
|
1156
1297
|
const locale = ctx.get("locale");
|
|
1157
|
-
const
|
|
1298
|
+
const promotion = { enabled: false };
|
|
1158
1299
|
ctx.effect(() => {
|
|
1159
1300
|
const style = document.createElement("style");
|
|
1160
1301
|
style.dataset.plugin = "dsh-image-gen";
|
|
@@ -1165,24 +1306,54 @@ window.__ModuleLoader__.load({
|
|
|
1165
1306
|
};
|
|
1166
1307
|
}, "dsh-image-gen: styles");
|
|
1167
1308
|
const register = ctx.slots.register.bind(ctx.slots);
|
|
1168
|
-
ctx.
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1309
|
+
ctx.inject(["uiConversation"], (owner) => {
|
|
1310
|
+
const uiConversation = asModernUiConversation(owner.get("uiConversation"));
|
|
1311
|
+
if (uiConversation === void 0) throw new Error("dsh-image-gen: uiConversation has an incompatible interface");
|
|
1312
|
+
promotion.enabled = true;
|
|
1313
|
+
const ownerRegister = owner.slots.register.bind(owner.slots);
|
|
1314
|
+
owner.effect(() => uiConversation.events.register(imageResultDefinition), "dsh-image-gen: promoted image result node");
|
|
1315
|
+
owner.slots.inject("conversation.chat.node", () => ownerRegister({
|
|
1316
|
+
name: "conversation.chat.node",
|
|
1317
|
+
key: IMAGE_RESULT_NODE_KIND,
|
|
1318
|
+
inject: () => ({ locale })
|
|
1319
|
+
}, PromotedImageResultNode));
|
|
1320
|
+
});
|
|
1321
|
+
const injectSettingsItem = (owner, credentials) => {
|
|
1322
|
+
const ownerRegister = owner.slots.register.bind(owner.slots);
|
|
1323
|
+
owner.slots.inject("settings.plugin.item", () => ownerRegister({
|
|
1324
|
+
name: "settings.plugin.item",
|
|
1325
|
+
key: IMAGE_GENERATION_NAMESPACE,
|
|
1326
|
+
inject: () => ({
|
|
1327
|
+
scope,
|
|
1328
|
+
credentials,
|
|
1329
|
+
locale
|
|
1330
|
+
})
|
|
1331
|
+
}, ImageGenerationSettingsCard));
|
|
1332
|
+
};
|
|
1333
|
+
const remoteCredentials = asCredentialsRemote(ctx.get("remote.credentials"));
|
|
1334
|
+
const legacyCredentials = credentialsFromLegacyConnection(ctx.get("connection"));
|
|
1335
|
+
if (remoteCredentials !== void 0) injectSettingsItem(ctx, remoteCredentials);
|
|
1336
|
+
else if (legacyCredentials !== void 0) injectSettingsItem(ctx, legacyCredentials);
|
|
1337
|
+
else ctx.inject(["remote.credentials"], (remoteCtx) => {
|
|
1338
|
+
const credentials = asCredentialsRemote(remoteCtx.get("remote.credentials"));
|
|
1339
|
+
if (credentials === void 0) throw new Error("dsh-image-gen: remote.credentials has an incompatible interface");
|
|
1340
|
+
injectSettingsItem(remoteCtx, credentials);
|
|
1341
|
+
});
|
|
1177
1342
|
ctx.slots.inject("tool.call.toolview", () => register({
|
|
1178
1343
|
name: "tool.call.toolview",
|
|
1179
1344
|
key: "generate_image",
|
|
1180
|
-
inject: () => ({
|
|
1345
|
+
inject: () => ({
|
|
1346
|
+
locale,
|
|
1347
|
+
promoted: promotion.enabled
|
|
1348
|
+
})
|
|
1181
1349
|
}, GeneratedImageCard));
|
|
1182
1350
|
ctx.slots.inject("tool.call.toolview", () => register({
|
|
1183
1351
|
name: "tool.call.toolview",
|
|
1184
1352
|
key: "edit_image",
|
|
1185
|
-
inject: () => ({
|
|
1353
|
+
inject: () => ({
|
|
1354
|
+
locale,
|
|
1355
|
+
promoted: promotion.enabled
|
|
1356
|
+
})
|
|
1186
1357
|
}, GeneratedImageCard));
|
|
1187
1358
|
ctx.slots.inject("conversation.view", () => register({
|
|
1188
1359
|
name: "conversation.view",
|
|
@@ -1194,6 +1365,42 @@ window.__ModuleLoader__.load({
|
|
|
1194
1365
|
inject: () => ({ locale })
|
|
1195
1366
|
}, GalleryViewTab));
|
|
1196
1367
|
}
|
|
1368
|
+
function asModernUiConversation(value) {
|
|
1369
|
+
if (value === null || typeof value !== "object") return void 0;
|
|
1370
|
+
const events = value.events;
|
|
1371
|
+
if (events === null || typeof events !== "object") return void 0;
|
|
1372
|
+
return typeof events.register === "function" ? value : void 0;
|
|
1373
|
+
}
|
|
1374
|
+
function asCredentialsRemote(value) {
|
|
1375
|
+
if (value === null || typeof value !== "object") return void 0;
|
|
1376
|
+
const candidate = value;
|
|
1377
|
+
return typeof candidate.describe === "function" && typeof candidate.set === "function" ? candidate : void 0;
|
|
1378
|
+
}
|
|
1379
|
+
function credentialsFromLegacyConnection(value) {
|
|
1380
|
+
if (value === null || typeof value !== "object") return void 0;
|
|
1381
|
+
const credentials = value.api?.credentials;
|
|
1382
|
+
if (credentials === void 0 || typeof credentials.describe !== "function" || typeof credentials.set !== "function") return void 0;
|
|
1383
|
+
const legacy = credentials;
|
|
1384
|
+
return {
|
|
1385
|
+
async describe(refs) {
|
|
1386
|
+
const response = await legacy.describe({ refs });
|
|
1387
|
+
return response.result.ok ? {
|
|
1388
|
+
ok: true,
|
|
1389
|
+
value: response.result.value.credentials
|
|
1390
|
+
} : { ok: false };
|
|
1391
|
+
},
|
|
1392
|
+
async set(ref, credentialValue) {
|
|
1393
|
+
const response = await legacy.set({
|
|
1394
|
+
ref,
|
|
1395
|
+
value: credentialValue
|
|
1396
|
+
});
|
|
1397
|
+
return response.result.ok ? { ok: true } : {
|
|
1398
|
+
ok: false,
|
|
1399
|
+
error: response.result.error
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1197
1404
|
/** Edit provider settings and its write-only API credential. */
|
|
1198
1405
|
function ImageGenerationSettingsCard(props) {
|
|
1199
1406
|
const [open, setOpen] = (0, react.useState)(false);
|
|
@@ -1576,43 +1783,57 @@ window.__ModuleLoader__.load({
|
|
|
1576
1783
|
}) : null]
|
|
1577
1784
|
});
|
|
1578
1785
|
}
|
|
1579
|
-
/**
|
|
1786
|
+
/** Keep the legacy Tool row for old DSH and hand modern results to the independent Chat node. */
|
|
1580
1787
|
function GeneratedImageCard(props) {
|
|
1581
|
-
const
|
|
1582
|
-
|
|
1788
|
+
const result = imageResultFromBlock(props.block);
|
|
1789
|
+
if (props.promoted && result !== void 0) return (0, react_jsx_runtime.jsx)(PromotedResultNotice, { locale: props.locale });
|
|
1790
|
+
return (0, react_jsx_runtime.jsx)(ImageResultCard, {
|
|
1791
|
+
result,
|
|
1792
|
+
locale: props.locale
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1795
|
+
/** Render modern image artifacts as final conversation output instead of Tool process content. */
|
|
1796
|
+
function PromotedImageResultNode(props) {
|
|
1797
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
1798
|
+
className: "dsh-ig-promoted-results",
|
|
1799
|
+
children: props.node.data.results.map((result) => (0, react_jsx_runtime.jsx)(ImageResultCard, {
|
|
1800
|
+
result,
|
|
1801
|
+
locale: props.locale
|
|
1802
|
+
}, result.attachment.attachmentId))
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
function PromotedResultNotice({ locale }) {
|
|
1806
|
+
const lang = usePluginLanguage(locale);
|
|
1807
|
+
return (0, react_jsx_runtime.jsx)("div", {
|
|
1808
|
+
className: "dsh-ig-loading",
|
|
1809
|
+
children: DICT[lang].resultShown
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
function ImageResultCard({ result, locale }) {
|
|
1813
|
+
const attachment = result?.attachment;
|
|
1814
|
+
const savedTo = result?.savedTo;
|
|
1583
1815
|
const [url, setUrl] = (0, react.useState)();
|
|
1584
1816
|
const [blob, setBlob] = (0, react.useState)();
|
|
1585
1817
|
const [error, setError] = (0, react.useState)();
|
|
1586
1818
|
const [previewOpen, setPreviewOpen] = (0, react.useState)(false);
|
|
1587
1819
|
const [toast, setToast] = (0, react.useState)();
|
|
1588
|
-
const
|
|
1589
|
-
(0, react.useEffect)(() => {
|
|
1590
|
-
return props.locale?.subscribe?.(() => {
|
|
1591
|
-
setLang(props.locale?.getSnapshot?.()?.active?.startsWith("en") ? "en" : "zh");
|
|
1592
|
-
});
|
|
1593
|
-
}, [props.locale]);
|
|
1820
|
+
const lang = usePluginLanguage(locale);
|
|
1594
1821
|
const t = (keyName, params) => {
|
|
1595
1822
|
let text = (lang === "en" ? DICT.en : DICT.zh)[keyName] || DICT.zh[keyName] || keyName;
|
|
1596
1823
|
if (params) for (const [k, v] of Object.entries(params)) text = text.replace(`{${k}}`, v);
|
|
1597
1824
|
return text;
|
|
1598
1825
|
};
|
|
1599
1826
|
(0, react.useEffect)(() => {
|
|
1600
|
-
if (
|
|
1601
|
-
const blockAny = props.block;
|
|
1602
|
-
const meta = blockAny.meta ?? blockAny.resultView?.meta;
|
|
1603
|
-
const prompt = typeof meta?.prompt === "string" ? meta.prompt : blockAny.call?.args?.prompt ?? "Generated Image";
|
|
1604
|
-
const provider = typeof meta?.provider === "string" ? meta.provider : "google";
|
|
1605
|
-
const model = typeof meta?.model === "string" ? meta.model : "";
|
|
1606
|
-
const output = typeof meta?.output === "string" ? meta.output : "";
|
|
1827
|
+
if (result === void 0) return;
|
|
1607
1828
|
saveGalleryItem({
|
|
1608
|
-
id: attachment.attachmentId,
|
|
1609
|
-
attachment,
|
|
1610
|
-
prompt,
|
|
1611
|
-
provider,
|
|
1612
|
-
model,
|
|
1613
|
-
output
|
|
1829
|
+
id: result.attachment.attachmentId,
|
|
1830
|
+
attachment: result.attachment,
|
|
1831
|
+
prompt: result.prompt,
|
|
1832
|
+
provider: result.provider,
|
|
1833
|
+
model: result.model,
|
|
1834
|
+
output: result.output
|
|
1614
1835
|
});
|
|
1615
|
-
}, [attachment
|
|
1836
|
+
}, [result?.attachment.attachmentId]);
|
|
1616
1837
|
(0, react.useEffect)(() => {
|
|
1617
1838
|
if (!previewOpen) return;
|
|
1618
1839
|
const onKeyDown = (e) => {
|
|
@@ -1816,6 +2037,27 @@ window.__ModuleLoader__.load({
|
|
|
1816
2037
|
]
|
|
1817
2038
|
});
|
|
1818
2039
|
}
|
|
2040
|
+
function usePluginLanguage(locale) {
|
|
2041
|
+
const [lang, setLang] = (0, react.useState)(() => locale?.getSnapshot?.()?.active?.startsWith("en") ? "en" : "zh");
|
|
2042
|
+
(0, react.useEffect)(() => locale?.subscribe?.(() => {
|
|
2043
|
+
setLang(locale?.getSnapshot?.()?.active?.startsWith("en") ? "en" : "zh");
|
|
2044
|
+
}), [locale]);
|
|
2045
|
+
return lang;
|
|
2046
|
+
}
|
|
2047
|
+
function imageResultFromBlock(block) {
|
|
2048
|
+
const attachment = imageRef(block);
|
|
2049
|
+
if (attachment === void 0) return void 0;
|
|
2050
|
+
const blockValue = block;
|
|
2051
|
+
const meta = blockValue.meta ?? blockValue.resultView?.meta;
|
|
2052
|
+
return {
|
|
2053
|
+
attachment,
|
|
2054
|
+
prompt: typeof meta?.prompt === "string" ? meta.prompt : blockValue.call?.args?.prompt ?? "Generated Image",
|
|
2055
|
+
provider: typeof meta?.provider === "string" ? meta.provider : "google",
|
|
2056
|
+
model: typeof meta?.model === "string" ? meta.model : "",
|
|
2057
|
+
output: typeof meta?.output === "string" ? meta.output : "",
|
|
2058
|
+
...typeof meta?.savedTo === "string" ? { savedTo: meta.savedTo } : {}
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
1819
2061
|
function modelOf(provider, value) {
|
|
1820
2062
|
const stored = provider === "google" ? value?.googleModel : provider === "openai" ? value?.openaiModel : provider === "seedream" ? value?.seedreamModel : provider === "dashscope" ? value?.dashscopeModel : value?.comfyuiWorkflowName;
|
|
1821
2063
|
return typeof stored === "string" && stored.length > 0 ? stored : DEFAULT_MODELS[provider];
|
|
@@ -1824,20 +2066,10 @@ window.__ModuleLoader__.load({
|
|
|
1824
2066
|
const stored = provider === "google" ? value?.googleEndpoint : provider === "openai" ? value?.openaiBaseURL : provider === "seedream" ? value?.seedreamBaseURL : provider === "dashscope" ? value?.dashscopeEndpoint : value?.comfyuiBaseURL;
|
|
1825
2067
|
return typeof stored === "string" && stored.length > 0 ? stored : DEFAULT_BASE_URLS[provider];
|
|
1826
2068
|
}
|
|
1827
|
-
function imageRef(block) {
|
|
1828
|
-
if (!("kind" in block) || block.resultView?.card !== "generic") return void 0;
|
|
1829
|
-
const image = block.resultView.content?.find((item) => item.type === "image");
|
|
1830
|
-
return image?.type === "image" ? image.attachment : void 0;
|
|
1831
|
-
}
|
|
1832
|
-
/** The workspace file path a completed image call saved, when the result meta carries one. */
|
|
1833
|
-
function imageSavedTo(block) {
|
|
1834
|
-
if (!("kind" in block)) return void 0;
|
|
1835
|
-
const meta = block.meta ?? block.resultView?.meta;
|
|
1836
|
-
return typeof meta?.savedTo === "string" ? meta.savedTo : void 0;
|
|
1837
|
-
}
|
|
1838
2069
|
//#endregion
|
|
1839
2070
|
exports.GeneratedImageCard = GeneratedImageCard;
|
|
1840
2071
|
exports.ImageGenerationSettingsCard = ImageGenerationSettingsCard;
|
|
2072
|
+
exports.PromotedImageResultNode = PromotedImageResultNode;
|
|
1841
2073
|
exports.apply = apply;
|
|
1842
2074
|
exports.inject = inject;
|
|
1843
2075
|
return module.exports;
|