-
Notifications
You must be signed in to change notification settings - Fork 38
AI-207: Add Smart Suggestion Engine for MCP Tools #297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 9 commits
fd1e835
1a3e7c8
858fbd0
4fc4277
27ec324
df8a745
ff7b32c
aeb2442
1bda2db
e5ee988
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| def generate_suggestions(intent, data): | ||
| """ | ||
| Generate context-aware suggestions based on MCP tool responses. | ||
| """ | ||
|
|
||
| suggestions: List[str] = [] | ||
|
|
||
| # 🔹 Case 1: Overdue loans | ||
| if intent == "get_overdue_loans": | ||
|
|
||
| # Extract loan list safely | ||
| if isinstance(data, dict): | ||
| if "error" in data: | ||
| return [] # Don't generate suggestions for error responses | ||
| loans = data.get("overdueLoans", []) | ||
| else: | ||
| loans = data or [] | ||
|
|
||
| # Ensure it's iterable list | ||
| if not isinstance(loans, list): | ||
| return [] | ||
|
|
||
| for loan in loans: | ||
| if not isinstance(loan, dict): | ||
| continue | ||
|
|
||
| loan_id = loan.get("loanId") or loan.get("id") | ||
|
|
||
| if not loan_id: | ||
| continue | ||
|
|
||
| suggestions.append(f"Apply a late fee to loan {loan_id}") | ||
| suggestions.append(f"View repayment schedule for loan {loan_id}") | ||
| suggestions.append(f"Send a repayment reminder for loan {loan_id}") | ||
|
|
||
| # 🔹 Case 2: Loan details | ||
| elif intent == "get_loan_details": | ||
|
|
||
| if not isinstance(data, dict): | ||
| return suggestions | ||
|
|
||
| if "error" in data: | ||
| return suggestions | ||
|
|
||
| loan_id = data.get("loanId") | ||
|
|
||
| # Safe normalization (prevents None.lower() crash) | ||
| status = (data.get("status") or "").lower() | ||
|
|
||
| if not loan_id: | ||
| return suggestions | ||
|
|
||
| # Active loan actions | ||
| if "active" in status: | ||
| suggestions.append(f"Make a repayment for loan {loan_id}") | ||
| suggestions.append(f"View repayment schedule for loan {loan_id}") | ||
|
|
||
| # Pending/submitted actions | ||
| if "pending" in status or "submitted" in status: | ||
| suggestions.append(f"Approve loan {loan_id}") | ||
| suggestions.append(f"Reject loan {loan_id}") | ||
|
|
||
| return suggestions | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -289,11 +289,16 @@ def get_addresses(clientId: int) -> dict: | |||||||||||||||||||
| @mcp.tool() | ||||||||||||||||||||
| def get_loan(loanId: int) -> dict: | ||||||||||||||||||||
| """Get key details of a specific loan.""" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| data = get_loan_details.func(loanId) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if not isinstance(data, dict): | ||||||||||||||||||||
| return data | ||||||||||||||||||||
|
|
||||||||||||||||||||
| tl = data.get("timeline", {}) | ||||||||||||||||||||
| return { | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # 🔹 Step 1: Prepare clean response | ||||||||||||||||||||
| response = { | ||||||||||||||||||||
| "loanId": data.get("id"), | ||||||||||||||||||||
| "accountNo": data.get("accountNo"), | ||||||||||||||||||||
| "productName": data.get("loanProductName"), | ||||||||||||||||||||
|
|
@@ -310,6 +315,14 @@ def get_loan(loanId: int) -> dict: | |||||||||||||||||||
| "repaymentFrequency": f"Every {data.get('repaymentEvery')} {data.get('repaymentFrequencyType', {}).get('value','')}", | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # 🔹 Step 2: Generate suggestions | ||||||||||||||||||||
| suggestions = generate_suggestions("get_loan_details", response) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # 🔹 Step 3: Return enhanced response | ||||||||||||||||||||
| return { | ||||||||||||||||||||
| "data": response, | ||||||||||||||||||||
| "suggestions": suggestions | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Comment on lines
+318
to
+325
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not wrap loan responses with server-side suggestions.
Proposed fix- # 🔹 Step 2: Generate suggestions
- suggestions = generate_suggestions("get_loan_details", response)
-
- # 🔹 Step 3: Return enhanced response
- return {
- "data": response,
- "suggestions": suggestions
- }
+ return responseAs per coding guidelines, “Ensure 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||
| @mcp.tool() | ||||||||||||||||||||
| def get_repayment_sched(loanId: int) -> dict: | ||||||||||||||||||||
| """Get the repayment schedule for a loan.""" | ||||||||||||||||||||
|
|
@@ -414,10 +427,23 @@ def waive_loan_interest(loanId: int, amount: float, note: str = "AI Authorized W | |||||||||||||||||||
| return waive_interest.func(loanId, amount, note) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| @mcp.tool() | ||||||||||||||||||||
| def get_overdue_loans_for_client(clientId: int) -> dict: | ||||||||||||||||||||
| def get_overdue_loans_for_client(clientId: int) -> list: | ||||||||||||||||||||
| """Get all overdue or in-arrears loans for a client""" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Step 1: Get actual data | ||||||||||||||||||||
|
|
||||||||||||||||||||
| return get_overdue_loans.func(clientId) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # 🔹 Step 2: Generate smart suggestions | ||||||||||||||||||||
| suggestions = generate_suggestions("get_overdue_loans", result) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # 🔹 Step 3: Return enhanced response | ||||||||||||||||||||
| # ✅ correct | ||||||||||||||||||||
| return { | ||||||||||||||||||||
| **result, | ||||||||||||||||||||
| "suggestions": suggestions | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| @mcp.tool() | ||||||||||||||||||||
| def create_group_loan_app(groupId: int, principal: float, months: int, productId: int = 1) -> dict: | ||||||||||||||||||||
| """Create a group loan application for an existing lending group""" | ||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Add mypy-compatible type annotations.
generate_suggestionshas untyped parameters/return, andListis referenced without an import. Add explicit types and import the typing symbols used.Proposed fix
As per coding guidelines, “Type Safety: Flag any new function signatures, complex variable assignments, or class attributes that are missing mypy-compatible type hints.”
🤖 Prompt for AI Agents