/** * OpenViking 分层历史索引 v5.1 * * 三层架构: * - L0: 时间线索引(始终加载,极度精简,~200-500 tok) * → 什么时间做了什么事,像书的目录 * → 时间戳本身就是 ID(如 202602260705),一举两得 * - L1: 关键决策摘要(按日期按需加载,~1000-2000 tok) * → 每个事件的具体细节,像每章的摘要 * → 每条决策带 [202602260705],关联到 L0 和 L2 * - L2: 完整对话(按需加载,极少触发) * → 原始 JSONL 文件,像书的正文 * → 通过时间戳 ID 从 L1/L0 定位到对应 session * * 时间戳 ID 格式: YYYYMMDDHHmm(精确到分钟,如 202602260705) * - 天然唯一,不需要额外字段 * - 同时承担"可读时间"和"唯一标识"双重角色 * - 节省 token(不需要单独的 sid:xxx 字段) * * 关联链路: * L0 (时间戳ID) → L1 ([时间戳ID]) → L2 (通过 tsid-session-map.json 映射到 sessionId) * * v5.1 变更(相对 v5): * - 去掉 sid:xxx,改用时间戳 ID * - L0 格式: "- 202602260705 | 摘要" * - L1 格式: "- [202602260705] 决策内容" * - 新增 tsid-session-map.json 映射文件 * - loadL2Session 通过时间戳 ID 反查 sessionId 再读 JSONL * * 放置位置: src/agents/history-index.ts */ /** L0 加载结果(始终加载) */ export interface L0TimelineResult { available: boolean; /** L0 时间线文本,直接注入 system prompt */ prompt: string; /** L0 原始文本(不带 XML 标签,给路由模型用) */ rawTimeline: string; /** 分层模式下保留的最近对话轮数 */ recentTurns: number; /** 日期(YYYY-MM-DD) → 时间戳ID[] 映射 */ dateTsidMap: Record; /** 时间戳ID → sessionId 映射(用于 L2 加载) */ tsidSessionMap: Record; } /** L1 加载结果(按日期按需加载) */ export interface L1DecisionsResult { available: boolean; /** L1 关键决策文本 */ prompt: string; } /** L2 加载结果(按需加载) */ export interface L2SessionResult { available: boolean; /** L2 完整对话文本 */ prompt: string; /** 实际加载的 sessionId 列表 */ loadedSessionIds: string[]; } /** * 从 L1 文本中提取所有时间戳 ID * 匹配格式: [202602260705] */ export declare function extractTsids(l1Text: string): string[]; /** * 从 L0 的 dateTsidMap 中根据日期提取时间戳 ID 列表 */ export declare function extractTsidsFromL0(l0Result: L0TimelineResult, dates?: string[]): string[]; /** * 将时间戳 ID 列表转换为 sessionId 列表(用于 L2 加载) */ export declare function resolveSessionIdsFromTsids(tsids: string[], tsidSessionMap: Record): string[]; /** * 按 sessionId 加载完整对话内容(L2) * * 触发条件:Viking 路由判断 needsL2: true * 来源:从 L1/L0 提取时间戳 ID → 通过 tsidSessionMap 转换为 sessionId → 读取 JSONL */ export declare function loadL2Session(params: { agentDir: string; sessionIds: string[]; maxTotalChars?: number; }): Promise; export declare function appendTimelineEntry(params: { agentDir: string; sessionKey: string; sessionId: string; prompt: string; assistantTexts: string[]; toolMetas: Array<{ toolName: string; }>; durationMs: number; model?: unknown; modelRegistry?: unknown; provider?: string; }): Promise; export declare function loadL0Timeline(params: { agentDir: string; }): Promise; /** * 从 decisions.md 中提取指定日期和/或时间戳 ID 的决策内容 * * decisions.md 格式: * ## 2026-02-24 * - [202602241600] 决策1 * - [202602241600] 决策2 * * ## 2026-02-26 * - [202602260705] 决策3 * * 过滤优先级: * 1. 如果指定了 tsids,精确匹配包含这些时间戳 ID 的条目 * 2. 如果指定了 dates,加载整个日期段 * 3. 都不指定则加载全部 */ export declare function loadL1Decisions(params: { agentDir: string; /** 指定要加载的日期列表 */ dates?: string[]; /** 指定要加载的时间戳 ID 列表(更精确的过滤) */ tsids?: string[]; }): Promise; export declare function maybeTriggerL1Summary(params: { agentDir: string; config?: unknown; model?: unknown; modelRegistry?: unknown; provider?: string; }): Promise; export declare function loadLayeredHistory(params: { agentDir: string; sessionKey: string; config?: unknown; }): Promise<{ enabled: boolean; prompt: string; recentTurns: number; }>;