dsh-llm-codebuddy-power 1.0.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 (44) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +66 -0
  3. package/README.zh.md +66 -0
  4. package/cordis.patch.yml +32 -0
  5. package/lib/cli-login.js +2099 -0
  6. package/lib/client.js +2814 -0
  7. package/lib/index.js +3957 -0
  8. package/lib/types/adapter.d.ts +58 -0
  9. package/lib/types/atomic-file.d.ts +43 -0
  10. package/lib/types/auth-service.d.ts +195 -0
  11. package/lib/types/cli/login.d.ts +23 -0
  12. package/lib/types/client/AccountSwitcher.d.ts +53 -0
  13. package/lib/types/client/CodeBuddySection.d.ts +62 -0
  14. package/lib/types/client/ComposerControls.d.ts +29 -0
  15. package/lib/types/client/DrawToolCard.d.ts +24 -0
  16. package/lib/types/client/ModelPanel.d.ts +77 -0
  17. package/lib/types/client/TurnCreditPill.d.ts +33 -0
  18. package/lib/types/client/UsageIndicator.d.ts +21 -0
  19. package/lib/types/client/icons.d.ts +24 -0
  20. package/lib/types/client/index.d.ts +34 -0
  21. package/lib/types/client/locales.d.ts +90 -0
  22. package/lib/types/client/poll.d.ts +19 -0
  23. package/lib/types/client/store.d.ts +59 -0
  24. package/lib/types/client/wire.d.ts +147 -0
  25. package/lib/types/codebuddy.d.ts +187 -0
  26. package/lib/types/constants.d.ts +67 -0
  27. package/lib/types/credit-store.d.ts +25 -0
  28. package/lib/types/image-tool.d.ts +34 -0
  29. package/lib/types/index.d.ts +79 -0
  30. package/lib/types/login.d.ts +43 -0
  31. package/lib/types/model-enrich.d.ts +125 -0
  32. package/lib/types/prefs.d.ts +43 -0
  33. package/lib/types/rpc-route.d.ts +25 -0
  34. package/lib/types/selection.d.ts +35 -0
  35. package/lib/types/serialize.d.ts +37 -0
  36. package/lib/types/session-store.d.ts +63 -0
  37. package/lib/types/session.d.ts +415 -0
  38. package/lib/types/settings.d.ts +18 -0
  39. package/lib/types/sse.d.ts +22 -0
  40. package/lib/types/storage.d.ts +118 -0
  41. package/lib/types/translate.d.ts +61 -0
  42. package/lib/types/types.d.ts +345 -0
  43. package/lib/types/usage.d.ts +109 -0
  44. package/package.json +119 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * DeepSeek Harness 的 Tencent CodeBuddy provider 插件。
3
+ *
4
+ * 在 `ctx.llm` 上注册一条 `codebuddy` 路由,由浏览器 OAuth 登录而非 API key
5
+ * 授权,并提供 CodeBuddy 自己的(非 OpenAI)目录端点所报告的模型。
6
+ *
7
+ * 通过 Web 设置 → CodeBuddy 页面登录,或在终端执行
8
+ * `dsh plugin --profile web codebuddy-power`。无需 API key,运行中的 harness
9
+ * 无需重启即可取得该凭据。
10
+ *
11
+ * @module dsh-llm-codebuddy-power
12
+ */
13
+ import type { Context } from '@deepseek-ai/cordis';
14
+ import type { CodeBuddyConnectionOptions } from './adapter.ts';
15
+ import type { CodeBuddyPrefs, CodeBuddyPrefsConfig } from './prefs.ts';
16
+ export { CodeBuddyAdapter, httpErrorCode } from './adapter.ts';
17
+ export type { CodeBuddyAdapterOptions, CodeBuddyConnectionOptions } from './adapter.ts';
18
+ export { CodeBuddyAuthService, CODEBUDDY_AUTH_CHANNEL } from './auth-service.ts';
19
+ export type { CodeBuddyAccountsResult, CodeBuddyLoginStart, CodeBuddyLoginPoll, CodeBuddySessionAccount, CodeBuddyUsageResult, CodeBuddyUsageWindow, } from './auth-service.ts';
20
+ export { CodeBuddySession, NotLoggedInError } from './session.ts';
21
+ export type { CodeBuddyAccountInfo, TurnCreditAccount, TurnCreditAccountView, TurnCreditRecord, TurnCreditRecordView, } from './session.ts';
22
+ export { login } from './login.ts';
23
+ export type { LoginHooks, LoginResult } from './login.ts';
24
+ export { getStoragePath, loadStorage, removeAccounts, setDefaultAccount, setLastAccount, updateStorage, upsertAccount, } from './storage.ts';
25
+ export type { CodeBuddyStorage, CodeBuddyStoredAccount } from './storage.ts';
26
+ export { loadSessionInfo, updateSessionInfo } from './session-store.ts';
27
+ export type { SessionAccountRef, SessionInfo } from './session-store.ts';
28
+ export { fetchUsage, fetchPersonalUsage, fetchEnterpriseUsage, parseUsage } from './usage.ts';
29
+ export type { UsageSnapshot, UsageWindow } from './usage.ts';
30
+ export * from './constants.ts';
31
+ export { BLOCKED_MODEL_IDS, hasDisclosedCapacity, isBlockedModelId } from './types.ts';
32
+ export type * from './types.ts';
33
+ /** Cordis 插件名。 */
34
+ export declare const name = "llm-codebuddy-power";
35
+ /**
36
+ * 本插件的激活服务。`llm` 承载适配器路由,`tools` 接受文生图工具注册,
37
+ * `agents` 用于极简模式会话中按 agent 限制画图工具可见性。生成图片经
38
+ * 标准附件通道(attachments.saveImage + uiConversation.imageUrl)持久化与
39
+ * 展示,工具注册在附件服务挂载后(`ctx.inject(['attachments'])`)。
40
+ */
41
+ export declare const inject: string[];
42
+ /**
43
+ * 插件配置。每个字段都是可选的:内置默认值直达公开的 CodeBuddy 服务,且按
44
+ * 设计完全没有凭据字段 → 唯一的进入方式是浏览器登录。
45
+ *
46
+ * 界面偏好字段(`CodeBuddyPrefsConfig`)是设置命名空间的 base 层:用户在 Web
47
+ * 设置页的写入存在 harness 的用户设置文档里并覆盖它们。
48
+ */
49
+ export interface Config extends CodeBuddyPrefsConfig {
50
+ /** Chat 端点基址;默认为 CodeBuddy 的 OpenAI 兼容路由。 */
51
+ baseURL?: string;
52
+ /** 目录未给出规模的模型的上下文容量。 */
53
+ defaultContextWindow?: number;
54
+ /** 目录未给出上限的模型的单次请求输出上限。 */
55
+ defaultMaxTokens?: number;
56
+ /** 单次流读取尚未完成时 provider 的最大空闲时间。 */
57
+ streamIdleTimeoutMs?: number;
58
+ }
59
+ /**
60
+ * 校验并补全原始配置。
61
+ *
62
+ * 编程式构造可以绕过任何 schema,因此边界在此判定,坏值在加载时就带字段名
63
+ * 失败,而不是等到请求中途。
64
+ * @param config - 原始入口配置。
65
+ * @returns 解析出的连接事实。
66
+ */
67
+ export declare function resolveConnectionOptions(config?: Config): CodeBuddyConnectionOptions;
68
+ /**
69
+ * 解析界面偏好的部署级 base 层。用户设置文档中的写入覆盖它。
70
+ *
71
+ * 与 {@link resolveConnectionOptions} 同理,编程式构造可以绕过任何 schema,
72
+ * 因此坏值在此判定并在加载时失败。
73
+ * @param config - 原始入口配置。
74
+ * @returns 设置命名空间的 base 值。
75
+ */
76
+ export declare function resolvePrefsBase(config?: Config): CodeBuddyPrefs;
77
+ /** 挂载插件:解析配置,然后注册路由。 */
78
+ export declare function apply(ctx: Context, config?: Config): void;
79
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 浏览器 OAuth 登录流程,从发起到凭据落盘。
3
+ *
4
+ * 全程不索取 API key:握手生成一个 `state`,用户在普通浏览器中
5
+ * 登录,然后依据该 state 从服务轮询取出令牌。用户需要做的
6
+ * 只是在一个登录页面上点击完成。
7
+ *
8
+ * @module dsh-llm-codebuddy-power/login
9
+ */
10
+ import type { Account, AuthToken } from './types.ts';
11
+ import type { CodeBuddyStoredAccount } from './storage.ts';
12
+ /** 一次完成的登录所产生的结果。 */
13
+ export interface LoginResult {
14
+ account: CodeBuddyStoredAccount;
15
+ nickname: string;
16
+ }
17
+ /**
18
+ * 由刚签发的令牌与账号信息构建一个可持久化的账号条目。
19
+ *
20
+ * CLI 流程与 Web 认证服务共用,以免两者在存储结构上
21
+ * 产生分歧:两者写入的都是这个对象。
22
+ * @param token - 浏览器登录完成后签发的令牌。
23
+ * @param account - 令牌所对应的已登录账号。
24
+ * @returns 要持久化的账号条目。
25
+ */
26
+ export declare function buildAccount(token: AuthToken, account: Account): CodeBuddyStoredAccount;
27
+ /** 调用方提供的钩子,用于驱动流程中的用户交互。 */
28
+ export interface LoginHooks {
29
+ /** 以用户必须打开的 URL 调用。 */
30
+ onUrl?: (url: string) => void;
31
+ /** 是否尝试自动打开浏览器。 */
32
+ openBrowser?: boolean;
33
+ }
34
+ /**
35
+ * 运行完整的浏览器登录流程。
36
+ * @param hooks - 用户交互钩子。
37
+ * @param signal - 可选取消。
38
+ * @returns 已追加到账号列表的账号与已登录昵称。
39
+ * @throws Error 握手失败、用户未及时完成,或
40
+ * 账号无法读取时。
41
+ */
42
+ export declare function login(hooks?: LoginHooks, signal?: AbortSignal): Promise<LoginResult>;
43
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1,125 @@
1
+ /**
2
+ * 客户端模型面板的模型增强:推广/等级解析、按模型的覆盖值存储,以及
3
+ * RPC 安全的目录投影。
4
+ *
5
+ * 推广是 CodeBuddy 的定时活动(徽章 + 悬浮提示 + 可选折扣);等级是订阅档位
6
+ * 徽章("订阅优先")。二者都是提示性的展示数据:主机解析展示事实,客户端负责
7
+ * 渲染。覆盖值让用户按模型限制上下文窗口 / 最大输出 token,统一存储在
8
+ * `$DSH_HOME/data/plugins/llm-codebuddy-power/`。
9
+ *
10
+ * @module dsh-llm-codebuddy-power/model-enrich
11
+ */
12
+ import type { CodeBuddyModel, CodeBuddyModelPromotion, CodeBuddyModelTier } from './types.ts';
13
+ /** 按模型的用户覆盖值:仅包含被显式限制的字段。 */
14
+ export interface ModelOverrides {
15
+ /** 覆盖后的上下文容量(token);缺省时取目录值。 */
16
+ contextWindow?: number;
17
+ /** 覆盖后的最大输出 token;缺省时取目录值。 */
18
+ maxOutputTokens?: number;
19
+ }
20
+ /** 覆盖值表:model id → 用户限制。 */
21
+ export type ModelOverrideTable = Record<string, ModelOverrides>;
22
+ /** 加载覆盖值表;文件缺失或损坏时按空表处理(丢失用户限制是安全的)。 */
23
+ export declare function loadOverrides(): Promise<ModelOverrideTable>;
24
+ /** 原子地持久化整张覆盖值表(读-改-写由调用方负责)。 */
25
+ export declare function saveOverrides(table: ModelOverrideTable): Promise<void>;
26
+ /** 面向客户端的单个生效推广的展示事实。 */
27
+ export interface PromotionView {
28
+ /** 徽章标签,例如 "错峰使用"。 */
29
+ label: string;
30
+ /** 徽章底板颜色(十六进制)。 */
31
+ color: string;
32
+ /** 折扣后的积分费率,活动带有该项时才有。 */
33
+ discountedCredits?: string;
34
+ /** "strikethrough" 列出原价与折扣;"replace" 仅显示折扣。 */
35
+ displayMode?: string;
36
+ /** 悬浮提示文案,按语言排列。 */
37
+ textZh?: string;
38
+ textEn?: string;
39
+ /** 提示框按钮动作,存在时才有。 */
40
+ action?: {
41
+ type?: string;
42
+ labelZh?: string;
43
+ labelEn?: string;
44
+ };
45
+ }
46
+ /** 面向客户端的模型等级展示事实。 */
47
+ export interface TierView {
48
+ /** 徽章标签,例如 "订阅优先"。 */
49
+ label: string;
50
+ /** 悬浮提示文案,按语言排列。 */
51
+ textZh?: string;
52
+ textEn?: string;
53
+ /** 提示框按钮动作,存在时才有(升级会打开定价页)。 */
54
+ action?: {
55
+ type?: string;
56
+ labelZh?: string;
57
+ labelEn?: string;
58
+ };
59
+ }
60
+ /**
61
+ * 判断某个推广当前是否生效:已启用、处于绝对有效期内,且声明了每日时段时
62
+ * 落在匹配的每日时段内(考虑时区)。
63
+ * @param promotion - 待判定的推广活动。
64
+ * @param now - 判定时刻,epoch 毫秒。
65
+ * @returns 活动当前生效时为 true。
66
+ */
67
+ export declare function isPromotionActive(promotion: CodeBuddyModelPromotion, now?: number): boolean;
68
+ /**
69
+ * 解析某个模型最终胜出的生效推广:在 `modelIds` 覆盖该模型且当前生效的活动
70
+ * 中,优先级最高者胜出(CodeBuddy 自身的选择规则)。只投影展示事实。
71
+ * @param promotions - 全部推广活动。
72
+ * @param modelId - 待解析的模型。
73
+ * @returns 胜出活动的展示事实,没有时为 undefined。
74
+ */
75
+ export declare function promotionFor(promotions: readonly CodeBuddyModelPromotion[], modelId: string, now?: number): PromotionView | undefined;
76
+ /**
77
+ * 解析挂在某个模型上的等级徽章。
78
+ * @param tiers - 全部模型等级。
79
+ * @param modelId - 待解析的模型。
80
+ * @returns 首个匹配等级的展示事实,没有时为 undefined。
81
+ */
82
+ export declare function tierFor(tiers: readonly CodeBuddyModelTier[] | undefined, modelId: string): TierView | undefined;
83
+ /** 客户端面板中的一行增强模型。 */
84
+ export interface EnrichedModelRow {
85
+ id: string;
86
+ name: string;
87
+ /** 标价积分标签,例如 "x0.79"。 */
88
+ credits?: string;
89
+ /** 胜出的生效推广的展示事实,适用时才有。 */
90
+ promotion?: PromotionView;
91
+ /** 等级徽章,该模型带有等级时才有。 */
92
+ tier?: TierView;
93
+ /** 能力事实。 */
94
+ supportsImages?: boolean;
95
+ supportsReasoning?: boolean;
96
+ supportsToolCall?: boolean;
97
+ /** 目录默认的上下文容量。 */
98
+ contextWindow?: number;
99
+ /** 目录默认的最大输出 token。 */
100
+ maxOutputTokens?: number;
101
+ /**
102
+ * 目录公布的上下文容量上限,不受用户覆写影响。
103
+ *
104
+ * 与 `contextWindow`(生效值)分开下发是必需的:面板既要用生效值显示与起草,
105
+ * 又要用目录值限制可输入的上限。若限制也用生效值,用户把上限调低一次之后,
106
+ * 那个较低的覆写就会成为下一次编辑的上限,再也调不回去。
107
+ */
108
+ contextWindowCap?: number;
109
+ /** 目录公布的最大输出上限;与 `contextWindowCap` 同理。 */
110
+ maxOutputTokensCap?: number;
111
+ /** 各语言的描述。 */
112
+ descriptionZh?: string;
113
+ descriptionEn?: string;
114
+ }
115
+ /**
116
+ * 把目录模型及其推广/等级事实投影为可安全下发给客户端的增强行。
117
+ * 提供 `withOverrides` 时应用按模型的用户限制。
118
+ * @param model - 目录模型。
119
+ * @param promotions - 全部推广活动(按模型逐个解析)。
120
+ * @param tiers - 全部模型等级。
121
+ * @param withOverrides - 按模型的用户限制,没有时为 undefined。
122
+ * @returns 增强后的行。
123
+ */
124
+ export declare function enrichModel(model: CodeBuddyModel, promotions: readonly CodeBuddyModelPromotion[], tiers: readonly CodeBuddyModelTier[] | undefined, withOverrides: ModelOverrides | undefined): EnrichedModelRow;
125
+ //# sourceMappingURL=model-enrich.d.ts.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * CodeBuddy 界面偏好的命名空间契约,Host 与 Client 两面共享。
3
+ *
4
+ * 这些偏好是**插件自己的设置命名空间**里的一段:`Config` 提供部署级 base,
5
+ * 用户在 Web 设置页的写入落在 harness 的用户设置文档里,因此换浏览器、重启
6
+ * harness 后仍然生效 —— 其中「极简模式画图工具」还会被宿主读取来决定
7
+ * `codebuddy-draw` 对模型是否可见,存在浏览器里会让同一次部署因浏览器而异。
8
+ *
9
+ * 本文件必须保持零依赖:两面都会编译它,而 Client 面若因此引入 schemastery
10
+ * 就会把它打进浏览器产物(校验 schema 是宿主面的事,见 `./settings.ts`)。
11
+ *
12
+ * @module dsh-llm-codebuddy-power/prefs
13
+ */
14
+ /** 本插件拥有的设置命名空间,与插件名一致。 */
15
+ export declare const CODEBUDDY_SETTINGS_NAMESPACE = "llm-codebuddy-power";
16
+ /** 告警百分比的下界(含)。 */
17
+ export declare const DANGER_PCT_MIN = 1;
18
+ /** 告警百分比的上界(含)。 */
19
+ export declare const DANGER_PCT_MAX = 100;
20
+ /** 本插件在用户设置文档里持久化的界面偏好。 */
21
+ export interface CodeBuddyPrefs {
22
+ /** 对话输入区是否显示额度圆环。 */
23
+ showUsage: boolean;
24
+ /** 圆环填充变为告警颜色的已用百分比,取值 `DANGER_PCT_MIN`..`DANGER_PCT_MAX`。 */
25
+ dangerPct: number;
26
+ /** 极简模式(agent preset `minimal`)会话是否注入 codebuddy-draw 工具。 */
27
+ drawToolInMinimal: boolean;
28
+ }
29
+ /** 未覆盖任何一层时使用的偏好默认值。 */
30
+ export declare const DEFAULT_CODEBUDDY_SETTINGS: CodeBuddyPrefs;
31
+ /**
32
+ * 插件配置里可覆盖的偏好字段。三者都是部署级默认值,用户设置文档中的写入
33
+ * 覆盖它们。
34
+ */
35
+ export interface CodeBuddyPrefsConfig {
36
+ /** 对话输入区是否显示额度圆环。 */
37
+ showUsage?: boolean;
38
+ /** 圆环填充变为告警颜色的已用百分比。 */
39
+ dangerPct?: number;
40
+ /** 极简模式会话是否注入 codebuddy-draw 工具。 */
41
+ drawToolInMinimal?: boolean;
42
+ }
43
+ //# sourceMappingURL=prefs.d.ts.map
@@ -0,0 +1,25 @@
1
+ /**
2
+ * 本插件私有浏览器 RPC 通道的物理 HTTP 路由持有者。
3
+ *
4
+ * `connection.rpc.handle()` 无法在功能插件中使用:它在 Connection 服务自身的
5
+ * Context 下注册路由,而该 Context 的 fiber 从未声明 `webServer`,因此注册会抛出
6
+ * `cannot get property "webServer" without inject`,通道永远无法挂载,浏览器调用
7
+ * 随后落到 SPA 回退(HTTP 405)。本模块改为在同时声明这两个服务的 inject fork 中,
8
+ * 把前缀路由直接注册到 `webServer` 上,复现 Connection 桥本应提供的同一传输契约:
9
+ * 先做浏览器认证,然后接收 JSON `client-request` 信封、返回 `server-response` 信封。
10
+ *
11
+ * @module dsh-llm-codebuddy-power/rpc-route
12
+ */
13
+ import type { Context } from '@deepseek-ai/cordis';
14
+ import type { ConnectionRpcHandler } from '@deepseek-ai/dsh-client-connection';
15
+ /**
16
+ * 把一个私有 RPC 通道挂载为 Web 前缀路由。
17
+ *
18
+ * 该路由由下方的 inject fork 持有,因此卸载本插件的 fiber 时会将其移除。
19
+ * 不含 `webServer` 的 profile(headless)不会解析出该 fork,也就不会挂载路由。
20
+ * @param ctx - 插件自身的 Context,用于创建持有路由的 inject fork。
21
+ * @param channel - 绝对通道前缀,例如 `/codebuddy`。
22
+ * @param handler - 已解码的 endpoint 处理器,返回 RPC 结果信封。
23
+ */
24
+ export declare function mountPrivateChannel(ctx: Context, channel: string, handler: ConnectionRpcHandler): void;
25
+ //# sourceMappingURL=rpc-route.d.ts.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 每个会话选用的账号,以及“最后一次手动切换”的账号。
3
+ *
4
+ * 单独放在 `codebuddy-selection.json`,而不是并进凭据文件:凭据文件有两个写者
5
+ * (运行中的 harness 与 CLI),会话选择只有 harness 写,分开后两边不会各自基于
6
+ * 旧内容覆盖对方。文件里的 uid 指向已退出的账号时按“没有选择”处理 —— 兜底放在
7
+ * 读取侧,磁盘记录因此只增不删(与每轮积分一致);同一个 uid 账号日后重新登录
8
+ * 时,原来的选择会重新生效。
9
+ *
10
+ * @module dsh-llm-codebuddy-power/selection
11
+ */
12
+ /** 会话选择文件的内容。 */
13
+ export interface CodeBuddySelection {
14
+ /** 会话 id → 该会话显式选用的账号 uid。 */
15
+ sessions: Record<string, string>;
16
+ /** 最后一次被手动切换到的账号 uid;没有默认账号时作为兜底。 */
17
+ lastUid?: string;
18
+ }
19
+ /**
20
+ * 读取会话选择;文件缺失或损坏时按空内容处理。
21
+ * @returns 会话选择;没有任何选择时 `sessions` 为空对象。
22
+ */
23
+ export declare function loadSelection(): Promise<CodeBuddySelection>;
24
+ /**
25
+ * 记下一个会话选用的账号,并把它记为最后一次手动切换的账号。
26
+ * @param sessionId - dsh 会话 id。
27
+ * @param uid - 该会话要使用的账号 uid。
28
+ */
29
+ export declare function selectAccount(sessionId: string, uid: string): Promise<void>;
30
+ /**
31
+ * 选择文件的不透明新鲜度令牌,与 {@link storageFreshness} 同形。
32
+ * @returns 一个令牌;文件不存在时返回 `undefined`。
33
+ */
34
+ export declare function selectionFreshness(): Promise<string | undefined>;
35
+ //# sourceMappingURL=selection.d.ts.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * 把 harness 消息序列化为 CodeBuddy(OpenAI 兼容)chat 请求。
3
+ *
4
+ * 用户文本被拼接,助手文本成为 `content`,工具调用成为
5
+ * `tool_calls`,每个工具结果成为其自身的 `role: 'tool'` 消息 →
6
+ * harness 把工具结果放在用户消息内部,而这条 wire 路由
7
+ * 不接受这种形式。对于支持图像的模型,图像以 OpenAI 兼容的
8
+ * `image_url` 部件(`data:<type>;base64,...`)出现在用户或工具 content
9
+ * 数组中,与官方 CLI 的发送方式完全一致。工具结果的图只对 `read_image`
10
+ * 这类"看图"工具发送,生成图工具的结果仍走纯文本信封。
11
+ *
12
+ * @module dsh-llm-codebuddy-power/serialize
13
+ */
14
+ import type { GenerateOptions, Message } from '@deepseek-ai/dsh-llm';
15
+ import type { RequestImageAttachment } from '@deepseek-ai/dsh-attachment';
16
+ import type { WireMessage, WireRequest } from './types.ts';
17
+ /** 请求中每个图像已解析的请求版本,以 attachment id 为键。 */
18
+ export type RequestImages = ReadonlyMap<RequestImageAttachment['attachment']['attachmentId'], RequestImageAttachment>;
19
+ /**
20
+ * 按顺序序列化整个对话。
21
+ * @param messages - harness 会话。
22
+ * @param supportsImages - 所选模型是否声明支持图像输入。
23
+ * @param images - 请求中每个图像已解析的请求版本。
24
+ * @returns wire 消息,每个工具结果展开为独立条目。
25
+ */
26
+ export declare function serializeMessages(messages: readonly Message[], supportsImages: boolean, images?: RequestImages): WireMessage[];
27
+ /**
28
+ * 构建 chat-completions 请求体。始终流式并上报 usage;
29
+ * 缺省的选项被省略而非以 null 发送,以便应用
30
+ * 提供方自身的默认值。
31
+ * @param options - 组装好的 harness 请求。
32
+ * @param supportsImages - 所选模型是否声明支持图像输入。
33
+ * @param images - 请求中每个图像已解析的请求版本。
34
+ * @returns 请求体。
35
+ */
36
+ export declare function serializeRequest(options: GenerateOptions, supportsImages: boolean, images?: RequestImages): WireRequest;
37
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1,63 @@
1
+ /**
2
+ * 插件自有的会话信息持久化:按会话一个文件,存该会话选用的账号、用过的账号表与
3
+ * 每轮消耗的积分。
4
+ *
5
+ * 这三件事都是"这个会话自己的事实",因此放在同一个文件里
6
+ * (`$DSH_HOME/data/plugins/llm-codebuddy-power/sessions/<会话id>.json`):读一次
7
+ * 就拿到它们,也不会出现两份记录各自指向不同账号。文件是纯增量记录 —— 缺文件等价于
8
+ * "没选过账号、没有积分"。写入是读-改-写的原子替换,并经 [atomic-file.ts](./atomic-file.ts)
9
+ * 按路径串行化:一轮里画图与聊天会各自累加一次积分,分开读-改-写会丢掉其中一次。
10
+ *
11
+ * 文件只增不删:会话被销毁(一次性子代理跑完即如此)不等于用户删除了会话。
12
+ *
13
+ * **账号在表里存一次,每轮记录只引用它的序号**:同一个账号会在几十轮里反复出现,逐轮
14
+ * 内联昵称是同一份事实的重复副本 —— 实测这让文件大了近一倍。键是文件内部自己编的序号
15
+ * 而不是 uid 的任何截断:一个只在本文件里做引用的键不必携带 uid 的信息,截断反而会
16
+ * 让两个同前缀的账号共用一条记录(把历史轮次张冠李戴),而序号不可能重复。
17
+ *
18
+ * 排版也在这里决定:`credits` 每条一行、`accounts` 每条一行,其余保持缩进。逐条一行
19
+ * 让追加一轮只改动两行,而整个文件一行虽然更小,却让文件不可读、改动无法辨别。
20
+ *
21
+ * @module dsh-llm-codebuddy-power/session-store
22
+ */
23
+ import type { TurnCreditRecord } from './session.ts';
24
+ /** 账号表里一个账号的两个事实:完整 uid 与昵称。 */
25
+ export interface SessionAccountRef {
26
+ uid: string;
27
+ nick: string;
28
+ }
29
+ /** 一个会话的持久化信息。 */
30
+ export interface SessionInfo {
31
+ /** 该会话选用的账号 uid;未选用时缺省,按默认账号解析。 */
32
+ uid?: string;
33
+ /** 本会话用过的账号,以文件内部序号为键;每轮记录里的账号引用指向这里。 */
34
+ accounts: Record<string, SessionAccountRef>;
35
+ /** 每轮消耗的积分,按轮次号索引。 */
36
+ credits: Record<string, TurnCreditRecord>;
37
+ }
38
+ /**
39
+ * 账号在账号表里的序号。
40
+ *
41
+ * 序号从 0 起、按首次用到该账号的顺序分配,并保留在表里 —— 记录引用的是序号,因此
42
+ * 序号不能随表内增删而改变,否则已有轮次会指向别的账号。
43
+ * @param table - 当前的账号表。
44
+ * @param uid - 要引用的账号 uid。
45
+ * @returns 该账号的序号;从未用过时是下一个未占用的序号。
46
+ */
47
+ export declare function accountKeyFor(table: Record<string, SessionAccountRef>, uid: string): string;
48
+ /**
49
+ * 读取一个会话的信息。
50
+ * @param sessionId - dsh 会话 id。
51
+ * @returns 该会话选用的账号、用过的账号表与积分记录;缺文件或损坏时返回空信息。
52
+ */
53
+ export declare function loadSessionInfo(sessionId: string): Promise<SessionInfo>;
54
+ /**
55
+ * 读-改-写一个会话的信息(原子替换,文件不存在则新建)。
56
+ *
57
+ * 读发生在队列内部,因此排队中的后一次改动看得到前一次的结果,而不是各自基于同一份
58
+ * 旧内容。文件此刻不可读时按空信息起手,与 {@link loadSessionInfo} 对同一情况的判断一致。
59
+ * @param sessionId - dsh 会话 id。
60
+ * @param change - 由当前信息算出新信息;不得就地修改传入值。
61
+ */
62
+ export declare function updateSessionInfo(sessionId: string, change: (current: SessionInfo) => SessionInfo): Promise<void>;
63
+ //# sourceMappingURL=session-store.d.ts.map