dsh-image-gen 0.1.0 → 0.1.2

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.md CHANGED
@@ -1,85 +1,158 @@
1
- # dsh-image-gen
2
-
3
- English | [简体中文](README.zh-CN.md)
4
-
5
- `dsh-image-gen` is an installable DeepSeek Harness (DSH) Bundle that contributes a native `generate_image` tool and renders durable image result cards directly in Web conversations.
6
-
7
- ![Chat Preview](docs/assets/chat-preview.png)
8
-
9
- ---
10
-
11
- ## ✨ Features
12
-
13
- - **Multi-Provider Support**: Seamless integration with **Google Gemini**, **OpenAI / OpenAI-compatible relays**, and **ByteDance Seedream (Volcengine Ark)**.
14
- - **Secure Credential Management**: Write-only API Key storage powered by DSH `credentials` service. Keys are never logged or exposed in plaintext.
15
- - **Web Settings Integration**: Built-in settings card in DSH Settings with auto-filled defaults and one-click endpoint reset.
16
- - **Durable Media Persistence**: Generated images are automatically saved to DSH conversation attachment storage and rendered in rich UI cards.
17
-
18
- ![Settings Preview](docs/assets/settings-preview.png)
19
-
20
- ---
21
-
22
- ## 📦 Supported Providers
23
-
24
- | Provider | Credential Key | Default Model | Default Endpoint / Base URL | Note |
25
- | :--- | :--- | :--- | :--- | :--- |
26
- | **Google Gemini** | `GEMINI_API_KEY` | `gemini-3.1-flash-image` | `https://generativelanguage.googleapis.com/v1beta/interactions` | Native Gemini Interactions API |
27
- | **OpenAI / Relay** | `OPENAI_API_KEY` | `gpt-image-2` | `https://api.openai.com/v1` | Standard OpenAI / OneAPI / NewAPI |
28
- | **ByteDance Seedream** | `ARK_API_KEY` | `doubao-seedream-5-0-260128` | `https://ark.cn-beijing.volces.com/api/v3` | Volcengine Ark Doubao T2I |
29
-
30
- ---
31
-
32
- ## 🚀 Installation & Usage
33
-
34
- ### 1. Install Plugin
35
-
36
- In your DeepSeek Harness workspace, add the plugin to your profile (default `web`):
37
-
38
- ```bash
39
- # Install via npm (when published)
40
- dsh plugin --profile web add dsh-image-gen
41
-
42
- # Or install from local path (development)
43
- dsh plugin --profile web add /path/to/dsh-image-gen
44
- ```
45
-
46
- ### 2. Configure in Web UI
47
-
48
- 1. Open DSH Web UI (e.g. `http://localhost:3080`).
49
- 2. Navigate to **Settings → Plugins → Image generation (图像生成)**.
50
- 3. Select your provider, enter the API Key, verify or customize endpoint / model, and click **Save**.
51
-
52
- ### 3. Generate Images
53
-
54
- Start a conversation and ask the agent naturally:
55
- > *"Generate a realistic picture of a Holstein cow in a green meadow with wildflowers under golden sunlight."*
56
-
57
- The model will automatically invoke `generate_image`, fetch the image, and render it inline.
58
-
59
- ---
60
-
61
- ## 🛠️ Development
62
-
63
- ```bash
64
- # Install dependencies
65
- pnpm install
66
-
67
- # Typecheck
68
- pnpm run typecheck
69
-
70
- # Run unit tests
71
- pnpm run test
72
-
73
- # Build host and client bundles
74
- pnpm run build
75
-
76
- # Verify packaging
77
- pnpm run pack:check
78
- ```
79
-
80
- ---
81
-
82
- ## 📄 License
83
-
84
- [MIT](LICENSE)
85
-
1
+ <div align="center">
2
+
3
+ # 🎨 dsh-image-gen
4
+
5
+ ### DeepSeek Harness (DSH) 原生生图插件
6
+
7
+ **让 DeepSeek Harness 像 ChatGPT 一样,在对话里直接生成图片。**
8
+
9
+ 支持 Google Gemini、OpenAI Images、OpenAI Compatible API、字节 Seedream / 火山方舟。
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.en.md) | **简体中文**
17
+
18
+ <br />
19
+
20
+ <p align="center">💬 <b>直接对你的 DeepSeek Harness Agent 发送以下提示词:</b></p>
21
+
22
+ ```text
23
+ 帮我安装生图插件,执行命令:pnpm dsh plugin --profile web add dsh-image-gen
24
+ ```
25
+
26
+ <p align="center"><sub>(也可以手动在终端执行:<code>pnpm dsh plugin --profile web add dsh-image-gen</code>)</sub></p>
27
+
28
+ <br />
29
+
30
+ <p align="center">安装完成后,在 DSH 设置中填入自己的 API Key,就可以直接对 Agent 说:</p>
31
+
32
+ ```text
33
+ 帮我画一张雨夜霓虹街头的赛博朋克猫咪。
34
+ ```
35
+
36
+ <p align="center">Agent 会自动调用 <code>generate_image</code>,生成图片并直接显示在当前对话中。</p>
37
+
38
+ <br />
39
+
40
+ <img src="docs/assets/chat-preview.png" alt="对话生图效果预览" width="820" />
41
+
42
+ </div>
43
+
44
+ ---
45
+
46
+ ## 💡 它解决什么问题?
47
+
48
+ **`dsh-image-gen` 是专为 DeepSeek Harness (DSH) 打造的开源图像生成插件。**
49
+
50
+ DeepSeek Harness 已经可以让 Agent 调用不同工具完成任务,本项目为它补上了原生的**多模态生图能力**:
51
+
52
+ ```mermaid
53
+ graph LR
54
+ A[用户 Prompt] --> B[DeepSeek Harness Agent]
55
+ B --> C[generate_image 工具]
56
+ C --> D[Gemini / OpenAI / Seedream]
57
+ D --> E[图片数据]
58
+ E --> F[当前 Conversation 对话流]
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 🚀 快速安装与使用
64
+
65
+ ### 1. 安装插件
66
+
67
+ 在你的 DeepSeek Harness 项目根目录下运行:
68
+
69
+ ```bash
70
+ # 推荐方式:通过 pnpm 一键安装并注册插件
71
+ pnpm dsh plugin --profile web add dsh-image-gen
72
+
73
+ # 若已将 dsh 安装为系统全局命令:
74
+ dsh plugin --profile web add dsh-image-gen
75
+ ```
76
+
77
+ <details>
78
+ <summary><b>🛠️ 其他安装方式(Git 仓库直装 / 本地调试)</b></summary>
79
+
80
+ ```bash
81
+ # 方式 B:从 GitHub 仓库直接安装最新代码
82
+ pnpm dsh plugin --profile web add git+https://github.com/shanliuling/dsh-image-gen.git
83
+
84
+ # 方式 C:本地克隆源码开发安装
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. 配置 API Key
92
+
93
+ 打开 DSH Web 页面(默认 `http://localhost:3080`):
94
+
95
+ 1. 进入 **Settings → Plugins → Image generation**。
96
+ 2. 选择 Provider,填写 API Key,点击 **保存** 即可。
97
+
98
+ <div align="center">
99
+ <img src="docs/assets/settings-preview.png" alt="设置面板预览" width="720" />
100
+ </div>
101
+
102
+ ### 3. 开始对话生图
103
+
104
+ 现在直接在聊天框输入:
105
+
106
+ ```text
107
+ 生成一张极简主义的现代建筑客厅插画。
108
+ ```
109
+
110
+ 当前 Agent 就会自动调用 `generate_image` 工具并在对话流中返回图片。
111
+
112
+ ---
113
+
114
+ ## ✨ 主要能力
115
+
116
+ - 💬 **对话中直接生图**:不需要切换到其他网站,也不需要手动复制 Prompt,直接告诉 Agent 你想画什么即可。
117
+ - 🎨 **多 Provider 支持**:目前支持 Google Gemini、OpenAI Images、OpenAI Compatible API 以及 ByteDance Seedream / Volcengine Ark。Provider、模型和 Endpoint 都可以在设置界面中自由修改。
118
+ - 🔑 **BYOK (自带 Key)**:插件使用你自己的 API Key。API Key 通过 DeepSeek Harness 的 `credentials` 服务管理,采用写保护隔离,不需要写进项目源码或配置文件,前端不存明文。
119
+ - 🖼️ **图片跟随会话保存**:生成结果会接入 DeepSeek Harness 的 Attachment / Conversation 体系,重新打开历史会话后,仍然可以看到之前生成的图片。
120
+ - ⚙️ **原生设置界面**:Provider、API Key、模型和 Endpoint 都可以直接在 DSH Web 设置中修改,不需要手动编辑配置文件。
121
+
122
+ ---
123
+
124
+ ## 📦 支持的 Provider
125
+
126
+ | Provider | 默认模型 | 默认 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** | 自定义 | 自定义 Base URL |
131
+ | **ByteDance Seedream / 火山方舟** | `doubao-seedream-5-0-260128` | `https://ark.cn-beijing.volces.com/api/v3` |
132
+
133
+ ---
134
+
135
+ ## 🛠️ 本地开发 (Development)
136
+
137
+ ```bash
138
+ # 克隆仓库
139
+ git clone https://github.com/shanliuling/dsh-image-gen.git
140
+ cd dsh-image-gen
141
+
142
+ # 安装依赖与构建
143
+ pnpm install
144
+ pnpm run typecheck
145
+ pnpm run test
146
+ pnpm run build
147
+
148
+ # 检查 npm 打包内容
149
+ pnpm run pack:check
150
+ ```
151
+
152
+ ---
153
+
154
+ ## 📄 开源协议 (License)
155
+
156
+ 本项目基于 [MIT License](LICENSE) 开源。
157
+
158
+ 如果这个插件对你有用,欢迎点一个 ⭐️ **Star** 支持!
package/README.zh-CN.md CHANGED
@@ -1,85 +1,158 @@
1
- # dsh-image-gen
2
-
3
- [English](README.md) | 简体中文
4
-
5
- `dsh-image-gen` 是适用于 DeepSeek Harness (DSH) 的多厂商生图 Bundle 插件。它向智能体注册 `generate_image` 工具,并在 Web 对话流中直接持久化渲染高清图片卡片。
6
-
7
- ![对话效果预览](docs/assets/chat-preview.png)
8
-
9
- ---
10
-
11
- ## ✨ 核心特性
12
-
13
- - **多厂商生态支持**:原生支持 **Google Gemini**、**OpenAI / 兼容中转站 (OneAPI/NewAPI)** 以及 **字节火山方舟 Seedream (豆包绘图)**。
14
- - **安全凭证隔离**:借助 DSH `credentials` 服务实现 API Key 仅写入保护,前端防读取,后端内存透传,杜绝密钥泄露风险。
15
- - **开箱即用设置面板**:无缝集成至 DSH 设置中心,自动带出最新推荐模型与默认地址,支持自定义反代及一键还原官方地址。
16
- - **附件持久化存储**:生成的图片自动入库 DSH 附件体系(Attachment),会话历史完整可溯。
17
-
18
- ![设置面板预览](docs/assets/settings-preview.png)
19
-
20
- ---
21
-
22
- ## 📦 支持厂商与默认规范
23
-
24
- | 厂商 (Provider) | 凭据环境变量 | 默认模型 | 默认接口地址 (Endpoint / Base URL) | 协议说明 |
25
- | :------------------ | :--------------- | :--------------------------- | :-------------------------------------------------------------- | :----------------------------------- |
26
- | **Google Gemini** | `GEMINI_API_KEY` | `gemini-3.1-flash-image` | `https://generativelanguage.googleapis.com/v1beta/interactions` | Google 原生 Interactions 协议 |
27
- | **OpenAI / 中转站** | `OPENAI_API_KEY` | `gpt-image-2` | `https://api.openai.com/v1` | 标准 OpenAI `/v1/images/generations` |
28
- | **字节 Seedream** | `ARK_API_KEY` | `doubao-seedream-5-0-260128` | `https://ark.cn-beijing.volces.com/api/v3` | 火山方舟豆包文生图标准网关 |
29
-
30
- ---
31
-
32
- ## 🚀 安装与使用
33
-
34
- ### 1. 安装插件
35
-
36
- 在你的 DeepSeek Harness 工作区中安装本插件(以默认 `web` profile 为例):
37
-
38
- ```bash
39
- # 方式 A:npm 安装
40
- dsh plugin --profile web add dsh-image-gen
41
-
42
- # 方式 B:本地开发引入
43
- dsh plugin --profile web add /path/to/dsh-image-gen
44
- ```
45
-
46
- ### 2. 在 Web 界面配置
47
-
48
- 1. 打开 DSH Web 页面(默认 `http://localhost:3080`)。
49
- 2. 进入 **设置 (Settings) → 插件 (Plugins) → 图像生成 (Image generation)**。
50
- 3. 选择厂商,填入对应的 API Key,确认或自定义接口地址与模型,点击 **保存**。
51
-
52
- ### 3. 在对话中触发生图
53
-
54
- 新建对话,直接向大模型输入绘图提示词即可:
55
-
56
- > _"生成一只牛来的图片"_ 或 _"帮我画一张在雨夜霓虹街头的赛博朋克猫咪"_
57
-
58
- 模型将自动调用 `generate_image` 工具生成图片,并在对话中渲染出精美卡片。
59
-
60
- ---
61
-
62
- ## 🛠️ 本地开发与构建
63
-
64
- ```bash
65
- # 安装依赖
66
- pnpm install
67
-
68
- # 类型检查
69
- pnpm run typecheck
70
-
71
- # 运行单元测试
72
- pnpm run test
73
-
74
- # 编译 Node 端与浏览器端产物
75
- pnpm run build
76
-
77
- # 预打包检查
78
- pnpm run pack:check
79
- ```
80
-
81
- ---
82
-
83
- ## 📄 开源协议
84
-
85
- [MIT](LICENSE)
1
+ <div align="center">
2
+
3
+ # 🎨 dsh-image-gen
4
+
5
+ ### DeepSeek Harness (DSH) 原生生图插件
6
+
7
+ **让 DeepSeek Harness 像 ChatGPT 一样,在对话里直接生成图片。**
8
+
9
+ 支持 Google Gemini、OpenAI Images、OpenAI Compatible API、字节 Seedream / 火山方舟。
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.en.md) | **简体中文**
17
+
18
+ <br />
19
+
20
+ <p align="center">💬 <b>直接对你的 DeepSeek Harness Agent 发送以下提示词:</b></p>
21
+
22
+ ```text
23
+ 帮我安装生图插件,执行命令:pnpm dsh plugin --profile web add dsh-image-gen
24
+ ```
25
+
26
+ <p align="center"><sub>(也可以手动在终端执行:<code>pnpm dsh plugin --profile web add dsh-image-gen</code>)</sub></p>
27
+
28
+ <br />
29
+
30
+ <p align="center">安装完成后,在 DSH 设置中填入自己的 API Key,就可以直接对 Agent 说:</p>
31
+
32
+ ```text
33
+ 帮我画一张雨夜霓虹街头的赛博朋克猫咪。
34
+ ```
35
+
36
+ <p align="center">Agent 会自动调用 <code>generate_image</code>,生成图片并直接显示在当前对话中。</p>
37
+
38
+ <br />
39
+
40
+ <img src="docs/assets/chat-preview.png" alt="对话生图效果预览" width="820" />
41
+
42
+ </div>
43
+
44
+ ---
45
+
46
+ ## 💡 它解决什么问题?
47
+
48
+ **`dsh-image-gen` 是专为 DeepSeek Harness (DSH) 打造的开源图像生成插件。**
49
+
50
+ DeepSeek Harness 已经可以让 Agent 调用不同工具完成任务,本项目为它补上了原生的**多模态生图能力**:
51
+
52
+ ```mermaid
53
+ graph LR
54
+ A[用户 Prompt] --> B[DeepSeek Harness Agent]
55
+ B --> C[generate_image 工具]
56
+ C --> D[Gemini / OpenAI / Seedream]
57
+ D --> E[图片数据]
58
+ E --> F[当前 Conversation 对话流]
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 🚀 快速安装与使用
64
+
65
+ ### 1. 安装插件
66
+
67
+ 在你的 DeepSeek Harness 项目根目录下运行:
68
+
69
+ ```bash
70
+ # 推荐方式:通过 pnpm 一键安装并注册插件
71
+ pnpm dsh plugin --profile web add dsh-image-gen
72
+
73
+ # 若已将 dsh 安装为系统全局命令:
74
+ dsh plugin --profile web add dsh-image-gen
75
+ ```
76
+
77
+ <details>
78
+ <summary><b>🛠️ 其他安装方式(Git 仓库直装 / 本地调试)</b></summary>
79
+
80
+ ```bash
81
+ # 方式 B:从 GitHub 仓库直接安装最新代码
82
+ pnpm dsh plugin --profile web add git+https://github.com/shanliuling/dsh-image-gen.git
83
+
84
+ # 方式 C:本地克隆源码开发安装
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. 配置 API Key
92
+
93
+ 打开 DSH Web 页面(默认 `http://localhost:3080`):
94
+
95
+ 1. 进入 **Settings → Plugins → Image generation**。
96
+ 2. 选择 Provider,填写 API Key,点击 **保存** 即可。
97
+
98
+ <div align="center">
99
+ <img src="docs/assets/settings-preview.png" alt="设置面板预览" width="720" />
100
+ </div>
101
+
102
+ ### 3. 开始对话生图
103
+
104
+ 现在直接在聊天框输入:
105
+
106
+ ```text
107
+ 生成一张极简主义的现代建筑客厅插画。
108
+ ```
109
+
110
+ 当前 Agent 就会自动调用 `generate_image` 工具并在对话流中返回图片。
111
+
112
+ ---
113
+
114
+ ## ✨ 主要能力
115
+
116
+ - 💬 **对话中直接生图**:不需要切换到其他网站,也不需要手动复制 Prompt,直接告诉 Agent 你想画什么即可。
117
+ - 🎨 **多 Provider 支持**:目前支持 Google Gemini、OpenAI Images、OpenAI Compatible API 以及 ByteDance Seedream / Volcengine Ark。Provider、模型和 Endpoint 都可以在设置界面中自由修改。
118
+ - 🔑 **BYOK (自带 Key)**:插件使用你自己的 API Key。API Key 通过 DeepSeek Harness 的 `credentials` 服务管理,采用写保护隔离,不需要写进项目源码或配置文件,前端不存明文。
119
+ - 🖼️ **图片跟随会话保存**:生成结果会接入 DeepSeek Harness 的 Attachment / Conversation 体系,重新打开历史会话后,仍然可以看到之前生成的图片。
120
+ - ⚙️ **原生设置界面**:Provider、API Key、模型和 Endpoint 都可以直接在 DSH Web 设置中修改,不需要手动编辑配置文件。
121
+
122
+ ---
123
+
124
+ ## 📦 支持的 Provider
125
+
126
+ | Provider | 默认模型 | 默认 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** | 自定义 | 自定义 Base URL |
131
+ | **ByteDance Seedream / 火山方舟** | `doubao-seedream-5-0-260128` | `https://ark.cn-beijing.volces.com/api/v3` |
132
+
133
+ ---
134
+
135
+ ## 🛠️ 本地开发 (Development)
136
+
137
+ ```bash
138
+ # 克隆仓库
139
+ git clone https://github.com/shanliuling/dsh-image-gen.git
140
+ cd dsh-image-gen
141
+
142
+ # 安装依赖与构建
143
+ pnpm install
144
+ pnpm run typecheck
145
+ pnpm run test
146
+ pnpm run build
147
+
148
+ # 检查 npm 打包内容
149
+ pnpm run pack:check
150
+ ```
151
+
152
+ ---
153
+
154
+ ## 📄 开源协议 (License)
155
+
156
+ 本项目基于 [MIT License](LICENSE) 开源。
157
+
158
+ 如果这个插件对你有用,欢迎点一个 ⭐️ **Star** 支持!
package/lib/client.js CHANGED
@@ -34,24 +34,105 @@ window.__ModuleLoader__.load({
34
34
  openai: "OPENAI_API_KEY",
35
35
  seedream: "ARK_API_KEY"
36
36
  };
37
- const PROVIDER_LABEL = {
38
- google: "Google Gemini",
39
- openai: "OpenAI / 中转站",
40
- seedream: "字节 Seedream"
37
+ const DICT = {
38
+ zh: {
39
+ title: "图像生成",
40
+ description: "选择厂商并配置生图模型。",
41
+ provider: "Provider",
42
+ providerGoogle: "Google Gemini",
43
+ providerOpenAI: "OpenAI / 中转站",
44
+ providerSeedream: "字节 Seedream",
45
+ apiKeyLabel: "{provider} API Key",
46
+ apiKeyPlaceholder: "留空即可保留已配置的 Key",
47
+ apiKeyHint: "安全保存为 {key};页面不会读回明文。",
48
+ endpoint: "接口地址",
49
+ reset: "重置",
50
+ resetTitle: "重置为默认官方地址",
51
+ endpointHintGoogle: "Google 官方地址或反代端点(全路径)。",
52
+ endpointHintOpenAI: "中转站请填其 OpenAI 兼容的 /v1 地址。",
53
+ endpointHintSeedream: "火山方舟兼容的 /api/v3 地址。",
54
+ model: "模型",
55
+ saving: "保存中…",
56
+ save: "保存",
57
+ saved: "已保存",
58
+ checkingKey: "正在检查 API Key…",
59
+ keyConfigured: "已配置 API Key",
60
+ keyNotConfigured: "尚未配置 API Key",
61
+ generating: "正在生成图片…",
62
+ loading: "正在加载图片…",
63
+ loadFailed: "图片读取失败 ({status})",
64
+ generatedTitle: "Generated image"
65
+ },
66
+ en: {
67
+ title: "Image Generation",
68
+ description: "Select provider and configure image generation models.",
69
+ provider: "Provider",
70
+ providerGoogle: "Google Gemini",
71
+ providerOpenAI: "OpenAI / Relay",
72
+ providerSeedream: "ByteDance Seedream",
73
+ apiKeyLabel: "{provider} API Key",
74
+ apiKeyPlaceholder: "Leave empty to keep configured key",
75
+ apiKeyHint: "Securely saved as {key}; never read back in plaintext.",
76
+ endpoint: "Endpoint / Base URL",
77
+ reset: "Reset",
78
+ resetTitle: "Reset to official default URL",
79
+ endpointHintGoogle: "Official Google endpoint or reverse proxy (full path).",
80
+ endpointHintOpenAI: "OpenAI-compatible /v1 base URL for relays.",
81
+ endpointHintSeedream: "Volcengine Ark compatible /api/v3 base URL.",
82
+ model: "Model",
83
+ saving: "Saving…",
84
+ save: "Save",
85
+ saved: "Saved",
86
+ checkingKey: "Checking API Key…",
87
+ keyConfigured: "API Key configured",
88
+ keyNotConfigured: "API Key not configured",
89
+ generating: "Generating image…",
90
+ loading: "Loading image…",
91
+ loadFailed: "Failed to load image ({status})",
92
+ generatedTitle: "Generated image"
93
+ }
41
94
  };
42
95
  const STYLE = `
43
- .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}`;
96
+ .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}
97
+ .dsh-ig-card:hover{border-color:var(--dsw-alias-label-dimmed,#9ca3af)}
98
+ .dsh-ig-card-open{background:var(--dsw-alias-bg-layer-2,#fff);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}
99
+ .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}
100
+ .dsh-ig-head:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#4c78ff);outline-offset:-2px}
101
+ .dsh-ig-head-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
102
+ .dsh-ig-title{display:block;font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary,inherit)}
103
+ .dsh-ig-desc{display:block;font-size:13px;line-height:1.5;color:var(--dsw-alias-label-tertiary,#7b818b)}
104
+ .dsh-ig-chevron{flex:none;color:var(--dsw-alias-label-tertiary,#7b818b);transition:transform .16s;display:inline-flex;align-items:center}
105
+ .dsh-ig-chevron-open{transform:rotate(180deg)}
106
+ .dsh-ig-body{border-top:1px solid var(--dsw-alias-border-l2,#eee);padding:0 16px 16px}
107
+ .dsh-ig-field{display:grid;gap:6px;margin-top:14px}
108
+ .dsh-ig-label{font-size:13px;font-weight:500;color:var(--dsw-alias-label-primary,inherit)}
109
+ .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}
110
+ .dsh-ig-input:focus{border-color:var(--dsw-alias-brand-primary,#4c78ff)}
111
+ .dsh-ig-input-group{display:flex;gap:8px;align-items:center}
112
+ .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}
113
+ .dsh-ig-btn-reset:hover{background:var(--dsw-alias-bg-layer-2,#edf0f3);border-color:var(--dsw-alias-label-dimmed,#9ca3af)}
114
+ .dsh-ig-hint,.dsh-ig-status{margin:0;color:var(--dsw-alias-label-tertiary,#7b818b);font-size:12px;line-height:1.4}
115
+ .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)}
116
+ .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}
117
+ .dsh-ig-save:disabled{opacity:.4;cursor:default}
118
+ .dsh-ig-result{display:grid;gap:10px;max-width:520px}
119
+ .dsh-ig-result-title{font-size:14px;font-weight:600}
120
+ .dsh-ig-image{display:block;max-width:100%;max-height:520px;border-radius:12px;background:#f2f3f5}
121
+ .dsh-ig-error{color:var(--dsw-alias-label-error,#d33);font-size:13px}
122
+ .dsh-ig-loading{color:var(--dsw-alias-label-tertiary,#7b818b);font-size:13px}`;
44
123
  /** Required browser services. */
45
124
  const inject = [
46
125
  "slots",
47
126
  "connection",
48
127
  "remote",
49
- "settingsScope"
128
+ "settingsScope",
129
+ "locale"
50
130
  ];
51
131
  /** Mount the settings card and generated-image card. */
52
132
  function apply(ctx) {
53
133
  const { api } = ctx.get("connection");
54
134
  const scope = ctx.settingsScope.bind({ namespace: IMAGE_GENERATION_NAMESPACE });
135
+ const locale = ctx.get("locale");
55
136
  ctx.effect(() => {
56
137
  const style = document.createElement("style");
57
138
  style.dataset.plugin = "dsh-image-gen";
@@ -61,13 +142,16 @@ window.__ModuleLoader__.load({
61
142
  style.remove();
62
143
  };
63
144
  }, "dsh-image-gen: styles");
64
- ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
145
+ const register = ctx.slots.register.bind(ctx.slots);
146
+ ctx.slots.inject("settings.plugin.item", () => register({
65
147
  name: "settings.plugin.item",
66
- id: "dsh-image-gen",
67
- order: 30,
148
+ key: IMAGE_GENERATION_NAMESPACE,
149
+ id: IMAGE_GENERATION_NAMESPACE,
150
+ order: 100,
68
151
  inject: () => ({
69
152
  scope,
70
- credentials: api.credentials
153
+ credentials: api.credentials,
154
+ locale
71
155
  })
72
156
  }, ImageGenerationSettingsCard));
73
157
  ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
@@ -79,6 +163,7 @@ window.__ModuleLoader__.load({
79
163
  function ImageGenerationSettingsCard(props) {
80
164
  const [open, setOpen] = (0, react.useState)(false);
81
165
  const [snapshot, setSnapshot] = (0, react.useState)(() => props.scope.getSnapshot());
166
+ const [lang, setLang] = (0, react.useState)(() => props.locale?.getSnapshot?.()?.active ?? "zh");
82
167
  const [provider, setProvider] = (0, react.useState)("google");
83
168
  const [model, setModel] = (0, react.useState)("");
84
169
  const [baseURL, setBaseURL] = (0, react.useState)("");
@@ -89,6 +174,21 @@ window.__ModuleLoader__.load({
89
174
  (0, react.useEffect)(() => props.scope.subscribe(() => {
90
175
  setSnapshot(props.scope.getSnapshot());
91
176
  }), [props.scope]);
177
+ (0, react.useEffect)(() => {
178
+ return props.locale?.subscribe?.(() => {
179
+ setLang(props.locale?.getSnapshot?.()?.active ?? "zh");
180
+ });
181
+ }, [props.locale]);
182
+ const t = (keyName, params) => {
183
+ let text = (lang === "en" ? DICT.en : DICT.zh)[keyName] || DICT.zh[keyName] || keyName;
184
+ if (params) for (const [k, v] of Object.entries(params)) text = text.replace(`{${k}}`, v);
185
+ return text;
186
+ };
187
+ const providerLabels = {
188
+ google: t("providerGoogle"),
189
+ openai: t("providerOpenAI"),
190
+ seedream: t("providerSeedream")
191
+ };
92
192
  (0, react.useEffect)(() => {
93
193
  const value = snapshot.value;
94
194
  const next = value?.provider ?? "google";
@@ -124,16 +224,16 @@ window.__ModuleLoader__.load({
124
224
  setKey("");
125
225
  setConfigured(true);
126
226
  }
127
- setMessage("已保存");
227
+ setMessage(t("saved"));
128
228
  } catch (cause) {
129
229
  setMessage(cause instanceof Error ? cause.message : String(cause));
130
230
  } finally {
131
231
  setSaving(false);
132
232
  }
133
233
  };
134
- const keyStatus = configured === void 0 ? "正在检查 API Key…" : configured ? "已配置 API Key" : "尚未配置 API Key";
234
+ const keyStatus = configured === void 0 ? t("checkingKey") : configured ? t("keyConfigured") : t("keyNotConfigured");
135
235
  return (0, react_jsx_runtime.jsxs)("li", {
136
- className: "dsh-ig-card",
236
+ className: `dsh-ig-card ${open ? "dsh-ig-card-open" : ""}`,
137
237
  children: [(0, react_jsx_runtime.jsxs)("button", {
138
238
  type: "button",
139
239
  className: "dsh-ig-head",
@@ -141,15 +241,29 @@ window.__ModuleLoader__.load({
141
241
  onClick: () => {
142
242
  setOpen((value) => !value);
143
243
  },
144
- children: [(0, react_jsx_runtime.jsxs)("span", { children: [(0, react_jsx_runtime.jsx)("span", {
145
- className: "dsh-ig-title",
146
- children: "图像生成"
244
+ children: [(0, react_jsx_runtime.jsxs)("span", {
245
+ className: "dsh-ig-head-text",
246
+ children: [(0, react_jsx_runtime.jsx)("span", {
247
+ className: "dsh-ig-title",
248
+ children: t("title")
249
+ }), (0, react_jsx_runtime.jsx)("span", {
250
+ className: "dsh-ig-desc",
251
+ children: t("description")
252
+ })]
147
253
  }), (0, react_jsx_runtime.jsx)("span", {
148
- className: "dsh-ig-desc",
149
- children: "选择厂商并配置生图模型。"
150
- })] }), (0, react_jsx_runtime.jsx)("span", {
254
+ className: `dsh-ig-chevron ${open ? "dsh-ig-chevron-open" : ""}`,
151
255
  "aria-hidden": "true",
152
- children: open ? "⌃" : "⌄"
256
+ children: (0, react_jsx_runtime.jsx)("svg", {
257
+ width: "14",
258
+ height: "14",
259
+ viewBox: "0 0 16 16",
260
+ fill: "none",
261
+ stroke: "currentColor",
262
+ strokeWidth: "2",
263
+ strokeLinecap: "round",
264
+ strokeLinejoin: "round",
265
+ children: (0, react_jsx_runtime.jsx)("path", { d: "M4 6l4 4 4-4" })
266
+ })
153
267
  })]
154
268
  }), open ? (0, react_jsx_runtime.jsxs)("form", {
155
269
  className: "dsh-ig-body",
@@ -162,7 +276,7 @@ window.__ModuleLoader__.load({
162
276
  children: [
163
277
  (0, react_jsx_runtime.jsx)("span", {
164
278
  className: "dsh-ig-label",
165
- children: "Provider"
279
+ children: t("provider")
166
280
  }),
167
281
  (0, react_jsx_runtime.jsxs)("select", {
168
282
  className: "dsh-ig-input",
@@ -177,30 +291,30 @@ window.__ModuleLoader__.load({
177
291
  children: [
178
292
  (0, react_jsx_runtime.jsx)("option", {
179
293
  value: "google",
180
- children: "Google Gemini"
294
+ children: t("providerGoogle")
181
295
  }),
182
296
  (0, react_jsx_runtime.jsx)("option", {
183
297
  value: "openai",
184
- children: "OpenAI / 中转站"
298
+ children: t("providerOpenAI")
185
299
  }),
186
300
  (0, react_jsx_runtime.jsx)("option", {
187
301
  value: "seedream",
188
- children: "字节 Seedream"
302
+ children: t("providerSeedream")
189
303
  })
190
304
  ]
191
305
  }),
192
306
  (0, react_jsx_runtime.jsx)("span", {
193
307
  className: "dsh-ig-hint",
194
- children: PROVIDER_LABEL[provider]
308
+ children: providerLabels[provider]
195
309
  })
196
310
  ]
197
311
  }),
198
312
  (0, react_jsx_runtime.jsxs)("label", {
199
313
  className: "dsh-ig-field",
200
314
  children: [
201
- (0, react_jsx_runtime.jsxs)("span", {
315
+ (0, react_jsx_runtime.jsx)("span", {
202
316
  className: "dsh-ig-label",
203
- children: [PROVIDER_LABEL[provider], " API Key"]
317
+ children: t("apiKeyLabel", { provider: providerLabels[provider] })
204
318
  }),
205
319
  (0, react_jsx_runtime.jsx)("input", {
206
320
  className: "dsh-ig-input",
@@ -210,15 +324,11 @@ window.__ModuleLoader__.load({
210
324
  onChange: (event) => {
211
325
  setKey(event.target.value);
212
326
  },
213
- placeholder: configured ? "留空即可保留已配置的 Key" : ""
327
+ placeholder: configured ? t("apiKeyPlaceholder") : ""
214
328
  }),
215
- (0, react_jsx_runtime.jsxs)("span", {
329
+ (0, react_jsx_runtime.jsx)("span", {
216
330
  className: "dsh-ig-hint",
217
- children: [
218
- "安全保存为 ",
219
- KEY_REF[provider],
220
- ";页面不会读回明文。"
221
- ]
331
+ children: t("apiKeyHint", { key: KEY_REF[provider] })
222
332
  })
223
333
  ]
224
334
  }),
@@ -227,7 +337,7 @@ window.__ModuleLoader__.load({
227
337
  children: [
228
338
  (0, react_jsx_runtime.jsx)("span", {
229
339
  className: "dsh-ig-label",
230
- children: "接口地址"
340
+ children: t("endpoint")
231
341
  }),
232
342
  (0, react_jsx_runtime.jsxs)("div", {
233
343
  className: "dsh-ig-input-group",
@@ -242,16 +352,16 @@ window.__ModuleLoader__.load({
242
352
  }), (0, react_jsx_runtime.jsx)("button", {
243
353
  type: "button",
244
354
  className: "dsh-ig-btn-reset",
245
- title: "重置为默认官方地址",
355
+ title: t("resetTitle"),
246
356
  onClick: () => {
247
357
  setBaseURL(DEFAULT_BASE_URLS[provider]);
248
358
  },
249
- children: "重置"
359
+ children: t("reset")
250
360
  })]
251
361
  }),
252
362
  (0, react_jsx_runtime.jsx)("span", {
253
363
  className: "dsh-ig-hint",
254
- children: provider === "google" ? "Google 官方地址或反代端点(全路径)。" : provider === "openai" ? "中转站请填其 OpenAI 兼容的 /v1 地址。" : "火山方舟兼容的 /api/v3 地址。"
364
+ children: provider === "google" ? t("endpointHintGoogle") : provider === "openai" ? t("endpointHintOpenAI") : t("endpointHintSeedream")
255
365
  })
256
366
  ]
257
367
  }),
@@ -259,7 +369,7 @@ window.__ModuleLoader__.load({
259
369
  className: "dsh-ig-field",
260
370
  children: [(0, react_jsx_runtime.jsx)("span", {
261
371
  className: "dsh-ig-label",
262
- children: "模型"
372
+ children: t("model")
263
373
  }), (0, react_jsx_runtime.jsx)("input", {
264
374
  className: "dsh-ig-input",
265
375
  value: model,
@@ -279,7 +389,7 @@ window.__ModuleLoader__.load({
279
389
  className: "dsh-ig-save",
280
390
  type: "submit",
281
391
  disabled: saving || !snapshot.writable,
282
- children: saving ? "保存中…" : "保存"
392
+ children: saving ? t("saving") : t("save")
283
393
  })]
284
394
  })
285
395
  ]
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 ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({ name: 'settings.plugin.item', id: 'dsh-image-gen', order: 30, inject: () => ({ scope, credentials: api.credentials }) }, 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-image{display:block;max-width:100%;max-height:520px;border-radius:12px;background:#f2f3f5}\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 [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":";;;;;;;;;;;EAEA,MAAa,cAAc;;EAE3B,MAAa,6BAA6B;;EAI1C,MAAa,0BAA0B;EACvC,MAAa,0BAA0B;EACvC,MAAa,4BAA4B;EAKzC,MAAa,iBAAiB;GAC1B,QAAQ;GACR,QAAQ;GACR,UAAU;EACd;EACA,MAAa,oBAAoB;GAC7B,QAAQ;GACR,QAAQ;GACR,UAAU;EACd;;;;ECpBA,MAAM,UAAU;GAAE,QAAQ;GAAkB,QAAQ;GAAkB,UAAU;EAAc;EAC9F,MAAM,OAAO;GACT,IAAI;IACA,OAAO;IACP,aAAa;IACb,UAAU;IACV,gBAAgB;IAChB,gBAAgB;IAChB,kBAAkB;IAClB,aAAa;IACb,mBAAmB;IACnB,YAAY;IACZ,UAAU;IACV,OAAO;IACP,YAAY;IACZ,oBAAoB;IACpB,oBAAoB;IACpB,sBAAsB;IACtB,OAAO;IACP,QAAQ;IACR,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;IACf,kBAAkB;IAClB,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,gBAAgB;GACpB;GACA,IAAI;IACA,OAAO;IACP,aAAa;IACb,UAAU;IACV,gBAAgB;IAChB,gBAAgB;IAChB,kBAAkB;IAClB,aAAa;IACb,mBAAmB;IACnB,YAAY;IACZ,UAAU;IACV,OAAO;IACP,YAAY;IACZ,oBAAoB;IACpB,oBAAoB;IACpB,sBAAsB;IACtB,OAAO;IACP,QAAQ;IACR,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;IACf,kBAAkB;IAClB,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,gBAAgB;GACpB;EACJ;EACA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6Bd,MAAa,SAAS;GAAC;GAAS;GAAc;GAAU;GAAiB;EAAQ;;EAEjF,SAAgB,MAAM,KAAK;GACvB,MAAM,EAAE,QAAQ,IAAI,IAAI,YAAY;GACpC,MAAM,QAAQ,IAAI,cAAc,KAAK,EAAE,WAAW,2BAA2B,CAAC;GAC9E,MAAM,SAAS,IAAI,IAAI,QAAQ;GAC/B,IAAI,aAAa;IACb,MAAM,QAAQ,SAAS,cAAc,OAAO;IAC5C,MAAM,QAAQ,SAAS;IACvB,MAAM,cAAc;IACpB,SAAS,KAAK,YAAY,KAAK;IAC/B,aAAa;KAAE,MAAM,OAAO;IAAG;GACnC,GAAG,uBAAuB;GAC1B,MAAM,WAAW,IAAI,MAAM,SAAS,KAAK,IAAI,KAAK;GAClD,IAAI,MAAM,OAAO,8BAA8B,SAAS;IACpD,MAAM;IACN,KAAK;IACL,IAAI;IACJ,OAAO;IACP,eAAe;KAAE;KAAO,aAAa,IAAI;KAAa;IAAO;GACjE,GAAG,2BAA2B,CAAC;GAC/B,IAAI,MAAM,OAAO,4BAA4B,IAAI,MAAM,SAAS;IAAE,MAAM;IAAsB,KAAK;GAAiB,GAAG,kBAAkB,CAAC;EAC9I;;EAEA,SAAgB,4BAA4B,OAAO;GAC/C,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,CAAS,KAAK;GACtC,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,OAAe,MAAM,MAAM,YAAY,CAAC;GACxE,MAAM,CAAC,MAAM,YAAA,GAAWA,MAAAA,SAAAA,OAAe,MAAM,QAAQ,cAAc,CAAC,EAAE,UAAU,IAAI;GACpF,MAAM,CAAC,UAAU,gBAAA,GAAeA,MAAAA,SAAAA,CAAS,QAAQ;GACjD,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,EAAE;GACrC,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,EAAE;GACzC,MAAM,CAAC,KAAK,WAAA,GAAUA,MAAAA,SAAAA,CAAS,EAAE;GACjC,MAAM,CAAC,YAAY,kBAAA,GAAiBA,MAAAA,SAAAA,CAAS;GAC7C,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,KAAK;GAC1C,MAAM,CAAC,SAAS,eAAA,GAAcA,MAAAA,SAAAA,CAAS,EAAE;GACzC,CAAA,GAAA,MAAA,UAAA,OAAgB,MAAM,MAAM,gBAAgB;IAAE,YAAY,MAAM,MAAM,YAAY,CAAC;GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;GACvG,CAAA,GAAA,MAAA,UAAA,OAAgB;IACZ,OAAO,MAAM,QAAQ,kBAAkB;KACnC,QAAQ,MAAM,QAAQ,cAAc,CAAC,EAAE,UAAU,IAAI;IACzD,CAAC;GACL,GAAG,CAAC,MAAM,MAAM,CAAC;GACjB,MAAM,KAAK,SAAS,WAAW;IAE3B,IAAI,QADS,SAAS,OAAO,KAAK,KAAK,KAAK,GAAA,CAC5B,YAAY,KAAK,GAAG,YAAY;IAChD,IAAI,QACA,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,MAAM,GACtC,OAAO,KAAK,QAAQ,IAAI,EAAE,IAAI,CAAC;IAGvC,OAAO;GACX;GACA,MAAM,iBAAiB;IACnB,QAAQ,EAAE,gBAAgB;IAC1B,QAAQ,EAAE,gBAAgB;IAC1B,UAAU,EAAE,kBAAkB;GAClC;GACA,CAAA,GAAA,MAAA,UAAA,OAAgB;IACZ,MAAM,QAAQ,SAAS;IACvB,MAAM,OAAO,OAAO,YAAY;IAChC,YAAY,IAAI;IAChB,SAAS,QAAQ,MAAM,KAAK,CAAC;IAC7B,WAAW,UAAU,MAAM,KAAK,CAAC;GACrC,GAAG,CAAC,QAAQ,CAAC;GACb,CAAA,GAAA,MAAA,UAAA,OAAgB;IACZ,IAAI,SAAS;IACb,MAAW,YAAY,SAAS,EAAE,MAAM,CAAC,QAAQ,SAAS,EAAE,CAAC,CAAC,CAAC,MAAK,aAAY;KAC5E,IAAI,QACA,cAAc,SAAS,OAAO,KAAK,SAAS,OAAO,MAAM,YAAY,QAAQ,UAAU,EAAE,cAAc,QAAQ,KAAA,CAAS;IAChI,CAAC,CAAC,CAAC,YAAY;KAAE,IAAI,QACjB,cAAc,KAAA,CAAS;IAAG,CAAC;IAC/B,aAAa;KAAE,SAAS;IAAO;GACnC,GAAG,CAAC,MAAM,aAAa,QAAQ,CAAC;GAChC,MAAM,OAAO,OAAO,UAAU;IAC1B,MAAM,eAAe;IACrB,UAAU,IAAI;IACd,WAAW,EAAE;IACb,IAAI;KACA,MAAM,MAAM,MAAM,IAAI,YAAY,QAAQ;KAC1C,MAAM,MAAM,MAAM,IAAI,aAAa,WAAW,gBAAgB,aAAa,WAAW,gBAAgB,iBAAiB,KAAK;KAC5H,MAAM,MAAM,MAAM,IAAI,aAAa,WAAW,mBAAmB,aAAa,WAAW,kBAAkB,mBAAmB,OAAO;KACrI,IAAI,IAAI,KAAK,CAAC,CAAC,SAAS,GAAG;MACvB,MAAM,WAAW,MAAM,MAAM,YAAY,IAAI;OAAE,KAAK,QAAQ;OAAW,OAAO,IAAI,KAAK;MAAE,CAAC;MAC1F,IAAI,CAAC,SAAS,OAAO,IACjB,MAAM,IAAI,MAAM,SAAS,OAAO,MAAM,OAAO;MACjD,OAAO,EAAE;MACT,cAAc,IAAI;KACtB;KACA,WAAW,EAAE,OAAO,CAAC;IACzB,SACO,OAAO;KACV,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IACrE,UACQ;KACJ,UAAU,KAAK;IACnB;GACJ;GACA,MAAM,YAAY,eAAe,KAAA,IAAY,EAAE,aAAa,IAAI,aAAa,EAAE,eAAe,IAAI,EAAE,kBAAkB;GACtH,QAAA,GAAOC,kBAAAA,KAAAA,CAAM,MAAM;IAAE,WAAW,eAAe,OAAO,qBAAqB;IAAM,UAAU,EAAA,GAACA,kBAAAA,KAAAA,CAAM,UAAU;KAAE,MAAM;KAAU,WAAW;KAAe,iBAAiB;KAAM,eAAe;MAAE,SAAQ,UAAS,CAAC,KAAK;KAAG;KAAG,UAAU,EAAA,GAACA,kBAAAA,KAAAA,CAAM,QAAQ;MAAE,WAAW;MAAoB,UAAU,EAAA,GAACC,kBAAAA,IAAAA,CAAK,QAAQ;OAAE,WAAW;OAAgB,UAAU,EAAE,OAAO;MAAE,CAAC,IAAA,GAAGA,kBAAAA,IAAAA,CAAK,QAAQ;OAAE,WAAW;OAAe,UAAU,EAAE,aAAa;MAAE,CAAC,CAAC;KAAE,CAAC,IAAA,GAAGA,kBAAAA,IAAAA,CAAK,QAAQ;MAAE,WAAW,kBAAkB,OAAO,wBAAwB;MAAM,eAAe;MAAQ,WAAA,GAAUA,kBAAAA,IAAAA,CAAK,OAAO;OAAE,OAAO;OAAM,QAAQ;OAAM,SAAS;OAAa,MAAM;OAAQ,QAAQ;OAAgB,aAAa;OAAK,eAAe;OAAS,gBAAgB;OAAS,WAAA,GAAUA,kBAAAA,IAAAA,CAAK,QAAQ,EAAE,GAAG,eAAe,CAAC;MAAE,CAAC;KAAE,CAAC,CAAC;IAAE,CAAC,GAAG,QAAA,GAAOD,kBAAAA,KAAAA,CAAM,QAAQ;KAAE,WAAW;KAAe,WAAW,UAAU;MAAE,KAAU,KAAK;KAAG;KAAG,UAAU;OAACA,GAAAA,kBAAAA,KAAAA,CAAM,SAAS;OAAE,WAAW;OAAgB,UAAU;SAACC,GAAAA,kBAAAA,IAAAA,CAAK,QAAQ;SAAE,WAAW;SAAgB,UAAU,EAAE,UAAU;QAAE,CAAC;SAAGD,GAAAA,kBAAAA,KAAAA,CAAM,UAAU;SAAE,WAAW;SAAgB,OAAO;SAAU,WAAU,UAAS;UAAE,MAAM,OAAO,MAAM,OAAO;UAAO,YAAY,IAAI;UAAG,SAAS,QAAQ,MAAM,SAAS,KAAK,CAAC;UAAG,WAAW,UAAU,MAAM,SAAS,KAAK,CAAC;UAAG,OAAO,EAAE;SAAG;SAAG,UAAU;WAACC,GAAAA,kBAAAA,IAAAA,CAAK,UAAU;WAAE,OAAO;WAAU,UAAU,EAAE,gBAAgB;UAAE,CAAC;WAAGA,GAAAA,kBAAAA,IAAAA,CAAK,UAAU;WAAE,OAAO;WAAU,UAAU,EAAE,gBAAgB;UAAE,CAAC;WAAGA,GAAAA,kBAAAA,IAAAA,CAAK,UAAU;WAAE,OAAO;WAAY,UAAU,EAAE,kBAAkB;UAAE,CAAC;SAAC;QAAE,CAAC;SAAGA,GAAAA,kBAAAA,IAAAA,CAAK,QAAQ;SAAE,WAAW;SAAe,UAAU,eAAe;QAAU,CAAC;OAAC;MAAE,CAAC;OAAGD,GAAAA,kBAAAA,KAAAA,CAAM,SAAS;OAAE,WAAW;OAAgB,UAAU;SAACC,GAAAA,kBAAAA,IAAAA,CAAK,QAAQ;SAAE,WAAW;SAAgB,UAAU,EAAE,eAAe,EAAE,UAAU,eAAe,UAAU,CAAC;QAAE,CAAC;SAAGA,GAAAA,kBAAAA,IAAAA,CAAK,SAAS;SAAE,WAAW;SAAgB,MAAM;SAAY,cAAc;SAAO,OAAO;SAAK,WAAU,UAAS;UAAE,OAAO,MAAM,OAAO,KAAK;SAAG;SAAG,aAAa,aAAa,EAAE,mBAAmB,IAAI;QAAG,CAAC;SAAGA,GAAAA,kBAAAA,IAAAA,CAAK,QAAQ;SAAE,WAAW;SAAe,UAAU,EAAE,cAAc,EAAE,KAAK,QAAQ,UAAU,CAAC;QAAE,CAAC;OAAC;MAAE,CAAC;OAAGD,GAAAA,kBAAAA,KAAAA,CAAM,SAAS;OAAE,WAAW;OAAgB,UAAU;SAACC,GAAAA,kBAAAA,IAAAA,CAAK,QAAQ;SAAE,WAAW;SAAgB,UAAU,EAAE,UAAU;QAAE,CAAC;SAAGD,GAAAA,kBAAAA,KAAAA,CAAM,OAAO;SAAE,WAAW;SAAsB,UAAU,EAAA,GAACC,kBAAAA,IAAAA,CAAK,SAAS;UAAE,WAAW;UAAgB,MAAM;UAAO,OAAO;UAAS,WAAU,UAAS;WAAE,WAAW,MAAM,OAAO,KAAK;UAAG;UAAG,UAAU;SAAK,CAAC,IAAA,GAAGA,kBAAAA,IAAAA,CAAK,UAAU;UAAE,MAAM;UAAU,WAAW;UAAoB,OAAO,EAAE,YAAY;UAAG,eAAe;WAAE,WAAW,kBAAkB,SAAS;UAAG;UAAG,UAAU,EAAE,OAAO;SAAE,CAAC,CAAC;QAAE,CAAC;SAAGA,GAAAA,kBAAAA,IAAAA,CAAK,QAAQ;SAAE,WAAW;SAAe,UAAU,aAAa,WAAW,EAAE,oBAAoB,IAAI,aAAa,WAAW,EAAE,oBAAoB,IAAI,EAAE,sBAAsB;QAAE,CAAC;OAAC;MAAE,CAAC;OAAGD,GAAAA,kBAAAA,KAAAA,CAAM,SAAS;OAAE,WAAW;OAAgB,UAAU,EAAA,GAACC,kBAAAA,IAAAA,CAAK,QAAQ;QAAE,WAAW;QAAgB,UAAU,EAAE,OAAO;OAAE,CAAC,IAAA,GAAGA,kBAAAA,IAAAA,CAAK,SAAS;QAAE,WAAW;QAAgB,OAAO;QAAO,WAAU,UAAS;SAAE,SAAS,MAAM,OAAO,KAAK;QAAG;QAAG,UAAU;OAAK,CAAC,CAAC;MAAE,CAAC;OAAGD,GAAAA,kBAAAA,KAAAA,CAAM,OAAO;OAAE,WAAW;OAAkB,UAAU,EAAA,GAACC,kBAAAA,IAAAA,CAAK,KAAK;QAAE,WAAW;QAAiB,MAAM;QAAU,UAAU,WAAW;OAAU,CAAC,IAAA,GAAGA,kBAAAA,IAAAA,CAAK,UAAU;QAAE,WAAW;QAAe,MAAM;QAAU,UAAU,UAAU,CAAC,SAAS;QAAU,UAAU,SAAS,EAAE,QAAQ,IAAI,EAAE,MAAM;OAAE,CAAC,CAAC;MAAE,CAAC;KAAC;IAAE,CAAC,IAAI,IAAI;GAAE,CAAC;EACjtG;;EAEA,SAAgB,mBAAmB,OAAO;GACtC,MAAM,aAAa,SAAS,MAAM,KAAK;GACvC,MAAM,CAAC,KAAK,WAAA,GAAUF,MAAAA,SAAAA,CAAS;GAC/B,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS;GACnC,CAAA,GAAA,MAAA,UAAA,OAAgB;IACZ,IAAI,eAAe,KAAA,GACf;IACJ,MAAM,aAAa,IAAI,gBAAgB;IACvC,IAAI;IACJ,MAAW,aAAa;KAAE,QAAQ;KAAQ,QAAQ,WAAW;KAAQ,SAAS,EAAE,gBAAgB,mBAAmB;KAAG,MAAM,KAAK,UAAU,EAAE,WAAW,CAAC;IAAE,CAAC,CAAC,CAAC,KAAK,OAAO,aAAa;KAAE,IAAI,CAAC,SAAS,IACnM,MAAM,IAAI,MAAM,WAAW,OAAO,SAAS,MAAM,EAAE,EAAE;KAAG,MAAM,OAAO,MAAM,SAAS,KAAK;KAAG,IAAI,WAAW,OAAO,SAClH;KAAQ,YAAY,IAAI,gBAAgB,IAAI;KAAG,OAAO,SAAS;IAAG,CAAC,CAAC,CAAC,OAAM,UAAS;KAAE,IAAI,CAAC,WAAW,OAAO,SAC7G,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IAAG,CAAC;IACvE,aAAa;KAAE,WAAW,MAAM;KAAG,IAAI,cAAc,KAAA,GACjD,IAAI,gBAAgB,SAAS;IAAG;GACxC,GAAG,CAAC,YAAY,YAAY,CAAC;GAC7B,IAAI,eAAe,KAAA,GACf,QAAA,GAAOE,kBAAAA,IAAAA,CAAK,OAAO;IAAE,WAAW;IAAkB,UAAU;GAA6C,CAAC;GAC9G,QAAA,GAAOD,kBAAAA,KAAAA,CAAM,WAAW;IAAE,WAAW;IAAiB,cAAc;IAAmB,UAAU;MAACC,GAAAA,kBAAAA,IAAAA,CAAK,OAAO;MAAE,WAAW;MAAuB,UAAU;KAAkB,CAAC;KAAG,UAAU,KAAA,KAAA,GAAYA,kBAAAA,IAAAA,CAAK,OAAO;MAAE,WAAW;MAAgB,UAAU;KAAM,CAAC,IAAI;KAAM,QAAQ,KAAA,KAAa,UAAU,KAAA,KAAA,GAAYA,kBAAAA,IAAAA,CAAK,OAAO;MAAE,WAAW;MAAkB,UAAU;KAA6C,CAAC,IAAI;KAAM,QAAQ,KAAA,KAAA,GAAYA,kBAAAA,IAAAA,CAAK,OAAO;MAAE,WAAW;MAAgB,KAAK;MAAK,KAAK,WAAW,QAAQ;KAAkB,CAAC,IAAI;IAAI;GAAE,CAAC;EACriB;EACA,SAAS,QAAQ,UAAU,OAAO;GAC9B,MAAM,SAAS,aAAa,WAAW,OAAO,cAAc,aAAa,WAAW,OAAO,cAAc,OAAO;GAChH,OAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,SAAS,eAAe;EACrF;EACA,SAAS,UAAU,UAAU,OAAO;GAChC,MAAM,SAAS,aAAa,WAAW,OAAO,iBAAiB,aAAa,WAAW,OAAO,gBAAgB,OAAO;GACrH,OAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,SAAS,kBAAkB;EACxF;EACA,SAAS,SAAS,OAAO;GAAE,IAAI,EAAE,UAAU,UAAU,MAAM,YAAY,SAAS,WAC5E,OAAO,KAAA;GAAW,MAAM,QAAQ,MAAM,WAAW,SAAS,MAAK,SAAQ,KAAK,SAAS,OAAO;GAAG,OAAO,OAAO,SAAS,UAAU,MAAM,aAAa,KAAA;EAAW"}
@@ -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,113 +1,124 @@
1
- {
2
- "name": "dsh-image-gen",
3
- "version": "0.1.0",
4
- "description": "Installable multi-provider image generation bundle for DeepSeek Harness",
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
- ],
52
- "platform": "web"
53
- }
54
- },
55
- "engines": {
56
- "node": "^22.19.0 || >=24.0.0"
57
- },
58
- "license": "MIT",
59
- "keywords": [
60
- "deepseek-harness",
61
- "dsh",
62
- "gemini",
63
- "openai",
64
- "seedream",
65
- "image-generation",
66
- "cordis"
67
- ],
68
- "peerDependencies": {
69
- "@deepseek-ai/cordis": ">=4.0.0 <5",
70
- "@deepseek-ai/dsh-attachment": ">=0.1.0-rc.5 <0.2.0",
71
- "@deepseek-ai/dsh-api-remotes": ">=0.1.0-rc.5 <0.2.0",
72
- "@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.5 <0.2.0",
73
- "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.5 <0.2.0",
74
- "@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.5 <0.2.0",
75
- "@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.0-rc.5 <0.2.0",
76
- "@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.5 <0.2.0",
77
- "@deepseek-ai/dsh-client-ui-tool": ">=0.1.0-rc.5 <0.2.0",
78
- "@deepseek-ai/dsh-credentials": ">=0.1.0-rc.5 <0.2.0",
79
- "@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.5 <0.2.0",
80
- "@deepseek-ai/dsh-settings": ">=0.1.0-rc.5 <0.2.0",
81
- "@deepseek-ai/dsh-tools": ">=0.1.0-rc.5 <0.2.0",
82
- "@deepseek-ai/schemastery": ">=3.18.0 <4",
83
- "react": ">=18.2.0 <19"
84
- },
85
- "devDependencies": {
86
- "@deepseek-ai/cordis": "4.0.1",
87
- "@deepseek-ai/dsh-attachment": "0.1.0-rc.6",
88
- "@deepseek-ai/dsh-api-remotes": "0.1.0-rc.6",
89
- "@deepseek-ai/dsh-client-connection": "0.1.0-rc.6",
90
- "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
91
- "@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.6",
92
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.0-rc.6",
93
- "@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
94
- "@deepseek-ai/dsh-client-ui-tool": "0.1.0-rc.6",
95
- "@deepseek-ai/dsh-credentials": "0.1.0-rc.6",
96
- "@deepseek-ai/dsh-host-webserver": "0.1.0-rc.6",
97
- "@deepseek-ai/dsh-settings": "0.1.0-rc.6",
98
- "@deepseek-ai/dsh-tools": "0.1.0-rc.6",
99
- "@deepseek-ai/schemastery": "3.18.1",
100
- "@types/node": "^22.20.0",
101
- "@types/react": "~18.3.1",
102
- "react": "^18.2.0",
103
- "tsdown": "^0.22.2",
104
- "typescript": "^6.0.3",
105
- "vitest": "^4.1.8"
106
- },
107
- "scripts": {
108
- "typecheck": "tsc --noEmit",
109
- "build": "tsc && tsdown",
110
- "test": "vitest run",
111
- "pack:check": "pnpm pack --dry-run"
112
- }
113
- }
1
+ {
2
+ "name": "dsh-image-gen",
3
+ "version": "0.1.2",
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
+ }