@entro314labs/ai-changelog-generator 3.1.1 → 3.2.1
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/CHANGELOG.md +412 -875
- package/README.md +8 -3
- package/ai-changelog-mcp.sh +0 -0
- package/ai-changelog.sh +0 -0
- package/bin/ai-changelog-dxt.js +9 -9
- package/bin/ai-changelog-mcp.js +19 -17
- package/bin/ai-changelog.js +6 -6
- package/package.json +80 -48
- package/src/ai-changelog-generator.js +91 -81
- package/src/application/orchestrators/changelog.orchestrator.js +791 -516
- package/src/application/services/application.service.js +137 -128
- package/src/cli.js +76 -57
- package/src/domains/ai/ai-analysis.service.js +289 -209
- package/src/domains/analysis/analysis.engine.js +328 -192
- package/src/domains/changelog/changelog.service.js +1174 -783
- package/src/domains/changelog/workspace-changelog.service.js +487 -249
- package/src/domains/git/git-repository.analyzer.js +348 -258
- package/src/domains/git/git.service.js +132 -112
- package/src/infrastructure/cli/cli.controller.js +390 -274
- package/src/infrastructure/config/configuration.manager.js +220 -190
- package/src/infrastructure/interactive/interactive-staging.service.js +154 -135
- package/src/infrastructure/interactive/interactive-workflow.service.js +200 -159
- package/src/infrastructure/mcp/mcp-server.service.js +208 -207
- package/src/infrastructure/metrics/metrics.collector.js +140 -123
- package/src/infrastructure/providers/core/base-provider.js +87 -40
- package/src/infrastructure/providers/implementations/anthropic.js +101 -99
- package/src/infrastructure/providers/implementations/azure.js +124 -101
- package/src/infrastructure/providers/implementations/bedrock.js +136 -126
- package/src/infrastructure/providers/implementations/dummy.js +23 -23
- package/src/infrastructure/providers/implementations/google.js +123 -114
- package/src/infrastructure/providers/implementations/huggingface.js +94 -87
- package/src/infrastructure/providers/implementations/lmstudio.js +75 -60
- package/src/infrastructure/providers/implementations/mock.js +69 -73
- package/src/infrastructure/providers/implementations/ollama.js +89 -66
- package/src/infrastructure/providers/implementations/openai.js +88 -89
- package/src/infrastructure/providers/implementations/vertex.js +227 -197
- package/src/infrastructure/providers/provider-management.service.js +245 -207
- package/src/infrastructure/providers/provider-manager.service.js +145 -125
- package/src/infrastructure/providers/utils/base-provider-helpers.js +308 -302
- package/src/infrastructure/providers/utils/model-config.js +220 -195
- package/src/infrastructure/providers/utils/provider-utils.js +105 -100
- package/src/infrastructure/validation/commit-message-validation.service.js +259 -161
- package/src/shared/constants/colors.js +453 -180
- package/src/shared/utils/cli-demo.js +285 -0
- package/src/shared/utils/cli-entry-utils.js +257 -249
- package/src/shared/utils/cli-ui.js +447 -0
- package/src/shared/utils/diff-processor.js +513 -0
- package/src/shared/utils/error-classes.js +125 -156
- package/src/shared/utils/json-utils.js +93 -89
- package/src/shared/utils/utils.js +1117 -945
- package/types/index.d.ts +353 -344
|
@@ -3,22 +3,18 @@
|
|
|
3
3
|
* Used for testing without real API credentials
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { ProviderError } from '../../../shared/utils/utils.js'
|
|
7
|
+
import { BaseProvider } from '../core/base-provider.js'
|
|
8
8
|
|
|
9
9
|
class MockProvider extends BaseProvider {
|
|
10
10
|
constructor(config = {}) {
|
|
11
|
-
super(config)
|
|
12
|
-
this.name = 'mock'
|
|
13
|
-
this.mockResponses = config.MOCK_RESPONSES || {}
|
|
14
|
-
this.shouldFail = config.MOCK_SHOULD_FAIL === 'true'
|
|
15
|
-
this.failureRate = parseFloat(config.MOCK_FAILURE_RATE || '0.1')
|
|
16
|
-
this.latency = parseInt(config.MOCK_LATENCY || '500', 10)
|
|
17
|
-
this.models = [
|
|
18
|
-
'mock-basic',
|
|
19
|
-
'mock-standard',
|
|
20
|
-
'mock-advanced'
|
|
21
|
-
];
|
|
11
|
+
super(config)
|
|
12
|
+
this.name = 'mock'
|
|
13
|
+
this.mockResponses = config.MOCK_RESPONSES || {}
|
|
14
|
+
this.shouldFail = config.MOCK_SHOULD_FAIL === 'true'
|
|
15
|
+
this.failureRate = Number.parseFloat(config.MOCK_FAILURE_RATE || '0.1')
|
|
16
|
+
this.latency = Number.parseInt(config.MOCK_LATENCY || '500', 10)
|
|
17
|
+
this.models = ['mock-basic', 'mock-standard', 'mock-advanced']
|
|
22
18
|
}
|
|
23
19
|
|
|
24
20
|
/**
|
|
@@ -26,7 +22,7 @@ class MockProvider extends BaseProvider {
|
|
|
26
22
|
* @returns {string} Provider name
|
|
27
23
|
*/
|
|
28
24
|
getName() {
|
|
29
|
-
return this.name
|
|
25
|
+
return this.name
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
/**
|
|
@@ -34,7 +30,7 @@ class MockProvider extends BaseProvider {
|
|
|
34
30
|
* @returns {boolean} Always true for mock provider
|
|
35
31
|
*/
|
|
36
32
|
isAvailable() {
|
|
37
|
-
return true
|
|
33
|
+
return true
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
/**
|
|
@@ -43,7 +39,7 @@ class MockProvider extends BaseProvider {
|
|
|
43
39
|
* @returns {Promise} - Promise that resolves after delay
|
|
44
40
|
*/
|
|
45
41
|
async _simulateLatency() {
|
|
46
|
-
return new Promise(resolve => setTimeout(resolve, this.latency))
|
|
42
|
+
return new Promise((resolve) => setTimeout(resolve, this.latency))
|
|
47
43
|
}
|
|
48
44
|
|
|
49
45
|
/**
|
|
@@ -52,9 +48,9 @@ class MockProvider extends BaseProvider {
|
|
|
52
48
|
*/
|
|
53
49
|
_shouldFailOperation() {
|
|
54
50
|
if (this.shouldFail) {
|
|
55
|
-
return true
|
|
51
|
+
return true
|
|
56
52
|
}
|
|
57
|
-
return Math.random() < this.failureRate
|
|
53
|
+
return Math.random() < this.failureRate
|
|
58
54
|
}
|
|
59
55
|
|
|
60
56
|
/**
|
|
@@ -64,7 +60,7 @@ class MockProvider extends BaseProvider {
|
|
|
64
60
|
* @returns {Promise} - Promise that resolves with mock completion
|
|
65
61
|
*/
|
|
66
62
|
async generateCompletion(messages, options = {}) {
|
|
67
|
-
await this._simulateLatency()
|
|
63
|
+
await this._simulateLatency()
|
|
68
64
|
|
|
69
65
|
if (this._shouldFailOperation()) {
|
|
70
66
|
throw new ProviderError(
|
|
@@ -72,22 +68,20 @@ class MockProvider extends BaseProvider {
|
|
|
72
68
|
'mock_error',
|
|
73
69
|
this.getName(),
|
|
74
70
|
options.model || 'mock-standard'
|
|
75
|
-
)
|
|
71
|
+
)
|
|
76
72
|
}
|
|
77
73
|
|
|
78
|
-
const model = options.model || 'mock-standard'
|
|
79
|
-
const lastMessage = messages
|
|
80
|
-
const prompt = typeof lastMessage === 'string'
|
|
81
|
-
? lastMessage
|
|
82
|
-
: (lastMessage.content || '');
|
|
74
|
+
const model = options.model || 'mock-standard'
|
|
75
|
+
const lastMessage = messages.at(-1)
|
|
76
|
+
const prompt = typeof lastMessage === 'string' ? lastMessage : lastMessage.content || ''
|
|
83
77
|
|
|
84
78
|
// Check for predefined responses
|
|
85
79
|
if (this.mockResponses[prompt]) {
|
|
86
80
|
return {
|
|
87
81
|
content: this.mockResponses[prompt],
|
|
88
82
|
tokens: this.mockResponses[prompt].length / 4, // Rough estimate
|
|
89
|
-
model
|
|
90
|
-
}
|
|
83
|
+
model,
|
|
84
|
+
}
|
|
91
85
|
}
|
|
92
86
|
|
|
93
87
|
// Generate mock response based on commit convention if it looks like a commit message
|
|
@@ -95,16 +89,16 @@ class MockProvider extends BaseProvider {
|
|
|
95
89
|
return {
|
|
96
90
|
content: this._generateMockChangelog(prompt),
|
|
97
91
|
tokens: 150,
|
|
98
|
-
model
|
|
99
|
-
}
|
|
92
|
+
model,
|
|
93
|
+
}
|
|
100
94
|
}
|
|
101
95
|
|
|
102
96
|
// Default mock response
|
|
103
97
|
return {
|
|
104
98
|
content: `This is a mock response from the ${model} model.`,
|
|
105
99
|
tokens: 10,
|
|
106
|
-
model
|
|
107
|
-
}
|
|
100
|
+
model,
|
|
101
|
+
}
|
|
108
102
|
}
|
|
109
103
|
|
|
110
104
|
/**
|
|
@@ -113,15 +107,17 @@ class MockProvider extends BaseProvider {
|
|
|
113
107
|
* @returns {string} - Mock changelog entry
|
|
114
108
|
*/
|
|
115
109
|
_generateMockChangelog(commitMessage) {
|
|
116
|
-
const typeMatch = commitMessage.match(
|
|
110
|
+
const typeMatch = commitMessage.match(
|
|
111
|
+
/^(feat|fix|docs|style|refactor|perf|test|build|ci|chore)(\(.+\))?:/
|
|
112
|
+
)
|
|
117
113
|
|
|
118
114
|
if (!typeMatch) {
|
|
119
|
-
return 'Mock changelog entry for conventional commit'
|
|
115
|
+
return 'Mock changelog entry for conventional commit'
|
|
120
116
|
}
|
|
121
117
|
|
|
122
|
-
const type = typeMatch[1]
|
|
123
|
-
const scope = typeMatch[2] ? typeMatch[2].replace(/[()]/g, '') : ''
|
|
124
|
-
const description = commitMessage.split(':')[1]?.trim() || ''
|
|
118
|
+
const type = typeMatch[1]
|
|
119
|
+
const scope = typeMatch[2] ? typeMatch[2].replace(/[()]/g, '') : ''
|
|
120
|
+
const description = commitMessage.split(':')[1]?.trim() || ''
|
|
125
121
|
|
|
126
122
|
const typeMap = {
|
|
127
123
|
feat: 'Feature',
|
|
@@ -133,11 +129,11 @@ class MockProvider extends BaseProvider {
|
|
|
133
129
|
test: 'Tests',
|
|
134
130
|
build: 'Build',
|
|
135
131
|
ci: 'CI',
|
|
136
|
-
chore: 'Chore'
|
|
137
|
-
}
|
|
132
|
+
chore: 'Chore',
|
|
133
|
+
}
|
|
138
134
|
|
|
139
|
-
const title = `${typeMap[type]}${scope ? ` (${scope})` : ''}
|
|
140
|
-
return `### ${title}\n\n- ${description}\n
|
|
135
|
+
const title = `${typeMap[type]}${scope ? ` (${scope})` : ''}`
|
|
136
|
+
return `### ${title}\n\n- ${description}\n`
|
|
141
137
|
}
|
|
142
138
|
|
|
143
139
|
/**
|
|
@@ -149,29 +145,29 @@ class MockProvider extends BaseProvider {
|
|
|
149
145
|
if (!commitInfo.message) {
|
|
150
146
|
return {
|
|
151
147
|
model: 'mock-standard',
|
|
152
|
-
reason: 'Default model selected due to insufficient commit information'
|
|
153
|
-
}
|
|
148
|
+
reason: 'Default model selected due to insufficient commit information',
|
|
149
|
+
}
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
// Simple logic based on commit complexity
|
|
157
|
-
const filesChanged = commitInfo.files?.length || 0
|
|
158
|
-
const linesChanged = (commitInfo.additions || 0) + (commitInfo.deletions || 0)
|
|
153
|
+
const filesChanged = commitInfo.files?.length || 0
|
|
154
|
+
const linesChanged = (commitInfo.additions || 0) + (commitInfo.deletions || 0)
|
|
159
155
|
|
|
160
156
|
if (filesChanged > 10 || linesChanged > 500 || commitInfo.breaking) {
|
|
161
157
|
return {
|
|
162
158
|
model: 'mock-advanced',
|
|
163
|
-
reason: 'Complex commit detected, using advanced model'
|
|
164
|
-
}
|
|
165
|
-
}
|
|
159
|
+
reason: 'Complex commit detected, using advanced model',
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (filesChanged > 3 || linesChanged > 100) {
|
|
166
163
|
return {
|
|
167
164
|
model: 'mock-standard',
|
|
168
|
-
reason: 'Moderate commit detected, using standard model'
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
};
|
|
165
|
+
reason: 'Moderate commit detected, using standard model',
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
model: 'mock-basic',
|
|
170
|
+
reason: 'Simple commit detected, using basic model',
|
|
175
171
|
}
|
|
176
172
|
}
|
|
177
173
|
|
|
@@ -181,23 +177,23 @@ class MockProvider extends BaseProvider {
|
|
|
181
177
|
* @returns {Promise} - Promise that resolves with validation result
|
|
182
178
|
*/
|
|
183
179
|
async validateModelAvailability(model) {
|
|
184
|
-
await this._simulateLatency()
|
|
180
|
+
await this._simulateLatency()
|
|
185
181
|
|
|
186
182
|
if (this._shouldFailOperation()) {
|
|
187
183
|
return {
|
|
188
184
|
available: false,
|
|
189
185
|
error: 'Mock validation failure',
|
|
190
|
-
alternatives: this.models
|
|
191
|
-
}
|
|
186
|
+
alternatives: this.models,
|
|
187
|
+
}
|
|
192
188
|
}
|
|
193
189
|
|
|
194
|
-
const isAvailable = this.models.includes(model)
|
|
190
|
+
const isAvailable = this.models.includes(model)
|
|
195
191
|
|
|
196
192
|
return {
|
|
197
193
|
available: isAvailable,
|
|
198
194
|
model: isAvailable ? model : null,
|
|
199
|
-
alternatives: isAvailable ? [] : this.models
|
|
200
|
-
}
|
|
195
|
+
alternatives: isAvailable ? [] : this.models,
|
|
196
|
+
}
|
|
201
197
|
}
|
|
202
198
|
|
|
203
199
|
/**
|
|
@@ -205,22 +201,22 @@ class MockProvider extends BaseProvider {
|
|
|
205
201
|
* @returns {Promise} - Promise that resolves with connection test result
|
|
206
202
|
*/
|
|
207
203
|
async testConnection() {
|
|
208
|
-
await this._simulateLatency()
|
|
204
|
+
await this._simulateLatency()
|
|
209
205
|
|
|
210
206
|
if (this._shouldFailOperation()) {
|
|
211
207
|
return {
|
|
212
208
|
success: false,
|
|
213
209
|
error: 'Mock connection failure',
|
|
214
|
-
provider: this.getName()
|
|
215
|
-
}
|
|
210
|
+
provider: this.getName(),
|
|
211
|
+
}
|
|
216
212
|
}
|
|
217
213
|
|
|
218
214
|
return {
|
|
219
215
|
success: true,
|
|
220
216
|
provider: this.getName(),
|
|
221
217
|
model: 'mock-standard',
|
|
222
|
-
response: 'Mock connection successful'
|
|
223
|
-
}
|
|
218
|
+
response: 'Mock connection successful',
|
|
219
|
+
}
|
|
224
220
|
}
|
|
225
221
|
|
|
226
222
|
/**
|
|
@@ -232,8 +228,8 @@ class MockProvider extends BaseProvider {
|
|
|
232
228
|
streaming: false,
|
|
233
229
|
tool_use: true,
|
|
234
230
|
vision: false,
|
|
235
|
-
json_mode: true
|
|
236
|
-
}
|
|
231
|
+
json_mode: true,
|
|
232
|
+
}
|
|
237
233
|
}
|
|
238
234
|
|
|
239
235
|
getAvailableModels() {
|
|
@@ -246,7 +242,7 @@ class MockProvider extends BaseProvider {
|
|
|
246
242
|
inputCost: 0,
|
|
247
243
|
outputCost: 0,
|
|
248
244
|
features: ['text', 'testing'],
|
|
249
|
-
description: 'Basic mock model for simple testing'
|
|
245
|
+
description: 'Basic mock model for simple testing',
|
|
250
246
|
},
|
|
251
247
|
{
|
|
252
248
|
id: 'mock-standard',
|
|
@@ -256,7 +252,7 @@ class MockProvider extends BaseProvider {
|
|
|
256
252
|
inputCost: 0,
|
|
257
253
|
outputCost: 0,
|
|
258
254
|
features: ['text', 'tools', 'testing'],
|
|
259
|
-
description: 'Standard mock model for moderate testing'
|
|
255
|
+
description: 'Standard mock model for moderate testing',
|
|
260
256
|
},
|
|
261
257
|
{
|
|
262
258
|
id: 'mock-advanced',
|
|
@@ -266,10 +262,10 @@ class MockProvider extends BaseProvider {
|
|
|
266
262
|
inputCost: 0,
|
|
267
263
|
outputCost: 0,
|
|
268
264
|
features: ['text', 'tools', 'json', 'testing'],
|
|
269
|
-
description: 'Advanced mock model for complex testing scenarios'
|
|
270
|
-
}
|
|
271
|
-
]
|
|
265
|
+
description: 'Advanced mock model for complex testing scenarios',
|
|
266
|
+
},
|
|
267
|
+
]
|
|
272
268
|
}
|
|
273
269
|
}
|
|
274
270
|
|
|
275
|
-
export default MockProvider
|
|
271
|
+
export default MockProvider
|
|
@@ -1,34 +1,37 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import {
|
|
1
|
+
import process from 'node:process'
|
|
2
|
+
|
|
3
|
+
import { Ollama } from 'ollama'
|
|
4
|
+
|
|
5
|
+
import { ProviderError } from '../../../shared/utils/utils.js'
|
|
6
|
+
import { BaseProvider } from '../core/base-provider.js'
|
|
7
|
+
import { applyMixins } from '../utils/base-provider-helpers.js'
|
|
8
|
+
import { buildClientOptions } from '../utils/provider-utils.js'
|
|
6
9
|
|
|
7
10
|
class OllamaProvider extends BaseProvider {
|
|
8
11
|
constructor(config) {
|
|
9
|
-
super(config)
|
|
10
|
-
this.client = null
|
|
12
|
+
super(config)
|
|
13
|
+
this.client = null
|
|
11
14
|
if (this.isAvailable()) {
|
|
12
|
-
this.initializeClient()
|
|
15
|
+
this.initializeClient()
|
|
13
16
|
}
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
initializeClient() {
|
|
17
20
|
const clientOptions = buildClientOptions(this.getProviderConfig(), {
|
|
18
|
-
host: 'http://localhost:11434'
|
|
19
|
-
})
|
|
21
|
+
host: 'http://localhost:11434',
|
|
22
|
+
})
|
|
20
23
|
|
|
21
24
|
this.client = new Ollama({
|
|
22
|
-
host: clientOptions.host
|
|
23
|
-
})
|
|
25
|
+
host: clientOptions.host,
|
|
26
|
+
})
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
getName() {
|
|
27
|
-
return 'ollama'
|
|
30
|
+
return 'ollama'
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
isAvailable() {
|
|
31
|
-
return !!this.config.OLLAMA_HOST
|
|
34
|
+
return !!this.config.OLLAMA_HOST
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
async generateCompletion(messages, options = {}) {
|
|
@@ -36,116 +39,136 @@ class OllamaProvider extends BaseProvider {
|
|
|
36
39
|
return this.handleProviderError(
|
|
37
40
|
new Error('Ollama provider is not configured'),
|
|
38
41
|
'generate_completion'
|
|
39
|
-
)
|
|
42
|
+
)
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
try {
|
|
43
46
|
// Test connection first time if not already done
|
|
44
47
|
if (!this._connectionTested) {
|
|
45
48
|
try {
|
|
46
|
-
await this.client.list()
|
|
47
|
-
this._connectionTested = true
|
|
49
|
+
await this.client.list()
|
|
50
|
+
this._connectionTested = true
|
|
48
51
|
} catch (connectionError) {
|
|
49
52
|
return this.handleProviderError(
|
|
50
|
-
new Error(
|
|
53
|
+
new Error(
|
|
54
|
+
`Ollama server unreachable: ${connectionError.message}. Please run 'ollama serve' first.`
|
|
55
|
+
),
|
|
51
56
|
'generate_completion'
|
|
52
|
-
)
|
|
57
|
+
)
|
|
53
58
|
}
|
|
54
59
|
}
|
|
55
60
|
|
|
56
|
-
const modelConfig = this.getProviderModelConfig()
|
|
57
|
-
const modelName = options.model || modelConfig.standardModel
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
const modelConfig = this.getProviderModelConfig()
|
|
62
|
+
const modelName = options.model || modelConfig.standardModel
|
|
63
|
+
|
|
64
|
+
const params = {
|
|
65
|
+
model: modelName,
|
|
66
|
+
messages,
|
|
67
|
+
stream: !!options.stream,
|
|
68
|
+
options: {
|
|
69
|
+
temperature: options.temperature || 0.7,
|
|
70
|
+
top_p: options.top_p || 0.9,
|
|
71
|
+
num_predict: options.max_tokens || 1024,
|
|
72
|
+
stop: options.stop || [],
|
|
73
|
+
},
|
|
74
|
+
}
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
if (options.tools && this.getCapabilities(modelName).tool_use) {
|
|
77
|
+
params.tools = options.tools
|
|
78
|
+
}
|
|
74
79
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
if (
|
|
81
|
+
options.response_format?.type === 'json_object' &&
|
|
82
|
+
this.getCapabilities(modelName).json_mode
|
|
83
|
+
) {
|
|
84
|
+
params.format = 'json'
|
|
85
|
+
}
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
if (params.stream) {
|
|
88
|
+
const stream = await this.client.chat(params)
|
|
89
|
+
return { stream, model: modelName }
|
|
90
|
+
}
|
|
83
91
|
|
|
84
|
-
const response = await this.client.chat(params)
|
|
92
|
+
const response = await this.client.chat(params)
|
|
85
93
|
return {
|
|
86
94
|
content: response.message.content,
|
|
87
95
|
model: response.model,
|
|
88
96
|
tokens: response.eval_count,
|
|
89
97
|
finish_reason: response.done ? 'stop' : 'incomplete',
|
|
90
98
|
tool_calls: response.message.tool_calls,
|
|
91
|
-
}
|
|
99
|
+
}
|
|
92
100
|
} catch (error) {
|
|
93
|
-
return this.handleProviderError(error, 'generate_completion', { model: options.model })
|
|
101
|
+
return this.handleProviderError(error, 'generate_completion', { model: options.model })
|
|
94
102
|
}
|
|
95
103
|
}
|
|
96
104
|
|
|
97
105
|
async generateEmbedding(text, options = {}) {
|
|
98
106
|
if (!this.isAvailable()) {
|
|
99
|
-
throw new ProviderError('Ollama provider is not configured', 'ollama', 'isAvailable')
|
|
107
|
+
throw new ProviderError('Ollama provider is not configured', 'ollama', 'isAvailable')
|
|
100
108
|
}
|
|
101
109
|
|
|
102
|
-
const modelName =
|
|
110
|
+
const modelName =
|
|
111
|
+
options.model ||
|
|
112
|
+
this.config.OLLAMA_EMBEDDING_MODEL ||
|
|
113
|
+
this.config.AI_MODEL_EMBEDDING ||
|
|
114
|
+
'nomic-embed-text'
|
|
103
115
|
|
|
104
116
|
const response = await this.client.embeddings({
|
|
105
117
|
model: modelName,
|
|
106
118
|
prompt: text,
|
|
107
119
|
options: {
|
|
108
|
-
temperature: options.temperature || 0.0
|
|
109
|
-
}
|
|
110
|
-
})
|
|
120
|
+
temperature: options.temperature || 0.0,
|
|
121
|
+
},
|
|
122
|
+
})
|
|
111
123
|
|
|
112
124
|
return {
|
|
113
125
|
embedding: response.embedding,
|
|
114
126
|
model: modelName,
|
|
115
|
-
tokens: response.token_count || 0
|
|
116
|
-
}
|
|
127
|
+
tokens: response.token_count || 0,
|
|
128
|
+
}
|
|
117
129
|
}
|
|
118
130
|
|
|
119
131
|
// Ollama-specific helper methods
|
|
120
132
|
async getAvailableModels() {
|
|
121
|
-
if (!this.isAvailable())
|
|
133
|
+
if (!this.isAvailable()) {
|
|
134
|
+
return []
|
|
135
|
+
}
|
|
122
136
|
try {
|
|
123
|
-
const response = await this.client.list()
|
|
124
|
-
return response.models.map(m => m.name)
|
|
137
|
+
const response = await this.client.list()
|
|
138
|
+
return response.models.map((m) => m.name)
|
|
125
139
|
} catch (error) {
|
|
126
140
|
// Only log connection errors in development mode or when explicitly used
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
141
|
+
if (
|
|
142
|
+
!this._connectionErrorLogged &&
|
|
143
|
+
(process.env.NODE_ENV === 'development' || process.env.DEBUG)
|
|
144
|
+
) {
|
|
145
|
+
console.warn(`⚠️ Ollama connection failed: ${error.message}`)
|
|
146
|
+
console.warn('💡 Make sure Ollama is running: ollama serve')
|
|
147
|
+
this._connectionErrorLogged = true
|
|
131
148
|
}
|
|
132
|
-
return []
|
|
149
|
+
return []
|
|
133
150
|
}
|
|
134
151
|
}
|
|
135
152
|
|
|
136
153
|
async pullModel(modelName) {
|
|
137
154
|
if (!this.isAvailable()) {
|
|
138
|
-
throw new ProviderError('Ollama provider is not configured', 'ollama', 'isAvailable')
|
|
155
|
+
throw new ProviderError('Ollama provider is not configured', 'ollama', 'isAvailable')
|
|
139
156
|
}
|
|
140
157
|
|
|
141
158
|
try {
|
|
142
|
-
const pullStream = await this.client.pull({ model: modelName, stream: true })
|
|
143
|
-
return { stream: pullStream, model: modelName }
|
|
159
|
+
const pullStream = await this.client.pull({ model: modelName, stream: true })
|
|
160
|
+
return { stream: pullStream, model: modelName }
|
|
144
161
|
} catch (error) {
|
|
145
|
-
throw new ProviderError(
|
|
162
|
+
throw new ProviderError(
|
|
163
|
+
`Failed to pull model ${modelName}: ${error.message}`,
|
|
164
|
+
'ollama',
|
|
165
|
+
'pullModel',
|
|
166
|
+
error,
|
|
167
|
+
{ modelName }
|
|
168
|
+
)
|
|
146
169
|
}
|
|
147
170
|
}
|
|
148
171
|
}
|
|
149
172
|
|
|
150
173
|
// Apply mixins to add standard provider functionality
|
|
151
|
-
export default applyMixins(OllamaProvider, 'ollama')
|
|
174
|
+
export default applyMixins(OllamaProvider, 'ollama')
|