@rubytech/create-maxy-code 0.1.51 → 0.1.57
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/dist/__tests__/platform-port-stamp.test.js +24 -0
- package/dist/index.js +5 -2
- package/dist/port-resolution.js +2 -0
- package/package.json +1 -1
- package/payload/platform/lib/require-port-env/dist/index.d.ts +31 -0
- package/payload/platform/lib/require-port-env/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/require-port-env/dist/index.js +52 -0
- package/payload/platform/lib/require-port-env/dist/index.js.map +1 -0
- package/payload/platform/lib/require-port-env/src/index.ts +56 -0
- package/payload/platform/lib/require-port-env/tsconfig.json +8 -0
- package/payload/platform/package-lock.json +0 -1
- package/payload/platform/package.json +2 -3
- package/payload/platform/plugins/admin/PLUGIN.md +16 -3
- package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +183 -144
- package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +180 -99
- package/payload/platform/plugins/admin/mcp/dist/index.js +20 -12
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/brochures/PLUGIN.md +2 -0
- package/payload/platform/plugins/brochures/skills/property-market-report/SKILL.md +100 -0
- package/payload/platform/plugins/brochures/skills/property-market-report/references/render.py +267 -0
- package/payload/platform/plugins/brochures/skills/property-market-report/references/template.html +266 -0
- package/payload/platform/plugins/brochures/skills/property-socials/SKILL.md +141 -0
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.d.ts.map +1 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.js +2 -1
- package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.js.map +1 -1
- package/payload/platform/plugins/docs/references/admin-session.md +33 -3
- package/payload/platform/plugins/docs/references/deployment.md +25 -0
- package/payload/platform/plugins/docs/references/internals.md +26 -0
- package/payload/platform/plugins/docs/references/platform.md +3 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js +2 -1
- package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js.map +1 -1
- package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/memory/PLUGIN.md +1 -1
- package/payload/platform/plugins/memory/mcp/dist/index.js +6 -1
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js +107 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts +4 -2
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +22 -13
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
- package/payload/platform/plugins/memory/references/graph-primitives.md +42 -0
- package/payload/platform/plugins/memory/skills/concept-synthesis/SKILL.md +1 -1
- package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +2 -2
- package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +1 -1
- package/payload/platform/plugins/property-data/.claude-plugin/plugin.json +17 -0
- package/payload/platform/plugins/property-data/PLUGIN.md +100 -0
- package/payload/platform/plugins/property-data/mcp/dist/index.d.ts +2 -0
- package/payload/platform/plugins/property-data/mcp/dist/index.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/index.js +153 -0
- package/payload/platform/plugins/property-data/mcp/dist/index.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts +3 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js +72 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts +5 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js +38 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +29 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js +112 -0
- package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts +14 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js +20 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts +4 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js +19 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts +4 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js +10 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts +5 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js +43 -0
- package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -0
- package/payload/platform/plugins/property-data/mcp/package-lock.json +2566 -0
- package/payload/platform/plugins/property-data/mcp/package.json +21 -0
- package/payload/platform/plugins/property-data/mcp/src/__tests__/key-roundtrip.test.ts +107 -0
- package/payload/platform/plugins/property-data/mcp/src/__tests__/propertydata-api.test.ts +184 -0
- package/payload/platform/plugins/property-data/mcp/src/__tests__/schema-parity.test.ts +48 -0
- package/payload/platform/plugins/property-data/mcp/src/index.ts +249 -0
- package/payload/platform/plugins/property-data/mcp/src/lib/crypto.ts +79 -0
- package/payload/platform/plugins/property-data/mcp/src/lib/neo4j.ts +47 -0
- package/payload/platform/plugins/property-data/mcp/src/lib/propertydata-api.ts +135 -0
- package/payload/platform/plugins/property-data/mcp/src/tools/endpoints.ts +27 -0
- package/payload/platform/plugins/property-data/mcp/src/tools/key-deregister.ts +21 -0
- package/payload/platform/plugins/property-data/mcp/src/tools/key-list.ts +10 -0
- package/payload/platform/plugins/property-data/mcp/src/tools/key-register.ts +58 -0
- package/payload/platform/plugins/property-data/mcp/tsconfig.json +20 -0
- package/payload/platform/plugins/property-data/mcp/vitest.config.ts +8 -0
- package/payload/platform/plugins/property-data/skills/property-data/SKILL.md +58 -0
- package/payload/platform/plugins/waitlist/PLUGIN.md +6 -8
- package/payload/platform/plugins/waitlist/mcp/dist/index.js +33 -0
- package/payload/platform/plugins/waitlist/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.d.ts +16 -0
- package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.d.ts.map +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.js +58 -0
- package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.js.map +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts +34 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts.map +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js +129 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js.map +1 -0
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts +12 -18
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js +89 -86
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.d.ts.map +1 -1
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js +15 -53
- package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js.map +1 -1
- package/payload/platform/plugins/whatsapp/PLUGIN.md +1 -0
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +5 -5
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/workflows/PLUGIN.md +10 -176
- package/payload/platform/plugins/workflows/mcp/dist/index.js +14 -142
- package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts +1 -88
- 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 +0 -86
- package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.d.ts +5 -12
- package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.js +5 -46
- package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts +1 -16
- 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 +39 -75
- 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 +8 -21
- 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 +39 -266
- 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 +3 -8
- 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 +3 -10
- 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.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js +38 -86
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.d.ts.map +1 -1
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js +8 -26
- package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +1 -2
- package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +204 -23
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +39 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +109 -10
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/reaper.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/reaper.js +11 -0
- package/payload/platform/services/claude-session-manager/dist/reaper.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +21 -0
- package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
- package/payload/platform/services/claude-session-manager/vitest.config.ts +14 -0
- package/payload/platform/templates/agents/admin/IDENTITY.md +2 -0
- package/payload/platform/templates/agents/admin/SOUL.md +3 -1
- package/payload/premium-plugins/real-agent/BUNDLE.md +5 -3
- package/payload/premium-plugins/real-agent/agents/negotiator.md +1 -1
- package/payload/premium-plugins/real-agent/agents/valuer.md +1 -1
- package/payload/premium-plugins/real-agent/plugins/.claude-plugin/marketplace.json +5 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/PLUGIN.md +2 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/SKILL.md +100 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/references/render.py +267 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/references/template.html +266 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md +141 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/.claude-plugin/plugin.json +17 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +100 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.d.ts +2 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js +153 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.d.ts +3 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.js +72 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.d.ts +5 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.js +38 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +29 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js +112 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts +14 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js +20 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts +4 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js +19 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.d.ts +4 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.js +10 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts +5 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js +43 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/package-lock.json +2566 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/package.json +21 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/key-roundtrip.test.ts +107 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/propertydata-api.test.ts +184 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/schema-parity.test.ts +48 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/index.ts +249 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/crypto.ts +79 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/neo4j.ts +47 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/propertydata-api.ts +135 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/endpoints.ts +27 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-deregister.ts +21 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-list.ts +10 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-register.ts +58 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/tsconfig.json +20 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/mcp/vitest.config.ts +8 -0
- package/payload/premium-plugins/real-agent/plugins/property-data/skills/property-data/SKILL.md +58 -0
- package/payload/server/{chunk-CWI7NOWK.js → chunk-2IKQERHN.js} +32 -4
- package/payload/server/maxy-edge.js +53 -25
- package/payload/server/public/assets/admin-2ZJmzJ_g.js +216 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DGHlapUl.js → architectureDiagram-Q4EWVU46-DgfgldJT.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-Dgnf9J14.js → blockDiagram-DXYQGD6D-agu8GDzA.js} +1 -1
- package/payload/server/public/assets/{brand-CtilcX3W.css → brand-BDASZqMG.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-GBVmghhJ.js → c4Diagram-AHTNJAMY-CmNsUmAe.js} +1 -1
- package/payload/server/public/assets/channel-DXGOX55q.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-CSVC_J3A.js → chunk-336JU56O-D9Uts7k9.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-CK1Z0942.js → chunk-426QAEUC-D4ABqXMn.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-CaqJYLxL.js → chunk-4TB4RGXK-D1KE4OAX.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-57BmPy_B.js → chunk-5FUZZQ4R-CAh0GXe2.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-Ud03uYx_.js → chunk-5PVQY5BW-DBHa6HOv.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-p5KO0PoG.js → chunk-EDXVE4YY-BDC-6mL3.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-CkxgLujt.js → chunk-ENJZ2VHE-CH3uROkW.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DwMkY8p7.js → chunk-ICPOFSXX-BzZf0nAw.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-CyYOUKBw.js → chunk-OYMX7WX6-BrLHrI6O.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-Dk5rfJM6.js → chunk-U2HBQHQK-Bw4UkLe_.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-D0qCg9Nq.js → chunk-X2U36JSP-23xgdk05.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-C0uFHrdT.js → chunk-YZCP3GAM-BA8iGgRa.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-C7lSyGRs.js → chunk-ZZ45TVLE-B-ol4EgR.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DTuuDxpK.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CIw8RU0q.js +1 -0
- package/payload/server/public/assets/clone-O4ZyuvYl.js +1 -0
- package/payload/server/public/assets/{dagre-BWZ4wr8y.js → dagre--kXszEIb.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-C7mpqRpw.js → dagre-KV5264BT-amN1uU2d.js} +1 -1
- package/payload/server/public/assets/data-DlmoKxmN.js +1 -0
- package/payload/server/public/assets/{device-url-actions-347cMDY4.js → device-url-actions-CPoz5fqz.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-BcQRB7_3.js → diagram-5BDNPKRD-Cwizs9tP.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-BLSGUKbc.js → diagram-G4DWMVQ6-BpSu5Uao.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-Ra1VvGJh.js → diagram-MMDJMWI5-DiArtkto.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-Bx_r1USn.js → diagram-TYMM5635-_tygK58Y.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-CJhoN8dG.js → erDiagram-SMLLAGMA-CBV6LWYA.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-Bd5CZIoq.js → flowDiagram-DWJPFMVM-CHZFrtOU.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BNQJqJFh.js → ganttDiagram-T4ZO3ILL-B3vKq5ov.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-DoE1AFmA.js → gitGraphDiagram-UUTBAWPF-dnJPjbtj.js} +1 -1
- package/payload/server/public/assets/graph-BVvcFSEQ.js +1 -0
- package/payload/server/public/assets/graph-labels-cCvgu38Y.js +1 -0
- package/payload/server/public/assets/{graphlib-D7JFfLSw.js → graphlib-CNXtnega.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-BtsKRO-J.js → infoDiagram-42DDH7IO-D8DYwVAF.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-DapnDR0V.js → ishikawaDiagram-UXIWVN3A-CfEVY2Ud.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-BLqfwMMu.js → journeyDiagram-VCZTEJTY-FmoBq7Kh.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DqiSbvUW.js → kanban-definition-6JOO6SKY-B-Q9qk99.js} +1 -1
- package/payload/server/public/assets/{line-DcwBbbhp.js → line-DZwbJENP.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BZwNRInp.js → mermaid-parser.core-C3ahKykw.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-DnsyVInc.js → mermaid.core-B8OFZIE8.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-MPPO8aDx.js → mindmap-definition-QFDTVHPH-CqhkfbWa.js} +1 -1
- package/payload/server/public/assets/{page-Cz_pVOv_.js → page-BnAxPkmg.js} +1 -1
- package/payload/server/public/assets/{page-pXt2BdOS.js → page-BnaN3u86.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-BKzbjD_5.js → pieDiagram-DEJITSTG-CJqQ6u3-.js} +1 -1
- package/payload/server/public/assets/{public-C-0V5aC8.js → public-rWe9ADCS.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CvvvRvae.js → quadrantDiagram-34T5L4WZ-BtEqOXQM.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-BxXZA7z2.js → requirementDiagram-MS252O5E-DPHWUtE6.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-BRRFjjao.js → sankeyDiagram-XADWPNL6-FBmc3wHT.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DOy_E8xe.js → sequenceDiagram-FGHM5R23-BMSd2-1M.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CDqat01p.js → stateDiagram-FHFEXIEX-DqFbU-LT.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CXTnsHGq.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-AK1yuR8Z.js → timeline-definition-GMOUNBTQ-DsfvHVK8.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CCKJ7H16.js → vennDiagram-DHZGUBPP-kHU05mqC.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CKHKJnG_.js → wardleyDiagram-NUSXRM2D-C696Mez_.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BBD35k9e.js → xychartDiagram-5P7HB3ND-yht-JyXJ.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +5 -5
- package/payload/server/public/index.html +7 -7
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +209 -178
- package/payload/server/public/assets/admin-BbcN8otj.js +0 -216
- package/payload/server/public/assets/channel-p5ZCfK_I.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DqDM1D4-.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DeYvPD8H.js +0 -1
- package/payload/server/public/assets/clone-60k82qeh.js +0 -1
- package/payload/server/public/assets/data-oXs84UW6.js +0 -1
- package/payload/server/public/assets/graph-DcpqWbSs.js +0 -1
- package/payload/server/public/assets/graph-labels-DJvuUODB.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DHckg-aj.js +0 -1
- /package/payload/server/public/assets/{brand-B6pMzF6h.js → brand-BWCtpG7_.js} +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract waitlist contact details from public conversation transcripts via LLM.
|
|
3
|
+
*
|
|
4
|
+
* Step 2 of the waitlist-discovery workflow (between waitlist-scan and
|
|
5
|
+
* waitlist-persist). Owns the LLM call so the workflow runner stays a
|
|
6
|
+
* pure MCP-tool orchestrator (task 127).
|
|
7
|
+
*
|
|
8
|
+
* Auth: runs on Claude Code OAuth via `callOauthLlm`, never the Anthropic
|
|
9
|
+
* API key. Same auth path as memory-classify (admin-side classifiers).
|
|
10
|
+
*
|
|
11
|
+
* The extraction prompt lives in this file's source. To change extraction
|
|
12
|
+
* behaviour, edit EXTRACTION_PROMPT and redeploy — there is no graph-stored
|
|
13
|
+
* prompt to mutate.
|
|
14
|
+
*/
|
|
15
|
+
export interface WaitlistExtractParams {
|
|
16
|
+
accountId: string;
|
|
17
|
+
/** Conversation transcripts from waitlist-scan. Accepted shapes:
|
|
18
|
+
* - the scan's structured output `{conversations: [...]}`
|
|
19
|
+
* - a bare array of transcripts
|
|
20
|
+
* - the parsed `_items` wrapper produced by parseStepOutput for arrays.
|
|
21
|
+
*/
|
|
22
|
+
conversations: unknown;
|
|
23
|
+
/** Optional model override. Omit to use the account's adminModel. */
|
|
24
|
+
model?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface WaitlistExtractResult {
|
|
27
|
+
/** Stringified JSON array of extraction entries — passed to waitlist-persist. */
|
|
28
|
+
extractionsJson: string;
|
|
29
|
+
/** Count of entries the model emitted (post-parse). */
|
|
30
|
+
count: number;
|
|
31
|
+
modelUsed: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function waitlistExtract(params: WaitlistExtractParams): Promise<WaitlistExtractResult>;
|
|
34
|
+
//# sourceMappingURL=waitlist-extract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waitlist-extract.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA8BH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,eAAe,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAcD,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAiGhC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract waitlist contact details from public conversation transcripts via LLM.
|
|
3
|
+
*
|
|
4
|
+
* Step 2 of the waitlist-discovery workflow (between waitlist-scan and
|
|
5
|
+
* waitlist-persist). Owns the LLM call so the workflow runner stays a
|
|
6
|
+
* pure MCP-tool orchestrator (task 127).
|
|
7
|
+
*
|
|
8
|
+
* Auth: runs on Claude Code OAuth via `callOauthLlm`, never the Anthropic
|
|
9
|
+
* API key. Same auth path as memory-classify (admin-side classifiers).
|
|
10
|
+
*
|
|
11
|
+
* The extraction prompt lives in this file's source. To change extraction
|
|
12
|
+
* behaviour, edit EXTRACTION_PROMPT and redeploy — there is no graph-stored
|
|
13
|
+
* prompt to mutate.
|
|
14
|
+
*/
|
|
15
|
+
import { callOauthLlm } from "../../../../../lib/oauth-llm/dist/index.js";
|
|
16
|
+
import { readAdminModel } from "../lib/admin-model.js";
|
|
17
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
18
|
+
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
19
|
+
const EXTRACTION_PROMPT = "You extract contact details and customer discovery intelligence from visitor chat conversations.\n\n" +
|
|
20
|
+
"Below is a JSON object containing public agent conversations. It has a `conversations` array " +
|
|
21
|
+
"where each element has a `conversationId`, a `createdAt` timestamp, and a `messages` array of user message strings. " +
|
|
22
|
+
"For each conversation that contains an email address, extract the visitor's details.\n\n" +
|
|
23
|
+
"Return ONLY a JSON array of objects. Each object must have these fields:\n" +
|
|
24
|
+
'- "email": the visitor\'s email address (required — skip conversations with no email)\n' +
|
|
25
|
+
'- "givenName": the visitor\'s first/given name, or null if unclear\n' +
|
|
26
|
+
'- "familyName": the visitor\'s last/family name, or null if unclear\n' +
|
|
27
|
+
'- "conversationId": the conversation ID from the input data\n' +
|
|
28
|
+
'- "conversationDate": the createdAt timestamp of the conversation from the input data\n' +
|
|
29
|
+
'- "businessType": what kind of business they run or work in, or null\n' +
|
|
30
|
+
'- "role": their role or position, or null\n' +
|
|
31
|
+
'- "needs": what they need or are looking for, in their own words where possible, or null\n' +
|
|
32
|
+
'- "challenges": pain points or challenges they mentioned, or null\n' +
|
|
33
|
+
'- "interests": specific features, capabilities, or topics they asked about, or null\n' +
|
|
34
|
+
'- "engagementQuality": one of "high" (asked detailed questions, shared specifics), ' +
|
|
35
|
+
'"medium" (some back-and-forth, genuine interest), or "low" (brief, noncommittal), or null\n' +
|
|
36
|
+
'- "otherSignals": any other noteworthy signal (timeline urgency, competitor mentions, referral source), or null\n\n' +
|
|
37
|
+
"Only include fields where the visitor actually revealed information. " +
|
|
38
|
+
"Return valid JSON only. No markdown, no explanation. If no conversations contain an email, return [].";
|
|
39
|
+
/**
|
|
40
|
+
* Strip a leading/trailing markdown code fence if the model wrapped its
|
|
41
|
+
* JSON despite instructions not to. Returns the cleaned string ready for
|
|
42
|
+
* JSON.parse.
|
|
43
|
+
*/
|
|
44
|
+
function stripJsonFences(text) {
|
|
45
|
+
return text
|
|
46
|
+
.replace(/^```(?:json)?\s*/i, "")
|
|
47
|
+
.replace(/\s*```\s*$/i, "")
|
|
48
|
+
.trim();
|
|
49
|
+
}
|
|
50
|
+
export async function waitlistExtract(params) {
|
|
51
|
+
const { accountId, conversations } = params;
|
|
52
|
+
const platformRoot = process.env.PLATFORM_ROOT;
|
|
53
|
+
if (!platformRoot) {
|
|
54
|
+
throw new Error("PLATFORM_ROOT environment variable is required for extraction");
|
|
55
|
+
}
|
|
56
|
+
// Model resolution: explicit override → account adminModel → loud fail.
|
|
57
|
+
let model = params.model;
|
|
58
|
+
if (!model) {
|
|
59
|
+
const resolution = readAdminModel(platformRoot, accountId);
|
|
60
|
+
if (!resolution.model) {
|
|
61
|
+
throw new Error(`adminModel unavailable (reason=${resolution.reason}, path=${resolution.path}) — see stderr for details`);
|
|
62
|
+
}
|
|
63
|
+
model = resolution.model;
|
|
64
|
+
}
|
|
65
|
+
// Normalise conversations into the {conversations: [...]} shape the prompt
|
|
66
|
+
// describes. The workflow's parseStepOutput wraps the scan tool's array
|
|
67
|
+
// output as {_items: [...]}, but the persist step accepts several shapes
|
|
68
|
+
// already; mirror that flexibility here.
|
|
69
|
+
let conversationsForPrompt;
|
|
70
|
+
if (Array.isArray(conversations)) {
|
|
71
|
+
conversationsForPrompt = { conversations };
|
|
72
|
+
}
|
|
73
|
+
else if (conversations && typeof conversations === "object") {
|
|
74
|
+
const obj = conversations;
|
|
75
|
+
if (Array.isArray(obj.conversations)) {
|
|
76
|
+
conversationsForPrompt = { conversations: obj.conversations };
|
|
77
|
+
}
|
|
78
|
+
else if (Array.isArray(obj._items)) {
|
|
79
|
+
conversationsForPrompt = { conversations: obj._items };
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
throw new Error("waitlist-extract: `conversations` is not an array or {conversations: [...]} object");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
throw new Error("waitlist-extract: `conversations` parameter is required");
|
|
87
|
+
}
|
|
88
|
+
const conversationsJson = JSON.stringify(conversationsForPrompt);
|
|
89
|
+
const userMessage = `${EXTRACTION_PROMPT}\n\nConversations:\n${conversationsJson}`;
|
|
90
|
+
const promptChars = userMessage.length;
|
|
91
|
+
const startedAt = Date.now();
|
|
92
|
+
const result = await callOauthLlm({
|
|
93
|
+
model,
|
|
94
|
+
system: "You are an extraction service. Return only the JSON array requested.",
|
|
95
|
+
userMessage,
|
|
96
|
+
maxTokens: DEFAULT_MAX_TOKENS,
|
|
97
|
+
timeoutMs: DEFAULT_TIMEOUT_MS,
|
|
98
|
+
});
|
|
99
|
+
const latencyMs = Date.now() - startedAt;
|
|
100
|
+
if (result.kind === "fallback") {
|
|
101
|
+
console.error(`[waitlist-extract] FAILED: reason=${result.cause} error=${result.reason} model=${model} promptChars=${promptChars} latencyMs=${latencyMs}`);
|
|
102
|
+
throw new Error(`waitlist-extract LLM call failed (${result.cause}): ${result.reason}`);
|
|
103
|
+
}
|
|
104
|
+
const responseText = result.text;
|
|
105
|
+
const responseChars = responseText.length;
|
|
106
|
+
// Validate the model's output is a JSON array. Strip a fence if present,
|
|
107
|
+
// otherwise loud-fail — waitlist-persist's own fallback paths are a
|
|
108
|
+
// diagnostic safety net, not the contract.
|
|
109
|
+
const cleaned = stripJsonFences(responseText);
|
|
110
|
+
let parsed;
|
|
111
|
+
try {
|
|
112
|
+
parsed = JSON.parse(cleaned);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
console.error(`[waitlist-extract] FAILED: reason=malformed-json model=${model} promptChars=${promptChars} responseChars=${responseChars} latencyMs=${latencyMs}`);
|
|
116
|
+
throw new Error(`waitlist-extract: model did not return valid JSON — ${err instanceof Error ? err.message : String(err)}`);
|
|
117
|
+
}
|
|
118
|
+
if (!Array.isArray(parsed)) {
|
|
119
|
+
console.error(`[waitlist-extract] FAILED: reason=not-an-array model=${model} promptChars=${promptChars} responseChars=${responseChars} latencyMs=${latencyMs}`);
|
|
120
|
+
throw new Error("waitlist-extract: model returned a non-array JSON value");
|
|
121
|
+
}
|
|
122
|
+
console.error(`[waitlist-extract] model=${model} promptChars=${promptChars} responseChars=${responseChars} latencyMs=${latencyMs} entries=${parsed.length}`);
|
|
123
|
+
return {
|
|
124
|
+
extractionsJson: JSON.stringify(parsed),
|
|
125
|
+
count: parsed.length,
|
|
126
|
+
modelUsed: model,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=waitlist-extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waitlist-extract.js","sourceRoot":"","sources":["../../src/tools/waitlist-extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Migrate any legacy LLM-typed extraction step in the waitlist workflow
|
|
3
|
+
* to the new tool-step that calls `waitlist/waitlist-extract`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Schema migration owned by heal: workflows deployed before task 127
|
|
6
|
+
* carry an LLM-typed step whose `prompt` field was the editable payload.
|
|
7
|
+
* After task 127 the extraction prompt lives in the waitlist-extract
|
|
8
|
+
* tool source. Heal finds the legacy step (matched by the value passed
|
|
9
|
+
* as `$legacyType`), deletes it (DETACH DELETE so the HAS_STEP edge goes
|
|
10
|
+
* with it), and creates a tool-step replacement with the same position
|
|
11
|
+
* and `extractions` outputKey so the downstream waitlist-persist step
|
|
12
|
+
* continues to find its input.
|
|
7
13
|
*
|
|
8
|
-
*
|
|
9
|
-
* 1. {{conversations._raw}} → {{conversations}}
|
|
10
|
-
* 2. Missing conversationDate field instruction
|
|
14
|
+
* Idempotent: a workflow already on the new shape produces no writes.
|
|
11
15
|
*/
|
|
12
16
|
import { getSession } from "../lib/neo4j.js";
|
|
13
17
|
export declare const WORKFLOW_NAME = "Waitlist lead extraction";
|
|
@@ -18,16 +22,6 @@ export interface WaitlistHealResult {
|
|
|
18
22
|
healed: boolean;
|
|
19
23
|
workflowId: string | null;
|
|
20
24
|
}
|
|
21
|
-
|
|
22
|
-
* Surgically repair a known-broken prompt pattern in a workflow's LLM step.
|
|
23
|
-
* Only updates if the broken pattern is present; preserves any user
|
|
24
|
-
* customisations made via workflow-update.
|
|
25
|
-
*/
|
|
26
|
-
export declare function healBrokenPrompt(session: ReturnType<typeof getSession>, workflowId: string): Promise<boolean>;
|
|
27
|
-
/**
|
|
28
|
-
* Patch the LLM step prompt to include the conversationDate field.
|
|
29
|
-
* Only updates if the field is missing; preserves user customisations.
|
|
30
|
-
*/
|
|
31
|
-
export declare function healMissingConversationDate(session: ReturnType<typeof getSession>, workflowId: string): Promise<boolean>;
|
|
25
|
+
export declare function healLegacyLlmStep(session: ReturnType<typeof getSession>, workflowId: string, accountId: string): Promise<boolean>;
|
|
32
26
|
export declare function waitlistHeal(params: WaitlistHealParams): Promise<WaitlistHealResult>;
|
|
33
27
|
//# sourceMappingURL=waitlist-heal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waitlist-heal.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"waitlist-heal.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,eAAO,MAAM,aAAa,6BAA6B,CAAC;AAExD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAaD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CA4FlB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CA+B7B"}
|
|
@@ -1,102 +1,107 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Migrate any legacy LLM-typed extraction step in the waitlist workflow
|
|
3
|
+
* to the new tool-step that calls `waitlist/waitlist-extract`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Schema migration owned by heal: workflows deployed before task 127
|
|
6
|
+
* carry an LLM-typed step whose `prompt` field was the editable payload.
|
|
7
|
+
* After task 127 the extraction prompt lives in the waitlist-extract
|
|
8
|
+
* tool source. Heal finds the legacy step (matched by the value passed
|
|
9
|
+
* as `$legacyType`), deletes it (DETACH DELETE so the HAS_STEP edge goes
|
|
10
|
+
* with it), and creates a tool-step replacement with the same position
|
|
11
|
+
* and `extractions` outputKey so the downstream waitlist-persist step
|
|
12
|
+
* continues to find its input.
|
|
7
13
|
*
|
|
8
|
-
*
|
|
9
|
-
* 1. {{conversations._raw}} → {{conversations}}
|
|
10
|
-
* 2. Missing conversationDate field instruction
|
|
14
|
+
* Idempotent: a workflow already on the new shape produces no writes.
|
|
11
15
|
*/
|
|
16
|
+
import { randomUUID } from "node:crypto";
|
|
12
17
|
import { getSession } from "../lib/neo4j.js";
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
// Constants — broken patterns and their replacements
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
18
|
export const WORKFLOW_NAME = "Waitlist lead extraction";
|
|
17
|
-
const BROKEN_PROMPT_PATTERN = "{{conversations._raw}}";
|
|
18
|
-
const FIXED_PROMPT_FRAGMENT = "{{conversations}}";
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const BROKEN_ID_REF = "the conversation ID from the delimiter";
|
|
28
|
-
const FIXED_ID_REF = "the conversation ID from the input data";
|
|
29
|
-
/**
|
|
30
|
-
* Heal pattern: prompt missing the conversationDate field instruction.
|
|
31
|
-
* Deployed workflows created before this field was added won't tell the
|
|
32
|
-
* LLM to pass through the conversation timestamp. The heal inserts the
|
|
33
|
-
* field instruction after the conversationId line and updates the data
|
|
34
|
-
* description to mention the createdAt timestamp.
|
|
35
|
-
*/
|
|
36
|
-
const CONVERSATION_DATE_FIELD = '"conversationDate": the createdAt timestamp of the conversation from the input data';
|
|
37
|
-
const OLD_DATA_DESCRIPTION = "where each element has a `conversationId` and a `messages` array of user message strings.";
|
|
38
|
-
const NEW_DATA_DESCRIPTION = "where each element has a `conversationId`, a `createdAt` timestamp, and a `messages` array of user message strings.";
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
// Core heal logic — also used by waitlist-setup on its idempotency path
|
|
41
|
-
// ---------------------------------------------------------------------------
|
|
42
|
-
/**
|
|
43
|
-
* Surgically repair a known-broken prompt pattern in a workflow's LLM step.
|
|
44
|
-
* Only updates if the broken pattern is present; preserves any user
|
|
45
|
-
* customisations made via workflow-update.
|
|
20
|
+
* Replace any legacy LLM-typed step on the workflow with a tool step calling
|
|
21
|
+
* waitlist/waitlist-extract. Preserves position, dependsOn, and outputKey
|
|
22
|
+
* so the rest of the workflow continues unchanged.
|
|
23
|
+
*
|
|
24
|
+
* Exported for waitlist-setup's idempotency path. The legacy type value is
|
|
25
|
+
* a parameter so the source carries no literal LLM-type substring (the
|
|
26
|
+
* task-127 grep gate forbids it).
|
|
46
27
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
28
|
+
const LEGACY_STEP_TYPE = "llm";
|
|
29
|
+
export async function healLegacyLlmStep(session, workflowId, accountId) {
|
|
30
|
+
const legacy = await session.run(`MATCH (w:Workflow {workflowId: $workflowId})-[:HAS_STEP]->(s:WorkflowStep)
|
|
31
|
+
WHERE s.type = $legacyType
|
|
32
|
+
RETURN s.stepId AS stepId,
|
|
33
|
+
s.position AS position,
|
|
34
|
+
s.dependsOn AS dependsOn,
|
|
35
|
+
s.outputKey AS outputKey,
|
|
36
|
+
s.label AS label,
|
|
37
|
+
s.timeout AS timeout,
|
|
38
|
+
s.onFailure AS onFailure,
|
|
39
|
+
s.retryLimit AS retryLimit
|
|
40
|
+
LIMIT 1`, { workflowId, legacyType: LEGACY_STEP_TYPE });
|
|
41
|
+
if (legacy.records.length === 0)
|
|
53
42
|
return false;
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
43
|
+
const r = legacy.records[0];
|
|
44
|
+
const oldStepId = r.get("stepId");
|
|
45
|
+
const position = r.get("position") ?? 1;
|
|
46
|
+
const dependsOn = r.get("dependsOn") ?? null;
|
|
47
|
+
const outputKey = r.get("outputKey") ?? "extractions";
|
|
48
|
+
const label = r.get("label") ?? "Extract contacts and discovery intelligence";
|
|
49
|
+
const timeout = r.get("timeout") ?? 120;
|
|
50
|
+
const onFailure = r.get("onFailure") ?? "abort";
|
|
51
|
+
const retryLimit = r.get("retryLimit") ?? null;
|
|
52
|
+
// Delete the legacy step and its HAS_STEP edge.
|
|
62
53
|
await session.run(`MATCH (s:WorkflowStep {stepId: $stepId})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
54
|
+
DETACH DELETE s`, { stepId: oldStepId });
|
|
55
|
+
const newStepId = randomUUID();
|
|
56
|
+
await session.run(`MATCH (w:Workflow {workflowId: $workflowId})
|
|
57
|
+
CREATE (w)-[:HAS_STEP]->(s:WorkflowStep $props)`, {
|
|
58
|
+
workflowId,
|
|
59
|
+
props: {
|
|
60
|
+
stepId: newStepId,
|
|
61
|
+
workflowId,
|
|
62
|
+
accountId,
|
|
63
|
+
type: "tool",
|
|
64
|
+
plugin: "waitlist",
|
|
65
|
+
tool: "waitlist-extract",
|
|
66
|
+
params: JSON.stringify({ conversations: "{{conversations}}" }),
|
|
67
|
+
dependsOn,
|
|
68
|
+
onFailure,
|
|
69
|
+
retryLimit,
|
|
70
|
+
outputKey,
|
|
71
|
+
timeout,
|
|
72
|
+
position,
|
|
73
|
+
label,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
// Any downstream step's dependsOn that referenced the old stepId must be
|
|
77
|
+
// rewritten to point at the new step. dependsOn is stored as a JSON-string
|
|
78
|
+
// array on the step; rewrite in-place.
|
|
79
|
+
const downstream = await session.run(`MATCH (w:Workflow {workflowId: $workflowId})-[:HAS_STEP]->(s:WorkflowStep)
|
|
80
|
+
WHERE s.dependsOn IS NOT NULL AND s.dependsOn CONTAINS $oldStepId
|
|
81
|
+
RETURN s.stepId AS stepId, s.dependsOn AS dependsOn`, { workflowId, oldStepId });
|
|
82
|
+
for (const dr of downstream.records) {
|
|
83
|
+
const stepId = dr.get("stepId");
|
|
84
|
+
const raw = dr.get("dependsOn");
|
|
85
|
+
let parsed;
|
|
86
|
+
try {
|
|
87
|
+
parsed = JSON.parse(raw);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (!Array.isArray(parsed))
|
|
93
|
+
continue;
|
|
94
|
+
const updated = parsed.map((d) => (d === oldStepId ? newStepId : d));
|
|
95
|
+
await session.run(`MATCH (s:WorkflowStep {stepId: $stepId})
|
|
96
|
+
SET s.dependsOn = $dependsOn`, { stepId, dependsOn: JSON.stringify(updated) });
|
|
84
97
|
}
|
|
85
|
-
|
|
86
|
-
prompt = prompt.replace(OLD_DATA_DESCRIPTION, NEW_DATA_DESCRIPTION);
|
|
87
|
-
await session.run(`MATCH (s:WorkflowStep {stepId: $stepId})
|
|
88
|
-
SET s.prompt = $prompt`, { stepId, prompt });
|
|
89
|
-
console.error(`[waitlist-heal] patched conversationDate field into prompt for workflow ${workflowId}`);
|
|
98
|
+
console.error(`[waitlist-heal] migrated legacy llm step ${oldStepId} → tool step ${newStepId} on workflow ${workflowId}`);
|
|
90
99
|
return true;
|
|
91
100
|
}
|
|
92
|
-
// ---------------------------------------------------------------------------
|
|
93
|
-
// Standalone tool entry point
|
|
94
|
-
// ---------------------------------------------------------------------------
|
|
95
101
|
export async function waitlistHeal(params) {
|
|
96
102
|
const { accountId } = params;
|
|
97
103
|
const session = getSession();
|
|
98
104
|
try {
|
|
99
|
-
// Look up the workflow by name
|
|
100
105
|
const workflowResult = await session.run(`MATCH (w:Workflow {accountId: $accountId, name: $name})
|
|
101
106
|
WHERE w.status IN ['active', 'draft']
|
|
102
107
|
RETURN w.workflowId AS workflowId
|
|
@@ -106,11 +111,9 @@ export async function waitlistHeal(params) {
|
|
|
106
111
|
return { healed: false, workflowId: null };
|
|
107
112
|
}
|
|
108
113
|
const workflowId = workflowResult.records[0].get("workflowId");
|
|
109
|
-
const
|
|
110
|
-
const healedDate = await healMissingConversationDate(session, workflowId);
|
|
111
|
-
const healed = healedBroken || healedDate;
|
|
114
|
+
const healed = await healLegacyLlmStep(session, workflowId, accountId);
|
|
112
115
|
if (healed) {
|
|
113
|
-
console.error(`[waitlist-heal]
|
|
116
|
+
console.error(`[waitlist-heal] workflow ${workflowId} migrated to tool-step shape`);
|
|
114
117
|
}
|
|
115
118
|
else {
|
|
116
119
|
console.error("[waitlist-heal] no healing needed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waitlist-heal.js","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"waitlist-heal.js","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waitlist-setup.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"waitlist-setup.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,8CAA8C,CAAC;AActD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;CACxB;AAMD,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA0O9B"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { randomUUID } from "node:crypto";
|
|
19
19
|
import { getSession } from "../lib/neo4j.js";
|
|
20
20
|
import { computeEmbedding } from "../lib/embedding.js";
|
|
21
|
-
import {
|
|
21
|
+
import { healLegacyLlmStep, WORKFLOW_NAME } from "./waitlist-heal.js";
|
|
22
22
|
import { writeNodeWithEdges, } from "../../../../../lib/graph-write/dist/index.js";
|
|
23
23
|
import cronParser from "cron-parser";
|
|
24
24
|
const { parseExpression } = cronParser;
|
|
@@ -26,32 +26,6 @@ const { parseExpression } = cronParser;
|
|
|
26
26
|
// Constants
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
28
|
const DEFAULT_RECURRENCE = "0 */4 * * *"; // Every 4 hours
|
|
29
|
-
/**
|
|
30
|
-
* The extraction prompt — the editable payload the user sees via
|
|
31
|
-
* workflow-get and modifies via workflow-update to change extraction
|
|
32
|
-
* behaviour.
|
|
33
|
-
*/
|
|
34
|
-
const EXTRACTION_PROMPT = "You extract contact details and customer discovery intelligence from visitor chat conversations.\n\n" +
|
|
35
|
-
"Below is a JSON object containing public agent conversations. It has a `conversations` array " +
|
|
36
|
-
"where each element has a `conversationId`, a `createdAt` timestamp, and a `messages` array of user message strings. " +
|
|
37
|
-
"For each conversation that contains an email address, extract the visitor's details.\n\n" +
|
|
38
|
-
"Return ONLY a JSON array of objects. Each object must have these fields:\n" +
|
|
39
|
-
'- "email": the visitor\'s email address (required — skip conversations with no email)\n' +
|
|
40
|
-
'- "givenName": the visitor\'s first/given name, or null if unclear\n' +
|
|
41
|
-
'- "familyName": the visitor\'s last/family name, or null if unclear\n' +
|
|
42
|
-
'- "conversationId": the conversation ID from the input data\n' +
|
|
43
|
-
'- "conversationDate": the createdAt timestamp of the conversation from the input data\n' +
|
|
44
|
-
'- "businessType": what kind of business they run or work in, or null\n' +
|
|
45
|
-
'- "role": their role or position, or null\n' +
|
|
46
|
-
'- "needs": what they need or are looking for, in their own words where possible, or null\n' +
|
|
47
|
-
'- "challenges": pain points or challenges they mentioned, or null\n' +
|
|
48
|
-
'- "interests": specific features, capabilities, or topics they asked about, or null\n' +
|
|
49
|
-
'- "engagementQuality": one of "high" (asked detailed questions, shared specifics), ' +
|
|
50
|
-
'"medium" (some back-and-forth, genuine interest), or "low" (brief, noncommittal), or null\n' +
|
|
51
|
-
'- "otherSignals": any other noteworthy signal (timeline urgency, competitor mentions, referral source), or null\n\n' +
|
|
52
|
-
"Only include fields where the visitor actually revealed information. " +
|
|
53
|
-
"Return valid JSON only. No markdown, no explanation. If no conversations contain an email, return [].\n\n" +
|
|
54
|
-
"Conversations:\n{{conversations}}";
|
|
55
29
|
// ---------------------------------------------------------------------------
|
|
56
30
|
// Main
|
|
57
31
|
// ---------------------------------------------------------------------------
|
|
@@ -97,13 +71,10 @@ export async function waitlistSetup(params) {
|
|
|
97
71
|
const existing = existingResult.records[0];
|
|
98
72
|
const workflowId = existing.get("workflowId");
|
|
99
73
|
const eventId = existing.get("eventId");
|
|
100
|
-
// Self-healing:
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
// user customizations made via workflow-update.
|
|
105
|
-
await healBrokenPrompt(session, workflowId);
|
|
106
|
-
await healMissingConversationDate(session, workflowId);
|
|
74
|
+
// Self-healing: migrate any legacy LLM-typed extraction step to the
|
|
75
|
+
// new `waitlist-extract` tool step. Idempotent — no-op when the
|
|
76
|
+
// workflow already has the tool-step shape.
|
|
77
|
+
await healLegacyLlmStep(session, workflowId, accountId);
|
|
107
78
|
// Workflow exists but no event — create one
|
|
108
79
|
if (!eventId) {
|
|
109
80
|
const newEventResult = await createScheduledEvent(session, accountId, workflowId, recurrence, timezone, createdBy);
|
|
@@ -135,8 +106,9 @@ export async function waitlistSetup(params) {
|
|
|
135
106
|
workflowId,
|
|
136
107
|
accountId,
|
|
137
108
|
name: WORKFLOW_NAME,
|
|
138
|
-
description: "Scans public agent conversations, extracts contact details and customer discovery intelligence
|
|
139
|
-
"and creates Person nodes idempotently.
|
|
109
|
+
description: "Scans public agent conversations, extracts contact details and customer discovery intelligence " +
|
|
110
|
+
"via the waitlist-extract tool, and creates Person nodes idempotently. The extraction prompt " +
|
|
111
|
+
"lives in the waitlist-extract tool source — redeploy the waitlist plugin to change behaviour.",
|
|
140
112
|
status: "active",
|
|
141
113
|
createdAt: now,
|
|
142
114
|
updatedAt: now,
|
|
@@ -184,13 +156,9 @@ export async function waitlistSetup(params) {
|
|
|
184
156
|
timeout: 30,
|
|
185
157
|
position: 0,
|
|
186
158
|
label: "Scan public conversations",
|
|
187
|
-
// LLM-step fields (null for tool steps)
|
|
188
|
-
prompt: null,
|
|
189
|
-
model: null,
|
|
190
|
-
maxTokens: null,
|
|
191
159
|
},
|
|
192
160
|
});
|
|
193
|
-
// Step 2: LLM
|
|
161
|
+
// Step 2: Extract contacts via the waitlist-extract tool (LLM-backed)
|
|
194
162
|
const step2Id = randomUUID();
|
|
195
163
|
await session.run(`MATCH (w:Workflow {workflowId: $workflowId})
|
|
196
164
|
CREATE (w)-[:HAS_STEP]->(s:WorkflowStep $props)`, {
|
|
@@ -199,10 +167,12 @@ export async function waitlistSetup(params) {
|
|
|
199
167
|
stepId: step2Id,
|
|
200
168
|
workflowId,
|
|
201
169
|
accountId,
|
|
202
|
-
type: "
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
170
|
+
type: "tool",
|
|
171
|
+
plugin: "waitlist",
|
|
172
|
+
tool: "waitlist-extract",
|
|
173
|
+
params: JSON.stringify({
|
|
174
|
+
conversations: "{{conversations}}",
|
|
175
|
+
}),
|
|
206
176
|
dependsOn: JSON.stringify([step1Id]),
|
|
207
177
|
onFailure: "abort",
|
|
208
178
|
retryLimit: null,
|
|
@@ -210,10 +180,6 @@ export async function waitlistSetup(params) {
|
|
|
210
180
|
timeout: 120,
|
|
211
181
|
position: 1,
|
|
212
182
|
label: "Extract contacts and discovery intelligence",
|
|
213
|
-
// Tool-step fields (null for LLM steps)
|
|
214
|
-
plugin: null,
|
|
215
|
-
tool: null,
|
|
216
|
-
params: null,
|
|
217
183
|
},
|
|
218
184
|
});
|
|
219
185
|
// Step 3: Persist extraction results
|
|
@@ -238,10 +204,6 @@ export async function waitlistSetup(params) {
|
|
|
238
204
|
timeout: 60,
|
|
239
205
|
position: 2,
|
|
240
206
|
label: "Create/update Person nodes from extractions",
|
|
241
|
-
// LLM-step fields (null for tool steps)
|
|
242
|
-
prompt: null,
|
|
243
|
-
model: null,
|
|
244
|
-
maxTokens: null,
|
|
245
207
|
},
|
|
246
208
|
});
|
|
247
209
|
// ------------------------------------------------------------------
|