Skip to content

Commit 853a339

Browse files
committed
Update docs & test methods
1 parent c640deb commit 853a339

11 files changed

Lines changed: 247 additions & 219 deletions

File tree

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
- [Docker Model Runner](./docker-model-runner.md)
77
- [Foundry Local](./foundry-local.md)
88
- [Hugging Face](./hugging-face.md)
9-
- [Ollama](ollama.md)
9+
- [Ollama](./ollama.md)
1010
- [LG](./lg.md)
1111
- [OpenAI](./openai.md)
1212
- [Upstage](./upstage.md)

docs/ollama.md

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,31 @@ This page describes how to run OpenChat Playground (OCP) with [Ollama](https://o
1818

1919
## Run on local machine
2020

21-
1. Make sure Ollama is installed and running on your local machine. If not, install Ollama from [ollama.com](https://ollama.com/) and start the service.
21+
1. Make sure Ollama is installed and running on your local machine. If not, install Ollama from [ollama.com](https://ollama.com/search) and start the service.
2222

2323
```bash
2424
ollama serve
2525
```
2626

27-
1. Pull the model you want to use. The default model OCP uses is "llama3.2"
27+
1. Pull the model you want to use. The default model OCP uses is [llama3.2](https://ollama.com/library/llama3.2).
2828

2929
```bash
3030
ollama pull llama3.2
3131
```
32-
33-
Alternatively, if you want to run with a different model, say [qwen](https://ollama.com/library/qwen) other than the default one, download it first by running the following command.
32+
33+
Alternatively, if you want to run with a different model, say [qwen3](https://ollama.com/library/qwen3) other than the default one, download it first by running the following command.
3434

3535
```bash
36-
ollama pull qwen
36+
ollama pull qwen3
3737
```
3838

39-
2. Make sure you are at the repository root.
39+
1. Make sure you are at the repository root.
4040

4141
```bash
4242
cd $REPOSITORY_ROOT
4343
```
4444

45-
3. Run the app.
45+
1. Run the app.
4646

4747
```bash
4848
# bash/zsh
@@ -56,44 +56,42 @@ This page describes how to run OpenChat Playground (OCP) with [Ollama](https://o
5656
--connector-type Ollama
5757
```
5858
59-
Alternatively, if you want to run with a different model, say [qwen](https://ollama.com/library/qwen) other than the default one, download it first by running the following command.
59+
Alternatively, if you want to run with a different model, say [qwen3](https://ollama.com/library/qwen3), make sure you've already downloaded the model by running the `ollama pull qwen3` command.
6060
6161
```bash
6262
# bash/zsh
6363
dotnet run --project $REPOSITORY_ROOT/src/OpenChat.PlaygroundApp -- \
6464
--connector-type Ollama \
65-
--model qwen
65+
--model qwen3
6666
```
6767
6868
```powershell
6969
# PowerShell
7070
dotnet run --project $REPOSITORY_ROOT\src\OpenChat.PlaygroundApp -- `
7171
--connector-type Ollama `
72-
--model qwen
72+
--model qwen3
7373
```
7474
75-
4. Open your web browser, navigate to `http://localhost:5280`, and enter prompts.
75+
1. Open your web browser, navigate to `http://localhost:5280`, and enter prompts.
7676
7777
## Run on local container
7878
79-
This approach runs OpenChat Playground in a container while connecting to Ollama running on the host machine.
80-
81-
1. Configure Ollama to accept connections from containers.
79+
1. Make sure the Ollama server is up and running.
8280
8381
```bash
8482
ollama serve
8583
```
8684
87-
1. Pull the model you want to use, and verify Ollama is accessible
85+
1. Download the Ollama model. The default model OCP uses is [llama3.2](https://ollama.com/library/llama3.2).
8886
8987
```bash
9088
ollama pull llama3.2
91-
curl http://localhost:11434/api/version
9289
```
93-
94-
```powershell
95-
ollama pull llama3.2
96-
Invoke-RestMethod -Uri http://localhost:11434/api/version
90+
91+
Alternatively, if you want to run with a different model, say [qwen3](https://ollama.com/library/qwen3), other than the default one, download it first by running the following command.
92+
93+
```bash
94+
ollama pull qwen3
9795
```
9896
9997
1. Make sure you are at the repository root.
@@ -126,54 +124,54 @@ This approach runs OpenChat Playground in a container while connecting to Ollama
126124
127125
```bash
128126
# bash/zsh - from GitHub Container Registry
129-
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest\
127+
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest \
130128
--connector-type Ollama \
131129
--base-url http://host.docker.internal:11434
132130
```
133-
131+
134132
```powershell
135133
# PowerShell - from GitHub Container Registry
136134
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest `
137135
--connector-type Ollama `
138136
--base-url http://host.docker.internal:11434
139137
```
140138
141-
Alternatively, if you want to run with a different model, say [qwen](https://ollama.com/library/qwen), make sure you've already downloaded the model by running the `ollama pull qwen` command.
139+
Alternatively, if you want to run with a different model, say [qwen3](https://ollama.com/library/qwen), make sure you've already downloaded the model by running the `ollama pull qwen3` command.
142140
143141
```bash
144-
ollama pull qwen
142+
ollama pull qwen3
145143
```
146144
147145
```bash
148146
# bash/zsh - from locally built container
149147
docker run -i --rm -p 8080:8080 openchat-playground:latest \
150148
--connector-type Ollama \
151149
--base-url http://host.docker.internal:11434 \
152-
--model qwen
150+
--model qwen3
153151
```
154152
155153
```powershell
156154
# PowerShell - from locally built container
157155
docker run -i --rm -p 8080:8080 openchat-playground:latest `
158156
--connector-type Ollama `
159157
--base-url http://host.docker.internal:11434 `
160-
--model qwen
158+
--model qwen3
161159
```
162160
163161
```bash
164162
# bash/zsh - from GitHub Container Registry
165-
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest\
163+
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest \
166164
--connector-type Ollama \
167165
--base-url http://host.docker.internal:11434 \
168-
--model qwen
166+
--model qwen3
169167
```
170-
168+
171169
```powershell
172170
# PowerShell - from GitHub Container Registry
173171
docker run -i --rm -p 8080:8080 ghcr.io/aliencube/open-chat-playground/openchat-playground:latest `
174172
--connector-type Ollama `
175173
--base-url http://host.docker.internal:11434 `
176-
--model qwen
174+
--model qwen3
177175
```
178176
179177
> **NOTE**: Use `host.docker.internal:11434` to connect to Ollama running on the host machine from inside the container.
@@ -216,21 +214,21 @@ This approach runs OpenChat Playground in a container while connecting to Ollama
216214
azd env set CONNECTOR_TYPE "Ollama"
217215
```
218216
219-
The default model OCP uses is [llama3.2](https://ollama.com/library/llama3.2). If you want to run with a different model, say [qwen](https://ollama.com/library/qwen) other than the default one, add it to azd environment variables.
217+
The default model OCP uses is [llama3.2](https://ollama.com/library/llama3.2). If you want to run with a different model, say [qwen3](https://ollama.com/library/qwen3) other than the default one, add it to azd environment variables.
220218
221219
```bash
222-
azd env set OLLAMA_MODEL "qwen"
220+
azd env set OLLAMA_MODEL "qwen3"
223221
```
224222
225-
2. As a default, the app uses a Serverless GPU with NVIDIA T4 (`NC8as-T4`). If you want to use NVIDIA A100, set the GPU profile.
223+
1. As a default, the app uses a Serverless GPU with NVIDIA T4 (`NC8as-T4`). If you want to use NVIDIA A100, set the GPU profile.
226224
227225
```bash
228226
azd env set GPU_PROFILE_NAME "NC24-A100"
229227
```
230228
231229
If you want to know more about Serverless GPU, visit [Using serverless GPUs in Azure Container Apps](https://learn.microsoft.com/azure/container-apps/gpu-serverless-overview#use-serverless-gpus).
232230
233-
3. Run the following commands in order to provision and deploy the app.
231+
1. Run the following commands in order to provision and deploy the app.
234232
235233
```bash
236234
azd up
@@ -241,9 +239,9 @@ This approach runs OpenChat Playground in a container while connecting to Ollama
241239
242240
Once deployed, you will be able to see the deployed OCP app URL.
243241
244-
4. Open your web browser, navigate to the OCP app URL, and enter prompts.
242+
1. Open your web browser, navigate to the OCP app URL, and enter prompts.
245243
246-
5. Clean up all the resources.
244+
1. Clean up all the resources.
247245
248246
```bash
249247
azd down --force --purge

src/OpenChat.PlaygroundApp/Connectors/HuggingFaceConnector.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public override async Task<IChatClient> GetChatClientAsync()
5353
var settings = this.Settings as HuggingFaceSettings;
5454

5555
var baseUrl = settings!.BaseUrl!.Trim() ?? throw new InvalidOperationException("Missing configuration: HuggingFace:BaseUrl.");
56+
if (Uri.IsWellFormedUriString(baseUrl, UriKind.Absolute) == false)
57+
{
58+
throw new UriFormatException($"Invalid URI: The Hugging Face base URL '{baseUrl}' is not a valid URI.");
59+
}
5660
var model = settings!.Model!.Trim() ?? throw new InvalidOperationException("Missing configuration: HuggingFace:Model.");
5761

5862
var config = new OllamaApiClient.Configuration

src/OpenChat.PlaygroundApp/Connectors/LGConnector.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ public override async Task<IChatClient> GetChatClientAsync()
4747
var settings = this.Settings as LGSettings;
4848

4949
var baseUrl = settings!.BaseUrl!.Trim() ?? throw new InvalidOperationException("Missing configuration: LG:BaseUrl.");
50+
if (Uri.IsWellFormedUriString(baseUrl, UriKind.Absolute) == false)
51+
{
52+
throw new UriFormatException($"Invalid URI: The LG base URL '{baseUrl}' is not a valid URI.");
53+
}
5054
var model = settings!.Model!.Trim() ?? throw new InvalidOperationException("Missing configuration: LG:Model.");
5155

5256
var config = new OllamaApiClient.Configuration

src/OpenChat.PlaygroundApp/Connectors/OllamaConnector.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
using OpenChat.PlaygroundApp.Abstractions;
66
using OpenChat.PlaygroundApp.Configurations;
77

8-
using System.Linq;
9-
108
namespace OpenChat.PlaygroundApp.Connectors;
119

1210
/// <summary>
@@ -15,11 +13,11 @@ namespace OpenChat.PlaygroundApp.Connectors;
1513
public class OllamaConnector(AppSettings settings) : LanguageModelConnector(settings.Ollama)
1614
{
1715
private readonly AppSettings _appSettings = settings ?? throw new ArgumentNullException(nameof(settings));
16+
1817
/// <inheritdoc/>
1918
public override bool EnsureLanguageModelSettingsValid()
2019
{
21-
var settings = this.Settings as OllamaSettings;
22-
if (settings is null)
20+
if (this.Settings is not OllamaSettings settings)
2321
{
2422
throw new InvalidOperationException("Missing configuration: Ollama.");
2523
}
@@ -41,8 +39,13 @@ public override bool EnsureLanguageModelSettingsValid()
4139
public override async Task<IChatClient> GetChatClientAsync()
4240
{
4341
var settings = this.Settings as OllamaSettings;
44-
var baseUrl = settings!.BaseUrl!;
45-
var model = settings!.Model!;
42+
43+
var baseUrl = settings!.BaseUrl!.Trim() ?? throw new InvalidOperationException("Missing configuration: Ollama:BaseUrl.");
44+
if (Uri.IsWellFormedUriString(baseUrl, UriKind.Absolute) == false)
45+
{
46+
throw new UriFormatException($"Invalid URI: The Ollama base URL '{baseUrl}' is not a valid URI.");
47+
}
48+
var model = settings!.Model!.Trim() ?? throw new InvalidOperationException("Missing configuration: Ollama:Model.");
4649

4750
var config = new OllamaApiClient.Configuration
4851
{
@@ -51,13 +54,15 @@ public override async Task<IChatClient> GetChatClientAsync()
5154
};
5255

5356
var chatClient = new OllamaApiClient(config);
57+
5458
var pulls = chatClient.PullModelAsync(model);
5559
await foreach (var pull in pulls)
5660
{
5761
Console.WriteLine($"Pull status: {pull!.Status}");
5862
}
5963

60-
Console.WriteLine($"The {this._appSettings.ConnectorType} connector created with model: {settings.Model}");
61-
return await Task.FromResult(chatClient).ConfigureAwait(false);
64+
Console.WriteLine($"The {this._appSettings.ConnectorType} connector created with model: {model}");
65+
66+
return chatClient;
6267
}
6368
}

src/OpenChat.PlaygroundApp/Connectors/UpstageConnector.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ public class UpstageConnector(AppSettings settings) : LanguageModelConnector(set
1919
/// <inheritdoc/>
2020
public override bool EnsureLanguageModelSettingsValid()
2121
{
22-
var settings = this.Settings as UpstageSettings;
23-
if (settings is null)
22+
if (this.Settings is not UpstageSettings settings)
2423
{
2524
throw new InvalidOperationException("Missing configuration: Upstage.");
2625
}

test/OpenChat.PlaygroundApp.Tests/Connectors/DockerModelRunnerConnectorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,11 @@ public async Task Given_Valid_Settings_When_GetChatClient_Invoked_Then_It_Should
217217

218218
[Trait("Category", "UnitTest")]
219219
[Theory]
220-
[InlineData(null, Model, typeof(InvalidOperationException),"DockerModelRunner:BaseUrl")]
220+
[InlineData(null, Model, typeof(InvalidOperationException),"DockerModelRunner:BaseUrl")]
221221
[InlineData("", Model, typeof(InvalidOperationException), "DockerModelRunner:BaseUrl")]
222222
[InlineData(" ", Model, typeof(InvalidOperationException), "DockerModelRunner:BaseUrl")]
223223
[InlineData("\t\r\n", Model, typeof(InvalidOperationException), "DockerModelRunner:BaseUrl")]
224-
[InlineData(BaseUrl, null, typeof(InvalidOperationException), "DockerModelRunner:Model")]
224+
[InlineData(BaseUrl, null, typeof(InvalidOperationException), "DockerModelRunner:Model")]
225225
[InlineData(BaseUrl, "", typeof(InvalidOperationException), "DockerModelRunner:Model")]
226226
[InlineData(BaseUrl, " ", typeof(InvalidOperationException), "DockerModelRunner:Model")]
227227
[InlineData(BaseUrl, "\t\r\n", typeof(InvalidOperationException), "DockerModelRunner:Model")]

test/OpenChat.PlaygroundApp.Tests/Connectors/FoundryLocalConnectorTests.cs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,32 @@ public void Given_Null_FoundryLocalSettings_When_GetChatClient_Invoked_Then_It_S
137137
.Message.ShouldContain("Object reference not set to an instance of an object.");
138138
}
139139

140+
[Trait("Category", "UnitTest")]
141+
[Theory]
142+
[InlineData(null, typeof(NullReferenceException), "Object reference not set to an instance of an object")]
143+
public void Given_Null_Alias_When_GetChatClient_Invoked_Then_It_Should_Throw(string? alias, Type expected, string message)
144+
{
145+
// Arrange
146+
var settings = BuildAppSettings(alias: alias);
147+
var connector = new FoundryLocalConnector(settings);
148+
149+
// Act
150+
Func<Task> func = async () => await connector.GetChatClientAsync();
151+
152+
// Assert
153+
func.ShouldThrow(expected)
154+
.Message.ShouldContain(message);
155+
}
156+
140157
[Trait("Category", "IntegrationTest")]
141158
[Trait("Category", "LLMRequired")]
142159
[Trait("Category", "IgnoreGitHubActions")]
143160
[Theory]
144-
[InlineData(null, typeof(InvalidOperationException), "not found in catalog.")]
145-
[InlineData("", typeof(InvalidOperationException), "not found in catalog.")]
146-
[InlineData(" ", typeof(InvalidOperationException), "not found in catalog.")]
147-
[InlineData("\t\r\n", typeof(InvalidOperationException), "not found in catalog.")]
148-
[InlineData("not-a-model", typeof(InvalidOperationException), "not found in catalog.")]
161+
[InlineData(null, typeof(NullReferenceException), "Object reference not set to an instance of an object")]
162+
[InlineData("", typeof(InvalidOperationException), "not found in catalog")]
163+
[InlineData(" ", typeof(InvalidOperationException), "not found in catalog")]
164+
[InlineData("\t\r\n", typeof(InvalidOperationException), "not found in catalog")]
165+
[InlineData("not-a-model", typeof(InvalidOperationException), "not found in catalog")]
149166
public void Given_Invalid_Alias_When_GetChatClient_Invoked_Then_It_Should_Throw(string? alias, Type expected, string message)
150167
{
151168
// Arrange

test/OpenChat.PlaygroundApp.Tests/Connectors/HuggingFaceConnectorTests.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public void Given_Null_HuggingFaceSettings_When_GetChatClientAsync_Invoked_Then_
166166
[Trait("Category", "UnitTest")]
167167
[Theory]
168168
[InlineData(null, typeof(NullReferenceException), "Object reference not set to an instance of an object")]
169-
[InlineData("", typeof(UriFormatException), "empty")]
169+
[InlineData("", typeof(UriFormatException), "Invalid URI:")]
170170
[InlineData(" ", typeof(UriFormatException), "Invalid URI:")]
171171
[InlineData("\t\r\n", typeof(UriFormatException), "Invalid URI:")]
172172
[InlineData("invalid-uri-format", typeof(UriFormatException), "Invalid URI:")]
@@ -243,17 +243,17 @@ public async Task Given_Valid_Settings_When_GetChatClient_Invoked_Then_It_Should
243243

244244
[Trait("Category", "UnitTest")]
245245
[Theory]
246-
[InlineData(null, Model, typeof(NullReferenceException),"Object reference not set to an instance of an object")]
247-
[InlineData("", Model, typeof(InvalidOperationException), "Missing configuration: HuggingFace:BaseUrl")]
248-
[InlineData(" ", Model, typeof(InvalidOperationException), "Missing configuration: HuggingFace:BaseUrl")]
249-
[InlineData("\t\r\n", Model, typeof(InvalidOperationException), "Missing configuration: HuggingFace:BaseUrl")]
250-
[InlineData(BaseUrl, null, typeof(NullReferenceException), "Object reference not set to an instance of an object")]
251-
[InlineData(BaseUrl, "", typeof(InvalidOperationException), "Missing configuration: HuggingFace:Model")]
252-
[InlineData(BaseUrl, " ", typeof(InvalidOperationException), "Missing configuration: HuggingFace:Model")]
253-
[InlineData(BaseUrl, "\t\r\n", typeof(InvalidOperationException), "Missing configuration: HuggingFace:Model")]
254-
[InlineData(BaseUrl, "hf.co/org/model", typeof(InvalidOperationException), "Invalid configuration: HuggingFace:Model format")]
255-
[InlineData(BaseUrl, "org/model-gguf", typeof(InvalidOperationException), "Invalid configuration: HuggingFace:Model format")]
256-
[InlineData(BaseUrl, "hf.co//model-gguf", typeof(InvalidOperationException), "Invalid configuration: HuggingFace:Model format")]
246+
[InlineData(null, Model, typeof(NullReferenceException),"Object reference not set to an instance of an object")]
247+
[InlineData("", Model, typeof(InvalidOperationException), "Missing configuration: HuggingFace:BaseUrl")]
248+
[InlineData(" ", Model, typeof(InvalidOperationException), "Missing configuration: HuggingFace:BaseUrl")]
249+
[InlineData("\t\r\n", Model, typeof(InvalidOperationException), "Missing configuration: HuggingFace:BaseUrl")]
250+
[InlineData(BaseUrl, null, typeof(NullReferenceException), "Object reference not set to an instance of an object")]
251+
[InlineData(BaseUrl, "", typeof(InvalidOperationException), "Missing configuration: HuggingFace:Model")]
252+
[InlineData(BaseUrl, " ", typeof(InvalidOperationException), "Missing configuration: HuggingFace:Model")]
253+
[InlineData(BaseUrl, "\t\r\n", typeof(InvalidOperationException), "Missing configuration: HuggingFace:Model")]
254+
[InlineData(BaseUrl, "hf.co/org/model", typeof(InvalidOperationException), "Invalid configuration: HuggingFace:Model format")]
255+
[InlineData(BaseUrl, "org/model-gguf", typeof(InvalidOperationException), "Invalid configuration: HuggingFace:Model format")]
256+
[InlineData(BaseUrl, "hf.co//model-gguf", typeof(InvalidOperationException), "Invalid configuration: HuggingFace:Model format")]
257257
public void Given_Invalid_Settings_When_CreateChatClientAsync_Invoked_Then_It_Should_Throw(string? baseUrl, string? model, Type expected, string expectedMessage)
258258
{
259259
// Arrange

test/OpenChat.PlaygroundApp.Tests/Connectors/LGConnectorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public void Given_Valid_Model_Format_When_EnsureLanguageModelSettingsValid_Invok
151151
[Trait("Category", "UnitTest")]
152152
[Theory]
153153
[InlineData(null, typeof(NullReferenceException), "Object reference not set to an instance of an object")]
154-
[InlineData("", typeof(UriFormatException), "empty")]
154+
[InlineData("", typeof(UriFormatException), "Invalid URI:")]
155155
[InlineData(" ", typeof(UriFormatException), "Invalid URI:")]
156156
[InlineData("\t\r\n", typeof(UriFormatException), "Invalid URI:")]
157157
[InlineData("invalid-uri-format", typeof(UriFormatException), "Invalid URI:")]

0 commit comments

Comments
 (0)