diff --git a/config/scripts/ci/sharding/ci-shard-timings.json b/config/scripts/ci/sharding/ci-shard-timings.json index 0df9e76c876..4b124d87adf 100644 --- a/config/scripts/ci/sharding/ci-shard-timings.json +++ b/config/scripts/ci/sharding/ci-shard-timings.json @@ -7298,7 +7298,6 @@ "src/shared/agent-status/transport/agent-status-osc-pending-retention.test.ts": 154, "src/shared/agent-status/transport/agent-status-osc.test.ts": 104, "src/shared/agent-status/store/agent-status-store-reopen.test.ts": 199, - "src/shared/agent-status/contracts/agent-status-subject.test.ts": 171, "src/shared/agent-status/title/agent-status-tracker-program-activity.test.ts": 77, "src/shared/agent-launch/startup/agent-tui-input-clear.test.ts": 57, "src/shared/ai-vault/resume/ai-vault-resume-command.test.ts": 70, diff --git a/config/scripts/performance/agent-lineage/agent-inspection-cadence-batching-benchmark.mjs b/config/scripts/performance/agent-lineage/agent-inspection-cadence-batching-benchmark.mjs deleted file mode 100644 index ac0f0ec31af..00000000000 --- a/config/scripts/performance/agent-lineage/agent-inspection-cadence-batching-benchmark.mjs +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env node -// Measure real cadence picker against independent ±10% jitter over simulated time. -// TTL-deduped same-tick work shares one capture, so count distinct wake instants rather than pane wakes. -import { spawnSync } from 'node:child_process' -import fs from 'node:fs' -import nodeModule from 'node:module' -import path from 'node:path' -import process from 'node:process' -import { fileURLToPath, pathToFileURL } from 'node:url' - -if (!process.execArgv.includes('--experimental-transform-types')) { - const result = spawnSync( - process.execPath, - ['--experimental-transform-types', '--no-warnings', import.meta.filename], - { stdio: 'inherit' } - ) - process.exit(result.status ?? 1) -} - -nodeModule.registerHooks({ - resolve(specifier, context, nextResolve) { - if (specifier.startsWith('.') && !/\.[cm]?[jt]s$/.test(specifier) && context.parentURL) { - const candidate = new URL(`${specifier}.ts`, context.parentURL) - if (fs.existsSync(fileURLToPath(candidate))) { - return { url: candidate.href, shortCircuit: true } - } - } - return nextResolve(specifier, context) - } -}) - -const ROOT = path.resolve(import.meta.dirname, '../../../..') -const WINDOW_MS = Number(process.env.ORCA_INSPECTION_BENCH_WINDOW_MS ?? '60000') -const PANE_COUNTS = (process.env.ORCA_INSPECTION_BENCH_PANES ?? '1,2,4,8') - .split(',') - .map((value) => Number(value.trim())) - -if (!Number.isSafeInteger(WINDOW_MS) || WINDOW_MS <= 0) { - throw new Error(`ORCA_INSPECTION_BENCH_WINDOW_MS must be a positive integer, got ${WINDOW_MS}`) -} -for (const paneCount of PANE_COUNTS) { - if (!Number.isSafeInteger(paneCount) || paneCount <= 0) { - throw new Error(`ORCA_INSPECTION_BENCH_PANES entries must be positive, got ${paneCount}`) - } -} - -const { nextCadenceInspectionDelayMs } = await import( - pathToFileURL( - path.join( - ROOT, - 'src/renderer/src/components/terminal-pane/agent-completion/agent-completion-poll-interval.ts' - ) - ).href -) -const { POLL_TIER_INTERVAL_MS } = await import( - pathToFileURL( - path.join( - ROOT, - 'src/renderer/src/components/terminal-pane/agent-completion/agent-completion-poll-cadence.ts' - ) - ).href -) -const { PROCESS_TABLE_SNAPSHOT_MAX_STALENESS_MS } = await import( - pathToFileURL(path.join(ROOT, 'src/shared/process-table-snapshot-reader.ts')).href -) - -// Pre-change: independent ±10% jitter per pane, re-rolled on every reschedule. -function baselineDelayMs(baseMs) { - return Math.round(baseMs * (1 + (Math.random() * 0.2 - 0.1))) -} - -function simulate(paneCount, baseMs, pickDelay) { - const startedAt = 1_700_000_000_000 - const wakes = [] - for (let pane = 0; pane < paneCount; pane += 1) { - // Panes mount at arbitrary moments, which is what spreads them apart in the first place. - let clock = startedAt + Math.floor(Math.random() * baseMs) - while ((clock += pickDelay(baseMs, clock)) < startedAt + WINDOW_MS) { - wakes.push(clock) - } - } - // Snapshot TTL starts at actual capture, not epoch grid; nearby wakes reuse it. - let captures = 0 - let snapshotExpiresAt = -Infinity - for (const wakeAt of wakes.sort((left, right) => left - right)) { - if (wakeAt >= snapshotExpiresAt) { - captures += 1 - snapshotExpiresAt = wakeAt + PROCESS_TABLE_SNAPSHOT_MAX_STALENESS_MS - } - } - return captures -} - -function medianOf(rounds, run) { - const samples = Array.from({ length: rounds }, run).sort((left, right) => left - right) - return samples[Math.floor(samples.length / 2)] -} - -const baseMs = POLL_TIER_INTERVAL_MS.idle -console.log( - `Agent-completion cadence — whole-host \`ps\` captures over ${WINDOW_MS / 1000}s at the idle tier (${baseMs}ms)\n` -) -console.log('| visible panes | before | after | reduction |') -console.log('| --- | --- | --- | --- |') -for (const paneCount of PANE_COUNTS) { - const before = medianOf(21, () => simulate(paneCount, baseMs, baselineDelayMs)) - const after = medianOf(21, () => - simulate(paneCount, baseMs, (base, now) => - nextCadenceInspectionDelayMs({ - baseMs: base, - hasConsecutiveErrors: false, - alignToSharedGrid: true, - now - }) - ) - ) - // Short windows may yield no baseline captures; avoid meaningless division by zero. - const reduction = before > 0 ? `${(((before - after) / before) * 100).toFixed(0)}%` : 'n/a' - console.log(`| ${paneCount} | ${before} | ${after} | ${reduction} |`) -} - -// Detection latency must not regress: the grid deadline is always within one interval. -let worstDelay = 0 -for (let sample = 0; sample < 100_000; sample += 1) { - const now = 1_700_000_000_000 + sample * 7 - worstDelay = Math.max( - worstDelay, - nextCadenceInspectionDelayMs({ - baseMs, - hasConsecutiveErrors: false, - alignToSharedGrid: true, - now - }) - ) -} -if (worstDelay > baseMs) { - throw new Error(`grid alignment delayed a poll to ${worstDelay}ms, above the ${baseMs}ms tier`) -} -console.log( - `\nWorst observed wait: ${worstDelay}ms (tier interval ${baseMs}ms) — no inspection is ever delayed.` -) diff --git a/config/scripts/performance/agent-lineage/agent-lineage-cycle-cleanup-benchmark.mjs b/config/scripts/performance/agent-lineage/agent-lineage-cycle-cleanup-benchmark.mjs deleted file mode 100644 index 0693bc025a0..00000000000 --- a/config/scripts/performance/agent-lineage/agent-lineage-cycle-cleanup-benchmark.mjs +++ /dev/null @@ -1,90 +0,0 @@ -// Run: node --expose-gc config/scripts/agent-lineage-cycle-cleanup-benchmark.mjs [baseline-ref] -import assert from 'node:assert/strict' -import { execFileSync } from 'node:child_process' -import { readFile } from 'node:fs/promises' -import { performance } from 'node:perf_hooks' -import { transform } from 'esbuild' -import { buildCounterbalancedSchedule } from '../measurement/counterbalanced-benchmark-schedule.mjs' - -const sourcePath = 'src/renderer/src/components/dashboard/agent-row-lineage-model.ts' -const baseline = process.argv[2] ?? '20ab9950654' -const beforeSource = execFileSync('git', ['show', `${baseline}:${sourcePath}`], { - encoding: 'utf8', - windowsHide: true -}) -async function load(source) { - const { code } = await transform(source, { loader: 'ts', format: 'esm' }) - return (await import(`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`)) - .buildAgentRowLineageTree -} -const before = await load(beforeSource) -const after = await load(await readFile(sourcePath, 'utf8')) - -function row(index, parent) { - return { - paneKey: `pane-${index}`, - entry: { - terminalHandle: `term-${index}`, - orchestration: parent === undefined ? undefined : { parentPaneKey: `pane-${parent}` } - } - } -} - -// Exercise duplicate keys, disconnected cycles, missing parents, and handle fallback. -let seed = 7391 -function random(max) { - seed = (Math.imul(seed, 1664525) + 1013904223) >>> 0 - return seed % max -} -for (let sample = 0; sample < 500; sample++) { - const rows = Array.from({ length: 40 }, () => { - const value = row(random(30), random(40)) - value.entry.orchestration.parentTerminalHandle = `term-${random(40)}` - value.entry.orchestration.coordinatorHandle = `term-${random(40)}` - return value - }) - if (sample % 2 === 0) { - rows.unshift(row('root', undefined)) - } - assert.deepEqual(after(rows), before(rows)) -} - -const results = [] -for (const [topology, count] of [ - ['flat', 1000], - ['all-cycles', 1000], - ['mixed-cycles', 100], - ['mixed-cycles', 500], - ['mixed-cycles', 1000] -]) { - const rows = Array.from({ length: count }, (_, index) => - row(index, topology === 'flat' ? undefined : index ^ 1) - ) - if (topology === 'mixed-cycles') { - rows.unshift(row('root', undefined)) - } - assert.deepEqual(after(rows), before(rows)) - for (let warmup = 0; warmup < 30; warmup++) { - before(rows) - after(rows) - } - const samples = { before: [], after: [] } - for (const pair of buildCounterbalancedSchedule(8, 'before', 'after')) { - for (const arm of pair) { - global.gc?.() - const run = arm === 'before' ? before : after - const cpu = process.cpuUsage() - const start = performance.now() - for (let iteration = 0; iteration < 30; iteration++) { - run(rows) - } - const wallMs = (performance.now() - start) / 30 - const used = process.cpuUsage(cpu) - samples[arm].push({ wallMs, cpuMs: (used.user + used.system) / 30_000 }) - } - } - results.push({ topology, count, samples }) -} -console.log( - JSON.stringify({ baseline, node: process.version, parityGraphs: 500, results }, null, 2) -) diff --git a/config/scripts/performance/agent-lineage/agent-lineage-reachability-benchmark.mjs b/config/scripts/performance/agent-lineage/agent-lineage-reachability-benchmark.mjs deleted file mode 100644 index bf881a2be79..00000000000 --- a/config/scripts/performance/agent-lineage/agent-lineage-reachability-benchmark.mjs +++ /dev/null @@ -1,118 +0,0 @@ -import assert from 'node:assert/strict' -import { readFileSync } from 'node:fs' -import { performance } from 'node:perf_hooks' -import { transform } from 'esbuild' -import { buildCounterbalancedSchedule } from '../measurement/counterbalanced-benchmark-schedule.mjs' -import { summarizeBenchmarkSamples } from '../measurement/benchmark-sample-summary.mjs' - -// git show :src/renderer/src/components/dashboard/agent-row-lineage-model.ts | node config/scripts/agent-lineage-reachability-benchmark.mjs -async function load(source) { - const { code } = await transform(source, { loader: 'ts', format: 'esm' }) - return (await import(`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`)) - .buildAgentRowLineageTree -} -const implementations = { - before: await load(readFileSync(0, 'utf8')), - after: await load( - readFileSync('src/renderer/src/components/dashboard/agent-row-lineage-model.ts', 'utf8') - ) -} -function orderedTree(tree) { - return { - roots: tree.rootRows, - children: [...tree.childrenByParentPaneKey], - childKeys: [...tree.childPaneKeys] - } -} - -let seed = 42 -const random = (max) => { - seed = (Math.imul(seed, 1664525) + 1013904223) >>> 0 - return Math.floor((seed / 2 ** 32) * max) -} -let differentialCases = 0 -for (let trial = 0; trial < 5000; trial += 1) { - const count = random(100) - const rows = Object.freeze( - Array.from({ length: count }, (_, index) => - Object.freeze({ - paneKey: `pane-${random(count + 4)}`, - index, - entry: Object.freeze({ - terminalHandle: random(2) ? `term-${random(count)}` : undefined, - orchestration: Object.freeze({ - parentPaneKey: random(3) ? `pane-${random(count + 4)}` : undefined, - parentTerminalHandle: random(2) ? `term-${random(count)}` : undefined, - coordinatorHandle: random(2) ? `term-${random(count)}` : undefined - }) - }) - }) - ) - ) - assert.deepEqual( - orderedTree(implementations.after(rows)), - orderedTree(implementations.before(rows)) - ) - differentialCases += 1 -} - -const results = [] -for (const count of [8, 32, 128, 512, 1024]) { - for (const topology of ['flat', 'fanout', 'balanced', 'chain']) { - const rows = Array.from({ length: count }, (_, index) => { - const parent = - topology === 'fanout' - ? 0 - : topology === 'balanced' - ? Math.floor((index - 1) / 4) - : index - 1 - return { - paneKey: `pane-${index}`, - entry: { - orchestration: - index > 0 && topology !== 'flat' ? { parentPaneKey: `pane-${parent}` } : undefined - } - } - }) - const expected = orderedTree(implementations.before(rows)) - assert.deepEqual(orderedTree(implementations.after(rows)), expected) - const iterations = Math.max(5, Math.floor(10_000 / count)) - for (let warmup = 0; warmup < 20; warmup += 1) { - implementations.before(rows) - implementations.after(rows) - } - /** @type {{ before: number[], after: number[] }} */ - const samples = { before: [], after: [] } - for (const pair of buildCounterbalancedSchedule(8, 'before', 'after')) { - for (const arm of pair) { - let result - const started = performance.now() - for (let repeat = 0; repeat < iterations; repeat += 1) { - result = implementations[arm](rows) - } - samples[arm].push(performance.now() - started) - assert.deepEqual(orderedTree(result), expected) - } - } - results.push({ - count, - topology, - iterations, - meanMicrosecondsPerTree: Object.fromEntries( - Object.entries(samples).map(([arm, values]) => [ - arm, - (values.reduce((sum, ms) => sum + ms, 0) * 1000) / values.length / iterations - ]) - ), - before: summarizeBenchmarkSamples(samples.before), - after: summarizeBenchmarkSamples(samples.after) - }) - } -} -console.log( - JSON.stringify( - { node: process.version, platform: process.platform, differentialCases, results }, - null, - 2 - ) -) diff --git a/package.json b/package.json index faf04c0f277..ef3a28bdc7d 100644 --- a/package.json +++ b/package.json @@ -208,7 +208,6 @@ "bench:hang-watchdog-memory": "pnpm run ensure:electron-runtime && node config/scripts/diagnostics/hang-watchdog/hang-watchdog-memory-benchmark.mjs", "bench:main-thread-jank": "pnpm run ensure:electron-runtime && node tests/tools/benchmarks/main-thread-jank-bench.mjs", "bench:zustand-selector-fanout": "node config/scripts/performance/renderer-projection/zustand-selector-fanout-benchmark.mjs", - "bench:agent-inspection-cadence": "node config/scripts/performance/agent-lineage/agent-inspection-cadence-batching-benchmark.mjs", "bench:renderer-quadratic-scans": "node config/scripts/performance/renderer-markdown/renderer-quadratic-scan-benchmark.mjs", "bench:session-write-hot-path": "node config/scripts/performance/session-transcripts/session-write-hot-path-benchmark.mjs", "bench:terminal-partial-escape-tail": "node config/scripts/performance/terminal-stream/terminal-partial-escape-tail-benchmark.mjs", diff --git a/src/main/browser/agent-browser/commands/agent-browser-bridge-keypress-input.test.ts b/src/main/browser/agent-browser/commands/agent-browser-bridge-keypress-input.test.ts index 5cee79cc2dc..42896945463 100644 --- a/src/main/browser/agent-browser/commands/agent-browser-bridge-keypress-input.test.ts +++ b/src/main/browser/agent-browser/commands/agent-browser-bridge-keypress-input.test.ts @@ -79,7 +79,8 @@ describe('AgentBrowserBridge keypress input', () => { webContentsFromIdMock.mockImplementation((id: number) => (id === 100 ? wc : null)) }) - describe.each(['a', 'MediaPlayPause'])('target admission for %s', (key) => { + describe('target admission', () => { + const key = 'a' function registerTwoWorkspaces(): MockWebContents { const otherPage = mockWebContents(200) otherPage.debugger.sendCommand.mockResolvedValue({}) diff --git a/src/main/browser/agent-browser/helper-process/agent-browser-bridge-cdp-endpoint.test.ts b/src/main/browser/agent-browser/helper-process/agent-browser-bridge-cdp-endpoint.test.ts deleted file mode 100644 index 7c08b8cf623..00000000000 --- a/src/main/browser/agent-browser/helper-process/agent-browser-bridge-cdp-endpoint.test.ts +++ /dev/null @@ -1,110 +0,0 @@ -import type * as BrowserErrorTypes from '../../browser-error' -import { describe, it, expect, vi, beforeEach } from 'vitest' - -const { execFileMock, webContentsFromIdMock, existsSyncMock, readFileSyncMock, stdinWrites } = - vi.hoisted(() => ({ - execFileMock: vi.fn(), - webContentsFromIdMock: vi.fn(), - existsSyncMock: vi.fn(() => false), - readFileSyncMock: vi.fn(() => Buffer.from('')), - stdinWrites: new Array() - })) - -vi.mock('child_process', () => ({ execFile: execFileMock })) -vi.mock('fs', () => ({ - existsSync: existsSyncMock, - readFileSync: readFileSyncMock, - accessSync: vi.fn(), - chmodSync: vi.fn(), - constants: { X_OK: 1 } -})) -vi.mock('os', () => ({ platform: () => 'darwin', arch: () => 'arm64' })) -vi.mock('electron', () => { - return { - app: { getPath: vi.fn(() => '/app'), getAppPath: vi.fn(() => '/project'), isPackaged: false }, - webContents: { fromId: webContentsFromIdMock } - } -}) -const { CdpWsProxyMock, proxyStops } = vi.hoisted(() => { - const instances: unknown[] = [] - const proxyStops: ReturnType[] = [] - const MockClass = vi.fn().mockImplementation(function ( - this: Record, - _wc: unknown - ) { - this._wc = _wc - const endpoint = `ws://127.0.0.1:9222/token-${instances.length}` - this.start = vi.fn(async () => endpoint) - const stop = vi.fn(async () => {}) - this.stop = stop - proxyStops.push(stop) - this.getPort = vi.fn(() => 9222) - instances.push(this) - }) - return { CdpWsProxyMock: Object.assign(MockClass, { instances }), proxyStops } -}) - -vi.mock('../../cdp/transport/cdp-ws-proxy', () => ({ - CdpWsProxy: CdpWsProxyMock -})) -vi.mock('../../browser-error', () => ({ - BrowserError: class BrowserError extends Error { - code: string - constructor(code: string, message: string) { - super(message) - this.code = code - } - } -})) - -vi.mock('../../cdp/commands/cdp-bridge', async () => { - const { BrowserError } = await vi.importMock('../../browser-error') - return { BrowserError } -}) - -import { AgentBrowserBridge } from '../agent-browser-bridge' -import { - mockBrowserManager, - overrideBridgeWebContentsLookup, - resetAgentBrowserBridgeMocks, - succeedRecordingAgentBrowserSpawns -} from '../testing/agent-browser-bridge-test-harness' - -overrideBridgeWebContentsLookup(AgentBrowserBridge.prototype, webContentsFromIdMock) - -// agent-browser only reaches Orca's proxy through AGENT_BROWSER_CDP; `--cdp ` drops the token path. -describe('AgentBrowserBridge CDP endpoint contract', () => { - let bridge: AgentBrowserBridge - - beforeEach(() => { - resetAgentBrowserBridgeMocks({ - webContentsFromIdMock, - existsSyncMock, - readFileSyncMock, - stdinWrites, - cdpWsProxyInstances: CdpWsProxyMock.instances - }) - proxyStops.length = 0 - bridge = new AgentBrowserBridge(mockBrowserManager()) - bridge.setActiveTab(100) - }) - - it('passes the tokened endpoint only through env, for batch and raw CLI spawns', async () => { - const spawns = succeedRecordingAgentBrowserSpawns(execFileMock, stdinWrites, { - snapshot: '' - }) - - await bridge.snapshot() - await bridge.exec('--cdp 4444 get title') - - // The stale-session reset only closes a daemon; it must not name any CDP target. - const [reset, ...commands] = spawns - expect(reset).toMatchObject({ command: ['close'], cdp: undefined }) - expect(commands.map(({ command }) => command[0])).toEqual(['snapshot', 'get']) - for (const spawn of commands) { - expect(spawn.cdp).toBe('ws://127.0.0.1:9222/token-0') - expect(spawn.args).not.toContain('--cdp') - expect(spawn.args.join(' ')).not.toContain('token-0') - } - }) -}) diff --git a/src/main/browser/agent-browser/helper-process/agent-browser-bridge-raw-process-retention.test.ts b/src/main/browser/agent-browser/helper-process/agent-browser-bridge-raw-process-retention.test.ts deleted file mode 100644 index 453c60719e5..00000000000 --- a/src/main/browser/agent-browser/helper-process/agent-browser-bridge-raw-process-retention.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as childProcess from 'node:child_process' -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { afterEach, beforeEach, expect, it, vi } from 'vitest' - -const { userDataPath } = vi.hoisted(() => ({ userDataPath: { current: '' } })) - -vi.mock('electron', () => ({ - app: { - getPath: vi.fn(() => userDataPath.current), - getAppPath: vi.fn(() => userDataPath.current), - isPackaged: false - } -})) - -vi.mock('node:child_process', async (importOriginal) => { - const actual = await importOriginal() - return { ...actual, execFile: vi.fn(actual.execFile) } -}) - -import { AgentBrowserBridge } from '../agent-browser-bridge' -import { mockBrowserManager } from '../testing/agent-browser-bridge-test-harness' - -let bridge: AgentBrowserBridge - -beforeEach(() => { - vi.clearAllMocks() - userDataPath.current = mkdtempSync(join(tmpdir(), 'orca-agent-browser-retention-')) - bridge = new AgentBrowserBridge(mockBrowserManager()) - Object.defineProperty(bridge, 'agentBrowserBin', { value: process.execPath, configurable: true }) -}) - -afterEach(() => { - vi.restoreAllMocks() - rmSync(userDataPath.current, { recursive: true, force: true }) -}) - -function run(script: string): Promise { - return bridge['runAgentBrowserRaw']('orca-tab-retention', ['-e', script]) -} - -function rememberChild(script: string) { - const spawn = vi.mocked(childProcess.execFile) - const pending = run(script) - const result = spawn.mock.results[0] - if (result?.type !== 'return') { - throw new Error('Expected a real helper process') - } - const child = new WeakRef(result.value) - // Mock call records must not keep the completed helper alive. - spawn.mockClear() - return { pending, child } -} - -async function collect(): Promise { - if (!global.gc) { - throw new Error('This retention test requires --expose-gc') - } - for (let turn = 0; turn < 5; turn++) { - await new Promise((resolve) => setImmediate(resolve)) - global.gc() - } -} - -it('releases the completed helper before the fallback deadline while its bridge stays usable', async () => { - const { pending, child } = rememberChild("process.stdout.write('complete')") - expect(await pending).toBe('complete') - await collect() - expect(child.deref()).toBeUndefined() - expect(await run("process.stdout.write('next')")).toBe('next') -}) diff --git a/src/main/speech/model-manager-progress-callback.test.ts b/src/main/speech/model-manager-progress-callback.test.ts deleted file mode 100644 index 49cff109461..00000000000 --- a/src/main/speech/model-manager-progress-callback.test.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { mkdtempSync, rmSync } from 'node:fs' -import { tmpdir } from 'node:os' -import { join } from 'node:path' -import { describe, expect, it, vi } from 'vitest' -import { ModelManager } from './model-manager' -import { openElectronSpeechDownloadRequest } from '../host/electron-speech-services' - -vi.mock('electron', () => ({ - app: { - getPath: () => '/tmp/orca-speech-models-test' - } -})) - -type ModelManagerInternals = { - updateState: ( - modelId: string, - status: 'not-downloaded' | 'downloading' | 'extracting' | 'ready' | 'error', - progress?: number, - error?: string - ) => void -} - -describe('ModelManager progress callbacks', () => { - it('unsubscribes progress callbacks without replacing other listeners', () => { - const dir = mkdtempSync(join(tmpdir(), 'orca-model-manager-')) - try { - const manager = new ModelManager(dir, openElectronSpeechDownloadRequest) - const internals = manager as unknown as ModelManagerInternals - const first = vi.fn() - const second = vi.fn() - const clearFirst = manager.setProgressCallback(first) - const clearSecond = manager.setProgressCallback(second) - - internals.updateState('model-a', 'downloading', 0.25) - clearFirst() - internals.updateState('model-a', 'extracting') - clearSecond() - internals.updateState('model-a', 'ready') - - expect(first).toHaveBeenCalledTimes(1) - expect(first).toHaveBeenCalledWith('model-a', 0.25) - expect(second).toHaveBeenCalledTimes(2) - expect(second).toHaveBeenNthCalledWith(1, 'model-a', 0.25) - expect(second).toHaveBeenNthCalledWith(2, 'model-a', 0.95) - } finally { - rmSync(dir, { recursive: true, force: true }) - } - }) - - it('coalesces per-chunk download progress to whole percent', () => { - const dir = mkdtempSync(join(tmpdir(), 'orca-model-manager-')) - try { - const manager = new ModelManager(dir, openElectronSpeechDownloadRequest) - const internals = manager as unknown as ModelManagerInternals - const listener = vi.fn() - manager.setProgressCallback(listener) - - // A 500MB model over a 64KB chunk stream reports this many times. - for (let chunk = 0; chunk < 8_000; chunk += 1) { - internals.updateState('model-a', 'downloading', chunk / 8_000) - } - - expect(listener.mock.calls.map(([, progress]) => progress)).toEqual( - Array.from({ length: 101 }, (_unused, percent) => percent / 100) - ) - const afterDownload = listener.mock.calls.length - internals.updateState('model-a', 'extracting') - internals.updateState('model-a', 'ready') - internals.updateState('model-a', 'ready') - expect(listener.mock.calls.length).toBe(afterDownload + 3) - } finally { - rmSync(dir, { recursive: true, force: true }) - } - }) -}) diff --git a/src/main/speech/node-speech-download-request.test.ts b/src/main/speech/node-speech-download-request.test.ts index 394f7802ccf..1ace63cedfa 100644 --- a/src/main/speech/node-speech-download-request.test.ts +++ b/src/main/speech/node-speech-download-request.test.ts @@ -64,15 +64,6 @@ describe('openNodeSpeechDownloadRequest', () => { expect(listeners.response).not.toHaveBeenCalled() }) - it('hands any other response to the download', () => { - const handle = openNodeSpeechDownloadRequest('https://models.example/a.tar.bz2') - const listeners = { error: vi.fn(), response: vi.fn(), redirect: vi.fn() } - handle.listen(listeners) - const ok = incoming(206, { 'content-range': 'bytes 10-19/20' }) - lastRequest().emit('response', ok) - expect(listeners.response).toHaveBeenCalledWith(ok) - }) - // Abort emits after detach; an unhandled ClientRequest error crashes orcad. it('swallows the error abort raises after the download detached', () => { const handle = openNodeSpeechDownloadRequest('https://models.example/a.tar.bz2') diff --git a/src/main/speech/openai-api-key-store.test.ts b/src/main/speech/openai-api-key-store.test.ts index 73dd4ff7ce0..26a2dfc56e1 100644 --- a/src/main/speech/openai-api-key-store.test.ts +++ b/src/main/speech/openai-api-key-store.test.ts @@ -46,15 +46,6 @@ function writeStoredOpenAiKey(value: string): void { } describe('OpenAI speech API key store', () => { - it('checks configured status without decrypting or touching safeStorage', async () => { - writeStoredOpenAiKey('encrypted-key') - const store = await loadStoreModule() - - expect(store.hasOpenAiSpeechApiKey()).toBe(true) - expect(safeStorageMock.isEncryptionAvailable).not.toHaveBeenCalled() - expect(safeStorageMock.decryptString).not.toHaveBeenCalled() - }) - // #31174: orcad cannot open a key the desktop sealed with safeStorage, so it must not say ready. it('reports a stored key this host cannot decrypt as unusable', async () => { writeStoredOpenAiKey('v10\u0000ÿþ sealed by another store') @@ -77,13 +68,4 @@ describe('OpenAI speech API key store', () => { expect(store.canReadOpenAiSpeechApiKey()).toBe(false) expect(() => store.readOpenAiSpeechApiKey()).toThrow('OpenAI API key could not be decrypted') }) - - it('caches the decrypted key so repeated dictations do not repeatedly touch safeStorage', async () => { - writeStoredOpenAiKey('encrypted-key') - const store = await loadStoreModule() - - expect(store.readOpenAiSpeechApiKey()).toBe('encrypted-key') - expect(store.readOpenAiSpeechApiKey()).toBe('encrypted-key') - expect(safeStorageMock.decryptString).toHaveBeenCalledOnce() - }) }) diff --git a/src/main/speech/stt-worker.test.ts b/src/main/speech/stt-worker.test.ts index 588ab88be72..91f5c8c5031 100644 --- a/src/main/speech/stt-worker.test.ts +++ b/src/main/speech/stt-worker.test.ts @@ -21,10 +21,4 @@ describe('resampleToRate', () => { expect(second[1]).toBeCloseTo(0.00625, 6) expect(second[80]).toBeCloseTo(0.5, 6) }) - - it('keeps same-rate chunks unchanged', () => { - const samples = new Float32Array([0, 0.5, -0.5]) - - expect(resampleToRate(samples, 16000, 16000)).toBe(samples) - }) }) diff --git a/src/renderer/src/components/dashboard/agent-row-lineage-model.test.ts b/src/renderer/src/components/dashboard/agent-row-lineage-model.test.ts index 8c97efe2039..75d2e5688dc 100644 --- a/src/renderer/src/components/dashboard/agent-row-lineage-model.test.ts +++ b/src/renderer/src/components/dashboard/agent-row-lineage-model.test.ts @@ -100,27 +100,6 @@ describe('buildAgentRowLineageTree', () => { }) describe('unreachable lineage cleanup', () => { - it('bounds pane-key reads while flattening disconnected cycles', () => { - let paneKeyReads = 0 - const root = makeRow('root') - const cycles = Array.from({ length: 200 }, (_, index) => { - const row = makeRow(`cycle-${index}`, { parentPaneKey: `cycle-${index ^ 1}` }) - Object.defineProperty(row, 'paneKey', { - get() { - paneKeyReads++ - return `cycle-${index}` - } - }) - return row - }) - const tree = buildAgentRowLineageTree([root, ...cycles]) - const measuredReads = paneKeyReads - expect(tree.rootRows).toEqual([root, ...cycles]) - expect(tree.childrenByParentPaneKey.size).toBe(0) - expect(tree.childPaneKeys.size).toBe(0) - expect(measuredReads).toBeLessThanOrEqual(cycles.length * 20) - }) - it('preserves reachable edges and promotes the first disconnected duplicate in input order', () => { const root = makeRow('root') const child = makeRow('child', { parentPaneKey: 'root' }) diff --git a/src/shared/agent-status/contracts/agent-status-subject.test.ts b/src/shared/agent-status/contracts/agent-status-subject.test.ts deleted file mode 100644 index 7ce69af0b45..00000000000 --- a/src/shared/agent-status/contracts/agent-status-subject.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { - agentStatusSubjectsEqual, - makePtyAgentStatusSubject, - makePtyRunAgentStatusSubject, - makeStructuredAgentStatusSubject, - serializeAgentStatusSubject, - type AgentStatusExecutionScope -} from './agent-status-subject' -const SESSION_ID = 'session_11111111-1111-4111-8111-111111111111' - -function scope(overrides: Partial = {}): AgentStatusExecutionScope { - return { - executionHostId: 'local', - wslDistro: null, - workspaceId: 'workspace-1', - workspaceKind: 'git-worktree', - ...overrides - } -} - -describe('agent status subjects', () => { - it('isolates identical identities across scope and subject kind', () => { - const identity = 'identity-1' - const subjects = [ - makePtyRunAgentStatusSubject(scope(), identity), - makePtyRunAgentStatusSubject(scope({ wslDistro: 'Ubuntu' }), identity), - makePtyRunAgentStatusSubject(scope({ executionHostId: 'ssh:target-a' }), identity), - makePtyRunAgentStatusSubject(scope({ executionHostId: 'runtime:peer-a' }), identity), - makePtyRunAgentStatusSubject(scope({ workspaceId: 'workspace-2' }), identity), - makePtyRunAgentStatusSubject(scope({ workspaceKind: 'folder' }), identity), - makePtyAgentStatusSubject(scope(), identity), - makeStructuredAgentStatusSubject(scope(), identity) - ] - - expect(new Set(subjects.map(serializeAgentStatusSubject))).toHaveLength(subjects.length) - for (const [index, subject] of subjects.entries()) { - for (const other of subjects.slice(index + 1)) { - expect(agentStatusSubjectsEqual(subject, other)).toBe(false) - } - } - }) - - it('keeps the existing structured-session encoding byte-for-byte stable', () => { - const serialized = serializeAgentStatusSubject( - makeStructuredAgentStatusSubject(scope(), SESSION_ID) - ) - - expect(serialized).toBe( - 'agent-status-subject-v1:["structured-session","local",null,"workspace-1","git-worktree","session_11111111-1111-4111-8111-111111111111"]' - ) - }) -}) diff --git a/src/shared/agent-status/title/agent-title-tracker.test.ts b/src/shared/agent-status/title/agent-title-tracker.test.ts index 466dd55c8ce..e991f64ffd7 100644 --- a/src/shared/agent-status/title/agent-title-tracker.test.ts +++ b/src/shared/agent-status/title/agent-title-tracker.test.ts @@ -43,13 +43,4 @@ describe('createAgentStatusTracker', () => { tracker.handleTitle('Cursor ready') expect(onBecameIdle).toHaveBeenCalledTimes(1) }) - - it('does not fire when Factory Droid reports needs input during a working turn', () => { - const onBecameIdle = vi.fn() - const tracker = createAgentStatusTracker(onBecameIdle) - - tracker.handleTitle('⠋ Droid') - tracker.handleTitle('Factory Droid needs input') - expect(onBecameIdle).not.toHaveBeenCalled() - }) }) diff --git a/src/shared/agent-status/title/providers/hermes-terminal-title.test.ts b/src/shared/agent-status/title/providers/hermes-terminal-title.test.ts deleted file mode 100644 index fcc3caab0fb..00000000000 --- a/src/shared/agent-status/title/providers/hermes-terminal-title.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { describe, expect, it } from 'vitest' -import { hermesNativeTitleStatus } from './hermes-terminal-title' - -describe('Hermes native session title markers', () => { - it.each([ - ['hermes', '✓ Run Orca dispatched worker … · grok-4.7 · ~/workspace', 'idle'], - ['hermes', '⏳ Ready to deploy', 'working'], - ['hermes', '⚠ Finished the changes', 'permission'], - ['hermes', '⚠️ Waiting for approval', 'permission'], - ['hermes', 'user@host: ~/workspace', null], - ['hermes', '✓not a status marker', null], - ['codex', '✓ Run Orca dispatched worker …', null], - [null, '✓ Run Orca dispatched worker …', null] - ] as const)('classifies %s title %s as %s', (agent, title, expected) => { - expect(hermesNativeTitleStatus(title, agent)).toBe(expected) - }) -}) diff --git a/src/shared/agent-status/transport/agent-status-osc.test.ts b/src/shared/agent-status/transport/agent-status-osc.test.ts index 3c61b0caad2..6b4523425a6 100644 --- a/src/shared/agent-status/transport/agent-status-osc.test.ts +++ b/src/shared/agent-status/transport/agent-status-osc.test.ts @@ -33,30 +33,4 @@ describe('createAgentStatusOscProcessor', () => { expect(lastOffset, `split ${split}`).toBe(expected.lastPayloadCleanOffset) } }) - - it('applies the pending cap only to incomplete frames', () => { - const marker = '\x1b]9999;{"state":"working"}' - const atCap = marker + ' '.repeat(64 * 1024 - marker.length) - const retained = createAgentStatusOscProcessor() - expect(retained(`before${atCap}`).cleanData).toBe('before') - expect(retained('\x1b')).toEqual({ cleanData: '', payloads: [], lastPayloadCleanOffset: null }) - expect(retained('\\after').cleanData).toBe('\\after') - - const exact = createAgentStatusOscProcessor() - exact(atCap) - expect(exact('\x07after')).toEqual({ - cleanData: 'after', - payloads: [{ state: 'working', prompt: '' }], - lastPayloadCleanOffset: 0, - payloadCleanOffsets: [0] - }) - - const complete = createAgentStatusOscProcessor() - expect(complete(`${atCap} \x1b\\after`)).toEqual({ - cleanData: 'after', - payloads: [{ state: 'working', prompt: '' }], - lastPayloadCleanOffset: 0, - payloadCleanOffsets: [0] - }) - }) })