This commit is contained in:
elpresidank 2026-05-12 08:06:58 -05:00
parent e8c7a4f6e0
commit ffd97375a8
160 changed files with 6704 additions and 1895 deletions

View file

@ -16,6 +16,7 @@ import {
type DocumentEmbeddingsRequest,
type DocumentEmbeddingsResponse,
} from "@trustgraph/base";
import { makeProcessorProgram } from "@trustgraph/base";
import { QdrantDocEmbeddingsQuery } from "./qdrant-doc.js";
export class DocEmbeddingsQueryService extends FlowProcessor {
@ -26,7 +27,7 @@ export class DocEmbeddingsQueryService extends FlowProcessor {
this.query = new QdrantDocEmbeddingsQuery();
this.registerSpecification(
new ConsumerSpec<DocumentEmbeddingsRequest>(
ConsumerSpec.fromPromise<DocumentEmbeddingsRequest>(
"document-embeddings-request",
this.onMessage.bind(this),
),
@ -44,7 +45,7 @@ export class DocEmbeddingsQueryService extends FlowProcessor {
flowCtx: FlowContext,
): Promise<void> {
const requestId = properties.id;
if (!requestId) return;
if (requestId === undefined || requestId.length === 0) return;
const producer = flowCtx.flow.producer<DocumentEmbeddingsResponse>("document-embeddings-response");
const collection = msg.collection ?? "default";
@ -64,7 +65,7 @@ export class DocEmbeddingsQueryService extends FlowProcessor {
allChunks.push({
chunkId: match.chunkId,
score: match.score,
content: match.content,
...(match.content !== undefined ? { content: match.content } : {}),
});
}
}
@ -80,6 +81,11 @@ export class DocEmbeddingsQueryService extends FlowProcessor {
}
}
export const program = makeProcessorProgram({
id: "doc-embeddings-query",
make: (config) => new DocEmbeddingsQueryService(config),
});
export async function run(): Promise<void> {
await DocEmbeddingsQueryService.launch("doc-embeddings-query");
}

View file

@ -34,7 +34,10 @@ export class QdrantDocEmbeddingsQuery {
const url = config.url ?? process.env.QDRANT_URL ?? "http://localhost:6333";
const apiKey = config.apiKey ?? process.env.QDRANT_API_KEY;
this.client = new QdrantClient({ url, apiKey });
this.client = new QdrantClient({
url,
...(apiKey !== undefined && apiKey.length > 0 ? { apiKey } : {}),
});
console.log("[QdrantDocQuery] Query service initialized");
}
@ -42,7 +45,7 @@ export class QdrantDocEmbeddingsQuery {
async query(request: DocEmbeddingsQueryRequest): Promise<ChunkMatch[]> {
const { vector, user, collection, limit } = request;
if (!vector || vector.length === 0) {
if (vector.length === 0) {
return [];
}
@ -68,11 +71,11 @@ export class QdrantDocEmbeddingsQuery {
for (const point of searchResult) {
const payload = point.payload as Record<string, unknown> | undefined;
const chunkId = payload?.chunk_id as string | undefined;
if (chunkId) {
if (chunkId !== undefined && chunkId.length > 0) {
chunks.push({
chunkId,
score: point.score,
content: (payload?.content as string) ?? undefined,
...(typeof payload?.content === "string" ? { content: payload.content } : {}),
});
}
}

View file

@ -16,6 +16,7 @@ import {
type GraphEmbeddingsRequest,
type GraphEmbeddingsResponse,
} from "@trustgraph/base";
import { makeProcessorProgram } from "@trustgraph/base";
import { QdrantGraphEmbeddingsQuery } from "./qdrant-graph.js";
export class GraphEmbeddingsQueryService extends FlowProcessor {
@ -26,7 +27,7 @@ export class GraphEmbeddingsQueryService extends FlowProcessor {
this.query = new QdrantGraphEmbeddingsQuery();
this.registerSpecification(
new ConsumerSpec<GraphEmbeddingsRequest>(
ConsumerSpec.fromPromise<GraphEmbeddingsRequest>(
"graph-embeddings-request",
this.onMessage.bind(this),
),
@ -44,7 +45,7 @@ export class GraphEmbeddingsQueryService extends FlowProcessor {
flowCtx: FlowContext,
): Promise<void> {
const requestId = properties.id;
if (!requestId) return;
if (requestId === undefined || requestId.length === 0) return;
const producer = flowCtx.flow.producer<GraphEmbeddingsResponse>("graph-embeddings-response");
const user = msg.user ?? "default";
@ -79,6 +80,11 @@ export class GraphEmbeddingsQueryService extends FlowProcessor {
}
}
export const program = makeProcessorProgram({
id: "graph-embeddings-query",
make: (config) => new GraphEmbeddingsQueryService(config),
});
export async function run(): Promise<void> {
await GraphEmbeddingsQueryService.launch("graph-embeddings-query");
}

View file

@ -44,7 +44,10 @@ export class QdrantGraphEmbeddingsQuery {
const url = config.url ?? process.env.QDRANT_URL ?? "http://localhost:6333";
const apiKey = config.apiKey ?? process.env.QDRANT_API_KEY;
this.client = new QdrantClient({ url, apiKey });
this.client = new QdrantClient({
url,
...(apiKey !== undefined && apiKey.length > 0 ? { apiKey } : {}),
});
console.log("[QdrantGraphQuery] Query service initialized");
}
@ -52,7 +55,7 @@ export class QdrantGraphEmbeddingsQuery {
async query(request: GraphEmbeddingsQueryRequest): Promise<EntityMatch[]> {
const { vector, user, collection, limit } = request;
if (!vector || vector.length === 0) {
if (vector.length === 0) {
return [];
}
@ -82,7 +85,7 @@ export class QdrantGraphEmbeddingsQuery {
for (const point of searchResult) {
const payload = point.payload as Record<string, unknown> | undefined;
const entityValue = payload?.entity as string | undefined;
if (!entityValue) continue;
if (entityValue === undefined || entityValue.length === 0) continue;
// Deduplicate by entity value, keeping the highest score (results are
// already sorted by score descending from Qdrant)