@proteos/sdk 0.57.1 → 0.59.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.
- package/dist/{chunk-2EB3P4AR.cjs → chunk-25PD6TYH.cjs} +4 -3
- package/dist/chunk-25PD6TYH.cjs.map +1 -0
- package/dist/{chunk-U3FT5KAH.js → chunk-OOOTPEJK.js} +4 -3
- package/dist/chunk-OOOTPEJK.js.map +1 -0
- package/dist/index.cjs +302 -121
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +639 -5
- package/dist/index.d.ts +639 -5
- package/dist/index.js +185 -4
- package/dist/index.js.map +1 -1
- package/dist/meta/index.cjs +89 -89
- package/dist/meta/index.d.cts +1 -1
- package/dist/meta/index.d.ts +1 -1
- package/dist/meta/index.js +1 -1
- package/dist/{types-mC4i_Wk3.d.cts → types-DQmqR_G8.d.cts} +8 -0
- package/dist/{types-mC4i_Wk3.d.ts → types-DQmqR_G8.d.ts} +8 -0
- package/package.json +3 -3
- package/src/auth/platform-entities.ts +27 -1
- package/src/auth/shares.ts +5 -4
- package/src/conversation/index.ts +286 -0
- package/src/conversation/types.ts +605 -2
- package/src/index.ts +36 -0
- package/src/meta/types.ts +6 -0
- package/dist/chunk-2EB3P4AR.cjs.map +0 -1
- package/dist/chunk-U3FT5KAH.js.map +0 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* mirror of packages/go/model/conversation (snake_case, Is-prefixed booleans).
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import type { PrincipalRef } from '../meta/types.js'
|
|
6
7
|
import type { FileRef } from '../types/common.js'
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -862,6 +863,579 @@ export interface ListConversationTypesQuery extends PaginationQuery {
|
|
|
862
863
|
module_slug?: string
|
|
863
864
|
}
|
|
864
865
|
|
|
866
|
+
// ---------------------------------------------------------------------------
|
|
867
|
+
// Conversation intelligence — tag definitions, tag sets, tags, evaluations.
|
|
868
|
+
// Hand-maintained mirror of conversation-tag-*.go + api/conversation-tag-*.go.
|
|
869
|
+
// ---------------------------------------------------------------------------
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Discriminates a tag definition's question (1:1 with the agent-service
|
|
873
|
+
* decision question types): boolean ("is this present?"), choice ("which
|
|
874
|
+
* one?"), score ("where on this ordered scale?").
|
|
875
|
+
*/
|
|
876
|
+
export type ConversationTagQuestionType = 'boolean' | 'choice' | 'score'
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* What a tag anchors to: the whole conversation (one value per conversation),
|
|
880
|
+
* one message (a verdict per message), or a span (character ranges inside a
|
|
881
|
+
* message, or message-to-message ranges). `span` REQUIRES evaluator kind
|
|
882
|
+
* `reason` — only a reasoning generation can localise verbatim quotes.
|
|
883
|
+
*/
|
|
884
|
+
export type ConversationTagScope = 'conversation' | 'message' | 'span'
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* The model path a definition is judged by: `decide` (agent-service's
|
|
888
|
+
* calibrated typed decision — probabilities, no prose, no localisation) or
|
|
889
|
+
* `reason` (a schema-constrained generation that returns rationale + verbatim
|
|
890
|
+
* anchors; required for span scope).
|
|
891
|
+
*/
|
|
892
|
+
export type ConversationTagEvaluatorKind = 'decide' | 'reason'
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* WHY an evaluation ran: `realtime` (the debounced window after new messages),
|
|
896
|
+
* `completion` (the conversation completed — final transcript + summary for
|
|
897
|
+
* spoken media, End for the rest) or `manual` (`conversationTags.evaluate`).
|
|
898
|
+
* A tag set's `evaluate_on` lists the automatic ones it subscribes to; manual
|
|
899
|
+
* ignores it.
|
|
900
|
+
*/
|
|
901
|
+
export type ConversationTagTrigger = 'realtime' | 'completion' | 'manual'
|
|
902
|
+
|
|
903
|
+
/** Who produced a tag: the evaluator (`model`) or a person (`user`). */
|
|
904
|
+
export type ConversationTagSource = 'model' | 'user'
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* `pending` = a provisional realtime observation on a spoken-medium
|
|
908
|
+
* conversation that is still live (a completion evaluation will replace it);
|
|
909
|
+
* `active` = current; `dismissed` = a person rejected it — kept as feedback
|
|
910
|
+
* and never re-created by a later evaluation.
|
|
911
|
+
*/
|
|
912
|
+
export type ConversationTagStatus = 'pending' | 'active' | 'dismissed'
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* One evaluation's lifecycle: `pending` (a manual evaluation was accepted and
|
|
916
|
+
* not yet started), `running`, `done`, `failed`.
|
|
917
|
+
*/
|
|
918
|
+
export type ConversationTagEvaluationStatus = 'pending' | 'running' | 'done' | 'failed'
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* Spells out what makes a boolean question hold (`true`) or not (`false`)
|
|
922
|
+
* when the boundary is subtle.
|
|
923
|
+
*/
|
|
924
|
+
export interface BooleanTagCriteria {
|
|
925
|
+
true: string
|
|
926
|
+
false: string
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* Populated per question type: boolean → `boolean` (optional, both
|
|
931
|
+
* descriptions or neither), choice → `choice` (option key → description,
|
|
932
|
+
* ≥ 2), score → `score` (ordered level descriptions, ≥ 2; the tag value is
|
|
933
|
+
* the 0-based level index). Descriptions are handed to the evaluator
|
|
934
|
+
* verbatim, so they should describe the observable content, not internal
|
|
935
|
+
* process.
|
|
936
|
+
*/
|
|
937
|
+
export interface ConversationTagCriteria {
|
|
938
|
+
boolean?: BooleanTagCriteria
|
|
939
|
+
choice?: Record<string, string>
|
|
940
|
+
score?: string[]
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* The decide-shaped question a definition asks over a conversation — the
|
|
945
|
+
* same three types as the agent-service decision question, with criteria in
|
|
946
|
+
* an explicit struct so manifests and SDKs need no tagged-union decoder.
|
|
947
|
+
* `type` is immutable after create: tag values are typed by it.
|
|
948
|
+
*/
|
|
949
|
+
export interface ConversationTagQuestion {
|
|
950
|
+
type: ConversationTagQuestionType
|
|
951
|
+
instructions: string
|
|
952
|
+
/** Always on the wire; pass `{}` for a boolean question without descriptions. */
|
|
953
|
+
criteria: ConversationTagCriteria
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Makes a `reason` definition ask the cheap decide model first whether it
|
|
958
|
+
* applies anywhere in the judged window (its own boolean question, one answer
|
|
959
|
+
* per window); only a definition that passes (probability ≥ `min_probability`)
|
|
960
|
+
* reaches the reasoning call, which is skipped entirely when nothing passes. A
|
|
961
|
+
* screened-out definition's stale tags are still replaced. Boolean questions
|
|
962
|
+
* only — choice and score always have an answer. Omitted = screening on with
|
|
963
|
+
* the service default threshold (0.3, `CONVERSATION_TAG_SCREENING_MIN_PROBABILITY`);
|
|
964
|
+
* `{ is_enabled: false }` turns it off. The service rejects `screening` on a
|
|
965
|
+
* `decide` evaluator or on a choice/score question, and a `min_probability`
|
|
966
|
+
* outside 0..1.
|
|
967
|
+
*/
|
|
968
|
+
export interface ConversationTagScreening {
|
|
969
|
+
is_enabled: boolean
|
|
970
|
+
/** Pass threshold in 0..1; absent = the service default. */
|
|
971
|
+
min_probability?: number
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Selects the model path. `model_id` is only meaningful for `reason` (absent =
|
|
976
|
+
* the service default); `decide` always uses the service-wide decision model.
|
|
977
|
+
* `screening` is only meaningful for `reason` with a boolean question; absent =
|
|
978
|
+
* screening on with the service default threshold.
|
|
979
|
+
*/
|
|
980
|
+
export interface ConversationTagEvaluator {
|
|
981
|
+
kind: ConversationTagEvaluatorKind
|
|
982
|
+
model_id?: string
|
|
983
|
+
screening?: ConversationTagScreening
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Describes WHAT to look for in a conversation: one typed question plus where
|
|
988
|
+
* its answers anchor (`scope`) and which model path answers it (`evaluator`).
|
|
989
|
+
* WHERE and WHEN a definition is evaluated is a ConversationTagSet's business
|
|
990
|
+
* — a definition that no enabled set references is never evaluated. Keyed
|
|
991
|
+
* (org_id, key) and module-deployable (conversation-tag-definitions/<key>.json),
|
|
992
|
+
* like conversation types.
|
|
993
|
+
*/
|
|
994
|
+
export interface ConversationTagDefinition {
|
|
995
|
+
org_id: string
|
|
996
|
+
/** Immutable identity within the org — the value every tag carries as `definition_key`. */
|
|
997
|
+
key: string
|
|
998
|
+
name: string
|
|
999
|
+
/** Free grouping for UIs ("content", "sentiment", "signal"). */
|
|
1000
|
+
group?: string
|
|
1001
|
+
question: ConversationTagQuestion
|
|
1002
|
+
/** `span` requires `evaluator.kind = 'reason'`. */
|
|
1003
|
+
scope: ConversationTagScope
|
|
1004
|
+
evaluator: ConversationTagEvaluator
|
|
1005
|
+
/**
|
|
1006
|
+
* Narrows message/span-scope judging to messages of these directions (e.g.
|
|
1007
|
+
* inbound only for customer sentiment); empty = all. Ignored for
|
|
1008
|
+
* conversation scope.
|
|
1009
|
+
*/
|
|
1010
|
+
directions: MessageDirection[]
|
|
1011
|
+
/**
|
|
1012
|
+
* Observations below it are dropped, for every question type — an absent
|
|
1013
|
+
* tag means "not determined", not "false".
|
|
1014
|
+
*/
|
|
1015
|
+
min_confidence: number
|
|
1016
|
+
/** Optional UI hint (any CSS color token the client accepts). */
|
|
1017
|
+
color?: string
|
|
1018
|
+
is_enabled: boolean
|
|
1019
|
+
/** Module that deployed the definition; absent when not module-owned. */
|
|
1020
|
+
module_slug?: string
|
|
1021
|
+
created_at: string
|
|
1022
|
+
created_by: UserRef
|
|
1023
|
+
updated_at: string
|
|
1024
|
+
updated_by: UserRef
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Describes WHERE and WHEN a group of tag definitions is evaluated. A
|
|
1029
|
+
* conversation matches a set when every NON-EMPTY selector contains it:
|
|
1030
|
+
* `channels`, `connection_ids`, `type_keys` (an empty conversation `type_key`
|
|
1031
|
+
* never matches a type-scoped set, so type-scoped sets only apply once a
|
|
1032
|
+
* conversation has been classified). At least one of those three must be
|
|
1033
|
+
* non-empty — tagging is opt-in, never org-wide by accident. `directions` is
|
|
1034
|
+
* a message-level filter on top (which messages arm / are judged), not a
|
|
1035
|
+
* conversation selector. Matched sets union their definition keys; timing
|
|
1036
|
+
* takes the minimum quiet window and max wait over the matched sets that
|
|
1037
|
+
* evaluate in realtime. Keyed (org_id, key) and module-deployable
|
|
1038
|
+
* (conversation-tag-sets/<key>.json).
|
|
1039
|
+
*/
|
|
1040
|
+
export interface ConversationTagSet {
|
|
1041
|
+
org_id: string
|
|
1042
|
+
key: string
|
|
1043
|
+
name: string
|
|
1044
|
+
/**
|
|
1045
|
+
* The definitions this set evaluates (≥ 1; each must exist in the org at
|
|
1046
|
+
* write time — a definition deleted later is skipped).
|
|
1047
|
+
*/
|
|
1048
|
+
definition_keys: string[]
|
|
1049
|
+
channels: Channel[]
|
|
1050
|
+
connection_ids: string[]
|
|
1051
|
+
type_keys: string[]
|
|
1052
|
+
/**
|
|
1053
|
+
* Narrows which NEW messages arm a realtime evaluation (and which messages a
|
|
1054
|
+
* completion evaluation judges for message/span scope): inbound only,
|
|
1055
|
+
* outbound only, or both when empty. A definition's own `directions`
|
|
1056
|
+
* narrows further.
|
|
1057
|
+
*/
|
|
1058
|
+
directions: MessageDirection[]
|
|
1059
|
+
/**
|
|
1060
|
+
* A non-empty subset of [realtime, completion]: realtime = the debounced
|
|
1061
|
+
* window after new messages arrive; completion = once the conversation
|
|
1062
|
+
* completed (final transcript + summary for spoken media, End for the
|
|
1063
|
+
* rest). Manual evaluations ignore it.
|
|
1064
|
+
*/
|
|
1065
|
+
evaluate_on: ConversationTagTrigger[]
|
|
1066
|
+
/** A realtime evaluation fires this long after the LAST new message (default 90, min 5). */
|
|
1067
|
+
quiet_window_seconds: number
|
|
1068
|
+
/**
|
|
1069
|
+
* Bounds the wait since the FIRST unjudged message (default 600, ≥ quiet
|
|
1070
|
+
* window) so a busy stream is still tagged periodically.
|
|
1071
|
+
*/
|
|
1072
|
+
max_wait_seconds: number
|
|
1073
|
+
is_enabled: boolean
|
|
1074
|
+
/** Module that deployed the set; absent when not module-owned. */
|
|
1075
|
+
module_slug?: string
|
|
1076
|
+
created_at: string
|
|
1077
|
+
created_by: UserRef
|
|
1078
|
+
updated_at: string
|
|
1079
|
+
updated_by: UserRef
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* One observation a definition made on a conversation.
|
|
1084
|
+
*
|
|
1085
|
+
* Anchors encode the definition's scope: conversation scope = every anchor
|
|
1086
|
+
* field absent; message scope = `start_message_id === end_message_id` with no
|
|
1087
|
+
* offsets; span = offsets set (a span may cross messages, then start/end
|
|
1088
|
+
* message ids differ). Offsets are UNICODE CODE POINT indexes into the
|
|
1089
|
+
* message's first text content block, end exclusive — JS strings are UTF-16,
|
|
1090
|
+
* so convert (e.g. via `Array.from(text)` / code-point iteration) before
|
|
1091
|
+
* slicing. `quote` (and `end_quote` for a span that continues into a later
|
|
1092
|
+
* message) is the verbatim text at the anchor: the reason evaluator emits
|
|
1093
|
+
* quotes because a model cannot count characters, the service resolves them
|
|
1094
|
+
* to offsets, and afterwards the quote is the evidence that survives a message
|
|
1095
|
+
* row change (the final transcript swaps realtime message ids; a term
|
|
1096
|
+
* correction edits text) — a tag whose anchors no longer resolve still shows
|
|
1097
|
+
* its quote and can be re-anchored by search.
|
|
1098
|
+
*
|
|
1099
|
+
* `value` is normalized per question type: `"true"` for a boolean (false is
|
|
1100
|
+
* never stored), the option key for a choice, the 0-based level index AS A
|
|
1101
|
+
* STRING for a score. Status `pending` marks a provisional realtime
|
|
1102
|
+
* observation on a live spoken-medium conversation; a completion evaluation
|
|
1103
|
+
* replaces it. Dismissed tags are feedback: a later evaluation never
|
|
1104
|
+
* re-creates a tag matching a dismissed one on (definition_key, value,
|
|
1105
|
+
* start/end message).
|
|
1106
|
+
*/
|
|
1107
|
+
export interface ConversationTag {
|
|
1108
|
+
id: string
|
|
1109
|
+
org_id: string
|
|
1110
|
+
conversation_id: string
|
|
1111
|
+
/**
|
|
1112
|
+
* Denormalized from the conversation so org-wide lists and counts group by
|
|
1113
|
+
* channel without a join.
|
|
1114
|
+
*/
|
|
1115
|
+
channel: Channel
|
|
1116
|
+
definition_key: string
|
|
1117
|
+
/** `"true"` | choice option key | score level index as a string. */
|
|
1118
|
+
value: string
|
|
1119
|
+
confidence: number
|
|
1120
|
+
/**
|
|
1121
|
+
* The raw decide distribution (`{"true":p,"false":1-p}`, option → p, or
|
|
1122
|
+
* `{"levels":[…],"mean":x}`); a screened reason tag carries
|
|
1123
|
+
* `{"screening":p}` instead; absent for unscreened reason and user tags.
|
|
1124
|
+
*/
|
|
1125
|
+
probabilities?: Record<string, unknown>
|
|
1126
|
+
/** The reason evaluator's one-line rationale; absent for decide. */
|
|
1127
|
+
why?: string
|
|
1128
|
+
source: ConversationTagSource
|
|
1129
|
+
status: ConversationTagStatus
|
|
1130
|
+
/** Links a model tag to the evaluation that produced it. */
|
|
1131
|
+
evaluation_id?: string
|
|
1132
|
+
start_message_id?: string
|
|
1133
|
+
/** Unicode code-point index, inclusive. */
|
|
1134
|
+
start_offset?: number
|
|
1135
|
+
end_message_id?: string
|
|
1136
|
+
/** Unicode code-point index, exclusive. */
|
|
1137
|
+
end_offset?: number
|
|
1138
|
+
start_occurred_at?: string
|
|
1139
|
+
end_occurred_at?: string
|
|
1140
|
+
quote?: string
|
|
1141
|
+
end_quote?: string
|
|
1142
|
+
/**
|
|
1143
|
+
* When the observed thing happened (the end message's `occurred_at`, else
|
|
1144
|
+
* the last message's) — the time-series axis.
|
|
1145
|
+
*/
|
|
1146
|
+
observed_at: string
|
|
1147
|
+
created_at: string
|
|
1148
|
+
created_by: UserRef
|
|
1149
|
+
updated_at: string
|
|
1150
|
+
updated_by: UserRef
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
/**
|
|
1154
|
+
* One row of `conversationTags.counts`: the grouped columns that were
|
|
1155
|
+
* requested plus the count.
|
|
1156
|
+
*/
|
|
1157
|
+
export interface ConversationTagCount {
|
|
1158
|
+
definition_key?: string
|
|
1159
|
+
value?: string
|
|
1160
|
+
channel?: Channel
|
|
1161
|
+
count: number
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* The model spend of one evaluation, summed over its decide and generate
|
|
1166
|
+
* calls.
|
|
1167
|
+
*/
|
|
1168
|
+
export interface ConversationTagUsage {
|
|
1169
|
+
input_tokens: number
|
|
1170
|
+
output_tokens: number
|
|
1171
|
+
request_count: number
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
/**
|
|
1175
|
+
* One screening verdict of an evaluation: the decide probability that the
|
|
1176
|
+
* definition applies in the judged window and whether that passed the
|
|
1177
|
+
* threshold. `probability` is absent (and `error` set) when the screening
|
|
1178
|
+
* could not be asked — it then passes, fail-open.
|
|
1179
|
+
*/
|
|
1180
|
+
export interface ConversationTagScreeningResult {
|
|
1181
|
+
definition_key: string
|
|
1182
|
+
probability?: number
|
|
1183
|
+
is_passed: boolean
|
|
1184
|
+
error?: string
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
/**
|
|
1188
|
+
* Records one time the tagger ran on a conversation: why (`trigger`), what it
|
|
1189
|
+
* judged (`definition_keys`, the message window), with which models, what it
|
|
1190
|
+
* cost, and how it ended. Model tags reference it through `evaluation_id`
|
|
1191
|
+
* (provenance), the UI polls it after a manual evaluate (202), and the latest
|
|
1192
|
+
* done realtime/completion evaluation's `window_end_occurred_at` is the
|
|
1193
|
+
* watermark the next realtime window starts after.
|
|
1194
|
+
*
|
|
1195
|
+
* Window = the messages JUDGED by this evaluation. realtime: everything after
|
|
1196
|
+
* the previous watermark (older messages ride along as context only);
|
|
1197
|
+
* completion/manual: all messages. Lifecycle: manual creates `pending` on the
|
|
1198
|
+
* 202 then flips to `running`; realtime/completion create `running` directly;
|
|
1199
|
+
* ends `done` or `failed`.
|
|
1200
|
+
*/
|
|
1201
|
+
export interface ConversationTagEvaluation {
|
|
1202
|
+
id: string
|
|
1203
|
+
org_id: string
|
|
1204
|
+
conversation_id: string
|
|
1205
|
+
trigger: ConversationTagTrigger
|
|
1206
|
+
status: ConversationTagEvaluationStatus
|
|
1207
|
+
definition_keys: string[]
|
|
1208
|
+
model_ids: string[]
|
|
1209
|
+
usage: ConversationTagUsage
|
|
1210
|
+
/**
|
|
1211
|
+
* The rendered state exceeded the cap and older context (or, for a huge
|
|
1212
|
+
* window, the newest window messages — deferred to the next evaluation) was
|
|
1213
|
+
* dropped.
|
|
1214
|
+
*/
|
|
1215
|
+
is_truncated: boolean
|
|
1216
|
+
window_start_occurred_at?: string
|
|
1217
|
+
window_end_occurred_at?: string
|
|
1218
|
+
window_message_ids: string[]
|
|
1219
|
+
/**
|
|
1220
|
+
* Every screened reason definition's verdict, so "why was nothing tagged"
|
|
1221
|
+
* is answerable and thresholds can be tuned. Empty when no definition was
|
|
1222
|
+
* screened.
|
|
1223
|
+
*/
|
|
1224
|
+
screenings: ConversationTagScreeningResult[]
|
|
1225
|
+
error?: string
|
|
1226
|
+
started_at: string
|
|
1227
|
+
finished_at?: string
|
|
1228
|
+
created_at: string
|
|
1229
|
+
created_by: UserRef
|
|
1230
|
+
updated_at: string
|
|
1231
|
+
updated_by: UserRef
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/**
|
|
1235
|
+
* The `conversation.tagged` event payload: the conversation, the evaluation
|
|
1236
|
+
* that landed, and every tag it produced (status pending or active — the
|
|
1237
|
+
* event header carries the status so a consumer can filter provisional
|
|
1238
|
+
* realtime observations without decoding).
|
|
1239
|
+
*/
|
|
1240
|
+
export interface ConversationTaggedEvent {
|
|
1241
|
+
conversation: Conversation
|
|
1242
|
+
evaluation: ConversationTagEvaluation
|
|
1243
|
+
tags: ConversationTag[]
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* Creates one tag definition. `key` is the immutable identity (kebab/snake,
|
|
1248
|
+
* like every platform key); `question` is the decide-shaped question the
|
|
1249
|
+
* evaluator answers; `scope` and `evaluator` say where answers anchor and
|
|
1250
|
+
* which model path answers (`span` requires `evaluator.kind = 'reason'`).
|
|
1251
|
+
* `is_enabled` omitted ⇒ true (manifests may omit it). `module_slug` is
|
|
1252
|
+
* stamped by `pro module deploy` — interactive callers leave it empty.
|
|
1253
|
+
*/
|
|
1254
|
+
export interface CreateConversationTagDefinitionRequest {
|
|
1255
|
+
key: string
|
|
1256
|
+
name?: string
|
|
1257
|
+
group?: string
|
|
1258
|
+
question: ConversationTagQuestion
|
|
1259
|
+
scope: ConversationTagScope
|
|
1260
|
+
evaluator: ConversationTagEvaluator
|
|
1261
|
+
directions?: MessageDirection[]
|
|
1262
|
+
/** 0..1 */
|
|
1263
|
+
min_confidence?: number
|
|
1264
|
+
color?: string
|
|
1265
|
+
is_enabled?: boolean
|
|
1266
|
+
module_slug?: string
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
/**
|
|
1270
|
+
* Partial update — an omitted field leaves the stored value untouched.
|
|
1271
|
+
* `question`, when present, replaces the stored question wholesale but must
|
|
1272
|
+
* keep its `type` (400 `conversation_tag_question_type_immutable` otherwise).
|
|
1273
|
+
* `directions` replaces wholesale. `key` is immutable.
|
|
1274
|
+
*/
|
|
1275
|
+
export interface UpdateConversationTagDefinitionRequest {
|
|
1276
|
+
name?: string
|
|
1277
|
+
group?: string
|
|
1278
|
+
question?: ConversationTagQuestion
|
|
1279
|
+
scope?: ConversationTagScope
|
|
1280
|
+
evaluator?: ConversationTagEvaluator
|
|
1281
|
+
directions?: MessageDirection[]
|
|
1282
|
+
/** 0..1 */
|
|
1283
|
+
min_confidence?: number
|
|
1284
|
+
color?: string
|
|
1285
|
+
is_enabled?: boolean
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
export interface ListConversationTagDefinitionsQuery extends PaginationQuery {
|
|
1289
|
+
/** Definitions deployed by one module — the `pro module` remote-state discovery door. */
|
|
1290
|
+
module_slug?: string
|
|
1291
|
+
/** Exact filter. */
|
|
1292
|
+
group?: string
|
|
1293
|
+
/** Exact filter. */
|
|
1294
|
+
scope?: string
|
|
1295
|
+
is_enabled?: boolean
|
|
1296
|
+
/** Case-insensitive substring match on key or name. */
|
|
1297
|
+
search?: string
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* Creates one tag set: which definitions to evaluate (`definition_keys`, ≥ 1,
|
|
1302
|
+
* each must exist), for which conversations (at least one of `channels` /
|
|
1303
|
+
* `connection_ids` / `type_keys` non-empty; `directions` additionally limits
|
|
1304
|
+
* which messages arm/are judged — empty = both), when (`evaluate_on` ⊆
|
|
1305
|
+
* [realtime, completion], ≥ 1) and the realtime timing (omitted ⇒ defaults:
|
|
1306
|
+
* quiet 90s, max wait 600s). `is_enabled` omitted ⇒ true. `module_slug` is
|
|
1307
|
+
* stamped by `pro module deploy`.
|
|
1308
|
+
*/
|
|
1309
|
+
export interface CreateConversationTagSetRequest {
|
|
1310
|
+
key: string
|
|
1311
|
+
name?: string
|
|
1312
|
+
definition_keys: string[]
|
|
1313
|
+
channels?: Channel[]
|
|
1314
|
+
connection_ids?: string[]
|
|
1315
|
+
type_keys?: string[]
|
|
1316
|
+
directions?: MessageDirection[]
|
|
1317
|
+
evaluate_on: ConversationTagTrigger[]
|
|
1318
|
+
quiet_window_seconds?: number
|
|
1319
|
+
max_wait_seconds?: number
|
|
1320
|
+
is_enabled?: boolean
|
|
1321
|
+
module_slug?: string
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
/**
|
|
1325
|
+
* Partial update — an omitted field leaves the stored value untouched; arrays
|
|
1326
|
+
* replace wholesale. `key` is immutable.
|
|
1327
|
+
*/
|
|
1328
|
+
export interface UpdateConversationTagSetRequest {
|
|
1329
|
+
name?: string
|
|
1330
|
+
definition_keys?: string[]
|
|
1331
|
+
channels?: Channel[]
|
|
1332
|
+
connection_ids?: string[]
|
|
1333
|
+
type_keys?: string[]
|
|
1334
|
+
directions?: MessageDirection[]
|
|
1335
|
+
evaluate_on?: ConversationTagTrigger[]
|
|
1336
|
+
quiet_window_seconds?: number
|
|
1337
|
+
max_wait_seconds?: number
|
|
1338
|
+
is_enabled?: boolean
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
export interface ListConversationTagSetsQuery extends PaginationQuery {
|
|
1342
|
+
/** Sets deployed by one module. */
|
|
1343
|
+
module_slug?: string
|
|
1344
|
+
/** Sets that reference the definition. */
|
|
1345
|
+
definition_key?: string
|
|
1346
|
+
is_enabled?: boolean
|
|
1347
|
+
/** Case-insensitive substring match on key or name. */
|
|
1348
|
+
search?: string
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* The manual door (`conversationTags.create`): a person tags a conversation,
|
|
1353
|
+
* a message or a span. Anchors follow the definition's scope (conversation:
|
|
1354
|
+
* none; message: start == end message, no offsets; span: UNICODE CODE POINT
|
|
1355
|
+
* offsets into the message's first text block, end exclusive — convert from
|
|
1356
|
+
* UTF-16 indexes before sending). The service stamps `source = 'user'`,
|
|
1357
|
+
* confidence 1, and fills `quote` from the anchored text.
|
|
1358
|
+
*/
|
|
1359
|
+
export interface CreateConversationTagRequest {
|
|
1360
|
+
definition_key: string
|
|
1361
|
+
/** `"true"` | choice option key | score level index as a string. */
|
|
1362
|
+
value: string
|
|
1363
|
+
why?: string
|
|
1364
|
+
start_message_id?: string
|
|
1365
|
+
/** Unicode code-point index, inclusive. */
|
|
1366
|
+
start_offset?: number
|
|
1367
|
+
end_message_id?: string
|
|
1368
|
+
/** Unicode code-point index, exclusive. */
|
|
1369
|
+
end_offset?: number
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
/**
|
|
1373
|
+
* Flips a tag between `active` and `dismissed` (the feedback loop) and lets a
|
|
1374
|
+
* person annotate why.
|
|
1375
|
+
*/
|
|
1376
|
+
export interface UpdateConversationTagRequest {
|
|
1377
|
+
status?: ConversationTagStatus
|
|
1378
|
+
why?: string
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
/**
|
|
1382
|
+
* Starts a manual evaluation (`conversationTags.evaluate`, 202). Omitted or
|
|
1383
|
+
* empty `definition_keys` = every definition the currently matching sets
|
|
1384
|
+
* reference (and every model tag on the conversation is replaced); a list
|
|
1385
|
+
* narrows both the questions and the replacement to those keys.
|
|
1386
|
+
*/
|
|
1387
|
+
export interface EvaluateConversationTagsRequest {
|
|
1388
|
+
definition_keys?: string[]
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
/**
|
|
1392
|
+
* Serves both `conversationTags.listByConversation` (the service forces
|
|
1393
|
+
* `conversation_id` from the path) and the org-wide `conversationTags.list`.
|
|
1394
|
+
*/
|
|
1395
|
+
export interface ListConversationTagsQuery extends PaginationQuery {
|
|
1396
|
+
conversation_id?: string
|
|
1397
|
+
definition_key?: string
|
|
1398
|
+
value?: string
|
|
1399
|
+
channel?: string
|
|
1400
|
+
source?: string
|
|
1401
|
+
status?: string
|
|
1402
|
+
/** Tags anchored on the message at either end. */
|
|
1403
|
+
message_id?: string
|
|
1404
|
+
/** Tags on conversations whose roster contains the contact. */
|
|
1405
|
+
contact_id?: string
|
|
1406
|
+
/** Lower bound on `observed_at` (inclusive), RFC 3339. */
|
|
1407
|
+
since?: string
|
|
1408
|
+
/** Upper bound on `observed_at` (exclusive), RFC 3339. */
|
|
1409
|
+
until?: string
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
/**
|
|
1413
|
+
* Groups active tags for dashboards. `group_by` is a COMMA-JOINED string
|
|
1414
|
+
* (`'definition_key,value'`) — not an array, because the query serializer
|
|
1415
|
+
* repeats array keys — whitelisted to definition_key, value, channel (order
|
|
1416
|
+
* kept).
|
|
1417
|
+
*/
|
|
1418
|
+
export interface CountConversationTagsQuery {
|
|
1419
|
+
group_by?: string
|
|
1420
|
+
definition_key?: string
|
|
1421
|
+
channel?: string
|
|
1422
|
+
source?: string
|
|
1423
|
+
status?: string
|
|
1424
|
+
/** Lower bound on `observed_at` (inclusive), RFC 3339. */
|
|
1425
|
+
since?: string
|
|
1426
|
+
/** Upper bound on `observed_at` (exclusive), RFC 3339. */
|
|
1427
|
+
until?: string
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
export interface CountConversationTagsResponse {
|
|
1431
|
+
data: ConversationTagCount[]
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
export interface ListConversationTagEvaluationsQuery extends PaginationQuery {
|
|
1435
|
+
trigger?: string
|
|
1436
|
+
status?: string
|
|
1437
|
+
}
|
|
1438
|
+
|
|
865
1439
|
/** Who assigned a contact's group membership. */
|
|
866
1440
|
export type ContactGroupSource = 'manual' | 'model'
|
|
867
1441
|
|
|
@@ -1039,6 +1613,11 @@ export interface ListConnectionsQuery extends PaginationQuery {
|
|
|
1039
1613
|
*/
|
|
1040
1614
|
owner_id?: string
|
|
1041
1615
|
status?: string
|
|
1616
|
+
/**
|
|
1617
|
+
* The caller's intent: `read` (default) lists every connection they reach;
|
|
1618
|
+
* `write` only those they may send through — the compose picker's question.
|
|
1619
|
+
*/
|
|
1620
|
+
permission?: 'read' | 'write'
|
|
1042
1621
|
}
|
|
1043
1622
|
|
|
1044
1623
|
/**
|
|
@@ -1079,6 +1658,13 @@ export interface ListConversationsQuery extends PaginationQuery {
|
|
|
1079
1658
|
sender_address_id?: string
|
|
1080
1659
|
/** Opt into the root/latest message projection on each row. */
|
|
1081
1660
|
include?: 'messages_summary'
|
|
1661
|
+
/**
|
|
1662
|
+
* Conversations carrying an ACTIVE conversation tag of this definition —
|
|
1663
|
+
* the "which conversations talk about billing" stream.
|
|
1664
|
+
*/
|
|
1665
|
+
tag_key?: string
|
|
1666
|
+
/** With `tag_key`: only conversations whose tag has this value. */
|
|
1667
|
+
tag_value?: string
|
|
1082
1668
|
}
|
|
1083
1669
|
|
|
1084
1670
|
/**
|
|
@@ -1136,7 +1722,13 @@ export type ConversationFilterType =
|
|
|
1136
1722
|
| 'internal_participant'
|
|
1137
1723
|
| 'internal_conversations'
|
|
1138
1724
|
| 'all'
|
|
1139
|
-
|
|
1725
|
+
/**
|
|
1726
|
+
* block drops the message; allow keeps it. restrict and share keep it too
|
|
1727
|
+
* (they rank as allow) and decide who sees the thread the message CREATES:
|
|
1728
|
+
* restrict writes only the rule's principals onto the new thread, share adds
|
|
1729
|
+
* them on top of what the thread inherits. Applied once, at creation.
|
|
1730
|
+
*/
|
|
1731
|
+
export type ConversationFilterAction = 'block' | 'allow' | 'restrict' | 'share'
|
|
1140
1732
|
/** Which side of the message address/domain rules test (default: sender). */
|
|
1141
1733
|
export type FilterMatchOn = 'sender' | 'any_participant'
|
|
1142
1734
|
/** Deterministic machine-mail header signals the automated filter matches. */
|
|
@@ -1203,7 +1795,11 @@ export interface ConversationFilter {
|
|
|
1203
1795
|
action: ConversationFilterAction
|
|
1204
1796
|
filter_config?: ConversationFilterConfig
|
|
1205
1797
|
is_enabled: boolean
|
|
1206
|
-
/**
|
|
1798
|
+
/** restrict / share only: who the created thread is opened to. */
|
|
1799
|
+
principals?: PrincipalRef[]
|
|
1800
|
+
/** restrict / share only: read or write (write implies read; the default). */
|
|
1801
|
+
permission?: 'read' | 'write'
|
|
1802
|
+
/** Read-only rollup: messages this rule matched in the last 30 days. */
|
|
1207
1803
|
recent_event_count?: number
|
|
1208
1804
|
created_at: string
|
|
1209
1805
|
created_by: UserRef
|
|
@@ -1222,6 +1818,8 @@ export interface ConversationFilterEvent {
|
|
|
1222
1818
|
sender_kind?: ContactAddressKind
|
|
1223
1819
|
sender_value?: string
|
|
1224
1820
|
external_message_id?: string
|
|
1821
|
+
/** The thread a restrict / share match applied to; empty on a drop. */
|
|
1822
|
+
conversation_id?: string
|
|
1225
1823
|
occurred_at: string
|
|
1226
1824
|
}
|
|
1227
1825
|
|
|
@@ -1231,6 +1829,9 @@ export interface CreateConversationFilterRequest {
|
|
|
1231
1829
|
action: ConversationFilterAction
|
|
1232
1830
|
filter_config?: Record<string, unknown>
|
|
1233
1831
|
is_enabled?: boolean
|
|
1832
|
+
/** Required for restrict / share, empty otherwise. */
|
|
1833
|
+
principals?: PrincipalRef[]
|
|
1834
|
+
permission?: 'read' | 'write'
|
|
1234
1835
|
/** Opts past the own-domain guard (self_domain_block). */
|
|
1235
1836
|
is_self_domain_acknowledged?: boolean
|
|
1236
1837
|
}
|
|
@@ -1241,6 +1842,8 @@ export interface UpdateConversationFilterRequest {
|
|
|
1241
1842
|
action?: ConversationFilterAction
|
|
1242
1843
|
filter_config?: Record<string, unknown>
|
|
1243
1844
|
is_enabled?: boolean
|
|
1845
|
+
principals?: PrincipalRef[]
|
|
1846
|
+
permission?: 'read' | 'write'
|
|
1244
1847
|
is_self_domain_acknowledged?: boolean
|
|
1245
1848
|
}
|
|
1246
1849
|
|