@kernl-sdk/turbopuffer 0.1.4 → 0.1.5

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,4 +1,4 @@
1
1
 
2
- > @kernl-sdk/turbopuffer@0.1.3 build /Users/andjones/Documents/projects/kernl/packages/storage/turbopuffer
2
+ > @kernl-sdk/turbopuffer@0.1.5 build /home/runner/work/kernl/kernl/packages/storage/turbopuffer
3
3
  > tsc && tsc-alias --resolve-full-paths
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @kernl-sdk/turbopuffer
2
2
 
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - @kernl-sdk/retrieval@0.1.4
8
+
3
9
  ## 0.1.4
4
10
 
5
11
  ### Patch Changes
@@ -317,11 +317,10 @@ describe("Lifecycle edge cases integration tests", () => {
317
317
  });
318
318
  it("topK of 0 throws", async () => {
319
319
  const index = tpuf.index(indexId);
320
- // Turbopuffer requires topK between 1 and 1200
321
320
  await expect(index.query({
322
321
  query: [{ vector: [0.1, 0.1, 0.1, 0.1] }],
323
322
  topK: 0,
324
- })).rejects.toThrow(/top_k must be between 1 and 1200/i);
323
+ })).rejects.toThrow();
325
324
  });
326
325
  });
327
326
  // ============================================================
@@ -41,7 +41,7 @@ describe.sequential("Memory Integration with Turbopuffer", { timeout: 60000 }, (
41
41
  }),
42
42
  },
43
43
  memory: {
44
- embeddingModel: "openai/text-embedding-3-small",
44
+ embedding: "openai/text-embedding-3-small",
45
45
  dimensions: 1536,
46
46
  indexId: vectorIndexId,
47
47
  },
@@ -284,4 +284,47 @@ describe.sequential("Memory Integration with Turbopuffer", { timeout: 60000 }, (
284
284
  expect(results.length).toBe(1);
285
285
  expect(results[0].document?.id).toBe(id1);
286
286
  });
287
+ it("isolates memories by agentId", async () => {
288
+ const ns = uid("ns");
289
+ // Register a second agent
290
+ const model2 = {
291
+ spec: "1.0",
292
+ provider: "test",
293
+ modelId: "test-model",
294
+ };
295
+ const agent2 = new Agent({
296
+ id: "test-agent-2",
297
+ name: "Test Agent 2",
298
+ instructions: () => "test instructions",
299
+ model: model2,
300
+ });
301
+ kernl.register(agent2);
302
+ // Create memories for each agent in the same namespace
303
+ await agent.memories.create({
304
+ namespace: ns,
305
+ collection: "facts",
306
+ content: { text: "Agent 1 knows about cats" },
307
+ });
308
+ await agent2.memories.create({
309
+ namespace: ns,
310
+ collection: "facts",
311
+ content: { text: "Agent 2 knows about cats" },
312
+ });
313
+ // Search from agent1 - should only see agent1's memory
314
+ const results1 = await agent.memories.search({
315
+ query: "cats",
316
+ filter: { scope: { namespace: ns } },
317
+ limit: 10,
318
+ });
319
+ // Search from agent2 - should only see agent2's memory
320
+ const results2 = await agent2.memories.search({
321
+ query: "cats",
322
+ filter: { scope: { namespace: ns } },
323
+ limit: 10,
324
+ });
325
+ expect(results1).toHaveLength(1);
326
+ expect(results1[0].document?.agentId).toBe("test-agent");
327
+ expect(results2).toHaveLength(1);
328
+ expect(results2[0].document?.agentId).toBe("test-agent-2");
329
+ });
287
330
  });
@@ -275,15 +275,16 @@ describe("Query modes integration tests", () => {
275
275
  expect(hits[0].document).toHaveProperty("category");
276
276
  expect(hits[0].document).toHaveProperty("priority");
277
277
  });
278
- it("include: false returns no attributes", async () => {
278
+ it("include: false returns only id", async () => {
279
279
  const hits = await index.query({
280
280
  query: [{ vector: [1.0, 0.0, 0.0, 0.0] }],
281
281
  topK: 1,
282
282
  include: false,
283
283
  });
284
284
  expect(hits.length).toBe(1);
285
- // document should be undefined or empty
286
- expect(hits[0].document).toBeUndefined();
285
+ // Turbopuffer always returns id, but no other attributes
286
+ const { id, ...rest } = hits[0].document ?? {};
287
+ expect(Object.keys(rest).length).toBe(0);
287
288
  });
288
289
  it("include: [fields] returns only specified fields", async () => {
289
290
  const hits = await index.query({
@@ -299,16 +300,16 @@ describe("Query modes integration tests", () => {
299
300
  expect(hits[0].document).not.toHaveProperty("content");
300
301
  expect(hits[0].document).not.toHaveProperty("priority");
301
302
  });
302
- it("include: [] returns no attributes", async () => {
303
+ it("include: [] returns only id", async () => {
303
304
  const hits = await index.query({
304
305
  query: [{ vector: [1.0, 0.0, 0.0, 0.0] }],
305
306
  topK: 1,
306
307
  include: [],
307
308
  });
308
309
  expect(hits.length).toBe(1);
309
- // Empty include array should return no fields
310
- expect(hits[0].document === undefined ||
311
- Object.keys(hits[0].document).length === 0).toBe(true);
310
+ // Turbopuffer always returns id, but no other attributes
311
+ const { id, ...rest } = hits[0].document ?? {};
312
+ expect(Object.keys(rest).length).toBe(0);
312
313
  });
313
314
  });
314
315
  // ============================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kernl-sdk/turbopuffer",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Turbopuffer search index adapter for kernl",
5
5
  "keywords": [
6
6
  "kernl",
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@turbopuffer/turbopuffer": "^0.10.0",
34
- "@kernl-sdk/retrieval": "0.1.3",
34
+ "@kernl-sdk/retrieval": "0.1.4",
35
35
  "@kernl-sdk/shared": "0.3.0"
36
36
  },
37
37
  "devDependencies": {
@@ -41,10 +41,10 @@
41
41
  "tsc-alias": "^1.8.10",
42
42
  "typescript": "5.9.2",
43
43
  "vitest": "^4.0.8",
44
- "@kernl-sdk/ai": "0.2.10",
45
- "kernl": "0.7.3",
46
- "@kernl-sdk/pg": "0.1.16",
47
- "@kernl-sdk/protocol": "0.2.8"
44
+ "@kernl-sdk/ai": "0.3.1",
45
+ "@kernl-sdk/pg": "0.1.24",
46
+ "@kernl-sdk/protocol": "0.3.0",
47
+ "kernl": "0.9.0"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsc && tsc-alias --resolve-full-paths",
@@ -392,13 +392,12 @@ describe("Lifecycle edge cases integration tests", () => {
392
392
  it("topK of 0 throws", async () => {
393
393
  const index = tpuf.index(indexId);
394
394
 
395
- // Turbopuffer requires topK between 1 and 1200
396
395
  await expect(
397
396
  index.query({
398
397
  query: [{ vector: [0.1, 0.1, 0.1, 0.1] }],
399
398
  topK: 0,
400
399
  }),
401
- ).rejects.toThrow(/top_k must be between 1 and 1200/i);
400
+ ).rejects.toThrow();
402
401
  });
403
402
  });
404
403
 
@@ -55,7 +55,7 @@ describe.sequential(
55
55
  }),
56
56
  },
57
57
  memory: {
58
- embeddingModel: "openai/text-embedding-3-small",
58
+ embedding: "openai/text-embedding-3-small",
59
59
  dimensions: 1536,
60
60
  indexId: vectorIndexId,
61
61
  },
@@ -349,5 +349,57 @@ describe.sequential(
349
349
  expect(results.length).toBe(1);
350
350
  expect(results[0].document?.id).toBe(id1);
351
351
  });
352
+
353
+ it("isolates memories by agentId", async () => {
354
+ const ns = uid("ns");
355
+
356
+ // Register a second agent
357
+ const model2 = {
358
+ spec: "1.0" as const,
359
+ provider: "test",
360
+ modelId: "test-model",
361
+ } as unknown as LanguageModel;
362
+
363
+ const agent2 = new Agent({
364
+ id: "test-agent-2",
365
+ name: "Test Agent 2",
366
+ instructions: () => "test instructions",
367
+ model: model2,
368
+ });
369
+ kernl.register(agent2);
370
+
371
+ // Create memories for each agent in the same namespace
372
+ await agent.memories.create({
373
+ namespace: ns,
374
+ collection: "facts",
375
+ content: { text: "Agent 1 knows about cats" },
376
+ });
377
+
378
+ await agent2.memories.create({
379
+ namespace: ns,
380
+ collection: "facts",
381
+ content: { text: "Agent 2 knows about cats" },
382
+ });
383
+
384
+ // Search from agent1 - should only see agent1's memory
385
+ const results1 = await agent.memories.search({
386
+ query: "cats",
387
+ filter: { scope: { namespace: ns } },
388
+ limit: 10,
389
+ });
390
+
391
+ // Search from agent2 - should only see agent2's memory
392
+ const results2 = await agent2.memories.search({
393
+ query: "cats",
394
+ filter: { scope: { namespace: ns } },
395
+ limit: 10,
396
+ });
397
+
398
+ expect(results1).toHaveLength(1);
399
+ expect(results1[0].document?.agentId).toBe("test-agent");
400
+
401
+ expect(results2).toHaveLength(1);
402
+ expect(results2[0].document?.agentId).toBe("test-agent-2");
403
+ });
352
404
  },
353
405
  );
@@ -342,7 +342,7 @@ describe("Query modes integration tests", () => {
342
342
  expect(hits[0].document).toHaveProperty("priority");
343
343
  });
344
344
 
345
- it("include: false returns no attributes", async () => {
345
+ it("include: false returns only id", async () => {
346
346
  const hits = await index.query({
347
347
  query: [{ vector: [1.0, 0.0, 0.0, 0.0] }],
348
348
  topK: 1,
@@ -350,8 +350,9 @@ describe("Query modes integration tests", () => {
350
350
  });
351
351
 
352
352
  expect(hits.length).toBe(1);
353
- // document should be undefined or empty
354
- expect(hits[0].document).toBeUndefined();
353
+ // Turbopuffer always returns id, but no other attributes
354
+ const { id, ...rest } = hits[0].document ?? {};
355
+ expect(Object.keys(rest).length).toBe(0);
355
356
  });
356
357
 
357
358
  it("include: [fields] returns only specified fields", async () => {
@@ -370,7 +371,7 @@ describe("Query modes integration tests", () => {
370
371
  expect(hits[0].document).not.toHaveProperty("priority");
371
372
  });
372
373
 
373
- it("include: [] returns no attributes", async () => {
374
+ it("include: [] returns only id", async () => {
374
375
  const hits = await index.query({
375
376
  query: [{ vector: [1.0, 0.0, 0.0, 0.0] }],
376
377
  topK: 1,
@@ -378,11 +379,9 @@ describe("Query modes integration tests", () => {
378
379
  });
379
380
 
380
381
  expect(hits.length).toBe(1);
381
- // Empty include array should return no fields
382
- expect(
383
- hits[0].document === undefined ||
384
- Object.keys(hits[0].document).length === 0,
385
- ).toBe(true);
382
+ // Turbopuffer always returns id, but no other attributes
383
+ const { id, ...rest } = hits[0].document ?? {};
384
+ expect(Object.keys(rest).length).toBe(0);
386
385
  });
387
386
  });
388
387
 
@@ -1,60 +0,0 @@
1
-
2
- > @kernl-sdk/turbopuffer@0.0.1 check-types /Users/andjones/Documents/projects/kernl/packages/storage/turbopuffer
3
- > tsc --noEmit
4
-
5
- src/__tests__/convert.test.ts(315,9): error TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'SearchQuery'.
6
- src/__tests__/convert.test.ts(326,9): error TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'SearchQuery'.
7
- src/__tests__/convert.test.ts(338,9): error TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'SearchQuery'.
8
- src/__tests__/convert.test.ts(355,9): error TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'SearchQuery'.
9
- src/__tests__/convert.test.ts(366,9): error TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'SearchQuery'.
10
- src/__tests__/convert.test.ts(377,9): error TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'SearchQuery'.
11
- src/__tests__/convert.test.ts(388,9): error TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'SearchQuery'.
12
- src/__tests__/convert.test.ts(432,21): error TS2339: Property 'vector' does not exist on type 'SearchHit<UnknownDocument>'.
13
- src/__tests__/integration.test.ts(27,30): error TS2345: Argument of type '{ id: string; }' is not assignable to parameter of type 'string'.
14
- src/__tests__/integration.test.ts(45,46): error TS2345: Argument of type '{ id: string; }' is not assignable to parameter of type 'string'.
15
- src/__tests__/integration.test.ts(121,46): error TS2345: Argument of type '{ id: string; }' is not assignable to parameter of type 'string'.
16
- src/__tests__/integration.test.ts(135,28): error TS2345: Argument of type '{ id: string; }' is not assignable to parameter of type 'string'.
17
- src/__tests__/integration.test.ts(153,46): error TS2345: Argument of type '{ id: string; }' is not assignable to parameter of type 'string'.
18
- src/__tests__/integration.test.ts(157,30): error TS2345: Argument of type '{ id: string; }' is not assignable to parameter of type 'string'.
19
- src/__tests__/integration.test.ts(160,39): error TS2345: Argument of type '{ id: string; }' is not assignable to parameter of type 'string'.
20
- src/__tests__/integration.test.ts(168,18): error TS2339: Property 'upsert' does not exist on type 'TurbopufferSearchIndex'.
21
- src/__tests__/integration.test.ts(179,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
22
- src/__tests__/integration.test.ts(187,30): error TS7006: Parameter 'h' implicitly has an 'any' type.
23
- src/__tests__/integration.test.ts(196,18): error TS2339: Property 'upsert' does not exist on type 'TurbopufferSearchIndex'.
24
- src/__tests__/integration.test.ts(207,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
25
- src/__tests__/integration.test.ts(214,30): error TS7006: Parameter 'h' implicitly has an 'any' type.
26
- src/__tests__/integration.test.ts(222,18): error TS2339: Property 'mupsert' does not exist on type 'TurbopufferSearchIndex'.
27
- src/__tests__/integration.test.ts(244,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
28
- src/__tests__/integration.test.ts(253,29): error TS7006: Parameter 'h' implicitly has an 'any' type.
29
- src/__tests__/integration.test.ts(260,18): error TS2339: Property 'mupsert' does not exist on type 'TurbopufferSearchIndex'.
30
- src/__tests__/integration.test.ts(266,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
31
- src/__tests__/integration.test.ts(279,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
32
- src/__tests__/integration.test.ts(293,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
33
- src/__tests__/integration.test.ts(308,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
34
- src/__tests__/integration.test.ts(333,18): error TS2339: Property 'upsert' does not exist on type 'TurbopufferSearchIndex'.
35
- src/__tests__/integration.test.ts(344,29): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
36
- src/__tests__/integration.test.ts(350,25): error TS7006: Parameter 'h' implicitly has an 'any' type.
37
- src/__tests__/integration.test.ts(353,18): error TS2339: Property 'delete' does not exist on type 'TurbopufferSearchIndex'.
38
- src/__tests__/integration.test.ts(356,25): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
39
- src/__tests__/integration.test.ts(362,25): error TS7006: Parameter 'h' implicitly has an 'any' type.
40
- src/__tests__/integration.test.ts(371,18): error TS2339: Property 'mupsert' does not exist on type 'TurbopufferSearchIndex'.
41
- src/__tests__/integration.test.ts(393,29): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
42
- src/__tests__/integration.test.ts(402,18): error TS2339: Property 'mdelete' does not exist on type 'TurbopufferSearchIndex'.
43
- src/__tests__/integration.test.ts(408,25): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
44
- src/__tests__/integration.test.ts(414,25): error TS7006: Parameter 'h' implicitly has an 'any' type.
45
- src/__tests__/integration.test.ts(415,25): error TS7006: Parameter 'h' implicitly has an 'any' type.
46
- src/__tests__/integration.test.ts(422,18): error TS2339: Property 'mupsert' does not exist on type 'TurbopufferSearchIndex'.
47
- src/__tests__/integration.test.ts(444,29): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
48
- src/__tests__/integration.test.ts(453,18): error TS2339: Property 'mdelete' does not exist on type 'TurbopufferSearchIndex'.
49
- src/__tests__/integration.test.ts(459,25): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
50
- src/__tests__/integration.test.ts(474,18): error TS2339: Property 'upsert' does not exist on type 'TurbopufferSearchIndex'.
51
- src/__tests__/integration.test.ts(485,18): error TS2339: Property 'update' does not exist on type 'TurbopufferSearchIndex'.
52
- src/__tests__/integration.test.ts(494,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
53
- src/__tests__/integration.test.ts(502,30): error TS7006: Parameter 'h' implicitly has an 'any' type.
54
- src/__tests__/integration.test.ts(514,18): error TS2339: Property 'mupsert' does not exist on type 'TurbopufferSearchIndex'.
55
- src/__tests__/integration.test.ts(536,18): error TS2339: Property 'mupdate' does not exist on type 'TurbopufferSearchIndex'.
56
- src/__tests__/integration.test.ts(550,31): error TS2339: Property 'query' does not exist on type 'TurbopufferSearchIndex'.
57
- src/__tests__/integration.test.ts(559,25): error TS7006: Parameter 'h' implicitly has an 'any' type.
58
- src/__tests__/integration.test.ts(560,25): error TS7006: Parameter 'h' implicitly has an 'any' type.
59
- src/__tests__/integration.test.ts(564,18): error TS2339: Property 'mupdate' does not exist on type 'TurbopufferSearchIndex'.
60
-  ELIFECYCLE  Command failed with exit code 2.