@rol1n/pi-kit 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/LICENSE +21 -0
- package/README.md +87 -50
- package/README_zh.md +136 -0
- package/ask-u-questions/README.md +26 -0
- package/{extensions/ask-u-questions → ask-u-questions}/dialog-ui.ts +23 -0
- package/{extensions/ask-u-questions → ask-u-questions}/index.ts +9 -5
- package/{extensions/ask-u-questions → ask-u-questions}/multi-choice.ts +1 -3
- package/{extensions/ask-u-questions → ask-u-questions}/single-choice.ts +1 -3
- package/{extensions/ask-u-questions → ask-u-questions}/tool-renderers.ts +1 -3
- package/ask-u-questions/types.ts +192 -0
- package/continue-signal/README.md +20 -0
- package/{extensions/continue-signal → continue-signal}/index.ts +21 -3
- package/custom-providers/README.md +20 -0
- package/{extensions/custom-providers → custom-providers}/index.ts +16 -2
- package/image-generate/README.md +25 -0
- package/{extensions/image-generate → image-generate}/index.ts +22 -2
- package/{extensions/image-generate → image-generate}/model-selector.ts +1 -1
- package/memory-log/README.md +121 -0
- package/{extensions/memory-log → memory-log}/config.ts +1 -1
- package/{extensions/memory-log → memory-log}/hooks/compaction-hook.ts +58 -15
- package/memory-log/hooks/compaction-trigger.ts +87 -0
- package/{extensions/memory-log → memory-log}/hooks/observer-trigger.ts +2 -1
- package/{extensions/memory-log → memory-log}/index.ts +4 -0
- package/{extensions/memory-log → memory-log}/ledger/index.ts +1 -0
- package/memory-log/ledger/recall.ts +111 -0
- package/{extensions/memory-log → memory-log}/ledger/render.ts +3 -1
- package/{extensions/memory-log → memory-log}/ledger/serialize.ts +2 -4
- package/{extensions/memory-log → memory-log}/ledger/types.ts +4 -1
- package/{extensions/memory-log → memory-log}/runtime.ts +0 -5
- package/memory-log/tools/recall.ts +60 -0
- package/model-vision/README.md +22 -0
- package/{extensions/multi-harness → multi-harness}/README.md +3 -3
- package/oai-subquota/README.md +22 -0
- package/{extensions/oai-subquota → oai-subquota}/index.ts +16 -6
- package/{extensions/oai-subquota → oai-subquota}/snapshot.ts +127 -1
- package/{extensions/oai-subquota → oai-subquota}/ui.ts +1 -1
- package/package.json +46 -46
- package/prompt-snipaste/README.md +27 -0
- package/{extensions/prompt-snipaste → prompt-snipaste}/renderers.ts +0 -1
- package/{extensions/prompt-snipaste → prompt-snipaste}/snippets.ts +5 -2
- package/{extensions/prompt-snipaste → prompt-snipaste}/types.ts +0 -1
- package/screenshot/README.md +14 -0
- package/srp-theme/README.md +18 -0
- package/{extensions/srp-theme → srp-theme}/footer.ts +0 -1
- package/{extensions/srp-theme → srp-theme}/tps-meter.ts +0 -1
- package/{extensions/subagent → subagent}/README.md +1 -1
- package/tui-asr/README.md +21 -0
- package/{extensions/tui-asr → tui-asr}/dictation.ts +70 -3
- package/{extensions/tui-asr → tui-asr}/index.ts +2 -2
- package/{extensions/tui-asr → tui-asr}/input.ts +30 -1
- package/{extensions/tui-asr → tui-asr}/model-selector.ts +1 -1
- package/web-reach/README.md +19 -0
- package/windows-wheel-fix/README.md +12 -0
- package/extensions/ask-u-questions/README.md +0 -32
- package/extensions/ask-u-questions/answers.ts +0 -53
- package/extensions/ask-u-questions/results.ts +0 -83
- package/extensions/ask-u-questions/schema.ts +0 -17
- package/extensions/ask-u-questions/types.ts +0 -45
- package/extensions/ask-u-questions/ui-lock.ts +0 -24
- package/extensions/continue-signal/README.md +0 -28
- package/extensions/continue-signal/renderer.ts +0 -21
- package/extensions/custom-providers/README.md +0 -28
- package/extensions/image-generate/README.md +0 -29
- package/extensions/image-generate/models.ts +0 -19
- package/extensions/memory-log/README.md +0 -54
- package/extensions/memory-log/hooks/compaction-trigger.ts +0 -160
- package/extensions/model-vision/README.md +0 -28
- package/extensions/oai-subquota/README.md +0 -30
- package/extensions/oai-subquota/api.ts +0 -27
- package/extensions/oai-subquota/auth.ts +0 -34
- package/extensions/oai-subquota/cache.ts +0 -30
- package/extensions/oai-subquota/types.ts +0 -40
- package/extensions/prompt-snipaste/README.md +0 -33
- package/extensions/screenshot/README.md +0 -25
- package/extensions/srp-theme/README.md +0 -24
- package/extensions/subagent/skills/subagent/SKILL.md +0 -70
- package/extensions/tui-asr/README.md +0 -28
- package/extensions/tui-asr/audio.ts +0 -40
- package/extensions/tui-asr/clipboard.ts +0 -30
- package/extensions/tui-asr/providers.ts +0 -25
- package/extensions/web-reach/README.md +0 -37
- package/extensions/web-reach/html.ts +0 -83
- package/extensions/web-reach/index.ts +0 -82
- package/extensions/web-reach/page.ts +0 -132
- package/extensions/web-reach/pdf.ts +0 -42
- package/extensions/web-reach/reader.ts +0 -42
- package/extensions/web-reach/rsc.ts +0 -161
- package/extensions/web-reach/search.ts +0 -85
- package/extensions/web-reach/transport.ts +0 -35
- package/extensions/windows-wheel-fix/README.md +0 -21
- /package/{extensions/custom-providers → custom-providers}/asr/handlers/dashscope.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/asr/index.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/asr/models.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/asr/types.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/chat/index.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/chat/magpie.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/chat/models.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/classifier/index.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/classifier/models.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/image/handlers/dashscope.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/image/handlers/openrouter.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/image/index.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/image/models.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/image/types.ts +0 -0
- /package/{extensions/custom-providers → custom-providers}/types.ts +0 -0
- /package/{extensions/image-generate → image-generate}/files.ts +0 -0
- /package/{extensions/memory-log → memory-log}/agent/consolidator/prompt.ts +0 -0
- /package/{extensions/memory-log → memory-log}/agent/consolidator/tools.ts +0 -0
- /package/{extensions/memory-log → memory-log}/agent/cost.ts +0 -0
- /package/{extensions/memory-log → memory-log}/agent/index.ts +0 -0
- /package/{extensions/memory-log → memory-log}/agent/observer/prompt.ts +0 -0
- /package/{extensions/memory-log → memory-log}/agent/observer/tool.ts +0 -0
- /package/{extensions/memory-log → memory-log}/commands/compact.ts +0 -0
- /package/{extensions/memory-log → memory-log}/commands/consolidate.ts +0 -0
- /package/{extensions/memory-log → memory-log}/commands/status.ts +0 -0
- /package/{extensions/memory-log → memory-log}/debug-log.ts +0 -0
- /package/{extensions/memory-log → memory-log}/hooks/consolidator-trigger.ts +0 -0
- /package/{extensions/memory-log → memory-log}/ids.ts +0 -0
- /package/{extensions/memory-log → memory-log}/ledger/fold.ts +0 -0
- /package/{extensions/memory-log → memory-log}/ledger/pool.ts +0 -0
- /package/{extensions/memory-log → memory-log}/ledger/progress.ts +0 -0
- /package/{extensions/memory-log → memory-log}/ledger/projection.ts +0 -0
- /package/{extensions/memory-log → memory-log}/memory/index-render.ts +0 -0
- /package/{extensions/memory-log → memory-log}/memory/paths.ts +0 -0
- /package/{extensions/memory-log → memory-log}/memory/session.ts +0 -0
- /package/{extensions/memory-log → memory-log}/spawn/launch.ts +0 -0
- /package/{extensions/memory-log → memory-log}/spawn/runs.ts +0 -0
- /package/{extensions/memory-log → memory-log}/tokens.ts +0 -0
- /package/{extensions/memory-log → memory-log}/ui/status-controller.ts +0 -0
- /package/{extensions/memory-log → memory-log}/ui/timeline.ts +0 -0
- /package/{extensions/multi-harness → multi-harness}/adapters.mjs +0 -0
- /package/{extensions/multi-harness → multi-harness}/harness-done.mjs +0 -0
- /package/{extensions/multi-harness → multi-harness}/index.ts +0 -0
- /package/{extensions/multi-harness → multi-harness}/ipc.mjs +0 -0
- /package/{extensions/multi-harness → multi-harness}/opencode-plugin.mjs +0 -0
- /package/{extensions/multi-harness → multi-harness}/process-runner.mjs +0 -0
- /package/{extensions/multi-harness → multi-harness}/turn-hook.mjs +0 -0
- /package/{extensions/multi-harness → multi-harness}/worker-bridge.ts +0 -0
- /package/{extensions/prompt-snipaste → prompt-snipaste}/index.ts +0 -0
- /package/{extensions/prompt-snipaste → prompt-snipaste}/menu.ts +0 -0
- /package/{prompts → prompt-snipaste/prompts}/ask-questions.md +0 -0
- /package/{prompts → prompt-snipaste/prompts}/delegate-exploration.md +0 -0
- /package/{prompts → prompt-snipaste/prompts}/diagnose-report.md +0 -0
- /package/{prompts → prompt-snipaste/prompts}/frontend-tech-preset.md +0 -0
- /package/{prompts → prompt-snipaste/prompts}/orchestrator-mode.md +0 -0
- /package/{prompts → prompt-snipaste/prompts}/session-kickoff.md +0 -0
- /package/{prompts → prompt-snipaste/prompts}/verify-not-assume.md +0 -0
- /package/{extensions/srp-theme → srp-theme}/index.ts +0 -0
- /package/{extensions/subagent → subagent}/bridge.ts +0 -0
- /package/{extensions/subagent → subagent}/index.ts +0 -0
- /package/{extensions/subagent → subagent}/mux.ts +0 -0
- /package/{extensions/subagent → subagent}/session.ts +0 -0
- /package/{extensions/subagent → subagent}/ui.ts +0 -0
- /package/{extensions/tui-asr → tui-asr}/status.ts +0 -0
- /package/{extensions/windows-wheel-fix → windows-wheel-fix}/index.ts +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RoL1n_SrP
|
|
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.md
CHANGED
|
@@ -1,99 +1,136 @@
|
|
|
1
1
|
# pi-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Modular extensions and prompt templates for the [Pi Coding Agent](https://pi.dev), published as the **`@rol1n/pi-kit`** bundle and as standalone **`@rol1n/<extension>`** packages.
|
|
4
|
+
|
|
5
|
+
<p align="left">
|
|
6
|
+
<b>English</b> •
|
|
7
|
+
<a href="README_zh.md"><b>中文说明</b></a>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/@rol1n/pi-kit)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
|
|
13
|
+
---
|
|
4
14
|
|
|
5
15
|
## Install
|
|
6
16
|
|
|
17
|
+
Install the default bundle:
|
|
18
|
+
|
|
7
19
|
```sh
|
|
8
20
|
pi install npm:@rol1n/pi-kit
|
|
9
21
|
```
|
|
10
22
|
|
|
23
|
+
Or install any standalone extension individually:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pi install npm:@rol1n/memory-log
|
|
27
|
+
pi install npm:@rol1n/subagent
|
|
28
|
+
pi install npm:@rol1n/multi-harness
|
|
29
|
+
```
|
|
30
|
+
|
|
11
31
|
Install from GitHub or a local checkout during development:
|
|
12
32
|
|
|
13
33
|
```sh
|
|
14
|
-
pi install
|
|
34
|
+
pi install https://github.com/RolinShmily/pi-kit
|
|
15
35
|
pi install /absolute/path/to/pi-kit
|
|
16
36
|
```
|
|
17
37
|
|
|
18
|
-
Update
|
|
38
|
+
Update installed packages:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
pi update npm:@rol1n/pi-kit
|
|
42
|
+
pi update --extensions
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
19
46
|
|
|
20
47
|
## Extensions
|
|
21
48
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
|
25
|
-
|
|
|
26
|
-
| [
|
|
27
|
-
| [
|
|
28
|
-
| [
|
|
29
|
-
| [
|
|
30
|
-
| [
|
|
31
|
-
| [
|
|
32
|
-
| [
|
|
33
|
-
| [
|
|
34
|
-
| [
|
|
35
|
-
| [
|
|
36
|
-
| [
|
|
37
|
-
| [
|
|
38
|
-
| [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Every extension uses the same directory layout:
|
|
43
|
-
|
|
44
|
-
```text
|
|
45
|
-
extensions/<name>/
|
|
46
|
-
├── index.ts # Pi entrypoint and registration
|
|
47
|
-
├── README.md # Package documentation
|
|
48
|
-
└── ... # Modules grouped by responsibility
|
|
49
|
-
```
|
|
49
|
+
Each top-level directory is a self-contained extension (`<name>/index.ts` + `README.md`). Detailed commands, parameters, and settings are documented in each extension's README:
|
|
50
|
+
|
|
51
|
+
| Extension | Description | In `@rol1n/pi-kit` | Standalone Package |
|
|
52
|
+
| :--- | :--- | :---: | :--- |
|
|
53
|
+
| [ask-u-questions](ask-u-questions/README.md) | Interactive single-choice, multi-choice, and text dialogs | Yes | `@rol1n/ask-u-questions` |
|
|
54
|
+
| [continue-signal](continue-signal/README.md) | Resume an idle agent via `/continue` or `Alt+C` | Yes | `@rol1n/continue-signal` |
|
|
55
|
+
| [custom-providers](custom-providers/README.md) | Additional model providers and gateway registration | Yes | `@rol1n/custom-providers` |
|
|
56
|
+
| [image-generate](image-generate/README.md) | Image generation tool and `/image-generate` model selector | Yes | `@rol1n/image-generate` |
|
|
57
|
+
| [memory-log](memory-log/README.md) | Tiered asynchronous observational memory and instant compaction | Yes | `@rol1n/memory-log` |
|
|
58
|
+
| [model-vision](model-vision/README.md) | Image understanding and OCR tool (`model_vision`) | No | `@rol1n/model-vision` |
|
|
59
|
+
| [multi-harness](multi-harness/README.md) | Delegate tasks across `pi`, `codex`, `claude`, and `opencode` | Yes | `@rol1n/multi-harness` |
|
|
60
|
+
| [oai-subquota](oai-subquota/README.md) | OpenAI Codex subscription quota monitor and statusline | Yes | `@rol1n/oai-subquota` |
|
|
61
|
+
| [prompt-snipaste](prompt-snipaste/README.md) | Prompt snippet selector (`/snipaste`, `Alt+S`) with 7 built-in prompts | Yes | `@rol1n/prompt-snipaste` |
|
|
62
|
+
| [screenshot](screenshot/README.md) | Insert the latest Windows/WSL screenshot path (`/screenshot`) | No | `@rol1n/screenshot` |
|
|
63
|
+
| [srp-theme](srp-theme/README.md) | Last-prompt preview widget and real-time streaming TPS meter | Yes | `@rol1n/srp-theme` |
|
|
64
|
+
| [subagent](subagent/README.md) | Delegate tasks to parallel Pi workers in tmux/Zellij or background processes | Yes | `@rol1n/subagent` |
|
|
65
|
+
| [tui-asr](tui-asr/README.md) | Streaming voice dictation via Aliyun DashScope ASR (`/asr`, `Alt+M`) | Yes | `@rol1n/tui-asr` |
|
|
66
|
+
| [web-reach](web-reach/README.md) | Keyless Exa MCP web search and multi-tier page extraction | No | `@rol1n/web-reach` |
|
|
67
|
+
| [windows-wheel-fix](windows-wheel-fix/README.md) | Windows ConPTY / Zellij mouse-wheel reporting fix | Yes (Windows) | `@rol1n/windows-wheel-fix` |
|
|
50
68
|
|
|
51
|
-
|
|
69
|
+
> Standalone packages with cross-extension dependencies (`tui-asr` / `image-generate` -> `@rol1n/custom-providers`, `multi-harness` -> `@rol1n/subagent`) declare standard npm `dependencies` and resolve them automatically on install.
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
---
|
|
54
72
|
|
|
55
|
-
|
|
73
|
+
## Resource Selection
|
|
56
74
|
|
|
57
|
-
Use `pi config` or
|
|
75
|
+
`@rol1n/pi-kit` exposes 12 extension entrypoints and the 7 prompt templates bundled in [prompt-snipaste/prompts](prompt-snipaste/prompts/). Use `pi config` or filter loaded resources in `settings.json`:
|
|
58
76
|
|
|
59
77
|
```json
|
|
60
78
|
{
|
|
61
79
|
"packages": [
|
|
62
80
|
{
|
|
63
81
|
"source": "npm:@rol1n/pi-kit",
|
|
64
|
-
"extensions": ["
|
|
65
|
-
"prompts": ["prompts/diagnose-report.md"]
|
|
82
|
+
"extensions": ["**/*.ts", "!tui-asr/**"],
|
|
83
|
+
"prompts": ["prompt-snipaste/prompts/diagnose-report.md"]
|
|
66
84
|
}
|
|
67
85
|
]
|
|
68
86
|
}
|
|
69
87
|
```
|
|
70
88
|
|
|
71
|
-
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Development & Publishing
|
|
72
92
|
|
|
73
|
-
|
|
93
|
+
[kit.config.json](kit.config.json) controls bundle selection (`bundle`), inter-extension dependencies (`deps`), and release versions. The top-level `version` belongs to `@rol1n/pi-kit`; each extension can set its own `version`, otherwise it inherits the top-level version. Set explicit extension versions to release the kit and standalone packages independently.
|
|
74
94
|
|
|
75
|
-
|
|
95
|
+
### Automated releases
|
|
96
|
+
|
|
97
|
+
1. Update the code and bump the relevant version(s) in `kit.config.json`.
|
|
98
|
+
2. Push to `main` with changes to `kit.config.json` or `package.json`, or manually run **Publish to npm** in GitHub Actions. Changes to the packaging script or workflow also trigger a release run.
|
|
99
|
+
3. CI runs the same pipeline for both triggers:
|
|
76
100
|
|
|
77
101
|
```sh
|
|
78
102
|
npm run manifest
|
|
79
103
|
npm run check
|
|
80
|
-
npm
|
|
81
|
-
npm publish --access public
|
|
104
|
+
npm run publish:ci -- all
|
|
82
105
|
```
|
|
83
106
|
|
|
84
|
-
|
|
107
|
+
The workflow in [`.github/workflows/publish.yml`](.github/workflows/publish.yml) generates `package.json`, validates the layout, then publishes all standalone extensions in dependency order, followed by the kit. Already-published versions are skipped; versions are never bumped automatically. `bundle: false` excludes an extension from the kit, not from standalone publishing. Publishing runs do not overlap, and a new run does not cancel an active release. Code-only pushes do not trigger publishing.
|
|
108
|
+
|
|
109
|
+
You do not need to run `manifest` or publish locally for an npm release. CI generates the manifest only in its checkout and does not commit it back. For local or Git installs, run `npm run manifest` and commit the generated `package.json` when changing bundle selection or versions so the repository manifest stays in sync.
|
|
110
|
+
|
|
111
|
+
### Local development and manual publishing
|
|
85
112
|
|
|
86
113
|
```sh
|
|
114
|
+
# Sync the local manifest and validate all extensions
|
|
115
|
+
npm run manifest
|
|
116
|
+
npm run check
|
|
117
|
+
|
|
118
|
+
# Stage a standalone package into dist/<id>
|
|
87
119
|
npm run prepare:extension -- memory-log
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
npm publish --
|
|
120
|
+
|
|
121
|
+
# Optional local release; also accepts extensions, kit, or a single extension ID
|
|
122
|
+
npm run publish:ci -- all
|
|
91
123
|
```
|
|
92
124
|
|
|
93
|
-
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Acknowledgements
|
|
128
|
+
|
|
129
|
+
- [elpapi42/pi-observational-memory](https://github.com/elpapi42/pi-observational-memory) — Observational memory architecture and inspiration for [`memory-log`](memory-log/README.md).
|
|
130
|
+
- [earendil-works/pi](https://github.com/earendil-works/pi) — The Pi coding agent harness and SDK.
|
|
94
131
|
|
|
95
|
-
|
|
132
|
+
---
|
|
96
133
|
|
|
97
|
-
##
|
|
134
|
+
## License
|
|
98
135
|
|
|
99
|
-
|
|
136
|
+
[MIT](LICENSE) © RoL1n_SrP
|
package/README_zh.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# pi-kit
|
|
2
|
+
|
|
3
|
+
> 面向 [Pi Coding Agent](https://pi.dev) 的模块化扩展与提示词模板套件,支持作为 **`@rol1n/pi-kit`** 聚合包或 **`@rol1n/<extension>`** 独立包安装。
|
|
4
|
+
|
|
5
|
+
<p align="left">
|
|
6
|
+
<a href="README.md"><b>English</b></a> •
|
|
7
|
+
<b>中文说明</b>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/@rol1n/pi-kit)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 安装
|
|
16
|
+
|
|
17
|
+
安装默认聚合包:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
pi install npm:@rol1n/pi-kit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
或按需安装任意独立扩展包:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pi install npm:@rol1n/memory-log
|
|
27
|
+
pi install npm:@rol1n/subagent
|
|
28
|
+
pi install npm:@rol1n/multi-harness
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
开发期间也可直接从 GitHub 或本地目录安装:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pi install https://github.com/RolinShmily/pi-kit
|
|
35
|
+
pi install /absolute/path/to/pi-kit
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
更新已安装的包:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
pi update npm:@rol1n/pi-kit
|
|
42
|
+
pi update --extensions
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 扩展列表
|
|
48
|
+
|
|
49
|
+
仓库根目录下每个文件夹均为自包含扩展(`<name>/index.ts` + `README.md`)。各扩展的详细命令、参数与配置说明请参阅对应目录的 README:
|
|
50
|
+
|
|
51
|
+
| 扩展目录 | 功能简介 | 默认纳入 `pi-kit` | 独立 npm 包名 |
|
|
52
|
+
| :--- | :--- | :---: | :--- |
|
|
53
|
+
| [ask-u-questions](ask-u-questions/README.md) | 交互式单选、多选与自由文本提问弹窗(共享 UI 锁) | Yes | `@rol1n/ask-u-questions` |
|
|
54
|
+
| [continue-signal](continue-signal/README.md) | 通过 `/continue` 或 `Alt+C` 唤醒空闲智能体继续未完成任务 | Yes | `@rol1n/continue-signal` |
|
|
55
|
+
| [custom-providers](custom-providers/README.md) | 自定义模型服务商与网关(Magpie、智谱、阿里百炼等)注册 | Yes | `@rol1n/custom-providers` |
|
|
56
|
+
| [image-generate](image-generate/README.md) | OpenRouter / 百炼文生图与参考图生图工具及 `/image-generate` 模型选择器 | Yes | `@rol1n/image-generate` |
|
|
57
|
+
| [memory-log](memory-log/README.md) | 分层异步观察记忆系统与零模型阻塞的确定性秒级压缩 | Yes | `@rol1n/memory-log` |
|
|
58
|
+
| [model-vision](model-vision/README.md) | 本地与远程图片视觉理解、OCR 与 UI 诊断工具(`model_vision`) | No | `@rol1n/model-vision` |
|
|
59
|
+
| [multi-harness](multi-harness/README.md) | 跨 `pi`、`codex`、`claude`、`opencode` 的多 CLI 协同委派运行时 | Yes | `@rol1n/multi-harness` |
|
|
60
|
+
| [oai-subquota](oai-subquota/README.md) | OpenAI Codex 订阅额度(5h / 7d 窗口与重置时间)状态栏监控 | Yes | `@rol1n/oai-subquota` |
|
|
61
|
+
| [prompt-snipaste](prompt-snipaste/README.md) | 提示词片段选择器(`/snipaste`、`Alt+S`),内置 7 个常用提示词模板 | Yes | `@rol1n/prompt-snipaste` |
|
|
62
|
+
| [screenshot](screenshot/README.md) | 一键将最新 Windows / WSL 系统截图路径插入编辑器(`/screenshot`) | No | `@rol1n/screenshot` |
|
|
63
|
+
| [srp-theme](srp-theme/README.md) | 编辑器下方最近提问预览组件与实时流式 TPS 速率仪表 | Yes | `@rol1n/srp-theme` |
|
|
64
|
+
| [subagent](subagent/README.md) | 基于 tmux / Zellij 分屏或后台进程的并发 Pi 子智能体工具 | Yes | `@rol1n/subagent` |
|
|
65
|
+
| [tui-asr](tui-asr/README.md) | 基于阿里百炼 Paraformer 的终端实时流式语音听写(`/asr`、`Alt+M`) | Yes | `@rol1n/tui-asr` |
|
|
66
|
+
| [web-reach](web-reach/README.md) | 免 Key Exa MCP 网页搜索与多级网页正文提取(RSC / HTML / PDF / Jina) | No | `@rol1n/web-reach` |
|
|
67
|
+
| [windows-wheel-fix](windows-wheel-fix/README.md) | 修复 Windows ConPTY / Zellij 下鼠标滚轮被误转为上下方向键的问题 | Yes (仅 Windows) | `@rol1n/windows-wheel-fix` |
|
|
68
|
+
|
|
69
|
+
> 带有跨扩展依赖的独立包(`tui-asr` / `image-generate` 依赖 `@rol1n/custom-providers`,`multi-harness` 依赖 `@rol1n/subagent`)已声明标准 npm `dependencies`,单独安装时会自动拉取补全并激活所需依赖。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 资源按需筛选
|
|
74
|
+
|
|
75
|
+
`@rol1n/pi-kit` 默认导出 12 个扩展入口与 [prompt-snipaste/prompts](prompt-snipaste/prompts/) 下的 7 个提示词模板。可通过 `pi config` 或在 `settings.json` 中按需过滤:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"packages": [
|
|
80
|
+
{
|
|
81
|
+
"source": "npm:@rol1n/pi-kit",
|
|
82
|
+
"extensions": ["**/*.ts", "!tui-asr/**"],
|
|
83
|
+
"prompts": ["prompt-snipaste/prompts/diagnose-report.md"]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 构建与发布
|
|
92
|
+
|
|
93
|
+
[kit.config.json](kit.config.json) 统一管理聚合包选择(`bundle`)、扩展间的依赖关系(`deps`)与发布版本。顶层 `version` 属于 `@rol1n/pi-kit`;各扩展可以单独设置 `version`,未设置时继承顶层版本。为每个扩展显式设置版本即可让聚合包与独立包分别升级。
|
|
94
|
+
|
|
95
|
+
### 自动发布
|
|
96
|
+
|
|
97
|
+
1. 修改代码,并在 `kit.config.json` 中提升需要发布的包的版本。
|
|
98
|
+
2. 将包含 `kit.config.json` 或 `package.json` 变更的提交推送到 `main`,或在 GitHub Actions 手动运行 **Publish to npm**。修改打包脚本或工作流本身也会触发发布流程。
|
|
99
|
+
3. 自动和手动触发均执行同一条流水线:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
npm run manifest
|
|
103
|
+
npm run check
|
|
104
|
+
npm run publish:ci -- all
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
[`.github/workflows/publish.yml`](.github/workflows/publish.yml) 会生成 `package.json`、校验扩展布局,再按依赖顺序发布所有独立扩展,最后发布聚合包。已存在的版本自动跳过,不会自动提升版本号。`bundle: false` 只表示不纳入聚合包,不影响独立发布。发布流程不会并行执行,新触发的流程也不会取消正在进行的发布。仅修改扩展代码不会触发发布。
|
|
108
|
+
|
|
109
|
+
发布 npm 包无需本地运行 `manifest` 或 `publish`。CI 只在运行目录中生成清单,不会自动提交回仓库。若使用本地或 Git 安装,调整聚合包选择或版本后仍应运行 `npm run manifest` 并提交生成的 `package.json`,保持仓库清单同步。
|
|
110
|
+
|
|
111
|
+
### 本地开发与手动发布
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
# 同步本地清单并校验所有扩展
|
|
115
|
+
npm run manifest
|
|
116
|
+
npm run check
|
|
117
|
+
|
|
118
|
+
# 将单个扩展构建到 dist/<id>
|
|
119
|
+
npm run prepare:extension -- memory-log
|
|
120
|
+
|
|
121
|
+
# 可选的本地发布,也支持 extensions、kit 或单个扩展 ID
|
|
122
|
+
npm run publish:ci -- all
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 致谢
|
|
128
|
+
|
|
129
|
+
- [elpapi42/pi-observational-memory](https://github.com/elpapi42/pi-observational-memory) — [`memory-log`](memory-log/README.md) 的观察记忆架构灵感与上游基础。
|
|
130
|
+
- [earendil-works/pi](https://github.com/earendil-works/pi) — Pi Coding Agent 运行时与 SDK。
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 许可证
|
|
135
|
+
|
|
136
|
+
[MIT](LICENSE) © RoL1n_SrP
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# ask-u-questions
|
|
2
|
+
|
|
3
|
+
Interactive single-choice, multiple-choice, and free-text questions for Pi. Registers the `ask_user_question` tool and serializes dialogs through a shared UI lock.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pi install npm:@rol1n/ask-u-questions
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Also included in `@rol1n/pi-kit`.
|
|
12
|
+
|
|
13
|
+
## Use
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"question": "Which output format should I use?",
|
|
18
|
+
"options": [
|
|
19
|
+
{ "label": "Markdown (Recommended)", "value": "markdown" },
|
|
20
|
+
{ "label": "JSON", "value": "json" }
|
|
21
|
+
],
|
|
22
|
+
"multiSelect": false
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Omit `options` or pass `[]` for free-text input. Set `multiSelect: true` only when multiple choices are expected. `details` adds supporting context, and an `Other` option is provided automatically for choice questions.
|
|
@@ -55,3 +55,26 @@ export function addWrapped(
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
const SHARED_UI_LOCK_KEY = "__piSharedUiLock";
|
|
59
|
+
function getSharedUiLock(): { withLock<T>(fn: () => T | Promise<T>): Promise<T> } {
|
|
60
|
+
const g = globalThis as any;
|
|
61
|
+
if (!g[SHARED_UI_LOCK_KEY]) {
|
|
62
|
+
let chain: Promise<void> = Promise.resolve();
|
|
63
|
+
g[SHARED_UI_LOCK_KEY] = {
|
|
64
|
+
withLock<T>(fn: () => T | Promise<T>): Promise<T> {
|
|
65
|
+
const prev = chain;
|
|
66
|
+
let release: () => void;
|
|
67
|
+
chain = new Promise<void>((r) => {
|
|
68
|
+
release = r;
|
|
69
|
+
});
|
|
70
|
+
return prev.then(fn).finally(() => release!());
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return g[SHARED_UI_LOCK_KEY];
|
|
75
|
+
}
|
|
76
|
+
const sharedUiLock = getSharedUiLock();
|
|
77
|
+
|
|
78
|
+
export function withUILock<T>(fn: () => Promise<T>): Promise<T> {
|
|
79
|
+
return sharedUiLock.withLock(fn);
|
|
80
|
+
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/** Interactive questions, serialized through the shared dialog lock. */
|
|
2
2
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import {
|
|
4
|
+
AskUserQuestionParams,
|
|
5
|
+
buildResult,
|
|
6
|
+
cancelledResult,
|
|
7
|
+
normalizeOptions,
|
|
8
|
+
unavailableResult,
|
|
9
|
+
type AskUserQuestionMode,
|
|
10
|
+
} from "./types.ts";
|
|
11
|
+
import { withUILock } from "./dialog-ui.ts";
|
|
7
12
|
import { askSingleChoice } from "./single-choice.ts";
|
|
8
13
|
import { askMultiChoice } from "./multi-choice.ts";
|
|
9
|
-
import { withUILock } from "./ui-lock.ts";
|
|
10
14
|
import { questionRenderers } from "./tool-renderers.ts";
|
|
11
15
|
|
|
12
16
|
export type { AskOption, TextAnswer, OptionAnswer, OtherAnswer, AskAnswer, AskUserQuestionStatus, AskUserQuestionMode, AskUserQuestionResultDetails } from "./types.ts";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Editor, Key, matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
|
-
import type
|
|
4
|
-
import { getOtherLabel, isChineseContext, sortAnswers } from "./answers.ts";
|
|
3
|
+
import { getOtherLabel, isChineseContext, sortAnswers, type AskAnswer, type AskOption, type DisplayOption } from "./types.ts";
|
|
5
4
|
import { addWrapped, createEditorTheme } from "./dialog-ui.ts";
|
|
6
5
|
|
|
7
6
|
export async function askMultiChoice(
|
|
@@ -257,4 +256,3 @@ export async function askMultiChoice(
|
|
|
257
256
|
},
|
|
258
257
|
);
|
|
259
258
|
}
|
|
260
|
-
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Editor, Key, matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
3
|
-
import type
|
|
4
|
-
import { getOtherLabel, isChineseContext } from "./answers.ts";
|
|
3
|
+
import { getOtherLabel, isChineseContext, type AskAnswer, type AskOption, type DisplayOption } from "./types.ts";
|
|
5
4
|
import { addWrapped, createEditorTheme } from "./dialog-ui.ts";
|
|
6
5
|
|
|
7
6
|
export async function askSingleChoice(
|
|
@@ -179,4 +178,3 @@ export async function askSingleChoice(
|
|
|
179
178
|
},
|
|
180
179
|
);
|
|
181
180
|
}
|
|
182
|
-
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Text } from "@earendil-works/pi-tui";
|
|
3
|
-
import
|
|
4
|
-
import type { AskUserQuestionResultDetails } from "./types.ts";
|
|
5
|
-
import { getOtherLabel, isChineseContext, normalizeOptions } from "./answers.ts";
|
|
3
|
+
import { AskUserQuestionParams, getOtherLabel, isChineseContext, normalizeOptions, type AskUserQuestionResultDetails } from "./types.ts";
|
|
6
4
|
|
|
7
5
|
export const questionRenderers: Pick<ToolDefinition<typeof AskUserQuestionParams, AskUserQuestionResultDetails>, "renderCall" | "renderResult"> = {
|
|
8
6
|
renderCall(args, theme, context) {
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
|
|
3
|
+
const OptionSchema = Type.Object({
|
|
4
|
+
label: Type.String({ description: 'Option label. Put a recommended option first and append "(Recommended)".' }),
|
|
5
|
+
value: Type.Optional(Type.String({ description: "Machine-readable value; defaults to the label." })),
|
|
6
|
+
description: Type.Optional(Type.String({ description: "Additional context shown below the option." })),
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const AskUserQuestionParams = Type.Object({
|
|
10
|
+
question: Type.String({ description: "The question to ask. Ask only one question per call." }),
|
|
11
|
+
details: Type.Optional(Type.String({ description: "Background or instructions shown below the question." })),
|
|
12
|
+
options: Type.Optional(Type.Array(OptionSchema, {
|
|
13
|
+
description: "Choices for selection. Omit or pass an empty array for free-text input. An Other choice is always available.",
|
|
14
|
+
})),
|
|
15
|
+
multiSelect: Type.Optional(Type.Boolean({ description: "Allow selecting multiple options when true." })),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export interface AskOption {
|
|
19
|
+
label: string;
|
|
20
|
+
value: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface DisplayOption extends AskOption {
|
|
25
|
+
id: string;
|
|
26
|
+
index?: number;
|
|
27
|
+
isOther?: boolean;
|
|
28
|
+
isSubmit?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface TextAnswer {
|
|
32
|
+
type: "text";
|
|
33
|
+
label: string;
|
|
34
|
+
value: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface OptionAnswer {
|
|
38
|
+
type: "option";
|
|
39
|
+
label: string;
|
|
40
|
+
value: string;
|
|
41
|
+
index: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface OtherAnswer {
|
|
45
|
+
type: "other";
|
|
46
|
+
label: string;
|
|
47
|
+
value: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type AskAnswer = TextAnswer | OptionAnswer | OtherAnswer;
|
|
51
|
+
export type AskUserQuestionStatus = "answered" | "cancelled" | "unavailable";
|
|
52
|
+
export type AskUserQuestionMode = "text" | "single-select" | "multi-select";
|
|
53
|
+
|
|
54
|
+
export interface AskUserQuestionResultDetails {
|
|
55
|
+
status: AskUserQuestionStatus;
|
|
56
|
+
question: string;
|
|
57
|
+
context?: string;
|
|
58
|
+
mode: AskUserQuestionMode;
|
|
59
|
+
answers: AskAnswer[];
|
|
60
|
+
message?: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function normalizeOptions(
|
|
64
|
+
options: Array<{ label: string; value?: string; description?: string }> | undefined,
|
|
65
|
+
): AskOption[] {
|
|
66
|
+
return (options || [])
|
|
67
|
+
.map((option) => ({
|
|
68
|
+
label: option.label.trim(),
|
|
69
|
+
value: option.value?.trim() || option.label.trim(),
|
|
70
|
+
description: option.description?.trim() || undefined,
|
|
71
|
+
}))
|
|
72
|
+
.filter((option) => option.label.length > 0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function isChineseContext(
|
|
76
|
+
question: string,
|
|
77
|
+
options?: Array<{ label?: string; description?: string }>,
|
|
78
|
+
context?: string,
|
|
79
|
+
): boolean {
|
|
80
|
+
if (/[\u4e00-\u9fa5]/.test(question)) return true;
|
|
81
|
+
if (context && /[\u4e00-\u9fa5]/.test(context)) return true;
|
|
82
|
+
if (options && options.some((o) => (o.label && /[\u4e00-\u9fa5]/.test(o.label)) || (o.description && /[\u4e00-\u9fa5]/.test(o.description)))) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function getOtherLabel(options: AskOption[], isZh = false): string {
|
|
89
|
+
if (isZh) {
|
|
90
|
+
return options.some((option) => option.label === "其他(自定义输入)")
|
|
91
|
+
? "自定义输入"
|
|
92
|
+
: "其他(自定义输入)";
|
|
93
|
+
}
|
|
94
|
+
return options.some((option) => option.label === "Other (custom input)")
|
|
95
|
+
? "Custom input"
|
|
96
|
+
: "Other (custom input)";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function answerSortRank(answer: AskAnswer): number {
|
|
100
|
+
switch (answer.type) {
|
|
101
|
+
case "option":
|
|
102
|
+
return answer.index;
|
|
103
|
+
case "other":
|
|
104
|
+
return Number.MAX_SAFE_INTEGER - 1;
|
|
105
|
+
case "text":
|
|
106
|
+
return Number.MAX_SAFE_INTEGER;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function sortAnswers(answers: AskAnswer[]): AskAnswer[] {
|
|
111
|
+
return [...answers].sort((a, b) => answerSortRank(a) - answerSortRank(b));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function formatAnswerForModel(answer: AskAnswer): string {
|
|
115
|
+
switch (answer.type) {
|
|
116
|
+
case "text":
|
|
117
|
+
return answer.label;
|
|
118
|
+
case "other":
|
|
119
|
+
return `Other: ${answer.label}`;
|
|
120
|
+
case "option":
|
|
121
|
+
return `${answer.index}. ${answer.label}`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function buildStructuredResult(
|
|
126
|
+
status: AskUserQuestionStatus,
|
|
127
|
+
question: string,
|
|
128
|
+
mode: AskUserQuestionMode,
|
|
129
|
+
answers: AskAnswer[],
|
|
130
|
+
context?: string,
|
|
131
|
+
message?: string,
|
|
132
|
+
): AskUserQuestionResultDetails {
|
|
133
|
+
return {
|
|
134
|
+
status,
|
|
135
|
+
question,
|
|
136
|
+
context,
|
|
137
|
+
mode,
|
|
138
|
+
answers,
|
|
139
|
+
message,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function cancelledResult(question: string, mode: AskUserQuestionMode, context?: string) {
|
|
144
|
+
const isZh = isChineseContext(question, undefined, context);
|
|
145
|
+
const message = isZh ? "用户取消了本次提问" : "User cancelled the question.";
|
|
146
|
+
return {
|
|
147
|
+
content: [{ type: "text" as const, text: message }],
|
|
148
|
+
details: buildStructuredResult("cancelled", question, mode, [], context, message),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function unavailableResult(question: string, mode: AskUserQuestionMode, message: string, context?: string) {
|
|
153
|
+
return {
|
|
154
|
+
content: [{ type: "text" as const, text: message }],
|
|
155
|
+
details: buildStructuredResult("unavailable", question, mode, [], context, message),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function buildResult(
|
|
160
|
+
question: string,
|
|
161
|
+
context: string | undefined,
|
|
162
|
+
mode: AskUserQuestionMode,
|
|
163
|
+
answers: AskAnswer[],
|
|
164
|
+
) {
|
|
165
|
+
const isZh = isChineseContext(question, answers, context);
|
|
166
|
+
let text: string;
|
|
167
|
+
if (mode === "text") {
|
|
168
|
+
const answer = answers[0];
|
|
169
|
+
if (isZh) {
|
|
170
|
+
text = answer.label.trim().length > 0
|
|
171
|
+
? `用户输入回答: ${answer.label}`
|
|
172
|
+
: "用户提交了空回答";
|
|
173
|
+
} else {
|
|
174
|
+
text = answer.label.trim().length > 0
|
|
175
|
+
? `User answered: ${answer.label}`
|
|
176
|
+
: "User submitted an empty answer";
|
|
177
|
+
}
|
|
178
|
+
} else if (mode === "single-select") {
|
|
179
|
+
text = isZh
|
|
180
|
+
? `用户选择项: ${formatAnswerForModel(answers[0])}`
|
|
181
|
+
: `User selected: ${formatAnswerForModel(answers[0])}`;
|
|
182
|
+
} else {
|
|
183
|
+
text = isZh
|
|
184
|
+
? `用户选择多项:\n${answers.map((answer) => `- ${formatAnswerForModel(answer)}`).join("\n")}`
|
|
185
|
+
: `User selected multiple:\n${answers.map((answer) => `- ${formatAnswerForModel(answer)}`).join("\n")}`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
content: [{ type: "text" as const, text }],
|
|
190
|
+
details: buildStructuredResult("answered", question, mode, answers, context),
|
|
191
|
+
};
|
|
192
|
+
}
|