Skip to content

v4.12.15

Choose a tag to compare

@acn-ericlaw acn-ericlaw released this 23 Sep 01:39
· 51 commits to main since this release
Immutable release. Only release title and notes can be modified.

4.12.15 (2026-09-22)

The lock-step round with the engines: the pack moves from 4.12.1 to 4.12.15, the number the Java engine and the
Rust port ship in the same round (a version names content, not a cadence). Interop evidence for this release:
the four-runtime OpenTelemetry certification drive of 2026-09-22 — this host's forwarder and llm.stream node
under both engines' edges, one connected trace per request, confirmed in the backend UI
(docs/test-reports/otel-dynatrace-certification.md). Off by default; nothing to configure.

Added

  • The OpenTelemetry trace forwarder (otel namespace, src/otel/), the lock-step twin of the
    engines' opentelemetry-forwarder extension: with otel.forwarding=true the host hands every
    distributed-trace dataset it emits to the engines' extension route distributed.trace.forwarder,
    where the built-in forwarder maps it to one OpenTelemetry span carrying the host's exact W3C ids
    and exports it over OTLP/HTTP (protobuf) through the runtime's fetch - the same otel.* keys,
    span mapping, per-export credential headers, retry policy and failure diagnostics as the Java and
    Rust forwarders. No OpenTelemetry SDK and no new dependency: the encoder is the Rust port's
    hand-written OTLP writer, ported. Off by default.
  • The AI nodes llm.chat and llm.stream (examples/llm-nodes.mjs, joined to the demo app) - the
    Node.js twins of the Python demo's AI nodes of the agent-orchestration experiment E0: provider-neutral
    LLM adapters (Gemini and Anthropic behind one contract; select with params.provider /
    -Dllm.provider=gemini) spoken over their REST APIs through the runtime's fetch - no SDK, no
    dependency. llm.stream relays the provider's real token stream over the multi-shot reply contract,
    so a calling engine renders it progressively out its own HTTP edge; the terminal metadata carries
    model, stop_reason, usage and the trace / business correlation ids. Credentials: GEMINI_API_KEY
    (or GOOGLE_API_KEY), ANTHROPIC_API_KEY. The default Gemini model is the stable alias
    gemini-flash-latest.
  • The distributed.trace.forwarder extension route itself (DISTRIBUTED_TRACE_FORWARDER): a
    function an application registers under that name receives every emitted dataset (routed without
    a trace, so the forwarder's own execution emits none) - the engines' zero-tracing forwarder contract.

Changed

  • The forwarder's span kind now follows the engines' connected-span-tree rule: the record whose
    service is http.request - an engine edge's round-trip record - is the SERVER span, and every
    function execution is INTERNAL (a record's from no longer decides the kind). A host's own
    records are function executions, so a backend now shows them as INTERNAL hops under the
    calling engine's edge span.

  • The demo application.yml carries the otel.* keys switched off, wired to the
    OTLP_API_ENDPOINT, OTLP_AUTH_HEADER and OTLP_TOKEN environment variables, so
    -Dotel.forwarding=true at run time is enough to export to a backend.