@eddyskywalker/dsh-chatgpt-subscription 0.44.0 → 0.45.0

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 (31) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/lib/client.js +13 -0
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +2100 -10
  5. package/lib/types/compat.d.ts +1 -1
  6. package/lib/types/host/cache-warmup/budget.d.ts +64 -0
  7. package/lib/types/host/cache-warmup/budget.d.ts.map +1 -0
  8. package/lib/types/host/cache-warmup/contracts.d.ts +267 -0
  9. package/lib/types/host/cache-warmup/contracts.d.ts.map +1 -0
  10. package/lib/types/host/cache-warmup/index.d.ts +21 -0
  11. package/lib/types/host/cache-warmup/index.d.ts.map +1 -0
  12. package/lib/types/host/cache-warmup/install.d.ts +130 -0
  13. package/lib/types/host/cache-warmup/install.d.ts.map +1 -0
  14. package/lib/types/host/cache-warmup/logging.d.ts +120 -0
  15. package/lib/types/host/cache-warmup/logging.d.ts.map +1 -0
  16. package/lib/types/host/cache-warmup/projection.d.ts +29 -0
  17. package/lib/types/host/cache-warmup/projection.d.ts.map +1 -0
  18. package/lib/types/host/cache-warmup/result-tool.d.ts +87 -0
  19. package/lib/types/host/cache-warmup/result-tool.d.ts.map +1 -0
  20. package/lib/types/host/cache-warmup/settings.d.ts +73 -0
  21. package/lib/types/host/cache-warmup/settings.d.ts.map +1 -0
  22. package/lib/types/host/cache-warmup/store.d.ts +108 -0
  23. package/lib/types/host/cache-warmup/store.d.ts.map +1 -0
  24. package/lib/types/host/cache-warmup/usage.d.ts +86 -0
  25. package/lib/types/host/cache-warmup/usage.d.ts.map +1 -0
  26. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  27. package/lib/types/index.d.ts +11 -0
  28. package/lib/types/index.d.ts.map +1 -1
  29. package/lib/types/shared/model-catalog.d.ts +12 -1
  30. package/lib/types/shared/model-catalog.d.ts.map +1 -1
  31. package/package.json +1 -1
@@ -71,7 +71,7 @@ export declare const ROUTE_PREFIX: "/api/dsh-chatgpt-subscription";
71
71
  * `test/responses-client.test.ts` asserts the two agree, so a release that
72
72
  * forgets this constant fails the suite instead of shipping quietly.
73
73
  */
74
- export declare const PLUGIN_VERSION: "0.44.0";
74
+ export declare const PLUGIN_VERSION: "0.45.0";
75
75
  export declare const CODEX_CHATGPT_PROVIDER_ID: "codex-chatgpt";
76
76
  export { MINIMAX_CODE_PROVIDER_ID, MINIMAX_CODE_ROUTE_PREFIX } from './shared/minimax-code-contracts.ts';
77
77
  export declare const CODEX_API_BASE: "https://chatgpt.com/backend-api/codex";
@@ -0,0 +1,64 @@
1
+ /**
2
+ * 预热预算:预热期保守、连续命中后放大、漂移立刻收回。
3
+ *
4
+ * 控制器是**纯函数**:不发起请求、不改消息、不改登记表。它只回答一个问题 ——
5
+ * 「这一次预览最多能占多少字符」。把决策与执行分开,才能保证预算收紧或放开
6
+ * 都不会悄悄改写已经进入历史的文本(历史里的 preview 是常量)。
7
+ *
8
+ * @module dsh-chatgpt-subscription/host/cache-warmup/budget
9
+ */
10
+ import { CACHE_WARMUP_DEFAULTS, type PreviewBudget } from './contracts.ts';
11
+ /**
12
+ * 当前会话的预览预算。
13
+ *
14
+ * 规则(约束 4):预热期 `maxChars = 1200`(约 600-750 tokens);连续
15
+ * `consecutiveHitsRequired`(2) 次命中率 ≥ 0.97 且期间没有 drift,才进入稳态
16
+ * `maxChars = 8000`。任何一次 drift 都清零连续计数,于是下一条请求立刻回落到预热预算。
17
+ *
18
+ * **不抛出**:没有会话、没有报告、登记表异常,一律返回预热期的保守预算。
19
+ * @param sessionId - 会话 id;不传则按最保守的预热预算处理。
20
+ * @returns 本次投影可用的预算。
21
+ */
22
+ export declare function cacheWarmupBudget(sessionId?: string): PreviewBudget;
23
+ /** 用量汇总。 */
24
+ export interface CacheWarmupUsageTotals {
25
+ /** 输入 token 合计。 */
26
+ inputTokens: number;
27
+ /** 命中缓存 token 合计。 */
28
+ cacheReadTokens: number;
29
+ /** 输出 token 合计。 */
30
+ outputTokens: number;
31
+ /** 总 token 合计。 */
32
+ totalTokens: number;
33
+ }
34
+ /** `cacheWarmupSnapshot()` 的返回形状:一份自足的只读快照。 */
35
+ export interface CacheWarmupSnapshot {
36
+ /** 会话 id;全局快照时不存在。 */
37
+ sessionId?: string;
38
+ /** 该会话当前的预算。 */
39
+ budget: PreviewBudget;
40
+ /** 子包默认值,方便设置页展示「当前处于预热期/稳态」的判据。 */
41
+ defaults: typeof CACHE_WARMUP_DEFAULTS;
42
+ /** 该会话的用量汇总。 */
43
+ usage: {
44
+ /** 保留的报告条数。 */
45
+ reports: number;
46
+ /** 最近一条报告时刻。 */
47
+ lastAt?: number;
48
+ /** 最近一次命中率。 */
49
+ hitRatio: number;
50
+ /** token 汇总。 */
51
+ totals: CacheWarmupUsageTotals;
52
+ /** 期间观测到的漂移原因(去重,供诊断)。 */
53
+ driftCauses: string[];
54
+ };
55
+ /** 登记表里的会话总数。 */
56
+ sessions: number;
57
+ }
58
+ /**
59
+ * 一份可读快照。**不抛出**,且完全无副作用(只读登记表)。
60
+ * @param sessionId - 会话 id;不传则给全局汇总。
61
+ * @returns 快照。
62
+ */
63
+ export declare function cacheWarmupSnapshot(sessionId?: string): CacheWarmupSnapshot;
64
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../../../src/host/cache-warmup/budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,qBAAqB,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAgB1E;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,CAkBnE;AAED,YAAY;AACZ,MAAM,WAAW,sBAAsB;IACrC,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,qBAAqB;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,kBAAkB;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB;IAChB,MAAM,EAAE,aAAa,CAAA;IACrB,oCAAoC;IACpC,QAAQ,EAAE,OAAO,qBAAqB,CAAA;IACtC,gBAAgB;IAChB,KAAK,EAAE;QACL,eAAe;QACf,OAAO,EAAE,MAAM,CAAA;QACf,gBAAgB;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,eAAe;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,gBAAgB;QAChB,MAAM,EAAE,sBAAsB,CAAA;QAC9B,0BAA0B;QAC1B,WAAW,EAAE,MAAM,EAAE,CAAA;KACtB,CAAA;IACD,iBAAiB;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,mBAAmB,CA6C3E"}
@@ -0,0 +1,267 @@
1
+ /**
2
+ * 缓存预热子包(cache-warmup)的共享契约:类型、默认值与错误码。
3
+ *
4
+ * 这一层刻意不 import 任何 `node:` 内置模块:投影与预算的一半逻辑是纯字符串/数字运算,
5
+ * 保持零依赖才能让消费者(宿主适配层、设置路由、测试)只为了一个类型就拖进文件系统实现。
6
+ * 唯一的例外是 `parseStructuredResultRows` —— 它是对**已存储原文**的解析器,
7
+ * 存储分页与投影预览必须共用同一份判定,否则「能分页但预览判断不同」会立刻变成幻觉。
8
+ *
9
+ * @module dsh-chatgpt-subscription/host/cache-warmup/contracts
10
+ */
11
+ /**
12
+ * 子包默认值。
13
+ *
14
+ * 预热期的字符上限是**按 token 反推的保守字符预算**:中文/代码混排大约每 token 1.6-2.0
15
+ * 字符,1200 字符落在 512-1024 token 区间的中段,宁可少给也不要在预热期用一个
16
+ * 还没被验证过的更大预算去撞缓存键。命中率与连续次数见约束 4。
17
+ */
18
+ export declare const CACHE_WARMUP_DEFAULTS: {
19
+ /** 预热期单次预览的字符预算。约 600-750 tokens。 */
20
+ readonly warmupMaxChars: 1200;
21
+ /** 稳态(连续两次高命中率且无 drift 之后)的字符预算。 */
22
+ readonly steadyStateMaxChars: 8000;
23
+ /** 视为命中的最低命中率。 */
24
+ readonly hitRatioThreshold: 0.97;
25
+ /** 退出预热期需要连续命中的报告条数。 */
26
+ readonly consecutiveHitsRequired: 2;
27
+ /** 单结果原文上限(字节)。 */
28
+ readonly maxResultBytes: number;
29
+ /** 每 session 原文总量上限(字节)。 */
30
+ readonly maxSessionBytes: number;
31
+ /** 分页 limit 默认值(行)。 */
32
+ readonly pageLimitDefault: 64;
33
+ /** 分页 limit 上限(行)。 */
34
+ readonly pageLimitMax: 512;
35
+ /** 分页 maxBytes 默认值(字节)。 */
36
+ readonly pageMaxBytesDefault: number;
37
+ /** 分页 maxBytes 上限(字节)。 */
38
+ readonly pageMaxBytesMax: number;
39
+ /** usage registry 的 session 数上限。 */
40
+ readonly maxUsageSessions: 256;
41
+ /** 每 session 保留的用量报告条数上限。 */
42
+ readonly maxUsageReportsPerSession: 32;
43
+ };
44
+ /** 预览预算,也是 `cacheWarmupBudget()` 的返回形状。 */
45
+ export interface PreviewBudget {
46
+ /** 一次预览最多占用的字符数。 */
47
+ maxChars: number;
48
+ /** 是否仍处于预热期。 */
49
+ warmup: boolean;
50
+ /** 当前连续高命中率报告条数(drift 会把它清零)。 */
51
+ consecutiveHits: number;
52
+ /** 最近一次报告的缓存命中率(0-1);没有报告时为 0。 */
53
+ hitRatio: number;
54
+ }
55
+ /** 一次缓存用量报告,形状与宿主 usage 统计一一对应。 */
56
+ export interface CacheWarmupUsage {
57
+ /** 会话 id。 */
58
+ sessionId: string;
59
+ /** 本次请求的输入 token 总数。 */
60
+ inputTokens: number;
61
+ /** 其中命中缓存的 token 数。 */
62
+ cacheReadTokens: number;
63
+ /** 本次请求的输出 token 数。 */
64
+ outputTokens: number;
65
+ /** 本次请求的总 token 数。 */
66
+ totalTokens: number;
67
+ /** 报告时刻(Unix 毫秒)。 */
68
+ at: number;
69
+ /** 非空表示这次观测到缓存漂移(前缀被改、工具集变化等),连续命中计数随之清零。 */
70
+ driftCause?: string;
71
+ }
72
+ /** 结果内容的「块」形状,与宿主工具结果的文本块对齐。 */
73
+ export interface ToolResultBlock {
74
+ /** 块类型;只有 `text` 会被投影考虑。 */
75
+ type: string;
76
+ /** 文本块正文。 */
77
+ text?: string;
78
+ /** 其他字段原样保留,永不改写。 */
79
+ [key: string]: unknown;
80
+ }
81
+ /** 工具结果内容:纯文本,或块数组(非文本块必须原样保留)。 */
82
+ export type ToolResultContent = string | readonly ToolResultBlock[];
83
+ /** 投影策略。`verbatim-*` 一律 `changed: false`。 */
84
+ export type ProjectionStrategy = 'verbatim-small' | 'verbatim-non-text' | 'verbatim-unparsed' | 'verbatim-source-code' | 'verbatim-contract' | 'verbatim-subagent-report' | 'verbatim-budget' | 'store-unavailable' | 'test-failure' | 'shell-output' | 'grep-results' | 'glob-results' | 'structured-rows';
85
+ /** 投影度量。契约要求前四个字段。 */
86
+ export interface ProjectionMetrics {
87
+ /** 输入字符数(原文长度)。 */
88
+ inputChars: number;
89
+ /** 输出字符数(预览长度)。 */
90
+ outputChars: number;
91
+ /** 被预览省略掉的字符数。 */
92
+ omittedChars: number;
93
+ /** 本次采用的策略。 */
94
+ strategy: ProjectionStrategy;
95
+ }
96
+ /** `projectToolResult` 的返回值。 */
97
+ export interface ProjectionResult {
98
+ /** 新内容:未改变时与入参逐字相同,改变时是预览文本(或替换了单个文本块的块数组)。 */
99
+ content: ToolResultContent;
100
+ /** 是否真的改写了内容。只有可证明结构化预览时才为 true。 */
101
+ changed: boolean;
102
+ /** 度量。 */
103
+ metrics: ProjectionMetrics;
104
+ /** 原文引用(只有在 `changed: true` 时存在)。 */
105
+ refId?: string;
106
+ /** 预览正文(只有在 `changed: true` 时存在)。 */
107
+ preview?: string;
108
+ /** 工具名(原样回显,便于统计)。 */
109
+ toolName: string;
110
+ /** 会话 id。 */
111
+ sessionId: string;
112
+ /** provider id(有就回显)。 */
113
+ provider?: string;
114
+ /** 投影时刻(Unix 毫秒)。 */
115
+ at: number;
116
+ }
117
+ /** `projectToolResult` 的入参。 */
118
+ export interface ProjectToolResultInput {
119
+ /** 工具名;用于识别测试/shell/grep/glob 结果。 */
120
+ toolName: string;
121
+ /** provider id,可选,只回显。 */
122
+ provider?: string;
123
+ /** 会话 id;refId 与分页的归属校验都基于它。 */
124
+ sessionId: string;
125
+ /** 工具结果内容。 */
126
+ content: ToolResultContent;
127
+ /** 是否为失败结果;失败结果的失败集必须完整保留。 */
128
+ isError?: boolean;
129
+ /** 预览预算;不传则按 `cacheWarmupBudget(sessionId)` 取当前预算。 */
130
+ budget?: PreviewBudget;
131
+ /** 原文存储;不传则保持原样(没有 ref 的预览等于丢数据)。 */
132
+ store?: ResultReferenceStore;
133
+ /** 投影时刻(Unix 毫秒),默认 `Date.now()`。 */
134
+ at?: number;
135
+ }
136
+ /** 一条已存储的结果引用。 */
137
+ export interface StoredResultReference {
138
+ /** `ref://<session>/<sha256>`。 */
139
+ refId: string;
140
+ /** 所属会话。 */
141
+ sessionId: string;
142
+ /** 原文的 sha256(小写十六进制)。 */
143
+ digest: string;
144
+ /** 原文字节数。 */
145
+ bytes: number;
146
+ /** 原文字符数。 */
147
+ chars: number;
148
+ /** 入库时刻(Unix 毫秒)。 */
149
+ at: number;
150
+ /** 是否本次新写入(false 表示命中了已存在的同一份内容)。 */
151
+ created: boolean;
152
+ }
153
+ /** `put` 的入参。 */
154
+ export interface ResultPutInput {
155
+ /** 会话 id。 */
156
+ sessionId: string;
157
+ /** 原文(逐字保存)。 */
158
+ content: string;
159
+ /** 工具名,只做记录,不参与寻址。 */
160
+ toolName?: string;
161
+ /** 入库时刻(Unix 毫秒)。 */
162
+ at?: number;
163
+ }
164
+ /** `page` 的入参。offset 从 0 开始。 */
165
+ export interface ResultPageQuery {
166
+ /** 会话 id;必须与 refId 内嵌的 session 一致。 */
167
+ sessionId: string;
168
+ /** `ref://<session>/<sha256>`。 */
169
+ refId: string;
170
+ /** 起始位置:文本模式是 UTF-8 字节偏移,结构化模式是(过滤后的)行下标。 */
171
+ offset?: number;
172
+ /** 本页最多行数,默认 64,上限 512。 */
173
+ limit?: number;
174
+ /** 本页最多字节数,默认 16384,上限 65536。 */
175
+ maxBytes?: number;
176
+ /** 结构化模式下要返回的字段;不传则返回全部字段。 */
177
+ fields?: readonly string[];
178
+ /** 结构化模式下的等值过滤(字符串比较,全部命中才算匹配)。 */
179
+ equals?: Readonly<Record<string, string>>;
180
+ }
181
+ /** 一页里被省略掉的部分;`reason: 'none'` 表示这一页就是全部。 */
182
+ export interface ResultPageOmitted {
183
+ /** 省略原因。 */
184
+ reason: 'none' | 'bytes' | 'lines' | 'rows';
185
+ /** 省略的字符数。 */
186
+ chars: number;
187
+ /** 省略的行数。 */
188
+ lines: number;
189
+ /** 省略的行数(结构化模式)。 */
190
+ rows: number;
191
+ /** 省略的字节数。 */
192
+ bytes: number;
193
+ }
194
+ /** `page` 的返回值。 */
195
+ export interface ResultPage {
196
+ /** 会话 id。 */
197
+ sessionId: string;
198
+ /** 原文引用。 */
199
+ refId: string;
200
+ /** 分页模式。 */
201
+ mode: 'text' | 'structured';
202
+ /** 本页内容;文本模式下是原文的一段,结构化模式下是 JSON 行。 */
203
+ content: string;
204
+ /** 本页起始位置(与入参同一单位)。 */
205
+ offset: number;
206
+ /** 下一页的起始位置;`null` 表示已经取完。 */
207
+ nextOffset: number | null;
208
+ /** 本页取完是否就是全文(不要用 content 长度去猜)。 */
209
+ complete: boolean;
210
+ /** 被省略的部分。 */
211
+ omitted: ResultPageOmitted;
212
+ /** 原文总字符数。 */
213
+ totalChars: number;
214
+ /** 原文总字节数。 */
215
+ totalBytes: number;
216
+ /** 实际生效的 limit。 */
217
+ limit: number;
218
+ /** 实际生效的 maxBytes。 */
219
+ maxBytes: number;
220
+ /** 结构化模式下返回的字段。 */
221
+ fields?: string[];
222
+ /** 结构化模式下的总行数。 */
223
+ totalRows?: number;
224
+ /** 结构化模式下过滤后参与分页的行数。 */
225
+ matchedRows?: number;
226
+ }
227
+ /**
228
+ * 结果引用存储。
229
+ *
230
+ * 一条结果一旦进入历史,它的 preview 与 refId 就是常量:存储过期、淘汰、
231
+ * 释放都只影响「还能不能读到原文」,永不影响已经写进历史的那段文本。
232
+ */
233
+ export interface ResultReferenceStore {
234
+ /** 保存原文并返回引用;同内容重复保存必须幂等。 */
235
+ put(input: ResultPutInput): Promise<StoredResultReference>;
236
+ /** 读取一页;必须校验 session 归属。 */
237
+ page(input: ResultPageQuery): Promise<ResultPage>;
238
+ /** 释放一条引用(只删这个具体文件);返回是否真的删掉了。 */
239
+ release(input: {
240
+ sessionId: string;
241
+ refId: string;
242
+ }): Promise<boolean>;
243
+ }
244
+ /** 错误码。 */
245
+ export type CacheWarmupErrorCode = 'SESSION_INVALID' | 'CONTENT_INVALID' | 'RESULT_TOO_LARGE' | 'STORE_FULL' | 'ROOT_INVALID' | 'REFERENCE_INVALID' | 'SESSION_MISMATCH' | 'RESULT_NOT_FOUND' | 'RESULT_EXPIRED' | 'OFFSET_OUT_OF_RANGE' | 'OFFSET_INVALID' | 'NOT_STRUCTURED' | 'FIELD_UNKNOWN';
246
+ /**
247
+ * 存储层错误。信息里只描述**请求本身**的问题,绝不回显其他 session 的内容或存在性。
248
+ */
249
+ export declare class CacheWarmupStoreError extends Error {
250
+ readonly code: CacheWarmupErrorCode;
251
+ constructor(message: string, code: CacheWarmupErrorCode);
252
+ }
253
+ /** 可靠解析出来的结构化行。 */
254
+ export interface StructuredResultRows {
255
+ /** 字段名,按首次出现顺序。 */
256
+ fields: string[];
257
+ /** 行,非字符串值用 JSON 序列化后存放。 */
258
+ rows: Array<Record<string, string>>;
259
+ }
260
+ /**
261
+ * 把一段文本可靠地解析成结构化行;解析不可靠就返回 undefined。
262
+ *
263
+ * 判定刻意保守:宁可返回 undefined 让调用方保持原文,也不要猜出一张表,
264
+ * 因为下游会把「猜出来的表」当成完整事实。
265
+ */
266
+ export declare function parseStructuredResultRows(text: string): StructuredResultRows | undefined;
267
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../../src/host/cache-warmup/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 缓存预热子包(cache-warmup)的公开入口。
3
+ *
4
+ * 三方(核心库 / 宿主集成 / Kimi adapter)只从这里取东西:
5
+ * 预算与用量状态、保守投影、内容寻址的结果存储与分页读取。
6
+ *
7
+ * 这个子包**不改变任何现有文件的行为**:它不被 `src/index.ts` 自动装载,
8
+ * 只有显式 import 它的调用方才会用上,所以引入它本身对现有请求是零影响。
9
+ *
10
+ * @module dsh-chatgpt-subscription/host/cache-warmup
11
+ */
12
+ export { CACHE_WARMUP_DEFAULTS, CacheWarmupStoreError, parseStructuredResultRows, } from './contracts.ts';
13
+ export type { CacheWarmupErrorCode, CacheWarmupUsage, PreviewBudget, ProjectionMetrics, ProjectionResult, ProjectionStrategy, ProjectToolResultInput, ResultPage, ResultPageOmitted, ResultPageQuery, ResultPutInput, ResultReferenceStore, StoredResultReference, StructuredResultRows, ToolResultBlock, ToolResultContent, } from './contracts.ts';
14
+ export { FileResultReferenceStore, defaultResultStoreRootDir, formatResultRefId, parseResultRefId, RESULT_REFERENCE_PREFIX, } from './store.ts';
15
+ export type { FileResultReferenceStoreOptions } from './store.ts';
16
+ export { projectToolResult, defaultPreviewBudget } from './projection.ts';
17
+ export { cacheWarmupBudget, cacheWarmupSnapshot } from './budget.ts';
18
+ export type { CacheWarmupSnapshot, CacheWarmupUsageTotals } from './budget.ts';
19
+ export { cacheWarmupHitRatio, cacheWarmupUsageReports, cacheWarmupUsageSessions, consecutiveWarmupHits, recordCacheWarmupUsage, resetCacheWarmupForTests, } from './usage.ts';
20
+ export type { CacheWarmupUsageSessionSummary, CacheWarmupUsageState } from './usage.ts';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/host/cache-warmup/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAA;AAEjE,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEzE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACpE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAE9E,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,8BAA8B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * 「缓存预热」宿主集成的挂载点。
3
+ *
4
+ * 这个文件把核心(结果投影、预算、引用存储、指标)接到宿主上,挂四样东西:
5
+ *
6
+ * 1. `tools/post-execute` 上的**新结果投影**:Kimi 线路的 `run_code` 结果交给
7
+ * `projectToolResult`,能可靠结构化提取的大结果被换成带 `ref://` 引用的预览;
8
+ * 2. `cache_warmup_result` 工具(`result-tool.ts`),预览的唯一精确补读入口;
9
+ * 3. 一段**静态**系统提示词引导(见 `CACHE_WARMUP_GUIDANCE`);
10
+ * 4. 结构化指标日志(`logging.ts`)。
11
+ *
12
+ * ## 只处理新结果
13
+ *
14
+ * post-execute 是每条工具结果各触发一次的**当下**事件:这里改的只是这次调用即将
15
+ * 写进历史的 content。历史里已经落下的结果不会被回改,`promptCacheKey`、replay、
16
+ * mapper、动态工具 in-history 机制一概不碰——它们读的是同一个 content,改历史
17
+ * 等于让同一个会话两次重放得到两段不同的字节。
18
+ *
19
+ * 因此开关的语义是**只影响之后的新结果**:关掉之后,已有的 preview/refId 继续
20
+ * 存在、继续可读(引用过期与否归存储管),只是不再产生新的。
21
+ *
22
+ * ## 可选服务一律走 `ctx.get()`
23
+ *
24
+ * `tools` 与 `systemPrompt` 都不在本插件的 `inject` 里(前者由宿主另装,后者
25
+ * 出现与否随 harness 代次)。Cordis 对没写进 `inject` 的服务直接读属性会抛
26
+ * `cannot get property "..." without inject`,一次就够把整个插件打成 degraded。
27
+ * 所以这里全部是**调用时**的 `get()`,缺席就安静降级:没有 tools 就不注册工具,
28
+ * 没有 systemPrompt 就不挂引导,插件照样挂得上。
29
+ *
30
+ * @module dsh-chatgpt-subscription/host/cache-warmup/install
31
+ */
32
+ import { type ResultReferenceStore } from './index.ts';
33
+ import { type CacheWarmupLogger } from './logging.ts';
34
+ import type { CacheWarmupSettings } from './settings.ts';
35
+ /**
36
+ * 本模块服务的线路。
37
+ *
38
+ * 结果投影的正确性依赖这条线路的缓存语义(内容前缀命中),别的线路上把结果换成
39
+ * 预览只有坏处没有好处,所以这里写死一个 provider 名而不是做成开关。
40
+ */
41
+ export declare const CACHE_WARMUP_PROVIDER = "kimi-code";
42
+ /**
43
+ * 被投影的工具名。
44
+ *
45
+ * 只有 `run_code` 的结果会走这张表:它的结果常常是一整屏的结构化输出,也正是
46
+ * 「换成预览 + 精确补读」唯一划得来的场景。别的工具(`read` 的源码、`grep` 的
47
+ * 契约定义)必须原样到达模型,核心侧的保守策略也建立在"调用方只喂该喂的"之上。
48
+ */
49
+ export declare const CACHE_WARMUP_SOURCE_TOOL = "run_code";
50
+ /** 提示词分节名,全局唯一(重复注册会抛错)。 */
51
+ export declare const CACHE_WARMUP_SECTION_NAME = "plugin:cache-warmup";
52
+ /**
53
+ * 引导词在提示词里的排序位。
54
+ *
55
+ * 插件族占用的区间在部署人设之后、SDK 的 `PLAN_POLICY`(500) 之前;进展更新占了
56
+ * 220,这里取 225,紧挨着它但不并列。
57
+ */
58
+ export declare const CACHE_WARMUP_SECTION_ORDER = 225;
59
+ /**
60
+ * 一段**恒定**的引导词:告诉模型预览是什么、怎么补读。
61
+ *
62
+ * 文本与开关无关,这是刻意的——系统提示是缓存前缀的第一段,会话中途改一个字就
63
+ * 让整段前缀失效、整段重新计费。开关的语义只交给 post-execute 与工具。
64
+ */
65
+ export declare const CACHE_WARMUP_GUIDANCE: string;
66
+ /**
67
+ * 静态引导词的文本提供者。
68
+ * @returns 一个永远返回同一段文本的函数(系统提示的稳定前缀)。
69
+ */
70
+ export declare function cacheWarmupSectionText(): () => string;
71
+ /** 一次工具调用所属的线路。 */
72
+ export interface CacheWarmupRoute {
73
+ /** 当前会话被路由到的 provider id。 */
74
+ readonly provider?: string;
75
+ /** 当前会话标识;引用归属、预算与命中率都按它记账。 */
76
+ readonly sessionId?: string;
77
+ }
78
+ /**
79
+ * 读一次工具调用所属的线路。
80
+ *
81
+ * provider 先问会话的 request header(那是本轮请求真正走的那条线),再退回
82
+ * agent 自己的 options。两处都没有就返回空对象——调用方据此放手,而不是猜一个。
83
+ * @param agent - 事件里的调用方 agent。
84
+ * @returns 线路信息;读不到的字段省略。
85
+ */
86
+ export declare function cacheWarmupRouteOf(agent: unknown): CacheWarmupRoute;
87
+ /** 挂载选项。 */
88
+ export interface CacheWarmupOptions {
89
+ /**
90
+ * 读取当前设置。
91
+ *
92
+ * 必须是**函数**:loader 把 volatile 字段换成活引用,设置保存时就地写新值而不
93
+ * 重挂插件行;apply 时求值一次存下来的写法会让开关在会话中途失效。
94
+ */
95
+ settings: () => CacheWarmupSettings;
96
+ /**
97
+ * 结果引用存储。
98
+ *
99
+ * 缺省时按需构造一个 `FileResultReferenceStore()`(核心的 `CACHE_WARMUP_DEFAULTS`
100
+ * 提供其余默认值);注入一个工厂是为了让测试与别的部署换掉存储,而不必改这里。
101
+ */
102
+ store?: () => ResultReferenceStore | undefined;
103
+ }
104
+ /** 本模块读得到的宿主上下文(Cordis Context 结构上满足;测试可用假对象)。 */
105
+ export interface CacheWarmupContext {
106
+ /** Cordis 的副作用登记:回调返回的 disposer 会随插件卸载执行。 */
107
+ effect?<T>(execute: () => T, label?: string): unknown;
108
+ /** Cordis 的事件总线。 */
109
+ on?(event: string, listener: (...args: never[]) => unknown): () => void;
110
+ /** 服务查找:**调用时**读可选服务,不触发 inject 断言。 */
111
+ get?(name: string): unknown;
112
+ /** 宿主 logger(可选)。 */
113
+ logger?: CacheWarmupLogger;
114
+ }
115
+ /**
116
+ * 挂载「缓存预热」的宿主半边。
117
+ * @param ctx - 宿主插件上下文。
118
+ * @param options - 挂载选项(设置读取器、可选的存储工厂)。
119
+ * @returns 卸载函数;重复挂载时返回一个空操作。
120
+ */
121
+ export declare function installCacheWarmup(ctx: CacheWarmupContext, options: CacheWarmupOptions): () => void;
122
+ /**
123
+ * 本文件刻意**不保留**任何"把异常压成一句话"的辅助函数。
124
+ *
125
+ * 这里曾经有一个 `describe(error)`,把 `error.message` 截断后拼进宿主日志。它看上去
126
+ * 无害(只取第一行、还截了长度),实际上是一条原文出口:异常消息里常常带着绝对
127
+ * 路径、命令行片段、凭据,或者被读取结果的一段正文。三处降级日志现在统一走
128
+ * {@link cacheWarmupErrorLabel}——只输出稳定的 name/code。
129
+ */
130
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../../src/host/cache-warmup/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,EAQL,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAA;AACnB,OAAO,EAKL,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAExD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,cAAc,CAAA;AAEhD;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,aAAa,CAAA;AAElD,4BAA4B;AAC5B,eAAO,MAAM,yBAAyB,wBAAwB,CAAA;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,MAAM,CAAA;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAStB,CAAA;AAEZ;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,MAAM,CAErD;AAED,mBAAmB;AACnB,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,+BAA+B;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAaD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAiBnE;AAED,YAAY;AACZ,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,mBAAmB,CAAA;IACnC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,oBAAoB,GAAG,SAAS,CAAA;CAC/C;AAED,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,oBAAoB;IACpB,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAAG,MAAM,IAAI,CAAA;IACvE,uCAAuC;IACvC,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B,qBAAqB;IACrB,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;AA+GD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,EAAE,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI,CA4NnG;AAiBD;;;;;;;GAOG"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * 「缓存预热」的结构化指标日志。
3
+ *
4
+ * 这个文件只做一件事:把一个**指标**形状的事件序列化成一行 JSON。它不碰原文、
5
+ * 不碰凭据、不碰路径——日志会被收进部署方的日志管道,一条原文进去就把整个工具
6
+ * 结果的体积原样复制了一份,一条凭据进去就是一次泄露。
7
+ *
8
+ * 形状按 `event` 判别,每个分支只允许出现它自己那几个字段:
9
+ *
10
+ * - `projection`:一次 post-execute 投影的输入/输出字符数与所选策略;
11
+ * - `ref-page`:一次 ref 分页读取(读了多少、是否读完、下一页从哪开始);
12
+ * - `ref-release`:一次引用释放;
13
+ * - `warmup-exit`:本会话的预热窗口结束(连同结束时的命中率指标)。
14
+ *
15
+ * @module dsh-chatgpt-subscription/host/cache-warmup/logging
16
+ */
17
+ /** 预热窗口退出时的判定原因(取值有限,便于按值统计)。 */
18
+ export type CacheWarmupExitReason =
19
+ /** 命中率已经稳定在阈值之上:预热算成功。 */
20
+ 'settled'
21
+ /** 命中率没跟上来:预热失败,回到保守行为。 */
22
+ | 'dropped';
23
+ /** 一次投影的日志记录。 */
24
+ export interface CacheWarmupProjectionLog {
25
+ readonly event: 'projection';
26
+ /** 会话标识(只用于把指标归到会话,不含任何正文)。 */
27
+ readonly session: string;
28
+ /** 核心选中的策略名(`raw` / `preview` 之类)。 */
29
+ readonly strategy: string;
30
+ /** 本次是否真的替换了内容。 */
31
+ readonly changed: boolean;
32
+ /** 投影前内容的字符数。 */
33
+ readonly inputChars: number;
34
+ /** 投影后内容的字符数。 */
35
+ readonly outputChars: number;
36
+ /** 被省略(只剩 preview 指向)的字符数。 */
37
+ readonly omittedChars: number;
38
+ /** 会话是否处在预热窗口内。 */
39
+ readonly warmup?: boolean;
40
+ }
41
+ /** 一次 ref 分页读取的日志记录。 */
42
+ export interface CacheWarmupPageLog {
43
+ readonly event: 'ref-page';
44
+ readonly session: string;
45
+ /** `ref://<session>/<sha256>` 形式的引用(本身不含原文)。 */
46
+ readonly refId: string;
47
+ /** 本次读取的起始偏移。 */
48
+ readonly offset: number;
49
+ /** 本次真正读到的字符数。 */
50
+ readonly returnedChars: number;
51
+ /** 这一次读取是否已经读到结尾。 */
52
+ readonly complete: boolean;
53
+ /** 下一次应从哪个偏移继续;`complete` 为真时没有这一项。 */
54
+ readonly nextOffset?: number;
55
+ }
56
+ /** 一次引用释放的日志记录。 */
57
+ export interface CacheWarmupReleaseLog {
58
+ readonly event: 'ref-release';
59
+ readonly session: string;
60
+ readonly refId: string;
61
+ /** 是否真的释放掉了(引用不存在时为 false,不算错误)。 */
62
+ readonly released: boolean;
63
+ }
64
+ /** 一次预热窗口退出的日志记录。 */
65
+ export interface CacheWarmupWarmupExitLog {
66
+ readonly event: 'warmup-exit';
67
+ readonly session: string;
68
+ readonly reason: CacheWarmupExitReason;
69
+ /** 退出时的连续命中次数(读不到就省略)。 */
70
+ readonly consecutiveHits?: number;
71
+ /** 退出时的命中率(读不到就省略)。 */
72
+ readonly hitRatio?: number;
73
+ }
74
+ /** 本模块产出的全部日志事件。 */
75
+ export type CacheWarmupLogEvent = CacheWarmupProjectionLog | CacheWarmupPageLog | CacheWarmupReleaseLog | CacheWarmupWarmupExitLog;
76
+ /** 日志行前缀,便于在混合日志里一眼认出来源。 */
77
+ export declare const CACHE_WARMUP_LOG_PREFIX = "[cache-warmup]";
78
+ /** 日志面(可选:本插件的 logger 老宿主上可能只有一部分成员)。 */
79
+ export interface CacheWarmupLogger {
80
+ /** 常规信息行。 */
81
+ info?(message: string): void;
82
+ /** 警告行。 */
83
+ warn?(message: string): void;
84
+ }
85
+ /**
86
+ * 把一条事件序列化成日志行。
87
+ *
88
+ * 形状写死在这里,而不是让调用方自己拼字符串:任何一次「顺手把 content 也带进
89
+ * 去」的改动都只会发生在这个函数里,而它有测试盯着(断言日志里不含原文)。
90
+ * 值为 `undefined` 的字段直接不出现在行里,保持每一行只描述它确实测到的指标。
91
+ * @param event - 指标事件。
92
+ * @returns 一行日志文本(带上本模块前缀)。
93
+ */
94
+ export declare function formatCacheWarmupLog(event: CacheWarmupLogEvent): string;
95
+ /**
96
+ * 把一个异常压成**稳定的身份标签**,只用于宿主日志。
97
+ *
98
+ * 只取两样东西:`name`(构造器名;缺失或不是非空字符串时退成 `'Error'`)和
99
+ * `code`(有就带上——`CacheWarmupStoreError` 与 Node 的系统错误都靠它区分)。
100
+ *
101
+ * **`message` 一律不进日志**,这是本函数存在的全部理由:异常消息里常常带着绝对
102
+ * 路径、命令行片段、凭据,或者被读取结果的一段原文。一条日志就够把原文复制一份,
103
+ * 或者把主机的目录结构写进部署方的日志管道。想知道"哪一类错误、来自哪一层",
104
+ * name/code 就够了;想知道"具体哪一条",该去会话本身看,不该从日志里捞。
105
+ * @param error - 捕获到的任意值。
106
+ * @returns 形如 `Error`、`RangeError`、`CacheWarmupStoreError/SESSION_MISMATCH`
107
+ * 的标签(`code` 是非空字符串时以 `/` 连接)。
108
+ */
109
+ export declare function cacheWarmupErrorLabel(error: unknown): string;
110
+ /**
111
+ * 发一条指标日志。
112
+ *
113
+ * logger 缺席时**安静跳过**:日志不是功能,装不上日志服务的宿主不该因此装不上
114
+ * 这个模块。写入失败同样吞掉——一条日志把工具调用搞挂是最不划算的失败。
115
+ * @param logger - 宿主 logger(可选)。
116
+ * @param event - 指标事件。
117
+ * @returns 写出的那一行(调用方/测试可以拿去断言);没写出去时 undefined。
118
+ */
119
+ export declare function logCacheWarmup(logger: CacheWarmupLogger | undefined, event: CacheWarmupLogEvent): string | undefined;
120
+ //# sourceMappingURL=logging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../../src/host/cache-warmup/logging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,iCAAiC;AACjC,MAAM,MAAM,qBAAqB;AAC/B,0BAA0B;AACxB,SAAS;AACX,2BAA2B;GACzB,SAAS,CAAA;AAEb,iBAAiB;AACjB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,sCAAsC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,mBAAmB;IACnB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,iBAAiB;IACjB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iBAAiB;IACjB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,8BAA8B;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,mBAAmB;IACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,wBAAwB;AACxB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iBAAiB;IACjB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,kBAAkB;IAClB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,qBAAqB;IACrB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,mBAAmB;AACnB,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED,qBAAqB;AACrB,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAA;IACtC,0BAA0B;IAC1B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,uBAAuB;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,oBAAoB;AACpB,MAAM,MAAM,mBAAmB,GAC3B,wBAAwB,GACxB,kBAAkB,GAClB,qBAAqB,GACrB,wBAAwB,CAAA;AAE5B,4BAA4B;AAC5B,eAAO,MAAM,uBAAuB,mBAAmB,CAAA;AAEvD,yCAAyC;AACzC,MAAM,WAAW,iBAAiB;IAChC,aAAa;IACb,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,WAAW;IACX,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAUvE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQ5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,EAAE,KAAK,EAAE,mBAAmB,GAAG,MAAM,GAAG,SAAS,CAUpH"}