@aalis/api-webui 0.11.1 → 0.13.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 (54) hide show
  1. package/dist/frame/frame.css +218 -0
  2. package/dist/frame/frame.js +158 -0
  3. package/dist/frame/schema-i18n/catalog.js +101 -0
  4. package/dist/frame/schema-i18n/check.js +65 -0
  5. package/dist/frame/schema-i18n/define.js +105 -0
  6. package/dist/frame/schema-i18n/errors.js +41 -0
  7. package/dist/frame/schema-i18n/format.js +160 -0
  8. package/dist/frame/schema-i18n/index.js +17 -0
  9. package/dist/frame/schema-i18n/locale.js +100 -0
  10. package/dist/frame/schema-i18n/locales/en.js +3 -0
  11. package/dist/frame/schema-i18n/message.js +249 -0
  12. package/dist/frame/schema-i18n/packs.js +52 -0
  13. package/dist/frame/schema-i18n/params.js +2 -0
  14. package/dist/frame/schema-i18n/resolve.js +85 -0
  15. package/dist/frame/schema-i18n/source.js +4 -0
  16. package/dist/frame/schema-i18n/text-ref.js +94 -0
  17. package/dist/frame/schema-i18n/texts.js +29 -0
  18. package/dist/frame.d.ts +190 -0
  19. package/dist/frame.d.ts.map +1 -0
  20. package/dist/frame.js +121 -0
  21. package/dist/frame.js.map +1 -0
  22. package/dist/index.d.ts +137 -206
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +53 -32
  25. package/dist/index.js.map +1 -1
  26. package/dist/locales/en.d.ts +82 -0
  27. package/dist/locales/en.d.ts.map +1 -0
  28. package/dist/locales/en.js +82 -0
  29. package/dist/locales/en.js.map +1 -0
  30. package/dist/page.d.ts +433 -0
  31. package/dist/page.d.ts.map +1 -0
  32. package/dist/page.js +30 -0
  33. package/dist/page.js.map +1 -0
  34. package/dist/rest.d.ts +674 -0
  35. package/dist/rest.d.ts.map +1 -0
  36. package/dist/rest.js +21 -0
  37. package/dist/rest.js.map +1 -0
  38. package/dist/texts.d.ts +163 -0
  39. package/dist/texts.d.ts.map +1 -0
  40. package/dist/texts.js +85 -0
  41. package/dist/texts.js.map +1 -0
  42. package/dist/theme.d.ts +466 -0
  43. package/dist/theme.d.ts.map +1 -0
  44. package/dist/theme.js +298 -0
  45. package/dist/theme.js.map +1 -0
  46. package/dist/themes/aalis-dark.json +49 -0
  47. package/dist/themes/aalis-light.json +49 -0
  48. package/dist/themes/brand-dark.json +49 -0
  49. package/dist/themes/brand-light.json +49 -0
  50. package/dist/themes/calm-dark.json +49 -0
  51. package/dist/themes/calm-light.json +49 -0
  52. package/dist/themes/neutral-dark.json +49 -0
  53. package/dist/themes/neutral-light.json +49 -0
  54. package/package.json +14 -6
package/dist/rest.d.ts ADDED
@@ -0,0 +1,674 @@
1
+ import type { UserIdentity } from '@aalis/api-authority';
2
+ import type { InstallResult, UninstallOptions, UpdateResult, UpdateTarget } from '@aalis/api-package-manager';
3
+ import type { PlatformConnection } from '@aalis/api-platform';
4
+ import type { LogEntry, PluginState, SelectionBasis } from '@aalis/core';
5
+ import type { ConfigSchema, SchemaIssue, WireConfigSchema } from '@aalis/schema-config';
6
+ import type { Localized, TextRef } from '@aalis/schema-i18n';
7
+ import type { DepOrigin } from '@aalis/util-dep-spec';
8
+ import type { FrameTexts } from './frame.js';
9
+ import type { AttentionItem, ExtendDeclaration, LogFilter, PluginBlockers } from './index.js';
10
+ import type { LayoutOperation, LayoutRecords, PageDataByType, PageRef, PageView } from './page.js';
11
+ import type { PluginTheme } from './theme.js';
12
+ /** 失败的回应(4xx、5xx) */
13
+ export interface ErrorResponse {
14
+ error: string | TextRef;
15
+ /** 输入没过校验时逐项列出:path、kind、code 同 schema-config 的 SchemaIssue,message 是这一项的说明 */
16
+ issues?: Array<Pick<SchemaIssue, 'path' | 'kind' | 'code'> & {
17
+ message: string | TextRef;
18
+ }>;
19
+ /** 改动已在运行态生效,只是没写进配置文件 */
20
+ applied?: true;
21
+ }
22
+ export interface OkResponse {
23
+ ok: true;
24
+ }
25
+ /** 管理动作的回执:message 写做成了什么,动作之后插件没落在预期状态(激活失败、仍在激活等)时也写在这里 */
26
+ export interface MessageResponse extends OkResponse {
27
+ message: string | TextRef;
28
+ }
29
+ export interface LoginRequest {
30
+ token: string;
31
+ }
32
+ export interface LoginResponse extends OkResponse {
33
+ identity: UserIdentity;
34
+ }
35
+ export interface AuthStatusResponse {
36
+ authed: boolean;
37
+ /** 登录了才有 */
38
+ identity?: UserIdentity;
39
+ }
40
+ /** GET /api/plugins 的一项:一个插件实例;没起来的原因见 PluginBlockers */
41
+ export interface PluginListItem extends PluginBlockers {
42
+ /** 插件包名:同一插件的几个实例按它合在一起 */
43
+ name: string;
44
+ instanceId: string;
45
+ displayName?: string | TextRef;
46
+ /** 插件声明的子系统,没声明的不给;组名与顺序见 DEFAULT_SUBSYSTEM_METADATA */
47
+ subsystem?: string;
48
+ /** 已装的包的版本,本地查不到的不给 */
49
+ version?: string;
50
+ state: PluginState;
51
+ /** 失败的说明(api-doctor 的 failureText) */
52
+ error?: string | TextRef;
53
+ /** 激活超过慢激活阈值、已转入后台 */
54
+ slow?: boolean;
55
+ /** 旧实例超过宽限仍未停下:停下之前同一 id 不起新实例 */
56
+ lingering?: boolean;
57
+ /** 提供这个界面:不能从界面停用或卸载 */
58
+ self?: true;
59
+ provides: string[];
60
+ requiredServices: string[];
61
+ optionalServices: string[];
62
+ /** 本插件偏好(用户设的、只对这个实例生效):服务名 → 偏好的提供者(contextId),只列它声明了的、设了的服务 */
63
+ servicePreferences: Record<string, string>;
64
+ /** 它声明的服务此刻各落到哪一家、依据是什么(本插件偏好、全局偏好或排名),只列选得到的 */
65
+ serviceSelections: Record<string, {
66
+ contextId: string;
67
+ basis?: SelectionBasis;
68
+ }>;
69
+ tools: string[];
70
+ commands: string[];
71
+ reusable: boolean;
72
+ extends?: ExtendDeclaration;
73
+ /** 配置文件里有这个实例的配置段(空段也算):市场卸载时「同时删除配置」看它;宿主不提供配置文档时为 false */
74
+ configSection: boolean;
75
+ /** 配置文档里这一段:密钥字段上是引用 `{ $secret }`;宿主不提供配置文档时是运行态配置,去掉密钥字段 */
76
+ config: Record<string, unknown>;
77
+ /** 插件的 configSchema 经 JSON 下发:带 session 声明,没有函数成员(validate、fromText、toText) */
78
+ configSchema?: WireConfigSchema;
79
+ defaultConfig: Record<string, unknown>;
80
+ }
81
+ export interface PluginListResponse {
82
+ plugins: PluginListItem[];
83
+ /** 密钥键 → 配置文档里引用它的处数 */
84
+ secretRefCounts: Record<string, number>;
85
+ }
86
+ /** 插件配置的部分更新:提交的顶层键整键替换,值为 null 的视为删除 */
87
+ export interface PluginConfigRequest {
88
+ config: Record<string, unknown>;
89
+ }
90
+ export interface PluginConfigResponse extends MessageResponse {
91
+ /** 本次提交里裁掉的未声明字段 */
92
+ ignored: string[];
93
+ /** 配置文档里原有、随这次写回删掉的未声明字段 */
94
+ removed: string[];
95
+ }
96
+ export interface InstanceCreateRequest {
97
+ /** 实例 id 是 `<插件名>:<suffix>`:字母、数字、下划线与连字符 */
98
+ suffix: string;
99
+ config?: Record<string, unknown>;
100
+ }
101
+ export interface InstanceCreateResponse extends MessageResponse {
102
+ instanceId: string;
103
+ ignored: string[];
104
+ }
105
+ export interface PluginScanResponse extends MessageResponse {
106
+ /** 新加载的插件 */
107
+ loaded: string[];
108
+ }
109
+ export interface HostConfigResponse {
110
+ /** 配置文档里写了的核心键 */
111
+ config: Record<string, unknown>;
112
+ /** 核心键的 schema */
113
+ schema: ConfigSchema;
114
+ /** 要重启才生效的键 */
115
+ restartKeys: string[];
116
+ /** 家目录,宿主不提供路径时没有 */
117
+ home?: string;
118
+ }
119
+ /** 核心键 → 新值,null 回到默认;只收核心键 */
120
+ export type HostConfigRequest = Record<string, unknown>;
121
+ export interface HostConfigSaved extends MessageResponse {
122
+ /** 改了的键里有要重启才生效的 */
123
+ restartNeeded: boolean;
124
+ }
125
+ export interface ServiceProviderView {
126
+ /** 提供者的插件实例 id,宿主自己提供的是 `root` */
127
+ contextId: string;
128
+ displayName?: string | TextRef;
129
+ label?: string | TextRef;
130
+ priority: number;
131
+ exclusive: boolean;
132
+ }
133
+ export interface ServiceListResponse {
134
+ /** 服务名 → 提供者(按偏好、优先级、登记先后排好,第一个就是正在用的)与偏好的提供者 */
135
+ services: Record<string, {
136
+ providers: ServiceProviderView[];
137
+ preferred: string | null;
138
+ }>;
139
+ }
140
+ export interface PreferRequest {
141
+ contextId: string;
142
+ }
143
+ /** 「需要处理」:审批在前,其后是插件故障与提示,各按先后 */
144
+ export interface AttentionResponse {
145
+ items: AttentionItem[];
146
+ }
147
+ export interface PlatformStatus {
148
+ adapterName: string;
149
+ platform: string;
150
+ /** 适配器所在的插件实例 */
151
+ contextId: string;
152
+ connections: PlatformConnection[];
153
+ }
154
+ export interface PlatformListResponse {
155
+ platforms: PlatformStatus[];
156
+ }
157
+ /** 日志历史的查询参数:筛选(与 /admin 的订阅同一份)与条数(默认 200,上限 5000) */
158
+ export interface LogQuery extends LogFilter {
159
+ limit?: number;
160
+ }
161
+ /** GET /api/themes:插件此刻提供的主题,按全局键排 */
162
+ export interface PluginThemesResponse {
163
+ themes: PluginTheme[];
164
+ }
165
+ /**
166
+ * 一个可选项:default 标没设时生效的那一项;description 是写在选项下面的一行说明(如工具分组的概述)。
167
+ *
168
+ * members 与回应的 others 是通用字段:任何「选几组、每组带一批东西」的多选(如工具分组)都按它们交,
169
+ * 界面不认来源、不认插件
170
+ */
171
+ export interface OptionDetail {
172
+ value: string;
173
+ label: string | TextRef;
174
+ default?: true;
175
+ description?: string | TextRef;
176
+ /** 选上这一项会带上哪些成员的名字:界面在这一项下面写「包含 N 项」、点开列出;没有成员时不交 */
177
+ members?: string[];
178
+ }
179
+ /**
180
+ * `webui:options` 贡献点的 spec:一个可选项来源。id 是来源名,即配置字段的 dynamicOptions;list 收字段依赖的那一项的
181
+ * 生效值(GET /api/models/:service 的 dependency,原样转交),给出可选项。同一个来源名有几家交付时取全局键最前的
182
+ */
183
+ export interface OptionsContribution {
184
+ id: string;
185
+ list(dependency?: string): OptionItem[] | Promise<OptionItem[]>;
186
+ }
187
+ /** 可选项来源给的一项:value 是存进配置的值 */
188
+ export type OptionItem = Pick<OptionDetail, 'value' | 'label' | 'description' | 'members'>;
189
+ declare module '@aalis/api-contributions' {
190
+ interface ContributionPointMap {
191
+ 'webui:options': OptionsContribution;
192
+ }
193
+ }
194
+ /**
195
+ * 可选项来源的回应:models 是取值,details 是带名字的可选项(有它时按它画),labels 是不在可选项里的取值的名字
196
+ * (深度思考的档位:换了模型以后存着的档位不在可选项里,界面按它写名字)。others 是不属于任何可选项、不随选择变的成员与
197
+ * 这一行的名字,界面写在可选项末尾、点开列出;这些成员怎么用由字段的说明写。只有宿主回答的来源(如 toolGroups)交得了
198
+ * others,插件经 webui:options 交的来源只交可选项
199
+ */
200
+ export interface OptionsResponse {
201
+ models: string[];
202
+ details?: OptionDetail[];
203
+ labels?: Record<string, string | TextRef>;
204
+ others?: {
205
+ label: string | TextRef;
206
+ members: string[];
207
+ };
208
+ }
209
+ /** 一个模型:contextId 是提供它的插件实例,llm-ref 的取值 `{ provider, model }` 认的是它 */
210
+ export interface LLMModelEntry {
211
+ model: string;
212
+ /** 显示名 */
213
+ provider: string | TextRef;
214
+ contextId: string;
215
+ capabilities: string[];
216
+ }
217
+ /** 模型服务(llm)的回应 */
218
+ export interface LLMModelsResponse {
219
+ providers: LLMModelEntry[];
220
+ }
221
+ export interface ModelRefreshResponse extends OkResponse {
222
+ added: string[];
223
+ removed: string[];
224
+ total: number;
225
+ }
226
+ export interface PageListResponse {
227
+ /** 按位置内的 order、实例、key 排好 */
228
+ pages: PageView[];
229
+ }
230
+ export interface PanelPagesResponse {
231
+ pages: PageRef[];
232
+ }
233
+ /** 声明式页面一个组件的数据,按组件种类 */
234
+ export interface PageDataResponse<T extends keyof PageDataByType = keyof PageDataByType> {
235
+ data: PageDataByType[T];
236
+ }
237
+ /** 插件前端一个数据源的数据:数据源返回的值 */
238
+ export interface FrameDataResponse {
239
+ data: unknown;
240
+ }
241
+ /**
242
+ * 数据路由的查询参数:sessionId 给会话面板,rowKey 给详情里的组件;插件前端的数据源另收 input(JSON 字符串,声明了输入的
243
+ * 数据源才收)。只收用得上的键,多出或缺了都拒收
244
+ */
245
+ export interface PageDataQuery {
246
+ sessionId?: string;
247
+ rowKey?: string;
248
+ input?: string;
249
+ }
250
+ /** 只收这三个键:sessionId 给会话面板,rowKey 给行动作(插件前端没有),input 给声明了输入的动作;多出或缺了都拒收 */
251
+ export interface PageActionRequest {
252
+ sessionId?: string;
253
+ rowKey?: string;
254
+ input?: Record<string, unknown>;
255
+ }
256
+ export interface PageActionResponse {
257
+ /** 处理函数给的一句结果 */
258
+ message?: string | TextRef;
259
+ }
260
+ /** 组件类别:plugin 可装卸,api 与 schema 只读,interface 是前端界面,util 是工具库 */
261
+ export type PackageCategory = 'plugin' | 'api' | 'schema' | 'interface' | 'util';
262
+ export interface MarketplacePackage {
263
+ name: string;
264
+ /** 安装源上的最新版,查不到为空串;不是本地已装的版本 */
265
+ version: string;
266
+ description: string;
267
+ author?: string;
268
+ installed: boolean;
269
+ /** 本地已装的版本 */
270
+ resolved?: string;
271
+ /** 根 package.json 里的依赖声明,未装或不是直接依赖时没有 */
272
+ request?: string;
273
+ /** 本地这份从哪来,未装时没有 */
274
+ origin?: DepOrigin;
275
+ /** 此刻能否经市场更新:来源是 registry,且安装源上的最新版严格新于本地。界面直接用它,不自己比版本 */
276
+ updatable: boolean;
277
+ /** `@aalis/` 下的包 */
278
+ official: boolean;
279
+ category: PackageCategory;
280
+ /**
281
+ * 声明提供的服务(package.json 的 `aalis.service.provides`),市场按服务搜靠它:已装的取本地这份(与本地版本对得上),
282
+ * 没装的取安装源上的最新版;都查不到或没声明时为空
283
+ */
284
+ provides: string[];
285
+ /** 关键词,去掉了类型词 */
286
+ keywords?: string[];
287
+ /** 月下载量 */
288
+ downloads?: number;
289
+ /** 最近更新时间(ISO) */
290
+ updated?: string;
291
+ /** npm 的综合评分,只用来排序 */
292
+ score?: number;
293
+ /** npm 标记的不安全包 */
294
+ insecure?: boolean;
295
+ license?: string;
296
+ links?: {
297
+ npm?: string;
298
+ homepage?: string;
299
+ repository?: string;
300
+ };
301
+ }
302
+ export interface MarketplaceResponse {
303
+ packages: MarketplacePackage[];
304
+ /** 检索源或安装源查不到时的说明 */
305
+ warning?: string | TextRef;
306
+ }
307
+ /** 系统组件:本地已装的内核、宿主、契约、规范与工具库 */
308
+ export interface SystemComponent {
309
+ name: string;
310
+ /** 本地已装的版本 */
311
+ version?: string;
312
+ /** 安装源上的最新版,查不到时没有 */
313
+ latest?: string;
314
+ request?: string;
315
+ /** 来源分档:已是最新版与查不到最新版都不能更新,从 updatable 推不出来源,所以另给 */
316
+ origin: DepOrigin;
317
+ description?: string;
318
+ kind: 'core' | 'runtime' | 'api' | 'schema' | 'util';
319
+ /** 根 dependencies 里以 semver 范围声明、且最新版严格新于本地 */
320
+ updatable: boolean;
321
+ }
322
+ export interface SystemComponentsResponse {
323
+ components: SystemComponent[];
324
+ warning?: string | TextRef;
325
+ }
326
+ /** 依赖链路的一个节点:present 为 false 是本地没有这个包,链路在此中断 */
327
+ export interface DependencyNode {
328
+ name: string;
329
+ present: boolean;
330
+ /** 已加载的插件才有:它提供与要用的服务 */
331
+ services?: {
332
+ provides: string[];
333
+ requires: string[];
334
+ };
335
+ children: DependencyNode[];
336
+ }
337
+ export interface DependencyGraphResponse {
338
+ /** 它依赖谁 */
339
+ upstream: DependencyNode;
340
+ /** 谁依赖它 */
341
+ downstream: DependencyNode;
342
+ /** 它要用的服务由谁提供(宿主提供的写「宿主」,没人提供为 null),与它提供的服务 */
343
+ services: {
344
+ required: Array<{
345
+ service: string;
346
+ providedBy: string | TextRef | null;
347
+ }>;
348
+ provides: string[];
349
+ };
350
+ /** 卸载它会断掉服务的插件 */
351
+ serviceDependents: string[];
352
+ }
353
+ export interface PackageRequest {
354
+ name: string;
355
+ }
356
+ /** 卸载:removeConfig 不给为 false,配置段与密钥留着 */
357
+ export interface UninstallRequest extends PackageRequest, UninstallOptions {
358
+ }
359
+ export interface UpdateRequest {
360
+ targets: UpdateTarget[];
361
+ }
362
+ /**
363
+ * GET /api/i18n/languages:界面的语言与时区。languages 是有文字可用的语言(i18n 服务的 languages()),供可选项与第三方客户端
364
+ * 用,每项的形状同 api-i18n 的 LanguageInfo(tag 是规范化的语言标签,name 是该语言的自称),第一方前端只读 chain 与 timeZone;
365
+ * chain 是全局层的语言链(i18n 的 chainOf({ host: true })),界面的文字按它渲染,数字、日期与排序
366
+ * 按渲染时选中的语言;timeZone 是服务进程的时区,界面的时间按它。i18n 缺席时 languages 与 chain 为空,timeZone 照给
367
+ */
368
+ export interface I18nLanguagesResponse {
369
+ languages: Array<{
370
+ tag: string;
371
+ name: string;
372
+ }>;
373
+ chain: string[];
374
+ timeZone: string;
375
+ }
376
+ /** 界面的语言:GET /api/i18n/languages 的 chain 与 timeZone */
377
+ export type PageLanguage = Pick<I18nLanguagesResponse, 'chain' | 'timeZone'>;
378
+ /**
379
+ * 前端入口里写好的界面语言:SPA 兜底发 index.html 时在 `</head>` 前放一个 id 为它的 application/json 块,内容是
380
+ * {@link PageLanguage},前端首帧按它画,不等一次往返。直接打开 /index.html、开发模式等没有这一块时,前端取
381
+ * GET /api/i18n/languages,取到之前按原文
382
+ */
383
+ export declare const PAGE_LANGUAGE_ID = "aalis-language";
384
+ /** 语言包给的一条译文:from 是翻译时原文模板的指纹 */
385
+ export interface PackedText {
386
+ language: string;
387
+ text: string;
388
+ from: string;
389
+ }
390
+ /**
391
+ * GET /api/i18n/messages:语言包给这些 ns 补的译文,供前端自带的字典用。entries 是 ns → 键 → 各语言包给的
392
+ * (同一语言按交付的先后,取先),只留全局层的语言链用得上的语言(与链里某种的语言相同的,以及 en);没有的 ns 不列。
393
+ * 前端照它建语言包索引(schema-i18n 的 PackIndex)交给 resolveText,取舍(只补缺、指纹)在那里做。i18n 缺席时为空
394
+ */
395
+ export interface I18nMessagesResponse {
396
+ entries: Record<string, Record<string, PackedText[]>>;
397
+ }
398
+ /** 回 JSON 的路由 */
399
+ export interface WebuiRestRoutes {
400
+ 'POST /api/auth/login': {
401
+ body: LoginRequest;
402
+ response: LoginResponse;
403
+ };
404
+ 'GET /api/auth/status': {
405
+ response: AuthStatusResponse;
406
+ };
407
+ 'POST /api/auth/logout': {
408
+ response: OkResponse;
409
+ };
410
+ 'GET /api/plugins': {
411
+ response: PluginListResponse;
412
+ };
413
+ 'PUT /api/plugins/:name/config': {
414
+ body: PluginConfigRequest;
415
+ response: PluginConfigResponse;
416
+ };
417
+ 'POST /api/plugins/:name/enable': {
418
+ response: MessageResponse;
419
+ };
420
+ 'POST /api/plugins/:name/disable': {
421
+ response: MessageResponse;
422
+ };
423
+ 'POST /api/plugins/:name/reload': {
424
+ response: MessageResponse;
425
+ };
426
+ 'POST /api/plugins/scan': {
427
+ response: PluginScanResponse;
428
+ };
429
+ 'POST /api/plugins/:name/instances': {
430
+ body: InstanceCreateRequest;
431
+ response: InstanceCreateResponse;
432
+ };
433
+ 'DELETE /api/plugins/:instanceId/instance': {
434
+ response: MessageResponse;
435
+ };
436
+ /** 本插件偏好:只对这个实例生效,校验、持久化与回应同全局偏好的两条 */
437
+ 'POST /api/plugins/:instanceId/services/:name/prefer': {
438
+ body: PreferRequest;
439
+ response: OkResponse;
440
+ };
441
+ 'DELETE /api/plugins/:instanceId/services/:name/prefer': {
442
+ response: OkResponse;
443
+ };
444
+ 'GET /api/config': {
445
+ response: HostConfigResponse;
446
+ };
447
+ 'PUT /api/config': {
448
+ body: HostConfigRequest;
449
+ response: HostConfigSaved;
450
+ };
451
+ 'POST /api/restart': {
452
+ response: MessageResponse;
453
+ };
454
+ 'GET /api/services': {
455
+ response: ServiceListResponse;
456
+ };
457
+ 'POST /api/services/:name/prefer': {
458
+ body: PreferRequest;
459
+ response: OkResponse;
460
+ };
461
+ 'DELETE /api/services/:name/prefer': {
462
+ response: OkResponse;
463
+ };
464
+ 'GET /api/attention': {
465
+ response: AttentionResponse;
466
+ };
467
+ 'GET /api/platforms': {
468
+ response: PlatformListResponse;
469
+ };
470
+ 'GET /api/logs/tail': {
471
+ query: LogQuery;
472
+ response: LogEntry[];
473
+ };
474
+ /** 往前翻:seq 比 before 小的最后 limit 条 */
475
+ 'GET /api/logs/range': {
476
+ query: LogQuery & {
477
+ before: number;
478
+ };
479
+ response: LogEntry[];
480
+ };
481
+ 'GET /api/themes': {
482
+ response: PluginThemesResponse;
483
+ };
484
+ /**
485
+ * 按来源取可选项:先找贡献点 webui:options 里同名的来源(dependency 原样交给它),回 `{ models, details }`;没有时
486
+ * llm 回模型;toolGroups 与 llm-thinking 由宿主回答:toolGroups 是已登记的分组与工具上出现过的分组的并集,有工具的
487
+ * 分组带组内工具的名字,不属于任何分组的工具另交 others;llm-thinking 收 dependency(条目 id
488
+ * `<提供者实例 id>/<模型 id>`,没带时回空的可选项);其余服务合起各提供者的 listModels(),回 `{ models }`
489
+ */
490
+ 'GET /api/models/:service': {
491
+ query: {
492
+ dependency?: string;
493
+ };
494
+ response: LLMModelsResponse | OptionsResponse;
495
+ };
496
+ /** :contextId 是提供者的插件实例,与模型的 contextId 相同 */
497
+ 'POST /api/llm-providers/:contextId/refresh': {
498
+ response: ModelRefreshResponse;
499
+ };
500
+ 'GET /api/i18n/languages': {
501
+ response: I18nLanguagesResponse;
502
+ };
503
+ /** ns 以逗号分隔 */
504
+ 'GET /api/i18n/messages': {
505
+ query: {
506
+ ns: string;
507
+ };
508
+ response: I18nMessagesResponse;
509
+ };
510
+ 'GET /api/pages': {
511
+ response: PageListResponse;
512
+ };
513
+ 'GET /api/session-pages': {
514
+ query: {
515
+ sessionId: string;
516
+ };
517
+ response: PanelPagesResponse;
518
+ };
519
+ /** 这一页所属插件的字典,插件前端的宿主随 init 交给框架 */
520
+ 'GET /api/pages/:instance/:pageKey/texts': {
521
+ response: FrameTexts;
522
+ };
523
+ 'GET /api/pages/:instance/:pageKey/data/:componentId': {
524
+ query: PageDataQuery;
525
+ response: PageDataResponse | FrameDataResponse;
526
+ };
527
+ 'POST /api/pages/:instance/:pageKey/actions/:action': {
528
+ body: PageActionRequest;
529
+ response: PageActionResponse;
530
+ };
531
+ 'GET /api/layout': {
532
+ response: LayoutRecords;
533
+ };
534
+ 'POST /api/layout': {
535
+ body: LayoutOperation;
536
+ response: LayoutRecords;
537
+ };
538
+ 'GET /api/marketplace': {
539
+ query: {
540
+ q?: string;
541
+ };
542
+ response: MarketplaceResponse;
543
+ };
544
+ 'GET /api/system-components': {
545
+ response: SystemComponentsResponse;
546
+ };
547
+ 'GET /api/marketplace/depgraph': {
548
+ query: {
549
+ name: string;
550
+ };
551
+ response: DependencyGraphResponse;
552
+ };
553
+ /** 包管理拒绝时也回 200,ok 为 false、message 写原因 */
554
+ 'POST /api/marketplace/install': {
555
+ body: PackageRequest;
556
+ response: InstallResult;
557
+ };
558
+ 'POST /api/marketplace/uninstall': {
559
+ body: UninstallRequest;
560
+ response: {
561
+ ok: boolean;
562
+ message: string | TextRef;
563
+ };
564
+ };
565
+ /** 整批更新,成功后进程重启 */
566
+ 'POST /api/marketplace/update': {
567
+ body: UpdateRequest;
568
+ response: UpdateResult;
569
+ };
570
+ }
571
+ /** 下载的文件:一律当附件,不在 WebUI 的源里内联;带长度,界面据它决定能不能预览 */
572
+ interface AttachmentHeaders {
573
+ 'content-type': 'application/octet-stream';
574
+ 'content-disposition': `attachment; ${string}`;
575
+ 'content-length': `${number}`;
576
+ 'x-content-type-options': 'nosniff';
577
+ 'content-security-policy': string;
578
+ }
579
+ /** 插件前端的文件:框架 CSP 的脚本只认这一页的目录与公用目录 */
580
+ interface FrameFileHeaders {
581
+ 'content-type': string;
582
+ 'content-length': `${number}`;
583
+ 'content-security-policy': `sandbox allow-scripts; ${string}`;
584
+ 'x-content-type-options': 'nosniff';
585
+ 'referrer-policy': 'no-referrer';
586
+ 'access-control-allow-origin': '*';
587
+ 'cache-control': 'no-cache';
588
+ }
589
+ /** WebUI 自己的页面与脚本:带文档级 CSP */
590
+ interface DocumentHeaders<T extends string> {
591
+ 'content-type': `${T}; charset=utf-8`;
592
+ 'content-length': `${number}`;
593
+ 'content-security-policy': string;
594
+ }
595
+ /** 回文件或页面的路由:写请求与 2xx 时的响应头(小写,不含 Date、ETag 这类传输层的头) */
596
+ export interface WebuiFileRoutes {
597
+ 'GET /api/auth/login.js': {
598
+ headers: DocumentHeaders<'application/javascript'>;
599
+ };
600
+ /** 句柄由会话服务签发,绑定会话 */
601
+ 'GET /api/session-file': {
602
+ query: {
603
+ sessionId: string;
604
+ handle: string;
605
+ };
606
+ headers: AttachmentHeaders;
607
+ };
608
+ /** 句柄是页面数据里的 FileCell.handle */
609
+ 'GET /api/page-file': {
610
+ query: {
611
+ handle: string;
612
+ };
613
+ headers: AttachmentHeaders;
614
+ };
615
+ /** 存储地址上的图片、视频与音频,按文件头判定类型 */
616
+ 'GET /api/media': {
617
+ query: {
618
+ uri: string;
619
+ };
620
+ headers: {
621
+ 'content-type': `${'image' | 'video' | 'audio'}/${string}`;
622
+ 'content-disposition': 'inline';
623
+ 'content-length': `${number}`;
624
+ 'x-content-type-options': 'nosniff';
625
+ 'content-security-policy': "sandbox; default-src 'none'";
626
+ 'cache-control': 'private, max-age=3600';
627
+ };
628
+ };
629
+ /** 代为取外站的图片 */
630
+ 'GET /api/proxy/image': {
631
+ query: {
632
+ url: string;
633
+ };
634
+ headers: {
635
+ 'content-type': `image/${string}`;
636
+ 'x-content-type-options': 'nosniff';
637
+ 'content-security-policy': 'sandbox';
638
+ 'cache-control': 'private, max-age=86400';
639
+ };
640
+ };
641
+ /** 插件前端的文件:token 取自 FramePageView.frame.src;只收 GET 与 HEAD */
642
+ 'GET /frames/:token/{*path}': {
643
+ headers: FrameFileHeaders;
644
+ };
645
+ /** 宿主给框架的助手 */
646
+ 'GET /frames/_base/frame.js': {
647
+ headers: FrameFileHeaders;
648
+ };
649
+ /** 宿主给框架的样式基线 */
650
+ 'GET /frames/_base/frame.css': {
651
+ headers: FrameFileHeaders;
652
+ };
653
+ /** 助手导入的 schema-i18n(随 api-webui 带的一份构建产物) */
654
+ 'GET /frames/_base/schema-i18n/{*path}': {
655
+ headers: FrameFileHeaders;
656
+ };
657
+ /** 换前端的恢复页:任何前端卡住时都能在这里切回 */
658
+ 'GET /__clients': {
659
+ headers: DocumentHeaders<'text/html'>;
660
+ };
661
+ 'GET /__clients.js': {
662
+ headers: DocumentHeaders<'application/javascript'>;
663
+ };
664
+ /** 其余 GET:活跃前端的 index.html(前端自己的路由),每次再验证;/assets/ 下没有的文件回 404 */
665
+ 'GET /{*path}': {
666
+ headers: DocumentHeaders<'text/html'> & {
667
+ 'cache-control': 'public, max-age=0';
668
+ };
669
+ };
670
+ }
671
+ /** 一条 JSON 路由 2xx 时线上的回应:文字对象已按读者语言渲染成字符串 */
672
+ export type WebuiRestResponse<K extends keyof WebuiRestRoutes> = Localized<WebuiRestRoutes[K]['response']>;
673
+ export {};
674
+ //# sourceMappingURL=rest.d.ts.map