mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.1 KiB
77 lines
2.1 KiB
import { tool } from '@anthropic-ai/claude-agent-sdk';
|
|
import { Logger } from '@nestjs/common';
|
|
import { z } from 'zod/v4';
|
|
|
|
import { classifyToolError, withTimeout } from './error-helpers';
|
|
import { buildToolCacheKey, compactJson, withRedisCache } from './helpers';
|
|
import type { ToolDependencies } from './interfaces';
|
|
|
|
const logger = new Logger('Tool:get_account_details');
|
|
|
|
export function createGetAccountDetailsTool(deps: ToolDependencies) {
|
|
return tool(
|
|
'get_account_details',
|
|
'Get account details: balances, platforms, and totals.',
|
|
{
|
|
filters: z
|
|
.array(
|
|
z.object({
|
|
id: z.string().describe('Filter value ID'),
|
|
type: z
|
|
.enum(['ACCOUNT', 'ASSET_CLASS', 'TAG'])
|
|
.describe('Filter type')
|
|
})
|
|
)
|
|
.optional()
|
|
.describe('Optional filters to narrow account results')
|
|
},
|
|
async ({ filters }) => {
|
|
try {
|
|
const redisCacheKey = buildToolCacheKey(
|
|
deps.user.id,
|
|
'get_account_details',
|
|
{ filters }
|
|
);
|
|
|
|
const accounts = await withRedisCache(
|
|
deps.redisCacheService,
|
|
redisCacheKey,
|
|
300_000,
|
|
() =>
|
|
withTimeout(
|
|
deps.portfolioService.getAccountsWithAggregations({
|
|
filters: filters ?? [],
|
|
userId: deps.user.id,
|
|
withExcludedAccounts: true
|
|
})
|
|
)
|
|
);
|
|
|
|
return {
|
|
content: [{ type: 'text' as const, text: compactJson(accounts) }]
|
|
};
|
|
} catch (error) {
|
|
const classified = classifyToolError(error);
|
|
logger.error({
|
|
event: 'agent.tool.error',
|
|
tool: 'get_account_details',
|
|
...classified
|
|
});
|
|
return {
|
|
isError: true,
|
|
content: [
|
|
{
|
|
type: 'text' as const,
|
|
text: JSON.stringify({
|
|
error: true,
|
|
type: classified.type,
|
|
message: classified.userMessage
|
|
})
|
|
}
|
|
]
|
|
};
|
|
}
|
|
},
|
|
{ annotations: { readOnlyHint: true } }
|
|
);
|
|
}
|
|
|