@guidify-ai/vapi-studio 0.1.0

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.
Files changed (407) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/agent/AGENTS.md +42 -0
  4. package/agent/CLAUDE.md +15 -0
  5. package/agent/claude/rules/ui-and-api-identity.md +9 -0
  6. package/agent/claude/rules/vapi-studio-best-practices.md +36 -0
  7. package/agent/cursor/ui-and-api-identity.mdc +16 -0
  8. package/agent/cursor/vapi-studio-best-practices.mdc +43 -0
  9. package/dist/adapters/vapi/vapi-sse.compiler.d.ts +61 -0
  10. package/dist/adapters/vapi/vapi-sse.compiler.d.ts.map +1 -0
  11. package/dist/adapters/vapi/vapi-sse.compiler.js +396 -0
  12. package/dist/adapters/vapi/vapi-sse.compiler.js.map +1 -0
  13. package/dist/analytics/analytics-tags.d.ts +60 -0
  14. package/dist/analytics/analytics-tags.d.ts.map +1 -0
  15. package/dist/analytics/analytics-tags.js +27 -0
  16. package/dist/analytics/analytics-tags.js.map +1 -0
  17. package/dist/brain/adapters/chatgpt-brain.adapter.d.ts +27 -0
  18. package/dist/brain/adapters/chatgpt-brain.adapter.d.ts.map +1 -0
  19. package/dist/brain/adapters/chatgpt-brain.adapter.js +94 -0
  20. package/dist/brain/adapters/chatgpt-brain.adapter.js.map +1 -0
  21. package/dist/brain/adapters/claude-brain.adapter.d.ts +24 -0
  22. package/dist/brain/adapters/claude-brain.adapter.d.ts.map +1 -0
  23. package/dist/brain/adapters/claude-brain.adapter.js +96 -0
  24. package/dist/brain/adapters/claude-brain.adapter.js.map +1 -0
  25. package/dist/brain/adapters/gemini-brain.adapter.d.ts +24 -0
  26. package/dist/brain/adapters/gemini-brain.adapter.d.ts.map +1 -0
  27. package/dist/brain/adapters/gemini-brain.adapter.js +106 -0
  28. package/dist/brain/adapters/gemini-brain.adapter.js.map +1 -0
  29. package/dist/brain/adapters/grok-brain.adapter.d.ts +24 -0
  30. package/dist/brain/adapters/grok-brain.adapter.d.ts.map +1 -0
  31. package/dist/brain/adapters/grok-brain.adapter.js +90 -0
  32. package/dist/brain/adapters/grok-brain.adapter.js.map +1 -0
  33. package/dist/brain/adapters/json-llm-brain.base.d.ts +63 -0
  34. package/dist/brain/adapters/json-llm-brain.base.d.ts.map +1 -0
  35. package/dist/brain/adapters/json-llm-brain.base.js +511 -0
  36. package/dist/brain/adapters/json-llm-brain.base.js.map +1 -0
  37. package/dist/brain/adapters/mock-brain.adapter.d.ts +32 -0
  38. package/dist/brain/adapters/mock-brain.adapter.d.ts.map +1 -0
  39. package/dist/brain/adapters/mock-brain.adapter.js +201 -0
  40. package/dist/brain/adapters/mock-brain.adapter.js.map +1 -0
  41. package/dist/brain/adapters/mock-provider-brains.adapter.d.ts +22 -0
  42. package/dist/brain/adapters/mock-provider-brains.adapter.d.ts.map +1 -0
  43. package/dist/brain/adapters/mock-provider-brains.adapter.js +48 -0
  44. package/dist/brain/adapters/mock-provider-brains.adapter.js.map +1 -0
  45. package/dist/brain/brain-clarify.d.ts +75 -0
  46. package/dist/brain/brain-clarify.d.ts.map +1 -0
  47. package/dist/brain/brain-clarify.js +146 -0
  48. package/dist/brain/brain-clarify.js.map +1 -0
  49. package/dist/brain/brain-config.d.ts +20 -0
  50. package/dist/brain/brain-config.d.ts.map +1 -0
  51. package/dist/brain/brain-config.js +20 -0
  52. package/dist/brain/brain-config.js.map +1 -0
  53. package/dist/brain/brain-judge.d.ts +68 -0
  54. package/dist/brain/brain-judge.d.ts.map +1 -0
  55. package/dist/brain/brain-judge.js +111 -0
  56. package/dist/brain/brain-judge.js.map +1 -0
  57. package/dist/brain/brain-ranking.d.ts +41 -0
  58. package/dist/brain/brain-ranking.d.ts.map +1 -0
  59. package/dist/brain/brain-ranking.js +103 -0
  60. package/dist/brain/brain-ranking.js.map +1 -0
  61. package/dist/brain/brain-usage.tracker.d.ts +48 -0
  62. package/dist/brain/brain-usage.tracker.d.ts.map +1 -0
  63. package/dist/brain/brain-usage.tracker.js +106 -0
  64. package/dist/brain/brain-usage.tracker.js.map +1 -0
  65. package/dist/brain/brain.port.d.ts +63 -0
  66. package/dist/brain/brain.port.d.ts.map +1 -0
  67. package/dist/brain/brain.port.js +7 -0
  68. package/dist/brain/brain.port.js.map +1 -0
  69. package/dist/brain/brain.service.d.ts +14 -0
  70. package/dist/brain/brain.service.d.ts.map +1 -0
  71. package/dist/brain/brain.service.js +27 -0
  72. package/dist/brain/brain.service.js.map +1 -0
  73. package/dist/brain/claude-cheap-models.d.ts +18 -0
  74. package/dist/brain/claude-cheap-models.d.ts.map +1 -0
  75. package/dist/brain/claude-cheap-models.js +53 -0
  76. package/dist/brain/claude-cheap-models.js.map +1 -0
  77. package/dist/brain/gemini-cheap-models.d.ts +18 -0
  78. package/dist/brain/gemini-cheap-models.d.ts.map +1 -0
  79. package/dist/brain/gemini-cheap-models.js +53 -0
  80. package/dist/brain/gemini-cheap-models.js.map +1 -0
  81. package/dist/brain/grok-cheap-models.d.ts +18 -0
  82. package/dist/brain/grok-cheap-models.d.ts.map +1 -0
  83. package/dist/brain/grok-cheap-models.js +53 -0
  84. package/dist/brain/grok-cheap-models.js.map +1 -0
  85. package/dist/brain/llm-model-pricing.d.ts +29 -0
  86. package/dist/brain/llm-model-pricing.d.ts.map +1 -0
  87. package/dist/brain/llm-model-pricing.js +38 -0
  88. package/dist/brain/llm-model-pricing.js.map +1 -0
  89. package/dist/brain/openai-cheap-models.d.ts +34 -0
  90. package/dist/brain/openai-cheap-models.d.ts.map +1 -0
  91. package/dist/brain/openai-cheap-models.js +72 -0
  92. package/dist/brain/openai-cheap-models.js.map +1 -0
  93. package/dist/brain/prompt-injection-guard.d.ts +34 -0
  94. package/dist/brain/prompt-injection-guard.d.ts.map +1 -0
  95. package/dist/brain/prompt-injection-guard.js +109 -0
  96. package/dist/brain/prompt-injection-guard.js.map +1 -0
  97. package/dist/channel/channel-tools.d.ts +72 -0
  98. package/dist/channel/channel-tools.d.ts.map +1 -0
  99. package/dist/channel/channel-tools.js +131 -0
  100. package/dist/channel/channel-tools.js.map +1 -0
  101. package/dist/conversation/call-turn-queue.d.ts +64 -0
  102. package/dist/conversation/call-turn-queue.d.ts.map +1 -0
  103. package/dist/conversation/call-turn-queue.js +156 -0
  104. package/dist/conversation/call-turn-queue.js.map +1 -0
  105. package/dist/conversation/conversation-bootstrap.service.d.ts +60 -0
  106. package/dist/conversation/conversation-bootstrap.service.d.ts.map +1 -0
  107. package/dist/conversation/conversation-bootstrap.service.js +383 -0
  108. package/dist/conversation/conversation-bootstrap.service.js.map +1 -0
  109. package/dist/conversation/conversation-entry.d.ts +38 -0
  110. package/dist/conversation/conversation-entry.d.ts.map +1 -0
  111. package/dist/conversation/conversation-entry.js +17 -0
  112. package/dist/conversation/conversation-entry.js.map +1 -0
  113. package/dist/conversation/conversation-history.d.ts +31 -0
  114. package/dist/conversation/conversation-history.d.ts.map +1 -0
  115. package/dist/conversation/conversation-history.js +53 -0
  116. package/dist/conversation/conversation-history.js.map +1 -0
  117. package/dist/conversation/conversation-limits.d.ts +49 -0
  118. package/dist/conversation/conversation-limits.d.ts.map +1 -0
  119. package/dist/conversation/conversation-limits.js +44 -0
  120. package/dist/conversation/conversation-limits.js.map +1 -0
  121. package/dist/conversation/conversation-resume.service.d.ts +39 -0
  122. package/dist/conversation/conversation-resume.service.d.ts.map +1 -0
  123. package/dist/conversation/conversation-resume.service.js +234 -0
  124. package/dist/conversation/conversation-resume.service.js.map +1 -0
  125. package/dist/conversation/conversation-schema.d.ts +23 -0
  126. package/dist/conversation/conversation-schema.d.ts.map +1 -0
  127. package/dist/conversation/conversation-schema.js +3 -0
  128. package/dist/conversation/conversation-schema.js.map +1 -0
  129. package/dist/conversation/listen-expectation.d.ts +145 -0
  130. package/dist/conversation/listen-expectation.d.ts.map +1 -0
  131. package/dist/conversation/listen-expectation.js +219 -0
  132. package/dist/conversation/listen-expectation.js.map +1 -0
  133. package/dist/conversation/listen-timeout.d.ts +42 -0
  134. package/dist/conversation/listen-timeout.d.ts.map +1 -0
  135. package/dist/conversation/listen-timeout.js +57 -0
  136. package/dist/conversation/listen-timeout.js.map +1 -0
  137. package/dist/conversation/supervised-conversation.d.ts +64 -0
  138. package/dist/conversation/supervised-conversation.d.ts.map +1 -0
  139. package/dist/conversation/supervised-conversation.js +198 -0
  140. package/dist/conversation/supervised-conversation.js.map +1 -0
  141. package/dist/conversation/supervised-conversation.registry.d.ts +14 -0
  142. package/dist/conversation/supervised-conversation.registry.d.ts.map +1 -0
  143. package/dist/conversation/supervised-conversation.registry.js +47 -0
  144. package/dist/conversation/supervised-conversation.registry.js.map +1 -0
  145. package/dist/conversation/types.d.ts +52 -0
  146. package/dist/conversation/types.d.ts.map +1 -0
  147. package/dist/conversation/types.js +3 -0
  148. package/dist/conversation/types.js.map +1 -0
  149. package/dist/events/conversation-console.d.ts +17 -0
  150. package/dist/events/conversation-console.d.ts.map +1 -0
  151. package/dist/events/conversation-console.js +863 -0
  152. package/dist/events/conversation-console.js.map +1 -0
  153. package/dist/events/daily-log.driver.d.ts +35 -0
  154. package/dist/events/daily-log.driver.d.ts.map +1 -0
  155. package/dist/events/daily-log.driver.js +206 -0
  156. package/dist/events/daily-log.driver.js.map +1 -0
  157. package/dist/events/event.service.d.ts +24 -0
  158. package/dist/events/event.service.d.ts.map +1 -0
  159. package/dist/events/event.service.js +141 -0
  160. package/dist/events/event.service.js.map +1 -0
  161. package/dist/events/route-forensics.d.ts +38 -0
  162. package/dist/events/route-forensics.d.ts.map +1 -0
  163. package/dist/events/route-forensics.js +85 -0
  164. package/dist/events/route-forensics.js.map +1 -0
  165. package/dist/events/studio-event-bus.d.ts +17 -0
  166. package/dist/events/studio-event-bus.d.ts.map +1 -0
  167. package/dist/events/studio-event-bus.js +37 -0
  168. package/dist/events/studio-event-bus.js.map +1 -0
  169. package/dist/events/studio-event.d.ts +44 -0
  170. package/dist/events/studio-event.d.ts.map +1 -0
  171. package/dist/events/studio-event.js +27 -0
  172. package/dist/events/studio-event.js.map +1 -0
  173. package/dist/flow/condition.d.ts +35 -0
  174. package/dist/flow/condition.d.ts.map +1 -0
  175. package/dist/flow/condition.js +246 -0
  176. package/dist/flow/condition.js.map +1 -0
  177. package/dist/flow/flow-loader.d.ts +71 -0
  178. package/dist/flow/flow-loader.d.ts.map +1 -0
  179. package/dist/flow/flow-loader.js +182 -0
  180. package/dist/flow/flow-loader.js.map +1 -0
  181. package/dist/forms/form-html.d.ts +30 -0
  182. package/dist/forms/form-html.d.ts.map +1 -0
  183. package/dist/forms/form-html.js +130 -0
  184. package/dist/forms/form-html.js.map +1 -0
  185. package/dist/forms/form.tokens.d.ts +3 -0
  186. package/dist/forms/form.tokens.d.ts.map +1 -0
  187. package/dist/forms/form.tokens.js +6 -0
  188. package/dist/forms/form.tokens.js.map +1 -0
  189. package/dist/forms/form.types.d.ts +81 -0
  190. package/dist/forms/form.types.d.ts.map +1 -0
  191. package/dist/forms/form.types.js +36 -0
  192. package/dist/forms/form.types.js.map +1 -0
  193. package/dist/forms/forms.service.d.ts +52 -0
  194. package/dist/forms/forms.service.d.ts.map +1 -0
  195. package/dist/forms/forms.service.js +434 -0
  196. package/dist/forms/forms.service.js.map +1 -0
  197. package/dist/forms/noop-form-dispose.adapter.d.ts +12 -0
  198. package/dist/forms/noop-form-dispose.adapter.d.ts.map +1 -0
  199. package/dist/forms/noop-form-dispose.adapter.js +27 -0
  200. package/dist/forms/noop-form-dispose.adapter.js.map +1 -0
  201. package/dist/forms/twilio-sms-form-dispose.adapter.d.ts +33 -0
  202. package/dist/forms/twilio-sms-form-dispose.adapter.d.ts.map +1 -0
  203. package/dist/forms/twilio-sms-form-dispose.adapter.js +125 -0
  204. package/dist/forms/twilio-sms-form-dispose.adapter.js.map +1 -0
  205. package/dist/forms/twilio-sms.env.d.ts +62 -0
  206. package/dist/forms/twilio-sms.env.d.ts.map +1 -0
  207. package/dist/forms/twilio-sms.env.js +147 -0
  208. package/dist/forms/twilio-sms.env.js.map +1 -0
  209. package/dist/forms/twilio-sms.sender.d.ts +27 -0
  210. package/dist/forms/twilio-sms.sender.d.ts.map +1 -0
  211. package/dist/forms/twilio-sms.sender.js +75 -0
  212. package/dist/forms/twilio-sms.sender.js.map +1 -0
  213. package/dist/identity/email-parse.d.ts +20 -0
  214. package/dist/identity/email-parse.d.ts.map +1 -0
  215. package/dist/identity/email-parse.js +102 -0
  216. package/dist/identity/email-parse.js.map +1 -0
  217. package/dist/identity/index.d.ts +17 -0
  218. package/dist/identity/index.d.ts.map +1 -0
  219. package/dist/identity/index.js +23 -0
  220. package/dist/identity/index.js.map +1 -0
  221. package/dist/index.d.ts +108 -0
  222. package/dist/index.d.ts.map +1 -0
  223. package/dist/index.js +300 -0
  224. package/dist/index.js.map +1 -0
  225. package/dist/integrations/integration-client.d.ts +41 -0
  226. package/dist/integrations/integration-client.d.ts.map +1 -0
  227. package/dist/integrations/integration-client.js +152 -0
  228. package/dist/integrations/integration-client.js.map +1 -0
  229. package/dist/integrations/jwt-hmac.d.ts +33 -0
  230. package/dist/integrations/jwt-hmac.d.ts.map +1 -0
  231. package/dist/integrations/jwt-hmac.js +108 -0
  232. package/dist/integrations/jwt-hmac.js.map +1 -0
  233. package/dist/intention/code-intention.d.ts +94 -0
  234. package/dist/intention/code-intention.d.ts.map +1 -0
  235. package/dist/intention/code-intention.js +89 -0
  236. package/dist/intention/code-intention.js.map +1 -0
  237. package/dist/intention/intention-constants.d.ts +37 -0
  238. package/dist/intention/intention-constants.d.ts.map +1 -0
  239. package/dist/intention/intention-constants.js +37 -0
  240. package/dist/intention/intention-constants.js.map +1 -0
  241. package/dist/intentions/standard-intentions.d.ts +26 -0
  242. package/dist/intentions/standard-intentions.d.ts.map +1 -0
  243. package/dist/intentions/standard-intentions.js +28 -0
  244. package/dist/intentions/standard-intentions.js.map +1 -0
  245. package/dist/node/agent-node.d.ts +156 -0
  246. package/dist/node/agent-node.d.ts.map +1 -0
  247. package/dist/node/agent-node.js +179 -0
  248. package/dist/node/agent-node.js.map +1 -0
  249. package/dist/node/catch-directive.d.ts +33 -0
  250. package/dist/node/catch-directive.d.ts.map +1 -0
  251. package/dist/node/catch-directive.js +41 -0
  252. package/dist/node/catch-directive.js.map +1 -0
  253. package/dist/output/conversation-output.d.ts +113 -0
  254. package/dist/output/conversation-output.d.ts.map +1 -0
  255. package/dist/output/conversation-output.js +100 -0
  256. package/dist/output/conversation-output.js.map +1 -0
  257. package/dist/persistence/conversation.entity.d.ts +27 -0
  258. package/dist/persistence/conversation.entity.d.ts.map +1 -0
  259. package/dist/persistence/conversation.entity.js +115 -0
  260. package/dist/persistence/conversation.entity.js.map +1 -0
  261. package/dist/persistence/conversation.repository.d.ts +82 -0
  262. package/dist/persistence/conversation.repository.d.ts.map +1 -0
  263. package/dist/persistence/conversation.repository.js +277 -0
  264. package/dist/persistence/conversation.repository.js.map +1 -0
  265. package/dist/persistence/project.entity.d.ts +12 -0
  266. package/dist/persistence/project.entity.d.ts.map +1 -0
  267. package/dist/persistence/project.entity.js +46 -0
  268. package/dist/persistence/project.entity.js.map +1 -0
  269. package/dist/persistence/project.repository.d.ts +17 -0
  270. package/dist/persistence/project.repository.d.ts.map +1 -0
  271. package/dist/persistence/project.repository.js +69 -0
  272. package/dist/persistence/project.repository.js.map +1 -0
  273. package/dist/persistence/provider-ingress.entity.d.ts +18 -0
  274. package/dist/persistence/provider-ingress.entity.d.ts.map +1 -0
  275. package/dist/persistence/provider-ingress.entity.js +91 -0
  276. package/dist/persistence/provider-ingress.entity.js.map +1 -0
  277. package/dist/persistence/provider-ingress.repository.d.ts +21 -0
  278. package/dist/persistence/provider-ingress.repository.d.ts.map +1 -0
  279. package/dist/persistence/provider-ingress.repository.js +76 -0
  280. package/dist/persistence/provider-ingress.repository.js.map +1 -0
  281. package/dist/studio-ui/assets/index-BGd2OhLv.js +84 -0
  282. package/dist/studio-ui/assets/index-BGd2OhLv.js.map +1 -0
  283. package/dist/studio-ui/assets/index-DnJos5x2.css +1 -0
  284. package/dist/studio-ui/index.html +13 -0
  285. package/dist/studio-ui-mount/index.d.ts +6 -0
  286. package/dist/studio-ui-mount/index.d.ts.map +1 -0
  287. package/dist/studio-ui-mount/index.js +13 -0
  288. package/dist/studio-ui-mount/index.js.map +1 -0
  289. package/dist/studio-ui-mount/resolve-studio-ui-root.d.ts +6 -0
  290. package/dist/studio-ui-mount/resolve-studio-ui-root.d.ts.map +1 -0
  291. package/dist/studio-ui-mount/resolve-studio-ui-root.js +25 -0
  292. package/dist/studio-ui-mount/resolve-studio-ui-root.js.map +1 -0
  293. package/dist/studio-ui-mount/studio-spa.controller.d.ts +18 -0
  294. package/dist/studio-ui-mount/studio-spa.controller.d.ts.map +1 -0
  295. package/dist/studio-ui-mount/studio-spa.controller.js +57 -0
  296. package/dist/studio-ui-mount/studio-spa.controller.js.map +1 -0
  297. package/dist/studio-ui-mount/studio-ui.module.d.ts +15 -0
  298. package/dist/studio-ui-mount/studio-ui.module.d.ts.map +1 -0
  299. package/dist/studio-ui-mount/studio-ui.module.js +47 -0
  300. package/dist/studio-ui-mount/studio-ui.module.js.map +1 -0
  301. package/dist/studio-ui-mount/studio-ui.tokens.d.ts +2 -0
  302. package/dist/studio-ui-mount/studio-ui.tokens.d.ts.map +1 -0
  303. package/dist/studio-ui-mount/studio-ui.tokens.js +5 -0
  304. package/dist/studio-ui-mount/studio-ui.tokens.js.map +1 -0
  305. package/dist/supervisor/supervisor-cascade.d.ts +55 -0
  306. package/dist/supervisor/supervisor-cascade.d.ts.map +1 -0
  307. package/dist/supervisor/supervisor-cascade.js +261 -0
  308. package/dist/supervisor/supervisor-cascade.js.map +1 -0
  309. package/dist/supervisor/supervisor-engine.d.ts +9 -0
  310. package/dist/supervisor/supervisor-engine.d.ts.map +1 -0
  311. package/dist/supervisor/supervisor-engine.js +64 -0
  312. package/dist/supervisor/supervisor-engine.js.map +1 -0
  313. package/dist/supervisor/supervisor-limits.d.ts +8 -0
  314. package/dist/supervisor/supervisor-limits.d.ts.map +1 -0
  315. package/dist/supervisor/supervisor-limits.js +36 -0
  316. package/dist/supervisor/supervisor-limits.js.map +1 -0
  317. package/dist/supervisor/supervisor-node-exec.d.ts +39 -0
  318. package/dist/supervisor/supervisor-node-exec.d.ts.map +1 -0
  319. package/dist/supervisor/supervisor-node-exec.js +201 -0
  320. package/dist/supervisor/supervisor-node-exec.js.map +1 -0
  321. package/dist/supervisor/supervisor-orchestration.d.ts +24 -0
  322. package/dist/supervisor/supervisor-orchestration.d.ts.map +1 -0
  323. package/dist/supervisor/supervisor-orchestration.js +395 -0
  324. package/dist/supervisor/supervisor-orchestration.js.map +1 -0
  325. package/dist/supervisor/supervisor-portal.d.ts +75 -0
  326. package/dist/supervisor/supervisor-portal.d.ts.map +1 -0
  327. package/dist/supervisor/supervisor-portal.js +320 -0
  328. package/dist/supervisor/supervisor-portal.js.map +1 -0
  329. package/dist/supervisor/supervisor-route.d.ts +53 -0
  330. package/dist/supervisor/supervisor-route.d.ts.map +1 -0
  331. package/dist/supervisor/supervisor-route.js +308 -0
  332. package/dist/supervisor/supervisor-route.js.map +1 -0
  333. package/dist/supervisor/supervisor-special-turns.d.ts +34 -0
  334. package/dist/supervisor/supervisor-special-turns.d.ts.map +1 -0
  335. package/dist/supervisor/supervisor-special-turns.js +308 -0
  336. package/dist/supervisor/supervisor-special-turns.js.map +1 -0
  337. package/dist/supervisor/supervisor.d.ts +44 -0
  338. package/dist/supervisor/supervisor.d.ts.map +1 -0
  339. package/dist/supervisor/supervisor.js +79 -0
  340. package/dist/supervisor/supervisor.js.map +1 -0
  341. package/dist/supervisor/supervisor.types.d.ts +71 -0
  342. package/dist/supervisor/supervisor.types.d.ts.map +1 -0
  343. package/dist/supervisor/supervisor.types.js +8 -0
  344. package/dist/supervisor/supervisor.types.js.map +1 -0
  345. package/dist/tasks/studio-task-queue.d.ts +93 -0
  346. package/dist/tasks/studio-task-queue.d.ts.map +1 -0
  347. package/dist/tasks/studio-task-queue.js +226 -0
  348. package/dist/tasks/studio-task-queue.js.map +1 -0
  349. package/dist/util/studio-env.d.ts +7 -0
  350. package/dist/util/studio-env.d.ts.map +1 -0
  351. package/dist/util/studio-env.js +32 -0
  352. package/dist/util/studio-env.js.map +1 -0
  353. package/dist/vapi-studio.module.d.ts +55 -0
  354. package/dist/vapi-studio.module.d.ts.map +1 -0
  355. package/dist/vapi-studio.module.js +166 -0
  356. package/dist/vapi-studio.module.js.map +1 -0
  357. package/dist/workflow/workflow-handoff.service.d.ts +29 -0
  358. package/dist/workflow/workflow-handoff.service.d.ts.map +1 -0
  359. package/dist/workflow/workflow-handoff.service.js +165 -0
  360. package/dist/workflow/workflow-handoff.service.js.map +1 -0
  361. package/dist/workflow/workflow-loader.d.ts +48 -0
  362. package/dist/workflow/workflow-loader.d.ts.map +1 -0
  363. package/dist/workflow/workflow-loader.js +87 -0
  364. package/dist/workflow/workflow-loader.js.map +1 -0
  365. package/docs/README.md +69 -0
  366. package/docs/assets/deterministic-assistant-flow.svg +128 -0
  367. package/docs/assets/vapi-studio-stack.svg +26 -0
  368. package/docs/best-practices/README.md +37 -0
  369. package/docs/best-practices/brain-and-prompt-injection.md +70 -0
  370. package/docs/best-practices/conversation-design.md +152 -0
  371. package/docs/best-practices/debugging-and-observability.md +49 -0
  372. package/docs/best-practices/documentation-layers.md +31 -0
  373. package/docs/best-practices/identity-and-pii.md +66 -0
  374. package/docs/best-practices/nodes-and-listens.md +116 -0
  375. package/docs/best-practices/ui-and-api-identity.md +51 -0
  376. package/docs/building-apps/creating-an-app.md +59 -0
  377. package/docs/building-apps/example-apps.md +23 -0
  378. package/docs/building-apps/overview.md +27 -0
  379. package/docs/getting-started/installation.md +52 -0
  380. package/docs/getting-started/introduction.md +23 -0
  381. package/docs/getting-started/quick-start.md +23 -0
  382. package/docs/guide/concepts.md +103 -0
  383. package/docs/guide/forms.md +102 -0
  384. package/docs/guide/handbook.md +21 -0
  385. package/docs/guide/introduction.md +56 -0
  386. package/docs/guide/module-setup.md +68 -0
  387. package/docs/guide/vapi-adapter.md +70 -0
  388. package/docs/guide/workflow-squad.md +59 -0
  389. package/docs/guides/agents.md +85 -0
  390. package/docs/guides/docker-compose.events.stub.yaml +27 -0
  391. package/docs/guides/documentation.md +13 -0
  392. package/docs/guides/extending-events.md +155 -0
  393. package/docs/guides/node-conventions.md +59 -0
  394. package/docs/guides/speckit.md +56 -0
  395. package/docs/reference/data-model.md +79 -0
  396. package/docs/reference/environment-variables.md +60 -0
  397. package/docs/reference/events-and-logging.md +137 -0
  398. package/docs/reference/flow-schema.md +79 -0
  399. package/docs/reference/runtime-api.md +708 -0
  400. package/docs/reference/security.md +41 -0
  401. package/docs/reference/standard-intentions.md +49 -0
  402. package/docs/reference/testing.md +15 -0
  403. package/docs/samples/events/nest-listener.example.ts +17 -0
  404. package/docs/samples/events/redis-bridge.example.ts +44 -0
  405. package/package.json +81 -0
  406. package/scripts/fix-access-modifiers.mjs +85 -0
  407. package/scripts/install-agent-refs.cjs +196 -0
@@ -0,0 +1,21 @@
1
+ # Handbook
2
+
3
+ Runtime contracts moved out of the repository README.
4
+
5
+ ## Canonical sources
6
+
7
+ | Layer | Path |
8
+ | --- | --- |
9
+ | **Entry index** | [README.md](../../README.md) — product intro, tools list, diagram, links |
10
+ | **Runtime API** | [runtime-api.md](../reference/runtime-api.md) — shipped behavior (update with code) |
11
+ | **Documentation site** | [docs/README.md](../README.md) |
12
+
13
+ ## Do not
14
+
15
+ - Put application-specific agent steps or customer copy in framework docs
16
+ - Import `@guidify-ai/vapi-studio/src/...` — use public `index.ts` only
17
+
18
+ ## Related
19
+
20
+ - [Concepts](./concepts.md)
21
+ - [Best practices](../best-practices/README.md)
@@ -0,0 +1,56 @@
1
+ # Vapi Studio — Introduction
2
+
3
+ **Vapi Studio** is Guidify AI's code-first framework for deterministic voice agents. It ships as `@guidify-ai/vapi-studio` in `vapi-studio/`.
4
+
5
+ ## What it is
6
+
7
+ A NestJS module that provides:
8
+
9
+ - **Supervised conversations** — one runtime per call, durable Postgres record
10
+ - **Nodes** — `AgentNode` subclasses with `before` → `listen` → `run` → `after` → `catch`
11
+ - **Flow YAML** — start node, intentions, portals, condition transitions
12
+ - **Brain port** — mock, OpenAI, or your HTTP adapter for intention scan
13
+ - **Output port** — `say`, `sayAndListen`, `endCall`, `transferToHuman`, `handoff`, `continueTo`, `invokeAdvertisedTool`, forms
14
+ - **Vapi adapter** — OpenAI-compatible Custom LLM SSE + webhook helpers
15
+ - **Events & logs** — call forensics (`ROUTE_DECISION`, form sendout, daily files)
16
+
17
+ ## What it is not
18
+
19
+ - A no-code bot builder
20
+ - A hosted SaaS
21
+ - A place for customer-specific logic — that belongs in **your application** (separate from this package)
22
+
23
+ ## How apps use it
24
+
25
+ ```typescript
26
+ VapiStudioModule.forRoot({
27
+ entryPoint: MyConversationEntry,
28
+ nodes: [
29
+ { className: 'AcknowledgeNode', useClass: AcknowledgeNode },
30
+ { className: 'GoodbyeNode', useClass: GoodbyeNode },
31
+ ],
32
+ intentions: [NeedSmsPhoneIntention],
33
+ brainAdapter: ChatGptBrainAdapter,
34
+ brain: {
35
+ model: 'gpt-4.1-mini',
36
+ confidenceThreshold: 0.4,
37
+ },
38
+ formDisposeAdapter: LinkFormDisposeAdapter,
39
+ eventListeners: [MyEventBuffer],
40
+ })
41
+ ```
42
+
43
+ Applications own `config/flow.yaml`, node classes, variables/memory types, channel wiring, and `.env`. The framework owns orchestration contracts.
44
+
45
+ ## Documentation map
46
+
47
+ | Depth | Where |
48
+ | --- | --- |
49
+ | Concepts | [Concepts](./concepts.md) |
50
+ | Wiring | [Module setup](./module-setup.md) |
51
+ | Forms | [Forms](./forms.md) |
52
+ | Vapi | [Vapi adapter](./vapi-adapter.md) |
53
+ | Squads | [Workflow & Squad](./workflow-squad.md) |
54
+ | Full API | [Runtime API](../reference/runtime-api.md) |
55
+ | Conversation design | [Best practices](../best-practices/README.md) |
56
+ | Example app | [Example apps](../building-apps/example-apps.md) (external repos) |
@@ -0,0 +1,68 @@
1
+ # Module setup
2
+
3
+ The [vapi-studio-project](https://github.com/guidify-ai/vapi-studio-project) starter already depends on `@guidify-ai/vapi-studio` and wires `VapiStudioModule.forRoot`. Use this page when extending that module options block.
4
+
5
+ ## Dependency (already in the starter)
6
+
7
+ ```json
8
+ {
9
+ "dependencies": {
10
+ "@guidify-ai/vapi-studio": "0.1.0"
11
+ }
12
+ }
13
+ ```
14
+
15
+ ## `VapiStudioModule.forRoot` options
16
+
17
+ | Option | Required | Purpose |
18
+ | --- | --- | --- |
19
+ | `nodes` | Yes | `{ className, useClass }[]` — every node in `flow.yaml` |
20
+ | `entryPoint` | Yes | `ConversationEntryPoint` — seed variables, `beforeEach` / `afterEach` |
21
+ | `brainAdapter` | Yes | `MockBrainAdapter`, `ChatGptBrainAdapter`, `ClaudeBrainAdapter`, `GeminiBrainAdapter`, `GrokBrainAdapter`, or custom |
22
+ | `brain` | No | `{ model, confidenceThreshold }` for ChatGPT adapter |
23
+ | `intentions` | No | `CodeIntention[]` providers (`INTENTION_CASCADE_PHASE`) |
24
+ | `limits` | No | Always on: `{ maxTurns?, maxDurationMs?, endMessage? }` (defaults 40 / 20m; ceilings 150 / 60m) |
25
+ | `eventListeners` | No | `StudioEventListener[]` |
26
+ | `formDisposeAdapter` | No | Delivers forms (HTML link, Studio modal, Twilio SMS, …) |
27
+
28
+ ## Node registration pattern
29
+
30
+ Every node class must be:
31
+
32
+ 1. A Nest `@Injectable()` extending `AgentNode<YourSchema>`
33
+ 2. Listed in `VapiStudioModule.forRoot({ nodes: [...] })`
34
+ 3. Referenced in `config/flow.yaml` by `className`
35
+
36
+ ## Conversation entry
37
+
38
+ ```typescript
39
+ @Injectable()
40
+ export class MyConversationEntry implements ConversationEntryPoint<MySchema> {
41
+ createVariables(ctx): MyVariables { /* channel, callerId, flags */ }
42
+ async beforeEach(ctx) { /* CRM hydrate, feature flags — not cross-call resume */ }
43
+ async afterEach(ctx) { /* optional */ }
44
+ }
45
+ ```
46
+
47
+ ## Flow file location
48
+
49
+ `FlowLoader` reads `config/flow.yaml` relative to `CONFIG_DIR` (default: app `config/` in Docker).
50
+
51
+ ## Agent scaffolding
52
+
53
+ `yarn install` in an app runs postinstall:
54
+
55
+ - `.cursor/rules/vapi-studio-best-practices.mdc`
56
+ - `AGENTS.md` stamped block
57
+
58
+ Manual refresh:
59
+
60
+ ```bash
61
+ INIT_CWD=$PWD node node_modules/@guidify-ai/vapi-studio/scripts/install-agent-refs.cjs
62
+ ```
63
+
64
+ ## Related
65
+
66
+ - [Concepts](./concepts.md)
67
+ - [Runtime API](../reference/runtime-api.md)
68
+ - [Creating an app](../building-apps/creating-an-app.md)
@@ -0,0 +1,70 @@
1
+ # Vapi adapter
2
+
3
+ How Vapi Studio compiles node output for Vapi Custom LLM and webhooks.
4
+
5
+ ## Endpoints (app-owned)
6
+
7
+ Typical PoC routes:
8
+
9
+ | Method | Path | Vapi assistant field |
10
+ | --- | --- | --- |
11
+ | `POST` | `/vapi/webhook` | **Webhook** — assistant-request, status-update, tool-calls |
12
+ | `POST` | `/vapi/chat/completions` | **Conversation** (Custom LLM SSE, single assistant) |
13
+ | `POST` | `/vapi/:moduleId/chat/completions` | **Conversation** per Squad module when workflow loaded |
14
+
15
+ See [Creating an app](../building-apps/creating-an-app.md) for route patterns in your NestJS app.
16
+
17
+ **Routing:** each starter fork is its own deploy (`PUBLIC_BASE_URL` / port). Paths are host-scoped — no project UUID segment. Vapi `assistantId` is forensics only — not used to pick the project.
18
+
19
+ ## Correlation
20
+
21
+ - Vapi **call id** (`message.call.id`) maps to supervised runtime via `extractVapiCallId`
22
+ - Framework **conversation id** is canonical — never replace with provider id
23
+ - Lazy bootstrap: first Custom LLM POST may create runtime if webhook order differs
24
+
25
+ ## Custom LLM SSE contract
26
+
27
+ 1. Open SSE immediately (before Brain HTTP)
28
+ 2. Run supervisor turn
29
+ 3. Stream `say` chunks via `VapiSseCompiler`
30
+ 4. `sayAndListen` — speak then end turn as listening
31
+ 5. `endCall` / `transferToHuman` — OpenAI-compatible **tool calls** (names must match Vapi assistant tools)
32
+ 6. Duplicate/stale Custom LLM POSTs: replay on that connection — never empty dead air on live stream
33
+
34
+ ## Tool names (env)
35
+
36
+ | Variable | Default | Purpose |
37
+ | --- | --- | --- |
38
+ | `VAPI_END_CALL_TOOL_NAME` | `end_call_tool` | Farewell `endCall` |
39
+ | `VAPI_TRANSFER_CALL_TOOL_NAME` | `transfer_call` | Human transfer (`.env.example` snake_case; live may keep `transferCall`) |
40
+ | `VAPI_HANDOFF_TOOL_NAME` | `handoff` | Squad module handoff |
41
+ | `VAPI_TRANSFER_DESTINATION` | — | E.164 for transfer tool |
42
+
43
+ Function names on the Vapi assistant **must match** these exactly.
44
+
45
+ ## Webhook strategies (PoC)
46
+
47
+ | `message.type` | Typical behavior |
48
+ | --- | --- |
49
+ | `assistant-request` | Bootstrap + return `assistantId` or transient assistant config |
50
+ | `call.started` / `assistant.started` | Bootstrap (saved-assistant path) |
51
+ | `status-update` | Bootstrap on `in-progress`; finalize on `ended` |
52
+ | `tool-calls` | Still-there portal tool → StillThere portal |
53
+ | `user-interrupted` | Record interrupt |
54
+
55
+ Guard: reject messages missing `message.call.id` → `400`.
56
+
57
+ ## Channel tools
58
+
59
+ `ctx.tools` — tools advertised on this Custom LLM request
60
+ `ctx.toolResults()` — results from `role: tool` messages (re-entry after tool execution)
61
+
62
+ ## Operator setup
63
+
64
+ Full dashboard checklist: implement in **your application** — see [Creating an app](../building-apps/creating-an-app.md).
65
+
66
+ ## Related
67
+
68
+ - [Runtime API](../reference/runtime-api.md)
69
+ - [Workflow & Squad](./workflow-squad.md)
70
+ - [Creating an app](../building-apps/creating-an-app.md)
@@ -0,0 +1,59 @@
1
+ # Workflow & Squad
2
+
3
+ Optional multi-assistant deployments. Many apps use **one assistant** and `continueTo` instead.
4
+
5
+ ## When to use
6
+
7
+ | Pattern | Use |
8
+ | --- | --- |
9
+ | `continueTo({ nodeId })` | Same assistant, same Conversation — lane jumps |
10
+ | `handoff({ moduleId })` | Vapi Squad — switch assistant, shared workflow memory |
11
+
12
+ ## `workflow.yaml`
13
+
14
+ ```yaml
15
+ version: 1
16
+ workflow:
17
+ id: my-workflow
18
+ entryModule: router
19
+ modules:
20
+ router:
21
+ assistantName: MyRouter
22
+ kind: studio
23
+ flowFile: modules/router.flow.yaml
24
+ entryNode: routerTriage
25
+ identity:
26
+ assistantName: MyIdentity
27
+ kind: studio
28
+ flowFile: modules/identity.flow.yaml
29
+ ```
30
+
31
+ - `WorkflowLoader` resolves module id ↔ Vapi `assistantName`
32
+ - `WorkflowHandoffService` enriches handoff actions, checkpoints, emits `WORKFLOW_HANDOFF`
33
+ - Handoff does **not** finalize the Conversation
34
+
35
+ ## URLs
36
+
37
+ - `POST /vapi/:moduleId/chat/completions`
38
+ - Header `X-Vapi-Studio-Module` also accepted
39
+
40
+ ## Vapi handoff tool
41
+
42
+ SSE must call the handoff function with **`destination` as a string** (Squad member name), e.g.:
43
+
44
+ ```json
45
+ { "destination": "MyIdentity" }
46
+ ```
47
+
48
+ Not `{ type, assistantName }` objects — that is assistant config, not tool-call args.
49
+
50
+ ## Examples on disk (not loaded by default)
51
+
52
+ Ship example configs in your app repo (e.g. `config/workflow.squad.example.yaml`, `config/vapi-squad.example.json`).
53
+
54
+ Copy to `workflow.yaml` only when deliberately enabling Squad.
55
+
56
+ ## Related
57
+
58
+ - [Runtime API](../reference/runtime-api.md) — workflow / handoff
59
+ - [Example apps](../building-apps/example-apps.md) — single-assistant vs squad patterns
@@ -0,0 +1,85 @@
1
+ # Agents & coding CLIs
2
+
3
+ Guidify AI is built to be **agent-friendly**: one handbook, stamped refs, and always-on rules for Cursor and Claude Code.
4
+
5
+ ## Shared handbook
6
+
7
+ | Resource | Purpose |
8
+ | --- | --- |
9
+ | [`agent/AGENTS.md`](../../agent/AGENTS.md) | Canonical doctrine (tool-agnostic) |
10
+ | [`docs/best-practices/README.md`](../best-practices/README.md) | Which doctrine guide to open |
11
+ | App `AGENTS.md` | Stamped block from package postinstall |
12
+
13
+ Claude Code does **not** auto-read `AGENTS.md`. Keep the handbook under `agent/` (`AGENTS.md` + `CLAUDE.md`); put a one-line root `CLAUDE.md` that `@agent/CLAUDE.md` so Claude Code discovers it (Anthropic’s documented pattern).
14
+
15
+ This framework package does **not** keep always-on rules under `.cursor/` or `.claude/` in-repo. Edit templates under `agent/`; postinstall copies them into **consumer apps**.
16
+
17
+ ## Cursor
18
+
19
+ | Resource | Purpose |
20
+ | --- | --- |
21
+ | `agent/cursor/*.mdc` | Templates copied into app `.cursor/rules/` |
22
+ | App `.cursor/rules/vapi-studio-best-practices.mdc` | Always-on conversation rules |
23
+ | App `.cursor/rules/ui-and-api-identity.mdc` | UUID / label identity |
24
+
25
+ ## Claude Code CLI
26
+
27
+ | Resource | Purpose |
28
+ | --- | --- |
29
+ | Repo [`agent/CLAUDE.md`](../../agent/CLAUDE.md) | Framework Claude notes (`@AGENTS.md`); root `CLAUDE.md` is discovery-only |
30
+ | `agent/claude/rules/*.md` | Templates copied into **app** `.claude/rules/` on postinstall |
31
+ | App `.claude/rules/vapi-studio-best-practices.md` | Always-on conversation rules |
32
+ | App `.claude/rules/ui-and-api-identity.md` | UUID / label identity |
33
+ | App `CLAUDE.md` | Stamped import of package `agent/AGENTS.md` |
34
+
35
+ | Cursor template (`agent/cursor/`) | Claude template (`agent/claude/rules/`) |
36
+ | --- | --- |
37
+ | `vapi-studio-best-practices.mdc` | `vapi-studio-best-practices.md` |
38
+ | `ui-and-api-identity.mdc` | `ui-and-api-identity.md` |
39
+
40
+ See [Node conventions](./node-conventions.md) for agent-step naming and lifecycle order (doctrine in [nodes-and-listens.md](../best-practices/nodes-and-listens.md)).
41
+
42
+ ## Recommended workflow
43
+
44
+ 1. Read app **northern stars** (app repo `README.md`).
45
+ 2. Read `agent/AGENTS.md` / `agent/CLAUDE.md` (app: stamped `AGENTS.md` / `CLAUDE.md`).
46
+ 3. Open matching [best-practice guide](../best-practices/README.md).
47
+ 4. Framework changes → [Runtime API](../reference/runtime-api.md) first.
48
+ 5. Update docs in the **same PR** as behavior.
49
+
50
+ ## Decision tree: which guide?
51
+
52
+ | Changing… | Read |
53
+ | --- | --- |
54
+ | Bot copy / CTA | conversation-design.md |
55
+ | Soft affirmatives / silent handoffs / lane choice | conversation-design.md (+ nodes-and-listens.md) |
56
+ | Mad callers (one re-engage → human) | nodes-and-listens.md · conversation-design.md |
57
+ | New agent step / listen / extract | nodes-and-listens.md |
58
+ | Phone, email, forms | identity-and-pii.md |
59
+ | Studio FE / Nest DTO identity | ui-and-api-identity.md |
60
+ | Analytics funnels / tags | debugging-and-observability.md · events-and-logging.md |
61
+ | Logs / events | debugging-and-observability.md |
62
+ | Limits / public API / env | [Runtime API](../reference/runtime-api.md) |
63
+ | README placement | documentation-layers.md |
64
+
65
+ ## Postinstall
66
+
67
+ ```bash
68
+ INIT_CWD=$PWD node node_modules/@guidify-ai/vapi-studio/scripts/install-agent-refs.cjs
69
+ ```
70
+
71
+ Refreshes **in the consumer app**:
72
+
73
+ - `.cursor/rules/vapi-studio-best-practices.mdc` + `ui-and-api-identity.mdc`
74
+ - `.claude/rules/vapi-studio-best-practices.md` + `ui-and-api-identity.md`
75
+ - stamped blocks in app `AGENTS.md` and `CLAUDE.md`
76
+
77
+ Sources: `agent/cursor/` and `agent/claude/rules/` inside the package. Does not wipe custom sections outside the stamped markers.
78
+
79
+ ## SpecKit
80
+
81
+ Greenfield features: [SpecKit guide](./speckit.md) (`.specify/` in this repo).
82
+
83
+ ## Related
84
+
85
+ - [Documentation layers](./documentation.md)
@@ -0,0 +1,27 @@
1
+ # Optional compose fragment — Redis + a consumer process only.
2
+ # Use the app's existing `postgres` service; create a second database on it
3
+ # instead of a second Postgres container. Wire your own consumer image/env.
4
+ #
5
+ # EVENT_STORE_DATABASE_URL=postgres://studio:studio@postgres:5432/app_events
6
+
7
+ services:
8
+ redis:
9
+ image: redis:7-alpine
10
+ ports:
11
+ - "${STUDIO_EVENTS_REDIS_HOST_PORT:-16379}:6379"
12
+ healthcheck:
13
+ test: ["CMD", "redis-cli", "ping"]
14
+ interval: 5s
15
+ timeout: 3s
16
+ retries: 10
17
+
18
+ event-consumer:
19
+ image: ${STUDIO_EVENT_CONSUMER_IMAGE:-studio-event-consumer:local}
20
+ environment:
21
+ DATABASE_URL: ${EVENT_STORE_DATABASE_URL:-postgres://studio:studio@postgres:5432/app_events}
22
+ STUDIO_EVENTS_REDIS_URL: ${STUDIO_EVENTS_REDIS_URL:-redis://redis:6379}
23
+ STUDIO_EVENTS_REDIS_STREAM: ${STUDIO_EVENTS_REDIS_STREAM:-studio:events}
24
+ depends_on:
25
+ redis:
26
+ condition: service_healthy
27
+ restart: unless-stopped
@@ -0,0 +1,13 @@
1
+ # Documentation map
2
+
3
+ | Layer | Location | Purpose |
4
+ | --- | --- | --- |
5
+ | **Package README** | `README.md` | Install + product framing |
6
+ | **Doc site** | `docs/README.md` | Navigation |
7
+ | **Runtime handbook** | `docs/reference/runtime-api.md` | Shipped contracts |
8
+ | **Best practices** | `docs/best-practices/` | Conversation doctrine |
9
+ | **Building apps** | `docs/building-apps/` | Scaffold apps that depend on the package |
10
+ | **Example apps** | `docs/building-apps/example-apps.md` | Links to external sample repos |
11
+ | **App northern stars** | *your app* `README.md` | Goals, triggers — no flow dumps |
12
+
13
+ See [documentation layers](../best-practices/documentation-layers.md).
@@ -0,0 +1,155 @@
1
+ # Extending Studio events
2
+
3
+ Vapi Studio is **event-driven**. Every meaningful turn can emit structured events
4
+ on an in-process Node bus. The OSS package does **not** lock you into a single
5
+ sink — you attach your own listeners (the same way you attach Postgres).
6
+
7
+ Guidify companion tools (e.g. analytics) subscribe the same way: listen in-process,
8
+ optionally publish to a broker + store. Your app can too.
9
+
10
+ ## Mental model
11
+
12
+ ```text
13
+ Node / Supervisor / Forms / Integrations
14
+ │
15
+ ▼
16
+ EventService.emit / persist / persistAnalyticsTag
17
+ │
18
+ ├── console + daily file logs
19
+ ├── onStudioEvent(...) ← process-wide Node EventEmitter
20
+ └── Nest eventListeners[] ← DI / StudioEventListener
21
+ │
22
+ ▼ (your code)
23
+ Redis Streams / queue / HTTP / warehouse / CRM
24
+ ```
25
+
26
+ **Postgres** = durable conversations. **Event bus** = explainability + side effects.
27
+ Neither is Guidify-hosted — both run on your infra.
28
+
29
+ `EventService.log(...)` is **console/file only** — it does **not** hit `onStudioEvent`.
30
+ Use `persist` / `emit` / `persistAnalyticsTag` for anything listeners must see.
31
+
32
+ ## Two listener styles
33
+
34
+ ### 1. `onStudioEvent` (any process code)
35
+
36
+ ```ts
37
+ // main.ts — register BEFORE app.listen
38
+ import { onStudioEvent, STUDIO_EVENTS } from '@guidify-ai/vapi-studio';
39
+
40
+ onStudioEvent(async (event) => {
41
+ if (event.type === 'ROUTE_DECISION') {
42
+ // why this node ran
43
+ }
44
+ if (event.type === STUDIO_EVENTS.OUTBOUND_NOTIFICATION) {
45
+ // SMS / outbound channel
46
+ }
47
+ if (event.type === 'ANALYTICS_TAG') {
48
+ // funnel milestone — payload.tag
49
+ }
50
+ });
51
+ ```
52
+
53
+ ### 2. Nest `eventListeners`
54
+
55
+ ```ts
56
+ import { Injectable } from '@nestjs/common';
57
+ import {
58
+ VapiStudioModule,
59
+ type StudioEvent,
60
+ type StudioEventListener,
61
+ } from '@guidify-ai/vapi-studio';
62
+
63
+ @Injectable()
64
+ export class AuditEventListener implements StudioEventListener {
65
+ async handle(event: StudioEvent): Promise<void> {
66
+ // DI-friendly: inject repos, queues, …
67
+ }
68
+ }
69
+
70
+ VapiStudioModule.forRoot({
71
+ // …
72
+ eventListeners: [AuditEventListener],
73
+ });
74
+ ```
75
+
76
+ Both styles are first-class.
77
+
78
+ ## Sample: Redis Streams broker (like analytics)
79
+
80
+ Framework does **not** open Redis for you. Your app bridges the bus — same
81
+ optional infra pattern as a second Postgres database for an event store.
82
+
83
+ Compose stub: [`docker-compose.events.stub.yaml`](./docker-compose.events.stub.yaml)
84
+
85
+ ```ts
86
+ // src/events/redis-event-bridge.ts — register from main.ts
87
+ import { onStudioEvent, type StudioEvent } from '@guidify-ai/vapi-studio';
88
+ import Redis from 'ioredis'; // your dependency
89
+
90
+ const url = process.env.STUDIO_EVENTS_REDIS_URL?.trim();
91
+ const stream = process.env.STUDIO_EVENTS_REDIS_STREAM?.trim() || 'studio:events';
92
+
93
+ export function registerRedisEventBridge(): void {
94
+ if (!url) {
95
+ console.warn('[events] STUDIO_EVENTS_REDIS_URL unset — bus stays in-process only');
96
+ return;
97
+ }
98
+ const redis = new Redis(url);
99
+ onStudioEvent(async (event: StudioEvent) => {
100
+ await redis.xadd(
101
+ stream,
102
+ '*',
103
+ 'type', event.type,
104
+ 'ts', event.ts,
105
+ 'conversationId', event.conversationId ?? '',
106
+ 'providerCallId', event.providerCallId ?? '',
107
+ 'payload', JSON.stringify(event.payload ?? {}),
108
+ );
109
+ });
110
+ }
111
+ ```
112
+
113
+ ```ts
114
+ // main.ts
115
+ import { registerRedisEventBridge } from './events/redis-event-bridge';
116
+
117
+ registerRedisEventBridge();
118
+ // … NestFactory.create / listen
119
+ ```
120
+
121
+ A separate **consumer** process (analytics, warehouse loader, …) reads the stream
122
+ and writes Postgres / ClickHouse / whatever you own. Env presets:
123
+
124
+ | Variable | Purpose |
125
+ | --- | --- |
126
+ | `STUDIO_EVENTS_REDIS_URL` | Broker URL (app-owned) |
127
+ | `STUDIO_EVENTS_REDIS_STREAM` | Stream name (default `studio:events`) |
128
+ | `EVENT_STORE_DATABASE_URL` | Optional durable store for the consumer |
129
+
130
+ ## Sample: emit your own domain events
131
+
132
+ ```ts
133
+ // inside a Node
134
+ await ctx.events.persist(ctx.conversationId, 'LEAD_QUALIFIED', {
135
+ companyName: ctx.memory.companyName,
136
+ });
137
+
138
+ // funnel milestone (payload.tag only — never payload.funnels)
139
+ await ctx.events.persistAnalyticsTag(ctx.conversationId, 'quote_requested');
140
+ ```
141
+
142
+ ## What events exist?
143
+
144
+ Canonical catalog: [Events & logging — Event catalog](../reference/events-and-logging.md#event-catalog).
145
+
146
+ Typed constants exported as `STUDIO_EVENTS` (integrations, outbound, tasks). Many
147
+ forensic types are string names (`ROUTE_DECISION`, `FORM_SENDOUT`, …) — filter on
148
+ `event.type`.
149
+
150
+ ## Related
151
+
152
+ - [Events & logging](../reference/events-and-logging.md)
153
+ - [Environment variables](../reference/environment-variables.md) · [`.env.example`](../../.env.example)
154
+ - [Debugging and observability](../best-practices/debugging-and-observability.md)
155
+ - [Data model](../reference/data-model.md)
@@ -0,0 +1,59 @@
1
+ # Node conventions
2
+
3
+ Human-readable summary of agent-step conventions. Doctrine: [nodes-and-listens.md](../best-practices/nodes-and-listens.md).
4
+
5
+ ## Intention naming
6
+
7
+ - **Actions:** `is{VerbPast}…` — `isCollectedFirstName`, `isConfirmedAddressMatch`
8
+ - **Polarity:** `studio.isPositive`, `studio.isNegative`
9
+ - **Framework standard:** `studio.isGoodbye`, `studio.isStillThere`, …
10
+
11
+ ## Node method order
12
+
13
+ Declare in source in **runtime call order**:
14
+
15
+ 1. `before()` — CAN gate **and** async prep (auth warm, JWT spawn, lookups needed to authorize). Prefer non-blocking spawn when speech must not wait; `await` only for the gate.
16
+ 2. `listen()` — register extract / intentions (before speech completes); no I/O
17
+ 3. `run()` — speech + one terminal output only; do not overload with integrations that belong in `before()` / `after()`
18
+ 4. `after()` — teardown / non-speech side effects after the terminal action (no TTS)
19
+ 5. `catch()` — only when overridden
20
+
21
+ Doctrine: [nodes-and-listens.md](../best-practices/nodes-and-listens.md#prefer-before--after-for-async-work).
22
+
23
+ ## Brain (live ChatGPT path)
24
+
25
+ - No Custom LLM listen-hold before scan
26
+ - Scan abort ≤ 3s
27
+ - Target first speech < 1.5s after request
28
+ - Model in `VapiStudioModule.forRoot({ brain })` or `brain.config.ts` — not `.env`
29
+ - `interruptible: false` — queue overlapping POSTs until 3s silence, then one scan
30
+ - End of call: `BRAIN_COST_SUMMARY` when usage tracked
31
+
32
+ ## Listed choices
33
+
34
+ After numbered options, always the same closing question pattern via `listedChoiceQuestion` / `listedChoiceListen` — pick N or neither.
35
+
36
+ Soft affirmatives that do **not** pick N (“yeah, why not”, bare “sure”) are not a choice — re-ask which option with cheap `resolveIntention`; do not send them to Brain/unknown ([conversation-design.md](../best-practices/conversation-design.md#do-not-auto-pick-lanes)).
37
+
38
+ ## Integrations
39
+
40
+ ```typescript
41
+ await ctx.integrations.request({
42
+ name: 'my-api',
43
+ url: 'https://…',
44
+ body: { … },
45
+ secretEnvKey: 'MY_HMAC_SECRET', // env KEY name, not the secret value
46
+ });
47
+ ```
48
+
49
+ JWT HS256 in `x-signature`. Events: `INTEGRATION_REQUEST`, `INTEGRATION_RESPONSE`, `INTEGRATION_ERROR`.
50
+
51
+ ## Shit in, shit out
52
+
53
+ Do not add Node logic for Vapi stale Custom LLM repeats or “caller repeating previous field.” Unknown / re-ask is enough.
54
+
55
+ ## Related
56
+
57
+ - [Standard intentions](../reference/standard-intentions.md)
58
+ - [Nodes and listens (doctrine)](../best-practices/nodes-and-listens.md)
59
+ - [Agents](./agents.md)
@@ -0,0 +1,56 @@
1
+ # SpecKit
2
+
3
+ Workspace tooling for specify → plan → tasks → implement workflows under `specs/`.
4
+
5
+ Config, templates, and scripts live under **`.specify/`** (not under framework-local `.cursor/` — that tree was removed from this package).
6
+
7
+ ## Workflows
8
+
9
+ | Workflow | Use |
10
+ | --- | --- |
11
+ | specify | Create/update feature spec from description |
12
+ | clarify | Targeted clarification questions → spec |
13
+ | plan | Generate plan from spec template |
14
+ | tasks | Generate `tasks.md` from plan |
15
+ | analyze | Cross-artifact consistency check |
16
+ | checklist | Custom checklist from requirements |
17
+ | implement | Execute tasks from `tasks.md` |
18
+ | converge | Find unbuilt work → append tasks |
19
+ | constitution | Update constitution |
20
+ | taskstoissues | Convert tasks to GitHub issues |
21
+
22
+ Invoke via SpecKit / Specify CLI against `.specify/` (see `.specify/workflows/`, `.specify/templates/`). IDE skills (`.cursor/skills/speckit-*`, `.claude/skills/speckit-*`) are **not** shipped in this framework package — SpecKit here is `.specify/` only. Reinstall SpecKit skills into a local checkout if you need IDE skill discovery.
23
+
24
+ ## Artifact layout
25
+
26
+ ```text
27
+ specs/<feature-id>/
28
+ ├── spec.md
29
+ ├── plan.md
30
+ ├── tasks.md
31
+ ├── research.md
32
+ ├── quickstart.md
33
+ ├── data-model.md
34
+ └── contracts/
35
+ ```
36
+
37
+ Templates: `.specify/templates/`
38
+
39
+ ## When to use SpecKit vs best practices
40
+
41
+ | Work | Start here |
42
+ | --- | --- |
43
+ | Day-to-day bot nodes / copy | [Best practices](../best-practices/README.md) + [Agents](./agents.md) |
44
+ | Greenfield framework feature | SpecKit specify → plan → tasks |
45
+ | Compliance check | SpecKit analyze after tasks |
46
+
47
+ ## Historical artifacts
48
+
49
+ Older SpecKit PoC dumps may exist under a local `archive/` folder (gitignored — not in the repo). Prefer current `docs/` and `docs/reference/runtime-api.md`.
50
+
51
+ **Authority:** root `README.md` and `docs/` over SpecKit contracts.
52
+
53
+ ## Related
54
+
55
+ - [Constitution](../reference/principles.md)
56
+ - [Documentation layers](./documentation.md)