dsh-context-compression-improved 0.5.1 → 0.5.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/CHANGELOG.ja.md +36 -0
- package/CHANGELOG.ko.md +36 -0
- package/CHANGELOG.md +38 -0
- package/CHANGELOG.zh.md +32 -0
- package/package.json +1 -1
- package/packages/selector/lib/advisor-state.js +4 -231
- package/packages/selector/lib/client.d.ts +0 -24
- package/packages/selector/lib/client.js +6 -501
- package/packages/selector/lib/index.d.ts +4 -10
- package/packages/selector/lib/index.js +16 -234
- package/packages/selector/lib/pruner.d.ts +13 -248
- package/packages/selector/lib/pruner.js +148 -552
- package/packages/selector/src/client/EstimatorControls.tsx +277 -378
- package/packages/selector/src/client/index.ts +0 -17
- package/packages/selector/src/client/locales.ts +196 -234
- package/packages/selector/src/client/preset-options.ts +3 -2
- package/packages/selector/src/client/settings-section.tsx +8 -17
- package/packages/selector/src/index.ts +463 -710
- package/packages/selector/src/profiles.ts +4 -27
- package/packages/selector/src/pruner/state.ts +50 -73
- package/packages/selector/src/pruner.ts +2402 -2730
- package/packages/selector/src/runtime/audit.ts +27 -21
- package/packages/selector/src/runtime/config.ts +6 -32
- package/packages/selector/src/runtime/tokenpilot/advisor-state.ts +16 -0
- package/packages/selector/src/runtime/tokenpilot/benefit.ts +200 -0
- package/packages/selector/src/runtime/types.ts +0 -17
- package/packages/selector/tests/preset-options-write.client.spec.ts +7 -23
- package/packages/selector/tests/runtime/advice-never-withholds.host.spec.ts +232 -0
- package/packages/selector/tests/runtime/audit.spec.ts +35 -21
- package/packages/selector/tests/runtime/deprecated-preset-options.spec.ts +96 -0
- package/packages/selector/tests/runtime/tokenpilot/benefit.spec.ts +217 -0
- package/packages/selector/tests/runtime/tokenpilot/profile-baseline.spec.ts +4 -5
- package/packages/selector/tests/settings-seat.client.spec.ts +16 -10
- package/packages/selector/src/client/ReviewOverlay.tsx +0 -320
- package/packages/selector/src/client/review-scope.ts +0 -16
- package/packages/selector/src/runtime/tokenpilot/proposal.ts +0 -267
- package/packages/selector/src/runtime/tokenpilot/review-queue.ts +0 -231
- package/packages/selector/src/runtime/tokenpilot/review-registry.ts +0 -117
- package/packages/selector/src/runtime/tokenpilot/review-storage.ts +0 -122
- package/packages/selector/tests/review-overlay.client.spec.tsx +0 -118
- package/packages/selector/tests/review-routes-registry.host.spec.ts +0 -142
- package/packages/selector/tests/review-routes.host.spec.ts +0 -290
- package/packages/selector/tests/runtime/tokenpilot/proposal.spec.ts +0 -393
- package/packages/selector/tests/runtime/tokenpilot/pruner-review.spec.ts +0 -382
- package/packages/selector/tests/runtime/tokenpilot/review-queue.spec.ts +0 -168
package/CHANGELOG.ja.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
> 完全な履歴(アップストリーム 0.1.0 以前を含む)は [CHANGELOG.md](CHANGELOG.md) を参照。このファイルはフォークの追加エントリーのみを翻訳したものです。 · [English](CHANGELOG.md) · [中文](CHANGELOG.zh.md) · [한국어](CHANGELOG.ko.md)
|
|
4
4
|
|
|
5
|
+
## 0.5.2 - 2026-09-20
|
|
6
|
+
|
|
7
|
+
### Changed(変更)
|
|
8
|
+
|
|
9
|
+
- 人手ゲート付きレビューパイプライン(review gate、beta)を**廃止**しました。その意味論は
|
|
10
|
+
「助言」に置き換わります。便益モデルは従来どおり 1 パスを 1 回の統合 mutation として
|
|
11
|
+
価格付けしますが、算出したバンド(`profitable` / `high-impact` / `slow-payback` /
|
|
12
|
+
`unpriceable` / `not-worth-it`)は `reduction-advice` 監査レコードとして公開され、
|
|
13
|
+
advisor レポートルートにスナップショットされるだけになりました——reduction を保留・遅延・
|
|
14
|
+
書き換えることはありません。この gate は機能自身の要件(削減は自動処理を妨げない)と矛盾し、
|
|
15
|
+
出荷既定(`reviewMode` 有効 + 4,000 トークンの高影響しきい値に対し 8,192 トークンの
|
|
16
|
+
fresh トリガー)では fresh バッチを 100% 人手レビューへ迂回させ、有効化した利用者から
|
|
17
|
+
自動経路を事実上奪っていました。助言のしきい値はモジュール定数(α `0.1`、高影響
|
|
18
|
+
`4,000` トークン)になりました。何もこれに従って動作しないため、設定項目ではなくなります。
|
|
19
|
+
- gate とともに削除:レビューキューとその `storageDomain` アダプタ、プロセス全体の
|
|
20
|
+
レジストリ、`review-queue` / `review-decide` の HTTP ルートと `reviewQueueRoute` 配置
|
|
21
|
+
フラグ、`shell.overlay` クライアントパネル、`reviewMode` / `reviewTimeoutTurns` /
|
|
22
|
+
`cacheHitDiscountAlpha` / `reviewHighImpactTokens` の設定キー、`review-outcome` 監査種別。
|
|
23
|
+
4 つの設定キーは**両方のデコーダで引き続き受理され無視されます**——既存の文書(稼働中は
|
|
24
|
+
`reviewMode: false` を含む)はそのまま読み込まれ、設定カードも表示されます——そして解決済み
|
|
25
|
+
policy には決して到達しません。読み取り専用の `GET .../advisor-report` は `lastAdvice` も
|
|
26
|
+
返します。
|
|
27
|
+
|
|
28
|
+
### Added(追加)
|
|
29
|
+
|
|
30
|
+
- 廃止に対する回帰ピン:かつて全量を迂回させていた設定(`reviewMode: true`、
|
|
31
|
+
`reviewHighImpactTokens: 1`)で fresh バッチが**そのまま着地**し、`high-impact` の助言
|
|
32
|
+
レコードがそれを記述することをホスト統合テストで固定。ランタイムパーサとブラウザデコーダの
|
|
33
|
+
両側で「受理して無視」を固定する非推奨契約テストも追加。
|
|
34
|
+
|
|
35
|
+
### Rollback(ロールバック)
|
|
36
|
+
|
|
37
|
+
- gate を含む最後のリリースへ戻す:`npm dist-tag add
|
|
38
|
+
dsh-context-compression-improved@0.5.1 dsh-0.1.5 --registry https://registry.npmjs.org/`
|
|
39
|
+
の後、`dsh plugin --profile web add dsh-context-compression-improved@0.5.1`。
|
|
40
|
+
|
|
5
41
|
## 0.5.1 - 2026-09-20
|
|
6
42
|
|
|
7
43
|
### Fixed(修正)
|
package/CHANGELOG.ko.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
> 전체 히스토리(업스트림 0.1.0 이전 포함)는 [CHANGELOG.md](CHANGELOG.md)를 참고하세요. 이 파일은 포크의 추가 항목만 번역한 것입니다. · [English](CHANGELOG.md) · [中文](CHANGELOG.zh.md) · [日本語](CHANGELOG.ja.md)
|
|
4
4
|
|
|
5
|
+
## 0.5.2 - 2026-09-20
|
|
6
|
+
|
|
7
|
+
### Changed(변경)
|
|
8
|
+
|
|
9
|
+
- 사람이 승인하는 리뷰 파이프라인(review gate, beta)을 **폐기**했습니다. 그 의미론은
|
|
10
|
+
"조언"으로 대체됩니다. 이익 모델은 여전히 한 패스를 하나의 병합 mutation으로 가격
|
|
11
|
+
책정하지만, 계산한 밴드(`profitable` / `high-impact` / `slow-payback` /
|
|
12
|
+
`unpriceable` / `not-worth-it`)는 이제 `reduction-advice` 감사 레코드로 게시되고 advisor
|
|
13
|
+
리포트 라우트에 스냅샷될 뿐입니다——reduction을 보류·지연·재작성하지 않습니다. 이 gate는
|
|
14
|
+
기능 자체의 요구(축소는 자동 처리를 막지 않는다)와 모순되었고, 출하 기본값(`reviewMode`
|
|
15
|
+
켬 + 4,000 토큰 고영향 임계값 대 8,192 토큰 fresh 트리거)에서는 fresh 배치를 100% 사람
|
|
16
|
+
리뷰로 우회시켜, 이를 켠 사용자에게서 자동 경로를 사실상 빼앗았습니다. 조언 임계값은 이제
|
|
17
|
+
모듈 상수(α `0.1`, 고영향 `4,000` 토큰)입니다. 아무 경로도 이에 따라 동작하지 않으므로
|
|
18
|
+
더 이상 설정 항목이 아닙니다.
|
|
19
|
+
- gate와 함께 제거: 리뷰 큐와 그 `storageDomain` 어댑터, 프로세스 전역 레지스트리,
|
|
20
|
+
`review-queue` / `review-decide` HTTP 라우트와 `reviewQueueRoute` 배포 플래그,
|
|
21
|
+
`shell.overlay` 클라이언트 패널, `reviewMode` / `reviewTimeoutTurns` /
|
|
22
|
+
`cacheHitDiscountAlpha` / `reviewHighImpactTokens` 설정 키, `review-outcome` 감사 종류.
|
|
23
|
+
네 개의 설정 키는 **두 디코더 모두에서 계속 허용되고 무시됩니다**——기존 문서(운영 중인
|
|
24
|
+
문서에는 `reviewMode: false`가 있음)는 그대로 로드되고 설정 카드도 렌더링됩니다——그리고
|
|
25
|
+
해석된 policy에는 결코 도달하지 않습니다. 읽기 전용 `GET .../advisor-report`는
|
|
26
|
+
`lastAdvice`도 함께 제공합니다.
|
|
27
|
+
|
|
28
|
+
### Added(추가)
|
|
29
|
+
|
|
30
|
+
- 폐기에 대한 회귀 고정: 예전에 전량을 우회시키던 설정(`reviewMode: true`,
|
|
31
|
+
`reviewHighImpactTokens: 1`)으로 fresh 배치가 **그대로 착지**하고 `high-impact` 조언
|
|
32
|
+
레코드가 이를 설명함을 호스트 통합 테스트로 고정했습니다. 런타임 파서와 브라우저 디코더
|
|
33
|
+
양쪽에서 "허용 후 무시"를 고정하는 폐기 계약 테스트도 추가했습니다.
|
|
34
|
+
|
|
35
|
+
### Rollback(롤백)
|
|
36
|
+
|
|
37
|
+
- gate를 포함한 마지막 릴리스로 되돌리기: `npm dist-tag add
|
|
38
|
+
dsh-context-compression-improved@0.5.1 dsh-0.1.5 --registry https://registry.npmjs.org/`
|
|
39
|
+
후 `dsh plugin --profile web add dsh-context-compression-improved@0.5.1`.
|
|
40
|
+
|
|
5
41
|
## 0.5.1 - 2026-09-20
|
|
6
42
|
|
|
7
43
|
### Fixed(수정)
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes use this file. The project follows semantic versioning after `0.1.0`.
|
|
4
4
|
|
|
5
|
+
## 0.5.2 - 2026-09-20
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- The human-gated review pipeline (beta) is **retired**. Its semantics are replaced by
|
|
10
|
+
advice: the benefit model still prices every pass as ONE merged mutation, but the band it
|
|
11
|
+
computes (`profitable` / `high-impact` / `slow-payback` / `unpriceable` / `not-worth-it`)
|
|
12
|
+
is now published as a `reduction-advice` audit record and snapshotted onto the advisor
|
|
13
|
+
report route — it never withholds, delays, or rewrites a reduction. The gate contradicted
|
|
14
|
+
the feature's own requirement (a reduction must never block automatic processing) and, with
|
|
15
|
+
the shipped defaults (`reviewMode` on plus a 4,000-token high-impact threshold against an
|
|
16
|
+
8,192-token fresh trigger), diverted 100% of a fresh batch into human review, leaving the
|
|
17
|
+
automatic path effectively off for anyone who opted in. The advice thresholds are now
|
|
18
|
+
module constants (α `0.1`, high-impact `4,000` tokens): nothing acts on them, so they are
|
|
19
|
+
no longer settings.
|
|
20
|
+
- Removed with the gate: the review queue and its `storageDomain` adapter, the process-wide
|
|
21
|
+
registry, the `review-queue` / `review-decide` HTTP routes and the `reviewQueueRoute`
|
|
22
|
+
deployment flag, the `shell.overlay` client panel, the `reviewMode` /
|
|
23
|
+
`reviewTimeoutTurns` / `cacheHitDiscountAlpha` / `reviewHighImpactTokens` settings keys,
|
|
24
|
+
and the `review-outcome` audit kind. The four settings keys stay ACCEPTED and IGNORED by
|
|
25
|
+
both decoders — an existing document (the live one carries `reviewMode: false`) still loads
|
|
26
|
+
and still renders its settings card — and never reach the resolved policy. The read-only
|
|
27
|
+
`GET .../advisor-report` route additionally serves `lastAdvice`.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- Regression pins for the retirement: a host-integration spec drives the exact settings that
|
|
32
|
+
used to divert everything (`reviewMode: true`, `reviewHighImpactTokens: 1`) and asserts the
|
|
33
|
+
fresh batch LANDS, described by a `high-impact` advice record; a deprecation-contract spec
|
|
34
|
+
pins accept-and-ignore for the retired keys on both the runtime parser and the browser
|
|
35
|
+
decoder.
|
|
36
|
+
|
|
37
|
+
### Rollback
|
|
38
|
+
|
|
39
|
+
- Reinstall the last release that still ships the gate: `npm dist-tag add
|
|
40
|
+
dsh-context-compression-improved@0.5.1 dsh-0.1.5 --registry https://registry.npmjs.org/`
|
|
41
|
+
then `dsh plugin --profile web add dsh-context-compression-improved@0.5.1`.
|
|
42
|
+
|
|
5
43
|
## 0.5.1 - 2026-09-20
|
|
6
44
|
|
|
7
45
|
### Fixed
|
package/CHANGELOG.zh.md
CHANGED
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
> 完整历史(含上游 0.1.0 及更早版本)见 [CHANGELOG.md](CHANGELOG.md)。本文件只翻译本 fork 的新增条目。 · [English](CHANGELOG.md) · [日本語](CHANGELOG.ja.md) · [한국어](CHANGELOG.ko.md)
|
|
4
4
|
|
|
5
|
+
## 0.5.2 - 2026-09-20
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **退役**人工审查管线(review gate,beta)。其语义由"建议"取代:收益模型仍按"整批一次
|
|
10
|
+
mutation"定价,但它算出的分带(`profitable` / `high-impact` / `slow-payback` /
|
|
11
|
+
`unpriceable` / `not-worth-it`)现在只作为 `reduction-advice` 审计记录发布,并在 advisor
|
|
12
|
+
报告路由上留一份快照——绝不扣留、延迟或改写任何 reduction。该 gate 与本功能自身的要求
|
|
13
|
+
(缩减不阻断自动处理)相矛盾,且在出厂默认下(`reviewMode` 开 + 4000 token 高影响阈值
|
|
14
|
+
对 8192 token 的 fresh 门槛)会把整批 fresh 100% 改道进人审,等于让选择开启它的用户失去
|
|
15
|
+
自动路径。建议阈值改为模块常量(α `0.1`、高影响 `4000` token):没有任何路径依据它们
|
|
16
|
+
行动,因此不再作为配置项。
|
|
17
|
+
- 随 gate 一并移除:审查队列及其 `storageDomain` 适配器、进程级注册表、
|
|
18
|
+
`review-queue` / `review-decide` 两条 HTTP 路由与 `reviewQueueRoute` 部署开关、
|
|
19
|
+
`shell.overlay` 客户端浮窗、`reviewMode` / `reviewTimeoutTurns` /
|
|
20
|
+
`cacheHitDiscountAlpha` / `reviewHighImpactTokens` 四个 settings 键,以及
|
|
21
|
+
`review-outcome` 审计类型。这四个键在**两个解码器**中仍被接受但被忽略——既有配置文档
|
|
22
|
+
(线上即带 `reviewMode: false`)照常加载、设置卡照常渲染——且永不进入已解析的 policy。
|
|
23
|
+
只读路由 `GET .../advisor-report` 额外提供 `lastAdvice`。
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- 退役的回归钉桩:一条宿主集成测试用**当年会全量改道的那套配置**(`reviewMode: true`、
|
|
28
|
+
`reviewHighImpactTokens: 1`)断言 fresh 批次**照常落地**并附带 `high-impact` 建议记录;
|
|
29
|
+
另一条弃用契约测试在运行时解析器与浏览器解码器两侧钉死"接受但忽略"。
|
|
30
|
+
|
|
31
|
+
### Rollback
|
|
32
|
+
|
|
33
|
+
- 回退到仍带 gate 的最后一个版本:`npm dist-tag add
|
|
34
|
+
dsh-context-compression-improved@0.5.1 dsh-0.1.5 --registry https://registry.npmjs.org/`,
|
|
35
|
+
然后 `dsh plugin --profile web add dsh-context-compression-improved@0.5.1`。
|
|
36
|
+
|
|
5
37
|
## 0.5.1 - 2026-09-20
|
|
6
38
|
|
|
7
39
|
### Fixed
|
package/package.json
CHANGED
|
@@ -408,8 +408,7 @@ function parsePresetOptionsSettings(value) {
|
|
|
408
408
|
"dedupeToolResults",
|
|
409
409
|
"summaryLocator",
|
|
410
410
|
"prefixStabilizer",
|
|
411
|
-
"readState"
|
|
412
|
-
"reviewMode"
|
|
411
|
+
"readState"
|
|
413
412
|
]) {
|
|
414
413
|
const entry = value[key];
|
|
415
414
|
if (entry !== void 0 && typeof entry !== "boolean") throw new TypeError(`Context-compression presetOptions.${key} must be a boolean`);
|
|
@@ -430,12 +429,6 @@ function parsePresetOptionsSettings(value) {
|
|
|
430
429
|
if (advisorMinTokens !== void 0 && (typeof advisorMinTokens !== "number" || !Number.isSafeInteger(advisorMinTokens) || advisorMinTokens < 1)) throw new TypeError("Context-compression presetOptions.advisorMinTokens must be a positive integer");
|
|
431
430
|
const estimatorTimeoutMs = value.estimatorTimeoutMs;
|
|
432
431
|
if (estimatorTimeoutMs !== void 0 && (typeof estimatorTimeoutMs !== "number" || !Number.isSafeInteger(estimatorTimeoutMs) || estimatorTimeoutMs < 100 || estimatorTimeoutMs > 6e4)) throw new TypeError("Context-compression presetOptions.estimatorTimeoutMs must be an integer between 100 and 60000");
|
|
433
|
-
const reviewTimeoutTurns = value.reviewTimeoutTurns;
|
|
434
|
-
if (reviewTimeoutTurns !== void 0 && (typeof reviewTimeoutTurns !== "number" || !Number.isSafeInteger(reviewTimeoutTurns) || reviewTimeoutTurns < 1)) throw new TypeError("Context-compression presetOptions.reviewTimeoutTurns must be an integer of at least 1");
|
|
435
|
-
const cacheHitDiscountAlpha = value.cacheHitDiscountAlpha;
|
|
436
|
-
if (cacheHitDiscountAlpha !== void 0 && (typeof cacheHitDiscountAlpha !== "number" || !Number.isFinite(cacheHitDiscountAlpha) || cacheHitDiscountAlpha <= 0 || cacheHitDiscountAlpha >= 1)) throw new TypeError("Context-compression presetOptions.cacheHitDiscountAlpha must be a number strictly between 0 and 1");
|
|
437
|
-
const reviewHighImpactTokens = value.reviewHighImpactTokens;
|
|
438
|
-
if (reviewHighImpactTokens !== void 0 && (typeof reviewHighImpactTokens !== "number" || !Number.isSafeInteger(reviewHighImpactTokens) || reviewHighImpactTokens < 0)) throw new TypeError("Context-compression presetOptions.reviewHighImpactTokens must be a non-negative integer");
|
|
439
432
|
for (const key of [
|
|
440
433
|
"estimatorProvider",
|
|
441
434
|
"estimatorModel",
|
|
@@ -456,10 +449,6 @@ function parsePresetOptionsSettings(value) {
|
|
|
456
449
|
if (value.estimatorBaseUrl !== void 0) result.estimatorBaseUrl = value.estimatorBaseUrl;
|
|
457
450
|
if (value.estimatorApiKey !== void 0) result.estimatorApiKey = value.estimatorApiKey;
|
|
458
451
|
if (estimatorTimeoutMs !== void 0) result.estimatorTimeoutMs = estimatorTimeoutMs;
|
|
459
|
-
if (value.reviewMode !== void 0) result.reviewMode = value.reviewMode;
|
|
460
|
-
if (reviewTimeoutTurns !== void 0) result.reviewTimeoutTurns = reviewTimeoutTurns;
|
|
461
|
-
if (cacheHitDiscountAlpha !== void 0) result.cacheHitDiscountAlpha = cacheHitDiscountAlpha;
|
|
462
|
-
if (reviewHighImpactTokens !== void 0) result.reviewHighImpactTokens = reviewHighImpactTokens;
|
|
463
452
|
if (advisorMode !== void 0) result.advisorMode = advisorMode;
|
|
464
453
|
if (advisorTimeoutMs !== void 0) result.advisorTimeoutMs = advisorTimeoutMs;
|
|
465
454
|
if (advisorRefreshTurns !== void 0) result.advisorRefreshTurns = advisorRefreshTurns;
|
|
@@ -681,10 +670,6 @@ const PRESET_OPTION_DEFAULTS = deepFreeze({
|
|
|
681
670
|
prefixStabilizer: true,
|
|
682
671
|
readState: true,
|
|
683
672
|
estimator: { mode: "" },
|
|
684
|
-
reviewMode: false,
|
|
685
|
-
reviewTimeoutTurns: 6,
|
|
686
|
-
cacheHitDiscountAlpha: .1,
|
|
687
|
-
reviewHighImpactTokens: 4e3,
|
|
688
673
|
advisor: {
|
|
689
674
|
mode: "",
|
|
690
675
|
timeoutMs: 8e3,
|
|
@@ -709,10 +694,6 @@ function mergePresetOptions(overrides) {
|
|
|
709
694
|
prefixStabilizer: overrides.prefixStabilizer ?? PRESET_OPTION_DEFAULTS.prefixStabilizer,
|
|
710
695
|
readState: overrides.readState ?? PRESET_OPTION_DEFAULTS.readState,
|
|
711
696
|
estimator: { mode: overrides.estimatorMode ?? PRESET_OPTION_DEFAULTS.estimator.mode },
|
|
712
|
-
reviewMode: overrides.reviewMode ?? PRESET_OPTION_DEFAULTS.reviewMode,
|
|
713
|
-
reviewTimeoutTurns: overrides.reviewTimeoutTurns ?? PRESET_OPTION_DEFAULTS.reviewTimeoutTurns,
|
|
714
|
-
cacheHitDiscountAlpha: overrides.cacheHitDiscountAlpha ?? PRESET_OPTION_DEFAULTS.cacheHitDiscountAlpha,
|
|
715
|
-
reviewHighImpactTokens: overrides.reviewHighImpactTokens ?? PRESET_OPTION_DEFAULTS.reviewHighImpactTokens,
|
|
716
697
|
advisor: {
|
|
717
698
|
mode: overrides.advisorMode ?? PRESET_OPTION_DEFAULTS.advisor.mode,
|
|
718
699
|
timeoutMs: overrides.advisorTimeoutMs ?? PRESET_OPTION_DEFAULTS.advisor.timeoutMs,
|
|
@@ -915,215 +896,6 @@ function assertPositiveInteger(name, value) {
|
|
|
915
896
|
function assertNonNegativeInteger(name, value) {
|
|
916
897
|
if (!Number.isSafeInteger(value) || value < 0) throw new Error(`ToolResultPruneConfig: ${name} (${String(value)}) must be a non-negative safe integer`);
|
|
917
898
|
}
|
|
918
|
-
//#endregion
|
|
919
|
-
//#region src/runtime/tokenpilot/review-queue.ts
|
|
920
|
-
/** In-memory store: the fail-open fallback when no durable seam is available. */
|
|
921
|
-
var MemoryReviewStore = class {
|
|
922
|
-
sessions = /* @__PURE__ */ new Map();
|
|
923
|
-
load(sessionId) {
|
|
924
|
-
return this.sessions.get(sessionId);
|
|
925
|
-
}
|
|
926
|
-
save(sessionId, record) {
|
|
927
|
-
this.sessions.set(sessionId, record);
|
|
928
|
-
}
|
|
929
|
-
ids() {
|
|
930
|
-
return [...this.sessions.keys()];
|
|
931
|
-
}
|
|
932
|
-
};
|
|
933
|
-
var ReviewQueue = class {
|
|
934
|
-
store;
|
|
935
|
-
options;
|
|
936
|
-
constructor(store, options) {
|
|
937
|
-
this.store = store;
|
|
938
|
-
this.options = options;
|
|
939
|
-
}
|
|
940
|
-
/**
|
|
941
|
-
* Fail-open store access: a throwing seam must never break the compression
|
|
942
|
-
* pipeline. Reads degrade to "no stored record"; writes degrade to losing
|
|
943
|
-
* durability for that call (the store itself is expected to warn).
|
|
944
|
-
*/
|
|
945
|
-
safeLoad(sessionId) {
|
|
946
|
-
try {
|
|
947
|
-
return this.store.load(sessionId);
|
|
948
|
-
} catch {
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
safeSave(sessionId, record) {
|
|
953
|
-
try {
|
|
954
|
-
this.store.save(sessionId, record);
|
|
955
|
-
} catch {}
|
|
956
|
-
}
|
|
957
|
-
sessionRecord(sessionId) {
|
|
958
|
-
return this.safeLoad(sessionId) ?? {
|
|
959
|
-
version: 1,
|
|
960
|
-
proposals: []
|
|
961
|
-
};
|
|
962
|
-
}
|
|
963
|
-
/**
|
|
964
|
-
* Queue one classified proposal. A repeated classification of the same
|
|
965
|
-
* content re-does nothing but refresh the patience clock, so re-enqueue
|
|
966
|
-
* cannot duplicate a live proposal.
|
|
967
|
-
* @returns `false` when an identical live proposal already exists.
|
|
968
|
-
*/
|
|
969
|
-
enqueue(sessionId, skeleton, turnIndex) {
|
|
970
|
-
const record = this.sessionRecord(sessionId);
|
|
971
|
-
const existing = record.proposals.find((entry) => entry.id === skeleton.id);
|
|
972
|
-
if (existing !== void 0 && existing.status !== "expired") {
|
|
973
|
-
existing.lastTurnIndex = turnIndex;
|
|
974
|
-
this.safeSave(sessionId, record);
|
|
975
|
-
return false;
|
|
976
|
-
}
|
|
977
|
-
const proposal = {
|
|
978
|
-
id: skeleton.id,
|
|
979
|
-
sessionId,
|
|
980
|
-
kind: skeleton.kind,
|
|
981
|
-
items: skeleton.items.map((item) => ({ ...item })),
|
|
982
|
-
benefit: { ...skeleton.benefit },
|
|
983
|
-
status: "pending",
|
|
984
|
-
enqueuedTurn: turnIndex,
|
|
985
|
-
lastTurnIndex: turnIndex
|
|
986
|
-
};
|
|
987
|
-
this.safeSave(sessionId, {
|
|
988
|
-
version: 1,
|
|
989
|
-
proposals: [...record.proposals.filter((entry) => entry.id !== skeleton.id), proposal]
|
|
990
|
-
});
|
|
991
|
-
return true;
|
|
992
|
-
}
|
|
993
|
-
/** Live pending proposals of one session, oldest enqueue first. */
|
|
994
|
-
listPending(sessionId) {
|
|
995
|
-
return this.sessionRecord(sessionId).proposals.filter((entry) => entry.status === "pending").sort((left, right) => left.enqueuedTurn - right.enqueuedTurn);
|
|
996
|
-
}
|
|
997
|
-
/** Approved proposals waiting for the next turn-boundary batch. */
|
|
998
|
-
listApproved(sessionId) {
|
|
999
|
-
return this.sessionRecord(sessionId).proposals.filter((entry) => entry.status === "approved").sort((left, right) => left.enqueuedTurn - right.enqueuedTurn);
|
|
1000
|
-
}
|
|
1001
|
-
/**
|
|
1002
|
-
* Transition one pending proposal. Idempotent: deciding an unknown id or a
|
|
1003
|
-
* non-pending proposal changes nothing and reports the miss.
|
|
1004
|
-
*/
|
|
1005
|
-
decide(sessionId, id, decision) {
|
|
1006
|
-
const record = this.sessionRecord(sessionId);
|
|
1007
|
-
const proposal = record.proposals.find((entry) => entry.id === id);
|
|
1008
|
-
if (proposal === void 0) return {
|
|
1009
|
-
ok: false,
|
|
1010
|
-
reason: "unknown-proposal"
|
|
1011
|
-
};
|
|
1012
|
-
if (proposal.status !== "pending") return {
|
|
1013
|
-
ok: false,
|
|
1014
|
-
reason: "not-pending"
|
|
1015
|
-
};
|
|
1016
|
-
proposal.status = decision;
|
|
1017
|
-
this.safeSave(sessionId, record);
|
|
1018
|
-
return { ok: true };
|
|
1019
|
-
}
|
|
1020
|
-
/**
|
|
1021
|
-
* Expire every pending proposal whose patience has run out at this turn
|
|
1022
|
-
* boundary. Expired proposals are removed from the store (the summary view
|
|
1023
|
-
* aggregates them from the audit log instead).
|
|
1024
|
-
* @returns the expired proposals, for the caller's audit emission.
|
|
1025
|
-
*/
|
|
1026
|
-
expireTurn(sessionId, turnIndex) {
|
|
1027
|
-
const record = this.sessionRecord(sessionId);
|
|
1028
|
-
const keep = [];
|
|
1029
|
-
const expired = [];
|
|
1030
|
-
for (const proposal of record.proposals) {
|
|
1031
|
-
if (proposal.status === "pending" && turnIndex - proposal.lastTurnIndex > this.options.timeoutTurns) {
|
|
1032
|
-
expired.push({
|
|
1033
|
-
...proposal,
|
|
1034
|
-
status: "expired"
|
|
1035
|
-
});
|
|
1036
|
-
continue;
|
|
1037
|
-
}
|
|
1038
|
-
keep.push(proposal);
|
|
1039
|
-
}
|
|
1040
|
-
if (expired.length > 0) this.safeSave(sessionId, {
|
|
1041
|
-
version: 1,
|
|
1042
|
-
proposals: keep
|
|
1043
|
-
});
|
|
1044
|
-
return expired;
|
|
1045
|
-
}
|
|
1046
|
-
/**
|
|
1047
|
-
* Settle an approved proposal with its execution receipt and retire it from
|
|
1048
|
-
* the live store. The caller is responsible for auditing the receipt; the
|
|
1049
|
-
* queue only records which proposal left and why.
|
|
1050
|
-
*/
|
|
1051
|
-
recordReceipt(sessionId, id, receipt) {
|
|
1052
|
-
const record = this.sessionRecord(sessionId);
|
|
1053
|
-
const proposal = record.proposals.find((entry) => entry.id === id);
|
|
1054
|
-
if (proposal === void 0 || proposal.status !== "approved") return void 0;
|
|
1055
|
-
this.safeSave(sessionId, {
|
|
1056
|
-
version: 1,
|
|
1057
|
-
proposals: record.proposals.filter((entry) => entry.id !== id)
|
|
1058
|
-
});
|
|
1059
|
-
return {
|
|
1060
|
-
...proposal,
|
|
1061
|
-
receipt
|
|
1062
|
-
};
|
|
1063
|
-
}
|
|
1064
|
-
};
|
|
1065
|
-
//#endregion
|
|
1066
|
-
//#region src/runtime/tokenpilot/review-registry.ts
|
|
1067
|
-
/**
|
|
1068
|
-
* Scope-independent handle on the live review pipeline.
|
|
1069
|
-
*
|
|
1070
|
-
* The R4 HTTP routes are registered on the plugin's TOP-LEVEL fiber
|
|
1071
|
-
* (`cordis.patch.yml` → `context-compression-improved-estimator-catalog`),
|
|
1072
|
-
* but every `ToolResultPruner` is mounted inside an agent preset's isolated
|
|
1073
|
-
* group — `canonicalCompressionRows()` declares
|
|
1074
|
-
* `isolate: { compaction: true, toolResultPruner: true }` — so
|
|
1075
|
-
* `ctx.get('toolResultPruner')` at the top level is always `undefined` and the
|
|
1076
|
-
* queue route could only ever answer 503 "review pipeline unavailable".
|
|
1077
|
-
*
|
|
1078
|
-
* Ownership, not transport, was in the wrong place: the queue records are
|
|
1079
|
-
* already keyed by session id, so the store belongs to the plugin rather than
|
|
1080
|
-
* to one pruner instance. Every instance shares one store and publishes itself
|
|
1081
|
-
* here, which lets a top-level reader reach whichever instance currently holds
|
|
1082
|
-
* a session's proposals.
|
|
1083
|
-
*
|
|
1084
|
-
* The durable seam already behaves this way — `REVIEW_STORAGE_DOMAIN` /
|
|
1085
|
-
* `REVIEW_STORAGE_TABLE` are constants, so every instance opens the same table.
|
|
1086
|
-
* Only the in-memory fallback was per-instance, and that is what this module
|
|
1087
|
-
* makes shared.
|
|
1088
|
-
*
|
|
1089
|
-
* @module dsh-context-compression-improved/review-registry
|
|
1090
|
-
*/
|
|
1091
|
-
/**
|
|
1092
|
-
* The one in-memory fallback every pruner instance starts from. Session ids are
|
|
1093
|
-
* globally unique and `ReviewSessionRecord` is keyed by them, so a single store
|
|
1094
|
-
* is semantically identical to one store per instance — except that a reader
|
|
1095
|
-
* reaching any instance now observes every session.
|
|
1096
|
-
*/
|
|
1097
|
-
const sharedStore = new MemoryReviewStore();
|
|
1098
|
-
const live = /* @__PURE__ */ new Set();
|
|
1099
|
-
/** The process-wide review queue store shared by every pruner instance. */
|
|
1100
|
-
function sharedReviewStore() {
|
|
1101
|
-
return sharedStore;
|
|
1102
|
-
}
|
|
1103
|
-
/**
|
|
1104
|
-
* Publish one pruner instance for scope-independent readers.
|
|
1105
|
-
* @param pruner - the instance to publish.
|
|
1106
|
-
* @returns the disposer removing it, for `ctx.effect`.
|
|
1107
|
-
*/
|
|
1108
|
-
function registerReviewPruner(pruner) {
|
|
1109
|
-
live.add(pruner);
|
|
1110
|
-
return () => {
|
|
1111
|
-
live.delete(pruner);
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
/**
|
|
1115
|
-
* Resolve a live pruner instance for the top-level routes.
|
|
1116
|
-
*
|
|
1117
|
-
* Any instance can serve an aggregate read because the store is shared, and a
|
|
1118
|
-
* session-scoped read is answered from that same store. Instances that have
|
|
1119
|
-
* upgraded to the durable seam read the same table, so the answer does not
|
|
1120
|
-
* depend on which instance this happens to return.
|
|
1121
|
-
*
|
|
1122
|
-
* @returns a live instance, or `undefined` when no preset has been composed yet.
|
|
1123
|
-
*/
|
|
1124
|
-
function resolveReviewPruner() {
|
|
1125
|
-
return live.values().next().value;
|
|
1126
|
-
}
|
|
1127
899
|
const advisorStates = /* @__PURE__ */ new WeakMap();
|
|
1128
900
|
/**
|
|
1129
901
|
* The per-session advisor state, created on first touch.
|
|
@@ -1141,7 +913,8 @@ function getAdvisorState(session) {
|
|
|
1141
913
|
recertified: /* @__PURE__ */ new Map(),
|
|
1142
914
|
failures: void 0,
|
|
1143
915
|
inFlight: false,
|
|
1144
|
-
lastDecay: void 0
|
|
916
|
+
lastDecay: void 0,
|
|
917
|
+
lastAdvice: void 0
|
|
1145
918
|
};
|
|
1146
919
|
advisorStates.set(session, state);
|
|
1147
920
|
}
|
|
@@ -1186,4 +959,4 @@ function invalidateOnTaskChange(state, todoVersion) {
|
|
|
1186
959
|
return true;
|
|
1187
960
|
}
|
|
1188
961
|
//#endregion
|
|
1189
|
-
export {
|
|
962
|
+
export { COMPRESSION_PROFILES as C, deepFreeze as S, resolvePolicy as _, AUTO_COMPACT_THRESHOLD_LIMITS as a, resolveCustomPolicy as b, DEFAULTS as c, charsToTokens as d, codePointLength as f, resolveConfig as g, parseContextCompressionSettings as h, recordScore as i, PRUNE_MARKER as l, isValidAutoCompactThresholdPercent as m, invalidateOnTaskChange as n, CONTEXT_COMPRESSION_SETTINGS_NAMESPACE as o, isCompressionProfile as p, recordRecertified as r, ContextCompressionSettingsSchema as s, getAdvisorState as t, charsForTokens as u, CustomCompressionPolicySchema as v, assertNever as x, DEFAULT_CUSTOM_COMPRESSION_POLICY as y };
|
|
@@ -84,11 +84,6 @@ interface PresetOptionsSettings {
|
|
|
84
84
|
readonly estimatorBaseUrl?: string;
|
|
85
85
|
readonly estimatorApiKey?: string;
|
|
86
86
|
readonly estimatorTimeoutMs?: number;
|
|
87
|
-
/** Review-mode overrides (beta); mirrors the runtime PresetOptions.reviewMode. */
|
|
88
|
-
readonly reviewMode?: boolean;
|
|
89
|
-
readonly reviewTimeoutTurns?: number;
|
|
90
|
-
readonly cacheHitDiscountAlpha?: number;
|
|
91
|
-
readonly reviewHighImpactTokens?: number;
|
|
92
87
|
/** Advisory advisor channel; `''` (the default) keeps the advisor off. */
|
|
93
88
|
readonly advisorMode?: '' | 'host' | 'direct';
|
|
94
89
|
readonly advisorTimeoutMs?: number;
|
|
@@ -153,25 +148,6 @@ declare const zh: {
|
|
|
153
148
|
'estimator.apiKey.set': string;
|
|
154
149
|
'estimator.apiKey.clear': string;
|
|
155
150
|
'estimator.apiKey.overwrite': string;
|
|
156
|
-
'review.title': string;
|
|
157
|
-
'review.description': string;
|
|
158
|
-
'review.enabled': string;
|
|
159
|
-
'review.enabled.on': string;
|
|
160
|
-
'review.enabled.off': string;
|
|
161
|
-
'review.timeoutTurns': string;
|
|
162
|
-
'review.alpha': string;
|
|
163
|
-
'review.highImpact': string;
|
|
164
|
-
'review.badge': string;
|
|
165
|
-
'review.summary.autoApplied': string;
|
|
166
|
-
'review.summary.reviewApplied': string;
|
|
167
|
-
'review.summary.expired': string;
|
|
168
|
-
'review.summary.voided': string;
|
|
169
|
-
'review.row.payback': string;
|
|
170
|
-
'review.row.expectedSaving': string;
|
|
171
|
-
'review.row.estimated': string;
|
|
172
|
-
'review.action.approve': string;
|
|
173
|
-
'review.action.reject': string;
|
|
174
|
-
'review.action.ignore': string;
|
|
175
151
|
'detail.tokenpilot-inspired': string;
|
|
176
152
|
'profile.custom': string;
|
|
177
153
|
'profile.native': string;
|