diff --git a/Agent/AgentViewModel/Core/AgentViewModel.swift b/Agent/AgentViewModel/Core/AgentViewModel.swift index 02181950..fce7eb3f 100644 --- a/Agent/AgentViewModel/Core/AgentViewModel.swift +++ b/Agent/AgentViewModel/Core/AgentViewModel.swift @@ -431,6 +431,19 @@ final class AgentViewModel { didSet { UserDefaults.standard.set(openRouterProtocol.rawValue, forKey: "openRouterProtocol") } } + // MARK: - Requesty + + var requestyAPIKey: String = KeychainService.shared.get(.requesty) ?? "" { + didSet { KeychainService.shared.set(.requesty, requestyAPIKey) } + } + + var requestyModel: String = UserDefaults.standard.string(forKey: "requestyModel") ?? "" { + didSet { UserDefaults.standard.set(requestyModel, forKey: "requestyModel") } + } + + var requestyModels: [OpenAIModelInfo] = [] + var isFetchingRequestyModels = false + // MARK: - Google Gemini var geminiAPIKey: String = KeychainService.shared.get(.gemini) ?? "" { diff --git a/Agent/AgentViewModel/Core/Colors.swift b/Agent/AgentViewModel/Core/Colors.swift index 06bd15d9..6f461305 100644 --- a/Agent/AgentViewModel/Core/Colors.swift +++ b/Agent/AgentViewModel/Core/Colors.swift @@ -121,6 +121,7 @@ extension AgentViewModel { case .bigModel: return zAITemperature case .miniMax: return miniMaxTemperature case .openRouter: return openAITemperature + case .requesty: return openAITemperature case .qwen: return openAITemperature case .gemini: return geminiTemperature case .grok: return grokTemperature diff --git a/Agent/AgentViewModel/Features/ModelFetching.swift b/Agent/AgentViewModel/Features/ModelFetching.swift index e026c118..b29bc567 100644 --- a/Agent/AgentViewModel/Features/ModelFetching.swift +++ b/Agent/AgentViewModel/Features/ModelFetching.swift @@ -290,6 +290,54 @@ extension AgentViewModel { return filtered.sorted { $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending } } + func fetchRequestyModels() { + isFetchingRequestyModels = true + Task { + defer { isFetchingRequestyModels = false } + do { + let models = try await Self.fetchRequestyCatalog(apiKey: requestyAPIKey) + requestyModels = models + let ids = models.map(\.id) + if requestyModel.isEmpty || (!ids.isEmpty && !ids.contains(requestyModel)) { + requestyModel = ids.first ?? "" + } + } catch { + appendLog("Failed to fetch Requesty models: \(error.localizedDescription)") + requestyModels = [] + } + } + } + + /// Fetch Requesty's /models catalog and keep only entries Agent! can actually drive: + /// nonzero context_window AND supports_tool_calling. Requesty ids are already + /// `provider/model` (e.g. openai/gpt-4o-mini), so the id doubles as the display name. + private nonisolated static func fetchRequestyCatalog(apiKey: String) async throws -> [OpenAIModelInfo] { + guard let url = URL(string: "https://router.requesty.ai/v1/models") else { throw AgentError.invalidURL } + var request = URLRequest(url: url) + request.httpMethod = "GET" + if !apiKey.isEmpty { + request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization") + } + request.timeoutInterval = llmAPITimeout + + let (data, response) = try await URLSession.shared.data(for: request) + guard let http = response as? HTTPURLResponse, http.statusCode == 200 else { + throw AgentError.apiError(statusCode: (response as? HTTPURLResponse)?.statusCode ?? 0, message: "Requesty /models error") + } + guard let json = try JSONSerialization.jsonObject(with: data) as? [String: Any], + let entries = json["data"] as? [[String: Any]] else { return [] } + + let filtered = entries.compactMap { entry -> OpenAIModelInfo? in + guard let id = entry["id"] as? String, !id.isEmpty else { return nil } + let ctx = entry["context_window"] as? Int ?? 0 + guard ctx > 0 else { return nil } + // Agent!'s loop is tool-driven, so skip models that cannot call tools. + guard entry["supports_tool_calling"] as? Bool == true else { return nil } + return OpenAIModelInfo(id: id, name: id) + } + return filtered.sorted { $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending } + } + func fetchHuggingFaceModels() { guard !huggingFaceAPIKey.isEmpty else { huggingFaceModels = Self.defaultHuggingFaceModels @@ -917,6 +965,7 @@ extension AgentViewModel { case .vibe: if force || vibeModels.isEmpty { fetchVibeModels() } case .miniMax: if force || miniMaxModels.isEmpty { fetchMiniMaxModels() } case .openRouter: if force || openRouterModels.isEmpty { fetchOpenRouterModels() } + case .requesty: if force || requestyModels.isEmpty { fetchRequestyModels() } case .bigModel: break default: break } diff --git a/Agent/AgentViewModel/Features/ScriptTabs.swift b/Agent/AgentViewModel/Features/ScriptTabs.swift index bed84e15..07102715 100644 --- a/Agent/AgentViewModel/Features/ScriptTabs.swift +++ b/Agent/AgentViewModel/Features/ScriptTabs.swift @@ -75,6 +75,7 @@ extension AgentViewModel { case .bigModel: return bigModelModel.replacingOccurrences(of: ":v", with: "") case .miniMax: return miniMaxModel case .openRouter: return openRouterModel + case .requesty: return requestyModel case .qwen: return qwenModel case .gemini: return geminiModel case .grok: return grokModel @@ -100,6 +101,7 @@ extension AgentViewModel { case .bigModel: return bigModelAPIKey case .miniMax: return miniMaxAPIKey case .openRouter: return openRouterAPIKey + case .requesty: return requestyAPIKey case .qwen: return qwenAPIKey case .gemini: return geminiAPIKey case .grok: return grokAPIKey @@ -152,6 +154,8 @@ extension AgentViewModel { ?? Self.defaultMiniMaxModels.first(where: { $0.id == modelId })?.name ?? modelId case .openRouter: return openRouterModels.first(where: { $0.id == modelId })?.name ?? modelId + case .requesty: + return requestyModels.first(where: { $0.id == modelId })?.name ?? modelId case .qwen: return modelId case .gemini: diff --git a/Agent/AgentViewModel/Messages/Compression.swift b/Agent/AgentViewModel/Messages/Compression.swift index f2824339..00840a8a 100644 --- a/Agent/AgentViewModel/Messages/Compression.swift +++ b/Agent/AgentViewModel/Messages/Compression.swift @@ -126,6 +126,7 @@ extension AgentViewModel { case .bigModel: return 128_000 case .miniMax: return 1_000_000 case .openRouter: return 200_000 + case .requesty: return 200_000 case .qwen: return 131_072 case .mistral: return 256_000 case .vibe: return 128_000 diff --git a/Agent/AgentViewModel/TaskExecution/Setup.swift b/Agent/AgentViewModel/TaskExecution/Setup.swift index c2d89f48..a205a687 100644 --- a/Agent/AgentViewModel/TaskExecution/Setup.swift +++ b/Agent/AgentViewModel/TaskExecution/Setup.swift @@ -95,6 +95,9 @@ extension AgentViewModel { case .openRouter: modelName = openRouterModel isVision = Self.isVisionModel(openRouterModel) + case .requesty: + modelName = requestyModel + isVision = Self.isVisionModel(requestyModel) case .qwen: modelName = qwenModel isVision = Self.isVisionModel(qwenModel) diff --git a/Agent/Services/KeychainService.swift b/Agent/Services/KeychainService.swift index 2931dbc0..92beb9be 100644 --- a/Agent/Services/KeychainService.swift +++ b/Agent/Services/KeychainService.swift @@ -28,6 +28,7 @@ final class KeychainService: Sendable { case qwen = "com.agent.qwen-api-key" case miniMax = "com.agent.minimax-api-key" case openRouter = "com.agent.openrouter-api-key" + case requesty = "com.agent.requesty-api-key" case exa = "com.agent.exa-api-key" case lmStudio = "com.agent.lmstudio-api-key" } diff --git a/Agent/Services/LLMProviderSetup.swift b/Agent/Services/LLMProviderSetup.swift index 34c75981..4e3622b6 100644 --- a/Agent/Services/LLMProviderSetup.swift +++ b/Agent/Services/LLMProviderSetup.swift @@ -9,7 +9,7 @@ enum LLMProviderSetup { static func registerAllProviders() { LLMRegistry.shared.registerAll([ claude, codex, openAI, gemini, grok, mistral, vibe, deepSeek, huggingFace, miniMax, zAI, bigModel, qwen, openRouter, - ollama, localOllama, vLLM, lmStudio, appleIntelligence + requesty, ollama, localOllama, vLLM, lmStudio, appleIntelligence ]) } @@ -83,6 +83,16 @@ enum LLMProviderSetup { capabilities: [.streaming, .tools, .vision, .systemPrompt] ) + static let requesty = LLMProviderConfig( + id: "requesty", displayName: "Requesty", + kind: .cloudAPI, apiProtocol: .openAI, + endpoint: LLMEndpoint( + chatURL: "https://router.requesty.ai/v1/chat/completions", + modelsURL: "https://router.requesty.ai/v1/models" + ), + capabilities: [.streaming, .tools, .vision, .systemPrompt] + ) + static let miniMax = LLMProviderConfig( id: "miniMax", displayName: "MiniMax", kind: .cloudAPI, apiProtocol: .openAI, diff --git a/Agent/Views/Settings/FallbackChainView.swift b/Agent/Views/Settings/FallbackChainView.swift index e06a9f4f..206c040c 100644 --- a/Agent/Views/Settings/FallbackChainView.swift +++ b/Agent/Views/Settings/FallbackChainView.swift @@ -213,6 +213,7 @@ struct FallbackChainView: View { case .grok: return oai(viewModel.grokModels) case .mistral: return oai(viewModel.mistralModels) case .openRouter: return oai(viewModel.openRouterModels) + case .requesty: return oai(viewModel.requestyModels) default: return [] } } @@ -253,6 +254,7 @@ struct FallbackChainView: View { case .bigModel: if !viewModel.bigModelModel.isEmpty { return viewModel.bigModelModel } case .miniMax: if !viewModel.miniMaxModel.isEmpty { return viewModel.miniMaxModel } case .openRouter: if !viewModel.openRouterModel.isEmpty { return viewModel.openRouterModel } + case .requesty: if !viewModel.requestyModel.isEmpty { return viewModel.requestyModel } case .foundationModel: return "Apple Intelligence" } // Fall back to the first dynamically-fetched model for this provider diff --git a/Agent/Views/Settings/SettingsView.swift b/Agent/Views/Settings/SettingsView.swift index 97b67c3c..a6f5bc88 100644 --- a/Agent/Views/Settings/SettingsView.swift +++ b/Agent/Views/Settings/SettingsView.swift @@ -20,6 +20,7 @@ struct SettingsView: View { case .bigModel: return $viewModel.zAITemperature case .miniMax: return $viewModel.miniMaxTemperature case .openRouter: return $viewModel.openAITemperature + case .requesty: return $viewModel.openAITemperature case .qwen: return $viewModel.openAITemperature case .gemini: return $viewModel.geminiTemperature case .grok: return $viewModel.grokTemperature @@ -401,6 +402,48 @@ struct SettingsView: View { } } } + } else if viewModel.selectedProvider == .requesty { + VStack(alignment: .leading, spacing: 10) { + Text("Requesty") + .font(.headline) + + VStack(alignment: .leading, spacing: 4) { + Text("API Key").font(.caption).foregroundStyle(.secondary) + LockedSecureField(text: $viewModel.requestyAPIKey, placeholder: "Requesty API key", lockKey: "lock.requestyAPIKey") + } + + VStack(alignment: .leading, spacing: 4) { + Text("Model").font(.caption).foregroundStyle(.secondary) + HStack { + if viewModel.requestyModels.isEmpty { + TextField("e.g. anthropic/claude-sonnet-4-5", text: $viewModel.requestyModel) + .textFieldStyle(.roundedBorder) + } else { + Picker("Model", selection: $viewModel.requestyModel) { + ForEach(viewModel.requestyModels) { model in + Text(model.name).tag(model.id) + } + } + .labelsHidden() + } + + Button { + viewModel.fetchRequestyModels() + } label: { + if viewModel.isFetchingRequestyModels { + ProgressView() + .controlSize(.small) + } else { + Image(systemName: "arrow.clockwise") + } + } + .buttonStyle(.bordered) + .controlSize(.small) + .disabled(viewModel.isFetchingRequestyModels) + .help("Fetch available models") + } + } + } } else if viewModel.selectedProvider == .qwen { VStack(alignment: .leading, spacing: 10) { Text("Qwen (DashScope)") diff --git a/Agent/Views/Tabs/NewMainTabSheet.swift b/Agent/Views/Tabs/NewMainTabSheet.swift index dddce63a..883b7e58 100644 --- a/Agent/Views/Tabs/NewMainTabSheet.swift +++ b/Agent/Views/Tabs/NewMainTabSheet.swift @@ -167,6 +167,14 @@ struct NewMainTabSheet: View { fetch: { viewModel.fetchModelsIfNeeded(for: .openRouter, force: true) } ) + case .requesty: + modelPickerWithFetch( + models: viewModel.requestyModels, + fallbackBinding: $selectedModelId, + isFetching: viewModel.isFetchingRequestyModels, + fetch: { viewModel.fetchModelsIfNeeded(for: .requesty, force: true) } + ) + case .qwen: TextField("Model (e.g. qwen-plus)", text: $selectedModelId) .textFieldStyle(.roundedBorder) @@ -309,6 +317,7 @@ struct NewMainTabSheet: View { case .bigModel: return "glm-4.7" case .miniMax: return viewModel.miniMaxModel.isEmpty ? "MiniMax-M3" : viewModel.miniMaxModel case .openRouter: return viewModel.openRouterModel + case .requesty: return viewModel.requestyModel case .qwen: return "qwen-plus" case .gemini: return viewModel.geminiModel case .grok: return viewModel.grokModel diff --git a/Agent/Views/Tools/ToolsView.swift b/Agent/Views/Tools/ToolsView.swift index 1e3398c6..1c589adb 100644 --- a/Agent/Views/Tools/ToolsView.swift +++ b/Agent/Views/Tools/ToolsView.swift @@ -152,6 +152,7 @@ struct ToolsView: View { case .vibe: return $viewModel.vibeModel case .miniMax: return $viewModel.miniMaxModel case .openRouter: return $viewModel.openRouterModel + case .requesty: return $viewModel.requestyModel case .foundationModel: return .constant("Apple Intelligence") } } @@ -189,6 +190,7 @@ struct ToolsView: View { case .lmStudio: return viewModel.lmStudioModels.map { ($0.id, $0.name) } case .miniMax: return oai(viewModel.miniMaxModels, AgentViewModel.defaultMiniMaxModels) case .openRouter: return viewModel.openRouterModels.map { ($0.id, $0.name) } + case .requesty: return viewModel.requestyModels.map { ($0.id, $0.name) } case .bigModel: return [] case .foundationModel: return [("Apple Intelligence", "Apple Intelligence")] diff --git a/README.md b/README.md index f53e9720..08797f1f 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ **One app. Any AI. Total command over your Mac.** -Agent! is a 100% native Swift 6.2 / SwiftUI app that wires **18 LLM providers** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Ollama (cloud and local), vLLM, and LM Studio — plus on-device **Apple Intelligence** — into an autonomous task loop that actually *does things*: reads your codebase, fixes the bug, builds the Xcode project, commits the diff, drives any Mac app through the Accessibility API, runs shell commands as you or as root, texts you results over iMessage, and answers to a spoken *"Agent!"*. +Agent! is a 100% native Swift 6.2 / SwiftUI app that wires **19 LLM providers** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Requesty, Ollama (cloud and local), vLLM, and LM Studio — plus on-device **Apple Intelligence** — into an autonomous task loop that actually *does things*: reads your codebase, fixes the bug, builds the Xcode project, commits the diff, drives any Mac app through the Accessibility API, runs shell commands as you or as root, texts you results over iMessage, and answers to a spoken *"Agent!"*. No NPM, no Electron, no subscription, no telemetry. Bring your own API key, run fully local, or run free on Apple Intelligence. Every Swift package it depends on was written by the same author. See [Backstory](#backstory) below. @@ -98,7 +98,7 @@ Just type what you want. Agent! figures out how and makes it happen. - **🗂 Tabs, history, memory, plans, skills** — each tab has its own project folder and log; persistent user memory; multi-plan checklists surfaced in every prompt. - **🔄 Fallback chain** — auto-switch to the next configured provider on 429/timeout/network failure. -## 🤖 18 AI Providers +## 🤖 19 AI Providers | Provider | Cost | Best for | |---|---|---| @@ -114,6 +114,7 @@ Just type what you want. Agent! figures out how and makes it happen. | **Qwen** (Alibaba) | Cheap | Qwen 3.8 via Dashscope | | **MiniMax** | Cheap | 1M-token context | | **OpenRouter** | Paid | 200+ models, one key; Claude routed via Anthropic protocol | +| **Requesty** | Paid | 300+ models via one OpenAI-compatible key; per-model pricing and capability metadata | | **Ollama** (cloud) | Free tier | Hosted open models | | **Local Ollama** / **vLLM** / **LM Studio** | Free + hardware | Fully offline; real per-model context window detected | | **Apple Intelligence** | Free, on-device | Triage, summaries, token compression (brain icon, not the provider picker) | diff --git a/README_de.md b/README_de.md index ccf1a076..3de4e97e 100644 --- a/README_de.md +++ b/README_de.md @@ -24,7 +24,7 @@ **Eine App. Jede KI. Volle Kontrolle über deinen Mac.** -Agent! ist eine zu 100 % native Swift-6.2-/SwiftUI-App, die **18 LLM-Anbieter** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Ollama (Cloud und lokal), vLLM und LM Studio — plus die geräteinterne **Apple Intelligence** — mit einer autonomen Aufgabenschleife verbindet, die wirklich *etwas tut*: Sie liest deinen Code, behebt den Fehler, baut das Xcode-Projekt, committet den Diff, steuert jede Mac-App über die Accessibility-API, führt Shell-Befehle als du oder als root aus, schickt dir Ergebnisse per iMessage und reagiert auf ein gesprochenes *„Agent!"*. +Agent! ist eine zu 100 % native Swift-6.2-/SwiftUI-App, die **19 LLM-Anbieter** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Requesty, Ollama (Cloud und lokal), vLLM und LM Studio — plus die geräteinterne **Apple Intelligence** — mit einer autonomen Aufgabenschleife verbindet, die wirklich *etwas tut*: Sie liest deinen Code, behebt den Fehler, baut das Xcode-Projekt, committet den Diff, steuert jede Mac-App über die Accessibility-API, führt Shell-Befehle als du oder als root aus, schickt dir Ergebnisse per iMessage und reagiert auf ein gesprochenes *„Agent!"*. Kein NPM, kein Electron, kein Abo, keine Telemetrie. Bring deinen eigenen API-Schlüssel mit, lauf komplett lokal oder kostenlos mit Apple Intelligence. Jedes Swift-Paket, von dem die App abhängt, wurde vom selben Autor geschrieben. Siehe [Entstehungsgeschichte](#entstehungsgeschichte) unten. @@ -98,7 +98,7 @@ Tipp einfach, was du willst. Agent! findet heraus wie und setzt es um. - **🗂 Tabs, Verlauf, Gedächtnis, Pläne, Skills** — jeder Tab hat eigenen Projektordner und eigenes Log; persistentes Nutzergedächtnis; Multi-Plan-Checklisten in jedem Prompt. - **🔄 Fallback-Kette** — automatischer Wechsel zum nächsten konfigurierten Anbieter bei 429/Timeout/Netzwerkfehler. -## 🤖 18 KI-Anbieter +## 🤖 19 KI-Anbieter | Anbieter | Kosten | Am besten für | |---|---|---| @@ -111,6 +111,7 @@ Tipp einfach, was du willst. Agent! findet heraus wie und setzt es um. | **DeepSeek** | Günstig | Budget-Coding, Cache-Hit-Reporting | | **Hugging Face** | Variabel | Offene Modelle, serverless oder dedizierte Endpunkte | | **OpenRouter** | Kostenpflichtig | 200+ Modelle, ein Schlüssel; Claude über Anthropic-Protokoll | +| **Requesty** | Kostenpflichtig | 300+ Modelle mit einem OpenAI-kompatiblen Schlüssel; Preise und Fähigkeiten pro Modell | | **Z.ai** / **BigModel** | Günstig | GLM-5.3 — empfohlener Einstieg | | **Qwen** (Alibaba) | Günstig | Qwen 3.8 über Dashscope | | **MiniMax** | Günstig | 1M-Token-Kontext | diff --git a/README_es.md b/README_es.md index f72cd187..0f8c99bf 100644 --- a/README_es.md +++ b/README_es.md @@ -24,7 +24,7 @@ **Una app. Cualquier IA. Control total de tu Mac.** -Agent! es una app 100 % nativa en Swift 6.2 / SwiftUI que conecta **18 proveedores de LLM** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Ollama (nube y local), vLLM y LM Studio — más **Apple Intelligence** en el dispositivo — a un bucle de tareas autónomo que realmente *hace cosas*: lee tu código, corrige el bug, compila el proyecto de Xcode, hace commit del diff, controla cualquier app de Mac mediante la API de Accesibilidad, ejecuta comandos de shell como tú o como root, te envía los resultados por iMessage y responde a un *«Agent!»* hablado. +Agent! es una app 100 % nativa en Swift 6.2 / SwiftUI que conecta **19 proveedores de LLM** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Requesty, Ollama (nube y local), vLLM y LM Studio — más **Apple Intelligence** en el dispositivo — a un bucle de tareas autónomo que realmente *hace cosas*: lee tu código, corrige el bug, compila el proyecto de Xcode, hace commit del diff, controla cualquier app de Mac mediante la API de Accesibilidad, ejecuta comandos de shell como tú o como root, te envía los resultados por iMessage y responde a un *«Agent!»* hablado. Sin NPM, sin Electron, sin suscripción, sin telemetría. Trae tu propia clave de API, ejecútalo totalmente en local o gratis con Apple Intelligence. Cada paquete Swift del que depende fue escrito por el mismo autor. Consulta la [Historia](#historia) más abajo. @@ -98,7 +98,7 @@ Solo escribe lo que quieres. Agent! averigua cómo y lo hace realidad. - **🗂 Pestañas, historial, memoria, planes, skills** — cada pestaña tiene su propia carpeta de proyecto y registro; memoria de usuario persistente; listas multi-plan en cada prompt. - **🔄 Cadena de respaldo** — cambio automático al siguiente proveedor configurado ante 429/timeout/fallo de red. -## 🤖 18 proveedores de IA +## 🤖 19 proveedores de IA | Proveedor | Coste | Ideal para | |---|---|---| @@ -111,6 +111,7 @@ Solo escribe lo que quieres. Agent! averigua cómo y lo hace realidad. | **DeepSeek** | Barato | Programación económica, informe de aciertos de caché | | **Hugging Face** | Varía | Modelos abiertos, serverless o endpoints dedicados | | **OpenRouter** | De pago | 200+ modelos, una clave; Claude enrutado por protocolo Anthropic | +| **Requesty** | De pago | 300+ modelos con una sola clave compatible con OpenAI; precios y capacidades por modelo | | **Z.ai** / **BigModel** | Barato | GLM-5.3 — punto de partida recomendado | | **Qwen** (Alibaba) | Barato | Qwen 3.8 vía Dashscope | | **MiniMax** | Barato | Contexto de 1M tokens | diff --git a/README_fr.md b/README_fr.md index 092aa254..2fc3ef30 100644 --- a/README_fr.md +++ b/README_fr.md @@ -24,7 +24,7 @@ **Une app. N'importe quelle IA. Le contrôle total de votre Mac.** -Agent! est une app 100 % native Swift 6.2 / SwiftUI qui relie **18 fournisseurs de LLM** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Ollama (cloud et local), vLLM et LM Studio — plus **Apple Intelligence** sur l'appareil — à une boucle de tâches autonome qui *agit vraiment* : elle lit votre code, corrige le bug, compile le projet Xcode, committe le diff, pilote n'importe quelle app Mac via l'API d'Accessibilité, exécute des commandes shell en votre nom ou en root, vous envoie les résultats par iMessage et répond à un *« Agent! »* prononcé à voix haute. +Agent! est une app 100 % native Swift 6.2 / SwiftUI qui relie **19 fournisseurs de LLM** — Claude, Codex, OpenAI, Gemini, Grok, Mistral, Mistral Vibe, DeepSeek, Hugging Face, Z.ai, BigModel, Qwen, MiniMax, OpenRouter, Requesty, Ollama (cloud et local), vLLM et LM Studio — plus **Apple Intelligence** sur l'appareil — à une boucle de tâches autonome qui *agit vraiment* : elle lit votre code, corrige le bug, compile le projet Xcode, committe le diff, pilote n'importe quelle app Mac via l'API d'Accessibilité, exécute des commandes shell en votre nom ou en root, vous envoie les résultats par iMessage et répond à un *« Agent! »* prononcé à voix haute. Pas de NPM, pas d'Electron, pas d'abonnement, pas de télémétrie. Apportez votre propre clé API, tournez entièrement en local, ou gratuitement avec Apple Intelligence. Chaque package Swift dont l'app dépend a été écrit par le même auteur. Voir l'[Histoire](#histoire) ci-dessous. @@ -98,7 +98,7 @@ Tapez simplement ce que vous voulez. Agent! trouve comment et le réalise. - **🗂 Onglets, historique, mémoire, plans, skills** — chaque onglet a son propre dossier de projet et son journal ; mémoire utilisateur persistante ; checklists multi-plans dans chaque prompt. - **🔄 Chaîne de repli** — bascule automatique vers le fournisseur suivant configuré en cas de 429/timeout/panne réseau. -## 🤖 18 fournisseurs d'IA +## 🤖 19 fournisseurs d'IA | Fournisseur | Coût | Idéal pour | |---|---|---| @@ -111,6 +111,7 @@ Tapez simplement ce que vous voulez. Agent! trouve comment et le réalise. | **DeepSeek** | Bon marché | Codage économique, rapport de hits de cache | | **Hugging Face** | Variable | Modèles ouverts, serverless ou endpoints dédiés | | **OpenRouter** | Payant | 200+ modèles, une clé ; Claude routé via le protocole Anthropic | +| **Requesty** | Payant | 300+ modèles avec une seule clé compatible OpenAI ; tarifs et capacités par modèle | | **Z.ai** / **BigModel** | Bon marché | GLM-5.3 — point de départ recommandé | | **Qwen** (Alibaba) | Bon marché | Qwen 3.8 via Dashscope | | **MiniMax** | Bon marché | Contexte de 1M tokens | diff --git a/README_zh.md b/README_zh.md index fe7efe31..cb3c77a7 100644 --- a/README_zh.md +++ b/README_zh.md @@ -24,7 +24,7 @@ **一个应用。任意 AI。完全掌控你的 Mac。** -Agent! 是一款 100% 原生的 Swift 6.2 / SwiftUI 应用,将 **18 家 LLM 提供商**——Claude、Codex、OpenAI、Gemini、Grok、Mistral、Mistral Vibe、DeepSeek、Hugging Face、Z.ai、BigModel、Qwen、MiniMax、OpenRouter、Ollama(云端和本地)、vLLM、LM Studio,以及设备端的 **Apple Intelligence**——接入一个真正*会做事*的自主任务循环:读取你的代码库、修复 bug、构建 Xcode 项目、提交 diff、通过辅助功能 API 驱动任何 Mac 应用、以你的身份或 root 运行 shell 命令、通过 iMessage 把结果发给你,并响应你说出的 *「Agent!」*。 +Agent! 是一款 100% 原生的 Swift 6.2 / SwiftUI 应用,将 **19 家 LLM 提供商**——Claude、Codex、OpenAI、Gemini、Grok、Mistral、Mistral Vibe、DeepSeek、Hugging Face、Z.ai、BigModel、Qwen、MiniMax、OpenRouter、Requesty、Ollama(云端和本地)、vLLM、LM Studio,以及设备端的 **Apple Intelligence**——接入一个真正*会做事*的自主任务循环:读取你的代码库、修复 bug、构建 Xcode 项目、提交 diff、通过辅助功能 API 驱动任何 Mac 应用、以你的身份或 root 运行 shell 命令、通过 iMessage 把结果发给你,并响应你说出的 *「Agent!」*。 没有 NPM,没有 Electron,没有订阅,没有遥测。使用你自己的 API 密钥,完全本地运行,或用 Apple Intelligence 免费运行。它依赖的每个 Swift 包都出自同一位作者之手。详见下方的[项目背景](#项目背景)。 @@ -98,7 +98,7 @@ open "build/DerivedData/Build/Products/Debug/Agent!.app" - **🗂 标签页、历史、记忆、计划、技能** —— 每个标签页有独立的项目文件夹和日志;持久化用户记忆;多计划清单出现在每个提示词中。 - **🔄 回退链** —— 遇到 429/超时/网络故障时自动切换到下一个已配置的提供商。 -## 🤖 18 家 AI 提供商 +## 🤖 19 家 AI 提供商 | 提供商 | 费用 | 适合 | |---|---|---| @@ -111,6 +111,7 @@ open "build/DerivedData/Build/Products/Debug/Agent!.app" | **DeepSeek** | 便宜 | 低成本编码、缓存命中报告 | | **Hugging Face** | 不定 | 开源模型,serverless 或专用端点 | | **OpenRouter** | 付费 | 200+ 模型,一把密钥;Claude 经 Anthropic 协议路由 | +| **Requesty** | 付费 | 一把 OpenAI 兼容密钥即可访问 300+ 模型;按模型提供价格与能力信息 | | **Z.ai** / **BigModel** | 便宜 | GLM-5.3 —— 推荐起点 | | **Qwen**(阿里巴巴) | 便宜 | 通过 Dashscope 使用 Qwen 3.8 | | **MiniMax** | 便宜 | 1M token 上下文 |