@opencxh/domain 1.270.0 → 1.275.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 (39) hide show
  1. package/dist/entities/ai-account/capabilities.d.ts +4 -0
  2. package/dist/entities/ai-account/index.d.ts +3 -0
  3. package/dist/entities/ai-account/modality.d.ts +26 -0
  4. package/dist/entities/ai-account/modality.test.d.ts +1 -0
  5. package/dist/entities/ai-account/routing.d.ts +71 -0
  6. package/dist/entities/ai-account/routing.test.d.ts +1 -0
  7. package/dist/entities/ai-account/system-one.d.ts +109 -0
  8. package/dist/entities/ai-account/system-one.test.d.ts +1 -0
  9. package/dist/entities/ai-account/types.d.ts +12 -5
  10. package/dist/entities/ai-message/types.d.ts +7 -0
  11. package/dist/entities/ai-settings/types.d.ts +9 -0
  12. package/dist/entities/eval/index.d.ts +2 -0
  13. package/dist/entities/eval/runner.d.ts +14 -0
  14. package/dist/entities/eval/runner.test.d.ts +1 -0
  15. package/dist/entities/eval/types.d.ts +46 -0
  16. package/dist/entities/inbox/types.d.ts +4 -4
  17. package/dist/entities/interaction/attention.d.ts +12 -13
  18. package/dist/entities/kb/index.d.ts +1 -0
  19. package/dist/entities/kb/keys.d.ts +2 -0
  20. package/dist/entities/rule/bind.d.ts +8 -0
  21. package/dist/entities/rule/bind.test.d.ts +1 -0
  22. package/dist/entities/rule/condition-flat.test.d.ts +1 -0
  23. package/dist/entities/rule/condition.d.ts +52 -0
  24. package/dist/entities/rule/condition.test.d.ts +1 -0
  25. package/dist/entities/rule/cron.d.ts +40 -0
  26. package/dist/entities/rule/cron.test.d.ts +1 -0
  27. package/dist/entities/rule/eval.d.ts +31 -0
  28. package/dist/entities/rule/index.d.ts +6 -0
  29. package/dist/entities/rule/match.d.ts +8 -0
  30. package/dist/entities/rule/outcome.d.ts +42 -0
  31. package/dist/entities/rule/outcome.test.d.ts +1 -0
  32. package/dist/entities/rule/trigger-source.d.ts +137 -0
  33. package/dist/entities/rule/trigger-source.test.d.ts +1 -0
  34. package/dist/entities/rule/types.d.ts +44 -0
  35. package/dist/index.cjs +20 -20
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +2054 -1712
  38. package/dist/platform/resource-source.d.ts +5 -0
  39. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Is what a rule wrote still standing?
3
+ *
4
+ * The feedback loop's first real signal, and it needs no new write path: every run already
5
+ * carries `priors` — the previous value of each field it wrote, plus the params it wrote them
6
+ * with — because undo needs exactly that. Asking the same question an hour later turns it into a
7
+ * measurement.
8
+ *
9
+ * **Why this matters more than an approval rate.** The trust ladder promotes on *observed
10
+ * unchanged approval*, and approving is a ritual — people click yes. A correction is a real
11
+ * objection, and so is an undo. An automatic action that could be reversed in one click and never
12
+ * is, is a stronger promotion signal than any approval percentage; a burst of corrections is an
13
+ * immediate demotion signal.
14
+ */
15
+ export type RunOutcome = "kept" | "corrected" | "undone" | "unknown";
16
+ /** The half of an action's prior this question needs. `before` is undo's business, not this one. */
17
+ export interface OutcomePrior {
18
+ action: string;
19
+ params: Record<string, unknown>;
20
+ /** Which params were content — a field the subject owns — rather than addressing. */
21
+ fields: string[];
22
+ }
23
+ /**
24
+ * Which fields no longer hold what the action put there.
25
+ *
26
+ * Shared with the undo, deliberately: "changed since" decides both whether an undo may run and
27
+ * whether this run counts as corrected, and two definitions of that would eventually disagree —
28
+ * with the undo overwriting somebody's change while the measurement called it kept.
29
+ *
30
+ * A field the subject does not report at all (`undefined`) is **not** drift. That is a reader
31
+ * that did not return the column, not a person who changed it, and counting it would turn every
32
+ * thin read into a wave of false corrections.
33
+ */
34
+ export declare function driftedFields(prior: OutcomePrior, current: Record<string, unknown> | undefined): string[];
35
+ /**
36
+ * The outcome of one run.
37
+ *
38
+ * `unknown` when the subject cannot be read — it was deleted, or its kind has no reader. Kept
39
+ * apart from `kept` on purpose: "nobody objected" and "we could not look" are different facts,
40
+ * and folding the second into the first is how a trust ladder promotes on silence.
41
+ */
42
+ export declare function runOutcome(priors: readonly OutcomePrior[], current: Record<string, unknown> | undefined, undoneAt?: number): RunOutcome;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,137 @@
1
+ import { ToolCatalogEntry } from '../../platform/ai-tools';
2
+ /**
3
+ * What kind of value sits at a field, so the builder knows which widget to draw and the
4
+ * comparison operators that make sense.
5
+ *
6
+ * No `object`: a rule compares a leaf. Offering a whole object as the left-hand side of `==`
7
+ * produces a condition that is never true and reads as if it should be.
8
+ *
9
+ * `string[]` is here for the same reason rather than being folded into `string`. Tags, labels and
10
+ * party keys are the most obvious things to write a rule about, and on an array only `in` means
11
+ * anything — `==` against one is the silent never-matches this whole seam exists to prevent.
12
+ */
13
+ export type EventFieldType = "string" | "string[]" | "number" | "boolean" | "date";
14
+ /** Operators that mean something for this kind of value. The builder offers no others. */
15
+ export declare function opsForFieldType(type: EventFieldType): readonly string[];
16
+ /** One choice for a field with a fixed or looked-up set of values. */
17
+ export interface EventFieldOption {
18
+ value: string;
19
+ /**
20
+ * The label as the server could build it. For something an admin typed (a project status, an
21
+ * inbox) that is the text itself; for one of ours it is the already-resolved fallback.
22
+ */
23
+ label: string;
24
+ /**
25
+ * Translation key, for a value that is *ours* and therefore translatable.
26
+ *
27
+ * Same split as `ActivityPreview.snippet`/`snippetKey`, and for the same reason: the list is
28
+ * built once on a server that has no user language, while every reader has their own. The
29
+ * builder prefers this and falls back to `label`.
30
+ */
31
+ labelKey?: string;
32
+ }
33
+ /**
34
+ * One thing a rule can test, declared by the app that writes the row.
35
+ *
36
+ * **Why declared and not listed centrally.** A hand-written table of fields drifts from the
37
+ * payload it describes, and the drift is silent: a rule on a path that yields `undefined` never
38
+ * fires and says nothing about why. That already happened here once — `TRIGGER_VARS` exists
39
+ * because the picker offered `trigger.fromEmail` and `trigger.channel`, neither of which the
40
+ * engine ever filled. A central list for comms, work and sales would be that same table with
41
+ * three apps to drift from instead of one.
42
+ */
43
+ export interface EventField {
44
+ /**
45
+ * Path under `subject`, dot-notated: `"priority"`, `"lastActivityPreview.text"`.
46
+ *
47
+ * Relative, because `subject` is where the owning app's row lands in the condition context
48
+ * (`matchRules` builds `{ event, subject }`) and repeating that prefix in every declaration is
49
+ * an invitation to get it wrong in one of them. {@link fieldVarPath} adds it, once.
50
+ */
51
+ path: string;
52
+ type: EventFieldType;
53
+ /** What a person calls this. The builder shows this; the path is never on screen. */
54
+ label: string;
55
+ /**
56
+ * A fixed set of values — the builder offers a dropdown instead of a free text field.
57
+ *
58
+ * For what the *app* defines (a priority, a direction, a status category). What the
59
+ * *organisation* defines goes through {@link lookup}, because it is data and not vocabulary.
60
+ */
61
+ values?: EventFieldOption[];
62
+ /**
63
+ * The values are organisation data: ask the declaring app via `/provider/triggers/options`.
64
+ *
65
+ * This exists so the builder needs no per-field knowledge. Today `ConditionBuilder` has a
66
+ * `topicOptions()` that recognises a topic *by field name* — one hard-coded exception, and
67
+ * the second one (inboxes, users, statuses, pipelines) makes it a pattern.
68
+ */
69
+ lookup?: string;
70
+ }
71
+ /**
72
+ * One event an app publishes, and what a rule can ask about its subject.
73
+ *
74
+ * `fields` is per event and not per app on purpose: the subject differs even within one app —
75
+ * comms hands over the interaction, work the item, sales the transaction.
76
+ */
77
+ export interface EventDescriptor {
78
+ /** As the bus delivers it, app-prefixed: `"communication:activities:created"`. */
79
+ name: string;
80
+ /** What this event is, in the author's language: "Er komt een bericht binnen". */
81
+ label: string;
82
+ /**
83
+ * What the subject is. Also the key the undo reader uses to fetch current state, so a new
84
+ * subject kind needs a reader there before its runs can be undone.
85
+ */
86
+ subjectKind: string;
87
+ fields: EventField[];
88
+ }
89
+ /** What a `trigger-source` returns on `GET /provider/triggers/describe`. */
90
+ export interface TriggerSourceDescription {
91
+ events: EventDescriptor[];
92
+ }
93
+ /** An event plus the app that answered for it — the merged catalog a builder reads. */
94
+ export interface VocabularyEvent extends EventDescriptor {
95
+ /**
96
+ * From the runtime, never from a field inside the payload: that would let one app claim
97
+ * another's events. Same rule the rest of the fan-out helpers hold.
98
+ */
99
+ app: string;
100
+ }
101
+ /**
102
+ * Everything a builder needs to write a rule: what it can react to, and what it can do.
103
+ *
104
+ * Both halves in one answer because they are one question — "what is possible here" — and because
105
+ * they are read together on every builder render. The action half is the tool federation with the
106
+ * model taken out from in front; it is filtered to what a rule may actually use, so the builder
107
+ * never has to show something it would refuse to save.
108
+ */
109
+ export interface RuleVocabulary {
110
+ events: VocabularyEvent[];
111
+ /** The actions a rule may use. Outward ones are absent, not disabled — see `validateActions`. */
112
+ actions: ToolCatalogEntry[];
113
+ /** Apps that declare the role but answered nothing. Silence is named, not hidden. */
114
+ degradedApps: string[];
115
+ }
116
+ /**
117
+ * The JSONLogic variable for a field: `subject.<path>`.
118
+ *
119
+ * One function so the builder, the templates and the declaration tests cannot disagree about the
120
+ * prefix. `matchRules` evaluates against `{ event, subject }`, and a condition written against
121
+ * the bare path silently compares `undefined`.
122
+ */
123
+ export declare function fieldVarPath(field: Pick<EventField, "path">): string;
124
+ /** The event with this name, or `undefined`. */
125
+ export declare function findEvent(vocabulary: Pick<RuleVocabulary, "events">, name: string): VocabularyEvent | undefined;
126
+ /**
127
+ * Which declared paths the real subject does not have.
128
+ *
129
+ * **This is the point of declaring fields near the code that writes them.** A declaration is only
130
+ * worth more than a central list if something holds it against reality, and this is that
131
+ * something: each app's test feeds a real row through and asserts the answer is empty.
132
+ *
133
+ * A path is "missing" when it resolves to `undefined` — absent, or running through a `null`.
134
+ * `null` itself counts as present: a cleared assignee is a value a rule can meaningfully test
135
+ * for, and treating it as missing would make every declaration fail on an empty row.
136
+ */
137
+ export declare function missingFieldPaths(fields: readonly EventField[], subject: unknown): string[];
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { OwnerScope } from '../scope/types';
2
+ import { OutcomePrior, RunOutcome } from './outcome';
2
3
  /**
3
4
  * When something starts. One vocabulary for every executor.
4
5
  *
@@ -101,3 +102,46 @@ export interface RuleEvent {
101
102
  /** How many rule hops produced this event. Absent = zero, a genuine first cause. */
102
103
  depth?: number;
103
104
  }
105
+ /** One line of a rule run log. `ok: false` is a step that did not land, not a rule that did not fire. */
106
+ export interface RuleTraceEntry {
107
+ ruleId: string;
108
+ action?: string;
109
+ ok: boolean;
110
+ note: string;
111
+ }
112
+ /**
113
+ * What one action changed, captured when it ran — the params it was called with, which of those
114
+ * were content (a field the subject owns) rather than addressing, and those fields as they were.
115
+ * A key missing from `before` held nothing.
116
+ */
117
+ export interface ActionPrior extends OutcomePrior {
118
+ /** The rule that ran this action. Empty for an undo replay. */
119
+ ruleId?: string;
120
+ before: Record<string, unknown>;
121
+ }
122
+ /** What an owning app's write path posts after a rule acted: one rule, one event. */
123
+ export interface RuleRunRecord {
124
+ ruleId: string;
125
+ ruleName?: string;
126
+ eventName: string;
127
+ eventId: string;
128
+ subjectKind?: string;
129
+ subjectId?: string;
130
+ applied: number;
131
+ trace: RuleTraceEntry[];
132
+ priors: ActionPrior[];
133
+ }
134
+ /**
135
+ * One thing a rule did, once, as the run log stores it. Written only when something happened.
136
+ *
137
+ * `outcome` is stamped an hour after the fact; empty means "not judged yet", and `unknown` is
138
+ * deliberately not `kept` — "nobody objected" and "we could not look" are different facts.
139
+ */
140
+ export interface RuleRun extends RuleRunRecord {
141
+ id: string;
142
+ undoneAt?: number;
143
+ undoneBy?: string;
144
+ outcome?: RunOutcome | "";
145
+ outcomeAt?: number;
146
+ createdAt?: number;
147
+ }