mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
feat(provider): 重构模型测试对话框,加固 Vertex AI 传输层
模型测试: - 将消息输入替换为完整 JSON 请求体编辑器,支持格式化和校验 - 新增端点选择面板,测试前可选择目标端点 - 新增调试检查器,可查看每次尝试的请求/响应头和体 - 结果视图改用 HorizontalRequestTimeline 组件展示请求追踪 - endpoint_checker 返回完整调试数据,通过 candidate extra_data 持久化 Vertex AI: - 改进上下文检测逻辑,不再仅依赖 provider_type,支持从 base_url 推断 - Service Account 密钥现支持自动拉取模型(使用 auth_config 而非 api_key) - 移除 Gemini Developer API 回退,API Key 仅走 Express 模式 - 端点表单为 Vertex AI 显示格式特定的默认路径模板 - 密钥格式校验仅在 auth_type/api_formats 变更时执行 其他: - 禁用 ClaudeCode 提供商类型创建入口 - Dialog 组件新增 closeOnBackdrop 属性
This commit is contained in:
@@ -240,6 +240,10 @@
|
||||
-->{{ proxyTimingBreakdown(currentAttempt.extra_data.proxy) }}<!--
|
||||
-->)</span>
|
||||
</span>
|
||||
<code
|
||||
v-if="typeof currentAttempt.extra_data.proxy.node_id === 'string' && currentAttempt.extra_data.proxy.node_id"
|
||||
class="text-xs font-mono text-muted-foreground"
|
||||
>节点 Key {{ currentAttempt.extra_data.proxy.node_id }}</code>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -462,7 +466,7 @@ interface UsageData {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
requestId: string
|
||||
requestId?: string | null
|
||||
/** 外部传入的状态码,用于覆盖 trace.final_status 的判断 */
|
||||
overrideStatusCode?: number
|
||||
/** 请求侧 API 格式(客户端入口格式) */
|
||||
@@ -471,6 +475,12 @@ const props = defineProps<{
|
||||
usageData?: UsageData | null
|
||||
/** 请求元数据(用于号池调度组装) */
|
||||
requestMetadata?: Record<string, unknown> | null
|
||||
/** 已获取的追踪数据;传入时不再内部拉取 */
|
||||
traceData?: RequestTrace | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
selectAttempt: [attempt: CandidateRecord | null]
|
||||
}>()
|
||||
|
||||
// 用量数据(从 props 获取)
|
||||
@@ -525,7 +535,8 @@ const getFinalStatusBadgeVariant = (status: string): BadgeVariant => {
|
||||
|
||||
const loading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const trace = ref<RequestTrace | null>(null)
|
||||
const internalTrace = ref<RequestTrace | null>(null)
|
||||
const trace = computed(() => props.traceData ?? internalTrace.value)
|
||||
const selectedGroupIndex = ref(0)
|
||||
const selectedAttemptIndex = ref(0)
|
||||
const hoveredGroupIndex = ref<number | null>(null)
|
||||
@@ -1045,6 +1056,10 @@ const currentAttempt = computed(() => {
|
||||
return selectedGroup.value.allAttempts[selectedAttemptIndex.value] || selectedGroup.value.primary
|
||||
})
|
||||
|
||||
watch(currentAttempt, (attempt) => {
|
||||
emit('selectAttempt', attempt ?? null)
|
||||
}, { immediate: true })
|
||||
|
||||
const currentGroupTitle = computed(() => {
|
||||
if (!selectedGroup.value || !currentAttempt.value) return ''
|
||||
if (selectedGroup.value.isPoolGroup) {
|
||||
@@ -1224,7 +1239,7 @@ const navigateGroup = (direction: number) => {
|
||||
// 加载请求追踪数据
|
||||
const isSilentRefresh = ref(false)
|
||||
const loadTrace = async (silent = false) => {
|
||||
if (!props.requestId) return
|
||||
if (!props.requestId || props.traceData) return
|
||||
|
||||
isSilentRefresh.value = silent
|
||||
|
||||
@@ -1234,7 +1249,7 @@ const loadTrace = async (silent = false) => {
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
trace.value = await requestTraceApi.getRequestTrace(props.requestId)
|
||||
internalTrace.value = await requestTraceApi.getRequestTrace(props.requestId)
|
||||
} catch (err: unknown) {
|
||||
if (!silent) {
|
||||
error.value = parseApiError(err, '加载失败')
|
||||
@@ -1304,12 +1319,31 @@ watch(groupedTimeline, (newGroups) => {
|
||||
selectedAttemptIndex.value = 0
|
||||
}, { immediate: true })
|
||||
|
||||
// 监听 requestId 变化
|
||||
watch(() => props.requestId, () => {
|
||||
selectedGroupIndex.value = 0
|
||||
selectedAttemptIndex.value = 0
|
||||
loadTrace()
|
||||
}, { immediate: true })
|
||||
// 监听 requestId / 外部 trace 变化
|
||||
watch(
|
||||
[() => props.requestId, () => props.traceData],
|
||||
() => {
|
||||
selectedGroupIndex.value = 0
|
||||
selectedAttemptIndex.value = 0
|
||||
|
||||
if (props.traceData) {
|
||||
internalTrace.value = null
|
||||
loading.value = false
|
||||
error.value = null
|
||||
return
|
||||
}
|
||||
|
||||
if (!props.requestId) {
|
||||
internalTrace.value = null
|
||||
loading.value = false
|
||||
error.value = null
|
||||
return
|
||||
}
|
||||
|
||||
void loadTrace()
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
defineExpose({ refresh: () => loadTrace(true) })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user