fix: provide available models of all configured authTypes

This commit is contained in:
mingholy.lmh 2026-01-20 17:29:45 +08:00
parent bd900d3668
commit 889c49f0f4
10 changed files with 344 additions and 74 deletions

View file

@ -0,0 +1,42 @@
/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect } from 'vitest';
import { AuthType } from '@qwen-code/qwen-code-core';
import {
formatAcpModelId,
parseAcpBaseModelId,
parseAcpModelOption,
} from './acpModelUtils.js';
describe('acpModelUtils', () => {
it('formats modelId(authType)', () => {
expect(formatAcpModelId('qwen3', AuthType.QWEN_OAUTH)).toBe(
`qwen3(${AuthType.QWEN_OAUTH})`,
);
});
it('extracts base model id when string ends with parentheses', () => {
expect(parseAcpBaseModelId(`qwen3(${AuthType.USE_OPENAI})`)).toBe('qwen3');
});
it('does not strip when parentheses are not a trailing suffix', () => {
expect(parseAcpBaseModelId('qwen3(x) y')).toBe('qwen3(x) y');
});
it('parses modelId and validates authType', () => {
expect(parseAcpModelOption(` qwen3(${AuthType.USE_OPENAI}) `)).toEqual({
modelId: 'qwen3',
authType: AuthType.USE_OPENAI,
});
});
it('returns trimmed input as modelId when authType is invalid', () => {
expect(parseAcpModelOption('qwen3(not-a-real-auth)')).toEqual({
modelId: 'qwen3(not-a-real-auth)',
});
});
});

View file

@ -0,0 +1,55 @@
/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { AuthType } from '@qwen-code/qwen-code-core';
import { z } from 'zod';
/**
* ACP model IDs are represented as `${modelId}(${authType})` in the ACP protocol.
*/
export function formatAcpModelId(modelId: string, authType: AuthType): string {
return `${modelId}(${authType})`;
}
/**
* Extracts the base model id from an ACP model id string.
*
* If the string ends with `(...)`, the suffix is removed; otherwise returns the
* trimmed input as-is.
*/
export function parseAcpBaseModelId(value: string): string {
const trimmed = value.trim();
const closeIdx = trimmed.lastIndexOf(')');
const openIdx = trimmed.lastIndexOf('(');
if (openIdx >= 0 && closeIdx === trimmed.length - 1 && openIdx < closeIdx) {
return trimmed.slice(0, openIdx);
}
return trimmed;
}
/**
* Parses an ACP model option string into `{ modelId, authType? }`.
*
* If the string ends with `(...)` and `...` is a valid `AuthType`, returns both;
* otherwise returns the trimmed input as `modelId` only.
*/
export function parseAcpModelOption(input: string): {
modelId: string;
authType?: AuthType;
} {
const trimmed = input.trim();
const closeIdx = trimmed.lastIndexOf(')');
const openIdx = trimmed.lastIndexOf('(');
if (openIdx >= 0 && closeIdx === trimmed.length - 1 && openIdx < closeIdx) {
const maybeModelId = trimmed.slice(0, openIdx);
const maybeAuthType = trimmed.slice(openIdx + 1, closeIdx);
const parsedAuthType = z.nativeEnum(AuthType).safeParse(maybeAuthType);
if (parsedAuthType.success) {
return { modelId: maybeModelId, authType: parsedAuthType.data };
}
}
return { modelId: trimmed };
}