Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions migrations/1757019168841-add-source-column.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Client } from 'pg';

const schema = process.env.DB_SCHEMA || 'tiger_memory';

export const description = 'Add a source column for memories';

export async function up() {
const client = new Client();

try {
await client.connect();
await client.query(/* sql */ `
ALTER TABLE ${schema}.memory ADD COLUMN source TEXT DEFAULT NULL;
`);
} finally {
await client.end();
}
}

export async function down() {
const client = new Client();

try {
await client.connect();
await client.query(/* sql */ `
ALTER TABLE ${schema}.memory DROP COLUMN source;
`);
} finally {
await client.end();
}
}
2 changes: 1 addition & 1 deletion src/apis/getMemories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const getMemoriesFactory: ApiFactory<
fn: async ({ key }) => {
const result = await pgPool.query<Memory>(
/* sql */ `
SELECT id, content, created_at, updated_at
SELECT id, content, source, created_at, updated_at
FROM ${schema}.memory
WHERE key = $1 AND deleted_at IS NULL
`,
Expand Down
11 changes: 6 additions & 5 deletions src/apis/remember.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { z } from 'zod';
import { ApiFactory } from '../shared/boilerplate/src/types.js';
import { ServerContext, zKey } from '../types.js';
import { ServerContext, zKey, zSource } from '../types.js';

const inputSchema = {
key: zKey,
content: z.string().min(1).describe('The content to remember.'),
source: zSource,
} as const;

const outputSchema = {
Expand All @@ -26,14 +27,14 @@ export const rememberFactory: ApiFactory<
inputSchema,
outputSchema,
},
fn: async ({ key, content }) => {
fn: async ({ key, content, source }) => {
const result = await pgPool.query<{ id: string }>(
/* sql */ `
INSERT INTO ${schema}.memory (key, content)
VALUES ($1, $2)
INSERT INTO ${schema}.memory (key, content, source)
VALUES ($1, $2, $3)
RETURNING id
`,
[key, content],
[key, content, source || null],
);

return {
Expand Down
11 changes: 6 additions & 5 deletions src/apis/update.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { z } from 'zod';
import { ApiFactory } from '../shared/boilerplate/src/types.js';
import { ServerContext, zKey } from '../types.js';
import { ServerContext, zKey, zSource } from '../types.js';
import { StatusError } from '../shared/boilerplate/src/StatusError.js';

const inputSchema = {
Expand All @@ -10,6 +10,7 @@ const inputSchema = {
.describe('The id of a specific memory to replace.'),
key: zKey,
content: z.string().min(1).describe('The new content to remember.'),
source: zSource,
} as const;

const outputSchema = {
Expand All @@ -31,15 +32,15 @@ export const updateFactory: ApiFactory<
inputSchema,
outputSchema,
},
fn: async ({ id, key, content }) => {
fn: async ({ id, key, content, source }) => {
const result = await pgPool.query<{ id: string }>(
/* sql */ `
UPDATE ${schema}.memory
SET content = $1, updated_at = NOW()
WHERE id = $2 AND key = $3 AND deleted_at IS NULL
SET content = $1, source = $2, updated_at = NOW()
WHERE id = $3 AND key = $4 AND deleted_at IS NULL
RETURNING id
`,
[content, id, key],
[content, source || null, id, key],
);

if (result.rows[0]?.id == null) {
Expand Down
9 changes: 9 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ export interface ServerContext extends Record<string, unknown> {
schema: string;
}

export const zSource = z
.string()
.min(0)
.nullable()
.describe(
'The source or origin of this memory. A deep URI to the origin of the fact is preferred (e.g., a specific URL, file path, or reference).',
);

export const zMemory = z.object({
id: z.string().describe('The unique identifier of this memory.'),
content: z.string().describe('The content of this memory.'),
source: zSource,
created_at: z
.date()
.describe('The date and time when this memory was created.'),
Expand Down