Addition of an AI chat assistant and a 100MB file upload limit.

This commit is contained in:
2026-09-30 16:30:41 +03:30
parent e94600a02e
commit ae21d9bbc7
8 changed files with 139 additions and 13 deletions
+11 -2
View File
@@ -134,8 +134,12 @@ export class AiAskService {
actor: Actor,
question: string,
personId?: string,
chatContext?: string,
): Promise<AskMentoResponse> {
const { context, catalog } = await this.buildContext(actor, personId);
const chatBlock = String(chatContext || '')
.trim()
.slice(0, 3500);
const raw = await this.ai.completeJson<{
answer?: string;
sources?: Array<{ type?: string; id?: string; label?: string }>;
@@ -145,12 +149,17 @@ export class AiAskService {
"مشتری" / "مشتری جدید" means a Person (contact) record.
Period stats use Asia/Tehran calendar: today, yesterday, this_week (Saturday–Friday), this_month (current Jalali month).
Workspace facts and Period stats are complete and authoritative for counts of customers, companies, activities, deals, won deals, invoices, quotes, products, notes, and tickets.
Answer ONLY from the CRM context. Never say a listed count is unavailable.
Answer ONLY from the CRM context for CRM facts. Never say a listed count is unavailable.
If a "Recent conversation" block is provided, use it only to understand the user's question and tone; do not invent CRM facts from chat alone.
Do not invent customers, amounts, dates, or promises.
Return JSON: { "answer": string, "sources": [{ "type": "person"|"note"|"activity"|"deal"|"memory", "id": string, "label": string }] }
Use at most 4 sources, and only ids that appear in the context. Workspace/period facts do not need sources; when naming customers, prefer person sources.
Write the answer in Persian, concise, with exact numbers and names when present.`,
`Question:\n${question.trim()}\n\nCRM context:\n${context}`,
`Question:\n${question.trim()}\n\nCRM context:\n${context}${
chatBlock
? `\n\nRecent conversation (for context only, not CRM facts):\n${chatBlock}`
: ''
}`,
);
const allowed = new Map(catalog.map((item) => [item.id, item]));
+1 -1
View File
@@ -26,7 +26,7 @@ export class AiController {
@Post('ask')
askMento(@CurrentUser() user: Actor, @Body() dto: AskMentoDto) {
return this.ask.ask(user, dto.question, dto.personId);
return this.ask.ask(user, dto.question, dto.personId, dto.chatContext);
}
@Get('people/:personId/summary')
+5
View File
@@ -16,4 +16,9 @@ export class AskMentoDto {
@IsOptional()
@IsString()
personId?: string;
@IsOptional()
@IsString()
@MaxLength(4000)
chatContext?: string;
}