dsh-image-gen 0.1.1 → 0.1.3

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/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useState","_jsxs","_jsx"],"sources":["types/shared.js","types/client/index.js"],"sourcesContent":["/** Values shared by the Host and browser Bundle faces. */\n/** Browser route used by the generated-image card. */\nexport const IMAGE_ROUTE = '/plugins/dsh-image-gen/image';\n/** Namespace persisted through DSH Settings. */\nexport const IMAGE_GENERATION_NAMESPACE = 'image-generation';\n/** Supported providers. */\nexport const IMAGE_PROVIDERS = ['google', 'openai', 'seedream'];\n/** Default endpoints and base URLs. */\nexport const DEFAULT_GOOGLE_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/interactions';\nexport const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';\nexport const DEFAULT_SEEDREAM_BASE_URL = 'https://ark.cn-beijing.volces.com/api/v3';\n/** Default model names. */\nexport const DEFAULT_GOOGLE_MODEL = 'gemini-3.1-flash-image';\nexport const DEFAULT_OPENAI_MODEL = 'gpt-image-2';\nexport const DEFAULT_SEEDREAM_MODEL = 'doubao-seedream-5-0-260128';\nexport const DEFAULT_MODELS = {\n google: DEFAULT_GOOGLE_MODEL,\n openai: DEFAULT_OPENAI_MODEL,\n seedream: DEFAULT_SEEDREAM_MODEL,\n};\nexport const DEFAULT_BASE_URLS = {\n google: DEFAULT_GOOGLE_ENDPOINT,\n openai: DEFAULT_OPENAI_BASE_URL,\n seedream: DEFAULT_SEEDREAM_BASE_URL,\n};\n//# sourceMappingURL=shared.js.map","import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\n/** Web settings and generated-image cards contributed by the Bundle. */\nimport { useEffect, useState } from 'react';\nimport { DEFAULT_BASE_URLS, DEFAULT_MODELS, IMAGE_GENERATION_NAMESPACE, IMAGE_ROUTE, } from '../shared.js';\nconst KEY_REF = { google: 'GEMINI_API_KEY', openai: 'OPENAI_API_KEY', seedream: 'ARK_API_KEY' };\nconst PROVIDER_LABEL = { google: 'Google Gemini', openai: 'OpenAI / 中转站', seedream: '字节 Seedream' };\nconst STYLE = `\n.dsh-ig-card{list-style:none;border:1px solid var(--border-color,#e5e7eb);border-radius:14px;background:var(--surface-color,#fff);overflow:hidden}.dsh-ig-head{width:100%;padding:18px 20px;border:0;background:transparent;text-align:left;cursor:pointer;display:flex;justify-content:space-between;gap:16px;color:inherit}.dsh-ig-title{display:block;font-size:16px;font-weight:650}.dsh-ig-desc{display:block;margin-top:5px;color:#7b818b;font-size:14px}.dsh-ig-body{padding:0 20px 20px;border-top:1px solid var(--border-color,#eee)}.dsh-ig-field{display:grid;gap:7px;margin-top:18px}.dsh-ig-label{font-size:14px;font-weight:600}.dsh-ig-input{box-sizing:border-box;width:100%;padding:10px 12px;border:1px solid #d7dbe0;border-radius:9px;background:transparent;color:inherit}.dsh-ig-input-group{display:flex;gap:8px;align-items:center}.dsh-ig-btn-reset{padding:9px 14px;border:1px solid #d7dbe0;border-radius:9px;background:var(--surface-color,#f9fafb);color:inherit;font-size:13px;cursor:pointer;white-space:nowrap;transition:background .15s}.dsh-ig-btn-reset:hover{background:#edf0f3}.dsh-ig-hint,.dsh-ig-status{margin:0;color:#7b818b;font-size:12px}.dsh-ig-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px}.dsh-ig-save{border:0;border-radius:9px;padding:9px 16px;background:#4c78ff;color:#fff;cursor:pointer}.dsh-ig-save:disabled{opacity:.55;cursor:default}.dsh-ig-result{display:grid;gap:10px;max-width:520px}.dsh-ig-result-title{font-size:14px;font-weight:600}.dsh-ig-image{display:block;max-width:100%;max-height:520px;border-radius:14px;background:#f2f3f5}.dsh-ig-error{color:#d33;font-size:13px}.dsh-ig-loading{color:#7b818b;font-size:13px}`;\n/** Required browser services. */\nexport const inject = ['slots', 'connection', 'remote', 'settingsScope'];\n/** Mount the settings card and generated-image card. */\nexport function apply(ctx) {\n const { api } = ctx.get('connection');\n const scope = ctx.settingsScope.bind({ namespace: IMAGE_GENERATION_NAMESPACE });\n ctx.effect(() => {\n const style = document.createElement('style');\n style.dataset.plugin = 'dsh-image-gen';\n style.textContent = STYLE;\n document.head.appendChild(style);\n return () => { style.remove(); };\n }, 'dsh-image-gen: styles');\n const register = ctx.slots.register.bind(ctx.slots);\n ctx.slots.inject('settings.plugin.item', () => register({\n name: 'settings.plugin.item',\n key: IMAGE_GENERATION_NAMESPACE,\n id: IMAGE_GENERATION_NAMESPACE,\n inject: () => ({ scope, credentials: api.credentials }),\n }, ImageGenerationSettingsCard));\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({ name: 'tool.call.toolview', key: 'generate_image' }, GeneratedImageCard));\n}\n/** Edit provider settings and its write-only API credential. */\nexport function ImageGenerationSettingsCard(props) {\n const [open, setOpen] = useState(false);\n const [snapshot, setSnapshot] = useState(() => props.scope.getSnapshot());\n const [provider, setProvider] = useState('google');\n const [model, setModel] = useState('');\n const [baseURL, setBaseURL] = useState('');\n const [key, setKey] = useState('');\n const [configured, setConfigured] = useState();\n const [saving, setSaving] = useState(false);\n const [message, setMessage] = useState('');\n useEffect(() => props.scope.subscribe(() => { setSnapshot(props.scope.getSnapshot()); }), [props.scope]);\n useEffect(() => {\n const value = snapshot.value;\n const next = value?.provider ?? 'google';\n setProvider(next);\n setModel(modelOf(next, value));\n setBaseURL(baseURLOf(next, value));\n }, [snapshot]);\n useEffect(() => {\n let active = true;\n void props.credentials.describe({ refs: [KEY_REF[provider]] }).then(response => {\n if (active)\n setConfigured(response.result.ok ? response.result.value.credentials[KEY_REF[provider]]?.configured ?? false : undefined);\n }).catch(() => { if (active)\n setConfigured(undefined); });\n return () => { active = false; };\n }, [props.credentials, provider]);\n const save = async (event) => {\n event.preventDefault();\n setSaving(true);\n setMessage('');\n try {\n await props.scope.set('provider', provider);\n await props.scope.set(provider === 'google' ? 'googleModel' : provider === 'openai' ? 'openaiModel' : 'seedreamModel', model);\n await props.scope.set(provider === 'google' ? 'googleEndpoint' : provider === 'openai' ? 'openaiBaseURL' : 'seedreamBaseURL', baseURL);\n if (key.trim().length > 0) {\n const response = await props.credentials.set({ ref: KEY_REF[provider], value: key.trim() });\n if (!response.result.ok)\n throw new Error(response.result.error.message);\n setKey('');\n setConfigured(true);\n }\n setMessage('已保存');\n }\n catch (cause) {\n setMessage(cause instanceof Error ? cause.message : String(cause));\n }\n finally {\n setSaving(false);\n }\n };\n const keyStatus = configured === undefined ? '正在检查 API Key…' : configured ? '已配置 API Key' : '尚未配置 API Key';\n return _jsxs(\"li\", { className: \"dsh-ig-card\", children: [_jsxs(\"button\", { type: \"button\", className: \"dsh-ig-head\", \"aria-expanded\": open, onClick: () => { setOpen(value => !value); }, children: [_jsxs(\"span\", { children: [_jsx(\"span\", { className: \"dsh-ig-title\", children: \"\\u56FE\\u50CF\\u751F\\u6210\" }), _jsx(\"span\", { className: \"dsh-ig-desc\", children: \"\\u9009\\u62E9\\u5382\\u5546\\u5E76\\u914D\\u7F6E\\u751F\\u56FE\\u6A21\\u578B\\u3002\" })] }), _jsx(\"span\", { \"aria-hidden\": \"true\", children: open ? '⌃' : '⌄' })] }), open ? _jsxs(\"form\", { className: \"dsh-ig-body\", onSubmit: (event) => { void save(event); }, children: [_jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsx(\"span\", { className: \"dsh-ig-label\", children: \"Provider\" }), _jsxs(\"select\", { className: \"dsh-ig-input\", value: provider, onChange: event => { const next = event.target.value; setProvider(next); setModel(modelOf(next, snapshot.value)); setBaseURL(baseURLOf(next, snapshot.value)); setKey(''); }, children: [_jsx(\"option\", { value: \"google\", children: \"Google Gemini\" }), _jsx(\"option\", { value: \"openai\", children: \"OpenAI / \\u4E2D\\u8F6C\\u7AD9\" }), _jsx(\"option\", { value: \"seedream\", children: \"\\u5B57\\u8282 Seedream\" })] }), _jsx(\"span\", { className: \"dsh-ig-hint\", children: PROVIDER_LABEL[provider] })] }), _jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsxs(\"span\", { className: \"dsh-ig-label\", children: [PROVIDER_LABEL[provider], \" API Key\"] }), _jsx(\"input\", { className: \"dsh-ig-input\", type: \"password\", autoComplete: \"off\", value: key, onChange: event => { setKey(event.target.value); }, placeholder: configured ? '留空即可保留已配置的 Key' : '' }), _jsxs(\"span\", { className: \"dsh-ig-hint\", children: [\"\\u5B89\\u5168\\u4FDD\\u5B58\\u4E3A \", KEY_REF[provider], \"\\uFF1B\\u9875\\u9762\\u4E0D\\u4F1A\\u8BFB\\u56DE\\u660E\\u6587\\u3002\"] })] }), _jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsx(\"span\", { className: \"dsh-ig-label\", children: \"\\u63A5\\u53E3\\u5730\\u5740\" }), _jsxs(\"div\", { className: \"dsh-ig-input-group\", children: [_jsx(\"input\", { className: \"dsh-ig-input\", type: \"url\", value: baseURL, onChange: event => { setBaseURL(event.target.value); }, required: true }), _jsx(\"button\", { type: \"button\", className: \"dsh-ig-btn-reset\", title: \"\\u91CD\\u7F6E\\u4E3A\\u9ED8\\u8BA4\\u5B98\\u65B9\\u5730\\u5740\", onClick: () => { setBaseURL(DEFAULT_BASE_URLS[provider]); }, children: \"\\u91CD\\u7F6E\" })] }), _jsx(\"span\", { className: \"dsh-ig-hint\", children: provider === 'google' ? 'Google 官方地址或反代端点(全路径)。' : provider === 'openai' ? '中转站请填其 OpenAI 兼容的 /v1 地址。' : '火山方舟兼容的 /api/v3 地址。' })] }), _jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsx(\"span\", { className: \"dsh-ig-label\", children: \"\\u6A21\\u578B\" }), _jsx(\"input\", { className: \"dsh-ig-input\", value: model, onChange: event => { setModel(event.target.value); }, required: true })] }), _jsxs(\"div\", { className: \"dsh-ig-actions\", children: [_jsx(\"p\", { className: \"dsh-ig-status\", role: \"status\", children: message || keyStatus }), _jsx(\"button\", { className: \"dsh-ig-save\", type: \"submit\", disabled: saving || !snapshot.writable, children: saving ? '保存中…' : '保存' })] })] }) : null] });\n}\n/** Render the durable attachment referenced by a completed image tool call. */\nexport function GeneratedImageCard(props) {\n const attachment = imageRef(props.block);\n const [url, setUrl] = useState();\n const [error, setError] = useState();\n useEffect(() => {\n if (attachment === undefined)\n return;\n const controller = new AbortController();\n let objectUrl;\n void fetch(IMAGE_ROUTE, { method: 'POST', signal: controller.signal, headers: { 'content-type': 'application/json' }, body: JSON.stringify({ attachment }) }).then(async (response) => { if (!response.ok)\n throw new Error(`图片读取失败 (${String(response.status)})`); const blob = await response.blob(); if (controller.signal.aborted)\n return; objectUrl = URL.createObjectURL(blob); setUrl(objectUrl); }).catch(cause => { if (!controller.signal.aborted)\n setError(cause instanceof Error ? cause.message : String(cause)); });\n return () => { controller.abort(); if (objectUrl !== undefined)\n URL.revokeObjectURL(objectUrl); };\n }, [attachment?.attachmentId]);\n if (attachment === undefined)\n return _jsx(\"div\", { className: \"dsh-ig-loading\", children: \"\\u6B63\\u5728\\u751F\\u6210\\u56FE\\u7247\\u2026\" });\n return _jsxs(\"section\", { className: \"dsh-ig-result\", \"aria-label\": \"Generated image\", children: [_jsx(\"div\", { className: \"dsh-ig-result-title\", children: \"Generated image\" }), error !== undefined ? _jsx(\"div\", { className: \"dsh-ig-error\", children: error }) : null, url === undefined && error === undefined ? _jsx(\"div\", { className: \"dsh-ig-loading\", children: \"\\u6B63\\u5728\\u52A0\\u8F7D\\u56FE\\u7247\\u2026\" }) : null, url !== undefined ? _jsx(\"img\", { className: \"dsh-ig-image\", src: url, alt: attachment.name ?? 'Generated image' }) : null] });\n}\nfunction modelOf(provider, value) {\n const stored = provider === 'google' ? value?.googleModel : provider === 'openai' ? value?.openaiModel : value?.seedreamModel;\n return typeof stored === 'string' && stored.length > 0 ? stored : DEFAULT_MODELS[provider];\n}\nfunction baseURLOf(provider, value) {\n const stored = provider === 'google' ? value?.googleEndpoint : provider === 'openai' ? value?.openaiBaseURL : value?.seedreamBaseURL;\n return typeof stored === 'string' && stored.length > 0 ? stored : DEFAULT_BASE_URLS[provider];\n}\nfunction imageRef(block) { if (!('kind' in block) || block.resultView?.card !== 'generic')\n return undefined; const image = block.resultView.content?.find(item => item.type === 'image'); return image?.type === 'image' ? image.attachment : undefined; }\n//# sourceMappingURL=index.js.map"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useState","_jsxs","_jsx"],"sources":["types/shared.js","types/client/index.js"],"sourcesContent":["/** Values shared by the Host and browser Bundle faces. */\n/** Browser route used by the generated-image card. */\nexport const IMAGE_ROUTE = '/plugins/dsh-image-gen/image';\n/** Namespace persisted through DSH Settings. */\nexport const IMAGE_GENERATION_NAMESPACE = 'image-generation';\n/** Supported providers. */\nexport const IMAGE_PROVIDERS = ['google', 'openai', 'seedream'];\n/** Default endpoints and base URLs. */\nexport const DEFAULT_GOOGLE_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/interactions';\nexport const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';\nexport const DEFAULT_SEEDREAM_BASE_URL = 'https://ark.cn-beijing.volces.com/api/v3';\n/** Default model names. */\nexport const DEFAULT_GOOGLE_MODEL = 'gemini-3.1-flash-image';\nexport const DEFAULT_OPENAI_MODEL = 'gpt-image-2';\nexport const DEFAULT_SEEDREAM_MODEL = 'doubao-seedream-5-0-260128';\nexport const DEFAULT_MODELS = {\n google: DEFAULT_GOOGLE_MODEL,\n openai: DEFAULT_OPENAI_MODEL,\n seedream: DEFAULT_SEEDREAM_MODEL,\n};\nexport const DEFAULT_BASE_URLS = {\n google: DEFAULT_GOOGLE_ENDPOINT,\n openai: DEFAULT_OPENAI_BASE_URL,\n seedream: DEFAULT_SEEDREAM_BASE_URL,\n};\n//# sourceMappingURL=shared.js.map","import { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\n/** Web settings and generated-image cards contributed by the Bundle. */\nimport { useEffect, useState } from 'react';\nimport { DEFAULT_BASE_URLS, DEFAULT_MODELS, IMAGE_GENERATION_NAMESPACE, IMAGE_ROUTE, } from '../shared.js';\nconst KEY_REF = { google: 'GEMINI_API_KEY', openai: 'OPENAI_API_KEY', seedream: 'ARK_API_KEY' };\nconst DICT = {\n zh: {\n title: '图像生成',\n description: '选择厂商并配置生图模型。',\n provider: 'Provider',\n providerGoogle: 'Google Gemini',\n providerOpenAI: 'OpenAI / 中转站',\n providerSeedream: '字节 Seedream',\n apiKeyLabel: '{provider} API Key',\n apiKeyPlaceholder: '留空即可保留已配置的 Key',\n apiKeyHint: '安全保存为 {key};页面不会读回明文。',\n endpoint: '接口地址',\n reset: '重置',\n resetTitle: '重置为默认官方地址',\n endpointHintGoogle: 'Google 官方地址或反代端点(全路径)。',\n endpointHintOpenAI: '中转站请填其 OpenAI 兼容的 /v1 地址。',\n endpointHintSeedream: '火山方舟兼容的 /api/v3 地址。',\n model: '模型',\n saving: '保存中…',\n save: '保存',\n saved: '已保存',\n checkingKey: '正在检查 API Key…',\n keyConfigured: '已配置 API Key',\n keyNotConfigured: '尚未配置 API Key',\n generating: '正在生成图片…',\n loading: '正在加载图片…',\n loadFailed: '图片读取失败 ({status})',\n generatedTitle: 'Generated image',\n },\n en: {\n title: 'Image Generation',\n description: 'Select provider and configure image generation models.',\n provider: 'Provider',\n providerGoogle: 'Google Gemini',\n providerOpenAI: 'OpenAI / Relay',\n providerSeedream: 'ByteDance Seedream',\n apiKeyLabel: '{provider} API Key',\n apiKeyPlaceholder: 'Leave empty to keep configured key',\n apiKeyHint: 'Securely saved as {key}; never read back in plaintext.',\n endpoint: 'Endpoint / Base URL',\n reset: 'Reset',\n resetTitle: 'Reset to official default URL',\n endpointHintGoogle: 'Official Google endpoint or reverse proxy (full path).',\n endpointHintOpenAI: 'OpenAI-compatible /v1 base URL for relays.',\n endpointHintSeedream: 'Volcengine Ark compatible /api/v3 base URL.',\n model: 'Model',\n saving: 'Saving…',\n save: 'Save',\n saved: 'Saved',\n checkingKey: 'Checking API Key…',\n keyConfigured: 'API Key configured',\n keyNotConfigured: 'API Key not configured',\n generating: 'Generating image…',\n loading: 'Loading image…',\n loadFailed: 'Failed to load image ({status})',\n generatedTitle: 'Generated image',\n },\n};\nconst STYLE = `\r\n.dsh-ig-card{list-style:none;border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;background:var(--dsw-alias-bg-layer-3,#fff);transition:border-color .16s,background .16s;overflow:hidden}\r\n.dsh-ig-card:hover{border-color:var(--dsw-alias-label-dimmed,#9ca3af)}\r\n.dsh-ig-card-open{background:var(--dsw-alias-bg-layer-2,#fff);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}\r\n.dsh-ig-head{width:100%;appearance:none;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 16px;border-radius:12px}\r\n.dsh-ig-head:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#4c78ff);outline-offset:-2px}\r\n.dsh-ig-head-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}\r\n.dsh-ig-title{display:block;font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary,inherit)}\r\n.dsh-ig-desc{display:block;font-size:13px;line-height:1.5;color:var(--dsw-alias-label-tertiary,#7b818b)}\r\n.dsh-ig-chevron{flex:none;color:var(--dsw-alias-label-tertiary,#7b818b);transition:transform .16s;display:inline-flex;align-items:center}\r\n.dsh-ig-chevron-open{transform:rotate(180deg)}\r\n.dsh-ig-body{border-top:1px solid var(--dsw-alias-border-l2,#eee);padding:0 16px 16px}\r\n.dsh-ig-field{display:grid;gap:6px;margin-top:14px}\r\n.dsh-ig-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary,inherit)}\r\n.dsh-ig-input{box-sizing:border-box;width:100%;padding:8px 12px;font-size:13px;border:1px solid var(--dsw-alias-border-l2,#d7dbe0);border-radius:8px;background:var(--dsw-alias-bg-layer-3,transparent);color:inherit;outline:none;transition:border-color .15s}\r\n.dsh-ig-input:focus{border-color:var(--dsw-alias-brand-primary,#4c78ff)}\r\n.dsh-ig-input-group{display:flex;gap:8px;align-items:center}\r\n.dsh-ig-btn-reset{appearance:none;border:1px solid var(--dsw-alias-border-l2,#d7dbe0);border-radius:8px;padding:7px 12px;background:var(--dsw-alias-bg-layer-3,#f9fafb);color:var(--dsw-alias-label-secondary,inherit);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s}\r\n.dsh-ig-btn-reset:hover{background:var(--dsw-alias-bg-layer-2,#edf0f3);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}\r\n.dsh-ig-hint,.dsh-ig-status{margin:0;color:var(--dsw-alias-label-tertiary,#7b818b);font-size:12px;line-height:1.4}\r\n.dsh-ig-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2,#eee)}\r\n.dsh-ig-save{appearance:none;border:0;border-radius:8px;padding:6px 16px;background:var(--dsw-alias-label-primary,#111827);color:var(--dsw-alias-bg-layer-3,#fff);font:inherit;font-size:13px;font-weight:500;cursor:pointer;transition:opacity .15s}\r\n.dsh-ig-save:disabled{opacity:.4;cursor:default}\r\n.dsh-ig-result{display:grid;gap:10px;max-width:520px}\r\n.dsh-ig-result-title{font-size:14px;font-weight:600}\r\n.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}\r\n.dsh-ig-container:hover .dsh-ig-toolbar{opacity:1;pointer-events:auto}\r\n.dsh-ig-toolbar{position:absolute;top:8px;left:8px;display:flex;align-items:center;gap:5px;padding:3px 5px;border-radius:8px;background:rgba(0,0,0,0.65);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);opacity:0;pointer-events:none;transition:opacity .18s ease;z-index:10;line-height:1}\r\n.dsh-ig-tool-btn{appearance:none;border:0;background:transparent;color:#fff;padding:5px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .15s}\r\n.dsh-ig-tool-btn:hover{background:rgba(255,255,255,0.25)}\r\n.dsh-ig-toast{position:absolute;top:100%;left:0;margin-top:5px;padding:3px 8px;border-radius:6px;background:rgba(0,0,0,0.85);color:#fff;font-size:11px;white-space:nowrap;pointer-events:none;z-index:20}\r\n.dsh-ig-image{display:block;max-width:100%;max-height:520px;border-radius:12px;background:#f2f3f5;cursor:pointer}\r\n.dsh-ig-modal{position:fixed;inset:0;z-index:99999;background:rgba(0,0,0,0.88);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:flex;align-items:center;justify-content:center;padding:20px;box-sizing:border-box;cursor:zoom-out;animation:dsh-ig-fade .15s ease-out}\r\n@keyframes dsh-ig-fade{from{opacity:0}to{opacity:1}}\r\n.dsh-ig-modal-img{max-width:92vw;max-height:92vh;object-fit:contain;border-radius:8px;box-shadow:0 24px 60px rgba(0,0,0,0.6);user-select:none;cursor:default}\r\n.dsh-ig-error{color:var(--dsw-alias-label-error,#d33);font-size:13px}\r\n.dsh-ig-loading{color:var(--dsw-alias-label-tertiary,#7b818b);font-size:13px}`;\n/** Required browser services. */\nexport const inject = ['slots', 'connection', 'remote', 'settingsScope', 'locale'];\n/** Mount the settings card and generated-image card. */\nexport function apply(ctx) {\n const { api } = ctx.get('connection');\n const scope = ctx.settingsScope.bind({ namespace: IMAGE_GENERATION_NAMESPACE });\n const locale = ctx.get('locale');\n ctx.effect(() => {\n const style = document.createElement('style');\n style.dataset.plugin = 'dsh-image-gen';\n style.textContent = STYLE;\n document.head.appendChild(style);\n return () => { style.remove(); };\n }, 'dsh-image-gen: styles');\n const register = ctx.slots.register.bind(ctx.slots);\n ctx.slots.inject('settings.plugin.item', () => register({\n name: 'settings.plugin.item',\n key: IMAGE_GENERATION_NAMESPACE,\n id: IMAGE_GENERATION_NAMESPACE,\n order: 100,\n inject: () => ({ scope, credentials: api.credentials, locale }),\n }, ImageGenerationSettingsCard));\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({ name: 'tool.call.toolview', key: 'generate_image' }, GeneratedImageCard));\n}\n/** Edit provider settings and its write-only API credential. */\nexport function ImageGenerationSettingsCard(props) {\n const [open, setOpen] = useState(false);\n const [snapshot, setSnapshot] = useState(() => props.scope.getSnapshot());\n const [lang, setLang] = useState(() => props.locale?.getSnapshot?.()?.active ?? 'zh');\n const [provider, setProvider] = useState('google');\n const [model, setModel] = useState('');\n const [baseURL, setBaseURL] = useState('');\n const [key, setKey] = useState('');\n const [configured, setConfigured] = useState();\n const [saving, setSaving] = useState(false);\n const [message, setMessage] = useState('');\n useEffect(() => props.scope.subscribe(() => { setSnapshot(props.scope.getSnapshot()); }), [props.scope]);\n useEffect(() => {\n return props.locale?.subscribe?.(() => {\n setLang(props.locale?.getSnapshot?.()?.active ?? 'zh');\n });\n }, [props.locale]);\n const t = (keyName, params) => {\n const dict = lang === 'en' ? DICT.en : DICT.zh;\n let text = dict[keyName] || DICT.zh[keyName] || keyName;\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n text = text.replace(`{${k}}`, v);\n }\n }\n return text;\n };\n const providerLabels = {\n google: t('providerGoogle'),\n openai: t('providerOpenAI'),\n seedream: t('providerSeedream'),\n };\n useEffect(() => {\n const value = snapshot.value;\n const next = value?.provider ?? 'google';\n setProvider(next);\n setModel(modelOf(next, value));\n setBaseURL(baseURLOf(next, value));\n }, [snapshot]);\n useEffect(() => {\n let active = true;\n void props.credentials.describe({ refs: [KEY_REF[provider]] }).then(response => {\n if (active)\n setConfigured(response.result.ok ? response.result.value.credentials[KEY_REF[provider]]?.configured ?? false : undefined);\n }).catch(() => { if (active)\n setConfigured(undefined); });\n return () => { active = false; };\n }, [props.credentials, provider]);\n const save = async (event) => {\n event.preventDefault();\n setSaving(true);\n setMessage('');\n try {\n await props.scope.set('provider', provider);\n await props.scope.set(provider === 'google' ? 'googleModel' : provider === 'openai' ? 'openaiModel' : 'seedreamModel', model);\n await props.scope.set(provider === 'google' ? 'googleEndpoint' : provider === 'openai' ? 'openaiBaseURL' : 'seedreamBaseURL', baseURL);\n if (key.trim().length > 0) {\n const response = await props.credentials.set({ ref: KEY_REF[provider], value: key.trim() });\n if (!response.result.ok)\n throw new Error(response.result.error.message);\n setKey('');\n setConfigured(true);\n }\n setMessage(t('saved'));\n }\n catch (cause) {\n setMessage(cause instanceof Error ? cause.message : String(cause));\n }\n finally {\n setSaving(false);\n }\n };\n const keyStatus = configured === undefined ? t('checkingKey') : configured ? t('keyConfigured') : t('keyNotConfigured');\n return _jsxs(\"li\", { className: `dsh-ig-card ${open ? 'dsh-ig-card-open' : ''}`, children: [_jsxs(\"button\", { type: \"button\", className: \"dsh-ig-head\", \"aria-expanded\": open, onClick: () => { setOpen(value => !value); }, children: [_jsxs(\"span\", { className: \"dsh-ig-head-text\", children: [_jsx(\"span\", { className: \"dsh-ig-title\", children: t('title') }), _jsx(\"span\", { className: \"dsh-ig-desc\", children: t('description') })] }), _jsx(\"span\", { className: `dsh-ig-chevron ${open ? 'dsh-ig-chevron-open' : ''}`, \"aria-hidden\": \"true\", children: _jsx(\"svg\", { width: \"14\", height: \"14\", viewBox: \"0 0 16 16\", fill: \"none\", stroke: \"currentColor\", strokeWidth: \"2\", strokeLinecap: \"round\", strokeLinejoin: \"round\", children: _jsx(\"path\", { d: \"M4 6l4 4 4-4\" }) }) })] }), open ? _jsxs(\"form\", { className: \"dsh-ig-body\", onSubmit: (event) => { void save(event); }, children: [_jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsx(\"span\", { className: \"dsh-ig-label\", children: t('provider') }), _jsxs(\"select\", { className: \"dsh-ig-input\", value: provider, onChange: event => { const next = event.target.value; setProvider(next); setModel(modelOf(next, snapshot.value)); setBaseURL(baseURLOf(next, snapshot.value)); setKey(''); }, children: [_jsx(\"option\", { value: \"google\", children: t('providerGoogle') }), _jsx(\"option\", { value: \"openai\", children: t('providerOpenAI') }), _jsx(\"option\", { value: \"seedream\", children: t('providerSeedream') })] }), _jsx(\"span\", { className: \"dsh-ig-hint\", children: providerLabels[provider] })] }), _jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsx(\"span\", { className: \"dsh-ig-label\", children: t('apiKeyLabel', { provider: providerLabels[provider] }) }), _jsx(\"input\", { className: \"dsh-ig-input\", type: \"password\", autoComplete: \"off\", value: key, onChange: event => { setKey(event.target.value); }, placeholder: configured ? t('apiKeyPlaceholder') : '' }), _jsx(\"span\", { className: \"dsh-ig-hint\", children: t('apiKeyHint', { key: KEY_REF[provider] }) })] }), _jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsx(\"span\", { className: \"dsh-ig-label\", children: t('endpoint') }), _jsxs(\"div\", { className: \"dsh-ig-input-group\", children: [_jsx(\"input\", { className: \"dsh-ig-input\", type: \"url\", value: baseURL, onChange: event => { setBaseURL(event.target.value); }, required: true }), _jsx(\"button\", { type: \"button\", className: \"dsh-ig-btn-reset\", title: t('resetTitle'), onClick: () => { setBaseURL(DEFAULT_BASE_URLS[provider]); }, children: t('reset') })] }), _jsx(\"span\", { className: \"dsh-ig-hint\", children: provider === 'google' ? t('endpointHintGoogle') : provider === 'openai' ? t('endpointHintOpenAI') : t('endpointHintSeedream') })] }), _jsxs(\"label\", { className: \"dsh-ig-field\", children: [_jsx(\"span\", { className: \"dsh-ig-label\", children: t('model') }), _jsx(\"input\", { className: \"dsh-ig-input\", value: model, onChange: event => { setModel(event.target.value); }, required: true })] }), _jsxs(\"div\", { className: \"dsh-ig-actions\", children: [_jsx(\"p\", { className: \"dsh-ig-status\", role: \"status\", children: message || keyStatus }), _jsx(\"button\", { className: \"dsh-ig-save\", type: \"submit\", disabled: saving || !snapshot.writable, children: saving ? t('saving') : t('save') })] })] }) : null] });\n}\n/** Render the durable attachment referenced by a completed image tool call. */\nexport function GeneratedImageCard(props) {\n const attachment = imageRef(props.block);\n const [url, setUrl] = useState();\n const [blob, setBlob] = useState();\n const [error, setError] = useState();\n const [previewOpen, setPreviewOpen] = useState(false);\n const [toast, setToast] = useState();\n useEffect(() => {\n if (!previewOpen)\n return;\n const onKeyDown = (e) => {\n if (e.key === 'Escape')\n setPreviewOpen(false);\n };\n window.addEventListener('keydown', onKeyDown);\n return () => { window.removeEventListener('keydown', onKeyDown); };\n }, [previewOpen]);\n useEffect(() => {\n if (attachment === undefined)\n return;\n const controller = new AbortController();\n let objectUrl;\n void fetch(IMAGE_ROUTE, {\n method: 'POST',\n signal: controller.signal,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ attachment }),\n }).then(async (response) => {\n if (!response.ok)\n throw new Error(`图片读取失败 (${String(response.status)})`);\n const resBlob = await response.blob();\n if (controller.signal.aborted)\n return;\n setBlob(resBlob);\n objectUrl = URL.createObjectURL(resBlob);\n setUrl(objectUrl);\n }).catch(cause => {\n if (!controller.signal.aborted)\n setError(cause instanceof Error ? cause.message : String(cause));\n });\n return () => {\n controller.abort();\n if (objectUrl !== undefined)\n URL.revokeObjectURL(objectUrl);\n };\n }, [attachment?.attachmentId]);\n const copy = async (e) => {\n e.stopPropagation();\n if (!blob)\n return;\n const ok = await copyImageBlob(blob);\n setToast(ok ? '已复制图片' : '复制失败');\n setTimeout(() => { setToast(undefined); }, 2000);\n };\n const download = (e) => {\n e.stopPropagation();\n if (!url)\n return;\n const a = document.createElement('a');\n a.href = url;\n a.download = attachment?.name || `dsh-image-${Date.now()}.png`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n };\n const openNewTab = (e) => {\n e.stopPropagation();\n if (!url)\n return;\n window.open(url, '_blank', 'noopener,noreferrer');\n };\n if (attachment === undefined)\n return _jsx(\"div\", { className: \"dsh-ig-loading\", children: \"\\u6B63\\u5728\\u751F\\u6210\\u56FE\\u7247\\u2026\" });\n return _jsxs(\"section\", { className: \"dsh-ig-result\", \"aria-label\": \"Generated image\", children: [_jsx(\"div\", { className: \"dsh-ig-result-title\", children: \"Generated image\" }), error !== undefined ? _jsx(\"div\", { className: \"dsh-ig-error\", children: error }) : null, url === undefined && error === undefined ? _jsx(\"div\", { className: \"dsh-ig-loading\", children: \"\\u6B63\\u5728\\u52A0\\u8F7D\\u56FE\\u7247\\u2026\" }) : null, url !== undefined ? _jsxs(\"div\", { className: \"dsh-ig-container\", children: [_jsx(\"img\", { className: \"dsh-ig-image\", src: url, alt: attachment.name ?? 'Generated image', onClick: () => { setPreviewOpen(true); } }), _jsxs(\"div\", { className: \"dsh-ig-toolbar\", children: [_jsx(\"button\", { type: \"button\", className: \"dsh-ig-tool-btn\", title: \"\\u590D\\u5236\\u56FE\\u7247\", onClick: (e) => { void copy(e); }, children: _jsxs(\"svg\", { width: \"15\", height: \"15\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", strokeWidth: \"2\", strokeLinecap: \"round\", strokeLinejoin: \"round\", children: [_jsx(\"rect\", { x: \"9\", y: \"9\", width: \"13\", height: \"13\", rx: \"2\", ry: \"2\" }), _jsx(\"path\", { d: \"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" })] }) }), _jsx(\"button\", { type: \"button\", className: \"dsh-ig-tool-btn\", title: \"\\u4E0B\\u8F7D\\u56FE\\u7247\", onClick: download, children: _jsxs(\"svg\", { width: \"15\", height: \"15\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", strokeWidth: \"2\", strokeLinecap: \"round\", strokeLinejoin: \"round\", children: [_jsx(\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" }), _jsx(\"polyline\", { points: \"7 10 12 15 17 10\" }), _jsx(\"line\", { x1: \"12\", y1: \"15\", x2: \"12\", y2: \"3\" })] }) }), _jsx(\"button\", { type: \"button\", className: \"dsh-ig-tool-btn\", title: \"\\u65B0\\u6807\\u7B7E\\u9875\\u6253\\u5F00\", onClick: openNewTab, children: _jsxs(\"svg\", { width: \"15\", height: \"15\", viewBox: \"0 0 24 24\", fill: \"none\", stroke: \"currentColor\", strokeWidth: \"2\", strokeLinecap: \"round\", strokeLinejoin: \"round\", children: [_jsx(\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" }), _jsx(\"polyline\", { points: \"15 3 21 3 21 9\" }), _jsx(\"line\", { x1: \"10\", y1: \"14\", x2: \"21\", y2: \"3\" })] }) }), toast ? _jsx(\"div\", { className: \"dsh-ig-toast\", children: toast }) : null] })] }) : null, previewOpen && url !== undefined ? _jsx(\"div\", { className: \"dsh-ig-modal\", onClick: () => { setPreviewOpen(false); }, children: _jsx(\"img\", { className: \"dsh-ig-modal-img\", src: url, alt: attachment.name ?? 'Generated image preview', onClick: (e) => { e.stopPropagation(); } }) }) : null] });\n}\nasync function copyImageBlob(blob) {\n try {\n if (blob.type === 'image/png') {\n await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]);\n return true;\n }\n const img = new Image();\n const url = URL.createObjectURL(blob);\n await new Promise((resolve, reject) => {\n img.onload = resolve;\n img.onerror = reject;\n img.src = url;\n });\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d');\n if (!ctx)\n throw new Error('Canvas unavailable');\n ctx.drawImage(img, 0, 0);\n URL.revokeObjectURL(url);\n const pngBlob = await new Promise(res => { canvas.toBlob(res, 'image/png'); });\n if (!pngBlob)\n throw new Error('Blob conversion failed');\n await navigator.clipboard.write([new ClipboardItem({ 'image/png': pngBlob })]);\n return true;\n }\n catch (_err) {\n return false;\n }\n}\nfunction modelOf(provider, value) {\n const stored = provider === 'google' ? value?.googleModel : provider === 'openai' ? value?.openaiModel : value?.seedreamModel;\n return typeof stored === 'string' && stored.length > 0 ? stored : DEFAULT_MODELS[provider];\n}\nfunction baseURLOf(provider, value) {\n const stored = provider === 'google' ? value?.googleEndpoint : provider === 'openai' ? value?.openaiBaseURL : value?.seedreamBaseURL;\n return typeof stored === 'string' && stored.length > 0 ? stored : DEFAULT_BASE_URLS[provider];\n}\nfunction imageRef(block) { if (!('kind' in block) || block.resultView?.card !== 'generic')\n return undefined; const image = block.resultView.content?.find(item => item.type === 'image'); return image?.type === 'image' ? image.attachment : undefined; }\n//# sourceMappingURL=index.js.map"],"mappings":"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"}
@@ -13,9 +13,16 @@ interface ImageSettings {
13
13
  seedreamBaseURL?: string;
14
14
  seedreamModel?: string;
15
15
  }
16
+ interface LocaleService {
17
+ getSnapshot(): {
18
+ active: string;
19
+ };
20
+ subscribe(fn: () => void): () => void;
21
+ }
16
22
  interface SettingsFace {
17
23
  scope: SettingsScope<ImageSettings>;
18
24
  credentials: ConnectionHandle['api']['credentials'];
25
+ locale?: LocaleService | undefined;
19
26
  }
20
27
  type SettingsCardProps = PropsRuntime<'settings.plugin.item'> & InjectFace<SettingsFace>;
21
28
  type ImageCardProps = PropsRuntime<'tool.call.toolview'>;
package/package.json CHANGED
@@ -1,122 +1,124 @@
1
- {
2
- "name": "dsh-image-gen",
3
- "version": "0.1.1",
4
- "description": "Bring ChatGPT-like image generation to DeepSeek Harness — Gemini, OpenAI, Seedream & more.",
5
- "type": "module",
6
- "author": "shanliuling",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/shanliuling/dsh-image-gen.git"
10
- },
11
- "bugs": {
12
- "url": "https://github.com/shanliuling/dsh-image-gen/issues"
13
- },
14
- "homepage": "https://github.com/shanliuling/dsh-image-gen#readme",
15
- "main": "lib/index.js",
16
- "types": "lib/types/index.d.ts",
17
- "exports": {
18
- ".": {
19
- "types": "./lib/types/index.d.ts",
20
- "default": "./lib/index.js"
21
- },
22
- "./client": {
23
- "types": "./lib/types/client/index.d.ts",
24
- "default": "./lib/client.js"
25
- },
26
- "./package.json": "./package.json"
27
- },
28
- "files": [
29
- "lib/index.js",
30
- "lib/client.js",
31
- "lib/client.js.map",
32
- "lib/types/**/*.d.ts",
33
- "skills/**/*.md",
34
- "cordis.patch.yml",
35
- "README.md",
36
- "README.zh-CN.md",
37
- "README.en.md",
38
- "LICENSE"
39
- ],
40
- "dsh": {
41
- "bundle": {
42
- "patch": "./cordis.patch.yml"
43
- },
44
- "client": {
45
- "inject": [
46
- "@deepseek-ai/dsh-client-connection",
47
- "@deepseek-ai/dsh-api-remotes",
48
- "@deepseek-ai/dsh-client-runtime",
49
- "@deepseek-ai/dsh-client-ui-settings",
50
- "@deepseek-ai/dsh-client-ui-settings-plugins",
51
- "@deepseek-ai/dsh-client-ui-tool"
52
- ],
53
- "platform": "web"
54
- }
55
- },
56
- "engines": {
57
- "node": "^22.19.0 || >=24.0.0"
58
- },
59
- "license": "MIT",
60
- "keywords": [
61
- "deepseek",
62
- "deepseek-harness",
63
- "dsh",
64
- "dsh-plugin",
65
- "ai-agent",
66
- "image-generation",
67
- "ai-image-generation",
68
- "multimodal",
69
- "gemini",
70
- "openai",
71
- "openai-compatible",
72
- "seedream",
73
- "volcengine",
74
- "byok",
75
- "cordis"
76
- ],
77
- "peerDependencies": {
78
- "@deepseek-ai/cordis": ">=4.0.0 <5",
79
- "@deepseek-ai/dsh-attachment": ">=0.1.0-rc.5 <0.2.0",
80
- "@deepseek-ai/dsh-api-remotes": ">=0.1.0-rc.5 <0.2.0",
81
- "@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.5 <0.2.0",
82
- "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.5 <0.2.0",
83
- "@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.5 <0.2.0",
84
- "@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.0-rc.5 <0.2.0",
85
- "@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.5 <0.2.0",
86
- "@deepseek-ai/dsh-client-ui-tool": ">=0.1.0-rc.5 <0.2.0",
87
- "@deepseek-ai/dsh-credentials": ">=0.1.0-rc.5 <0.2.0",
88
- "@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.5 <0.2.0",
89
- "@deepseek-ai/dsh-settings": ">=0.1.0-rc.5 <0.2.0",
90
- "@deepseek-ai/dsh-tools": ">=0.1.0-rc.5 <0.2.0",
91
- "@deepseek-ai/schemastery": ">=3.18.0 <4",
92
- "react": ">=18.2.0 <19"
93
- },
94
- "devDependencies": {
95
- "@deepseek-ai/cordis": "4.0.1",
96
- "@deepseek-ai/dsh-attachment": "0.1.0-rc.6",
97
- "@deepseek-ai/dsh-api-remotes": "0.1.0-rc.6",
98
- "@deepseek-ai/dsh-client-connection": "0.1.0-rc.6",
99
- "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
100
- "@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6",
101
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.0-rc.6",
102
- "@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
103
- "@deepseek-ai/dsh-client-ui-tool": "0.1.0-rc.6",
104
- "@deepseek-ai/dsh-credentials": "0.1.0-rc.6",
105
- "@deepseek-ai/dsh-host-webserver": "0.1.0-rc.6",
106
- "@deepseek-ai/dsh-settings": "0.1.0-rc.6",
107
- "@deepseek-ai/dsh-tools": "0.1.0-rc.6",
108
- "@deepseek-ai/schemastery": "3.18.1",
109
- "@types/node": "^22.20.0",
110
- "@types/react": "~18.3.1",
111
- "react": "^18.2.0",
112
- "tsdown": "^0.22.2",
113
- "typescript": "^6.0.3",
114
- "vitest": "^4.1.8"
115
- },
116
- "scripts": {
117
- "typecheck": "tsc --noEmit",
118
- "build": "tsc && tsdown",
119
- "test": "vitest run",
120
- "pack:check": "pnpm pack --dry-run"
121
- }
122
- }
1
+ {
2
+ "name": "dsh-image-gen",
3
+ "version": "0.1.3",
4
+ "description": "Bring ChatGPT-like image generation to DeepSeek Harness — Gemini, OpenAI, Seedream & more.",
5
+ "type": "module",
6
+ "author": "shanliuling",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/shanliuling/dsh-image-gen.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/shanliuling/dsh-image-gen/issues"
13
+ },
14
+ "homepage": "https://github.com/shanliuling/dsh-image-gen#readme",
15
+ "main": "lib/index.js",
16
+ "types": "lib/types/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./lib/types/index.d.ts",
20
+ "default": "./lib/index.js"
21
+ },
22
+ "./client": {
23
+ "types": "./lib/types/client/index.d.ts",
24
+ "default": "./lib/client.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "lib/index.js",
30
+ "lib/client.js",
31
+ "lib/client.js.map",
32
+ "lib/types/**/*.d.ts",
33
+ "skills/**/*.md",
34
+ "cordis.patch.yml",
35
+ "README.md",
36
+ "README.zh-CN.md",
37
+ "LICENSE"
38
+ ],
39
+ "dsh": {
40
+ "bundle": {
41
+ "patch": "./cordis.patch.yml"
42
+ },
43
+ "client": {
44
+ "inject": [
45
+ "@deepseek-ai/dsh-client-connection",
46
+ "@deepseek-ai/dsh-api-remotes",
47
+ "@deepseek-ai/dsh-client-runtime",
48
+ "@deepseek-ai/dsh-client-ui-settings",
49
+ "@deepseek-ai/dsh-client-ui-settings-plugins",
50
+ "@deepseek-ai/dsh-client-ui-tool",
51
+ "@deepseek-ai/dsh-client-locale"
52
+ ],
53
+ "platform": "web"
54
+ }
55
+ },
56
+ "scripts": {
57
+ "typecheck": "tsc --noEmit",
58
+ "build": "tsc && tsdown",
59
+ "prepare": "pnpm run build",
60
+ "test": "vitest run",
61
+ "pack:check": "pnpm pack --dry-run"
62
+ },
63
+ "engines": {
64
+ "node": "^22.19.0 || >=24.0.0"
65
+ },
66
+ "license": "MIT",
67
+ "keywords": [
68
+ "deepseek",
69
+ "deepseek-harness",
70
+ "dsh",
71
+ "dsh-plugin",
72
+ "ai-agent",
73
+ "image-generation",
74
+ "ai-image-generation",
75
+ "multimodal",
76
+ "gemini",
77
+ "openai",
78
+ "openai-compatible",
79
+ "seedream",
80
+ "volcengine",
81
+ "byok",
82
+ "cordis"
83
+ ],
84
+ "peerDependencies": {
85
+ "@deepseek-ai/cordis": ">=4.0.0 <5",
86
+ "@deepseek-ai/dsh-attachment": ">=0.1.0-rc.5 <0.2.0",
87
+ "@deepseek-ai/dsh-api-remotes": ">=0.1.0-rc.5 <0.2.0",
88
+ "@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.5 <0.2.0",
89
+ "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.5 <0.2.0",
90
+ "@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.5 <0.2.0",
91
+ "@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.0-rc.5 <0.2.0",
92
+ "@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.5 <0.2.0",
93
+ "@deepseek-ai/dsh-client-ui-tool": ">=0.1.0-rc.5 <0.2.0",
94
+ "@deepseek-ai/dsh-credentials": ">=0.1.0-rc.5 <0.2.0",
95
+ "@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.5 <0.2.0",
96
+ "@deepseek-ai/dsh-settings": ">=0.1.0-rc.5 <0.2.0",
97
+ "@deepseek-ai/dsh-tools": ">=0.1.0-rc.5 <0.2.0",
98
+ "@deepseek-ai/schemastery": ">=3.18.0 <4",
99
+ "react": ">=18.2.0 <19"
100
+ },
101
+ "devDependencies": {
102
+ "@deepseek-ai/cordis": "4.0.1",
103
+ "@deepseek-ai/dsh-attachment": "0.1.0-rc.6",
104
+ "@deepseek-ai/dsh-api-remotes": "0.1.0-rc.6",
105
+ "@deepseek-ai/dsh-client-connection": "0.1.0-rc.6",
106
+ "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
107
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6",
108
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.0-rc.6",
109
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
110
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.0-rc.6",
111
+ "@deepseek-ai/dsh-credentials": "0.1.0-rc.6",
112
+ "@deepseek-ai/dsh-host-webserver": "0.1.0-rc.6",
113
+ "@deepseek-ai/dsh-settings": "0.1.0-rc.6",
114
+ "@deepseek-ai/dsh-tools": "0.1.0-rc.6",
115
+ "@deepseek-ai/schemastery": "3.18.1",
116
+ "@types/node": "^22.20.0",
117
+ "@types/react": "~18.3.1",
118
+ "react": "^18.2.0",
119
+ "tsdown": "^0.22.2",
120
+ "typescript": "^6.0.3",
121
+ "vitest": "^4.1.8"
122
+ },
123
+ "packageManager": "pnpm@11.7.0"
124
+ }
package/README.en.md DELETED
@@ -1,158 +0,0 @@
1
- <div align="center">
2
-
3
- # 🎨 dsh-image-gen
4
-
5
- ### Native Image Generation Plugin for DeepSeek Harness (DSH)
6
-
7
- **Bring ChatGPT-like image generation into DeepSeek Harness conversation flows.**
8
-
9
- Supports Google Gemini, OpenAI Images, OpenAI Compatible APIs, ByteDance Seedream / Volcengine Ark.
10
-
11
- [![npm version](https://img.shields.io/npm/v/dsh-image-gen.svg?style=flat-square&color=blue)](https://www.npmjs.com/package/dsh-image-gen)
12
- [![DSH Plugin](https://img.shields.io/badge/Plugin%20For-DeepSeek%20Harness-6366f1?style=flat-square)](https://github.com/deepseek-ai)
13
- [![npm downloads](https://img.shields.io/npm/dm/dsh-image-gen.svg?style=flat-square&color=emerald)](https://www.npmjs.com/package/dsh-image-gen)
14
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE)
15
-
16
- **English** | [简体中文](README.md)
17
-
18
- <br />
19
-
20
- <p align="center">💬 <b>Just prompt your DeepSeek Harness Agent:</b></p>
21
-
22
- ```text
23
- Install the image generation plugin by running: pnpm dsh plugin --profile web add dsh-image-gen
24
- ```
25
-
26
- <p align="center"><sub>(Or run manually in terminal: <code>pnpm dsh plugin --profile web add dsh-image-gen</code>)</sub></p>
27
-
28
- <br />
29
-
30
- <p align="center">Once installed, configure your API Key in DSH Settings and prompt your Agent:</p>
31
-
32
- ```text
33
- Create an illustration of a cyberpunk cat in a neon rainy street.
34
- ```
35
-
36
- <p align="center">The Agent will automatically invoke <code>generate_image</code> and render the generated image directly in the conversation flow.</p>
37
-
38
- <br />
39
-
40
- <img src="docs/assets/chat-preview.png" alt="Conversational image generation preview" width="820" />
41
-
42
- </div>
43
-
44
- ---
45
-
46
- ## 💡 What Problem Does It Solve?
47
-
48
- **`dsh-image-gen` is an open-source multimodal image generation bundle built specifically for DeepSeek Harness (DSH).**
49
-
50
- DeepSeek Harness already lets Agents dispatch tools to accomplish complex tasks; this plugin equips DSH with native **multimodal image generation capabilities**:
51
-
52
- ```mermaid
53
- graph LR
54
- A[User Prompt] --> B[DeepSeek Harness Agent]
55
- B --> C[generate_image Tool]
56
- C --> D[Gemini / OpenAI / Seedream]
57
- D --> E[Image Payload]
58
- E --> F[Conversation Stream]
59
- ```
60
-
61
- ---
62
-
63
- ## 🚀 Quick Start
64
-
65
- ### 1. Install Plugin
66
-
67
- Run the following command in your DeepSeek Harness workspace root:
68
-
69
- ```bash
70
- # Recommended: Install and register plugin via pnpm
71
- pnpm dsh plugin --profile web add dsh-image-gen
72
-
73
- # If dsh is installed globally:
74
- dsh plugin --profile web add dsh-image-gen
75
- ```
76
-
77
- <details>
78
- <summary><b>🛠️ Advanced Installation (Git Repository / Local Dev)</b></summary>
79
-
80
- ```bash
81
- # Option B: Direct install from GitHub repo
82
- pnpm dsh plugin --profile web add git+https://github.com/shanliuling/dsh-image-gen.git
83
-
84
- # Option C: Local clone for development
85
- git clone https://github.com/shanliuling/dsh-image-gen.git
86
- pnpm dsh plugin --profile web add ./dsh-image-gen
87
- ```
88
-
89
- </details>
90
-
91
- ### 2. Configure API Key
92
-
93
- Open DSH Web UI (default `http://localhost:3080`):
94
-
95
- 1. Go to **Settings → Plugins → Image generation**.
96
- 2. Select your Provider, enter your API Key, and click **Save**.
97
-
98
- <div align="center">
99
- <img src="docs/assets/settings-preview.png" alt="Settings Card Preview" width="720" />
100
- </div>
101
-
102
- ### 3. Start Generating Images in Chat
103
-
104
- Simply prompt in the chat input:
105
-
106
- ```text
107
- Generate a minimalist illustration of a modern architectural living room.
108
- ```
109
-
110
- The Agent will automatically invoke `generate_image` and render the result in the conversation.
111
-
112
- ---
113
-
114
- ## ✨ Key Features
115
-
116
- - 💬 **In-Conversation Image Generation**: No need to switch between external websites or manually copy prompts; ask your Agent naturally.
117
- - 🎨 **Multi-Provider Support**: Out-of-the-box support for Google Gemini, OpenAI Images, OpenAI Compatible APIs (OneAPI, NewAPI), and ByteDance Seedream / Volcengine Ark. Models and endpoints can be customized directly in the settings UI.
118
- - 🔑 **BYOK (Bring Your Own Key)**: Uses your own API credentials securely managed through DSH's write-isolated `credentials` service. Keys are never saved in plain text on the frontend.
119
- - 🖼️ **Durable Session Attachments**: Images are attached to DSH's native Attachment / Conversation system and remain visible when returning to historical sessions.
120
- - ⚙️ **Native Settings UI**: Change providers, API keys, models, and endpoints directly inside the DSH Web UI without manual config file editing.
121
-
122
- ---
123
-
124
- ## 📦 Supported Providers
125
-
126
- | Provider | Default Model | Default Endpoint / Base URL |
127
- | :--- | :--- | :--- |
128
- | **Google Gemini** | `gemini-3.1-flash-image` | `https://generativelanguage.googleapis.com/v1beta/interactions` |
129
- | **OpenAI Images** | `gpt-image-2` | `https://api.openai.com/v1` |
130
- | **OpenAI Compatible** | Custom | Custom Base URL |
131
- | **ByteDance Seedream / Volcengine** | `doubao-seedream-5-0-260128` | `https://ark.cn-beijing.volces.com/api/v3` |
132
-
133
- ---
134
-
135
- ## 🛠️ Development
136
-
137
- ```bash
138
- # Clone repository
139
- git clone https://github.com/shanliuling/dsh-image-gen.git
140
- cd dsh-image-gen
141
-
142
- # Install dependencies and build
143
- pnpm install
144
- pnpm run typecheck
145
- pnpm run test
146
- pnpm run build
147
-
148
- # Check package payload
149
- pnpm run pack:check
150
- ```
151
-
152
- ---
153
-
154
- ## 📄 License
155
-
156
- This project is licensed under the [MIT License](LICENSE).
157
-
158
- If this plugin helps you, consider giving it a ⭐️ **Star**!