@opencxh/domain 1.128.0 → 1.131.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.
@@ -1,3 +1,4 @@
1
1
  export * from './types';
2
2
  export * from './preview';
3
3
  export * from './seen';
4
+ export * from './timestamp';
@@ -0,0 +1,15 @@
1
+ import { Activity } from './types';
2
+ /**
3
+ * The epoch-ms an activity happened at.
4
+ *
5
+ * `Activity.createdAt` is optional because the same type describes an activity
6
+ * that has not been written yet (`Omit<Activity, "id">` on the way into a create
7
+ * call). Everything reading a *persisted* activity — sorting a feed, formatting a
8
+ * timestamp — needs a number, and reaching for `createdAt` directly there means
9
+ * every call site either repeats a fallback or quietly passes `undefined` into
10
+ * `new Date()` (which yields an Invalid Date, not an error).
11
+ *
12
+ * Falls back to 0 (epoch) so ordering stays deterministic: an activity with no
13
+ * timestamp sorts oldest rather than to a random place.
14
+ */
15
+ export declare function activityTimestamp(activity: Pick<Activity, "createdAt">): number;
@@ -0,0 +1 @@
1
+ export * from './types';
@@ -0,0 +1,50 @@
1
+ import { OwnerScope } from '../contact/types';
2
+ /** Where a company row came from. `local` is a row somebody created by hand. */
3
+ export interface CompanySource {
4
+ providerId: string;
5
+ readOnly?: boolean;
6
+ }
7
+ /**
8
+ * A company we own a row for.
9
+ *
10
+ * The identity fields are deliberately flat string arrays: only that shape is
11
+ * indexable in this datastore, so `keys`, `domains` and `externalIds` are what makes a
12
+ * lookup an indexed exact match instead of a scan.
13
+ */
14
+ export interface Company {
15
+ id: string;
16
+ organizationId: string;
17
+ name: string;
18
+ /**
19
+ * Registrable e-mail domains that identify this company (`vandijck.nl`). Matched
20
+ * after `registrableDomain`, so a subdomain resolves too. Public/consumer domains
21
+ * are rejected on write — one company with `gmail.com` here would claim every
22
+ * private customer.
23
+ */
24
+ domains: string[];
25
+ /**
26
+ * Canonical endpoint keys (`tel:+31882112121`, `mailto:info@vandijck.nl`), produced
27
+ * by `endpointKey`. Never a raw value: the raw form is kept for display only.
28
+ */
29
+ keys: string[];
30
+ /**
31
+ * Namespaced references into external systems (`hubspot:5591`, `exact:REL0042`).
32
+ * A reference, never a copy — live figures (balance, deal value) stay where they
33
+ * belong and are fetched on demand.
34
+ */
35
+ externalIds: string[];
36
+ ownerScope: OwnerScope;
37
+ source: CompanySource;
38
+ /** Raw, human-readable phone/website as entered, for display. */
39
+ phone?: string;
40
+ website?: string;
41
+ notes?: string;
42
+ }
43
+ /** What a resolve returns: which company, and how we got there. */
44
+ export interface CompanyMatch {
45
+ company: Company;
46
+ /** Which rung of the local chain matched — useful for debugging a wrong link. */
47
+ via: "contact" | "key" | "domain";
48
+ /** The contact row that carried the link, when `via` is `contact`. */
49
+ contactId?: string;
50
+ }
@@ -20,6 +20,16 @@ export interface ContactSource {
20
20
  externalId?: string;
21
21
  readOnly?: boolean;
22
22
  }
23
+ /**
24
+ * Where a contact row came from.
25
+ *
26
+ * - `own` — somebody created or promoted it here; freely editable.
27
+ * - `shadow` — a lazily cached hit from a federated source (a directory, a CRM). It
28
+ * exists so the second call from that number is an indexed hit instead of another
29
+ * fan-out. Hidden from the contact list by default: the Entra directory is full of
30
+ * your own colleagues, and writing those in as customers pollutes the list.
31
+ */
32
+ export type ContactOrigin = "own" | "shadow";
23
33
  export interface Contact {
24
34
  id: string;
25
35
  organizationId: string;
@@ -27,7 +37,26 @@ export interface Contact {
27
37
  source: ContactSource;
28
38
  firstName: string;
29
39
  lastName?: string;
40
+ /**
41
+ * Free-text company name. Stays as the display fallback for contacts that have no
42
+ * `companyId` — a dozen render sites use it as a label.
43
+ */
30
44
  company?: string;
45
+ /** The company row this contact belongs to, once resolved. */
46
+ companyId?: string;
31
47
  address?: string;
48
+ /** Display form: the resource exactly as entered or as the provider delivered it. */
32
49
  endpoints?: ContactEndpoint[];
50
+ /**
51
+ * Canonical, indexable mirror of `endpoints`, produced by `endpointKey` on every
52
+ * write. `endpoints[]` is an array of objects and therefore not indexable, which is
53
+ * why the old lookup was an unindexed `$elemMatch` scan. Read and write side must use
54
+ * the same normaliser or the index is structurally a miss.
55
+ */
56
+ keys?: string[];
57
+ /** Namespaced source references (`ms:AAMk…`, `google:people/c123`, `hubspot:42`). */
58
+ externalIds?: string[];
59
+ origin?: ContactOrigin;
60
+ /** When a shadow row last saw its source. There is no refresh job; touching refreshes. */
61
+ syncedAt?: number;
33
62
  }
@@ -0,0 +1 @@
1
+ export * from './types';
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Which sources this organisation uses to search for and enrich contacts.
3
+ *
4
+ * Named `...Config` because `ContactSource` already means something else on a contact: its
5
+ * provenance (`{ providerId, externalId, readOnly }`). This is the register row.
6
+ *
7
+ * The one configuration surface of the contact layer. Deliberately *not* a tool name
8
+ * inside a playbook step: MCP tool names are `mcp__<server row id>__<tool>` and therefore
9
+ * per-organisation random, a shipped step could never name one, and playbook steps are
10
+ * snapshotted onto runs so changing a source would leave parked runs on the old one.
11
+ *
12
+ * Note what is NOT configurable here: personal versus organisation-wide. That follows from
13
+ * *who is asking* — an interactive search runs with the user's delegated tokens and may use
14
+ * their personal connections, an unattended job has no user and cannot, both because
15
+ * `SYSTEM_TOOL_POLICY` filters personal tools and because the Graph API refuses `/me/*`
16
+ * without a user token.
17
+ */
18
+ export interface ContactSourceConfig {
19
+ /**
20
+ * Either a built-in source id (`microsoft-directory`, `google`, `eylo-voip`, `local`)
21
+ * or an AI tool name (`mcp__<id>__search_companies`).
22
+ *
23
+ * A field VALUE, never an object key: the SDK client deep-mangles object keys between
24
+ * camel and snake case, which would corrupt any namespaced name used as a key.
25
+ */
26
+ sourceId: string;
27
+ kind: "internal" | "mcp";
28
+ /** Take part in the interactive launcher / composer search. */
29
+ search: boolean;
30
+ /** Take part in the background enrichment of interactions. */
31
+ enrich: boolean;
32
+ order: number;
33
+ }
34
+ /** A source as the settings page sees it: config merged with what is actually available. */
35
+ export interface ContactSourceEntry extends ContactSourceConfig {
36
+ label: string;
37
+ /** `platform` = shipped default, `org` = the organisation added it. */
38
+ origin: "platform" | "org";
39
+ /**
40
+ * True when the source is configured but its tool is gone — an MCP server that was
41
+ * disconnected. Surfaced rather than silently skipped, because a source that quietly
42
+ * stops answering looks exactly like a customer who is not in the CRM.
43
+ */
44
+ broken?: boolean;
45
+ }
46
+ export interface ContactSourceCatalog {
47
+ sources: ContactSourceEntry[];
48
+ /** Master switch for background enrichment. Absent means on. */
49
+ enrichmentEnabled: boolean;
50
+ /**
51
+ * Bumped on every change to the register. Used as the generation token of the negative
52
+ * cache, so a number that was unknown before gets a fresh chance once the organisation
53
+ * connects a new source — expiry on time alone would never do that.
54
+ */
55
+ generation: string;
56
+ }
@@ -80,6 +80,21 @@ export interface Interaction {
80
80
  * en meetings hier de volledige lijst inclusief rollen (cc/bcc/organizer/…).
81
81
  */
82
82
  participants?: InteractionParticipant[];
83
+ /**
84
+ * Canonieke identiteitssleutels van de tegenpartij — de andere helft van `channelUriKey`,
85
+ * dat onze eigen kant canonicaliseert. Geïndexeerd, zodat "elk gesprek met dit adres, dit
86
+ * nummer of dit domein" een indexvraag is en geen scan.
87
+ *
88
+ * Bevat `mailto:`/`tel:`-sleutels, een `domain:<registreerbaar>`-pseudosleutel voor
89
+ * niet-publieke e-maildomeinen, en `company:<id>`/`contact:<id>` wanneer een mens een
90
+ * koppeling expliciet heeft gelegd.
91
+ *
92
+ * **Een sleutel wordt nooit onwaar.** "Dit adres kwam voor in dit gesprek" blijft altijd
93
+ * gelden, terwijl een afgeleide `companyId` onwaar wordt zodra iemand een bedrijf aanmaakt,
94
+ * samenvoegt of corrigeert — en dan backfill zou vragen. Los een identiteit bij het lezen op
95
+ * naar zijn sleutels en het antwoord omvat ook gesprekken van vóór die identiteit bestond.
96
+ */
97
+ partyKeys?: string[];
83
98
  source?: InteractionSource;
84
99
  tags: string[];
85
100
  links: InteractionLink[];
@@ -27,6 +27,30 @@ export interface MemoryItem {
27
27
  id: string;
28
28
  organizationId: string;
29
29
  subject: MemorySubjectKey;
30
+ /**
31
+ * De dossiersleutels waaronder dit item vindbaar is: het subject zelf, plus de sleutels die
32
+ * de eigenaar-app van dat subject teruggaf (`ScopeAuth.keys`). Gestempeld bij het schrijven.
33
+ *
34
+ * Dit is wat "vertel me wat er speelde bij deze klant" één geïndexeerde query maakt in
35
+ * plaats van een traversal. Een casus die op een gesprek is onthouden draagt via
36
+ * `Interaction.partyKeys` ook `domain:vandijck.nl` en `company:co_1`; het bedrijfsdossier
37
+ * matcht daarop met zijn eigen handvol sleutels, hoeveel medewerkers dat bedrijf ook heeft.
38
+ *
39
+ * **`keys` en niet `subjects`**, want dat zijn ze niet: `domain:vandijck.nl` is geen subject
40
+ * — geen app bezit die soort, dus `authorizeIdentity` erop geeft `allowed: false`. Een naam
41
+ * die belooft dat dit subjects zijn, nodigt precies die fout uit. Zelfde woord als
42
+ * `Interaction.partyKeys`, `Contact.keys` en `ScopeAuth.keys`: één begrip, één term.
43
+ *
44
+ * Bewust een momentopname en niet op leesmoment opgelost: opgelost bij elke query zou
45
+ * betekenen dat elke hit een autorisatie-fan-out kost — precies wat de engine zich niet kan
46
+ * veroorloven. De prijs is dat een sleutel die *later* wordt vastgelegd dit item niet meer
47
+ * bereikt; in de praktijk dekken `mailto:`/`domain:` dat vrijwel altijd al.
48
+ *
49
+ * `subject` blijft het anker, en is dus géén element-onder-de-andere: de unieke index, het
50
+ * vouwen, het wissen bij een verwijderd contact en de autorisatie lopen alle vier dáárover,
51
+ * en die hebben er exact één nodig.
52
+ */
53
+ keys?: string[];
30
54
  kind: MemoryKindId;
31
55
  title: string;
32
56
  /** DE inhoud: markdown, begrensd op {@link MAX_MEMORY_CHARS}. Nooit een genest object. */
@@ -52,7 +76,18 @@ export interface MemoryItem {
52
76
  * stale-permissive is een lek.
53
77
  */
54
78
  audienceRef?: string;
55
- /** Cosine over taalgrenzen wordt geweigerd; de skip wordt geteld, niet verzwegen. */
79
+ /**
80
+ * Taal van de inhoud. **Beschrijvend, geen filter** — en dat is een besluit, geen omissie.
81
+ *
82
+ * Retrieval vergelijkt bewust óók over taalgrenzen: de embeddingmodellen hier zijn meertalig,
83
+ * dus een Nederlandse vraag hoort een Engelse casus over hetzelfde probleem te vinden. Er
84
+ * stond eerder een harde taalcheck in `rank.ts`; die was nooit aangesloten en zou, als je hem
85
+ * wél had aangesloten, bij een anderstalige zoekvraag élk item hebben overgeslagen — want
86
+ * niets zet dit veld, dus alles staat op de default.
87
+ *
88
+ * Zet je dit ooit echt, houd het dan een *ordenings*-signaal (materiaal in je eigen taal is
89
+ * makkelijker te gebruiken) en geen zichtbaarheidsfilter.
90
+ */
56
91
  locale: string;
57
92
  /** Gedenormaliseerde termen: het enige selectieve structurele filter (er is geen substring-operator). */
58
93
  keywords?: string[];
@@ -12,6 +12,23 @@ export interface MemoryQuery {
12
12
  subject?: MemorySubjectKey;
13
13
  /** Extra subjects die bij hetzelfde beeld horen, bv. het contact naast de interactie. */
14
14
  alsoSubjects?: MemorySubjectKey[];
15
+ /**
16
+ * Ook items die niet ópt subject staan maar er wél bij horen: alles wat dezelfde
17
+ * dossiersleutel draagt (`MemoryItem.keys`).
18
+ *
19
+ * Dit is het antwoord op "wat speelde er bij dit bedrijf": een casus staat op het gesprek,
20
+ * en het bedrijfsdossier vindt hem via `domain:`/`company:` in plaats van via een lijst van
21
+ * vijftig medewerker-subjects. Eén extra `$or`-tak op een geïndexeerde array-kolom, geen
22
+ * tweede query en geen extra autorisatie-fan-out.
23
+ *
24
+ * **Alleen `visibility: "org"` erft mee.** De autorisatie van dit pad is de ene check op het
25
+ * anker; een geërfd item is per definitie niet op dat anker geautoriseerd. Een casus uit
26
+ * iemands persoonlijke mailbox is bij het schrijven al versmald naar `audience`
27
+ * (`effectiveVisibility`) en blijft dus buiten het klantdossier van een collega.
28
+ *
29
+ * Vereist een anker (`subject`); zonder anker is dit het cross-subject-pad.
30
+ */
31
+ related?: boolean;
15
32
  /** Default true. */
16
33
  resolveAliases?: boolean;
17
34
  kinds?: MemoryKindId[];
@@ -28,6 +45,22 @@ export interface MemoryQuery {
28
45
  /** Fase 3: ook live bronnen bevragen, met harde timeout en eigen sub-budget. */
29
46
  live?: boolean;
30
47
  }
48
+ /**
49
+ * Subject-soorten waarvoor "het dossier" de **verbanden** insluit: alles wat dezelfde
50
+ * dossiersleutel draagt, ook als het op een ander subject is onthouden.
51
+ *
52
+ * Bij een klant of een persoon ís de partij de vraag — "wat speelde er bij Van Dijck" gaat over
53
+ * het bedrijf, terwijl de casussen op de gesprekken staan. Bij een gesprek niet: dan wil je de
54
+ * draad zelf, want het hele klantverleden verdringt in een begrensde bundel precies wat er nú
55
+ * aan de hand is.
56
+ *
57
+ * Staat hier en niet in de tool of in het paneel, omdat het er twee zijn: de assistent en het
58
+ * dossierpaneel horen hetzelfde te bedoelen met "het dossier van deze klant". Twee kopieën van
59
+ * die regel is precies de soort regel die uit elkaar loopt.
60
+ */
61
+ export declare const RELATED_SUBJECT_KINDS: readonly ["contact", "company"];
62
+ /** Hoort {@link MemoryQuery.related} standaard aan te staan voor dit subject? */
63
+ export declare function relatedByDefault(subject: MemorySubjectKey | undefined): boolean;
31
64
  export interface MemoryHit {
32
65
  item: MemoryItem;
33
66
  score: number;
@@ -50,6 +83,15 @@ export interface MemoryQueryResult {
50
83
  semantic: boolean;
51
84
  /** Hits die de her-autorisatie van de top-K niet overleefden. */
52
85
  withheld?: number;
86
+ /**
87
+ * Kandidaten die op het cross-subject-pad afvielen op de absolute gelijkenisdrempel.
88
+ *
89
+ * Het verschil met een leeg resultaat: `belowThreshold: 7` betekent "er was materiaal, maar
90
+ * niets leek er echt op" en `undefined` betekent "er was niets". Zonder deze teller is de
91
+ * drempel niet te kalibreren — je ziet dan alleen dat er niets terugkomt, niet of hij te hoog
92
+ * staat.
93
+ */
94
+ belowThreshold?: number;
53
95
  /**
54
96
  * Kandidaten overgeslagen door model- of taal-mismatch. Zonder deze teller degradeert
55
97
  * een modelwissel volkomen stil: `cosineSimilarity` geeft bij dimensie-mismatch 0, dus
@@ -36,6 +36,13 @@ export interface Organization {
36
36
  billing?: OrganizationBilling;
37
37
  /** Small company logo stored inline as a base64 data-URI. */
38
38
  logo?: string;
39
+ /**
40
+ * ISO 3166-1 alpha-2 region used to turn a national phone number into E.164
41
+ * (`088 211 2121` → `+31882112121`). Absent falls back to `DEFAULT_PHONE_REGION`.
42
+ * Belongs on the organisation and not in code: hardcoding `+31` is wrong for an
43
+ * org with Belgian numbers. See `toE164` in `text/endpoint.ts`.
44
+ */
45
+ defaultPhoneRegion?: string;
39
46
  }
40
47
  /**
41
48
  * Recursive tenant hierarchy node returned by `system.tenants/tree`.
@@ -46,6 +46,12 @@ export declare const TRIGGER_VARS: readonly [{
46
46
  }, {
47
47
  readonly name: "toStatus";
48
48
  readonly type: "string";
49
+ }, {
50
+ readonly name: "contactId";
51
+ readonly type: "string";
52
+ }, {
53
+ readonly name: "companyId";
54
+ readonly type: "string";
49
55
  }];
50
56
  /** De variabelen die een classify-stap oplevert, per mode. */
51
57
  export declare const CLASSIFY_VARS: {
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
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"?`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=140;function T(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 Y(e){const n=e.trim();return n.length<=m?n:n.slice(0,m-1).trimEnd()+"…"}function d(e){if(!e||e<0)return"";const n=Math.floor(e/60),t=Math.floor(e%60);return`${n}:${t.toString().padStart(2,"0")}`}function j(e){switch(e.type){case"EMAIL_RECEIVED":case"EMAIL_SENT":{const n=e.payload,t=n.bodySnippet?.trim()||T(n.body??"");return n.subject?`${n.subject} — ${t}`:t}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(n=>n.name).join(", ")} toegevoegd`;case"CHAT_MEMBER_LEFT":return`${e.payload.members.map(n=>n.name).join(", ")} verlaten`;case"CHAT_CALL_STARTED":return"Gesprek gestart";case"CHAT_CALL_ENDED":return`Gesprek beëindigd${e.payload.duration?` (${d(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?` (${d(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(n=>n.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?` (${d(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 K(e){return{activityId:e.id,type:e.type,snippet:Y(j(e)),authorName:e.author?.name??"",direction:e.direction,createdAt:e.createdAt??Date.now()}}function z(e,n,t=[]){const r=e.createdAt;if(!r)return[];const a=new Set(t);return e.author.type==="user"&&e.author.id&&a.add(e.author.id),Object.entries(n).filter(([i,o])=>o>=r&&!a.has(i)).map(([i])=>i)}function q(e){return e.createdAt??0}const X=[{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 J(e){const n=[];for(const t of Object.keys(e))for(const r of Object.keys(e[t]))n.push({lang:t,key:r,value:e[t][r]});return n}function p(e){return e<10?`0${e}`:`${e}`}function D(e,n){const t=new Date(e),r=`${t.getUTCFullYear()}-${p(t.getUTCMonth()+1)}-${p(t.getUTCDate())}`;return n==="day"?r:`${r}T${p(t.getUTCHours())}`}function h(e,n){const t=new Date(e);return t.setUTCMinutes(0,0,0),n==="day"&&t.setUTCHours(0),t.getTime()}const Q=36e5,Z=864e5;function ee(e,n,t){const r=t==="hour"?Q:Z,a=[];for(let i=h(e,t);i<=n;i+=r)a.push(D(i,t));return a}const N=[{id:"resource",label:"Resource",labelSource:"raw"},{id:"origin",label:"Herkomst",labelSource:"raw"}],R=N.map(e=>e.id);function O(e,n){return`${e}.usage.${n}`}function ne(e,n){return n.map(t=>({id:O(e,t.unit),label:t.label,category:"Verbruik",valueType:t.valueType??"count",aggregation:"sum",supportedDimensions:["provider",...R,...t.extraDimensions??[],"time"]}))}function te(e){return(e.startsWith("tool:")?e.slice(5):e).replace(/__/g," · ").replace(/\./g," · ").replace(/_/g," ")}const re=[{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"},{name:"contactId",type:"string"},{name:"companyId",type:"string"}],ae={topics:[{name:"topic",type:"string"},{name:"confidence",type:"number"}],question:[{name:"answer",type:"boolean"},{name:"confidence",type:"number"}],extract:[]};function C(e){switch(e.kind){case"user":return`user:${e.userId}`;case"team":return`team:${e.teamId}`;case"org":return"org"}}function ie(e){if(typeof e!="string")return;const n=e.trim();if(n==="org")return{kind:"org"};const t=n.indexOf(":");if(t<=0)return;const r=n.slice(0,t),a=n.slice(t+1).trim();if(a){if(r==="user")return{kind:"user",userId:a};if(r==="team")return{kind:"team",teamId:a}}}function L(e){return C(e)}function oe(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 se(e){return L(e)}const y=["done","escalated","failed","timed_out","stopped"],U=["awaiting_approval","awaiting_reply"];function P(e){return y.includes(e)}function le(e){return P(e)}function ce(e){return U.includes(e)}const f=[{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 c(e){return f.find(n=>n.id===e)}function ue(e){return c(e)?.label??e}function de(e,n="gpt-5-mini"){return c(e)?.defaultModel??n}function pe(e){return f.filter(n=>n.capabilities.includes(e))}function Ee(e){const n=c(e);return!!n&&!n.baseUrl}const fe=new Set(["mail","message"]);function k(e,n){const t=e.settings?.signatures?.[n];return!t||!t.enabled||!t.body||t.body.trim()===""?null:t}function ge(e,n,t,r="html"){if(!e)return t;const a=k(e,n);return a?`${t}${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=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
- `).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
- `),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 A(e){return e.replace(/\r/g,"").replace(/[ \t]+/g," ").replace(/ *\n */g,`
3
+ `:n==="mail"?"<br><br>-- <br>":"<br><br>"}${a.body}`:t}function me(e){return e.endpoints??[]}const Ae=e=>!!e.assignedUserId||!!e.assignedInboxId,Ie=e=>e.status==="closed",_e=e=>({urgent:10,high:5,normal:2,low:1})[e.priority]||0,Se=(e,n=30)=>e.title?.length<=n?e.title:`${e.title.substring(0,n)}...`;function Me(e,n){return e.lastActivityAt?!(e.seenBy??[]).includes(n):!1}const be=2e3,Te=500,De=12e3,he=4e3,x=["contact","company"];function Ne(e){if(!e)return!1;const n=e.slice(0,e.indexOf(":"));return x.includes(n)}const u={NL:{callingCode:"31",trunkPrefix:"0",nsnMin:7,nsnMax:9},BE:{callingCode:"32",trunkPrefix:"0",nsnMin:8,nsnMax:9},LU:{callingCode:"352",nsnMin:6,nsnMax:9},DE:{callingCode:"49",trunkPrefix:"0",nsnMin:6,nsnMax:13},FR:{callingCode:"33",trunkPrefix:"0",nsnMin:9,nsnMax:9},GB:{callingCode:"44",trunkPrefix:"0",nsnMin:9,nsnMax:10},IE:{callingCode:"353",trunkPrefix:"0",nsnMin:7,nsnMax:9},ES:{callingCode:"34",nsnMin:9,nsnMax:9},PT:{callingCode:"351",nsnMin:9,nsnMax:9},IT:{callingCode:"39",nsnMin:6,nsnMax:11},AT:{callingCode:"43",trunkPrefix:"0",nsnMin:7,nsnMax:13},CH:{callingCode:"41",trunkPrefix:"0",nsnMin:9,nsnMax:9},DK:{callingCode:"45",nsnMin:8,nsnMax:8},SE:{callingCode:"46",trunkPrefix:"0",nsnMin:7,nsnMax:13},NO:{callingCode:"47",nsnMin:8,nsnMax:8},FI:{callingCode:"358",trunkPrefix:"0",nsnMin:5,nsnMax:12},PL:{callingCode:"48",nsnMin:9,nsnMax:9},US:{callingCode:"1",nsnMin:10,nsnMax:10},CA:{callingCode:"1",nsnMin:10,nsnMax:10}},$="NL",Re=15,Oe=8,Ce=Array.from(new Set(Object.values(u).map(e=>e.callingCode))).sort((e,n)=>n.length-e.length);function A(e){if(e)return u[e.trim().toUpperCase()]}function l(e,n){return e.length>=n.nsnMin&&e.length<=n.nsnMax}function I(e){if(e.length>Re)return null;for(const n of Ce){if(!e.startsWith(n))continue;const t=e.slice(n.length);for(const r of Object.values(u)){if(r.callingCode!==n)continue;const a=r.trunkPrefix,i=a&&t.startsWith(a)?t.slice(a.length):t;if(l(i,r))return`+${n}${i}`}return null}return e.length<Oe?null:`+${e}`}function Le(e){let n=e.trim();const t=n.match(/^(sips?|tel|whatsapp):/i);t&&(n=n.slice(t[0].length));const r=n.indexOf("@");return r>=0&&(n=n.slice(0,r)),n.trim()}function ye(e){if(!e)return!1;const n=e.indexOf("@");if(n<=0)return!1;const t=e.slice(0,n).trim();return!/^[+\d\s().-]+$/.test(t)}function E(e,n){if(!e)return null;const t=Le(e);if(!t)return null;const r=t.startsWith("+"),a=t.replace(/\D/g,"");if(!a)return null;if(r)return I(a);if(a.startsWith("00"))return I(a.slice(2));const i=A(n)??A($);if(!i)return null;const o=i.trunkPrefix;if(o&&a.startsWith(o)){const s=a.slice(o.length);return l(s,i)?`+${i.callingCode}${s}`:null}if(a.startsWith(i.callingCode)){const s=a.slice(i.callingCode.length);if(l(s,i))return`+${i.callingCode}${s}`}return!o&&l(a,i)?`+${i.callingCode}${a}`:null}function Ue(e,n=9){const t=(e??"").replace(/\D/g,"");return t.length<n?null:t.slice(-n)}function g(e){if(!e)return null;const n=e.trim().toLowerCase(),t=n.lastIndexOf("@");if(t<=0||t===n.length-1)return null;const r=n.slice(0,t).split("+")[0],a=n.slice(t+1);return!r||!a.includes(".")?null:`${r}@${a}`}function Pe(e){const n=g(e);return n?n.slice(n.lastIndexOf("@")+1):null}const ke=new Set(["co.uk","org.uk","gov.uk","ac.uk","com.au","co.nz","com.br","co.za"]);function G(e){if(!e)return null;const n=e.trim().toLowerCase().replace(/\.$/,"").split(".").filter(Boolean);if(n.length<2)return null;const t=n.slice(-2).join(".");return ke.has(t)&&n.length>=3?n.slice(-3).join("."):t}const V=new Set(["gmail.com","googlemail.com","outlook.com","hotmail.com","hotmail.nl","hotmail.be","hotmail.co.uk","live.com","live.nl","live.be","msn.com","yahoo.com","yahoo.co.uk","ymail.com","icloud.com","me.com","mac.com","aol.com","gmx.net","gmx.de","web.de","protonmail.com","proton.me","pm.me","tutanota.com","zoho.com","mail.com","ziggo.nl","kpnmail.nl","planet.nl","home.nl","casema.nl","chello.nl","xs4all.nl","telfort.nl","hetnet.nl","zonnet.nl","upcmail.nl","quicknet.nl","telenet.be","skynet.be","proximus.be","scarlet.be"]);function xe(e){const n=G(e);return n?V.has(n):!1}function $e(e){if(!e)return!1;const n=e.trim().toLowerCase();return n==="tel"||n==="sms"||n==="whatsapp"||n==="fax"}function Ge(e,n,t){if(!e||!n)return null;const r=e.trim().toLowerCase();if(r==="tel"||r==="sms"||r==="whatsapp"){const i=E(n,t);return i?`tel:${i}`:null}if(r==="fax"){const i=E(n,t);return i?`fax:${i}`:null}if(r==="mailto"||r==="email"){const i=g(n);return i?`mailto:${i}`:null}const a=n.trim().toLowerCase();return a?`${r}:${a}`:null}const Ve=[/<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],_=/^\s*(?:>+\s*)?(?:from|van|sent|verzonden|to|aan|cc|subject|onderwerp|date|datum)\s*:/i,we=/^\s*(?:on|op)\b.{0,200}?\b(?:wrote|schreef|geschreven)\s*:?\s*$/i;function Be(e){const n=e.split(`
4
+ `);for(let t=0;t<n.length;t++)if(we.test(n[t])||_.test(n[t])&&n.slice(t+1,t+4).some(r=>_.test(r)))return n.slice(0,t).join(`
5
+ `).trim();return e}function S(e){let n=e;return n=n.replace(/<(script|style)[\s\S]*?<\/\1>/gi,""),n=n.replace(/<br\s*\/?>/gi,`
6
+ `),n=n.replace(/<\/(p|div|li|tr|h[1-6]|ul|ol|table)>/gi,`
7
+ `),n=n.replace(/<[^>]+>/g,""),n=n.replace(/<[^>]*$/,""),n}function M(e){return e.replace(/&nbsp;/gi," ").replace(/&lt;/gi,"<").replace(/&gt;/gi,">").replace(/&quot;/gi,'"').replace(/&#39;/gi,"'").replace(/&#(\d+);/g,(n,t)=>String.fromCharCode(Number(t))).replace(/&amp;/gi,"&")}function b(e){return e.replace(/\r/g,"").replace(/[ \t]+/g," ").replace(/ *\n */g,`
8
8
  `).replace(/\n{3,}/g,`
9
9
 
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;
10
+ `).trim()}function He(e){if(typeof e!="string"||!e)return"";let n=e.length;for(const i of Ve){const o=e.search(i);o>=0&&o<n&&(n=o)}const t=e.slice(0,n);let r=b(M(S(t)));return r||(r=b(M(S(e)))),Be(r)||r}const Fe=/(^|[._+-])(no-?reply|noreply|donotreply|do-not-reply|newsletter|nieuwsbrief|mailer|mailing|notifications?|bounce|postmaster|marketing)@/i,ve=/\b(unsubscribe|afmelden|uitschrijven|opt[\s-]?out|manage (your )?preferences|geen (e-?mails?|nieuwsbrief|berichten) meer)\b/i;function We(e,n){return!!(e&&Fe.test(e)||n&&ve.test(n))}const w=3,B=600;function Ye(e,n){return e>=w||n>=B}function H(e,n){const t=new Set(e.disabledIntents??[]),r=e.intentOverrides??{},a=n.intents.filter(o=>!t.has(o.intent)).map(o=>Ke(o,r[o.intent]));if(!e.extraIntents||e.extraIntents.length===0)return a;const i=new Set(a.map(o=>o.intent));for(const o of e.extraIntents)i.has(o.intent)||(a.push(o),i.add(o.intent));return a}function F(e,n){const t={};for(const r of e.intents){if(!r.togglable)continue;const a=n?.[r.intent];t[r.intent]=a??r.defaultEnabled??!0}return t}function je(e,n){const t=F(e,n);return Object.entries(t).filter(([,r])=>!r).map(([r])=>r)}function Ke(e,n){return n?{intent:n.intent??e.intent,targetSchemes:n.targetSchemes??e.targetSchemes,transport:n.transport??e.transport}:e}function ze(e,n){const t=[];for(const r of e){if(!r.enabled)continue;const a=n[r.providerId];if(a)for(const i of H(r,a))t.push({channel:r,description:a,capability:i})}return t}function qe(e,n){return n.filter(t=>t.capability.intent===e)}function v(e,n){return n.filter(t=>t.capability.targetSchemes.includes(e))}function Xe(e,n){return v(e.scheme,n)}function Je(e,n,t){const r=[];for(const a of e)for(const i of t)i.capability.intent===n&&i.capability.targetSchemes.includes(a.scheme)&&r.push({channelIntent:i,endpoint:a});return r}var W=(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))(W||{});const Qe="message_window",Ze="message_templates",en={FROM:"from",TO:"to",CC:"cc",BCC:"bcc",ORGANIZER:"organizer",PRESENTER:"presenter",ATTENDEE:"attendee",OWNER:"owner",MEMBER:"member",GUEST:"guest",HOST:"host",PARTICIPANT:"participant"},nn=(e,n)=>({intent:e,...n}),tn="folder_management",rn="remote_search",an={ok:!1,code:"UNSUPPORTED",message:"Provider does not support this op"},on=9e4,sn="installation-id";exports.AI_VENDORS=f;exports.CLASSIFY_VARS=ae;exports.CORE_DIMENSIONS=X;exports.CommunicationScheme=W;exports.DEFAULT_MEMORY_BUDGET=he;exports.DEFAULT_PHONE_REGION=$;exports.FEATURE_FOLDER_MANAGEMENT=tn;exports.FEATURE_REMOTE_SEARCH=rn;exports.INSTALLATION_HEADER=sn;exports.InteractionParticipantRole=en;exports.MAX_MEMORY_BUDGET=De;exports.MAX_MEMORY_CHARS=be;exports.MIN_MEMORY_BUDGET=Te;exports.PAUSED_RUN_STATUSES=U;exports.PHONE_REGIONS=u;exports.PRESENCE_ONLINE_WINDOW_MS=on;exports.PROVIDER_FEATURE_MESSAGE_TEMPLATES=Ze;exports.PROVIDER_FEATURE_MESSAGE_WINDOW=Qe;exports.PUBLIC_EMAIL_DOMAINS=V;exports.RELATED_SUBJECT_KINDS=x;exports.SIGNATURE_INTENTS=fe;exports.SUMMARY_MIN_LAST_CHARS=B;exports.SUMMARY_MIN_MESSAGES=w;exports.TERMINAL_RUN_STATUSES=y;exports.TRIGGER_VARS=re;exports.UNSUPPORTED=an;exports.USAGE_DIMENSIONS=N;exports.USAGE_DIMENSION_IDS=R;exports.actingIdentityKey=L;exports.activityTimestamp=q;exports.actorKey=se;exports.aiVendorDefaultModel=de;exports.aiVendorLabel=ue;exports.aiVendorNeedsBaseUrl=Ee;exports.aiVendorsWith=pe;exports.applySignature=ge;exports.buildActivityPreview=K;exports.buildChannelIntents=ze;exports.cleanMessageText=He;exports.defineIntent=nn;exports.disabledIntentsFromCapabilities=je;exports.emailDomain=Pe;exports.endpointKey=Ge;exports.filterByEndpoint=Xe;exports.filterByIntent=qe;exports.filterByTargetScheme=v;exports.findAiVendor=c;exports.flattenLocales=J;exports.floorToPeriod=h;exports.formatActingIdentity=C;exports.formatPeriod=D;exports.getActivitySeenUserIds=z;exports.getContactEndpoints=me;exports.getShortTitle=Se;exports.getUrgencyScore=_e;exports.humanizeAction=te;exports.isAssigned=Ae;exports.isClosed=Ie;exports.isInteractionUnseen=Me;exports.isLikelyBulk=We;exports.isPaused=ce;exports.isPublicEmailDomain=xe;exports.isRetryable=le;exports.isTerminal=P;exports.isThreadLongEnough=Ye;exports.looksLikeEmail=ye;exports.matchContactToIntents=Je;exports.needsPhoneRegion=$e;exports.normalizeEmail=g;exports.parseActingIdentity=ie;exports.periodsInRange=ee;exports.phoneSuffix=Ue;exports.playbookActor=oe;exports.registrableDomain=G;exports.relatedByDefault=Ne;exports.resolveAccountCapabilities=F;exports.resolveChannelIntents=H;exports.resolveSignature=k;exports.stripHtml=T;exports.toE164=E;exports.usageMetricId=O;exports.usageMetrics=ne;
package/dist/index.d.ts CHANGED
@@ -12,7 +12,9 @@ export * from './entities/ai-profile';
12
12
  export * from './entities/mcp';
13
13
  export * from './entities/channel';
14
14
  export * from './entities/communication';
15
+ export * from './entities/company';
15
16
  export * from './entities/contact';
17
+ export * from './entities/contact-source';
16
18
  export * from './entities/custom-field-def';
17
19
  export * from './entities/calendar-event';
18
20
  export * from './entities/draft';
@@ -29,6 +31,7 @@ export * from './entities/shopify';
29
31
  export * from './entities/transcript';
30
32
  export * from './entities/user';
31
33
  export * from './entities/webhook';
34
+ export * from './text/endpoint';
32
35
  export * from './text/message';
33
36
  export * from './text/triage';
34
37
  export * from './platform/ai-tools';