explainthisrepo 0.9.3 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/init.js +10 -1
- package/dist/providers/anthropic.d.ts +17 -0
- package/dist/providers/anthropic.js +68 -0
- package/dist/providers/registry.js +2 -0
- package/package.json +1 -1
package/dist/init.js
CHANGED
|
@@ -5,7 +5,8 @@ import { writeConfig } from "./config.js";
|
|
|
5
5
|
const PROVIDERS = {
|
|
6
6
|
"1": "gemini",
|
|
7
7
|
"2": "openai",
|
|
8
|
-
"3": "ollama"
|
|
8
|
+
"3": "ollama",
|
|
9
|
+
"4": "anthropic",
|
|
9
10
|
};
|
|
10
11
|
export async function runInit() {
|
|
11
12
|
const err = process.stderr;
|
|
@@ -42,6 +43,7 @@ async function promptProvider() {
|
|
|
42
43
|
err.write(" 1) Gemini\n");
|
|
43
44
|
err.write(" 2) OpenAI\n");
|
|
44
45
|
err.write(" 3) Ollama (local)\n");
|
|
46
|
+
err.write(" 4) Anthropic\n");
|
|
45
47
|
const choice = (await prompt("> ")).trim();
|
|
46
48
|
const provider = PROVIDERS[choice];
|
|
47
49
|
if (!provider) {
|
|
@@ -76,6 +78,13 @@ async function promptProviderConfig(provider) {
|
|
|
76
78
|
host
|
|
77
79
|
};
|
|
78
80
|
}
|
|
81
|
+
if (provider === "anthropic") {
|
|
82
|
+
const key = (await promptHidden("Anthropic API key: ")).trim();
|
|
83
|
+
if (!key) {
|
|
84
|
+
throw new Error("API key cannot be empty");
|
|
85
|
+
}
|
|
86
|
+
return { api_key: key };
|
|
87
|
+
}
|
|
79
88
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
80
89
|
}
|
|
81
90
|
function prompt(label) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LLMProvider } from "./base.js";
|
|
2
|
+
type AnthropicConfig = {
|
|
3
|
+
api_key?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class AnthropicProvider implements LLMProvider {
|
|
7
|
+
name: string;
|
|
8
|
+
private apiKey;
|
|
9
|
+
private model;
|
|
10
|
+
private client;
|
|
11
|
+
constructor(config?: AnthropicConfig);
|
|
12
|
+
validateConfig(): void;
|
|
13
|
+
private getClient;
|
|
14
|
+
generate(prompt: string): Promise<string>;
|
|
15
|
+
doctor(): Promise<string[]>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { LLMProviderError } from "./base.js";
|
|
2
|
+
const DEFAULT_MODEL = "claude-3-5-sonnet-20241022";
|
|
3
|
+
export class AnthropicProvider {
|
|
4
|
+
name = "anthropic";
|
|
5
|
+
apiKey;
|
|
6
|
+
model;
|
|
7
|
+
client = null;
|
|
8
|
+
constructor(config = {}) {
|
|
9
|
+
this.apiKey = config.api_key ?? "";
|
|
10
|
+
this.model = config.model ?? DEFAULT_MODEL;
|
|
11
|
+
this.validateConfig();
|
|
12
|
+
}
|
|
13
|
+
validateConfig() {
|
|
14
|
+
if (!this.apiKey || !this.apiKey.trim()) {
|
|
15
|
+
throw new LLMProviderError("Anthropic provider requires an API key.\n" +
|
|
16
|
+
"Run `explainthisrepo init` or set providers.anthropic.api_key.");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
getClient() {
|
|
20
|
+
if (this.client) {
|
|
21
|
+
return this.client;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const { default: Anthropic } = require("@anthropic-ai/sdk");
|
|
25
|
+
this.client = new Anthropic({ apiKey: this.apiKey });
|
|
26
|
+
return this.client;
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
throw new LLMProviderError("Anthropic support is not installed.\n" +
|
|
30
|
+
"Install it with:\n" +
|
|
31
|
+
' npm install @anthropic-ai/sdk');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async generate(prompt) {
|
|
35
|
+
const client = this.getClient();
|
|
36
|
+
let response;
|
|
37
|
+
try {
|
|
38
|
+
response = await client.messages.create({
|
|
39
|
+
model: this.model,
|
|
40
|
+
max_tokens: 1024,
|
|
41
|
+
messages: [
|
|
42
|
+
{ role: "user", content: prompt }
|
|
43
|
+
]
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
const message = err?.message ? String(err.message) : String(err);
|
|
48
|
+
throw new LLMProviderError(`Anthropic request failed: ${message}`);
|
|
49
|
+
}
|
|
50
|
+
let text = null;
|
|
51
|
+
try {
|
|
52
|
+
text = response?.content?.[0]?.text ?? null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
text = null;
|
|
56
|
+
}
|
|
57
|
+
if (!text || !text.trim()) {
|
|
58
|
+
throw new LLMProviderError("Anthropic returned no text");
|
|
59
|
+
}
|
|
60
|
+
return text.trim();
|
|
61
|
+
}
|
|
62
|
+
async doctor() {
|
|
63
|
+
return [
|
|
64
|
+
`ANTHROPIC_API_KEY set: ${Boolean(this.apiKey)}`,
|
|
65
|
+
`model: ${this.model}`,
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -3,10 +3,12 @@ import { LLMProviderError } from "./base.js";
|
|
|
3
3
|
import { GeminiProvider } from "./gemini.js";
|
|
4
4
|
import { OpenAIProvider } from "./openai.js";
|
|
5
5
|
import { OllamaProvider } from "./ollama.js";
|
|
6
|
+
import { AnthropicProvider } from "./anthropic.js";
|
|
6
7
|
const PROVIDER_REGISTRY = {
|
|
7
8
|
gemini: GeminiProvider,
|
|
8
9
|
openai: OpenAIProvider,
|
|
9
10
|
ollama: OllamaProvider,
|
|
11
|
+
anthropic: AnthropicProvider,
|
|
10
12
|
};
|
|
11
13
|
export function listProviders() {
|
|
12
14
|
return Object.keys(PROVIDER_REGISTRY);
|