@senso-ai/cli 0.8.2 → 0.9.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/README.md +1 -1
- package/dist/cli.js +45 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,7 +141,7 @@ Options: `content list` supports `--limit`, `--offset`, `--search`, `--sort`. `c
|
|
|
141
141
|
```
|
|
142
142
|
senso generate settings Get generation settings
|
|
143
143
|
senso generate update-settings Update generation settings (--data)
|
|
144
|
-
senso generate sample Generate sample for a prompt (--prompt-id, --content-type-id)
|
|
144
|
+
senso generate sample Generate sample for a prompt; waits for async job by default (--prompt-id, --content-type-id, --no-wait)
|
|
145
145
|
senso generate run Trigger a content engine run (--prompt-ids)
|
|
146
146
|
```
|
|
147
147
|
|
package/dist/cli.js
CHANGED
|
@@ -1433,6 +1433,8 @@ function registerContentCommands(program2) {
|
|
|
1433
1433
|
}
|
|
1434
1434
|
|
|
1435
1435
|
// src/commands/generate.ts
|
|
1436
|
+
var SAMPLE_JOB_POLL_INTERVAL_MS = 2e3;
|
|
1437
|
+
var SAMPLE_JOB_TIMEOUT_MS = 18e4;
|
|
1436
1438
|
function registerGenerateCommands(program2) {
|
|
1437
1439
|
const gen = program2.command("generate").description("AI content generation. Configure settings, generate content samples from prompts, or trigger full content engine runs.");
|
|
1438
1440
|
gen.command("settings").description("Get content generation settings. Shows whether generation and auto-publish are enabled, the content schedule, and configured publishers.").action(async () => {
|
|
@@ -1457,7 +1459,7 @@ function registerGenerateCommands(program2) {
|
|
|
1457
1459
|
process.exit(1);
|
|
1458
1460
|
}
|
|
1459
1461
|
});
|
|
1460
|
-
gen.command("sample").description("Generate an ad hoc content sample for a specific prompt and content type.
|
|
1462
|
+
gen.command("sample").description("Generate an ad hoc content sample for a specific prompt and content type. Submits an async job, waits for completion by default, then returns the generated markdown, SEO title, and publish results. Use 'prompts list' to find a prompt ID, and 'content-types list' to find a content-type ID.").requiredOption("--prompt-id <id>", "Prompt (geo question) ID to generate content for").requiredOption("--content-type-id <id>", "Content type ID that defines the output format (use 'content-types list' to find)").option("--destination <dest>", "Publisher slug to publish to immediately after generation. Omit to save as draft only.").option("--no-wait", "Return the accepted sample job immediately instead of polling for the generated content.").action(async (cmdOpts) => {
|
|
1461
1463
|
const opts = program2.opts();
|
|
1462
1464
|
try {
|
|
1463
1465
|
const body = {
|
|
@@ -1474,7 +1476,25 @@ function registerGenerateCommands(program2) {
|
|
|
1474
1476
|
apiKey: opts.apiKey,
|
|
1475
1477
|
baseUrl: opts.baseUrl
|
|
1476
1478
|
});
|
|
1477
|
-
|
|
1479
|
+
if (cmdOpts.wait === false) {
|
|
1480
|
+
console.log(JSON.stringify(data, null, 2));
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
const quiet = opts.quiet || opts.output === "json";
|
|
1484
|
+
if (!quiet) {
|
|
1485
|
+
info(`Sample job accepted: ${data.sample_job_id}`);
|
|
1486
|
+
}
|
|
1487
|
+
const job = await waitForSampleJob(data.sample_job_id, {
|
|
1488
|
+
apiKey: opts.apiKey,
|
|
1489
|
+
baseUrl: opts.baseUrl,
|
|
1490
|
+
quiet
|
|
1491
|
+
});
|
|
1492
|
+
if (job.status === "completed") {
|
|
1493
|
+
console.log(JSON.stringify(job.result ?? job, null, 2));
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
const message = job.error?.message || `Sample job ended with status: ${job.status}`;
|
|
1497
|
+
throw new Error(job.error?.code ? `${message} (${job.error.code})` : message);
|
|
1478
1498
|
} catch (err) {
|
|
1479
1499
|
error(formatApiError(err));
|
|
1480
1500
|
process.exit(1);
|
|
@@ -1568,6 +1588,29 @@ function registerGenerateCommands(program2) {
|
|
|
1568
1588
|
}
|
|
1569
1589
|
});
|
|
1570
1590
|
}
|
|
1591
|
+
async function waitForSampleJob(sampleJobId, opts) {
|
|
1592
|
+
const deadline = Date.now() + SAMPLE_JOB_TIMEOUT_MS;
|
|
1593
|
+
let lastStatus = "";
|
|
1594
|
+
while (Date.now() < deadline) {
|
|
1595
|
+
const job = await apiRequest({
|
|
1596
|
+
path: `/org/content-generation/sample-jobs/${sampleJobId}`,
|
|
1597
|
+
apiKey: opts.apiKey,
|
|
1598
|
+
baseUrl: opts.baseUrl
|
|
1599
|
+
});
|
|
1600
|
+
if (!opts.quiet && job.status !== lastStatus) {
|
|
1601
|
+
info(`Sample job status: ${job.status}`);
|
|
1602
|
+
lastStatus = job.status;
|
|
1603
|
+
}
|
|
1604
|
+
if (job.status === "completed" || job.status === "failed" || job.status === "expired") {
|
|
1605
|
+
return job;
|
|
1606
|
+
}
|
|
1607
|
+
await sleep(SAMPLE_JOB_POLL_INTERVAL_MS);
|
|
1608
|
+
}
|
|
1609
|
+
throw new Error(`Timed out waiting for sample job ${sampleJobId}. Poll /org/content-generation/sample-jobs/${sampleJobId} for status.`);
|
|
1610
|
+
}
|
|
1611
|
+
function sleep(ms) {
|
|
1612
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
1613
|
+
}
|
|
1571
1614
|
|
|
1572
1615
|
// src/commands/engine.ts
|
|
1573
1616
|
function registerEngineCommands(program2) {
|