adding fin goals and tools

This commit is contained in:
Joshua Smith
2025-03-20 13:37:51 -04:00
parent 850404e0d5
commit c3084eec41
9 changed files with 200 additions and 11 deletions

View File

@@ -39,7 +39,7 @@ OPENAI_API_KEY=sk-proj-...
AGENT_GOAL=goal_choose_agent_type # (default) AGENT_GOAL=goal_choose_agent_type # (default)
#Choose which category(ies) of goals you want to be listed by the Agent - options are system (always included), hr, travel, or all. #Choose which category(ies) of goals you want to be listed by the Agent - options are system (always included), hr, travel, or all.
GOAL_CATEGORIES=hr,travel # default is all GOAL_CATEGORIES=hr,travel,fin # default is all
# Set if the UI should force a user confirmation step or not # Set if the UI should force a user confirmation step or not
SHOW_CONFIRM=True SHOW_CONFIRM=True

View File

@@ -52,7 +52,7 @@ description="Help the user gather args for these tools in order: "
2. Define the tool 2. Define the tool
- `name`: name of the tool - this is the name as defined in the goal description list of tools. The name should be (sort of) the same as the tool name given in the goal description. So, if the description lists "CurrentPTO" as a tool, the name here should be `current_pto_tool`. - `name`: name of the tool - this is the name as defined in the goal description list of tools. The name should be (sort of) the same as the tool name given in the goal description. So, if the description lists "CurrentPTO" as a tool, the name here should be `current_pto_tool`.
- `description`: LLM-facing description of tool - `description`: LLM-facing description of tool
- `arguments`: These are the _input_ arguments to the tool. Each input argument should be defined as a [/models/tool_definitions.py](ToolArgument). Tools don't have to have arguments but the arguments list has to be declared. If the tool you're creating doesn't have inputs, define arguments as `arguments=[]` - `arguments`: These are the _input_ arguments to the tool. Each input argument should be defined as a [ToolArgument](./models/tool_definitions.py). Tools don't have to have arguments but the arguments list has to be declared. If the tool you're creating doesn't have inputs, define arguments as `arguments=[]`
#### Create Each Tool #### Create Each Tool
- The tools themselves are defined in their own files in `/tools` - you can add a subfolder to organize them, see the hr tools for an example. - The tools themselves are defined in their own files in `/tools` - you can add a subfolder to organize them, see the hr tools for an example.
@@ -61,8 +61,8 @@ description="Help the user gather args for these tools in order: "
- The return dict should match the output format you specified in the goal's `example_conversation_history` - The return dict should match the output format you specified in the goal's `example_conversation_history`
- tools are where the user input+model output becomes deterministic. Add validation here to make sure what the system is doing is valid and acceptable - tools are where the user input+model output becomes deterministic. Add validation here to make sure what the system is doing is valid and acceptable
#### Add to `tools/__init__.py` #### Add to `tools/__init__.py` and the tool get_handler()
- In `tools/__init__.py`, add an import statement for each new tool as well as an applicable return statement in `get_handler`. The tool name here should match the tool name as described in the goal's `description` field. - In [tools/__init__.py](./tools/__init__.py), add an import statement for each new tool as well as an applicable return statement in `get_handler`. The tool name here should match the tool name as described in the goal's `description` field.
Example: Example:
``` ```
if tool_name == "CurrentPTO": if tool_name == "CurrentPTO":

17
todo.md
View File

@@ -11,13 +11,20 @@
[x] create people management scenarios <br /> [x] create people management scenarios <br />
[ ] 2. Others HR goals: <br /> [ ] 2. Others HR goals: <br />
-- book work travel <br /> - book work travel <br />
-- check insurance coverages <br /> - check insurance coverages <br />
-- expense management <br /> - expense management <br />
-- check in on the health of the team <br /> - check in on the health of the team <br />
[ ] fintech goals <br />
- Fraud Detection and Prevention - The AI monitors transactions across accounts, flagging suspicious activities (e.g., unusual spending patterns or login attempts) and autonomously freezing accounts or notifying customers and compliance teams.<br />
- Personalized Financial Advice - An AI agent analyzes a customers financial data (e.g., income, spending habits, savings, investments) and provides tailored advice, such as budgeting tips, investment options, or debt repayment strategies.<br />
- Portfolio Management and Rebalancing - The AI monitors a customers investment portfolio, rebalancing it automatically based on market trends, risk tolerance, and financial goals (e.g., shifting assets between stocks, bonds, or crypto).<br />
- money movement - start money transfer <br />
- [x] account balance - <br />
[ ] ask the ai agent how it did at the end of the conversation, was it efficient? successful? insert a search attribute to document that before return [ ] ask the ai agent how it did at the end of the conversation, was it efficient? successful? insert a search attribute to document that before return <br />
- Insight into the agents performance <br /> - Insight into the agents performance <br />
[ ] non-retry the api key error - "Invalid API Key provided: sk_test_**J..." and "AuthenticationError" <br /> [ ] non-retry the api key error - "Invalid API Key provided: sk_test_**J..." and "AuthenticationError" <br />

View File

@@ -13,6 +13,9 @@ from .hr.book_pto import book_pto
from .hr.future_pto_calc import future_pto_calc from .hr.future_pto_calc import future_pto_calc
from .hr.checkpaybankstatus import checkpaybankstatus from .hr.checkpaybankstatus import checkpaybankstatus
from .fin.check_account_valid import check_account_valid
from .fin.get_account_balances import get_account_balance
from .give_hint import give_hint from .give_hint import give_hint
from .guess_location import guess_location from .guess_location import guess_location
@@ -44,6 +47,10 @@ def get_handler(tool_name: str):
return future_pto_calc return future_pto_calc
if tool_name == "CheckPayBankStatus": if tool_name == "CheckPayBankStatus":
return checkpaybankstatus return checkpaybankstatus
if tool_name == "FinCheckAccountIsValid":
return check_account_valid
if tool_name == "FinCheckAccountBalance":
return get_account_balance
if tool_name == "GiveHint": if tool_name == "GiveHint":
return give_hint return give_hint
if tool_name == "GuessLocation": if tool_name == "GuessLocation":

View File

@@ -0,0 +1,58 @@
{
"accounts": [
{
"name": "Matt Murdock",
"email": "matt.murdock@nelsonmurdock.com",
"account_id": "11235",
"checking_balance": 875.40,
"savings_balance": 3200.15,
"bitcoin_balance": 0.1378,
"account_creation_date": "2014-03-10"
},
{
"name": "Foggy Nelson",
"email": "foggy.nelson@nelsonmurdock.com",
"account_id": "112358",
"checking_balance": 1523.67,
"savings_balance": 4875.90,
"bitcoin_balance": 0.0923,
"account_creation_date": "2014-03-10"
},
{
"name": "Karen Page",
"email": "karen.page@nelsonmurdock.com",
"account_id": "112",
"checking_balance": 645.25,
"savings_balance": 1830.50,
"bitcoin_balance": 0.0456,
"account_creation_date": "2015-01-15"
},
{
"name": "Wilson Fisk",
"email": "wilson.fisk@fiskcorp.com",
"account_id": "11",
"checking_balance": 25000.00,
"savings_balance": 150000.75,
"bitcoin_balance": 5987.6721,
"account_creation_date": "2013-09-20"
},
{
"name": "Frank Castle",
"email": "frank.castle@vigilante.net",
"account_id": "1",
"checking_balance": 320.10,
"savings_balance": 0.30,
"bitcoin_balance": 15.2189,
"account_creation_date": "2016-02-05"
},
{
"name": "Joshua Smith",
"email": "joshmsmith@gmail.com",
"account_id": "11235813",
"checking_balance": 3021.90,
"savings_balance": 500.50,
"bitcoin_balance": 0.001,
"account_creation_date": "2020-03-19"
}
]
}

View File

@@ -0,0 +1,24 @@
from pathlib import Path
import json
# this is made to demonstrate functionality but it could just as durably be an API call
# called as part of a temporal activity with automatic retries
def check_account_valid(args: dict) -> dict:
email = args.get("email")
account_id = args.get("account_id")
file_path = Path(__file__).resolve().parent.parent / "data" / "customer_account_data.json"
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
account_list = data["accounts"]
for account in account_list:
if account["email"] == email or account["account_id"] == account_id:
return{"status": "account valid"}
return_msg = "Account not found with email address " + email + " or account ID: " + account_id
return {"error": return_msg}

View File

@@ -0,0 +1,24 @@
from pathlib import Path
import json
# this is made to demonstrate functionality but it could just as durably be an API call
# this assumes it's a valid account - use check_account_valid() to verify that first
def get_account_balance(args: dict) -> dict:
account_key = args.get("accountkey")
file_path = Path(__file__).resolve().parent.parent / "data" / "customer_account_data.json"
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
account_list = data["accounts"]
for account in account_list:
if account["email"] == account_key or account["account_id"] == account_key:
#return{"status": "account valid"}
return{ "name": account["name"], "email": account["email"], "account_id": account["account_id"], "checking_balance": account["checking_balance"], "savings_balance": account["savings_balance"], "bitcoin_balance": account["bitcoin_balance"], "account_creation_date": account["account_creation_date"] }
return_msg = "Account not found with email address " + email + " or account ID: " + account_id
return {"error": return_msg}

View File

@@ -248,12 +248,12 @@ goal_hr_check_pto = AgentGoal(
), ),
) )
# This goal uses the data/employee_pto_data.json file as dummy data. # check integration with bank
goal_hr_check_paycheck_bank_integration_status = AgentGoal( goal_hr_check_paycheck_bank_integration_status = AgentGoal(
id = "goal_hr_check_paycheck_bank_integration_status", id = "goal_hr_check_paycheck_bank_integration_status",
category_tag="hr", category_tag="hr",
agent_name="Check paycheck bank integration status", agent_name="Check paycheck bank integration status",
agent_friendly_description="Check your available PTO.", agent_friendly_description="Check your integration between paycheck payer and your financial institution.",
tools=[ tools=[
tool_registry.paycheck_bank_integration_status_check, tool_registry.paycheck_bank_integration_status_check,
tool_registry.list_agents_tool, #last tool must be list_agents to fasciliate changing back to picking an agent again at the end tool_registry.list_agents_tool, #last tool must be list_agents to fasciliate changing back to picking an agent again at the end
@@ -274,6 +274,41 @@ goal_hr_check_paycheck_bank_integration_status = AgentGoal(
), ),
) )
# this tool checks account balances, and uses ./data/customer_account_data.json as dummy data
goal_fin_check_account_balances = AgentGoal(
id = "goal_fin_check_account_balances",
category_tag="fin",
agent_name="Check balances",
agent_friendly_description="Check your account balances in Checking, Savings, etc.",
tools=[
tool_registry.financial_check_account_is_valid,
tool_registry.financial_get_account_balances,
tool_registry.list_agents_tool, #last tool must be list_agents to fasciliate changing back to picking an agent again at the end
],
description="The user wants to check their account balances at the bank or financial institution. To assist with that goal, help the user gather args for these tools in order: "
"1. FinCheckAccountIsValid: validate the user's account is valid"
"2. FinCheckAccountBalance: Tell the user their account balance at the bank or financial institution",
starter_prompt=starter_prompt_generic,
example_conversation_history="\n ".join(
[
"user: I'd like to check my account balances",
"agent: Sure! I can help you out with that. May I have your email address or account number?",
"user: email is bob.johnson@emailzzz.com ",
"user_confirmed_tool_run: <user clicks confirm on FincheckAccountIsValid tool>",
"tool_result: { 'status': account valid }",
"agent: Great! I can tell you what the your account balances are.",
"user_confirmed_tool_run: <user clicks confirm on FinCheckAccountBalance tool>",
"tool_result: { 'name': Matt Murdock, 'email': matt.murdock@nelsonmurdock.com, 'account_id': 11235, 'checking_balance': 875.40, 'savings_balance': 3200.15, 'bitcoin_balance': 0.1378, 'account_creation_date': 2014-03-10 }",
"agent: Your account balances are as follows: \n "
"Checking: $875.40. \n "
"Savings: $3200.15. \n "
"Bitcoint: 0.1378 \n "
"Thanks for being a customer since 2014!",
]
),
)
#todo add money movement, fraud check (update with start)
#Add the goals to a list for more generic processing, like listing available agents #Add the goals to a list for more generic processing, like listing available agents
goal_list: List[AgentGoal] = [] goal_list: List[AgentGoal] = []
goal_list.append(goal_choose_agent_type) goal_list.append(goal_choose_agent_type)
@@ -283,4 +318,6 @@ goal_list.append(goal_match_train_invoice)
goal_list.append(goal_hr_schedule_pto) goal_list.append(goal_hr_schedule_pto)
goal_list.append(goal_hr_check_pto) goal_list.append(goal_hr_check_pto)
goal_list.append(goal_hr_check_paycheck_bank_integration_status) goal_list.append(goal_hr_check_paycheck_bank_integration_status)
goal_list.append(goal_fin_check_account_balances)

View File

@@ -253,3 +253,35 @@ paycheck_bank_integration_status_check = ToolDefinition(
), ),
], ],
) )
financial_check_account_is_valid = ToolDefinition(
name="FinCheckAccountIsValid",
description="Check if an account is valid by email address or account ID. "
"Returns the account status, valid or invalid. ",
arguments=[
ToolArgument(
name="email",
type="string",
description="email address of user",
),
ToolArgument(
name="account_id",
type="string",
description="account ID of user",
),
],
)
financial_get_account_balances = ToolDefinition(
name="FinCheckAccountBalance",
description="Get account balance for your accounts. "
"Returns the account balances of your accounts. ",
arguments=[
ToolArgument(
name="accountkey",
type="string",
description="email address or account ID of user",
),
],
)