@opencxh/domain 1.127.0 → 1.128.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.
@@ -0,0 +1,19 @@
1
+ import { MemorySubjectKey } from './item';
2
+ /**
3
+ * Twee subjects die hetzelfde blijken te zijn (een merge van interacties, later een echte
4
+ * identiteitslaag). Het geheugen verhuist niet: de alias wordt bij het lezen opgelost.
5
+ *
6
+ * **Eén niveau diep by construction**: een alias wiens `canonical` zelf een alias is wordt
7
+ * geweigerd bij het schrijven. Resolutie is daarmee twee queries en nooit recursief — geen
8
+ * cyclus-detectie, geen diepte-limiet, geen verrassing op het hete pad.
9
+ */
10
+ export interface MemorySubjectAlias {
11
+ id: string;
12
+ organizationId: string;
13
+ /** Het subject dat is opgegaan in `canonical`. Unique per org. */
14
+ subject: MemorySubjectKey;
15
+ canonical: MemorySubjectKey;
16
+ /** De app die de samenvoeging meldde. */
17
+ source: string;
18
+ createdAt?: number;
19
+ }
@@ -0,0 +1,5 @@
1
+ export * from './alias';
2
+ export * from './ingest';
3
+ export * from './item';
4
+ export * from './kind';
5
+ export * from './query';
@@ -0,0 +1,61 @@
1
+ import { MemoryKindId, MemoryLink, MemorySubjectKey } from './item';
2
+ /**
3
+ * Schrijven is een **CAS-upsert**, geen snapshot-replace zoals analytics.
4
+ *
5
+ * Analytics mag een hele periode weggooien en opnieuw wegschrijven omdat een fact
6
+ * herberekenbaar is uit de bronstore. Een delta-gevouwen verhaal is de opgetelde uitkomst
7
+ * van N modelcalls en is dat niet. Bovendien is remove+insert niet atomair: een lezer kan
8
+ * "geen item" observeren op een subject dat wél een verhaal heeft.
9
+ */
10
+ export interface MemoryUpsertRequest {
11
+ organizationId: string;
12
+ /** De schrijvende app; de hub vult dit uit `req.source.app` en vertrouwt de body hier niet. */
13
+ source: string;
14
+ subject: MemorySubjectKey;
15
+ kind: MemoryKindId;
16
+ /** Default bij `cardinality: "single"`: `"<kind>:<subject>"`. */
17
+ sourceRef?: string;
18
+ title: string;
19
+ body: string;
20
+ occurredAt?: number;
21
+ /** Watermerk van het bron-event dat deze schrijfactie veroorzaakte. */
22
+ throughRef?: string;
23
+ throughAt?: number;
24
+ /** Mismatch => `accepted: false` met `reason: "stale-version"`; de caller herplant. */
25
+ expectedVersion?: number;
26
+ audienceRef?: string;
27
+ locale?: string;
28
+ /** Weglaten: de hub extraheert keywords zelf uit titel + body (één tokenizer, schrijf én lees). */
29
+ keywords?: string[];
30
+ tags?: string[];
31
+ links?: MemoryLink[];
32
+ }
33
+ export type MemoryUpsertRejection = "stale-version" | "stale-watermark" | "unknown-kind" | "kind-disabled" | "subject-kind-mismatch" | "not-owner";
34
+ export interface MemoryUpsertResult {
35
+ accepted: boolean;
36
+ /** De versie zoals die nu in de store staat — ook bij een afwijzing, zodat de caller kan herplannen. */
37
+ version: number;
38
+ itemId?: string;
39
+ reason?: MemoryUpsertRejection;
40
+ }
41
+ /**
42
+ * Expliciet destructief: gooit alle items van (subject, kind) van deze bron weg en zet
43
+ * `items` ervoor terug. Alleen voor **herberekenbare** kinds, bv. een nachtelijke re-fold.
44
+ */
45
+ export interface MemoryReplaceRequest {
46
+ organizationId: string;
47
+ source: string;
48
+ subject: MemorySubjectKey;
49
+ kind: MemoryKindId;
50
+ items: MemoryUpsertRequest[];
51
+ }
52
+ /**
53
+ * Bron-gestuurd wissen. De **bron** pusht dit; de hub interpreteert geen deletes: de
54
+ * mapping van een verwijderd contact naar zijn interacties leeft in comms, en
55
+ * `contacts:deleted` publiceert alleen `{ id }` — zonder `organizationId`.
56
+ */
57
+ export interface MemoryPurgeRequest {
58
+ organizationId: string;
59
+ source: string;
60
+ subjects: MemorySubjectKey[];
61
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * De geheugenlaag (`apps/context`): één durende laag per **subject**, waarbij de
3
+ * organisatie zelf per event bepaalt wat er onthouden wordt.
4
+ *
5
+ * `Memory*` en niet `Context*`: `platform/context.ts` exporteert al `HostContext` en
6
+ * `context.collect` (vluchtige route-context) uit dezelfde platte barrel.
7
+ */
8
+ /** Een bestaande scopeKey: `interaction:i_1`, `contact:c_9`. Een latere identiteitslaag is gewoon een ander prefix. */
9
+ export type MemorySubjectKey = string;
10
+ /** `comms.resolution` (app-gedeclareerd) of `sales_besluitvormer` (org-eigen). */
11
+ export type MemoryKindId = string;
12
+ /**
13
+ * Een verwijzing naar iets anders — intern (`interaction:i_2`) of extern
14
+ * (`hubspot:5591`, `clickup:86ab2`).
15
+ *
16
+ * Een **lijst**, nooit een object met de relatie als key: de app-sdk http-client
17
+ * mangelt elke object-key camel<->snake, dus `{ "crm.company": "..." }` komt verminkt
18
+ * aan de andere kant aan.
19
+ */
20
+ export interface MemoryLink {
21
+ rel: string;
22
+ target: string;
23
+ }
24
+ /** Harde grens op de body. Geheugen is een samenvatting; een mailbox-schaduwkopie is het niet. */
25
+ export declare const MAX_MEMORY_CHARS = 2000;
26
+ export interface MemoryItem {
27
+ id: string;
28
+ organizationId: string;
29
+ subject: MemorySubjectKey;
30
+ kind: MemoryKindId;
31
+ title: string;
32
+ /** DE inhoud: markdown, begrensd op {@link MAX_MEMORY_CHARS}. Nooit een genest object. */
33
+ body: string;
34
+ /** Schrijvende app (== `req.source.app`); playbook-schrijfacties komen binnen als "ai". */
35
+ source: string;
36
+ /** Identiteit binnen (subject, kind) voor de bron. Bij `cardinality: "single"` de vouw-sleutel. */
37
+ sourceRef: string;
38
+ occurredAt: number;
39
+ /**
40
+ * Watermerk: tot en met welk bron-event dit item gevouwen is. Maakt dubbele events en
41
+ * retries gratis — een oudere `throughAt` wordt afgewezen in plaats van overschreven.
42
+ */
43
+ throughRef?: string;
44
+ throughAt?: number;
45
+ /** Optimistic concurrency; de hub doet compare-and-swap op dit veld. */
46
+ version: number;
47
+ /** Overgenomen uit de kind-definitie, niet uit de call — zie `MemoryKindDefinition.visibility`. */
48
+ visibility: MemoryVisibility;
49
+ /**
50
+ * Zichtbaarheids-ANKER (inbox-id / OwnerScope-sleutel), **geen ledenlijst**: een
51
+ * gesnapshotte ledenlijst veroudert bij elke inbox-join en reassignment, en
52
+ * stale-permissive is een lek.
53
+ */
54
+ audienceRef?: string;
55
+ /** Cosine over taalgrenzen wordt geweigerd; de skip wordt geteld, niet verzwegen. */
56
+ locale: string;
57
+ /** Gedenormaliseerde termen: het enige selectieve structurele filter (er is geen substring-operator). */
58
+ keywords?: string[];
59
+ /** Snelle alternatieve sleutels, bv. `tel:+31612345678` voor het rinkelmoment. */
60
+ tags?: string[];
61
+ links?: MemoryLink[];
62
+ /** Model waarmee de vector is gemaakt; retrieval vergelijkt alleen binnen hetzelfde model. */
63
+ embeddingModel?: string;
64
+ /** Uit een live pull (fase 3); nooit gepersisteerd. */
65
+ live?: boolean;
66
+ createdAt?: number;
67
+ updatedAt?: number;
68
+ }
69
+ /**
70
+ * `"audience"` = alleen voor wie het subject mag zien. `"org"` = org-breed leesbaar en
71
+ * daarmee vindbaar in het cross-subject-pad ("is dit eerder bij een andere klant
72
+ * voorgekomen?").
73
+ *
74
+ * Per **kind** gedeclareerd en niet per item: het cross-subject-pad kan zich geen
75
+ * autorisatie-round-trip per hit veroorloven, dus het filtert structureel op deze kolom.
76
+ */
77
+ export type MemoryVisibility = "audience" | "org";
@@ -0,0 +1,66 @@
1
+ import { LocaleBundle } from '../analytics/dashboard';
2
+ import { OwnerScope } from '../contact/types';
3
+ import { MemoryKindId, MemoryVisibility } from './item';
4
+ /**
5
+ * Wat er onthouden mág worden, en met welke regels.
6
+ *
7
+ * Twee bronnen, één type:
8
+ * - **app-gedeclareerd** via `GET /provider/memory/describe` (de ingebouwde defaults);
9
+ * - **org-eigen** als rij in `memory_kind`. Mal: `CustomFieldDef` — de organisatie
10
+ * definieert de sleutel, een generieke store bewaart de waarde.
11
+ *
12
+ * `ownerScope` is wat "iedereen wil zijn eigen relevante data" mogelijk maakt: sales legt
13
+ * andere dingen vast dan support, en een persoonlijk kind is alleen van die gebruiker.
14
+ */
15
+ export interface MemoryKindDefinition {
16
+ /** Org-eigen: `[a-z0-9_]+` (geen punt — die leest als een genest form-pad). App-eigen: `<app>.<naam>`. */
17
+ id: MemoryKindId;
18
+ label: string;
19
+ description?: string;
20
+ /** Subject-soorten waarop dit kind mag landen, bv. `["interaction"]` of `["contact"]`. */
21
+ subjectKinds: string[];
22
+ visibility: MemoryVisibility;
23
+ /** `"single"` = één item per (subject, kind), doorvouwen. `"many"` = losse items. */
24
+ cardinality: "single" | "many";
25
+ /** Ordening onder het tekenbudget van de bundel. */
26
+ priority: number;
27
+ /** Mag dit kind in het cross-subject-pad meedoen? Alleen zinvol bij `visibility: "org"`. */
28
+ crossSubjectSearchable: boolean;
29
+ /** Embedden kost geld; per kind aan/uit. */
30
+ embed: boolean;
31
+ retentionDays?: number;
32
+ /** Rang-multiplier: een opgeloste casus verslaat een losse notitie. Default 1. */
33
+ weight?: number;
34
+ /**
35
+ * Wie dit kind bezit. Bepaalt zowel wie mag schrijven als de **ordening** voor een
36
+ * lezer (eigen team eerst). Afwezig = de hele organisatie.
37
+ */
38
+ ownerScope?: OwnerScope;
39
+ /** Wie hem declareerde. De org kan een app-kind niet oprekken, alleen uitzetten. */
40
+ origin: "app" | "org";
41
+ enabled: boolean;
42
+ }
43
+ /**
44
+ * Bare payload van `GET /provider/memory/describe` — **niet** in `ResponseFactory`
45
+ * verpakt (mal: `AnalyticsSourceDescription`).
46
+ */
47
+ export interface MemorySourceDescription {
48
+ /** De declarerende app (== `manifest.name` == `req.source.app`). */
49
+ source: string;
50
+ kinds: MemoryKindDefinition[];
51
+ /** Vlakke LIJST: keys met een punt worden gemangeld. */
52
+ locales?: LocaleBundle;
53
+ /** Fase 3: welke subjects/kinds deze bron live kan leveren. */
54
+ live?: {
55
+ subjectKinds: string[];
56
+ kinds: MemoryKindId[];
57
+ };
58
+ }
59
+ /** De samengestelde catalogus die de hub aan de frontend levert (`GET /kinds`). */
60
+ export interface MemoryKindCatalog {
61
+ /** App-gedeclareerd + org-eigen, gemengd. */
62
+ kinds: MemoryKindDefinition[];
63
+ /** Bronnen die meededen aan de fan-out (voor "wie levert dit?"). */
64
+ sources: string[];
65
+ locales: LocaleBundle;
66
+ }
@@ -0,0 +1,71 @@
1
+ import { MemoryItem, MemoryKindId, MemorySubjectKey } from './item';
2
+ /** Grenzen van het tekenbudget van een bundel. Buiten bereik wordt geklemd, niet geweigerd. */
3
+ export declare const MIN_MEMORY_BUDGET = 500;
4
+ export declare const MAX_MEMORY_BUDGET = 12000;
5
+ export declare const DEFAULT_MEMORY_BUDGET = 4000;
6
+ /**
7
+ * Één query-contract voor het dossier-paneel, de brief tijdens het rinkelen en elke
8
+ * AI-tool. Geen tweede codepad: het verschil tussen die drie is `budget`, niet code.
9
+ */
10
+ export interface MemoryQuery {
11
+ /** Weglaten = cross-subject zoeken ("vergelijkbare cases"). */
12
+ subject?: MemorySubjectKey;
13
+ /** Extra subjects die bij hetzelfde beeld horen, bv. het contact naast de interactie. */
14
+ alsoSubjects?: MemorySubjectKey[];
15
+ /** Default true. */
16
+ resolveAliases?: boolean;
17
+ kinds?: MemoryKindId[];
18
+ tags?: string[];
19
+ /** Vrije tekst. Afwezig = puur structurele ordening (priority x recency x weight) en dus geen embedding-call. */
20
+ text?: string;
21
+ since?: number;
22
+ limit?: number;
23
+ /** Zo bedoel je "bij ANDERE klanten". */
24
+ excludeSubjects?: MemorySubjectKey[];
25
+ format?: "items" | "bundle" | "both";
26
+ /** Geklemd op [{@link MIN_MEMORY_BUDGET}, {@link MAX_MEMORY_BUDGET}]. */
27
+ budget?: number;
28
+ /** Fase 3: ook live bronnen bevragen, met harde timeout en eigen sub-budget. */
29
+ live?: boolean;
30
+ }
31
+ export interface MemoryHit {
32
+ item: MemoryItem;
33
+ score: number;
34
+ snippet: string;
35
+ /** Ruw materiaal voor een confidence-gate (fase 4): waar kwam de score vandaan? */
36
+ matched: {
37
+ keyword: number;
38
+ semantic: number;
39
+ recency: number;
40
+ };
41
+ }
42
+ export interface MemoryQueryResult {
43
+ hits: MemoryHit[];
44
+ bundle?: string;
45
+ /** Hoeveel rijen het structurele voorfilter opleverde. */
46
+ scanned: number;
47
+ /** Scan-cap geraakt OF hits uit de bundel gevallen — nooit stil afkappen. */
48
+ truncated?: boolean;
49
+ /** `false` = keyword-only (geen embedding-account, of geen enkele vergelijkbare vector). */
50
+ semantic: boolean;
51
+ /** Hits die de her-autorisatie van de top-K niet overleefden. */
52
+ withheld?: number;
53
+ /**
54
+ * Kandidaten overgeslagen door model- of taal-mismatch. Zonder deze teller degradeert
55
+ * een modelwissel volkomen stil: `cosineSimilarity` geeft bij dimensie-mismatch 0, dus
56
+ * na het omzetten van `isDefaultEmbedding` scoort élk bestaand item 0 en valt retrieval
57
+ * geruisloos terug op keyword.
58
+ */
59
+ vectorSkipped?: number;
60
+ /**
61
+ * Waarom er niets terugkwam, als dat een structurele reden heeft in plaats van "niets
62
+ * gevonden".
63
+ *
64
+ * `"no-cross-subject-kinds"` is de belangrijkste: zoeken bij ándere klanten leest alleen
65
+ * geheugensoorten die als `visibility: "org"` én `crossSubjectSearchable` zijn
66
+ * gedeclareerd. Is er geen enkele, dan is een leeg resultaat geen zoekuitkomst maar een
67
+ * configuratiefeit — en dat hoort de caller te weten in plaats van te concluderen dat er
68
+ * niets vergelijkbaars bestaat.
69
+ */
70
+ reason?: "no-cross-subject-kinds" | "no-subject-access";
71
+ }
@@ -40,6 +40,12 @@ export declare const TRIGGER_VARS: readonly [{
40
40
  }, {
41
41
  readonly name: "textRaw";
42
42
  readonly type: "string";
43
+ }, {
44
+ readonly name: "fromStatus";
45
+ readonly type: "string";
46
+ }, {
47
+ readonly name: "toStatus";
48
+ readonly type: "string";
43
49
  }];
44
50
  /** De variabelen die een classify-stap oplevert, per mode. */
45
51
  export declare const CLASSIFY_VARS: {
@@ -14,6 +14,19 @@ export type PlaybookTrigger = {
14
14
  /** Specific channel ids (e.g. per mailbox). Matched against activity.channelId. */
15
15
  channelIds?: string[];
16
16
  filter?: unknown;
17
+ /**
18
+ * Wacht dit aantal milliseconden en draai dan **één** run voor de berichten in dat
19
+ * venster, in plaats van een run per bericht.
20
+ *
21
+ * Voor een playbook dat bij elk bericht een modelcall doet is dit het verschil tussen
22
+ * vier calls en één bij een mailwisseling van vier berichten in tien minuten. De run
23
+ * draait op het **nieuwste** bericht uit het venster; wat ertussen zat is in de
24
+ * samenvatting van dat gesprek al meegenomen via de lookup-stap.
25
+ *
26
+ * Bewust op de trigger en niet in de geheugenlaag: coalesceren is een eigenschap van
27
+ * "hoe vaak wil ik hierop reageren", niet van wat je onthoudt.
28
+ */
29
+ debounceMs?: number;
17
30
  } | {
18
31
  kind: "manual";
19
32
  };
@@ -59,6 +72,15 @@ export interface ClassifyStep {
59
72
  question?: string;
60
73
  fields?: unknown;
61
74
  instruction?: string;
75
+ /**
76
+ * Wélke tekst geclassificeerd wordt, als `$ref` in de run-vars. Default `$trigger.text`.
77
+ *
78
+ * Nodig zodra de trigger zelf geen tekst draagt. Een `INTERACTION_STATUS_CHANGED`-activity
79
+ * heeft alleen `{ fromStatus, toStatus }` in zijn payload, dus `trigger.text` is leeg — en
80
+ * dan krijgt het model een lege invoer. Met `input: "$thread"` leest de stap wat een
81
+ * eerdere `lookup` heeft opgehaald, zoals de berichten van het gesprek.
82
+ */
83
+ input?: string;
62
84
  }
63
85
  export interface GenerateStep {
64
86
  type: "generate";
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=140;function A(e){return e.replace(/<style[\s\S]*?<\/style>/gi," ").replace(/<script[\s\S]*?<\/script>/gi," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/g," ").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/\s+/g," ").trim()}function k(e){const t=e.trim();return t.length<=d?t:t.slice(0,d-1).trimEnd()+"…"}function l(e){if(!e||e<0)return"";const t=Math.floor(e/60),n=Math.floor(e%60);return`${t}:${n.toString().padStart(2,"0")}`}function V(e){switch(e.type){case"EMAIL_RECEIVED":case"EMAIL_SENT":{const t=e.payload,n=t.bodySnippet?.trim()||A(t.body??"");return t.subject?`${t.subject} — ${n}`:n}case"CHAT_MESSAGE_SENT":case"CHAT_MESSAGE_RECEIVED":return e.payload.text??"";case"CHAT_RENAMED":return`Hernoemd naar "${e.payload.newName}"`;case"CHAT_MEMBER_JOINED":return`${e.payload.members.map(t=>t.name).join(", ")} toegevoegd`;case"CHAT_MEMBER_LEFT":return`${e.payload.members.map(t=>t.name).join(", ")} verlaten`;case"CHAT_CALL_STARTED":return"Gesprek gestart";case"CHAT_CALL_ENDED":return`Gesprek beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"CHAT_EVENT":return e.payload.text??e.payload.eventType;case"VOICE_CALL_STARTED":case"VIDEO_CALL_STARTED":return"Gesprek gestart";case"VOICE_CALL_ANSWERED":case"VIDEO_CALL_ANSWERED":return"Gesprek aangenomen";case"VOICE_CALL_HOLD":case"VIDEO_CALL_HOLD":return"In de wacht";case"VOICE_CALL_UNHOLD":case"VIDEO_CALL_UNHOLD":return"Hervat";case"VOICE_CALL_ENDED":case"VIDEO_CALL_ENDED":return`Gesprek beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"VOICE_CALL_MISSED":case"VIDEO_CALL_MISSED":return"Gemiste oproep";case"VOICE_CALL_FAILED":case"VIDEO_CALL_FAILED":return"Gesprek mislukt";case"VOICE_CALL_VOICEMAIL":return e.payload.transcription?.trim()?e.payload.transcription:"Voicemail ontvangen";case"TRANSCRIPT_ADDED":return(e.payload.segments??[]).map(t=>t.text).join(" ");case"AI_MESSAGE_ADDED":return e.payload.output?.text??e.payload.input?.text??"";case"AI_ACTION_PROPOSED":return`Voorstel wacht op goedkeuring (${e.payload.actions?.length??0} actie(s))`;case"PLAYBOOK_STARTED":return`Playbook gestart${e.payload.playbookName?`: ${e.payload.playbookName}`:""}`;case"PLAYBOOK_COMPLETED":return"Playbook afgerond";case"PLAYBOOK_ESCALATED":return"Playbook geëscaleerd naar een mens";case"MEETING_SCHEDULED":return`Vergadering gepland: ${e.payload.title}`;case"MEETING_STARTED":return`Vergadering gestart: ${e.payload.title}`;case"MEETING_ENDED":return`Vergadering beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"MEETING_PARTICIPANT_JOINED":return`${e.payload.name} deelgenomen`;case"MEETING_PARTICIPANT_LEFT":return`${e.payload.name} verlaten`;case"COMMENT_ADDED":return e.payload.text??"";case"FILE_UPLOADED":return`Bestand: ${e.payload.fileName}`;case"INTERACTION_CREATED":return"Interactie aangemaakt";case"INTERACTION_STATUS_CHANGED":return`Status: ${e.payload.fromStatus} → ${e.payload.toStatus}`;case"INTERACTION_ASSIGNED":return"Interactie toegewezen";default:return""}}function G(e){return{activityId:e.id,type:e.type,snippet:k(V(e)),authorName:e.author?.name??"",direction:e.direction,createdAt:e.createdAt??Date.now()}}function $(e,t,n=[]){const r=e.createdAt;if(!r)return[];const a=new Set(n);return e.author.type==="user"&&e.author.id&&a.add(e.author.id),Object.entries(t).filter(([s,i])=>i>=r&&!a.has(s)).map(([s])=>s)}const w=[{id:"agent",label:"Agent",labelSource:"user"},{id:"team",label:"Team",labelSource:"team"},{id:"inbox",label:"Inbox",labelSource:"inbox"},{id:"channel",label:"Kanaal",labelSource:"channel"},{id:"provider",label:"Provider",labelSource:"raw"},{id:"status",label:"Status",labelSource:"raw"},{id:"handledBy",label:"Afhandelaar",labelSource:"raw"},{id:"time",label:"Tijd",labelSource:"raw"}];function H(e){const t=[];for(const n of Object.keys(e))for(const r of Object.keys(e[n]))t.push({lang:n,key:r,value:e[n][r]});return t}function c(e){return e<10?`0${e}`:`${e}`}function I(e,t){const n=new Date(e),r=`${n.getUTCFullYear()}-${c(n.getUTCMonth()+1)}-${c(n.getUTCDate())}`;return t==="day"?r:`${r}T${c(n.getUTCHours())}`}function S(e,t){const n=new Date(e);return n.setUTCMinutes(0,0,0),t==="day"&&n.setUTCHours(0),n.getTime()}const B=36e5,x=864e5;function F(e,t,n){const r=n==="hour"?B:x,a=[];for(let s=S(e,n);s<=t;s+=r)a.push(I(s,n));return a}const b=[{id:"resource",label:"Resource",labelSource:"raw"},{id:"origin",label:"Herkomst",labelSource:"raw"}],_=b.map(e=>e.id);function m(e,t){return`${e}.usage.${t}`}function v(e,t){return t.map(n=>({id:m(e,n.unit),label:n.label,category:"Verbruik",valueType:n.valueType??"count",aggregation:"sum",supportedDimensions:["provider",..._,...n.extraDimensions??[],"time"]}))}function W(e){return(e.startsWith("tool:")?e.slice(5):e).replace(/__/g," · ").replace(/\./g," · ").replace(/_/g," ")}const j=[{name:"text",type:"string"},{name:"subject",type:"string"},{name:"from",type:"string"},{name:"type",type:"string"},{name:"direction",type:"string"},{name:"channelId",type:"string"},{name:"interactionId",type:"string"},{name:"activityId",type:"string"},{name:"authorType",type:"string"},{name:"authorName",type:"string"},{name:"textRaw",type:"string"}],K={topics:[{name:"topic",type:"string"},{name:"confidence",type:"number"}],question:[{name:"answer",type:"boolean"},{name:"confidence",type:"number"}],extract:[]};function T(e){switch(e.kind){case"user":return`user:${e.userId}`;case"team":return`team:${e.teamId}`;case"org":return"org"}}function Y(e){if(typeof e!="string")return;const t=e.trim();if(t==="org")return{kind:"org"};const n=t.indexOf(":");if(n<=0)return;const r=t.slice(0,n),a=t.slice(n+1).trim();if(a){if(r==="user")return{kind:"user",userId:a};if(r==="team")return{kind:"team",teamId:a}}}function R(e){return T(e)}function q(e){switch(e.kind){case"personal":return{kind:"user",userId:e.userId};case"team":return{kind:"team",teamId:e.teamId};case"org":return{kind:"org"}}}function z(e){return R(e)}const N=["done","escalated","failed","timed_out","stopped"],M=["awaiting_approval","awaiting_reply"];function D(e){return N.includes(e)}function J(e){return D(e)}function Q(e){return M.includes(e)}const u=[{id:"openai",label:"OpenAI",capabilities:["chat","transcription","embedding"],defaultModel:"gpt-5-mini",baseUrl:"https://api.openai.com/v1"},{id:"gemini",label:"Google Gemini",capabilities:["chat","transcription","embedding"],defaultModel:"gemini-3.5-flash",baseUrl:"https://generativelanguage.googleapis.com/v1beta"},{id:"anthropic",label:"Anthropic",capabilities:["chat"],defaultModel:"claude-haiku-4-5",baseUrl:"https://api.anthropic.com/v1"},{id:"elevenlabs",label:"ElevenLabs",capabilities:["transcription"],baseUrl:"https://api.elevenlabs.io/v1"},{id:"moonshot",label:"Moonshot (Kimi)",capabilities:["chat"],defaultModel:"kimi-k3",baseUrl:"https://api.moonshot.ai/v1"},{id:"deepseek",label:"DeepSeek",capabilities:["chat"],defaultModel:"deepseek-v4-flash",baseUrl:"https://api.deepseek.com/v1"},{id:"groq",label:"Groq",capabilities:["chat"],defaultModel:"openai/gpt-oss-120b",baseUrl:"https://api.groq.com/openai/v1"},{id:"mistral",label:"Mistral",capabilities:["chat"],defaultModel:"mistral-large-latest",baseUrl:"https://api.mistral.ai/v1"},{id:"openrouter",label:"OpenRouter",capabilities:["chat"],defaultModel:"openrouter/auto",baseUrl:"https://openrouter.ai/api/v1"},{id:"ollama",label:"Ollama (self-hosted)",capabilities:["chat"],defaultModel:"llama3.3"},{id:"openai-compatible",label:"OpenAI-compatible (eigen endpoint)",capabilities:["chat"],defaultModel:"default"}];function o(e){return u.find(t=>t.id===e)}function X(e){return o(e)?.label??e}function Z(e,t="gpt-5-mini"){return o(e)?.defaultModel??t}function ee(e){return u.filter(t=>t.capabilities.includes(e))}function te(e){const t=o(e);return!!t&&!t.baseUrl}const ne=new Set(["mail","message"]);function O(e,t){const n=e.settings?.signatures?.[t];return!n||!n.enabled||!n.body||n.body.trim()===""?null:n}function re(e,t,n,r="html"){if(!e)return n;const a=O(e,t);return a?`${n}${r==="text"?`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=140;function f(e){return e.replace(/<style[\s\S]*?<\/style>/gi," ").replace(/<script[\s\S]*?<\/script>/gi," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/g," ").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/\s+/g," ").trim()}function G(e){const t=e.trim();return t.length<=d?t:t.slice(0,d-1).trimEnd()+"…"}function l(e){if(!e||e<0)return"";const t=Math.floor(e/60),n=Math.floor(e%60);return`${t}:${n.toString().padStart(2,"0")}`}function k(e){switch(e.type){case"EMAIL_RECEIVED":case"EMAIL_SENT":{const t=e.payload,n=t.bodySnippet?.trim()||f(t.body??"");return t.subject?`${t.subject} — ${n}`:n}case"CHAT_MESSAGE_SENT":case"CHAT_MESSAGE_RECEIVED":return e.payload.text??"";case"CHAT_RENAMED":return`Hernoemd naar "${e.payload.newName}"`;case"CHAT_MEMBER_JOINED":return`${e.payload.members.map(t=>t.name).join(", ")} toegevoegd`;case"CHAT_MEMBER_LEFT":return`${e.payload.members.map(t=>t.name).join(", ")} verlaten`;case"CHAT_CALL_STARTED":return"Gesprek gestart";case"CHAT_CALL_ENDED":return`Gesprek beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"CHAT_EVENT":return e.payload.text??e.payload.eventType;case"VOICE_CALL_STARTED":case"VIDEO_CALL_STARTED":return"Gesprek gestart";case"VOICE_CALL_ANSWERED":case"VIDEO_CALL_ANSWERED":return"Gesprek aangenomen";case"VOICE_CALL_HOLD":case"VIDEO_CALL_HOLD":return"In de wacht";case"VOICE_CALL_UNHOLD":case"VIDEO_CALL_UNHOLD":return"Hervat";case"VOICE_CALL_ENDED":case"VIDEO_CALL_ENDED":return`Gesprek beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"VOICE_CALL_MISSED":case"VIDEO_CALL_MISSED":return"Gemiste oproep";case"VOICE_CALL_FAILED":case"VIDEO_CALL_FAILED":return"Gesprek mislukt";case"VOICE_CALL_VOICEMAIL":return e.payload.transcription?.trim()?e.payload.transcription:"Voicemail ontvangen";case"TRANSCRIPT_ADDED":return(e.payload.segments??[]).map(t=>t.text).join(" ");case"AI_MESSAGE_ADDED":return e.payload.output?.text??e.payload.input?.text??"";case"AI_ACTION_PROPOSED":return`Voorstel wacht op goedkeuring (${e.payload.actions?.length??0} actie(s))`;case"PLAYBOOK_STARTED":return`Playbook gestart${e.payload.playbookName?`: ${e.payload.playbookName}`:""}`;case"PLAYBOOK_COMPLETED":return"Playbook afgerond";case"PLAYBOOK_ESCALATED":return"Playbook geëscaleerd naar een mens";case"MEETING_SCHEDULED":return`Vergadering gepland: ${e.payload.title}`;case"MEETING_STARTED":return`Vergadering gestart: ${e.payload.title}`;case"MEETING_ENDED":return`Vergadering beëindigd${e.payload.duration?` (${l(e.payload.duration)})`:""}`;case"MEETING_PARTICIPANT_JOINED":return`${e.payload.name} deelgenomen`;case"MEETING_PARTICIPANT_LEFT":return`${e.payload.name} verlaten`;case"COMMENT_ADDED":return e.payload.text??"";case"FILE_UPLOADED":return`Bestand: ${e.payload.fileName}`;case"INTERACTION_CREATED":return"Interactie aangemaakt";case"INTERACTION_STATUS_CHANGED":return`Status: ${e.payload.fromStatus} → ${e.payload.toStatus}`;case"INTERACTION_ASSIGNED":return"Interactie toegewezen";default:return""}}function V(e){return{activityId:e.id,type:e.type,snippet:G(k(e)),authorName:e.author?.name??"",direction:e.direction,createdAt:e.createdAt??Date.now()}}function $(e,t,n=[]){const r=e.createdAt;if(!r)return[];const a=new Set(n);return e.author.type==="user"&&e.author.id&&a.add(e.author.id),Object.entries(t).filter(([s,i])=>i>=r&&!a.has(s)).map(([s])=>s)}const H=[{id:"agent",label:"Agent",labelSource:"user"},{id:"team",label:"Team",labelSource:"team"},{id:"inbox",label:"Inbox",labelSource:"inbox"},{id:"channel",label:"Kanaal",labelSource:"channel"},{id:"provider",label:"Provider",labelSource:"raw"},{id:"status",label:"Status",labelSource:"raw"},{id:"handledBy",label:"Afhandelaar",labelSource:"raw"},{id:"time",label:"Tijd",labelSource:"raw"}];function w(e){const t=[];for(const n of Object.keys(e))for(const r of Object.keys(e[n]))t.push({lang:n,key:r,value:e[n][r]});return t}function c(e){return e<10?`0${e}`:`${e}`}function _(e,t){const n=new Date(e),r=`${n.getUTCFullYear()}-${c(n.getUTCMonth()+1)}-${c(n.getUTCDate())}`;return t==="day"?r:`${r}T${c(n.getUTCHours())}`}function I(e,t){const n=new Date(e);return n.setUTCMinutes(0,0,0),t==="day"&&n.setUTCHours(0),n.getTime()}const B=36e5,F=864e5;function x(e,t,n){const r=n==="hour"?B:F,a=[];for(let s=I(e,n);s<=t;s+=r)a.push(_(s,n));return a}const S=[{id:"resource",label:"Resource",labelSource:"raw"},{id:"origin",label:"Herkomst",labelSource:"raw"}],b=S.map(e=>e.id);function T(e,t){return`${e}.usage.${t}`}function v(e,t){return t.map(n=>({id:T(e,n.unit),label:n.label,category:"Verbruik",valueType:n.valueType??"count",aggregation:"sum",supportedDimensions:["provider",...b,...n.extraDimensions??[],"time"]}))}function Y(e){return(e.startsWith("tool:")?e.slice(5):e).replace(/__/g," · ").replace(/\./g," · ").replace(/_/g," ")}const W=[{name:"text",type:"string"},{name:"subject",type:"string"},{name:"from",type:"string"},{name:"type",type:"string"},{name:"direction",type:"string"},{name:"channelId",type:"string"},{name:"interactionId",type:"string"},{name:"activityId",type:"string"},{name:"authorType",type:"string"},{name:"authorName",type:"string"},{name:"textRaw",type:"string"},{name:"fromStatus",type:"string"},{name:"toStatus",type:"string"}],j={topics:[{name:"topic",type:"string"},{name:"confidence",type:"number"}],question:[{name:"answer",type:"boolean"},{name:"confidence",type:"number"}],extract:[]};function m(e){switch(e.kind){case"user":return`user:${e.userId}`;case"team":return`team:${e.teamId}`;case"org":return"org"}}function K(e){if(typeof e!="string")return;const t=e.trim();if(t==="org")return{kind:"org"};const n=t.indexOf(":");if(n<=0)return;const r=t.slice(0,n),a=t.slice(n+1).trim();if(a){if(r==="user")return{kind:"user",userId:a};if(r==="team")return{kind:"team",teamId:a}}}function M(e){return m(e)}function q(e){switch(e.kind){case"personal":return{kind:"user",userId:e.userId};case"team":return{kind:"team",teamId:e.teamId};case"org":return{kind:"org"}}}function X(e){return M(e)}const R=["done","escalated","failed","timed_out","stopped"],N=["awaiting_approval","awaiting_reply"];function D(e){return R.includes(e)}function z(e){return D(e)}function J(e){return N.includes(e)}const u=[{id:"openai",label:"OpenAI",capabilities:["chat","transcription","embedding"],defaultModel:"gpt-5-mini",baseUrl:"https://api.openai.com/v1"},{id:"gemini",label:"Google Gemini",capabilities:["chat","transcription","embedding"],defaultModel:"gemini-3.5-flash",baseUrl:"https://generativelanguage.googleapis.com/v1beta"},{id:"anthropic",label:"Anthropic",capabilities:["chat"],defaultModel:"claude-haiku-4-5",baseUrl:"https://api.anthropic.com/v1"},{id:"elevenlabs",label:"ElevenLabs",capabilities:["transcription"],baseUrl:"https://api.elevenlabs.io/v1"},{id:"moonshot",label:"Moonshot (Kimi)",capabilities:["chat"],defaultModel:"kimi-k3",baseUrl:"https://api.moonshot.ai/v1"},{id:"deepseek",label:"DeepSeek",capabilities:["chat"],defaultModel:"deepseek-v4-flash",baseUrl:"https://api.deepseek.com/v1"},{id:"groq",label:"Groq",capabilities:["chat"],defaultModel:"openai/gpt-oss-120b",baseUrl:"https://api.groq.com/openai/v1"},{id:"mistral",label:"Mistral",capabilities:["chat"],defaultModel:"mistral-large-latest",baseUrl:"https://api.mistral.ai/v1"},{id:"openrouter",label:"OpenRouter",capabilities:["chat"],defaultModel:"openrouter/auto",baseUrl:"https://openrouter.ai/api/v1"},{id:"ollama",label:"Ollama (self-hosted)",capabilities:["chat"],defaultModel:"llama3.3"},{id:"openai-compatible",label:"OpenAI-compatible (eigen endpoint)",capabilities:["chat"],defaultModel:"default"}];function o(e){return u.find(t=>t.id===e)}function Q(e){return o(e)?.label??e}function Z(e,t="gpt-5-mini"){return o(e)?.defaultModel??t}function ee(e){return u.filter(t=>t.capabilities.includes(e))}function te(e){const t=o(e);return!!t&&!t.baseUrl}const ne=new Set(["mail","message"]);function O(e,t){const n=e.settings?.signatures?.[t];return!n||!n.enabled||!n.body||n.body.trim()===""?null:n}function re(e,t,n,r="html"){if(!e)return n;const a=O(e,t);return a?`${n}${r==="text"?`
2
2
 
3
- `:t==="mail"?"<br><br>-- <br>":"<br><br>"}${a.body}`:n}function ae(e){return e.endpoints??[]}const se=e=>!!e.assignedUserId||!!e.assignedInboxId,ie=e=>e.status==="closed",oe=e=>({urgent:10,high:5,normal:2,low:1})[e.priority]||0,le=(e,t=30)=>e.title?.length<=t?e.title:`${e.title.substring(0,t)}...`;function ce(e,t){return e.lastActivityAt?!(e.seenBy??[]).includes(t):!1}const ue=[/<blockquote/i,/class="?gmail_quote/i,/id="?[^"]*divRplyFwdMsg/i,/id="?[^"]*mail-editor-reference-message-container/i,/-{3,}\s*Original Message\s*-{3,}/i,/\n_{5,}\s*\n/,/\bOn\b[\s\S]{0,200}?\bwrote:/i],p=/^\s*(?:>+\s*)?(?:from|van|sent|verzonden|to|aan|cc|subject|onderwerp|date|datum)\s*:/i,de=/^\s*(?:on|op)\b.{0,200}?\b(?:wrote|schreef|geschreven)\s*:?\s*$/i;function pe(e){const t=e.split(`
4
- `);for(let n=0;n<t.length;n++)if(de.test(t[n])||p.test(t[n])&&t.slice(n+1,n+4).some(r=>p.test(r)))return t.slice(0,n).join(`
3
+ `:t==="mail"?"<br><br>-- <br>":"<br><br>"}${a.body}`:n}function ae(e){return e.endpoints??[]}const se=e=>!!e.assignedUserId||!!e.assignedInboxId,ie=e=>e.status==="closed",oe=e=>({urgent:10,high:5,normal:2,low:1})[e.priority]||0,le=(e,t=30)=>e.title?.length<=t?e.title:`${e.title.substring(0,t)}...`;function ce(e,t){return e.lastActivityAt?!(e.seenBy??[]).includes(t):!1}const ue=2e3,de=500,pe=12e3,Ee=4e3,ge=[/<blockquote/i,/class="?gmail_quote/i,/id="?[^"]*divRplyFwdMsg/i,/id="?[^"]*mail-editor-reference-message-container/i,/-{3,}\s*Original Message\s*-{3,}/i,/\n_{5,}\s*\n/,/\bOn\b[\s\S]{0,200}?\bwrote:/i],p=/^\s*(?:>+\s*)?(?:from|van|sent|verzonden|to|aan|cc|subject|onderwerp|date|datum)\s*:/i,Ae=/^\s*(?:on|op)\b.{0,200}?\b(?:wrote|schreef|geschreven)\s*:?\s*$/i;function fe(e){const t=e.split(`
4
+ `);for(let n=0;n<t.length;n++)if(Ae.test(t[n])||p.test(t[n])&&t.slice(n+1,n+4).some(r=>p.test(r)))return t.slice(0,n).join(`
5
5
  `).trim();return e}function E(e){let t=e;return t=t.replace(/<(script|style)[\s\S]*?<\/\1>/gi,""),t=t.replace(/<br\s*\/?>/gi,`
6
6
  `),t=t.replace(/<\/(p|div|li|tr|h[1-6]|ul|ol|table)>/gi,`
7
- `),t=t.replace(/<[^>]+>/g,""),t=t.replace(/<[^>]*$/,""),t}function g(e){return e.replace(/&nbsp;/gi," ").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/&#(\d+);/g,(t,n)=>String.fromCharCode(Number(n))).replace(/&amp;/gi,"&")}function f(e){return e.replace(/\r/g,"").replace(/[ \t]+/g," ").replace(/ *\n */g,`
7
+ `),t=t.replace(/<[^>]+>/g,""),t=t.replace(/<[^>]*$/,""),t}function g(e){return e.replace(/&nbsp;/gi," ").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/&#(\d+);/g,(t,n)=>String.fromCharCode(Number(n))).replace(/&amp;/gi,"&")}function A(e){return e.replace(/\r/g,"").replace(/[ \t]+/g," ").replace(/ *\n */g,`
8
8
  `).replace(/\n{3,}/g,`
9
9
 
10
- `).trim()}function Ee(e){if(typeof e!="string"||!e)return"";let t=e.length;for(const s of ue){const i=e.search(s);i>=0&&i<t&&(t=i)}const n=e.slice(0,t);let r=f(g(E(n)));return r||(r=f(g(E(e)))),pe(r)||r}const ge=/(^|[._+-])(no-?reply|noreply|donotreply|do-not-reply|newsletter|nieuwsbrief|mailer|mailing|notifications?|bounce|postmaster|marketing)@/i,fe=/\b(unsubscribe|afmelden|uitschrijven|opt[\s-]?out|manage (your )?preferences|geen (e-?mails?|nieuwsbrief|berichten) meer)\b/i;function Ae(e,t){return!!(e&&ge.test(e)||t&&fe.test(t))}const h=3,y=600;function Ie(e,t){return e>=h||t>=y}function L(e,t){const n=new Set(e.disabledIntents??[]),r=e.intentOverrides??{},a=t.intents.filter(i=>!n.has(i.intent)).map(i=>be(i,r[i.intent]));if(!e.extraIntents||e.extraIntents.length===0)return a;const s=new Set(a.map(i=>i.intent));for(const i of e.extraIntents)s.has(i.intent)||(a.push(i),s.add(i.intent));return a}function C(e,t){const n={};for(const r of e.intents){if(!r.togglable)continue;const a=t?.[r.intent];n[r.intent]=a??r.defaultEnabled??!0}return n}function Se(e,t){const n=C(e,t);return Object.entries(n).filter(([,r])=>!r).map(([r])=>r)}function be(e,t){return t?{intent:t.intent??e.intent,targetSchemes:t.targetSchemes??e.targetSchemes,transport:t.transport??e.transport}:e}function _e(e,t){const n=[];for(const r of e){if(!r.enabled)continue;const a=t[r.providerId];if(a)for(const s of L(r,a))n.push({channel:r,description:a,capability:s})}return n}function me(e,t){return t.filter(n=>n.capability.intent===e)}function U(e,t){return t.filter(n=>n.capability.targetSchemes.includes(e))}function Te(e,t){return U(e.scheme,t)}function Re(e,t,n){const r=[];for(const a of e)for(const s of n)s.capability.intent===t&&s.capability.targetSchemes.includes(a.scheme)&&r.push({channelIntent:s,endpoint:a});return r}var P=(e=>(e.MAILTO="mailto",e.SIP="sip",e.TEL="tel",e.WEBHOOK="webhook",e.USERNAME="username",e.ID="id",e.CUSTOM="custom",e.URL="url",e.TELEGRAM="telegram",e.WHATSAPP="whatsapp",e.MESSENGER="messenger",e.INSTAGRAM="instagram",e.VIBER="viber",e.SMS="sms",e.FAX="fax",e.TEAMS="teams",e.CALENDAR="calendar",e))(P||{});const Ne="message_window",Me="message_templates",De={FROM:"from",TO:"to",CC:"cc",BCC:"bcc",ORGANIZER:"organizer",PRESENTER:"presenter",ATTENDEE:"attendee",OWNER:"owner",MEMBER:"member",GUEST:"guest",HOST:"host",PARTICIPANT:"participant"},Oe=(e,t)=>({intent:e,...t}),he="folder_management",ye="remote_search",Le={ok:!1,code:"UNSUPPORTED",message:"Provider does not support this op"},Ce=9e4,Ue="installation-id";exports.AI_VENDORS=u;exports.CLASSIFY_VARS=K;exports.CORE_DIMENSIONS=w;exports.CommunicationScheme=P;exports.FEATURE_FOLDER_MANAGEMENT=he;exports.FEATURE_REMOTE_SEARCH=ye;exports.INSTALLATION_HEADER=Ue;exports.InteractionParticipantRole=De;exports.PAUSED_RUN_STATUSES=M;exports.PRESENCE_ONLINE_WINDOW_MS=Ce;exports.PROVIDER_FEATURE_MESSAGE_TEMPLATES=Me;exports.PROVIDER_FEATURE_MESSAGE_WINDOW=Ne;exports.SIGNATURE_INTENTS=ne;exports.SUMMARY_MIN_LAST_CHARS=y;exports.SUMMARY_MIN_MESSAGES=h;exports.TERMINAL_RUN_STATUSES=N;exports.TRIGGER_VARS=j;exports.UNSUPPORTED=Le;exports.USAGE_DIMENSIONS=b;exports.USAGE_DIMENSION_IDS=_;exports.actingIdentityKey=R;exports.actorKey=z;exports.aiVendorDefaultModel=Z;exports.aiVendorLabel=X;exports.aiVendorNeedsBaseUrl=te;exports.aiVendorsWith=ee;exports.applySignature=re;exports.buildActivityPreview=G;exports.buildChannelIntents=_e;exports.cleanMessageText=Ee;exports.defineIntent=Oe;exports.disabledIntentsFromCapabilities=Se;exports.filterByEndpoint=Te;exports.filterByIntent=me;exports.filterByTargetScheme=U;exports.findAiVendor=o;exports.flattenLocales=H;exports.floorToPeriod=S;exports.formatActingIdentity=T;exports.formatPeriod=I;exports.getActivitySeenUserIds=$;exports.getContactEndpoints=ae;exports.getShortTitle=le;exports.getUrgencyScore=oe;exports.humanizeAction=W;exports.isAssigned=se;exports.isClosed=ie;exports.isInteractionUnseen=ce;exports.isLikelyBulk=Ae;exports.isPaused=Q;exports.isRetryable=J;exports.isTerminal=D;exports.isThreadLongEnough=Ie;exports.matchContactToIntents=Re;exports.parseActingIdentity=Y;exports.periodsInRange=F;exports.playbookActor=q;exports.resolveAccountCapabilities=C;exports.resolveChannelIntents=L;exports.resolveSignature=O;exports.stripHtml=A;exports.usageMetricId=m;exports.usageMetrics=v;
10
+ `).trim()}function _e(e){if(typeof e!="string"||!e)return"";let t=e.length;for(const s of ge){const i=e.search(s);i>=0&&i<t&&(t=i)}const n=e.slice(0,t);let r=A(g(E(n)));return r||(r=A(g(E(e)))),fe(r)||r}const Ie=/(^|[._+-])(no-?reply|noreply|donotreply|do-not-reply|newsletter|nieuwsbrief|mailer|mailing|notifications?|bounce|postmaster|marketing)@/i,Se=/\b(unsubscribe|afmelden|uitschrijven|opt[\s-]?out|manage (your )?preferences|geen (e-?mails?|nieuwsbrief|berichten) meer)\b/i;function be(e,t){return!!(e&&Ie.test(e)||t&&Se.test(t))}const h=3,y=600;function Te(e,t){return e>=h||t>=y}function L(e,t){const n=new Set(e.disabledIntents??[]),r=e.intentOverrides??{},a=t.intents.filter(i=>!n.has(i.intent)).map(i=>Me(i,r[i.intent]));if(!e.extraIntents||e.extraIntents.length===0)return a;const s=new Set(a.map(i=>i.intent));for(const i of e.extraIntents)s.has(i.intent)||(a.push(i),s.add(i.intent));return a}function U(e,t){const n={};for(const r of e.intents){if(!r.togglable)continue;const a=t?.[r.intent];n[r.intent]=a??r.defaultEnabled??!0}return n}function me(e,t){const n=U(e,t);return Object.entries(n).filter(([,r])=>!r).map(([r])=>r)}function Me(e,t){return t?{intent:t.intent??e.intent,targetSchemes:t.targetSchemes??e.targetSchemes,transport:t.transport??e.transport}:e}function Re(e,t){const n=[];for(const r of e){if(!r.enabled)continue;const a=t[r.providerId];if(a)for(const s of L(r,a))n.push({channel:r,description:a,capability:s})}return n}function Ne(e,t){return t.filter(n=>n.capability.intent===e)}function C(e,t){return t.filter(n=>n.capability.targetSchemes.includes(e))}function De(e,t){return C(e.scheme,t)}function Oe(e,t,n){const r=[];for(const a of e)for(const s of n)s.capability.intent===t&&s.capability.targetSchemes.includes(a.scheme)&&r.push({channelIntent:s,endpoint:a});return r}var P=(e=>(e.MAILTO="mailto",e.SIP="sip",e.TEL="tel",e.WEBHOOK="webhook",e.USERNAME="username",e.ID="id",e.CUSTOM="custom",e.URL="url",e.TELEGRAM="telegram",e.WHATSAPP="whatsapp",e.MESSENGER="messenger",e.INSTAGRAM="instagram",e.VIBER="viber",e.SMS="sms",e.FAX="fax",e.TEAMS="teams",e.CALENDAR="calendar",e))(P||{});const he="message_window",ye="message_templates",Le={FROM:"from",TO:"to",CC:"cc",BCC:"bcc",ORGANIZER:"organizer",PRESENTER:"presenter",ATTENDEE:"attendee",OWNER:"owner",MEMBER:"member",GUEST:"guest",HOST:"host",PARTICIPANT:"participant"},Ue=(e,t)=>({intent:e,...t}),Ce="folder_management",Pe="remote_search",Ge={ok:!1,code:"UNSUPPORTED",message:"Provider does not support this op"},ke=9e4,Ve="installation-id";exports.AI_VENDORS=u;exports.CLASSIFY_VARS=j;exports.CORE_DIMENSIONS=H;exports.CommunicationScheme=P;exports.DEFAULT_MEMORY_BUDGET=Ee;exports.FEATURE_FOLDER_MANAGEMENT=Ce;exports.FEATURE_REMOTE_SEARCH=Pe;exports.INSTALLATION_HEADER=Ve;exports.InteractionParticipantRole=Le;exports.MAX_MEMORY_BUDGET=pe;exports.MAX_MEMORY_CHARS=ue;exports.MIN_MEMORY_BUDGET=de;exports.PAUSED_RUN_STATUSES=N;exports.PRESENCE_ONLINE_WINDOW_MS=ke;exports.PROVIDER_FEATURE_MESSAGE_TEMPLATES=ye;exports.PROVIDER_FEATURE_MESSAGE_WINDOW=he;exports.SIGNATURE_INTENTS=ne;exports.SUMMARY_MIN_LAST_CHARS=y;exports.SUMMARY_MIN_MESSAGES=h;exports.TERMINAL_RUN_STATUSES=R;exports.TRIGGER_VARS=W;exports.UNSUPPORTED=Ge;exports.USAGE_DIMENSIONS=S;exports.USAGE_DIMENSION_IDS=b;exports.actingIdentityKey=M;exports.actorKey=X;exports.aiVendorDefaultModel=Z;exports.aiVendorLabel=Q;exports.aiVendorNeedsBaseUrl=te;exports.aiVendorsWith=ee;exports.applySignature=re;exports.buildActivityPreview=V;exports.buildChannelIntents=Re;exports.cleanMessageText=_e;exports.defineIntent=Ue;exports.disabledIntentsFromCapabilities=me;exports.filterByEndpoint=De;exports.filterByIntent=Ne;exports.filterByTargetScheme=C;exports.findAiVendor=o;exports.flattenLocales=w;exports.floorToPeriod=I;exports.formatActingIdentity=m;exports.formatPeriod=_;exports.getActivitySeenUserIds=$;exports.getContactEndpoints=ae;exports.getShortTitle=le;exports.getUrgencyScore=oe;exports.humanizeAction=Y;exports.isAssigned=se;exports.isClosed=ie;exports.isInteractionUnseen=ce;exports.isLikelyBulk=be;exports.isPaused=J;exports.isRetryable=z;exports.isTerminal=D;exports.isThreadLongEnough=Te;exports.matchContactToIntents=Oe;exports.parseActingIdentity=K;exports.periodsInRange=x;exports.playbookActor=q;exports.resolveAccountCapabilities=U;exports.resolveChannelIntents=L;exports.resolveSignature=O;exports.stripHtml=f;exports.usageMetricId=T;exports.usageMetrics=v;
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from './entities/calendar-event';
18
18
  export * from './entities/draft';
19
19
  export * from './entities/inbox';
20
20
  export * from './entities/interaction';
21
+ export * from './entities/memory';
21
22
  export * from './entities/task';
22
23
  export * from './entities/note';
23
24
  export * from './entities/read-state';
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ const W = [
117
117
  { id: "handledBy", label: "Afhandelaar", labelSource: "raw" },
118
118
  { id: "time", label: "Tijd", labelSource: "raw" }
119
119
  ];
120
- function K(e) {
120
+ function Y(e) {
121
121
  const t = [];
122
122
  for (const n of Object.keys(e))
123
123
  for (const r of Object.keys(e[n]))
@@ -131,43 +131,43 @@ function m(e, t) {
131
131
  const n = new Date(e), r = `${n.getUTCFullYear()}-${l(n.getUTCMonth() + 1)}-${l(n.getUTCDate())}`;
132
132
  return t === "day" ? r : `${r}T${l(n.getUTCHours())}`;
133
133
  }
134
- function I(e, t) {
134
+ function _(e, t) {
135
135
  const n = new Date(e);
136
136
  return n.setUTCMinutes(0, 0, 0), t === "day" && n.setUTCHours(0), n.getTime();
137
137
  }
138
- const _ = 36e5, S = 864e5;
139
- function q(e, t, n) {
140
- const r = n === "hour" ? _ : S, a = [];
141
- for (let s = I(e, n); s <= t; s += r)
138
+ const I = 36e5, T = 864e5;
139
+ function K(e, t, n) {
140
+ const r = n === "hour" ? I : T, a = [];
141
+ for (let s = _(e, n); s <= t; s += r)
142
142
  a.push(m(s, n));
143
143
  return a;
144
144
  }
145
- const T = [
145
+ const S = [
146
146
  { id: "resource", label: "Resource", labelSource: "raw" },
147
147
  { id: "origin", label: "Herkomst", labelSource: "raw" }
148
- ], D = T.map((e) => e.id);
149
- function N(e, t) {
148
+ ], M = S.map((e) => e.id);
149
+ function D(e, t) {
150
150
  return `${e}.usage.${t}`;
151
151
  }
152
- function Y(e, t) {
152
+ function q(e, t) {
153
153
  return t.map((n) => ({
154
- id: N(e, n.unit),
154
+ id: D(e, n.unit),
155
155
  label: n.label,
156
156
  category: "Verbruik",
157
157
  valueType: n.valueType ?? "count",
158
158
  aggregation: "sum",
159
159
  supportedDimensions: [
160
160
  "provider",
161
- ...D,
161
+ ...M,
162
162
  ...n.extraDimensions ?? [],
163
163
  "time"
164
164
  ]
165
165
  }));
166
166
  }
167
- function z(e) {
167
+ function X(e) {
168
168
  return (e.startsWith("tool:") ? e.slice(5) : e).replace(/__/g, " · ").replace(/\./g, " · ").replace(/_/g, " ");
169
169
  }
170
- const X = [
170
+ const z = [
171
171
  { name: "text", type: "string" },
172
172
  { name: "subject", type: "string" },
173
173
  { name: "from", type: "string" },
@@ -178,7 +178,15 @@ const X = [
178
178
  { name: "activityId", type: "string" },
179
179
  { name: "authorType", type: "string" },
180
180
  { name: "authorName", type: "string" },
181
- { name: "textRaw", type: "string" }
181
+ { name: "textRaw", type: "string" },
182
+ // Alleen gevuld bij INTERACTION_STATUS_CHANGED; een filter als
183
+ // `trigger.toStatus == "closed"` is de trigger voor "onthoud dit bij afsluiten".
184
+ { name: "fromStatus", type: "string" },
185
+ { name: "toStatus", type: "string" }
186
+ // Bewust GEEN `contactId`. Een interactie draagt geen contact-id; dat zou per run een
187
+ // lookup via `remoteParty` naar de contactenlijst kosten, en dan hangt geheugen op
188
+ // klantniveau aan een gok in plaats van aan een vastgelegde identiteit. Zodra partijen
189
+ // wél in de database staan (party/CRM) komt dit terug als een echt veld.
182
190
  ], J = {
183
191
  topics: [
184
192
  { name: "topic", type: "string" },
@@ -190,7 +198,7 @@ const X = [
190
198
  ],
191
199
  extract: []
192
200
  };
193
- function h(e) {
201
+ function N(e) {
194
202
  switch (e.kind) {
195
203
  case "user":
196
204
  return `user:${e.userId}`;
@@ -212,8 +220,8 @@ function Q(e) {
212
220
  if (r === "team") return { kind: "team", teamId: a };
213
221
  }
214
222
  }
215
- function M(e) {
216
- return h(e);
223
+ function R(e) {
224
+ return N(e);
217
225
  }
218
226
  function Z(e) {
219
227
  switch (e.kind) {
@@ -226,17 +234,17 @@ function Z(e) {
226
234
  }
227
235
  }
228
236
  function ee(e) {
229
- return M(e);
237
+ return R(e);
230
238
  }
231
- const R = ["done", "escalated", "failed", "timed_out", "stopped"], O = ["awaiting_approval", "awaiting_reply"];
239
+ const O = ["done", "escalated", "failed", "timed_out", "stopped"], h = ["awaiting_approval", "awaiting_reply"];
232
240
  function L(e) {
233
- return R.includes(e);
241
+ return O.includes(e);
234
242
  }
235
243
  function te(e) {
236
244
  return L(e);
237
245
  }
238
246
  function ne(e) {
239
- return O.includes(e);
247
+ return h.includes(e);
240
248
  }
241
249
  const g = [
242
250
  {
@@ -366,7 +374,7 @@ const ue = (e) => !!e.assignedUserId || !!e.assignedInboxId, de = (e) => e.statu
366
374
  function ge(e, t) {
367
375
  return e.lastActivityAt ? !(e.seenBy ?? []).includes(t) : !1;
368
376
  }
369
- const C = [
377
+ const fe = 2e3, be = 500, Ae = 12e3, me = 4e3, C = [
370
378
  /<blockquote/i,
371
379
  /class="?gmail_quote/i,
372
380
  // Gmail quote container
@@ -404,7 +412,7 @@ function E(e) {
404
412
 
405
413
  `).trim();
406
414
  }
407
- function fe(e) {
415
+ function _e(e) {
408
416
  if (typeof e != "string" || !e) return "";
409
417
  let t = e.length;
410
418
  for (const s of C) {
@@ -416,12 +424,12 @@ function fe(e) {
416
424
  return r || (r = E(p(d(e)))), k(r) || r;
417
425
  }
418
426
  const P = /(^|[._+-])(no-?reply|noreply|donotreply|do-not-reply|newsletter|nieuwsbrief|mailer|mailing|notifications?|bounce|postmaster|marketing)@/i, $ = /\b(unsubscribe|afmelden|uitschrijven|opt[\s-]?out|manage (your )?preferences|geen (e-?mails?|nieuwsbrief|berichten) meer)\b/i;
419
- function be(e, t) {
427
+ function Ie(e, t) {
420
428
  return !!(e && P.test(e) || t && $.test(t));
421
429
  }
422
- const V = 3, G = 600;
423
- function Ae(e, t) {
424
- return e >= V || t >= G;
430
+ const G = 3, V = 600;
431
+ function Te(e, t) {
432
+ return e >= G || t >= V;
425
433
  }
426
434
  function w(e, t) {
427
435
  const n = new Set(e.disabledIntents ?? []), r = e.intentOverrides ?? {}, a = t.intents.filter((o) => !n.has(o.intent)).map((o) => x(o, r[o.intent]));
@@ -440,7 +448,7 @@ function H(e, t) {
440
448
  }
441
449
  return n;
442
450
  }
443
- function me(e, t) {
451
+ function Se(e, t) {
444
452
  const n = H(e, t);
445
453
  return Object.entries(n).filter(([, r]) => !r).map(([r]) => r);
446
454
  }
@@ -451,7 +459,7 @@ function x(e, t) {
451
459
  transport: t.transport ?? e.transport
452
460
  } : e;
453
461
  }
454
- function Ie(e, t) {
462
+ function Me(e, t) {
455
463
  const n = [];
456
464
  for (const r of e) {
457
465
  if (!r.enabled) continue;
@@ -462,16 +470,16 @@ function Ie(e, t) {
462
470
  }
463
471
  return n;
464
472
  }
465
- function _e(e, t) {
473
+ function De(e, t) {
466
474
  return t.filter((n) => n.capability.intent === e);
467
475
  }
468
476
  function B(e, t) {
469
477
  return t.filter((n) => n.capability.targetSchemes.includes(e));
470
478
  }
471
- function Se(e, t) {
479
+ function Ne(e, t) {
472
480
  return B(e.scheme, t);
473
481
  }
474
- function Te(e, t, n) {
482
+ function Re(e, t, n) {
475
483
  const r = [];
476
484
  for (const a of e)
477
485
  for (const s of n)
@@ -479,7 +487,7 @@ function Te(e, t, n) {
479
487
  return r;
480
488
  }
481
489
  var F = /* @__PURE__ */ ((e) => (e.MAILTO = "mailto", e.SIP = "sip", e.TEL = "tel", e.WEBHOOK = "webhook", e.USERNAME = "username", e.ID = "id", e.CUSTOM = "custom", e.URL = "url", e.TELEGRAM = "telegram", e.WHATSAPP = "whatsapp", e.MESSENGER = "messenger", e.INSTAGRAM = "instagram", e.VIBER = "viber", e.SMS = "sms", e.FAX = "fax", e.TEAMS = "teams", e.CALENDAR = "calendar", e))(F || {});
482
- const De = "message_window", Ne = "message_templates", he = {
490
+ const Oe = "message_window", he = "message_templates", Le = {
483
491
  // E-mail
484
492
  FROM: "from",
485
493
  TO: "to",
@@ -496,29 +504,33 @@ const De = "message_window", Ne = "message_templates", he = {
496
504
  // Voice/conference
497
505
  HOST: "host",
498
506
  PARTICIPANT: "participant"
499
- }, Me = (e, t) => ({ intent: e, ...t }), Re = "folder_management", Oe = "remote_search", Le = { ok: !1, code: "UNSUPPORTED", message: "Provider does not support this op" }, ye = 9e4, Ce = "installation-id";
507
+ }, ye = (e, t) => ({ intent: e, ...t }), Ce = "folder_management", Ue = "remote_search", ke = { ok: !1, code: "UNSUPPORTED", message: "Provider does not support this op" }, Pe = 9e4, $e = "installation-id";
500
508
  export {
501
509
  g as AI_VENDORS,
502
510
  J as CLASSIFY_VARS,
503
511
  W as CORE_DIMENSIONS,
504
512
  F as CommunicationScheme,
505
- Re as FEATURE_FOLDER_MANAGEMENT,
506
- Oe as FEATURE_REMOTE_SEARCH,
507
- Ce as INSTALLATION_HEADER,
508
- he as InteractionParticipantRole,
509
- O as PAUSED_RUN_STATUSES,
510
- ye as PRESENCE_ONLINE_WINDOW_MS,
511
- Ne as PROVIDER_FEATURE_MESSAGE_TEMPLATES,
512
- De as PROVIDER_FEATURE_MESSAGE_WINDOW,
513
+ me as DEFAULT_MEMORY_BUDGET,
514
+ Ce as FEATURE_FOLDER_MANAGEMENT,
515
+ Ue as FEATURE_REMOTE_SEARCH,
516
+ $e as INSTALLATION_HEADER,
517
+ Le as InteractionParticipantRole,
518
+ Ae as MAX_MEMORY_BUDGET,
519
+ fe as MAX_MEMORY_CHARS,
520
+ be as MIN_MEMORY_BUDGET,
521
+ h as PAUSED_RUN_STATUSES,
522
+ Pe as PRESENCE_ONLINE_WINDOW_MS,
523
+ he as PROVIDER_FEATURE_MESSAGE_TEMPLATES,
524
+ Oe as PROVIDER_FEATURE_MESSAGE_WINDOW,
513
525
  ie as SIGNATURE_INTENTS,
514
- G as SUMMARY_MIN_LAST_CHARS,
515
- V as SUMMARY_MIN_MESSAGES,
516
- R as TERMINAL_RUN_STATUSES,
517
- X as TRIGGER_VARS,
518
- Le as UNSUPPORTED,
519
- T as USAGE_DIMENSIONS,
520
- D as USAGE_DIMENSION_IDS,
521
- M as actingIdentityKey,
526
+ V as SUMMARY_MIN_LAST_CHARS,
527
+ G as SUMMARY_MIN_MESSAGES,
528
+ O as TERMINAL_RUN_STATUSES,
529
+ z as TRIGGER_VARS,
530
+ ke as UNSUPPORTED,
531
+ S as USAGE_DIMENSIONS,
532
+ M as USAGE_DIMENSION_IDS,
533
+ R as actingIdentityKey,
522
534
  ee as actorKey,
523
535
  ae as aiVendorDefaultModel,
524
536
  re as aiVendorLabel,
@@ -526,39 +538,39 @@ export {
526
538
  se as aiVendorsWith,
527
539
  le as applySignature,
528
540
  j as buildActivityPreview,
529
- Ie as buildChannelIntents,
530
- fe as cleanMessageText,
531
- Me as defineIntent,
532
- me as disabledIntentsFromCapabilities,
533
- Se as filterByEndpoint,
534
- _e as filterByIntent,
541
+ Me as buildChannelIntents,
542
+ _e as cleanMessageText,
543
+ ye as defineIntent,
544
+ Se as disabledIntentsFromCapabilities,
545
+ Ne as filterByEndpoint,
546
+ De as filterByIntent,
535
547
  B as filterByTargetScheme,
536
548
  c as findAiVendor,
537
- K as flattenLocales,
538
- I as floorToPeriod,
539
- h as formatActingIdentity,
549
+ Y as flattenLocales,
550
+ _ as floorToPeriod,
551
+ N as formatActingIdentity,
540
552
  m as formatPeriod,
541
553
  v as getActivitySeenUserIds,
542
554
  ce as getContactEndpoints,
543
555
  Ee as getShortTitle,
544
556
  pe as getUrgencyScore,
545
- z as humanizeAction,
557
+ X as humanizeAction,
546
558
  ue as isAssigned,
547
559
  de as isClosed,
548
560
  ge as isInteractionUnseen,
549
- be as isLikelyBulk,
561
+ Ie as isLikelyBulk,
550
562
  ne as isPaused,
551
563
  te as isRetryable,
552
564
  L as isTerminal,
553
- Ae as isThreadLongEnough,
554
- Te as matchContactToIntents,
565
+ Te as isThreadLongEnough,
566
+ Re as matchContactToIntents,
555
567
  Q as parseActingIdentity,
556
- q as periodsInRange,
568
+ K as periodsInRange,
557
569
  Z as playbookActor,
558
570
  H as resolveAccountCapabilities,
559
571
  w as resolveChannelIntents,
560
572
  y as resolveSignature,
561
573
  f as stripHtml,
562
- N as usageMetricId,
563
- Y as usageMetrics
574
+ D as usageMetricId,
575
+ q as usageMetrics
564
576
  };
@@ -59,6 +59,23 @@ export interface AiToolDescriptor extends AiTool {
59
59
  * overal.
60
60
  */
61
61
  surface?: "interactive";
62
+ /**
63
+ * Reikt deze tool naar **buiten** de organisatie, of blijft het intern?
64
+ *
65
+ * `"outward"` = er gaat iets de deur uit of er verschijnt iets bij een derde: een mail
66
+ * versturen, een ticket aanmaken, in Slack posten. Twee autonome playbooks die dat
67
+ * tegelijk op hetzelfde gesprek doen leveren dubbele berichten aan een klant, en dáár
68
+ * hoort een mens tussen te staan.
69
+ *
70
+ * `"internal"` = het resultaat blijft binnen het platform: een attribuut, een
71
+ * geheugen-item, een notitie. Twee playbooks die dat tegelijk doen zitten elkaar niet in
72
+ * de weg — verschillende rijen, en de concurrency wordt al door de store afgehandeld.
73
+ *
74
+ * **Afwezig betekent `"outward"`.** Bewust de voorzichtige kant: een tool die niets
75
+ * declareert hoort niet stilzwijgend als onschuldig te gelden. Zie
76
+ * `shouldDemoteAuto` in de playbook-engine, dat hierop de suggest-degradatie bepaalt.
77
+ */
78
+ effect?: "internal" | "outward";
62
79
  }
63
80
  /**
64
81
  * Body van `POST /provider/ai-tools/invoke`. Vervangt vijf inline structurele
@@ -1,9 +1,26 @@
1
+ import { OwnerScope } from '../entities/contact/types';
1
2
  import { ActingIdentity } from './identity';
2
3
  /** Access decision + whether the scope anchor is team-shared + the SSE audience. */
3
4
  export interface ScopeAuth {
4
5
  allowed: boolean;
5
6
  shared?: boolean;
6
7
  audience?: string[];
8
+ /**
9
+ * Van wie deze resource is, zoals de eigenaar-app het ziet: een persoonlijke mailbox, een
10
+ * teaminbox, of de organisatie.
11
+ *
12
+ * Los van `shared` en `audience`, die iets anders zeggen. `shared` gaat over of een
13
+ * AI-gesprek op deze scope met het team gedeeld wordt (voor een interactie altijd waar), en
14
+ * `audience` is de momentane ledenlijst voor SSE. Dit veld gaat over **eigenaarschap**, en
15
+ * dat is wat een consument nodig heeft om te beslissen of afgeleide kennis breder mag dan
16
+ * de resource zelf.
17
+ *
18
+ * Eerste consument is de geheugenlaag: een org-brede geheugensoort wordt bij het schrijven
19
+ * versmald naar `audience` als het bronsubject persoonlijk is, zodat een gesprek uit iemands
20
+ * eigen mailbox niet in de cross-klant-zoekresultaten van een collega opduikt. Afwezig =
21
+ * onbekend, en dat wordt daar als "versmallen" gelezen: de veilige kant.
22
+ */
23
+ ownerScope?: OwnerScope;
7
24
  }
8
25
  /** GET /provider/scope/describe response: the scopeKey prefixes an app owns. */
9
26
  export interface ScopeDescribe {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencxh/domain",
3
- "version": "1.127.0",
3
+ "version": "1.128.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",