@stage5/lumine 0.3.1 → 0.3.3
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/lib/admin-daily.js +5 -1
- package/lib/admin.js +1 -1
- package/lib/rewards.js +1 -1
- package/package.json +1 -1
- package/sdk/BUILD_SDK_INDEX.md +10 -8
- package/sdk/LUMINE_ADMIN.md +1 -1
package/lib/admin-daily.js
CHANGED
|
@@ -260,7 +260,7 @@ nav h4{margin:0 0 10px;font-size:12px;letter-spacing:.08em;text-transform:upperc
|
|
|
260
260
|
main{margin-left:250px;padding:28px 40px;max-width:1100px}a{color:var(--link)}table{border-collapse:collapse;margin:10px 0;display:block;overflow-x:auto}th,td{border:1px solid var(--line);padding:6px 9px;text-align:left;vertical-align:top}
|
|
261
261
|
code{background:var(--code);padding:1px 5px;border-radius:4px;font-size:.9em}pre{background:var(--code);padding:12px;border-radius:8px;overflow:auto}h2{border-bottom:1px solid var(--line);padding-bottom:4px;margin-top:34px}
|
|
262
262
|
@media (max-width:760px){nav{position:static;width:auto;height:auto;border-right:0;border-bottom:1px solid var(--line)}main{margin-left:0;padding:16px}}
|
|
263
|
-
</style></head><body><nav><h4>Sections</h4><div id="toc"></div><h4 style="margin-top:18px">Source</h4><a href="
|
|
263
|
+
</style></head><body><nav><h4>Sections</h4><div id="toc"></div><h4 style="margin-top:18px">Source</h4><a href="source.html">Markdown</a></nav><main id="content">Loading…</main>
|
|
264
264
|
<script src="marked.min.js"></script><script>
|
|
265
265
|
fetch('daily-management-report.md',{cache:'no-store'}).then(r=>r.text()).then(md=>{const el=document.getElementById('content');el.innerHTML=marked.parse(md);const toc=document.getElementById('toc');let i=0;el.querySelectorAll('h1,h2').forEach(h=>{h.id='s'+(i++);if(h.tagName==='H2'){const a=document.createElement('a');a.href='#'+h.id;a.textContent=h.textContent;toc.appendChild(a)}})});
|
|
266
266
|
</script></body></html>`;
|
|
@@ -279,6 +279,10 @@ export async function reportServe(options) {
|
|
|
279
279
|
"/": () => ({ type: "text/html; charset=utf-8", body: reportHtml(title) }),
|
|
280
280
|
"/index.html": () => ({ type: "text/html; charset=utf-8", body: reportHtml(title) }),
|
|
281
281
|
"/marked.min.js": () => ({ type: "text/javascript", body: fs.readFileSync(MARKED_ASSET) }),
|
|
282
|
+
"/source.html": () => ({
|
|
283
|
+
type: "text/html; charset=utf-8",
|
|
284
|
+
body: `<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Original Markdown</title><style>body{margin:24px;font:15px/1.5 system-ui}pre{white-space:pre-wrap;overflow-wrap:anywhere}</style><a href="/">Back to report</a> · <a href="daily-management-report.md" download>Download Markdown</a><h1>Original Markdown</h1><pre>${fs.readFileSync(file, "utf8").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</pre></html>`,
|
|
285
|
+
}),
|
|
282
286
|
"/daily-management-report.md": () => ({
|
|
283
287
|
type: "text/markdown; charset=utf-8",
|
|
284
288
|
body: fs.readFileSync(file),
|
package/lib/admin.js
CHANGED
|
@@ -2414,7 +2414,7 @@ export function parseAdminOperation(options) {
|
|
|
2414
2414
|
// Seed questions for an approved app's reward question bank (generated-quiz
|
|
2415
2415
|
// rules). coverage is read-only; seed writes ONE missing question per call
|
|
2416
2416
|
// (lowest step first) as the daily run's Zero/Ciel identity and takes as
|
|
2417
|
-
// long as two GPT-6 Sol calls, so it gets its own timeout. The daily
|
|
2417
|
+
// long as two GPT-6.1 Sol calls, so it gets its own timeout. The daily
|
|
2418
2418
|
// website management run calls it in a bounded loop (Mikey, 2026-09-28).
|
|
2419
2419
|
const usage =
|
|
2420
2420
|
"Usage: lumine admin reward-bank coverage <buildId> [--max-step 3] | seed <buildId> [--max-step 3] | report <buildId> [--days 1].";
|
package/lib/rewards.js
CHANGED
|
@@ -247,6 +247,6 @@ rewards.json (project root) declares the economy the reviewer approves:
|
|
|
247
247
|
The Earn page shows rules under their category headers and each series as one row ("up to 3 a day").
|
|
248
248
|
Questions and answer keys never go in project files; they belong in the sheet.
|
|
249
249
|
generated-quiz rules need no sheet: the server writes each question for a topic at the learner's step
|
|
250
|
-
(GPT-6 Sol, billed to that learner's AI Energy), checks it with a second independent solve, and pays
|
|
250
|
+
(GPT-6.1 Sol, billed to that learner's AI Energy), checks it with a second independent solve, and pays
|
|
251
251
|
the step's percent of xp/coins. The reviewer approves the ladder, topics and instructions.`);
|
|
252
252
|
}
|
package/package.json
CHANGED
package/sdk/BUILD_SDK_INDEX.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Version: 1.63.0
|
|
4
4
|
Updated: 2026-09-28
|
|
5
|
-
Generated: 2026-09-
|
|
5
|
+
Generated: 2026-09-30T02:34:09.690Z
|
|
6
6
|
|
|
7
7
|
## Notes
|
|
8
8
|
- This SDK is injected into Build iframes via the Build preview/runtime.
|
|
@@ -34,7 +34,7 @@ Generated: 2026-09-28T08:22:20.133Z
|
|
|
34
34
|
- Media Energy is separate from AI Energy. Replace Media Energy UI only from canonical mediaEnergy/getUsage responses; never decrement, reserve, or synthesize it in app code.
|
|
35
35
|
- Twinkle.rewards awards real XP and Coins only in the current approved published release. Drafts, local previews, private apps and superseded releases cannot earn. The server supplies a published-runtime grant; app code cannot choose a recipient or award amount.
|
|
36
36
|
- The creator's agent designs the rewards. Declare the economy in a project file `rewards.json` at the root: budgets (userDailyXP, userDailyCoins, optional userDailyClaims; there is no app-wide daily or lifetime budget, only what one learner can earn per day) and rules [{ id, title, howTo?, category? (section header, up to 40 characters), series? (key for repeat rules that share category and amounts), xp, coins, verifier: 'numeric-quiz' | 'completion' | 'generated-quiz', maxAttempts?, retry?: { xpPercent, coinsPercent, paidAttempts? }, minSeconds? (completion), progression?: 'dated' | 'until-earned' (quiz), bank? (generated-quiz): { steps: [percent, ...] rising to 100, startStep?, instructions, topics: [{ key, title, description }] } }]. generated-quiz rules need no question sheet. Wire the matching Twinkle.rewards calls with those literal rule ids. Questions and answer keys NEVER go in project files (published source is readable by every player): quiz rules get them from the private question sheet uploaded with `lumine rewards sheet <file.json>` ({ rules: { <ruleId>: { questions?, sets? } } }); `lumine rewards check` validates both together. A review request freezes the code and proposes rewards.json merged with the sheet; the administrator reads the code, checks the amounts and whether the app is exploitable, may change any amount, and approves. Creators are kids and teens: show approval status and one Send for review action; do not ask them to fill in technical forms. Every code update that retains rewards needs a new approval before publishing. Removing the SDK automatically clears its gate. Apps read amounts, tries and sets from getStatus, never from their own file.
|
|
37
|
-
- Verifiers: 'numeric-quiz' pays for server-checked numeric answers (retry share, attempt limits, dated sets or until-earned sets that stay up until somebody earns them, after-answer guides). 'completion' pays when the app reports an activity finished — a cleared stage, a finished round — at least minSeconds after start({ ruleId }); the server checks only the elapsed time, once per learner per site day (UTC midnight), and the budgets. Call start when the activity begins and claim({ challengeId }) with no answers when it ends; keep completion amounts and userDailyXP small enough that a player scripting the calls would not matter, because nothing else is verified. 'generated-quiz' pays from a question bank the server fills itself: for one declared topic at the learner's step of the ladder, the server writes a question with GPT-6 Sol (billed to that learner's AI Energy), solves it again independently and keeps it only when both answers agree; every learner who has not seen a question gets it before anything new is written. `xp`/`coins` are the top step's amounts and each step pays its `steps` percent of them (then the usual retry share). Two first-try answers in a row climb a step; two misses in a row step down. Learners may earn many bank questions a day, bounded by userDailyXP/userDailyCoins. The reviewer approves the ladder, amounts, topics and instructions, not each question; learner reports and solve rates hide bad questions. Use the rewards bank methods (getBankStatus, startBankQuestion, generateBankQuestion, claimBankQuestion, reportBankQuestion); start and claim refuse bank rules.
|
|
37
|
+
- Verifiers: 'numeric-quiz' pays for server-checked numeric answers (retry share, attempt limits, dated sets or until-earned sets that stay up until somebody earns them, after-answer guides). 'completion' pays when the app reports an activity finished — a cleared stage, a finished round — at least minSeconds after start({ ruleId }); the server checks only the elapsed time, once per learner per site day (UTC midnight), and the budgets. Call start when the activity begins and claim({ challengeId }) with no answers when it ends; keep completion amounts and userDailyXP small enough that a player scripting the calls would not matter, because nothing else is verified. 'generated-quiz' pays from a question bank the server fills itself: for one declared topic at the learner's step of the ladder, the server writes a question with GPT-6.1 Sol (billed to that learner's AI Energy), solves it again independently and keeps it only when both answers agree; every learner who has not seen a question gets it before anything new is written. `xp`/`coins` are the top step's amounts and each step pays its `steps` percent of them (then the usual retry share). Two first-try answers in a row climb a step; two misses in a row step down. Learners may earn many bank questions a day, bounded by userDailyXP/userDailyCoins. The reviewer approves the ladder, amounts, topics and instructions, not each question; learner reports and solve rates hide bad questions. Use the rewards bank methods (getBankStatus, startBankQuestion, generateBankQuestion, claimBankQuestion, reportBankQuestion); start and claim refuse bank rules.
|
|
38
38
|
- Numeric quiz answers are verified on the server; client scores, privateDb state, timers and completion booleans are not verified reward evidence. Limits reset at UTC midnight. Rules are earned once per viewer per UTC day; attempt limits and retry payouts come from the approved rule. Challenges expire at the UTC day boundary. Budgets apply across release changes.
|
|
39
39
|
- Optional reward rule controls: maxLifetimeClaims caps one learner’s receipts for that rule across every day and release; completionProof: classic-tower-v1 requires a server-simulated Classic Tower finish in addition to minSeconds. These are server-enforced controls. Existing completion rules without completionProof still verify elapsed time only. Registered proof profiles also include breadface-v1, breadface-v2 and breadface-v3 (server-simulated Breadface inputs; each is one reviewed release's exact physics, chosen by the reviewer) study-record-v1 (a private study record reviewed by JEV, billed to the learner’s AI Energy), and Groove Lab's groove-lab-song-v1 (a song the learner published today, checked on the server for length, notes and originality) and groove-lab-heard-v1 (three established accounts finished the learner's songs today), Ashen Vigil's vigil-guest-coplay-v1 (a new guest spent 10 minutes with the learner in a private world room, measured by the world relay; each guest pays once) and minecraft-first-link-v1 (the learner is the first Twinkle account ever linked to that Minecraft player; each player pays once). Profiles are platform-owned; an app cannot invent a verifier or authorize its own reward.
|
|
40
40
|
|
|
@@ -497,20 +497,22 @@ const result = await Twinkle.ai.chat({ message, history: chatHistory, systemProm
|
|
|
497
497
|
- Signed-in viewers only.
|
|
498
498
|
- Use this instead of asking Twinkle.ai.chat to return JSON.
|
|
499
499
|
- expectedStructure must be a JSON object that describes the exact returned object shape.
|
|
500
|
+
- Template values describe types, not answers to copy. All object keys are required and extra keys are rejected, including inside nested objects; {} means an exactly empty object, not a free-form dictionary. A non-empty array uses only its first item as the template for every returned item, with no fixed length; mixed examples do not declare a union. [] allows arbitrary JSON items. A null template accepts any JSON primitive (string, number, boolean or null), but the key is still required. Use 'number' for fractional numbers; 0 and other integer examples require integers. State content requirements in prompt or instructions. GPT routes retain descriptive string examples as field guidance, not enforced enum values.
|
|
501
|
+
- GPT models prefer native JSON Schema output for compatible shapes. Shapes outside the strict provider subset, such as [] with arbitrary items or deeply nested structures, use prompt-based JSON generation with the same final validation. A provider rejection specifically of the native schema triggers one prompt-based fallback; auth, quota, safety and unrelated request failures do not trigger that fallback. Validation retries preserve the original task and instructions. The returned object/result shape and streaming callbacks are unchanged.
|
|
500
502
|
- mode is accepted as an alias for thinkingMode, and mid is accepted as an alias for medium.
|
|
501
|
-
- Omit model to use the normal Lite/Medium/High routing. model accepts gpt-6-sol or claude-opus-5-5, and every explicit model must be paired with thinkingMode: 'high'; unknown model IDs reject instead of silently falling back. Retired IDs still work and run on their replacement: gpt-5.6-sol
|
|
503
|
+
- Omit model to use the normal Lite/Medium/High routing. model accepts claude-sonnet-5-5, gpt-6.1-sol or claude-opus-5-5, and every explicit model must be paired with thinkingMode: 'high'; unknown model IDs reject instead of silently falling back. Retired IDs still work and run on their replacement: claude-sonnet-5 runs claude-sonnet-5-5; gpt-6-sol and gpt-5.6-sol run gpt-6.1-sol; gpt-6-astra, claude-opus-5 and claude-fable-5-1 run claude-opus-5-5.
|
|
502
504
|
- thinkingMode low uses GPT-6 Luna and consumes the viewer's AI Energy from confirmed provider usage; its smaller model is usually cheaper than Medium or High.
|
|
503
505
|
- thinkingMode medium uses GPT-6 Luna with medium reasoning and consumes normal AI Energy.
|
|
504
|
-
- thinkingMode high without model uses
|
|
505
|
-
- claude-opus-5-5
|
|
506
|
+
- thinkingMode high without model uses Claude Sonnet 5.5 with high adaptive thinking and consumes high AI Energy. Explicit model: 'gpt-6.1-sol' selects GPT-6.1 Sol with xhigh reasoning at the same High AI Energy tier; model: 'claude-sonnet-5-5' names Sonnet 5.5 directly.
|
|
507
|
+
- claude-sonnet-5-5 and claude-opus-5-5 use Anthropic adaptive High thinking and debit confirmed provider usage at the High tier.
|
|
506
508
|
- 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.
|
|
507
509
|
- 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.
|
|
508
510
|
- onText receives accumulated structured-output text plus { done, delta, requestId, status }. Partial output is intentionally incomplete and may include provider formatting; parse only when done is true, when the callback receives the canonical object serialized as JSON, and use the resolved object as the source of truth.
|
|
509
511
|
- Put a user-facing field such as producerNotes in expectedStructure when commentary must be part of the validated final object rather than transient reasoning progress.
|
|
510
512
|
- When AI Energy is empty, every automatic or named model choice rejects before new provider work; there is no free fallback mode.
|
|
511
513
|
- Live web search is enabled by default in Medium and High modes. Pass webSearch: false to disable it for the app. Low/Lite Mode remains tool-free; explicitly forcing webSearch: true in Low Mode returns an error.
|
|
512
|
-
- The server validates the final shape; automatic OpenAI/xAI routes can retry malformed output, while
|
|
513
|
-
- Example: const { object } = await Twinkle.ai.generateObject({ thinkingMode: 'high', model: 'claude-opus-5-5', prompt: 'Plan the next section from: ' + currentState, expectedStructure: { producerNotes: 'string', action: 'string', confidence:
|
|
514
|
+
- The server validates the final shape; automatic OpenAI/xAI routes can retry malformed output, while Anthropic routes (High without a model, claude-sonnet-5-5 and claude-opus-5-5) use native JSON Schema output and retry one malformed or shape-invalid result. App code should still validate business-specific enum values.
|
|
515
|
+
- Example: const { object } = await Twinkle.ai.generateObject({ thinkingMode: 'high', model: 'claude-opus-5-5', prompt: 'Plan the next section from: ' + currentState, expectedStructure: { producerNotes: 'string', action: 'string', confidence: 'number' }, onStatus: (phase) => showPhase(phase), onReasoning: (summary, meta) => showReasoningProgress(summary, meta), onText: (partialJson, meta) => showStructuredProgress(partialJson, meta) });
|
|
514
516
|
- onChatStatus(listener) | scopes: none
|
|
515
517
|
- Returns: unsubscribe function
|
|
516
518
|
- Listen to shared runtime AI chat stream events.
|
|
@@ -1518,7 +1520,7 @@ world.updatePresence({ x, y, z, facing });
|
|
|
1518
1520
|
- Returns: Same as startBankQuestion with the new question, or { needsQuestion: false } when an unseen question already exists (call startBankQuestion).
|
|
1519
1521
|
- Have the server write, double-check and serve a new question at the learner's step. Uses the learner's AI Energy.
|
|
1520
1522
|
- Show a progress bar from onProgress: stage is 'pending', 'writing', 'checking' (the independent solve), 'saving' or 'done'; percent follows the server's real phases and the model's streamed output, never goes backwards, and reaches 100 only when the question is served. Silent model thinking inside a phase cannot be measured, so the bar eases forward there rather than guessing.
|
|
1521
|
-
- Takes as long as two GPT-6 Sol calls (tens of seconds): show progress and keep one request in flight. Both calls are billed to the signed-in learner's AI Energy; an empty battery rejects before any work.
|
|
1523
|
+
- Takes as long as two GPT-6.1 Sol calls (tens of seconds): show progress and keep one request in flight. Both calls are billed to the signed-in learner's AI Energy; an empty battery rejects before any work.
|
|
1522
1524
|
- build_reward_bank_unverified (503) means two tries did not produce a question whose answers agreed; nothing is stored. build_reward_bank_generation_limit (429) caps questions one learner writes per day.
|
|
1523
1525
|
- The question joins the shared bank: every other learner at that step gets it before anything new is written.
|
|
1524
1526
|
- await Twinkle.rewards.claimBankQuestion({ challengeId, answer: number }) | scopes: rewards:claim
|
package/sdk/LUMINE_ADMIN.md
CHANGED
|
@@ -1296,7 +1296,7 @@ leaves the offered media as unused uploads in the creator's library.
|
|
|
1296
1296
|
### Reward question-bank seeding (every full daily review; added 2026-09-28)
|
|
1297
1297
|
|
|
1298
1298
|
`generated-quiz` rules fill a question bank on the server: a question is
|
|
1299
|
-
written for one declared topic at one ladder step (GPT-6 Sol) and kept only
|
|
1299
|
+
written for one declared topic at one ladder step (GPT-6.1 Sol) and kept only
|
|
1300
1300
|
when an independent second solve agrees. Learners write missing questions
|
|
1301
1301
|
themselves on their own AI Energy; seeding writes the gentlest steps ahead of
|
|
1302
1302
|
them so the first learner on a unit never waits or pays.
|