mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 02:17:46 +08:00
fix(frontend): 按端点能力约束会话压缩映射
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
COMPACT_REQUEST_SCOPE_VALUE,
|
||||
formatModelMappingEndpointLabel,
|
||||
formatModelMappingRequestScope,
|
||||
modelMappingEndpointScopeSupportsSessionCompaction,
|
||||
modelMappingOperationsKey,
|
||||
modelMappingOperationsFromScopeValue,
|
||||
modelMappingRequestScopeOptions,
|
||||
@@ -36,12 +37,50 @@ describe('model mapping request scope', () => {
|
||||
it('preserves an unknown operation scope while editing', () => {
|
||||
const operations = ['future_operation', 'compact']
|
||||
const value = modelMappingRequestScopeValue(operations)
|
||||
const options = modelMappingRequestScopeOptions(operations)
|
||||
const options = modelMappingRequestScopeOptions(
|
||||
operations,
|
||||
{ sessionCompaction: true },
|
||||
)
|
||||
|
||||
expect(modelMappingOperationsFromScopeValue(value)).toEqual(operations)
|
||||
expect(options).toContainEqual({ value, label: '仅匹配:future_operation, compact' })
|
||||
})
|
||||
|
||||
it('offers compact scope only when the selected endpoint scope supports it', () => {
|
||||
expect(modelMappingRequestScopeOptions(undefined, { sessionCompaction: false }))
|
||||
.toEqual([{ value: ALL_REQUESTS_SCOPE_VALUE, label: '所有请求' }])
|
||||
expect(modelMappingRequestScopeOptions(undefined, { sessionCompaction: true }))
|
||||
.toContainEqual({ value: COMPACT_REQUEST_SCOPE_VALUE, label: '仅会话压缩' })
|
||||
})
|
||||
|
||||
it('requires every explicitly selected endpoint to use OpenAI Responses', () => {
|
||||
const responsesEndpoint = {
|
||||
id: 'responses',
|
||||
api_format: 'OPENAI_RESPONSES',
|
||||
base_url: 'https://api.example.com/v1',
|
||||
is_active: true,
|
||||
}
|
||||
const chatEndpoint = {
|
||||
id: 'chat',
|
||||
api_format: 'openai:chat',
|
||||
base_url: 'https://api.example.com/v1',
|
||||
is_active: true,
|
||||
}
|
||||
|
||||
expect(modelMappingEndpointScopeSupportsSessionCompaction(
|
||||
undefined,
|
||||
[responsesEndpoint, chatEndpoint],
|
||||
)).toBe(false)
|
||||
expect(modelMappingEndpointScopeSupportsSessionCompaction(
|
||||
[responsesEndpoint.id],
|
||||
[responsesEndpoint, chatEndpoint],
|
||||
)).toBe(true)
|
||||
expect(modelMappingEndpointScopeSupportsSessionCompaction(
|
||||
[responsesEndpoint.id, chatEndpoint.id],
|
||||
[responsesEndpoint, chatEndpoint],
|
||||
)).toBe(false)
|
||||
})
|
||||
|
||||
it('rejects malformed scope values without constructing operations', () => {
|
||||
expect(modelMappingOperationsFromScopeValue('compact')).toBeUndefined()
|
||||
expect(modelMappingOperationsFromScopeValue('{"compact":true}')).toBeUndefined()
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { formatApiFormat } from '@/api/endpoints/types/api-format'
|
||||
import {
|
||||
API_FORMATS,
|
||||
formatApiFormat,
|
||||
normalizeApiFormatAlias,
|
||||
} from '@/api/endpoints/types/api-format'
|
||||
|
||||
export const MODEL_MAPPING_OPERATION_COMPACT = 'compact'
|
||||
|
||||
@@ -12,6 +16,10 @@ export interface ModelMappingRequestScopeOption {
|
||||
label: string
|
||||
}
|
||||
|
||||
export interface ModelMappingRequestScopeCapabilities {
|
||||
sessionCompaction: boolean
|
||||
}
|
||||
|
||||
export interface ModelMappingRequestScopeLabels {
|
||||
allRequests: string
|
||||
sessionCompactionOnly: string
|
||||
@@ -90,14 +98,22 @@ export function formatModelMappingRequestScope(
|
||||
|
||||
export function modelMappingRequestScopeOptions(
|
||||
operations: string[] | undefined,
|
||||
capabilities: ModelMappingRequestScopeCapabilities,
|
||||
labels: ModelMappingRequestScopeLabels = DEFAULT_REQUEST_SCOPE_LABELS,
|
||||
): ModelMappingRequestScopeOption[] {
|
||||
const options: ModelMappingRequestScopeOption[] = [
|
||||
{ value: ALL_REQUESTS_SCOPE_VALUE, label: labels.allRequests },
|
||||
{ value: COMPACT_REQUEST_SCOPE_VALUE, label: labels.sessionCompactionOnly },
|
||||
]
|
||||
if (capabilities.sessionCompaction) {
|
||||
options.push({
|
||||
value: COMPACT_REQUEST_SCOPE_VALUE,
|
||||
label: labels.sessionCompactionOnly,
|
||||
})
|
||||
}
|
||||
const currentValue = modelMappingRequestScopeValue(operations)
|
||||
if (!options.some(option => option.value === currentValue)) {
|
||||
const compactScopeUnavailable = currentValue === COMPACT_REQUEST_SCOPE_VALUE
|
||||
&& !capabilities.sessionCompaction
|
||||
if (!compactScopeUnavailable && !options.some(option => option.value === currentValue)) {
|
||||
options.push({
|
||||
value: currentValue,
|
||||
label: formatModelMappingRequestScope(operations, labels),
|
||||
@@ -106,6 +122,23 @@ export function modelMappingRequestScopeOptions(
|
||||
return options
|
||||
}
|
||||
|
||||
export function modelMappingEndpointScopeSupportsSessionCompaction(
|
||||
endpointIds: string[] | undefined,
|
||||
endpoints: ModelMappingEndpoint[],
|
||||
): boolean {
|
||||
const selectedIds = [...new Set(
|
||||
(endpointIds ?? []).map(id => id.trim()).filter(Boolean),
|
||||
)]
|
||||
if (selectedIds.length === 0) return false
|
||||
|
||||
const endpointsById = new Map(endpoints.map(endpoint => [endpoint.id, endpoint]))
|
||||
return selectedIds.every((endpointId) => {
|
||||
const endpoint = endpointsById.get(endpointId)
|
||||
return endpoint !== undefined
|
||||
&& normalizeApiFormatAlias(endpoint.api_format) === API_FORMATS.OPENAI_RESPONSES
|
||||
})
|
||||
}
|
||||
|
||||
export function formatModelMappingEndpointLabel(
|
||||
endpoint: ModelMappingEndpoint,
|
||||
endpoints: ModelMappingEndpoint[],
|
||||
|
||||
Reference in New Issue
Block a user