Skip to content

Commit 00952e5

Browse files
bloveclaude
andauthored
feat(cockpit-registry): add ag-ui product type + register ag-ui-streaming demo (#450)
* docs: ag-ui demo capability-registry integration design Thread A of Task #2 (rename + structural-consistency sweep). Registers the existing cockpit-ag-ui-streaming-angular cap in apps/cockpit/scripts/capability-registry.ts. Schema makes pythonDir + graphName optional to accommodate ag-ui's in-process FakeAgent architecture. Two consumer guards: deploy script skips no-Python caps; e2e-wiring spec guards its pythonDir checks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: ag-ui registry integration implementation plan 5 tasks (3 code commits + 1 verification + 1 orchestrator). Each code commit touches one file; verification covers manifest count, build, test target, and 4 aimock e2es. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(cockpit-registry): add ag-ui product type + ag-ui-streaming entry Schema change: pythonDir and graphName become optional to accommodate caps without a Python backend. Adds 'ag-ui' to the product union and registers the existing cockpit-ag-ui-streaming-angular cap (uses FakeAgent in-process; no LangSmith deployment). Two downstream consumers need guards (separate commits): - scripts/generate-shared-deployment-config.ts (skip when no pythonDir) - apps/cockpit/cockpit-e2e-wiring.spec.ts (guard pythonDir check) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(deploy): skip caps without pythonDir in shared-deploy manifest Per the schema change in the prior commit, pythonDir is now optional. ag-ui caps (in-process FakeAgent) and any future no-Python caps need to be skipped — they have no langgraph.json to stage and contribute no graphs to the shared-dev deployment. Manifest graph count unchanged (32 graphs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(cockpit-e2e-wiring): guard pythonDir check for no-Python caps Per the registry schema change two commits prior, pythonDir is now optional. The e2e-wiring spec compares capability.pythonDir against the per-cap e2e harness's langgraphCwd; caps without pythonDir (ag-ui) don't have an e2e harness either, so the check should skip rather than fail comparing undefined to a path string. Mirrors the existing pythonPort guard pattern (already wrapped in !== undefined). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(cockpit-scripts): guard pythonDir/graphName for no-Python caps Two consumers missed in PR #450's pre-flight grep (which used `capability.pythonDir` pattern but missed `c.pythonDir`/`cap.pythonDir`): - apps/cockpit/scripts/generate-combined-langgraph.ts: TypeScript error using `c.graphName` (undefined for ag-ui) as object index - apps/cockpit/scripts/serve-example.ts: would spawn `cd undefined && uv run langgraph dev` for ag-ui-streaming Both now skip cleanly when pythonDir is absent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e1fa045 commit 00952e5

7 files changed

Lines changed: 691 additions & 6 deletions

apps/cockpit/cockpit-e2e-wiring.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ describe('cockpit e2e wiring', () => {
149149
if (capability.pythonPort !== undefined && capability.pythonPort !== wiring.langgraphPort) {
150150
errors.push(`${wiring.project}: registry pythonPort ${capability.pythonPort} != global setup langgraphPort ${wiring.langgraphPort}`);
151151
}
152-
if (capability.pythonDir !== wiring.langgraphCwd) {
152+
if (capability.pythonDir !== undefined && capability.pythonDir !== wiring.langgraphCwd) {
153153
errors.push(`${wiring.project}: registry pythonDir ${capability.pythonDir} != global setup langgraphCwd ${wiring.langgraphCwd}`);
154154
}
155155

apps/cockpit/scripts/capability-registry.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
*/
55
export interface Capability {
66
id: string;
7-
product: 'langgraph' | 'deep-agents' | 'render' | 'chat';
7+
product: 'langgraph' | 'deep-agents' | 'render' | 'chat' | 'ag-ui';
88
topic: string;
99
angularProject: string;
1010
port: number;
1111
pythonPort?: number;
12-
pythonDir: string;
13-
graphName: string;
12+
/** Optional — ag-ui caps run in-process via FakeAgent and have no Python backend. */
13+
pythonDir?: string;
14+
/** Optional — see pythonDir. */
15+
graphName?: string;
1416
}
1517

1618
export const capabilities: readonly Capability[] = [
@@ -47,6 +49,8 @@ export const capabilities: readonly Capability[] = [
4749
{ id: 'c-debug', product: 'chat', topic: 'debug', angularProject: 'cockpit-chat-debug-angular', port: 4509, pythonPort: 5509, pythonDir: 'cockpit/chat/debug/python', graphName: 'c-debug' },
4850
{ id: 'c-theming', product: 'chat', topic: 'theming', angularProject: 'cockpit-chat-theming-angular', port: 4510, pythonPort: 5510, pythonDir: 'cockpit/chat/theming/python', graphName: 'c-theming' },
4951
{ id: 'c-a2ui', product: 'chat', topic: 'a2ui', angularProject: 'cockpit-chat-a2ui-angular', port: 4511, pythonPort: 5511, pythonDir: 'cockpit/chat/a2ui/python', graphName: 'c-a2ui' },
52+
// AG-UI capabilities (in-process FakeAgent; no Python backend, not deployed to LangSmith)
53+
{ id: 'ag-ui-streaming', product: 'ag-ui', topic: 'streaming', angularProject: 'cockpit-ag-ui-streaming-angular', port: 4600 },
5054
] as const;
5155

5256
export function findCapability(id: string): Capability | undefined {

apps/cockpit/scripts/generate-combined-langgraph.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ function normalizeEntrypoint(pythonDir: string, graphName: string): string {
3939
const graphs: Record<string, string> = {};
4040
const dependencies = new Set<string>();
4141
for (const c of capabilities) {
42+
if (!c.pythonDir || !c.graphName) {
43+
continue; // ag-ui (in-process) and other no-Python caps
44+
}
4245
graphs[c.graphName] = `./${c.pythonDir}/${normalizeEntrypoint(c.pythonDir, c.graphName)}`;
4346
dependencies.add(`./${c.pythonDir}`);
4447
}

apps/cockpit/scripts/serve-example.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ if (allMode) {
3636
const cap = findCapability(capabilityArg!);
3737
if (!cap) { console.error(`Unknown: ${capabilityArg}`); process.exit(1); }
3838
run(cap.id, `npx nx run ${cap.angularProject}:serve:cockpit --port ${cap.port}`, '33');
39-
run(`${cap.id}-py`, `cd ${cap.pythonDir} && source $HOME/.local/bin/env 2>/dev/null; uv sync && uv run langgraph dev --port 8123`, '35');
40-
console.log(`\n🚀 ${cap.id}: cockpit=4201 angular=${cap.port} langgraph=8123\n`);
39+
if (cap.pythonDir) {
40+
run(`${cap.id}-py`, `cd ${cap.pythonDir} && source $HOME/.local/bin/env 2>/dev/null; uv sync && uv run langgraph dev --port 8123`, '35');
41+
console.log(`\n🚀 ${cap.id}: cockpit=4201 angular=${cap.port} langgraph=8123\n`);
42+
} else {
43+
// ag-ui (in-process) and other no-Python caps have no langgraph backend.
44+
console.log(`\n🚀 ${cap.id}: cockpit=4201 angular=${cap.port} (no langgraph backend)\n`);
45+
}
4146
}

0 commit comments

Comments
 (0)