Skip to content

Releases: sema-lisp/sema

1.28.1

Choose a tag to compare

@github-actions github-actions released this 27 Jun 20:36

Release Notes

Fixed

  • Dynamic workflow resume is safer. Checkpoint writes now resume lazily:
    when a checkpoint memo exists, (checkpoint :key expr) returns the stored
    value without evaluating expr again. Checkpoint journal events also carry
    the resume content_key, so checkpoint memo files can be inspected and
    invalidated with the same model as agent leaves.
  • Workflow memo keys now include workflow source and --args. Editing the
    workflow or changing run arguments invalidates stale memo hits automatically,
    while unchanged leaves still resume per-leaf.
  • Workflow-declared sandbox permissions are enforced. defworkflow
    metadata can declare :permissions using the same syntax as --sandbox
    (strict, all, none, or comma-separated denial capabilities such as
    no-fs-write,no-network). Workflow permissions can only tighten the
    caller's sandbox; they cannot loosen a stricter CLI sandbox or
    --allowed-paths setting.
  • Crates.io publish order includes sema-workflow. The publish workflow
    now publishes the workflow runtime crate before crates that depend on it.

Docs and Website

  • Workflow documentation caught up with the runtime. The workflow guide,
    agent-facing docs, CLI sandbox reference, builtin docs, changelog, and
    deferred notes now document :permissions, checkpoint resume behavior,
    memo invalidation, and the complete workflow permission list. The abbreviated
    :perms metadata spelling is not documented or accepted.
  • Website rendering fixes. The notebook feature page has more stable
    shortcut layout, the website logo color is fixed, and generated Open Graph
    images are deterministic by using vendored fonts and blocking external font
    requests during generation.
  • Docs/site maintenance. Architecture docs now include the sema-workflow
    crate, the workflow docs have an Open Graph image, and the playground loading
    screen has a small rotating Lisp-joke set.

Install sema-lang 1.28.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.28.1/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.28.1/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.28.1

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.28.0

Choose a tag to compare

@github-actions github-actions released this 27 Jun 18:30

Release Notes

Added

  • 7 new chat/inference providers. DeepSeek (DEEPSEEK_API_KEY),
    OpenRouter (OPENROUTER_API_KEY), Together AI (TOGETHER_API_KEY),
    Fireworks AI (FIREWORKS_API_KEY), Cerebras (CEREBRAS_API_KEY),
    SambaNova (SAMBANOVA_API_KEY), and Perplexity (PERPLEXITY_API_KEY).
    All are OpenAI-compatible and auto-configured from env vars.
    llm/configure, llm/auto-configure, and llm/with-fallback support them.
  • 3 new embedding/reranking providers. Nomic (NOMIC_API_KEY),
    Together AI, and Fireworks AI now support embeddings and reranking via
    llm/configure-embeddings and llm/auto-configure. New RerankDialect
    variants for each provider's wire format.
  • :int type validation in llm/extract. The :int type tag is now
    properly validated — accepts integers and whole-number floats, rejects
    other types.
  • [:type] list syntax in llm/extract schemas. A field spec like
    {:authors [:string]} is now sent to the model as "array of string" and
    validated as a list where each element matches the inner type.

Fixed

  • llm/configure-embeddings now wires reranking. Previously, configuring
    embeddings via llm/configure-embeddings for Jina, Voyage, or Cohere did
    not call .with_rerank() or set_rerank_provider(), so llm/rerank would
    fail with "does not support reranking". All three providers now correctly
    set up reranking when configured via this path.
  • llm/extract and llm/classify are now sandbox-gated with Caps::LLM.
    Previously only llm/extract-from-image was gated. Text-based extraction
    and classification made LLM API calls even when the sandbox denied Caps::LLM.
  • Dynamic workflows. defworkflow / phase / step / checkpoint /
    parallel / pipeline — a journaled, resumable agentic-workflow runtime.
    Define multi-phase LLM workflows as ordinary Sema code; the runtime journals
    every event to a frozen JSONL run directory (.sema/runs/<run-id>/), enforces
    budget caps (:tokens / :usd), and supports --resume via content-keyed
    memo sidecars. sema workflow run / view / index / check CLI commands.
    A web viewer (sema workflow view) renders live runs with a SQLite cross-run
    index. sema workflow check statically validates workflow files without
    evaluating them — catches arity traps and layout issues before a run.
    Doc entries for all workflow builtins are available in LSP hover/completion.
    Feature page at /feature/workflows.
  • :stack-trace on caught error maps. The VM now captures the call stack
    at error time and serializes it as a :stack-trace field on caught error
    maps — a list of {:name :file :line :col} frame maps, innermost first.
    For inline opcodes (+, -, car, etc.), a synthetic intrinsic frame is
    synthesized by decoding the opcode at the failing PC. TCO-bounded: tail
    calls reuse frames, so the trace stays small even for deep recursion.
    Source spans are now threaded through the main eval path
    (run_exprs_on_vm) via compile_program_with_spans_and_natives, so
    function frames carry :line and :col from the original source.

Fixed

  • pretty_print no longer double-serializes values. pretty_print called
    format!("{value}") to check if the compact form fit, then pp_value repeated
    the same format! at indent=0 when it didn't — walking and stringifying the
    entire tree twice. The redundant check is removed; pp_value handles it
    directly. Affects every REPL result, DAP variable inspection, and WASM
    playground output.
  • Runtime / now matches the constant folder for large integers. The
    optimizer used exact i64 division while the runtime converted to f64
    first, causing (/ 9007199254740993 1) to return different results depending
    on whether the operands were compile-time constants. A two-integer fast path
    in the runtime / uses exact i64 division when a % b == 0, falling back
    to f64 for non-whole results. +, -, * were unaffected (both paths
    already used i64).
  • ValueViewRef — zero-refcount trait impls. PartialEq, Hash, Ord,
    Display, and pp_value previously used view() which calls
    Rc::increment_strong_count + Rc::from_raw (and a matching decrement on
    drop) for every heap-typed Value comparison. A new ValueViewRef<'a> enum
    and view_ref() method use borrow_ref (raw pointer deref) instead,
    eliminating refcount mutations on every ==, cmp(), hash(), and
    format!(). Micro-benchmarked 40–60% faster on eq/cmp for strings,
    lists, and maps; 39.9% faster total across the benchmark suite.
  • VM arithmetic and comparison functions use view_ref(). vm_add,
    vm_sub, vm_mul, vm_div, vm_eq, vm_lt (the handlers for every
    ADD/SUB/MUL/DIV/EQ/LT/GT/LE/GE opcode) and the stdlib
    comparison.rs, arithmetic.rs, predicates.rs, math.rs, map.rs, and
    list.rs modules were migrated from view() to view_ref(), eliminating
    refcount churn on numeric and collection operations.
  • filter no longer double-clones passing items. Each item that passed the
    predicate was cloned twice (once for the predicate call, once for the result
    vector). Now cloned once and reused for both.
  • Optimizer extend_shadowed avoids allocation when nothing is shadowed.
    The function previously called current.to_vec() on every let/let*/
    letrec/lambda/do/try form, even when none of the new names were
    foldable builtins (the common case). Now returns Cow::Borrowed when no
    foldable names are added, avoiding the allocation entirely.
  • DAP serde_json::to_string().unwrap() replaced with error handling. Four
    sites in the DAP server (event send, initialized event, send_response,
    send_error) now log serialization errors to stderr instead of panicking.
    A malformed debug value would have crashed the entire debug session.
  • DAP decode_percent off-by-one fixed. The check i + 2 < bytes.len()
    required at least one byte after the two hex digits, so a percent-encoded
    sequence at the very end of a file URI (e.g. file%20 for a trailing space)
    was not decoded. Fixed to i + 3 <= bytes.len().
  • DAP debug query boilerplate extracted into helpers. The
    sync_channel(1) + send + spawn_blocking + recv pattern duplicated
    6× across setBreakpoints, stackTrace, scopes, variables, evaluate,
    and setVariable is now send_cmd_and_recv / send_cmd_and_recv_result.
  • Formatter token_text returns Cow<str> and token_width avoids
    allocation.
    token_text was -> String, allocating on every call including
    in measure_width where only .len() was needed. Now -> Cow<'_, str>
    (symbols — the most common token — return Cow::Borrowed), with a separate
    token_width function that computes the width without allocating.
  • Formatter format_top_level O(n²) → single-pass. When alignment failed
    for a group of N consecutive defines, the code formatted only the first and
    re-scanned the remaining N-1 on the next iteration. Now formats the entire
    group in one pass and advances past it.
  • Span::contains and Span::contains_pos consolidated. Three
    near-identical span containment functions duplicated across
    sema-lsp/helpers.rs and sema-lsp/scope.rs are now methods on Span in
    sema-core, available to all crates.

Performance

  • builtin_index() cached with OnceLock. The ~11K-line JSON doc index
    was deserialized from scratch on every ,apropos REPL command. Now parsed
    once and cached; subsequent calls return a &'static DocIndex reference.
  • BuiltinDocs::load() shares entries via Rc<DocEntry>. Each DocEntry
    (with full markdown body, params, examples) was cloned once per alias. Now
    all names for the same entry share a single Rc<DocEntry>, eliminating
    hundreds of string clones at LSP startup.
  • expand_query O(n²) → O(n) dedup. The synonym expansion in MCP
    docs_search used a linear scan per token for de-duplication. Now uses a
    HashSet.

Install sema-lang 1.28.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.28.0/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.28.0/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.28.0

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
[sema-lang-x86_64-unknown-linux-gnu.tar.xz](https://github.com/HelgeSverre/sema/releases/d...
Read more

1.27.1

Choose a tag to compare

@github-actions github-actions released this 23 Jun 22:03

Release Notes

Added

  • Scientific / exponential number literals. Floats can now be written as
    <mantissa>e<exponent>6.022e23, 1.0e19, 1e-9, -2.5E6 (e/E, optional
    exponent sign, bare-integer mantissa allowed). Out-of-range magnitudes follow
    IEEE-754 (1e400inf). An e/E not followed by (an optional sign and) digits
    is left untouched, so identifiers like e and exp are never mis-parsed.

Fixed

  • Breakpoints fire inside async tasks — in both the native DAP (VS Code) and the
    WASM playground debuggers. A breakpoint on a line that runs only inside an
    async/async/spawn task (or via async/map/pool-map/async/all/channels) was
    silently skipped because the scheduler ran every async task step in non-debug mode.
    STOP + CONTINUE and step into/over/out now work at async breakpoints (verified e2e in
    the playground). Known follow-ups: stepping across the scheduler into sibling tasks,
    and variable-panel scoping to the paused task's frame at a cooperative stop.
  • stdlib semantic-correctness sweep. A pass over divergence bugs across the standard
    library: string/foldcase and string-ci=? now use full Unicode case folding
    ("Straße" folds to "strasse", so caseless comparison matches "STRASSE") — distinct
    from string/lower; plus correctness fixes in equality (eq), shell, date/time,
    typed arrays, and text helpers, with matching doc updates.

Install sema-lang 1.27.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.27.1/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.27.1/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.27.1

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.27.0

Choose a tag to compare

@github-actions github-actions released this 23 Jun 18:02

Release Notes

Added

  • Concurrent I/O — blocking leaves now overlap on the scheduler. Previously
    async/spawn could interleave channels and sleeps, but any task that hit network or a
    subprocess froze the single VM thread for the whole round-trip, so spawned I/O ran
    serially. Now http/*, shell, llm/embed, and llm/complete / llm/classify /
    llm/extract yield to the scheduler while their work runs on a background runtime
    (via a new cooperative AwaitIo yield), so spawning them as tasks makes wall-clock
    approach max(latency) instead of sum(latency). Verified live: 4× concurrent
    llm/complete ~3.4× faster than serial; 4× llm/embed ~13.6×; 5× shell 514 ms vs
    2571 ms. Top-level (non-async) calls are unchanged — byte-identical synchronous behavior.
  • async/pool-map — bounded-concurrency fan-out: (async/pool-map f items n) maps f
    over items with at most n calls in flight, results in input order. Fan a large batch
    (embeddings, fetches, completions) across a rate-limited resource without launching
    everything at once.
  • async/map and async/spawn-all — ergonomic unbounded fan-out. (async/map f items)
    is a concurrent map (a task per item, results in input order); (async/spawn-all thunks)
    spawns a list of zero-arg thunks and awaits them all. Both are the obvious sugar over
    (async/all (map #(async/spawn …) …)); reach for async/pool-map when you need a cap.
  • Nested-trace propagation across async/spawn. Spans opened inside a spawned task now
    nest under the spawning task's active span and share its trace, so
    (with-span … (async/map …)) (or any nested async) renders as ONE connected trace tree in
    Jaeger/Phoenix/Langfuse instead of fragmenting into N disconnected single-span traces. A
    top-level spawn (no active span) still starts its own trace, so independent top-level tasks
    stay isolated.
  • True cancellation. async/cancel and async/timeout now abort in-flight I/O for
    real where the runtime allows: a cancelled/timed-out http/* request tears down its
    connection, and a shell subprocess is killed (SIGKILL) instead of running to
    completion in the background. llm/* cancellation stays best-effort (the blocking worker
    can't be interrupted mid-call; the result is discarded). async/timeout expiry now
    cancels its target task automatically (you no longer need a paired async/cancel to free
    its resources).
  • Per-task OpenTelemetry isolation. Concurrent LLM tasks each carry their own span
    stack + conversation/session/user scope (swapped on every scheduler task-switch), so
    overlapping llm/embed / llm/complete spans never cross-contaminate.

Fixed

  • Scheduler no longer reaps still-pending tasks at an outermost exit. A task spawned in
    one top-level form and awaited in a later one (e.g. a streaming-pipeline collector spawned
    before an (async/all …) of the other stages) was being cleared between scheduler runs
    → "async/await: still pending after scheduler run". The reap is now terminal-only.

Docs: Concurrency → Concurrent I/O.

Install sema-lang 1.27.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.27.0/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.27.0/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.27.0

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.26.0

Choose a tag to compare

@github-actions github-actions released this 23 Jun 00:20

Release Notes

Added

  • Sema-native tracing API. New otel/* builtins + with-span / with-session macros
    let your own Sema code emit first-class spans — not just the auto-instrumented llm/* /
    agent/* paths. with-span / otel/span wrap a block in a generic span;
    otel/set-attribute(s), otel/set-status, and otel/event annotate the innermost active
    span; the typed helpers otel/llm-span + otel/llm-usage, otel/tool-span, and
    otel/retrieval-span render a user-built LLM/tool/retrieval step as an LLM/TOOL/RETRIEVER
    span in Phoenix/Traceloop/Langfuse (via the SEMA_OTEL_COMPAT layer) with gen_ai.usage.*
    accounting identical to the built-ins; with-session / otel/with-session groups
    non-agent code into Langfuse Sessions/Users. Every form is a no-op when tracing is off and
    never changes a program's return value. Docs: Tracing & Metrics → Adding your own
    spans
    . Test: crates/sema/tests/otel_native_test.rs.

Install sema-lang 1.26.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.26.0/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.26.0/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.26.0

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.25.0

Choose a tag to compare

@github-actions github-actions released this 22 Jun 23:28

Release Notes

Added

  • llm/stream now applies resilience at stream-open. Streaming was bypassing the whole
    dispatch layer; it now runs through rate-limiting and provider fallback before the
    first token (a primary that fails to open the stream fails over to the next; once a token
    is delivered, a mid-stream failure surfaces and keeps the partial — failing over would
    re-emit it). Budgets can gate streams with llm/with-budget {... :on-stream :pre-gate}
    (off by default). The cache and mid-stream retry still don't apply to streams (use
    cassettes for deterministic stream replay).
    Verified live (OpenAI bad-model → fail over to Anthropic mid-llm/stream).
  • Per-call :timeout (ms) on llm/complete / llm/chat / llm/send. The option
    now reaches the HTTP layer as a per-request reqwest timeout for the network providers
    (Anthropic / OpenAI / Gemini) — previously parsed but ignored. (Local Ollama is excluded;
    streaming calls aren't capped, since a wall-clock timeout would kill a long legitimate stream.)

Fixed

  • OpenAI streaming dropped tool calls. stream_complete returned an empty tool_calls,
    discarding tool-call deltas — streaming agents on OpenAI were broken. It now accumulates the
    index-keyed id / function.name / function.arguments fragments and assembles them into
    the final response (verified live against the OpenAI API).
  • Gemini silent empty output. A thinking model with a small :max-tokens could spend the
    whole budget reasoning and return an empty string with finishReason: MAX_TOKENS (exit 0,
    no signal). It now raises an actionable error telling you to raise :max-tokens / lower
    :reasoning-effort (verified live; normal calls unaffected).

Install sema-lang 1.25.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.25.0/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.25.0/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.25.0

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.24.0

Choose a tag to compare

@github-actions github-actions released this 22 Jun 21:44

Release Notes

Added

  • Stdlib ergonomics — routine text/list/number helpers. Added seven builtins that
    everyday code kept hand-rolling: math/round-to (round to N decimals) and
    math/format-fixed (fixed-decimal display string); string/lines (split on line
    endings, Clojure split-lines semantics); list/contains? (boolean membership, vs
    member's Scheme tail), list/nth-or (safe indexed access with a default), and
    list/take-last / list/drop-last (tail counterparts to take/drop). The RAG
    example now leans entirely on stdlib (list/chunk, flat-map, string/take,
    math/round-to) instead of local helpers.

Changed

  • Eval test macros emit one test per case. With the tree-walker retired, eval_str
    and eval_str_compiled are the same path, so eval_tests! / eval_error_tests! no
    longer generate redundant _tw + _vm pairs — halving the eval test count with no
    loss of coverage.

  • Reranking + a full RAG pipeline. New llm/rerank cross-encoder reranking over
    Cohere / Jina / Voyage (the same key already used for embeddings) — (llm/rerank query documents {:top-k 5 :model "..." :provider :cohere}) returns {:index :score :document}
    maps, highest relevance first. This completes the retrieve-many → rerank-to-a-few RAG
    recipe with llm/embed + vector-store/* + llm/complete. The vector-store search and
    rerank steps emit OpenInference RETRIEVER / RERANKER spans (retrieval.documents.*,
    reranker.*) so a full RAG trace renders natively in Phoenix/Arize. New worked example
    examples/llm/rag-docs-search.sema (indexes Sema's own docs; make rag-demo), a
    RAG guide, and a FakeProvider regression test.

  • OpenTelemetry tags, metadata & streaming time-to-first-token (compat layer). With a
    SEMA_OTEL_COMPAT mode on, every LLM span is now auto-tagged with
    operation:/provider:/model: (+ cache-hit), and you can pass :tags (a list) and
    :metadata (a map) to llm/complete, llm/chat, llm/stream, and agent/run — tags
    merge with the auto-tags, metadata fans out to each backend's native field
    (langfuse.trace.metadata.*, langsmith.metadata.*, traceloop.association.properties.*,
    braintrust.metadata). Streamed calls record time-to-first-token
    (sema.gen_ai.server.time_to_first_token always-on; Langfuse completion_start_time +
    Traceloop gen_ai.is_streaming under compat) — a signal almost no other emitter
    reports. LangSmith now also gets its own langsmith.trace.session_id, and
    Langfuse a langfuse.release from SEMA_OTEL_RELEASE. Verified end-to-end against a live
    OTel Collector (HTTP + gRPC) and Jaeger with real provider calls; regression test in
    crates/sema/tests/otel_tags_test.rs.

  • OpenTelemetry per-direction cost split & embedding detail (OpenInference compat). LLM
    spans now also carry llm.cost.prompt / llm.cost.completion next to llm.cost.total
    (so Phoenix/Arize show the prompt-vs-completion cost breakdown), and embeddings spans
    carry embedding.model_name plus (content-gated, capped) embedding.embeddings.{i}.embedding.text.

Documentation

  • Website docs audit + reference coverage. Documented the nine new builtins
    (math/round-to, math/format-fixed, string/lines, list/contains?, list/nth-or,
    list/take-last, list/drop-last, io/read-line, io/eof?) on their stdlib pages,
    added the OTel cost-split/embedding-detail attributes to the compat doc, and gave the
    RAG/rerank guide a depth pass (score semantics, top-k, cost/scaling, error handling,
    observability). Fixed copy-paste examples that didn't run: shell returns a map
    (:stdout/:stderr/:exit-code), the web-server demo's streaming/summarize/extract
    handlers (llm/stream, llm/complete, and llm/extract's schema-first argument order).

Install sema-lang 1.24.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.24.0/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.24.0/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.24.0

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.23.0

Choose a tag to compare

@github-actions github-actions released this 22 Jun 13:34

Release Notes

Added

  • LLM cassettes — record/replay for deterministic, keyless testing & demos. A new
    sema-llm::cassette layer records real LLM responses to an NDJSON tape once, then
    replays them deterministically forever — no API key, no network. llm/complete,
    llm/chat, llm/extract, agent loops (agent/run, each turn keyed
    independently), streaming (llm/stream, the chunk sequence is recorded and
    replayed in order) and embeddings (llm/embed, vectors recorded and replayed)
    are all covered. Modes
    :auto / :replay / :record; a :replay miss is a hard error that surfaces
    prompt drift. Surface: (llm/with-cassette path opts thunk),
    llm/cassette-load/-save/-eject, and SEMA_LLM_CASSETTE /
    SEMA_LLM_CASSETTE_MODE for CI. Folds with the rest of the runtime: it sits below
    the OpenTelemetry span + response cache + cost accounting and above the provider, so
    a replay still emits its chat span and reports its recorded usage (distinct
    from a cache hit's zero usage), and with-cassette disables the response cache for
    its scope. The tape stores only the response keyed by a request hash — no prompt
    text, key, or header touches disk (redaction by construction). Docs:
    website/docs/llm/cassettes.md.

CI

  • Publish-list guard. scripts/check-publish-list.sh (run in the release
    verify gate + make check-publish-list) fails if a publishable workspace crate is
    missing from publish.yml's order — preventing the half-published release that hit
    1.22.0 when the new sema-otel crate wasn't in the list.
  • The two publishes now share a single verify gate (was one full suite per
    registry), CI uses Swatinem/rust-cache, and the per-crate publish sleeps are
    trimmed (cargo already waits for index propagation).

Install sema-lang 1.23.0

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.23.0/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.23.0/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.23.0

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.21.2

Choose a tag to compare

@github-actions github-actions released this 21 Jun 19:51

Release Notes

Bugfix + release-process hardening.

Fixed

  • Special-form names are bindable again. A change in 1.20.4 reserved special-form names (if, fn, let, and, message, …) and rejected binding any of them — but that also rejected correct value-position use, like a function parameter named message or a variable named fn, because the scope-free lowerer can't distinguish value use from operator use. It broke real code (5 bundled examples) and slipped a CI regression past four releases. The reservation is removed: special-form names shadow correctly in value position again. In operator/head position the special form still wins (a documented, accepted footgun — docs/limitations.md #36); the proper fix (full lexical shadowing) is future work.

CI / release process

  • Publishing now requires the test suite to pass. The crates.io and npm publish workflows triggered on a version tag with no dependency on CI, so a red test suite never blocked a release — which is how the reserved-name regression shipped. They now gate on a reusable verify workflow that runs the full CI-equivalent suite (fmt, clippy, doc check, cargo test, example + bytecode smoke tests) before any publish. The local release runbook was updated to run the example/bytecode smoke tests too (plain cargo test skips them).

Install sema-lang 1.21.2

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.21.2/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.21.2/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.21.2

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum

1.21.1

Choose a tag to compare

@github-actions github-actions released this 21 Jun 19:01

Release Notes

Bugfix. Found by a live stress test of the resilience features (Ollama-down →
Mistral fallback, caching, and budgets).

Fixed

  • Cache hits double-charged cost and burned budget. A cached response (llm/with-cache) makes no provider call — no tokens are consumed and no money is spent — but its stored token usage was still run through track_usage, so llm/session-usage cost and llm/with-budget spend incremented on every cache hit (e.g. a repeated call reported 2× the cost, and cache hits could trip a budget). Cache hits now report zero usage, so cost/budget reflect actual spend. Verified live (cost unchanged across identical calls; a budget that allows one real call is not tripped by subsequent cache hits) and with a deterministic regression test. Provider fallback and budget enforcement were verified correct and unchanged.

Install sema-lang 1.21.1

Install prebuilt binaries via shell script

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/HelgeSverre/sema/releases/download/v1.21.1/sema-lang-installer.sh | sh

Install prebuilt binaries via powershell script

powershell -ExecutionPolicy Bypass -c "irm https://github.com/HelgeSverre/sema/releases/download/v1.21.1/sema-lang-installer.ps1 | iex"

Install prebuilt binaries via Homebrew

brew install helgesverre/tap/sema-lang

Download sema-lang 1.21.1

File Platform Checksum
sema-lang-aarch64-apple-darwin.tar.xz Apple Silicon macOS checksum
sema-lang-x86_64-apple-darwin.tar.xz Intel macOS checksum
sema-lang-x86_64-pc-windows-msvc.zip x64 Windows checksum
sema-lang-aarch64-unknown-linux-gnu.tar.xz ARM64 Linux checksum
sema-lang-x86_64-unknown-linux-gnu.tar.xz x64 Linux checksum