direct-api-service.ts 文件解读
一、文件作用
DirectApiService 是直接执行模式的 API 服务类,用于与后端执行器 API 交互,支持直接执行任务、按工具名执行、停止任务等操作。
二、核心功能分析
#### 1. 基础配置
``20:21:ui-vue3/src/api/direct-api-service.ts
export class DirectApiService {
private static readonly BASE_URL = '/api/executor'
24:40:ui-vue3/src/api/direct-api-service.ts
// Send task directly (direct execution mode)
public static async sendMessage(query: InputMessage): Promise- 使用静态类,所有方法都是静态方法
- 统一的基础 URL:`/api/executor`
#### 2. 方法一:`sendMessage` - 直接发送消息
const response = await fetch(${this.BASE_URL}/execute, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestBody),
})
if (!response.ok) throw new Error(API request failed: ${response.status})
return await response.json()
})
}
43:53:ui-vue3/src/api/direct-api-service.ts
// Send task using executeByToolNameAsync with default plan template
public static async sendMessageWithDefaultPlan(query: InputMessage): Promise作用:
- 直接执行模式:发送用户输入到后端执行
- 请求标识:添加 `isVueRequest: true` 标识来源
- LLM 检查:通过 `LlmCheckService.withLlmCheck` 确保 LLM 已配置
原理:
1. 包装在 `withLlmCheck` 中,先检查 LLM 配置
2. 添加 `isVueRequest` 标识
3. POST 到 `/api/executor/execute`
4. 返回执行结果
#### 3. 方法二:`sendMessageWithDefaultPlan` - 使用默认计划模板
// Create replacement parameters with user input const replacementParams = { userRequirement: query.input, }
return this.executeByToolName(toolName, replacementParams, query.uploadedFiles, query.uploadKey) }
作用:
- 使用默认计划模板执行
- 将用户输入作为 `userRequirement` 参数
- 支持上传文件
原理:
- 硬编码默认模板 ID:`'default-plan-id-001000222'`
- 将用户输入包装为替换参数
- 调用统一的 `executeByToolName` 方法
#### 4. 方法三:`executeByToolName` - 统一执行方法(核心)
56:117:ui-vue3/src/api/direct-api-service.ts
// Unified method to execute by tool name (replaces both sendMessageWithDefaultPlan and PlanActApiService.executePlan)
public static async executeByToolName(
toolName: string,
replacementParams?: Record const requestBody: Record
// Include replacement parameters if present if (replacementParams && Object.keys(replacementParams).length > 0) { requestBody.replacementParams = replacementParams console.log('[DirectApiService] Including replacement params:', replacementParams) }
// Include uploaded files if present if (uploadedFiles && uploadedFiles.length > 0) { requestBody.uploadedFiles = uploadedFiles console.log('[DirectApiService] Including uploaded files:', uploadedFiles.length) }
// Include uploadKey if present if (uploadKey) { requestBody.uploadKey = uploadKey console.log('[DirectApiService] Including uploadKey:', uploadKey) }
console.log(
'[DirectApiService] Making request to:',
${this.BASE_URL}/executeByToolNameAsync
)
console.log('[DirectApiService] Request body:', requestBody)
const response = await fetch(${this.BASE_URL}/executeByToolNameAsync, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestBody),
})
console.log('[DirectApiService] Response status:', response.status, response.ok)
if (!response.ok) {
const errorText = await response.text()
console.error('[DirectApiService] Request failed:', errorText)
throw new Error(Failed to execute: ${response.status})
}
const result = await response.json() console.log('[DirectApiService] executeByToolName response:', result) return result }) }
作用:
- 统一执行入口:按工具名(计划模板 ID)执行
- 支持参数替换、文件上传、上传键
- 详细的日志记录
原理:
1. 参数构建:动态构建请求体
typescript
{
toolName: string, // 必需:工具/计划模板名称
isVueRequest: true, // 标识来源
replacementParams?: {...}, // 可选:参数替换
uploadedFiles?: string[], // 可选:上传的文件列表
uploadKey?: string // 可选:上传键
}
2. 条件包含:仅在有值时添加可选字段
3. 错误处理:检查响应状态,失败时抛出错误
4. 日志记录:记录关键步骤
#### 5. 方法四:`stopTask` - 停止运行中的任务
120:136:ui-vue3/src/api/direct-api-service.ts
// Stop a running task by plan ID
public static async stopTask(planId: string): Promise const response = await fetch(${this.BASE_URL}/stopTask/${planId}, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
})
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
throw new Error(errorData.error || Failed to stop task: ${response.status})
}
return await response.json() }) }
作用:
- 停止正在执行的任务
- 通过计划 ID 标识任务
原理:
- RESTful 设计:`POST /api/executor/stopTask/{planId}`
- 错误处理:尝试解析错误信息,失败时使用默认消息
### 三、设计模式与原理
#### 1. 装饰器模式:LLM 检查包装
typescript
LlmCheckService.withLlmCheck(async () => {
// API 调用代码
})
原理:
- 在执行前检查 LLM 配置
- 未配置时自动重定向到初始化页面
- 统一错误处理
`LlmCheckService.withLlmCheck` 实现:
108:117:ui-vue3/src/utils/llm-check.ts
public static async withLlmCheck#### 2. 请求标识:`isVueRequest` 标志
typescript
const requestBody = {
...query,
isVueRequest: true, // 标识这是来自 Vue 前端的请求
}
作用:
- 后端区分请求来源(Vue 前端 vs 其他客户端)
- 可能用于不同的处理逻辑或日志记录
#### 3. 统一执行接口:`executeByToolName`
设计思想:
- 统一入口:所有执行操作都通过此方法
- 参数化:通过参数控制行为
- 可扩展:易于添加新功能
### 四、使用场景
#### 场景 1:直接执行页面发送消息
typescript
// views/direct/index.vue
const { DirectApiService } = await import('@/api/direct-api-service')// 使用默认计划模板 response = await DirectApiService.sendMessageWithDefaultPlan(query)
// 或使用指定工具 response = await DirectApiService.executeByToolName(toolName, params)
#### 场景 2:停止任务
typescript
// stores/task.ts
const { DirectApiService } = await import('@/api/direct-api-service')
await DirectApiService.stopTask(planId)
#### 场景 3:计划执行
typescript
// api/plan-act-api-service.ts
return await DirectApiService.executeByToolName(
toolName,
replacementParams,
uploadedFiles,
uploadKey
)
### 五、架构优势
1. 统一接口:所有执行操作通过统一方法
2. 安全检查:自动检查 LLM 配置
3. 类型安全:TypeScript 类型定义
4. 错误处理:统一的错误处理机制
5. 日志记录:详细的调试日志
6. 可扩展性:易于添加新功能
### 六、数据流
用户输入
↓
DirectApiService.sendMessage()
↓
LlmCheckService.withLlmCheck() [检查 LLM 配置]
↓
构建请求体 { toolName, replacementParams, ... }
↓
POST /api/executor/executeByToolNameAsync
↓
后端处理
↓
返回执行结果
`七、总结
DirectApiService 是直接执行模式的核心服务类,提供:
- 直接执行:
sendMessage
默认计划执行: sendMessageWithDefaultPlan
统一执行接口: executeByToolName
任务控制: stopTask`
设计特点:
- 统一的执行接口
- 自动 LLM 配置检查
- 支持参数替换和文件上传
- 完善的错误处理和日志