fix: replace AiGateway.embedBatch with direct LiteLLM cURL for upload indexing
AiGateway uses getenv(LITELLM_MASTER_KEY) + stream_context HTTP which was failing on the chloe virtualhost process. New dbnToolsLiteLLMEmbedBatch() helper mirrors dbnToolsCallGpuLlm — hardcoded URL + key, cURL-first, same pattern already proven for LLM calls. Removes AiGateway dependency from DeepResearchAgent entirely. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,6 @@ final class DbnDeepResearchAgent
|
||||
private const POOL_CAP = 30;
|
||||
|
||||
private DbnAzureOpenAiGateway $azure;
|
||||
private ?AiGateway $ai = null;
|
||||
private array $uploadVecs = [];
|
||||
private array $stepTimings = [];
|
||||
|
||||
@@ -50,9 +49,7 @@ final class DbnDeepResearchAgent
|
||||
dbnToolsBootCaveau();
|
||||
$aiPortalRoot = dbnToolsAiPortalRoot();
|
||||
require_once $aiPortalRoot . '/platform/includes/dbn_v6.php';
|
||||
require_once $aiPortalRoot . '/lib/ai/AiGateway.php';
|
||||
|
||||
$this->ai = new AiGateway();
|
||||
$this->uploadVecs = [];
|
||||
$this->stepTimings = [];
|
||||
|
||||
@@ -141,7 +138,7 @@ final class DbnDeepResearchAgent
|
||||
if ($uploadChunks) {
|
||||
try {
|
||||
$texts = array_map(fn(array $c) => $c['text'], $uploadChunks);
|
||||
$vecs = $this->ai->embedBatch($texts, 'nomic-embed-text');
|
||||
$vecs = dbnToolsLiteLLMEmbedBatch($texts);
|
||||
if (count($vecs) === count($uploadChunks)) {
|
||||
foreach ($uploadChunks as $i => $chunk) {
|
||||
$this->uploadVecs[] = [
|
||||
@@ -531,7 +528,7 @@ PROMPT;
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
$qVec = $this->ai->embed($question, 'nomic-embed-text');
|
||||
$qVec = dbnToolsLiteLLMEmbedBatch([$question])[0] ?? [];
|
||||
} catch (Throwable $e) {
|
||||
error_log('DBN deep research sub-Q embed failed: ' . $e->getMessage());
|
||||
return [];
|
||||
|
||||
@@ -676,3 +676,72 @@ function dbnToolsCallGpuLlm(array $messages, array $options = []): array
|
||||
}
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch-embed texts via LiteLLM /v1/embeddings using cURL.
|
||||
* Returns an array of float[] indexed by input position.
|
||||
*/
|
||||
function dbnToolsLiteLLMEmbedBatch(array $texts, string $model = 'nomic-embed-text', int $timeout = 60): array
|
||||
{
|
||||
if (empty($texts)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$url = 'http://10.0.1.10:4000/v1/embeddings';
|
||||
$apiKey = (string)(dbnToolsEnv('LITELLM_MASTER_KEY') ?: 'sk-bnl-litellm-26xR9mK4qvN3wL8sTj7pB2d');
|
||||
|
||||
$payload = json_encode(['model' => $model, 'input' => array_values($texts)], JSON_UNESCAPED_UNICODE);
|
||||
$headers = [
|
||||
'Content-Type: application/json',
|
||||
'Authorization: Bearer ' . $apiKey,
|
||||
];
|
||||
|
||||
if (function_exists('curl_init')) {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $payload,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
CURLOPT_TIMEOUT => $timeout,
|
||||
]);
|
||||
$response = curl_exec($ch);
|
||||
$code = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
|
||||
$err = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
throw new RuntimeException('LiteLLM embed request failed: ' . $err);
|
||||
}
|
||||
} else {
|
||||
$ctx = stream_context_create(['http' => [
|
||||
'method' => 'POST',
|
||||
'header' => implode("\r\n", $headers),
|
||||
'content' => $payload,
|
||||
'timeout' => $timeout,
|
||||
'ignore_errors' => true,
|
||||
]]);
|
||||
$response = @file_get_contents($url, false, $ctx);
|
||||
$code = 0;
|
||||
if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $m)) {
|
||||
$code = (int)$m[1];
|
||||
}
|
||||
if ($response === false) {
|
||||
throw new RuntimeException('LiteLLM embed request failed.');
|
||||
}
|
||||
}
|
||||
|
||||
$decoded = json_decode($response, true);
|
||||
if (!is_array($decoded)) {
|
||||
throw new RuntimeException('LiteLLM embed returned non-JSON.');
|
||||
}
|
||||
if ($code < 200 || $code >= 300) {
|
||||
$msg = $decoded['error']['message'] ?? ('HTTP ' . $code);
|
||||
throw new RuntimeException('LiteLLM embed error: ' . $msg);
|
||||
}
|
||||
|
||||
// OpenAI /v1/embeddings returns data[].embedding ordered by index
|
||||
$data = $decoded['data'] ?? [];
|
||||
usort($data, fn($a, $b) => ($a['index'] ?? 0) <=> ($b['index'] ?? 0));
|
||||
return array_map(fn($d) => $d['embedding'], $data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user