@audienti/cli 0.1.139 → 0.1.141
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 +14 -0
- package/README.md +17 -1
- package/package.json +1 -1
- package/src/api-client.js +34 -0
- package/src/cli.js +149 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to the Audienti CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.141] - 2026-10-26
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `audienti events defer-comment-retry <event_id>` is "Not now" for a post comment you said was not sent (`POST /api/v1/accounts/:account_id/events/:id/defer_comment_retry`). It hides the "Not sent: try again?" offer for 24 hours; the offer comes back once, and a second "Not now" ends it. Nothing is sent.
|
|
12
|
+
|
|
13
|
+
## [0.1.140] - 2026-10-25
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Connect Signal search to shared quote acceptance and one-search credit units.
|
|
18
|
+
- Add credit history, exact receipts, root price/payer approvals and staff result-refund commands through shared APIs.
|
|
19
|
+
- Preserve exact decimal credit strings and keep supplier accounting out of customer financial output.
|
|
20
|
+
|
|
7
21
|
## [0.1.139] - 2026-10-25
|
|
8
22
|
|
|
9
23
|
### Changed
|
package/README.md
CHANGED
|
@@ -328,10 +328,11 @@ 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
|
|
331
|
+
For active paid Email Find or Signal search work, review a server quote first:
|
|
332
332
|
|
|
333
333
|
```bash
|
|
334
334
|
audienti tools email-find --file people.csv --quote
|
|
335
|
+
audienti tools signals-find --icp "Logistics companies" --question "Warehouse expansion" --count 5 --quote
|
|
335
336
|
audienti tools email-find --file people.csv --accept-quote <quote_reference>
|
|
336
337
|
audienti tools runs review <run_id>
|
|
337
338
|
audienti tools runs resume <run_id> --item <item_id> --revision <revision> --idempotency-key <unique_key>
|
|
@@ -899,3 +900,18 @@ Batch import accepts up to 50 rows per API request. Split larger files before im
|
|
|
899
900
|
Bulk destinations: `audienti prospects set-destination <prsp_id> --type list --destination <list_id>` adds by default. Use `--name "New list"` to create a list, `--type experiment --name "Existing relationships"` to create a transition without setup, or `--mode move` for explicit reassignment. Add preserves existing memberships; experiment Add skips people assigned elsewhere.
|
|
900
901
|
|
|
901
902
|
Create a child workspace with `audienti accounts create --name <name> --parent <name-or-id> [--json]`. The parent can be a visible name, unique name fragment, numeric ID, or prefixed ID. You must administer a root team account. All parent admins receive access to the child; ordinary members do not. Ambiguous names show matching IDs and stop. A duplicate child name under the same parent fails clearly. The response includes the new account ID. Creation keeps your selected account unchanged: use `audienti accounts select <new_acct_id>` or `--account <new_acct_id>` before creating a motion there.
|
|
903
|
+
|
|
904
|
+
### Credit history and root approvals
|
|
905
|
+
|
|
906
|
+
`audienti credits history` lists credit charges. `credits show <usage_id>` opens an
|
|
907
|
+
exact receipt. A root billing role does not grant access to private saved results.
|
|
908
|
+
`credits approvals` shows action prices and changed-payer requests. After the
|
|
909
|
+
root billing admin explicitly agrees, use `credits accept-price <price_id>` or
|
|
910
|
+
`credits approve-payer <operation_id> --revision <revision> --request-key <unique_key>`.
|
|
911
|
+
Approval never resumes waiting work. Increased prices also require the notice period.
|
|
912
|
+
|
|
913
|
+
Omalab staff can use `credits refund-review <usage_id>` to inspect the exact charge,
|
|
914
|
+
result and previous reviews. After confirming a defect, `credits refund <usage_id>
|
|
915
|
+
--cumulative-principal <exact_credits> --evidence-token <uuid> --reason <reason>
|
|
916
|
+
--evidence <exact_result_evidence>` records the cumulative credit return. Customer
|
|
917
|
+
billing admins cannot use these staff actions. This never refunds cash.
|
package/package.json
CHANGED
package/src/api-client.js
CHANGED
|
@@ -1154,6 +1154,12 @@ export class AudientiClient {
|
|
|
1154
1154
|
});
|
|
1155
1155
|
}
|
|
1156
1156
|
|
|
1157
|
+
deferCommentRetry(accountId, eventId) {
|
|
1158
|
+
return this.requestJson(accountPath(accountId, ["events", eventId, "defer_comment_retry"]), {
|
|
1159
|
+
method: "POST"
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1157
1163
|
resolveUncertainCommentStatus(accountId, eventId, resolutionId) {
|
|
1158
1164
|
return this.requestJson(accountPath(accountId, ["events", eventId, "resolve_uncertain_comment", "status"], { resolution_id: resolutionId }));
|
|
1159
1165
|
}
|
|
@@ -1351,6 +1357,34 @@ export class AudientiClient {
|
|
|
1351
1357
|
return this.requestJson(accountPath(accountId, ["tools", "runs", runId, "export"], query));
|
|
1352
1358
|
}
|
|
1353
1359
|
|
|
1360
|
+
creditRefundReview(accountId, usageId) {
|
|
1361
|
+
return this.requestJson(accountPath(accountId, ["credit_usages", usageId, "refund"]));
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
approveCreditRefund(accountId, usageId, body) {
|
|
1365
|
+
return this.requestJson(accountPath(accountId, ["credit_usages", usageId, "refund"]), { method: "POST", body });
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
creditUsages(accountId, query = {}) {
|
|
1369
|
+
return this.requestJson(accountPath(accountId, ["credit_usages"], query));
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
creditUsage(accountId, usageId) {
|
|
1373
|
+
return this.requestJson(accountPath(accountId, ["credit_usages", usageId]));
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
creditApprovals(accountId) {
|
|
1377
|
+
return this.requestJson(accountPath(accountId, ["credit_approvals"]));
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
acceptCreditPrice(accountId, priceId) {
|
|
1381
|
+
return this.requestJson(accountPath(accountId, ["credit_approvals", "prices", priceId]), { method: "POST", body: {} });
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
approveCreditPayer(accountId, operationId, body) {
|
|
1385
|
+
return this.requestJson(accountPath(accountId, ["credit_approvals", "payers", operationId]), { method: "POST", body });
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1354
1388
|
// Saved network of one connected account (owner-only).
|
|
1355
1389
|
socialCookieNetwork(accountId, socialCookieId, query = {}) {
|
|
1356
1390
|
return this.requestJson(accountPath(accountId, ["social_cookies", socialCookieId, "network"], query));
|
package/src/cli.js
CHANGED
|
@@ -231,6 +231,7 @@ 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 CREDITS_USAGE = "Usage: audienti credits (history [--limit <n>] [--cursor <id>] | show <usage_id> | approvals | accept-price <price_id> | approve-payer <operation_id> --revision <revision> --request-key <key>) [--json] [--account <acct_id>]";
|
|
234
235
|
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
236
|
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
237
|
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}`;
|
|
@@ -429,6 +430,7 @@ async function dispatch(argv, context) {
|
|
|
429
430
|
if (normalizedResource === "webhooks") return webhooksCommand(action, rest, context, { accountOverride });
|
|
430
431
|
if (normalizedResource === "reply-alerts") return replyAlertsCommand(action, rest, context);
|
|
431
432
|
if (normalizedResource === "brand-profile") return brandProfileCommand(action, rest, context, { accountOverride });
|
|
433
|
+
if (normalizedResource === "credits") return creditsCommand(action, rest, context, { accountOverride });
|
|
432
434
|
if (normalizedResource === "payment") return paymentCommand(action, rest, context, { accountOverride });
|
|
433
435
|
if (normalizedResource === "find") return findByName([action, ...rest].filter((value) => value !== undefined), context, { accountOverride });
|
|
434
436
|
if (normalizedResource === "tags" && action === "list") return tagsList(rest, context, { accountOverride });
|
|
@@ -15899,6 +15901,16 @@ const PARITY_ACTION_COMMANDS = new Map([
|
|
|
15899
15901
|
return `Event ${id} is recorded as posted (${display(payload?.status)}).`;
|
|
15900
15902
|
}
|
|
15901
15903
|
}],
|
|
15904
|
+
["events defer-comment-retry", {
|
|
15905
|
+
usage: "audienti events defer-comment-retry <event_id>",
|
|
15906
|
+
purpose: "Say \"Not now\" to the \"Not sent: try again?\" offer for a post comment you settled as not sent. Hides the offer for 24 hours; it comes back once, and a second \"Not now\" ends it. Nothing is sent.",
|
|
15907
|
+
api: "POST /api/v1/accounts/:account_id/events/:id/defer_comment_retry.json",
|
|
15908
|
+
run: (client, accountId, [id]) => client.deferCommentRetry(accountId, id),
|
|
15909
|
+
done: ([id], payload) => {
|
|
15910
|
+
if (payload?.status === "retired" || payload?.status === "already_retired") return `Event ${id}: the offer to send again has ended. Nothing was sent.`;
|
|
15911
|
+
return `Event ${id}: the offer to send again is hidden until ${display(payload?.hidden_until)}. Nothing was sent.`;
|
|
15912
|
+
}
|
|
15913
|
+
}],
|
|
15902
15914
|
["events resolve-uncertain-comment-status", {
|
|
15903
15915
|
usage: "audienti events resolve-uncertain-comment-status <event_id> --resolution <resolution_id>",
|
|
15904
15916
|
purpose: "Show whether your Computer has finished checking a short comment link: checking, resolved or failed. Read-only.",
|
|
@@ -16403,6 +16415,8 @@ async function toolsSignalsFind(args, context, { accountOverride } = {}) {
|
|
|
16403
16415
|
const { values, positionals } = parseCommandArgs(args, {
|
|
16404
16416
|
...jsonOptions(),
|
|
16405
16417
|
...TOOL_RUN_WAIT_OPTIONS,
|
|
16418
|
+
quote: { type: "boolean" },
|
|
16419
|
+
"accept-quote": { type: "string" },
|
|
16406
16420
|
icp: { type: "string" },
|
|
16407
16421
|
question: { type: "string" },
|
|
16408
16422
|
count: { type: "string" },
|
|
@@ -16456,7 +16470,7 @@ async function submitToolRun(tool, input, values, context, { accountOverride } =
|
|
|
16456
16470
|
if (values["accept-quote"]) throw new CommandError("Choose --quote or --accept-quote, not both.");
|
|
16457
16471
|
const quote = await client.quoteToolRun(accountId, { tool, input });
|
|
16458
16472
|
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.`);
|
|
16473
|
+
writeLine(context.stdout, `Up to ${quote.maximum_credits} credits for ${tool === "signals_find" ? "one search" : `${quote.max_units} rows`}. Available: ${quote.available_credits} credits.`);
|
|
16460
16474
|
writeLine(context.stdout, `Accept with the same input and --accept-quote ${quote.quote_reference}`);
|
|
16461
16475
|
return 0;
|
|
16462
16476
|
}
|
|
@@ -16545,6 +16559,140 @@ async function toolsRunsCredits(action, args, context, { accountOverride } = {})
|
|
|
16545
16559
|
return writeJson(context.stdout, result);
|
|
16546
16560
|
}
|
|
16547
16561
|
|
|
16562
|
+
async function creditsCommand(action, args, context, { accountOverride } = {}) {
|
|
16563
|
+
if (["refund-review", "refund"].includes(action)) return creditRefundCommand(action, args, context, { accountOverride });
|
|
16564
|
+
if (action === "history") return creditsHistory(args, context, { accountOverride });
|
|
16565
|
+
if (action === "show") return creditUsageShow(args, context, { accountOverride });
|
|
16566
|
+
if (action === "approvals") return creditApprovals(args, context, { accountOverride });
|
|
16567
|
+
if (action === "accept-price") return acceptCreditPrice(args, context, { accountOverride });
|
|
16568
|
+
if (action === "approve-payer") return approveCreditPayer(args, context, { accountOverride });
|
|
16569
|
+
throw new CommandError(CREDITS_USAGE);
|
|
16570
|
+
}
|
|
16571
|
+
|
|
16572
|
+
async function creditRefundCommand(action, args, context, { accountOverride } = {}) {
|
|
16573
|
+
const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(),
|
|
16574
|
+
"cumulative-principal": { type: "string" }, "evidence-token": { type: "string" }, reason: { type: "string" }, evidence: { type: "string" }
|
|
16575
|
+
});
|
|
16576
|
+
if (positionals.length !== 1) throw new CommandError(CREDITS_USAGE);
|
|
16577
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16578
|
+
if (action === "refund-review") return writeJson(context.stdout, await client.creditRefundReview(accountId, positionals[0]));
|
|
16579
|
+
if (!["cumulative-principal", "evidence-token", "reason", "evidence"].every((key) => values[key])) {
|
|
16580
|
+
throw new CommandError("Staff only: credits refund <usage_id> --cumulative-principal <exact_credits> --evidence-token <uuid> --reason <confirmed_defect> --evidence <exact_result_evidence>");
|
|
16581
|
+
}
|
|
16582
|
+
return writeJson(context.stdout, await client.approveCreditRefund(accountId, positionals[0], {
|
|
16583
|
+
cumulative_principal: values["cumulative-principal"], evidence_token: values["evidence-token"], reason: values.reason, evidence: values.evidence
|
|
16584
|
+
}));
|
|
16585
|
+
}
|
|
16586
|
+
|
|
16587
|
+
async function creditsHistory(args, context, { accountOverride } = {}) {
|
|
16588
|
+
const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(), limit: { type: "string" }, cursor: { type: "string" } });
|
|
16589
|
+
if (positionals.length > 0) throw new CommandError(CREDITS_USAGE);
|
|
16590
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16591
|
+
const payload = safeCreditHistory(await client.creditUsages(accountId, compactObject({
|
|
16592
|
+
limit: normalizeOptionalPositiveInteger(values.limit, "--limit"), cursor: values.cursor
|
|
16593
|
+
})));
|
|
16594
|
+
if (values.json) return writeJson(context.stdout, payload);
|
|
16595
|
+
writeLine(context.stdout, `Credit balance: ${display(payload.balance, "unknown")}`);
|
|
16596
|
+
const usages = payload.usages || [];
|
|
16597
|
+
if (usages.length === 0) return writeLine(context.stdout, "No customer credit charges recorded.");
|
|
16598
|
+
for (const usage of usages) renderCreditReceipt(usage, context);
|
|
16599
|
+
if (payload.next_cursor) writeLine(context.stdout, `More credit history: audienti credits history --cursor ${payload.next_cursor}`);
|
|
16600
|
+
}
|
|
16601
|
+
|
|
16602
|
+
async function creditUsageShow(args, context, { accountOverride } = {}) {
|
|
16603
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
16604
|
+
if (positionals.length !== 1) throw new CommandError(CREDITS_USAGE);
|
|
16605
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16606
|
+
const usage = safeCreditReceipt(await client.creditUsage(accountId, positionals[0]));
|
|
16607
|
+
if (values.json) return writeJson(context.stdout, usage);
|
|
16608
|
+
renderCreditReceipt(usage, context);
|
|
16609
|
+
}
|
|
16610
|
+
|
|
16611
|
+
async function creditApprovals(args, context, { accountOverride } = {}) {
|
|
16612
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
16613
|
+
if (positionals.length > 0) throw new CommandError(CREDITS_USAGE);
|
|
16614
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16615
|
+
const approvals = safeCreditApprovals(await client.creditApprovals(accountId));
|
|
16616
|
+
if (values.json) return writeJson(context.stdout, approvals);
|
|
16617
|
+
renderCreditApprovals(approvals, context);
|
|
16618
|
+
}
|
|
16619
|
+
|
|
16620
|
+
async function acceptCreditPrice(args, context, { accountOverride } = {}) {
|
|
16621
|
+
const { values, positionals } = parseCommandArgs(args, jsonOptions());
|
|
16622
|
+
if (positionals.length !== 1) throw new CommandError(CREDITS_USAGE);
|
|
16623
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16624
|
+
const approvals = safeCreditApprovals(await client.acceptCreditPrice(accountId, positionals[0]));
|
|
16625
|
+
if (values.json) return writeJson(context.stdout, approvals);
|
|
16626
|
+
writeLine(context.stdout, `Price approval recorded for ${positionals[0]}.`);
|
|
16627
|
+
renderCreditApprovals(approvals, context);
|
|
16628
|
+
}
|
|
16629
|
+
|
|
16630
|
+
async function approveCreditPayer(args, context, { accountOverride } = {}) {
|
|
16631
|
+
const { values, positionals } = parseCommandArgs(args, { ...jsonOptions(), revision: { type: "string" }, "request-key": { type: "string" } });
|
|
16632
|
+
if (positionals.length !== 1 || !values.revision || !values["request-key"]) throw new CommandError(CREDITS_USAGE);
|
|
16633
|
+
const { client, accountId } = await requireAccountContext(context, { accountOverride });
|
|
16634
|
+
const approvals = safeCreditApprovals(await client.approveCreditPayer(accountId, positionals[0], {
|
|
16635
|
+
revision: values.revision, idempotency_key: values["request-key"]
|
|
16636
|
+
}));
|
|
16637
|
+
if (values.json) return writeJson(context.stdout, approvals);
|
|
16638
|
+
writeLine(context.stdout, `Payer approval recorded for operation ${positionals[0]}. Waiting work remains paused.`);
|
|
16639
|
+
renderCreditApprovals(approvals, context);
|
|
16640
|
+
}
|
|
16641
|
+
|
|
16642
|
+
function renderCreditApprovals(approvals, context) {
|
|
16643
|
+
writeLine(context.stdout, `Payer: ${display(approvals.payer_account_id, "unknown")}`);
|
|
16644
|
+
writeLine(context.stdout, "Credit prices:");
|
|
16645
|
+
for (const price of approvals.prices || []) {
|
|
16646
|
+
writeLine(context.stdout, ` ${price.id} ${price.version}: ${JSON.stringify(price.prices)} credits (${price.accepted ? "approved" : "approval required"})${price.test_price ? " [test price]" : ""}`);
|
|
16647
|
+
}
|
|
16648
|
+
writeLine(context.stdout, "Payer approvals waiting:");
|
|
16649
|
+
for (const approval of approvals.payer_approvals || []) {
|
|
16650
|
+
writeLine(context.stdout, ` ${approval.operation_id} workspace ${approval.origin_account_id}: ${approval.action_label}, price ${approval.price_version}, maximum ${approval.maximum_credits} credits, revision ${approval.revision}`);
|
|
16651
|
+
}
|
|
16652
|
+
}
|
|
16653
|
+
|
|
16654
|
+
function renderCreditReceipt(usage, context) {
|
|
16655
|
+
writeLine(context.stdout, `${display(usage.label, "Credit usage")} (${display(usage.id, "unknown")})`);
|
|
16656
|
+
if (usage.origin_account_id) writeLine(context.stdout, `Workspace: ${usage.origin_account_id}`);
|
|
16657
|
+
if (typeof usage.credits === "string") writeLine(context.stdout, `Credits charged: ${usage.credits}`);
|
|
16658
|
+
if (typeof usage.returned_credits === "string") writeLine(context.stdout, `Credits returned: ${usage.returned_credits}`);
|
|
16659
|
+
if (usage.created_at) writeLine(context.stdout, `Date: ${usage.created_at}`);
|
|
16660
|
+
if (usage.result_url && usage.result_available) writeLine(context.stdout, `Saved result: ${usage.result_url}`);
|
|
16661
|
+
else if (usage.result_message) writeLine(context.stdout, usage.result_message);
|
|
16662
|
+
}
|
|
16663
|
+
|
|
16664
|
+
function safeCreditHistory(payload) {
|
|
16665
|
+
const result = {};
|
|
16666
|
+
if (typeof payload?.balance === "string") result.balance = payload.balance;
|
|
16667
|
+
if (Array.isArray(payload?.usages)) result.usages = payload.usages.map(safeCreditReceipt);
|
|
16668
|
+
if (typeof payload?.next_cursor === "string") result.next_cursor = payload.next_cursor;
|
|
16669
|
+
return result;
|
|
16670
|
+
}
|
|
16671
|
+
|
|
16672
|
+
function safeCreditReceipt(usage) {
|
|
16673
|
+
return pickFields(usage, ["id", "key", "label", "credits", "returned_credits", "origin_account_id", "created_at", "result_available", "result_url", "result_message"], {
|
|
16674
|
+
decimalFields: ["credits", "returned_credits"]
|
|
16675
|
+
});
|
|
16676
|
+
}
|
|
16677
|
+
|
|
16678
|
+
function safeCreditApprovals(payload) {
|
|
16679
|
+
const result = {};
|
|
16680
|
+
if (typeof payload?.payer_account_id === "string") result.payer_account_id = payload.payer_account_id;
|
|
16681
|
+
if (Array.isArray(payload?.prices)) result.prices = payload.prices.map((price) => ({ ...pickFields(price, ["id", "version", "effective_at", "email_sent_at", "accepted", "test_price"]), prices: Object.fromEntries(Object.entries(price.prices || {}).filter(([key, value]) => ["tool.email_find", "tool.signals_find"].includes(key) && typeof value === "string")) }));
|
|
16682
|
+
if (Array.isArray(payload?.payer_approvals)) result.payer_approvals = payload.payer_approvals.map((approval) => pickFields(approval,
|
|
16683
|
+
["operation_id", "origin_account_id", "key", "action_label", "price_version", "revision", "maximum_credits"], { decimalFields: ["maximum_credits"] }));
|
|
16684
|
+
return result;
|
|
16685
|
+
}
|
|
16686
|
+
|
|
16687
|
+
function pickFields(value, fields, { decimalFields = [] } = {}) {
|
|
16688
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
16689
|
+
return Object.fromEntries(fields.filter((field) => {
|
|
16690
|
+
if (!Object.hasOwn(value, field)) return false;
|
|
16691
|
+
if (decimalFields.includes(field)) return typeof value[field] === "string";
|
|
16692
|
+
return typeof value[field] === "string" || typeof value[field] === "boolean" || Number.isSafeInteger(value[field]);
|
|
16693
|
+
}).map((field) => [field, value[field]]));
|
|
16694
|
+
}
|
|
16695
|
+
|
|
16548
16696
|
async function toolsRunsList(args, context, { accountOverride } = {}) {
|
|
16549
16697
|
const { values, positionals } = parseCommandArgs(args, {
|
|
16550
16698
|
...jsonOptions(),
|