@codeguide/core 0.0.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/__tests__/authentication.test.ts +259 -0
- package/__tests__/codeguide.test.ts +293 -0
- package/__tests__/services/base/base-service.test.ts +334 -0
- package/__tests__/services/generation/generation-service.test.ts +294 -0
- package/__tests__/services/usage/usage-service.test.ts +385 -0
- package/__tests__/simple.test.ts +10 -0
- package/__tests__/test-service.ts +37 -0
- package/api-service.ts +67 -0
- package/codeguide.ts +70 -0
- package/dist/__tests__/test-service.d.ts +12 -0
- package/dist/__tests__/test-service.js +32 -0
- package/dist/api-service.d.ts +8 -0
- package/dist/api-service.js +64 -0
- package/dist/codeguide.d.ts +14 -0
- package/dist/codeguide.js +53 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +31 -0
- package/dist/services/base/base-service.d.ts +30 -0
- package/dist/services/base/base-service.js +187 -0
- package/dist/services/base/index.d.ts +1 -0
- package/dist/services/base/index.js +5 -0
- package/dist/services/generation/generation-service.d.ts +15 -0
- package/dist/services/generation/generation-service.js +40 -0
- package/dist/services/generation/generation-types.d.ts +111 -0
- package/dist/services/generation/generation-types.js +2 -0
- package/dist/services/generation/index.d.ts +2 -0
- package/dist/services/generation/index.js +20 -0
- package/dist/services/index.d.ts +11 -0
- package/dist/services/index.js +45 -0
- package/dist/services/projects/index.d.ts +2 -0
- package/dist/services/projects/index.js +20 -0
- package/dist/services/projects/project-service.d.ts +14 -0
- package/dist/services/projects/project-service.js +53 -0
- package/dist/services/projects/project-types.d.ts +97 -0
- package/dist/services/projects/project-types.js +2 -0
- package/dist/services/repository-analysis/index.d.ts +2 -0
- package/dist/services/repository-analysis/index.js +20 -0
- package/dist/services/repository-analysis/repository-service.d.ts +10 -0
- package/dist/services/repository-analysis/repository-service.js +31 -0
- package/dist/services/repository-analysis/repository-types.d.ts +90 -0
- package/dist/services/repository-analysis/repository-types.js +2 -0
- package/dist/services/tasks/index.d.ts +2 -0
- package/dist/services/tasks/index.js +20 -0
- package/dist/services/tasks/task-service.d.ts +30 -0
- package/dist/services/tasks/task-service.js +105 -0
- package/dist/services/tasks/task-types.d.ts +144 -0
- package/dist/services/tasks/task-types.js +2 -0
- package/dist/services/usage/index.d.ts +2 -0
- package/dist/services/usage/index.js +20 -0
- package/dist/services/usage/usage-service.d.ts +14 -0
- package/dist/services/usage/usage-service.js +68 -0
- package/dist/services/usage/usage-types.d.ts +133 -0
- package/dist/services/usage/usage-types.js +2 -0
- package/dist/types.d.ts +42 -0
- package/dist/types.js +2 -0
- package/index.ts +12 -0
- package/jest.config.json +19 -0
- package/package.json +45 -0
- package/services/README.md +113 -0
- package/services/base/base-service.ts +230 -0
- package/services/base/index.ts +1 -0
- package/services/generation/generation-service.ts +81 -0
- package/services/generation/generation-types.ts +131 -0
- package/services/generation/index.ts +2 -0
- package/services/index.ts +22 -0
- package/services/projects/index.ts +2 -0
- package/services/projects/project-service.ts +67 -0
- package/services/projects/project-types.ts +108 -0
- package/services/repository-analysis/index.ts +2 -0
- package/services/repository-analysis/repository-service.ts +42 -0
- package/services/repository-analysis/repository-types.ts +99 -0
- package/services/tasks/index.ts +2 -0
- package/services/tasks/task-service.ts +143 -0
- package/services/tasks/task-types.ts +165 -0
- package/services/usage/index.ts +2 -0
- package/services/usage/usage-service.ts +96 -0
- package/services/usage/usage-types.ts +147 -0
- package/tsconfig.json +10 -0
- package/types.ts +51 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { UsageService } from '../../../services/usage/usage-service'
|
|
2
|
+
import { APIServiceConfig } from '../../../types'
|
|
3
|
+
import axios from 'axios'
|
|
4
|
+
import MockAdapter from 'axios-mock-adapter'
|
|
5
|
+
import {
|
|
6
|
+
TrackUsageRequest,
|
|
7
|
+
CreditBalanceResponse,
|
|
8
|
+
CreditCheckResponse,
|
|
9
|
+
UsageSummaryResponse,
|
|
10
|
+
AuthorizationResponse,
|
|
11
|
+
CalculateUsageResponse,
|
|
12
|
+
TrackCodespaceUsageResponse,
|
|
13
|
+
CodespaceTaskUsageResponse,
|
|
14
|
+
} from '../../../services/usage/usage-types'
|
|
15
|
+
|
|
16
|
+
describe('UsageService', () => {
|
|
17
|
+
let mockAxios: MockAdapter
|
|
18
|
+
let usageService: UsageService
|
|
19
|
+
let config: APIServiceConfig
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
mockAxios = new MockAdapter(axios)
|
|
23
|
+
config = {
|
|
24
|
+
baseUrl: 'https://api.codeguide.app',
|
|
25
|
+
databaseApiKey: 'sk_test123',
|
|
26
|
+
}
|
|
27
|
+
usageService = new UsageService(config)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
mockAxios.restore()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('trackUsage', () => {
|
|
35
|
+
it('should track usage successfully', async () => {
|
|
36
|
+
const request: TrackUsageRequest = {
|
|
37
|
+
model_key: 'gpt-4',
|
|
38
|
+
input_tokens: 100,
|
|
39
|
+
output_tokens: 50,
|
|
40
|
+
call_seconds: 2,
|
|
41
|
+
cost_amount: 0.05,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const response: TrackUsageResponse = {
|
|
45
|
+
success: true,
|
|
46
|
+
credits_used: 0.05,
|
|
47
|
+
remaining_credits: 9.95,
|
|
48
|
+
message: 'Usage tracked successfully',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
mockAxios.onPost('/v1/usage/track', request).reply(200, response)
|
|
52
|
+
|
|
53
|
+
const result = await usageService.trackUsage(request)
|
|
54
|
+
|
|
55
|
+
expect(result).toEqual(response)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should handle track usage errors', async () => {
|
|
59
|
+
const request: TrackUsageRequest = {
|
|
60
|
+
model_key: 'gpt-4',
|
|
61
|
+
input_tokens: 100,
|
|
62
|
+
output_tokens: 50,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
mockAxios.onPost('/v1/usage/track', request).reply(400, {
|
|
66
|
+
detail: 'Invalid request',
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
await expect(usageService.trackUsage(request)).rejects.toThrow('API Error: Invalid request')
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe('getCreditBalance', () => {
|
|
74
|
+
it('should get credit balance successfully', async () => {
|
|
75
|
+
const response: CreditBalanceResponse = {
|
|
76
|
+
user_id: 'user123',
|
|
77
|
+
total_consumed: 10.5,
|
|
78
|
+
total_allotted: 100,
|
|
79
|
+
remaining_credits: 89.5,
|
|
80
|
+
utilization_percentage: 10.5,
|
|
81
|
+
billing_cycle_start: '2024-01-01',
|
|
82
|
+
billing_cycle_end: '2024-02-01',
|
|
83
|
+
subscription: {
|
|
84
|
+
plan: 'pro',
|
|
85
|
+
status: 'active',
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
mockAxios.onGet('/v1/usage/credit-balance').reply(200, response)
|
|
90
|
+
|
|
91
|
+
const result = await usageService.getCreditBalance()
|
|
92
|
+
|
|
93
|
+
expect(result).toEqual(response)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
describe('checkCredits', () => {
|
|
98
|
+
it('should check credits with all parameters', async () => {
|
|
99
|
+
const params = {
|
|
100
|
+
model_key: 'gpt-4',
|
|
101
|
+
input_tokens: 100,
|
|
102
|
+
output_tokens: 50,
|
|
103
|
+
call_seconds: 2,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const response: CreditCheckResponse = {
|
|
107
|
+
has_sufficient_credits: true,
|
|
108
|
+
estimated_cost: 0.05,
|
|
109
|
+
remaining_credits: 89.5,
|
|
110
|
+
model_key: 'gpt-4',
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
mockAxios
|
|
114
|
+
.onGet(
|
|
115
|
+
'/v1/usage/credit-check?model_key=gpt-4&input_tokens=100&output_tokens=50&call_seconds=2'
|
|
116
|
+
)
|
|
117
|
+
.reply(200, response)
|
|
118
|
+
|
|
119
|
+
const result = await usageService.checkCredits(params)
|
|
120
|
+
|
|
121
|
+
expect(result).toEqual(response)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('should check credits with partial parameters', async () => {
|
|
125
|
+
const params = {
|
|
126
|
+
model_key: 'gpt-4',
|
|
127
|
+
input_tokens: 100,
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const response: CreditCheckResponse = {
|
|
131
|
+
has_sufficient_credits: true,
|
|
132
|
+
estimated_cost: 0.02,
|
|
133
|
+
remaining_credits: 89.5,
|
|
134
|
+
model_key: 'gpt-4',
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
mockAxios
|
|
138
|
+
.onGet('/v1/usage/credit-check?model_key=gpt-4&input_tokens=100')
|
|
139
|
+
.reply(200, response)
|
|
140
|
+
|
|
141
|
+
const result = await usageService.checkCredits(params)
|
|
142
|
+
|
|
143
|
+
expect(result).toEqual(response)
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
describe('getUsageSummary', () => {
|
|
148
|
+
it('should get usage summary with date range', async () => {
|
|
149
|
+
const params = {
|
|
150
|
+
start_date: '2024-01-01',
|
|
151
|
+
end_date: '2024-01-31',
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const response: UsageSummaryResponse = {
|
|
155
|
+
user_id: 'user123',
|
|
156
|
+
period: {
|
|
157
|
+
start_date: '2024-01-01',
|
|
158
|
+
end_date: '2024-01-31',
|
|
159
|
+
},
|
|
160
|
+
usage_summary: {
|
|
161
|
+
total_credits_used: 15.5,
|
|
162
|
+
total_calls: 42,
|
|
163
|
+
model_breakdown: {
|
|
164
|
+
'gpt-4': { calls: 20, credits: 12.0 },
|
|
165
|
+
'gpt-3.5': { calls: 22, credits: 3.5 },
|
|
166
|
+
},
|
|
167
|
+
daily_usage: [
|
|
168
|
+
{ date: '2024-01-01', credits_used: 1.5, calls: 5 },
|
|
169
|
+
{ date: '2024-01-02', credits_used: 2.0, calls: 8 },
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
subscription: {
|
|
173
|
+
plan: 'pro',
|
|
174
|
+
status: 'active',
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
mockAxios
|
|
179
|
+
.onGet('/v1/usage/summary?start_date=2024-01-01&end_date=2024-01-31')
|
|
180
|
+
.reply(200, response)
|
|
181
|
+
|
|
182
|
+
const result = await usageService.getUsageSummary(params)
|
|
183
|
+
|
|
184
|
+
expect(result).toEqual(response)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('should get usage summary without date range', async () => {
|
|
188
|
+
const response: UsageSummaryResponse = {
|
|
189
|
+
user_id: 'user123',
|
|
190
|
+
period: {
|
|
191
|
+
start_date: '2024-01-01',
|
|
192
|
+
end_date: '2024-01-31',
|
|
193
|
+
},
|
|
194
|
+
usage_summary: {
|
|
195
|
+
total_credits_used: 15.5,
|
|
196
|
+
total_calls: 42,
|
|
197
|
+
model_breakdown: {},
|
|
198
|
+
daily_usage: [],
|
|
199
|
+
},
|
|
200
|
+
subscription: {
|
|
201
|
+
plan: 'pro',
|
|
202
|
+
status: 'active',
|
|
203
|
+
},
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
mockAxios.onGet('/v1/usage/summary').reply(200, response)
|
|
207
|
+
|
|
208
|
+
const result = await usageService.getUsageSummary()
|
|
209
|
+
|
|
210
|
+
expect(result).toEqual(response)
|
|
211
|
+
})
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
describe('getAuthorization', () => {
|
|
215
|
+
it('should get authorization info successfully', async () => {
|
|
216
|
+
const response: AuthorizationResponse = {
|
|
217
|
+
user_id: 'user123',
|
|
218
|
+
subscription: {
|
|
219
|
+
plan: 'pro',
|
|
220
|
+
status: 'active',
|
|
221
|
+
features: ['api-access', 'priority-queue'],
|
|
222
|
+
},
|
|
223
|
+
usage_limits: {
|
|
224
|
+
monthly_credits: 100,
|
|
225
|
+
max_calls_per_day: 1000,
|
|
226
|
+
},
|
|
227
|
+
permissions: ['read', 'write', 'delete'],
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
mockAxios.onGet('/v1/usage/authorization').reply(200, response)
|
|
231
|
+
|
|
232
|
+
const result = await usageService.getAuthorization()
|
|
233
|
+
|
|
234
|
+
expect(result).toEqual(response)
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
describe('getFreeUserStatus', () => {
|
|
239
|
+
it('should get free user status successfully', async () => {
|
|
240
|
+
const response = {
|
|
241
|
+
is_free_user: true,
|
|
242
|
+
has_available_credits: true,
|
|
243
|
+
credits_remaining: 5.0,
|
|
244
|
+
credits_expire_at: '2024-12-31',
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
mockAxios.onGet('/v1/usage/free-user-status').reply(200, response)
|
|
248
|
+
|
|
249
|
+
const result = await usageService.getFreeUserStatus()
|
|
250
|
+
|
|
251
|
+
expect(result).toEqual(response)
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
describe('calculateUsageCost', () => {
|
|
256
|
+
it('should calculate usage cost with all parameters', async () => {
|
|
257
|
+
const params = {
|
|
258
|
+
model_key: 'gpt-4',
|
|
259
|
+
input_tokens: 100,
|
|
260
|
+
output_tokens: 50,
|
|
261
|
+
call_seconds: 2,
|
|
262
|
+
cost_amount: 0.05,
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const response: CalculateUsageResponse = {
|
|
266
|
+
model_key: 'gpt-4',
|
|
267
|
+
estimated_cost: 0.05,
|
|
268
|
+
calculation_breakdown: {
|
|
269
|
+
input_cost: 0.02,
|
|
270
|
+
output_cost: 0.02,
|
|
271
|
+
time_cost: 0.01,
|
|
272
|
+
total_cost: 0.05,
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
mockAxios
|
|
277
|
+
.onGet(
|
|
278
|
+
'/v1/usage/calculate?model_key=gpt-4&input_tokens=100&output_tokens=50&call_seconds=2&cost_amount=0.05'
|
|
279
|
+
)
|
|
280
|
+
.reply(200, response)
|
|
281
|
+
|
|
282
|
+
const result = await usageService.calculateUsageCost(params)
|
|
283
|
+
|
|
284
|
+
expect(result).toEqual(response)
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
describe('trackCodespaceUsage', () => {
|
|
289
|
+
it('should track codespace usage successfully', async () => {
|
|
290
|
+
const request = {
|
|
291
|
+
codespace_task_id: 'task123',
|
|
292
|
+
model_key: 'gpt-4',
|
|
293
|
+
input_tokens: 100,
|
|
294
|
+
output_tokens: 50,
|
|
295
|
+
call_seconds: 2,
|
|
296
|
+
cost_amount: 0.05,
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const response: TrackCodespaceUsageResponse = {
|
|
300
|
+
id: 'usage123',
|
|
301
|
+
codespace_task_id: 'task123',
|
|
302
|
+
user_id: 'user123',
|
|
303
|
+
model_key: 'gpt-4',
|
|
304
|
+
input_tokens: 100,
|
|
305
|
+
output_tokens: 50,
|
|
306
|
+
call_seconds: 2,
|
|
307
|
+
cost_amount: 0.05,
|
|
308
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
mockAxios.onPost('/v1/usage/codespace/track', request).reply(200, response)
|
|
312
|
+
|
|
313
|
+
const result = await usageService.trackCodespaceUsage(request)
|
|
314
|
+
|
|
315
|
+
expect(result).toEqual(response)
|
|
316
|
+
})
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
describe('getCodespaceTaskUsage', () => {
|
|
320
|
+
it('should get codespace task usage successfully', async () => {
|
|
321
|
+
const response: CodespaceTaskUsageResponse = {
|
|
322
|
+
codespace_task_id: 'task123',
|
|
323
|
+
total_usage: {
|
|
324
|
+
total_input_tokens: 200,
|
|
325
|
+
total_output_tokens: 100,
|
|
326
|
+
total_call_seconds: 4,
|
|
327
|
+
total_cost: 0.1,
|
|
328
|
+
},
|
|
329
|
+
usage_records: [
|
|
330
|
+
{
|
|
331
|
+
id: 'usage123',
|
|
332
|
+
codespace_task_id: 'task123',
|
|
333
|
+
user_id: 'user123',
|
|
334
|
+
model_key: 'gpt-4',
|
|
335
|
+
input_tokens: 100,
|
|
336
|
+
output_tokens: 50,
|
|
337
|
+
call_seconds: 2,
|
|
338
|
+
cost_amount: 0.05,
|
|
339
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
340
|
+
},
|
|
341
|
+
],
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
mockAxios.onGet('/v1/usage/codespace/task/task123').reply(200, response)
|
|
345
|
+
|
|
346
|
+
const result = await usageService.getCodespaceTaskUsage('task123')
|
|
347
|
+
|
|
348
|
+
expect(result).toEqual(response)
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
describe('healthCheck', () => {
|
|
353
|
+
it('should return true when API is healthy', async () => {
|
|
354
|
+
mockAxios.onGet('/v1/usage/health').reply(200, {
|
|
355
|
+
status: 'healthy',
|
|
356
|
+
timestamp: '2024-01-01T00:00:00Z',
|
|
357
|
+
version: '1.0.0',
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
const result = await usageService.healthCheck()
|
|
361
|
+
|
|
362
|
+
expect(result).toBe(true)
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
it('should return false when API is not healthy', async () => {
|
|
366
|
+
mockAxios.onGet('/v1/usage/health').reply(200, {
|
|
367
|
+
status: 'unhealthy',
|
|
368
|
+
timestamp: '2024-01-01T00:00:00Z',
|
|
369
|
+
version: '1.0.0',
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
const result = await usageService.healthCheck()
|
|
373
|
+
|
|
374
|
+
expect(result).toBe(false)
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
it('should return false when health check fails', async () => {
|
|
378
|
+
mockAxios.onGet('/v1/usage/health').reply(500)
|
|
379
|
+
|
|
380
|
+
const result = await usageService.healthCheck()
|
|
381
|
+
|
|
382
|
+
expect(result).toBe(false)
|
|
383
|
+
})
|
|
384
|
+
})
|
|
385
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BaseService } from '../services/base/base-service'
|
|
2
|
+
import { APIServiceConfig } from '../types'
|
|
3
|
+
|
|
4
|
+
export class TestService extends BaseService {
|
|
5
|
+
constructor(config: APIServiceConfig) {
|
|
6
|
+
super(config)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Public methods to test protected methods
|
|
10
|
+
public async testGet(url: string, config?: any): Promise<any> {
|
|
11
|
+
return this.get(url, config)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public async testPost(url: string, data?: any, config?: any): Promise<any> {
|
|
15
|
+
return this.post(url, data, config)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public async testPut(url: string, data?: any, config?: any): Promise<any> {
|
|
19
|
+
return this.put(url, data, config)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public async testDelete(url: string, config?: any): Promise<any> {
|
|
23
|
+
return this.delete(url, config)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public testBuildUrl(endpoint: string): string {
|
|
27
|
+
return this.buildUrl(endpoint)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public testGetAuthenticationMethod() {
|
|
31
|
+
return this.getAuthenticationMethod()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public testValidateAuthentication() {
|
|
35
|
+
return this.validateAuthentication()
|
|
36
|
+
}
|
|
37
|
+
}
|
package/api-service.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import dotenv from 'dotenv'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
// Load environment variables from project root
|
|
5
|
+
dotenv.config({
|
|
6
|
+
path: path.resolve(__dirname, '../../../.env'),
|
|
7
|
+
quiet: true,
|
|
8
|
+
})
|
|
9
|
+
import axios, { AxiosInstance } from 'axios'
|
|
10
|
+
import { CodeGuideRequest, CodeGuideResponse, APIServiceConfig } from './types'
|
|
11
|
+
|
|
12
|
+
export class APIService {
|
|
13
|
+
private client: AxiosInstance
|
|
14
|
+
private config: APIServiceConfig
|
|
15
|
+
|
|
16
|
+
constructor(config: APIServiceConfig) {
|
|
17
|
+
this.config = config
|
|
18
|
+
|
|
19
|
+
// Ensure baseUrl includes the API version
|
|
20
|
+
const baseUrl = config.baseUrl.endsWith('/v1')
|
|
21
|
+
? config.baseUrl
|
|
22
|
+
: `${config.baseUrl}${config.baseUrl.endsWith('/') ? '' : '/'}v1`
|
|
23
|
+
|
|
24
|
+
this.client = axios.create({
|
|
25
|
+
baseURL: baseUrl,
|
|
26
|
+
timeout: config.timeout || 3600000, // 1 hour timeout for document generation
|
|
27
|
+
headers: {
|
|
28
|
+
'Content-Type': 'application/json',
|
|
29
|
+
...(config.apiKey && { 'X-API-Key': config.apiKey }),
|
|
30
|
+
...(config.userId && { 'X-User-ID': config.userId }),
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async getCodeGuide(request: CodeGuideRequest): Promise<CodeGuideResponse> {
|
|
36
|
+
try {
|
|
37
|
+
// Use the appropriate endpoint based on the API documentation
|
|
38
|
+
const response = await this.client.post<CodeGuideResponse>('/generate/refine-prompt', {
|
|
39
|
+
user_prompt: request.prompt,
|
|
40
|
+
...request,
|
|
41
|
+
})
|
|
42
|
+
return {
|
|
43
|
+
id: response.data.id || Date.now().toString(),
|
|
44
|
+
response: response.data.refined_prompt || response.data.content || 'No response available',
|
|
45
|
+
timestamp: new Date().toISOString(),
|
|
46
|
+
language: request.language,
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (axios.isAxiosError(error)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`API Error: ${error.response?.data?.detail || error.response?.data?.message || error.message}`
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`Unknown error: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async healthCheck(): Promise<boolean> {
|
|
59
|
+
try {
|
|
60
|
+
// Use usage health endpoint from API documentation
|
|
61
|
+
await this.client.get('/usage/health')
|
|
62
|
+
return true
|
|
63
|
+
} catch {
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
package/codeguide.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import dotenv from 'dotenv'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
// Load environment variables from project root
|
|
5
|
+
dotenv.config({
|
|
6
|
+
path: path.resolve(__dirname, '../../../.env'),
|
|
7
|
+
quiet: true,
|
|
8
|
+
})
|
|
9
|
+
import {
|
|
10
|
+
GenerationService,
|
|
11
|
+
ProjectService,
|
|
12
|
+
UsageService,
|
|
13
|
+
RepositoryAnalysisService,
|
|
14
|
+
TaskService,
|
|
15
|
+
} from './services'
|
|
16
|
+
import { APIServiceConfig, CodeGuideOptions } from './types'
|
|
17
|
+
|
|
18
|
+
export class CodeGuide {
|
|
19
|
+
public generation: GenerationService
|
|
20
|
+
public projects: ProjectService
|
|
21
|
+
public usage: UsageService
|
|
22
|
+
public repositoryAnalysis: RepositoryAnalysisService
|
|
23
|
+
public tasks: TaskService
|
|
24
|
+
private options: CodeGuideOptions
|
|
25
|
+
|
|
26
|
+
constructor(config: APIServiceConfig, options: CodeGuideOptions = {}) {
|
|
27
|
+
this.options = options
|
|
28
|
+
|
|
29
|
+
// Initialize all services with the same config
|
|
30
|
+
this.generation = new GenerationService(config)
|
|
31
|
+
this.projects = new ProjectService(config)
|
|
32
|
+
this.usage = new UsageService(config)
|
|
33
|
+
this.repositoryAnalysis = new RepositoryAnalysisService(config)
|
|
34
|
+
this.tasks = new TaskService(config)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Convenience method for backward compatibility
|
|
38
|
+
async getGuidance(prompt: string): Promise<any> {
|
|
39
|
+
const request = {
|
|
40
|
+
user_prompt: prompt,
|
|
41
|
+
...(this.options.language && { language: this.options.language }),
|
|
42
|
+
...(this.options.context && { context: this.options.context }),
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (this.options.verbose) {
|
|
46
|
+
console.log('Sending request:', JSON.stringify(request, null, 2))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const response = await this.generation.refinePrompt(request)
|
|
50
|
+
|
|
51
|
+
if (this.options.verbose) {
|
|
52
|
+
console.log('Received response:', JSON.stringify(response, null, 2))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
id: Date.now().toString(),
|
|
57
|
+
response: response.refined_prompt,
|
|
58
|
+
timestamp: new Date().toISOString(),
|
|
59
|
+
language: this.options.language,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async isHealthy(): Promise<boolean> {
|
|
64
|
+
return this.usage.healthCheck()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
setOptions(options: Partial<CodeGuideOptions>): void {
|
|
68
|
+
this.options = { ...this.options, ...options }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseService } from '../services/base/base-service';
|
|
2
|
+
import { APIServiceConfig } from '../types';
|
|
3
|
+
export declare class TestService extends BaseService {
|
|
4
|
+
constructor(config: APIServiceConfig);
|
|
5
|
+
testGet(url: string, config?: any): Promise<any>;
|
|
6
|
+
testPost(url: string, data?: any, config?: any): Promise<any>;
|
|
7
|
+
testPut(url: string, data?: any, config?: any): Promise<any>;
|
|
8
|
+
testDelete(url: string, config?: any): Promise<any>;
|
|
9
|
+
testBuildUrl(endpoint: string): string;
|
|
10
|
+
testGetAuthenticationMethod(): import("../types").AuthenticationMethod | null;
|
|
11
|
+
testValidateAuthentication(): import("../types").AuthenticationResult;
|
|
12
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestService = void 0;
|
|
4
|
+
const base_service_1 = require("../services/base/base-service");
|
|
5
|
+
class TestService extends base_service_1.BaseService {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
super(config);
|
|
8
|
+
}
|
|
9
|
+
// Public methods to test protected methods
|
|
10
|
+
async testGet(url, config) {
|
|
11
|
+
return this.get(url, config);
|
|
12
|
+
}
|
|
13
|
+
async testPost(url, data, config) {
|
|
14
|
+
return this.post(url, data, config);
|
|
15
|
+
}
|
|
16
|
+
async testPut(url, data, config) {
|
|
17
|
+
return this.put(url, data, config);
|
|
18
|
+
}
|
|
19
|
+
async testDelete(url, config) {
|
|
20
|
+
return this.delete(url, config);
|
|
21
|
+
}
|
|
22
|
+
testBuildUrl(endpoint) {
|
|
23
|
+
return this.buildUrl(endpoint);
|
|
24
|
+
}
|
|
25
|
+
testGetAuthenticationMethod() {
|
|
26
|
+
return this.getAuthenticationMethod();
|
|
27
|
+
}
|
|
28
|
+
testValidateAuthentication() {
|
|
29
|
+
return this.validateAuthentication();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.TestService = TestService;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CodeGuideRequest, CodeGuideResponse, APIServiceConfig } from './types';
|
|
2
|
+
export declare class APIService {
|
|
3
|
+
private client;
|
|
4
|
+
private config;
|
|
5
|
+
constructor(config: APIServiceConfig);
|
|
6
|
+
getCodeGuide(request: CodeGuideRequest): Promise<CodeGuideResponse>;
|
|
7
|
+
healthCheck(): Promise<boolean>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.APIService = void 0;
|
|
7
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
// Load environment variables from project root
|
|
10
|
+
dotenv_1.default.config({
|
|
11
|
+
path: path_1.default.resolve(__dirname, '../../../.env'),
|
|
12
|
+
quiet: true,
|
|
13
|
+
});
|
|
14
|
+
const axios_1 = __importDefault(require("axios"));
|
|
15
|
+
class APIService {
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
// Ensure baseUrl includes the API version
|
|
19
|
+
const baseUrl = config.baseUrl.endsWith('/v1')
|
|
20
|
+
? config.baseUrl
|
|
21
|
+
: `${config.baseUrl}${config.baseUrl.endsWith('/') ? '' : '/'}v1`;
|
|
22
|
+
this.client = axios_1.default.create({
|
|
23
|
+
baseURL: baseUrl,
|
|
24
|
+
timeout: config.timeout || 3600000, // 1 hour timeout for document generation
|
|
25
|
+
headers: {
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
...(config.apiKey && { 'X-API-Key': config.apiKey }),
|
|
28
|
+
...(config.userId && { 'X-User-ID': config.userId }),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async getCodeGuide(request) {
|
|
33
|
+
try {
|
|
34
|
+
// Use the appropriate endpoint based on the API documentation
|
|
35
|
+
const response = await this.client.post('/generate/refine-prompt', {
|
|
36
|
+
user_prompt: request.prompt,
|
|
37
|
+
...request,
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
id: response.data.id || Date.now().toString(),
|
|
41
|
+
response: response.data.refined_prompt || response.data.content || 'No response available',
|
|
42
|
+
timestamp: new Date().toISOString(),
|
|
43
|
+
language: request.language,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
48
|
+
throw new Error(`API Error: ${error.response?.data?.detail || error.response?.data?.message || error.message}`);
|
|
49
|
+
}
|
|
50
|
+
throw new Error(`Unknown error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async healthCheck() {
|
|
54
|
+
try {
|
|
55
|
+
// Use usage health endpoint from API documentation
|
|
56
|
+
await this.client.get('/usage/health');
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.APIService = APIService;
|