Skip to content

$ llm plane: Bedrock InvokeModel (protocol: bedrock-invoke), the Anthropic dialect inside the invoke envelope (stacked on #841) - #985

Merged
MattJackson merged 4 commits into
predevfrom
lane-llm-bedrock-invoke
Oct 15, 2026
Merged

MattJackson merged 4 commits into
predevfrom
lane-llm-bedrock-invoke

Conversation

@MattJackson

Copy link
Copy Markdown
Collaborator

PARITY-SCOPE item 2. The owner's 2026-09-29 compat scope puts the "Bedrock InvokeModel dialect" in scope (BUSBAR-1.6.0.md l.4805; l.4810 "Anthropic-on-Bedrock InvokeModel chat only"; l.4835; E table l.5499 "no evidence found"). #841 is only the model-override seam. The design is ARCHITECT-approved 2026-10-14 with four conditions, each met below. Stacked on #841: DRAFT until #841 lands. It is $, so it lands alone (rule 15).

Design. InvokeModel takes Anthropic's own Messages body and answers with Anthropic's own body and events, so bedrock-invoke is the Anthropic dialect carried inside Bedrock's envelope, not a seventh dialect. A model selects it with models.<m>.protocol: bedrock-invoke on a Bedrock provider. exchange/invoke.rs owns the envelope:

  • Target. /model/{model}/invoke, or /invoke-with-response-stream. It is encoded by the same wire_and_canonical_path the Converse target goes through.
  • Body. A byte-level splice, never a re-serialization: model and stream are removed, anthropic_version: bedrock-2023-05-31 is stated, and the caller's anthropic-beta field moves to body anthropic_beta. The anthropic-version field and the dialect's static headers are not sent. A streamed request asks accept: application/vnd.amazon.eventstream.
  • Relay. An Anthropic caller is RELAYED inside the envelope (dialect fidelity: same dialect, governed splices only). Other callers translate to Anthropic exactly as for an Anthropic provider.
  • Streams. Each AWS event-stream chunk frame's base64 bytes is one Anthropic stream event. Transcoder re-frames it as that dialect's own SSE, the event JSON byte for byte, on the shared codec/eventstream.rs. A mid-stream exception frame or a malformed frame becomes the dialect's error event and ends the stream.
  • Refusals. {message} plus x-amzn-ErrorType is restated as Anthropic's error envelope, with the exception mapped to its kind, before the failure judge reads it.
  • Probes. A probe goes through the same envelope.
  • Credential. root::door_steps::member_routes now falls back to the provider protocol's default style when the member's own protocol states none, so the model keeps its Bedrock provider's SigV4. No dialect is named.

Conditions (ARCHITECT 2026-10-14)

  1. tests/dialect_self_contained.rs needs no exemption. Nothing under src/codec changed; the envelope lives in the plane's exchange adapter.
  2. No ProtocolDecl change and no ABI change. The envelope is no declared protocol at all, so nothing needs a model_only flag: a provider cannot default to it because the kernel's provider sweep does not know the name.
  3. The kernel reads nothing and names nothing. the_envelope_is_no_declared_protocol_and_the_1_5_5_list_is_unchanged pins DECLS to 1.5.5's six in order, which is the list BOOT-020 and validate_unknown_protocol_lists_only_the_configured_planes_dialects print. a_provider_never_defaults_to_the_envelope pins the plane's refusal.
  4. 1.5.5 never served InvokeModel chat (E table l.5499), so this is new surface. It has a CHANGELOG Added line and no oracle cell.

REDs (busbar-plane-llm/tests/exchange_invoke.rs, plus the root's a_member_whose_protocol_states_no_default_style_rides_its_providers): lane resolution; the provider refusal; targets; relay inside the envelope (body members, beta flags, fields, accept); the whole-answer target; byte preservation of the body edit; stream re-framing at four chunkings; a mid-stream exception; refusal restatement; money: a streamed answer over the envelope meters the carried dialect's 11 in and 7 out through Reply, with the carried dialect's text/event-stream head; and the 1.5.5 protocol list.

…nd is served, fail-closed (#51)

Row-159 audit plane-llm L1#3: a model entry's `protocol` (#51, THE DESIGN §2 BEDROCK-INVOKE
ruling; CHANGELOG "a model entry takes `protocol`") was dropped by the root's section builder and
never read by the plane, so the plane wrote that model's requests in its provider's dialect and
accepted an unknown override. The root now hands the member through (`kernel_sections`), and the
plane resolves model override, else provider default, else the default dialect, refusing a dialect
it does not serve naming the model.

RED-able: exchange_shaping::a_models_protocol_overrides_its_providers_and_an_unknown_one_is_refused,
root door_steps::a_models_protocol_override_is_handed_to_the_plane.
…lect (kind-isolation law0 busbar x vendor 92 -> 89)

The root hands the model's override through as opaque data; its test now spells two neutral dialect
words, so the root carries no vendor name (#841 gates: law0 busbar x vendor 92/89, law0-base 89/0).
…drock InvokeModel, the carried dialect inside the invoke envelope (stacked on #841)
@MattJackson
MattJackson merged commit d772db8 into predev Oct 15, 2026
1 check was pending
@MattJackson
MattJackson deleted the lane-llm-bedrock-invoke branch October 15, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant