@eddyskywalker/dsh-chatgpt-subscription 0.32.0 → 0.34.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 (116) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +100 -111
  3. package/lib/client.js +4731 -1239
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +11514 -3162
  6. package/lib/types/client/common/format.d.ts +10 -0
  7. package/lib/types/client/common/format.d.ts.map +1 -1
  8. package/lib/types/client/hub/brand-icons.d.ts +18 -2
  9. package/lib/types/client/hub/brand-icons.d.ts.map +1 -1
  10. package/lib/types/client/hub/hub-styles.d.ts.map +1 -1
  11. package/lib/types/client/hub/providers.d.ts.map +1 -1
  12. package/lib/types/client/index.d.ts +4 -0
  13. package/lib/types/client/index.d.ts.map +1 -1
  14. package/lib/types/client/minimax-code/VideoFormDialog.d.ts +46 -50
  15. package/lib/types/client/minimax-code/VideoFormDialog.d.ts.map +1 -1
  16. package/lib/types/client/minimax-code/locales.d.ts +80 -20
  17. package/lib/types/client/minimax-code/locales.d.ts.map +1 -1
  18. package/lib/types/client/minimax-code/styles.d.ts.map +1 -1
  19. package/lib/types/client/minimax-code/video-command-host.d.ts +17 -11
  20. package/lib/types/client/minimax-code/video-command-host.d.ts.map +1 -1
  21. package/lib/types/client/minimax-code/video-command-icon.d.ts +38 -0
  22. package/lib/types/client/minimax-code/video-command-icon.d.ts.map +1 -0
  23. package/lib/types/client/minimax-code/video-command.d.ts +53 -59
  24. package/lib/types/client/minimax-code/video-command.d.ts.map +1 -1
  25. package/lib/types/client/minimax-code/video-media-dropzone.d.ts +57 -0
  26. package/lib/types/client/minimax-code/video-media-dropzone.d.ts.map +1 -0
  27. package/lib/types/client/minimax-code/video-media-input.d.ts +173 -0
  28. package/lib/types/client/minimax-code/video-media-input.d.ts.map +1 -0
  29. package/lib/types/client/minimax-code/video-presets.d.ts +67 -0
  30. package/lib/types/client/minimax-code/video-presets.d.ts.map +1 -0
  31. package/lib/types/client/minimax-code/video-workspace.d.ts +41 -0
  32. package/lib/types/client/minimax-code/video-workspace.d.ts.map +1 -0
  33. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts +20 -0
  34. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts.map +1 -0
  35. package/lib/types/client/opendesign/OpenDesignSection.d.ts +18 -0
  36. package/lib/types/client/opendesign/OpenDesignSection.d.ts.map +1 -0
  37. package/lib/types/client/opendesign/api.d.ts +45 -0
  38. package/lib/types/client/opendesign/api.d.ts.map +1 -0
  39. package/lib/types/client/opendesign/locales.d.ts +689 -0
  40. package/lib/types/client/opendesign/locales.d.ts.map +1 -0
  41. package/lib/types/client/opendesign/styles.d.ts +11 -0
  42. package/lib/types/client/opendesign/styles.d.ts.map +1 -0
  43. package/lib/types/client/qoder/QoderComposerQuota.d.ts +41 -0
  44. package/lib/types/client/qoder/QoderComposerQuota.d.ts.map +1 -0
  45. package/lib/types/client/qoder/QoderSection.d.ts +36 -0
  46. package/lib/types/client/qoder/QoderSection.d.ts.map +1 -0
  47. package/lib/types/client/qoder/api.d.ts +4 -0
  48. package/lib/types/client/qoder/api.d.ts.map +1 -0
  49. package/lib/types/client/qoder/locales.d.ts +316 -0
  50. package/lib/types/client/qoder/locales.d.ts.map +1 -0
  51. package/lib/types/client/qoder/styles.d.ts +16 -0
  52. package/lib/types/client/qoder/styles.d.ts.map +1 -0
  53. package/lib/types/client/qoder/useQoderSection.d.ts +97 -0
  54. package/lib/types/client/qoder/useQoderSection.d.ts.map +1 -0
  55. package/lib/types/host/common/model-request-control.d.ts +1 -1
  56. package/lib/types/host/common/model-request-control.d.ts.map +1 -1
  57. package/lib/types/host/common/request-diagnostics.d.ts +1 -1
  58. package/lib/types/host/common/request-diagnostics.d.ts.map +1 -1
  59. package/lib/types/host/kimi-code/adapter.d.ts +34 -1
  60. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  61. package/lib/types/host/kimi-code/mapper.d.ts +8 -0
  62. package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
  63. package/lib/types/host/kimi-code/types.d.ts +92 -0
  64. package/lib/types/host/kimi-code/types.d.ts.map +1 -1
  65. package/lib/types/host/opendesign/account-pool.d.ts +54 -0
  66. package/lib/types/host/opendesign/account-pool.d.ts.map +1 -0
  67. package/lib/types/host/opendesign/adapter.d.ts +69 -0
  68. package/lib/types/host/opendesign/adapter.d.ts.map +1 -0
  69. package/lib/types/host/opendesign/catalog.d.ts +44 -0
  70. package/lib/types/host/opendesign/catalog.d.ts.map +1 -0
  71. package/lib/types/host/opendesign/client.d.ts +148 -0
  72. package/lib/types/host/opendesign/client.d.ts.map +1 -0
  73. package/lib/types/host/opendesign/line.d.ts +49 -0
  74. package/lib/types/host/opendesign/line.d.ts.map +1 -0
  75. package/lib/types/host/opendesign/mapper.d.ts +128 -0
  76. package/lib/types/host/opendesign/mapper.d.ts.map +1 -0
  77. package/lib/types/host/opendesign/oauth.d.ts +105 -0
  78. package/lib/types/host/opendesign/oauth.d.ts.map +1 -0
  79. package/lib/types/host/opendesign/routes.d.ts +74 -0
  80. package/lib/types/host/opendesign/routes.d.ts.map +1 -0
  81. package/lib/types/host/opendesign/token-store.d.ts +154 -0
  82. package/lib/types/host/opendesign/token-store.d.ts.map +1 -0
  83. package/lib/types/host/opendesign/types.d.ts +180 -0
  84. package/lib/types/host/opendesign/types.d.ts.map +1 -0
  85. package/lib/types/host/qoder/account-pool.d.ts +137 -0
  86. package/lib/types/host/qoder/account-pool.d.ts.map +1 -0
  87. package/lib/types/host/qoder/adapter.d.ts +158 -0
  88. package/lib/types/host/qoder/adapter.d.ts.map +1 -0
  89. package/lib/types/host/qoder/adopt.d.ts +146 -0
  90. package/lib/types/host/qoder/adopt.d.ts.map +1 -0
  91. package/lib/types/host/qoder/client.d.ts +301 -0
  92. package/lib/types/host/qoder/client.d.ts.map +1 -0
  93. package/lib/types/host/qoder/cosy.d.ts +173 -0
  94. package/lib/types/host/qoder/cosy.d.ts.map +1 -0
  95. package/lib/types/host/qoder/mapper.d.ts +235 -0
  96. package/lib/types/host/qoder/mapper.d.ts.map +1 -0
  97. package/lib/types/host/qoder/model-catalog.d.ts +231 -0
  98. package/lib/types/host/qoder/model-catalog.d.ts.map +1 -0
  99. package/lib/types/host/qoder/oauth.d.ts +134 -0
  100. package/lib/types/host/qoder/oauth.d.ts.map +1 -0
  101. package/lib/types/host/qoder/routes.d.ts +119 -0
  102. package/lib/types/host/qoder/routes.d.ts.map +1 -0
  103. package/lib/types/host/qoder/token-store.d.ts +280 -0
  104. package/lib/types/host/qoder/token-store.d.ts.map +1 -0
  105. package/lib/types/host/qoder/types.d.ts +257 -0
  106. package/lib/types/host/qoder/types.d.ts.map +1 -0
  107. package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
  108. package/lib/types/host/workbuddy/mapper.d.ts +1 -0
  109. package/lib/types/host/workbuddy/mapper.d.ts.map +1 -1
  110. package/lib/types/index.d.ts +15 -0
  111. package/lib/types/index.d.ts.map +1 -1
  112. package/lib/types/shared/opendesign-contracts.d.ts +159 -0
  113. package/lib/types/shared/opendesign-contracts.d.ts.map +1 -0
  114. package/lib/types/shared/qoder-contracts.d.ts +332 -0
  115. package/lib/types/shared/qoder-contracts.d.ts.map +1 -0
  116. package/package.json +1 -1
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Qoder(订阅)线路的上游 I/O:模型目录 + 额度 + userinfo + PAT 兑换 + 令牌刷新。
3
+ *
4
+ * 本文件只做两件事:**把请求发到上游**,以及**把上游的载荷翻译成本线路的形状**。
5
+ * 对话传输(编码 body、拆信封流)不在这里——那是 mapper.ts / adapter.ts 的活。
6
+ *
7
+ * ---------------------------------------------------------------------------
8
+ * 三条必须记住的上游事实(逐字证据在每处注释里)
9
+ * ---------------------------------------------------------------------------
10
+ *
11
+ * 1. **目录与对话都要 COSY 签名。** 模型列表是一个带 COSY 头的 GET(无 body;
12
+ * 签名里 body 分量是空串)。OpenAPI 面(PAT 兑换 / userinfo / 额度 / 设备轮询)
13
+ * 是 plain Bearer,不签名(pi-provider 的全部 openapi 调用一致)。
14
+ * 2. **COSY 版本落后会拿到缩减目录。** 版本每日跟随 Qoder CLI 的 release feed
15
+ * (pi-provider cosy-version.ts 同一设计),失败回落随包版本。
16
+ * 3. **额度失败绝不影响模型请求。** 额度是非公开个人端点(计划 §5、§9 风险 1),
17
+ * 它的一切都返回**值**(QoderQuotaRead),没有一条路径把错误抛给调用方之外的边界。
18
+ *
19
+ * ---------------------------------------------------------------------------
20
+ * 注入缝
21
+ * ---------------------------------------------------------------------------
22
+ * 每个网络函数都接受 fetchFn(默认 fetch)与 env(默认 process.env),且 env
23
+ * **在调用时**读取(不是模块加载时),这样单测不碰真实网络也不碰真实凭据。
24
+ */
25
+ import type { QoderQuotaSnapshotDto, QoderRegion } from '../../shared/qoder-contracts.ts';
26
+ import { type QoderCosyIdentity } from './cosy.ts';
27
+ import { type QoderModelEntry } from './model-catalog.ts';
28
+ export interface QoderRequestOptions {
29
+ /** 测试缝。默认 fetch。 */
30
+ fetchFn?: typeof fetch;
31
+ signal?: AbortSignal;
32
+ /** 环境变量读取处。默认 process.env,且**调用时**读取。 */
33
+ env?: NodeJS.ProcessEnv;
34
+ }
35
+ /** 错误详情去控制字符并截断(卡片与日志共用同一口径)。 */
36
+ export declare function qoderErrorDetail(text: string, limit?: number): string;
37
+ /**
38
+ * 本线路发上游请求需要的那份凭据切片。
39
+ *
40
+ * 这是**号池凭据的结构化超集**:account-pool.ts 的 QoderCredentials 加了来源与
41
+ * 落盘字段,而本文件的每个函数都能直接吃号池交出来的凭据,而不必认识池。
42
+ */
43
+ export interface QoderUpstreamCredential {
44
+ readonly accessToken: string;
45
+ readonly region: QoderRegion;
46
+ readonly uid: string | null;
47
+ readonly email: string | null;
48
+ readonly accountName: string | null;
49
+ readonly organizationId?: string | null;
50
+ readonly organizationTags?: readonly string[];
51
+ readonly dataPolicyAgreed?: boolean;
52
+ }
53
+ /**
54
+ * 凭据切片 → COSY 身份。
55
+ *
56
+ * UserInfo 的字段顺序**固定**(uid / security_oauth_token / name / aid / email,
57
+ * 逐字 pi-provider \`cosy.ts\` 的 UserInfo 形状):它原样进 AES 明文,而官方算法
58
+ * 对 raw 字符串原样处理(docs/oauth.md §5),所以这里手写键序而不是 JSON.stringify
59
+ * 一个对象——后者的键序是实现细节,不是协议事实。
60
+ */
61
+ export declare function qoderCosyIdentityOf(credentials: QoderUpstreamCredential, env?: NodeJS.ProcessEnv): QoderCosyIdentity;
62
+ /** OpenAPI 面请求的头(plain Bearer,不签名;逐字 pi-provider pat.ts 的头集)。 */
63
+ export declare function qoderOpenapiHeaders(credentials: {
64
+ accessToken: string;
65
+ }): Record<string, string>;
66
+ /** 一个值是不是合法的 x.y.z 版本串。 */
67
+ export declare function isQoderCliVersion(value: unknown): value is string;
68
+ /** x.y.z 的数字比较。 */
69
+ export declare function compareQoderCliVersions(a: string, b: string): number;
70
+ /**
71
+ * 当前签名用的 COSY 版本:缓存里更新的 CLI release 优先,否则随包回落。
72
+ * 同步且**无网络**;刷新发生在 {@link refreshQoderCosyVersion}。
73
+ */
74
+ export declare function getQoderCosyVersion(): string;
75
+ /**
76
+ * 跟随 Qoder CLI 的最新 release(每日最多一次,失败完全容忍)。
77
+ *
78
+ * 逐字 pi-provider \`refreshGatewayCosyVersion\` 的设计:网关给 COSY 版本落后的客户端
79
+ * 发**缩减的**模型目录,所以签名身份要跟着 CLI 走;但任何失败(离线、坏载荷、更旧的
80
+ * tag)都回落到既有版本——签名绝不依赖这次 fetch 成功。
81
+ */
82
+ export declare function refreshQoderCosyVersion(options?: QoderRequestOptions & {
83
+ force?: boolean;
84
+ }): Promise<void>;
85
+ /** 测试用:清掉进程内版本缓存。 */
86
+ export declare function clearQoderCosyVersionCache(): void;
87
+ /** 模型列表 URL。 */
88
+ export declare function qoderModelListUrl(region: QoderRegion, env?: NodeJS.ProcessEnv): string;
89
+ /** 对话 URL(adapter 用;拼在这里,全局只有这一处)。 */
90
+ export declare function qoderChatUrl(region: QoderRegion, env?: NodeJS.ProcessEnv): string;
91
+ /**
92
+ * 目录里的一条模型(host 内部形状 = 能力行;只含端点真的报了的字段装配出来的结果)。
93
+ * 与 step-code 的 StepCodeCatalogEntry 不同:本线路的解析直接产出能力行
94
+ * ({@link parseQoderModelListing}),缓存里放的就是它。
95
+ */
96
+ export type QoderCatalogEntry = QoderModelEntry;
97
+ /** 无凭据 / 失败 / 离线时目录为空:调用方回落随包表,而不是抛错。 */
98
+ export declare function fetchQoderModelCatalog(credentials: QoderUpstreamCredential, options?: QoderRequestOptions): Promise<QoderCatalogEntry[]>;
99
+ /** 本进程当前记住的目录(纯内存读,不触发任何网络请求)。 */
100
+ export declare function getCachedQoderModelCatalog(region?: QoderRegion): readonly QoderCatalogEntry[];
101
+ /**
102
+ * 本进程此刻拿到的目录是**实时目录**(上游真的答过)还是**随包兜底表**。
103
+ *
104
+ * 这条判定必须单独导出、口径只有一处,因为下游对它有两个消费者而两处的后果都很具体:
105
+ *
106
+ * - `adapter.listModels` 与状态面的勾选标记要知道「这一份目录是不是这个账号真实可用的
107
+ * 集合」,才知道用不用用户的白名单去筛它(见下面的「两套 id 词汇表」);
108
+ * - 任何自己拼「缓存有没有 / 是不是空」的地方都会与它漂:一处按 `undefined` 判空、
109
+ * 另一处按「条目数为 0」判空,兜底表就会被当成本账号的真实目录。
110
+ *
111
+ * -------------------------------------------------------------------------
112
+ * 两套 id 词汇表(这是缺陷 1 的证据,别再合并它们)
113
+ * -------------------------------------------------------------------------
114
+ * 用户的白名单是在设置卡片上对着**实时目录**勾出来的 id,而实时目录的 id 就是上游
115
+ * `display_name` 去空白(model-catalog.ts `toQoderModelId`);随包兜底表照录
116
+ * pi-provider 的静态表,同一批模型在两边**叫法不同**:
117
+ *
118
+ * | 实时目录(用户勾的) | 随包兜底表 |
119
+ * | --- | --- |
120
+ * | `DeepSeek-Flash` | `DeepSeek-V4-Flash` |
121
+ * | `Qwen3.8-Flash` | `Qwen3.8-Max` / `Qwen3.7-Plus` |
122
+ * | `Ultimate` | `Ultimate`(少数恰好同名) |
123
+ *
124
+ * 所以「用白名单去筛兜底表」这件事在冷启动时必然收敛成空集,而 `listModels` 返回空
125
+ * 会让 DSH 把整个 provider 分组过滤掉——选择器里连 Qoder 都不剩。
126
+ *
127
+ * @param region 要判定的区域(目录是区域的属性,别的区域的缓存不算数)。
128
+ */
129
+ export declare function qoderCatalogIsLive(region: QoderRegion): boolean;
130
+ /** 清掉内存目录、快照 scope 与在飞的去重。 */
131
+ export declare function clearCachedQoderModelCatalog(): void;
132
+ /**
133
+ * 当前进程的目录缓存是否「需要(或应该)拉一次」:空缓存、别的区域的缓存、
134
+ * 或者已经旧到过了 {@link CATALOG_CACHE_TTL_MS}。
135
+ *
136
+ * 之所以把这条判定单独导出,是因为它有两个消费者而只能有一份口径:设置卡片的
137
+ * `GET /status` 要在应答背后决定「这次要不要顺手拉一次」,而不是每条路径
138
+ * 各写一遍「有没有缓存 / 过没过期」。判定口径分叉的那种后果很具体——一处按
139
+ * `undefined` 判空、另一处按「条目数为 0」判空,于是空数组缓存永远被判成
140
+ * 「有缓存,不用拉」,选择器就永远停在兜底表上。
141
+ *
142
+ * 读的是与 {@link loadQoderModelCatalog} **同一个** `cachedCatalog` 与其
143
+ * `fetchedAt`,所以「这里说不用拉」与「那边会直接命中缓存」是同一件事。
144
+ * 纯读:不联网、不写缓存、不改任何状态,因此可以在应答路径上随手调用。
145
+ *
146
+ * @param region 要判定的区域(目录是区域的属性,别的区域的缓存不算数)。
147
+ * @param now 当前时刻;显式传入是为了让「过期」这件事在测试里可确定。
148
+ */
149
+ /**
150
+ * 缓存目录的写入时刻(Unix 毫秒),没有缓存时为 undefined。
151
+ *
152
+ * 给「过期判定」的测试一个**确定**的基准:测试原先在 await 返回后用
153
+ * `Date.now()` 去推边界,而缓存里的 `fetchedAt` 是稍早一次 `Date.now()`,
154
+ * 两次读时钟之间的毫秒差会让「差一毫秒到期仍算新鲜」这条断言偶发翻车。
155
+ * 读的是与 {@link qoderCatalogNeedsRefresh} 同一个字段,纯读、无副作用。
156
+ */
157
+ export declare function qoderCatalogFetchedAt(region: QoderRegion): number | undefined;
158
+ export declare function qoderCatalogNeedsRefresh(region: QoderRegion, now?: number): boolean;
159
+ /**
160
+ * 进程内实时目录的指纹:还没有实时目录(只有随包兜底表)时是空数组的序列化。
161
+ *
162
+ * 「这次刷新有没有真的换掉目录」的判定**只有这一处**。它有两个调用方,而两处
163
+ * 判错的后果都很具体:
164
+ *
165
+ * - `routes.ts` 的刷新路径在这一条上决定发不发 `llm/adapters-updated`:这张卡片
166
+ * 每 60 秒轮询一次,无条件发就等于让模型选择器每拍重建一遍;
167
+ * - `index.ts` 的**启动预热**同样要发一次,而且启动那一刻根本没有任何订阅方在等,
168
+ * 发早发晚都不影响正确性——但它与刷新路径必须是同一句判词,否则「目录变了没有」
169
+ * 在两条路径上会给出两个答案。
170
+ *
171
+ * 用 id 序列而不是数组引用:{@link loadQoderModelCatalog} 命中缓存时会把**同一个
172
+ * 数组**交回来,按引用比较永远相等,那样「目录真的变了」就永远判不出来。
173
+ *
174
+ * @param region 要取指纹的区域(目录是区域的属性,别的区域的缓存不算数)。
175
+ */
176
+ export declare function qoderCatalogFingerprint(region: QoderRegion): string;
177
+ /**
178
+ * 启动预热:把上一次落盘的真实目录**立刻**放回进程内缓存,再让上游刷新跑在背后。
179
+ *
180
+ * ---------------------------------------------------------------------------
181
+ * 为什么要在启动时预热
182
+ * ---------------------------------------------------------------------------
183
+ * `cachedCatalog` 是进程内的,宿主一重启它就是空的;而此时磁盘快照
184
+ * (`<DSH_HOME>/storages/qoder-global-catalog.json`)里明明躺着上一次的真实目录。
185
+ * 没有预热时,唯一把它读回来的入口是 `loadQoderModelCatalog`,而它只被设置页的
186
+ * `GET /status` / 登录 / adopt / `POST /catalog/refresh` 调用——于是**启动之后、
187
+ * 用户第一次打开设置页之前**,`adapter.listModels` 读到的是随包兜底表(全球区
188
+ * 15 条),模型选择器就把这一大片缺省模型摊在用户面前;等设置页被打开、那次
189
+ * 应答背后的刷新落地,它才换成真实的两条。用户看到的是「重启后先冒出一堆假模型,
190
+ * 点一下设置页才正常」。
191
+ *
192
+ * 预热把这段空窗压到进程启动的第一拍:快照是本地读,几十毫秒内就位。
193
+ *
194
+ * ---------------------------------------------------------------------------
195
+ * 为什么不能 await(调用方必须 `void ... .catch()`)
196
+ * ---------------------------------------------------------------------------
197
+ * 第二段(`loadQoderModelCatalog`)在**没有快照**的机器上就是一次真实的上游请求:
198
+ * 它会跟随 COSY 版本、签一次名、打一次目录端点,超时上限是 `DISCOVERY_TIMEOUT_MS`。
199
+ * 把它 await 在插件装配里,等于让整个宿主插件的装载挂在一条可降级的网络请求上——
200
+ * 离线、上游抽风、代理没起来,都会变成「插件装不上」,而这条线路在没有目录时本来
201
+ * 就有一张随包兜底表可用。所以:预热是**尽力而为**,失败一律吞掉,调用方不等待。
202
+ *
203
+ * 有快照时它不会等网络:快照回填之后 `loadQoderModelCatalog` 走的是「陈旧缓存
204
+ * 立刻返回 + 后台刷新」那条路(见该函数),所以正常机器的预热是毫秒级的。
205
+ *
206
+ * @param credentials 预热用的凭据切片。没有账号时调用方不该调用本函数。
207
+ * @param options 与其它上游函数同一套注入缝(fetchFn / env)。
208
+ * @returns **快照回填之后、网络刷新之前**那份目录的指纹,也就是这次预热里「上游那一版
209
+ * 将要顶替掉的是什么」。调用方拿它当比较基线:与它不同才算「目录真的变了」。
210
+ * 只为发一次事件而返回它,而不是让调用方自己再取一次——那样它取到的是回填**之前**
211
+ * 的空目录,冷启动时永远「变了」,等于每次启动都无条件发事件。
212
+ * 预热失败时返回回填后(可能仍为空)的指纹。
213
+ */
214
+ export declare function warmQoderModelCatalog(credentials: QoderUpstreamCredential, options?: QoderRequestOptions): Promise<string>;
215
+ /**
216
+ * TTL 缓存 + in-flight 去重 + 磁盘快照的目录读取(三层各解决一件事,
217
+ * 照抄 step-code/client.ts 的同名结构):
218
+ *
219
+ * - **TTL**:目录不是快变数据;
220
+ * - **in-flight 去重**:同一个区域上并发的两个调用共用一次请求;
221
+ * - **磁盘快照**(catalog-snapshot.ts):冷启动不等网络;快照按区域分文件。
222
+ *
223
+ * force: true 跳过缓存与快照直接重取(设置卡片的「刷新」按钮用)。
224
+ */
225
+ export declare function loadQoderModelCatalog(credentials: QoderUpstreamCredential, options?: QoderRequestOptions & {
226
+ force?: boolean;
227
+ }): Promise<QoderCatalogEntry[]>;
228
+ /** 上游 userinfo 的账号事实。 */
229
+ export interface QoderUserInfo {
230
+ userID: string;
231
+ email: string;
232
+ name: string;
233
+ organizationId?: string;
234
+ organizationTags?: string[];
235
+ dataPolicyAgreed?: boolean;
236
+ }
237
+ /**
238
+ * GET {openapi}/api/v1/userinfo(Bearer job token;best-effort 字段读取,
239
+ * 逐字 pi-provider pat.ts \`fetchUserInfo\` 的字段名)。
240
+ *
241
+ * 失败**抛错**(与目录不同):调用方是登录/刷新路径,一把读不出 userinfo 的 token
242
+ * 在 CN 会被推理面拒成「Login expired」(105),让调用方知道比静默兜底诚实。
243
+ */
244
+ export declare function fetchQoderUserInfo(accessToken: string, region: QoderRegion, options?: QoderRequestOptions): Promise<QoderUserInfo>;
245
+ /** PAT 兑换的返回值。 */
246
+ export interface QoderJobTokenExchange {
247
+ /** 短期 job token(\`jt-...\`)。 */
248
+ token: string;
249
+ /** job refresh token(\`jrt-...\`);上游没给时为 null。 */
250
+ refreshToken: string | null;
251
+ /** 过期时刻(Unix 毫秒,已含安全边)。 */
252
+ expiresAt: number;
253
+ }
254
+ /**
255
+ * POST {openapi}/api/v1/jobToken/exchange,体 \`{"personal_token":"<pt-...>"}\`。
256
+ *
257
+ * PAT 不能直接鉴权,必须先兑换(docs.qoder.com/cli/authentication + pi-provider pat.ts)。
258
+ * 失败抛错(登录路径要如实告诉用户 PAT 被拒)。
259
+ */
260
+ export declare function exchangeQoderJobToken(personalToken: string, region: QoderRegion, options?: QoderRequestOptions): Promise<QoderJobTokenExchange>;
261
+ /**
262
+ * POST {center}/algo/api/v3/user/refresh_token(Bearer access + \`{"refreshToken"}\`)。
263
+ *
264
+ * 逐字 pi-provider \`refreshQoderTokenForMode\` 的请求形状(live 验证)。
265
+ * 失败抛错由调用方(号池的 refresh 钩子)分类。
266
+ */
267
+ export declare function refreshQoderAccessToken(credentials: {
268
+ accessToken: string;
269
+ refreshToken: string;
270
+ }, region: QoderRegion, options?: QoderRequestOptions): Promise<QoderJobTokenExchange>;
271
+ /** 一次额度读取的结果;失败以值返回而不是抛出(路由据此下发 quotaError)。 */
272
+ export type QoderQuotaRead = {
273
+ ok: true;
274
+ snapshot: QoderQuotaSnapshotDto;
275
+ } | {
276
+ ok: false;
277
+ error: string;
278
+ };
279
+ /**
280
+ * 归一化一份额度载荷。
281
+ *
282
+ * 一只桶都不认识时返回 undefined(上游改版或账号没有套餐)——快照不下发,
283
+ * 卡片显示「读不出来」而不是一张全空的卡。缺失的数字保持缺失,**绝不发明**
284
+ * (技能规约「零不是未知」)。
285
+ */
286
+ export declare function normalizeQoderQuotaSnapshot(value: unknown, region: QoderRegion, fetchedAt?: number): QoderQuotaSnapshotDto | undefined;
287
+ /** 某账号最近一次读到的额度快照(纯内存读;号池装配摘要时用)。 */
288
+ export declare function getCachedQoderQuotaFor(accountId: string): QoderQuotaSnapshotDto | undefined;
289
+ /** 测试与登出用:清掉内存额度缓存。 */
290
+ export declare function clearCachedQoderQuota(): void;
291
+ /**
292
+ * GET {openapi}/api/v2/quota/usage(Bearer job token)。
293
+ *
294
+ * ⚠ 非公开个人端点(计划 §5、§9 风险 1)。TTL 缓存 + 在飞去重;失败以值返回。
295
+ * \`cacheKey\` 是号池账号 id:快照记在**账号**名下,额度跟着账号走。
296
+ */
297
+ export declare function loadQoderQuota(credentials: QoderUpstreamCredential, options?: QoderRequestOptions & {
298
+ force?: boolean;
299
+ cacheKey?: string;
300
+ }): Promise<QoderQuotaRead>;
301
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/host/qoder/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Qoder(订阅)线路的 COSY 签名与请求 codec。
3
+ *
4
+ * 本文件是整条线路协议风险最高的部分,所以它的每一步都被一份**全合成 frozen
5
+ * fixture** 锁成 byte-exact(`test/qoder-cosy.test.ts`,fixture 来自
6
+ * Liki4/qodercli2api `testdata/protocol/1.1.34/`,逐字算法见它的
7
+ * `docs/oauth.md` §5 与 `docs/inference-protocol.md` §2-§4):
8
+ *
9
+ * - {@link generateQoderRuntimeAuthFields} —— runtime-fields.json;
10
+ * - {@link decryptQoderAdoptPayload} —— credential.json;
11
+ * - {@link encodeQoderBody} —— infer-user-no-org.json 的 `body_string`;
12
+ * - {@link buildQoderCosyHeaders} —— infer-user-no-org.json 的 18 头集合与签名。
13
+ *
14
+ * 与 pi-provider-qoder `src/cosy.ts` 的分歧(它多发 `Cosy-Machineos` /
15
+ * `Cosy-Clientip` / `Cosy-Bodyhash` / `Cosy-Bodylength` / `Cosy-Sigpath` /
16
+ * `X-Request-Id` 六个头)以 **fixture 为准**:那是官方 pinned WASM 的头集合,
17
+ * pi 的超集只是「被服务端容忍」,不是协议的一部分(计划 §9 风险 3)。
18
+ *
19
+ * 本文件不做任何网络 I/O,也不持有凭据:它吃的是调用方递进来的材料,吐出的是
20
+ * 头与 body。machine id 的读取顺序(qodercli 原配 → 本线路自己的文件 → 内存生成)
21
+ * 见 {@link resolveQoderMachineId}。
22
+ */
23
+ /**
24
+ * runtime RSA-1024 SPKI 公钥(**非秘密公钥**)。
25
+ *
26
+ * 逐字来源:qodercli2api `docs/oauth.md` §5(从 pinned v1.1.34 WASM 提取,
27
+ * SPKI DER 162 bytes,SHA-256 `a6a4aa468d90c618966e38122abfb06e566c18c9b21090d61f3e9b796b33e569`),
28
+ * 与 pi-provider `cosy.ts` 内嵌的那把逐字相同。用途只有一个:PKCS#1 v1.5 加密
29
+ * 每次请求的 runtime AES key(16 个 ASCII 字符),产物是 `Cosy-Key` 头与签名的
30
+ * `key` 分量。**不要**与同一 WASM 里另一把 2048-bit profile RSA 公钥混淆。
31
+ */
32
+ export declare const QODER_RUNTIME_RSA_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA8iMH5c02LilrsERw9t6Pv5Nc\n4k6Pz1EaDicBMpdpxKduSZu5OANqUq8er4GM95omAGIOPOh+Nx0spthYA2BqGz+l\n6HRkPJ7S236FZz73In/KVuLnwI8JJ2CbuJap8kvheCCZpmAWpb/cPx/3Vr/J6I17\nXcW+ML9FoCI6AOvOzwIDAQAB\n-----END PUBLIC KEY-----";
33
+ /**
34
+ * 官方的字节变换(逐字 docs/oauth.md §5.1 与 inference-protocol.md §3.1):
35
+ * RNG bytes `R[16]` 逐字节反转为 `U[i]=R[15-i]`,再置 UUID 版本/变体位
36
+ * `U[6]=(U[6]&0x0f)|0x40`、`U[8]=(U[8]&0x3f)|0x80`。
37
+ *
38
+ * 同一段变换服务两个产物:runtime AES key(hex 的前 16 个字符)与
39
+ * COSY request UUID(完整 hex 按 8-4-4-4-12 格式化)。
40
+ */
41
+ export declare function qoderMaskedBytes(entropy: Buffer): Buffer;
42
+ /**
43
+ * 熵 → COSY request UUID。
44
+ *
45
+ * 逐字 inference-protocol.md §3.1:完整 masked U 按 lowercase `8-4-4-4-12` 格式化,
46
+ * 不再反转字段内部字节。每次 prepare 重新生成且不得复用(服务端对重复 `request_id`
47
+ * 返回 code 103)。
48
+ */
49
+ export declare function qoderRequestUuid(entropy: Buffer): string;
50
+ /**
51
+ * 一次请求的 runtime 凭据材料。
52
+ *
53
+ * 逐字 docs/oauth.md §5(frozen fixture `runtime-fields.json` 锁定):
54
+ *
55
+ * 1. `K` = {@link qoderMaskedBytes} 的 lowercase hex 的前 16 个字符,作为
56
+ * **16 个 ASCII 字节**使用(绝不再做 hex decode);
57
+ * 2. `encryptUserInfo` = AES-128-CBC(key=IV=K 的原始字节,PKCS#7)加密
58
+ * 调用方给的 **raw UTF-8 字符串原样**(不 parse / 不 re-marshal——字段顺序、
59
+ * 空白和转义都进 AES 明文),输出 strict standard padded Base64;
60
+ * 3. `key` = 用 {@link QODER_RUNTIME_RSA_PUBLIC_KEY}(PKCS#1 v1.5)加密 `K`
61
+ * 的 standard padded Base64。
62
+ *
63
+ * @param rawUserInfo - UserInfo 的原始 JSON 串(原样加密,不规范化)。
64
+ * @param entropy - 测试缝:16 字节熵的供应处(fixture 用固定 tape 驱动)。
65
+ */
66
+ export declare function generateQoderRuntimeAuthFields(rawUserInfo: string, entropy?: () => Buffer): {
67
+ encryptUserInfo: string;
68
+ key: string;
69
+ };
70
+ /**
71
+ * 解密一份 qodercli 的凭据文件内容。
72
+ *
73
+ * 格式(逐字 docs/oauth.md §4):strict standard padded Base64 信封 →
74
+ * AES-128-CBC(key=IV=`machineId` 前 16 个字符的 raw UTF-8 字节,PKCS#7 严格校验)。
75
+ * 官方加载兼容:去除外围空白后以 `{` 开头的内容按明文 JSON 解析——本函数同一行为。
76
+ *
77
+ * 解密失败(格式不对、padding 坏了、key 不对)抛错;调用方(adopt.ts)把它归到
78
+ * `invalid-credentials`,**绝不在这里猜第二把 key**。
79
+ */
80
+ export declare function decryptQoderAdoptPayload(content: string, machineId: string): string;
81
+ /**
82
+ * 请求体编码:raw bytes → standard padded Base64 → alphabet 逐位置映射(`=`→`$`)
83
+ * → 外三段交换(`k=floor(len/3)`,输出 `s[len-k:] + s[k:len-k] + s[:k]`)。
84
+ *
85
+ * 它是**可逆的确定性编码,不是加密**(inference-protocol.md §4 原话);算法不依赖
86
+ * user、model、clock 或 randomness,输入的每个字节(含字段顺序与空白)都进输出——
87
+ * 所以调用方一旦拼好 JSON 就不要再经任何一轮 parse/re-marshal。
88
+ *
89
+ * @returns ASCII 字符串(签名参与的就是这串字符的 UTF-8 字节,两者相同)。
90
+ */
91
+ export declare function encodeQoderBody(raw: string | Buffer): string;
92
+ /** COSY 签名身份材料(一次请求一份)。 */
93
+ export interface QoderCosyIdentity {
94
+ /** `Cosy-User`:上游账号 id。 */
95
+ uid: string;
96
+ /** UserInfo 的原始 JSON 串(被 AES 进 payload 的 `info`)。 */
97
+ rawUserInfo: string;
98
+ /** `Cosy-MachineId` / `Cosy-MachineToken`(同一个 36 字符 UUID)。 */
99
+ machineId: string;
100
+ /** `Cosy-Version`:当前生效的 COSY 版本(跟随 CLI release,client.ts 管)。 */
101
+ cosyVersion: string;
102
+ /** `Cosy-Data-Policy`:true → `agree`,否则 `disagree`。 */
103
+ dataPolicyAgreed: boolean;
104
+ /** 组织 id;非空才出现在头里(presence 矩阵,docs/inference-protocol.md §2)。 */
105
+ organizationId?: string | null;
106
+ /** 组织 tags;长度大于零才出现在头里(逗号连接)。 */
107
+ organizationTags?: readonly string[];
108
+ }
109
+ /**
110
+ * COSY 签名(inference-protocol.md §3.3,fixture 锁定)。
111
+ *
112
+ * canonical bytes 精确为 `payloadB64 LF key LF unixSeconds LF encodedBody LF signedPath`
113
+ * ——五段、四个 `\n`,**末尾没有 LF**;签名是小写 hex MD5。
114
+ */
115
+ export declare function qoderCosySignature(input: {
116
+ payloadB64: string;
117
+ key: string;
118
+ unixSeconds: string;
119
+ encodedBody: string;
120
+ signedPath: string;
121
+ }): string;
122
+ /**
123
+ * 一个 URL 的签名路径:pathname 剥掉 `/algo` 前缀,不含 query
124
+ * (inference-protocol.md §1:签名 path 固定为 `/api/v2/service/pro/sse/agent_chat_generation`;
125
+ * pi-provider `computeSigPath` 把它泛化成逐 URL 计算,模型列表 GET 的签名照同一规则)。
126
+ */
127
+ export declare function cosySignedPath(url: string): string;
128
+ export interface QoderCosyHeadersOptions {
129
+ /** 已编码的 body(GET 无 body 时为空串)。 */
130
+ encodedBody: string;
131
+ /** 完整请求 URL(签名路径从这里剥)。 */
132
+ url: string;
133
+ /** Accept 头:对话是 `text/event-stream`,模型列表是 `application/json`。 */
134
+ accept: string;
135
+ /** 是否带 `Content-Type: application/json`(有 body 的 POST 才带)。 */
136
+ withContentType: boolean;
137
+ /** 上行模型 key(`X-Model-Key`);空/缺省时连同 `X-Model-Source` 一起省略。 */
138
+ modelKey?: string;
139
+ /** 模型来源(`X-Model-Source`,通常 `system` 或 `custom`)。 */
140
+ modelSource?: string;
141
+ /** 测试缝:时钟(Unix 毫秒)。 */
142
+ now?: number;
143
+ /** 测试缝:runtime fields 的熵(fixture 驱动)。 */
144
+ entropy?: () => Buffer;
145
+ /** 测试缝:request UUID 的熵(fixture 驱动)。缺省与 runtime fields 共用一段。 */
146
+ requestEntropy?: () => Buffer;
147
+ }
148
+ /**
149
+ * 一套完整的 COSY 请求头(条件 presence 逐字 inference-protocol.md §2 的矩阵)。
150
+ *
151
+ * payload 的字段顺序固定(`version, requestId, info, cosyVersion, ideVersion`——
152
+ * 它参与签名,散装键序就是一次签名漂移),所以这里按字面量顺序写键而不是用 Map。
153
+ */
154
+ export declare function buildQoderCosyHeaders(identity: QoderCosyIdentity, options: QoderCosyHeadersOptions): Record<string, string>;
155
+ /** qodercli 的 machine_id 文件路径(本插件**只读**它,理由见 adopt.ts 的文件头)。 */
156
+ export declare function qoderCliMachineIdPath(env?: NodeJS.ProcessEnv): string;
157
+ /** 读取qodercli 原配的 machine id(不存在时 null;只读)。 */
158
+ export declare function readQoderCliMachineId(env?: NodeJS.ProcessEnv): string | null;
159
+ /**
160
+ * 本线路发请求用的 machine id。
161
+ *
162
+ * 读取顺序(逐字 pi-provider `cosy.ts` `getMachineId` 的同一决定):
163
+ *
164
+ * 1. qodercli 的原配 `~/.qoder/.auth/machine_id`(**只读**)——adopt 来的凭据
165
+ * 与它配套,同一个 id 让账号在两边的审计记录里是同一条;
166
+ * 2. 本线路自己持久化的那份(`storages/qoder-machine-id`);
167
+ * 3. 都没有时生成一个并尽力落盘(落不了盘就用内存里的那份——身份在一次
168
+ * 进程内一致即可,持久化失败不值得让请求失败)。
169
+ */
170
+ export declare function resolveQoderMachineId(env?: NodeJS.ProcessEnv): string;
171
+ /** 测试用:清掉进程内记忆。 */
172
+ export declare function clearQoderMachineIdMemo(): void;
173
+ //# sourceMappingURL=cosy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cosy.d.ts","sourceRoot":"","sources":["../../../../src/host/qoder/cosy.ts"],"names":[],"mappings":"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"}