Revert "Add research data provider settings"

This reverts commit 23630d1746.
This commit is contained in:
a1chzt
2026-05-07 20:44:15 +08:00
parent a866e7b012
commit 02bd04ad6c
5 changed files with 5 additions and 209 deletions
-6
View File
@@ -74,12 +74,6 @@ const ENV_KEYS = {
udio: ['OD_UDIO_API_KEY'],
elevenlabs: ['OD_ELEVENLABS_API_KEY', 'ELEVENLABS_API_KEY'],
fishaudio: ['OD_FISHAUDIO_API_KEY', 'FISH_AUDIO_API_KEY'],
financialdatasets: [
'OD_FINANCIAL_DATASETS_API_KEY',
'FINANCIAL_DATASETS_API_KEY',
],
exa: ['OD_EXASEARCH_API_KEY', 'EXASEARCH_API_KEY', 'EXA_API_KEY'],
perplexity: ['OD_PERPLEXITY_API_KEY', 'PERPLEXITY_API_KEY'],
tavily: ['OD_TAVILY_API_KEY', 'TAVILY_API_KEY'],
};
+1 -4
View File
@@ -25,10 +25,7 @@ export const MEDIA_PROVIDERS = [
{ id: 'udio', label: 'Udio', hint: 'Music generation', integrated: false },
{ id: 'elevenlabs', label: 'ElevenLabs', hint: 'Voice / SFX', integrated: false },
{ id: 'fishaudio', label: 'FishAudio', hint: 'Speech / voice clone', integrated: true, defaultBaseUrl: 'https://api.fish.audio' },
{ id: 'financialdatasets', label: 'Financial Datasets', hint: '股票/财报/市场数据', integrated: true, defaultBaseUrl: 'https://api.financialdatasets.ai' },
{ id: 'exa', label: 'Exa', hint: 'Web search 首选', integrated: true, defaultBaseUrl: 'https://api.exa.ai' },
{ id: 'perplexity', label: 'Perplexity', hint: 'Web search 第二选择', integrated: true, defaultBaseUrl: 'https://api.perplexity.ai' },
{ id: 'tavily', label: 'Tavily', hint: 'Web search fallback', integrated: true, defaultBaseUrl: 'https://api.tavily.com' },
{ id: 'tavily', label: 'Tavily Search', hint: 'Agent-callable web research', integrated: true, defaultBaseUrl: 'https://api.tavily.com' },
{ id: 'stub', label: 'Stub (placeholder)', hint: 'Deterministic local placeholder bytes', integrated: true },
];
+2 -140
View File
@@ -18,27 +18,12 @@ const OPENAI_ENV_KEYS = [
'AZURE_OPENAI_API_KEY',
];
const RESEARCH_PROVIDER_ENV_KEYS = [
'OD_FINANCIAL_DATASETS_API_KEY',
'FINANCIAL_DATASETS_API_KEY',
'OD_EXASEARCH_API_KEY',
'EXASEARCH_API_KEY',
'EXA_API_KEY',
'OD_PERPLEXITY_API_KEY',
'PERPLEXITY_API_KEY',
'OD_TAVILY_API_KEY',
'TAVILY_API_KEY',
];
describe('media-config OpenAI OAuth fallback', () => {
let homeDir: string;
let projectRoot: string;
const originalHome = process.env.HOME;
const originalEnv = Object.fromEntries(
[...OPENAI_ENV_KEYS, ...RESEARCH_PROVIDER_ENV_KEYS].map((key) => [
key,
process.env[key],
]),
OPENAI_ENV_KEYS.map((key) => [key, process.env[key]]),
);
const originalMediaConfigDir = process.env.OD_MEDIA_CONFIG_DIR;
const originalDataDir = process.env.OD_DATA_DIR;
@@ -52,9 +37,6 @@ describe('media-config OpenAI OAuth fallback', () => {
for (const key of OPENAI_ENV_KEYS) {
delete process.env[key];
}
for (const key of RESEARCH_PROVIDER_ENV_KEYS) {
delete process.env[key];
}
delete process.env.OD_MEDIA_CONFIG_DIR;
delete process.env.OD_DATA_DIR;
});
@@ -65,7 +47,7 @@ describe('media-config OpenAI OAuth fallback', () => {
} else {
process.env.HOME = originalHome;
}
for (const key of [...OPENAI_ENV_KEYS, ...RESEARCH_PROVIDER_ENV_KEYS]) {
for (const key of OPENAI_ENV_KEYS) {
if (originalEnv[key] == null) {
delete process.env[key];
} else {
@@ -203,126 +185,6 @@ describe('media-config OpenAI OAuth fallback', () => {
delete process.env.OD_NANOBANANA_API_KEY;
});
it('resolves stored research provider credentials without exposing secrets in masked config', async () => {
await writeStoredMediaConfig({
providers: {
financialdatasets: {
apiKey: 'stored-financialdatasets-key',
baseUrl: 'https://financialdatasets.example.test',
},
exa: {
apiKey: 'stored-exa-key',
baseUrl: 'https://exa.example.test',
},
perplexity: {
apiKey: 'stored-perplexity-key',
baseUrl: 'https://perplexity.example.test',
},
tavily: {
apiKey: 'stored-tavily-key',
baseUrl: 'https://tavily.example.test',
},
},
});
await expect(
resolveProviderConfig(projectRoot, 'financialdatasets'),
).resolves.toEqual({
apiKey: 'stored-financialdatasets-key',
baseUrl: 'https://financialdatasets.example.test',
});
await expect(resolveProviderConfig(projectRoot, 'exa')).resolves.toEqual({
apiKey: 'stored-exa-key',
baseUrl: 'https://exa.example.test',
});
await expect(
resolveProviderConfig(projectRoot, 'perplexity'),
).resolves.toEqual({
apiKey: 'stored-perplexity-key',
baseUrl: 'https://perplexity.example.test',
});
await expect(resolveProviderConfig(projectRoot, 'tavily')).resolves.toEqual({
apiKey: 'stored-tavily-key',
baseUrl: 'https://tavily.example.test',
});
const masked = await readMaskedConfig(projectRoot);
const providers = masked.providers as Record<string, unknown>;
expect(providers.financialdatasets).toMatchObject({
configured: true,
source: 'stored',
apiKeyTail: '-key',
baseUrl: 'https://financialdatasets.example.test',
});
expect(JSON.stringify(masked)).not.toContain('stored-financialdatasets-key');
expect(JSON.stringify(masked)).not.toContain('stored-exa-key');
expect(JSON.stringify(masked)).not.toContain('stored-perplexity-key');
expect(JSON.stringify(masked)).not.toContain('stored-tavily-key');
});
it('resolves research provider credentials from canonical environment variables', async () => {
process.env.FINANCIAL_DATASETS_API_KEY = 'env-financialdatasets-key';
process.env.EXASEARCH_API_KEY = 'env-exasearch-key';
process.env.PERPLEXITY_API_KEY = 'env-perplexity-key';
process.env.TAVILY_API_KEY = 'env-tavily-key';
await writeStoredMediaConfig({
providers: {
financialdatasets: { apiKey: 'stored-financialdatasets-key' },
exa: { apiKey: 'stored-exa-key' },
perplexity: { apiKey: 'stored-perplexity-key' },
tavily: { apiKey: 'stored-tavily-key' },
},
});
await expect(
resolveProviderConfig(projectRoot, 'financialdatasets'),
).resolves.toMatchObject({ apiKey: 'env-financialdatasets-key' });
await expect(resolveProviderConfig(projectRoot, 'exa')).resolves.toMatchObject({
apiKey: 'env-exasearch-key',
});
await expect(
resolveProviderConfig(projectRoot, 'perplexity'),
).resolves.toMatchObject({ apiKey: 'env-perplexity-key' });
await expect(resolveProviderConfig(projectRoot, 'tavily')).resolves.toMatchObject({
apiKey: 'env-tavily-key',
});
const masked = await readMaskedConfig(projectRoot);
const providers = masked.providers as Record<string, unknown>;
expect(providers.financialdatasets).toMatchObject({
configured: true,
source: 'env',
apiKeyTail: '-key',
});
expect(providers.exa).toMatchObject({
configured: true,
source: 'env',
apiKeyTail: '-key',
});
expect(providers.perplexity).toMatchObject({
configured: true,
source: 'env',
apiKeyTail: '-key',
});
expect(providers.tavily).toMatchObject({
configured: true,
source: 'env',
apiKeyTail: '-key',
});
expect(JSON.stringify(masked)).not.toContain('env-financialdatasets-key');
expect(JSON.stringify(masked)).not.toContain('env-exasearch-key');
expect(JSON.stringify(masked)).not.toContain('env-perplexity-key');
expect(JSON.stringify(masked)).not.toContain('env-tavily-key');
});
it('accepts EXA_API_KEY as a compatibility fallback for Exa', async () => {
process.env.EXA_API_KEY = 'env-exa-compat-key';
await expect(resolveProviderConfig(projectRoot, 'exa')).resolves.toMatchObject({
apiKey: 'env-exa-compat-key',
});
});
describe('OD_MEDIA_CONFIG_DIR / OD_DATA_DIR storage routing', () => {
let overrideRoot: string;
let originalMediaConfigDir: string | undefined;
+2 -29
View File
@@ -44,9 +44,6 @@ export type MediaProviderId =
| 'udio'
| 'elevenlabs'
| 'fishaudio'
| 'financialdatasets'
| 'exa'
| 'perplexity'
| 'tavily'
| 'stub';
@@ -198,34 +195,10 @@ export const MEDIA_PROVIDERS: MediaProvider[] = [
defaultBaseUrl: 'https://api.fish.audio',
docsUrl: 'https://fish.audio',
},
{
id: 'financialdatasets',
label: 'Financial Datasets',
hint: '股票/财报/市场数据',
integrated: true,
defaultBaseUrl: 'https://api.financialdatasets.ai',
docsUrl: 'https://financialdatasets.ai',
},
{
id: 'exa',
label: 'Exa',
hint: 'Web search 首选',
integrated: true,
defaultBaseUrl: 'https://api.exa.ai',
docsUrl: 'https://exa.ai',
},
{
id: 'perplexity',
label: 'Perplexity',
hint: 'Web search 第二选择',
integrated: true,
defaultBaseUrl: 'https://api.perplexity.ai',
docsUrl: 'https://docs.perplexity.ai',
},
{
id: 'tavily',
label: 'Tavily',
hint: 'Web search fallback',
label: 'Tavily Search',
hint: 'Agent-callable web research',
integrated: true,
defaultBaseUrl: 'https://api.tavily.com',
docsUrl: 'https://app.tavily.com/home',
@@ -9,7 +9,6 @@ import {
updateAgentCliEnvValue,
updateCurrentApiProtocolConfig,
} from '../../src/components/SettingsDialog';
import { MEDIA_PROVIDERS } from '../../src/media/models';
import type { AppConfig, ConnectionTestResponse } from '../../src/types';
const baseConfig: AppConfig = {
@@ -186,35 +185,6 @@ describe('SettingsDialog provider connection test requirements', () => {
});
});
describe('SettingsDialog media provider catalog', () => {
it('includes the research data provider credentials in Settings', () => {
const providers = Object.fromEntries(
MEDIA_PROVIDERS.map((provider) => [provider.id, provider]),
);
expect(providers.financialdatasets).toMatchObject({
label: 'Financial Datasets',
hint: '股票/财报/市场数据',
});
expect(providers.financialdatasets?.settingsVisible).not.toBe(false);
expect(providers.exa).toMatchObject({
label: 'Exa',
hint: 'Web search 首选',
});
expect(providers.exa?.settingsVisible).not.toBe(false);
expect(providers.perplexity).toMatchObject({
label: 'Perplexity',
hint: 'Web search 第二选择',
});
expect(providers.perplexity?.settingsVisible).not.toBe(false);
expect(providers.tavily).toMatchObject({
label: 'Tavily',
hint: 'Web search fallback',
});
expect(providers.tavily?.settingsVisible).not.toBe(false);
});
});
describe('SettingsDialog custom model picker state', () => {
it('keeps custom input visible while an intermediate value matches a known model', () => {
expect(