feat(admin): 添加网络代理配置和钱包交易功能
- 在管理面板中集成网络代理配置显示和平台代理设置 - 添加钱包摘要和交易列表API接口及数据管理 - 实现SSE流式响应中的错误处理机制 - 添加全局HTTP代理环境变量配置支持 - 更新平台表单以支持代理模式选择和自定义代理地址 - 集成钱包交易查询过滤和分页功能 - 优化API错误详情解析和显示格式
This commit is contained in:
@@ -2,8 +2,10 @@ import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
|
||||
import {
|
||||
AssistantRuntimeProvider,
|
||||
ComposerPrimitive,
|
||||
ErrorPrimitive,
|
||||
MessagePrimitive,
|
||||
ThreadPrimitive,
|
||||
useMessage,
|
||||
useMessagePartText,
|
||||
useLocalRuntime,
|
||||
useThread,
|
||||
@@ -19,11 +21,12 @@ import { mermaid } from '@streamdown/mermaid';
|
||||
import type { GatewayApiKey, GatewayTask, PlatformModel } from '@easyai-ai-gateway/contracts';
|
||||
import { Bot, ChevronDown, Image as ImageIcon, MessageSquarePlus, Paperclip, Send, Sparkles, Video } from 'lucide-react';
|
||||
import { Badge, Button, Select, Textarea } from '../components/ui';
|
||||
import { createImageGenerationTask, createVideoGenerationTask, getTask, streamChatCompletionText } from '../api';
|
||||
import { GatewayApiError, createImageGenerationTask, createVideoGenerationTask, getTask, streamChatCompletionText } from '../api';
|
||||
import type { PlaygroundMode } from '../types';
|
||||
import {
|
||||
defaultMediaGenerationSettings,
|
||||
deriveMediaModelCapabilities,
|
||||
gatewayTaskErrorText,
|
||||
mediaRequestPayload,
|
||||
MediaSettingsPopover,
|
||||
MediaTaskBoard,
|
||||
@@ -172,7 +175,7 @@ export function PlaygroundPage(props: {
|
||||
.then((detail) => {
|
||||
if (!isMountedRef.current) return;
|
||||
setMediaRuns((current) => updateMediaRun(current, run.localId, {
|
||||
error: detail.error,
|
||||
error: gatewayTaskErrorText(detail, '任务执行失败'),
|
||||
status: detail.status,
|
||||
task: detail,
|
||||
}));
|
||||
@@ -240,7 +243,7 @@ export function PlaygroundPage(props: {
|
||||
setMediaRuns((current) => updateMediaRun(current, localId, { status: response.task.status, task: response.task }));
|
||||
const detail = await pollTaskUntilSettled(credential, response.task);
|
||||
setMediaRuns((current) => updateMediaRun(current, localId, {
|
||||
error: detail.error,
|
||||
error: gatewayTaskErrorText(detail, '任务执行失败'),
|
||||
status: detail.status,
|
||||
task: detail,
|
||||
}));
|
||||
@@ -453,13 +456,13 @@ function AssistantChatPlayground(props: {
|
||||
async *run({ abortSignal, messages }) {
|
||||
if (!props.token) {
|
||||
props.onLogin();
|
||||
throw new Error('请先登录后再测试模型。');
|
||||
throw new GatewayApiError('请先登录后再测试模型。');
|
||||
}
|
||||
if (!activeApiKeySecret) {
|
||||
throw new Error('请选择可用于测试的 API Key;如果列表为空,请刷新或重新创建一个 Key。');
|
||||
throw new GatewayApiError('请选择可用于测试的 API Key;如果列表为空,请刷新或重新创建一个 Key。');
|
||||
}
|
||||
if (!props.selectedModel) {
|
||||
throw new Error('当前没有可用的大模型,请确认用户组权限或平台模型配置。');
|
||||
throw new GatewayApiError('当前没有可用的大模型,请确认用户组权限或平台模型配置。');
|
||||
}
|
||||
let text = '';
|
||||
for await (const delta of streamChatCompletionText(
|
||||
@@ -696,6 +699,8 @@ function AssistantChatComposer(props: {
|
||||
}
|
||||
|
||||
function AssistantMessage() {
|
||||
const hasError = useMessage((state) => state.status?.type === 'incomplete' && state.status.reason === 'error');
|
||||
|
||||
return (
|
||||
<MessagePrimitive.Root className="assistantMessage">
|
||||
<MessagePrimitive.If user>
|
||||
@@ -704,16 +709,19 @@ function AssistantMessage() {
|
||||
</div>
|
||||
</MessagePrimitive.If>
|
||||
<MessagePrimitive.If assistant>
|
||||
<div className="assistantBubble assistant">
|
||||
<div className={hasError ? 'assistantBubble assistant error' : 'assistantBubble assistant'}>
|
||||
<MessagePrimitive.Parts components={{ Text: AssistantMarkdownText }} />
|
||||
<MessagePrimitive.If hasContent={false}>
|
||||
<span className="assistantTyping">模型正在回复...</span>
|
||||
</MessagePrimitive.If>
|
||||
<MessagePrimitive.Error>
|
||||
<strong>调用失败</strong>
|
||||
<ErrorPrimitive.Message className="assistantErrorMessage" />
|
||||
</MessagePrimitive.Error>
|
||||
{!hasError && (
|
||||
<MessagePrimitive.If hasContent={false}>
|
||||
<span className="assistantTyping">模型正在回复...</span>
|
||||
</MessagePrimitive.If>
|
||||
)}
|
||||
</div>
|
||||
</MessagePrimitive.If>
|
||||
<MessagePrimitive.Error>
|
||||
<div className="assistantBubble error">调用失败,请检查模型、平台凭证或测试模式配置。</div>
|
||||
</MessagePrimitive.Error>
|
||||
</MessagePrimitive.Root>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user