@agentionai/agents 0.4.2 → 0.6.1

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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/agents/AgentConfig.d.ts +19 -0
  3. package/dist/agents/BaseAgent.d.ts +39 -0
  4. package/dist/agents/BaseAgent.js +100 -1
  5. package/dist/agents/anthropic/ClaudeAgent.d.ts +0 -2
  6. package/dist/agents/anthropic/ClaudeAgent.js +8 -4
  7. package/dist/agents/google/GeminiAgent.d.ts +0 -2
  8. package/dist/agents/google/GeminiAgent.js +4 -4
  9. package/dist/agents/mistral/MistralAgent.d.ts +0 -2
  10. package/dist/agents/mistral/MistralAgent.js +4 -4
  11. package/dist/agents/openai/OpenAiAgent.d.ts +0 -2
  12. package/dist/agents/openai/OpenAiAgent.js +4 -4
  13. package/dist/{vectorstore → embeddings}/OpenAIEmbeddings.d.ts +10 -2
  14. package/dist/{vectorstore → embeddings}/OpenAIEmbeddings.js +5 -1
  15. package/dist/embeddings/VoyageAIEmbeddings.d.ts +80 -0
  16. package/dist/embeddings/VoyageAIEmbeddings.js +139 -0
  17. package/dist/embeddings/index.d.ts +23 -0
  18. package/dist/embeddings/index.js +29 -0
  19. package/dist/graph/AgentGraph.d.ts +77 -0
  20. package/dist/graph/AgentGraph.js +112 -1
  21. package/dist/graph/context/ContextStore.d.ts +69 -0
  22. package/dist/graph/context/ContextStore.js +101 -0
  23. package/dist/graph/context/ContextTools.d.ts +52 -0
  24. package/dist/graph/context/ContextTools.js +148 -0
  25. package/dist/graph/context/index.d.ts +3 -0
  26. package/dist/graph/context/index.js +11 -0
  27. package/dist/graph/planning/PlanExecutor.d.ts +184 -0
  28. package/dist/graph/planning/PlanExecutor.js +396 -0
  29. package/dist/graph/planning/PlanStore.d.ts +81 -0
  30. package/dist/graph/planning/PlanStore.js +199 -0
  31. package/dist/graph/planning/PlanningTools.d.ts +45 -0
  32. package/dist/graph/planning/PlanningTools.js +178 -0
  33. package/dist/graph/planning/index.d.ts +5 -0
  34. package/dist/graph/planning/index.js +14 -0
  35. package/dist/graph/planning/types.d.ts +41 -0
  36. package/dist/graph/planning/types.js +3 -0
  37. package/dist/history/History.js +3 -0
  38. package/dist/index.d.ts +1 -0
  39. package/dist/index.js +2 -0
  40. package/dist/ingestion/IngestionPipeline.d.ts +1 -1
  41. package/dist/vectorstore/LanceDBVectorStore.d.ts +67 -2
  42. package/dist/vectorstore/LanceDBVectorStore.js +134 -23
  43. package/dist/vectorstore/index.d.ts +6 -4
  44. package/dist/vectorstore/index.js +10 -6
  45. package/package.json +12 -3
  46. /package/dist/{vectorstore → embeddings}/Embeddings.d.ts +0 -0
  47. /package/dist/{vectorstore → embeddings}/Embeddings.js +0 -0
@@ -0,0 +1,45 @@
1
+ import { Tool } from "../../tools/Tool";
2
+ import { PlanStore } from "./PlanStore";
3
+ /**
4
+ * Create a tool for agents to create an execution plan.
5
+ *
6
+ * @param planStore - The PlanStore to create plans in
7
+ * @returns A Tool that creates plans
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const store = new PlanStore();
12
+ * const createTool = createPlanTool(store);
13
+ * agent.addTools([createTool]);
14
+ * ```
15
+ */
16
+ export declare function createPlanTool(planStore: PlanStore): Tool<string>;
17
+ /**
18
+ * Create a tool for agents to view the current plan status.
19
+ *
20
+ * @param planStore - The PlanStore to view plans from
21
+ * @returns A Tool that displays plan information
22
+ */
23
+ export declare function createViewPlanTool(planStore: PlanStore): Tool<string>;
24
+ /**
25
+ * Create a tool for agents to update step status.
26
+ *
27
+ * @param planStore - The PlanStore to update steps in
28
+ * @returns A Tool that updates step status
29
+ */
30
+ export declare function createUpdateStepTool(planStore: PlanStore): Tool<string>;
31
+ /**
32
+ * Create a tool for agents to get the next step to work on.
33
+ *
34
+ * @param planStore - The PlanStore to get steps from
35
+ * @returns A Tool that retrieves the next pending step
36
+ */
37
+ export declare function createGetNextStepTool(planStore: PlanStore): Tool<string>;
38
+ /**
39
+ * Create a tool for agents to add a step to the current plan.
40
+ *
41
+ * @param planStore - The PlanStore to add steps to
42
+ * @returns A Tool that adds new steps
43
+ */
44
+ export declare function createAddStepTool(planStore: PlanStore): Tool<string>;
45
+ //# sourceMappingURL=PlanningTools.d.ts.map
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPlanTool = createPlanTool;
4
+ exports.createViewPlanTool = createViewPlanTool;
5
+ exports.createUpdateStepTool = createUpdateStepTool;
6
+ exports.createGetNextStepTool = createGetNextStepTool;
7
+ exports.createAddStepTool = createAddStepTool;
8
+ const Tool_1 = require("../../tools/Tool");
9
+ /**
10
+ * Create a tool for agents to create an execution plan.
11
+ *
12
+ * @param planStore - The PlanStore to create plans in
13
+ * @returns A Tool that creates plans
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const store = new PlanStore();
18
+ * const createTool = createPlanTool(store);
19
+ * agent.addTools([createTool]);
20
+ * ```
21
+ */
22
+ function createPlanTool(planStore) {
23
+ return new Tool_1.Tool({
24
+ name: "create_plan",
25
+ description: "Create an execution plan with a goal and ordered steps. Each step should be a clear, actionable task.",
26
+ inputSchema: {
27
+ type: "object",
28
+ properties: {
29
+ goal: {
30
+ type: "string",
31
+ description: "The overall goal to achieve",
32
+ },
33
+ steps: {
34
+ type: "array",
35
+ description: "Ordered list of step descriptions",
36
+ },
37
+ },
38
+ required: ["goal", "steps"],
39
+ },
40
+ execute: async (input) => {
41
+ const plan = planStore.createPlan(input.goal, input.steps);
42
+ return JSON.stringify({
43
+ success: true,
44
+ planId: plan.id,
45
+ stepCount: plan.steps.length,
46
+ summary: planStore.getSummary(),
47
+ });
48
+ },
49
+ });
50
+ }
51
+ /**
52
+ * Create a tool for agents to view the current plan status.
53
+ *
54
+ * @param planStore - The PlanStore to view plans from
55
+ * @returns A Tool that displays plan information
56
+ */
57
+ function createViewPlanTool(planStore) {
58
+ return new Tool_1.Tool({
59
+ name: "view_plan",
60
+ description: "View the current plan status and steps.",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: {},
64
+ },
65
+ execute: async () => {
66
+ const plan = planStore.getActivePlan();
67
+ if (!plan) {
68
+ return JSON.stringify({ error: "No active plan" });
69
+ }
70
+ return JSON.stringify({
71
+ plan,
72
+ summary: planStore.getSummary(),
73
+ });
74
+ },
75
+ });
76
+ }
77
+ /**
78
+ * Create a tool for agents to update step status.
79
+ *
80
+ * @param planStore - The PlanStore to update steps in
81
+ * @returns A Tool that updates step status
82
+ */
83
+ function createUpdateStepTool(planStore) {
84
+ return new Tool_1.Tool({
85
+ name: "update_step",
86
+ description: "Update the status of a plan step. Mark as completed when done, failed if there was an error.",
87
+ inputSchema: {
88
+ type: "object",
89
+ properties: {
90
+ stepId: {
91
+ type: "string",
92
+ description: "The step ID to update (e.g., step_1)",
93
+ },
94
+ status: {
95
+ type: "string",
96
+ enum: ["in_progress", "completed", "failed", "skipped"],
97
+ description: "New status for the step",
98
+ },
99
+ output: {
100
+ type: "string",
101
+ description: "Optional output or result from this step",
102
+ },
103
+ error: {
104
+ type: "string",
105
+ description: "Optional error message if the step failed",
106
+ },
107
+ },
108
+ required: ["stepId", "status"],
109
+ },
110
+ execute: async (input) => {
111
+ planStore.updateStep(input.stepId, input.status, input.output, input.error);
112
+ return JSON.stringify({
113
+ success: true,
114
+ summary: planStore.getSummary(),
115
+ });
116
+ },
117
+ });
118
+ }
119
+ /**
120
+ * Create a tool for agents to get the next step to work on.
121
+ *
122
+ * @param planStore - The PlanStore to get steps from
123
+ * @returns A Tool that retrieves the next pending step
124
+ */
125
+ function createGetNextStepTool(planStore) {
126
+ return new Tool_1.Tool({
127
+ name: "get_next_step",
128
+ description: "Get the next pending step from the plan to work on.",
129
+ inputSchema: {
130
+ type: "object",
131
+ properties: {},
132
+ },
133
+ execute: async () => {
134
+ const step = planStore.getNextStep();
135
+ if (!step) {
136
+ return JSON.stringify({
137
+ message: "No more pending steps",
138
+ summary: planStore.getSummary(),
139
+ });
140
+ }
141
+ return JSON.stringify({ nextStep: step });
142
+ },
143
+ });
144
+ }
145
+ /**
146
+ * Create a tool for agents to add a step to the current plan.
147
+ *
148
+ * @param planStore - The PlanStore to add steps to
149
+ * @returns A Tool that adds new steps
150
+ */
151
+ function createAddStepTool(planStore) {
152
+ return new Tool_1.Tool({
153
+ name: "add_step",
154
+ description: "Add a new step to the current plan.",
155
+ inputSchema: {
156
+ type: "object",
157
+ properties: {
158
+ description: {
159
+ type: "string",
160
+ description: "Description of the new step",
161
+ },
162
+ },
163
+ required: ["description"],
164
+ },
165
+ execute: async (input) => {
166
+ const step = planStore.addStep(input.description);
167
+ if (!step) {
168
+ return JSON.stringify({ error: "No active plan to add step to" });
169
+ }
170
+ return JSON.stringify({
171
+ success: true,
172
+ step,
173
+ summary: planStore.getSummary(),
174
+ });
175
+ },
176
+ });
177
+ }
178
+ //# sourceMappingURL=PlanningTools.js.map
@@ -0,0 +1,5 @@
1
+ export { Plan, PlanStep, PlanStepStatus, PlanStatus } from "./types";
2
+ export { PlanStore } from "./PlanStore";
3
+ export { createPlanTool, createViewPlanTool, createUpdateStepTool, createGetNextStepTool, createAddStepTool, } from "./PlanningTools";
4
+ export { PlanExecutor, PlanExecutorOptions } from "./PlanExecutor";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PlanExecutor = exports.createAddStepTool = exports.createGetNextStepTool = exports.createUpdateStepTool = exports.createViewPlanTool = exports.createPlanTool = exports.PlanStore = void 0;
4
+ var PlanStore_1 = require("./PlanStore");
5
+ Object.defineProperty(exports, "PlanStore", { enumerable: true, get: function () { return PlanStore_1.PlanStore; } });
6
+ var PlanningTools_1 = require("./PlanningTools");
7
+ Object.defineProperty(exports, "createPlanTool", { enumerable: true, get: function () { return PlanningTools_1.createPlanTool; } });
8
+ Object.defineProperty(exports, "createViewPlanTool", { enumerable: true, get: function () { return PlanningTools_1.createViewPlanTool; } });
9
+ Object.defineProperty(exports, "createUpdateStepTool", { enumerable: true, get: function () { return PlanningTools_1.createUpdateStepTool; } });
10
+ Object.defineProperty(exports, "createGetNextStepTool", { enumerable: true, get: function () { return PlanningTools_1.createGetNextStepTool; } });
11
+ Object.defineProperty(exports, "createAddStepTool", { enumerable: true, get: function () { return PlanningTools_1.createAddStepTool; } });
12
+ var PlanExecutor_1 = require("./PlanExecutor");
13
+ Object.defineProperty(exports, "PlanExecutor", { enumerable: true, get: function () { return PlanExecutor_1.PlanExecutor; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Status of a plan step.
3
+ */
4
+ export type PlanStepStatus = "pending" | "in_progress" | "completed" | "failed" | "skipped";
5
+ /**
6
+ * A single step in a plan.
7
+ */
8
+ export interface PlanStep {
9
+ /** Unique identifier for this step (e.g., "step_1") */
10
+ id: string;
11
+ /** Human-readable description of what this step does */
12
+ description: string;
13
+ /** Current status of this step */
14
+ status: PlanStepStatus;
15
+ /** Output or result from this step (set after completion) */
16
+ output?: string;
17
+ /** Error message if the step failed */
18
+ error?: string;
19
+ }
20
+ /**
21
+ * Overall status of a plan.
22
+ */
23
+ export type PlanStatus = "created" | "executing" | "completed" | "failed";
24
+ /**
25
+ * A complete execution plan with a goal and ordered steps.
26
+ */
27
+ export interface Plan {
28
+ /** Unique identifier for this plan */
29
+ id: string;
30
+ /** The overall goal this plan aims to achieve */
31
+ goal: string;
32
+ /** Ordered list of steps to execute */
33
+ steps: PlanStep[];
34
+ /** Overall status of the plan */
35
+ status: PlanStatus;
36
+ /** Timestamp when the plan was created */
37
+ createdAt: number;
38
+ /** Timestamp when the plan was last updated */
39
+ updatedAt: number;
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -62,6 +62,9 @@ class History extends events_1.default {
62
62
  ...entry,
63
63
  __metadata,
64
64
  });
65
+ if (this.options.maxLength && this._entries.length > this.options.maxLength) {
66
+ this._entries = this._entries.slice(this._entries.length - this.options.maxLength);
67
+ }
65
68
  this.emit("entry", entry);
66
69
  }
67
70
  /**
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export * from "./graph/AgentGraph";
11
11
  export * from "./tools/Tool";
12
12
  export * from "./viz";
13
13
  export * from "./vectorstore";
14
+ export * from "./embeddings";
14
15
  export * from "./chunkers";
15
16
  export * from "./ingestion";
16
17
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -49,6 +49,8 @@ __exportStar(require("./tools/Tool"), exports);
49
49
  __exportStar(require("./viz"), exports);
50
50
  // Vector Store
51
51
  __exportStar(require("./vectorstore"), exports);
52
+ // Embeddings (also re-exported from vectorstore for backward compatibility)
53
+ __exportStar(require("./embeddings"), exports);
52
54
  // Chunkers
53
55
  __exportStar(require("./chunkers"), exports);
54
56
  // Ingestion
@@ -1,6 +1,6 @@
1
1
  import { Chunk, ChunkOptions } from "../chunkers/types";
2
2
  import { Chunker } from "../chunkers/Chunker";
3
- import { Embeddings } from "../vectorstore/Embeddings";
3
+ import { Embeddings } from "../embeddings/Embeddings";
4
4
  import { VectorStore } from "../vectorstore/VectorStore";
5
5
  import { IngestionOptions, IngestionResult, DocumentInput } from "./types";
6
6
  /**
@@ -9,7 +9,22 @@
9
9
  */
10
10
  import type { Connection, Table, ConnectionOptions } from "@lancedb/lancedb";
11
11
  import { VectorStore, Document, EmbeddedDocument, SearchResult, AddDocumentsOptions, SearchOptions, DeleteOptions } from "./VectorStore";
12
- import { Embeddings } from "./Embeddings";
12
+ import { Embeddings } from "../embeddings/Embeddings";
13
+ /**
14
+ * Supported types for metadata fields.
15
+ */
16
+ export type MetadataFieldType = "string" | "number" | "boolean";
17
+ /**
18
+ * Definition for a metadata field that will be stored as a separate column.
19
+ */
20
+ export interface MetadataFieldDefinition {
21
+ /** Name of the metadata field */
22
+ name: string;
23
+ /** Data type for the field */
24
+ type: MetadataFieldType;
25
+ /** Whether the field can be null (default: true) */
26
+ nullable?: boolean;
27
+ }
13
28
  /**
14
29
  * Configuration for LanceDBVectorStore.
15
30
  */
@@ -26,11 +41,17 @@ export interface LanceDBVectorStoreConfig {
26
41
  dimensions?: number;
27
42
  /** Additional connection options */
28
43
  connectionOptions?: Partial<ConnectionOptions>;
44
+ /**
45
+ * Metadata field definitions for filterable columns.
46
+ * When specified, metadata fields are stored as separate columns enabling efficient filtering.
47
+ * If not specified, metadata is stored as a JSON string (legacy behavior).
48
+ */
49
+ metadataFields?: MetadataFieldDefinition[];
29
50
  }
30
51
  /**
31
52
  * LanceDB implementation of the VectorStore interface.
32
53
  *
33
- * @example
54
+ * @example Basic usage with JSON metadata (legacy)
34
55
  * ```typescript
35
56
  * import { LanceDBVectorStore, OpenAIEmbeddings } from "@agentionai/agents";
36
57
  *
@@ -58,6 +79,38 @@ export interface LanceDBVectorStoreConfig {
58
79
  * // Create a tool for agents
59
80
  * const searchTool = store.toRetrievalTool("Search the knowledge base");
60
81
  * ```
82
+ *
83
+ * @example With filterable metadata fields
84
+ * ```typescript
85
+ * const store = await LanceDBVectorStore.create({
86
+ * name: "knowledge_base",
87
+ * uri: "./my-database",
88
+ * tableName: "documents",
89
+ * embeddings,
90
+ * metadataFields: [
91
+ * { name: "category", type: "string" },
92
+ * { name: "source", type: "string" },
93
+ * { name: "year", type: "number" },
94
+ * { name: "verified", type: "boolean" },
95
+ * { name: "hash", type: "string" }, // Enables efficient deduplication
96
+ * ],
97
+ * });
98
+ *
99
+ * // Add documents with metadata
100
+ * await store.addDocuments([
101
+ * {
102
+ * id: "1",
103
+ * content: "LanceDB is a vector database",
104
+ * metadata: { category: "database", source: "docs", year: 2024, verified: true },
105
+ * },
106
+ * ]);
107
+ *
108
+ * // Search with filters on metadata columns
109
+ * const results = await store.search("vector database", {
110
+ * limit: 5,
111
+ * filter: { category: "database", year: 2024 },
112
+ * });
113
+ * ```
61
114
  */
62
115
  export declare class LanceDBVectorStore extends VectorStore {
63
116
  readonly name: string;
@@ -66,6 +119,7 @@ export declare class LanceDBVectorStore extends VectorStore {
66
119
  private embeddings?;
67
120
  private tableName;
68
121
  private dimensions;
122
+ private metadataFields?;
69
123
  private constructor();
70
124
  /**
71
125
  * Create a new LanceDBVectorStore instance.
@@ -110,6 +164,9 @@ export declare class LanceDBVectorStore extends VectorStore {
110
164
  /**
111
165
  * Get existing documents by their content hashes.
112
166
  * Used for deduplication during ingestion.
167
+ *
168
+ * Note: If using metadataFields, include a "hash" field of type "string"
169
+ * for efficient hash lookups. Otherwise, falls back to LIKE queries on JSON metadata.
113
170
  */
114
171
  getByHashes(hashes: string[], _options?: DeleteOptions): Promise<Map<string, string>>;
115
172
  /**
@@ -145,5 +202,13 @@ export declare class LanceDBVectorStore extends VectorStore {
145
202
  * Process raw LanceDB results into SearchResult format.
146
203
  */
147
204
  private processResults;
205
+ /**
206
+ * Extract metadata from a row based on metadataFields configuration.
207
+ */
208
+ private extractMetadata;
209
+ /**
210
+ * Get the configured metadata fields.
211
+ */
212
+ getMetadataFields(): MetadataFieldDefinition[] | undefined;
148
213
  }
149
214
  //# sourceMappingURL=LanceDBVectorStore.d.ts.map
@@ -47,7 +47,7 @@ const VectorStore_1 = require("./VectorStore");
47
47
  /**
48
48
  * LanceDB implementation of the VectorStore interface.
49
49
  *
50
- * @example
50
+ * @example Basic usage with JSON metadata (legacy)
51
51
  * ```typescript
52
52
  * import { LanceDBVectorStore, OpenAIEmbeddings } from "@agentionai/agents";
53
53
  *
@@ -75,6 +75,38 @@ const VectorStore_1 = require("./VectorStore");
75
75
  * // Create a tool for agents
76
76
  * const searchTool = store.toRetrievalTool("Search the knowledge base");
77
77
  * ```
78
+ *
79
+ * @example With filterable metadata fields
80
+ * ```typescript
81
+ * const store = await LanceDBVectorStore.create({
82
+ * name: "knowledge_base",
83
+ * uri: "./my-database",
84
+ * tableName: "documents",
85
+ * embeddings,
86
+ * metadataFields: [
87
+ * { name: "category", type: "string" },
88
+ * { name: "source", type: "string" },
89
+ * { name: "year", type: "number" },
90
+ * { name: "verified", type: "boolean" },
91
+ * { name: "hash", type: "string" }, // Enables efficient deduplication
92
+ * ],
93
+ * });
94
+ *
95
+ * // Add documents with metadata
96
+ * await store.addDocuments([
97
+ * {
98
+ * id: "1",
99
+ * content: "LanceDB is a vector database",
100
+ * metadata: { category: "database", source: "docs", year: 2024, verified: true },
101
+ * },
102
+ * ]);
103
+ *
104
+ * // Search with filters on metadata columns
105
+ * const results = await store.search("vector database", {
106
+ * limit: 5,
107
+ * filter: { category: "database", year: 2024 },
108
+ * });
109
+ * ```
78
110
  */
79
111
  class LanceDBVectorStore extends VectorStore_1.VectorStore {
80
112
  constructor(config, connection, table) {
@@ -86,6 +118,7 @@ class LanceDBVectorStore extends VectorStore_1.VectorStore {
86
118
  this.tableName = config.tableName;
87
119
  this.dimensions =
88
120
  config.dimensions ?? config.embeddings?.dimensions ?? 1536;
121
+ this.metadataFields = config.metadataFields;
89
122
  }
90
123
  /**
91
124
  * Create a new LanceDBVectorStore instance.
@@ -122,12 +155,38 @@ class LanceDBVectorStore extends VectorStore_1.VectorStore {
122
155
  catch {
123
156
  throw new Error("apache-arrow is not installed. Install it with: npm install apache-arrow");
124
157
  }
125
- const schema = new arrow.Schema([
158
+ // Build schema fields - use explicit type to allow different Field types
159
+ const schemaFields = [
126
160
  new arrow.Field("id", new arrow.Utf8(), false),
127
161
  new arrow.Field("text", new arrow.Utf8(), false),
128
162
  new arrow.Field("vector", new arrow.FixedSizeList(dimensions, new arrow.Field("item", new arrow.Float32(), true)), false),
129
- new arrow.Field("metadata", new arrow.Utf8(), true),
130
- ]);
163
+ ];
164
+ // Add metadata fields - either as separate columns or as a JSON string
165
+ if (config.metadataFields && config.metadataFields.length > 0) {
166
+ for (const field of config.metadataFields) {
167
+ const nullable = field.nullable !== false;
168
+ let arrowType;
169
+ switch (field.type) {
170
+ case "string":
171
+ arrowType = new arrow.Utf8();
172
+ break;
173
+ case "number":
174
+ arrowType = new arrow.Float64();
175
+ break;
176
+ case "boolean":
177
+ arrowType = new arrow.Bool();
178
+ break;
179
+ default:
180
+ throw new Error(`Unsupported metadata field type: ${field.type}`);
181
+ }
182
+ schemaFields.push(new arrow.Field(field.name, arrowType, nullable));
183
+ }
184
+ }
185
+ else {
186
+ // Legacy: store metadata as JSON string
187
+ schemaFields.push(new arrow.Field("metadata", new arrow.Utf8(), true));
188
+ }
189
+ const schema = new arrow.Schema(schemaFields);
131
190
  table = await connection.createEmptyTable(config.tableName, schema);
132
191
  }
133
192
  return new LanceDBVectorStore(config, connection, table);
@@ -154,12 +213,25 @@ class LanceDBVectorStore extends VectorStore_1.VectorStore {
154
213
  * Add documents with pre-computed embeddings.
155
214
  */
156
215
  async addEmbeddedDocuments(documents, _options) {
157
- const records = documents.map((doc) => ({
158
- id: doc.id,
159
- text: doc.content,
160
- vector: doc.embedding,
161
- metadata: doc.metadata ? JSON.stringify(doc.metadata) : undefined,
162
- }));
216
+ const records = documents.map((doc) => {
217
+ const record = {
218
+ id: doc.id,
219
+ text: doc.content,
220
+ vector: doc.embedding,
221
+ };
222
+ if (this.metadataFields && this.metadataFields.length > 0) {
223
+ // Store each metadata field as a separate column
224
+ for (const field of this.metadataFields) {
225
+ const value = doc.metadata?.[field.name];
226
+ record[field.name] = value !== undefined ? value : null;
227
+ }
228
+ }
229
+ else {
230
+ // Legacy: store metadata as JSON string
231
+ record.metadata = doc.metadata ? JSON.stringify(doc.metadata) : undefined;
232
+ }
233
+ return record;
234
+ });
163
235
  await this.table.add(records);
164
236
  return documents.map((d) => d.id);
165
237
  }
@@ -222,28 +294,41 @@ class LanceDBVectorStore extends VectorStore_1.VectorStore {
222
294
  return {
223
295
  id: row.id,
224
296
  content: row.text,
225
- metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
297
+ metadata: this.extractMetadata(row),
226
298
  };
227
299
  }
228
300
  /**
229
301
  * Get existing documents by their content hashes.
230
302
  * Used for deduplication during ingestion.
303
+ *
304
+ * Note: If using metadataFields, include a "hash" field of type "string"
305
+ * for efficient hash lookups. Otherwise, falls back to LIKE queries on JSON metadata.
231
306
  */
232
307
  async getByHashes(hashes, _options) {
233
308
  const hashMap = new Map();
234
309
  if (hashes.length === 0) {
235
310
  return hashMap;
236
311
  }
237
- // Query for documents with matching hashes
238
- // Since hash is stored in the metadata JSON, we need to check each hash
312
+ // Check if hash is a defined metadata field for efficient queries
313
+ const hasHashField = this.metadataFields?.some((field) => field.name === "hash");
239
314
  for (const hash of hashes) {
240
- // LanceDB doesn't support JSON path queries, so we search for the hash string
241
- // in the metadata field. This works because the hash is a unique string.
242
- const results = await this.table
243
- .query()
244
- .where(`metadata LIKE '%${hash}%'`)
245
- .limit(1)
246
- .toArray();
315
+ let results;
316
+ if (hasHashField) {
317
+ // Efficient direct column query
318
+ results = await this.table
319
+ .query()
320
+ .where(`hash = '${hash}'`)
321
+ .limit(1)
322
+ .toArray();
323
+ }
324
+ else {
325
+ // Legacy: search for hash string in JSON metadata
326
+ results = await this.table
327
+ .query()
328
+ .where(`metadata LIKE '%${hash}%'`)
329
+ .limit(1)
330
+ .toArray();
331
+ }
247
332
  if (results.length > 0) {
248
333
  const record = results[0];
249
334
  hashMap.set(hash, record.id);
@@ -319,9 +404,7 @@ class LanceDBVectorStore extends VectorStore_1.VectorStore {
319
404
  if (scoreThreshold !== undefined && score < scoreThreshold) {
320
405
  continue;
321
406
  }
322
- const metadata = row.metadata
323
- ? JSON.parse(row.metadata)
324
- : undefined;
407
+ const metadata = this.extractMetadata(row);
325
408
  searchResults.push({
326
409
  document: {
327
410
  id: row.id,
@@ -333,6 +416,34 @@ class LanceDBVectorStore extends VectorStore_1.VectorStore {
333
416
  }
334
417
  return searchResults;
335
418
  }
419
+ /**
420
+ * Extract metadata from a row based on metadataFields configuration.
421
+ */
422
+ extractMetadata(row) {
423
+ if (this.metadataFields && this.metadataFields.length > 0) {
424
+ // Reconstruct metadata from separate columns
425
+ const metadata = {};
426
+ let hasValue = false;
427
+ for (const field of this.metadataFields) {
428
+ const value = row[field.name];
429
+ if (value !== null && value !== undefined) {
430
+ metadata[field.name] = value;
431
+ hasValue = true;
432
+ }
433
+ }
434
+ return hasValue ? metadata : undefined;
435
+ }
436
+ else {
437
+ // Legacy: parse metadata from JSON string
438
+ return row.metadata ? JSON.parse(row.metadata) : undefined;
439
+ }
440
+ }
441
+ /**
442
+ * Get the configured metadata fields.
443
+ */
444
+ getMetadataFields() {
445
+ return this.metadataFields;
446
+ }
336
447
  }
337
448
  exports.LanceDBVectorStore = LanceDBVectorStore;
338
449
  //# sourceMappingURL=LanceDBVectorStore.js.map