add hermes agent provider

This commit is contained in:
2026-05-04 21:52:39 -07:00
parent 195e157e1a
commit 8b580fd3e1
27 changed files with 359 additions and 83 deletions

View File

@@ -4,12 +4,14 @@ public enum Provider: String, Codable, CaseIterable, Hashable, Sendable {
case openai
case anthropic
case xai
case hermesAgent = "hermes-agent"
public var displayName: String {
switch self {
case .openai: return "OpenAI"
case .anthropic: return "Anthropic"
case .xai: return "xAI"
case .hermesAgent: return "Hermes Agent"
}
}
}

View File

@@ -11,6 +11,7 @@ final class SybilSettingsStore {
static let preferredOpenAIModel = "sybil.ios.preferredOpenAIModel"
static let preferredAnthropicModel = "sybil.ios.preferredAnthropicModel"
static let preferredXAIModel = "sybil.ios.preferredXAIModel"
static let preferredHermesAgentModel = "sybil.ios.preferredHermesAgentModel"
}
private let defaults: UserDefaults
@@ -35,7 +36,8 @@ final class SybilSettingsStore {
self.preferredModelByProvider = [
.openai: defaults.string(forKey: Keys.preferredOpenAIModel) ?? "gpt-4.1-mini",
.anthropic: defaults.string(forKey: Keys.preferredAnthropicModel) ?? "claude-3-5-sonnet-latest",
.xai: defaults.string(forKey: Keys.preferredXAIModel) ?? "grok-3-mini"
.xai: defaults.string(forKey: Keys.preferredXAIModel) ?? "grok-3-mini",
.hermesAgent: defaults.string(forKey: Keys.preferredHermesAgentModel) ?? "hermes-agent"
]
}
@@ -53,6 +55,7 @@ final class SybilSettingsStore {
defaults.set(preferredModelByProvider[.openai], forKey: Keys.preferredOpenAIModel)
defaults.set(preferredModelByProvider[.anthropic], forKey: Keys.preferredAnthropicModel)
defaults.set(preferredModelByProvider[.xai], forKey: Keys.preferredXAIModel)
defaults.set(preferredModelByProvider[.hermesAgent], forKey: Keys.preferredHermesAgentModel)
}
var trimmedTokenOrNil: String? {

View File

@@ -141,7 +141,8 @@ final class SybilViewModel {
private let fallbackModels: [Provider: [String]] = [
.openai: ["gpt-4.1-mini"],
.anthropic: ["claude-3-5-sonnet-latest"],
.xai: ["grok-3-mini"]
.xai: ["grok-3-mini"],
.hermesAgent: ["hermes-agent"]
]
init(
@@ -160,6 +161,12 @@ final class SybilViewModel {
modelOptions(for: provider)
}
var providerOptions: [Provider] {
Provider.allCases.filter { candidate in
candidate != .hermesAgent || modelCatalog[candidate] != nil
}
}
func modelOptions(for candidate: Provider) -> [String] {
let serverModels = modelCatalog[candidate]?.models ?? []
if !serverModels.isEmpty {
@@ -893,6 +900,11 @@ final class SybilViewModel {
}
private func syncModelSelectionWithServerCatalog() {
if !providerOptions.contains(provider), let firstProvider = providerOptions.first {
provider = firstProvider
settings.preferredProvider = firstProvider
}
if !providerModelOptions.contains(model), let first = providerModelOptions.first {
model = first
settings.preferredModelByProvider[provider] = first

View File

@@ -495,7 +495,7 @@ struct SybilWorkspaceView: View {
Divider()
ForEach(Provider.allCases, id: \.self) { candidate in
ForEach(viewModel.providerOptions, id: \.self) { candidate in
Menu(candidate.displayName) {
let models = viewModel.modelOptions(for: candidate)
if models.isEmpty {