fix: move API keys to .env.local, remove localStorage dual system
Single source of truth: OPENAI_API_KEY in .env.local. Deleted the apiKeyService class/singleton that stored keys in localStorage. All server code reads process.env directly. FirstRunModal and Settings now show .env.local instructions instead of key input. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
49ff3678a3
commit
3b04a1bad0
@@ -1,5 +1,6 @@
|
||||
import { openai as openaiProvider } from '@ai-sdk/openai';
|
||||
import { generateText } from 'ai';
|
||||
import { hasValidOpenAiKey } from '../storage/apiKeys';
|
||||
|
||||
export interface DescriptionInput {
|
||||
title: string;
|
||||
@@ -15,16 +16,8 @@ export interface DescriptionInput {
|
||||
dimensions?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have a valid OpenAI API key configured.
|
||||
* Checks both environment variable and validates format.
|
||||
*/
|
||||
export function hasValidOpenAiKey(): boolean {
|
||||
const key = process.env.OPENAI_API_KEY;
|
||||
if (!key || key === 'your-openai-api-key-here') return false;
|
||||
// Valid OpenAI keys start with sk- or sk-proj-
|
||||
return key.startsWith('sk-') && key.length > 20;
|
||||
}
|
||||
// Re-export for backwards compatibility — canonical source is ../storage/apiKeys
|
||||
export { hasValidOpenAiKey } from '../storage/apiKeys';
|
||||
|
||||
/**
|
||||
* Generate a simple fallback description without AI.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getSQLiteClient } from './sqlite-client';
|
||||
import { openai as openaiProvider } from '@ai-sdk/openai';
|
||||
import { generateText } from 'ai';
|
||||
import { hasValidOpenAiKey } from './descriptionService';
|
||||
import { hasValidOpenAiKey } from '../storage/apiKeys';
|
||||
|
||||
export interface Dimension {
|
||||
name: string;
|
||||
|
||||
@@ -2,7 +2,6 @@ import { getSQLiteClient } from './sqlite-client';
|
||||
import { Edge, EdgeContext, EdgeData, EdgeCreatedVia, NodeConnection, Node } from '@/types/database';
|
||||
import { eventBroadcaster } from '../events';
|
||||
import { nodeService } from './nodes';
|
||||
import { apiKeyService } from '../storage/apiKeys';
|
||||
import { generateText } from 'ai';
|
||||
import { createOpenAI } from '@ai-sdk/openai';
|
||||
import { z } from 'zod';
|
||||
@@ -54,7 +53,7 @@ async function inferEdgeContext(params: {
|
||||
|
||||
// If no API key is configured, degrade gracefully.
|
||||
// We still enforce explanation, but fall back to "related_to" classification.
|
||||
const apiKey = apiKeyService.getOpenAiKey();
|
||||
const apiKey = process.env.OPENAI_API_KEY;
|
||||
if (!apiKey) {
|
||||
return { type: 'related_to', confidence: 0.0, swap_direction: false };
|
||||
}
|
||||
@@ -119,7 +118,7 @@ async function autoInferEdge(params: {
|
||||
}): Promise<{ explanation: string; type: EdgeContext['type']; confidence: number; swap_direction: boolean }> {
|
||||
const { fromNode, toNode } = params;
|
||||
|
||||
const apiKey = apiKeyService.getOpenAiKey();
|
||||
const apiKey = process.env.OPENAI_API_KEY;
|
||||
if (!apiKey) {
|
||||
// Fallback without AI
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user