WIP - saving list views
This commit is contained in:
@@ -38,4 +38,12 @@ export class AiAssistantController {
|
||||
payload,
|
||||
);
|
||||
}
|
||||
|
||||
@Post('suggest-view-name')
|
||||
async suggestViewName(
|
||||
@TenantId() tenantId: string,
|
||||
@Body() payload: { objectLabel: string; filters: any[]; explanation?: string },
|
||||
) {
|
||||
return this.aiAssistantService.suggestViewName(tenantId, payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,6 +688,8 @@ export class AiAssistantService {
|
||||
totalCount: meiliResults.total ?? records.totalCount ?? 0,
|
||||
strategy: plan.strategy,
|
||||
explanation: plan.explanation,
|
||||
filters: [],
|
||||
sort: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -702,6 +704,8 @@ export class AiAssistantService {
|
||||
...fallback,
|
||||
strategy: plan.strategy,
|
||||
explanation: plan.explanation,
|
||||
filters: [],
|
||||
sort: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -730,9 +734,53 @@ export class AiAssistantService {
|
||||
...filtered,
|
||||
strategy: plan.strategy,
|
||||
explanation: plan.explanation,
|
||||
filters: resolvedFilters,
|
||||
sort: plan.sort || null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the LLM to suggest a short, human-friendly name for a saved list view
|
||||
* based on the resolved filters / explanation.
|
||||
*/
|
||||
async suggestViewName(
|
||||
tenantId: string,
|
||||
payload: { objectLabel: string; filters: AiSearchFilter[]; explanation?: string },
|
||||
): Promise<{ suggestedName: string }> {
|
||||
const openAiConfig = await this.getOpenAiConfig(tenantId);
|
||||
if (!openAiConfig) {
|
||||
return { suggestedName: `${payload.objectLabel} View` };
|
||||
}
|
||||
|
||||
const model = new ChatOpenAI({
|
||||
apiKey: openAiConfig.apiKey,
|
||||
model: this.normalizeChatModel(openAiConfig.model),
|
||||
temperature: 0.4,
|
||||
});
|
||||
|
||||
const filterSummary = payload.explanation?.trim()
|
||||
|| payload.filters.map(f => `${f.field} ${f.operator} ${f.value ?? ''}`).join(', ')
|
||||
|| 'no filters';
|
||||
|
||||
try {
|
||||
const response = await model.invoke([
|
||||
new SystemMessage(
|
||||
'You are a CRM assistant. Suggest a very short (2–5 words), descriptive, and human-friendly name for a saved list view. ' +
|
||||
'Reply with ONLY the name, no quotes or punctuation.',
|
||||
),
|
||||
new HumanMessage(
|
||||
`Object: ${payload.objectLabel}.\nFilter summary: ${filterSummary}`,
|
||||
),
|
||||
]);
|
||||
|
||||
const raw = typeof response.content === 'string' ? response.content.trim() : '';
|
||||
const suggestedName = raw || `${payload.objectLabel} View`;
|
||||
return { suggestedName };
|
||||
} catch {
|
||||
return { suggestedName: `${payload.objectLabel} View` };
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Planning-Based LangGraph Workflow
|
||||
// ============================================
|
||||
|
||||
Reference in New Issue
Block a user