From efd0d20ccaef4d6656114e922974564aad7f4b52 Mon Sep 17 00:00:00 2001 From: Hillary Mutisya <150286414+hillary-mutisya@users.noreply.github.com> Date: Sun, 13 Sep 2026 15:01:27 -0700 Subject: [PATCH] Simplify MSI installer options page Remove Ollama and embedding choices from the MSI installer, reject legacy provider properties, and provision Copilot with local embeddings automatically. Update installer docs and add tests for the simplified provider UI. --- ts/config.sample.yaml | 7 +- ts/tools/installers/wix/README.md | 68 +++++----- .../installers/wix/TypeAgent-AgentServer.wxs | 127 +++++++----------- .../test/msiInstallerProviderUi.spec.mjs | 83 ++++++++++++ 4 files changed, 164 insertions(+), 121 deletions(-) create mode 100644 ts/tools/scripts/test/msiInstallerProviderUi.spec.mjs diff --git a/ts/config.sample.yaml b/ts/config.sample.yaml index 194b7179c1..0c6bd11320 100644 --- a/ts/config.sample.yaml +++ b/ts/config.sample.yaml @@ -138,9 +138,10 @@ openAI: # ╚═══════════════════════════════════════════════════════════════════╝ # # For machines WITHOUT AI Systems Key Vault access, TypeAgent can run entirely -# against a local (Ollama) or Copilot-SDK chat backend. The install scripts and -# MSI generate one of these config.local.yaml shapes automatically via -# `typeagent-serve.mjs provision --provider ollama|copilot` +# against a local (Ollama) or Copilot-SDK chat backend. The script installers +# and provisioning CLI can generate either config.local.yaml shape via +# `typeagent-serve.mjs provision --provider ollama|copilot`; the MSI exposes +# Copilot only and selects local embeddings automatically # (tools/scripts/generate-selfhost-config.mjs). The blocks below are the # equivalent hand-written config; omit the `vault:` section in these modes. # diff --git a/ts/tools/installers/wix/README.md b/ts/tools/installers/wix/README.md index e92def7d52..909852dd64 100644 --- a/ts/tools/installers/wix/README.md +++ b/ts/tools/installers/wix/README.md @@ -328,55 +328,49 @@ On uninstall the MSI removes the extension only when the installed version still matches the version originally installed by TypeAgent, so it does not delete an independently upgraded extension. -## Endpoint provider selection (self-host) +## Endpoint provider selection TypeAgent needs an LLM endpoint configuration (`config.local.yaml`) at runtime. -By default it is downloaded from the AI Systems Key Vault, but machines without -Key Vault access can instead run against a local **Ollama** server or the -**Copilot** SDK. - -During an **interactive** install the MSI shows a provider-selection dialog -(after the license page) with radio-button groups for the chat provider -(AI Systems / Ollama / Copilot), the embedding provider (Local / Ollama / OpenAI -/ None), and an Ollama host field. The same choices can be driven **silently** -through public properties: - -| Property | Values | Default | Notes | -| ------------ | ----------------------------------- | ------------------------ | ------------------------------------------------------------------------------- | -| `PROVIDER` | `AISYSTEMS`, `OLLAMA`, `COPILOT` | `AISYSTEMS` | `OLLAMA`/`COPILOT` generate `config.local.yaml` during install (no Key Vault). | -| `EMBEDDING` | `LOCAL`, `OLLAMA`, `OPENAI`, `NONE` | `LOCAL` | Embedding source for the self-host providers. `LOCAL` = bundled CPU-only model. | -| `OLLAMAHOST` | any URL | `http://localhost:11434` | Ollama base URL (used for `OLLAMA` chat and/or embeddings). | +The MSI supports two completion providers: + +- **AI Systems** downloads configuration from the AI Systems Key Vault. +- **GitHub Copilot** uses the authenticated Copilot CLI for chat and + automatically configures TypeAgent's local embedding provider. + +During an **interactive** install the provider-selection dialog appears after +the license page. The same choice can be driven **silently** through the public +`PROVIDER` property: + +| Property | Values | Default | Notes | +| ---------- | ---------------------- | ----------- | ---------------------------------------------------------------------- | +| `PROVIDER` | `AISYSTEMS`, `COPILOT` | `AISYSTEMS` | `COPILOT` generates `config.local.yaml` with local embeddings enabled. | ```powershell # AI Systems (default) — provisions via az login + getKeys after install msiexec /i TypeAgent--win32-x64.msi -# Local Ollama chat with the bundled local embedding model -msiexec /i TypeAgent--win32-x64.msi PROVIDER=OLLAMA - -# Copilot SDK chat (requires an authenticated `copilot` CLI) + local embeddings +# Copilot chat (requires an authenticated `copilot` CLI) + local embeddings msiexec /i TypeAgent--win32-x64.msi PROVIDER=COPILOT -# Fully silent -msiexec /i TypeAgent--win32-x64.msi /quiet PROVIDER=OLLAMA EMBEDDING=LOCAL +# Fully silent Copilot install +msiexec /i TypeAgent--win32-x64.msi /quiet PROVIDER=COPILOT ``` The UI is a custom scheme (`WixUI_TypeAgent`): WelcomeDlg → **ProviderDlg** → -VerifyReadyDlg. For `OLLAMA`/`COPILOT`, a deferred, impersonated custom action -runs `node "[INSTALLFOLDER]typeagent-serve.mjs" provision --provider [PROVIDER] ---embedding [EMBEDDING] --ollama-host [OLLAMAHOST] --force` as the installing -user, writing `config.local.yaml` to `~/.typeagent`. For `AISYSTEMS` -(the default), the MSI **attempts** provisioning during install via a deferred, -impersonated (interactive) custom action `ProvisionAiSystemsConfig` that runs -`node "[INSTALLFOLDER]typeagent-serve.mjs" provision` (browser/device sign-in as -the installing user). It is **non-fatal**: if sign-in is unavailable during the -install, the final page (ExitDialog) reminds the user to run `provision` -manually. Because the embedding config for `AISYSTEMS` comes from Key Vault, the -embedding radio and Ollama host field are **disabled** in the dialog when -`PROVIDER=AISYSTEMS` (they apply only to the self-host providers). Fine-grained -overrides (chat model, embedding endpoint, API keys) are available on the -`provision`/`generate-selfhost-config` CLI; re-run provisioning post-install to -adjust them. +VerifyReadyDlg. For `COPILOT`, a deferred, impersonated custom action runs +`node "[INSTALLFOLDER]typeagent-serve.mjs" provision --provider COPILOT +--embedding LOCAL --force` as the installing user, writing +`config.local.yaml` to `~/.typeagent`. For `AISYSTEMS` (the default), the MSI +**attempts** provisioning during install via a deferred, impersonated +(interactive) custom action `ProvisionAiSystemsConfig` that runs +`node "[INSTALLFOLDER]typeagent-serve.mjs" provision` (browser/device sign-in +as the installing user). It is **non-fatal**: if sign-in is unavailable during +the install, the final page (ExitDialog) reminds the user to run `provision` +manually. + +The MSI rejects `PROVIDER=OLLAMA` and the legacy `EMBEDDING` and `OLLAMAHOST` +properties. Ollama and custom embedding configurations remain available through +the script installers and the `provision`/`generate-selfhost-config` CLI. ## Agent-server prerequisites & lifecycle diff --git a/ts/tools/installers/wix/TypeAgent-AgentServer.wxs b/ts/tools/installers/wix/TypeAgent-AgentServer.wxs index 52e9313c71..90bdec4006 100644 --- a/ts/tools/installers/wix/TypeAgent-AgentServer.wxs +++ b/ts/tools/installers/wix/TypeAgent-AgentServer.wxs @@ -56,16 +56,19 @@ - - + + PROVIDER="AISYSTEMS" OR PROVIDER="COPILOT" + + + NOT EMBEDDING AND NOT OLLAMAHOST + - + Value=""[WindowsFolder]System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass -NoProfile -NonInteractive -File "[TYPEAGENTROOT]run-serve.ps1" -ServePath "[INSTALLFOLDER]typeagent-serve.mjs" -LogPath "[LocalAppDataFolder]TypeAgent\logs\msi-serve.log" provision --provider COPILOT --embedding LOCAL --force" /> - (NOT REMOVE~="ALL") AND (VSCODECHAT="1") (NOT Installed) AND (VSCODESHELL="1") NOT REMOVE~="ALL" - (NOT REMOVE~="ALL") AND (PROVIDER<>"AISYSTEMS") - (NOT REMOVE~="ALL") AND (PROVIDER="AISYSTEMS") + (NOT REMOVE~="ALL") AND (PROVIDER="COPILOT") + (NOT REMOVE~="ALL") AND (PROVIDER="AISYSTEMS") NOT REMOVE~="ALL" @@ -699,7 +702,7 @@ REMOVE~="ALL" - + @@ -707,10 +710,10 @@ @@ -726,7 +729,7 @@ Step 3 of 8: Registering Copilot plugin... Step 4 of 8: Installing TypeAgent Chat for VS Code... Step 4 of 8: Installing TypeAgent VS Code Shell... - Step 5 of 8: Configuring TypeAgent... + Step 5 of 8: Configuring TypeAgent for GitHub Copilot... Step 5 of 8: Downloading TypeAgent configuration... Step 6 of 8: Checking TypeAgent prerequisites... Step 7 of 8: Starting TypeAgent agent server... @@ -749,91 +752,53 @@ - - + + - + + Text="Choose the components to install and how TypeAgent connects to language models." /> + Width="326" Height="36" Property="PROVIDER"> - - + Text="AI Systems — Azure Key Vault configuration (requires az login access)" /> + - - PROVIDER="AISYSTEMS" - PROVIDER<>"AISYSTEMS" - - - - - - - - - - PROVIDER="AISYSTEMS" - PROVIDER<>"AISYSTEMS" - - - - PROVIDER="AISYSTEMS" - PROVIDER<>"AISYSTEMS" - - - PROVIDER="AISYSTEMS" - PROVIDER<>"AISYSTEMS" - - - - - - - - + - - 1 diff --git a/ts/tools/scripts/test/msiInstallerProviderUi.spec.mjs b/ts/tools/scripts/test/msiInstallerProviderUi.spec.mjs new file mode 100644 index 0000000000..5faf4761bf --- /dev/null +++ b/ts/tools/scripts/test/msiInstallerProviderUi.spec.mjs @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; +import test from "node:test"; + +const scriptsDir = path.dirname(fileURLToPath(import.meta.url)); +const wxs = readFileSync( + path.resolve( + scriptsDir, + "..", + "..", + "installers", + "wix", + "TypeAgent-AgentServer.wxs", + ), + "utf8", +); + +const providerRadio = wxs.match( + //, +)?.[0]; + +test("MSI labels the second page as Install Options", () => { + assert.match(wxs, /Text="\{\\WixUI_Font_Title\}Install Options"/); + assert.match( + wxs, + /Text="Choose the components to install and how TypeAgent connects to language models\."/, + ); +}); + +test("MSI provider selection is limited to AI Systems and GitHub Copilot", () => { + assert.ok(providerRadio, "ProviderRadio control must exist"); + assert.match(providerRadio, / { + assert.match( + wxs, + //, + ); + assert.match(wxs, /PROVIDER="AISYSTEMS" OR PROVIDER="COPILOT"/); + assert.match(wxs, /Ollama is not supported by this MSI/); +}); + +test("MSI no longer exposes embedding or Ollama host properties and controls", () => { + assert.doesNotMatch(wxs, / { + const command = wxs.match( + / { + assert.match( + wxs, + /]*>\(NOT REMOVE~="ALL"\) AND \(PROVIDER="COPILOT"\)<\/Custom>/, + ); + assert.match( + wxs, + /]*>\(NOT REMOVE~="ALL"\) AND \(PROVIDER="AISYSTEMS"\)<\/Custom>/, + ); +});