Browse Source

Feature/extend holdings table of AI prompt with activities count (#7700)

* Extend holdings table with activities count

* Update changelog
pull/4198/merge
Thomas Kaul 6 days ago
committed by GitHub
parent
commit
3d9352255d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      CHANGELOG.md
  2. 19
      apps/api/src/app/endpoints/ai/ai.service.ts

2
CHANGELOG.md

@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Extended the holdings table by the activities count in the _Copy AI prompt to clipboard for analysis_ action on the analysis page (experimental)
- Extended the holdings table by the activities count in the _Copy portfolio data to clipboard for AI prompt_ action on the analysis page (experimental)
- Extended the holdings table by the date of first activity in the _Copy AI prompt to clipboard for analysis_ action on the analysis page (experimental) - Extended the holdings table by the date of first activity in the _Copy AI prompt to clipboard for analysis_ action on the analysis page (experimental)
- Extended the holdings table by the date of first activity in the _Copy portfolio data to clipboard for AI prompt_ action on the analysis page (experimental) - Extended the holdings table by the date of first activity in the _Copy portfolio data to clipboard for AI prompt_ action on the analysis page (experimental)

19
apps/api/src/app/endpoints/ai/ai.service.ts

@ -19,6 +19,7 @@ import type { ColumnDescriptor } from 'tablemark';
export class AiService { export class AiService {
private static readonly HOLDINGS_TABLE_COLUMN_DEFINITIONS: ({ private static readonly HOLDINGS_TABLE_COLUMN_DEFINITIONS: ({
key: key:
| 'ACTIVITIES_COUNT'
| 'ALLOCATION_PERCENTAGE' | 'ALLOCATION_PERCENTAGE'
| 'ASSET_CLASS' | 'ASSET_CLASS'
| 'ASSET_SUB_CLASS' | 'ASSET_SUB_CLASS'
@ -33,6 +34,7 @@ export class AiService {
{ key: 'ASSET_CLASS', name: 'Asset Class' }, { key: 'ASSET_CLASS', name: 'Asset Class' },
{ key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' }, { key: 'ASSET_SUB_CLASS', name: 'Asset Sub Class' },
{ key: 'DATE_OF_FIRST_ACTIVITY', name: 'Date of First Activity' }, { key: 'DATE_OF_FIRST_ACTIVITY', name: 'Date of First Activity' },
{ align: 'right', key: 'ACTIVITIES_COUNT', name: 'Activities Count' },
{ {
align: 'right', align: 'right',
key: 'ALLOCATION_PERCENTAGE', key: 'ALLOCATION_PERCENTAGE',
@ -101,6 +103,7 @@ export class AiService {
}) })
.map( .map(
({ ({
activitiesCount,
allocationInPercentage, allocationInPercentage,
assetProfile: { assetProfile: {
assetClass, assetClass,
@ -114,6 +117,10 @@ export class AiService {
return AiService.HOLDINGS_TABLE_COLUMN_DEFINITIONS.reduce( return AiService.HOLDINGS_TABLE_COLUMN_DEFINITIONS.reduce(
(row, { key, name }) => { (row, { key, name }) => {
switch (key) { switch (key) {
case 'ACTIVITIES_COUNT':
row[name] = activitiesCount.toString();
break;
case 'ALLOCATION_PERCENTAGE': case 'ALLOCATION_PERCENTAGE':
row[name] = `${(allocationInPercentage * 100).toFixed(3)}%`; row[name] = `${(allocationInPercentage * 100).toFixed(3)}%`;
break; break;
@ -163,17 +170,21 @@ export class AiService {
) => Promise<typeof import('tablemark')>; ) => Promise<typeof import('tablemark')>;
const { tablemark } = await dynamicImport('tablemark'); const { tablemark } = await dynamicImport('tablemark');
const holdingsTableString = tablemark(holdingsTableRows, { const holdingsSection = [
'## Holdings',
'',
tablemark(holdingsTableRows, {
columns: holdingsTableColumns columns: holdingsTableColumns
}); })
].join('\n');
if (mode === 'portfolio') { if (mode === 'portfolio') {
return holdingsTableString; return holdingsSection;
} }
return [ return [
`You are a neutral financial assistant. Please analyze the following investment portfolio (base currency being ${userCurrency}) in simple words.`, `You are a neutral financial assistant. Please analyze the following investment portfolio (base currency being ${userCurrency}) in simple words.`,
holdingsTableString, holdingsSection,
'Structure your answer with these sections:', 'Structure your answer with these sections:',
'Overview: Briefly summarize the portfolio’s composition and allocation rationale.', 'Overview: Briefly summarize the portfolio’s composition and allocation rationale.',
'Risk Assessment: Identify potential risks, including market volatility, concentration, and sectoral imbalances.', 'Risk Assessment: Identify potential risks, including market volatility, concentration, and sectoral imbalances.',

Loading…
Cancel
Save