feat: add Responses API compatibility
This commit is contained in:
@@ -33,6 +33,8 @@ type FieldDefinition = {
|
||||
placeholder?: string;
|
||||
type: FieldType;
|
||||
scope?: FieldScope;
|
||||
fixedOptions?: ValueOption[];
|
||||
allowCustom?: boolean;
|
||||
};
|
||||
|
||||
type ValueOption = { label: string; value: string };
|
||||
@@ -50,6 +52,19 @@ const textFields: FieldDefinition[] = [
|
||||
{ key: 'thinkingEffortLevels', label: '推理深度', hint: '声明模型支持的 OpenAI reasoning_effort 取值,平台差异由网关适配', placeholder: 'none, minimal, low, medium, high, xhigh', type: 'list' },
|
||||
];
|
||||
|
||||
const apiProtocolField: FieldDefinition = {
|
||||
key: 'supportedApiProtocols',
|
||||
label: '支持的接口规范',
|
||||
hint: '字段缺失时按 OpenAI Chat 处理;Responses 入口会优先选择原生 Responses 候选',
|
||||
type: 'list',
|
||||
allowCustom: false,
|
||||
fixedOptions: [
|
||||
{ value: 'openai_chat_completions', label: 'OpenAI Chat' },
|
||||
{ value: 'openai_responses', label: 'OpenAI Responses' },
|
||||
{ value: 'anthropic_messages', label: 'Anthropic' },
|
||||
],
|
||||
};
|
||||
|
||||
const embeddingFields: FieldDefinition[] = [
|
||||
{ key: 'dimensions', label: '向量维度', placeholder: '1024, 768, 512', type: 'numberList' },
|
||||
];
|
||||
@@ -481,7 +496,7 @@ function MultiValueControl(props: {
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
<div className="capabilityCustomValue">
|
||||
{props.field.allowCustom !== false ? <div className="capabilityCustomValue">
|
||||
<Input
|
||||
size="sm"
|
||||
value={customValue}
|
||||
@@ -495,7 +510,7 @@ function MultiValueControl(props: {
|
||||
}}
|
||||
/>
|
||||
<Button className="capabilityAddValueButton" type="button" size="sm" variant="outline" onClick={addCustom}>添加</Button>
|
||||
</div>
|
||||
</div> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -605,6 +620,7 @@ function defaultDirectValueForConfigKey(key: string) {
|
||||
}
|
||||
|
||||
function multiOptionsForField(field: FieldDefinition, config: Record<string, unknown>, value: unknown): ValueOption[] {
|
||||
if (field.fixedOptions) return field.fixedOptions;
|
||||
let options: string[] = [];
|
||||
if (field.key === 'output_resolutions') options = field.scope ? videoResolutionOptions : imageResolutionOptions;
|
||||
if (field.key === 'aspect_ratio_allowed') options = field.scope ? videoAspectRatioOptions : imageAspectRatioOptions;
|
||||
@@ -699,7 +715,7 @@ function hasMeaningfulValue(value: unknown): boolean {
|
||||
}
|
||||
|
||||
function capabilityFieldGroups(type: string): Array<{ title: string; icon: ReactNode; fields: FieldDefinition[] }> {
|
||||
if (isTextType(type)) return [{ title: '文本默认能力', icon: <Brain size={15} />, fields: textFields }];
|
||||
if (isTextType(type)) return [{ title: '文本默认能力', icon: <Brain size={15} />, fields: type === 'text_generate' ? [apiProtocolField, ...textFields] : textFields }];
|
||||
if (type === 'text_embedding') return [{ title: '向量默认能力', icon: <Brain size={15} />, fields: embeddingFields }];
|
||||
if (isImageType(type)) return [{ title: '图像默认能力', icon: <Image size={15} />, fields: imageFieldsFor(type) }];
|
||||
if (isVideoType(type)) return [{ title: '视频默认能力', icon: <Video size={15} />, fields: videoFieldsFor(type) }];
|
||||
@@ -736,6 +752,13 @@ function summarizeEnabledCapabilities(types: string[], typeConfigs: Record<strin
|
||||
|
||||
function capabilitySummaryHighlights(types: string[], typeConfigs: Record<string, Record<string, unknown>>) {
|
||||
const highlights: string[] = [];
|
||||
const protocolLabels: Record<string, string> = {
|
||||
openai_chat_completions: 'Chat',
|
||||
openai_responses: 'Responses',
|
||||
anthropic_messages: 'Anthropic',
|
||||
};
|
||||
const protocols = uniqueStrings(types.flatMap((type) => flattenStringValues(typeConfigs[type]?.supportedApiProtocols)));
|
||||
if (protocols.length) highlights.push(`接口 ${protocols.map((item) => protocolLabels[item] ?? item).join('/')}`);
|
||||
const textLimits = uniqueStrings(types.flatMap((type) => stringValue(typeConfigs[type]?.max_context_tokens ? typeConfigs[type].max_context_tokens : '').split(',').filter(Boolean)));
|
||||
if (textLimits.length) highlights.push(`上下文 ${textLimits[0]} Token`);
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ const managedRootKeys = new Set<string>([
|
||||
]);
|
||||
|
||||
const managedNestedKeys = new Set<string>([
|
||||
'supportedApiProtocols',
|
||||
'supportTool',
|
||||
'supportThinking',
|
||||
'supportThinkingModeSwitch',
|
||||
@@ -275,6 +276,7 @@ export function capabilitiesFromForm(state: CapabilityEditorState): Record<strin
|
||||
export function defaultCapabilityConfig(type: string): Record<string, unknown> {
|
||||
if (isTextLike(type)) {
|
||||
return {
|
||||
...(type === 'text_generate' ? { supportedApiProtocols: ['openai_chat_completions'] } : {}),
|
||||
supportTool: type === 'tools_call',
|
||||
supportThinking: false,
|
||||
supportThinkingModeSwitch: false,
|
||||
@@ -398,7 +400,7 @@ function shouldKeepNestedValue(key: string, value: unknown) {
|
||||
if (key === 'output_resolutions' || key === 'aspect_ratio_allowed' || key === 'aspect_ratio_range' || key === 'input_aspect_ratio_range' || key === 'duration_range') {
|
||||
return !Array.isArray(value);
|
||||
}
|
||||
if (key === 'thinkingEffortLevels' || key === 'dimensions') {
|
||||
if (key === 'thinkingEffortLevels' || key === 'dimensions' || key === 'supportedApiProtocols') {
|
||||
return !Array.isArray(value);
|
||||
}
|
||||
if (key.endsWith('_count') || key === 'output_max_size' || key.endsWith('_tokens')) {
|
||||
|
||||
Reference in New Issue
Block a user