@opencxh/domain 1.172.1 → 1.173.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/entities/activity/blocks.d.ts +30 -30
  2. package/dist/entities/activity/catalog.d.ts +63 -86
  3. package/dist/entities/activity/descriptor.d.ts +31 -32
  4. package/dist/entities/activity/index.d.ts +2 -2
  5. package/dist/entities/activity/preview.d.ts +7 -7
  6. package/dist/entities/activity/resolve.d.ts +37 -38
  7. package/dist/entities/activity/types.d.ts +64 -35
  8. package/dist/entities/ai-account/types.d.ts +3 -3
  9. package/dist/entities/ai-account/vendors.d.ts +25 -32
  10. package/dist/entities/ai-budget/types.d.ts +5 -5
  11. package/dist/entities/ai-conversation/types.d.ts +12 -12
  12. package/dist/entities/ai-profile/types.d.ts +14 -21
  13. package/dist/entities/ai-settings/types.d.ts +12 -13
  14. package/dist/entities/analytics/index.d.ts +4 -4
  15. package/dist/entities/analytics/source.d.ts +1 -1
  16. package/dist/entities/analytics/usage.d.ts +23 -28
  17. package/dist/entities/artifact/blocks.d.ts +54 -69
  18. package/dist/entities/artifact/markdown.d.ts +2 -3
  19. package/dist/entities/artifact/types.d.ts +46 -54
  20. package/dist/entities/assignment/types.d.ts +76 -90
  21. package/dist/entities/channel/index.d.ts +1 -1
  22. package/dist/entities/channel/signature.d.ts +8 -9
  23. package/dist/entities/communication/index.d.ts +1 -1
  24. package/dist/entities/contact/index.d.ts +1 -1
  25. package/dist/entities/custom-field-def/types.d.ts +14 -14
  26. package/dist/entities/external-identity/types.d.ts +45 -50
  27. package/dist/entities/interaction/index.d.ts +1 -1
  28. package/dist/entities/interaction/types.d.ts +44 -47
  29. package/dist/entities/live-lens/types.d.ts +39 -44
  30. package/dist/entities/mcp/types.d.ts +53 -57
  31. package/dist/entities/memory/alias.d.ts +7 -7
  32. package/dist/entities/memory/browse.d.ts +21 -21
  33. package/dist/entities/memory/ingest.d.ts +24 -28
  34. package/dist/entities/memory/item.d.ts +53 -58
  35. package/dist/entities/memory/kind.d.ts +25 -25
  36. package/dist/entities/memory/query.d.ts +49 -51
  37. package/dist/entities/playbook/actor.d.ts +17 -17
  38. package/dist/entities/playbook/assignment.d.ts +54 -63
  39. package/dist/entities/playbook/index.d.ts +2 -2
  40. package/dist/entities/playbook/labels.d.ts +4 -4
  41. package/dist/entities/playbook/trigger-vars.d.ts +17 -15
  42. package/dist/entities/playbook/types.d.ts +174 -303
  43. package/dist/entities/resource-reminder/types.d.ts +8 -9
  44. package/dist/entities/time-entry/duration.d.ts +11 -11
  45. package/dist/entities/time-entry/types.d.ts +59 -59
  46. package/dist/entities/time-entry/work-type.d.ts +21 -24
  47. package/dist/entities/topic/examples.d.ts +26 -27
  48. package/dist/entities/topic/scope.d.ts +11 -12
  49. package/dist/entities/topic/types.d.ts +26 -28
  50. package/dist/entities/user/types.d.ts +24 -28
  51. package/dist/entities/webhook/types.d.ts +6 -6
  52. package/dist/entities/work/activity.d.ts +36 -0
  53. package/dist/entities/work/index.d.ts +1 -0
  54. package/dist/entities/work/keys.d.ts +25 -26
  55. package/dist/entities/work/ladder.d.ts +48 -52
  56. package/dist/entities/work/types.d.ts +108 -114
  57. package/dist/index.cjs +6 -6
  58. package/dist/index.d.ts +29 -28
  59. package/dist/index.js +1416 -1258
  60. package/dist/platform/account.d.ts +34 -38
  61. package/dist/platform/ai-tools.d.ts +48 -52
  62. package/dist/platform/api.d.ts +9 -10
  63. package/dist/platform/author.d.ts +7 -9
  64. package/dist/platform/capabilities.d.ts +3 -3
  65. package/dist/platform/communication.d.ts +163 -204
  66. package/dist/platform/context.d.ts +8 -8
  67. package/dist/platform/identity.d.ts +16 -19
  68. package/dist/platform/kernel.d.ts +1 -1
  69. package/dist/platform/manifest.d.ts +2 -2
  70. package/dist/platform/media.d.ts +13 -15
  71. package/dist/platform/permission.d.ts +39 -0
  72. package/dist/platform/permission.test.d.ts +1 -0
  73. package/dist/platform/presence.d.ts +30 -30
  74. package/dist/platform/provider.d.ts +14 -15
  75. package/dist/platform/resource-source.d.ts +43 -45
  76. package/dist/platform/resource.d.ts +17 -23
  77. package/dist/platform/scope.d.ts +35 -61
  78. package/dist/platform/services.d.ts +4 -4
  79. package/dist/platform/storage.d.ts +1 -1
  80. package/dist/platform/sync-source.d.ts +196 -216
  81. package/dist/platform/transcript-cadence.d.ts +37 -41
  82. package/dist/platform/ui.d.ts +6 -6
  83. package/dist/text/endpoint.d.ts +11 -27
  84. package/package.json +3 -2
@@ -1,31 +1,31 @@
1
1
  import { MemoryKindId, MemoryLink, MemorySubjectKey } from './item';
2
2
  /**
3
- * Schrijven is een **CAS-upsert**, geen snapshot-replace zoals analytics.
3
+ * Writing is a **CAS upsert**, not a snapshot replace like analytics.
4
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.
5
+ * Analytics may throw a whole period away and write it again because a fact is recomputable from
6
+ * the source store. A delta-folded story is the accumulated outcome of N model calls and is not.
7
+ * On top of that, remove+insert is not atomic: a reader can observe "no item" on a subject that
8
+ * does have a story.
9
9
  */
10
10
  export interface MemoryUpsertRequest {
11
11
  organizationId: string;
12
- /** De schrijvende app; de hub vult dit uit `req.source.app` en vertrouwt de body hier niet. */
12
+ /** The writing app; the hub fills this from `req.source.app` and does not trust the body. */
13
13
  source: string;
14
14
  subject: MemorySubjectKey;
15
15
  kind: MemoryKindId;
16
- /** Default bij `cardinality: "single"`: `"<kind>:<subject>"`. */
16
+ /** Default with `cardinality: "single"`: `"<kind>:<subject>"`. */
17
17
  sourceRef?: string;
18
18
  title: string;
19
19
  body: string;
20
20
  occurredAt?: number;
21
- /** Watermerk van het bron-event dat deze schrijfactie veroorzaakte. */
21
+ /** Watermark of the source event that caused this write. */
22
22
  throughRef?: string;
23
23
  throughAt?: number;
24
- /** Mismatch => `accepted: false` met `reason: "stale-version"`; de caller herplant. */
24
+ /** A mismatch => `accepted: false` with `reason: "stale-version"`; the caller reschedules. */
25
25
  expectedVersion?: number;
26
26
  audienceRef?: string;
27
27
  locale?: string;
28
- /** Weglaten: de hub extraheert keywords zelf uit titel + body (één tokenizer, schrijf én lees). */
28
+ /** Omit it: the hub extracts keywords from title + body itself (one tokenizer, write and read). */
29
29
  keywords?: string[];
30
30
  tags?: string[];
31
31
  links?: MemoryLink[];
@@ -33,14 +33,14 @@ export interface MemoryUpsertRequest {
33
33
  export type MemoryUpsertRejection = "stale-version" | "stale-watermark" | "unknown-kind" | "kind-disabled" | "subject-kind-mismatch" | "not-owner";
34
34
  export interface MemoryUpsertResult {
35
35
  accepted: boolean;
36
- /** De versie zoals die nu in de store staat — ook bij een afwijzing, zodat de caller kan herplannen. */
36
+ /** The version as it stands in the store now — also on a rejection, so the caller can reschedule. */
37
37
  version: number;
38
38
  itemId?: string;
39
39
  reason?: MemoryUpsertRejection;
40
40
  }
41
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.
42
+ * Explicitly destructive: throws away all items of (subject, kind) from this source and puts
43
+ * `items` back in their place. Only for **recomputable** kinds, e.g. a nightly re-fold.
44
44
  */
45
45
  export interface MemoryReplaceRequest {
46
46
  organizationId: string;
@@ -50,23 +50,19 @@ export interface MemoryReplaceRequest {
50
50
  items: MemoryUpsertRequest[];
51
51
  }
52
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`.
53
+ * Source-driven wiping. The **source** pushes this; the hub interprets no deletes: the mapping
54
+ * from a deleted contact to its interactions lives in comms, and `contacts:deleted` publishes only
55
+ * `{ id }` — without an `organizationId`.
56
56
  *
57
- * ## Er staat geen `source` in, en dat was de bug
57
+ * **There is no `source` field, and that was the bug.** It used to exist and the purge filtered on
58
+ * it, so only memory carrying that source was wiped. The server derived it from the *calling* app,
59
+ * but memory is written by the app that *records* it — `"context"` for a note, `ctx.app` for the
60
+ * `memory_remember` tool — never by the app deleting the subject. Net effect: the purge matched
61
+ * nothing, a deleted contact or conversation kept its memory. A retention leak, and invisible,
62
+ * because `{ removed: 0 }` is a valid answer.
58
63
  *
59
- * Dit veld bestond en de purge filterde erop: alleen geheugen mét die bron werd gewist. De
60
- * serverkant leidde hem af uit de *aanroepende* app (`requireApp`), dus comms wiste met
61
- * `source: "communication"` en crm zou met `"crm"` wissen. Maar geheugen wordt geschreven door
62
- * de app die het *vastlegt* — `"context"` voor een notitie, `ctx.app` voor de
63
- * `memory_remember`-tool. Nooit door de app die het subject verwijdert.
64
- *
65
- * Netto matchte de purge dus niets: een verwijderd contact of gesprek liet zijn geheugen
66
- * staan. Een retentie-lek, en niet zichtbaar, want `{ removed: 0 }` is een geldig antwoord.
67
- *
68
- * Een purge is subject-gescopeerd en niet bron-gescopeerd: "dit subject bestaat niet meer, haal
69
- * alles erover weg". Dat de aanroeper een app moet zijn blijft de poort; het is geen filter.
64
+ * A purge is subject-scoped and not source-scoped: "this subject no longer exists, remove
65
+ * everything about it". That the caller has to be an app stays the gate; it is not a filter.
70
66
  */
71
67
  export interface MemoryPurgeRequest {
72
68
  organizationId: string;
@@ -1,114 +1,109 @@
1
1
  /**
2
- * De geheugenlaag (`apps/context`): één durende laag per **subject**, waarbij de
3
- * organisatie zelf per event bepaalt wat er onthouden wordt.
2
+ * The memory layer (`apps/context`): one durable layer per **subject**, where the organisation
3
+ * itself decides per event what gets remembered.
4
4
  *
5
- * `Memory*` en niet `Context*`: `platform/context.ts` exporteert al `HostContext` en
6
- * `context.collect` (vluchtige route-context) uit dezelfde platte barrel.
5
+ * `Memory*` and not `Context*`: `platform/context.ts` already exports `HostContext` and
6
+ * `context.collect` (ephemeral route context) from the same flat barrel.
7
7
  */
8
- /** Een bestaande scopeKey: `interaction:i_1`, `contact:c_9`. Een latere identiteitslaag is gewoon een ander prefix. */
8
+ /** An existing scopeKey: `interaction:i_1`, `contact:c_9`. A later identity layer is just another prefix. */
9
9
  export type MemorySubjectKey = string;
10
- /** `comms.resolution` (app-gedeclareerd) of `sales_besluitvormer` (org-eigen). */
10
+ /** `comms.resolution` (app-declared) or `sales_besluitvormer` (org-owned). */
11
11
  export type MemoryKindId = string;
12
12
  /**
13
- * Een verwijzing naar iets anders — intern (`interaction:i_2`) of extern
14
- * (`hubspot:5591`, `clickup:86ab2`).
13
+ * A reference to something else — internal (`interaction:i_2`) or external (`hubspot:5591`,
14
+ * `clickup:86ab2`).
15
15
  *
16
- * Een **lijst**, nooit een object met de relatie als key.
17
- *
18
- * De oorspronkelijke reden (de http-client mangelde object-keys) geldt niet meer sinds 17-08-2026.
19
- * De lijst blijft om een reden die altijd al sterker was: **dezelfde `rel` mag twee keer voorkomen**
20
- * — twee gekoppelde bedrijven, drie betrokken interacties — en een map gooit er dan één weg.
16
+ * A **list**, never an object keyed by the relation: **the same `rel` may occur twice** — two
17
+ * linked companies, three involved interactions — and a map would throw one away.
21
18
  */
22
19
  export interface MemoryLink {
23
20
  rel: string;
24
21
  target: string;
25
22
  }
26
- /** Harde grens op de body. Geheugen is een samenvatting; een mailbox-schaduwkopie is het niet. */
23
+ /** Hard limit on the body. Memory is a summary; it is not a shadow copy of a mailbox. */
27
24
  export declare const MAX_MEMORY_CHARS = 2000;
28
25
  export interface MemoryItem {
29
26
  id: string;
30
27
  organizationId: string;
31
28
  subject: MemorySubjectKey;
32
29
  /**
33
- * De dossiersleutels waaronder dit item vindbaar is: het subject zelf, plus de sleutels die
34
- * de eigenaar-app van dat subject teruggaf (`ScopeAuth.keys`). Gestempeld bij het schrijven.
30
+ * The file keys this item is findable under: the subject itself, plus the keys the owning app of
31
+ * that subject returned (`ScopeAuth.keys`). Stamped at write time.
35
32
  *
36
- * Dit is wat "vertel me wat er speelde bij deze klant" één geïndexeerde query maakt in
37
- * plaats van een traversal. Een casus die op een gesprek is onthouden draagt via
38
- * `Interaction.partyKeys` ook `domain:vandijck.nl` en `company:co_1`; het bedrijfsdossier
39
- * matcht daarop met zijn eigen handvol sleutels, hoeveel medewerkers dat bedrijf ook heeft.
33
+ * This is what makes "tell me what was going on at this customer" one indexed query instead of a
34
+ * traversal. A case remembered on a conversation also carries `domain:vandijck.nl` and
35
+ * `company:co_1` through `Interaction.partyKeys`; the company file matches on those with its own
36
+ * handful of keys, however many employees that company has.
40
37
  *
41
- * **`keys` en niet `subjects`**, want dat zijn ze niet: `domain:vandijck.nl` is geen subject
42
- * — geen app bezit die soort, dus `authorizeIdentity` erop geeft `allowed: false`. Een naam
43
- * die belooft dat dit subjects zijn, nodigt precies die fout uit. Zelfde woord als
44
- * `Interaction.partyKeys`, `Contact.keys` en `ScopeAuth.keys`: één begrip, één term.
38
+ * **`keys` and not `subjects`**, because they are not: `domain:vandijck.nl` is no subject — no
39
+ * app owns that kind, so `authorizeIdentity` on it returns `allowed: false`. A name promising
40
+ * these are subjects invites exactly that mistake. Same word as `Interaction.partyKeys`,
41
+ * `Contact.keys` and `ScopeAuth.keys`: one concept, one term.
45
42
  *
46
- * Bewust een momentopname en niet op leesmoment opgelost: opgelost bij elke query zou
47
- * betekenen dat elke hit een autorisatie-fan-out kost — precies wat de engine zich niet kan
48
- * veroorloven. De prijs is dat een sleutel die *later* wordt vastgelegd dit item niet meer
49
- * bereikt; in de praktijk dekken `mailto:`/`domain:` dat vrijwel altijd al.
43
+ * Deliberately a snapshot and not resolved at read time: resolving on every query would mean
44
+ * every hit costs an authorization fan-out, which the engine cannot afford. The price is that a
45
+ * key recorded *later* no longer reaches this item; in practice `mailto:`/`domain:` already
46
+ * cover that almost always.
50
47
  *
51
- * `subject` blijft het anker, en is dus géén element-onder-de-andere: de unieke index, het
52
- * vouwen, het wissen bij een verwijderd contact en de autorisatie lopen alle vier dáárover,
53
- * en die hebben er exact één nodig.
48
+ * `subject` stays the anchor and is therefore not one element among the others: the unique
49
+ * index, the folding, the wipe on a deleted contact and the authorization all four run over it,
50
+ * and those need exactly one.
54
51
  */
55
52
  keys?: string[];
56
53
  kind: MemoryKindId;
57
54
  title: string;
58
- /** DE inhoud: markdown, begrensd op {@link MAX_MEMORY_CHARS}. Nooit een genest object. */
55
+ /** THE content: markdown, capped at {@link MAX_MEMORY_CHARS}. Never a nested object. */
59
56
  body: string;
60
- /** Schrijvende app (== `req.source.app`); playbook-schrijfacties komen binnen als "ai". */
57
+ /** Writing app (== `req.source.app`); playbook writes arrive as "ai". */
61
58
  source: string;
62
- /** Identiteit binnen (subject, kind) voor de bron. Bij `cardinality: "single"` de vouw-sleutel. */
59
+ /** Identity within (subject, kind) for the source. With `cardinality: "single"` the fold key. */
63
60
  sourceRef: string;
64
61
  occurredAt: number;
65
62
  /**
66
- * Watermerk: tot en met welk bron-event dit item gevouwen is. Maakt dubbele events en
67
- * retries gratis — een oudere `throughAt` wordt afgewezen in plaats van overschreven.
63
+ * Watermark: up to and including which source event this item is folded. Makes duplicate events
64
+ * and retries free — an older `throughAt` is refused instead of overwriting.
68
65
  */
69
66
  throughRef?: string;
70
67
  throughAt?: number;
71
- /** Optimistic concurrency; de hub doet compare-and-swap op dit veld. */
68
+ /** Optimistic concurrency; the hub does compare-and-swap on this field. */
72
69
  version: number;
73
- /** Overgenomen uit de kind-definitie, niet uit de call — zie `MemoryKindDefinition.visibility`. */
70
+ /** Taken from the kind definition, not from the call — see `MemoryKindDefinition.visibility`. */
74
71
  visibility: MemoryVisibility;
75
72
  /**
76
- * Zichtbaarheids-ANKER (inbox-id / OwnerScope-sleutel), **geen ledenlijst**: een
77
- * gesnapshotte ledenlijst veroudert bij elke inbox-join en reassignment, en
78
- * stale-permissive is een lek.
73
+ * Visibility ANCHOR (inbox id / OwnerScope key), **not a member list**: a snapshotted member list
74
+ * goes stale on every inbox join and reassignment, and stale-permissive is a leak.
79
75
  */
80
76
  audienceRef?: string;
81
77
  /**
82
- * Taal van de inhoud. **Beschrijvend, geen filter** — en dat is een besluit, geen omissie.
78
+ * Language of the content. **Descriptive, not a filter** — a decision, not an omission.
83
79
  *
84
- * Retrieval vergelijkt bewust óók over taalgrenzen: de embeddingmodellen hier zijn meertalig,
85
- * dus een Nederlandse vraag hoort een Engelse casus over hetzelfde probleem te vinden. Er
86
- * stond eerder een harde taalcheck in `rank.ts`; die was nooit aangesloten en zou, als je hem
87
- * wél had aangesloten, bij een anderstalige zoekvraag élk item hebben overgeslagen — want
88
- * niets zet dit veld, dus alles staat op de default.
80
+ * Retrieval deliberately compares across language boundaries too: the embedding models here are
81
+ * multilingual, so a Dutch question should find an English case about the same problem. A hard
82
+ * language check once sat in `rank.ts`; it was never wired up and, had it been, would have
83
+ * skipped *every* item on a foreign-language query — because nothing sets this field, so
84
+ * everything sits on the default.
89
85
  *
90
- * Zet je dit ooit echt, houd het dan een *ordenings*-signaal (materiaal in je eigen taal is
91
- * makkelijker te gebruiken) en geen zichtbaarheidsfilter.
86
+ * If this is ever really set, keep it an *ordering* signal (material in your own language is
87
+ * easier to use) and not a visibility filter.
92
88
  */
93
89
  locale: string;
94
- /** Gedenormaliseerde termen: het enige selectieve structurele filter (er is geen substring-operator). */
90
+ /** Denormalized terms: the only selective structural filter (there is no substring operator). */
95
91
  keywords?: string[];
96
- /** Snelle alternatieve sleutels, bv. `tel:+31612345678` voor het rinkelmoment. */
92
+ /** Fast alternative keys, e.g. `tel:+31612345678` for the moment the phone rings. */
97
93
  tags?: string[];
98
94
  links?: MemoryLink[];
99
- /** Model waarmee de vector is gemaakt; retrieval vergelijkt alleen binnen hetzelfde model. */
95
+ /** Model the vector was made with; retrieval only compares within the same model. */
100
96
  embeddingModel?: string;
101
- /** Uit een live pull (fase 3); nooit gepersisteerd. */
97
+ /** From a live pull (phase 3); never persisted. */
102
98
  live?: boolean;
103
99
  createdAt?: number;
104
100
  updatedAt?: number;
105
101
  }
106
102
  /**
107
- * `"audience"` = alleen voor wie het subject mag zien. `"org"` = org-breed leesbaar en
108
- * daarmee vindbaar in het cross-subject-pad ("is dit eerder bij een andere klant
109
- * voorgekomen?").
103
+ * `"audience"` = only for whoever may see the subject. `"org"` = readable org-wide and therefore
104
+ * findable in the cross-subject path ("has this happened at another customer before?").
110
105
  *
111
- * Per **kind** gedeclareerd en niet per item: het cross-subject-pad kan zich geen
112
- * autorisatie-round-trip per hit veroorloven, dus het filtert structureel op deze kolom.
106
+ * Declared per **kind** and not per item: the cross-subject path cannot afford an authorization
107
+ * round trip per hit, so it filters structurally on this column.
113
108
  */
114
109
  export type MemoryVisibility = "audience" | "org";
@@ -2,65 +2,65 @@ import { LocaleBundle } from '../analytics/dashboard';
2
2
  import { OwnerScope } from '../scope/types';
3
3
  import { MemoryKindId, MemoryVisibility } from './item';
4
4
  /**
5
- * Wat er onthouden mág worden, en met welke regels.
5
+ * What may be remembered, and under which rules.
6
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.
7
+ * Two sources, one type:
8
+ * - **app-declared** through `GET /provider/memory/describe` (the built-in defaults);
9
+ * - **org-owned** as a row in `memory_kind`. Template: `CustomFieldDef` — the organisation
10
+ * defines the key, a generic store keeps the value.
11
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.
12
+ * `ownerScope` is what makes "everyone wants their own relevant data" possible: sales records
13
+ * different things from support, and a personal kind belongs to that user only.
14
14
  */
15
15
  export interface MemoryKindDefinition {
16
- /** Org-eigen: `[a-z0-9_]+` (geen punt — die leest als een genest form-pad). App-eigen: `<app>.<naam>`. */
16
+ /** Org-owned: `[a-z0-9_]+` (no dot — that reads as a nested form path). App-owned: `<app>.<name>`. */
17
17
  id: MemoryKindId;
18
18
  label: string;
19
19
  description?: string;
20
- /** Subject-soorten waarop dit kind mag landen, bv. `["interaction"]` of `["contact"]`. */
20
+ /** Subject kinds this kind may land on, e.g. `["interaction"]` or `["contact"]`. */
21
21
  subjectKinds: string[];
22
22
  visibility: MemoryVisibility;
23
- /** `"single"` = één item per (subject, kind), doorvouwen. `"many"` = losse items. */
23
+ /** `"single"` = one item per (subject, kind), folded onward. `"many"` = separate items. */
24
24
  cardinality: "single" | "many";
25
- /** Ordening onder het tekenbudget van de bundel. */
25
+ /** Ordering under the bundle's character budget. */
26
26
  priority: number;
27
- /** Mag dit kind in het cross-subject-pad meedoen? Alleen zinvol bij `visibility: "org"`. */
27
+ /** May this kind take part in the cross-subject path? Only meaningful with `visibility: "org"`. */
28
28
  crossSubjectSearchable: boolean;
29
- /** Embedden kost geld; per kind aan/uit. */
29
+ /** Embedding costs money; on or off per kind. */
30
30
  embed: boolean;
31
31
  retentionDays?: number;
32
- /** Rang-multiplier: een opgeloste casus verslaat een losse notitie. Default 1. */
32
+ /** Rank multiplier: a resolved case beats a loose note. Defaults to 1. */
33
33
  weight?: number;
34
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.
35
+ * Who owns this kind. Decides both who may write and the **ordering** for a reader (own team
36
+ * first). Absent = the whole organisation.
37
37
  */
38
38
  ownerScope?: OwnerScope;
39
- /** Wie hem declareerde. De org kan een app-kind niet oprekken, alleen uitzetten. */
39
+ /** Who declared it. The org cannot widen an app kind, only switch it off. */
40
40
  origin: "app" | "org";
41
41
  enabled: boolean;
42
42
  }
43
43
  /**
44
- * Bare payload van `GET /provider/memory/describe` — **niet** in `ResponseFactory`
45
- * verpakt (mal: `AnalyticsSourceDescription`).
44
+ * Bare payload of `GET /provider/memory/describe` — **not** wrapped in `ResponseFactory`
45
+ * (template: `AnalyticsSourceDescription`).
46
46
  */
47
47
  export interface MemorySourceDescription {
48
- /** De declarerende app (== `manifest.name` == `req.source.app`). */
48
+ /** The declaring app (== `manifest.name` == `req.source.app`). */
49
49
  source: string;
50
50
  kinds: MemoryKindDefinition[];
51
- /** Vlakke LIJST, zoals {@link LocaleBundle}; zie daar waarom die vorm blijft. */
51
+ /** Flat LIST, like {@link LocaleBundle}; see there why that shape stays. */
52
52
  locales?: LocaleBundle;
53
- /** Fase 3: welke subjects/kinds deze bron live kan leveren. */
53
+ /** Phase 3: which subjects/kinds this source can deliver live. */
54
54
  live?: {
55
55
  subjectKinds: string[];
56
56
  kinds: MemoryKindId[];
57
57
  };
58
58
  }
59
- /** De samengestelde catalogus die de hub aan de frontend levert (`GET /kinds`). */
59
+ /** The composed catalog the hub delivers to the frontend (`GET /kinds`). */
60
60
  export interface MemoryKindCatalog {
61
- /** App-gedeclareerd + org-eigen, gemengd. */
61
+ /** App-declared plus org-owned, mixed. */
62
62
  kinds: MemoryKindDefinition[];
63
- /** Bronnen die meededen aan de fan-out (voor "wie levert dit?"). */
63
+ /** Sources that took part in the fan-out (for "who provides this?"). */
64
64
  sources: string[];
65
65
  locales: LocaleBundle;
66
66
  }
@@ -1,71 +1,71 @@
1
1
  import { MemoryItem, MemoryKindId, MemorySubjectKey } from './item';
2
- /** Grenzen van het tekenbudget van een bundel. Buiten bereik wordt geklemd, niet geweigerd. */
2
+ /** Bounds of a bundle's character budget. Out of range is clamped, not refused. */
3
3
  export declare const MIN_MEMORY_BUDGET = 500;
4
4
  export declare const MAX_MEMORY_BUDGET = 12000;
5
5
  export declare const DEFAULT_MEMORY_BUDGET = 4000;
6
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.
7
+ * One query contract for the file panel, the briefing while the phone rings, and every AI tool. No
8
+ * second code path: the difference between those three is `budget`, not code.
9
9
  */
10
10
  export interface MemoryQuery {
11
- /** Weglaten = cross-subject zoeken ("vergelijkbare cases"). */
11
+ /** Omit = cross-subject search ("similar cases"). */
12
12
  subject?: MemorySubjectKey;
13
- /** Extra subjects die bij hetzelfde beeld horen, bv. het contact naast de interactie. */
13
+ /** Extra subjects belonging to the same picture, e.g. the contact next to the interaction. */
14
14
  alsoSubjects?: MemorySubjectKey[];
15
15
  /**
16
- * Ook items die niet ópt subject staan maar er wél bij horen: alles wat dezelfde
17
- * dossiersleutel draagt (`MemoryItem.keys`).
16
+ * Also items not *on* the subject but belonging to it: everything carrying the same file key
17
+ * (`MemoryItem.keys`).
18
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.
19
+ * This is the answer to "what was going on at this company": a case sits on the conversation, and
20
+ * the company file finds it through `domain:`/`company:` instead of through a list of fifty
21
+ * employee subjects. One extra `$or` branch on an indexed array column, no second query and no
22
+ * extra authorization fan-out.
23
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.
24
+ * **Only `visibility: "org"` is inherited.** The authorization of this path is the single check
25
+ * on the anchor; an inherited item is by definition not authorized on that anchor. A case from
26
+ * someone's personal mailbox is already narrowed to `audience` at write time
27
+ * (`effectiveVisibility`) and therefore stays out of a colleague's customer file.
28
28
  *
29
- * Vereist een anker (`subject`); zonder anker is dit het cross-subject-pad.
29
+ * Requires an anchor (`subject`); without one this is the cross-subject path.
30
30
  */
31
31
  related?: boolean;
32
32
  /** Default true. */
33
33
  resolveAliases?: boolean;
34
34
  kinds?: MemoryKindId[];
35
35
  tags?: string[];
36
- /** Vrije tekst. Afwezig = puur structurele ordening (priority x recency x weight) en dus geen embedding-call. */
36
+ /** Free text. Absent = purely structural ordering (priority x recency x weight), so no embedding call. */
37
37
  text?: string;
38
38
  since?: number;
39
39
  limit?: number;
40
- /** Zo bedoel je "bij ANDERE klanten". */
40
+ /** This is how you say "at OTHER customers". */
41
41
  excludeSubjects?: MemorySubjectKey[];
42
42
  format?: "items" | "bundle" | "both";
43
- /** Geklemd op [{@link MIN_MEMORY_BUDGET}, {@link MAX_MEMORY_BUDGET}]. */
43
+ /** Clamped to [{@link MIN_MEMORY_BUDGET}, {@link MAX_MEMORY_BUDGET}]. */
44
44
  budget?: number;
45
- /** Fase 3: ook live bronnen bevragen, met harde timeout en eigen sub-budget. */
45
+ /** Phase 3: query live sources too, with a hard timeout and their own sub-budget. */
46
46
  live?: boolean;
47
47
  }
48
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.
49
+ * Subject kinds for which "the file" includes the **relations**: everything carrying the same file
50
+ * key, even when it was remembered on another subject.
51
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.
52
+ * With a customer or a person the party *is* the question — "what was going on at Van Dijck" is
53
+ * about the company, while the cases sit on the conversations. With a conversation it is not: there
54
+ * you want the thread itself, because in a bounded bundle the whole customer history crowds out
55
+ * exactly what is going on right now.
56
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.
57
+ * Here and not in the tool or the panel, because there are two of them: the assistant and the file
58
+ * panel should mean the same thing by "this customer's file". Two copies of that rule is exactly
59
+ * the kind of rule that drifts apart.
60
60
  */
61
61
  export declare const RELATED_SUBJECT_KINDS: readonly ["contact", "company"];
62
- /** Hoort {@link MemoryQuery.related} standaard aan te staan voor dit subject? */
62
+ /** Should {@link MemoryQuery.related} default to on for this subject? */
63
63
  export declare function relatedByDefault(subject: MemorySubjectKey | undefined): boolean;
64
64
  export interface MemoryHit {
65
65
  item: MemoryItem;
66
66
  score: number;
67
67
  snippet: string;
68
- /** Ruw materiaal voor een confidence-gate (fase 4): waar kwam de score vandaan? */
68
+ /** Raw material for a confidence gate (phase 4): where did the score come from? */
69
69
  matched: {
70
70
  keyword: number;
71
71
  semantic: number;
@@ -75,39 +75,37 @@ export interface MemoryHit {
75
75
  export interface MemoryQueryResult {
76
76
  hits: MemoryHit[];
77
77
  bundle?: string;
78
- /** Hoeveel rijen het structurele voorfilter opleverde. */
78
+ /** How many rows the structural pre-filter yielded. */
79
79
  scanned: number;
80
- /** Scan-cap geraakt OF hits uit de bundel gevallen — nooit stil afkappen. */
80
+ /** Scan cap hit OR hits dropped from the bundle — never truncate silently. */
81
81
  truncated?: boolean;
82
- /** `false` = keyword-only (geen embedding-account, of geen enkele vergelijkbare vector). */
82
+ /** `false` = keyword-only (no embedding account, or not a single comparable vector). */
83
83
  semantic: boolean;
84
- /** Hits die de her-autorisatie van de top-K niet overleefden. */
84
+ /** Hits that did not survive the re-authorization of the top-K. */
85
85
  withheld?: number;
86
86
  /**
87
- * Kandidaten die op het cross-subject-pad afvielen op de absolute gelijkenisdrempel.
87
+ * Candidates dropped on the cross-subject path by the absolute similarity threshold.
88
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.
89
+ * The difference with an empty result: `belowThreshold: 7` means "there was material, but nothing
90
+ * really resembled it" and `undefined` means "there was nothing". Without this counter the
91
+ * threshold cannot be calibrated — you only see that nothing comes back, not whether it sits too
92
+ * high.
93
93
  */
94
94
  belowThreshold?: number;
95
95
  /**
96
- * Kandidaten overgeslagen door model- of taal-mismatch. Zonder deze teller degradeert
97
- * een modelwissel volkomen stil: `cosineSimilarity` geeft bij dimensie-mismatch 0, dus
98
- * na het omzetten van `isDefaultEmbedding` scoort élk bestaand item 0 en valt retrieval
99
- * geruisloos terug op keyword.
96
+ * Candidates skipped by a model or language mismatch. Without this counter a model switch
97
+ * degrades completely silently: `cosineSimilarity` returns 0 on a dimension mismatch, so after
98
+ * flipping `isDefaultEmbedding` *every* existing item scores 0 and retrieval quietly falls back
99
+ * to keyword.
100
100
  */
101
101
  vectorSkipped?: number;
102
102
  /**
103
- * Waarom er niets terugkwam, als dat een structurele reden heeft in plaats van "niets
104
- * gevonden".
103
+ * Why nothing came back, when that has a structural reason instead of "nothing found".
105
104
  *
106
- * `"no-cross-subject-kinds"` is de belangrijkste: zoeken bij ándere klanten leest alleen
107
- * geheugensoorten die als `visibility: "org"` én `crossSubjectSearchable` zijn
108
- * gedeclareerd. Is er geen enkele, dan is een leeg resultaat geen zoekuitkomst maar een
109
- * configuratiefeit — en dat hoort de caller te weten in plaats van te concluderen dat er
110
- * niets vergelijkbaars bestaat.
105
+ * `"no-cross-subject-kinds"` is the important one: searching at *other* customers reads only
106
+ * memory kinds declared both `visibility: "org"` and `crossSubjectSearchable`. If there is not a
107
+ * single one, an empty result is not a search outcome but a configuration fact — and the caller
108
+ * should know that instead of concluding nothing comparable exists.
111
109
  */
112
110
  reason?: "no-cross-subject-kinds" | "no-subject-access";
113
111
  }