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

78 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** 上下文检查点(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,
};
}
}