Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ FIRECRAWL_API_KEY=fc-your-api-key-here
# Get yours at https://platform.openai.com
OPENAI_API_KEY=sk-your-api-key-here

# Optional: Ollama configuration
# OLLAMA_API_BASE="http://localhost:11434/v1" # Example for local Ollama
# OLLAMA_MODEL="deepseek-coder" # Example model, replace with your desired Ollama model

# Enable unlimited mode (optional)
# When true, removes all limits on rows, columns, and file size
# Automatically enabled in development mode
Expand Down
25 changes: 17 additions & 8 deletions app/api/enrich/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,21 @@ export async function POST(request: NextRequest) {
// Check environment variables and headers for API keys
const openaiApiKey = process.env.OPENAI_API_KEY || request.headers.get('X-OpenAI-API-Key');
const firecrawlApiKey = process.env.FIRECRAWL_API_KEY || request.headers.get('X-Firecrawl-API-Key');
const ollamaApiBase = process.env.OLLAMA_API_BASE || request.headers.get('X-Ollama-API-Base');
const ollamaModel = process.env.OLLAMA_MODEL || request.headers.get('X-Ollama-Model');

if (!openaiApiKey || !firecrawlApiKey) {
console.error('Missing API keys:', {
hasOpenAI: !!openaiApiKey,
hasFirecrawl: !!firecrawlApiKey
});
if (!firecrawlApiKey) {
console.error('Missing Firecrawl API key');
return NextResponse.json(
{ error: 'Server configuration error: Missing API keys' },
{ error: 'Server configuration error: Missing Firecrawl API key' },
{ status: 500 }
);
}

if (!openaiApiKey && (!ollamaApiBase || !ollamaModel)) {
console.error('Missing OpenAI API key or Ollama configuration');
return NextResponse.json(
{ error: 'Server configuration error: Missing OpenAI API key or Ollama configuration' },
{ status: 500 }
);
}
Expand All @@ -69,8 +76,10 @@ export async function POST(request: NextRequest) {

console.log(`[STRATEGY] Using ${strategyName} - Advanced multi-agent architecture with specialized agents`);
const enrichmentStrategy = new AgentEnrichmentStrategy(
openaiApiKey,
firecrawlApiKey
openaiApiKey || 'ollama', // Pass 'ollama' if using Ollama, actual key not needed by OpenAIService then
firecrawlApiKey,
ollamaApiBase,
ollamaModel
);

// Load skip list
Expand Down
23 changes: 17 additions & 6 deletions app/api/generate-fields/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,30 @@ export async function POST(request: NextRequest) {
);
}

if (!process.env.OPENAI_API_KEY) {
const openaiApiKey = process.env.OPENAI_API_KEY;
const ollamaApiBase = process.env.OLLAMA_API_BASE;
const ollamaModel = process.env.OLLAMA_MODEL;

if (!openaiApiKey && (!ollamaApiBase || !ollamaModel)) {
return NextResponse.json(
{ error: 'OpenAI API key not configured' },
{ error: 'OpenAI API key or Ollama configuration not configured' },
{ status: 500 }
);
}

const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAI(
(ollamaApiBase && ollamaModel) ? {
apiKey: 'ollama', // Ollama doesn't require an API key
baseURL: ollamaApiBase,
} : {
apiKey: openaiApiKey,
}
);

const modelToUse = (ollamaApiBase && ollamaModel) ? ollamaModel : 'gpt-4o';

const completion = await openai.chat.completions.create({
model: 'gpt-4o',
model: modelToUse,
messages: [
{
role: 'system',
Expand Down
6 changes: 4 additions & 2 deletions lib/agent-architecture/orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ export class AgentOrchestrator {

constructor(
private firecrawlApiKey: string,
private openaiApiKey: string
private openaiApiKey: string,
private ollamaApiBase?: string,
private ollamaModel?: string,
) {
this.firecrawl = new FirecrawlService(firecrawlApiKey);
this.openai = new OpenAIService(openaiApiKey);
this.openai = new OpenAIService(openaiApiKey, ollamaApiBase, ollamaModel);
}

async enrichRow(
Expand Down
28 changes: 22 additions & 6 deletions lib/services/openai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,25 @@ import type { EnrichmentField, EnrichmentResult } from '../types';

export class OpenAIService {
private client: OpenAI;
private ollamaBaseUrl?: string;
private ollamaModel?: string;

constructor(apiKey: string) {
this.client = new OpenAI({ apiKey });
constructor(apiKey: string, ollamaBaseUrl?: string, ollamaModel?: string) {
this.ollamaBaseUrl = ollamaBaseUrl;
this.ollamaModel = ollamaModel;

if (this.ollamaBaseUrl && this.ollamaModel) {
this.client = new OpenAI({
apiKey: 'ollama', // Ollama doesn't require an API key
baseURL: this.ollamaBaseUrl,
});
} else {
this.client = new OpenAI({ apiKey });
}
}

private getModel(): string {
return this.ollamaModel || 'gpt-4o';
}

createEnrichmentSchema(fields: EnrichmentField[]) {
Expand Down Expand Up @@ -139,7 +155,7 @@ export class OpenAIService {
}

const response = await this.client.chat.completions.create({
model: 'gpt-4o',
model: this.getModel(),
messages: [
{
role: 'system',
Expand Down Expand Up @@ -374,7 +390,7 @@ DOMAIN PARKING/SALE PAGES:
}

const response = await this.client.chat.completions.create({
model: 'gpt-4o',
model: this.getModel(),
messages: [
{
role: 'system',
Expand Down Expand Up @@ -754,7 +770,7 @@ REMEMBER: Extract exact_text from the "=== ACTUAL CONTENT BELOW ===" section, NO
.join('\n');

const response = await this.client.chat.completions.create({
model: 'gpt-4o-mini',
model: this.getModel(),
messages: [
{
role: 'system',
Expand Down Expand Up @@ -824,7 +840,7 @@ ${schemaDescription}
): Promise<string[]> {
try {
const response = await this.client.chat.completions.create({
model: 'gpt-4o',
model: this.getModel(),
messages: [
{
role: 'system',
Expand Down
4 changes: 3 additions & 1 deletion lib/strategies/agent-enrichment-strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ export class AgentEnrichmentStrategy {
constructor(
openaiApiKey: string,
firecrawlApiKey: string,
ollamaApiBase?: string,
ollamaModel?: string,
) {
this.orchestrator = new AgentOrchestrator(firecrawlApiKey, openaiApiKey);
this.orchestrator = new AgentOrchestrator(firecrawlApiKey, openaiApiKey, ollamaApiBase, ollamaModel);
}

async enrichRow(
Expand Down