hiwork-core 0.0.30 → 0.0.37

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 (41) hide show
  1. package/cordis.patch.yml +15 -1
  2. package/lib/ai-router-client.js +394 -2
  3. package/lib/browser-login.js +42 -16
  4. package/lib/client-policy.js +2 -2
  5. package/lib/client.js +2496 -500
  6. package/lib/image-rpc.js +306 -0
  7. package/lib/imagegen.js +424 -0
  8. package/lib/index.js +18639 -7060
  9. package/lib/knowledge-config.js +91 -1
  10. package/lib/provision-session.js +10 -2
  11. package/lib/tool-names.js +10 -0
  12. package/lib/tools.js +205 -0
  13. package/lib/types/ai-router-client.d.ts +255 -2
  14. package/lib/types/browser-login.d.ts +10 -1
  15. package/lib/types/client/about-section.d.ts +27 -7
  16. package/lib/types/client/controller.d.ts +17 -9
  17. package/lib/types/client/daily-data.d.ts +31 -3
  18. package/lib/types/client/feature-center.d.ts +46 -1
  19. package/lib/types/client/feature-registry.d.ts +36 -3
  20. package/lib/types/client/image-cards.d.ts +218 -0
  21. package/lib/types/client/image-styles.d.ts +9 -0
  22. package/lib/types/client/images-data.d.ts +127 -0
  23. package/lib/types/client/images-page.d.ts +97 -0
  24. package/lib/types/client/index.d.ts +0 -1
  25. package/lib/types/client/login-gate.d.ts +2 -2
  26. package/lib/types/client/logo.d.ts +7 -2
  27. package/lib/types/client/menu-preferences.d.ts +163 -0
  28. package/lib/types/client/menu-section.d.ts +5 -0
  29. package/lib/types/client/menu-store.d.ts +101 -0
  30. package/lib/types/client/styles.d.ts +16 -0
  31. package/lib/types/client/types.d.ts +9 -0
  32. package/lib/types/image-rpc.d.ts +142 -0
  33. package/lib/types/imagegen.d.ts +241 -0
  34. package/lib/types/index.d.ts +89 -8
  35. package/lib/types/knowledge-config.d.ts +50 -2
  36. package/lib/types/tool-names.d.ts +11 -0
  37. package/lib/types/tools.d.ts +80 -0
  38. package/lib/types/user-agent.d.ts +31 -0
  39. package/lib/user-agent.js +54 -0
  40. package/lib/web-search.js +2 -2
  41. package/package.json +34 -24
@@ -0,0 +1,80 @@
1
+ import { type GenerateOutcome } from './imagegen.ts';
2
+ import { IMAGE_TOOL_NAMES } from './tool-names.ts';
3
+ export { IMAGE_TOOL_NAMES };
4
+ /**
5
+ * 生图工具的单次预算(**工具层护栏**,不是业务判据)。
6
+ *
7
+ * 它必须**大于**客户端真正会等的时间,否则工具会先掐断客户端请求,把一次本可成功的
8
+ * 生图变成工具超时。客户端等待上限 = 网关预算 + 15s(见 `imageGenerateTimeoutMs`),
9
+ * 而网关预算的合法上界是 600s、读不到配置时走 900s 兜底 ⇒ 工具预算取 960s(16 分钟),
10
+ * 比两者都高。真正的超时语义由网关的 504 / `IMAGE_TIMEOUT` 表达。
11
+ *
12
+ * 实测背景:原值 330s 是按「网关默认 180s」估的,而网关上界 600s、实测单张已到 415s
13
+ * —— 按那条估算会在合法的慢生图上误报。
14
+ */
15
+ export declare const IMAGE_TOOL_TIMEOUT_MS = 960000;
16
+ /**
17
+ * 注册工具所需的最小 Agent 结构端口(不 import DSH agent 运行时)。
18
+ * 与 knowledge 的 `KnowledgeAgent` 同形:`id` 用于身份判定,`ctx.tools.register` 是落点。
19
+ */
20
+ export type ImageAgent = {
21
+ readonly id: string;
22
+ readonly ctx: {
23
+ readonly tools: {
24
+ register(definition: unknown): () => void;
25
+ };
26
+ };
27
+ };
28
+ /**
29
+ * 工具执行期读到的会话/取消面(结构端口,便于单测直接伪造:
30
+ * `{ agent: { session: { header: { cwd } } }, signal }`)。
31
+ */
32
+ export interface ImageToolExec {
33
+ readonly agent?: {
34
+ readonly session?: {
35
+ readonly header?: {
36
+ readonly cwd?: string;
37
+ };
38
+ };
39
+ } | undefined;
40
+ readonly signal: AbortSignal;
41
+ }
42
+ /** 工具对 Host 生图服务的全部要求(生产由 `src/imagegen.ts` 的 `generateImageFile` 满足)。 */
43
+ export interface ImageToolService {
44
+ generate(request: {
45
+ prompt: string;
46
+ size?: string | undefined;
47
+ workspaceRoot?: string | undefined;
48
+ }): Promise<GenerateOutcome>;
49
+ }
50
+ /** 工具的模型可见描述(设计 §6.3 逐字冻结)。 */
51
+ export declare const IMAGE_GENERATE_DESCRIPTION: string;
52
+ /** 卡片数据源(JSON 形态):与 `GenerateOutcome` 同形,外加给模型读的 `text`。 */
53
+ export interface ImageToolValue {
54
+ ok: boolean;
55
+ /** 给模型读的那段话(见 {@link formatImageGenerateText})。 */
56
+ text: string;
57
+ files: Array<{
58
+ path: string;
59
+ mimeType: string;
60
+ byteSize: number;
61
+ revisedPrompt?: string;
62
+ }>;
63
+ prompt?: string;
64
+ model?: string;
65
+ size?: string;
66
+ generationMs?: number;
67
+ code?: string;
68
+ message?: string;
69
+ }
70
+ /** 模型可见的那段话(成功:路径 + 尺寸/模型/耗时 + 落盘说明;失败:原因 + 可执行提示)。 */
71
+ export declare function formatImageGenerateText(outcome: GenerateOutcome): string;
72
+ /** `GenerateOutcome` → 工具结果(卡片与模型共用同一份 JSON)。 */
73
+ export declare function toImageToolValue(outcome: GenerateOutcome): ImageToolValue;
74
+ /**
75
+ * 给一个根 Agent 注册生图工具。
76
+ * @param service - Host 侧生图服务(生产是 `src/imagegen.ts` 的 `generateImageFile`)。
77
+ * @param agent - 目标根 Agent。
78
+ * @returns 注销器(注销全部已注册工具)。
79
+ */
80
+ export declare function registerImageTools(service: ImageToolService, agent: ImageAgent): () => void;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * 发往网关的 `User-Agent`:`hiwork/<桌面端版本>`。
3
+ *
4
+ * 「客户端」在网关侧就是这一条头(请求日志的客户端列、排障时的流量归属),所以它必须报
5
+ * **产品 + 版本**,而不是插件内部包名。版本号取桌面端版本:这是运维真正关心的维度
6
+ * (哪一版客户端),插件版本对同一台机器上的所有请求都相同,报它区分不出客户端版本。
7
+ *
8
+ * 版本来源的优先级(高 → 低):
9
+ * 1. 环境变量 `HIWORK_APP_VERSION`——桌面端拉起 DSH 时注入,**宿主进程一启动就有**;
10
+ * 2. 桌面端经 IPC 推来的设备信息里的 `appVersion`(见 `src/browser-login.ts`)——
11
+ * 推送发生在宿主就绪之后,早于它的请求拿不到,所以只作兜底;
12
+ * 3. 两者都没有(纯 `dsh web` / CLI 场景)——回报插件自身的 `hiwork-core/<插件版本>`,
13
+ * 不拿插件版本冒充桌面端版本。
14
+ *
15
+ * 值一律经 {@link headerSafeVersion} 过滤后再进 header:环境变量与 IPC 都可能带来空串、
16
+ * 前后空白或换行,而 fetch 遇到非法 header 值会直接抛错——那会让每一次网关请求都失败。
17
+ */
18
+ /** 桌面端注入自身版本用的环境变量名;两侧契约,改这里必须同步 `hiwork-desktop/src/main.ts`。 */
19
+ export declare const DESKTOP_APP_VERSION_ENV = "HIWORK_APP_VERSION";
20
+ /**
21
+ * 桌面端版本号。
22
+ * @param env - 环境变量表;缺省 `process.env`(测试可注入)。
23
+ * @returns 版本号;环境变量与 IPC 都没有时 undefined。
24
+ */
25
+ export declare function desktopAppVersion(env?: NodeJS.ProcessEnv): string | undefined;
26
+ /**
27
+ * 网关请求的 User-Agent。
28
+ * @param version - 桌面端版本;缺省按 {@link desktopAppVersion} 解析(测试可注入)。
29
+ * @returns `hiwork/<桌面端版本>`;拿不到桌面端版本时 `hiwork-core/<插件版本>`。
30
+ */
31
+ export declare function gatewayUserAgent(version?: string | undefined): string;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * 发往网关的 `User-Agent`:`hiwork/<桌面端版本>`。
3
+ *
4
+ * 「客户端」在网关侧就是这一条头(请求日志的客户端列、排障时的流量归属),所以它必须报
5
+ * **产品 + 版本**,而不是插件内部包名。版本号取桌面端版本:这是运维真正关心的维度
6
+ * (哪一版客户端),插件版本对同一台机器上的所有请求都相同,报它区分不出客户端版本。
7
+ *
8
+ * 版本来源的优先级(高 → 低):
9
+ * 1. 环境变量 `HIWORK_APP_VERSION`——桌面端拉起 DSH 时注入,**宿主进程一启动就有**;
10
+ * 2. 桌面端经 IPC 推来的设备信息里的 `appVersion`(见 `src/browser-login.ts`)——
11
+ * 推送发生在宿主就绪之后,早于它的请求拿不到,所以只作兜底;
12
+ * 3. 两者都没有(纯 `dsh web` / CLI 场景)——回报插件自身的 `hiwork-core/<插件版本>`,
13
+ * 不拿插件版本冒充桌面端版本。
14
+ *
15
+ * 值一律经 {@link headerSafeVersion} 过滤后再进 header:环境变量与 IPC 都可能带来空串、
16
+ * 前后空白或换行,而 fetch 遇到非法 header 值会直接抛错——那会让每一次网关请求都失败。
17
+ */
18
+ import { PKG_VERSION } from "./version.js";
19
+ import { pushedAppVersion } from "./browser-login.js";
20
+ /** 桌面端注入自身版本用的环境变量名;两侧契约,改这里必须同步 `hiwork-desktop/src/main.ts`。 */
21
+ export const DESKTOP_APP_VERSION_ENV = 'HIWORK_APP_VERSION';
22
+ /**
23
+ * 版本号允许的形态:以字母或数字开头,其后只允许 semver 常见字符(`0-9 A-Z a-z . + - _`)。
24
+ *
25
+ * **必须是白名单,不能只过滤控制字符**:换成「删掉 `\n` 就放行」的写法时,
26
+ * `"1.0.7\nX-Injected: evil"` 会被拼成 `hiwork/1.0.7X-Injected: evil` —— 换行没了,
27
+ * 但被注入的文本原样进了 header,运维在网关看到的是一串看不懂的客户端名。
28
+ * 版本号本来就不该含空格/冒号,所以「不像版本号就当作没拿到」比「尽量修好它」正确。
29
+ */
30
+ const versionPattern = /^[0-9A-Za-z][0-9A-Za-z.+_-]*$/;
31
+ /** 版本号安全化:只接受白名单形态;空串、含空白/控制字符/其他标点一律视为「没拿到版本」。 */
32
+ function headerSafeVersion(value) {
33
+ if (value === undefined)
34
+ return undefined;
35
+ const trimmed = value.trim();
36
+ return versionPattern.test(trimmed) ? trimmed : undefined;
37
+ }
38
+ /**
39
+ * 桌面端版本号。
40
+ * @param env - 环境变量表;缺省 `process.env`(测试可注入)。
41
+ * @returns 版本号;环境变量与 IPC 都没有时 undefined。
42
+ */
43
+ export function desktopAppVersion(env = process.env) {
44
+ return headerSafeVersion(env[DESKTOP_APP_VERSION_ENV]) ?? headerSafeVersion(pushedAppVersion());
45
+ }
46
+ /**
47
+ * 网关请求的 User-Agent。
48
+ * @param version - 桌面端版本;缺省按 {@link desktopAppVersion} 解析(测试可注入)。
49
+ * @returns `hiwork/<桌面端版本>`;拿不到桌面端版本时 `hiwork-core/<插件版本>`。
50
+ */
51
+ export function gatewayUserAgent(version = desktopAppVersion()) {
52
+ const safe = headerSafeVersion(version);
53
+ return safe === undefined ? `hiwork-core/${PKG_VERSION}` : `hiwork/${safe}`;
54
+ }
package/lib/web-search.js CHANGED
@@ -34,7 +34,7 @@
34
34
  * 端口,接线方(index.ts)传真实 ctx 侧依赖;单测直接伪造。
35
35
  */
36
36
  import { WebError } from '@deepseek-ai/dsh-web';
37
- import { PKG_VERSION } from "./version.js";
37
+ import { gatewayUserAgent } from "./user-agent.js";
38
38
  /** 本 provider 注册进 `ctx.web` 用的稳定 id(cordis.patch.yml 的 searchProvider pin 与它逐字一致)。 */
39
39
  export const HIWORK_SEARCH_PROVIDER_ID = 'hiwork-managed-search';
40
40
  /** 网关侧端点(跨仓冻结;会话鉴权与 `/api/me/memory-config` 同一条)。 */
@@ -208,7 +208,7 @@ export function createWebSearchGateway(baseURL, opts = {}) {
208
208
  res = await doFetch(`${root}${ME_WEB_SEARCH_PATH}`, {
209
209
  method: 'POST',
210
210
  headers: {
211
- 'user-agent': `hiwork-core/${PKG_VERSION}`,
211
+ 'user-agent': gatewayUserAgent(),
212
212
  cookie: sessionCookie,
213
213
  'content-type': 'application/json',
214
214
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hiwork-core",
3
- "version": "0.0.30",
3
+ "version": "0.0.37",
4
4
  "type": "module",
5
5
  "description": "HiWork 企业统一登录与模型自动供给插件(ai-router 网关登录,Web 表单,无 CLI 认证)",
6
6
  "license": "UNLICENSED",
@@ -32,6 +32,7 @@
32
32
  "@deepseek-ai/dsh-client-store",
33
33
  "@deepseek-ai/dsh-client-ui-slots",
34
34
  "@deepseek-ai/dsh-client-ui-settings",
35
+ "@deepseek-ai/dsh-client-ui-layout",
35
36
  "@deepseek-ai/dsh-api-remotes",
36
37
  "@deepseek-ai/dsh-client-ui-primitives",
37
38
  "@deepseek-ai/dsh-client-ui-chat",
@@ -40,29 +41,35 @@
40
41
  }
41
42
  },
42
43
  "peerDependencies": {
43
- "@deepseek-ai/cordis": "4.0.2"
44
+ "@deepseek-ai/cordis": "~4.0.4",
45
+ "@deepseek-ai/dsh-client-ui-layout": ">=0.1.0-rc.5 <0.2.0"
44
46
  },
45
47
  "devDependencies": {
46
- "@deepseek-ai/cordis": "4.0.2",
47
- "@deepseek-ai/dsh-api-remotes": "0.1.5-rc.1",
48
- "@deepseek-ai/dsh-client-store": "0.1.5-rc.1",
49
- "@deepseek-ai/dsh-client-ui-chat": "0.1.5-rc.1",
50
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.1",
51
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
52
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.1",
53
- "@deepseek-ai/dsh-client-ui-session": "0.1.5-rc.1",
54
- "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.1",
55
- "@deepseek-ai/dsh-client-ui-sidebar": "0.1.5-rc.1",
56
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
57
- "@deepseek-ai/dsh-credentials": "0.1.5-rc.1",
58
- "@deepseek-ai/dsh-credentials-local": "0.1.5-rc.1",
59
- "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
60
- "@deepseek-ai/dsh-llm-pi-ai": "0.1.5-rc.1",
61
- "@deepseek-ai/dsh-settings": "0.1.5-rc.1",
62
- "@deepseek-ai/dsh-settings-file": "0.1.5-rc.1",
63
- "@deepseek-ai/dsh-web": "0.1.5-rc.1",
64
- "@deepseek-ai/dsh-workspace": "0.1.5-rc.1",
65
- "@deepseek-ai/schemastery": "3.18.2",
48
+ "@deepseek-ai/cordis": "4.0.4",
49
+ "@deepseek-ai/cordis-plugin-loader": "1.0.5",
50
+ "@deepseek-ai/dsh-agent-default-model": "0.1.7-rc.2",
51
+ "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2",
52
+ "@deepseek-ai/dsh-app-boot": "0.1.7-rc.2",
53
+ "@deepseek-ai/dsh-attachment": "0.1.7-rc.2",
54
+ "@deepseek-ai/dsh-client-store": "0.1.7-rc.2",
55
+ "@deepseek-ai/dsh-client-ui-chat": "0.1.7-rc.2",
56
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2",
57
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2",
58
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.2",
59
+ "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2",
60
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2",
61
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.1.7-rc.2",
62
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
63
+ "@deepseek-ai/dsh-config-editor": "0.1.7-rc.2",
64
+ "@deepseek-ai/dsh-credentials": "0.1.7-rc.2",
65
+ "@deepseek-ai/dsh-credentials-local": "0.1.7-rc.2",
66
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
67
+ "@deepseek-ai/dsh-llm-pi-ai": "0.1.7-rc.2",
68
+ "@deepseek-ai/dsh-settings": "0.1.7-rc.2",
69
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2",
70
+ "@deepseek-ai/dsh-web": "0.1.7-rc.2",
71
+ "@deepseek-ai/dsh-workspace": "0.1.7-rc.2",
72
+ "@deepseek-ai/schemastery": "3.18.4",
66
73
  "@types/node": "^22",
67
74
  "@types/react": "^18",
68
75
  "@types/react-dom": "^18",
@@ -72,13 +79,16 @@
72
79
  "react-dom": "^18",
73
80
  "tsx": "^4.23.12",
74
81
  "typescript": "^5",
75
- "vitest": "^3"
82
+ "vitest": "^3",
83
+ "yaml": "^2.8.1",
84
+ "@deepseek-ai/dsh-client-ui-layout": "0.1.7-rc.2"
76
85
  },
77
86
  "scripts": {
78
87
  "typecheck": "tsc --noEmit",
79
88
  "build:host": "tsc -p tsconfig.build.json && node scripts/host-build.mjs",
80
89
  "build:client": "tsc -p tsconfig.client-build.json && node scripts/client-build.mjs",
81
90
  "build": "npm run build:host && npm run build:client",
82
- "test": "vitest run"
91
+ "test": "vitest run",
92
+ "smoke": "tsx scripts/smoke/smoke.ts"
83
93
  }
84
94
  }