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 { // 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'); } } }