From 79dcd40dded5150a0533b02077a2ab41c40afb88 Mon Sep 17 00:00:00 2001 From: Joshua Smith Date: Sat, 12 Apr 2025 15:41:47 -0400 Subject: [PATCH] well it kinda works --- tools/fin/submit_loan_application.py | 79 ++++++++++++++++------------ tools/goal_registry.py | 4 +- tools/tool_registry.py | 2 +- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/tools/fin/submit_loan_application.py b/tools/fin/submit_loan_application.py index 4aa1e83..4093ec0 100644 --- a/tools/fin/submit_loan_application.py +++ b/tools/fin/submit_loan_application.py @@ -1,8 +1,14 @@ -from datetime import timedelta +from datetime import date, timedelta import os from pathlib import Path import json -from temporalio.client import Client, WorkflowHandle +from temporalio.client import ( + Client, + WithStartWorkflowOperation, + WorkflowHandle, + WorkflowUpdateFailedError, +) +from temporalio import common from dataclasses import dataclass from typing import Optional import asyncio @@ -15,12 +21,13 @@ from shared.config import get_temporal_client @dataclass class TransactionRequest: amount: float - account_id: str + sourceAccount: str + targetAccount: str @dataclass class TxResult: - transaction_id: str - message: str + transactionId: str + status: str #demonstrate starting a workflow and early return pattern while the workflow continues async def submit_loan_application(args: dict) -> dict: @@ -29,7 +36,11 @@ async def submit_loan_application(args: dict) -> dict: loan_status: dict = await start_workflow(amount=amount,account_name=account_key) - return {'status': loan_status.get("loan_status"), 'detailed_status': loan_status.get("results"), 'next_step': loan_status.get("advisement"), 'confirmation_id': loan_status.get("workflowID")} + if loan_status.get("error") is None: + return {'status': loan_status.get("loan_application_status"), 'detailed_status': loan_status.get("application_details"), 'next_step': loan_status.get("advisement"), 'confirmation_id': loan_status.get("transaction_id")} + else: + print(loan_status) + return loan_status # Async function to start workflow @@ -40,55 +51,53 @@ async def start_workflow(amount: str, account_name: str, )-> dict: start_real_workflow = os.getenv("FIN_START_REAL_WORKFLOW") if start_real_workflow is not None and start_real_workflow.lower() == "false": START_REAL_WORKFLOW = False + return {'loan_application_status': "applied", 'application_details': "loan application is submitted and initial validation is complete",'transaction_id': "APPLICATION"+account_name, 'advisement': "You'll receive a confirmation for final approval in three business days", } else: START_REAL_WORKFLOW = True - if START_REAL_WORKFLOW: - # Define the workflow ID and task queue - workflow_id = "APPLICATION-"+account_name + workflow_id = "LOAN_APPLICATION-"+account_name+"-"+date.today().strftime('%Y-%m-%d') task_queue = "LatencyOptimizationTEST" # Create a TransactionRequest (matching the Java workflow's expected input) tx_request = TransactionRequest( amount=float(amount), - account_id=account_name + targetAccount=account_name, + sourceAccount=account_name, ) - #try: - # Use update-with-start to start the workflow and call the update method - handle: WorkflowHandle = await client.start_workflow( - "TransactionWorkflowLocalBeforeUpdate.processTransaction", # Workflow name - tx_request, # Input to the processTransaction method + start_op = WithStartWorkflowOperation( + "TransactionWorkflowLocalBeforeUpdate", + tx_request, id=workflow_id, + id_conflict_policy=common.WorkflowIDConflictPolicy.USE_EXISTING, task_queue=task_queue, - execution_timeout=timedelta(minutes=5), - # Specify the update to call immediately after starting - update="returnInitResult", - update_args=[] # No arguments needed for returnInitResult ) - # Wait for the update result (returnInitResult) - update_result = await handle.result_of_update("returnInitResult") - - # Since the result is a RawValue, we need to deserialize it - # For simplicity, assuming the result is TxResult (adjust based on actual serialization) - #result_dict = update_result.payloads[0].decode() # Simplified; use proper deserialization - tx_result = TxResult( - transaction_id=result_dict.get("transaction_id", ""), - message=result_dict.get("message", "") - ) + try: + print("trying update-with-start") + tx_result = TxResult( + await client.execute_update_with_start_workflow( + "returnInitResult", + start_workflow_operation=start_op, + ) + ) + except WorkflowUpdateFailedError: + print("aww man got exception WorkflowUpdateFailedError" ) + tx_result = None + return_msg = "Loan could not be processed for " + account_name + return {"error": return_msg} - print(f"Update result: Transaction ID = {tx_result.transaction_id}, Message = {tx_result.message}") + workflow_handle = await start_op.workflow_handle() + print(tx_result) + + print(f"Update result: Transaction ID = {tx_result.transactionId}, Message = {tx_result.status}") # Optionally, wait for the workflow to complete and get the final result # final_result = await handle.result() # print(f"Workflow completed with result: {final_result}") - #except Exception as e: - # print(f"Error executing workflow: {e}") - - # return {'status': loan_status.get("loan_status"), 'detailed_status': loan_status.get("results"), 'next_step': loan_status.get("advisement"), 'confirmation_id': loan_status.get("workflowID")} - return {'status': "status", 'detailed_status': "loan application is submitted and initial validation is complete",'confirmation id': "11358", 'next_step': "You'll receive a confirmation for final approval in three business days", } + # return {'status': loan_status.get("loan_status"), 'detailed_status': loan_status.get("results"), 'next_step': loan_status.get("advisement"), 'confirmation_id': loan_status.get("workflowID")} + return {'loan_application_status': "applied", 'application_details': "loan application is submitted and initial validation is complete",'transaction_id': tx_result.transactionId, 'advisement': "You'll receive a confirmation for final approval in three business days", } \ No newline at end of file diff --git a/tools/goal_registry.py b/tools/goal_registry.py index 837f412..95c329f 100644 --- a/tools/goal_registry.py +++ b/tools/goal_registry.py @@ -346,7 +346,7 @@ goal_fin_move_money = AgentGoal( goal_fin_loan_application = AgentGoal( id = "goal_fin_loan_application", category_tag="fin", - agent_name="Loan Application", + agent_name="Easy Loan Apply", agent_friendly_description="Initiate loan application.", tools=[ tool_registry.financial_check_account_is_valid, @@ -367,7 +367,7 @@ goal_fin_loan_application = AgentGoal( "user: I'd like a loan for $500", "user_confirmed_tool_run: ", "tool_result: { 'status': submitted, 'detailed_status': loan application is submitted and initial validation is complete, 'confirmation id': 333421, 'next_step': You'll receive a confirmation for final approval in three business days }", - "agent: I have submitted your loan application process and the initial validation is successful. You'll receive a confirmation from us in three business days. " + "agent: I have submitted your loan application process and the initial validation is successful. Your application ID is 333421. You'll receive a notification for final approval from us in three business days. " ] ), ) diff --git a/tools/tool_registry.py b/tools/tool_registry.py index c0805fd..c9b601b 100644 --- a/tools/tool_registry.py +++ b/tools/tool_registry.py @@ -318,7 +318,7 @@ financial_move_money = ToolDefinition( ], ) -financial_move_money = ToolDefinition( +financial_submit_loan_approval = ToolDefinition( name="FinCheckAccountSubmitLoanApproval", description="Submit a loan application. " "Returns the loan status. ",