@erdoai/cli 0.109.1 → 0.111.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 +51 -7
  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",
@@ -1141,6 +1149,11 @@ var ErdoClient = class {
1141
1149
  const qs = q.toString();
1142
1150
  return this.request("GET", `/v1/datasets-purposes${qs ? `?${qs}` : ""}`);
1143
1151
  }
1152
+ // Create an empty dataset with its declared columns. The server refuses a
1153
+ // create without a schema unless the purpose's columns are platform-defined.
1154
+ createDataset(input) {
1155
+ return this.request("POST", "/v1/datasets-create", input);
1156
+ }
1144
1157
  ensureDataset(input) {
1145
1158
  return this.request("POST", "/v1/datasets-ensure", input);
1146
1159
  }
@@ -3962,17 +3975,26 @@ agentCmd.command("wait <threadId>").description("Re-attach to a thread's latest
3962
3975
  fail(e);
3963
3976
  }
3964
3977
  });
3965
- 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) => {
3978
+ 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) => {
3966
3979
  try {
3967
3980
  const res = await new ErdoClient().createThread({
3968
3981
  name: opts.name,
3969
- dataset_ids: opts.datasets ? opts.datasets.split(",").map((s) => s.trim()) : void 0
3982
+ dataset_ids: opts.datasets ? opts.datasets.split(",").map((s) => s.trim()) : void 0,
3983
+ visibility: opts.hidden ? "hidden" : void 0
3970
3984
  });
3971
3985
  console.log(res.id);
3972
3986
  } catch (e) {
3973
3987
  fail(e);
3974
3988
  }
3975
3989
  });
3990
+ 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) => {
3991
+ try {
3992
+ await new ErdoClient().deleteThread(threadId);
3993
+ console.log(`deleted ${threadId}`);
3994
+ } catch (e) {
3995
+ fail(e);
3996
+ }
3997
+ });
3976
3998
  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(
3977
3999
  "--order-by <order>",
3978
4000
  "created_at (default) | activity (last message time) \u2014 scope=org/shared only"
@@ -6502,15 +6524,37 @@ datasetsCmd.command("purposes").description(
6502
6524
  fail(e);
6503
6525
  }
6504
6526
  });
6527
+ function readSchemaFile(path) {
6528
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
6529
+ const schema = Array.isArray(parsed) ? { columns: parsed } : parsed;
6530
+ if (!schema || !Array.isArray(schema.columns)) {
6531
+ throw new Error('--schema must contain a JSON columns array or {"columns": [...]} object');
6532
+ }
6533
+ return schema;
6534
+ }
6535
+ datasetsCmd.command("create <name>").description(
6536
+ "Create an empty dataset with its columns declared up front. Every write is checked against the schema, which is set now rather than taken from the first rows. --schema is required unless the purpose is one whose columns Erdo defines (page events, widget events, widget leads)."
6537
+ ).option("--schema <file>", "JSON file containing { columns: [...] } or a columns array").option("--purpose <purpose>", "the dataset's role in the org vocabulary, e.g. leads (see `erdo datasets purposes`)").option("--purpose-description <text>", "what writes and reads this purpose").option("--description <text>", "what the dataset holds").option("--separate", "deliberately create a second dataset for a purpose the org already has").action(async (name, opts) => {
6538
+ try {
6539
+ const result = await new ErdoClient().createDataset({
6540
+ name,
6541
+ ...opts.schema ? { schema: readSchemaFile(opts.schema) } : {},
6542
+ ...opts.purpose ? { purpose: opts.purpose } : {},
6543
+ ...opts.purposeDescription ? { purpose_description: opts.purposeDescription } : {},
6544
+ ...opts.description ? { description: opts.description } : {},
6545
+ ...opts.separate ? { separate_dataset: true } : {}
6546
+ });
6547
+ console.log(`${result.slug} created${result.purpose ? ` ${result.purpose}` : ""}`);
6548
+ for (const warning of result.warnings ?? []) console.error(`warning: ${warning}`);
6549
+ } catch (e) {
6550
+ fail(e);
6551
+ }
6552
+ });
6505
6553
  datasetsCmd.command("ensure <purpose>").description(
6506
6554
  "Create or reuse the one dataset for a purpose and verify its declared producer contract. Refuses legacy splits and incompatible populated datasets instead of choosing silently."
6507
6555
  ).requiredOption("--schema <file>", "JSON file containing { columns: [...] } or a columns array").option("--name <name>", "dataset name when creation is required").option("--description <text>", "dataset description when creation is required").option("--purpose-description <text>", "what writes and reads this purpose").option("--preferred-dataset <slug>", "existing bound dataset slug or id to adopt").option("--email-column <name>", "for a leads purpose: which declared column holds the email (default email)").option("--phone-column <name>", "for a leads purpose: which declared column holds the phone (default phone)").action(async (purpose, opts) => {
6508
6556
  try {
6509
- const parsed = JSON.parse(readFileSync4(opts.schema, "utf8"));
6510
- const declaredSchema = Array.isArray(parsed) ? { columns: parsed } : parsed;
6511
- if (!declaredSchema || !Array.isArray(declaredSchema.columns)) {
6512
- throw new Error('--schema must contain a JSON columns array or {"columns": [...]} object');
6513
- }
6557
+ const declaredSchema = readSchemaFile(opts.schema);
6514
6558
  const result = await new ErdoClient().ensureDataset({
6515
6559
  purpose,
6516
6560
  ...opts.name ? { name: opts.name } : {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erdoai/cli",
3
- "version": "0.109.1",
3
+ "version": "0.111.0",
4
4
  "description": "Erdo CLI — drive datasets, pages, and evals from the terminal or CI",
5
5
  "type": "module",
6
6
  "bin": {