Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3ebe580
Add quick support for ollama and litert-lm router inference with gemm…
sidwan02 Jan 21, 2026
2d47336
Remove ollama router and modularize liter-lm router into new gemma cl…
sidwan02 Jan 21, 2026
222ae37
Simplify gemmaModelRouter experimental setting to implicitly use lite…
sidwan02 Jan 21, 2026
4bed6b9
Add engineered gemma classifier system prompt and reminder + router c…
sidwan02 Jan 21, 2026
06e8059
Flatten chat history in gemma Classifier for much better performance.
sidwan02 Jan 21, 2026
04aab94
In Gemma router fix TCP timeout if litert-lm shim is started but wron…
sidwan02 Jan 21, 2026
4dbce54
Add tests for Gemma router and LiteRT services + simplify flatten cha…
sidwan02 Feb 5, 2026
8e22c16
Add tests for gemma model router settings.
sidwan02 Feb 5, 2026
f556d5b
Remove unused ollama and reminder prompt config dependencies
sidwan02 Feb 5, 2026
c9f8b57
Update gemma model router classifier defaults to latest host and mode…
sidwan02 Feb 5, 2026
960a6f4
Clean up router logs and debug chat history file
sidwan02 Feb 6, 2026
393b266
Simplify local gemini client API call to litert-lm shim
sidwan02 Feb 6, 2026
3d5ab14
Simplify gemma response cleaning with jsonrepair
sidwan02 Feb 6, 2026
13ee548
gemma router invalid/undownloaded model is handled by the litert-lm s…
sidwan02 Feb 6, 2026
3b32f57
Delete temp dev files and fix gitignore
sidwan02 Feb 6, 2026
4b06d45
fix incorrect call to resolveClassifierModel in gemma classifier stra…
sidwan02 Feb 8, 2026
9edc0a1
npm preflight passing, setting and docs updated
sidwan02 Feb 8, 2026
1a58a29
remove skills and gemma model router from default settings json
sidwan02 Feb 8, 2026
80e96f7
rename localGeminiClient to localLiteRtLmClient
sidwan02 Feb 8, 2026
8aec362
Defaults for gemma model router are not re-checked in the litert lm c…
sidwan02 Feb 8, 2026
651471e
Lazily initialize litertlm client and reuse in new calls to gemma router
sidwan02 Feb 8, 2026
ba64940
Remove prompt duplication between gemma3:1b system prompt and reminder
sidwan02 Feb 8, 2026
41333cb
gemma classifier prompt filters out non text parts
sidwan02 Feb 9, 2026
9810bdb
Propagate abort signal to litertlm client in gemma classifier
sidwan02 Feb 9, 2026
e38f5a1
Retire jsonrepair in client (shim handles this) + add comment explain…
sidwan02 Feb 18, 2026
6c9e650
Update tests for gemmaClassifierStrategy and localLiteRtLmClient to h…
sidwan02 Feb 18, 2026
b1d8834
Update gemma router documentation with requirements and alerts
sidwan02 Feb 18, 2026
6d48b06
Only allow gemma3-1b-gpu-custom to be set for gemma model router.
sidwan02 Feb 19, 2026
fca16d8
Reset package-lock.json and vitest.config.ts
sidwan02 Feb 19, 2026
a98e133
Merge branch 'synced' into gemma-router-pr
sidwan02 Feb 26, 2026
c7a0b7e
Final test fixes with preflight
sidwan02 Feb 26, 2026
1e85554
Merge branch 'main' into gemma-router-pr
sidwan02 Feb 26, 2026
7ab16b7
Merge branch 'main' into gemma-router-pr
allenhutchison Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/cli/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ they appear in the UI.
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
| Model Steering | `experimental.modelSteering` | Enable model steering (user hints) to guide the model during tool execution. | `false` |
| Direct Web Fetch | `experimental.directWebFetch` | Enable web fetch behavior that bypasses LLM summarization. | `false` |
| Enable Gemma Model Router | `experimental.gemmaModelRouter.enabled` | Enable the Gemma Model Router. Requires a local endpoint serving Gemma via the Gemini API using LiteRT-LM shim. | `false` |

### Skills

Expand Down
17 changes: 17 additions & 0 deletions docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,23 @@ their corresponding top-level category object in your `settings.json` file.
- **Default:** `false`
- **Requires restart:** Yes

- **`experimental.gemmaModelRouter.enabled`** (boolean):
- **Description:** Enable the Gemma Model Router. Requires a local endpoint
serving Gemma via the Gemini API using LiteRT-LM shim.
- **Default:** `false`
- **Requires restart:** Yes

- **`experimental.gemmaModelRouter.classifier.host`** (string):
- **Description:** The host of the classifier.
- **Default:** `"http://localhost:9379"`
- **Requires restart:** Yes

- **`experimental.gemmaModelRouter.classifier.model`** (string):
- **Description:** The model to use for the classifier. Only tested on
`gemma3-1b-gpu-custom`.
- **Default:** `"gemma3-1b-gpu-custom"`
- **Requires restart:** Yes

#### `skills`

- **`skills.enabled`** (boolean):
Expand Down
26 changes: 1 addition & 25 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions packages/cli/src/config/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2765,6 +2765,66 @@ describe('loadCliConfig approval mode', () => {
});
});

describe('loadCliConfig gemmaModelRouter', () => {
beforeEach(() => {
vi.resetAllMocks();
vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
});

afterEach(() => {
vi.unstubAllEnvs();
vi.restoreAllMocks();
});

it('should have gemmaModelRouter disabled by default', async () => {
process.argv = ['node', 'script.js'];
const argv = await parseArguments(createTestMergedSettings());
const settings = createTestMergedSettings();
const config = await loadCliConfig(settings, 'test-session', argv);
expect(config.getGemmaModelRouterEnabled()).toBe(false);
});

it('should load gemmaModelRouter settings from merged settings', async () => {
process.argv = ['node', 'script.js'];
const argv = await parseArguments(createTestMergedSettings());
const settings = createTestMergedSettings({
experimental: {
gemmaModelRouter: {
enabled: true,
classifier: {
host: 'http://custom:1234',
model: 'custom-gemma',
},
},
},
});
const config = await loadCliConfig(settings, 'test-session', argv);
expect(config.getGemmaModelRouterEnabled()).toBe(true);
const gemmaSettings = config.getGemmaModelRouterSettings();
expect(gemmaSettings.classifier?.host).toBe('http://custom:1234');
expect(gemmaSettings.classifier?.model).toBe('custom-gemma');
});

it('should handle partial gemmaModelRouter settings', async () => {
process.argv = ['node', 'script.js'];
const argv = await parseArguments(createTestMergedSettings());
const settings = createTestMergedSettings({
experimental: {
gemmaModelRouter: {
enabled: true,
},
},
});
const config = await loadCliConfig(settings, 'test-session', argv);
expect(config.getGemmaModelRouterEnabled()).toBe(true);
const gemmaSettings = config.getGemmaModelRouterSettings();
expect(gemmaSettings.classifier?.host).toBe('http://localhost:9379');
expect(gemmaSettings.classifier?.model).toBe('gemma3-1b-gpu-custom');
});
});

describe('loadCliConfig fileFiltering', () => {
const originalArgv = process.argv;

Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ export async function loadCliConfig(
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
format: (argv.outputFormat ?? settings.output?.format) as OutputFormat,
},
gemmaModelRouter: settings.experimental?.gemmaModelRouter,
fakeResponses: argv.fakeResponses,
recordResponses: argv.recordResponses,
retryFetchErrors: settings.general?.retryFetchErrors,
Expand Down
54 changes: 54 additions & 0 deletions packages/cli/src/config/settingsSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,60 @@ describe('SettingsSchema', () => {
expect(hookItemProperties.description).toBeDefined();
expect(hookItemProperties.description.type).toBe('string');
});

it('should have gemmaModelRouter setting in schema', () => {
const gemmaModelRouter =
getSettingsSchema().experimental.properties.gemmaModelRouter;
expect(gemmaModelRouter).toBeDefined();
expect(gemmaModelRouter.type).toBe('object');
expect(gemmaModelRouter.category).toBe('Experimental');
expect(gemmaModelRouter.default).toEqual({});
expect(gemmaModelRouter.requiresRestart).toBe(true);
expect(gemmaModelRouter.showInDialog).toBe(true);
expect(gemmaModelRouter.description).toBe(
'Enable Gemma model router (experimental).',
);

const enabled = gemmaModelRouter.properties.enabled;
expect(enabled).toBeDefined();
expect(enabled.type).toBe('boolean');
expect(enabled.category).toBe('Experimental');
expect(enabled.default).toBe(false);
expect(enabled.requiresRestart).toBe(true);
expect(enabled.showInDialog).toBe(true);
expect(enabled.description).toBe(
'Enable the Gemma Model Router. Requires a local endpoint serving Gemma via the Gemini API using LiteRT-LM shim.',
);

const classifier = gemmaModelRouter.properties.classifier;
expect(classifier).toBeDefined();
expect(classifier.type).toBe('object');
expect(classifier.category).toBe('Experimental');
expect(classifier.default).toEqual({});
expect(classifier.requiresRestart).toBe(true);
expect(classifier.showInDialog).toBe(false);
expect(classifier.description).toBe('Classifier configuration.');

const host = classifier.properties.host;
expect(host).toBeDefined();
expect(host.type).toBe('string');
expect(host.category).toBe('Experimental');
expect(host.default).toBe('http://localhost:9379');
expect(host.requiresRestart).toBe(true);
expect(host.showInDialog).toBe(false);
expect(host.description).toBe('The host of the classifier.');

const model = classifier.properties.model;
expect(model).toBeDefined();
expect(model.type).toBe('string');
expect(model.category).toBe('Experimental');
expect(model.default).toBe('gemma3-1b-gpu-custom');
expect(model.requiresRestart).toBe(true);
expect(model.showInDialog).toBe(false);
expect(model.description).toBe(
'The model to use for the classifier. Only tested on `gemma3-1b-gpu-custom`.',
);
});
});

it('has JSON schema definitions for every referenced ref', () => {
Expand Down
Loading
Loading