# Migrate Go AI SDK v0.3.x to v0.4.0

Go AI SDK v0.4.0 changes when streaming tools execute, switches xAI's default API, removes two retired xAI model IDs, and rejects MCP server redirects by default. None of these rename or remove a Go type or function signature, so v0.3.x code keeps compiling — what changes is runtime behavior. This guide is for anyone still on v0.3.x.

## Recommended migration process

1. Update: `go get github.com/digitallysavvy/go-ai@v0.4.0`
2. If a `StreamText` consumer expects tool-result chunks interleaved with text, move that handling to run after the stream ends.
3. Replace `grok-2` and `grok-2-vision-1212` model IDs with a `grok-3` or later model.
4. If you rely on xAI's Chat Completions API, call `ChatCompletionsLanguageModel()` explicitly.
5. If an MCP server needs redirects, opt in with `Redirect: mcp.MCPRedirectFollow`.
6. Build and test: `go build ./...` and `go test ./...`.

## Behavior changes

### Streaming tool execution moves to after the stream

**Impact:** runtime only — no compile change.

`StreamText` forwards every provider chunk (text, reasoning, custom content) to `OnChunk` before running any tool's `Execute` callback; `ChunkTypeToolResult` chunks now arrive only after the stream ends. In v0.3.x they could interleave with text chunks. This applies to tools with a Go `Execute` callback — provider-executed results (`ProviderExecuted: true`, e.g. Google code execution) still arrive inline as the provider produces them.

```go
result, err := ai.StreamText(ctx, ai.StreamTextOptions{
    Model:  model,
    Prompt: "What's the weather?",
    Tools:  []types.Tool{weatherTool},
    // StreamText defaults to a single step; allow more so the model gets
    // a turn to respond in text after the tool result.
    StopWhen: []ai.StopCondition{ai.IsStepCount(5)},
    OnChunk: func(chunk provider.StreamChunk) {
        fmt.Print(chunk.Text)
    },
})
if err != nil {
    log.Fatal(err)
}
defer result.Close()

for range result.Chunks() {
}
```

This code is unchanged between v0.3.x and v0.4.0. What changes is the order `OnChunk` sees: in v0.3.x a `ChunkTypeToolResult` chunk could arrive between text chunks; in v0.4.0 it always arrives after the stream's text and reasoning chunks have finished.

### XAI's default language model uses the Responses API

**Impact:** runtime only — no compile change.

`xai.Provider.LanguageModel()` now returns a model backed by xAI's Responses API instead of Chat Completions. The Responses API adds image input and finer-grained reasoning effort levels. Call `ChatCompletionsLanguageModel()` for the v0.3.x behavior.

> **v0.5.0:** `ChatCompletionsLanguageModel()` has since been removed (the TS SDK dropped xAI's Chat Completions API). On v0.5.0, `LanguageModel()` is the only xAI language model. See [Migrating from v0.4 to v0.5](https://goaisdk.com/docs/migration-guides/from-v0.4-to-v0.5.md).

```go
provider := xai.New(xai.Config{APIKey: os.Getenv("XAI_API_KEY")})

model, _ := provider.LanguageModel("grok-3")                    // Responses API (new default)
chatModel, _ := provider.ChatCompletionsLanguageModel("grok-3") // Chat Completions API (v0.3.x behavior)
```

### XAI removed grok-2 model IDs

**Impact:** runtime only. `LanguageModel()` never validated model ID strings at compile time or call time, so this doesn't produce a Go error either — the request reaches xAI, and xAI rejects the retired model.

```go
model, _ := provider.LanguageModel("grok-2")             // xAI: model not found
model, _ := provider.LanguageModel("grok-2-vision-1212") // xAI: model not found

// Use instead:
model, _ := provider.LanguageModel("grok-3")
model, _ := provider.LanguageModel("grok-3-mini")
```

### MCP HTTP transport rejects redirects by default

**Impact:** runtime only — no compile change; may break an MCP integration that relied on a redirect.

`MCPRedirectMode`'s zero value is `MCPRedirectError`, so `mcp.NewHTTPTransport` now rejects a redirect instead of following it. This closes an SSRF path where a malicious MCP server redirects requests to an internal service.

```go
transport := mcp.NewHTTPTransport(mcp.HTTPTransportConfig{
    URL: "https://mcp.example.com",
})
// v0.4.0: a redirect from this server now returns an error.

// To allow redirects (only for a server you trust):
transport := mcp.NewHTTPTransport(mcp.HTTPTransportConfig{
    URL: "https://mcp.example.com",
    Config: mcp.TransportConfig{
        Redirect: mcp.MCPRedirectFollow,
    },
})
```

### Telemetry: register an integration instead of passing a Tracer per call

**Impact:** low. `telemetry.Options.Tracer` still works; `RegisterTelemetryIntegration` is the supported path for new code.

```go
telemetry.RegisterTelemetryIntegration(telemetry.OTelTelemetryIntegration{})

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
    Model:  model,
    Prompt: "Hello",
    Telemetry: &telemetry.Options{
        IsEnabled:    telemetry.Bool(true),
        RecordInputs: true,
        FunctionID:   "my-chat",
    },
})
```

If you relied on the default global tracer rather than a custom `Tracer`, register `telemetry.OTelTelemetryIntegration{}` — it uses `otel.Tracer("ai-sdk")` when no custom tracer is set. `AddTelemetryIntegration()` fans out to multiple backends, `ClearTelemetryIntegrations()` resets the registry, and `telemetry.NoopTelemetryIntegration{}` disables telemetry globally.

## New in v0.4.0

These are additive; existing code keeps compiling without them.

- **Top-level `Reasoning`** on `GenerateTextOptions`/`StreamTextOptions` — see [Generating text](https://goaisdk.com/docs/ai-sdk-core/generating-text.md)
- **Deferred provider tool results** via `Tool.SupportsDeferredResults` — see [Tools and tool calling](https://goaisdk.com/docs/ai-sdk-core/tools-and-tool-calling.md)
- **`CustomContent` and `ReasoningFileContent`** content types
- **Tool-level timeouts** via `TimeoutConfig.ToolMs` / `TimeoutConfig.Tools`
- **Embed/rerank `OnStart`/`OnFinish` callbacks** — see [Embeddings](https://goaisdk.com/docs/ai-sdk-core/embeddings.md)
- **[KlingAI v3.0 motion control](https://goaisdk.com/docs/providers/klingai.md)** — new video generation capability
- **[Prodia](https://goaisdk.com/docs/providers/prodia.md) language and video models** — Prodia's existing image generation provider gains a language model and a video model
