Skip to content

API — Agents

Status: Available in ETLantic 0.51.0 (published Beta). Human-governed context bundles, proposal sandbox, and instruction generators. Hub: Python API Reference. Tutorial: Human-governed AI.

from etlantic.agents import ALLOWED_PROPOSAL_ACTIONS, FORBIDDEN_ACTIONS

assert "inspect" in ALLOWED_PROPOSAL_ACTIONS
assert "run.submit" in FORBIDDEN_ACTIONS

Proposals never apply files. applied is always false. Apply remains the 0.42 ApprovalStore / /v1/approvals* path. Failures use PMCTX*, PMPROP*, PMGUIDE*, and PMMCP* — see Diagnostics and Exceptions.

Symbol Behavior
assemble_context_bundle Redacted inspect/validate/plan evidence; no network, no secrets
validate_proposal Deterministic sandbox; allowlisted verbs only
generate_agent_guidance Writes AGENTS.md / Claude / Codex / Cursor files; preserves user regions
Proposal / ProposalValidation Wire etlantic.proposal/1; applied is always false
ALLOWED_PROPOSAL_ACTIONS inspect, validate, plan, diff, impact, context_bundle
FORBIDDEN_ACTIONS run.submit, schedule/erasure/secret/network/tool grants, …

etlantic.agents

ETLantic agent guidance, context bundles, and human-governed proposals.

AiTask dataclass

AiTask(task_id: str, title: str, description: str, required_evidence: tuple[str, ...], approval_hook: str, forbidden_actions: tuple[str, ...] = tuple(sorted(FORBIDDEN_ACTIONS)), adapters: tuple[str, ...] = ('codex', 'claude', 'cursor'))

One vendor-neutral agent workflow.

ContextBundle dataclass

ContextBundle(schema: str = CONTEXT_BUNDLE_SCHEMA, pipeline_id: str | None = None, sources: list[dict[str, Any]] = list(), freshness: str = _now(), redacted: bool = True, graph: dict[str, Any] | None = None, plan: dict[str, Any] | None = None, diagnostics: list[dict[str, Any]] = list(), budgets: dict[str, int] = (lambda: dict(DEFAULT_BUDGETS))(), ok: bool = True)

Machine-readable inspection bundle. Never authoritative.

Proposal dataclass

Proposal(schema: str = PROPOSAL_SCHEMA, task_id: str = 'scaffold_model', kind: str = 'files', files: list[dict[str, str]] = list(), plan_fingerprint: str | None = None, policy_fingerprint: str | None = None, optimization_candidate: dict[str, Any] | None = None, requested_actions: tuple[str, ...] = ())

Ordinary reviewable files/plans. Untrusted until sandbox + approval.

action_is_forbidden

action_is_forbidden(action: str) -> bool

True for canonical mutate verbs and any sibling under those prefixes.

task_catalog

task_catalog() -> tuple[AiTask, ...]

Return the frozen vendor-neutral catalog.

assemble_context_bundle

assemble_context_bundle(pipeline: Any, *, profile: str | Any | None = 'development', budgets: Mapping[str, int] | None = None) -> ContextBundle

Assemble a bounded bundle from inspect/validate/plan. No execution.

generate_agent_guidance

generate_agent_guidance(root: str | Path, *, overwrite: bool = False, preserve_user_regions: bool = True) -> dict[str, Path]

Write agent guidance files under root.

Marked user regions are preserved. Unmarked existing files are left untouched unless overwrite=True. Generated content never grants mutation authority. Returns only paths that were written.

discover_mcp_servers

discover_mcp_servers(*, profile: Profile | None = None) -> dict[str, object]

Discover MCP extras with plugin allowlist, then PMMCP140.

mcp_server_allowed

mcp_server_allowed(profile: Profile, package_name: str, *, version: str | None = None, selected: bool = True) -> tuple[bool, object | None]

Fail closed in production when etlantic-mcp is selected.

request_proposal_approval

request_proposal_approval(store: ApprovalStore, ctx: ControlPlaneContext, validation: ProposalValidation, *, hook: str | None = None, revision_id: str | None = None) -> ApprovalRequest

Create a 0.42 approval covering the validated proposal fingerprints.

validate_proposal

validate_proposal(proposal: Proposal | Mapping[str, Any], *, pipeline: Any | None = None, profile: str | Any | None = 'development') -> ProposalValidation

Deterministic no-network/no-secret sandbox. Never applies files.

merge_user_regions

merge_user_regions(generated: str, existing: str | None) -> RegionMergeResult

Keep marked user regions from existing while replacing generated text.

If generated has no placeholders, preserved regions are appended in a generated trailer so they are not silently dropped.