GET /cache/regions 列出 kv_cache 各区的未过期条数、已过期条数、占用字节、最近写入;
POST /cache/regions/{region}/clear 清空一个区(admin)。contracts 加区名中文映射
cacheRegionLabel,web 加对应 hooks。
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
314 lines
10 KiB
TypeScript
314 lines
10 KiB
TypeScript
import { z } from "zod";
|
||
import * as cache from "../cache.ts";
|
||
import { WebSearchTestInput, WebSearchTestResult } from "../capabilities-io.ts";
|
||
import { CapabilityDescriptor, KnownCapabilityId } from "../capability.ts";
|
||
import { Id, IdParam } from "../common.ts";
|
||
import * as mcp from "../mcp.ts";
|
||
import * as pi from "../pi.ts";
|
||
import * as settingsNs from "../settings.ts";
|
||
import { GlobalSettings, GlobalSettingsUpdate } from "../settings.ts";
|
||
import { ep, OkResult } from "./shared.ts";
|
||
|
||
export const platformApi = {
|
||
// ── 能力 ──
|
||
capabilities: {
|
||
list: ep({
|
||
method: "get",
|
||
path: "/capabilities",
|
||
scope: "read",
|
||
summary: "能力注册中心描述",
|
||
response: z.object({ items: z.array(CapabilityDescriptor) }),
|
||
}),
|
||
invoke: ep({
|
||
method: "post",
|
||
path: "/capabilities/{capabilityId}/invoke",
|
||
scope: "read",
|
||
summary: "调用能力(实际所需 scope 见描述符;服务端按能力再次鉴权)",
|
||
params: z.object({ capabilityId: KnownCapabilityId }),
|
||
body: z.object({ input: z.unknown(), preview: z.boolean().default(false) }),
|
||
response: z.object({ output: z.unknown(), taskId: Id.nullable(), planId: Id.nullable() }),
|
||
}),
|
||
stats: ep({
|
||
method: "get",
|
||
path: "/capabilities/stats",
|
||
scope: "read",
|
||
summary: "能力调用统计:每能力调用数、失败数、平均耗时、最近调用、调用来源(内置智能体 / MCP / REST)",
|
||
query: mcp.CapabilityStatsQuery,
|
||
response: mcp.CapabilityStatsResponse,
|
||
}),
|
||
tools: ep({
|
||
method: "get",
|
||
path: "/capabilities/tools",
|
||
scope: "read",
|
||
summary: "能力清单:描述符、工具名、输入输出 JSON Schema、当前授权状态",
|
||
response: mcp.CapabilityToolsResponse,
|
||
}),
|
||
},
|
||
|
||
// ── 对外 MCP 服务端(Streamable HTTP 在 /mcp,不进 OpenAPI;这里是状态与配置)──
|
||
mcp: {
|
||
status: ep({
|
||
method: "get",
|
||
path: "/mcp/status",
|
||
scope: "admin",
|
||
summary: "MCP 服务端状态:启用、允许的 API Key、当前会话、最近调用、限速",
|
||
response: mcp.McpServerStatus,
|
||
}),
|
||
update: ep({
|
||
method: "patch",
|
||
path: "/mcp/config",
|
||
scope: "admin",
|
||
summary: "修改 MCP 服务端配置(启用开关、允许的 API Key)",
|
||
body: mcp.McpServerConfigUpdate,
|
||
response: mcp.McpServerConfig,
|
||
}),
|
||
},
|
||
|
||
// ── 缓存(C2-A,docs/runbook/cache.md) ──
|
||
cache: {
|
||
tmdb: ep({
|
||
method: "get",
|
||
path: "/cache/tmdb",
|
||
scope: "admin",
|
||
summary: "TMDB 缓存条目(请求响应与识别结果:键、过期时间、大小)与上限 / TTL",
|
||
query: cache.TmdbCacheQuery,
|
||
response: cache.TmdbCacheList,
|
||
}),
|
||
tmdbClear: ep({
|
||
method: "post",
|
||
path: "/cache/tmdb/clear",
|
||
scope: "admin",
|
||
summary: "清空 TMDB 缓存(请求响应与识别结果)",
|
||
response: cache.CacheClearResult,
|
||
}),
|
||
images: ep({
|
||
method: "get",
|
||
path: "/cache/images",
|
||
scope: "admin",
|
||
summary: "图片代理缓存用量",
|
||
response: cache.ImageCacheStatus,
|
||
}),
|
||
imagesClear: ep({
|
||
method: "post",
|
||
path: "/cache/images/clear",
|
||
scope: "admin",
|
||
summary: "清空图片代理缓存",
|
||
response: cache.CacheClearResult,
|
||
}),
|
||
regions: ep({
|
||
method: "get",
|
||
path: "/cache/regions",
|
||
scope: "admin",
|
||
summary: "通用缓存(kv_cache)按区统计:条目数、已过期数、占用字节、最近写入",
|
||
response: cache.CacheRegionList,
|
||
}),
|
||
regionClear: ep({
|
||
method: "post",
|
||
path: "/cache/regions/{region}/clear",
|
||
scope: "admin",
|
||
summary: "清空通用缓存的一个区",
|
||
params: cache.CacheRegionParam,
|
||
response: cache.CacheClearResult,
|
||
}),
|
||
},
|
||
|
||
// ── 网页搜索(WEB-1,docs/runbook/websearch.md) ──
|
||
websearch: {
|
||
test: ep({
|
||
method: "post",
|
||
path: "/websearch/test",
|
||
scope: "admin",
|
||
summary: "用已保存的搜索服务 Key 实际查询一次(不走缓存,计入每分钟上限)",
|
||
body: WebSearchTestInput,
|
||
response: WebSearchTestResult,
|
||
}),
|
||
},
|
||
|
||
// ── 设置 ──
|
||
settings: {
|
||
get: ep({ method: "get", path: "/settings", scope: "read", summary: "全局设置", response: GlobalSettings }),
|
||
update: ep({
|
||
method: "patch",
|
||
path: "/settings",
|
||
scope: "admin",
|
||
summary: "修改全局设置",
|
||
body: GlobalSettingsUpdate,
|
||
response: GlobalSettings,
|
||
}),
|
||
},
|
||
|
||
// ── 整理命名模板(W9-C,docs/design/naming-template.md):保存前服务端编译校验 ──
|
||
naming: {
|
||
variables: ep({
|
||
method: "get",
|
||
path: "/naming/variables",
|
||
scope: "read",
|
||
summary: "命名变量表(名称对齐 MP,含说明/示例值/我们特有标记)、过滤器、预览内置样本",
|
||
response: settingsNs.NamingVariablesResponse,
|
||
}),
|
||
preview: ep({
|
||
method: "post",
|
||
path: "/naming/preview",
|
||
scope: "read",
|
||
summary:
|
||
"预览:模板 + 样本(文件名 / 资源 / 资产 / 内置)→ 相对路径、段角色、错误(行列号)、提示;已有路径绑定时目录用绑定",
|
||
body: settingsNs.NamingPreviewInput,
|
||
response: settingsNs.NamingPreviewResult,
|
||
}),
|
||
templates: ep({
|
||
method: "get",
|
||
path: "/naming/templates",
|
||
scope: "read",
|
||
summary: "全局 / 库根 / 作品三级模板与按类型的生效结果(作品 > 库根 > 全局)",
|
||
query: settingsNs.NamingTemplatesQuery,
|
||
response: settingsNs.NamingTemplatesView,
|
||
}),
|
||
saveTemplates: ep({
|
||
method: "put",
|
||
path: "/naming/templates",
|
||
scope: "admin",
|
||
summary: "保存全局命名模板(逐条编译校验,有错 422 不保存)",
|
||
body: settingsNs.NamingSettingsPut,
|
||
response: settingsNs.NamingSettings,
|
||
}),
|
||
libraryRoot: ep({
|
||
method: "put",
|
||
path: "/library-roots/{id}/naming",
|
||
scope: "admin",
|
||
summary: "库根级命名覆盖(按类型;null 清除)",
|
||
params: IdParam,
|
||
body: settingsNs.LibraryRootNamingPut,
|
||
response: settingsNs.LibraryRootNamingPut,
|
||
}),
|
||
entity: ep({
|
||
method: "put",
|
||
path: "/media-entities/{id}/naming-override",
|
||
scope: "admin",
|
||
summary: "作品级命名覆盖(按类型;null 清除)。已有路径绑定的目录不受影响,只影响之后的文件名与新季目录",
|
||
params: IdParam,
|
||
body: settingsNs.EntityNamingOverridePut,
|
||
response: settingsNs.EntityNamingOverridePut,
|
||
}),
|
||
},
|
||
|
||
// ── Pi 模型上游(W7-A):多上游共存 + 订阅登录;写操作与登录只接受控制台会话 ──
|
||
pi: {
|
||
providers: ep({
|
||
method: "get",
|
||
path: "/pi/providers",
|
||
scope: "admin",
|
||
summary: "Pi provider 能力表(认证方式、订阅登录方式与条款提示、baseUrl 覆盖、env 字段、静态模型表)",
|
||
query: pi.PiProvidersQuery,
|
||
response: pi.PiProvidersResponse,
|
||
}),
|
||
list: ep({
|
||
method: "get",
|
||
path: "/pi/upstreams",
|
||
scope: "admin",
|
||
summary: "模型服务列表(不含密钥)",
|
||
response: pi.PiUpstreamList,
|
||
}),
|
||
get: ep({
|
||
method: "get",
|
||
path: "/pi/upstreams/{id}",
|
||
scope: "admin",
|
||
summary: "模型服务详情",
|
||
params: IdParam,
|
||
response: pi.PiUpstream,
|
||
}),
|
||
create: ep({
|
||
method: "post",
|
||
path: "/pi/upstreams",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "新建模型服务(apiKey 只写,存 secret 表)",
|
||
body: pi.PiUpstreamCreate,
|
||
response: pi.PiUpstream,
|
||
}),
|
||
update: ep({
|
||
method: "patch",
|
||
path: "/pi/upstreams/{id}",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "修改模型服务(provider 不可改;makeDefault 设默认模型服务)",
|
||
params: IdParam,
|
||
body: pi.PiUpstreamUpdate,
|
||
response: pi.PiUpstream,
|
||
}),
|
||
remove: ep({
|
||
method: "delete",
|
||
path: "/pi/upstreams/{id}",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "删除模型服务(连同凭据;是默认模型服务时清空默认)",
|
||
params: IdParam,
|
||
response: OkResult,
|
||
}),
|
||
test: ep({
|
||
method: "post",
|
||
path: "/pi/upstreams/{id}/test",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "测试模型服务:默认只解析凭据与校验模型(不产生费用);mode=completion 发一次最小补全",
|
||
params: IdParam,
|
||
body: pi.PiUpstreamTestRequest,
|
||
response: pi.PiUpstreamTestResult,
|
||
}),
|
||
models: ep({
|
||
method: "get",
|
||
path: "/pi/upstreams/{id}/models",
|
||
scope: "admin",
|
||
summary: "模型列表:已获取过远程列表时返回远程与静态目录的合并(远程优先),否则静态目录",
|
||
params: IdParam,
|
||
response: pi.PiUpstreamModels,
|
||
}),
|
||
modelsRefresh: ep({
|
||
method: "post",
|
||
path: "/pi/upstreams/{id}/models/refresh",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "获取模型列表:用该模型服务的凭证调 provider 的模型列表接口并存库;失败或不支持时回静态目录并给出原因",
|
||
params: IdParam,
|
||
response: pi.PiUpstreamModels,
|
||
}),
|
||
modelsProbe: ep({
|
||
method: "post",
|
||
path: "/pi/models/probe",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "新建模型服务前试拉模型列表(凭证只用于这一次请求,不落库)",
|
||
body: pi.PiModelsProbeRequest,
|
||
response: pi.PiUpstreamModels,
|
||
}),
|
||
oauthStart: ep({
|
||
method: "post",
|
||
path: "/pi/upstreams/{id}/oauth/start",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "开始订阅登录:返回授权链接(browser)或验证码(device)",
|
||
params: IdParam,
|
||
body: pi.PiOAuthStartRequest,
|
||
response: pi.PiOAuthStartResult,
|
||
}),
|
||
oauthComplete: ep({
|
||
method: "post",
|
||
path: "/pi/upstreams/{id}/oauth/complete",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "完成订阅登录:browser 粘回地址栏 URL;device 服务端轮询(本次最多等 waitMs,未完成返回 pending)",
|
||
params: IdParam,
|
||
body: pi.PiOAuthCompleteRequest,
|
||
response: pi.PiOAuthCompleteResult,
|
||
}),
|
||
oauthLogout: ep({
|
||
method: "post",
|
||
path: "/pi/upstreams/{id}/oauth/logout",
|
||
scope: "admin",
|
||
auth: "session",
|
||
summary: "退出订阅登录:删除本地 token(不会撤销提供方侧授权)",
|
||
params: IdParam,
|
||
response: pi.PiUpstream,
|
||
}),
|
||
},
|
||
} as const;
|