@drax/ai-back 3.35.1 → 3.37.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/.env +4 -0
- package/dist/agents/ChatbotTaskService.js +143 -0
- package/dist/agents/ChatbotTaskTools.js +756 -0
- package/dist/agents/DraxAgent.js +4 -7
- package/dist/controllers/AIController.js +150 -0
- package/dist/controllers/DraxAgentController.js +29 -6
- package/dist/factory/DraxAgentFactory.js +15 -0
- package/dist/index.js +2 -1
- package/dist/interfaces/IAILog.js +1 -0
- package/dist/routes/ChatbotTaskRoutes.js +8 -0
- package/dist/routes/DraxAgentRoutes.js +2 -1
- package/dist/tools/ToolBuilder.js +243 -0
- package/dist/vectors/ChromaVector.js +65 -0
- package/package.json +3 -3
- package/src/agents/DraxAgent.ts +5 -11
- package/src/controllers/DraxAgentController.ts +34 -6
- package/src/factory/DraxAgentFactory.ts +22 -0
- package/src/index.ts +2 -0
- package/src/interfaces/IDraxAgent.ts +2 -0
- package/src/interfaces/IDraxAgentController.ts +2 -0
- package/src/routes/DraxAgentRoutes.ts +2 -1
- package/test/DraxAgent.test.ts +26 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/types/agents/ChatbotTaskService.d.ts +42 -0
- package/types/agents/ChatbotTaskService.d.ts.map +1 -0
- package/types/agents/ChatbotTaskTools.d.ts +54 -0
- package/types/agents/ChatbotTaskTools.d.ts.map +1 -0
- package/types/agents/DraxAgent.d.ts +3 -3
- package/types/agents/DraxAgent.d.ts.map +1 -1
- package/types/controllers/AIController.d.ts +25 -0
- package/types/controllers/AIController.d.ts.map +1 -0
- package/types/controllers/DraxAgentController.d.ts +6 -2
- package/types/controllers/DraxAgentController.d.ts.map +1 -1
- package/types/factory/DraxAgentFactory.d.ts +9 -0
- package/types/factory/DraxAgentFactory.d.ts.map +1 -0
- package/types/index.d.ts +3 -2
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/IAILog.d.ts +77 -0
- package/types/interfaces/IAILog.d.ts.map +1 -0
- package/types/interfaces/IDraxAgent.d.ts +2 -0
- package/types/interfaces/IDraxAgent.d.ts.map +1 -1
- package/types/interfaces/IDraxAgentController.d.ts +2 -0
- package/types/interfaces/IDraxAgentController.d.ts.map +1 -1
- package/types/routes/ChatbotTaskRoutes.d.ts +4 -0
- package/types/routes/ChatbotTaskRoutes.d.ts.map +1 -0
- package/types/routes/DraxAgentRoutes.d.ts.map +1 -1
- package/types/tools/ToolBuilder.d.ts +47 -0
- package/types/tools/ToolBuilder.d.ts.map +1 -0
- package/types/vectors/ChromaVector.d.ts +21 -0
- package/types/vectors/ChromaVector.d.ts.map +1 -0
package/src/agents/DraxAgent.ts
CHANGED
|
@@ -19,22 +19,15 @@ import AgentSessionServiceFactory from "../factory/services/AgentSessionServiceF
|
|
|
19
19
|
import type {AgentSessionService} from "../services/AgentSessionService.js";
|
|
20
20
|
|
|
21
21
|
class DraxAgent {
|
|
22
|
-
private static singleton?: DraxAgent;
|
|
23
|
-
|
|
24
22
|
protected sessions: Map<string, DraxAgentSession> = new Map();
|
|
25
23
|
protected config: DraxAgentConfig = {
|
|
26
24
|
systemPrompt: "Sos un asistente del sistema. Responde de forma clara, breve y util.",
|
|
27
25
|
};
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!DraxAgent.singleton) {
|
|
34
|
-
DraxAgent.singleton = new DraxAgent();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return DraxAgent.singleton;
|
|
27
|
+
constructor(
|
|
28
|
+
public readonly identifier: string = "default",
|
|
29
|
+
public readonly description: string = "",
|
|
30
|
+
) {
|
|
38
31
|
}
|
|
39
32
|
|
|
40
33
|
configure(config: DraxAgentConfig): this {
|
|
@@ -132,6 +125,7 @@ class DraxAgent {
|
|
|
132
125
|
});
|
|
133
126
|
|
|
134
127
|
return {
|
|
128
|
+
agentIdentifier: this.identifier,
|
|
135
129
|
sessionId: session.id,
|
|
136
130
|
message: assistantMessage,
|
|
137
131
|
navigationPath: navigationState.path,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {z} from "zod";
|
|
2
2
|
import {CommonController} from "@drax/common-back";
|
|
3
3
|
import {DraxAgent} from "../agents/DraxAgent.js";
|
|
4
|
+
import DraxAgentFactory from "../factory/DraxAgentFactory.js";
|
|
4
5
|
import {AgentPermissions} from "../permissions/AgentPermissions.js";
|
|
6
|
+
import type {DraxAgentControllerOptions} from "../interfaces/IDraxAgentController.js";
|
|
5
7
|
|
|
6
8
|
const PromptImageSchema = z.object({
|
|
7
9
|
url: z.string().min(1),
|
|
@@ -34,6 +36,7 @@ const PromptInputFileSchema = z.object({
|
|
|
34
36
|
});
|
|
35
37
|
|
|
36
38
|
const AgentSessionRequestSchema = z.object({
|
|
39
|
+
identifier: z.string().min(1).optional(),
|
|
37
40
|
sessionId: z.string().optional(),
|
|
38
41
|
userId: z.string().optional().nullable(),
|
|
39
42
|
tenantId: z.string().optional().nullable(),
|
|
@@ -55,13 +58,31 @@ const AgentMessageRequestSchema = AgentSessionRequestSchema.extend({
|
|
|
55
58
|
});
|
|
56
59
|
|
|
57
60
|
class DraxAgentController extends CommonController {
|
|
58
|
-
protected agent: DraxAgent;
|
|
59
61
|
protected permission: string | false;
|
|
62
|
+
protected defaultAgentIdentifier: string;
|
|
63
|
+
protected defaultAgentDescription: string;
|
|
60
64
|
|
|
61
|
-
constructor() {
|
|
65
|
+
constructor(options: DraxAgentControllerOptions = {}) {
|
|
62
66
|
super();
|
|
63
|
-
this.permission = AgentPermissions.Session;
|
|
64
|
-
this.
|
|
67
|
+
this.permission = options.permission ?? AgentPermissions.Session;
|
|
68
|
+
this.defaultAgentIdentifier = options.agentIdentifier ?? "default";
|
|
69
|
+
this.defaultAgentDescription = options.agentDescription ?? "";
|
|
70
|
+
DraxAgentFactory.instance(this.defaultAgentIdentifier, this.defaultAgentDescription);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async agents(request, reply) {
|
|
74
|
+
try {
|
|
75
|
+
this.assertAccess(request);
|
|
76
|
+
|
|
77
|
+
return reply.send({
|
|
78
|
+
agents: DraxAgentFactory.agents().map(agent => ({
|
|
79
|
+
identifier: agent.identifier,
|
|
80
|
+
description: agent.description,
|
|
81
|
+
})),
|
|
82
|
+
});
|
|
83
|
+
} catch (e: any) {
|
|
84
|
+
this.handleControllerError(e, reply);
|
|
85
|
+
}
|
|
65
86
|
}
|
|
66
87
|
|
|
67
88
|
async startSession(request, reply) {
|
|
@@ -69,13 +90,15 @@ class DraxAgentController extends CommonController {
|
|
|
69
90
|
this.assertAccess(request);
|
|
70
91
|
|
|
71
92
|
const input = AgentSessionRequestSchema.parse(request.body ?? {});
|
|
72
|
-
const
|
|
93
|
+
const agent = this.resolveAgent(input.identifier);
|
|
94
|
+
const session = await agent.startSession({
|
|
73
95
|
sessionId: input.sessionId,
|
|
74
96
|
userId: this.resolveUserId(request, input.userId),
|
|
75
97
|
tenantId: this.resolveTenantId(request, input.tenantId),
|
|
76
98
|
});
|
|
77
99
|
|
|
78
100
|
return reply.send({
|
|
101
|
+
agentIdentifier: agent.identifier,
|
|
79
102
|
sessionId: session.id,
|
|
80
103
|
createdAt: session.createdAt,
|
|
81
104
|
updatedAt: session.updatedAt,
|
|
@@ -90,7 +113,8 @@ class DraxAgentController extends CommonController {
|
|
|
90
113
|
this.assertAccess(request);
|
|
91
114
|
|
|
92
115
|
const input = AgentMessageRequestSchema.parse(request.body ?? {});
|
|
93
|
-
const
|
|
116
|
+
const agent = this.resolveAgent(input.identifier);
|
|
117
|
+
const response = await agent.sendMessage({
|
|
94
118
|
...input,
|
|
95
119
|
userId: this.resolveUserId(request, input.userId),
|
|
96
120
|
tenantId: this.resolveTenantId(request, input.tenantId),
|
|
@@ -104,6 +128,10 @@ class DraxAgentController extends CommonController {
|
|
|
104
128
|
}
|
|
105
129
|
}
|
|
106
130
|
|
|
131
|
+
protected resolveAgent(identifier?: string): DraxAgent {
|
|
132
|
+
return DraxAgentFactory.instance(identifier ?? this.defaultAgentIdentifier);
|
|
133
|
+
}
|
|
134
|
+
|
|
107
135
|
protected assertAccess(request: any) {
|
|
108
136
|
if (this.permission === false) {
|
|
109
137
|
return;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import DraxAgent from "../agents/DraxAgent.js";
|
|
2
|
+
|
|
3
|
+
class DraxAgentFactory {
|
|
4
|
+
private static singletons: Record<string, DraxAgent> = {};
|
|
5
|
+
|
|
6
|
+
public static instance(identifier: string = "default", description: string = ""): DraxAgent {
|
|
7
|
+
if (!DraxAgentFactory.singletons[identifier]) {
|
|
8
|
+
DraxAgentFactory.singletons[identifier] = new DraxAgent(identifier, description);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return DraxAgentFactory.singletons[identifier];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public static agents(): DraxAgent[] {
|
|
15
|
+
return Object.values(DraxAgentFactory.singletons);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default DraxAgentFactory;
|
|
20
|
+
export {
|
|
21
|
+
DraxAgentFactory,
|
|
22
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {OpenAiProviderFactory} from "./factory/OpenAiProviderFactory.js";
|
|
|
9
9
|
import {GoogleAiProviderFactory} from "./factory/GoogleAiProviderFactory.js";
|
|
10
10
|
import {OllamaAiProviderFactory} from "./factory/OllamaAiProviderFactory.js";
|
|
11
11
|
import {AiProviderFactory} from "./factory/AiProviderFactory.js";
|
|
12
|
+
import {DraxAgentFactory} from "./factory/DraxAgentFactory.js";
|
|
12
13
|
import AILogServiceFactory from "./factory/services/AILogServiceFactory.js";
|
|
13
14
|
import {OpenAiProvider} from "./providers/OpenAiProvider.js";
|
|
14
15
|
import {GoogleAiProvider} from "./providers/GoogleAiProvider.js";
|
|
@@ -112,6 +113,7 @@ export {
|
|
|
112
113
|
GoogleAiProviderFactory,
|
|
113
114
|
OllamaAiProviderFactory,
|
|
114
115
|
AiProviderFactory,
|
|
116
|
+
DraxAgentFactory,
|
|
115
117
|
AILogServiceFactory,
|
|
116
118
|
OpenAiProvider,
|
|
117
119
|
GoogleAiProvider,
|
|
@@ -40,6 +40,7 @@ interface DraxAgentConfig {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
interface DraxAgentSessionInput {
|
|
43
|
+
identifier?: string;
|
|
43
44
|
sessionId?: string;
|
|
44
45
|
userId?: string | null;
|
|
45
46
|
tenantId?: string | null;
|
|
@@ -69,6 +70,7 @@ interface DraxAgentMessageInput extends DraxAgentSessionInput {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
interface DraxAgentMessageOutput {
|
|
73
|
+
agentIdentifier: string;
|
|
72
74
|
sessionId: string;
|
|
73
75
|
message: string;
|
|
74
76
|
navigationPath?: string | null;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import DraxAgentController from "../controllers/DraxAgentController.js";
|
|
2
2
|
|
|
3
3
|
async function DraxAgentRoutes(fastify, options:any) {
|
|
4
|
-
const controller = new DraxAgentController();
|
|
4
|
+
const controller = new DraxAgentController(options);
|
|
5
5
|
const prefix = "/api/ai/agent";
|
|
6
6
|
|
|
7
|
+
fastify.get(`${prefix}`, (req, rep) => controller.agents(req, rep));
|
|
7
8
|
fastify.post(`${prefix}/session`, (req, rep) => controller.startSession(req, rep));
|
|
8
9
|
fastify.post(`${prefix}/message`, (req, rep) => controller.message(req, rep));
|
|
9
10
|
}
|
package/test/DraxAgent.test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {describe, expect, test} from "vitest";
|
|
2
2
|
import {DraxAgent} from "../src/agents/DraxAgent.js";
|
|
3
|
+
import {DraxAgentFactory} from "../src/factory/DraxAgentFactory.js";
|
|
3
4
|
import type {IAIProvider, IPromptParams, IPromptResponse, IPromptTool} from "../src/interfaces/IAIProvider.js";
|
|
4
5
|
|
|
5
6
|
class MockProvider implements IAIProvider {
|
|
@@ -23,9 +24,29 @@ class MockProvider implements IAIProvider {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
describe("DraxAgent", () => {
|
|
27
|
+
test("factory returns one agent instance per identifier", () => {
|
|
28
|
+
expect(DraxAgentFactory.instance()).toBe(DraxAgentFactory.instance("default"));
|
|
29
|
+
expect(DraxAgentFactory.instance("taskSpecialist")).toBe(DraxAgentFactory.instance("taskSpecialist"));
|
|
30
|
+
expect(DraxAgentFactory.instance("taskSpecialist")).not.toBe(DraxAgentFactory.instance("default"));
|
|
31
|
+
expect(DraxAgentFactory.agents()).toContain(DraxAgentFactory.instance("taskSpecialist"));
|
|
32
|
+
expect(new DraxAgent()).not.toBe(new DraxAgent());
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("stores agent identifier and description", () => {
|
|
36
|
+
const defaultAgent = new DraxAgent();
|
|
37
|
+
const specialist = DraxAgentFactory.instance("taskSpecialistWithDescription", "Resuelve tareas especificas");
|
|
38
|
+
|
|
39
|
+
expect(defaultAgent.identifier).toBe("default");
|
|
40
|
+
expect(defaultAgent.description).toBe("");
|
|
41
|
+
expect(specialist.identifier).toBe("taskSpecialistWithDescription");
|
|
42
|
+
expect(specialist.description).toBe("Resuelve tareas especificas");
|
|
43
|
+
expect(DraxAgentFactory.instance("taskSpecialistWithDescription", "Otra descripcion")).toBe(specialist);
|
|
44
|
+
expect(DraxAgentFactory.instance("taskSpecialistWithDescription").description).toBe("Resuelve tareas especificas");
|
|
45
|
+
});
|
|
46
|
+
|
|
26
47
|
test("creates a session and sends messages through the injected provider", async () => {
|
|
27
48
|
const provider = new MockProvider();
|
|
28
|
-
const agent = DraxAgent
|
|
49
|
+
const agent = new DraxAgent().configure({
|
|
29
50
|
provider,
|
|
30
51
|
systemPrompt: "Sos un asistente.",
|
|
31
52
|
sessionService: false,
|
|
@@ -74,7 +95,7 @@ describe("DraxAgent", () => {
|
|
|
74
95
|
},
|
|
75
96
|
};
|
|
76
97
|
|
|
77
|
-
const agent = DraxAgent
|
|
98
|
+
const agent = new DraxAgent().configure({
|
|
78
99
|
provider,
|
|
79
100
|
systemPrompt: "Prompt base.",
|
|
80
101
|
sessionService: false,
|
|
@@ -99,7 +120,7 @@ describe("DraxAgent", () => {
|
|
|
99
120
|
|
|
100
121
|
test("uses previous session messages as history", async () => {
|
|
101
122
|
const provider = new MockProvider();
|
|
102
|
-
const agent = DraxAgent
|
|
123
|
+
const agent = new DraxAgent().configure({
|
|
103
124
|
provider,
|
|
104
125
|
systemPrompt: "Sos un asistente.",
|
|
105
126
|
sessionService: false,
|
|
@@ -125,7 +146,7 @@ describe("DraxAgent", () => {
|
|
|
125
146
|
|
|
126
147
|
test("returns a navigation path from tool execution metadata", async () => {
|
|
127
148
|
const provider = new MockProvider();
|
|
128
|
-
const agent = DraxAgent
|
|
149
|
+
const agent = new DraxAgent().configure({
|
|
129
150
|
provider,
|
|
130
151
|
systemPrompt: "Sos un asistente.",
|
|
131
152
|
sessionService: false,
|
|
@@ -178,7 +199,7 @@ describe("DraxAgent", () => {
|
|
|
178
199
|
}),
|
|
179
200
|
} as any;
|
|
180
201
|
|
|
181
|
-
const agent = DraxAgent
|
|
202
|
+
const agent = new DraxAgent().configure({
|
|
182
203
|
provider,
|
|
183
204
|
systemPrompt: "Sos un asistente.",
|
|
184
205
|
sessionService,
|