mirror of
https://github.com/temporal-community/temporal-ai-agent.git
synced 2026-03-15 14:08:08 +01:00
adding fin goals and tools
This commit is contained in:
@@ -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
|
||||||
@@ -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
17
todo.md
@@ -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 customer’s 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 customer’s 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 agent’s performance <br />
|
- Insight into the agent’s 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 />
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
58
tools/data/customer_account_data.json
Normal file
58
tools/data/customer_account_data.json
Normal 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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
24
tools/fin/check_account_valid.py
Normal file
24
tools/fin/check_account_valid.py
Normal 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}
|
||||||
24
tools/fin/get_account_balances.py
Normal file
24
tools/fin/get_account_balances.py
Normal 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}
|
||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -252,4 +252,36 @@ paycheck_bank_integration_status_check = ToolDefinition(
|
|||||||
description="email address of user",
|
description="email address of user",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
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",
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
Reference in New Issue
Block a user