@builder.io/ai-utils 0.86.0 → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builder.io/ai-utils",
3
- "version": "0.86.0",
3
+ "version": "0.87.0",
4
4
  "description": "Builder.io AI utils",
5
5
  "files": [
6
6
  "src"
package/src/codegen.d.ts CHANGED
@@ -79,71 +79,6 @@ export type ReasoningEffort = z.infer<typeof ReasoningEffortSchema>;
79
79
  export declare const AgentModelOverridesSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
80
80
  export type AgentModelOverrides = z.infer<typeof AgentModelOverridesSchema>;
81
81
  export type ReviewEffort = "medium" | "high" | "low";
82
- export interface CustomAgentDefinition {
83
- name: string;
84
- description?: string;
85
- /**
86
- * When provided as an array, the first element must be the static prompt and
87
- * subsequent elements should be dynamic content (e.g. env var placeholders).
88
- * Only the first element is marked as cacheable — placing dynamic content
89
- * first would invalidate the prompt cache on every request.
90
- */
91
- systemPrompt?: string | string[];
92
- tools?: string[];
93
- model?: string;
94
- roundRobinModels?: string[];
95
- position?: CodeGenPosition;
96
- needDevServer?: boolean;
97
- needValidation?: boolean;
98
- includeMemories?: boolean;
99
- resetAfterRun?: boolean;
100
- mcpServers?: boolean;
101
- asyncSubAgents?: boolean;
102
- /**
103
- * Expressive queue behavior for messages sent to this agent. See
104
- * {@link QueueBehavior}. When both `queueBehavior` and `queueMode` are
105
- * provided, `queueBehavior` wins.
106
- */
107
- queueBehavior?: QueueBehavior;
108
- /**
109
- * @deprecated Use {@link CustomAgentDefinition.queueBehavior} instead.
110
- * Kept as a string alias for backwards compatibility with existing agent
111
- * definitions in the wild.
112
- */
113
- queueMode?: QueueMode;
114
- softContextWindow?: number;
115
- filePath?: string;
116
- /** Maximum wall time (in milliseconds) before the agent watchdog aborts. */
117
- maxTimeoutMs?: number;
118
- /**
119
- * Default max LLM completion turns when this agent is spawned via the Agent tool.
120
- * Overrides generic sub-agent defaults in dev-tools when set.
121
- */
122
- maxCompletions?: number;
123
- /** Default reasoning effort level for this agent type. Overrides the session default. */
124
- reasoning?: ReasoningEffort;
125
- /**
126
- * Default {@link SyncChangesFromRemote} policy applied to messages received
127
- * by this agent when the message itself does not specify `syncChanges`.
128
- * Only consulted at the session/sub-agent level (i.e. when the session was
129
- * spawned with `agentType` equal to this agent's name). Use cases include
130
- * always resetting the working branch to its base before each new message
131
- * (e.g. the setup-project agent).
132
- */
133
- defaultSyncChanges?: SyncChangesFromRemote;
134
- /**
135
- * Where this agent was discovered. Drives precedence on name collision:
136
- * `project` > `user` > `plugin`. Set by the discovery loader, not by the
137
- * parsed file itself.
138
- */
139
- scope?: "project" | "user" | "plugin";
140
- /**
141
- * Name of the plugin that contributed this agent, if any. Set by the
142
- * plugin loader (Phase 2); always `undefined` for project-level and
143
- * user-level standalone files (Phase 1).
144
- */
145
- pluginName?: string;
146
- }
147
82
  export declare const CodeGenFrameworkSchema: z.ZodEnum<{
148
83
  angular: "angular";
149
84
  flutter: "flutter";
@@ -2090,7 +2025,14 @@ export type CodeGenMode = z.infer<typeof CodeGenModeSchema>;
2090
2025
  * previous review). The in-flight user prompt and any partial
2091
2026
  * assistant output for it are discarded.
2092
2027
  */
2093
- export type QueueSchedule = "next-turn" | "until-idle" | "interrupt" | "interrupt-clear" | "interrupt-replace";
2028
+ export declare const QueueScheduleSchema: z.ZodEnum<{
2029
+ interrupt: "interrupt";
2030
+ "interrupt-clear": "interrupt-clear";
2031
+ "interrupt-replace": "interrupt-replace";
2032
+ "next-turn": "next-turn";
2033
+ "until-idle": "until-idle";
2034
+ }>;
2035
+ export type QueueSchedule = z.infer<typeof QueueScheduleSchema>;
2094
2036
  /**
2095
2037
  * What happens when multiple messages are pending in the queue.
2096
2038
  *
@@ -2102,15 +2044,31 @@ export type QueueSchedule = "next-turn" | "until-idle" | "interrupt" | "interrup
2102
2044
  * - `preserve-order`: never merge; pop one message at a time in FIFO order.
2103
2045
  * This is the historical behavior for `"until-idle"`.
2104
2046
  */
2105
- export type QueueCoalesce = "merge" | "replace-latest" | "preserve-order";
2047
+ export declare const QueueCoalesceSchema: z.ZodEnum<{
2048
+ merge: "merge";
2049
+ "preserve-order": "preserve-order";
2050
+ "replace-latest": "replace-latest";
2051
+ }>;
2052
+ export type QueueCoalesce = z.infer<typeof QueueCoalesceSchema>;
2106
2053
  /**
2107
2054
  * Expressive queue behavior built from two orthogonal axes:
2108
2055
  * `schedule` (when to dispatch) and `coalesce` (how to combine pending).
2109
2056
  */
2110
- export interface QueueBehavior {
2111
- schedule: QueueSchedule;
2112
- coalesce: QueueCoalesce;
2113
- }
2057
+ export declare const QueueBehaviorSchema: z.ZodObject<{
2058
+ schedule: z.ZodEnum<{
2059
+ interrupt: "interrupt";
2060
+ "interrupt-clear": "interrupt-clear";
2061
+ "interrupt-replace": "interrupt-replace";
2062
+ "next-turn": "next-turn";
2063
+ "until-idle": "until-idle";
2064
+ }>;
2065
+ coalesce: z.ZodEnum<{
2066
+ merge: "merge";
2067
+ "preserve-order": "preserve-order";
2068
+ "replace-latest": "replace-latest";
2069
+ }>;
2070
+ }, z.core.$strip>;
2071
+ export type QueueBehavior = z.infer<typeof QueueBehaviorSchema>;
2114
2072
  /**
2115
2073
  * Backwards-compatible queue mode. Accepts either a legacy string alias
2116
2074
  * or the full {@link QueueBehavior} object.
@@ -2119,7 +2077,21 @@ export interface QueueBehavior {
2119
2077
  * - `"next-turn"` → `{ schedule: "next-turn", coalesce: "merge" }`
2120
2078
  * - `"until-idle"` → `{ schedule: "until-idle", coalesce: "preserve-order" }`
2121
2079
  */
2122
- export type QueueMode = "next-turn" | "until-idle" | QueueBehavior;
2080
+ export declare const QueueModeSchema: z.ZodUnion<readonly [z.ZodLiteral<"next-turn">, z.ZodLiteral<"until-idle">, z.ZodObject<{
2081
+ schedule: z.ZodEnum<{
2082
+ interrupt: "interrupt";
2083
+ "interrupt-clear": "interrupt-clear";
2084
+ "interrupt-replace": "interrupt-replace";
2085
+ "next-turn": "next-turn";
2086
+ "until-idle": "until-idle";
2087
+ }>;
2088
+ coalesce: z.ZodEnum<{
2089
+ merge: "merge";
2090
+ "preserve-order": "preserve-order";
2091
+ "replace-latest": "replace-latest";
2092
+ }>;
2093
+ }, z.core.$strip>]>;
2094
+ export type QueueMode = z.infer<typeof QueueModeSchema>;
2123
2095
  export declare const DEFAULT_QUEUE_BEHAVIOR: QueueBehavior;
2124
2096
  /**
2125
2097
  * Normalize any accepted queue-mode shape into a concrete {@link QueueBehavior}.
@@ -2911,7 +2883,7 @@ export type CodeGenInputOptions = z.infer<typeof CodeGenInputOptionsSchema> & {
2911
2883
  */
2912
2884
  _mcpClientWrapperFactory?: (realClient: any) => any;
2913
2885
  };
2914
- export type CodeGenErrorCodes = "credits-limit-daily" | "credits-limit-monthly" | "credits-limit-user" | "credits-limit-other" | "cli-genetic-error" | "git-update-error" | "prompt-too-long" | "context-too-long" | "abrupt-end" | "unknown" | "failed-recover-state" | "completion-expired" | "ask-to-continue" | "bad-initial-url" | "bad-smart-export-payload" | "invalid-last-message" | "corrupted-session" | "privacy-mode-key-required" | "privacy-mode-key-invalid" | "privacy-mode-key-mismatch" | "cli-network-error" | "invalid-credentials" | "model-restricted-too-large" | "org-no-models-enabled" | "assertion" | "rate-limit" | "unknown-design-system";
2886
+ export type CodeGenErrorCodes = "credits-limit-daily" | "credits-limit-monthly" | "credits-limit-user" | "credits-limit-other" | "cli-genetic-error" | "git-update-error" | "prompt-too-long" | "context-too-long" | "abrupt-end" | "unknown" | "failed-recover-state" | "completion-expired" | "ask-to-continue" | "bad-initial-url" | "bad-smart-export-payload" | "invalid-last-message" | "corrupted-session" | "privacy-mode-key-required" | "privacy-mode-key-invalid" | "privacy-mode-key-mismatch" | "privacy-mode-validation-unavailable" | "cli-network-error" | "invalid-credentials" | "model-restricted-too-large" | "org-no-models-enabled" | "assertion" | "rate-limit" | "unknown-design-system";
2915
2887
  export interface CodegenUsage {
2916
2888
  total: number;
2917
2889
  fast: number;
@@ -3498,6 +3470,112 @@ export declare const SyncChangesFromRemoteSchema: z.ZodObject<{
3498
3470
  updateLastCommits: z.ZodOptional<z.ZodBoolean>;
3499
3471
  }, z.core.$strip>;
3500
3472
  export type SyncChangesFromRemote = z.infer<typeof SyncChangesFromRemoteSchema>;
3473
+ export declare const CustomAgentDefinitionSchema: z.ZodObject<{
3474
+ name: z.ZodString;
3475
+ description: z.ZodOptional<z.ZodString>;
3476
+ systemPrompt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
3477
+ tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
3478
+ model: z.ZodOptional<z.ZodString>;
3479
+ roundRobinModels: z.ZodOptional<z.ZodArray<z.ZodString>>;
3480
+ position: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
3481
+ "browser-testing": "browser-testing";
3482
+ "builder-code": "builder-code";
3483
+ "builder-code-panel": "builder-code-panel";
3484
+ "builder-publish-integration": "builder-publish-integration";
3485
+ cli: "cli";
3486
+ "code-review-orchestrator": "code-review-orchestrator";
3487
+ "create-app-firebase": "create-app-firebase";
3488
+ "create-app-lovable": "create-app-lovable";
3489
+ "design-system-indexer": "design-system-indexer";
3490
+ "dsi-mcp": "dsi-mcp";
3491
+ "editor-ai": "editor-ai";
3492
+ fusion: "fusion";
3493
+ "org-agent": "org-agent";
3494
+ "org-worker": "org-worker";
3495
+ "project-configuration": "project-configuration";
3496
+ "projects-scheduler-memory-extraction": "projects-scheduler-memory-extraction";
3497
+ "repo-indexing": "repo-indexing";
3498
+ "setup-project": "setup-project";
3499
+ unknown: "unknown";
3500
+ }>, z.ZodTemplateLiteral<"browser-testing-agent" | "builder-code-agent" | "builder-code-panel-agent" | "builder-publish-integration-agent" | "cli-agent" | "code-review-orchestrator-agent" | "create-app-firebase-agent" | "create-app-lovable-agent" | "design-system-indexer-agent" | "dsi-mcp-agent" | "editor-ai-agent" | "fusion-agent" | "org-agent-agent" | "org-worker-agent" | "project-configuration-agent" | "projects-scheduler-memory-extraction-agent" | "repo-indexing-agent" | "setup-project-agent" | "unknown-agent">]>>;
3501
+ needDevServer: z.ZodOptional<z.ZodBoolean>;
3502
+ needValidation: z.ZodOptional<z.ZodBoolean>;
3503
+ includeMemories: z.ZodOptional<z.ZodBoolean>;
3504
+ resetAfterRun: z.ZodOptional<z.ZodBoolean>;
3505
+ mcpServers: z.ZodOptional<z.ZodBoolean>;
3506
+ asyncSubAgents: z.ZodOptional<z.ZodBoolean>;
3507
+ queueBehavior: z.ZodOptional<z.ZodObject<{
3508
+ schedule: z.ZodEnum<{
3509
+ interrupt: "interrupt";
3510
+ "interrupt-clear": "interrupt-clear";
3511
+ "interrupt-replace": "interrupt-replace";
3512
+ "next-turn": "next-turn";
3513
+ "until-idle": "until-idle";
3514
+ }>;
3515
+ coalesce: z.ZodEnum<{
3516
+ merge: "merge";
3517
+ "preserve-order": "preserve-order";
3518
+ "replace-latest": "replace-latest";
3519
+ }>;
3520
+ }, z.core.$strip>>;
3521
+ queueMode: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<"next-turn">, z.ZodLiteral<"until-idle">, z.ZodObject<{
3522
+ schedule: z.ZodEnum<{
3523
+ interrupt: "interrupt";
3524
+ "interrupt-clear": "interrupt-clear";
3525
+ "interrupt-replace": "interrupt-replace";
3526
+ "next-turn": "next-turn";
3527
+ "until-idle": "until-idle";
3528
+ }>;
3529
+ coalesce: z.ZodEnum<{
3530
+ merge: "merge";
3531
+ "preserve-order": "preserve-order";
3532
+ "replace-latest": "replace-latest";
3533
+ }>;
3534
+ }, z.core.$strip>]>>;
3535
+ softContextWindow: z.ZodOptional<z.ZodNumber>;
3536
+ filePath: z.ZodOptional<z.ZodString>;
3537
+ maxTimeoutMs: z.ZodOptional<z.ZodNumber>;
3538
+ maxCompletions: z.ZodOptional<z.ZodNumber>;
3539
+ reasoning: z.ZodOptional<z.ZodEnum<{
3540
+ auto: "auto";
3541
+ high: "high";
3542
+ low: "low";
3543
+ max: "max";
3544
+ medium: "medium";
3545
+ minimal: "minimal";
3546
+ none: "none";
3547
+ xhigh: "xhigh";
3548
+ }>>;
3549
+ defaultSyncChanges: z.ZodOptional<z.ZodObject<{
3550
+ remoteBranches: z.ZodOptional<z.ZodEnum<{
3551
+ ai: "ai";
3552
+ both: "both";
3553
+ main: "main";
3554
+ }>>;
3555
+ fastForward: z.ZodOptional<z.ZodEnum<{
3556
+ auto: "auto";
3557
+ never: "never";
3558
+ required: "required";
3559
+ }>>;
3560
+ canPush: z.ZodOptional<z.ZodBoolean>;
3561
+ uncommittedChanges: z.ZodOptional<z.ZodEnum<{
3562
+ commit: "commit";
3563
+ fail: "fail";
3564
+ stash: "stash";
3565
+ }>>;
3566
+ requestRefresh: z.ZodOptional<z.ZodBoolean>;
3567
+ allowUnrelatedHistory: z.ZodOptional<z.ZodBoolean>;
3568
+ resetToBase: z.ZodOptional<z.ZodBoolean>;
3569
+ updateLastCommits: z.ZodOptional<z.ZodBoolean>;
3570
+ }, z.core.$strip>>;
3571
+ scope: z.ZodOptional<z.ZodEnum<{
3572
+ plugin: "plugin";
3573
+ project: "project";
3574
+ user: "user";
3575
+ }>>;
3576
+ pluginName: z.ZodOptional<z.ZodString>;
3577
+ }, z.core.$strip>;
3578
+ export type CustomAgentDefinition = z.infer<typeof CustomAgentDefinitionSchema>;
3501
3579
  export declare const GenerateUserMessageSchema: z.ZodObject<{
3502
3580
  idempotencyKey: z.ZodOptional<z.ZodString>;
3503
3581
  user: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -3845,6 +3923,30 @@ export interface GenerateCodeEventError {
3845
3923
  message: string;
3846
3924
  usage?: CodegenUsage;
3847
3925
  }
3926
+ /**
3927
+ * Wire schema for the pre-stream error protocol on `/codegen/completion`:
3928
+ * middlewares that reject a request before the stream starts (credit limits,
3929
+ * privacy mode) respond with an error status whose body is a single
3930
+ * {@link GenerateCodeEventError} JSONL line. Loose so servers can attach
3931
+ * extra fields (e.g. `usageInfo`), and `code` stays an open string so newer
3932
+ * server codes pass through older clients.
3933
+ */
3934
+ export declare const GenerateCodeEventErrorBodySchema: z.ZodObject<{
3935
+ type: z.ZodLiteral<"error">;
3936
+ stopReason: z.ZodEnum<{
3937
+ error: "error";
3938
+ limit: "limit";
3939
+ }>;
3940
+ code: z.ZodString;
3941
+ id: z.ZodString;
3942
+ message: z.ZodString;
3943
+ }, z.core.$loose>;
3944
+ /**
3945
+ * Decode a non-OK `/codegen/completion` response body as a structured error
3946
+ * event. Returns undefined for anything else (auth failures, proxy errors,
3947
+ * plain-text bodies), letting transport-level status handling take over.
3948
+ */
3949
+ export declare function parseGenerateCodeEventErrorBody(body: string): GenerateCodeEventError | undefined;
3848
3950
  export interface GenerateCodeEventPagination {
3849
3951
  type: "pagination";
3850
3952
  pop: number;
@@ -4171,23 +4273,22 @@ export interface PrivacyMode {
4171
4273
  mcpServers?: boolean;
4172
4274
  }
4173
4275
  export type Mode = "init-and-launch" | "backup" | "backup-force-full" | "snapshot-creation";
4174
- export interface FileOverride {
4175
- /**
4176
- * Path where the file should be written.
4177
- * Supports absolute paths ("/app/.env"), tilde ("~/.npmrc"), and relative paths ("./config.json").
4178
- */
4179
- path: string;
4180
- /**
4181
- * Plain text content to write to the file.
4182
- * Mutually exclusive with `base64`.
4183
- */
4184
- content?: string;
4185
- /**
4186
- * Base64-encoded binary content to write to the file.
4187
- * Mutually exclusive with `content`.
4188
- */
4189
- base64?: string;
4190
- }
4276
+ /**
4277
+ * A file to write into the container during setup. Exactly one of `content`
4278
+ * (plain text) or `base64` (binary) must be provided: `z.xor` is an exclusive
4279
+ * union that fails if zero or both options match, so the mutual exclusivity is
4280
+ * enforced at runtime and reflected in the inferred type. Each variant omits
4281
+ * the other's field — combined with `z.object`'s key-stripping, that's what
4282
+ * makes the "both provided" case fail (it matches both options).
4283
+ */
4284
+ export declare const FileOverrideSchema: z.ZodXor<readonly [z.ZodObject<{
4285
+ path: z.ZodString;
4286
+ content: z.ZodString;
4287
+ }, z.core.$strip>, z.ZodObject<{
4288
+ path: z.ZodString;
4289
+ base64: z.ZodString;
4290
+ }, z.core.$strip>]>;
4291
+ export type FileOverride = z.infer<typeof FileOverrideSchema>;
4191
4292
  export interface MCPServerDefinition {
4192
4293
  command: string;
4193
4294
  args?: string[];
package/src/codegen.js CHANGED
@@ -1626,6 +1626,70 @@ export const CodeGenModeSchema = z
1626
1626
  "quality-v4-agent",
1627
1627
  ])
1628
1628
  .meta({ title: "CodeGenMode" });
1629
+ /**
1630
+ * When a queued message gets picked up by the scheduler.
1631
+ *
1632
+ * - `next-turn`: process queued messages as soon as the current LLM turn
1633
+ * finishes (i.e. between turns of an in-flight run).
1634
+ * - `until-idle`: hold queued messages until the agent is fully idle
1635
+ * (current run has ended). Messages never interrupt an in-flight run.
1636
+ * - `interrupt`: abort the in-flight run as soon as a new message arrives
1637
+ * and start processing it. Reserved for high-priority/reactive cases.
1638
+ * - `interrupt-clear`: like `interrupt`, but also clears the session
1639
+ * (turn history, queued messages, last user, accumulated credits) before
1640
+ * processing the new message. Use when the new message should start from
1641
+ * a clean slate.
1642
+ * - `interrupt-replace`: equivalent to abort + rewind to the previous
1643
+ * user message + replace it with the new one. Use when a fresh
1644
+ * request supersedes the in-flight one (e.g. incremental code-review
1645
+ * requests where a newer review should replace the still-running
1646
+ * previous review). The in-flight user prompt and any partial
1647
+ * assistant output for it are discarded.
1648
+ */
1649
+ export const QueueScheduleSchema = z
1650
+ .enum([
1651
+ "next-turn",
1652
+ "until-idle",
1653
+ "interrupt",
1654
+ "interrupt-clear",
1655
+ "interrupt-replace",
1656
+ ])
1657
+ .meta({ title: "QueueSchedule" });
1658
+ /**
1659
+ * What happens when multiple messages are pending in the queue.
1660
+ *
1661
+ * - `merge`: combine all pending messages into a single user message before
1662
+ * the next turn. This is the historical default for `"next-turn"`.
1663
+ * - `replace-latest`: discard older pending messages and keep only the
1664
+ * most recently queued one (useful when stale inputs are obsolete, e.g.
1665
+ * a typing user replacing their previous draft).
1666
+ * - `preserve-order`: never merge; pop one message at a time in FIFO order.
1667
+ * This is the historical behavior for `"until-idle"`.
1668
+ */
1669
+ export const QueueCoalesceSchema = z
1670
+ .enum(["merge", "replace-latest", "preserve-order"])
1671
+ .meta({ title: "QueueCoalesce" });
1672
+ /**
1673
+ * Expressive queue behavior built from two orthogonal axes:
1674
+ * `schedule` (when to dispatch) and `coalesce` (how to combine pending).
1675
+ */
1676
+ export const QueueBehaviorSchema = z
1677
+ .object({
1678
+ schedule: QueueScheduleSchema,
1679
+ coalesce: QueueCoalesceSchema,
1680
+ })
1681
+ .meta({ title: "QueueBehavior" });
1682
+ /**
1683
+ * Backwards-compatible queue mode. Accepts either a legacy string alias
1684
+ * or the full {@link QueueBehavior} object.
1685
+ *
1686
+ * Legacy aliases:
1687
+ * - `"next-turn"` → `{ schedule: "next-turn", coalesce: "merge" }`
1688
+ * - `"until-idle"` → `{ schedule: "until-idle", coalesce: "preserve-order" }`
1689
+ */
1690
+ export const QueueModeSchema = z
1691
+ .union([z.literal("next-turn"), z.literal("until-idle"), QueueBehaviorSchema])
1692
+ .meta({ title: "QueueMode" });
1629
1693
  export const DEFAULT_QUEUE_BEHAVIOR = {
1630
1694
  schedule: "next-turn",
1631
1695
  coalesce: "merge",
@@ -1958,6 +2022,54 @@ export const SyncChangesFromRemoteSchema = z
1958
2022
  }),
1959
2023
  })
1960
2024
  .meta({ title: "SyncChangesFromRemote" });
2025
+ export const CustomAgentDefinitionSchema = z
2026
+ .object({
2027
+ name: z.string(),
2028
+ description: z.string().optional(),
2029
+ systemPrompt: z
2030
+ .union([z.string(), z.array(z.string())])
2031
+ .optional()
2032
+ .meta({
2033
+ description: "When provided as an array, the first element must be the static prompt and subsequent elements should be dynamic content (e.g. env var placeholders). Only the first element is marked as cacheable — placing dynamic content first would invalidate the prompt cache on every request.",
2034
+ }),
2035
+ tools: z.array(z.string()).optional(),
2036
+ model: z.string().optional(),
2037
+ roundRobinModels: z.array(z.string()).optional(),
2038
+ position: CodeGenPositionSchema.optional(),
2039
+ needDevServer: z.boolean().optional(),
2040
+ needValidation: z.boolean().optional(),
2041
+ includeMemories: z.boolean().optional(),
2042
+ resetAfterRun: z.boolean().optional(),
2043
+ mcpServers: z.boolean().optional(),
2044
+ asyncSubAgents: z.boolean().optional(),
2045
+ queueBehavior: QueueBehaviorSchema.optional().meta({
2046
+ description: "Expressive queue behavior for messages sent to this agent. When both `queueBehavior` and `queueMode` are provided, `queueBehavior` wins.",
2047
+ }),
2048
+ queueMode: QueueModeSchema.optional().meta({
2049
+ description: "@deprecated Use `queueBehavior` instead. Kept as a string alias for backwards compatibility with existing agent definitions in the wild.",
2050
+ }),
2051
+ softContextWindow: z.number().optional(),
2052
+ filePath: z.string().optional(),
2053
+ maxTimeoutMs: z.number().optional().meta({
2054
+ description: "Maximum wall time (in milliseconds) before the agent watchdog aborts.",
2055
+ }),
2056
+ maxCompletions: z.number().optional().meta({
2057
+ description: "Default max LLM completion turns when this agent is spawned via the Agent tool. Overrides generic sub-agent defaults in dev-tools when set.",
2058
+ }),
2059
+ reasoning: ReasoningEffortSchema.optional().meta({
2060
+ description: "Default reasoning effort level for this agent type. Overrides the session default.",
2061
+ }),
2062
+ defaultSyncChanges: SyncChangesFromRemoteSchema.optional().meta({
2063
+ description: "Default sync-changes policy applied to messages received by this agent when the message itself does not specify `syncChanges`. Only consulted at the session/sub-agent level (i.e. when the session was spawned with `agentType` equal to this agent's name). Use cases include always resetting the working branch to its base before each new message (e.g. the setup-project agent).",
2064
+ }),
2065
+ scope: z.enum(["project", "user", "plugin"]).optional().meta({
2066
+ description: "Where this agent was discovered. Drives precedence on name collision: `project` > `user` > `plugin`. Set by the discovery loader, not by the parsed file itself.",
2067
+ }),
2068
+ pluginName: z.string().optional().meta({
2069
+ description: "Name of the plugin that contributed this agent, if any. Set by the plugin loader (Phase 2); always `undefined` for project-level and user-level standalone files (Phase 1).",
2070
+ }),
2071
+ })
2072
+ .meta({ title: "CustomAgentDefinition" });
1961
2073
  export const GenerateUserMessageSchema = z
1962
2074
  .object({
1963
2075
  idempotencyKey: z.string().optional(),
@@ -2017,6 +2129,66 @@ export const CodegenSettingsRequestSchema = z
2017
2129
  repoHash: z.string().optional(),
2018
2130
  })
2019
2131
  .meta({ title: "CodegenSettingsRequest" });
2132
+ /**
2133
+ * Wire schema for the pre-stream error protocol on `/codegen/completion`:
2134
+ * middlewares that reject a request before the stream starts (credit limits,
2135
+ * privacy mode) respond with an error status whose body is a single
2136
+ * {@link GenerateCodeEventError} JSONL line. Loose so servers can attach
2137
+ * extra fields (e.g. `usageInfo`), and `code` stays an open string so newer
2138
+ * server codes pass through older clients.
2139
+ */
2140
+ export const GenerateCodeEventErrorBodySchema = z.looseObject({
2141
+ type: z.literal("error"),
2142
+ stopReason: z.enum(["error", "limit"]),
2143
+ code: z.string(),
2144
+ id: z.string(),
2145
+ message: z.string(),
2146
+ });
2147
+ /**
2148
+ * Decode a non-OK `/codegen/completion` response body as a structured error
2149
+ * event. Returns undefined for anything else (auth failures, proxy errors,
2150
+ * plain-text bodies), letting transport-level status handling take over.
2151
+ */
2152
+ export function parseGenerateCodeEventErrorBody(body) {
2153
+ try {
2154
+ const parsed = GenerateCodeEventErrorBodySchema.safeParse(JSON.parse(body.trim().split("\n")[0]));
2155
+ return parsed.success
2156
+ ? parsed.data
2157
+ : undefined;
2158
+ }
2159
+ catch (_a) {
2160
+ return undefined;
2161
+ }
2162
+ }
2163
+ const FileOverrideBaseShape = {
2164
+ path: z.string().meta({
2165
+ description: 'Path where the file should be written. Supports absolute paths ("/app/.env"), tilde ("~/.npmrc"), and relative paths ("./config.json").',
2166
+ }),
2167
+ };
2168
+ /**
2169
+ * A file to write into the container during setup. Exactly one of `content`
2170
+ * (plain text) or `base64` (binary) must be provided: `z.xor` is an exclusive
2171
+ * union that fails if zero or both options match, so the mutual exclusivity is
2172
+ * enforced at runtime and reflected in the inferred type. Each variant omits
2173
+ * the other's field — combined with `z.object`'s key-stripping, that's what
2174
+ * makes the "both provided" case fail (it matches both options).
2175
+ */
2176
+ export const FileOverrideSchema = z
2177
+ .xor([
2178
+ z.object({
2179
+ ...FileOverrideBaseShape,
2180
+ content: z.string().meta({
2181
+ description: "Plain text content to write to the file.",
2182
+ }),
2183
+ }),
2184
+ z.object({
2185
+ ...FileOverrideBaseShape,
2186
+ base64: z.string().meta({
2187
+ description: "Base64-encoded binary content to write to the file.",
2188
+ }),
2189
+ }),
2190
+ ])
2191
+ .meta({ title: "FileOverride" });
2020
2192
  /**
2021
2193
  * Request for generating a commit message via LLM
2022
2194
  */
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { DEFAULT_QUEUE_BEHAVIOR, isInterruptSchedule, normalizeQueueMode, } from "./codegen";
2
+ import { DEFAULT_QUEUE_BEHAVIOR, isInterruptSchedule, normalizeQueueMode, parseGenerateCodeEventErrorBody, } from "./codegen";
3
3
  describe("normalizeQueueMode", () => {
4
4
  it("returns the default behavior when input is undefined", () => {
5
5
  expect(normalizeQueueMode(undefined)).toEqual(DEFAULT_QUEUE_BEHAVIOR);
@@ -56,3 +56,38 @@ describe("isInterruptSchedule", () => {
56
56
  expect(isInterruptSchedule("until-idle")).toBe(false);
57
57
  });
58
58
  });
59
+ describe("parseGenerateCodeEventErrorBody", () => {
60
+ it("decodes a structured error-event body", () => {
61
+ const body = JSON.stringify({
62
+ type: "error",
63
+ stopReason: "error",
64
+ code: "privacy-mode-key-required",
65
+ id: "abc",
66
+ message: "no key",
67
+ }) + "\n";
68
+ expect(parseGenerateCodeEventErrorBody(body)).toMatchObject({
69
+ code: "privacy-mode-key-required",
70
+ message: "no key",
71
+ });
72
+ });
73
+ it("preserves extra fields like usageInfo and decodes only the first line", () => {
74
+ const body = JSON.stringify({
75
+ type: "error",
76
+ stopReason: "limit",
77
+ code: "credits-limit-monthly",
78
+ id: "abc",
79
+ message: "limit reached",
80
+ usageInfo: { plan: "free" },
81
+ }) + "\nnot-json-second-line";
82
+ expect(parseGenerateCodeEventErrorBody(body)).toMatchObject({
83
+ code: "credits-limit-monthly",
84
+ usageInfo: { plan: "free" },
85
+ });
86
+ });
87
+ it("returns undefined for non-event bodies", () => {
88
+ expect(parseGenerateCodeEventErrorBody("Forbidden")).toBeUndefined();
89
+ expect(parseGenerateCodeEventErrorBody('{"error":"invalid token"}')).toBeUndefined();
90
+ expect(parseGenerateCodeEventErrorBody(JSON.stringify({ type: "error", code: 42, message: "bad shape" }))).toBeUndefined();
91
+ expect(parseGenerateCodeEventErrorBody("")).toBeUndefined();
92
+ });
93
+ });
@@ -11,6 +11,22 @@ export interface FigmaHydrationResponse {
11
11
  manifest: import("./events.js").FigmaFrameManifest | null;
12
12
  files: FigmaHydrationFile[];
13
13
  }
14
+ export declare const figmaDecodeJobStatusParamsSchema: z.ZodObject<{
15
+ jobId: z.ZodString;
16
+ }, z.core.$strip>;
17
+ export type FigmaDecodeJobStatusParams = z.infer<typeof figmaDecodeJobStatusParamsSchema>;
18
+ export interface FigmaDecodeJobStatusResponse {
19
+ jobId: string;
20
+ status: "pending" | "processing" | "complete" | "error";
21
+ framesProcessed: number;
22
+ totalFrames: number;
23
+ branchName: string | null;
24
+ branchUrl: string | null;
25
+ error: string | null;
26
+ partialFailure?: boolean;
27
+ createdAt: number;
28
+ updatedAt: number;
29
+ }
14
30
  /**
15
31
  * Accepts `https://github.com/<owner>/<repo>` (optionally with a trailing
16
32
  * `.git` or path segments). Used to gate public-repo inputs before cloning.
@@ -1,4 +1,7 @@
1
1
  import { z } from "zod";
2
+ export const figmaDecodeJobStatusParamsSchema = z.object({
3
+ jobId: z.string().min(1),
4
+ });
2
5
  /**
3
6
  * Accepts `https://github.com/<owner>/<repo>` (optionally with a trailing
4
7
  * `.git` or path segments). Used to gate public-repo inputs before cloning.