@drax/ai-back 2.0.0 → 3.16.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.
Files changed (64) hide show
  1. package/dist/config/OpenAiConfig.js +1 -0
  2. package/dist/controllers/AILogController.js +18 -0
  3. package/dist/factory/OpenAiProviderFactory.js +2 -1
  4. package/dist/factory/services/AILogServiceFactory.js +30 -0
  5. package/dist/index.js +10 -1
  6. package/dist/interfaces/IAILog.js +1 -0
  7. package/dist/interfaces/IAILogRepository.js +1 -0
  8. package/dist/models/AILogModel.js +50 -0
  9. package/dist/permissions/AILogPermissions.js +10 -0
  10. package/dist/providers/OpenAiProvider.js +176 -26
  11. package/dist/repository/mongo/AILogMongoRepository.js +13 -0
  12. package/dist/repository/sqlite/AILogSqliteRepository.js +45 -0
  13. package/dist/routes/AILogRoutes.js +21 -0
  14. package/dist/schemas/AILogSchema.js +44 -0
  15. package/dist/services/AILogService.js +9 -0
  16. package/package.json +8 -2
  17. package/src/config/OpenAiConfig.ts +1 -0
  18. package/src/controllers/AILogController.ts +29 -0
  19. package/src/factory/OpenAiProviderFactory.ts +4 -2
  20. package/src/factory/services/AILogServiceFactory.ts +41 -0
  21. package/src/index.ts +39 -1
  22. package/src/interfaces/IAILogRepository.ts +11 -0
  23. package/src/interfaces/IAIProvider.ts +48 -2
  24. package/src/models/AILogModel.ts +65 -0
  25. package/src/permissions/AILogPermissions.ts +14 -0
  26. package/src/providers/OpenAiProvider.ts +231 -29
  27. package/src/repository/mongo/AILogMongoRepository.ts +22 -0
  28. package/src/repository/sqlite/AILogSqliteRepository.ts +53 -0
  29. package/src/routes/AILogRoutes.ts +38 -0
  30. package/src/schemas/AILogSchema.ts +52 -0
  31. package/src/services/AILogService.ts +20 -0
  32. package/test/OpenAiProvider.test.ts +91 -0
  33. package/tsconfig.tsbuildinfo +1 -1
  34. package/types/config/OpenAiConfig.d.ts +2 -1
  35. package/types/config/OpenAiConfig.d.ts.map +1 -1
  36. package/types/controllers/AILogController.d.ts +8 -0
  37. package/types/controllers/AILogController.d.ts.map +1 -0
  38. package/types/factory/OpenAiProviderFactory.d.ts.map +1 -1
  39. package/types/factory/services/AILogServiceFactory.d.ts +8 -0
  40. package/types/factory/services/AILogServiceFactory.d.ts.map +1 -0
  41. package/types/index.d.ts +13 -3
  42. package/types/index.d.ts.map +1 -1
  43. package/types/interfaces/IAILog.d.ts +77 -0
  44. package/types/interfaces/IAILog.d.ts.map +1 -0
  45. package/types/interfaces/IAILogRepository.d.ts +6 -0
  46. package/types/interfaces/IAILogRepository.d.ts.map +1 -0
  47. package/types/interfaces/IAIProvider.d.ts +32 -2
  48. package/types/interfaces/IAIProvider.d.ts.map +1 -1
  49. package/types/models/AILogModel.d.ts +15 -0
  50. package/types/models/AILogModel.d.ts.map +1 -0
  51. package/types/permissions/AILogPermissions.d.ts +10 -0
  52. package/types/permissions/AILogPermissions.d.ts.map +1 -0
  53. package/types/providers/OpenAiProvider.d.ts +71 -2
  54. package/types/providers/OpenAiProvider.d.ts.map +1 -1
  55. package/types/repository/mongo/AILogMongoRepository.d.ts +9 -0
  56. package/types/repository/mongo/AILogMongoRepository.d.ts.map +1 -0
  57. package/types/repository/sqlite/AILogSqliteRepository.d.ts +23 -0
  58. package/types/repository/sqlite/AILogSqliteRepository.d.ts.map +1 -0
  59. package/types/routes/AILogRoutes.d.ts +4 -0
  60. package/types/routes/AILogRoutes.d.ts.map +1 -0
  61. package/types/schemas/AILogSchema.d.ts +81 -0
  62. package/types/schemas/AILogSchema.d.ts.map +1 -0
  63. package/types/services/AILogService.d.ts +10 -0
  64. package/types/services/AILogService.d.ts.map +1 -0
@@ -0,0 +1,38 @@
1
+
2
+ import AILogController from "../controllers/AILogController.js";
3
+ import {CrudSchemaBuilder} from "@drax/crud-back";
4
+ import {AILogSchema, AILogBaseSchema} from '../schemas/AILogSchema.js'
5
+
6
+ async function AILogFastifyRoutes(fastify, options) {
7
+
8
+ const controller: AILogController = new AILogController()
9
+ const schemas = new CrudSchemaBuilder(AILogSchema, AILogBaseSchema,AILogBaseSchema, 'AILog', 'openapi-3.0', ['ai']);
10
+
11
+ fastify.get('/api/ailog', {schema: schemas.paginateSchema}, (req,rep) => controller.paginate(req,rep))
12
+
13
+ fastify.get('/api/ailog/find', {schema: schemas.findSchema}, (req,rep) => controller.find(req,rep))
14
+
15
+ fastify.get('/api/ailog/search', {schema: schemas.searchSchema}, (req,rep) => controller.search(req,rep))
16
+
17
+ fastify.get('/api/ailog/:id', {schema: schemas.findByIdSchema}, (req,rep) => controller.findById(req,rep))
18
+
19
+ fastify.get('/api/ailog/find-one', {schema: schemas.findOneSchema}, (req,rep) => controller.findOne(req,rep))
20
+
21
+ fastify.get('/api/ailog/group-by', {schema: schemas.groupBySchema}, (req,rep) => controller.groupBy(req,rep))
22
+
23
+ fastify.post('/api/ailog', {schema: schemas.createSchema}, (req,rep) =>controller.create(req,rep))
24
+
25
+ fastify.put('/api/ailog/:id', {schema: schemas.updateSchema}, (req,rep) =>controller.update(req,rep))
26
+
27
+ fastify.patch('/api/ailog/:id', {schema: schemas.updateSchema}, (req,rep) =>controller.updatePartial(req,rep))
28
+
29
+ fastify.delete('/api/ailog/:id', {schema: schemas.deleteSchema}, (req,rep) =>controller.delete(req,rep))
30
+
31
+ fastify.get('/api/ailog/export', (req,rep) =>controller.export(req,rep))
32
+
33
+ fastify.post('/api/ailog/import', (req,rep) => controller.import(req,rep))
34
+
35
+ }
36
+
37
+ export default AILogFastifyRoutes;
38
+ export {AILogFastifyRoutes}
@@ -0,0 +1,52 @@
1
+ import {z} from 'zod';
2
+
3
+
4
+ const AILogBaseSchema = z.object({
5
+ provider: z.string().optional(),
6
+ model: z.string().optional(),
7
+ operationTitle: z.string().optional(),
8
+ operationGroup: z.string().optional(),
9
+ ip: z.string().optional(),
10
+ userAgent: z.string().optional(),
11
+ input: z.string().optional(),
12
+ inputImages: z.array(
13
+ z.object({
14
+ filename: z.string().optional(),
15
+ filepath: z.string().optional(),
16
+ size: z.number().nullable().optional(),
17
+ mimetype: z.string().optional(),
18
+ url: z.string().optional()
19
+ })
20
+ ).optional(),
21
+ inputFiles: z.array(
22
+ z.object({
23
+ filename: z.string().optional(),
24
+ filepath: z.string().optional(),
25
+ size: z.number().nullable().optional(),
26
+ mimetype: z.string().optional(),
27
+ url: z.string().optional()
28
+ })
29
+ ).optional(),
30
+ inputTokens: z.number().nullable().optional(),
31
+ outputTokens: z.number().nullable().optional(),
32
+ tokens: z.number().nullable().optional(),
33
+ startedAt: z.coerce.date().nullable().optional(),
34
+ endedAt: z.coerce.date().nullable().optional(),
35
+ responseTime: z.string().optional(),
36
+ output: z.string().optional(),
37
+ success: z.boolean().optional(),
38
+ statusCode: z.number().nullable().optional(),
39
+ errorMessage: z.string().optional(),
40
+ tenant: z.coerce.string().optional().nullable(),
41
+ user: z.coerce.string().optional().nullable()
42
+ });
43
+
44
+ const AILogSchema = AILogBaseSchema
45
+ .extend({
46
+ _id: z.coerce.string(),
47
+ tenant: z.object({_id: z.coerce.string(), name: z.string()}).nullable().optional(),
48
+ user: z.object({_id: z.coerce.string(), username: z.string()}).nullable().optional()
49
+ })
50
+
51
+ export default AILogSchema;
52
+ export {AILogSchema, AILogBaseSchema}
@@ -0,0 +1,20 @@
1
+
2
+ import type{IAILogRepository} from "../interfaces/IAILogRepository";
3
+ import type {IAILogBase, IAILog} from "@drax/ai-share";
4
+ import {AbstractService} from "@drax/crud-back";
5
+ import type {ZodObject, ZodRawShape} from "zod";
6
+
7
+ class AILogService extends AbstractService<IAILog, IAILogBase, IAILogBase> {
8
+
9
+
10
+ constructor(AILogRepository: IAILogRepository, baseSchema?: ZodObject<ZodRawShape>, fullSchema?: ZodObject<ZodRawShape>) {
11
+ super(AILogRepository, baseSchema, fullSchema);
12
+
13
+ this._validateOutput = true
14
+
15
+ }
16
+
17
+ }
18
+
19
+ export default AILogService
20
+ export {AILogService}
@@ -6,6 +6,97 @@ import {IPromptMemory, IPromptMessage} from "../src/interfaces/IAIProvider";
6
6
 
7
7
  describe('OpenAi Test', () => {
8
8
 
9
+ test('OpenAi prompt supports image inputs and vision model fallback', async () => {
10
+ let request: any
11
+
12
+ class MockedOpenAiProvider extends OpenAiProvider {
13
+ constructor() {
14
+ super('test-key', 'gpt-4.1-mini', 'gpt-4o-mini')
15
+ this._client = {
16
+ chat: {
17
+ completions: {
18
+ create: async (payload: any) => {
19
+ request = payload
20
+ return {
21
+ choices: [{message: {content: '{"name":"invoice"}'}}],
22
+ usage: {
23
+ total_tokens: 10,
24
+ prompt_tokens: 7,
25
+ completion_tokens: 3
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ const openAi = new MockedOpenAiProvider()
36
+
37
+ const r = await openAi.prompt({
38
+ systemPrompt: 'Extract invoice data',
39
+ userInput: 'Read this invoice',
40
+ userImages: [{url: 'data:image/png;base64,abc123', detail: 'high'}]
41
+ })
42
+
43
+ expect(r.output).toBe('{"name":"invoice"}')
44
+ expect(request.model).toBe('gpt-4o-mini')
45
+ expect(request.messages[1]).toEqual({
46
+ role: 'user',
47
+ content: [
48
+ {type: 'text', text: 'Read this invoice'},
49
+ {
50
+ type: 'image_url',
51
+ image_url: {
52
+ url: 'data:image/png;base64,abc123',
53
+ detail: 'high'
54
+ }
55
+ }
56
+ ]
57
+ })
58
+ })
59
+
60
+ test('OpenAi prompt keeps default model for text-only inputs', async () => {
61
+ let request: any
62
+
63
+ class MockedOpenAiProvider extends OpenAiProvider {
64
+ constructor() {
65
+ super('test-key', 'gpt-4.1-mini', 'gpt-4o-mini')
66
+ this._client = {
67
+ chat: {
68
+ completions: {
69
+ create: async (payload: any) => {
70
+ request = payload
71
+ return {
72
+ choices: [{message: {content: 'Buenos Aires'}}],
73
+ usage: {
74
+ total_tokens: 8,
75
+ prompt_tokens: 6,
76
+ completion_tokens: 2
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ const openAi = new MockedOpenAiProvider()
87
+
88
+ await openAi.prompt({
89
+ systemPrompt: 'You are an AI assistant.',
90
+ userInput: 'What is the capital of Argentina?'
91
+ })
92
+
93
+ expect(request.model).toBe('gpt-4.1-mini')
94
+ expect(request.messages[1]).toEqual({
95
+ role: 'user',
96
+ content: 'What is the capital of Argentina?'
97
+ })
98
+ })
99
+
9
100
  test('OpenAi Factory', () => {
10
101
  const openAi = OpenAiProviderFactory.instance()
11
102
  expect(openAi).toBeInstanceOf(OpenAiProvider)