Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Language migration guide: 0.3 to 0.6

Language versions are opt-in. Existing explicitly versioned files retain their behavior.

0.3 to 0.4

Add language "0.4"; to use effects, idempotency, deployment requirements, budgets, or evaluations. Existing tasks default to unspecified effects/idempotency. Declare external writes accurately before adding retries; unsafe retries become static errors. Move provider/model settings into deployment JSON when portability matters.

0.4 to 0.5

Add language "0.5"; for parallel map, race, task/tool scheduler limits, and approve. Contextual native handlers should observe Invocation.cancellation. Durable runs should supply both --event-store and a stable --execution-id; resume must use unchanged source and deployment.

0.5 to 0.6

Add language "0.6"; for imports and packages. Visibility now defaults to private, so mark imported APIs public. Replace cross-file global names with alias::name, create agl.json, and check in the generated agl.lock. Generate an API snapshot before a release so breaking changes can enforce a major version bump.

Native extensions declare extension API version 1.

Rust-only implementation

The Python implementation, package, CLI, and task/tool subprocess bridge have been removed. This is a breaking host API change: --plugin, agl::plugins, PYTHON_PROTOCOL_VERSION, and ProtocolEnvelope are no longer available. Language version headers do not restore these host features.

Run programs with agl <source> <pipeline> --input <json>. Move custom task handlers into a Rust Registry and model-callable tool handlers into ToolRegistry; use a Rust host application to register them before execution. See native extensions. Run in-language test blocks against those registries, and use cargo bench --bench runtime for the maintained benchmark.

Control-flow correctness corrections (all versions)

These fixes apply to 0.2–0.6 without a new syntax version:

  • return, break, and continue inside a successful try now propagate.
  • Optional, match, and catch bindings restore shadowed values on every exit.
  • Every reachable return must match the pipeline result type. An unrelated valid return no longer hides a mismatch.
  • Parallel branches cannot depend on sibling results. Move dependent calls after the join, or execute them sequentially.
  • Loop back-edges must preserve entry binding types; break exits participate in the post-loop scope. Use a separate variable when changing a value's type.
  • Catch can observe partial execution, so a name must have compatible types at every potential failure prefix to be readable there. Avoid changing an existing variable's type inside a try block; bind the new type to a separate name.

Returning branches no longer hide names supplied by continuing branches. AGL 0.2 still permits fallthrough; 0.3–0.6 require a return on every normally completing path. Diagnostic code AGL2001 is unchanged, but return errors now point to the incompatible expression. Incompatible code may stop passing --check; runtime value encodings and public Rust APIs are unchanged.