@proteos/sdk 0.18.1
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/LICENSE +40 -0
- package/dist/chunk-7RGN4E22.cjs +1185 -0
- package/dist/chunk-7RGN4E22.cjs.map +1 -0
- package/dist/chunk-XJP5WCRZ.js +1125 -0
- package/dist/chunk-XJP5WCRZ.js.map +1 -0
- package/dist/index.cjs +2384 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5225 -0
- package/dist/index.d.ts +5225 -0
- package/dist/index.js +2146 -0
- package/dist/index.js.map +1 -0
- package/dist/meta/index.cjs +204 -0
- package/dist/meta/index.cjs.map +1 -0
- package/dist/meta/index.d.cts +2 -0
- package/dist/meta/index.d.ts +2 -0
- package/dist/meta/index.js +3 -0
- package/dist/meta/index.js.map +1 -0
- package/dist/types-BNsjfU8N.d.cts +3299 -0
- package/dist/types-BNsjfU8N.d.ts +3299 -0
- package/package.json +86 -0
- package/src/agent/agents.ts +53 -0
- package/src/agent/index.ts +134 -0
- package/src/agent/mcp-servers.ts +102 -0
- package/src/agent/prompts.ts +80 -0
- package/src/agent/session-types.ts +397 -0
- package/src/agent/sessions.ts +197 -0
- package/src/agent/skills.ts +89 -0
- package/src/agent/tools.ts +53 -0
- package/src/agent/types.ts +362 -0
- package/src/auth/index.ts +111 -0
- package/src/auth/me.ts +46 -0
- package/src/auth/organizations.ts +128 -0
- package/src/auth/platform-entities.ts +78 -0
- package/src/auth/roles.ts +213 -0
- package/src/auth/types.ts +294 -0
- package/src/auth/users.ts +226 -0
- package/src/client.ts +441 -0
- package/src/connector/index.ts +120 -0
- package/src/connector/types.ts +150 -0
- package/src/conversation/index.ts +297 -0
- package/src/conversation/types.ts +590 -0
- package/src/conversation/voice.ts +123 -0
- package/src/data/index.ts +53 -0
- package/src/data/queries.ts +66 -0
- package/src/data/records.ts +122 -0
- package/src/data/types.ts +89 -0
- package/src/errors.ts +148 -0
- package/src/events/index.ts +172 -0
- package/src/events/types.ts +77 -0
- package/src/functions/actions.ts +95 -0
- package/src/functions/index.ts +32 -0
- package/src/functions/types.ts +71 -0
- package/src/http/index.ts +2 -0
- package/src/http/query-params.ts +106 -0
- package/src/index.ts +598 -0
- package/src/iterator.ts +183 -0
- package/src/knowledge/graph.ts +35 -0
- package/src/knowledge/index.ts +104 -0
- package/src/knowledge/labels.ts +70 -0
- package/src/knowledge/links.ts +65 -0
- package/src/knowledge/nodes.ts +198 -0
- package/src/knowledge/record-links.ts +66 -0
- package/src/knowledge/types.ts +569 -0
- package/src/meta/apps.ts +107 -0
- package/src/meta/components.ts +124 -0
- package/src/meta/currency/index.ts +202 -0
- package/src/meta/entities.ts +193 -0
- package/src/meta/filters.ts +76 -0
- package/src/meta/index.ts +227 -0
- package/src/meta/layout/common-props.ts +93 -0
- package/src/meta/layout/control-registry.json +70 -0
- package/src/meta/layout/control-registry.ts +92 -0
- package/src/meta/layout/elements.ts +203 -0
- package/src/meta/layout/index.ts +41 -0
- package/src/meta/layout/page-layout.ts +35 -0
- package/src/meta/layout/size-value.ts +27 -0
- package/src/meta/list-views.ts +109 -0
- package/src/meta/lists.ts +104 -0
- package/src/meta/menu-configurations.ts +128 -0
- package/src/meta/modules.ts +159 -0
- package/src/meta/pages.ts +106 -0
- package/src/meta/types.ts +1115 -0
- package/src/meta/variables.ts +98 -0
- package/src/storage/files.ts +183 -0
- package/src/storage/index.ts +33 -0
- package/src/storage/types.ts +70 -0
- package/src/types/common.ts +143 -0
- package/src/types/index.ts +28 -0
- package/src/types/options.ts +95 -0
- package/src/workflow/executions.ts +99 -0
- package/src/workflow/index.ts +109 -0
- package/src/workflow/node-types.ts +50 -0
- package/src/workflow/types.ts +658 -0
- package/src/workflow/workflows.ts +152 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types for conversation-service (/conversations/v1) — hand-maintained
|
|
3
|
+
* mirror of packages/go/model/conversation (snake_case, Is-prefixed booleans).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { FileRef } from '../types/common.js'
|
|
7
|
+
|
|
8
|
+
/** Platform medium a conversation lives on (closed enum; platform identity). */
|
|
9
|
+
export type Channel =
|
|
10
|
+
| 'slack'
|
|
11
|
+
| 'email'
|
|
12
|
+
| 'linkedin'
|
|
13
|
+
| 'sms'
|
|
14
|
+
| 'teams'
|
|
15
|
+
| 'telegram'
|
|
16
|
+
| 'whatsapp'
|
|
17
|
+
| 'meeting'
|
|
18
|
+
| 'adhoc'
|
|
19
|
+
| 'instagram'
|
|
20
|
+
| 'messenger'
|
|
21
|
+
| 'x'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Concrete integration serving a channel (typed union — one value per shipped
|
|
25
|
+
* connector; runtime availability is decided by the service's registry).
|
|
26
|
+
* The unipile-* family serves the six messaging systems aggregated through
|
|
27
|
+
* Unipile — one key per messaging system.
|
|
28
|
+
*/
|
|
29
|
+
export type ConnectorKey =
|
|
30
|
+
| 'slack'
|
|
31
|
+
| 'gmail'
|
|
32
|
+
| 'echo'
|
|
33
|
+
| 'unipile-whatsapp'
|
|
34
|
+
| 'unipile-linkedin'
|
|
35
|
+
| 'unipile-telegram'
|
|
36
|
+
| 'unipile-instagram'
|
|
37
|
+
| 'unipile-messenger'
|
|
38
|
+
| 'unipile-x'
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Who operates the integration mechanics behind a connector: Proteos' own
|
|
42
|
+
* integration (native) or an account aggregated through Unipile (unipile).
|
|
43
|
+
* Computed on connection reads; the UI groups the connector catalog by it.
|
|
44
|
+
*/
|
|
45
|
+
export type ConnectorProvider = 'native' | 'unipile'
|
|
46
|
+
|
|
47
|
+
export type MessageDirection = 'inbound' | 'outbound'
|
|
48
|
+
export type MessageStatus = 'received' | 'pending' | 'sent' | 'failed'
|
|
49
|
+
export type ConnectionScope = 'org' | 'user'
|
|
50
|
+
export type ConnectionStatus = 'pending' | 'active' | 'error' | 'revoked'
|
|
51
|
+
export type ConversationStatus = 'active' | 'ended' | 'archived'
|
|
52
|
+
export type AgentListenerTriggerType = 'always' | 'mention' | 'channel' | 'keyword'
|
|
53
|
+
|
|
54
|
+
export interface UserRef {
|
|
55
|
+
type: string
|
|
56
|
+
id: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Inline snapshot of a person on a message/reaction — the integration-side
|
|
61
|
+
* identity plus, when resolved via email match, the platform user.
|
|
62
|
+
*/
|
|
63
|
+
export interface ParticipantRef {
|
|
64
|
+
external_id?: string
|
|
65
|
+
name: string
|
|
66
|
+
email?: string
|
|
67
|
+
/** Resolved platform identity (email match); absent when unresolved. */
|
|
68
|
+
platform_user?: UserRef
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* One member of a conversation's roster — everyone in the thread, INCLUDING the
|
|
73
|
+
* connected account itself. The account's own entries carry is_self=true; a UI
|
|
74
|
+
* renders "who it's with" as the non-self subset (1 → single avatar, ≥2 →
|
|
75
|
+
* stacked).
|
|
76
|
+
*/
|
|
77
|
+
export interface ConversationParticipant extends ParticipantRef {
|
|
78
|
+
is_self: boolean
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** How a MessageRecipient was addressed: primary, carbon copy, blind copy. */
|
|
82
|
+
export type RecipientRole = 'to' | 'cc' | 'bcc'
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* One addressee of a message with the role it was addressed under. Bcc is only
|
|
86
|
+
* present on messages the platform itself sent (inbound bcc is SMTP-stripped).
|
|
87
|
+
*/
|
|
88
|
+
export interface MessageRecipient extends ParticipantRef {
|
|
89
|
+
role: RecipientRole
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* One unit of message content — what was SAID. Files a message CARRIED are
|
|
94
|
+
* NOT content: they are Attachment rows (Message.attachments).
|
|
95
|
+
*/
|
|
96
|
+
export interface ContentBlock {
|
|
97
|
+
type: 'text' | 'html'
|
|
98
|
+
text?: string
|
|
99
|
+
/**
|
|
100
|
+
* Sanitized rich email body (ingest-time allowlist: layout tables, inline
|
|
101
|
+
* styles, https images; no scripts/forms/handlers). Rides ALONGSIDE the
|
|
102
|
+
* canonical text block. Render only in an isolated, script-less surface.
|
|
103
|
+
*/
|
|
104
|
+
html?: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Secret material is redacted on every read ("********" when set). */
|
|
108
|
+
export interface ConnectionCredentials {
|
|
109
|
+
bot_token?: string
|
|
110
|
+
bot_user_id?: string
|
|
111
|
+
refresh_token?: string
|
|
112
|
+
access_token?: string
|
|
113
|
+
token_expires_at?: string
|
|
114
|
+
granted_scopes?: string
|
|
115
|
+
/** Aggregator-hosted account identity (unipile-*) — nothing secret. */
|
|
116
|
+
account_id?: string
|
|
117
|
+
owner_provider_id?: string
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** How a channel's reaction vocabulary is shaped. */
|
|
121
|
+
export type ReactionSetKind = 'open' | 'fixed'
|
|
122
|
+
|
|
123
|
+
/** One entry of a fixed reaction vocabulary (token = the value to send). */
|
|
124
|
+
export interface ReactionOption {
|
|
125
|
+
token: string
|
|
126
|
+
unicode?: string
|
|
127
|
+
label?: string
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* A connector's declarative reaction capability, projected onto the
|
|
132
|
+
* connection read: open → show an emoji picker; fixed → exactly the allowed
|
|
133
|
+
* buttons; absent (connection.reactions undefined) → no affordance.
|
|
134
|
+
*/
|
|
135
|
+
export interface ReactionCapability {
|
|
136
|
+
kind: ReactionSetKind
|
|
137
|
+
allowed?: ReactionOption[]
|
|
138
|
+
/** 0 = unbounded (Slack); 1 = single-slot (a new reaction replaces the old). */
|
|
139
|
+
max_per_actor: number
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface Connection {
|
|
143
|
+
id: string
|
|
144
|
+
org_id: string
|
|
145
|
+
connector_key: ConnectorKey
|
|
146
|
+
channel: Channel
|
|
147
|
+
name: string
|
|
148
|
+
scope: ConnectionScope
|
|
149
|
+
/** Set only when scope=user (the connecting user); absent for org-wide. */
|
|
150
|
+
owner?: UserRef
|
|
151
|
+
external_workspace_id: string
|
|
152
|
+
credentials: ConnectionCredentials
|
|
153
|
+
settings: Record<string, unknown>
|
|
154
|
+
status: ConnectionStatus
|
|
155
|
+
/** Computed on read: the connector implements the reaction capability. */
|
|
156
|
+
supports_reactions: boolean
|
|
157
|
+
/** The capability descriptor; absent when unsupported. */
|
|
158
|
+
reactions?: ReactionCapability
|
|
159
|
+
/**
|
|
160
|
+
* Computed on read like supports_reactions: who operates the integration
|
|
161
|
+
* (native | unipile). Absent when the connector is not registered in this
|
|
162
|
+
* environment.
|
|
163
|
+
*/
|
|
164
|
+
provider?: ConnectorProvider
|
|
165
|
+
created_at: string
|
|
166
|
+
created_by: UserRef
|
|
167
|
+
updated_at: string
|
|
168
|
+
updated_by: UserRef
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface Conversation {
|
|
172
|
+
id: string
|
|
173
|
+
org_id: string
|
|
174
|
+
connection_id: string
|
|
175
|
+
channel: Channel
|
|
176
|
+
external_conversation_id: string
|
|
177
|
+
subject: string
|
|
178
|
+
status: ConversationStatus
|
|
179
|
+
/**
|
|
180
|
+
* Room directory row a room-borne thread (Slack channel conversation) lives
|
|
181
|
+
* in; absent for DMs, email, meeting, adhoc.
|
|
182
|
+
*/
|
|
183
|
+
room_id?: string
|
|
184
|
+
/**
|
|
185
|
+
* Main conversation a child conversation forked from (Slack: the channel's
|
|
186
|
+
* main conversation; provider-side the child is a native Slack thread);
|
|
187
|
+
* absent for main/DM/email/meeting/adhoc.
|
|
188
|
+
*/
|
|
189
|
+
parent_conversation_id?: string
|
|
190
|
+
/**
|
|
191
|
+
* Message id of the child conversation's root message, which lives in the
|
|
192
|
+
* parent conversation; absent when the root is unknown (predates ingest).
|
|
193
|
+
*/
|
|
194
|
+
started_by_message_id?: string
|
|
195
|
+
started_at?: string
|
|
196
|
+
ended_at?: string
|
|
197
|
+
/**
|
|
198
|
+
* The thread's complete roster — everyone in it, including the connected
|
|
199
|
+
* account (its own entries marked is_self). Deduped by external_id; the
|
|
200
|
+
* queryable person dimension. Replaces the old single `counterpart`.
|
|
201
|
+
*/
|
|
202
|
+
participants?: ConversationParticipant[]
|
|
203
|
+
last_message_at: string
|
|
204
|
+
metadata: Record<string, unknown>
|
|
205
|
+
/**
|
|
206
|
+
* Messages summary — present only when the list opted in via
|
|
207
|
+
* include: 'messages_summary'. Renders a hub stream row (root on Slack,
|
|
208
|
+
* latest on email, reply affordance) without a per-conversation fetch.
|
|
209
|
+
*/
|
|
210
|
+
root_message?: MessagePreview
|
|
211
|
+
latest_message?: MessagePreview
|
|
212
|
+
messages_total?: number
|
|
213
|
+
/** Up to 3 most recent distinct senders excluding the root sender. */
|
|
214
|
+
last_repliers?: ParticipantRef[]
|
|
215
|
+
/** Requesting user's read marker; absent = never opened. */
|
|
216
|
+
last_read_at?: string
|
|
217
|
+
/**
|
|
218
|
+
* Server-computed unread predicate for the requesting user: activity after
|
|
219
|
+
* the marker AND the latest message is inbound.
|
|
220
|
+
*/
|
|
221
|
+
is_unread: boolean
|
|
222
|
+
created_at: string
|
|
223
|
+
created_by: UserRef
|
|
224
|
+
updated_at: string
|
|
225
|
+
updated_by: UserRef
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Compact snapshot of one message riding on conversation reads
|
|
230
|
+
* (include: 'messages_summary'): enough for a stream row — who, the first
|
|
231
|
+
* ~500 chars of text, direction/status for outbound identity.
|
|
232
|
+
*/
|
|
233
|
+
export interface MessagePreview {
|
|
234
|
+
sender: ParticipantRef
|
|
235
|
+
text: string
|
|
236
|
+
direction: MessageDirection
|
|
237
|
+
status: MessageStatus
|
|
238
|
+
occurred_at: string
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Aggregated unread-conversation counts for the requesting user (unit:
|
|
243
|
+
* conversations, not messages) — the envelope total and per-channel badges.
|
|
244
|
+
*/
|
|
245
|
+
export interface UnreadCounts {
|
|
246
|
+
total: number
|
|
247
|
+
channels: Partial<Record<Channel, number>>
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* One file that arrived with a message. `file` is the platform FileRef —
|
|
252
|
+
* bytes live in storage-service; size and content type resolve from storage
|
|
253
|
+
* by id. content_id/is_inline carry the MIME inline-image semantics
|
|
254
|
+
* (cid: references in the html body vs user-facing downloads).
|
|
255
|
+
*/
|
|
256
|
+
export interface Attachment {
|
|
257
|
+
id: string
|
|
258
|
+
org_id: string
|
|
259
|
+
message_id: string
|
|
260
|
+
connection_id: string
|
|
261
|
+
file: FileRef
|
|
262
|
+
content_id?: string
|
|
263
|
+
is_inline: boolean
|
|
264
|
+
created_at: string
|
|
265
|
+
created_by: UserRef
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Aggregated reactions on a message: one entry per emoji (native token). */
|
|
269
|
+
export interface Reaction {
|
|
270
|
+
emoji: string
|
|
271
|
+
count: number
|
|
272
|
+
participants: ParticipantRef[]
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface Message {
|
|
276
|
+
id: string
|
|
277
|
+
org_id: string
|
|
278
|
+
conversation_id: string
|
|
279
|
+
connection_id: string
|
|
280
|
+
channel: Channel
|
|
281
|
+
direction: MessageDirection
|
|
282
|
+
external_message_id: string
|
|
283
|
+
sender: ParticipantRef
|
|
284
|
+
/** Who the message was addressed to (To/Cc/Bcc), each tagged with its role. */
|
|
285
|
+
recipients?: MessageRecipient[]
|
|
286
|
+
content: ContentBlock[]
|
|
287
|
+
status: MessageStatus
|
|
288
|
+
occurred_at: string
|
|
289
|
+
/** Read-time projection; absent/empty on channels without reactions. */
|
|
290
|
+
reactions?: Reaction[]
|
|
291
|
+
/** Read-time projection of the message's attachment rows; absent without files. */
|
|
292
|
+
attachments?: Attachment[]
|
|
293
|
+
/**
|
|
294
|
+
* Child-conversation projection (read-time, per-conversation lists): the
|
|
295
|
+
* conversation rooted at this message and its message count — the "N
|
|
296
|
+
* replies" affordance. Absent for messages no child conversation forked
|
|
297
|
+
* from.
|
|
298
|
+
*/
|
|
299
|
+
child_conversation_id?: string
|
|
300
|
+
child_messages_total?: number
|
|
301
|
+
metadata: Record<string, unknown>
|
|
302
|
+
error: string
|
|
303
|
+
created_at: string
|
|
304
|
+
created_by: UserRef
|
|
305
|
+
updated_at: string
|
|
306
|
+
updated_by: UserRef
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Per-trigger configuration, discriminated by the sibling trigger_type: channel
|
|
311
|
+
* carries external_channel_id, keyword carries phrases, always/mention carry
|
|
312
|
+
* neither. (Serialized as the bare variant; both fields optional here.)
|
|
313
|
+
*/
|
|
314
|
+
export interface AgentListenerTriggerConfig {
|
|
315
|
+
external_channel_id?: string
|
|
316
|
+
phrases?: string[]
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export interface AgentListener {
|
|
320
|
+
id: string
|
|
321
|
+
org_id: string
|
|
322
|
+
connection_id: string
|
|
323
|
+
conversation_id: string
|
|
324
|
+
name: string
|
|
325
|
+
agent_key: string
|
|
326
|
+
trigger_type: AgentListenerTriggerType
|
|
327
|
+
trigger_config: AgentListenerTriggerConfig
|
|
328
|
+
/** The user the dispatcher acts as when driving the agent. */
|
|
329
|
+
acting_user: UserRef
|
|
330
|
+
is_enabled: boolean
|
|
331
|
+
priority: number
|
|
332
|
+
created_at: string
|
|
333
|
+
created_by: UserRef
|
|
334
|
+
updated_at: string
|
|
335
|
+
updated_by: UserRef
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export interface CreateConnectionRequest {
|
|
339
|
+
connector_key: ConnectorKey
|
|
340
|
+
name: string
|
|
341
|
+
scope: ConnectionScope
|
|
342
|
+
settings?: Record<string, unknown>
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export interface UpdateConnectionRequest {
|
|
346
|
+
name?: string
|
|
347
|
+
settings?: Record<string, unknown>
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface InstallConnectionResponse {
|
|
351
|
+
authorization_url: string
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export interface SendMessageRequest {
|
|
355
|
+
/** Reply mode: send into this existing conversation. */
|
|
356
|
+
conversation_id?: string
|
|
357
|
+
/**
|
|
358
|
+
* Targeted reply: reply aimed at ONE message (mutually exclusive with the
|
|
359
|
+
* other modes). Slack starts/continues the child conversation rooted at
|
|
360
|
+
* that message (carrying parent_conversation_id/started_by_message_id —
|
|
361
|
+
* provider-side a native Slack thread); email replies in the same
|
|
362
|
+
* conversation with In-Reply-To anchored at the target; channels without
|
|
363
|
+
* message-targeted replies reject with `child_conversation_not_supported`.
|
|
364
|
+
*/
|
|
365
|
+
reply_to_message_id?: string
|
|
366
|
+
/** Originate mode (omit conversation_id): connection_id + at least one To are required. */
|
|
367
|
+
connection_id?: string
|
|
368
|
+
/**
|
|
369
|
+
* Primary destinations for originate: one room (Slack channel) OR one-or-more
|
|
370
|
+
* participants (email To, a Slack DM, or several users → a Slack MPIM).
|
|
371
|
+
*/
|
|
372
|
+
to?: SendRecipient[]
|
|
373
|
+
/** Carbon-copy participants (email only). */
|
|
374
|
+
cc?: SendRecipient[]
|
|
375
|
+
/** Blind-carbon-copy participants (email only). */
|
|
376
|
+
bcc?: SendRecipient[]
|
|
377
|
+
/** Optional subject, used by email when originating. */
|
|
378
|
+
subject?: string
|
|
379
|
+
/** May be empty when attachments are present. */
|
|
380
|
+
content: ContentBlock[]
|
|
381
|
+
/**
|
|
382
|
+
* Files to send with the message. Pre-upload each file to storage-service
|
|
383
|
+
* and reference it here ({id, name}); the server downloads the bytes and
|
|
384
|
+
* hands them to the channel connector (Slack: one native message with the
|
|
385
|
+
* text as its comment; Gmail: multipart/mixed mail; ≤25MB per file, Slack
|
|
386
|
+
* ≤10 files per message). Channels without file support reject with
|
|
387
|
+
* `unsupported_content`.
|
|
388
|
+
*/
|
|
389
|
+
attachments?: FileRef[]
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export interface CreateAgentListenerRequest {
|
|
393
|
+
connection_id?: string
|
|
394
|
+
conversation_id?: string
|
|
395
|
+
name: string
|
|
396
|
+
agent_key: string
|
|
397
|
+
trigger_type: AgentListenerTriggerType
|
|
398
|
+
trigger_config?: AgentListenerTriggerConfig
|
|
399
|
+
/** A bare user id; the service wraps it into a person UserRef. */
|
|
400
|
+
acting_user_id: string
|
|
401
|
+
/** Omit to default to enabled. */
|
|
402
|
+
is_enabled?: boolean
|
|
403
|
+
priority?: number
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export interface UpdateAgentListenerRequest {
|
|
407
|
+
name?: string
|
|
408
|
+
agent_key?: string
|
|
409
|
+
trigger_type?: AgentListenerTriggerType
|
|
410
|
+
trigger_config?: AgentListenerTriggerConfig
|
|
411
|
+
acting_user_id?: string
|
|
412
|
+
is_enabled?: boolean
|
|
413
|
+
priority?: number
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export interface PaginationQuery {
|
|
417
|
+
page?: number
|
|
418
|
+
page_size?: number
|
|
419
|
+
sort_by?: string
|
|
420
|
+
sort_direction?: 'asc' | 'desc'
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export interface ListConnectionsQuery extends PaginationQuery {
|
|
424
|
+
connector_key?: string
|
|
425
|
+
channel?: string
|
|
426
|
+
scope?: string
|
|
427
|
+
status?: string
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
export interface ListConversationsQuery extends PaginationQuery {
|
|
431
|
+
channel?: string
|
|
432
|
+
status?: string
|
|
433
|
+
connection_id?: string
|
|
434
|
+
/** Conversations of one room (Slack channel) — the room stream. */
|
|
435
|
+
room_id?: string
|
|
436
|
+
/** Child conversations forked from one main conversation. */
|
|
437
|
+
parent_conversation_id?: string
|
|
438
|
+
/** Threads whose roster contains this external party — the person stream. */
|
|
439
|
+
participant_external_id?: string
|
|
440
|
+
/** Opt into the root/latest message projection on each row. */
|
|
441
|
+
include?: 'messages_summary'
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export interface ListMessagesQuery extends PaginationQuery {
|
|
445
|
+
direction?: string
|
|
446
|
+
status?: string
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
export interface ListAgentListenersQuery extends PaginationQuery {
|
|
450
|
+
connection_id?: string
|
|
451
|
+
conversation_id?: string
|
|
452
|
+
agent_key?: string
|
|
453
|
+
is_enabled?: boolean
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** Discriminates a send target: a person or a venue. */
|
|
457
|
+
export type RecipientKind = 'participant' | 'room'
|
|
458
|
+
export type ParticipantSource = 'sync' | 'ingest'
|
|
459
|
+
export type RoomSource = 'sync' | 'ingest'
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Send-time addressing VO: who/where an originated message goes. Points at a
|
|
463
|
+
* Participant or a Room by kind + external id (never a stored entity itself).
|
|
464
|
+
*/
|
|
465
|
+
export interface SendRecipient {
|
|
466
|
+
kind: RecipientKind
|
|
467
|
+
/** The connector-side id: a room's (Slack channel id) or a participant's (Slack user id, email address). */
|
|
468
|
+
external_id: string
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/** A PERSON known on a connection (directory row; resolvable to a platform user). */
|
|
472
|
+
export interface Participant {
|
|
473
|
+
id: string
|
|
474
|
+
org_id: string
|
|
475
|
+
connection_id: string
|
|
476
|
+
/** Slack user id / email address — the id to DM or email. */
|
|
477
|
+
external_id: string
|
|
478
|
+
name: string
|
|
479
|
+
email?: string
|
|
480
|
+
/** Resolved platform identity (email match); absent when unresolved. */
|
|
481
|
+
platform_user?: UserRef
|
|
482
|
+
metadata: Record<string, unknown>
|
|
483
|
+
source: ParticipantSource
|
|
484
|
+
last_seen_at: string
|
|
485
|
+
created_at: string
|
|
486
|
+
created_by: UserRef
|
|
487
|
+
updated_at: string
|
|
488
|
+
updated_by: UserRef
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/** An addressable VENUE on a connection (Slack channel; later meeting rooms). */
|
|
492
|
+
export interface Room {
|
|
493
|
+
id: string
|
|
494
|
+
org_id: string
|
|
495
|
+
connection_id: string
|
|
496
|
+
/** Slack channel id — the id to post into. */
|
|
497
|
+
external_id: string
|
|
498
|
+
name: string
|
|
499
|
+
metadata: Record<string, unknown>
|
|
500
|
+
/** How the row was populated: a directory sweep or minted at ingest. */
|
|
501
|
+
source: RoomSource
|
|
502
|
+
last_seen_at: string
|
|
503
|
+
created_at: string
|
|
504
|
+
created_by: UserRef
|
|
505
|
+
updated_at: string
|
|
506
|
+
updated_by: UserRef
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
export interface ListParticipantsQuery extends PaginationQuery {
|
|
510
|
+
/** Free-text needle matched against display name + external id. */
|
|
511
|
+
q?: string
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export interface ListRoomsQuery extends PaginationQuery {
|
|
515
|
+
/** Free-text needle matched against name + external id. */
|
|
516
|
+
q?: string
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export interface AddReactionRequest {
|
|
520
|
+
/** Connector-native token (Slack shortcode like "thumbsup"). */
|
|
521
|
+
emoji: string
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export interface ListReactionsResponse {
|
|
525
|
+
data: Reaction[]
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export interface ResponseMeta {
|
|
529
|
+
page: number
|
|
530
|
+
page_size: number
|
|
531
|
+
items_total: number
|
|
532
|
+
pages_total: number
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
export interface ListResponse<T> {
|
|
536
|
+
meta: ResponseMeta
|
|
537
|
+
data: T[]
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export type TranscriptionStatus = 'pending' | 'processing' | 'completed' | 'failed'
|
|
541
|
+
|
|
542
|
+
export interface TranscriptTurn {
|
|
543
|
+
speaker: number
|
|
544
|
+
speaker_label: string
|
|
545
|
+
text: string
|
|
546
|
+
start_ms: number
|
|
547
|
+
end_ms: number
|
|
548
|
+
confidence: number
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export interface Transcription {
|
|
552
|
+
id: string
|
|
553
|
+
org_id: string
|
|
554
|
+
source_file_id: string
|
|
555
|
+
audio_file_id: string
|
|
556
|
+
transcript_file_id: string
|
|
557
|
+
status: TranscriptionStatus
|
|
558
|
+
language: string
|
|
559
|
+
duration_seconds: number
|
|
560
|
+
model: string
|
|
561
|
+
is_diarized: boolean
|
|
562
|
+
turns: TranscriptTurn[]
|
|
563
|
+
speaker_count: number
|
|
564
|
+
provider_request_id: string
|
|
565
|
+
conversation_id: string
|
|
566
|
+
error: string
|
|
567
|
+
created_at: string
|
|
568
|
+
created_by: UserRef
|
|
569
|
+
updated_at: string
|
|
570
|
+
updated_by: UserRef
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export interface CreateTranscriptionRequest {
|
|
574
|
+
file_id: string
|
|
575
|
+
language?: string
|
|
576
|
+
model?: string
|
|
577
|
+
is_diarized?: boolean
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/** Channel defaults to adhoc; meeting is the only other allowed target. */
|
|
581
|
+
export interface MaterializeTranscriptionRequest {
|
|
582
|
+
channel?: Channel
|
|
583
|
+
subject?: string
|
|
584
|
+
/** Maps diarized speaker indexes ("0", "1", …) to display names. */
|
|
585
|
+
speaker_names?: Record<string, string>
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export interface ListTranscriptionsQuery extends PaginationQuery {
|
|
589
|
+
status?: string
|
|
590
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { ProteosClient } from '../client.js'
|
|
2
|
+
|
|
3
|
+
const VOICE_BASE_PATH = '/conversations/v1/voice'
|
|
4
|
+
|
|
5
|
+
/** One normalized transcription update streamed back from the server. */
|
|
6
|
+
export interface TranscriptResult {
|
|
7
|
+
/** The recognized text for this segment. */
|
|
8
|
+
transcript: string
|
|
9
|
+
/** True once this segment is final and will not change. */
|
|
10
|
+
is_final: boolean
|
|
11
|
+
/** True when the server detected end-of-speech (a natural pause). */
|
|
12
|
+
speech_final: boolean
|
|
13
|
+
/** Recognition confidence, 0–1. */
|
|
14
|
+
confidence: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Options for opening a live transcription stream. */
|
|
18
|
+
export interface TranscribeStreamOptions {
|
|
19
|
+
/** BCP-47 language code (e.g. `en`, `de`). Defaults to the server's default. */
|
|
20
|
+
language?: string
|
|
21
|
+
/** Stream interim (non-final) results as audio arrives. Defaults to `true`. */
|
|
22
|
+
interimResults?: boolean
|
|
23
|
+
/** Add punctuation to results. Defaults to `true`. */
|
|
24
|
+
punctuate?: boolean
|
|
25
|
+
/** Format entities (numbers, dates…) in results. Defaults to `true`. */
|
|
26
|
+
smartFormat?: boolean
|
|
27
|
+
/**
|
|
28
|
+
* Raw audio encoding (e.g. `linear16`). Omit for containerized audio
|
|
29
|
+
* (WebM/Opus from MediaRecorder), which the server auto-detects.
|
|
30
|
+
*/
|
|
31
|
+
encoding?: string
|
|
32
|
+
/** Sample rate in Hz. Required only when `encoding` is set. */
|
|
33
|
+
sampleRate?: number
|
|
34
|
+
/** Called for each transcription result. */
|
|
35
|
+
onResult: (result: TranscriptResult) => void
|
|
36
|
+
/** Called if the stream errors. */
|
|
37
|
+
onError?: (error: Event) => void
|
|
38
|
+
/** Called when the stream closes (either side). */
|
|
39
|
+
onClose?: () => void
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A live transcription session: push audio in, results arrive via `onResult`. */
|
|
43
|
+
export interface VoiceTranscriptionStream {
|
|
44
|
+
/** Forward one audio chunk (binary) to the server. */
|
|
45
|
+
sendAudio(chunk: Blob | ArrayBufferView | ArrayBuffer): void
|
|
46
|
+
/** Ask the server to flush pending results without closing the stream. */
|
|
47
|
+
finalize(): void
|
|
48
|
+
/** Close the stream. */
|
|
49
|
+
close(): void
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Service for realtime speech-to-text on conversation-service.
|
|
54
|
+
*
|
|
55
|
+
* Transcription is a WebSocket: open a stream, push audio chunks, and receive
|
|
56
|
+
* {@link TranscriptResult}s. The transcription provider is a server-side concern
|
|
57
|
+
* and is not exposed here.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const stream = await agent.voice.transcribeStream({
|
|
62
|
+
* onResult: (r) => console.log(r.transcript, r.is_final),
|
|
63
|
+
* });
|
|
64
|
+
* recorder.ondataavailable = (e) => stream.sendAudio(e.data);
|
|
65
|
+
* // …later: stream.finalize(); stream.close();
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export interface VoiceService {
|
|
69
|
+
/**
|
|
70
|
+
* Opens a live transcription stream and resolves once it is connected.
|
|
71
|
+
*
|
|
72
|
+
* @param options - Stream configuration and result/lifecycle callbacks
|
|
73
|
+
* @returns A handle to push audio and control the stream
|
|
74
|
+
*/
|
|
75
|
+
transcribeStream(options: TranscribeStreamOptions): Promise<VoiceTranscriptionStream>
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export class VoiceServiceImpl implements VoiceService {
|
|
79
|
+
constructor(private readonly client: ProteosClient) {}
|
|
80
|
+
|
|
81
|
+
async transcribeStream(options: TranscribeStreamOptions): Promise<VoiceTranscriptionStream> {
|
|
82
|
+
const query = buildQuery(options)
|
|
83
|
+
const socket = await this.client.openWebSocket(`${VOICE_BASE_PATH}/transcribe/stream${query}`)
|
|
84
|
+
socket.binaryType = 'arraybuffer'
|
|
85
|
+
|
|
86
|
+
socket.onmessage = (event: MessageEvent) => {
|
|
87
|
+
if (typeof event.data !== 'string') return
|
|
88
|
+
try {
|
|
89
|
+
options.onResult(JSON.parse(event.data) as TranscriptResult)
|
|
90
|
+
} catch {
|
|
91
|
+
// Ignore malformed frames.
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (options.onError) socket.onerror = options.onError
|
|
95
|
+
socket.onclose = () => options.onClose?.()
|
|
96
|
+
|
|
97
|
+
const isOpen = () => socket.readyState === WebSocket.OPEN
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
sendAudio: (chunk) => {
|
|
101
|
+
if (isOpen()) socket.send(chunk)
|
|
102
|
+
},
|
|
103
|
+
finalize: () => {
|
|
104
|
+
if (isOpen()) socket.send(JSON.stringify({ type: 'finalize' }))
|
|
105
|
+
},
|
|
106
|
+
close: () => socket.close(),
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Serializes options into the endpoint's query string (snake_case wire format). */
|
|
112
|
+
function buildQuery(options: TranscribeStreamOptions): string {
|
|
113
|
+
const params = new URLSearchParams()
|
|
114
|
+
if (options.language) params.set('language', options.language)
|
|
115
|
+
if (options.interimResults !== undefined)
|
|
116
|
+
params.set('interim_results', String(options.interimResults))
|
|
117
|
+
if (options.punctuate !== undefined) params.set('punctuate', String(options.punctuate))
|
|
118
|
+
if (options.smartFormat !== undefined) params.set('smart_format', String(options.smartFormat))
|
|
119
|
+
if (options.encoding) params.set('encoding', options.encoding)
|
|
120
|
+
if (options.sampleRate !== undefined) params.set('sample_rate', String(options.sampleRate))
|
|
121
|
+
const queryString = params.toString()
|
|
122
|
+
return queryString ? `?${queryString}` : ''
|
|
123
|
+
}
|