Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ jobs:
- name: Run cockpit example aimock e2e suites
run: |
set -e
for proj in cockpit-langgraph-streaming-angular cockpit-chat-tool-calls-angular; do
for proj in cockpit-langgraph-streaming-angular cockpit-chat-tool-calls-angular cockpit-chat-subagents-angular; do
echo "::group::nx e2e $proj"
npx nx e2e "$proj" --skip-nx-cache
echo "::endgroup::"
Expand Down
3 changes: 3 additions & 0 deletions cockpit/chat/subagents/angular/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test-results/
playwright-report/
*.tmp
29 changes: 29 additions & 0 deletions cockpit/chat/subagents/angular/e2e/c-subagents.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
import { test, expect } from '@playwright/test';
import { sendPromptAndWait } from '../../../../../libs/internal/aimock-harness/src';

const PROMPT = 'Plan a trip from LAX to JFK';

test('c-subagents: orchestrator dispatches task subagents, summary surfaces in bubble', async ({
page,
}) => {
const bubble = await sendPromptAndWait(page, PROMPT);

// The chat-tool-calls primitive renders a collapsible button labeled
// "Called task N times" for the orchestrator's task dispatches. Asserting
// it's in the DOM proves the orchestrator emitted real task tool_calls.
//
// We don't assert on <chat-subagent-card> because that primitive only
// renders while a subagent is in a RUNNING state — once all subagents
// complete (which is the state sendPromptAndWait returns at, since the
// agent is idle), the cards are filtered out of the DOM. The tool-call
// chip is the durable signal.
const taskChip = page.getByRole('button', { name: /called task|task/i }).first();
await expect(taskChip).toBeVisible({ timeout: 30_000 });

// Final summary text contains an aviation-related phrase from the captured
// continuation. Loose regex so refactors to the subagent prompts (research/
// booking/itinerary outputs) don't break the test.
const finalText = await bubble.innerText();
expect(finalText.toLowerCase()).toMatch(/lax|jfk|itinerary|trip|flight/);
});
178 changes: 178 additions & 0 deletions cockpit/chat/subagents/angular/e2e/fixtures/c-subagents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
{
"fixtures": [
{
"match": {
"userMessage": "Plan a trip from LAX to JFK",
"model": "gpt-5-mini",
"turnIndex": 0,
"hasToolResult": false
},
"response": {
"toolCalls": [
{
"name": "task",
"arguments": "{\"role\":\"research\",\"task_description\":\"Gather info on LAX (Los Angeles International Airport) and JFK (John F. Kennedy International Airport). Include: major terminals used by typical carriers, ground transportation options at each airport, typical weather/temperature and conditions in New York (JFK) year-round and what to expect this time of year (assume current date May 2026), and any travel advisories or common delays for LAX-JFK route.\"}",
"id": "call_ScDzZETqORD2oBYSW1qz7Mk2"
}
]
},
"metadata": {
"systemHash": "13e1b238",
"toolsHash": "bca09fd7"
}
},
{
"match": {
"userMessage": "Gather info on LAX (Los Angeles International Airport) and JFK (John F. Kennedy International Airport). Include: major terminals used by typical carriers, ground transportation options at each airport, typical weather/temperature and conditions in New York (JFK) year-round and what to expect this time of year (assume current date May 2026), and any travel advisories or common delays for LAX-JFK route.",
"model": "gpt-5-mini",
"turnIndex": 0,
"hasToolResult": false
},
"response": {
"toolCalls": [
{
"name": "get_airport_info",
"arguments": "{\"airport_code\": \"LAX\"}",
"id": "call_jWLEa38IenhEVyK4O8qIcxtr"
},
{
"name": "get_airport_info",
"arguments": "{\"airport_code\": \"JFK\"}",
"id": "call_ijvxJqRmWdiOECD1wwOFSivZ"
}
]
},
"metadata": {
"systemHash": "bfabc0f4",
"toolsHash": "d00ddc0a"
}
},
{
"match": {
"userMessage": "Gather info on LAX (Los Angeles International Airport) and JFK (John F. Kennedy International Airport). Include: major terminals used by typical carriers, ground transportation options at each airport, typical weather/temperature and conditions in New York (JFK) year-round and what to expect this time of year (assume current date May 2026), and any travel advisories or common delays for LAX-JFK route.",
"model": "gpt-5-mini",
"turnIndex": 1,
"hasToolResult": true
},
"response": {
"content": "I looked up both airports: LAX (Los Angeles International) \u2014 9 terminals, current conditions about 72\u00b0F and partly cloudy \u2014 and JFK (John F. Kennedy International) \u2014 6 terminals, current conditions about 58\u00b0F and clear. Major carriers (typical terminal groupings) at LAX include American (Terminals 4\u20135), Delta (T2\u2013T3 and Tom Bradley for many intl. connections), United (T7\u2013T8), Southwest (primarily T1) and Tom Bradley/Terminal B handling most international carriers; at JFK, Delta is centered at T4, JetBlue at T5, American at T8, with many international carriers in T1/T7/T4. Ground transportation: LAX offers FlyAway buses to central LA, an on\u2011airport People Mover connection to Metro rail and the rental car center, taxis and designated rideshare areas; JFK is served by the AirTrain linking terminals to the LIRR (Jamaica) and NYC Subway (Howard Beach/Jamaica), plus taxis, app-based pick\u2011ups and shuttle/rental services. Typical NYC climate year\u2011round is cold, snowy winters and hot, humid summers with mild/transitional spring and fall; in May expect mild, springlike weather (roughly mid\u201150s to low\u201170s\u00b0F, occasional showers); the LAX\u2013JFK route is very busy and commonly sees ATC/airspace delays (NYC metro congestion), seasonal weather delays (winter snow nor\u2019easters or summer thunderstorms), and occasional long taxi/ground times at either airport \u2014 allow extra time, monitor status, and consider TSA PreCheck or earlier check\u2011in for smoother travel."
},
"metadata": {
"systemHash": "bfabc0f4",
"toolsHash": "d00ddc0a"
}
},
{
"match": {
"userMessage": "Plan a trip from LAX to JFK",
"model": "gpt-5-mini",
"turnIndex": 1,
"hasToolResult": true
},
"response": {
"toolCalls": [
{
"name": "task",
"arguments": "{\"role\":\"booking\",\"task_description\":\"Find flight options from LAX to JFK for one adult departing May 20, 2026, returning May 24, 2026. Provide 3 flight options: low-cost, balanced (good price and timing), and premium (more legroom or non\u2011stop at convenient times). Include airline, flight times (depart/arrive local), number of stops, total duration, and a rough price estimate in USD.\"}",
"id": "call_Q2EP65ATIaYLGdvQl0Ijj57K"
}
]
},
"metadata": {
"systemHash": "13e1b238",
"toolsHash": "bca09fd7"
}
},
{
"match": {
"userMessage": "Find flight options from LAX to JFK for one adult departing May 20, 2026, returning May 24, 2026. Provide 3 flight options: low-cost, balanced (good price and timing), and premium (more legroom or non\u2011stop at convenient times). Include airline, flight times (depart/arrive local), number of stops, total duration, and a rough price estimate in USD.",
"model": "gpt-5-mini",
"turnIndex": 0,
"hasToolResult": false
},
"response": {
"toolCalls": [
{
"name": "find_routes",
"arguments": "{\"from_code\": \"LAX\", \"to_code\": \"JFK\", \"date_offset_days\": 0}",
"id": "call_U1N177nViX8Bt3o9jUm6C4aH"
},
{
"name": "find_routes",
"arguments": "{\"from_code\": \"JFK\", \"to_code\": \"LAX\", \"date_offset_days\": 4}",
"id": "call_NHAd49cqGK50CvOC948tXXgn"
}
]
},
"metadata": {
"systemHash": "33b52d2f",
"toolsHash": "b71efcf3"
}
},
{
"match": {
"userMessage": "Find flight options from LAX to JFK for one adult departing May 20, 2026, returning May 24, 2026. Provide 3 flight options: low-cost, balanced (good price and timing), and premium (more legroom or non\u2011stop at convenient times). Include airline, flight times (depart/arrive local), number of stops, total duration, and a rough price estimate in USD.",
"model": "gpt-5-mini",
"turnIndex": 1,
"hasToolResult": true
},
"response": {
"content": "Below are three round\u2011trip options I found for LAX \u2192 JFK departing May 20, returning May 24 (one adult). Flights come from the schedule data; prices are rough market estimates for economy/premium seats.\n\n1) Low\u2011cost (cheapest, still nonstop)\n- Outbound: UA 123 (United) \u2014 LAX 08:00 \u2192 JFK 16:30 (local) \n - Nonstop, duration 5h30, aircraft: Boeing 787 \n- Return: B6 6601 (JetBlue) \u2014 JFK 07:30 \u2192 LAX 10:55 (local) \n - Nonstop, duration 6h25, aircraft: Airbus A321 \n- Round\u2011trip total flying time: 11h55 (330 + 385 min) \n- Rough price (economy, basic): ~USD 220\u2013280\n\n2) Balanced (good price + single\u2011carrier convenience)\n- Outbound: UA 123 (United) \u2014 LAX 08:00 \u2192 JFK 16:30 (local) \n - Nonstop, duration 5h30, Boeing 787 \n- Return: UA 456 (United) \u2014 JFK 10:00 \u2192 LAX 13:15 (local) \n - Nonstop, duration 6h15, Boeing 757 \u2014 note: schedule currently shows this leg as delayed in the data \n- Round\u2011trip total flying time: 11h45 (330 + 375 min) \n- Rough price (economy, standard): ~USD 320\u2013420\n\n3) Premium (more legroom / more comfortable cabin on convenient nonstop times)\n- Outbound: UA 123 (United) \u2014 LAX 08:00 \u2192 JFK 16:30 (local) \n - Nonstop, 5h30, Boeing 787 (widebody \u2014 better cabin space) \n- Return: UA 456 (United) \u2014 JFK 10:00 \u2192 LAX 13:15 (local) \n - Nonstop, 6h15, Boeing 757 \n- Round\u2011trip total flying time: 11h45 \n- Rough price: \n - Premium Economy / Economy Plus seats: ~USD 700\u20131,000 \n - Business / First class: ~USD 1,600\u20132,400\n\nNotes:\n- All options above are nonstop each leg. The dataset shows only these flights for your dates; if you want cheaper fares I can look for one\u2011stop itineraries or different carriers/dates. \n- UA456 is flagged as \u201cdelayed\u201d in the schedule data \u2014 consider the earlier JetBlue return if tight connections or schedule certainty matter. \n- Want me to pull live fares for any one of these options and check exact seat/price availability or preferences (flexible ticket, extra legroom, specific airline)?"
},
"metadata": {
"systemHash": "33b52d2f",
"toolsHash": "b71efcf3"
}
},
{
"match": {
"userMessage": "Plan a trip from LAX to JFK",
"model": "gpt-5-mini",
"turnIndex": 2,
"hasToolResult": true
},
"response": {
"toolCalls": [
{
"name": "task",
"arguments": "{\"role\":\"itinerary\",\"task_description\":\"Using the research and booking outputs, synthesize a concise trip plan for one adult traveling LAX\u2192JFK, departing May 20, 2026 and returning May 24, 2026. Include: chosen flight option (pick the balanced option), terminals to use at LAX and JFK for those flights, recommended arrival times at the airport, ground transportation options to/from each airport, packing/weather notes for May in NYC, and simple tips to avoid common delays.\"}",
"id": "call_abvWLlynVR1RaX6VNBh21aGc"
}
]
},
"metadata": {
"systemHash": "13e1b238",
"toolsHash": "bca09fd7"
}
},
{
"match": {
"userMessage": "Using the research and booking outputs, synthesize a concise trip plan for one adult traveling LAX\u2192JFK, departing May 20, 2026 and returning May 24, 2026. Include: chosen flight option (pick the balanced option), terminals to use at LAX and JFK for those flights, recommended arrival times at the airport, ground transportation options to/from each airport, packing/weather notes for May in NYC, and simple tips to avoid common delays.",
"model": "gpt-5-mini",
"turnIndex": 0,
"hasToolResult": false
},
"response": {
"content": "Pick the balanced nonstop: JetBlue LAX \u2192 JFK outbound May 20 and return May 24 (JetBlue operates at LAX Terminal 5 and arrives/departs JFK Terminal 5). \nPlan to arrive at LAX 2\u20132.5 hours before departure (allow extra time for traffic and checked bags) and at JFK about 2 hours before your return; check in on the airline app and have your mobile boarding pass ready. \nGround transport: at LAX use the FlyAway bus to/from downtown, rideshare/taxi pickups on the Lower (Arrivals) curb, or rental cars via the Rental Car Center shuttle; at JFK use the AirTrain (to Jamaica for LIRR or Howard Beach for the A subway), or door\u2011to\u2011door taxi/rideshare (allow 45\u201375 minutes to Manhattan depending on traffic). \nMay in NYC is mild (highs ~65\u201372\u00b0F / 18\u201322\u00b0C, lows ~50\u201355\u00b0F / 10\u201313\u00b0C) so pack layers, a light jacket and a compact umbrella; to avoid delays, pick mid\u2011morning flights when possible, enroll in TSA PreCheck/CLEAR, check the airline app for real\u2011time updates, and leave extra time for LAX traffic and JFK security lines."
},
"metadata": {
"systemHash": "ec82747b"
}
},
{
"match": {
"userMessage": "Plan a trip from LAX to JFK",
"model": "gpt-5-mini",
"turnIndex": 3,
"hasToolResult": true
},
"response": {
"content": "All set \u2014 I gathered research, found flights, and prepared a concise itinerary.\n\nSummary plan (1\u20132 sentences):\n- Balanced option: round\u2011trip nonstop LAX \u2192 JFK departing May 20, returning May 24 using United (nonstop outbound/return) with a convenient schedule and moderate price. Arrive at LAX ~2\u20132.5 hours before departure and at JFK ~2 hours before your return; use LAX ground transportation (FlyAway, rideshare, rental shuttle) and JFK AirTrain/LIRR or rideshare to reach the city."
},
"metadata": {
"systemHash": "13e1b238",
"toolsHash": "bca09fd7"
}
}
]
}
15 changes: 15 additions & 0 deletions cockpit/chat/subagents/angular/e2e/global-setup-impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
import { resolve } from 'node:path';
import { createGlobalSetup } from '../../../../../libs/internal/aimock-harness/src';

export default createGlobalSetup({
langgraphCwd: 'cockpit/langgraph/streaming/python',
// Each cockpit example pins its OWN langgraph port to avoid TIME_WAIT
// collisions when a sequential CI loop runs multiple per-example e2es
// back-to-back. Streaming uses 8123; tool-calls 8124; subagents 8125.
// The Angular proxy.conf.json target must match.
langgraphPort: 8125,
angularProject: 'cockpit-chat-subagents-angular',
angularPort: 4505,
fixturesDir: resolve(__dirname, 'fixtures'),
});
18 changes: 18 additions & 0 deletions cockpit/chat/subagents/angular/e2e/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: '.',
testMatch: '**/*.spec.ts',
fullyParallel: false,
workers: 1,
retries: process.env.CI ? 2 : 0,
reporter: process.env.CI ? [['list'], ['html', { open: 'never' }]] : 'list',
use: {
baseURL: 'http://localhost:4505',
trace: 'retain-on-failure',
},
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
globalSetup: './global-setup-impl.ts',
globalTeardown: require.resolve('../../../../../libs/internal/aimock-harness/src/global-teardown'),
});
Loading
Loading