dsh-session-guard 0.1.2 → 0.1.5-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 +52 -29
- package/CHANGELOG.ko.md +52 -29
- package/CHANGELOG.md +94 -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 +241 -170
- package/README.ja.md +149 -106
- package/README.ko.md +149 -106
- package/README.md +86 -9
- package/dsh.plugin.json +13 -0
- package/lib/client.js +462 -270
- package/lib/client.js.map +1 -1
- package/package.json +101 -78
- package/src/client/badge-text.ts +44 -0
- package/src/client/locales.ts +163 -95
- package/src/client/settings-card.tsx +370 -191
- package/src/client/status-badge.tsx +55 -66
- package/src/deferrals.js +197 -0
- package/src/index.js +303 -293
- package/src/pause-gate.js +451 -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 +114 -97
- package/src/targets.js +70 -0
- package/src/time.js +195 -104
- package/src/tool-call-id.js +44 -0
- package/src/wiring.js +263 -0
package/README.ja.md
CHANGED
|
@@ -1,106 +1,149 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<strong>ピーク自動セッションゲート:週末モード + ピーク自動一時停止 + セッション級凍結 + バックエンド自動リトライ</strong>
|
|
3
|
-
</p>
|
|
4
|
-
<p align="center">
|
|
5
|
-
<a href="README.en.md">English</a> · <a href="README.md">中文</a> · <strong>日本語</strong> · <a href="README.ko.md">한국어</a>
|
|
6
|
-
</p>
|
|
7
|
-
<p align="center">
|
|
8
|
-
<a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-263146?style=flat-square"></a>
|
|
9
|
-
<img src="https://camo.githubusercontent.com/2c11fb2e0e14bb9985c5acbe61123a7441c5ee63aa27fa6e04e2a707ebfd6022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6473682d2d706c7567696e2d72656164792d3437384342463f6c6f676f3d646565707365656b266c6f676f436f6c6f723d7768697465" alt="dsh-plugin" style="max-width: 100%;">
|
|
10
|
-
<img alt="Public beta" src="https://img.shields.io/badge/status-public%20beta-7da1de?style=flat-square">
|
|
11
|
-
</p>
|
|
12
|
-
|
|
13
|
-
# dsh-session-guard
|
|
14
|
-
|
|
15
|
-
- [English README](./README.en.md)
|
|
16
|
-
- [中文 README](./README.md)
|
|
17
|
-
- [日本語 README](./README.ja.md)
|
|
18
|
-
- [한국어 README](./README.ko.md)
|
|
19
|
-
- [Installation guide](./INSTALL.md)
|
|
20
|
-
- [中文安装指南](./INSTALL.zh.md)
|
|
21
|
-
- [日本語インストールガイド](./INSTALL.ja.md)
|
|
22
|
-
- [한국어 설치 안내](./INSTALL.ko.md)
|
|
23
|
-
- [Changelog](./CHANGELOG.md)
|
|
24
|
-
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
25
|
-
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
26
|
-
|
|
27
|
-
> **互換性について:** v0.1.1 には日本語(`ja`)と韓国語(`ko`)の辞書が含まれていますが、現在の公式 DSH リリースは `LocaleRuntime` 経由で `zh` と `en` のみを提供しています。純正 DSH で `ja` または `ko` を選択すると `locale "<id>" is not registered` で失敗します。公式 DSH が对应的 locale ID を追加するまで利用できません。上級ユーザーは DSH フォークを保守して更新してください。
|
|
28
|
-
|
|
29
|
-
> ピーク課金時間帯に実行中のセッションを自動一時停止し、オフピーク/週末に自動再開。input-traffic の凍結ボタンと連携して**セッション級**ロックを実現。バックエンド**自動リトライ**は凍結/ゲート期間中は譲歩。カスタムセッションゲート(`agent.cancel keepInbox + goals.pause + session/event 安全境界 + followup 再開`)に基づき、dsh-task-control に依存しません。
|
|
30
|
-
|
|
31
|
-
`dsh plugin` コマンドで组装 + バンドルパッチで装配する cordis プラグイン。dsh ソース変更も PR も不要。
|
|
32
|
-
|
|
33
|
-
> 💡 **推奨理由**:DeepSeek は 2026-08-17 から**峰谷課金**を開始しました。ピーク時間帯の単価はオフピークの 2 倍。本プラグインはピーク時に実行セッションを自動一時停止、オフピーク時に自動再開し、長時間セッションの費用を最大 **50%** 削減。手動凍結(input-traffic ボタン経由)でセッションごとの精密制御が可能。
|
|
34
|
-
|
|
35
|
-
## 機能
|
|
36
|
-
|
|
37
|
-
- **週末モード**:`Intl.DateTimeFormat` で週末を正しく識別(タイムゾーン正確)→ 週末は峰谷を無視して自由実行。
|
|
38
|
-
- **ピーク自動一時停止(グローバル)**:ピーク入場時(かつ非週末)、全 running ルートセッションを自動一時停止。退峰時自動再開——**グローバルスイッチ、手動不要**。
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
|
56
|
-
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
###
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
###
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
|
89
|
-
|---|---|---|---|
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<strong>ピーク自動セッションゲート:週末モード + ピーク自動一時停止 + 公式ソース二次判定 + セッション級凍結 + バックエンド自動リトライ</strong>
|
|
3
|
+
</p>
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="README.en.md">English</a> · <a href="README.md">中文</a> · <strong>日本語</strong> · <a href="README.ko.md">한국어</a>
|
|
6
|
+
</p>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-263146?style=flat-square"></a>
|
|
9
|
+
<img src="https://camo.githubusercontent.com/2c11fb2e0e14bb9985c5acbe61123a7441c5ee63aa27fa6e04e2a707ebfd6022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6473682d2d706c7567696e2d72656164792d3437384342463f6c6f676f3d646565707365656b266c6f676f436f6c6f723d7768697465" alt="dsh-plugin" style="max-width: 100%;">
|
|
10
|
+
<img alt="Public beta" src="https://img.shields.io/badge/status-public%20beta-7da1de?style=flat-square">
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
# dsh-session-guard
|
|
14
|
+
|
|
15
|
+
- [English README](./README.en.md)
|
|
16
|
+
- [中文 README](./README.md)
|
|
17
|
+
- [日本語 README](./README.ja.md)
|
|
18
|
+
- [한국어 README](./README.ko.md)
|
|
19
|
+
- [Installation guide](./INSTALL.md)
|
|
20
|
+
- [中文安装指南](./INSTALL.zh.md)
|
|
21
|
+
- [日本語インストールガイド](./INSTALL.ja.md)
|
|
22
|
+
- [한국어 설치 안내](./INSTALL.ko.md)
|
|
23
|
+
- [Changelog](./CHANGELOG.md)
|
|
24
|
+
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
25
|
+
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
26
|
+
|
|
27
|
+
> **互換性について:** v0.1.1 には日本語(`ja`)と韓国語(`ko`)の辞書が含まれていますが、現在の公式 DSH リリースは `LocaleRuntime` 経由で `zh` と `en` のみを提供しています。純正 DSH で `ja` または `ko` を選択すると `locale "<id>" is not registered` で失敗します。公式 DSH が对应的 locale ID を追加するまで利用できません。上級ユーザーは DSH フォークを保守して更新してください。
|
|
28
|
+
|
|
29
|
+
> ピーク課金時間帯に実行中のセッションを自動一時停止し、オフピーク/週末に自動再開。input-traffic の凍結ボタンと連携して**セッション級**ロックを実現。バックエンド**自動リトライ**は凍結/ゲート期間中は譲歩。カスタムセッションゲート(`agent.cancel keepInbox + goals.pause + session/event 安全境界 + followup 再開`)に基づき、dsh-task-control に依存しません。
|
|
30
|
+
|
|
31
|
+
`dsh plugin` コマンドで组装 + バンドルパッチで装配する cordis プラグイン。dsh ソース変更も PR も不要。
|
|
32
|
+
|
|
33
|
+
> 💡 **推奨理由**:DeepSeek は 2026-08-17 から**峰谷課金**を開始しました。ピーク時間帯の単価はオフピークの 2 倍。本プラグインはピーク時に実行セッションを自動一時停止、オフピーク時に自動再開し、長時間セッションの費用を最大 **50%** 削減。手動凍結(input-traffic ボタン経由)でセッションごとの精密制御が可能。
|
|
34
|
+
|
|
35
|
+
## 機能
|
|
36
|
+
|
|
37
|
+
- **週末モード**:`Intl.DateTimeFormat` で週末を正しく識別(タイムゾーン正確)→ 週末は峰谷を無視して自由実行。
|
|
38
|
+
- **ピーク自動一時停止(グローバル)**:ピーク入場時(かつ非週末)、全 running ルートセッションを自動一時停止。退峰時自動再開——**グローバルスイッチ、手動不要**。
|
|
39
|
+
- **公式ソース二次判定(`providerGuard`)**:ピーク時は**リクエスト先が DeepSeek 公式ソースの場合のみ**遮断。ローカル/第三者 provider(例 `local-35b`)は通常どおり実行。判定順 = 明示 id リスト → `baseURL` エンドポイント → catalog 既定エンドポイント → 内蔵 id。
|
|
40
|
+
- **リクエスト級バックストップ + 延後キュー**:ピーク入場後に起動したセッション、途中で公式ソースへ切り替えたセッションは `agent/request` ガードが捕捉(既定 `hold`:リクエストを保留しエラーなし、退峰時に自動解放)。
|
|
41
|
+
- **セッション級凍結/再開**:`sessionGuard` 冗余ポート + `POST /session-guard/rpc`、input-traffic 凍結ボタンでセッションごと透伝。`/pause /resume /cancel` 手動コマンドも提供。
|
|
42
|
+
- **バックエンド自動リトライ(D9)**:turn/end 瞬時失敗(error/429/max-tokens)はアダプティブバックオフで自動再試行。永久失敗は停止。**凍結/ゲート期間中は譲歩**、セッションゲートを迂回しません。
|
|
43
|
+
- **fail-open**:カスタムセッションゲート利用不可、session-guard 未インストール、設定サービス欠如——すべて静的降格、依存でクラッシュしません。
|
|
44
|
+
|
|
45
|
+
## インストール
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
dsh plugin --profile web add github:<owner>/dsh-session-guard
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
インストール後 dsh web を再起動し、ページをリフレッシュ。
|
|
52
|
+
|
|
53
|
+
## 設定(設定 → プラグイン → session-guard)
|
|
54
|
+
|
|
55
|
+
| スイッチ | デフォルト | 説明 |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `enabled` | on | **ピーク自動一時停止**:ピーク時間帯に実行セッションを自動一時停止 |
|
|
58
|
+
| `providerGuard` | on | **公式ソース二次判定**:ピーク時は DeepSeek 公式ソースのみ遮断、ローカル/第三者 provider は通常実行 |
|
|
59
|
+
| `guardSubagents` | on | **サブエージェントも対象**:サブエージェントのリクエストも課金対象、既定で遮断 |
|
|
60
|
+
| `offPeakAutoResume` | on | **オフピーク自動再開**:オフピーク時に一時停止セッションを自動再開 |
|
|
61
|
+
| `weekendMode` | on | **週末モード**:週末を認識→週末は自動一時停止しない |
|
|
62
|
+
| `deferredResume` | on | **ピーク後の自動再開**:オフにすると延後したリクエスト/セッションは手動 `/resume` まで停止 |
|
|
63
|
+
| `queueFallback` | on | カスタムセッションゲート利用不可時にロック待機キューにフォールバック(fail-open) |
|
|
64
|
+
| `retryEnabled` | off | **自動リトライ(バックエンド)**:瞬時失敗自動再試行(デフォルトオフ、保守的) |
|
|
65
|
+
|
|
66
|
+
追加設定:
|
|
67
|
+
|
|
68
|
+
- `timezone`(デフォルト Asia/Shanghai)——**週末判定**とバッジ表示に使用。**峰谷判定には影響しない**(峰谷は常に北京時間);
|
|
69
|
+
- `peakWindows`(デフォルト 09:00–12:00 / 14:00–18:00)——北京時間(UTC+8)の峰谷ウィンドウ。DeepSeek 公式課金と一致;
|
|
70
|
+
- `pauseMode`(`safe`/`force`)、`pauseReason`(`wait`/`stop`);
|
|
71
|
+
- 公式ソース判定:`officialProviders`(公式 provider id を追加、カンマ区切り、最優先)、`officialBaseURLs`(公式エンドポイント host、既定 `api.deepseek.com`);
|
|
72
|
+
- 延後キュー:`deferredMode`(`hold` / `error`)、`deferredResumeText`、`deferredMaxHoldMs`(保留上限、既定 6h、超過で error);
|
|
73
|
+
- リトライパラメータ:`retryText`、`retryGraceMs`、`retryCooldownMs`、`retryBackoffFactor`、`retryBackoffMaxMs`、`retryMaxConsecutive`。
|
|
74
|
+
|
|
75
|
+
## 動作
|
|
76
|
+
|
|
77
|
+
### ピーク自動ゲート(グローバル)
|
|
78
|
+
|
|
79
|
+
- **ピーク入り**(かつ非週末):全 running ルートセッションに `gate.stopNextTurn` を呼び出し——カスタムセッションゲートで真の一時停止(推論を中断せず、安全境界で一時停止)、`queueFallback` でロック待機キューにフォールバック;
|
|
80
|
+
- **退峰 / 週末**:`gate.resume` **全**セッション(自動再開、手動不要)——`offPeakAutoResume` スイッチで制御;
|
|
81
|
+
- **峰谷タイムゾーン**:常に北京時間(`Asia/Shanghai`)を使用。DeepSeek 公式課金基準に一致。`timezone` 設定の影響を受けません;
|
|
82
|
+
- 状態機械:単一インスタンス `NORMAL ↔ PAUSED_PEAK`(`scheduler.js`)、単一 30s tick で駆動。
|
|
83
|
+
|
|
84
|
+
### 公式ソース判定(providerGuard)
|
|
85
|
+
|
|
86
|
+
ピーク時は無差別停止ではなく、まず「このリクエストが実際に向かうルートが DeepSeek 公式ソースか」を判定します。
|
|
87
|
+
|
|
88
|
+
| 優先 | 根拠 | `matchedBy` | 例 |
|
|
89
|
+
|---|---|---|---|
|
|
90
|
+
| 1 | `officialProviders` 明示 id リスト | `explicit` | 自前ゲートウェイを公式として宣言 |
|
|
91
|
+
| 2 | リアルタイム `baseURL` の host | `endpoint` | `deepseek-official` を中継へ変更 → **遮断しない** |
|
|
92
|
+
| 3 | catalog 内蔵の既定エンドポイント | `endpoint-default` | pi-ai の `deepseek` ルートは既定で公式 API → **遮断する** |
|
|
93
|
+
| 4 | 内蔵 id リスト(`deepseek-official`) | `route-id` | エンドポイントが読めない場合のフォールバック |
|
|
94
|
+
| 5 | その他 | `unknown` | 非公式、通過 |
|
|
95
|
+
|
|
96
|
+
- **エンドポイントが id より優先**:`deepseek-official` の `baseURL` を中継へ向けても誤遮断しません。逆に pi-ai 内蔵 `deepseek` ルートは漏れません。
|
|
97
|
+
- **エンドポイント取得元**:`ctx.get('llm').listConfigurableProviders()` → ディレクトリ項目 → `ctx.settings.get(settingsNs)` → `settingsPath` で `baseURL`(非機密フィールドのみ、`apiKeyEnv` の値は読みません)。毎リクエスト再計算・キャッシュなし → provider 設定の変更が即時反映。
|
|
98
|
+
- **非公式へ切替で自動復帰**:ピーク入場で停止したセッションをローカル/第三者 provider へ切り替えると(0.1.2+ の `model/selection` イベント)、自動的に再開します(`deferredResume` の制約下)。本プラグインが入峰時に停止したセッションだけが対象で、手動 `/pause` は上書きしません。0.1.1 にはこのイベントがないため「次回リクエストまたは手動 `/resume`」に降格。
|
|
99
|
+
- **取得できない場合**:`llm` サービス欠如、名前空間構造の変化、非文字列フィールド——すべて id / 内蔵エンドポイント判定へ降格し `matchedBy` を記録、**例外は投げません**。
|
|
100
|
+
- **誤判定の調査**:`GET /session-guard/provider?provider=<id>` が `{ official, matchedBy, endpoint }` を返します。
|
|
101
|
+
|
|
102
|
+
### リクエスト級ガードと延後キュー
|
|
103
|
+
|
|
104
|
+
- **なぜリクエスト級か**:30s tick は `NORMAL → PAUSED_PEAK` 遷移時に `running` だったセッションのみ処理します。ピーク入場後に起動したセッションや途中で公式ソースへ切り替えたセッションは漏れます。`agent/request` waterfall は**毎リクエスト**通ります。
|
|
105
|
+
- **`next()` の戻り値で判定**:モデル選択ミドルウェアが waterfall 内で provider/model を上書きするため、`await next()` の後に判定します。
|
|
106
|
+
- **`hold` モード(既定)**:リクエストを保留——**送信もエラーもなし**、退峰の瞬間に自動解放(`msUntilOffPeak` の精密タイマー、30s tick はバックストップ);abort で通常どおり中断。
|
|
107
|
+
- **`error` モード**:識別可能な `PEAK_DEFERRED` エラーを投げ延後キューに記録、退峰時に `deferredResumeText` で再開(`deferredResume` オフなら自動再開しない)。
|
|
108
|
+
- **上限**:`deferredMaxHoldMs`(既定 6h)で、無期限の保留を error に変換。
|
|
109
|
+
- **相互排他**:保留中はセッションゲートの一時停止を**併用しません**(一時停止は安全境界を待ちますが、保留中のリクエストはそこへ到達できません)。ピーク入場時、既に保留中のセッションはスキップされます。
|
|
110
|
+
- **永続化なし**:延後キューはプロセス内 promise、再起動で消えます。
|
|
111
|
+
|
|
112
|
+
### 境界(対象外)
|
|
113
|
+
|
|
114
|
+
- **provider の付け替えはしません**(遮断のみ)。
|
|
115
|
+
- **compaction は `agent/request` を通りません**:セッション停止中は発生しません。ピーク中に手動で圧縮すると公式ソースへ行く可能性があります(`ctx.llm.stream` 層は介入しません)。
|
|
116
|
+
- **0.1.1 には `model/selection` イベントがありません**:非公式ソースへ切り替えた後の自動復帰は「次回リクエストまたは手動 `/resume`」に降格(0.1.2+ では即時)。
|
|
117
|
+
- **npm 依存の追加なし**、資格情報の読み取りなし、`dsh-llm-retry` の 429 / トランスポート再試行は不変。
|
|
118
|
+
|
|
119
|
+
### タイムゾーン処理
|
|
120
|
+
|
|
121
|
+
- **峰谷判定**:常に **北京時間(UTC+8)** を使用(`BILLING_TIMEZONE = 'Asia/Shanghai'`)。DeepSeek 公式課金基準。`timezone` 設定で変更不可(ハードコード);
|
|
122
|
+
- **週末判定**:ユーザー設定の `timezone`(例:`Asia/Tokyo`、`Asia/Seoul`)を使用。「週末」はローカル概念のため;
|
|
123
|
+
- `Intl.DateTimeFormat` でタイムゾーン投影。無効な IANA タイムゾーン名は `RangeError` で fail-open し `Asia/Shanghai` にフォールバック;
|
|
124
|
+
- 峰谷ウィンドウは**左閉右開** `[start, end)`。深夜跨ぎウィンドウ(例:`22:00–06:00`)対応。
|
|
125
|
+
|
|
126
|
+
### status-badge(フロントエンド表示)
|
|
127
|
+
|
|
128
|
+
コンポーザー入力エリア右側に**読み取り専用**のステータスバッジを表示:
|
|
129
|
+
|
|
130
|
+
| 階層 | ラベル | CSS クラス | 意味 |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `peak`(二次判定 on) | 高峰·拦官方 | `sg-peak` | ピーク時間帯、DeepSeek 公式ソースのみ遮断 |
|
|
133
|
+
| `peak`(二次判定 off) | 高峰·全部暂停 | `sg-peak` | ピーク時間帯、全セッション停止 |
|
|
134
|
+
| `off-peak` | 谷時 | `sg-off` | オフピーク時間帯、セッション通常稼働 |
|
|
135
|
+
| `weekend` | 週末 | `sg-weekend` | 週末(週末モード有効時)、峰谷無視 |
|
|
136
|
+
|
|
137
|
+
- 15 秒ごとに `GET /session-guard/status` をポーリング(`phase` / `providerGuard` / `held` / `deferred`);
|
|
138
|
+
- fail-open:ルート到達不可・ネットワークエラー・`enabled` オフ時→バッジ非表示;
|
|
139
|
+
- **input-traffic に依存しない**:session-guard クライアントコードが単独で描画。input-traffic は凍結ボタンのみ担当;
|
|
140
|
+
|
|
141
|
+
### input-traffic との連携
|
|
142
|
+
|
|
143
|
+
- input-traffic の**凍結ボタン**は `sessionGuard.stopNextTurn`(RPC、セッション経由)経由でサーバーサイドに伝達;
|
|
144
|
+
- input-traffic は**凍結強化のみ**(キュー凍結/解凍 + composer ブロック)、リトライは本プラグインのバックエンドが処理;
|
|
145
|
+
- 両方「セッション分離」セマンティスを共有:input-traffic 凍結キューは sessionId で分離、session-guard RPC も sessionId で分離。
|
|
146
|
+
|
|
147
|
+
## ライセンス
|
|
148
|
+
|
|
149
|
+
MIT — [LICENSE](LICENSE) 参照。
|
package/README.ko.md
CHANGED
|
@@ -1,106 +1,149 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<strong>피크 자동 세션 게이트: 주말 모드 + 피크 자동 일시정지 + 세션급 동결 + 백엔드 자동 재시도</strong>
|
|
3
|
-
</p>
|
|
4
|
-
<p align="center">
|
|
5
|
-
<a href="README.en.md">English</a> · <a href="README.md">中文</a> · <a href="README.ja.md">日本語</a> · <strong>한국어</strong>
|
|
6
|
-
</p>
|
|
7
|
-
<p align="center">
|
|
8
|
-
<a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-263146?style=flat-square"></a>
|
|
9
|
-
<img src="https://camo.githubusercontent.com/2c11fb2e0e14bb9985c5acbe61123a7441c5ee63aa27fa6e04e2a707ebfd6022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6473682d2d706c7567696e2d72656164792d3437384342463f6c6f676f3d646565707365656b266c6f676f436f6c6f723d7768697465" alt="dsh-plugin" style="max-width: 100%;">
|
|
10
|
-
<img alt="Public beta" src="https://img.shields.io/badge/status-public%20beta-7da1de?style=flat-square">
|
|
11
|
-
</p>
|
|
12
|
-
|
|
13
|
-
# dsh-session-guard
|
|
14
|
-
|
|
15
|
-
- [English README](./README.en.md)
|
|
16
|
-
- [中文 README](./README.md)
|
|
17
|
-
- [日本語 README](./README.ja.md)
|
|
18
|
-
- [한국어 README](./README.ko.md)
|
|
19
|
-
- [Installation guide](./INSTALL.md)
|
|
20
|
-
- [中文安装指南](./INSTALL.zh.md)
|
|
21
|
-
- [日本語インストールガイド](./INSTALL.ja.md)
|
|
22
|
-
- [한국어 설치 안내](./INSTALL.ko.md)
|
|
23
|
-
- [Changelog](./CHANGELOG.md)
|
|
24
|
-
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
25
|
-
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
26
|
-
|
|
27
|
-
> **호환성 참고:** v0.1.1에는 일본어(`ja`)와 한국어(`ko`) 사전이 포함되어 있지만, 현재 공식 DSH 릴리스는 `LocaleRuntime`을 통해 `zh`와 `en`만 제공합니다. 순정 DSH에서 `ja` 또는 `ko`를 선택하면 `locale "<id>" is not registered` 오류가 발생합니다. 공식 DSH가 해당 locale ID를 추가할 때까지 사용할 수 없습니다. 고급 사용자는 DSH 포크를 유지하면서 업데이트하세요.
|
|
28
|
-
|
|
29
|
-
> 피크 과금 시간대에 실행 중인 세션을 자동 일시정지하고 오피크/주말에 자동 재개; input-traffic의 동결 버튼과 페어링하여 **세션급** 잠금 구현; 백엔드 **자동 재시도**는 동결/게이트 기간 중 양보. 커스텀 세션 게이트(`agent.cancel keepInbox + goals.pause + session/event 안전 경계 + followup 재개`) 기반, dsh-task-control 의존성 제거.
|
|
30
|
-
|
|
31
|
-
`dsh plugin` 명령으로 조립 + 번들 패치로 장착하는 cordis 플러그인. dsh 소스 변경이나 PR 필요 없음.
|
|
32
|
-
|
|
33
|
-
> 💡 **권장 이유**: DeepSeek는 2026-08-17부터 **피크/오피크 과금**을 시행. 피크 시간대 단가 2배. 본 플러그인이 피크 시 실행 세션을 자동 일시정지하고 오피크에 자동 재개하여 장시간 세션 비용을 최대 **50%** 절감. 수동 동결(input-traffic 버튼 경유)로 세션별 정밀 제어 가능.
|
|
34
|
-
|
|
35
|
-
## 기능
|
|
36
|
-
|
|
37
|
-
- **주말 모드**: `Intl.DateTimeFormat`으로 주말을 정확히 인식(타임존 정확) → 주말은 피크/오피크 무시하고 자유 실행.
|
|
38
|
-
- **피크 자동 일시정지(글로벌)**: 피크 진입 시(그리고 주말이 아닌 경우) 모든 running 루트 세션을 자동 일시정지; 이탈 시 자동 재개 — **글로벌 스위치, 수동 불필요**.
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
|
56
|
-
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
###
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
- `
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
###
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
|
89
|
-
|---|---|---|---|
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<strong>피크 자동 세션 게이트: 주말 모드 + 피크 자동 일시정지 + 세션급 동결 + 백엔드 자동 재시도</strong>
|
|
3
|
+
</p>
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="README.en.md">English</a> · <a href="README.md">中文</a> · <a href="README.ja.md">日本語</a> · <strong>한국어</strong>
|
|
6
|
+
</p>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-263146?style=flat-square"></a>
|
|
9
|
+
<img src="https://camo.githubusercontent.com/2c11fb2e0e14bb9985c5acbe61123a7441c5ee63aa27fa6e04e2a707ebfd6022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6473682d2d706c7567696e2d72656164792d3437384342463f6c6f676f3d646565707365656b266c6f676f436f6c6f723d7768697465" alt="dsh-plugin" style="max-width: 100%;">
|
|
10
|
+
<img alt="Public beta" src="https://img.shields.io/badge/status-public%20beta-7da1de?style=flat-square">
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
# dsh-session-guard
|
|
14
|
+
|
|
15
|
+
- [English README](./README.en.md)
|
|
16
|
+
- [中文 README](./README.md)
|
|
17
|
+
- [日本語 README](./README.ja.md)
|
|
18
|
+
- [한국어 README](./README.ko.md)
|
|
19
|
+
- [Installation guide](./INSTALL.md)
|
|
20
|
+
- [中文安装指南](./INSTALL.zh.md)
|
|
21
|
+
- [日本語インストールガイド](./INSTALL.ja.md)
|
|
22
|
+
- [한국어 설치 안내](./INSTALL.ko.md)
|
|
23
|
+
- [Changelog](./CHANGELOG.md)
|
|
24
|
+
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
25
|
+
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
26
|
+
|
|
27
|
+
> **호환성 참고:** v0.1.1에는 일본어(`ja`)와 한국어(`ko`) 사전이 포함되어 있지만, 현재 공식 DSH 릴리스는 `LocaleRuntime`을 통해 `zh`와 `en`만 제공합니다. 순정 DSH에서 `ja` 또는 `ko`를 선택하면 `locale "<id>" is not registered` 오류가 발생합니다. 공식 DSH가 해당 locale ID를 추가할 때까지 사용할 수 없습니다. 고급 사용자는 DSH 포크를 유지하면서 업데이트하세요.
|
|
28
|
+
|
|
29
|
+
> 피크 과금 시간대에 실행 중인 세션을 자동 일시정지하고 오피크/주말에 자동 재개; input-traffic의 동결 버튼과 페어링하여 **세션급** 잠금 구현; 백엔드 **자동 재시도**는 동결/게이트 기간 중 양보. 커스텀 세션 게이트(`agent.cancel keepInbox + goals.pause + session/event 안전 경계 + followup 재개`) 기반, dsh-task-control 의존성 제거.
|
|
30
|
+
|
|
31
|
+
`dsh plugin` 명령으로 조립 + 번들 패치로 장착하는 cordis 플러그인. dsh 소스 변경이나 PR 필요 없음.
|
|
32
|
+
|
|
33
|
+
> 💡 **권장 이유**: DeepSeek는 2026-08-17부터 **피크/오피크 과금**을 시행. 피크 시간대 단가 2배. 본 플러그인이 피크 시 실행 세션을 자동 일시정지하고 오피크에 자동 재개하여 장시간 세션 비용을 최대 **50%** 절감. 수동 동결(input-traffic 버튼 경유)로 세션별 정밀 제어 가능.
|
|
34
|
+
|
|
35
|
+
## 기능
|
|
36
|
+
|
|
37
|
+
- **주말 모드**: `Intl.DateTimeFormat`으로 주말을 정확히 인식(타임존 정확) → 주말은 피크/오피크 무시하고 자유 실행.
|
|
38
|
+
- **피크 자동 일시정지(글로벌)**: 피크 진입 시(그리고 주말이 아닌 경우) 모든 running 루트 세션을 자동 일시정지; 이탈 시 자동 재개 — **글로벌 스위치, 수동 불필요**.
|
|
39
|
+
- **공식 소스 2차 판정(`providerGuard`)**: 피크 시간에는 **요청 대상이 DeepSeek 공식 소스일 때만** 차단. 로컬/서드파티 provider(예: `local-35b`)는 정상 실행. 판정 순서 = 명시 id 목록 → `baseURL` 엔드포인트 → catalog 기본 엔드포인트 → 내장 id.
|
|
40
|
+
- **요청급 백스톱 + 연기 큐**: 피크 진입 후 시작된 세션, 도중에 공식 소스로 전환된 세션은 `agent/request` 가드가 포착(기본 `hold`: 요청을 보류하고 오류 없이, 피크 종료 시 자동 해제).
|
|
41
|
+
- **세션급 동결/재개**: `sessionGuard` 중복 포트 + `POST /session-guard/rpc`, input-traffic 동결 버튼으로 세션별 패스스루. `/pause /resume /cancel` 수동 명령도 제공.
|
|
42
|
+
- **백엔드 자동 재시도(D9)**: turn/end 일시적 실패(error/429/max-tokens)는 적응형 백오프로 자동 재시도; 영구 실패는 중지; **동결/게이트 기간 중 양보**, 세션 게이트를 우회하지 않음.
|
|
43
|
+
- **fail-open**: 커스텀 세션 게이트 사용 불가, session-guard 미설치, 설정 서비스 누락 — 모두 조용히 성능 저하, 의존성으로 크래시하지 않음.
|
|
44
|
+
|
|
45
|
+
## 설치
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
dsh plugin --profile web add github:<owner>/dsh-session-guard
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
설치 후 dsh web을 재시작하고 페이지를 새로고침.
|
|
52
|
+
|
|
53
|
+
## 설정 (설정 → 플러그인 → session-guard)
|
|
54
|
+
|
|
55
|
+
| 스위치 | 기본값 | 설명 |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `enabled` | on | **피크 자동 일시정지**: 피크 시간대에 실행 세션을 자동 일시정지 |
|
|
58
|
+
| `providerGuard` | on | **공식 소스 2차 판정**: 피크에는 DeepSeek 공식 소스만 차단, 로컬/서드파티 provider는 정상 실행 |
|
|
59
|
+
| `guardSubagents` | on | **서브에이전트 포함**: 서브에이전트 요청도 과금 대상, 기본 포함 |
|
|
60
|
+
| `offPeakAutoResume` | on | **오피크 자동 재개**: 오피크에 일시정지 세션을 자동 재개 |
|
|
61
|
+
| `weekendMode` | on | **주말 모드**: 주말 인식 → 주말 자동 일시정지 안 함 |
|
|
62
|
+
| `deferredResume` | on | **피크 후 자동 재개**: 끄면 연기된 요청/세션은 수동 `/resume` 전까지 멈춤 |
|
|
63
|
+
| `queueFallback` | on | 커스텀 세션 게이트 사용 불가 시 락 대기 큐로 폴백 (fail-open) |
|
|
64
|
+
| `retryEnabled` | off | **자동 재시도 (백엔드)**: 일시적 실패 자동 재시도 (기본값 off, 보수적) |
|
|
65
|
+
|
|
66
|
+
추가 설정:
|
|
67
|
+
|
|
68
|
+
- `timezone` (기본값 Asia/Shanghai) — **주말 판정**과 배지 표시에 사용. **피크/오피크 판정에는 영향 없음** (피크는 항상 북경 시간);
|
|
69
|
+
- `peakWindows` (기본값 09:00–12:00 / 14:00–18:00) — 북경 시간(UTC+8) 기준 피크 윈도우. DeepSeek 공식 과금과 일치;
|
|
70
|
+
- `pauseMode` (`safe`/`force`), `pauseReason` (`wait`/`stop`);
|
|
71
|
+
- 공식 소스 판정: `officialProviders`(공식 provider id 추가, 쉼표 구분, 최우선), `officialBaseURLs`(공식 엔드포인트 host, 기본 `api.deepseek.com`);
|
|
72
|
+
- 연기 큐: `deferredMode`(`hold`/`error`), `deferredResumeText`, `deferredMaxHoldMs`(보류 상한, 기본 6h, 초과 시 error);
|
|
73
|
+
- 재시도 매개변수: `retryText`, `retryGraceMs`, `retryCooldownMs`, `retryBackoffFactor`, `retryBackoffMaxMs`, `retryMaxConsecutive`.
|
|
74
|
+
|
|
75
|
+
## 동작
|
|
76
|
+
|
|
77
|
+
### 피크 자동 게이트 (글로벌)
|
|
78
|
+
|
|
79
|
+
- **피크 진입** (그리고 주말 아님): 모든 running 루트 세션에 `gate.stopNextTurn` 호출 — 커스텀 세션 게이트로 진정한 일시정지 (추론 중단 안 함, 안전 경계에서 일시정지), `queueFallback`으로 락 대기 큐 폴백;
|
|
80
|
+
- **오피크 / 주말**: `gate.resume` **모든** 세션 (자동 재개, 수동 불필요) — `offPeakAutoResume` 스위치로 제어;
|
|
81
|
+
- **피크 타임존**: 하드코딩된 북경 시간 (`Asia/Shanghai`), DeepSeek 공식 과금 기준과 일치 — `timezone` 설정의 영향을 받지 않음;
|
|
82
|
+
- 상태 머신: 단일 인스턴스 `NORMAL ↔ PAUSED_PEAK` (`scheduler.js`), 단일 30s tick으로 구동.
|
|
83
|
+
|
|
84
|
+
### 공식 소스 판정 (`providerGuard`)
|
|
85
|
+
|
|
86
|
+
피크 시간에 무차별 정지하지 않고, 먼저 "이 요청이 실제로 향하는 라우트가 DeepSeek 공식 소스인가"를 판정합니다.
|
|
87
|
+
|
|
88
|
+
| 우선순위 | 근거 | `matchedBy` | 예 |
|
|
89
|
+
|---|---|---|---|
|
|
90
|
+
| 1 | `officialProviders` 명시 id 목록 | `explicit` | 자체 게이트웨이를 공식으로 선언 |
|
|
91
|
+
| 2 | 실시간 `baseURL` 정규화 host | `endpoint` | `deepseek-official`을 중계로 변경 → **차단 안 함** |
|
|
92
|
+
| 3 | catalog 내장 기본 엔드포인트 | `endpoint-default` | pi-ai의 `deepseek` 라우트는 기본이 공식 API → **차단함** |
|
|
93
|
+
| 4 | 내장 id 목록 (`deepseek-official`) | `route-id` | 엔드포인트를 읽을 수 없을 때 폴백 |
|
|
94
|
+
| 5 | 그 외 | `unknown` | 비공식, 통과 |
|
|
95
|
+
|
|
96
|
+
- **엔드포인트가 id보다 우선**: `deepseek-official`의 `baseURL`을 중계로 돌려도 오차단하지 않습니다. 반대로 pi-ai 내장 `deepseek` 라우트는 누락되지 않습니다.
|
|
97
|
+
- **엔드포인트 출처**: `ctx.get('llm').listConfigurableProviders()` → 디렉터리 항목 → `ctx.settings.get(settingsNs)` → `settingsPath`로 `baseURL`(비밀 아닌 필드만, `apiKeyEnv` 값은 읽지 않음). 요청마다 재계산·캐시 없음 → provider 설정 변경이 즉시 반영.
|
|
98
|
+
- **비공식으로 전환 시 자동 복귀**: 피크 진입으로 정지된 세션을 로컬/서드파티 provider로 바꾸면(0.1.2+의 `model/selection` 이벤트) 자동으로 재개합니다(`deferredResume` 제약). 본 플러그인이 피크 진입 시 정지한 세션만 대상이며 수동 `/pause`는 덮어쓰지 않습니다. 0.1.1에는 이 이벤트가 없어 "다음 요청 또는 수동 `/resume`"으로 강등.
|
|
99
|
+
- **읽을 수 없을 때**: `llm` 서비스 부재, 네임스페이스 구조 변경, 비문자열 필드 — 모두 id / 내장 엔드포인트 판정으로 강등하고 `matchedBy`를 기록, **예외를 던지지 않습니다**.
|
|
100
|
+
- **오판정 조사**: `GET /session-guard/provider?provider=<id>`가 `{ official, matchedBy, endpoint }`를 반환.
|
|
101
|
+
|
|
102
|
+
### 요청급 가드와 연기 큐
|
|
103
|
+
|
|
104
|
+
- **왜 요청급인가**: 30s tick은 `NORMAL → PAUSED_PEAK` 전환 시점에 `running`이던 세션만 처리합니다. 피크 진입 후 시작된 세션, 도중에 공식 소스로 바뀐 세션은 누락됩니다. `agent/request` waterfall은 **모든 요청**을 지납니다.
|
|
105
|
+
- **`next()` 반환값으로 판정**: 모델 선택 미들웨어가 waterfall 내부에서 provider/model을 덮어쓰므로 `await next()` 후에 판정합니다.
|
|
106
|
+
- **`hold` 모드(기본)**: 요청을 보류 — **전송도 오류도 없음** — 피크 종료 순간 자동 해제(`msUntilOffPeak` 정밀 타이머, 30s tick은 백스톱); abort 시 정상 중단.
|
|
107
|
+
- **`error` 모드**: 식별 가능한 `PEAK_DEFERRED` 오류를 던지고 연기 큐에 기록, 피크 종료 시 `deferredResumeText`로 재개(`deferredResume` 끄면 자동 재개 안 함).
|
|
108
|
+
- **상한**: `deferredMaxHoldMs`(기본 6h)로 무한 보류를 error로 전환.
|
|
109
|
+
- **상호 배타**: 보류 중에는 세션 게이트 일시정지를 **함께 쓰지 않습니다**(일시정지는 안전 경계를 기다리지만 보류된 요청은 도달할 수 없음). 피크 진입 시 이미 보류 중인 세션은 건너뜁니다.
|
|
110
|
+
- **영속화 없음**: 연기 큐는 프로세스 내 promise, 재시작 시 사라집니다.
|
|
111
|
+
|
|
112
|
+
### 경계 (대상 아님)
|
|
113
|
+
|
|
114
|
+
- **provider 재라우팅 없음**(차단만).
|
|
115
|
+
- **compaction은 `agent/request`를 지나지 않음**: 세션이 정지된 동안에는 발생하지 않습니다. 피크 중 수동 압축은 공식 소스로 갈 수 있습니다(`ctx.llm.stream` 계층은 개입하지 않음).
|
|
116
|
+
- **0.1.1에는 `model/selection` 이벤트가 없음**: 비공식 소스로 전환 후 자동 복귀는 "다음 요청 또는 수동 `/resume`"으로 강등(0.1.2+는 즉시).
|
|
117
|
+
- **npm 의존성 추가 없음**, 자격 증명 읽기 없음, `dsh-llm-retry`의 429 / 전송 재시도는 그대로.
|
|
118
|
+
|
|
119
|
+
### 타임존 처리
|
|
120
|
+
|
|
121
|
+
- **피크/오피크判定**: 항상 **북경 시간(UTC+8)** 사용 (`BILLING_TIMEZONE = 'Asia/Shanghai'`). DeepSeek 공식 과금 기준. `timezone` 설정으로 변경 불가 (하드코딩);
|
|
122
|
+
- **주말判定**: 사용자 설정 `timezone` (예: `Asia/Tokyo`, `Asia/Seoul`) 사용. "주말"은 로컬 개념이므로;
|
|
123
|
+
- `Intl.DateTimeFormat`으로 타임존 투영. 잘못된 IANA 타임존 이름은 `RangeError`로 fail-open하여 `Asia/Shanghai`로 폴백;
|
|
124
|
+
- 피크 윈도우는 **좌폐우개** `[start, end)`. 자정 횡단 윈도우 (예: `22:00–06:00`) 지원.
|
|
125
|
+
|
|
126
|
+
### 상태 배지 (프론트엔드 표시)
|
|
127
|
+
|
|
128
|
+
컴포저 입력 영역 오른쪽에 **읽기 전용** 상태 배지 표시:
|
|
129
|
+
|
|
130
|
+
| 단계 | 라벨 | CSS 클래스 | 의미 |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `peak` (2차 판정 on) | 高峰·拦官方 | `sg-peak` | 피크 시간대, DeepSeek 공식 소스만 차단 |
|
|
133
|
+
| `peak` (2차 판정 off) | 高峰·全部暂停 | `sg-peak` | 피크 시간대, 모든 세션 정지 |
|
|
134
|
+
| `off-peak` | 谷时 | `sg-off` | 오피크 시간대, 세션 정상 실행 |
|
|
135
|
+
| `weekend` | 週末 | `sg-weekend` | 주말 (주말 모드 활성화 시), 피크/오피크 무시 |
|
|
136
|
+
|
|
137
|
+
- 15초마다 `GET /session-guard/status` 폴링(`phase` / `providerGuard` / `held` / `deferred`);
|
|
138
|
+
- fail-open: 라우트 도달 불가·네트워크 오류·`enabled` OFF → 배지 숨김;
|
|
139
|
+
- **input-traffic에 의존하지 않음**: session-guard 클라이언트 코드가 단독으로 렌더링. input-traffic는 동결 버튼만 담당;
|
|
140
|
+
|
|
141
|
+
### input-traffic와의 협업
|
|
142
|
+
|
|
143
|
+
- input-traffic의 **동결 버튼**은 `sessionGuard.stopNextTurn` (RPC, 세션별) 경유 서버사이드에 전달;
|
|
144
|
+
- input-traffic는 **동결 강화만** (큐 동결/해제 + composer 차단), 재시도는 본 플러그인 백엔드가 처리;
|
|
145
|
+
- 둘 다 "세션 격리" 시맨틱 공유: input-traffic 동결 큐는 sessionId로 격리, session-guard RPC도 sessionId로 격리.
|
|
146
|
+
|
|
147
|
+
## 라이선스
|
|
148
|
+
|
|
149
|
+
MIT — [LICENSE](LICENSE) 참조.
|