Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"./llm-connections": "./dist/llm-connections.js",
"./provider-registry": "./dist/provider-registry.js",
"./model-catalog": "./dist/model-catalog.js",
"./model-facts": "./dist/model-facts.js",
"./model-metadata": "./dist/model-metadata.js",
"./model-web-search": "./dist/model-web-search.js",
"./model-thinking": "./dist/model-thinking.js",
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/__tests__/llm-connections.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,33 @@ test('model reconciliation never invents a default the user cleared', () => {
);
});

test('model reconciliation preserves enabled model-fact overrides outside live inventory', () => {
assert.deepEqual(
reconcileConnectionAfterModelFetch(
{
defaultModel: 'custom-model',
enabledModelIds: ['custom-model'],
hasModelInventory: true,
},
[{ id: 'live-model' }],
{ factBackedModelIds: new Set(['custom-model']) },
),
{ defaultModel: 'custom-model', enabledModelIds: ['custom-model'] },
);
assert.deepEqual(
reconcileConnectionAfterModelFetch(
{
defaultModel: 'live-model',
enabledModelIds: ['live-model', 'custom-model'],
hasModelInventory: true,
},
[{ id: 'live-model' }, { id: 'other-live-model' }],
{ factBackedModelIds: new Set(['custom-model']) },
),
{ defaultModel: 'live-model', enabledModelIds: ['live-model', 'custom-model'] },
);
});

test('a renamed id follows its model, and only for a caller that supplies the table', () => {
const curated = [{ id: 'claude-opus-5' }, { id: 'claude-haiku-4-5' }];
const stored = {
Expand Down
111 changes: 111 additions & 0 deletions packages/core/src/__tests__/model-catalog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,72 @@ test('every picker sees a model the user enabled but no catalog describes', () =
assert.deepEqual(declared?.provenance.sources?.userChoice, ['saved_model']);
});

test('catalog provenance follows the projected model facts marker used in production', () => {
const [entry] = buildConnectionModelCatalogEntries({
connection: {
slug: 'facts',
providerType: 'openai',
defaultModel: 'custom-model',
models: [
{
id: 'custom-model',
contextWindow: 200_000,
capabilities: { chat: true },
factOverriddenFields: ['contextWindow', 'capabilities'],
},
],
modelSource: 'fetched',
},
});
assert.equal(entry?.capabilitySource, 'user_override');
assert.equal(entry?.contextWindow, 200_000);
});

test('fallback provider catalogs include projected facts-backed models', () => {
const entries = buildConnectionModelCatalogEntries({
connection: {
slug: 'opencode-free-facts',
providerType: 'opencode-free',
defaultModel: 'custom-free-model',
models: [
{
id: 'custom-free-model',
contextWindow: 128_000,
factOverriddenFields: ['contextWindow', 'capabilities'],
},
],
modelSource: 'fallback',
},
});
const entry = entries.find((candidate) => candidate.id === 'custom-free-model');
assert.equal(entry?.contextWindow, 128_000);
assert.equal(entry?.capabilitySource, 'user_override');
});

test('fallback provider catalogs apply facts to known fallback models', () => {
const entries = buildConnectionModelCatalogEntries({
connection: {
slug: 'opencode-free-known-facts',
providerType: 'opencode-free',
defaultModel: 'nemotron-3-ultra-free',
models: [
{
id: 'nemotron-3-ultra-free',
contextWindow: 200_000,
inputLimit: 200_000,
capabilities: { chat: true },
factOverriddenFields: ['contextWindow', 'inputLimit', 'capabilities'],
},
],
modelSource: 'fallback',
},
});
const entry = entries.find((candidate) => candidate.id === 'nemotron-3-ultra-free');
assert.equal(entry?.contextWindow, 200_000);
assert.equal(entry?.inputLimit, 200_000);
assert.equal(entry?.capabilitySource, 'user_override');
});

test('unknown persisted provider ids return an empty catalog', () => {
assert.deepEqual(
buildConnectionModelCatalogEntries({
Expand Down Expand Up @@ -351,3 +417,48 @@ test('Alibaba (China) catalogs Qwen3.8 Max as the default model on the China end
assert.deepEqual(model?.modalities, { input: ['text', 'image', 'pdf'], output: ['text'] });
assert.equal(model?.canUseAsChatDefault, true);
});

test('saved model choices can materialize a user fact override without exposing unrelated entries', () => {
const entries = buildConnectionModelCatalogEntries({
connection: {
slug: 'zai-live',
providerType: 'zai-coding-plan',
defaultModel: 'glm-4.7',
models: [{ id: 'glm-4.7' }],
modelSource: 'fetched',
},
savedModelIds: [{ id: 'saved-custom', source: 'session_model' }],
modelFactOverrides: {
'zai-coding-plan:saved-custom': {
displayName: 'Saved Custom',
contextWindow: 88_000,
knowledgeCutoff: '2026-01-01',
structuredOutput: true,
lastUpdated: '2026-02-01',
modalities: { input: ['text'], output: ['text'] },
},
'zai-coding-plan:hidden': { contextWindow: 1_000 },
},
});
const saved = entries.find((entry) => entry.id === 'saved-custom');
assert.equal(saved?.displayName, 'Saved Custom');
assert.equal(saved?.contextWindow, 88_000);
assert.equal(saved?.knowledgeCutoff, '2026-01-01');
assert.equal(saved?.structuredOutput, true);
assert.equal(saved?.lastUpdated, '2026-02-01');
assert.deepEqual(saved?.modalities, { input: ['text'], output: ['text'] });
assert.equal(
entries.some((entry) => entry.id === 'hidden'),
false,
);
});

test('catalog capability merges retain provider web search facts alongside overrides', () => {
const entries = buildModelCatalogEntries({
providerType: 'deepseek',
models: [{ id: 'deepseek-v4-flash', capabilities: { webSearch: true } }],
modelSource: 'fetched',
modelFactOverrides: { 'deepseek:deepseek-v4-flash': { capabilities: { chat: true } } },
});
assert.equal(entries[0]?.capabilities.webSearch, true);
});
167 changes: 167 additions & 0 deletions packages/core/src/__tests__/model-facts.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import assert from 'node:assert/strict';
import test from 'node:test';
import {
applyModelFactOverride,
applyModelFactOverridesToConnection,
decodeModelFactsDocument,
modelFactKey,
} from '../model-facts.js';

test('model facts use provider:model keys and merge fields without replacing provider facts', () => {
const key = modelFactKey('openai', 'o4-mini');
const document = decodeModelFactsDocument({
schemaVersion: 1,
overrides: { [key]: { contextWindow: 200_000, capabilities: { vision: false } } },
});
const model = applyModelFactOverride(
{
id: 'o4-mini',
displayName: 'Provider name',
maxOutputTokens: 4_000,
capabilities: { chat: true, vision: true },
},
document.overrides[key],
);
assert.equal(model.displayName, 'Provider name');
assert.equal(model.contextWindow, 200_000);
assert.deepEqual(model.capabilities, { chat: true, vision: false });
});

test('malformed and unknown model fact fields are rejected', () => {
assert.throws(() =>
decodeModelFactsDocument({ schemaVersion: 1, overrides: { 'openai:o4-mini': {} } }),
);
assert.throws(() =>
decodeModelFactsDocument({ schemaVersion: 1, overrides: { 'openai:o4-mini': { nope: true } } }),
);
assert.throws(() =>
decodeModelFactsDocument({ schemaVersion: 1, overrides: { 'o4-mini': { contextWindow: 1 } } }),
);
assert.throws(() =>
decodeModelFactsDocument({
schemaVersion: 1,
overrides: { 'openai:o4-mini': { contextWindow: 0 } },
}),
);
assert.throws(() =>
decodeModelFactsDocument({
schemaVersion: 1,
overrides: { 'openai:o4-mini': { capabilities: { toString: true } } },
}),
);
assert.throws(() =>
decodeModelFactsDocument({
schemaVersion: 1,
overrides: { 'toString:model': { contextWindow: 1 } },
}),
);
});

test('model fact keys preserve colons in provider model ids', () => {
const key = modelFactKey('ollama-cloud', 'gpt-oss:120b');
assert.equal(key, 'ollama-cloud:gpt-oss:120b');
const document = decodeModelFactsDocument({
schemaVersion: 1,
overrides: { [key]: { contextWindow: 131_072 } },
});
assert.equal(document.overrides[key]?.contextWindow, 131_072);
});

test('override-only models are projected only when enabled', () => {
const connection = {
slug: 'openai',
providerType: 'openai' as const,
defaultModel: 'custom',
enabledModelIds: ['custom'],
models: [{ id: 'provider-model' }],
};
const result = applyModelFactOverridesToConnection(connection, {
'openai:custom': { contextWindow: 64_000 },
'openai:hidden': { contextWindow: 1_000 },
});
assert.deepEqual(result.models, [
{ id: 'provider-model' },
{
id: 'custom',
contextWindow: 64_000,
inputLimit: 64_000,
factOverriddenFields: ['contextWindow', 'inputLimit'],
},
]);
});

test('context window facts cannot be truncated by an older input limit', () => {
const result = applyModelFactOverride(
{ id: 'model', contextWindow: 8_192, inputLimit: 8_192 },
{ contextWindow: 200_000 },
);
assert.equal(result.contextWindow, 200_000);
assert.equal(result.inputLimit, 200_000);
});

test('overrides replace fields on discovered models while preserving untouched provider facts', () => {
const result = applyModelFactOverridesToConnection(
{
providerType: 'openai',
defaultModel: 'provider-model',
enabledModelIds: ['provider-model'],
models: [
{ id: 'provider-model', contextWindow: 8_000, capabilities: { chat: true, vision: true } },
],
},
{ 'openai:provider-model': { contextWindow: 64_000, capabilities: { vision: false } } },
);
assert.equal(result.models?.[0]?.contextWindow, 64_000);
assert.deepEqual(result.models?.[0]?.capabilities, { chat: true, vision: false });
});

test('modality overrides merge directions independently', () => {
const result = applyModelFactOverride(
{
id: 'multimodal',
modalities: { input: ['text', 'image', 'pdf'], output: ['text', 'audio'] },
},
{ modalities: { input: ['text'] } },
);
assert.deepEqual(result.modalities, {
input: ['text'],
output: ['text', 'audio'],
});
});

test('model capabilities preserve web search facts from metadata and overrides', () => {
const result = applyModelFactOverride(
{ id: 'web-model', capabilities: { webSearch: true } },
{ capabilities: { chat: true } },
);
assert.deepEqual(result.capabilities, { webSearch: true, chat: true });
});

test('model fact overrides accept parallel tool-call capability metadata', () => {
const document = decodeModelFactsDocument({
schemaVersion: 1,
overrides: { 'openai:tool-model': { capabilities: { parallelToolCalls: false } } },
});
assert.deepEqual(document.overrides['openai:tool-model']?.capabilities, {
parallelToolCalls: false,
});
});
44 changes: 44 additions & 0 deletions packages/core/src/__tests__/runtime-policy-codec.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,50 @@ test('normalizes exact bounded model discovery results', () => {
}
});

test('normalizes extended model facts used by the runtime host catalog', () => {
const result = normalizeConnectionModelDiscoveryResult({
models: [
{
id: 'custom-model',
description: 'A custom model',
inputLimit: 120_000,
knowledgeCutoff: '2025-01',
structuredOutput: true,
lastUpdated: '2026-01-01',
modalities: { input: ['text', 'image'], output: ['text'] },
},
],
source: 'fetched',
fetchedAt: 42,
});
assert.deepEqual(result.models[0], {
id: 'custom-model',
description: 'A custom model',
inputLimit: 120_000,
knowledgeCutoff: '2025-01',
structuredOutput: true,
lastUpdated: '2026-01-01',
modalities: { input: ['text', 'image'], output: ['text'] },
});
});

test('rejects sparse model modality arrays', () => {
assert.throws(
() =>
normalizeConnectionModelDiscoveryResult({
models: [
{
id: 'custom-model',
modalities: { input: Array(1), output: ['text'] },
},
],
source: 'fetched',
fetchedAt: 42,
}),
RuntimePolicyDomainDecodeError,
);
});

test('credential domain validation requires material but leaves capacity to callers', () => {
const input = normalizeSetCredentialInput({
locator: {
Expand Down
Loading