diff --git a/.github/workflows/composer_build_and_test.yml b/.github/workflows/composer_build_and_test.yml index 54b4413b7..18363858a 100644 --- a/.github/workflows/composer_build_and_test.yml +++ b/.github/workflows/composer_build_and_test.yml @@ -18,10 +18,14 @@ on: push: paths: - 'tools/composer/**' + - 'renderers/react/**' + - 'renderers/web_core/**' - '.github/workflows/composer_build_and_test.yml' pull_request: paths: - 'tools/composer/**' + - 'renderers/react/**' + - 'renderers/web_core/**' - '.github/workflows/composer_build_and_test.yml' jobs: @@ -43,6 +47,14 @@ jobs: cache: 'pnpm' cache-dependency-path: 'tools/composer/pnpm-lock.yaml' + - name: Build web_core (dependency of @a2ui/react) + working-directory: ./renderers/web_core + run: npm ci && npm run build + + - name: Build React renderer (local file dependency) + working-directory: ./renderers/react + run: npm ci && npm run build + - name: Install dependencies working-directory: ./tools/composer run: pnpm install diff --git a/tools/composer/.gitignore b/tools/composer/.gitignore index 1b99d4581..d846a1deb 100644 --- a/tools/composer/.gitignore +++ b/tools/composer/.gitignore @@ -48,3 +48,4 @@ yarn-error.log* __pycache__ .playwright-mcp +RENDERER_ISSUES.md diff --git a/tools/composer/package.json b/tools/composer/package.json index 6b4cb82b9..b3fe28e23 100644 --- a/tools/composer/package.json +++ b/tools/composer/package.json @@ -12,7 +12,8 @@ "format": "prettier --write \"**/*.{ts,tsx,md}\"" }, "dependencies": { - "@copilotkit/a2ui-renderer": "1.50.1", + "@a2ui/react": "file:../../renderers/react", + "@a2ui/web_core": "file:../../renderers/web_core", "@copilotkit/react-core": "^1.50.1", "@copilotkit/react-ui": "^1.50.1", "@copilotkit/runtime": "^1.50.1", diff --git a/tools/composer/pnpm-lock.yaml b/tools/composer/pnpm-lock.yaml index bdff681fe..ab70e9fba 100644 --- a/tools/composer/pnpm-lock.yaml +++ b/tools/composer/pnpm-lock.yaml @@ -22,9 +22,12 @@ importers: .: dependencies: - '@copilotkit/a2ui-renderer': - specifier: 1.50.1 - version: 1.50.1(@copilotkit/react-core@1.50.1(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(graphql@16.12.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(@copilotkitnext/react@0.0.33(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(signal-polyfill@0.2.2) + '@a2ui/react': + specifier: file:../../renderers/react + version: file:../../renderers/react(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(rxjs@7.8.1)(zod@3.25.76) + '@a2ui/web_core': + specifier: file:../../renderers/web_core + version: file:../../renderers/web_core '@copilotkit/react-core': specifier: ^1.50.1 version: 1.50.1(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(graphql@16.12.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) @@ -175,8 +178,17 @@ packages: graphql: optional: true - '@a2ui/lit@0.8.1': - resolution: {integrity: sha512-QeqobciZz4OGMSgc2WGLFVidyhy+K7Z2GDpiuHN9NN+QlYMXByZqlzMvYPJsXrqf1lpQcMFRHgmUn1mwPpq9ew==} + '@a2ui/react@file:../../renderers/react': + resolution: {directory: ../../renderers/react, type: directory} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + rxjs: ^7.8.1 + zod: ^3.23.8 + + '@a2ui/web_core@file:../../renderers/web_core': + resolution: {directory: ../../renderers/web_core, type: directory} '@acemir/cssom@0.9.31': resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} @@ -383,14 +395,6 @@ packages: '@chevrotain/utils@11.0.3': resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} - '@copilotkit/a2ui-renderer@1.50.1': - resolution: {integrity: sha512-hKgNWsiOew+Bc/iYG592BND9T0gOAVRJrHKxVmyeEaDGB/XnSzGFgZplLzRYJX5Qc2QVkOWmOIvN1e2AFV5nHA==} - peerDependencies: - '@copilotkit/react-core': ^1.50.1 - '@copilotkitnext/react': '*' - react: ^18 || ^19 || ^19.0.0-rc - react-dom: ^18 || ^19 || ^19.0.0-rc - '@copilotkit/react-core@1.50.1': resolution: {integrity: sha512-L7WdesE1PAP+Ks5kY0NXT+/sZfmx/Vj5t7l4eMQzzLDSvwgLDqvrQCZLJq/PtSLKidrX+z8zDyLJad7YR3L6dQ==} peerDependencies: @@ -865,89 +869,105 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -1009,15 +1029,9 @@ packages: '@lit-labs/react@2.1.3': resolution: {integrity: sha512-OD9h2JynerBQUMNzb563jiVpxfvPF0HjQkKY2mx0lpVYvD7F+rtJpOGz6ek+6ufMidV3i+MPT9SX62OKWHFrQg==} - '@lit-labs/signals@0.1.3': - resolution: {integrity: sha512-P0yWgH5blwVyEwBg+WFspLzeu1i0ypJP1QB0l1Omr9qZLIPsUu0p4Fy2jshOg7oQyha5n163K3GJGeUhQQ682Q==} - '@lit-labs/ssr-dom-shim@1.4.0': resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} - '@lit/context@1.1.6': - resolution: {integrity: sha512-M26qDE6UkQbZA2mQ3RjJ3Gzd8TxP+/0obMgE5HfkfLhEEyYE3Bui4A5XHiGPjy0MUGAyxB3QgVuw2ciS0kHn6A==} - '@lit/react@1.0.8': resolution: {integrity: sha512-p2+YcF+JE67SRX3mMlJ1TKCSTsgyOVdAwd/nxp3NuV1+Cb6MWALbN6nT7Ld4tpmYofcE5kcaSY1YBB9erY+6fw==} peerDependencies: @@ -1080,24 +1094,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@16.1.5': resolution: {integrity: sha512-U+kBxGUY1xMAzDTXmuVMfhaWUZQAwzRaHJ/I6ihtR5SbTVUEaDRiEU9YMjy1obBWpdOBuk1bcm+tsmifYSygfw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@16.1.5': resolution: {integrity: sha512-gq2UtoCpN7Ke/7tKaU7i/1L7eFLfhMbXjNghSv0MVGF1dmuoaPeEVDvkDuO/9LVa44h5gqpWeJ4mRRznjDv7LA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@16.1.5': resolution: {integrity: sha512-bQWSE729PbXT6mMklWLf8dotislPle2L70E9q6iwETYEOt092GDn0c+TTNj26AjmeceSsC4ndyGsK5nKqHYXjQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@16.1.5': resolution: {integrity: sha512-LZli0anutkIllMtTAWZlDqdfvjWX/ch8AFK5WgkNTvaqwlouiD1oHM+WW8RXMiL0+vAkAJyAGEzPPjO+hnrSNQ==} @@ -1130,6 +1148,9 @@ packages: '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + '@preact/signals-core@1.14.0': + resolution: {integrity: sha512-AowtCcCU/33lFlh1zRFf/u+12rfrhtNakj7UpaGEsmMwUKpKWMVvcktOGcwBBNiB4lWrZWc01LhiyyzVklJyaQ==} + '@protobuf-ts/protoc@2.11.1': resolution: {integrity: sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg==} hasBin: true @@ -1564,66 +1585,79 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} @@ -1736,24 +1770,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.16': resolution: {integrity: sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.16': resolution: {integrity: sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.16': resolution: {integrity: sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.16': resolution: {integrity: sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==} @@ -2652,6 +2690,9 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} @@ -3626,24 +3667,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.30.2: resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.30.2: resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.30.2: resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.30.2: resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} @@ -4692,14 +4737,6 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - signal-polyfill@0.2.2: - resolution: {integrity: sha512-p63Y4Er5/eMQ9RHg0M0Y64NlsQKpiu6MDdhBXpyywRuWiPywhJTpKJ1iB5K2hJEbFZ0BnDS7ZkJ+0AfTuL37Rg==} - - signal-utils@0.21.1: - resolution: {integrity: sha512-i9cdLSvVH4j8ql8mz2lyrA93xL499P8wEbIev3ldSriXeUwqh+wM4Q5VPhIZ19gPtIS4BOopJuKB8l1+wH9LCg==} - peerDependencies: - signal-polyfill: ^0.2.0 - simple-wcswidth@1.1.2: resolution: {integrity: sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==} @@ -5342,15 +5379,22 @@ snapshots: optionalDependencies: graphql: 16.12.0 - '@a2ui/lit@0.8.1(signal-polyfill@0.2.2)': + '@a2ui/react@file:../../renderers/react(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(rxjs@7.8.1)(zod@3.25.76)': dependencies: - '@lit-labs/signals': 0.1.3 - '@lit/context': 1.1.6 - lit: 3.3.1 + '@a2ui/web_core': file:../../renderers/web_core + clsx: 2.1.1 markdown-it: 14.1.1 - signal-utils: 0.21.1(signal-polyfill@0.2.2) - transitivePeerDependencies: - - signal-polyfill + react: 19.2.1 + react-dom: 19.2.1(react@19.2.1) + rxjs: 7.8.1 + zod: 3.25.76 + + '@a2ui/web_core@file:../../renderers/web_core': + dependencies: + '@preact/signals-core': 1.14.0 + date-fns: 4.1.0 + zod: 3.25.76 + zod-to-json-schema: 3.25.1(zod@3.25.76) '@acemir/cssom@0.9.31': {} @@ -5619,20 +5663,6 @@ snapshots: '@chevrotain/utils@11.0.3': {} - '@copilotkit/a2ui-renderer@1.50.1(@copilotkit/react-core@1.50.1(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(graphql@16.12.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(@copilotkitnext/react@0.0.33(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(signal-polyfill@0.2.2)': - dependencies: - '@a2ui/lit': 0.8.1(signal-polyfill@0.2.2) - '@copilotkit/react-core': 1.50.1(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(graphql@16.12.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) - '@copilotkitnext/react': 0.0.33(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) - '@lit-labs/signals': 0.1.3 - '@lit/context': 1.1.6 - lit: 3.3.1 - react: 19.2.1 - react-dom: 19.2.1(react@19.2.1) - zod: 3.25.76 - transitivePeerDependencies: - - signal-polyfill - '@copilotkit/react-core@1.50.1(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(graphql@16.12.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76)': dependencies: '@ag-ui/client': 0.0.42 @@ -6240,7 +6270,7 @@ snapshots: p-retry: 4.6.2 uuid: 10.0.0 zod: 3.25.76 - zod-to-json-schema: 3.25.0(zod@3.25.76) + zod-to-json-schema: 3.25.1(zod@3.25.76) transitivePeerDependencies: - '@opentelemetry/api' - '@opentelemetry/exporter-trace-otlp-proto' @@ -6264,17 +6294,8 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@lit-labs/signals@0.1.3': - dependencies: - lit: 3.3.1 - signal-polyfill: 0.2.2 - '@lit-labs/ssr-dom-shim@1.4.0': {} - '@lit/context@1.1.6': - dependencies: - '@lit/reactive-element': 2.1.1 - '@lit/react@1.0.8(@types/react@19.2.3)': dependencies: '@types/react': 19.2.3 @@ -6374,6 +6395,8 @@ snapshots: '@pinojs/redact@0.4.0': {} + '@preact/signals-core@1.14.0': {} + '@protobuf-ts/protoc@2.11.1': {} '@radix-ui/primitive@1.1.3': {} @@ -7990,6 +8013,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + date-fns@4.1.0: {} + dateformat@4.6.3: {} dayjs@1.11.18: {} @@ -10763,12 +10788,6 @@ snapshots: siginfo@2.0.0: {} - signal-polyfill@0.2.2: {} - - signal-utils@0.21.1(signal-polyfill@0.2.2): - dependencies: - signal-polyfill: 0.2.2 - simple-wcswidth@1.1.2: {} sonic-boom@4.2.0: diff --git a/tools/composer/src/app/api/copilotkit/[[...slug]]/route.ts b/tools/composer/src/app/api/copilotkit/[[...slug]]/route.ts index 940673d30..b87c6fd90 100644 --- a/tools/composer/src/app/api/copilotkit/[[...slug]]/route.ts +++ b/tools/composer/src/app/api/copilotkit/[[...slug]]/route.ts @@ -21,7 +21,8 @@ import { BuiltInAgent, } from "@copilotkit/runtime/v2"; import { handle } from "hono/vercel"; -import { A2UI_SYSTEM_PROMPT } from "../a2ui-prompt"; +import { A2UI_V08_PROMPT } from "../a2ui-prompt-v08"; +import { A2UI_V09_PROMPT } from "../a2ui-prompt-v09"; const determineModel = () => { if ( @@ -48,14 +49,26 @@ const determineModel = () => { return "google/gemini-2.5-flash"; }; -const agent = new BuiltInAgent({ - model: determineModel(), - prompt: A2UI_SYSTEM_PROMPT, +const model = determineModel(); + +const agentV08 = new BuiltInAgent({ + model, + prompt: A2UI_V08_PROMPT, + temperature: 0.7, +}); + +const agentV09 = new BuiltInAgent({ + model, + prompt: A2UI_V09_PROMPT, temperature: 0.7, }); const runtime = new CopilotRuntime({ - agents: { default: agent }, + agents: { + default: agentV08, + v08: agentV08, + v09: agentV09, + }, runner: new InMemoryAgentRunner(), }); diff --git a/tools/composer/src/app/api/copilotkit/a2ui-prompt-v08.ts b/tools/composer/src/app/api/copilotkit/a2ui-prompt-v08.ts new file mode 100644 index 000000000..2176f62b4 --- /dev/null +++ b/tools/composer/src/app/api/copilotkit/a2ui-prompt-v08.ts @@ -0,0 +1,111 @@ +/** + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A2UI v0.8 system prompt for the CopilotKit agent. + * + * Uses the actual v0.8 catalog spec from the specification directory. + */ +import { readFileSync } from 'fs'; +import { join } from 'path'; + +// Load the actual v0.8 catalog spec +const catalogSpec = readFileSync( + join(process.cwd(), '../../specification/v0_8/json/standard_catalog_definition.json'), + 'utf-8', +); + +export const A2UI_V08_PROMPT = `You are an expert A2UI v0.8 widget builder. A2UI is a protocol for defining platform-agnostic user interfaces using JSON. + +## Component Catalog (v0.8 Spec) + +${catalogSpec} + +## Widget Format + +A widget has TWO parts: +1. **components** — A flat array of component definitions (the UI structure) +2. **data** — A JSON object with the data model (the values) + +## Component Structure + +Each component in the array has: +- \`id\`: A unique string identifier +- \`component\`: An object with exactly ONE key (the component type) containing its properties + +Example: +\`\`\`json +{ + "id": "title", + "component": { + "Text": { + "text": { "literalString": "Hello World" }, + "usageHint": "h1" + } + } +} +\`\`\` + +## Key Rules + +### Literal Values vs Data Binding +- **Literal values**: Static values — \`{ literalString: "text" }\`, \`{ literalNumber: 42 }\`, \`{ literalBoolean: true }\` +- **Data binding**: Dynamic values from the data model — \`{ path: "/user/name" }\` +- **NEVER mix** literal and path in the same value +- **IMPORTANT**: Properties like \`fit\`, \`usageHint\`, \`textFieldType\`, \`axis\`, \`direction\` are plain enum strings, NOT literal value wrappers + - Correct: \`"fit": "cover"\` + - WRONG: \`"fit": { "literalString": "cover" }\` + +### Children +- Use \`{ explicitList: ["child-id-1", "child-id-2"] }\` for static children arrays +- Card uses \`child: "child-id"\` (single child, plain string) + +### Actions (Button) +- \`action: { name: "actionName" }\` or \`action: { name: "actionName", context: [{ key: "k", value: { path: "/v" } }] }\` + +### Flat Array Structure +All components are in a flat array — reference children by ID, never nest components. +Every widget needs a root component (ID "root"), usually a Card or Column. + +## Common Patterns + +### Simple Card +\`\`\`json +{ + "components": [ + { "id": "root", "component": { "Card": { "child": "content" } } }, + { "id": "content", "component": { "Column": { "children": { "explicitList": ["title", "desc"] } } } }, + { "id": "title", "component": { "Text": { "text": { "literalString": "Hello" }, "usageHint": "h2" } } }, + { "id": "desc", "component": { "Text": { "text": { "path": "/message" } } } } + ], + "data": { "message": "Welcome!" } +} +\`\`\` + +### Button (requires child Text) +\`\`\`json +{ "id": "btn", "component": { "Button": { "child": "btnText", "action": { "name": "click" } } } }, +{ "id": "btnText", "component": { "Text": { "text": { "literalString": "Click Me" } } } } +\`\`\` + +## Using the editWidget Tool + +Provide: +- \`name\`: Short descriptive name +- \`components\`: Complete JSON string of the components array +- \`data\`: Complete JSON string of the data object + +Always provide ALL components (replacement, not merge). Keep IDs unique. Ensure all referenced child IDs exist.`; diff --git a/tools/composer/src/app/api/copilotkit/a2ui-prompt-v09.ts b/tools/composer/src/app/api/copilotkit/a2ui-prompt-v09.ts new file mode 100644 index 000000000..d7c677de1 --- /dev/null +++ b/tools/composer/src/app/api/copilotkit/a2ui-prompt-v09.ts @@ -0,0 +1,123 @@ +/** + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A2UI v0.9 system prompt for the CopilotKit agent. + * + * Uses the actual v0.9 catalog spec and rules from the specification directory. + */ +import { readFileSync } from 'fs'; +import { join } from 'path'; + +// Load the actual v0.9 catalog spec and rules +const catalogSpec = readFileSync( + join(process.cwd(), '../../specification/v0_9/json/basic_catalog.json'), + 'utf-8', +); + +const catalogRules = readFileSync( + join(process.cwd(), '../../specification/v0_9/json/basic_catalog_rules.txt'), + 'utf-8', +); + +export const A2UI_V09_PROMPT = `You are an expert A2UI v0.9 widget builder. A2UI is a protocol for defining platform-agnostic user interfaces using JSON. + +## Component Catalog (v0.9 Spec) + +${catalogSpec} + +## Catalog Rules + +${catalogRules} + +## Widget Format + +A widget has TWO parts: +1. **components** — A flat array of component definitions (the UI structure) +2. **data** — A JSON object with the data model (the values) + +## Component Structure + +Each component has: +- \`id\`: A unique string identifier +- \`component\`: A string with the component type name +- All properties are top-level (flattened) + +Example: +\`\`\`json +{ + "id": "title", + "component": "Text", + "text": "Hello World", + "variant": "h1" +} +\`\`\` + +## Key Rules + +### Values +- **Static values**: Plain JSON — \`"text"\`, \`42\`, \`true\` +- **Data binding**: \`{ path: "/user/name" }\` +- **Children**: Plain array — \`["child-id-1", "child-id-2"]\` +- Card uses \`child: "child-id"\` (single child) + +### Actions (Button) +- \`action: { event: { name: "actionName" } }\` +- With context: \`action: { event: { name: "actionName", context: { key: { path: "/value" } } } }\` + +### Property Names (v0.9 specific) +- \`variant\` (not \`usageHint\`) for Text, Image, Button, TextField +- \`align\` (not \`alignment\`) for Row, Column +- \`justify\` (not \`distribution\`) for Row, Column +- \`children\` is a plain array (not \`{ explicitList: [...] }\`) +- \`trigger\` and \`content\` (not \`entryPointChild\` / \`contentChild\`) for Modal +- \`tabs\` (not \`tabItems\`) for Tabs +- \`min\` / \`max\` (not \`minValue\` / \`maxValue\`) for Slider +- \`value\` (not \`text\`) for TextField + +### Flat Array Structure +All components are in a flat array — reference children by ID, never nest. +Every widget needs a root component (ID "root"), usually a Card or Column. + +## Common Patterns + +### Simple Card +\`\`\`json +{ + "components": [ + { "id": "root", "component": "Card", "child": "content" }, + { "id": "content", "component": "Column", "children": ["title", "desc"] }, + { "id": "title", "component": "Text", "text": "Hello", "variant": "h2" }, + { "id": "desc", "component": "Text", "text": { "path": "/message" } } + ], + "data": { "message": "Welcome!" } +} +\`\`\` + +### Button (requires child Text) +\`\`\`json +{ "id": "btn", "component": "Button", "child": "btnText", "action": { "event": { "name": "click" } } }, +{ "id": "btnText", "component": "Text", "text": "Click Me" } +\`\`\` + +## Using the editWidget Tool + +Provide: +- \`name\`: Short descriptive name +- \`components\`: Complete JSON string of the components array +- \`data\`: Complete JSON string of the data object + +Always provide ALL components (replacement, not merge). Keep IDs unique. Ensure all referenced child IDs exist.`; diff --git a/tools/composer/src/app/api/copilotkit/a2ui-prompt.ts b/tools/composer/src/app/api/copilotkit/a2ui-prompt.ts deleted file mode 100644 index 10450a5aa..000000000 --- a/tools/composer/src/app/api/copilotkit/a2ui-prompt.ts +++ /dev/null @@ -1,286 +0,0 @@ -/** - * Copyright 2026 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// A2UI Component Catalog and Protocol Schema for LLM prompt -// Based on A2UI Protocol v0.8 - -export const A2UI_COMPONENT_CATALOG = { - "components": { - "Text": { - "description": "Displays text content with optional styling hints", - "properties": { - "text": "The text content - use { literalString: 'value' } for static text or { path: '/data/path' } for data binding", - "usageHint": "Style hint: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'caption' | 'body'" - }, - "required": ["text"] - }, - "Image": { - "description": "Displays an image", - "properties": { - "url": "Image URL - use { literalString: 'url' } or { path: '/data/path' }", - "fit": "'contain' | 'cover' | 'fill' | 'none' | 'scale-down'", - "usageHint": "'icon' | 'avatar' | 'smallFeature' | 'mediumFeature' | 'largeFeature' | 'header'" - }, - "required": ["url"] - }, - "Icon": { - "description": "Displays a named icon", - "properties": { - "name": "Icon name - use { literalString: 'iconName' }. Available: accountCircle, add, arrowBack, arrowForward, attachFile, calendarToday, call, camera, check, close, delete, download, edit, event, error, favorite, favoriteOff, folder, help, home, info, locationOn, lock, lockOpen, mail, menu, moreVert, moreHoriz, notificationsOff, notifications, payment, person, phone, photo, print, refresh, search, send, settings, share, shoppingCart, star, starHalf, starOff, upload, visibility, visibilityOff, warning" - }, - "required": ["name"] - }, - "Row": { - "description": "Horizontal container for children", - "properties": { - "children": "Use { explicitList: ['child-id-1', 'child-id-2'] } for static children", - "distribution": "'start' | 'center' | 'end' | 'spaceBetween' | 'spaceAround' | 'spaceEvenly' (horizontal alignment)", - "alignment": "'start' | 'center' | 'end' | 'stretch' (vertical alignment)" - }, - "required": ["children"] - }, - "Column": { - "description": "Vertical container for children", - "properties": { - "children": "Use { explicitList: ['child-id-1', 'child-id-2'] } for static children", - "distribution": "'start' | 'center' | 'end' | 'spaceBetween' | 'spaceAround' | 'spaceEvenly' (vertical alignment)", - "alignment": "'start' | 'center' | 'end' | 'stretch' (horizontal alignment)" - }, - "required": ["children"] - }, - "Card": { - "description": "A card container with a single child", - "properties": { - "child": "The ID of the component to render inside the card" - }, - "required": ["child"] - }, - "Button": { - "description": "A clickable button", - "properties": { - "child": "The ID of a Text component to display as the button label", - "primary": "boolean - whether this is a primary action button", - "action": "{ name: 'actionName', context: [{ key: 'key', value: { literalString: 'value' } }] }" - }, - "required": ["child", "action"] - }, - "TextField": { - "description": "A text input field", - "properties": { - "label": "Field label - use { literalString: 'Label' }", - "text": "Field value - use { path: '/form/fieldName' } for data binding", - "textFieldType": "'shortText' | 'longText' | 'number' | 'date' | 'obscured'" - }, - "required": ["label"] - }, - "CheckBox": { - "description": "A checkbox input", - "properties": { - "label": "Checkbox label - use { literalString: 'Label' }", - "value": "Checked state - use { literalBoolean: true } or { path: '/form/checked' }" - }, - "required": ["label", "value"] - }, - "Slider": { - "description": "A slider input for numeric values", - "properties": { - "value": "Current value - use { literalNumber: 50 } or { path: '/form/value' }", - "minValue": "Minimum value (number)", - "maxValue": "Maximum value (number)" - }, - "required": ["value"] - }, - "Divider": { - "description": "A visual separator line", - "properties": { - "axis": "'horizontal' | 'vertical'" - } - }, - "List": { - "description": "A scrollable list container", - "properties": { - "children": "Use { explicitList: ['id1', 'id2'] } or { template: { componentId: 'template-id', dataBinding: '/items' } }", - "direction": "'vertical' | 'horizontal'", - "alignment": "'start' | 'center' | 'end' | 'stretch'" - }, - "required": ["children"] - }, - "Tabs": { - "description": "A tabbed container", - "properties": { - "tabItems": "Array of { title: { literalString: 'Tab Name' }, child: 'content-component-id' }" - }, - "required": ["tabItems"] - }, - "Modal": { - "description": "A modal dialog", - "properties": { - "entryPointChild": "ID of the component that triggers the modal (e.g., a button)", - "contentChild": "ID of the component to display inside the modal" - }, - "required": ["entryPointChild", "contentChild"] - }, - "MultipleChoice": { - "description": "A multiple choice selection component", - "properties": { - "selections": "Selected values - use { literalArray: ['option1'] } or { path: '/form/selected' }", - "options": "Array of { label: { literalString: 'Option' }, value: 'option-value' }", - "maxAllowedSelections": "Maximum selections allowed (number)" - }, - "required": ["selections", "options"] - }, - "DateTimeInput": { - "description": "A date/time picker", - "properties": { - "value": "Current value - use { literalString: '' } or { path: '/form/date' }", - "enableDate": "boolean - enable date selection", - "enableTime": "boolean - enable time selection" - }, - "required": ["value"] - } - } -}; - -export const A2UI_SYSTEM_PROMPT = `You are an expert A2UI widget builder. A2UI is a protocol for defining platform-agnostic user interfaces using JSON. - -## IMPORTANT: Widget Format - -You are editing an A2UI widget that has TWO parts: -1. **components** - An array of component definitions (the UI structure) -2. **data** - A JSON object with the data model (the values) - -When using the editWidget tool, you can update either or both parts. - -## Component Structure - -Each component in the array has: -- \`id\`: A unique string identifier -- \`component\`: An object with exactly ONE key (the component type) containing its properties - -Example component: -\`\`\`json -{ - "id": "title", - "component": { - "Text": { - "text": { "literalString": "Hello World" }, - "usageHint": "h1" - } - } -} -\`\`\` - -## Available Components - -${JSON.stringify(A2UI_COMPONENT_CATALOG.components, null, 2)} - -## Key Concepts - -### 1. Literal Values vs Data Binding -- **Literal values**: Static values in the component - - \`{ literalString: "text" }\` - - \`{ literalNumber: 42 }\` - - \`{ literalBoolean: true }\` - - \`{ literalArray: ["a", "b"] }\` -- **Data binding**: Values from the data model using paths - - \`{ path: "/user/name" }\` - reads from data.user.name - -**IMPORTANT: These are MUTUALLY EXCLUSIVE.** Use EITHER a literal value OR a path, NEVER both together. -- ✅ Correct: \`{ literalString: "Hello" }\` -- ✅ Correct: \`{ path: "/user/name" }\` -- ❌ WRONG: \`{ literalString: "Hello", path: "/user/name" }\` - Never mix them! - -### 2. Parent-Child Relationships (Adjacency List) -Components reference children by ID, NOT by nesting. All components are in a flat array. - -**Correct** (flat list with ID references): -\`\`\`json -[ - { "id": "root", "component": { "Column": { "children": { "explicitList": ["title", "content"] } } } }, - { "id": "title", "component": { "Text": { "text": { "literalString": "Title" } } } }, - { "id": "content", "component": { "Text": { "text": { "literalString": "Content" } } } } -] -\`\`\` - -### 3. Root Component -Every widget needs a root component (typically "root" ID) that contains all other components. Usually a Column or Card. - -### 4. Data Model -The data object holds dynamic values that components can bind to: -\`\`\`json -{ - "user": { "name": "John", "email": "john@example.com" }, - "settings": { "darkMode": true } -} -\`\`\` - -Components bind to this using paths: \`{ path: "/user/name" }\` - -## Common Patterns - -### Simple Card with Text -\`\`\`json -{ - "components": [ - { "id": "root", "component": { "Card": { "child": "content" } } }, - { "id": "content", "component": { "Column": { "children": { "explicitList": ["title", "description"] } } } }, - { "id": "title", "component": { "Text": { "text": { "literalString": "Card Title" }, "usageHint": "h2" } } }, - { "id": "description", "component": { "Text": { "text": { "literalString": "Card description text" } } } } - ], - "data": {} -} -\`\`\` - -### Form with Data Binding -\`\`\`json -{ - "components": [ - { "id": "root", "component": { "Column": { "children": { "explicitList": ["nameField", "submitBtn", "submitBtnText"] } } } }, - { "id": "nameField", "component": { "TextField": { "label": { "literalString": "Name" }, "text": { "path": "/form/name" } } } }, - { "id": "submitBtn", "component": { "Button": { "child": "submitBtnText", "action": { "name": "submit" } } } }, - { "id": "submitBtnText", "component": { "Text": { "text": { "literalString": "Submit" } } } } - ], - "data": { "form": { "name": "" } } -} -\`\`\` - -### Button Component (Important!) -Buttons require a child Text component for their label: -\`\`\`json -{ "id": "btn", "component": { "Button": { "child": "btnText", "action": { "name": "click" } } } }, -{ "id": "btnText", "component": { "Text": { "text": { "literalString": "Click Me" } } } } -\`\`\` - -## Using the editWidget Tool - -When editing, always provide complete valid components and/or data. The tool accepts: -- \`data\`: The complete data object to replace the current data -- \`components\`: The complete components array to replace current components - -Example tool call to add a button: -\`\`\` -editWidget({ - components: [ - // ... all existing components plus the new ones - ] -}) -\`\`\` - -Remember: -1. Always include ALL components (it's a replacement, not a merge) -2. Keep component IDs unique -3. Ensure all referenced child IDs exist -4. Use proper data binding syntax for dynamic values`; \ No newline at end of file diff --git a/tools/composer/src/app/components/page.tsx b/tools/composer/src/app/components/page.tsx index 67f0c2f18..505384c76 100644 --- a/tools/composer/src/app/components/page.tsx +++ b/tools/composer/src/app/components/page.tsx @@ -18,20 +18,26 @@ import { useState } from 'react'; import { cn } from '@/lib/utils'; -import { COMPONENTS_DATA, ComponentDoc } from '@/lib/components-data'; -import { A2UIViewer } from '@copilotkit/a2ui-renderer'; +import { COMPONENTS_DATA } from '@/lib/components-data'; +import { COMPONENTS_DATA_V09 } from '@/lib/components-data-v09'; +import type { ComponentDoc } from '@/lib/components-data'; +import { A2UIViewer } from '@/lib/a2ui'; +import { useSpecVersion } from '@/contexts/spec-version-context'; +import type { SpecVersion } from '@/types/widget'; function ComponentSidebar({ selectedComponent, onSelect, + data, }: { selectedComponent: string; onSelect: (name: string) => void; + data: typeof COMPONENTS_DATA; }) { return (