@mastra/rag 0.1.8-alpha.10 → 0.1.8-alpha.11

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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/rag@0.1.8-alpha.10 build /home/runner/work/mastra/mastra/packages/rag
2
+ > @mastra/rag@0.1.8-alpha.11 build /home/runner/work/mastra/mastra/packages/rag
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.3.6
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 27998ms
9
+ TSC ⚡️ Build success in 21457ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.7.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/packages/rag/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.7.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/packages/rag/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 34113ms
16
+ DTS ⚡️ Build success in 14197ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- CJS dist/index.cjs 90.62 KB
21
- CJS ⚡️ Build success in 1827ms
22
- ESM dist/index.js 89.94 KB
23
- ESM ⚡️ Build success in 1831ms
20
+ CJS dist/index.cjs 90.75 KB
21
+ CJS ⚡️ Build success in 740ms
22
+ ESM dist/index.js 90.06 KB
23
+ ESM ⚡️ Build success in 741ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @mastra/rag
2
2
 
3
+ ## 0.1.8-alpha.11
4
+
5
+ ### Patch Changes
6
+
7
+ - aec08af: Update vector query tool to change input schema depending on filter enabled
8
+
3
9
  ## 0.1.8-alpha.10
4
10
 
5
11
  ### Patch Changes
@@ -143,7 +143,7 @@ declare type ExtractParams = {
143
143
  export { ExtractParams }
144
144
  export { ExtractParams as ExtractParams_alias_1 }
145
145
 
146
- declare const filterDescription = "JSON-formatted criteria to refine search results.\n- Uses provided filter if specified\n- Default: {} (no filtering)\n- Example: {\"category\": \"health\"}\n- Must be valid JSON format\n- Based on query intent\n- Multiple filters can be combined";
146
+ declare const filterDescription = "JSON-formatted criteria to refine search results.\n- Must be valid JSON format\n- Uses provided filter if specified\n- Default: \"{}\" (no filtering)\n- Example: '{\"category\": \"health\"}'\n- Based on query intent\n- Multiple filters can be combined";
147
147
  export { filterDescription }
148
148
  export { filterDescription as filterDescription_alias_1 }
149
149
  export { filterDescription as filterDescription_alias_2 }
@@ -608,7 +608,7 @@ export declare class TokenTransformer extends TextTransformer {
608
608
  }): TokenTransformer;
609
609
  }
610
610
 
611
- declare const topKDescription = "Controls how many matching documents to return.\n- Uses provided value if specified\n- Default: 10 results\n- Higher values provide more context\n- Lower values focus on best matches\n- Must be a valid number\n- Based on query requirements";
611
+ declare const topKDescription = "Controls how many matching documents to return.\n- Must be a valid number\n- Uses provided value if specified\n- Default: 10 results\n- Higher values provide more context\n- Lower values focus on best matches\n- Based on query requirements";
612
612
  export { topKDescription }
613
613
  export { topKDescription as topKDescription_alias_1 }
614
614
  export { topKDescription as topKDescription_alias_2 }
@@ -143,7 +143,7 @@ declare type ExtractParams = {
143
143
  export { ExtractParams }
144
144
  export { ExtractParams as ExtractParams_alias_1 }
145
145
 
146
- declare const filterDescription = "JSON-formatted criteria to refine search results.\n- Uses provided filter if specified\n- Default: {} (no filtering)\n- Example: {\"category\": \"health\"}\n- Must be valid JSON format\n- Based on query intent\n- Multiple filters can be combined";
146
+ declare const filterDescription = "JSON-formatted criteria to refine search results.\n- Must be valid JSON format\n- Uses provided filter if specified\n- Default: \"{}\" (no filtering)\n- Example: '{\"category\": \"health\"}'\n- Based on query intent\n- Multiple filters can be combined";
147
147
  export { filterDescription }
148
148
  export { filterDescription as filterDescription_alias_1 }
149
149
  export { filterDescription as filterDescription_alias_2 }
@@ -608,7 +608,7 @@ export declare class TokenTransformer extends TextTransformer {
608
608
  }): TokenTransformer;
609
609
  }
610
610
 
611
- declare const topKDescription = "Controls how many matching documents to return.\n- Uses provided value if specified\n- Default: 10 results\n- Higher values provide more context\n- Lower values focus on best matches\n- Must be a valid number\n- Based on query requirements";
611
+ declare const topKDescription = "Controls how many matching documents to return.\n- Must be a valid number\n- Uses provided value if specified\n- Default: 10 results\n- Higher values provide more context\n- Lower values focus on best matches\n- Based on query requirements";
612
612
  export { topKDescription }
613
613
  export { topKDescription as topKDescription_alias_1 }
614
614
  export { topKDescription as topKDescription_alias_2 }
package/dist/index.cjs CHANGED
@@ -1814,17 +1814,17 @@ var vectorQuerySearch = async ({
1814
1814
  var defaultVectorQueryDescription = () => `Access the knowledge base to find information needed to answer user questions.`;
1815
1815
  var defaultGraphRagDescription = () => `Access and analyze relationships between information in the knowledge base to answer complex questions about connections and patterns.`;
1816
1816
  var topKDescription = `Controls how many matching documents to return.
1817
+ - Must be a valid number
1817
1818
  - Uses provided value if specified
1818
1819
  - Default: 10 results
1819
1820
  - Higher values provide more context
1820
1821
  - Lower values focus on best matches
1821
- - Must be a valid number
1822
1822
  - Based on query requirements`;
1823
1823
  var filterDescription = `JSON-formatted criteria to refine search results.
1824
- - Uses provided filter if specified
1825
- - Default: {} (no filtering)
1826
- - Example: {"category": "health"}
1827
1824
  - Must be valid JSON format
1825
+ - Uses provided filter if specified
1826
+ - Default: "{}" (no filtering)
1827
+ - Example: '{"category": "health"}'
1828
1828
  - Based on query intent
1829
1829
  - Multiple filters can be combined`;
1830
1830
 
@@ -1922,13 +1922,17 @@ var createVectorQueryTool = ({
1922
1922
  }) => {
1923
1923
  const toolId = id || `VectorQuery ${vectorStoreName} ${indexName} Tool`;
1924
1924
  const toolDescription = description || defaultVectorQueryDescription();
1925
+ const baseSchema = {
1926
+ queryText: zod.z.string().describe("The text query to search for in the vector database"),
1927
+ topK: zod.z.coerce.number().describe(topKDescription)
1928
+ };
1929
+ const inputSchema = enableFilter ? zod.z.object({
1930
+ ...baseSchema,
1931
+ filter: zod.z.coerce.string().describe(filterDescription)
1932
+ }).strict() : zod.z.object(baseSchema).strict();
1925
1933
  return tools.createTool({
1926
1934
  id: toolId,
1927
- inputSchema: zod.z.object({
1928
- queryText: zod.z.string().describe("The text query to search for in the vector database"),
1929
- topK: zod.z.number().describe(topKDescription),
1930
- filter: zod.z.string().describe(filterDescription)
1931
- }),
1935
+ inputSchema,
1932
1936
  outputSchema: zod.z.object({
1933
1937
  relevantContext: zod.z.any()
1934
1938
  }),
@@ -1937,14 +1941,14 @@ var createVectorQueryTool = ({
1937
1941
  const vectorStore = mastra?.vectors?.[vectorStoreName];
1938
1942
  if (vectorStore) {
1939
1943
  let queryFilter = {};
1940
- if (enableFilter) {
1941
- queryFilter = filter ? (() => {
1944
+ if (enableFilter && filter) {
1945
+ queryFilter = (() => {
1942
1946
  try {
1943
1947
  return JSON.parse(filter);
1944
1948
  } catch {
1945
1949
  return filter;
1946
1950
  }
1947
- })() : filter;
1951
+ })();
1948
1952
  }
1949
1953
  if (mastra.logger) {
1950
1954
  mastra.logger.debug("Using this filter and topK:", { queryFilter, topK });
package/dist/index.js CHANGED
@@ -1812,17 +1812,17 @@ var vectorQuerySearch = async ({
1812
1812
  var defaultVectorQueryDescription = () => `Access the knowledge base to find information needed to answer user questions.`;
1813
1813
  var defaultGraphRagDescription = () => `Access and analyze relationships between information in the knowledge base to answer complex questions about connections and patterns.`;
1814
1814
  var topKDescription = `Controls how many matching documents to return.
1815
+ - Must be a valid number
1815
1816
  - Uses provided value if specified
1816
1817
  - Default: 10 results
1817
1818
  - Higher values provide more context
1818
1819
  - Lower values focus on best matches
1819
- - Must be a valid number
1820
1820
  - Based on query requirements`;
1821
1821
  var filterDescription = `JSON-formatted criteria to refine search results.
1822
- - Uses provided filter if specified
1823
- - Default: {} (no filtering)
1824
- - Example: {"category": "health"}
1825
1822
  - Must be valid JSON format
1823
+ - Uses provided filter if specified
1824
+ - Default: "{}" (no filtering)
1825
+ - Example: '{"category": "health"}'
1826
1826
  - Based on query intent
1827
1827
  - Multiple filters can be combined`;
1828
1828
 
@@ -1920,13 +1920,17 @@ var createVectorQueryTool = ({
1920
1920
  }) => {
1921
1921
  const toolId = id || `VectorQuery ${vectorStoreName} ${indexName} Tool`;
1922
1922
  const toolDescription = description || defaultVectorQueryDescription();
1923
+ const baseSchema = {
1924
+ queryText: z.string().describe("The text query to search for in the vector database"),
1925
+ topK: z.coerce.number().describe(topKDescription)
1926
+ };
1927
+ const inputSchema = enableFilter ? z.object({
1928
+ ...baseSchema,
1929
+ filter: z.coerce.string().describe(filterDescription)
1930
+ }).strict() : z.object(baseSchema).strict();
1923
1931
  return createTool({
1924
1932
  id: toolId,
1925
- inputSchema: z.object({
1926
- queryText: z.string().describe("The text query to search for in the vector database"),
1927
- topK: z.number().describe(topKDescription),
1928
- filter: z.string().describe(filterDescription)
1929
- }),
1933
+ inputSchema,
1930
1934
  outputSchema: z.object({
1931
1935
  relevantContext: z.any()
1932
1936
  }),
@@ -1935,14 +1939,14 @@ var createVectorQueryTool = ({
1935
1939
  const vectorStore = mastra?.vectors?.[vectorStoreName];
1936
1940
  if (vectorStore) {
1937
1941
  let queryFilter = {};
1938
- if (enableFilter) {
1939
- queryFilter = filter ? (() => {
1942
+ if (enableFilter && filter) {
1943
+ queryFilter = (() => {
1940
1944
  try {
1941
1945
  return JSON.parse(filter);
1942
1946
  } catch {
1943
1947
  return filter;
1944
1948
  }
1945
- })() : filter;
1949
+ })();
1946
1950
  }
1947
1951
  if (mastra.logger) {
1948
1952
  mastra.logger.debug("Using this filter and topK:", { queryFilter, topK });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/rag",
3
- "version": "0.1.8-alpha.10",
3
+ "version": "0.1.8-alpha.11",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,239 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { vectorQuerySearch } from '../utils';
3
+ import { createVectorQueryTool } from './vector-query';
4
+
5
+ // Mock dependencies
6
+ vi.mock('@mastra/core/tools', () => ({
7
+ createTool: vi.fn(({ inputSchema, execute }) => ({
8
+ inputSchema,
9
+ execute,
10
+ // Return a simplified version of the tool for testing
11
+ __inputSchema: inputSchema,
12
+ })),
13
+ }));
14
+
15
+ vi.mock('../utils', () => ({
16
+ vectorQuerySearch: vi.fn().mockResolvedValue({ results: [] }),
17
+ defaultVectorQueryDescription: () => 'Default vector query description',
18
+ filterDescription: 'Filter description',
19
+ topKDescription: 'Top K description',
20
+ }));
21
+
22
+ describe('createVectorQueryTool', () => {
23
+ const mockModel = { name: 'test-model' } as any;
24
+ const mockMastra = {
25
+ vectors: {
26
+ testStore: {
27
+ // Mock vector store methods
28
+ },
29
+ },
30
+ logger: {
31
+ debug: vi.fn(),
32
+ },
33
+ };
34
+
35
+ beforeEach(() => {
36
+ vi.clearAllMocks();
37
+ });
38
+
39
+ describe('input schema validation', () => {
40
+ it('should make filter invalid when enableFilter is false', () => {
41
+ // Create tool with enableFilter set to false
42
+ const tool = createVectorQueryTool({
43
+ vectorStoreName: 'testStore',
44
+ indexName: 'testIndex',
45
+ model: mockModel,
46
+ enableFilter: false,
47
+ });
48
+
49
+ // Get the Zod schema
50
+ const schema = tool.__inputSchema;
51
+
52
+ // Test with no filter (should be valid)
53
+ const validInput = {
54
+ queryText: 'test query',
55
+ topK: 5,
56
+ };
57
+ expect(() => schema.parse(validInput)).not.toThrow();
58
+
59
+ // Test with filter (should throw - unexpected property)
60
+ const inputWithFilter = {
61
+ ...validInput,
62
+ filter: '{"field": "value"}',
63
+ };
64
+ expect(() => schema.parse(inputWithFilter)).toThrow();
65
+ });
66
+
67
+ it('should handle filter permissively when enableFilter is true', () => {
68
+ const tool = createVectorQueryTool({
69
+ vectorStoreName: 'testStore',
70
+ indexName: 'testIndex',
71
+ model: mockModel,
72
+ enableFilter: true,
73
+ });
74
+
75
+ // Get the Zod schema
76
+ const schema = tool.__inputSchema;
77
+
78
+ // Test various filter inputs that should all work
79
+ const testCases = [
80
+ // String inputs
81
+ { filter: '{"field": "value"}' },
82
+ { filter: '{}' },
83
+ { filter: 'simple-string' },
84
+ // Object inputs (should be coerced to strings)
85
+ { filter: { field: 'value' } },
86
+ { filter: {} },
87
+ // Numbers (should be coerced)
88
+ { filter: 123 },
89
+ // Empty/null values (should be coerced)
90
+ { filter: '' },
91
+ { filter: null },
92
+ { filter: undefined },
93
+ ];
94
+
95
+ testCases.forEach(({ filter }) => {
96
+ expect(() =>
97
+ schema.parse({
98
+ queryText: 'test query',
99
+ topK: 5,
100
+ filter,
101
+ }),
102
+ ).not.toThrow();
103
+ });
104
+
105
+ // Verify that all parsed values are strings
106
+ testCases.forEach(({ filter }) => {
107
+ const result = schema.parse({
108
+ queryText: 'test query',
109
+ topK: 5,
110
+ filter,
111
+ });
112
+ expect(typeof result.filter).toBe('string');
113
+ });
114
+ });
115
+
116
+ it('should reject unexpected properties in both modes', () => {
117
+ // Test with enableFilter false
118
+ const toolWithoutFilter = createVectorQueryTool({
119
+ vectorStoreName: 'testStore',
120
+ indexName: 'testIndex',
121
+ model: mockModel,
122
+ enableFilter: false,
123
+ });
124
+
125
+ // Should reject unexpected property
126
+ expect(() =>
127
+ toolWithoutFilter.__inputSchema.parse({
128
+ queryText: 'test query',
129
+ topK: 5,
130
+ unexpectedProp: 'value',
131
+ }),
132
+ ).toThrow();
133
+
134
+ // Test with enableFilter true
135
+ const toolWithFilter = createVectorQueryTool({
136
+ vectorStoreName: 'testStore',
137
+ indexName: 'testIndex',
138
+ model: mockModel,
139
+ enableFilter: true,
140
+ });
141
+
142
+ // Should reject unexpected property even with valid filter
143
+ expect(() =>
144
+ toolWithFilter.__inputSchema.parse({
145
+ queryText: 'test query',
146
+ topK: 5,
147
+ filter: '{}',
148
+ unexpectedProp: 'value',
149
+ }),
150
+ ).toThrow();
151
+ });
152
+ });
153
+
154
+ describe('execute function', () => {
155
+ it('should not process filter when enableFilter is false', async () => {
156
+ // Create tool with enableFilter set to false
157
+ const tool = createVectorQueryTool({
158
+ vectorStoreName: 'testStore',
159
+ indexName: 'testIndex',
160
+ model: mockModel,
161
+ enableFilter: false,
162
+ });
163
+
164
+ // Execute with no filter
165
+ await tool.execute({
166
+ context: {
167
+ queryText: 'test query',
168
+ topK: 5,
169
+ },
170
+ mastra: mockMastra,
171
+ });
172
+
173
+ // Check that vectorQuerySearch was called with undefined queryFilter
174
+ expect(vectorQuerySearch).toHaveBeenCalledWith(
175
+ expect.objectContaining({
176
+ queryFilter: undefined,
177
+ }),
178
+ );
179
+ });
180
+
181
+ it('should process filter when enableFilter is true and filter is provided', async () => {
182
+ // Create tool with enableFilter set to true
183
+ const tool = createVectorQueryTool({
184
+ vectorStoreName: 'testStore',
185
+ indexName: 'testIndex',
186
+ model: mockModel,
187
+ enableFilter: true,
188
+ });
189
+
190
+ const filterJson = '{"field": "value"}';
191
+
192
+ // Execute with filter
193
+ await tool.execute({
194
+ context: {
195
+ queryText: 'test query',
196
+ topK: 5,
197
+ filter: filterJson,
198
+ },
199
+ mastra: mockMastra,
200
+ });
201
+
202
+ // Check that vectorQuerySearch was called with the parsed filter
203
+ expect(vectorQuerySearch).toHaveBeenCalledWith(
204
+ expect.objectContaining({
205
+ queryFilter: { field: 'value' },
206
+ }),
207
+ );
208
+ });
209
+
210
+ it('should handle string filters correctly', async () => {
211
+ // Create tool with enableFilter set to true
212
+ const tool = createVectorQueryTool({
213
+ vectorStoreName: 'testStore',
214
+ indexName: 'testIndex',
215
+ model: mockModel,
216
+ enableFilter: true,
217
+ });
218
+
219
+ const stringFilter = 'string-filter';
220
+
221
+ // Execute with string filter
222
+ await tool.execute({
223
+ context: {
224
+ queryText: 'test query',
225
+ topK: 5,
226
+ filter: stringFilter,
227
+ },
228
+ mastra: mockMastra,
229
+ });
230
+
231
+ // Check that vectorQuerySearch was called with the string filter
232
+ expect(vectorQuerySearch).toHaveBeenCalledWith(
233
+ expect.objectContaining({
234
+ queryFilter: 'string-filter',
235
+ }),
236
+ );
237
+ });
238
+ });
239
+ });
@@ -25,13 +25,22 @@ export const createVectorQueryTool = ({
25
25
  }): ReturnType<typeof createTool> => {
26
26
  const toolId = id || `VectorQuery ${vectorStoreName} ${indexName} Tool`;
27
27
  const toolDescription = description || defaultVectorQueryDescription();
28
+ // Create base schema with required fields
29
+ const baseSchema = {
30
+ queryText: z.string().describe('The text query to search for in the vector database'),
31
+ topK: z.coerce.number().describe(topKDescription),
32
+ };
33
+ const inputSchema = enableFilter
34
+ ? z
35
+ .object({
36
+ ...baseSchema,
37
+ filter: z.coerce.string().describe(filterDescription),
38
+ })
39
+ .strict()
40
+ : z.object(baseSchema).strict();
28
41
  return createTool({
29
42
  id: toolId,
30
- inputSchema: z.object({
31
- queryText: z.string().describe('The text query to search for in the vector database'),
32
- topK: z.number().describe(topKDescription),
33
- filter: z.string().describe(filterDescription),
34
- }),
43
+ inputSchema,
35
44
  outputSchema: z.object({
36
45
  relevantContext: z.any(),
37
46
  }),
@@ -42,16 +51,14 @@ export const createVectorQueryTool = ({
42
51
  // Get relevant chunks from the vector database
43
52
  if (vectorStore) {
44
53
  let queryFilter = {};
45
- if (enableFilter) {
46
- queryFilter = filter
47
- ? (() => {
48
- try {
49
- return JSON.parse(filter);
50
- } catch {
51
- return filter;
52
- }
53
- })()
54
- : filter;
54
+ if (enableFilter && filter) {
55
+ queryFilter = (() => {
56
+ try {
57
+ return JSON.parse(filter);
58
+ } catch {
59
+ return filter;
60
+ }
61
+ })();
55
62
  }
56
63
  if (mastra.logger) {
57
64
  mastra.logger.debug('Using this filter and topK:', { queryFilter, topK });
@@ -5,17 +5,17 @@ export const defaultGraphRagDescription = () =>
5
5
  `Access and analyze relationships between information in the knowledge base to answer complex questions about connections and patterns.`;
6
6
 
7
7
  export const topKDescription = `Controls how many matching documents to return.
8
+ - Must be a valid number
8
9
  - Uses provided value if specified
9
10
  - Default: 10 results
10
11
  - Higher values provide more context
11
12
  - Lower values focus on best matches
12
- - Must be a valid number
13
13
  - Based on query requirements`;
14
14
 
15
15
  export const filterDescription = `JSON-formatted criteria to refine search results.
16
- - Uses provided filter if specified
17
- - Default: {} (no filtering)
18
- - Example: {"category": "health"}
19
16
  - Must be valid JSON format
17
+ - Uses provided filter if specified
18
+ - Default: "{}" (no filtering)
19
+ - Example: '{"category": "health"}'
20
20
  - Based on query intent
21
21
  - Multiple filters can be combined`;