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

# Chat

<Tip>
  In this example, we will download a model and get a reply to a specific list of messages.
</Tip>

<Tabs>
  <Tab title="Python">
    <Steps>
      <Step title="Create a new project">
        ```sh theme={null}
        uv init demo && cd demo
        ```
      </Step>

      <Step title="Install dependencies">
        ```sh theme={null}
        uv add uzu
        ```
      </Step>

      <Step title="Paste into main.py">
        ```python theme={null}
        import asyncio

        from uzu import (
            ChatConfig,
            ChatMessage,
            ChatReplyConfig,
            ChatSessionStreamChunk,
            Engine,
            EngineConfig,
        )


        async def main() -> None:
            engine_config = EngineConfig.create()
            engine = await Engine.create(engine_config)

            model = await engine.model("Qwen/Qwen3-0.6B")
            if model is None:
                raise RuntimeError("Model not found")
            async for update in (await engine.download(model)).iterator():
                print(f"Download progress: {update.progress}")

            messages = [
                ChatMessage.system().with_text("You are a helpful assistant"),
                ChatMessage.user().with_text("Tell me a short, funny story about a robot"),
            ]
            session = await engine.chat(model, ChatConfig.create())
            stream = await session.reply_with_stream(messages, ChatReplyConfig.create())
            message: ChatMessage | None = None
            async for chunk in stream.iterator():
                if isinstance(chunk, ChatSessionStreamChunk.Replies):
                    replies = chunk.replies
                    if replies:
                        reply = replies[0]
                        message = reply.message
                        print(f"Generated tokens: {reply.stats.tokens_count_output}")
                elif isinstance(chunk, ChatSessionStreamChunk.Error):
                    print(f"Error: {chunk.error}")
            if message is not None:
                print(f"Reasoning: {message.reasoning}")
                print(f"Text: {message.text}")


        if __name__ == "__main__":
            asyncio.run(main())
        ```
      </Step>

      <Step title="Run the snippet">
        ```sh theme={null}
        uv run main.py
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Swift">
    <Steps>
      <Step title="Create a new SwiftUI project">
        <img src="https://mintcdn.com/mirai-bded675a/-MIzY7hlOp3HioeZ/images/quick-start/xcode-new-project.png?fit=max&auto=format&n=-MIzY7hlOp3HioeZ&q=85&s=7ef3a6a5ada8fec6d6cfe024e598e278" alt="" width="1430" height="1020" data-path="images/quick-start/xcode-new-project.png" />
      </Step>

      <Step title="Add the SDK">
        Add this package through SPM:

        ```sh theme={null}
        https://github.com/trymirai/uzu.git
        ```
      </Step>

      <Step title="Paste the snippet">
        ```swift theme={null}
        import Uzu

        public func runChat() async throws {
            let engineConfig = EngineConfig.create()
            let engine = try await Engine.create(config: engineConfig)
            
            guard let model = try await engine.model(identifier: "Qwen/Qwen3-0.6B") else {
                return
            }
            for try await update in try await engine.download(model: model).iterator() {
                print("Download progress: \(update.progress())")
            }
            
            let messages = [
                ChatMessage.system().withText(text: "You are a helpful assistant"),
                ChatMessage.user().withText(text: "Tell me a short, funny story about a robot")
            ]
            let session = try await engine.chat(model: model, config: .create())
            let stream = await session.replyWithStream(input: messages, config: .create())
            var message: ChatMessage? = nil
            for try await update in stream.iterator() {
                switch update {
                case .replies(let replies):
                    let reply = replies.last
                    message = reply?.message
                    print("Generated tokens: \(reply?.stats.tokensCountOutput ?? 0)")
                case .error(let error):
                    print("Error: \(error)")
                }
            }
            print("Reasoning: \(message?.reasoning() ?? "empty")")
            print("Text: \(message?.text() ?? "empty")")
        }
        ```
      </Step>

      <Step title="Add the snippet call">
        ```swift theme={null}
        var body: some View {
            VStack {
                Text("On-device AI")
            }
            .onAppear() {
                Task {
                    try await runExampleName()
                }
            }
        }
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="TypeScript">
    <Steps>
      <Step title="Make a new project folder">
        ```sh theme={null}
        mkdir demo && cd demo
        ```
      </Step>

      <Step title="Initialize with pnpm">
        ```sh theme={null}
        pnpm init
        ```
      </Step>

      <Step title="Install dependencies">
        ```sh theme={null}
        pnpm add typescript ts-node @types/node -D
        pnpm add @trymirai/uzu
        ```
      </Step>

      <Step title="Initialize a tsconfig.json">
        ```json theme={null}
        {
            "compilerOptions": {
                "target": "es2020",
                "module": "commonjs",
                "moduleResolution": "node",
                "strict": true,
                "esModuleInterop": true,
                "outDir": "dist",
                "types": [
                    "node"
                ]
            },
            "include": [
                "*.ts"
            ]
        }
        ```
      </Step>

      <Step title="Create main.ts">
        ```ts theme={null}
        import { ChatConfig, ChatMessage, ChatReplyConfig, ChatSessionStreamChunkError, ChatSessionStreamChunkReplies, Engine, EngineConfig } from '@trymirai/uzu';

        async function main() {
            let engineConfig = EngineConfig.create();
            let engine = await Engine.create(engineConfig);

            let model = await engine.model('Qwen/Qwen3-0.6B');
            if (!model) {
                throw new Error('Model not found');
            }
            for await (const update of await engine.download(model)) {
                console.log('Download progress:', update.progress);
            }

            let messages = [
                ChatMessage.system().withText('You are a helpful assistant'),
                ChatMessage.user().withText('Tell me a short, funny story about a robot')
            ];
            let session = await engine.chat(model, ChatConfig.create());
            let stream = await session.replyWithStream(messages, ChatReplyConfig.create());
            let message: ChatMessage | undefined;
            for await (const chunk of stream) {
                if (chunk instanceof ChatSessionStreamChunkReplies) {
                    message = chunk.replies[0]?.message;
                    console.log('Generated tokens: ', chunk.replies[0]?.stats.tokensCountOutput);
                } else if (chunk instanceof ChatSessionStreamChunkError) {
                    console.error('Error: ', chunk.error);
                }
            }
            console.log('Reasoning: ', message?.reasoning);
            console.log('Text: ', message?.text);
        }

        main().catch((error) => {
            console.error(error);
        });
        ```
      </Step>

      <Step title="Run the snippet">
        ```sh theme={null}
        pnpm ts-node main.ts
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Rust">
    <Steps>
      <Step title="Create a new project">
        ```sh theme={null}
        cargo new demo && cd demo
        ```
      </Step>

      <Step title="Install dependencies">
        ```sh theme={null}
        cargo add uzu --git https://github.com/trymirai/uzu
        cargo add tokio --features full
        ```
      </Step>

      <Step title="Paste into src/main.rs">
        ```rust theme={null}
        use uzu::{
            engine::{Engine, EngineConfig},
            session::chat::ChatSessionStreamChunk,
            types::session::chat::{ChatConfig, ChatMessage, ChatReplyConfig},
        };

        #[tokio::main]
        async fn main() -> Result<(), Box<dyn std::error::Error>> {
            let engine_config = EngineConfig::default();
            let engine = Engine::new(engine_config).await?;

            let model = engine.model("Qwen/Qwen3-0.6B".to_string()).await?.ok_or("Model not found")?;
            let downloader = engine.download(&model).await?;
            while let Some(update) = downloader.next().await {
                println!("Download progress: {}", update.progress());
            }

            let messages = vec![
                ChatMessage::system().with_text("You are a helpful assistant".to_string()),
                ChatMessage::user().with_text("Tell me a short, funny story about a robot".to_string()),
            ];
            let session = engine.chat(model, ChatConfig::default()).await?;
            let stream = session.reply_with_stream(messages, ChatReplyConfig::default()).await;
            let mut last_message: Option<ChatMessage> = None;
            while let Some(chunk) = stream.next().await {
                match chunk {
                    ChatSessionStreamChunk::Replies {
                        replies,
                    } => {
                        if let Some(reply) = replies.first() {
                            last_message = Some(reply.message.clone());
                            println!("Generated tokens: {}", reply.stats.tokens_count_output.unwrap_or_default());
                        }
                    },
                    ChatSessionStreamChunk::Error {
                        error,
                    } => {
                        println!("Error: {error}");
                    },
                }
            }
            if let Some(message) = last_message {
                println!("Reasoning: {}", message.reasoning().unwrap_or_default());
                println!("Text: {}", message.text().unwrap_or_default());
            }

            Ok(())
        }
        ```
      </Step>

      <Step title="Run the snippet">
        ```sh theme={null}
        cargo run --release
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

<Info>
  Once loaded, the same `ChatSession` can be reused for multiple requests until you drop it. Each model may consume a significant amount of RAM, so it's important to keep only one session loaded at a time. For iOS apps, we recommend adding the [Increased Memory Capability](https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.kernel.increased-memory-limit) entitlement to ensure your app can allocate the required memory.
</Info>
