feat: use managed model capabilities for reasoning and image input
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { IncomingMessage, ServerResponse } from 'node:http';
|
||||
import { parseManagedReasoningChoice } from '../../../shared/managed-model-capabilities';
|
||||
import type { ConversationInteractionResponse } from '../../coding-runtime/contracts';
|
||||
import { CodingConversationServiceError } from '../../coding-runtime/conversation-service';
|
||||
import { normalizeProductModelRef } from '../../coding-projects/project-config';
|
||||
@@ -182,12 +183,15 @@ export async function handleCodingConversationRoutes(
|
||||
return true;
|
||||
}
|
||||
if (action === 'thinking' && req.method === 'POST') {
|
||||
const body = await parseJsonBody<{ thinkingLevel?: unknown }>(req);
|
||||
const body = await parseJsonBody<{ thinkingLevel?: unknown; reasoningChoice?: unknown }>(req);
|
||||
const reasoningChoice = body.reasoningChoice === undefined ? undefined : parseManagedReasoningChoice(body.reasoningChoice);
|
||||
if (reasoningChoice === null) invalidRequest('Reasoning choice is invalid');
|
||||
if (!THINKING_LEVELS.has(String(body.thinkingLevel))) invalidRequest('Thinking level is invalid');
|
||||
sendJson(res, 200, {
|
||||
model: await service.setThinking(
|
||||
conversationId,
|
||||
body.thinkingLevel as 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'max',
|
||||
reasoningChoice ?? undefined,
|
||||
),
|
||||
});
|
||||
return true;
|
||||
|
||||
@@ -136,7 +136,10 @@ function normalizeWorksSquareAiGatewayBaseUrl(baseUrl: string, credentialMode: s
|
||||
return normalized;
|
||||
}
|
||||
|
||||
import { normalizeManagedModelCatalog } from '../../../shared/managed-model-capabilities';
|
||||
|
||||
type ImportedUserModelConfig = {
|
||||
modelCapabilitiesV2?: import('../../../shared/managed-model-capabilities').ManagedModelCatalog;
|
||||
label: string;
|
||||
baseUrl: string;
|
||||
apiKey: string;
|
||||
@@ -176,7 +179,10 @@ export function normalizeImportedUserModelConfig(payload: unknown): ImportedUser
|
||||
const apiKeyExpiresIn = typeof apiKeyExpiresInRaw === 'number' && Number.isFinite(apiKeyExpiresInRaw)
|
||||
? Math.max(0, Math.floor(apiKeyExpiresInRaw))
|
||||
: null;
|
||||
const models = normalizeImportedModels(record.models);
|
||||
const v2 = normalizeManagedModelCatalog(record.model_capabilities_v2);
|
||||
const models = v2 && Array.isArray(record.models)
|
||||
? [...new Set(record.models.filter((id): id is string => typeof id === 'string' && !!id.trim()).map(id => id.trim()))]
|
||||
: normalizeImportedModels(record.models);
|
||||
if (models.length === 0) {
|
||||
throw new Error('Works Square model config response has no models');
|
||||
}
|
||||
@@ -185,6 +191,7 @@ export function normalizeImportedUserModelConfig(payload: unknown): ImportedUser
|
||||
? record.label.trim()
|
||||
: NIANCODE_USER_MODEL_ACCOUNT_LABEL;
|
||||
const modelCapabilities = normalizeImportedModelCapabilities(record.model_capabilities, models);
|
||||
const modelCapabilitiesV2 = normalizeManagedModelCatalog(record.model_capabilities_v2, models);
|
||||
|
||||
return {
|
||||
label,
|
||||
@@ -194,6 +201,7 @@ export function normalizeImportedUserModelConfig(payload: unknown): ImportedUser
|
||||
apiKeyExpiresIn,
|
||||
models,
|
||||
...(modelCapabilities ? { modelCapabilities } : {}),
|
||||
...(modelCapabilitiesV2 ? { modelCapabilitiesV2 } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -217,9 +225,11 @@ function importedUserModelMetadata(
|
||||
const metadata = { ...(existing?.metadata ?? {}) };
|
||||
delete metadata.worksSquareCredentialExpiresAt;
|
||||
delete metadata.worksSquareModelCapabilities;
|
||||
delete metadata.worksSquareModelCapabilitiesV2;
|
||||
return {
|
||||
...metadata,
|
||||
customModels: modelConfig.models,
|
||||
...(modelConfig.modelCapabilitiesV2 ? { worksSquareModelCapabilitiesV2: modelConfig.modelCapabilitiesV2 } : {}),
|
||||
...(modelConfig.modelCapabilities
|
||||
? { worksSquareModelCapabilities: modelConfig.modelCapabilities }
|
||||
: {}),
|
||||
@@ -232,12 +242,14 @@ function importedUserModelMetadata(
|
||||
delete metadata.worksSquareCredentialExpiresAt;
|
||||
delete metadata.worksSquareOneApiBaseUrl;
|
||||
delete metadata.worksSquareModelCapabilities;
|
||||
delete metadata.worksSquareModelCapabilitiesV2;
|
||||
const credentialExpiresAt = modelConfig.apiKeyExpiresIn === null
|
||||
? undefined
|
||||
: new Date(nowMs + modelConfig.apiKeyExpiresIn * 1000).toISOString();
|
||||
return {
|
||||
...metadata,
|
||||
customModels: modelConfig.models,
|
||||
...(modelConfig.modelCapabilitiesV2 ? { worksSquareModelCapabilitiesV2: modelConfig.modelCapabilitiesV2 } : {}),
|
||||
...(modelConfig.modelCapabilities
|
||||
? { worksSquareModelCapabilities: modelConfig.modelCapabilities }
|
||||
: {}),
|
||||
@@ -309,6 +321,7 @@ function providerAccountRuntimeShape(account: ProviderAccount): unknown {
|
||||
metadata: {
|
||||
customModels: account.metadata?.customModels,
|
||||
worksSquareModelCapabilities: account.metadata?.worksSquareModelCapabilities,
|
||||
worksSquareModelCapabilitiesV2: account.metadata?.worksSquareModelCapabilitiesV2,
|
||||
worksSquareCredentialMode: account.metadata?.worksSquareCredentialMode,
|
||||
worksSquareOneApiBaseUrl: account.metadata?.worksSquareOneApiBaseUrl,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user