静态缓存页面 · 查看动态版本 · 登录
智柴网 登录 | 注册
← 返回话题
✨步子哥 @steper · 2025-11-15 14:36

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'

- 使用静态类,所有方法都是静态方法
- 统一的基础 URL:`/api/executor`

#### 2. 方法一:`sendMessage` - 直接发送消息

24:40:ui-vue3/src/api/direct-api-service.ts // Send task directly (direct execution mode) public static async sendMessage(query: InputMessage): Promise { return LlmCheckService.withLlmCheck(async () => { // Add Vue identification flag to distinguish from HTTP requests const requestBody = { ...query, isVueRequest: true, }

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() }) }

作用:
- 直接执行模式:发送用户输入到后端执行
- 请求标识:添加 `isVueRequest: true` 标识来源
- LLM 检查:通过 `LlmCheckService.withLlmCheck` 确保 LLM 已配置

原理:
1. 包装在 `withLlmCheck` 中,先检查 LLM 配置
2. 添加 `isVueRequest` 标识
3. POST 到 `/api/executor/execute`
4. 返回执行结果

#### 3. 方法二:`sendMessageWithDefaultPlan` - 使用默认计划模板

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 { // Use default plan template ID as toolName const toolName = 'default-plan-id-001000222'

// 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, uploadedFiles?: string[], uploadKey?: string ): Promise { return LlmCheckService.withLlmCheck(async () => { console.log('[DirectApiService] executeByToolName called with:', { toolName, replacementParams, uploadedFiles, uploadKey, })

const requestBody: Record = { toolName: toolName, isVueRequest: true, }

// 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 { return LlmCheckService.withLlmCheck(async () => { console.log('[DirectApiService] Stopping task for planId:', planId)

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( apiCall: () => Promise, options?: { showAlert?: boolean redirectToInit?: boolean } ): Promise { await this.ensureLlmConfigured(options) return apiCall() }
#### 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 配置检查
  • 支持参数替换和文件上传
  • 完善的错误处理和日志
该服务是前端与后端执行器交互的主要接口,封装了执行相关的 API 调用逻辑。

暂无表态