@adonis-agora/agent 0.1.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/LICENSE +21 -0
- package/dist/configure.d.ts +18 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +29 -0
- package/dist/configure.js.map +1 -0
- package/dist/providers/agent_provider.d.ts +25 -0
- package/dist/providers/agent_provider.d.ts.map +1 -0
- package/dist/providers/agent_provider.js +511 -0
- package/dist/providers/agent_provider.js.map +1 -0
- package/dist/src/actor-resolver.d.ts +41 -0
- package/dist/src/actor-resolver.d.ts.map +1 -0
- package/dist/src/agent-deps-factory.d.ts +59 -0
- package/dist/src/agent-deps-factory.d.ts.map +1 -0
- package/dist/src/agent-deps-factory.js +111 -0
- package/dist/src/agent-deps-factory.js.map +1 -0
- package/dist/src/agent-deps.d.ts +42 -0
- package/dist/src/agent-deps.d.ts.map +1 -0
- package/dist/src/agent-deps.js +5 -0
- package/dist/src/agent-deps.js.map +1 -0
- package/dist/src/agent-loop.d.ts +101 -0
- package/dist/src/agent-loop.d.ts.map +1 -0
- package/dist/src/agent-loop.js +396 -0
- package/dist/src/agent-loop.js.map +1 -0
- package/dist/src/agent-registry.d.ts +10 -0
- package/dist/src/agent-registry.d.ts.map +1 -0
- package/dist/src/agent-service.d.ts +50 -0
- package/dist/src/agent-service.d.ts.map +1 -0
- package/dist/src/agent-service.js +82 -0
- package/dist/src/agent-service.js.map +1 -0
- package/dist/src/ai-sdk/ai-sdk-model.d.ts +17 -0
- package/dist/src/ai-sdk/ai-sdk-model.d.ts.map +1 -0
- package/dist/src/ai-sdk/ai-sdk-model.js +263 -0
- package/dist/src/ai-sdk/ai-sdk-model.js.map +1 -0
- package/dist/src/ai-sdk/index.d.ts +2 -0
- package/dist/src/ai-sdk/index.d.ts.map +1 -0
- package/dist/src/ai-tool-ref.d.ts +79 -0
- package/dist/src/ai-tool-ref.d.ts.map +1 -0
- package/dist/src/ai-tool-ref.js +81 -0
- package/dist/src/ai-tool-ref.js.map +1 -0
- package/dist/src/authorizer.d.ts +18 -0
- package/dist/src/authorizer.d.ts.map +1 -0
- package/dist/src/authz/authz-tool-authorizer.d.ts +85 -0
- package/dist/src/authz/authz-tool-authorizer.d.ts.map +1 -0
- package/dist/src/authz/authz-tool-authorizer.js +63 -0
- package/dist/src/authz/authz-tool-authorizer.js.map +1 -0
- package/dist/src/authz/index.d.ts +3 -0
- package/dist/src/authz/index.d.ts.map +1 -0
- package/dist/src/authz/index.js +2 -0
- package/dist/src/authz/index.js.map +1 -0
- package/dist/src/data/data-tool.d.ts +64 -0
- package/dist/src/data/data-tool.d.ts.map +1 -0
- package/dist/src/data/data-tool.js +146 -0
- package/dist/src/data/data-tool.js.map +1 -0
- package/dist/src/data/index.d.ts +7 -0
- package/dist/src/data/index.d.ts.map +1 -0
- package/dist/src/data/index.js +7 -0
- package/dist/src/data/index.js.map +1 -0
- package/dist/src/data/limit.d.ts +12 -0
- package/dist/src/data/limit.d.ts.map +1 -0
- package/dist/src/data/limit.js +29 -0
- package/dist/src/data/limit.js.map +1 -0
- package/dist/src/data/parser.d.ts +27 -0
- package/dist/src/data/parser.d.ts.map +1 -0
- package/dist/src/data/parser.js +18 -0
- package/dist/src/data/parser.js.map +1 -0
- package/dist/src/data/sql-validator.d.ts +37 -0
- package/dist/src/data/sql-validator.d.ts.map +1 -0
- package/dist/src/data/sql-validator.js +92 -0
- package/dist/src/data/sql-validator.js.map +1 -0
- package/dist/src/data/table-access.d.ts +40 -0
- package/dist/src/data/table-access.d.ts.map +1 -0
- package/dist/src/data/table-access.js +41 -0
- package/dist/src/data/table-access.js.map +1 -0
- package/dist/src/data/tenant-scope.d.ts +39 -0
- package/dist/src/data/tenant-scope.d.ts.map +1 -0
- package/dist/src/data/tenant-scope.js +126 -0
- package/dist/src/data/tenant-scope.js.map +1 -0
- package/dist/src/define_config.d.ts +153 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +7 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/diagnostics.d.ts +82 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +50 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/durable/agent-run-context.d.ts +24 -0
- package/dist/src/durable/agent-run-context.d.ts.map +1 -0
- package/dist/src/durable/agent-run-context.js +17 -0
- package/dist/src/durable/agent-run-context.js.map +1 -0
- package/dist/src/durable/agent-run-workflow.d.ts +37 -0
- package/dist/src/durable/agent-run-workflow.d.ts.map +1 -0
- package/dist/src/durable/agent-run-workflow.js +128 -0
- package/dist/src/durable/agent-run-workflow.js.map +1 -0
- package/dist/src/durable/durable-agent-runner.d.ts +25 -0
- package/dist/src/durable/durable-agent-runner.d.ts.map +1 -0
- package/dist/src/durable/durable-agent-runner.js +59 -0
- package/dist/src/durable/durable-agent-runner.js.map +1 -0
- package/dist/src/durable/index.d.ts +17 -0
- package/dist/src/durable/index.d.ts.map +1 -0
- package/dist/src/durable/index.js +20 -0
- package/dist/src/durable/index.js.map +1 -0
- package/dist/src/index.d.ts +55 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +45 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/personas.d.ts +7 -0
- package/dist/src/personas.d.ts.map +1 -0
- package/dist/src/rag/chunk.d.ts +14 -0
- package/dist/src/rag/chunk.d.ts.map +1 -0
- package/dist/src/rag/chunk.js +42 -0
- package/dist/src/rag/chunk.js.map +1 -0
- package/dist/src/rag/embedding-retriever.d.ts +15 -0
- package/dist/src/rag/embedding-retriever.d.ts.map +1 -0
- package/dist/src/rag/embedding-retriever.js +24 -0
- package/dist/src/rag/embedding-retriever.js.map +1 -0
- package/dist/src/rag/filter.d.ts +6 -0
- package/dist/src/rag/filter.d.ts.map +1 -0
- package/dist/src/rag/filter.js +11 -0
- package/dist/src/rag/filter.js.map +1 -0
- package/dist/src/rag/index.d.ts +8 -0
- package/dist/src/rag/index.d.ts.map +1 -0
- package/dist/src/rag/index.js +8 -0
- package/dist/src/rag/index.js.map +1 -0
- package/dist/src/rag/ingest.d.ts +33 -0
- package/dist/src/rag/ingest.d.ts.map +1 -0
- package/dist/src/rag/ingest.js +37 -0
- package/dist/src/rag/ingest.js.map +1 -0
- package/dist/src/rag/memory-vector-store.d.ts +16 -0
- package/dist/src/rag/memory-vector-store.d.ts.map +1 -0
- package/dist/src/rag/memory-vector-store.js +70 -0
- package/dist/src/rag/memory-vector-store.js.map +1 -0
- package/dist/src/rag/pg-vector-store.d.ts +84 -0
- package/dist/src/rag/pg-vector-store.d.ts.map +1 -0
- package/dist/src/rag/pg-vector-store.js +220 -0
- package/dist/src/rag/pg-vector-store.js.map +1 -0
- package/dist/src/rag/vector-store.d.ts +47 -0
- package/dist/src/rag/vector-store.d.ts.map +1 -0
- package/dist/src/rag/vector-store.js +5 -0
- package/dist/src/rag/vector-store.js.map +1 -0
- package/dist/src/rag-media/diagnostics.d.ts +43 -0
- package/dist/src/rag-media/diagnostics.d.ts.map +1 -0
- package/dist/src/rag-media/diagnostics.js +36 -0
- package/dist/src/rag-media/diagnostics.js.map +1 -0
- package/dist/src/rag-media/index.d.ts +5 -0
- package/dist/src/rag-media/index.d.ts.map +1 -0
- package/dist/src/rag-media/index.js +5 -0
- package/dist/src/rag-media/index.js.map +1 -0
- package/dist/src/rag-media/media-events.d.ts +23 -0
- package/dist/src/rag-media/media-events.d.ts.map +1 -0
- package/dist/src/rag-media/media-events.js +28 -0
- package/dist/src/rag-media/media-events.js.map +1 -0
- package/dist/src/rag-media/media-rag-ingestion.d.ts +155 -0
- package/dist/src/rag-media/media-rag-ingestion.d.ts.map +1 -0
- package/dist/src/rag-media/media-rag-ingestion.js +204 -0
- package/dist/src/rag-media/media-rag-ingestion.js.map +1 -0
- package/dist/src/rag-media/text-extractor.d.ts +46 -0
- package/dist/src/rag-media/text-extractor.d.ts.map +1 -0
- package/dist/src/rag-media/text-extractor.js +92 -0
- package/dist/src/rag-media/text-extractor.js.map +1 -0
- package/dist/src/redis-stream-client.d.ts +29 -0
- package/dist/src/redis-stream-client.d.ts.map +1 -0
- package/dist/src/redis-stream-client.js +2 -0
- package/dist/src/redis-stream-client.js.map +1 -0
- package/dist/src/redis-token-stream-sink.d.ts +36 -0
- package/dist/src/redis-token-stream-sink.d.ts.map +1 -0
- package/dist/src/redis-token-stream-sink.js +94 -0
- package/dist/src/redis-token-stream-sink.js.map +1 -0
- package/dist/src/runners/inline-agent-runner.d.ts +26 -0
- package/dist/src/runners/inline-agent-runner.d.ts.map +1 -0
- package/dist/src/runners/inline-agent-runner.js +85 -0
- package/dist/src/runners/inline-agent-runner.js.map +1 -0
- package/dist/src/spi/actor-directory.d.ts +23 -0
- package/dist/src/spi/actor-directory.d.ts.map +1 -0
- package/dist/src/spi/actor-directory.js +2 -0
- package/dist/src/spi/actor-directory.js.map +1 -0
- package/dist/src/spi/actor-resolver.d.ts +18 -0
- package/dist/src/spi/actor-resolver.d.ts.map +1 -0
- package/dist/src/spi/agent-runner.d.ts +20 -0
- package/dist/src/spi/agent-runner.d.ts.map +1 -0
- package/dist/src/spi/agent-store.d.ts +104 -0
- package/dist/src/spi/agent-store.d.ts.map +1 -0
- package/dist/src/spi/agent-store.js +2 -0
- package/dist/src/spi/agent-store.js.map +1 -0
- package/dist/src/spi/attachment-staging.d.ts +27 -0
- package/dist/src/spi/attachment-staging.d.ts.map +1 -0
- package/dist/src/spi/attachment-staging.js +2 -0
- package/dist/src/spi/attachment-staging.js.map +1 -0
- package/dist/src/spi/embedding-provider.d.ts +12 -0
- package/dist/src/spi/embedding-provider.d.ts.map +1 -0
- package/dist/src/spi/embedding-provider.js +2 -0
- package/dist/src/spi/embedding-provider.js.map +1 -0
- package/dist/src/spi/governance-queries.d.ts +215 -0
- package/dist/src/spi/governance-queries.d.ts.map +1 -0
- package/dist/src/spi/governance-queries.js +15 -0
- package/dist/src/spi/governance-queries.js.map +1 -0
- package/dist/src/spi/model-provider.d.ts +41 -0
- package/dist/src/spi/model-provider.d.ts.map +1 -0
- package/dist/src/spi/pricing-store.d.ts +45 -0
- package/dist/src/spi/pricing-store.d.ts.map +1 -0
- package/dist/src/spi/pricing-store.js +24 -0
- package/dist/src/spi/pricing-store.js.map +1 -0
- package/dist/src/spi/quota-store.d.ts +7 -0
- package/dist/src/spi/quota-store.d.ts.map +1 -0
- package/dist/src/spi/reranker.d.ts +17 -0
- package/dist/src/spi/reranker.d.ts.map +1 -0
- package/dist/src/spi/reranker.js +2 -0
- package/dist/src/spi/reranker.js.map +1 -0
- package/dist/src/spi/retriever.d.ts +28 -0
- package/dist/src/spi/retriever.d.ts.map +1 -0
- package/dist/src/spi/retriever.js +11 -0
- package/dist/src/spi/retriever.js.map +1 -0
- package/dist/src/spi/roles-policy.d.ts +11 -0
- package/dist/src/spi/roles-policy.d.ts.map +1 -0
- package/dist/src/spi/tool.d.ts +21 -0
- package/dist/src/spi/tool.d.ts.map +1 -0
- package/dist/src/stores/factory.d.ts +363 -0
- package/dist/src/stores/factory.d.ts.map +1 -0
- package/dist/src/stores/factory.js +341 -0
- package/dist/src/stores/factory.js.map +1 -0
- package/dist/src/stores/ledger-quota.d.ts +23 -0
- package/dist/src/stores/ledger-quota.d.ts.map +1 -0
- package/dist/src/stores/ledger-quota.js +32 -0
- package/dist/src/stores/ledger-quota.js.map +1 -0
- package/dist/src/stores/lucid-governance-queries.d.ts +73 -0
- package/dist/src/stores/lucid-governance-queries.d.ts.map +1 -0
- package/dist/src/stores/lucid-governance-queries.js +510 -0
- package/dist/src/stores/lucid-governance-queries.js.map +1 -0
- package/dist/src/stores/lucid-pricing.d.ts +20 -0
- package/dist/src/stores/lucid-pricing.d.ts.map +1 -0
- package/dist/src/stores/lucid-pricing.js +67 -0
- package/dist/src/stores/lucid-pricing.js.map +1 -0
- package/dist/src/stores/lucid-schema.d.ts +37 -0
- package/dist/src/stores/lucid-schema.d.ts.map +1 -0
- package/dist/src/stores/lucid-schema.js +139 -0
- package/dist/src/stores/lucid-schema.js.map +1 -0
- package/dist/src/stores/lucid.d.ts +73 -0
- package/dist/src/stores/lucid.d.ts.map +1 -0
- package/dist/src/stores/lucid.js +400 -0
- package/dist/src/stores/lucid.js.map +1 -0
- package/dist/src/telescope/dashboard.d.ts +21 -0
- package/dist/src/telescope/dashboard.d.ts.map +1 -0
- package/dist/src/telescope/dashboard.js +140 -0
- package/dist/src/telescope/dashboard.js.map +1 -0
- package/dist/src/telescope/data-providers.d.ts +39 -0
- package/dist/src/telescope/data-providers.d.ts.map +1 -0
- package/dist/src/telescope/data-providers.js +345 -0
- package/dist/src/telescope/data-providers.js.map +1 -0
- package/dist/src/telescope/extension.d.ts +27 -0
- package/dist/src/telescope/extension.d.ts.map +1 -0
- package/dist/src/telescope/extension.js +45 -0
- package/dist/src/telescope/extension.js.map +1 -0
- package/dist/src/telescope/index.d.ts +5 -0
- package/dist/src/telescope/index.d.ts.map +1 -0
- package/dist/src/telescope/index.js +4 -0
- package/dist/src/telescope/index.js.map +1 -0
- package/dist/src/telescope/telescope-sdk.d.ts +126 -0
- package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
- package/dist/src/telescope/telescope-sdk.js +15 -0
- package/dist/src/telescope/telescope-sdk.js.map +1 -0
- package/dist/src/testing/fake-embedding-provider.d.ts +37 -0
- package/dist/src/testing/fake-embedding-provider.d.ts.map +1 -0
- package/dist/src/testing/fake-embedding-provider.js +67 -0
- package/dist/src/testing/fake-embedding-provider.js.map +1 -0
- package/dist/src/testing/fake-media.d.ts +44 -0
- package/dist/src/testing/fake-media.d.ts.map +1 -0
- package/dist/src/testing/fake-media.js +69 -0
- package/dist/src/testing/fake-media.js.map +1 -0
- package/dist/src/testing/fake-model-provider.d.ts +29 -0
- package/dist/src/testing/fake-model-provider.d.ts.map +1 -0
- package/dist/src/testing/in-memory-actor-directory.d.ts +14 -0
- package/dist/src/testing/in-memory-actor-directory.d.ts.map +1 -0
- package/dist/src/testing/in-memory-actor-directory.js +27 -0
- package/dist/src/testing/in-memory-actor-directory.js.map +1 -0
- package/dist/src/testing/in-memory-attachment-staging.d.ts +22 -0
- package/dist/src/testing/in-memory-attachment-staging.d.ts.map +1 -0
- package/dist/src/testing/in-memory-attachment-staging.js +28 -0
- package/dist/src/testing/in-memory-attachment-staging.js.map +1 -0
- package/dist/src/testing/in-memory-governance-queries.d.ts +34 -0
- package/dist/src/testing/in-memory-governance-queries.d.ts.map +1 -0
- package/dist/src/testing/in-memory-governance-queries.js +373 -0
- package/dist/src/testing/in-memory-governance-queries.js.map +1 -0
- package/dist/src/testing/in-memory-pricing.d.ts +13 -0
- package/dist/src/testing/in-memory-pricing.d.ts.map +1 -0
- package/dist/src/testing/in-memory-pricing.js +27 -0
- package/dist/src/testing/in-memory-pricing.js.map +1 -0
- package/dist/src/testing/in-memory-quota.d.ts +11 -0
- package/dist/src/testing/in-memory-quota.d.ts.map +1 -0
- package/dist/src/testing/in-memory-sink.d.ts +14 -0
- package/dist/src/testing/in-memory-sink.d.ts.map +1 -0
- package/dist/src/testing/in-memory-store.d.ts +119 -0
- package/dist/src/testing/in-memory-store.d.ts.map +1 -0
- package/dist/src/testing/in-memory-store.js +317 -0
- package/dist/src/testing/in-memory-store.js.map +1 -0
- package/dist/src/testing/index.d.ts +11 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +11 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/tool-discovery.d.ts +35 -0
- package/dist/src/tool-discovery.d.ts.map +1 -0
- package/dist/src/tool-registry.d.ts +45 -0
- package/dist/src/tool-registry.d.ts.map +1 -0
- package/dist/src/tool-retry.d.ts +56 -0
- package/dist/src/tool-retry.d.ts.map +1 -0
- package/dist/src/tool-retry.js +95 -0
- package/dist/src/tool-retry.js.map +1 -0
- package/dist/src/types.d.ts +222 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/stubs/config/agent.stub +55 -0
- package/dist/stubs/database/migrations/create_agent_rag_chunks.stub +41 -0
- package/dist/stubs/database/migrations/create_agent_run_tracking.stub +80 -0
- package/dist/stubs/database/migrations/create_agent_tables.stub +113 -0
- package/package.json +174 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { EmbeddingProvider } from '../spi/embedding-provider.js';
|
|
2
|
+
import { type ChunkOptions } from './chunk.js';
|
|
3
|
+
import type { VectorStore } from './vector-store.js';
|
|
4
|
+
/** A source document to ingest. `id` scopes the chunk ids (`${id}#${n}`); `source` is the citation. */
|
|
5
|
+
export interface IngestDocument {
|
|
6
|
+
id: string;
|
|
7
|
+
text: string;
|
|
8
|
+
source?: string;
|
|
9
|
+
metadata?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/** A chunked, not-yet-embedded record. */
|
|
12
|
+
export interface ChunkRecord {
|
|
13
|
+
id: string;
|
|
14
|
+
text: string;
|
|
15
|
+
source?: string;
|
|
16
|
+
metadata?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface IngestChunksOptions {
|
|
19
|
+
embedder: EmbeddingProvider;
|
|
20
|
+
store: VectorStore;
|
|
21
|
+
}
|
|
22
|
+
export interface IngestOptions extends ChunkOptions, IngestChunksOptions {
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Split documents into chunk records. Chunk ids are `${doc.id}#${index}`, so re-chunking the same
|
|
26
|
+
* document produces the same ids (upsert overwrites in place rather than duplicating).
|
|
27
|
+
*/
|
|
28
|
+
export declare function chunkDocuments(documents: IngestDocument[], options?: ChunkOptions): ChunkRecord[];
|
|
29
|
+
/** Embed pre-chunked records (one batched `embed`) and upsert them. Returns the record count. */
|
|
30
|
+
export declare function ingestChunks(chunks: ChunkRecord[], options: IngestChunksOptions): Promise<number>;
|
|
31
|
+
/** Chunk → embed → upsert in one call. Returns the number of chunks indexed. */
|
|
32
|
+
export declare function ingestDocuments(documents: IngestDocument[], options: IngestOptions): Promise<number>;
|
|
33
|
+
//# sourceMappingURL=ingest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../../src/rag/ingest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,KAAK,YAAY,EAAa,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEnE,uGAAuG;AACvG,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY,EAAE,mBAAmB;CAAG;AAE3E;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,cAAc,EAAE,EAC3B,OAAO,GAAE,YAAiB,GACzB,WAAW,EAAE,CAaf;AAED,iGAAiG;AACjG,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED,gFAAgF;AAChF,wBAAsB,eAAe,CACnC,SAAS,EAAE,cAAc,EAAE,EAC3B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,MAAM,CAAC,CAEjB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { chunkText } from './chunk.js';
|
|
2
|
+
/**
|
|
3
|
+
* Split documents into chunk records. Chunk ids are `${doc.id}#${index}`, so re-chunking the same
|
|
4
|
+
* document produces the same ids (upsert overwrites in place rather than duplicating).
|
|
5
|
+
*/
|
|
6
|
+
export function chunkDocuments(documents, options = {}) {
|
|
7
|
+
const chunks = [];
|
|
8
|
+
for (const document of documents) {
|
|
9
|
+
chunkText(document.text, options).forEach((text, index) => {
|
|
10
|
+
chunks.push({
|
|
11
|
+
id: `${document.id}#${index}`,
|
|
12
|
+
text,
|
|
13
|
+
...(document.source !== undefined ? { source: document.source } : {}),
|
|
14
|
+
...(document.metadata !== undefined ? { metadata: document.metadata } : {}),
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return chunks;
|
|
19
|
+
}
|
|
20
|
+
/** Embed pre-chunked records (one batched `embed`) and upsert them. Returns the record count. */
|
|
21
|
+
export async function ingestChunks(chunks, options) {
|
|
22
|
+
if (chunks.length === 0) {
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
const embeddings = await options.embedder.embed(chunks.map((chunk) => chunk.text));
|
|
26
|
+
const records = chunks.map((chunk, index) => ({
|
|
27
|
+
...chunk,
|
|
28
|
+
embedding: embeddings[index] ?? [],
|
|
29
|
+
}));
|
|
30
|
+
await options.store.upsert(records);
|
|
31
|
+
return records.length;
|
|
32
|
+
}
|
|
33
|
+
/** Chunk → embed → upsert in one call. Returns the number of chunks indexed. */
|
|
34
|
+
export async function ingestDocuments(documents, options) {
|
|
35
|
+
return ingestChunks(chunkDocuments(documents, options), options);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../../src/rag/ingest.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,SAAS,EAAE,MAAM,YAAY,CAAC;AA0B1D;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,SAA2B,EAC3B,UAAwB,EAAE;IAE1B,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACxD,MAAM,CAAC,IAAI,CAAC;gBACV,EAAE,EAAE,GAAG,QAAQ,CAAC,EAAE,IAAI,KAAK,EAAE;gBAC7B,IAAI;gBACJ,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrE,GAAG,CAAC,QAAQ,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5E,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAqB,EACrB,OAA4B;IAE5B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,MAAM,OAAO,GAAmB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5D,GAAG,KAAK;QACR,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE;KACnC,CAAC,CAAC,CAAC;IACJ,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAA2B,EAC3B,OAAsB;IAEtB,OAAO,YAAY,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Passage } from '../spi/retriever.js';
|
|
2
|
+
import { type IndexedDocument, type VectorRecord, type VectorSearchOptions, type VectorStore } from './vector-store.js';
|
|
3
|
+
/**
|
|
4
|
+
* An in-process {@link VectorStore} — cosine similarity over a Map, no infra. The reference adapter for
|
|
5
|
+
* tests and small/embedded corpora; a pgvector/Lucid-backed store for production scale is deferred.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MemoryVectorStore implements VectorStore {
|
|
8
|
+
private readonly records;
|
|
9
|
+
upsert(records: VectorRecord[]): Promise<void>;
|
|
10
|
+
remove(documentId: string): Promise<void>;
|
|
11
|
+
listDocuments(filter?: Record<string, unknown>): Promise<IndexedDocument[]>;
|
|
12
|
+
search(embedding: number[], options: VectorSearchOptions): Promise<Passage[]>;
|
|
13
|
+
}
|
|
14
|
+
/** Cosine similarity of two vectors; `0` when either has zero magnitude. Pure. */
|
|
15
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
16
|
+
//# sourceMappingURL=memory-vector-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-vector-store.d.ts","sourceRoot":"","sources":["../../../src/rag/memory-vector-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAEjB,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAErD,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAiB3E,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAgBpF;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAcjE"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { matchesFilter } from './filter.js';
|
|
2
|
+
import { documentIdOf, } from './vector-store.js';
|
|
3
|
+
/**
|
|
4
|
+
* An in-process {@link VectorStore} — cosine similarity over a Map, no infra. The reference adapter for
|
|
5
|
+
* tests and small/embedded corpora; a pgvector/Lucid-backed store for production scale is deferred.
|
|
6
|
+
*/
|
|
7
|
+
export class MemoryVectorStore {
|
|
8
|
+
records = new Map();
|
|
9
|
+
async upsert(records) {
|
|
10
|
+
for (const record of records) {
|
|
11
|
+
this.records.set(record.id, record);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async remove(documentId) {
|
|
15
|
+
for (const id of this.records.keys()) {
|
|
16
|
+
if (documentIdOf(id) === documentId) {
|
|
17
|
+
this.records.delete(id);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async listDocuments(filter) {
|
|
22
|
+
const documents = new Map();
|
|
23
|
+
for (const record of this.records.values()) {
|
|
24
|
+
if (filter !== undefined && !matchesFilter(record.metadata, filter)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const id = documentIdOf(record.id);
|
|
28
|
+
if (!documents.has(id)) {
|
|
29
|
+
documents.set(id, {
|
|
30
|
+
id,
|
|
31
|
+
...(record.metadata !== undefined ? { metadata: record.metadata } : {}),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [...documents.values()];
|
|
36
|
+
}
|
|
37
|
+
async search(embedding, options) {
|
|
38
|
+
const scored = [];
|
|
39
|
+
for (const record of this.records.values()) {
|
|
40
|
+
if (options.filter !== undefined && !matchesFilter(record.metadata, options.filter)) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
scored.push({
|
|
44
|
+
id: record.id,
|
|
45
|
+
text: record.text,
|
|
46
|
+
score: cosineSimilarity(embedding, record.embedding),
|
|
47
|
+
...(record.source !== undefined ? { source: record.source } : {}),
|
|
48
|
+
...(record.metadata !== undefined ? { metadata: record.metadata } : {}),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return scored.sort((a, b) => b.score - a.score).slice(0, options.topK);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Cosine similarity of two vectors; `0` when either has zero magnitude. Pure. */
|
|
55
|
+
export function cosineSimilarity(a, b) {
|
|
56
|
+
let dot = 0;
|
|
57
|
+
let normA = 0;
|
|
58
|
+
let normB = 0;
|
|
59
|
+
const length = Math.min(a.length, b.length);
|
|
60
|
+
for (let index = 0; index < length; index += 1) {
|
|
61
|
+
const valueA = a[index] ?? 0;
|
|
62
|
+
const valueB = b[index] ?? 0;
|
|
63
|
+
dot += valueA * valueB;
|
|
64
|
+
normA += valueA * valueA;
|
|
65
|
+
normB += valueB * valueB;
|
|
66
|
+
}
|
|
67
|
+
const denominator = Math.sqrt(normA) * Math.sqrt(normB);
|
|
68
|
+
return denominator === 0 ? 0 : dot / denominator;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=memory-vector-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-vector-store.js","sourceRoot":"","sources":["../../../src/rag/memory-vector-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { EmbeddingProvider } from '../spi/embedding-provider.js';
|
|
2
|
+
import type { Passage } from '../spi/retriever.js';
|
|
3
|
+
import type { LucidDatabaseLike } from '../stores/lucid.js';
|
|
4
|
+
import { EmbeddingRetriever } from './embedding-retriever.js';
|
|
5
|
+
import type { IndexedDocument, VectorRecord, VectorSearchOptions, VectorStore } from './vector-store.js';
|
|
6
|
+
/**
|
|
7
|
+
* The similarity metric — which pgvector distance operator ranks results (and which index opclass the
|
|
8
|
+
* migration should build). `cosine` (the default) is scale-invariant and the right choice for most
|
|
9
|
+
* embedding models; `l2` (Euclidean) and `inner` (inner product) are offered for models trained for them.
|
|
10
|
+
*/
|
|
11
|
+
export type PgVectorMetric = 'cosine' | 'l2' | 'inner';
|
|
12
|
+
/**
|
|
13
|
+
* Physical column names for the pgvector chunk table. Every field defaults to the mirror of the
|
|
14
|
+
* in-memory store's record shape (`id`/`text`/`source`/`metadata`/`embedding`); override to point the
|
|
15
|
+
* store at an existing table. Each name is validated against a strict identifier regex before it is ever
|
|
16
|
+
* spliced into SQL — the ONLY parts of a statement not passed as a positional binding.
|
|
17
|
+
*/
|
|
18
|
+
export interface PgVectorColumns {
|
|
19
|
+
/** Chunk id column (PK). Chunk ids are `${documentId}#<n>`. Default `id`. */
|
|
20
|
+
id?: string;
|
|
21
|
+
/** Chunk text column. Default `text`. */
|
|
22
|
+
text?: string;
|
|
23
|
+
/** Citation/source column (nullable). Default `source`. */
|
|
24
|
+
source?: string;
|
|
25
|
+
/** `jsonb` metadata column (nullable). Default `metadata`. */
|
|
26
|
+
metadata?: string;
|
|
27
|
+
/** `vector(N)` embedding column. Default `embedding`. */
|
|
28
|
+
embedding?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface PgVectorStoreOptions {
|
|
31
|
+
/** Table name. Default `agent_rag_chunks`. Validated against the identifier regex. */
|
|
32
|
+
table?: string;
|
|
33
|
+
/** Embedding width — must match your model (e.g. 1536 for text-embedding-3-small). Default 1536. */
|
|
34
|
+
dimension?: number;
|
|
35
|
+
/** Similarity metric / distance operator. Default `cosine`. */
|
|
36
|
+
metric?: PgVectorMetric;
|
|
37
|
+
/** Override the physical column names (each validated). */
|
|
38
|
+
columns?: PgVectorColumns;
|
|
39
|
+
}
|
|
40
|
+
/** pgvector accepts a `'[1,2,3]'` text literal cast to `vector`; the literal itself is a `?` binding. */
|
|
41
|
+
export declare function toVectorLiteral(embedding: number[]): string;
|
|
42
|
+
/**
|
|
43
|
+
* A pgvector-backed {@link VectorStore} — the production RAG adapter, the durable twin of
|
|
44
|
+
* {@link import('./memory-vector-store.js').MemoryVectorStore}. It runs over the structural
|
|
45
|
+
* {@link LucidDatabaseLike} (so `@adonisjs/lucid` stays an optional peer — this file imports no Lucid
|
|
46
|
+
* types) with raw SQL for the pgvector operators. Similarity ranks via the `<=>`/`<->`/`<#>` operator for
|
|
47
|
+
* the configured {@link PgVectorMetric}; the query embedding is always a `?::vector` positional binding
|
|
48
|
+
* (NEVER string-interpolated) and metadata filters an `@> ?::jsonb` binding, so only the (validated)
|
|
49
|
+
* table/column identifiers are ever spliced into a statement.
|
|
50
|
+
*
|
|
51
|
+
* Usually you don't construct this directly: `config/agent.ts` selects it via `retrievers.pgvector({...})`
|
|
52
|
+
* and the provider builds it, lazily importing `@adonisjs/lucid` only when the pgvector retriever is
|
|
53
|
+
* chosen. Call {@link PgVectorStore.ensureSchema} once (or run the bundled migration) to provision the
|
|
54
|
+
* `vector` extension, the chunk table, and the metric's index.
|
|
55
|
+
*/
|
|
56
|
+
export declare class PgVectorStore implements VectorStore {
|
|
57
|
+
private readonly db;
|
|
58
|
+
private readonly table;
|
|
59
|
+
private readonly dimension;
|
|
60
|
+
private readonly metric;
|
|
61
|
+
private readonly metricName;
|
|
62
|
+
private readonly col;
|
|
63
|
+
constructor(db: LucidDatabaseLike, options?: PgVectorStoreOptions);
|
|
64
|
+
/**
|
|
65
|
+
* Idempotent DDL — the `vector` extension, the chunk table, and the metric's index. Handy for tests
|
|
66
|
+
* and scripts; an AdonisJS app should prefer the bundled migration so the schema is versioned.
|
|
67
|
+
*/
|
|
68
|
+
ensureSchema(): Promise<void>;
|
|
69
|
+
/** The `CREATE EXTENSION` / `CREATE TABLE` / `CREATE INDEX` statements {@link ensureSchema} issues. */
|
|
70
|
+
schemaStatements(): string[];
|
|
71
|
+
upsert(records: VectorRecord[]): Promise<void>;
|
|
72
|
+
remove(documentId: string): Promise<void>;
|
|
73
|
+
listDocuments(filter?: Record<string, unknown>): Promise<IndexedDocument[]>;
|
|
74
|
+
search(embedding: number[], options: VectorSearchOptions): Promise<Passage[]>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A {@link import('../spi/retriever.js').Retriever} over a {@link PgVectorStore}: embed the query, then
|
|
78
|
+
* pgvector-search. The production sibling of the in-memory {@link EmbeddingRetriever} wiring — this is
|
|
79
|
+
* what `retrievers.pgvector({...})` builds. Construct it directly for programmatic use, or let the factory.
|
|
80
|
+
*/
|
|
81
|
+
export declare class PgVectorRetriever extends EmbeddingRetriever {
|
|
82
|
+
constructor(embedder: EmbeddingProvider, store: PgVectorStore);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=pg-vector-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-store.d.ts","sourceRoot":"","sources":["../../../src/rag/pg-vector-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAsDD,yGAAyG;AACzG,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAE3D;AAuCD;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAc,YAAW,WAAW;IAQ7C,OAAO,CAAC,QAAQ,CAAC,EAAE;IAPrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4B;gBAG7B,EAAE,EAAE,iBAAiB,EACtC,OAAO,GAAE,oBAAyB;IAgBpC;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAMnC,uGAAuG;IACvG,gBAAgB,IAAI,MAAM,EAAE;IAgBtB,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB9C,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAoB3E,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAmCpF;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,kBAAkB;gBAE3C,QAAQ,EAAE,iBAAiB,EAAE,KAAK,EAAE,aAAa;CAG9D"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { EmbeddingRetriever } from './embedding-retriever.js';
|
|
2
|
+
const METRICS = {
|
|
3
|
+
cosine: {
|
|
4
|
+
operator: '<=>',
|
|
5
|
+
opclass: 'vector_cosine_ops',
|
|
6
|
+
score: (col) => `1 - (${col} <=> ?::vector)`,
|
|
7
|
+
},
|
|
8
|
+
l2: {
|
|
9
|
+
operator: '<->',
|
|
10
|
+
opclass: 'vector_l2_ops',
|
|
11
|
+
score: (col) => `-(${col} <-> ?::vector)`,
|
|
12
|
+
},
|
|
13
|
+
inner: {
|
|
14
|
+
// pgvector's `<#>` returns the NEGATIVE inner product, so `-(a <#> b)` recovers the inner product
|
|
15
|
+
// and `ORDER BY a <#> b ASC` ranks the largest inner product first — consistent with the others.
|
|
16
|
+
operator: '<#>',
|
|
17
|
+
opclass: 'vector_ip_ops',
|
|
18
|
+
score: (col) => `-(${col} <#> ?::vector)`,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
/** Only unqualified SQL identifiers (letter/underscore start, then letters/digits/underscores) are allowed. */
|
|
22
|
+
const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
23
|
+
/**
|
|
24
|
+
* Reject any table/column name that is not a bare SQL identifier. Table and column names are the only
|
|
25
|
+
* parts of a pgvector statement that CANNOT be a positional binding (an identifier is not a value), so
|
|
26
|
+
* every one is validated here before it is spliced in — closing the injection vector that raw operator
|
|
27
|
+
* SQL would otherwise open. Embeddings, filters, top-K are always `?` bindings and never reach this path.
|
|
28
|
+
*/
|
|
29
|
+
function assertIdentifier(name, role) {
|
|
30
|
+
if (!IDENTIFIER.test(name)) {
|
|
31
|
+
throw new Error(`Invalid ${role} "${name}": a pgvector identifier must match ${IDENTIFIER.source}`);
|
|
32
|
+
}
|
|
33
|
+
return name;
|
|
34
|
+
}
|
|
35
|
+
/** pgvector accepts a `'[1,2,3]'` text literal cast to `vector`; the literal itself is a `?` binding. */
|
|
36
|
+
export function toVectorLiteral(embedding) {
|
|
37
|
+
return `[${embedding.join(',')}]`;
|
|
38
|
+
}
|
|
39
|
+
/** Normalize whatever a Lucid `rawQuery` returns (PG `{rows}`, SQLite array, MySQL `[rows,fields]`). */
|
|
40
|
+
function normalizeRows(raw) {
|
|
41
|
+
if (Array.isArray(raw)) {
|
|
42
|
+
if (raw.length > 0 && Array.isArray(raw[0])) {
|
|
43
|
+
return raw[0];
|
|
44
|
+
}
|
|
45
|
+
return raw;
|
|
46
|
+
}
|
|
47
|
+
if (raw !== null && typeof raw === 'object' && Array.isArray(raw.rows)) {
|
|
48
|
+
return raw.rows;
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
/** A `jsonb` column comes back parsed (object) on `pg` or as a string on some drivers — accept both. */
|
|
53
|
+
function parseMetadata(value) {
|
|
54
|
+
if (value === null || value === undefined)
|
|
55
|
+
return undefined;
|
|
56
|
+
if (typeof value === 'object')
|
|
57
|
+
return value;
|
|
58
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
59
|
+
try {
|
|
60
|
+
return JSON.parse(value);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* SQL that collapses a chunk id (`${documentId}#<n>`) back to its source document id — the pgvector
|
|
70
|
+
* mirror of {@link import('./vector-store.js').documentIdOf}. Shared by `remove` and `listDocuments` so
|
|
71
|
+
* both key on the exact same definition of "chunk belongs to document". `col` is a validated identifier.
|
|
72
|
+
*/
|
|
73
|
+
function documentIdExpr(col) {
|
|
74
|
+
return `regexp_replace(${col}, '#[0-9]+$', '')`;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A pgvector-backed {@link VectorStore} — the production RAG adapter, the durable twin of
|
|
78
|
+
* {@link import('./memory-vector-store.js').MemoryVectorStore}. It runs over the structural
|
|
79
|
+
* {@link LucidDatabaseLike} (so `@adonisjs/lucid` stays an optional peer — this file imports no Lucid
|
|
80
|
+
* types) with raw SQL for the pgvector operators. Similarity ranks via the `<=>`/`<->`/`<#>` operator for
|
|
81
|
+
* the configured {@link PgVectorMetric}; the query embedding is always a `?::vector` positional binding
|
|
82
|
+
* (NEVER string-interpolated) and metadata filters an `@> ?::jsonb` binding, so only the (validated)
|
|
83
|
+
* table/column identifiers are ever spliced into a statement.
|
|
84
|
+
*
|
|
85
|
+
* Usually you don't construct this directly: `config/agent.ts` selects it via `retrievers.pgvector({...})`
|
|
86
|
+
* and the provider builds it, lazily importing `@adonisjs/lucid` only when the pgvector retriever is
|
|
87
|
+
* chosen. Call {@link PgVectorStore.ensureSchema} once (or run the bundled migration) to provision the
|
|
88
|
+
* `vector` extension, the chunk table, and the metric's index.
|
|
89
|
+
*/
|
|
90
|
+
export class PgVectorStore {
|
|
91
|
+
db;
|
|
92
|
+
table;
|
|
93
|
+
dimension;
|
|
94
|
+
metric;
|
|
95
|
+
metricName;
|
|
96
|
+
col;
|
|
97
|
+
constructor(db, options = {}) {
|
|
98
|
+
this.db = db;
|
|
99
|
+
this.table = assertIdentifier(options.table ?? 'agent_rag_chunks', 'table');
|
|
100
|
+
this.dimension = options.dimension ?? 1536;
|
|
101
|
+
this.metricName = options.metric ?? 'cosine';
|
|
102
|
+
this.metric = METRICS[this.metricName];
|
|
103
|
+
const columns = options.columns ?? {};
|
|
104
|
+
this.col = {
|
|
105
|
+
id: assertIdentifier(columns.id ?? 'id', 'column'),
|
|
106
|
+
text: assertIdentifier(columns.text ?? 'text', 'column'),
|
|
107
|
+
source: assertIdentifier(columns.source ?? 'source', 'column'),
|
|
108
|
+
metadata: assertIdentifier(columns.metadata ?? 'metadata', 'column'),
|
|
109
|
+
embedding: assertIdentifier(columns.embedding ?? 'embedding', 'column'),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Idempotent DDL — the `vector` extension, the chunk table, and the metric's index. Handy for tests
|
|
114
|
+
* and scripts; an AdonisJS app should prefer the bundled migration so the schema is versioned.
|
|
115
|
+
*/
|
|
116
|
+
async ensureSchema() {
|
|
117
|
+
for (const statement of this.schemaStatements()) {
|
|
118
|
+
await this.db.rawQuery(statement);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** The `CREATE EXTENSION` / `CREATE TABLE` / `CREATE INDEX` statements {@link ensureSchema} issues. */
|
|
122
|
+
schemaStatements() {
|
|
123
|
+
const c = this.col;
|
|
124
|
+
return [
|
|
125
|
+
'CREATE EXTENSION IF NOT EXISTS vector',
|
|
126
|
+
`CREATE TABLE IF NOT EXISTS ${this.table} (
|
|
127
|
+
${c.id} TEXT PRIMARY KEY,
|
|
128
|
+
${c.text} TEXT NOT NULL,
|
|
129
|
+
${c.source} TEXT,
|
|
130
|
+
${c.metadata} JSONB,
|
|
131
|
+
${c.embedding} vector(${this.dimension}) NOT NULL
|
|
132
|
+
)`,
|
|
133
|
+
`CREATE INDEX IF NOT EXISTS ${this.table}_${c.embedding}_idx
|
|
134
|
+
ON ${this.table} USING hnsw (${c.embedding} ${this.metric.opclass})`,
|
|
135
|
+
];
|
|
136
|
+
}
|
|
137
|
+
async upsert(records) {
|
|
138
|
+
const c = this.col;
|
|
139
|
+
for (const record of records) {
|
|
140
|
+
await this.db.rawQuery(`INSERT INTO ${this.table} (${c.id}, ${c.text}, ${c.source}, ${c.metadata}, ${c.embedding})
|
|
141
|
+
VALUES (?, ?, ?, ?::jsonb, ?::vector)
|
|
142
|
+
ON CONFLICT (${c.id}) DO UPDATE SET
|
|
143
|
+
${c.text} = EXCLUDED.${c.text},
|
|
144
|
+
${c.source} = EXCLUDED.${c.source},
|
|
145
|
+
${c.metadata} = EXCLUDED.${c.metadata},
|
|
146
|
+
${c.embedding} = EXCLUDED.${c.embedding}`, [
|
|
147
|
+
record.id,
|
|
148
|
+
record.text,
|
|
149
|
+
record.source ?? null,
|
|
150
|
+
record.metadata !== undefined ? JSON.stringify(record.metadata) : null,
|
|
151
|
+
toVectorLiteral(record.embedding),
|
|
152
|
+
]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async remove(documentId) {
|
|
156
|
+
await this.db.rawQuery(`DELETE FROM ${this.table} WHERE ${documentIdExpr(this.col.id)} = ?`, [
|
|
157
|
+
documentId,
|
|
158
|
+
]);
|
|
159
|
+
}
|
|
160
|
+
async listDocuments(filter) {
|
|
161
|
+
const c = this.col;
|
|
162
|
+
const docExpr = documentIdExpr(c.id);
|
|
163
|
+
const hasFilter = filter !== undefined && Object.keys(filter).length > 0;
|
|
164
|
+
const raw = await this.db.rawQuery(`SELECT DISTINCT ON (${docExpr}) ${docExpr} AS doc_id, ${c.metadata} AS metadata
|
|
165
|
+
FROM ${this.table}
|
|
166
|
+
${hasFilter ? `WHERE ${c.metadata} @> ?::jsonb` : ''}
|
|
167
|
+
ORDER BY ${docExpr}`, hasFilter ? [JSON.stringify(filter)] : []);
|
|
168
|
+
return normalizeRows(raw).map((row) => {
|
|
169
|
+
const metadata = parseMetadata(row.metadata);
|
|
170
|
+
return {
|
|
171
|
+
id: String(row.doc_id),
|
|
172
|
+
...(metadata !== undefined ? { metadata } : {}),
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
async search(embedding, options) {
|
|
177
|
+
const c = this.col;
|
|
178
|
+
const vector = toVectorLiteral(embedding);
|
|
179
|
+
const hasFilter = options.filter !== undefined && Object.keys(options.filter).length > 0;
|
|
180
|
+
// Bindings are consumed positionally, in the exact order the `?`s appear: score expr (embedding),
|
|
181
|
+
// then the optional filter, then the ORDER BY embedding, then the LIMIT. The embedding is bound
|
|
182
|
+
// TWICE — once per `?::vector` — because a positional `?` cannot be reused like a numbered `$1`.
|
|
183
|
+
const bindings = [vector];
|
|
184
|
+
let where = '';
|
|
185
|
+
if (hasFilter) {
|
|
186
|
+
where = `WHERE ${c.metadata} @> ?::jsonb`;
|
|
187
|
+
bindings.push(JSON.stringify(options.filter));
|
|
188
|
+
}
|
|
189
|
+
bindings.push(vector, options.topK);
|
|
190
|
+
const raw = await this.db.rawQuery(`SELECT ${c.id} AS id, ${c.text} AS text, ${c.source} AS source, ${c.metadata} AS metadata,
|
|
191
|
+
${this.metric.score(c.embedding)} AS score
|
|
192
|
+
FROM ${this.table}
|
|
193
|
+
${where}
|
|
194
|
+
ORDER BY ${c.embedding} ${this.metric.operator} ?::vector
|
|
195
|
+
LIMIT ?`, bindings);
|
|
196
|
+
return normalizeRows(raw).map((row) => {
|
|
197
|
+
const metadata = parseMetadata(row.metadata);
|
|
198
|
+
const source = row.source;
|
|
199
|
+
return {
|
|
200
|
+
id: String(row.id),
|
|
201
|
+
text: String(row.text),
|
|
202
|
+
score: Number(row.score),
|
|
203
|
+
...(source !== null && source !== undefined ? { source: String(source) } : {}),
|
|
204
|
+
...(metadata !== undefined ? { metadata } : {}),
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* A {@link import('../spi/retriever.js').Retriever} over a {@link PgVectorStore}: embed the query, then
|
|
211
|
+
* pgvector-search. The production sibling of the in-memory {@link EmbeddingRetriever} wiring — this is
|
|
212
|
+
* what `retrievers.pgvector({...})` builds. Construct it directly for programmatic use, or let the factory.
|
|
213
|
+
*/
|
|
214
|
+
export class PgVectorRetriever extends EmbeddingRetriever {
|
|
215
|
+
// biome-ignore lint/complexity/noUselessConstructor: not useless — it NARROWS `store` from the base's `VectorStore` to `PgVectorStore`, which is this subclass's whole point. Delete it and `new PgVectorRetriever(embedder, anyInMemoryStore)` starts compiling.
|
|
216
|
+
constructor(embedder, store) {
|
|
217
|
+
super(embedder, store);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=pg-vector-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-vector-store.js","sourceRoot":"","sources":["../../../src/rag/pg-vector-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Passage } from '../spi/retriever.js';
|
|
2
|
+
/** A stored, embedded chunk. `embedding` length must match the store's configured dimensions. */
|
|
3
|
+
export interface VectorRecord {
|
|
4
|
+
id: string;
|
|
5
|
+
text: string;
|
|
6
|
+
embedding: number[];
|
|
7
|
+
/** Citation-facing origin (document title, URL, row id). */
|
|
8
|
+
source?: string;
|
|
9
|
+
metadata?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export interface VectorSearchOptions {
|
|
12
|
+
topK: number;
|
|
13
|
+
/** Exact-match metadata filter (all keys must equal). Passed through from `RetrieveOptions.filter`. */
|
|
14
|
+
filter?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The write + search side of RAG storage. This package ships {@link import('./memory-vector-store.js').MemoryVectorStore}
|
|
18
|
+
* (in-JS cosine, tests + small/embedded corpora); a pgvector/Lucid-backed store is deferred. Pair one
|
|
19
|
+
* with an {@link import('../spi/embedding-provider.js').EmbeddingProvider} via
|
|
20
|
+
* {@link import('./embedding-retriever.js').EmbeddingRetriever} to get a `Retriever`.
|
|
21
|
+
*/
|
|
22
|
+
export interface VectorStore {
|
|
23
|
+
upsert(records: VectorRecord[]): Promise<void>;
|
|
24
|
+
search(embedding: number[], options: VectorSearchOptions): Promise<Passage[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Delete every chunk belonging to a source document — all records whose id is `${documentId}` or
|
|
27
|
+
* `${documentId}#<n>` (the id scheme {@link import('./ingest.js').chunkDocuments} produces). Use it to
|
|
28
|
+
* drop a document from the index, and before re-ingesting one: `upsert` overwrites matching ids but
|
|
29
|
+
* can't remove chunks a shorter new version no longer produces, so a re-ingest without a preceding
|
|
30
|
+
* `remove` leaves the old tail orphaned.
|
|
31
|
+
*/
|
|
32
|
+
remove(documentId: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* List the distinct source documents currently indexed (chunk ids collapsed back to their document by
|
|
35
|
+
* stripping the trailing `#<n>`), each with a representative chunk's `metadata`, optionally narrowed
|
|
36
|
+
* by a metadata `filter`.
|
|
37
|
+
*/
|
|
38
|
+
listDocuments(filter?: Record<string, unknown>): Promise<IndexedDocument[]>;
|
|
39
|
+
}
|
|
40
|
+
/** A distinct source document as seen by the index — its id plus a representative chunk's metadata. */
|
|
41
|
+
export interface IndexedDocument {
|
|
42
|
+
id: string;
|
|
43
|
+
metadata?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
/** Collapse a chunk id (`${documentId}#<n>`) back to its source document id. */
|
|
46
|
+
export declare function documentIdOf(chunkId: string): string;
|
|
47
|
+
//# sourceMappingURL=vector-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../../src/rag/vector-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,iGAAiG;AACjG,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,uGAAuG;IACvG,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9E;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C;;;;OAIG;IACH,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CAC7E;AAED,uGAAuG;AACvG,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector-store.js","sourceRoot":"","sources":["../../../src/rag/vector-store.ts"],"names":[],"mappings":"AAiDA,gFAAgF;AAChF,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type RagMediaSkipReason = 'unsupported-type' | 'too-large' | 'empty-text';
|
|
2
|
+
/** Emitted on `agora:rag:media.ingested` once a media file's chunks are embedded + upserted. */
|
|
3
|
+
export interface RagMediaIngestedPayload {
|
|
4
|
+
mediaId: string;
|
|
5
|
+
ownerType?: string;
|
|
6
|
+
ownerId?: string;
|
|
7
|
+
collection?: string;
|
|
8
|
+
tenantRef?: string;
|
|
9
|
+
chunks: number;
|
|
10
|
+
}
|
|
11
|
+
/** Emitted on `agora:rag:media.removed` when a media document's chunks are dropped from the store. */
|
|
12
|
+
export interface RagMediaRemovedPayload {
|
|
13
|
+
mediaId: string;
|
|
14
|
+
}
|
|
15
|
+
/** Emitted on `agora:rag:media.skipped` when a file is not indexed (unsupported/too-large/empty). */
|
|
16
|
+
export interface RagMediaSkippedPayload {
|
|
17
|
+
mediaId: string;
|
|
18
|
+
contentType: string;
|
|
19
|
+
reason: RagMediaSkipReason;
|
|
20
|
+
}
|
|
21
|
+
/** Emitted on `agora:rag:media.failed` when an ingestion throws (bytes fetch / embed / upsert). */
|
|
22
|
+
export interface RagMediaFailedPayload {
|
|
23
|
+
mediaId: string;
|
|
24
|
+
error: string;
|
|
25
|
+
}
|
|
26
|
+
/** Maps each event name to its payload type, so {@link publishRagMedia} is checked at the call site. */
|
|
27
|
+
export interface RagMediaDiagnosticPayloads {
|
|
28
|
+
'media.ingested': RagMediaIngestedPayload;
|
|
29
|
+
'media.removed': RagMediaRemovedPayload;
|
|
30
|
+
'media.skipped': RagMediaSkippedPayload;
|
|
31
|
+
'media.failed': RagMediaFailedPayload;
|
|
32
|
+
}
|
|
33
|
+
export type RagMediaDiagnosticEvent = keyof RagMediaDiagnosticPayloads;
|
|
34
|
+
/**
|
|
35
|
+
* Publish a rag-media event on `agora:rag:<event>` via the structural diagnostics slot. No-op when
|
|
36
|
+
* diagnostics isn't installed (the slot is empty) — and it never throws back into an ingestion.
|
|
37
|
+
*/
|
|
38
|
+
export declare function publishRagMedia<E extends RagMediaDiagnosticEvent>(event: E, payload: RagMediaDiagnosticPayloads[E]): void;
|
|
39
|
+
export declare function publishRagMediaIngested(payload: RagMediaIngestedPayload): void;
|
|
40
|
+
export declare function publishRagMediaRemoved(payload: RagMediaRemovedPayload): void;
|
|
41
|
+
export declare function publishRagMediaSkipped(payload: RagMediaSkippedPayload): void;
|
|
42
|
+
export declare function publishRagMediaFailed(payload: RagMediaFailedPayload): void;
|
|
43
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../src/rag-media/diagnostics.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,GAAG,WAAW,GAAG,YAAY,CAAC;AAEjF,gGAAgG;AAChG,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,sGAAsG;AACtG,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,qGAAqG;AACrG,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AACD,mGAAmG;AACnG,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wGAAwG;AACxG,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,eAAe,EAAE,sBAAsB,CAAC;IACxC,eAAe,EAAE,sBAAsB,CAAC;IACxC,cAAc,EAAE,qBAAqB,CAAC;CACvC;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,uBAAuB,EAC/D,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC,GACrC,IAAI,CASN;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAE9E;AACD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAE5E;AACD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAE5E;AACD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAE1E"}
|