diff --git a/apps/api/src/services/fetch/fetch.service.ts b/apps/api/src/services/fetch/fetch.service.ts index 3908e8148..7d074ee9b 100644 --- a/apps/api/src/services/fetch/fetch.service.ts +++ b/apps/api/src/services/fetch/fetch.service.ts @@ -40,11 +40,15 @@ export class FetchService implements OnModuleInit { const url = input instanceof Request ? input.url : input.toString(); const urlRedacted = this.redactUrl(url); + const matchedWebFetchDomain = this.getMatchingWebFetchDomain(url, method); Logger.debug(`${method} ${urlRedacted}`, 'FetchService'); - if (method === 'GET' && this.matchesWebFetchDomain(url)) { - const response = await this.fetchViaWebFetchTool(url); + if (matchedWebFetchDomain) { + const response = await this.fetchViaWebFetchTool( + url, + matchedWebFetchDomain + ); if (response) { return response; @@ -71,7 +75,8 @@ export class FetchService implements OnModuleInit { } private async fetchViaWebFetchTool( - url: string + url: string, + webFetchDomain: WebFetchDomain ): Promise { const [openRouterApiKey, openRouterModel] = await Promise.all([ this.propertyService.getByKey(PROPERTY_API_KEY_OPENROUTER), @@ -107,7 +112,7 @@ export class FetchService implements OnModuleInit { }); const candidates = [ - ...sources.map((source) => { + ...(sources ?? []).map((source) => { return source.providerMetadata?.openrouter?.content; }), text @@ -120,19 +125,25 @@ export class FetchService implements OnModuleInit { const body = candidate.trim(); - try { - JSON.parse(body); - } catch { + if (!body) { continue; } + if (webFetchDomain.responseContentType.includes('application/json')) { + try { + JSON.parse(body); + } catch { + continue; + } + } + Logger.debug( `Routed ${this.redactUrl(url)} via web fetch tool`, 'FetchService' ); return new Response(body, { - headers: { 'content-type': 'application/json' } + headers: { 'content-type': webFetchDomain.responseContentType } }); } @@ -149,15 +160,22 @@ export class FetchService implements OnModuleInit { } } - private matchesWebFetchDomain(rawUrl: string): boolean { + private getMatchingWebFetchDomain( + rawUrl: string, + method: string + ): WebFetchDomain | undefined { try { const { hostname } = new URL(rawUrl); - return this.webFetchDomains.some(({ domain }) => { - return hostname === domain || hostname.endsWith(`.${domain}`); + return this.webFetchDomains.find((webFetchDomain) => { + const { domain, methods } = webFetchDomain; + const matchesDomain = + hostname === domain || hostname.endsWith(`.${domain}`); + + return matchesDomain && methods.includes(method); }); } catch { - return false; + return undefined; } } diff --git a/apps/api/src/services/fetch/interfaces/web-fetch-domain.interface.ts b/apps/api/src/services/fetch/interfaces/web-fetch-domain.interface.ts index 231438181..122caecc4 100644 --- a/apps/api/src/services/fetch/interfaces/web-fetch-domain.interface.ts +++ b/apps/api/src/services/fetch/interfaces/web-fetch-domain.interface.ts @@ -1,3 +1,5 @@ export interface WebFetchDomain { domain: string; + methods: string[]; + responseContentType: string; }