Blazor 前端¶
本導覽說明位於零售分析 API 前方的 Blazor WebAssembly 用戶端。您將瞭解它如何連線至 API、將聊天回應串流至訊息清單、儲存本機設定,並讓模型選擇器與線上模型清單保持一致。
應用程式結構與連接埠¶
前端是位於下列路徑的 Blazor WebAssembly 應用程式:
AgentHQDemo.Web。
在此存放庫中,這兩個服務一律以明確的
--urls,而這會覆寫啟動設定檔:
因此,文件、圖表與實驗都會參照 5051 供 UI 使用,以及
5050 供 API 使用。⚠️ 簽入的啟動設定檔預設使用 不同
連接埠—Web 專案使用 5240,API 使用 5167—因此若不使用
--urls (或在 IDE 中按 F5)則會改由這些連接埠提供服務,而 UI 的預設 API 基底位址 http://localhost:5050 將不再相符。請傳入 --urls (如文件所述),或設定 ApiBaseUrl 以保持一致。
AgentHQDemo.Web/Program.cs
會設定 API 基底位址:
var apiBase = builder.Configuration["ApiBaseUrl"] ?? "http://localhost:5050";
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(apiBase) });
API 會在
AgentHQDemo.Api/Program.cs
啟用 CORS,並採用允許任何來源、方法與標頭的預設原則。這可讓從本機開發 URL 提供的 WebAssembly 應用程式,在示範期間呼叫已設定的 API 基底位址。
Home.razor¶
Home.razor 是主要聊天頁面,並擁有下列頁面狀態:
Messages:依序排列的聊天記錄。SelectedModel:目前選取的 Copilot 模型。Models:模型 ID 與顯示名稱的字典。IsDarkTheme:目前的佈景主題旗標。IsStreaming:助理回應是否正在進行。
沒有訊息時,頁面會顯示歡迎面板以及
SuggestionChips。只要已有訊息,它便會使用 Message
元件。
串流狀態與捲動¶
Home.razor.SendMessage 會加入使用者訊息並加以儲存,接著附加一則空白的助理預留訊息。當 IsStreaming 為 true 時,輸入會停用,且助理訊息會隨著來自下列來源的區塊抵達而更新:
ChatService.StreamChatAsync。
頁面會使用 Timer 以每秒約 20 個畫面的頻率批次更新 UI,而不是每收到一個權杖就重新呈現。呈現後,它會呼叫 JavaScript 協助程式,將訊息容器捲動到底部並醒目提示程式碼區塊。
本機儲存持久化¶
StorageService
會封裝 Blazored.LocalStorage。它會在本機儲存三個值:
| 索引鍵 | 用途 |
|---|---|
chat_messages |
儲存的 ChatMessage 聊天記錄。 |
selected_model |
下次載入頁面時還原的模型。 |
theme |
儲存的 dark 或 light 佈景主題。 |
Home.razor.OnInitializedAsync 會在擷取模型清單前載入全部三個值。
模型選擇器¶
Header.razor
會呈現模型選擇器。它會接收線上 Models 字典,並將選取的選項繫結至 SelectedModel:
當使用者變更選項時, Header.OnModelChanged 會叫用
SelectedModelChanged 回呼。 Home.razor.OnModelChanged 會更新本機狀態,並透過下列方式儲存新模型: StorageService.SetSelectedModelAsync。
擷取線上模型¶
ChatService.GetModelsAsync
會從 API 載入模型中繼資料:
如果 API 至少回傳一個模型,服務會將其轉換為
Dictionary<string, string>,供 Header.razor 使用。如果 API 無法連線或回傳無法使用的資料,則會退回使用 ChatService.AvailableModels,也就是供離線備援使用的靜態目錄。
防範已儲存的過期模型¶
儲存在本機的模型可能已不再提供給目前登入的帳戶。 Home.razor.OnInitializedAsync 會在擷取線上模型後處理此情況:
if (!Models.ContainsKey(SelectedModel))
{
SelectedModel = Models.ContainsKey("claude-haiku-4.5")
? "claude-haiku-4.5"
: Models.Keys.First();
}
接著,頁面會儲存替代模型。這可避免使用舊的 localStorage 值,否則聊天要求可能會使用 API 已不再提供的模型。
支援元件¶
ChatInput
提供文字區域與傳送按鈕。按一下按鈕或按下未搭配 Shift 的 Enter 鍵時會傳送訊息;載入時會停用輸入、修剪空白訊息,並在第一次呈現後將焦點移至輸入欄位。
Message
會呈現使用者與助理訊息。空白助理內容會顯示輸入中指示器;非空白內容會使用 Markdig 從 Markdown 呈現,程式碼區塊則會標記以供 JavaScript 執行醒目提示。
SuggestionChips
會顯示預先定義的零售分析提示詞。選取提示詞按鈕後,會透過相同的 Home.razor.SendMessage 路徑傳送,行為與手動輸入相同。