AI Conversations | Getting Started
Shiny.AiConversation is a centralized AI conversation service that combines Microsoft.Extensions.AI chat completions with Shiny.Speech for speech recognition, text-to-speech, wake word detection, and audio feedback — all behind a single IAiConversationService interface.
Building a conversational AI experience in a mobile or web app typically means stitching together many concerns yourself: managing chat client authentication, wiring up speech-to-text and text-to-speech, handling microphone permissions, coordinating state between listening/thinking/responding phases, playing audio cues, persisting message history, and exposing tools for the AI to call. Each of these is a separate library with its own lifecycle and threading model.
Shiny.AiConversation collapses all of that into a single service registration and one interface. By default, it resolves IChatClient directly from your DI container — just register your chat client and the library handles the rest. For advanced scenarios (on-demand authentication, token refresh), you can implement IChatClientProvider. Either way, the library manages the entire flow — from capturing the user’s voice, streaming it through speech recognition, sending the transcript to the chat model, reading the response aloud, and optionally persisting the conversation. The entire flow is observable through a simple Status property so your UI always knows what’s happening.
This means you can go from zero to a fully functional voice-enabled AI assistant with wake word support, audio feedback, and chat history in under 50 lines of registration code — and swap AI backends (OpenAI, Azure, Ollama, GitHub Copilot) without changing your app logic.
| GitHub | |
| Downloads |
Features
Section titled “Features”- Access checking —
RequestAccess()verifies speech-to-text permissions before starting voice features - Text chat — send messages via
TalkTo()and receive streaming AI responses - Voice chat —
ListenAndTalk()captures speech and sends it to the AI in one call - Wake word — hands-free activation with
StartWakeWord("Hey Copilot")that listens continuously - Text-to-speech — AI responses can be read aloud automatically
- Audio feedback — configurable sound effects for thinking, responding, ok, cancel, and error states
- Acknowledgement modes —
None,AudioBlip,LessWordy, orFulltext-to-speech - Context providers — pluggable
IContextProvidervisitor pattern for populating anAiContextper request. Each provider’sApply(AiContext)method receives a mutable context containing system prompts, AI tools, quiet words, speech-to-text options, and text-to-speech options. A built-inContextProviderhandles time-based prompts, acknowledgement-aware voice prompts, and DI-registeredAIToolinstances. Register additional providers to inject custom prompts, tools, or override speech settings. - Message persistence — optional
IMessageStorefor chat history storage and retrieval - AI chat lookup tool — automatically available when an
IMessageStoreis registered, lets the AI search its own conversation history - Conversation continuation — AI responses ending with a question automatically keep the microphone open for a reply
- Voice interruption — configurable quiet words (e.g., “stop”, “cancel”) immediately silence TTS; any other speech during TTS interrupts and continues the conversation with the new utterance
- Speech options — configurable
SpeechToTextOptionsandTextToSpeechOptions(culture, silence timeout, voice, speech rate, etc.) - State tracking — observable
Statusproperty (Idle,Listening,Thinking,Responding) - Pluggable providers — default resolves
IChatClientfrom DI; optionally implementIChatClientProviderfor custom auth (OpenAI, Copilot, Ollama, etc.) - AOT compatible — fully trimmer-safe with
IsAotCompatibleenabled - Cross-platform — works on MAUI (Android, iOS, Windows) and Blazor (Server, WASM)
Architecture
Section titled “Architecture”┌─────────────────────────────────┐│ IAiConversationService │ ← Your app talks to this├─────────────────────────────────┤│ IChatClientProvider │ ← Default resolves IChatClient from DI│ ISpeechToTextService │ ← From Shiny.Speech│ ITextToSpeechService │ ← From Shiny.Speech│ IAudioPlayer │ ← From Shiny.Speech│ IMessageStore? │ ← Optional persistence (you implement)│ IEnumerable<IContextProvider> │ ← System prompts & tools (pluggable)└─────────────────────────────────┘-
Install the NuGet package
Terminal window dotnet add package Shiny.AiConversation -
Register a chat client
The simplest approach is to register an
IChatClientin DI — the library resolves it automatically:builder.Services.AddChatClient(new OpenAIClient("your-api-key").GetChatClient("gpt-4o").AsIChatClient());Or use one of the built-in provider packages:
Package Description Shiny.AiConversation.OpenAiStatic OpenAI-compatible client (OpenAI, Azure, Ollama) Shiny.AiConversation.Maui.GithubCopilotGitHub Copilot with device code auth (MAUI only) // OpenAIopts.AddStaticOpenAIChatClient("your-api-key", "https://api.openai.com/v1", "gpt-4o");// GitHub Copilot (MAUI only — handles auth, token storage, everything)opts.AddGithubCopilotChatClient();For other backends, implement
IChatClientProvider— see Chat Client Provider. -
Register the service in your app
MAUI (MauiProgram.cs):
builder.Services.AddShinyAiConversation(opts =>{// Optional: add message store, configure settings});Blazor (Program.cs):
builder.Services.AddShinyAiConversation(opts =>{// Optional: add message store, configure settings}); -
Add custom system prompts (optional)
System prompts, tools, and speech settings are supplied by
IContextProviderimplementations using a visitor pattern. AContextProvideris auto-registered. Add your own:public class MyContextProvider : IContextProvider{public Task Apply(AiContext context){context.SystemPrompts.Add("You are a helpful assistant.");// context.Tools.Add(...) to add AI tools// context.Acknowledgement is available to adjust behavior per mode// context.QuietWords — modify quiet words for voice interruption// context.SpeechToTextOptions — set/override speech recognition options// context.TextToSpeechOptions — set/override text-to-speech optionsreturn Task.CompletedTask;}}// Register in DI (multiple providers are supported, executed in sequence)builder.Services.AddShinyAiConversation(opts =>{opts.AddContextProvider<MyContextProvider>();}); -
Use the service
public class ChatViewModel(IAiConversationService aiService){public async Task Send(string message){aiService.AiResponded += response =>{if (response.Response.Text is { } text)Console.WriteLine($"AI: {text}");};await aiService.TalkTo(message, CancellationToken.None);}}
Quick Example
Section titled “Quick Example”// Check access before using voice featuresvar access = await aiService.RequestAccess();if (access != AccessState.Available) return; // Speech is not available
// Text chatawait aiService.TalkTo("What is .NET MAUI?", cancellationToken);
// Voice chat (push-to-talk)await aiService.ListenAndTalk(cancellationToken);
// Hands-free wake wordawait aiService.StartWakeWord("Hey Copilot");// ... user says "Hey Copilot, what's the weather?"// Service automatically captures and sends to AIaiService.StopWakeWord();
// Chat history (requires IMessageStore)var history = await aiService.GetChatHistory(limit: 50);await aiService.ClearChatHistory();
// Acknowledgement modesaiService.Acknowledgement = AiAcknowledgement.Full; // Read response aloudaiService.Acknowledgement = AiAcknowledgement.LessWordy; // Concise TTSaiService.Acknowledgement = AiAcknowledgement.AudioBlip; // Sound effects onlyaiService.Acknowledgement = AiAcknowledgement.None; // SilentPlatform Notes
Section titled “Platform Notes”Platform Permissions
Section titled “Platform Permissions”Since AI Conversations uses Shiny.Speech for voice features, you must declare speech and microphone permissions.
Android — Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />MODIFY_AUDIO_SETTINGS is required for the TTS audio-level Visualizer and for the native STT beep suppression.
iOS — Add to Info.plist:
<key>NSSpeechRecognitionUsageDescription</key><string>This app uses speech recognition</string><key>NSMicrophoneUsageDescription</key><string>This app uses the microphone for speech recognition</string>Windows — Add the Microphone capability to your Package.appxmanifest:
<Capabilities> <DeviceCapability Name="microphone" /></Capabilities>Dependencies
Section titled “Dependencies”All required dependencies are pulled in transitively by the Shiny.AiConversation package — you only need to install the one package.
| Package | Purpose |
|---|---|
Microsoft.Extensions.AI | IChatClient abstraction for AI chat completions |
Shiny.Speech | Speech-to-text, text-to-speech, and audio playback |
Samples
Section titled “Samples”- Sample MAUI App — Full chat app with GitHub Copilot authentication, settings, and aura visualization
- Sample Blazor WASM App — Blazor WebAssembly app with static OpenAI provider
AI Coding Assistant
Section titled “AI Coding Assistant”Step 1 — Add the marketplace:
claude plugin marketplace add shinyorg/skills Step 2 — Install plugins:
claude plugin install shiny-client@shiny claude plugin install shiny-maui@shiny claude plugin install controls@shiny claude plugin install shiny-mediator@shiny claude plugin install shiny-data@shiny claude plugin install shiny-aspire@shiny claude plugin install shiny-extensions@shiny Step 1 — Add the marketplace:
copilot plugin marketplace add https://github.com/shinyorg/skills Step 2 — Install plugins:
copilot plugin install shiny-client@shiny copilot plugin install shiny-maui@shiny copilot plugin install controls@shiny copilot plugin install shiny-mediator@shiny copilot plugin install shiny-data@shiny copilot plugin install shiny-aspire@shiny copilot plugin install shiny-extensions@shiny Next Steps
Section titled “Next Steps”- Chat Client Provider — How to implement
IChatClientProviderfor different AI backends - Message Store — Persist and query chat history
- Acknowledgements & Sound — Configure audio feedback and text-to-speech modes
- Wake Word — Hands-free voice activation
- AI Tools — Register AI tools including the built-in chat history lookup