Conversation
This was referenced Sep 6, 2026
Scaffold incubator/binding-llm.spec per AGENTS.md conventions and define LlmBeginEx, LlmDataEx, and the LlmFlushEx union, modelled on binding-mcp.spec's idl. LlmBeginEx carries dialect only; model routing is deferred. LlmDataEx has no fields: content flows through the DATA frame's own payload octets and INIT/FIN through its existing flags, so nothing survives in the extension once block identity moves to the FLUSH plane. LlmFlushEx is a 7-case union covering message start, block start/end, finish, usage, keepalive, and an opaque native/raw case for re-encoding events a same-dialect route doesn't recognize. Fixes #2476 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AuZoMsETwEczJx3cbkb8EJ
Scaffolds incubator/binding-llm and incubator/binding-llm.conf, modelled on binding-mcp's SERVER/CLIENT BindingContext structure. LlmBindingInfo is annotated @Incubating so type: llm config loading is gated behind ZILLA_INCUBATOR_ENABLED via FeatureFilter, matching the AmqpBindingInfo/ PgsqlBindingInfo/RisingwaveBindingInfo precedent. Fixes #2477 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0142buJWS7C89AKr9uDJtSy4
…t-type Registers by content-type and hands back a per-stream LlmContentDecoder; stays in an internal, unexported package for now with no concrete implementation registered yet. Fixes #2478 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mw32oxEw24fLt5Ypakj6pH
jfallows
force-pushed
the
claude/issue-2478-76f5ry
branch
from
September 11, 2026 19:52
384ff38 to
b822228
Compare
Closes the non-streaming half of #2478's own scope: "Non-streaming application/json goes through the same abstraction as one event, rather than a special-cased branch." Only text/event-stream had an LlmContentDecoderSpi implementation; application/json requests (non-streaming dialect responses) had no decoder to dispatch to. LlmJsonContentDecoder treats the entire buffered document as a single event (one data + one flush call, no framing loop), mirroring LlmSseContentDecoder's structure and unit-test conventions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mw32oxEw24fLt5Ypakj6pH
3 tasks
…odecSpi LlmContentDecoderSpi and LlmContentEncoderSpi (the latter previously living downstream in #2571) let a content-type register a decoder with no matching encoder, or vice versa, since each was ServiceLoader-discovered and dispatched independently. LlmContentCodecSpi makes "this content-type is fully supported" one type-enforced fact: a single contentType() key with both supplyDecoder() and supplyEncoder(), one META-INF/services registration per content-type, one LlmContentCodecFactory dispatching both directions. Pulls the internal/encode/ base package and its text/event-stream implementation (LlmContentEncoder, LlmSseContentEncoder) forward from #2571 so the collapse can happen where decode already lives, rather than forking that package ahead of its own introduction there; #2571 will need to rebase on top of this and drop its now-duplicate copies. LlmSseContentDecoder, LlmSseContentEncoder, LlmJsonContentDecoder widen from package-private to public (unchanged otherwise) since their new LlmSseContentCodecSpi/LlmJsonContentCodecSpi providers construct them from the sibling internal.codec package. Adds LlmJsonContentEncoder (new): the application/json inverse of LlmJsonContentDecoder, copying content bytes through unchanged with no framing on flush. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mw32oxEw24fLt5Ypakj6pH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Defines
LlmContentCodecSpi, keyed by content-type, sobinding-llmcan dispatch a stream's raw bytes to the decoder/encoder pair registered for that content-type. Framing is a property of content-type, not of dialect (OpenAI and Anthropic both use SSE), so this stays a single content-type-keyed lookup rather than a per-dialect branch.LlmContentCodecSpi(io.aklivity.zilla.runtime.binding.llm.internal.codec) — keyed bycontentType(), supplies a freshLlmContentDecoder/LlmContentEncoderpair per stream. A single interface for both directions, rather than two independently-registered SPIs, so "content-type X is supported" is one type-enforced fact — a decoder registered with no matching encoder (or vice versa) can't happen. Kept in an internal, unexported package for now, per the issue: noexports, no compatibility obligation while init/cont/fin semantics are still being learned.LlmContentDecoder/LlmContentEncoder— decode/encode buffered bytes for one stream.LlmContentDecoderOutput— receives the decoded eventdata/flushframes as the decoder makes progress.LlmContentCodecFactory— ServiceLoader-based dispatch by content-type, modelled onbinding-mcp'sMcpToolSearchIndexFactorySpi/McpToolSearchIndexFactoryprecedent for a within-module SPI.LlmSseContentCodecSpi/LlmJsonContentCodecSpi— the two content-types named in the issue's own scope:text/event-stream(framing decode/encode per the WHATWG SSE parsing algorithm) and non-streamingapplication/json(the entire buffered document dispatched as a single event, since it has no event boundary of its own — "the same abstraction as one event, rather than a special-cased branch").LlmContentCodecFactoryTestcovers SPI lookup/dispatch by content-type (registered and unrecognized, both directions), backed by a test-scopeLlmTestContentCodecSpiregistered viaMETA-INF/services.The
internal/encode/base package (LlmContentEncoder) and itstext/event-streamimplementation (LlmSseContentEncoder) are pulled forward from #2571 so the decoder/encoder collapse could happen where decode already lives, rather than forkinginternal/encode/ahead of its own introduction downstream.LlmSseContentDecoder/LlmSseContentEncoder/LlmJsonContentDecoderwiden from package-private to public (unchanged otherwise) since their codec-SPI providers construct them from the siblinginternal.codecpackage.LlmJsonContentEncoderis new: theapplication/jsoninverse ofLlmJsonContentDecoder, copying content bytes through unchanged with no framing on flush. #2571 will need to rebase on top of this and drop its now-duplicateinternal/encode/base package andLlmSseContentEncoder.This is scoped to the SPI contract plus both of the issue's named content-types —
LlmDialect(event classification) and exporting this SPI once more than one content-type has exercised the shape (#2501) remain separate follow-ups.Verified
./mvnw clean install -pl incubator/binding-llm.conf,incubator/binding-llmpasses end-to-end: checkstyle, license headers, and all 47 unit tests pass with full jacoco coverage.This branch is built on top of
claude/issue-2477-h1b9ia(#2552, scaffoldingbinding-llm), so this diff will include #2552's commits until that merges todevelop— at which point this PR's diff will shrink to just this PR's own commits.Fixes #2478
🤖 Generated with Claude Code
https://claude.ai/code/session_01Mw32oxEw24fLt5Ypakj6pH