dsh-session-guard 0.1.2 → 0.2.0-beta.1
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 +75 -29
- package/CHANGELOG.ko.md +75 -29
- package/CHANGELOG.md +146 -29
- package/INSTALL.ja.md +83 -42
- package/INSTALL.ko.md +83 -42
- package/INSTALL.md +86 -44
- package/INSTALL.zh.md +82 -42
- package/README.en.md +303 -170
- package/README.ja.md +177 -106
- package/README.ko.md +177 -106
- package/README.md +159 -20
- package/dsh.plugin.json +13 -0
- package/lib/client.js +397 -11
- package/lib/client.js.map +1 -1
- package/package.json +101 -78
- package/src/bridge.js +61 -1
- package/src/client/badge-text.ts +49 -0
- package/src/client/index.ts +11 -1
- package/src/client/locales.ts +163 -95
- package/src/client/pause-button-text.ts +60 -0
- package/src/client/pause-button.tsx +129 -0
- package/src/client/settings-card.tsx +391 -191
- package/src/client/status-badge.tsx +59 -66
- package/src/client/styles.ts +30 -0
- package/src/deferrals.js +197 -0
- package/src/index.js +405 -293
- package/src/pause-gate.js +472 -416
- package/src/provider-directory.js +101 -0
- package/src/provider.js +139 -0
- package/src/request-guard.js +191 -0
- package/src/retry.js +227 -202
- package/src/settings.js +118 -97
- package/src/step-gate.js +399 -0
- package/src/targets.js +70 -0
- package/src/time.js +195 -104
- package/src/tool-call-id.js +44 -0
- package/src/wiring.js +305 -0
package/CHANGELOG.ja.md
CHANGED
|
@@ -1,29 +1,75 @@
|
|
|
1
|
-
# 変更履歴
|
|
2
|
-
|
|
3
|
-
`dsh-session-guard` の主な変更を記録します。バージョンはセマンティックバージョニングに従います。
|
|
4
|
-
|
|
5
|
-
- [English changelog](./CHANGELOG.md)
|
|
6
|
-
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
7
|
-
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
8
|
-
|
|
9
|
-
## 0.
|
|
10
|
-
|
|
11
|
-
### 追加
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- `
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
1
|
+
# 変更履歴
|
|
2
|
+
|
|
3
|
+
`dsh-session-guard` の主な変更を記録します。バージョンはセマンティックバージョニングに従います。
|
|
4
|
+
|
|
5
|
+
- [English changelog](./CHANGELOG.md)
|
|
6
|
+
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
7
|
+
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
8
|
+
|
|
9
|
+
## 0.2.0-beta.1 — 2026-09-10
|
|
10
|
+
|
|
11
|
+
### 追加
|
|
12
|
+
|
|
13
|
+
- **step 級ゲート(`agent/pre-step`)**:ピーク時、ターン境界で中断するのではなく、**次の step のモデルリクエスト前**にターンを保留します。セッションは次の `agent/pre-step` まで走り、そこでゲートが閉じます(設定 `stepLevelPause`、既定 on)。退峰時は**その場で**再開し、followup メッセージは不要。ゲート条件:ピーク(北京時間)+ 非週末 + `step > 1` + 対象 provider が公式(`providerGuard`)+ リクエスト級 hold なし + このピーク期間でスキップなし。新規モジュール `src/step-gate.js`(純関数 `decideStepHold` + hold / release / abort / timeout エンジン)。
|
|
14
|
+
- **`stepResume` ポート + RPC + `/resume`**:`sessionGuard.stepResume(sessionId, {bypass})`、`POST /session-guard/rpc {action:'stepResume'}`、`/resume` のいずれでもゲートを解放。手動再開はそのピーク期間中のゲートを停止します。
|
|
15
|
+
- **タイムアウト昇格**:`stepGateTimeoutMs`(既定 300000)でゲートを解放し**ターン級 force 一時停止へ昇格**。長時間ピークでもデッドロックせず、「5 分ごとに 1 step」の滴漏も起きません。
|
|
16
|
+
- **「⏸ 一時停止」ボタン**(クライアント、slot `conversation.input.right`、id `session-guard-pause`、order 20 — input-traffic の凍結ボタンの左)。1 秒ごとに `/session-guard/state` をポーリングし、未保留時は無効、保留時は `stepResume` を呼びます。バッジは order 40 へ移動し、step 保留数を表示。
|
|
17
|
+
- **新規設定**:`stepLevelPause`、`stepGateTimeoutMs`。
|
|
18
|
+
- **新規状態**:`GET /session-guard/state` が `paused: { step, turn }` と `stepGate: { held, since, bypass }` を返し、`/status` は `stepHeld`、`/diag` は `stepGate` を返します。サービス側 `state().paused` は互換のため真偽値のまま(新フィールド `pausedStep`)。
|
|
19
|
+
|
|
20
|
+
### 修正
|
|
21
|
+
|
|
22
|
+
- **step 保留とターン級一時停止のデッドロック**:`pauseTask` / `resumeTask` / `cancelTask` が先に step ゲートを解放します。step 保留は `agent/pre-step` 上にあり `assistant/message` / `tool/result` が永遠に来ないため、`safe` 一時停止が永久に待ち、`paused` も永続化されませんでした。
|
|
23
|
+
|
|
24
|
+
### 変更
|
|
25
|
+
|
|
26
|
+
- **ピーク入りで実行中ターンを中断しなくなりました**(`stepLevelPause` 有効時、`onEnterPeak` は `stopNextTurn` ではなく step ゲートを arm)。無効時は従来のターン級動作のままです。
|
|
27
|
+
- input-traffic の凍結ボタンのラベルは **「凍結して追加」** になりました(`冻结追加` / `Freeze & append` / `동결 후 추가`)。再開ラベルは **「再開して追加」**(`恢复追加` / `Resume & append` / `재개 후 추가`)——ターンを凍結しつつキューを保持する動作で、一時停止ボタンとは別物です。
|
|
28
|
+
- **一時停止ボタンはトグルになりました**:「一時停止」/「再開」(グレー無効状態は廃止)。「一時停止」は新規 `stepPause` を呼び、**次の step 境界**でセッションを保留します(step 1 も対象、峰谷 / provider の制限なし)。「再開」は `stepResume`。新ポートメソッド `sessionGuard.stepPause(sessionId)`。
|
|
29
|
+
- **SSE プッシュ**:新ルート `GET /session-guard/events?session=<id>` が step ゲート状態の変化を即時配信——ピークで自動的に閉じた瞬間にボタンが「再開」へ変わります。10 秒ポーリングはフォールバックとして残ります。`/state` は `paused.manual` と `stepGate.manual` を返すようになりました。
|
|
30
|
+
- **スタイルを input-traffic のコンポーザーボタンに揃えました**(高さ 24px / 角丸 6px / 12px フォント / 同じ border・hover・pressed トークン)。ボタンとステータスバッジの両方。スタイルは `<style data-plugin-css="session-guard-client">` で一度だけ注入。
|
|
31
|
+
|
|
32
|
+
## Unreleased
|
|
33
|
+
|
|
34
|
+
### 追加
|
|
35
|
+
|
|
36
|
+
- **公式ソース二次判定(ピーク × 対象 provider)**:ピーク時は対象ルートが DeepSeek 公式ソースの場合のみ遮断し、ローカル/第三者 provider は通常実行。判定順は明示 `officialProviders` id リスト → 実時間 `baseURL` エンドポイント → catalog 内蔵エンドポイント(pi-ai の `deepseek`)→ 内蔵 id(`deepseek-official`)で、`matchedBy` を返します。新規モジュール:`src/provider.js`(純関数)、`src/provider-directory.js`、`src/deferrals.js`、`src/request-guard.js`、`src/targets.js`、`src/wiring.js`。
|
|
37
|
+
- **リクエスト級バックストップ(`agent/request`)**:ピーク入場後に起動したセッション、途中で公式ソースへ切り替えたセッションを捕捉(30s tick は遷移時に `running` だったセッションのみ処理)。既定 `hold` はエラーなしで保留し、退峰の瞬間に解放(`msUntilOffPeak`);`error` は識別可能な `PEAK_DEFERRED` を投げ延後キューに記録。
|
|
38
|
+
- **新しい設定**:`providerGuard`、`officialProviders`、`officialBaseURLs`、`deferredResume`、`deferredResumeText`、`deferredMode`、`deferredMaxHoldMs`(既定 6h)、`guardSubagents`。
|
|
39
|
+
- **新しいルート**:`GET /session-guard/provider?provider=<id>`(判定診断)。`/session-guard/status` は `providerGuard` / `held` / `deferred` を返します。
|
|
40
|
+
- **ドリフトガード** `tools/check-api-drift.ps1`(4 つの tag で必須 API の存在を検証)。
|
|
41
|
+
|
|
42
|
+
### 変更
|
|
43
|
+
|
|
44
|
+
- **DSH 二重バージョン対応(0.1.0-rc.7 … 0.1.2-rc.1)**:`dsh-v0.1.1-rc.2` と `dsh-v0.1.2-rc.1` を 1 つの成果物でカバー。
|
|
45
|
+
- **設定面は共通 API のみ**:`settings.register` + `settings.get`。`installSection`(0.1.2+)と削除された `installSettingsSection` は使用しません。任意 API は特性検出して降格。
|
|
46
|
+
- **`src/retry.js` は正確な `PEAK_DEFERRED` のみ短絡**:429 / `RATE_LIMIT` / `TRANSPORT` / タイムアウトは引き続き瞬時扱い。DSH のグローバルリトライ(`dsh-llm-retry`)は不変。
|
|
47
|
+
- バッジが「ピーク・公式のみ」と「ピーク・全停止」を区別。
|
|
48
|
+
|
|
49
|
+
## 0.1.4 — 2026-09-09
|
|
50
|
+
|
|
51
|
+
### 変更
|
|
52
|
+
|
|
53
|
+
- **公開ベータ**(`0.1.4-beta.1`):二重バージョン系のベータチャネル向けにバージョン表記・README 互換表・パッケージメタデータを整備。
|
|
54
|
+
|
|
55
|
+
## 0.1.1 — 2026-08-24
|
|
56
|
+
|
|
57
|
+
### 追加
|
|
58
|
+
|
|
59
|
+
- **バックエンド自動リトライ(D9)**:`turn/end` の瞬時失敗(error/429/max-tokens)はアダプティブバックオフの `followup(retryText)` で自動再開。永久失敗(認証/残高/モデル/コンテキスト上限)は停止。ユーザー介入または成功ターンで連続失敗カウントをリセット。
|
|
60
|
+
- **凍結/ゲート譲歩**:`isFrozen(sessionId)` が真のときリトライをスキップ、セッションゲートを迂回しません。
|
|
61
|
+
|
|
62
|
+
### 変更
|
|
63
|
+
|
|
64
|
+
- `sessionGuard` 冗余ポートが `state(sessionId)` を公開し、`{ queueLocked, lockReason, paused, taskControlAvailable, taskControl }` を返すように。
|
|
65
|
+
- HTTP ルート `GET /session-guard/diag` がリトライ状態を含むランタイム診断を返すように。
|
|
66
|
+
|
|
67
|
+
### 修正
|
|
68
|
+
|
|
69
|
+
- 週末検出を裸 `getUTCDay()` から `Intl.DateTimeFormat`(設定タイムゾーン使用)に変更し、北京タイムゾーンの 8 時間境界バグを修正。
|
|
70
|
+
|
|
71
|
+
## 0.1.0 — 2026-08-18
|
|
72
|
+
|
|
73
|
+
### 追加
|
|
74
|
+
|
|
75
|
+
- 初回リリース:ピーク自動一時停止(グローバル)、週末モード、`sessionGuard` 冗余ポート + RPC ブリッジによるセッションごとの凍結/再開、カスタムセッションゲート、設定パネル。
|
package/CHANGELOG.ko.md
CHANGED
|
@@ -1,29 +1,75 @@
|
|
|
1
|
-
# 변경 기록
|
|
2
|
-
|
|
3
|
-
`dsh-session-guard`의 주요 변경 사항을 기록합니다. 버전은 시맨틱 버저닝을 따릅니다.
|
|
4
|
-
|
|
5
|
-
- [English changelog](./CHANGELOG.md)
|
|
6
|
-
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
7
|
-
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
8
|
-
|
|
9
|
-
## 0.
|
|
10
|
-
|
|
11
|
-
### 추가
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- `
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
1
|
+
# 변경 기록
|
|
2
|
+
|
|
3
|
+
`dsh-session-guard`의 주요 변경 사항을 기록합니다. 버전은 시맨틱 버저닝을 따릅니다.
|
|
4
|
+
|
|
5
|
+
- [English changelog](./CHANGELOG.md)
|
|
6
|
+
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
7
|
+
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
8
|
+
|
|
9
|
+
## 0.2.0-beta.1 — 2026-09-10
|
|
10
|
+
|
|
11
|
+
### 추가
|
|
12
|
+
|
|
13
|
+
- **step급 게이트(`agent/pre-step`)**: 피크 시간에 턴 경계에서 중단하는 대신 **다음 step의 모델 요청 전에** 턴을 보류합니다. 세션은 다음 `agent/pre-step`까지 진행하고 거기서 게이트가 닫힙니다(설정 `stepLevelPause`, 기본 on). 오피크에는 **그 자리에서** 재개되며 followup 메시지가 필요 없습니다. 게이트 조건: 피크(북경 시간) + 주말 아님 + `step > 1` + 대상 provider가 공식(`providerGuard`) + 요청급 hold 아님 + 이번 피크 구간에서 스킵 아님. 신규 모듈 `src/step-gate.js`(순수 `decideStepHold` + hold / release / abort / timeout 엔진).
|
|
14
|
+
- **`stepResume` 포트 + RPC + `/resume`**: `sessionGuard.stepResume(sessionId, {bypass})`, `POST /session-guard/rpc {action:'stepResume'}`, `/resume` 모두 게이트를 해제합니다. 수동 재개는 해당 피크 구간 동안 게이트를 중단합니다.
|
|
15
|
+
- **타임아웃 승격**: `stepGateTimeoutMs`(기본 300000)로 게이트를 해제하고 **턴급 force 일시정지로 승격**합니다. 긴 피크에서도 교착이 없고 "5분마다 1 step" 누수도 없습니다.
|
|
16
|
+
- **"⏸ 일시정지" 버튼**(클라이언트, slot `conversation.input.right`, id `session-guard-pause`, order 20 — input-traffic 동결 버튼 왼쪽). 1초마다 `/session-guard/state`를 폴링하며, 미보류 시 비활성, 보류 시 `stepResume`을 호출합니다. 배지는 order 40으로 이동하고 step 보류 수를 표시합니다.
|
|
17
|
+
- **신규 설정**: `stepLevelPause`, `stepGateTimeoutMs`.
|
|
18
|
+
- **신규 상태**: `GET /session-guard/state`가 `paused: { step, turn }`과 `stepGate: { held, since, bypass }`를 반환하고, `/status`는 `stepHeld`, `/diag`는 `stepGate`를 반환합니다. 서비스 포트 `state().paused`는 호환을 위해 불리언 유지(신규 필드 `pausedStep`).
|
|
19
|
+
|
|
20
|
+
### 수정
|
|
21
|
+
|
|
22
|
+
- **step 보류와 턴급 일시정지의 교착**: `pauseTask` / `resumeTask` / `cancelTask`가 먼저 step 게이트를 해제합니다. step 보류는 `agent/pre-step`에 있어 `assistant/message` / `tool/result`가 영원히 오지 않으므로, `safe` 일시정지가 무한 대기하고 `paused`도 영속화되지 않았습니다.
|
|
23
|
+
|
|
24
|
+
### 변경
|
|
25
|
+
|
|
26
|
+
- **피크 진입 시 실행 중 턴을 중단하지 않습니다**(`stepLevelPause` on일 때 `onEnterPeak`는 `stopNextTurn` 대신 step 게이트를 arm). off일 때는 기존 턴급 동작 그대로입니다.
|
|
27
|
+
- input-traffic 동결 버튼 라벨이 **"동결 후 추가"**로 바뀌었고(`冻结追加` / `Freeze & append` / `凍結して追加`), 재개 라벨은 **"재개 후 추가"**(`恢复追加` / `Resume & append` / `再開して追加`)입니다 — 턴을 동결하면서 큐를 보존하는 동작으로, 일시정지 버튼과는 다릅니다.
|
|
28
|
+
- **일시정지 버튼이 토글이 되었습니다**: "일시정지" / "재개" (회색 비활성 상태 제거). "일시정지"는 새 `stepPause`를 호출해 **다음 step 경계**에서 세션을 보류합니다(step 1도 대상, 피크/provider 제한 없음). "재개"는 `stepResume`. 신규 포트 메서드 `sessionGuard.stepPause(sessionId)`.
|
|
29
|
+
- **SSE push**: 새 라우트 `GET /session-guard/events?session=<id>`가 step 게이트 상태 변화를 즉시 전달 — 피크에서 자동으로 닫히는 순간 버튼이 "재개"로 바뀝니다. 10초 폴링은 폴백으로 남습니다. `/state`는 `paused.manual`과 `stepGate.manual`을 반환합니다.
|
|
30
|
+
- **스타일을 input-traffic 컴포저 버튼과 맞췄습니다**(높이 24px / 반경 6px / 12px 글꼴 / 동일 border·hover·pressed 토큰). 버튼과 상태 배지 모두. 스타일은 `<style data-plugin-css="session-guard-client">`로 한 번만 주입.
|
|
31
|
+
|
|
32
|
+
## Unreleased
|
|
33
|
+
|
|
34
|
+
### 추가
|
|
35
|
+
|
|
36
|
+
- **공식 소스 2차 판정(피크 × 대상 provider)**: 피크 시간에는 대상 라우트가 DeepSeek 공식 소스일 때만 차단하고, 로컬/서드파티 provider는 정상 실행. 판정 순서는 명시 `officialProviders` id 목록 → 실시간 `baseURL` 엔드포인트 → catalog 내장 엔드포인트(pi-ai의 `deepseek`) → 내장 id(`deepseek-official`)이며 `matchedBy`를 반환. 신규 모듈: `src/provider.js`(순수), `src/provider-directory.js`, `src/deferrals.js`, `src/request-guard.js`, `src/targets.js`, `src/wiring.js`.
|
|
37
|
+
- **요청급 백스톱(`agent/request`)**: 피크 진입 후 시작된 세션, 도중에 공식 소스로 전환된 세션을 포착(30s tick은 전환 시점에 `running`이던 세션만 처리). 기본 `hold`는 오류 없이 보류하고 피크 종료 순간 해제(`msUntilOffPeak`); `error`는 식별 가능한 `PEAK_DEFERRED`를 던지고 연기 큐에 기록.
|
|
38
|
+
- **새 설정**: `providerGuard`, `officialProviders`, `officialBaseURLs`, `deferredResume`, `deferredResumeText`, `deferredMode`, `deferredMaxHoldMs`(기본 6h), `guardSubagents`.
|
|
39
|
+
- **새 라우트**: `GET /session-guard/provider?provider=<id>`(판정 진단). `/session-guard/status`가 `providerGuard` / `held` / `deferred` 반환.
|
|
40
|
+
- **드리프트 가드** `tools/check-api-drift.ps1`(4개 tag에서 필수 API 존재 검증).
|
|
41
|
+
|
|
42
|
+
### 변경
|
|
43
|
+
|
|
44
|
+
- **DSH 이중 버전 지원(0.1.0-rc.7 … 0.1.2-rc.1)**: 하나의 산출물로 `dsh-v0.1.1-rc.2`와 `dsh-v0.1.2-rc.1` 지원.
|
|
45
|
+
- **설정 표면은 교집합 API만**: `settings.register` + `settings.get`. `installSection`(0.1.2+)과 제거된 `installSettingsSection`은 사용하지 않음. 선택적 API는 특성 감지 후 강등.
|
|
46
|
+
- **`src/retry.js`는 정확한 `PEAK_DEFERRED`만 단락**: 429 / `RATE_LIMIT` / `TRANSPORT` / 타임아웃은 여전히 일시적으로 처리. DSH 전역 재시도(`dsh-llm-retry`)는 불변.
|
|
47
|
+
- 배지가 "피크·공식만"과 "피크·전체 정지"를 구분.
|
|
48
|
+
|
|
49
|
+
## 0.1.4 — 2026-09-09
|
|
50
|
+
|
|
51
|
+
### 변경
|
|
52
|
+
|
|
53
|
+
- **공개 베타**(`0.1.4-beta.1`): 이중 버전 라인의 베타 채널용으로 버전 표기·README 호환 표·패키지 메타데이터 정비.
|
|
54
|
+
|
|
55
|
+
## 0.1.1 — 2026-08-24
|
|
56
|
+
|
|
57
|
+
### 추가
|
|
58
|
+
|
|
59
|
+
- **백엔드 자동 재시도(D9)**: `turn/end` 일시적 실패(error/429/max-tokens)는 적응형 백오프의 `followup(retryText)`로 자동 재개; 영구 실패(인증/잔액/모델/컨텍스트 제한)는 중지; 사용자 개입 또는 성공 턴에서 연속 실패 카운트 리셋.
|
|
60
|
+
- **동결/게이트 양보**: `isFrozen(sessionId)`가 참일 때 재시도 건너뜀, 세션 게이트를 우회하지 않음.
|
|
61
|
+
|
|
62
|
+
### 변경
|
|
63
|
+
|
|
64
|
+
- `sessionGuard` 중복 포트가 `state(sessionId)`를 노출하여 `{ queueLocked, lockReason, paused, taskControlAvailable, taskControl }` 반환.
|
|
65
|
+
- HTTP 라우트 `GET /session-guard/diag`가 재시도 상태를 포함한 런타임 진단 반환.
|
|
66
|
+
|
|
67
|
+
### 수정
|
|
68
|
+
|
|
69
|
+
- 주말 감지를 벌거벗은 `getUTCDay()`에서 `Intl.DateTimeFormat`(설정된 타임존 사용)으로 변경, 베이징 타임존 8시간 경계 버그 수정.
|
|
70
|
+
|
|
71
|
+
## 0.1.0 — 2026-08-18
|
|
72
|
+
|
|
73
|
+
### 추가
|
|
74
|
+
|
|
75
|
+
- 최초 릴리스: 피크 자동 일시정지(글로벌), 주말 모드, `sessionGuard` 중복 포트 + RPC 브리지 기반 세션별 동결/재개, 커스텀 세션 게이트, 설정 패널.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,29 +1,146 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to `dsh-session-guard` are recorded here. Versions follow semver.
|
|
4
|
-
|
|
5
|
-
- [English changelog](./CHANGELOG.md)
|
|
6
|
-
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
7
|
-
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
8
|
-
|
|
9
|
-
## 0.
|
|
10
|
-
|
|
11
|
-
### Added
|
|
12
|
-
|
|
13
|
-
- **
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `dsh-session-guard` are recorded here. Versions follow semver.
|
|
4
|
+
|
|
5
|
+
- [English changelog](./CHANGELOG.md)
|
|
6
|
+
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
7
|
+
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
8
|
+
|
|
9
|
+
## 0.2.0-beta.1 — 2026-09-10
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Step-level gate (`agent/pre-step`).** During peak hours the turn is now held **before** the
|
|
14
|
+
next step's model request instead of being interrupted at a turn boundary: the session keeps
|
|
15
|
+
running until the next `agent/pre-step`, where the gate holds it (setting `stepLevelPause`, on by
|
|
16
|
+
default). The turn resumes **in place** off-peak — no followup message needed. Hold conditions:
|
|
17
|
+
peak (Beijing time) + not weekend + `step > 1` + official target provider (`providerGuard`) +
|
|
18
|
+
not request-held + not bypassed in this peak window. New module `src/step-gate.js` (pure
|
|
19
|
+
`decideStepHold` + hold / release / abort / timeout engine).
|
|
20
|
+
- **`stepResume` port + RPC + `/resume`.** `sessionGuard.stepResume(sessionId, {bypass})`,
|
|
21
|
+
`POST /session-guard/rpc {action:'stepResume'}` and `/resume` all release the gate; a manual
|
|
22
|
+
resume also stops gating that session for the rest of the peak window.
|
|
23
|
+
- **Timeout escalation.** `stepGateTimeoutMs` (default 300000) releases the gate and escalates to a
|
|
24
|
+
turn-level **force** pause, so a long peak neither deadlocks nor drips one step every five minutes.
|
|
25
|
+
- **"⏸ Pause session" button** (client, slot `conversation.input.right`, id `session-guard-pause`,
|
|
26
|
+
order 20 — left of input-traffic's freeze button). It polls `/session-guard/state` once a second,
|
|
27
|
+
stays disabled while nothing is held, and calls `stepResume` when it is. The status badge moved to
|
|
28
|
+
order 40 and now reports the number of step-held sessions.
|
|
29
|
+
- **New settings**: `stepLevelPause`, `stepGateTimeoutMs`.
|
|
30
|
+
- **New state**: `GET /session-guard/state` now returns `paused: { step, turn }` and
|
|
31
|
+
`stepGate: { held, since, bypass }`; `/status` returns `stepHeld`; `/diag` returns `stepGate`.
|
|
32
|
+
The service port's `state().paused` stays boolean for compatibility (new field `pausedStep`).
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **Deadlock between a held step and a turn-level pause.** `pauseTask` / `resumeTask` /
|
|
37
|
+
`cancelTask` now release the step gate first: a step hold sits at `agent/pre-step`, where no
|
|
38
|
+
`assistant/message` or `tool/result` can ever arrive, so a `safe` pause used to wait forever and
|
|
39
|
+
never persisted `paused`.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- **Peak entry no longer interrupts running turns** when `stepLevelPause` is on (`onEnterPeak` arms
|
|
44
|
+
the step gate instead of calling `stopNextTurn`); with it off the previous turn-level behaviour is
|
|
45
|
+
unchanged.
|
|
46
|
+
- input-traffic's freeze button label is now **"Freeze & append"** (`冻结追加` / `凍結して追加` /
|
|
47
|
+
`동결 후 추가`), and its resume label **"Resume & append"** (`恢复追加` / `再開して追加` /
|
|
48
|
+
`재개 후 추가`) — it freezes the turn and keeps queued messages, distinct from the pause button.
|
|
49
|
+
- **The pause button is a toggle now**: "Pause session" / "Resume session" (no disabled grey state).
|
|
50
|
+
Clicking "Pause session" calls the new `stepPause` action, which holds the session at the **next
|
|
51
|
+
step boundary** (step 1 included, regardless of peak or provider); "Resume session" calls
|
|
52
|
+
`stepResume`. New port method `sessionGuard.stepPause(sessionId)`.
|
|
53
|
+
- **SSE push**: new route `GET /session-guard/events?session=<id>` pushes step-gate state changes the
|
|
54
|
+
moment they happen, so peak auto-holds flip the button to "Resume session" without waiting for a
|
|
55
|
+
poll; the 10s `/session-guard/state` poll remains as a fallback. `/state` now reports
|
|
56
|
+
`paused.manual` and `stepGate.manual`.
|
|
57
|
+
- **Styling aligned** with input-traffic's composer button (24px height, 6px radius, 12px font, the
|
|
58
|
+
same border/hover/pressed tokens) for both the pause button and the status badge; styles are
|
|
59
|
+
injected once via `<style data-plugin-css="session-guard-client">`.
|
|
60
|
+
|
|
61
|
+
## Unreleased
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
- **Official-source two-dimensional guard (peak × target provider).** Peak hours now block only
|
|
66
|
+
requests whose target route is a DeepSeek official source; local/third-party providers keep
|
|
67
|
+
running. Verdict order: explicit `officialProviders` id list → live `baseURL` endpoint →
|
|
68
|
+
catalog builtin endpoint (pi-ai's `deepseek`) → builtin id (`deepseek-official`); each verdict
|
|
69
|
+
reports `matchedBy`. New modules: `src/provider.js` (pure), `src/provider-directory.js`,
|
|
70
|
+
`src/deferrals.js`, `src/request-guard.js`, `src/targets.js`, `src/wiring.js`.
|
|
71
|
+
- **Request-level backstop (`agent/request`).** Covers sessions started after peak entry and
|
|
72
|
+
sessions switched to an official source mid-run — the 30s tick only handled sessions that were
|
|
73
|
+
already `running` at the transition. Default `hold` mode suspends the request without an error
|
|
74
|
+
and releases it at the exact off-peak instant (`msUntilOffPeak`); `error` mode throws a
|
|
75
|
+
recognizable `PEAK_DEFERRED` failure and records a deferral for off-peak resume.
|
|
76
|
+
- **New settings**: `providerGuard`, `officialProviders`, `officialBaseURLs`, `deferredResume`,
|
|
77
|
+
`deferredResumeText`, `deferredMode`, `deferredMaxHoldMs` (default 6h), `guardSubagents`.
|
|
78
|
+
- **New routes**: `GET /session-guard/provider?provider=<id>` (verdict diagnostics);
|
|
79
|
+
`/session-guard/status` now reports `providerGuard` / `held` / `deferred`;
|
|
80
|
+
`/session-guard/state` reports the session's last target.
|
|
81
|
+
- **Drift guard** `tools/check-api-drift.ps1` asserting the required APIs exist on
|
|
82
|
+
`dsh-v0.1.1-rc.2` / `dsh-v0.1.2-rc.1` / `dsh-v0.1.3-alpha.2` / `dsh-v0.1.5-alpha.1`.
|
|
83
|
+
|
|
84
|
+
### Changed
|
|
85
|
+
|
|
86
|
+
- **DSH dual-version support (0.1.0-rc.7 … 0.1.2-rc.1).** One artifact now covers both
|
|
87
|
+
`dsh-v0.1.1-rc.2` and `dsh-v0.1.2-rc.1`. The `tool/result` call-id dual read
|
|
88
|
+
(`content[].toolCallId` first, `source.callId` fallback — both forms appear in replay logs of
|
|
89
|
+
both versions) is extracted to the dependency-free `src/tool-call-id.js` with unit tests.
|
|
90
|
+
`dsh.client.inject` no longer names `@deepseek-ai/dsh-client-runtime` (removed in 0.1.2) or
|
|
91
|
+
`@deepseek-ai/dsh-client-ui-slots` (not a dynamic client row); peer ranges widened to
|
|
92
|
+
`>=0.1.0-rc.7 <0.2.0-0` and the removed package dropped. Added `engines.dsh` and a
|
|
93
|
+
version-compatibility table to the README (ZH/EN).
|
|
94
|
+
- **Settings surface stays on the intersection API**: `settings.register` + `settings.get` only;
|
|
95
|
+
`installSection` (0.1.2+) and the removed `installSettingsSection` are never used. Optional
|
|
96
|
+
APIs (`model/selection`, `llm.listConfigurableProviders`, `settings.get`) are feature-probed and
|
|
97
|
+
degrade instead of throwing.
|
|
98
|
+
- **`src/retry.js` short-circuits only the exact `PEAK_DEFERRED` sentinel.** 429 / `RATE_LIMIT` /
|
|
99
|
+
`TRANSPORT` / timeout failures remain transient, so DSH's global retry (`dsh-llm-retry` on
|
|
100
|
+
`agent/request-error`) and this plugin's own retry semantics are unchanged. `dsh-llm-retry`
|
|
101
|
+
itself is never touched.
|
|
102
|
+
- Badge distinguishes "peak · official only" from "peak · all paused".
|
|
103
|
+
|
|
104
|
+
## 0.1.4 — 2026-09-09
|
|
105
|
+
|
|
106
|
+
### Changed
|
|
107
|
+
|
|
108
|
+
- **Public beta release** of the dual-version line (`0.1.4-beta.1`): version metadata, README
|
|
109
|
+
compatibility table and package metadata aligned for the beta channel.
|
|
110
|
+
|
|
111
|
+
## 0.1.3 — 2026-09-09
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
|
|
115
|
+
- **package.json encoding restored**: description was corrupted (GB2312 bytes misread as UTF-8); rewritten with correct Chinese text.
|
|
116
|
+
- **Missing metadata**: added `repository`, `homepage` fields.
|
|
117
|
+
- **peerDependencies corrected**: removed pinned `dsh-llm` exact version; added `cordis`, `dsh-client-runtime`, `dsh-client-locale`, `dsh-client-ui-settings`, `dsh-client-ui-slots` as optional peers matching `dsh.client.inject`.
|
|
118
|
+
- Added `dsh.plugin.json` manifest.
|
|
119
|
+
|
|
120
|
+
## 0.1.2 — 2026-08-28
|
|
121
|
+
|
|
122
|
+
### Fixed
|
|
123
|
+
|
|
124
|
+
- **Peak timezone fixed**: 峰谷判定固定北京时间 (`BILLING_TIMEZONE`),周末判定用配置时区。
|
|
125
|
+
|
|
126
|
+
## 0.1.1 — 2026-08-24
|
|
127
|
+
|
|
128
|
+
### Added
|
|
129
|
+
|
|
130
|
+
- **Backend auto-retry (D9)**: `turn/end` transient failures (error/429/max-tokens) trigger adaptive-backoff `followup(retryText)` resume; permanent failures (auth/balance/model/context limit) stop; user intervention or successful turn resets consecutive failure count.
|
|
131
|
+
- **Freeze/gate yield**: retry skips when `isFrozen(sessionId)` is true (queueLocked / paused / taskControl paused), never bypasses the session gate.
|
|
132
|
+
|
|
133
|
+
### Changed
|
|
134
|
+
|
|
135
|
+
- `sessionGuard` redundant port now exposes `state(sessionId)` returning `{ queueLocked, lockReason, paused, taskControlAvailable, taskControl }`.
|
|
136
|
+
- HTTP route `GET /session-guard/diag` returns runtime diagnostics including retry state.
|
|
137
|
+
|
|
138
|
+
### Fixed
|
|
139
|
+
|
|
140
|
+
- Weekend detection now uses `Intl.DateTimeFormat` with the configured timezone instead of bare `getUTCDay()`, fixing an 8-hour boundary bug for Beijing timezone.
|
|
141
|
+
|
|
142
|
+
## 0.1.0 — 2026-08-18
|
|
143
|
+
|
|
144
|
+
### Added
|
|
145
|
+
|
|
146
|
+
- Initial release: peak auto-pause (global), weekend mode, per-session freeze/resume via `sessionGuard` redundant port + RPC bridge, custom session gate (`agent.cancel keepInbox + goals.pause + session/event safe boundary + followup resume`), settings panel (Settings → Plugins → session-guard).
|
package/INSTALL.ja.md
CHANGED
|
@@ -1,42 +1,83 @@
|
|
|
1
|
-
# インストールガイド(公式 DSH CLI)
|
|
2
|
-
|
|
3
|
-
- [日本語インストールガイド](./INSTALL.ja.md)
|
|
4
|
-
- [English installation guide](./INSTALL.md)
|
|
5
|
-
- [中文安装指南](./INSTALL.zh.md)
|
|
6
|
-
- [한국어 설치 안내](./INSTALL.ko.md)
|
|
7
|
-
- [日本語 README](./README.ja.md)
|
|
8
|
-
- [English README](./README.en.md)
|
|
9
|
-
- [中文 README](./README.md)
|
|
10
|
-
- [한국어 README](./README.ko.md)
|
|
11
|
-
- [Changelog](./CHANGELOG.md)
|
|
12
|
-
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
|
-
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
|
-
|
|
15
|
-
## 0. 前提条件
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
echo "DSH_HOME=${DSH_HOME:-$HOME/.dsh}"
|
|
19
|
-
dsh --version
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## 1. インストール
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
dsh plugin --profile web add github:drscrewdriver/dsh-session-guard
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
dsh web を再起動し、ページをリフレッシュ。
|
|
29
|
-
|
|
30
|
-
## 2. 検証
|
|
31
|
-
|
|
32
|
-
「設定 → プラグイン → session-guard」を開く。スイッチ:`enabled`、`
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
1
|
+
# インストールガイド(公式 DSH CLI)
|
|
2
|
+
|
|
3
|
+
- [日本語インストールガイド](./INSTALL.ja.md)
|
|
4
|
+
- [English installation guide](./INSTALL.md)
|
|
5
|
+
- [中文安装指南](./INSTALL.zh.md)
|
|
6
|
+
- [한국어 설치 안내](./INSTALL.ko.md)
|
|
7
|
+
- [日本語 README](./README.ja.md)
|
|
8
|
+
- [English README](./README.en.md)
|
|
9
|
+
- [中文 README](./README.md)
|
|
10
|
+
- [한국어 README](./README.ko.md)
|
|
11
|
+
- [Changelog](./CHANGELOG.md)
|
|
12
|
+
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
13
|
+
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
14
|
+
|
|
15
|
+
## 0. 前提条件
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
echo "DSH_HOME=${DSH_HOME:-$HOME/.dsh}"
|
|
19
|
+
dsh --version
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 1. インストール
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
dsh plugin --profile web add github:drscrewdriver/dsh-session-guard
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
dsh web を再起動し、ページをリフレッシュ。
|
|
29
|
+
|
|
30
|
+
## 2. 検証
|
|
31
|
+
|
|
32
|
+
「設定 → プラグイン → session-guard」を開く。スイッチ:`enabled`、`providerGuard`、`guardSubagents`、
|
|
33
|
+
`offPeakAutoResume`、`weekendMode`、`deferredResume`、`queueFallback`、`retryEnabled`;
|
|
34
|
+
テキスト/リスト項目:`officialProviders`、`officialBaseURLs`、`deferredResumeText`。
|
|
35
|
+
|
|
36
|
+
セッション UI のステータスバッジを確認——現在のフェーズ(`高峰·拦官方` / `高峰·全部暂停` / `谷时` / `周末`)を表示。
|
|
37
|
+
|
|
38
|
+
特定ルートの公式ソース判定を確認(host ルート、再起動不要):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
curl -s 'http://127.0.0.1:3080/session-guard/provider?provider=deepseek-official'
|
|
42
|
+
# {"ok":true,"verdict":{"provider":"deepseek-official","official":true,"matchedBy":"endpoint","endpoint":"https://api.deepseek.com"}}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
テスト実行(ネットワーク・資格情報不要):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm test
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 3. アップグレード
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
dsh plugin --profile web remove dsh-session-guard
|
|
55
|
+
dsh plugin --profile web add github:drscrewdriver/dsh-session-guard
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
dsh web を再起動しページをリフレッシュ。設定は `$DSH_HOME/settings.yaml` の `session-guard`
|
|
59
|
+
名前空間にありアップグレード後も残ります。新しいキー(`providerGuard`、`deferredMode` など)は
|
|
60
|
+
触るまで既定値です。
|
|
61
|
+
|
|
62
|
+
`0.1.3`/`0.1.4-beta.1` から `0.1.5-beta.1` への唯一の挙動変更は、ピーク時に既定で
|
|
63
|
+
**公式ソースのみ**遮断する点です。従来の一律停止に戻すには `providerGuard: false`
|
|
64
|
+
(または `officialProviders` / `officialBaseURLs` で判定を狭める)。
|
|
65
|
+
|
|
66
|
+
## 4. トラブルシューティング
|
|
67
|
+
|
|
68
|
+
| 症状 | 確認 |
|
|
69
|
+
|---|---|
|
|
70
|
+
| ピーク時でもセッションが動く | `GET /session-guard/status` → `phase` が `peak`;`GET /session-guard/settings` → `enabled: true` |
|
|
71
|
+
| ローカル provider が遮断される | `GET /session-guard/provider?provider=<id>` → `matchedBy` が `endpoint`/`unknown` で `official: false` のはず。`explicit` なら `officialProviders` から削除 |
|
|
72
|
+
| 公式リクエストが遮断されない | `matchedBy: 'endpoint'` かつ `official: false` は `baseURL` が `officialBaseURLs` にない;host を追加するか、ルート id を `officialProviders` へ |
|
|
73
|
+
| リクエストが保留のまま | `hold` モードの仕様。明示エラーにするなら `deferredMode: 'error'`、または `deferredMaxHoldMs` を短く |
|
|
74
|
+
| ピーク後に再開しない | `deferredResume` が有効(または `/resume`);セッション級は `offPeakAutoResume` |
|
|
75
|
+
| 判定診断が使えない | `GET /session-guard/diag` → `providerGuard`、`configurableProviders`、`held`、`deferred` |
|
|
76
|
+
|
|
77
|
+
## 5. アンインストール
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
dsh plugin --profile web remove dsh-session-guard
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
dsh web を再起動。アンロード時に保留中のリクエストは解放(reject)され、promise リークはありません。
|