diff --git a/apps/world-lab/src/components/world-lab.test.tsx b/apps/world-lab/src/components/world-lab.test.tsx index 9070134..216cb2d 100644 --- a/apps/world-lab/src/components/world-lab.test.tsx +++ b/apps/world-lab/src/components/world-lab.test.tsx @@ -1,4 +1,4 @@ -import { render, screen, waitFor } from '@testing-library/react'; +import { render, screen, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { simulationSnapshotSchema } from '@hexzero/shared'; @@ -351,4 +351,53 @@ describe('WorldLab swarm workspace', () => { screen.getByRole('button', { name: 'Download JSON' }), ).toBeDisabled(); }); + + it('model console shows exactly one Agent Zero planner row and no per-agent override controls', async () => { + vi.stubGlobal( + 'fetch', + vi.fn(() => response(snapshot)), + ); + const user = userEvent.setup(); + render(); + await user.click(await screen.findByLabelText('More World Lab actions')); + await user.click(screen.getByRole('button', { name: 'Agent setup' })); + const trigger = await screen.findByRole('button', { + name: /Agent Zero model/, + }); + await user.click(trigger); + const dialog = await screen.findByRole('dialog', { + name: 'Agent Zero model selection', + }); + expect(dialog).toBeVisible(); + await user.click(screen.getByRole('tab', { name: 'Overview' })); + expect(within(dialog).getByText('Agent Zero')).toBeVisible(); + for (const { name } of world.agents) { + expect(within(dialog).queryByText(name)).not.toBeInTheDocument(); + } + await user.click(screen.getByRole('tab', { name: 'Models' })); + expect(screen.queryByText('Agent overrides')).not.toBeInTheDocument(); + expect( + screen.queryByText('Apply global model to all agents'), + ).not.toBeInTheDocument(); + }); + + it('export dialog offers JSON serialization but no agent / turn / level / outcome / action filters', async () => { + vi.stubGlobal( + 'fetch', + vi.fn(() => response(snapshot)), + ); + const user = userEvent.setup(); + render(); + await user.click(await screen.findByLabelText('More World Lab actions')); + await user.click(screen.getByRole('button', { name: 'Export' })); + expect(screen.queryByText('Export level')).not.toBeInTheDocument(); + expect(screen.queryByText('Turn range')).not.toBeInTheDocument(); + expect(screen.queryByText('Outcomes')).not.toBeInTheDocument(); + expect(screen.queryByText('Actions')).not.toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Preview' })).toBeVisible(); + expect( + screen.getByRole('button', { name: 'Generate export' }), + ).toBeVisible(); + expect(screen.getByLabelText('JSON serialization')).toBeVisible(); + }); }); diff --git a/apps/world-lab/src/components/world-lab.tsx b/apps/world-lab/src/components/world-lab.tsx index 8896e78..9ffece9 100644 --- a/apps/world-lab/src/components/world-lab.tsx +++ b/apps/world-lab/src/components/world-lab.tsx @@ -3,7 +3,6 @@ import { useCallback, useEffect, - useLayoutEffect, useMemo, useRef, useState, @@ -32,7 +31,6 @@ import { defaultWorldSetupResponseSchema, WORLD_RADIUS_PRESETS, type AgentId, - type CustomExportOptions, type ExperimentExportDocument, type ExperimentExportPreview, type ExperimentExportRequest, @@ -98,7 +96,6 @@ export function WorldLab() { const [uiError, setUiError] = useState(null); const [exportOpen, setExportOpen] = useState(false); const [setupOpen, setSetupOpen] = useState(false); - const [exportAgentIds, setExportAgentIds] = useState([]); const [catalog, setCatalog] = useState(null); const [catalogLoading, setCatalogLoading] = useState(false); const [configurationPending, setConfigurationPending] = useState(false); @@ -115,7 +112,6 @@ export function WorldLab() { const mutationSequenceRef = useRef(0); const runningRef = useRef(false); const configurationPendingRef = useRef(false); - const exportInitializedRef = useRef(false); const exportTriggerRef = useRef(null); const modeTriggerRef = useRef(null); const setupTriggerRef = useRef(null); @@ -595,7 +591,6 @@ export function WorldLab() { ? 'running' : 'paused'; const activeTick = snapshot.status === 'waiting-for-model'; - const swarmMode = true; const terminal = snapshot.status === 'patient-zero-captured' || snapshot.status === 'infection-eliminated'; @@ -611,9 +606,6 @@ export function WorldLab() { activeTick; const modelsReady = Boolean(zeroModel?.available); const executionReady = modelsReady; - const reasoningUnavailable = snapshot.resolvedModels.some( - ({ issue }) => issue === 'reasoning-unavailable', - ); return (
State
{status.replaceAll('-', ' ')}
- {swarmMode ? ( -
-
Retained swarm ticks
-
{snapshot.swarmTicks?.length ?? 0}
-
- ) : ( -
-
Retained turns
-
{snapshot.swarmTicks?.length ?? 0}
-
- )} - {!swarmMode && ( -
-
Patient Zero
-
- {snapshot.world.agents.find( - ({ id }) => id === snapshot.scenario.patientZeroAgentId, - )?.name ?? 'None'} -
-
- )} +
+
Retained swarm ticks
+
{snapshot.swarmTicks?.length ?? 0}
+
Provider attempts
@@ -768,24 +743,13 @@ export function WorldLab() {
)} - {!swarmMode && ( -
-
Tokens
-
- {snapshot.experiment.metrics.aggregate.tokens.totalTokens ?? - 'Unknown'} -
-
- )} - {swarmMode && ( -

- Jev reports tokens but no monetary cost. Its unknown-cost - attempts retain the configured admission reserve in exposure; - that reserve is not a provider bill. The reported cost above - includes OpenRouter amounts only when returned by the provider. -

- )} +

+ Jev reports tokens but no monetary cost. Its unknown-cost attempts + retain the configured admission reserve in exposure; that reserve + is not a provider bill. The reported cost above includes + OpenRouter amounts only when returned by the provider. +