Extension engines & integrations¶
Framework extensions that live under lazybridge.ext.* — pip install
lazybridge ships them by default (except OTelExporter, which requires the
[otel] extra).
Connectors moved (0.8). The MCP connector and the external tool gateway are no longer
lazybridge.ext.*— they moved to the LazyTools package (lazytools.connectors.{mcp,gateway},pip install lazytoolkit). The oldlazybridge.ext.{mcp,gateway}deprecation shims were removed in 0.9 — import fromlazytoolsinstead.
For narrative usage see the corresponding guides: HumanEngine, SupervisorEngine, MCP, Evals, OpenTelemetry, Visualizer.
Human-in-the-loop¶
lazybridge.ext.hil.HumanEngine ¶
HumanEngine(*, timeout: float | None = None, ui: Literal['terminal', 'web'] | _UIProtocol = 'terminal', default: str | None = None)
Presents the task to a human and returns their response as an Envelope.
With output=PydanticModel, terminal prompts each field; web renders a form. Emits the same 8 event types as LLMEngine for transparent observability.
Source code in lazybridge/ext/hil/human.py
lazybridge.ext.hil.SupervisorEngine ¶
SupervisorEngine(*, tools: list[Tool | Callable | Any] | None = None, agents: list[Any] | None = None, store: Store | None = None, input_fn: Callable[[str], str] | None = None, ainput_fn: Callable[[str], Awaitable[str]] | None = None, timeout: float | None = None, default: str | None = None)
Human-in-the-loop engine with tool-calling and agent retry.
Source code in lazybridge/ext/hil/supervisor.py
lazybridge.ext.hil.human_agent ¶
human_agent(*, timeout: float | None = None, ui: Literal['terminal', 'web'] | Any = 'terminal', default: str | None = None, **agent_kwargs: Any) -> Agent
Build a human-input :class:Agent (approval gate / form-style HIL).
Symmetric counterpart of Agent.from_<kind>(...) for the
:class:HumanEngine. Use this for synchronous human input —
a prompt at the terminal or a web form — rather than the full REPL
of :func:supervisor_agent.
Engine kwargs (timeout, ui, default) configure the
:class:HumanEngine; remaining **agent_kwargs flow to the
unified Agent constructor::
from lazybridge.ext.hil import human_agent
human_agent(timeout=60.0, default="approve")("Approve deploy?")
Source code in lazybridge/ext/hil/__init__.py
lazybridge.ext.hil.supervisor_agent ¶
supervisor_agent(*, tools: list[Any] | None = None, agents: list[Any] | None = None, store: Any | None = None, input_fn: Callable[[str], str] | None = None, ainput_fn: Callable[[str], Awaitable[str]] | None = None, timeout: float | None = None, default: str | None = None, **agent_kwargs: Any) -> Agent
Build a human-supervised :class:Agent (REPL + tool dispatch + retry).
Symmetric counterpart of Agent.from_<kind>(...) for the
:class:SupervisorEngine. Kept on the ext side rather than as
Agent.from_supervisor to respect the core/ext import boundary
(see docs/guides/core-vs-ext.md).
Engine kwargs (tools, agents, store, input_fn /
ainput_fn, timeout, default) configure the
:class:SupervisorEngine; remaining **agent_kwargs (memory= /
session= / output= / verify= / fallback= / guard= /
name= / etc.) flow to the unified Agent constructor::
from lazybridge.ext.hil import supervisor_agent
supervisor_agent(
tools=[search],
agents=[researcher], # human can `retry researcher: <feedback>`
session=sess,
name="ops-supervisor",
)("publish a policy brief")
Source code in lazybridge/ext/hil/__init__.py
MCP integration¶
Moved to lazytools.connectors.mcp — see the MCP guide
and the LazyTools overview. Install with
pip install lazytoolkit[mcp].
Evaluation framework¶
lazybridge.ext.evals.EvalSuite ¶
lazybridge.ext.evals.EvalCase
dataclass
¶
lazybridge.ext.evals.EvalResult
dataclass
¶
Assertion helpers¶
Ready-made assertion callables for EvalCase (compose your own too):
lazybridge.ext.evals.exact_match ¶
lazybridge.ext.evals.contains ¶
lazybridge.ext.evals.not_contains ¶
lazybridge.ext.evals.min_length ¶
lazybridge.ext.evals.max_length ¶
lazybridge.ext.evals.llm_judge ¶
Returns a judge function using an agent to evaluate output.
Verdict recognition uses the same robust normaliser as
:func:lazybridge._verify.verify_with_retry (W1.1): the judge may
return any of approved / accept / allow / pass /
ok / yes / good / valid (synonyms,
case-insensitive, prefix-anchored) to approve. Explicit reject
prefixes (rejected / deny / block / fail / no
/ bad / invalid) and any unrecognised verdict are treated
as rejection (fail-safe) — so a judge that fails to produce a
clean verdict never accidentally passes a bad output.
Source code in lazybridge/ext/evals/__init__.py
Planners¶
Multi-step planning agents (lazybridge.ext.planners). orchestrator_agent /
blackboard_orchestrator_agent are the canonical factories; make_planner /
make_blackboard_planner are backward-compat aliases for the same callables.
See the Planners guide.
lazybridge.ext.planners.blackboard_orchestrator_agent
module-attribute
¶
lazybridge.ext.planners.make_plan_builder_tools ¶
Five builder tools that share state via closure.
Returns [create_plan, add_step, inspect_plan, run_plan, discard_plan].
The state is per-factory-instance — call make_plan_builder_tools
fresh for each planner agent (or each session) if you want isolated
blackboards. run_plan and discard_plan consume the plan from
the dict, so memory stays bounded as long as the planner finishes its
plans. max_plans is a hard cap on concurrent in-progress plans
(oldest-evicted on overflow) so a misbehaving planner can't leak memory.
Source code in lazybridge/ext/planners/builder.py
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | |
lazybridge.ext.planners.make_execute_plan_tool ¶
Deprecated alias for :func:make_plan_builder_tools. Returns the
list of builder tools rather than a single Tool.
Source code in lazybridge/ext/planners/builder.py
lazybridge.ext.planners.PlanSpec ¶
Bases: BaseModel
The argument shape of execute_plan.
lazybridge.ext.planners.StepSpec ¶
Bases: BaseModel
One node in the plan DAG.
OpenTelemetry exporter¶
lazybridge.ext.otel.OTelExporter ¶
Export events as OpenTelemetry spans (requires opentelemetry-sdk).
Emits gen_ai.* attributes per the OpenTelemetry Semantic
Conventions for GenAI, with proper parent-child span hierarchy.
Install: pip install lazybridge[otel]
Thread-safe: Session.emit can fan events out to this exporter
from multiple worker threads, so the in-flight span registry is
guarded by a lock. Call :meth:close to flush any spans that are
still open (e.g. when a run is cancelled before agent_finish).
The exporter sets each span as the current OTel context span while it is open, so nested agents (Agent-as-tool) automatically inherit the outer tool span as their parent without any explicit correlation id — OTel's contextvars-based propagation does the work.
Source code in lazybridge/ext/otel/exporter.py
close ¶
Flush any spans still open — e.g. after a cancelled run.
Idempotent. Without this, a run that crashes before emitting
agent_finish leaves its spans stuck for the life of the
process, and the OTel contextvars stay attached to nothing.
Source code in lazybridge/ext/otel/exporter.py
flush ¶
Drain pending spans from the BatchSpanProcessor.
No-op when batch=False (SimpleSpanProcessor flushes synchronously).
Call before process exit to ensure all spans reach the collector.
Source code in lazybridge/ext/otel/exporter.py
Visualizer¶
lazybridge.ext.viz.Visualizer ¶
Visualizer(session: Session, *, store: Store | None = None, host: str = '127.0.0.1', port: int = 0, auto_open: bool = True)
Live or replay visualizer.
Use as a context manager so the HTTP server is shut down cleanly when the with-block exits. The browser stays open across that boundary; the user is expected to close the tab themselves.
Source code in lazybridge/ext/viz/visualizer.py
open ¶
Block the caller until Ctrl+C, useful for replay scripts.