fix: integrate Claude CLI provider state
This commit is contained in:
@@ -120,6 +120,13 @@ export async function generateSmallModelText({ prompt, system, maxOutputTokens,
|
||||
);
|
||||
}
|
||||
|
||||
if (resolved.providerID === 'claude-code') {
|
||||
throw Object.assign(
|
||||
new Error('Claude Code cannot be used for background small-model actions. Choose another Small Model in Settings → Sessions.'),
|
||||
{ statusCode: 422, code: 'small-model-provider-unsupported' },
|
||||
);
|
||||
}
|
||||
|
||||
// Callers with a session context can forbid silently switching providers:
|
||||
// an explicit user choice (settings override, opencode config, request
|
||||
// model) is always allowed, anything else must stay on the session's
|
||||
@@ -183,6 +190,7 @@ export function listAuthenticatedProviders() {
|
||||
const ids = new Set(
|
||||
Object.keys(auth || {}).filter((providerID) => isUsableAuthEntry(auth[providerID])),
|
||||
);
|
||||
ids.delete('claude-code');
|
||||
// The catalog id is github-copilot while legacy auth entries may sit
|
||||
// under the copilot alias.
|
||||
if (isUsableAuthEntry(getAuthEntryForProvider(auth, 'github-copilot'))) {
|
||||
|
||||
@@ -26,12 +26,42 @@ vi.mock('./call.js', () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
const { generateSmallModelText, describeSmallModel } = await import('./index.js');
|
||||
const { generateSmallModelText, describeSmallModel, listAuthenticatedProviders } = await import('./index.js');
|
||||
const { readAuthFile } = await import('../opencode/auth.js');
|
||||
const { readConfigLayers } = await import('../opencode/shared.js');
|
||||
const { getModelCatalog } = await import('./catalog.js');
|
||||
const { callSmallModel } = await import('./call.js');
|
||||
|
||||
describe('unsupported small-model providers', () => {
|
||||
beforeEach(() => {
|
||||
readAuthFile.mockReturnValue({
|
||||
'claude-code': {
|
||||
type: 'oauth',
|
||||
access: 'claude-cli-managed',
|
||||
refresh: 'claude-cli-managed',
|
||||
},
|
||||
});
|
||||
readConfigLayers.mockReturnValue({ mergedConfig: {} });
|
||||
getModelCatalog.mockResolvedValue({});
|
||||
callSmallModel.mockReset();
|
||||
});
|
||||
|
||||
it('rejects Claude Code with an actionable error before transport dispatch', async () => {
|
||||
await expect(generateSmallModelText({
|
||||
prompt: 'summarize this',
|
||||
model: 'claude-code/haiku',
|
||||
})).rejects.toMatchObject({
|
||||
statusCode: 422,
|
||||
code: 'small-model-provider-unsupported',
|
||||
});
|
||||
expect(callSmallModel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not offer Claude Code in the Small Model picker', () => {
|
||||
expect(listAuthenticatedProviders()).not.toContain('claude-code');
|
||||
});
|
||||
});
|
||||
|
||||
// 8k context leaves 4k input tokens after the output reserve → 16k chars.
|
||||
const CATALOG = {
|
||||
anthropic: {
|
||||
|
||||
@@ -39,7 +39,9 @@ export function registerSmallModelRoutes(app, { getSmallModelService }) {
|
||||
console.error('Small model generation failed:', error);
|
||||
}
|
||||
res.status(statusCode).json({
|
||||
error: error.message || 'Small model generation failed',
|
||||
error: statusCode === 404
|
||||
? (error.message || 'No small model is available')
|
||||
: 'The selected Small Model could not complete this action. Choose another model in Settings → Sessions → Small Model and try again.',
|
||||
...(error?.code ? { code: error.code } : {}),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user