api.ts 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. // 对外 API 的数据结构(docs/design/04-api.md)
  2. import type { InteractionRequest, ProviderId, UsagePayload } from './events'
  3. export type PermissionMode = 'ask' | 'auto' | 'readonly'
  4. export type SessionStatus = 'idle' | 'running' | 'waiting_input'
  5. export type RunStatus = 'queued' | 'running' | 'waiting_input' | 'completed' | 'failed' | 'interrupted'
  6. export interface SessionDto {
  7. id: string
  8. title: string
  9. provider: ProviderId
  10. model: string
  11. profileId: string | null
  12. status: SessionStatus
  13. archived: boolean
  14. source: string
  15. lastSeq: number
  16. createdAt: string
  17. updatedAt: string
  18. }
  19. export interface SessionDetailDto extends SessionDto {
  20. activeRunId: string | null
  21. pendingInteractions: InteractionRequest[]
  22. /** 实际生效的权限模式:会话覆盖值(仅后台可设)或 Profile 的设置 */
  23. permissionMode: PermissionMode
  24. permissionModeOverridden: boolean
  25. systemPromptAppend: string
  26. }
  27. export interface CreateSessionBody {
  28. profileId?: string
  29. model?: string
  30. title?: string
  31. permissionMode?: PermissionMode
  32. systemPromptAppend?: string
  33. }
  34. export interface SendMessageBody {
  35. text: string
  36. attachments?: string[]
  37. }
  38. export interface RunDto {
  39. id: string
  40. sessionId: string
  41. status: RunStatus
  42. startedAt: string | null
  43. endedAt: string | null
  44. usage: UsagePayload | null
  45. error: string | null
  46. }
  47. export interface FileDto {
  48. id: string
  49. sessionId: string
  50. path: string
  51. origin: 'upload' | 'agent'
  52. mime: string
  53. size: number
  54. createdAt: string
  55. updatedAt: string
  56. }
  57. export interface FileAccessPolicy {
  58. mode: 'restricted' | 'broad'
  59. read: PathRule[]
  60. write: PathRule[]
  61. deny: string[]
  62. }
  63. export type PathRule = { knowledgeRootId: string } | { path: string }
  64. export interface ProfileDto {
  65. id: string
  66. name: string
  67. description: string
  68. provider: ProviderId
  69. model: string
  70. systemPrompt: string
  71. permissionMode: PermissionMode
  72. allowedTools: string[]
  73. disallowedTools: string[]
  74. skills: string[] | 'all'
  75. fileAccess: FileAccessPolicy
  76. knowledgeRootIds: string[]
  77. isDefault: boolean
  78. /** 内置 Profile(通用助手)不可删除 */
  79. builtin: boolean
  80. version: number
  81. updatedAt: string
  82. }
  83. export type ProfileInput = Omit<ProfileDto, 'id' | 'version' | 'updatedAt' | 'builtin'>
  84. export interface KnowledgeRootDto {
  85. id: string
  86. name: string
  87. path: string
  88. description: string
  89. access: 'read' | 'write'
  90. enabled: boolean
  91. check: PathCheck
  92. }
  93. export interface PathCheck {
  94. exists: boolean
  95. readable: boolean
  96. isDirectory: boolean
  97. /** 命中的全局禁止项 */
  98. denied: string | null
  99. /** 位于 home 下,systemd ProtectHome 部署时需要额外绑定 */
  100. underHome: boolean
  101. message: string | null
  102. }
  103. export interface ProviderStatusDto {
  104. id: ProviderId
  105. enabled: boolean
  106. available: boolean
  107. loggedIn: boolean | null
  108. account: string | null
  109. cliPath: string
  110. version: string | null
  111. models: string[]
  112. defaultModel: string
  113. message: string | null
  114. }
  115. export interface ResolvedAccessDto {
  116. readable: string[]
  117. writable: string[]
  118. denied: string[]
  119. mode: FileAccessPolicy['mode']
  120. }
  121. export interface ApiKeyDto {
  122. id: string
  123. name: string
  124. prefix: string
  125. enabled: boolean
  126. allowedProfileIds: string[]
  127. defaultProfileId: string | null
  128. createdAt: string
  129. lastUsedAt: string | null
  130. }
  131. export interface ApiErrorBody {
  132. error: { code: string; message: string; details?: unknown }
  133. }
  134. export interface Page<T> {
  135. items: T[]
  136. nextCursor: string | null
  137. }
  138. // ---- 技能与插件(通过 Claude Code 官方插件机制安装,ADR-0013)----
  139. export type LicenseKind = 'open' | 'restricted' | 'unknown'
  140. export interface SkillInfo {
  141. /** 带插件前缀的技能 ID,例如 agent-skills:report-conventions、document-skills:xlsx */
  142. id: string
  143. name: string
  144. description: string
  145. plugin: string
  146. /** local 本地技能目录;plugin Claude 插件;official 从官方仓库安装(Codex);system 引擎自带;community 第三方技能(两个引擎共用,需在 Profile 中单独启用) */
  147. source: 'local' | 'plugin' | 'official' | 'system' | 'community'
  148. license: LicenseKind
  149. }
  150. export interface InstalledPluginDto {
  151. id: string
  152. name: string
  153. marketplace: string
  154. version: string | null
  155. enabled: boolean
  156. installPath: string
  157. installedAt: string | null
  158. lastUpdated: string | null
  159. skills: SkillInfo[]
  160. license: { kind: LicenseKind; summary: string | null }
  161. }
  162. export interface AvailablePluginDto {
  163. pluginId: string
  164. name: string
  165. description: string
  166. marketplaceName: string
  167. version: string | null
  168. installed: boolean
  169. }
  170. export interface MarketplaceDto {
  171. name: string
  172. source: string
  173. location: string | null
  174. }
  175. export interface PluginStateDto {
  176. cliPath: string
  177. installed: InstalledPluginDto[]
  178. available: AvailablePluginDto[]
  179. marketplaces: MarketplaceDto[]
  180. localSkills: SkillInfo[]
  181. error: string | null
  182. }
  183. export type PluginAction =
  184. | { action: 'marketplace-add'; source: string }
  185. | { action: 'marketplace-remove' | 'marketplace-update'; name: string }
  186. | { action: 'install' | 'uninstall' | 'update' | 'enable' | 'disable'; plugin: string }
  187. export interface ApiKeyProfiles {
  188. allowedProfileIds: string[]
  189. defaultProfileId: string
  190. }
  191. export interface CodexCatalogSkillDto {
  192. name: string
  193. description: string
  194. license: LicenseKind
  195. licenseName: string | null
  196. installed: boolean
  197. installedSha: string | null
  198. updatable: boolean
  199. }
  200. export interface CodexSkillCatalogDto {
  201. repo: string
  202. sha: string | null
  203. fetchedAt: string | null
  204. skills: CodexCatalogSkillDto[]
  205. unmanaged: string[]
  206. }
  207. // ---- 第三方技能(skills.sh 目录,从 GitHub 按提交安装,两个引擎共用,ADR-0017)----
  208. /** 第三方技能的插件名,技能 ID 形如 community-skills:<name> */
  209. export const COMMUNITY_SKILL_PLUGIN = 'community-skills'
  210. export interface CommunitySearchResultDto {
  211. /** GitHub 仓库 owner/repo */
  212. source: string
  213. skillId: string
  214. name: string
  215. installs: number
  216. installed: boolean
  217. /** 不能从这里安装的原因(如官方技能仓库应在对应引擎的页面安装) */
  218. blocked: string | null
  219. }
  220. export interface CommunitySkillPreviewDto {
  221. source: string
  222. skillId: string
  223. /** 安装后的技能名(取自 SKILL.md 的 name) */
  224. name: string
  225. description: string
  226. sha: string
  227. /** 技能在仓库中的路径 */
  228. path: string
  229. skillMd: string
  230. files: { path: string; size: number }[]
  231. /** 技能包含可执行脚本(.py / .sh / .js 等) */
  232. hasScripts: boolean
  233. license: LicenseKind
  234. licenseName: string | null
  235. /** 许可证来自哪里:技能目录、SKILL.md 声明或仓库根目录 */
  236. licenseFrom: 'skill' | 'frontmatter' | 'repo' | null
  237. installed: { sha: string } | null
  238. /** 同名技能已从其他来源安装 */
  239. conflict: string | null
  240. }
  241. export interface CommunitySkillDto {
  242. id: string
  243. name: string
  244. description: string
  245. source: string
  246. skillId: string
  247. path: string
  248. sha: string
  249. license: string | null
  250. installedAt: string
  251. }
  252. // ---- Codex 插件(OpenAI 官方 openai-curated 目录,只在 Playground 中使用,ADR-0018)----
  253. export interface CodexPluginDto {
  254. /** 插件 ID(plugin/uninstall 使用),形如 gmail@openai-curated-remote */
  255. id: string
  256. name: string
  257. displayName: string
  258. description: string
  259. category: string | null
  260. developer: string | null
  261. marketplace: string
  262. installed: boolean
  263. enabled: boolean
  264. /** NOT_AVAILABLE / AVAILABLE / INSTALLED_BY_DEFAULT */
  265. installPolicy: string
  266. /** AVAILABLE / DISABLED_BY_ADMIN */
  267. availability: string
  268. logoUrl: string | null
  269. }
  270. export interface CodexPluginCatalogDto {
  271. items: CodexPluginDto[]
  272. /** 符合筛选条件的总数 */
  273. total: number
  274. categories: string[]
  275. fetchedAt: string | null
  276. error: string | null
  277. }
  278. export interface CodexPluginDetailDto extends CodexPluginDto {
  279. longDescription: string | null
  280. skills: { name: string; description: string }[]
  281. apps: { id: string; name: string; description: string | null; installUrl: string | null }[]
  282. mcpServers: string[]
  283. websiteUrl: string | null
  284. privacyPolicyUrl: string | null
  285. termsOfServiceUrl: string | null
  286. }
  287. export interface CodexPluginInstallResultDto {
  288. /** 需要在 ChatGPT 中授权的应用(打开 installUrl 完成连接) */
  289. appsNeedingAuth: { id: string; name: string; installUrl: string | null }[]
  290. }
  291. // ---- 用量统计 ----
  292. export interface UsageTotals {
  293. runs: number
  294. failed: number
  295. interrupted: number
  296. inputTokens: number
  297. outputTokens: number
  298. cacheReadTokens: number
  299. cacheWriteTokens: number
  300. /** 订阅登录下为引擎给出的估算值 */
  301. costUsd: number
  302. durationMs: number
  303. }
  304. export interface UsageSummaryDto {
  305. /** 统计区间(含首尾,服务器本地日期) */
  306. from: string
  307. to: string
  308. total: UsageTotals
  309. today: UsageTotals
  310. /** 每天一项,没有用量的日期也会列出 */
  311. daily: ({ date: string } & UsageTotals)[]
  312. /** 按来源:API Key(平台)或后台 Playground(source = admin) */
  313. bySource: ({ source: string; name: string } & UsageTotals)[]
  314. byModel: ({ provider: string; model: string } & UsageTotals)[]
  315. }
  316. export interface RecentErrorDto {
  317. runId: string
  318. sessionId: string
  319. sessionTitle: string
  320. source: string
  321. provider: string
  322. error: string
  323. endedAt: string | null
  324. }