fix: carry paired turn attachments into review context (#201)
This commit is contained in:
@@ -180,7 +180,7 @@ export function applyBaseSchema(database: Database): void {
|
||||
task_id TEXT NOT NULL,
|
||||
turn_number INTEGER NOT NULL,
|
||||
role TEXT NOT NULL,
|
||||
output_text TEXT NOT NULL,
|
||||
output_text TEXT NOT NULL, attachment_payload TEXT,
|
||||
verdict TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
UNIQUE(task_id, turn_number, role)
|
||||
|
||||
@@ -42,6 +42,7 @@ function getExpectedSchemaMigrations(): Array<{
|
||||
{ version: 15, name: 'turn_progress_text' },
|
||||
{ version: 16, name: 'room_skill_overrides' },
|
||||
{ version: 17, name: 'scheduled_task_room_role' },
|
||||
{ version: 18, name: 'paired_turn_output_attachments' },
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
20
src/db/migrations/018_paired-turn-output-attachments.ts
Normal file
20
src/db/migrations/018_paired-turn-output-attachments.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { Database } from 'bun:sqlite';
|
||||
|
||||
import { tableHasColumn } from './helpers.js';
|
||||
import type { SchemaMigrationDefinition } from './types.js';
|
||||
|
||||
export const PAIRED_TURN_OUTPUT_ATTACHMENTS_MIGRATION: SchemaMigrationDefinition =
|
||||
{
|
||||
version: 18,
|
||||
name: 'paired_turn_output_attachments',
|
||||
apply(database: Database) {
|
||||
if (
|
||||
!tableHasColumn(database, 'paired_turn_outputs', 'attachment_payload')
|
||||
) {
|
||||
database.exec(`
|
||||
ALTER TABLE paired_turn_outputs
|
||||
ADD COLUMN attachment_payload TEXT
|
||||
`);
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -17,6 +17,7 @@ import { WORK_ITEM_ATTACHMENTS_MIGRATION } from './014_work-item-attachments.js'
|
||||
import { TURN_PROGRESS_TEXT_MIGRATION } from './015_turn-progress-text.js';
|
||||
import { ROOM_SKILL_OVERRIDES_MIGRATION } from './016_room-skill-overrides.js';
|
||||
import { SCHEDULED_TASK_ROOM_ROLE_MIGRATION } from './017_scheduled-task-room-role.js';
|
||||
import { PAIRED_TURN_OUTPUT_ATTACHMENTS_MIGRATION } from './018_paired-turn-output-attachments.js';
|
||||
import type {
|
||||
SchemaMigrationArgs,
|
||||
SchemaMigrationDefinition,
|
||||
@@ -42,6 +43,7 @@ const ORDERED_SCHEMA_MIGRATIONS: readonly SchemaMigrationDefinition[] = [
|
||||
TURN_PROGRESS_TEXT_MIGRATION,
|
||||
ROOM_SKILL_OVERRIDES_MIGRATION,
|
||||
SCHEDULED_TASK_ROOM_ROLE_MIGRATION,
|
||||
PAIRED_TURN_OUTPUT_ATTACHMENTS_MIGRATION,
|
||||
];
|
||||
|
||||
function ensureSchemaMigrationsTable(database: Database): void {
|
||||
|
||||
@@ -2,7 +2,15 @@ import { Database } from 'bun:sqlite';
|
||||
|
||||
import { logger } from '../logger.js';
|
||||
import { parseVisibleVerdict } from '../paired-verdict.js';
|
||||
import { PairedRoomRole, PairedTurnOutput } from '../types.js';
|
||||
import {
|
||||
OutboundAttachment,
|
||||
PairedRoomRole,
|
||||
PairedTurnOutput,
|
||||
} from '../types.js';
|
||||
import {
|
||||
parseAttachmentPayload,
|
||||
serializeAttachmentPayload,
|
||||
} from './work-items.js';
|
||||
|
||||
const MAX_TURN_OUTPUT_CHARS = 50_000;
|
||||
|
||||
@@ -12,7 +20,10 @@ export function insertPairedTurnOutputInDatabase(
|
||||
turnNumber: number,
|
||||
role: PairedRoomRole,
|
||||
outputText: string,
|
||||
createdAt?: string,
|
||||
options: {
|
||||
createdAt?: string;
|
||||
attachments?: OutboundAttachment[];
|
||||
} = {},
|
||||
): void {
|
||||
if (outputText.length > MAX_TURN_OUTPUT_CHARS) {
|
||||
logger.warn(
|
||||
@@ -30,19 +41,33 @@ export function insertPairedTurnOutputInDatabase(
|
||||
database
|
||||
.prepare(
|
||||
`INSERT OR REPLACE INTO paired_turn_outputs
|
||||
(task_id, turn_number, role, output_text, verdict, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||
(task_id, turn_number, role, output_text, attachment_payload, verdict, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
||||
)
|
||||
.run(
|
||||
taskId,
|
||||
turnNumber,
|
||||
role,
|
||||
outputText.slice(0, MAX_TURN_OUTPUT_CHARS),
|
||||
serializeAttachmentPayload(options.attachments),
|
||||
parseVisibleVerdict(outputText),
|
||||
createdAt ?? new Date().toISOString(),
|
||||
options.createdAt ?? new Date().toISOString(),
|
||||
);
|
||||
}
|
||||
|
||||
type StoredPairedTurnOutputRow = PairedTurnOutput & {
|
||||
attachment_payload?: string | null;
|
||||
};
|
||||
|
||||
function hydratePairedTurnOutputRow(
|
||||
row: StoredPairedTurnOutputRow,
|
||||
): PairedTurnOutput {
|
||||
return {
|
||||
...row,
|
||||
attachments: parseAttachmentPayload(row.attachment_payload),
|
||||
};
|
||||
}
|
||||
|
||||
export function getPairedTurnOutputsFromDatabase(
|
||||
database: Database,
|
||||
taskId: string,
|
||||
@@ -53,7 +78,8 @@ export function getPairedTurnOutputsFromDatabase(
|
||||
WHERE task_id = ?
|
||||
ORDER BY turn_number ASC`,
|
||||
)
|
||||
.all(taskId) as PairedTurnOutput[];
|
||||
.all(taskId)
|
||||
.map((row) => hydratePairedTurnOutputRow(row as StoredPairedTurnOutputRow));
|
||||
}
|
||||
|
||||
const recentOutputsForChatStmtCache = new WeakMap<
|
||||
@@ -78,8 +104,8 @@ export function getRecentPairedTurnOutputsForChatFromDatabase(
|
||||
`);
|
||||
recentOutputsForChatStmtCache.set(database, stmt);
|
||||
}
|
||||
const rows = stmt.all(chatJid, limit) as PairedTurnOutput[];
|
||||
return rows.reverse();
|
||||
const rows = stmt.all(chatJid, limit) as StoredPairedTurnOutputRow[];
|
||||
return rows.reverse().map(hydratePairedTurnOutputRow);
|
||||
}
|
||||
|
||||
export function getLatestTurnNumberFromDatabase(
|
||||
|
||||
@@ -362,15 +362,24 @@ export function insertPairedTurnOutput(
|
||||
turnNumber: number,
|
||||
role: PairedRoomRole,
|
||||
outputText: string,
|
||||
createdAt?: string,
|
||||
createdAtOrOptions?:
|
||||
| string
|
||||
| {
|
||||
createdAt?: string;
|
||||
attachments?: import('../types.js').OutboundAttachment[];
|
||||
},
|
||||
): void {
|
||||
const options =
|
||||
typeof createdAtOrOptions === 'string'
|
||||
? { createdAt: createdAtOrOptions }
|
||||
: (createdAtOrOptions ?? {});
|
||||
insertPairedTurnOutputInDatabase(
|
||||
requireDatabase(),
|
||||
taskId,
|
||||
turnNumber,
|
||||
role,
|
||||
outputText,
|
||||
createdAt,
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ function hydrateWorkItemRow(row: StoredWorkItemRow): WorkItem {
|
||||
};
|
||||
}
|
||||
|
||||
function parseAttachmentPayload(
|
||||
export function parseAttachmentPayload(
|
||||
payload: string | null | undefined,
|
||||
): OutboundAttachment[] {
|
||||
if (!payload) return [];
|
||||
@@ -130,7 +130,7 @@ function parseAttachmentPayload(
|
||||
}
|
||||
}
|
||||
|
||||
function serializeAttachmentPayload(
|
||||
export function serializeAttachmentPayload(
|
||||
attachments: OutboundAttachment[] | undefined,
|
||||
): string | null {
|
||||
if (!attachments?.length) return null;
|
||||
|
||||
Reference in New Issue
Block a user