primitive-admin 1.1.0-alpha.85 → 1.1.0-alpha.86

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.
Files changed (73) hide show
  1. package/README.md +34 -0
  2. package/assets/skill/skills/primitive-platform/SKILL.md +8 -0
  3. package/dist/src/commands/analytics.js +13 -1
  4. package/dist/src/commands/analytics.js.map +1 -1
  5. package/dist/src/commands/collections.js +648 -1
  6. package/dist/src/commands/collections.js.map +1 -1
  7. package/dist/src/commands/database-type-configs.js +1 -1
  8. package/dist/src/commands/database-type-configs.js.map +1 -1
  9. package/dist/src/commands/databases.js +11 -2
  10. package/dist/src/commands/databases.js.map +1 -1
  11. package/dist/src/commands/documents.d.ts +20 -0
  12. package/dist/src/commands/documents.js +213 -17
  13. package/dist/src/commands/documents.js.map +1 -1
  14. package/dist/src/commands/functions.js +56 -5
  15. package/dist/src/commands/functions.js.map +1 -1
  16. package/dist/src/commands/integrations.js +4 -0
  17. package/dist/src/commands/integrations.js.map +1 -1
  18. package/dist/src/commands/sync.d.ts +73 -41
  19. package/dist/src/commands/sync.js +527 -80
  20. package/dist/src/commands/sync.js.map +1 -1
  21. package/dist/src/commands/users.js +3 -1
  22. package/dist/src/commands/users.js.map +1 -1
  23. package/dist/src/lib/api-client.d.ts +93 -7
  24. package/dist/src/lib/api-client.js +72 -19
  25. package/dist/src/lib/api-client.js.map +1 -1
  26. package/dist/src/lib/collection-export.d.ts +184 -0
  27. package/dist/src/lib/collection-export.js +252 -0
  28. package/dist/src/lib/collection-export.js.map +1 -0
  29. package/dist/src/lib/config-object-descriptor.js +17 -3
  30. package/dist/src/lib/config-object-descriptor.js.map +1 -1
  31. package/dist/src/lib/config-payload.d.ts +8 -1
  32. package/dist/src/lib/config-payload.js +29 -9
  33. package/dist/src/lib/config-payload.js.map +1 -1
  34. package/dist/src/lib/config-surface.js +11 -7
  35. package/dist/src/lib/config-surface.js.map +1 -1
  36. package/dist/src/lib/deprecation.d.ts +22 -0
  37. package/dist/src/lib/deprecation.js +43 -0
  38. package/dist/src/lib/deprecation.js.map +1 -0
  39. package/dist/src/lib/function-db-types.d.ts +14 -3
  40. package/dist/src/lib/function-db-types.js +55 -11
  41. package/dist/src/lib/function-db-types.js.map +1 -1
  42. package/dist/src/lib/function-trigger-listing.d.ts +27 -0
  43. package/dist/src/lib/function-trigger-listing.js +70 -0
  44. package/dist/src/lib/function-trigger-listing.js.map +1 -0
  45. package/dist/src/lib/generated-config-surfaces.d.ts +540 -10
  46. package/dist/src/lib/generated-config-surfaces.js +1914 -155
  47. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  48. package/dist/src/lib/generated-sdk-types.d.ts +1 -1
  49. package/dist/src/lib/generated-sdk-types.js +1 -1
  50. package/dist/src/lib/generated-sdk-types.js.map +1 -1
  51. package/dist/src/lib/log-inspection.d.ts +18 -1
  52. package/dist/src/lib/log-inspection.js +5 -0
  53. package/dist/src/lib/log-inspection.js.map +1 -1
  54. package/dist/src/lib/prompt-cost-format.d.ts +11 -0
  55. package/dist/src/lib/prompt-cost-format.js +41 -0
  56. package/dist/src/lib/prompt-cost-format.js.map +1 -0
  57. package/dist/src/lib/prompt-schema-codegen.d.ts +53 -0
  58. package/dist/src/lib/prompt-schema-codegen.js +253 -3
  59. package/dist/src/lib/prompt-schema-codegen.js.map +1 -1
  60. package/dist/src/lib/swift-codegen/agentGenerator.d.ts +42 -0
  61. package/dist/src/lib/swift-codegen/agentGenerator.js +118 -0
  62. package/dist/src/lib/swift-codegen/agentGenerator.js.map +1 -0
  63. package/dist/src/lib/swift-codegen/banners.d.ts +6 -0
  64. package/dist/src/lib/swift-codegen/banners.js +6 -0
  65. package/dist/src/lib/swift-codegen/banners.js.map +1 -1
  66. package/dist/src/lib/swift-codegen/dbGenerator.js +11 -3
  67. package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
  68. package/dist/src/lib/swift-codegen/functionGenerator.d.ts +7 -0
  69. package/dist/src/lib/swift-codegen/functionGenerator.js +41 -3
  70. package/dist/src/lib/swift-codegen/functionGenerator.js.map +1 -1
  71. package/dist/src/lib/swift-codegen/generator.js +8 -2
  72. package/dist/src/lib/swift-codegen/generator.js.map +1 -1
  73. package/package.json +2 -2
@@ -106,8 +106,14 @@ export interface ConfigField {
106
106
  *
107
107
  * The group must be declared in the table's `tomlGroups`
108
108
  * (`findBadTomlGroupDeclarations`).
109
+ *
110
+ * #3798 — a LIST names a key authored under more than one block: the six
111
+ * model settings an agent shares with chat are `["chat", "agent"]`. Push
112
+ * reads the key from whichever of its blocks the entry carries, and pull
113
+ * writes it under the block the caller names (the prompt's kind), the first
114
+ * one otherwise. Read it through `tomlGroupsOf`, never directly.
109
115
  */
110
- tomlGroup?: string;
116
+ tomlGroup?: string | readonly string[];
111
117
  type: FieldType;
112
118
  /** "whenSet" omits the key on pull when the value is empty; see #1033's `emit`. */
113
119
  emit: "always" | "whenSet";
@@ -164,6 +170,17 @@ export interface ConfigField {
164
170
  dualEncoded?: {
165
171
  note: string;
166
172
  };
173
+ /**
174
+ * The field is still accepted but deprecated, and `note` says what to use
175
+ * instead (#1815). Unlike `NotExposed`'s `deprecated` kind, the field stays
176
+ * on the TOML surface: it round-trips on pull and push exactly as before.
177
+ * The generated request schema marks the key `deprecated: true` in the
178
+ * published OpenAPI spec. `config push` does not read this note; any push
179
+ * warning for the field lives in the CLI's push preflight.
180
+ */
181
+ deprecated?: {
182
+ note: string;
183
+ };
167
184
  /**
168
185
  * The value the SERVER materializes when a create omits this key (#2880
169
186
  * DSO-002).
@@ -594,6 +611,12 @@ export declare function findUnclassifiedSecretishFields(table: ConfigTable, mode
594
611
  * when the module or the export is missing (#2644 behavior 2b).
595
612
  */
596
613
  export declare function handlerReferences(table: ConfigTable): string[];
614
+ /**
615
+ * The blocks a field is authored under, in declaration order: `[]` for a root
616
+ * key, one name for most grouped keys, several for a key two blocks share
617
+ * (#3798). Every reader of `tomlGroup` goes through this.
618
+ */
619
+ export declare function tomlGroupsOf(field: ConfigField): readonly string[];
597
620
  /** The group names this table declares, sorted. Empty for an ungrouped table. */
598
621
  export declare function tomlGroupNames(table: ConfigTable): string[];
599
622
  /** The TOML keys accepted INSIDE `group`: every field that declares it. */
@@ -955,8 +978,8 @@ export declare function findUnreachedPreflightRules(surface: ConfigObjectSurface
955
978
  * unrecognized TOML keys locally (criterion 6).
956
979
  *
957
980
  * ── What the schema says, and what it deliberately does not ──────────────
958
- * It states the KEY SET only: each property is the empty schema, so no value is
959
- * type-checked here. That is the decision of record (#1976, carried forward at
981
+ * It states the KEY SET only: each property is the empty schema (or carries
982
+ * only the `deprecated` annotation, #1815), so no value is type-checked here. That is the decision of record (#1976, carried forward at
960
983
  * #2644's design gate): the definition classifies, handlers behave. The
961
984
  * `status` enum, the queue limits' integer coercion, `runAs`'s caller|system
962
985
  * check, the CEL parse of `accessRule` — all stay in the handlers the
@@ -991,7 +1014,15 @@ export declare function findUnreachedPreflightRules(surface: ConfigObjectSurface
991
1014
  */
992
1015
  export interface ConfigRequestSchema {
993
1016
  type: "object";
994
- properties: Record<string, Record<string, never>>;
1017
+ /**
1018
+ * Each property is the empty schema, or `{ deprecated: true }` for a field
1019
+ * the definition marks `deprecated` (#1815). `deprecated` is an OpenAPI
1020
+ * annotation: it constrains no value, so the schema still states the key set
1021
+ * and nothing more.
1022
+ */
1023
+ properties: Record<string, {
1024
+ deprecated?: true;
1025
+ }>;
995
1026
  additionalProperties: false;
996
1027
  /**
997
1028
  * Structural-typing escape hatch: the app API's `meta.request` slot is a
@@ -2169,7 +2200,7 @@ export declare function resolvePromptReasoning(input: PromptReasoningInput): Pro
2169
2200
  /**
2170
2201
  * What a prompt's KIND admits — issue #3626.
2171
2202
  *
2172
- * A prompt declares `[prompt] kind = "chat" | "decisions"`. The kind decides
2203
+ * A prompt declares `[prompt] kind = "chat" | "decisions" | "agent"`. The kind decides
2173
2204
  * the input envelope (`variables` rendered into templates for chat, a `state`
2174
2205
  * value for decisions), the provider endpoint the executor posts to, and which
2175
2206
  * `[configs.<kind>]` block a `[[configs]]` entry may carry. Adding a kind is a
@@ -2186,17 +2217,43 @@ export declare function resolvePromptReasoning(input: PromptReasoningInput): Pro
2186
2217
  *
2187
2218
  * Pure and dependency-free, like every module under `src/config-surface/`.
2188
2219
  */
2189
- /** The kinds a prompt may declare. An omitted `kind` is `chat`. */
2190
- export declare const PROMPT_KINDS: readonly ["chat", "decisions"];
2220
+ /**
2221
+ * The kinds a prompt may declare. An omitted `kind` is `chat`.
2222
+ *
2223
+ * #3798 — `agent` is a prompt run turn by turn in a session: no template, no
2224
+ * output schema, never run single-shot. Its tools and events are declared in
2225
+ * `[prompt.agent]` (`agent-declaration.ts`); its configs carry
2226
+ * `[configs.agent]`.
2227
+ */
2228
+ export declare const PROMPT_KINDS: readonly ["chat", "decisions", "agent"];
2191
2229
  export type PromptKind = (typeof PROMPT_KINDS)[number];
2192
2230
  /**
2193
- * The nine settings that describe a CHAT COMPLETION and nothing else. They are
2194
- * authored under `[configs.chat]`; the flat spelling is deprecated (#3642).
2231
+ * The nine chat settings that existed before `[configs.chat]` did. Only these
2232
+ * keep the deprecated FLAT spelling (#3642): a key added to the block later was
2233
+ * never written flat by any file, so it has none (the `questions` posture,
2234
+ * SO3626-013).
2235
+ */
2236
+ export declare const LEGACY_FLAT_CHAT_KEYS: readonly ["systemPrompt", "userPromptTemplate", "temperature", "topP", "maxTokens", "outputFormat", "outputSchema", "reasoningEffort", "reasoningBudget"];
2237
+ /**
2238
+ * The settings that describe a CHAT COMPLETION and nothing else. They are
2239
+ * authored under `[configs.chat]`; the flat spelling of the nine legacy keys
2240
+ * is deprecated (#3642).
2241
+ *
2242
+ * #3801 — `strictOutput`, the opt-in that sends `[prompt].outputSchema` as a
2243
+ * strict `json_schema` on OpenRouter (`prompt-strict-output.ts`). Not an agent
2244
+ * key (§D1: an agent has no output schema), so the agent arm refuses it.
2195
2245
  */
2196
- export declare const CHAT_CONFIG_KEYS: readonly ["systemPrompt", "userPromptTemplate", "temperature", "topP", "maxTokens", "outputFormat", "outputSchema", "reasoningEffort", "reasoningBudget"];
2246
+ export declare const CHAT_CONFIG_KEYS: readonly ["systemPrompt", "userPromptTemplate", "temperature", "topP", "maxTokens", "outputFormat", "outputSchema", "reasoningEffort", "reasoningBudget", "strictOutput"];
2197
2247
  export type ChatConfigKey = (typeof CHAT_CONFIG_KEYS)[number];
2198
2248
  /** The settings that describe a DECISIONS request. */
2199
2249
  export declare const DECISIONS_CONFIG_KEYS: readonly ["questions"];
2250
+ /**
2251
+ * #3798 — the settings of an AGENT's model round: the chat block less
2252
+ * `userPromptTemplate` (the model sees each message as sent), `outputFormat`
2253
+ * and `outputSchema` (an agent's final answer is text; anything structured is
2254
+ * a tool call). The same wire keys as chat, authored under `[configs.agent]`.
2255
+ */
2256
+ export declare const AGENT_CONFIG_KEYS: readonly ["systemPrompt", "temperature", "topP", "maxTokens", "reasoningEffort", "reasoningBudget"];
2200
2257
  /**
2201
2258
  * The WIRE field names each kind's block holds. The config surface declares the
2202
2259
  * same grouping through `ConfigField.tomlGroup`, and the drift guard asserts
@@ -2208,6 +2265,21 @@ export declare const PROMPT_KIND_BLOCKS: Readonly<Record<PromptKind, readonly st
2208
2265
  /** The question types TypeSafe's System One models answer. */
2209
2266
  export declare const DECISIONS_QUESTION_TYPES: readonly ["choice", "score", "noul"];
2210
2267
  export type DecisionsQuestionType = (typeof DECISIONS_QUESTION_TYPES)[number];
2268
+ /**
2269
+ * #3813 — where a `choice` question's options come from. `"static"`: the
2270
+ * config's `criteria` table. `"dynamic"`: each run supplies the table as
2271
+ * `variables.criteria.<question>`. Required on every `choice` question, with
2272
+ * no default, and a platform key: it is removed before the provider request.
2273
+ */
2274
+ export declare const DECISIONS_CRITERIA_SOURCES: readonly ["static", "dynamic"];
2275
+ export type DecisionsCriteriaSource = (typeof DECISIONS_CRITERIA_SOURCES)[number];
2276
+ /**
2277
+ * #3813 — the code a decisions run carries when the options it was asked to
2278
+ * choose between are refused before the provider call: malformed per-run
2279
+ * criteria, criteria for a question that does not take them, or a stored
2280
+ * `choice` question that does not say where its options come from.
2281
+ */
2282
+ export declare const PROMPT_CRITERIA_INVALID = "PROMPT_CRITERIA_INVALID";
2211
2283
  /**
2212
2284
  * The prompt's kind, normalized.
2213
2285
  *
@@ -2227,6 +2299,8 @@ export interface PromptKindConfigInput {
2227
2299
  outputSchema?: unknown;
2228
2300
  reasoningEffort?: unknown;
2229
2301
  reasoningBudget?: unknown;
2302
+ /** #3801 — a chat key; the agent and decisions arms refuse it. */
2303
+ strictOutput?: unknown;
2230
2304
  questions?: unknown;
2231
2305
  }
2232
2306
  export interface PromptKindInput {
@@ -2248,9 +2322,13 @@ export type PromptKindResolution = {
2248
2322
  ok: true;
2249
2323
  kind: "decisions";
2250
2324
  questions: Record<string, unknown>;
2325
+ } | {
2326
+ ok: true;
2327
+ kind: "agent";
2251
2328
  } | {
2252
2329
  ok: false;
2253
2330
  error: string;
2331
+ code?: string;
2254
2332
  };
2255
2333
  /**
2256
2334
  * The one rule: does this (kind, provider, config) triple describe something
@@ -2261,6 +2339,34 @@ export type PromptKindResolution = {
2261
2339
  * whichever transport the author used.
2262
2340
  */
2263
2341
  export declare function resolvePromptKind(input: PromptKindInput): PromptKindResolution;
2342
+ export type DecisionsRunQuestionsResolution = {
2343
+ ok: true;
2344
+ questions: Record<string, unknown>;
2345
+ } | {
2346
+ ok: false;
2347
+ error: string;
2348
+ };
2349
+ /**
2350
+ * #3813 — the questions one run sends to the provider.
2351
+ *
2352
+ * `questions` is the RAN config's declaration, as stored; `runCriteria` is
2353
+ * the run's `variables.criteria` (`undefined` when the run sent none). A
2354
+ * `"dynamic"` question is given the run's table as its `criteria`; every
2355
+ * question loses `criteriaSource`, which is the platform's key and not the
2356
+ * endpoint's. The config still owns each question's name, type and
2357
+ * instructions: a run can supply options only for a question declared
2358
+ * `"dynamic"`, so nothing a run sends can change what is being asked.
2359
+ *
2360
+ * Refuses, before any provider call: a `variables.criteria` that is not an
2361
+ * object; criteria for a name the config does not declare, for a `"static"`
2362
+ * question, or for a `score` or `noul` one; a `"dynamic"` question with no
2363
+ * table or a table the criteria rule refuses; and a stored `choice` question
2364
+ * with no usable `criteriaSource` — a config written before the key existed,
2365
+ * which is refused rather than given a silent default.
2366
+ *
2367
+ * Pure: the stored questions object is never mutated.
2368
+ */
2369
+ export declare function resolveDecisionsRunQuestions(questions: Record<string, unknown>, runCriteria: unknown): DecisionsRunQuestionsResolution;
2264
2370
  /** What the hoist did to one `[[configs]]` entry. */
2265
2371
  export interface DeprecatedChatKeyHoist {
2266
2372
  /** A COPY of the entry with the flat chat keys moved under `chat`. */
@@ -2283,6 +2389,430 @@ export interface DeprecatedChatKeyHoist {
2283
2389
  * spelling at all (SO3626-013).
2284
2390
  */
2285
2391
  export declare function hoistDeprecatedChatKeys(entry: unknown): DeprecatedChatKeyHoist;
2392
+ /**
2393
+ * Strict output for a chat config — issue #3801 (project `agents`, §D6).
2394
+ *
2395
+ * A chat prompt's OpenRouter request asks for JSON mode (`outputFormat =
2396
+ * "json"`) and the answer is checked AFTERWARDS against `[prompt].outputSchema`
2397
+ * (`derivePromptRunEnvelope`). A config that sets `[configs.chat].strictOutput
2398
+ * = true` asks the provider to constrain the answer instead: the prompt-level
2399
+ * schema is sent as `response_format: { type: "json_schema", json_schema: {
2400
+ * name: "output", strict: true, schema } }`, with `provider: {
2401
+ * require_parameters: true }` so OpenRouter refuses an endpoint that would
2402
+ * ignore it rather than dropping it in silence (the #3358 posture).
2403
+ *
2404
+ * This module is the whole rule, and it is read in both places a config is
2405
+ * written: the admin routes, and (vendored) the CLI's push preflight, so a
2406
+ * refusal at push and at the route cannot disagree — `resolvePromptReasoning`
2407
+ * and `resolvePromptKind`'s posture.
2408
+ *
2409
+ * Which schema is sent is never ambiguous: always the PROMPT's (§D6), so a
2410
+ * config that also declares its own `outputSchema` is refused. Five refusals,
2411
+ * in this order, each with its own code:
2412
+ *
2413
+ * - `PROMPT_STRICT_OUTPUT_INVALID` — the value is not a boolean.
2414
+ * - `PROMPT_STRICT_OUTPUT_SCHEMA_CONFLICT` — the config declares its own
2415
+ * `outputSchema` too.
2416
+ * - `PROMPT_STRICT_OUTPUT_PROVIDER_UNSUPPORTED` — not OpenRouter. A Gemini
2417
+ * config already constrains its request through `responseSchema`.
2418
+ * - `PROMPT_STRICT_OUTPUT_FORMAT_CONFLICT` — `outputFormat = "text"`.
2419
+ * - `PROMPT_STRICT_OUTPUT_SCHEMA_MISSING` — the prompt declares no usable
2420
+ * `[prompt].outputSchema`.
2421
+ *
2422
+ * The first four are about the config itself and apply whatever its status.
2423
+ * The last depends on PROMPT-level state that can change under a config, so it
2424
+ * is skipped for an ARCHIVED config (DSO-3801-002): a retired strict config may
2425
+ * be pulled, pushed and renamed after its prompt dropped the schema, and the
2426
+ * requirement is enforced when a config is or becomes active — the #3799
2427
+ * posture, "an archive is never checked".
2428
+ *
2429
+ * Pure and dependency-free, like every module under `src/config-surface/`.
2430
+ */
2431
+ /** Every code the rule answers, in the order it checks. */
2432
+ export declare const PROMPT_STRICT_OUTPUT_CODES: readonly ["PROMPT_STRICT_OUTPUT_INVALID", "PROMPT_STRICT_OUTPUT_SCHEMA_CONFLICT", "PROMPT_STRICT_OUTPUT_PROVIDER_UNSUPPORTED", "PROMPT_STRICT_OUTPUT_FORMAT_CONFLICT", "PROMPT_STRICT_OUTPUT_SCHEMA_MISSING"];
2433
+ export type PromptStrictOutputErrorCode = (typeof PROMPT_STRICT_OUTPUT_CODES)[number];
2434
+ /**
2435
+ * The one code a RUN can also carry: the executor refuses a strict config whose
2436
+ * stored prompt schema is absent or unusable before any provider call, rather
2437
+ * than downgrading the request to JSON mode.
2438
+ */
2439
+ export declare const PROMPT_STRICT_OUTPUT_SCHEMA_MISSING = "PROMPT_STRICT_OUTPUT_SCHEMA_MISSING";
2440
+ /**
2441
+ * `json_schema.name`. The OpenAI-shaped API requires one and the executor has
2442
+ * no prompt key to hand, so it is fixed — the same request for the same schema.
2443
+ */
2444
+ export declare const STRICT_OUTPUT_SCHEMA_NAME = "output";
2445
+ export interface PromptStrictOutputInput {
2446
+ provider?: unknown;
2447
+ /** `[configs.chat].strictOutput` as authored or stored. */
2448
+ strictOutput?: unknown;
2449
+ outputFormat?: unknown;
2450
+ /** The CONFIG's own `outputSchema` — the one strict output never sends. */
2451
+ configOutputSchema?: unknown;
2452
+ /** `[prompt].outputSchema` — the one it does. */
2453
+ promptOutputSchema?: unknown;
2454
+ /** The config's effective status; absent is `active`. */
2455
+ status?: unknown;
2456
+ }
2457
+ export type PromptStrictOutputResolution = {
2458
+ ok: true;
2459
+ strict: boolean;
2460
+ } | {
2461
+ ok: false;
2462
+ code: PromptStrictOutputErrorCode;
2463
+ error: string;
2464
+ };
2465
+ /** Does this config opt in? Only a literal `true` does. */
2466
+ export declare function isStrictOutput(value: unknown): boolean;
2467
+ /**
2468
+ * The schema strict output sends, from a stored or authored
2469
+ * `[prompt].outputSchema`: a JSON object (or its text), else `null`.
2470
+ */
2471
+ export declare function strictOutputSchemaOf(value: unknown): Record<string, unknown> | null;
2472
+ /**
2473
+ * Is this (provider, strictOutput, outputFormat, schemas, status) a config the
2474
+ * platform can run as strict — or not strict at all?
2475
+ */
2476
+ export declare function resolvePromptStrictOutput(input: PromptStrictOutputInput): PromptStrictOutputResolution;
2477
+ /**
2478
+ * What an agent prompt may declare — issue #3798 (project `agents`, §D1).
2479
+ *
2480
+ * An agent is a prompt of `kind = "agent"`. Its configs carry `[configs.agent]`
2481
+ * (the rule for those is `resolvePromptKind`); its contract lives in ONE
2482
+ * prompt-level block, `[prompt.agent]`: the tools the model may call, the event
2483
+ * kinds members record, the turn context, how history is selected, who answers
2484
+ * a paused call, and the limits an agent may lower but never raise.
2485
+ *
2486
+ * This module is the whole rule for that block. `resolveAgentDeclaration` is
2487
+ * called by the CLI's push preflight through the vendored artifact and by the
2488
+ * admin prompt routes, so a refusal at push and a refusal at the route cannot
2489
+ * disagree — the `resolvePromptKind` posture of #3626.
2490
+ *
2491
+ * STORED AS WRITTEN (DSO-3798-001). The resolver returns the AUTHORED value —
2492
+ * a block written as one JSON string is parsed to the object it encodes, and
2493
+ * nothing is added. `config diff` compares a `json` field by value with no
2494
+ * defaults applied, so a stored declaration with defaults filled in would read
2495
+ * Modified after every push, and `config pull` would write keys the author
2496
+ * never did. The defaults live in one reader instead, `normalizeAgentDeclaration`,
2497
+ * which every consumer (the executor, codegen, the turn engine) calls.
2498
+ *
2499
+ * Every refusal carries a stable code (intent criterion 22) and a refusal lists
2500
+ * EVERY offending item, so an author fixes a declaration in one pass.
2501
+ *
2502
+ * Pure and dependency-free, like every module under `src/config-surface/`.
2503
+ */
2504
+ /** The stable codes every agent agentRefusal this project adds carries. */
2505
+ export declare const AGENT_ERROR_CODES: readonly ["AGENT_DECLARATION_INVALID", "AGENT_TOOL_FUNCTION_MISSING", "AGENT_TOOL_FUNCTION_SCHEMA_MISSING", "AGENT_OUTPUT_SCHEMA_NOT_ALLOWED", "AGENT_CONFIG_KEY_NOT_ALLOWED", "AGENT_NOT_RUNNABLE", "AGENT_TEST_CASE_NOT_SUPPORTED", "AGENT_SCHEMA_NOT_TRANSLATABLE", "AGENT_MODEL_UNKNOWN", "AGENT_MODEL_CAPABILITY_MISSING", "AGENT_MODEL_CAPABILITIES_UNAVAILABLE", "AGENT_ROUND_NOT_AGENT", "AGENT_ROUND_INPUT_INVALID", "AGENT_TOOL_UNKNOWN", "AGENT_TOOL_ARGUMENTS_INVALID", "AGENT_ROUND_TRUNCATED", "AGENT_ROUND_EMPTY"];
2506
+ export type AgentErrorCode = (typeof AGENT_ERROR_CODES)[number];
2507
+ /** One agentRefusal: the code a client branches on, and the sentence a person reads. */
2508
+ export interface AgentRefusal {
2509
+ code: AgentErrorCode;
2510
+ message: string;
2511
+ }
2512
+ /**
2513
+ * The platform maximums. An agent may lower `maxSteps` and `waitLimitSeconds`,
2514
+ * never raise them; the tool and event counts bound what one declaration can
2515
+ * make every turn carry (principle 2).
2516
+ */
2517
+ export declare const AGENT_LIMITS: {
2518
+ readonly maxSteps: 25;
2519
+ readonly waitLimitSeconds: 604800;
2520
+ readonly tools: 64;
2521
+ readonly events: 64;
2522
+ };
2523
+ /**
2524
+ * A tool or event name: the intersection of OpenRouter's and Gemini's
2525
+ * function-name rules, so one declaration maps onto either provider.
2526
+ */
2527
+ export declare const AGENT_NAME: RegExp;
2528
+ export declare const AGENT_ANSWERED_BY: readonly ["initiator", "participants"];
2529
+ export declare const AGENT_TOOL_INVOKE: readonly ["request", "task"];
2530
+ export declare const AGENT_TOOL_HISTORY_SCOPES: readonly ["session", "turn"];
2531
+ export type AgentAnsweredBy = (typeof AGENT_ANSWERED_BY)[number];
2532
+ export type AgentToolInvoke = (typeof AGENT_TOOL_INVOKE)[number];
2533
+ export type AgentToolHistoryScope = (typeof AGENT_TOOL_HISTORY_SCOPES)[number];
2534
+ /** A JSON Schema object, as the declaration holds one. */
2535
+ export type AgentSchema = Record<string, unknown>;
2536
+ /** One `[[prompt.agent.tools]]` entry, as authored. */
2537
+ export interface AgentToolDeclaration {
2538
+ name: string;
2539
+ description: string;
2540
+ /** A server tool: the function whose schemas are the tool's. */
2541
+ function?: string;
2542
+ invoke?: AgentToolInvoke;
2543
+ /** A client tool: answered by a member's client, schemas in the TOML. */
2544
+ runs?: "client";
2545
+ inputSchema?: AgentSchema;
2546
+ outputSchema?: AgentSchema;
2547
+ approval?: boolean;
2548
+ statusText?: string;
2549
+ historyScope?: AgentToolHistoryScope;
2550
+ }
2551
+ /** One `[[prompt.agent.events]]` entry. */
2552
+ export interface AgentEventDeclaration {
2553
+ name: string;
2554
+ schema: AgentSchema;
2555
+ }
2556
+ /** `[prompt.agent]` as authored: every key optional. */
2557
+ export interface AgentDeclaration {
2558
+ answeredBy?: AgentAnsweredBy;
2559
+ maxSteps?: number;
2560
+ waitLimitSeconds?: number;
2561
+ turnContext?: {
2562
+ schema: AgentSchema;
2563
+ function?: string;
2564
+ };
2565
+ history?: {
2566
+ function?: string;
2567
+ maxHistoryChars?: number;
2568
+ };
2569
+ tools?: AgentToolDeclaration[];
2570
+ events?: AgentEventDeclaration[];
2571
+ }
2572
+ /** A tool with its defaults applied. */
2573
+ export type NormalizedAgentTool = AgentToolDeclaration & {
2574
+ approval: boolean;
2575
+ historyScope: AgentToolHistoryScope;
2576
+ };
2577
+ /** The declaration with every default applied — what readers consume. */
2578
+ export interface NormalizedAgentDeclaration {
2579
+ answeredBy: AgentAnsweredBy;
2580
+ maxSteps: number;
2581
+ waitLimitSeconds: number;
2582
+ turnContext: {
2583
+ schema: AgentSchema;
2584
+ function?: string;
2585
+ } | null;
2586
+ history: {
2587
+ function?: string;
2588
+ maxHistoryChars?: number;
2589
+ } | null;
2590
+ tools: NormalizedAgentTool[];
2591
+ events: AgentEventDeclaration[];
2592
+ }
2593
+ /**
2594
+ * What the caller knows about each function a declaration may name: `null` (or
2595
+ * absence from the map) is a function this app does not have. The CLI resolves
2596
+ * it from the live listing overlaid by the function files this push selects;
2597
+ * the admin routes from an app-scoped lookup.
2598
+ */
2599
+ export type AgentFunctionFacts = Readonly<Record<string, AgentFunctionFact | null>>;
2600
+ /**
2601
+ * What one function declares. `hasInputSchema`/`hasOutputSchema` are #3798's
2602
+ * presence facts; `inputSchema`/`outputSchema` are #3799's — the stored value,
2603
+ * a JSON string or an object, which `agentSchemaTranslationRefusals` translates
2604
+ * for each of the agent's providers. Both schema fields are OPTIONAL, so a
2605
+ * caller that only needs the presence half is unchanged (principle 5).
2606
+ */
2607
+ export interface AgentFunctionFact {
2608
+ hasInputSchema: boolean;
2609
+ hasOutputSchema: boolean;
2610
+ inputSchema?: unknown;
2611
+ outputSchema?: unknown;
2612
+ }
2613
+ export interface AgentDeclarationInput {
2614
+ /** `[prompt].kind`; unset means `chat`. */
2615
+ kind?: unknown;
2616
+ /** `[prompt.agent]`: a table, a JSON string encoding one, or unset. */
2617
+ agent?: unknown;
2618
+ /** `[prompt].outputSchema` — refused on an agent. */
2619
+ outputSchema?: unknown;
2620
+ /**
2621
+ * The function facts. Omitted means "not known here": the file-decidable
2622
+ * half runs alone (the CLI's `config diff` collector has no app state).
2623
+ */
2624
+ functions?: AgentFunctionFacts;
2625
+ }
2626
+ export type AgentDeclarationResolution = {
2627
+ ok: true;
2628
+ declaration: AgentDeclaration | null;
2629
+ } | {
2630
+ ok: false;
2631
+ refusals: AgentRefusal[];
2632
+ };
2633
+ /**
2634
+ * The same label, for the sibling rules that refuse a declaration from their
2635
+ * own module (#3799's `provider-schema.ts`), so every agent refusal points at
2636
+ * the block the author wrote.
2637
+ */
2638
+ export declare const AGENT_BLOCK_LABEL = "[prompt.agent]";
2639
+ /**
2640
+ * The function keys a declaration references (tools, turn context, history),
2641
+ * each once, in declaration order. What a caller resolves into the
2642
+ * `functions` facts before calling the resolver. `[]` for a block that is
2643
+ * absent or does not parse — the resolver refuses the latter itself.
2644
+ */
2645
+ /**
2646
+ * `[prompt.agent]` as a value: a table as it is, one JSON string parsed,
2647
+ * `undefined` for absence or for anything that is not a JSON object (which
2648
+ * `resolveAgentDeclaration` refuses on its own).
2649
+ *
2650
+ * Exported for the sibling rules that read the same block — #3799's
2651
+ * `agentSchemaTranslationRefusals` — so a declaration written as one JSON
2652
+ * string is read identically by every rule that consumes it.
2653
+ */
2654
+ export declare function parseAgentDeclarationBlock(agent: unknown): Record<string, unknown> | undefined;
2655
+ export declare function agentDeclarationFunctionKeys(agent: unknown): string[];
2656
+ /**
2657
+ * The one rule: is this `[prompt.agent]` declaration (with the prompt's kind
2658
+ * and `outputSchema`) something the platform can run?
2659
+ *
2660
+ * `{ ok: true, declaration }` carries the AUTHORED value — parsed when the
2661
+ * block was one JSON string, otherwise unchanged — or `null` for an absent
2662
+ * block. Callers store exactly this.
2663
+ */
2664
+ export declare function resolveAgentDeclaration(input: AgentDeclarationInput): AgentDeclarationResolution;
2665
+ /**
2666
+ * The refusal of a single-shot run of an agent — `ctx.prompts.run`, the member
2667
+ * execute route, the admin execute and preview routes, the workflow
2668
+ * `prompt.execute` step and the executor itself (§D1: an agent runs turn by
2669
+ * turn in a session, never once).
2670
+ */
2671
+ export declare function agentNotRunnableRefusal(promptKey?: string): AgentRefusal;
2672
+ /**
2673
+ * The refusal of an agent round asked of a prompt that is not an agent —
2674
+ * #3800 (`PromptExecutionService.resolveAgentTurnConfig` and
2675
+ * `executeAgentRound`). The mirror of `agentNotRunnableRefusal`.
2676
+ */
2677
+ export declare function agentRoundNotAgentRefusal(promptKey: string): AgentRefusal;
2678
+ /**
2679
+ * The refusal of a prompt test case that involves an agent (§D1: prompt test
2680
+ * cases are refused for the kind in v1; multi-turn tests are deferred).
2681
+ * `subject` is a case written ON the agent, `evaluator` a case that names the
2682
+ * agent as its judge.
2683
+ */
2684
+ export declare function agentTestCaseRefusal(promptKey: string, role: "subject" | "evaluator"): AgentRefusal;
2685
+ /**
2686
+ * The declaration with every default applied: `answeredBy = "initiator"`, the
2687
+ * platform maximums for the limits, and per tool `invoke = "request"` (server
2688
+ * tools), `approval = false` and `historyScope = "session"`.
2689
+ *
2690
+ * The ONLY accessor for defaults — the stored value never carries them
2691
+ * (DSO-3798-001). Takes a value `resolveAgentDeclaration` accepted (or `null`)
2692
+ * and leaves it untouched.
2693
+ */
2694
+ export declare function normalizeAgentDeclaration(declaration: AgentDeclaration | null | undefined): NormalizedAgentDeclaration;
2695
+ /**
2696
+ * Meaning-preserving schema translation, per provider — issue #3799
2697
+ * (project `agents`, §D6, intent criterion 2).
2698
+ *
2699
+ * A tool or event schema reaches a provider only through a translation that
2700
+ * preserves its meaning; anything else is refused at push, naming the path, the
2701
+ * keyword and the provider. The lossy `sanitizeSchemaForGemini` clean-up
2702
+ * (`src/services/block-executor.ts`) is NOT reused here: it drops unions and
2703
+ * references and rewrites a free-form object as a string, all of which change
2704
+ * what the model may produce. It stays where it is, for chat output schemas
2705
+ * (the project's non-goal: chat is unchanged).
2706
+ *
2707
+ * ## What "lossless" means (spec §3)
2708
+ *
2709
+ * Every keyword is either
2710
+ * (a) passed to the provider unchanged with the same meaning,
2711
+ * (b) rewritten into a provider spelling that admits exactly the same set of
2712
+ * values, or
2713
+ * (c) dropped because dropping it changes neither what the model is told it
2714
+ * may produce nor what the platform enforces on what it produced.
2715
+ *
2716
+ * Anything else is refused. The only silent drops are the annotations with no
2717
+ * value meaning (`$schema`, `$id`, `$comment`) and `additionalProperties`
2718
+ * (DSO-3799-001): Gemini's function `Schema` has no spelling for a closed
2719
+ * object at all, the platform validates every tool argument against the
2720
+ * ORIGINAL, untranslated schema (#3800, criterion 3) so an extra key becomes
2721
+ * the structured error the model sees, and a model following `properties` is
2722
+ * never told it may add keys. Refusing it instead would put the platform's own
2723
+ * closed-object marker — `additionalProperties: false` is how
2724
+ * `src/workflows/schema-descriptor.ts` spells a closed object — outside
2725
+ * Gemini's reach.
2726
+ *
2727
+ * The TRANSLATED schema is what the provider is sent; the ORIGINAL is what the
2728
+ * platform keeps and validates against. Neither function here mutates its
2729
+ * input.
2730
+ *
2731
+ * ## The two providers
2732
+ *
2733
+ * - `openrouter` forwards `tools[].function.parameters` as JSON Schema to the
2734
+ * model's own upstream. The platform cannot know each upstream's dialect, so
2735
+ * the only honest translation is identity — nothing is refused.
2736
+ * - `gemini` takes the OpenAPI 3.0 `Schema` object that
2737
+ * `functionDeclarations[].parameters` accepts: one `type` from a closed list,
2738
+ * `nullable`, `format` from a documented list, `enum` of strings,
2739
+ * `properties`/`required`, `items`, the numeric and length bounds,
2740
+ * `propertyOrdering`, `example`, and `anyOf`. It has no `$ref`, `oneOf`,
2741
+ * `allOf`, `not`, `const`, `additionalProperties`, type arrays or
2742
+ * `type: "null"`; an object needs non-empty `properties` and an array needs
2743
+ * `items`. Lowercase type names are accepted (the existing `responseSchema`
2744
+ * path already sends them).
2745
+ *
2746
+ * Pure and dependency-free, like every module under `src/config-surface/`, and
2747
+ * vendored into the CLI artifact after `agent-declaration.ts` so the push
2748
+ * preflight and the admin routes refuse exactly the same schemas.
2749
+ */
2750
+ /** The providers a prompt config may name. */
2751
+ export type SchemaProvider = "openrouter" | "gemini";
2752
+ /** One untranslatable keyword: where it is, what it is, and why it cannot go. */
2753
+ export interface SchemaTranslationRefusal {
2754
+ /**
2755
+ * The dotted path from the schema root, with indexes — `properties.amount`,
2756
+ * `items.properties.kind`, `anyOf[1].properties.x`. `""` is the root itself.
2757
+ */
2758
+ path: string;
2759
+ /** The keyword that cannot be carried, as the author spelled it. */
2760
+ keyword: string;
2761
+ /** What the provider cannot express, and what to write instead. */
2762
+ reason: string;
2763
+ }
2764
+ export type SchemaTranslation = {
2765
+ ok: true;
2766
+ schema: Record<string, unknown>;
2767
+ } | {
2768
+ ok: false;
2769
+ refusals: SchemaTranslationRefusal[];
2770
+ };
2771
+ /** What a message calls the root. */
2772
+ export declare function schemaPathLabel(path: string): string;
2773
+ /**
2774
+ * Translate one schema for one provider, or refuse it naming every keyword it
2775
+ * cannot carry.
2776
+ *
2777
+ * OpenRouter is identity — a deep copy of the input, so a caller that edits the
2778
+ * result never reaches the stored original. Gemini follows the table in spec
2779
+ * §4. Every refusal of one schema is returned at once, so an author fixes it in
2780
+ * one pass (principle 6).
2781
+ */
2782
+ export declare function translateSchemaForProvider(schema: unknown, provider: SchemaProvider | string): SchemaTranslation;
2783
+ /** One non-archived config of the prompt: which provider, under which name. */
2784
+ export interface AgentSchemaConfigFact {
2785
+ configName: string;
2786
+ provider: string;
2787
+ /** The per-version status; `archived` is skipped (spec §3). */
2788
+ status?: string | null;
2789
+ }
2790
+ export interface AgentSchemaTranslationInput {
2791
+ /** `[prompt.agent]` as authored: a table, one JSON string encoding one, or unset. */
2792
+ declaration: unknown;
2793
+ /**
2794
+ * What this app holds for each function the declaration names, including the
2795
+ * schemas a server tool's two schemas come from. Omitted means "not known
2796
+ * here" — server tools are then not checked, and the caller that does know
2797
+ * checks them.
2798
+ */
2799
+ functions?: AgentFunctionFacts;
2800
+ /** Every config of the prompt. Archived ones are skipped. */
2801
+ configs: ReadonlyArray<AgentSchemaConfigFact>;
2802
+ }
2803
+ /**
2804
+ * Every `AGENT_SCHEMA_NOT_TRANSLATABLE` refusal an agent's declaration owes,
2805
+ * checked against the provider of every config that is not archived
2806
+ * (intent criterion 2).
2807
+ *
2808
+ * One refusal per (schema, path, keyword, provider): it names the tool or
2809
+ * event, which schema, the dotted path, the keyword, the provider, the config
2810
+ * names on that provider, and the remedy. Two configs on the same provider
2811
+ * produce ONE refusal naming both — the author's fix is the same either way.
2812
+ *
2813
+ * A declaration with no tools and no events reads no function schema at all.
2814
+ */
2815
+ export declare function agentSchemaTranslationRefusals(input: AgentSchemaTranslationInput): AgentRefusal[];
2286
2816
  export declare const PROMPT_SURFACE: ConfigObjectSurface;
2287
2817
  export declare const INTEGRATION_SURFACE: ConfigObjectSurface;
2288
2818
  export declare const WEBHOOK_SURFACE: ConfigObjectSurface;