@opencxh/domain 1.172.1 → 1.172.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entities/activity/blocks.d.ts +30 -30
- package/dist/entities/activity/catalog.d.ts +63 -86
- package/dist/entities/activity/descriptor.d.ts +31 -32
- package/dist/entities/activity/index.d.ts +2 -2
- package/dist/entities/activity/preview.d.ts +7 -7
- package/dist/entities/activity/resolve.d.ts +37 -38
- package/dist/entities/activity/types.d.ts +34 -34
- package/dist/entities/ai-account/types.d.ts +3 -3
- package/dist/entities/ai-account/vendors.d.ts +25 -32
- package/dist/entities/ai-budget/types.d.ts +5 -5
- package/dist/entities/ai-conversation/types.d.ts +12 -12
- package/dist/entities/ai-profile/types.d.ts +14 -21
- package/dist/entities/ai-settings/types.d.ts +12 -13
- package/dist/entities/analytics/index.d.ts +4 -4
- package/dist/entities/analytics/source.d.ts +1 -1
- package/dist/entities/analytics/usage.d.ts +23 -28
- package/dist/entities/artifact/blocks.d.ts +54 -69
- package/dist/entities/artifact/markdown.d.ts +2 -3
- package/dist/entities/artifact/types.d.ts +46 -54
- package/dist/entities/assignment/types.d.ts +74 -88
- package/dist/entities/channel/index.d.ts +1 -1
- package/dist/entities/channel/signature.d.ts +8 -9
- package/dist/entities/communication/index.d.ts +1 -1
- package/dist/entities/contact/index.d.ts +1 -1
- package/dist/entities/custom-field-def/types.d.ts +14 -14
- package/dist/entities/external-identity/types.d.ts +45 -50
- package/dist/entities/interaction/index.d.ts +1 -1
- package/dist/entities/interaction/types.d.ts +44 -47
- package/dist/entities/live-lens/types.d.ts +39 -44
- package/dist/entities/mcp/types.d.ts +53 -57
- package/dist/entities/memory/alias.d.ts +7 -7
- package/dist/entities/memory/browse.d.ts +21 -21
- package/dist/entities/memory/ingest.d.ts +24 -28
- package/dist/entities/memory/item.d.ts +53 -58
- package/dist/entities/memory/kind.d.ts +25 -25
- package/dist/entities/memory/query.d.ts +49 -51
- package/dist/entities/playbook/actor.d.ts +17 -17
- package/dist/entities/playbook/assignment.d.ts +54 -63
- package/dist/entities/playbook/index.d.ts +2 -2
- package/dist/entities/playbook/labels.d.ts +4 -4
- package/dist/entities/playbook/trigger-vars.d.ts +14 -15
- package/dist/entities/playbook/types.d.ts +172 -302
- package/dist/entities/resource-reminder/types.d.ts +8 -9
- package/dist/entities/time-entry/duration.d.ts +11 -11
- package/dist/entities/time-entry/types.d.ts +59 -59
- package/dist/entities/time-entry/work-type.d.ts +21 -24
- package/dist/entities/topic/examples.d.ts +26 -27
- package/dist/entities/topic/scope.d.ts +11 -12
- package/dist/entities/topic/types.d.ts +26 -28
- package/dist/entities/user/types.d.ts +24 -28
- package/dist/entities/webhook/types.d.ts +6 -6
- package/dist/entities/work/keys.d.ts +25 -26
- package/dist/entities/work/ladder.d.ts +48 -52
- package/dist/entities/work/types.d.ts +108 -114
- package/dist/index.cjs +6 -6
- package/dist/index.d.ts +29 -28
- package/dist/index.js +1377 -1242
- package/dist/platform/account.d.ts +34 -38
- package/dist/platform/ai-tools.d.ts +48 -52
- package/dist/platform/api.d.ts +9 -10
- package/dist/platform/author.d.ts +7 -9
- package/dist/platform/capabilities.d.ts +3 -3
- package/dist/platform/communication.d.ts +163 -204
- package/dist/platform/context.d.ts +8 -8
- package/dist/platform/identity.d.ts +16 -19
- package/dist/platform/kernel.d.ts +1 -1
- package/dist/platform/manifest.d.ts +2 -2
- package/dist/platform/media.d.ts +13 -15
- package/dist/platform/permission.d.ts +39 -0
- package/dist/platform/permission.test.d.ts +1 -0
- package/dist/platform/presence.d.ts +30 -30
- package/dist/platform/provider.d.ts +14 -15
- package/dist/platform/resource-source.d.ts +43 -45
- package/dist/platform/resource.d.ts +17 -23
- package/dist/platform/scope.d.ts +35 -61
- package/dist/platform/services.d.ts +4 -4
- package/dist/platform/storage.d.ts +1 -1
- package/dist/platform/sync-source.d.ts +196 -216
- package/dist/platform/transcript-cadence.d.ts +37 -41
- package/dist/platform/ui.d.ts +6 -6
- package/dist/text/endpoint.d.ts +11 -27
- package/package.json +3 -2
|
@@ -18,19 +18,19 @@ export interface HostContext {
|
|
|
18
18
|
/** Highest wins when multiple apps claim the same route. */
|
|
19
19
|
priority?: number;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* The interaction this surface is about, when there is one.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* As a **field** and not as a loose `slices` key: a panel leaning on this should be able to
|
|
24
|
+
* trust it is there. `CallTranscriptTab` already hung its "save as note" off it while nobody
|
|
25
|
+
* filled it, so that button was permanently disabled — an accidental key gives no type error, a
|
|
26
|
+
* missing field does.
|
|
27
27
|
*/
|
|
28
28
|
interactionId?: string;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* The **live** call session, only filled while a connection stands.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* This is the key a panel subscribes to `transcripts.deltas$(sessionId)` with. Without this
|
|
33
|
+
* field the transcript tab always showed the empty state, whatever was being said.
|
|
34
34
|
*/
|
|
35
35
|
sessionId?: string;
|
|
36
36
|
/** Extra data providers attach (e.g. interaction, activities, transcripts). */
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Who an action happens on behalf of.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* namens wie gehandeld wordt. Vandaar dit eigen, expliciete kanaal.
|
|
4
|
+
* Orthogonal to *who* is calling (that is `Caller` in `@opencxh/platform-api`): an app can call on
|
|
5
|
+
* behalf of a user, of a team, or of the organisation. An app-to-app call carries no usable
|
|
6
|
+
* identity of its own — the auth the runtime passes along is the original caller's, not that of
|
|
7
|
+
* whoever is being acted for. Hence this separate, explicit channel.
|
|
9
8
|
*
|
|
10
|
-
* `MutationAuthor`
|
|
11
|
-
*
|
|
9
|
+
* `MutationAuthor` is *derived* from this (attribution is a projection of identity), not tracked in
|
|
10
|
+
* parallel. See `resolveAuthor`.
|
|
12
11
|
*/
|
|
13
12
|
export type ActingIdentity = {
|
|
14
13
|
kind: "user";
|
|
@@ -20,23 +19,21 @@ export type ActingIdentity = {
|
|
|
20
19
|
kind: "org";
|
|
21
20
|
};
|
|
22
21
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* dit blijft leesbaar in logs.
|
|
22
|
+
* Compact, header-safe form: `"user:<id>"` | `"team:<id>"` | `"org"`. ASCII, no JSON — a header
|
|
23
|
+
* should not carry a structured payload, and this stays readable in logs.
|
|
26
24
|
*/
|
|
27
25
|
export declare function formatActingIdentity(actor: ActingIdentity): string;
|
|
28
26
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* glippen.
|
|
27
|
+
* Reads the compact form back. Strict: an unknown kind, a missing or empty ref yields `undefined` —
|
|
28
|
+
* never a guess and never a half-filled identity like `{ kind: "user", userId: "" }`, which would
|
|
29
|
+
* slip through a gate as valid.
|
|
33
30
|
*
|
|
34
|
-
* Round-trip: `parseActingIdentity(formatActingIdentity(a))`
|
|
31
|
+
* Round-trip: `parseActingIdentity(formatActingIdentity(a))` deep-equals `a`.
|
|
35
32
|
*/
|
|
36
33
|
export declare function parseActingIdentity(raw: string | null | undefined): ActingIdentity | undefined;
|
|
37
34
|
/**
|
|
38
|
-
*
|
|
39
|
-
* "
|
|
40
|
-
*
|
|
35
|
+
* Stable key for comparing or deduplicating identities ("one authorization call per distinct
|
|
36
|
+
* actor", say). Identical to the wire form; named separately because the intent differs from
|
|
37
|
+
* transporting.
|
|
41
38
|
*/
|
|
42
39
|
export declare function actingIdentityKey(actor: ActingIdentity): string;
|
|
@@ -4,7 +4,7 @@ export interface PlatformContext {
|
|
|
4
4
|
user: User | null;
|
|
5
5
|
activeOrg: Organization | null;
|
|
6
6
|
availableOrganizations: Organization[];
|
|
7
|
-
env:
|
|
7
|
+
env: "production" | "staging" | "dev";
|
|
8
8
|
locale: string;
|
|
9
9
|
isAuthenticated: boolean;
|
|
10
10
|
isOrgSelected: boolean;
|
|
@@ -53,7 +53,7 @@ export interface AppManifest<TSDK = any> {
|
|
|
53
53
|
/**
|
|
54
54
|
* The framework of the application.
|
|
55
55
|
*/
|
|
56
|
-
framework?:
|
|
56
|
+
framework?: "react" | "svelte" | "other";
|
|
57
57
|
/**
|
|
58
58
|
* Optional short description of the application.
|
|
59
59
|
*/
|
|
@@ -93,7 +93,7 @@ export interface AppManifest<TSDK = any> {
|
|
|
93
93
|
/**
|
|
94
94
|
* Optional documentation URL for the application.
|
|
95
95
|
*/
|
|
96
|
-
visibility?:
|
|
96
|
+
visibility?: "public" | "private";
|
|
97
97
|
/**
|
|
98
98
|
* Defines the security permissions for this app. The SDK will deny any
|
|
99
99
|
* action not explicitly granted here, following the principle of least privilege.
|
package/dist/platform/media.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type Speaker =
|
|
1
|
+
export type Speaker = "local" | "remote";
|
|
2
2
|
export interface AudioSegment {
|
|
3
3
|
sessionId: string;
|
|
4
4
|
speaker: Speaker;
|
|
@@ -10,14 +10,13 @@ export interface AudioSegment {
|
|
|
10
10
|
avgRMS: number;
|
|
11
11
|
isFinal: boolean;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
* `maxSpeechDurationMs`
|
|
13
|
+
* This segment starts mid-sentence, because the VAD had to cut hard on
|
|
14
|
+
* `maxSpeechDurationMs` instead of on a silence.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* fuzzy dedupe-lagen bestonden.
|
|
16
|
+
* The only case in which two consecutive segments can overlap each other's text, and therefore
|
|
17
|
+
* the only case in which the seam has to be glued. A cut on silence falls between two words:
|
|
18
|
+
* nothing to deduplicate there. Without this flag the receiver had to guess that difference, and
|
|
19
|
+
* that guessing was the whole reason three fuzzy dedupe layers existed.
|
|
21
20
|
*/
|
|
22
21
|
continuesPrevious?: boolean;
|
|
23
22
|
}
|
|
@@ -29,10 +28,9 @@ export interface TranscriptWord {
|
|
|
29
28
|
export interface TranscriptSegment {
|
|
30
29
|
sessionId: string;
|
|
31
30
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* links/rechts-alignment).
|
|
31
|
+
* Only set when it is known who speaks locally/remotely (live calls). With batch or diarized
|
|
32
|
+
* transcription we do not know — then this stays empty and the UI uses
|
|
33
|
+
* `speakerLabel`/`speakerId` as a tag (Fireflies style, no left/right alignment).
|
|
36
34
|
*/
|
|
37
35
|
speaker?: Speaker;
|
|
38
36
|
speakerId?: string;
|
|
@@ -44,7 +42,7 @@ export interface TranscriptSegment {
|
|
|
44
42
|
endedAt: number;
|
|
45
43
|
language?: string;
|
|
46
44
|
confidence?: number;
|
|
47
|
-
/**
|
|
45
|
+
/** See {@link AudioSegment.continuesPrevious} — travels along so the store knows the seam. */
|
|
48
46
|
continuesPrevious?: boolean;
|
|
49
47
|
}
|
|
50
48
|
export interface AudioPipelineOptions {
|
|
@@ -53,9 +51,9 @@ export interface AudioPipelineOptions {
|
|
|
53
51
|
speechFrameRatio: number;
|
|
54
52
|
silenceDurationMs: number;
|
|
55
53
|
maxSpeechDurationMs: number;
|
|
56
|
-
/**
|
|
54
|
+
/** Seam overlap, applied only after a hard `maxSpeechDurationMs` cut. */
|
|
57
55
|
overlapMs: number;
|
|
58
|
-
/** Audio
|
|
56
|
+
/** Audio kept before the speech onset, so the first sound is not lost. */
|
|
59
57
|
preRollMs: number;
|
|
60
58
|
}
|
|
61
59
|
export type MediaPermissionKind = "microphone" | "camera";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platform-wide permission vocabulary — the only place permission strings are declared.
|
|
3
|
+
*
|
|
4
|
+
* The shape is the locked `resource.action` convention, dot-separated and WITHOUT an app prefix:
|
|
5
|
+
* the app key comes from the router (`routes(app, APP)` in platform-api passes it once), and
|
|
6
|
+
* grants in `auth.permissions` are grouped per app (`Record<app, string[]>`), so the string itself
|
|
7
|
+
* need not repeat the app. Verbs are `read` / `write` / `publish` — no create/update/delete split;
|
|
8
|
+
* `write` covers every mutation. A third segment (like `billing.write`) is field level within a
|
|
9
|
+
* resource.
|
|
10
|
+
*
|
|
11
|
+
* `as const` and not an enum or a loose union: the declaration sites want literal types (a typo in
|
|
12
|
+
* `permissions: ["inbox.wirte"]` has to go red), and the runtime value is needed for tests and
|
|
13
|
+
* later for seeding roles.
|
|
14
|
+
*/
|
|
15
|
+
export declare const APP_PERMISSIONS: {
|
|
16
|
+
readonly ai: readonly ["account.read", "account.write", "agent.read", "agent.write", "assignment.read", "budget.read", "budget.write", "connector.read", "connector.write", "context.read", "context.write", "conversation.read", "conversation.write", "lens.read", "lens.write", "message.read", "message.write", "playbook.read", "playbook.write", "profile.read", "profile.write", "run.read", "run.write", "settings.read", "settings.write", "tool.read", "transcript.write", "usage.read"];
|
|
17
|
+
readonly analytics: readonly ["report.read"];
|
|
18
|
+
readonly "app-store": readonly ["app.publish", "app.read", "app.write", "setting.read", "setting.write"];
|
|
19
|
+
readonly automations: readonly ["sync.read", "sync.write", "webhook.read", "webhook.write"];
|
|
20
|
+
readonly communication: readonly ["account.read", "account.write", "activity-type.read", "activity.read", "activity.write", "attachment.read", "attribute.read", "attribute.write", "calendar.read", "calendar.write", "channel.read", "channel.write", "custom-field.read", "custom-field.write", "folder.read", "folder.write", "inbox.read", "inbox.write", "interaction.read", "interaction.write", "reminder.read", "task.read", "task.write", "template.read", "template.write", "topic.read", "topic.write"];
|
|
21
|
+
readonly context: readonly ["kind.read", "kind.write", "memory.read", "memory.write"];
|
|
22
|
+
readonly crm: readonly ["company.read", "company.write", "contact.read", "contact.write"];
|
|
23
|
+
readonly "eylo-voip": readonly ["account.read", "account.write", "callflow.read", "callflow.write", "channel.read", "channel.write", "contact.read", "contact.write", "device.read", "device.write", "group.read", "group.write", "interaction.read", "interaction.write", "media.read", "media.write", "menu.read", "menu.write", "phone-number.read", "phone-number.write", "recording.read", "recording.write", "sip.read", "temporal-rule.read", "temporal-rule.write", "user.read", "user.write", "vmbox.read", "vmbox.write", "webhook.read", "webhook.write"];
|
|
24
|
+
readonly google: readonly ["account.read", "account.write", "contact.read"];
|
|
25
|
+
readonly kb: readonly ["article.read", "article.write", "category.read", "category.write", "help-center.read", "help-center.write", "kb.read", "kb.write"];
|
|
26
|
+
readonly mail: readonly ["account.write"];
|
|
27
|
+
readonly meta: readonly ["account.read", "account.write"];
|
|
28
|
+
readonly microsoft: readonly ["account.read", "account.write", "contact.read", "sync.write"];
|
|
29
|
+
readonly organization: readonly ["billing.read", "billing.write", "settings.read", "settings.write", "team.read", "team.write"];
|
|
30
|
+
readonly shopify: readonly ["account.read", "account.write", "order.read"];
|
|
31
|
+
readonly slack: readonly ["thread.read", "thread.write"];
|
|
32
|
+
readonly storage: readonly ["artifact.read", "artifact.write", "file.read", "file.write", "mount.read", "mount.write"];
|
|
33
|
+
readonly time: readonly ["entry.read", "entry.write", "work-type.read", "work-type.write"];
|
|
34
|
+
readonly user: readonly ["user.read", "user.write"];
|
|
35
|
+
readonly work: readonly ["item.read", "item.write", "project.read", "project.write"];
|
|
36
|
+
};
|
|
37
|
+
export type PermissionApp = keyof typeof APP_PERMISSIONS;
|
|
38
|
+
/** One app's permission strings, as a literal union (`"inbox.read" | "inbox.write"`). */
|
|
39
|
+
export type PermissionOf<A extends PermissionApp> = (typeof APP_PERMISSIONS)[A][number];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -98,37 +98,37 @@ export interface AgeablePresence {
|
|
|
98
98
|
*/
|
|
99
99
|
export declare function agePresenceEntry<T extends AgeablePresence>(entry: T, now: number): T;
|
|
100
100
|
/**
|
|
101
|
-
*
|
|
101
|
+
* Which **team** someone is working for right now.
|
|
102
102
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
103
|
+
* An agent's role is a property of the person and not of the conversation: a support agent usually
|
|
104
|
+
* does one thing, and on a personal channel there is nothing to read off the conversation. This
|
|
105
|
+
* setting sits next to presence for the same reason presence exists — it is "how am I now", not
|
|
106
|
+
* "who am I".
|
|
107
107
|
*
|
|
108
|
-
*
|
|
109
|
-
* workflows
|
|
110
|
-
* (`assignedInboxId` → `Inbox.teamId`).
|
|
108
|
+
* The value is a `teamId` and not a profile reference: team is the scope profiles, topics,
|
|
109
|
+
* workflows and inboxes are already scoped on, and it is also what a routed conversation yields
|
|
110
|
+
* (`assignedInboxId` → `Inbox.teamId`). One choice resolves them all consistently.
|
|
111
111
|
*/
|
|
112
112
|
export interface WorkMode {
|
|
113
113
|
userId: string;
|
|
114
114
|
teamId: string;
|
|
115
|
-
/** `"manual"`
|
|
115
|
+
/** `"manual"` or a source that set it on the user's behalf (a schedule, later). */
|
|
116
116
|
source: string;
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
|
-
*
|
|
119
|
+
* Which team this user is working for right now, and whether they have to choose one first.
|
|
120
120
|
*
|
|
121
|
-
*
|
|
121
|
+
* Three outcomes, and the third is the whole point:
|
|
122
122
|
*
|
|
123
|
-
* - **`teamId`** —
|
|
124
|
-
*
|
|
125
|
-
* - **`undefined`
|
|
126
|
-
*
|
|
127
|
-
* - **`undefined`
|
|
128
|
-
*
|
|
129
|
-
*
|
|
123
|
+
* - **`teamId`** — either set explicitly, or implicit because there is only one team. Whoever does
|
|
124
|
+
* one thing never has to configure anything.
|
|
125
|
+
* - **`undefined` with `mustChoose: false`** — no team at all; there is nothing to choose and
|
|
126
|
+
* nothing to do.
|
|
127
|
+
* - **`undefined` with `mustChoose: true`** — more than one team and nothing chosen. A surface
|
|
128
|
+
* leaning on the role should then **stay quiet** instead of guessing one: guessing wrong is
|
|
129
|
+
* worse than showing nothing, the same fail-closed rule as the account↔channel binding.
|
|
130
130
|
*
|
|
131
|
-
*
|
|
131
|
+
* A pure function, because this is the only real decision in the work mode — the rest is storage.
|
|
132
132
|
*/
|
|
133
133
|
export declare function resolveWorkMode(stored: {
|
|
134
134
|
teamId?: string;
|
|
@@ -137,20 +137,20 @@ export declare function resolveWorkMode(stored: {
|
|
|
137
137
|
mustChoose: boolean;
|
|
138
138
|
};
|
|
139
139
|
/**
|
|
140
|
-
*
|
|
140
|
+
* May the audio pipeline run — and therefore: may anything listen along?
|
|
141
141
|
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
142
|
+
* Two independent conditions, which is exactly why this is a function and not an `&&` at the point
|
|
143
|
+
* of use:
|
|
144
144
|
*
|
|
145
|
-
* - **`providerAvailable`** — is
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* - **`allowed`** —
|
|
149
|
-
*
|
|
145
|
+
* - **`providerAvailable`** — is an STT provider registered. That used to be the *only* condition,
|
|
146
|
+
* making "the AI app is installed" the same as "we listen in on every call, org-wide". A
|
|
147
|
+
* technical accident as policy.
|
|
148
|
+
* - **`allowed`** — does the organisation want it. An assistant listening unasked should not exist
|
|
149
|
+
* without a way to stop it.
|
|
150
150
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
151
|
+
* The gate is re-asserted every two seconds (federated remotes may register their handler later
|
|
152
|
+
* than this app boots), so a switch that is not inside this function races that tick and turns
|
|
153
|
+
* itself back on.
|
|
154
154
|
*/
|
|
155
155
|
export declare function shouldRunAudioPipeline(input: {
|
|
156
156
|
providerAvailable: boolean;
|
|
@@ -2,12 +2,11 @@ import { Interaction } from '../entities/interaction';
|
|
|
2
2
|
import { Uri } from './communication';
|
|
3
3
|
import { TranscriptSegment } from './media';
|
|
4
4
|
export interface ProviderTranscribeResponse {
|
|
5
|
-
/**
|
|
5
|
+
/** Full transcript text (always present, backwards compatible). */
|
|
6
6
|
text: string;
|
|
7
7
|
/**
|
|
8
|
-
* Segment-
|
|
9
|
-
*
|
|
10
|
-
* provider kent de call-session niet).
|
|
8
|
+
* Segment-level transcript, only filled when `segments` was requested and the provider supports
|
|
9
|
+
* it. `sessionId` is filled in by the consumer (the provider does not know the call session).
|
|
11
10
|
*/
|
|
12
11
|
segments?: TranscriptSegment[];
|
|
13
12
|
}
|
|
@@ -17,14 +16,14 @@ export interface ComposePayload {
|
|
|
17
16
|
channelId: string;
|
|
18
17
|
channelUri?: Uri;
|
|
19
18
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* Addressing envelope. `to` is required (1+); `cc`/`bcc` are mail only. Non-mail providers use
|
|
20
|
+
* `to[0]`.
|
|
22
21
|
*/
|
|
23
22
|
recipients: import('./communication').RecipientList;
|
|
24
23
|
subject?: string;
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* Outgoing attachments (base64 + filename + mimeType). Compose handlers pass them to the
|
|
26
|
+
* provider send; the metadata lands on the Activity.
|
|
28
27
|
*/
|
|
29
28
|
attachments?: import('./communication').OutgoingAttachment[];
|
|
30
29
|
/**
|
|
@@ -121,17 +120,17 @@ export interface ListFilesPayload {
|
|
|
121
120
|
path?: string;
|
|
122
121
|
}
|
|
123
122
|
/**
|
|
124
|
-
*
|
|
123
|
+
* Looking across folders instead of inside one (`POST storage/file/browse`).
|
|
125
124
|
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
125
|
+
* No `mountId` and no `path`: the question is precisely "anywhere I am allowed to look". The
|
|
126
|
+
* server decides which folders those are — see `readableMounts`.
|
|
128
127
|
*/
|
|
129
128
|
export interface BrowseFilesPayload {
|
|
130
|
-
/**
|
|
129
|
+
/** Free text on the file name; case-insensitive, substring. */
|
|
131
130
|
name?: string;
|
|
132
|
-
/** `mine`
|
|
131
|
+
/** `mine` restricts to what you added yourself; everything by default. */
|
|
133
132
|
scope?: "all" | "mine";
|
|
134
|
-
/**
|
|
133
|
+
/** Ceiling on the number of rows; the server truncates it at its own maximum. */
|
|
135
134
|
limit?: number;
|
|
136
135
|
}
|
|
137
136
|
export interface DownloadAttachmentPayload {
|
|
@@ -139,6 +138,6 @@ export interface DownloadAttachmentPayload {
|
|
|
139
138
|
accountId?: string;
|
|
140
139
|
path?: string;
|
|
141
140
|
id?: string;
|
|
142
|
-
/**
|
|
141
|
+
/** Conversation id (Teams chatId) — needed to proxy chat hostedContent. */
|
|
143
142
|
conversationId?: string;
|
|
144
143
|
}
|
|
@@ -1,94 +1,92 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Pointable resources, across app boundaries.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `resource_ref
|
|
7
|
-
*
|
|
4
|
+
* One question that kept coming back in this platform and was solved case by case until now:
|
|
5
|
+
* *which things can I point at here, and what are they called?* Linking a work item to a
|
|
6
|
+
* conversation, filling a `resource_ref` field, attaching a file later — the same question asked
|
|
7
|
+
* of three different apps three times.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* The answer is a **service-bus contract**, not an HTTP provider role: both questions are asked on
|
|
10
|
+
* the client by a user who has the source app open anyway, and that app already has its
|
|
11
|
+
* conversations and companies in a store. A provider role would turn that into a round trip for
|
|
12
|
+
* data sitting in memory.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
* app
|
|
14
|
+
* Three keys, all three through `sdk.services.execute` (which returns the answers of every
|
|
15
|
+
* installed app as an array):
|
|
16
16
|
*
|
|
17
|
-
* |
|
|
17
|
+
* | Key | Params | Answer |
|
|
18
18
|
* |---|---|---|
|
|
19
19
|
* | `resources.describe` | — | {@link ResourceSourceDescribe} |
|
|
20
20
|
* | `resources.search` | {@link ResourceSearchParams} | {@link ResourceSummary}`[]` |
|
|
21
21
|
* | `resources.resolve` | {@link ResourceResolveParams} | {@link ResourceSummary}`[]` |
|
|
22
22
|
*
|
|
23
|
-
* `describe` is
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* `describe` is not cosmetic: a picker draws its kind filters from what actually answers. Without
|
|
24
|
+
* that call it would show a fixed list with tabs that stay empty as soon as an app is not
|
|
25
|
+
* installed — exactly the per-provider assumption this contract avoids.
|
|
26
26
|
*/
|
|
27
|
-
/**
|
|
27
|
+
/** The service-bus keys, as constants so a typo does not silently yield an empty list. */
|
|
28
28
|
export declare const RESOURCE_DESCRIBE_SERVICE = "resources.describe";
|
|
29
29
|
export declare const RESOURCE_SEARCH_SERVICE = "resources.search";
|
|
30
30
|
export declare const RESOURCE_RESOLVE_SERVICE = "resources.resolve";
|
|
31
|
-
/**
|
|
31
|
+
/** One pointable resource, as the app that owns it shows it. */
|
|
32
32
|
export interface ResourceSummary {
|
|
33
33
|
/**
|
|
34
|
-
* `<kind>:<ref>` —
|
|
34
|
+
* `<kind>:<ref>` — the same shape `ScopeAuth` authorizes and `WorkLink.toKey` carries.
|
|
35
35
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* ontdubbelt daarop.
|
|
36
|
+
* This is the identity: two providers knowing the same resource (comms federates address books,
|
|
37
|
+
* crm has its own contacts) deliver the same key, and a consumer deduplicates on it.
|
|
39
38
|
*/
|
|
40
39
|
scopeKey: string;
|
|
41
|
-
/**
|
|
40
|
+
/** The prefix of {@link ResourceSummary.scopeKey}, separate so filtering needs no split. */
|
|
42
41
|
kind: string;
|
|
43
42
|
title: string;
|
|
44
|
-
/**
|
|
43
|
+
/** Second line: sender, email address, company name, status label. */
|
|
45
44
|
subtitle?: string;
|
|
46
|
-
/** Lucide
|
|
45
|
+
/** Lucide icon name, like `TimeTarget.icon`. Absent = the consumer picks one for the kind. */
|
|
47
46
|
icon?: string;
|
|
48
47
|
/**
|
|
49
|
-
*
|
|
48
|
+
* Path inside the shell to open this resource.
|
|
50
49
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* Absent = the row is not clickable. Deliberately a separate state and not a guess: an invented
|
|
51
|
+
* path yields a dead-end navigation, which is worse than no link.
|
|
53
52
|
*/
|
|
54
53
|
href?: string;
|
|
55
|
-
/**
|
|
54
|
+
/** Sort hint; more recent ranks higher. Absent counts as oldest. */
|
|
56
55
|
updatedAt?: number;
|
|
57
56
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
57
|
+
* Other scopeKeys belonging to this resource — the contact and the company behind a
|
|
58
|
+
* conversation, the customer behind a case.
|
|
60
59
|
*
|
|
61
|
-
* **
|
|
62
|
-
* `partyKeys
|
|
63
|
-
*
|
|
64
|
-
*
|
|
60
|
+
* **The source says it, the consumer does not guess it.** Comms knows an interaction has
|
|
61
|
+
* `partyKeys`; `apps/work` does not and should not. Without this field, "bring the contact
|
|
62
|
+
* along" in the link flow would become an `if (kind === "interaction")` with a comms-specific
|
|
63
|
+
* field name, and that breaks at the next provider.
|
|
65
64
|
*
|
|
66
|
-
*
|
|
67
|
-
* kiezer, geen graaf.
|
|
65
|
+
* One hop only, and only what the source already holds: this is a hint for a picker, not a graph.
|
|
68
66
|
*/
|
|
69
67
|
related?: string[];
|
|
70
68
|
}
|
|
71
|
-
/**
|
|
69
|
+
/** Answer to `resources.describe`: which kinds this app can search and resolve. */
|
|
72
70
|
export interface ResourceSourceDescribe {
|
|
73
71
|
kinds: string[];
|
|
74
72
|
}
|
|
75
|
-
/** Params
|
|
73
|
+
/** Params for `resources.search`. */
|
|
76
74
|
export interface ResourceSearchParams {
|
|
77
|
-
/**
|
|
75
|
+
/** Free text. Empty = "what is recent", not "everything". */
|
|
78
76
|
query: string;
|
|
79
|
-
/**
|
|
77
|
+
/** Restrict to these kinds. Empty/absent = everything the provider has. */
|
|
80
78
|
kinds?: string[];
|
|
81
|
-
/** Maximum per
|
|
79
|
+
/** Maximum per provider, not in total — the consumer truncates after deduplicating. */
|
|
82
80
|
limit?: number;
|
|
83
81
|
}
|
|
84
|
-
/** Params
|
|
82
|
+
/** Params for `resources.resolve`: from key to readable row. */
|
|
85
83
|
export interface ResourceResolveParams {
|
|
86
84
|
scopeKeys: string[];
|
|
87
85
|
}
|
|
88
86
|
/**
|
|
89
|
-
*
|
|
87
|
+
* The kind out of a scopeKey, without having to split the rest.
|
|
90
88
|
*
|
|
91
|
-
*
|
|
92
|
-
* contract
|
|
89
|
+
* A separate helper and not a reuse of `splitScopeKey`: that one sits in `platform-api` (server),
|
|
90
|
+
* and this contract is read mostly on the client.
|
|
93
91
|
*/
|
|
94
92
|
export declare function resourceKindOf(scopeKey: string): string;
|