@rubytech/create-maxy-code 0.1.427 → 0.1.431
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/lib/embed-client/dist/index.d.ts +5 -1
- package/payload/platform/lib/embed-client/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/embed-client/dist/index.js +114 -36
- package/payload/platform/lib/embed-client/dist/index.js.map +1 -1
- package/payload/platform/lib/embed-client/src/index.ts +141 -34
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +72 -4
- package/payload/platform/plugins/docs/PLUGIN.md +1 -0
- package/payload/platform/plugins/docs/references/admin-ui.md +2 -0
- package/payload/platform/plugins/docs/references/internals.md +3 -3
- package/payload/platform/plugins/docs/references/workflows.md +61 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js +92 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.js +56 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-timeout.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js +56 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js.map +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/resolve-read-account.d.ts +8 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/resolve-read-account.d.ts.map +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/resolve-read-account.js +8 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/resolve-read-account.js.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/lib/embeddings.d.ts +9 -3
- package/payload/platform/plugins/work/mcp/dist/lib/embeddings.d.ts.map +1 -1
- package/payload/platform/plugins/work/mcp/dist/lib/embeddings.js +19 -15
- package/payload/platform/plugins/work/mcp/dist/lib/embeddings.js.map +1 -1
- package/payload/platform/plugins/workflows/PLUGIN.md +29 -9
- package/payload/platform/plugins/workflows/mcp/dist/index.js +34 -0
- package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.d.ts +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.js +7 -18
- package/payload/platform/plugins/workflows/mcp/dist/lib/embeddings.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts +2 -2
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts +25 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js +14 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts +25 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +79 -15
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.d.ts +2 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js +4 -0
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.d.ts +3 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js +8 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js.map +1 -1
- package/payload/platform/plugins/workflows/skills/workflow-manager/SKILL.md +24 -3
- package/payload/platform/services/telegram-channel/dist/instructions.js +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +10 -5
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/notification.js +9 -6
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/telegram-channel/dist/server.js +15 -5
- package/payload/platform/services/telegram-channel/dist/server.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/instructions.js +1 -1
- package/payload/platform/services/webchat-channel/dist/instructions.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.d.ts +12 -10
- package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.js +12 -11
- package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/webchat-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/server.js +12 -1
- package/payload/platform/services/webchat-channel/dist/server.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +11 -6
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +11 -8
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/server.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/server.js +39 -14
- package/payload/platform/services/whatsapp-channel/dist/server.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/targets.d.ts +17 -2
- package/payload/platform/services/whatsapp-channel/dist/targets.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/targets.js +37 -2
- package/payload/platform/services/whatsapp-channel/dist/targets.js.map +1 -1
- package/payload/server/{chunk-3Z5WE53X.js → chunk-UUG6ZSO5.js} +65 -9
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/AdminLoginScreens-CcW3pAAZ.js +1 -0
- package/payload/server/public/assets/AdminShell-BfLQQ27Z.js +2 -0
- package/payload/server/public/assets/{Checkbox-B_lfjsqd.js → Checkbox-BC0c_gbn.js} +1 -1
- package/payload/server/public/assets/admin-Co3hOTNp.js +1 -0
- package/payload/server/public/assets/{arc-dVLpR-ec.js → arc-qKfXIt8v.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-FPHT7s-C.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-C6u_CVzb.js → architectureDiagram-Q4EWVU46-DkVrGn7G.js} +1 -1
- package/payload/server/public/assets/audio-attachment-mime-CwYrV1pg.js +2 -0
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-Cy8F5b8O.js → blockDiagram-DXYQGD6D-DqavswGH.js} +1 -1
- package/payload/server/public/assets/{browser-CCWufeXr.js → browser-CvZxNdKw.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DRXrlepj.js → c4Diagram-AHTNJAMY-B7fyKiXe.js} +1 -1
- package/payload/server/public/assets/calendar-DXxLMF2J.js +1 -0
- package/payload/server/public/assets/channel-j70eMvcL.js +1 -0
- package/payload/server/public/assets/chat-rxbGimwf.js +1 -0
- package/payload/server/public/assets/chevron-left-CLPxfjDV.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-fEyfhRLz.js → chunk-2KRD3SAO-DsgMtGkv.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-NUWO4y7q.js → chunk-336JU56O-CkdISfNt.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-D-NcAlTW.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-BnfiNR3l.js → chunk-4BX2VUAB-CYpiF2bl.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-Bj_aJOz8.js → chunk-4TB4RGXK-CWyc_F7v.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-aK0DNSKb.js → chunk-55IACEB6-BbzKMw2Z.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-DeqAkq5C.js → chunk-5FUZZQ4R-u19Nai9e.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-SShlujAQ.js → chunk-5PVQY5BW-Ba8by6Uy.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-CZpzQ0DL.js → chunk-67CJDMHE-BwUuxtyb.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-COnjO6jy.js → chunk-7N4EOEYR-BRH9iM9L.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-C9V31L2z.js → chunk-AA7GKIK3-BGoztgLL.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-DSwnSGe3.js → chunk-BSJP7CBP-C5GDAZTl.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-CnRUTuta.js → chunk-CIAEETIT-ChY32VPS.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-BexiL2LH.js → chunk-EDXVE4YY-CPSD3p6p.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-aTklWdJQ.js → chunk-ENJZ2VHE-D1oL-iUr.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-svcEBQzs.js → chunk-FMBD7UC4-CPvYEr54.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-CG7R7Xri.js → chunk-FOC6F5B3-9Yyj7Vbz.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-CGN7Z4x9.js → chunk-ICPOFSXX-BaYgh8FR.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-CWBh78jw.js → chunk-K5T4RW27-5ucpeRvm.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-Ctiq4q-5.js → chunk-KGLVRYIC-DW-FHk7T.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-BII77Q7K.js → chunk-LIHQZDEY-CGGVfAyG.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-DT7R01H8.js → chunk-ORNJ4GCN-Bv8EUa5d.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-y-Jkbd4C.js → chunk-OYMX7WX6-C1mXJnyw.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-CAwbQBtf.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-DzFo6KbQ.js → chunk-U2HBQHQK-PwSQz6EP.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-CYSwgtLV.js → chunk-X2U36JSP--NPHTBlU.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-DHlM4tOn.js → chunk-XPW4576I-Bbc7Da32.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-B20rTmLl.js → chunk-YZCP3GAM-D-9v8e--.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-C7hP4J8m.js → chunk-ZZ45TVLE-CMPg670Q.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-Ct6Rn0vt.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-B_2XCIFv.js +1 -0
- package/payload/server/public/assets/clone-DjPWA_NH.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-nKjTv9sR.js → cose-bilkent-S5V4N54A-NVSb1Bhy.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-BNJYTnls.js → dagre-KV5264BT-V2Ai1DFl.js} +1 -1
- package/payload/server/public/assets/{dagre-Cx8LiiUZ.js → dagre-QfLcO-1j.js} +1 -1
- package/payload/server/public/assets/data-D0YFYP1i.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-CoAN5_f9.js → diagram-5BDNPKRD-Caw21693.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-pRmsN4_x.js → diagram-G4DWMVQ6-CgwVkT2q.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-CRoylyp4.js → diagram-MMDJMWI5-DFUrLZhs.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-BT3ZtG5b.js → diagram-TYMM5635-CEEiEuZJ.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DSKws1ZV.js → erDiagram-SMLLAGMA-CG10NrT3.js} +1 -1
- package/payload/server/public/assets/file-download-B2B2DTar.js +1 -0
- package/payload/server/public/assets/{flatten-jn8bZgcI.js → flatten-DAO0sfCM.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-C2L38ZE5.js → flowDiagram-DWJPFMVM-BqkV9Okv.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-Bm2h-vjm.js → ganttDiagram-T4ZO3ILL-DRiCDQF6.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-B8Hx7f-D.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-BoowbF7u.js → gitGraphDiagram-UUTBAWPF-BZV2voyy.js} +1 -1
- package/payload/server/public/assets/graph-DRNzDBTV.js +51 -0
- package/payload/server/public/assets/{graph-labels-BLx-0vyT.js → graph-labels-DxqDdO7G.js} +1 -1
- package/payload/server/public/assets/{graphlib-BvT2s_o1.js → graphlib-DGPThX8M.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-BicCJTqU.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-tf-8rOez.js +2 -0
- package/payload/server/public/assets/{isEmpty-Dkk6_L-B.js → isEmpty-Cb_U81C6.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-nxcmj-IX.js → ishikawaDiagram-UXIWVN3A-BKsAxSvp.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-q5SNIvmS.js → journeyDiagram-VCZTEJTY-CmliuOd-.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-BugG9Q1o.js → kanban-definition-6JOO6SKY-DAlElMb-.js} +1 -1
- package/payload/server/public/assets/{line-MZCQLR-q.js → line-DKZqLKAC.js} +1 -1
- package/payload/server/public/assets/{linear-DmQGNk-g.js → linear-CbSGdh1x.js} +1 -1
- package/payload/server/public/assets/{maximize-2-CnNQnj_v.js → maximize-2-DKx6OBKv.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-DvoeqLxw.js → mermaid-parser.core-DFvbao9C.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-BLaw7iG4.js → mermaid.core-C0vEBxDm.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-DMkt10Vc.js → mindmap-definition-QFDTVHPH-CShASUKd.js} +1 -1
- package/payload/server/public/assets/operator-Djv3MdcL.js +1 -0
- package/payload/server/public/assets/{ordinal-DuJYM7p1.js → ordinal-H0tVmBDP.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-Ckn_5hq0.js +1 -0
- package/payload/server/public/assets/page-Ci27UrJz.js +32 -0
- package/payload/server/public/assets/page-D1EAVC_9.js +1 -0
- package/payload/server/public/assets/{pdf-render-riHufgrn.js → pdf-render-jAQU0nXt.js} +1 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-DzlGQW3J.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-DRp4lD2B.js → pieDiagram-DEJITSTG-CBZHpDAJ.js} +1 -1
- package/payload/server/public/assets/{play-yEkd7ouW.js → play-DHttF4fl.js} +1 -1
- package/payload/server/public/assets/public-C6k-fPfx.js +1 -0
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-DkT63Dn4.js → quadrantDiagram-34T5L4WZ-n3bB3K91.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-BHo2YD8b.js +1 -0
- package/payload/server/public/assets/{reduce-COyotL2V.js → reduce-DAvwat-a.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-65GGtDkc.js → requirementDiagram-MS252O5E-DiDvQK3c.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-D1vRwLWd.js → sankeyDiagram-XADWPNL6-DWDQQZmd.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-Bp47ZSN2.js → sequenceDiagram-FGHM5R23-DmAqRlBT.js} +1 -1
- package/payload/server/public/assets/square-CHcQHtK8.js +1 -0
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-BZHHcP_e.js → stateDiagram-FHFEXIEX-D4R-n6bZ.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BcFRbGRu.js +1 -0
- package/payload/server/public/assets/tasks-ClfJU1CK.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DZ1wUyj-.js → timeline-definition-GMOUNBTQ-CjiHGP4l.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-BtRr5vXp.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-D8p0sbyo.js +1 -0
- package/payload/server/public/assets/useCopyFeedback-CPEOUSGU.js +1 -0
- package/payload/server/public/assets/{useSubAccountSwitcher-ayajZz8T.css → useSubAccountSwitcher-CdS1CorH.css} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CttBahsn.js → vennDiagram-DHZGUBPP-CBdDQ7c-.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-DgMn-9ZJ.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-Y5tWieZg.js → wardleyDiagram-NUSXRM2D-BlIQPKLb.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-C78A9qbe.js → xychartDiagram-5P7HB3ND-CslKgh9B.js} +1 -1
- package/payload/server/public/browser.html +6 -6
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +13 -14
- package/payload/server/public/data.html +10 -10
- package/payload/server/public/graph.html +11 -11
- package/payload/server/public/index.html +14 -15
- package/payload/server/public/operator.html +15 -16
- package/payload/server/public/public.html +13 -14
- package/payload/server/public/tasks.html +5 -5
- package/payload/server/server.js +321 -32
- package/payload/server/public/assets/AdminLoginScreens-yAIhWcGc.js +0 -1
- package/payload/server/public/assets/AdminShell-Bk1AFQ4D.js +0 -2
- package/payload/server/public/assets/Transcript-D67OZnVM.js +0 -2
- package/payload/server/public/assets/admin-DuOhkvrZ.js +0 -1
- package/payload/server/public/assets/admin-types-ClHBm0ni.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-CgeA3HPD.js +0 -1
- package/payload/server/public/assets/calendar-CNk1iPrA.js +0 -1
- package/payload/server/public/assets/channel-B04VBWf7.js +0 -1
- package/payload/server/public/assets/chat-7qB-dwBq.js +0 -1
- package/payload/server/public/assets/chevron-left-CpcDbHIz.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-DZkHcXRA.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-D9Mwgzti.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-CIo_TzfF.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-SzQYvAUZ.js +0 -1
- package/payload/server/public/assets/clone-BVjcjsBA.js +0 -1
- package/payload/server/public/assets/data-BnHcS27X.js +0 -1
- package/payload/server/public/assets/file-download-Hf_UILaA.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DzQ18i0T.js +0 -1
- package/payload/server/public/assets/graph-klLugHEK.js +0 -51
- package/payload/server/public/assets/info-OMHHGYJF-CwsoaVzV.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-ieNsH2bV.js +0 -2
- package/payload/server/public/assets/operator-CRcySYv9.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-DxB-bO4L.js +0 -1
- package/payload/server/public/assets/page-CVo3CWIY.js +0 -1
- package/payload/server/public/assets/page-DPTbZRwl.js +0 -32
- package/payload/server/public/assets/pie-ZZUOXDRM-PSdKvB8-.js +0 -1
- package/payload/server/public/assets/public-Fi6ccYaE.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-D8FqRiWq.js +0 -1
- package/payload/server/public/assets/rotate-ccw-xHksz9mr.js +0 -1
- package/payload/server/public/assets/square-BZqaxg7D.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-qVtoGx56.js +0 -1
- package/payload/server/public/assets/tasks-COWmfts8.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-i-w4rJmQ.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-Dij6AlAj.js +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-BJhOQVqW.js +0 -1
- /package/payload/server/public/assets/{_baseFor-Bjj9It3Q.js → _baseFor-D3BqAOBr.js} +0 -0
- /package/payload/server/public/assets/{array-BrrxEo12.js → array-iYP9fzJp.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-CTWJxUxo.js → cytoscape.esm-BQSBzPsB.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-CFDbRV4k.js → defaultLocale-BrdA1gDi.js} +0 -0
- /package/payload/server/public/assets/{dist-CRpLAnCP.js → dist-Cvgxm7qv.js} +0 -0
- /package/payload/server/public/assets/{init-dXCzGgLP.js → init-Bx0S6pkp.js} +0 -0
- /package/payload/server/public/assets/{katex-CHA1JFYJ.js → katex-BsiH_a6d.js} +0 -0
- /package/payload/server/public/assets/{path-CCRpdXhK.js → path-BLSgTy3w.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-CH6UZRzu.js → preload-helper-ClBMtM1g.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-Bud4g4fh.js → rough.esm-BMOtDaaS.js} +0 -0
- /package/payload/server/public/assets/{src-xN1oULc8.js → src-DV4LKv2E.js} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-DADvGnr1.js → useSubAccountSwitcher-DyjTbzQR.js} +0 -0
|
@@ -24,6 +24,7 @@ Load these when users ask about Maxy features or need guidance:
|
|
|
24
24
|
- **Settings** → `references/settings.md` — output style, effort level, account preferences
|
|
25
25
|
- **Access Control** → `references/access-control.md` — who can chat with your public agent, invitations, authentication
|
|
26
26
|
- **Projects** → `references/projects-guide.md` — creating projects, tracking health, phase transitions, completing
|
|
27
|
+
- **Workflows** → `references/workflows.md` — saving and running multi-step processes, declared inputs, scheduling, run history
|
|
27
28
|
- **Slides** → `references/slides.md` — generating, theming, and reviewing HTML slide decks with `/slides`
|
|
28
29
|
- **Calendar & booking** → `references/calendar-booking.md` — the admin calendar at `/calendar`, deploying a public booking page, setting availability, and how bookings become meetings
|
|
29
30
|
- **Troubleshooting** → `references/troubleshooting.md` — common issues and how to resolve them
|
|
@@ -75,6 +75,8 @@ either is a regression.
|
|
|
75
75
|
|
|
76
76
|
**`/chat` Claude-desktop transcript presentation.** The admin webchat keeps the shared `Transcript` shell (stream, follow-tail) but injects a /chat-only item renderer via the component's optional `renderItems` prop: `renderChatTimeline` in `app/chat/transcript-render.tsx`. Presentation: operator turns render as a right-aligned grey bubble showing the message text and, beneath it, a subtle always-visible time-of-day stamp (no label); delivered agent replies render as plain prose with the same time-of-day stamp beneath (the reply-document filename line stays, as prose); the stamp is HH:MM from the turn's `ts` (locale-formatted, right-aligned inside the operator bubble, left-aligned under agent prose), and a turn whose `ts` is null/unparseable shows no stamp, never an empty line — so only delivered operator and agent-reply turns are stamped, while tool runs, the collapsed "Thinking" block, and the agent-error banner stay time-free; a maximal consecutive run of `tool-call`/`tool-result` turns renders as one collapsed grey one-liner ("Used N tools ›") whose expansion shows every call and result payload — a lone call still gets the one-liner, and prose or a directive row ends a run. The WhatsApp/operator reader (`/whatsapp`, `OperatorConversations`) omits the prop and keeps the default `renderTimeline`, so its bubble/DM chrome is unchanged — except that since the attachment-render extraction the default renderer draws inbound `operator-inbound` uploads and `agent-file` deliveries inline (image thumbnail / pdf.js preview / audio player / download chip) via the attachment renderer shared with `/chat`, extracted to `app/chat/attachment-render.tsx` to break the cycle with `transcript-render.tsx`; `renderChatTimeline` is untouched. Both presentations are test-pinned (`app/whatsapp/__tests__/Transcript-*.test.tsx`, `app/chat/__tests__/transcript-render.test.tsx`, `app/chat/__tests__/pdf-preview.test.tsx`). **Day-divider:** both renderers insert a centered `.day-divider` row between two consecutive timeline items on different local calendar days (label `Today`/`Yesterday`, else `Sat 14 Jun 2026`), so a thread spanning midnight is never an ambiguous run of HH:MM; the first dated item gets a leading divider, a null/unparseable `ts` marks no boundary, dividers are computed over the filtered `visibleItems`, and in `/chat` a day crossover flushes any open tool/think run first so a collapsed run never spans it. Per-bubble HH:MM stamps are unchanged. Shared helpers `dayKey`/`dayLabel`/`itemTs`/`DayDivider` live in `app/whatsapp/Transcript.tsx`.
|
|
77
77
|
|
|
78
|
+
**WhatsApp reader is read/write (WhatsApp-Web surface).** A WhatsApp store conversation in the operator Conversations reader (`OperatorConversations`) and the admin root channel viewer (`app/page.tsx`) no longer opens the plain read-only DM chrome — it opens `app/whatsapp/WhatsappWebConversation.tsx`, a WhatsApp-Web-styled surface: a conversation header, the delivered-only store transcript reskinned green/white under a `.wa-web` root class, and a reply composer (`app/whatsapp/ReplyComposer.tsx`). The operator can type text and attach files (the webchat allowlist: `SUPPORTED_MIME_SET` / 50 MB / 5 files) and send them into that WhatsApp conversation. **Send is reply-only and DM-only:** `POST /api/whatsapp-reader/reply` (`requireAdminSession`) refuses any target with no existing stored conversation (`reason=no-existing-conversation`, HTTP 403) — a cold first-contact send bans the account, so the composer is never a cold-contact path, enforced server-side — and refuses `@g.us` groups (`reason=group-send-blocked`), matching the agent's observe-only group invariant; a group thread shows a read-only note in place of the composer. The endpoint is the sole store writer for a manual send: right after each send resolves it appends the record itself, stamped `origin:'operator-manual'` (attributed "You", distinct from an assistant reply), because the Baileys echo that normally persists the store is gated on message text (`manager.ts:906`) and would leave an uncaptioned media send delivered-but-invisible. The record's `messageId` matches the echo's derivation so the async text echo's own persist dedups to a no-op; the send is confirmed by re-read (`op=recorded present=<bool>`). A sent send does not spawn an assistant turn (echo dispatch stays suppressed). Attachments deliver as WhatsApp media/documents and appear in the reader as an attributed text line (`[sent <file>]`) — inline media rendering in the store reader is a follow-up. The `.wa-web` skin is scoped to WhatsApp store threads only, so `/chat`, the admin agent session view, and the public visitor webchat are unchanged; the visitor webchat gains no send capability. The header call/video/search icons and the in-bubble delivered-tick are cosmetic (no presence or read-receipt data is stored); inbound bubbles keep their sender name so group threads stay attributable. Non-WhatsApp reader rows (Telegram/webchat session JSONLs) keep the plain read-only `Transcript`. Observability rides `[wa-manual-send]` lines correlated by a per-request `sendId`.
|
|
79
|
+
|
|
78
80
|
**`/chat` live activity line.** While a turn is in flight the transcript tail shows one ephemeral `ChatActivity` line (mounted only while `busy`, admin/operator only). It tracks real activity, not a timer: while a `Task` subagent runs it shows that subagent's headline (`agentType · description`, prefixed `N agents ·` when ≥2 are concurrent), sourced from `agent-<hex>.meta.json` via named `activity` SSE events the admin reader pushes from the session's `subagents/` dir; with no subagent active it shows a neutral word that advances only on a real turn arrival. The line carries a turn-elapsed clock and flips to a `stalled` state once nothing has been written for 5 minutes (`now − lastEmitAt`), so the operator can tell a wedge from progress without SSH. It is never added to the persisted timeline. Detail and the `[webchat-activity]` observability live in [`admin-webchat-native-channel.md`](../../../.docs/admin-webchat-native-channel.md).
|
|
79
81
|
|
|
80
82
|
**maxy title for public sessions.** A `role=public` webchat spawn never produces a useful Claude Code `ai-title` (an anonymous one-line visitor turn), so every public row would otherwise read identically. The webchat route (`chat.ts`) composes a deterministic title — `Web · <senderId[:8]>[ · <personId>] · <UTC YYYY-MM-DD HH:mm>` (personId present only for gated visitors) — and threads it through the native webchat gateway's public spawn (`handleInbound` → `buildPublicWebchatSpawnRequest` → `managerSpawn`) to the manager `POST /public-spawn` body as `name`. `/spawn` validates it with `validateUserTitle` and, for `role=public` only, writes it into `UserTitleStore` so it occupies the operator-rename tier and wins over `ai-title`. Admin (`/rc-spawn`) and WhatsApp titling are unchanged. Observability: every public spawn logs `[spawn] role=public … title="…"` (or `title=missing`); the manager's row builder emits `[public-title] sessionId=… unexpected titleSource=<ai|null>` on the next list read for any public row that did not resolve from the user tier.
|
|
@@ -95,7 +95,7 @@ If Ollama is unavailable at write time, the node is stored without an embedding
|
|
|
95
95
|
|
|
96
96
|
The `memory-reindex` tool backfills missing embeddings by iterating nodes where `embedding IS NULL`. It uses the bounded representation (the `summary` for document/archive labels, never the raw body), embeds in batches with a per-node fallback on batch error, and **skips and continues** past a failing node — keeping skipped nodes out of the re-fetch via an exclude set — instead of aborting the whole run. `embed()`/`embedBatch()` cap oversized input (`EMBED_INPUT_MAX_CHARS`) before the Ollama POST, so a large body embeds truncated rather than throwing. Per-node `[reindex] op=embedded|skip-error` lines and a terminal `[reindex] op=done processed=N skipped=M`.
|
|
97
97
|
|
|
98
|
-
`embedBatch()` also paces large batches. A document's summary plus every section body in one `/api/embed` POST pins ollama's `llama-server` across all cores for the whole batch with no idle gaps; on a passively-cooled Pi the SoC climbs past its soft-temp limit and the board thermally hard-resets. `embedBatch` splits an input array longer than
|
|
98
|
+
`embedBatch()` also paces large batches. A document's summary plus every section body in one `/api/embed` POST pins ollama's `llama-server` across all cores for the whole batch with no idle gaps; on a passively-cooled Pi the SoC climbs past its soft-temp limit and the board thermally hard-resets. `embedBatch` splits an input array longer than the effective sub-batch size into sub-batches, waiting `EMBED_SUBBATCH_COOLDOWN_MS` (default 1000) between them so the SoC gets cooling gaps; vectors are concatenated in input order. The effective sub-batch size is the smaller of two ceilings: the thermal count ceiling `EMBED_SUBBATCH_SIZE` (default 32) and a throughput ceiling `floor(EMBED_REQUEST_TIMEOUT_MS * 0.8 / EMBED_MS_PER_INPUT)`. The throughput ceiling exists because on a CPU-only embedder a fixed 32-input POST can exceed `EMBED_REQUEST_TIMEOUT_MS` and abort the atomic ingest write, so `EMBED_MS_PER_INPUT` (the budgeted worst-case wall-time for one capped input, default 6000 ms, env-tunable) bounds each POST to 80 % of the request timeout. Every `/api/embed` POST also carries `keep_alive` (`EMBED_KEEP_ALIVE`, default `-1` = keep the model resident forever) so an interactive graph query-embed never cold-loads and blows its 5 s timeout. All knobs are env-overridable for on-device tuning. The load-bearing thermal protection is the installer's `CPUQuota` cap on `ollama.service` (every embed caller is bounded there regardless of batch shape); this pacing is defence-in-depth. The UI's file-index path uses its own single-input embed client in `platform/ui/app/lib/neo4j-store.ts` (one embed per file, not a batch), so it is covered by the CPU cap, not by `embedBatch` pacing.
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
|
@@ -400,9 +400,9 @@ Standing rules the operator gives over a channel are `Preference` nodes. Two mec
|
|
|
400
400
|
|
|
401
401
|
**Reconcile by meaning on write (`profile-update`).** The existence check is two-tier. First an exact `(category, key)` match — the classic fast path, unchanged. When that misses, a semantic-neighbour lookup runs over the `preference_embedding` vector index, scoped to the same `accountId` and `scope:'admin'`, non-trashed. If the nearest neighbour is at or above `SAME_SUBJECT_COSINE` (0.85), the write lands on that node through the existing reinforce/update/contradict curve instead of minting a duplicate; the matched neighbours are returned in the tool result so the agent can classify future writes against real prior state. The confidence constants are unchanged — only the join key widens, so a rephrasing under a new `key` no longer forks the rule and a correction demotes the prior node rather than adding a contradictory one.
|
|
402
402
|
|
|
403
|
-
**Inject the active rule-set every turn (channel gateways).** The one definition of "this account's active rules" is `@maxy/active-rules`: a bounded, floor-filtered (`confidence >= 0.4`), confidence-ordered candidate query, then semantic de-confliction (one winner per subject at the same 0.85 cosine), capped to `INJECTION_RULE_CAP` (12). `profile-read` exposes this set as `activeRules`, and the three inbound gateways (`wa-gateway`, `telegram-gateway`, `webchat-gateway`) fetch it for the effective session account and attach it as `standingRules` on the inbound frame; the channel builders prepend it as a `## Standing rules` block above `## Context`. The read is by code, not agent discretion, so a rule set last week is applied this week regardless of how many times the session compacted. Telegram and webchat inject for `role:'admin'` only — a public visitor never receives operator rules.
|
|
403
|
+
**Inject the active rule-set every turn (channel gateways).** The one definition of "this account's active rules" is `@maxy/active-rules`: a bounded, floor-filtered (`confidence >= 0.4`), confidence-ordered candidate query, then semantic de-confliction (one winner per subject at the same 0.85 cosine), capped to `INJECTION_RULE_CAP` (12). `profile-read` exposes this set as `activeRules`, and the three inbound gateways (`wa-gateway`, `telegram-gateway`, `webchat-gateway`) fetch it for the effective session account and attach it as `standingRules` on the inbound frame; the channel builders prepend it as a `## Standing rules` block above `## Context`. Both channel-server inbound paths carry the block: the single-target SSE loop parses the whole frame, and the unified multi-target door reader (`runDoorStream`,) reconstructs it through the shared `doorInboundPayload` seam whose `parseFrame` closures read `standingRules` off the frame. The read is by code, not agent discretion, so a rule set last week is applied this week regardless of how many times the session compacted. Telegram and webchat inject for `role:'admin'` only — a public visitor never receives operator rules.
|
|
404
404
|
|
|
405
|
-
**Trust a scheduled turn's provenance, never an inbound's claim (channel-agent grounding).** A cron-dispatched agent turn reaches the same channel builders as a real inbound, so its own authorisation text would otherwise land inside `## Context` — the zone `REFRAME_INSTRUCTION` demotes to untrusted — and a security-cautious agent would distrust its own automation (the self-cancel loop). The dispatcher therefore stamps a `ScheduleProvenance` marker (owning account, event, owner userId, dispatch time) that the channel builders render as a `## Scheduled automation (platform-verified)` preamble **above** `## Context` (and above the rules block); the whatsapp wrap tag names the door `scheduler`. Because the marker is dispatcher-stamped and never derived from payload text, an inbound message cannot forge it — placement above `## Context` alone is not the trust signal, the dispatcher provenance is. The grounding binds to it in two places: one recipient-neutral clause added byte-identical to the three reframe instructions (a marker-bearing turn is authorised standing automation; a reconfiguration or re-enable is not intrusion), and the admin `IDENTITY.md` "Untrusted input" rule that the agent never states a platform-level authenticity or impersonation verdict it was not given (an unsourced "this is not from you" is its own inference, flagged, never asserted as the platform's). The amplifier that let one misread harden was the accreting seat: a recurring event resumed one long-lived session every firing. A subsequent change removes it — each firing runs a fresh per-firing seat (`scheduledSeatIdFor`, salted with the firing's eventId + dispatch time), so distrust cannot accrete across firings, and the self-cancel guard compares the cancelling `SESSION_ID` to the node's dispatcher-stamped `lastDispatchSessionId` rather than a recomputed deterministic seat. See `.docs/scheduling-agent-dispatch.md § Operator-provenance marker` and `§ Session model — fresh per firing`.
|
|
405
|
+
**Trust a scheduled turn's provenance, never an inbound's claim (channel-agent grounding).** A cron-dispatched agent turn reaches the same channel builders as a real inbound, so its own authorisation text would otherwise land inside `## Context` — the zone `REFRAME_INSTRUCTION` demotes to untrusted — and a security-cautious agent would distrust its own automation (the self-cancel loop). The dispatcher therefore stamps a `ScheduleProvenance` marker (owning account, event, owner userId, dispatch time) that the channel builders render as a `## Scheduled automation (platform-verified)` preamble **above** `## Context` (and above the rules block); the whatsapp wrap tag names the door `scheduler`. Both channel-server paths carry the marker — the single-target loop and the unified multi-target door reader (via the same `doorInboundPayload` seam that carries `standingRules`); the scheduler only dispatches to the whatsapp/telegram door, so a webchat frame never bears one. Because the marker is dispatcher-stamped and never derived from payload text, an inbound message cannot forge it — placement above `## Context` alone is not the trust signal, the dispatcher provenance is. The grounding binds to it in two places: one recipient-neutral clause added byte-identical to the three reframe instructions (a marker-bearing turn is authorised standing automation; a reconfiguration or re-enable is not intrusion), and the admin `IDENTITY.md` "Untrusted input" rule that the agent never states a platform-level authenticity or impersonation verdict it was not given (an unsourced "this is not from you" is its own inference, flagged, never asserted as the platform's). The amplifier that let one misread harden was the accreting seat: a recurring event resumed one long-lived session every firing. A subsequent change removes it — each firing runs a fresh per-firing seat (`scheduledSeatIdFor`, salted with the firing's eventId + dispatch time), so distrust cannot accrete across firings, and the self-cancel guard compares the cancelling `SESSION_ID` to the node's dispatcher-stamped `lastDispatchSessionId` rather than a recomputed deterministic seat. See `.docs/scheduling-agent-dispatch.md § Operator-provenance marker` and `§ Session model — fresh per firing`.
|
|
406
406
|
|
|
407
407
|
**Observability.** `[preference-write] op=reconcile … mode=<reinforce|update|contradict|new> similarity=…` — a stream of `mode=new` for subjects that already exist is the duplicate-minting signature. `[preference-inject] op=inject channel=<wa|tg|web> injected=<N>` — `injected=0` on an account with stored rules is the write-only regression re-appearing. `[preference-audit] op=drift accountId=… storedActive=… injectedActive=… duplicateClusters=…` — the standing reconciliation audit (claude-session-manager, 5-minute tick) flags any account whose store holds more active rows than injection would surface, the no-event detector for drift.
|
|
408
408
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Workflows Guide
|
|
2
|
+
|
|
3
|
+
## What a Workflow Is
|
|
4
|
+
|
|
5
|
+
A workflow is a saved, named sequence of steps that {{productName}} runs for you on demand. Each step calls one tool, and steps can pass their results to later steps. Use a workflow when you have a recurring process with two or more steps that you would otherwise ask for by hand every time. A single one-off action does not need a workflow.
|
|
6
|
+
|
|
7
|
+
Examples of good workflows:
|
|
8
|
+
|
|
9
|
+
- "When a new lead comes in, create a contact, log it, and send me a notification."
|
|
10
|
+
- "Every time I book a viewing, add the calendar event and message the client the details."
|
|
11
|
+
|
|
12
|
+
## Creating a Workflow
|
|
13
|
+
|
|
14
|
+
Describe the process to {{productName}} naturally:
|
|
15
|
+
|
|
16
|
+
- "Set up a workflow: when I get a new lead, create the contact and send a Telegram notification."
|
|
17
|
+
- "Make a follow-up workflow that adds a calendar reminder and drafts an email."
|
|
18
|
+
|
|
19
|
+
{{productName}} will confirm the name, the steps, and how data flows between them before saving. If a step needs a tool from a plugin you have not installed yet, the workflow is saved as a draft and activates automatically once that plugin is in place.
|
|
20
|
+
|
|
21
|
+
## Declared Inputs
|
|
22
|
+
|
|
23
|
+
Most workflows need a few values that are specific to each run, for example a customer name or a chosen option. A workflow can declare these up front as its inputs. Declaring them means {{productName}} asks you the same questions every time it runs the workflow, so nothing is forgotten and nothing is guessed.
|
|
24
|
+
|
|
25
|
+
Each declared input has a question to ask you, a type, whether it is required, and an optional default. When a value has a default, {{productName}} offers it and you can accept or change it.
|
|
26
|
+
|
|
27
|
+
You do not manage inputs by hand. When you describe a workflow that clearly needs a per-run value, {{productName}} proposes the input and confirms it with you. At run time it reads the list and asks you each question before starting.
|
|
28
|
+
|
|
29
|
+
## Running a Workflow
|
|
30
|
+
|
|
31
|
+
Ask {{productName}} to run it:
|
|
32
|
+
|
|
33
|
+
- "Run the new-lead workflow."
|
|
34
|
+
- "Start the viewing follow-up for the Cardinal Roofing booking."
|
|
35
|
+
|
|
36
|
+
Before it starts, {{productName}} gathers every required input by asking you. If you leave a required value out, the workflow does not start and no steps run. {{productName}} tells you which value is missing and asks for it, then runs the workflow with the complete set. This is deliberate: the workflow refuses to run half-finished rather than failing partway through.
|
|
37
|
+
|
|
38
|
+
## Seeing What Ran
|
|
39
|
+
|
|
40
|
+
Ask for the history:
|
|
41
|
+
|
|
42
|
+
- "Show me recent workflow runs."
|
|
43
|
+
- "Did the new-lead workflow run today?"
|
|
44
|
+
|
|
45
|
+
You get each run's status, timing, and how many steps completed, were skipped, or failed. If a step failed, {{productName}} can show you which one and why.
|
|
46
|
+
|
|
47
|
+
## Managing Workflows
|
|
48
|
+
|
|
49
|
+
Tell {{productName}} naturally:
|
|
50
|
+
|
|
51
|
+
- "List my workflows."
|
|
52
|
+
- "Show me the follow-up workflow."
|
|
53
|
+
- "Pause the new-lead workflow." or "Turn the new-lead workflow back on."
|
|
54
|
+
- "Change the follow-up workflow so it also messages me."
|
|
55
|
+
- "Delete the old onboarding workflow."
|
|
56
|
+
|
|
57
|
+
Pausing keeps a workflow but stops it running. Editing replaces the steps or the inputs with the new version you describe. Deleting removes the workflow and its run history, so {{productName}} confirms with you first.
|
|
58
|
+
|
|
59
|
+
## Scheduling a Workflow
|
|
60
|
+
|
|
61
|
+
A workflow can run on a schedule instead of on demand. Tell {{productName}} when you want it to run, for example "run the daily summary workflow every morning at eight," and it sets up the schedule. Scheduled runs happen with no one present, so a workflow that needs you to supply inputs is best run on demand rather than scheduled.
|
package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embed-throughput.test.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed-throughput.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-throughput.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
// Record the size of every /api/embed POST's input array, and return one
|
|
3
|
+
// zero-vector per input so the index-aligned contract can be checked.
|
|
4
|
+
function stubFetchRecordingBatchSizes(sizes) {
|
|
5
|
+
vi.stubGlobal("fetch", vi.fn(async (_url, init) => {
|
|
6
|
+
const body = JSON.parse(init.body);
|
|
7
|
+
const inputs = Array.isArray(body.input) ? body.input : [body.input];
|
|
8
|
+
sizes.push(inputs.length);
|
|
9
|
+
return {
|
|
10
|
+
ok: true,
|
|
11
|
+
json: async () => ({ embeddings: inputs.map(() => [0]) }),
|
|
12
|
+
};
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
describe("throughput-aware embed sub-batch sizing", () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
vi.resetModules();
|
|
19
|
+
process.env.EMBED_REQUEST_TIMEOUT_MS = "120000";
|
|
20
|
+
process.env.EMBED_SUBBATCH_SIZE = "32";
|
|
21
|
+
process.env.EMBED_SUBBATCH_COOLDOWN_MS = "0"; // no real sleeps in test
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
delete process.env.EMBED_REQUEST_TIMEOUT_MS;
|
|
25
|
+
delete process.env.EMBED_SUBBATCH_SIZE;
|
|
26
|
+
delete process.env.EMBED_SUBBATCH_COOLDOWN_MS;
|
|
27
|
+
delete process.env.EMBED_MS_PER_INPUT;
|
|
28
|
+
});
|
|
29
|
+
it("caps each POST at min(count, duration) and keeps vectors index-aligned", async () => {
|
|
30
|
+
process.env.EMBED_MS_PER_INPUT = "6000"; // durationCap = floor(120000*0.8/6000) = 16
|
|
31
|
+
const sizes = [];
|
|
32
|
+
stubFetchRecordingBatchSizes(sizes);
|
|
33
|
+
const { embedBatch } = await import("../../lib/embeddings.js");
|
|
34
|
+
const texts = Array.from({ length: 35 }, (_, i) => `section ${i}`);
|
|
35
|
+
const out = await embedBatch(texts);
|
|
36
|
+
expect(out).toHaveLength(35);
|
|
37
|
+
expect(sizes.every((n) => n <= 16)).toBe(true); // duration cap wins over 32
|
|
38
|
+
expect(sizes.reduce((a, b) => a + b, 0)).toBe(35); // every input embedded once
|
|
39
|
+
});
|
|
40
|
+
it("lets the count cap win when per-input duration is small", async () => {
|
|
41
|
+
process.env.EMBED_MS_PER_INPUT = "1000"; // durationCap = floor(120000*0.8/1000) = 96 -> count cap 32 wins
|
|
42
|
+
const sizes = [];
|
|
43
|
+
stubFetchRecordingBatchSizes(sizes);
|
|
44
|
+
const { embedBatch } = await import("../../lib/embeddings.js");
|
|
45
|
+
await embedBatch(Array.from({ length: 40 }, (_, i) => `s${i}`));
|
|
46
|
+
expect(Math.max(...sizes)).toBe(32);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe("embed keep_alive + per-POST breadcrumb", () => {
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
vi.restoreAllMocks();
|
|
52
|
+
vi.resetModules();
|
|
53
|
+
process.env.EMBED_SUBBATCH_COOLDOWN_MS = "0";
|
|
54
|
+
});
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
delete process.env.EMBED_KEEP_ALIVE;
|
|
57
|
+
delete process.env.EMBED_SUBBATCH_COOLDOWN_MS;
|
|
58
|
+
});
|
|
59
|
+
it("sends keep_alive=-1 by default in the POST body", async () => {
|
|
60
|
+
let seenBody = {};
|
|
61
|
+
vi.stubGlobal("fetch", vi.fn(async (_u, init) => {
|
|
62
|
+
seenBody = JSON.parse(init.body);
|
|
63
|
+
return { ok: true, json: async () => ({ embeddings: [[0]] }) };
|
|
64
|
+
}));
|
|
65
|
+
const { embed } = await import("../../lib/embeddings.js");
|
|
66
|
+
await embed("hello");
|
|
67
|
+
expect(seenBody.keep_alive).toBe(-1);
|
|
68
|
+
});
|
|
69
|
+
it("treats an empty-string EMBED_KEEP_ALIVE env as unset (defaults to -1)", async () => {
|
|
70
|
+
process.env.EMBED_KEEP_ALIVE = "";
|
|
71
|
+
let seenBody = {};
|
|
72
|
+
vi.stubGlobal("fetch", vi.fn(async (_u, init) => {
|
|
73
|
+
seenBody = JSON.parse(init.body);
|
|
74
|
+
return { ok: true, json: async () => ({ embeddings: [[0]] }) };
|
|
75
|
+
}));
|
|
76
|
+
const { embed } = await import("../../lib/embeddings.js");
|
|
77
|
+
await embed("hello");
|
|
78
|
+
expect(seenBody.keep_alive).toBe(-1);
|
|
79
|
+
});
|
|
80
|
+
it("writes a per-POST breadcrumb on success", async () => {
|
|
81
|
+
vi.stubGlobal("fetch", vi.fn(async () => ({ ok: true, json: async () => ({ embeddings: [[0]] }) })));
|
|
82
|
+
const writes = [];
|
|
83
|
+
vi.spyOn(process.stderr, "write").mockImplementation((s) => {
|
|
84
|
+
writes.push(String(s));
|
|
85
|
+
return true;
|
|
86
|
+
});
|
|
87
|
+
const { embed } = await import("../../lib/embeddings.js");
|
|
88
|
+
await embed("hello");
|
|
89
|
+
expect(writes.some((w) => /\[embed\] op=post inputs=1 /.test(w))).toBe(true);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=embed-throughput.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed-throughput.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-throughput.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed-timeout.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-timeout.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
describe("embed request timeout + enriched errors", () => {
|
|
3
|
+
beforeEach(() => {
|
|
4
|
+
vi.restoreAllMocks();
|
|
5
|
+
process.env.EMBED_REQUEST_TIMEOUT_MS = "50";
|
|
6
|
+
// These tests assert enriched errors for a whole POST (inputs=2), not
|
|
7
|
+
// sub-batch sizing. Throughput-aware sizing (Task 1533) derives the POST
|
|
8
|
+
// size from the timeout, and a 50 ms timeout would otherwise floor the
|
|
9
|
+
// batch to one input per POST. Pin a 1 ms per-input estimate so the
|
|
10
|
+
// 2-input batch stays a single POST and the error still names inputs=2.
|
|
11
|
+
process.env.EMBED_MS_PER_INPUT = "1";
|
|
12
|
+
vi.resetModules();
|
|
13
|
+
});
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
delete process.env.EMBED_REQUEST_TIMEOUT_MS;
|
|
16
|
+
delete process.env.EMBED_MS_PER_INPUT;
|
|
17
|
+
});
|
|
18
|
+
it("rejects promptly with an enriched timeout error, not a bare fetch failed", async () => {
|
|
19
|
+
// Honour the abort signal: never resolve, reject when the timeout fires.
|
|
20
|
+
vi.stubGlobal("fetch", vi.fn((_u, init) => new Promise((_res, rej) => {
|
|
21
|
+
init.signal.addEventListener("abort", () => rej(init.signal.reason ?? new Error("aborted")));
|
|
22
|
+
})));
|
|
23
|
+
const { embed } = await import("../../lib/embeddings.js");
|
|
24
|
+
const start = Date.now();
|
|
25
|
+
await expect(embed("hello")).rejects.toThrow(/timed out/i);
|
|
26
|
+
// Nowhere near undici's 300000ms default.
|
|
27
|
+
expect(Date.now() - start).toBeLessThan(5000);
|
|
28
|
+
});
|
|
29
|
+
it("names input count and largest input size in the timeout error", async () => {
|
|
30
|
+
vi.stubGlobal("fetch", vi.fn((_u, init) => new Promise((_res, rej) => {
|
|
31
|
+
init.signal.addEventListener("abort", () => rej(init.signal.reason ?? new Error("aborted")));
|
|
32
|
+
})));
|
|
33
|
+
const { embedBatch } = await import("../../lib/embeddings.js");
|
|
34
|
+
await expect(embedBatch(["a", "bbbb"])).rejects.toThrow(/timed out.*inputs=2.*largestInputChars=4/s);
|
|
35
|
+
});
|
|
36
|
+
it("names the underlying cause on a connection failure, not a bare fetch failed", async () => {
|
|
37
|
+
// Mirrors undici on a refused connection: TypeError("fetch failed", { cause }).
|
|
38
|
+
vi.stubGlobal("fetch", vi.fn(async () => {
|
|
39
|
+
throw new TypeError("fetch failed", {
|
|
40
|
+
cause: new Error("connect ECONNREFUSED 127.0.0.1:11434"),
|
|
41
|
+
});
|
|
42
|
+
}));
|
|
43
|
+
const { embed } = await import("../../lib/embeddings.js");
|
|
44
|
+
await expect(embed("hello")).rejects.toThrow(/failed.*inputs=1.*largestInputChars=5.*ECONNREFUSED/s);
|
|
45
|
+
});
|
|
46
|
+
it("enriches an HTTP error with status, input count and largest input size", async () => {
|
|
47
|
+
vi.stubGlobal("fetch", vi.fn(async () => ({
|
|
48
|
+
ok: false,
|
|
49
|
+
status: 400,
|
|
50
|
+
text: async () => '{"error":"the input length exceeds the context length"}',
|
|
51
|
+
})));
|
|
52
|
+
const { embedBatch } = await import("../../lib/embeddings.js");
|
|
53
|
+
await expect(embedBatch(["a", "bbbb"])).rejects.toThrow(/400.*inputs=2.*largestInputChars=4/s);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=embed-timeout.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed-timeout.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embed-timeout.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,4 +31,60 @@ describe("embed input capping", () => {
|
|
|
31
31
|
expect(sent[1].length).toBe(EMBED_INPUT_MAX_CHARS);
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
+
describe("token-safe cap default", () => {
|
|
35
|
+
beforeEach(() => vi.restoreAllMocks());
|
|
36
|
+
it("defaults to 6000 chars, provably under a 2048-token context at 3 chars/token", async () => {
|
|
37
|
+
const { EMBED_INPUT_MAX_CHARS } = await import("../../lib/embeddings.js");
|
|
38
|
+
expect(EMBED_INPUT_MAX_CHARS).toBe(6000);
|
|
39
|
+
// 6000 chars / 3 chars-per-token = 2000 tokens <= 2048 context
|
|
40
|
+
expect(EMBED_INPUT_MAX_CHARS / 3).toBeLessThanOrEqual(2048);
|
|
41
|
+
});
|
|
42
|
+
it("caps a dense 24k-char emoji/markup body to <= 6000 chars before POST", async () => {
|
|
43
|
+
const dense = "🟢🟡🔴 ## Observatory\n".repeat(1400); // ~24k chars
|
|
44
|
+
let sent = "";
|
|
45
|
+
vi.stubGlobal("fetch", vi.fn(async (_u, init) => {
|
|
46
|
+
sent = JSON.parse(init.body).input;
|
|
47
|
+
return {
|
|
48
|
+
ok: true,
|
|
49
|
+
json: async () => ({ embeddings: [[0.1]] }),
|
|
50
|
+
};
|
|
51
|
+
}));
|
|
52
|
+
const { embed, EMBED_INPUT_MAX_CHARS } = await import("../../lib/embeddings.js");
|
|
53
|
+
await embed(dense);
|
|
54
|
+
expect(sent.length).toBeLessThanOrEqual(6000);
|
|
55
|
+
expect(sent.length).toBe(EMBED_INPUT_MAX_CHARS);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe("multi-section document batch (exitchatcontrol regression)", () => {
|
|
59
|
+
beforeEach(() => vi.restoreAllMocks());
|
|
60
|
+
it("embeds a mix of short and dense oversized sections with no 400 and no timeout", async () => {
|
|
61
|
+
// Resembles ingesting a document: a summary plus several sections, one of
|
|
62
|
+
// them the dense emoji/markup 'observatory' chapter that used to 400.
|
|
63
|
+
const sections = [
|
|
64
|
+
"Exit Chat Control summary.",
|
|
65
|
+
"🟢🟡🔴 ## Observatory\n".repeat(1400), // ~30k dense chars
|
|
66
|
+
"A normal-length prose section about the campaign.",
|
|
67
|
+
"🔴🔴🔴 status matrix ".repeat(600),
|
|
68
|
+
"Closing section.",
|
|
69
|
+
];
|
|
70
|
+
const sentInputs = [];
|
|
71
|
+
vi.stubGlobal("fetch", vi.fn(async (_u, init) => {
|
|
72
|
+
const inp = JSON.parse(init.body).input;
|
|
73
|
+
sentInputs.push(inp);
|
|
74
|
+
return {
|
|
75
|
+
ok: true,
|
|
76
|
+
json: async () => ({ embeddings: inp.map(() => [0.1]) }),
|
|
77
|
+
};
|
|
78
|
+
}));
|
|
79
|
+
const { embedBatch } = await import("../../lib/embeddings.js");
|
|
80
|
+
const vectors = await embedBatch(sections);
|
|
81
|
+
// One vector per section, index-aligned.
|
|
82
|
+
expect(vectors).toHaveLength(sections.length);
|
|
83
|
+
// Every input actually POSTed was within the token-safe cap.
|
|
84
|
+
for (const batch of sentInputs) {
|
|
85
|
+
for (const s of batch)
|
|
86
|
+
expect(s.length).toBeLessThanOrEqual(6000);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
});
|
|
34
90
|
//# sourceMappingURL=embeddings-cap.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embeddings-cap.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embeddings-cap.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC;IAEvC,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QACjG,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,SAAkB,CAAC;QACvB,EAAE,CAAC,UAAU,CACX,OAAO,EACP,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,IAAsB,EAAE,EAAE;YACnD,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;YACxC,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;aAC1B,CAAC;QAC3B,CAAC,CAAC,CACH,CAAC;QACF,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACjF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAChC,MAAM,CAAE,SAAoB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,IAAI,IAAI,GAAa,EAAE,CAAC;QACxB,EAAE,CAAC,UAAU,CACX,OAAO,EACP,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAU,EAAE,IAAsB,EAAE,EAAE;YACjD,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;YACnC,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;aACnC,CAAC;QAC3B,CAAC,CAAC,CACH,CAAC;QACF,MAAM,EAAE,UAAU,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACtF,MAAM,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"embeddings-cap.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/embeddings-cap.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
* admin reading a specific account); otherwise the calling session's own account
|
|
3
3
|
* (`ACCOUNT_ID`, stamped per-spawn by pty-spawner — the sub-account for a sub-account
|
|
4
4
|
* session); otherwise the legacy `"default"`. An empty env value is treated as
|
|
5
|
-
* absent so a boot-tolerant empty ACCOUNT_ID never scopes reads to "".
|
|
5
|
+
* absent so a boot-tolerant empty ACCOUNT_ID never scopes reads to "".
|
|
6
|
+
*
|
|
7
|
+
* `"default"` is a sentinel, not a store key: the in-memory message store is keyed
|
|
8
|
+
* by platform UUID (Task 1532), so the platform read routes resolve `"default"` (the
|
|
9
|
+
* legacy waname / connection map key) to the socket-owning account's UUID before
|
|
10
|
+
* hitting the store (`resolveReadStoreKey`, Task 1535). This resolver has no access
|
|
11
|
+
* to the connection map — the UUID lives in the platform server, not the MCP env —
|
|
12
|
+
* so the sentinel is produced here and resolved there. */
|
|
6
13
|
export declare function resolveReadAccountId(explicit: string | undefined, envAccountId: string | undefined): string;
|
|
7
14
|
//# sourceMappingURL=resolve-read-account.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-read-account.d.ts","sourceRoot":"","sources":["../src/resolve-read-account.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"resolve-read-account.d.ts","sourceRoot":"","sources":["../src/resolve-read-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;2DAW2D;AAC3D,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,CAIR"}
|
|
@@ -2,7 +2,14 @@
|
|
|
2
2
|
* admin reading a specific account); otherwise the calling session's own account
|
|
3
3
|
* (`ACCOUNT_ID`, stamped per-spawn by pty-spawner — the sub-account for a sub-account
|
|
4
4
|
* session); otherwise the legacy `"default"`. An empty env value is treated as
|
|
5
|
-
* absent so a boot-tolerant empty ACCOUNT_ID never scopes reads to "".
|
|
5
|
+
* absent so a boot-tolerant empty ACCOUNT_ID never scopes reads to "".
|
|
6
|
+
*
|
|
7
|
+
* `"default"` is a sentinel, not a store key: the in-memory message store is keyed
|
|
8
|
+
* by platform UUID (Task 1532), so the platform read routes resolve `"default"` (the
|
|
9
|
+
* legacy waname / connection map key) to the socket-owning account's UUID before
|
|
10
|
+
* hitting the store (`resolveReadStoreKey`, Task 1535). This resolver has no access
|
|
11
|
+
* to the connection map — the UUID lives in the platform server, not the MCP env —
|
|
12
|
+
* so the sentinel is produced here and resolved there. */
|
|
6
13
|
export function resolveReadAccountId(explicit, envAccountId) {
|
|
7
14
|
if (explicit)
|
|
8
15
|
return explicit;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-read-account.js","sourceRoot":"","sources":["../src/resolve-read-account.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"resolve-read-account.js","sourceRoot":"","sources":["../src/resolve-read-account.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;2DAW2D;AAC3D,MAAM,UAAU,oBAAoB,CAClC,QAA4B,EAC5B,YAAgC;IAEhC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IACjE,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Non-fatal embedding: returns empty array if
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Non-fatal embedding: returns an empty array if the shared embed client fails
|
|
3
|
+
* (Ollama unavailable, slow or wedged past the request timeout, or a dense body
|
|
4
|
+
* that still errors after the token-safe cap). Task operations succeed without
|
|
5
|
+
* an embedding — memory-search just will not find the node by similarity until
|
|
6
|
+
* the next update re-embeds. Delegates the POST to platform/lib/embed-client so
|
|
7
|
+
* the token-safe cap, the explicit request timeout, and the cause-naming error
|
|
8
|
+
* are inherited (Task 1530). The failure the shared client would throw is caught
|
|
9
|
+
* here and downgraded to `[]`, but first written as a greppable breadcrumb so a
|
|
10
|
+
* swallowed embed is diagnosable rather than silent.
|
|
5
11
|
*/
|
|
6
12
|
export declare function computeEmbedding(text: string): Promise<number[]>;
|
|
7
13
|
//# sourceMappingURL=embeddings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../../src/lib/embeddings.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"embeddings.d.ts","sourceRoot":"","sources":["../../src/lib/embeddings.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAetE"}
|
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
const EMBED_MODEL = process.env.EMBED_MODEL ?? "nomic-embed-text";
|
|
1
|
+
import { embed } from "../../../../../lib/embed-client/dist/index.js";
|
|
3
2
|
/**
|
|
4
|
-
* Non-fatal embedding: returns empty array if
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Non-fatal embedding: returns an empty array if the shared embed client fails
|
|
4
|
+
* (Ollama unavailable, slow or wedged past the request timeout, or a dense body
|
|
5
|
+
* that still errors after the token-safe cap). Task operations succeed without
|
|
6
|
+
* an embedding — memory-search just will not find the node by similarity until
|
|
7
|
+
* the next update re-embeds. Delegates the POST to platform/lib/embed-client so
|
|
8
|
+
* the token-safe cap, the explicit request timeout, and the cause-naming error
|
|
9
|
+
* are inherited (Task 1530). The failure the shared client would throw is caught
|
|
10
|
+
* here and downgraded to `[]`, but first written as a greppable breadcrumb so a
|
|
11
|
+
* swallowed embed is diagnosable rather than silent.
|
|
7
12
|
*/
|
|
8
13
|
export async function computeEmbedding(text) {
|
|
9
14
|
try {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return [];
|
|
17
|
-
const data = (await res.json());
|
|
18
|
-
return data.embeddings[0] ?? [];
|
|
15
|
+
// Coerce to [] so the returns-[] contract holds even on the shared client's
|
|
16
|
+
// one non-throwing empty-result path: an empty input string makes ollama
|
|
17
|
+
// answer HTTP 200 with `embeddings: []`, so embed() resolves undefined
|
|
18
|
+
// rather than rejecting. The old local client guarded this with the same
|
|
19
|
+
// `?? []`; keep it so a caller never reads `.length` on undefined.
|
|
20
|
+
return (await embed(text)) ?? [];
|
|
19
21
|
}
|
|
20
|
-
catch {
|
|
22
|
+
catch (err) {
|
|
23
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
24
|
+
process.stderr.write(`[work-embed] op=failed inputChars=${text.length} reason=${reason}\n`);
|
|
21
25
|
return [];
|
|
22
26
|
}
|
|
23
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../src/lib/embeddings.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../../src/lib/embeddings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,+CAA+C,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY;IACjD,IAAI,CAAC;QACH,4EAA4E;QAC5E,yEAAyE;QACzE,uEAAuE;QACvE,yEAAyE;QACzE,mEAAmE;QACnE,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qCAAqC,IAAI,CAAC,MAAM,WAAW,MAAM,IAAI,CACtE,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -66,6 +66,22 @@ Every step is `type: "tool"`:
|
|
|
66
66
|
- **retryLimit** — max retries when onFailure is `retry` (max 3)
|
|
67
67
|
- **outputKey** — name under which this step's output is stored for use in subsequent step templates
|
|
68
68
|
|
|
69
|
+
### Declared inputs
|
|
70
|
+
|
|
71
|
+
A workflow can declare the inputs it needs before it can run. This is the front half of gather-then-execute: the contract states what the workflow requires, `workflow-manager` gathers those values from the operator, and `workflow-execute` refuses to run any step until every required input is present. Because each variable choice is resolved with the operator at collection time, the run context is flat and concrete and the linear step DAG is all execution needs.
|
|
72
|
+
|
|
73
|
+
Each entry in `inputs` has:
|
|
74
|
+
|
|
75
|
+
- **key** — the context key this input provides, referenced as `{{key}}` in step params
|
|
76
|
+
- **prompt** — the operator-facing question that gathers the value
|
|
77
|
+
- **type** — `string`, `number`, `boolean`, or `object`
|
|
78
|
+
- **required** — when true, execution is refused until the input is present
|
|
79
|
+
- **default** — optional value seeded when the input is absent; a required input with a default is satisfied without asking
|
|
80
|
+
|
|
81
|
+
The contract is a full-replacement field on both `workflow-create` and `workflow-update`, stored like step params. A workflow that declares no inputs runs exactly as before — the gate passes on an empty contract.
|
|
82
|
+
|
|
83
|
+
A scalar input referenced as `{{key}}` resolves to its value (for example `{{customerName}}` becomes `Cardinal Roofing`), not a wrapper object.
|
|
84
|
+
|
|
69
85
|
### Capability validation
|
|
70
86
|
|
|
71
87
|
At creation time, every step's referenced plugin directory and built MCP server are checked. If any capability is missing, the workflow's status is set to `draft` with specific error messages listing which plugins or tools are unavailable. Only `active` workflows can be executed.
|
|
@@ -87,11 +103,14 @@ Active workflows are discoverable via `workflow-list` and via `memory-search` (t
|
|
|
87
103
|
## Execution
|
|
88
104
|
|
|
89
105
|
Use `workflow-execute` to run a workflow. The engine:
|
|
90
|
-
1. Loads the workflow and its
|
|
91
|
-
2.
|
|
92
|
-
3.
|
|
93
|
-
4.
|
|
94
|
-
5.
|
|
106
|
+
1. Loads the workflow, its steps, and its declared input contract
|
|
107
|
+
2. Pre-flight gate: applies any declared defaults, then checks that every required input is present. If any are missing it returns `status: "incomplete"` with the missing keys, runs zero steps, and creates no WorkflowRun node
|
|
108
|
+
3. Resolves step dependencies into execution order (topological sort)
|
|
109
|
+
4. For each step: resolves `{{template.variables}}` from context and prior step outputs, spawns the target plugin's MCP server, and calls the specified tool
|
|
110
|
+
5. Records every step's outcome as a StepResult node
|
|
111
|
+
6. Creates a WorkflowRun node with the overall status
|
|
112
|
+
|
|
113
|
+
The pre-flight gate runs before any WorkflowRun is created, so a refused execution leaves no orphan `running` run behind. A missing required input is caught up front by the contract rather than late, mid-pipeline, as an unresolved-template failure.
|
|
95
114
|
|
|
96
115
|
### Template variables
|
|
97
116
|
|
|
@@ -115,6 +134,7 @@ Each step declares an `onFailure` policy:
|
|
|
115
134
|
| `completed` | Every step succeeded |
|
|
116
135
|
| `partial` | Finished, but one or more steps were skipped |
|
|
117
136
|
| `failed` | A step failed with abort policy, execution stopped |
|
|
137
|
+
| `incomplete` | Refused at the pre-flight gate — a required input was missing, zero steps ran, no WorkflowRun was created |
|
|
118
138
|
|
|
119
139
|
### Step status values
|
|
120
140
|
|
|
@@ -150,11 +170,11 @@ Scheduled workflows are dispatched by `check-due-events`, which the installer ar
|
|
|
150
170
|
|
|
151
171
|
## Tools
|
|
152
172
|
|
|
153
|
-
- `workflow-create` — Create a workflow with name, description, and
|
|
173
|
+
- `workflow-create` — Create a workflow with name, description, tool steps, and an optional declared input contract
|
|
154
174
|
- `workflow-list` — List workflows with status and step counts
|
|
155
|
-
- `workflow-get` — Fetch a workflow with full step details
|
|
156
|
-
- `workflow-update` — Update name, description, steps (full replacement), or status
|
|
175
|
+
- `workflow-get` — Fetch a workflow with full step details and its declared inputs
|
|
176
|
+
- `workflow-update` — Update name, description, steps (full replacement), inputs (full replacement), or status
|
|
157
177
|
- `workflow-delete` — Permanently remove a workflow and all history
|
|
158
178
|
- `workflow-validate` — Re-check step capabilities and update status
|
|
159
|
-
- `workflow-execute` — Execute a workflow with optional runtime context
|
|
179
|
+
- `workflow-execute` — Execute a workflow with optional runtime context; refuses with `status: "incomplete"` when a required input is missing
|
|
160
180
|
- `workflow-runs` — Query execution history with optional filters
|