@erdoai/cli 0.138.0 → 0.139.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 +53 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1327,8 +1327,9 @@ var ErdoClient = class {
|
|
|
1327
1327
|
input
|
|
1328
1328
|
);
|
|
1329
1329
|
}
|
|
1330
|
-
// Cannot be undone. Removes the lead from
|
|
1331
|
-
//
|
|
1330
|
+
// Cannot be undone. Removes the lead from Erdo so the same phone and email
|
|
1331
|
+
// can arrive as a new lead (details captured from conversations stay in the
|
|
1332
|
+
// pipeline's run history). Staff-only, for demos and tests. A
|
|
1332
1333
|
// retry of a delete that stopped part-way resumes it, and a lead already
|
|
1333
1334
|
// deleted answers "already_deleted".
|
|
1334
1335
|
deleteLead(datasetSlug, lead) {
|
|
@@ -1729,6 +1730,9 @@ var ErdoClient = class {
|
|
|
1729
1730
|
listHeartbeats() {
|
|
1730
1731
|
return this.request("GET", "/v1/heartbeats");
|
|
1731
1732
|
}
|
|
1733
|
+
createHeartbeat(body) {
|
|
1734
|
+
return this.request("POST", "/v1/heartbeats", body);
|
|
1735
|
+
}
|
|
1732
1736
|
runHeartbeat(id) {
|
|
1733
1737
|
return this.request("POST", `/v1/heartbeats/${encodeURIComponent(id)}/run`, {});
|
|
1734
1738
|
}
|
|
@@ -7838,7 +7842,7 @@ leadsCmd.command("merge <dataset> <survivor>").description(
|
|
|
7838
7842
|
}
|
|
7839
7843
|
);
|
|
7840
7844
|
leadsCmd.command("delete <dataset> <lead>").description(
|
|
7841
|
-
"Delete a lead from
|
|
7845
|
+
"Delete a lead from Erdo: its row and identity, its text and WhatsApp conversations, its calls and website chats, its emails, and the follow-up engine's decisions about it. The same phone and email submitted again then make a new lead with nothing behind it. This cannot be undone. A staff tool for demos and tests: copies held by providers (message bodies, call audio, sent mail) and in logs stay, and so do opt-outs and the contact details a call, text or chat gave Erdo, in the Conversation leads pipeline's run history. A phone or email another lead in the organization also holds is not released until that lead is deleted too. Read the lead with `leads get` before running it."
|
|
7842
7846
|
).option("-y, --yes", "skip the confirmation prompt").option("--json", "print the raw JSON result instead of a summary").action(async (dataset, lead, opts) => {
|
|
7843
7847
|
try {
|
|
7844
7848
|
if (!opts.yes) {
|
|
@@ -8886,10 +8890,51 @@ knowledgeAssetsCmd.command("list <objectId>").description("List files attached t
|
|
|
8886
8890
|
}
|
|
8887
8891
|
});
|
|
8888
8892
|
var autoCmd = program.command("automations").description("Scheduled automations (heartbeats)");
|
|
8893
|
+
function heartbeatBounds(h) {
|
|
8894
|
+
return `${h.run_at ? ` run_at:${h.run_at}` : ""}${h.ends_at ? ` ends_at:${h.ends_at}` : ""}`;
|
|
8895
|
+
}
|
|
8896
|
+
function scheduleBound(flag, v) {
|
|
8897
|
+
if (v === void 0) return void 0;
|
|
8898
|
+
const value = v.trim();
|
|
8899
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/.test(value) || Number.isNaN(Date.parse(value))) {
|
|
8900
|
+
throw new Error(`${flag} must be an RFC3339 timestamp such as 2026-10-19T09:00:00Z \u2014 got ${JSON.stringify(v)}`);
|
|
8901
|
+
}
|
|
8902
|
+
return value;
|
|
8903
|
+
}
|
|
8904
|
+
autoCmd.command("create <name>").description(
|
|
8905
|
+
"Create an automation. Pass --run-at for one-off work at a date (it runs once, then stops for good) instead of a recurring automation that checks the date"
|
|
8906
|
+
).option("--description <text>", "What the automation does").option("--instructions <text>", "Instructions for each run (agent automation)").option("--script-js <js>", "Deterministic script body (scripted automation, no LLM)").option("--script-file <path>", "Read the script body from a file (scripted automation)").requiredOption("--interval <minutes>", "Interval in minutes (minimum 5)", (v) => parseInt(v, 10)).option("--timezone <tz>", "Scheduling timezone, e.g. America/New_York (default UTC)").option("--run-at <rfc3339>", "Run once at or after this instant, then stop permanently").option("--ends-at <rfc3339>", "Never run after this instant").addOption(new Option2("--agent-key <key>", "Executor for an agent automation").choices(["erdo.heartbeat-executor", "erdo.workflow-executor"])).addOption(new Option2("--conversation <target>", "Target 'new' (fresh thread) or 'direct' conversation").choices(["new", "direct"])).option("--thread-id <id>", "Post each run into an existing conversation UUID").option("--persona-id <id>", "Org-enabled persona UUID to speak as").action(
|
|
8907
|
+
async (name, opts) => {
|
|
8908
|
+
try {
|
|
8909
|
+
if (opts.scriptJs && opts.scriptFile) {
|
|
8910
|
+
fail(new Error("pass either --script-js or --script-file, not both"));
|
|
8911
|
+
return;
|
|
8912
|
+
}
|
|
8913
|
+
const scriptJs = opts.scriptFile ? readFileSync4(opts.scriptFile, "utf8") : opts.scriptJs;
|
|
8914
|
+
const h = await new ErdoClient().createHeartbeat({
|
|
8915
|
+
name,
|
|
8916
|
+
description: opts.description,
|
|
8917
|
+
instructions: opts.instructions,
|
|
8918
|
+
script_js: scriptJs,
|
|
8919
|
+
interval_minutes: opts.interval,
|
|
8920
|
+
timezone: opts.timezone,
|
|
8921
|
+
run_at: scheduleBound("--run-at", opts.runAt),
|
|
8922
|
+
ends_at: scheduleBound("--ends-at", opts.endsAt),
|
|
8923
|
+
agent_key: opts.agentKey,
|
|
8924
|
+
conversation: opts.conversation,
|
|
8925
|
+
thread_id: opts.threadId,
|
|
8926
|
+
persona_id: opts.personaId
|
|
8927
|
+
});
|
|
8928
|
+
console.log(`${h.id} ${h.state} ${h.name}${heartbeatBounds(h)}`);
|
|
8929
|
+
} catch (e) {
|
|
8930
|
+
fail(e);
|
|
8931
|
+
}
|
|
8932
|
+
}
|
|
8933
|
+
);
|
|
8889
8934
|
autoCmd.command("list").description("List automations").action(async () => {
|
|
8890
8935
|
try {
|
|
8891
8936
|
const { heartbeats } = await new ErdoClient().listHeartbeats();
|
|
8892
|
-
for (const h of heartbeats) console.log(`${h.id} ${h.state} ${h.name} ${h.kind === "script" ? "script" : h.thread_id ? `thread:${h.thread_id}` : h.conversation ?? "new"}${h.persona_id ? ` persona:${h.persona_id}` : ""}`);
|
|
8937
|
+
for (const h of heartbeats) console.log(`${h.id} ${h.state} ${h.name} ${h.kind === "script" ? "script" : h.thread_id ? `thread:${h.thread_id}` : h.conversation ?? "new"}${h.persona_id ? ` persona:${h.persona_id}` : ""}${heartbeatBounds(h)}`);
|
|
8893
8938
|
} catch (e) {
|
|
8894
8939
|
fail(e);
|
|
8895
8940
|
}
|
|
@@ -8915,7 +8960,7 @@ autoCmd.command("run <id>").description("Trigger an automation now").action(asyn
|
|
|
8915
8960
|
autoCmd.command("update <id>").description("Edit an automation \u2014 rename, reschedule, or replace its script/instructions").option("--name <name>", "New name").option("--description <text>", "New description").option("--instructions <text>", "Replacement instructions (agent automation)").addOption(new Option2("--agent-key <key>", "Executor for an agent automation; omit to keep current").choices(["erdo.heartbeat-executor", "erdo.workflow-executor"])).option("--script-js <js>", "Replacement script body (scripted automation)").option(
|
|
8916
8961
|
"--script-file <path>",
|
|
8917
8962
|
"Read the replacement script body from a file (scripted automation)"
|
|
8918
|
-
).addOption(new Option2("--conversation <target>", "Target 'new' (fresh thread) or 'direct' conversation").choices(["new", "direct"])).option("--thread-id <id>", "Post each run into an existing conversation UUID").option("--persona-id <id>", "Org-enabled persona UUID to speak as").option("--interval <minutes>", "New interval in minutes (minimum 5)", (v) => parseInt(v, 10)).option("--timezone <tz>", "New scheduling timezone, e.g. America/New_York").action(
|
|
8963
|
+
).addOption(new Option2("--conversation <target>", "Target 'new' (fresh thread) or 'direct' conversation").choices(["new", "direct"])).option("--thread-id <id>", "Post each run into an existing conversation UUID").option("--persona-id <id>", "Org-enabled persona UUID to speak as").option("--interval <minutes>", "New interval in minutes (minimum 5)", (v) => parseInt(v, 10)).option("--timezone <tz>", "New scheduling timezone, e.g. America/New_York").option("--run-at <rfc3339>", "New one-off fire time: runs once at or after it, then stops permanently (omit to keep)").option("--ends-at <rfc3339>", "New end time after which it never runs (omit to keep)").action(
|
|
8919
8964
|
async (id, opts) => {
|
|
8920
8965
|
try {
|
|
8921
8966
|
if (opts.scriptJs && opts.scriptFile) {
|
|
@@ -8931,6 +8976,8 @@ autoCmd.command("update <id>").description("Edit an automation \u2014 rename, re
|
|
|
8931
8976
|
script_js: scriptJs,
|
|
8932
8977
|
interval_minutes: opts.interval,
|
|
8933
8978
|
timezone: opts.timezone,
|
|
8979
|
+
run_at: scheduleBound("--run-at", opts.runAt),
|
|
8980
|
+
ends_at: scheduleBound("--ends-at", opts.endsAt),
|
|
8934
8981
|
conversation: opts.conversation,
|
|
8935
8982
|
thread_id: opts.threadId,
|
|
8936
8983
|
persona_id: opts.personaId
|
|
@@ -8940,7 +8987,7 @@ autoCmd.command("update <id>").description("Edit an automation \u2014 rename, re
|
|
|
8940
8987
|
return;
|
|
8941
8988
|
}
|
|
8942
8989
|
const h = await new ErdoClient().updateHeartbeat(id, body);
|
|
8943
|
-
console.log(`${h.id} ${h.state} ${h.name}`);
|
|
8990
|
+
console.log(`${h.id} ${h.state} ${h.name}${heartbeatBounds(h)}`);
|
|
8944
8991
|
} catch (e) {
|
|
8945
8992
|
fail(e);
|
|
8946
8993
|
}
|