From fcf3173f245a9a722307b60cadb0cb72f7cf4452 Mon Sep 17 00:00:00 2001 From: csehatt741 Date: Wed, 12 Mar 2025 10:59:28 +0100 Subject: [PATCH] Filters added to AI prompt --- .../api/src/app/endpoints/ai/ai.controller.ts | 27 +++++++++++++++++-- apps/api/src/app/endpoints/ai/ai.service.ts | 4 +++ .../analysis/analysis-page.component.ts | 5 +++- apps/client/src/app/services/data.service.ts | 14 ++++++++-- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/apps/api/src/app/endpoints/ai/ai.controller.ts b/apps/api/src/app/endpoints/ai/ai.controller.ts index 910abbf96..849b8438a 100644 --- a/apps/api/src/app/endpoints/ai/ai.controller.ts +++ b/apps/api/src/app/endpoints/ai/ai.controller.ts @@ -1,5 +1,6 @@ import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { ApiService } from '@ghostfolio/api/services/api/api.service'; import { DEFAULT_CURRENCY, DEFAULT_LANGUAGE_CODE @@ -8,7 +9,14 @@ import { AiPromptResponse } from '@ghostfolio/common/interfaces'; import { permissions } from '@ghostfolio/common/permissions'; import type { AiPromptMode, RequestWithUser } from '@ghostfolio/common/types'; -import { Controller, Get, Inject, Param, UseGuards } from '@nestjs/common'; +import { + Controller, + Get, + Inject, + Param, + Query, + UseGuards +} from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; @@ -17,6 +25,7 @@ import { AiService } from './ai.service'; @Controller('ai') export class AiController { public constructor( + private readonly apiService: ApiService, private readonly aiService: AiService, @Inject(REQUEST) private readonly request: RequestWithUser ) {} @@ -25,10 +34,24 @@ export class AiController { @HasPermission(permissions.readAiPrompt) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async getPrompt( - @Param('mode') mode: AiPromptMode + @Param('mode') mode: AiPromptMode, + @Query('accounts') filterByAccounts?: string, + @Query('assetClasses') filterByAssetClasses?: string, + @Query('dataSource') filterByDataSource?: string, + @Query('symbol') filterBySymbol?: string, + @Query('tags') filterByTags?: string ): Promise { + const filters = this.apiService.buildFiltersFromQueryParams({ + filterByAccounts, + filterByAssetClasses, + filterByDataSource, + filterBySymbol, + filterByTags + }); + const prompt = await this.aiService.getPrompt({ mode, + filters, impersonationId: undefined, languageCode: this.request.user.Settings.settings.language ?? DEFAULT_LANGUAGE_CODE, diff --git a/apps/api/src/app/endpoints/ai/ai.service.ts b/apps/api/src/app/endpoints/ai/ai.service.ts index d9090d77c..8807e67bf 100644 --- a/apps/api/src/app/endpoints/ai/ai.service.ts +++ b/apps/api/src/app/endpoints/ai/ai.service.ts @@ -1,4 +1,5 @@ import { PortfolioService } from '@ghostfolio/api/app/portfolio/portfolio.service'; +import { Filter } from '@ghostfolio/common/interfaces'; import type { AiPromptMode } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; @@ -8,12 +9,14 @@ export class AiService { public constructor(private readonly portfolioService: PortfolioService) {} public async getPrompt({ + filters, impersonationId, languageCode, mode, userCurrency, userId }: { + filters?: Filter[]; impersonationId: string; languageCode: string; mode: AiPromptMode; @@ -21,6 +24,7 @@ export class AiService { userId: string; }) { const { holdings } = await this.portfolioService.getDetails({ + filters, impersonationId, userId }); diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index 4aee450e6..3ffab0cc6 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -161,7 +161,10 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { } this.dataService - .fetchPrompt(mode) + .fetchPrompt({ + filters: this.userService.getFilters(), + mode + }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(({ prompt }) => { this.clipboard.copy(prompt); diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index e8d4b7826..34ba5c6e9 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -655,8 +655,18 @@ export class DataService { return this.http.get('/api/v1/portfolio/report'); } - public fetchPrompt(mode: AiPromptMode) { - return this.http.get(`/api/v1/ai/prompt/${mode}`); + public fetchPrompt({ + filters, + mode + }: { + filters?: Filter[]; + mode: AiPromptMode; + }) { + const params = this.buildFiltersAsQueryParams({ filters }); + + return this.http.get(`/api/v1/ai/prompt/${mode}`, { + params + }); } public fetchPublicPortfolio(aAccessId: string) {