aps-agent/server/core/storage/context.ts

78 lines
2.5 KiB
TypeScript
Raw Normal View History

/** 上下文检查点(A3.8):平台保存「发给模型的上下文」的摘要与来源,权威在平台(实施设计 1.5) */
import type { Database } from './db.js';
export interface ContextCheckpoint {
sessionId: string;
summary: string;
summarySourceIds: string[];
includedMessageIds: string[];
lastMessageId: string | null;
pinned: string[];
estimatedChars: number;
updatedAt: number;
}
interface CheckpointRow {
session_id: string;
summary: string;
summary_source_ids: string;
included_message_ids: string;
last_message_id: string | null;
pinned: string;
estimated_chars: number;
updated_at: number;
}
const parseIds = (raw: string): string[] => {
try {
const parsed = JSON.parse(raw) as unknown;
return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === 'string') : [];
} catch {
return [];
}
};
export class ContextRepository {
constructor(private readonly db: Database) {}
save(checkpoint: Omit<ContextCheckpoint, 'updatedAt'>): void {
this.db
.prepare(
`insert into context_checkpoints (session_id, summary, summary_source_ids, included_message_ids, last_message_id, pinned, estimated_chars, updated_at)
values (?, ?, ?, ?, ?, ?, ?, ?)
on conflict(session_id) do update set
summary = excluded.summary,
summary_source_ids = excluded.summary_source_ids,
included_message_ids = excluded.included_message_ids,
last_message_id = excluded.last_message_id,
pinned = excluded.pinned,
estimated_chars = excluded.estimated_chars,
updated_at = excluded.updated_at`,
)
.run(
checkpoint.sessionId,
checkpoint.summary,
JSON.stringify(checkpoint.summarySourceIds),
JSON.stringify(checkpoint.includedMessageIds),
checkpoint.lastMessageId,
JSON.stringify(checkpoint.pinned),
checkpoint.estimatedChars,
Date.now(),
);
}
get(sessionId: string): ContextCheckpoint | undefined {
const row = this.db.prepare('select * from context_checkpoints where session_id = ?').get(sessionId) as unknown as CheckpointRow | undefined;
if (!row) return undefined;
return {
sessionId: row.session_id,
summary: row.summary,
summarySourceIds: parseIds(row.summary_source_ids),
includedMessageIds: parseIds(row.included_message_ids),
lastMessageId: row.last_message_id,
pinned: parseIds(row.pinned),
estimatedChars: row.estimated_chars,
updatedAt: row.updated_at,
};
}
}