> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inworld.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration Guide

This guide covers breaking changes when upgrading to Inworld Agent Runtime 1.0.

***

## Templates: MetaHuman and Lipsync removed

The MetaHuman and Lipsync template plugins have been removed. Lip-sync is now a first-class feature of the core SDK and does not require a separate template.

For lip-sync setup, see the [Inworld Lip-sync](/unreal-engine/runtime/inworld-lipsync) guide.

***

## Streams are now typed iterables

Previously, stream outputs were consumed by polling a `FInworldDataHandle_Stream` (which carried `Index` and `IsFinal` fields). In 1.0, stream types like `FInworldData_DataStream_TTSOutput` support range-based iteration directly — each iteration yields a `FInworldDataHandle` that you inspect with `IsA` or `Unwrap`.

```cpp theme={"system"}
// Iterate a TTS output stream
void ProcessStream(FInworldData_DataStream_TTSOutput VoiceStream)
{
    for (FInworldDataHandle DataHandle : VoiceStream)
    {
        if (FInworldData_TTSOutput* TTSOutput = DataHandle.Unwrap<FInworldData_TTSOutput>())
        {
            // use TTSOutput->Audio, TTSOutput->Text, TTSOutput->Timestamps, etc.
        }
    }
}
```

`FInworldDataHandle_Stream` no longer exists. Remove any code that referenced its `Index` or `IsFinal` fields — use the typed handles from iteration instead.

***

## FInworldData\_Error: StatusCode and StatusMessage

The error fields have been renamed and the type of the status changed.

| Before            | After                            |
| ----------------- | -------------------------------- |
| `Reason: FString` | `StatusMessage: FString`         |
| `bOk: bool`       | `StatusCode: EInworldStatusCode` |

Update any error-handling code to use the new field names:

```cpp theme={"system"}
// Before
if (!Error->bOk)
{
    UE_LOG(LogTemp, Error, TEXT("Error: %s"), *Error->Reason);
}

// After
if (Error->StatusCode != EInworldStatusCode::OK)
{
    UE_LOG(LogTemp, Error, TEXT("Error: %s"), *Error->StatusMessage);
}
```

***

## FInworldData\_EventHistory: Events array

The event history struct has changed. The old `SpeechEvents: TArray<FInworldEventSpeech>` field and the internal `TSharedPtr<inworld::vector_Event>` native pointer are removed. Event history is now exposed as `Events: TArray<FInworldInteractionEvent>`.

| Before                                           | After                                      |
| ------------------------------------------------ | ------------------------------------------ |
| `SpeechEvents: TArray<FInworldEventSpeech>`      | `Events: TArray<FInworldInteractionEvent>` |
| `TSharedPtr<inworld::vector_Event> EventHistory` | *(removed)*                                |

### Rendering event history to Jinja (before / after)

If you were passing event history into a Jinja template via `RenderJinjaWithJson` or `RenderJinjaWithArgMap`, update the field accessor from `SpeechEvents` to `Events` and update the struct fields to match `FInworldInteractionEvent`.

**Before:**

```
{%- if EventHistory %}
{%- for SpeechEvent in EventHistory.speechEvents %}
{{SpeechEvent.agentName}}: {{SpeechEvent.utterance}}
{%- endfor %}{%- endif %}
```

**After:**

```
{%- if EventHistory %}
{%- for Event in EventHistory.events if Event.eventType == 'SPEECH' %}
{{ Event.speech.agentName }}: {{ Event.speech.utterance }}
{%- endfor %}{%- endif %}
```
