learngraph 0.2.0 → 0.3.0
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/README.md +82 -1
- package/dist/cjs/llm/adapters/anthropic.js +124 -0
- package/dist/cjs/llm/adapters/anthropic.js.map +1 -0
- package/dist/cjs/llm/adapters/base.js +100 -0
- package/dist/cjs/llm/adapters/base.js.map +1 -0
- package/dist/cjs/llm/adapters/index.js +22 -0
- package/dist/cjs/llm/adapters/index.js.map +1 -0
- package/dist/cjs/llm/adapters/ollama.js +149 -0
- package/dist/cjs/llm/adapters/ollama.js.map +1 -0
- package/dist/cjs/llm/adapters/openai.js +126 -0
- package/dist/cjs/llm/adapters/openai.js.map +1 -0
- package/dist/cjs/llm/index.js +34 -5
- package/dist/cjs/llm/index.js.map +1 -1
- package/dist/cjs/llm/orchestrator.js +219 -0
- package/dist/cjs/llm/orchestrator.js.map +1 -0
- package/dist/cjs/llm/prompts.js +367 -0
- package/dist/cjs/llm/prompts.js.map +1 -0
- package/dist/cjs/types/llm.js +8 -0
- package/dist/cjs/types/llm.js.map +1 -0
- package/dist/esm/llm/adapters/anthropic.js +119 -0
- package/dist/esm/llm/adapters/anthropic.js.map +1 -0
- package/dist/esm/llm/adapters/base.js +95 -0
- package/dist/esm/llm/adapters/base.js.map +1 -0
- package/dist/esm/llm/adapters/index.js +10 -0
- package/dist/esm/llm/adapters/index.js.map +1 -0
- package/dist/esm/llm/adapters/ollama.js +144 -0
- package/dist/esm/llm/adapters/ollama.js.map +1 -0
- package/dist/esm/llm/adapters/openai.js +121 -0
- package/dist/esm/llm/adapters/openai.js.map +1 -0
- package/dist/esm/llm/index.js +12 -6
- package/dist/esm/llm/index.js.map +1 -1
- package/dist/esm/llm/orchestrator.js +214 -0
- package/dist/esm/llm/orchestrator.js.map +1 -0
- package/dist/esm/llm/prompts.js +360 -0
- package/dist/esm/llm/prompts.js.map +1 -0
- package/dist/esm/types/llm.js +7 -0
- package/dist/esm/types/llm.js.map +1 -0
- package/dist/types/llm/adapters/anthropic.d.ts +21 -0
- package/dist/types/llm/adapters/anthropic.d.ts.map +1 -0
- package/dist/types/llm/adapters/base.d.ts +46 -0
- package/dist/types/llm/adapters/base.d.ts.map +1 -0
- package/dist/types/llm/adapters/index.d.ts +11 -0
- package/dist/types/llm/adapters/index.d.ts.map +1 -0
- package/dist/types/llm/adapters/ollama.d.ts +30 -0
- package/dist/types/llm/adapters/ollama.d.ts.map +1 -0
- package/dist/types/llm/adapters/openai.d.ts +22 -0
- package/dist/types/llm/adapters/openai.d.ts.map +1 -0
- package/dist/types/llm/index.d.ts +5 -0
- package/dist/types/llm/index.d.ts.map +1 -1
- package/dist/types/llm/orchestrator.d.ts +35 -0
- package/dist/types/llm/orchestrator.d.ts.map +1 -0
- package/dist/types/llm/prompts.d.ts +269 -0
- package/dist/types/llm/prompts.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/types/llm.d.ts +298 -0
- package/dist/types/types/llm.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../../src/types/llm.ts"],"names":[],"mappings":";AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic adapter for LLM integration
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import { BaseLLMAdapter, LLMError, DEFAULT_CONFIG } from './base.js';
|
|
7
|
+
/**
|
|
8
|
+
* Anthropic adapter for Claude models
|
|
9
|
+
*/
|
|
10
|
+
export class AnthropicAdapter extends BaseLLMAdapter {
|
|
11
|
+
baseUrl;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super(config);
|
|
14
|
+
this.baseUrl = config.baseUrl ?? 'https://api.anthropic.com/v1';
|
|
15
|
+
}
|
|
16
|
+
get provider() {
|
|
17
|
+
return 'anthropic';
|
|
18
|
+
}
|
|
19
|
+
async complete(request) {
|
|
20
|
+
if (!this.isConfigured()) {
|
|
21
|
+
throw new LLMError('Anthropic adapter not configured. Set ANTHROPIC_API_KEY or pass apiKey in config.', 'NOT_CONFIGURED', this.provider);
|
|
22
|
+
}
|
|
23
|
+
return this.withRetry(async () => {
|
|
24
|
+
// Extract system message
|
|
25
|
+
const systemMessage = request.messages.find((m) => m.role === 'system');
|
|
26
|
+
const otherMessages = request.messages.filter((m) => m.role !== 'system');
|
|
27
|
+
const headers = {
|
|
28
|
+
'Content-Type': 'application/json',
|
|
29
|
+
'x-api-key': this.config.apiKey,
|
|
30
|
+
'anthropic-version': '2023-06-01',
|
|
31
|
+
};
|
|
32
|
+
const body = {
|
|
33
|
+
model: this.config.model,
|
|
34
|
+
messages: otherMessages.map((m) => ({
|
|
35
|
+
role: m.role,
|
|
36
|
+
content: m.content,
|
|
37
|
+
})),
|
|
38
|
+
max_tokens: request.maxTokens ?? this.config.maxTokens ?? DEFAULT_CONFIG.maxTokens,
|
|
39
|
+
};
|
|
40
|
+
// Add system message if present
|
|
41
|
+
if (systemMessage) {
|
|
42
|
+
body.system = systemMessage.content;
|
|
43
|
+
}
|
|
44
|
+
// Temperature (Anthropic uses 0-1 scale like OpenAI)
|
|
45
|
+
const temp = request.temperature ?? this.config.temperature ?? DEFAULT_CONFIG.temperature;
|
|
46
|
+
if (temp !== undefined) {
|
|
47
|
+
body.temperature = temp;
|
|
48
|
+
}
|
|
49
|
+
const controller = new AbortController();
|
|
50
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeout ?? DEFAULT_CONFIG.timeout);
|
|
51
|
+
try {
|
|
52
|
+
const response = await fetch(`${this.baseUrl}/messages`, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers,
|
|
55
|
+
body: JSON.stringify(body),
|
|
56
|
+
signal: controller.signal,
|
|
57
|
+
});
|
|
58
|
+
clearTimeout(timeout);
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
const errorData = (await response.json().catch(() => ({})));
|
|
61
|
+
const errorMessage = errorData.error?.message ?? `HTTP ${response.status}`;
|
|
62
|
+
if (response.status === 429) {
|
|
63
|
+
throw new LLMError(`Rate limit exceeded: ${errorMessage}`, 'RATE_LIMIT', this.provider);
|
|
64
|
+
}
|
|
65
|
+
throw new LLMError(`Anthropic API error: ${errorMessage}`, 'API_ERROR', this.provider);
|
|
66
|
+
}
|
|
67
|
+
const data = (await response.json());
|
|
68
|
+
// Get text content
|
|
69
|
+
const textBlock = data.content.find((block) => block.type === 'text');
|
|
70
|
+
const content = textBlock?.text ?? '';
|
|
71
|
+
let json;
|
|
72
|
+
if (request.responseFormat === 'json') {
|
|
73
|
+
json = this.parseJSON(content);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
content,
|
|
77
|
+
json,
|
|
78
|
+
usage: {
|
|
79
|
+
promptTokens: data.usage.input_tokens,
|
|
80
|
+
completionTokens: data.usage.output_tokens,
|
|
81
|
+
totalTokens: data.usage.input_tokens + data.usage.output_tokens,
|
|
82
|
+
},
|
|
83
|
+
model: data.model,
|
|
84
|
+
finishReason: data.stop_reason === 'end_turn' ? 'stop' :
|
|
85
|
+
data.stop_reason === 'max_tokens' ? 'length' : 'error',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
clearTimeout(timeout);
|
|
90
|
+
if (error instanceof LLMError) {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
if (error instanceof Error) {
|
|
94
|
+
if (error.name === 'AbortError') {
|
|
95
|
+
throw new LLMError('Request timeout', 'TIMEOUT', this.provider, error);
|
|
96
|
+
}
|
|
97
|
+
throw new LLMError(`Network error: ${error.message}`, 'NETWORK_ERROR', this.provider, error);
|
|
98
|
+
}
|
|
99
|
+
throw new LLMError('Unknown error', 'API_ERROR', this.provider);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Create an Anthropic adapter from environment variables
|
|
106
|
+
*/
|
|
107
|
+
export function createAnthropicAdapter(model = 'claude-3-5-sonnet-20241022', overrides) {
|
|
108
|
+
const apiKey = typeof process !== 'undefined' ? process.env.ANTHROPIC_API_KEY : undefined;
|
|
109
|
+
const config = {
|
|
110
|
+
provider: 'anthropic',
|
|
111
|
+
model,
|
|
112
|
+
...overrides,
|
|
113
|
+
};
|
|
114
|
+
if (apiKey) {
|
|
115
|
+
config.apiKey = apiKey;
|
|
116
|
+
}
|
|
117
|
+
return new AnthropicAdapter(config);
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../../src/llm/adapters/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base adapter class for LLM providers
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* LLM-related errors
|
|
8
|
+
*/
|
|
9
|
+
export class LLMError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
provider;
|
|
12
|
+
cause;
|
|
13
|
+
constructor(message, code, provider, cause) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.provider = provider;
|
|
17
|
+
this.cause = cause;
|
|
18
|
+
this.name = 'LLMError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Default configuration values
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_CONFIG = {
|
|
25
|
+
maxTokens: 4096,
|
|
26
|
+
temperature: 0.3,
|
|
27
|
+
timeout: 60000,
|
|
28
|
+
retries: 2,
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Abstract base class for LLM adapters
|
|
32
|
+
*/
|
|
33
|
+
export class BaseLLMAdapter {
|
|
34
|
+
config;
|
|
35
|
+
constructor(config) {
|
|
36
|
+
this.config = {
|
|
37
|
+
...DEFAULT_CONFIG,
|
|
38
|
+
...config,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
get model() {
|
|
42
|
+
return this.config.model;
|
|
43
|
+
}
|
|
44
|
+
isConfigured() {
|
|
45
|
+
if (this.provider === 'ollama') {
|
|
46
|
+
return !!this.config.model;
|
|
47
|
+
}
|
|
48
|
+
return !!this.config.apiKey && !!this.config.model;
|
|
49
|
+
}
|
|
50
|
+
getConfig() {
|
|
51
|
+
const { apiKey: _, ...rest } = this.config;
|
|
52
|
+
return rest;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Retry a function with exponential backoff
|
|
56
|
+
*/
|
|
57
|
+
async withRetry(fn, maxRetries = this.config.retries ?? DEFAULT_CONFIG.retries) {
|
|
58
|
+
let lastError;
|
|
59
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
60
|
+
try {
|
|
61
|
+
return await fn();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
65
|
+
// Don't retry on certain errors
|
|
66
|
+
if (error instanceof LLMError) {
|
|
67
|
+
if (error.code === 'NOT_CONFIGURED' || error.code === 'INVALID_RESPONSE') {
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (attempt < maxRetries) {
|
|
72
|
+
// Exponential backoff: 1s, 2s, 4s, ...
|
|
73
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
throw lastError;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse JSON from LLM response, handling common issues
|
|
82
|
+
*/
|
|
83
|
+
parseJSON(content) {
|
|
84
|
+
// Try to extract JSON from markdown code blocks
|
|
85
|
+
const jsonMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
86
|
+
const jsonStr = jsonMatch && jsonMatch[1] ? jsonMatch[1].trim() : content.trim();
|
|
87
|
+
try {
|
|
88
|
+
return JSON.parse(jsonStr);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throw new LLMError(`Failed to parse JSON response: ${error instanceof Error ? error.message : 'Unknown error'}`, 'PARSE_ERROR', this.provider, error instanceof Error ? error : undefined);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../../src/llm/adapters/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM adapter exports
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
export { BaseLLMAdapter, LLMError, DEFAULT_CONFIG } from './base.js';
|
|
7
|
+
export { OpenAIAdapter, createOpenAIAdapter } from './openai.js';
|
|
8
|
+
export { AnthropicAdapter, createAnthropicAdapter } from './anthropic.js';
|
|
9
|
+
export { OllamaAdapter, createOllamaAdapter } from './ollama.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/llm/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGrE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama adapter for local LLM integration
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import { BaseLLMAdapter, LLMError, DEFAULT_CONFIG } from './base.js';
|
|
7
|
+
/**
|
|
8
|
+
* Ollama adapter for local models
|
|
9
|
+
*/
|
|
10
|
+
export class OllamaAdapter extends BaseLLMAdapter {
|
|
11
|
+
baseUrl;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super(config);
|
|
14
|
+
this.baseUrl = config.baseUrl ?? 'http://localhost:11434';
|
|
15
|
+
}
|
|
16
|
+
get provider() {
|
|
17
|
+
return 'ollama';
|
|
18
|
+
}
|
|
19
|
+
isConfigured() {
|
|
20
|
+
return !!this.config.model;
|
|
21
|
+
}
|
|
22
|
+
async complete(request) {
|
|
23
|
+
if (!this.isConfigured()) {
|
|
24
|
+
throw new LLMError('Ollama adapter not configured. Set model in config.', 'NOT_CONFIGURED', this.provider);
|
|
25
|
+
}
|
|
26
|
+
return this.withRetry(async () => {
|
|
27
|
+
const body = {
|
|
28
|
+
model: this.config.model,
|
|
29
|
+
messages: request.messages.map((m) => ({
|
|
30
|
+
role: m.role,
|
|
31
|
+
content: m.content,
|
|
32
|
+
})),
|
|
33
|
+
stream: false,
|
|
34
|
+
options: {
|
|
35
|
+
num_predict: request.maxTokens ?? this.config.maxTokens ?? DEFAULT_CONFIG.maxTokens,
|
|
36
|
+
temperature: request.temperature ?? this.config.temperature ?? DEFAULT_CONFIG.temperature,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
// Add JSON format if requested
|
|
40
|
+
if (request.responseFormat === 'json') {
|
|
41
|
+
body.format = 'json';
|
|
42
|
+
}
|
|
43
|
+
const controller = new AbortController();
|
|
44
|
+
// Ollama can be slow, use longer timeout
|
|
45
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeout ?? DEFAULT_CONFIG.timeout * 2);
|
|
46
|
+
try {
|
|
47
|
+
const response = await fetch(`${this.baseUrl}/api/chat`, {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
headers: {
|
|
50
|
+
'Content-Type': 'application/json',
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify(body),
|
|
53
|
+
signal: controller.signal,
|
|
54
|
+
});
|
|
55
|
+
clearTimeout(timeout);
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
const errorText = await response.text().catch(() => '');
|
|
58
|
+
throw new LLMError(`Ollama API error: HTTP ${response.status} - ${errorText}`, 'API_ERROR', this.provider);
|
|
59
|
+
}
|
|
60
|
+
const data = (await response.json());
|
|
61
|
+
const content = data.message?.content ?? '';
|
|
62
|
+
let json;
|
|
63
|
+
if (request.responseFormat === 'json') {
|
|
64
|
+
json = this.parseJSON(content);
|
|
65
|
+
}
|
|
66
|
+
// Estimate tokens (Ollama provides eval_count)
|
|
67
|
+
const promptTokens = data.prompt_eval_count ?? Math.ceil(request.messages.reduce((acc, m) => acc + m.content.length, 0) / 4);
|
|
68
|
+
const completionTokens = data.eval_count ?? Math.ceil(content.length / 4);
|
|
69
|
+
return {
|
|
70
|
+
content,
|
|
71
|
+
json,
|
|
72
|
+
usage: {
|
|
73
|
+
promptTokens,
|
|
74
|
+
completionTokens,
|
|
75
|
+
totalTokens: promptTokens + completionTokens,
|
|
76
|
+
},
|
|
77
|
+
model: data.model,
|
|
78
|
+
finishReason: data.done ? 'stop' : 'error',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
clearTimeout(timeout);
|
|
83
|
+
if (error instanceof LLMError) {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
if (error instanceof Error) {
|
|
87
|
+
if (error.name === 'AbortError') {
|
|
88
|
+
throw new LLMError('Request timeout', 'TIMEOUT', this.provider, error);
|
|
89
|
+
}
|
|
90
|
+
// Check for connection refused
|
|
91
|
+
if (error.message.includes('ECONNREFUSED') || error.message.includes('fetch failed')) {
|
|
92
|
+
throw new LLMError(`Cannot connect to Ollama at ${this.baseUrl}. Is Ollama running?`, 'NETWORK_ERROR', this.provider, error);
|
|
93
|
+
}
|
|
94
|
+
throw new LLMError(`Network error: ${error.message}`, 'NETWORK_ERROR', this.provider, error);
|
|
95
|
+
}
|
|
96
|
+
throw new LLMError('Unknown error', 'API_ERROR', this.provider);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Check if Ollama is available
|
|
102
|
+
*/
|
|
103
|
+
async isAvailable() {
|
|
104
|
+
try {
|
|
105
|
+
const response = await fetch(`${this.baseUrl}/api/tags`, {
|
|
106
|
+
method: 'GET',
|
|
107
|
+
});
|
|
108
|
+
return response.ok;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* List available models
|
|
116
|
+
*/
|
|
117
|
+
async listModels() {
|
|
118
|
+
try {
|
|
119
|
+
const response = await fetch(`${this.baseUrl}/api/tags`, {
|
|
120
|
+
method: 'GET',
|
|
121
|
+
});
|
|
122
|
+
if (!response.ok) {
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
const data = (await response.json());
|
|
126
|
+
return data.models?.map((m) => m.name) ?? [];
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Create an Ollama adapter
|
|
135
|
+
*/
|
|
136
|
+
export function createOllamaAdapter(model = 'llama3.2', overrides) {
|
|
137
|
+
return new OllamaAdapter({
|
|
138
|
+
provider: 'ollama',
|
|
139
|
+
model,
|
|
140
|
+
baseUrl: 'http://localhost:11434',
|
|
141
|
+
...overrides,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../../src/llm/adapters/ollama.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI adapter for LLM integration
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
import { BaseLLMAdapter, LLMError, DEFAULT_CONFIG } from './base.js';
|
|
7
|
+
/**
|
|
8
|
+
* OpenAI adapter for chat completions
|
|
9
|
+
*/
|
|
10
|
+
export class OpenAIAdapter extends BaseLLMAdapter {
|
|
11
|
+
baseUrl;
|
|
12
|
+
organization;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
super(config);
|
|
15
|
+
this.baseUrl = config.baseUrl ?? 'https://api.openai.com/v1';
|
|
16
|
+
if (config.organization) {
|
|
17
|
+
this.organization = config.organization;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
get provider() {
|
|
21
|
+
return 'openai';
|
|
22
|
+
}
|
|
23
|
+
async complete(request) {
|
|
24
|
+
if (!this.isConfigured()) {
|
|
25
|
+
throw new LLMError('OpenAI adapter not configured. Set OPENAI_API_KEY or pass apiKey in config.', 'NOT_CONFIGURED', this.provider);
|
|
26
|
+
}
|
|
27
|
+
return this.withRetry(async () => {
|
|
28
|
+
const headers = {
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
31
|
+
};
|
|
32
|
+
if (this.organization) {
|
|
33
|
+
headers['OpenAI-Organization'] = this.organization;
|
|
34
|
+
}
|
|
35
|
+
const body = {
|
|
36
|
+
model: this.config.model,
|
|
37
|
+
messages: request.messages.map((m) => ({
|
|
38
|
+
role: m.role,
|
|
39
|
+
content: m.content,
|
|
40
|
+
})),
|
|
41
|
+
max_tokens: request.maxTokens ?? this.config.maxTokens ?? DEFAULT_CONFIG.maxTokens,
|
|
42
|
+
temperature: request.temperature ?? this.config.temperature ?? DEFAULT_CONFIG.temperature,
|
|
43
|
+
};
|
|
44
|
+
// Add JSON mode if requested
|
|
45
|
+
if (request.responseFormat === 'json') {
|
|
46
|
+
body.response_format = { type: 'json_object' };
|
|
47
|
+
}
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeout ?? DEFAULT_CONFIG.timeout);
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers,
|
|
54
|
+
body: JSON.stringify(body),
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
});
|
|
57
|
+
clearTimeout(timeout);
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
const errorData = (await response.json().catch(() => ({})));
|
|
60
|
+
const errorMessage = errorData.error?.message ?? `HTTP ${response.status}`;
|
|
61
|
+
if (response.status === 429) {
|
|
62
|
+
throw new LLMError(`Rate limit exceeded: ${errorMessage}`, 'RATE_LIMIT', this.provider);
|
|
63
|
+
}
|
|
64
|
+
throw new LLMError(`OpenAI API error: ${errorMessage}`, 'API_ERROR', this.provider);
|
|
65
|
+
}
|
|
66
|
+
const data = (await response.json());
|
|
67
|
+
const choice = data.choices[0];
|
|
68
|
+
if (!choice) {
|
|
69
|
+
throw new LLMError('No response from OpenAI', 'INVALID_RESPONSE', this.provider);
|
|
70
|
+
}
|
|
71
|
+
const content = choice.message.content;
|
|
72
|
+
let json;
|
|
73
|
+
if (request.responseFormat === 'json') {
|
|
74
|
+
json = this.parseJSON(content);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
content,
|
|
78
|
+
json,
|
|
79
|
+
usage: {
|
|
80
|
+
promptTokens: data.usage.prompt_tokens,
|
|
81
|
+
completionTokens: data.usage.completion_tokens,
|
|
82
|
+
totalTokens: data.usage.total_tokens,
|
|
83
|
+
},
|
|
84
|
+
model: data.model,
|
|
85
|
+
finishReason: choice.finish_reason === 'stop' ? 'stop' :
|
|
86
|
+
choice.finish_reason === 'length' ? 'length' :
|
|
87
|
+
choice.finish_reason === 'content_filter' ? 'content_filter' : 'error',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
clearTimeout(timeout);
|
|
92
|
+
if (error instanceof LLMError) {
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
if (error instanceof Error) {
|
|
96
|
+
if (error.name === 'AbortError') {
|
|
97
|
+
throw new LLMError('Request timeout', 'TIMEOUT', this.provider, error);
|
|
98
|
+
}
|
|
99
|
+
throw new LLMError(`Network error: ${error.message}`, 'NETWORK_ERROR', this.provider, error);
|
|
100
|
+
}
|
|
101
|
+
throw new LLMError('Unknown error', 'API_ERROR', this.provider);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Create an OpenAI adapter from environment variables
|
|
108
|
+
*/
|
|
109
|
+
export function createOpenAIAdapter(model = 'gpt-4o', overrides) {
|
|
110
|
+
const apiKey = typeof process !== 'undefined' ? process.env.OPENAI_API_KEY : undefined;
|
|
111
|
+
const config = {
|
|
112
|
+
provider: 'openai',
|
|
113
|
+
model,
|
|
114
|
+
...overrides,
|
|
115
|
+
};
|
|
116
|
+
if (apiKey) {
|
|
117
|
+
config.apiKey = apiKey;
|
|
118
|
+
}
|
|
119
|
+
return new OpenAIAdapter(config);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../../src/llm/adapters/openai.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/llm/index.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* LLM integration for skill extraction and prerequisite inference
|
|
4
3
|
*
|
|
5
4
|
* @packageDocumentation
|
|
6
5
|
*/
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
//
|
|
6
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
7
|
+
// Adapters
|
|
8
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
9
|
+
export { BaseLLMAdapter, LLMError, DEFAULT_CONFIG, OpenAIAdapter, createOpenAIAdapter, AnthropicAdapter, createAnthropicAdapter, OllamaAdapter, createOllamaAdapter, } from './adapters/index.js';
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
// Orchestrator
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
export { LLMOrchestrator, createOrchestrator } from './orchestrator.js';
|
|
14
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15
|
+
// Prompts
|
|
16
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
17
|
+
export { SYSTEM_PROMPTS, EXTRACTION_SCHEMA, PREREQUISITE_SCHEMA, BLOOM_ANALYSIS_SCHEMA, DECOMPOSITION_SCHEMA, buildExtractionPrompt, buildPrerequisitePrompt, buildBloomPrompt, buildDecompositionPrompt, } from './prompts.js';
|
|
12
18
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/llm/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/llm/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6BH,gFAAgF;AAChF,WAAW;AACX,gFAAgF;AAChF,OAAO,EACL,cAAc,EACd,QAAQ,EACR,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAG7B,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAExE,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAChF,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,cAAc,CAAC"}
|