false, 'message' => '缺少必要参数(provider、model、messages)']); return; } if (!is_array($messages) || empty($messages)) { http_response_code(400); echo json_encode(['success' => false, 'message' => 'messages 必须是非空数组']); return; } // 获取供应商配置 $configRow = Config::getByKey('providers'); if (!$configRow) { http_response_code(500); echo json_encode(['success' => false, 'message' => '未找到供应商配置']); return; } $providers = json_decode($configRow['config_value'], true); if (!is_array($providers)) { http_response_code(500); echo json_encode(['success' => false, 'message' => '供应商配置格式错误']); return; } $providerKey = $provider; if (!isset($providers[$providerKey])) { http_response_code(400); echo json_encode(['success' => false, 'message' => '供应商不存在: ' . $providerKey]); return; } $providerConfig = $providers[$providerKey]; if (empty($providerConfig['enabled'])) { http_response_code(400); echo json_encode(['success' => false, 'message' => '供应商已禁用: ' . $providerKey]); return; } $models = $providerConfig['models'] ?? []; if (!empty($models) && !in_array($model, $models)) { http_response_code(400); echo json_encode(['success' => false, 'message' => '模型不在供应商支持列表中: ' . $model]); return; } // 非流式模式暂不支持 if (!$stream) { http_response_code(400); echo json_encode(['success' => false, 'message' => '当前仅支持流式响应']); return; } // 设置 SSE 响应头 header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header('Connection: keep-alive'); header('X-Accel-Buffering: no'); // 关闭输出缓冲 while (ob_get_level()) { ob_end_flush(); } $options = [ 'provider' => $providerConfig, 'systemPrompt' => $systemPrompt, 'thinkingMode' => (bool) $thinkingMode ]; try { AIService::streamChat($providerKey, $model, $messages, $options, function ($chunk, $type = 'content') { if ($type === 'thinking') { self::sendSSE(['thinking' => $chunk]); } else { self::sendSSE(['content' => $chunk]); } }); self::sendSSE('[DONE]'); } catch (\Throwable $e) { self::sendSSE(['type' => 'error', 'message' => $e->getMessage()]); } } private static function sendSSE($data): void { if (is_string($data)) { echo "data: " . $data . "\n\n"; } else { echo "data: " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n\n"; } flush(); } }