mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
Add Claude and OpenAI provider support with token services
- Add Claude and OpenAI to AIProviderModel enum - Implement ClaudeTokenService and OpenAITokenService - Update service registration to handle new providers - Install @anthropic-ai/sdk and gpt-tokenizer dependencies - Add error handling for invalid provider selection
This commit is contained in:
parent
023913b0b7
commit
bf948a79b2
8 changed files with 114 additions and 3 deletions
9
AIClasses/Claude/ClaudeConversationNamingService.ts
Normal file
9
AIClasses/Claude/ClaudeConversationNamingService.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import type { IConversationNamingService } from "AIClasses/IConversationNamingService";
|
||||
|
||||
export class ClaudeConversationNamingService implements IConversationNamingService {
|
||||
|
||||
public async generateName(userPrompt: string, abortSignal?: AbortSignal): Promise<string> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
30
AIClasses/Claude/ClaudeTokenService.ts
Normal file
30
AIClasses/Claude/ClaudeTokenService.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import type { ITokenService } from "AIClasses/ITokenService";
|
||||
import Anthropic from '@anthropic-ai/sdk'
|
||||
import type AIAgentPlugin from "main";
|
||||
import { Resolve } from "Services/DependencyService";
|
||||
import { Services } from "Services/Services";
|
||||
import { AIProviderModel } from "Enums/ApiProvider";
|
||||
import { Role } from "Enums/Role";
|
||||
|
||||
export class ClaudeTokenService implements ITokenService {
|
||||
|
||||
private ai: Anthropic;
|
||||
|
||||
public constructor() {
|
||||
this.ai = new Anthropic({
|
||||
apiKey: Resolve<AIAgentPlugin>(Services.AIAgentPlugin).settings.apiKey
|
||||
})
|
||||
}
|
||||
|
||||
public async countTokens(input: string): Promise<number> {
|
||||
// to maintain the convenience of the interface we just submit the entire input as one message
|
||||
const result = await this.ai.messages.countTokens({
|
||||
model: AIProviderModel.Claude,
|
||||
messages: [
|
||||
{ role: Role.User, content: input }
|
||||
]
|
||||
})
|
||||
return result.input_tokens;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ export class GeminiTokenService implements ITokenService {
|
|||
|
||||
public constructor() {
|
||||
this.ai = new GoogleGenAI({
|
||||
apiKey: Resolve<AIAgentPlugin>(Services.AIAgentPlugin).settings.apiKey
|
||||
apiKey: Resolve<AIAgentPlugin>(Services.AIAgentPlugin).settings.apiKey
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
10
AIClasses/OpenAI/OpenAITokenService.ts
Normal file
10
AIClasses/OpenAI/OpenAITokenService.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { ITokenService } from "AIClasses/ITokenService";
|
||||
import { countTokens } from 'gpt-tokenizer'
|
||||
|
||||
export class OpenAITokenService implements ITokenService {
|
||||
|
||||
public async countTokens(input: string): Promise<number> {
|
||||
return countTokens(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,7 +5,9 @@ export enum AIProvider {
|
|||
};
|
||||
|
||||
export enum AIProviderModel {
|
||||
Gemini = "gemini-2.5-flash"
|
||||
Claude = "claude-sonnet-4-5",
|
||||
Gemini = "gemini-2.5-flash",
|
||||
OpenAI = ""
|
||||
}
|
||||
|
||||
export enum AIProviderURL {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import { VaultService } from "./VaultService";
|
|||
import type { ITokenService } from "AIClasses/ITokenService";
|
||||
import { GeminiTokenService } from "AIClasses/Gemini/GeminiTokenService";
|
||||
import { StatusBarService } from "./StatusBarService";
|
||||
import { ClaudeTokenService } from "AIClasses/Claude/ClaudeTokenService";
|
||||
import { OpenAITokenService } from "AIClasses/OpenAI/OpenAITokenService";
|
||||
|
||||
export function RegisterDependencies(plugin: AIAgentPlugin) {
|
||||
RegisterSingleton<AIAgentPlugin>(Services.AIAgentPlugin, plugin);
|
||||
|
|
@ -46,11 +48,20 @@ export function RegisterDependencies(plugin: AIAgentPlugin) {
|
|||
}
|
||||
|
||||
export function RegisterAiProvider(plugin: AIAgentPlugin) {
|
||||
if (plugin.settings.apiProvider == AIProvider.Gemini) {
|
||||
if (plugin.settings.apiProvider == AIProvider.Claude) {
|
||||
RegisterSingleton<ITokenService>(Services.ITokenService, new ClaudeTokenService());
|
||||
}
|
||||
else if (plugin.settings.apiProvider == AIProvider.Gemini) {
|
||||
RegisterSingleton<IAIClass>(Services.IAIClass, new Gemini());
|
||||
RegisterSingleton<ITokenService>(Services.ITokenService, new GeminiTokenService());
|
||||
RegisterSingleton<IConversationNamingService>(Services.IConversationNamingService, new GeminiConversationNamingService());
|
||||
}
|
||||
else if (plugin.settings.apiProvider == AIProvider.OpenAI) {
|
||||
RegisterSingleton<ITokenService>(Services.ITokenService, new OpenAITokenService());
|
||||
}
|
||||
else { // should be impossible to land here
|
||||
throw new Error("Invalid Provider Selection!");
|
||||
}
|
||||
Resolve<ChatService>(Services.ChatService).resolveAIProvider();
|
||||
Resolve<ConversationNamingService>(Services.ConversationNamingService).resolveNamingProvider();
|
||||
}
|
||||
|
|
|
|||
47
package-lock.json
generated
47
package-lock.json
generated
|
|
@ -9,10 +9,12 @@
|
|||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.67.0",
|
||||
"@google/genai": "^1.17.0",
|
||||
"@shikijs/rehype": "^3.12.2",
|
||||
"core-js": "^3.45.1",
|
||||
"express": "^5.1.0",
|
||||
"gpt-tokenizer": "^3.2.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"katex": "^0.16.22",
|
||||
"lowlight": "^3.3.0",
|
||||
|
|
@ -53,6 +55,26 @@
|
|||
"typescript": "~5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/sdk": {
|
||||
"version": "0.67.0",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.67.0.tgz",
|
||||
"integrity": "sha512-Buxbf6jYJ+pPtfCgXe1pcFtZmdXPrbdqhBjiscFt9irS1G0hCsmR/fPA+DwKTk4GPjqeNnnCYNecXH6uVZ4G/A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"json-schema-to-ts": "^3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"anthropic-ai-sdk": "bin/cli"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"zod": "^3.25.0 || ^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"zod": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
|
||||
|
|
@ -2772,6 +2794,12 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gpt-tokenizer": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-3.2.0.tgz",
|
||||
"integrity": "sha512-QRRhzJIHcGbbdzhMGNCHhF+98RVaBaVD5+NYgyPOamqRBEqG5yN9p5j4udnY5FJnkesjdUPsikG/DO4OfJdhpQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/graphemer": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
||||
|
|
@ -3459,6 +3487,19 @@
|
|||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/json-schema-to-ts": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
|
||||
"integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"ts-algebra": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
|
|
@ -6786,6 +6827,12 @@
|
|||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-algebra": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz",
|
||||
"integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ts-dedent": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
|
||||
|
|
|
|||
|
|
@ -28,10 +28,12 @@
|
|||
"typescript": "~5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.67.0",
|
||||
"@google/genai": "^1.17.0",
|
||||
"@shikijs/rehype": "^3.12.2",
|
||||
"core-js": "^3.45.1",
|
||||
"express": "^5.1.0",
|
||||
"gpt-tokenizer": "^3.2.0",
|
||||
"highlight.js": "^11.11.1",
|
||||
"katex": "^0.16.22",
|
||||
"lowlight": "^3.3.0",
|
||||
|
|
|
|||
Loading…
Reference in a new issue