Add Cloudflare AI provider support and enhance connection management

- Introduced Cloudflare AI as a new provider with specific configurations in providerModels.js and providers.js.
- Updated DefaultExecutor to handle account ID resolution for Cloudflare AI connections.
- Enhanced AddApiKeyModal and EditConnectionModal to include account ID input for Cloudflare AI.
- Implemented validation for Cloudflare AI API key connections in testUtils.js and route.js.
- Updated UI components to reflect changes in provider management and connection handling.
This commit is contained in:
decolua committed 2026-04-28 11:07:39 +07:00
1 parent 111e78940a
commit 1bb621317d
18 files changed
+325 -71

No files matched your search

@@ -14,6 +14,7 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa
: "";
const isAzure = provider === "azure";
const isCloudflareAi = provider === "cloudflare-ai";
const [formData, setFormData] = useState({
name: "",
@@ -28,6 +29,7 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa
deployment: "",
organization: "",
});
const [cloudflareData, setCloudflareData] = useState({ accountId: "" });
const [validating, setValidating] = useState(false);
const [validationResult, setValidationResult] = useState(null);
const [saving, setSaving] = useState(false);
@@ -44,6 +46,9 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa
organization: azureData.organization,
};
}
if (isCloudflareAi) {
return { accountId: cloudflareData.accountId };
}
return undefined;
};
@@ -180,6 +185,20 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa
}
</p>
)}
{isCloudflareAi && (
<div className="bg-sidebar/50 p-4 rounded-lg border border-accent/20">
<h3 className="font-semibold mb-3 text-sm">Cloudflare Workers AI</h3>
<Input
label="Account ID"
value={cloudflareData.accountId}
onChange={(e) => setCloudflareData({ ...cloudflareData, accountId: e.target.value })}
placeholder="abc123def456..."
/>
<p className="text-xs text-text-muted mt-2">
Find your Account ID in the right sidebar of <a href="https://dash.cloudflare.com" target="_blank" rel="noopener noreferrer" className="text-primary underline">dash.cloudflare.com</a>
</p>
</div>
)}
{isAzure && (
<div className="bg-sidebar/50 p-4 rounded-lg border border-accent/20">
<h3 className="font-semibold mb-3 text-sm">Azure OpenAI Configuration</h3>
@@ -241,7 +260,7 @@ export default function AddApiKeyModal({ isOpen, provider, providerName, isCompa
</p>
<div className="flex gap-2">
<Button onClick={handleSubmit} fullWidth disabled={saving || (!isOllamaLocal && (!formData.name || !formData.apiKey)) || (isAzure && (!azureData.azureEndpoint || !azureData.deployment || !azureData.organization))}>
<Button onClick={handleSubmit} fullWidth disabled={saving || (!isOllamaLocal && (!formData.name || !formData.apiKey)) || (isAzure && (!azureData.azureEndpoint || !azureData.deployment || !azureData.organization)) || (isCloudflareAi && !cloudflareData.accountId)}>
{saving ? "Saving..." : "Save"}
</Button>
@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback } from "react";
import { useParams, useRouter } from "next/navigation";
import Link from "next/link";
import Image from "next/image";
import { Card, Button, Badge, Input, Modal, CardSkeleton, OAuthModal, KiroOAuthWrapper, CursorAuthModal, IFlowCookieModal, GitLabAuthModal, Toggle, Select, EditConnectionModal } from "@/shared/components";
import { Card, Button, Badge, Input, Modal, CardSkeleton, OAuthModal, KiroOAuthWrapper, CursorAuthModal, IFlowCookieModal, GitLabAuthModal, Toggle, Select, EditConnectionModal, NoAuthProxyCard } from "@/shared/components";
import { OAUTH_PROVIDERS, APIKEY_PROVIDERS, FREE_PROVIDERS, FREE_TIER_PROVIDERS, WEB_COOKIE_PROVIDERS, getProviderAlias, isOpenAICompatibleProvider, isAnthropicCompatibleProvider, AI_PROVIDERS, THINKING_CONFIG } from "@/shared/constants/providers";
import { getModelsByProviderId } from "@/shared/constants/models";
import { useCopyToClipboard } from "@/shared/hooks/useCopyToClipboard";
@@ -849,17 +849,7 @@ export default function ProviderDetailPage() {
{/* Connections */}
{isFreeNoAuth ? (
<Card>
<div className="flex items-center gap-3">
<div className="inline-flex items-center justify-center w-10 h-10 rounded-full bg-green-500/10 text-green-500">
<span className="material-symbols-outlined text-[20px]">lock_open</span>
</div>
<div>
<p className="text-sm font-medium">No authentication required</p>
<p className="text-xs text-text-muted">This provider is ready to use.</p>
</div>
</div>
</Card>
<NoAuthProxyCard providerId={providerId} />
) : (
<Card>
<div className="flex items-center justify-between mb-4">