Files
happy-life-star/docs/superpowers/plans/2026-05-23-ai-config-test-fix.md
peanut 89fc42819d feat: AI 场景路由、ASR 服务及前后端全链路同步
- 新增 AI 场景路由控制器和管理接口
- 新增 ASR 语音识别服务及前后端集成
- 同步 AI Runtime 客户端到 Web/小程序/Life-Script
- 完善 AI 配置测试修复和管理后台路由配置
- 新增数据库迁移脚本

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 13:25:21 +08:00

7.0 KiB
Raw Permalink Blame History

AI 配置管理接口测试修复实施计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 删除废弃的旧 AI 配置页面,在新系统测试对话框中增加非流式测试功能

Architecture: 路由已正确指向新系统 AiRoutingList.vue,只需删除旧文件残留并增强测试对话框。后端接口 testAiRuntime 已存在,只需在 API 层和 UI 层连接。

Tech Stack: Vue 3, Element Plus, TypeScript


前置确认:检查生产数据库配置

  • 在生产数据库上执行以下查询,确认 Dify provider 和 endpoint 状态
-- 检查 Dify provider
SELECT id, provider_code, provider_name, provider_type, base_url, is_enabled 
FROM t_ai_provider WHERE provider_code = 'dify_default';

-- 检查 Dify endpoints
SELECT id, endpoint_code, endpoint_name, provider_id, api_path, support_stream, is_enabled 
FROM t_ai_endpoint_config WHERE endpoint_code LIKE 'dify.%';

-- 检查场景绑定
SELECT id, scene_code, scene_name, endpoint_id, is_enabled, required_stream 
FROM t_ai_scene_binding WHERE is_enabled = 1;
  • 如果 Dify provider is_enabled = 0,执行:
UPDATE t_ai_provider SET is_enabled = 1 WHERE provider_code = 'dify_default';
  • 如果 Dify endpoints is_enabled = 0,执行:
UPDATE t_ai_endpoint_config SET is_enabled = 1 WHERE endpoint_code LIKE 'dify.%';

Task 1: 删除废弃的旧 AI 配置页面

Files:

  • Delete: web-admin/src/views/aiconfig/AiConfigList.vue

  • 删除旧页面文件

rm web-admin/src/views/aiconfig/AiConfigList.vue

Task 2: 在 API 层导出非流式测试函数

Files:

  • Modify: web-admin/src/api/aiconfig.ts

  • 确认 testAiRuntime 已存在(已确认在第 263 行)

export function testAiRuntime(data: AiRuntimeRequest) {
  return request({ url: '/ai/runtime/test', method: 'post', data })
}

已存在,无需修改。但需要确认 AiRoutingList.vue 中是否 import 了这个函数。

检查 web-admin/src/views/aiconfig/AiRoutingList.vue 的 import 语句(当前第 269-281 行):

  • 当前 import 了 streamAiRuntime没有 import testAiRuntime
  • 需要在 import 列表中添加 testAiRuntime

Task 3: 在测试对话框中增加非流式测试按钮

Files:

  • Modify: web-admin/src/views/aiconfig/AiRoutingList.vue

  • 在 import 中添加 testAiRuntime

修改第 269-281 行的 import 语句:

import {
  deleteAiEndpoint,
  deleteAiProvider,
  deleteAiScene,
  listAiCallLogs,
  listAiEndpoints,
  listAiProviders,
  listAiScenes,
  saveAiEndpoint,
  saveAiProvider,
  saveAiScene,
  streamAiRuntime,
  testAiRuntime          // ← 新增
} from '@/api/aiconfig'
  • 在测试对话框 footer 中增加「非流式测试」按钮

找到第 257-261 行的 <template #footer>,修改为:

<template #footer>
  <el-button @click="testDialog = false">关闭</el-button>
  <el-button :loading="testing" @click="submitNonStreamTest">非流式测试</el-button>
  <el-button type="primary" :loading="testing" @click="submitRuntimeTest">流式测试</el-button>
</template>
  • 添加 nonStreamResult 响应式变量

testResult 声明后面(第 296 行)添加:

const nonStreamResult = ref<AiRuntimeTestResponse | null>(null)
  • 实现 submitNonStreamTest 函数

submitRuntimeTest 函数(第 451 行)之前添加:

async function submitNonStreamTest() {
  let inputs: Record<string, any>
  try {
    inputs = JSON.parse(testInputsJson.value || '{}')
  } catch (error) {
    ElMessage.error('入参 JSON 格式不正确')
    return
  }
  testing.value = true
  try {
    const res = await testAiRuntime({ sceneCode: testForm.sceneCode, inputs })
    nonStreamResult.value = res.data as AiRuntimeTestResponse
    if (nonStreamResult.value.status === 'success') {
      ElMessage.success('非流式测试成功')
    } else {
      ElMessage.error(`测试失败: ${nonStreamResult.value.errorMessage || nonStreamResult.value.errorCode}`)
    }
    await loadAll()
  } catch (error: any) {
    nonStreamResult.value = {
      sceneCode: testForm.sceneCode,
      status: 'failed',
      errorMessage: error?.message || '非流式测试失败'
    } as AiRuntimeTestResponse
    ElMessage.error(error?.message || '非流式测试失败')
  } finally {
    testing.value = false
  }
}
  • 在测试对话框中展示非流式测试结果

submitRuntimeTest 相关的 <el-alert><pre> 展示块(第 250-256 行)之前,添加非流式测试结果的展示:

<el-alert
  v-if="nonStreamResult"
  :type="nonStreamResult.status === 'success' ? 'success' : 'error'"
  :title="nonStreamResult.status === 'success' ? '非流式测试成功' : '非流式测试失败'"
  show-icon
  :closable="false"
  style="margin-bottom: 12px;"
/>
<pre v-if="nonStreamResult" class="test-output">{{ nonStreamResult.output || nonStreamResult.errorMessage || '暂无输出' }}</pre>

<el-alert
  v-if="testResult"
  :type="testResult.status === 'success' ? 'success' : 'error'"
  :title="testResult.status === 'success' ? '流式测试成功' : '流式测试失败'"
  show-icon
/>
<pre v-if="testResult" class="test-output">{{ testResult.output || testResult.errorMessage || '暂无输出' }}</pre>
  • 在打开测试对话框时清空非流式结果

openRuntimeTest 函数(第 400-404 行)中添加:

function openRuntimeTest() {
  testForm.sceneCode = scenes.value.find(item => item.isEnabled === 1 && item.endpointId)?.sceneCode || scenes.value[0]?.sceneCode || ''
  testResult.value = null
  nonStreamResult.value = null    // ← 新增
  testDialog.value = true
}
  • 在 TypeScript 类型定义中确保 AiRuntimeTestResponse 包含所有必要字段

检查 web-admin/src/types/aiconfig.ts 中的 AiRuntimeTestResponse 定义,确保包含:

export interface AiRuntimeTestResponse {
  sceneCode: string
  status: 'success' | 'failed'
  output?: string
  streamChunks?: number
  durationMs?: number
  errorCode?: string
  errorMessage?: string
}

Task 4: 浏览器验证

  • 启动 web-admin 开发服务器
cd web-admin && npm run dev
  • 在浏览器中访问管理后台 http://localhost:5174/emotion-museum-admin/

  • 导航到「AI 配置管理」页面,确认旧页面已删除、新页面正常显示

  • 在「场景绑定」Tab 中点击「流式测试」按钮,确认测试对话框正常打开

  • 确认测试对话框中有两个按钮:「非流式测试」和「流式测试」

  • 选择一个场景(如 script_generate),输入入参 { "prompt": "请用一句中文回复测试成功。" },点击「非流式测试」,确认返回成功结果

  • 点击「流式测试」,确认流式输出正常

  • 确认浏览器 Console 中没有任何错误