mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 04:00:36 +00:00
merge main de resolve conflict
This commit is contained in:
commit
3458c1d68b
191 changed files with 9340 additions and 7371 deletions
|
|
@ -1322,7 +1322,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should read excludeMCPServers from settings', async () => {
|
||||
it('should read excludeMCPServers from settings but still return all servers', async () => {
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = {
|
||||
|
|
@ -1330,12 +1330,18 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|||
mcp: { excluded: ['server1', 'server2'] },
|
||||
};
|
||||
const config = await loadCliConfig(settings, argv, undefined, []);
|
||||
// getMcpServers() now returns all servers, use isMcpServerDisabled() to check status
|
||||
expect(config.getMcpServers()).toEqual({
|
||||
server1: { url: 'http://localhost:8080' },
|
||||
server2: { url: 'http://localhost:8081' },
|
||||
server3: { url: 'http://localhost:8082' },
|
||||
});
|
||||
expect(config.isMcpServerDisabled('server1')).toBe(true);
|
||||
expect(config.isMcpServerDisabled('server2')).toBe(true);
|
||||
expect(config.isMcpServerDisabled('server3')).toBe(false);
|
||||
});
|
||||
|
||||
it('should override allowMCPServers with excludeMCPServers if overlapping', async () => {
|
||||
it('should apply allowedMcpServers filter but excluded servers are still returned', async () => {
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = {
|
||||
|
|
@ -1346,9 +1352,14 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|||
},
|
||||
};
|
||||
const config = await loadCliConfig(settings, argv, undefined, []);
|
||||
// allowedMcpServers filters which servers are available
|
||||
// but excluded servers are still returned by getMcpServers()
|
||||
expect(config.getMcpServers()).toEqual({
|
||||
server1: { url: 'http://localhost:8080' },
|
||||
server2: { url: 'http://localhost:8081' },
|
||||
});
|
||||
expect(config.isMcpServerDisabled('server1')).toBe(true);
|
||||
expect(config.isMcpServerDisabled('server2')).toBe(false);
|
||||
});
|
||||
|
||||
it('should prioritize mcp server flag if set', async () => {
|
||||
|
|
@ -2244,8 +2255,8 @@ describe('parseArguments with positional prompt', () => {
|
|||
});
|
||||
|
||||
describe('Telemetry configuration via environment variables', () => {
|
||||
it('should prioritize GEMINI_TELEMETRY_ENABLED over settings', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', 'true');
|
||||
it('should prioritize QWEN_TELEMETRY_ENABLED over settings', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_ENABLED', 'true');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = { telemetry: { enabled: false } };
|
||||
|
|
@ -2253,8 +2264,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
it('should prioritize GEMINI_TELEMETRY_TARGET over settings', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_TARGET', 'gcp');
|
||||
it('should prioritize QWEN_TELEMETRY_TARGET over settings', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_TARGET', 'gcp');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = {
|
||||
|
|
@ -2264,8 +2275,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryTarget()).toBe('gcp');
|
||||
});
|
||||
|
||||
it('should throw when GEMINI_TELEMETRY_TARGET is invalid', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_TARGET', 'bogus');
|
||||
it('should throw when QWEN_TELEMETRY_TARGET is invalid', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_TARGET', 'bogus');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = {
|
||||
|
|
@ -2277,9 +2288,9 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it('should prioritize GEMINI_TELEMETRY_OTLP_ENDPOINT over settings and default env var', async () => {
|
||||
it('should prioritize QWEN_TELEMETRY_OTLP_ENDPOINT over settings and default env var', async () => {
|
||||
vi.stubEnv('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://default.env.com');
|
||||
vi.stubEnv('GEMINI_TELEMETRY_OTLP_ENDPOINT', 'http://gemini.env.com');
|
||||
vi.stubEnv('QWEN_TELEMETRY_OTLP_ENDPOINT', 'http://gemini.env.com');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = {
|
||||
|
|
@ -2289,8 +2300,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryOtlpEndpoint()).toBe('http://gemini.env.com');
|
||||
});
|
||||
|
||||
it('should prioritize GEMINI_TELEMETRY_OTLP_PROTOCOL over settings', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_OTLP_PROTOCOL', 'http');
|
||||
it('should prioritize QWEN_TELEMETRY_OTLP_PROTOCOL over settings', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_OTLP_PROTOCOL', 'http');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = { telemetry: { otlpProtocol: 'grpc' } };
|
||||
|
|
@ -2298,8 +2309,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryOtlpProtocol()).toBe('http');
|
||||
});
|
||||
|
||||
it('should prioritize GEMINI_TELEMETRY_LOG_PROMPTS over settings', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', 'false');
|
||||
it('should prioritize QWEN_TELEMETRY_LOG_PROMPTS over settings', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_LOG_PROMPTS', 'false');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = { telemetry: { logPrompts: true } };
|
||||
|
|
@ -2307,8 +2318,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryLogPromptsEnabled()).toBe(false);
|
||||
});
|
||||
|
||||
it('should prioritize GEMINI_TELEMETRY_OUTFILE over settings', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_OUTFILE', '/gemini/env/telemetry.log');
|
||||
it('should prioritize QWEN_TELEMETRY_OUTFILE over settings', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_OUTFILE', '/gemini/env/telemetry.log');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = {
|
||||
|
|
@ -2318,8 +2329,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryOutfile()).toBe('/gemini/env/telemetry.log');
|
||||
});
|
||||
|
||||
it('should prioritize GEMINI_TELEMETRY_USE_COLLECTOR over settings', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_USE_COLLECTOR', 'true');
|
||||
it('should prioritize QWEN_TELEMETRY_USE_COLLECTOR over settings', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_USE_COLLECTOR', 'true');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = { telemetry: { useCollector: false } };
|
||||
|
|
@ -2327,8 +2338,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryUseCollector()).toBe(true);
|
||||
});
|
||||
|
||||
it('should use settings value when GEMINI_TELEMETRY_ENABLED is not set', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', undefined);
|
||||
it('should use settings value when QWEN_TELEMETRY_ENABLED is not set', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_ENABLED', undefined);
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = { telemetry: { enabled: true } };
|
||||
|
|
@ -2336,8 +2347,8 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
it('should use settings value when GEMINI_TELEMETRY_TARGET is not set', async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_TARGET', undefined);
|
||||
it('should use settings value when QWEN_TELEMETRY_TARGET is not set', async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_TARGET', undefined);
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const settings: Settings = {
|
||||
|
|
@ -2347,16 +2358,16 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryTarget()).toBe('local');
|
||||
});
|
||||
|
||||
it("should treat GEMINI_TELEMETRY_ENABLED='1' as true", async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', '1');
|
||||
it("should treat QWEN_TELEMETRY_ENABLED='1' as true", async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_ENABLED', '1');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const config = await loadCliConfig({}, argv, undefined, []);
|
||||
expect(config.getTelemetryEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
it("should treat GEMINI_TELEMETRY_ENABLED='0' as false", async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', '0');
|
||||
it("should treat QWEN_TELEMETRY_ENABLED='0' as false", async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_ENABLED', '0');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const config = await loadCliConfig(
|
||||
|
|
@ -2368,16 +2379,16 @@ describe('Telemetry configuration via environment variables', () => {
|
|||
expect(config.getTelemetryEnabled()).toBe(false);
|
||||
});
|
||||
|
||||
it("should treat GEMINI_TELEMETRY_LOG_PROMPTS='1' as true", async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', '1');
|
||||
it("should treat QWEN_TELEMETRY_LOG_PROMPTS='1' as true", async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_LOG_PROMPTS', '1');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const config = await loadCliConfig({}, argv, undefined, []);
|
||||
expect(config.getTelemetryLogPromptsEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
it("should treat GEMINI_TELEMETRY_LOG_PROMPTS='false' as false", async () => {
|
||||
vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', 'false');
|
||||
it("should treat QWEN_TELEMETRY_LOG_PROMPTS='false' as false", async () => {
|
||||
vi.stubEnv('QWEN_TELEMETRY_LOG_PROMPTS', 'false');
|
||||
process.argv = ['node', 'script.js'];
|
||||
const argv = await parseArguments();
|
||||
const config = await loadCliConfig(
|
||||
|
|
|
|||
|
|
@ -1023,7 +1023,7 @@ export async function loadCliConfig(
|
|||
useBuiltinRipgrep: settings.tools?.useBuiltinRipgrep,
|
||||
shouldUseNodePtyShell: settings.tools?.shell?.enableInteractiveShell,
|
||||
skipNextSpeakerCheck: settings.model?.skipNextSpeakerCheck,
|
||||
skipLoopDetection: settings.model?.skipLoopDetection ?? false,
|
||||
skipLoopDetection: settings.model?.skipLoopDetection ?? true,
|
||||
skipStartupContext: settings.model?.skipStartupContext ?? false,
|
||||
truncateToolOutputThreshold: settings.tools?.truncateToolOutputThreshold,
|
||||
truncateToolOutputLines: settings.tools?.truncateToolOutputLines,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ function getSandboxCommand(
|
|||
|
||||
// note environment variable takes precedence over argument (from command line or settings)
|
||||
const environmentConfiguredSandbox =
|
||||
process.env['GEMINI_SANDBOX']?.toLowerCase().trim() ?? '';
|
||||
process.env['QWEN_SANDBOX']?.toLowerCase().trim() ?? '';
|
||||
sandbox =
|
||||
environmentConfiguredSandbox?.length > 0
|
||||
? environmentConfiguredSandbox
|
||||
|
|
@ -63,7 +63,7 @@ function getSandboxCommand(
|
|||
return sandbox;
|
||||
}
|
||||
throw new FatalSandboxError(
|
||||
`Missing sandbox command '${sandbox}' (from GEMINI_SANDBOX)`,
|
||||
`Missing sandbox command '${sandbox}' (from QWEN_SANDBOX)`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -80,8 +80,8 @@ function getSandboxCommand(
|
|||
// throw an error if user requested sandbox but no command was found
|
||||
if (sandbox === true) {
|
||||
throw new FatalSandboxError(
|
||||
'GEMINI_SANDBOX is true but failed to determine command for sandbox; ' +
|
||||
'install docker or podman or specify command in GEMINI_SANDBOX',
|
||||
'QWEN_SANDBOX is true but failed to determine command for sandbox; ' +
|
||||
'install docker or podman or specify command in QWEN_SANDBOX',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ export async function loadSandboxConfig(
|
|||
const packageJson = await getPackageJson();
|
||||
const image =
|
||||
argv.sandboxImage ??
|
||||
process.env['GEMINI_SANDBOX_IMAGE'] ??
|
||||
process.env['QWEN_SANDBOX_IMAGE'] ??
|
||||
packageJson?.config?.sandboxImageUri;
|
||||
|
||||
return command && image ? { command, image } : undefined;
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ describe('Settings Loading and Merging', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should warn about unknown top-level keys in a v2 settings file', () => {
|
||||
it('should silently ignore unknown top-level keys in a v2 settings file', () => {
|
||||
(mockFsExistsSync as Mock).mockImplementation(
|
||||
(p: fs.PathLike) => p === USER_SETTINGS_PATH,
|
||||
);
|
||||
|
|
@ -471,13 +471,7 @@ describe('Settings Loading and Merging', () => {
|
|||
|
||||
const settings = loadSettings(MOCK_WORKSPACE_DIR);
|
||||
|
||||
expect(getSettingsWarnings(settings)).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.stringContaining(
|
||||
"Unknown setting 'someUnknownKey' will be ignored",
|
||||
),
|
||||
]),
|
||||
);
|
||||
expect(getSettingsWarnings(settings)).toEqual([]);
|
||||
});
|
||||
|
||||
it('should not warn for valid v2 container keys', () => {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import { resolveEnvVarsInObject } from '../utils/envVarResolver.js';
|
|||
import { setNestedPropertySafe } from '../utils/settingsUtils.js';
|
||||
import { customDeepMerge } from '../utils/deepMerge.js';
|
||||
import { updateSettingsFilePreservingFormat } from '../utils/commentJson.js';
|
||||
const debugLogger = createDebugLogger('SETTINGS');
|
||||
import { runMigrations, needsMigration } from './migration/index.js';
|
||||
import {
|
||||
V1_TO_V2_MIGRATION_MAP,
|
||||
|
|
@ -42,6 +41,8 @@ import {
|
|||
} from './migration/versions/v1-to-v2-shared.js';
|
||||
import { writeWithBackupSync } from '../utils/writeWithBackup.js';
|
||||
|
||||
const debugLogger = createDebugLogger('SETTINGS');
|
||||
|
||||
function getMergeStrategyForPath(path: string[]): MergeStrategy | undefined {
|
||||
let current: SettingDefinition | undefined = undefined;
|
||||
let currentSchema: SettingsSchema | undefined = getSettingsSchema();
|
||||
|
|
@ -165,7 +166,7 @@ function getSettingsFileKeyWarnings(
|
|||
);
|
||||
}
|
||||
|
||||
// Unknown top-level keys.
|
||||
// Unknown top-level keys — log silently to debug output.
|
||||
const schemaKeys = new Set(Object.keys(getSettingsSchema()));
|
||||
for (const key of Object.keys(settings)) {
|
||||
if (key === SETTINGS_VERSION_KEY) {
|
||||
|
|
@ -178,8 +179,8 @@ function getSettingsFileKeyWarnings(
|
|||
continue;
|
||||
}
|
||||
|
||||
warnings.push(
|
||||
`Warning: Unknown setting '${key}' will be ignored in ${settingsFilePath}.`,
|
||||
debugLogger.warn(
|
||||
`Unknown setting '${key}' will be ignored in ${settingsFilePath}.`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ const SETTINGS_SCHEMA = {
|
|||
label: 'Skip Loop Detection',
|
||||
category: 'Model',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
default: true,
|
||||
description: 'Disable all loop detection checks (streaming and LLM).',
|
||||
showInDialog: false,
|
||||
},
|
||||
|
|
@ -822,9 +822,9 @@ const SETTINGS_SCHEMA = {
|
|||
label: 'Interactive Shell (PTY)',
|
||||
category: 'Tools',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
default: true,
|
||||
description:
|
||||
'Use node-pty for an interactive shell experience. Fallback to child_process still applies.',
|
||||
'Use node-pty for an interactive shell experience. Falls back to child_process if PTY is unavailable.',
|
||||
showInDialog: true,
|
||||
},
|
||||
pager: {
|
||||
|
|
|
|||
|
|
@ -158,9 +158,9 @@ describe('Trusted Folders Loading', () => {
|
|||
expect(errors[0].message).toContain('Unexpected token');
|
||||
});
|
||||
|
||||
it('should use GEMINI_CLI_TRUSTED_FOLDERS_PATH env var if set', () => {
|
||||
it('should use QWEN_CODE_TRUSTED_FOLDERS_PATH env var if set', () => {
|
||||
const customPath = '/custom/path/to/trusted_folders.json';
|
||||
process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH'] = customPath;
|
||||
process.env['QWEN_CODE_TRUSTED_FOLDERS_PATH'] = customPath;
|
||||
|
||||
(mockFsExistsSync as Mock).mockImplementation((p) => p === customPath);
|
||||
const userContent = {
|
||||
|
|
@ -180,7 +180,7 @@ describe('Trusted Folders Loading', () => {
|
|||
]);
|
||||
expect(errors).toEqual([]);
|
||||
|
||||
delete process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH'];
|
||||
delete process.env['QWEN_CODE_TRUSTED_FOLDERS_PATH'];
|
||||
});
|
||||
|
||||
it('setValue should update the user config and save it', () => {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ export const SETTINGS_DIRECTORY_NAME = '.qwen';
|
|||
export const USER_SETTINGS_DIR = path.join(homedir(), SETTINGS_DIRECTORY_NAME);
|
||||
|
||||
export function getTrustedFoldersPath(): string {
|
||||
if (process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH']) {
|
||||
return process.env['GEMINI_CLI_TRUSTED_FOLDERS_PATH'];
|
||||
if (process.env['QWEN_CODE_TRUSTED_FOLDERS_PATH']) {
|
||||
return process.env['QWEN_CODE_TRUSTED_FOLDERS_PATH'];
|
||||
}
|
||||
return path.join(USER_SETTINGS_DIR, TRUSTED_FOLDERS_FILENAME);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue