@erdoai/cli 0.131.0 → 0.132.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/README.md +1 -1
- package/dist/index.js +148 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,7 +111,7 @@ erdo datasets upload ./leads.csv # create a dataset from a file
|
|
|
111
111
|
|
|
112
112
|
```bash
|
|
113
113
|
erdo agent ask "what was revenue last week?" --datasets sales
|
|
114
|
-
erdo
|
|
114
|
+
erdo threads create --name "landing build" # -> thread id
|
|
115
115
|
erdo agent send <thread> "Build a landing page for ACME ..." --agent erdo.artifact-builder
|
|
116
116
|
erdo agent send <thread> "What should I do next?" --context "Current screen: checkout experiment"
|
|
117
117
|
|
package/dist/index.js
CHANGED
|
@@ -1071,6 +1071,34 @@ var ErdoClient = class {
|
|
|
1071
1071
|
input
|
|
1072
1072
|
);
|
|
1073
1073
|
}
|
|
1074
|
+
listPersonas() {
|
|
1075
|
+
return this.request(
|
|
1076
|
+
"GET",
|
|
1077
|
+
"/v1/personas"
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
openDirectConversation(personaID) {
|
|
1081
|
+
return this.request(
|
|
1082
|
+
"POST",
|
|
1083
|
+
"/v1/threads-direct",
|
|
1084
|
+
{ persona_id: personaID }
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
1087
|
+
markThreadSeen(threadID) {
|
|
1088
|
+
return this.request("POST", `/v1/threads/${encodeURIComponent(threadID)}/seen`, {});
|
|
1089
|
+
}
|
|
1090
|
+
listSeenThreads() {
|
|
1091
|
+
return this.request("GET", "/v1/threads-seen");
|
|
1092
|
+
}
|
|
1093
|
+
getThread(threadID) {
|
|
1094
|
+
return this.request("GET", `/v1/threads/${encodeURIComponent(threadID)}`);
|
|
1095
|
+
}
|
|
1096
|
+
addThreadParticipant(threadID, participant) {
|
|
1097
|
+
return this.request("POST", `/v1/threads/${encodeURIComponent(threadID)}/participants`, participant);
|
|
1098
|
+
}
|
|
1099
|
+
removeThreadParticipant(threadID, participantID) {
|
|
1100
|
+
return this.request("DELETE", `/v1/threads/${encodeURIComponent(threadID)}/participants/${encodeURIComponent(participantID)}`);
|
|
1101
|
+
}
|
|
1074
1102
|
async deleteThread(threadID) {
|
|
1075
1103
|
try {
|
|
1076
1104
|
await this.request("DELETE", `/v1/threads/${encodeURIComponent(threadID)}`);
|
|
@@ -4147,50 +4175,139 @@ thread: ${response.thread_id}`);
|
|
|
4147
4175
|
fail(e);
|
|
4148
4176
|
}
|
|
4149
4177
|
});
|
|
4150
|
-
agentCmd.command("
|
|
4178
|
+
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) => {
|
|
4179
|
+
try {
|
|
4180
|
+
await new ErdoClient().deleteThread(threadId);
|
|
4181
|
+
console.log(`deleted ${threadId}`);
|
|
4182
|
+
} catch (e) {
|
|
4183
|
+
fail(e);
|
|
4184
|
+
}
|
|
4185
|
+
});
|
|
4186
|
+
async function resolveConversationPersona(client, selector) {
|
|
4187
|
+
const { personas } = await client.listPersonas();
|
|
4188
|
+
const needle = selector.trim().toLocaleLowerCase();
|
|
4189
|
+
const matches = personas.filter(
|
|
4190
|
+
(persona) => [persona.id, persona.key, persona.human_name, persona.name].some((value) => value?.trim().toLocaleLowerCase() === needle)
|
|
4191
|
+
);
|
|
4192
|
+
if (matches.length === 1) return matches[0];
|
|
4193
|
+
if (matches.length > 1) throw new Error(`Agent "${selector}" is ambiguous; use its persona key or ID`);
|
|
4194
|
+
throw new Error(`No enabled agent matches "${selector}"`);
|
|
4195
|
+
}
|
|
4196
|
+
var conversationsCmd = program.command("threads").description("List and open conversations with people and named agents");
|
|
4197
|
+
conversationsCmd.command("list").description("List conversations with the latest message, speaker, unread status and open questions").option("-s, --scope <scope>", "own (default) | org | shared | all \u2014 org/shared require org membership").option("--order-by <order>", "created_at (default) | activity (last message time) \u2014 scope=org/shared only").option("--include-automation", "include automation/heartbeat-sourced threads \u2014 scope=org/shared only").option("-l, --limit <n>", "max conversations (default 20, max 100)", (v) => parseInt(v, 10)).option("--offset <n>", "pagination offset", (v) => parseInt(v, 10)).action(async (opts) => {
|
|
4198
|
+
try {
|
|
4199
|
+
const { threads, total } = await new ErdoClient().listThreads(opts);
|
|
4200
|
+
for (const thread of threads) {
|
|
4201
|
+
const preview = (thread.last_message_preview || "").replace(/[\t\r\n]+/g, " ").slice(0, 120);
|
|
4202
|
+
const speaker = thread.last_message_author_display_name || thread.last_message_author_entity_type || "";
|
|
4203
|
+
const creator = thread.created_by_user_name || thread.created_by_user_id;
|
|
4204
|
+
console.log(`${thread.id} ${thread.name || ""} ${creator} ${thread.source || "unrecorded"} ${thread.unread ? "unread" : "read"} ${speaker} ${preview} questions=${thread.open_question_count ?? 0}`);
|
|
4205
|
+
}
|
|
4206
|
+
const shown = (opts.offset ?? 0) + threads.length;
|
|
4207
|
+
console.error(total > shown ? `(showing ${threads.length} of ${total} \u2014 use --limit/--offset for more)` : `(${total} conversation${total === 1 ? "" : "s"})`);
|
|
4208
|
+
} catch (e) {
|
|
4209
|
+
fail(e);
|
|
4210
|
+
}
|
|
4211
|
+
});
|
|
4212
|
+
conversationsCmd.command("open <agent>").description("Open or create your direct conversation with an enabled agent").action(async (agent) => {
|
|
4213
|
+
try {
|
|
4214
|
+
const client = new ErdoClient();
|
|
4215
|
+
const persona = await resolveConversationPersona(client, agent);
|
|
4216
|
+
const thread = await client.openDirectConversation(persona.id);
|
|
4217
|
+
console.log(thread.id);
|
|
4218
|
+
} catch (e) {
|
|
4219
|
+
fail(e);
|
|
4220
|
+
}
|
|
4221
|
+
});
|
|
4222
|
+
conversationsCmd.command("create").description("Create a conversation, optionally bound to an enabled agent").option("--agent <agent>", "agent name, persona key or ID").option("-n, --name <name>", "conversation name").option("-d, --datasets <csv>", "dataset UUIDs to attach").option("--hidden", "keep the conversation out of the organization's conversation list").option("--parent <threadId>", "parent conversation this internal conversation supports").option("--internal", "create an internal conversation hidden until someone follows it").action(async (opts) => {
|
|
4151
4223
|
try {
|
|
4152
|
-
|
|
4224
|
+
if (opts.internal && !opts.parent) throw new Error("--internal requires --parent <thread-id>");
|
|
4225
|
+
const client = new ErdoClient();
|
|
4226
|
+
const persona = opts.agent ? await resolveConversationPersona(client, opts.agent) : void 0;
|
|
4227
|
+
const thread = await client.createThread({
|
|
4153
4228
|
name: opts.name,
|
|
4154
|
-
dataset_ids: opts.datasets ? opts.datasets.split(",").map((s) => s.trim()) : void 0,
|
|
4155
|
-
visibility: opts.hidden ? "hidden" : void 0
|
|
4229
|
+
dataset_ids: opts.datasets ? opts.datasets.split(",").map((s) => s.trim()).filter(Boolean) : void 0,
|
|
4230
|
+
visibility: opts.hidden ? "hidden" : void 0,
|
|
4231
|
+
persona_id: persona?.id,
|
|
4232
|
+
parent_thread_id: opts.parent,
|
|
4233
|
+
listing: opts.internal ? "internal" : void 0
|
|
4156
4234
|
});
|
|
4157
|
-
console.log(
|
|
4235
|
+
console.log(thread.id);
|
|
4158
4236
|
} catch (e) {
|
|
4159
4237
|
fail(e);
|
|
4160
4238
|
}
|
|
4161
4239
|
});
|
|
4162
|
-
|
|
4240
|
+
conversationsCmd.command("follow <threadId>").description("Follow an internal conversation so it appears in your conversation list").action(async (threadID) => {
|
|
4163
4241
|
try {
|
|
4164
|
-
|
|
4165
|
-
|
|
4242
|
+
const client = new ErdoClient();
|
|
4243
|
+
const user = await client.me();
|
|
4244
|
+
await client.addThreadParticipant(threadID, { user_id: user.user_id });
|
|
4245
|
+
console.log(`following ${threadID}`);
|
|
4166
4246
|
} catch (e) {
|
|
4167
4247
|
fail(e);
|
|
4168
4248
|
}
|
|
4169
4249
|
});
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
try {
|
|
4179
|
-
const { threads, total } = await new ErdoClient().listThreads(opts);
|
|
4180
|
-
for (const t of threads) {
|
|
4181
|
-
console.log(`${t.id} ${t.name} ${t.created_by_user_name || t.created_by_user_id} ${t.source || "unrecorded"}`);
|
|
4182
|
-
}
|
|
4183
|
-
const shown = (opts.offset ?? 0) + threads.length;
|
|
4184
|
-
if (total > shown) {
|
|
4185
|
-
console.error(`(showing ${threads.length} of ${total} \u2014 use --limit/--offset for more)`);
|
|
4186
|
-
} else {
|
|
4187
|
-
console.error(`(${total} thread${total === 1 ? "" : "s"})`);
|
|
4188
|
-
}
|
|
4189
|
-
} catch (e) {
|
|
4190
|
-
fail(e);
|
|
4191
|
-
}
|
|
4250
|
+
conversationsCmd.command("unfollow <threadId>").description("Unfollow an internal conversation").action(async (threadID) => {
|
|
4251
|
+
try {
|
|
4252
|
+
const client = new ErdoClient();
|
|
4253
|
+
const user = await client.me();
|
|
4254
|
+
await client.removeThreadParticipant(threadID, user.user_id);
|
|
4255
|
+
console.log(`unfollowed ${threadID}`);
|
|
4256
|
+
} catch (e) {
|
|
4257
|
+
fail(e);
|
|
4192
4258
|
}
|
|
4193
|
-
);
|
|
4259
|
+
});
|
|
4260
|
+
conversationsCmd.command("seen <threadId>").description("Mark a conversation as seen").action(async (threadID) => {
|
|
4261
|
+
try {
|
|
4262
|
+
await new ErdoClient().markThreadSeen(threadID);
|
|
4263
|
+
console.log(`seen ${threadID}`);
|
|
4264
|
+
} catch (e) {
|
|
4265
|
+
fail(e);
|
|
4266
|
+
}
|
|
4267
|
+
});
|
|
4268
|
+
conversationsCmd.command("seen-list").description("List conversations you have marked as seen").action(async () => {
|
|
4269
|
+
try {
|
|
4270
|
+
print(await new ErdoClient().listSeenThreads());
|
|
4271
|
+
} catch (e) {
|
|
4272
|
+
fail(e);
|
|
4273
|
+
}
|
|
4274
|
+
});
|
|
4275
|
+
conversationsCmd.command("agents").description("List enabled agents and their persona IDs").action(async () => {
|
|
4276
|
+
try {
|
|
4277
|
+
const { personas } = await new ErdoClient().listPersonas();
|
|
4278
|
+
for (const persona of personas) console.log(`${persona.id} ${persona.key} ${persona.human_name || persona.name}`);
|
|
4279
|
+
} catch (e) {
|
|
4280
|
+
fail(e);
|
|
4281
|
+
}
|
|
4282
|
+
});
|
|
4283
|
+
conversationsCmd.command("get <threadId>").description("Show a conversation and its participants").action(async (threadID) => {
|
|
4284
|
+
try {
|
|
4285
|
+
print(await new ErdoClient().getThread(threadID));
|
|
4286
|
+
} catch (e) {
|
|
4287
|
+
fail(e);
|
|
4288
|
+
}
|
|
4289
|
+
});
|
|
4290
|
+
var conversationParticipantsCmd = conversationsCmd.command("participants").description("Manage named-agent participants in a conversation");
|
|
4291
|
+
conversationParticipantsCmd.command("add <threadId> <agent>").description("Add an enabled agent to a conversation").action(async (threadID, agent) => {
|
|
4292
|
+
try {
|
|
4293
|
+
const client = new ErdoClient();
|
|
4294
|
+
const persona = await resolveConversationPersona(client, agent);
|
|
4295
|
+
await client.addThreadParticipant(threadID, { persona_id: persona.id });
|
|
4296
|
+
console.log(`added ${persona.human_name || persona.name} to ${threadID}`);
|
|
4297
|
+
} catch (e) {
|
|
4298
|
+
fail(e);
|
|
4299
|
+
}
|
|
4300
|
+
});
|
|
4301
|
+
conversationParticipantsCmd.command("remove <threadId> <agent>").description("Remove an enabled agent from a conversation").action(async (threadID, agent) => {
|
|
4302
|
+
try {
|
|
4303
|
+
const client = new ErdoClient();
|
|
4304
|
+
const persona = await resolveConversationPersona(client, agent);
|
|
4305
|
+
await client.removeThreadParticipant(threadID, persona.id);
|
|
4306
|
+
console.log(`removed ${persona.human_name || persona.name} from ${threadID}`);
|
|
4307
|
+
} catch (e) {
|
|
4308
|
+
fail(e);
|
|
4309
|
+
}
|
|
4310
|
+
});
|
|
4194
4311
|
function contentBlockLabel(c) {
|
|
4195
4312
|
const type = c.ui_content_type || c.content_type;
|
|
4196
4313
|
const payload = c.content;
|