cloving 0.3.19 → 0.3.20
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/index.js +2 -0
- package/dist/managers/CommitManager.js +30 -16
- package/dist/package.json +1 -1
- package/package.json +1 -1
- package/.DS_Store +0 -0
- package/.aider.chat.history.md +0 -16978
- package/.aider.input.history +0 -15
- package/.aider.tags.cache.v3/cache.db +0 -0
- package/.aider.tags.cache.v3/cache.db-shm +0 -0
- package/.aider.tags.cache.v3/cache.db-wal +0 -0
- package/.cursorrules +0 -77
- package/.github/workflows/auto-release.yml +0 -83
- package/.github/workflows/ci.yml +0 -32
- package/.github/workflows/npm-publish.yml +0 -34
- package/.gitignore +0 -67
- package/.husky/_/.gitignore +0 -1
- package/.husky/_/applypatch-msg +0 -2
- package/.husky/_/commit-msg +0 -2
- package/.husky/_/h +0 -22
- package/.husky/_/husky.sh +0 -9
- package/.husky/_/post-applypatch +0 -2
- package/.husky/_/post-checkout +0 -2
- package/.husky/_/post-commit +0 -2
- package/.husky/_/post-merge +0 -2
- package/.husky/_/post-rewrite +0 -2
- package/.husky/_/pre-applypatch +0 -2
- package/.husky/_/pre-auto-gc +0 -2
- package/.husky/_/pre-commit +0 -2
- package/.husky/_/pre-merge-commit +0 -2
- package/.husky/_/pre-push +0 -2
- package/.husky/_/pre-rebase +0 -2
- package/.husky/_/prepare-commit-msg +0 -2
- package/.husky/pre-commit +0 -1
- package/.husky/pre-push +0 -1
- package/.prettierrc.json +0 -7
- package/.tool-versions +0 -2
- package/SECURITY.md +0 -15
- package/cloving.json +0 -67
- package/jest.config.js +0 -11
- package/src/cloving_gpt/adapters/azureopenai.ts +0 -83
- package/src/cloving_gpt/adapters/claude.ts +0 -140
- package/src/cloving_gpt/adapters/gemini.ts +0 -146
- package/src/cloving_gpt/adapters/index.ts +0 -43
- package/src/cloving_gpt/adapters/mistral.ts +0 -142
- package/src/cloving_gpt/adapters/ollama.ts +0 -136
- package/src/cloving_gpt/adapters/openai.ts +0 -113
- package/src/cloving_gpt/index.ts +0 -229
- package/src/commands/chat.ts +0 -12
- package/src/commands/config.ts +0 -192
- package/src/commands/generate/code.ts +0 -18
- package/src/commands/generate/commit.ts +0 -9
- package/src/commands/generate/context.ts +0 -93
- package/src/commands/generate/docs.ts +0 -9
- package/src/commands/generate/review.ts +0 -9
- package/src/commands/generate/shell.ts +0 -9
- package/src/commands/generate/unit_tests.ts +0 -9
- package/src/commands/init.ts +0 -9
- package/src/commands/models.ts +0 -21
- package/src/commands/proxy.ts +0 -9
- package/src/commands/tokens.ts +0 -82
- package/src/index.ts +0 -197
- package/src/managers/BlockManager.ts +0 -126
- package/src/managers/ChatManager.ts +0 -755
- package/src/managers/ChunkManager.ts +0 -31
- package/src/managers/CodeManager.ts +0 -226
- package/src/managers/CommitManager.ts +0 -71
- package/src/managers/DocsManager.ts +0 -101
- package/src/managers/InitManager.ts +0 -263
- package/src/managers/ProxyManager.ts +0 -240
- package/src/managers/ReviewManager.ts +0 -154
- package/src/managers/ShellManager.ts +0 -172
- package/src/managers/StreamManager.ts +0 -353
- package/src/managers/UnitTestManager.ts +0 -293
- package/src/utils/config_utils.ts +0 -271
- package/src/utils/git_utils.ts +0 -230
- package/src/utils/model_utils.ts +0 -3
- package/src/utils/prompt_utils.ts +0 -375
- package/src/utils/prompts/CODEGEN_COULDNT_APPLY.md +0 -5
- package/src/utils/prompts/CODEGEN_EXAMPLES.md +0 -82
- package/src/utils/prompts/CODEGEN_INSTRUCTIONS.md +0 -43
- package/src/utils/prompts/DOCS_INSTRUCTIONS.md +0 -9
- package/src/utils/prompts/INIT_INSTRUCTIONS.md +0 -132
- package/src/utils/prompts/REVIEW_INSTRUCTIONS.md +0 -49
- package/src/utils/prompts/SHELL_INSTRUCTIONS.md +0 -15
- package/src/utils/prompts/SPECIAL_FILES.md +0 -66
- package/src/utils/prompts/index.ts +0 -37
- package/src/utils/string_utils.ts +0 -552
- package/src/utils/types.ts +0 -127
- package/tests/commands/generate/unit_tests.test.ts +0 -27
- package/tests/utils/git_utils.test.ts +0 -116
- package/tests/utils/model_utils.test.ts +0 -27
- package/tests/utils/prompt_utils.test.ts +0 -33
- package/tests/utils/string_utils.test.ts +0 -560
- package/tsconfig.json +0 -14
- package/yarn.lock +0 -5823
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { Adapter } from '.'
|
|
2
|
-
import type { GPTRequest, OpenAIStreamChunk } from '../../utils/types'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* ClaudeAdapter class implements the Adapter interface for Claude AI models.
|
|
6
|
-
*/
|
|
7
|
-
export class ClaudeAdapter implements Adapter {
|
|
8
|
-
private model: string
|
|
9
|
-
private anthropicVersion: string
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Array of supported Claude model identifiers.
|
|
13
|
-
*/
|
|
14
|
-
static supportedModels: string[] = [
|
|
15
|
-
'claude:claude-3-5:sonnet-20240620',
|
|
16
|
-
'claude:claude-3:opus-20240229',
|
|
17
|
-
'claude:claude-3:sonnet-20240229',
|
|
18
|
-
'claude:claude-3:haiku-20240307',
|
|
19
|
-
// Add more supported models here as needed
|
|
20
|
-
]
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Initializes a new ClaudeAdapter instance.
|
|
24
|
-
* @param model - The Claude model identifier.
|
|
25
|
-
*/
|
|
26
|
-
constructor(model: string) {
|
|
27
|
-
this.model = model
|
|
28
|
-
this.anthropicVersion = '2023-06-01'
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Logs all supported Claude models to the console.
|
|
33
|
-
*/
|
|
34
|
-
static listSupportedModels(): void {
|
|
35
|
-
ClaudeAdapter.supportedModels.forEach((model) => {
|
|
36
|
-
console.log(model)
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Returns the API endpoint for Claude.
|
|
42
|
-
* @returns The API endpoint URL.
|
|
43
|
-
*/
|
|
44
|
-
getEndpoint(): string {
|
|
45
|
-
return `https://api.anthropic.com/v1/messages`
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Generates headers for API requests.
|
|
50
|
-
* @param apiKey - The API key for authentication.
|
|
51
|
-
* @returns An object containing the required headers.
|
|
52
|
-
*/
|
|
53
|
-
getHeaders(apiKey: string): Record<string, string> {
|
|
54
|
-
return {
|
|
55
|
-
'x-api-key': apiKey,
|
|
56
|
-
'Content-Type': 'application/json',
|
|
57
|
-
'anthropic-version': this.anthropicVersion,
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Prepares the payload for API requests.
|
|
63
|
-
* @param request - The GPTRequest object containing request details.
|
|
64
|
-
* @param stream - Whether to enable streaming (default: false).
|
|
65
|
-
* @returns An object containing the prepared payload.
|
|
66
|
-
*/
|
|
67
|
-
getPayload(request: GPTRequest, stream: boolean = false): Record<string, any> {
|
|
68
|
-
let system = 'You are a computer programmer giving advice on how to write better code.'
|
|
69
|
-
if (request.messages && request.messages.length > 0 && request.messages[0].role === 'system') {
|
|
70
|
-
system = request.messages[0].content
|
|
71
|
-
request = { ...request, messages: request.messages.slice(1) }
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
model: this.model.replace(':', '-'),
|
|
75
|
-
system,
|
|
76
|
-
messages:
|
|
77
|
-
request.messages && request.messages.length > 0
|
|
78
|
-
? request.messages
|
|
79
|
-
: [{ role: 'user', content: request.prompt }],
|
|
80
|
-
max_tokens: request.maxTokens || 4096,
|
|
81
|
-
temperature: request.temperature || 0.2,
|
|
82
|
-
stream,
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Extracts the response text from the API response data.
|
|
88
|
-
* @param data - The API response data.
|
|
89
|
-
* @returns The extracted response text.
|
|
90
|
-
* @throws Error if the response structure is invalid.
|
|
91
|
-
*/
|
|
92
|
-
extractResponse(data: any): string {
|
|
93
|
-
try {
|
|
94
|
-
if (data && data.content && Array.isArray(data.content) && data.content.length > 0) {
|
|
95
|
-
return data.content.map((item: any) => item.text).join('\n')
|
|
96
|
-
} else {
|
|
97
|
-
console.error('Unexpected response structure:', data)
|
|
98
|
-
throw new Error('Invalid response structure')
|
|
99
|
-
}
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.error('Error extracting response:', error)
|
|
102
|
-
throw error
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Converts streaming data to OpenAIStreamChunk format.
|
|
108
|
-
* @param data - The streaming data string.
|
|
109
|
-
* @returns An OpenAIStreamChunk object or null if parsing fails.
|
|
110
|
-
*/
|
|
111
|
-
convertStream(data: string): OpenAIStreamChunk | null {
|
|
112
|
-
let beginningChar = 0
|
|
113
|
-
let lastChar = 0
|
|
114
|
-
|
|
115
|
-
while (lastChar < data.length) {
|
|
116
|
-
try {
|
|
117
|
-
let remainingString = data.slice(beginningChar, lastChar)
|
|
118
|
-
|
|
119
|
-
// Strip any leading characters until we encounter the first '{' in this block
|
|
120
|
-
const firstBraceIndex = remainingString.indexOf('{')
|
|
121
|
-
if (firstBraceIndex > -1) {
|
|
122
|
-
remainingString = remainingString.slice(firstBraceIndex)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const parsedObject = JSON.parse(remainingString)
|
|
126
|
-
const output = parsedObject?.delta?.text || ''
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
output,
|
|
130
|
-
lastChar,
|
|
131
|
-
}
|
|
132
|
-
} catch (error) {
|
|
133
|
-
// Incrementally increase the size of the JSON string to parse
|
|
134
|
-
lastChar += 1
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return null
|
|
139
|
-
}
|
|
140
|
-
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { Adapter } from '.'
|
|
2
|
-
import type { OpenAIStreamChunk, GPTRequest } from '../../utils/types'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* GeminiAdapter class implements the Adapter interface for Google's Gemini AI model.
|
|
6
|
-
*/
|
|
7
|
-
export class GeminiAdapter implements Adapter {
|
|
8
|
-
private model: string
|
|
9
|
-
|
|
10
|
-
static supportedModels: string[] = [
|
|
11
|
-
'gemini:gemini-1.5:pro-latest',
|
|
12
|
-
'gemini:gemini-1.5:flash-latest',
|
|
13
|
-
'gemini:gemini-1.0:pro-latest',
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Creates a new GeminiAdapter instance.
|
|
18
|
-
* @param model - The Gemini model to use.
|
|
19
|
-
*/
|
|
20
|
-
constructor(model: string) {
|
|
21
|
-
this.model = model
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Lists all supported Gemini models to the console.
|
|
26
|
-
*/
|
|
27
|
-
static async listSupportedModels(): Promise<void> {
|
|
28
|
-
GeminiAdapter.supportedModels.forEach((model) => {
|
|
29
|
-
console.log(model)
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Gets the appropriate API endpoint URL based on whether streaming is required.
|
|
35
|
-
* @param stream - Whether to use streaming endpoint.
|
|
36
|
-
* @returns The API endpoint URL.
|
|
37
|
-
*/
|
|
38
|
-
getEndpoint(stream: boolean = false): string {
|
|
39
|
-
if (stream) {
|
|
40
|
-
return `https://generativelanguage.googleapis.com/v1beta/models/${this.model.replace(':', '-')}:streamGenerateContent`
|
|
41
|
-
} else {
|
|
42
|
-
return `https://generativelanguage.googleapis.com/v1beta/models/${this.model.replace(':', '-')}:generateContent`
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Generates headers for the API request.
|
|
48
|
-
* @param apiKey - The API key for authentication.
|
|
49
|
-
* @returns An object containing the necessary headers.
|
|
50
|
-
*/
|
|
51
|
-
getHeaders(apiKey: string): Record<string, string> {
|
|
52
|
-
return {
|
|
53
|
-
'Content-Type': 'application/json',
|
|
54
|
-
'x-goog-api-key': apiKey,
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Prepares the payload for the API request.
|
|
60
|
-
* @param request - The GPTRequest object containing prompt and other parameters.
|
|
61
|
-
* @param stream - Whether the request is for streaming.
|
|
62
|
-
* @returns The formatted payload object.
|
|
63
|
-
*/
|
|
64
|
-
getPayload(request: GPTRequest, stream: boolean = false): Record<string, any> {
|
|
65
|
-
return {
|
|
66
|
-
contents: [
|
|
67
|
-
{
|
|
68
|
-
role: 'user', // or 'model' if generated from the model
|
|
69
|
-
parts: [
|
|
70
|
-
{
|
|
71
|
-
text: request.prompt,
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
generationConfig: {
|
|
77
|
-
temperature: request.temperature || 0.2,
|
|
78
|
-
topK: 40,
|
|
79
|
-
topP: 0.95,
|
|
80
|
-
maxOutputTokens: 1024,
|
|
81
|
-
},
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Extracts the response text from the API response data.
|
|
87
|
-
* @param data - The raw API response data.
|
|
88
|
-
* @returns The extracted response text.
|
|
89
|
-
* @throws Error if the response structure is invalid.
|
|
90
|
-
*/
|
|
91
|
-
extractResponse(data: any): string {
|
|
92
|
-
try {
|
|
93
|
-
if (
|
|
94
|
-
data &&
|
|
95
|
-
data.candidates &&
|
|
96
|
-
data.candidates[0] &&
|
|
97
|
-
data.candidates[0].content &&
|
|
98
|
-
data.candidates[0].content.parts &&
|
|
99
|
-
data.candidates[0].content.parts[0]
|
|
100
|
-
) {
|
|
101
|
-
return data.candidates[0].content.parts[0].text
|
|
102
|
-
} else {
|
|
103
|
-
console.error('Unexpected response structure:', data)
|
|
104
|
-
throw new Error('Invalid response structure')
|
|
105
|
-
}
|
|
106
|
-
} catch (error) {
|
|
107
|
-
console.error('Error extracting response:', error)
|
|
108
|
-
throw error
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Converts a stream chunk to an OpenAIStreamChunk format.
|
|
114
|
-
* @param data - The raw stream chunk data.
|
|
115
|
-
* @returns An OpenAIStreamChunk object or null if parsing fails.
|
|
116
|
-
*/
|
|
117
|
-
convertStream(data: string): OpenAIStreamChunk | null {
|
|
118
|
-
let beginningChar = 0
|
|
119
|
-
let lastChar = 0
|
|
120
|
-
|
|
121
|
-
while (lastChar < data.length) {
|
|
122
|
-
try {
|
|
123
|
-
let remainingString = data.slice(beginningChar, lastChar)
|
|
124
|
-
|
|
125
|
-
// Strip any leading characters until we encounter the first '{' in this block
|
|
126
|
-
const firstBraceIndex = remainingString.indexOf('{')
|
|
127
|
-
if (firstBraceIndex > -1) {
|
|
128
|
-
remainingString = remainingString.slice(firstBraceIndex)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const parsedObject = JSON.parse(remainingString)
|
|
132
|
-
const output = parsedObject?.candidates[0]?.content?.parts[0]?.text || ''
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
output,
|
|
136
|
-
lastChar,
|
|
137
|
-
}
|
|
138
|
-
} catch (error) {
|
|
139
|
-
// Incrementally increase the size of the JSON string to parse
|
|
140
|
-
lastChar += 1
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return null
|
|
145
|
-
}
|
|
146
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { GPTRequest, OpenAIStreamChunk } from '../../utils/types'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Interface defining the structure for GPT adapters.
|
|
5
|
-
* This interface allows for different implementations of GPT API interactions.
|
|
6
|
-
*/
|
|
7
|
-
export interface Adapter {
|
|
8
|
-
/**
|
|
9
|
-
* Determines the appropriate endpoint URL based on whether streaming is enabled.
|
|
10
|
-
* @param stream - Boolean indicating if streaming is enabled.
|
|
11
|
-
* @returns The endpoint URL as a string.
|
|
12
|
-
*/
|
|
13
|
-
getEndpoint(stream: boolean): string
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Generates the necessary headers for the API request.
|
|
17
|
-
* @param apiKey - The API key for authentication.
|
|
18
|
-
* @returns An object containing the required headers.
|
|
19
|
-
*/
|
|
20
|
-
getHeaders(apiKey: string): Record<string, string>
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Prepares the payload for the API request.
|
|
24
|
-
* @param request - The GPTRequest object containing the request details.
|
|
25
|
-
* @param stream - Boolean indicating if streaming is enabled.
|
|
26
|
-
* @returns An object representing the request payload.
|
|
27
|
-
*/
|
|
28
|
-
getPayload(request: GPTRequest, stream: boolean): Record<string, any>
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Extracts the response from the API data.
|
|
32
|
-
* @param data - The raw data received from the API.
|
|
33
|
-
* @returns The extracted response as a string.
|
|
34
|
-
*/
|
|
35
|
-
extractResponse(data: any): string
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Converts streaming data into an OpenAIStreamChunk object.
|
|
39
|
-
* @param data - The raw streaming data as a string.
|
|
40
|
-
* @returns An OpenAIStreamChunk object or null if conversion is not possible.
|
|
41
|
-
*/
|
|
42
|
-
convertStream(data: string): OpenAIStreamChunk | null
|
|
43
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { Adapter } from '.'
|
|
2
|
-
import type { OpenAIStreamChunk, GPTRequest } from '../../utils/types'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* MistralAdapter class
|
|
6
|
-
* Implements the Adapter interface for Mistral AI models.
|
|
7
|
-
*/
|
|
8
|
-
export class MistralAdapter implements Adapter {
|
|
9
|
-
private model: string
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* List of supported Mistral AI models
|
|
13
|
-
*/
|
|
14
|
-
static supportedModels: string[] = [
|
|
15
|
-
'mistral:mistral:embed',
|
|
16
|
-
'mistral:mistral:tiny-latest',
|
|
17
|
-
'mistral:mistral:small-latest',
|
|
18
|
-
'mistral:mistral:medium-latest',
|
|
19
|
-
'mistral:mistral:large-latest',
|
|
20
|
-
'mistral:open-mistral:7b',
|
|
21
|
-
'mistral:open-mixtral:8x7b',
|
|
22
|
-
'mistral:open-mixtral:8x22b',
|
|
23
|
-
'mistral:codestral:latest',
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Prints all supported models to the console
|
|
28
|
-
*/
|
|
29
|
-
static listSupportedModels(): void {
|
|
30
|
-
MistralAdapter.supportedModels.forEach((model) => {
|
|
31
|
-
console.log(model)
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Constructor
|
|
37
|
-
* @param model - The Mistral AI model to use
|
|
38
|
-
*/
|
|
39
|
-
constructor(model: string) {
|
|
40
|
-
this.model = model
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @returns The Mistral AI API endpoint
|
|
45
|
-
*/
|
|
46
|
-
getEndpoint(): string {
|
|
47
|
-
return 'https://api.mistral.ai/v1/chat/completions'
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @param apiKey - The API key for authentication
|
|
52
|
-
* @returns Headers for the API request
|
|
53
|
-
*/
|
|
54
|
-
getHeaders(apiKey: string): Record<string, string> {
|
|
55
|
-
return {
|
|
56
|
-
Authorization: `Bearer ${apiKey}`,
|
|
57
|
-
'Content-Type': 'application/json',
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Prepares the payload for the API request
|
|
63
|
-
* @param request - The GPT request object
|
|
64
|
-
* @param stream - Whether to use streaming mode
|
|
65
|
-
* @returns The formatted payload
|
|
66
|
-
*/
|
|
67
|
-
getPayload(request: GPTRequest, stream: boolean = false): Record<string, any> {
|
|
68
|
-
return {
|
|
69
|
-
model: this.model.replace(':', '-'),
|
|
70
|
-
messages:
|
|
71
|
-
request.messages && request.messages.length > 0
|
|
72
|
-
? request.messages
|
|
73
|
-
: [{ role: 'user', content: request.prompt }],
|
|
74
|
-
max_tokens: request.maxTokens,
|
|
75
|
-
temperature: request.temperature || 0.2,
|
|
76
|
-
stream,
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Extracts the response content from the API data
|
|
82
|
-
* @param data - The API response data
|
|
83
|
-
* @returns The extracted response content
|
|
84
|
-
*/
|
|
85
|
-
extractResponse(data: any): string {
|
|
86
|
-
return data.choices[0].message.content
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// data example:
|
|
90
|
-
// {
|
|
91
|
-
// id: 'chatcmpl-9tL477A98d54qvVQqJT010bm8BLJl',
|
|
92
|
-
// object: 'chat.completion.chunk',
|
|
93
|
-
// created: 1722976043,
|
|
94
|
-
// model: 'gpt-4o-2024-05-13',
|
|
95
|
-
// system_fingerprint: 'fp_3aa7262c27',
|
|
96
|
-
// choices: [
|
|
97
|
-
// {
|
|
98
|
-
// "index": 0,
|
|
99
|
-
// "delta": {
|
|
100
|
-
// "content": " basic"
|
|
101
|
-
// },
|
|
102
|
-
// "logprobs": null,
|
|
103
|
-
// "finish_reason": null
|
|
104
|
-
// }
|
|
105
|
-
// ]
|
|
106
|
-
// }
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Converts streaming data to OpenAIStreamChunk format
|
|
110
|
-
* @param data - The streaming data string
|
|
111
|
-
* @returns Parsed OpenAIStreamChunk or null if parsing fails
|
|
112
|
-
*/
|
|
113
|
-
convertStream(data: string): OpenAIStreamChunk | null {
|
|
114
|
-
let beginningChar = 0
|
|
115
|
-
let lastChar = 0
|
|
116
|
-
|
|
117
|
-
while (lastChar < data.length) {
|
|
118
|
-
try {
|
|
119
|
-
let remainingString = data.slice(beginningChar, lastChar)
|
|
120
|
-
|
|
121
|
-
// Strip any leading characters until we encounter the first '{' in this block
|
|
122
|
-
const firstBraceIndex = remainingString.indexOf('{')
|
|
123
|
-
if (firstBraceIndex > -1) {
|
|
124
|
-
remainingString = remainingString.slice(firstBraceIndex)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const parsedObject = JSON.parse(remainingString)
|
|
128
|
-
const output = parsedObject?.choices[0]?.delta?.content || ''
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
output,
|
|
132
|
-
lastChar,
|
|
133
|
-
}
|
|
134
|
-
} catch (error) {
|
|
135
|
-
// Incrementally increase the size of the JSON string to parse
|
|
136
|
-
lastChar += 1
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return null
|
|
141
|
-
}
|
|
142
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import axios from 'axios'
|
|
2
|
-
|
|
3
|
-
import { Adapter } from '.'
|
|
4
|
-
import type { OpenAIStreamChunk, GPTRequest } from '../../utils/types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Adapter for interacting with the Ollama API.
|
|
8
|
-
*/
|
|
9
|
-
export class OllamaAdapter implements Adapter {
|
|
10
|
-
private model: string
|
|
11
|
-
|
|
12
|
-
static supportedModels: string[] = []
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Constructor to initialize the OllamaAdapter with a specific model.
|
|
16
|
-
* @param model - The model to be used by the adapter.
|
|
17
|
-
*/
|
|
18
|
-
constructor(model: string) {
|
|
19
|
-
this.model = model
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Fetches and lists supported models from the Ollama API.
|
|
24
|
-
*/
|
|
25
|
-
static async listSupportedModels(): Promise<void> {
|
|
26
|
-
try {
|
|
27
|
-
const endpoint = 'http://localhost:11434/api/tags'
|
|
28
|
-
const headers = {
|
|
29
|
-
'Content-Type': 'application/json',
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const response = await axios.get(endpoint, { headers })
|
|
33
|
-
const data = response.data
|
|
34
|
-
|
|
35
|
-
if (data && Array.isArray(data.models)) {
|
|
36
|
-
OllamaAdapter.supportedModels = data.models.map((model: any) => `ollama:${model.name}`)
|
|
37
|
-
OllamaAdapter.supportedModels.forEach((model) => {
|
|
38
|
-
console.log(model)
|
|
39
|
-
})
|
|
40
|
-
} else {
|
|
41
|
-
console.error('Unexpected response structure:', data)
|
|
42
|
-
}
|
|
43
|
-
} catch (error) {
|
|
44
|
-
// do nothing, no ollama server running
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Returns the endpoint URL for generating responses.
|
|
50
|
-
* @returns The endpoint URL as a string.
|
|
51
|
-
*/
|
|
52
|
-
getEndpoint(): string {
|
|
53
|
-
return `http://localhost:11434/api/generate`
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Returns the headers required for making API requests.
|
|
58
|
-
* @param apiKey - The API key for authorization.
|
|
59
|
-
* @returns An object containing the headers.
|
|
60
|
-
*/
|
|
61
|
-
getHeaders(apiKey: string): Record<string, string> {
|
|
62
|
-
return {
|
|
63
|
-
Authorization: `Bearer ${apiKey}`,
|
|
64
|
-
'Content-Type': 'application/json',
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Constructs the payload for the API request.
|
|
70
|
-
* @param request - The GPT request object containing the prompt.
|
|
71
|
-
* @param stream - Boolean indicating if the response should be streamed.
|
|
72
|
-
* @returns An object containing the payload.
|
|
73
|
-
*/
|
|
74
|
-
getPayload(request: GPTRequest, stream: boolean = false): Record<string, any> {
|
|
75
|
-
return {
|
|
76
|
-
model: this.model,
|
|
77
|
-
prompt: request.prompt,
|
|
78
|
-
stream,
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Extracts the response from the API response data.
|
|
84
|
-
* @param data - The response data from the API.
|
|
85
|
-
* @returns The extracted response as a string.
|
|
86
|
-
* @throws Will throw an error if the response structure is invalid.
|
|
87
|
-
*/
|
|
88
|
-
extractResponse(data: any): string {
|
|
89
|
-
try {
|
|
90
|
-
if (data && typeof data === 'object' && 'response' in data) {
|
|
91
|
-
return data.response
|
|
92
|
-
} else {
|
|
93
|
-
console.error('Unexpected response structure:', data)
|
|
94
|
-
throw new Error('Invalid response structure')
|
|
95
|
-
}
|
|
96
|
-
} catch (error) {
|
|
97
|
-
console.error('Error extracting response:', error)
|
|
98
|
-
throw error
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Converts a stream of data into an OpenAIStreamChunk.
|
|
104
|
-
* @param data - The string data to be converted.
|
|
105
|
-
* @returns An OpenAIStreamChunk object or null if conversion fails.
|
|
106
|
-
*/
|
|
107
|
-
convertStream(data: string): OpenAIStreamChunk | null {
|
|
108
|
-
let beginningChar = 0
|
|
109
|
-
let lastChar = 0
|
|
110
|
-
|
|
111
|
-
while (lastChar < data.length) {
|
|
112
|
-
try {
|
|
113
|
-
let remainingString = data.slice(beginningChar, lastChar)
|
|
114
|
-
|
|
115
|
-
// Strip any leading characters until we encounter the first '{' in this block
|
|
116
|
-
const firstBraceIndex = remainingString.indexOf('{')
|
|
117
|
-
if (firstBraceIndex > -1) {
|
|
118
|
-
remainingString = remainingString.slice(firstBraceIndex)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const parsedObject = JSON.parse(remainingString)
|
|
122
|
-
const output = parsedObject?.response || ''
|
|
123
|
-
|
|
124
|
-
return {
|
|
125
|
-
output,
|
|
126
|
-
lastChar,
|
|
127
|
-
}
|
|
128
|
-
} catch (error) {
|
|
129
|
-
// Incrementally increase the size of the JSON string to parse
|
|
130
|
-
lastChar += 1
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return null
|
|
135
|
-
}
|
|
136
|
-
}
|