@apollo-music/dsh-sidecar-terms 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/coordinator.d.ts +7 -0
- package/dist/coordinator.js +58 -1
- package/package.json +14 -5
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
6. steer 修订后不再审计同一 turn 的后续 assistant 输出,避免规则回执自我触发;下一 turn 自动恢复;
|
|
11
11
|
7. 最终答案前只 steer 尚未交付的 canonical term / Rule delta。
|
|
12
12
|
8. Catalog、Resolver、鉴权或网络不可用时失败关闭,不生成离线替代规则。
|
|
13
|
+
9. 超过 Resolver 单段上限的消息只在术语审计传输层按自然或结构边界无损分段;DSH 交给模型的消息保持完整不变,分段按原事件序号在一次 Resolver 请求中合并命中与 Delta。
|
|
13
14
|
|
|
14
15
|
插件固定只读 `https://apollomusic-poc1.fde0.com/kb/terminology`。`apiUrl` 不再是运行时配置项,线上服务返回 `degraded` 也会按错误处理;插件不包含本地术语表或 P0 fallback。
|
|
15
16
|
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
在 DeepSeek Harness 项目中安装:
|
|
19
20
|
|
|
20
21
|
```bash
|
|
21
|
-
npm install @apollo-music/dsh-sidecar-terms
|
|
22
|
+
npm install @apollo-music/dsh-sidecar-terms@0.1.5
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
## 配置
|
|
@@ -74,7 +75,7 @@ export APOLLO_TERMINOLOGY_READ_API_KEY='<READ_ONLY_API_KEY>'
|
|
|
74
75
|
|
|
75
76
|
`auditReasoning: true` 只匹配每个 step 已提交的完整 reasoning block;流式 `reasoning-delta` 不参与匹配。thinking 原文只发送给 Resolver 做瞬时匹配,不会回注给模型。若部署边界不允许 thinking 离开 Harness 进程,可设为 `false`。
|
|
76
77
|
|
|
77
|
-
该插件声明依赖 `agents`、`sessions` 与 `tools`;Cordis 会等相关服务存在后再加载。官方 Harness 目前仍处于 Developer Preview,本项目锁定并测试 `0.1.
|
|
78
|
+
该插件声明依赖 `agents`、`sessions` 与 `tools`;Cordis 会等相关服务存在后再加载。官方 Harness 目前仍处于 Developer Preview,本项目锁定并测试 `0.1.1-rc.2` 的公开 `Agent`、`session/event`、`tools/post-execute`、`agent/pre-step`、`agent/turn-stopping` 接口。包清单显式声明这一组接口的完整 DSH peer 闭包,避免依赖宿主包管理器自动补齐隐式 peer。
|
|
78
79
|
|
|
79
80
|
配置线上只读凭据后验证:
|
|
80
81
|
|
package/dist/coordinator.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { type UserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
2
|
import { TerminologyApi } from "./api.js";
|
|
3
3
|
import type { AgentPort, LoggerPort, PluginConfig, ResolveResponse } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Split one audited message for the resolver transport without changing the
|
|
6
|
+
* message that DSH sends to the model. Chunks preserve order and concatenate
|
|
7
|
+
* exactly to the original text; natural or serialized-JSON boundaries are
|
|
8
|
+
* preferred so a multi-word terminology match is not cut unnecessarily.
|
|
9
|
+
*/
|
|
10
|
+
export declare function splitResolverText(text: string): string[];
|
|
4
11
|
interface AuditItem {
|
|
5
12
|
eventSeq: number;
|
|
6
13
|
source: string;
|
package/dist/coordinator.js
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
2
|
import { findCatalogMatches } from "./matcher.js";
|
|
3
3
|
const PLUGIN_NAME = "apollo-terminology-rules";
|
|
4
|
+
const RESOLVER_TEXT_TARGET_CHARS = 90_000;
|
|
5
|
+
const NATURAL_TEXT_BOUNDARIES = [
|
|
6
|
+
{ needle: "\n\n", offset: 2 },
|
|
7
|
+
{ needle: "\n", offset: 1 },
|
|
8
|
+
{ needle: "},{\"", offset: 2 },
|
|
9
|
+
{ needle: "\",\"", offset: 2 },
|
|
10
|
+
{ needle: "。", offset: 1 },
|
|
11
|
+
{ needle: "!", offset: 1 },
|
|
12
|
+
{ needle: "?", offset: 1 },
|
|
13
|
+
{ needle: ". ", offset: 2 },
|
|
14
|
+
{ needle: "! ", offset: 2 },
|
|
15
|
+
{ needle: "? ", offset: 2 },
|
|
16
|
+
{ needle: "; ", offset: 2 },
|
|
17
|
+
{ needle: ";", offset: 1 },
|
|
18
|
+
{ needle: " ", offset: 1 },
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Split one audited message for the resolver transport without changing the
|
|
22
|
+
* message that DSH sends to the model. Chunks preserve order and concatenate
|
|
23
|
+
* exactly to the original text; natural or serialized-JSON boundaries are
|
|
24
|
+
* preferred so a multi-word terminology match is not cut unnecessarily.
|
|
25
|
+
*/
|
|
26
|
+
export function splitResolverText(text) {
|
|
27
|
+
if (text.length <= RESOLVER_TEXT_TARGET_CHARS)
|
|
28
|
+
return [text];
|
|
29
|
+
const chunks = [];
|
|
30
|
+
let start = 0;
|
|
31
|
+
while (start < text.length) {
|
|
32
|
+
const targetEnd = Math.min(start + RESOLVER_TEXT_TARGET_CHARS, text.length);
|
|
33
|
+
if (targetEnd === text.length) {
|
|
34
|
+
chunks.push(text.slice(start));
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
const preferredStart = start + Math.floor(RESOLVER_TEXT_TARGET_CHARS * 0.75);
|
|
38
|
+
let end = 0;
|
|
39
|
+
for (const boundary of NATURAL_TEXT_BOUNDARIES) {
|
|
40
|
+
const index = text.lastIndexOf(boundary.needle, targetEnd - boundary.needle.length);
|
|
41
|
+
const candidate = index + boundary.offset;
|
|
42
|
+
if (index >= preferredStart && candidate > end)
|
|
43
|
+
end = candidate;
|
|
44
|
+
}
|
|
45
|
+
if (end <= start)
|
|
46
|
+
end = targetEnd;
|
|
47
|
+
// JavaScript string limits are measured in UTF-16 code units. Avoid
|
|
48
|
+
// placing a transport boundary between the halves of a surrogate pair.
|
|
49
|
+
const before = text.charCodeAt(end - 1);
|
|
50
|
+
const after = text.charCodeAt(end);
|
|
51
|
+
if (before >= 0xD800 && before <= 0xDBFF
|
|
52
|
+
&& after >= 0xDC00 && after <= 0xDFFF) {
|
|
53
|
+
end -= 1;
|
|
54
|
+
}
|
|
55
|
+
chunks.push(text.slice(start, end));
|
|
56
|
+
start = end;
|
|
57
|
+
}
|
|
58
|
+
return chunks;
|
|
59
|
+
}
|
|
4
60
|
export class TerminologyCoordinator {
|
|
5
61
|
config;
|
|
6
62
|
api;
|
|
@@ -165,6 +221,7 @@ export class TerminologyCoordinator {
|
|
|
165
221
|
async queryOnce(agent, state, mode, captured) {
|
|
166
222
|
const segments = [...state.pendingSegments.values()].sort((a, b) => a.event_seq - b.event_seq);
|
|
167
223
|
const throughSeq = segments.at(-1).event_seq;
|
|
224
|
+
const resolverSegments = segments.flatMap(({ event_seq, source, text }) => splitResolverText(text).map((chunk) => ({ event_seq, source, text: chunk })));
|
|
168
225
|
for (const segment of segments)
|
|
169
226
|
state.pendingSegments.delete(segment.event_seq);
|
|
170
227
|
state.lastQueryAt = Date.now();
|
|
@@ -172,7 +229,7 @@ export class TerminologyCoordinator {
|
|
|
172
229
|
const response = await this.api.resolve({
|
|
173
230
|
session_id: agent.id,
|
|
174
231
|
audit_through_seq: throughSeq,
|
|
175
|
-
segments:
|
|
232
|
+
segments: resolverSegments,
|
|
176
233
|
candidate_terms: [...new Set(segments.flatMap((segment) => segment.candidates ?? []))],
|
|
177
234
|
delivered_rule_ids: this.knownRuleIds(state),
|
|
178
235
|
delivered_term_ids: this.knownTermIds(state),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apollo-music/dsh-sidecar-terms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "DeepSeek Harness sidecar plugin for incremental Apollo terminology and rule injection",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,10 +41,19 @@
|
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
44
|
-
"@deepseek-ai/dsh-agent": "
|
|
45
|
-
"@deepseek-ai/dsh-
|
|
46
|
-
"@deepseek-ai/dsh-
|
|
47
|
-
"@deepseek-ai/dsh-
|
|
44
|
+
"@deepseek-ai/dsh-agent": "0.1.1-rc.2",
|
|
45
|
+
"@deepseek-ai/dsh-attachment": "0.1.1-rc.2",
|
|
46
|
+
"@deepseek-ai/dsh-brand": "0.1.1-rc.2",
|
|
47
|
+
"@deepseek-ai/dsh-code-runtime": "0.1.1-rc.2",
|
|
48
|
+
"@deepseek-ai/dsh-invariants": "0.1.1-rc.2",
|
|
49
|
+
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
|
|
50
|
+
"@deepseek-ai/dsh-scope": "0.1.1-rc.2",
|
|
51
|
+
"@deepseek-ai/dsh-session": "0.1.1-rc.2",
|
|
52
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
|
|
53
|
+
"@deepseek-ai/dsh-timeout": "0.1.1-rc.2",
|
|
54
|
+
"@deepseek-ai/dsh-tools": "0.1.1-rc.2",
|
|
55
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.1-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-user-approval": "0.1.1-rc.2",
|
|
48
57
|
"@deepseek-ai/schemastery": "^3.18.1"
|
|
49
58
|
}
|
|
50
59
|
}
|