@xbzb404/dsh-context-compression-selector-runtime 0.0.0-stage → 0.2.1-rc.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/LICENSE +21 -0
- package/README.md +13 -3
- package/README.zh.md +13 -0
- package/THIRD_PARTY_NOTICES.md +36 -0
- package/assets/deepseek-v4/LICENSE.DeepSeek-V4-Pro.txt +21 -0
- package/assets/deepseek-v4/manifest.json +22 -0
- package/assets/deepseek-v4/tokenizer.json +267359 -0
- package/assets/deepseek-v4/tokenizer_config.json +34 -0
- package/assets/deepseek-v4.1-flash/LICENSE.DeepSeek-V4.1-Flash.txt +21 -0
- package/assets/deepseek-v4.1-flash/manifest.json +24 -0
- package/assets/deepseek-v4.1-flash/tokenizer.json +267359 -0
- package/assets/deepseek-v4.1-flash/tokenizer_config.json +34 -0
- package/lib/index.d.ts +581 -0
- package/lib/index.js +3871 -0
- package/lib/invariant.d.ts +10 -0
- package/lib/invariant.js +70 -0
- package/lib/tail-trim.js +142 -0
- package/package.json +67 -4
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
//#region src/invariant.d.ts
|
|
3
|
+
/** Cordis companion plugin name. */
|
|
4
|
+
declare const name = "context-compression-selector-runtime-invariant";
|
|
5
|
+
/** Services required before the companion can register. */
|
|
6
|
+
declare const inject: string[];
|
|
7
|
+
/** Register this package's invariant companion. */
|
|
8
|
+
declare const apply: (ctx: Context) => Promise<() => void>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { apply, inject, name };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { a as validatePublishedTailTrim, o as sessionEvents } from "./tail-trim.js";
|
|
2
|
+
//#region src/invariant.ts
|
|
3
|
+
const PACKAGE_NAME = "dsh-context-compression-selector-runtime";
|
|
4
|
+
/** Cordis companion plugin name. */
|
|
5
|
+
const name = "context-compression-selector-runtime-invariant";
|
|
6
|
+
/** Services required before the companion can register. */
|
|
7
|
+
const inject = ["invariants"];
|
|
8
|
+
/** Whether the next event claims the unresolved prune's replacement range. */
|
|
9
|
+
function resemblesCompanion(prune, event) {
|
|
10
|
+
if (event.type !== "tool/result" && event.type !== "user/message" || typeof event.surfaceOp !== "object") return false;
|
|
11
|
+
const sources = new Set(event.sourceEventSeqs ?? []);
|
|
12
|
+
return event.surfaceOp.startSeq === prune.data.shadowedRange.start && event.surfaceOp.endSeq === prune.data.shadowedRange.end || prune.data.shadowedSeqs.some((seq) => sources.has(seq));
|
|
13
|
+
}
|
|
14
|
+
/** Validate one standard prune's immediately adjacent surface replacement. */
|
|
15
|
+
function validateCompanion(session, prune, event, fail) {
|
|
16
|
+
if (event.type !== "tool/result" && event.type !== "user/message" || typeof event.surfaceOp !== "object") fail(`compaction/prune at seq ${prune.seq} must be immediately followed by a replacement surface event`);
|
|
17
|
+
const { shadowedRange, shadowedSeqs } = prune.data;
|
|
18
|
+
if (shadowedSeqs.length === 0 || shadowedSeqs[0] !== shadowedRange.start || shadowedSeqs.at(-1) !== shadowedRange.end) fail(`compaction/prune at seq ${prune.seq} has a shadowed range inconsistent with shadowedSeqs`);
|
|
19
|
+
if (event.surfaceOp.startSeq !== shadowedRange.start || event.surfaceOp.endSeq !== shadowedRange.end) fail(`replacement at seq ${event.seq} does not replace compaction/prune range ${shadowedRange.start}-${shadowedRange.end}`);
|
|
20
|
+
const sources = new Set(event.sourceEventSeqs ?? []);
|
|
21
|
+
const missing = shadowedSeqs.filter((seq) => !sources.has(seq));
|
|
22
|
+
if (missing.length > 0) fail(`replacement at seq ${event.seq} omits shadowed source seqs ${missing.join(", ")}`);
|
|
23
|
+
if (event.type === "user/message" && validatePublishedTailTrim(session, prune.seq) === null) fail(`TailTrim publication at seq ${prune.seq} is invalid`);
|
|
24
|
+
}
|
|
25
|
+
/** Validate a replayed log and return its only legal unresolved tail. */
|
|
26
|
+
function seedPending(session, fail) {
|
|
27
|
+
let pending;
|
|
28
|
+
for (const event of sessionEvents(session)) {
|
|
29
|
+
if (pending !== void 0) {
|
|
30
|
+
if (resemblesCompanion(pending, event)) validateCompanion(session, pending, event, fail);
|
|
31
|
+
pending = void 0;
|
|
32
|
+
}
|
|
33
|
+
if (event.type === "compaction/prune") pending = event;
|
|
34
|
+
}
|
|
35
|
+
return pending;
|
|
36
|
+
}
|
|
37
|
+
/** Install adjacency checks with pre-commit staging. */
|
|
38
|
+
const install = Object.assign((ctx, fail) => {
|
|
39
|
+
const pending = /* @__PURE__ */ new WeakMap();
|
|
40
|
+
const staged = /* @__PURE__ */ new WeakMap();
|
|
41
|
+
const seed = (session) => {
|
|
42
|
+
pending.set(session, seedPending(session, fail));
|
|
43
|
+
};
|
|
44
|
+
const current = (session) => {
|
|
45
|
+
if (!pending.has(session)) seed(session);
|
|
46
|
+
return pending.get(session);
|
|
47
|
+
};
|
|
48
|
+
for (const session of ctx.sessions.list()) seed(session);
|
|
49
|
+
ctx.on("session/created", seed, { global: true });
|
|
50
|
+
ctx.on("internal/dispatch", (_mode, eventName, args) => {
|
|
51
|
+
if (eventName !== "session/event") return;
|
|
52
|
+
const [session, event] = args;
|
|
53
|
+
const open = current(session);
|
|
54
|
+
if (open !== void 0 && resemblesCompanion(open, event)) validateCompanion(session, open, event, fail);
|
|
55
|
+
staged.set(event, {
|
|
56
|
+
session,
|
|
57
|
+
next: event.type === "compaction/prune" ? event : void 0
|
|
58
|
+
});
|
|
59
|
+
}, { global: true });
|
|
60
|
+
ctx.on("session/event", (session, event) => {
|
|
61
|
+
const candidate = staged.get(event);
|
|
62
|
+
if (candidate === void 0 || candidate.session !== session) return fail("session/event reached publication without matching pre-commit validation");
|
|
63
|
+
staged.delete(event);
|
|
64
|
+
pending.set(session, candidate.next);
|
|
65
|
+
}, { global: true });
|
|
66
|
+
}, { inject: ["sessions"] });
|
|
67
|
+
/** Register this package's invariant companion. */
|
|
68
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
69
|
+
//#endregion
|
|
70
|
+
export { apply, inject, name };
|
package/lib/tail-trim.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
2
|
+
//#region src/session-events.ts
|
|
3
|
+
/**
|
|
4
|
+
* Read one immutable Session event snapshot.
|
|
5
|
+
*
|
|
6
|
+
* Harness rc.2 exposed `events`; Alpha 5 replaced it with the public
|
|
7
|
+
* `snapshotEvents()` method. 0.2.0 keeps `snapshotEvents()` (now with default
|
|
8
|
+
* `[0, seq)` range arguments) and removed the `events` accessor. This helper
|
|
9
|
+
* prefers the modern public API but retains the rc.2 `events` accessor as a
|
|
10
|
+
* fallback so sessions produced by older harness builds still resolve.
|
|
11
|
+
*/
|
|
12
|
+
function sessionEvents(session) {
|
|
13
|
+
const candidate = session;
|
|
14
|
+
if (typeof candidate.snapshotEvents === "function") return candidate.snapshotEvents();
|
|
15
|
+
if (candidate.events !== void 0) return candidate.events;
|
|
16
|
+
throw new TypeError("Session exposes neither snapshotEvents() nor the rc.2 events accessor");
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/tail-trim.ts
|
|
20
|
+
/** Plugin-owned TailTrim publication protocol over official Session events. */
|
|
21
|
+
const PRUNE_SOURCE_PLUGIN = "dsh-context-compression-selector-runtime";
|
|
22
|
+
const TAIL_TRIM_REF_PATTERN = /^session:\/\/([^/]+)\/tailtrim\/(\d+)$/;
|
|
23
|
+
const MAX_ROOTS = 64;
|
|
24
|
+
const MAX_STUB_CODE_POINTS = 1024;
|
|
25
|
+
/** Build a same-session reference keyed by the standard prune event. */
|
|
26
|
+
function tailTrimRef(sessionId, manifestSeq) {
|
|
27
|
+
return `session://${sessionId}/tailtrim/${String(manifestSeq)}`;
|
|
28
|
+
}
|
|
29
|
+
/** Parse one exact TailTrim reference. */
|
|
30
|
+
function parseTailTrimRef(ref) {
|
|
31
|
+
const match = TAIL_TRIM_REF_PATTERN.exec(ref);
|
|
32
|
+
if (match === null) return null;
|
|
33
|
+
const manifestSeq = Number(match[2]);
|
|
34
|
+
if (!Number.isSafeInteger(manifestSeq) || manifestSeq < 0) return null;
|
|
35
|
+
return {
|
|
36
|
+
sessionId: match[1] ?? "",
|
|
37
|
+
manifestSeq
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Build the fixed bounded model-visible TailTrim stub. */
|
|
41
|
+
function tailTrimStub(ref, toolNames, sourceEventSeqs) {
|
|
42
|
+
const stub = [
|
|
43
|
+
"[TailTrim: completed tool-call group]",
|
|
44
|
+
`ref: ${ref}`,
|
|
45
|
+
`tools: ${toolNames.join(", ")}`,
|
|
46
|
+
`source_event_seqs: ${sourceEventSeqs.join(", ")}`,
|
|
47
|
+
"use context_compression_retrieve with this TailTrim ref if needed"
|
|
48
|
+
].join("\n");
|
|
49
|
+
return Array.from(stub).length <= MAX_STUB_CODE_POINTS ? stub : null;
|
|
50
|
+
}
|
|
51
|
+
/** Wrap a TailTrim stub in the one user message used for range replacement. */
|
|
52
|
+
function tailTrimMessage(stub) {
|
|
53
|
+
return createUserMessage({
|
|
54
|
+
content: [{
|
|
55
|
+
type: "text",
|
|
56
|
+
text: stub
|
|
57
|
+
}],
|
|
58
|
+
source: {
|
|
59
|
+
kind: "context-compression-prune",
|
|
60
|
+
plugin: PRUNE_SOURCE_PLUGIN
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Validate the standard prune, adjacent replacement, append roots and stub. */
|
|
65
|
+
function validatePublishedTailTrim(session, manifestSeq) {
|
|
66
|
+
const events = sessionEvents(session);
|
|
67
|
+
const manifest = events[manifestSeq];
|
|
68
|
+
if (manifest?.type !== "compaction/prune" || manifest.data.shadowedSeqs.length < 2 || manifest.data.shadowedSeqs.length > MAX_ROOTS || manifest.data.shadowedSeqs[0] !== manifest.data.shadowedRange.start || manifest.data.shadowedSeqs.at(-1) !== manifest.data.shadowedRange.end || new Set(manifest.data.shadowedSeqs).size !== manifest.data.shadowedSeqs.length) return null;
|
|
69
|
+
const replacement = events[manifestSeq + 1];
|
|
70
|
+
if (replacement?.type !== "user/message" || replacement.seq !== manifest.seq + 1 || replacement.data.source.kind !== "context-compression-prune" || replacement.data.source.plugin !== PRUNE_SOURCE_PLUGIN || replacement.surfaceOp === void 0 || replacement.surfaceOp === "append" || replacement.surfaceOp.startSeq !== manifest.data.shadowedRange.start || replacement.surfaceOp.endSeq !== manifest.data.shadowedRange.end || !sameNumbers(replacement.sourceEventSeqs, [manifest.seq, ...manifest.data.shadowedSeqs]) || replacement.data.content.length !== 1 || replacement.data.content[0]?.type !== "text") return null;
|
|
71
|
+
const tracedRoots = manifest.data.shadowedSeqs.map((seq) => uniqueAppendRoot(session, seq, manifestSeq));
|
|
72
|
+
if (tracedRoots.some((root) => root === null)) return null;
|
|
73
|
+
const sourceEventSeqs = tracedRoots;
|
|
74
|
+
if (new Set(sourceEventSeqs).size !== sourceEventSeqs.length) return null;
|
|
75
|
+
const roots = sourceEventSeqs.map((seq) => events[seq]);
|
|
76
|
+
if (roots.some((event) => event === void 0)) return null;
|
|
77
|
+
const typedRoots = roots;
|
|
78
|
+
if (!validRootGroup(typedRoots, manifestSeq)) return null;
|
|
79
|
+
const assistant = typedRoots[0];
|
|
80
|
+
if (assistant?.type !== "assistant/message") return null;
|
|
81
|
+
const toolNames = assistant.data.message.content.map((block) => {
|
|
82
|
+
if (block.type !== "tool-call") throw new Error("unreachable");
|
|
83
|
+
return block.name;
|
|
84
|
+
});
|
|
85
|
+
const ref = tailTrimRef(String(session.id), manifestSeq);
|
|
86
|
+
const stub = tailTrimStub(ref, toolNames, sourceEventSeqs);
|
|
87
|
+
if (stub === null || replacement.data.content[0].text !== stub) return null;
|
|
88
|
+
return {
|
|
89
|
+
manifest,
|
|
90
|
+
replacement,
|
|
91
|
+
roots: typedRoots,
|
|
92
|
+
toolNames,
|
|
93
|
+
ref,
|
|
94
|
+
stub
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function uniqueAppendRoot(session, seq, beforeSeq) {
|
|
98
|
+
const events = sessionEvents(session);
|
|
99
|
+
const pending = [{
|
|
100
|
+
seq,
|
|
101
|
+
depth: 0
|
|
102
|
+
}];
|
|
103
|
+
const visited = /* @__PURE__ */ new Set();
|
|
104
|
+
const roots = /* @__PURE__ */ new Set();
|
|
105
|
+
while (pending.length > 0) {
|
|
106
|
+
const next = pending.pop();
|
|
107
|
+
if (next === void 0 || next.depth > MAX_ROOTS || visited.has(next.seq)) continue;
|
|
108
|
+
if (!Number.isSafeInteger(next.seq) || next.seq < 0 || next.seq >= beforeSeq) return null;
|
|
109
|
+
visited.add(next.seq);
|
|
110
|
+
if (visited.size > MAX_ROOTS) return null;
|
|
111
|
+
const event = events[next.seq];
|
|
112
|
+
if (event === void 0 || event.type !== "assistant/message" && event.type !== "tool/result") return null;
|
|
113
|
+
if (event.surfaceOp === "append") roots.add(event.seq);
|
|
114
|
+
else if (typeof event.surfaceOp === "object") {
|
|
115
|
+
const sources = event.sourceEventSeqs;
|
|
116
|
+
if (sources === void 0 || sources.length === 0) return null;
|
|
117
|
+
for (const source of sources) pending.push({
|
|
118
|
+
seq: source,
|
|
119
|
+
depth: next.depth + 1
|
|
120
|
+
});
|
|
121
|
+
} else return null;
|
|
122
|
+
if (roots.size > 1) return null;
|
|
123
|
+
}
|
|
124
|
+
return roots.size === 1 ? [...roots][0] ?? null : null;
|
|
125
|
+
}
|
|
126
|
+
function validRootGroup(roots, manifestSeq) {
|
|
127
|
+
const assistant = roots[0];
|
|
128
|
+
if (assistant?.type !== "assistant/message" || assistant.seq >= manifestSeq || assistant.surfaceOp !== "append" || assistant.data.interrupted === true || assistant.data.message.content.length === 0 || assistant.data.message.content.some((block) => block.type !== "tool-call")) return false;
|
|
129
|
+
const callIds = assistant.data.message.content.map((call) => call.id);
|
|
130
|
+
if (new Set(callIds).size !== callIds.length || roots.length !== callIds.length + 1) return false;
|
|
131
|
+
for (const [index, root] of roots.slice(1).entries()) {
|
|
132
|
+
if (root.type !== "tool/result" || root.seq >= manifestSeq || root.surfaceOp !== "append") return false;
|
|
133
|
+
const message = root.data.message;
|
|
134
|
+
if (message.isError === true || root.data.error !== void 0 || root.data.turn !== assistant.data.turn || root.data.step !== assistant.data.step || String(message.toolCallId) !== String(callIds[index])) return false;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
function sameNumbers(left, right) {
|
|
139
|
+
return left !== void 0 && left.length === right.length && left.every((value, index) => value === right[index]);
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
export { validatePublishedTailTrim as a, tailTrimStub as i, tailTrimMessage as n, sessionEvents as o, tailTrimRef as r, parseTailTrimRef as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xbzb404/dsh-context-compression-selector-runtime",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.1-rc.3",
|
|
4
|
+
"description": "Auditable context-compression runtime for DeepSeek Harness",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./invariant": {
|
|
14
|
+
"types": "./lib/invariant.d.ts",
|
|
15
|
+
"default": "./lib/invariant.js"
|
|
16
|
+
},
|
|
17
|
+
"./package.json": "./package.json"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"lib/**/*.js",
|
|
21
|
+
"lib/**/*.d.ts",
|
|
22
|
+
"assets/**/*",
|
|
23
|
+
"README.md",
|
|
24
|
+
"README.zh.md",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"THIRD_PARTY_NOTICES.md"
|
|
27
|
+
],
|
|
28
|
+
"keywords": [
|
|
29
|
+
"deepseek",
|
|
30
|
+
"harness",
|
|
31
|
+
"context",
|
|
32
|
+
"compression",
|
|
33
|
+
"plugin"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"author": "ZHB",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/xbzb404/dsh-context-compression-selector.git",
|
|
40
|
+
"directory": "packages/runtime"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/xbzb404/dsh-context-compression-selector#readme",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/xbzb404/dsh-context-compression-selector/issues"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@huggingface/tokenizers": "0.1.3"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@deepseek-ai/cordis": ">=4.0.4 <5",
|
|
54
|
+
"@deepseek-ai/schemastery": ">=3.18.4 <4",
|
|
55
|
+
"@deepseek-ai/dsh-agent": ">=0.2.0-rc.2 <0.3.0",
|
|
56
|
+
"@deepseek-ai/dsh-compaction": ">=0.2.0-rc.2 <0.3.0",
|
|
57
|
+
"@deepseek-ai/dsh-invariants": ">=0.2.0-rc.2 <0.3.0",
|
|
58
|
+
"@deepseek-ai/dsh-llm": ">=0.2.0-rc.2 <0.3.0",
|
|
59
|
+
"@deepseek-ai/dsh-session": ">=0.2.0-rc.2 <0.3.0",
|
|
60
|
+
"@deepseek-ai/dsh-settings": ">=0.2.0-rc.2 <0.3.0",
|
|
61
|
+
"@deepseek-ai/dsh-system-prompt": ">=0.2.0-rc.2 <0.3.0",
|
|
62
|
+
"@deepseek-ai/dsh-token-meter": ">=0.2.0-rc.2 <0.3.0",
|
|
63
|
+
"@deepseek-ai/dsh-tools": ">=0.2.0-rc.2 <0.3.0"
|
|
64
|
+
},
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"access": "public",
|
|
67
|
+
"tag": "latest"
|
|
68
|
+
}
|
|
69
|
+
}
|