Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions .azure/container-group.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,7 @@ properties:
secureValue: ${RELEASE_HISTORY_TOKEN}
- name: APPLICATIONINSIGHTS_CONNECTION_STRING
value: ${APPINSIGHTS_CONN_STR}
- name: ConnectionStrings__bottomlymodel
secureValue: "Endpoint=http://localhost:11434;Key=${OLLAMA_API_KEY}"
- name: ollama
properties:
image: ollama/ollama:latest
resources:
requests:
cpu: 0.5
memoryInGB: 0.5
environmentVariables:
- name: OLLAMA_API_KEY
- name: bottomly_ollama_api_key
secureValue: ${OLLAMA_API_KEY}
imageRegistryCredentials:
- server: ghcr.io
Expand Down
11 changes: 0 additions & 11 deletions Bottomly.AppHost/AppHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,8 @@

var mongodb = mongo.AddDatabase("mongodb", "bottomly");

// var ollama = builder.AddOllama("ollama")
// .WithEnvironment("OLLAMA_API_KEY", builder.Configuration["AppHost:OllamaApiKey"])
// .WithDataVolume()
// .WithLifetime(ContainerLifetime.Persistent);

var ollama = builder.AddOllamaLocal("ollama");

var bottomlyModel = ollama.AddModel("bottomlymodel", "qwen3.5:cloud");

var bottomly = builder.AddProject<Bottomly>("bottomly")
.WaitFor(mongodb)
.WaitFor(ollama)
.WithReference(bottomlyModel)
.WithReference(mongodb)
;

Expand Down
2 changes: 0 additions & 2 deletions Bottomly.AppHost/Bottomly.AppHost.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
<PackageReference Include="Aspire.Hosting" Version="13.3.0-preview.1.26156.8"/>
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.3.0-preview.1.26156.8"/>
<PackageReference Include="Aspire.Hosting.MongoDB" Version="13.3.0-preview.1.26156.8"/>
<PackageReference Include="CommunityToolkit.Aspire.Hosting.Ollama" Version="13.2.1-beta.528"/>
<PackageReference Include="OllamaSharp" Version="5.4.23"/>
</ItemGroup>

</Project>
3 changes: 1 addition & 2 deletions Bottomly/Configuration/BottomlyOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ public class BottomlyOptions
public string GiphyApiKey { get; set; } = string.Empty;
public string Environment { get; set; } = "live";
public string GitHubToken { get; set; } = string.Empty;
public bool EnableLlm { get; set; } = false;

public bool IsDebug => Environment != "live";
public string BraveApiKey { get; set; } = string.Empty;
public string OllamaApiKey { get; set; } = string.Empty;
}
20 changes: 10 additions & 10 deletions Bottomly/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Bottomly.Slack;
using Bottomly.Slack.MembershipEventHandlers;
using Bottomly.Slack.MessageEventHandlers;
using Bottomly.Slack.MessageEventHandlers.ConversationMessageHandling;
using Bottomly.Slack.ReactionHandlers;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -47,7 +46,7 @@
opts.Environment = builder.Configuration["bottomly_env"] ?? "live";
opts.GitHubToken = builder.Configuration["bottomly_github_token"] ?? string.Empty;
opts.BraveApiKey = builder.Configuration["bottomly_brave_api_key"] ?? string.Empty;
opts.EnableLlm = builder.Configuration.GetValue<bool>("EnableLlm");
opts.OllamaApiKey = builder.Configuration["bottomly_ollama_api_key"] ?? string.Empty;
});

var opts = builder.Services.BuildServiceProvider().GetRequiredService<IOptions<BottomlyOptions>>();
Expand Down Expand Up @@ -104,13 +103,18 @@
builder.Services.AddHostedService(sp => sp.GetRequiredService<SlackWorker>());

// LLM Support
builder.AddOllamaApiClient("bottomlymodel")
builder.AddOllamaApiClient("bottomlymodel", x =>
{
x.Endpoint = new Uri("https://ollama.com");
x.SelectedModel = "qwen3.5:cloud";
})
.AddChatClient();

// The built-in resilience settings are super aggressive, with a 10s timeout.
// Running locally Qwen3 takes ~2m to respond to simple queries, so we need to override the defaults.
#pragma warning disable EXTEXP0001
builder.Services.AddHttpClient("bottomlymodel_httpClient")
.ConfigureHttpClient(c => c.DefaultRequestHeaders.Add("Authorization", $"Bearer {opts.Value.OllamaApiKey}"))
.RemoveAllResilienceHandlers()
#pragma warning restore EXTEXP0001
.AddStandardResilienceHandler(options =>
Expand All @@ -129,7 +133,7 @@
var app = builder.Build();

var featureFlagRepository = app.Services.GetRequiredService<IFeatureFlagRepository>();
await featureFlagRepository.SeedAsync("EnableLlm", opts.Value.EnableLlm);
await featureFlagRepository.SeedAsync("EnableLlm", false);

var populator = app.Services.GetRequiredService<MemberlistPopulator>();
await populator.PopulateMembers();
Expand All @@ -147,23 +151,19 @@ public static class HostBuilderExtensions
{
extension(HostApplicationBuilder builder)
{
public void RegisterEventHandlers(Assembly assembly, Type[] exclude)
{
public void RegisterEventHandlers(Assembly assembly, Type[] exclude) =>
assembly.GetTypes()
.Where(t => typeof(IMessageEventHandler).IsAssignableFrom(t) &&
t is { IsInterface: false, IsAbstract: false })
.Where(t => t.Name != nameof(HelpHandler))
.Where(t => !exclude.Contains(t))
.ToList()
.ForEach(t => builder.Services.AddSingleton(typeof(IMessageEventHandler), t));
}

public void RegisterCommands(Assembly assembly)
{
public void RegisterCommands(Assembly assembly) =>
assembly.GetTypes()
.Where(t => typeof(ICommand).IsAssignableFrom(t) && t is { IsInterface: false, IsAbstract: false })
.ToList()
.ForEach(t => builder.Services.AddSingleton(t));
}
}
}
Loading