Conversation
8fdec3e to
1847282
Compare
✅ Deployed crypto-map-next
|
Use a bash script for generating embeddings since node is not available in the database container image.
1847282 to
1a12c54
Compare
database/schema.ts
Outdated
| export type Location = typeof locations.$inferSelect | ||
| export type LocationCategory = typeof locationCategories.$inferSelect |
There was a problem hiding this comment.
This was my mistake. This kind of types are defined in ~/shared/types. defining the types here seems to no give us anything.
database/startup.sh
Outdated
| /docker-entrypoint-initdb.d/03-seed.sh || true | ||
|
|
||
| # Run the vector embeddings generation | ||
| echo "Running vector embeddings generation on startup..." |
There was a problem hiding this comment.
This morning the whole docker/supabase thing was refactored completely. I think this might create a mergin issue. I will fix it in this PR :)
server/api/search.get.ts
Outdated
| if (error instanceof Error && error.message.includes('OpenAI API key')) { | ||
| consola.warn('OpenAI API key not configured, falling back to keyword-only search') | ||
| } | ||
| else if (error instanceof Error && error.message.includes('OpenAI authentication')) { | ||
| consola.warn('OpenAI authentication failed, falling back to keyword-only search') | ||
| } | ||
| else if (error instanceof Error && error.message.includes('vector')) { | ||
| consola.warn('Vector database operations failed, falling back to keyword-only search') |
There was a problem hiding this comment.
i would remove this completely. Just use
throw createError(error)
createError is a function from h3.
if we needed it we can always add more details later, but let;s keep the code clean i would say
server/utils/config-validation.ts
Outdated
| private static validateVectorSearchConfig( | ||
| config: any, | ||
| errors: string[], | ||
| warnings: string[], | ||
| ): void { | ||
| if (typeof config.keywordLimit !== 'number' || config.keywordLimit < 1 || config.keywordLimit > 100) { | ||
| errors.push('VECTOR_SEARCH_KEYWORD_LIMIT must be a number between 1 and 100') | ||
| } | ||
|
|
||
| if (typeof config.vectorLimit !== 'number' || config.vectorLimit < 1 || config.vectorLimit > 100) { | ||
| errors.push('VECTOR_SEARCH_VECTOR_LIMIT must be a number between 1 and 100') | ||
| } | ||
|
|
||
| if (typeof config.hybridThreshold !== 'number' || config.hybridThreshold < 1 || config.hybridThreshold > 50) { | ||
| errors.push('VECTOR_SEARCH_HYBRID_THRESHOLD must be a number between 1 and 50') | ||
| } | ||
|
|
||
| if (typeof config.similarityThreshold !== 'number' || config.similarityThreshold < 0 || config.similarityThreshold > 1) { | ||
| errors.push('VECTOR_SEARCH_SIMILARITY_THRESHOLD must be a number between 0 and 1') | ||
| } | ||
|
|
||
| // Logical validation | ||
| if (config.hybridThreshold > config.keywordLimit) { | ||
| warnings.push('VECTOR_SEARCH_HYBRID_THRESHOLD is greater than VECTOR_SEARCH_KEYWORD_LIMIT. Vector search may never be triggered.') | ||
| } | ||
|
|
||
| if (config.similarityThreshold > 0.9) { | ||
| warnings.push('VECTOR_SEARCH_SIMILARITY_THRESHOLD is very high (>0.9). This may result in very few vector search results.') | ||
| } | ||
|
|
||
| if (config.similarityThreshold < 0.3) { | ||
| warnings.push('VECTOR_SEARCH_SIMILARITY_THRESHOLD is very low (<0.3). This may result in many irrelevant vector search results.') | ||
| } | ||
| } |
There was a problem hiding this comment.
This kind of check adds complexity. we can always improve the safeRuntimeConfig to add these checks.
server/plugins/config-validation.ts
Outdated
| /** | ||
| * Nitro plugin to validate configuration during server startup | ||
| */ | ||
| export default defineNitroPlugin(async (_nitroApp) => { |
There was a problem hiding this comment.
since the validateVectorSearchConfig is unnecessary, this whole plugin is also unnecessary imo
server/utils/config-validation.ts
Outdated
| /** | ||
| * Validate all required environment variables and configuration | ||
| */ | ||
| static validateConfiguration(): void { |
server/utils/embedding.ts
Outdated
| /** | ||
| * Service for generating embeddings using OpenAI API | ||
| */ | ||
| export class EmbeddingService { |
There was a problem hiding this comment.
I think this is way too much code.
we can use something like this https://ai-sdk.dev/docs/ai-sdk-core/embeddings#embedding-a-single-value
Then setup the OPENAI_API_KEY in .env and it should be more than enough.
There was a problem hiding this comment.
config such as maxRetries: 3,
baseDelay: 1000, // 1 second
maxDelay: 30000, // 30 seconds
batchSize: 100, // OpenAI batch limit
not necessaary in m opinion. the ai sdk provides that for us
There was a problem hiding this comment.
also the "batch" optimization is also not ncessary.
I would suggest to run a embedding manually for the categories and put the result in the database/seed The scrit can be run with tsx and ai sdk. We should run it only once.
in the future if we update the categories, then we run it again.
- Remove Location type from schema (use shared/types) - Simplify error handling in search endpoint - Remove config validation (use safeRuntimeConfig) - Remove location embeddings (only category embeddings) - Revert to named catalog structure in workspace - Remove vector search dependencies and config
- Add full-text search on location name and address - Add category similarity search using embeddings - Cache query embeddings in NuxtHub KV (30 day TTL) - Combine text and category results with deduplication - Use AI SDK for embedding generation - Support user-selected category filters
- Add /api/search/autocomplete for fast full-text search - Add /api/search/embed for background embedding precompute - Remove TTL from embedding cache (permanent storage) - Min query length: 2 characters
- Add form-based autocomplete with search icon - Show user's query as first result - Display matching locations below with map pin icons - Precompute embeddings while typing (background) - Support UUID-based location fetching - Extract locationSelect helper to reduce duplication - Use semantic search when submitting user's query - Use direct UUID fetch when selecting location
- Format template to one line per element - Use @submit.prevent for form submission - Remove icons from autocomplete locations - Add PostgreSQL ts_headline for match highlighting - Style <mark> tags as bold (no background) - Move search.get.ts to search/index.get.ts
Add vector embedding for search queries.
This closes #11.