feat: Make semantic search optional and disabled by default

- Add SemanticSearchConfig interface with enabled toggle to siteConfig.ts
- Default semantic search to disabled (enabled: false) to avoid blocking forks without OPENAI_API_KEY
- Update SearchModal.tsx to conditionally show mode toggle based on config
- Update sync-posts.ts to skip embedding generation when disabled
- Add semantic search toggle to Dashboard config generator
- Update FORK_CONFIG.md with Semantic Search Configuration section
- Update fork-config.json.example with semanticSearch option
- Update docs-semantic-search.md with enable/disable instructions
- Update changelog and documentation

When disabled (default):
- Search modal shows only keyword search (no mode toggle)
- Embedding generation skipped during sync
- No OpenAI API key required

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Wayne Sutton
2026-01-05 22:22:50 -08:00
parent 5a8df46681
commit 3c9feb071b
15 changed files with 239 additions and 49 deletions

View File

@@ -4,6 +4,7 @@ import matter from "gray-matter";
import { ConvexHttpClient } from "convex/browser";
import { api } from "../convex/_generated/api";
import dotenv from "dotenv";
import { siteConfig } from "../src/config/siteConfig";
// Load environment variables based on SYNC_ENV
const isProduction = process.env.SYNC_ENV === "production";
@@ -375,22 +376,26 @@ async function syncPosts() {
}
}
// Generate embeddings for semantic search (if OPENAI_API_KEY is configured)
console.log("\nGenerating embeddings for semantic search...");
try {
const embeddingResult = await client.action(
api.embeddings.generateMissingEmbeddings,
{}
);
if (embeddingResult.skipped) {
console.log(" Skipped: OPENAI_API_KEY not configured");
} else {
console.log(` Posts: ${embeddingResult.postsProcessed} embeddings generated`);
console.log(` Pages: ${embeddingResult.pagesProcessed} embeddings generated`);
// Generate embeddings for semantic search (if enabled in siteConfig and OPENAI_API_KEY is configured)
if (siteConfig.semanticSearch?.enabled === false) {
console.log("\nSkipping embedding generation (semantic search disabled in siteConfig)");
} else {
console.log("\nGenerating embeddings for semantic search...");
try {
const embeddingResult = await client.action(
api.embeddings.generateMissingEmbeddings,
{}
);
if (embeddingResult.skipped) {
console.log(" Skipped: OPENAI_API_KEY not configured");
} else {
console.log(` Posts: ${embeddingResult.postsProcessed} embeddings generated`);
console.log(` Pages: ${embeddingResult.pagesProcessed} embeddings generated`);
}
} catch (error) {
// Non-fatal - continue even if embedding generation fails
console.log(" Warning: Could not generate embeddings:", error);
}
} catch (error) {
// Non-fatal - continue even if embedding generation fails
console.log(" Warning: Could not generate embeddings:", error);
}
// Generate static raw markdown files in public/raw/