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.