Skip to content

Commit

Permalink
Merge pull request #26 from CommunityToolkit/ollama
Browse files Browse the repository at this point in the history
Ollama
  • Loading branch information
aaronpowell authored Sep 24, 2024
2 parents 0176bc0 + 7380e01 commit 91da0ec
Show file tree
Hide file tree
Showing 40 changed files with 1,248 additions and 1 deletion.
38 changes: 38 additions & 0 deletions CommunityToolkit.Aspire.sln
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hos
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.NodeJS.Extensions.Tests", "tests\CommunityToolkit.Aspire.Hosting.NodeJS.Extensions.Tests\CommunityToolkit.Aspire.Hosting.NodeJS.Extensions.Tests.csproj", "{E8F93376-1367-4A7B-A729-116199804356}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.Ollama", "src\CommunityToolkit.Aspire.Hosting.Ollama\CommunityToolkit.Aspire.Hosting.Ollama.csproj", "{6C6696CB-8DCC-4E93-A667-A313D70E0220}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.Ollama.Tests", "tests\CommunityToolkit.Aspire.Hosting.Ollama.Tests\CommunityToolkit.Aspire.Hosting.Ollama.Tests.csproj", "{1DB27FA0-E7E4-42C1-B062-4DE0128D4FA1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ollama", "ollama", "{14BD8AE7-C8DF-4C7C-8244-7F74C101569D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.Ollama.AppHost", "examples\ollama\CommunityToolkit.Aspire.Hosting.Ollama.AppHost\CommunityToolkit.Aspire.Hosting.Ollama.AppHost.csproj", "{F4602DC8-3C17-4834-B640-9A3B27FE278A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.Ollama.ServiceDefaults", "examples\ollama\CommunityToolkit.Aspire.Hosting.Ollama.ServiceDefaults\CommunityToolkit.Aspire.Hosting.Ollama.ServiceDefaults.csproj", "{2F037600-2002-4A13-9359-98FB0D2416BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.Ollama.Web", "examples\ollama\CommunityToolkit.Aspire.Hosting.Ollama.Web\CommunityToolkit.Aspire.Hosting.Ollama.Web.csproj", "{0A17021E-5F10-429B-88C8-E4073EADACB6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -111,6 +123,26 @@ Global
{E8F93376-1367-4A7B-A729-116199804356}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8F93376-1367-4A7B-A729-116199804356}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8F93376-1367-4A7B-A729-116199804356}.Release|Any CPU.Build.0 = Release|Any CPU
{6C6696CB-8DCC-4E93-A667-A313D70E0220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C6696CB-8DCC-4E93-A667-A313D70E0220}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C6696CB-8DCC-4E93-A667-A313D70E0220}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C6696CB-8DCC-4E93-A667-A313D70E0220}.Release|Any CPU.Build.0 = Release|Any CPU
{1DB27FA0-E7E4-42C1-B062-4DE0128D4FA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1DB27FA0-E7E4-42C1-B062-4DE0128D4FA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DB27FA0-E7E4-42C1-B062-4DE0128D4FA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DB27FA0-E7E4-42C1-B062-4DE0128D4FA1}.Release|Any CPU.Build.0 = Release|Any CPU
{F4602DC8-3C17-4834-B640-9A3B27FE278A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F4602DC8-3C17-4834-B640-9A3B27FE278A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F4602DC8-3C17-4834-B640-9A3B27FE278A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F4602DC8-3C17-4834-B640-9A3B27FE278A}.Release|Any CPU.Build.0 = Release|Any CPU
{2F037600-2002-4A13-9359-98FB0D2416BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F037600-2002-4A13-9359-98FB0D2416BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F037600-2002-4A13-9359-98FB0D2416BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F037600-2002-4A13-9359-98FB0D2416BE}.Release|Any CPU.Build.0 = Release|Any CPU
{0A17021E-5F10-429B-88C8-E4073EADACB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A17021E-5F10-429B-88C8-E4073EADACB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A17021E-5F10-429B-88C8-E4073EADACB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A17021E-5F10-429B-88C8-E4073EADACB6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -134,6 +166,12 @@ Global
{261AC321-8982-4C3A-8DBF-DAFC95F97697} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
{D3F5EF2B-CE37-4339-A8BD-50E6C5B2AFA1} = {261AC321-8982-4C3A-8DBF-DAFC95F97697}
{E8F93376-1367-4A7B-A729-116199804356} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{6C6696CB-8DCC-4E93-A667-A313D70E0220} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
{1DB27FA0-E7E4-42C1-B062-4DE0128D4FA1} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{14BD8AE7-C8DF-4C7C-8244-7F74C101569D} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
{F4602DC8-3C17-4834-B640-9A3B27FE278A} = {14BD8AE7-C8DF-4C7C-8244-7F74C101569D}
{2F037600-2002-4A13-9359-98FB0D2416BE} = {14BD8AE7-C8DF-4C7C-8244-7F74C101569D}
{0A17021E-5F10-429B-88C8-E4073EADACB6} = {14BD8AE7-C8DF-4C7C-8244-7F74C101569D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {08B1D4B8-D2C5-4A64-BB8B-E1A2B29525F0}
Expand Down
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,7 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageVersion Include="xunit" Version="2.9.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<!-- External packages -->
<PackageVersion Include="OllamaSharp" Version="3.0.7" />
</ItemGroup>
</Project>
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This repository contains the source code for the .NET Aspire Community Toolkit,
| [`Hosting.Azure.StaticWebApps`][swa-integration-docs] | [![CommunityToolkit.Aspire.Hosting.Azure.StaticWebApps][swa-shields]][swa-nuget] | [![CommunityToolkit.Aspire.Hosting.Azure.StaticWebApps][swa-shields-preview]][swa-nuget-preview] | A hosting integration for the [Azure Static Web Apps emulator](https://learn.microsoft.com/azure/static-web-apps/static-web-apps-cli-overview) (Note: this does not support deployment of a project to Azure Static Web Apps). |
| [`Hosting.Java`][java-integration-docs] | [![CommunityToolkit.Aspire.Hosting.Java][java-shields]][java-nuget] | [![CommunityToolkit.Aspire.Hosting.Java][java-shields-preview]][java-nuget-preview] | A integration for running Java code in .NET Aspire either using the local JDK or using a container. |
| [`Hosting.NodeJS.Extensions`][nodejs-ext-integration-docs] | [![CommunityToolkit.Aspire.NodeJS.Extensions][nodejs-ext-shields]][nodejs-ext-nuget] | [![CommunityToolkit.Aspire.Hosting.NodeJS.Extensions][nodejs-ext-shields-preview]][nodejs-ext-nuget-preview] | An integration that contains some additional extensions for running Node.js applications |
| [`Hosting.Ollama`][ollama-integration-docs] | [![CommunityToolkit.Aspire.Ollama][ollama-shields]][ollama-nuget] | [![CommunityToolkit.Aspire.Hosting.Ollama][ollama-shields-preview]][ollama-nuget-preview] | An Aspire component leveraging the [Ollama](https://ollama.com) container with support for downloading a model on startup. |

## 🙌 Getting Started

Expand Down Expand Up @@ -51,4 +52,8 @@ Made with [contrib.rocks](https://contrib.rocks).
[nodejs-ext-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.NodeJS.Extensions/
[nodejs-ext-shields-preview]: https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Hosting.NodeJS.Extensions?label=nuget%20(preview)
[nodejs-ext-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.NodeJS.Extensions/absoluteLatest

[ollama-integration-docs]: https://communitytoolkit.github.io/aspire/integrations/hosting-ollama
[ollama-shields]: https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Hosting.Ollama
[ollama-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.Ollama/
[ollama-shields-preview]: https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Hosting.Ollama?label=nuget%20(preview)
[ollama-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.Ollama/absoluteLatest
1 change: 1 addition & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Each integration is a separate NuGet package that you can add to your project. A
- [CommunityToolkit.Aspire.Hosting.Azure.StaticWebApps](integrations/hosting-azure-static-web-apps.md)
- [CommunityToolkit.Aspire.Hosting.Java](integrations/hosting-java.md)
- [CommunityToolkit.Aspire.Hosting.NodeJS.Extensions](integrations/hosting-nodejs-extensions.md)
- [CommunityToolkit.Aspire.Hosting.Ollama](integrations/hosting-ollama.md)
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The Community Toolkit consists of a collection of NuGet packages that can be add
- [CommunityToolkit.Aspire.Hosting.Azure.StaticWebApps](integrations/hosting-azure-static-web-apps.md)
- [CommunityToolkit.Aspire.Hosting.Java](integrations/hosting-java.md)
- [CommunityToolkit.Aspire.Hosting.NodeJS.Extensions](integrations/hosting-nodejs-extensions.md)
- [CommunityToolkit.Aspire.Hosting.Ollama](integrations/hosting-ollama.md)

## .NET Aspire and the Community Toolkit

Expand Down
51 changes: 51 additions & 0 deletions docs/integrations/hosting-ollama.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# CommunityToolkit.Aspire.Hosting.Ollama

[![CommunityToolkit.Aspire.Ollama](https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Ollama)](https://nuget.org/packages/CommunityToolkit.Aspire.Ollama/) | [![CommunityToolkit.Aspire.Ollama (latest)](<https://img.shields.io/nuget/vpre/CommunityToolkit.Aspire.Ollama?label=nuget%20(preview)>)](https://nuget.org/packages/CommunityToolkit.Aspire.Ollama/absoluteLatest)

## Overview

An Aspire component leveraging the [Ollama](https://ollama.com) container with support for downloading a model on startup.

## Usage

Use the static `AddOllama` method to add this container component to the application builder.

```csharp
// The distributed application builder is created here
var ollama = builder.AddOllama("ollama");

// The builder is used to build and run the app somewhere down here
```

### Configuration

The AddOllama method has optional arguments to set the `name`, `port` and `modelName`.
The `name` is what gets displayed in the Aspire orchestration app against this component.
The `port` is provided randomly by Aspire. If for whatever reason you need a fixed port, you can set that here.
The `modelName` specifies what LLM to pull when it starts up. The default is `llama3`. You can also set this to null to prevent any models being pulled on startup - leaving you with a plain Ollama container to work with.

## Downloading the LLM

When the Ollama container for this component first spins up, this component will download the LLM (llama3 unless otherwise specified).
The progress of this download will be displayed in the State column for this component on the Aspire orchestration app.
Important: Keep the Aspire orchestration app open until the download is complete, otherwise the download will be cancelled.
In the spirit of productivity, we recommend kicking off this process before heading for lunch.
This component binds a volume called "ollama" so that once the model is fully downloaded, it'll be available for subsequent runs.

## Accessing the Ollama server from other Aspire components

You can pass the ollama component to other Aspire components in the usual way:

```csharp
builder.AddMyComponent().WithReference(ollama);
```

Within that component (e.g. a web app), you can fetch the Ollama connection string from the application builder as follows.
Note that if you changed the name of the Ollama component via the `name` argument, then you'll need to use that here when specifying which connection string to get.

```csharp
var connectionString = builder.Configuration.GetConnectionString("Ollama");
```

You can then call any of the Ollama endpoints through this connection string. We recommend using the [OllamaSharp](https://www.nuget.org/packages/OllamaSharp) client to do this.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>f39fb70f-21f3-4af9-89b4-3062ff4431e6</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Aspire.Hosting.Ollama.Web\CommunityToolkit.Aspire.Hosting.Ollama.Web.csproj" />
<ProjectReference Include="..\..\..\src\CommunityToolkit.Aspire.Hosting.Ollama\CommunityToolkit.Aspire.Hosting.Ollama.csproj" IsAspireProjectResource="false" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
var builder = DistributedApplication.CreateBuilder(args);

var ollama = builder.AddOllama("ollama", modelName: "phi3");

builder.AddProject<Projects.CommunityToolkit_Aspire_Hosting_Ollama_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(ollama)
.WithEnvironment("ollama:model", "phi3");

builder.Build().Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:17117;http://localhost:15077",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21075",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22200"
}
},
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15077",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19024",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20271"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireSharedProject>true</IsAspireSharedProject>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;

namespace Microsoft.Extensions.Hosting;

// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
// This project should be referenced by each service project in your solution.
// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
public static class Extensions
{
public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder)
{
builder.ConfigureOpenTelemetry();

builder.AddDefaultHealthChecks();

builder.Services.AddServiceDiscovery();

builder.Services.ConfigureHttpClientDefaults(http =>
{
// Turn on resilience by default
http.AddStandardResilienceHandler();

// Turn on service discovery by default
http.AddServiceDiscovery();
});

return builder;
}

public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder)
{
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});

builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
.WithTracing(tracing =>
{
tracing.AddAspNetCoreInstrumentation()
// Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
//.AddGrpcClientInstrumentation()
.AddHttpClientInstrumentation();
});

builder.AddOpenTelemetryExporters();

return builder;
}

private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder)
{
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);

if (useOtlpExporter)
{
builder.Services.AddOpenTelemetry().UseOtlpExporter();
}

// Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
//if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
//{
// builder.Services.AddOpenTelemetry()
// .UseAzureMonitor();
//}

return builder;
}

public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder)
{
builder.Services.AddHealthChecks()
// Add a default liveness check to ensure app is responsive
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);

return builder;
}

public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
// Adding health checks endpoints to applications in non-development environments has security implications.
// See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.
if (app.Environment.IsDevelopment())
{
// All health checks must pass for app to be considered ready to accept traffic after starting
app.MapHealthChecks("/health");

// Only health checks tagged with the "live" tag must pass for app to be considered alive
app.MapHealthChecks("/alive", new HealthCheckOptions
{
Predicate = r => r.Tags.Contains("live")
});
}

return app;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Aspire.Hosting.Ollama.ServiceDefaults\CommunityToolkit.Aspire.Hosting.Ollama.ServiceDefaults.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="OllamaSharp" />
</ItemGroup>

</Project>
Loading

0 comments on commit 91da0ec

Please sign in to comment.