feat: skip TLS verification for .lan domains in BrainService
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s

Adds a private http() helper that wraps Http::timeout() with
conditional withoutVerifying() for self-signed .lan certs behind
Traefik. Boot singleton auto-detects .lan URLs at construction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-03-03 10:53:00 +00:00
parent 20a0b584ae
commit b6823538d5
2 changed files with 30 additions and 8 deletions

View file

@ -74,11 +74,18 @@ class Boot extends ServiceProvider
$this->app->singleton(\Core\Mod\Agentic\Services\AgenticManager::class);
$this->app->singleton(\Core\Mod\Agentic\Services\BrainService::class, function ($app) {
$ollamaUrl = config('mcp.brain.ollama_url', 'http://localhost:11434');
$qdrantUrl = config('mcp.brain.qdrant_url', 'http://localhost:6334');
// Skip TLS verification for .lan domains (self-signed certs behind Traefik)
$verifySsl = ! (str_contains($ollamaUrl, '.lan') || str_contains($qdrantUrl, '.lan'));
return new \Core\Mod\Agentic\Services\BrainService(
ollamaUrl: config('mcp.brain.ollama_url', 'http://localhost:11434'),
qdrantUrl: config('mcp.brain.qdrant_url', 'http://localhost:6334'),
ollamaUrl: $ollamaUrl,
qdrantUrl: $qdrantUrl,
collection: config('mcp.brain.collection', 'openbrain'),
embeddingModel: config('mcp.brain.embedding_model', 'nomic-embed-text'),
verifySsl: $verifySsl,
);
});
}

View file

@ -20,8 +20,23 @@ class BrainService
private string $qdrantUrl = 'http://localhost:6334',
private string $collection = 'openbrain',
private string $embeddingModel = self::DEFAULT_MODEL,
private bool $verifySsl = true,
) {}
/**
* Create an HTTP client with common settings.
*/
private function http(int $timeout = 10): \Illuminate\Http\Client\PendingRequest
{
$request = Http::timeout($timeout);
if (! $this->verifySsl) {
$request = $request->withoutVerifying();
}
return $request;
}
/**
* Generate an embedding vector for the given text.
*
@ -31,7 +46,7 @@ class BrainService
*/
public function embed(string $text): array
{
$response = Http::timeout(30)
$response = $this->http(30)
->post("{$this->ollamaUrl}/api/embeddings", [
'model' => $this->embeddingModel,
'prompt' => $text,
@ -102,7 +117,7 @@ class BrainService
$filter['workspace_id'] = $workspaceId;
$qdrantFilter = $this->buildQdrantFilter($filter);
$response = Http::timeout(10)
$response = $this->http(10)
->post("{$this->qdrantUrl}/collections/{$this->collection}/points/search", [
'vector' => $vector,
'filter' => $qdrantFilter,
@ -156,11 +171,11 @@ class BrainService
*/
public function ensureCollection(): void
{
$response = Http::timeout(5)
$response = $this->http(5)
->get("{$this->qdrantUrl}/collections/{$this->collection}");
if ($response->status() === 404) {
$createResponse = Http::timeout(10)
$createResponse = $this->http(10)
->put("{$this->qdrantUrl}/collections/{$this->collection}", [
'vectors' => [
'size' => self::VECTOR_DIMENSION,
@ -236,7 +251,7 @@ class BrainService
*/
private function qdrantUpsert(array $points): void
{
$response = Http::timeout(10)
$response = $this->http(10)
->put("{$this->qdrantUrl}/collections/{$this->collection}/points", [
'points' => $points,
]);
@ -254,7 +269,7 @@ class BrainService
*/
private function qdrantDelete(array $ids): void
{
$response = Http::timeout(10)
$response = $this->http(10)
->post("{$this->qdrantUrl}/collections/{$this->collection}/points/delete", [
'points' => $ids,
]);