From 771bc054ee7b8714dc7e4f3b8baed9561b05e2a0 Mon Sep 17 00:00:00 2001 From: evanlowe <62918515+evanlowe@users.noreply.github.com> Date: Sat, 22 Aug 2026 22:53:21 +0800 Subject: [PATCH 1/3] feat(studio): add visual agent creation workflow --- frontend/src/App.tsx | 181 +-- frontend/src/adk/client.ts | 32 + frontend/src/create/CreateCanvas.css | 263 ++++ frontend/src/create/CreateCanvas.tsx | 216 ++++ frontend/src/create/CreateNavbar.css | 220 ++++ frontend/src/create/CreateNavbar.tsx | 108 ++ frontend/src/create/CreateWorkspace.css | 303 +++++ frontend/src/create/CreateWorkspace.tsx | 536 ++++++++ frontend/src/create/CreationFlowCanvas.css | 525 ++++++++ frontend/src/create/CreationFlowCanvas.tsx | 861 +++++++++++++ frontend/src/create/DebugWorkspace.css | 406 ++++++ frontend/src/create/DebugWorkspace.tsx | 908 ++++++++++++++ frontend/src/create/DeploymentWorkspace.css | 367 ++++++ frontend/src/create/DeploymentWorkspace.tsx | 178 +++ frontend/src/create/IntelligentCreate.tsx | 4 +- frontend/src/create/TemplateCreate.css | 349 ------ frontend/src/create/TemplateCreate.tsx | 402 ------ .../create/assets/create-workspace/back.svg | 3 + .../assets/create-workspace/collapse.svg | 3 + .../create/assets/create-workspace/copy.svg | 3 + .../assets/create-workspace/dingtalk.svg | 42 + .../assets/create-workspace/download.svg | 3 + .../create/assets/create-workspace/feishu.svg | 47 + .../create/assets/create-workspace/graph.svg | 146 +++ .../create/assets/create-workspace/layout.svg | 5 + .../assets/create-workspace/maximize.svg | 3 + .../assets/create-workspace/message.svg | 3 + .../create/assets/create-workspace/play.svg | 3 + .../assets/create-workspace/publish.svg | 3 + .../create/assets/create-workspace/send.svg | 5 + .../create/assets/create-workspace/slack.svg | 41 + .../assets/create-workspace/thumb-down.svg | 3 + .../assets/create-workspace/thumb-up.svg | 3 + .../create/assets/create-workspace/wecom.svg | 40 + .../assets/create-workspace/zoom-in.svg | 5 + .../assets/create-workspace/zoom-out.svg | 5 + frontend/src/create/types.ts | 6 +- frontend/src/ui/AgentConfigPanel.css | 473 +++++++ frontend/src/ui/AgentConfigPanel.tsx | 474 +++++++ frontend/src/ui/AgentDebugConfigPanel.css | 199 +++ frontend/src/ui/AgentDebugConfigPanel.tsx | 105 ++ frontend/src/ui/AgentModelConfigFields.tsx | 162 +++ frontend/src/ui/AgentStorageConfigDialog.css | 324 +++++ frontend/src/ui/AgentStorageConfigDialog.tsx | 380 ++++++ frontend/src/ui/DeploymentErrorMessage.tsx | 6 +- frontend/src/ui/Sidebar.tsx | 21 +- frontend/tests/agentConfigPanelUi.test.mjs | 260 ++++ frontend/tests/codePackageDeploy.test.mjs | 39 +- .../tests/createWorkspaceNavigation.test.mjs | 351 ++++++ .../tests/debugErrorPresentation.test.mjs | 9 + .../tests/intelligentDevelopment.test.mjs | 4 - frontend/tests/markdownPromptEditor.test.mjs | 1 - frontend/tests/migrationWorkspace.test.mjs | 11 +- frontend/tests/siteBranding.test.mjs | 5 +- .../test_generated_agent_component_matrix.py | 23 + tests/cli/test_generated_agent_planner.py | 50 + veadk/cli/cli_frontend.py | 58 +- veadk/cli/generated_agent_codegen.py | 1 + veadk/cli/generated_agent_planner.py | 129 +- veadk/webui/assets/app/index-CFtkYxt5.js | 1107 ---------------- veadk/webui/assets/app/index-CVgsrej3.js | 1108 +++++++++++++++++ ...XF.js => MarkdownPromptEditor-G7Rc-YDv.js} | 2 +- .../{arc-BHYkO21x.js => arc-DC1MWvFs.js} | 2 +- ...hannel-CquEleFv.js => channel-CRuDCO0H.js} | 2 +- ...{linear-BqPv-BSG.js => linear-WgRKVahV.js} | 2 +- veadk/webui/assets/media/feishu-PEGbi5j4.svg | 47 + veadk/webui/assets/media/wecom-CjLcHtb6.svg | 40 + ...{index-0lb0M8Hb.css => index-eCr3-5Py.css} | 2 +- ...7q.js => abnfDiagram-N423BO3Z-B_MqT24r.js} | 2 +- ... architectureDiagram-T3A2C74G-Lea13Qxs.js} | 2 +- ...r.js => blockDiagram-VBNYF7ZC-DrH2U18m.js} | 2 +- ...OMFY.js => c4Diagram-5PPSVZJV-BG-qs3Xn.js} | 2 +- ...BZ6-8oFM.js => chunk-2GRJ4B5K-DhZDWK1j.js} | 2 +- ...VzujOq0R.js => chunk-2Q5K7J3B-Dmu218OQ.js} | 2 +- ...DgrejSZ7.js => chunk-5RXB4S5H-BRfwBcd4.js} | 2 +- ...Bya697Xa.js => chunk-5VM5RSS4-DHugJ-Di.js} | 2 +- ...BJsk-Dkp.js => chunk-6Q2QTUOP-BG6NdDzy.js} | 2 +- ...UmrEe0dP.js => chunk-GF5L2VYU-BBeyTAdO.js} | 2 +- ...VzQiMWNz.js => chunk-JWPE2WC7-CVUgo0oB.js} | 2 +- ...BsFdqzPA.js => chunk-KBJHAD2P-DWx9HtAP.js} | 2 +- ...BDqyjyvh.js => chunk-RYQCIY6F-CZ2xlNRn.js} | 2 +- ...U12399Ta.js => chunk-XXDRQBXY-RRwtPl4B.js} | 2 +- .../mermaid/classDiagram-JCYQIIEL-CBDzW9hG.js | 1 + .../mermaid/classDiagram-JCYQIIEL-nsAuibyY.js | 1 - .../classDiagram-v2-OCEON4UE-CBDzW9hG.js | 1 + .../classDiagram-v2-OCEON4UE-nsAuibyY.js | 1 - ...k.js => cose-bilkent-JH36ORCC-D2Pkkwox.js} | 2 +- ...gqZd54.js => cynefin-OW5HDTMX-B5xuLTnX.js} | 2 +- ...js => cynefinDiagram-MW4NZA55-VLg15WPh.js} | 2 +- ...DC-XsMNI.js => dagre-VZM6K2ZE-CkdUAHR5.js} | 2 +- ...SXtkAH.js => diagram-7IWD3JNH-DMbo6iDy.js} | 2 +- ...Vm9Je-.js => diagram-B4RE2ZJO-G9SASU28.js} | 2 +- ...kr75Em.js => diagram-LBJQPF4R-CwjXJN_j.js} | 2 +- ...s8aWti.js => diagram-Q27KOJAE-B8bWxbyC.js} | 2 +- ..._Vp29w.js => diagram-UB23O5K3-B6EKHV2l.js} | 2 +- ...kK.js => ebnfDiagram-BXEA7PRR-C3boPoa5.js} | 2 +- ...GVk2.js => erDiagram-JOGREHBK-CTGvcDzH.js} | 2 +- ...X-.js => flowDiagram-UKHOOZJN-C8e1Phzy.js} | 2 +- ...S.js => ganttDiagram-PKOTCBZU-DeXmR8Tx.js} | 2 +- ...s => gitGraphDiagram-DS77QQ5N-D8bq4D9z.js} | 2 +- ...Kq.js => infoDiagram-6WML65LV-DZqo5BdT.js} | 2 +- ...s => ishikawaDiagram-WSZJBQD7-CjjSw-FU.js} | 2 +- ...js => journeyDiagram-NVQOT4AX-TM1C5HUT.js} | 2 +- ...=> kanban-definition-27J2QSJJ-vLHAhJTE.js} | 2 +- ...e-BVnO3lYF.js => mermaid.core-DAZ9Dn9_.js} | 8 +- ...> mindmap-definition-FAOFIHXS-Be3vp1MP.js} | 2 +- ...qbZ.js => pegDiagram-VL7TDLO6-a4JYUSHE.js} | 2 +- ...Tuu.js => pieDiagram-7S7Q4E2Y-7CUoiAww.js} | 2 +- ...s => quadrantDiagram-CIZ2JOQS-BLt1jGRZ.js} | 2 +- ...s => railroadDiagram-AXF67PYL-B5BuTKgp.js} | 2 +- ...> requirementDiagram-LRYGKXZP-CanMd6zT.js} | 2 +- ....js => sankeyDiagram-W5VNT64P-DxZ7STf2.js} | 2 +- ...s => sequenceDiagram-SI44F4Z6-COIFGRO9.js} | 2 +- ...By.js => sizeCapture-X5ZJPWSS-CMIXZ4qM.js} | 2 +- ...d.js => stateDiagram-OKZ733FA-mab5I62k.js} | 2 +- .../stateDiagram-v2-UEYNNEHI-D1btorEW.js | 1 + .../stateDiagram-v2-UEYNNEHI-DP2Rdz7L.js | 1 - ...s2Ud.js => swimlanes-SLNWSIFB-CaFU3NrB.js} | 4 +- .../swimlanesDiagram-ULZ7WXOC-B6EK2k9P.js | 8 + .../swimlanesDiagram-ULZ7WXOC-CCn_FOiG.js | 8 - ... timeline-definition-Z64GVDOM-BRkgAT9t.js} | 2 +- ...Fu.js => vennDiagram-T6HMQDX7-DwcuTLda.js} | 2 +- ...js => wardleyDiagram-T6FBY63Y-2rKWHeOH.js} | 2 +- ...js => xychartDiagram-ELKLHX3M-CRJxH01j.js} | 2 +- veadk/webui/index.html | 4 +- veadk/webui/website-integration.js | 530 ++++---- 126 files changed, 9916 insertions(+), 2372 deletions(-) create mode 100644 frontend/src/create/CreateCanvas.css create mode 100644 frontend/src/create/CreateCanvas.tsx create mode 100644 frontend/src/create/CreateNavbar.css create mode 100644 frontend/src/create/CreateNavbar.tsx create mode 100644 frontend/src/create/CreateWorkspace.css create mode 100644 frontend/src/create/CreateWorkspace.tsx create mode 100644 frontend/src/create/CreationFlowCanvas.css create mode 100644 frontend/src/create/CreationFlowCanvas.tsx create mode 100644 frontend/src/create/DebugWorkspace.css create mode 100644 frontend/src/create/DebugWorkspace.tsx create mode 100644 frontend/src/create/DeploymentWorkspace.css create mode 100644 frontend/src/create/DeploymentWorkspace.tsx delete mode 100644 frontend/src/create/TemplateCreate.css delete mode 100644 frontend/src/create/TemplateCreate.tsx create mode 100644 frontend/src/create/assets/create-workspace/back.svg create mode 100644 frontend/src/create/assets/create-workspace/collapse.svg create mode 100644 frontend/src/create/assets/create-workspace/copy.svg create mode 100644 frontend/src/create/assets/create-workspace/dingtalk.svg create mode 100644 frontend/src/create/assets/create-workspace/download.svg create mode 100644 frontend/src/create/assets/create-workspace/feishu.svg create mode 100644 frontend/src/create/assets/create-workspace/graph.svg create mode 100644 frontend/src/create/assets/create-workspace/layout.svg create mode 100644 frontend/src/create/assets/create-workspace/maximize.svg create mode 100644 frontend/src/create/assets/create-workspace/message.svg create mode 100644 frontend/src/create/assets/create-workspace/play.svg create mode 100644 frontend/src/create/assets/create-workspace/publish.svg create mode 100644 frontend/src/create/assets/create-workspace/send.svg create mode 100644 frontend/src/create/assets/create-workspace/slack.svg create mode 100644 frontend/src/create/assets/create-workspace/thumb-down.svg create mode 100644 frontend/src/create/assets/create-workspace/thumb-up.svg create mode 100644 frontend/src/create/assets/create-workspace/wecom.svg create mode 100644 frontend/src/create/assets/create-workspace/zoom-in.svg create mode 100644 frontend/src/create/assets/create-workspace/zoom-out.svg create mode 100644 frontend/src/ui/AgentConfigPanel.css create mode 100644 frontend/src/ui/AgentConfigPanel.tsx create mode 100644 frontend/src/ui/AgentDebugConfigPanel.css create mode 100644 frontend/src/ui/AgentDebugConfigPanel.tsx create mode 100644 frontend/src/ui/AgentModelConfigFields.tsx create mode 100644 frontend/src/ui/AgentStorageConfigDialog.css create mode 100644 frontend/src/ui/AgentStorageConfigDialog.tsx create mode 100644 frontend/tests/agentConfigPanelUi.test.mjs create mode 100644 frontend/tests/createWorkspaceNavigation.test.mjs delete mode 100644 veadk/webui/assets/app/index-CFtkYxt5.js create mode 100644 veadk/webui/assets/app/index-CVgsrej3.js rename veadk/webui/assets/chunks/{MarkdownPromptEditor-DmV1G1XF.js => MarkdownPromptEditor-G7Rc-YDv.js} (99%) rename veadk/webui/assets/chunks/{arc-BHYkO21x.js => arc-DC1MWvFs.js} (98%) rename veadk/webui/assets/chunks/{channel-CquEleFv.js => channel-CRuDCO0H.js} (53%) rename veadk/webui/assets/chunks/{linear-BqPv-BSG.js => linear-WgRKVahV.js} (98%) create mode 100644 veadk/webui/assets/media/feishu-PEGbi5j4.svg create mode 100644 veadk/webui/assets/media/wecom-CjLcHtb6.svg rename veadk/webui/assets/styles/{index-0lb0M8Hb.css => index-eCr3-5Py.css} (67%) rename veadk/webui/assets/visualizations/mermaid/{abnfDiagram-N423BO3Z-C6f8uF7q.js => abnfDiagram-N423BO3Z-B_MqT24r.js} (85%) rename veadk/webui/assets/visualizations/mermaid/{architectureDiagram-T3A2C74G-DY7RBrYC.js => architectureDiagram-T3A2C74G-Lea13Qxs.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{blockDiagram-VBNYF7ZC-bfGnEaDr.js => blockDiagram-VBNYF7ZC-DrH2U18m.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{c4Diagram-5PPSVZJV-mPM3OMFY.js => c4Diagram-5PPSVZJV-BG-qs3Xn.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{chunk-2GRJ4B5K-BZ6-8oFM.js => chunk-2GRJ4B5K-DhZDWK1j.js} (93%) rename veadk/webui/assets/visualizations/mermaid/{chunk-2Q5K7J3B-VzujOq0R.js => chunk-2Q5K7J3B-Dmu218OQ.js} (66%) rename veadk/webui/assets/visualizations/mermaid/{chunk-5RXB4S5H-DgrejSZ7.js => chunk-5RXB4S5H-BRfwBcd4.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{chunk-5VM5RSS4-Bya697Xa.js => chunk-5VM5RSS4-DHugJ-Di.js} (83%) rename veadk/webui/assets/visualizations/mermaid/{chunk-6Q2QTUOP-BJsk-Dkp.js => chunk-6Q2QTUOP-BG6NdDzy.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{chunk-GF5L2VYU-UmrEe0dP.js => chunk-GF5L2VYU-BBeyTAdO.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{chunk-JWPE2WC7-VzQiMWNz.js => chunk-JWPE2WC7-CVUgo0oB.js} (78%) rename veadk/webui/assets/visualizations/mermaid/{chunk-KBJHAD2P-BsFdqzPA.js => chunk-KBJHAD2P-DWx9HtAP.js} (87%) rename veadk/webui/assets/visualizations/mermaid/{chunk-RYQCIY6F-BDqyjyvh.js => chunk-RYQCIY6F-CZ2xlNRn.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{chunk-XXDRQBXY-U12399Ta.js => chunk-XXDRQBXY-RRwtPl4B.js} (52%) create mode 100644 veadk/webui/assets/visualizations/mermaid/classDiagram-JCYQIIEL-CBDzW9hG.js delete mode 100644 veadk/webui/assets/visualizations/mermaid/classDiagram-JCYQIIEL-nsAuibyY.js create mode 100644 veadk/webui/assets/visualizations/mermaid/classDiagram-v2-OCEON4UE-CBDzW9hG.js delete mode 100644 veadk/webui/assets/visualizations/mermaid/classDiagram-v2-OCEON4UE-nsAuibyY.js rename veadk/webui/assets/visualizations/mermaid/{cose-bilkent-JH36ORCC-CqnGnZ_k.js => cose-bilkent-JH36ORCC-D2Pkkwox.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{cynefin-OW5HDTMX-klgqZd54.js => cynefin-OW5HDTMX-B5xuLTnX.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{cynefinDiagram-MW4NZA55-CsraXHFa.js => cynefinDiagram-MW4NZA55-VLg15WPh.js} (98%) rename veadk/webui/assets/visualizations/mermaid/{dagre-VZM6K2ZE-DC-XsMNI.js => dagre-VZM6K2ZE-CkdUAHR5.js} (97%) rename veadk/webui/assets/visualizations/mermaid/{diagram-7IWD3JNH-CrSXtkAH.js => diagram-7IWD3JNH-DMbo6iDy.js} (96%) rename veadk/webui/assets/visualizations/mermaid/{diagram-B4RE2ZJO-DXVm9Je-.js => diagram-B4RE2ZJO-G9SASU28.js} (97%) rename veadk/webui/assets/visualizations/mermaid/{diagram-LBJQPF4R-ESkr75Em.js => diagram-LBJQPF4R-CwjXJN_j.js} (93%) rename veadk/webui/assets/visualizations/mermaid/{diagram-Q27KOJAE-BVs8aWti.js => diagram-Q27KOJAE-B8bWxbyC.js} (98%) rename veadk/webui/assets/visualizations/mermaid/{diagram-UB23O5K3-Df_Vp29w.js => diagram-UB23O5K3-B6EKHV2l.js} (95%) rename veadk/webui/assets/visualizations/mermaid/{ebnfDiagram-BXEA7PRR-EboexIkK.js => ebnfDiagram-BXEA7PRR-C3boPoa5.js} (87%) rename veadk/webui/assets/visualizations/mermaid/{erDiagram-JOGREHBK-C1u4GVk2.js => erDiagram-JOGREHBK-CTGvcDzH.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{flowDiagram-UKHOOZJN-B6TOeRX-.js => flowDiagram-UKHOOZJN-C8e1Phzy.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{ganttDiagram-PKOTCBZU-D3KlzahS.js => ganttDiagram-PKOTCBZU-DeXmR8Tx.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{gitGraphDiagram-DS77QQ5N-2dalhumv.js => gitGraphDiagram-DS77QQ5N-D8bq4D9z.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{infoDiagram-6WML65LV-BfJHDVKq.js => infoDiagram-6WML65LV-DZqo5BdT.js} (67%) rename veadk/webui/assets/visualizations/mermaid/{ishikawaDiagram-WSZJBQD7-Bv4mJjzR.js => ishikawaDiagram-WSZJBQD7-CjjSw-FU.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{journeyDiagram-NVQOT4AX-BBjWMpLu.js => journeyDiagram-NVQOT4AX-TM1C5HUT.js} (98%) rename veadk/webui/assets/visualizations/mermaid/{kanban-definition-27J2QSJJ-BpXtCJ3x.js => kanban-definition-27J2QSJJ-vLHAhJTE.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{mermaid.core-BVnO3lYF.js => mermaid.core-DAZ9Dn9_.js} (98%) rename veadk/webui/assets/visualizations/mermaid/{mindmap-definition-FAOFIHXS-B5QXBZ-K.js => mindmap-definition-FAOFIHXS-Be3vp1MP.js} (98%) rename veadk/webui/assets/visualizations/mermaid/{pegDiagram-VL7TDLO6-CBAXjqbZ.js => pegDiagram-VL7TDLO6-a4JYUSHE.js} (86%) rename veadk/webui/assets/visualizations/mermaid/{pieDiagram-7S7Q4E2Y-B5OfcTuu.js => pieDiagram-7S7Q4E2Y-7CUoiAww.js} (95%) rename veadk/webui/assets/visualizations/mermaid/{quadrantDiagram-CIZ2JOQS-CH7i7eU6.js => quadrantDiagram-CIZ2JOQS-BLt1jGRZ.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{railroadDiagram-AXF67PYL-DPLBrk6_.js => railroadDiagram-AXF67PYL-B5BuTKgp.js} (84%) rename veadk/webui/assets/visualizations/mermaid/{requirementDiagram-LRYGKXZP-CwUzp3js.js => requirementDiagram-LRYGKXZP-CanMd6zT.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{sankeyDiagram-W5VNT64P-G9FQGWLH.js => sankeyDiagram-W5VNT64P-DxZ7STf2.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{sequenceDiagram-SI44F4Z6-BmraS3eG.js => sequenceDiagram-SI44F4Z6-COIFGRO9.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{sizeCapture-X5ZJPWSS-fEU2-yBy.js => sizeCapture-X5ZJPWSS-CMIXZ4qM.js} (87%) rename veadk/webui/assets/visualizations/mermaid/{stateDiagram-OKZ733FA-C1y0VuZd.js => stateDiagram-OKZ733FA-mab5I62k.js} (96%) create mode 100644 veadk/webui/assets/visualizations/mermaid/stateDiagram-v2-UEYNNEHI-D1btorEW.js delete mode 100644 veadk/webui/assets/visualizations/mermaid/stateDiagram-v2-UEYNNEHI-DP2Rdz7L.js rename veadk/webui/assets/visualizations/mermaid/{swimlanes-SLNWSIFB-DrDzs2Ud.js => swimlanes-SLNWSIFB-CaFU3NrB.js} (99%) create mode 100644 veadk/webui/assets/visualizations/mermaid/swimlanesDiagram-ULZ7WXOC-B6EK2k9P.js delete mode 100644 veadk/webui/assets/visualizations/mermaid/swimlanesDiagram-ULZ7WXOC-CCn_FOiG.js rename veadk/webui/assets/visualizations/mermaid/{timeline-definition-Z64GVDOM-DK8JlCR3.js => timeline-definition-Z64GVDOM-BRkgAT9t.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{vennDiagram-T6HMQDX7-DlgdwYFu.js => vennDiagram-T6HMQDX7-DwcuTLda.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{wardleyDiagram-T6FBY63Y-B75iWodl.js => wardleyDiagram-T6FBY63Y-2rKWHeOH.js} (99%) rename veadk/webui/assets/visualizations/mermaid/{xychartDiagram-ELKLHX3M-BpITSryf.js => xychartDiagram-ELKLHX3M-CRJxH01j.js} (99%) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6aa3b4f18..3775f6643 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -124,7 +124,8 @@ import { Blocks, ThinkingPlaceholder } from "./ui/Blocks"; import { Composer } from "./ui/Composer"; import { InvocationChips } from "./ui/InvocationChips"; import { MediaGroup } from "./ui/Media"; -import { StackCards } from "./ui/AddAgentMenu"; +import { CreateCanvas } from "./create/CreateCanvas"; +import { CreateWorkspace } from "./create/CreateWorkspace"; import { IntelligentCreate, type IntelligentPreparationStage, @@ -339,7 +340,7 @@ async function loadHydratedSessions( } type CreateView = "custom" | "package" | "migration" | null; -type AppView = CreateView | "intelligent"; +type AppView = CreateView | "intelligent" | "intelligent-workspace"; type CustomCreateMode = "custom" | "yaml_import"; type StudioPageId = | "new-chat" @@ -470,7 +471,7 @@ function mentionableDescendants(node: AgentNode): AgentTarget[] { function loadView(): AppView { const v = typeof localStorage !== "undefined" ? localStorage.getItem(LS.view) : null; if (v === "intelligent") return v; - if (["menu", "custom", "template", "workflow"].includes(v ?? "")) { + if (["menu", "custom", "workflow"].includes(v ?? "")) { return "custom"; } return v === "package" || v === "migration" ? v : null; @@ -547,66 +548,6 @@ function telemetrySandboxStatus( } } -/** Hand-drawn "from zero" mark: a blank Agent canvas ready to create. */ -function ScratchIcon({ className }: { className?: string }) { - return ( - - ); -} - -/** Hand-drawn code package mark: an archive with source inside. */ -function PackageIcon({ className }: { className?: string }) { - return ( - - ); -} - -/** Hand-drawn migration mark: an existing project moving into a new runtime. */ -function MigrationIcon({ className }: { className?: string }) { - return ( - - ); -} - /** Hand-drawn "tracing / observability" icon (stacked spans). */ function TraceIcon() { return ( @@ -1927,6 +1868,7 @@ export default function App() { } }; const [createView, setCreateView] = useState(loadView); + const [intelligentInitialGoal, setIntelligentInitialGoal] = useState(""); const [deploymentTasks, setDeploymentTasks] = useState< DeploymentTaskUpdate[] >([]); @@ -3041,6 +2983,8 @@ export default function App() { ? runtimeUpdateTarget?.name ? `更新 ${runtimeUpdateTarget.name}` : "创建智能体" + : createView === "intelligent-workspace" + ? "创建智能体" : createView === "package" ? "从代码包添加" : "迁移智能体", @@ -5931,6 +5875,7 @@ export default function App() { ) : showAddMenu ? ( - { - setAddMenu(false); - setImportedDraft(null); - setCustomCreateMode("custom"); - setRuntimeUpdateTarget(null); - setFocusedDeploymentTaskId(""); - setFocusedWorkspaceAgentId(""); - setEditingDraftId(`draft-${Date.now().toString(36)}`); - editingDraftBaselineRef.current = null; - setCreateView("custom"); - }, - }, - { - key: "intelligent", - icon: ScratchIcon, - title: "智能模式", - desc: intelligentCapabilitiesError - || intelligentCapabilities?.reason - || "描述目标,按你的意图构建、调试并验证 Agent。", - status: intelligentCapabilitiesLoading - ? "能力检查中" - : intelligentCapabilities?.enabled - ? undefined - : "暂不可用", - disabled: - intelligentCapabilitiesLoading || - intelligentCapabilities?.enabled !== true, - onClick: () => { - setAddMenu(false); - setImportedDraft(null); - setRuntimeUpdateTarget(null); - setFocusedDeploymentTaskId(""); - setFocusedWorkspaceAgentId(""); - setEditingDraftId(""); - editingDraftBaselineRef.current = null; - setCreateView("intelligent"); - }, - }, - { - key: "package", - icon: PackageIcon, - title: "从代码包添加和部署", - desc: "上传 Agent 项目压缩包,查看代码并直接部署到 AgentKit Runtime。", - onClick: () => { - setAddMenu(false); - setImportedDraft(null); - setCreateView("package"); - }, - }, - { - key: "migration", - icon: MigrationIcon, - title: "从存量迁移", - desc: "从您的 LangChain / Dify 等存量项目迁移至 AgentKit Runtime", - onClick: () => { - setAddMenu(false); - setImportedDraft(null); - setCreateView("migration"); - }, - }, - ]} + { + setIntelligentInitialGoal(prompt); + setAddMenu(false); + setCreateView("intelligent-workspace"); + }} + onBlank={() => { + setAddMenu(false); + setImportedDraft(null); + setCustomCreateMode("custom"); + setRuntimeUpdateTarget(null); + setFocusedDeploymentTaskId(""); + setFocusedWorkspaceAgentId(""); + setEditingDraftId(`draft-${Date.now().toString(36)}`); + editingDraftBaselineRef.current = null; + setCreateView("custom"); + }} + onUploadPackage={() => { + setAddMenu(false); + setImportedDraft(null); + setCreateView("package"); + }} + onMigration={() => { + setAddMenu(false); + setImportedDraft(null); + setCreateView("migration"); + }} /> ) : searchView ? ( - ) : visibleCreateView !== null && !["menu", "intelligent"].includes(visibleCreateView) && !hasCreds ? ( + ) : visibleCreateView !== null && !["menu", "intelligent", "intelligent-workspace"].includes(visibleCreateView) && !hasCreds ? (
+ ) : visibleCreateView === "intelligent-workspace" ? ( + { + setCreateView(null); + setAddMenu(true); + }} + /> ) : visibleCreateView === "intelligent" ? ( (res, "生成 Agent 配置失败"); } +export async function chatWithGeneratedAgent( + sessionId: string, + message: string, + signal?: AbortSignal, +): Promise { + const res = await apiFetch( + "/web/generated-agent-conversations", + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ sessionId, message }), + signal, + }, + {}, + GENERATED_AGENT_DRAFT_TIMEOUT_MS + 60_000, + ); + if (!res.ok) { + throw new Error(await httpErrorMessage(res, "创建助手回复失败")); + } + return parseJsonResponse( + res, + "创建助手回复失败", + ); +} + export async function createGeneratedAgentTestRun( draft: AgentDraft, runtime?: { runtimeId: string; region: string }, diff --git a/frontend/src/create/CreateCanvas.css b/frontend/src/create/CreateCanvas.css new file mode 100644 index 000000000..9abe4f5fd --- /dev/null +++ b/frontend/src/create/CreateCanvas.css @@ -0,0 +1,263 @@ +.create-canvas { + position: relative; + flex: 1; + min-width: 0; + min-height: 0; + overflow: hidden; + border-radius: 0; + background-color: hsl(var(--canvas)); + background-image: radial-gradient( + circle, + hsl(var(--foreground) / 0.09) 0 1px, + transparent 1.15px + ); + background-position: 8px 15px; + background-size: 18px 18px; +} + +.create-canvas, +.create-canvas *, +.create-canvas *::before, +.create-canvas *::after { + box-sizing: border-box; +} + +.create-canvas__send:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; +} + +.create-canvas__hero { + position: absolute; + z-index: 1; + top: 349px; + left: 50%; + width: min(800px, calc(100% - 32px)); + transform: translateX(-50%); +} + +.create-canvas__hero-title { + height: 45px; + display: flex; + align-items: center; + gap: 12px; +} + +.create-canvas__hero-title > svg { + width: 36px; + height: 36px; + flex: 0 0 36px; + color: #101013; +} + +.create-canvas__hero-title h2 { + margin: 0; + color: #101013; + font-size: 32px; + font-weight: 500; + line-height: 45px; + letter-spacing: -0.01em; +} + +.create-canvas__composer { + height: 54px; + display: flex; + align-items: center; + gap: 12px; + margin-top: 24px; + padding: 0 16px 0 20px; + border: 1px solid rgba(31, 35, 41, 0.08); + border-radius: 16px; + background: #fff; +} + +.create-canvas__composer:focus-within { + border-color: rgba(31, 35, 41, 0.18); +} + +.create-canvas__composer textarea { + min-width: 0; + height: 22px; + flex: 1; + overflow: hidden; + padding: 0; + border: 0; + outline: 0; + resize: none; + background: transparent; + color: #101013; + font: inherit; + font-size: 14px; + font-weight: 400; + line-height: 22px; + white-space: nowrap; +} + +.create-canvas__composer textarea::placeholder { + color: #7a7880; + opacity: 1; +} + +.create-canvas__send { + width: 32px; + height: 32px; + flex: 0 0 32px; + display: inline-grid; + place-items: center; + padding: 0; + border: 0; + border-radius: 50%; + background: #101013; + color: #fff; + cursor: pointer; +} + +.create-canvas__send:disabled { + background: rgba(0, 0, 0, 0.2); + cursor: default; +} + +.create-canvas__send svg { + width: 20px; + height: 20px; +} + +.create-canvas__shortcuts { + position: absolute; + left: 50%; + bottom: 49px; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 16px; + width: min(800px, calc(100% - 32px)); + transform: translateX(-50%); +} + +.create-canvas__shortcut { + min-width: 0; + height: 80px; + display: flex; + align-items: center; + gap: 12px; + padding: 16px; + border: 0; + border-radius: 16px; + background: hsl(var(--background)); + color: hsl(var(--foreground)); + box-shadow: 0 0 2px hsl(var(--foreground) / 0.06); + cursor: pointer; + font: inherit; + text-align: left; + transition: + background-color 160ms ease-out, + box-shadow 160ms ease-out; +} + +.create-canvas__shortcut:hover { + background: hsl(var(--background) / 0.94); + box-shadow: 0 4px 16px hsl(var(--foreground) / 0.08); +} + +.create-canvas__shortcut:active { + background: hsl(var(--background) / 0.88); +} + +.create-canvas__shortcut:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; +} + +.create-canvas__shortcut-icon { + width: 48px; + height: 48px; + flex: 0 0 48px; + display: inline-grid; + place-items: center; + border-radius: 14px; + background: hsl(var(--canvas)); +} + +.create-canvas__shortcut-icon svg { + width: 24px; + height: 24px; +} + +.create-canvas__shortcut-copy { + min-width: 0; + display: flex; + flex: 1; + flex-direction: column; + align-items: flex-start; + gap: 2px; +} + +.create-canvas__shortcut-title { + max-width: 100%; + overflow: hidden; + color: hsl(var(--sidebar-foreground)); + font-size: 14px; + font-weight: 500; + line-height: 22px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.create-canvas__shortcut-description { + max-width: 100%; + overflow: hidden; + color: hsl(var(--sidebar-section-title)); + font-size: 13px; + font-weight: 400; + line-height: 19.5px; + text-overflow: ellipsis; + white-space: nowrap; +} + +@media (max-width: 720px) { + .create-canvas__hero { + top: 112px; + } + + .create-canvas__hero-title { + height: auto; + align-items: flex-start; + } + + .create-canvas__hero-title > svg { + width: 30px; + height: 30px; + flex-basis: 30px; + } + + .create-canvas__hero-title h2 { + font-size: 24px; + line-height: 32px; + } + + .create-canvas__composer { + margin-top: 18px; + } + + .create-canvas__shortcuts { + bottom: 16px; + grid-template-columns: minmax(0, 1fr); + gap: 10px; + } + + .create-canvas__shortcut { + height: 72px; + padding: 12px; + } + + .create-canvas__shortcut-icon { + width: 44px; + height: 44px; + flex-basis: 44px; + } +} + +@media (prefers-reduced-motion: reduce) { + .create-canvas__shortcut { + transition: none; + } +} diff --git a/frontend/src/create/CreateCanvas.tsx b/frontend/src/create/CreateCanvas.tsx new file mode 100644 index 000000000..024899df6 --- /dev/null +++ b/frontend/src/create/CreateCanvas.tsx @@ -0,0 +1,216 @@ +import { useState, type ComponentType, type SVGProps } from "react"; +import { isImeCompositionEvent } from "../ui/composerKeyboard"; +import { CreateNavbar } from "./CreateNavbar"; +import "./CreateCanvas.css"; + +interface CreateCanvasProps { + onBack: () => void; + onPromptSubmit: (prompt: string) => void; + onBlank: () => void; + onUploadPackage: () => void; + onMigration: () => void; +} + +interface CreateShortcut { + key: string; + title: string; + description: string; + icon: ComponentType>; + onClick: () => void; +} + +function BlankCreateIcon(props: SVGProps) { + return ( + + ); +} + +function UploadCodeIcon(props: SVGProps) { + return ( + + ); +} + +function MigrationCubeIcon(props: SVGProps) { + return ( + + ); +} + +function CreateAgentIcon(props: SVGProps) { + return ( + + ); +} + +function SendIcon(props: SVGProps) { + return ( + + ); +} + +export function CreateCanvas({ + onBack, + onPromptSubmit, + onBlank, + onUploadPackage, + onMigration, +}: CreateCanvasProps) { + const [prompt, setPrompt] = useState(""); + const shortcuts: CreateShortcut[] = [ + { + key: "blank", + title: "从空白创建", + description: "手动配置智能体", + icon: BlankCreateIcon, + onClick: onBlank, + }, + { + key: "package", + title: "上传代码包", + description: "查看代码并一键部署", + icon: UploadCodeIcon, + onClick: onUploadPackage, + }, + { + key: "migration", + title: "存量迁移", + description: "从 LangChain/Dify 等迁移", + icon: MigrationCubeIcon, + onClick: onMigration, + }, + ]; + + function submitPrompt() { + const value = prompt.trim(); + if (value) onPromptSubmit(value); + } + + return ( +
+ + +
+
+ +

描述你想创建的智能体

+
+
+