diff --git a/samples/python/src/roles/shopping_agent/subagents/shopper/tools.py b/samples/python/src/roles/shopping_agent/subagents/shopper/tools.py index cee16eff..aff52646 100644 --- a/samples/python/src/roles/shopping_agent/subagents/shopper/tools.py +++ b/samples/python/src/roles/shopping_agent/subagents/shopper/tools.py @@ -65,7 +65,8 @@ def create_intent_mandate( datetime.now(timezone.utc) + timedelta(days=1) ).isoformat(), ) - tool_context.state["intent_mandate"] = intent_mandate + # Store as dict to ensure JSON serialization compatibility with ADK session storage + tool_context.state["intent_mandate"] = intent_mandate.model_dump() return intent_mandate @@ -93,7 +94,7 @@ async def find_products( message = ( A2aMessageBuilder() .add_text("Find products that match the user's IntentMandate.") - .add_data(INTENT_MANDATE_DATA_KEY, intent_mandate.model_dump()) + .add_data(INTENT_MANDATE_DATA_KEY, intent_mandate) .add_data("risk_data", risk_data) .add_data("debug_mode", debug_mode) .add_data("shopping_agent_id", "trusted_shopping_agent") @@ -106,7 +107,8 @@ async def find_products( tool_context.state["shopping_context_id"] = task.context_id cart_mandates = _parse_cart_mandates(task.artifacts) - tool_context.state["cart_mandates"] = cart_mandates + # Store as list of dicts for JSON serialization compatibility + tool_context.state["cart_mandates"] = [cm.model_dump() for cm in cart_mandates] return cart_mandates @@ -117,7 +119,11 @@ def update_chosen_cart_mandate(cart_id: str, tool_context: ToolContext) -> str: cart_id: The ID of the chosen cart. tool_context: The ADK supplied tool context. """ - cart_mandates: list[CartMandate] = tool_context.state.get("cart_mandates", []) + cart_mandates_data = tool_context.state.get("cart_mandates", []) + # Reconstruct CartMandate objects from stored dicts + cart_mandates: list[CartMandate] = [] + for cm in cart_mandates_data: + cart_mandates.append(CartMandate.model_validate(cm)) for cart in cart_mandates: print( f"Checking cart with ID: {cart.contents.id} with chosen ID: {cart_id}" diff --git a/samples/python/src/roles/shopping_agent/tools.py b/samples/python/src/roles/shopping_agent/tools.py index 1d8b7bf1..455194a3 100644 --- a/samples/python/src/roles/shopping_agent/tools.py +++ b/samples/python/src/roles/shopping_agent/tools.py @@ -76,7 +76,8 @@ async def update_cart( _parse_cart_mandates(task.artifacts) ) - tool_context.state["cart_mandate"] = updated_cart_mandate + # Store as dict for JSON serialization compatibility + tool_context.state["cart_mandate"] = updated_cart_mandate.model_dump() tool_context.state["shipping_address"] = shipping_address return updated_cart_mandate @@ -163,7 +164,8 @@ def store_receipt_if_present(task, tool_context: ToolContext) -> None: ) if payment_receipts: payment_receipt = artifact_utils.only(payment_receipts) - tool_context.state["payment_receipt"] = payment_receipt + # Store as dict for JSON serialization compatibility + tool_context.state["payment_receipt"] = payment_receipt.model_dump() def create_payment_mandate( @@ -181,7 +183,9 @@ def create_payment_mandate( Returns: The payment mandate. """ - cart_mandate = tool_context.state["cart_mandate"] + cart_mandate_data = tool_context.state["cart_mandate"] + # Reconstruct CartMandate from stored dict + cart_mandate = CartMandate.model_validate(cart_mandate_data) payment_request = cart_mandate.contents.payment_request shipping_address = tool_context.state["shipping_address"] @@ -215,7 +219,8 @@ def create_payment_mandate( ), ) - tool_context.state["payment_mandate"] = payment_mandate + # Store as dict for JSON serialization compatibility + tool_context.state["payment_mandate"] = payment_mandate.model_dump() return payment_mandate @@ -238,8 +243,11 @@ def sign_mandates_on_user_device(tool_context: ToolContext) -> str: Returns: A string representing the simulated user authorization signature (JWT). """ - payment_mandate: PaymentMandate = tool_context.state["payment_mandate"] - cart_mandate: CartMandate = tool_context.state["cart_mandate"] + payment_mandate_data = tool_context.state["payment_mandate"] + cart_mandate_data = tool_context.state["cart_mandate"] + # Reconstruct Pydantic objects from stored dicts + payment_mandate = PaymentMandate.model_validate(payment_mandate_data) + cart_mandate = CartMandate.model_validate(cart_mandate_data) cart_mandate_hash = _generate_cart_mandate_hash(cart_mandate) payment_mandate_hash = _generate_payment_mandate_hash( payment_mandate.payment_mandate_contents @@ -250,7 +258,8 @@ def sign_mandates_on_user_device(tool_context: ToolContext) -> str: payment_mandate.user_authorization = ( cart_mandate_hash + "_" + payment_mandate_hash ) - tool_context.state["signed_payment_mandate"] = payment_mandate + # Store as dict for JSON serialization compatibility + tool_context.state["signed_payment_mandate"] = payment_mandate.model_dump() return payment_mandate.user_authorization