mirror of
https://github.com/eliasstepanik/core.git
synced 2026-01-11 09:38:27 +00:00
132 lines
3.5 KiB
TypeScript
132 lines
3.5 KiB
TypeScript
import { runQuery } from "~/lib/neo4j.server";
|
|
import type { EpisodicNode } from "@core/types";
|
|
|
|
export async function saveEpisode(episode: EpisodicNode): Promise<string> {
|
|
const query = `
|
|
MERGE (e:Episode {uuid: $uuid})
|
|
ON CREATE SET
|
|
e.content = $content,
|
|
e.originalContent = $originalContent,
|
|
e.contentEmbedding = $contentEmbedding,
|
|
e.type = $type,
|
|
e.source = $source,
|
|
e.createdAt = $createdAt,
|
|
e.validAt = $validAt,
|
|
e.userId = $userId,
|
|
e.labels = $labels,
|
|
e.space = $space,
|
|
e.sessionId = $sessionId
|
|
ON MATCH SET
|
|
e.content = $content,
|
|
e.contentEmbedding = $contentEmbedding,
|
|
e.originalContent = $originalContent,
|
|
e.type = $type,
|
|
e.source = $source,
|
|
e.validAt = $validAt,
|
|
e.labels = $labels,
|
|
e.space = $space,
|
|
e.sessionId = $sessionId
|
|
RETURN e.uuid as uuid
|
|
`;
|
|
|
|
const params = {
|
|
uuid: episode.uuid,
|
|
content: episode.content,
|
|
originalContent: episode.originalContent,
|
|
source: episode.source,
|
|
type: episode.type,
|
|
userId: episode.userId || null,
|
|
labels: episode.labels || [],
|
|
createdAt: episode.createdAt.toISOString(),
|
|
validAt: episode.validAt.toISOString(),
|
|
contentEmbedding: episode.contentEmbedding || [],
|
|
space: episode.space || null,
|
|
sessionId: episode.sessionId || null,
|
|
};
|
|
|
|
const result = await runQuery(query, params);
|
|
return result[0].get("uuid");
|
|
}
|
|
|
|
// Get an episode by UUID
|
|
export async function getEpisode(uuid: string): Promise<EpisodicNode | null> {
|
|
const query = `
|
|
MATCH (e:Episode {uuid: $uuid})
|
|
RETURN e
|
|
`;
|
|
|
|
const result = await runQuery(query, { uuid });
|
|
if (result.length === 0) return null;
|
|
|
|
const episode = result[0].get("e").properties;
|
|
return {
|
|
uuid: episode.uuid,
|
|
content: episode.content,
|
|
originalContent: episode.originalContent,
|
|
contentEmbedding: episode.contentEmbedding,
|
|
type: episode.type,
|
|
source: episode.source,
|
|
createdAt: new Date(episode.createdAt),
|
|
validAt: new Date(episode.validAt),
|
|
labels: episode.labels,
|
|
userId: episode.userId,
|
|
space: episode.space,
|
|
sessionId: episode.sessionId,
|
|
};
|
|
}
|
|
|
|
// Get recent episodes with optional filters
|
|
export async function getRecentEpisodes(params: {
|
|
referenceTime: Date;
|
|
limit: number;
|
|
userId: string;
|
|
source?: string;
|
|
sessionId?: string;
|
|
}): Promise<EpisodicNode[]> {
|
|
let filters = `WHERE e.validAt <= $referenceTime
|
|
AND e.userId = $userId`;
|
|
|
|
if (params.source) {
|
|
filters += `\nAND e.source = $source`;
|
|
}
|
|
|
|
if (params.sessionId) {
|
|
filters += `\nAND e.sessionId = $sessionId`;
|
|
}
|
|
|
|
const query = `
|
|
MATCH (e:Episode)
|
|
${filters}
|
|
RETURN e
|
|
ORDER BY e.validAt DESC
|
|
LIMIT ${params.limit}
|
|
`;
|
|
|
|
const queryParams = {
|
|
referenceTime: new Date(params.referenceTime).toISOString(),
|
|
userId: params.userId,
|
|
source: params.source || null,
|
|
sessionId: params.sessionId || null,
|
|
};
|
|
|
|
const result = await runQuery(query, queryParams);
|
|
|
|
return result.map((record) => {
|
|
const episode = record.get("e").properties;
|
|
return {
|
|
uuid: episode.uuid,
|
|
content: episode.content,
|
|
originalContent: episode.originalContent,
|
|
contentEmbedding: episode.contentEmbedding,
|
|
type: episode.type,
|
|
source: episode.source,
|
|
createdAt: new Date(episode.createdAt),
|
|
validAt: new Date(episode.validAt),
|
|
labels: episode.labels,
|
|
userId: episode.userId,
|
|
space: episode.space,
|
|
sessionId: episode.sessionId,
|
|
};
|
|
});
|
|
}
|