@ -124,7 +124,6 @@ export class AiService {
broker ,
rows ,
accounts : user.accounts ,
subscription : user.subscription ,
userCurrency : user.settings.settings.baseCurrency ,
userId : user.id
} ) ;
@ -152,7 +151,6 @@ export class AiService {
accounts ,
broker ,
rows ,
subscription ,
userCurrency ,
userId
} : {
@ -160,7 +158,6 @@ export class AiService {
accounts : AccountToMatch [ ] ;
broker? : string ;
rows : ActivityRow [ ] ;
subscription? : UserWithSettings [ 'subscription' ] ;
userCurrency : string ;
userId : string ;
} ) {
@ -211,7 +208,6 @@ export class AiService {
abortSignal ,
accountHints ,
assets ,
subscription ,
userId
} )
: { accounts : [ ] , assets : [ ] } ;
@ -524,15 +520,9 @@ export class AiService {
/ * *
* Gives the holdings of the user with the tool get - portfolio of the server
* of the Model Context Protocol , without the holdings whose data source the
* import refuses for the user
* import refuses
* /
private async getHoldingsToMatch ( {
subscription ,
userId
} : {
subscription? : UserWithSettings [ 'subscription' ] ;
userId : string ;
} ) {
private async getHoldingsToMatch ( { userId } : { userId : string } ) {
const [ { content } , dataSources ] = await Promise . all ( [
this . mcpService . getPortfolio ( { userId , withValues : false } ) ,
this . dataProviderService . getDataSources ( )
@ -540,11 +530,7 @@ export class AiService {
return this . getHoldingsFromTable ( content [ 0 ] . text ) . filter (
( { dataSource } ) = > {
return this . isValidDataSourceForImport ( {
dataSource ,
dataSources ,
subscription
} ) ;
return this . isValidDataSourceForImport ( { dataSource , dataSources } ) ;
}
) ;
}
@ -608,8 +594,8 @@ export class AiService {
* symbol only . The holdings let the model select an asset profile which the
* user already has , also if no search gives it , for example as no data
* provider finds its ISIN . A holding whose data source the import refuses
* for the user is not given to the model , so that the model selects an
* asset profile of the search instead and the whole import does not fail .
* is not given to the model , so that the model selects an asset profile of
* the search instead and the whole import does not fail .
* If get - accounts fails , the model gets no accounts , so that only the
* account hints have no match . If get - portfolio or the data sources fail ,
* the model gets no holdings . The reasoning is disabled , as it can add
@ -625,13 +611,11 @@ export class AiService {
abortSignal ,
accountHints ,
assets ,
subscription ,
userId
} : {
abortSignal? : AbortSignal ;
accountHints : AccountHint [ ] ;
assets : AssetToMatch [ ] ;
subscription? : UserWithSettings [ 'subscription' ] ;
userId : string ;
} ) {
const startTime = performance . now ( ) ;
@ -650,7 +634,7 @@ export class AiService {
} )
: undefined ,
assets . length > 0
? this . getHoldingsToMatch ( { subscription , userId } ) . catch (
? this . getHoldingsToMatch ( { userId } ) . catch (
( error : Error ) : undefined = > {
this . logger . warn ( ` Could not get the holdings: ${ error . message } ` ) ;
@ -751,31 +735,24 @@ export class AiService {
/ * *
* Checks without a request to a data provider if the import takes a data
* source for the user : it is configured and does not require Ghostfolio
* Premium , for example after the Premium subscription has expired . The data
* source is first transformed as POST api / v1 / import transforms it . A symbol
* which the data source cannot resolve , for example a delisted one , is not
* found , as this needs a request to the data provider .
* source of a holding : it is configured . The data source is first
* transformed as POST api / v1 / import transforms it . A data source which
* requires Ghostfolio Premium is taken , as the import takes it for an asset
* profile which the user already has . A symbol which the data source cannot
* resolve , for example a delisted one , is not found , as this needs a
* request to the data provider .
* /
private isValidDataSourceForImport ( {
dataSource ,
dataSources ,
subscription
dataSources
} : {
dataSource : string ;
dataSources : DataSource [ ] ;
subscription? : UserWithSettings [ 'subscription' ] ;
} ) {
const dataSourceOfImport = transformDataSourceInRequest ( {
return dataSources . includes (
transformDataSourceInRequest ( {
dataSource ,
configurationService : this.configurationService
} ) ;
return (
dataSources . includes ( dataSourceOfImport ) &&
! this . dataProviderService . isPremiumRequired ( {
subscription ,
dataSource : dataSourceOfImport
} )
) ;
}