@drax/ai-back 3.32.0 → 3.35.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/dist/config/GoogleAiConfig.js +8 -0
- package/dist/config/OllamaAiConfig.js +9 -0
- package/dist/factory/AiProviderFactory.js +12 -3
- package/dist/factory/GoogleAiProviderFactory.js +14 -0
- package/dist/factory/OllamaAiProviderFactory.js +14 -0
- package/dist/index.js +7 -1
- package/dist/providers/GoogleAiProvider.js +367 -0
- package/dist/providers/OllamaAiProvider.js +342 -0
- package/dist/tools/BuilderTool.js +9 -0
- package/package.json +4 -2
- package/src/config/GoogleAiConfig.ts +13 -0
- package/src/config/OllamaAiConfig.ts +14 -0
- package/src/factory/AiProviderFactory.ts +12 -5
- package/src/factory/GoogleAiProviderFactory.ts +26 -0
- package/src/factory/OllamaAiProviderFactory.ts +27 -0
- package/src/index.ts +12 -0
- package/src/providers/GoogleAiProvider.ts +489 -0
- package/src/providers/OllamaAiProvider.ts +469 -0
- package/src/tools/BuilderTool.ts +12 -0
- package/test/GoogleAiProvider.test.ts +211 -0
- package/test/ToolBuilder.test.ts +48 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/config/GoogleAiConfig.d.ts +8 -0
- package/types/config/GoogleAiConfig.d.ts.map +1 -0
- package/types/config/OllamaAiConfig.d.ts +9 -0
- package/types/config/OllamaAiConfig.d.ts.map +1 -0
- package/types/factory/AiProviderFactory.d.ts.map +1 -1
- package/types/factory/GoogleAiProviderFactory.d.ts +8 -0
- package/types/factory/GoogleAiProviderFactory.d.ts.map +1 -0
- package/types/factory/OllamaAiProviderFactory.d.ts +8 -0
- package/types/factory/OllamaAiProviderFactory.d.ts.map +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/providers/GoogleAiProvider.d.ts +63 -0
- package/types/providers/GoogleAiProvider.d.ts.map +1 -0
- package/types/providers/OllamaAiProvider.d.ts +78 -0
- package/types/providers/OllamaAiProvider.d.ts.map +1 -0
- package/types/tools/BuilderTool.d.ts.map +1 -1
- package/.env +0 -4
- package/dist/agents/ChatbotTaskService.js +0 -143
- package/dist/agents/ChatbotTaskTools.js +0 -756
- package/dist/controllers/AIController.js +0 -150
- package/dist/interfaces/IAILog.js +0 -1
- package/dist/routes/ChatbotTaskRoutes.js +0 -8
- package/dist/tools/ToolBuilder.js +0 -243
- package/dist/vectors/ChromaVector.js +0 -65
- package/types/agents/ChatbotTaskService.d.ts +0 -42
- package/types/agents/ChatbotTaskService.d.ts.map +0 -1
- package/types/agents/ChatbotTaskTools.d.ts +0 -54
- package/types/agents/ChatbotTaskTools.d.ts.map +0 -1
- package/types/controllers/AIController.d.ts +0 -25
- package/types/controllers/AIController.d.ts.map +0 -1
- package/types/interfaces/IAILog.d.ts +0 -77
- package/types/interfaces/IAILog.d.ts.map +0 -1
- package/types/routes/ChatbotTaskRoutes.d.ts +0 -4
- package/types/routes/ChatbotTaskRoutes.d.ts.map +0 -1
- package/types/tools/ToolBuilder.d.ts +0 -47
- package/types/tools/ToolBuilder.d.ts.map +0 -1
- package/types/vectors/ChromaVector.d.ts +0 -21
- package/types/vectors/ChromaVector.d.ts.map +0 -1
|
@@ -1,756 +0,0 @@
|
|
|
1
|
-
import TaskServiceFactory from "../factory/services/TaskServiceFactory.js";
|
|
2
|
-
import TaskSourceServiceFactory from "../factory/services/TaskSourceServiceFactory.js";
|
|
3
|
-
import TaskStatusServiceFactory from "../factory/services/TaskStatusServiceFactory.js";
|
|
4
|
-
import TaskTypeServiceFactory from "../factory/services/TaskTypeServiceFactory.js";
|
|
5
|
-
import PriorityServiceFactory from "../factory/services/PriorityServiceFactory.js";
|
|
6
|
-
import GoalServiceFactory from "../factory/services/GoalServiceFactory.js";
|
|
7
|
-
import ProjectServiceFactory from "../factory/services/ProjectServiceFactory.js";
|
|
8
|
-
import ContactServiceFactory from "../factory/services/ContactServiceFactory.js";
|
|
9
|
-
import ClientServiceFactory from "../factory/services/ClientServiceFactory.js";
|
|
10
|
-
import CompanyServiceFactory from "../factory/services/CompanyServiceFactory.js";
|
|
11
|
-
import ContactTypeServiceFactory from "../factory/services/ContactTypeServiceFactory.js";
|
|
12
|
-
import CompanyTypeServiceFactory from "../factory/services/CompanyTypeServiceFactory.js";
|
|
13
|
-
import ClientTypeServiceFactory from "../factory/services/ClientTypeServiceFactory.js";
|
|
14
|
-
const TASK_GROUP_BY_FIELDS = [
|
|
15
|
-
"source",
|
|
16
|
-
"type",
|
|
17
|
-
"status",
|
|
18
|
-
"priority",
|
|
19
|
-
"project",
|
|
20
|
-
"client",
|
|
21
|
-
"dueDate",
|
|
22
|
-
"scheduledDate",
|
|
23
|
-
"completedAt",
|
|
24
|
-
"createdAt",
|
|
25
|
-
"updatedAt",
|
|
26
|
-
"archivedAt",
|
|
27
|
-
"valueScore",
|
|
28
|
-
"motivationScore",
|
|
29
|
-
"effortScore",
|
|
30
|
-
"urgencyScore",
|
|
31
|
-
"estimatedMinutes",
|
|
32
|
-
"spentMinutes",
|
|
33
|
-
];
|
|
34
|
-
const TASK_GROUP_BY_DATE_FORMATS = ["year", "month", "day", "hour", "minute", "second"];
|
|
35
|
-
class ChatbotTaskTools {
|
|
36
|
-
static build(context) {
|
|
37
|
-
return [
|
|
38
|
-
this.registerTaskTool(context),
|
|
39
|
-
this.searchTasksTool(context),
|
|
40
|
-
this.findTaskByIdTool(context),
|
|
41
|
-
this.groupTasksTool(context),
|
|
42
|
-
this.updateTaskPartialTool(context),
|
|
43
|
-
this.listTaskOptionsTool(),
|
|
44
|
-
this.createTaskOptionTool("source"),
|
|
45
|
-
this.createTaskOptionTool("status"),
|
|
46
|
-
this.createTaskOptionTool("type"),
|
|
47
|
-
this.createTaskOptionTool("priority"),
|
|
48
|
-
...this.buildEntityTools(context),
|
|
49
|
-
];
|
|
50
|
-
}
|
|
51
|
-
static async fetchTaskOptionNames() {
|
|
52
|
-
const [sources, statuses, types, priorities] = await Promise.all([
|
|
53
|
-
TaskSourceServiceFactory.instance.fetchAll(),
|
|
54
|
-
TaskStatusServiceFactory.instance.fetchAll(),
|
|
55
|
-
TaskTypeServiceFactory.instance.fetchAll(),
|
|
56
|
-
PriorityServiceFactory.instance.fetchAll(),
|
|
57
|
-
]);
|
|
58
|
-
return {
|
|
59
|
-
sources: this.serializeOptionNames(sources),
|
|
60
|
-
statuses: this.serializeOptionNames(statuses),
|
|
61
|
-
types: this.serializeOptionNames(types),
|
|
62
|
-
priorities: this.serializeOptionNames(priorities),
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
static async fetchLifeOpsOptionNames() {
|
|
66
|
-
const [task, contactTypes, companyTypes, clientTypes] = await Promise.all([
|
|
67
|
-
this.fetchTaskOptionNames(),
|
|
68
|
-
ContactTypeServiceFactory.instance.fetchAll(),
|
|
69
|
-
CompanyTypeServiceFactory.instance.fetchAll(),
|
|
70
|
-
ClientTypeServiceFactory.instance.fetchAll(),
|
|
71
|
-
]);
|
|
72
|
-
return {
|
|
73
|
-
task,
|
|
74
|
-
entityTypes: {
|
|
75
|
-
contactTypes: this.serializeOptionNames(contactTypes),
|
|
76
|
-
companyTypes: this.serializeOptionNames(companyTypes),
|
|
77
|
-
clientTypes: this.serializeOptionNames(clientTypes),
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
static taskUserFilter(userId) {
|
|
82
|
-
return { field: "user", operator: "eq", value: userId };
|
|
83
|
-
}
|
|
84
|
-
static compactObject(data) {
|
|
85
|
-
return Object.fromEntries(Object.entries(data).filter(([, value]) => value !== undefined));
|
|
86
|
-
}
|
|
87
|
-
static serializeOptionNames(options) {
|
|
88
|
-
return options
|
|
89
|
-
.map(option => option?.name)
|
|
90
|
-
.filter((name) => typeof name === "string" && name.trim().length > 0);
|
|
91
|
-
}
|
|
92
|
-
static serializeTask(task) {
|
|
93
|
-
if (!task) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
_id: task._id,
|
|
98
|
-
title: task.title,
|
|
99
|
-
description: task.description,
|
|
100
|
-
source: task.source,
|
|
101
|
-
type: task.type,
|
|
102
|
-
status: task.status,
|
|
103
|
-
priority: task.priority,
|
|
104
|
-
dueDate: task.dueDate,
|
|
105
|
-
scheduledDate: task.scheduledDate,
|
|
106
|
-
completedAt: task.completedAt,
|
|
107
|
-
estimatedMinutes: task.estimatedMinutes,
|
|
108
|
-
spentMinutes: task.spentMinutes,
|
|
109
|
-
nextAction: task.nextAction,
|
|
110
|
-
tags: task.tags,
|
|
111
|
-
notes: task.notes,
|
|
112
|
-
createdAt: task.createdAt,
|
|
113
|
-
updatedAt: task.updatedAt,
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
static entityUserFilter(userId) {
|
|
117
|
-
return { field: "user", operator: "eq", value: userId };
|
|
118
|
-
}
|
|
119
|
-
static serializeGoal(goal) {
|
|
120
|
-
return this.serializeFields(goal, [
|
|
121
|
-
"_id", "name", "description", "status", "priority", "valueScore", "motivationScore",
|
|
122
|
-
"effortScore", "timeHorizon", "targetDate", "completedAt", "archivedAt",
|
|
123
|
-
"progressPercent", "successCriteria", "purpose", "constraints", "tags", "createdAt", "updatedAt",
|
|
124
|
-
]);
|
|
125
|
-
}
|
|
126
|
-
static serializeProject(project) {
|
|
127
|
-
return this.serializeFields(project, [
|
|
128
|
-
"_id", "name", "description", "status", "priority", "goals", "client", "valueScore",
|
|
129
|
-
"motivationScore", "effortScore", "priorityScore", "startDate", "targetDate", "completedAt",
|
|
130
|
-
"progressPercent", "tags", "archivedAt", "createdAt", "updatedAt",
|
|
131
|
-
]);
|
|
132
|
-
}
|
|
133
|
-
static serializeContact(contact) {
|
|
134
|
-
return this.serializeFields(contact, [
|
|
135
|
-
"_id", "firstName", "lastName", "displayName", "type", "status", "priority", "client",
|
|
136
|
-
"company", "jobTitle", "department", "emails", "phones", "valueScore", "relationshipScore",
|
|
137
|
-
"tags", "notes", "archivedAt", "createdAt", "updatedAt",
|
|
138
|
-
]);
|
|
139
|
-
}
|
|
140
|
-
static serializeClient(client) {
|
|
141
|
-
return this.serializeFields(client, [
|
|
142
|
-
"_id", "name", "description", "type", "status", "priority", "valueScore", "relationshipScore",
|
|
143
|
-
"priorityScore", "website", "emailDomains", "company", "mainContact", "redmineProjectIds",
|
|
144
|
-
"tags", "notes", "archivedAt", "createdAt", "updatedAt",
|
|
145
|
-
]);
|
|
146
|
-
}
|
|
147
|
-
static serializeCompany(company) {
|
|
148
|
-
return this.serializeFields(company, [
|
|
149
|
-
"_id", "name", "legalName", "taxIdType", "taxIdNumber", "description", "type", "status",
|
|
150
|
-
"website", "emailDomains", "tags", "notes", "archivedAt", "createdAt", "updatedAt",
|
|
151
|
-
]);
|
|
152
|
-
}
|
|
153
|
-
static serializeFields(entity, fields) {
|
|
154
|
-
if (!entity) {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
return Object.fromEntries(fields.map(field => [field, entity[field]]));
|
|
158
|
-
}
|
|
159
|
-
static async findUserTaskById(id, userId) {
|
|
160
|
-
const taskService = TaskServiceFactory.instance;
|
|
161
|
-
return await taskService.findOneBy("_id", id, [this.taskUserFilter(userId)]);
|
|
162
|
-
}
|
|
163
|
-
static async findUserEntityById(config, id, userId) {
|
|
164
|
-
return await config.serviceFactory.instance.findOneBy("_id", id, [this.entityUserFilter(userId)]);
|
|
165
|
-
}
|
|
166
|
-
static buildEntityTools(context) {
|
|
167
|
-
return this.entityConfigs().flatMap(config => [
|
|
168
|
-
this.createEntityTool(context, config),
|
|
169
|
-
this.searchEntitiesTool(context, config),
|
|
170
|
-
this.findEntityByIdTool(context, config),
|
|
171
|
-
this.updateEntityPartialTool(context, config),
|
|
172
|
-
]);
|
|
173
|
-
}
|
|
174
|
-
static entityConfigs() {
|
|
175
|
-
const scoreProperty = { type: "number", minimum: 1, maximum: 10 };
|
|
176
|
-
const nullableDateProperty = { type: ["string", "null"], description: "Fecha ISO 8601 o null para limpiar." };
|
|
177
|
-
const tagArrayProperty = { type: "array", items: { type: "string" } };
|
|
178
|
-
return [
|
|
179
|
-
{
|
|
180
|
-
kind: "goal",
|
|
181
|
-
plural: "goals",
|
|
182
|
-
serviceFactory: GoalServiceFactory,
|
|
183
|
-
requiredCreateFields: ["name"],
|
|
184
|
-
serialize: (entity) => this.serializeGoal(entity),
|
|
185
|
-
createProperties: {
|
|
186
|
-
name: { type: "string", description: "Nombre breve del objetivo." },
|
|
187
|
-
description: { type: "string" },
|
|
188
|
-
status: { type: "string", enum: ["draft", "active", "paused", "completed", "cancelled", "archived"] },
|
|
189
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
190
|
-
valueScore: scoreProperty,
|
|
191
|
-
motivationScore: scoreProperty,
|
|
192
|
-
effortScore: scoreProperty,
|
|
193
|
-
timeHorizon: { type: "string", enum: ["short_term", "medium_term", "long_term"] },
|
|
194
|
-
targetDate: { type: "string", description: "Fecha objetivo en formato ISO 8601." },
|
|
195
|
-
completedAt: { type: "string", description: "Fecha de completado en formato ISO 8601." },
|
|
196
|
-
progressPercent: { type: "number", minimum: 0, maximum: 100 },
|
|
197
|
-
successCriteria: { type: "string" },
|
|
198
|
-
purpose: { type: "string" },
|
|
199
|
-
constraints: tagArrayProperty,
|
|
200
|
-
tags: tagArrayProperty,
|
|
201
|
-
},
|
|
202
|
-
updateProperties: {
|
|
203
|
-
name: { type: "string" },
|
|
204
|
-
description: { type: "string" },
|
|
205
|
-
status: { type: "string", enum: ["draft", "active", "paused", "completed", "cancelled", "archived"] },
|
|
206
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
207
|
-
valueScore: scoreProperty,
|
|
208
|
-
motivationScore: scoreProperty,
|
|
209
|
-
effortScore: scoreProperty,
|
|
210
|
-
timeHorizon: { type: "string", enum: ["short_term", "medium_term", "long_term"] },
|
|
211
|
-
targetDate: nullableDateProperty,
|
|
212
|
-
completedAt: nullableDateProperty,
|
|
213
|
-
archivedAt: nullableDateProperty,
|
|
214
|
-
progressPercent: { type: "number", minimum: 0, maximum: 100 },
|
|
215
|
-
successCriteria: { type: "string" },
|
|
216
|
-
purpose: { type: "string" },
|
|
217
|
-
constraints: tagArrayProperty,
|
|
218
|
-
tags: tagArrayProperty,
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
kind: "project",
|
|
223
|
-
plural: "projects",
|
|
224
|
-
serviceFactory: ProjectServiceFactory,
|
|
225
|
-
requiredCreateFields: ["name"],
|
|
226
|
-
serialize: (entity) => this.serializeProject(entity),
|
|
227
|
-
createProperties: {
|
|
228
|
-
name: { type: "string", description: "Nombre breve del proyecto." },
|
|
229
|
-
description: { type: "string" },
|
|
230
|
-
status: { type: "string", enum: ["idea", "active", "paused", "completed", "cancelled", "archived"] },
|
|
231
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
232
|
-
goals: { type: "array", items: { type: "string" }, description: "IDs de objetivos relacionados." },
|
|
233
|
-
client: { type: "string", description: "ID del cliente relacionado." },
|
|
234
|
-
valueScore: scoreProperty,
|
|
235
|
-
motivationScore: scoreProperty,
|
|
236
|
-
effortScore: scoreProperty,
|
|
237
|
-
priorityScore: { type: "number" },
|
|
238
|
-
startDate: { type: "string", description: "Fecha de inicio en formato ISO 8601." },
|
|
239
|
-
targetDate: { type: "string", description: "Fecha objetivo en formato ISO 8601." },
|
|
240
|
-
completedAt: { type: "string", description: "Fecha de completado en formato ISO 8601." },
|
|
241
|
-
progressPercent: { type: "number", minimum: 0, maximum: 100 },
|
|
242
|
-
tags: tagArrayProperty,
|
|
243
|
-
},
|
|
244
|
-
updateProperties: {
|
|
245
|
-
name: { type: "string" },
|
|
246
|
-
description: { type: "string" },
|
|
247
|
-
status: { type: "string", enum: ["idea", "active", "paused", "completed", "cancelled", "archived"] },
|
|
248
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
249
|
-
goals: { type: "array", items: { type: "string" } },
|
|
250
|
-
client: { type: ["string", "null"], description: "ID del cliente o null para limpiar." },
|
|
251
|
-
valueScore: { type: ["number", "null"] },
|
|
252
|
-
motivationScore: { type: ["number", "null"] },
|
|
253
|
-
effortScore: { type: ["number", "null"] },
|
|
254
|
-
priorityScore: { type: ["number", "null"] },
|
|
255
|
-
startDate: nullableDateProperty,
|
|
256
|
-
targetDate: nullableDateProperty,
|
|
257
|
-
completedAt: nullableDateProperty,
|
|
258
|
-
archivedAt: nullableDateProperty,
|
|
259
|
-
progressPercent: { type: ["number", "null"], minimum: 0, maximum: 100 },
|
|
260
|
-
tags: tagArrayProperty,
|
|
261
|
-
},
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
kind: "contact",
|
|
265
|
-
plural: "contacts",
|
|
266
|
-
serviceFactory: ContactServiceFactory,
|
|
267
|
-
requiredCreateFields: ["firstName", "displayName", "company"],
|
|
268
|
-
serialize: (entity) => this.serializeContact(entity),
|
|
269
|
-
createProperties: {
|
|
270
|
-
firstName: { type: "string" },
|
|
271
|
-
lastName: { type: "string" },
|
|
272
|
-
displayName: { type: "string" },
|
|
273
|
-
type: { type: "string", description: "Nombre de ContactType si el usuario eligio una opcion existente." },
|
|
274
|
-
status: { type: "string", enum: ["active", "inactive", "archived"] },
|
|
275
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
276
|
-
client: { type: "string", description: "ID del cliente relacionado." },
|
|
277
|
-
company: { type: "string", description: "ID de la empresa relacionada." },
|
|
278
|
-
jobTitle: { type: "string" },
|
|
279
|
-
department: { type: "string" },
|
|
280
|
-
emails: tagArrayProperty,
|
|
281
|
-
phones: tagArrayProperty,
|
|
282
|
-
valueScore: scoreProperty,
|
|
283
|
-
relationshipScore: scoreProperty,
|
|
284
|
-
tags: tagArrayProperty,
|
|
285
|
-
notes: { type: "string" },
|
|
286
|
-
},
|
|
287
|
-
updateProperties: {
|
|
288
|
-
firstName: { type: "string" },
|
|
289
|
-
lastName: { type: "string" },
|
|
290
|
-
displayName: { type: "string" },
|
|
291
|
-
type: { type: "string", description: "Nombre de ContactType." },
|
|
292
|
-
status: { type: "string", enum: ["active", "inactive", "archived"] },
|
|
293
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
294
|
-
client: { type: ["string", "null"], description: "ID del cliente o null para limpiar." },
|
|
295
|
-
company: { type: "string", description: "ID de la empresa relacionada." },
|
|
296
|
-
jobTitle: { type: "string" },
|
|
297
|
-
department: { type: "string" },
|
|
298
|
-
emails: tagArrayProperty,
|
|
299
|
-
phones: tagArrayProperty,
|
|
300
|
-
valueScore: { type: ["number", "null"] },
|
|
301
|
-
relationshipScore: { type: ["number", "null"] },
|
|
302
|
-
tags: tagArrayProperty,
|
|
303
|
-
notes: { type: "string" },
|
|
304
|
-
archivedAt: nullableDateProperty,
|
|
305
|
-
},
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
kind: "client",
|
|
309
|
-
plural: "clients",
|
|
310
|
-
serviceFactory: ClientServiceFactory,
|
|
311
|
-
requiredCreateFields: ["name", "company"],
|
|
312
|
-
serialize: (entity) => this.serializeClient(entity),
|
|
313
|
-
createProperties: {
|
|
314
|
-
name: { type: "string" },
|
|
315
|
-
description: { type: "string" },
|
|
316
|
-
type: { type: "string", description: "Nombre de ClientType si el usuario eligio una opcion existente." },
|
|
317
|
-
status: { type: "string", enum: ["active", "inactive", "prospect", "paused", "archived"] },
|
|
318
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
319
|
-
valueScore: scoreProperty,
|
|
320
|
-
relationshipScore: scoreProperty,
|
|
321
|
-
priorityScore: { type: "number" },
|
|
322
|
-
website: { type: "string" },
|
|
323
|
-
emailDomains: tagArrayProperty,
|
|
324
|
-
company: { type: "string", description: "ID de la empresa relacionada." },
|
|
325
|
-
mainContact: { type: "string", description: "ID del contacto principal." },
|
|
326
|
-
redmineProjectIds: tagArrayProperty,
|
|
327
|
-
tags: tagArrayProperty,
|
|
328
|
-
notes: { type: "string" },
|
|
329
|
-
},
|
|
330
|
-
updateProperties: {
|
|
331
|
-
name: { type: "string" },
|
|
332
|
-
description: { type: "string" },
|
|
333
|
-
type: { type: "string", description: "Nombre de ClientType." },
|
|
334
|
-
status: { type: "string", enum: ["active", "inactive", "prospect", "paused", "archived"] },
|
|
335
|
-
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
336
|
-
valueScore: { type: ["number", "null"] },
|
|
337
|
-
relationshipScore: { type: ["number", "null"] },
|
|
338
|
-
priorityScore: { type: ["number", "null"] },
|
|
339
|
-
website: { type: "string" },
|
|
340
|
-
emailDomains: tagArrayProperty,
|
|
341
|
-
company: { type: "string", description: "ID de la empresa relacionada." },
|
|
342
|
-
mainContact: { type: ["string", "null"], description: "ID del contacto principal o null para limpiar." },
|
|
343
|
-
redmineProjectIds: tagArrayProperty,
|
|
344
|
-
tags: tagArrayProperty,
|
|
345
|
-
notes: { type: "string" },
|
|
346
|
-
archivedAt: nullableDateProperty,
|
|
347
|
-
},
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
kind: "company",
|
|
351
|
-
plural: "companies",
|
|
352
|
-
serviceFactory: CompanyServiceFactory,
|
|
353
|
-
requiredCreateFields: ["name"],
|
|
354
|
-
serialize: (entity) => this.serializeCompany(entity),
|
|
355
|
-
createProperties: {
|
|
356
|
-
name: { type: "string" },
|
|
357
|
-
legalName: { type: "string" },
|
|
358
|
-
taxIdType: { type: "string" },
|
|
359
|
-
taxIdNumber: { type: "string" },
|
|
360
|
-
description: { type: "string" },
|
|
361
|
-
type: { type: "string", description: "Nombre de CompanyType si el usuario eligio una opcion existente." },
|
|
362
|
-
status: { type: "string", enum: ["active", "inactive", "archived"] },
|
|
363
|
-
website: { type: "string" },
|
|
364
|
-
emailDomains: tagArrayProperty,
|
|
365
|
-
tags: tagArrayProperty,
|
|
366
|
-
notes: { type: "string" },
|
|
367
|
-
},
|
|
368
|
-
updateProperties: {
|
|
369
|
-
name: { type: "string" },
|
|
370
|
-
legalName: { type: "string" },
|
|
371
|
-
taxIdType: { type: "string" },
|
|
372
|
-
taxIdNumber: { type: "string" },
|
|
373
|
-
description: { type: "string" },
|
|
374
|
-
type: { type: "string", description: "Nombre de CompanyType." },
|
|
375
|
-
status: { type: "string", enum: ["active", "inactive", "archived"] },
|
|
376
|
-
website: { type: "string" },
|
|
377
|
-
emailDomains: tagArrayProperty,
|
|
378
|
-
tags: tagArrayProperty,
|
|
379
|
-
notes: { type: "string" },
|
|
380
|
-
archivedAt: nullableDateProperty,
|
|
381
|
-
},
|
|
382
|
-
},
|
|
383
|
-
];
|
|
384
|
-
}
|
|
385
|
-
static createEntityTool(context, config) {
|
|
386
|
-
return {
|
|
387
|
-
name: `create_${config.kind}`,
|
|
388
|
-
description: `Crea un ${config.kind} para el usuario autenticado.`,
|
|
389
|
-
parameters: {
|
|
390
|
-
type: "object",
|
|
391
|
-
properties: config.createProperties,
|
|
392
|
-
required: config.requiredCreateFields,
|
|
393
|
-
additionalProperties: false,
|
|
394
|
-
},
|
|
395
|
-
execute: async (args) => {
|
|
396
|
-
const entity = await config.serviceFactory.instance.create(this.compactObject({
|
|
397
|
-
...args,
|
|
398
|
-
user: context.userId,
|
|
399
|
-
}));
|
|
400
|
-
return config.serialize(entity);
|
|
401
|
-
},
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
static searchEntitiesTool(context, config) {
|
|
405
|
-
return {
|
|
406
|
-
name: `search_${config.plural}`,
|
|
407
|
-
description: `Busca ${config.plural} del usuario por texto. Opcionalmente filtra por status y fecha de creacion.`,
|
|
408
|
-
parameters: {
|
|
409
|
-
type: "object",
|
|
410
|
-
properties: {
|
|
411
|
-
query: { type: "string", description: "Texto de busqueda." },
|
|
412
|
-
limit: { type: "number", minimum: 1, maximum: 50, default: 10 },
|
|
413
|
-
status: { type: "string", description: "Status exacto para filtrar." },
|
|
414
|
-
createdAtFrom: { type: "string", description: "Fecha ISO desde la cual filtrar createdAt inclusive." },
|
|
415
|
-
createdAtTo: { type: "string", description: "Fecha ISO hasta la cual filtrar createdAt inclusive." },
|
|
416
|
-
},
|
|
417
|
-
required: ["query"],
|
|
418
|
-
additionalProperties: false,
|
|
419
|
-
},
|
|
420
|
-
execute: async (args) => {
|
|
421
|
-
const filters = [this.entityUserFilter(context.userId)];
|
|
422
|
-
const limit = Math.min(Math.max(Number(args.limit ?? 10), 1), 50);
|
|
423
|
-
if (args.status) {
|
|
424
|
-
filters.push({ field: "status", operator: "eq", value: args.status });
|
|
425
|
-
}
|
|
426
|
-
if (args.createdAtFrom) {
|
|
427
|
-
filters.push({ field: "createdAt", operator: "gte", value: args.createdAtFrom });
|
|
428
|
-
}
|
|
429
|
-
if (args.createdAtTo) {
|
|
430
|
-
filters.push({ field: "createdAt", operator: "lte", value: args.createdAtTo });
|
|
431
|
-
}
|
|
432
|
-
const entities = await config.serviceFactory.instance.search(args.query, limit, filters);
|
|
433
|
-
return entities.map((entity) => config.serialize(entity));
|
|
434
|
-
},
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
static findEntityByIdTool(context, config) {
|
|
438
|
-
return {
|
|
439
|
-
name: `find_${config.kind}_by_id`,
|
|
440
|
-
description: `Busca un ${config.kind} especifico por ID, siempre limitado al usuario autenticado.`,
|
|
441
|
-
parameters: {
|
|
442
|
-
type: "object",
|
|
443
|
-
properties: {
|
|
444
|
-
id: { type: "string", description: `ID exacto de ${config.kind}.` },
|
|
445
|
-
},
|
|
446
|
-
required: ["id"],
|
|
447
|
-
additionalProperties: false,
|
|
448
|
-
},
|
|
449
|
-
execute: async (args) => {
|
|
450
|
-
const entity = await this.findUserEntityById(config, args.id, context.userId);
|
|
451
|
-
return config.serialize(entity);
|
|
452
|
-
},
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
static updateEntityPartialTool(context, config) {
|
|
456
|
-
return {
|
|
457
|
-
name: `update_${config.kind}_partial`,
|
|
458
|
-
description: `Actualiza parcialmente un ${config.kind} del usuario autenticado. Usa esta tool para cambiar solo algunos campos particulares de una entidad existente.`,
|
|
459
|
-
parameters: {
|
|
460
|
-
type: "object",
|
|
461
|
-
properties: {
|
|
462
|
-
id: { type: "string", description: `ID exacto de ${config.kind} a modificar.` },
|
|
463
|
-
...config.updateProperties,
|
|
464
|
-
},
|
|
465
|
-
required: ["id"],
|
|
466
|
-
additionalProperties: false,
|
|
467
|
-
},
|
|
468
|
-
execute: async (args) => {
|
|
469
|
-
const existingEntity = await this.findUserEntityById(config, args.id, context.userId);
|
|
470
|
-
if (!existingEntity) {
|
|
471
|
-
return { updated: false, reason: `${config.kind}_not_found` };
|
|
472
|
-
}
|
|
473
|
-
const { _id, id, user, ...input } = args;
|
|
474
|
-
const updateData = this.compactObject(input);
|
|
475
|
-
const updatedEntity = await config.serviceFactory.instance.updatePartial(args.id, updateData);
|
|
476
|
-
return {
|
|
477
|
-
updated: true,
|
|
478
|
-
[config.kind]: config.serialize(updatedEntity),
|
|
479
|
-
};
|
|
480
|
-
},
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
static registerTaskTool(context) {
|
|
484
|
-
return {
|
|
485
|
-
name: "register_task",
|
|
486
|
-
description: "Registra una tarea para el usuario autenticado cuando el usuario pide crear, guardar o registrar una tarea.",
|
|
487
|
-
parameters: {
|
|
488
|
-
type: "object",
|
|
489
|
-
properties: {
|
|
490
|
-
title: { type: "string", description: "Titulo breve y accionable de la tarea." },
|
|
491
|
-
description: { type: "string", description: "Descripcion o contexto adicional." },
|
|
492
|
-
source: { type: "string", description: "Nombre de TaskSource si el usuario eligio una opcion existente." },
|
|
493
|
-
type: { type: "string", description: "Nombre de TaskType si el usuario eligio una opcion existente." },
|
|
494
|
-
status: { type: "string", description: "Nombre de TaskStatus si el usuario eligio una opcion existente." },
|
|
495
|
-
priority: { type: "string", description: "Nombre de Priority si el usuario eligio una opcion existente." },
|
|
496
|
-
nextAction: { type: "string", description: "Proxima accion concreta, si se puede inferir." },
|
|
497
|
-
dueDate: { type: "string", description: "Fecha limite en formato ISO 8601." },
|
|
498
|
-
scheduledDate: { type: "string", description: "Fecha programada en formato ISO 8601." },
|
|
499
|
-
estimatedMinutes: { type: "number", description: "Minutos estimados." },
|
|
500
|
-
valueScore: { type: "number", minimum: 1, maximum: 10 },
|
|
501
|
-
motivationScore: { type: "number", minimum: 1, maximum: 10 },
|
|
502
|
-
effortScore: { type: "number", minimum: 1, maximum: 10 },
|
|
503
|
-
urgencyScore: { type: "number", minimum: 1, maximum: 10 },
|
|
504
|
-
tags: {
|
|
505
|
-
type: "array",
|
|
506
|
-
items: { type: "string" },
|
|
507
|
-
},
|
|
508
|
-
notes: { type: "string" },
|
|
509
|
-
},
|
|
510
|
-
required: ["title"],
|
|
511
|
-
additionalProperties: false,
|
|
512
|
-
},
|
|
513
|
-
execute: async (args) => {
|
|
514
|
-
const taskService = TaskServiceFactory.instance;
|
|
515
|
-
const task = await taskService.create(this.compactObject({
|
|
516
|
-
title: args.title,
|
|
517
|
-
description: args.description,
|
|
518
|
-
source: args.source,
|
|
519
|
-
type: args.type,
|
|
520
|
-
status: args.status,
|
|
521
|
-
priority: args.priority,
|
|
522
|
-
nextAction: args.nextAction,
|
|
523
|
-
dueDate: args.dueDate,
|
|
524
|
-
scheduledDate: args.scheduledDate,
|
|
525
|
-
estimatedMinutes: args.estimatedMinutes,
|
|
526
|
-
valueScore: args.valueScore,
|
|
527
|
-
motivationScore: args.motivationScore,
|
|
528
|
-
effortScore: args.effortScore,
|
|
529
|
-
urgencyScore: args.urgencyScore,
|
|
530
|
-
tags: args.tags ?? [],
|
|
531
|
-
notes: args.notes,
|
|
532
|
-
user: context.userId,
|
|
533
|
-
}));
|
|
534
|
-
return this.serializeTask(task);
|
|
535
|
-
},
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
static searchTasksTool(context) {
|
|
539
|
-
return {
|
|
540
|
-
name: "search_tasks",
|
|
541
|
-
description: "Busca tareas del usuario por texto usando los campos parametrizados del repositorio, principalmente titulo y descripcion. Opcionalmente filtra por status y fecha de creacion.",
|
|
542
|
-
parameters: {
|
|
543
|
-
type: "object",
|
|
544
|
-
properties: {
|
|
545
|
-
query: { type: "string", description: "Texto de busqueda para title, description y otros campos configurados." },
|
|
546
|
-
limit: { type: "number", minimum: 1, maximum: 50, default: 10 },
|
|
547
|
-
status: { type: "string", description: "Nombre exacto de TaskStatus para filtrar." },
|
|
548
|
-
createdAtFrom: { type: "string", description: "Fecha ISO desde la cual filtrar createdAt inclusive." },
|
|
549
|
-
createdAtTo: { type: "string", description: "Fecha ISO hasta la cual filtrar createdAt inclusive." },
|
|
550
|
-
},
|
|
551
|
-
required: ["query"],
|
|
552
|
-
additionalProperties: false,
|
|
553
|
-
},
|
|
554
|
-
execute: async (args) => {
|
|
555
|
-
const filters = [this.taskUserFilter(context.userId)];
|
|
556
|
-
const limit = Math.min(Math.max(Number(args.limit ?? 10), 1), 50);
|
|
557
|
-
if (args.status) {
|
|
558
|
-
filters.push({ field: "status", operator: "eq", value: args.status });
|
|
559
|
-
}
|
|
560
|
-
if (args.createdAtFrom) {
|
|
561
|
-
filters.push({ field: "createdAt", operator: "gte", value: args.createdAtFrom });
|
|
562
|
-
}
|
|
563
|
-
if (args.createdAtTo) {
|
|
564
|
-
filters.push({ field: "createdAt", operator: "lte", value: args.createdAtTo });
|
|
565
|
-
}
|
|
566
|
-
const tasks = await TaskServiceFactory.instance.search(args.query, limit, filters);
|
|
567
|
-
return tasks.map(task => this.serializeTask(task));
|
|
568
|
-
},
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
static findTaskByIdTool(context) {
|
|
572
|
-
return {
|
|
573
|
-
name: "find_task_by_id",
|
|
574
|
-
description: "Busca una tarea especifica por ID, siempre limitada al usuario autenticado.",
|
|
575
|
-
parameters: {
|
|
576
|
-
type: "object",
|
|
577
|
-
properties: {
|
|
578
|
-
id: { type: "string", description: "ID exacto de la tarea." },
|
|
579
|
-
},
|
|
580
|
-
required: ["id"],
|
|
581
|
-
additionalProperties: false,
|
|
582
|
-
},
|
|
583
|
-
execute: async (args) => {
|
|
584
|
-
const task = await this.findUserTaskById(args.id, context.userId);
|
|
585
|
-
return this.serializeTask(task);
|
|
586
|
-
},
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
static groupTasksTool(context) {
|
|
590
|
-
return {
|
|
591
|
-
name: "group_tasks",
|
|
592
|
-
description: "Cuenta tareas agrupadas por atributos de Task. Tambien suma campos numericos cuando se incluyen en fields. Usa esta tool para responder metricas como tareas por status, prioridad, fecha, proyecto, cliente o totales de minutos.",
|
|
593
|
-
parameters: {
|
|
594
|
-
type: "object",
|
|
595
|
-
properties: {
|
|
596
|
-
fields: {
|
|
597
|
-
type: "array",
|
|
598
|
-
items: { type: "string", enum: TASK_GROUP_BY_FIELDS },
|
|
599
|
-
minItems: 1,
|
|
600
|
-
maxItems: 10,
|
|
601
|
-
description: "Campos por los que agrupar o sumar. Los campos numericos se suman; los demas agrupan.",
|
|
602
|
-
},
|
|
603
|
-
filters: {
|
|
604
|
-
type: "array",
|
|
605
|
-
description: "Filtros AND opcionales compatibles con Drax. No incluyas user; la tool lo agrega automaticamente.",
|
|
606
|
-
items: {
|
|
607
|
-
type: "object",
|
|
608
|
-
properties: {
|
|
609
|
-
field: { type: "string", enum: TASK_GROUP_BY_FIELDS },
|
|
610
|
-
operator: {
|
|
611
|
-
type: "string",
|
|
612
|
-
enum: ["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin", "like", "empty"],
|
|
613
|
-
},
|
|
614
|
-
value: {
|
|
615
|
-
type: ["string", "number", "boolean", "array", "null"],
|
|
616
|
-
items: { type: ["string", "number", "boolean"] },
|
|
617
|
-
description: "Valor del filtro. Para fechas usa ISO 8601; para in/nin puede ser array.",
|
|
618
|
-
},
|
|
619
|
-
},
|
|
620
|
-
required: ["field", "operator"],
|
|
621
|
-
additionalProperties: false,
|
|
622
|
-
},
|
|
623
|
-
},
|
|
624
|
-
dateFormat: {
|
|
625
|
-
type: "string",
|
|
626
|
-
enum: TASK_GROUP_BY_DATE_FORMATS,
|
|
627
|
-
default: "day",
|
|
628
|
-
description: "Granularidad para campos fecha.",
|
|
629
|
-
},
|
|
630
|
-
},
|
|
631
|
-
required: ["fields"],
|
|
632
|
-
additionalProperties: false,
|
|
633
|
-
},
|
|
634
|
-
execute: async (args) => {
|
|
635
|
-
const filters = [
|
|
636
|
-
...(Array.isArray(args.filters) ? args.filters : []),
|
|
637
|
-
this.taskUserFilter(context.userId),
|
|
638
|
-
];
|
|
639
|
-
return await TaskServiceFactory.instance.groupBy({
|
|
640
|
-
fields: args.fields,
|
|
641
|
-
filters,
|
|
642
|
-
dateFormat: args.dateFormat ?? "day",
|
|
643
|
-
});
|
|
644
|
-
},
|
|
645
|
-
};
|
|
646
|
-
}
|
|
647
|
-
static updateTaskPartialTool(context) {
|
|
648
|
-
return {
|
|
649
|
-
name: "update_task_partial",
|
|
650
|
-
description: "Actualiza parcialmente una tarea del usuario autenticado. Usa esta tool para cambiar solo algunos campos particulares de una tarea existente.",
|
|
651
|
-
parameters: {
|
|
652
|
-
type: "object",
|
|
653
|
-
properties: {
|
|
654
|
-
id: { type: "string", description: "ID exacto de la tarea a modificar." },
|
|
655
|
-
title: { type: "string" },
|
|
656
|
-
description: { type: "string" },
|
|
657
|
-
source: { type: "string", description: "Nombre de TaskSource." },
|
|
658
|
-
type: { type: "string", description: "Nombre de TaskType." },
|
|
659
|
-
status: { type: "string", description: "Nombre de TaskStatus." },
|
|
660
|
-
priority: { type: "string", description: "Nombre de Priority." },
|
|
661
|
-
nextAction: { type: "string" },
|
|
662
|
-
dueDate: { type: ["string", "null"], description: "Fecha limite ISO o null para limpiar." },
|
|
663
|
-
scheduledDate: { type: ["string", "null"], description: "Fecha programada ISO o null para limpiar." },
|
|
664
|
-
completedAt: { type: ["string", "null"], description: "Fecha de completado ISO o null para limpiar." },
|
|
665
|
-
estimatedMinutes: { type: "number" },
|
|
666
|
-
spentMinutes: { type: "number" },
|
|
667
|
-
valueScore: { type: "number", minimum: 1, maximum: 10 },
|
|
668
|
-
motivationScore: { type: "number", minimum: 1, maximum: 10 },
|
|
669
|
-
effortScore: { type: "number", minimum: 1, maximum: 10 },
|
|
670
|
-
urgencyScore: { type: "number", minimum: 1, maximum: 10 },
|
|
671
|
-
tags: { type: "array", items: { type: "string" } },
|
|
672
|
-
notes: { type: "string" },
|
|
673
|
-
archivedAt: { type: ["string", "null"], description: "Fecha ISO o null para limpiar." },
|
|
674
|
-
},
|
|
675
|
-
required: ["id"],
|
|
676
|
-
additionalProperties: false,
|
|
677
|
-
},
|
|
678
|
-
execute: async (args) => {
|
|
679
|
-
const existingTask = await this.findUserTaskById(args.id, context.userId);
|
|
680
|
-
if (!existingTask) {
|
|
681
|
-
return { updated: false, reason: "task_not_found" };
|
|
682
|
-
}
|
|
683
|
-
const { _id, id, user, ...input } = args;
|
|
684
|
-
const updateData = this.compactObject(input);
|
|
685
|
-
const updatedTask = await TaskServiceFactory.instance.updatePartial(args.id, updateData);
|
|
686
|
-
return {
|
|
687
|
-
updated: true,
|
|
688
|
-
task: this.serializeTask(updatedTask),
|
|
689
|
-
};
|
|
690
|
-
},
|
|
691
|
-
};
|
|
692
|
-
}
|
|
693
|
-
static listTaskOptionsTool() {
|
|
694
|
-
return {
|
|
695
|
-
name: "list_task_options",
|
|
696
|
-
description: "Consulta de una sola vez todas las opciones disponibles de TaskSource, TaskStatus, TaskType y Priority.",
|
|
697
|
-
parameters: {
|
|
698
|
-
type: "object",
|
|
699
|
-
properties: {},
|
|
700
|
-
additionalProperties: false,
|
|
701
|
-
},
|
|
702
|
-
execute: async () => {
|
|
703
|
-
return await this.fetchTaskOptionNames();
|
|
704
|
-
},
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
static createTaskOptionTool(kind) {
|
|
708
|
-
const serviceMap = {
|
|
709
|
-
source: TaskSourceServiceFactory.instance,
|
|
710
|
-
status: TaskStatusServiceFactory.instance,
|
|
711
|
-
type: TaskTypeServiceFactory.instance,
|
|
712
|
-
priority: PriorityServiceFactory.instance,
|
|
713
|
-
};
|
|
714
|
-
const entityLabelMap = {
|
|
715
|
-
source: "TaskSource",
|
|
716
|
-
status: "TaskStatus",
|
|
717
|
-
type: "TaskType",
|
|
718
|
-
priority: "Priority",
|
|
719
|
-
};
|
|
720
|
-
const toolNameMap = {
|
|
721
|
-
source: "create_task_source",
|
|
722
|
-
status: "create_task_status",
|
|
723
|
-
type: "create_task_type",
|
|
724
|
-
priority: "create_priority",
|
|
725
|
-
};
|
|
726
|
-
const properties = {
|
|
727
|
-
name: { type: "string", description: "Nombre de la nueva opcion." },
|
|
728
|
-
description: { type: "string", description: "Descripcion opcional." },
|
|
729
|
-
};
|
|
730
|
-
const required = ["name"];
|
|
731
|
-
if (kind === "priority") {
|
|
732
|
-
properties.color = { type: "string", description: "Color de la prioridad." };
|
|
733
|
-
required.push("color");
|
|
734
|
-
}
|
|
735
|
-
return {
|
|
736
|
-
name: toolNameMap[kind],
|
|
737
|
-
description: `Crea una nueva opcion de ${entityLabelMap[kind]} cuando el usuario necesita una opcion que no existe.`,
|
|
738
|
-
parameters: {
|
|
739
|
-
type: "object",
|
|
740
|
-
properties,
|
|
741
|
-
required,
|
|
742
|
-
additionalProperties: false,
|
|
743
|
-
},
|
|
744
|
-
execute: async (args) => {
|
|
745
|
-
const createData = this.compactObject({
|
|
746
|
-
name: args.name,
|
|
747
|
-
description: args.description,
|
|
748
|
-
color: kind === "priority" ? args.color : undefined,
|
|
749
|
-
});
|
|
750
|
-
return await serviceMap[kind].create(createData);
|
|
751
|
-
},
|
|
752
|
-
};
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
export default ChatbotTaskTools;
|
|
756
|
-
export { ChatbotTaskTools };
|