Remove Qwen provider from application

- Remove Qwen from ModelProvider type
- Remove Qwen OAuth service and device flow
- Update store to only support Ollama and Z.AI
- Remove Qwen from all component provider selectors
- Delete qwen-oauth.ts service file
This commit is contained in:
Gemini AI
2025-12-25 22:11:12 +04:00
Unverified
parent 0c828461e4
commit 1e175ae514
7 changed files with 73 additions and 237 deletions

View File

@@ -40,7 +40,6 @@ export default function ActionPlanGenerator() {
if (saved) {
try {
const keys = JSON.parse(saved);
if (keys.qwen) modelAdapter.updateQwenApiKey(keys.qwen);
if (keys.ollama) modelAdapter.updateOllamaApiKey(keys.ollama);
if (keys.zai) modelAdapter.updateZaiApiKey(keys.zai);
} catch (e) {
@@ -133,7 +132,7 @@ export default function ActionPlanGenerator() {
<div className="space-y-2">
<label className="text-sm font-medium">AI Provider</label>
<div className="flex gap-2">
{(["qwen", "ollama", "zai"] as const).map((provider) => (
{(["ollama", "zai"] as const).map((provider) => (
<Button
key={provider}
variant={selectedProvider === provider ? "default" : "outline"}
@@ -141,7 +140,7 @@ export default function ActionPlanGenerator() {
onClick={() => setSelectedProvider(provider)}
className="capitalize"
>
{provider === "qwen" ? "Qwen" : provider === "ollama" ? "Ollama" : "Z.AI"}
{provider === "ollama" ? "Ollama" : "Z.AI"}
</Button>
))}
</div>

View File

@@ -47,7 +47,6 @@ export default function PRDGenerator() {
if (saved) {
try {
const keys = JSON.parse(saved);
if (keys.qwen) modelAdapter.updateQwenApiKey(keys.qwen);
if (keys.ollama) modelAdapter.updateOllamaApiKey(keys.ollama);
if (keys.zai) modelAdapter.updateZaiApiKey(keys.zai);
} catch (e) {
@@ -147,7 +146,7 @@ export default function PRDGenerator() {
<div className="space-y-2">
<label className="text-sm font-medium">AI Provider</label>
<div className="flex gap-2">
{(["qwen", "ollama", "zai"] as const).map((provider) => (
{(["ollama", "zai"] as const).map((provider) => (
<Button
key={provider}
variant={selectedProvider === provider ? "default" : "outline"}
@@ -155,7 +154,7 @@ export default function PRDGenerator() {
onClick={() => setSelectedProvider(provider)}
className="capitalize"
>
{provider === "qwen" ? "Qwen" : provider === "ollama" ? "Ollama" : "Z.AI"}
{provider === "ollama" ? "Ollama" : "Z.AI"}
</Button>
))}
</div>

View File

@@ -40,7 +40,6 @@ export default function PromptEnhancer() {
if (saved) {
try {
const keys = JSON.parse(saved);
if (keys.qwen) modelAdapter.updateQwenApiKey(keys.qwen);
if (keys.ollama) modelAdapter.updateOllamaApiKey(keys.ollama);
if (keys.zai) modelAdapter.updateZaiApiKey(keys.zai);
} catch (e) {
@@ -124,7 +123,7 @@ export default function PromptEnhancer() {
<div className="space-y-2">
<label className="text-sm font-medium">AI Provider</label>
<div className="flex flex-wrap gap-2">
{(["qwen", "ollama", "zai"] as const).map((provider) => (
{(["ollama", "zai"] as const).map((provider) => (
<Button
key={provider}
variant={selectedProvider === provider ? "default" : "outline"}
@@ -135,7 +134,7 @@ export default function PromptEnhancer() {
selectedProvider === provider && "bg-primary text-primary-foreground"
)}
>
{provider === "qwen" ? "Qwen" : provider === "ollama" ? "Ollama" : "Z.AI"}
{provider === "ollama" ? "Ollama" : "Z.AI"}
</Button>
))}
</div>

View File

@@ -3,15 +3,19 @@
import { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Textarea } from "@/components/ui/textarea";
import { Input } from "@/components/ui/input";
import useStore from "@/lib/store";
import modelAdapter from "@/lib/services/adapter-instance";
import { Save, Key, Server, Eye, EyeOff } from "lucide-react";
import { cn } from "@/lib/utils";
export default function SettingsPanel() {
const { apiKeys, setApiKey, selectedProvider, setSelectedProvider, qwenTokens, setQwenTokens } = useStore();
const {
apiKeys,
setApiKey,
selectedProvider,
setSelectedProvider
} = useStore();
const [showApiKey, setShowApiKey] = useState<Record<string, boolean>>({});
const handleSave = () => {
@@ -27,10 +31,6 @@ export default function SettingsPanel() {
if (saved) {
try {
const keys = JSON.parse(saved);
if (keys.qwen) {
setApiKey("qwen", keys.qwen);
modelAdapter.updateQwenApiKey(keys.qwen);
}
if (keys.ollama) {
setApiKey("ollama", keys.ollama);
modelAdapter.updateOllamaApiKey(keys.ollama);
@@ -47,12 +47,9 @@ export default function SettingsPanel() {
};
const handleApiKeyChange = (provider: string, value: string) => {
setApiKey(provider as "qwen" | "ollama" | "zai", value);
setApiKey(provider as "ollama" | "zai", value);
switch (provider) {
case "qwen":
modelAdapter.updateQwenApiKey(value);
break;
case "ollama":
modelAdapter.updateOllamaApiKey(value);
break;
@@ -79,69 +76,6 @@ export default function SettingsPanel() {
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
<div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium">
<Server className="h-4 w-4" />
Qwen Code API Key
</label>
<div className="relative">
<Input
type={showApiKey.qwen ? "text" : "password"}
placeholder="Enter your Qwen API key"
value={apiKeys.qwen || ""}
onChange={(e) => handleApiKeyChange("qwen", e.target.value)}
className="font-mono text-sm"
/>
<Button
type="button"
variant="ghost"
size="icon"
className="absolute right-0 top-0 h-full"
onClick={() => setShowApiKey((prev) => ({ ...prev, qwen: !prev.qwen }))}
>
{showApiKey.qwen ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
)}
</Button>
</div>
<div className="flex items-center gap-4">
<p className="text-xs text-muted-foreground flex-1">
Get API key from{" "}
<a
href="https://help.aliyun.com/zh/dashscope/"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline"
>
Alibaba DashScope
</a>
</p>
<Button
variant={qwenTokens ? "secondary" : "outline"}
size="sm"
className="h-8"
onClick={() => {
if (qwenTokens) {
setQwenTokens(undefined as any);
localStorage.removeItem("promptarch-qwen-tokens");
modelAdapter.updateQwenApiKey(apiKeys.qwen || "");
} else {
window.location.href = modelAdapter.getQwenAuthUrl();
}
}}
>
{qwenTokens ? "Logout from Qwen" : "Login with Qwen (OAuth)"}
</Button>
</div>
{qwenTokens && (
<p className="text-[10px] text-green-600 dark:text-green-400 font-medium">
Authenticated via OAuth (Expires: {new Date(qwenTokens.expiresAt || 0).toLocaleString()})
</p>
)}
</div>
<div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium">
<Server className="h-4 w-4" />
@@ -238,7 +172,7 @@ export default function SettingsPanel() {
</CardHeader>
<CardContent className="space-y-4">
<div className="grid gap-3">
{(["qwen", "ollama", "zai"] as const).map((provider) => (
{(["ollama", "zai"] as const).map((provider) => (
<button
key={provider}
onClick={() => setSelectedProvider(provider)}
@@ -254,7 +188,6 @@ export default function SettingsPanel() {
<div className="flex-1">
<h3 className="font-medium capitalize">{provider}</h3>
<p className="text-sm text-muted-foreground">
{provider === "qwen" && "Alibaba DashScope API"}
{provider === "ollama" && "Ollama Cloud API"}
{provider === "zai" && "Z.AI Plan API"}
</p>
@@ -278,7 +211,7 @@ export default function SettingsPanel() {
<CardContent>
<div className="rounded-md border bg-muted/30 p-4">
<p className="text-sm">
All API keys are stored locally in your browser. Your prompts are sent directly to the selected AI provider and are not stored by PromptArch.
All API keys are stored locally in your browser. Your prompts are sent directly to selected AI provider and are not stored by PromptArch.
</p>
</div>
</CardContent>