@channlize/core 0.2.1 → 0.5.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/CHANGELOG.md +46 -0
- package/README.md +316 -15
- package/dist/index.d.mts +1355 -19
- package/dist/index.d.ts +1355 -19
- package/dist/index.js +1152 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1114 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,1226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channlize for Agents: the JSON shapes of the `/v1/agents` API. They mirror
|
|
3
|
+
* the API's DTOs (`api/lib/agents/dto.ts`), so fields are `snake_case` as
|
|
4
|
+
* the API sends them. Request options are `camelCase`, like the rest of the
|
|
5
|
+
* SDK.
|
|
6
|
+
*/
|
|
7
|
+
/** An agent's lifecycle status. Only `active` agents can send. */
|
|
8
|
+
declare const AGENT_STATUSES: readonly ["active", "paused", "retired"];
|
|
9
|
+
type AgentStatus = (typeof AGENT_STATUSES)[number];
|
|
10
|
+
/** How channel messages reach an agent. */
|
|
11
|
+
declare const AGENT_DELIVERY_MODES: readonly ["webhook", "inbox", "a2a"];
|
|
12
|
+
type AgentDeliveryMode = (typeof AGENT_DELIVERY_MODES)[number];
|
|
13
|
+
/** Every message type a channel can hold. */
|
|
14
|
+
declare const AGENT_MESSAGE_TYPES: readonly ["message", "task", "question", "escalation", "status"];
|
|
15
|
+
type AgentMessageType = (typeof AGENT_MESSAGE_TYPES)[number];
|
|
16
|
+
/** The message types an agent can send (`agents.send`). */
|
|
17
|
+
declare const SENDABLE_AGENT_MESSAGE_TYPES: readonly ["message", "task", "status"];
|
|
18
|
+
type SendableAgentMessageType = (typeof SENDABLE_AGENT_MESSAGE_TYPES)[number];
|
|
19
|
+
/**
|
|
20
|
+
* A task's lifecycle. A `task` starts `open`; a `status` message moves it.
|
|
21
|
+
* `completed`, `failed`, `canceled` and `rejected` are final.
|
|
22
|
+
*/
|
|
23
|
+
declare const AGENT_TASK_STATUSES: readonly ["open", "working", "input_required", "completed", "failed", "canceled", "rejected"];
|
|
24
|
+
type AgentTaskStatus = (typeof AGENT_TASK_STATUSES)[number];
|
|
25
|
+
/** Agents are `member`s (post and read) or `observer`s (read); people are `supervisor`s. */
|
|
26
|
+
type AgentMemberRole = 'member' | 'observer' | 'supervisor';
|
|
27
|
+
/**
|
|
28
|
+
* Where one delivery stands: `inbox` (waiting to be pulled), `pending`
|
|
29
|
+
* (webhook or A2A push queued), `delivered`, `failed` (pushes gave up; still
|
|
30
|
+
* in the inbox), `held` (recipient paused), `pending_a2a`, `skipped`.
|
|
31
|
+
*/
|
|
32
|
+
type AgentDeliveryStatus = 'pending' | 'inbox' | 'delivered' | 'failed' | 'held' | 'pending_a2a' | 'skipped';
|
|
33
|
+
/** An agent of the directory (`GET /v1/agents`). Never carries its secret. */
|
|
34
|
+
interface Agent {
|
|
35
|
+
id: string;
|
|
36
|
+
slug: string;
|
|
37
|
+
name: string;
|
|
38
|
+
/** `webhook` (run by you) or `builtin` (run by Channlize). */
|
|
39
|
+
type: string;
|
|
40
|
+
delivery: AgentDeliveryMode;
|
|
41
|
+
status: AgentStatus;
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
avatar_url: string | null;
|
|
44
|
+
emoji: string | null;
|
|
45
|
+
role: string | null;
|
|
46
|
+
description: string | null;
|
|
47
|
+
owner_user_id: string | null;
|
|
48
|
+
manager_agent_id: string | null;
|
|
49
|
+
manager_user_id: string | null;
|
|
50
|
+
webhook_url: string | null;
|
|
51
|
+
a2a_agent_card_url: string | null;
|
|
52
|
+
a2a_agent_card: unknown;
|
|
53
|
+
a2a_agent_card_fetched_at: string | null;
|
|
54
|
+
has_secret: boolean;
|
|
55
|
+
last_seen_at: string | null;
|
|
56
|
+
created_at: string;
|
|
57
|
+
updated_at: string;
|
|
58
|
+
}
|
|
59
|
+
/** Slack mirroring of a channel. Default: everything on. */
|
|
60
|
+
interface AgentMirrorConfig {
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
types: Record<AgentMessageType, boolean>;
|
|
63
|
+
/** Each task (and its status updates) gets its own Slack thread. */
|
|
64
|
+
thread_per_task: boolean;
|
|
65
|
+
}
|
|
66
|
+
/** An agent channel. */
|
|
67
|
+
interface AgentChannel {
|
|
68
|
+
id: string;
|
|
69
|
+
slug: string;
|
|
70
|
+
name: string;
|
|
71
|
+
description: string | null;
|
|
72
|
+
slack_channel_id: string | null;
|
|
73
|
+
mirror: AgentMirrorConfig;
|
|
74
|
+
archived: boolean;
|
|
75
|
+
archived_at: string | null;
|
|
76
|
+
created_by: string | null;
|
|
77
|
+
created_at: string;
|
|
78
|
+
updated_at: string;
|
|
79
|
+
}
|
|
80
|
+
/** A channel member: an agent (`member` / `observer`) or a person (`supervisor`). */
|
|
81
|
+
interface AgentChannelMember {
|
|
82
|
+
id: string;
|
|
83
|
+
channel_id: string;
|
|
84
|
+
kind: 'agent' | 'user';
|
|
85
|
+
agent_id: string | null;
|
|
86
|
+
user_id: string | null;
|
|
87
|
+
role: AgentMemberRole;
|
|
88
|
+
name: string | null;
|
|
89
|
+
agent_slug?: string | null;
|
|
90
|
+
agent_status?: string | null;
|
|
91
|
+
user_email?: string | null;
|
|
92
|
+
created_at: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Who sent a message. `slack_user`: a person replying in Slack who isn't
|
|
96
|
+
* matched to a Channlize user. `deleted`: the sender no longer exists.
|
|
97
|
+
*/
|
|
98
|
+
type AgentMessageSender = {
|
|
99
|
+
kind: 'agent';
|
|
100
|
+
agent_id: string;
|
|
101
|
+
} | {
|
|
102
|
+
kind: 'user';
|
|
103
|
+
user_id: string;
|
|
104
|
+
} | {
|
|
105
|
+
kind: 'slack_user';
|
|
106
|
+
slack_user_id: string;
|
|
107
|
+
name: string;
|
|
108
|
+
} | {
|
|
109
|
+
kind: 'deleted';
|
|
110
|
+
};
|
|
111
|
+
/** A message in an agent channel. */
|
|
112
|
+
interface AgentMessage {
|
|
113
|
+
id: string;
|
|
114
|
+
/** Position in the channel feed. */
|
|
115
|
+
seq: string;
|
|
116
|
+
channel_id: string;
|
|
117
|
+
/** Root message of its thread; null on a root. */
|
|
118
|
+
thread_id: string | null;
|
|
119
|
+
sender: AgentMessageSender;
|
|
120
|
+
type: AgentMessageType;
|
|
121
|
+
text: string;
|
|
122
|
+
data: Record<string, unknown>;
|
|
123
|
+
/** Mentioned agent ids. */
|
|
124
|
+
mentions: string[];
|
|
125
|
+
/** On a `status` message: the task it updates. */
|
|
126
|
+
task_id: string | null;
|
|
127
|
+
/** On a `task`: its current status. On a `status` message: the status it reported. */
|
|
128
|
+
task_status: AgentTaskStatus | null;
|
|
129
|
+
tokens: number | null;
|
|
130
|
+
cost: number | null;
|
|
131
|
+
slack_ts: string | null;
|
|
132
|
+
a2a: {
|
|
133
|
+
context_id: string | null;
|
|
134
|
+
task_id: string | null;
|
|
135
|
+
message_id: string | null;
|
|
136
|
+
};
|
|
137
|
+
created_at: string;
|
|
138
|
+
}
|
|
139
|
+
/** One message for one recipient agent. */
|
|
140
|
+
interface AgentDelivery {
|
|
141
|
+
id: string;
|
|
142
|
+
message_id: string;
|
|
143
|
+
agent_id: string;
|
|
144
|
+
status: AgentDeliveryStatus;
|
|
145
|
+
attempts: number;
|
|
146
|
+
last_error: string | null;
|
|
147
|
+
delivered_at: string | null;
|
|
148
|
+
acked_at: string | null;
|
|
149
|
+
created_at: string;
|
|
150
|
+
}
|
|
151
|
+
/** `agents.send` input. */
|
|
152
|
+
interface SendAgentMessageInput {
|
|
153
|
+
/**
|
|
154
|
+
* The agent that sends. Required with a multi-agent key (unless it lists
|
|
155
|
+
* one agent); optional with an agent key. Defaults to the client's `agentId`.
|
|
156
|
+
*/
|
|
157
|
+
agentId?: string;
|
|
158
|
+
/** The channel id. The agent must be a `member` (observers can't post). */
|
|
159
|
+
channel: string;
|
|
160
|
+
/** Default `message`. A `task` starts `open`; a `status` updates `taskId`. */
|
|
161
|
+
type?: SendableAgentMessageType;
|
|
162
|
+
text: string;
|
|
163
|
+
/** Reply in this thread (any message of it). */
|
|
164
|
+
threadId?: string;
|
|
165
|
+
/** Agent ids to mention. */
|
|
166
|
+
mentions?: string[];
|
|
167
|
+
/** Structured data, stored and delivered with the message. */
|
|
168
|
+
data?: Record<string, unknown>;
|
|
169
|
+
/** Tokens the agent used for this message, for reporting. */
|
|
170
|
+
tokens?: number;
|
|
171
|
+
/** Cost the agent reports for this message, for reporting. */
|
|
172
|
+
cost?: number;
|
|
173
|
+
/** On a `status` message: the task to update. */
|
|
174
|
+
taskId?: string;
|
|
175
|
+
/** On a `status` message: the task's new status. */
|
|
176
|
+
taskStatus?: AgentTaskStatus;
|
|
177
|
+
}
|
|
178
|
+
/** `agents.send` result (`201`). */
|
|
179
|
+
interface SendAgentMessageResult {
|
|
180
|
+
message: AgentMessage;
|
|
181
|
+
/** One per recipient agent. */
|
|
182
|
+
deliveries: Array<{
|
|
183
|
+
id: string;
|
|
184
|
+
agent_id: string;
|
|
185
|
+
status: AgentDeliveryStatus;
|
|
186
|
+
}>;
|
|
187
|
+
}
|
|
188
|
+
/** One unacked message of an agent's inbox. */
|
|
189
|
+
interface AgentInboxItem {
|
|
190
|
+
delivery_id: string;
|
|
191
|
+
/** This item's position; pass it as `cursor` to read after it. */
|
|
192
|
+
cursor: string;
|
|
193
|
+
status: AgentDeliveryStatus;
|
|
194
|
+
attempts: number;
|
|
195
|
+
message: AgentMessage;
|
|
196
|
+
}
|
|
197
|
+
interface AgentInboxOptions {
|
|
198
|
+
/** Read after this cursor (`nextCursor` of the previous page). Default: the oldest unacked message. */
|
|
199
|
+
cursor?: string;
|
|
200
|
+
/** Page size (1-200, default 50). */
|
|
201
|
+
limit?: number;
|
|
202
|
+
}
|
|
203
|
+
/** `agents.inbox` result: unacked messages, oldest first. */
|
|
204
|
+
interface AgentInboxPage {
|
|
205
|
+
messages: AgentInboxItem[];
|
|
206
|
+
/** Pass as `cursor` for the next page; the same cursor when nothing is newer. */
|
|
207
|
+
nextCursor: string | null;
|
|
208
|
+
hasMore: boolean;
|
|
209
|
+
}
|
|
210
|
+
/** `agents.ack` input: everything up to and including one id, or a list of ids (delivery or message ids). */
|
|
211
|
+
type AgentAckInput = {
|
|
212
|
+
upTo: string;
|
|
213
|
+
} | {
|
|
214
|
+
ids: string[];
|
|
215
|
+
};
|
|
216
|
+
interface AgentAckResult {
|
|
217
|
+
/** How many were newly acked (acking twice is harmless). */
|
|
218
|
+
acked: number;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* `agents.get` result. An `agents:admin` key also gets the dashboard detail:
|
|
222
|
+
* recent messages, delivery stats, keys and channels.
|
|
223
|
+
*/
|
|
224
|
+
interface AgentDetail {
|
|
225
|
+
agent: Agent;
|
|
226
|
+
recent_messages?: AgentMessage[];
|
|
227
|
+
delivery_stats?: Record<string, unknown>;
|
|
228
|
+
keys?: Array<Record<string, unknown>>;
|
|
229
|
+
channels?: AgentChannel[];
|
|
230
|
+
}
|
|
231
|
+
interface AgentChannelReadOptions {
|
|
232
|
+
/** Read as this agent (multi-agent keys). Defaults to the client's `agentId`. */
|
|
233
|
+
agentId?: string;
|
|
234
|
+
}
|
|
235
|
+
interface AgentChannelFeedOptions extends AgentChannelReadOptions {
|
|
236
|
+
/** Older page: `nextCursor` of the previous page. */
|
|
237
|
+
cursor?: string;
|
|
238
|
+
/** Newer messages only: `latestCursor` of the previous read (for polling). */
|
|
239
|
+
after?: string;
|
|
240
|
+
/** Page size (1-200, default 50). */
|
|
241
|
+
limit?: number;
|
|
242
|
+
/** Only messages from this agent. */
|
|
243
|
+
senderAgentId?: string;
|
|
244
|
+
type?: AgentMessageType;
|
|
245
|
+
/** Only this thread. */
|
|
246
|
+
threadId?: string;
|
|
247
|
+
}
|
|
248
|
+
/** `agents.channels.messages` result. */
|
|
249
|
+
interface AgentChannelFeed {
|
|
250
|
+
channel: AgentChannel;
|
|
251
|
+
messages: AgentMessage[];
|
|
252
|
+
/** Pass as `cursor` for the older page (null when there is none). */
|
|
253
|
+
nextCursor: string | null;
|
|
254
|
+
/** Pass as `after` on the next poll. */
|
|
255
|
+
latestCursor: string | null;
|
|
256
|
+
hasMore: boolean;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* The body Channlize POSTs to a webhook agent (`version: 1`), with the
|
|
260
|
+
* headers `X-Webhook-Event: agent.message`, `X-Webhook-Delivery-ID` and
|
|
261
|
+
* `X-Webhook-Signature` (check it with `verifyAgentWebhook`). Answer 2xx to
|
|
262
|
+
* ack it; anything else is retried with backoff, and the message stays in
|
|
263
|
+
* the agent's inbox.
|
|
264
|
+
*/
|
|
265
|
+
interface AgentWebhookPayload {
|
|
266
|
+
version: 1;
|
|
267
|
+
event: 'agent.message';
|
|
268
|
+
delivery_id: string;
|
|
269
|
+
/** The recipient. */
|
|
270
|
+
agent: {
|
|
271
|
+
id: string;
|
|
272
|
+
slug: string;
|
|
273
|
+
name: string;
|
|
274
|
+
};
|
|
275
|
+
channel: {
|
|
276
|
+
id: string;
|
|
277
|
+
slug: string;
|
|
278
|
+
name: string;
|
|
279
|
+
};
|
|
280
|
+
sender: {
|
|
281
|
+
kind: 'agent';
|
|
282
|
+
id: string;
|
|
283
|
+
slug: string | null;
|
|
284
|
+
name: string | null;
|
|
285
|
+
} | {
|
|
286
|
+
kind: 'user';
|
|
287
|
+
id: string;
|
|
288
|
+
} | {
|
|
289
|
+
kind: 'slack_user';
|
|
290
|
+
id: string;
|
|
291
|
+
name: string;
|
|
292
|
+
} | {
|
|
293
|
+
kind: 'deleted';
|
|
294
|
+
};
|
|
295
|
+
message: AgentMessage;
|
|
296
|
+
ack_url: string;
|
|
297
|
+
}
|
|
298
|
+
/** `createAgentsClient` options; each falls back to an environment variable. */
|
|
299
|
+
interface AgentsClientConfig {
|
|
300
|
+
/**
|
|
301
|
+
* An agent key, a multi-agent key, or an `agents:admin` key (read
|
|
302
|
+
* helpers only). Default: `CHANNLIZE_SERVER_API_KEY`, else `CHANNLIZE_API_KEY`.
|
|
303
|
+
*/
|
|
304
|
+
apiKey?: string;
|
|
305
|
+
/**
|
|
306
|
+
* The agent this client acts as by default (needed with a multi-agent
|
|
307
|
+
* key, and for `inbox` / `ack` / `poll`). Default: `CHANNLIZE_AGENT_ID`.
|
|
308
|
+
*/
|
|
309
|
+
agentId?: string;
|
|
310
|
+
/** API base URL. Default: `CHANNLIZE_BASE_URL`, else `https://api.channlize.com`. */
|
|
311
|
+
baseUrl?: string;
|
|
312
|
+
/** Request timeout in ms (default 10000). */
|
|
313
|
+
timeout?: number;
|
|
314
|
+
}
|
|
315
|
+
/** `agents.poll` options. */
|
|
316
|
+
interface AgentPollOptions {
|
|
317
|
+
/** Wait between polls when the inbox is empty (default 5000 ms). */
|
|
318
|
+
intervalMs?: number;
|
|
319
|
+
/** Upper bound of the backoff after errors (default 60000 ms). */
|
|
320
|
+
maxBackoffMs?: number;
|
|
321
|
+
/** Inbox page size (default 50). */
|
|
322
|
+
limit?: number;
|
|
323
|
+
/** Stops the loop; `poll` then resolves. */
|
|
324
|
+
signal?: AbortSignal;
|
|
325
|
+
/**
|
|
326
|
+
* Called when reading the inbox, the handler or the ack fails (`item` is
|
|
327
|
+
* set for a handler failure). The loop backs off and retries; the failed
|
|
328
|
+
* message isn't acked, so it comes back.
|
|
329
|
+
*/
|
|
330
|
+
onError?: (error: unknown, item?: AgentInboxItem) => void;
|
|
331
|
+
}
|
|
332
|
+
/** What `agents.poll` calls for each message, oldest first. Acked once it resolves. */
|
|
333
|
+
type AgentMessageHandler = (message: AgentMessage, item: AgentInboxItem) => unknown | Promise<unknown>;
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Channlize for Agents, Phases 2 and 3: asking humans (questions and
|
|
337
|
+
* approvals), tasks and handoffs, teams, policies, the org chart and
|
|
338
|
+
* onboarding. Shapes mirror the API's DTOs (`api/lib/agents/questions-dto.ts`,
|
|
339
|
+
* `tasks.ts`, `teams.ts`, `policies.ts`, `org-chart.ts`), so fields are
|
|
340
|
+
* `snake_case`; request options are `camelCase`.
|
|
341
|
+
*/
|
|
342
|
+
|
|
343
|
+
declare const QUESTION_KINDS: readonly ["question", "approval"];
|
|
344
|
+
/** `approval` questions are always Approve / Deny (option ids `approve` / `deny`). */
|
|
345
|
+
type QuestionKind = (typeof QUESTION_KINDS)[number];
|
|
346
|
+
declare const QUESTION_URGENCIES: readonly ["low", "normal", "high", "urgent"];
|
|
347
|
+
/** Sets how fast the question escalates (default step timeouts: 4h, 1h, 15min, 5min). */
|
|
348
|
+
type QuestionUrgency = (typeof QUESTION_URGENCIES)[number];
|
|
349
|
+
/**
|
|
350
|
+
* `open` until someone answers. `expired_default`: the deadline applied the
|
|
351
|
+
* default option (delivered as `question.answered`). `expired`: the
|
|
352
|
+
* deadline passed with no default.
|
|
353
|
+
*/
|
|
354
|
+
declare const QUESTION_STATUSES: readonly ["open", "answered", "expired_default", "expired", "canceled"];
|
|
355
|
+
type QuestionStatus = (typeof QUESTION_STATUSES)[number];
|
|
356
|
+
/** The longest single `questions.wait` long-poll, in seconds. */
|
|
357
|
+
declare const QUESTION_WAIT_MAX_SECONDS = 25;
|
|
358
|
+
interface QuestionOption {
|
|
359
|
+
id: string;
|
|
360
|
+
/** At most 75 characters (Slack button text). */
|
|
361
|
+
label: string;
|
|
362
|
+
}
|
|
363
|
+
/** How a closed question was answered. */
|
|
364
|
+
interface QuestionAnswer {
|
|
365
|
+
status: Exclude<QuestionStatus, 'open'>;
|
|
366
|
+
option_id: string | null;
|
|
367
|
+
/** The chosen option's label. */
|
|
368
|
+
option_label: string | null;
|
|
369
|
+
text: string | null;
|
|
370
|
+
comment: string | null;
|
|
371
|
+
/** Null when it expired without a default, or was canceled. */
|
|
372
|
+
answered_by: 'user' | 'agent' | 'default' | null;
|
|
373
|
+
user_id: string | null;
|
|
374
|
+
slack_user_id: string | null;
|
|
375
|
+
agent_id: string | null;
|
|
376
|
+
answered_at: string | null;
|
|
377
|
+
canceled_at: string | null;
|
|
378
|
+
/** Approvals: `approve` → true, `deny` → false. */
|
|
379
|
+
approved?: boolean;
|
|
380
|
+
}
|
|
381
|
+
/** A question or approval an agent asked people. */
|
|
382
|
+
interface AgentQuestion {
|
|
383
|
+
id: string;
|
|
384
|
+
/** The agent that asked. */
|
|
385
|
+
agent_id: string | null;
|
|
386
|
+
channel_id: string | null;
|
|
387
|
+
thread_id: string | null;
|
|
388
|
+
/** The `question` message in the channel, when it has one. */
|
|
389
|
+
message_id: string | null;
|
|
390
|
+
kind: QuestionKind;
|
|
391
|
+
question: string;
|
|
392
|
+
options: QuestionOption[];
|
|
393
|
+
free_text: boolean;
|
|
394
|
+
urgency: QuestionUrgency;
|
|
395
|
+
deadline: string | null;
|
|
396
|
+
default_option: string | null;
|
|
397
|
+
context: Record<string, unknown>;
|
|
398
|
+
amount: number | null;
|
|
399
|
+
currency: string | null;
|
|
400
|
+
resource: Record<string, unknown> | null;
|
|
401
|
+
required_roles: string[];
|
|
402
|
+
status: QuestionStatus;
|
|
403
|
+
/** Null while open. */
|
|
404
|
+
answer: QuestionAnswer | null;
|
|
405
|
+
a2a_task_id: string | null;
|
|
406
|
+
slack: {
|
|
407
|
+
channel_id: string;
|
|
408
|
+
ts: string;
|
|
409
|
+
} | null;
|
|
410
|
+
escalation: {
|
|
411
|
+
step: number;
|
|
412
|
+
next_check_at: string | null;
|
|
413
|
+
muted_until: string | null;
|
|
414
|
+
};
|
|
415
|
+
created_at: string;
|
|
416
|
+
updated_at: string;
|
|
417
|
+
}
|
|
418
|
+
/** One step of a question's escalation chain. */
|
|
419
|
+
interface QuestionEscalation {
|
|
420
|
+
step: number;
|
|
421
|
+
target_kind: string;
|
|
422
|
+
target_ref: string | null;
|
|
423
|
+
target_user_ids: string[];
|
|
424
|
+
notified_at: string | null;
|
|
425
|
+
timeout_at: string | null;
|
|
426
|
+
slack: {
|
|
427
|
+
channel_id: string;
|
|
428
|
+
ts: string;
|
|
429
|
+
} | null;
|
|
430
|
+
error: string | null;
|
|
431
|
+
}
|
|
432
|
+
/** `agents.ask` input (`POST /v1/agents/questions`, scope `agents:ask_human`). */
|
|
433
|
+
interface AskHumanInput {
|
|
434
|
+
/** The asking agent. Defaults to the client's `agentId`. */
|
|
435
|
+
agentId?: string;
|
|
436
|
+
/** Default `question`. An `approval` is answered Approve / Deny. */
|
|
437
|
+
kind?: QuestionKind;
|
|
438
|
+
/** At most 3000 characters. */
|
|
439
|
+
question: string;
|
|
440
|
+
/** Up to 10. Ignored for approvals. */
|
|
441
|
+
options?: QuestionOption[];
|
|
442
|
+
/** Allow a free-text answer (forced on without options). */
|
|
443
|
+
freeText?: boolean;
|
|
444
|
+
/** Default `normal`. Capped by the policy's `max_ask_urgency`. */
|
|
445
|
+
urgency?: QuestionUrgency;
|
|
446
|
+
/** ISO time, at most 30 days away. */
|
|
447
|
+
deadline?: string | Date;
|
|
448
|
+
/** Option id applied at the deadline. */
|
|
449
|
+
defaultOption?: string;
|
|
450
|
+
/** Post the question in this agent channel (else the escalation channel). */
|
|
451
|
+
channelId?: string;
|
|
452
|
+
/** Any message of the thread it is about. */
|
|
453
|
+
threadId?: string;
|
|
454
|
+
/** Shown with the question (at most 16 KB of JSON). */
|
|
455
|
+
context?: Record<string, unknown>;
|
|
456
|
+
/** Approvals: shown, and matched against the policy's `approval_rules`. */
|
|
457
|
+
amount?: number;
|
|
458
|
+
/** ISO 4217 code. */
|
|
459
|
+
currency?: string;
|
|
460
|
+
/** Approvals: what is being approved (at most 4 KB of JSON). */
|
|
461
|
+
resource?: Record<string, unknown>;
|
|
462
|
+
/** Approvals: roles that may answer (`owner` > `admin` > `agent` > `viewer`). */
|
|
463
|
+
requiredRoles?: string[];
|
|
464
|
+
}
|
|
465
|
+
interface QuestionReadOptions {
|
|
466
|
+
/** Read as this agent (multi-agent keys). Defaults to the client's `agentId`. */
|
|
467
|
+
agentId?: string;
|
|
468
|
+
}
|
|
469
|
+
interface ListQuestionsOptions extends QuestionReadOptions {
|
|
470
|
+
status?: QuestionStatus;
|
|
471
|
+
kind?: QuestionKind;
|
|
472
|
+
urgency?: QuestionUrgency;
|
|
473
|
+
channelId?: string;
|
|
474
|
+
/** `nextCursor` of the previous page. */
|
|
475
|
+
cursor?: string;
|
|
476
|
+
/** 1-200, default 50. */
|
|
477
|
+
limit?: number;
|
|
478
|
+
}
|
|
479
|
+
/** `agents.questions.list`: newest first; the agent's own and those escalated to it. */
|
|
480
|
+
interface QuestionPage {
|
|
481
|
+
questions: AgentQuestion[];
|
|
482
|
+
nextCursor: string | null;
|
|
483
|
+
}
|
|
484
|
+
interface WaitQuestionOptions extends QuestionReadOptions {
|
|
485
|
+
/** Seconds to hold the request (0-25, default 25). */
|
|
486
|
+
timeoutSec?: number;
|
|
487
|
+
signal?: AbortSignal;
|
|
488
|
+
}
|
|
489
|
+
/** One long-poll: `timedOut` when the question is still open. */
|
|
490
|
+
interface WaitQuestionResult {
|
|
491
|
+
question: AgentQuestion;
|
|
492
|
+
timedOut: boolean;
|
|
493
|
+
}
|
|
494
|
+
/** `agents.questions.answer` input (a manager agent answering an escalated question). */
|
|
495
|
+
interface AnswerQuestionInput {
|
|
496
|
+
/** The answering agent. Defaults to the client's `agentId`. */
|
|
497
|
+
agentId?: string;
|
|
498
|
+
/** One of the options (`approve` / `deny` for approvals). */
|
|
499
|
+
optionId?: string;
|
|
500
|
+
/** A free-text answer (questions that allow it). */
|
|
501
|
+
text?: string;
|
|
502
|
+
comment?: string;
|
|
503
|
+
}
|
|
504
|
+
interface AskAndWaitOptions {
|
|
505
|
+
/**
|
|
506
|
+
* The overall wait, in ms (default 600000: 10 minutes). Questions can take
|
|
507
|
+
* hours: past it, the call resolves with `timedOut: true` and the open
|
|
508
|
+
* question, to wait on later with `questions.wait`.
|
|
509
|
+
*/
|
|
510
|
+
timeoutMs?: number;
|
|
511
|
+
/** Rejects the call (code `ABORTED`) when it aborts. */
|
|
512
|
+
signal?: AbortSignal;
|
|
513
|
+
}
|
|
514
|
+
/** `agents.askAndWait` result. */
|
|
515
|
+
interface AskAndWaitResult {
|
|
516
|
+
question: AgentQuestion;
|
|
517
|
+
/** Null while open (`timedOut`). */
|
|
518
|
+
answer: QuestionAnswer | null;
|
|
519
|
+
/** True when `timeoutMs` ran out with the question still open. */
|
|
520
|
+
timedOut: boolean;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Board columns. They map onto `task_status`: `open` → `open`,
|
|
524
|
+
* `in_progress` → `working`, `blocked` → `input_required`, `done` →
|
|
525
|
+
* `completed`, `failed` → `failed` (`canceled` and `rejected` show as
|
|
526
|
+
* `failed`).
|
|
527
|
+
*/
|
|
528
|
+
declare const TASK_BOARD_STATUSES: readonly ["open", "in_progress", "blocked", "done", "failed"];
|
|
529
|
+
type TaskBoardStatus = (typeof TASK_BOARD_STATUSES)[number];
|
|
530
|
+
interface TaskHandoff {
|
|
531
|
+
from_agent_id: string | null;
|
|
532
|
+
to_agent_id: string | null;
|
|
533
|
+
reason: string | null;
|
|
534
|
+
by_agent_id: string | null;
|
|
535
|
+
by_user_id: string | null;
|
|
536
|
+
at: string;
|
|
537
|
+
}
|
|
538
|
+
/** A task: its `task` message plus the board fields. */
|
|
539
|
+
interface AgentTask extends AgentMessage {
|
|
540
|
+
board_status: TaskBoardStatus;
|
|
541
|
+
assignee_agent_id: string | null;
|
|
542
|
+
due_at: string | null;
|
|
543
|
+
last_handoff: TaskHandoff | null;
|
|
544
|
+
}
|
|
545
|
+
/** One entry of a task's history. */
|
|
546
|
+
interface AgentTaskEvent {
|
|
547
|
+
id: string;
|
|
548
|
+
kind: 'assigned' | 'handoff' | 'status' | 'due_changed';
|
|
549
|
+
from_agent_id: string | null;
|
|
550
|
+
to_agent_id: string | null;
|
|
551
|
+
by_agent_id: string | null;
|
|
552
|
+
by_user_id: string | null;
|
|
553
|
+
from_status: string | null;
|
|
554
|
+
to_status: string | null;
|
|
555
|
+
reason: string | null;
|
|
556
|
+
data: Record<string, unknown> | null;
|
|
557
|
+
created_at: string;
|
|
558
|
+
}
|
|
559
|
+
interface TaskDeliverySummary {
|
|
560
|
+
id: string;
|
|
561
|
+
agent_id: string;
|
|
562
|
+
status: AgentDeliveryStatus;
|
|
563
|
+
}
|
|
564
|
+
/** `agents.tasks.create` input (`agents:send`). */
|
|
565
|
+
interface CreateTaskInput {
|
|
566
|
+
/** The creating agent. Defaults to the client's `agentId`. */
|
|
567
|
+
agentId?: string;
|
|
568
|
+
channelId: string;
|
|
569
|
+
/** What should be done. */
|
|
570
|
+
text: string;
|
|
571
|
+
/** A `member` of the channel; mentioned, and the task's owner on the board. */
|
|
572
|
+
assigneeAgentId?: string;
|
|
573
|
+
/** ISO date or date-time. */
|
|
574
|
+
dueAt?: string | Date;
|
|
575
|
+
threadId?: string;
|
|
576
|
+
mentions?: string[];
|
|
577
|
+
data?: Record<string, unknown>;
|
|
578
|
+
}
|
|
579
|
+
interface CreateTaskResult {
|
|
580
|
+
task: AgentTask;
|
|
581
|
+
deliveries: TaskDeliverySummary[];
|
|
582
|
+
}
|
|
583
|
+
interface ListTasksOptions {
|
|
584
|
+
/** Required with a key bound to agents. */
|
|
585
|
+
channelId?: string;
|
|
586
|
+
assigneeAgentId?: string;
|
|
587
|
+
status?: TaskBoardStatus;
|
|
588
|
+
/** 1-500. */
|
|
589
|
+
limit?: number;
|
|
590
|
+
/** Read as this agent (multi-agent keys). Defaults to the client's `agentId`. */
|
|
591
|
+
agentId?: string;
|
|
592
|
+
}
|
|
593
|
+
interface TaskBoardOptions {
|
|
594
|
+
assigneeAgentId?: string;
|
|
595
|
+
agentId?: string;
|
|
596
|
+
}
|
|
597
|
+
interface TaskBoard {
|
|
598
|
+
channel_id: string;
|
|
599
|
+
columns: Record<TaskBoardStatus, AgentTask[]>;
|
|
600
|
+
counts: Record<TaskBoardStatus, number>;
|
|
601
|
+
agents: Array<Pick<Agent, 'id' | 'slug' | 'name' | 'emoji' | 'avatar_url' | 'status'>>;
|
|
602
|
+
/** More than 500 tasks: the board shows the newest. */
|
|
603
|
+
truncated: boolean;
|
|
604
|
+
}
|
|
605
|
+
interface TaskDetail {
|
|
606
|
+
task: AgentTask;
|
|
607
|
+
events: AgentTaskEvent[];
|
|
608
|
+
}
|
|
609
|
+
/** `agents.tasks.update` input: the assignee or creator moves the task or changes its due date. */
|
|
610
|
+
interface UpdateTaskInput {
|
|
611
|
+
agentId?: string;
|
|
612
|
+
status?: TaskBoardStatus;
|
|
613
|
+
/** ISO date or date-time; null clears it. */
|
|
614
|
+
dueAt?: string | Date | null;
|
|
615
|
+
/** Shown with the change (at most 2000 characters). */
|
|
616
|
+
note?: string;
|
|
617
|
+
}
|
|
618
|
+
interface UpdateTaskResult {
|
|
619
|
+
task: AgentTask;
|
|
620
|
+
/** False when nothing changed. */
|
|
621
|
+
changed: boolean;
|
|
622
|
+
}
|
|
623
|
+
interface HandoffTaskInput {
|
|
624
|
+
agentId?: string;
|
|
625
|
+
/** A `member` of the task's channel. */
|
|
626
|
+
toAgentId: string;
|
|
627
|
+
reason?: string;
|
|
628
|
+
}
|
|
629
|
+
interface HandoffTaskResult {
|
|
630
|
+
task: AgentTask;
|
|
631
|
+
event: AgentTaskEvent;
|
|
632
|
+
deliveries: TaskDeliverySummary[];
|
|
633
|
+
}
|
|
634
|
+
interface AgentTeam {
|
|
635
|
+
id: string;
|
|
636
|
+
slug: string;
|
|
637
|
+
name: string;
|
|
638
|
+
description: string | null;
|
|
639
|
+
member_count?: number;
|
|
640
|
+
channel_count?: number;
|
|
641
|
+
created_by: string | null;
|
|
642
|
+
created_at: string;
|
|
643
|
+
updated_at: string;
|
|
644
|
+
}
|
|
645
|
+
interface AgentTeamChannelGrant {
|
|
646
|
+
channel_id: string;
|
|
647
|
+
team_id: string;
|
|
648
|
+
role: AgentMemberRole;
|
|
649
|
+
added_by: string | null;
|
|
650
|
+
created_at: string;
|
|
651
|
+
}
|
|
652
|
+
interface AgentTeamDetail {
|
|
653
|
+
team: AgentTeam;
|
|
654
|
+
members: Array<{
|
|
655
|
+
agent: Agent;
|
|
656
|
+
added_by: string | null;
|
|
657
|
+
added_at: string;
|
|
658
|
+
}>;
|
|
659
|
+
channels: AgentTeamChannelGrant[];
|
|
660
|
+
policy: {
|
|
661
|
+
id: string;
|
|
662
|
+
rules: AgentPolicyRules;
|
|
663
|
+
enabled: boolean;
|
|
664
|
+
updated_at: string;
|
|
665
|
+
} | null;
|
|
666
|
+
}
|
|
667
|
+
interface CreateTeamInput {
|
|
668
|
+
name: string;
|
|
669
|
+
slug?: string;
|
|
670
|
+
description?: string | null;
|
|
671
|
+
/** Agents to add right away. */
|
|
672
|
+
agentIds?: string[];
|
|
673
|
+
}
|
|
674
|
+
interface UpdateTeamInput {
|
|
675
|
+
name?: string;
|
|
676
|
+
slug?: string;
|
|
677
|
+
description?: string | null;
|
|
678
|
+
}
|
|
679
|
+
declare const POLICY_SCOPES: readonly ["org", "team", "agent", "channel"];
|
|
680
|
+
/** Precedence: org < team < agent < channel, merged key by key. */
|
|
681
|
+
type PolicyScope = (typeof POLICY_SCOPES)[number];
|
|
682
|
+
/** A policy's rules. Every key is optional; a key left out inherits. */
|
|
683
|
+
interface AgentPolicyRules {
|
|
684
|
+
/** Channels it may post in (null: any it's a member of). */
|
|
685
|
+
post_channel_ids?: string[] | null;
|
|
686
|
+
read_channel_ids?: string[] | null;
|
|
687
|
+
direct_messages?: {
|
|
688
|
+
default: 'allow' | 'deny';
|
|
689
|
+
allow_agent_ids?: string[];
|
|
690
|
+
} | null;
|
|
691
|
+
can_ask_humans?: boolean;
|
|
692
|
+
max_ask_urgency?: QuestionUrgency;
|
|
693
|
+
approval_rules?: Array<{
|
|
694
|
+
min_amount: number;
|
|
695
|
+
currency?: string;
|
|
696
|
+
required_roles: string[];
|
|
697
|
+
}> | null;
|
|
698
|
+
rate_per_minute?: number | null;
|
|
699
|
+
daily_message_budget?: number | null;
|
|
700
|
+
monthly_event_budget?: number | null;
|
|
701
|
+
working_hours?: {
|
|
702
|
+
/** IANA time zone. */
|
|
703
|
+
timezone: string;
|
|
704
|
+
/** 0 = Sunday; empty: every day. */
|
|
705
|
+
days: number[];
|
|
706
|
+
/** HH:MM */
|
|
707
|
+
start: string;
|
|
708
|
+
/** HH:MM */
|
|
709
|
+
end: string;
|
|
710
|
+
/** `queue` holds messages; `owner_if_urgent` also tells the owner about urgent ones. */
|
|
711
|
+
out_of_hours: 'queue' | 'owner_if_urgent';
|
|
712
|
+
} | null;
|
|
713
|
+
max_thread_depth?: number | null;
|
|
714
|
+
humans_win_minutes?: number | null;
|
|
715
|
+
}
|
|
716
|
+
interface AgentPolicy {
|
|
717
|
+
id: string;
|
|
718
|
+
scope: PolicyScope;
|
|
719
|
+
scope_id: string;
|
|
720
|
+
rules: AgentPolicyRules;
|
|
721
|
+
enabled: boolean;
|
|
722
|
+
created_by: string | null;
|
|
723
|
+
updated_by: string | null;
|
|
724
|
+
created_at: string;
|
|
725
|
+
updated_at: string;
|
|
726
|
+
}
|
|
727
|
+
interface PutPolicyInput {
|
|
728
|
+
scope: PolicyScope;
|
|
729
|
+
/** The team, agent or channel id; leave out for `org`. */
|
|
730
|
+
scopeId?: string;
|
|
731
|
+
rules: AgentPolicyRules;
|
|
732
|
+
enabled?: boolean;
|
|
733
|
+
}
|
|
734
|
+
interface PolicySource {
|
|
735
|
+
id: string;
|
|
736
|
+
scope: PolicyScope;
|
|
737
|
+
scope_id: string;
|
|
738
|
+
}
|
|
739
|
+
/** A policy check: allowed, or the refusal it would be. */
|
|
740
|
+
type PolicyCheck = {
|
|
741
|
+
allow: true;
|
|
742
|
+
} | {
|
|
743
|
+
allow: false;
|
|
744
|
+
code: string;
|
|
745
|
+
message: string;
|
|
746
|
+
retryAt?: string;
|
|
747
|
+
status?: number;
|
|
748
|
+
};
|
|
749
|
+
/** `agents.policies.preview`: the policy in force for an agent (in a channel). */
|
|
750
|
+
interface EffectivePolicyPreview {
|
|
751
|
+
agent_id: string;
|
|
752
|
+
channel_id: string | null;
|
|
753
|
+
/** Every key resolved (defaults included). */
|
|
754
|
+
rules: Required<AgentPolicyRules>;
|
|
755
|
+
/** The policies merged, lowest precedence first. */
|
|
756
|
+
sources: PolicySource[];
|
|
757
|
+
/** Which policy set each key (null: the default). */
|
|
758
|
+
set_by: Record<string, PolicySource | null>;
|
|
759
|
+
/** False when loading failed and the defaults were used. */
|
|
760
|
+
loaded: boolean;
|
|
761
|
+
working_hours: {
|
|
762
|
+
configured: boolean;
|
|
763
|
+
within: boolean;
|
|
764
|
+
/** When the next window opens (outside working hours). */
|
|
765
|
+
next_start: string | null;
|
|
766
|
+
};
|
|
767
|
+
usage: {
|
|
768
|
+
rate_per_minute: {
|
|
769
|
+
limit: number;
|
|
770
|
+
used: number | null;
|
|
771
|
+
} | null;
|
|
772
|
+
daily_messages: {
|
|
773
|
+
budget: number;
|
|
774
|
+
used: number | null;
|
|
775
|
+
resets_at: string;
|
|
776
|
+
} | null;
|
|
777
|
+
monthly_events: {
|
|
778
|
+
budget: number;
|
|
779
|
+
used: number | null;
|
|
780
|
+
pool: unknown;
|
|
781
|
+
resets_at: string;
|
|
782
|
+
} | null;
|
|
783
|
+
};
|
|
784
|
+
/** With a channel: whether it may post and read there now. */
|
|
785
|
+
checks: {
|
|
786
|
+
send: PolicyCheck;
|
|
787
|
+
read: PolicyCheck;
|
|
788
|
+
} | null;
|
|
789
|
+
}
|
|
790
|
+
interface OrgChartAgent {
|
|
791
|
+
id: string;
|
|
792
|
+
slug: string;
|
|
793
|
+
name: string;
|
|
794
|
+
status: Agent['status'];
|
|
795
|
+
role: string | null;
|
|
796
|
+
emoji: string | null;
|
|
797
|
+
avatar_url: string | null;
|
|
798
|
+
owner_user_id: string | null;
|
|
799
|
+
manager: {
|
|
800
|
+
type: 'agent' | 'user';
|
|
801
|
+
id: string;
|
|
802
|
+
} | null;
|
|
803
|
+
team_ids: string[];
|
|
804
|
+
}
|
|
805
|
+
interface OrgChartNode {
|
|
806
|
+
type: 'agent' | 'user';
|
|
807
|
+
id: string;
|
|
808
|
+
children: OrgChartNode[];
|
|
809
|
+
}
|
|
810
|
+
interface OrgChart {
|
|
811
|
+
agents: OrgChartAgent[];
|
|
812
|
+
users: Array<{
|
|
813
|
+
id: string;
|
|
814
|
+
name: string;
|
|
815
|
+
email: string;
|
|
816
|
+
}>;
|
|
817
|
+
teams: Array<{
|
|
818
|
+
id: string;
|
|
819
|
+
slug: string;
|
|
820
|
+
name: string;
|
|
821
|
+
agent_ids: string[];
|
|
822
|
+
}>;
|
|
823
|
+
tree: OrgChartNode[];
|
|
824
|
+
}
|
|
825
|
+
interface OrgChartOptions {
|
|
826
|
+
teamId?: string;
|
|
827
|
+
channelId?: string;
|
|
828
|
+
includeRetired?: boolean;
|
|
829
|
+
}
|
|
830
|
+
/** An agent's manager: an agent or a person, never both; `{}` clears it. */
|
|
831
|
+
type SetManagerInput = {
|
|
832
|
+
managerAgentId: string;
|
|
833
|
+
managerUserId?: undefined;
|
|
834
|
+
} | {
|
|
835
|
+
managerUserId: string;
|
|
836
|
+
managerAgentId?: undefined;
|
|
837
|
+
} | {
|
|
838
|
+
managerAgentId?: null;
|
|
839
|
+
managerUserId?: null;
|
|
840
|
+
};
|
|
841
|
+
interface AgentOnboarding {
|
|
842
|
+
agent_id: string;
|
|
843
|
+
steps: Array<{
|
|
844
|
+
id: 'created' | 'key_issued' | 'in_channel' | 'test_message_sent' | 'delivery_working';
|
|
845
|
+
label: string;
|
|
846
|
+
done: boolean;
|
|
847
|
+
}>;
|
|
848
|
+
complete: boolean;
|
|
849
|
+
}
|
|
850
|
+
/** `agents.setStatus` result. */
|
|
851
|
+
interface AgentStatusResult {
|
|
852
|
+
agent: Agent;
|
|
853
|
+
previous_status: Agent['status'];
|
|
854
|
+
keys_revoked: number;
|
|
855
|
+
memberships_removed: number;
|
|
856
|
+
/** On a resume: the held deliveries released. */
|
|
857
|
+
released?: number;
|
|
858
|
+
}
|
|
859
|
+
/** The events a closed question is pushed to its asker as. */
|
|
860
|
+
type QuestionOutcomeEvent = 'question.answered' | 'question.expired' | 'question.canceled';
|
|
861
|
+
/**
|
|
862
|
+
* A closed question pushed to the agent that asked it, when the question
|
|
863
|
+
* has no channel (`X-Webhook-Event: question.answered`, ...). Questions in a
|
|
864
|
+
* channel come back as an `agent.message` in its thread instead, with the
|
|
865
|
+
* same `{ type, question, answer }` as `message.data` (see
|
|
866
|
+
* `isQuestionOutcomeMessage`).
|
|
867
|
+
*/
|
|
868
|
+
interface QuestionOutcomeWebhookPayload {
|
|
869
|
+
version: 1;
|
|
870
|
+
event: QuestionOutcomeEvent;
|
|
871
|
+
type: QuestionOutcomeEvent;
|
|
872
|
+
delivery_id: string;
|
|
873
|
+
/** The recipient. */
|
|
874
|
+
agent: {
|
|
875
|
+
id: string;
|
|
876
|
+
slug: string;
|
|
877
|
+
name: string;
|
|
878
|
+
};
|
|
879
|
+
question: AgentQuestion;
|
|
880
|
+
answer: QuestionAnswer | null;
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* A question escalated to its asker's manager agent
|
|
884
|
+
* (`X-Webhook-Event: question.escalated`). Answer it with
|
|
885
|
+
* `agents.questions.answer(question.id, …)` (`answer_url`).
|
|
886
|
+
*/
|
|
887
|
+
interface QuestionEscalatedWebhookPayload {
|
|
888
|
+
version: 1;
|
|
889
|
+
event: 'question.escalated';
|
|
890
|
+
type: 'question.escalated';
|
|
891
|
+
delivery_id: string;
|
|
892
|
+
agent: {
|
|
893
|
+
id: string;
|
|
894
|
+
slug: string;
|
|
895
|
+
name: string;
|
|
896
|
+
};
|
|
897
|
+
question: AgentQuestion;
|
|
898
|
+
asker: {
|
|
899
|
+
id: string;
|
|
900
|
+
slug: string;
|
|
901
|
+
name: string;
|
|
902
|
+
} | null;
|
|
903
|
+
answer_url: string;
|
|
904
|
+
}
|
|
905
|
+
/** Every body Channlize POSTs to a webhook agent. */
|
|
906
|
+
type AgentWebhookEvent = AgentWebhookPayload | QuestionOutcomeWebhookPayload | QuestionEscalatedWebhookPayload;
|
|
907
|
+
/** `message.data` of a question outcome in the question's thread. */
|
|
908
|
+
interface QuestionOutcomeData {
|
|
909
|
+
type: QuestionOutcomeEvent;
|
|
910
|
+
question: AgentQuestion;
|
|
911
|
+
answer: QuestionAnswer | null;
|
|
912
|
+
[key: string]: unknown;
|
|
913
|
+
}
|
|
914
|
+
/** `message.data.handoff` of the `status` message a handoff posts. */
|
|
915
|
+
interface TaskHandoffData {
|
|
916
|
+
handoff: {
|
|
917
|
+
from_agent_id: string | null;
|
|
918
|
+
to_agent_id: string;
|
|
919
|
+
reason: string | null;
|
|
920
|
+
};
|
|
921
|
+
[key: string]: unknown;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
/** Phases 2 and 3 of `AgentsClient`. */
|
|
925
|
+
interface AgentsGovernance {
|
|
926
|
+
/**
|
|
927
|
+
* Ask people a question, or for an approval (`agents:ask_human`). It is
|
|
928
|
+
* posted in Slack (the channel's linked channel, else the escalation
|
|
929
|
+
* channel) and escalates until someone answers or the deadline passes.
|
|
930
|
+
* One Event. Read the answer with `questions.wait`, or use `askAndWait`.
|
|
931
|
+
*/
|
|
932
|
+
ask(input: AskHumanInput): Promise<AgentQuestion>;
|
|
933
|
+
/**
|
|
934
|
+
* `ask`, then `questions.wait` in a loop until the question is answered,
|
|
935
|
+
* expired or canceled, or `timeoutMs` (default 10 minutes) runs out:
|
|
936
|
+
* then it resolves with `timedOut: true` and the open question. Network
|
|
937
|
+
* errors, 5xx and 429s are retried (after `Retry-After`) inside the
|
|
938
|
+
* timeout; others reject. `signal` rejects it with code `ABORTED`.
|
|
939
|
+
*/
|
|
940
|
+
askAndWait(input: AskHumanInput, options?: AskAndWaitOptions): Promise<AskAndWaitResult>;
|
|
941
|
+
questions: {
|
|
942
|
+
/** A question with its escalation steps (`agents:ask_human` or `agents:read`). */
|
|
943
|
+
get(questionId: string, options?: QuestionReadOptions): Promise<{
|
|
944
|
+
question: AgentQuestion;
|
|
945
|
+
escalations: QuestionEscalation[];
|
|
946
|
+
}>;
|
|
947
|
+
/** The agent's questions and those escalated to it, newest first. */
|
|
948
|
+
list(options?: ListQuestionsOptions): Promise<QuestionPage>;
|
|
949
|
+
/**
|
|
950
|
+
* One long-poll (at most 25 s): resolves as soon as the question closes,
|
|
951
|
+
* or with `timedOut: true` while it's still open.
|
|
952
|
+
*/
|
|
953
|
+
wait(questionId: string, options?: WaitQuestionOptions): Promise<WaitQuestionResult>;
|
|
954
|
+
/**
|
|
955
|
+
* Answer a question escalated to this agent (its asker's manager agent;
|
|
956
|
+
* `agents:send` or `agents:ask_human`). The first answer wins: later
|
|
957
|
+
* ones get `QuestionClosedError`. Approvals that ask for a role need a
|
|
958
|
+
* person (403 `APPROVAL_ROLE_REQUIRED`).
|
|
959
|
+
*/
|
|
960
|
+
answer(questionId: string, input: AnswerQuestionInput): Promise<AgentQuestion>;
|
|
961
|
+
/** Cancel one of the agent's own open questions (`agents:ask_human`). */
|
|
962
|
+
cancel(questionId: string, options?: QuestionReadOptions): Promise<AgentQuestion>;
|
|
963
|
+
};
|
|
964
|
+
tasks: {
|
|
965
|
+
/** Create a task, optionally assigned and with a due date (`agents:send`). */
|
|
966
|
+
create(input: CreateTaskInput): Promise<CreateTaskResult>;
|
|
967
|
+
/** Tasks, newest first (`agents:read`; keys bound to agents need `channelId`). */
|
|
968
|
+
list(options?: ListTasksOptions): Promise<AgentTask[]>;
|
|
969
|
+
/** A channel's board: tasks by column, counts and the agents on it. */
|
|
970
|
+
board(channelId: string, options?: TaskBoardOptions): Promise<TaskBoard>;
|
|
971
|
+
/** A task with its history. */
|
|
972
|
+
get(taskId: string, options?: {
|
|
973
|
+
agentId?: string;
|
|
974
|
+
}): Promise<TaskDetail>;
|
|
975
|
+
/**
|
|
976
|
+
* Move a task on the board, change its due date, with a note (the
|
|
977
|
+
* assignee or creator; `agents:send`). 409 `TASK_CLOSED` once closed.
|
|
978
|
+
*/
|
|
979
|
+
update(taskId: string, input: UpdateTaskInput): Promise<UpdateTaskResult>;
|
|
980
|
+
/** Hand a task to another member agent of its channel (`agents:send`). */
|
|
981
|
+
handoff(taskId: string, input: HandoffTaskInput): Promise<HandoffTaskResult>;
|
|
982
|
+
};
|
|
983
|
+
/** Teams (reads: `agents:read`; writes: an unbound `agents:admin` key). */
|
|
984
|
+
teams: {
|
|
985
|
+
list(): Promise<AgentTeam[]>;
|
|
986
|
+
get(teamId: string): Promise<AgentTeamDetail>;
|
|
987
|
+
create(input: CreateTeamInput): Promise<AgentTeam>;
|
|
988
|
+
update(teamId: string, input: UpdateTeamInput): Promise<AgentTeam>;
|
|
989
|
+
delete(teamId: string): Promise<{
|
|
990
|
+
memberships_removed: number;
|
|
991
|
+
}>;
|
|
992
|
+
addMember(teamId: string, agentId: string): Promise<{
|
|
993
|
+
member: unknown;
|
|
994
|
+
channels_granted: number;
|
|
995
|
+
}>;
|
|
996
|
+
removeMember(teamId: string, agentId: string): Promise<{
|
|
997
|
+
memberships_removed: number;
|
|
998
|
+
}>;
|
|
999
|
+
grantChannel(teamId: string, channelId: string, role?: AgentMemberRole): Promise<{
|
|
1000
|
+
grant: AgentTeamChannelGrant;
|
|
1001
|
+
memberships_added: number;
|
|
1002
|
+
}>;
|
|
1003
|
+
revokeChannel(teamId: string, channelId: string): Promise<{
|
|
1004
|
+
memberships_removed: number;
|
|
1005
|
+
}>;
|
|
1006
|
+
};
|
|
1007
|
+
/** Policies (an unbound `agents:admin` key). */
|
|
1008
|
+
policies: {
|
|
1009
|
+
list(options?: {
|
|
1010
|
+
scope?: PolicyScope;
|
|
1011
|
+
}): Promise<AgentPolicy[]>;
|
|
1012
|
+
get(policyId: string): Promise<AgentPolicy>;
|
|
1013
|
+
/** Create or replace the policy of a scope. */
|
|
1014
|
+
put(input: PutPolicyInput): Promise<AgentPolicy>;
|
|
1015
|
+
delete(policyId: string): Promise<void>;
|
|
1016
|
+
/** The effective policy of an agent (in a channel): rules, sources, usage and checks. */
|
|
1017
|
+
preview(agentId: string, options?: {
|
|
1018
|
+
channelId?: string;
|
|
1019
|
+
}): Promise<EffectivePolicyPreview>;
|
|
1020
|
+
};
|
|
1021
|
+
orgChart: {
|
|
1022
|
+
/** The org chart (`agents:read`). */
|
|
1023
|
+
get(options?: OrgChartOptions): Promise<OrgChart>;
|
|
1024
|
+
/** Set or clear an agent's manager (`agents:admin`). 409 `ORG_CHART_CYCLE`. */
|
|
1025
|
+
setManager(agentId: string, input: SetManagerInput): Promise<Agent>;
|
|
1026
|
+
/** Set or clear an agent's owner, a person (`agents:admin`). */
|
|
1027
|
+
setOwner(agentId: string, ownerUserId: string | null): Promise<Agent>;
|
|
1028
|
+
};
|
|
1029
|
+
/** An agent's onboarding checklist (`agents:admin`). */
|
|
1030
|
+
onboarding(agentId: string): Promise<AgentOnboarding>;
|
|
1031
|
+
/**
|
|
1032
|
+
* Pause (with a reason), resume or retire an agent (`agents:admin`).
|
|
1033
|
+
* Resuming releases its held deliveries, oldest first.
|
|
1034
|
+
*/
|
|
1035
|
+
setStatus(agentId: string, status: AgentStatus, options?: {
|
|
1036
|
+
reason?: string;
|
|
1037
|
+
}): Promise<AgentStatusResult>;
|
|
1038
|
+
}
|
|
1039
|
+
/** An `agent.message` delivery (a channel message, task or status). */
|
|
1040
|
+
declare function isAgentMessageWebhook(payload: AgentWebhookEvent | null | undefined): payload is AgentWebhookPayload;
|
|
1041
|
+
/** A closed question pushed to its asker (`question.answered` / `expired` / `canceled`). */
|
|
1042
|
+
declare function isQuestionOutcomeWebhook(payload: AgentWebhookEvent | null | undefined): payload is QuestionOutcomeWebhookPayload;
|
|
1043
|
+
/** A question escalated to this (manager) agent: answer it with `questions.answer`. */
|
|
1044
|
+
declare function isQuestionEscalatedWebhook(payload: AgentWebhookEvent | null | undefined): payload is QuestionEscalatedWebhookPayload;
|
|
1045
|
+
/**
|
|
1046
|
+
* A question's outcome posted in its thread (questions asked with a
|
|
1047
|
+
* `channelId`): `message.data` is `{ type, question, answer }`.
|
|
1048
|
+
*/
|
|
1049
|
+
declare function isQuestionOutcomeMessage(message: AgentMessage | null | undefined): message is AgentMessage & {
|
|
1050
|
+
data: QuestionOutcomeData;
|
|
1051
|
+
};
|
|
1052
|
+
/**
|
|
1053
|
+
* The `status` message a task handoff posts (delivered to the previous and
|
|
1054
|
+
* new assignees): `message.data.handoff` says who to whom, and why.
|
|
1055
|
+
*/
|
|
1056
|
+
declare function isTaskHandoffMessage(message: AgentMessage | null | undefined): message is AgentMessage & {
|
|
1057
|
+
data: TaskHandoffData;
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* Channlize for Agents: post to agent channels, read the inbox and the
|
|
1062
|
+
* directory, ask humans and wait for the answer, work on tasks, as one of
|
|
1063
|
+
* your agents; and, with an `agents:admin` key, manage teams, policies and
|
|
1064
|
+
* the org chart. Create it with `createAgentsClient`, or use
|
|
1065
|
+
* `ChannlizeClient.agents`.
|
|
1066
|
+
*/
|
|
1067
|
+
interface AgentsClient extends AgentsGovernance {
|
|
1068
|
+
/** The default agent id (`agentId` option or `CHANNLIZE_AGENT_ID`). */
|
|
1069
|
+
readonly agentId: string | undefined;
|
|
1070
|
+
/** Post a message, task or task status to a channel (`agents:send`). One Event per message. */
|
|
1071
|
+
send(input: SendAgentMessageInput): Promise<SendAgentMessageResult>;
|
|
1072
|
+
/** The agent's unacked messages, oldest first (`agents:read`). */
|
|
1073
|
+
inbox(agentId?: string, options?: AgentInboxOptions): Promise<AgentInboxPage>;
|
|
1074
|
+
/** Acknowledge inbox messages so they leave the inbox (`agents:read`). */
|
|
1075
|
+
ack(agentId: string | undefined, input: AgentAckInput): Promise<AgentAckResult>;
|
|
1076
|
+
/**
|
|
1077
|
+
* Read the inbox in a loop, call `handler` for each message (oldest
|
|
1078
|
+
* first) and ack it once the handler resolves. Errors back off
|
|
1079
|
+
* exponentially; the failed message isn't acked, so it comes back. 400,
|
|
1080
|
+
* 401, 403 and 404 stop the loop (the returned promise rejects): retrying
|
|
1081
|
+
* can't fix a wrong key, scope or agent. Resolves when `signal` aborts.
|
|
1082
|
+
*/
|
|
1083
|
+
poll(agentId: string | undefined, handler: AgentMessageHandler, options?: AgentPollOptions): Promise<void>;
|
|
1084
|
+
/** The organization's agents (`agents:read`). */
|
|
1085
|
+
list(options?: {
|
|
1086
|
+
includeRetired?: boolean;
|
|
1087
|
+
}): Promise<Agent[]>;
|
|
1088
|
+
/** One agent (`agents:read`); an `agents:admin` key also gets the detail. */
|
|
1089
|
+
get(agentId: string): Promise<AgentDetail>;
|
|
1090
|
+
channels: {
|
|
1091
|
+
/** Channels the key's agents are members or observers of (all of them for an `agents:admin` key). */
|
|
1092
|
+
list(options?: {
|
|
1093
|
+
includeArchived?: boolean;
|
|
1094
|
+
}): Promise<AgentChannel[]>;
|
|
1095
|
+
/** A channel and its members. */
|
|
1096
|
+
get(channelId: string, options?: AgentChannelReadOptions): Promise<{
|
|
1097
|
+
channel: AgentChannel;
|
|
1098
|
+
members: AgentChannelMember[];
|
|
1099
|
+
}>;
|
|
1100
|
+
/** A channel's members and roles. */
|
|
1101
|
+
members(channelId: string, options?: AgentChannelReadOptions): Promise<AgentChannelMember[]>;
|
|
1102
|
+
/** A channel's messages: newest first with `cursor`, or newer than `after` (polling). */
|
|
1103
|
+
messages(channelId: string, options?: AgentChannelFeedOptions): Promise<AgentChannelFeed>;
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Channlize for Agents client. Reads the key from `CHANNLIZE_SERVER_API_KEY`
|
|
1108
|
+
* or `CHANNLIZE_API_KEY`, and the default agent from `CHANNLIZE_AGENT_ID`,
|
|
1109
|
+
* unless given. Server-side only: never ship an agent key to a browser.
|
|
1110
|
+
*
|
|
1111
|
+
* ```ts
|
|
1112
|
+
* const agents = createAgentsClient({ agentId: process.env.CHANNLIZE_AGENT_ID });
|
|
1113
|
+
* await agents.send({ channel: channelId, text: 'Deploy finished' });
|
|
1114
|
+
* ```
|
|
1115
|
+
*/
|
|
1116
|
+
declare function createAgentsClient(config?: AgentsClientConfig): AgentsClient;
|
|
1117
|
+
/**
|
|
1118
|
+
* Checks the `X-Webhook-Signature` header of a webhook agent delivery:
|
|
1119
|
+
* `sha256=<hex HMAC-SHA256 of the raw body>`, keyed with the agent's secret
|
|
1120
|
+
* (shown once when the agent is created or its secret rotated).
|
|
1121
|
+
*
|
|
1122
|
+
* Pass the body **exactly as received** (a string or bytes), before any JSON
|
|
1123
|
+
* parsing: re-serializing changes the bytes and the signature no longer
|
|
1124
|
+
* matches. The comparison is constant-time (Web Crypto `verify`). Uses
|
|
1125
|
+
* `globalThis.crypto.subtle`, or `node:crypto`'s `webcrypto` on Node.js 18.
|
|
1126
|
+
*
|
|
1127
|
+
* ```ts
|
|
1128
|
+
* const raw = await req.text();
|
|
1129
|
+
* if (!(await verifyAgentWebhook(raw, req.headers.get('x-webhook-signature'), secret))) {
|
|
1130
|
+
* return new Response('bad signature', { status: 401 });
|
|
1131
|
+
* }
|
|
1132
|
+
* const payload = JSON.parse(raw) as AgentWebhookPayload;
|
|
1133
|
+
* ```
|
|
1134
|
+
*/
|
|
1135
|
+
declare function verifyAgentWebhook(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<boolean>;
|
|
1136
|
+
/**
|
|
1137
|
+
* `verifyAgentWebhook`, then the parsed `agent.message` payload. Throws a
|
|
1138
|
+
* 401 `ChannlizeError` (`INVALID_SIGNATURE`) when the signature doesn't
|
|
1139
|
+
* match. A webhook agent that asks humans (or manages agents) also gets
|
|
1140
|
+
* question events: use `parseAgentWebhookEvent` for those.
|
|
1141
|
+
*/
|
|
1142
|
+
declare function parseAgentWebhook(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<AgentWebhookPayload>;
|
|
1143
|
+
/**
|
|
1144
|
+
* `verifyAgentWebhook`, then any webhook body: `agent.message`,
|
|
1145
|
+
* `question.answered` / `question.expired` / `question.canceled` or
|
|
1146
|
+
* `question.escalated` (the `X-Webhook-Event` header). Narrow it with
|
|
1147
|
+
* `isAgentMessageWebhook`, `isQuestionOutcomeWebhook` and
|
|
1148
|
+
* `isQuestionEscalatedWebhook`.
|
|
1149
|
+
*/
|
|
1150
|
+
declare function parseAgentWebhookEvent(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<AgentWebhookEvent>;
|
|
1151
|
+
|
|
1152
|
+
/**
|
|
1153
|
+
* Helpers shared by `@channlize/core`, `@channlize/react` and
|
|
1154
|
+
* `@channlize/mcp`: defaults, key detection, environment variables, event
|
|
1155
|
+
* keys and the API's error shape. Core is the single source for these.
|
|
1156
|
+
*/
|
|
1157
|
+
/** Default API base URL. */
|
|
1158
|
+
declare const DEFAULT_BASE_URL = "https://api.channlize.com";
|
|
1159
|
+
/** Default request timeout, in milliseconds. */
|
|
1160
|
+
declare const DEFAULT_TIMEOUT = 10000;
|
|
1161
|
+
/** Log tracking severities, lowest first. */
|
|
1162
|
+
declare const EVENT_SEVERITIES: readonly ["info", "warning", "error"];
|
|
1163
|
+
/**
|
|
1164
|
+
* Valid Events key (same rule as the API): lowercase letters, digits,
|
|
1165
|
+
* dots, underscores and dashes, e.g. `user.subscribed`. At most 100
|
|
1166
|
+
* characters.
|
|
1167
|
+
*/
|
|
1168
|
+
declare const EVENT_KEY_PATTERN: RegExp;
|
|
1169
|
+
/** Whether `event` is a valid Events key for `notify`. */
|
|
1170
|
+
declare function isValidEventKey(event: unknown): event is string;
|
|
1171
|
+
type KeyKind = 'widget' | 'server';
|
|
1172
|
+
/**
|
|
1173
|
+
* `wk_…` is the public widget key (browser: contact form, chat, browser
|
|
1174
|
+
* log tracking); anything else is a server API key (`ch_live_…`).
|
|
1175
|
+
*/
|
|
1176
|
+
declare function keyKind(key: string): KeyKind;
|
|
1177
|
+
/** The `CHANNLIZE_*` environment variables, trimmed (empty → undefined). */
|
|
1178
|
+
interface ChannlizeEnv {
|
|
1179
|
+
/** `CHANNLIZE_SERVER_API_KEY` */
|
|
1180
|
+
serverApiKey?: string;
|
|
1181
|
+
/** `CHANNLIZE_WIDGET_KEY` */
|
|
1182
|
+
widgetKey?: string;
|
|
1183
|
+
/** `CHANNLIZE_API_KEY` (either kind of key) */
|
|
1184
|
+
apiKey?: string;
|
|
1185
|
+
/** `CHANNLIZE_PROJECT_ID` */
|
|
1186
|
+
projectId?: string;
|
|
1187
|
+
/** `CHANNLIZE_BASE_URL` */
|
|
1188
|
+
baseUrl?: string;
|
|
1189
|
+
/** `CHANNLIZE_TIMEOUT` (milliseconds, unparsed) */
|
|
1190
|
+
timeout?: string;
|
|
1191
|
+
/** `CHANNLIZE_AGENT_ID` (Channlize for Agents: the agent to act as) */
|
|
1192
|
+
agentId?: string;
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Reads the `CHANNLIZE_*` environment variables. Safe in browsers and edge
|
|
1196
|
+
* runtimes without `process` (everything is undefined there).
|
|
1197
|
+
*/
|
|
1198
|
+
declare function readChannlizeEnv(env?: Record<string, string | undefined> | undefined): ChannlizeEnv;
|
|
1199
|
+
/** A failed API response, parsed from its JSON body. */
|
|
1200
|
+
interface ApiErrorInfo {
|
|
1201
|
+
status: number;
|
|
1202
|
+
/** Human-readable text (field messages joined with `, `). */
|
|
1203
|
+
message: string;
|
|
1204
|
+
/** Machine-readable code: the body's `code`, else its `error` (e.g. `NOT_FOUND`). */
|
|
1205
|
+
code?: string;
|
|
1206
|
+
/** `requestId` from the body, to quote to support. */
|
|
1207
|
+
requestId?: string;
|
|
1208
|
+
/** The parsed body (e.g. `limit`, `used`, `resetAt` on a plan-limit 429). */
|
|
1209
|
+
body: Record<string, unknown>;
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Parses the API's error shape (`api/lib/api/error.ts`):
|
|
1213
|
+
* `{ statusCode, error: "NOT_FOUND", message: string | string[], requestId? }`.
|
|
1214
|
+
* A few legacy routes put the human text in `error`.
|
|
1215
|
+
*/
|
|
1216
|
+
declare function parseApiError(status: number, body: unknown, statusText?: string): ApiErrorInfo;
|
|
1217
|
+
|
|
1
1218
|
/**
|
|
2
1219
|
* Core types for Channlize SDK
|
|
3
1220
|
*/
|
|
1221
|
+
|
|
4
1222
|
/** Severity for log tracking (`trackEvent` / `trackServerEvent`); Slack alerts use project settings. */
|
|
5
|
-
type EventSeverity =
|
|
1223
|
+
type EventSeverity = (typeof EVENT_SEVERITIES)[number];
|
|
6
1224
|
/** Options for log tracking (`trackEvent` / `trackServerEvent`). */
|
|
7
1225
|
interface TrackEventOptions {
|
|
8
1226
|
properties?: Record<string, unknown>;
|
|
@@ -105,11 +1323,15 @@ interface ChatMessage {
|
|
|
105
1323
|
id: string;
|
|
106
1324
|
/** Message content */
|
|
107
1325
|
content: string;
|
|
108
|
-
/**
|
|
1326
|
+
/**
|
|
1327
|
+
* Message timestamp. The API sends an ISO 8601 string, which
|
|
1328
|
+
* `ChannlizeClient` passes through as is; `@channlize/react` converts it
|
|
1329
|
+
* to a `Date`. Wrap it in `new Date(...)` before using `Date` methods.
|
|
1330
|
+
*/
|
|
109
1331
|
timestamp: Date;
|
|
110
1332
|
/** Message author (user or agent) */
|
|
111
1333
|
author: 'user' | 'agent';
|
|
112
|
-
/** Author metadata */
|
|
1334
|
+
/** Author metadata (`name` / `email` can be `null` in message history) */
|
|
113
1335
|
authorData?: {
|
|
114
1336
|
name?: string;
|
|
115
1337
|
email?: string;
|
|
@@ -133,15 +1355,23 @@ interface FileAttachment {
|
|
|
133
1355
|
interface ChatSession {
|
|
134
1356
|
/** Session ID */
|
|
135
1357
|
id: string;
|
|
136
|
-
/**
|
|
1358
|
+
/**
|
|
1359
|
+
* Session status. `createChatSession` answers `active`; `getChatSession`
|
|
1360
|
+
* and `closeChatSession` answer the conversation's status (`open`,
|
|
1361
|
+
* `pending`, `resolved` or `closed`).
|
|
1362
|
+
*/
|
|
137
1363
|
status: 'active' | 'closed' | 'waiting';
|
|
138
|
-
/**
|
|
1364
|
+
/**
|
|
1365
|
+
* Messages in the session. Only `createChatSession` returns it (empty);
|
|
1366
|
+
* `getChatSession`, `closeChatSession` and `sendMessage` return a session
|
|
1367
|
+
* summary without it. Load history with `getChatMessages`.
|
|
1368
|
+
*/
|
|
139
1369
|
messages: ChatMessage[];
|
|
140
1370
|
/** Session metadata */
|
|
141
1371
|
metadata?: Record<string, unknown>;
|
|
142
|
-
/** Created timestamp */
|
|
1372
|
+
/** Created timestamp (an ISO 8601 string on the wire; not sent by `closeChatSession`) */
|
|
143
1373
|
createdAt: Date;
|
|
144
|
-
/** Updated timestamp */
|
|
1374
|
+
/** Updated timestamp (an ISO 8601 string on the wire) */
|
|
145
1375
|
updatedAt: Date;
|
|
146
1376
|
}
|
|
147
1377
|
interface ApiResponse<T = unknown> {
|
|
@@ -178,7 +1408,7 @@ interface CreateChatSessionResponse {
|
|
|
178
1408
|
interface SendMessageResponse {
|
|
179
1409
|
/** The sent message */
|
|
180
1410
|
message: ChatMessage;
|
|
181
|
-
/**
|
|
1411
|
+
/** The session (the API sends only `id` and `status`) */
|
|
182
1412
|
session: ChatSession;
|
|
183
1413
|
}
|
|
184
1414
|
/**
|
|
@@ -187,6 +1417,19 @@ interface SendMessageResponse {
|
|
|
187
1417
|
declare class ChannlizeError extends Error {
|
|
188
1418
|
statusCode?: number | undefined;
|
|
189
1419
|
code?: string | undefined;
|
|
1420
|
+
/** The API's `requestId` for a failed response, to quote to support. */
|
|
1421
|
+
requestId?: string;
|
|
1422
|
+
/**
|
|
1423
|
+
* The API's JSON error body, e.g. `limit`, `used`, `resetAt` and
|
|
1424
|
+
* `upgradeUrl` on a plan-limit 429. Undefined for network errors.
|
|
1425
|
+
*/
|
|
1426
|
+
details?: Record<string, unknown>;
|
|
1427
|
+
/**
|
|
1428
|
+
* ISO time the call may succeed again: the body's `retryAt` (agent
|
|
1429
|
+
* policies, human takeovers), else derived from a `Retry-After` header.
|
|
1430
|
+
* See `retryAfter(error)`.
|
|
1431
|
+
*/
|
|
1432
|
+
retryAt?: string;
|
|
190
1433
|
constructor(message: string, statusCode?: number | undefined, code?: string | undefined);
|
|
191
1434
|
}
|
|
192
1435
|
declare class ValidationError extends ChannlizeError {
|
|
@@ -196,8 +1439,25 @@ declare class ValidationError extends ChannlizeError {
|
|
|
196
1439
|
declare class AuthenticationError extends ChannlizeError {
|
|
197
1440
|
constructor(message?: string);
|
|
198
1441
|
}
|
|
1442
|
+
/**
|
|
1443
|
+
* A 429. `code` is `PLAN_LIMIT_REACHED` when the organization is past its
|
|
1444
|
+
* plan's limit for the billing period (the API's 110 % hard cap), else
|
|
1445
|
+
* `RATE_LIMIT_ERROR`.
|
|
1446
|
+
*/
|
|
199
1447
|
declare class RateLimitError extends ChannlizeError {
|
|
200
|
-
constructor(message?: string);
|
|
1448
|
+
constructor(message?: string, code?: string);
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* What `trackEvent` / `trackServerEvent` resolve with. When the API refuses
|
|
1452
|
+
* the event with a 429 (rate limit or plan limit), the call resolves with
|
|
1453
|
+
* `success: false` and `dropped` instead of throwing: log tracking never
|
|
1454
|
+
* breaks the app that calls it.
|
|
1455
|
+
*/
|
|
1456
|
+
interface TrackEventResult {
|
|
1457
|
+
success: boolean;
|
|
1458
|
+
id: string;
|
|
1459
|
+
/** Set when the event was refused and not stored. */
|
|
1460
|
+
dropped?: 'plan_limit' | 'rate_limit';
|
|
201
1461
|
}
|
|
202
1462
|
|
|
203
1463
|
/**
|
|
@@ -211,6 +1471,13 @@ declare class ChannlizeClient<TEvents extends object = ChannlizeEvents> {
|
|
|
211
1471
|
private readonly config;
|
|
212
1472
|
constructor(config: ChannlizeConfig);
|
|
213
1473
|
private validateConfig;
|
|
1474
|
+
private agentsClient?;
|
|
1475
|
+
/**
|
|
1476
|
+
* Channlize for Agents (`agents.send`, `agents.inbox`, `agents.poll`, ...),
|
|
1477
|
+
* authenticated with `serverApiKey`: an agent key or a multi-agent key.
|
|
1478
|
+
* Same as `createAgentsClient({ apiKey: serverApiKey, baseUrl, timeout })`.
|
|
1479
|
+
*/
|
|
1480
|
+
get agents(): AgentsClient;
|
|
214
1481
|
private makeRequest;
|
|
215
1482
|
/**
|
|
216
1483
|
* Submit a contact form
|
|
@@ -242,10 +1509,8 @@ declare class ChannlizeClient<TEvents extends object = ChannlizeEvents> {
|
|
|
242
1509
|
* Log tracking: record a log line from the browser (widget key →
|
|
243
1510
|
* `POST /public/events`). Shown under Log tracking in the dashboard.
|
|
244
1511
|
*/
|
|
245
|
-
trackEvent(name: string, options?: TrackEventOptions): Promise<
|
|
246
|
-
|
|
247
|
-
id: string;
|
|
248
|
-
}>;
|
|
1512
|
+
trackEvent(name: string, options?: TrackEventOptions): Promise<TrackEventResult>;
|
|
1513
|
+
private sendBrowserEvent;
|
|
249
1514
|
/**
|
|
250
1515
|
* Log tracking from a trusted server, using the organization API key
|
|
251
1516
|
* (`POST /v1/events`). Shown under Log tracking in the dashboard.
|
|
@@ -253,10 +1518,15 @@ declare class ChannlizeClient<TEvents extends object = ChannlizeEvents> {
|
|
|
253
1518
|
trackServerEvent(name: string, options?: {
|
|
254
1519
|
properties?: Record<string, unknown>;
|
|
255
1520
|
severity?: EventSeverity;
|
|
256
|
-
}): Promise<
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
1521
|
+
}): Promise<TrackEventResult>;
|
|
1522
|
+
/**
|
|
1523
|
+
* Log tracking must never break the caller: a 429 (rate limit, or the
|
|
1524
|
+
* plan's limit for the billing period) resolves with `success: false`
|
|
1525
|
+
* and `dropped` instead of throwing, with one console warning per client.
|
|
1526
|
+
*/
|
|
1527
|
+
private nonFatalTracking;
|
|
1528
|
+
private warnedDropped;
|
|
1529
|
+
private sendServerEvent;
|
|
260
1530
|
/**
|
|
261
1531
|
* Events: post a Slack message from your server when something happens
|
|
262
1532
|
* (`POST /v1/notify`). The event key picks the channel and message
|
|
@@ -284,5 +1554,71 @@ type Notifier<TEvents extends object = ChannlizeEvents> = <K extends NotifyEvent
|
|
|
284
1554
|
*/
|
|
285
1555
|
declare function createNotifier<TEvents extends object = ChannlizeEvents>(config?: NotifierConfig): Notifier<TEvents>;
|
|
286
1556
|
|
|
287
|
-
|
|
288
|
-
|
|
1557
|
+
/**
|
|
1558
|
+
* Channlize for Agents: typed errors for the policy, takeover, loop-guard,
|
|
1559
|
+
* task and question refusals of the `/v1/agents` API, and the
|
|
1560
|
+
* `isRetryable` / `retryAfter` helpers. `requestJson` (`http.ts`) picks the
|
|
1561
|
+
* class from the error body's `code`.
|
|
1562
|
+
*/
|
|
1563
|
+
|
|
1564
|
+
/** The policy refusal codes (`api/lib/agents/policy.ts`, `POLICY_CODES`). */
|
|
1565
|
+
declare const AGENT_POLICY_CODES: readonly ["POLICY_CHANNEL_NOT_ALLOWED", "POLICY_DM_NOT_ALLOWED", "POLICY_ASK_HUMAN_NOT_ALLOWED", "POLICY_URGENCY_NOT_ALLOWED", "POLICY_RATE_LIMITED", "POLICY_BUDGET_EXHAUSTED", "POLICY_OUTSIDE_WORKING_HOURS", "POLICY_MAX_DEPTH"];
|
|
1566
|
+
type AgentPolicyCode = (typeof AGENT_POLICY_CODES)[number];
|
|
1567
|
+
/** Why the loop guard paused a thread (`details.reason` of `AGENT_THREAD_PAUSED`). */
|
|
1568
|
+
type AgentThreadPauseReason = 'thread_cap' | 'ping_pong' | 'duplicate_content';
|
|
1569
|
+
/** The task refusals: 409 `TASK_CLOSED`, `ALREADY_ASSIGNED`, `AGENT_NOT_IN_CHANNEL`; 403 `NOT_TASK_PARTICIPANT`. */
|
|
1570
|
+
declare const AGENT_TASK_ERROR_CODES: readonly ["TASK_CLOSED", "ALREADY_ASSIGNED", "AGENT_NOT_IN_CHANNEL", "NOT_TASK_PARTICIPANT"];
|
|
1571
|
+
type AgentTaskErrorCode = (typeof AGENT_TASK_ERROR_CODES)[number];
|
|
1572
|
+
/**
|
|
1573
|
+
* An agent policy refused the call (403, or 429 for rate limits and
|
|
1574
|
+
* budgets). `retryAt` is set when waiting helps: rate limits, budgets (the
|
|
1575
|
+
* next period) and working hours (the next window). Without it, retrying
|
|
1576
|
+
* can't succeed: the policy forbids the channel, the DM, the urgency or
|
|
1577
|
+
* asking at all.
|
|
1578
|
+
*/
|
|
1579
|
+
declare class AgentPolicyError extends ChannlizeError {
|
|
1580
|
+
constructor(message: string, statusCode: number, code: AgentPolicyCode | (string & {}), retryAt?: string);
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* 409 `HUMAN_TAKEOVER`: a person replied in the thread, so its agents stay
|
|
1584
|
+
* out of it until `retryAt` (the policy's `humans_win_minutes`), or until
|
|
1585
|
+
* an admin resumes the thread.
|
|
1586
|
+
*/
|
|
1587
|
+
declare class HumanTakeoverError extends ChannlizeError {
|
|
1588
|
+
constructor(message: string, retryAt?: string);
|
|
1589
|
+
}
|
|
1590
|
+
/**
|
|
1591
|
+
* 429 `AGENT_THREAD_PAUSED`: the loop guard paused the thread (`reason`:
|
|
1592
|
+
* the thread cap, two agents ping-ponging, or duplicate content). A
|
|
1593
|
+
* person's reply or an admin resumes it; else the pause ends after
|
|
1594
|
+
* `Retry-After` (an hour). Still a `RateLimitError`.
|
|
1595
|
+
*/
|
|
1596
|
+
declare class AgentThreadPausedError extends RateLimitError {
|
|
1597
|
+
reason: AgentThreadPauseReason | (string & {});
|
|
1598
|
+
constructor(message: string, reason?: AgentThreadPauseReason | (string & {}));
|
|
1599
|
+
}
|
|
1600
|
+
/** A task change the API refused (see `AGENT_TASK_ERROR_CODES`). Retrying doesn't help. */
|
|
1601
|
+
declare class AgentTaskError extends ChannlizeError {
|
|
1602
|
+
constructor(message: string, statusCode: number, code: AgentTaskErrorCode | (string & {}));
|
|
1603
|
+
}
|
|
1604
|
+
/** 409 `QUESTION_CLOSED`: the question was already answered, expired or canceled (the first answer wins). */
|
|
1605
|
+
declare class QuestionClosedError extends ChannlizeError {
|
|
1606
|
+
constructor(message: string);
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Whether retrying the same call later can succeed: network errors and
|
|
1610
|
+
* timeouts, 5xx, 429s (except `PLAN_LIMIT_REACHED`, which lasts the billing
|
|
1611
|
+
* period), and policy refusals or human takeovers that carry a `retryAt`.
|
|
1612
|
+
* Wrong input, scopes, ids, closed tasks and forbidding policies are not.
|
|
1613
|
+
*/
|
|
1614
|
+
declare function isRetryable(error: unknown): boolean;
|
|
1615
|
+
/**
|
|
1616
|
+
* How long to wait before retrying, in milliseconds (0 when the time has
|
|
1617
|
+
* passed), from the error's `retryAt` (the body's `retryAt`, else the
|
|
1618
|
+
* `Retry-After` header). Undefined when the error isn't retryable or names
|
|
1619
|
+
* no time: then pick your own backoff.
|
|
1620
|
+
*/
|
|
1621
|
+
declare function retryAfter(error: unknown, now?: number): number | undefined;
|
|
1622
|
+
|
|
1623
|
+
export { AGENT_DELIVERY_MODES, AGENT_MESSAGE_TYPES, AGENT_POLICY_CODES, AGENT_STATUSES, AGENT_TASK_ERROR_CODES, AGENT_TASK_STATUSES, AgentPolicyError, AgentTaskError, AgentThreadPausedError, AuthenticationError, ChannlizeClient, ChannlizeError, DEFAULT_BASE_URL, DEFAULT_TIMEOUT, EVENT_KEY_PATTERN, EVENT_SEVERITIES, HumanTakeoverError, POLICY_SCOPES, QUESTION_KINDS, QUESTION_STATUSES, QUESTION_URGENCIES, QUESTION_WAIT_MAX_SECONDS, QuestionClosedError, RateLimitError, SENDABLE_AGENT_MESSAGE_TYPES, TASK_BOARD_STATUSES, ValidationError, createAgentsClient, createNotifier, ChannlizeClient as default, isAgentMessageWebhook, isQuestionEscalatedWebhook, isQuestionOutcomeMessage, isQuestionOutcomeWebhook, isRetryable, isTaskHandoffMessage, isValidEventKey, keyKind, parseAgentWebhook, parseAgentWebhookEvent, parseApiError, readChannlizeEnv, retryAfter, verifyAgentWebhook };
|
|
1624
|
+
export type { Agent, AgentAckInput, AgentAckResult, AgentChannel, AgentChannelFeed, AgentChannelFeedOptions, AgentChannelMember, AgentChannelReadOptions, AgentDelivery, AgentDeliveryMode, AgentDeliveryStatus, AgentDetail, AgentInboxItem, AgentInboxOptions, AgentInboxPage, AgentMemberRole, AgentMessage, AgentMessageHandler, AgentMessageSender, AgentMessageType, AgentMirrorConfig, AgentOnboarding, AgentPolicy, AgentPolicyCode, AgentPolicyRules, AgentPollOptions, AgentQuestion, AgentStatus, AgentStatusResult, AgentTask, AgentTaskErrorCode, AgentTaskEvent, AgentTaskStatus, AgentTeam, AgentTeamChannelGrant, AgentTeamDetail, AgentThreadPauseReason, AgentWebhookEvent, AgentWebhookPayload, AgentsClient, AgentsClientConfig, AgentsGovernance, AnswerQuestionInput, ApiErrorInfo, ApiResponse, AskAndWaitOptions, AskAndWaitResult, AskHumanInput, ChannlizeConfig, ChannlizeEnv, ChannlizeEvents, ChatMessage, ChatSession, ContactFormData, CreateChatSessionResponse, CreateContactResponse, CreateTaskInput, CreateTaskResult, CreateTeamInput, EffectivePolicyPreview, EventSeverity, FileAttachment, HandoffTaskInput, HandoffTaskResult, KeyKind, ListQuestionsOptions, ListTasksOptions, Notifier, NotifierConfig, NotifyEventData, NotifyEventName, NotifyOptions, NotifyResponse, OrgChart, OrgChartAgent, OrgChartNode, OrgChartOptions, PolicyCheck, PolicyScope, PolicySource, PutPolicyInput, QuestionAnswer, QuestionEscalatedWebhookPayload, QuestionEscalation, QuestionKind, QuestionOption, QuestionOutcomeData, QuestionOutcomeEvent, QuestionOutcomeWebhookPayload, QuestionPage, QuestionReadOptions, QuestionStatus, QuestionUrgency, SendAgentMessageInput, SendAgentMessageResult, SendMessageResponse, SendableAgentMessageType, SetManagerInput, TaskBoard, TaskBoardOptions, TaskBoardStatus, TaskDeliverySummary, TaskDetail, TaskHandoff, TaskHandoffData, TrackEventOptions, TrackEventResult, UpdateTaskInput, UpdateTaskResult, UpdateTeamInput, WaitQuestionOptions, WaitQuestionResult };
|