@audienti/cli 0.1.136 → 0.1.138
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/CHANGELOG.md +13 -0
- package/README.md +17 -0
- package/package.json +1 -1
- package/src/api-client.js +12 -0
- package/src/cli.js +35 -30
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.138] - 2026-10-24
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Review and explicitly accept Email Find credit quotes. Review queued rows and resume, pause, cancel or approve a new payer through shared API controls. Read exact credit receipts; ordinary tool history hides supplier monetary amounts (#2643). Real charging remains separately gated.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [0.1.137] - 2026-10-24
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- No CLI behavior change. The API events controller now shares its rejection status table with the Operator drawer for settling an uncertain post comment (#3097).
|
|
19
|
+
|
|
7
20
|
## [0.1.136] - 2026-10-24
|
|
8
21
|
|
|
9
22
|
### Added
|
package/README.md
CHANGED
|
@@ -328,6 +328,23 @@ inside fields are not. With `--wait`, the exit code is 1 on an API error, a
|
|
|
328
328
|
timeout or an aborted (failed) run; per-item outcomes such as `no_match` do
|
|
329
329
|
not change it.
|
|
330
330
|
|
|
331
|
+
For an active paid Email Find operation, review a server quote first:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
audienti tools email-find --file people.csv --quote
|
|
335
|
+
audienti tools email-find --file people.csv --accept-quote <quote_reference>
|
|
336
|
+
audienti tools runs review <run_id>
|
|
337
|
+
audienti tools runs resume <run_id> --item <item_id> --revision <revision> --idempotency-key <unique_key>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Use the same input when accepting the quote. Queued rows retain the accepted price.
|
|
341
|
+
Review reports available credits and the rows that can continue. Select fewer rows
|
|
342
|
+
or top up; a top-up does not restart manually paused work. Use `pause` or `cancel`
|
|
343
|
+
in place of `resume` with the same reviewed selection. `approve-payer` requires the
|
|
344
|
+
new root administrator and does not resume work. `tools runs usage <usage_reference>`
|
|
345
|
+
opens the exact receipt data. Tool history displays credits; supplier costs stay internal.
|
|
346
|
+
Real prices and production charging require separate approval.
|
|
347
|
+
|
|
331
348
|
Prefer `tools email-find` for an email lookup. `tools get email` still runs the
|
|
332
349
|
prospect import pipeline and creates a prospect.
|
|
333
350
|
|
package/package.json
CHANGED
package/src/api-client.js
CHANGED
|
@@ -1318,6 +1318,18 @@ export class AudientiClient {
|
|
|
1318
1318
|
}
|
|
1319
1319
|
|
|
1320
1320
|
// Standalone account tool runs (#2554).
|
|
1321
|
+
quoteToolRun(accountId, body) {
|
|
1322
|
+
return this.requestJson(accountPath(accountId, ["tools", "run_quotes"]), { method: "POST", body });
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
toolRunCreditAction(accountId, runId, body) {
|
|
1326
|
+
return this.requestJson(accountPath(accountId, ["tools", "runs", runId, "credit_actions"]), { method: "POST", body });
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
toolCreditUsage(accountId, reference) {
|
|
1330
|
+
return this.requestJson(accountPath(accountId, ["tools", "credit_usages", reference]));
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1321
1333
|
createToolRun(accountId, body) {
|
|
1322
1334
|
return this.requestJson(accountPath(accountId, ["tools", "runs"]), { method: "POST", body });
|
|
1323
1335
|
}
|
package/src/cli.js
CHANGED
|
@@ -231,11 +231,11 @@ const ANALYTICS_COHORT_LIST_USAGE = "Usage: audienti analytics cohorts create-li
|
|
|
231
231
|
const TOOLS_LIST_USAGE = "Usage: audienti tools list [--json]";
|
|
232
232
|
const TOOLS_HUMANIZE_USAGE = "Usage: audienti tools humanize --file <path> [--tone <professional|academic|blog|casual|creative|scientific|technical>] [--language <language>] [--async [--wait]] [--json] [--account <acct_id>]";
|
|
233
233
|
const TOOL_RUN_FLAGS_USAGE = "[--request-key <key>] [--wait [--timeout-seconds <n>] [--poll-interval-seconds <n>]] [--json] [--account <acct_id>]";
|
|
234
|
-
const TOOLS_EMAIL_FIND_USAGE = `Usage: audienti tools email-find (--first-name <name> --last-name <name> --company-domain <domain> | --linkedin-url <url> | --file <csv|jsonl|json>) ${TOOL_RUN_FLAGS_USAGE}`;
|
|
234
|
+
const TOOLS_EMAIL_FIND_USAGE = `Usage: audienti tools email-find (--first-name <name> --last-name <name> --company-domain <domain> | --linkedin-url <url> | --file <csv|jsonl|json>) [--quote | --accept-quote <reference>] ${TOOL_RUN_FLAGS_USAGE}`;
|
|
235
235
|
const TOOLS_LINKEDIN_ENRICH_USAGE = `Usage: audienti tools linkedin-enrich (--url <linkedin_url> [--kind <person|company>] | --file <csv|jsonl|json>) ${TOOL_RUN_FLAGS_USAGE}`;
|
|
236
236
|
const TOOLS_SIGNALS_FIND_USAGE = `Usage: audienti tools signals-find --icp <text> --question <text> [--count <1-10>] [--date-window-days <n>] ${TOOL_RUN_FLAGS_USAGE}`;
|
|
237
237
|
const TOOLS_WRITE_USAGE = `Usage: audienti tools write --purpose <text> --audience <text> --fact <text> [--fact <text> ...] --channel <channel> [--tone <tone>] [--subject|--no-subject] [--prospect <prsp_id>] ${TOOL_RUN_FLAGS_USAGE}`;
|
|
238
|
-
const TOOLS_RUNS_USAGE = "Usage: audienti tools runs (list [--tool <tool>] [--status <status>] [--limit <n>] [--cursor <id>] | show <trun_id> | results <trun_id> [--limit <n>] [--cursor <n>] | export <trun_id> [--format <csv|json>] [--output <path>]) [--json] [--account <acct_id>]";
|
|
238
|
+
const TOOLS_RUNS_USAGE = "Usage: audienti tools runs (list [--tool <tool>] [--status <status>] [--limit <n>] [--cursor <id>] | show <trun_id> | results <trun_id> [--limit <n>] [--cursor <n>] | export <trun_id> [--format <csv|json>] [--output <path>] | review <trun_id> | (resume|pause|cancel|approve-payer) <trun_id> --item <item_id> --revision <revision> --idempotency-key <key> [--cancel-others] | usage <reference>) [--json] [--account <acct_id>]";
|
|
239
239
|
const NETWORK_USAGE = "Usage: audienti network (list|export) --cookie <scok_id> [--platform <linkedin|twitter>] [--kind <connection|follow>] [--direction <incoming|outgoing>] [--query <text>] [--limit <n>] [--cursor <n>] [--format <csv|json>] [--output <path>] [--json] [--account <acct_id>]";
|
|
240
240
|
const TOOLS_LINKEDIN_REVIEW_USAGE = "Usage: audienti tools linkedin-review --url <linkedin_url> [--icp <icp_id>] [--json] [--account <acct_id>]";
|
|
241
241
|
const TOOLS_LINKEDIN_REVIEW_REPORTS_USAGE = "Usage: audienti tools linkedin-review reports [--limit <n>] [--json] [--account <acct_id>]";
|
|
@@ -16353,6 +16353,8 @@ async function toolsEmailFind(args, context, { accountOverride } = {}) {
|
|
|
16353
16353
|
const { values, positionals } = parseCommandArgs(args, {
|
|
16354
16354
|
...jsonOptions(),
|
|
16355
16355
|
...TOOL_RUN_WAIT_OPTIONS,
|
|
16356
|
+
quote: { type: "boolean" },
|
|
16357
|
+
"accept-quote": { type: "string" },
|
|
16356
16358
|
"first-name": { type: "string" },
|
|
16357
16359
|
"last-name": { type: "string" },
|
|
16358
16360
|
"company-domain": { type: "string" },
|
|
@@ -16450,7 +16452,16 @@ async function toolsWrite(args, context, { accountOverride } = {}) {
|
|
|
16450
16452
|
|
|
16451
16453
|
async function submitToolRun(tool, input, values, context, { accountOverride } = {}) {
|
|
16452
16454
|
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16453
|
-
|
|
16455
|
+
if (values.quote) {
|
|
16456
|
+
if (values["accept-quote"]) throw new CommandError("Choose --quote or --accept-quote, not both.");
|
|
16457
|
+
const quote = await client.quoteToolRun(accountId, { tool, input });
|
|
16458
|
+
if (values.json) return writeJson(context.stdout, quote);
|
|
16459
|
+
writeLine(context.stdout, `Up to ${quote.maximum_credits} credits for ${quote.max_units} rows. Available: ${quote.available_credits} credits.`);
|
|
16460
|
+
writeLine(context.stdout, `Accept with the same input and --accept-quote ${quote.quote_reference}`);
|
|
16461
|
+
return 0;
|
|
16462
|
+
}
|
|
16463
|
+
const run = await client.createToolRun(accountId, compactObject({ tool, input, request_key: values["request-key"],
|
|
16464
|
+
quote_reference: values["accept-quote"], accept_quote: values["accept-quote"] ? true : undefined }));
|
|
16454
16465
|
if (!values.wait) {
|
|
16455
16466
|
if (values.json) return writeJson(context.stdout, run);
|
|
16456
16467
|
|
|
@@ -16507,6 +16518,7 @@ async function fetchAllToolRunItems(client, accountId, runId) {
|
|
|
16507
16518
|
|
|
16508
16519
|
async function toolsRuns(args, context, { accountOverride } = {}) {
|
|
16509
16520
|
const [subcommand, ...rest] = args;
|
|
16521
|
+
if (["review", "resume", "pause", "cancel", "approve-payer", "usage"].includes(subcommand)) return toolsRunsCredits(subcommand, rest, context, { accountOverride });
|
|
16510
16522
|
if (subcommand === "list") return toolsRunsList(rest, context, { accountOverride });
|
|
16511
16523
|
if (subcommand === "show") return toolsRunsShow(rest, context, { accountOverride });
|
|
16512
16524
|
if (subcommand === "results") return toolsRunsResults(rest, context, { accountOverride });
|
|
@@ -16515,6 +16527,24 @@ async function toolsRuns(args, context, { accountOverride } = {}) {
|
|
|
16515
16527
|
throw new CommandError(TOOLS_RUNS_USAGE);
|
|
16516
16528
|
}
|
|
16517
16529
|
|
|
16530
|
+
async function toolsRunsCredits(action, args, context, { accountOverride } = {}) {
|
|
16531
|
+
const { values, positionals } = parseCommandArgs(args, {
|
|
16532
|
+
...jsonOptions(), item: { type: "string", multiple: true }, revision: { type: "string" },
|
|
16533
|
+
"idempotency-key": { type: "string" }, "cancel-others": { type: "boolean" }
|
|
16534
|
+
});
|
|
16535
|
+
if (positionals.length !== 1) throw new CommandError("Supply one run id (or usage reference for usage).");
|
|
16536
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16537
|
+
if (action === "usage") return writeJson(context.stdout, await client.toolCreditUsage(accountId, positionals[0]));
|
|
16538
|
+
if (action !== "review" && (!values.item?.length || !values.revision || !values["idempotency-key"])) {
|
|
16539
|
+
throw new CommandError("Review first, then supply --item for each selected row, --revision and --idempotency-key.");
|
|
16540
|
+
}
|
|
16541
|
+
const result = await client.toolRunCreditAction(accountId, positionals[0], compactObject({
|
|
16542
|
+
action_name: action.replaceAll("-", "_"), item_ids: values.item, revision: values.revision,
|
|
16543
|
+
idempotency_key: values["idempotency-key"], cancel_others: values["cancel-others"]
|
|
16544
|
+
}));
|
|
16545
|
+
return writeJson(context.stdout, result);
|
|
16546
|
+
}
|
|
16547
|
+
|
|
16518
16548
|
async function toolsRunsList(args, context, { accountOverride } = {}) {
|
|
16519
16549
|
const { values, positionals } = parseCommandArgs(args, {
|
|
16520
16550
|
...jsonOptions(),
|
|
@@ -16666,8 +16696,8 @@ function renderToolRun(run, context) {
|
|
|
16666
16696
|
if (Number(run.summary.cache_hit_count) > 0) usage.push(`${run.summary.cache_hit_count} cached`);
|
|
16667
16697
|
writeLine(context.stdout, `Usage: ${usage.join("; ")}`);
|
|
16668
16698
|
}
|
|
16669
|
-
|
|
16670
|
-
|
|
16699
|
+
if (run?.credit_usage) writeLine(context.stdout, run.credit_usage.credit_history_available
|
|
16700
|
+
? `Charged: ${run.credit_usage.charged_credits} credits` : "Credit history unavailable");
|
|
16671
16701
|
const outcomes = run?.summary?.outcomes || {};
|
|
16672
16702
|
if (Object.keys(outcomes).length > 0) {
|
|
16673
16703
|
writeLine(context.stdout, `Outcomes: ${Object.entries(outcomes).map(([outcome, count]) => `${outcome} ${count}`).join(", ")}`);
|
|
@@ -16676,31 +16706,6 @@ function renderToolRun(run, context) {
|
|
|
16676
16706
|
if (run?.details_expired) writeLine(context.stdout, "Details expired after 90 days; only this summary remains.");
|
|
16677
16707
|
}
|
|
16678
16708
|
|
|
16679
|
-
function toolRunExpenseSummary(expenses) {
|
|
16680
|
-
if (expenses.state === "unavailable") return "data unavailable";
|
|
16681
|
-
if (expenses.state === "none") return "no recorded expenses";
|
|
16682
|
-
if (expenses.state === "expired") {
|
|
16683
|
-
const known = expenses.completion_snapshot?.known_billed_expense_cents;
|
|
16684
|
-
return `current receipt detail expired; completion-time snapshot ${expenseAmountLabel(known)}; ${display(expenses.uncertain_attempt_count, 0)} call(s) with unknown or uncertain expense at completion`;
|
|
16685
|
-
}
|
|
16686
|
-
|
|
16687
|
-
const known = expenses.known_expense_cents;
|
|
16688
|
-
const parts = [known === null || known === undefined ? "no priced receipts" : `${expenseAmountLabel(known)} recorded`];
|
|
16689
|
-
if (expenses.unknown_expense_receipt_count > 0) parts.push(`${expenses.unknown_expense_receipt_count} linked receipt(s) with unknown amount`);
|
|
16690
|
-
if (expenses.uncertain_attempt_count > 0) parts.push(`${expenses.uncertain_attempt_count} call(s) with unknown or uncertain expense`);
|
|
16691
|
-
if (expenses.completion_unverified_attempt_count > 0) parts.push(`${expenses.completion_unverified_attempt_count} call(s) with cost unverified at completion`);
|
|
16692
|
-
if (expenses.in_progress_attempt_count > 0) parts.push(`${expenses.in_progress_attempt_count} call(s) in progress`);
|
|
16693
|
-
if (expenses.state === "partial") parts.push("known sum may be partial");
|
|
16694
|
-
return parts.join("; ");
|
|
16695
|
-
}
|
|
16696
|
-
|
|
16697
|
-
function expenseAmountLabel(cents) {
|
|
16698
|
-
if (cents === null || cents === undefined) return "no known amount";
|
|
16699
|
-
const amount = Number(cents);
|
|
16700
|
-
if (amount > 0 && amount < 0.01) return "less than 0.01¢";
|
|
16701
|
-
return `${amount.toFixed(2)}¢`;
|
|
16702
|
-
}
|
|
16703
|
-
|
|
16704
16709
|
function renderToolRunItems(tool, items, context) {
|
|
16705
16710
|
if (items.length === 0) return writeLine(context.stdout, "No results yet.");
|
|
16706
16711
|
|