@builder.io/ai-utils 0.86.1 → 0.87.1

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.1",
3
+ "version": "0.87.1",
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}.
@@ -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<{
@@ -4044,6 +4122,12 @@ export interface BranchBackup {
4044
4122
  forced: ForcedBackup;
4045
4123
  commitInRepoVerified?: "verified" | "not-found" | "unverified";
4046
4124
  metadata?: Record<string, any>;
4125
+ /**
4126
+ * Paths of submodules / embedded git repos whose state the bundle cannot
4127
+ * reproduce. When non-empty the backup is restorable for the outer repo
4128
+ * but must not be treated as deletion-safe.
4129
+ */
4130
+ changedSubmodules?: string[];
4047
4131
  }
4048
4132
  export interface CheckBackupDataResultValid {
4049
4133
  state: "valid";
@@ -4063,15 +4147,26 @@ export interface CheckBackupDataResultStale {
4063
4147
  message: string;
4064
4148
  backup: BranchBackup;
4065
4149
  }
4150
+ /**
4151
+ * The backup is otherwise valid but includes submodule changes the bundle
4152
+ * cannot reproduce (see BranchBackup.changedSubmodules). It can still be
4153
+ * restored, but the volume must be retained.
4154
+ */
4155
+ export interface CheckBackupDataResultSubmoduleChanges {
4156
+ state: "submodule-changes";
4157
+ outcome: "submodule-changes";
4158
+ message: string;
4159
+ backup: BranchBackup;
4160
+ }
4066
4161
  export interface CheckBackupDataResultInvalid {
4067
4162
  state: "invalid";
4068
4163
  outcome: "no-backup" | "error" | "not-completed" | "no-session-id" | "no-last-commit-hash" | "no-backup-file" | "empty-full-backup" | "no-vcpCodeGenEvent" | "commits-not-in-repo" | "no-after-commit" | "no-signed-url" | "no-git-branch-name" | "repo-url-mismatch" | "branch-uninitialized" | "unexpected-partial-backup" | "unexpected-full-backup" | "no-backup-keys";
4069
4164
  message: string;
4070
4165
  backup: BranchBackup | undefined;
4071
4166
  }
4072
- export type CheckBackupDataResult = CheckBackupDataResultValid | CheckBackupDataResultForcedBackup | CheckBackupDataResultStale | CheckBackupDataResultInvalid;
4167
+ export type CheckBackupDataResult = CheckBackupDataResultValid | CheckBackupDataResultForcedBackup | CheckBackupDataResultStale | CheckBackupDataResultSubmoduleChanges | CheckBackupDataResultInvalid;
4073
4168
  export interface BackupMetadata {
4074
- check: CheckBackupDataResultValid | CheckBackupDataResultStale | CheckBackupDataResultForcedBackup;
4169
+ check: CheckBackupDataResultValid | CheckBackupDataResultStale | CheckBackupDataResultForcedBackup | CheckBackupDataResultSubmoduleChanges;
4075
4170
  downloadUrl: GitBackupDownloadUrlResult | undefined;
4076
4171
  downloadUrlError?: string;
4077
4172
  }
@@ -4195,23 +4290,22 @@ export interface PrivacyMode {
4195
4290
  mcpServers?: boolean;
4196
4291
  }
4197
4292
  export type Mode = "init-and-launch" | "backup" | "backup-force-full" | "snapshot-creation";
4198
- export interface FileOverride {
4199
- /**
4200
- * Path where the file should be written.
4201
- * Supports absolute paths ("/app/.env"), tilde ("~/.npmrc"), and relative paths ("./config.json").
4202
- */
4203
- path: string;
4204
- /**
4205
- * Plain text content to write to the file.
4206
- * Mutually exclusive with `base64`.
4207
- */
4208
- content?: string;
4209
- /**
4210
- * Base64-encoded binary content to write to the file.
4211
- * Mutually exclusive with `content`.
4212
- */
4213
- base64?: string;
4214
- }
4293
+ /**
4294
+ * A file to write into the container during setup. Exactly one of `content`
4295
+ * (plain text) or `base64` (binary) must be provided: `z.xor` is an exclusive
4296
+ * union that fails if zero or both options match, so the mutual exclusivity is
4297
+ * enforced at runtime and reflected in the inferred type. Each variant omits
4298
+ * the other's field — combined with `z.object`'s key-stripping, that's what
4299
+ * makes the "both provided" case fail (it matches both options).
4300
+ */
4301
+ export declare const FileOverrideSchema: z.ZodXor<readonly [z.ZodObject<{
4302
+ path: z.ZodString;
4303
+ content: z.ZodString;
4304
+ }, z.core.$strip>, z.ZodObject<{
4305
+ path: z.ZodString;
4306
+ base64: z.ZodString;
4307
+ }, z.core.$strip>]>;
4308
+ export type FileOverride = z.infer<typeof FileOverrideSchema>;
4215
4309
  export interface MCPServerDefinition {
4216
4310
  command: string;
4217
4311
  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(),
@@ -2048,6 +2160,35 @@ export function parseGenerateCodeEventErrorBody(body) {
2048
2160
  return undefined;
2049
2161
  }
2050
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" });
2051
2192
  /**
2052
2193
  * Request for generating a commit message via LLM
2053
2194
  */
@@ -0,0 +1,5 @@
1
+ import type { Branch, FusionExecutionEnvironment } from "./projects.js";
2
+ /** Upgrade legacy `cloud` to `cloud-v2` when kube is enabled. */
3
+ export declare function upgradeCloudForKube(environment: FusionExecutionEnvironment, useKube: boolean): FusionExecutionEnvironment;
4
+ /** Work branch whose fusion environment a new sibling branch should inherit. */
5
+ export declare function pickReferenceWorkBranch(branches: Branch[]): Branch | undefined;
@@ -0,0 +1,16 @@
1
+ import { getBranchState } from "./projects.js";
2
+ /** Upgrade legacy `cloud` to `cloud-v2` when kube is enabled. */
3
+ export function upgradeCloudForKube(environment, useKube) {
4
+ return environment === "cloud" && useKube ? "cloud-v2" : environment;
5
+ }
6
+ /** Work branch whose fusion environment a new sibling branch should inherit. */
7
+ export function pickReferenceWorkBranch(branches) {
8
+ var _a, _b;
9
+ const activeWorkBranches = branches.filter((branch) => {
10
+ if (branch.type === "deploy" || branch.hidden) {
11
+ return false;
12
+ }
13
+ return getBranchState(branch) === "active";
14
+ });
15
+ return ((_b = (_a = activeWorkBranches.find((branch) => branch.name === "development")) !== null && _a !== void 0 ? _a : activeWorkBranches.find((branch) => branch.isDefault)) !== null && _b !== void 0 ? _b : activeWorkBranches[0]);
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { pickReferenceWorkBranch, upgradeCloudForKube, } from "./fusion-environment.js";
3
+ function branch(overrides) {
4
+ return {
5
+ id: `br-${overrides.name}`,
6
+ projectId: "project-1",
7
+ ownerId: "org-1",
8
+ isPublic: true,
9
+ ...overrides,
10
+ };
11
+ }
12
+ describe("upgradeCloudForKube", () => {
13
+ it("upgrades cloud when useKube is true", () => {
14
+ expect(upgradeCloudForKube("cloud", true)).toBe("cloud-v2");
15
+ });
16
+ it("leaves cloud-v2 unchanged", () => {
17
+ expect(upgradeCloudForKube("cloud-v2", false)).toBe("cloud-v2");
18
+ });
19
+ });
20
+ describe("pickReferenceWorkBranch", () => {
21
+ it("prefers development over other work branches", () => {
22
+ var _a;
23
+ expect((_a = pickReferenceWorkBranch([
24
+ branch({ name: "feature-a", lockedFusionEnvironment: "cloud" }),
25
+ branch({ name: "development", lockedFusionEnvironment: "cloud-v2" }),
26
+ ])) === null || _a === void 0 ? void 0 : _a.name).toBe("development");
27
+ });
28
+ it("ignores deploy and hidden branches", () => {
29
+ var _a;
30
+ expect((_a = pickReferenceWorkBranch([
31
+ branch({
32
+ name: "deploy-pod",
33
+ type: "deploy",
34
+ hidden: true,
35
+ lockedFusionEnvironment: "cloud",
36
+ }),
37
+ branch({ name: "development", lockedFusionEnvironment: "cloud-v2" }),
38
+ ])) === null || _a === void 0 ? void 0 : _a.name).toBe("development");
39
+ });
40
+ });
package/src/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from "./codegen.js";
9
9
  export * from "./codegen/investigation-context.js";
10
10
  export * from "./diff-hunks.js";
11
11
  export * from "./projects.js";
12
+ export * from "./fusion-environment.js";
12
13
  export * from "./repo-indexing.js";
13
14
  export * from "./organization.js";
14
15
  export * from "./features.js";
package/src/index.js CHANGED
@@ -9,6 +9,7 @@ export * from "./codegen.js";
9
9
  export * from "./codegen/investigation-context.js";
10
10
  export * from "./diff-hunks.js";
11
11
  export * from "./projects.js";
12
+ export * from "./fusion-environment.js";
12
13
  export * from "./repo-indexing.js";
13
14
  export * from "./organization.js";
14
15
  export * from "./features.js";