fix(web): adapt workflow agent logs (#39488)

This commit is contained in:
yyh 2026-07-24 12:55:30 +08:00 committed by GitHub
parent bbb133cd58
commit c4bfea6096
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 113 additions and 13 deletions

View File

@ -106,6 +106,40 @@ const populatedLogsResponse: AgentLogListResponse = {
total: 1,
}
const workflowLogsResponse: AgentLogListResponse = {
data: [
{
conversation_id: 'execution-1',
created_at: 1781660000,
end_user_id: 'end-user-1',
id: 'execution-1',
message_count: 1,
operation_rate: null,
source: {
app_icon: '🖌',
app_icon_background: '#EEF4FF',
app_icon_type: 'emoji',
app_id: 'workflow-app-id',
app_name: 'SVG Logo Design',
id: 'workflow:workflow-app-id:workflow-id:v3:agent-node-id',
node_id: 'agent-node-id',
type: 'workflow',
workflow_id: 'workflow-id',
workflow_version: 'v3',
},
status: 'success',
title: 'Workflow agent execution',
unread: false,
updated_at: 1781661000,
user_rate: null,
},
],
has_more: false,
limit: 25,
page: 1,
total: 1,
}
const logSourcesResponse: AgentLogSourceListResponse = {
data: [],
groups: [
@ -357,7 +391,37 @@ describe('AgentLogsPage', () => {
},
})
})
expect(screen.getByText('appLog.detail.conversationId')).toBeInTheDocument()
expect(await screen.findByText('Translated chapter summary')).toBeInTheDocument()
})
it('should identify workflow log details by execution id', async () => {
const user = userEvent.setup()
mocks.logsQueryFn.mockResolvedValue(workflowLogsResponse)
renderPage()
await user.click(await screen.findByRole('button', { name: 'Workflow agent execution' }))
await waitFor(() => {
expect(mocks.messagesQueryOptions).toHaveBeenCalledWith({
input: {
params: {
agent_id: 'agent-1',
conversation_id: 'execution-1',
},
query: {
limit: 100,
page: 1,
sort_by: 'created_at',
sort_order: 'asc',
sources: ['workflow:workflow-app-id:workflow-id:v3:agent-node-id'],
},
},
})
})
expect(screen.getByText('agentV2.agentDetail.logs.executionId')).toBeInTheDocument()
expect(screen.queryByText('appLog.detail.conversationId')).not.toBeInTheDocument()
})
})
})

View File

@ -62,7 +62,9 @@ export function AgentLogDetailPanel({
<div className="flex shrink-0 items-center gap-2 rounded-t-xl bg-components-panel-bg pt-3 pr-3 pb-2 pl-4">
<div className="min-w-0 shrink-0">
<div className="mb-0.5 system-xs-semibold-uppercase text-text-primary">
{t(($) => $['detail.conversationId'], { ns: 'appLog' })}
{log?.source?.type === 'workflow'
? tAgentV2(($) => $['agentDetail.logs.executionId'])
: t(($) => $['detail.conversationId'], { ns: 'appLog' })}
</div>
<div className="flex min-w-0 items-center system-2xs-regular-uppercase text-text-secondary">
{log && (

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "وكيل",
"agentDetail.logs.description": "تسجل السجلات الكاملة حالة تشغيل التطبيق، بما في ذلك مدخلات المستخدم وردود الوكيل والتخطيط واستخدامات الأدوات.",
"agentDetail.logs.empty": "لم يتم العثور على سجلات",
"agentDetail.logs.executionId": "معرّف التنفيذ",
"agentDetail.logs.filters.period.allTime": "كل الأوقات",
"agentDetail.logs.filters.period.last30days": "آخر 30 يوماً",
"agentDetail.logs.filters.period.last7days": "آخر 7 أيام",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "Vollständige Logs zeichnen den Laufzeitstatus der Anwendung auf, einschließlich Benutzereingaben, Agentenantworten, Planung und Tool-Nutzung.",
"agentDetail.logs.empty": "Keine Logs gefunden",
"agentDetail.logs.executionId": "Ausführungs-ID",
"agentDetail.logs.filters.period.allTime": "Gesamter Zeitraum",
"agentDetail.logs.filters.period.last30days": "Letzte 30 Tage",
"agentDetail.logs.filters.period.last7days": "Letzte 7 Tage",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "Full logs record the running status of the application, including user inputs, agent replies, planning and tool uses.",
"agentDetail.logs.empty": "No logs found",
"agentDetail.logs.executionId": "Execution ID",
"agentDetail.logs.filters.period.allTime": "All time",
"agentDetail.logs.filters.period.last30days": "Last 30 days",
"agentDetail.logs.filters.period.last7days": "Last 7 days",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agente",
"agentDetail.logs.description": "Los registros completos registran el estado de ejecución de la aplicación, incluidas las entradas del usuario, las respuestas del agente, la planificación y los usos de herramientas.",
"agentDetail.logs.empty": "No se encontraron registros",
"agentDetail.logs.executionId": "ID de ejecución",
"agentDetail.logs.filters.period.allTime": "Todo el tiempo",
"agentDetail.logs.filters.period.last30days": "Últimos 30 días",
"agentDetail.logs.filters.period.last7days": "Últimos 7 días",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "عامل",
"agentDetail.logs.description": "گزارش‌های کامل وضعیت اجرای برنامه را ثبت می‌کنند، از جمله ورودی‌های کاربر، پاسخ‌های عامل، برنامه‌ریزی و استفاده از ابزار.",
"agentDetail.logs.empty": "هیچ گزارشی یافت نشد",
"agentDetail.logs.executionId": "شناسه اجرا",
"agentDetail.logs.filters.period.allTime": "همه زمان‌ها",
"agentDetail.logs.filters.period.last30days": "۳۰ روز گذشته",
"agentDetail.logs.filters.period.last7days": "۷ روز گذشته",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "Les journaux complets enregistrent létat dexécution de lapplication, y compris les entrées des utilisateurs, les réponses de lagent, la planification et lutilisation des outils.",
"agentDetail.logs.empty": "Aucun journal trouvé",
"agentDetail.logs.executionId": "ID dexécution",
"agentDetail.logs.filters.period.allTime": "Toute la période",
"agentDetail.logs.filters.period.last30days": "30 derniers jours",
"agentDetail.logs.filters.period.last7days": "7 derniers jours",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "एजेंट",
"agentDetail.logs.description": "पूर्ण लॉग एप्लिकेशन की चल रही स्थिति को रिकॉर्ड करते हैं, जिसमें उपयोगकर्ता इनपुट, एजेंट उत्तर, योजना और उपकरण उपयोग शामिल हैं।",
"agentDetail.logs.empty": "कोई लॉग नहीं मिला",
"agentDetail.logs.executionId": "निष्पादन आईडी",
"agentDetail.logs.filters.period.allTime": "हर समय",
"agentDetail.logs.filters.period.last30days": "पिछले 30 दिन",
"agentDetail.logs.filters.period.last7days": "पिछले 7 दिन",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agen",
"agentDetail.logs.description": "Log lengkap mencatat status berjalan aplikasi, termasuk input pengguna, balasan agen, perencanaan, dan penggunaan alat.",
"agentDetail.logs.empty": "Tidak ada log ditemukan",
"agentDetail.logs.executionId": "ID Eksekusi",
"agentDetail.logs.filters.period.allTime": "Sepanjang waktu",
"agentDetail.logs.filters.period.last30days": "30 hari terakhir",
"agentDetail.logs.filters.period.last7days": "7 hari terakhir",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agente",
"agentDetail.logs.description": "I log completi registrano lo stato di esecuzione dellapplicazione, inclusi input degli utenti, risposte dellagente, pianificazione e uso degli strumenti.",
"agentDetail.logs.empty": "Nessun log trovato",
"agentDetail.logs.executionId": "ID esecuzione",
"agentDetail.logs.filters.period.allTime": "Tutto il periodo",
"agentDetail.logs.filters.period.last30days": "Ultimi 30 giorni",
"agentDetail.logs.filters.period.last7days": "Ultimi 7 giorni",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "エージェント",
"agentDetail.logs.description": "完全なログには、ユーザー入力、エージェントの応答、計画、ツールの使用など、アプリケーションの実行状況が記録されます。",
"agentDetail.logs.empty": "ログが見つかりません",
"agentDetail.logs.executionId": "実行 ID",
"agentDetail.logs.filters.period.allTime": "全期間",
"agentDetail.logs.filters.period.last30days": "過去 30 日間",
"agentDetail.logs.filters.period.last7days": "過去 7 日間",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "에이전트",
"agentDetail.logs.description": "전체 로그는 사용자 입력, 에이전트 응답, 계획 및 도구 사용을 포함한 애플리케이션의 실행 상태를 기록합니다.",
"agentDetail.logs.empty": "로그가 없습니다",
"agentDetail.logs.executionId": "실행 ID",
"agentDetail.logs.filters.period.allTime": "전체 기간",
"agentDetail.logs.filters.period.last30days": "지난 30 일",
"agentDetail.logs.filters.period.last7days": "지난 7 일",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "Volledige logs registreren de status van de applicatie tijdens het uitvoeren, inclusief gebruikersinvoer, antwoorden van de agent, planning en gebruik van tools.",
"agentDetail.logs.empty": "Geen logs gevonden",
"agentDetail.logs.executionId": "Uitvoerings-ID",
"agentDetail.logs.filters.period.allTime": "Alle tijd",
"agentDetail.logs.filters.period.last30days": "Laatste 30 dagen",
"agentDetail.logs.filters.period.last7days": "Laatste 7 dagen",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "Pełne logi rejestrują stan działania aplikacji, w tym dane wejściowe użytkownika, odpowiedzi agenta, planowanie i użycie narzędzi.",
"agentDetail.logs.empty": "Nie znaleziono logów",
"agentDetail.logs.executionId": "ID wykonania",
"agentDetail.logs.filters.period.allTime": "Cały czas",
"agentDetail.logs.filters.period.last30days": "Ostatnie 30 dni",
"agentDetail.logs.filters.period.last7days": "Ostatnie 7 dni",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agente",
"agentDetail.logs.description": "Os logs completos registram o status de execução do aplicativo, incluindo entradas do usuário, respostas do agente, planejamento e uso de ferramentas.",
"agentDetail.logs.empty": "Nenhum log encontrado",
"agentDetail.logs.executionId": "ID da execução",
"agentDetail.logs.filters.period.allTime": "Todo o período",
"agentDetail.logs.filters.period.last30days": "Últimos 30 dias",
"agentDetail.logs.filters.period.last7days": "Últimos 7 dias",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "Jurnalele complete înregistrează starea de execuție a aplicației, inclusiv intrările utilizatorilor, răspunsurile agentului, planificarea și utilizarea instrumentelor.",
"agentDetail.logs.empty": "Niciun jurnal găsit",
"agentDetail.logs.executionId": "ID execuție",
"agentDetail.logs.filters.period.allTime": "Toată perioada",
"agentDetail.logs.filters.period.last30days": "Ultimele 30 de zile",
"agentDetail.logs.filters.period.last7days": "Ultimele 7 zile",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Агент",
"agentDetail.logs.description": "Полные журналы записывают статус работы приложения, включая ввод пользователя, ответы агента, планирование и использование инструментов.",
"agentDetail.logs.empty": "Журналы не найдены",
"agentDetail.logs.executionId": "ID выполнения",
"agentDetail.logs.filters.period.allTime": "За всё время",
"agentDetail.logs.filters.period.last30days": "Последние 30 дней",
"agentDetail.logs.filters.period.last7days": "Последние 7 дней",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "Polni dnevniki beležijo stanje izvajanja aplikacije, vključno z uporabniškimi vnosi, odgovori agenta, načrtovanjem in uporabo orodij.",
"agentDetail.logs.empty": "Dnevnikov ni",
"agentDetail.logs.executionId": "ID izvedbe",
"agentDetail.logs.filters.period.allTime": "Ves čas",
"agentDetail.logs.filters.period.last30days": "Zadnjih 30 dni",
"agentDetail.logs.filters.period.last7days": "Zadnjih 7 dni",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "ตัวแทน",
"agentDetail.logs.description": "บันทึกแบบเต็มจะบันทึกสถานะการทำงานของแอปพลิเคชัน รวมถึงอินพุตของผู้ใช้ การตอบกลับของตัวแทน การวางแผน และการใช้เครื่องมือ",
"agentDetail.logs.empty": "ไม่พบบันทึก",
"agentDetail.logs.executionId": "รหัสการดำเนินการ",
"agentDetail.logs.filters.period.allTime": "ตลอดเวลา",
"agentDetail.logs.filters.period.last30days": "30 วันที่ผ่านมา",
"agentDetail.logs.filters.period.last7days": "7 วันที่ผ่านมา",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Ajan",
"agentDetail.logs.description": "Tam günlükler, kullanıcı girişleri, ajan yanıtları, planlama ve araç kullanımları dahil olmak üzere uygulamanın çalışma durumunu kaydeder.",
"agentDetail.logs.empty": "Günlük bulunamadı",
"agentDetail.logs.executionId": "Yürütme Kimliği",
"agentDetail.logs.filters.period.allTime": "Tüm zamanlar",
"agentDetail.logs.filters.period.last30days": "Son 30 gün",
"agentDetail.logs.filters.period.last7days": "Son 7 gün",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Агент",
"agentDetail.logs.description": "Повні журнали записують стан роботи застосунка, включаючи введення користувача, відповіді агента, планування та використання інструментів.",
"agentDetail.logs.empty": "Журнали не знайдено",
"agentDetail.logs.executionId": "ID виконання",
"agentDetail.logs.filters.period.allTime": "За весь час",
"agentDetail.logs.filters.period.last30days": "Останні 30 днів",
"agentDetail.logs.filters.period.last7days": "Останні 7 днів",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Tác nhân",
"agentDetail.logs.description": "Nhật ký đầy đủ ghi lại trạng thái chạy của ứng dụng, bao gồm đầu vào của người dùng, phản hồi của tác nhân, lập kế hoạch và sử dụng công cụ.",
"agentDetail.logs.empty": "Không tìm thấy nhật ký",
"agentDetail.logs.executionId": "ID thực thi",
"agentDetail.logs.filters.period.allTime": "Mọi lúc",
"agentDetail.logs.filters.period.last30days": "30 ngày qua",
"agentDetail.logs.filters.period.last7days": "7 ngày qua",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "完整日志记录应用运行状态包括用户输入、Agent 回复、规划和工具使用。",
"agentDetail.logs.empty": "暂无日志",
"agentDetail.logs.executionId": "执行 ID",
"agentDetail.logs.filters.period.allTime": "全部时间",
"agentDetail.logs.filters.period.last30days": "最近 30 天",
"agentDetail.logs.filters.period.last7days": "最近 7 天",

View File

@ -279,6 +279,7 @@
"agentDetail.documentTitle": "Agent",
"agentDetail.logs.description": "完整日誌記錄應用程式執行狀態包括使用者輸入、Agent 回覆、規劃和工具使用。",
"agentDetail.logs.empty": "暫無日誌",
"agentDetail.logs.executionId": "執行 ID",
"agentDetail.logs.filters.period.allTime": "全部時間",
"agentDetail.logs.filters.period.last30days": "最近 30 天",
"agentDetail.logs.filters.period.last7days": "最近 7 天",

View File

@ -35,6 +35,16 @@ const loadConsoleQueryWithRequest = async (request: ReturnType<typeof vi.fn>) =>
return module.consoleQuery
}
const loadConsoleQueryWithFetch = async () => {
vi.resetModules()
vi.doUnmock('./base')
vi.doMock('@/utils/client', () => ({ isClient: true, isServer: false }))
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
const module = await import('./client')
warnSpy.mockRestore()
return module.consoleQuery
}
const loadWorkflowGenerationStream = async (sseGeneratorPost: ReturnType<typeof vi.fn>) => {
vi.resetModules()
vi.doMock('@/utils/client', () => ({ isClient: true, isServer: false }))
@ -355,7 +365,7 @@ describe('consoleQuery transport context', () => {
})
it('should serialize trial app dataset ids as repeated query params', async () => {
const request = vi.fn().mockResolvedValue(
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
new Response(
JSON.stringify({
data: [],
@ -372,7 +382,7 @@ describe('consoleQuery transport context', () => {
},
),
)
const consoleQuery = await loadConsoleQueryWithRequest(request)
const consoleQuery = await loadConsoleQueryWithFetch()
const queryOptions = consoleQuery.trialApps.byAppId.datasets.get.queryOptions({
input: {
params: {
@ -386,14 +396,12 @@ describe('consoleQuery transport context', () => {
await queryOptions.queryFn({ signal: new AbortController().signal } as QueryFunctionContext)
expect(request).toHaveBeenCalledWith(
expect.stringContaining('/trial-apps/app-1/datasets?ids=id-1&ids=id-2'),
expect.any(Object),
expect.objectContaining({
fetchCompat: true,
}),
)
expect(request.mock.calls[0]![0]).not.toContain('ids%5B0%5D')
expect(fetchSpy).toHaveBeenCalledTimes(1)
const resource = fetchSpy.mock.calls[0]![0]
const requestURL = new URL(resource instanceof Request ? resource.url : resource.toString())
expect(requestURL.searchParams.getAll('ids')).toEqual(['id-1', 'id-2'])
expect(requestURL.searchParams.has('ids[0]')).toBe(false)
expect(requestURL.searchParams.has('ids[1]')).toBe(false)
})
it('should consume KnowledgeFS processing events through the generated stream contract', async () => {

View File

@ -74,10 +74,13 @@ function createConsoleOpenAPILink(contract: AnyContractRouter): ConsoleClientLin
url: getBaseURL(API_PREFIX),
fetch: (input, init, options) => {
const requestInit = options.context.keepalive ? { ...init, keepalive: true } : init
const normalizedURL = normalizeConsoleOpenAPIURL(input.url)
const normalizedRequest =
normalizedURL === input.url ? input : new Request(normalizedURL, input)
return request(normalizeConsoleOpenAPIURL(input.url), requestInit, {
return request(normalizedURL, requestInit, {
fetchCompat: true,
request: input,
request: normalizedRequest,
silent: options.context.silent,
})
},