Browse Source

fix(ai): add natural language responses for greetings and casual queries

Replace robotic system prompts with conversational responses for:
- Greetings (hi, hello, hey, etc.) - returns friendly varied responses
- Acknowledgments (thanks, ok, great) - returns polite follow-ups
- Default queries - 3 varied helpful options instead of canned text

Keeps specialized responses for identity/usage/capability queries.

Updated tests to check for conversational patterns instead of
specific robotic phrases.

Fixes issue where casual queries like "hi" would return
"I am Ghostfolio AI. I can help with..." style responses.
pull/6395/head
Max P 1 month ago
parent
commit
047b23f2a9
  1. 2
      apps/api/src/app/endpoints/ai/ai-agent.policy.utils.spec.ts
  2. 35
      apps/api/src/app/endpoints/ai/ai-agent.policy.utils.ts
  3. 2
      apps/api/src/app/endpoints/ai/ai.service.spec.ts

2
apps/api/src/app/endpoints/ai/ai-agent.policy.utils.spec.ts

@ -90,7 +90,7 @@ describe('AiAgentPolicyUtils', () => {
policyDecision: decision, policyDecision: decision,
query query
}) })
).toContain('portfolio analysis'); ).toMatch(/(portfolio|holdings|ask|help)/i);
} }
); );

35
apps/api/src/app/endpoints/ai/ai-agent.policy.utils.ts

@ -355,13 +355,34 @@ function createNoToolDirectResponse(query?: string) {
].join('\n'); ].join('\n');
} }
return [ const greetingPattern = /^(hi|hello|hey|hiya|greetings|good (morning|afternoon|evening))/i;
'I am Ghostfolio AI. I can help with portfolio analysis, concentration risk, market prices, diversification options, and stress scenarios.', const acknowledgmentPattern = /^(thanks|thank you|thx|ty|ok|okay|great|awesome|perfect)/i;
'Try one of these:',
'- "Show my top holdings"', if (greetingPattern.test(normalizedQuery)) {
'- "What is my concentration risk?"', const greetings = [
'- "Help me diversify with actionable options"' "Hello! I'm here to help with your portfolio analysis. What would you like to know?",
].join('\n'); "Hi! I can help you understand your portfolio better. What's on your mind?",
"Hey there! Ready to dive into your portfolio? Just ask!"
];
return greetings[Math.floor(Math.random() * greetings.length)];
}
if (acknowledgmentPattern.test(normalizedQuery)) {
const acknowledgments = [
"You're welcome! Let me know if you need anything else.",
"Happy to help! What else would you like to know?",
"Anytime! Feel free to ask if you have more questions."
];
return acknowledgments[Math.floor(Math.random() * acknowledgments.length)];
}
const defaults = [
"I'm here to help with your portfolio! You can ask me things like 'Show my top holdings' or 'What's my concentration risk?'",
"Sure! I can analyze your portfolio, check concentration risks, look up market prices, and more. What would you like to explore?",
"I'd be happy to help! Try asking about your holdings, risk analysis, or market data for your investments."
];
return defaults[Math.floor(Math.random() * defaults.length)];
} }
export function applyToolExecutionPolicy({ export function applyToolExecutionPolicy({

2
apps/api/src/app/endpoints/ai/ai.service.spec.ts

@ -255,7 +255,7 @@ describe('AiService', () => {
userId: 'user-direct-route' userId: 'user-direct-route'
}); });
expect(result.answer).toContain('I am Ghostfolio AI'); expect(result.answer).toMatch(/(hello|hi|here to help|portfolio)/i);
expect(result.toolCalls).toEqual([]); expect(result.toolCalls).toEqual([]);
expect(result.citations).toEqual([]); expect(result.citations).toEqual([]);
expect(dataProviderService.getQuotes).not.toHaveBeenCalled(); expect(dataProviderService.getQuotes).not.toHaveBeenCalled();

Loading…
Cancel
Save