|
|
|
@ -10,7 +10,17 @@ import type { AiPromptMode } from '@ghostfolio/common/types'; |
|
|
|
import { Injectable } from '@nestjs/common'; |
|
|
|
import { createOpenRouter } from '@openrouter/ai-sdk-provider'; |
|
|
|
import { generateText } from 'ai'; |
|
|
|
import type { ColumnDescriptor } from 'tablemark'; |
|
|
|
import tablemark, { ColumnDescriptor } from 'tablemark'; |
|
|
|
|
|
|
|
// Column name constants for holdings table
|
|
|
|
const HOLDINGS_TABLE_COLUMNS = { |
|
|
|
CURRENCY: 'Currency', |
|
|
|
NAME: 'Name', |
|
|
|
SYMBOL: 'Symbol', |
|
|
|
ASSET_CLASS: 'Asset Class', |
|
|
|
ALLOCATION_PERCENTAGE: 'Allocation in Percentage', |
|
|
|
ASSET_SUB_CLASS: 'Asset Sub Class' |
|
|
|
} as const; |
|
|
|
|
|
|
|
@Injectable() |
|
|
|
export class AiService { |
|
|
|
@ -60,12 +70,12 @@ export class AiService { |
|
|
|
}); |
|
|
|
|
|
|
|
const holdingsTableColumns: ColumnDescriptor[] = [ |
|
|
|
{ name: 'Name' }, |
|
|
|
{ name: 'Symbol' }, |
|
|
|
{ name: 'Currency' }, |
|
|
|
{ name: 'Asset Class' }, |
|
|
|
{ name: 'Asset Sub Class' }, |
|
|
|
{ align: 'right', name: 'Allocation in Percentage' } |
|
|
|
{ name: HOLDINGS_TABLE_COLUMNS.CURRENCY }, |
|
|
|
{ name: HOLDINGS_TABLE_COLUMNS.NAME }, |
|
|
|
{ name: HOLDINGS_TABLE_COLUMNS.SYMBOL }, |
|
|
|
{ name: HOLDINGS_TABLE_COLUMNS.ASSET_CLASS }, |
|
|
|
{ align: 'right', name: HOLDINGS_TABLE_COLUMNS.ALLOCATION_PERCENTAGE }, |
|
|
|
{ name: HOLDINGS_TABLE_COLUMNS.ASSET_SUB_CLASS } |
|
|
|
]; |
|
|
|
|
|
|
|
const holdingsTableRows = Object.values(holdings) |
|
|
|
@ -82,23 +92,16 @@ export class AiService { |
|
|
|
symbol |
|
|
|
}) => { |
|
|
|
return { |
|
|
|
Name: name, |
|
|
|
Symbol: symbol, |
|
|
|
Currency: currency, |
|
|
|
'Asset Class': assetClass ?? '', |
|
|
|
'Asset Sub Class': assetSubClass ?? '', |
|
|
|
'Allocation in Percentage': `${(allocationInPercentage * 100).toFixed(3)}%` |
|
|
|
[HOLDINGS_TABLE_COLUMNS.CURRENCY]: currency, |
|
|
|
[HOLDINGS_TABLE_COLUMNS.NAME]: name, |
|
|
|
[HOLDINGS_TABLE_COLUMNS.SYMBOL]: symbol, |
|
|
|
[HOLDINGS_TABLE_COLUMNS.ASSET_CLASS]: assetClass ?? '', |
|
|
|
[HOLDINGS_TABLE_COLUMNS.ALLOCATION_PERCENTAGE]: `${(allocationInPercentage * 100).toFixed(3)}%`, |
|
|
|
[HOLDINGS_TABLE_COLUMNS.ASSET_SUB_CLASS]: assetSubClass ?? '' |
|
|
|
}; |
|
|
|
} |
|
|
|
); |
|
|
|
|
|
|
|
// Dynamic import to load ESM module from CommonJS context
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
|
|
const dynamicImport = new Function('s', 'return import(s)') as ( |
|
|
|
s: string |
|
|
|
) => Promise<typeof import('tablemark')>; |
|
|
|
const { tablemark } = await dynamicImport('tablemark'); |
|
|
|
|
|
|
|
const holdingsTableString = tablemark(holdingsTableRows, { |
|
|
|
columns: holdingsTableColumns |
|
|
|
}); |
|
|
|
|