Files
agent-park/e2e/agent-os-live.spec.ts
T

138 lines
4.9 KiB
TypeScript

import { expect, test } from '@playwright/test'
function resolveAdminKey(): string | undefined {
return process.env.E2E_ADMIN_KEY || process.env.ADMIN_CONSOLE_KEY
}
function hasLiveModelKey(): boolean {
return Boolean(
process.env.AGENT_OS_MODEL_API_KEY || process.env.BIGMODEL_API_KEY || process.env.ZHIPU_API_KEY
)
}
test.describe('Agent OS Live E2E', () => {
test.skip(!resolveAdminKey(), 'E2E_ADMIN_KEY or ADMIN_CONSOLE_KEY is required')
test.skip(!hasLiveModelKey(), 'Live model API key is required for this suite')
test('runs model planning and policy approval loop with audit records', async ({
request,
page,
}) => {
const adminKey = resolveAdminKey()!
const tokenResponse = await request.post('/api/admin/auth/token', {
data: {
adminKey,
operator: 'playwright-e2e',
},
})
expect(tokenResponse.ok()).toBeTruthy()
const tokenPayload = await tokenResponse.json()
expect(tokenPayload.success).toBe(true)
const bearerToken = tokenPayload.token as string
const headers = {
Authorization: `Bearer ${bearerToken}`,
'Content-Type': 'application/json',
}
const firstRunResponse = await request.post('/api/agent/goals', {
headers,
data: {
goal: 'Please discover AI agent projects from trending signals and summarize with RAG retrieval.',
preferredAgentId: 'agent.discovery.scout',
},
})
expect(firstRunResponse.ok()).toBeTruthy()
const firstRun = await firstRunResponse.json()
expect(firstRun.success).toBe(true)
expect(firstRun.planning?.source).toBe('model')
expect(Array.isArray(firstRun.tasks)).toBe(true)
expect(firstRun.tasks.length).toBeGreaterThan(0)
expect(Array.isArray(firstRun.toolCalls)).toBe(true)
expect(firstRun.toolCalls.length).toBeGreaterThan(0)
const runId = firstRun.run?.id as string
expect(typeof runId).toBe('string')
const runDetailResponse = await request.get(`/api/agent/runs/${runId}`, { headers })
expect(runDetailResponse.ok()).toBeTruthy()
const runDetail = await runDetailResponse.json()
expect(runDetail.success).toBe(true)
expect(runDetail.run?.id).toBe(runId)
expect(runDetail.tasks.length).toBeGreaterThan(0)
const proposalResponse = await request.post('/api/admin/policies/proposals', {
headers,
data: {
title: 'Deny MCP browser for discovery scout',
description: 'Policy proposal created by live e2e to validate approval effectiveness.',
targetType: 'agent',
targetId: 'agent.discovery.scout',
changes: {
policyOverrides: {
'mcp.agent_browser.read': 'deny',
},
},
},
})
expect(proposalResponse.ok()).toBeTruthy()
const proposalPayload = await proposalResponse.json()
expect(proposalPayload.success).toBe(true)
const approvalId = proposalPayload.approvalTicket?.id as string
expect(typeof approvalId).toBe('string')
const approveResponse = await request.post(`/api/admin/approvals/${approvalId}/decision`, {
headers,
data: {
decision: 'approved',
comment: 'approved by playwright e2e',
},
})
expect(approveResponse.ok()).toBeTruthy()
const approvePayload = await approveResponse.json()
expect(approvePayload.success).toBe(true)
expect(approvePayload.approvalTicket?.status).toBe('approved')
const secondRunResponse = await request.post('/api/agent/goals', {
headers,
data: {
goal: 'Use web_read capability to read website https://example.com and extract key points.',
preferredAgentId: 'agent.discovery.scout',
},
})
expect(secondRunResponse.ok()).toBeTruthy()
const secondRun = await secondRunResponse.json()
expect(secondRun.success).toBe(true)
const webReadCalls = secondRun.toolCalls.filter(
(call: { resourceId: string }) =>
call.resourceId === 'mcp.agent_browser.read' ||
call.resourceId === 'tool.web.read' ||
call.resourceId === 'tool.web.search'
)
expect(webReadCalls.length).toBeGreaterThan(0)
expect(webReadCalls.some((call: { resourceId: string }) => call.resourceId === 'tool.web.read')).toBe(
true
)
const allReasons: string[] = secondRun.toolCalls.flatMap((call: { reasons?: string[] }) =>
Array.isArray(call.reasons) ? call.reasons : []
)
expect(allReasons.some((reason) => reason.startsWith('fallback_low_trust:'))).toBe(true)
const secondRunId = secondRun.run?.id as string
const logResponse = await request.get(`/api/admin/logs/tool-calls?runId=${secondRunId}`, {
headers,
})
expect(logResponse.ok()).toBeTruthy()
const logPayload = await logResponse.json()
expect(logPayload.success).toBe(true)
expect(logPayload.toolCalls.length).toBeGreaterThan(0)
await page.goto('/en/admin/chat')
await expect(page.getByText('Agent Gateway Chat Console')).toBeVisible()
})
})