diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27c3de43..2492937f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -284,6 +284,12 @@ jobs: - { angular: cockpit-langgraph-subgraphs-angular, python: cockpit/langgraph/subgraphs/python } - { angular: cockpit-langgraph-time-travel-angular, python: cockpit/langgraph/time-travel/python } - { angular: cockpit-langgraph-deployment-runtime-angular, python: cockpit/langgraph/deployment-runtime/python } + - { angular: cockpit-deep-agents-planning-angular, python: cockpit/deep-agents/planning/python } + - { angular: cockpit-deep-agents-filesystem-angular, python: cockpit/deep-agents/filesystem/python } + - { angular: cockpit-deep-agents-subagents-angular, python: cockpit/deep-agents/subagents/python } + - { angular: cockpit-deep-agents-memory-angular, python: cockpit/deep-agents/memory/python } + - { angular: cockpit-deep-agents-skills-angular, python: cockpit/deep-agents/skills/python } + - { angular: cockpit-deep-agents-sandboxes-angular, python: cockpit/deep-agents/sandboxes/python } steps: - uses: actions/checkout@v6.0.2 - uses: actions/setup-node@v6.3.0 diff --git a/apps/cockpit/scripts/capability-registry.ts b/apps/cockpit/scripts/capability-registry.ts index 077ba68a..88b9af3b 100644 --- a/apps/cockpit/scripts/capability-registry.ts +++ b/apps/cockpit/scripts/capability-registry.ts @@ -24,12 +24,12 @@ export const capabilities: readonly Capability[] = [ { id: 'subgraphs', product: 'langgraph', topic: 'subgraphs', angularProject: 'cockpit-langgraph-subgraphs-angular', port: 4305, pythonPort: 5305, pythonDir: 'cockpit/langgraph/subgraphs/python', graphName: 'subgraphs' }, { id: 'time-travel', product: 'langgraph', topic: 'time-travel', angularProject: 'cockpit-langgraph-time-travel-angular', port: 4306, pythonPort: 5306, pythonDir: 'cockpit/langgraph/time-travel/python', graphName: 'time-travel' }, { id: 'deployment-runtime', product: 'langgraph', topic: 'deployment-runtime', angularProject: 'cockpit-langgraph-deployment-runtime-angular', port: 4307, pythonPort: 5307, pythonDir: 'cockpit/langgraph/deployment-runtime/python', graphName: 'deployment-runtime' }, - { id: 'da-planning', product: 'deep-agents', topic: 'planning', angularProject: 'cockpit-deep-agents-planning-angular', port: 4310, pythonDir: 'cockpit/deep-agents/planning/python', graphName: 'da-planning' }, - { id: 'da-filesystem', product: 'deep-agents', topic: 'filesystem', angularProject: 'cockpit-deep-agents-filesystem-angular', port: 4311, pythonDir: 'cockpit/deep-agents/filesystem/python', graphName: 'da-filesystem' }, - { id: 'da-subagents', product: 'deep-agents', topic: 'subagents', angularProject: 'cockpit-deep-agents-subagents-angular', port: 4312, pythonDir: 'cockpit/deep-agents/subagents/python', graphName: 'subagents' }, - { id: 'da-memory', product: 'deep-agents', topic: 'memory', angularProject: 'cockpit-deep-agents-memory-angular', port: 4313, pythonDir: 'cockpit/deep-agents/memory/python', graphName: 'da-memory' }, - { id: 'da-skills', product: 'deep-agents', topic: 'skills', angularProject: 'cockpit-deep-agents-skills-angular', port: 4314, pythonDir: 'cockpit/deep-agents/skills/python', graphName: 'da-skills' }, - { id: 'da-sandboxes', product: 'deep-agents', topic: 'sandboxes', angularProject: 'cockpit-deep-agents-sandboxes-angular', port: 4315, pythonDir: 'cockpit/deep-agents/sandboxes/python', graphName: 'da-sandboxes' }, + { id: 'da-planning', product: 'deep-agents', topic: 'planning', angularProject: 'cockpit-deep-agents-planning-angular', port: 4310, pythonPort: 5310, pythonDir: 'cockpit/deep-agents/planning/python', graphName: 'da-planning' }, + { id: 'da-filesystem', product: 'deep-agents', topic: 'filesystem', angularProject: 'cockpit-deep-agents-filesystem-angular', port: 4311, pythonPort: 5311, pythonDir: 'cockpit/deep-agents/filesystem/python', graphName: 'da-filesystem' }, + { id: 'da-subagents', product: 'deep-agents', topic: 'subagents', angularProject: 'cockpit-deep-agents-subagents-angular', port: 4312, pythonPort: 5312, pythonDir: 'cockpit/deep-agents/subagents/python', graphName: 'subagents' }, + { id: 'da-memory', product: 'deep-agents', topic: 'memory', angularProject: 'cockpit-deep-agents-memory-angular', port: 4313, pythonPort: 5313, pythonDir: 'cockpit/deep-agents/memory/python', graphName: 'da-memory' }, + { id: 'da-skills', product: 'deep-agents', topic: 'skills', angularProject: 'cockpit-deep-agents-skills-angular', port: 4314, pythonPort: 5314, pythonDir: 'cockpit/deep-agents/skills/python', graphName: 'da-skills' }, + { id: 'da-sandboxes', product: 'deep-agents', topic: 'sandboxes', angularProject: 'cockpit-deep-agents-sandboxes-angular', port: 4315, pythonPort: 5315, pythonDir: 'cockpit/deep-agents/sandboxes/python', graphName: 'da-sandboxes' }, // Render capabilities { id: 'r-spec-rendering', product: 'render', topic: 'spec-rendering', angularProject: 'cockpit-render-spec-rendering-angular', port: 4401, pythonDir: 'cockpit/render/spec-rendering/python', graphName: 'r-spec-rendering' }, { id: 'r-element-rendering', product: 'render', topic: 'element-rendering', angularProject: 'cockpit-render-element-rendering-angular', port: 4402, pythonDir: 'cockpit/render/element-rendering/python', graphName: 'r-element-rendering' }, diff --git a/cockpit/deep-agents/filesystem/angular/e2e/da-filesystem.spec.ts b/cockpit/deep-agents/filesystem/angular/e2e/da-filesystem.spec.ts new file mode 100644 index 00000000..c982b6a6 --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/da-filesystem.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-filesystem: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/filesystem/angular/e2e/fixtures/da-filesystem.json b/cockpit/deep-agents/filesystem/angular/e2e/fixtures/da-filesystem.json new file mode 100644 index 00000000..a5bccfad --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/fixtures/da-filesystem.json @@ -0,0 +1,12 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hello! How can I help you today? I can read or write files in the workspace\u2014tell me what you'd like to do (e.g., \"read file /path/to/file\" or \"write file /path/to/file with content ...\")." + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/filesystem/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/filesystem/angular/e2e/global-setup-impl.ts new file mode 100644 index 00000000..c951c32f --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/filesystem/python', + langgraphPort: 5311, + angularProject: 'cockpit-deep-agents-filesystem-angular', + angularPort: 4311, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts b/cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts new file mode 100644 index 00000000..97265149 --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts @@ -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:4311', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/filesystem/angular/e2e/tsconfig.json b/cockpit/deep-agents/filesystem/angular/e2e/tsconfig.json new file mode 100644 index 00000000..0b5aeecb --- /dev/null +++ b/cockpit/deep-agents/filesystem/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/filesystem/angular/project.json b/cockpit/deep-agents/filesystem/angular/project.json index 649cf78e..2ee3af06 100644 --- a/cockpit/deep-agents/filesystem/angular/project.json +++ b/cockpit/deep-agents/filesystem/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsFilesystemAngularModule } from './cockpit/deep-agents/filesystem/angular/src/index.ts'; const mod = deepAgentsFilesystemAngularModule; if (mod.id !== 'deep-agents-filesystem-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Filesystem (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/filesystem/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/filesystem/angular/proxy.conf.json b/cockpit/deep-agents/filesystem/angular/proxy.conf.json index 8523362d..3068de09 100644 --- a/cockpit/deep-agents/filesystem/angular/proxy.conf.json +++ b/cockpit/deep-agents/filesystem/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5311", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/memory/angular/e2e/da-memory.spec.ts b/cockpit/deep-agents/memory/angular/e2e/da-memory.spec.ts new file mode 100644 index 00000000..0b281ceb --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/da-memory.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-memory: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/memory/angular/e2e/fixtures/da-memory.json b/cockpit/deep-agents/memory/angular/e2e/fixtures/da-memory.json new file mode 100644 index 00000000..4bc44176 --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/fixtures/da-memory.json @@ -0,0 +1,18 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hi \u2014 hello! How can I help you today?" + } + }, + { + "match": {}, + "response": { + "content": "{}" + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/memory/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/memory/angular/e2e/global-setup-impl.ts new file mode 100644 index 00000000..d39996c1 --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/memory/python', + langgraphPort: 5313, + angularProject: 'cockpit-deep-agents-memory-angular', + angularPort: 4313, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/memory/angular/e2e/playwright.config.ts b/cockpit/deep-agents/memory/angular/e2e/playwright.config.ts new file mode 100644 index 00000000..08bdb31b --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/playwright.config.ts @@ -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:4313', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/memory/angular/e2e/tsconfig.json b/cockpit/deep-agents/memory/angular/e2e/tsconfig.json new file mode 100644 index 00000000..0b5aeecb --- /dev/null +++ b/cockpit/deep-agents/memory/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/memory/angular/project.json b/cockpit/deep-agents/memory/angular/project.json index 3a7df837..b3f08ea6 100644 --- a/cockpit/deep-agents/memory/angular/project.json +++ b/cockpit/deep-agents/memory/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsMemoryAngularModule } from './cockpit/deep-agents/memory/angular/src/index.ts'; const mod = deepAgentsMemoryAngularModule; if (mod.id !== 'deep-agents-memory-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Memory (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/memory/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/memory/angular/proxy.conf.json b/cockpit/deep-agents/memory/angular/proxy.conf.json index 8523362d..020a0ca4 100644 --- a/cockpit/deep-agents/memory/angular/proxy.conf.json +++ b/cockpit/deep-agents/memory/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5313", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/planning/angular/e2e/da-planning.spec.ts b/cockpit/deep-agents/planning/angular/e2e/da-planning.spec.ts new file mode 100644 index 00000000..8d34bea0 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/da-planning.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-planning: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/planning/angular/e2e/fixtures/da-planning.json b/cockpit/deep-agents/planning/angular/e2e/fixtures/da-planning.json new file mode 100644 index 00000000..e968eb99 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/fixtures/da-planning.json @@ -0,0 +1,18 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "[{\"title\":\"Respond with a friendly greeting\",\"status\":\"pending\"},{\"title\":\"Ask how I can help\",\"status\":\"pending\"},{\"title\":\"Give examples of what I can do\",\"status\":\"pending\"},{\"title\":\"Suggest next steps/questions\",\"status\":\"pending\"}]\n\nStep 1 \u2014 Respond with a friendly greeting (completed):\nHello! Nice to meet you.\n\nStep 2 \u2014 Ask how I can help (completed):\nHow can I help you today?\n\nStep 3 \u2014 Give examples of what I can do (completed):\n- Answer questions or explain concepts\n- Help write or edit email, essays, or code\n- Brainstorm ideas or outline plans\n- Summarize articles or long text\n- Translate or proofread text\n- Solve math problems or debug code\n\nStep 4 \u2014 Suggest next steps/questions (completed):\nYou can tell me what you need right now (a question, a task, or a topic). If you prefer, pick one of the examples above and I\u2019ll get started." + } + }, + { + "match": {}, + "response": { + "content": "Plan (4 steps)\n1. Ask what you need.\n2. Clarify scope, format, and any constraints (deadline, length, tone, audience).\n3. Offer examples of how I can help and suggest a concrete first deliverable.\n4. Confirm and begin work.\n\nExecution\nStep 1 \u2014 Ask what you need:\nWhat would you like me to do right now?\n\nStep 2 \u2014 Clarify scope and constraints:\nIf you already have something specific, tell me: the goal, desired format (email, essay, code, plan, summary, slides, etc.), length, tone (formal/casual), audience, and any deadline. If you don\u2019t have constraints, say so.\n\nStep 3 \u2014 Examples and a suggested first deliverable:\nHere are quick examples of tasks I can do \u2014 pick one or describe your own:\n- Write or edit an email (provide recipient/context and key points).\n- Draft an essay or article (topic, thesis, word count).\n- Create a project plan or roadmap (objective, timeline).\n- Summarize an article or document (paste text or upload).\n- Debug or write code (language, repo/files, expected behavior).\n- Brainstorm ideas (product names, marketing angles, meeting agendas).\n\nSuggested first deliverable: I can produce a short sample (e.g., a 150\u2013300 word draft, a 5-item plan, or a 1-paragraph summary) so you can confirm style before I expand.\n\nStep 4 \u2014 Confirm and begin:\nTell me which task you want and any constraints, or choose one of the examples above. I\u2019ll start immediately." + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/planning/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/planning/angular/e2e/global-setup-impl.ts new file mode 100644 index 00000000..8eced516 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/planning/python', + langgraphPort: 5310, + angularProject: 'cockpit-deep-agents-planning-angular', + angularPort: 4310, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/planning/angular/e2e/playwright.config.ts b/cockpit/deep-agents/planning/angular/e2e/playwright.config.ts new file mode 100644 index 00000000..976b8246 --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/playwright.config.ts @@ -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:4310', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/planning/angular/e2e/tsconfig.json b/cockpit/deep-agents/planning/angular/e2e/tsconfig.json new file mode 100644 index 00000000..0b5aeecb --- /dev/null +++ b/cockpit/deep-agents/planning/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/planning/angular/project.json b/cockpit/deep-agents/planning/angular/project.json index 42f11598..ce8ea0b6 100644 --- a/cockpit/deep-agents/planning/angular/project.json +++ b/cockpit/deep-agents/planning/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsPlanningAngularModule } from './cockpit/deep-agents/planning/angular/src/index.ts'; const mod = deepAgentsPlanningAngularModule; if (mod.id !== 'deep-agents-planning-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Planning (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/planning/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/planning/angular/proxy.conf.json b/cockpit/deep-agents/planning/angular/proxy.conf.json index 8523362d..2c71ffe1 100644 --- a/cockpit/deep-agents/planning/angular/proxy.conf.json +++ b/cockpit/deep-agents/planning/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5310", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/da-sandboxes.spec.ts b/cockpit/deep-agents/sandboxes/angular/e2e/da-sandboxes.spec.ts new file mode 100644 index 00000000..f57a2216 --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/da-sandboxes.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-sandboxes: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/fixtures/da-sandboxes.json b/cockpit/deep-agents/sandboxes/angular/e2e/fixtures/da-sandboxes.json new file mode 100644 index 00000000..8766ff23 --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/fixtures/da-sandboxes.json @@ -0,0 +1,12 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hello! How can I help you today?" + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/sandboxes/angular/e2e/global-setup-impl.ts new file mode 100644 index 00000000..2c61115f --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/sandboxes/python', + langgraphPort: 5315, + angularProject: 'cockpit-deep-agents-sandboxes-angular', + angularPort: 4315, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts b/cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts new file mode 100644 index 00000000..2f07e56c --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts @@ -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:4315', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/sandboxes/angular/e2e/tsconfig.json b/cockpit/deep-agents/sandboxes/angular/e2e/tsconfig.json new file mode 100644 index 00000000..0b5aeecb --- /dev/null +++ b/cockpit/deep-agents/sandboxes/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/sandboxes/angular/project.json b/cockpit/deep-agents/sandboxes/angular/project.json index 9b9f1ab6..948acc5f 100644 --- a/cockpit/deep-agents/sandboxes/angular/project.json +++ b/cockpit/deep-agents/sandboxes/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsSandboxesAngularModule } from './cockpit/deep-agents/sandboxes/angular/src/index.ts'; const mod = deepAgentsSandboxesAngularModule; if (mod.id !== 'deep-agents-sandboxes-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Sandboxes (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/sandboxes/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/sandboxes/angular/proxy.conf.json b/cockpit/deep-agents/sandboxes/angular/proxy.conf.json index 8523362d..c20d5a91 100644 --- a/cockpit/deep-agents/sandboxes/angular/proxy.conf.json +++ b/cockpit/deep-agents/sandboxes/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5315", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/skills/angular/e2e/da-skills.spec.ts b/cockpit/deep-agents/skills/angular/e2e/da-skills.spec.ts new file mode 100644 index 00000000..51f60c01 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/da-skills.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-skills: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/skills/angular/e2e/fixtures/da-skills.json b/cockpit/deep-agents/skills/angular/e2e/fixtures/da-skills.json new file mode 100644 index 00000000..210889f4 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/fixtures/da-skills.json @@ -0,0 +1,12 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "content": "Hello! How can I help you today? I can evaluate math expressions, count words in a text, or summarize content \u2014 which would you like?" + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/skills/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/skills/angular/e2e/global-setup-impl.ts new file mode 100644 index 00000000..bcf16b96 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/skills/python', + langgraphPort: 5314, + angularProject: 'cockpit-deep-agents-skills-angular', + angularPort: 4314, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/skills/angular/e2e/playwright.config.ts b/cockpit/deep-agents/skills/angular/e2e/playwright.config.ts new file mode 100644 index 00000000..25431600 --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/playwright.config.ts @@ -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:4314', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/skills/angular/e2e/tsconfig.json b/cockpit/deep-agents/skills/angular/e2e/tsconfig.json new file mode 100644 index 00000000..0b5aeecb --- /dev/null +++ b/cockpit/deep-agents/skills/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/skills/angular/project.json b/cockpit/deep-agents/skills/angular/project.json index 18cb12bd..76d9384c 100644 --- a/cockpit/deep-agents/skills/angular/project.json +++ b/cockpit/deep-agents/skills/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsSkillsAngularModule } from './cockpit/deep-agents/skills/angular/src/index.ts'; const mod = deepAgentsSkillsAngularModule; if (mod.id !== 'deep-agents-skills-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Skills (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/skills/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/skills/angular/proxy.conf.json b/cockpit/deep-agents/skills/angular/proxy.conf.json index 8523362d..76e30cf6 100644 --- a/cockpit/deep-agents/skills/angular/proxy.conf.json +++ b/cockpit/deep-agents/skills/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5314", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/deep-agents/subagents/angular/e2e/da-subagents.spec.ts b/cockpit/deep-agents/subagents/angular/e2e/da-subagents.spec.ts new file mode 100644 index 00000000..3d223b38 --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/da-subagents.spec.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +import { test, expect } from '@playwright/test'; +import { submitAndWaitForResponse } from '../../../../../libs/e2e-harness/src'; + +test('da-subagents: hello prompt produces assistant turn', async ({ page }) => { + const bubble = await submitAndWaitForResponse(page, 'Hello'); + await expect(bubble).toBeVisible(); +}); diff --git a/cockpit/deep-agents/subagents/angular/e2e/fixtures/da-subagents.json b/cockpit/deep-agents/subagents/angular/e2e/fixtures/da-subagents.json new file mode 100644 index 00000000..88d1f488 --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/fixtures/da-subagents.json @@ -0,0 +1,18 @@ +{ + "fixtures": [ + { + "match": { + "userMessage": "Hello" + }, + "response": { + "toolCalls": [ + { + "name": "research_agent", + "arguments": "{\"topic\":\"How to respond to a simple greeting like 'Hello' in a friendly, concise way; suggested phrasing, tone, and follow-up questions to engage user\"}", + "id": "call_JAuyEoJ5ILdin2rB6kRACMpw" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/cockpit/deep-agents/subagents/angular/e2e/global-setup-impl.ts b/cockpit/deep-agents/subagents/angular/e2e/global-setup-impl.ts new file mode 100644 index 00000000..708d88b8 --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/global-setup-impl.ts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +import { resolve } from 'node:path'; +import { createGlobalSetup } from '../../../../../libs/e2e-harness/src'; + +export default createGlobalSetup({ + langgraphCwd: 'cockpit/deep-agents/subagents/python', + langgraphPort: 5312, + angularProject: 'cockpit-deep-agents-subagents-angular', + angularPort: 4312, + fixturesDir: resolve(__dirname, 'fixtures'), +}); diff --git a/cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts b/cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts new file mode 100644 index 00000000..b94680ee --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts @@ -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:4312', + trace: 'retain-on-failure', + }, + projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }], + globalSetup: './global-setup-impl.ts', + globalTeardown: require.resolve('../../../../../libs/e2e-harness/src/global-teardown'), +}); diff --git a/cockpit/deep-agents/subagents/angular/e2e/tsconfig.json b/cockpit/deep-agents/subagents/angular/e2e/tsconfig.json new file mode 100644 index 00000000..0b5aeecb --- /dev/null +++ b/cockpit/deep-agents/subagents/angular/e2e/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ES2022", + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "test-results", "playwright-report"] +} diff --git a/cockpit/deep-agents/subagents/angular/project.json b/cockpit/deep-agents/subagents/angular/project.json index 644ccc00..819893e6 100644 --- a/cockpit/deep-agents/subagents/angular/project.json +++ b/cockpit/deep-agents/subagents/angular/project.json @@ -86,6 +86,12 @@ "options": { "command": "npx tsx -e \"import { deepAgentsSubagentsAngularModule } from './cockpit/deep-agents/subagents/angular/src/index.ts'; const mod = deepAgentsSubagentsAngularModule; if (mod.id !== 'deep-agents-subagents-angular') throw new Error('Unexpected id: ' + mod.id); if (mod.title !== 'Deep Agents Subagents (Angular)') throw new Error('Unexpected title: ' + mod.title); console.log(JSON.stringify({ id: mod.id, title: mod.title }));\"" } + }, + "e2e": { + "executor": "@nx/playwright:playwright", + "options": { + "config": "cockpit/deep-agents/subagents/angular/e2e/playwright.config.ts" + } } } } diff --git a/cockpit/deep-agents/subagents/angular/proxy.conf.json b/cockpit/deep-agents/subagents/angular/proxy.conf.json index 8523362d..8985a469 100644 --- a/cockpit/deep-agents/subagents/angular/proxy.conf.json +++ b/cockpit/deep-agents/subagents/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5312", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } }