import type { HmemConfig } from '../hmem-config.js'; import type { V2Store } from './store-facade.js'; import type { SelectedSegment } from './checkpoint-select.js'; import type { EventRow } from '../store/types.js'; import { type Harness } from '../cli-checkpoint-agent.js'; /** One selected segment paired with the unextracted events the agent will read. */ export interface SegmentWithEvents { segment: SelectedSegment; events: EventRow[]; } /** The model used for the v2 extraction agent on the free claude -p path. */ export declare const V2_EXTRACTION_MODEL = "claude-haiku-4-5-20251001"; /** * v2-appropriate hmem tools the extraction agent may call. Mirrors the v1 * allowedTools list MINUS `move_nodes` — v2 has no node-moving (project * attribution is derived from `session_bindings`, so a future retroactive fix * is a `rebind_segment`, not a move). * * DEFERRED: a follow-up chunk that implements retroactive segment correction * would add `mcp__hmem__rebind_segment` here (NOT `move_nodes`). Likewise, a * follow-up that lets the agent flag off-topic segments would add the tool * backing `sessions.irrelevant` here (e.g. `mcp__hmem__rebind_segment` with a * detach, or a dedicated `mark_session_irrelevant`) and lift the * "Do NOT mark anything irrelevant" line from the prompt's MUST NOT block. */ export declare const V2_ALLOWED_TOOLS: string[]; /** Probes injectable in tests to avoid reading ambient env / spawning. */ export interface ExtractionProbes { detectHarness?: () => Harness; hasClaudeBinary?: () => boolean; } export interface RunExtractionOptions { /** * Injectable seam (REQUIRED for tests). When provided, it is called INSTEAD * of spawning `claude -p`. A test fake can simulate the agent by executing * scripted hmem writes against the real v2 store and returning — no * subprocess, no network. */ invoke?: (args: { prompt: string; mcpConfigPath: string; allowedTools: string[]; }) => Promise; /** Override harness / claude-binary detection (tests). */ probes?: ExtractionProbes; } /** * Build ONE extraction prompt covering ALL given segments. Pure and * deterministic: identical inputs always produce byte-identical output. * * @param segments selected segments + their unextracted events (by seq) * @param config carries `schemas.P.sections` for the routing table * @param projectLabel the P-entry label these segments belong to (e.g. "P0042"). * `SelectedSegment` does not carry it (the selector is * scoped by project), so we take it as an explicit param. */ export declare function buildV2ExtractionPrompt(segments: SegmentWithEvents[], config: HmemConfig, projectLabel: string): string; /** * Run the v2 knowledge-extraction agent over the selected segments. * * One prompt for ALL segments → one agent invocation per pipeline run. * * Routing: * - `opts.invoke` provided → call it INSTEAD of spawning (test seam). * - claude-code harness + claude → build MCP config + prompt, spawn claude -p. * - claude binary on PATH → same (zero-config Max OAuth last resort). * - otherwise → safe no-op: log a one-line diagnostic and * return. (6c only runs this on a free path, * so a warning-and-return is correct here — * unlike v1 which throws.) * * @param projectLabel the P-entry label these segments belong to (e.g. "P0042"). * Not on `SelectedSegment`; passed explicitly (see builder). */ export declare function runV2ExtractionAgent(store: V2Store, segments: SegmentWithEvents[], config: HmemConfig, hmemPath: string, projectLabel: string, opts?: RunExtractionOptions): Promise;