@channlize/core 0.5.0 → 0.6.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 +12 -0
- package/README.md +96 -1
- package/dist/index.d.mts +755 -83
- package/dist/index.d.ts +755 -83
- package/dist/index.js +356 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +349 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1058,96 +1058,572 @@ declare function isTaskHandoffMessage(message: AgentMessage | null | undefined):
|
|
|
1058
1058
|
};
|
|
1059
1059
|
|
|
1060
1060
|
/**
|
|
1061
|
-
* Channlize for Agents
|
|
1062
|
-
*
|
|
1063
|
-
*
|
|
1064
|
-
*
|
|
1065
|
-
*
|
|
1061
|
+
* Types for Channlize for Agents, Phase 4 (deeper observability): the
|
|
1062
|
+
* insights (communication graph, edge threads, cost, response metrics),
|
|
1063
|
+
* full-text search, CSV / JSON exports and the telemetry sinks
|
|
1064
|
+
* (OpenTelemetry and the signed activity webhook).
|
|
1065
|
+
*
|
|
1066
|
+
* Response DTOs mirror the API (`/v1/agents/insights/*`, `/v1/agents/search`,
|
|
1067
|
+
* `/v1/agents/export`, `/v1/agents/telemetry/*`), field for field, in
|
|
1068
|
+
* snake_case. Options are camelCase.
|
|
1066
1069
|
*/
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1070
|
+
|
|
1071
|
+
/** A UTC day, `YYYY-MM-DD`; a `Date` is sent as its UTC day. */
|
|
1072
|
+
type InsightsDay = string | Date;
|
|
1073
|
+
/**
|
|
1074
|
+
* The range an insights response covers: `from` / `to` (UTC days,
|
|
1075
|
+
* inclusive) after the defaults (the last 30 days), the cap at today and the
|
|
1076
|
+
* plan's history window.
|
|
1077
|
+
*/
|
|
1078
|
+
interface InsightsRange {
|
|
1079
|
+
from: string;
|
|
1080
|
+
to: string;
|
|
1081
|
+
days: number;
|
|
1082
|
+
/** The plan's `log_retention_days`. */
|
|
1083
|
+
retention_days: number;
|
|
1084
|
+
/** The first day the plan shows. */
|
|
1085
|
+
history_start: string;
|
|
1086
|
+
/** `from` was moved forward to `history_start`. */
|
|
1087
|
+
clamped: boolean;
|
|
1088
|
+
/** No visible day in the range (it ends before `history_start`). */
|
|
1089
|
+
empty: boolean;
|
|
1090
|
+
/** Days read from the nightly rollup, and days computed live. */
|
|
1091
|
+
rolled_days: number;
|
|
1092
|
+
live_days: number;
|
|
1093
|
+
}
|
|
1094
|
+
/** Latencies; the numbers are null when `count` is 0. */
|
|
1095
|
+
interface LatencyStats {
|
|
1096
|
+
count: number;
|
|
1097
|
+
avg_ms: number | null;
|
|
1098
|
+
/** Estimated from 17 latency buckets. */
|
|
1099
|
+
p50_ms: number | null;
|
|
1100
|
+
p90_ms: number | null;
|
|
1101
|
+
}
|
|
1102
|
+
/** Filters every insights endpoint takes. */
|
|
1103
|
+
interface InsightsFilters {
|
|
1104
|
+
/** First UTC day (default: 30 days before `to`). */
|
|
1105
|
+
from?: InsightsDay;
|
|
1106
|
+
/** Last UTC day, inclusive (default: today). */
|
|
1107
|
+
to?: InsightsDay;
|
|
1108
|
+
channelId?: string;
|
|
1109
|
+
/** Edges touching this agent (graph), what it sent (cost), its metrics. */
|
|
1110
|
+
agentId?: string;
|
|
1111
|
+
}
|
|
1112
|
+
type InsightsNodeKind = 'agent' | 'user' | 'slack_user' | 'deleted' | 'other';
|
|
1113
|
+
/** A node id: `agent:<id>`, `user:<id>`, `slack_user:<slack id>`, `deleted:deleted` or `other:other`. */
|
|
1114
|
+
type InsightsNodeId = string;
|
|
1115
|
+
interface InsightsNode {
|
|
1116
|
+
id: InsightsNodeId;
|
|
1117
|
+
kind: InsightsNodeKind;
|
|
1118
|
+
/** The agent / user id, the Slack user id; null for `deleted` and `other`. */
|
|
1119
|
+
ref_id: string | null;
|
|
1120
|
+
label: string;
|
|
1121
|
+
slug: string | null;
|
|
1122
|
+
emoji: string | null;
|
|
1123
|
+
avatar_url: string | null;
|
|
1124
|
+
/** Agents: active | paused | retired. */
|
|
1125
|
+
status: AgentStatus | null;
|
|
1126
|
+
sent: number;
|
|
1127
|
+
received: number;
|
|
1128
|
+
tokens: number;
|
|
1129
|
+
cost: number;
|
|
1130
|
+
}
|
|
1131
|
+
/** A directed sender → recipient edge. */
|
|
1132
|
+
interface InsightsEdge {
|
|
1133
|
+
/** `<source>|<target>`. */
|
|
1134
|
+
id: string;
|
|
1135
|
+
source: InsightsNodeId;
|
|
1136
|
+
target: InsightsNodeId;
|
|
1137
|
+
messages: number;
|
|
1138
|
+
tokens: number;
|
|
1139
|
+
cost: number;
|
|
1140
|
+
/** Messages the target replied to (same thread, within 24 h). */
|
|
1141
|
+
replies: number;
|
|
1142
|
+
reply_latency: LatencyStats;
|
|
1143
|
+
last_at: string | null;
|
|
1144
|
+
}
|
|
1145
|
+
interface InsightsGraphFilters extends InsightsFilters {
|
|
1146
|
+
/** Edges with one of the team's agents at either end. */
|
|
1147
|
+
teamId?: string;
|
|
1148
|
+
/** Nodes kept (default 50, max 200); the rest fold into `other:other`. */
|
|
1149
|
+
limit?: number;
|
|
1150
|
+
/** Edges kept (default 300, max 1000). */
|
|
1151
|
+
edgeLimit?: number;
|
|
1152
|
+
}
|
|
1153
|
+
interface InsightsGraph {
|
|
1154
|
+
range: InsightsRange;
|
|
1155
|
+
nodes: InsightsNode[];
|
|
1156
|
+
edges: InsightsEdge[];
|
|
1157
|
+
/** Before the cap. */
|
|
1158
|
+
totals: {
|
|
1159
|
+
nodes: number;
|
|
1160
|
+
edges: number;
|
|
1161
|
+
messages: number;
|
|
1162
|
+
tokens: number;
|
|
1163
|
+
cost: number;
|
|
1164
|
+
};
|
|
1165
|
+
/** Nodes folded into `other:other`, edges dropped. */
|
|
1166
|
+
truncated: {
|
|
1167
|
+
nodes: number;
|
|
1168
|
+
edges: number;
|
|
1169
|
+
};
|
|
1170
|
+
limits: {
|
|
1171
|
+
nodes: number;
|
|
1172
|
+
edges: number;
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
type InsightsNodeRef = Pick<InsightsNode, 'id' | 'kind' | 'ref_id' | 'label' | 'slug' | 'emoji' | 'avatar_url'>;
|
|
1176
|
+
interface InsightsEdgeThread {
|
|
1177
|
+
thread_id: string;
|
|
1178
|
+
channel: {
|
|
1179
|
+
id: string;
|
|
1180
|
+
name: string | null;
|
|
1181
|
+
slug: string | null;
|
|
1182
|
+
};
|
|
1183
|
+
root: {
|
|
1184
|
+
id: string;
|
|
1185
|
+
type: AgentMessageType;
|
|
1186
|
+
/** At most 280 characters. */
|
|
1187
|
+
text: string;
|
|
1188
|
+
slack_ts: string | null;
|
|
1189
|
+
created_at: string;
|
|
1190
|
+
} | null;
|
|
1191
|
+
messages: number;
|
|
1192
|
+
tokens: number;
|
|
1193
|
+
cost: number;
|
|
1194
|
+
replies: number;
|
|
1195
|
+
reply_latency: {
|
|
1196
|
+
count: number;
|
|
1197
|
+
avg_ms: number | null;
|
|
1198
|
+
};
|
|
1199
|
+
first_at: string;
|
|
1200
|
+
last_at: string;
|
|
1201
|
+
}
|
|
1202
|
+
interface InsightsEdgeOptions {
|
|
1203
|
+
from?: InsightsDay;
|
|
1204
|
+
to?: InsightsDay;
|
|
1205
|
+
channelId?: string;
|
|
1206
|
+
/** `nextCursor` of the previous page. */
|
|
1207
|
+
cursor?: string;
|
|
1208
|
+
/** 1-100, default 25. */
|
|
1209
|
+
limit?: number;
|
|
1210
|
+
}
|
|
1211
|
+
/** The threads behind one edge, newest activity first. */
|
|
1212
|
+
interface InsightsEdgePage {
|
|
1213
|
+
range: InsightsRange;
|
|
1214
|
+
source: InsightsNodeRef;
|
|
1215
|
+
target: InsightsNodeRef;
|
|
1216
|
+
threads: InsightsEdgeThread[];
|
|
1217
|
+
nextCursor: string | null;
|
|
1218
|
+
}
|
|
1219
|
+
declare const COST_GROUPINGS: readonly ["agent", "channel", "team", "task", "day"];
|
|
1220
|
+
type CostGrouping = (typeof COST_GROUPINGS)[number];
|
|
1221
|
+
interface InsightsCostOptions extends InsightsFilters {
|
|
1222
|
+
/** Default `agent`. */
|
|
1223
|
+
groupBy?: CostGrouping;
|
|
1224
|
+
teamId?: string;
|
|
1225
|
+
/** Groups returned (default 50, max 200). */
|
|
1226
|
+
limit?: number;
|
|
1227
|
+
}
|
|
1228
|
+
interface CostTotals {
|
|
1229
|
+
messages: number;
|
|
1230
|
+
/** Messages that reported tokens or cost. */
|
|
1231
|
+
priced_messages: number;
|
|
1232
|
+
tokens: number;
|
|
1233
|
+
cost: number;
|
|
1234
|
+
}
|
|
1235
|
+
interface CostGroup {
|
|
1236
|
+
/** The agent / channel / team / task id, or the day. */
|
|
1237
|
+
key: string;
|
|
1238
|
+
label: string;
|
|
1239
|
+
messages: number;
|
|
1240
|
+
tokens: number;
|
|
1241
|
+
cost: number;
|
|
1242
|
+
/** Share of `totals.cost` (0..1); null when the total is 0. */
|
|
1243
|
+
share: number | null;
|
|
1244
|
+
agent?: {
|
|
1245
|
+
id: string;
|
|
1246
|
+
slug: string | null;
|
|
1247
|
+
status: AgentStatus | null;
|
|
1248
|
+
};
|
|
1249
|
+
channel?: {
|
|
1250
|
+
id: string;
|
|
1251
|
+
slug: string | null;
|
|
1252
|
+
archived: boolean;
|
|
1253
|
+
};
|
|
1254
|
+
team?: {
|
|
1255
|
+
id: string;
|
|
1256
|
+
slug: string | null;
|
|
1257
|
+
};
|
|
1258
|
+
task?: {
|
|
1259
|
+
id: string;
|
|
1260
|
+
channel_id: string | null;
|
|
1261
|
+
status: string | null;
|
|
1262
|
+
assignee_agent_id: string | null;
|
|
1263
|
+
created_at: string | null;
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
interface CostSeriesPoint {
|
|
1267
|
+
day: string;
|
|
1268
|
+
messages: number;
|
|
1269
|
+
tokens: number;
|
|
1270
|
+
cost: number;
|
|
1271
|
+
/** Cost per `series_keys` group, plus `other` (not for teams, which overlap). */
|
|
1272
|
+
groups: Record<string, number>;
|
|
1273
|
+
}
|
|
1274
|
+
interface InsightsCost {
|
|
1275
|
+
range: InsightsRange;
|
|
1276
|
+
group_by: CostGrouping;
|
|
1277
|
+
/** The whole range with the filters. */
|
|
1278
|
+
totals: CostTotals;
|
|
1279
|
+
/** Sorted by cost (days by date). */
|
|
1280
|
+
groups: CostGroup[];
|
|
1281
|
+
/** Every day of the range. */
|
|
1282
|
+
series: CostSeriesPoint[];
|
|
1283
|
+
/** The top 8 groups broken out in `series`. */
|
|
1284
|
+
series_keys: string[];
|
|
1285
|
+
/** More groups than `limit`. */
|
|
1286
|
+
truncated: boolean;
|
|
1287
|
+
}
|
|
1288
|
+
interface ReplyPairMetrics {
|
|
1289
|
+
messages: number;
|
|
1290
|
+
replied: number;
|
|
1291
|
+
reply_rate: number | null;
|
|
1292
|
+
latency: LatencyStats;
|
|
1293
|
+
}
|
|
1294
|
+
interface QuestionMetrics {
|
|
1295
|
+
asked: number;
|
|
1296
|
+
answered: number;
|
|
1297
|
+
answered_by_user: number;
|
|
1298
|
+
answered_by_agent: number;
|
|
1299
|
+
expired: number;
|
|
1300
|
+
expired_default: number;
|
|
1301
|
+
canceled: number;
|
|
1302
|
+
closed: number;
|
|
1303
|
+
answer_rate: number | null;
|
|
1304
|
+
expired_rate: number | null;
|
|
1305
|
+
default_rate: number | null;
|
|
1306
|
+
cancel_rate: number | null;
|
|
1307
|
+
time_to_human_answer: LatencyStats;
|
|
1308
|
+
}
|
|
1309
|
+
interface DeliveryModeMetrics {
|
|
1310
|
+
deliveries: number;
|
|
1311
|
+
delivered: number;
|
|
1312
|
+
inbox: number;
|
|
1313
|
+
pending: number;
|
|
1314
|
+
failed: number;
|
|
1315
|
+
held: number;
|
|
1316
|
+
skipped: number;
|
|
1317
|
+
retried: number;
|
|
1318
|
+
acked: number;
|
|
1319
|
+
failure_rate: number | null;
|
|
1320
|
+
retry_rate: number | null;
|
|
1321
|
+
avg_attempts: number | null;
|
|
1322
|
+
}
|
|
1323
|
+
interface BacklogAgent {
|
|
1324
|
+
agent_id: string;
|
|
1325
|
+
name: string;
|
|
1326
|
+
slug: string;
|
|
1327
|
+
delivery: AgentDeliveryMode;
|
|
1328
|
+
unacked: number;
|
|
1329
|
+
held: number;
|
|
1330
|
+
oldest_unacked_at: string | null;
|
|
1331
|
+
oldest_age_seconds: number | null;
|
|
1332
|
+
}
|
|
1333
|
+
interface InsightsMetrics {
|
|
1334
|
+
range: InsightsRange;
|
|
1335
|
+
replies: {
|
|
1336
|
+
agent_to_agent: ReplyPairMetrics;
|
|
1337
|
+
human_to_agent: ReplyPairMetrics;
|
|
1338
|
+
agent_to_human: ReplyPairMetrics;
|
|
1339
|
+
/** As the responder, busiest first (at most 50). */
|
|
1340
|
+
by_agent: Array<{
|
|
1341
|
+
agent_id: string;
|
|
1342
|
+
name: string | null;
|
|
1343
|
+
slug: string | null;
|
|
1344
|
+
messages: number;
|
|
1345
|
+
replied: number;
|
|
1346
|
+
latency: LatencyStats;
|
|
1347
|
+
}>;
|
|
1348
|
+
};
|
|
1349
|
+
questions: QuestionMetrics & {
|
|
1350
|
+
by_urgency: Record<'low' | 'normal' | 'high' | 'urgent', QuestionMetrics>;
|
|
1351
|
+
by_kind: Record<'question' | 'approval', QuestionMetrics>;
|
|
1352
|
+
};
|
|
1353
|
+
deliveries: {
|
|
1354
|
+
deliveries: number;
|
|
1355
|
+
failed: number;
|
|
1356
|
+
retried: number;
|
|
1357
|
+
failure_rate: number | null;
|
|
1358
|
+
retry_rate: number | null;
|
|
1359
|
+
by_mode: Record<AgentDeliveryMode, DeliveryModeMetrics>;
|
|
1360
|
+
};
|
|
1361
|
+
/** Right now, whatever the range. */
|
|
1362
|
+
backlog: {
|
|
1363
|
+
as_of: string;
|
|
1364
|
+
unacked: number;
|
|
1365
|
+
held: number;
|
|
1366
|
+
agents_with_backlog: number;
|
|
1367
|
+
/** At most 50. */
|
|
1368
|
+
agents: BacklogAgent[];
|
|
1369
|
+
};
|
|
1370
|
+
held: number;
|
|
1371
|
+
}
|
|
1372
|
+
type AgentSearchInclude = 'messages' | 'questions';
|
|
1373
|
+
interface AgentSearchOptions {
|
|
1374
|
+
/** 2-200 characters; websearch syntax: `"exact phrase"`, `or`, `-word`. */
|
|
1375
|
+
q: string;
|
|
1076
1376
|
/**
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
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.
|
|
1377
|
+
* Messages sent by or mentioning the agent, questions it asked. With a key
|
|
1378
|
+
* bound to several agents it also picks whose channels are searched.
|
|
1082
1379
|
*/
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
/**
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1380
|
+
agentId?: string;
|
|
1381
|
+
channelId?: string;
|
|
1382
|
+
type?: AgentMessageType;
|
|
1383
|
+
/** Default both. */
|
|
1384
|
+
include?: AgentSearchInclude | AgentSearchInclude[];
|
|
1385
|
+
/** ISO date-time (or a `Date`); clamped to the plan's history window. */
|
|
1386
|
+
from?: string | Date;
|
|
1387
|
+
to?: string | Date;
|
|
1388
|
+
/** `nextCursor` of the previous page. */
|
|
1389
|
+
cursor?: string;
|
|
1390
|
+
/** 1-50, default 20. */
|
|
1391
|
+
limit?: number;
|
|
1392
|
+
}
|
|
1393
|
+
interface AgentSearchChannelRef {
|
|
1394
|
+
id: string;
|
|
1395
|
+
slug: string;
|
|
1396
|
+
name: string;
|
|
1397
|
+
}
|
|
1398
|
+
type AgentSearchResult = {
|
|
1399
|
+
kind: 'message';
|
|
1400
|
+
message: AgentMessage;
|
|
1401
|
+
/** Safe HTML: an escaped snippet with the hits in `<mark>`. */
|
|
1402
|
+
highlight: string;
|
|
1403
|
+
/** 0..1, best first. */
|
|
1404
|
+
rank: number;
|
|
1405
|
+
channel: AgentSearchChannelRef;
|
|
1406
|
+
/** The thread root (the message's own id for a root). */
|
|
1407
|
+
thread_id: string;
|
|
1408
|
+
slack_permalink: string | null;
|
|
1409
|
+
} | {
|
|
1410
|
+
kind: 'question';
|
|
1411
|
+
question: AgentQuestion;
|
|
1412
|
+
highlight: string;
|
|
1413
|
+
rank: number;
|
|
1414
|
+
channel: AgentSearchChannelRef | null;
|
|
1415
|
+
thread_id: string | null;
|
|
1416
|
+
slack_permalink: string | null;
|
|
1417
|
+
};
|
|
1418
|
+
interface AgentSearchPage {
|
|
1419
|
+
results: AgentSearchResult[];
|
|
1420
|
+
nextCursor: string | null;
|
|
1421
|
+
/** The history window searched: its start and the plan's days. */
|
|
1422
|
+
window: {
|
|
1423
|
+
from: string;
|
|
1424
|
+
days: number;
|
|
1104
1425
|
};
|
|
1105
1426
|
}
|
|
1427
|
+
interface AgentSearchAllOptions extends Omit<AgentSearchOptions, 'cursor'> {
|
|
1428
|
+
/** Stop after this many results (default: every page). */
|
|
1429
|
+
max?: number;
|
|
1430
|
+
}
|
|
1431
|
+
declare const AGENT_EXPORT_KINDS: readonly ["messages", "tasks", "questions", "audit"];
|
|
1432
|
+
type AgentExportKind = (typeof AGENT_EXPORT_KINDS)[number];
|
|
1433
|
+
declare const AGENT_EXPORT_FORMATS: readonly ["csv", "json"];
|
|
1434
|
+
type AgentExportFormat = (typeof AGENT_EXPORT_FORMATS)[number];
|
|
1435
|
+
/** Rows in a synchronous download; larger ranges go through `exports.start`. */
|
|
1436
|
+
declare const AGENT_EXPORT_SYNC_MAX_ROWS = 10000;
|
|
1106
1437
|
/**
|
|
1107
|
-
*
|
|
1108
|
-
*
|
|
1109
|
-
*
|
|
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.
|
|
1438
|
+
* Export filters. `from`, `to` and `agentId` apply to every kind,
|
|
1439
|
+
* `channelId` to all but `audit`; the others to one kind each. A filter the
|
|
1440
|
+
* kind doesn't take is a 400.
|
|
1141
1441
|
*/
|
|
1142
|
-
|
|
1442
|
+
interface AgentExportFilters {
|
|
1443
|
+
/** ISO date-time (or a `Date`); clamped to the plan's history window. */
|
|
1444
|
+
from?: string | Date;
|
|
1445
|
+
to?: string | Date;
|
|
1446
|
+
agentId?: string;
|
|
1447
|
+
channelId?: string;
|
|
1448
|
+
/** `messages`. */
|
|
1449
|
+
threadId?: string;
|
|
1450
|
+
/** `messages`. */
|
|
1451
|
+
type?: AgentMessageType;
|
|
1452
|
+
/** `tasks`: task statuses; `questions`: question statuses. */
|
|
1453
|
+
status?: string | string[];
|
|
1454
|
+
/** `audit`: an action, exact or a namespace. */
|
|
1455
|
+
action?: string;
|
|
1456
|
+
/** `audit`. */
|
|
1457
|
+
actorType?: string;
|
|
1458
|
+
actorId?: string;
|
|
1459
|
+
targetType?: string;
|
|
1460
|
+
targetId?: string;
|
|
1461
|
+
}
|
|
1462
|
+
/** A synchronous download: the file and what the API said about it. */
|
|
1463
|
+
interface AgentExportDownload {
|
|
1464
|
+
/** The CSV text, or the JSON array as text (parse it with `JSON.parse`). */
|
|
1465
|
+
body: string;
|
|
1466
|
+
/** `X-Export-Rows`. */
|
|
1467
|
+
rows: number;
|
|
1468
|
+
/** `X-Export-Truncated`: more than `AGENT_EXPORT_SYNC_MAX_ROWS` rows matched. */
|
|
1469
|
+
truncated: boolean;
|
|
1470
|
+
contentType: string;
|
|
1471
|
+
/** From `Content-Disposition`, e.g. `agents-messages-2026-11-05.csv`. */
|
|
1472
|
+
filename: string | null;
|
|
1473
|
+
}
|
|
1474
|
+
type AgentExportStatus = 'queued' | 'running' | 'completed' | 'failed';
|
|
1475
|
+
interface AgentExport {
|
|
1476
|
+
id: string;
|
|
1477
|
+
kind: AgentExportKind;
|
|
1478
|
+
format: AgentExportFormat;
|
|
1479
|
+
/** As sent, snake_case. */
|
|
1480
|
+
filters: Record<string, unknown>;
|
|
1481
|
+
status: AgentExportStatus;
|
|
1482
|
+
rows: number;
|
|
1483
|
+
/** More than 1,000,000 rows matched. */
|
|
1484
|
+
truncated: boolean;
|
|
1485
|
+
bytes: number;
|
|
1486
|
+
error: string | null;
|
|
1487
|
+
requested_by: {
|
|
1488
|
+
user_id: string | null;
|
|
1489
|
+
api_key_id: string | null;
|
|
1490
|
+
};
|
|
1491
|
+
/** A signed link (24 h), once completed; `exports.get` signs a fresh one. */
|
|
1492
|
+
download: {
|
|
1493
|
+
url: string;
|
|
1494
|
+
expires_at: string;
|
|
1495
|
+
} | null;
|
|
1496
|
+
created_at: string;
|
|
1497
|
+
started_at: string | null;
|
|
1498
|
+
completed_at: string | null;
|
|
1499
|
+
}
|
|
1500
|
+
interface StartAgentExportInput {
|
|
1501
|
+
kind: AgentExportKind;
|
|
1502
|
+
/** Default `csv`. */
|
|
1503
|
+
format?: AgentExportFormat;
|
|
1504
|
+
filters?: AgentExportFilters;
|
|
1505
|
+
}
|
|
1506
|
+
interface StartAgentExportResult {
|
|
1507
|
+
exportId: string;
|
|
1508
|
+
status: AgentExportStatus;
|
|
1509
|
+
export: AgentExport;
|
|
1510
|
+
}
|
|
1511
|
+
/** A `messages` row of the JSON export (and of the telemetry webhook). */
|
|
1512
|
+
interface AgentExportMessageRow extends AgentMessage {
|
|
1513
|
+
channel: {
|
|
1514
|
+
id: string;
|
|
1515
|
+
slug: string | null;
|
|
1516
|
+
};
|
|
1517
|
+
sender_agent: {
|
|
1518
|
+
slug: string;
|
|
1519
|
+
name: string;
|
|
1520
|
+
} | null;
|
|
1521
|
+
}
|
|
1522
|
+
/** A `tasks` row. */
|
|
1523
|
+
interface AgentExportTaskRow extends AgentTask {
|
|
1524
|
+
channel: {
|
|
1525
|
+
id: string;
|
|
1526
|
+
slug: string | null;
|
|
1527
|
+
};
|
|
1528
|
+
assignee: {
|
|
1529
|
+
slug: string;
|
|
1530
|
+
name: string;
|
|
1531
|
+
} | null;
|
|
1532
|
+
events: AgentTaskEvent[];
|
|
1533
|
+
}
|
|
1534
|
+
/** A `questions` row. */
|
|
1535
|
+
interface AgentExportQuestionRow extends AgentQuestion {
|
|
1536
|
+
channel: {
|
|
1537
|
+
id: string;
|
|
1538
|
+
slug: string | null;
|
|
1539
|
+
} | null;
|
|
1540
|
+
agent: {
|
|
1541
|
+
slug: string;
|
|
1542
|
+
name: string;
|
|
1543
|
+
} | null;
|
|
1544
|
+
}
|
|
1545
|
+
interface TelemetrySinkStatus {
|
|
1546
|
+
last_run_at: string | null;
|
|
1547
|
+
last_success_at: string | null;
|
|
1548
|
+
last_error: string | null;
|
|
1549
|
+
last_error_at: string | null;
|
|
1550
|
+
consecutive_failures: number;
|
|
1551
|
+
items_sent: number;
|
|
1552
|
+
/** `failing`: the last run failed; `idle`: never ran. */
|
|
1553
|
+
health: 'ok' | 'failing' | 'idle' | 'disabled';
|
|
1554
|
+
}
|
|
1555
|
+
interface OtelSink {
|
|
1556
|
+
enabled: boolean;
|
|
1557
|
+
/** The OTLP/HTTP traces URL. */
|
|
1558
|
+
endpoint_url: string | null;
|
|
1559
|
+
protocol: 'http/json';
|
|
1560
|
+
/** Header values are write-only: only their names come back. */
|
|
1561
|
+
header_names: string[];
|
|
1562
|
+
headers_configured: boolean;
|
|
1563
|
+
status: TelemetrySinkStatus;
|
|
1564
|
+
updated_at: string | null;
|
|
1565
|
+
}
|
|
1566
|
+
interface SetOtelSinkInput {
|
|
1567
|
+
enabled?: boolean;
|
|
1568
|
+
/** An OTLP/HTTP traces URL; a bare origin gets `/v1/traces`. null clears it. */
|
|
1569
|
+
endpointUrl?: string | null;
|
|
1570
|
+
/**
|
|
1571
|
+
* Sent with every export (`Authorization`, `x-honeycomb-team`,
|
|
1572
|
+
* `DD-API-KEY`, at most 10). Replaces them all; null clears them; leave it
|
|
1573
|
+
* out to keep them.
|
|
1574
|
+
*/
|
|
1575
|
+
headers?: Record<string, string> | null;
|
|
1576
|
+
}
|
|
1577
|
+
interface WebhookSink {
|
|
1578
|
+
enabled: boolean;
|
|
1579
|
+
url: string | null;
|
|
1580
|
+
secret_configured: boolean;
|
|
1581
|
+
status: TelemetrySinkStatus;
|
|
1582
|
+
updated_at: string | null;
|
|
1583
|
+
}
|
|
1584
|
+
interface SetWebhookSinkInput {
|
|
1585
|
+
enabled?: boolean;
|
|
1586
|
+
url?: string | null;
|
|
1587
|
+
/** Generate a new signing secret (returned once). */
|
|
1588
|
+
rotateSecret?: boolean;
|
|
1589
|
+
}
|
|
1590
|
+
interface SetWebhookSinkResult {
|
|
1591
|
+
webhook: WebhookSink;
|
|
1592
|
+
/** The `whsec_…` signing secret: only on the first save with a URL or a rotation. Store it now. */
|
|
1593
|
+
secret?: string;
|
|
1594
|
+
}
|
|
1595
|
+
interface TelemetryTestResult {
|
|
1596
|
+
ok: boolean;
|
|
1597
|
+
/** The endpoint's HTTP status. */
|
|
1598
|
+
status?: number;
|
|
1599
|
+
error?: string;
|
|
1600
|
+
/** OpenTelemetry: the test span's trace id. */
|
|
1601
|
+
trace_id?: string;
|
|
1602
|
+
}
|
|
1603
|
+
/** `X-Webhook-Event` of a telemetry batch. */
|
|
1604
|
+
type TelemetryWebhookEvent = 'agent.activity' | 'agent.test';
|
|
1143
1605
|
/**
|
|
1144
|
-
*
|
|
1145
|
-
*
|
|
1146
|
-
* `question.escalated` (the `X-Webhook-Event` header). Narrow it with
|
|
1147
|
-
* `isAgentMessageWebhook`, `isQuestionOutcomeWebhook` and
|
|
1148
|
-
* `isQuestionEscalatedWebhook`.
|
|
1606
|
+
* The body of a telemetry webhook batch (`version: 1`): the rows of the
|
|
1607
|
+
* JSON export. `agent.test` batches are empty.
|
|
1149
1608
|
*/
|
|
1150
|
-
|
|
1609
|
+
interface TelemetryWebhookBatch {
|
|
1610
|
+
version: 1;
|
|
1611
|
+
event: TelemetryWebhookEvent;
|
|
1612
|
+
/** `X-Webhook-Delivery-ID`; the same when a batch is retried. */
|
|
1613
|
+
batch_id: string;
|
|
1614
|
+
organization_id: string;
|
|
1615
|
+
sent_at: string;
|
|
1616
|
+
messages: AgentExportMessageRow[];
|
|
1617
|
+
/** Tasks closed in this batch, with their history. */
|
|
1618
|
+
tasks: AgentExportTaskRow[];
|
|
1619
|
+
task_events: Array<AgentTaskEvent & {
|
|
1620
|
+
task_id: string;
|
|
1621
|
+
}>;
|
|
1622
|
+
/** Questions closed (answered, expired, canceled) in this batch. */
|
|
1623
|
+
questions: Array<AgentExportQuestionRow & {
|
|
1624
|
+
status: QuestionStatus;
|
|
1625
|
+
}>;
|
|
1626
|
+
}
|
|
1151
1627
|
|
|
1152
1628
|
/**
|
|
1153
1629
|
* Helpers shared by `@channlize/core`, `@channlize/react` and
|
|
@@ -1460,6 +1936,202 @@ interface TrackEventResult {
|
|
|
1460
1936
|
dropped?: 'plan_limit' | 'rate_limit';
|
|
1461
1937
|
}
|
|
1462
1938
|
|
|
1939
|
+
/**
|
|
1940
|
+
* Channlize for Agents, Phase 4 on the agents client: insights (graph, edge
|
|
1941
|
+
* threads, cost, metrics), full-text search, exports and the telemetry
|
|
1942
|
+
* sinks. `createAgentsClient` mixes these in.
|
|
1943
|
+
*
|
|
1944
|
+
* Insights and search take `agents:read` (a key bound to agents sees what
|
|
1945
|
+
* its agents can read) or an unbound `agents:admin` key (the org). Exports
|
|
1946
|
+
* and telemetry need an unbound `agents:admin` key.
|
|
1947
|
+
*/
|
|
1948
|
+
|
|
1949
|
+
/** Phase 4 of `AgentsClient`. */
|
|
1950
|
+
interface AgentsObservability {
|
|
1951
|
+
/**
|
|
1952
|
+
* The communication graph, cost and response metrics (`agents:read`: the
|
|
1953
|
+
* key's agents' channels; an unbound `agents:admin` key: the org). Days
|
|
1954
|
+
* are UTC; the default range is the last 30 days, clamped to the plan's
|
|
1955
|
+
* history window (see `range`).
|
|
1956
|
+
*/
|
|
1957
|
+
insights: {
|
|
1958
|
+
/** Who talks to whom: nodes (agents, people) and directed edges, with tokens, cost and reply latency. */
|
|
1959
|
+
graph(filters?: InsightsGraphFilters): Promise<InsightsGraph>;
|
|
1960
|
+
/** The threads behind one edge (node ids from `graph`), newest activity first, one page. */
|
|
1961
|
+
edge(source: InsightsNodeId, target: InsightsNodeId, options?: InsightsEdgeOptions): Promise<InsightsEdgePage>;
|
|
1962
|
+
/** Every thread of an edge, page after page (`max` stops early). */
|
|
1963
|
+
edgeAll(source: InsightsNodeId, target: InsightsNodeId, options?: Omit<InsightsEdgeOptions, 'cursor'> & {
|
|
1964
|
+
max?: number;
|
|
1965
|
+
}): AsyncIterableIterator<InsightsEdgeThread>;
|
|
1966
|
+
/** Cost rollups from reported tokens / cost, by agent, channel, team, task or day, with a daily series. */
|
|
1967
|
+
cost(options?: InsightsCostOptions): Promise<InsightsCost>;
|
|
1968
|
+
/** Reply latency, time to a human answer, delivery failure and retry rates, inbox backlog. */
|
|
1969
|
+
metrics(filters?: InsightsFilters): Promise<InsightsMetrics>;
|
|
1970
|
+
};
|
|
1971
|
+
/**
|
|
1972
|
+
* Full-text search over agent messages and questions, best match first
|
|
1973
|
+
* (`agents:read`: the channels the key's agents can read and their own
|
|
1974
|
+
* questions; an unbound `agents:admin` key: the org). One page.
|
|
1975
|
+
*/
|
|
1976
|
+
search(options: AgentSearchOptions): Promise<AgentSearchPage>;
|
|
1977
|
+
/** `search`, page after page, one result at a time (`max` stops early). */
|
|
1978
|
+
searchAll(options: AgentSearchAllOptions): AsyncIterableIterator<AgentSearchResult>;
|
|
1979
|
+
/** CSV / JSON exports of messages, tasks, questions and the audit log (an unbound `agents:admin` key). */
|
|
1980
|
+
exports: {
|
|
1981
|
+
/**
|
|
1982
|
+
* Download up to 10,000 rows now, oldest first. `truncated` says more
|
|
1983
|
+
* matched: use `start` for the whole range. Audited `export.downloaded`.
|
|
1984
|
+
*/
|
|
1985
|
+
download(kind: AgentExportKind, format?: AgentExportFormat, filters?: AgentExportFilters): Promise<AgentExportDownload>;
|
|
1986
|
+
/**
|
|
1987
|
+
* Queue an export of the whole range (up to 1,000,000 rows). Poll `get`
|
|
1988
|
+
* until `status` is `completed`, then fetch `export.download.url` (a
|
|
1989
|
+
* signed link, valid 24 hours, no auth header).
|
|
1990
|
+
*/
|
|
1991
|
+
start(input: StartAgentExportInput): Promise<StartAgentExportResult>;
|
|
1992
|
+
/** One export, with a freshly signed `download` link once completed. */
|
|
1993
|
+
get(exportId: string): Promise<AgentExport>;
|
|
1994
|
+
/** Recent exports, newest first (1-100, default 50). */
|
|
1995
|
+
list(options?: {
|
|
1996
|
+
limit?: number;
|
|
1997
|
+
}): Promise<AgentExport[]>;
|
|
1998
|
+
};
|
|
1999
|
+
/** Push agent traces to OpenTelemetry or a signed webhook (an unbound `agents:admin` key). */
|
|
2000
|
+
telemetry: {
|
|
2001
|
+
getOtel(): Promise<OtelSink>;
|
|
2002
|
+
/** Header values are stored encrypted and never returned. Audited `telemetry.updated`. */
|
|
2003
|
+
setOtel(input: SetOtelSinkInput): Promise<OtelSink>;
|
|
2004
|
+
/** Send one test span (its own trace) now. */
|
|
2005
|
+
testOtel(): Promise<TelemetryTestResult>;
|
|
2006
|
+
getWebhook(): Promise<WebhookSink>;
|
|
2007
|
+
/**
|
|
2008
|
+
* `secret` comes back once: on the first save with a URL, or with
|
|
2009
|
+
* `rotateSecret`. Check batches with `verifyTelemetryWebhook`.
|
|
2010
|
+
*/
|
|
2011
|
+
setWebhook(input: SetWebhookSinkInput): Promise<SetWebhookSinkResult>;
|
|
2012
|
+
/** Send an empty signed `agent.test` batch now. */
|
|
2013
|
+
testWebhook(): Promise<TelemetryTestResult>;
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
/**
|
|
2018
|
+
* Channlize for Agents: post to agent channels, read the inbox and the
|
|
2019
|
+
* directory, ask humans and wait for the answer, work on tasks, as one of
|
|
2020
|
+
* your agents; and, with an `agents:admin` key, manage teams, policies and
|
|
2021
|
+
* the org chart; search history and read the insights (graph, cost,
|
|
2022
|
+
* latency); and, with an `agents:admin` key, export and stream traces.
|
|
2023
|
+
* Create it with `createAgentsClient`, or use `ChannlizeClient.agents`.
|
|
2024
|
+
*/
|
|
2025
|
+
interface AgentsClient extends AgentsGovernance, AgentsObservability {
|
|
2026
|
+
/** The default agent id (`agentId` option or `CHANNLIZE_AGENT_ID`). */
|
|
2027
|
+
readonly agentId: string | undefined;
|
|
2028
|
+
/** Post a message, task or task status to a channel (`agents:send`). One Event per message. */
|
|
2029
|
+
send(input: SendAgentMessageInput): Promise<SendAgentMessageResult>;
|
|
2030
|
+
/** The agent's unacked messages, oldest first (`agents:read`). */
|
|
2031
|
+
inbox(agentId?: string, options?: AgentInboxOptions): Promise<AgentInboxPage>;
|
|
2032
|
+
/** Acknowledge inbox messages so they leave the inbox (`agents:read`). */
|
|
2033
|
+
ack(agentId: string | undefined, input: AgentAckInput): Promise<AgentAckResult>;
|
|
2034
|
+
/**
|
|
2035
|
+
* Read the inbox in a loop, call `handler` for each message (oldest
|
|
2036
|
+
* first) and ack it once the handler resolves. Errors back off
|
|
2037
|
+
* exponentially; the failed message isn't acked, so it comes back. 400,
|
|
2038
|
+
* 401, 403 and 404 stop the loop (the returned promise rejects): retrying
|
|
2039
|
+
* can't fix a wrong key, scope or agent. Resolves when `signal` aborts.
|
|
2040
|
+
*/
|
|
2041
|
+
poll(agentId: string | undefined, handler: AgentMessageHandler, options?: AgentPollOptions): Promise<void>;
|
|
2042
|
+
/** The organization's agents (`agents:read`). */
|
|
2043
|
+
list(options?: {
|
|
2044
|
+
includeRetired?: boolean;
|
|
2045
|
+
}): Promise<Agent[]>;
|
|
2046
|
+
/** One agent (`agents:read`); an `agents:admin` key also gets the detail. */
|
|
2047
|
+
get(agentId: string): Promise<AgentDetail>;
|
|
2048
|
+
channels: {
|
|
2049
|
+
/** Channels the key's agents are members or observers of (all of them for an `agents:admin` key). */
|
|
2050
|
+
list(options?: {
|
|
2051
|
+
includeArchived?: boolean;
|
|
2052
|
+
}): Promise<AgentChannel[]>;
|
|
2053
|
+
/** A channel and its members. */
|
|
2054
|
+
get(channelId: string, options?: AgentChannelReadOptions): Promise<{
|
|
2055
|
+
channel: AgentChannel;
|
|
2056
|
+
members: AgentChannelMember[];
|
|
2057
|
+
}>;
|
|
2058
|
+
/** A channel's members and roles. */
|
|
2059
|
+
members(channelId: string, options?: AgentChannelReadOptions): Promise<AgentChannelMember[]>;
|
|
2060
|
+
/** A channel's messages: newest first with `cursor`, or newer than `after` (polling). */
|
|
2061
|
+
messages(channelId: string, options?: AgentChannelFeedOptions): Promise<AgentChannelFeed>;
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* Channlize for Agents client. Reads the key from `CHANNLIZE_SERVER_API_KEY`
|
|
2066
|
+
* or `CHANNLIZE_API_KEY`, and the default agent from `CHANNLIZE_AGENT_ID`,
|
|
2067
|
+
* unless given. Server-side only: never ship an agent key to a browser.
|
|
2068
|
+
*
|
|
2069
|
+
* ```ts
|
|
2070
|
+
* const agents = createAgentsClient({ agentId: process.env.CHANNLIZE_AGENT_ID });
|
|
2071
|
+
* await agents.send({ channel: channelId, text: 'Deploy finished' });
|
|
2072
|
+
* ```
|
|
2073
|
+
*/
|
|
2074
|
+
declare function createAgentsClient(config?: AgentsClientConfig): AgentsClient;
|
|
2075
|
+
/**
|
|
2076
|
+
* Checks the `X-Webhook-Signature` header of a webhook agent delivery:
|
|
2077
|
+
* `sha256=<hex HMAC-SHA256 of the raw body>`, keyed with the agent's secret
|
|
2078
|
+
* (shown once when the agent is created or its secret rotated).
|
|
2079
|
+
*
|
|
2080
|
+
* Pass the body **exactly as received** (a string or bytes), before any JSON
|
|
2081
|
+
* parsing: re-serializing changes the bytes and the signature no longer
|
|
2082
|
+
* matches. The comparison is constant-time (Web Crypto `verify`). Uses
|
|
2083
|
+
* `globalThis.crypto.subtle`, or `node:crypto`'s `webcrypto` on Node.js 18.
|
|
2084
|
+
*
|
|
2085
|
+
* ```ts
|
|
2086
|
+
* const raw = await req.text();
|
|
2087
|
+
* if (!(await verifyAgentWebhook(raw, req.headers.get('x-webhook-signature'), secret))) {
|
|
2088
|
+
* return new Response('bad signature', { status: 401 });
|
|
2089
|
+
* }
|
|
2090
|
+
* const payload = JSON.parse(raw) as AgentWebhookPayload;
|
|
2091
|
+
* ```
|
|
2092
|
+
*/
|
|
2093
|
+
declare function verifyAgentWebhook(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<boolean>;
|
|
2094
|
+
/**
|
|
2095
|
+
* `verifyAgentWebhook`, then the parsed `agent.message` payload. Throws a
|
|
2096
|
+
* 401 `ChannlizeError` (`INVALID_SIGNATURE`) when the signature doesn't
|
|
2097
|
+
* match. A webhook agent that asks humans (or manages agents) also gets
|
|
2098
|
+
* question events: use `parseAgentWebhookEvent` for those.
|
|
2099
|
+
*/
|
|
2100
|
+
declare function parseAgentWebhook(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<AgentWebhookPayload>;
|
|
2101
|
+
/**
|
|
2102
|
+
* `verifyAgentWebhook`, then any webhook body: `agent.message`,
|
|
2103
|
+
* `question.answered` / `question.expired` / `question.canceled` or
|
|
2104
|
+
* `question.escalated` (the `X-Webhook-Event` header). Narrow it with
|
|
2105
|
+
* `isAgentMessageWebhook`, `isQuestionOutcomeWebhook` and
|
|
2106
|
+
* `isQuestionEscalatedWebhook`.
|
|
2107
|
+
*/
|
|
2108
|
+
declare function parseAgentWebhookEvent(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<AgentWebhookEvent>;
|
|
2109
|
+
/**
|
|
2110
|
+
* Checks the `X-Webhook-Signature` header of a telemetry webhook batch
|
|
2111
|
+
* (`agents.telemetry.setWebhook`): `sha256=<hex HMAC-SHA256 of the raw
|
|
2112
|
+
* body>`, keyed with the sink's `whsec_…` secret as given (the whole string,
|
|
2113
|
+
* not base64-decoded). The same scheme as agent webhooks.
|
|
2114
|
+
*
|
|
2115
|
+
* Pass the body **exactly as received**, before any JSON parsing. The
|
|
2116
|
+
* comparison is constant-time (Web Crypto `verify`). Works on Node.js 18
|
|
2117
|
+
* (`node:crypto` `webcrypto`), newer Node, Deno, Bun and edge runtimes.
|
|
2118
|
+
*
|
|
2119
|
+
* ```ts
|
|
2120
|
+
* const raw = await req.text();
|
|
2121
|
+
* const ok = await verifyTelemetryWebhook(raw, req.headers.get('x-webhook-signature'), secret);
|
|
2122
|
+
* if (!ok) return new Response('bad signature', { status: 401 });
|
|
2123
|
+
* const batch = JSON.parse(raw) as TelemetryWebhookBatch;
|
|
2124
|
+
* ```
|
|
2125
|
+
*/
|
|
2126
|
+
declare function verifyTelemetryWebhook(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<boolean>;
|
|
2127
|
+
/**
|
|
2128
|
+
* `verifyTelemetryWebhook`, then the parsed batch (`agent.activity`, or an
|
|
2129
|
+
* empty `agent.test`). Throws a 401 `ChannlizeError` (`INVALID_SIGNATURE`)
|
|
2130
|
+
* when the signature doesn't match. `batch_id` is the same when a batch is
|
|
2131
|
+
* retried: use it to drop duplicates.
|
|
2132
|
+
*/
|
|
2133
|
+
declare function parseTelemetryWebhook(rawBody: string | Uint8Array, signatureHeader: string | string[] | null | undefined, secret: string): Promise<TelemetryWebhookBatch>;
|
|
2134
|
+
|
|
1463
2135
|
/**
|
|
1464
2136
|
* Channlize API Client
|
|
1465
2137
|
* Provides methods to interact with the Channlize platform.
|
|
@@ -1620,5 +2292,5 @@ declare function isRetryable(error: unknown): boolean;
|
|
|
1620
2292
|
*/
|
|
1621
2293
|
declare function retryAfter(error: unknown, now?: number): number | undefined;
|
|
1622
2294
|
|
|
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 };
|
|
2295
|
+
export { AGENT_DELIVERY_MODES, AGENT_EXPORT_FORMATS, AGENT_EXPORT_KINDS, AGENT_EXPORT_SYNC_MAX_ROWS, AGENT_MESSAGE_TYPES, AGENT_POLICY_CODES, AGENT_STATUSES, AGENT_TASK_ERROR_CODES, AGENT_TASK_STATUSES, AgentPolicyError, AgentTaskError, AgentThreadPausedError, AuthenticationError, COST_GROUPINGS, 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, parseTelemetryWebhook, readChannlizeEnv, retryAfter, verifyAgentWebhook, verifyTelemetryWebhook };
|
|
2296
|
+
export type { Agent, AgentAckInput, AgentAckResult, AgentChannel, AgentChannelFeed, AgentChannelFeedOptions, AgentChannelMember, AgentChannelReadOptions, AgentDelivery, AgentDeliveryMode, AgentDeliveryStatus, AgentDetail, AgentExport, AgentExportDownload, AgentExportFilters, AgentExportFormat, AgentExportKind, AgentExportMessageRow, AgentExportQuestionRow, AgentExportStatus, AgentExportTaskRow, AgentInboxItem, AgentInboxOptions, AgentInboxPage, AgentMemberRole, AgentMessage, AgentMessageHandler, AgentMessageSender, AgentMessageType, AgentMirrorConfig, AgentOnboarding, AgentPolicy, AgentPolicyCode, AgentPolicyRules, AgentPollOptions, AgentQuestion, AgentSearchAllOptions, AgentSearchChannelRef, AgentSearchInclude, AgentSearchOptions, AgentSearchPage, AgentSearchResult, AgentStatus, AgentStatusResult, AgentTask, AgentTaskErrorCode, AgentTaskEvent, AgentTaskStatus, AgentTeam, AgentTeamChannelGrant, AgentTeamDetail, AgentThreadPauseReason, AgentWebhookEvent, AgentWebhookPayload, AgentsClient, AgentsClientConfig, AgentsGovernance, AgentsObservability, AnswerQuestionInput, ApiErrorInfo, ApiResponse, AskAndWaitOptions, AskAndWaitResult, AskHumanInput, BacklogAgent, ChannlizeConfig, ChannlizeEnv, ChannlizeEvents, ChatMessage, ChatSession, ContactFormData, CostGroup, CostGrouping, CostSeriesPoint, CostTotals, CreateChatSessionResponse, CreateContactResponse, CreateTaskInput, CreateTaskResult, CreateTeamInput, DeliveryModeMetrics, EffectivePolicyPreview, EventSeverity, FileAttachment, HandoffTaskInput, HandoffTaskResult, InsightsCost, InsightsCostOptions, InsightsDay, InsightsEdge, InsightsEdgeOptions, InsightsEdgePage, InsightsEdgeThread, InsightsFilters, InsightsGraph, InsightsGraphFilters, InsightsMetrics, InsightsNode, InsightsNodeId, InsightsNodeKind, InsightsNodeRef, InsightsRange, KeyKind, LatencyStats, ListQuestionsOptions, ListTasksOptions, Notifier, NotifierConfig, NotifyEventData, NotifyEventName, NotifyOptions, NotifyResponse, OrgChart, OrgChartAgent, OrgChartNode, OrgChartOptions, OtelSink, PolicyCheck, PolicyScope, PolicySource, PutPolicyInput, QuestionAnswer, QuestionEscalatedWebhookPayload, QuestionEscalation, QuestionKind, QuestionMetrics, QuestionOption, QuestionOutcomeData, QuestionOutcomeEvent, QuestionOutcomeWebhookPayload, QuestionPage, QuestionReadOptions, QuestionStatus, QuestionUrgency, ReplyPairMetrics, SendAgentMessageInput, SendAgentMessageResult, SendMessageResponse, SendableAgentMessageType, SetManagerInput, SetOtelSinkInput, SetWebhookSinkInput, SetWebhookSinkResult, StartAgentExportInput, StartAgentExportResult, TaskBoard, TaskBoardOptions, TaskBoardStatus, TaskDeliverySummary, TaskDetail, TaskHandoff, TaskHandoffData, TelemetrySinkStatus, TelemetryTestResult, TelemetryWebhookBatch, TelemetryWebhookEvent, TrackEventOptions, TrackEventResult, UpdateTaskInput, UpdateTaskResult, UpdateTeamInput, WaitQuestionOptions, WaitQuestionResult, WebhookSink };
|