@machina.ai/cell-cli-core 1.49.0-rc5 → 1.50.0-rc1

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 (53) hide show
  1. package/dist/docs/CHANGES.md +23 -0
  2. package/dist/docs/adr/001-openai-xai-compatible-adapters.md +75 -0
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/package.json +1 -1
  7. package/dist/src/agents/agentLoader.d.ts +4 -4
  8. package/dist/src/code_assist/types.d.ts +20 -20
  9. package/dist/src/config/config.d.ts +9 -0
  10. package/dist/src/config/config.js +33 -0
  11. package/dist/src/config/config.js.map +1 -1
  12. package/dist/src/config/config.test.js +17 -6
  13. package/dist/src/config/config.test.js.map +1 -1
  14. package/dist/src/config/defaultModelConfigs.js +65 -4
  15. package/dist/src/config/defaultModelConfigs.js.map +1 -1
  16. package/dist/src/config/extensions/integrityTypes.d.ts +2 -2
  17. package/dist/src/config/flashFallback.test.js +14 -11
  18. package/dist/src/config/flashFallback.test.js.map +1 -1
  19. package/dist/src/config/localModel.test.d.ts +6 -0
  20. package/dist/src/config/localModel.test.js +114 -0
  21. package/dist/src/config/localModel.test.js.map +1 -0
  22. package/dist/src/config/models.d.ts +17 -1
  23. package/dist/src/config/models.js +75 -2
  24. package/dist/src/config/models.js.map +1 -1
  25. package/dist/src/config/models.test.js +48 -1
  26. package/dist/src/config/models.test.js.map +1 -1
  27. package/dist/src/core/baseLlmClient.js +26 -1
  28. package/dist/src/core/baseLlmClient.js.map +1 -1
  29. package/dist/src/core/contentGenerator.js +74 -1
  30. package/dist/src/core/contentGenerator.js.map +1 -1
  31. package/dist/src/core/contentGenerator.test.js +44 -0
  32. package/dist/src/core/contentGenerator.test.js.map +1 -1
  33. package/dist/src/core/openAiCompatibleContentGenerator.d.ts +156 -0
  34. package/dist/src/core/openAiCompatibleContentGenerator.js +1161 -0
  35. package/dist/src/core/openAiCompatibleContentGenerator.js.map +1 -0
  36. package/dist/src/core/openAiCompatibleContentGenerator.test.d.ts +6 -0
  37. package/dist/src/core/openAiCompatibleContentGenerator.test.js +850 -0
  38. package/dist/src/core/openAiCompatibleContentGenerator.test.js.map +1 -0
  39. package/dist/src/generated/git-commit.d.ts +2 -2
  40. package/dist/src/generated/git-commit.js +2 -2
  41. package/dist/src/index.d.ts +1 -0
  42. package/dist/src/index.js +1 -0
  43. package/dist/src/index.js.map +1 -1
  44. package/dist/src/routing/strategies/approvalModeStrategy.test.js +1 -1
  45. package/dist/src/utils/modelUtils.d.ts +8 -0
  46. package/dist/src/utils/modelUtils.js +59 -0
  47. package/dist/src/utils/modelUtils.js.map +1 -1
  48. package/dist/src/utils/modelUtils.test.js +46 -2
  49. package/dist/src/utils/modelUtils.test.js.map +1 -1
  50. package/dist/src/voice/whisperModelManager.js +2 -0
  51. package/dist/src/voice/whisperModelManager.js.map +1 -1
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +1 -1
@@ -123,6 +123,29 @@ stored separately in `config.yml`.
123
123
  device flow Keycloak (mensaje "Open URL..." al iniciar sesión) a stderr cuando
124
124
  el CLI corre con `--acp`, garantizando un stream stdout limpio.
125
125
 
126
+ ### 5. Universal OpenAI & xAI Compatibility Adapters under Keycloak SSO
127
+
128
+ - **Problem**: Cell CLI was designed to interface natively with Gemini models.
129
+ Environments utilizing OpenAI or xAI models under a unified Keycloak proxy
130
+ could not use the CLI.
131
+ - **Solution**: Implemented a universal, lightweight, and stateless
132
+ compatibility adapter (`OpenAiCompatibleContentGenerator`) that translates
133
+ Gemini-formatted contents, system instructions, and tool definitions into
134
+ OpenAI-compatible formats and parses standard OpenAI outputs back to Gemini
135
+ parts and usage metadata.
136
+ - **Key Improvements**:
137
+ - **Stateless Tool Call Correlation**: Reconstructs and matches multi-turn
138
+ tool call IDs (`call_0`, `call_1`, etc.) dynamically without requiring
139
+ session/state cache.
140
+ - **Recursive Schema Translation**: Automatically maps uppercase Gemini schema
141
+ types (`STRING`, `OBJECT`, etc.) to lowercase standards required by OpenAI.
142
+ - **SSE Streaming Support**: Fully supports real-time Server-Sent Events
143
+ stream chunk parsing and return.
144
+ - **Transparent Model Routing**: Seamlessly hooks into
145
+ `createContentGenerator` to route all Keycloak-authenticated requests with
146
+ model names formatted as `{provider}/{model}` (e.g., `openai/gpt-4o`,
147
+ `xai/grok-2`) directly to the compatibility adapter.
148
+
126
149
  ## Name and Variable Renaming
127
150
 
128
151
  The following table documents the major renaming changes from "Gemini" to "Cell"
@@ -0,0 +1,75 @@
1
+ # Universal OpenAI & xAI Compatibility Adapters under Keycloak SSO
2
+
3
+ - Status: Accepted
4
+ - Deciders: Cell CLI Core Team
5
+ - Date: 2026-07-11
6
+
7
+ ## Context and Problem Statement
8
+
9
+ Currently, Cell CLI interacts natively with Gemini models via the Google Gen AI
10
+ SDK. To enable organizations using OpenAI-compatible or xAI endpoints hosted
11
+ through unified Keycloak proxies to utilize Cell CLI, we need a universal,
12
+ stateless compatibility adapter.
13
+
14
+ All communication must flow exclusively through the configured Keycloak
15
+ authentication proxy, appending `/cell/{provider}/v1/chat/completions` to the
16
+ proxy's base URL and forwarding Keycloak SSO headers.
17
+
18
+ ## Decision Drivers
19
+
20
+ - **Zero State Retention:** The adapter must remain entirely stateless, avoiding
21
+ any cache or session storage between separate generator invocations to
22
+ maintain clean horizontal scalability and thread safety.
23
+ - **Payload Fidelity:** Convert Gemini-formatted prompts (system instructions,
24
+ user/model history, schemas, tool definitions) accurately to OpenAI-compatible
25
+ payloads, and parse standard OpenAI completions back to Gemini parts and usage
26
+ metadata.
27
+ - **De-novo Tool ID Correlation:** Map sequential `tool_call_id`s across
28
+ multi-turn histories during pure payload scans without persisting state.
29
+ - **Maintainability:** Minimal impact on the core Gemini engine; transparent
30
+ routing of provider-prefixed models.
31
+
32
+ ## Considered Options
33
+
34
+ 1. **Option 1: Add a native OpenAI SDK dependency**
35
+ - _Pros:_ Reuses official OpenAI client wrappers.
36
+ - _Cons:_ Significantly increases NPM package weight, introduces potential
37
+ dependency conflicts, and complicates stateless stream handling over the
38
+ unified Keycloak proxy.
39
+ 2. **Option 2: Stateless lightweight compatibility generator adapter (Chosen)**
40
+ - _Pros:_ Zero extra dependencies, fully stateless, lightweight (`fetch`
41
+ based), allows recursive, custom-tailored schema mappings and deterministic
42
+ multi-turn tool call correlation.
43
+ - _Cons:_ Requires manually maintaining payload translations for text, tools,
44
+ and streaming chunks.
45
+
46
+ ## Decision Outcome
47
+
48
+ We choose **Option 2: Stateless lightweight compatibility generator adapter**.
49
+
50
+ ### Implementation Details
51
+
52
+ - **Validation Bypass:** Allow model names formatted as `{provider}/{model}`
53
+ when configured with `AuthType.KEYCLOAK`.
54
+ - **Stateless Tool Call ID Correlation:** Reconstruct and match `tool_call_id`s
55
+ (`call_0`, `call_1`, ...) on every single payload scan by tracing
56
+ conversational history turns sequentially.
57
+ - **SSE Stream Parser:** Efficiently stream OpenAI Server-Sent Events, yielding
58
+ parsed completion chunks and formatting them back to Gemini-compatible
59
+ `GenerateContentResponse` shapes.
60
+
61
+ ## Pros and Cons of the Chosen Option
62
+
63
+ ### Pros
64
+
65
+ - Extends the CLI to support OpenAI and xAI out-of-the-box without increasing
66
+ bundle size.
67
+ - Purely functional, keeping the runtime footprint minimal and highly
68
+ thread-safe.
69
+ - Correctly aligns with the established composition/delegation architectural
70
+ principles of Cell CLI.
71
+
72
+ ### Cons
73
+
74
+ - Stream chunks must be parsed line-by-line which we resolved using a standard
75
+ TextDecoder buffer stream loop.
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export * from './src/index.js';
7
7
  export { Storage } from './src/config/storage.js';
8
- export { DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_MODEL_AUTO, AUTO_GEMINI_3_5_MODEL, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, DEFAULT_GEMINI_EMBEDDING_MODEL, GEMMA_4_31B_IT_MODEL, GEMMA_4_26B_A4B_IT_MODEL, GEMINI_3_5_FLASH_MODEL, } from './src/config/models.js';
8
+ export { DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_MODEL_AUTO, AUTO_GEMINI_3_5_MODEL, AUTO_GROK_4_5_MODEL, AUTO_GPT_5_6_FRONTIER_MODEL, AUTO_GPT_5_4_MODEL, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, DEFAULT_GEMINI_EMBEDDING_MODEL, GEMMA_4_31B_IT_MODEL, GEMMA_4_26B_A4B_IT_MODEL, GEMINI_3_5_FLASH_MODEL, } from './src/config/models.js';
9
9
  export { serializeTerminalToObject, type AnsiOutput, type AnsiLine, type AnsiToken, } from './src/utils/terminalSerializer.js';
10
10
  export { DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD } from './src/config/config.js';
11
11
  export { detectIdeFromEnv } from './src/ide/detect-ide.js';
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export * from './src/index.js';
7
7
  export { Storage } from './src/config/storage.js';
8
- export { DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_MODEL_AUTO, AUTO_GEMINI_3_5_MODEL, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, DEFAULT_GEMINI_EMBEDDING_MODEL, GEMMA_4_31B_IT_MODEL, GEMMA_4_26B_A4B_IT_MODEL, GEMINI_3_5_FLASH_MODEL, } from './src/config/models.js';
8
+ export { DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_MODEL_AUTO, AUTO_GEMINI_3_5_MODEL, AUTO_GROK_4_5_MODEL, AUTO_GPT_5_6_FRONTIER_MODEL, AUTO_GPT_5_4_MODEL, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, DEFAULT_GEMINI_EMBEDDING_MODEL, GEMMA_4_31B_IT_MODEL, GEMMA_4_26B_A4B_IT_MODEL, GEMINI_3_5_FLASH_MODEL, } from './src/config/models.js';
9
9
  export { serializeTerminalToObject, } from './src/utils/terminalSerializer.js';
10
10
  export { DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD } from './src/config/config.js';
11
11
  export { detectIdeFromEnv } from './src/ide/detect-ide.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,0BAA0B,EAC1B,+BAA+B,EAC/B,8BAA8B,EAC9B,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,yBAAyB,GAI1B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,sCAAsC,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AACzF,cAAc,kCAAkC,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,2BAA2B,EAC3B,kBAAkB,EAClB,0BAA0B,EAC1B,+BAA+B,EAC/B,8BAA8B,EAC9B,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,yBAAyB,GAI1B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,sCAAsC,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AACzF,cAAc,kCAAkC,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@machina.ai/cell-cli-core",
3
- "version": "1.49.0-rc5",
3
+ "version": "1.50.0-rc1",
4
4
  "description": "Cell CLI Core",
5
5
  "repository": {
6
6
  "type": "git",
@@ -97,8 +97,8 @@ declare const localAgentSchema: z.ZodObject<{
97
97
  stdio?: boolean | undefined;
98
98
  description?: string | undefined;
99
99
  timeout?: number | undefined;
100
- trust?: boolean | undefined;
101
100
  headers?: Record<string, string> | undefined;
101
+ trust?: boolean | undefined;
102
102
  auth?: {
103
103
  type: "google-credentials";
104
104
  scopes?: string[] | undefined;
@@ -129,8 +129,8 @@ declare const localAgentSchema: z.ZodObject<{
129
129
  stdio?: boolean | undefined;
130
130
  description?: string | undefined;
131
131
  timeout?: number | undefined;
132
- trust?: boolean | undefined;
133
132
  headers?: Record<string, string> | undefined;
133
+ trust?: boolean | undefined;
134
134
  auth?: {
135
135
  type: "google-credentials";
136
136
  scopes?: string[] | undefined;
@@ -174,8 +174,8 @@ declare const localAgentSchema: z.ZodObject<{
174
174
  stdio?: boolean | undefined;
175
175
  description?: string | undefined;
176
176
  timeout?: number | undefined;
177
- trust?: boolean | undefined;
178
177
  headers?: Record<string, string> | undefined;
178
+ trust?: boolean | undefined;
179
179
  auth?: {
180
180
  type: "google-credentials";
181
181
  scopes?: string[] | undefined;
@@ -217,8 +217,8 @@ declare const localAgentSchema: z.ZodObject<{
217
217
  stdio?: boolean | undefined;
218
218
  description?: string | undefined;
219
219
  timeout?: number | undefined;
220
- trust?: boolean | undefined;
221
220
  headers?: Record<string, string> | undefined;
221
+ trust?: boolean | undefined;
222
222
  auth?: {
223
223
  type: "google-credentials";
224
224
  scopes?: string[] | undefined;
@@ -304,6 +304,7 @@ export declare const RequiredMcpServerConfigSchema: z.ZodObject<{
304
304
  url: string;
305
305
  description?: string | undefined;
306
306
  timeout?: number | undefined;
307
+ headers?: Record<string, string> | undefined;
307
308
  trust?: boolean | undefined;
308
309
  includeTools?: string[] | undefined;
309
310
  excludeTools?: string[] | undefined;
@@ -315,12 +316,12 @@ export declare const RequiredMcpServerConfigSchema: z.ZodObject<{
315
316
  } | undefined;
316
317
  targetAudience?: string | undefined;
317
318
  targetServiceAccount?: string | undefined;
318
- headers?: Record<string, string> | undefined;
319
319
  }, {
320
320
  type: "http" | "sse";
321
321
  url: string;
322
322
  description?: string | undefined;
323
323
  timeout?: number | undefined;
324
+ headers?: Record<string, string> | undefined;
324
325
  trust?: boolean | undefined;
325
326
  includeTools?: string[] | undefined;
326
327
  excludeTools?: string[] | undefined;
@@ -332,7 +333,6 @@ export declare const RequiredMcpServerConfigSchema: z.ZodObject<{
332
333
  } | undefined;
333
334
  targetAudience?: string | undefined;
334
335
  targetServiceAccount?: string | undefined;
335
- headers?: Record<string, string> | undefined;
336
336
  }>;
337
337
  export type RequiredMcpServerConfig = z.infer<typeof RequiredMcpServerConfigSchema>;
338
338
  export declare const McpConfigDefinitionSchema: z.ZodObject<{
@@ -385,6 +385,7 @@ export declare const McpConfigDefinitionSchema: z.ZodObject<{
385
385
  url: string;
386
386
  description?: string | undefined;
387
387
  timeout?: number | undefined;
388
+ headers?: Record<string, string> | undefined;
388
389
  trust?: boolean | undefined;
389
390
  includeTools?: string[] | undefined;
390
391
  excludeTools?: string[] | undefined;
@@ -396,12 +397,12 @@ export declare const McpConfigDefinitionSchema: z.ZodObject<{
396
397
  } | undefined;
397
398
  targetAudience?: string | undefined;
398
399
  targetServiceAccount?: string | undefined;
399
- headers?: Record<string, string> | undefined;
400
400
  }, {
401
401
  type: "http" | "sse";
402
402
  url: string;
403
403
  description?: string | undefined;
404
404
  timeout?: number | undefined;
405
+ headers?: Record<string, string> | undefined;
405
406
  trust?: boolean | undefined;
406
407
  includeTools?: string[] | undefined;
407
408
  excludeTools?: string[] | undefined;
@@ -413,7 +414,6 @@ export declare const McpConfigDefinitionSchema: z.ZodObject<{
413
414
  } | undefined;
414
415
  targetAudience?: string | undefined;
415
416
  targetServiceAccount?: string | undefined;
416
- headers?: Record<string, string> | undefined;
417
417
  }>>>;
418
418
  }, "strip", z.ZodTypeAny, {
419
419
  mcpServers?: Record<string, {
@@ -428,6 +428,7 @@ export declare const McpConfigDefinitionSchema: z.ZodObject<{
428
428
  url: string;
429
429
  description?: string | undefined;
430
430
  timeout?: number | undefined;
431
+ headers?: Record<string, string> | undefined;
431
432
  trust?: boolean | undefined;
432
433
  includeTools?: string[] | undefined;
433
434
  excludeTools?: string[] | undefined;
@@ -439,7 +440,6 @@ export declare const McpConfigDefinitionSchema: z.ZodObject<{
439
440
  } | undefined;
440
441
  targetAudience?: string | undefined;
441
442
  targetServiceAccount?: string | undefined;
442
- headers?: Record<string, string> | undefined;
443
443
  }> | undefined;
444
444
  }, {
445
445
  mcpServers?: Record<string, {
@@ -454,6 +454,7 @@ export declare const McpConfigDefinitionSchema: z.ZodObject<{
454
454
  url: string;
455
455
  description?: string | undefined;
456
456
  timeout?: number | undefined;
457
+ headers?: Record<string, string> | undefined;
457
458
  trust?: boolean | undefined;
458
459
  includeTools?: string[] | undefined;
459
460
  excludeTools?: string[] | undefined;
@@ -465,7 +466,6 @@ export declare const McpConfigDefinitionSchema: z.ZodObject<{
465
466
  } | undefined;
466
467
  targetAudience?: string | undefined;
467
468
  targetServiceAccount?: string | undefined;
468
- headers?: Record<string, string> | undefined;
469
469
  }> | undefined;
470
470
  }>;
471
471
  export type McpConfigDefinition = z.infer<typeof McpConfigDefinitionSchema>;
@@ -523,6 +523,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
523
523
  url: string;
524
524
  description?: string | undefined;
525
525
  timeout?: number | undefined;
526
+ headers?: Record<string, string> | undefined;
526
527
  trust?: boolean | undefined;
527
528
  includeTools?: string[] | undefined;
528
529
  excludeTools?: string[] | undefined;
@@ -534,12 +535,12 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
534
535
  } | undefined;
535
536
  targetAudience?: string | undefined;
536
537
  targetServiceAccount?: string | undefined;
537
- headers?: Record<string, string> | undefined;
538
538
  }, {
539
539
  type: "http" | "sse";
540
540
  url: string;
541
541
  description?: string | undefined;
542
542
  timeout?: number | undefined;
543
+ headers?: Record<string, string> | undefined;
543
544
  trust?: boolean | undefined;
544
545
  includeTools?: string[] | undefined;
545
546
  excludeTools?: string[] | undefined;
@@ -551,7 +552,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
551
552
  } | undefined;
552
553
  targetAudience?: string | undefined;
553
554
  targetServiceAccount?: string | undefined;
554
- headers?: Record<string, string> | undefined;
555
555
  }>>>;
556
556
  }, "strip", z.ZodTypeAny, {
557
557
  mcpServers?: Record<string, {
@@ -566,6 +566,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
566
566
  url: string;
567
567
  description?: string | undefined;
568
568
  timeout?: number | undefined;
569
+ headers?: Record<string, string> | undefined;
569
570
  trust?: boolean | undefined;
570
571
  includeTools?: string[] | undefined;
571
572
  excludeTools?: string[] | undefined;
@@ -577,7 +578,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
577
578
  } | undefined;
578
579
  targetAudience?: string | undefined;
579
580
  targetServiceAccount?: string | undefined;
580
- headers?: Record<string, string> | undefined;
581
581
  }> | undefined;
582
582
  }, {
583
583
  mcpServers?: Record<string, {
@@ -592,6 +592,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
592
592
  url: string;
593
593
  description?: string | undefined;
594
594
  timeout?: number | undefined;
595
+ headers?: Record<string, string> | undefined;
595
596
  trust?: boolean | undefined;
596
597
  includeTools?: string[] | undefined;
597
598
  excludeTools?: string[] | undefined;
@@ -603,7 +604,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
603
604
  } | undefined;
604
605
  targetAudience?: string | undefined;
605
606
  targetServiceAccount?: string | undefined;
606
- headers?: Record<string, string> | undefined;
607
607
  }> | undefined;
608
608
  }>>;
609
609
  requiredMcpConfig: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -636,6 +636,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
636
636
  url: string;
637
637
  description?: string | undefined;
638
638
  timeout?: number | undefined;
639
+ headers?: Record<string, string> | undefined;
639
640
  trust?: boolean | undefined;
640
641
  includeTools?: string[] | undefined;
641
642
  excludeTools?: string[] | undefined;
@@ -647,12 +648,12 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
647
648
  } | undefined;
648
649
  targetAudience?: string | undefined;
649
650
  targetServiceAccount?: string | undefined;
650
- headers?: Record<string, string> | undefined;
651
651
  }, {
652
652
  type: "http" | "sse";
653
653
  url: string;
654
654
  description?: string | undefined;
655
655
  timeout?: number | undefined;
656
+ headers?: Record<string, string> | undefined;
656
657
  trust?: boolean | undefined;
657
658
  includeTools?: string[] | undefined;
658
659
  excludeTools?: string[] | undefined;
@@ -664,7 +665,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
664
665
  } | undefined;
665
666
  targetAudience?: string | undefined;
666
667
  targetServiceAccount?: string | undefined;
667
- headers?: Record<string, string> | undefined;
668
668
  }>>>;
669
669
  }, "strip", z.ZodTypeAny, {
670
670
  mcpEnabled?: boolean | undefined;
@@ -681,6 +681,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
681
681
  url: string;
682
682
  description?: string | undefined;
683
683
  timeout?: number | undefined;
684
+ headers?: Record<string, string> | undefined;
684
685
  trust?: boolean | undefined;
685
686
  includeTools?: string[] | undefined;
686
687
  excludeTools?: string[] | undefined;
@@ -692,7 +693,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
692
693
  } | undefined;
693
694
  targetAudience?: string | undefined;
694
695
  targetServiceAccount?: string | undefined;
695
- headers?: Record<string, string> | undefined;
696
696
  }> | undefined;
697
697
  } | undefined;
698
698
  requiredMcpConfig?: Record<string, {
@@ -700,6 +700,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
700
700
  url: string;
701
701
  description?: string | undefined;
702
702
  timeout?: number | undefined;
703
+ headers?: Record<string, string> | undefined;
703
704
  trust?: boolean | undefined;
704
705
  includeTools?: string[] | undefined;
705
706
  excludeTools?: string[] | undefined;
@@ -711,7 +712,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
711
712
  } | undefined;
712
713
  targetAudience?: string | undefined;
713
714
  targetServiceAccount?: string | undefined;
714
- headers?: Record<string, string> | undefined;
715
715
  }> | undefined;
716
716
  }, {
717
717
  mcpEnabled?: boolean | undefined;
@@ -728,6 +728,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
728
728
  url: string;
729
729
  description?: string | undefined;
730
730
  timeout?: number | undefined;
731
+ headers?: Record<string, string> | undefined;
731
732
  trust?: boolean | undefined;
732
733
  includeTools?: string[] | undefined;
733
734
  excludeTools?: string[] | undefined;
@@ -739,7 +740,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
739
740
  } | undefined;
740
741
  targetAudience?: string | undefined;
741
742
  targetServiceAccount?: string | undefined;
742
- headers?: Record<string, string> | undefined;
743
743
  }> | undefined;
744
744
  } | undefined;
745
745
  requiredMcpConfig?: Record<string, {
@@ -747,6 +747,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
747
747
  url: string;
748
748
  description?: string | undefined;
749
749
  timeout?: number | undefined;
750
+ headers?: Record<string, string> | undefined;
750
751
  trust?: boolean | undefined;
751
752
  includeTools?: string[] | undefined;
752
753
  excludeTools?: string[] | undefined;
@@ -758,7 +759,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
758
759
  } | undefined;
759
760
  targetAudience?: string | undefined;
760
761
  targetServiceAccount?: string | undefined;
761
- headers?: Record<string, string> | undefined;
762
762
  }> | undefined;
763
763
  }>>;
764
764
  cliFeatureSetting: z.ZodOptional<z.ZodObject<{
@@ -798,6 +798,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
798
798
  url: string;
799
799
  description?: string | undefined;
800
800
  timeout?: number | undefined;
801
+ headers?: Record<string, string> | undefined;
801
802
  trust?: boolean | undefined;
802
803
  includeTools?: string[] | undefined;
803
804
  excludeTools?: string[] | undefined;
@@ -809,7 +810,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
809
810
  } | undefined;
810
811
  targetAudience?: string | undefined;
811
812
  targetServiceAccount?: string | undefined;
812
- headers?: Record<string, string> | undefined;
813
813
  }> | undefined;
814
814
  } | undefined;
815
815
  requiredMcpConfig?: Record<string, {
@@ -817,6 +817,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
817
817
  url: string;
818
818
  description?: string | undefined;
819
819
  timeout?: number | undefined;
820
+ headers?: Record<string, string> | undefined;
820
821
  trust?: boolean | undefined;
821
822
  includeTools?: string[] | undefined;
822
823
  excludeTools?: string[] | undefined;
@@ -828,7 +829,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
828
829
  } | undefined;
829
830
  targetAudience?: string | undefined;
830
831
  targetServiceAccount?: string | undefined;
831
- headers?: Record<string, string> | undefined;
832
832
  }> | undefined;
833
833
  } | undefined;
834
834
  cliFeatureSetting?: {
@@ -854,6 +854,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
854
854
  url: string;
855
855
  description?: string | undefined;
856
856
  timeout?: number | undefined;
857
+ headers?: Record<string, string> | undefined;
857
858
  trust?: boolean | undefined;
858
859
  includeTools?: string[] | undefined;
859
860
  excludeTools?: string[] | undefined;
@@ -865,7 +866,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
865
866
  } | undefined;
866
867
  targetAudience?: string | undefined;
867
868
  targetServiceAccount?: string | undefined;
868
- headers?: Record<string, string> | undefined;
869
869
  }> | undefined;
870
870
  } | undefined;
871
871
  requiredMcpConfig?: Record<string, {
@@ -873,6 +873,7 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
873
873
  url: string;
874
874
  description?: string | undefined;
875
875
  timeout?: number | undefined;
876
+ headers?: Record<string, string> | undefined;
876
877
  trust?: boolean | undefined;
877
878
  includeTools?: string[] | undefined;
878
879
  excludeTools?: string[] | undefined;
@@ -884,7 +885,6 @@ export declare const AdminControlsSettingsSchema: z.ZodObject<{
884
885
  } | undefined;
885
886
  targetAudience?: string | undefined;
886
887
  targetServiceAccount?: string | undefined;
887
- headers?: Record<string, string> | undefined;
888
888
  }> | undefined;
889
889
  } | undefined;
890
890
  cliFeatureSetting?: {
@@ -461,6 +461,8 @@ export interface ConfigParameters {
461
461
  includeDirectories?: string[];
462
462
  bugCommand?: BugCommandSettings;
463
463
  model: string;
464
+ localModelUrl?: string;
465
+ localModelApiKey?: string;
464
466
  disableLoopDetection?: boolean;
465
467
  maxSessionTurns?: number;
466
468
  acpMode?: boolean;
@@ -556,6 +558,7 @@ export interface ConfigParameters {
556
558
  worktreeSettings?: WorktreeSettings;
557
559
  modelSteering?: boolean;
558
560
  onModelChange?: (model: string) => void;
561
+ onLocalModelConfigChange?: (url: string | undefined, apiKey: string | undefined) => void;
559
562
  mcpEnabled?: boolean;
560
563
  extensionsEnabled?: boolean;
561
564
  agents?: AgentSettings;
@@ -644,6 +647,8 @@ export declare class Config implements McpContext, AgentLoopContext {
644
647
  private readonly cwd;
645
648
  private readonly bugCommand;
646
649
  private model;
650
+ private localModelUrl?;
651
+ private localModelApiKey?;
647
652
  private readonly disableLoopDetection;
648
653
  private hasAccessToPreviewModel;
649
654
  private readonly noBrowser;
@@ -731,6 +736,7 @@ export declare class Config implements McpContext, AgentLoopContext {
731
736
  private experimentsPromise;
732
737
  private hookSystem?;
733
738
  private readonly onModelChange;
739
+ private readonly onLocalModelConfigChange;
734
740
  private readonly onReload;
735
741
  private readonly billing;
736
742
  private readonly vertexAiRouting;
@@ -826,6 +832,9 @@ export declare class Config implements McpContext, AgentLoopContext {
826
832
  getDiscoveryMaxDirs(): number;
827
833
  getContentGeneratorConfig(): ContentGeneratorConfig;
828
834
  getModel(): string;
835
+ getLocalModelUrl(): string | undefined;
836
+ getLocalModelApiKey(): string | undefined;
837
+ setLocalModelConfig(url: string | undefined, apiKey: string | undefined, isTemporary?: boolean): void;
829
838
  getDisableLoopDetection(): boolean;
830
839
  setModel(newModel: string, isTemporary?: boolean): void;
831
840
  activateFallbackMode(model: string, failedModel?: string): void;
@@ -277,6 +277,8 @@ export class Config {
277
277
  cwd;
278
278
  bugCommand;
279
279
  model;
280
+ localModelUrl;
281
+ localModelApiKey;
280
282
  disableLoopDetection;
281
283
  // null = unknown (quota not fetched); true = has access; false = definitively no access
282
284
  hasAccessToPreviewModel = null;
@@ -375,6 +377,7 @@ export class Config {
375
377
  experimentsPromise;
376
378
  hookSystem;
377
379
  onModelChange;
380
+ onLocalModelConfigChange;
378
381
  onReload;
379
382
  billing;
380
383
  vertexAiRouting;
@@ -522,6 +525,8 @@ export class Config {
522
525
  this.fileDiscoveryService = params.fileDiscoveryService ?? null;
523
526
  this.bugCommand = params.bugCommand;
524
527
  this.model = params.model;
528
+ this.localModelUrl = params.localModelUrl;
529
+ this.localModelApiKey = params.localModelApiKey;
525
530
  this.disableLoopDetection = params.disableLoopDetection ?? false;
526
531
  this._activeModel = params.model;
527
532
  this.enableAgents = params.enableAgents ?? true;
@@ -749,6 +754,7 @@ export class Config {
749
754
  }
750
755
  this.experiments = params.experiments;
751
756
  this.onModelChange = params.onModelChange;
757
+ this.onLocalModelConfigChange = params.onLocalModelConfigChange;
752
758
  this.onReload = params.onReload;
753
759
  this.billing = {
754
760
  overageStrategy: params.billing?.overageStrategy ?? 'ask',
@@ -1146,6 +1152,19 @@ export class Config {
1146
1152
  getModel() {
1147
1153
  return this.model;
1148
1154
  }
1155
+ getLocalModelUrl() {
1156
+ return this.localModelUrl;
1157
+ }
1158
+ getLocalModelApiKey() {
1159
+ return this.localModelApiKey;
1160
+ }
1161
+ setLocalModelConfig(url, apiKey, isTemporary = true) {
1162
+ this.localModelUrl = url;
1163
+ this.localModelApiKey = apiKey;
1164
+ if (this.onLocalModelConfigChange && !isTemporary) {
1165
+ this.onLocalModelConfigChange(url, apiKey);
1166
+ }
1167
+ }
1149
1168
  getDisableLoopDetection() {
1150
1169
  return this.disableLoopDetection ?? false;
1151
1170
  }
@@ -1158,6 +1177,20 @@ export class Config {
1158
1177
  this.lastEmittedQuotaRemaining = undefined;
1159
1178
  this.lastEmittedQuotaLimit = undefined;
1160
1179
  this.emitQuotaChangedEvent();
1180
+ if (this.contentGeneratorConfig) {
1181
+ // Promise.resolve normalizes both real async returns and test mocks
1182
+ // that may return a bare value/undefined.
1183
+ void Promise.resolve(createContentGenerator(this.contentGeneratorConfig, this, this.getSessionId()))
1184
+ .then((generator) => {
1185
+ if (generator) {
1186
+ this.contentGenerator = generator;
1187
+ this.baseLlmClient = new BaseLlmClient(generator, this);
1188
+ }
1189
+ })
1190
+ .catch((err) => {
1191
+ debugLogger.error('Failed to recreate content generator on model change', err);
1192
+ });
1193
+ }
1161
1194
  }
1162
1195
  if (this.onModelChange && !isTemporary) {
1163
1196
  this.onModelChange(newModel);