| import type { TokenGenStep } from '../attribution/tokenGenAttributionRunner'; |
| import type { PromptTokenSpan } from '../attribution/genAttributeDagPreprocess'; |
| import { |
| canonicalizeCompletionFinishReason, |
| isCompletionFinishReason, |
| type CompletionFinishReason, |
| } from '../utils/generationEndReasonLabel'; |
| import { |
| buildContentKeyFromBusinessKey, |
| getByContentKey, |
| listMru, |
| type CachedHistoryListRow, |
| removeByContentKey, |
| touchByContentKey, |
| upsertEntry, |
| } from './cachedHistoryStore'; |
|
|
| const NAMESPACE = 'gen_attr'; |
| const MAX_ENTRIES = 50; |
|
|
| |
| export type GenAttrRunDraft = { |
| mode: 'raw' | 'chat'; |
| |
| model?: string; |
| |
| maxTokens?: number; |
| |
| system?: string; |
| |
| user?: string; |
| |
| useSystem?: boolean; |
| |
| teacherForcing?: string; |
| |
| stopAfterTeacherForcing?: boolean; |
| }; |
|
|
| export type GenAttrCachedRun = { |
| initialContext: string; |
| steps: TokenGenStep[]; |
| |
| promptSpans?: PromptTokenSpan[]; |
| |
| completionReason?: CompletionFinishReason; |
| |
| draft?: GenAttrRunDraft; |
| }; |
|
|
| |
| |
| |
| |
| export type GenAttrCacheKey = { |
| initialContext: string; |
| model: string; |
| maxTokens: number; |
| |
| teacherForcing?: string; |
| |
| stopAfterTeacherForcing?: boolean; |
| }; |
|
|
| |
| function normalizeKey(key: GenAttrCacheKey): object { |
| const tf = key.teacherForcing && key.teacherForcing.length > 0 ? key.teacherForcing : undefined; |
| return { |
| initialContext: key.initialContext, |
| model: key.model, |
| maxTokens: key.maxTokens, |
| ...(tf !== undefined ? { teacherForcing: tf, stopAfterTeacherForcing: key.stopAfterTeacherForcing ?? false } : {}), |
| }; |
| } |
|
|
| function keyHash(key: GenAttrCacheKey): string { |
| return buildContentKeyFromBusinessKey(normalizeKey(key)); |
| } |
|
|
| export async function save( |
| key: GenAttrCacheKey, |
| steps: TokenGenStep[], |
| promptSpans: PromptTokenSpan[], |
| status: 'partial' | 'complete' = steps.length > 0 ? 'partial' : 'complete', |
| completionReason?: CompletionFinishReason, |
| draft?: GenAttrRunDraft |
| ): Promise<void> { |
| const { initialContext } = key; |
| let reasonToStore: CompletionFinishReason | undefined; |
| if (completionReason !== undefined) { |
| const c = canonicalizeCompletionFinishReason(completionReason); |
| if (!isCompletionFinishReason(c)) { |
| throw new Error(`gen_attr cache: invalid completionReason: ${completionReason}`); |
| } |
| reasonToStore = c; |
| } |
| const payload: GenAttrCachedRun = { |
| initialContext, |
| steps, |
| ...(promptSpans.length > 0 ? { promptSpans } : {}), |
| ...(reasonToStore !== undefined ? { completionReason: reasonToStore } : {}), |
| ...(draft !== undefined ? { draft } : {}), |
| }; |
| await upsertEntry({ |
| namespace: NAMESPACE, |
| businessKeyJson: JSON.stringify(normalizeKey(key)), |
| listLabel: initialContext, |
| payload, |
| status, |
| maxEntries: MAX_ENTRIES, |
| }); |
| } |
|
|
| export async function get(key: GenAttrCacheKey): Promise<GenAttrCachedRun | undefined> { |
| const row = await getByContentKey<GenAttrCachedRun>(NAMESPACE, keyHash(key)); |
| return row?.payload; |
| } |
|
|
| export async function getCachedEntryByContentKey(raw: string): Promise<GenAttrCachedRun | undefined> { |
| if (!raw) return undefined; |
| const row = await getByContentKey<GenAttrCachedRun>(NAMESPACE, raw); |
| return row?.payload; |
| } |
|
|
| export function buildCachedContentUrlParam(key: GenAttrCacheKey): string { |
| return keyHash(key); |
| } |
|
|
| export async function removeCachedEntryByContentKey(contentKey: string): Promise<void> { |
| await removeByContentKey(NAMESPACE, contentKey); |
| } |
|
|
| export async function touchCachedEntryByContentKey(contentKey: string): Promise<void> { |
| await touchByContentKey(NAMESPACE, contentKey); |
| } |
|
|
| export async function listCachedHistoryRows(): Promise<CachedHistoryListRow[]> { |
| const rows = await listMru<GenAttrCachedRun>(NAMESPACE); |
| return rows.map((r) => ({ contentKey: r.contentKey, listLabel: r.listLabel })); |
| } |
|
|