hiwork-core 0.0.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.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * hero 问候语轮换(每日卡片的同页组件,自 hiwork-dsh-ui 静态版演化):
3
+ * 官方口号「探索未至之境 / Into the Unknown」替换为「HiWork,+ 候选池随机一条」,
4
+ * 前缀固定保留,候选每次进入 hero 页时随机切换(排除上一条,不重复);
5
+ * 同时隐藏鱼形品牌标记与「预览版」徽标。
6
+ *
7
+ * 实现:宿主 headlineText 用 CSS 归零隐藏,问候语是插件自有(data-hiwork-hero-greeting
8
+ * 标记)的相邻 span,由观察器幂等插入——不搬移/不改写宿主节点,宿主重建 hero 时自动
9
+ * 重挂并换下一条,非 hero 阶段自动清残留。样式 id 改用 hiwork 前缀:本模块已是
10
+ * dsh-ui 静态 ::after 版的超集,两版并存会双份文案。
11
+ */
12
+ /** 问候候选池(前缀 HiWork,之后的部分),措辞逐字保留产品定稿。 */
13
+ export declare const HERO_GREETINGS: readonly string[];
14
+ /** 固定前缀:所有候选共用,轮换的只是后半句。 */
15
+ export declare const HERO_GREETING_PREFIX = "HiWork\uFF0C";
16
+ export declare const HERO_STYLE_ID = "hiwork-conversation-hero-style";
17
+ export declare const HERO_STYLE = "\n[class*=\"_fishHitbox\"],\n[class*=\"_previewBadge\"]{display:none}\n[class*=\"_headline\"]:not([class*=\"_headlineText\"]){display:flex;justify-content:center;align-items:center;column-gap:0}\n[class*=\"_headlineText\"]{font-size:0}\n[data-hiwork-hero-greeting]{font-size:26px;line-height:32px;font-weight:500}\n";
18
+ export declare function ensureHeroStyle(doc?: Document): void;
19
+ /** 随机取一条候选;命中上一条时顺移一位,保证连续两次不重复。 */
20
+ export declare function pickHeroGreeting(): string;
21
+ /**
22
+ * 幂等装饰:hero / headlineText 缺失 → 只清残留;问候 span 已紧邻 headlineText →
23
+ * 不动(观察循环不得反复重掷);否则清掉旧 span 后在 headlineText 之后插入新随机一条。
24
+ */
25
+ export declare function decorateHeroGreeting(doc: Document): void;
26
+ /** 清理非 hero / 槽位变化后残留的问候节点。 */
27
+ export declare function removeStaleHeroGreeting(doc: Document): void;
@@ -0,0 +1,5 @@
1
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
+ /** 浏览器插件契约(dsh client module system)。connection 随 IApiClient 移除后不再依赖。 */
3
+ export declare const inject: string[];
4
+ /** 挂载网关模型设置 section(一级 tab)与未登录弹窗。 */
5
+ export declare function apply(ctx: ClientContext): void;
@@ -0,0 +1,13 @@
1
+ import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
2
+ import type { CredentialStorePort } from './controller.ts';
3
+ import { type AiRouterCardSettings } from './controller.ts';
4
+ export declare function loginGateVisible(snapshot: {
5
+ status: string;
6
+ value?: {
7
+ lastLogin?: unknown;
8
+ lastError?: {
9
+ code?: string;
10
+ };
11
+ } | undefined;
12
+ } | undefined): boolean;
13
+ export declare function mountLoginGate(scope: SettingsScope<AiRouterCardSettings>, storeCredential: CredentialStorePort): () => void;
@@ -0,0 +1,6 @@
1
+ /** HiWork 品牌资产(与 hiwork-dsh-ui 同源):方标 / 词标 / 横版组合标(登录页用)。 */
2
+ export declare const HIWORK_LOGO: string;
3
+ export declare const HIWORK_LOGO_TEXT: string;
4
+ export declare const HIWORK_LOGO_WITH_TEXT: string;
5
+ /** HiWork 产品版本:品牌展示元素,与 hiwork-dsh-ui 的 HIWORK_VERSION 保持一致。 */
6
+ export declare const HIWORK_VERSION = "1.0.2";
@@ -0,0 +1,9 @@
1
+ import type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import { type AiRouterCardFace } from './controller.ts';
3
+ /**
4
+ * 设置页一级 section(tab):网关模型 —— 与「通用设置」同级的独立页面,
5
+ * 展示网关下发的模型额度与虚拟 KEY;未登录时由登录门禁接管,本 section 不渲染。
6
+ */
7
+ export type AiRouterSectionProps = PropsRuntime<'settings.section'> & InjectFace<AiRouterCardFace>;
8
+ /** 网关模型设置 section。 */
9
+ export declare function AiRouterSection(props: AiRouterSectionProps): import("react").JSX.Element | null;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 设置导航「关于」分区图标:官方设置壳只给少数自带分区画专用图标,自定义分区
3
+ * 回退齿轮。这里按导航可见文案把「关于」的图标换成官方问号圆环(路径取自
4
+ * ui-primitives 的 IconQuestionOutline14,与官方图标同源),机制与 hiwork-dsh-ui
5
+ * 的 settings-nav-icons 同款:MutationObserver + rAF 按帧合并,data 标记幂等。
6
+ */
7
+ export declare const ABOUT_NAV_ICON_ID = "hiwork-about-nav";
8
+ export declare const ABOUT_NAV_ICON_PATHS = "<path fill=\"currentColor\" d=\"M12.5757 7.00012C12.5757 3.92085 10.0794 1.42463 7.00012 1.42456C3.9208 1.42456 1.42456 3.9208 1.42456 7.00012C1.42463 10.0794 3.92085 12.5757 7.00012 12.5757C10.0793 12.5756 12.5756 10.0793 12.5757 7.00012ZM13.8002 7.00012C13.8001 10.7559 10.7559 13.8001 7.00012 13.8002C3.2443 13.8002 0.199291 10.7559 0.199219 7.00012C0.199219 3.24426 3.24426 0.199219 7.00012 0.199219C10.7559 0.199291 13.8002 3.2443 13.8002 7.00012Z\"/><path fill=\"currentColor\" d=\"M6.18042 8.68184C6.18043 8.09153 6.32893 7.34655 6.92127 6.8481C7.28566 6.54148 7.76104 6.27318 8.0022 6.10811C8.28964 5.91137 8.42234 5.76562 8.48328 5.58944C8.57774 5.31609 8.53121 5.00904 8.34912 4.76741C8.17409 4.53522 7.83879 4.32222 7.28186 4.32222C5.99668 4.32225 5.46969 5.11832 5.46949 5.78939H4.24414C4.24436 4.39942 5.36327 3.09691 7.28186 3.09688C8.17773 3.09688 8.89489 3.45606 9.32752 4.02999C9.75287 4.59438 9.86938 5.32775 9.64026 5.99019C9.44847 6.5444 9.04722 6.87743 8.69434 7.11898C8.29506 7.39226 8.02318 7.52192 7.70996 7.78548C7.51943 7.94582 7.40577 8.24899 7.40577 8.68184V8.75533H6.18042V8.68184Z\"/><path fill=\"currentColor\" d=\"M7.39455 9.44026V10.8109H6.16921V9.44026H7.39455Z\"/>";
9
+ /** 给「关于」导航钮换官方问号圆环图标;已打标(幂等)或无 svg 时不动。 */
10
+ export declare function applyAboutNavIcon(button: HTMLButtonElement): boolean;
11
+ export declare function applyAboutNavIcons(root: ParentNode): number;
12
+ /** 观察设置导航,宿主重渲染重建按钮后自动补换图标;返回卸载清理函数。 */
13
+ export declare function observeAboutNavIcon(doc?: Document): () => void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * DSH 设置壳暂未提供按 section id 打开的公开 API。该兼容层移植自 hiwork-dsh-ui,
3
+ * 从本插件渲染的设置入口触发:先打开设置弹窗,再按壳的可访问名称选择分区页;
4
+ * 宿主升级时可集中替换。
5
+ */
6
+ export declare function pickSettingsSectionButton<T extends {
7
+ textContent: string | null;
8
+ }>(buttons: readonly T[], labels: readonly string[]): T | undefined;
9
+ /** 取消在途跳转(测试隔离用;生产生命周期里看门狗超时自会清理)。 */
10
+ export declare function resetSettingsNavigationForTests(): void;
11
+ export declare function openSettingsSection(root: HTMLElement | null, label: string | readonly string[], onMissing?: () => void): void;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * hiwork-core client 共享样式:全面跟随 dsh 主题 token(--dsw-alias-*、--dsw-static-*)。
3
+ * 亮色/暗色(body[data-ds-dark-theme])由 dsh 在 body 上定义的两套 CSS 变量自动切换,
4
+ * 因此这里全部走变量引用 + 浏览器降级 fallback,插件无需感知主题状态。
5
+ *
6
+ * 内联样式无法表达 :hover/:focus,主/次按钮以实心/描边区分视觉层级;
7
+ * 输入框聚焦态、按钮 hover、placeholder 由 interactionCss 的数据属性选择器补充
8
+ *(client 入口 apply() 时注入一次,见 index.ts)。
9
+ */
10
+ import type { CSSProperties } from 'react';
11
+ /** DSH 品牌蓝:业务主色(亮色 deepseek-500 #4176e6 / 暗色 deepseek-400 #679efe)。 */
12
+ export declare const brandAccent = "var(--dsw-alias-state-business-primary, #4176e6)";
13
+ /** 主按钮填充:dsh 原生主按钮 = brand-primary(亮色近黑 #0f1115 / 暗色近白 #f9fafb)。 */
14
+ export declare const primaryFill = "var(--dsw-alias-button-primary-fill, #0f1115)";
15
+ /** 主按钮 hover 填充(由 interactionCss 应用)。 */
16
+ export declare const primaryHover = "var(--dsw-alias-button-primary-hover, #43454a)";
17
+ /** 主按钮文字:inverted 层级(亮色白 / 暗色深,与主按钮填充相反)。 */
18
+ export declare const onPrimary = "var(--dsw-alias-label-primary-inverted, #ffffff)";
19
+ export declare const textPrimary = "var(--dsw-alias-label-primary, #0f1115)";
20
+ export declare const textSecondary = "var(--dsw-alias-label-secondary, #61666b)";
21
+ export declare const textTertiary = "var(--dsw-alias-label-tertiary, #81858c)";
22
+ export declare const textCaption = "var(--dsw-alias-label-caption, #adb2b8)";
23
+ export declare const borderL2 = "var(--dsw-alias-border-l2, rgba(15,17,21,0.1))";
24
+ export declare const bgLayer1 = "var(--dsw-alias-bg-layer-1, #ffffff)";
25
+ export declare const bgLayer2 = "var(--dsw-alias-bg-layer-2, #f1f3f5)";
26
+ /** dsh 登录输入框专用底(亮色 bluish-50 / 暗色 bluish-900),兼顾一般表单输入。 */
27
+ export declare const inputFill = "var(--dsw-specific-login-input, var(--dsw-alias-bg-layer-2, #f1f3f5))";
28
+ export declare const interactiveHover = "var(--dsw-alias-interactive-bg-hover, rgba(15,17,21,0.06))";
29
+ export declare const errorText = "var(--dsw-alias-state-error-primary, #ec1313)";
30
+ export declare const warnText = "var(--dsw-alias-state-warn-label, #dd8629)";
31
+ export declare const warnFill = "var(--dsw-alias-state-warn-tertiary, #fef5e7)";
32
+ /** 主按钮(登录)。数据属性 data-hiwork-core-primary 挂 hover。 */
33
+ export declare const primaryButton: CSSProperties;
34
+ /** 次按钮(刷新/退出/暂不登录/我已分配 KEY):透明描边 ghost 风格。 */
35
+ export declare const secondaryButton: CSSProperties;
36
+ /** 禁用态(叠加到主/次按钮样式上)。 */
37
+ export declare const disabledButton: CSSProperties;
38
+ /** 文本输入框:dsh 登录输入框底 + 描边,聚焦光晕由 interactionCss 提供。 */
39
+ export declare const textInput: CSSProperties;
40
+ /**
41
+ * 主框架外观(对齐 Codex/WorkBuddy):
42
+ * - 框架底色改侧栏灰,内容区仅左上角圆角(16px),缺口露出侧栏色;
43
+ * 其余三角直角、贴边不悬浮——与 Codex/WorkBuddy 桌面端一致。
44
+ * - 不再画任何分隔描边/边框线,层次靠背景色差区分。
45
+ * - 左上角圆角仅 Windows 生效:宿主 preload(dsh-view-preload.cts)在 <html> 注入
46
+ * data-dsh-shell=process.platform;Windows 顶栏与侧栏同色,圆角呼应顶栏,
47
+ * 其余平台(含无该属性的纯浏览器预览)默认关闭,回到直角。
48
+ * 内容区根节点类名是 CSS module 哈希前缀(如 wSkVaW_root),语义后缀稳定;
49
+ * 用直接子链 `[class*="_centerCol"] > div > [class*="_root"]` 恰好命中会话区
50
+ * 根节点(实测唯一),避免误伤内容区里 10 个嵌套组件的 _root。
51
+ * 圆角裁切天然成立:会话区根节点自带 overflow:hidden,头部页签/气泡/输入框
52
+ * 都会被裁切;颜色全部走主题变量,亮暗自动切换。
53
+ * 侧栏右缘 0.5px 原生分界线一并归零(与内容区无边框保持一致)。
54
+ */
55
+ export declare const frameCss: string;
56
+ /**
57
+ * 隐藏宿主动作入口:
58
+ * - 会话头部右上角「Session 日志」下载按钮(产品要求不暴露会话日志导出);
59
+ * - 侧栏底部官方「设置」触发钮:账号行(sidebar.footer.action)自带设置入口。
60
+ * 注意官方设置弹窗面板 portal 在 settingsArea 容器内部渲染,只能隐藏触发钮
61
+ * 本身(settingsArea 整区 display:none 会连弹窗一起藏掉);触发钮留在 DOM 里
62
+ * 供 openSettingsSection 程序化点击(display:none 不影响 .click() 派发,
63
+ * dsh-ui 同款做法),弹窗照常打开。
64
+ * 均按 CSS module 语义后缀命中(hash 前缀无关;运行版实测
65
+ * nL4_yW_sessionLogButton / hHd-Xa_settingsArea)。display:none 同时移出
66
+ * 无障碍树与 Tab 焦点链。后续要隐藏其他宿主入口,规则追加到这里。
67
+ */
68
+ export declare const hostHideCss: string;
69
+ /**
70
+ * 品牌区样式:词标资产只有深色版,暗色主题下整体反白(纯色 logo 反转无损;
71
+ * body[data-ds-dark-theme] 为 dsh 暗色选择器,与 hiwork-dsh-ui 同款)。
72
+ * 由 client 入口 apply() 与 interactionCss 一起注入一次(见 index.ts)。
73
+ */
74
+ export declare const brandCss: string;
75
+ /**
76
+ * 补充交互样式:挂在 input/button 的 data 属性上,跟随主题变量。
77
+ * 由 client 入口 apply() 注入一次(带 id 防重)。
78
+ */
79
+ export declare const interactionCss: string;
@@ -0,0 +1,7 @@
1
+ /** 稳定错误码,供 settings card 分支渲染。 */
2
+ export type LoginErrorCode = 'AUTH_FAILED' | 'RATE_LIMITED' | 'GATEWAY_UNREACHABLE' | 'NO_KEY_ASSIGNED' | 'SESSION_EXPIRED' | 'KEY_DISABLED' | 'KEY_INVALID';
3
+ /** 一个稳定的、可安全展示的登录/刷新错误。 */
4
+ export interface LoginError {
5
+ code: LoginErrorCode;
6
+ message: string;
7
+ }
@@ -0,0 +1,14 @@
1
+ import type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
2
+ import { type AiRouterCardFace } from './controller.ts';
3
+ /**
4
+ * 侧边栏底部「设置」上方的账号信息行:显示当前登录网关的显示名(网关 LDAP
5
+ * 中文名,缺省回退登录账号)。「头像 + 用户名」是一个合并钮,hover 高亮与点击
6
+ * 直达设置弹窗「网关模型」分区覆盖整块(避免只点头像无响应);行尾紧跟「设置」
7
+ * 「退出账号」两个独立图标钮(退出带二次确认)。
8
+ * 宽侧栏(wide)显示头像 + 用户名 + 图标钮;窄栏(rail)只显示头像,头像本身即
9
+ * 设置入口。行几何(高度/留白/字号/图标尺寸)与 ui-settings-general 的设置触发
10
+ * 行完全一致。
11
+ */
12
+ export type UserBadgeProps = PropsRuntime<'sidebar.footer.action'> & InjectFace<AiRouterCardFace>;
13
+ /** 底部账号信息行。 */
14
+ export declare function UserBadge(props: UserBadgeProps): import("react").JSX.Element | null;
@@ -0,0 +1,6 @@
1
+ import type { WorkspaceRegistry } from '@deepseek-ai/dsh-workspace';
2
+ export declare const DEFAULT_WORKSPACE_DIR: string;
3
+ export declare const DEFAULT_WORKSPACE_TITLE = "\u9ED8\u8BA4\u5DE5\u4F5C\u533A";
4
+ /** 结构化最小契约:单测 stub 不必实现整个 WorkspaceRegistry。 */
5
+ export type WorkspaceRegistryPort = Pick<WorkspaceRegistry, 'list' | 'create'>;
6
+ export declare function ensureDefaultWorkspace(registry: WorkspaceRegistryPort, warn: (message: string) => void, dir?: string): Promise<void>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * hiwork-core:企业 ai-router 网关登录 + 模型自动加载插件(Host 半边)。
3
+ * 注册 `ai-router` settings 命名空间;卡片写入的请求字段(pendingLogin /
4
+ * refreshRequest / logoutRequest)经 settings.installSection 的 onChange 触发
5
+ * 编排,编排结果回写该命名空间的状态字段(lastLogin / lastError)。
6
+ */
7
+ import type { Context } from '@deepseek-ai/cordis';
8
+ import z from '@deepseek-ai/schemastery';
9
+ export declare const name = "hiwork-core";
10
+ export declare const inject: string[];
11
+ /** 插件配置 + 运行时状态字段(全部可选;写操作按此 schema 校验)。 */
12
+ export interface Config {
13
+ baseURL?: string;
14
+ keyId?: string;
15
+ username?: string;
16
+ displayName?: string;
17
+ lastLogin?: {
18
+ at: string;
19
+ modelCount: number;
20
+ gatewayName: string;
21
+ };
22
+ lastError?: {
23
+ code: string;
24
+ message: string;
25
+ };
26
+ pendingLogin?: {
27
+ username: string;
28
+ passwordRef: string;
29
+ };
30
+ rememberPassword?: boolean;
31
+ refreshRequest?: {
32
+ at: string;
33
+ };
34
+ logoutRequest?: {
35
+ at: string;
36
+ };
37
+ budgets?: Array<{
38
+ model_name: string;
39
+ total_budget?: number | null;
40
+ consumed_budget?: number | null;
41
+ remaining_budget?: number | null;
42
+ }>;
43
+ keys?: Array<{
44
+ id: string;
45
+ employee_name?: string;
46
+ team_name?: string;
47
+ enabled?: boolean;
48
+ max_concurrency?: number;
49
+ key_masked?: string;
50
+ }>;
51
+ }
52
+ export declare const Config: z<Config>;
53
+ export declare function apply(ctx: Context, config: Config): void;
@@ -0,0 +1,91 @@
1
+ import { type GatewayBudget, type GatewayClient, type GatewayKey } from './ai-router-client.ts';
2
+ import type { LoginError } from './types.ts';
3
+ /** 凭据端口:对 ctx.credentials 的抽象,便于测试。 */
4
+ export interface CredentialsPort {
5
+ resolve(ref: string): Promise<{
6
+ value: string;
7
+ } | undefined>;
8
+ set(ref: string, value: string): Promise<void>;
9
+ unset(ref: string): Promise<void>;
10
+ }
11
+ /** pi-ai 配置端口:写/清协议路由集合(多路由按协议拆分)。 */
12
+ export interface PiAiPort {
13
+ applyAiRouterProfiles(profiles: Record<string, Record<string, unknown>> | null): Promise<void>;
14
+ }
15
+ /** 对 ai-router 状态段的一次补丁。 */
16
+ export interface AiRouterStatePatch {
17
+ set?: Record<string, unknown>;
18
+ unset?: readonly string[];
19
+ }
20
+ /** ai-router 状态端口:Host 的唯一写者。 */
21
+ export interface AiRouterStatePort {
22
+ patch(patch: AiRouterStatePatch): Promise<void>;
23
+ }
24
+ /** ai-router 命名空间解析后的值(相关字段)。 */
25
+ export interface AiRouterNamespaceValue {
26
+ baseURL?: string;
27
+ keyId?: string;
28
+ username?: string;
29
+ /** 登录账号的显示名(网关 LDAP displayName,如中文名);缺省时 UI 回退 username。 */
30
+ displayName?: string;
31
+ pendingLogin?: {
32
+ username: string;
33
+ passwordRef: string;
34
+ };
35
+ rememberPassword?: boolean;
36
+ refreshRequest?: {
37
+ at?: string;
38
+ };
39
+ logoutRequest?: {
40
+ at?: string;
41
+ };
42
+ /** 最近一次拉取到的各模型额度(登录/刷新时写入)。 */
43
+ budgets?: readonly GatewayBudget[];
44
+ /** 最近一次拉取到的当前用户全部虚拟 Key(多 Key 选择器数据源)。 */
45
+ keys?: readonly GatewayKey[];
46
+ }
47
+ /**
48
+ * 归一化 budgets:过滤空模型名与已下架模型(model_status === 'inactive',已不可调用,
49
+ * 不进入额度展示),保留额度字段。状态缺省(旧网关)视同 active,正常保留。
50
+ */
51
+ export declare function computeBudgets(budgets: readonly GatewayBudget[]): GatewayBudget[];
52
+ /** 归一化 keys:过滤无 id 项,只保留选择器需要的字段。 */
53
+ export declare function computeKeys(keys: readonly GatewayKey[]): GatewayKey[];
54
+ /** 任意抛错 → 稳定 LoginError;GatewayError 原样,其余归为 GATEWAY_UNREACHABLE。 */
55
+ export declare function toLoginError(error: unknown, fallback: string): LoginError;
56
+ /** 执行一次登录:拉 Key + budgets → 写凭据 → 写 pi-ai 配置 → 写状态。 */
57
+ export declare function runLogin(opts: {
58
+ gateway: GatewayClient;
59
+ credentials: CredentialsPort;
60
+ piAi: PiAiPort;
61
+ state: AiRouterStatePort;
62
+ /** 登录成功尾部触发(默认工作区 ensure 等);可选以便既有测试直接构造 opts。 */
63
+ ensureWorkspace?: () => Promise<void>;
64
+ value: AiRouterNamespaceValue;
65
+ }): Promise<LoginError | null>;
66
+ /** 用已存会话刷新模型列表。 */
67
+ export declare function runRefresh(opts: {
68
+ gateway: GatewayClient;
69
+ credentials: CredentialsPort;
70
+ piAi: PiAiPort;
71
+ state: AiRouterStatePort;
72
+ /** 透传给重登路径 runLogin 的可选端口。 */
73
+ ensureWorkspace?: () => Promise<void>;
74
+ value: AiRouterNamespaceValue;
75
+ }): Promise<LoginError | null>;
76
+ /** 退出登录:best-effort 登出 + 清凭据与 pi-ai 配置。 */
77
+ export declare function runLogout(opts: {
78
+ gateway: GatewayClient;
79
+ credentials: CredentialsPort;
80
+ piAi: PiAiPort;
81
+ state: AiRouterStatePort;
82
+ }): Promise<void>;
83
+ /** 分发一次 ai-router 命名空间变更:三个请求字段至多存在一个。 */
84
+ export declare function handleAiRouterSectionChange(opts: {
85
+ gateway: GatewayClient;
86
+ credentials: CredentialsPort;
87
+ piAi: PiAiPort;
88
+ state: AiRouterStatePort;
89
+ ensureWorkspace?: () => Promise<void>;
90
+ value: AiRouterNamespaceValue;
91
+ }): Promise<LoginError | null>;
@@ -0,0 +1,84 @@
1
+ import type { GatewayModelMapping } from './ai-router-client.ts';
2
+ /** ai-router 路由的凭据 ref 名(dsh Models 页 deriveKeyRef 惯例)。 */
3
+ export declare const API_KEY_REF = "AI_ROUTER_API_KEY";
4
+ /** 网关会话 cookie 的凭据 ref 名。 */
5
+ export declare const SESSION_REF = "AI_ROUTER_SESSION";
6
+ /** 登录中的临时密码 ref 名(用完即清)。 */
7
+ export declare const PENDING_PASSWORD_REF = "AI_ROUTER_PENDING_PASSWORD";
8
+ /** 勾选“记住密码”后保存的凭据 ref(由 credentials provider 加密存储)。 */
9
+ export declare const REMEMBERED_PASSWORD_REF = "AI_ROUTER_REMEMBERED_PASSWORD";
10
+ /**
11
+ * 注册到 llm-pi-ai 的协议路由表:路由名 → pi-ai 协议。
12
+ * 网关按「入站协议 + 模型」匹配模型映射(internal/service/provider_service.go),
13
+ * 而 pi-ai 的 `api` 是路由级的 —— 因此每个协议一条路由,模型按映射归属到对应路由,
14
+ * 切模型时 dsh 自动落到讲该协议的路由,协议随模型走。
15
+ * 主路由固定用 Responses 协议(/v1/responses),OpenAI 兼容模型统一落到它。
16
+ */
17
+ export declare const PROVIDER_ROUTES: {
18
+ readonly 'ai-router': "openai-responses";
19
+ readonly 'ai-router-anthropic': "anthropic-messages";
20
+ };
21
+ export type ProviderRouteName = keyof typeof PROVIDER_ROUTES;
22
+ /** 预算项的只读视图:模型名 + 可选目录状态(inactive = 已下架,不可调用)。 */
23
+ export interface BudgetItem {
24
+ model_name: string;
25
+ model_status?: 'active' | 'inactive';
26
+ /** 模型接受的输入模态(网关 CSV,如 'text,image');缺省视同 'text'。 */
27
+ input_modalities?: string;
28
+ }
29
+ /**
30
+ * DSH 面向的输入模态字面量。对应 llm-pi-ai 当前 `MODALITIES`(catalog.ts
31
+ * MODALITY_GATE 仅 text/image);DSH 扩模态时同步扩展此并集与
32
+ * {@link DSH_SUPPORTED_MODALITIES} 即可解锁,无需改网关。
33
+ */
34
+ export type PiAiModality = 'text' | 'image';
35
+ /** DSH 当前能接受的模态集。网关可声明 video/audio,但 DSH 尚不能接,故输入前求交过滤。 */
36
+ export declare const DSH_SUPPORTED_MODALITIES: readonly PiAiModality[];
37
+ /** 每模型描述符:id + 注入 DSH 的 input 模态(已过滤到 DSH 支持集)。 */
38
+ export interface ModelDescriptor {
39
+ id: string;
40
+ input: readonly PiAiModality[];
41
+ }
42
+ /** 固定写入顺序:先主路由(兼容 agent-default-model 的 provider: ai-router)。 */
43
+ export declare const PROVIDER_ROUTE_NAMES: readonly ProviderRouteName[];
44
+ /** 旧版独立 responses 路由(现已并入主路由);仅用于升级时清理残留 provider。 */
45
+ export declare const LEGACY_PROVIDER_ROUTE_NAMES: readonly string[];
46
+ /**
47
+ * 从 budgets 归一化出去重、非空的模型 id 列表。已下架模型(model_status === 'inactive',
48
+ * 网关 PreCheck 直接 402)不在「能成功调用」集合内,剔除;状态缺省(旧网关)视同 active。
49
+ */
50
+ export declare function computeModelIds(budgets: readonly BudgetItem[]): string[];
51
+ /**
52
+ * 解析网关模态 CSV 为 DSH 可接受的模态集,并保证 text 在前、去重、过滤未知项。
53
+ *
54
+ * 缺省/空/未声明 → `['text']`(与旧网关语义一致)。网关声明的 video/audio 在 DSH 支持前
55
+ * 自动过滤:`'text,video,audio'` 目前落到 `['text']`,永不向 DSH 注入它不接受的模态
56
+ * (否则整个 profile 被 llm-pi-ai 拒绝)。
57
+ */
58
+ export declare function parseModalities(raw: string | undefined): PiAiModality[];
59
+ /** 由 budgets 构造每模型描述符(已剔除下架模型;模态按 budget 的 input_modalities 解析)。 */
60
+ export declare function computeModelDescriptors(budgets: readonly BudgetItem[]): ModelDescriptor[];
61
+ /**
62
+ * 按网关模型映射把预算内模型拆到各协议路由:
63
+ * 每个模型归属「优先级最高且映射命中(精确或通配)的协议」;
64
+ * 无任何映射命中的模型落到主路由(默认 responses,网关侧仍有 `*` 兜底,保持预算内模型均可选)。
65
+ * 返回每模型描述符(含 DSH 可接受的 input 模态),供 profile 注入。
66
+ */
67
+ export declare function computeRouteModels(budgets: readonly BudgetItem[], mapping: readonly GatewayModelMapping[]): Partial<Record<ProviderRouteName, ModelDescriptor[]>>;
68
+ /**
69
+ * 各协议的 pi-ai baseURL:OpenAI 系 SDK 把 baseURL 视为根(追加 chat/completions、
70
+ * responses),补 `/v1`;Anthropic SDK 自带 `v1/` 前缀,必须传裸 base,
71
+ * 否则会拼出 `/v1/v1/messages` 404。
72
+ */
73
+ export declare function protocolBaseURL(baseURL: string, protocol: string): string;
74
+ /** 构造一条 llm-pi-ai 手写声明的路由 profile(协议与 baseURL 由路由决定)。 */
75
+ export declare function buildPiAiProviderProfile(opts: {
76
+ baseURL: string;
77
+ route: ProviderRouteName;
78
+ models: readonly ModelDescriptor[];
79
+ }): Record<string, unknown>;
80
+ /** 构造全部非空协议路由的 profile 字典(空路由不产出,由写入侧清理旧路由)。 */
81
+ export declare function buildPiAiProviderProfiles(opts: {
82
+ baseURL: string;
83
+ routeModels: Partial<Record<ProviderRouteName, readonly ModelDescriptor[]>>;
84
+ }): Record<string, Record<string, unknown>>;
@@ -0,0 +1,4 @@
1
+ /** 稳定错误码/错误类型的定义在 src/client/types.ts(client 半边声明构建的 rootDir 内)。
2
+ * 此处仅为 Host 半边(orchestration / ai-router-client)提供同源的类型再导出,
3
+ * 避免两份定义漂移;声明构建时各自 emit 到 lib/types 对应位置。 */
4
+ export type { LoginError, LoginErrorCode } from './client/types.ts';
package/lib/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "hiwork-core",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "description": "HiWork 企业统一登录与模型自动供给插件(ai-router 网关登录,Web 表单,无 CLI 认证)",
6
+ "license": "UNLICENSED",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "registry": "https://registry.npmjs.org/"
10
+ },
11
+ "main": "lib/index.js",
12
+ "types": "lib/types/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./lib/types/index.d.ts",
16
+ "default": "./lib/index.js"
17
+ },
18
+ "./client": {
19
+ "types": "./lib/types/client/index.d.ts",
20
+ "default": "./lib/client.js"
21
+ },
22
+ "./cordis.patch.yml": "./cordis.patch.yml",
23
+ "./package.json": "./package.json"
24
+ },
25
+ "dsh": {
26
+ "bundle": {
27
+ "patch": "./cordis.patch.yml"
28
+ },
29
+ "client": {
30
+ "platform": "web",
31
+ "inject": [
32
+ "@deepseek-ai/dsh-client-store",
33
+ "@deepseek-ai/dsh-client-ui-slots",
34
+ "@deepseek-ai/dsh-client-ui-settings",
35
+ "@deepseek-ai/dsh-api-remotes",
36
+ "@deepseek-ai/dsh-client-ui-primitives"
37
+ ]
38
+ }
39
+ },
40
+ "peerDependencies": {
41
+ "@deepseek-ai/cordis": "4.0.2"
42
+ },
43
+ "devDependencies": {
44
+ "@deepseek-ai/cordis": "4.0.2",
45
+ "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1",
46
+ "@deepseek-ai/dsh-client-store": "0.1.2-rc.1",
47
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
48
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.2-rc.1",
49
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1",
50
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.1.2-rc.1",
51
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
52
+ "@deepseek-ai/dsh-credentials": "0.1.2-rc.1",
53
+ "@deepseek-ai/dsh-credentials-local": "0.1.2-rc.1",
54
+ "@deepseek-ai/dsh-llm": "0.1.2-rc.1",
55
+ "@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1",
56
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1",
57
+ "@deepseek-ai/dsh-settings-file": "0.1.2-rc.1",
58
+ "@deepseek-ai/dsh-workspace": "0.1.2-rc.1",
59
+ "@deepseek-ai/schemastery": "3.18.2",
60
+ "@types/node": "^22",
61
+ "@types/react": "^18",
62
+ "@types/react-dom": "^18",
63
+ "esbuild": "^0.24",
64
+ "jsdom": "^30.0.1",
65
+ "react": "^18",
66
+ "react-dom": "^18",
67
+ "tsx": "^4.23.12",
68
+ "typescript": "^5",
69
+ "vitest": "^3"
70
+ },
71
+ "scripts": {
72
+ "typecheck": "tsc --noEmit",
73
+ "build:host": "tsc -p tsconfig.build.json && node scripts/host-build.mjs",
74
+ "build:client": "tsc -p tsconfig.client-build.json && node scripts/client-build.mjs",
75
+ "build": "npm run build:host && npm run build:client",
76
+ "test": "vitest run"
77
+ }
78
+ }