@erdoai/cli 0.26.0 → 0.28.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 +95 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -524,6 +524,21 @@ var ErdoClient = class {
|
|
|
524
524
|
timezone
|
|
525
525
|
});
|
|
526
526
|
}
|
|
527
|
+
// Fetch rows from a dataset, optionally shaped by a SQL query and/or opting into
|
|
528
|
+
// named saved filters. filter_names are additive on top of the dataset's default
|
|
529
|
+
// filters — they narrow the result, never bypass a default. An unknown name is
|
|
530
|
+
// rejected server-side with the available names.
|
|
531
|
+
fetchDatasetContents(slug, opts) {
|
|
532
|
+
return this.request(
|
|
533
|
+
"POST",
|
|
534
|
+
`/v1/datasets/${encodeURIComponent(slug)}/fetch`,
|
|
535
|
+
{
|
|
536
|
+
sql_query: opts.sql_query,
|
|
537
|
+
limit: opts.limit,
|
|
538
|
+
filter_names: opts.filter_names
|
|
539
|
+
}
|
|
540
|
+
);
|
|
541
|
+
}
|
|
527
542
|
uploadDatasetFile(body) {
|
|
528
543
|
return this.request("POST", "/v1/datasets-upload", body);
|
|
529
544
|
}
|
|
@@ -2023,34 +2038,60 @@ attnCmd.command("list").description("List attention items").option("--status <st
|
|
|
2023
2038
|
}
|
|
2024
2039
|
);
|
|
2025
2040
|
attnCmd.command("respond <id>").description(
|
|
2026
|
-
`Respond to an attention item. A choice answer's shape is {"<question_id>": ["<option>", ...]}. Answering a choice mapped to experiment variants records your pick as a human comparison in the calibration ledger.`
|
|
2027
|
-
).option("--answer <json>", `a JSON answer, e.g. '{"q1":["option-a"]}'`).option(
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
+
`Respond to an attention item. A choice answer's shape is {"<question_id>": ["<option>", ...]}. Answering a choice mapped to experiment variants records your pick as a human comparison in the calibration ledger. Use --flag-broken to flag one or more variants as broken (recorded as defect observations judge generation reads) \u2014 on its own or alongside --answer.`
|
|
2042
|
+
).option("--answer <json>", `a JSON answer, e.g. '{"q1":["option-a"]}'`).option(
|
|
2043
|
+
"--flag-broken <json>",
|
|
2044
|
+
'flag choice variants as broken: JSON array [{"variant_key":"...","reason":"..."}]'
|
|
2045
|
+
).option("--ack", "mark read / acknowledge").option("--dismiss", "dismiss the item").action(
|
|
2046
|
+
async (id, opts) => {
|
|
2047
|
+
try {
|
|
2048
|
+
if (opts.ack || opts.dismiss) {
|
|
2049
|
+
if (opts.ack && opts.dismiss) {
|
|
2050
|
+
fail(new Error("provide only one of --ack or --dismiss"));
|
|
2051
|
+
}
|
|
2052
|
+
if (opts.answer !== void 0 || opts.flagBroken !== void 0) {
|
|
2053
|
+
fail(new Error("--answer / --flag-broken cannot be combined with --ack or --dismiss"));
|
|
2054
|
+
}
|
|
2055
|
+
print(
|
|
2056
|
+
await new ErdoClient().respondAttentionItem(id, {
|
|
2057
|
+
action: opts.ack ? "acknowledge" : "dismiss"
|
|
2058
|
+
})
|
|
2041
2059
|
);
|
|
2060
|
+
return;
|
|
2042
2061
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2062
|
+
if (opts.answer === void 0 && opts.flagBroken === void 0) {
|
|
2063
|
+
fail(new Error("provide one of --answer, --flag-broken, --ack, or --dismiss"));
|
|
2064
|
+
}
|
|
2065
|
+
const input = { action: "answer" };
|
|
2066
|
+
if (opts.answer !== void 0) {
|
|
2067
|
+
try {
|
|
2068
|
+
input.answer = JSON.parse(opts.answer);
|
|
2069
|
+
} catch {
|
|
2070
|
+
throw new Error(
|
|
2071
|
+
`--answer must be valid JSON, e.g. '{"<question_id>": ["<option>", ...]}'`
|
|
2072
|
+
);
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
if (opts.flagBroken !== void 0) {
|
|
2076
|
+
let parsed;
|
|
2077
|
+
try {
|
|
2078
|
+
parsed = JSON.parse(opts.flagBroken);
|
|
2079
|
+
} catch {
|
|
2080
|
+
throw new Error(
|
|
2081
|
+
`--flag-broken must be valid JSON, e.g. '[{"variant_key":"b","reason":"clipped hero"}]'`
|
|
2082
|
+
);
|
|
2083
|
+
}
|
|
2084
|
+
if (!Array.isArray(parsed)) {
|
|
2085
|
+
throw new Error('--flag-broken must be a JSON array of {"variant_key","reason"} objects');
|
|
2086
|
+
}
|
|
2087
|
+
input.defects = parsed;
|
|
2088
|
+
}
|
|
2089
|
+
print(await new ErdoClient().respondAttentionItem(id, input));
|
|
2090
|
+
} catch (e) {
|
|
2091
|
+
fail(e);
|
|
2048
2092
|
}
|
|
2049
|
-
print(await new ErdoClient().respondAttentionItem(id, input));
|
|
2050
|
-
} catch (e) {
|
|
2051
|
-
fail(e);
|
|
2052
2093
|
}
|
|
2053
|
-
|
|
2094
|
+
);
|
|
2054
2095
|
var reviewsCmd = program.command("reviews").description(
|
|
2055
2096
|
"The Knowledge Review queue \u2014 knowledge patches the critic proposes, investigations, and deduplicated failure signals awaiting a human decision"
|
|
2056
2097
|
);
|
|
@@ -2210,6 +2251,24 @@ datasetsCmd.command("query <slug> <question>").description("Ask a natural-langua
|
|
|
2210
2251
|
fail(e);
|
|
2211
2252
|
}
|
|
2212
2253
|
});
|
|
2254
|
+
datasetsCmd.command("fetch <slug>").description("Fetch rows from a dataset, optionally shaped by SQL and named filters").option("-q, --sql <query>", "SQL query to filter/transform the rows").option("-l, --limit <n>", "max rows to return", (v) => parseInt(v, 10)).option(
|
|
2255
|
+
"-f, --filter <name>",
|
|
2256
|
+
"opt into a saved filter by name (repeatable); additive on top of the dataset's default filters (see: erdo datasets filter list <slug>)",
|
|
2257
|
+
(v, acc) => acc.concat(v),
|
|
2258
|
+
[]
|
|
2259
|
+
).action(async (slug, opts) => {
|
|
2260
|
+
try {
|
|
2261
|
+
print(
|
|
2262
|
+
await new ErdoClient().fetchDatasetContents(slug, {
|
|
2263
|
+
sql_query: opts.sql,
|
|
2264
|
+
limit: opts.limit,
|
|
2265
|
+
filter_names: opts.filter.length ? opts.filter : void 0
|
|
2266
|
+
})
|
|
2267
|
+
);
|
|
2268
|
+
} catch (e) {
|
|
2269
|
+
fail(e);
|
|
2270
|
+
}
|
|
2271
|
+
});
|
|
2213
2272
|
var MAX_UPLOAD_BYTES = 20 * 1024 * 1024;
|
|
2214
2273
|
datasetsCmd.command("upload <file>").description("Upload a file (CSV, Excel, JSON, ...) and create a dataset from it").option("-n, --name <name>", "display name for the dataset (defaults to the filename)").option("-d, --description <text>", "description shown to agents analyzing the dataset").action(async (file, opts) => {
|
|
2215
2274
|
try {
|
|
@@ -2349,15 +2408,24 @@ pipelinesCmd.command("get <slug>").description("Show one event pipeline \u2014 s
|
|
|
2349
2408
|
fail(e);
|
|
2350
2409
|
}
|
|
2351
2410
|
});
|
|
2352
|
-
filterCmd.command("add <slug>").description("Add a
|
|
2411
|
+
filterCmd.command("add <slug>").description("Add a filter to a dataset (default-on unless --no-default)").requiredOption(
|
|
2353
2412
|
"--where <condition>",
|
|
2354
2413
|
"a '<column> <operator> <value>' condition (repeatable, AND-combined), e.g. --where 'email contains @example.com'. Operators: " + OPERATORS.join(", ") + " (for 'between' use 'col between 10,100')",
|
|
2355
2414
|
collect,
|
|
2356
2415
|
[]
|
|
2357
|
-
).option("--name <name>", "optional human-readable label, e.g. 'Exclude test submissions'").
|
|
2416
|
+
).option("--name <name>", "optional human-readable label, e.g. 'Exclude test submissions'").option(
|
|
2417
|
+
"--no-default",
|
|
2418
|
+
"save as a named view that reads opt into with 'datasets fetch --filter <name>', instead of applying to every read"
|
|
2419
|
+
).action(async (slug, opts) => {
|
|
2358
2420
|
try {
|
|
2359
2421
|
const conditions = opts.where.map(parseCondition);
|
|
2360
|
-
print(
|
|
2422
|
+
print(
|
|
2423
|
+
await new ErdoClient().createDatasetFilter(slug, {
|
|
2424
|
+
name: opts.name,
|
|
2425
|
+
conditions,
|
|
2426
|
+
is_default: opts.default === false ? false : void 0
|
|
2427
|
+
})
|
|
2428
|
+
);
|
|
2361
2429
|
} catch (e) {
|
|
2362
2430
|
fail(e);
|
|
2363
2431
|
}
|