@thenajs/qdrant-client 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # @thenajs/qdrant-client
2
+
3
+ Cliente [Qdrant](https://qdrant.tech) nativo para [ThenaJS](https://github.com/thenajs/ThenaJS) —
4
+ implementação de `VectorStore` sobre a API REST. Sem SDK: `fetch` puro, herdando o retry e o
5
+ timeout do transporte do framework.
6
+
7
+ > **Requer Qdrant 1.10 ou superior.** O endpoint unificado `/points/query`, que o cliente usa
8
+ > para buscar, estreou nessa versão.
9
+
10
+ ## Instalação
11
+
12
+ ```bash
13
+ npm install @thenajs/qdrant-client
14
+ ```
15
+
16
+ ## Uso
17
+
18
+ ```ts
19
+ import { QdrantStore } from "@thenajs/qdrant-client";
20
+
21
+ export class MeuQdrant extends QdrantStore {
22
+ constructor() {
23
+ super({
24
+ url: "http://localhost:6333",
25
+ collection: "conhecimento",
26
+ datasets: ["persistent", "sessao"], // opcional: só para tipar
27
+ retry: { maxAttempts: 3, timeoutMs: 10_000 },
28
+ });
29
+ }
30
+ }
31
+ ```
32
+
33
+ Registre uma vez no config:
34
+
35
+ ```ts
36
+ export const config: ThenaConfig = {
37
+ memory: [MeuQdrant],
38
+ };
39
+ ```
40
+
41
+ E injete em qualquer agente:
42
+
43
+ ```ts
44
+ @Agent({
45
+ provider: LocalOllamaProvider, // o embed() dele gera os vetores
46
+ prompt: "./assistente.agent.md",
47
+ })
48
+ export class Assistente {
49
+ constructor(private readonly memory: VectorMemory) {}
50
+
51
+ async beforePrompt(prompt: string) {
52
+ const achados = await this.memory.recall("como faço deploy?", {
53
+ dataset: "persistent",
54
+ limit: 3,
55
+ });
56
+ return `${prompt}\n\n${achados.map((a) => `- ${a.text}`).join("\n")}`;
57
+ }
58
+ }
59
+ ```
60
+
61
+ Documentação completa em [thenajs.github.io](https://thenajs.github.io/concepts/memory.html).
62
+
63
+ ## Credentials
64
+
65
+ | Campo | Default | O que faz |
66
+ | --- | --- | --- |
67
+ | `url` | — | Endereço do Qdrant (obrigatório) |
68
+ | `apiKey` | — | Header `api-key`, para Qdrant Cloud |
69
+ | `collection` | `"thena_memory"` | A collection onde tudo é gravado |
70
+ | `datasets` | — | Nomes conhecidos, só para tipagem |
71
+ | `datasetField` | `"dataset"` | Campo do payload que particiona |
72
+ | `retry` | ligado | Política de retry/timeout do `HttpTransport` |
73
+
74
+ ## Uma collection, vários contextos
75
+
76
+ Os `datasets` **não** viram collections. São um campo do payload, com índice dedicado — que é a
77
+ recomendação do próprio Qdrant: muitas collections geram overhead de recursos, e o Qdrant Cloud
78
+ limita a 1000 por cluster.
79
+
80
+ Na prática isso significa que dá para buscar dentro de um contexto ou através de todos:
81
+
82
+ ```ts
83
+ await this.memory.recall("pergunta", { dataset: "persistent" }); // um dataset
84
+ await this.memory.recall("pergunta"); // o "default"
85
+ await this.memory.recall("pergunta", { dataset: null }); // todos
86
+ ```
87
+
88
+ Em Qdrant 1.12+, o índice é criado com `is_tenant: true`, que co-loca os pontos do mesmo dataset
89
+ em disco. Em versões anteriores o cliente cai para o índice `keyword` simples — funciona igual,
90
+ só sem essa otimização.
91
+
92
+ ## Licença
93
+
94
+ MIT
@@ -0,0 +1,3 @@
1
+ export { QdrantStore } from "./qdrant.store.js";
2
+ export type { QdrantCredentials } from "./qdrant.store.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { QdrantStore } from "./qdrant.store.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { VectorStore } from "@thenajs/core";
2
+ import type { CollectionOptions, VectorDocument, VectorMatch, VectorSearch, VectorSelector, VectorStoreCredentials } from "@thenajs/core";
3
+ export type QdrantCredentials = VectorStoreCredentials;
4
+ /**
5
+ * Cliente Qdrant nativo, sobre a API REST — sem SDK, só `fetch`, herdando
6
+ * retry e timeout do transporte do ThenaJS.
7
+ *
8
+ * Grava tudo numa **collection só** e separa contextos por um campo do payload
9
+ * (`dataset`), que é a recomendação do próprio Qdrant: muitas collections
10
+ * geram overhead de recursos, e o Qdrant Cloud limita a 1000 por cluster.
11
+ * O campo ganha um índice `keyword` com `is_tenant`, que co-localiza os pontos
12
+ * do mesmo dataset em disco.
13
+ *
14
+ * Requer **Qdrant 1.10 ou superior** — o endpoint unificado `/points/query`
15
+ * estreou nessa versão.
16
+ */
17
+ export declare class QdrantStore extends VectorStore {
18
+ private readonly url;
19
+ private readonly apiKey?;
20
+ private readonly collection;
21
+ /** Público para o `VectorMemory` saber qual campo particiona. */
22
+ readonly datasetField: string;
23
+ readonly datasets: readonly string[];
24
+ constructor(credentials: QdrantCredentials);
25
+ ensureCollection(options: CollectionOptions): Promise<void>;
26
+ /**
27
+ * Índice no campo que particiona os datasets.
28
+ *
29
+ * `is_tenant` faz o Qdrant agrupar em disco os pontos do mesmo dataset,
30
+ * trocando seeks aleatórios por leitura sequencial — mas a forma de objeto
31
+ * do `field_schema` só existe em versões mais novas. No 1.10 (nosso piso)
32
+ * apenas a forma abreviada é aceita, então caímos para ela: o índice sai
33
+ * igual, só sem a otimização de co-locação.
34
+ */
35
+ private criarIndiceDePartição;
36
+ collectionExists(): Promise<boolean>;
37
+ dropCollection(): Promise<void>;
38
+ upsert(docs: VectorDocument[]): Promise<void>;
39
+ search(params: VectorSearch): Promise<VectorMatch[]>;
40
+ remove(selector: VectorSelector): Promise<void>;
41
+ /**
42
+ * Traduz o `where` neutro (igualdade) para o formato do Qdrant. O
43
+ * `rawFilter` vence quando presente — é o escape hatch para o que a
44
+ * igualdade não cobre (ranges, geo, aninhamento).
45
+ */
46
+ private montarFiltro;
47
+ /** Uma chamada à API, já com auth, retry e a mensagem de erro do Qdrant. */
48
+ private chamar;
49
+ }
50
+ //# sourceMappingURL=qdrant.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qdrant.store.d.ts","sourceRoot":"","sources":["../src/qdrant.store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EACR,iBAAiB,EAEjB,cAAc,EACd,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,EACzB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,iBAAiB,GACzB,sBAAsB,CAAC;AAU3B;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAY,SAAQ,WAAW;IAExC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,iEAAiE;IACjE,SAAgB,YAAY,EAAE,MAAM,CAAC;IACrC,SAAyB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;gBAEzC,WAAW,EAAE,iBAAiB;IAUpC,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAajE;;;;;;;;OAQG;YACW,qBAAqB;IAgB7B,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAQpC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAI/B,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAkBpD,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBrD;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAepB,4EAA4E;YAC9D,MAAM;CAuBvB"}
@@ -0,0 +1,152 @@
1
+ import { VectorStore } from "@thenajs/core";
2
+ /** O shape neutro de distância → o nome que o Qdrant espera. */
3
+ const DISTANCIAS = {
4
+ cosine: "Cosine",
5
+ euclid: "Euclid",
6
+ dot: "Dot",
7
+ manhattan: "Manhattan",
8
+ };
9
+ /**
10
+ * Cliente Qdrant nativo, sobre a API REST — sem SDK, só `fetch`, herdando
11
+ * retry e timeout do transporte do ThenaJS.
12
+ *
13
+ * Grava tudo numa **collection só** e separa contextos por um campo do payload
14
+ * (`dataset`), que é a recomendação do próprio Qdrant: muitas collections
15
+ * geram overhead de recursos, e o Qdrant Cloud limita a 1000 por cluster.
16
+ * O campo ganha um índice `keyword` com `is_tenant`, que co-localiza os pontos
17
+ * do mesmo dataset em disco.
18
+ *
19
+ * Requer **Qdrant 1.10 ou superior** — o endpoint unificado `/points/query`
20
+ * estreou nessa versão.
21
+ */
22
+ export class QdrantStore extends VectorStore {
23
+ url;
24
+ apiKey;
25
+ collection;
26
+ /** Público para o `VectorMemory` saber qual campo particiona. */
27
+ datasetField;
28
+ datasets;
29
+ constructor(credentials) {
30
+ super();
31
+ this.configureTransport(credentials);
32
+ this.url = credentials.url.replace(/\/$/, "");
33
+ this.apiKey = credentials.apiKey;
34
+ this.collection = credentials.collection ?? "thena_memory";
35
+ this.datasetField = credentials.datasetField ?? "dataset";
36
+ this.datasets = credentials.datasets ?? [];
37
+ }
38
+ async ensureCollection(options) {
39
+ if (await this.collectionExists())
40
+ return;
41
+ await this.chamar(`/collections/${this.collection}`, "PUT", {
42
+ vectors: {
43
+ size: options.size,
44
+ distance: DISTANCIAS[options.distance ?? "cosine"],
45
+ },
46
+ });
47
+ await this.criarIndiceDePartição();
48
+ }
49
+ /**
50
+ * Índice no campo que particiona os datasets.
51
+ *
52
+ * `is_tenant` faz o Qdrant agrupar em disco os pontos do mesmo dataset,
53
+ * trocando seeks aleatórios por leitura sequencial — mas a forma de objeto
54
+ * do `field_schema` só existe em versões mais novas. No 1.10 (nosso piso)
55
+ * apenas a forma abreviada é aceita, então caímos para ela: o índice sai
56
+ * igual, só sem a otimização de co-locação.
57
+ */
58
+ async criarIndiceDePartição() {
59
+ const rota = `/collections/${this.collection}/index?wait=true`;
60
+ try {
61
+ await this.chamar(rota, "PUT", {
62
+ field_name: this.datasetField,
63
+ field_schema: { type: "keyword", is_tenant: true },
64
+ });
65
+ }
66
+ catch {
67
+ // Se a forma abreviada também falhar, aí é problema de verdade e sobe.
68
+ await this.chamar(rota, "PUT", {
69
+ field_name: this.datasetField,
70
+ field_schema: "keyword",
71
+ });
72
+ }
73
+ }
74
+ async collectionExists() {
75
+ const data = await this.chamar(`/collections/${this.collection}/exists`, "GET");
76
+ return Boolean(data?.result?.exists);
77
+ }
78
+ async dropCollection() {
79
+ await this.chamar(`/collections/${this.collection}`, "DELETE");
80
+ }
81
+ async upsert(docs) {
82
+ if (!docs.length)
83
+ return;
84
+ await this.chamar(`/collections/${this.collection}/points?wait=true`, "PUT", {
85
+ points: docs.map((d) => ({
86
+ id: d.id,
87
+ vector: d.vector,
88
+ payload: d.payload ?? {},
89
+ })),
90
+ });
91
+ }
92
+ async search(params) {
93
+ const data = await this.chamar(`/collections/${this.collection}/points/query`, "POST", {
94
+ query: params.vector,
95
+ limit: params.limit ?? 5,
96
+ filter: this.montarFiltro(params.where, params.rawFilter),
97
+ with_payload: params.withPayload ?? true,
98
+ score_threshold: params.scoreThreshold,
99
+ });
100
+ return (data?.result?.points ?? []).map((p) => ({
101
+ id: p.id,
102
+ score: p.score,
103
+ payload: p.payload ?? undefined,
104
+ }));
105
+ }
106
+ async remove(selector) {
107
+ const filter = this.montarFiltro(selector.where);
108
+ const corpo = selector.ids?.length
109
+ ? { points: selector.ids }
110
+ : filter
111
+ ? { filter }
112
+ : undefined;
113
+ // Sem seletor nenhum, apagar tudo seria destrutivo demais para ser implícito.
114
+ if (!corpo)
115
+ return;
116
+ await this.chamar(`/collections/${this.collection}/points/delete?wait=true`, "POST", corpo);
117
+ }
118
+ /**
119
+ * Traduz o `where` neutro (igualdade) para o formato do Qdrant. O
120
+ * `rawFilter` vence quando presente — é o escape hatch para o que a
121
+ * igualdade não cobre (ranges, geo, aninhamento).
122
+ */
123
+ montarFiltro(where, rawFilter) {
124
+ if (rawFilter !== undefined)
125
+ return rawFilter;
126
+ if (!where || !Object.keys(where).length)
127
+ return undefined;
128
+ return {
129
+ must: Object.entries(where).map(([key, value]) => ({
130
+ key,
131
+ match: { value },
132
+ })),
133
+ };
134
+ }
135
+ /** Uma chamada à API, já com auth, retry e a mensagem de erro do Qdrant. */
136
+ async chamar(caminho, method, body) {
137
+ const { response } = await this.request(`${this.url}${caminho}`, {
138
+ method,
139
+ headers: {
140
+ "Content-Type": "application/json",
141
+ ...(this.apiKey ? { "api-key": this.apiKey } : {}),
142
+ },
143
+ body: body === undefined ? undefined : JSON.stringify(body),
144
+ });
145
+ if (!response.ok) {
146
+ const detalhe = await response.text();
147
+ throw new Error(`Qdrant ${method} ${caminho} falhou (${response.status}): ${detalhe}`);
148
+ }
149
+ return (await response.json());
150
+ }
151
+ }
152
+ //# sourceMappingURL=qdrant.store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qdrant.store.js","sourceRoot":"","sources":["../src/qdrant.store.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@thenajs/qdrant-client",
3
+ "version": "0.4.0",
4
+ "description": "Cliente Qdrant nativo para ThenaJS — implementação de VectorStore sobre a API REST, sem SDK.",
5
+ "license": "MIT",
6
+ "author": "castroneto",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/thenajs/ThenaJS.git",
10
+ "directory": "packages/qdrant-client"
11
+ },
12
+ "homepage": "https://github.com/thenajs/ThenaJS#readme",
13
+ "keywords": ["thenajs", "qdrant", "vector-database", "rag", "embeddings"],
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": "./dist/index.js"
19
+ },
20
+ "files": ["dist", "README.md"],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "dependencies": {
25
+ "@thenajs/core": "^0.4.0"
26
+ }
27
+ }