{"version":3,"file":"xxmachina-components-services-openai.mjs","sources":["../../../../../packages/@xxmachina/components/src/lib/services/openai/openai.service.ts","../../../../../packages/@xxmachina/components/src/lib/services/openai/xxmachina-components-services-openai.ts"],"sourcesContent":["import { computed, inject, Injectable, InjectionToken, Provider, signal } from '@angular/core';\nimport OpenAI, { ClientOptions } from 'openai';\nimport type { ChatCompletionMessageParam } from 'openai/resources/chat/completions';\nimport { Message } from '@ng-atomic/common/models';\nimport { HttpClient } from '@angular/common/http';\nimport { lastValueFrom } from 'rxjs';\n\nasync function imageToBase64(imageFile: File): Promise<string> {\n  return new Promise((resolve, reject) => {\n    const reader = new FileReader();\n    reader.onload = () => {\n      const base64String = reader.result as string;\n      resolve(base64String.split(',')[1]);\n    };\n    reader.onerror = reject;\n    reader.readAsDataURL(imageFile);\n  });\n}\n\nclass OpenAiMessageHelper {\n  static async buildMessage(message: Message): Promise<ChatCompletionMessageParam> {\n    if (message?.attachments?.length) {\n      const content = await Promise.all(message.attachments.map(async attachment => ({\n        type: 'image_url' as const,\n        image_url: { url: `data:image/jpeg;base64,${await imageToBase64(attachment.file)}` },\n      })));\n      return {\n        role: message.role as 'user',\n        content: [\n          ...content,\n          { type: 'text', text: message.content }\n        ] as never\n      };\n    }\n\n    return {\n      role: message.role,\n      content: message?.content || ''\n    }\n  }\n}\n\nexport const OPENAI_CONFIG = new InjectionToken<ClientOptions>('[@xxmachina/components/services/openai] OpenAiConfig');\nexport const OPENAI_BACKEND_URL = new InjectionToken<string>('[@xxmachina/components/services/openai] OpenAiBackendUrl');\n\nexport function provideOpenaiConfig(useFactory?: () => ClientOptions) {\n  return [\n    { provide: OPENAI_CONFIG, useFactory },\n  ]\n}\n\nexport function provideOpenaiBackendUrl(url: string) {\n  return { provide: OPENAI_BACKEND_URL, useValue: url };\n}\n\n@Injectable({ providedIn: 'root' })\nexport class OpenAIService {\n  readonly config = inject(OPENAI_CONFIG);\n  readonly apiKey = signal(this.config?.apiKey);\n  readonly openai = computed(() => new OpenAI(this.config));\n  readonly hasApiKey = computed(() => (this.apiKey() as string)?.trim() !== '');\n\n  async complete(_messages: Message[]): Promise<Message[]> {\n    const resolvedMessages = await Promise.all(_messages.map(message => OpenAiMessageHelper.buildMessage(message)));\n    console.debug('[OpenAIService] resolvedMessages', resolvedMessages);\n    const response = await this.openai().chat.completions.create({\n      model: 'gpt-4o-mini',\n      messages: [...resolvedMessages],\n    });\n    const assistantMessage = response.choices[0]?.message?.content || 'エラーが発生しました。';\n    return [\n      ..._messages,\n      { role: 'assistant', content: assistantMessage, time: new Date() }\n    ];\n  }\n}\n\n@Injectable()\nexport class OpenAIViaBackendService extends OpenAIService {\n  private readonly http = inject(HttpClient);\n  private readonly backendUrl = inject(OPENAI_BACKEND_URL);\n\n  async complete(_messages: Message[]): Promise<Message[]> {\n    const resolvedMessages = await Promise.all(_messages.map(message => OpenAiMessageHelper.buildMessage(message)));\n    console.debug('[OpenAIService] resolvedMessages', resolvedMessages);\n    const response = await lastValueFrom(this.http.post<any>(this.backendUrl, {\n      model: 'gpt-4o-mini',\n      messages: [...resolvedMessages],\n    }))\n    const assistantMessage = response.choices[0]?.message?.content || 'エラーが発生しました。';\n    return [\n      ..._messages,\n      { role: 'assistant', content: assistantMessage, time: new Date() }\n    ];\n  }\n}\n\nexport function provideOpenAIViaBackendService(backendUrl: string): Provider[] {\n  return [\n    { provide: OPENAI_BACKEND_URL, useValue: backendUrl },\n    { provide: OpenAIService, useClass: OpenAIViaBackendService },\n  ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}