@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.
- package/README.md +28 -8
- package/dist/builder/codegen/emit.d.ts +29 -11
- package/dist/builder/codegen/emit.js +328 -61
- package/dist/builder/codegen/generate.d.ts +21 -0
- package/dist/builder/codegen/generate.js +152 -20
- package/dist/builder/company-import-graph.d.ts +2 -0
- package/dist/builder/company-import-graph.js +40 -8
- package/dist/builder/company-imports.d.ts +24 -0
- package/dist/builder/company-imports.js +114 -0
- package/dist/builder/compile/compile-sequence.d.ts +59 -8
- package/dist/builder/compile/compile-sequence.js +279 -77
- package/dist/builder/compile/function-code.d.ts +12 -2
- package/dist/builder/compile/function-code.js +87 -39
- package/dist/builder/compile/registry.d.ts +7 -3
- package/dist/builder/compile/registry.js +24 -23
- package/dist/builder/load.d.ts +70 -10
- package/dist/builder/load.js +250 -61
- package/dist/builder/paths.d.ts +3 -0
- package/dist/builder/paths.js +16 -0
- package/dist/builder/schedules.d.ts +23 -0
- package/dist/builder/schedules.js +102 -0
- package/dist/builder/slot-schema-validation.d.ts +4 -0
- package/dist/builder/slot-schema-validation.js +10 -0
- package/dist/builder/typecheck.d.ts +8 -0
- package/dist/builder/typecheck.js +105 -0
- package/dist/builder/types.d.ts +91 -19
- package/dist/builder/types.js +2 -1
- package/dist/cli/auth/auth.d.ts +37 -0
- package/dist/cli/auth/auth.js +211 -0
- package/dist/cli/auth/backend-url.d.ts +5 -0
- package/dist/cli/auth/backend-url.js +25 -0
- package/dist/cli/auth/clipboard.d.ts +9 -0
- package/dist/cli/auth/clipboard.js +38 -0
- package/dist/cli/auth/http.d.ts +20 -0
- package/dist/cli/auth/http.js +27 -0
- package/dist/cli/auth/index.d.ts +10 -0
- package/dist/cli/auth/index.js +27 -0
- package/dist/cli/auth/progress.d.ts +12 -0
- package/dist/cli/auth/progress.js +15 -0
- package/dist/cli/auth/serve-login.d.ts +8 -0
- package/dist/cli/auth/serve-login.js +24 -0
- package/dist/cli/compile/index.js +3 -0
- package/dist/cli/config.d.ts +10 -0
- package/dist/cli/config.js +52 -0
- package/dist/cli/index.js +28 -8
- package/dist/cli/serve/index.d.ts +73 -3
- package/dist/cli/serve/index.js +410 -113
- package/dist/cli/type-gen/index.js +9 -8
- package/dist/compiler.d.ts +7 -0
- package/dist/compiler.js +7 -0
- package/dist/compute-host/compute-host.d.ts +15 -23
- package/dist/compute-host/compute-host.js +25 -28
- package/dist/compute-host/index.d.ts +2 -2
- package/dist/compute-host/index.js +1 -1
- package/dist/compute-host/source-compute-host.d.ts +11 -9
- package/dist/compute-host/source-compute-host.js +50 -31
- package/dist/core/case-orchestrator/contact-hours.d.ts +50 -0
- package/dist/core/case-orchestrator/contact-hours.js +108 -0
- package/dist/core/case-orchestrator/follow-ups.d.ts +31 -0
- package/dist/core/case-orchestrator/follow-ups.js +103 -0
- package/dist/core/case-orchestrator/index.d.ts +6 -0
- package/dist/core/case-orchestrator/index.js +6 -0
- package/dist/core/case-orchestrator/render.d.ts +75 -0
- package/dist/core/case-orchestrator/render.js +239 -0
- package/dist/core/case-orchestrator/time.d.ts +11 -0
- package/dist/core/case-orchestrator/time.js +29 -0
- package/dist/core/case-orchestrator/tools.d.ts +29 -0
- package/dist/core/case-orchestrator/tools.js +31 -0
- package/dist/core/case-orchestrator/types.d.ts +753 -0
- package/dist/core/case-orchestrator/types.js +46 -0
- package/dist/core/case-orchestrator/validate.d.ts +11 -0
- package/dist/core/case-orchestrator/validate.js +63 -0
- package/dist/core/context/call.d.ts +291 -0
- package/dist/core/context/call.js +94 -0
- package/dist/core/context/channels.d.ts +60 -0
- package/dist/core/context/channels.js +35 -0
- package/dist/core/context/contact.d.ts +96 -6
- package/dist/core/context/contact.js +48 -2
- package/dist/core/context/email-message.d.ts +159 -0
- package/dist/core/context/email-message.js +59 -0
- package/dist/core/context/email.d.ts +97 -0
- package/dist/core/context/email.js +91 -0
- package/dist/core/context/exchanges.d.ts +142 -0
- package/dist/core/context/exchanges.js +63 -0
- package/dist/core/context/instances.d.ts +278 -0
- package/dist/core/context/instances.js +123 -0
- package/dist/core/context/kv.d.ts +113 -0
- package/dist/core/context/kv.js +60 -0
- package/dist/core/context/platform-registry.d.ts +509 -4
- package/dist/core/context/platform-registry.js +14 -2
- package/dist/core/context/platform.d.ts +2 -1
- package/dist/core/context/sms.d.ts +147 -0
- package/dist/core/context/sms.js +57 -0
- package/dist/core/context/types.d.ts +51 -30
- package/dist/core/context/types.js +1 -7
- package/dist/core/conversation/index.d.ts +31 -0
- package/dist/core/conversation/index.js +14 -0
- package/dist/core/functions/define/bind.d.ts +25 -0
- package/dist/core/functions/define/bind.js +14 -0
- package/dist/core/functions/define/case.d.ts +9 -0
- package/dist/core/functions/define/case.js +13 -0
- package/dist/core/functions/define/events.d.ts +20 -0
- package/dist/core/functions/define/events.js +21 -0
- package/dist/core/functions/define/no-case.d.ts +4 -0
- package/dist/core/functions/define/no-case.js +9 -0
- package/dist/core/functions/events.d.ts +247 -0
- package/dist/core/functions/events.js +32 -0
- package/dist/core/functions/func-ref.d.ts +11 -2
- package/dist/core/functions/schedules.d.ts +51 -0
- package/dist/core/functions/schedules.js +20 -0
- package/dist/core/functions/types.d.ts +62 -51
- package/dist/core/functions/types.js +6 -1
- package/dist/core/office-hours/index.d.ts +39 -0
- package/dist/core/office-hours/index.js +187 -0
- package/dist/core/page/define.d.ts +834 -0
- package/dist/core/page/define.js +477 -0
- package/dist/core/page/ops.d.ts +58 -0
- package/dist/core/page/ops.js +220 -0
- package/dist/core/page/render.d.ts +253 -0
- package/dist/core/page/render.js +840 -0
- package/dist/core/page/time-format.d.ts +19 -0
- package/dist/core/page/time-format.js +41 -0
- package/dist/core/page/timeline.d.ts +40 -0
- package/dist/core/page/timeline.js +2 -0
- package/dist/core/page/typed.d.ts +642 -0
- package/dist/core/page/typed.js +2 -0
- package/dist/core/page/workspace.d.ts +33 -0
- package/dist/core/page/workspace.js +231 -0
- package/dist/core/party/index.d.ts +3 -0
- package/dist/core/party/index.js +3 -0
- package/dist/core/party/schema.d.ts +137 -0
- package/dist/core/party/schema.js +80 -0
- package/dist/core/party/types.d.ts +40 -0
- package/dist/core/party/types.js +15 -0
- package/dist/core/sequence/define.d.ts +57 -0
- package/dist/core/sequence/define.js +10 -0
- package/dist/core/sequence/index.d.ts +63 -0
- package/dist/core/sequence/index.js +231 -0
- package/dist/core/slot/binding.d.ts +40 -0
- package/dist/core/slot/binding.js +2 -0
- package/dist/core/slot/company-metadata.d.ts +113 -0
- package/dist/core/slot/company-metadata.js +563 -0
- package/dist/core/slot/compile-schema.d.ts +19 -13
- package/dist/core/slot/compile-schema.js +51 -248
- package/dist/core/slot/contact-timezone.d.ts +110 -0
- package/dist/core/slot/contact-timezone.js +186 -0
- package/dist/core/slot/field.d.ts +2 -24
- package/dist/core/slot/field.js +0 -69
- package/dist/core/slot/id-ref.d.ts +17 -2
- package/dist/core/slot/id-ref.js +16 -8
- package/dist/core/slot/index.d.ts +12 -13
- package/dist/core/slot/index.js +11 -12
- package/dist/core/slot/naming.d.ts +15 -0
- package/dist/core/slot/naming.js +96 -0
- package/dist/core/slot/platform-fields.d.ts +119 -0
- package/dist/core/slot/platform-fields.js +121 -0
- package/dist/core/slot/ref.d.ts +16 -0
- package/dist/core/slot/ref.js +14 -0
- package/dist/core/slot/row.d.ts +2 -9
- package/dist/core/slot/row.js +13 -23
- package/dist/core/slot/schema-compat.d.ts +16 -0
- package/dist/core/slot/schema-compat.js +112 -0
- package/dist/core/slot/schema.d.ts +409 -76
- package/dist/core/slot/schema.js +178 -10
- package/dist/core/slot/types.d.ts +27 -92
- package/dist/core/slot/value.d.ts +26 -3
- package/dist/core/slot/value.js +89 -57
- package/dist/dev-overlay/protocol.d.ts +41 -8
- package/dist/fn-context/build-context.d.ts +3 -1
- package/dist/fn-context/build-context.js +20 -10
- package/dist/fn-context/fake/empty-api.js +9 -28
- package/dist/fn-context/fake/index.d.ts +11 -4
- package/dist/fn-context/fake/index.js +27 -2
- package/dist/fn-context/fn-params.d.ts +6 -0
- package/dist/fn-context/fn-params.js +13 -0
- package/dist/fn-context/index.d.ts +5 -5
- package/dist/fn-context/index.js +4 -4
- package/dist/fn-context/log.js +2 -2
- package/dist/fn-context/make-ctx.d.ts +11 -0
- package/dist/fn-context/make-ctx.js +18 -8
- package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +24 -0
- package/dist/fn-context/rpc/case-orchestrator-tools.js +13 -0
- package/dist/fn-context/rpc/index.d.ts +3 -1
- package/dist/fn-context/rpc/index.js +3 -1
- package/dist/fn-context/rpc/integration/index.d.ts +4 -4
- package/dist/fn-context/rpc/integration/index.js +1 -1
- package/dist/fn-context/rpc/integration/list-surfaces.d.ts +21 -0
- package/dist/fn-context/rpc/integration/{list-bindings.js → list-surfaces.js} +4 -4
- package/dist/fn-context/rpc/platform.d.ts +2 -2
- package/dist/fn-context/rpc/platform.js +1 -1
- package/dist/fn-context/rpc/records.d.ts +78 -0
- package/dist/fn-context/rpc/records.js +26 -0
- package/dist/fn-context/rpc/trpc-client.d.ts +2 -2
- package/dist/fn-context/rpc/trpc-client.js +89 -5
- package/dist/fn-context/rpc/trpc-init.d.ts +2 -2
- package/dist/fn-context/rpc/trpc-router-factory.d.ts +49 -3
- package/dist/fn-context/rpc/trpc-router-factory.js +2 -0
- package/dist/fn-context/run-scope.d.ts +4 -0
- package/dist/fn-context/run-scope.js +9 -0
- package/dist/fn-context/types.d.ts +36 -3
- package/dist/index.d.ts +37 -46
- package/dist/index.js +33 -33
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +41 -0
- package/dist/platform.d.ts +76 -0
- package/dist/platform.js +56 -0
- package/dist/voice-service/actions.d.ts +71 -4
- package/dist/voice-service/types.d.ts +42 -2
- package/dist/worker.d.ts +10 -0
- package/dist/worker.js +10 -0
- package/package.json +38 -19
- package/dist/builder/compile/compile-agenda.d.ts +0 -15
- package/dist/builder/compile/compile-agenda.js +0 -59
- package/dist/builder/merge.d.ts +0 -4
- package/dist/builder/merge.js +0 -19
- package/dist/core/context/db.d.ts +0 -69
- package/dist/core/context/db.js +0 -44
- package/dist/core/context/docusign.d.ts +0 -134
- package/dist/core/context/docusign.js +0 -108
- package/dist/core/context/filevine.d.ts +0 -323
- package/dist/core/context/filevine.js +0 -254
- package/dist/core/context/http.d.ts +0 -9
- package/dist/core/context/http.js +0 -4
- package/dist/core/context/hubspot.d.ts +0 -250
- package/dist/core/context/hubspot.js +0 -191
- package/dist/core/context/twilio.d.ts +0 -50
- package/dist/core/context/twilio.js +0 -42
- package/dist/core/functions/define/case-context.d.ts +0 -14
- package/dist/core/functions/define/case-context.js +0 -15
- package/dist/core/functions/define/compute.d.ts +0 -7
- package/dist/core/functions/define/compute.js +0 -17
- package/dist/core/functions/define/custom.d.ts +0 -4
- package/dist/core/functions/define/custom.js +0 -8
- package/dist/core/functions/define/system.d.ts +0 -7
- package/dist/core/functions/define/system.js +0 -12
- package/dist/core/slot/deps.d.ts +0 -15
- package/dist/core/slot/deps.js +0 -88
- package/dist/core/slot/derived.d.ts +0 -32
- package/dist/core/slot/derived.js +0 -115
- package/dist/core/slot/platform-session-fields.d.ts +0 -38
- package/dist/core/slot/platform-session-fields.js +0 -48
- package/dist/core/slot/sf-schema.d.ts +0 -23
- package/dist/core/slot/sf-schema.js +0 -125
- package/dist/core/slot/sf-validate.d.ts +0 -14
- package/dist/core/slot/sf-validate.js +0 -132
- package/dist/core/slot/snapshot.d.ts +0 -18
- package/dist/core/slot/snapshot.js +0 -138
- package/dist/core/slot/write.d.ts +0 -41
- package/dist/core/slot/write.js +0 -319
- package/dist/core/stage/builders.d.ts +0 -36
- package/dist/core/stage/builders.js +0 -28
- package/dist/core/stage/condition.d.ts +0 -17
- package/dist/core/stage/condition.js +0 -198
- package/dist/core/stage/drive.d.ts +0 -43
- package/dist/core/stage/drive.js +0 -77
- package/dist/core/stage/finish-when.d.ts +0 -20
- package/dist/core/stage/finish-when.js +0 -82
- package/dist/core/stage/flatten.d.ts +0 -27
- package/dist/core/stage/flatten.js +0 -464
- package/dist/core/stage/index.d.ts +0 -11
- package/dist/core/stage/index.js +0 -10
- package/dist/core/stage/simulate.d.ts +0 -24
- package/dist/core/stage/simulate.js +0 -33
- package/dist/core/stage/transfer-fields.d.ts +0 -14
- package/dist/core/stage/transfer-fields.js +0 -88
- package/dist/core/stage/types.d.ts +0 -177
- package/dist/core/stage/types.js +0 -2
- package/dist/core/stage/validate.d.ts +0 -11
- package/dist/core/stage/validate.js +0 -226
- package/dist/core/stage/walk.d.ts +0 -34
- package/dist/core/stage/walk.js +0 -96
- package/dist/fn-context/rpc/integration/list-bindings.d.ts +0 -21
- package/dist/fn-context/system-args.d.ts +0 -6
- package/dist/fn-context/system-args.js +0 -14
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
import type { SystemContext } from '../context/types.js';
|
|
2
|
+
import type { Db, ReadDb } from '../page/define.js';
|
|
3
|
+
import type { Id, PageTablesDesc, TypedDb, TypedReadDb } from '../page/typed.js';
|
|
4
|
+
import type { ContactSchedule } from '../slot/schema.js';
|
|
5
|
+
/** Reserved export of `sequences/<id>/orchestrator.ts` and its name in the build's `functions`. */
|
|
6
|
+
export declare const ORCHESTRATOR_FUNCTION = "orchestrator";
|
|
7
|
+
/** `orchestrator.ts`'s required `contacts` export: its name in the build's `functions`. */
|
|
8
|
+
export declare const ORCHESTRATOR_CONTACTS_FUNCTION = "orchestratorContacts";
|
|
9
|
+
/** `ctx.meta.entry` / RunScope entry of a Case Orchestrator call. */
|
|
10
|
+
export declare const ORCHESTRATOR_ENTRY = "orchestrator";
|
|
11
|
+
/** `SequenceBuild.orchestrator`: the entry point, and the function that says whom a Run may contact. */
|
|
12
|
+
export type CaseOrchestratorManifest = {
|
|
13
|
+
fn: string;
|
|
14
|
+
contactsFn: string;
|
|
15
|
+
};
|
|
16
|
+
/** Platform tools a Run may open. Names, descriptions, schemas and executors belong to the platform. */
|
|
17
|
+
export declare const CASE_ORCHESTRATOR_TOOL_NAMES: readonly ['readExchange', 'searchExchanges', 'updateSlots', 'scheduleCall', 'scheduleSms', 'scheduleEmail', 'scheduleUpdateSlots', 'rescheduleAction', 'cancelScheduledAction', 'scheduleNextSequence', 'closeInstance', 'scheduleWake', 'cancelWake'];
|
|
18
|
+
export type CaseOrchestratorToolName = (typeof CASE_ORCHESTRATOR_TOOL_NAMES)[number];
|
|
19
|
+
/** A reference to one platform tool, from `tools.*()`. */
|
|
20
|
+
export type ToolRef<N extends CaseOrchestratorToolName = CaseOrchestratorToolName> = {
|
|
21
|
+
kind: 'tool';
|
|
22
|
+
name: N;
|
|
23
|
+
};
|
|
24
|
+
/** Channels the Agent can contact a contact on. */
|
|
25
|
+
export type ContactChannel = 'call' | 'sms' | 'email';
|
|
26
|
+
/**
|
|
27
|
+
* Kinds of actions the Agent can schedule: contacting a contact, slot writes at a later time,
|
|
28
|
+
* handing the instance over to the next sequence (14-sequence-instance §4.3), or waking the
|
|
29
|
+
* Orchestrator up (`wake`, 25 §6.3).
|
|
30
|
+
*/
|
|
31
|
+
export type ScheduledActionKind = ContactChannel | 'update_slots' | 'next_sequence' | 'wake';
|
|
32
|
+
/** Fields every trigger has. `key` is a stable event id: triggers with the same key merge into one. */
|
|
33
|
+
type TriggerBase = {
|
|
34
|
+
key: string;
|
|
35
|
+
occurredAt: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Why a Run started. Handed to `orchestrator` as is, so it is a public contract: grow it only
|
|
39
|
+
* (new `type`s, new optional fields); never rename or remove.
|
|
40
|
+
*/
|
|
41
|
+
export type RunTrigger = TriggerBase & ({
|
|
42
|
+
type: 'call.ended';
|
|
43
|
+
exchangeId: string;
|
|
44
|
+
direction: 'inbound' | 'outbound';
|
|
45
|
+
/** Null when the call never connected. Read it with `ctx.api.db.session.findUnique({ where: { id } })`. */
|
|
46
|
+
sessionId: Id<'session'> | null;
|
|
47
|
+
/** Set when the Agent scheduled this call. */
|
|
48
|
+
scheduledActionId: string | null;
|
|
49
|
+
/**
|
|
50
|
+
* `'connected'` when a session opened (corresponds to `result === 'answered'` on `ExchangeEvent`);
|
|
51
|
+
* `'voicemail'` when a message was left on it, `'screened'` when only a call-screening assistant
|
|
52
|
+
* answered (25 §13).
|
|
53
|
+
*/
|
|
54
|
+
result: 'connected' | 'no-answer' | 'busy' | 'failed' | 'voicemail' | 'screened';
|
|
55
|
+
}
|
|
56
|
+
/** An outbound SMS was handed to the provider, or failed to send. */
|
|
57
|
+
| {
|
|
58
|
+
type: 'sms.sent';
|
|
59
|
+
exchangeId: string;
|
|
60
|
+
scheduledActionId: string | null;
|
|
61
|
+
result: 'sent' | 'failed';
|
|
62
|
+
/** Provider or platform error code when `result === 'failed'`; null otherwise. */
|
|
63
|
+
errorCode: string | null;
|
|
64
|
+
}
|
|
65
|
+
/** An outbound email was handed to the provider, or failed to send. */
|
|
66
|
+
| {
|
|
67
|
+
type: 'email.sent';
|
|
68
|
+
exchangeId: string;
|
|
69
|
+
scheduledActionId: string | null;
|
|
70
|
+
result: 'sent' | 'failed';
|
|
71
|
+
/** Provider or platform error code when `result === 'failed'`; null otherwise. */
|
|
72
|
+
errorCode: string | null;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One SMS run finished: its hooks ran and the reply was stored (21 §6.1). `exchangeId` holds the
|
|
76
|
+
* text line's exchange id (`sms:<our number id>:<their number>`, 21 §12.3).
|
|
77
|
+
*/
|
|
78
|
+
| {
|
|
79
|
+
type: 'sms.turn-ended';
|
|
80
|
+
exchangeId: string;
|
|
81
|
+
runId: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* One email run finished: its hooks ran and the reply was stored (21 §6.1). `exchangeId` holds the
|
|
85
|
+
* thread's exchange id (`email:<emailThreadId>`, 21 §12.3).
|
|
86
|
+
*/
|
|
87
|
+
| {
|
|
88
|
+
type: 'email.turn-ended';
|
|
89
|
+
exchangeId: string;
|
|
90
|
+
runId: string;
|
|
91
|
+
} | {
|
|
92
|
+
type: 'contact.communication-preferences.updated';
|
|
93
|
+
contactId: Id<'contact'>;
|
|
94
|
+
/** The contact's `Record.version` after the preference write committed. */
|
|
95
|
+
contactVersion: number;
|
|
96
|
+
}
|
|
97
|
+
/** The instance started (a first conversation, a script, a hand-over). */
|
|
98
|
+
| {
|
|
99
|
+
type: 'instance_started';
|
|
100
|
+
}
|
|
101
|
+
/** Requested after an edit in the frontend. */
|
|
102
|
+
| {
|
|
103
|
+
type: 'manual';
|
|
104
|
+
requestedBy: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* A scheduled action failed its checks when it came due (the instance closed, the contact left
|
|
108
|
+
* the page, an opt-out, a deadline passed, a write no longer valid, …): nothing was done.
|
|
109
|
+
*/
|
|
110
|
+
| {
|
|
111
|
+
type: 'scheduled_action.failed';
|
|
112
|
+
scheduledActionId: string;
|
|
113
|
+
kind: ScheduledActionKind;
|
|
114
|
+
errorCode: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Company code told the instance about something outside the platform (a payment posted, a CRM
|
|
118
|
+
* change): `ctx.api.instances.notify` from a webhook, a function or an event handler (25 §6.2).
|
|
119
|
+
* Only a label: the facts are in the records, read them with `ctx.api.db`.
|
|
120
|
+
*/
|
|
121
|
+
| {
|
|
122
|
+
type: 'external';
|
|
123
|
+
reason: string;
|
|
124
|
+
}
|
|
125
|
+
/** A wake-up the Orchestrator booked with `scheduleWake` came due (25 §6.3). */
|
|
126
|
+
| {
|
|
127
|
+
type: 'timer';
|
|
128
|
+
name: string;
|
|
129
|
+
note: string | null;
|
|
130
|
+
scheduledActionId: string;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* A call, texts or an email came in while the case was fully paused (29 §4.1): the AI did not take
|
|
134
|
+
* it; a call went to the fallback number, a message was kept unanswered. Told once the pause is lifted.
|
|
135
|
+
*/
|
|
136
|
+
| {
|
|
137
|
+
type: 'inbound.paused';
|
|
138
|
+
channel: ContactChannel;
|
|
139
|
+
exchangeId: string;
|
|
140
|
+
});
|
|
141
|
+
export type RunTriggerType = RunTrigger['type'];
|
|
142
|
+
/** A stored action's timing: `at`, the exact time (ISO 8601) it runs (25 §4). */
|
|
143
|
+
export type ScheduledActionTiming = {
|
|
144
|
+
mode: 'at';
|
|
145
|
+
at: string;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* What a contact (call / SMS / email) was asked for: its stored `input`. `timing` says when: it is
|
|
149
|
+
* what two requests are compared on and what a reschedule replaces; the other keys ride along.
|
|
150
|
+
*/
|
|
151
|
+
export type ContactActionInput = {
|
|
152
|
+
timing: ScheduledActionTiming;
|
|
153
|
+
/** Why it happens; the conversation it opens gets it too. */
|
|
154
|
+
note?: string;
|
|
155
|
+
/** The contact's address to use: its `phone` (a call, a text) or `email`, the default. */
|
|
156
|
+
to?: string;
|
|
157
|
+
/** Our number to use; default the contact's assigned number, else the sequence's outbound numbers. */
|
|
158
|
+
from?: string;
|
|
159
|
+
/**
|
|
160
|
+
* An agreed follow-up (the party asked for it or agreed to it): where, in which message (its
|
|
161
|
+
* time, ISO 8601) and in which words they said it. Absent for a regular follow-up.
|
|
162
|
+
* docs/design/09-agreed-follow-up.md
|
|
163
|
+
*/
|
|
164
|
+
agreement?: {
|
|
165
|
+
exchangeId: string;
|
|
166
|
+
agreedAt: string;
|
|
167
|
+
customerQuote: string;
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
/** What scheduled slot writes (`update_slots`) were asked for: when, what is written, and why. */
|
|
171
|
+
export type UpdateSlotsActionInput = {
|
|
172
|
+
timing: {
|
|
173
|
+
mode: 'at';
|
|
174
|
+
at: string;
|
|
175
|
+
};
|
|
176
|
+
writes: SlotWriteInput[];
|
|
177
|
+
reason: string;
|
|
178
|
+
};
|
|
179
|
+
/** What a hand-over (`next_sequence`) was asked for: when, to which sequence, on which row, its variables, and why. */
|
|
180
|
+
export type NextSequenceActionInput = {
|
|
181
|
+
timing: {
|
|
182
|
+
mode: 'at';
|
|
183
|
+
at: string;
|
|
184
|
+
};
|
|
185
|
+
/** Name of the sequence the next instance runs. */
|
|
186
|
+
sequence: string;
|
|
187
|
+
/** The row the next instance starts on, when one was named; else this instance's own. */
|
|
188
|
+
subjectRecordId?: string;
|
|
189
|
+
variables?: Record<string, unknown>;
|
|
190
|
+
reason: string;
|
|
191
|
+
};
|
|
192
|
+
/** What a wake-up (`wake`) was booked for: when, its name (one pending per name), and why. */
|
|
193
|
+
export type WakeActionInput = {
|
|
194
|
+
timing: {
|
|
195
|
+
mode: 'at';
|
|
196
|
+
at: string;
|
|
197
|
+
};
|
|
198
|
+
name: string;
|
|
199
|
+
note?: string;
|
|
200
|
+
};
|
|
201
|
+
/** Each kind's stored `input`. */
|
|
202
|
+
export type ScheduledActionInputs = {
|
|
203
|
+
call: ContactActionInput;
|
|
204
|
+
sms: ContactActionInput;
|
|
205
|
+
email: ContactActionInput;
|
|
206
|
+
update_slots: UpdateSlotsActionInput;
|
|
207
|
+
next_sequence: NextSequenceActionInput;
|
|
208
|
+
wake: WakeActionInput;
|
|
209
|
+
};
|
|
210
|
+
export type ScheduledActionInput = ScheduledActionInputs[ScheduledActionKind];
|
|
211
|
+
/** A pending contact: who and its `input`. */
|
|
212
|
+
export type ContactActionView = {
|
|
213
|
+
id: string;
|
|
214
|
+
kind: ContactChannel;
|
|
215
|
+
/** The contact to reach. */
|
|
216
|
+
contactId: string;
|
|
217
|
+
/**
|
|
218
|
+
* When it runs (ISO 8601): `input.timing.at`, as given (25 §4).
|
|
219
|
+
*/
|
|
220
|
+
scheduledFor: string;
|
|
221
|
+
input: ContactActionInput;
|
|
222
|
+
};
|
|
223
|
+
/** Pending scheduled slot writes: instance-level, no contact. */
|
|
224
|
+
export type UpdateSlotsActionView = {
|
|
225
|
+
id: string;
|
|
226
|
+
kind: 'update_slots';
|
|
227
|
+
contactId: null;
|
|
228
|
+
/** Execution time (`input.timing.at`, ISO 8601). */
|
|
229
|
+
scheduledFor: string;
|
|
230
|
+
input: UpdateSlotsActionInput;
|
|
231
|
+
};
|
|
232
|
+
/** A pending hand-over to the next sequence: instance-level, no contact. */
|
|
233
|
+
export type NextSequenceActionView = {
|
|
234
|
+
id: string;
|
|
235
|
+
kind: 'next_sequence';
|
|
236
|
+
contactId: null;
|
|
237
|
+
/** Execution time (`input.timing.at`, ISO 8601). */
|
|
238
|
+
scheduledFor: string;
|
|
239
|
+
input: NextSequenceActionInput;
|
|
240
|
+
};
|
|
241
|
+
/** A pending wake-up of the Orchestrator: instance-level, no contact. */
|
|
242
|
+
export type WakeActionView = {
|
|
243
|
+
id: string;
|
|
244
|
+
kind: 'wake';
|
|
245
|
+
contactId: null;
|
|
246
|
+
/** When it wakes the Orchestrator (`input.timing.at`, ISO 8601). */
|
|
247
|
+
scheduledFor: string;
|
|
248
|
+
input: WakeActionInput;
|
|
249
|
+
};
|
|
250
|
+
/** A scheduled action still active when the Run input is built; `kind` tells which `input` it has. */
|
|
251
|
+
export type ScheduledActionView = ContactActionView | UpdateSlotsActionView | NextSequenceActionView | WakeActionView;
|
|
252
|
+
/** An agreed follow-up (`input.agreement` set) that already ran, failed or was cancelled. */
|
|
253
|
+
export type FinishedAgreedActionView = ContactActionView & {
|
|
254
|
+
status: 'completed' | 'failed' | 'cancelled';
|
|
255
|
+
finishedAt: string;
|
|
256
|
+
};
|
|
257
|
+
/** One real contact (a call, or a sent / received SMS or email). */
|
|
258
|
+
export type ExchangeEvent = {
|
|
259
|
+
exchangeId: string;
|
|
260
|
+
channel: 'call' | 'sms' | 'email';
|
|
261
|
+
direction: 'inbound' | 'outbound';
|
|
262
|
+
occurredAt: string;
|
|
263
|
+
/** Day of the interaction, counting the first interaction's day as 1. */
|
|
264
|
+
dayNumber: number;
|
|
265
|
+
/**
|
|
266
|
+
* Outcome of the contact:
|
|
267
|
+
* - `call`: `'answered'` | `'no-answer'` (includes busy) | `'failed'`
|
|
268
|
+
* - outbound `sms` / `email`: `'sent'` | `'failed'`
|
|
269
|
+
* - inbound `sms` / `email`: `'received'`
|
|
270
|
+
*/
|
|
271
|
+
result: 'answered' | 'no-answer' | 'sent' | 'failed' | 'received';
|
|
272
|
+
/** A call's length in seconds; null for SMS and email, or a call whose length is not known yet. */
|
|
273
|
+
durationSec: number | null;
|
|
274
|
+
/** Set when the Agent scheduled it. */
|
|
275
|
+
scheduledActionId: string | null;
|
|
276
|
+
};
|
|
277
|
+
/** Exchange counts, last events by kind, and recent timeline for the Case (`all`) or one party. */
|
|
278
|
+
export type ActivityStats = {
|
|
279
|
+
/** Timestamp of the very first interaction (day 1); null when none happened yet. */
|
|
280
|
+
firstAt: string | null;
|
|
281
|
+
/** Real contacts counted, of which `recent` holds the newest. */
|
|
282
|
+
total: number;
|
|
283
|
+
/** Today's day number; 1 when nothing happened yet. */
|
|
284
|
+
dayNumber: number;
|
|
285
|
+
/** Today's interaction counts: the party's contact timezone, or the primary party's for `all`. */
|
|
286
|
+
today: {
|
|
287
|
+
calls: number;
|
|
288
|
+
answeredCalls: number;
|
|
289
|
+
smsOut: number;
|
|
290
|
+
smsIn: number;
|
|
291
|
+
emailsOut: number;
|
|
292
|
+
emailsIn: number;
|
|
293
|
+
};
|
|
294
|
+
/** Most recent event of each kind (null when none happened yet). */
|
|
295
|
+
last: {
|
|
296
|
+
/** Most recent exchange across all channels and directions. */
|
|
297
|
+
exchange: ExchangeEvent | null;
|
|
298
|
+
/** Most recent inbound exchange (call, SMS, or email from the contact). */
|
|
299
|
+
inbound: ExchangeEvent | null;
|
|
300
|
+
/** Most recent outbound exchange (call, SMS, or email to the contact). */
|
|
301
|
+
outbound: ExchangeEvent | null;
|
|
302
|
+
/** Most recent call (inbound or outbound, answered or not). */
|
|
303
|
+
call: ExchangeEvent | null;
|
|
304
|
+
/** Most recent call that was answered (`result === 'answered'`). */
|
|
305
|
+
answeredCall: ExchangeEvent | null;
|
|
306
|
+
/** Most recent SMS (inbound or outbound). */
|
|
307
|
+
sms: ExchangeEvent | null;
|
|
308
|
+
/** Most recent email (inbound or outbound). */
|
|
309
|
+
email: ExchangeEvent | null;
|
|
310
|
+
};
|
|
311
|
+
/** Most recent events, oldest first (at most {@link ACTIVITY_RECENT_LIMIT}). */
|
|
312
|
+
recent: readonly ExchangeEvent[];
|
|
313
|
+
};
|
|
314
|
+
export declare const ACTIVITY_RECENT_LIMIT = 50;
|
|
315
|
+
/** How far back `recentAgreedActions` reaches. */
|
|
316
|
+
export declare const RECENT_AGREED_ACTIONS_DAYS = 14;
|
|
317
|
+
/**
|
|
318
|
+
* Why a channel cannot be used: no phone / email on file, the contact opted out of it, or the address
|
|
319
|
+
* cannot take it (a number Twilio said is a landline or out of service, 21 §5.10).
|
|
320
|
+
*/
|
|
321
|
+
export type ChannelUnavailableReason = 'no_address' | 'opted_out' | 'unreachable';
|
|
322
|
+
export type ChannelAvailability = {
|
|
323
|
+
/** The address exists and the channel is not opted out (globally or alone). */
|
|
324
|
+
channels: Record<ContactChannel, boolean>;
|
|
325
|
+
/** Why each unavailable channel is unavailable. */
|
|
326
|
+
unavailableChannels: Partial<Record<ContactChannel, ChannelUnavailableReason>>;
|
|
327
|
+
};
|
|
328
|
+
/** One party's activity, counted from its own first contact, in its own timezone. */
|
|
329
|
+
export type PartyActivity = ActivityStats & ChannelAvailability & {
|
|
330
|
+
contactId: string;
|
|
331
|
+
timezone: string;
|
|
332
|
+
/** Local time of the party, ISO 8601 with offset. */
|
|
333
|
+
localNow: string;
|
|
334
|
+
localWeekday: string;
|
|
335
|
+
contactHours: PartyContactHours;
|
|
336
|
+
};
|
|
337
|
+
type ContactHoursWeekday = 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun';
|
|
338
|
+
/**
|
|
339
|
+
* When a party may be contacted, in their timezone: their `contact_schedule` within the platform
|
|
340
|
+
* window, or default working hours when they have none. The platform places regular follow-ups (and
|
|
341
|
+
* agreed ones without an exact time) inside these hours.
|
|
342
|
+
*/
|
|
343
|
+
export type PartyContactHours = {
|
|
344
|
+
/**
|
|
345
|
+
* `contact_schedule`: the party's own schedule; `none`: none on file (every day all day). The
|
|
346
|
+
* company's rules for when to reach them are not here (25 §3): they are the company's own.
|
|
347
|
+
*/
|
|
348
|
+
source: 'contact_schedule' | 'none';
|
|
349
|
+
/** Each weekday's windows; an empty list: never on that weekday. */
|
|
350
|
+
weekly: Readonly<Record<ContactHoursWeekday, readonly {
|
|
351
|
+
start: string;
|
|
352
|
+
end: string;
|
|
353
|
+
}[]>>;
|
|
354
|
+
/** Dates from today on whose hours replace the weekly ones, soonest first; an empty list: not that day. */
|
|
355
|
+
dateOverrides: readonly {
|
|
356
|
+
date: string;
|
|
357
|
+
windows: readonly {
|
|
358
|
+
start: string;
|
|
359
|
+
end: string;
|
|
360
|
+
}[];
|
|
361
|
+
}[];
|
|
362
|
+
};
|
|
363
|
+
/** Exchange aggregates the platform computes when a Run starts. */
|
|
364
|
+
export type CaseActivity = {
|
|
365
|
+
/** Timezone of the instance-level day numbers: the first contact's of the Run's `contacts`. */
|
|
366
|
+
timezone: string;
|
|
367
|
+
all: ActivityStats;
|
|
368
|
+
/** Every contact the Run may reach (orchestrator.ts's `contacts`), keyed by contactId, in that order. */
|
|
369
|
+
byContact: Readonly<Record<string, PartyActivity>>;
|
|
370
|
+
};
|
|
371
|
+
export declare const EMPTY_CASE_ACTIVITY: CaseActivity;
|
|
372
|
+
/** Frozen inputs of one orchestration Run. */
|
|
373
|
+
export type CaseOrchestratorParams = {
|
|
374
|
+
/** This Run's triggers, frozen when it started, oldest first. */
|
|
375
|
+
triggers: readonly RunTrigger[];
|
|
376
|
+
/**
|
|
377
|
+
* Scheduled actions still waiting to run when the Run started. Writes through `ctx.api.tools`
|
|
378
|
+
* do not update it.
|
|
379
|
+
*/
|
|
380
|
+
scheduledActions: readonly ScheduledActionView[];
|
|
381
|
+
/** Agreed follow-ups that finished in the last {@link RECENT_AGREED_ACTIONS_DAYS} days, newest first: a promise already kept is not booked again. */
|
|
382
|
+
recentAgreedActions: readonly FinishedAgreedActionView[];
|
|
383
|
+
activity: CaseActivity;
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* The Orchestrator's API: everything a function's `ctx.api` has (25 §7: the platform surfaces, every
|
|
387
|
+
* integration, `log`, the company's records), so a function of the sequence can be called from the
|
|
388
|
+
* Orchestrator with its `ctx` and works the same, plus the awaitable platform `tools`. Like a
|
|
389
|
+
* function's, `call` / `sms` / `email` read the history of the whole company and environment: pass
|
|
390
|
+
* `instanceId: ctx.meta.instanceId` to `list` for this instance's. `db` reads the records the way a page script does
|
|
391
|
+
* (Prisma-shaped, every `where` anchored) and changes them the way a page action does (`create` /
|
|
392
|
+
* `update` / `delete`), any row of the company and environment. Each call is one request: a write is
|
|
393
|
+
* its own transaction, and the same write sent again within the Run is not made twice; a Run run again
|
|
394
|
+
* (after it failed) writes again, so read first, then create.
|
|
395
|
+
* `D` is the sequence's `PageTables` (`__gen` binds it): tables, fields and ids typed.
|
|
396
|
+
*/
|
|
397
|
+
export type CaseOrchestratorApi<D extends PageTablesDesc | undefined = undefined> = Omit<SystemContext['api'], 'db'> & {
|
|
398
|
+
/**
|
|
399
|
+
* The platform's tools, the Agent's too: scheduling goes through them, where opt-outs and the
|
|
400
|
+
* instance's state are checked. A text or email sent with an integration directly is not.
|
|
401
|
+
*/
|
|
402
|
+
tools: CaseOrchestratorTools;
|
|
403
|
+
db: D extends PageTablesDesc ? TypedDb<D> : Db;
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* `ctx` of `orchestrator`: a function's `ctx`, so a function can be
|
|
407
|
+
* called with it, plus `params` and `api.tools`. `D` types `ctx.api.db`.
|
|
408
|
+
*/
|
|
409
|
+
export type CaseOrchestratorContext<D extends PageTablesDesc | undefined = undefined> = Omit<SystemContext, 'api'> & {
|
|
410
|
+
api: CaseOrchestratorApi<D>;
|
|
411
|
+
params: CaseOrchestratorParams;
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* When a scheduled action runs (25 §4): `at`, an exact instant (ISO 8601 with an offset or Z; its
|
|
415
|
+
* offset need not be the contact's); pass the current time for now. It runs then: the platform does
|
|
416
|
+
* not check contact hours (25 §3). The company's rules decide `at`: `nextContactTime` for the first
|
|
417
|
+
* allowed time, `randomTimeBetween` to spread contacts.
|
|
418
|
+
*/
|
|
419
|
+
export type ScheduleTiming = {
|
|
420
|
+
at: string;
|
|
421
|
+
};
|
|
422
|
+
/**
|
|
423
|
+
* What makes a contact an agreed follow-up: the party asked for it or agreed to it in
|
|
424
|
+
* `agreedInExchangeId`, in their message at `agreedAt`, in the words `customerQuote` (all three
|
|
425
|
+
* together; the platform does not check them, and `agreedAt` tells agreements apart). Like any
|
|
426
|
+
* action it runs at its `at`; an opt-out still stops it.
|
|
427
|
+
* docs/design/09-agreed-follow-up.md
|
|
428
|
+
*/
|
|
429
|
+
export type AgreementFields = {
|
|
430
|
+
agreedInExchangeId?: string;
|
|
431
|
+
/** The time of the party's message, as the conversation shows it, ISO 8601 with an offset or Z. */
|
|
432
|
+
agreedAt?: string;
|
|
433
|
+
customerQuote?: string;
|
|
434
|
+
/** Why this contact happens; the conversation it opens gets it. Any action may have one. */
|
|
435
|
+
note?: string;
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* Whom to contact (one of the Run's `contacts`) and, optionally, the addresses: `to` one of the
|
|
439
|
+
* contact's phone / email fields' values (default: its `phone` / `email`), `from` one of our numbers
|
|
440
|
+
* (default: the contact's assigned number, else this sequence's outbound numbers, 14 §10).
|
|
441
|
+
*/
|
|
442
|
+
export type ScheduleActionInput = {
|
|
443
|
+
contactId: string;
|
|
444
|
+
to?: string;
|
|
445
|
+
from?: string;
|
|
446
|
+
} & ScheduleTiming & AgreementFields;
|
|
447
|
+
/** One field on an existing row, as `updateSlots` takes it. */
|
|
448
|
+
export type SlotFieldWriteInput = {
|
|
449
|
+
/** `table.field`. */
|
|
450
|
+
path: string;
|
|
451
|
+
value?: string | number | boolean | string[] | null;
|
|
452
|
+
state?: 'filled' | 'empty' | 'asked_unknown' | 'declined';
|
|
453
|
+
reason?: string;
|
|
454
|
+
/** A multi-row table (`contact` included): the existing row's id. */
|
|
455
|
+
rowId?: string;
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* A new row of a multi-row table other than contact. Any field, conversation ones included; its
|
|
459
|
+
* parent when the parent is not the business root (which the platform fills).
|
|
460
|
+
*/
|
|
461
|
+
export type SlotInsertInput = {
|
|
462
|
+
insert: string;
|
|
463
|
+
values: Record<string, string | number | boolean | string[] | null | ContactSchedule>;
|
|
464
|
+
};
|
|
465
|
+
/** One slot write, as `updateSlots` and `scheduleUpdateSlots` take it. */
|
|
466
|
+
export type SlotWriteInput = SlotFieldWriteInput | SlotInsertInput;
|
|
467
|
+
/**
|
|
468
|
+
* Slot writes to make at a set time, and why. Validated now, written as given when due (checked
|
|
469
|
+
* again then); nothing is re-decided, so cancel or reschedule it when it no longer fits. Not a
|
|
470
|
+
* contact: no window or opt-out applies.
|
|
471
|
+
*/
|
|
472
|
+
export type ScheduleUpdateSlotsInput = {
|
|
473
|
+
at: string;
|
|
474
|
+
writes: SlotWriteInput[];
|
|
475
|
+
reason: string;
|
|
476
|
+
};
|
|
477
|
+
/**
|
|
478
|
+
* Hand the instance over to the next sequence at `at` (now when left out): when due, this instance
|
|
479
|
+
* closes (`superseded`) and an instance of `sequence` starts, in one transaction. It starts on
|
|
480
|
+
* `subjectRecordId`, a row of the table `sequence` declares as `subject`; left out, on this
|
|
481
|
+
* instance's own row, which then must be of that table (`subject_required`). A row with an active
|
|
482
|
+
* instance is refused (`subject_busy`).
|
|
483
|
+
*/
|
|
484
|
+
export type ScheduleNextSequenceInput = {
|
|
485
|
+
sequence: string;
|
|
486
|
+
subjectRecordId?: string;
|
|
487
|
+
at?: string;
|
|
488
|
+
variables?: Record<string, unknown>;
|
|
489
|
+
reason: string;
|
|
490
|
+
};
|
|
491
|
+
/** One utterance of a call, or one SMS / email, inside an exchange. */
|
|
492
|
+
export type ExchangeEntry = {
|
|
493
|
+
at: string;
|
|
494
|
+
/** `party`: the person on the other side; `ai`: what the platform said or sent. */
|
|
495
|
+
speaker: 'party' | 'ai';
|
|
496
|
+
text: string;
|
|
497
|
+
/** Set when `text` was cut to fit the result. */
|
|
498
|
+
truncated?: true;
|
|
499
|
+
};
|
|
500
|
+
/** One exchange's content, a window of its entries at a time, newest window first. */
|
|
501
|
+
export type ReadExchangeResult = {
|
|
502
|
+
exchangeId: string;
|
|
503
|
+
contactId: string | null;
|
|
504
|
+
direction: 'inbound' | 'outbound';
|
|
505
|
+
occurredAt: string;
|
|
506
|
+
totalEntries: number;
|
|
507
|
+
/** These are entries [from, to) of all of them; `from > 0`: pass `before: from` for earlier ones. */
|
|
508
|
+
range: {
|
|
509
|
+
from: number;
|
|
510
|
+
to: number;
|
|
511
|
+
};
|
|
512
|
+
entries: ExchangeEntry[];
|
|
513
|
+
} & ({
|
|
514
|
+
channel: 'call';
|
|
515
|
+
/** Null while the call has not happened yet (still dialing or ringing). */
|
|
516
|
+
result: ExchangeEvent['result'] | null;
|
|
517
|
+
durationSec: number | null;
|
|
518
|
+
} | {
|
|
519
|
+
channel: 'sms';
|
|
520
|
+
} | {
|
|
521
|
+
channel: 'email';
|
|
522
|
+
subject: string | null;
|
|
523
|
+
});
|
|
524
|
+
/** A {@link ExchangeEvent} as `searchExchanges` returns it. */
|
|
525
|
+
export type ExchangeSearchHit = Omit<ExchangeEvent, 'dayNumber' | 'durationSec'> & {
|
|
526
|
+
contactId: string | null;
|
|
527
|
+
/** The case it was on (with scope `contact`, possibly not this one); null when none. */
|
|
528
|
+
instanceId: string | null;
|
|
529
|
+
/** Calls only. */
|
|
530
|
+
durationSec?: number | null;
|
|
531
|
+
/** Emails only. */
|
|
532
|
+
subject?: string | null;
|
|
533
|
+
/** SMS / email: the start of the message body. */
|
|
534
|
+
preview?: string | null;
|
|
535
|
+
};
|
|
536
|
+
export type SearchExchangesResult = {
|
|
537
|
+
/** Every event matching the filters, not only this page. */
|
|
538
|
+
total: number;
|
|
539
|
+
/** Newest first. */
|
|
540
|
+
events: ExchangeSearchHit[];
|
|
541
|
+
/** Pass as `before` for the next (older) page; null on the last page. */
|
|
542
|
+
nextBefore: string | null;
|
|
543
|
+
};
|
|
544
|
+
/** Each tool's arguments: the same parameters the model sends. The tool validates them when it runs. */
|
|
545
|
+
export type ToolCallArgs = {
|
|
546
|
+
/** `before`: exclusive upper entry index for paging back (pass `range.from` from the previous read). */
|
|
547
|
+
readExchange: {
|
|
548
|
+
exchangeId: string;
|
|
549
|
+
before?: number;
|
|
550
|
+
};
|
|
551
|
+
searchExchanges: {
|
|
552
|
+
/** `occurredAt >= from`, ISO 8601 with an offset or Z. */
|
|
553
|
+
from?: string;
|
|
554
|
+
/** `occurredAt < to`, ISO 8601 with an offset or Z. */
|
|
555
|
+
to?: string;
|
|
556
|
+
contactId?: string;
|
|
557
|
+
channel?: ExchangeEvent['channel'];
|
|
558
|
+
direction?: ExchangeEvent['direction'];
|
|
559
|
+
result?: ExchangeEvent['result'][];
|
|
560
|
+
scheduledActionId?: string;
|
|
561
|
+
/** `case` (default): this case only; `contact`: every case of this case's contacts (27 §5.4). */
|
|
562
|
+
scope?: 'case' | 'contact';
|
|
563
|
+
limit?: number;
|
|
564
|
+
/** Pagination cursor from a previous result's `nextBefore`. */
|
|
565
|
+
before?: string;
|
|
566
|
+
};
|
|
567
|
+
updateSlots: {
|
|
568
|
+
writes: SlotWriteInput[];
|
|
569
|
+
};
|
|
570
|
+
scheduleCall: ScheduleActionInput;
|
|
571
|
+
scheduleSms: ScheduleActionInput;
|
|
572
|
+
scheduleEmail: ScheduleActionInput;
|
|
573
|
+
scheduleUpdateSlots: ScheduleUpdateSlotsInput;
|
|
574
|
+
rescheduleAction: {
|
|
575
|
+
scheduledActionId: string;
|
|
576
|
+
} & ScheduleTiming & {
|
|
577
|
+
/** Required to move an agreed follow-up. */
|
|
578
|
+
reason?: string;
|
|
579
|
+
/** The party changed an agreed follow-up: where, in which message and in which words (all three). */
|
|
580
|
+
agreedInExchangeId?: string;
|
|
581
|
+
agreedAt?: string;
|
|
582
|
+
customerQuote?: string;
|
|
583
|
+
};
|
|
584
|
+
cancelScheduledAction: {
|
|
585
|
+
scheduledActionId: string;
|
|
586
|
+
reason: string;
|
|
587
|
+
};
|
|
588
|
+
scheduleNextSequence: ScheduleNextSequenceInput;
|
|
589
|
+
/** End this instance (completed / cancelled / a short text): pending actions are cancelled. */
|
|
590
|
+
/** `reason`: why, 1–64 characters (`'signed up'`, `'asked us to stop'`). */
|
|
591
|
+
closeInstance: {
|
|
592
|
+
reason: string;
|
|
593
|
+
};
|
|
594
|
+
scheduleWake: ScheduleWakeInput;
|
|
595
|
+
/** Cancel the pending wake-up of this name, if there is one. */
|
|
596
|
+
cancelWake: {
|
|
597
|
+
name: string;
|
|
598
|
+
reason?: string;
|
|
599
|
+
};
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* `scheduleWake`: wake this instance's Orchestrator at `at` with a `timer` trigger (25 §6.3). It
|
|
603
|
+
* contacts no one, so it runs exactly then, at any hour. One pending per `name`: booking the same
|
|
604
|
+
* name again moves it. Cancelled with the instance.
|
|
605
|
+
*/
|
|
606
|
+
export type ScheduleWakeInput = {
|
|
607
|
+
/** Its name in this instance (e.g. `payment-check`); the trigger carries it. */
|
|
608
|
+
name: string;
|
|
609
|
+
/** ISO 8601 with an offset or Z; at most 90 days ahead. */
|
|
610
|
+
at: string;
|
|
611
|
+
/** Why, for the Run it starts. */
|
|
612
|
+
note?: string;
|
|
613
|
+
};
|
|
614
|
+
export type WakeResult = {
|
|
615
|
+
/** `rescheduled`: a wake-up of this name was pending and moved; `existing`: it already had this time and note. */
|
|
616
|
+
outcome: 'created' | 'rescheduled' | 'existing';
|
|
617
|
+
scheduledActionId: string;
|
|
618
|
+
scheduledFor: string;
|
|
619
|
+
};
|
|
620
|
+
export type ScheduledResult = {
|
|
621
|
+
/**
|
|
622
|
+
* `existing`: this contact and channel already have an active action with the same timing, or
|
|
623
|
+
* these agreed words were already booked.
|
|
624
|
+
*/
|
|
625
|
+
outcome: 'created' | 'existing';
|
|
626
|
+
scheduledActionId: string;
|
|
627
|
+
scheduledFor: string;
|
|
628
|
+
/**
|
|
629
|
+
* The contact's `Record.version` at the time the action was scheduled (`0` without a contact);
|
|
630
|
+
* for `existing`, the version recorded when it was first scheduled. Recorded only, not checked
|
|
631
|
+
* when the action fires.
|
|
632
|
+
*/
|
|
633
|
+
contactVersion: number;
|
|
634
|
+
/** An agreed follow-up replaced this pending regular follow-up on the same channel (it is cancelled). */
|
|
635
|
+
supersededScheduledActionId?: string;
|
|
636
|
+
};
|
|
637
|
+
export type RescheduledResult = {
|
|
638
|
+
/** `unchanged`: the action already had this timing. */
|
|
639
|
+
outcome: 'rescheduled' | 'unchanged';
|
|
640
|
+
scheduledActionId: string;
|
|
641
|
+
scheduledFor: string;
|
|
642
|
+
/** The `scheduledFor` timestamp before rescheduling (equals `scheduledFor` when `unchanged`). */
|
|
643
|
+
previousScheduledFor: string;
|
|
644
|
+
/** The contact's `Record.version` at the time of rescheduling (`0` without a contact). */
|
|
645
|
+
contactVersion: number;
|
|
646
|
+
};
|
|
647
|
+
export type ToolCallResult = {
|
|
648
|
+
readExchange: ReadExchangeResult;
|
|
649
|
+
searchExchanges: SearchExchangesResult;
|
|
650
|
+
updateSlots: {
|
|
651
|
+
outcome: 'written';
|
|
652
|
+
paths: string[];
|
|
653
|
+
inserts: string[];
|
|
654
|
+
};
|
|
655
|
+
scheduleCall: ScheduledResult;
|
|
656
|
+
scheduleSms: ScheduledResult;
|
|
657
|
+
scheduleEmail: ScheduledResult;
|
|
658
|
+
scheduleUpdateSlots: ScheduledResult;
|
|
659
|
+
rescheduleAction: RescheduledResult;
|
|
660
|
+
/** `too_late`: it already started; otherwise the action's final status. */
|
|
661
|
+
cancelScheduledAction: {
|
|
662
|
+
outcome: 'cancelled' | 'too_late' | 'completed' | 'failed';
|
|
663
|
+
scheduledActionId: string;
|
|
664
|
+
};
|
|
665
|
+
scheduleNextSequence: ScheduledResult;
|
|
666
|
+
closeInstance: {
|
|
667
|
+
outcome: 'closed' | 'already_closed';
|
|
668
|
+
cancelledScheduledActionIds: string[];
|
|
669
|
+
};
|
|
670
|
+
scheduleWake: WakeResult;
|
|
671
|
+
/** `not_pending`: no wake-up of that name was waiting (it never was, already ran, or was cancelled). */
|
|
672
|
+
cancelWake: {
|
|
673
|
+
outcome: 'cancelled' | 'not_pending';
|
|
674
|
+
scheduledActionId: string | null;
|
|
675
|
+
};
|
|
676
|
+
};
|
|
677
|
+
export type ToolResult<T> = {
|
|
678
|
+
ok: true;
|
|
679
|
+
value: T;
|
|
680
|
+
toolCallId: string;
|
|
681
|
+
} | {
|
|
682
|
+
ok: false;
|
|
683
|
+
error: {
|
|
684
|
+
code: string;
|
|
685
|
+
message: string;
|
|
686
|
+
};
|
|
687
|
+
toolCallId: string;
|
|
688
|
+
};
|
|
689
|
+
export type ToolCallOptions = {
|
|
690
|
+
/**
|
|
691
|
+
* Stable idempotency key within the Run: calling the same tool again with the same `callKey`
|
|
692
|
+
* and arguments replays the recorded result instead of executing twice; reusing it for another
|
|
693
|
+
* tool or other arguments fails with `idempotency_conflict`.
|
|
694
|
+
*/
|
|
695
|
+
callKey: string;
|
|
696
|
+
};
|
|
697
|
+
export type CaseOrchestratorTools = {
|
|
698
|
+
[N in CaseOrchestratorToolName]: (input: ToolCallArgs[N], options: ToolCallOptions) => Promise<ToolResult<ToolCallResult[N]>>;
|
|
699
|
+
};
|
|
700
|
+
/** An Agent Run request: the LLM decides which of `tools` to call. */
|
|
701
|
+
export type AgentRequest = {
|
|
702
|
+
kind: 'agent';
|
|
703
|
+
/** The whole user message the Agent reads, written by company code (docs/design/08-case-orchestrator.md §5.3). */
|
|
704
|
+
prompt: string;
|
|
705
|
+
/** The tools the Agent may call, from `tools.*()`. Left out: every platform tool; `[]`: none. */
|
|
706
|
+
tools?: readonly ToolRef[];
|
|
707
|
+
};
|
|
708
|
+
/** An AgentRequest as the platform runs it: `tools` resolved to the Agent's whitelist. */
|
|
709
|
+
export type ResolvedAgentRequest = AgentRequest & {
|
|
710
|
+
tools: readonly ToolRef[];
|
|
711
|
+
};
|
|
712
|
+
export type FinalOrchestrationResult = {
|
|
713
|
+
kind: 'final';
|
|
714
|
+
finalSummary: string;
|
|
715
|
+
};
|
|
716
|
+
export type CaseOrchestratorResult = AgentRequest | FinalOrchestrationResult;
|
|
717
|
+
/**
|
|
718
|
+
* What code working on a case receives as `c` — the Orchestrator and event handlers: the instance, and
|
|
719
|
+
* its business root's id, the anchor of its reads (`ctx.api.db.<root table>.findUnique({ where: { id:
|
|
720
|
+
* c.subject } })`). Fixed for the instance, so the platform fills it; what changes (run variables, the
|
|
721
|
+
* instance's status) is read with `ctx.api.instances.get`.
|
|
722
|
+
*/
|
|
723
|
+
export type CaseInput<S extends string = string> = {
|
|
724
|
+
subject: Id<S>;
|
|
725
|
+
instanceId: string;
|
|
726
|
+
};
|
|
727
|
+
/** What `orchestrator` and `contacts` receive as `c` ({@link CaseInput}). */
|
|
728
|
+
export type CaseOrchestratorInput<S extends string = string> = CaseInput<S>;
|
|
729
|
+
/**
|
|
730
|
+
* `ctx` of `contacts`: the Orchestrator's API, before the Run's params are gathered; it only reads
|
|
731
|
+
* (`db` has the read methods only). The platform runs it more than once per Run, so a write or a
|
|
732
|
+
* tool call there would be made again each time.
|
|
733
|
+
*/
|
|
734
|
+
export type CaseOrchestratorContactsContext<D extends PageTablesDesc | undefined = undefined> = Omit<CaseOrchestratorContext<D>, 'params' | 'api'> & {
|
|
735
|
+
api: Pick<CaseOrchestratorApi<D>, 'call' | 'sms' | 'email' | 'log'> & {
|
|
736
|
+
db: D extends PageTablesDesc ? TypedReadDb<D> : ReadDb;
|
|
737
|
+
};
|
|
738
|
+
};
|
|
739
|
+
/**
|
|
740
|
+
* `orchestrator.ts`'s `contacts`: whom this Run may contact (schedule calls, SMS and email to), read
|
|
741
|
+
* with `ctx.api.db`; the ids of contact rows of the company. The platform runs it when the Run
|
|
742
|
+
* starts (a pending contact of a person no longer listed is cancelled, and
|
|
743
|
+
* `ctx.params.activity.byContact` is keyed by these), and again when the Run is handed to the Agent
|
|
744
|
+
* (the orchestrator may have changed the data).
|
|
745
|
+
*/
|
|
746
|
+
export type CaseOrchestratorContacts<C = CaseOrchestratorInput, D extends PageTablesDesc | undefined = undefined> = (caseContext: C, ctx: CaseOrchestratorContactsContext<D>) => Promise<readonly string[]>;
|
|
747
|
+
/**
|
|
748
|
+
* `orchestrator.ts`: `export const orchestrator: CaseOrchestrator = async (c, ctx) => …`.
|
|
749
|
+
* `C` is the sequence's `CaseOrchestratorInput`; `D` its `PageTables` (`__gen` binds both).
|
|
750
|
+
*/
|
|
751
|
+
export type CaseOrchestrator<C = CaseOrchestratorInput, D extends PageTablesDesc | undefined = undefined> = (caseContext: C, ctx: CaseOrchestratorContext<D>) => Promise<CaseOrchestratorResult>;
|
|
752
|
+
export {};
|
|
753
|
+
//# sourceMappingURL=types.d.ts.map
|