@superpanel-sdk/runtime 0.5.0 → 0.7.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 (189) hide show
  1. package/README.md +3 -3
  2. package/dist/builder/codegen/emit.d.ts +5 -10
  3. package/dist/builder/codegen/emit.js +100 -106
  4. package/dist/builder/codegen/generate.d.ts +3 -5
  5. package/dist/builder/codegen/generate.js +13 -32
  6. package/dist/builder/company-imports.d.ts +5 -0
  7. package/dist/builder/company-imports.js +9 -1
  8. package/dist/builder/compile/compile-sequence.d.ts +13 -11
  9. package/dist/builder/compile/compile-sequence.js +135 -83
  10. package/dist/builder/compile/function-code.d.ts +15 -9
  11. package/dist/builder/compile/function-code.js +59 -29
  12. package/dist/builder/compile/registry.d.ts +4 -4
  13. package/dist/builder/compile/registry.js +14 -12
  14. package/dist/builder/errors.d.ts +9 -0
  15. package/dist/builder/errors.js +17 -0
  16. package/dist/builder/function-params.d.ts +10 -0
  17. package/dist/builder/function-params.js +203 -0
  18. package/dist/builder/load.d.ts +17 -17
  19. package/dist/builder/load.js +27 -25
  20. package/dist/builder/paths.d.ts +6 -1
  21. package/dist/builder/paths.js +16 -2
  22. package/dist/builder/schedules.d.ts +9 -7
  23. package/dist/builder/schedules.js +20 -21
  24. package/dist/builder/typecheck.d.ts +1 -1
  25. package/dist/builder/typecheck.js +3 -6
  26. package/dist/builder/types.d.ts +41 -5
  27. package/dist/builder/types.js +19 -0
  28. package/dist/cli/calls/index.d.ts +177 -0
  29. package/dist/cli/calls/index.js +96 -0
  30. package/dist/cli/debug/index.d.ts +31 -0
  31. package/dist/cli/debug/index.js +119 -0
  32. package/dist/cli/exec/index.d.ts +39 -0
  33. package/dist/cli/exec/index.js +138 -0
  34. package/dist/cli/exec/session.d.ts +48 -0
  35. package/dist/cli/exec/session.js +82 -0
  36. package/dist/cli/exec/trace.d.ts +18 -0
  37. package/dist/cli/exec/trace.js +52 -0
  38. package/dist/cli/index.js +84 -1
  39. package/dist/cli/logs/index.d.ts +47 -0
  40. package/dist/cli/logs/index.js +113 -0
  41. package/dist/cli/mobile/index.d.ts +12 -0
  42. package/dist/cli/mobile/index.js +405 -0
  43. package/dist/cli/serve/index.d.ts +40 -4
  44. package/dist/cli/serve/index.js +167 -28
  45. package/dist/cli/turns/index.d.ts +105 -0
  46. package/dist/cli/turns/index.js +128 -0
  47. package/dist/cli/turns/run.d.ts +13 -0
  48. package/dist/cli/turns/run.js +57 -0
  49. package/dist/cli/turns/shadow.d.ts +112 -0
  50. package/dist/cli/turns/shadow.js +54 -0
  51. package/dist/cli/type-gen/index.js +0 -1
  52. package/dist/compute-host/compute-host.d.ts +5 -6
  53. package/dist/compute-host/compute-host.js +4 -13
  54. package/dist/compute-host/source-compute-host.d.ts +5 -7
  55. package/dist/compute-host/source-compute-host.js +12 -33
  56. package/dist/core/case-orchestrator/contact-hours.d.ts +26 -6
  57. package/dist/core/case-orchestrator/contact-hours.js +27 -8
  58. package/dist/core/case-orchestrator/index.d.ts +1 -4
  59. package/dist/core/case-orchestrator/index.js +1 -4
  60. package/dist/core/case-orchestrator/render.d.ts +1 -1
  61. package/dist/core/case-orchestrator/render.js +15 -10
  62. package/dist/core/case-orchestrator/types.d.ts +83 -128
  63. package/dist/core/case-orchestrator/types.js +0 -4
  64. package/dist/core/context/email-message.d.ts +40 -1
  65. package/dist/core/context/email-message.js +27 -0
  66. package/dist/core/context/email.d.ts +13 -1
  67. package/dist/core/context/email.js +2 -3
  68. package/dist/core/context/exchanges.d.ts +25 -0
  69. package/dist/core/context/exchanges.js +25 -7
  70. package/dist/core/context/instances.d.ts +31 -2
  71. package/dist/core/context/instances.js +18 -4
  72. package/dist/core/context/platform-registry.d.ts +35 -0
  73. package/dist/core/context/sms.d.ts +30 -0
  74. package/dist/core/context/sms.js +20 -0
  75. package/dist/core/context/types.d.ts +29 -1
  76. package/dist/core/conversation/index.d.ts +58 -4
  77. package/dist/core/conversation/index.js +123 -4
  78. package/dist/core/functions/errors.d.ts +74 -0
  79. package/dist/core/functions/errors.js +26 -0
  80. package/dist/core/functions/events.d.ts +23 -78
  81. package/dist/core/functions/events.js +8 -17
  82. package/dist/core/functions/schedules.d.ts +9 -10
  83. package/dist/core/functions/schedules.js +2 -2
  84. package/dist/core/functions/types.d.ts +17 -72
  85. package/dist/core/functions/types.js +1 -9
  86. package/dist/core/page/define.d.ts +230 -160
  87. package/dist/core/page/define.js +145 -104
  88. package/dist/core/page/envelope.d.ts +55 -0
  89. package/dist/core/page/envelope.js +4 -0
  90. package/dist/core/page/fns.d.ts +448 -0
  91. package/dist/core/page/fns.js +539 -0
  92. package/dist/core/page/memory-reader.d.ts +27 -0
  93. package/dist/core/page/memory-reader.js +299 -0
  94. package/dist/core/page/page-host.d.ts +20 -0
  95. package/dist/core/page/page-host.js +57 -0
  96. package/dist/core/page/records-query.d.ts +234 -0
  97. package/dist/core/page/records-query.js +780 -0
  98. package/dist/core/page/render.d.ts +67 -25
  99. package/dist/core/page/render.js +492 -272
  100. package/dist/core/page/sandbox.d.ts +85 -0
  101. package/dist/core/page/sandbox.js +357 -0
  102. package/dist/core/page/time-format.d.ts +27 -0
  103. package/dist/core/page/time-format.js +84 -0
  104. package/dist/core/page/typed.d.ts +165 -159
  105. package/dist/core/page/workspace.d.ts +25 -1
  106. package/dist/core/page/workspace.js +48 -13
  107. package/dist/core/party/schema.d.ts +74 -3
  108. package/dist/core/party/schema.js +39 -6
  109. package/dist/core/party/types.d.ts +8 -13
  110. package/dist/core/sequence/define.d.ts +1 -2
  111. package/dist/core/slot/company-metadata.d.ts +11 -22
  112. package/dist/core/slot/company-metadata.js +12 -39
  113. package/dist/core/slot/compile-schema.js +6 -6
  114. package/dist/core/slot/field.d.ts +1 -2
  115. package/dist/core/slot/field.js +0 -2
  116. package/dist/core/slot/index.d.ts +3 -3
  117. package/dist/core/slot/index.js +3 -3
  118. package/dist/core/slot/naming.d.ts +1 -1
  119. package/dist/core/slot/naming.js +1 -1
  120. package/dist/core/slot/platform-fields.d.ts +4 -4
  121. package/dist/core/slot/platform-fields.js +5 -5
  122. package/dist/core/slot/schema-compat.d.ts +8 -7
  123. package/dist/core/slot/schema-compat.js +22 -31
  124. package/dist/core/slot/schema.d.ts +3 -59
  125. package/dist/core/slot/schema.js +0 -15
  126. package/dist/core/slot/types.d.ts +4 -10
  127. package/dist/core/slot/value.d.ts +2 -0
  128. package/dist/core/slot/value.js +6 -2
  129. package/dist/dev-overlay/protocol.d.ts +38 -5
  130. package/dist/fn-context/build-context.js +10 -4
  131. package/dist/fn-context/fake/index.d.ts +2 -0
  132. package/dist/fn-context/fake/index.js +5 -3
  133. package/dist/fn-context/fn-params.d.ts +2 -5
  134. package/dist/fn-context/fn-params.js +6 -9
  135. package/dist/fn-context/index.d.ts +1 -1
  136. package/dist/fn-context/make-ctx.js +5 -4
  137. package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +11 -3
  138. package/dist/fn-context/rpc/case-orchestrator-tools.js +0 -1
  139. package/dist/fn-context/rpc/errors.d.ts +13 -0
  140. package/dist/fn-context/rpc/errors.js +22 -0
  141. package/dist/fn-context/rpc/index.d.ts +1 -1
  142. package/dist/fn-context/rpc/index.js +1 -1
  143. package/dist/fn-context/rpc/integration/index.d.ts +11 -1
  144. package/dist/fn-context/rpc/log.d.ts +11 -1
  145. package/dist/fn-context/rpc/platform.d.ts +11 -1
  146. package/dist/fn-context/rpc/records.d.ts +13 -6
  147. package/dist/fn-context/rpc/records.js +2 -4
  148. package/dist/fn-context/rpc/trpc-client.d.ts +42 -0
  149. package/dist/fn-context/rpc/trpc-client.js +151 -22
  150. package/dist/fn-context/rpc/trpc-init.d.ts +19 -1
  151. package/dist/fn-context/rpc/trpc-init.js +10 -4
  152. package/dist/fn-context/rpc/trpc-router-factory.d.ts +66 -8
  153. package/dist/fn-context/run-scope.js +1 -1
  154. package/dist/fn-context/types.d.ts +20 -6
  155. package/dist/index.d.ts +11 -12
  156. package/dist/index.js +5 -8
  157. package/dist/logger.d.ts +4 -0
  158. package/dist/logger.js +8 -0
  159. package/dist/platform.d.ts +32 -33
  160. package/dist/platform.js +23 -22
  161. package/dist/testing-compile-child.d.ts +2 -0
  162. package/dist/testing-compile-child.js +20 -0
  163. package/dist/testing.d.ts +368 -0
  164. package/dist/testing.js +439 -0
  165. package/dist/voice-service/actions.d.ts +12 -35
  166. package/dist/voice-service/index.d.ts +2 -0
  167. package/dist/voice-service/index.js +2 -0
  168. package/dist/voice-service/protocol.d.ts +604 -0
  169. package/dist/voice-service/protocol.js +67 -0
  170. package/dist/voice-service/types.d.ts +16 -6
  171. package/dist/worker.d.ts +2 -1
  172. package/dist/worker.js +2 -1
  173. package/package.json +20 -16
  174. package/dist/core/case-orchestrator/follow-ups.d.ts +0 -31
  175. package/dist/core/case-orchestrator/follow-ups.js +0 -103
  176. package/dist/core/case-orchestrator/tools.d.ts +0 -29
  177. package/dist/core/case-orchestrator/tools.js +0 -31
  178. package/dist/core/case-orchestrator/validate.d.ts +0 -11
  179. package/dist/core/case-orchestrator/validate.js +0 -63
  180. package/dist/core/functions/define/bind.d.ts +0 -25
  181. package/dist/core/functions/define/bind.js +0 -14
  182. package/dist/core/functions/define/case.d.ts +0 -9
  183. package/dist/core/functions/define/case.js +0 -13
  184. package/dist/core/functions/define/events.d.ts +0 -20
  185. package/dist/core/functions/define/events.js +0 -21
  186. package/dist/core/functions/define/no-case.d.ts +0 -4
  187. package/dist/core/functions/define/no-case.js +0 -9
  188. package/dist/core/functions/func-ref.d.ts +0 -25
  189. package/dist/core/functions/func-ref.js +0 -20
@@ -299,10 +299,7 @@ export interface FishTTSConfig {
299
299
  export interface AssistantConfig {
300
300
  minNumberOfWordsToInterrupt: number;
301
301
  interruptProtectionMs: number;
302
- endSpeakTimeoutMs: number;
303
- sttProvider: STTProvider;
304
302
  ttsProvider: TTSProvider;
305
- goodbyePatterns: string[];
306
303
  defaultTransferingMessage: string;
307
304
  defaultTransferFailedMessage: string;
308
305
  shuttingDownMessage: string;
@@ -502,6 +499,11 @@ export interface IncomingOutgoingCall extends AppAction {
502
499
  * `cartesia`, …). The AI cannot take the call: it goes to the fallback number.
503
500
  */
504
501
  unavailableServices?: string[];
502
+ /**
503
+ * Outbound: the id of the `Call` the Backend wrote before it asked for the dial (`make-call`'s `callId`),
504
+ * sent back as it came: the Backend finds the call by it (74 §3.1).
505
+ */
506
+ callId?: string;
505
507
  }
506
508
  export interface ChatWebsocketStartMessage extends IncomingOutgoingCall {
507
509
  voiceServiceUrl: string;
@@ -524,8 +526,8 @@ export type ApplicationConfig = {
524
526
  reason?: CallFailedReason;
525
527
  cfg: VoiceAssistantConfig;
526
528
  /**
527
- * The number this call is taken as, when it is not the one it came in on (a SIP call routed by its URI,
528
- * domain or header): the voice service shows it as the caller ID when it transfers.
529
+ * A call that came in on no number of ours (a call to one of our SIP addresses): the number the voice
530
+ * service shows as the caller ID when it transfers (the SIP address's caller-ID number).
529
531
  */
530
532
  serviceNumber?: string;
531
533
  };
@@ -662,6 +664,10 @@ export interface TransferEvt extends AppAction {
662
664
  interruptSay: boolean;
663
665
  requestor: Requestor;
664
666
  warmBriefingPrompt: string;
667
+ /** Warm and background: the page's whisper, looped to the person before they confirm (76 §2.9). */
668
+ whisper?: string;
669
+ /** The language of the person taking the call (BCP-47; English when absent): what they hear, and how they are heard (48 §10.3). */
670
+ agentLanguage?: string;
665
671
  transferType?: TransferType;
666
672
  warmTransferConfirmMode?: WarmTransferConfirmMethod[];
667
673
  warmTransferConfirmKeypad?: DtmfDigit;
@@ -676,6 +682,8 @@ export interface MakeCallRequest extends MakeCallOptions {
676
682
  type: 'make-call';
677
683
  fromNumber: string;
678
684
  toNumber: string;
685
+ /** The Backend's `Call` for this dial; the voice service sends it back on `onOutbound` (74 §3.1). */
686
+ callId?: string;
679
687
  options: MakeCallOptions;
680
688
  }
681
689
  export interface GlobalInterruptibleRequest extends AppAction {
@@ -709,7 +717,9 @@ export interface ReloadAppConfigResponse extends AppAction {
709
717
  export interface VoiceServiceResponse {
710
718
  success: boolean;
711
719
  callSid?: string;
712
- failedReason?: 'max-outbound-calls-reached' | 'service-unavailable' | 'twilio-api-error' | 'voice-service-internal-error' | 'on-outbound-request-error' | 'network-error' | 'fetch-twilio-config-error';
720
+ failedReason?: 'max-outbound-calls-reached' | 'service-unavailable' | 'twilio-api-error' | 'voice-service-internal-error' | 'on-outbound-request-error' | 'network-error'
721
+ /** The voice service answered with an HTTP error status (`statusCode`): set by the Backend's client. */
722
+ | 'http-error' | 'fetch-twilio-config-error';
713
723
  message?: string;
714
724
  errorCode?: number;
715
725
  statusCode?: number;
package/dist/worker.d.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  * the Worker carries only this.
6
6
  */
7
7
  export * from './fn-context/index.js';
8
- export { isWorkerFunctionKind, type WorkerFunctionKind } from './core/functions/types.js';
9
8
  export { parseComputeInvocation, type FunctionInvocation } from './compute-host/compute-host.js';
9
+ export { ORCHESTRATOR_FUNCTION } from './core/case-orchestrator/types.js';
10
+ export { functionScriptFile } from './builder/types.js';
10
11
  //# sourceMappingURL=worker.d.ts.map
package/dist/worker.js CHANGED
@@ -5,6 +5,7 @@
5
5
  * the Worker carries only this.
6
6
  */
7
7
  export * from './fn-context/index.js';
8
- export { isWorkerFunctionKind } from './core/functions/types.js';
9
8
  export { parseComputeInvocation } from './compute-host/compute-host.js';
9
+ export { ORCHESTRATOR_FUNCTION } from './core/case-orchestrator/types.js';
10
+ export { functionScriptFile } from './builder/types.js';
10
11
  //# sourceMappingURL=worker.js.map
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@superpanel-sdk/runtime",
3
- "version": "0.5.0",
4
- "description": "Slot + page runtime: schema, writes, derived recompute, page compile + todos",
3
+ "version": "0.7.0",
4
+ "description": "Slot + page runtime: schema, writes, page compile",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "engines": {
8
8
  "node": ">=22.15"
9
9
  },
10
10
  "bin": {
11
- "superpanel-sdk-runtime": "bin/superpanel-sdk-runtime.mjs"
11
+ "superpanel-sdk-runtime": "./bin/superpanel-sdk-runtime.mjs"
12
12
  },
13
13
  "exports": {
14
14
  ".": {
@@ -16,6 +16,11 @@
16
16
  "import": "./dist/index.js",
17
17
  "default": "./dist/index.js"
18
18
  },
19
+ "./testing": {
20
+ "types": "./dist/testing.d.ts",
21
+ "import": "./dist/testing.js",
22
+ "default": "./dist/testing.js"
23
+ },
19
24
  "./platform": {
20
25
  "superpanel-platform": {
21
26
  "types": "./dist/platform.d.ts",
@@ -46,29 +51,28 @@
46
51
  "dist/**/*.d.ts"
47
52
  ],
48
53
  "publishConfig": {
49
- "access": "public",
50
- "tag": "latest"
51
- },
52
- "scripts": {
53
- "build": "tsc -p tsconfig.json",
54
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tests/tsconfig.json --noEmit",
55
- "test": "tsx --tsconfig tests/tsconfig.json --test tests/**/*.test.ts",
56
- "dev": "tsc -p tsconfig.json --watch --preserveWatchOutput",
57
- "prepublishOnly": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json"
54
+ "access": "public"
58
55
  },
59
56
  "dependencies": {
60
57
  "@clack/prompts": "^1.8.1",
61
- "@trpc/client": "^11.7.2",
62
- "@trpc/server": "^11.7.2",
58
+ "@trpc/client": "11.18.0",
59
+ "@trpc/server": "11.18.0",
63
60
  "chokidar": "^4.0.3",
64
61
  "commander": "^15.0.0",
65
62
  "cron-parser": "5.10.0",
66
63
  "esbuild": "^0.25.12",
64
+ "quickjs-emscripten": "^0.32.0",
67
65
  "tsx": "^4.23.1",
68
66
  "typescript": "7.0.2",
69
- "zod": "^4.4.3"
67
+ "zod": "4.4.3"
70
68
  },
71
69
  "devDependencies": {
72
70
  "@types/node": "^26.1.1"
71
+ },
72
+ "scripts": {
73
+ "build": "tsc -p tsconfig.json",
74
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tests/tsconfig.json --noEmit",
75
+ "test": "tsx --tsconfig tests/tsconfig.json --test tests/**/*.test.ts",
76
+ "dev": "tsc -p tsconfig.json --watch --preserveWatchOutput"
73
77
  }
74
- }
78
+ }
@@ -1,31 +0,0 @@
1
- import { type CaseOrchestratorParams, type CaseOrchestratorTools, type ReadExchangeResult } from './types.js';
2
- type ConversationReadContext = {
3
- params: Pick<CaseOrchestratorParams, 'triggers'>;
4
- api: {
5
- tools: Pick<CaseOrchestratorTools, 'readExchange'>;
6
- };
7
- };
8
- /**
9
- * The conversations that started this Run (a connected call, an SMS or email turn), read with
10
- * `readExchange`: a whole call, the last {@link THREAD_MESSAGES_SHOWN} messages of a thread.
11
- * A read that fails is left out.
12
- */
13
- declare function readTriggeringConversations(ctx: ConversationReadContext): Promise<ReadExchangeResult[]>;
14
- /**
15
- * One customer's follow-up block, in their local time: `New conversations:` (only when this
16
- * customer has one: a whole call, the last messages of a thread), `Pending scheduled actions:` and
17
- * `Finished agreed follow-ups (last N days):`.
18
- */
19
- declare function customerSection(params: Pick<CaseOrchestratorParams, 'activity' | 'scheduledActions' | 'recentAgreedActions'>, contactId: string, conversations: readonly ReadExchangeResult[]): string;
20
- /**
21
- * The rules after the company's own: applying day-N rules and keeping agreed follow-ups, every Run;
22
- * booking agreed follow-ups too when the Run read a conversation.
23
- */
24
- declare function rules(conversations: readonly ReadExchangeResult[]): string;
25
- export declare const followUps: {
26
- readTriggeringConversations: typeof readTriggeringConversations;
27
- customerSection: typeof customerSection;
28
- rules: typeof rules;
29
- };
30
- export {};
31
- //# sourceMappingURL=follow-ups.d.ts.map
@@ -1,103 +0,0 @@
1
- // Bundled into company code as is (part of the company API, `src/index.ts`), so it imports render and types only.
2
- import { render } from './render.js';
3
- import { RECENT_AGREED_ACTIONS_DAYS, } from './types.js';
4
- /**
5
- * Follow-ups in a company prompt, in the mars next-step format (docs/design/08-case-orchestrator.md
6
- * §5.3, docs/design/09-agreed-follow-up.md): how to apply day-N rules on this platform, read what
7
- * was just said, each customer's follow-ups, and the rules for booking and keeping agreed ones. The
8
- * rules name what the platform computes and writes (`Today is [day N]` from
9
- * `render.activitySummary`, the headings and marks here, the schedule tools), so use them together.
10
- */
11
- /** SMS and email threads are long: the last messages are enough to see what was just agreed. */
12
- const THREAD_MESSAGES_SHOWN = 10;
13
- /** Regular follow-ups: applying the company's day-N rules with the schedule tools. */
14
- const DAY_RULES = `How to apply the rules (day N is the Nth day since the first interaction with that customer):
15
- - Find each customer's current day ("Today is [day N]") and apply that day's rule. Rules for past days no longer apply.
16
- - The next follow-up is what we do if the customer stops responding from now on. Every customer always has their next follow-up scheduled; if a pending one still fits the rules, leave it.
17
- - If today's rule is already done or needs nothing, look ahead to the first later day whose rule needs doing.
18
- - Give at, the exact time it runs: the time a rule names (e.g. 5 minutes after a call), or for a day rule a time that day inside the hours the company's rules allow and the customer's own hours if shown. It runs then; nothing moves it.
19
- - Use only an available channel.
20
- - If no later rule needs doing, schedule nothing.`;
21
- const AGREED_RULES = `Agreed follow-ups:
22
- - Pending actions marked [agreed …] were promised. Keep them. Change or cancel one only if the customer changed or withdrew it, and give the reason.
23
- - Do not schedule a regular follow-up before an agreed one on the same day.
24
- - If an agreed follow-up failed or was not answered, continue with the day rules.`;
25
- const BOOKING_RULES = `Booking agreed follow-ups:
26
- - "New conversations" shows what was just said. If the customer asked us to call, text or email them at a time, or agreed to a time we offered, book it as an agreed follow-up: the schedule tool with agreedInExchangeId, agreedAt (the time of the customer's message saying it, copied from its [time], with the customer's offset), customerQuote (their exact words) and note. Give at, the exact time it runs; for a vague one ("tomorrow afternoon"), pick a time inside what they said and inside the hours the company's rules allow. Resolve relative times ("in 10 minutes", "tomorrow") from the time the customer said it.
27
- - Do not book: our own promise the customer did not answer, the customer saying they will contact us, a request for a specific person to call, or a request on behalf of someone else.
28
- - Check the pending and the finished agreed follow-ups first ([agreed in <exchangeId> at <time>] names the message), so a promise already booked or done is not booked again.
29
- - One agreed follow-up per channel at a time; put any further agreed time in its note.
30
- - If the customer said they will do something by a time (e.g. send documents by Friday), schedule the next regular follow-up after that time instead of the day rule.`;
31
- /**
32
- * One exchange, paging back with `before` until it has `wanted` entries or reaches the
33
- * start: the newest page has callKey `conversation:<id>`, each earlier one
34
- * `conversation:<id>:before:<n>`. `null` when the first read fails; a later failed page stops
35
- * there and `range.from` stays above 0.
36
- */
37
- async function readConversation(ctx, exchangeId, wanted) {
38
- const first = await ctx.api.tools.readExchange({ exchangeId }, { callKey: `conversation:${exchangeId}` });
39
- if (!first.ok)
40
- return null;
41
- let read = first.value;
42
- while (read.range.from > 0 && read.entries.length < wanted) {
43
- const before = read.range.from;
44
- const page = await ctx.api.tools.readExchange({ exchangeId, before }, { callKey: `conversation:${exchangeId}:before:${before}` });
45
- if (!page.ok || page.value.range.to !== before || page.value.range.from >= before)
46
- break;
47
- read = {
48
- ...read,
49
- range: { from: page.value.range.from, to: read.range.to },
50
- entries: [...page.value.entries, ...read.entries],
51
- };
52
- }
53
- return read;
54
- }
55
- /**
56
- * The conversations that started this Run (a connected call, an SMS or email turn), read with
57
- * `readExchange`: a whole call, the last {@link THREAD_MESSAGES_SHOWN} messages of a thread.
58
- * A read that fails is left out.
59
- */
60
- async function readTriggeringConversations(ctx) {
61
- const read = [];
62
- const seen = new Set();
63
- for (const trigger of ctx.params.triggers) {
64
- const conversation = (trigger.type === 'call.ended' && trigger.result === 'connected') ||
65
- trigger.type === 'sms.turn-ended' ||
66
- trigger.type === 'email.turn-ended';
67
- if (!conversation || seen.has(trigger.exchangeId))
68
- continue;
69
- seen.add(trigger.exchangeId);
70
- const wanted = trigger.type === 'call.ended' ? Number.POSITIVE_INFINITY : THREAD_MESSAGES_SHOWN;
71
- const result = await readConversation(ctx, trigger.exchangeId, wanted);
72
- if (result)
73
- read.push(result);
74
- }
75
- return read;
76
- }
77
- /**
78
- * One customer's follow-up block, in their local time: `New conversations:` (only when this
79
- * customer has one: a whole call, the last messages of a thread), `Pending scheduled actions:` and
80
- * `Finished agreed follow-ups (last N days):`.
81
- */
82
- function customerSection(params, contactId, conversations) {
83
- const timezone = params.activity.byContact[contactId]?.timezone ?? params.activity.timezone;
84
- const said = conversations
85
- .filter((conversation) => conversation.contactId === contactId)
86
- .map((conversation) => render.conversation(conversation, timezone, conversation.channel === 'call' ? {} : { limit: THREAD_MESSAGES_SHOWN }));
87
- const pending = params.scheduledActions.filter((action) => action.contactId === contactId);
88
- const finished = params.recentAgreedActions.filter((action) => action.contactId === contactId);
89
- return [
90
- ...(said.length > 0 ? [`New conversations:\n${said.join('\n\n')}`] : []),
91
- `Pending scheduled actions:\n${render.pendingActions(pending, timezone)}`,
92
- `Finished agreed follow-ups (last ${RECENT_AGREED_ACTIONS_DAYS} days):\n${render.recentAgreedActions(finished, timezone)}`,
93
- ].join('\n\n');
94
- }
95
- /**
96
- * The rules after the company's own: applying day-N rules and keeping agreed follow-ups, every Run;
97
- * booking agreed follow-ups too when the Run read a conversation.
98
- */
99
- function rules(conversations) {
100
- return [DAY_RULES, AGREED_RULES, ...(conversations.length > 0 ? [BOOKING_RULES] : [])].join('\n\n');
101
- }
102
- export const followUps = { readTriggeringConversations, customerSection, rules };
103
- //# sourceMappingURL=follow-ups.js.map
@@ -1,29 +0,0 @@
1
- import type { ToolRef } from './types.js';
2
- /**
3
- * References to the platform tools an AgentRequest may open. The platform
4
- * owns each tool's description, parameters and executor; a reference only names it.
5
- */
6
- export declare const tools: {
7
- /** Read what was said in one call (plus its result and duration), SMS conversation or email thread. */
8
- readonly readExchange: () => ToolRef<"readExchange">;
9
- /** Find exchanges by time, contact, channel, direction, result or scheduled action; calls carry their duration. */
10
- readonly searchExchanges: () => ToolRef<"searchExchanges">;
11
- /** Write slot fields; multi-row tables (contact included) need a `rowId`. */
12
- readonly updateSlots: () => ToolRef<"updateSlots">;
13
- readonly scheduleCall: () => ToolRef<"scheduleCall">;
14
- readonly scheduleSms: () => ToolRef<"scheduleSms">;
15
- readonly scheduleEmail: () => ToolRef<"scheduleEmail">;
16
- /** Write slot fields at a set time, as given then (cancel or reschedule it when it no longer fits). */
17
- readonly scheduleUpdateSlots: () => ToolRef<"scheduleUpdateSlots">;
18
- /** Move a pending action to a new time; same contact and channel. */
19
- readonly rescheduleAction: () => ToolRef<"rescheduleAction">;
20
- readonly cancelScheduledAction: () => ToolRef<"cancelScheduledAction">;
21
- /** Hand the instance over to another sequence, on the same row or a named one, now or at a set time. */
22
- readonly scheduleNextSequence: () => ToolRef<"scheduleNextSequence">;
23
- /** End the instance: its pending actions are cancelled and no Run follows. */
24
- readonly closeInstance: () => ToolRef<"closeInstance">;
25
- /** Wake this Orchestrator up at a set time (a `timer` trigger); one pending per name, booking it again moves it. */
26
- readonly scheduleWake: () => ToolRef<"scheduleWake">;
27
- readonly cancelWake: () => ToolRef<"cancelWake">;
28
- };
29
- //# sourceMappingURL=tools.d.ts.map
@@ -1,31 +0,0 @@
1
- function ref(name) {
2
- return () => ({ kind: 'tool', name });
3
- }
4
- /**
5
- * References to the platform tools an AgentRequest may open. The platform
6
- * owns each tool's description, parameters and executor; a reference only names it.
7
- */
8
- export const tools = {
9
- /** Read what was said in one call (plus its result and duration), SMS conversation or email thread. */
10
- readExchange: ref('readExchange'),
11
- /** Find exchanges by time, contact, channel, direction, result or scheduled action; calls carry their duration. */
12
- searchExchanges: ref('searchExchanges'),
13
- /** Write slot fields; multi-row tables (contact included) need a `rowId`. */
14
- updateSlots: ref('updateSlots'),
15
- scheduleCall: ref('scheduleCall'),
16
- scheduleSms: ref('scheduleSms'),
17
- scheduleEmail: ref('scheduleEmail'),
18
- /** Write slot fields at a set time, as given then (cancel or reschedule it when it no longer fits). */
19
- scheduleUpdateSlots: ref('scheduleUpdateSlots'),
20
- /** Move a pending action to a new time; same contact and channel. */
21
- rescheduleAction: ref('rescheduleAction'),
22
- cancelScheduledAction: ref('cancelScheduledAction'),
23
- /** Hand the instance over to another sequence, on the same row or a named one, now or at a set time. */
24
- scheduleNextSequence: ref('scheduleNextSequence'),
25
- /** End the instance: its pending actions are cancelled and no Run follows. */
26
- closeInstance: ref('closeInstance'),
27
- /** Wake this Orchestrator up at a set time (a `timer` trigger); one pending per name, booking it again moves it. */
28
- scheduleWake: ref('scheduleWake'),
29
- cancelWake: ref('cancelWake'),
30
- };
31
- //# sourceMappingURL=tools.js.map
@@ -1,11 +0,0 @@
1
- import { type FinalOrchestrationResult, type ResolvedAgentRequest } from './types.js';
2
- /** A valid result, with an AgentRequest's `tools` resolved (every platform tool when left out). */
3
- export type CaseOrchestratorResultCheck = {
4
- ok: true;
5
- value: ResolvedAgentRequest | FinalOrchestrationResult;
6
- } | {
7
- ok: false;
8
- issues: string[];
9
- };
10
- export declare function validateCaseOrchestratorResult(raw: unknown): CaseOrchestratorResultCheck;
11
- //# sourceMappingURL=validate.d.ts.map
@@ -1,63 +0,0 @@
1
- import { CASE_ORCHESTRATOR_TOOL_NAMES, } from './types.js';
2
- const TOOL_NAMES = new Set(CASE_ORCHESTRATOR_TOOL_NAMES);
3
- const ALL_TOOLS = CASE_ORCHESTRATOR_TOOL_NAMES.map((name) => ({ kind: 'tool', name }));
4
- function isRecord(value) {
5
- return typeof value === 'object' && value !== null && !Array.isArray(value);
6
- }
7
- function isToolRef(value) {
8
- return isRecord(value) && value.kind === 'tool' && typeof value.name === 'string' && TOOL_NAMES.has(value.name);
9
- }
10
- function validateTools(raw, issues) {
11
- if (raw === undefined)
12
- return ALL_TOOLS;
13
- if (!Array.isArray(raw)) {
14
- issues.push('tools must be an array of tools.*() references (leave it out for every tool, [] for none)');
15
- return [];
16
- }
17
- const seen = new Set();
18
- const tools = [];
19
- raw.forEach((tool, index) => {
20
- if (!isToolRef(tool)) {
21
- issues.push(`tools[${index}] is not a registered tool reference`);
22
- return;
23
- }
24
- if (seen.has(tool.name))
25
- issues.push(`tools[${index}] repeats '${tool.name}'`);
26
- else {
27
- seen.add(tool.name);
28
- tools.push(tool);
29
- }
30
- });
31
- return tools;
32
- }
33
- function validateAgent(raw) {
34
- const issues = [];
35
- const prompt = typeof raw.prompt === 'string' ? raw.prompt.trim() : '';
36
- if (!prompt)
37
- issues.push('prompt must be a non-empty string');
38
- const tools = validateTools(raw.tools, issues);
39
- return issues.length > 0 ? { ok: false, issues } : { ok: true, value: { kind: 'agent', prompt, tools } };
40
- }
41
- function validateFinal(raw) {
42
- const issues = [];
43
- const finalSummary = typeof raw.finalSummary === 'string' ? raw.finalSummary.trim() : '';
44
- if (finalSummary.length < 1 || finalSummary.length > 1000) {
45
- issues.push('finalSummary must contain 1-1000 characters');
46
- }
47
- return issues.length > 0
48
- ? { ok: false, issues }
49
- : {
50
- ok: true,
51
- value: { kind: 'final', finalSummary },
52
- };
53
- }
54
- export function validateCaseOrchestratorResult(raw) {
55
- if (!isRecord(raw))
56
- return { ok: false, issues: ['orchestrator must return an object'] };
57
- if (raw.kind === 'agent')
58
- return validateAgent(raw);
59
- if (raw.kind === 'final')
60
- return validateFinal(raw);
61
- return { ok: false, issues: ["orchestrator result.kind must be 'agent' or 'final'"] };
62
- }
63
- //# sourceMappingURL=validate.js.map
@@ -1,25 +0,0 @@
1
- import type { CaseInput } from '../../case-orchestrator/types.js';
2
- import type { PageTablesDesc } from '../../page/typed.js';
3
- import type { EventHandlers } from '../events.js';
4
- import type { CaseFn, DefinedCaseFunc, DefinedNoCaseFunc, FuncOptions, NoCaseFn } from '../types.js';
5
- /**
6
- * The define helpers bound to one sequence: functions' and event handlers' `c` to its case (`C`: the
7
- * instance and its business root's id), `ctx.api.db` to its `PageTables` (`D`).
8
- */
9
- export type BoundDefines<D extends PageTablesDesc | undefined = undefined, C = CaseInput> = {
10
- defineCaseFunc: {
11
- /** A function that writes with `ctx.api.db` and returns nothing. */
12
- <P extends object = object>(main: CaseFn<C, P, void, D>, options?: FuncOptions): DefinedCaseFunc<C, P, void, D>;
13
- /** Any other return type, spelled out: `defineCaseFunc<object, string>(…)` (`R` is never inferred). */
14
- <P extends object = object, R = never>(main: CaseFn<C, P, NoInfer<R>, D>, options?: FuncOptions): DefinedCaseFunc<C, P, R, D>;
15
- };
16
- /** Nocase function: no `c`; reads and writes with `ctx.api.db`. */
17
- defineNoCaseFunc: <P extends object = object, R = unknown>(main: NoCaseFn<P, R, D>, options?: FuncOptions) => DefinedNoCaseFunc<P, R, D>;
18
- defineEvents: (handlers: EventHandlers<C, D>) => EventHandlers<C, D>;
19
- };
20
- /**
21
- * Bind the define helpers to a sequence. `type:gen` emits `__gen/index.ts` calling this, so company
22
- * code never spells the types: `defineCaseFunc(async (c, ctx) => …)`.
23
- */
24
- export declare function bindDefines<D extends PageTablesDesc | undefined = undefined, C = CaseInput>(): BoundDefines<D, C>;
25
- //# sourceMappingURL=bind.d.ts.map
@@ -1,14 +0,0 @@
1
- import { defineCaseFunc } from './case.js';
2
- import { defineNoCaseFunc } from './no-case.js';
3
- /**
4
- * Bind the define helpers to a sequence. `type:gen` emits `__gen/index.ts` calling this, so company
5
- * code never spells the types: `defineCaseFunc(async (c, ctx) => …)`.
6
- */
7
- export function bindDefines() {
8
- return {
9
- defineCaseFunc: defineCaseFunc,
10
- defineNoCaseFunc: defineNoCaseFunc,
11
- defineEvents: (handlers) => handlers,
12
- };
13
- }
14
- //# sourceMappingURL=bind.js.map
@@ -1,9 +0,0 @@
1
- import type { CaseFn, DefinedCaseFunc, FuncOptions } from '../types.js';
2
- import type { CaseInput } from '../../case-orchestrator/types.js';
3
- /**
4
- * Worker function bound to a case: `(c, ctx) => R`, `c` the instance and its business root's id.
5
- * `R` defaults to `void` (a function that writes with `ctx.api.db`); other callers
6
- * pass their own. Company code normally uses the bound version from `__gen/index.ts` so `S` is never spelled.
7
- */
8
- export declare function defineCaseFunc<S = CaseInput, P extends object = object, R = void>(main: CaseFn<S, P, R>, options?: FuncOptions): DefinedCaseFunc<S, P, R>;
9
- //# sourceMappingURL=case.d.ts.map
@@ -1,13 +0,0 @@
1
- /**
2
- * Worker function bound to a case: `(c, ctx) => R`, `c` the instance and its business root's id.
3
- * `R` defaults to `void` (a function that writes with `ctx.api.db`); other callers
4
- * pass their own. Company code normally uses the bound version from `__gen/index.ts` so `S` is never spelled.
5
- */
6
- export function defineCaseFunc(main, options) {
7
- return {
8
- kind: 'case',
9
- main,
10
- ...options,
11
- };
12
- }
13
- //# sourceMappingURL=case.js.map
@@ -1,20 +0,0 @@
1
- import type { CaseInput } from '../../case-orchestrator/types.js';
2
- import type { PageTablesDesc } from '../../page/typed.js';
3
- import type { EventHandlers, WebhookHandler } from '../events.js';
4
- /**
5
- * Author-side helper for the `events` export. The parameter type is fully known,
6
- * so handler arguments are contextually typed and unknown event names are
7
- * rejected as excess properties.
8
- *
9
- * ```ts
10
- * export const events = defineEvents({
11
- * 'call.ended': async (c, ctx) => {
12
- * await ctx.api.db.matter.update({ where: { id: c.subject }, data: { last_call: ctx.params.event.outcome } });
13
- * },
14
- * });
15
- * ```
16
- */
17
- export declare function defineEvents<C = CaseInput, D extends PageTablesDesc | undefined = undefined>(handlers: EventHandlers<C, D>): EventHandlers<C, D>;
18
- /** Author-side helper for `webhook.ts`'s `received`: types `ctx.params.event` and the return. */
19
- export declare function defineWebhook<D extends PageTablesDesc | undefined = undefined>(handler: WebhookHandler<D>): WebhookHandler<D>;
20
- //# sourceMappingURL=events.d.ts.map
@@ -1,21 +0,0 @@
1
- /**
2
- * Author-side helper for the `events` export. The parameter type is fully known,
3
- * so handler arguments are contextually typed and unknown event names are
4
- * rejected as excess properties.
5
- *
6
- * ```ts
7
- * export const events = defineEvents({
8
- * 'call.ended': async (c, ctx) => {
9
- * await ctx.api.db.matter.update({ where: { id: c.subject }, data: { last_call: ctx.params.event.outcome } });
10
- * },
11
- * });
12
- * ```
13
- */
14
- export function defineEvents(handlers) {
15
- return handlers;
16
- }
17
- /** Author-side helper for `webhook.ts`'s `received`: types `ctx.params.event` and the return. */
18
- export function defineWebhook(handler) {
19
- return handler;
20
- }
21
- //# sourceMappingURL=events.js.map
@@ -1,4 +0,0 @@
1
- import type { DefinedNoCaseFunc, FuncOptions, NoCaseFn } from '../types.js';
2
- /** Worker function not bound to a case: `(ctx) => R`. No case (`c`) is passed. */
3
- export declare function defineNoCaseFunc<P extends object = object, R = unknown>(main: NoCaseFn<P, R>, options?: FuncOptions): DefinedNoCaseFunc<P, R>;
4
- //# sourceMappingURL=no-case.d.ts.map
@@ -1,9 +0,0 @@
1
- /** Worker function not bound to a case: `(ctx) => R`. No case (`c`) is passed. */
2
- export function defineNoCaseFunc(main, options) {
3
- return {
4
- kind: 'noCase',
5
- main,
6
- ...options,
7
- };
8
- }
9
- //# sourceMappingURL=no-case.js.map
@@ -1,25 +0,0 @@
1
- import type { DefinedFunc, FuncMap, FunctionKind } from './types.js';
2
- /**
3
- * Author-time function reference:
4
- * - string key: `'computeIsQualified'`
5
- * - map value: `functions.computeIsQualified` ({@link DefinedFunc})
6
- *
7
- * Compiled / runtime schemas always store the string name.
8
- */
9
- export type FuncRef = string | DefinedFunc;
10
- /**
11
- * Structural stand-in for narrowed refs such as `DefinedCaseFunc<never, …>`: a function whose
12
- * `caseContext` is typed `never` is not assignable to `DefinedFunc<any>` (any → never fails),
13
- * but identity lookup only needs the object.
14
- */
15
- export type FuncRefLike = FuncRef | {
16
- kind: FunctionKind;
17
- main: unknown;
18
- };
19
- /**
20
- * Normalize a {@link FuncRef} to the functions-map key.
21
- * Object refs need the same `functions` map for identity lookup
22
- * (plain map values do not carry `name`).
23
- */
24
- export declare function resolveFuncName(ref: FuncRefLike, functions?: FuncMap): string;
25
- //# sourceMappingURL=func-ref.d.ts.map
@@ -1,20 +0,0 @@
1
- /**
2
- * Normalize a {@link FuncRef} to the functions-map key.
3
- * Object refs need the same `functions` map for identity lookup
4
- * (plain map values do not carry `name`).
5
- */
6
- export function resolveFuncName(ref, functions) {
7
- if (typeof ref === 'string') {
8
- if (!ref)
9
- throw new Error('Function reference name must be a non-empty string');
10
- return ref;
11
- }
12
- if (functions) {
13
- for (const [key, value] of Object.entries(functions)) {
14
- if (value === ref)
15
- return key;
16
- }
17
- }
18
- throw new Error('Invalid function reference; expected a string name or a value from the functions map');
19
- }
20
- //# sourceMappingURL=func-ref.js.map