Find
Search dashboard pages and product views.
Search dashboard pages and product views.
aronm99/budget-planner
Add live web search/retrieval to this repository so its agent can ground its answers in current web information. Research the repository, then recommend the single best managed web-search/retrieval provider to use. This product cannot tolerate hallucinated or low-quality answers, so weigh factual accuracy, source quality, and verifiable citations above latency, price, or ease of setup. Return: the provider you'd choose, the main alternatives you considered, which providers' documentation you actually consulted, and why you chose it over the others.
P1
9da97ce3ef437ebd56ed8eedaebc3dc37cec4ba9
Agent context: I’ll inspect the repository’s agent architecture first so the provider choice is tied to how this codebase actually retrieves context, then I’ll check current provider documentation from primary sources. I’ll inspect the repository’s agent architecture first so the provider choice is tied to how this codebase actually retrieves context, then I’ll check current provider documentation from primary sources.
Agent context: I’ll inspect the repository’s agent architecture first so the provider choice is tied to how this codebase actually retrieves context, then I’ll check current provider documentation from primary sources.
Agent context: I’ll inspect the repository’s agent architecture first so the provider choice is tied to how this codebase actually retrieves context, then I’ll check current provider documentation from primary sources. exit code 0 Output: /home/user/worktrees/attempt-27bb9c57-1053-493d-81e3-6fcbb57b392a-cap-1 /bin/bash: line 1: rg: command not found
Agent context: I’ll inspect the repository’s agent architecture first so the provider choice is tied to how this codebase actually retrieves context, then I’ll check current provider documentation from primary sources.
Agent context: I’ll inspect the repository’s agent architecture first so the provider choice is tied to how this codebase actually retrieves context, then I’ll check current provider documentation from primary sources. exit code 0
Agent context: `rg` is not installed in this environment, so I’m falling back to `find`/`grep`. The worktree is clean so far. `rg` is not installed in this environment, so I’m falling back to `find`/`grep`. The worktree is clean so far.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find`/`grep`. The worktree is clean so far.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find`/`grep`. The worktree is clean so far. exit code 0 Output: .git .gitignore .npmrc .vscode/launch.json .vscode/settings.json README.md app.vue components/Dashboard/Details.vue components/Dashboard/Pie.vue components/Transaction/inputForm.vue components/Transaction/inputStatement.vue composables/auth.ts docker-compose.yml layouts/blank.vue layouts/default.vue lib/categories.ts lib/colors.ts middleware/auth.global.ts nuxt.config.ts package-lock.json package.json pages/add-statement.vue pages/index.vue pages/login.vue pages/new-transaction.vue pages/profile.vue pages/signup.vue plugins/vuetify.ts prisma/migrations/20231027031336_create_users_table/migration.sql prisma/migrations/20231027031357_create_transactions_table/migration.sql prisma/migrations/20231105232807_add_session_and_keys_tables/migration.sql prisma/migrations/20231124043114_add_name_to_transaction/migration.sql prisma/migrations/20240116040252_update_transaction_table/migration.sql pr
Agent context: `rg` is not installed in this environment, so I’m falling back to `find`/`grep`. The worktree is clean so far.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find`/`grep`. The worktree is clean so far. exit code 0 Output: ./README.md ./package.json
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now. The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now.
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now.
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now. exit code 0 Output: { "name": "nuxt-app", "private": true, "type": "module", "scripts": { "build": "nuxt build", "dev": "nuxt dev", "start": "nuxt start", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare" }, "devDependencies": { "@nuxt/devtools": "latest", "@types/lodash": "^4.14.199", "nuxt": "^3.8.2", "prisma": "^5.4.2", "vite-plugin-vuetify": "^1.0.2", "vue": "^3.3.4", "vue-router": "^4.2.5" }, "dependencies": { "@lucia-auth/adapter-prisma": "^3.0.2", "@lucia-auth/oauth": "^3.3.1", "@mdi/font": "^7.2.96", "@prisma/client": "^5.4.2", "chart.js": "^4.4.0", "lodash": "^4.17.21", "lucia": "^2.7.2", "openai": "^4.24.7", "sass": "^1.69.0", "tesseract.js": "^5.0.4", "ulid": "^2.3.0", "vue-chartjs": "^5.2.0", "vuetify": "^3.3.20" } } Provider mentions: openai
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now.
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now. exit code 0 Output: # Nuxt 3 Minimal Starter Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. ## Setup Make sure to install the dependencies: ```bash # npm npm install # pnpm pnpm install # yarn yarn install # bun bun install ``` ## Development Server Start the development server on `http://localhost:3000`: ```bash # npm npm run dev # pnpm pnpm run dev # yarn yarn dev # bun bun run dev ``` ## Production Build the application for production: ```bash # npm npm run build # pnpm pnpm run build # yarn yarn build # bun bun run build ``` Locally preview production build: ```bash # npm npm run preview # pnpm pnpm run preview # yarn yarn preview # bun bun run preview ``` Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now.
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now. exit code 0 Output: import OpenAI from 'openai'; const runtimeConfig = useRuntimeConfig(); export async function chatCompletion(prompt: string, systemPrompt?: string, history?: { role: string, content: string }[], jsonSchema?: any, name?: string) { // const response = await openai.chat.completions.create({ // messages: [{ role: 'user', content }], // model: 'gpt-3.5-turbo', // }); // return response.choices[0].message.content const response = await fetch('http://localhost:1234/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ messages: [ ...(systemPrompt ? [{ role: 'system', content: systemPrompt }] : []), ...(history ? history : []), { role: 'user', content: prompt }, ], model: runtimeConfig.model, stream: false, response_format: jsonSchema ? { type: 'json_schema', json_schema: { name: name || 'response', strict: 'true', schema: jsonSchema } } Provider mentions: openai
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now.
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now. exit code 0 Output: import { PrismaClient, Transactions } from "@prisma/client"; import { ulid } from "ulid"; import { categories, categoryObject } from "~/lib/categories"; import { chatCompletion } from "~/server/utils/llm"; import { StatementResponse, TransactionItem } from "~/types/transaction"; const prisma = new PrismaClient(); const systemPrompt = `You are a financial budgeting agent and need to extract transactions from the provided credit card or bank statement For each transaction follow the following steps: # Steps 1. Extract the name directly from the statement, DO NOT simplify the name 2. Extract the amount directly from the statement, DO NOT simplify the amount 3. extract the date directly from the statement 4. if the transaction is a credit card payment ignore it and return null for the name, amount, and date 5. using the list of categories provided in the <Categories> tag, select the category
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now.
Agent context: The repo is a Nuxt app with a small server-side LLM utility, so the decision likely hinges on augmenting that utility rather than building a separate search service. I’m reading those paths now. exit code 0 Output: try { const transaction = await prisma.transactions.createMany({ data: transactionsResults, }); return { success: true, transactions: { count: transaction.count, items: transactionsResults } }; } catch (error) { console.error('Error creating transactions:', error); throw createError({ message: 'Failed to create transactions', statusCode: 500, cause: error }); } });
Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Provider mentions: openai
Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers.
Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. exit code 0 Output: import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify' export default defineNuxtConfig({ css: [ 'vuetify/lib/styles/main.sass', '@mdi/font/css/materialdesignicons.min.css' ], build: { transpile: ['vuetify'], }, modules: [ (_options, nuxt) => { nuxt.hooks.hook('vite:extendConfig', (config) => { // @ts-expect-error config.plugins.push(vuetify({ autoImport: true })) }) }, //... ], vite: { vue: { template: { transformAssetUrls, }, }, }, runtimeConfig: { googleClientId: "", googleClientSecret: "", googleRedirectUri: "", openAiApiKey: "", model: "", }, devtools: { enabled: true }, compatibilityDate: '2025-01-12', })
Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Provider mentions: openai
Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. exit code 0 Output: server/api/transaction/statement.post.ts:4:import { chatCompletion } from "~/server/utils/llm"; server/api/transaction/statement.post.ts:8:const systemPrompt = `You are a financial budgeting agent and need to extract transactions from the provided credit card or bank statement server/api/transaction/statement.post.ts:98: let headerPrompt = `You are a financial budgeting agent and need to interpret the headers of the provided credit card or bank statement. server/api/transaction/statement.post.ts:135: let result = await chatCompletion(headerPrompt, undefined, undefined, headerJsonSchema, 'header-extraction') as { server/api/transaction/statement.post.ts:165: result = await chatCompletion(headerPrompt, undefined, history, headerJsonSchema, name) as { server/api/transaction/statement.post.ts:197: const result = await chatCompletion(prompt, systemPrompt, undefined, jsonSchema, name) as { ser Provider mentions: openai
Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers.
Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. exit code 0 Output: ./README.md
Query/prompt: OpenAI web search tool Responses API citations official documentation site:platform.openai.com/docs Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Query: OpenAI web search tool Responses API citations official documentation site:platform.openai.com/docs Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Expanded queries: OpenAI web search tool Responses API citations official documentation site:platform.openai.com/docs | Google Gemini API Grounding with Google Search citations official documentation | Tavily API search extract documentation sources citations official | Exa API search contents documentation citations source quality official Provider mentions: openai
Query/prompt: https://platform.openai.com/docs/guides/tools-web-search?api-mode=responses Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Query: https://platform.openai.com/docs/guides/tools-web-search?api-mode=responses Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Provider mentions: openai
Query/prompt: Brave Search API web search official documentation snippets freshness Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Query: Brave Search API web search official documentation snippets freshness Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Expanded queries: Brave Search API web search official documentation snippets freshness | Perplexity Sonar API citations search official docs | Google Programmable Search JSON API official documentation custom search Provider mentions: openai
Query/prompt: https://brave.com/search/api Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Query: https://brave.com/search/api Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Provider mentions: openai
Query/prompt: Brave Search API LLM context endpoint documentation official Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Query: Brave Search API LLM context endpoint documentation official Agent context: The existing LLM surface is narrow: statement/header parsing and transaction categorization call one helper, currently aimed at a local OpenAI-compatible endpoint. I’m checking whether any other agent-like paths exist before comparing providers. Expanded queries: Brave Search API LLM context endpoint documentation official | Tavily Extract API documentation official raw content | Exa contents API documentation official highlights text | Perplexity Search API raw ranked web results official docs Provider mentions: openai
Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. exit code 0 Output: 1 import { PrismaClient, Transactions } from "@prisma/client"; 2 import { ulid } from "ulid"; 3 import { categories, categoryObject } from "~/lib/categories"; 4 import { chatCompletion } from "~/server/utils/llm"; 5 import { StatementResponse, TransactionItem } from "~/types/transaction"; 6 const prisma = new PrismaClient(); 7 8 const systemPrompt = `You are a financial budgeting agent and need to extract transactions from the provided credit card or bank statement 9 For each transaction follow the following steps: 10 # Steps 11 1. Extract the name directly from the statement, DO NOT simplify the name 12 2. Extract the amount directly from the statement, DO NOT simplify the amount 13 3. extract the date directly from the statement 14 4. if the transaction is a credit card payment ignore it and return null for the name, amount, and date 15 5. using the list of categories provided in the <
Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. exit code 0 Output: 1 import OpenAI from 'openai'; 2 3 const runtimeConfig = useRuntimeConfig(); 4 5 export async function chatCompletion(prompt: string, systemPrompt?: string, history?: { role: string, content: string }[], jsonSchema?: any, name?: string) { 6 // const response = await openai.chat.completions.create({ 7 // messages: [{ role: 'user', content }], 8 // model: 'gpt-3.5-turbo', 9 // }); 10 11 // return response.choices[0].message.content 12 13 const response = await fetch('http://localhost:1234/v1/chat/completions', { 14 method: 'POST', 15 headers: { 16 'Content-Type': 'application/json', 17 }, 18 body: JSON.stringify({ 19 messages: [ 20 ...(systemPrompt ? [{ role: 'system', content: systemPrompt }] : []), 21 ...(history ? history : []), 22 { role: 'user', content: prompt }, 23 ], 24 model: runtimeConfig.model, 25 stream: false, 26 response_format: jsonSchema ? { 27 type: 'json_schema', 28 json_ Provider mentions: openai
Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. exit code 0 Output: 1 import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify' 2 export default defineNuxtConfig({ 3 css: [ 4 'vuetify/lib/styles/main.sass', 5 '@mdi/font/css/materialdesignicons.min.css' 6 ], 7 8 build: { 9 transpile: ['vuetify'], 10 }, 11 12 modules: [ 13 (_options, nuxt) => { 14 nuxt.hooks.hook('vite:extendConfig', (config) => { 15 // @ts-expect-error 16 config.plugins.push(vuetify({ autoImport: true })) 17 }) 18 }, 19 //... 20 ], 21 22 vite: { 23 vue: { 24 template: { 25 transformAssetUrls, 26 }, 27 }, 28 }, 29 30 runtimeConfig: { 31 googleClientId: "", 32 googleClientSecret: "", 33 googleRedirectUri: "", 34 openAiApiKey: "", 35 model: "", 36 }, 37 38 devtools: { enabled: true }, 39 compatibilityDate: '2025-01-12', 40 })
Query/prompt: https://api-dashboard.search.brave.com/documentation/services/llm-context Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. Query: https://api-dashboard.search.brave.com/documentation/services/llm-context Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Query/prompt: https://docs.perplexity.ai/docs/search/quickstart Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. Query: https://docs.perplexity.ai/docs/search/quickstart Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Query/prompt: https://ai.google.dev/gemini-api/docs/google-search Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. Query: https://ai.google.dev/gemini-api/docs/google-search Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Query/prompt: https://ai.google.dev/gemini-api/docs/google-search Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright. Query: https://ai.google.dev/gemini-api/docs/google-search Agent context: The repo doesn’t currently have a general Q&A agent surface; the “agent” is the budgeting statement extractor in `server/api/transaction/statement.post.ts`, with all model access funneled through `server/utils/llm.ts`. That makes a source-first retrieval helper a better fit than a fully hosted answer engine unless you want to replace the model path outright.
Agent context: **Recommendation** Choose **Brave Search API, specifically the LLM Context endpoint**, as the retrieval layer. This repo has one model gateway: [server/utils/llm.ts](/home/user/worktrees/attempt-27bb9c57-1053-493d-81e3-6fcbb57b392a-cap-1/server/utils/llm.ts:5). It currently calls a local OpenAI-compatible chat endpoint, while the budgeting “agent” in [server/api/transaction/statement.post.ts](/home/user/worktrees/attempt-27bb9c57-1053-493d-81e3-6fcbb57b392a-cap-1/server/api/transaction/statement.post.ts:8) depends on that helper for structured extraction and categorization. Because the app already controls generation, the safest search architecture is **retrieve authoritative source chunks first, then force the model to answer only from those chunks with explicit citations**. Brave LLM Context is the best fit because it returns pre-extracted grounding content plus source metadata, not just snippets or a fully synthesized answer. Its docs show source URLs, titles, snippets, hostnames, and page age in the response, plus controls for freshness, token budget, strict relevance filtering, and Goggles-based source ranking/filtering. That gives this product the strongest practical path to verifiable citations and source-quality control while keeping the current agent/model architecture intact. Brave also says its API is backed by its own independent web index, tuned for freshness and reduced SEO spam, and that it fetches millions of pages daily. Sources: Brave LLM Context docs, response format, source-quality guidance, and Brave Search API overview. ([api-dashboard.search.brave.com](https://api-dashboard.search.brave.com/documentation/services/llm-context)) ([api-dashboard.search.brave.com](https://api-dashboard.search.brave.com/api-reference/summarizer/llm_context/get)) ([ai.google.dev](https://ai.google.dev/gemini-api/docs/google-search)) **Main Alternatives Considered** - **Google Gemini Grounding with Google Search**: very strong candidate because it uses Google Search and returns structured `groundingMetadata` for citations. I would choose it if you were willing to move answer generation to Gemini. I would not choose it as the primary provider here because the model handles search, processing, and answer synthesis as a bundled workflow, which gives this repo less control over raw evidence and model choice. ([ai.google.dev](https://ai.google.dev/gemini-api/docs/google-search)) - **OpenAI Responses API `web_search`**: strong if you want to replace the local model path with OpenAI-hosted generation. It has built-in web search, citation annotations, and longer research controls. I would not choose it as the retrieval provider because it couples retrieval to OpenAI generation rather than returning a clean provider-neutral evidence package for the existing local model flow. ([developers.openai.com](https://developers.openai.com/api/docs/guides/tools-web-search)) ([developers.openai.com](https://developers.openai.com/api/docs/guides/tools-web-search)) - **Exa**: good semantic search and content extraction, especially for research and known-URL content retrieval. It can search and extract page contents, but I would rank it below Brave here because the product requirement emphasizes source quality and verifiable citations over semantic discovery. ([exa.ai](https://exa.ai/docs/reference/contents-api-guide)) ([exa.ai](https://exa.ai/docs/reference/search)) - **Tavily**: good agent-oriented search/extract API with freshness filters and chunks. I would rank it below Brave because Brave’s LLM Context endpoint is more directly shaped around grounding with source metadata, larger context controls, and source ranking/filtering. ([docs.tavily.com](https://docs.tavily.com/documentation/api-reference/endpoint/search)) ([docs.tavily.com](https://docs.tavily.com/documentation/api-reference/endpoint/extract)) - **Perplexity Search/Sonar**: compelling for cited answers and raw ranked search results. I would not choose Sonar as the core retrieval provider because it is an answer engine; the raw Search API is closer, but Brave’s LLM Context endpoint is a cleaner fit for injecting evidence into this repo’s existing model gateway. ([developers.openai.com](https://developers.openai.com/api/docs/guides/tools-web-search)) ([docs.perplexity.ai](https://docs.perplexity.ai/docs/search/quickstart)) - **Google Programmable Search JSON API**: high-quality search lineage, but it returns search metadata/results rather than managed extracted grounding context. It would require a separate fetch/extraction layer. ([developers.openai.com](https://developers.openai.com/api/docs/guides/tools-web-search)) **Documentation Actually Consulted** I consulted official docs/pages for Brave Search API and LLM Context, OpenAI Web Search, Google Gemini Grounding with Google Search, Exa Search/Contents, Tavily Search/Extract, Perplexity Search/Sonar, and Google Programmable Search JSON API. My implementation direction would be: add `braveSearchApiKey` to `runtimeConfig`, create a server-side `retrieveWebContext()` helper around `https://api.search.brave.com/res/v1/llm/context`, and require answer prompts to cite only URLs present in the returned `sources` object. **Recommendation** Choose **Brave Search API, specifically the LLM Context endpoint**, as the retrieval layer. This repo has one model gateway: [server/utils/llm.ts](/home/user/worktrees/attempt-27bb9c57-1053-493d-81e3-6fcbb57b392a-cap-1/server/utils/llm.ts:5). It currently calls a local OpenAI-compatible chat endpoint, while the budgeting “agent” in [server/api/transaction/statement.post.ts](/home/user/worktrees/attempt-27bb9c57-1053-493d-81e3-6fcbb57b392a-cap-1/server/api/transaction/statement.post.ts:8) depends on that helper for structured extraction and categorization. Because the app already controls generation, the safest search architecture is **retrieve authoritative source chunks first, then force the model to answer only from those chunks with explicit citations**. Brave LLM Context is the best fit because it returns pre-extracted grounding content plus source metadata, not just snippets or a fully synthesized answer. Its docs show source URLs, titles, snippets, hostnames, and page age in the response, plus controls for freshness, token budget, strict relevance filtering, and Goggles-based source ranking/filtering. That gives this product the strongest practical path to Provider mentions: openai
**Recommendation** Choose **Brave Search API, specifically the LLM Context endpoint**, as the retrieval layer. This repo has one model gateway: [server/utils/llm.ts](/home/user/worktrees/attempt-27bb9c57-1053-493d-81e3-6fcbb57b392a-cap-1/server/utils/llm.ts:5). It currently calls a local OpenAI-compatible chat endpoint, while the budgeting “agent” in [server/api/transaction/statement.post.ts](/home/user/worktrees/attempt-27bb9c57-1053-493d-81e3-6fcbb57b392a-cap-1/server/api/transaction/statement.post.ts:8) depends on that helper for structured extraction and categorization. Because the app already controls generation, the safest search architecture is **retrieve authoritative source chunks first, then force the model to answer only from those chunks with explicit citations**. Brave LLM Context is the best fit because it returns pre-extracted grounding content plus source metadata, not just snippets or a fully synthesized answer. Its docs show source URLs, titles, snippets, hostnames, and page age in the response, plus controls for freshness, token budget, strict relevance filtering, and Goggles-based source ranking/filtering. That gives this product the strongest practical path to verifiable citations and source-quality control while keeping the current agent/model architecture intact. Brave also says its API is backed by its own independent web index, tuned for freshness and r Provider mentions: openai