44 * Creates a client that matches the AppRouter interface with configurable mock data.
55 */
66import type { APIClient } from "@/browser/contexts/API" ;
7+ import type { AgentDefinitionDescriptor , AgentDefinitionPackage } from "@/common/types/agentDefinition" ;
78import type { FrontendWorkspaceMetadata } from "@/common/types/workspace" ;
89import type { ProjectConfig } from "@/node/config" ;
910import type {
@@ -25,6 +26,7 @@ import {
2526 normalizeModeAiDefaults ,
2627 type ModeAiDefaults ,
2728} from "@/common/types/modeAiDefaults" ;
29+ import { normalizeAgentAiDefaults , type AgentAiDefaults } from "@/common/types/agentAiDefaults" ;
2830import { createAsyncMessageQueue } from "@/common/utils/asyncMessageQueue" ;
2931import { isWorkspaceArchived } from "@/common/utils/archive" ;
3032
@@ -63,6 +65,10 @@ export interface MockORPCClientOptions {
6365 taskSettings ?: Partial < TaskSettings > ;
6466 /** Initial mode AI defaults for config.getConfig (e.g., Settings → Modes section) */
6567 modeAiDefaults ?: ModeAiDefaults ;
68+ /** Initial unified AI defaults for agents (plan/exec/compact + subagents) */
69+ agentAiDefaults ?: AgentAiDefaults ;
70+ /** Agent definitions to expose via agents.list */
71+ agentDefinitions ?: AgentDefinitionDescriptor [ ] ;
6672 /** Initial per-subagent AI defaults for config.getConfig (e.g., Settings → Tasks section) */
6773 subagentAiDefaults ?: SubagentAiDefaults ;
6874 /** Per-workspace chat callback. Return messages to emit, or use the callback for streaming. */
@@ -148,6 +154,8 @@ export function createMockORPCClient(options: MockORPCClientOptions = {}): APICl
148154 taskSettings : initialTaskSettings ,
149155 modeAiDefaults : initialModeAiDefaults ,
150156 subagentAiDefaults : initialSubagentAiDefaults ,
157+ agentAiDefaults : initialAgentAiDefaults ,
158+ agentDefinitions : initialAgentDefinitions ,
151159 } = options ;
152160
153161 // Feature flags
@@ -165,9 +173,78 @@ export function createMockORPCClient(options: MockORPCClientOptions = {}): APICl
165173 } ;
166174
167175 const workspaceMap = new Map ( workspaces . map ( ( w ) => [ w . id , w ] ) ) ;
168- let modeAiDefaults = normalizeModeAiDefaults ( initialModeAiDefaults ?? { } ) ;
176+
177+ const agentDefinitions : AgentDefinitionDescriptor [ ] =
178+ initialAgentDefinitions ??
179+ ( [
180+ {
181+ id : "plan" ,
182+ scope : "built-in" ,
183+ name : "Plan" ,
184+ description : "Create a plan before coding" ,
185+ uiSelectable : true ,
186+ subagentRunnable : false ,
187+ policyBase : "plan" ,
188+ } ,
189+ {
190+ id : "exec" ,
191+ scope : "built-in" ,
192+ name : "Exec" ,
193+ description : "Implement changes in the repository" ,
194+ uiSelectable : true ,
195+ subagentRunnable : true ,
196+ policyBase : "exec" ,
197+ } ,
198+ {
199+ id : "compact" ,
200+ scope : "built-in" ,
201+ name : "Compact" ,
202+ description : "History compaction (internal)" ,
203+ uiSelectable : false ,
204+ subagentRunnable : false ,
205+ policyBase : "compact" ,
206+ } ,
207+ {
208+ id : "explore" ,
209+ scope : "built-in" ,
210+ name : "Explore" ,
211+ description : "Read-only repository exploration" ,
212+ uiSelectable : false ,
213+ subagentRunnable : true ,
214+ policyBase : "exec" ,
215+ } ,
216+ ] satisfies AgentDefinitionDescriptor [ ] ) ;
217+
169218 let taskSettings = normalizeTaskSettings ( initialTaskSettings ?? DEFAULT_TASK_SETTINGS ) ;
170- let subagentAiDefaults = normalizeSubagentAiDefaults ( initialSubagentAiDefaults ?? { } ) ;
219+
220+ let agentAiDefaults = normalizeAgentAiDefaults (
221+ initialAgentAiDefaults ??
222+ ( {
223+ ...( initialSubagentAiDefaults ?? { } ) ,
224+ ...( initialModeAiDefaults ?? { } ) ,
225+ } as const )
226+ ) ;
227+
228+ const deriveModeAiDefaults = ( ) =>
229+ normalizeModeAiDefaults ( {
230+ plan : agentAiDefaults . plan ,
231+ exec : agentAiDefaults . exec ,
232+ compact : agentAiDefaults . compact ,
233+ } ) ;
234+
235+ const deriveSubagentAiDefaults = ( ) => {
236+ const raw : Record < string , unknown > = { } ;
237+ for ( const [ agentId , entry ] of Object . entries ( agentAiDefaults ) ) {
238+ if ( agentId === "plan" || agentId === "exec" || agentId === "compact" ) {
239+ continue ;
240+ }
241+ raw [ agentId ] = entry ;
242+ }
243+ return normalizeSubagentAiDefaults ( raw ) ;
244+ } ;
245+
246+ let modeAiDefaults = deriveModeAiDefaults ( ) ;
247+ let subagentAiDefaults = deriveSubagentAiDefaults ( ) ;
171248
172249 const mockStats : ChatStats = {
173250 consumers : [ ] ,
@@ -201,19 +278,69 @@ export function createMockORPCClient(options: MockORPCClientOptions = {}): APICl
201278 setSshHost : async ( ) => undefined ,
202279 } ,
203280 config : {
204- getConfig : async ( ) => ( { taskSettings, subagentAiDefaults, modeAiDefaults } ) ,
205- saveConfig : async ( input : { taskSettings : unknown ; subagentAiDefaults ?: unknown } ) => {
281+ getConfig : async ( ) => ( { taskSettings, agentAiDefaults, subagentAiDefaults, modeAiDefaults } ) ,
282+ saveConfig : async ( input : {
283+ taskSettings : unknown ;
284+ agentAiDefaults ?: unknown ;
285+ subagentAiDefaults ?: unknown ;
286+ } ) => {
206287 taskSettings = normalizeTaskSettings ( input . taskSettings ) ;
288+
289+ if ( input . agentAiDefaults !== undefined ) {
290+ agentAiDefaults = normalizeAgentAiDefaults ( input . agentAiDefaults ) ;
291+ modeAiDefaults = deriveModeAiDefaults ( ) ;
292+ subagentAiDefaults = deriveSubagentAiDefaults ( ) ;
293+ }
294+
207295 if ( input . subagentAiDefaults !== undefined ) {
208296 subagentAiDefaults = normalizeSubagentAiDefaults ( input . subagentAiDefaults ) ;
297+
298+ const nextAgentAiDefaults : Record < string , unknown > = { ...agentAiDefaults } ;
299+ for ( const [ agentType , entry ] of Object . entries ( subagentAiDefaults ) ) {
300+ nextAgentAiDefaults [ agentType ] = entry ;
301+ }
302+
303+ agentAiDefaults = normalizeAgentAiDefaults ( nextAgentAiDefaults ) ;
304+ modeAiDefaults = deriveModeAiDefaults ( ) ;
209305 }
306+
307+ return undefined ;
308+ } ,
309+ updateAgentAiDefaults : async ( input : { agentAiDefaults : unknown } ) => {
310+ agentAiDefaults = normalizeAgentAiDefaults ( input . agentAiDefaults ) ;
311+ modeAiDefaults = deriveModeAiDefaults ( ) ;
312+ subagentAiDefaults = deriveSubagentAiDefaults ( ) ;
210313 return undefined ;
211314 } ,
212315 updateModeAiDefaults : async ( input : { modeAiDefaults : unknown } ) => {
213316 modeAiDefaults = normalizeModeAiDefaults ( input . modeAiDefaults ) ;
317+ agentAiDefaults = normalizeAgentAiDefaults ( { ...agentAiDefaults , ...modeAiDefaults } ) ;
318+ modeAiDefaults = deriveModeAiDefaults ( ) ;
319+ subagentAiDefaults = deriveSubagentAiDefaults ( ) ;
214320 return undefined ;
215321 } ,
216322 } ,
323+ agents : {
324+ list : async ( _input : { workspaceId : string } ) => agentDefinitions ,
325+ get : async ( input : { workspaceId : string ; agentId : string } ) => {
326+ const descriptor =
327+ agentDefinitions . find ( ( agent ) => agent . id === input . agentId ) ?? agentDefinitions [ 0 ] ;
328+
329+ return {
330+ id : descriptor . id ,
331+ scope : descriptor . scope ,
332+ frontmatter : {
333+ name : descriptor . name ,
334+ description : descriptor . description ,
335+ ui : { selectable : descriptor . uiSelectable } ,
336+ subagent : { runnable : descriptor . subagentRunnable } ,
337+ ai : descriptor . aiDefaults ,
338+ policy : { base : descriptor . policyBase , tools : descriptor . toolFilter } ,
339+ } ,
340+ body : "" ,
341+ } satisfies AgentDefinitionPackage ;
342+ } ,
343+ } ,
217344 providers : {
218345 list : async ( ) => providersList ,
219346 getConfig : async ( ) => providersConfig ,
0 commit comments