primitive-admin 1.2.0-alpha.0 → 1.2.0-alpha.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.
- package/README.md +6 -4
- package/dist/bin/primitive.js +22 -24
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/agent-sessions.d.ts +20 -0
- package/dist/src/commands/agent-sessions.js +275 -0
- package/dist/src/commands/agent-sessions.js.map +1 -0
- package/dist/src/commands/apps-children.d.ts +54 -0
- package/dist/src/commands/apps-children.js +578 -0
- package/dist/src/commands/apps-children.js.map +1 -0
- package/dist/src/commands/apps.js +88 -9
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/auth-sessions.d.ts +3 -3
- package/dist/src/commands/auth-sessions.js +117 -23
- package/dist/src/commands/auth-sessions.js.map +1 -1
- package/dist/src/commands/auth.js +248 -15
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/connections.js +1 -5
- package/dist/src/commands/connections.js.map +1 -1
- package/dist/src/commands/databases.js +7 -109
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.d.ts +29 -0
- package/dist/src/commands/documents.js +676 -191
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/env.d.ts +9 -1
- package/dist/src/commands/env.js +158 -45
- package/dist/src/commands/env.js.map +1 -1
- package/dist/src/commands/functions.js +7 -1
- package/dist/src/commands/functions.js.map +1 -1
- package/dist/src/commands/init.js +2 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.js +14 -2
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/prompts.js +4 -0
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/scripts.js +1 -1
- package/dist/src/commands/scripts.js.map +1 -1
- package/dist/src/commands/sessions.js +3 -8
- package/dist/src/commands/sessions.js.map +1 -1
- package/dist/src/commands/sync-app-settings.d.ts +25 -7
- package/dist/src/commands/sync-app-settings.js +81 -20
- package/dist/src/commands/sync-app-settings.js.map +1 -1
- package/dist/src/commands/sync.d.ts +183 -12
- package/dist/src/commands/sync.js +974 -452
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.js +1 -6
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.js +77 -2
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/lib/api-client.d.ts +161 -35
- package/dist/src/lib/api-client.js +210 -86
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/app-settings-descriptor.d.ts +9 -1
- package/dist/src/lib/app-settings-descriptor.js +22 -10
- package/dist/src/lib/app-settings-descriptor.js.map +1 -1
- package/dist/src/lib/auth-flow.d.ts +41 -1
- package/dist/src/lib/auth-flow.js +45 -16
- package/dist/src/lib/auth-flow.js.map +1 -1
- package/dist/src/lib/child-apps-local.d.ts +184 -0
- package/dist/src/lib/child-apps-local.js +282 -0
- package/dist/src/lib/child-apps-local.js.map +1 -0
- package/dist/src/lib/ci-session-request.d.ts +22 -0
- package/dist/src/lib/ci-session-request.js +51 -0
- package/dist/src/lib/ci-session-request.js.map +1 -0
- package/dist/src/lib/codegen-shared/generatedFiles.d.ts +4 -1
- package/dist/src/lib/codegen-shared/generatedFiles.js +19 -13
- package/dist/src/lib/codegen-shared/generatedFiles.js.map +1 -1
- package/dist/src/lib/config-object-descriptor.js +5 -5
- package/dist/src/lib/config-object-descriptor.js.map +1 -1
- package/dist/src/lib/config-payload.js +2 -3
- package/dist/src/lib/config-payload.js.map +1 -1
- package/dist/src/lib/config-surface.d.ts +2 -1
- package/dist/src/lib/config-surface.js +7 -28
- package/dist/src/lib/config-surface.js.map +1 -1
- package/dist/src/lib/credentials-store.d.ts +17 -2
- package/dist/src/lib/credentials-store.js +72 -6
- package/dist/src/lib/credentials-store.js.map +1 -1
- package/dist/src/lib/document-export-lookups.d.ts +31 -0
- package/dist/src/lib/document-export-lookups.js +53 -0
- package/dist/src/lib/document-export-lookups.js.map +1 -0
- package/dist/src/lib/document-export-permissions.d.ts +7 -5
- package/dist/src/lib/document-export-permissions.js +7 -5
- package/dist/src/lib/document-export-permissions.js.map +1 -1
- package/dist/src/lib/env-resolver-core.d.ts +69 -1
- package/dist/src/lib/env-resolver-core.js +137 -20
- package/dist/src/lib/env-resolver-core.js.map +1 -1
- package/dist/src/lib/env-resolver.d.ts +14 -2
- package/dist/src/lib/env-resolver.js +32 -10
- package/dist/src/lib/env-resolver.js.map +1 -1
- package/dist/src/lib/function-run.d.ts +4 -1
- package/dist/src/lib/function-run.js +24 -4
- package/dist/src/lib/function-run.js.map +1 -1
- package/dist/src/lib/function-sync.d.ts +5 -2
- package/dist/src/lib/function-sync.js +7 -4
- package/dist/src/lib/function-sync.js.map +1 -1
- package/dist/src/lib/generated-config-surfaces.d.ts +49 -50
- package/dist/src/lib/generated-config-surfaces.js +283 -166
- package/dist/src/lib/generated-config-surfaces.js.map +1 -1
- package/dist/src/lib/generated-sdk-types.d.ts +1 -1
- package/dist/src/lib/generated-sdk-types.js +1 -1
- package/dist/src/lib/generated-sdk-types.js.map +1 -1
- package/dist/src/lib/init-adopt.js +12 -3
- package/dist/src/lib/init-adopt.js.map +1 -1
- package/dist/src/lib/local-state.d.ts +17 -1
- package/dist/src/lib/local-state.js +94 -15
- package/dist/src/lib/local-state.js.map +1 -1
- package/dist/src/lib/local-test-cases.d.ts +5 -2
- package/dist/src/lib/local-test-cases.js +7 -4
- package/dist/src/lib/local-test-cases.js.map +1 -1
- package/dist/src/lib/log-inspection.d.ts +25 -0
- package/dist/src/lib/log-inspection.js +24 -0
- package/dist/src/lib/log-inspection.js.map +1 -1
- package/dist/src/lib/logout-admin-session.d.ts +2 -1
- package/dist/src/lib/logout-admin-session.js +7 -1
- package/dist/src/lib/logout-admin-session.js.map +1 -1
- package/dist/src/lib/pull-write.d.ts +31 -0
- package/dist/src/lib/pull-write.js +49 -0
- package/dist/src/lib/pull-write.js.map +1 -0
- package/dist/src/lib/root-import-decision.d.ts +59 -0
- package/dist/src/lib/root-import-decision.js +95 -0
- package/dist/src/lib/root-import-decision.js.map +1 -0
- package/dist/src/lib/scope-request.d.ts +69 -0
- package/dist/src/lib/scope-request.js +188 -0
- package/dist/src/lib/scope-request.js.map +1 -0
- package/dist/src/lib/session-id.d.ts +9 -0
- package/dist/src/lib/session-id.js +28 -0
- package/dist/src/lib/session-id.js.map +1 -0
- package/dist/src/lib/snapshots.d.ts +17 -1
- package/dist/src/lib/snapshots.js +50 -2
- package/dist/src/lib/snapshots.js.map +1 -1
- package/dist/src/lib/sync-paths.d.ts +35 -0
- package/dist/src/lib/sync-paths.js +57 -5
- package/dist/src/lib/sync-paths.js.map +1 -1
- package/dist/src/lib/transient-retry.d.ts +34 -0
- package/dist/src/lib/transient-retry.js +57 -0
- package/dist/src/lib/transient-retry.js.map +1 -0
- package/dist/src/types/index.d.ts +21 -4
- package/package.json +4 -3
|
@@ -94,8 +94,8 @@ export function writableFieldNames(table, mode) {
|
|
|
94
94
|
* The field names the server PERSISTS for this table in `mode`: the writable
|
|
95
95
|
* fields, plus the `deprecated` classifications — "still writable, superseded
|
|
96
96
|
* by another field" is what that kind means (`types.ts`), so a superseded key
|
|
97
|
-
* a handler still honors (`
|
|
98
|
-
*
|
|
97
|
+
* a handler still honors (`passkeyRpId`) belongs in every accepted set, and a
|
|
98
|
+
* field that is NOT writable belongs in none of them.
|
|
99
99
|
*
|
|
100
100
|
* Stated once here because three consumers need the same answer: the generated
|
|
101
101
|
* request schemas, `PUT /settings`'s write allow-list, and the guards.
|
|
@@ -401,8 +401,9 @@ export function acceptedGroupTomlKeys(table, group) {
|
|
|
401
401
|
* is therefore an unknown key rather than one the payload builder silently
|
|
402
402
|
* ignores (SO3626-013) — the builder reads a grouped field only from
|
|
403
403
|
* `source[group][tomlKey]`, so accepting it here would drop the author's value
|
|
404
|
-
* without a word.
|
|
405
|
-
*
|
|
404
|
+
* without a word. A key whose root spelling was retired while it moved into a
|
|
405
|
+
* group (the flat chat keys, #3642) is refused the same way, with the guidance
|
|
406
|
+
* `RETIRED_TOML_SPELLINGS` states.
|
|
406
407
|
*/
|
|
407
408
|
export function acceptedTomlKeys(table) {
|
|
408
409
|
return new Set([
|
|
@@ -2343,9 +2344,11 @@ export const RETIRED_CONFIG_KEYS = {
|
|
|
2343
2344
|
"names.",
|
|
2344
2345
|
},
|
|
2345
2346
|
// #2884 — email sign-in became ONE flow, so it has ONE setting. Both keys
|
|
2346
|
-
// stay DECLARED in `models.yaml`
|
|
2347
|
-
//
|
|
2348
|
-
//
|
|
2347
|
+
// stay DECLARED in `models.yaml` as hidden attributes (#3993): never
|
|
2348
|
+
// written, never echoed, refused by `config push`, the tenant PUT and the
|
|
2349
|
+
// admin API alike, and read only by the fallback for a row that stores no
|
|
2350
|
+
// `emailSignInEnabled`. A file or body that still carries one is asking
|
|
2351
|
+
// for a method choice that no longer exists.
|
|
2349
2352
|
magicLinkEnabled: {
|
|
2350
2353
|
toml: "`magicLinkEnabled` is no longer authored in TOML (#2884). Email " +
|
|
2351
2354
|
"sign-in is one flow — one request sends one email carrying a code " +
|
|
@@ -2363,6 +2366,27 @@ export const RETIRED_CONFIG_KEYS = {
|
|
|
2363
2366
|
"send `emailSignInEnabled`.",
|
|
2364
2367
|
},
|
|
2365
2368
|
},
|
|
2369
|
+
// #3996 — a bucket's access is `preset` (#1020). The old spelling stayed
|
|
2370
|
+
// accepted as an alias, which left two vocabularies for one decision —
|
|
2371
|
+
// `owner-only` still read as "the uploader", the bug #1020 fixed — and an
|
|
2372
|
+
// echo whose value depended on the row's age. A file or body that still
|
|
2373
|
+
// carries it is refused rather than mapped, so the author meets the new
|
|
2374
|
+
// vocabulary once. The model attribute stays declared: a pre-#1020 row
|
|
2375
|
+
// still resolves to its preset (`resolveBucketPreset`).
|
|
2376
|
+
bucket: {
|
|
2377
|
+
accessPolicy: {
|
|
2378
|
+
toml: "`accessPolicy` is no longer authored in TOML (#3996): a bucket's " +
|
|
2379
|
+
"access is `preset`. Map the value — `public-read` → `public`, " +
|
|
2380
|
+
"`authenticated` → `authenticated`, `owner-only` → `admin-only` (it " +
|
|
2381
|
+
"always meant app admins; `personal-uploads` is the per-uploader " +
|
|
2382
|
+
"preset). Replace the line and push again, or `config pull` rewrites " +
|
|
2383
|
+
"the file.",
|
|
2384
|
+
request: "`accessPolicy` is retired (#3996): send `preset`. `public-read` → " +
|
|
2385
|
+
"`public`, `authenticated` → `authenticated`, `owner-only` → " +
|
|
2386
|
+
"`admin-only` (app admins; `personal-uploads` is the per-uploader " +
|
|
2387
|
+
"preset).",
|
|
2388
|
+
},
|
|
2389
|
+
},
|
|
2366
2390
|
// #2645 — pausing moved off `state` onto its own field, so `state` stopped
|
|
2367
2391
|
// being author-writable rather than becoming a second way to say "paused".
|
|
2368
2392
|
// Every pre-#2645 pull wrote the line, so existing repos hit this on their
|
|
@@ -2520,6 +2544,47 @@ export const RETIRED_CONFIG_KEYS = {
|
|
|
2520
2544
|
"Omit the field.",
|
|
2521
2545
|
},
|
|
2522
2546
|
},
|
|
2547
|
+
// #3998 — a test-case sidecar names what it pins: the configuration it runs
|
|
2548
|
+
// under and its judge prompt, by name, so the file means the same thing in
|
|
2549
|
+
// every app. The id spellings were deprecated TOML-only keys that won over
|
|
2550
|
+
// the name, and — unlike every other retired key — `config pull` still WROTE
|
|
2551
|
+
// them whenever its id→name lookup missed, so the spelling kept being
|
|
2552
|
+
// generated. Pull now reports such a case instead of writing an id.
|
|
2553
|
+
//
|
|
2554
|
+
// The three stay the stored references the admin API accepts on create and
|
|
2555
|
+
// update, so the `request` wording below is never shown: `rememberRetiredKeys`
|
|
2556
|
+
// and the admin API's unknown-key check both skip a key the wire accepts. It
|
|
2557
|
+
// is here because the entry's shape requires it.
|
|
2558
|
+
test: {
|
|
2559
|
+
configId: {
|
|
2560
|
+
toml: "`configId` is no longer authored in TOML (#3998): a test case names " +
|
|
2561
|
+
"the configuration it runs under, so the file means the same thing in " +
|
|
2562
|
+
"every app. Replace the line with `configName = \"…\"` (a " +
|
|
2563
|
+
"`[[configs]]` name of the block this sidecar belongs to), or delete it " +
|
|
2564
|
+
"to run the active configuration, and push again.",
|
|
2565
|
+
request: "`configId` is the stored configuration reference; only its TOML " +
|
|
2566
|
+
"spelling is retired (#3998). Sidecars author it as `configName`.",
|
|
2567
|
+
},
|
|
2568
|
+
evaluatorPromptId: {
|
|
2569
|
+
toml: "`evaluatorPromptId` is no longer authored in TOML (#3998): a test " +
|
|
2570
|
+
"case names its judge prompt, so the file means the same thing in " +
|
|
2571
|
+
"every app. Replace the line with `evaluatorPromptKey = \"…\"` (the " +
|
|
2572
|
+
"judge prompt's key) and push again.",
|
|
2573
|
+
request: "`evaluatorPromptId` is the stored judge-prompt reference; only its " +
|
|
2574
|
+
"TOML spelling is retired (#3998). Sidecars author it as " +
|
|
2575
|
+
"`evaluatorPromptKey`.",
|
|
2576
|
+
},
|
|
2577
|
+
evaluatorConfigId: {
|
|
2578
|
+
toml: "`evaluatorConfigId` is no longer authored in TOML (#3998): a test " +
|
|
2579
|
+
"case names its judge's configuration, so the file means the same " +
|
|
2580
|
+
"thing in every app. Replace the line with " +
|
|
2581
|
+
"`evaluatorConfigName = \"…\"` (a `[[configs]]` name of the prompt " +
|
|
2582
|
+
"`evaluatorPromptKey` names) and push again.",
|
|
2583
|
+
request: "`evaluatorConfigId` is the stored judge-configuration reference; only " +
|
|
2584
|
+
"its TOML spelling is retired (#3998). Sidecars author it as " +
|
|
2585
|
+
"`evaluatorConfigName`.",
|
|
2586
|
+
},
|
|
2587
|
+
},
|
|
2523
2588
|
// #2803 — availability is one server-owned `status`. As a TOML key it made
|
|
2524
2589
|
// `config push` a second writer: pushing a file pulled before an operator ran
|
|
2525
2590
|
// `workflows disable` put the workflow back in service as a side effect.
|
|
@@ -2539,6 +2604,47 @@ export const RETIRED_CONFIG_KEYS = {
|
|
|
2539
2604
|
export function retiredConfigKey(prefix, key) {
|
|
2540
2605
|
return RETIRED_CONFIG_KEYS[prefix]?.[key] ?? null;
|
|
2541
2606
|
}
|
|
2607
|
+
// #3642 — the pre-#3626 flat spelling of one chat setting. The six keys an
|
|
2608
|
+
// agent's model round shares (`AGENT_CONFIG_KEYS`) also name the agent block.
|
|
2609
|
+
// The names are written out rather than read from `prompt-kinds.ts`, which the
|
|
2610
|
+
// vendored artifact places after this module.
|
|
2611
|
+
function flatChatKeySpelling(key, sharedWithAgent) {
|
|
2612
|
+
return {
|
|
2613
|
+
toml: `\`${key}\` is no longer authored flat under \`[[configs]]\` (#3642). ` +
|
|
2614
|
+
"Chat settings live in the entry's `[configs.chat]` block" +
|
|
2615
|
+
(sharedWithAgent ? " (`[configs.agent]` on an agent prompt)" : "") +
|
|
2616
|
+
": move the line into that block and push again. `config pull` " +
|
|
2617
|
+
"rewrites a file whose prompt already exists on the server.",
|
|
2618
|
+
};
|
|
2619
|
+
}
|
|
2620
|
+
/**
|
|
2621
|
+
* Spellings retired from TOML while the key itself stays live on the wire,
|
|
2622
|
+
* keyed like `RETIRED_CONFIG_KEYS`. The request side never reads this map: a
|
|
2623
|
+
* body that sends one of these keys is a body the schema accepts.
|
|
2624
|
+
*/
|
|
2625
|
+
export const RETIRED_TOML_SPELLINGS = {
|
|
2626
|
+
// #3642 — the nine chat keys at the prompt `[[configs]]` root. The admin
|
|
2627
|
+
// API's create and update bodies still carry them flat; only the TOML
|
|
2628
|
+
// grouping (#3626) moved them under `[configs.chat]`.
|
|
2629
|
+
configs: {
|
|
2630
|
+
systemPrompt: flatChatKeySpelling("systemPrompt", true),
|
|
2631
|
+
userPromptTemplate: flatChatKeySpelling("userPromptTemplate", false),
|
|
2632
|
+
temperature: flatChatKeySpelling("temperature", true),
|
|
2633
|
+
topP: flatChatKeySpelling("topP", true),
|
|
2634
|
+
maxTokens: flatChatKeySpelling("maxTokens", true),
|
|
2635
|
+
outputFormat: flatChatKeySpelling("outputFormat", false),
|
|
2636
|
+
outputSchema: flatChatKeySpelling("outputSchema", false),
|
|
2637
|
+
reasoningEffort: flatChatKeySpelling("reasoningEffort", true),
|
|
2638
|
+
reasoningBudget: flatChatKeySpelling("reasoningBudget", true),
|
|
2639
|
+
},
|
|
2640
|
+
};
|
|
2641
|
+
/**
|
|
2642
|
+
* The TOML guidance for `key` under `prefix`: a fully retired key's, else a
|
|
2643
|
+
* retired spelling's, else null when the key is simply unknown.
|
|
2644
|
+
*/
|
|
2645
|
+
export function retiredTomlKey(prefix, key) {
|
|
2646
|
+
return (retiredConfigKey(prefix, key) ?? RETIRED_TOML_SPELLINGS[prefix]?.[key] ?? null);
|
|
2647
|
+
}
|
|
2542
2648
|
// ── src/config-surface/function-grants.ts ────────────────────────────────
|
|
2543
2649
|
/**
|
|
2544
2650
|
* The capability grammar for server functions — #3182 phase 1, rewritten by
|
|
@@ -4712,7 +4818,12 @@ export function checkCronTriggerEntry(entry) {
|
|
|
4712
4818
|
* all read this one copy, so a refusal at push and a refusal at execution
|
|
4713
4819
|
* cannot disagree.
|
|
4714
4820
|
*
|
|
4715
|
-
*
|
|
4821
|
+
* What this encodes is each provider's SPELLING, per model family — never
|
|
4822
|
+
* which values a particular model accepts (#4147). A value the spelling can
|
|
4823
|
+
* carry is sent, and a model that does not support it is refused by the
|
|
4824
|
+
* provider, whose answer the run reports. A per-model table of accepted levels
|
|
4825
|
+
* and floors went stale with each model release and refused or admitted the
|
|
4826
|
+
* wrong values.
|
|
4716
4827
|
*
|
|
4717
4828
|
* - OpenRouter takes a unified `reasoning` block: `{ effort }`,
|
|
4718
4829
|
* `{ max_tokens }`, or `{ enabled: false }` to decline it. `max_tokens` is an
|
|
@@ -4725,13 +4836,13 @@ export function checkCronTriggerEntry(entry) {
|
|
|
4725
4836
|
* is refused by OpenRouter and surfaces as a failed execution rather than a
|
|
4726
4837
|
* silent drop.
|
|
4727
4838
|
* - Gemini 3.x expresses thinking as a LEVEL
|
|
4728
|
-
* (`thinkingConfig.thinkingLevel`) and
|
|
4729
|
-
*
|
|
4730
|
-
*
|
|
4731
|
-
* a pointer at
|
|
4839
|
+
* (`thinkingConfig.thinkingLevel`), and the level spelling has no "off"
|
|
4840
|
+
* value, so `none` has nothing to translate to. `thinkingBudget` is accepted
|
|
4841
|
+
* there only for backward compatibility and is translated to a level rather
|
|
4842
|
+
* than honored as a bound, so a numeric budget is refused with a pointer at
|
|
4843
|
+
* `reasoningEffort`.
|
|
4732
4844
|
* - Gemini 2.5 expresses it as a numeric BUDGET
|
|
4733
|
-
* (`thinkingConfig.thinkingBudget`); `
|
|
4734
|
-
* Flash-Lite, while Pro has a floor of 128 and answers 400 for less.
|
|
4845
|
+
* (`thinkingConfig.thinkingBudget`); `none` is a budget of `0`.
|
|
4735
4846
|
* - Gemini 2.0 and earlier have no thinking control at all.
|
|
4736
4847
|
*/
|
|
4737
4848
|
/** The provider-neutral effort levels a config may state. */
|
|
@@ -4742,8 +4853,6 @@ export const REASONING_EFFORTS = [
|
|
|
4742
4853
|
"medium",
|
|
4743
4854
|
"high",
|
|
4744
4855
|
];
|
|
4745
|
-
/** The smallest budget Gemini 2.5 Pro accepts; it cannot stop thinking. */
|
|
4746
|
-
export const GEMINI_PRO_MIN_THINKING_BUDGET = 128;
|
|
4747
4856
|
export function geminiReasoningFamily(model) {
|
|
4748
4857
|
const match = /gemini-(\d+)(?:[.-](\d+))?/i.exec(model || "");
|
|
4749
4858
|
if (!match)
|
|
@@ -4758,10 +4867,6 @@ export function geminiReasoningFamily(model) {
|
|
|
4758
4867
|
return "budget";
|
|
4759
4868
|
return "none";
|
|
4760
4869
|
}
|
|
4761
|
-
/** Gemini Pro: the tier that cannot stop thinking in either family. */
|
|
4762
|
-
export function isGeminiProModel(model) {
|
|
4763
|
-
return /(^|[-_/.])pro($|[-_/.])/i.test(model || "");
|
|
4764
|
-
}
|
|
4765
4870
|
/** Is EITHER reasoning key stated on this config? */
|
|
4766
4871
|
export function hasPromptReasoning(input) {
|
|
4767
4872
|
return (normalizeEffort(input.reasoningEffort) !== null ||
|
|
@@ -4845,7 +4950,6 @@ function openRouterDirective(effort, budget) {
|
|
|
4845
4950
|
}
|
|
4846
4951
|
function geminiResolution(model, effort, budget) {
|
|
4847
4952
|
const family = geminiReasoningFamily(model);
|
|
4848
|
-
const isPro = isGeminiProModel(model);
|
|
4849
4953
|
if (family === "none") {
|
|
4850
4954
|
return {
|
|
4851
4955
|
ok: false,
|
|
@@ -4868,15 +4972,10 @@ function geminiResolution(model, effort, budget) {
|
|
|
4868
4972
|
if (effort === "none") {
|
|
4869
4973
|
return {
|
|
4870
4974
|
ok: false,
|
|
4871
|
-
error: `Gemini model '${model}'
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
if (isPro && (effort === "minimal" || effort === "medium")) {
|
|
4876
|
-
return {
|
|
4877
|
-
ok: false,
|
|
4878
|
-
error: `Gemini Pro model '${model}' accepts only 'low' or 'high' as a ` +
|
|
4879
|
-
`thinking level; '${effort}' is a Flash-only level.`,
|
|
4975
|
+
error: `Gemini model '${model}' expresses reasoning as a LEVEL, which has no ` +
|
|
4976
|
+
"'none' value. Use reasoningEffort " +
|
|
4977
|
+
`(${REASONING_EFFORTS.filter((e) => e !== "none").join(", ")}); the ` +
|
|
4978
|
+
"provider's model documentation lists which levels this model accepts.",
|
|
4880
4979
|
};
|
|
4881
4980
|
}
|
|
4882
4981
|
return {
|
|
@@ -4897,14 +4996,6 @@ function geminiResolution(model, effort, budget) {
|
|
|
4897
4996
|
};
|
|
4898
4997
|
}
|
|
4899
4998
|
const resolved = effort === "none" ? 0 : budget;
|
|
4900
|
-
if (isPro && resolved < GEMINI_PRO_MIN_THINKING_BUDGET) {
|
|
4901
|
-
return {
|
|
4902
|
-
ok: false,
|
|
4903
|
-
error: `Gemini Pro model '${model}' cannot turn thinking off: its smallest ` +
|
|
4904
|
-
`thinking budget is ${GEMINI_PRO_MIN_THINKING_BUDGET} tokens, and ` +
|
|
4905
|
-
`${resolved} is refused by the provider.`,
|
|
4906
|
-
};
|
|
4907
|
-
}
|
|
4908
4999
|
return {
|
|
4909
5000
|
ok: true,
|
|
4910
5001
|
directive: {
|
|
@@ -4944,12 +5035,16 @@ function geminiResolution(model, effort, budget) {
|
|
|
4944
5035
|
*/
|
|
4945
5036
|
export const PROMPT_KINDS = ["chat", "decisions", "agent"];
|
|
4946
5037
|
/**
|
|
4947
|
-
* The
|
|
4948
|
-
*
|
|
4949
|
-
*
|
|
4950
|
-
*
|
|
5038
|
+
* The settings that describe a CHAT COMPLETION and nothing else. They are
|
|
5039
|
+
* authored under `[configs.chat]` and only there: the pre-#3626 flat spelling
|
|
5040
|
+
* of the first nine is retired and refused at push (#3642,
|
|
5041
|
+
* `RETIRED_TOML_SPELLINGS`).
|
|
5042
|
+
*
|
|
5043
|
+
* #3801 — `strictOutput`, the opt-in that sends `[prompt].outputSchema` as a
|
|
5044
|
+
* strict `json_schema` on OpenRouter (`prompt-strict-output.ts`). Not an agent
|
|
5045
|
+
* key (§D1: an agent has no output schema), so the agent arm refuses it.
|
|
4951
5046
|
*/
|
|
4952
|
-
export const
|
|
5047
|
+
export const CHAT_CONFIG_KEYS = [
|
|
4953
5048
|
"systemPrompt",
|
|
4954
5049
|
"userPromptTemplate",
|
|
4955
5050
|
"temperature",
|
|
@@ -4959,18 +5054,6 @@ export const LEGACY_FLAT_CHAT_KEYS = [
|
|
|
4959
5054
|
"outputSchema",
|
|
4960
5055
|
"reasoningEffort",
|
|
4961
5056
|
"reasoningBudget",
|
|
4962
|
-
];
|
|
4963
|
-
/**
|
|
4964
|
-
* The settings that describe a CHAT COMPLETION and nothing else. They are
|
|
4965
|
-
* authored under `[configs.chat]`; the flat spelling of the nine legacy keys
|
|
4966
|
-
* is deprecated (#3642).
|
|
4967
|
-
*
|
|
4968
|
-
* #3801 — `strictOutput`, the opt-in that sends `[prompt].outputSchema` as a
|
|
4969
|
-
* strict `json_schema` on OpenRouter (`prompt-strict-output.ts`). Not an agent
|
|
4970
|
-
* key (§D1: an agent has no output schema), so the agent arm refuses it.
|
|
4971
|
-
*/
|
|
4972
|
-
export const CHAT_CONFIG_KEYS = [
|
|
4973
|
-
...LEGACY_FLAT_CHAT_KEYS,
|
|
4974
5057
|
"strictOutput",
|
|
4975
5058
|
];
|
|
4976
5059
|
/** The settings that describe a DECISIONS request. */
|
|
@@ -5406,45 +5489,6 @@ export function resolveDecisionsRunQuestions(questions, runCriteria) {
|
|
|
5406
5489
|
}
|
|
5407
5490
|
return { ok: true, questions: resolved };
|
|
5408
5491
|
}
|
|
5409
|
-
/**
|
|
5410
|
-
* Move the deprecated flat chat keys of one `[[configs]]` entry under `chat`
|
|
5411
|
-
* — #3626 §4, the blob-bucket `accessPolicy` precedent made reusable.
|
|
5412
|
-
*
|
|
5413
|
-
* Push keeps accepting the nine keys flat so no existing file breaks, and pull
|
|
5414
|
-
* rewrites them, so one pull-then-push migrates a file. A key present in BOTH
|
|
5415
|
-
* spellings is not merged: the grouped value is left standing and the key is
|
|
5416
|
-
* reported in `conflicts`, which the caller turns into a refusal naming the
|
|
5417
|
-
* entry. Nothing else in the entry is touched — `providerConfig` is
|
|
5418
|
-
* provider-keyed rather than chat-keyed (D3626-002) and `questions` has no flat
|
|
5419
|
-
* spelling at all (SO3626-013).
|
|
5420
|
-
*/
|
|
5421
|
-
export function hoistDeprecatedChatKeys(entry) {
|
|
5422
|
-
if (!isPlainObject(entry)) {
|
|
5423
|
-
return { entry: {}, moved: [], conflicts: [] };
|
|
5424
|
-
}
|
|
5425
|
-
const out = { ...entry };
|
|
5426
|
-
const existingGroup = isPlainObject(out.chat) ? { ...out.chat } : undefined;
|
|
5427
|
-
const group = existingGroup ?? {};
|
|
5428
|
-
const moved = [];
|
|
5429
|
-
const conflicts = [];
|
|
5430
|
-
// #3801 — only the legacy keys have a flat spelling to hoist; `strictOutput`
|
|
5431
|
-
// at the root is an unknown key naming its block.
|
|
5432
|
-
for (const key of LEGACY_FLAT_CHAT_KEYS) {
|
|
5433
|
-
if (!(key in out))
|
|
5434
|
-
continue;
|
|
5435
|
-
if (existingGroup && key in existingGroup) {
|
|
5436
|
-
conflicts.push(key);
|
|
5437
|
-
delete out[key];
|
|
5438
|
-
continue;
|
|
5439
|
-
}
|
|
5440
|
-
group[key] = out[key];
|
|
5441
|
-
delete out[key];
|
|
5442
|
-
moved.push(key);
|
|
5443
|
-
}
|
|
5444
|
-
if (existingGroup || moved.length > 0)
|
|
5445
|
-
out.chat = group;
|
|
5446
|
-
return { entry: out, moved: moved.sort(), conflicts: conflicts.sort() };
|
|
5447
|
-
}
|
|
5448
5492
|
// ── src/config-surface/prompt-strict-output.ts ───────────────────────────
|
|
5449
5493
|
/**
|
|
5450
5494
|
* Strict output for a chat config — issue #3801 (project `agents`, §D6).
|
|
@@ -5655,16 +5699,20 @@ export const AGENT_ERROR_CODES = [
|
|
|
5655
5699
|
"AGENT_ROUND_EMPTY",
|
|
5656
5700
|
];
|
|
5657
5701
|
/**
|
|
5658
|
-
* The platform maximums. An agent may lower `maxSteps
|
|
5659
|
-
* never raise them; the tool and event counts bound what
|
|
5660
|
-
* make every turn carry (principle 2).
|
|
5702
|
+
* The platform maximums. An agent may lower `maxSteps`, `waitLimitSeconds`
|
|
5703
|
+
* and `maxRowBytes`, never raise them; the tool and event counts bound what
|
|
5704
|
+
* one declaration can make every turn carry (principle 2).
|
|
5661
5705
|
*/
|
|
5662
5706
|
export const AGENT_LIMITS = {
|
|
5663
5707
|
maxSteps: 25,
|
|
5664
5708
|
waitLimitSeconds: 604800,
|
|
5709
|
+
/** The JSON bytes of one session-document row a turn writes from model or tool output. */
|
|
5710
|
+
maxRowBytes: 262144,
|
|
5665
5711
|
tools: 64,
|
|
5666
5712
|
events: 64,
|
|
5667
5713
|
};
|
|
5714
|
+
/** The smallest row ceiling an agent may declare: room for a call's own columns. */
|
|
5715
|
+
export const AGENT_ROW_BYTES_FLOOR = 1024;
|
|
5668
5716
|
/**
|
|
5669
5717
|
* A tool or event name: the intersection of OpenRouter's and Gemini's
|
|
5670
5718
|
* function-name rules, so one declaration maps onto either provider.
|
|
@@ -5677,6 +5725,7 @@ const AGENT_TOP_LEVEL_KEYS = [
|
|
|
5677
5725
|
"answeredBy",
|
|
5678
5726
|
"maxSteps",
|
|
5679
5727
|
"waitLimitSeconds",
|
|
5728
|
+
"maxRowBytes",
|
|
5680
5729
|
"turnContext",
|
|
5681
5730
|
"history",
|
|
5682
5731
|
"tools",
|
|
@@ -5767,13 +5816,13 @@ function agentSchemaError(value, path) {
|
|
|
5767
5816
|
return agentInvalid(path, `must be a table (a JSON Schema object); found ${found}. Write it as ` +
|
|
5768
5817
|
"TOML tables, or as an object inside a block written as one JSON string");
|
|
5769
5818
|
}
|
|
5770
|
-
function agentIntegerInRange(value, path, max, out) {
|
|
5819
|
+
function agentIntegerInRange(value, path, max, out, min = 1) {
|
|
5771
5820
|
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
5772
|
-
out.push(agentInvalid(path, `must be an integer from
|
|
5821
|
+
out.push(agentInvalid(path, `must be an integer from ${min} to ${max}`));
|
|
5773
5822
|
return;
|
|
5774
5823
|
}
|
|
5775
|
-
if (value <
|
|
5776
|
-
out.push(agentInvalid(path, `must be from
|
|
5824
|
+
if (value < min || value > max) {
|
|
5825
|
+
out.push(agentInvalid(path, `must be from ${min} to ${max} (the platform maximum); found ${value}`));
|
|
5777
5826
|
}
|
|
5778
5827
|
}
|
|
5779
5828
|
function checkAgentName(value, path, seen, what, out) {
|
|
@@ -5893,6 +5942,9 @@ function agentShapeRefusals(agent) {
|
|
|
5893
5942
|
if (agent.waitLimitSeconds !== undefined) {
|
|
5894
5943
|
agentIntegerInRange(agent.waitLimitSeconds, "waitLimitSeconds", AGENT_LIMITS.waitLimitSeconds, out);
|
|
5895
5944
|
}
|
|
5945
|
+
if (agent.maxRowBytes !== undefined) {
|
|
5946
|
+
agentIntegerInRange(agent.maxRowBytes, "maxRowBytes", AGENT_LIMITS.maxRowBytes, out, AGENT_ROW_BYTES_FLOOR);
|
|
5947
|
+
}
|
|
5896
5948
|
if (agent.turnContext !== undefined) {
|
|
5897
5949
|
const turnContext = agent.turnContext;
|
|
5898
5950
|
if (!agentIsPlainObject(turnContext)) {
|
|
@@ -6125,6 +6177,7 @@ export function normalizeAgentDeclaration(declaration) {
|
|
|
6125
6177
|
answeredBy: source.answeredBy ?? "initiator",
|
|
6126
6178
|
maxSteps: source.maxSteps ?? AGENT_LIMITS.maxSteps,
|
|
6127
6179
|
waitLimitSeconds: source.waitLimitSeconds ?? AGENT_LIMITS.waitLimitSeconds,
|
|
6180
|
+
maxRowBytes: source.maxRowBytes ?? AGENT_LIMITS.maxRowBytes,
|
|
6128
6181
|
turnContext: source.turnContext ?? null,
|
|
6129
6182
|
history: source.history ?? null,
|
|
6130
6183
|
tools: (source.tools ?? []).map((tool) => ({
|
|
@@ -6869,28 +6922,6 @@ const PROMPT_HANDLER = "src/admin-api.ts";
|
|
|
6869
6922
|
* and output keys (`AGENT_CONFIG_KEYS`).
|
|
6870
6923
|
*/
|
|
6871
6924
|
const SHARED_WITH_AGENT = ["chat", "agent"];
|
|
6872
|
-
/**
|
|
6873
|
-
* #3626 §4 — the nine chat keys, still accepted FLAT under `[[configs]]`.
|
|
6874
|
-
*
|
|
6875
|
-
* The blob-bucket `accessPolicy` precedent: declared `deprecated`, so
|
|
6876
|
-
* `config push` keeps taking a file written before the `[configs.chat]` block
|
|
6877
|
-
* existed, while `config pull` never writes the spelling again. One
|
|
6878
|
-
* pull-then-push migrates a file. `hoistDeprecatedChatKeys` moves them into the
|
|
6879
|
-
* group before the payload is built; rejecting the flat spelling outright is
|
|
6880
|
-
* #3642. #3801 — only the nine: a chat key added later (`strictOutput`) was
|
|
6881
|
-
* never written flat, so it has no deprecated spelling to accept.
|
|
6882
|
-
*/
|
|
6883
|
-
const DEPRECATED_FLAT_CHAT_KEYS = Object.fromEntries(LEGACY_FLAT_CHAT_KEYS.map((key) => [
|
|
6884
|
-
key,
|
|
6885
|
-
{
|
|
6886
|
-
kind: "deprecated",
|
|
6887
|
-
note: `#3626 — the pre-kind spelling of \`[configs.chat].${key}\`. Still ` +
|
|
6888
|
-
"accepted flat so no existing prompt file breaks (push hoists it " +
|
|
6889
|
-
"into the block and warns); `config pull` writes only the grouped " +
|
|
6890
|
-
"spelling, so one pull-then-push migrates the file. Rejecting the " +
|
|
6891
|
-
"flat spelling is #3642.",
|
|
6892
|
-
},
|
|
6893
|
-
]));
|
|
6894
6925
|
export const PROMPT_SURFACE = {
|
|
6895
6926
|
label: "prompt",
|
|
6896
6927
|
tables: [
|
|
@@ -7100,7 +7131,7 @@ export const PROMPT_SURFACE = {
|
|
|
7100
7131
|
note: "#3626 — the chat-completion settings of a `kind = \"chat\"` " +
|
|
7101
7132
|
"prompt: the nine keys that describe a chat call and nothing " +
|
|
7102
7133
|
"else. Authored under `[configs.chat]`; the flat spelling is " +
|
|
7103
|
-
"
|
|
7134
|
+
"retired (#3642) and refused at push with `RETIRED_TOML_SPELLINGS`.",
|
|
7104
7135
|
},
|
|
7105
7136
|
decisions: {
|
|
7106
7137
|
note: "#3626 — the settings of a `kind = \"decisions\"` prompt: the " +
|
|
@@ -7385,8 +7416,6 @@ export const PROMPT_SURFACE = {
|
|
|
7385
7416
|
"active entry; push enacts it through the activate endpoint " +
|
|
7386
7417
|
"(activatePromptConfig), never as a config-body key.",
|
|
7387
7418
|
},
|
|
7388
|
-
// #3626 §4 — the nine chat keys in their pre-kind FLAT spelling.
|
|
7389
|
-
...DEPRECATED_FLAT_CHAT_KEYS,
|
|
7390
7419
|
},
|
|
7391
7420
|
responseOnlyKeys: {},
|
|
7392
7421
|
},
|
|
@@ -8213,9 +8242,12 @@ export const CRON_TRIGGER_SURFACE = {
|
|
|
8213
8242
|
* `blob-buckets/<key>.toml` carries a single `[bucket]` table.
|
|
8214
8243
|
*
|
|
8215
8244
|
* `ttlTier` is `writableOn: ["create"]`: the update handler does not read it, so
|
|
8216
|
-
* the retention tier is fixed at creation. `preset` and
|
|
8217
|
-
* halves of the access model (#1020)
|
|
8218
|
-
* is the controller's rule and stays there.
|
|
8245
|
+
* the retention tier is fixed at creation. `preset` and the rule set are the two
|
|
8246
|
+
* halves of the access model (#1020), and the only access keys: at most one may
|
|
8247
|
+
* change per request, which is the controller's rule and stays there. The rule
|
|
8248
|
+
* set is authored by name (`ruleSetName`) and sent as `ruleSetId`, as the type
|
|
8249
|
+
* configs do (#4116); the id spelling in TOML is deprecated. The pre-#1020
|
|
8250
|
+
* `accessPolicy` spelling is a retired key (#3996, `retired-keys.ts`).
|
|
8219
8251
|
*/
|
|
8220
8252
|
const BLOB_BUCKET_HANDLER = "src/app-api/controllers/blob-buckets-controller.ts";
|
|
8221
8253
|
export const BLOB_BUCKET_SURFACE = {
|
|
@@ -8264,12 +8296,14 @@ export const BLOB_BUCKET_SURFACE = {
|
|
|
8264
8296
|
},
|
|
8265
8297
|
{
|
|
8266
8298
|
field: "ruleSetId",
|
|
8267
|
-
tomlKey: "
|
|
8299
|
+
tomlKey: "ruleSetName",
|
|
8268
8300
|
type: "string",
|
|
8269
8301
|
emit: "whenSet",
|
|
8270
8302
|
writableOn: BOTH,
|
|
8271
|
-
//
|
|
8272
|
-
//
|
|
8303
|
+
// Authored as a name, sent as an id (#4116), so a tree copied into
|
|
8304
|
+
// another app binds that app's rule set. Existence-checked against
|
|
8305
|
+
// AccessRuleSet; mutually exclusive with a preset change in the same
|
|
8306
|
+
// request.
|
|
8273
8307
|
validation: handledBy(BLOB_BUCKET_HANDLER, "BlobBucketsController", "apply"),
|
|
8274
8308
|
},
|
|
8275
8309
|
],
|
|
@@ -8294,11 +8328,11 @@ export const BLOB_BUCKET_SURFACE = {
|
|
|
8294
8328
|
"TOML spelling is declared in tomlOnlyKeys as `key`.",
|
|
8295
8329
|
},
|
|
8296
8330
|
accessPolicy: {
|
|
8297
|
-
kind: "
|
|
8298
|
-
note: "
|
|
8299
|
-
"
|
|
8300
|
-
"
|
|
8301
|
-
"
|
|
8331
|
+
kind: "server-owned",
|
|
8332
|
+
note: "RETIRED from the write surface by #3996, superseded by `preset` " +
|
|
8333
|
+
"(#1020). The attribute stays declared so `resolveBucketPreset` " +
|
|
8334
|
+
"can read a pre-#1020 row; no write path accepts it and no " +
|
|
8335
|
+
"serializer emits it.",
|
|
8302
8336
|
},
|
|
8303
8337
|
createdBy: {
|
|
8304
8338
|
kind: "server-owned",
|
|
@@ -8319,11 +8353,13 @@ export const BLOB_BUCKET_SURFACE = {
|
|
|
8319
8353
|
note: "The bucket key. `config pull` writes it for readability; push takes " +
|
|
8320
8354
|
"the identity from the file name and attaches `bucketKey` itself.",
|
|
8321
8355
|
},
|
|
8322
|
-
|
|
8356
|
+
ruleSetId: {
|
|
8323
8357
|
kind: "deprecated",
|
|
8324
|
-
note: "
|
|
8325
|
-
"
|
|
8326
|
-
"
|
|
8358
|
+
note: "The id spelling of the rule-set reference (#4116). An id names a " +
|
|
8359
|
+
"rule set in one app, so a copied tree cannot resolve it; " +
|
|
8360
|
+
"`ruleSetName` is the authored key. Still accepted on push, with " +
|
|
8361
|
+
"an advisory line, and `config pull` rewrites the file to " +
|
|
8362
|
+
"`ruleSetName`. Retiring it is a later change of its own.",
|
|
8327
8363
|
},
|
|
8328
8364
|
},
|
|
8329
8365
|
responseOnlyKeys: {},
|
|
@@ -9552,11 +9588,13 @@ export const SERVER_FUNCTION_SURFACE = {
|
|
|
9552
9588
|
* which is exactly why the spec names them explicitly: nothing that syncs sits
|
|
9553
9589
|
* outside the registry.
|
|
9554
9590
|
*
|
|
9555
|
-
* Three fields are stored as ids and AUTHORED as
|
|
9591
|
+
* Three fields are stored as ids and AUTHORED as names — `configId` /
|
|
9556
9592
|
* `evaluatorPromptId` / `evaluatorConfigId` become `configName` /
|
|
9557
9593
|
* `evaluatorPromptKey` / `evaluatorConfigName` — so a test file is portable
|
|
9558
|
-
* across apps. The
|
|
9559
|
-
*
|
|
9594
|
+
* across apps. The id spellings are retired from the TOML surface (#3998):
|
|
9595
|
+
* `config push` refuses a sidecar that still carries one, with the guidance in
|
|
9596
|
+
* `retired-keys.ts`, and `config pull` reports a reference it cannot resolve
|
|
9597
|
+
* rather than writing an id. On the wire the three stay ids.
|
|
9560
9598
|
*
|
|
9561
9599
|
* Three more are stored as JSON strings and carried in TOML as JSON strings
|
|
9562
9600
|
* (`inputVariables`, `expectedOutputContains`, `expectedJsonSubset`) while the
|
|
@@ -9733,23 +9771,7 @@ export const TEST_CASE_SURFACE = {
|
|
|
9733
9771
|
note: "Timestamp, assigned server-side.",
|
|
9734
9772
|
},
|
|
9735
9773
|
},
|
|
9736
|
-
tomlOnlyKeys: {
|
|
9737
|
-
configId: {
|
|
9738
|
-
kind: "deprecated",
|
|
9739
|
-
note: "The legacy id-based config reference. Still accepted on push so " +
|
|
9740
|
-
"an unmigrated file pushes unchanged; pull writes `configName`.",
|
|
9741
|
-
},
|
|
9742
|
-
evaluatorPromptId: {
|
|
9743
|
-
kind: "deprecated",
|
|
9744
|
-
note: "The legacy id-based evaluator-prompt reference; pull writes " +
|
|
9745
|
-
"`evaluatorPromptKey`.",
|
|
9746
|
-
},
|
|
9747
|
-
evaluatorConfigId: {
|
|
9748
|
-
kind: "deprecated",
|
|
9749
|
-
note: "The legacy id-based evaluator-config reference; pull writes " +
|
|
9750
|
-
"`evaluatorConfigName`.",
|
|
9751
|
-
},
|
|
9752
|
-
},
|
|
9774
|
+
tomlOnlyKeys: {},
|
|
9753
9775
|
responseOnlyKeys: {},
|
|
9754
9776
|
},
|
|
9755
9777
|
],
|
|
@@ -9877,6 +9899,33 @@ export const APP_SETTINGS_SURFACE = {
|
|
|
9877
9899
|
// offline work around it (`parseLargeDocumentWindowSetting`).
|
|
9878
9900
|
validation: handledBy(SETTINGS_HANDLER, "SettingsController", "apply"),
|
|
9879
9901
|
},
|
|
9902
|
+
{
|
|
9903
|
+
field: "rootDocumentFormat",
|
|
9904
|
+
tomlKey: "rootDocumentFormat",
|
|
9905
|
+
type: "number",
|
|
9906
|
+
// Whenever the app chose one. An app that never did mints legacy
|
|
9907
|
+
// roots, and a pulled file should not grow a key for it (#4195).
|
|
9908
|
+
emit: "whenSet",
|
|
9909
|
+
writableOn: UPDATE_ONLY,
|
|
9910
|
+
// 1, 2 or cleared; anything else is refused, because a root's format
|
|
9911
|
+
// is permanent and the mint must never guess
|
|
9912
|
+
// (`parseRootDocumentFormatSetting`).
|
|
9913
|
+
validation: handledBy(SETTINGS_HANDLER, "SettingsController", "apply"),
|
|
9914
|
+
},
|
|
9915
|
+
{
|
|
9916
|
+
field: "protected",
|
|
9917
|
+
tomlKey: "protected",
|
|
9918
|
+
type: "boolean",
|
|
9919
|
+
// Always: a pulled file states whether the app is live with real
|
|
9920
|
+
// users, rather than leaving it to the absence of a key (#3886).
|
|
9921
|
+
emit: "always",
|
|
9922
|
+
writableOn: UPDATE_ONLY,
|
|
9923
|
+
// Strict boolean, and only the app's console owner or a super-admin
|
|
9924
|
+
// may CHANGE it; a body carrying the stored value is a no-op for
|
|
9925
|
+
// anyone the route admits (`resolveProtectedFlagWrite`,
|
|
9926
|
+
// `src/services/protected-app.ts`).
|
|
9927
|
+
validation: handledBy(SETTINGS_HANDLER, "SettingsController", "apply"),
|
|
9928
|
+
},
|
|
9880
9929
|
],
|
|
9881
9930
|
notExposed: {
|
|
9882
9931
|
appId: {
|
|
@@ -9891,6 +9940,58 @@ export const APP_SETTINGS_SURFACE = {
|
|
|
9891
9940
|
kind: "server-owned",
|
|
9892
9941
|
note: "Admin who created the app; assigned server-side.",
|
|
9893
9942
|
},
|
|
9943
|
+
// Child apps: lineage is set when a child is created and never
|
|
9944
|
+
// changes; expiry and activity are written by the server. The admin
|
|
9945
|
+
// update route refuses a changed value of any of these.
|
|
9946
|
+
parentAppId: {
|
|
9947
|
+
kind: "server-owned",
|
|
9948
|
+
note: "A child's parent app; set at creation, never authored.",
|
|
9949
|
+
},
|
|
9950
|
+
childSlug: {
|
|
9951
|
+
kind: "server-owned",
|
|
9952
|
+
note: "A child's slug under its parent; set at creation, never authored.",
|
|
9953
|
+
},
|
|
9954
|
+
parentSlugKey: {
|
|
9955
|
+
kind: "server-owned",
|
|
9956
|
+
note: "The `<parentAppId>#<slug>` uniqueness key of a child.",
|
|
9957
|
+
},
|
|
9958
|
+
ownerAdminId: {
|
|
9959
|
+
kind: "server-owned",
|
|
9960
|
+
note: "The admin who owns a child; the creator, set at creation.",
|
|
9961
|
+
},
|
|
9962
|
+
branch: {
|
|
9963
|
+
kind: "server-owned",
|
|
9964
|
+
note: "The git branch a child was created from; set at creation.",
|
|
9965
|
+
},
|
|
9966
|
+
idleDays: {
|
|
9967
|
+
kind: "server-owned",
|
|
9968
|
+
note: "Days of inactivity before a child expires; set at creation.",
|
|
9969
|
+
},
|
|
9970
|
+
expiresAt: {
|
|
9971
|
+
kind: "server-owned",
|
|
9972
|
+
note: "When a child expires; maintained by the server.",
|
|
9973
|
+
},
|
|
9974
|
+
warnedForExpiresAt: {
|
|
9975
|
+
kind: "server-owned",
|
|
9976
|
+
note: "The expiry a child's owner was last warned about.",
|
|
9977
|
+
},
|
|
9978
|
+
deletingAt: {
|
|
9979
|
+
kind: "server-owned",
|
|
9980
|
+
note: "When the expiry sweep claimed a child for deletion.",
|
|
9981
|
+
},
|
|
9982
|
+
previewOrigins: {
|
|
9983
|
+
kind: "server-owned",
|
|
9984
|
+
note: "A child's preview origins; written only by the preview-origins " +
|
|
9985
|
+
"route, so sync never sees it.",
|
|
9986
|
+
},
|
|
9987
|
+
childPartition: {
|
|
9988
|
+
kind: "server-owned",
|
|
9989
|
+
note: "The constant partition of the child-only expiry index.",
|
|
9990
|
+
},
|
|
9991
|
+
lastActivityAt: {
|
|
9992
|
+
kind: "server-owned",
|
|
9993
|
+
note: "When the app last saw counted activity; written by the server.",
|
|
9994
|
+
},
|
|
9894
9995
|
passkeyRpId: {
|
|
9895
9996
|
kind: "server-owned",
|
|
9896
9997
|
note: "RETIRED from the write surface by #2891, superseded by " +
|
|
@@ -9924,15 +10025,17 @@ export const APP_SETTINGS_SURFACE = {
|
|
|
9924
10025
|
note: "RETIRED from the write surface by #2884, superseded by " +
|
|
9925
10026
|
"`emailSignInEnabled`. Email sign-in is ONE flow — one request, " +
|
|
9926
10027
|
"one email carrying a code and (when a link can be issued) a " +
|
|
9927
|
-
"link — so there is no method to enable separately.
|
|
9928
|
-
"
|
|
9929
|
-
"
|
|
9930
|
-
"
|
|
10028
|
+
"link — so there is no method to enable separately. Hidden " +
|
|
10029
|
+
"since #3993: never written, never echoed, refused on write; " +
|
|
10030
|
+
"read only by the email sign-in fallback for a row that stores " +
|
|
10031
|
+
"no `emailSignInEnabled`.",
|
|
9931
10032
|
},
|
|
9932
10033
|
otpEnabled: {
|
|
9933
10034
|
kind: "server-owned",
|
|
9934
10035
|
note: "The other half of the retired pair (#2884); superseded by " +
|
|
9935
|
-
"`emailSignInEnabled
|
|
10036
|
+
"`emailSignInEnabled`. Hidden since #3993 the same way: never " +
|
|
10037
|
+
"written, never echoed, refused on write; read only by the " +
|
|
10038
|
+
"email sign-in fallback.",
|
|
9936
10039
|
},
|
|
9937
10040
|
redirectUris: {
|
|
9938
10041
|
kind: "server-owned",
|
|
@@ -10314,6 +10417,20 @@ export const GENERATED_CONFIG_MODEL_FIELDS = {
|
|
|
10314
10417
|
"memberInvitationsEnabled",
|
|
10315
10418
|
"memberInvitationLimit",
|
|
10316
10419
|
"largeDocumentWindowDays",
|
|
10420
|
+
"rootDocumentFormat",
|
|
10421
|
+
"protected",
|
|
10422
|
+
"parentAppId",
|
|
10423
|
+
"childSlug",
|
|
10424
|
+
"parentSlugKey",
|
|
10425
|
+
"ownerAdminId",
|
|
10426
|
+
"branch",
|
|
10427
|
+
"idleDays",
|
|
10428
|
+
"expiresAt",
|
|
10429
|
+
"warnedForExpiresAt",
|
|
10430
|
+
"deletingAt",
|
|
10431
|
+
"previewOrigins",
|
|
10432
|
+
"childPartition",
|
|
10433
|
+
"lastActivityAt",
|
|
10317
10434
|
"createdAt",
|
|
10318
10435
|
"modifiedAt",
|
|
10319
10436
|
],
|