@erdoai/cli 0.110.0 → 0.112.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.
Files changed (2) hide show
  1. package/dist/index.js +68 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1067,6 +1067,14 @@ var ErdoClient = class {
1067
1067
  input
1068
1068
  );
1069
1069
  }
1070
+ async deleteThread(threadID) {
1071
+ try {
1072
+ await this.request("DELETE", `/v1/threads/${encodeURIComponent(threadID)}`);
1073
+ } catch (err) {
1074
+ if (err instanceof ErdoApiError && err.status === 404) return;
1075
+ throw err;
1076
+ }
1077
+ }
1070
1078
  sendMessage(threadID, input) {
1071
1079
  return this.request(
1072
1080
  "POST",
@@ -1285,6 +1293,15 @@ var ErdoClient = class {
1285
1293
  input
1286
1294
  );
1287
1295
  }
1296
+ // Ends the lead's hold or close now, so the engine decides for it again on
1297
+ // its next pass. Answers the hold or close with resumed_at set.
1298
+ resumeLeadNextActions(datasetSlug, lead) {
1299
+ return this.request(
1300
+ "POST",
1301
+ `/v1/datasets/${encodeURIComponent(datasetSlug)}/leads/${encodeURIComponent(lead)}/next-actions/resume`,
1302
+ {}
1303
+ );
1304
+ }
1288
1305
  // Everything the evaluation reads about one lead.
1289
1306
  getLeadTimeline(datasetSlug, lead) {
1290
1307
  return this.request(
@@ -3967,17 +3984,26 @@ agentCmd.command("wait <threadId>").description("Re-attach to a thread's latest
3967
3984
  fail(e);
3968
3985
  }
3969
3986
  });
3970
- agentCmd.command("thread").description("Create a thread; prints its id").option("-n, --name <name>", "thread name").option("-d, --datasets <csv>", "dataset UUIDs to attach").action(async (opts) => {
3987
+ agentCmd.command("thread").description("Create a thread; prints its id").option("-n, --name <name>", "thread name").option("-d, --datasets <csv>", "dataset UUIDs to attach").option("--hidden", "keep the thread out of the organization's thread list (for diagnostic or scripted threads)").action(async (opts) => {
3971
3988
  try {
3972
3989
  const res = await new ErdoClient().createThread({
3973
3990
  name: opts.name,
3974
- dataset_ids: opts.datasets ? opts.datasets.split(",").map((s) => s.trim()) : void 0
3991
+ dataset_ids: opts.datasets ? opts.datasets.split(",").map((s) => s.trim()) : void 0,
3992
+ visibility: opts.hidden ? "hidden" : void 0
3975
3993
  });
3976
3994
  console.log(res.id);
3977
3995
  } catch (e) {
3978
3996
  fail(e);
3979
3997
  }
3980
3998
  });
3999
+ agentCmd.command("delete").description("Permanently delete a thread and its messages (needs admin on the thread: you created it, or you are an org admin)").argument("<threadId>", "thread UUID").action(async (threadId) => {
4000
+ try {
4001
+ await new ErdoClient().deleteThread(threadId);
4002
+ console.log(`deleted ${threadId}`);
4003
+ } catch (e) {
4004
+ fail(e);
4005
+ }
4006
+ });
3981
4007
  agentCmd.command("threads").description("List threads (default: your own; --scope org/shared for organization-wide)").option("-s, --scope <scope>", "own (default) | org | shared \u2014 org/shared require org membership").option(
3982
4008
  "--order-by <order>",
3983
4009
  "created_at (default) | activity (last message time) \u2014 scope=org/shared only"
@@ -7329,7 +7355,7 @@ leadPlaybookCmd.command("revision <revision>").description(
7329
7355
  }
7330
7356
  });
7331
7357
  leadsCmd.command("timeline <dataset> <lead>").description(
7332
- "Show everything the next-action evaluation reads about one lead: captures, sent emails, replies, SMS, calls, website chats, bookings and earlier suggestions in time order, plus the timing facts a follow-up rule matches on. <lead> is the canonical_lead_id UUID or the 22-character lead reference."
7358
+ "Show everything the next-action evaluation reads about one lead: their current and earlier answers, context-only row columns, captures, sent emails, replies, SMS, calls, website chats, bookings and earlier suggestions in time order, plus the timing facts a follow-up rule matches on. <lead> is the canonical_lead_id UUID or the 22-character lead reference."
7333
7359
  ).option("--json", "print the raw JSON result instead of a summary").action(async (dataset, lead, opts) => {
7334
7360
  try {
7335
7361
  const res = await new ErdoClient().getLeadTimeline(dataset, lead);
@@ -7340,6 +7366,31 @@ leadsCmd.command("timeline <dataset> <lead>").description(
7340
7366
  console.log(`lead ${res.canonical_lead_id}`);
7341
7367
  console.log(`reference ${res.lead_reference}`);
7342
7368
  console.log(`dataset ${res.dataset_slug}`);
7369
+ if (res.details?.length) {
7370
+ console.log("\ndetails");
7371
+ printAlignedTable(
7372
+ ["question", "answer", "source", "when", "quote"],
7373
+ res.details.flatMap((detail) => [
7374
+ [detail.label || detail.key, detail.value, detail.source_kind, detail.observed_at, detail.quote ?? ""],
7375
+ ...(detail.earlier ?? []).map((earlier) => [
7376
+ "\u21B3 earlier",
7377
+ earlier.value,
7378
+ earlier.source_kind,
7379
+ earlier.observed_at,
7380
+ earlier.quote ?? ""
7381
+ ])
7382
+ ])
7383
+ );
7384
+ } else {
7385
+ console.log("\nNo lead details.");
7386
+ }
7387
+ if (res.context_columns?.length) {
7388
+ console.log("\ncontext columns (not lead answers)");
7389
+ printAlignedTable(
7390
+ ["column", "value"],
7391
+ res.context_columns.map((column) => [column, res.row?.[column] ?? ""])
7392
+ );
7393
+ }
7343
7394
  if (res.entries?.length) {
7344
7395
  console.log("\nentries");
7345
7396
  printAlignedTable(
@@ -7475,6 +7526,20 @@ leadNextActionsCmd.command("close <dataset> <lead>").description(
7475
7526
  fail(e);
7476
7527
  }
7477
7528
  });
7529
+ leadNextActionsCmd.command("resume <dataset> <lead>").description(
7530
+ "End the lead's hold or close now, so Erdo works the lead again. Nothing is sent from here: Erdo decides for the lead on its next pass, within about fifteen minutes. Refused when the lead is not held or closed."
7531
+ ).option("--json", "print the raw JSON result instead of a summary").action(async (dataset, lead, opts) => {
7532
+ try {
7533
+ const res = await new ErdoClient().resumeLeadNextActions(dataset, lead);
7534
+ if (opts.json) {
7535
+ print(res);
7536
+ return;
7537
+ }
7538
+ console.log(`Resumed lead ${res.lead_reference}: its ${res.action_kind} ended at ${res.resumed_at ?? "now"}. Erdo decides for it on its next pass.`);
7539
+ } catch (e) {
7540
+ fail(e);
7541
+ }
7542
+ });
7478
7543
  leadNextActionsCmd.command("evaluate <dataset> <lead>").description(
7479
7544
  "Dry-run the playbook on one lead: show the decision Erdo would make now, with the email or handoff it would write, the rule it cites and why. Nothing is stored and nothing is sent. --file tries a draft playbook instead of the saved one."
7480
7545
  ).option("-f, --file <path>", "a draft playbook text to evaluate with instead of the saved one").option("--agent-id <id>", "try the draft as that concierge, from `erdo voice agents`; only read alongside --file").option("--json", "print the raw JSON result instead of a summary").action(async (dataset, lead, opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erdoai/cli",
3
- "version": "0.110.0",
3
+ "version": "0.112.0",
4
4
  "description": "Erdo CLI — drive datasets, pages, and evals from the terminal or CI",
5
5
  "type": "module",
6
6
  "bin": {