/**
 * contextEngineering(agent) — first-class handle on the engineered
 * subset of `context.injected` events.
 *
 * The Block A8 piece. agentfootprint already emits `context.injected`
 * for EVERY piece of content that lands in a slot — including the
 * baseline flow (the user message, every tool result, the static
 * system prompt). For a developer who wants to inspect what their
 * RAG / Skills / Memory / Instructions / Steering / Facts ARE
 * INJECTING (the actual context-engineering work), the baseline flow
 * is noise.
 *
 * `contextEngineering(agent)` filters the stream to ONLY the
 * engineered injections and gives consumers two cleaner subscriptions:
 *
 *   - `onEngineered(cb)` — fires for `source` ∈ {rag, skill, memory,
 *     instructions, steering, fact, custom}. The actual
 *     context-engineering work.
 *   - `onBaseline(cb)` — fires for `source` ∈ {user, tool-result,
 *     assistant, base, registry}. The baseline message-history flow.
 *
 * Use cases:
 *   - **Lens UI**: render only engineered injections in the "context
 *     bin"; show the baseline flow as edges between iterations.
 *   - **Eval pipelines**: count how many RAG chunks vs Memory entries
 *     vs Skill bodies entered the prompt for an eval-set query.
 *   - **Cost attribution**: sum tokens by `source` to know what
 *     fraction of spend is RAG vs Skills vs baseline.
 *   - **Debug logging**: tail just the engineered signals to spot
 *     surprising activations during dev.
 *
 * Pattern: Strategy + Filter (GoF) — pure classifier function over
 *          the existing `context.injected` event payload, paired with
 *          a thin subscription helper.
 *
 * Role:    Layer-2 (event taxonomy) consumer-side helper. Doesn't
 *          emit new events; doesn't change the agent's flowchart.
 *          Pure observation.
 *
 * @example
 *   import { contextEngineering } from 'agentfootprint';
 *
 *   const ce = contextEngineering(agent);
 *   ce.onEngineered((e) => {
 *     console.log(`[${e.payload.source}] ${e.payload.contentSummary}`);
 *   });
 *   ce.onBaseline((e) => {
 *     console.log(`[baseline:${e.payload.source}]`);
 *   });
 *
 *   await agent.run({ message: 'help me' });
 *   // ... runs; engineered + baseline streams fire separately
 *
 *   ce.detach();   // stops both subscriptions; the agent itself is fine
 */
import type { AgentfootprintEventMap } from '../../events/registry.js';
import type { ContextSource } from '../../events/types.js';
/**
 * Public set of "engineered" sources — the context-engineering
 * primitives that consumers configure (RAG, Skills, Memory,
 * Instructions, Steering, Facts) plus user-defined `custom`.
 *
 * Frozen so consumers can `.has(value)` directly without copy.
 */
export declare const ENGINEERED_SOURCES: ReadonlySet<ContextSource>;
/**
 * Public set of "baseline" sources — the message-history flow that
 * exists regardless of context engineering: user input, tool results,
 * assistant outputs, the always-on system prompt anchor (`base`), and
 * the agent's static tool registry advertisement (`registry`).
 */
export declare const BASELINE_SOURCES: ReadonlySet<ContextSource>;
/**
 * Pure classifier: given a `ContextSource`, is it engineered?
 *
 * Useful for ad-hoc filtering on a raw `agent.on('agentfootprint.context.injected', ...)`
 * subscription when you don't need the wrapper helper.
 */
export declare function isEngineeredSource(source: ContextSource): boolean;
/**
 * Pure classifier: given a `ContextSource`, is it baseline?
 */
export declare function isBaselineSource(source: ContextSource): boolean;
/**
 * The shape of the event passed to `onEngineered` / `onBaseline`
 * callbacks. Same as `agentfootprint.context.injected`'s envelope —
 * we don't transform it, just route by source.
 */
export type ContextInjectedEvent = AgentfootprintEventMap['agentfootprint.context.injected'];
/** Listener signature for the wrapper helper. */
export type ContextInjectedListener = (event: ContextInjectedEvent) => void;
/** Unsubscribe handle. */
export type ContextEngineeringUnsubscribe = () => void;
/**
 * Minimal subset of the agent surface this helper depends on.
 * Lets us accept any runner (Agent, LLMCall, Sequence, etc.) that
 * implements the typed `on(type, cb)` subscription API.
 */
interface RunnerWithEvents {
    on(type: 'agentfootprint.context.injected', listener: ContextInjectedListener): ContextEngineeringUnsubscribe;
}
/**
 * Handle returned by `contextEngineering(agent)`. Lets consumers
 * subscribe to engineered / baseline streams and detach cleanly.
 */
export interface ContextEngineeringHandle {
    /**
     * Fires for `context.injected` events whose source is in
     * `ENGINEERED_SOURCES`. Returns an unsubscribe function.
     */
    onEngineered(listener: ContextInjectedListener): ContextEngineeringUnsubscribe;
    /**
     * Fires for `context.injected` events whose source is in
     * `BASELINE_SOURCES`. Returns an unsubscribe function.
     */
    onBaseline(listener: ContextInjectedListener): ContextEngineeringUnsubscribe;
    /**
     * Detach all subscriptions registered through this handle. After
     * calling, no further callbacks will fire. Idempotent (safe to
     * call multiple times).
     */
    detach(): void;
}
/**
 * Wrap a runner's `agentfootprint.context.injected` stream into two
 * filtered subscriptions: engineered + baseline. Multiple listeners
 * per stream are allowed; `detach()` removes all of them.
 *
 * The classifier inspects `event.payload.source`. Unknown sources
 * (forward-compat: `ContextSource` is open-extensible) are routed
 * to NEITHER stream — preferring under-firing over miscategorizing.
 * Use `agent.on('agentfootprint.context.injected', ...)` directly
 * if you need to observe sources that aren't (yet) classified.
 */
export declare function contextEngineering(agent: RunnerWithEvents): ContextEngineeringHandle;
export {};
