dsh-context-compression-improved 0.5.2 → 0.5.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.
Files changed (28) hide show
  1. package/.gitattributes +1 -0
  2. package/CHANGELOG.ja.md +144 -119
  3. package/CHANGELOG.ko.md +143 -118
  4. package/CHANGELOG.md +278 -250
  5. package/CHANGELOG.zh.md +131 -109
  6. package/docs/installation.md +103 -103
  7. package/docs/installation.zh.md +100 -100
  8. package/package.json +1 -1
  9. package/packages/selector/cordis.patch.yml +5 -6
  10. package/packages/selector/src/client/EstimatorControls.tsx +277 -277
  11. package/packages/selector/src/client/locales.ts +196 -196
  12. package/packages/selector/src/index.ts +463 -463
  13. package/packages/selector/src/pruner/state.ts +50 -50
  14. package/packages/selector/src/pruner.ts +2402 -2402
  15. package/packages/selector/src/runtime/tokenpilot/advisor-prompt.ts +188 -188
  16. package/packages/selector/src/runtime/tokenpilot/advisor-state.ts +149 -149
  17. package/packages/selector/src/runtime/tokenpilot/advisor.ts +419 -419
  18. package/packages/selector/src/runtime/tokenpilot/benefit.ts +200 -200
  19. package/packages/selector/tests/advisor-report.host.spec.ts +223 -223
  20. package/packages/selector/tests/public/package-contract.client.spec.ts +20 -0
  21. package/packages/selector/tests/runtime/advice-never-withholds.host.spec.ts +232 -232
  22. package/packages/selector/tests/runtime/advisor-invariant.spec.ts +272 -272
  23. package/packages/selector/tests/runtime/advisor.spec.ts +226 -226
  24. package/packages/selector/tests/runtime/char-basis.spec.ts +30 -30
  25. package/packages/selector/tests/runtime/deprecated-preset-options.spec.ts +96 -96
  26. package/packages/selector/tests/runtime/tokenpilot/benefit.spec.ts +217 -217
  27. package/packages/selector/tests/settings-seat.client.spec.ts +29 -4
  28. package/scripts/toolclass-corpus-replay.mjs +281 -281
@@ -1,223 +1,223 @@
1
- /**
2
- * Host-side guard for the advisory advisor's HTTP report route.
3
- *
4
- * Pins the read-only contract: the route registers under both prefixes only
5
- * when the row opts in, a session whose advisor never ran reports nulls and
6
- * empty arrays (not an error), a populated session reports its decay figure
7
- * and score distribution content-free, and every error path answers a
8
- * precise status — 400 for a missing sessionId, 404 for an unknown session,
9
- * 503 when no agents service can resolve sessions at all.
10
- */
11
-
12
- import { Context } from '@deepseek-ai/cordis'
13
- import { afterEach, describe, expect, it } from 'vitest'
14
- import { apply } from '../src/index.ts'
15
- import { getAdvisorState, recordScore, recordRecertified } from '../src/runtime/tokenpilot/advisor-state.ts'
16
-
17
- const REPORT_ROUTE = '/api/dsh-context-compression-improved/advisor-report'
18
- const LEGACY_REPORT_ROUTE = '/endpoint/dsh-context-compression-improved/advisor-report'
19
-
20
- interface RegisteredRoute {
21
- kind: string
22
- path: string
23
- handler: (req: unknown, res: unknown) => unknown
24
- }
25
-
26
- interface FakeResponse {
27
- status?: number
28
- body?: string
29
- }
30
-
31
- let ctx: Context | undefined
32
-
33
- afterEach(async () => {
34
- await ctx?.fiber.dispose()
35
- ctx = undefined
36
- })
37
-
38
- const settle = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 20))
39
-
40
- async function mountWebServer(runtime: Context, routes: RegisteredRoute[]): Promise<void> {
41
- await runtime.plugin({
42
- name: 'fake-webserver',
43
- apply(webCtx) {
44
- webCtx.provide('webServer', {
45
- tables: { exact: new Map<string, RegisteredRoute>() },
46
- register(this: { tables: { exact: Map<string, RegisteredRoute> } }, route: RegisteredRoute) {
47
- const table = this.tables.exact
48
- if (table.has(route.path)) {
49
- throw new Error(`webserver: duplicate ${route.kind} route "${route.path}"`)
50
- }
51
- table.set(route.path, route)
52
- routes.push(route)
53
- return () => {}
54
- },
55
- })
56
- },
57
- })
58
- }
59
-
60
- /** Mount an agents service that knows session 's1' (and nothing else). */
61
- function mountAgents(runtime: Context): void {
62
- void runtime.plugin({
63
- name: 'fake-agents',
64
- apply(serviceCtx) {
65
- serviceCtx.provide('agents', {
66
- get: (id: unknown) => {
67
- if (id !== 's1') return undefined
68
- const session = { id: 's1' }
69
- const state = getAdvisorState(session as never)
70
- state.summary = {
71
- overallTask: 'migrate the auth module',
72
- activeSubtasks: ['port login flow'],
73
- keywords: ['auth'],
74
- todoVersion: 'aaaa1111',
75
- turn: 4,
76
- }
77
- state.lastDecay = { decay: 0.42, weightedChars: 10_000, turn: 4 }
78
- recordScore(state, 3, { score: 0.95, turn: 4 })
79
- recordScore(state, 5, { score: 0.10, turn: 4 })
80
- recordRecertified(state, 5, 4)
81
- return { session }
82
- },
83
- })
84
- },
85
- })
86
- }
87
-
88
- async function invoke(route: RegisteredRoute, req?: unknown): Promise<FakeResponse> {
89
- const captured: FakeResponse = {}
90
- const res = {
91
- writeHead(code: number) { captured.status = code },
92
- end(body?: string) { if (body !== undefined) captured.body = body },
93
- }
94
- await route.handler(req ?? { method: 'GET' }, res)
95
- await settle()
96
- return captured
97
- }
98
-
99
- describe('advisor report route registration', () => {
100
- it('registers both prefixes only when the row opts in', async () => {
101
- const routes: RegisteredRoute[] = []
102
- const runtime = new Context()
103
- ctx = runtime
104
- await mountWebServer(runtime, routes)
105
- apply(runtime, { advisorReportRoute: true })
106
- await settle()
107
- const paths = routes.map(route => route.path)
108
- expect(paths).toContain(REPORT_ROUTE)
109
- expect(paths).toContain(LEGACY_REPORT_ROUTE)
110
- })
111
-
112
- it('registers nothing by default (advisor off adds zero behavior)', async () => {
113
- const routes: RegisteredRoute[] = []
114
- const runtime = new Context()
115
- ctx = runtime
116
- await mountWebServer(runtime, routes)
117
- apply(runtime, {})
118
- await settle()
119
- expect(routes.map(route => route.path)).not.toContain(REPORT_ROUTE)
120
- })
121
- })
122
-
123
- describe('advisor report route responses', () => {
124
- async function mountedRoute(): Promise<RegisteredRoute> {
125
- const routes: RegisteredRoute[] = []
126
- const runtime = new Context()
127
- ctx = runtime
128
- await mountWebServer(runtime, routes)
129
- apply(runtime, { advisorReportRoute: true })
130
- await settle()
131
- const route = routes.find(entry => entry.path === REPORT_ROUTE)
132
- expect(route).toBeDefined()
133
- return route as RegisteredRoute
134
- }
135
-
136
- it('answers 503 without an agents service', async () => {
137
- const route = await mountedRoute()
138
- const response = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=s1` })
139
- expect(response.status).toBe(503)
140
- })
141
-
142
- it('answers 404 for an unknown session and 400 for a missing sessionId', async () => {
143
- const routes: RegisteredRoute[] = []
144
- const runtime = new Context()
145
- ctx = runtime
146
- await mountWebServer(runtime, routes)
147
- mountAgents(runtime)
148
- apply(runtime, { advisorReportRoute: true })
149
- await settle()
150
- const route = routes.find(entry => entry.path === REPORT_ROUTE) as RegisteredRoute
151
-
152
- const unknown = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=other` })
153
- expect(unknown.status).toBe(404)
154
-
155
- const missing = await invoke(route, { url: REPORT_ROUTE })
156
- expect(missing.status).toBe(400)
157
- })
158
-
159
- it('serves the decay figure, summary, and scores content-free', async () => {
160
- const routes: RegisteredRoute[] = []
161
- const runtime = new Context()
162
- ctx = runtime
163
- await mountWebServer(runtime, routes)
164
- mountAgents(runtime)
165
- apply(runtime, { advisorReportRoute: true })
166
- await settle()
167
- const route = routes.find(entry => entry.path === REPORT_ROUTE) as RegisteredRoute
168
-
169
- const response = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=s1` })
170
- expect(response.status).toBe(200)
171
- const body = JSON.parse(response.body ?? '{}') as {
172
- ok: boolean
173
- sessionId: string
174
- advisor: {
175
- summary: { overallTask: string } | null
176
- decay: number | null
177
- weightedChars: number | null
178
- scores: { seq: number, score: number }[]
179
- lowRelevanceSeqs: number[]
180
- }
181
- }
182
- expect(body.ok).toBe(true)
183
- expect(body.sessionId).toBe('s1')
184
- expect(body.advisor.decay).toBeCloseTo(0.42, 12)
185
- expect(body.advisor.summary?.overallTask).toBe('migrate the auth module')
186
- expect(body.advisor.scores).toHaveLength(2)
187
- expect(body.advisor.lowRelevanceSeqs).toEqual([5])
188
- // Content-free: no message text ever rides along.
189
- expect(response.body).not.toContain('"text"')
190
- expect(response.body).not.toContain('"content"')
191
- expect(response.body).not.toContain('apiKey')
192
- })
193
-
194
- it('answers an empty report (nulls, not an error) for a session whose advisor never ran', async () => {
195
- const routes: RegisteredRoute[] = []
196
- const runtime = new Context()
197
- ctx = runtime
198
- await mountWebServer(runtime, routes)
199
- void runtime.plugin({
200
- name: 'fake-agents-empty',
201
- apply(serviceCtx) {
202
- serviceCtx.provide('agents', {
203
- get: (id: unknown) => (id === 's1' ? { session: { id: 's1' } } : undefined),
204
- })
205
- },
206
- })
207
- apply(runtime, { advisorReportRoute: true })
208
- await settle()
209
- const route = routes.find(entry => entry.path === REPORT_ROUTE) as RegisteredRoute
210
-
211
- const response = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=s1` })
212
- expect(response.status).toBe(200)
213
- const body = JSON.parse(response.body ?? '{}') as {
214
- ok: boolean
215
- advisor: { summary: unknown, decay: unknown, scores: unknown[], lowRelevanceSeqs: unknown[] }
216
- }
217
- expect(body.ok).toBe(true)
218
- expect(body.advisor.summary).toBeNull()
219
- expect(body.advisor.decay).toBeNull()
220
- expect(body.advisor.scores).toEqual([])
221
- expect(body.advisor.lowRelevanceSeqs).toEqual([])
222
- })
223
- })
1
+ /**
2
+ * Host-side guard for the advisory advisor's HTTP report route.
3
+ *
4
+ * Pins the read-only contract: the route registers under both prefixes only
5
+ * when the row opts in, a session whose advisor never ran reports nulls and
6
+ * empty arrays (not an error), a populated session reports its decay figure
7
+ * and score distribution content-free, and every error path answers a
8
+ * precise status — 400 for a missing sessionId, 404 for an unknown session,
9
+ * 503 when no agents service can resolve sessions at all.
10
+ */
11
+
12
+ import { Context } from '@deepseek-ai/cordis'
13
+ import { afterEach, describe, expect, it } from 'vitest'
14
+ import { apply } from '../src/index.ts'
15
+ import { getAdvisorState, recordScore, recordRecertified } from '../src/runtime/tokenpilot/advisor-state.ts'
16
+
17
+ const REPORT_ROUTE = '/api/dsh-context-compression-improved/advisor-report'
18
+ const LEGACY_REPORT_ROUTE = '/endpoint/dsh-context-compression-improved/advisor-report'
19
+
20
+ interface RegisteredRoute {
21
+ kind: string
22
+ path: string
23
+ handler: (req: unknown, res: unknown) => unknown
24
+ }
25
+
26
+ interface FakeResponse {
27
+ status?: number
28
+ body?: string
29
+ }
30
+
31
+ let ctx: Context | undefined
32
+
33
+ afterEach(async () => {
34
+ await ctx?.fiber.dispose()
35
+ ctx = undefined
36
+ })
37
+
38
+ const settle = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 20))
39
+
40
+ async function mountWebServer(runtime: Context, routes: RegisteredRoute[]): Promise<void> {
41
+ await runtime.plugin({
42
+ name: 'fake-webserver',
43
+ apply(webCtx) {
44
+ webCtx.provide('webServer', {
45
+ tables: { exact: new Map<string, RegisteredRoute>() },
46
+ register(this: { tables: { exact: Map<string, RegisteredRoute> } }, route: RegisteredRoute) {
47
+ const table = this.tables.exact
48
+ if (table.has(route.path)) {
49
+ throw new Error(`webserver: duplicate ${route.kind} route "${route.path}"`)
50
+ }
51
+ table.set(route.path, route)
52
+ routes.push(route)
53
+ return () => {}
54
+ },
55
+ })
56
+ },
57
+ })
58
+ }
59
+
60
+ /** Mount an agents service that knows session 's1' (and nothing else). */
61
+ function mountAgents(runtime: Context): void {
62
+ void runtime.plugin({
63
+ name: 'fake-agents',
64
+ apply(serviceCtx) {
65
+ serviceCtx.provide('agents', {
66
+ get: (id: unknown) => {
67
+ if (id !== 's1') return undefined
68
+ const session = { id: 's1' }
69
+ const state = getAdvisorState(session as never)
70
+ state.summary = {
71
+ overallTask: 'migrate the auth module',
72
+ activeSubtasks: ['port login flow'],
73
+ keywords: ['auth'],
74
+ todoVersion: 'aaaa1111',
75
+ turn: 4,
76
+ }
77
+ state.lastDecay = { decay: 0.42, weightedChars: 10_000, turn: 4 }
78
+ recordScore(state, 3, { score: 0.95, turn: 4 })
79
+ recordScore(state, 5, { score: 0.10, turn: 4 })
80
+ recordRecertified(state, 5, 4)
81
+ return { session }
82
+ },
83
+ })
84
+ },
85
+ })
86
+ }
87
+
88
+ async function invoke(route: RegisteredRoute, req?: unknown): Promise<FakeResponse> {
89
+ const captured: FakeResponse = {}
90
+ const res = {
91
+ writeHead(code: number) { captured.status = code },
92
+ end(body?: string) { if (body !== undefined) captured.body = body },
93
+ }
94
+ await route.handler(req ?? { method: 'GET' }, res)
95
+ await settle()
96
+ return captured
97
+ }
98
+
99
+ describe('advisor report route registration', () => {
100
+ it('registers both prefixes only when the row opts in', async () => {
101
+ const routes: RegisteredRoute[] = []
102
+ const runtime = new Context()
103
+ ctx = runtime
104
+ await mountWebServer(runtime, routes)
105
+ apply(runtime, { advisorReportRoute: true })
106
+ await settle()
107
+ const paths = routes.map(route => route.path)
108
+ expect(paths).toContain(REPORT_ROUTE)
109
+ expect(paths).toContain(LEGACY_REPORT_ROUTE)
110
+ })
111
+
112
+ it('registers nothing by default (advisor off adds zero behavior)', async () => {
113
+ const routes: RegisteredRoute[] = []
114
+ const runtime = new Context()
115
+ ctx = runtime
116
+ await mountWebServer(runtime, routes)
117
+ apply(runtime, {})
118
+ await settle()
119
+ expect(routes.map(route => route.path)).not.toContain(REPORT_ROUTE)
120
+ })
121
+ })
122
+
123
+ describe('advisor report route responses', () => {
124
+ async function mountedRoute(): Promise<RegisteredRoute> {
125
+ const routes: RegisteredRoute[] = []
126
+ const runtime = new Context()
127
+ ctx = runtime
128
+ await mountWebServer(runtime, routes)
129
+ apply(runtime, { advisorReportRoute: true })
130
+ await settle()
131
+ const route = routes.find(entry => entry.path === REPORT_ROUTE)
132
+ expect(route).toBeDefined()
133
+ return route as RegisteredRoute
134
+ }
135
+
136
+ it('answers 503 without an agents service', async () => {
137
+ const route = await mountedRoute()
138
+ const response = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=s1` })
139
+ expect(response.status).toBe(503)
140
+ })
141
+
142
+ it('answers 404 for an unknown session and 400 for a missing sessionId', async () => {
143
+ const routes: RegisteredRoute[] = []
144
+ const runtime = new Context()
145
+ ctx = runtime
146
+ await mountWebServer(runtime, routes)
147
+ mountAgents(runtime)
148
+ apply(runtime, { advisorReportRoute: true })
149
+ await settle()
150
+ const route = routes.find(entry => entry.path === REPORT_ROUTE) as RegisteredRoute
151
+
152
+ const unknown = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=other` })
153
+ expect(unknown.status).toBe(404)
154
+
155
+ const missing = await invoke(route, { url: REPORT_ROUTE })
156
+ expect(missing.status).toBe(400)
157
+ })
158
+
159
+ it('serves the decay figure, summary, and scores content-free', async () => {
160
+ const routes: RegisteredRoute[] = []
161
+ const runtime = new Context()
162
+ ctx = runtime
163
+ await mountWebServer(runtime, routes)
164
+ mountAgents(runtime)
165
+ apply(runtime, { advisorReportRoute: true })
166
+ await settle()
167
+ const route = routes.find(entry => entry.path === REPORT_ROUTE) as RegisteredRoute
168
+
169
+ const response = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=s1` })
170
+ expect(response.status).toBe(200)
171
+ const body = JSON.parse(response.body ?? '{}') as {
172
+ ok: boolean
173
+ sessionId: string
174
+ advisor: {
175
+ summary: { overallTask: string } | null
176
+ decay: number | null
177
+ weightedChars: number | null
178
+ scores: { seq: number, score: number }[]
179
+ lowRelevanceSeqs: number[]
180
+ }
181
+ }
182
+ expect(body.ok).toBe(true)
183
+ expect(body.sessionId).toBe('s1')
184
+ expect(body.advisor.decay).toBeCloseTo(0.42, 12)
185
+ expect(body.advisor.summary?.overallTask).toBe('migrate the auth module')
186
+ expect(body.advisor.scores).toHaveLength(2)
187
+ expect(body.advisor.lowRelevanceSeqs).toEqual([5])
188
+ // Content-free: no message text ever rides along.
189
+ expect(response.body).not.toContain('"text"')
190
+ expect(response.body).not.toContain('"content"')
191
+ expect(response.body).not.toContain('apiKey')
192
+ })
193
+
194
+ it('answers an empty report (nulls, not an error) for a session whose advisor never ran', async () => {
195
+ const routes: RegisteredRoute[] = []
196
+ const runtime = new Context()
197
+ ctx = runtime
198
+ await mountWebServer(runtime, routes)
199
+ void runtime.plugin({
200
+ name: 'fake-agents-empty',
201
+ apply(serviceCtx) {
202
+ serviceCtx.provide('agents', {
203
+ get: (id: unknown) => (id === 's1' ? { session: { id: 's1' } } : undefined),
204
+ })
205
+ },
206
+ })
207
+ apply(runtime, { advisorReportRoute: true })
208
+ await settle()
209
+ const route = routes.find(entry => entry.path === REPORT_ROUTE) as RegisteredRoute
210
+
211
+ const response = await invoke(route, { url: `${REPORT_ROUTE}?sessionId=s1` })
212
+ expect(response.status).toBe(200)
213
+ const body = JSON.parse(response.body ?? '{}') as {
214
+ ok: boolean
215
+ advisor: { summary: unknown, decay: unknown, scores: unknown[], lowRelevanceSeqs: unknown[] }
216
+ }
217
+ expect(body.ok).toBe(true)
218
+ expect(body.advisor.summary).toBeNull()
219
+ expect(body.advisor.decay).toBeNull()
220
+ expect(body.advisor.scores).toEqual([])
221
+ expect(body.advisor.lowRelevanceSeqs).toEqual([])
222
+ })
223
+ })
@@ -55,4 +55,24 @@ describe('standalone package contract', () => {
55
55
  expect(patch).toContain("name: 'dsh-context-compression-improved'")
56
56
  expect(patch).not.toContain('@deepseek-ai/dsh-client-ui-context-compression-selector')
57
57
  })
58
+
59
+ it('never ships a retired plugin config key in the Bundle patch', () => {
60
+ // Negative control: the patch is loaded by the host and validated against
61
+ // the plugin's own Config schema, but nothing tied the two together — so
62
+ // the retired review gate's `reviewQueueRoute` survived in this file after
63
+ // the key was removed from the schema, advertising a route that can never
64
+ // register. A retired key must fail here instead of shipping quietly.
65
+ //
66
+ // The pin is on KEY-SETTING lines, not on the whole document: the comments
67
+ // above the rows deliberately name the retired key while explaining why it
68
+ // is gone, and prose must not be mistaken for configuration.
69
+ const patch = readFileSync(resolve(root, 'selector/cordis.patch.yml'), 'utf8')
70
+ const lines = patch.split('\n')
71
+ for (const retired of ['reviewQueueRoute', 'reviewMode', 'reviewTimeoutTurns', 'reviewHighImpactTokens']) {
72
+ const setsRetired = lines.find(line => new RegExp(`^\\s*${retired}\\s*:`).test(line))
73
+ expect(setsRetired, `${retired} is still set in the Bundle patch`).toBeUndefined()
74
+ }
75
+ // And the live flag the routes row exists for is still wired.
76
+ expect(patch).toContain('estimatorCatalogRoute: true')
77
+ })
58
78
  })