@stage5/lumine 0.2.67 → 0.2.68
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 +26 -1
- package/lib/admin-featured.js +559 -0
- package/lib/admin-workflows.js +2 -2
- package/lib/admin.js +124 -14
- package/lib/commands.js +13 -5
- package/package.json +1 -1
- package/sdk/BUILD_SDK_INDEX.md +2 -2
- package/sdk/LUMINE_ADMIN.md +327 -36
package/lib/admin.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
readAdminJsonFile,
|
|
9
9
|
validateNewsEditorial,
|
|
10
10
|
writeNewsClaimArtifacts,
|
|
11
|
+
writeAdminJsonFile,
|
|
11
12
|
} from "./admin-news.js";
|
|
12
13
|
import {
|
|
13
14
|
forEachPaginatedResultItem,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
runManagedBuildReview,
|
|
22
23
|
} from "./build-review.js";
|
|
23
24
|
import { runAdminRuntimeLogWorkflow } from "./admin-runtime-logs.js";
|
|
25
|
+
import { readApprovedFeaturedPlan, runFeaturedWorkflow } from "./admin-featured.js";
|
|
24
26
|
|
|
25
27
|
const MAX_EDITORIAL_FILE_BYTES = 256 * 1024;
|
|
26
28
|
const MAX_COMPOSED_TEXT_FILE_BYTES = 64 * 1024;
|
|
@@ -270,7 +272,9 @@ export async function adminCommand(options) {
|
|
|
270
272
|
recommendationContentTypes,
|
|
271
273
|
viewFilter,
|
|
272
274
|
});
|
|
273
|
-
if (operation.
|
|
275
|
+
if (operation.featuredWorkflow) {
|
|
276
|
+
result = await runFeaturedWorkflow({ options, operation, authToken: auth.token, runId });
|
|
277
|
+
} else if (operation.name === "build.review") {
|
|
274
278
|
result = await runManagedBuildReview({
|
|
275
279
|
options,
|
|
276
280
|
authToken: auth.token,
|
|
@@ -325,9 +329,26 @@ export async function adminCommand(options) {
|
|
|
325
329
|
result = transformResult(await fetchOperation());
|
|
326
330
|
}
|
|
327
331
|
} catch (error) {
|
|
332
|
+
if (operation.featuredWorkflow && error.featuredProgress) {
|
|
333
|
+
const serverError = error.data?.error;
|
|
334
|
+
error.data = {
|
|
335
|
+
ok: false,
|
|
336
|
+
status: "partial_failure",
|
|
337
|
+
error: {
|
|
338
|
+
code: serverError?.code || error.code || "LUMINE_ADMIN_FEATURED_WORKFLOW_FAILED",
|
|
339
|
+
message: error.message,
|
|
340
|
+
details: {
|
|
341
|
+
...(serverError && typeof serverError === "object" ? serverError.details : {}),
|
|
342
|
+
...error.featuredProgress,
|
|
343
|
+
retryInstruction: "Resume the exact command with --resume; confirmed items are not replayed.",
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
}
|
|
328
348
|
if (
|
|
329
349
|
operation.mutates &&
|
|
330
350
|
requestId &&
|
|
351
|
+
!operation.featuredWorkflow &&
|
|
331
352
|
operation.name !== "post.skip-batch"
|
|
332
353
|
) {
|
|
333
354
|
const retryInstruction = `Retry with --idempotency-key ${requestId}.`;
|
|
@@ -480,6 +501,14 @@ export function assertSubjectWindowResult({ operation, result }) {
|
|
|
480
501
|
|
|
481
502
|
async function finishAdminOutput({ options, operation, result }) {
|
|
482
503
|
const paginationStorage = getPaginatedResultStorage(result);
|
|
504
|
+
if (
|
|
505
|
+
options.adminOutput &&
|
|
506
|
+
!paginationStorage &&
|
|
507
|
+
operation.name !== "news.claim" &&
|
|
508
|
+
operation.name !== "post.skip-batch"
|
|
509
|
+
) {
|
|
510
|
+
writeAdminResultOutput({ filePath: options.adminOutput, result, operation });
|
|
511
|
+
}
|
|
483
512
|
if (options.json) {
|
|
484
513
|
if (paginationStorage) {
|
|
485
514
|
await writePaginatedResultJson({
|
|
@@ -507,6 +536,27 @@ async function finishAdminOutput({ options, operation, result }) {
|
|
|
507
536
|
return result;
|
|
508
537
|
}
|
|
509
538
|
|
|
539
|
+
export function writeAdminResultOutput({ filePath, result, operation }) {
|
|
540
|
+
try {
|
|
541
|
+
return writeAdminJsonFile(filePath, result, { privateFile: true });
|
|
542
|
+
} catch (cause) {
|
|
543
|
+
const error = new Error(
|
|
544
|
+
`The canonical ${operation.name} result was received, but --output could not be saved: ${cause.message}. Do not repeat a successful mutation just to save its output.`,
|
|
545
|
+
);
|
|
546
|
+
error.code = "LUMINE_ADMIN_OUTPUT_WRITE_FAILED";
|
|
547
|
+
error.data = {
|
|
548
|
+
ok: false,
|
|
549
|
+
status: "error",
|
|
550
|
+
error: {
|
|
551
|
+
code: error.code,
|
|
552
|
+
message: error.message,
|
|
553
|
+
details: { canonicalResult: result, outputPath: String(filePath) },
|
|
554
|
+
},
|
|
555
|
+
};
|
|
556
|
+
throw error;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
510
560
|
export function normalizeAdminBuildCandidatesResult({ result, siteUrl }) {
|
|
511
561
|
const builds = Array.isArray(result?.builds) ? result.builds : [];
|
|
512
562
|
const nextCursor = String(result?.cursor || "").trim() || null;
|
|
@@ -756,7 +806,7 @@ export function canonicalAdminRunScope(run) {
|
|
|
756
806
|
const raw = run?.runScope;
|
|
757
807
|
if (raw === undefined || raw === null || raw === "") return "full";
|
|
758
808
|
const scope = String(raw);
|
|
759
|
-
if (
|
|
809
|
+
if (["full", "featured", "newspaper"].includes(scope)) return scope;
|
|
760
810
|
throw cliValidationError(
|
|
761
811
|
"The API returned an invalid administrator run scope.",
|
|
762
812
|
);
|
|
@@ -778,6 +828,12 @@ const FEATURED_RUN_OPERATIONS = new Set([
|
|
|
778
828
|
"featured.add",
|
|
779
829
|
"featured.reorder",
|
|
780
830
|
"featured.rotate",
|
|
831
|
+
"featured.plan",
|
|
832
|
+
"featured.apply",
|
|
833
|
+
"featured.comments.scan",
|
|
834
|
+
"featured.comments.acknowledge",
|
|
835
|
+
"featured.comments.recommend",
|
|
836
|
+
"featured.comments.report",
|
|
781
837
|
"daily-run.complete",
|
|
782
838
|
"daily-run.fail",
|
|
783
839
|
]);
|
|
@@ -786,6 +842,14 @@ export function assertAdminOperationAllowedForRunScope({
|
|
|
786
842
|
operation,
|
|
787
843
|
runScope,
|
|
788
844
|
}) {
|
|
845
|
+
if (runScope === "newspaper") {
|
|
846
|
+
if (
|
|
847
|
+
["news.status", "news.claim", "news.submit", "news.print", "daily-run.complete", "daily-run.fail"].includes(operation.name)
|
|
848
|
+
) return;
|
|
849
|
+
throw cliValidationError(
|
|
850
|
+
`A newspaper-only run does not authorize ${operation.name}.`,
|
|
851
|
+
);
|
|
852
|
+
}
|
|
789
853
|
if (runScope !== "featured") return;
|
|
790
854
|
const subjectCommentAlias =
|
|
791
855
|
operation.name === "post.comments" &&
|
|
@@ -794,7 +858,7 @@ export function assertAdminOperationAllowedForRunScope({
|
|
|
794
858
|
return;
|
|
795
859
|
}
|
|
796
860
|
throw cliValidationError(
|
|
797
|
-
`A Featured-only run does not authorize ${operation.name}.
|
|
861
|
+
`A Featured-only run does not authorize ${operation.name}. Use the review-bound Featured comment workflow for encouragement; do not start unrelated daily work to bypass scope.`,
|
|
798
862
|
);
|
|
799
863
|
}
|
|
800
864
|
|
|
@@ -1216,17 +1280,17 @@ export function parseAdminOperation(options) {
|
|
|
1216
1280
|
if (action === "start") {
|
|
1217
1281
|
const runScope = parseDailyRunScope(options.adminScope || "full");
|
|
1218
1282
|
const commentMode = parseCommentMode(options.commentMode || "off");
|
|
1219
|
-
if (runScope
|
|
1283
|
+
if (runScope !== "full" && commentMode !== "off") {
|
|
1220
1284
|
throw cliValidationError(
|
|
1221
|
-
"A
|
|
1285
|
+
"A scoped run requires --comment-mode off.",
|
|
1222
1286
|
);
|
|
1223
1287
|
}
|
|
1224
1288
|
return writeOperation(
|
|
1225
1289
|
"daily-run.start",
|
|
1226
1290
|
"POST",
|
|
1227
|
-
runScope === "
|
|
1228
|
-
? "/cli/admin/daily-runs/start
|
|
1229
|
-
:
|
|
1291
|
+
runScope === "full"
|
|
1292
|
+
? "/cli/admin/daily-runs/start"
|
|
1293
|
+
: `/cli/admin/daily-runs/start/${runScope}`,
|
|
1230
1294
|
{
|
|
1231
1295
|
identity: options.adminIdentity
|
|
1232
1296
|
? parseIdentity(options.adminIdentity)
|
|
@@ -1483,6 +1547,30 @@ export function parseAdminOperation(options) {
|
|
|
1483
1547
|
}
|
|
1484
1548
|
|
|
1485
1549
|
if (namespace === "featured") {
|
|
1550
|
+
if (action === "comments") {
|
|
1551
|
+
if (!["scan", "acknowledge", "recommend", "report"].includes(target)) {
|
|
1552
|
+
throw cliValidationError("Usage: featured comments scan|acknowledge|recommend|report --checkpoint <file>.");
|
|
1553
|
+
}
|
|
1554
|
+
if (options.adminAll || options.adminCursor || options.adminUnviewed || options.adminViewed || options.adminAfter) {
|
|
1555
|
+
throw cliValidationError("The Featured review covers every comment; filtered or caller-supplied cursors are not supported.");
|
|
1556
|
+
}
|
|
1557
|
+
return { ...writeOperation(`featured.comments.${target}`, "POST", "/cli/admin/subjects/featured/reviews", {}),
|
|
1558
|
+
mutates: target !== "report", featuredWorkflow: target };
|
|
1559
|
+
}
|
|
1560
|
+
if (action === "plan") {
|
|
1561
|
+
if (!options.adminPostedAfter) throw cliValidationError("A Featured plan requires --posted-after <timestamp>.");
|
|
1562
|
+
return writeOperation("featured.plan", "POST", "/cli/admin/subjects/featured/plan", {
|
|
1563
|
+
removeIds: parseFeaturedSubjectIds(options.adminRemoveIds, "--remove-subject-ids"),
|
|
1564
|
+
addIds: parseFeaturedSubjectIds(options.adminAddIds, "--add-subject-ids"),
|
|
1565
|
+
...(options.adminIds ? { finalIds: parseOrderedIds(options.adminIds) } : {}),
|
|
1566
|
+
postedAfter: options.adminPostedAfter,
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
if (action === "apply") {
|
|
1570
|
+
readApprovedFeaturedPlan(options.adminFile, options.adminApprove);
|
|
1571
|
+
return { ...writeOperation("featured.apply", "POST", "/cli/admin/subjects/featured/plan/apply", {}),
|
|
1572
|
+
featuredWorkflow: "apply" };
|
|
1573
|
+
}
|
|
1486
1574
|
if (action === "list") {
|
|
1487
1575
|
return readOperation("featured.list", "/cli/admin/subjects/featured");
|
|
1488
1576
|
}
|
|
@@ -1528,7 +1616,7 @@ export function parseAdminOperation(options) {
|
|
|
1528
1616
|
if (namespace === "post") {
|
|
1529
1617
|
if (action === "get") return postGetOperation(target, options);
|
|
1530
1618
|
if (action === "comments") {
|
|
1531
|
-
const parsedTarget =
|
|
1619
|
+
const parsedTarget = parseAdminCommentTarget({
|
|
1532
1620
|
target,
|
|
1533
1621
|
explicitType: options.adminType,
|
|
1534
1622
|
});
|
|
@@ -1729,7 +1817,9 @@ export function parseAdminOperation(options) {
|
|
|
1729
1817
|
"ai-costs monthly uses UTC calendar months and does not accept --days.",
|
|
1730
1818
|
);
|
|
1731
1819
|
}
|
|
1732
|
-
return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly"
|
|
1820
|
+
return readOperation("ai-costs.monthly", "/cli/admin/ai-costs/monthly", {
|
|
1821
|
+
requiresRun: false,
|
|
1822
|
+
});
|
|
1733
1823
|
}
|
|
1734
1824
|
if (action === "day" && !extra) {
|
|
1735
1825
|
if (options.adminDays) {
|
|
@@ -2243,6 +2333,7 @@ function featuredRotateOperation(options) {
|
|
|
2243
2333
|
{
|
|
2244
2334
|
removeIds,
|
|
2245
2335
|
addIds,
|
|
2336
|
+
...(options.adminPostedAfter ? { postedAfter: options.adminPostedAfter } : {}),
|
|
2246
2337
|
},
|
|
2247
2338
|
);
|
|
2248
2339
|
}
|
|
@@ -2524,7 +2615,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
|
|
|
2524
2615
|
throw error;
|
|
2525
2616
|
}
|
|
2526
2617
|
const handoff = result?.data?.carryoverTodos;
|
|
2527
|
-
if (runScope
|
|
2618
|
+
if (runScope !== "full") {
|
|
2528
2619
|
if (
|
|
2529
2620
|
!runId ||
|
|
2530
2621
|
!handoff ||
|
|
@@ -2536,7 +2627,7 @@ export function assertAdminTodoHandoffResult(result, expectedRunScope = null) {
|
|
|
2536
2627
|
Number(handoff.newlySurfacedCount) !== 0
|
|
2537
2628
|
) {
|
|
2538
2629
|
const error = cliValidationError(
|
|
2539
|
-
"The API did not confirm that carry-over telemetry was suppressed for the
|
|
2630
|
+
"The API did not confirm that carry-over telemetry was suppressed for the scoped run.",
|
|
2540
2631
|
);
|
|
2541
2632
|
error.code = "LUMINE_ADMIN_SCOPED_RUN_UNSUPPORTED";
|
|
2542
2633
|
throw error;
|
|
@@ -2617,8 +2708,8 @@ function parseDailyRunScope(value) {
|
|
|
2617
2708
|
const scope = String(value || "full")
|
|
2618
2709
|
.trim()
|
|
2619
2710
|
.toLowerCase();
|
|
2620
|
-
if (!["full", "featured"].includes(scope)) {
|
|
2621
|
-
throw cliValidationError("--scope must be full or
|
|
2711
|
+
if (!["full", "featured", "newspaper"].includes(scope)) {
|
|
2712
|
+
throw cliValidationError("--scope must be full, featured, or newspaper.");
|
|
2622
2713
|
}
|
|
2623
2714
|
return scope;
|
|
2624
2715
|
}
|
|
@@ -3156,6 +3247,18 @@ async function printSpooledAdminResult({ operation, result, storage }) {
|
|
|
3156
3247
|
|
|
3157
3248
|
function printAdminResult({ operation, result }) {
|
|
3158
3249
|
const data = result?.data || {};
|
|
3250
|
+
if (operation.name === "featured.plan") {
|
|
3251
|
+
for (const pair of data.plan?.replacements || []) {
|
|
3252
|
+
console.log(`${pair.remove.id} ${pair.remove.title} -> ${pair.add.id} ${pair.add.title}`);
|
|
3253
|
+
}
|
|
3254
|
+
console.log(`Proposed final order: ${(data.plan?.finalIds || []).join(",")}`);
|
|
3255
|
+
console.log(`Plan hash: ${data.planHash}. Obtain Mikey's approval before using featured apply --file <plan.json> --approve ${data.planHash}.`);
|
|
3256
|
+
return;
|
|
3257
|
+
}
|
|
3258
|
+
if (operation.featuredWorkflow) {
|
|
3259
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3260
|
+
return;
|
|
3261
|
+
}
|
|
3159
3262
|
if (Array.isArray(data.applications)) {
|
|
3160
3263
|
console.log(`${data.applications.length} sponsor application(s):`);
|
|
3161
3264
|
for (const application of data.applications) {
|
|
@@ -3300,6 +3403,13 @@ function printAdminResult({ operation, result }) {
|
|
|
3300
3403
|
` ${coverage.queue}: ${coverage.candidateCount} candidate(s), ${coverage.scannedCount} row(s) scanned across ${coverage.pages} page(s).`,
|
|
3301
3404
|
);
|
|
3302
3405
|
}
|
|
3406
|
+
for (const item of report.featuredReviews || []) {
|
|
3407
|
+
const coverage = item.coverage;
|
|
3408
|
+
const counts = item.encouragement || {};
|
|
3409
|
+
console.log(
|
|
3410
|
+
` Featured review #${item.review?.id || coverage?.reviewId}: ${coverage?.reviewed ? `${coverage.coveredSubjectIds.length}/${coverage.subjectCount} Subjects read, ${coverage.commentsRead} comments` : "not acknowledged as read"}; ${coverage?.complete ? "complete" : "incomplete"}; ${counts.newBasicRecommendations || 0} confirmed new basic recommendations, ${counts.alreadyDone || 0} already done, ${counts.rewardEligibilityGrants || 0} reward-permission grants, ${counts.directRewardsCreated || 0} direct rewards.`,
|
|
3411
|
+
);
|
|
3412
|
+
}
|
|
3303
3413
|
for (const escalation of report.escalations) {
|
|
3304
3414
|
const target =
|
|
3305
3415
|
escalation.url ||
|
package/lib/commands.js
CHANGED
|
@@ -2379,6 +2379,7 @@ export function parseArgs(args) {
|
|
|
2379
2379
|
adminCursor: raw.cursor ? String(raw.cursor) : "",
|
|
2380
2380
|
adminAfter: raw.after ? String(raw.after) : "",
|
|
2381
2381
|
adminPostedAfter: raw.postedAfter ? String(raw.postedAfter) : "",
|
|
2382
|
+
adminApprove: raw.approve ? String(raw.approve) : "",
|
|
2382
2383
|
adminSinceRun: Boolean(raw.sinceRun),
|
|
2383
2384
|
adminIncludeLegacy: Boolean(raw.includeLegacy),
|
|
2384
2385
|
adminIncludePrivateEvidence: parseBoolean(
|
|
@@ -2846,7 +2847,7 @@ export function printHelp() {
|
|
|
2846
2847
|
lumine admin ai-bucket note set --bucket-id <id> --note <text> [--json]
|
|
2847
2848
|
lumine admin ai-email-policy get --email <address> [--json]
|
|
2848
2849
|
lumine admin ai-email-policy set --email <address> --mode <automatic|separate_accounts> --note <text> [--json]
|
|
2849
|
-
lumine admin daily-run start [--scope full|featured] [--identity zero|ciel|auto] [--comment-mode off|draft|post] [--run-key <key>] [--json]
|
|
2850
|
+
lumine admin daily-run start [--scope full|featured|newspaper] [--identity zero|ciel|auto] [--comment-mode off|draft|post] [--run-key <key>] [--json]
|
|
2850
2851
|
lumine admin daily-run status|report|complete|fail [--run <completed-run-id>] [--reason <text>] [--json]
|
|
2851
2852
|
lumine admin daily-run escalation add --target <target> --note <summary> [--severity attention|urgent] [--json]
|
|
2852
2853
|
lumine admin escalation list [--status open|acknowledged|resolved|all] [--limit <number>] [--json]
|
|
@@ -2874,9 +2875,15 @@ export function printHelp() {
|
|
|
2874
2875
|
lumine admin featured history --subject-ids <id,id,...> [--all --checkpoint <file> [--resume]] [--cursor <cursor>] [--json]
|
|
2875
2876
|
lumine admin featured add --subject-ids <id,id,...> --posted-after <ISO-8601-or-Unix-time> [--json]
|
|
2876
2877
|
lumine admin featured reorder --subject-ids <id,id,...> [--json]
|
|
2877
|
-
lumine admin featured rotate --remove-subject-ids <id,id,...> --add-subject-ids <id,id,...> [--json]
|
|
2878
|
+
lumine admin featured rotate --remove-subject-ids <id,id,...> --add-subject-ids <id,id,...> [--posted-after <timestamp>] [--json]
|
|
2879
|
+
lumine admin featured plan --remove-subject-ids <ids> --add-subject-ids <ids> [--subject-ids <final-order>] --posted-after <timestamp> --output <plan.json> [--json]
|
|
2880
|
+
lumine admin featured apply --file <plan.json> --approve <exact-plan-hash> [--json]
|
|
2881
|
+
lumine admin featured comments scan --checkpoint <file> [--resume] [--json]
|
|
2882
|
+
lumine admin featured comments acknowledge --checkpoint <scan-file> --reviewed [--json]
|
|
2883
|
+
lumine admin featured comments recommend --file <decisions.json> --checkpoint <batch-file> [--resume] [--json]
|
|
2884
|
+
lumine admin featured comments report --checkpoint <scan-file> [--json]
|
|
2878
2885
|
lumine admin post get <target> [--type subject|comment|aiStory|dailyReflection] [--json]
|
|
2879
|
-
lumine admin post comments <target> [--type subject|aiStory|dailyReflection] [--unviewed|--viewed] [--all --checkpoint <file> [--resume]] [--cursor <cursor>] [--json]
|
|
2886
|
+
lumine admin post comments <target> [--type subject|build|aiStory|dailyReflection] [--unviewed|--viewed] [--all --checkpoint <file> [--resume]] [--cursor <cursor>] [--json]
|
|
2880
2887
|
lumine admin post recommend <target> [--type subject|comment|aiStory|dailyReflection] [--anyone-can-reward] [--reward-twinkles 3] [--json]
|
|
2881
2888
|
lumine admin post skip <target> [--type comment|aiStory|dailyReflection] [--reason <text>] [--json]
|
|
2882
2889
|
lumine admin post skip-batch --target-file <json-or-lines> [--reason <text>] [--checkpoint <file> [--resume]] [--json]
|
|
@@ -2886,7 +2893,7 @@ export function printHelp() {
|
|
|
2886
2893
|
lumine admin comment post --draft-id <id> [--json]
|
|
2887
2894
|
lumine admin comment edit <comment-id> --file <comment.md> [--json]
|
|
2888
2895
|
lumine admin brief [--days <1..30>] [--json]
|
|
2889
|
-
lumine admin ai-costs monthly [--json]
|
|
2896
|
+
lumine admin ai-costs monthly [--output <file.json>] [--json] (no active run required)
|
|
2890
2897
|
lumine admin ai-costs day <YYYY-MM-DD> [--json]
|
|
2891
2898
|
lumine admin media-costs monthly [--json]
|
|
2892
2899
|
lumine admin energy-budget [--days <1..31>] [--json]
|
|
@@ -2992,7 +2999,7 @@ Options:
|
|
|
2992
2999
|
--review-receipt <f> Confirmed managed Build runtime review receipt
|
|
2993
3000
|
--review-context <f> Private JSON understanding from the reviewed Build
|
|
2994
3001
|
--review-session <f> Private production-log review lease/checkpoint
|
|
2995
|
-
--reviewed
|
|
3002
|
+
--reviewed Explicitly acknowledge downloaded logs or Featured comment pages as read
|
|
2996
3003
|
--severity <level> Run escalation severity: attention or urgent
|
|
2997
3004
|
--status <state> Private escalation or todo lifecycle filter/state
|
|
2998
3005
|
--wait-ms <ms> Managed Build observation or sponsor watch duration
|
|
@@ -3008,6 +3015,7 @@ Options:
|
|
|
3008
3015
|
--subject-ids <ids> Complete ordered Featured subject IDs
|
|
3009
3016
|
--remove-subject-ids <ids> Featured subjects approved for rotation removal
|
|
3010
3017
|
--add-subject-ids <ids> Ordered replacement subjects for Featured rotation
|
|
3018
|
+
--approve <hash> Exact Featured plan hash, only after Mikey's go-ahead
|
|
3011
3019
|
--bucket-id <id> Unbanned AI identity bucket for account consolidation
|
|
3012
3020
|
--label <name> Name for a new unbanned AI identity bucket
|
|
3013
3021
|
--user-ids <ids> Explicit user IDs for an AI bucket batch (up to 500)
|
package/package.json
CHANGED
package/sdk/BUILD_SDK_INDEX.md
CHANGED
|
@@ -467,10 +467,10 @@ const result = await Twinkle.ai.chat({ message, history: chatHistory, systemProm
|
|
|
467
467
|
- Use this instead of asking Twinkle.ai.chat to return JSON.
|
|
468
468
|
- expectedStructure must be a JSON object that describes the exact returned object shape.
|
|
469
469
|
- mode is accepted as an alias for thinkingMode, and mid is accepted as an alias for medium.
|
|
470
|
-
- Omit model to use the normal Lite/Medium/High routing. model accepts gpt-5.6-sol, claude-opus-5, or claude-fable-5-1, and every explicit model must be paired with thinkingMode: 'high'; unknown model IDs reject instead of silently falling back.
|
|
470
|
+
- Omit model to use the normal Lite/Medium/High routing. model accepts gpt-6-astra, gpt-5.6-sol, claude-opus-5, or claude-fable-5-1, and every explicit model must be paired with thinkingMode: 'high'; unknown model IDs reject instead of silently falling back.
|
|
471
471
|
- thinkingMode low uses GPT-5.6 Luna and consumes the viewer's AI Energy from confirmed provider usage; its smaller model is usually cheaper than Medium or High.
|
|
472
472
|
- thinkingMode medium uses Grok 4.6 with medium reasoning and consumes normal AI Energy.
|
|
473
|
-
- thinkingMode high without model uses GPT-5.6 Sol with high reasoning and consumes high AI Energy. Explicit model: 'gpt-5.6-sol' selects Sol with xhigh reasoning at the same High AI Energy tier.
|
|
473
|
+
- thinkingMode high without model uses GPT-5.6 Sol with high reasoning and consumes high AI Energy. Explicit model: 'gpt-5.6-sol' selects Sol with xhigh reasoning at the same High AI Energy tier. Explicit model: 'gpt-6-astra' selects GPT-6 Astra with xhigh reasoning and debits confirmed usage at its own model rates in the High tier.
|
|
474
474
|
- claude-opus-5 uses Anthropic adaptive High thinking. claude-fable-5-1 uses Anthropic xhigh thinking and normally consumes more AI Energy for comparable token use. Both debit confirmed provider usage at the High tier.
|
|
475
475
|
- Pass onStatus, onReasoning, and/or onText to stream progress from the same structured generation. onStatus receives high-level phases such as thinking, searching_web, responding, validating, and completed.
|
|
476
476
|
- onReasoning receives accumulated provider-supplied, app-visible reasoning summaries plus { done, delta, requestId, status }. A provider retry may replace the accumulated summary; treat each callback's first argument as the current source of truth. This callback never exposes hidden/private model chain-of-thought.
|