dsh-fps-workbench 0.1.77 → 0.1.79

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.
Binary file
Binary file
@@ -1,21 +1,23 @@
1
1
  # Four-pointed star (FPS)
2
2
 
3
- FPS is a conversation workspace for DeepSeek Harness (DSH). Track tool progress, open session outputs, and check context and provider usage from one interface. Return to unsent attachments when you switch sessions, and use a configured vision model to interpret images for a text-only model.
3
+ FPS is a conversation workbench for DeepSeek Harness (DSH): follow long tasks, keep unsent drafts, and find the finished files. It combines tool summaries, task states, native output previews, local attachment recovery, provider usage, and optional image tools. Light and dark appearances follow DSH. Sessions, execution permissions, voice transcription, and previews remain native.
4
4
 
5
5
  ## What you can do
6
6
 
7
7
  - **Context and session outputs.** Open Context in the conversation header to see the model, session state, and estimated context composition. Outputs lists local files produced or explicitly linked in the session. Select a file to open it in DSH's native preview. The header also gives you access to Files, Terminal, and Browser.
8
8
  - **Tool progress summaries.** Consecutive file reads, commands, and edits appear in one summary row. Expand it for DSH's native tool details. The task list distinguishes completed, active, and pending work. While the session runs, `ThinKing` shows elapsed time alongside the FPS mark and respects the system's reduced motion setting.
9
- - **Composer and attachment drafts.** Paste images or use the Add menu to choose images and files. When you return to a session, its draft text and unsent attachments are restored. Reloading or closing the interface clears unsent attachments. Each message supports up to four images of 8 MB each and six files of 20 MB each.
10
- - **Images with text-only models.** When the selected model does not support images, FPS looks for an available model with image input in DSH. It sends the image and prompt to that model and passes the resulting description to the current session. If no suitable model is available, the composer keeps the draft and shows an error.
9
+ - **Composer and attachment drafts.** Paste images or use the Add menu to choose images and files. When you return to a session, its draft text and unsent attachments are restored. Unsent attachments are saved on this device and restored after a reload in the same client profile. They are removed after DSH accepts the message, when you remove them, or on a later load after 30 days without an attachment edit. Wait for the saved indicator before closing; storage failures keep the current draft in memory and offer Retry. While drafts load, text editing and voice input remain available; sending waits for loading to finish or fail. Each storage operation has a 10-second timeout. This is local storage, not cross-device sync. Each message supports up to four images of 8 MB each and six files of 20 MB each.
10
+ - **Long-task status.** The Context panel separates the plan currently reported by DSH from background jobs. A later turn can replace or clear that plan. Active jobs show their actual state, elapsed time, and any progress reported by DSH; finished jobs collapse into a separate group. Open the native job control for logs and stop actions. A running render does not create a plan automatically, and FPS does not invent a completion percentage.
11
+ - **Compatibility check.** Open Plugins → Four-pointed star → Compatibility check to inspect input, file, preview, job, and local draft storage interfaces. Refresh checks or copy a diagnostic summary without keys, file paths, or conversation content. This is a capability check, not a model/tool execution test. A missing input contract or an FPS composer render error restores the DSH native composer for the current page.
12
+ - **Images with text-only models.** When the selected model does not support images, FPS looks for an available model with image input in DSH. It sends the image and prompt to that model and passes the resulting description to the current session. No fallback model is hard-coded. The extra model request can incur provider charges. If no suitable model is available, the composer keeps the draft and shows an error.
11
13
  - **Sessions and workspaces.** The sidebar keeps DSH's workspaces, session search, and settings. Use the back and forward arrows beside the sidebar toggle to revisit sessions opened in the current window.
12
- - **Commands, references, and voice.** Type `/` to find commands and `@` to reference files or sessions. The composer footer gives you access to the workspace, permissions, model, reasoning effort, and usage. Enable the DSH voice input plugin to see a microphone in the composer.
14
+ - **Commands, references, and voice.** Type `/` to find commands and `@` to reference files or sessions. The composer footer gives you access to the workspace, permissions, model, reasoning effort, and usage. Enable the DSH voice input plugin to see a microphone in the composer. Recording and transcription remain native; transcribed text returns to the originating session draft even if you switch sessions. A configured voice provider and microphone permission are required.
13
15
 
14
16
  FPS sends messages through the native DSH session. Models can use the tools enabled in the current configuration, and DSH runs them or requests approval according to the session permissions.
15
17
 
16
18
  ## Provider usage
17
19
 
18
- Click the ring next to the model selector. FPS queries usage using the providers and API keys enabled in DSH. It shows the balance, spending, quota, or reset time returned by a supported endpoint. Zero balances are displayed. Accounts or fields are hidden when an endpoint is unsupported, a query fails, or data is missing. DSH supplies the session's token counts and estimated context usage separately.
20
+ Click the ring next to the model selector. FPS queries usage using the providers and API keys enabled in DSH. It shows the balance, spending, quota, or reset time returned by a supported endpoint. Zero balances are displayed. Accounts or fields are hidden when an endpoint is unsupported, a query fails, or data is missing. DSH supplies the session's token counts and estimated context usage separately. Provider sections have separators and sort alphabetically, ignoring case. The popup grows to at most 720 px, subject to available screen space, then scrolls. An ordinary model key may not expose organization-level usage; missing metrics are not inferred from token counts.
19
21
 
20
22
  ## Optional image generation
21
23
 
@@ -28,6 +30,8 @@ You can name a provider in your prompt. By default, FPS asks the model to prefer
28
30
  - **Pollinations.** Requires your own Pollinations API key and may require a positive available balance even for a zero-priced model. FPS checks the live price of its SDXL Lightning model before sending a generation request. This community model is suited to quick drafts, and its description states that prompts and completions are logged. [Pollinations API](https://gen.pollinations.ai/docs)
29
31
  - **ComfyUI + Comfy MCP.** Switch it on, then start the download from Image generation. The setup installs ComfyUI and its official Comfy MCP integration. It targets Apple Silicon with macOS 14 or newer, 64-bit Windows, and x86-64 Linux with glibc 2.28 or newer. Have Git, Python 3.11–3.13 with `venv` and `pip`, internet access, at least 8 GB of RAM, and 16 GiB of free disk space for setup. A compatible Apple or NVIDIA GPU is recommended. CPU generation can take several minutes. The included SD 1.5 workflow produces local drafts around 512 × 512 pixels by default. Fine text and photorealism can be limited. Local generation needs no Comfy account or credits. [Comfy MCP](https://github.com/Comfy-Org/comfy-mcp) · [Checkpoint and license](https://huggingface.co/Comfy-Org/stable-diffusion-v1-5-archive)
30
32
 
33
+ Enabling ComfyUI alone does not start a download. Installation offers progress and cancellation. Apple silicon generation has been tested; Windows and Linux setup have not been verified on physical devices. Free tiers and availability may change.
34
+
31
35
  Turning ComfyUI off disables local image generation and keeps the downloaded files for later use. FPS uses the official MCP to run the starter workflow and exposes only image generation to the conversation.
32
36
 
33
37
  Save the CogView-3-Flash and Pollinations keys in the Image generation settings. FPS uses the DSH credential store. You can also provide `FPS_COGVIEW_API_KEY` or `POLLINATIONS_API_KEY` in the environment that starts DSH. Each provider uses its own key.
@@ -1,21 +1,23 @@
1
1
  # Four-pointed star(FPS)
2
2
 
3
- FPS 是 DeepSeek Harness(DSH)的会话工作台。你可以在同一处跟踪工具进度、打开会话产物、查看上下文与服务商用量。切换会话后可以找回未发送的附件,使用纯文本模型时也可以借助已配置的视觉模型读图。
3
+ FPS 是 DeepSeek Harness(DSH)的会话工作台:看清长任务进度,留住未发送的草稿,找到最终产物。工具摘要、任务状态、原生产物预览、本机附件恢复、服务商用量和可选图片工具集中在同一处。浅色与深色外观跟随 DSH;会话、执行权限、语音转写和预览继续使用原生系统。
4
4
 
5
5
  ## 主要功能
6
6
 
7
7
  - **上下文与会话产物**。点会话顶栏的「上下文」按钮,查看模型、会话状态和上下文占用估算。「输出内容」汇集会话生成或明确链接的本地文件,点击后用 DSH 原生预览打开。顶栏也可切换文件、终端和浏览器。
8
8
  - **工具步骤摘要**。连续的读文件、执行命令和编辑操作会汇总成一行,展开可查看 DSH 原生详情。任务列表区分已完成、进行中和待处理。会话运行时,`ThinKing` 显示用时和 FPS 标志动画,遵循系统的减少动态效果设置。
9
- - **输入与附件草稿**。支持粘贴图片,也可从「添加」菜单选择图片和文件。切换会话再回来时,会恢复该会话的文字草稿和未发送的附件。重新加载或关闭界面会清除未发送的附件。每条消息最多可添加 4 张各 8 MB 的图片和 6 个各 20 MB 的文件。
10
- - **纯文本模型识图**。如果所选模型不支持图片输入,FPS 会从 DSH 的可用模型中查找支持图片的模型,将图片和问题发给它,再把生成的描述交给当前会话。找不到可用模型时,输入框会保留草稿并提示失败。
9
+ - **输入与附件草稿**。支持粘贴图片,也可从「添加」菜单选择图片和文件。切换会话再回来时,会恢复该会话的文字草稿和未发送的附件。未发送附件保存在本机,同一客户端配置下重新加载后也能恢复。DSH 接收消息后、手动移除附件后,或附件连续 30 天未修改后的下次加载时会清除。关闭前请等待保存完成提示;存储失败时保留当前内存草稿并提供重试。加载草稿时仍可编辑文字、使用语音;发送需等待加载完成或报错。每次存储操作设有 10 秒超时。此功能不跨设备同步。每条消息最多可添加 4 张各 8 MB 的图片和 6 个各 20 MB 的文件。
10
+ - **长任务状态**。上下文侧栏分别显示 DSH 当前报告的原生计划与后台任务;后续回合可能替换或清空计划。进行中的任务显示真实状态、用时和 DSH 返回的进度信息;已结束任务折叠显示。通过原生任务按钮查看日志或停止任务。开始渲染不会自动创建计划列表,FPS 也不会估算没有依据的完成百分比。
11
+ - **兼容性自检**。打开「插件 → Four-pointed star → 兼容性自检」,检查输入、文件、预览、后台任务及本机草稿存储接口。可重新检查或复制不包含 Key、文件路径和对话内容的诊断摘要。自检只检查接口能力,不调用模型或执行工具。输入框接口不匹配或 FPS 输入框渲染报错时,本次页面自动回退到 DSH 原生输入框。
12
+ - **纯文本模型识图**。如果所选模型不支持图片输入,FPS 会从 DSH 的可用模型中查找支持图片的模型,将图片和问题发给它,再把生成的描述交给当前会话。没有写死回退模型;额外模型请求可能产生服务商费用。找不到可用模型时,输入框会保留草稿并提示失败。
11
13
  - **会话和工作区**。左栏保留 DSH 的原生工作区、会话搜索和设置。侧栏按钮旁的前进、后退箭头可在本次打开窗口后访问过的会话间切换。
12
- - **命令、引用和语音**。输入 `/` 查找命令,输入 `@` 引用文件或会话。输入框下方可选择工作区、权限、模型和推理强度,也可查看用量。DSH 启用语音输入插件时,输入框会显示麦克风。
14
+ - **命令、引用和语音**。输入 `/` 查找命令,输入 `@` 引用文件或会话。输入框下方可选择工作区、权限、模型和推理强度,也可查看用量。DSH 启用语音输入插件时,输入框会显示麦克风。录音和转写使用原生实现,即便切换会话,转写结果仍归入原会话草稿;需配置可用语音服务并授权麦克风。
13
15
 
14
16
  FPS 通过 DSH 原生会话发送消息。模型可以使用当前配置已启用的工具,由 DSH 按会话权限执行或请求确认。
15
17
 
16
18
  ## 用量怎么显示
17
19
 
18
- 点模型选择器旁的圆环。FPS 根据 DSH 中已启用的服务商及其 API Key 查询用量,按适配接口实际返回的内容显示余额、已用金额、额度或重置时间。零余额正常显示。接口未适配、查询失败或缺少数据时,相应账户或字段会自动隐藏。会话 Token 和上下文占用估算由 DSH 提供,单独显示。
20
+ 点模型选择器旁的圆环。FPS 根据 DSH 中已启用的服务商及其 API Key 查询用量,按适配接口实际返回的内容显示余额、已用金额、额度或重置时间。零余额正常显示。接口未适配、查询失败或缺少数据时,相应账户或字段会自动隐藏。会话 Token 和上下文占用估算由 DSH 提供,单独显示。服务商区块之间有分隔,按名称字母顺序排列,不区分大小写。弹层最多增长到 720 px,同时受屏幕空间限制,超出后才滚动。普通模型 Key 不一定能读取组织级用量,缺失指标不会根据 Token 推算。
19
21
 
20
22
  ## 可选生图工具
21
23
 
@@ -28,6 +30,8 @@ FPS 通过 DSH 原生会话发送消息。模型可以使用当前配置已启
28
30
  - **Pollinations**。需要自己的 Pollinations API Key。即使使用零价模型,服务也可能要求账户有正的可用余额。FPS 在请求前检查 SDXL Lightning 的实时价格,仅在零价时调用。该社区模型适合快速打样,模型说明标明会记录提示词和生成结果。[Pollinations API](https://gen.pollinations.ai/docs)
29
31
  - **ComfyUI + Comfy MCP**。开启开关后,在「图片生成」中启动下载,安装 ComfyUI 和官方 Comfy MCP。安装支持 Apple 芯片的 macOS 14 或更新版本、64 位 Windows,以及 glibc 2.28 或更新版本的 x86-64 Linux。安装需要 Git、带 `venv` 和 `pip` 的 Python 3.11–3.13、网络连接、至少 8 GB 内存和 16 GiB 可用磁盘空间。建议使用兼容的 Apple 或 NVIDIA GPU,CPU 生图可能需要几分钟。随附的 SD 1.5 工作流默认在本地生成约 512 × 512 像素的草图,细小文字和写实效果有限。本地生成无需 Comfy 账号或积分。[Comfy MCP](https://github.com/Comfy-Org/comfy-mcp) · [模型与许可](https://huggingface.co/Comfy-Org/stable-diffusion-v1-5-archive)
30
32
 
33
+ 仅开启 ComfyUI 不会开始下载,安装提供进度和取消操作。Apple 芯片 Mac 已实测出图,Windows 和 Linux 安装尚未实机验证。免费档和服务可用性可能改变。
34
+
31
35
  关闭 ComfyUI 开关后,本地生图停用,已下载的文件保留供下次使用。FPS 通过官方 MCP 运行入门工作流,会话中只开放生图功能。
32
36
 
33
37
  在「图片生成」设置中,可将 CogView-3-Flash 和 Pollinations 的 Key 保存至 DSH 的凭证存储。也可以在启动 DSH 的环境中设置 `FPS_COGVIEW_API_KEY` 或 `POLLINATIONS_API_KEY`。各服务使用自己的 Key。
package/locale/en.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "meta": {
3
3
  "title": "Four-pointed star",
4
- "description": "A DeepSeek Harness workspace with session outputs, tool summaries, attachment drafts, provider usage, vision fallback, and optional cloud and local image generation.",
4
+ "description": "A DeepSeek Harness conversation workbench with long-task status, session outputs, tool summaries, persistent attachment drafts, native voice integration, provider usage, compatibility checks, vision fallback, and optional image generation.",
5
5
  "detail": "locale/detail.en.md"
6
6
  }
7
7
  }
package/locale/zh.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "meta": {
3
3
  "title": "Four-pointed star",
4
- "description": "DeepSeek Harness 会话工作台,支持会话产物、工具摘要、附件草稿、服务商用量、纯文本模型识图,以及可选的云端和本地生图。",
4
+ "description": "DeepSeek Harness 会话工作台,支持长任务状态、会话产物、工具摘要、附件持久化、原生语音接入、服务商用量、兼容性自检、识图转接和可选生图。",
5
5
  "detail": "locale/detail.zh.md"
6
6
  }
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-fps-workbench",
3
- "version": "0.1.77",
4
- "description": "Session outputs, tool summaries, attachment drafts, provider usage, and optional image tools for DeepSeek Harness.",
3
+ "version": "0.1.79",
4
+ "description": "A DSH conversation workbench with long-task status, outputs, tool summaries, persistent attachment drafts, usage, compatibility checks, and optional image tools.",
5
5
  "author": "Blacstar7",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -9,7 +9,11 @@
9
9
  "url": "git+https://github.com/Blacstar7/dsh-fps-workbench.git"
10
10
  },
11
11
  "homepage": "https://github.com/Blacstar7/dsh-fps-workbench#readme",
12
- "keywords": ["dsh-plugin", "deepseek-harness", "workbench"],
12
+ "keywords": [
13
+ "dsh-plugin",
14
+ "deepseek-harness",
15
+ "workbench"
16
+ ],
13
17
  "engines": {
14
18
  "dsh": ">=0.2.2-rc.1"
15
19
  },
@@ -34,7 +38,10 @@
34
38
  "icon.svg",
35
39
  "README.md",
36
40
  "README.zh.md",
37
- "CHANGELOG.md"
41
+ "CHANGELOG.md",
42
+ "screenshots.json",
43
+ "docs/screenshots/en/*.jpg",
44
+ "docs/screenshots/zh/*.jpg"
38
45
  ],
39
46
  "dsh": {
40
47
  "bundle": {
package/provider-usage.js CHANGED
@@ -11,6 +11,8 @@ const KIMI_WINDOWS = [
11
11
  ['limit_month_total', 'monthTotal'],
12
12
  ];
13
13
  const USER_AGENT = 'DeepSeek-Harness-Claude-Workbench';
14
+ const OPENAI_ORGANIZATION_URL = 'https://api.openai.com/v1/organization';
15
+ const OPENAI_USAGE_DAYS = 7;
14
16
  const DREAMINA_CREDIT_CYCLE_MS = 30 * 24 * 60 * 60 * 1000;
15
17
  const execFileAsync = promisify(execFile);
16
18
 
@@ -119,6 +121,38 @@ function openRouterUsage(payload) {
119
121
  return charges.length ? { charges } : null;
120
122
  }
121
123
 
124
+ function openAiUsageRows(payload) {
125
+ if (!Array.isArray(payload?.data) || payload.has_more
126
+ || payload.data.some((bucket) => !Array.isArray(bucket?.results))) return null;
127
+ return payload.data.flatMap((bucket) => bucket.results);
128
+ }
129
+
130
+ function openAiCosts(payload) {
131
+ const rows = openAiUsageRows(payload);
132
+ if (!rows) return null;
133
+ const totals = new Map();
134
+ for (const { amount } of rows) {
135
+ const cost = money(amount?.currency?.toUpperCase(), number(amount?.value));
136
+ if (!cost) return null;
137
+ totals.set(cost.currency, (totals.get(cost.currency) ?? 0) + cost.amount);
138
+ }
139
+ const organizationSpend = Array.from(totals, ([currency, amount]) => ({ currency, amount }));
140
+ return organizationSpend.length ? { organizationSpend } : null;
141
+ }
142
+
143
+ function openAiTokens(payload) {
144
+ const rows = openAiUsageRows(payload);
145
+ if (!rows) return null;
146
+ let organizationTokens = 0;
147
+ for (const row of rows) {
148
+ const input = number(row?.input_tokens);
149
+ const output = number(row?.output_tokens);
150
+ if (input === null || output === null || input < 0 || output < 0) return null;
151
+ organizationTokens += input + output;
152
+ }
153
+ return { organizationTokens };
154
+ }
155
+
122
156
  function adapterFor(baseURL) {
123
157
  if (typeof baseURL !== 'string') return null;
124
158
  let url;
@@ -238,6 +272,32 @@ async function queryUsage({ id, adapter, key }, signal, request) {
238
272
  }
239
273
  }
240
274
 
275
+ async function openAiOrganizationUsage(credentials, ref, signal, request) {
276
+ if (typeof ref !== 'string') return null;
277
+ const key = await resolveKey(credentials, { ref }).catch(() => null);
278
+ if (!key) return null;
279
+
280
+ const daySeconds = 24 * 60 * 60;
281
+ const now = Math.floor(Date.now() / 1000);
282
+ const today = Math.floor(now / daySeconds) * daySeconds;
283
+ const params = new URLSearchParams({
284
+ start_time: String(today - (OPENAI_USAGE_DAYS - 1) * daySeconds),
285
+ end_time: String(now),
286
+ bucket_width: '1d',
287
+ limit: String(OPENAI_USAGE_DAYS),
288
+ });
289
+ const targets = [
290
+ { path: 'costs', parse: openAiCosts },
291
+ { path: 'usage/completions', parse: openAiTokens },
292
+ ];
293
+ const [costs, tokens] = await Promise.all(targets.map(({ path, parse }) =>
294
+ queryUsage({
295
+ id: 'openai-organization', key,
296
+ adapter: { name: 'OpenAI', url: `${OPENAI_ORGANIZATION_URL}/${path}?${params}`, parse },
297
+ }, signal, request)));
298
+ return costs || tokens ? { ...costs, ...tokens } : null;
299
+ }
300
+
241
301
  async function readLocalSettings() {
242
302
  try {
243
303
  const directory = process.env.DSH_HOME || join(homedir(), '.dsh');
@@ -296,6 +356,10 @@ export async function providerUsage(ctx, signal, { request = fetch, localSetting
296
356
  seen.set(url, keys);
297
357
  return [queryUsage(target, signal, request)];
298
358
  });
299
- const sections = (await Promise.all([...jobs, dreaminaUsage(local?.dreamina, signal)])).filter(Boolean);
359
+ const sections = (await Promise.all([
360
+ ...jobs,
361
+ openAiOrganizationUsage(credentials, local?.openai?.adminKeyRef, signal, request),
362
+ dreaminaUsage(local?.dreamina, signal),
363
+ ])).filter(Boolean);
300
364
  return sections;
301
365
  }
@@ -0,0 +1,10 @@
1
+ [
2
+ "docs/screenshots/en/01-workspace.jpg",
3
+ "docs/screenshots/en/02-tasks.jpg",
4
+ "docs/screenshots/en/03-preview.jpg",
5
+ "docs/screenshots/en/04-drafts.jpg",
6
+ "docs/screenshots/en/05-image-tools.jpg",
7
+ "docs/screenshots/en/06-compatibility.jpg",
8
+ "docs/screenshots/zh/01-workspace.jpg",
9
+ "docs/screenshots/zh/04-drafts.jpg"
10
+ ]