fix(ts-oss): return snake_case entity ids from the redis and valkey stores (#6902)
This commit is contained in:
@@ -105,6 +105,18 @@ const ENTITY_PARAMS = [
|
|||||||
// actor_id has no camelCase alias.
|
// actor_id has no camelCase alias.
|
||||||
const IDENTITY_KEYS = [...ENTITY_PARAMS, "actor_id"];
|
const IDENTITY_KEYS = [...ENTITY_PARAMS, "actor_id"];
|
||||||
|
|
||||||
|
const PAYLOAD_METADATA_EXCLUDED_KEYS = new Set([
|
||||||
|
"user_id",
|
||||||
|
"agent_id",
|
||||||
|
"run_id",
|
||||||
|
"hash",
|
||||||
|
"data",
|
||||||
|
"createdAt",
|
||||||
|
"updatedAt",
|
||||||
|
"textLemmatized",
|
||||||
|
"attributedTo",
|
||||||
|
]);
|
||||||
|
|
||||||
// Caller metadata must not overwrite or inject an identity scope (#6342 / #6367 / #6371).
|
// Caller metadata must not overwrite or inject an identity scope (#6342 / #6367 / #6371).
|
||||||
function stripIdentityKeys(
|
function stripIdentityKeys(
|
||||||
metadata: Record<string, any> = {},
|
metadata: Record<string, any> = {},
|
||||||
@@ -1298,20 +1310,8 @@ export class Memory {
|
|||||||
metadata: {},
|
metadata: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add additional metadata
|
|
||||||
const excludedKeys = new Set([
|
|
||||||
"userId",
|
|
||||||
"agentId",
|
|
||||||
"runId",
|
|
||||||
"hash",
|
|
||||||
"data",
|
|
||||||
"createdAt",
|
|
||||||
"updatedAt",
|
|
||||||
"textLemmatized",
|
|
||||||
"attributedTo",
|
|
||||||
]);
|
|
||||||
for (const [key, value] of Object.entries(memory.payload)) {
|
for (const [key, value] of Object.entries(memory.payload)) {
|
||||||
if (!excludedKeys.has(key)) {
|
if (!PAYLOAD_METADATA_EXCLUDED_KEYS.has(key)) {
|
||||||
memoryItem.metadata![key] = value;
|
memoryItem.metadata![key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1567,18 +1567,6 @@ export class Memory {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Step 9: Format results
|
// Step 9: Format results
|
||||||
const excludedKeys = new Set([
|
|
||||||
"user_id",
|
|
||||||
"agent_id",
|
|
||||||
"run_id",
|
|
||||||
"hash",
|
|
||||||
"data",
|
|
||||||
"createdAt",
|
|
||||||
"updatedAt",
|
|
||||||
"textLemmatized",
|
|
||||||
"attributedTo",
|
|
||||||
]);
|
|
||||||
|
|
||||||
const results = scoredResults
|
const results = scoredResults
|
||||||
.filter((scored) => scored.payload?.data)
|
.filter((scored) => scored.payload?.data)
|
||||||
.map((scored) => {
|
.map((scored) => {
|
||||||
@@ -1591,7 +1579,7 @@ export class Memory {
|
|||||||
updatedAt: payload.updatedAt,
|
updatedAt: payload.updatedAt,
|
||||||
score: scored.score,
|
score: scored.score,
|
||||||
metadata: Object.entries(payload)
|
metadata: Object.entries(payload)
|
||||||
.filter(([key]) => !excludedKeys.has(key))
|
.filter(([key]) => !PAYLOAD_METADATA_EXCLUDED_KEYS.has(key))
|
||||||
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
|
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
|
||||||
...(payload.user_id && { user_id: payload.user_id }),
|
...(payload.user_id && { user_id: payload.user_id }),
|
||||||
...(payload.agent_id && { agent_id: payload.agent_id }),
|
...(payload.agent_id && { agent_id: payload.agent_id }),
|
||||||
@@ -1897,17 +1885,6 @@ export class Memory {
|
|||||||
? memories
|
? memories
|
||||||
: memories.filter((mem) => !payloadIsExpired(mem.payload));
|
: memories.filter((mem) => !payloadIsExpired(mem.payload));
|
||||||
|
|
||||||
const excludedKeys = new Set([
|
|
||||||
"user_id",
|
|
||||||
"agent_id",
|
|
||||||
"run_id",
|
|
||||||
"hash",
|
|
||||||
"data",
|
|
||||||
"createdAt",
|
|
||||||
"updatedAt",
|
|
||||||
"textLemmatized",
|
|
||||||
"attributedTo",
|
|
||||||
]);
|
|
||||||
const results = visibleMemories.slice(0, topK).map((mem) => ({
|
const results = visibleMemories.slice(0, topK).map((mem) => ({
|
||||||
id: mem.id,
|
id: mem.id,
|
||||||
memory: mem.payload.data,
|
memory: mem.payload.data,
|
||||||
@@ -1915,7 +1892,7 @@ export class Memory {
|
|||||||
createdAt: mem.payload.createdAt,
|
createdAt: mem.payload.createdAt,
|
||||||
updatedAt: mem.payload.updatedAt,
|
updatedAt: mem.payload.updatedAt,
|
||||||
metadata: Object.entries(mem.payload)
|
metadata: Object.entries(mem.payload)
|
||||||
.filter(([key]) => !excludedKeys.has(key))
|
.filter(([key]) => !PAYLOAD_METADATA_EXCLUDED_KEYS.has(key))
|
||||||
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
|
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
|
||||||
...(mem.payload.user_id && { user_id: mem.payload.user_id }),
|
...(mem.payload.user_id && { user_id: mem.payload.user_id }),
|
||||||
...(mem.payload.agent_id && { agent_id: mem.payload.agent_id }),
|
...(mem.payload.agent_id && { agent_id: mem.payload.agent_id }),
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
function toCamelCase(obj: Record<string, any>): Record<string, any> {
|
||||||
|
if (typeof obj !== "object" || obj === null) return obj;
|
||||||
|
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.entries(obj).map(([key, value]) => [
|
||||||
|
key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()),
|
||||||
|
value,
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toCamelCasePreservingIds(
|
||||||
|
payload: Record<string, any>,
|
||||||
|
): Record<string, any> {
|
||||||
|
const { agent_id, run_id, user_id, ...rest } = payload;
|
||||||
|
return {
|
||||||
|
...toCamelCase(rest),
|
||||||
|
...(agent_id !== undefined && { agent_id }),
|
||||||
|
...(run_id !== undefined && { run_id }),
|
||||||
|
...(user_id !== undefined && { user_id }),
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import type {
|
|||||||
import { VectorStore } from "./base";
|
import { VectorStore } from "./base";
|
||||||
import { SearchFilters, VectorStoreConfig, VectorStoreResult } from "../types";
|
import { SearchFilters, VectorStoreConfig, VectorStoreResult } from "../types";
|
||||||
import { loadPeer } from "../utils/load_peer";
|
import { loadPeer } from "../utils/load_peer";
|
||||||
|
import { toCamelCasePreservingIds } from "../utils/casing";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escape RediSearch TAG filter special characters. Any punctuation in the
|
* Escape RediSearch TAG filter special characters. Any punctuation in the
|
||||||
@@ -145,18 +146,6 @@ export function buildRedisFilterExpr(filters?: SearchFilters): string {
|
|||||||
return conditions.length > 0 ? conditions.join(" ") : "*";
|
return conditions.length > 0 ? conditions.join(" ") : "*";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to convert object keys to camelCase
|
|
||||||
function toCamelCase(obj: Record<string, any>): Record<string, any> {
|
|
||||||
if (typeof obj !== "object" || obj === null) return obj;
|
|
||||||
|
|
||||||
return Object.fromEntries(
|
|
||||||
Object.entries(obj).map(([key, value]) => [
|
|
||||||
key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()),
|
|
||||||
value,
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export class RedisDB implements VectorStore {
|
export class RedisDB implements VectorStore {
|
||||||
private client!: RedisClientType<
|
private client!: RedisClientType<
|
||||||
RedisDefaultModules & RedisModules & RedisFunctions & RedisScripts
|
RedisDefaultModules & RedisModules & RedisFunctions & RedisScripts
|
||||||
@@ -468,7 +457,7 @@ export class RedisDB implements VectorStore {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: doc.value.memory_id,
|
id: doc.value.memory_id,
|
||||||
payload: toCamelCase(resultPayload),
|
payload: toCamelCasePreservingIds(resultPayload),
|
||||||
score: Math.max(0, 1 - (Number(doc.value.__vector_score) ?? 0)),
|
score: Math.max(0, 1 - (Number(doc.value.__vector_score) ?? 0)),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -573,7 +562,7 @@ export class RedisDB implements VectorStore {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: vectorId,
|
id: vectorId,
|
||||||
payload: toCamelCase(payload),
|
payload: toCamelCasePreservingIds(payload),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error getting vector:", error);
|
console.error("Error getting vector:", error);
|
||||||
@@ -680,7 +669,7 @@ export class RedisDB implements VectorStore {
|
|||||||
|
|
||||||
const items = results.documents.map((doc) => ({
|
const items = results.documents.map((doc) => ({
|
||||||
id: doc.value.memory_id,
|
id: doc.value.memory_id,
|
||||||
payload: toCamelCase({
|
payload: toCamelCasePreservingIds({
|
||||||
hash: doc.value.hash,
|
hash: doc.value.hash,
|
||||||
data: doc.value.memory,
|
data: doc.value.memory,
|
||||||
created_at: new Date(parseInt(doc.value.created_at)).toISOString(),
|
created_at: new Date(parseInt(doc.value.created_at)).toISOString(),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { VectorStore } from "./base";
|
|||||||
import { SearchFilters, VectorStoreResult } from "../types";
|
import { SearchFilters, VectorStoreResult } from "../types";
|
||||||
import { ValkeyConfig } from "../types/valkey";
|
import { ValkeyConfig } from "../types/valkey";
|
||||||
import { loadPeer } from "../utils/load_peer";
|
import { loadPeer } from "../utils/load_peer";
|
||||||
|
import { toCamelCasePreservingIds } from "../utils/casing";
|
||||||
|
|
||||||
interface ValkeyClient {
|
interface ValkeyClient {
|
||||||
call: (...args: (string | number | Buffer)[]) => Promise<unknown>;
|
call: (...args: (string | number | Buffer)[]) => Promise<unknown>;
|
||||||
@@ -45,16 +46,6 @@ function toSnakeCase(obj: Record<string, any>): Record<string, any> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toCamelCase(obj: Record<string, any>): Record<string, any> {
|
|
||||||
if (typeof obj !== "object" || obj === null) return obj;
|
|
||||||
return Object.fromEntries(
|
|
||||||
Object.entries(obj).map(([key, value]) => [
|
|
||||||
key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()),
|
|
||||||
value,
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ValkeySearchDoc {
|
interface ValkeySearchDoc {
|
||||||
memory_id?: string;
|
memory_id?: string;
|
||||||
hash?: string;
|
hash?: string;
|
||||||
@@ -388,7 +379,7 @@ export class ValkeyDB implements VectorStore {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: doc.memory_id ?? "",
|
id: doc.memory_id ?? "",
|
||||||
payload: toCamelCase(resultPayload),
|
payload: toCamelCasePreservingIds(resultPayload),
|
||||||
score,
|
score,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,9 +269,7 @@ describe("Memory - add()", () => {
|
|||||||
"runId",
|
"runId",
|
||||||
"actor_id",
|
"actor_id",
|
||||||
]) {
|
]) {
|
||||||
if (key !== canonicalKey) {
|
expect(stored!.metadata).not.toHaveProperty(key);
|
||||||
expect(stored!.metadata).not.toHaveProperty(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -307,10 +305,7 @@ describe("Memory - add()", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect(stored!.metadata).toEqual(
|
expect(stored!.metadata).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({ ordinary: "preserved" }),
|
||||||
[filterKey]: filterValue,
|
|
||||||
ordinary: "preserved",
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
for (const key of [
|
for (const key of [
|
||||||
"user_id",
|
"user_id",
|
||||||
@@ -321,7 +316,6 @@ describe("Memory - add()", () => {
|
|||||||
"runId",
|
"runId",
|
||||||
"actor_id",
|
"actor_id",
|
||||||
]) {
|
]) {
|
||||||
if (key === filterKey) continue;
|
|
||||||
expect(stored!.metadata).not.toHaveProperty(key);
|
expect(stored!.metadata).not.toHaveProperty(key);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -128,6 +128,16 @@ describe("Memory - get()", () => {
|
|||||||
expect(item!.createdAt).toBeDefined();
|
expect(item!.createdAt).toBeDefined();
|
||||||
expect(new Date(item!.createdAt!).toString()).not.toBe("Invalid Date");
|
expect(new Date(item!.createdAt!).toString()).not.toBe("Invalid Date");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("does not duplicate the entity id inside metadata", async () => {
|
||||||
|
const addResult: SearchResult = await memory.add("Metadata leak test", {
|
||||||
|
userId,
|
||||||
|
});
|
||||||
|
const item: any = await memory.get(addResult.results[0].id);
|
||||||
|
expect(item.user_id).toBe(userId);
|
||||||
|
expect(item.metadata).not.toHaveProperty("user_id");
|
||||||
|
expect(item.metadata).not.toHaveProperty("userId");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// ─── update() ────────────────────────────────────────────
|
// ─── update() ────────────────────────────────────────────
|
||||||
|
|||||||
@@ -125,4 +125,88 @@ describe("RedisDB – entity payload handling", () => {
|
|||||||
expect(entry.created_at).toBeGreaterThan(0);
|
expect(entry.created_at).toBeGreaterThan(0);
|
||||||
expect(Number.isNaN(entry.created_at)).toBe(false);
|
expect(Number.isNaN(entry.created_at)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("search returns entity ids as snake_case", async () => {
|
||||||
|
mockClient.ft.search.mockResolvedValue({
|
||||||
|
total: 1,
|
||||||
|
documents: [
|
||||||
|
{
|
||||||
|
id: "mem0:test:mem-1",
|
||||||
|
value: {
|
||||||
|
memory_id: "mem-1",
|
||||||
|
hash: "h1",
|
||||||
|
memory: "likes coffee",
|
||||||
|
created_at: "1700000000000",
|
||||||
|
agent_id: "agent-1",
|
||||||
|
run_id: "run-1",
|
||||||
|
user_id: "user-1",
|
||||||
|
metadata: "{}",
|
||||||
|
__vector_score: 0.1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await store.search([0.1, 0.2, 0.3, 0.4], 5);
|
||||||
|
|
||||||
|
expect(results[0].payload.user_id).toBe("user-1");
|
||||||
|
expect(results[0].payload.agent_id).toBe("agent-1");
|
||||||
|
expect(results[0].payload.run_id).toBe("run-1");
|
||||||
|
expect(results[0].payload).not.toHaveProperty("userId");
|
||||||
|
expect(results[0].payload).not.toHaveProperty("agentId");
|
||||||
|
expect(results[0].payload).not.toHaveProperty("runId");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("get returns entity ids as snake_case", async () => {
|
||||||
|
mockClient.exists.mockResolvedValue(1);
|
||||||
|
mockClient.hGetAll.mockResolvedValue({
|
||||||
|
memory_id: "mem-1",
|
||||||
|
hash: "h1",
|
||||||
|
memory: "likes coffee",
|
||||||
|
created_at: "1700000000000",
|
||||||
|
agent_id: "agent-1",
|
||||||
|
run_id: "run-1",
|
||||||
|
user_id: "user-1",
|
||||||
|
metadata: "{}",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await store.get("mem-1");
|
||||||
|
|
||||||
|
expect(result?.payload.user_id).toBe("user-1");
|
||||||
|
expect(result?.payload.agent_id).toBe("agent-1");
|
||||||
|
expect(result?.payload.run_id).toBe("run-1");
|
||||||
|
expect(result?.payload).not.toHaveProperty("userId");
|
||||||
|
expect(result?.payload).not.toHaveProperty("agentId");
|
||||||
|
expect(result?.payload).not.toHaveProperty("runId");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("list returns entity ids as snake_case", async () => {
|
||||||
|
mockClient.ft.search.mockResolvedValue({
|
||||||
|
total: 1,
|
||||||
|
documents: [
|
||||||
|
{
|
||||||
|
id: "mem0:test:mem-1",
|
||||||
|
value: {
|
||||||
|
memory_id: "mem-1",
|
||||||
|
hash: "h1",
|
||||||
|
memory: "likes coffee",
|
||||||
|
created_at: "1700000000000",
|
||||||
|
agent_id: "agent-1",
|
||||||
|
run_id: "run-1",
|
||||||
|
user_id: "user-1",
|
||||||
|
metadata: "{}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const [items] = await store.list();
|
||||||
|
|
||||||
|
expect(items[0].payload.user_id).toBe("user-1");
|
||||||
|
expect(items[0].payload.agent_id).toBe("agent-1");
|
||||||
|
expect(items[0].payload.run_id).toBe("run-1");
|
||||||
|
expect(items[0].payload).not.toHaveProperty("userId");
|
||||||
|
expect(items[0].payload).not.toHaveProperty("agentId");
|
||||||
|
expect(items[0].payload).not.toHaveProperty("runId");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ describe("Valkey – mocked iovalkey client", () => {
|
|||||||
const result = await store.get("mem-1");
|
const result = await store.get("mem-1");
|
||||||
expect(result?.id).toBe("mem-1");
|
expect(result?.id).toBe("mem-1");
|
||||||
expect(result?.payload.data).toBe("hello valkey");
|
expect(result?.payload.data).toBe("hello valkey");
|
||||||
expect(result?.payload.userId).toBe("alice");
|
expect(result?.payload.user_id).toBe("alice");
|
||||||
// created_at is persisted as unix seconds and rendered back to its ISO instant.
|
// created_at is persisted as unix seconds and rendered back to its ISO instant.
|
||||||
expect(result?.payload.createdAt).toBe("2024-01-01T00:00:00.000Z");
|
expect(result?.payload.createdAt).toBe("2024-01-01T00:00:00.000Z");
|
||||||
});
|
});
|
||||||
@@ -244,6 +244,91 @@ describe("Valkey – mocked iovalkey client", () => {
|
|||||||
expect(searchCall[2]).toContain("@user_id:{a\\|b\\ c}");
|
expect(searchCall[2]).toContain("@user_id:{a\\|b\\ c}");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("get returns entity ids as snake_case", async () => {
|
||||||
|
const store = new ValkeyDB({
|
||||||
|
collectionName: "test",
|
||||||
|
embeddingModelDims: 4,
|
||||||
|
valkeyUrl: "valkey://localhost:6379",
|
||||||
|
});
|
||||||
|
await store.initialize();
|
||||||
|
|
||||||
|
await store.insert(
|
||||||
|
[[0.1, 0.2, 0.3, 0.4]],
|
||||||
|
["mem-ids"],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
data: "likes tea",
|
||||||
|
user_id: "user-1",
|
||||||
|
agent_id: "agent-1",
|
||||||
|
run_id: "run-1",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await store.get("mem-ids");
|
||||||
|
expect(result?.payload.user_id).toBe("user-1");
|
||||||
|
expect(result?.payload.agent_id).toBe("agent-1");
|
||||||
|
expect(result?.payload.run_id).toBe("run-1");
|
||||||
|
expect(result?.payload).not.toHaveProperty("userId");
|
||||||
|
expect(result?.payload).not.toHaveProperty("agentId");
|
||||||
|
expect(result?.payload).not.toHaveProperty("runId");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("search and list return entity ids as snake_case", async () => {
|
||||||
|
const store = new ValkeyDB({
|
||||||
|
collectionName: "test",
|
||||||
|
embeddingModelDims: 4,
|
||||||
|
valkeyUrl: "valkey://localhost:6379",
|
||||||
|
});
|
||||||
|
await store.initialize();
|
||||||
|
|
||||||
|
const iovalkey = require("iovalkey");
|
||||||
|
const mockClient = iovalkey.__mockClient;
|
||||||
|
mockClient.call.mockImplementation(async (...args: any[]) => {
|
||||||
|
if (args[0] === "FT.SEARCH") {
|
||||||
|
return [
|
||||||
|
1,
|
||||||
|
"mem0:test:mem-search",
|
||||||
|
[
|
||||||
|
"memory_id",
|
||||||
|
"mem-search",
|
||||||
|
"hash",
|
||||||
|
"h1",
|
||||||
|
"memory",
|
||||||
|
"likes tea",
|
||||||
|
"created_at",
|
||||||
|
"1700000000",
|
||||||
|
"agent_id",
|
||||||
|
"agent-1",
|
||||||
|
"run_id",
|
||||||
|
"run-1",
|
||||||
|
"user_id",
|
||||||
|
"user-1",
|
||||||
|
"metadata",
|
||||||
|
"{}",
|
||||||
|
"vector_score",
|
||||||
|
"0.1",
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return "OK";
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await store.search([0.1, 0.2, 0.3, 0.4], 5);
|
||||||
|
expect(results[0].payload.user_id).toBe("user-1");
|
||||||
|
expect(results[0].payload.agent_id).toBe("agent-1");
|
||||||
|
expect(results[0].payload.run_id).toBe("run-1");
|
||||||
|
expect(results[0].payload).not.toHaveProperty("userId");
|
||||||
|
expect(results[0].payload).not.toHaveProperty("agentId");
|
||||||
|
expect(results[0].payload).not.toHaveProperty("runId");
|
||||||
|
|
||||||
|
const [listed] = await store.list();
|
||||||
|
expect(listed[0].payload.user_id).toBe("user-1");
|
||||||
|
expect(listed[0].payload.agent_id).toBe("agent-1");
|
||||||
|
expect(listed[0].payload.run_id).toBe("run-1");
|
||||||
|
expect(listed[0].payload).not.toHaveProperty("userId");
|
||||||
|
});
|
||||||
|
|
||||||
it("does not raise an unhandled rejection when initialization fails", async () => {
|
it("does not raise an unhandled rejection when initialization fails", async () => {
|
||||||
const iovalkey = require("iovalkey");
|
const iovalkey = require("iovalkey");
|
||||||
iovalkey.__mockClient.call.mockImplementationOnce(async () => {
|
iovalkey.__mockClient.call.mockImplementationOnce(async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user