📄 integrator.ts  •  8856 bytes
/**
 * CmdCode V0.5 - 意图识别与执行计划集成
 * Phase 2: 将 Intent + Planner 集成到主流程
 */
import { routeIntent, routeIntentAsync, type IntentResult } from './router'
import { getIntentLabel, getFastPathReason } from './classifier'
import { generatePlan, formatPlan, type ExecutionPlan } from '../planner'

/** 集成结果 */
export interface IntentPlanResult {
  intent: IntentResult
  plan?: ExecutionPlan
  shouldExecute: boolean
  response: string
  needsConfirmation: boolean
}

/** 交互模式 */
export type InteractionMode = 'auto' | 'confirm' | 'verbose'

/** 集成选项 */
export interface IntegratorOptions {
  mode: InteractionMode          // 交互模式
  autoSimple: boolean           // 简单任务自动执行
  showIntent: boolean           // 显示意图识别结果
  showPlan: boolean             // 显示执行计划
  maxPlanSteps: number          // 最大计划步骤数
}

/** 默认选项 */
export const DEFAULT_INTEGRATOR_OPTIONS: IntegratorOptions = {
  mode: 'auto',
  autoSimple: true,
  showIntent: true,
  showPlan: true,
  maxPlanSteps: 10,
}

/**
 * 处理用户输入的集成入口
 */
export function processUserInput(
  userInput: string,
  options: Partial<IntegratorOptions> = {}
): IntentPlanResult {
  const opts = { ...DEFAULT_INTEGRATOR_OPTIONS, ...options }
  
  // 1. 意图识别
  const { intent, decision } = routeIntent(userInput)
  
  // 2. 显示意图识别结果
  if (opts.showIntent) {
    console.log('')
    console.log(`  \x1b[38;5;240m🔍 意图识别\x1b[0m`)
    console.log(`  \x1b[38;5;220m类型\x1b[0m: ${getIntentLabel(intent.type)}`)
    console.log(`  \x1b[38;5;220m置信\x1b[0m: ${(intent.confidence * 100).toFixed(0)}%`)
    console.log(`  \x1b[38;5;220m通道\x1b[0m: ${intent.fastPath ? '⚡ 快速' : '📋 计划'}`)
    console.log(`  \x1b[38;5;220m路由\x1b[0m: ${decision.message || decision.handler}`)
  }
  
  // 3. 根据路由决定处理方式
  switch (decision.handler) {
    case 'chat':
      // 闲聊/解释 - 直接响应
      return {
        intent,
        shouldExecute: false,
        response: buildChatResponse(intent, userInput),
        needsConfirmation: false,
      }
    
    case 'skill':
      // 技能执行 - 标记需要技能处理器
      return {
        intent,
        shouldExecute: true,
        response: `🎯 检测到技能执行请求,正在准备执行...\n\n技能类型: ${intent.type}\n置信度: ${(intent.confidence * 100).toFixed(0)}%`,
        needsConfirmation: opts.mode === 'confirm',
      }
    
    case 'direct':
      // 直接执行 - 简单任务自动执行
      if (opts.autoSimple && intent.fastPath) {
        return {
          intent,
          shouldExecute: true,
          response: `⚡ 快速执行模式\n\n检测到简单任务,直接执行...\n\n任务: ${userInput}`,
          needsConfirmation: false,
        }
      }
      // 非简单任务生成计划
      const plan = generatePlan(userInput)
      return {
        intent,
        plan,
        shouldExecute: true,
        response: opts.showPlan ? formatPlan(plan) : '📋 已生成执行计划',
        needsConfirmation: true,
      }
    
    case 'planner':
      // 计划模式 - 生成并显示计划
      const execPlan = generatePlan(userInput)
      
      if (opts.showPlan) {
        console.log('')
        console.log(`  \x1b[38;5;240m📋 执行计划\x1b[0m`)
        console.log(formatPlan(execPlan))
      }
      
      return {
        intent,
        plan: execPlan,
        shouldExecute: true,
        response: opts.showPlan ? '' : `📋 已生成 ${execPlan.steps.length} 步执行计划`,
        needsConfirmation: true,
      }
    
    default:
      return {
        intent,
        shouldExecute: false,
        response: '❓ 无法识别的请求类型',
        needsConfirmation: false,
      }
  }
}

/**
 * 构建闲聊响应
 */
function buildChatResponse(intent: IntentResult, userInput: string): string {
  if (intent.type === 'explain') {
    // 解释类请求,让 LLM 处理
    return `📖 您想了解相关概念,请告诉我具体是哪个部分?`
  }
  
  // 闲聊响应
  const greetings = ['你好', 'hi', 'hello', 'hey']
  const isGreeting = greetings.some(g => userInput.toLowerCase().includes(g))
  
  if (isGreeting) {
    return `👋 你好!我是 CmdCode,一个专业的 AI 编程助手。\n\n我可以帮你:\n- 💻 编写代码\n- 🔧 调试修复\n- 📖 解释概念\n- 📁 文件操作\n\n有什么我可以帮你的吗?`
  }
  
  return `💬 收到,我会尽力帮助你。如果你有编程相关的问题,请直接告诉我!`
}

/**
 * 处理用户输入的集成入口(异步版本,含向量语义搜索)
 * 当关键词匹配置信度低时,使用向量搜索补充
 */
export async function processUserInputAsync(
  userInput: string,
  options: Partial<IntegratorOptions> = {}
): Promise<IntentPlanResult> {
  const opts = { ...DEFAULT_INTEGRATOR_OPTIONS, ...options }
  
  // 1. 意图识别(异步,关键词 + 向量)
  const { intent, decision } = await routeIntentAsync(userInput)
  
  // 2. 显示意图识别结果
  if (opts.showIntent) {
    console.log('')
    console.log(`  \x1b[38;5;240m🔍 意图识别\x1b[0m`)
    console.log(`  \x1b[38;5;220m类型\x1b[0m: ${getIntentLabel(intent.type)}`)
    console.log(`  \x1b[38;5;220m置信\x1b[0m: ${(intent.confidence * 100).toFixed(0)}%`)
    console.log(`  \x1b[38;5;220m通道\x1b[0m: ${intent.fastPath ? '⚡ 快速' : '📋 计划'}`)
    console.log(`  \x1b[38;5;220m路由\x1b[0m: ${decision.message || decision.handler}`)
    if (intent.vectorMatches) {
      console.log(`  \x1b[38;5;220m向量\x1b[0m: 匹配到 ${intent.vectorMatches.length} 条相似种子`)
    }
  }
  
  // 3. 根据路由决定处理方式(复用同步版本的逻辑)
  return processRouteDecision(intent, decision, userInput, opts)
}

/**
 * 处理路由决策(公共逻辑)
 */
function processRouteDecision(
  intent: IntentResult,
  decision: any,
  userInput: string,
  opts: IntegratorOptions
): IntentPlanResult {
  // 根据路由决定处理方式
  switch (decision.handler) {
    case 'chat':
      return {
        intent,
        shouldExecute: false,
        response: buildChatResponse(intent, userInput),
        needsConfirmation: false,
      }
    
    case 'skill':
      return {
        intent,
        shouldExecute: true,
        response: `🎯 检测到技能执行请求,正在准备执行...\n\n技能类型: ${intent.type}\n置信度: ${(intent.confidence * 100).toFixed(0)}%`,
        needsConfirmation: opts.mode === 'confirm',
      }
    
    case 'direct':
      if (opts.autoSimple && intent.fastPath) {
        return {
          intent,
          shouldExecute: true,
          response: `⚡ 快速执行模式\n\n检测到简单任务,直接执行...\n\n任务: ${userInput}`,
          needsConfirmation: false,
        }
      }
      const plan = generatePlan(userInput)
      return {
        intent,
        plan,
        shouldExecute: true,
        response: opts.showPlan ? formatPlan(plan) : '📋 已生成执行计划',
        needsConfirmation: true,
      }
    
    case 'planner':
      const execPlan = generatePlan(userInput)
      
      if (opts.showPlan) {
        console.log('')
        console.log(`  \x1b[38;5;240m📋 执行计划\x1b[0m`)
        console.log(formatPlan(execPlan))
      }
      
      return {
        intent,
        plan: execPlan,
        shouldExecute: true,
        response: opts.showPlan ? '' : `📋 已生成 ${execPlan.steps.length} 步执行计划`,
        needsConfirmation: true,
      }
    
    default:
      return {
        intent,
        shouldExecute: false,
        response: '❓ 无法识别的请求类型',
        needsConfirmation: false,
      }
  }
}

/**
 * 确认用户选择
 */
export function parseConfirmation(
  response: string,
  plan: ExecutionPlan
): 'execute' | 'modify' | 'partial' | 'cancel' | null {
  const lower = response.trim().toLowerCase()
  
  if (['1', '确认', '执行', 'y', 'yes', 'execute'].includes(lower)) {
    return 'execute'
  }
  if (['2', '修改', 'modify'].includes(lower)) {
    return 'modify'
  }
  if (['3', '部分', 'partial'].includes(lower)) {
    return 'partial'
  }
  if (['4', '取消', 'cancel', 'no', 'n'].includes(lower)) {
    return 'cancel'
  }
  
  return null
}

/**
 * 获取交互建议
 */
export function getInteractionAdvice(mode: InteractionMode): string {
  switch (mode) {
    case 'auto':
      return '⚡ 自动模式:简单任务自动执行,复杂任务需要确认'
    case 'confirm':
      return '🔔 确认模式:所有任务执行前都需要确认'
    case 'verbose':
      return '📝 详细模式:显示所有中间结果'
  }
}