@opencxh/domain 1.256.0 → 1.260.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
+ import { Autonomy } from '../playbook/types';
1
2
  /**
2
3
  * An **agent**: a digital colleague. A profile plus an identity plus a mandate.
3
4
  *
@@ -42,6 +43,15 @@ export interface Agent {
42
43
  name: string;
43
44
  policy: "read" | "write";
44
45
  }[];
46
+ /**
47
+ * Does this colleague act, or propose and wait for a human?
48
+ *
49
+ * Absent = `"suggest"`, fail-closed. On the agent because it is the plainest mandate there is,
50
+ * and because it has to be settable for work that has no playbook: an assignment someone typed
51
+ * took its autonomy from the shared "Assist" playbook, which is gone. A triggered assignment
52
+ * still follows its playbook — that is where an organisation configured that scenario.
53
+ */
54
+ autonomy?: Autonomy;
45
55
  /**
46
56
  * Which colleagues this agent may call in for a sub-question (agent ids).
47
57
  *
@@ -1,5 +1,6 @@
1
1
  import { AIAttachment, RejectedAIAttachment } from '../../platform/ai-attachments';
2
2
  import { ToolTraceEntry } from '../../platform/ai-tools';
3
+ import { UserType } from '../user/types';
3
4
  export interface AIMessageInput {
4
5
  text: string;
5
6
  type: "text";
@@ -48,6 +49,37 @@ export interface AIMessage {
48
49
  output: AIMessageOutput;
49
50
  accountId?: string;
50
51
  model?: string;
52
+ /**
53
+ * The brain that produced this turn. `accountId` + `model` said *what* answered and never
54
+ * *who*, so "which profile wrote this" was unanswerable after the fact — and a profile people
55
+ * edit is exactly the thing you want to look back at when an answer was wrong.
56
+ *
57
+ * Absent on a row nobody's brain produced: a human writing in an assignment thread.
58
+ */
59
+ profileId?: string;
60
+ /** The agent whose turn this was, when it was an agent's. Absent for the assistant. */
61
+ agentId?: string;
62
+ /**
63
+ * Who put this row in the thread, when it was somebody rather than the assistant.
64
+ *
65
+ * **The shape `getUserProfile` returns**, deliberately: `type` is the existing answer to
66
+ * "human or agent" ({@link UserType}) and inventing a second author vocabulary for one screen
67
+ * is how this codebase ended up asking "is this a message?" in six places.
68
+ *
69
+ * Why it has to be stored: an answer from a colleague-agent arrives as `sender: "user"` — it
70
+ * *is* the user turn of the next model call — so after a reload it read exactly like an
71
+ * instruction from the person who gave the assignment. The difference between material to
72
+ * weigh and an order to follow lived only in the wake note, which is not persisted.
73
+ *
74
+ * `type` is required here even though it is optional on a user record: every writer of this
75
+ * field knows which of the two it is, and "unknown" is precisely the answer that would make
76
+ * the field pointless.
77
+ */
78
+ author?: {
79
+ id: string;
80
+ name: string;
81
+ type: UserType;
82
+ };
51
83
  externalId?: string;
52
84
  /** Tools the assistant invoked while producing this message (final, persisted trace). */
53
85
  toolTrace?: ToolTraceEntry[];
@@ -49,16 +49,25 @@ export interface Assignment {
49
49
  organizationId: string;
50
50
  /** The agent doing this: the `userId` of a user with `type: "agent"`. */
51
51
  agentId: string;
52
- /** The definition this assignment came from (a playbook with a procedure). */
53
- jobId: string;
54
52
  /**
55
- * The version it started on purely for the audit.
53
+ * The playbook this assignment came from, when a trigger put it down. **Absent when someone
54
+ * typed it**, which is the common case in Assist.
55
+ *
56
+ * It used to be required, so a typed request had to invent a definition to be allowed to exist:
57
+ * one org-wide "Assist" playbook with an empty procedure, created on first use and rewritten on
58
+ * every start and every delegation. A shared mutable row behind a foreign key — and a turn read
59
+ * its agent off it, so one delegation could hand every other running assignment to a different
60
+ * agent. The row is gone; what a typed assignment needs, it now carries itself.
61
+ */
62
+ jobId?: string;
63
+ /**
64
+ * The version it started on — purely for the audit. Absent with {@link Assignment.jobId}.
56
65
  *
57
66
  * Every **turn** pins its own procedure (`run.decider`), so improved prose arrives on the next
58
67
  * turn without a running turn switching instructions mid-flight. Pinning forever would mean a
59
68
  * correction never arrives; not pinning would mean a turn changes halfway.
60
69
  */
61
- jobVersion: number;
70
+ jobVersion?: number;
62
71
  /** What this assignment is about. Absent = work without a resource (a rollup, a chore). */
63
72
  subjectKind?: string;
64
73
  subjectId?: string;
@@ -79,6 +88,15 @@ export interface Assignment {
79
88
  * triggered one may not. The list needs to tell them apart, so it is stored.
80
89
  */
81
90
  origin?: "trigger" | "user";
91
+ /**
92
+ * Allowed tools for this assignment, narrowing-only against the agent's brain — the same rule
93
+ * `Procedure.tools` carries. Absent = whatever the brain allows.
94
+ *
95
+ * `POST assignment/start` has always accepted and validated this, and then dropped it on the
96
+ * floor: there was nowhere to put it, because the bounds lived on the shared playbook that
97
+ * every assignment in the organisation had to share.
98
+ */
99
+ tools?: string[];
82
100
  /**
83
101
  * The assignment that delegated this one, when an agent asked a colleague-agent a sub-question.
84
102
  * The return address: `applyTurn` reports back here the moment this assignment goes terminal.
@@ -439,8 +439,13 @@ export type StartedBy =
439
439
  export interface PlaybookRun {
440
440
  id: string;
441
441
  organizationId: string;
442
- playbookId: string;
443
- playbookVersion: number;
442
+ /**
443
+ * The definition this run is of. **Absent on a turn of a typed assignment**: that work has no
444
+ * playbook, and inventing one so this column could stay required is exactly what the shared
445
+ * "Assist" row was.
446
+ */
447
+ playbookId?: string;
448
+ playbookVersion?: number;
444
449
  /**
445
450
  * The assignment this is a **turn** of, if any. Absent = a standalone execution (an
446
451
  * automation that fires and is done). Present = one move in work that outlives this run,
@@ -28,7 +28,14 @@ export interface Session {
28
28
  */
29
29
  externalId?: string;
30
30
  ui: {
31
- canvas: FederatedResourceRef;
31
+ /**
32
+ * What this transport draws in the call surface — a video plane, a meeting
33
+ * grid. Optional: an audio-only call has no picture, and the shell renders
34
+ * the call timeline (events, captions, assistant cards) either way. A
35
+ * provider that declares one gets it *above* that timeline, never instead
36
+ * of it.
37
+ */
38
+ canvas?: FederatedResourceRef;
32
39
  actionTray?: FederatedResourceRef;
33
40
  };
34
41
  }
@@ -151,7 +158,8 @@ export type TransportConfig = {
151
158
  kind: "session";
152
159
  accountSelector: AccountSelector;
153
160
  ui: {
154
- canvas: `${string}:${string}`;
161
+ /** See `Session.ui.canvas` — optional, a transport need not draw a picture. */
162
+ canvas?: `${string}:${string}`;
155
163
  actionTray?: `${string}:${string}`;
156
164
  };
157
165
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencxh/domain",
3
- "version": "1.256.0",
3
+ "version": "1.260.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",