feat: add OllamaLocalExecutor and update provider handling

- Introduced OllamaLocalExecutor to handle requests for the "ollama-local" provider.
- Removed the direct URL construction for "ollama-local" from BaseExecutor.
- Updated index.js to include the new OllamaLocalExecutor in the executors mapping.
- Enhanced the ProvidersPage component to support dynamic addition of OpenAI/Anthropic compatible providers.
This commit is contained in:
decolua committed 2026-05-07 16:42:36 +07:00
1 parent 050e56f20b
commit 0d61a1d546
8 files changed
+127 -94

No files matched your search

+52 -76
View File
@@ -292,6 +292,58 @@ export default function ProvidersPage() {
</div>
)}
{/* Custom Providers (OpenAI/Anthropic Compatible) — dynamic */}
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<h2 className="text-lg sm:text-xl font-semibold flex items-center gap-2 leading-tight">
Custom Providers (OpenAI/Anthropic Compatible){" "}
</h2>
<div className="grid grid-cols-1 gap-2 sm:flex sm:w-auto">
<Button
size="sm"
icon="add"
onClick={() => setShowAddAnthropicCompatibleModal(true)}
className="w-full sm:w-auto"
>
Add Anthropic Compatible
</Button>
<Button
size="sm"
variant="secondary"
icon="add"
onClick={() => setShowAddCompatibleModal(true)}
className="w-full !bg-white !text-black hover:!bg-gray-100 sm:w-auto"
>
Add OpenAI Compatible
</Button>
</div>
</div>
{compatibleProviders.length === 0 &&
anthropicCompatibleProviders.length === 0 ? (
<div className="flex items-center justify-center gap-2 py-2 border border-dashed border-border rounded-xl text-text-muted text-sm">
<span className="material-symbols-outlined text-[18px]">extension</span>
<span>No custom providers — use buttons above to add OpenAI/Anthropic compatible endpoints</span>
</div>
) : (
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3 xl:grid-cols-4">
{[...compatibleProviders, ...anthropicCompatibleProviders].map(
(info) => (
<ApiKeyProviderCard
key={info.id}
providerId={info.id}
provider={info}
stats={getProviderStats(info.id, "apikey")}
authType="compatible"
onToggle={(active) =>
handleToggleProvider(info.id, "apikey", active)
}
/>
),
)}
</div>
)}
</div>
{/* OAuth Providers */}
{oauthEntries.length > 0 && (
<div className="flex flex-col gap-4">
@@ -449,82 +501,6 @@ export default function ProvidersPage() {
</div>
</div> */}
{/* API Key Compatible Providers — dynamic (OpenAI/Anthropic compatible) */}
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<h2 className="text-lg sm:text-xl font-semibold flex items-center gap-2 leading-tight">
API Key Compatible Providers{" "}
</h2>
<div className="grid grid-cols-1 gap-2 sm:flex sm:w-auto">
{/* {(compatibleProviders.length > 0 || anthropicCompatibleProviders.length > 0) && (
<button
onClick={() => handleBatchTest("compatible")}
disabled={!!testingMode}
className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium border transition-colors ${testingMode === "compatible"
? "bg-primary/20 border-primary/40 text-primary animate-pulse"
: "bg-bg border-border text-text-muted hover:text-text-main hover:border-primary/40"
}`}
title="Test all Compatible connections"
>
<span className={`material-symbols-outlined text-[14px]${testingMode === "compatible" ? " animate-spin" : ""}`}>
play_arrow
</span>
{testingMode === "compatible" ? "Testing..." : "Test All"}
</button>
)} */}
<Button
size="sm"
icon="add"
onClick={() => setShowAddAnthropicCompatibleModal(true)}
className="w-full sm:w-auto"
>
Add Anthropic Compatible
</Button>
<Button
size="sm"
variant="secondary"
icon="add"
onClick={() => setShowAddCompatibleModal(true)}
className="w-full !bg-white !text-black hover:!bg-gray-100 sm:w-auto"
>
Add OpenAI Compatible
</Button>
</div>
</div>
{compatibleProviders.length === 0 &&
anthropicCompatibleProviders.length === 0 ? (
<div className="text-center py-8 border border-dashed border-border rounded-xl">
<span className="material-symbols-outlined text-[32px] text-text-muted mb-2">
extension
</span>
<p className="text-text-muted text-sm">
No compatible providers added yet
</p>
<p className="text-text-muted text-xs mt-1">
Use the buttons above to add OpenAI or Anthropic compatible
endpoints
</p>
</div>
) : (
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4 lg:grid-cols-3 xl:grid-cols-4">
{[...compatibleProviders, ...anthropicCompatibleProviders].map(
(info) => (
<ApiKeyProviderCard
key={info.id}
providerId={info.id}
provider={info}
stats={getProviderStats(info.id, "apikey")}
authType="compatible"
onToggle={(active) =>
handleToggleProvider(info.id, "apikey", active)
}
/>
),
)}
</div>
)}
</div>
<AddOpenAICompatibleModal
isOpen={showAddCompatibleModal}
onClose={() => setShowAddCompatibleModal(false)}