@smooai/smooth-operator 1.18.0 → 1.19.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.
@@ -66,6 +66,10 @@ export interface CreateConversationSessionRequest {
66
66
  * Browser fingerprint string (e.g. from ThumbmarkJS) used for anonymous user correlation across sessions.
67
67
  */
68
68
  browserFingerprint?: string;
69
+ /**
70
+ * Client render capabilities for this session. Known value: `identity_form` — the client can render a structured identity-intake form, so the server may emit `identity_intake_required` mid-turn. Text-only channels (SMS, voice) omit this and the server degrades intake to conversational turn-by-turn collection. Unknown values are ignored (forward-compatible).
71
+ */
72
+ supports?: string[];
69
73
  /**
70
74
  * Arbitrary key/value metadata to attach to the session.
71
75
  */
@@ -321,6 +325,10 @@ export interface SendMessageRequest {
321
325
  * Whether to receive incremental `stream_chunk` and `stream_token` events. Defaults to `true`. Set to `false` to receive only the final `eventual_response`.
322
326
  */
323
327
  stream?: boolean;
328
+ /**
329
+ * Optional gateway model id to run THIS turn on (e.g. a /smooth-mode preset). Absent → the server's configured default model.
330
+ */
331
+ model?: string;
324
332
  }
325
333
 
326
334
  // ── from actions/send-message.schema.json ──
@@ -372,6 +380,54 @@ export interface GeneralAgentResponse {
372
380
  suggestedNextActions: string[];
373
381
  }
374
382
 
383
+ // ── from actions/submit-identity-intake.schema.json ──
384
+ /**
385
+ * Fields sent by the client to submit (or decline) identity intake.
386
+ */
387
+ export interface SubmitIdentityIntakeRequest {
388
+ /**
389
+ * Action discriminator.
390
+ */
391
+ action: 'submit_identity_intake';
392
+ /**
393
+ * Must match the `requestId` from the `identity_intake_required` event being responded to.
394
+ */
395
+ requestId: string;
396
+ /**
397
+ * Session ID of the parked session.
398
+ */
399
+ sessionId: string;
400
+ /**
401
+ * The visitor's identity values. Required unless `declined` is true. Only the fields requested by the `identity_intake_required` event are meaningful; the server validates required-ness against that request.
402
+ */
403
+ values?: {
404
+ /**
405
+ * The visitor's display name.
406
+ */
407
+ name?: string;
408
+ /**
409
+ * The visitor's email address (validated server-side).
410
+ */
411
+ email?: string;
412
+ /**
413
+ * The visitor's phone number (normalized server-side to E.164).
414
+ */
415
+ phone?: string;
416
+ };
417
+ /**
418
+ * True when the visitor refused to share their details. The turn resumes with a declined payload so the agent can proceed gracefully. When true, `values` is ignored.
419
+ */
420
+ declined?: boolean;
421
+ }
422
+
423
+ // ── from actions/submit-identity-intake.schema.json ──
424
+ /**
425
+ * No dedicated response event for `submit_identity_intake`. Valid values (or a decline) are acked with an `immediate_response` and the parked turn resumes its normal streaming sequence. Invalid values emit `identity_intake_invalid` (the turn stays parked). This schema is provided for documentation completeness only.
426
+ */
427
+ export interface SubmitIdentityIntakeResponse {
428
+ [k: string]: unknown;
429
+ }
430
+
375
431
  // ── from actions/verify-otp.schema.json ──
376
432
  /**
377
433
  * Fields sent by the client to submit an OTP code.
@@ -718,6 +774,10 @@ export interface Session {
718
774
  * The conversation this session is attached to.
719
775
  */
720
776
  conversationId: string;
777
+ /**
778
+ * The organization that owns this session. Mirrors `organizationId` on the conversation, participants, and messages so org-scoping is uniform across every domain type and storage backends can write the session's org directly.
779
+ */
780
+ organizationId: string;
721
781
  /**
722
782
  * The agent handling this session.
723
783
  */
@@ -804,6 +864,7 @@ export interface ActionEnvelope {
804
864
  | 'get_conversation_messages'
805
865
  | 'confirm_tool_action'
806
866
  | 'verify_otp'
867
+ | 'submit_identity_intake'
807
868
  | 'ping';
808
869
  /**
809
870
  * Client-generated correlation ID. Will be echoed back on all related server events. Should be unique per in-flight request. If omitted the server may generate one, but correlating responses becomes the client's problem.
@@ -919,6 +980,23 @@ export interface EventualResponse {
919
980
  * Human-readable escalation reason when `needsEscalation` is true.
920
981
  */
921
982
  escalationReason?: string;
983
+ /**
984
+ * Per-turn token accounting and cost, captured from the engine's terminal completion event. Lets a client accumulate live session cost. Optional and back-compatible: absent when the engine reported no usage for the turn (e.g. an offline/mock turn).
985
+ */
986
+ usage?: {
987
+ /**
988
+ * Accumulated cost in USD across every LLM call in this turn (gateway-priced).
989
+ */
990
+ costUsd?: number;
991
+ /**
992
+ * Accumulated prompt (input) tokens across every LLM call in this turn.
993
+ */
994
+ promptTokens?: number;
995
+ /**
996
+ * Accumulated completion (output) tokens across every LLM call in this turn.
997
+ */
998
+ completionTokens?: number;
999
+ };
922
1000
  /**
923
1001
  * The sources that grounded this answer, when any were retrieved. Collected by the runtime from the documents that actually grounded the turn — the auto-injected `[Relevant knowledge]` context and any `knowledge_search` tool results — deduplicated by source id and capped. Optional and back-compatible: absent when the turn used no knowledge sources. Each item is a `Citation` (see `domain/citation.schema.json`).
924
1002
  */
@@ -952,6 +1030,142 @@ export interface EventualResponse {
952
1030
  timestamp?: number;
953
1031
  }
954
1032
 
1033
+ // ── from events/identity-intake-invalid.schema.json ──
1034
+ /**
1035
+ * Event: `identity_intake_invalid`. Emitted when a `submit_identity_intake` action carried values that failed server-side validation (missing required field, malformed email, unparseable phone). The turn REMAINS parked — the client should re-render the intake form with the per-field errors and let the visitor resubmit. Mirrors `otp_invalid`: invalid input is a retryable state, never a terminal `error` event.
1036
+ */
1037
+ export interface IdentityIntakeInvalid {
1038
+ /**
1039
+ * Event type discriminator.
1040
+ */
1041
+ type: 'identity_intake_invalid';
1042
+ /**
1043
+ * Echoes the `requestId` of the parked turn (same correlation as the `identity_intake_required` event).
1044
+ */
1045
+ requestId?: string;
1046
+ /**
1047
+ * Validation failure details.
1048
+ */
1049
+ data: {
1050
+ /**
1051
+ * The request ID this intake belongs to.
1052
+ */
1053
+ requestId: string;
1054
+ /**
1055
+ * Per-field validation errors.
1056
+ */
1057
+ data: {
1058
+ /**
1059
+ * One entry per failed field.
1060
+ *
1061
+ * @minItems 1
1062
+ */
1063
+ errors: [
1064
+ {
1065
+ /**
1066
+ * The field that failed validation.
1067
+ */
1068
+ field: 'name' | 'email' | 'phone';
1069
+ /**
1070
+ * Human-readable validation message for this field.
1071
+ */
1072
+ message: string;
1073
+ },
1074
+ ...{
1075
+ /**
1076
+ * The field that failed validation.
1077
+ */
1078
+ field: 'name' | 'email' | 'phone';
1079
+ /**
1080
+ * Human-readable validation message for this field.
1081
+ */
1082
+ message: string;
1083
+ }[],
1084
+ ];
1085
+ /**
1086
+ * Human-readable summary suitable for a form-level error line.
1087
+ */
1088
+ message: string;
1089
+ };
1090
+ };
1091
+ /**
1092
+ * Unix epoch milliseconds when the event was emitted.
1093
+ */
1094
+ timestamp?: number;
1095
+ }
1096
+
1097
+ // ── from events/identity-intake-required.schema.json ──
1098
+ /**
1099
+ * Event: `identity_intake_required`. Emitted mid-turn when the agent requests structured identity/lead intake (name / email / phone) and the session declared the `identity_form` capability at `create_conversation_session`. The turn is parked until the client replies with a `submit_identity_intake` action carrying the same `requestId` (values or `declined: true`). Sessions that did not declare `identity_form` never receive this event — the server degrades to conversational, turn-by-turn collection instead.
1100
+ */
1101
+ export interface IdentityIntakeRequired {
1102
+ /**
1103
+ * Event type discriminator.
1104
+ */
1105
+ type: 'identity_intake_required';
1106
+ /**
1107
+ * Echoes the `requestId` from the originating `send_message` action. Must be included in the `submit_identity_intake` reply.
1108
+ */
1109
+ requestId?: string;
1110
+ /**
1111
+ * Intake prompt details.
1112
+ */
1113
+ data: {
1114
+ /**
1115
+ * The request ID this intake belongs to.
1116
+ */
1117
+ requestId: string;
1118
+ /**
1119
+ * The fields the agent wants and why.
1120
+ */
1121
+ data: {
1122
+ /**
1123
+ * The identity fields to collect, in display order.
1124
+ *
1125
+ * @minItems 1
1126
+ */
1127
+ fields: [
1128
+ {
1129
+ /**
1130
+ * Which identity field to collect.
1131
+ */
1132
+ key: 'name' | 'email' | 'phone';
1133
+ /**
1134
+ * Whether the visitor must provide this field to submit.
1135
+ */
1136
+ required: boolean;
1137
+ /**
1138
+ * Optional display label overriding the client's default for this field.
1139
+ */
1140
+ label?: string;
1141
+ },
1142
+ ...{
1143
+ /**
1144
+ * Which identity field to collect.
1145
+ */
1146
+ key: 'name' | 'email' | 'phone';
1147
+ /**
1148
+ * Whether the visitor must provide this field to submit.
1149
+ */
1150
+ required: boolean;
1151
+ /**
1152
+ * Optional display label overriding the client's default for this field.
1153
+ */
1154
+ label?: string;
1155
+ }[],
1156
+ ];
1157
+ /**
1158
+ * Human-readable reason the agent needs these details, suitable for the form header (e.g. `to send you the quote`).
1159
+ */
1160
+ reason: string;
1161
+ };
1162
+ };
1163
+ /**
1164
+ * Unix epoch milliseconds when the event was emitted.
1165
+ */
1166
+ timestamp?: number;
1167
+ }
1168
+
955
1169
  // ── from events/immediate-response.schema.json ──
956
1170
  /**
957
1171
  * Event: `immediate_response`. Sent by the server synchronously upon receiving any action, to acknowledge that the request was accepted and processing has begun. For streaming actions (`send_message`) this always precedes `stream_chunk` / `stream_token` events and the final `eventual_response`. For non-streaming actions (e.g. `get_session`, `create_conversation_session`) this also carries the complete response payload in `data`.
@@ -1280,6 +1494,42 @@ export interface StreamChunk {
1280
1494
  timestamp?: number;
1281
1495
  }
1282
1496
 
1497
+ // ── from events/stream-reasoning.schema.json ──
1498
+ /**
1499
+ * Event: `stream_reasoning`. A single *reasoning* token from a reasoning-model's separate thinking channel (`reasoning_content`/`reasoning` deltas — e.g. DeepSeek, gpt-oss/harmony, MiniMax, GLM), forwarded to the client in real time. Corresponds to smooth-operator's `AgentEvent::ReasoningDelta`. Shaped identically to `stream_token` so clients can render it the same way, but on a distinct `type` so reasoning is shown as collapsible "thinking" and is NEVER folded into the answer. The final response (carried by `eventual_response`) already excludes reasoning. Clients that do not recognize this event MUST ignore it — the answer still streams via `stream_token`, so reasoning simply isn't shown.
1500
+ */
1501
+ export interface StreamReasoning {
1502
+ /**
1503
+ * Event type discriminator.
1504
+ */
1505
+ type: 'stream_reasoning';
1506
+ /**
1507
+ * Echoes the `requestId` from the originating `send_message` action.
1508
+ */
1509
+ requestId?: string;
1510
+ /**
1511
+ * The raw reasoning token text. Also present inside `data.token` for consumers that only inspect `data`.
1512
+ */
1513
+ token?: string;
1514
+ /**
1515
+ * Reasoning token event payload.
1516
+ */
1517
+ data: {
1518
+ /**
1519
+ * The request ID this reasoning token belongs to.
1520
+ */
1521
+ requestId: string;
1522
+ /**
1523
+ * The raw reasoning token text.
1524
+ */
1525
+ token: string;
1526
+ };
1527
+ /**
1528
+ * Unix epoch milliseconds when the event was emitted.
1529
+ */
1530
+ timestamp?: number;
1531
+ }
1532
+
1283
1533
  // ── from events/stream-token.schema.json ──
1284
1534
  /**
1285
1535
  * Event: `stream_token`. A single LLM output token forwarded to the client in real time. Corresponds to smooth-operator's `AgentEvent::TokenDelta`. Clients accumulate tokens to display a live typing animation. After the node finishes, a `stream_chunk` event carries the complete state snapshot for that node.
package/src/types.ts CHANGED
@@ -21,6 +21,8 @@ import type {
21
21
  GetMessagesResponse,
22
22
  GetSessionRequest,
23
23
  GetSessionResponse,
24
+ IdentityIntakeInvalid,
25
+ IdentityIntakeRequired,
24
26
  ImmediateResponse,
25
27
  Keepalive,
26
28
  OtpInvalid,
@@ -33,6 +35,7 @@ import type {
33
35
  SendMessageResponse,
34
36
  StreamChunk,
35
37
  StreamToken,
38
+ SubmitIdentityIntakeRequest,
36
39
  VerifyOtpRequest,
37
40
  WriteConfirmationRequired,
38
41
  } from './generated/types.js';
@@ -55,6 +58,7 @@ export const ACTION_TYPES = [
55
58
  'get_conversation_messages',
56
59
  'confirm_tool_action',
57
60
  'verify_otp',
61
+ 'submit_identity_intake',
58
62
  'ping',
59
63
  ] as const;
60
64
  export type ActionType = (typeof ACTION_TYPES)[number];
@@ -71,6 +75,8 @@ export const EVENT_TYPES = [
71
75
  'otp_sent',
72
76
  'otp_verified',
73
77
  'otp_invalid',
78
+ 'identity_intake_required',
79
+ 'identity_intake_invalid',
74
80
  'error',
75
81
  'pong',
76
82
  ] as const;
@@ -89,6 +95,7 @@ export type ClientAction =
89
95
  | GetMessagesRequest
90
96
  | ConfirmToolActionRequest
91
97
  | VerifyOtpRequest
98
+ | SubmitIdentityIntakeRequest
92
99
  | PingRequest;
93
100
 
94
101
  // ───────────────────────────── Server events ───────────────────────────────
@@ -108,6 +115,8 @@ export type ServerEvent =
108
115
  | OtpSent
109
116
  | OtpVerified
110
117
  | OtpInvalid
118
+ | IdentityIntakeRequired
119
+ | IdentityIntakeInvalid
111
120
  | GeneratedErrorEvent
112
121
  | Pong;
113
122
 
@@ -125,6 +134,8 @@ export interface ServerEventByType {
125
134
  otp_sent: OtpSent;
126
135
  otp_verified: OtpVerified;
127
136
  otp_invalid: OtpInvalid;
137
+ identity_intake_required: IdentityIntakeRequired;
138
+ identity_intake_invalid: IdentityIntakeInvalid;
128
139
  error: GeneratedErrorEvent;
129
140
  pong: Pong;
130
141
  }
@@ -137,6 +148,7 @@ export interface ClientActionByType {
137
148
  get_conversation_messages: GetMessagesRequest;
138
149
  confirm_tool_action: ConfirmToolActionRequest;
139
150
  verify_otp: VerifyOtpRequest;
151
+ submit_identity_intake: SubmitIdentityIntakeRequest;
140
152
  ping: PingRequest;
141
153
  }
142
154
 
package/src/validate.ts CHANGED
@@ -47,6 +47,8 @@ const EVENT_SCHEMA_FILE: Record<EventType, string> = {
47
47
  otp_sent: 'events/otp-sent.schema.json',
48
48
  otp_verified: 'events/otp-verified.schema.json',
49
49
  otp_invalid: 'events/otp-invalid.schema.json',
50
+ identity_intake_required: 'events/identity-intake-required.schema.json',
51
+ identity_intake_invalid: 'events/identity-intake-invalid.schema.json',
50
52
  error: 'events/error.schema.json',
51
53
  pong: 'events/pong.schema.json',
52
54
  };
@@ -59,6 +61,7 @@ const ACTION_SCHEMA_REF: Record<ActionType, string> = {
59
61
  get_conversation_messages: 'actions/get-messages.schema.json#/$defs/Request',
60
62
  confirm_tool_action: 'actions/confirm-tool-action.schema.json#/$defs/Request',
61
63
  verify_otp: 'actions/verify-otp.schema.json#/$defs/Request',
64
+ submit_identity_intake: 'actions/submit-identity-intake.schema.json#/$defs/Request',
62
65
  ping: 'actions/ping.schema.json#/$defs/Request',
63
66
  };
64
67