Skip to content

feat: add dynamic model fetching from provider APIs#59

Open
adryserage wants to merge 30 commits intovas3k:mainfrom
adryserage:feature/dynamic-model-fetcher
Open

feat: add dynamic model fetching from provider APIs#59
adryserage wants to merge 30 commits intovas3k:mainfrom
adryserage:feature/dynamic-model-fetcher

Conversation

@adryserage
Copy link

@adryserage adryserage commented Jan 17, 2026

Summary

This PR adds the ability to dynamically fetch available models directly from each LLM provider's API, eliminating the problem of users configuring invalid model names.

Features

  • Dynamic model list: Fetch available models from OpenAI, Google Gemini, and Mistral APIs
  • Model selection dropdown: After entering an API key, users can click refresh (↻) to load available models and select from a dropdown
  • Vision support indicators: Models that support image input are marked with a 👁 icon
  • Smart caching: Model lists are cached for 1 hour to reduce API calls
  • Graceful fallback: If API fetch fails, users can still manually enter model names

How it works

  1. User enters their API key
  2. User clicks the refresh button (↻)
  3. The system fetches available models from the provider's API
  4. User selects a model from the dropdown or types manually

API Endpoints Used

  • OpenAI: GET https://api.openai.com/v1/models (docs)
  • Google Gemini: GET https://generativelanguage.googleapis.com/v1beta/models (docs)
  • Mistral: GET https://api.mistral.ai/v1/models (docs)

Files Changed

  • lib/model-fetcher.ts: Core utility for fetching models from each provider
  • app/api/models/route.ts: API endpoint to expose model fetching
  • components/settings/llm-settings-form.tsx: Updated UI with model selection

Test plan

  • Enter a valid OpenAI API key → click refresh → verify models load
  • Enter a valid Google API key → click refresh → verify Gemini models load
  • Enter a valid Mistral API key → click refresh → verify Mistral models load
  • Select a model from dropdown → verify it's saved correctly
  • Enter an invalid API key → verify appropriate error message
  • Verify model list is cached (second refresh should be faster)

Related: This PR complements #58 which improves error messages for invalid models

- Add helpful error messages for invalid model names, API key issues,
  rate limits, and quota errors
- Update default Google model from non-existent "gemini-2.5-flash" to
  valid "gemini-2.0-flash"
- Add suggested models list for each provider in settings UI
- Improve error logging with model name context
- Use safer key-based provider lookup instead of array indices

Fixes vas3k#57
- Add model-fetcher.ts utility to fetch available models from OpenAI,
  Google Gemini, and Mistral APIs
- Add /api/models endpoint to expose model fetching functionality
- Update LLM settings form with dynamic model selection dropdown
- Add refresh button to fetch models when API key is provided
- Display model count and vision support indicators
- Cache model lists for 1 hour to reduce API calls

This allows users to see exactly which models they have access to
with their API key, preventing invalid model configuration errors.
Parse date-only strings (YYYY-MM-DD) as local midnight instead of UTC
midnight to prevent dates from shifting by one day for users in timezones
behind UTC.

Fixes vas3k#22 vas3k#20

Changes:
- forms/transactions.ts: Parse form date inputs as local time
- models/export_and_import.ts: Parse CSV import dates as local time
- Add duplicateTransaction function in models/transactions.ts
- Add duplicateTransactionAction in transactions/actions.ts
- Add Duplicate button to transaction edit form
- Duplicated transactions get "(Copy)" suffix and no file references

Closes vas3k#38
- Add Ollama provider to lib/llm-providers.ts
- Add Ollama handling in ai/providers/llmProvider.ts using OpenAI-compatible API
- Update models/settings.ts to handle Ollama configuration
- Add Ollama environment variables to .env.example

Ollama enables fully local/private LLM processing with vision-capable models
like llava, llama3.2-vision, and bakllava.

Closes vas3k#17
- Add 'order' column to Field model in Prisma schema
- Implement updateFieldOrders function in models/fields.ts
- Create FieldsSettingsForm component with @dnd-kit for drag-and-drop
- Add reorderFieldsAction server action
- Update fields settings page to use new component
…ck (vas3k#32)

- Add SKIP_DB_CHECK environment variable support in docker-entrypoint.sh
- When set to 'true', skips the PostgreSQL connection check on startup
- Useful for external PostgreSQL or when URL parsing fails with special characters
- Document the option in .env.example
- Track last selected transaction index
- When SHIFT is held during click, select all transactions in range
- Range selection works in both directions (up and down)
- Combines with existing selection (union behavior)
- Add parentCode field to Category model with self-referential relation
- Update models/categories.ts to include children and add getCategoriesHierarchical
- Update categoryFormSchema to include parentCode field
- Update add/edit category actions to handle parentCode
- Update FormSelectCategory to display hierarchical categories with indentation
- Update categories settings page with parent category selector column

Closes vas3k#6
- Add tax_year_start setting to configure when tax year begins (MM-DD format)
- Add TaxYearSelector component for quick tax year filtering
- Integrate tax year selector into transaction filters
- Support both calendar years (01-01) and fiscal years (e.g., 04-06 for UK)
- Auto-detect selected tax year from date range

Closes vas3k#44
- Add collapsible "Recognized Text" section to the analyze form
- Display OCR/extracted text directly during analysis (no need to save first)
- Show character count badge for recognized text
- Allow editing of recognized text before saving
- Use monospace font for better readability of raw text

Closes vas3k#42
Refactor docker-compose configuration to use env_file for environment variables and improve volume management.
- Add engines field to package.json requiring Node >= 20
- Create nixpacks.toml to configure Node 22 for Dokploy builds
- Add .nvmrc file documenting Node 22 requirement
- Update GitHub Actions cache scope to bust stale Node 18 layers
- Replace File type with UploadedFile interface in server actions
  to avoid runtime errors in Node.js environments where File
  global may not be available

Fixes build failures caused by:
- EBADENGINE warnings from packages requiring Node >= 20
- ReferenceError: File is not defined during Next.js build
Adds support for SQLite as an alternative database provider, enabling
simpler single-container deployments without requiring a separate
PostgreSQL server.

Changes:
- Add prisma/schema.sqlite.prisma for SQLite-compatible schema
- Create scripts/select-schema.js to select schema based on DATABASE_PROVIDER
- Update docker-entrypoint.sh to handle both PostgreSQL and SQLite
- Add docker-compose.sqlite.yml for SQLite-only deployments
- Update package.json with db:setup and postinstall scripts
- Update nixpacks.toml to support both database providers
- Update .env.example with database configuration options

Usage:
- PostgreSQL: DATABASE_URL=postgresql://user:pass@host:5432/db
- SQLite: DATABASE_URL=file:./data/taxhacker.db

The database provider is auto-detected from DATABASE_URL, or can be
explicitly set via DATABASE_PROVIDER=postgresql|sqlite
- Create lib/db-compat.ts with utilities for handling JSON fields
- Update SQLite schema to include missing 'order' field and Category parent/child relations
- Fix getAppData/setAppData to parse/stringify JSON for SQLite
- Update transaction model to handle both PostgreSQL (native JSON) and SQLite (string) types
- Add parseFilesArray helper to handle files field in both database types
- Fix case-insensitive search to work with SQLite (no 'mode' support)
- Update components to parse JSON fields that could be strings in SQLite
- Add NEXT_TELEMETRY_DISABLED=1 to Dockerfile
- Remove prisma migrate deploy from npm start (handled by docker-entrypoint.sh)
- Prevents migration conflict error when using SQLite
The NEXT_TELEMETRY_DISABLED=1 environment variable alone doesn't
prevent the telemetry status message from appearing during build.
Added explicit `npx next telemetry disable` command before npm run build
in both Dockerfile and nixpacks.toml.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant