dsh-zotero 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +16 -13
- package/README.md +16 -13
- package/lib/ask.d.ts +27 -1
- package/lib/ask.d.ts.map +1 -1
- package/lib/ask.js +61 -19
- package/lib/ask.js.map +1 -1
- package/lib/client.js +281 -302
- package/lib/client.js.map +4 -4
- package/lib/command.d.ts.map +1 -1
- package/lib/command.js +6 -1
- package/lib/command.js.map +1 -1
- package/lib/concurrency.d.ts +40 -1
- package/lib/concurrency.d.ts.map +1 -1
- package/lib/concurrency.js +101 -1
- package/lib/concurrency.js.map +1 -1
- package/lib/config.d.ts +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/constants.d.ts +35 -0
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +35 -0
- package/lib/constants.js.map +1 -1
- package/lib/contract.d.ts +2 -0
- package/lib/contract.d.ts.map +1 -1
- package/lib/contract.js +1 -0
- package/lib/contract.js.map +1 -1
- package/lib/errors.d.ts +13 -1
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +17 -0
- package/lib/errors.js.map +1 -1
- package/lib/evidence.d.ts +9 -4
- package/lib/evidence.d.ts.map +1 -1
- package/lib/evidence.js +13 -6
- package/lib/evidence.js.map +1 -1
- package/lib/http-client.d.ts +34 -0
- package/lib/http-client.d.ts.map +1 -1
- package/lib/http-client.js +132 -13
- package/lib/http-client.js.map +1 -1
- package/lib/local/changes-domain.d.ts +37 -10
- package/lib/local/changes-domain.d.ts.map +1 -1
- package/lib/local/changes-domain.js +385 -114
- package/lib/local/changes-domain.js.map +1 -1
- package/lib/local/limits.d.ts +1 -1
- package/lib/local/limits.d.ts.map +1 -1
- package/lib/local/provider.d.ts.map +1 -1
- package/lib/local/provider.js +2 -1
- package/lib/local/provider.js.map +1 -1
- package/lib/local/retrieve.d.ts +9 -2
- package/lib/local/retrieve.d.ts.map +1 -1
- package/lib/local/retrieve.js +184 -41
- package/lib/local/retrieve.js.map +1 -1
- package/lib/local/search-domain.d.ts.map +1 -1
- package/lib/local/search-domain.js +25 -26
- package/lib/local/search-domain.js.map +1 -1
- package/lib/prompt.js +1 -1
- package/lib/prompt.js.map +1 -1
- package/lib/remote.d.ts.map +1 -1
- package/lib/remote.js +1 -0
- package/lib/remote.js.map +1 -1
- package/lib/search-text.d.ts +29 -0
- package/lib/search-text.d.ts.map +1 -0
- package/lib/search-text.js +79 -0
- package/lib/search-text.js.map +1 -0
- package/lib/service.d.ts +9 -0
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +9 -0
- package/lib/service.js.map +1 -1
- package/lib/tools/attachment.d.ts.map +1 -1
- package/lib/tools/attachment.js +20 -3
- package/lib/tools/attachment.js.map +1 -1
- package/lib/tools/browse.js +1 -1
- package/lib/tools/browse.js.map +1 -1
- package/lib/tools/changes.d.ts +177 -14
- package/lib/tools/changes.d.ts.map +1 -1
- package/lib/tools/changes.js +218 -62
- package/lib/tools/changes.js.map +1 -1
- package/lib/tools/children.js +1 -1
- package/lib/tools/children.js.map +1 -1
- package/lib/tools/export.js +1 -1
- package/lib/tools/export.js.map +1 -1
- package/lib/tools/get.js +1 -1
- package/lib/tools/get.js.map +1 -1
- package/lib/tools/retrieve.d.ts +57 -1
- package/lib/tools/retrieve.d.ts.map +1 -1
- package/lib/tools/retrieve.js +92 -18
- package/lib/tools/retrieve.js.map +1 -1
- package/lib/tools/search.js +1 -1
- package/lib/tools/search.js.map +1 -1
- package/lib/tools/validate.d.ts +7 -0
- package/lib/tools/validate.d.ts.map +1 -1
- package/lib/tools/validate.js +13 -0
- package/lib/tools/validate.js.map +1 -1
- package/lib/types.d.ts +191 -8
- package/lib/types.d.ts.map +1 -1
- package/package.json +125 -127
package/README.en.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/v/dsh-zotero" alt="npm version" style="max-width:100%;"></a>
|
|
11
11
|
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/dm/dsh-zotero" alt="npm downloads" style="max-width:100%;"></a>
|
|
12
12
|
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/l/dsh-zotero" alt="license" style="max-width:100%;"></a>
|
|
13
|
-
<a href="https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.5-rc.
|
|
13
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.5-rc.2"><img src="https://img.shields.io/badge/dsh-%3E%3D0.1.5--rc.2-blue" alt="minimum dsh version" style="max-width:100%;"></a>
|
|
14
14
|
<a href="https://awesome-dsh-plugin.com"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="Awesome DSH Plugin"></a>
|
|
15
15
|
</p>
|
|
16
16
|
</div>
|
|
@@ -61,7 +61,7 @@ dsh plugin --profile <name> add ./dsh-zotero-*.tgz
|
|
|
61
61
|
|
|
62
62
|
After installing, start a new session so the agent picks up the Zotero tools.
|
|
63
63
|
|
|
64
|
-
The plugin provides a settings
|
|
64
|
+
The plugin provides a settings page under **Settings → Zotero** — a left-nav entry beside General, Models, and Plugins — where you can adjust the API address, concurrency limits, full-text retrieval toggle, and more. Changes take effect on save. See [Configuration](docs/configuration.md).
|
|
65
65
|
|
|
66
66
|
[Installation details →](docs/getting-started.md)
|
|
67
67
|
|
|
@@ -69,7 +69,7 @@ The plugin provides a settings card under **Settings → Plugins** where you can
|
|
|
69
69
|
|
|
70
70
|
- Zotero ≥ 7 with local API enabled: **Settings → Advanced → "Allow other applications on this computer to communicate with Zotero"**
|
|
71
71
|
- Node.js ≥ 22.19 (or ≥ 24)
|
|
72
|
-
- dsh 0.1.5-rc.
|
|
72
|
+
- dsh 0.1.5-rc.2 host (all `@deepseek-ai/dsh-*` peer dependencies are `^0.1.5-rc.2`, and the declared compatibility range is `engines.dsh`; only the latest pre-release line is supported until upstream stabilizes, with no backward compatibility)
|
|
73
73
|
- Local API at `http://127.0.0.1:23119/api`, unauthenticated, read-only
|
|
74
74
|
|
|
75
75
|
## Usage example
|
|
@@ -78,20 +78,23 @@ The agent calls tools step by step during a conversation. Each result becomes co
|
|
|
78
78
|
|
|
79
79
|
```text
|
|
80
80
|
User: Find papers about Risk
|
|
81
|
-
Agent → zotero_search(query: "Risk",
|
|
81
|
+
Agent → zotero_search(query: "Risk", itemTypes: ["journalArticle"])
|
|
82
82
|
5 matches; user picks the first 3
|
|
83
83
|
|
|
84
84
|
User: What does the first one's abstract say?
|
|
85
|
-
Agent → zotero_get(ref:
|
|
86
|
-
Returns the full abstract
|
|
85
|
+
Agent → zotero_get(ref: "zotero://user/0/item/ABCD1234")
|
|
86
|
+
Returns the full abstract (the standard model carries it)
|
|
87
87
|
|
|
88
88
|
User: Find the methodology discussion in this paper
|
|
89
|
-
Agent → zotero_retrieve(
|
|
89
|
+
Agent → zotero_retrieve(ref: "zotero://user/0/item/ABCD1234", query: "methodology",
|
|
90
|
+
sources: ["fulltext", "note"])
|
|
90
91
|
Returns relevant passages with page numbers
|
|
91
92
|
|
|
92
93
|
User: Export all three as BibTeX
|
|
93
|
-
Agent → zotero_export(refs: [
|
|
94
|
-
|
|
94
|
+
Agent → zotero_export(refs: ["zotero://user/0/item/ABCD1234",
|
|
95
|
+
"zotero://user/0/item/EFGH5678",
|
|
96
|
+
"zotero://user/0/item/IJKL9012"], format: "bibtex")
|
|
97
|
+
Generates BibTeX entries; the UI can download them, the model reads the same text
|
|
95
98
|
```
|
|
96
99
|
|
|
97
100
|
More examples in [Features](docs/features.md).
|
|
@@ -101,7 +104,7 @@ More examples in [Features](docs/features.md).
|
|
|
101
104
|
- **Read-only library**: all operations are reads; items, notes, tags, and collections are unchanged
|
|
102
105
|
- **Loopback only**: network requests go only to `127.0.0.1:23119`
|
|
103
106
|
- **Evidence ranking is term-based**: BM25 ranks passages by query-term frequency match
|
|
104
|
-
- **Exports are static text**:
|
|
107
|
+
- **Exports are static text**: the tool returns text, and that is what the model reads; the Zotero panel offers one-click copy or file download (`.bib`, `.ris`, `.json`), so nothing has to be retyped
|
|
105
108
|
- **Full-text evidence depends on Zotero's index**: unindexed PDFs yield no full-text passages
|
|
106
109
|
- **Attachment depth depends on the harness**: `zotero_attachment` returns the file location; reading the PDF further needs a matching host capability
|
|
107
110
|
|
|
@@ -109,7 +112,7 @@ More examples in [Features](docs/features.md).
|
|
|
109
112
|
|
|
110
113
|
- **Network**: HTTP requests go only to `http://127.0.0.1:23119/api` (redirects are not followed); `resolveConfig` enforces a loopback address
|
|
111
114
|
- **Filesystem**: read-only — `zotero_attachment` verifies attachment paths with `existsSync`; no file writes
|
|
112
|
-
- **Persistence**: the only write comes from the settings
|
|
115
|
+
- **Persistence**: the only write comes from the Zotero settings page in the left navigation, saved to the `zotero:` user layer of `$DSH_HOME/settings.yaml`
|
|
113
116
|
- **No shell / native / background tasks**: the plugin runs no shell commands, loads no native modules, and starts no daemon
|
|
114
117
|
- **Restart**: after installing or removing the plugin, restart dsh and start a new session; configuration changes hot-reload on save without a restart
|
|
115
118
|
|
|
@@ -120,7 +123,7 @@ More examples in [Features](docs/features.md).
|
|
|
120
123
|
| [Getting Started](docs/getting-started.md) | Installation, prerequisites, first verification |
|
|
121
124
|
| [Features](docs/features.md) | Sources panel, chat integration, evidence, exports |
|
|
122
125
|
| [Tool Reference](docs/tools.md) | Parameters, return values, error codes for all 8 tools |
|
|
123
|
-
| [Configuration](docs/configuration.md) |
|
|
126
|
+
| [Configuration](docs/configuration.md) | 22 config fields, defaults, hot-reload |
|
|
124
127
|
| [Architecture](docs/architecture.md) | Data flow, layer responsibilities, design boundaries |
|
|
125
128
|
| [Development](docs/development.md) | Build, test, local development |
|
|
126
129
|
| [Troubleshooting](docs/troubleshooting.md) | 11 common issues with symptoms and fixes |
|
|
@@ -136,7 +139,7 @@ npm run dev # tsc --watch for host half hot reload
|
|
|
136
139
|
npm run dev:client # esbuild --watch for browser half hot reload
|
|
137
140
|
```
|
|
138
141
|
|
|
139
|
-
Build output splits into `lib/` (Node side) and `lib/client.js` (browser side — settings
|
|
142
|
+
Build output splits into `lib/` (Node side) and `lib/client.js` (browser side — settings page + Zotero tab). For full plugin development with both halves, use the `dev-lib.cordis.yml` overlay. See [Development](docs/development.md) for details.
|
|
140
143
|
|
|
141
144
|
## License
|
|
142
145
|
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/v/dsh-zotero" alt="npm version" style="max-width:100%;"></a>
|
|
11
11
|
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/dm/dsh-zotero" alt="npm downloads" style="max-width:100%;"></a>
|
|
12
12
|
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/l/dsh-zotero" alt="license" style="max-width:100%;"></a>
|
|
13
|
-
<a href="https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.5-rc.
|
|
13
|
+
<a href="https://github.com/deepseek-ai/deepseek-harness/releases/tag/dsh-v0.1.5-rc.2"><img src="https://img.shields.io/badge/dsh-%3E%3D0.1.5--rc.2-blue" alt="最低 dsh 版本" style="max-width:100%;"></a>
|
|
14
14
|
<a href="https://awesome-dsh-plugin.com"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="Awesome DSH Plugin"></a>
|
|
15
15
|
</p>
|
|
16
16
|
</div>
|
|
@@ -61,7 +61,7 @@ dsh plugin --profile <name> add ./dsh-zotero-*.tgz
|
|
|
61
61
|
|
|
62
62
|
安装后重启新建会话,Agent 即可使用 Zotero 工具。
|
|
63
63
|
|
|
64
|
-
插件在
|
|
64
|
+
插件在 **设置 → Zotero** 中提供一个配置页(与 General、Models、Plugins 并列的左侧导航项),可调整 API 地址、并发限制、全文检索开关等参数,保存即生效。详见 [配置](docs/configuration.md)。
|
|
65
65
|
|
|
66
66
|
[安装详情 →](docs/getting-started.md)
|
|
67
67
|
|
|
@@ -69,7 +69,7 @@ dsh plugin --profile <name> add ./dsh-zotero-*.tgz
|
|
|
69
69
|
|
|
70
70
|
- Zotero ≥ 7 桌面版,启用本地 API:**设置 → 高级 → "允许其他应用程序与 Zotero 通信"**
|
|
71
71
|
- Node.js ≥ 22.19(或 ≥ 24)
|
|
72
|
-
- 宿主 dsh 0.1.5-rc.
|
|
72
|
+
- 宿主 dsh 0.1.5-rc.2(`@deepseek-ai/dsh-*` peer 依赖均为 `^0.1.5-rc.2`,兼容范围另见 `engines.dsh`;上游发布稳定版之前只跟最新预发布线,不向后兼容)
|
|
73
73
|
- 本地 API 地址 `http://127.0.0.1:23119/api`,无认证,只读
|
|
74
74
|
|
|
75
75
|
## 使用示例
|
|
@@ -78,20 +78,23 @@ Agent 在对话中根据用户需求逐步调用工具,每次调用的结果
|
|
|
78
78
|
|
|
79
79
|
```text
|
|
80
80
|
用户:帮我找 Risk 相关的论文
|
|
81
|
-
Agent → zotero_search(query: "Risk",
|
|
81
|
+
Agent → zotero_search(query: "Risk", itemTypes: ["journalArticle"])
|
|
82
82
|
5 篇匹配结果,用户选择前 3 篇
|
|
83
83
|
|
|
84
84
|
用户:第一篇的摘要说了什么?
|
|
85
|
-
Agent → zotero_get(ref:
|
|
86
|
-
|
|
85
|
+
Agent → zotero_get(ref: "zotero://user/0/item/ABCD1234")
|
|
86
|
+
返回摘要全文(标准模型已含 abstract)
|
|
87
87
|
|
|
88
88
|
用户:这篇里关于方法论的讨论,帮我找出来
|
|
89
|
-
Agent → zotero_retrieve(
|
|
89
|
+
Agent → zotero_retrieve(ref: "zotero://user/0/item/ABCD1234", query: "methodology",
|
|
90
|
+
sources: ["fulltext", "note"])
|
|
90
91
|
返回相关段落,带页码和来源
|
|
91
92
|
|
|
92
93
|
用户:把这三篇导出为 BibTeX
|
|
93
|
-
Agent → zotero_export(refs: [
|
|
94
|
-
|
|
94
|
+
Agent → zotero_export(refs: ["zotero://user/0/item/ABCD1234",
|
|
95
|
+
"zotero://user/0/item/EFGH5678",
|
|
96
|
+
"zotero://user/0/item/IJKL9012"], format: "bibtex")
|
|
97
|
+
生成 BibTeX 条目;界面可下载,模型读到同样的文本
|
|
95
98
|
```
|
|
96
99
|
|
|
97
100
|
更多示例见 [功能概览](docs/features.md)。
|
|
@@ -101,7 +104,7 @@ Agent → zotero_export(refs: [1,2,3], format: "bibtex")
|
|
|
101
104
|
- **只读文献库**:所有操作均为读取,不修改条目、笔记、标签或分类
|
|
102
105
|
- **只访问本机**:网络请求仅发往 `127.0.0.1:23119`
|
|
103
106
|
- **证据排序是词项相关性**:基于 BM25,按查询词与 passage 的词频匹配度排序
|
|
104
|
-
-
|
|
107
|
+
- **导出是静态文本**:工具以文本形式返回,模型读到的就是它;Zotero 面板可以一键复制或下载文件(`.bib` / `.ris` / `.json` 等),不需要手动誊抄
|
|
105
108
|
- **全文证据依赖 Zotero 索引**:未索引的 PDF 无法提供全文段落
|
|
106
109
|
- **附件深度取决于宿主**:`zotero_attachment` 返回文件位置,继续阅读 PDF 需要宿主具备对应能力
|
|
107
110
|
|
|
@@ -109,7 +112,7 @@ Agent → zotero_export(refs: [1,2,3], format: "bibtex")
|
|
|
109
112
|
|
|
110
113
|
- **网络**:只向 `http://127.0.0.1:23119/api` 发起 HTTP 请求(不跟随重定向),`resolveConfig` 强制 loopback 地址
|
|
111
114
|
- **文件**:只读,`zotero_attachment` 用 `existsSync` 校验 Zotero 返回的附件路径,不写文件系统
|
|
112
|
-
-
|
|
115
|
+
- **持久化**:唯一写入来自设置页左侧导航的 Zotero 配置页,保存到 `$DSH_HOME/settings.yaml` 的 `zotero:` 用户层
|
|
113
116
|
- **无 Shell / native / 后台任务**:插件不执行 shell 命令、不加载 native 模块、不启动常驻进程
|
|
114
117
|
- **重启**:安装或卸载插件后需要重启 dsh 并新建会话;配置修改保存即热更新,无需重启
|
|
115
118
|
|
|
@@ -120,7 +123,7 @@ Agent → zotero_export(refs: [1,2,3], format: "bibtex")
|
|
|
120
123
|
| [快速上手](docs/getting-started.md) | 安装、前置条件、首次验证 |
|
|
121
124
|
| [功能概览](docs/features.md) | 来源面板、对话集成、证据提取、导出 |
|
|
122
125
|
| [工具参考](docs/tools.md) | 全部 8 个工具的参数、返回值、错误码 |
|
|
123
|
-
| [配置](docs/configuration.md) |
|
|
126
|
+
| [配置](docs/configuration.md) | 22 个配置字段、默认值、热更新 |
|
|
124
127
|
| [架构](docs/architecture.md) | 数据流、各层职责、设计边界 |
|
|
125
128
|
| [开发指南](docs/development.md) | 构建、测试、本地开发 |
|
|
126
129
|
| [问题排查](docs/troubleshooting.md) | 11 个常见问题的症状和处理 |
|
|
@@ -136,7 +139,7 @@ npm run dev # tsc --watch,host half 热更新
|
|
|
136
139
|
npm run dev:client # esbuild --watch,浏览器部分热更新
|
|
137
140
|
```
|
|
138
141
|
|
|
139
|
-
`lib/` 放 Node 侧代码,`lib/client.js`
|
|
142
|
+
`lib/` 放 Node 侧代码,`lib/client.js` 放浏览器侧代码(设置页和 Zotero tab)。你用 `dev-lib.cordis.yml` overlay 跑完整插件流程,见[开发指南](docs/development.md)。本仓库与 `../deepseek-harness` 并列,属本地暂存布局。
|
|
140
143
|
|
|
141
144
|
## 许可证
|
|
142
145
|
|
package/lib/ask.d.ts
CHANGED
|
@@ -17,11 +17,37 @@ import type { Context } from '@deepseek-ai/cordis';
|
|
|
17
17
|
import { type ToolRunContext } from '@deepseek-ai/dsh-tools';
|
|
18
18
|
/** The parts of a tool execution `withConnectivityAsk` needs. */
|
|
19
19
|
type ConnectivityAskExec = Pick<ToolRunContext, 'signal' | 'agent'>;
|
|
20
|
+
/**
|
|
21
|
+
* One recovery conversation per failure kind, owned by one plugin instance.
|
|
22
|
+
*
|
|
23
|
+
* Tool calls run concurrently, and a Zotero that is down fails all of them:
|
|
24
|
+
* five parallel reads used to put five identical cards in front of the user,
|
|
25
|
+
* each one demanding the same answer. The gate keeps one ask per failure
|
|
26
|
+
* kind in flight and lets every other caller wait on that same answer, so a
|
|
27
|
+
* single card decides for all of them — and each caller then retries, or
|
|
28
|
+
* does not, on its own request. The entry is dropped as soon as the question
|
|
29
|
+
* settles, so a later failure asks again instead of inheriting a stale
|
|
30
|
+
* answer.
|
|
31
|
+
*/
|
|
32
|
+
export declare class ConnectivityRecovery {
|
|
33
|
+
private readonly asking;
|
|
34
|
+
/**
|
|
35
|
+
* Answer one failure kind, asking only when no question for it is in
|
|
36
|
+
* flight.
|
|
37
|
+
* @param code - the failure kind the question belongs to.
|
|
38
|
+
* @param question - the ask to run when this caller is the first; resolves
|
|
39
|
+
* true when the user chose to retry.
|
|
40
|
+
* @returns the answer this caller acts on.
|
|
41
|
+
*/
|
|
42
|
+
ask(code: string, question: () => Promise<boolean>): Promise<boolean>;
|
|
43
|
+
}
|
|
20
44
|
/**
|
|
21
45
|
* Run one Zotero request; on a connectivity failure, ask the user how to
|
|
22
46
|
* proceed and retry at most once when they choose the recommended action.
|
|
23
47
|
* @param ctx - the plugin context; the question service is looked up
|
|
24
48
|
* optionally, so headless compositions skip the ask.
|
|
49
|
+
* @param recovery - the instance's recovery gate: callers that failed the
|
|
50
|
+
* same way share one question instead of stacking identical cards.
|
|
25
51
|
* @param exec - the tool execution (signal and agent) the failure belongs to.
|
|
26
52
|
* @param run - the request to attempt; must be re-runnable with identical
|
|
27
53
|
* arguments, because the retry path calls it a second time.
|
|
@@ -30,6 +56,6 @@ type ConnectivityAskExec = Pick<ToolRunContext, 'signal' | 'agent'>;
|
|
|
30
56
|
* does not choose to retry, the question itself fails, or the retry
|
|
31
57
|
* fails again.
|
|
32
58
|
*/
|
|
33
|
-
export declare function withConnectivityAsk<T>(ctx: Context, exec: ConnectivityAskExec, run: () => Promise<T>): Promise<T>;
|
|
59
|
+
export declare function withConnectivityAsk<T>(ctx: Context, recovery: ConnectivityRecovery, exec: ConnectivityAskExec, run: () => Promise<T>): Promise<T>;
|
|
34
60
|
export {};
|
|
35
61
|
//# sourceMappingURL=ask.d.ts.map
|
package/lib/ask.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../src/ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../src/ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;AA0B1E,iEAAiE;AACjE,KAAK,mBAAmB,GAAG,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAA;AA2EnE;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAE7D;;;;;;;OAOG;IACG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAW5E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACpB,OAAO,CAAC,CAAC,CAAC,CAmCZ"}
|
package/lib/ask.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { HarnessError } from '@deepseek-ai/dsh-llm';
|
|
17
17
|
import { TOOL_ABORTED } from '@deepseek-ai/dsh-tools';
|
|
18
|
+
import { ZOTERO_LOCAL_API_VERSION } from './constants.js';
|
|
18
19
|
import { ZOTERO_API_DISABLED, ZOTERO_API_VERSION, ZOTERO_NOT_RUNNING, ZOTERO_TIMEOUT, ZoteroError, } from './errors.js';
|
|
19
20
|
/** The connectivity failure codes that warrant asking the user how to proceed. */
|
|
20
21
|
const ASK_WORTHY_CODES = [
|
|
@@ -46,10 +47,10 @@ const FAILURE_SPECS = {
|
|
|
46
47
|
abortDescription: ABORT_DESCRIPTION,
|
|
47
48
|
},
|
|
48
49
|
[ZOTERO_API_VERSION]: {
|
|
49
|
-
header: 'Zotero
|
|
50
|
-
question:
|
|
51
|
-
detail:
|
|
52
|
-
retryLabel: 'I
|
|
50
|
+
header: 'Zotero and this plugin share no API version',
|
|
51
|
+
question: `The running Zotero does not implement local API version ${ZOTERO_LOCAL_API_VERSION}, which this plugin requires.`,
|
|
52
|
+
detail: `Upgrade Zotero to a version whose local API supports version ${ZOTERO_LOCAL_API_VERSION} — or update dsh-zotero if the running Zotero is newer than this plugin line.`,
|
|
53
|
+
retryLabel: 'I fixed the version, retry (Recommended)',
|
|
53
54
|
retryDescription: RETRY_DESCRIPTION,
|
|
54
55
|
abortLabel: ABORT_LABEL,
|
|
55
56
|
abortDescription: ABORT_DESCRIPTION,
|
|
@@ -79,11 +80,49 @@ function questionOf(spec) {
|
|
|
79
80
|
],
|
|
80
81
|
};
|
|
81
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* One recovery conversation per failure kind, owned by one plugin instance.
|
|
85
|
+
*
|
|
86
|
+
* Tool calls run concurrently, and a Zotero that is down fails all of them:
|
|
87
|
+
* five parallel reads used to put five identical cards in front of the user,
|
|
88
|
+
* each one demanding the same answer. The gate keeps one ask per failure
|
|
89
|
+
* kind in flight and lets every other caller wait on that same answer, so a
|
|
90
|
+
* single card decides for all of them — and each caller then retries, or
|
|
91
|
+
* does not, on its own request. The entry is dropped as soon as the question
|
|
92
|
+
* settles, so a later failure asks again instead of inheriting a stale
|
|
93
|
+
* answer.
|
|
94
|
+
*/
|
|
95
|
+
export class ConnectivityRecovery {
|
|
96
|
+
asking = new Map();
|
|
97
|
+
/**
|
|
98
|
+
* Answer one failure kind, asking only when no question for it is in
|
|
99
|
+
* flight.
|
|
100
|
+
* @param code - the failure kind the question belongs to.
|
|
101
|
+
* @param question - the ask to run when this caller is the first; resolves
|
|
102
|
+
* true when the user chose to retry.
|
|
103
|
+
* @returns the answer this caller acts on.
|
|
104
|
+
*/
|
|
105
|
+
async ask(code, question) {
|
|
106
|
+
const inFlight = this.asking.get(code);
|
|
107
|
+
if (inFlight !== undefined)
|
|
108
|
+
return await inFlight;
|
|
109
|
+
const answer = question();
|
|
110
|
+
this.asking.set(code, answer);
|
|
111
|
+
try {
|
|
112
|
+
return await answer;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
this.asking.delete(code);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
82
119
|
/**
|
|
83
120
|
* Run one Zotero request; on a connectivity failure, ask the user how to
|
|
84
121
|
* proceed and retry at most once when they choose the recommended action.
|
|
85
122
|
* @param ctx - the plugin context; the question service is looked up
|
|
86
123
|
* optionally, so headless compositions skip the ask.
|
|
124
|
+
* @param recovery - the instance's recovery gate: callers that failed the
|
|
125
|
+
* same way share one question instead of stacking identical cards.
|
|
87
126
|
* @param exec - the tool execution (signal and agent) the failure belongs to.
|
|
88
127
|
* @param run - the request to attempt; must be re-runnable with identical
|
|
89
128
|
* arguments, because the retry path calls it a second time.
|
|
@@ -92,7 +131,7 @@ function questionOf(spec) {
|
|
|
92
131
|
* does not choose to retry, the question itself fails, or the retry
|
|
93
132
|
* fails again.
|
|
94
133
|
*/
|
|
95
|
-
export async function withConnectivityAsk(ctx, exec, run) {
|
|
134
|
+
export async function withConnectivityAsk(ctx, recovery, exec, run) {
|
|
96
135
|
try {
|
|
97
136
|
return await run();
|
|
98
137
|
}
|
|
@@ -103,14 +142,23 @@ export async function withConnectivityAsk(ctx, exec, run) {
|
|
|
103
142
|
if (questions === undefined)
|
|
104
143
|
throw error;
|
|
105
144
|
const spec = FAILURE_SPECS[error.code];
|
|
106
|
-
let
|
|
145
|
+
let retry;
|
|
107
146
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
147
|
+
retry = await recovery.ask(error.code, async () => {
|
|
148
|
+
const request = {
|
|
149
|
+
questions: [questionOf(spec)],
|
|
150
|
+
...(exec.agent !== undefined ? { agent: exec.agent } : {}),
|
|
151
|
+
signal: exec.signal,
|
|
152
|
+
};
|
|
153
|
+
const answer = await questions.ask(request);
|
|
154
|
+
const answerItem = answer.answers.find((item) => item.id === 'zotero-failure');
|
|
155
|
+
// Matched by label string because the answer protocol carries only
|
|
156
|
+
// selected labels (no stable option ids); the labels are code
|
|
157
|
+
// constants (FAILURE_SPECS), never i18n copy, so a rename breaks the
|
|
158
|
+
// build's contract visibly in one place. Revisit if the protocol
|
|
159
|
+
// gains option ids.
|
|
160
|
+
return (answerItem?.selected ?? []).includes(spec.retryLabel);
|
|
161
|
+
});
|
|
114
162
|
}
|
|
115
163
|
catch {
|
|
116
164
|
// A failed question (no provider, aborted ask, delegated caller) must
|
|
@@ -119,13 +167,7 @@ export async function withConnectivityAsk(ctx, exec, run) {
|
|
|
119
167
|
throw new HarnessError('tool call aborted', TOOL_ABORTED);
|
|
120
168
|
throw error;
|
|
121
169
|
}
|
|
122
|
-
|
|
123
|
-
const selected = answerItem?.selected ?? [];
|
|
124
|
-
// Matched by label string because the answer protocol carries only
|
|
125
|
-
// selected labels (no stable option ids); the labels are code constants
|
|
126
|
-
// (FAILURE_SPECS), never i18n copy, so a rename breaks the build's
|
|
127
|
-
// contract visibly in one place. Revisit if the protocol gains option ids.
|
|
128
|
-
if (!selected.includes(spec.retryLabel))
|
|
170
|
+
if (!retry)
|
|
129
171
|
throw error;
|
|
130
172
|
// Outside the catch: a second failure propagates as-is, never re-asking.
|
|
131
173
|
return await run();
|
package/lib/ask.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../src/ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAuB,MAAM,wBAAwB,CAAA;AAO1E,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,WAAW,GACZ,MAAM,aAAa,CAAA;AAEpB,kFAAkF;AAClF,MAAM,gBAAgB,GAAG;IACvB,kBAAkB;IAClB,mBAAmB;IACnB,kBAAkB;IAClB,cAAc;CACN,CAAA;AAkBV,MAAM,WAAW,GAAG,kBAAkB,CAAA;AACtC,MAAM,iBAAiB,GAAG,kEAAkE,CAAA;AAC5F,MAAM,iBAAiB,GAAG,gDAAgD,CAAA;AAE1E,MAAM,aAAa,GAAuC;IACxD,CAAC,kBAAkB,CAAC,EAAE;QACpB,MAAM,EAAE,uBAAuB;QAC/B,QAAQ,EAAE,yEAAyE;QACnF,MAAM,EACJ,yHAAyH;QAC3H,UAAU,EAAE,uCAAuC;QACnD,gBAAgB,EAAE,iBAAiB;QACnC,UAAU,EAAE,WAAW;QACvB,gBAAgB,EAAE,iBAAiB;KACpC;IACD,CAAC,mBAAmB,CAAC,EAAE;QACrB,MAAM,EAAE,8BAA8B;QACtC,QAAQ,EAAE,6DAA6D;QACvE,MAAM,EACJ,8GAA8G;QAChH,UAAU,EAAE,8CAA8C;QAC1D,gBAAgB,EAAE,iBAAiB;QACnC,UAAU,EAAE,WAAW;QACvB,gBAAgB,EAAE,iBAAiB;KACpC;IACD,CAAC,kBAAkB,CAAC,EAAE;QACpB,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../src/ask.ts"],"names":[],"mappings":"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"}
|