Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ Artifacts are chunked and embedded into Qdrant using the same hybrid dense + BM2
| Variable | Default | Description |
|----------|---------|-------------|
| `QDRANT_MODE` | `managed` | `managed` = Docker-managed local Qdrant (default). `external` = user-provided remote or cloud Qdrant (no Docker management). |
| `QDRANT_URL` | *(none)* | Full URL of a remote/cloud Qdrant instance (e.g. `https://xyz.aws.cloud.qdrant.io:6333`). When set, takes precedence over `QDRANT_HOST` + `QDRANT_PORT`. Required (or set `QDRANT_HOST`) when `QDRANT_MODE=external`. |
| `QDRANT_URL` | *(none)* | Full URL of a remote/cloud Qdrant instance (e.g. `https://xyz.aws.cloud.qdrant.io:6333`). When set, takes precedence over `QDRANT_HOST` + `QDRANT_PORT`. Port is auto-inferred from the URL: explicit port if present (e.g. `:8443`), otherwise `443` for `https://` or `6333` for `http://`. Required (or set `QDRANT_HOST`) when `QDRANT_MODE=external`. |
| `QDRANT_PORT` | `16333` | Qdrant REST API port (managed mode, or external without `QDRANT_URL`) |
| `QDRANT_GRPC_PORT` | `16334` | Qdrant gRPC port (managed mode only) |
| `QDRANT_HOST` | `localhost` | Qdrant hostname (alternative to `QDRANT_URL` for non-HTTPS external instances) |
Expand Down
11 changes: 11 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ export const QDRANT_MODE: "managed" | "external" =
export const QDRANT_CONTAINER_NAME = "socraticode-qdrant";
export const QDRANT_IMAGE = "qdrant/qdrant:v1.17.0";

/**
* Resolve the Qdrant REST port from a URL.
* Returns the explicit port if present (e.g. `:8443`),
* otherwise `443` for `https://` or `6333` for `http://`.
*/
export function resolveQdrantPort(url: string): number {
const parsed = new URL(url);
if (parsed.port) return parseInt(parsed.port, 10);
return url.startsWith("https:") ? 443 : 6333;
}

// ── Ollama configuration ────────────────────────────────────────────────

export const OLLAMA_PORT = parseInt(process.env.OLLAMA_PORT || "11435", 10);
Expand Down
3 changes: 2 additions & 1 deletion src/services/qdrant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright (C) 2026 Giancarlo Erra - Altaire Limited
import { createHash } from "node:crypto";
import { QdrantClient } from "@qdrant/js-client-rest";
import { QDRANT_API_KEY, QDRANT_HOST, QDRANT_PORT, QDRANT_URL } from "../constants.js";
import { QDRANT_API_KEY, QDRANT_HOST, QDRANT_PORT, QDRANT_URL, resolveQdrantPort } from "../constants.js";
import type { ArtifactIndexState, CodeGraph, FileChunk, SearchResult } from "../types.js";
import { getEmbeddingConfig } from "./embedding-config.js";
import { generateEmbeddings, generateQueryEmbedding, prepareDocumentText } from "./embeddings.js";
Expand Down Expand Up @@ -43,6 +43,7 @@ function getClient(): QdrantClient {
QDRANT_URL
? {
url: QDRANT_URL,
port: resolveQdrantPort(QDRANT_URL),
...(QDRANT_API_KEY ? { apiKey: QDRANT_API_KEY } : {}),
checkCompatibility: false,
}
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/constants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
QDRANT_MODE,
QDRANT_PORT,
QDRANT_URL,
resolveQdrantPort,
SEARCH_DEFAULT_LIMIT,
SEARCH_MIN_SCORE,
SPECIAL_FILES,
Expand Down Expand Up @@ -371,3 +372,26 @@ describe("constants", () => {
});
});
});

describe("resolveQdrantPort", () => {
it("returns explicit port from URL", () => {
expect(resolveQdrantPort("https://qdrant.example.com:6333")).toBe(6333);
expect(resolveQdrantPort("http://localhost:8080")).toBe(8080);
expect(resolveQdrantPort("https://my-qdrant.com:8443")).toBe(8443);
});

it("defaults to 443 for HTTPS URLs without explicit port", () => {
expect(resolveQdrantPort("https://qdrant.example.com")).toBe(443);
expect(resolveQdrantPort("https://my-tunnel.trycloudflare.com")).toBe(443);
});

it("defaults to 6333 for HTTP URLs without explicit port", () => {
expect(resolveQdrantPort("http://localhost")).toBe(6333);
expect(resolveQdrantPort("http://192.168.1.100")).toBe(6333);
});

it("handles URLs with paths and query strings", () => {
expect(resolveQdrantPort("https://qdrant.example.com:9999/some/path")).toBe(9999);
expect(resolveQdrantPort("https://qdrant.example.com/some/path")).toBe(443);
});
});
Loading