mirror of
https://github.com/Xe138/AI-Trader.git
synced 2026-04-01 17:17:24 -04:00
fix: extract position dict from CallToolResult.structuredContent
Fix negative cash bug where ContextInjector._current_position never updated. Root cause: MCP tools return mcp.types.CallToolResult objects, not plain dicts. The isinstance(result, dict) check always failed, preventing _current_position from accumulating trades within a session. This caused all trades to calculate from initial $10,000 position instead of previous trade's ending position, resulting in negative cash balances when total purchases exceeded $10,000. Solution: Extract position dict from CallToolResult.structuredContent field before validating. Maintains backward compatibility by handling both CallToolResult objects (production) and plain dicts (unit tests). Impact: - Fixes negative cash positions (e.g., -$8,768.68 after 11 trades) - Enables proper intra-day position tracking - Validates sufficient cash before each trade based on cumulative position - Trade tool responses now properly accumulate all holdings Testing: - All existing unit tests pass (handle plain dict results) - Production logs confirm structuredContent extraction works - Debug logging shows _current_position now updates after each trade
This commit is contained in:
@@ -91,15 +91,25 @@ class ContextInjector:
|
||||
# Debug: Log result type and structure
|
||||
print(f"[DEBUG ContextInjector] Trade result type: {type(result)}")
|
||||
print(f"[DEBUG ContextInjector] Trade result: {result}")
|
||||
print(f"[DEBUG ContextInjector] isinstance(result, dict): {isinstance(result, dict)}")
|
||||
|
||||
# Check if result is a valid position dict (not an error)
|
||||
if isinstance(result, dict) and "error" not in result and "CASH" in result:
|
||||
# Extract position dict from MCP result
|
||||
# MCP tools return CallToolResult objects with structuredContent field
|
||||
position_dict = None
|
||||
if hasattr(result, 'structuredContent') and result.structuredContent:
|
||||
position_dict = result.structuredContent
|
||||
print(f"[DEBUG ContextInjector] Extracted from structuredContent: {position_dict}")
|
||||
elif isinstance(result, dict):
|
||||
position_dict = result
|
||||
print(f"[DEBUG ContextInjector] Using result as dict: {position_dict}")
|
||||
|
||||
# Check if position dict is valid (not an error) and update state
|
||||
if position_dict and "error" not in position_dict and "CASH" in position_dict:
|
||||
# Update our tracked position with the new state
|
||||
self._current_position = result.copy()
|
||||
self._current_position = position_dict.copy()
|
||||
print(f"[DEBUG ContextInjector] Updated _current_position: {self._current_position}")
|
||||
else:
|
||||
print(f"[DEBUG ContextInjector] Did NOT update _current_position - check failed")
|
||||
print(f"[DEBUG ContextInjector] position_dict: {position_dict}")
|
||||
print(f"[DEBUG ContextInjector] _current_position remains: {self._current_position}")
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user