@lsfcy/dsh-composer-predictions 0.0.0-stage → 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 niujianya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,71 @@
1
+ # dsh-composer-predictions
2
+
3
+ [![CI](https://github.com/lsfcy/dsh-composer-predictions/actions/workflows/ci.yml/badge.svg)](https://github.com/lsfcy/dsh-composer-predictions/actions/workflows/ci.yml)
4
+
5
+ Dim next-message suggestions in the DeepSeek Harness composer after a turn settles.
6
+ **Tab** accepts the suggestion into the draft; **Esc** or typing dismisses it. Nothing is sent.
7
+
8
+ English | [中文](README.md) · [Live demo](https://lsfcy.github.io/dsh-composer-predictions/demo/dsh.html?lang=en)
9
+
10
+ ## Example
11
+
12
+ The assistant finishes with "All 12 tests pass." The empty composer then shows, dimmed:
13
+
14
+ > Want me to commit this change? I can write the message.
15
+
16
+ Press Tab and it becomes an editable draft. Press Esc, or start typing, and it disappears.
17
+
18
+ ![Composer prediction: ghost appears, Tab accepts](https://raw.githubusercontent.com/lsfcy/dsh-composer-predictions/main/demo/demo-en.gif)
19
+
20
+ ## Install
21
+
22
+ DSH Web / desktop only (0.2.x). It does not work in other agents or harnesses.
23
+
24
+ **Option 1 (recommended, inside a DSH session)**: ask the agent to run
25
+
26
+ ```
27
+ plugin_manager action: install_bundle
28
+ target: @lsfcy/dsh-composer-predictions
29
+ ```
30
+
31
+ It applies without a restart (refresh the page if the UI does not update).
32
+
33
+ **Option 2 (terminal)**:
34
+
35
+ ```bash
36
+ dsh plugin --profile desktop add @lsfcy/dsh-composer-predictions
37
+ ```
38
+
39
+ Restart DSH afterwards. The desktop app uses `desktop`; other entrypoints use their profile under `~/.dsh/profiles`, e.g. `web`. To pin a version without npm:
40
+ `dsh plugin --profile desktop add git+https://github.com/lsfcy/dsh-composer-predictions.git#v0.1.1`.
41
+
42
+ ## Config
43
+
44
+ **Settings → 输入框预测 / Composer prediction**:
45
+
46
+ | Key | Default | Meaning |
47
+ | --- | --- | --- |
48
+ | `enabled` | `true` | Master switch: off stops requests and hides the ghost. |
49
+ | `provider` | auto | Empty uses the provider you are currently using. |
50
+ | `model` | auto | Empty uses the cheapest model on that provider. |
51
+ | `reasoningEffort` | auto | Empty uses the cheapest effort the model supports. |
52
+
53
+ The same keys work as the bundle row's `config` in a profile patch.
54
+
55
+ ## How it works
56
+
57
+ 1. The host reads the session's real user/assistant messages, keeps the last 12, and clips them to 6,000 characters.
58
+ 2. It only predicts after a completed turn that ended on an assistant reply.
59
+ 3. One cheap model call returns a single line (≤160 characters), cached per session content for 30 minutes.
60
+ 4. The client paints it as ghost text; Tab writes it into the draft.
61
+
62
+ ## Cost
63
+
64
+ One generation uses roughly 2–3k tokens (system prompt + transcript + output capped at 512) on the cheapest model at the lowest reasoning effort. Cache hits are free, and aborted turns never call the model.
65
+
66
+ ## Limits
67
+
68
+ - It is a guess, not memory: no retrieval, no long-term profile, no knowledge beyond the recent transcript.
69
+ - Only after successful turns; a suggestion never sends itself.
70
+ - Cheap models can be bland or wrong. Pin a stronger model in Config if you care more about quality.
71
+ - One line only, no multi-step plans.
package/README.md CHANGED
@@ -1,3 +1,72 @@
1
- # Temporary Holding Version
1
+ # dsh-composer-predictions
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![CI](https://github.com/lsfcy/dsh-composer-predictions/actions/workflows/ci.yml/badge.svg)](https://github.com/lsfcy/dsh-composer-predictions/actions/workflows/ci.yml)
4
+
5
+ 给 DeepSeek Harness 的输入框补上“下一句预测”:一轮对话结束后,在空的输入框里用灰字显示
6
+ 你接下来可能发送的消息。**Tab** 填入草稿,**Esc** 或开始打字即忽略。不会自动发送。
7
+
8
+ [English](README.en.md) | 中文 · [在线试玩](https://lsfcy.github.io/dsh-composer-predictions/demo/dsh.html)
9
+
10
+ ## 示例
11
+
12
+ 助手刚说完「测试全部通过」,空输入框里出现灰字:
13
+
14
+ > 顺手把这次改动提交了吗?提交信息我一起写好
15
+
16
+ 按 Tab,它变成可编辑的草稿;按 Esc 或直接打字,它消失。
17
+
18
+ ![灰字预测:出现、Tab 接受](https://raw.githubusercontent.com/lsfcy/dsh-composer-predictions/main/demo/demo-zh.gif)
19
+
20
+ ## 安装
21
+
22
+ 仅适用于 DSH 的 Web / 桌面端(0.2.x),不能用于其他 agent/harness。
23
+
24
+ **方式一(推荐,已在 DSH 会话里)**:让 agent 执行
25
+
26
+ ```
27
+ plugin_manager action: install_bundle
28
+ target: @lsfcy/dsh-composer-predictions
29
+ ```
30
+
31
+ 即时生效,不用重启(页面没更新就刷新一次)。
32
+
33
+ **方式二(终端)**:
34
+
35
+ ```bash
36
+ dsh plugin --profile desktop add @lsfcy/dsh-composer-predictions
37
+ ```
38
+
39
+ 装完重启 DSH。桌面端 profile 是 `desktop`;其他入口用 `~/.dsh/profiles` 里对应的名字,如 `web`。不想走 npm 时,也可以用固定版本:
40
+ `dsh plugin --profile desktop add git+https://github.com/lsfcy/dsh-composer-predictions.git#v0.1.1`。
41
+
42
+ ## 配置
43
+
44
+ **设置 → 输入框预测**:
45
+
46
+ | 配置 | 默认 | 说明 |
47
+ | --- | --- | --- |
48
+ | `enabled` | `true` | 总开关:关闭后不再请求,也不显示灰字。 |
49
+ | `provider` | 自动 | 留空用你当前选中的 provider。 |
50
+ | `model` | 自动 | 留空用该 provider 下最便宜的型号。 |
51
+ | `reasoningEffort` | 自动 | 留空用模型支持的最省推理档。 |
52
+
53
+ 这些键同样可以写在 profile patch 的 bundle row `config` 里。
54
+
55
+ ## 原理
56
+
57
+ 1. 宿主读取会话里真人的 user/assistant 消息,只取最近 12 条,压到 6000 字符。
58
+ 2. 只在一轮**成功结束**、且最后一条是 assistant 回复时预测。
59
+ 3. 调一次便宜模型,取一行(≤160 字符),按会话内容缓存 30 分钟。
60
+ 4. 客户端把它画成灰字;Tab 写入输入框。
61
+
62
+ ## 成本
63
+
64
+ 单次生成约 2–3k token(system 提示词 + 转录 + 输出上限 512),走最便宜型号和最低推理档。
65
+ 命中缓存不产生费用;被中止的轮次不会调用模型。
66
+
67
+ ## 限制
68
+
69
+ - 它只是猜测,没有记忆:不做检索,不读长期画像,只看最近这段转录。
70
+ - 只在成功轮次后出现,且永不自动发送。
71
+ - 便宜模型可能平淡或猜错;在意质量可在配置里固定更强的模型。
72
+ - 只给一行,不会给多步计划。
package/build.mjs ADDED
@@ -0,0 +1,26 @@
1
+ // Concatenate the two browser sources into the lazy-CJS bundle protocol the
2
+ // DSH client module loader expects (window.__ModuleLoader__.load). No bundler,
3
+ // no dependencies: src/ghost.js and src/main.js are plain scripts that run
4
+ // inside the factory scope, so `require` there resolves against the platform
5
+ // module table (react, react/jsx-runtime, ...).
6
+ import { readFileSync, writeFileSync } from 'node:fs'
7
+
8
+ const packageJson = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'))
9
+ const ghost = readFileSync(new URL('./src/ghost.js', import.meta.url), 'utf8')
10
+ const main = readFileSync(new URL('./src/main.js', import.meta.url), 'utf8')
11
+
12
+ const bundle = `// GENERATED FILE — edit src/ghost.js or src/main.js and run: node build.mjs
13
+ window.__ModuleLoader__.load({
14
+ id: ${JSON.stringify(packageJson.name)},
15
+ factory: (require) => {
16
+ var module = { exports: {} }
17
+ var exports = module.exports
18
+ ${ghost}
19
+ ${main}
20
+ return module.exports
21
+ },
22
+ })
23
+ `
24
+
25
+ writeFileSync(new URL('./client.js', import.meta.url), bundle)
26
+ console.log('client.js written (' + bundle.length + ' bytes)')