| 239 | } |
| 240 | |
| 241 | export async function runPiHistorian(deps: PiHistorianDeps): Promise<void> { |
| 242 | const { |
| 243 | db, |
| 244 | sessionId, |
| 245 | directory, |
| 246 | provider, |
| 247 | runner, |
| 248 | historianModel, |
| 249 | fallbackModels, |
| 250 | historianChunkTokens, |
| 251 | boundarySnapshot: providedBoundarySnapshot, |
| 252 | refreshBoundarySnapshot, |
| 253 | currentContextLimit, |
| 254 | historianTimeoutMs = DEFAULT_HISTORIAN_TIMEOUT_MS, |
| 255 | twoPass, |
| 256 | thinkingLevel, |
| 257 | memoryEnabled, |
| 258 | autoPromote, |
| 259 | userMemoriesEnabled, |
| 260 | onPublished, |
| 261 | compartmentLeaseHolderId, |
| 262 | readBranchEntries, |
| 263 | notifyIssue, |
| 264 | ensureProjectRegistered = ensureProjectRegisteredFromPiDirectory, |
| 265 | } = deps; |
| 266 | |
| 267 | const notify = async (message: string): Promise<void> => { |
| 268 | if (shouldSuppressHistorianAlert(sessionId)) { |
| 269 | sessionLog(sessionId, "historian alert suppressed (cooldown)"); |
| 270 | return; |
| 271 | } |
| 272 | try { |
| 273 | await notifyIssue?.(message); |
| 274 | } catch (error) { |
| 275 | sessionLog(sessionId, "historian notify failed", { |
| 276 | error: describeError(error).brief, |
| 277 | }); |
| 278 | } |
| 279 | }; |
| 280 | |
| 281 | updateSessionMeta(db, sessionId, { compartmentInProgress: true }); |
| 282 | |
| 283 | // historian_runs telemetry (migration v24) — recorded ONCE in finally so every |
| 284 | // exit path is logged. Best-effort. Mirrors the OpenCode incremental runner. |
| 285 | const invocationBaseline = getLatestHistorianInvocationId(db, sessionId); |
| 286 | const telemetry: Partial<HistorianRunInput> = { |
| 287 | runKind: "incremental", |
| 288 | status: "failed", |
| 289 | }; |
| 290 | let completedSuccessfully = false; |
| 291 | let retainDrainReservationForRetryThrottle = false; |
| 292 | let drainReservation: ReturnType< |
| 293 | typeof reserveProtectedTailDrainTokens |
| 294 | >["reservation"] = null; |
| 295 | const rollbackDrainReservation = (): void => { |
| 296 | if (!drainReservation) return; |
| 297 | rollbackProtectedTailDrainReservation(db, drainReservation); |
| 298 | drainReservation = null; |