Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
a8cf690
fix(helm): use correct templating for mcpClientConfig (#2673)
crust3780 Apr 13, 2026
79a1ab4
docs updates (#2691)
akshaydeo Apr 13, 2026
8f84688
chore: regenerate openapi.json --skip-pipeline
github-actions[bot] Apr 13, 2026
663ded6
changelog update (#2693)
akshaydeo Apr 13, 2026
588e975
fix(bedrock): preserve image content in tool results for Converse API…
Edward-Upton Apr 14, 2026
188fc0e
chore: updates compat plugin docs (#2698)
sammaji Apr 14, 2026
1bda46a
fix: allow custom providers without a list models endpoint to pass in…
danpiths Apr 14, 2026
67938e2
docs: update langchain sdk docs for google (#2702)
BearTS Apr 15, 2026
b423d7d
[fix]: Bedrock provider - emit message_stop event for Anthropic invok…
tefimov Apr 15, 2026
5d3b34b
fix: otel plugin fixes (#2727)
sammaji Apr 15, 2026
1efbfcd
docs: delete example for patronus_ai (#2734)
BearTS Apr 15, 2026
f2005ef
helm chart updates (#2736)
akshaydeo Apr 15, 2026
132b0d4
fixed validation checks (#2737)
akshaydeo Apr 15, 2026
254e41e
fix: capture responses streaming api error (#2681)
BearTS Apr 15, 2026
12e443b
test case fixes for helm release (#2738)
akshaydeo Apr 15, 2026
e7ef535
removes prerelease tag from helm chart (#2739)
akshaydeo Apr 15, 2026
15b67f2
new docs updates for scim (#2748)
akshaydeo Apr 15, 2026
56c3cb4
chore: regenerate openapi.json --skip-pipeline
github-actions[bot] Apr 15, 2026
32138be
removed keycloak (#2749)
akshaydeo Apr 15, 2026
f76f600
fix: delete fallbacks from anthropic req (#2754)
TejasGhatte Apr 16, 2026
aa360ca
fix: preserve context values in async requests (#2703)
TejasGhatte Apr 16, 2026
b9efa11
[fix]: Gemini provider - handle content block tool outputs in Respons…
tom-diacono Apr 16, 2026
6d6b554
fix: gemini thinking level and finish reason round-trip preservation …
TejasGhatte Apr 16, 2026
6d0e64f
fix: remove cc user agent guard from streaming in anthropic (#2706)
TejasGhatte Apr 16, 2026
83599a2
remove unnecessary marshalling of payload (#2770)
akshaydeo Apr 16, 2026
ca5174e
feat: claude opus 4.7 compatibility (#2773)
TejasGhatte Apr 16, 2026
fce84de
docs: restructure helm guide into comprehensive multi-page reference …
BearTS Apr 16, 2026
896f571
v1.4.23 cut (#2778)
akshaydeo Apr 16, 2026
61e8079
validator fix (#2780)
akshaydeo Apr 16, 2026
594b508
fix: token usage for vllm --skip-pipeline (#2784)
sammaji Apr 17, 2026
3ed64a6
[fix]: OpenAI provider - flatten array-form tool_result output for Re…
martingiguere Apr 17, 2026
18427ac
fix: prevent send on closed channel panic in provider queue shutdown …
Pratham-Mishra04 Apr 17, 2026
16896bd
feat: preserve MCP tool annotations in bidirectional conversion --ski…
Pratham-Mishra04 Apr 17, 2026
8c11869
fix: add support for Anthropic structured output and response format …
emirhanmutlu-natuvion Apr 17, 2026
ce62c64
test fixes --skip-pipeline (#2782)
akshaydeo Apr 17, 2026
d1d1004
anthropic container changes --skip-pipeline (#2783)
akshaydeo Apr 17, 2026
19a4473
core schema changes --skip-pipeline (#2787)
akshaydeo Apr 17, 2026
0485a49
dependabot fixes --skip-pipeline (#2788)
akshaydeo Apr 17, 2026
a80bb41
move back go to 1.26.1 (#2792)
akshaydeo Apr 17, 2026
9c00d7b
temp gotoolchain auto (#2809)
akshaydeo Apr 17, 2026
f75d607
temp hack for tests (#2810)
akshaydeo Apr 17, 2026
72ecaca
temp block docker build (#2811)
akshaydeo Apr 17, 2026
c4a191d
removed docker build steps (#2812)
akshaydeo Apr 17, 2026
c907a4d
moves tests to 1.26.2 and 1.26.1 (#2813)
akshaydeo Apr 17, 2026
304d547
ocr test fixes (#2814)
akshaydeo Apr 17, 2026
12c68f3
revert to old schema (#2815)
akshaydeo Apr 17, 2026
9dc2478
reduced release pipeline for this cut for go downgrade (#2816)
akshaydeo Apr 17, 2026
3e0dd03
force verstion back to go 1.26.1 (#2817)
akshaydeo Apr 17, 2026
485810b
revert everything to go1.26.1 (#2818)
akshaydeo Apr 17, 2026
0ac9518
bumped up hello-world dep (#2819)
akshaydeo Apr 17, 2026
bfe8360
framework: bump core to v1.4.22 --skip-pipeline
github-actions[bot] Apr 17, 2026
f962154
plugins/governance: bump core to v1.4.22 and framework to v1.2.39 --s…
github-actions[bot] Apr 17, 2026
314f13f
plugins/jsonparser: bump core to v1.4.22 and framework to v1.2.39 --s…
github-actions[bot] Apr 17, 2026
dd36ff0
plugins/litellmcompat: bump core to v1.4.22 and framework to v1.2.39 …
github-actions[bot] Apr 17, 2026
aec4b7e
plugins/logging: bump core to v1.4.22 and framework to v1.2.39 --skip…
github-actions[bot] Apr 17, 2026
cbfa4f4
plugins/maxim: bump core to v1.4.22 and framework to v1.2.39 --skip-p…
github-actions[bot] Apr 17, 2026
40737ff
plugins/mocker: bump core to v1.4.22 and framework to v1.2.39 --skip-…
github-actions[bot] Apr 17, 2026
adc31bc
plugins/otel: bump core to v1.4.22 and framework to v1.2.39 --skip-pi…
github-actions[bot] Apr 17, 2026
67340ad
plugins/semanticcache: bump core to v1.4.22 and framework to v1.2.39 …
github-actions[bot] Apr 17, 2026
b31cc3a
plugins/telemetry: bump core to v1.4.22 and framework to v1.2.39 --sk…
github-actions[bot] Apr 17, 2026
67319e5
enforce go 1.26.1 (#2820)
akshaydeo Apr 17, 2026
be3edf3
transports: update dependencies --skip-pipeline
github-actions[bot] Apr 17, 2026
1e79b19
Adds changelog for v1.4.23 --skip-pipeline
github-actions[bot] Apr 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- fix: case-insensitive `anthropic-beta` merge in `MergeBetaHeaders`
- fix: Bedrock provider - emit message_stop event for Anthropic invoke stream [@tefimov](https://github.com/tefimov)
121 changes: 119 additions & 2 deletions core/providers/bedrock/bedrock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import (
)

func mustMarshalJSON(v interface{}) json.RawMessage {
b, _ := json.Marshal(v)
b, err := json.Marshal(v)
if err != nil {
panic("mustMarshalJSON: " + err.Error())
}
return json.RawMessage(b)
}

Expand All @@ -40,7 +43,10 @@ func jsonEqual(t *testing.T, expected, actual json.RawMessage, msgAndArgs ...int
// mustMarshalToolParams marshals ToolFunctionParameters to json.RawMessage,
// matching the conversion code path for deterministic output.
func mustMarshalToolParams(params *schemas.ToolFunctionParameters) json.RawMessage {
b, _ := json.Marshal(params)
b, err := json.Marshal(params)
if err != nil {
panic("mustMarshalToolParams: " + err.Error())
}
return json.RawMessage(b)
}

Expand Down Expand Up @@ -3663,3 +3669,114 @@ func TestToBedrockInvokeMessagesStreamResponse_NoDuplicateContentBlockStop(t *te

assert.Equal(t, 1, stopCount, "expected exactly one content_block_stop event, got %d", stopCount)
}

func TestToolResultImageContentResponsesAPI(t *testing.T) {
// Minimal 1x1 red PNG
pngBase64 := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"

t.Run("ImageBlockPreservedInToolResult", func(t *testing.T) {
input := []schemas.ResponsesMessage{
{
Type: schemas.Ptr(schemas.ResponsesMessageTypeFunctionCallOutput),
ResponsesToolMessage: &schemas.ResponsesToolMessage{
CallID: schemas.Ptr("tooluse_screenshot_001"),
Output: &schemas.ResponsesToolMessageOutputStruct{
ResponsesFunctionToolCallOutputBlocks: []schemas.ResponsesMessageContentBlock{
{
Type: schemas.ResponsesInputMessageContentBlockTypeImage,
ResponsesInputMessageContentBlockImage: &schemas.ResponsesInputMessageContentBlockImage{
ImageURL: schemas.Ptr("data:image/png;base64," + pngBase64),
},
},
},
},
},
},
}

messages, _, err := bedrock.ConvertBifrostMessagesToBedrockMessages(input)
require.NoError(t, err)
require.Len(t, messages, 1)

toolResultMsg := messages[0]
assert.Equal(t, bedrock.BedrockMessageRoleUser, toolResultMsg.Role)
require.Len(t, toolResultMsg.Content, 1)

toolResult := toolResultMsg.Content[0].ToolResult
require.NotNil(t, toolResult, "expected tool result in content block")
assert.Equal(t, "tooluse_screenshot_001", toolResult.ToolUseID)
require.Len(t, toolResult.Content, 1, "tool result should contain exactly one content block")

imageBlock := toolResult.Content[0]
require.NotNil(t, imageBlock.Image, "tool result content should be an image")
assert.Equal(t, "png", imageBlock.Image.Format)
require.NotNil(t, imageBlock.Image.Source.Bytes)
assert.Equal(t, pngBase64, *imageBlock.Image.Source.Bytes)
})

t.Run("MixedTextAndImageBlocksPreserved", func(t *testing.T) {
input := []schemas.ResponsesMessage{
{
Type: schemas.Ptr(schemas.ResponsesMessageTypeFunctionCallOutput),
ResponsesToolMessage: &schemas.ResponsesToolMessage{
CallID: schemas.Ptr("tooluse_mixed_002"),
Output: &schemas.ResponsesToolMessageOutputStruct{
ResponsesFunctionToolCallOutputBlocks: []schemas.ResponsesMessageContentBlock{
{
Type: schemas.ResponsesOutputMessageContentTypeText,
Text: schemas.Ptr("Screenshot captured successfully"),
},
{
Type: schemas.ResponsesInputMessageContentBlockTypeImage,
ResponsesInputMessageContentBlockImage: &schemas.ResponsesInputMessageContentBlockImage{
ImageURL: schemas.Ptr("data:image/png;base64," + pngBase64),
},
},
},
},
},
},
}

messages, _, err := bedrock.ConvertBifrostMessagesToBedrockMessages(input)
require.NoError(t, err)
require.Len(t, messages, 1)

toolResult := messages[0].Content[0].ToolResult
require.NotNil(t, toolResult)
require.Len(t, toolResult.Content, 2, "both text and image blocks should be preserved")

assert.NotNil(t, toolResult.Content[0].Text, "first block should be text")
assert.NotNil(t, toolResult.Content[1].Image, "second block should be image")
assert.Equal(t, "png", toolResult.Content[1].Image.Format)
})

t.Run("RemoteURLImageGracefullyDropped", func(t *testing.T) {
input := []schemas.ResponsesMessage{
{
Type: schemas.Ptr(schemas.ResponsesMessageTypeFunctionCallOutput),
ResponsesToolMessage: &schemas.ResponsesToolMessage{
CallID: schemas.Ptr("tooluse_remote_003"),
Output: &schemas.ResponsesToolMessageOutputStruct{
ResponsesFunctionToolCallOutputBlocks: []schemas.ResponsesMessageContentBlock{
{
Type: schemas.ResponsesInputMessageContentBlockTypeImage,
ResponsesInputMessageContentBlockImage: &schemas.ResponsesInputMessageContentBlockImage{
ImageURL: schemas.Ptr("https://example.com/screenshot.png"),
},
},
},
},
},
},
}

messages, _, err := bedrock.ConvertBifrostMessagesToBedrockMessages(input)
require.NoError(t, err)
require.Len(t, messages, 1)

toolResult := messages[0].Content[0].ToolResult
require.NotNil(t, toolResult)
assert.Empty(t, toolResult.Content, "remote URL image should be dropped (Bedrock only supports base64)")
Comment on lines +4298 to +4324

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Match this subtest to the current converter contract.

ConvertBifrostMessagesToBedrockMessages still propagates failed to convert image in tool result when convertImageToBedrockSource sees a remote URL, so this require.NoError + empty-content expectation will fail unless the production branch in core/providers/bedrock/utils.go:561-576 is changed to skip invalid tool-result images instead of returning.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/providers/bedrock/bedrock_test.go` around lines 3754 - 3780, The test
expects ConvertBifrostMessagesToBedrockMessages to silently drop remote URL
images and not return an error, but convertImageToBedrockSource currently
returns an error for remote URLs which propagates out; change the logic in
convertImageToBedrockSource so that when the image source is a remote URL
(http/https) it does not return an error but instead indicates "skip" (e.g.,
return nil image/source and no error), and ensure
ConvertBifrostMessagesToBedrockMessages treats a nil/skip result from
convertImageToBedrockSource as non-fatal and continues (leaving tool result
Content empty) rather than returning the conversion error.

})
}
40 changes: 29 additions & 11 deletions core/providers/bedrock/invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -644,24 +644,27 @@ func ToBedrockInvokeMessagesStreamResponse(ctx *schemas.BifrostContext, resp *sc
}

// For Anthropic models (and default): serialize as Anthropic Messages API SSE events,
// then wrap in InvokeModelRawChunk
rawBytes, err := toAnthropicInvokeStreamBytes(resp)
// then wrap in InvokeModelRawChunks. Some Bifrost events map to multiple Anthropic events
// (e.g., Completed → message_delta + message_stop).
rawChunks, err := toAnthropicInvokeStreamBytes(resp)
if err != nil {
return "", nil, err
}
if rawBytes == nil {
if len(rawChunks) == 0 {
return "", nil, nil
}

bedrockEvent := &BedrockStreamEvent{
InvokeModelRawChunk: rawBytes,
InvokeModelRawChunks: rawChunks,
}
return "", bedrockEvent, nil
}

// toAnthropicInvokeStreamBytes converts a Bifrost stream event into raw bytes representing
// the Anthropic Messages API streaming event JSON, suitable for wrapping in InvokeModelRawChunk.
func toAnthropicInvokeStreamBytes(resp *schemas.BifrostResponsesStreamResponse) ([]byte, error) {
// the Anthropic Messages API streaming event JSON, suitable for wrapping in InvokeModelRawChunks.
// Returns a slice of byte slices since some Bifrost events map to multiple Anthropic events
// (e.g., Completed → message_delta + message_stop).
func toAnthropicInvokeStreamBytes(resp *schemas.BifrostResponsesStreamResponse) ([][]byte, error) {
var event interface{}

switch resp.Type {
Expand Down Expand Up @@ -830,13 +833,13 @@ func toAnthropicInvokeStreamBytes(resp *schemas.BifrostResponsesStreamResponse)
return nil, nil

case schemas.ResponsesStreamResponseTypeCompleted:
// Emit message_delta + message_stop
// Emit message_delta + message_stop as two separate events
stopReason := "end_turn"
if resp.Response != nil && resp.Response.IncompleteDetails != nil {
stopReason = resp.Response.IncompleteDetails.Reason
}

// Build combined payload: message_delta data
// Build message_delta event
messageDelta := map[string]interface{}{
"type": "message_delta",
"delta": map[string]interface{}{
Expand All @@ -849,7 +852,22 @@ func toAnthropicInvokeStreamBytes(resp *schemas.BifrostResponsesStreamResponse)
"output_tokens": resp.Response.Usage.OutputTokens,
}
}
event = messageDelta

// Build message_stop event
messageStop := map[string]interface{}{
"type": "message_stop",
}

// Marshal both events
deltaBytes, err := providerUtils.MarshalSorted(messageDelta)
if err != nil {
return nil, fmt.Errorf("failed to marshal message_delta event: %w", err)
}
stopBytes, err := providerUtils.MarshalSorted(messageStop)
if err != nil {
return nil, fmt.Errorf("failed to marshal message_stop event: %w", err)
}
return [][]byte{deltaBytes, stopBytes}, nil

default:
return nil, nil
Expand All @@ -859,9 +877,9 @@ func toAnthropicInvokeStreamBytes(resp *schemas.BifrostResponsesStreamResponse)
return nil, nil
}

bytes, err := providerUtils.MarshalSorted(event)
eventBytes, err := providerUtils.MarshalSorted(event)
if err != nil {
return nil, fmt.Errorf("failed to marshal invoke stream event: %w", err)
}
return bytes, nil
return [][]byte{eventBytes}, nil
}
16 changes: 14 additions & 2 deletions core/providers/bedrock/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -1302,11 +1302,11 @@ type BedrockInvokeStreamChunkEvent struct {
func (event *BedrockStreamEvent) ToEncodedEvents() []BedrockEncodedEvent {
var events []BedrockEncodedEvent

if event.InvokeModelRawChunk != nil {
for _, rawChunk := range event.InvokeModelRawChunks {
events = append(events, BedrockEncodedEvent{
EventType: "chunk",
Payload: BedrockInvokeStreamChunkEvent{
Bytes: event.InvokeModelRawChunk,
Bytes: rawChunk,
},
})
}
Expand Down Expand Up @@ -2565,6 +2565,18 @@ func ConvertBifrostMessagesToBedrockMessages(bifrostMessages []schemas.Responses
for _, block := range msg.ResponsesToolMessage.Output.ResponsesFunctionToolCallOutputBlocks {
if block.Text != nil {
resultContent = append(resultContent, tryParseJSONIntoContentBlock(*block.Text))
} else if block.Type == schemas.ResponsesInputMessageContentBlockTypeImage &&
block.ResponsesInputMessageContentBlockImage != nil &&
block.ResponsesInputMessageContentBlockImage.ImageURL != nil {
imageSource, err := convertImageToBedrockSource(*block.ResponsesInputMessageContentBlockImage.ImageURL)
if err != nil {
// Bedrock only supports base64 data URIs for images. If conversion
// fails (e.g. remote URL), the image is dropped from the tool result
// which silently degrades the model's ability to see tool output.
_ = fmt.Errorf("bedrock: converting tool result image: %w", err)
} else {
resultContent = append(resultContent, BedrockContentBlock{Image: imageSource})
}
Comment on lines +2593 to +2604

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't register a tool result after dropping every image block.

If ResponsesFunctionToolCallOutputBlocks only contains remote image URLs, this branch drops them all and still registers the tool result with an empty resultContent. That turns a provider limitation into an empty Bedrock toolResult, which loses the tool output and can break downstream handling.

Based on learnings, a tool result message should only be created when msg.Content is non-nil, as there's no semantic meaning to a tool result without output content.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/providers/bedrock/responses.go` around lines 2593 - 2604, When
converting function tool output blocks (the loop that uses
convertImageToBedrockSource and appends to resultContent producing
BedrockContentBlock entries), ensure you do not register a Bedrock toolResult
when there is no actual content: after processing
ResponsesFunctionToolCallOutputBlocks and before creating/attaching the
toolResult, check whether resultContent is empty and msg.Content is nil (or
otherwise no semantic output) and skip creating/adding the toolResult in that
case; this prevents creating empty toolResult messages for remote-image-only
blocks that were dropped by convertImageToBedrockSource.

}
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/providers/bedrock/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,10 @@ type BedrockStreamEvent struct {
AdditionalModelResponseFields interface{} `json:"additionalModelResponseFields,omitempty"`

// For InvokeModelWithResponseStream (Legacy API)
InvokeModelRawChunk []byte `json:"invokeModelRawChunk,omitempty"` // Raw bytes for legacy invoke stream
// InvokeModelRawChunks holds one or more raw byte payloads for legacy invoke stream.
// Multiple chunks are needed when a single Bifrost event maps to multiple Anthropic SSE events
// (e.g., Completed → message_delta + message_stop).
InvokeModelRawChunks [][]byte `json:"invokeModelRawChunks,omitempty"`
}

// BedrockMessageStartEvent indicates the start of a message
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/framework/model-catalog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ You can reload the pricing configuration at runtime if you need to change the pr
newConfig := &modelcatalog.Config{
PricingSyncInterval: 12 * time.Hour,
}
err := modelCatalog.ReloadPricing(ctx, newConfig)
err := modelCatalog.UpdateSyncConfig(ctx, newConfig)
Comment on lines 321 to +324

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Make this example self-contained.

ctx is undefined in the snippet, so readers can't copy/paste it as-is. Use context.Background() inline or define ctx immediately above the call.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/architecture/framework/model-catalog.mdx` around lines 321 - 324, The
snippet uses an undefined ctx when calling modelCatalog.UpdateSyncConfig; make
the example self-contained by creating a context before use (e.g., define ctx :=
context.Background() immediately above the newConfig or call
modelCatalog.UpdateSyncConfig(context.Background(), newConfig)), and keep the
rest of the example (newConfig := &modelcatalog.Config{PricingSyncInterval: 12 *
time.Hour}) unchanged so readers can copy/paste directly.

```

## Error Handling and Fallbacks
Expand Down
17 changes: 0 additions & 17 deletions docs/changelogs/v1.5.0-prerelease2.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,8 @@ description: "v1.5.0-prerelease2 changelog - 2026-04-08"
- **Data Race Fix** — Fix race in data reading from fasthttp request for integrations
- **Model Listing** — Unify /api/models and /api/models/details listing behavior

<Warning>
**v1.5.0 contains multiple breaking changes.** See the [v1.5.0 Migration Guide](/migration-guides/v1.5.0) for full before/after examples and a migration checklist.
</Warning>

## Breaking Changes in This Release

This prerelease introduces 3 additional breaking changes on top of those in prerelease1. See the **[v1.5.0 Migration Guide](/migration-guides/v1.5.0)** for full before/after examples, automatic migration details, and a step-by-step checklist.

| # | Breaking Change | Affected |
|---|---|---|
| [9](/migration-guides/v1.5.0#breaking-change-9-provider-deployments-removed-migrate-to-aliases) | Provider `deployments` removed — migrate Azure, Bedrock, Vertex, and Replicate deployment maps to the unified top-level `aliases` field | `config.json`, REST API, Go SDK |
| [10](/migration-guides/v1.5.0#breaking-change-10-go-sdk-extrafields-model-fields-renamed) | Go SDK: `ExtraFields.ModelRequested` replaced by `OriginalModelRequested` + `ResolvedModelUsed` | Go SDK |
| [11](/migration-guides/v1.5.0#breaking-change-11-go-sdk-streamaccumulatorresult-field-renamed) | Go SDK: `StreamAccumulatorResult.Model` replaced by `RequestedModel` + `ResolvedModel` | Go SDK |

---
</Update>
<Update label="Core" description="1.5.1">
- feat: add model alias support — map model names to provider-specific identifiers per key
- feat: add Fireworks AI as a first-class provider (thanks [@ivanetchart](https://github.com/ivanetchart)!)
- feat: add realtime provider interfaces, schemas, and engine hooks
- feat: add session log storage and realtime request normalization
Expand All @@ -89,7 +73,6 @@ This prerelease introduces 3 additional breaking changes on top of those in prer

</Update>
<Update label="Framework" description="1.3.1">
- feat: add model alias storage and encryption in key config
- feat: add per-user OAuth consent flow with identity selection and MCP authentication
- feat: add access profiles for fine-grained permission control
- feat: add user level OAuth for MCP gateway
Expand Down
Loading
Loading