Skip to content

llm

llm

GateVerdict

Bases: BaseModel

LLM response model for llm_gate. The LLM sets block=True to deny.

NudgeVerdict

Bases: BaseModel

LLM response model for llm_nudge. The LLM sets fire=True to trigger the nudge.

PromptCheckVerdict

Bases: BaseModel

LLM response model for prompt_check. Action is "ok", "warning", or "block".

llm_gate

llm_gate(
    prompt: str,
    *,
    message: str | Callable[[GateVerdict], str],
    response_model: type[GateVerdict] = GateVerdict,
    verdict: Callable[[GateVerdict], bool] = lambda r: (
        r.block
    ),
    signals: Sequence[Signal | NlpSignal]
    | Signals
    | None = None,
    when: Callable[[BaseHookEvent], bool] | None = None,
    only_if: Sequence[TCondition] = (),
    skip_if: Sequence[TCondition] = (),
    events: Event | None = None,
    max_fires: int | None = None,
    tests: InlineTests | None = None,
    max_context: int = 2000,
    specialty: TSpecialty = "review",
    model: TModel = "small",
    agent: bool = True,
    transcript: bool = True,
) -> None

Register an LLM-powered blocking gate.

Defaults are tuned for the common case: agent=True and transcript=True so the gate has tool access and full transcript context. Pass agent=False, transcript=False for cheap, stateless yes/no checks.

Example

llm_gate("Is the agent making excuses?", ... message=lambda r: f"Excuse detected: {r.reasoning}", ... signals=Signals([Signal(r"external.*service", weight=2)], threshold=2))

llm_nudge

llm_nudge(
    prompt: str,
    *,
    message: str | Callable[[NudgeVerdict], str],
    response_model: type[NudgeVerdict] = NudgeVerdict,
    verdict: Callable[[NudgeVerdict], bool] = lambda r: (
        r.fire
    ),
    signals: Sequence[Signal | NlpSignal]
    | Signals
    | None = None,
    when: Callable[[BaseHookEvent], bool] | None = None,
    only_if: Sequence[TCondition] = (),
    skip_if: Sequence[TCondition] = (),
    events: Event | None = None,
    max_fires: int | None = None,
    tests: InlineTests | None = None,
    async_: bool = False,
    max_context: int = 2000,
    specialty: TSpecialty = "review",
    model: TModel = "small",
    agent: bool = True,
    transcript: bool = True,
) -> None

Register an LLM-powered advisory nudge.

Defaults are tuned for the common case: agent=True and transcript=True so the nudge has tool access and full transcript context. Pass agent=False, transcript=False for cheap, stateless yes/no checks.

Example

llm_nudge("Is the agent speculating instead of observing?", ... message="Observe, don't infer -- check traces first", ... signals=Signals([Signal(r"should contain", weight=2)], threshold=3))

prompt_check

prompt_check(
    evt: BaseHookEvent,
    template: str | PromptMessage,
    fmt: dict[str, Any] | None = None,
    *,
    prefix: str,
    suffix: str = "",
    timeout: int = 45,
    include_reasoning: bool = True,
    response_model: type[
        PromptCheckVerdict
    ] = PromptCheckVerdict,
) -> HookResult | None

Run an LLM check with a formatted prompt and return block/warn/None.