mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
Add Exception helper class for consistent error handling and logging. Replace throw statements and console.error calls with Exception methods. Update service methods to return Error | T instead of mixed success/failure objects. Improve type safety in Claude.extractContents with explicit return type. Add WikiLinks helper to VaultCacheService for managing wiki link references. Update unit tests.
70 lines
No EOL
2.4 KiB
TypeScript
70 lines
No EOL
2.4 KiB
TypeScript
import { Resolve } from "Services/DependencyService";
|
|
import { Services } from "Services/Services";
|
|
import type { IConversationNamingService } from "AIClasses/IConversationNamingService";
|
|
import { AIProvider, AIProviderURL, AIProviderModel } from "Enums/ApiProvider";
|
|
import { Role } from "Enums/Role";
|
|
import { NamePrompt } from "AIClasses/NamePrompt";
|
|
import type { SettingsService } from "Services/SettingsService";
|
|
import type OpenAI from "openai";
|
|
import { Exception } from "Helpers/Exception";
|
|
|
|
export class OpenAIConversationNamingService implements IConversationNamingService {
|
|
|
|
private readonly apiKey: string;
|
|
|
|
public constructor() {
|
|
const settingsService = Resolve<SettingsService>(Services.SettingsService);
|
|
this.apiKey = settingsService.getApiKeyForProvider(AIProvider.OpenAI);
|
|
}
|
|
|
|
public async generateName(userPrompt: string, abortSignal?: AbortSignal): Promise<string> {
|
|
|
|
const requestBody = {
|
|
model: AIProviderModel.OpenAINamer,
|
|
max_output_tokens: 100,
|
|
instructions: NamePrompt,
|
|
input: [
|
|
{
|
|
role: Role.User,
|
|
content: userPrompt
|
|
}
|
|
],
|
|
stream: false
|
|
};
|
|
|
|
const response = await fetch(AIProviderURL.OpenAI, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${this.apiKey}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(requestBody),
|
|
signal: abortSignal
|
|
});
|
|
|
|
if (!response.ok) {
|
|
Exception.throw(`OpenAI API error: ${response.status} ${response.statusText} - ${await response.text()}`);
|
|
}
|
|
|
|
const data = await response.json() as OpenAI.Responses.Response;
|
|
|
|
// Try to get the name from output_text first (most common case)
|
|
if (data.output_text && data.output_text.trim()) {
|
|
return data.output_text.trim();
|
|
}
|
|
|
|
// Fall back to checking the output array
|
|
const firstOutput = data.output?.[0];
|
|
const generatedName = firstOutput && 'content' in firstOutput
|
|
? firstOutput.content?.[0]?.type === 'output_text'
|
|
? firstOutput.content[0].text
|
|
: undefined
|
|
: undefined;
|
|
|
|
if (!generatedName) {
|
|
Exception.throw("Failed to generate conversation name");
|
|
}
|
|
|
|
return generatedName;
|
|
}
|
|
} |