Commit Graph

677 Commits

Author SHA1 Message Date
Jordan Ritter 6a4c25a24d fix: add nested sub-agent fixtures for D5 mcp-subagents demo
Add 3 fixtures for the independent LLM calls made by each sub-agent
tool (research_agent, writing_agent, critique_agent) so the demo works
without --proxy-only mode. Interleave them with supervisor fixtures for
readability. Rebuild d5-all.json bundle.
2026-04-28 20:45:00 -07:00
Jordan Ritter bd0b32525f fix: resolve merge conflict in aimock-wiring.ts (ops→harness rename + starter exclusions) 2026-04-28 19:55:29 -07:00
Jordan Ritter abf835d327 fix(showcase): migrate D5 fixtures from toolCallId to turnIndex (#4404)
## Summary

Migrates all D5 (e2e-deep) fixtures from the `toolCallId` workaround (PR
#4398) to aimock's native `turnIndex` matching shipped in v1.16.0.

- Removes all `toolCallId` match criteria from 9 fixture files (8 source
+ 1 bundle)
- Adds `turnIndex` values (counts assistant messages in request history)
- Reorders fixtures to natural 0→N reading order
- Response bodies and tool call IDs in responses untouched

## Why

`toolCallId` was a stateless workaround for the broken `sequenceIndex`
global counter. It required agent frameworks to return the exact
`tool_call_id` from the fixture response — if they generated their own
ID, the second-leg fixture never matched. This was the likely cause of
the remaining 10 e2e-deep failures (shared-state: 9, subagents: 8).

`turnIndex` counts `role: "assistant"` messages in the request's message
array. Zero server-side state, concurrent-safe,
fixture-ordering-insensitive, and agnostic to what `tool_call_id` the
agent framework generates.

## Test plan

- [ ] All JSON files parse successfully (validated locally)
- [ ] Merge to main → aimock restarts and fetches updated fixtures
- [ ] Trigger e2e-deep probe, verify improvement (expect shared-state +
subagents to fix)
2026-04-28 18:15:06 -07:00
Jordan Ritter a2bc64692f fix(showcase): migrate D5 fixtures from toolCallId to turnIndex
aimock v1.16.0 ships native turnIndex matching — counts assistant
messages in the request's message array instead of relying on
toolCallId in the last tool message. Stateless, concurrent-safe,
fixture-ordering-insensitive.

Removes all toolCallId match criteria from 9 D5 fixture files (8
source + 1 bundle), adds turnIndex values, and reorders fixtures
to natural 0→N reading order.
2026-04-28 18:10:25 -07:00
Jordan Ritter 00462bccbc fix(showcase): fix pre-existing test failures from smoke-red-tick deletion and e2e-deep timeout
The rename PR (#4388) deleted smoke-red-tick.yml from config/alerts/
and test/fixtures/rules/valid/ but left 16 tests referencing it:

- render-red-tick.test.ts: removed smoke-red-tick.yml from YAMLS array
  and deleted two smoke-specific tests (endpoint link rendering)
- rule-loader.test.ts: replaced smoke-red-tick.yml fixture references
  with agent-red-tick.yml; created matching valid fixture; removed the
  smoke-red-tick describe block from full YAML contract coverage
- e2e-deep.test.ts: increased timeout on failure_turn test from 5s to
  15s -- fillAndVerifySend retry loop (3 x 2s) exceeds 5s when
  stallEvaluate prevents user message count growth
2026-04-28 18:06:18 -07:00
Jordan Ritter 795a56953e fix(showcase): fix showcase-harness build — commander dep + cli runner type alignment
Add missing `commander` dependency to showcase-harness package.json
(imported in cli.ts but never declared). Add index signatures to
SmokeInput and ChatToolsInput interfaces in targets.ts so they satisfy
the `{ [k: string]: unknown }` constraint from the Zod `.passthrough()`
schemas used by the liveness and e2e-chat-tools drivers.
2026-04-28 17:55:46 -07:00
Jordan Ritter 57988fe9bc fix: persistent browser pool to eliminate Chromium thundering herd (#4343)
## Summary

- Pre-launches 4 Chromium instances at service boot; probes check
out/return `BrowserContext` handles instead of spawning fresh processes
per tick
- Eliminates `pthread_create: EAGAIN` failures when multiple e2e probes
fire simultaneously (root cause of crewai-crews + langgraph-fastapi
timeouts at aligned cron ticks)
- Recycles browsers after 100 contexts (configurable via
`BROWSER_POOL_RECYCLE_AFTER`) to prevent native memory drift
- Staggers e2e-demos cron from minute 0 → minute 5 to reduce probe
alignment overlap

## Validation

- **Benchmark**: 1.16x speedup, +46MB resident cost, recycling at 55ms
with zero degradation
- **Docker red-green test**: Pool of 4 browsers serving 12 simultaneous
contexts succeeds under the same `ulimit nproc` constraint that causes
12 simultaneous `chromium.launch()` to fail with EAGAIN
- **Test suite**: 1320 tests pass, typecheck + build clean

## Test plan

- [ ] Verify showcase-ops builds and deploys on Railway
- [ ] Monitor next e2e-smoke + e2e-deep overlap tick for absence of
EAGAIN errors
- [ ] Confirm pool stats visible in /metrics endpoint (future: expose
pool.stats())
- [ ] Verify e2e-demos fires at :05 past the hour instead of :00
2026-04-28 17:49:11 -07:00
Jordan Ritter a75f4c5258 feat(showcase): local CLI for Dn parity testing (#4396)
## Summary

- Adds a local CLI (`showcase/harness/src/cli.ts`) that lets developers
run Dn parity tests against Docker Compose containers without Railway or
CI
- Hardens `docker-compose.local.yml` with YAML anchors, healthchecks on
all 20 services, profiles, and switches aimock to the published GHCR
image
- CLI supports `up`/`down`/`test`/`rebuild`/`ps`/`logs`/`status`
commands with `--smoke`/`--d4`/`--d5` shorthand flags

## Why

Debugging Dn failures currently requires pushing to a branch and waiting
for CI + Railway. This gives Claude and developers a fully local loop:
`showcase test --d5 langgraph-python` spins up the container, runs
probes, and reports results in seconds. Three use cases: (1) Claude
debugging Dn failures by cutting Railway out of the loop, (2) developers
building new columns/cells/rows and testing iteratively, (3) background
automation testing during development.

## What changed

| Commit | Area |
|--------|------|
| `fix(showcase): harden docker-compose.local.yml` |
x-integration-defaults anchor, aimock→GHCR, healthchecks, profiles,
pocketbase/dashboard infra |
| `feat: CLI entry point + config` | Commander CLI, flags, mutual
exclusion, config loader |
| `feat: lifecycle manager` | Profile-aware compose wrapper, ENOENT
detection, caching |
| `feat: target resolution` | Driver input builders, manifest validation
|
| `feat: test runner` | Probe orchestration, Playwright adapter, SIGINT,
PB reuse |
| `feat: results formatter` | Console table output, createPbWriter
factory |
| `chore: format` | oxfmt cleanup |

## Test plan

- [ ] `docker compose -f showcase/docker-compose.local.yml --profile
infra up -d` starts aimock + pocketbase + dashboard with healthchecks
passing
- [ ] `docker compose -f showcase/docker-compose.local.yml --profile
langgraph-python up -d` starts the integration container and depends_on
aimock healthy
- [ ] CLI `--smoke` and `--level smoke` produce equivalent behavior
- [ ] CLI `--smoke --level d4` exits with mutual exclusion error
- [ ] `down` with no args tears down all profiled services
- [ ] `isRunning` correctly reports infra services (which have
`["infra", "all"]` profiles, not per-name profiles)
2026-04-28 17:46:40 -07:00
Jordan Ritter 9241c50190 chore(showcase): format CLI files with oxfmt 2026-04-28 17:09:06 -07:00
Jordan Ritter c95bf2384e feat(showcase): add results formatter with PocketBase writer factory
Table-formatted console output for probe results. createPbWriter
factory enables client reuse across multiple result writes in a single
test run.
2026-04-28 17:07:06 -07:00
Jordan Ritter 033450240d feat(showcase): add local test runner with Playwright adapter
Orchestrates probe execution across liveness/D4/D5 levels. SIGINT
handler installed before container startup. Simplified headed Playwright
adapter using Object.assign+getDiagnostics passthrough. PocketBase
client reuse via createPbWriter for reduced auth overhead.
2026-04-28 17:07:02 -07:00
Jordan Ritter 9554256952 feat(showcase): add target resolution and driver input builders
Resolves CLI slug arguments to probe driver inputs for liveness, D4,
and D5 levels. Validates manifest demos and features arrays. Filters
empty feature lists from deep inputs.
2026-04-28 17:06:54 -07:00
Jordan Ritter bee0ba1d16 feat(showcase): add Docker Compose lifecycle manager
Profile-aware compose wrapper with ENOENT detection for missing Docker.
Handles up/down/rebuild/ps/logs with correct --profile flags for both
targeted slugs and full-stack operations. Caches loadPortsFile result.
stageSharedModules wrapped in try/finally for cleanup on failure.
2026-04-28 17:06:49 -07:00
Jordan Ritter 43d574113a feat(showcase): add local CLI entry point and config loader
Commander-based CLI with up/down/test/rebuild/ps/logs/status commands.
Shorthand flags (--smoke, --d4, --d5) with mutual exclusion against
--level. Default test level is smoke. Config loader reads
showcase.local.json for PocketBase and port overrides.
2026-04-28 17:06:44 -07:00
Jordan Ritter bd32bcff78 fix(showcase): replace sequenceIndex with toolCallId in D5 fixtures
aimock sequenceIndex counter is server-global, causing fixture match
failures when multiple integrations run concurrently. Replace with
stateless toolCallId matching.
2026-04-28 16:55:46 -07:00
github-actions[bot] 9b3253df0c style: auto-fix formatting 2026-04-28 23:34:04 +00:00
Jordan Ritter f6f90595f7 fix: correct recycleSlot mutation ordering and always shutdown pool
Move the isShutdown check before slot mutation in recycleSlot to prevent
a double-close race where shutdown() closes a browser that was already
assigned to the slot and mapped in browserToSlot.

Always call browserPool.shutdown() in the orchestrator stop path
regardless of browserPoolReady flag, so partially-initialized pools
(where init threw after launching some browsers) get cleaned up.
2026-04-28 16:32:20 -07:00
Jordan Ritter a821e637a9 fix: address CR findings in BrowserPool — shutdown guards, acquire timeout, recycle recovery, init graceful degradation 2026-04-28 16:32:20 -07:00
github-actions[bot] 370fd854d5 style: auto-fix formatting 2026-04-28 16:32:20 -07:00
Jordan Ritter 86bf58cff4 fix: persistent browser pool to eliminate Chromium thundering herd
Pre-launch 4 Chromium instances at service boot and check out/return
BrowserContext handles instead of spawning fresh processes per probe.
Eliminates the pthread_create EAGAIN failures when multiple e2e probes
fire simultaneously by capping concurrent Chromium processes at 4.

Pool recycles browsers after 100 contexts (configurable via
BROWSER_POOL_RECYCLE_AFTER) to prevent native memory drift.

Also staggers e2e-demos cron from minute 0 to minute 5 to reduce
probe alignment overlap.
2026-04-28 16:31:59 -07:00
Jordan Ritter 3bfe757f11 fix(showcase): remove false-pass assistant-message selector from tool card cascade 2026-04-28 16:23:37 -07:00
Jordan Ritter 9ce4c6e8e8 fix(showcase): relax D5 assertions for cross-integration compatibility
Remove the "Tokyo" city label check from d5-tool-rendering's
validateProbe — some integrations render the weather card with
only temperature and condition, omitting the city name from the
card element's textContent. The card structure (selector matched,
numeric temperature, childCount >= 1) is the real D5 signal.

Reduce d5-mcp-subagents EXPECTED_REPLY_FRAGMENTS from 5 exact
phrases to 2 ("remote work", "talent pool") — some integration
runtimes truncate or rephrase the streamed text so the original
verbose fragments caused false negatives. The D5 signal is chain
completion, not exact phrase fidelity.

Tests updated to match the relaxed assertions.
2026-04-28 16:23:37 -07:00
Jordan Ritter 1406268f7f fix(showcase): add send-verification retry loop to conversation runner 2026-04-28 16:23:37 -07:00
github-actions[bot] a8c38ceb79 style: auto-fix formatting 2026-04-28 23:06:06 +00:00
Jordan Ritter c62dd66dc4 Merge remote-tracking branch 'origin/main' into blitz/showcase-harness-rename/integration
# Conflicts:
#	pnpm-lock.yaml
#	showcase/harness/config/alerts/smoke-red-tick.yml
#	showcase/harness/scripts/test-notify-harness-jq.sh
#	showcase/harness/src/probes/drivers/e2e-chat-tools.test.ts
#	showcase/harness/src/probes/drivers/e2e-chat-tools.ts
#	showcase/harness/src/probes/drivers/e2e-demos.test.ts
#	showcase/harness/src/probes/drivers/e2e-demos.ts
#	showcase/harness/src/probes/drivers/e2e-readiness.test.ts
#	showcase/harness/src/probes/drivers/e2e-readiness.ts
#	showcase/harness/src/probes/drivers/e2e-smoke.test.ts
#	showcase/harness/src/probes/drivers/e2e-smoke.ts
#	showcase/harness/src/probes/drivers/liveness.test.ts
#	showcase/harness/src/probes/drivers/liveness.ts
#	showcase/harness/src/probes/drivers/smoke.test.ts
#	showcase/harness/src/probes/drivers/smoke.ts
#	showcase/harness/src/probes/liveness.test.ts
#	showcase/harness/src/probes/liveness.ts
#	showcase/harness/src/probes/smoke.test.ts
#	showcase/harness/src/probes/smoke.ts
#	showcase/harness/test/fixtures/rules/valid/smoke-red-tick.yml
#	showcase/ops/src/probes/drivers/e2e-demos.test.ts
#	showcase/ops/src/probes/drivers/e2e-demos.ts
#	showcase/ops/src/probes/drivers/e2e-smoke.test.ts
#	showcase/ops/src/probes/drivers/e2e-smoke.ts
#	showcase/ops/src/probes/drivers/smoke.test.ts
#	showcase/ops/src/probes/drivers/smoke.ts
#	showcase/ops/src/probes/smoke.test.ts
#	showcase/ops/src/probes/smoke.ts
#	showcase/scripts/verify-railway-image-refs.ts
2026-04-28 16:04:44 -07:00
Jordan Ritter 9f25dd6f5c chore(showcase): format harness test files with oxfmt 2026-04-28 13:50:55 -07:00
Jordan Ritter 0522b7fa41 refactor(showcase): rename showcase/ops → showcase/harness
The monitoring/alerting service is a test harness (probes, assertions,
alerting), not an operations service. Rename the directory, package
name (@copilotkit/showcase-ops → @copilotkit/showcase-harness), all
internal references (Dockerfile, Prometheus metric prefix
showcase_ops_ → showcase_harness_, orchestrator log messages, probe
YAML nameExcludes, test fixtures), and regenerate pnpm-lock.yaml.

Wire protocol names (X-Ops-* headers) and shell-dashboard internal
API naming (OPS_BASE_URL, ops-api.ts) are intentionally unchanged —
they are stable contracts between sender and receiver.
2026-04-28 13:48:12 -07:00