Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion ui/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ ui/
│ │ └── <component-name>/ # Less-frequent shared components imported explicitly
│ ├── constants/ # Cross-feature constants grouped by domain
│ │ └── CONSTANT_README.md # Shared constant placement and naming rules
│ ├── layout/ # Shared application shells, headers, sidebars, and layout types
│ ├── layout/ # Shared application shells, headers, sidebars, types, and helpers
│ ├── locales/ # Reserved for internationalization messages and locale setup
│ ├── workflow-canvas/ # LogicFlow canvas and workflow domain components
│ │ ├── component/ # Reusable workflow canvas UI
Expand Down Expand Up @@ -124,6 +124,10 @@ Structural responsibilities:
through `useStore()`. Store modules may import a specific Store directly when coordinating state
internally to avoid circular access through the aggregate entry.
- Put functions shared by most pages or multiple business modules in `utils/`; detailed placement, file organization, and naming rules are maintained in `src/utils/UTILS_README.md`.
- Treat application, knowledge, model, and tool as the four special resource domains that can span
Workspace, System resource management, and System shared resources. Their route scope, API
selection, reusable cards, and context-specific Actions follow `ROUTE_README.md`,
`API_README.md`, and `VIEW_README.md`; do not extend this three-scope pattern to ordinary pages.
- Import source assets through `src/assets/`; use `public/` only when a file must retain its original filename and URL.

## Entry Points
Expand Down
65 changes: 46 additions & 19 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,32 @@ Admin API;Chat 目录作为独立体系预留。
```text
src/api/
├── admin/
│ ├── core/ # Admin 请求基础能力
│ │ ├── request.ts # Axios 实例、HTTP 方法与统一响应解包
│ │ └── types.ts # Admin 请求协议和 loading 类型
│ ├── auth/ # Admin 登录认证接口
│ │ └── types.ts # 认证 API 与认证 Store 共用类型
│ ├── workspace/ # 工作空间业务接口
│ └── system/ # 系统管理业务接口
├── chat/ # Chat 独立请求体系,当前预留
├── enums/ # 后端固定枚举值
│ ├── index.ts # API 枚举值的唯一导入入口
│ └── <domain>.ts # 按明确业务域拆分的枚举值
├── types/ # API 与 View/Component 共用的业务类型
│ ├── index.ts # API 公共类型的唯一导入入口
│ ├── common.ts # 多个 API 业务域共用的基础类型
│ └── <domain>.ts # 按明确业务域拆分的共享类型
│ ├── auth/ # Admin 登录认证与当前用户接口
│ │ └── types.ts # 认证 API 与认证 Store 共用类型
│ ├── core/ # Admin 请求基础能力
│ │ ├── request.ts # Axios 实例、HTTP 方法与统一响应解包
│ │ └── types.ts # Admin 请求协议和 loading 类型
│ ├── system/ # 系统管理业务接口
│ │ ├── chat-user/ # 对话用户、用户组及认证接口
│ │ ├── settings/ # 登录认证、邮件与外观设置接口
│ │ ├── shared-resources/ # System 共享资源接口
│ │ └── <resource>.ts # 其他 System 单资源接口
│ ├── workspace/ # 工作空间业务接口
│ │ ├── application/ # 智能体接口
│ │ ├── knowledge/ # 知识库接口
│ │ ├── model/ # 模型接口
│ │ ├── tool/ # 工具及工具商店接口
│ │ └── <resource>.ts # 工作空间公共资源接口
│ └── provider.ts # Workspace 与 System 共用的模型供应商接口
├── chat/ # Chat 独立请求体系,当前预留
│ └── README.md # Chat API 边界与后续实现说明
├── enums/ # 后端固定枚举值
│ ├── index.ts # API 枚举值的唯一导入入口
│ └── <domain>.ts # 按明确业务域拆分的枚举值
├── types/ # API 与 View/Component 共用的业务类型
│ ├── index.ts # API 公共类型的唯一导入入口
│ ├── common.ts # 多个 API 业务域共用的基础类型
│ └── <domain>.ts # 按明确业务域拆分的共享类型
└── API_README.md
```

Expand All @@ -35,9 +46,12 @@ src/api/

## 业务接口组织

- 业务 API 按一级业务域、二级资源文件归类,例如 `workspace/agent.ts` 和
`system/workspace.ts`。
- 一类资源的增删改查放在同一个文件,不创建同名业务文件夹或汇总所有业务接口的 `api.ts`。
- 业务 API 先按 Admin 入口下的 `auth`、`workspace`、`system` 等一级业务域归类。Workspace 和
System 内部可继续按明确的功能域建立子目录,例如 `workspace/application/`、
`workspace/tool/`、`system/chat-user/` 和 `system/settings/`;不需要分组的单资源接口直接放在
所属一级业务域下。
- 一类资源的增删改查放在同一个最终资源文件中。调用方直接导入该文件,不为业务目录创建聚合
入口,也不创建汇总所有业务接口的 `api.ts`。
- 每个业务接口函数必须添加简短的 JSDoc,说明接口的业务作用;注释应描述“获取什么”“保存什么”
或“对哪个资源执行什么操作”,不重复参数类型、请求方法等代码已经清楚表达的信息。
- 每个业务接口使用 `const` 声明的箭头函数,不单独具名导出;在文件末尾通过
Expand All @@ -47,7 +61,20 @@ src/api/
`admin/core/request.ts` 等请求基础设施可按职责提供具名导出。
例如从 `login.ts` 使用 `import LoginApi from '@/api/admin/auth/login'`,再调用
`LoginApi.postLogin()`;System Workspace API 使用
`import WorkspaceApi from '@/api/admin/system/workspace'`。
`import WorkspaceApi from '@/api/admin/system/workspace'`;System 登录设置使用
`import AuthSettingApi from '@/api/admin/system/settings/auth-setting'`。

### 四类特殊资源 API

`application`、`knowledge`、`model`、`tool` 是需要同时考虑 Workspace、System 资源管理和
System 共享资源的四类特殊资源。其接口按真实后端边界分别维护在 `admin/workspace/` 与
`admin/system/` 下,不把不同范围的 URL 合并为页面侧 API Map,也不让卡片或 Action 根据路由拼接
System 接口地址。

页面根据路由 `resourceScope` 选择当前范围的完整业务 API 对象,并将其传给需要请求的 Card
Action、Drawer 或 Dialog。复用方直接使用 `typeof XxxApi` 约束完整 API 对象;不要为每组 Action
额外维护逐方法接口,例如 `ModelActionApi`,也不要使用不断扩展的 `Pick<typeof XxxApi, ...>`。
仅展示数据的组件不接收 API。

## 枚举与类型组织

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get } from '../../core/request'
import { get } from './core/request'
import type {
BaseModelOption,
DynamicFormField,
Expand Down Expand Up @@ -36,7 +36,6 @@ const getBaseModelParamsForm = (provider: string, modelType: string, modelName:
})
}


/** 获取供应商支持的模型类型。 */
const getModelTypeList = (provider: string) => {
return get<ModelTypeOption[]>(`${prefix}/model_type_list`, { provider })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, post, put } from '../core/request'
import { get, post, put } from '../../core/request'
import type { QrLoginPlatform, QrLoginPlatformPayload } from '@/api/types'

const prefix = '/chat_user/auth/platform/source'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, post, put } from '../core/request'
import { get, post, put } from '../../core/request'
import type { AuthProviderSettingPayload, AuthProviderType } from '@/api/types'

const prefix = '/chat_user/auth'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { del, get, post } from '../core/request'
import type { ParamsPage, ResponsePage } from '../core/types'
import { del, get, post } from '../../core/request'
import type { ParamsPage, ResponsePage } from '../../core/types'
import type { ChatUserGroupMember, ChatUserGroupPayload, ListItem, Dict } from '@/api/types'

const prefix = '/system/group'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { del, get, post, put } from '../core/request'
import type { ParamsPage, ResponsePage, PasswordRequest } from '../core/types'
import { del, get, post, put } from '../../core/request'
import type { ParamsPage, ResponsePage, PasswordRequest } from '../../core/types'
import type {
BatchSetChatUserQuotaRequest,
BatchSetChatUserQuotaResult,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, post, put } from '../core/request'
import { get, post, put } from '../../core/request'
import type { QrLoginPlatform, QrLoginPlatformPayload } from '@/api/types'

const prefix = '/platform/source'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, post, put } from '../core/request'
import { get, post, put } from '../../core/request'
import type { AuthProviderSettingPayload, AuthProviderType, LoginAuthSettingPayload } from '@/api/types'

const prefix = '/auth'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, post, put } from '../core/request'
import { get, post, put } from '../../core/request'
import type { EmailSettingPayload } from '@/api/types'

const prefix = '/email_setting'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { get, put } from '../core/request'
import type { ThemeInfo } from '../auth/types'
import { get, put } from '../../core/request'
import type { ThemeInfo } from '../../auth/types'

/** 保存系统外观主题设置。 */
const putThemeSetting = (payload: FormData) => {
Expand Down
64 changes: 64 additions & 0 deletions ui/src/api/admin/system/shared-resources/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { del, get, post, put } from '../../core/request'
import type { Dict, DynamicFormField, ModelItem, ModelPayload } from '@/api/types'

const prefix = '/system/shared/model'

/**
* 获得模型列表
* @params 参数 name, model_type, model_name
*/
const getModelList = (query?: Dict<unknown>) => {
return get<ModelItem[]>(prefix, query)
}

/** 创建 System 共享模型。 */
const postModel = (payload: ModelPayload) => {
return post<ModelPayload, ModelItem>(prefix, payload)
}

/** 获取包含认证信息的 System 共享模型详情。 */
const getModelDetail = (modelId: string) => {
return get<ModelItem>(`${prefix}/${modelId}`)
}

/** 更新 System 共享模型。 */
const putModel = (modelId: string, payload: Partial<ModelPayload>) => {
return put<Partial<ModelPayload>, ModelItem>(`${prefix}/${modelId}`, payload)
}

/** 删除 System 共享模型。 */
const deleteModel = (modelId: string) => {
return del<undefined, boolean>(`${prefix}/${modelId}`)
}

/** 获取 System 共享模型参数表单。 */
const getModelParamsForm = (modelId: string) => {
return get<DynamicFormField[]>(`${prefix}/${modelId}/model_params_form`)
}

/** 保存 System 共享模型参数表单。 */
const putModelParamsForm = (modelId: string, payload: DynamicFormField[]) => {
return put<DynamicFormField[], boolean>(`${prefix}/${modelId}/model_params_form`, payload)
}

/** 获取不包含认证信息的 System 共享模型元数据。 */
const getModelMeta = (modelId: string) => {
return get<ModelItem>(`${prefix}/${modelId}/meta`)
}

/** 暂停 System 共享本地模型下载。 */
const putPauseModelDownload = (modelId: string) => {
return put<undefined, boolean>(`${prefix}/${modelId}/pause_download`)
}

export default {
deleteModel,
getModelDetail,
getModelList,
getModelMeta,
getModelParamsForm,
postModel,
putModel,
putModelParamsForm,
putPauseModelDownload,
}
35 changes: 35 additions & 0 deletions ui/src/api/admin/tool-store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { get, post } from './core/request'
import type { Dict, ToolItem, ToolStoreResponse } from '@/api/types'

/** 获取系统内置工具。 */
const getInternalToolList = (query?: Dict<unknown>) => {
return get<ToolItem[]>('/workspace/internal/tool', query)
}

/** 获取工具商店列表。 */
const getStoreToolList = (query?: Dict<unknown>) => {
return get<ToolStoreResponse>('/workspace/store/tool', query)
}

/** 获取知识库模板商店列表。 */
const getStoreKnowledgeList = (query?: Dict<unknown>) => {
return get<unknown>('/workspace/store/knowledge_template', query)
}

/** 获取工作流工具模板商店列表。 */
const getStoreToolWorkflowList = (query?: Dict<unknown>) => {
return get<unknown>('/workspace/store/tool_workflow_template', query)
}

/** 获取应用模板商店列表。 */
const getStoreApplicationList = (query?: Dict<unknown>) => {
return get<unknown>('/workspace/store/application_template', query)
}

export default {
getInternalToolList,
getStoreApplicationList,
getStoreKnowledgeList,
getStoreToolList,
getStoreToolWorkflowList,
}
2 changes: 1 addition & 1 deletion ui/src/api/admin/workspace/application/application.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { get, post, put } from '../../core/request'
import type { ParamsPage, ResponsePage } from '../../core/types'
import type { ApplicationDetail, ApplicationFormPayload, Dict } from '@/api/types'
import { getWorkspaceId } from '@/utils/workspace-context'
import { getWorkspaceId } from '@/utils/resource-context'

const getPrefix = () => {
const workspaceId = getWorkspaceId()
Expand Down
2 changes: 1 addition & 1 deletion ui/src/api/admin/workspace/common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { get } from '../core/request'
import type { Dict, WorkspaceUserOption } from '@/api/types'
import { getWorkspaceId } from '@/utils/workspace-context'
import { getWorkspaceId } from '@/utils/resource-context'

/** 获取当前工作空间下的用户选项。 */
const getAllUsers = (query?: Dict<unknown>) => {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/api/admin/workspace/folder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { del, get, post, put } from '../core/request'
import type { Dict, FolderSource, FolderItem, FolderPayload } from '@/api/types'
import { getWorkspaceId } from '@/utils/workspace-context'
import { getWorkspaceId } from '@/utils/resource-context'

const getPrefix = (source: FolderSource) => {
const workspaceId = getWorkspaceId()
Expand Down
2 changes: 1 addition & 1 deletion ui/src/api/admin/workspace/knowledge/knowledge.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { del, get } from '../../core/request'
import type { ParamsPage, ResponsePage } from '../../core/types'
import type { Dict, KnowledgeItem } from '@/api/types'
import { getWorkspaceId } from '@/utils/workspace-context'
import { getWorkspaceId } from '@/utils/resource-context'

const getPrefix = () => {
const workspaceId = getWorkspaceId()
Expand Down
2 changes: 1 addition & 1 deletion ui/src/api/admin/workspace/model/model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { del, get, post, put } from '../../core/request'
import type { Dict, DynamicFormField, ModelPayload, ModelItem } from '@/api/types'
import { getWorkspaceId } from '@/utils/workspace-context'
import { getWorkspaceId } from '@/utils/resource-context'

const getPrefix = () => {
const workspaceId = getWorkspaceId()
Expand Down
2 changes: 1 addition & 1 deletion ui/src/api/admin/workspace/shared.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { get } from '../core/request'
import type { ParamsPage, ResponsePage } from '../core/types'
import type { Dict, KnowledgeItem, ModelItem, ToolItem } from '@/api/types'
import { getWorkspaceId } from '@/utils/workspace-context'
import { getWorkspaceId } from '@/utils/resource-context'

const getPrefix = () => {
const workspaceId = getWorkspaceId()
Expand Down
Loading
Loading