@superpanel-sdk/runtime 0.2.2 → 0.5.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 (274) hide show
  1. package/README.md +28 -8
  2. package/dist/builder/codegen/emit.d.ts +29 -11
  3. package/dist/builder/codegen/emit.js +328 -61
  4. package/dist/builder/codegen/generate.d.ts +21 -0
  5. package/dist/builder/codegen/generate.js +152 -20
  6. package/dist/builder/company-import-graph.d.ts +2 -0
  7. package/dist/builder/company-import-graph.js +40 -8
  8. package/dist/builder/company-imports.d.ts +24 -0
  9. package/dist/builder/company-imports.js +114 -0
  10. package/dist/builder/compile/compile-sequence.d.ts +59 -8
  11. package/dist/builder/compile/compile-sequence.js +279 -77
  12. package/dist/builder/compile/function-code.d.ts +12 -2
  13. package/dist/builder/compile/function-code.js +87 -39
  14. package/dist/builder/compile/registry.d.ts +7 -3
  15. package/dist/builder/compile/registry.js +24 -23
  16. package/dist/builder/load.d.ts +70 -10
  17. package/dist/builder/load.js +250 -61
  18. package/dist/builder/paths.d.ts +3 -0
  19. package/dist/builder/paths.js +16 -0
  20. package/dist/builder/schedules.d.ts +23 -0
  21. package/dist/builder/schedules.js +102 -0
  22. package/dist/builder/slot-schema-validation.d.ts +4 -0
  23. package/dist/builder/slot-schema-validation.js +10 -0
  24. package/dist/builder/typecheck.d.ts +8 -0
  25. package/dist/builder/typecheck.js +105 -0
  26. package/dist/builder/types.d.ts +91 -19
  27. package/dist/builder/types.js +2 -1
  28. package/dist/cli/auth/auth.d.ts +37 -0
  29. package/dist/cli/auth/auth.js +211 -0
  30. package/dist/cli/auth/backend-url.d.ts +5 -0
  31. package/dist/cli/auth/backend-url.js +25 -0
  32. package/dist/cli/auth/clipboard.d.ts +9 -0
  33. package/dist/cli/auth/clipboard.js +38 -0
  34. package/dist/cli/auth/http.d.ts +20 -0
  35. package/dist/cli/auth/http.js +27 -0
  36. package/dist/cli/auth/index.d.ts +10 -0
  37. package/dist/cli/auth/index.js +27 -0
  38. package/dist/cli/auth/progress.d.ts +12 -0
  39. package/dist/cli/auth/progress.js +15 -0
  40. package/dist/cli/auth/serve-login.d.ts +8 -0
  41. package/dist/cli/auth/serve-login.js +24 -0
  42. package/dist/cli/compile/index.js +3 -0
  43. package/dist/cli/config.d.ts +10 -0
  44. package/dist/cli/config.js +52 -0
  45. package/dist/cli/index.js +28 -8
  46. package/dist/cli/serve/index.d.ts +73 -3
  47. package/dist/cli/serve/index.js +410 -113
  48. package/dist/cli/type-gen/index.js +9 -8
  49. package/dist/compiler.d.ts +7 -0
  50. package/dist/compiler.js +7 -0
  51. package/dist/compute-host/compute-host.d.ts +15 -23
  52. package/dist/compute-host/compute-host.js +25 -28
  53. package/dist/compute-host/index.d.ts +2 -2
  54. package/dist/compute-host/index.js +1 -1
  55. package/dist/compute-host/source-compute-host.d.ts +11 -9
  56. package/dist/compute-host/source-compute-host.js +50 -31
  57. package/dist/core/case-orchestrator/contact-hours.d.ts +50 -0
  58. package/dist/core/case-orchestrator/contact-hours.js +108 -0
  59. package/dist/core/case-orchestrator/follow-ups.d.ts +31 -0
  60. package/dist/core/case-orchestrator/follow-ups.js +103 -0
  61. package/dist/core/case-orchestrator/index.d.ts +6 -0
  62. package/dist/core/case-orchestrator/index.js +6 -0
  63. package/dist/core/case-orchestrator/render.d.ts +75 -0
  64. package/dist/core/case-orchestrator/render.js +239 -0
  65. package/dist/core/case-orchestrator/time.d.ts +11 -0
  66. package/dist/core/case-orchestrator/time.js +29 -0
  67. package/dist/core/case-orchestrator/tools.d.ts +29 -0
  68. package/dist/core/case-orchestrator/tools.js +31 -0
  69. package/dist/core/case-orchestrator/types.d.ts +753 -0
  70. package/dist/core/case-orchestrator/types.js +46 -0
  71. package/dist/core/case-orchestrator/validate.d.ts +11 -0
  72. package/dist/core/case-orchestrator/validate.js +63 -0
  73. package/dist/core/context/call.d.ts +291 -0
  74. package/dist/core/context/call.js +94 -0
  75. package/dist/core/context/channels.d.ts +60 -0
  76. package/dist/core/context/channels.js +35 -0
  77. package/dist/core/context/contact.d.ts +96 -6
  78. package/dist/core/context/contact.js +48 -2
  79. package/dist/core/context/email-message.d.ts +159 -0
  80. package/dist/core/context/email-message.js +59 -0
  81. package/dist/core/context/email.d.ts +97 -0
  82. package/dist/core/context/email.js +91 -0
  83. package/dist/core/context/exchanges.d.ts +142 -0
  84. package/dist/core/context/exchanges.js +63 -0
  85. package/dist/core/context/instances.d.ts +278 -0
  86. package/dist/core/context/instances.js +123 -0
  87. package/dist/core/context/kv.d.ts +113 -0
  88. package/dist/core/context/kv.js +60 -0
  89. package/dist/core/context/platform-registry.d.ts +509 -4
  90. package/dist/core/context/platform-registry.js +14 -2
  91. package/dist/core/context/platform.d.ts +2 -1
  92. package/dist/core/context/sms.d.ts +147 -0
  93. package/dist/core/context/sms.js +57 -0
  94. package/dist/core/context/types.d.ts +51 -30
  95. package/dist/core/context/types.js +1 -7
  96. package/dist/core/conversation/index.d.ts +31 -0
  97. package/dist/core/conversation/index.js +14 -0
  98. package/dist/core/functions/define/bind.d.ts +25 -0
  99. package/dist/core/functions/define/bind.js +14 -0
  100. package/dist/core/functions/define/case.d.ts +9 -0
  101. package/dist/core/functions/define/case.js +13 -0
  102. package/dist/core/functions/define/events.d.ts +20 -0
  103. package/dist/core/functions/define/events.js +21 -0
  104. package/dist/core/functions/define/no-case.d.ts +4 -0
  105. package/dist/core/functions/define/no-case.js +9 -0
  106. package/dist/core/functions/events.d.ts +247 -0
  107. package/dist/core/functions/events.js +32 -0
  108. package/dist/core/functions/func-ref.d.ts +11 -2
  109. package/dist/core/functions/schedules.d.ts +51 -0
  110. package/dist/core/functions/schedules.js +20 -0
  111. package/dist/core/functions/types.d.ts +62 -51
  112. package/dist/core/functions/types.js +6 -1
  113. package/dist/core/office-hours/index.d.ts +39 -0
  114. package/dist/core/office-hours/index.js +187 -0
  115. package/dist/core/page/define.d.ts +834 -0
  116. package/dist/core/page/define.js +477 -0
  117. package/dist/core/page/ops.d.ts +58 -0
  118. package/dist/core/page/ops.js +220 -0
  119. package/dist/core/page/render.d.ts +253 -0
  120. package/dist/core/page/render.js +840 -0
  121. package/dist/core/page/time-format.d.ts +19 -0
  122. package/dist/core/page/time-format.js +41 -0
  123. package/dist/core/page/timeline.d.ts +40 -0
  124. package/dist/core/page/timeline.js +2 -0
  125. package/dist/core/page/typed.d.ts +642 -0
  126. package/dist/core/page/typed.js +2 -0
  127. package/dist/core/page/workspace.d.ts +33 -0
  128. package/dist/core/page/workspace.js +231 -0
  129. package/dist/core/party/index.d.ts +3 -0
  130. package/dist/core/party/index.js +3 -0
  131. package/dist/core/party/schema.d.ts +137 -0
  132. package/dist/core/party/schema.js +80 -0
  133. package/dist/core/party/types.d.ts +40 -0
  134. package/dist/core/party/types.js +15 -0
  135. package/dist/core/sequence/define.d.ts +57 -0
  136. package/dist/core/sequence/define.js +10 -0
  137. package/dist/core/sequence/index.d.ts +63 -0
  138. package/dist/core/sequence/index.js +231 -0
  139. package/dist/core/slot/binding.d.ts +40 -0
  140. package/dist/core/slot/binding.js +2 -0
  141. package/dist/core/slot/company-metadata.d.ts +113 -0
  142. package/dist/core/slot/company-metadata.js +563 -0
  143. package/dist/core/slot/compile-schema.d.ts +19 -13
  144. package/dist/core/slot/compile-schema.js +51 -248
  145. package/dist/core/slot/contact-timezone.d.ts +110 -0
  146. package/dist/core/slot/contact-timezone.js +186 -0
  147. package/dist/core/slot/field.d.ts +2 -24
  148. package/dist/core/slot/field.js +0 -69
  149. package/dist/core/slot/id-ref.d.ts +17 -2
  150. package/dist/core/slot/id-ref.js +16 -8
  151. package/dist/core/slot/index.d.ts +12 -13
  152. package/dist/core/slot/index.js +11 -12
  153. package/dist/core/slot/naming.d.ts +15 -0
  154. package/dist/core/slot/naming.js +96 -0
  155. package/dist/core/slot/platform-fields.d.ts +119 -0
  156. package/dist/core/slot/platform-fields.js +121 -0
  157. package/dist/core/slot/ref.d.ts +16 -0
  158. package/dist/core/slot/ref.js +14 -0
  159. package/dist/core/slot/row.d.ts +2 -9
  160. package/dist/core/slot/row.js +13 -23
  161. package/dist/core/slot/schema-compat.d.ts +16 -0
  162. package/dist/core/slot/schema-compat.js +112 -0
  163. package/dist/core/slot/schema.d.ts +409 -76
  164. package/dist/core/slot/schema.js +178 -10
  165. package/dist/core/slot/types.d.ts +27 -92
  166. package/dist/core/slot/value.d.ts +26 -3
  167. package/dist/core/slot/value.js +89 -57
  168. package/dist/dev-overlay/protocol.d.ts +41 -8
  169. package/dist/fn-context/build-context.d.ts +3 -1
  170. package/dist/fn-context/build-context.js +20 -10
  171. package/dist/fn-context/fake/empty-api.js +9 -28
  172. package/dist/fn-context/fake/index.d.ts +11 -4
  173. package/dist/fn-context/fake/index.js +27 -2
  174. package/dist/fn-context/fn-params.d.ts +6 -0
  175. package/dist/fn-context/fn-params.js +13 -0
  176. package/dist/fn-context/index.d.ts +5 -5
  177. package/dist/fn-context/index.js +4 -4
  178. package/dist/fn-context/log.js +2 -2
  179. package/dist/fn-context/make-ctx.d.ts +11 -0
  180. package/dist/fn-context/make-ctx.js +18 -8
  181. package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +24 -0
  182. package/dist/fn-context/rpc/case-orchestrator-tools.js +13 -0
  183. package/dist/fn-context/rpc/index.d.ts +3 -1
  184. package/dist/fn-context/rpc/index.js +3 -1
  185. package/dist/fn-context/rpc/integration/index.d.ts +4 -4
  186. package/dist/fn-context/rpc/integration/index.js +1 -1
  187. package/dist/fn-context/rpc/integration/list-surfaces.d.ts +21 -0
  188. package/dist/fn-context/rpc/integration/{list-bindings.js → list-surfaces.js} +4 -4
  189. package/dist/fn-context/rpc/platform.d.ts +2 -2
  190. package/dist/fn-context/rpc/platform.js +1 -1
  191. package/dist/fn-context/rpc/records.d.ts +78 -0
  192. package/dist/fn-context/rpc/records.js +26 -0
  193. package/dist/fn-context/rpc/trpc-client.d.ts +2 -2
  194. package/dist/fn-context/rpc/trpc-client.js +89 -5
  195. package/dist/fn-context/rpc/trpc-init.d.ts +2 -2
  196. package/dist/fn-context/rpc/trpc-router-factory.d.ts +49 -3
  197. package/dist/fn-context/rpc/trpc-router-factory.js +2 -0
  198. package/dist/fn-context/run-scope.d.ts +4 -0
  199. package/dist/fn-context/run-scope.js +9 -0
  200. package/dist/fn-context/types.d.ts +36 -3
  201. package/dist/index.d.ts +37 -46
  202. package/dist/index.js +33 -33
  203. package/dist/logger.d.ts +7 -0
  204. package/dist/logger.js +41 -0
  205. package/dist/platform.d.ts +76 -0
  206. package/dist/platform.js +56 -0
  207. package/dist/voice-service/actions.d.ts +71 -4
  208. package/dist/voice-service/types.d.ts +42 -2
  209. package/dist/worker.d.ts +10 -0
  210. package/dist/worker.js +10 -0
  211. package/package.json +38 -19
  212. package/dist/builder/compile/compile-agenda.d.ts +0 -15
  213. package/dist/builder/compile/compile-agenda.js +0 -59
  214. package/dist/builder/merge.d.ts +0 -4
  215. package/dist/builder/merge.js +0 -19
  216. package/dist/core/context/db.d.ts +0 -69
  217. package/dist/core/context/db.js +0 -44
  218. package/dist/core/context/docusign.d.ts +0 -134
  219. package/dist/core/context/docusign.js +0 -108
  220. package/dist/core/context/filevine.d.ts +0 -323
  221. package/dist/core/context/filevine.js +0 -254
  222. package/dist/core/context/http.d.ts +0 -9
  223. package/dist/core/context/http.js +0 -4
  224. package/dist/core/context/hubspot.d.ts +0 -250
  225. package/dist/core/context/hubspot.js +0 -191
  226. package/dist/core/context/twilio.d.ts +0 -50
  227. package/dist/core/context/twilio.js +0 -42
  228. package/dist/core/functions/define/case-context.d.ts +0 -14
  229. package/dist/core/functions/define/case-context.js +0 -15
  230. package/dist/core/functions/define/compute.d.ts +0 -7
  231. package/dist/core/functions/define/compute.js +0 -17
  232. package/dist/core/functions/define/custom.d.ts +0 -4
  233. package/dist/core/functions/define/custom.js +0 -8
  234. package/dist/core/functions/define/system.d.ts +0 -7
  235. package/dist/core/functions/define/system.js +0 -12
  236. package/dist/core/slot/deps.d.ts +0 -15
  237. package/dist/core/slot/deps.js +0 -88
  238. package/dist/core/slot/derived.d.ts +0 -32
  239. package/dist/core/slot/derived.js +0 -115
  240. package/dist/core/slot/platform-session-fields.d.ts +0 -38
  241. package/dist/core/slot/platform-session-fields.js +0 -48
  242. package/dist/core/slot/sf-schema.d.ts +0 -23
  243. package/dist/core/slot/sf-schema.js +0 -125
  244. package/dist/core/slot/sf-validate.d.ts +0 -14
  245. package/dist/core/slot/sf-validate.js +0 -132
  246. package/dist/core/slot/snapshot.d.ts +0 -18
  247. package/dist/core/slot/snapshot.js +0 -138
  248. package/dist/core/slot/write.d.ts +0 -41
  249. package/dist/core/slot/write.js +0 -319
  250. package/dist/core/stage/builders.d.ts +0 -36
  251. package/dist/core/stage/builders.js +0 -28
  252. package/dist/core/stage/condition.d.ts +0 -17
  253. package/dist/core/stage/condition.js +0 -198
  254. package/dist/core/stage/drive.d.ts +0 -43
  255. package/dist/core/stage/drive.js +0 -77
  256. package/dist/core/stage/finish-when.d.ts +0 -20
  257. package/dist/core/stage/finish-when.js +0 -82
  258. package/dist/core/stage/flatten.d.ts +0 -27
  259. package/dist/core/stage/flatten.js +0 -464
  260. package/dist/core/stage/index.d.ts +0 -11
  261. package/dist/core/stage/index.js +0 -10
  262. package/dist/core/stage/simulate.d.ts +0 -24
  263. package/dist/core/stage/simulate.js +0 -33
  264. package/dist/core/stage/transfer-fields.d.ts +0 -14
  265. package/dist/core/stage/transfer-fields.js +0 -88
  266. package/dist/core/stage/types.d.ts +0 -177
  267. package/dist/core/stage/types.js +0 -2
  268. package/dist/core/stage/validate.d.ts +0 -11
  269. package/dist/core/stage/validate.js +0 -226
  270. package/dist/core/stage/walk.d.ts +0 -34
  271. package/dist/core/stage/walk.js +0 -96
  272. package/dist/fn-context/rpc/integration/list-bindings.d.ts +0 -21
  273. package/dist/fn-context/system-args.d.ts +0 -6
  274. package/dist/fn-context/system-args.js +0 -14
@@ -0,0 +1,231 @@
1
+ export function workspaceText(page, options = {}) {
2
+ const out = [];
3
+ const notes = options.notes ?? [];
4
+ if (notes.length) {
5
+ out.push('<notes>');
6
+ for (const n of notes)
7
+ out.push(element('note', { id: n.id, about: n.about, value: n.text }));
8
+ out.push('</notes>');
9
+ }
10
+ const root = page.root;
11
+ if (root.guide)
12
+ out.push(element('guide', { value: root.guide }));
13
+ out.push(open('page', { title: root.title, description: root.description, fallback: page.fallback ? (page.fallback.stale ? 'stale' : 'empty') : undefined }));
14
+ if (page.fallback) {
15
+ out.push(element('text', {
16
+ key: 'fallback',
17
+ value: page.fallback.stale
18
+ ? 'This page could not be refreshed: its values may be out of date, and nothing on it can be changed now.'
19
+ : 'The case page could not be loaded: nothing is known about the case here, and nothing can be changed now.',
20
+ }));
21
+ }
22
+ const defined = definedCells(page);
23
+ if (defined.size) {
24
+ out.push('<definitions>');
25
+ for (const [kind, cell] of defined)
26
+ out.push(element('definition', { for: kind, ...definitionAttrs(page, cell) }));
27
+ out.push('</definitions>');
28
+ }
29
+ for (const child of root.children)
30
+ walk(page, child, defined, false, out);
31
+ out.push('</page>');
32
+ return out.join('\n');
33
+ }
34
+ const kindOf = (cell) => `${cell.ref.table}.${cell.ref.field}`;
35
+ /** Each `table.field` some field on the page shows expanded, in page order: the page gives its definition once. */
36
+ function definedCells(page) {
37
+ const out = new Map();
38
+ const visit = (node) => {
39
+ if (node.kind === 'cell' && node.expand) {
40
+ const cell = page.cells[node.slotId];
41
+ if (!out.has(kindOf(cell)))
42
+ out.set(kindOf(cell), cell);
43
+ }
44
+ if (node.kind === 'block')
45
+ node.children.forEach(visit);
46
+ };
47
+ page.root.children.forEach(visit);
48
+ return out;
49
+ }
50
+ function walk(page, node, defined, inList, out) {
51
+ switch (node.kind) {
52
+ case 'block': {
53
+ const tag = node.list ? 'list' : 'block';
54
+ out.push(open(tag, { key: inList ? undefined : node.key, title: node.title, description: node.description }));
55
+ for (const child of node.children)
56
+ walk(page, child, defined, node.list, out);
57
+ out.push(`</${tag}>`);
58
+ return;
59
+ }
60
+ case 'cell': {
61
+ const cell = page.cells[node.slotId];
62
+ // A field the AI cannot change needs no definition: no `more` on it (26 §16.2 #5b).
63
+ out.push(element('field', fieldAttrs(page, node, cell, editable(node, cell) && !defined.has(kindOf(cell)), inList)));
64
+ return;
65
+ }
66
+ case 'text':
67
+ // null: the page put nothing here now (a region that does not apply yet, a value it has not got).
68
+ // In a list it has no key of its own, only its place, as a block there (26 §16.2 #10).
69
+ out.push(element('text', { key: inList ? undefined : node.key, value: node.value }));
70
+ return;
71
+ case 'action':
72
+ out.push(...buttonLines(page.actions[node.actionId]));
73
+ }
74
+ }
75
+ const editable = (node, cell) => !node.readOnly && cell.writable;
76
+ /**
77
+ * A field's value (26 §16.2): `key` always (#10; in a list, where it has only its place, none); `readonly`
78
+ * only on one the AI cannot change (#6a); `more` when its definition is not shown, with its type (#6);
79
+ * `state` only when it holds no value (#6a: a value is filled; `[]` too). A ref field (#7) writes the rows
80
+ * it may be set to as `one-of` {name: label}; read-only, who its value is as `value-label`, when the page
81
+ * labelled it.
82
+ */
83
+ function fieldAttrs(page, node, cell, more, inList = false) {
84
+ const value = valueOf(cell, page);
85
+ const open = editable(node, cell);
86
+ const labels = cell.optionLabels ?? {};
87
+ return {
88
+ id: cell.slotId,
89
+ key: inList ? undefined : node.key,
90
+ readonly: !open,
91
+ more,
92
+ type: more ? cell.type : undefined,
93
+ value,
94
+ 'value-label': !open && typeof value === 'string' && value in labels ? labels[value] : undefined,
95
+ 'one-of': open && cell.options ? Object.fromEntries(cell.options.map((name) => [name, labels[name] ?? name])) : undefined,
96
+ state: cell.state === 'filled' ? undefined : cell.state,
97
+ reason: (cell.state === 'asked_unknown' || cell.state === 'declined') && cell.reason ? cell.reason : undefined,
98
+ };
99
+ }
100
+ /** The value as JSON holds it; a value that is a row's id is the row's page name; null when not filled. */
101
+ function valueOf(cell, page) {
102
+ if (cell.state !== 'filled')
103
+ return null;
104
+ if (typeof cell.value === 'string') {
105
+ const name = Object.entries(page.rows).find(([, row]) => row.id === cell.value)?.[0];
106
+ if (name)
107
+ return name;
108
+ }
109
+ return cell.value ?? null;
110
+ }
111
+ /**
112
+ * What a field means and takes (26 §15.3): label, type, allowed values (`one-of`; a ref field's rows are
113
+ * on the field itself, 26 §16.2 #7), and `help` — the schema's description and how to fill it, the
114
+ * page's `$extraction` for its `table.field` replacing the schema's (a ref field's too, #5). How each type
115
+ * is written is the system message's (`PAGE_FORMAT`), once for every field.
116
+ */
117
+ function definitionAttrs(page, cell) {
118
+ const help = [];
119
+ if (cell.description)
120
+ help.push(cell.description);
121
+ const own = page.extractions?.[kindOf(cell)];
122
+ if (own !== undefined) {
123
+ if (own)
124
+ help.push(own);
125
+ }
126
+ else if (cell.extraction)
127
+ help.push(cell.extraction);
128
+ return {
129
+ label: cell.label,
130
+ type: cell.type,
131
+ 'one-of': cell.choices ?? undefined,
132
+ help: help.length ? help.join(' · ') : undefined,
133
+ };
134
+ }
135
+ function buttonLines(action) {
136
+ const attrs = { id: action.id, title: action.name, does: action.description };
137
+ const props = action.input?.properties ?? {};
138
+ if (!Object.keys(props).length)
139
+ return [element('button', attrs)];
140
+ const out = [open('button', attrs)];
141
+ for (const [name, prop] of Object.entries(props))
142
+ argLines(name, prop, action.input.required.includes(name), out);
143
+ out.push('</button>');
144
+ return out;
145
+ }
146
+ /**
147
+ * An argument, its type named as a field's (26 §15.8); a list's items are an `<item>`, an object's
148
+ * properties (a `contact_schedule`'s parts too) `<arg>`s inside it.
149
+ */
150
+ function argLines(name, prop, required, out) {
151
+ const tag = name === null ? 'item' : 'arg';
152
+ const base = { name: name ?? undefined, required };
153
+ if (prop.type === 'array') {
154
+ out.push(open(tag, { ...base, type: 'list', help: prop.description }));
155
+ argLines(null, prop.items, false, out);
156
+ out.push(`</${tag}>`);
157
+ return;
158
+ }
159
+ if (prop.type === 'object') {
160
+ out.push(open(tag, { ...base, type: prop['x-type'] ?? 'object', nullable: Boolean(prop.nullable), help: prop.description }));
161
+ for (const [key, inner] of Object.entries(prop.properties))
162
+ argLines(key, inner, (prop.required ?? []).includes(key), out);
163
+ out.push(`</${tag}>`);
164
+ return;
165
+ }
166
+ // A row choice: each row with its label (26 §16.2 #7), as a ref field's candidates.
167
+ const oneOf = prop.type === 'ref' && prop.labels ? Object.fromEntries(prop.enum.map((name) => [name, prop.labels[name] ?? name])) : prop.enum;
168
+ out.push(element(tag, { ...base, type: prop.type, 'one-of': oneOf, help: prop.description }));
169
+ }
170
+ /** The block at `path` (`''`: the root). */
171
+ export function blockAt(page, path) {
172
+ if (path === '')
173
+ return page.root;
174
+ let found = null;
175
+ const visit = (node) => {
176
+ if (found || node.kind !== 'block')
177
+ return;
178
+ if (node.path === path)
179
+ found = node;
180
+ else if (path.startsWith(`${node.path}.`) || node.path === '')
181
+ node.children.forEach(visit);
182
+ };
183
+ page.root.children.forEach(visit);
184
+ return found;
185
+ }
186
+ /** What `view` shows of one thing on the page (24 §3.2): a field with its definition, a button with its arguments. */
187
+ export function viewText(page, id) {
188
+ const cell = page.cells[id];
189
+ if (cell) {
190
+ const node = findCellNode(page, id);
191
+ if (!node)
192
+ return null;
193
+ const { type: _type, 'one-of': rows, ...own } = fieldAttrs(page, node, cell, false);
194
+ const definition = definitionAttrs(page, cell);
195
+ // The field, then its definition; a ref field's rows are its own (`one-of` on the field).
196
+ return element('field', { ...own, ...definition, 'one-of': rows ?? definition['one-of'] });
197
+ }
198
+ const action = page.actions[id];
199
+ return action ? buttonLines(action).join('\n') : null;
200
+ }
201
+ function findCellNode(page, slotId) {
202
+ let found = null;
203
+ const visit = (node) => {
204
+ if (found)
205
+ return;
206
+ if (node.kind === 'cell' && node.slotId === slotId)
207
+ found = node;
208
+ if (node.kind === 'block')
209
+ node.children.forEach(visit);
210
+ };
211
+ visit(page.root);
212
+ return found;
213
+ }
214
+ // ---------------------------------------------------------------------------------------------
215
+ // Writing elements
216
+ /** `true`: a bare flag; `false` / `undefined`: left out; anything else `name=<JSON>`. `value` always prints, null included. */
217
+ function attrText(attrs) {
218
+ const parts = [];
219
+ for (const [k, v] of Object.entries(attrs)) {
220
+ if (k === 'value')
221
+ parts.push(`value=${JSON.stringify(v ?? null)}`);
222
+ else if (v === true)
223
+ parts.push(k);
224
+ else if (v !== undefined && v !== false)
225
+ parts.push(`${k}=${JSON.stringify(v)}`);
226
+ }
227
+ return parts.length ? ` ${parts.join(' ')}` : '';
228
+ }
229
+ const open = (tag, attrs) => `<${tag}${attrText(attrs)}>`;
230
+ const element = (tag, attrs) => `<${tag}${attrText(attrs)}/>`;
231
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1,3 @@
1
+ export * from './schema.js';
2
+ export * from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ export * from './schema.js';
2
+ export * from './types.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,137 @@
1
+ import { z } from 'zod';
2
+ /** How a contact is reached: a phone number or an email address. */
3
+ export declare const partyAddress: z.ZodObject<{
4
+ kind: z.ZodEnum<{
5
+ email: "email";
6
+ phone: "phone";
7
+ }>;
8
+ value: z.ZodString;
9
+ }, z.core.$strip>;
10
+ export type PartyAddress = z.infer<typeof partyAddress>;
11
+ /**
12
+ * The other side as a conversation arrives: a phone number or an email address, or the SIP URI of a
13
+ * SIP caller whose URI is not a phone number (`sip:alice@pbx.example.com`): no contact field holds it,
14
+ * so `resolve` finds the contact by what the call carries (`sip.headers`).
15
+ */
16
+ export declare const arrivalAddress: z.ZodObject<{
17
+ kind: z.ZodEnum<{
18
+ email: "email";
19
+ phone: "phone";
20
+ sip: "sip";
21
+ }>;
22
+ value: z.ZodString;
23
+ }, z.core.$strip>;
24
+ export type ArrivalAddress = z.infer<typeof arrivalAddress>;
25
+ /**
26
+ * A call that came through our SIP Domain: its URIs as they came, the domain, and the headers the far
27
+ * end sent (`X-…` ones and `User-to-User`, by name: `X-Case-Id`). A system that puts the call through
28
+ * to us says in them what it is about.
29
+ */
30
+ export declare const sipArrival: z.ZodObject<{
31
+ fromUri: z.ZodNullable<z.ZodString>;
32
+ toUri: z.ZodNullable<z.ZodString>;
33
+ domain: z.ZodNullable<z.ZodString>;
34
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
35
+ }, z.core.$strip>;
36
+ export type SipArrival = z.infer<typeof sipArrival>;
37
+ /**
38
+ * `ctx.params` of the company `resolve` (§18.2): an inbound conversation, before its sequence is known.
39
+ * `to.name` is our number's or mailbox's name in the environment (22 §7), the same in test and prod.
40
+ */
41
+ export declare const companyResolveInput: z.ZodObject<{
42
+ channel: z.ZodEnum<{
43
+ call: "call";
44
+ email: "email";
45
+ sms: "sms";
46
+ }>;
47
+ from: z.ZodObject<{
48
+ kind: z.ZodEnum<{
49
+ email: "email";
50
+ phone: "phone";
51
+ sip: "sip";
52
+ }>;
53
+ value: z.ZodString;
54
+ }, z.core.$strip>;
55
+ threadId: z.ZodNullable<z.ZodString>;
56
+ sip: z.ZodOptional<z.ZodObject<{
57
+ fromUri: z.ZodNullable<z.ZodString>;
58
+ toUri: z.ZodNullable<z.ZodString>;
59
+ domain: z.ZodNullable<z.ZodString>;
60
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
61
+ }, z.core.$strip>>;
62
+ to: z.ZodObject<{
63
+ kind: z.ZodEnum<{
64
+ email: "email";
65
+ phone: "phone";
66
+ }>;
67
+ value: z.ZodString;
68
+ name: z.ZodNullable<z.ZodString>;
69
+ }, z.core.$strip>;
70
+ }, z.core.$strip>;
71
+ export type CompanyResolveInput = z.infer<typeof companyResolveInput>;
72
+ /**
73
+ * What the company `resolve` returns: the sequence (its name) the conversation goes to, or `decline`
74
+ * (we do not take it; §18.5): a call is transferred to the environment's fallback number, a text or
75
+ * an email gets `reply` when given.
76
+ */
77
+ export declare const companyResolveResult: z.ZodUnion<readonly [z.ZodObject<{
78
+ sequence: z.ZodString;
79
+ }, z.core.$strict>, z.ZodObject<{
80
+ decline: z.ZodObject<{
81
+ reply: z.ZodOptional<z.ZodString>;
82
+ }, z.core.$strict>;
83
+ }, z.core.$strict>]>;
84
+ export type CompanyResolveResult = z.infer<typeof companyResolveResult>;
85
+ /** `ctx.params` of a sequence's `resolve` (§18.3): the conversation, on this sequence. */
86
+ export declare const resolveInput: z.ZodObject<{
87
+ channel: z.ZodEnum<{
88
+ call: "call";
89
+ email: "email";
90
+ sms: "sms";
91
+ }>;
92
+ from: z.ZodObject<{
93
+ kind: z.ZodEnum<{
94
+ email: "email";
95
+ phone: "phone";
96
+ sip: "sip";
97
+ }>;
98
+ value: z.ZodString;
99
+ }, z.core.$strip>;
100
+ to: z.ZodObject<{
101
+ kind: z.ZodEnum<{
102
+ email: "email";
103
+ phone: "phone";
104
+ }>;
105
+ value: z.ZodString;
106
+ }, z.core.$strip>;
107
+ threadId: z.ZodNullable<z.ZodString>;
108
+ sip: z.ZodOptional<z.ZodObject<{
109
+ fromUri: z.ZodNullable<z.ZodString>;
110
+ toUri: z.ZodNullable<z.ZodString>;
111
+ domain: z.ZodNullable<z.ZodString>;
112
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
113
+ }, z.core.$strip>>;
114
+ direction: z.ZodEnum<{
115
+ inbound: "inbound";
116
+ outbound: "outbound";
117
+ }>;
118
+ sequence: z.ZodString;
119
+ }, z.core.$strip>;
120
+ export type ResolveInput = z.infer<typeof resolveInput>;
121
+ /**
122
+ * What a sequence's `resolve` returns: the contact the conversation is with, and either an active
123
+ * instance of this sequence to join or a new one of this sequence to start (on a row of its subject
124
+ * table; when another start won the race for the same row, the conversation joins that one).
125
+ */
126
+ export declare const resolveResult: z.ZodUnion<readonly [z.ZodObject<{
127
+ contactId: z.ZodString;
128
+ instanceId: z.ZodString;
129
+ }, z.core.$strict>, z.ZodObject<{
130
+ contactId: z.ZodString;
131
+ start: z.ZodObject<{
132
+ subjectRecordId: z.ZodString;
133
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
134
+ }, z.core.$strict>;
135
+ }, z.core.$strict>]>;
136
+ export type ResolveResult = z.infer<typeof resolveResult>;
137
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1,80 @@
1
+ import { z } from 'zod';
2
+ /** How a contact is reached: a phone number or an email address. */
3
+ export const partyAddress = z.object({
4
+ kind: z.enum(['phone', 'email']),
5
+ value: z.string().min(1),
6
+ });
7
+ /**
8
+ * The other side as a conversation arrives: a phone number or an email address, or the SIP URI of a
9
+ * SIP caller whose URI is not a phone number (`sip:alice@pbx.example.com`): no contact field holds it,
10
+ * so `resolve` finds the contact by what the call carries (`sip.headers`).
11
+ */
12
+ export const arrivalAddress = z.object({
13
+ kind: z.enum(['phone', 'email', 'sip']),
14
+ value: z.string().min(1),
15
+ });
16
+ /**
17
+ * A call that came through our SIP Domain: its URIs as they came, the domain, and the headers the far
18
+ * end sent (`X-…` ones and `User-to-User`, by name: `X-Case-Id`). A system that puts the call through
19
+ * to us says in them what it is about.
20
+ */
21
+ export const sipArrival = z.object({
22
+ fromUri: z.string().nullable(),
23
+ toUri: z.string().nullable(),
24
+ domain: z.string().nullable(),
25
+ headers: z.record(z.string(), z.string()),
26
+ });
27
+ /**
28
+ * What both resolves get (14-sequence-instance §18): the conversation as it arrives, no facts looked
29
+ * up. They look up what they need (`ctx.api.contact.find`, `ctx.api.instances.findForContact`,
30
+ * `ctx.api.exchanges`).
31
+ */
32
+ const conversationArrival = z.object({
33
+ channel: z.enum(['call', 'sms', 'email']),
34
+ /** The other side: the caller or sender on inbound, the one called on outbound. Normalized. */
35
+ from: arrivalAddress,
36
+ /** Our side: the number or mailbox the conversation came in on (inbound) or goes out from. */
37
+ to: partyAddress,
38
+ /** Email: the provider thread id, when the message belongs to one. */
39
+ threadId: z.string().nullable(),
40
+ /** A call through our SIP Domain; absent on any other conversation. */
41
+ sip: sipArrival.optional(),
42
+ });
43
+ /**
44
+ * `ctx.params` of the company `resolve` (§18.2): an inbound conversation, before its sequence is known.
45
+ * `to.name` is our number's or mailbox's name in the environment (22 §7), the same in test and prod.
46
+ */
47
+ export const companyResolveInput = conversationArrival.extend({
48
+ to: partyAddress.extend({ name: z.string().nullable() }),
49
+ });
50
+ /**
51
+ * What the company `resolve` returns: the sequence (its name) the conversation goes to, or `decline`
52
+ * (we do not take it; §18.5): a call is transferred to the environment's fallback number, a text or
53
+ * an email gets `reply` when given.
54
+ */
55
+ export const companyResolveResult = z.union([
56
+ z.strictObject({ sequence: z.string().min(1) }),
57
+ z.strictObject({ decline: z.strictObject({ reply: z.string().min(1).optional() }) }),
58
+ ]);
59
+ /** `ctx.params` of a sequence's `resolve` (§18.3): the conversation, on this sequence. */
60
+ export const resolveInput = conversationArrival.extend({
61
+ direction: z.enum(['inbound', 'outbound']),
62
+ /** This sequence (its name): the only one whose instances `resolve` may return or start. */
63
+ sequence: z.string(),
64
+ });
65
+ /**
66
+ * What a sequence's `resolve` returns: the contact the conversation is with, and either an active
67
+ * instance of this sequence to join or a new one of this sequence to start (on a row of its subject
68
+ * table; when another start won the race for the same row, the conversation joins that one).
69
+ */
70
+ export const resolveResult = z.union([
71
+ z.strictObject({ contactId: z.string().min(1), instanceId: z.string().min(1) }),
72
+ z.strictObject({
73
+ contactId: z.string().min(1),
74
+ start: z.strictObject({
75
+ subjectRecordId: z.string().min(1),
76
+ variables: z.record(z.string(), z.unknown()).optional(),
77
+ }),
78
+ }),
79
+ ]);
80
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1,40 @@
1
+ import type { FunctionCtx, NoCaseFn } from '../functions/types.js';
2
+ import type { PageTablesDesc } from '../page/typed.js';
3
+ import type { CompanyResolveInput, CompanyResolveResult, ResolveInput, ResolveResult } from './schema.js';
4
+ /**
5
+ * Who an inbound conversation goes to is decided in two steps (14-sequence-instance §18): the company
6
+ * repo's root `resolve.ts` picks the sequence, then that sequence's `sequences/<id>/resolve.ts` picks
7
+ * the instance of it (an active one, or a new one). Both export `resolve`.
8
+ */
9
+ export declare const RESOLVE_MODULE = "resolve";
10
+ /** Reserved export of `resolve.ts` and its name in the build's `functions`. */
11
+ export declare const RESOLVE_FUNCTION = "resolve";
12
+ /** `ctx.meta.entry` / RunScope entry of a `resolve` call. */
13
+ export declare const RESOLVE_ENTRY = "resolve";
14
+ /** The company `resolve.ts` compiled into every sequence's build, under this reserved name (§18.2). */
15
+ export declare const COMPANY_RESOLVE_FUNCTION = "companyResolve";
16
+ /** `ctx.meta.entry` / RunScope entry of a company `resolve` call. */
17
+ export declare const COMPANY_RESOLVE_ENTRY = "companyResolve";
18
+ /**
19
+ * The company `resolve.ts` (§18.2): `export const resolve: CompanyResolve = async (ctx) => …`. Runs for
20
+ * inbound calls, texts and emails only, before the sequence is known: returns `{ sequence }` (a name)
21
+ * or `{ decline: { reply? } }`. It reads with `ctx.api` like any function; the repository root's
22
+ * `__gen/` binds `D` to the company's tables, so `ctx.api.db` is typed.
23
+ */
24
+ export type CompanyResolve<D extends PageTablesDesc | undefined = undefined> = NoCaseFn<CompanyResolveInput, CompanyResolveResult, D>;
25
+ /**
26
+ * `ctx` of a sequence's `resolve`: the usual function ctx (it finds and creates through
27
+ * `ctx.api.contact`, reads and writes records through `ctx.api.db`, finds instances through
28
+ * `ctx.api.instances` and exchanges through `ctx.api.exchanges`) with the conversation as `params`.
29
+ * `meta.instanceId` is null.
30
+ */
31
+ export type ResolveContext<D extends PageTablesDesc | undefined = undefined> = FunctionCtx<ResolveInput, D>;
32
+ /**
33
+ * `sequences/<id>/resolve.ts`: `export const resolve: Resolve = async (ctx) => …`, with `Resolve`
34
+ * imported from the sequence's `__gen`. A `noCase` function: the conversation in, `{ contactId,
35
+ * instanceId }` or `{ contactId, start }` out, on this sequence only. The platform gives it what is
36
+ * left of the time limit, checks the ids (an active instance of this sequence, a contact, a row of
37
+ * its subject table, all of this company and environment), and fails the conversation when not.
38
+ */
39
+ export type Resolve<D extends PageTablesDesc | undefined = undefined> = NoCaseFn<ResolveInput, ResolveResult, D>;
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Who an inbound conversation goes to is decided in two steps (14-sequence-instance §18): the company
3
+ * repo's root `resolve.ts` picks the sequence, then that sequence's `sequences/<id>/resolve.ts` picks
4
+ * the instance of it (an active one, or a new one). Both export `resolve`.
5
+ */
6
+ export const RESOLVE_MODULE = 'resolve';
7
+ /** Reserved export of `resolve.ts` and its name in the build's `functions`. */
8
+ export const RESOLVE_FUNCTION = 'resolve';
9
+ /** `ctx.meta.entry` / RunScope entry of a `resolve` call. */
10
+ export const RESOLVE_ENTRY = 'resolve';
11
+ /** The company `resolve.ts` compiled into every sequence's build, under this reserved name (§18.2). */
12
+ export const COMPANY_RESOLVE_FUNCTION = 'companyResolve';
13
+ /** `ctx.meta.entry` / RunScope entry of a company `resolve` call. */
14
+ export const COMPANY_RESOLVE_ENTRY = 'companyResolve';
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * What a sequence's `index.ts` and `variables.ts` declare with (14-sequence-instance §4.4–§4.5). Part of
3
+ * the company API (`src/index.ts`), so it imports nothing: the checks live in `./index.ts`.
4
+ */
5
+ /** `sequences/<id>/index.ts` default export. */
6
+ export type SequenceDefinition<S extends string = string> = {
7
+ meta?: {
8
+ name?: string;
9
+ label?: string;
10
+ description?: string;
11
+ };
12
+ /** The company table each run is about: one row of it is the instance's business root. */
13
+ subject: S;
14
+ };
15
+ export declare function defineSequence<const S extends string>(definition: SequenceDefinition<S>): SequenceDefinition<S>;
16
+ /** A JSON variable's marker; the type argument is only an editor hint (the platform checks it serializes). */
17
+ export type JsonVariableType<T = unknown> = {
18
+ readonly kind: 'json';
19
+ readonly __type?: T;
20
+ };
21
+ export declare function json<T = unknown>(): JsonVariableType<T>;
22
+ /** One run variable as declared. */
23
+ export type VariableDecl = {
24
+ options: readonly (string | number | boolean)[];
25
+ default?: string | number | boolean | null;
26
+ } | {
27
+ type: 'string';
28
+ default?: string | null;
29
+ } | {
30
+ type: 'number';
31
+ default?: number | null;
32
+ } | {
33
+ type: 'boolean';
34
+ default?: boolean | null;
35
+ } | {
36
+ type: JsonVariableType;
37
+ default?: unknown;
38
+ };
39
+ export type VariableDecls = Record<string, VariableDecl>;
40
+ export declare function defineVariables<const V extends VariableDecls>(variables: V): V;
41
+ type VariableValue<D> = D extends {
42
+ options: readonly (infer O)[];
43
+ } ? O : D extends {
44
+ type: 'string';
45
+ } ? string : D extends {
46
+ type: 'number';
47
+ } ? number : D extends {
48
+ type: 'boolean';
49
+ } ? boolean : D extends {
50
+ type: JsonVariableType<infer T>;
51
+ } ? T : never;
52
+ /** The values of a `defineVariables` declaration, by name (null when unset and without a default). */
53
+ export type VariablesOf<V> = {
54
+ [K in keyof V]: VariableValue<V[K]> | null;
55
+ };
56
+ export {};
57
+ //# sourceMappingURL=define.d.ts.map
@@ -0,0 +1,10 @@
1
+ export function defineSequence(definition) {
2
+ return definition;
3
+ }
4
+ export function json() {
5
+ return { kind: 'json' };
6
+ }
7
+ export function defineVariables(variables) {
8
+ return variables;
9
+ }
10
+ //# sourceMappingURL=define.js.map
@@ -0,0 +1,63 @@
1
+ export { defineSequence, defineVariables, json, type JsonVariableType, type SequenceDefinition, type VariableDecl, type VariableDecls, type VariablesOf, } from './define.js';
2
+ /** One experiment: an enum variable and the share each of its values gets when a run does not set it. */
3
+ export type ExperimentDecl = {
4
+ variable: string;
5
+ split: Record<string, number>;
6
+ };
7
+ /** `SequenceBuild.variables`: every declared variable, normalized. */
8
+ export type CompiledVariable = {
9
+ type: 'enum';
10
+ options: Array<string | number | boolean>;
11
+ default: string | number | boolean | null;
12
+ } | {
13
+ type: 'string';
14
+ default: string | null;
15
+ } | {
16
+ type: 'number';
17
+ default: number | null;
18
+ } | {
19
+ type: 'boolean';
20
+ default: boolean | null;
21
+ } | {
22
+ type: 'json';
23
+ default: unknown;
24
+ };
25
+ export type CompiledVariables = Record<string, CompiledVariable>;
26
+ export type CompiledExperiments = Record<string, ExperimentDecl>;
27
+ /**
28
+ * Run variable names the platform reserves (14 §4.4). It reads `voice` when it opens a session;
29
+ * `responsePolicy` and `slotFillingPolicy` are reserved and not read yet. A sequence may leave them
30
+ * out (the platform default) or declare them as enums whose values the platform knows.
31
+ */
32
+ export declare const SYSTEM_VARIABLES: readonly ['responsePolicy', 'slotFillingPolicy', 'voice'];
33
+ export type SystemVariableName = (typeof SYSTEM_VARIABLES)[number];
34
+ export declare function isSystemVariable(name: string): name is SystemVariableName;
35
+ export type CompileVariablesResult = {
36
+ variables: CompiledVariables;
37
+ experiments: CompiledExperiments;
38
+ issues: string[];
39
+ };
40
+ /** Normalize and check a sequence's `variables.ts` (14 §4.4). */
41
+ export declare function compileVariables(declared: unknown, experiments: unknown): CompileVariablesResult;
42
+ /** Why `value` cannot be stored in the variable; null when it can. `null` always can (unset). */
43
+ export declare function variableValueIssue(name: string, variable: CompiledVariable | undefined, value: unknown): string | null;
44
+ /** Issues of a whole write of variables (unknown names, wrong types); empty when it may be stored. */
45
+ export declare function variablesWriteIssues(variables: CompiledVariables, values: Record<string, unknown>): string[];
46
+ /**
47
+ * The variables a new run starts with: every declared default, then the values given, then each
48
+ * experiment whose variable was not given assigns a value by `hash(instanceId + experiment)`, so the
49
+ * same instance always lands in the same group (14 §4.4). Returns the assigned groups too.
50
+ */
51
+ export declare function startVariables(instanceId: string, declared: CompiledVariables, experiments: CompiledExperiments, given: Record<string, unknown>): {
52
+ variables: Record<string, unknown>;
53
+ experiments: Record<string, string>;
54
+ };
55
+ /**
56
+ * The current value of each variable as a run reads it (14 §4.4 "sequence 版本变化"): a stored value
57
+ * the declaration no longer allows (a removed variable or option) falls back to the default.
58
+ * `onStale` hears each fallback. Stored values are not changed.
59
+ */
60
+ export declare function readVariables(declared: CompiledVariables, stored: Record<string, unknown>, onStale?: (name: string, value: unknown) => void): Record<string, unknown>;
61
+ /** Bytes of `variables` serialized: what {@link LIMITS.variablesBytes} bounds. */
62
+ export declare function variablesSize(variables: Record<string, unknown>): number;
63
+ //# sourceMappingURL=index.d.ts.map