@2kw/ai 4.0.0-dev.2

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.
Files changed (69) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +91 -0
  3. package/dist/commands/ai.d.ts +3 -0
  4. package/dist/commands/ai.js +72 -0
  5. package/dist/commands/analytics.d.ts +3 -0
  6. package/dist/commands/analytics.js +161 -0
  7. package/dist/commands/auth.d.ts +3 -0
  8. package/dist/commands/auth.js +134 -0
  9. package/dist/commands/billing.d.ts +3 -0
  10. package/dist/commands/billing.js +102 -0
  11. package/dist/commands/config.d.ts +3 -0
  12. package/dist/commands/config.js +90 -0
  13. package/dist/commands/context.d.ts +3 -0
  14. package/dist/commands/context.js +149 -0
  15. package/dist/commands/convert.d.ts +3 -0
  16. package/dist/commands/convert.js +291 -0
  17. package/dist/commands/dataset-versions.d.ts +3 -0
  18. package/dist/commands/dataset-versions.js +90 -0
  19. package/dist/commands/datasets.d.ts +3 -0
  20. package/dist/commands/datasets.js +150 -0
  21. package/dist/commands/docs.d.ts +3 -0
  22. package/dist/commands/docs.js +166 -0
  23. package/dist/commands/evaluators.d.ts +3 -0
  24. package/dist/commands/evaluators.js +124 -0
  25. package/dist/commands/experiments.d.ts +3 -0
  26. package/dist/commands/experiments.js +255 -0
  27. package/dist/commands/extractions.d.ts +3 -0
  28. package/dist/commands/extractions.js +134 -0
  29. package/dist/commands/prompt-labels.d.ts +3 -0
  30. package/dist/commands/prompt-labels.js +67 -0
  31. package/dist/commands/prompt-versions.d.ts +3 -0
  32. package/dist/commands/prompt-versions.js +65 -0
  33. package/dist/commands/prompts.d.ts +3 -0
  34. package/dist/commands/prompts.js +159 -0
  35. package/dist/commands/providers.d.ts +3 -0
  36. package/dist/commands/providers.js +115 -0
  37. package/dist/commands/schema-labels.d.ts +3 -0
  38. package/dist/commands/schema-labels.js +67 -0
  39. package/dist/commands/schema-versions.d.ts +3 -0
  40. package/dist/commands/schema-versions.js +66 -0
  41. package/dist/commands/schemas.d.ts +3 -0
  42. package/dist/commands/schemas.js +178 -0
  43. package/dist/commands/scores.d.ts +3 -0
  44. package/dist/commands/scores.js +31 -0
  45. package/dist/commands/tracing.d.ts +3 -0
  46. package/dist/commands/tracing.js +85 -0
  47. package/dist/commands/transcribe.d.ts +3 -0
  48. package/dist/commands/transcribe.js +65 -0
  49. package/dist/index.d.ts +3 -0
  50. package/dist/index.js +54 -0
  51. package/dist/lib/client.d.ts +12 -0
  52. package/dist/lib/client.js +52 -0
  53. package/dist/lib/config.d.ts +44 -0
  54. package/dist/lib/config.js +217 -0
  55. package/dist/lib/datasets.d.ts +6 -0
  56. package/dist/lib/datasets.js +10 -0
  57. package/dist/lib/errors.d.ts +14 -0
  58. package/dist/lib/errors.js +54 -0
  59. package/dist/lib/multipart.d.ts +10 -0
  60. package/dist/lib/multipart.js +59 -0
  61. package/dist/lib/output.d.ts +29 -0
  62. package/dist/lib/output.js +107 -0
  63. package/dist/lib/pagination.d.ts +21 -0
  64. package/dist/lib/pagination.js +21 -0
  65. package/dist/lib/schema-compat.d.ts +11 -0
  66. package/dist/lib/schema-compat.js +51 -0
  67. package/dist/lib/update-notifier.d.ts +9 -0
  68. package/dist/lib/update-notifier.js +96 -0
  69. package/package.json +49 -0
@@ -0,0 +1,150 @@
1
+ import { Command } from "commander";
2
+ import { getClient, runAction } from "../lib/client.js";
3
+ import { resolveLatestVersionId } from "../lib/datasets.js";
4
+ import { formatPage, formatDetail, formatSuccess } from "../lib/output.js";
5
+ import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
6
+ import { makeDatasetVersionsCommand } from "./dataset-versions.js";
7
+ export function makeDatasetsCommand() {
8
+ const cmd = new Command("datasets").description("Manage datasets");
9
+ const list = new Command("list").description("List datasets");
10
+ addPaginationOptions(list);
11
+ list.option("-s, --search <term>", "Filter by name");
12
+ list.option("-t, --type <type>", "Filter by type");
13
+ list.action(async (opts, command) => {
14
+ await runAction(command, async () => {
15
+ const client = getClient(command);
16
+ const { data } = await client.GET("/v1/datasets", {
17
+ params: {
18
+ query: { search: opts.search, type: opts.type, ...paginationParams(opts) },
19
+ },
20
+ });
21
+ formatPage(data, command, ["id", "name", "type", "description", "latestVersionId", "createdAt"]);
22
+ });
23
+ });
24
+ cmd.addCommand(list);
25
+ cmd
26
+ .command("get")
27
+ .description("Get a dataset by ID")
28
+ .argument("<id>", "Dataset ID")
29
+ .action(async (id, _opts, command) => {
30
+ await runAction(command, async () => {
31
+ const client = getClient(command);
32
+ const { data } = await client.GET("/v1/datasets/{id}", {
33
+ params: { path: { id } },
34
+ });
35
+ formatDetail(data, command);
36
+ });
37
+ });
38
+ cmd
39
+ .command("create")
40
+ .description("Create a new dataset")
41
+ .requiredOption("-n, --name <name>", "Dataset name")
42
+ .option("-d, --description <text>", "Dataset description")
43
+ .option("-t, --type <type>", "Dataset type")
44
+ .option("--input-schema <json>", "Input JSON Schema")
45
+ .option("--expected-output-schema <json>", "Expected output JSON Schema")
46
+ .option("--metadata <json>", "Metadata (JSON)")
47
+ .action(async (opts, command) => {
48
+ await runAction(command, async () => {
49
+ const client = getClient(command);
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ const body = { name: opts.name };
52
+ if (opts.description !== undefined)
53
+ body.description = opts.description;
54
+ if (opts.type !== undefined)
55
+ body.type = opts.type;
56
+ if (opts.inputSchema)
57
+ body.inputSchema = JSON.parse(opts.inputSchema);
58
+ if (opts.expectedOutputSchema)
59
+ body.expectedOutputSchema = JSON.parse(opts.expectedOutputSchema);
60
+ if (opts.metadata)
61
+ body.metadata = JSON.parse(opts.metadata);
62
+ const { data } = await client.POST("/v1/datasets", {
63
+ body: body,
64
+ });
65
+ formatDetail(data, command);
66
+ });
67
+ });
68
+ cmd
69
+ .command("update")
70
+ .description("Update a dataset")
71
+ .argument("<id>", "Dataset ID")
72
+ .option("-n, --name <name>", "New name")
73
+ .option("-d, --description <text>", "New description")
74
+ .option("-t, --type <type>", "New type")
75
+ .option("--input-schema <json>", "Input JSON Schema")
76
+ .option("--expected-output-schema <json>", "Expected output JSON Schema")
77
+ .option("--metadata <json>", "Metadata (JSON)")
78
+ .action(async (id, opts, command) => {
79
+ await runAction(command, async () => {
80
+ const client = getClient(command);
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
+ const body = {};
83
+ if (opts.name)
84
+ body.name = opts.name;
85
+ if (opts.description !== undefined)
86
+ body.description = opts.description;
87
+ if (opts.type !== undefined)
88
+ body.type = opts.type;
89
+ if (opts.inputSchema)
90
+ body.inputSchema = JSON.parse(opts.inputSchema);
91
+ if (opts.expectedOutputSchema)
92
+ body.expectedOutputSchema = JSON.parse(opts.expectedOutputSchema);
93
+ if (opts.metadata)
94
+ body.metadata = JSON.parse(opts.metadata);
95
+ const { data } = await client.PUT("/v1/datasets/{id}", {
96
+ params: { path: { id } },
97
+ body: body,
98
+ });
99
+ formatDetail(data, command);
100
+ });
101
+ });
102
+ cmd
103
+ .command("delete")
104
+ .description("Delete a dataset")
105
+ .argument("<id>", "Dataset ID")
106
+ .action(async (id, _opts, command) => {
107
+ await runAction(command, async () => {
108
+ const client = getClient(command);
109
+ await client.DELETE("/v1/datasets/{id}", {
110
+ params: { path: { id } },
111
+ });
112
+ formatSuccess(`Dataset ${id} deleted.`, command);
113
+ });
114
+ });
115
+ cmd
116
+ .command("add-item")
117
+ .description("Add an item to a dataset (uses the latest version)")
118
+ .requiredOption("--dataset <id>", "Dataset ID")
119
+ .requiredOption("--input <json>", "Item input data (JSON)")
120
+ .option("--expected-output <json>", "Expected output (JSON)")
121
+ .option("--tags <tags...>", "Tags")
122
+ .option("--metadata <json>", "Metadata (JSON)")
123
+ .action(async (opts, command) => {
124
+ await runAction(command, async () => {
125
+ const client = getClient(command);
126
+ const versionId = await resolveLatestVersionId(client, opts.dataset);
127
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
+ const body = {
129
+ input: JSON.parse(opts.input),
130
+ };
131
+ if (opts.expectedOutput)
132
+ body.expectedOutput = JSON.parse(opts.expectedOutput);
133
+ if (opts.tags)
134
+ body.tags = opts.tags;
135
+ if (opts.metadata)
136
+ body.metadata = JSON.parse(opts.metadata);
137
+ const { data } = await client.POST("/v1/datasets/{id}/versions/{versionId}/items", {
138
+ params: {
139
+ // OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
140
+ path: { id: opts.dataset, versionId },
141
+ },
142
+ body: body,
143
+ });
144
+ formatDetail(data, command);
145
+ });
146
+ });
147
+ cmd.addCommand(makeDatasetVersionsCommand());
148
+ return cmd;
149
+ }
150
+ //# sourceMappingURL=datasets.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeDocsCommand(): Command;
3
+ //# sourceMappingURL=docs.d.ts.map
@@ -0,0 +1,166 @@
1
+ import { Command } from "commander";
2
+ import { runAction } from "../lib/client.js";
3
+ import { resolveConfig, isJsonOutput } from "../lib/config.js";
4
+ /* eslint-enable @typescript-eslint/no-explicit-any */
5
+ /**
6
+ * Fetch the OpenAPI spec from the backend.
7
+ */
8
+ async function fetchSpec(baseUrl, apiKey) {
9
+ const specUrl = `${baseUrl.replace(/\/+$/, "")}/v3/api-docs`;
10
+ const res = await fetch(specUrl, {
11
+ headers: { Authorization: `Bearer ${apiKey}` },
12
+ });
13
+ if (!res.ok) {
14
+ if (res.status === 404 || res.status === 403) {
15
+ throw new Error("API documentation is not available. Enable it by setting SPRINGDOC_ENABLED=true on the backend.");
16
+ }
17
+ throw new Error(`Failed to fetch API docs: ${res.status} ${res.statusText}`);
18
+ }
19
+ return (await res.json());
20
+ }
21
+ /**
22
+ * Collect all $ref strings from an object tree.
23
+ */
24
+ function collectRefs(obj, refs) {
25
+ if (obj === null || obj === undefined || typeof obj !== "object")
26
+ return;
27
+ if (Array.isArray(obj)) {
28
+ for (const item of obj)
29
+ collectRefs(item, refs);
30
+ return;
31
+ }
32
+ const record = obj;
33
+ if (typeof record["$ref"] === "string") {
34
+ refs.add(record["$ref"]);
35
+ }
36
+ for (const value of Object.values(record)) {
37
+ collectRefs(value, refs);
38
+ }
39
+ }
40
+ /**
41
+ * Recursively resolve schema refs — the initial set plus any schemas they reference.
42
+ */
43
+ function resolveSchemas(refPaths, allSchemas) {
44
+ const resolved = {};
45
+ const queue = [...refPaths];
46
+ const visited = new Set();
47
+ while (queue.length > 0) {
48
+ const ref = queue.pop();
49
+ if (visited.has(ref))
50
+ continue;
51
+ visited.add(ref);
52
+ const prefix = "#/components/schemas/";
53
+ if (!ref.startsWith(prefix))
54
+ continue;
55
+ const name = ref.slice(prefix.length);
56
+ const schema = allSchemas[name];
57
+ if (!schema)
58
+ continue;
59
+ resolved[name] = schema;
60
+ const nested = new Set();
61
+ collectRefs(schema, nested);
62
+ for (const n of nested) {
63
+ if (!visited.has(n))
64
+ queue.push(n);
65
+ }
66
+ }
67
+ return resolved;
68
+ }
69
+ export function makeDocsCommand() {
70
+ const cmd = new Command("docs").description("Browse API documentation");
71
+ cmd
72
+ .command("sections")
73
+ .description("List available API documentation sections")
74
+ .action(async (_opts, command) => {
75
+ await runAction(command, async () => {
76
+ const config = resolveConfig(command);
77
+ const spec = await fetchSpec(config.baseUrl, config.apiKey);
78
+ const tags = spec.tags ?? [];
79
+ const paths = spec.paths ?? {};
80
+ // Count endpoints per tag
81
+ const tagCounts = new Map();
82
+ for (const methods of Object.values(paths)) {
83
+ for (const operation of Object.values(methods)) {
84
+ if (operation?.tags) {
85
+ for (const tag of operation.tags) {
86
+ tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ if (isJsonOutput(command)) {
92
+ const data = tags.map((t) => ({
93
+ name: t.name,
94
+ description: t.description ?? null,
95
+ endpoints: tagCounts.get(t.name) ?? 0,
96
+ }));
97
+ console.log(JSON.stringify(data, null, 2));
98
+ }
99
+ else {
100
+ const info = spec.info ?? {};
101
+ console.log(`${info.title ?? "API"} v${info.version ?? "?"}\n`);
102
+ console.log("Available sections:");
103
+ for (const t of tags) {
104
+ const count = tagCounts.get(t.name) ?? 0;
105
+ const desc = t.description ? ` — ${t.description}` : "";
106
+ console.log(` ${t.name} (${count} endpoint${count !== 1 ? "s" : ""})${desc}`);
107
+ }
108
+ }
109
+ });
110
+ });
111
+ cmd
112
+ .command("get")
113
+ .description("Get API documentation for a section")
114
+ .argument("<section>", "Section/tag name (e.g. Projects, Extractions)")
115
+ .action(async (section, _opts, command) => {
116
+ await runAction(command, async () => {
117
+ const config = resolveConfig(command);
118
+ const spec = await fetchSpec(config.baseUrl, config.apiKey);
119
+ const allTags = spec.tags ?? [];
120
+ const tagNames = allTags.map((t) => t.name);
121
+ if (!tagNames.includes(section)) {
122
+ throw new Error(`Section "${section}" not found. Available: ${tagNames.join(", ")}`);
123
+ }
124
+ const allPaths = spec.paths ?? {};
125
+ const allSchemas = spec.components?.schemas ?? {};
126
+ // Filter paths to only operations matching the requested tag
127
+ const filteredPaths = {};
128
+ const refs = new Set();
129
+ for (const [path, methods] of Object.entries(allPaths)) {
130
+ const filteredMethods = {};
131
+ for (const [method, operation] of Object.entries(methods)) {
132
+ const op = operation;
133
+ if (op?.tags?.includes(section)) {
134
+ filteredMethods[method] = operation;
135
+ collectRefs(operation, refs);
136
+ }
137
+ }
138
+ if (Object.keys(filteredMethods).length > 0) {
139
+ filteredPaths[path] = filteredMethods;
140
+ }
141
+ }
142
+ // Resolve referenced schemas (including transitive refs)
143
+ const referencedSchemas = resolveSchemas(refs, allSchemas);
144
+ if (isJsonOutput(command)) {
145
+ console.log(JSON.stringify({ paths: filteredPaths, schemas: referencedSchemas }, null, 2));
146
+ }
147
+ else {
148
+ // Human-readable summary
149
+ console.log(`\n${section}\n${"=".repeat(section.length)}\n`);
150
+ for (const [path, methods] of Object.entries(filteredPaths)) {
151
+ for (const [method, operation] of Object.entries(methods)) {
152
+ const op = operation;
153
+ const label = op.summary ?? op.operationId ?? "";
154
+ console.log(` ${method.toUpperCase().padEnd(7)} ${path}`);
155
+ if (label)
156
+ console.log(` ${label}`);
157
+ }
158
+ }
159
+ console.log(`\nReferenced schemas: ${Object.keys(referencedSchemas).join(", ") || "(none)"}`);
160
+ console.log("\nUse --json for full endpoint and schema details.");
161
+ }
162
+ });
163
+ });
164
+ return cmd;
165
+ }
166
+ //# sourceMappingURL=docs.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeEvaluatorsCommand(): Command;
3
+ //# sourceMappingURL=evaluators.d.ts.map
@@ -0,0 +1,124 @@
1
+ import { Command } from "commander";
2
+ import { readFileSync } from "node:fs";
3
+ import { getClient, runAction } from "../lib/client.js";
4
+ import { formatDetail, formatList } from "../lib/output.js";
5
+ export function makeEvaluatorsCommand() {
6
+ const cmd = new Command("evaluators").description("Built-in evaluator types and reusable org-scoped evaluator templates");
7
+ // ── built-in types ────────────────────────────────────────────
8
+ cmd
9
+ .command("types")
10
+ .description("List built-in evaluator types (exact_match, grounding, llm_judge)")
11
+ .action(async (_opts, command) => {
12
+ await runAction(command, async () => {
13
+ const client = getClient(command);
14
+ const { data } = await client.GET("/v1/evaluators");
15
+ formatList(data, command, [
16
+ "id",
17
+ "displayName",
18
+ "type",
19
+ ]);
20
+ });
21
+ });
22
+ // ── templates ─────────────────────────────────────────────────
23
+ cmd
24
+ .command("list")
25
+ .description("List evaluator templates")
26
+ .action(async (_opts, command) => {
27
+ await runAction(command, async () => {
28
+ const client = getClient(command);
29
+ const { data } = await client.GET("/v1/evaluator-templates");
30
+ formatList(data, command, [
31
+ "id",
32
+ "name",
33
+ "type",
34
+ "description",
35
+ ]);
36
+ });
37
+ });
38
+ cmd
39
+ .command("get <id>")
40
+ .description("Show one template by id")
41
+ .action(async (id, _opts, command) => {
42
+ await runAction(command, async () => {
43
+ const client = getClient(command);
44
+ const { data } = await client.GET("/v1/evaluator-templates/{id}", {
45
+ params: { path: { id } },
46
+ });
47
+ formatDetail(data, command);
48
+ });
49
+ });
50
+ cmd
51
+ .command("create")
52
+ .description("Create an evaluator template. LLM-judge templates require --config with rubricPrompt + model.")
53
+ .requiredOption("--name <name>", "Template name")
54
+ .requiredOption("--type <type>", "Evaluator type (CODE, LLM_JUDGE, or HUMAN)")
55
+ .option("--description <text>", "Description")
56
+ .option("--config <json-or-file>", "Config as inline JSON string or path to a .json file")
57
+ .action(async (opts, command) => {
58
+ await runAction(command, async () => {
59
+ const client = getClient(command);
60
+ const { data } = await client.POST("/v1/evaluator-templates", {
61
+ body: {
62
+ name: opts.name,
63
+ type: opts.type,
64
+ description: opts.description,
65
+ config: opts.config ? readConfigArg(opts.config) : undefined,
66
+ },
67
+ });
68
+ formatDetail(data, command);
69
+ });
70
+ });
71
+ cmd
72
+ .command("update <id>")
73
+ .description("Replace a template (name / description / config)")
74
+ .option("--name <name>")
75
+ .option("--type <type>", "Evaluator type")
76
+ .option("--description <text>")
77
+ .option("--config <json-or-file>", "Config JSON string or path to a .json file")
78
+ .action(async (id, opts, command) => {
79
+ await runAction(command, async () => {
80
+ const client = getClient(command);
81
+ // PUT is a full replace — fetch current, merge explicit fields.
82
+ const { data: current } = await client.GET("/v1/evaluator-templates/{id}", { params: { path: { id } } });
83
+ const { data } = await client.PUT("/v1/evaluator-templates/{id}", {
84
+ params: { path: { id } },
85
+ body: {
86
+ name: opts.name ?? current?.name,
87
+ type: opts.type ?? current?.type,
88
+ description: opts.description ?? current?.description,
89
+ config: opts.config !== undefined
90
+ ? readConfigArg(opts.config)
91
+ : current?.config,
92
+ },
93
+ });
94
+ formatDetail(data, command);
95
+ });
96
+ });
97
+ cmd
98
+ .command("delete <id>")
99
+ .description("Delete a template. Experiments already using it keep their past scores.")
100
+ .action(async (id, _opts, command) => {
101
+ await runAction(command, async () => {
102
+ const client = getClient(command);
103
+ await client.DELETE("/v1/evaluator-templates/{id}", {
104
+ params: { path: { id } },
105
+ });
106
+ console.log(`Deleted evaluator template ${id}`);
107
+ });
108
+ });
109
+ return cmd;
110
+ }
111
+ // Accepts either a path to a .json file or an inline JSON string. The
112
+ // file-first check keeps the common "--config ./judge.json" case simple
113
+ // while still allowing "--config '{"model":"…","rubricPrompt":"…"}'" when
114
+ // that's easier (e.g. shell pipelines).
115
+ function readConfigArg(arg) {
116
+ try {
117
+ const raw = readFileSync(arg, "utf-8");
118
+ return JSON.parse(raw);
119
+ }
120
+ catch {
121
+ return JSON.parse(arg);
122
+ }
123
+ }
124
+ //# sourceMappingURL=evaluators.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function makeExperimentsCommand(): Command;
3
+ //# sourceMappingURL=experiments.d.ts.map