@erdoai/cli 0.89.0 → 0.91.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +61 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -489,10 +489,15 @@ var ErdoClient = class {
|
|
|
489
489
|
// Phone conversation records: inbound calls to a voice agent's own number and
|
|
490
490
|
// the outbound calls Erdo placed. Website chat widget conversations are a
|
|
491
491
|
// different resource — they live under /v1/voice/widget-conversations.
|
|
492
|
+
// canonical_lead_id narrows to one lead's calls, by its UUID or its lead
|
|
493
|
+
// reference — the same filter every conversation list takes.
|
|
492
494
|
listVoiceCalls(params) {
|
|
493
495
|
const q = new URLSearchParams();
|
|
494
496
|
if (params?.agent) q.set("agent", params.agent);
|
|
495
497
|
if (params?.direction) q.set("direction", params.direction);
|
|
498
|
+
if (params?.since) q.set("since", params.since);
|
|
499
|
+
if (params?.until) q.set("until", params.until);
|
|
500
|
+
if (params?.canonical_lead_id) q.set("canonical_lead_id", params.canonical_lead_id);
|
|
496
501
|
if (params?.limit !== void 0) q.set("limit", String(params.limit));
|
|
497
502
|
if (params?.offset !== void 0) q.set("offset", String(params.offset));
|
|
498
503
|
if (params?.cursor) q.set("cursor", params.cursor);
|
|
@@ -510,6 +515,7 @@ var ErdoClient = class {
|
|
|
510
515
|
if (params?.widget) q.set("widget", params.widget);
|
|
511
516
|
if (params?.since) q.set("since", params.since);
|
|
512
517
|
if (params?.until) q.set("until", params.until);
|
|
518
|
+
if (params?.canonical_lead_id) q.set("canonical_lead_id", params.canonical_lead_id);
|
|
513
519
|
if (params?.limit !== void 0) q.set("limit", String(params.limit));
|
|
514
520
|
if (params?.offset !== void 0) q.set("offset", String(params.offset));
|
|
515
521
|
if (params?.cursor) q.set("cursor", params.cursor);
|
|
@@ -536,6 +542,7 @@ var ErdoClient = class {
|
|
|
536
542
|
const q = new URLSearchParams();
|
|
537
543
|
if (params?.phone_number) q.set("phone_number", params.phone_number);
|
|
538
544
|
if (params?.address) q.set("address", params.address);
|
|
545
|
+
if (params?.canonical_lead_id) q.set("canonical_lead_id", params.canonical_lead_id);
|
|
539
546
|
if (params?.limit !== void 0) q.set("limit", String(params.limit));
|
|
540
547
|
if (params?.cursor) q.set("cursor", params.cursor);
|
|
541
548
|
const qs = q.toString();
|
|
@@ -5215,13 +5222,20 @@ function contactLabel(contact) {
|
|
|
5215
5222
|
function leadStatusLabel(outcome) {
|
|
5216
5223
|
return outcome ? outcome : "pending";
|
|
5217
5224
|
}
|
|
5225
|
+
function leadReferenceLabel(reference) {
|
|
5226
|
+
return reference ? reference : "-";
|
|
5227
|
+
}
|
|
5228
|
+
var LEAD_FILTER_HELP = "only this lead's conversations \u2014 its canonical lead id (UUID) or its 22-character lead reference";
|
|
5218
5229
|
var voiceCallsCmd = voiceCmd.command("calls").description("Inbound and outbound phone call records");
|
|
5219
|
-
voiceCallsCmd.command("list").description("List the organization's phone calls, newest first").option("--agent <slug>", "only calls held by this voice agent, by slug").option("--direction <direction>", "only 'inbound' (calls to the agent's number) or 'outbound'").option("--limit <n>", "page size (default 25, max 100)").option("--offset <n>", "rows to skip").option("--cursor <cursor>", "next_cursor from the preceding page (stable paging)").option("--json", "print the raw JSON result instead of a table").action(
|
|
5230
|
+
voiceCallsCmd.command("list").description("List the organization's phone calls, newest first").option("--agent <slug>", "only calls held by this voice agent, by slug").option("--direction <direction>", "only 'inbound' (calls to the agent's number) or 'outbound'").option("--since <rfc3339>", "only calls that started at or after this time (inclusive)").option("--until <rfc3339>", "only calls that started before this time (exclusive)").option("--lead <lead>", LEAD_FILTER_HELP).option("--limit <n>", "page size (default 25, max 100)").option("--offset <n>", "rows to skip").option("--cursor <cursor>", "next_cursor from the preceding page (stable paging)").option("--json", "print the raw JSON result instead of a table").action(
|
|
5220
5231
|
async (opts) => {
|
|
5221
5232
|
try {
|
|
5222
5233
|
const res = await new ErdoClient().listVoiceCalls({
|
|
5223
5234
|
agent: opts.agent,
|
|
5224
5235
|
direction: opts.direction,
|
|
5236
|
+
since: opts.since,
|
|
5237
|
+
until: opts.until,
|
|
5238
|
+
canonical_lead_id: opts.lead,
|
|
5225
5239
|
limit: opts.limit ? Number(opts.limit) : void 0,
|
|
5226
5240
|
offset: opts.offset ? Number(opts.offset) : void 0,
|
|
5227
5241
|
cursor: opts.cursor
|
|
@@ -5232,7 +5246,14 @@ voiceCallsCmd.command("list").description("List the organization's phone calls,
|
|
|
5232
5246
|
}
|
|
5233
5247
|
const calls = res.conversations ?? [];
|
|
5234
5248
|
if (calls.length === 0) {
|
|
5235
|
-
|
|
5249
|
+
if (res.total > 0) {
|
|
5250
|
+
process.stderr.write(
|
|
5251
|
+
`showing 0 of ${res.total} call(s) \u2014 offset/cursor is past the last one
|
|
5252
|
+
`
|
|
5253
|
+
);
|
|
5254
|
+
} else {
|
|
5255
|
+
console.log("No calls match those filters.");
|
|
5256
|
+
}
|
|
5236
5257
|
return;
|
|
5237
5258
|
}
|
|
5238
5259
|
printAlignedTable(
|
|
@@ -5246,6 +5267,7 @@ voiceCallsCmd.command("list").description("List the organization's phone calls,
|
|
|
5246
5267
|
"transcript",
|
|
5247
5268
|
"contact",
|
|
5248
5269
|
"lead",
|
|
5270
|
+
"lead ref",
|
|
5249
5271
|
"started",
|
|
5250
5272
|
"summary"
|
|
5251
5273
|
],
|
|
@@ -5259,11 +5281,12 @@ voiceCallsCmd.command("list").description("List the organization's phone calls,
|
|
|
5259
5281
|
call.has_transcript ? "yes" : "no",
|
|
5260
5282
|
contactLabel(call.contact),
|
|
5261
5283
|
leadStatusLabel(call.lead_status),
|
|
5284
|
+
leadReferenceLabel(call.lead_reference),
|
|
5262
5285
|
call.created_at,
|
|
5263
5286
|
call.transcript_summary
|
|
5264
5287
|
])
|
|
5265
5288
|
);
|
|
5266
|
-
process.stderr.write(`showing ${calls.length} call(s)
|
|
5289
|
+
process.stderr.write(`showing ${calls.length} of ${res.total} call(s)
|
|
5267
5290
|
`);
|
|
5268
5291
|
if (res.next_cursor) {
|
|
5269
5292
|
process.stderr.write(`more available \u2014 re-run with --cursor ${res.next_cursor}
|
|
@@ -5275,7 +5298,7 @@ voiceCallsCmd.command("list").description("List the organization's phone calls,
|
|
|
5275
5298
|
}
|
|
5276
5299
|
);
|
|
5277
5300
|
voiceCallsCmd.command("get <callID>").description(
|
|
5278
|
-
"Read one phone call in full: transcript, summary, per-turn LLM metrics, and the lead it produced (contact, lead_status, lead_saved_at)"
|
|
5301
|
+
"Read one phone call in full: transcript, summary, per-turn LLM metrics, and the lead it produced (contact, lead_status, lead_saved_at, canonical_lead_id, lead_reference)"
|
|
5279
5302
|
).action(async (callID) => {
|
|
5280
5303
|
try {
|
|
5281
5304
|
print(await new ErdoClient().getVoiceCall(callID));
|
|
@@ -5284,13 +5307,14 @@ voiceCallsCmd.command("get <callID>").description(
|
|
|
5284
5307
|
}
|
|
5285
5308
|
});
|
|
5286
5309
|
var widgetConversationsCmd = voiceCmd.command("widget-conversations").description("Website concierge widget conversations (text, voice and video sessions)");
|
|
5287
|
-
widgetConversationsCmd.command("list").description("List the organization's widget conversations, newest first").option("--widget <handle>", "only this widget's conversations \u2014 its name or public key (vw_...)").option("--since <rfc3339>", "only conversations that started at or after this time (inclusive)").option("--until <rfc3339>", "only conversations that started before this time (exclusive)").option("--limit <n>", "page size (default 25, max 100)").option("--offset <n>", "rows to skip").option("--cursor <cursor>", "next_cursor from the preceding page (stable paging)").option("--json", "print the raw JSON result instead of a table").action(
|
|
5310
|
+
widgetConversationsCmd.command("list").description("List the organization's widget conversations, newest first").option("--widget <handle>", "only this widget's conversations \u2014 its name or public key (vw_...)").option("--since <rfc3339>", "only conversations that started at or after this time (inclusive)").option("--until <rfc3339>", "only conversations that started before this time (exclusive)").option("--lead <lead>", LEAD_FILTER_HELP).option("--limit <n>", "page size (default 25, max 100)").option("--offset <n>", "rows to skip").option("--cursor <cursor>", "next_cursor from the preceding page (stable paging)").option("--json", "print the raw JSON result instead of a table").action(
|
|
5288
5311
|
async (opts) => {
|
|
5289
5312
|
try {
|
|
5290
5313
|
const res = await new ErdoClient().listWidgetConversations({
|
|
5291
5314
|
widget: opts.widget,
|
|
5292
5315
|
since: opts.since,
|
|
5293
5316
|
until: opts.until,
|
|
5317
|
+
canonical_lead_id: opts.lead,
|
|
5294
5318
|
limit: opts.limit ? Number(opts.limit) : void 0,
|
|
5295
5319
|
offset: opts.offset ? Number(opts.offset) : void 0,
|
|
5296
5320
|
cursor: opts.cursor
|
|
@@ -5301,7 +5325,14 @@ widgetConversationsCmd.command("list").description("List the organization's widg
|
|
|
5301
5325
|
}
|
|
5302
5326
|
const conversations = res.conversations ?? [];
|
|
5303
5327
|
if (conversations.length === 0) {
|
|
5304
|
-
|
|
5328
|
+
if (res.total > 0) {
|
|
5329
|
+
process.stderr.write(
|
|
5330
|
+
`showing 0 of ${res.total} conversation(s) \u2014 offset/cursor is past the last one
|
|
5331
|
+
`
|
|
5332
|
+
);
|
|
5333
|
+
} else {
|
|
5334
|
+
console.log("No conversations match those filters.");
|
|
5335
|
+
}
|
|
5305
5336
|
return;
|
|
5306
5337
|
}
|
|
5307
5338
|
printAlignedTable(
|
|
@@ -5313,6 +5344,7 @@ widgetConversationsCmd.command("list").description("List the organization's widg
|
|
|
5313
5344
|
"transcript",
|
|
5314
5345
|
"contact",
|
|
5315
5346
|
"lead",
|
|
5347
|
+
"lead ref",
|
|
5316
5348
|
"started",
|
|
5317
5349
|
"summary"
|
|
5318
5350
|
],
|
|
@@ -5324,6 +5356,7 @@ widgetConversationsCmd.command("list").description("List the organization's widg
|
|
|
5324
5356
|
c.has_transcript ? "yes" : "no",
|
|
5325
5357
|
contactLabel(c.contact),
|
|
5326
5358
|
leadStatusLabel(c.lead_status),
|
|
5359
|
+
leadReferenceLabel(c.lead_reference),
|
|
5327
5360
|
c.created_at,
|
|
5328
5361
|
c.transcript_summary
|
|
5329
5362
|
])
|
|
@@ -5342,7 +5375,7 @@ widgetConversationsCmd.command("list").description("List the organization's widg
|
|
|
5342
5375
|
}
|
|
5343
5376
|
);
|
|
5344
5377
|
widgetConversationsCmd.command("get <sessionID>").description(
|
|
5345
|
-
"Read one widget conversation in full: transcript, summary, topics, per-turn LLM metrics, and the lead it produced (contact, lead_status, lead_saved_at)"
|
|
5378
|
+
"Read one widget conversation in full: transcript, summary, topics, per-turn LLM metrics, and the lead it produced (contact, lead_status, lead_saved_at, canonical_lead_id, lead_reference)"
|
|
5346
5379
|
).option("--widget <handle>", "the widget it belongs to \u2014 optional, the session id identifies it").action(async (sessionID, opts) => {
|
|
5347
5380
|
try {
|
|
5348
5381
|
print(await new ErdoClient().getWidgetConversation(sessionID, opts.widget));
|
|
@@ -5351,12 +5384,13 @@ widgetConversationsCmd.command("get <sessionID>").description(
|
|
|
5351
5384
|
}
|
|
5352
5385
|
});
|
|
5353
5386
|
var voiceSMSCmd = voiceCmd.command("sms").description("Text conversations on a voice agent's own number");
|
|
5354
|
-
voiceSMSCmd.command("list").description("List the organization's SMS conversations, most recently active first").option("--phone-number <number>", "only conversations on this Erdo number (any format)").option("--address <number>", "only the conversation with this person (any format)").option("--limit <n>", "page size (default 25, max 100)").option("--cursor <cursor>", "next_cursor from the preceding page (stable paging)").option("--json", "print the raw JSON result instead of a table").action(
|
|
5387
|
+
voiceSMSCmd.command("list").description("List the organization's SMS conversations, most recently active first").option("--phone-number <number>", "only conversations on this Erdo number (any format)").option("--address <number>", "only the conversation with this person (any format)").option("--lead <lead>", LEAD_FILTER_HELP).option("--limit <n>", "page size (default 25, max 100)").option("--cursor <cursor>", "next_cursor from the preceding page (stable paging)").option("--json", "print the raw JSON result instead of a table").action(
|
|
5355
5388
|
async (opts) => {
|
|
5356
5389
|
try {
|
|
5357
5390
|
const res = await new ErdoClient().listSMSConversations({
|
|
5358
5391
|
phone_number: opts.phoneNumber,
|
|
5359
5392
|
address: opts.address,
|
|
5393
|
+
canonical_lead_id: opts.lead,
|
|
5360
5394
|
limit: opts.limit ? Number(opts.limit) : void 0,
|
|
5361
5395
|
cursor: opts.cursor
|
|
5362
5396
|
});
|
|
@@ -5370,7 +5404,7 @@ voiceSMSCmd.command("list").description("List the organization's SMS conversatio
|
|
|
5370
5404
|
return;
|
|
5371
5405
|
}
|
|
5372
5406
|
printAlignedTable(
|
|
5373
|
-
["session id", "phone", "address", "msgs", "last inbound", "last outbound", "summary"],
|
|
5407
|
+
["session id", "phone", "address", "msgs", "last inbound", "last outbound", "lead ref", "summary"],
|
|
5374
5408
|
conversations.map((c) => [
|
|
5375
5409
|
c.session_id,
|
|
5376
5410
|
c.phone_number,
|
|
@@ -5380,6 +5414,7 @@ voiceSMSCmd.command("list").description("List the organization's SMS conversatio
|
|
|
5380
5414
|
c.message_count,
|
|
5381
5415
|
c.last_inbound_at ?? "",
|
|
5382
5416
|
c.last_outbound_at ?? "",
|
|
5417
|
+
leadReferenceLabel(c.lead_reference),
|
|
5383
5418
|
c.summary
|
|
5384
5419
|
])
|
|
5385
5420
|
);
|
|
@@ -5426,6 +5461,9 @@ voiceSMSCmd.command("get <sessionID>").description("Read one SMS conversation: i
|
|
|
5426
5461
|
console.log(`
|
|
5427
5462
|
contact: ${parts.join(" \xB7 ")}`);
|
|
5428
5463
|
}
|
|
5464
|
+
if (c.lead_reference) {
|
|
5465
|
+
console.log(`lead: ${c.lead_reference} (${c.canonical_lead_id})`);
|
|
5466
|
+
}
|
|
5429
5467
|
const messages = res.messages ?? [];
|
|
5430
5468
|
if (messages.length === 0) {
|
|
5431
5469
|
console.log("\nNo texts have been recorded in this conversation yet.");
|
|
@@ -6290,8 +6328,20 @@ function printLead(lead) {
|
|
|
6290
6328
|
if (lead.captures?.length) {
|
|
6291
6329
|
console.log("\ncaptures");
|
|
6292
6330
|
printAlignedTable(
|
|
6293
|
-
["when", "producer", "resolution", "conversion"],
|
|
6294
|
-
lead.captures.map((c) => [c.created_at, c.producer, c.resolution, c.conversion_status])
|
|
6331
|
+
["when", "producer", "pipeline", "resolution", "conversion"],
|
|
6332
|
+
lead.captures.map((c) => [c.created_at, c.producer, c.pipeline_id ?? "", c.resolution, c.conversion_status])
|
|
6333
|
+
);
|
|
6334
|
+
}
|
|
6335
|
+
if (lead.refused_captures?.length) {
|
|
6336
|
+
console.log("\nrefused captures (this lead was one of the candidates)");
|
|
6337
|
+
printAlignedTable(
|
|
6338
|
+
["when", "pipeline", "resolution", "candidates"],
|
|
6339
|
+
lead.refused_captures.map((c) => [
|
|
6340
|
+
c.created_at,
|
|
6341
|
+
c.pipeline_id ?? "",
|
|
6342
|
+
c.resolution,
|
|
6343
|
+
(c.candidate_lead_ids ?? []).join(", ")
|
|
6344
|
+
])
|
|
6295
6345
|
);
|
|
6296
6346
|
}
|
|
6297
6347
|
if (lead.row) {
|