157 lines
6.1 KiB
TypeScript
157 lines
6.1 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import Groq from 'groq-sdk';
|
|
import OpenAI from 'openai';
|
|
import { BusinessListingCriteria } from '../models/main.model';
|
|
|
|
// const businessListingCriteriaStructure = {
|
|
// criteriaType: 'business | commercialProperty | broker',
|
|
// types: "'Automotive'|'Industrial Services'|'Food and Restaurant'|'Real Estate'|'Retail'|'Oilfield SVE and MFG.'|'Service'|'Advertising'|'Agriculture'|'Franchise'|'Professional'|'Manufacturing'",
|
|
// city: 'string',
|
|
// state: 'string',
|
|
// county: 'string',
|
|
// minPrice: 'number',
|
|
// maxPrice: 'number',
|
|
// minRevenue: 'number',
|
|
// maxRevenue: 'number',
|
|
// minCashFlow: 'number',
|
|
// maxCashFlow: 'number',
|
|
// minNumberEmployees: 'number',
|
|
// maxNumberEmployees: 'number',
|
|
// establishedSince: 'number',
|
|
// establishedUntil: 'number',
|
|
// realEstateChecked: 'boolean',
|
|
// leasedLocation: 'boolean',
|
|
// franchiseResale: 'boolean',
|
|
// title: 'string',
|
|
// brokerName: 'string',
|
|
// searchType: "'exact' | 'radius'",
|
|
// radius: "'0' | '5' | '20' | '50' | '100' | '200' | '300' | '400' | '500'",
|
|
// };
|
|
|
|
const BusinessListingCriteriaStructure = `
|
|
export interface BusinessListingCriteria {
|
|
state: string;
|
|
city: string;
|
|
searchType: 'exact' | 'radius';
|
|
radius: '20' | '50' | '100' | '200' | '300' | '400' | '500';
|
|
|
|
minPrice: number;
|
|
maxPrice: number;
|
|
minRevenue: number;
|
|
maxRevenue: number;
|
|
minCashFlow: number;
|
|
maxCashFlow: number;
|
|
minNumberEmployees: number;
|
|
maxNumberEmployees: number;
|
|
establishedSince: number;
|
|
establishedUntil: number;
|
|
realEstateChecked: boolean;
|
|
leasedLocation: boolean;
|
|
franchiseResale: boolean;
|
|
//title: string;
|
|
brokerName: string;
|
|
//types:"'Automotive'|'Industrial Services'|'Food and Restaurant'|'Real Estate'|'Retail'|'Oilfield SVE and MFG.'|'Service'|'Advertising'|'Agriculture'|'Franchise'|'Professional'|'Manufacturing'",
|
|
criteriaType: 'businessListings';
|
|
}
|
|
`;
|
|
const CommercialPropertyListingCriteriaStructure = `
|
|
export interface CommercialPropertyListingCriteria {
|
|
state: string;
|
|
city: string;
|
|
searchType: 'exact' | 'radius';
|
|
radius: '20' | '50' | '100' | '200' | '300' | '400' | '500';
|
|
|
|
minPrice: number;
|
|
maxPrice: number;
|
|
//title: string;
|
|
//types:"'Retail'|'Land'|'Industrial'|'Office'|'Mixed Use'|'Multifamily'|'Uncategorized'"
|
|
criteriaType: 'commercialPropertyListings';
|
|
}
|
|
`;
|
|
const UserListingCriteriaStructure = `
|
|
export interface UserListingCriteria {
|
|
state: string;
|
|
city: string;
|
|
searchType: 'exact' | 'radius';
|
|
radius: '20' | '50' | '100' | '200' | '300' | '400' | '500';
|
|
|
|
brokerName: string;
|
|
companyName: string;
|
|
counties: string[];
|
|
criteriaType: 'brokerListings';
|
|
}
|
|
|
|
`;
|
|
@Injectable()
|
|
export class AiService {
|
|
private readonly openai: OpenAI;
|
|
private readonly groq: Groq;
|
|
constructor() {
|
|
this.openai = new OpenAI({
|
|
apiKey: process.env.OPENAI_API_KEY, // Verwenden Sie Umgebungsvariablen für den API-Schlüssel
|
|
});
|
|
this.groq = new Groq({ apiKey: process.env.GROQ_API_KEY });
|
|
}
|
|
|
|
async getBusinessCriteria(query: string): Promise<BusinessListingCriteria> {
|
|
// const prompt = `
|
|
// Dieses Objekt ist wie folgt definiert: ${JSON.stringify(businessListingCriteriaStructure)}.
|
|
// Die Antwort darf nur das von dir befüllte JSON als unformatierten Text enthalten so das es von mir mit JSON.parse() einlesbar ist!!!!
|
|
// Falls es Ortsangaben gibt, dann befülle City, County und State wenn möglich Die Suchanfrage des Users lautet: "${query}"`;
|
|
const prompt = `The Search Query of the User is: "${query}"`;
|
|
let response = null;
|
|
try {
|
|
response = await this.openai.chat.completions.create({
|
|
model: 'gpt-4o-mini',
|
|
//model: 'gpt-3.5-turbo',
|
|
max_tokens: 300,
|
|
messages: [
|
|
{
|
|
role: 'system',
|
|
content: `Please create unformatted JSON Object from a user input.
|
|
The criteriaType must be only either 'businessListings' or 'commercialPropertyListings' or 'brokerListings' !!!!
|
|
The format of the object (depending on your choice of criteriaType) must be either ${BusinessListingCriteriaStructure}, ${CommercialPropertyListingCriteriaStructure} or ${UserListingCriteriaStructure} !!!!
|
|
If location details available please fill city and state as State Code and only county if explicitly mentioned.
|
|
If you decide for searchType==='exact', please do not set the attribute radius`,
|
|
},
|
|
{
|
|
role: 'user',
|
|
content: prompt,
|
|
},
|
|
],
|
|
temperature: 0.5,
|
|
response_format: { type: 'json_object' },
|
|
});
|
|
|
|
// response = await this.groq.chat.completions.create({
|
|
// messages: [
|
|
// {
|
|
// role: 'system',
|
|
// content: `Please create unformatted JSON Object from a user input.
|
|
// The criteriaType must be only either 'businessListings' or 'commercialPropertyListings' or 'brokerListings' !!!!
|
|
// The format of the object (depending on your choice of criteriaType) must be either ${BusinessListingCriteriaStructure}, ${CommercialPropertyListingCriteriaStructure} or ${UserListingCriteriaStructure} !!!!
|
|
// If location details available please fill city and state as State Code and only county if explicitly mentioned.
|
|
// If you decide for searchType==='exact', please do not set the attribute radius`,
|
|
// },
|
|
// {
|
|
// role: 'user',
|
|
// content: prompt,
|
|
// },
|
|
// ],
|
|
// model: 'llama-3.3-70b-versatile',
|
|
// temperature: 0.2,
|
|
// max_tokens: 300,
|
|
// response_format: { type: 'json_object' },
|
|
// });
|
|
|
|
const generatedCriteria = JSON.parse(response.choices[0]?.message?.content);
|
|
return generatedCriteria;
|
|
|
|
// return response.choices[0]?.message?.content;
|
|
} catch (error) {
|
|
console.error(`Error calling GPT-4 API: ${response.choices[0]}`, error);
|
|
throw new Error('Failed to generate business criteria');
|
|
}
|
|
}
|
|
}
|