Restore Vertex AI LLM setup (#56)

* feat(context): resolve Vertex AI config references

* feat(cli): restore Vertex AI LLM setup

---------

Co-authored-by: Andrey Avtomonov <andreybavt@gmail.com>
This commit is contained in:
Luca Martial 2026-05-13 08:42:38 -04:00 committed by GitHub
parent d4d8ad1724
commit 4973ca562f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 1113 additions and 59 deletions

View file

@ -37,6 +37,52 @@ describe('local KTX LLM config', () => {
});
});
it('resolves Vertex AI env references into a KtxLlmConfig', () => {
const config: KtxProjectLlmConfig = {
provider: {
backend: 'vertex',
vertex: { project: 'env:GOOGLE_VERTEX_PROJECT', location: 'env:GOOGLE_VERTEX_LOCATION' },
},
models: { default: 'env:KTX_MODEL' },
promptCaching: { enabled: true, vertexFallbackTo5m: true },
};
expect(
resolveLocalKtxLlmConfig(config, {
GOOGLE_VERTEX_PROJECT: 'local-gcp-project',
GOOGLE_VERTEX_LOCATION: 'us-east5',
KTX_MODEL: 'claude-sonnet-4-6',
}),
).toEqual({
backend: 'vertex',
vertex: { project: 'local-gcp-project', location: 'us-east5' },
modelSlots: { default: 'claude-sonnet-4-6' },
promptCaching: { enabled: true, vertexFallbackTo5m: true },
});
});
it('ignores inactive Vertex AI references for non-Vertex backends', () => {
const config: KtxProjectLlmConfig = {
provider: {
backend: 'anthropic',
anthropic: { api_key: 'env:ANTHROPIC_API_KEY' }, // pragma: allowlist secret
vertex: { location: 'env:MISSING_VERTEX_LOCATION' },
},
models: { default: 'claude-sonnet-4-6' },
};
expect(
resolveLocalKtxLlmConfig(config, {
ANTHROPIC_API_KEY: 'sk-ant-test', // pragma: allowlist secret
}),
).toEqual({
backend: 'anthropic',
anthropic: { apiKey: 'sk-ant-test' }, // pragma: allowlist secret
modelSlots: { default: 'claude-sonnet-4-6' },
promptCaching: undefined,
});
});
it('returns null when the local LLM backend is disabled', () => {
expect(
createLocalKtxLlmProviderFromConfig({

View file

@ -67,16 +67,33 @@ function resolvedProviderConfig(
};
}
function resolvedVertexConfig(
config: { project?: string; location?: string } | undefined,
env: NodeJS.ProcessEnv,
): { project?: string; location: string } | undefined {
if (!config) {
return undefined;
}
const project = resolveOptional(config.project, env);
const location = resolveRequired(config.location, env, 'llm.provider.vertex.location is required');
return {
...(project ? { project } : {}),
location,
};
}
export function resolveLocalKtxLlmConfig(config: KtxProjectLlmConfig, env: NodeJS.ProcessEnv): KtxLlmConfig | null {
if (config.provider.backend === 'none') {
return null;
}
const modelSlots = resolveModelSlots(config.models, env);
const vertex = config.provider.backend === 'vertex' ? resolvedVertexConfig(config.provider.vertex, env) : undefined;
const anthropic = resolvedProviderConfig(config.provider.anthropic, env);
const gateway = resolvedProviderConfig(config.provider.gateway, env);
return {
backend: config.provider.backend,
...(config.provider.vertex ? { vertex: config.provider.vertex } : {}),
...(vertex ? { vertex } : {}),
...(anthropic ? { anthropic } : {}),
...(gateway ? { gateway } : {}),
modelSlots,