Skip to content
This repository was archived by the owner on Jul 14, 2026. It is now read-only.

Commit 345cb81

Browse files
authored
support batch genaration (#204)
* support batch genaration * type / readme * better error message
1 parent dad065e commit 345cb81

6 files changed

Lines changed: 91 additions & 8 deletions

File tree

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ This way even entityIds like environmentIds or testCaseIds will be autocompleted
4242

4343
# octomind
4444

45-
Octomind cli tool. Version: 1.3.1. Additional documentation see https://octomind.dev/docs/api-reference/
45+
Octomind cli tool. Version: 1.3.2. Additional documentation see https://octomind.dev/docs/api-reference/
4646

4747
**Usage:** `octomind [options] [command]`
4848

@@ -239,6 +239,23 @@ Create a new test case discovery
239239
| `--assigned-tag-ids [ids]` | Comma-separated list of tag IDs | No | |
240240
| `--folder-id [id]` | Folder ID | No | |
241241

242+
## batch-generation
243+
244+
Batch generation of test cases
245+
246+
**Usage:** `batch-generation [options]`
247+
248+
### Options
249+
250+
| Option | Description | Required | Default |
251+
|:-------|:----------|:---------|:--------|
252+
| `-j, --json` | Output raw JSON response | No | |
253+
| `-p, --prompt <prompt>` | Batch generation prompt | Yes | |
254+
| `-u, --url <url>` | Start url for generation | Yes | |
255+
| `-e, --environment-id <id>` | Environment ID | Yes | |
256+
| `-d, --prerequisite-id <id>` | Prerequisite ID | Yes | |
257+
| `-t, --test-target-id [id]` | Test target ID, if not provided will use the test target id from the config | No | |
258+
242259
## Notifications
243260

244261
## notifications

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@octomind/octomind",
3-
"version": "1.3.1",
3+
"version": "1.3.2",
44
"description": "a command line client for octomind apis",
55
"main": "./dist/index.js",
66
"packageManager": "pnpm@10.13.1",

src/cli.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { runDebugtopus } from "./debugtopus";
1616
import { promptUser, resolveTestTargetId } from "./helpers";
1717
import { startPrivateLocationWorker, stopPLW } from "./plw";
1818
import {
19+
batchGeneration,
1920
CreateDiscoveryBody,
2021
createDiscovery,
2122
createEnvironment,
@@ -257,7 +258,6 @@ export const buildCmd = (): CompletableCommand => {
257258
.action(addTestTargetWrapper(deleteEnvironment));
258259

259260
program
260-
261261
.completer(optionsCompleter)
262262
.completableCommand("start-private-location")
263263
.description(
@@ -276,22 +276,19 @@ export const buildCmd = (): CompletableCommand => {
276276
.action(startPrivateLocationWorker);
277277

278278
program
279-
280279
.completableCommand("stop-private-location")
281280
.completer(optionsCompleter)
282281
.description(
283282
"Stop a private location worker, see https://octomind.dev/docs/proxy/private-location",
284283
)
285284
.helpGroup("private-locations")
286-
287285
.action(stopPLW);
288286

289287
createCommandWithCommonOptions(program, "notifications")
290288
.completer(testTargetIdCompleter)
291289
.description("Get notifications for a test target")
292290
.helpGroup("notifications")
293291
.addOption(testTargetIdOption)
294-
295292
.action(addTestTargetWrapper(listNotifications));
296293

297294
createCommandWithCommonOptions(program, "delete-test-case")
@@ -328,7 +325,6 @@ export const buildCmd = (): CompletableCommand => {
328325
splitter,
329326
)
330327
.option("--folder-id [id]", "Folder ID")
331-
332328
.action(addTestTargetWrapper(createDiscovery));
333329

334330
createCommandWithCommonOptions(program, "list-test-cases")
@@ -343,6 +339,18 @@ export const buildCmd = (): CompletableCommand => {
343339
.helpGroup("test-targets")
344340
.action(listTestTargets);
345341

342+
createCommandWithCommonOptions(program, "batch-generation")
343+
.completer(testTargetIdCompleter)
344+
.completer(optionsCompleter)
345+
.description("Batch generation of test cases")
346+
.requiredOption("-p, --prompt <prompt>", "Batch generation prompt")
347+
.requiredOption("-u, --url <url>", "Start url for generation")
348+
.option("-e, --environment-id <id>", "Environment ID")
349+
.option("-d, --prerequisite-id <id>", "Prerequisite ID")
350+
.helpGroup("execute")
351+
.addOption(testTargetIdOption)
352+
.action(addTestTargetWrapper(batchGeneration));
353+
346354
program
347355
.completableCommand("install-completion")
348356
.description("Install tab completion")

src/tools/client.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ export { client };
5050
export const handleError = (error: ErrorResponse) => {
5151
if (error) {
5252
console.error(error);
53+
if (typeof error === "string" && error.startsWith("403")) {
54+
console.error(
55+
"You are not authorized. Check your API key or do a 'octomind init' to set it up.",
56+
);
57+
}
5358
process.exit(1);
5459
}
5560
};

src/tools/discoveries.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,56 @@ import { client, handleError, ListOptions, logJson } from "./client";
55
export type CreateDiscoveryBody =
66
components["schemas"]["ExternalDiscoveryBody"];
77
export type DiscoveryResponse = components["schemas"]["DiscoveryResponse"];
8+
export type BatchGenerationResponse =
9+
components["schemas"]["BatchGenerationResponse"];
10+
export type BatchGenerationParams =
11+
components["schemas"]["ExternalBatchGenerationBody"];
12+
export const batchGeneration = async (
13+
options: {
14+
environmentId: string;
15+
prompt: string;
16+
prerequisiteId?: string;
17+
testTargetId: string;
18+
url: string;
19+
} & ListOptions,
20+
): Promise<void> => {
21+
const { data, error } = await client.POST(
22+
"/apiKey/v2/test-targets/{testTargetId}/batch-generations",
23+
{
24+
params: {
25+
path: {
26+
testTargetId: options.testTargetId,
27+
},
28+
},
29+
body: {
30+
environmentId: options.environmentId,
31+
prompt: options.prompt,
32+
prerequisiteId: options.prerequisiteId,
33+
entryPointUrlPath: options.url,
34+
},
35+
},
36+
);
37+
38+
handleError(error);
39+
40+
const response = data as BatchGenerationResponse;
41+
if (options.json) {
42+
logJson(response);
43+
return;
44+
}
45+
if (!response.batchGenerationId) {
46+
throw new Error("Batch generation ID is missing");
47+
}
48+
49+
console.log("Batch generation created successfully!");
50+
console.log(`Batch generation ID: ${response.batchGenerationId}`);
51+
console.log(
52+
`Batch generation URL: ${await getUrl({
53+
batchGenerationId: response.batchGenerationId,
54+
entityType: "batch-generation",
55+
})}`,
56+
);
57+
};
858

959
export const createDiscovery = async (
1060
options: CreateDiscoveryBody & { testTargetId: string } & ListOptions,

src/url.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ export const getUrl = async (
1111
testResultId: string;
1212
entityType: "test-result";
1313
}
14-
| { testCaseId: string; entityType: "discovery" },
14+
| { testCaseId: string; entityType: "discovery" }
15+
| { batchGenerationId: string; entityType: "batch-generation" },
1516
): Promise<string> => {
1617
const relevantBaseUrl = new URL(BASE_URL).origin;
1718
const config = await loadConfig();
@@ -30,5 +31,7 @@ export const getUrl = async (
3031
return `${relevantBaseUrl}/testtargets/${configuredTestTargetId}/testreports/${input.testReportId}/testresults/${input.testResultId}`;
3132
case "discovery":
3233
return `${relevantBaseUrl}/testtargets/${configuredTestTargetId}/testcases/${input.testCaseId}`;
34+
case "batch-generation":
35+
return `${relevantBaseUrl}/testtargets/${configuredTestTargetId}/batch-generations/${input.batchGenerationId}`;
3336
}
3437
};

0 commit comments

Comments
 (0)