gabejavitt commited on
Commit
0dcd1e4
Β·
verified Β·
1 Parent(s): 25dda14

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -9
app.py CHANGED
@@ -816,6 +816,7 @@ class ChessAnalysisInput(BaseModel):
816
  image_path: str = Field(description="Path to chess board image file")
817
  description: str = Field(description="Any additional context about the position (optional)", default="")
818
 
 
819
  @tool(args_schema=ChessAnalysisInput)
820
  def analyze_chess_position(image_path: str, description: str = "") -> str:
821
  """
@@ -832,6 +833,10 @@ def analyze_chess_position(image_path: str, description: str = "") -> str:
832
  - An image file shows a chess board
833
  - Need to find the best move in a position
834
 
 
 
 
 
835
  Returns: Best move in algebraic notation (e.g., "Qh5", "Nf6+", "Rd5")
836
  """
837
  if not image_path:
@@ -879,27 +884,49 @@ def analyze_chess_position(image_path: str, description: str = "") -> str:
879
  temperature=0
880
  )
881
 
882
- fen_prompt = """Analyze this chess board image and provide the position in FEN notation.
 
 
 
 
 
 
 
 
 
883
 
884
  CRITICAL INSTRUCTIONS:
885
  1. Carefully identify each piece:
886
  - White pieces (UPPERCASE): K=King, Q=Queen, R=Rook, B=Bishop, N=Knight, P=Pawn
887
  - Black pieces (lowercase): k, q, r, b, n, p
888
 
889
- 2. Read the board from rank 8 (top) to rank 1 (bottom), left to right
 
 
 
 
 
 
 
 
 
 
 
890
  - Use numbers (1-8) for consecutive empty squares
891
  - Use '/' to separate ranks
 
 
892
 
893
- 3. Determine whose turn it is:
894
- - Look for text like "Black to move" or "White to move"
895
- - If unclear, analyze the position context
896
- - Return 'w' for white, 'b' for black
897
-
898
- 4. Return ONLY the FEN string in this format:
899
  piece_placement active_color castling en_passant halfmove fullmove
900
-
901
  Example: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
902
 
 
 
 
 
 
903
  Return ONLY the FEN string, nothing else."""
904
 
905
  message = HumanMessage(
@@ -931,6 +958,40 @@ Return ONLY the FEN string, nothing else."""
931
 
932
  print(f"βœ“ Extracted FEN: {fen}")
933
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
934
  # ====================================================================
935
  # STEP 2: Validate FEN with python-chess
936
  # ====================================================================
 
816
  image_path: str = Field(description="Path to chess board image file")
817
  description: str = Field(description="Any additional context about the position (optional)", default="")
818
 
819
+ @tool(args_schema=ChessAnalysisInput)
820
  @tool(args_schema=ChessAnalysisInput)
821
  def analyze_chess_position(image_path: str, description: str = "") -> str:
822
  """
 
833
  - An image file shows a chess board
834
  - Need to find the best move in a position
835
 
836
+ Args:
837
+ image_path: Path to chess board image
838
+ description: The full question text - IMPORTANT for determining whose turn it is!
839
+
840
  Returns: Best move in algebraic notation (e.g., "Qh5", "Nf6+", "Rd5")
841
  """
842
  if not image_path:
 
884
  temperature=0
885
  )
886
 
887
+ # Check if the question explicitly states whose turn it is
888
+ whose_turn = None
889
+ if description:
890
+ desc_lower = description.lower()
891
+ if "black" in desc_lower and ("turn" in desc_lower or "move" in desc_lower):
892
+ whose_turn = "b"
893
+ elif "white" in desc_lower and ("turn" in desc_lower or "move" in desc_lower):
894
+ whose_turn = "w"
895
+
896
+ fen_prompt = f"""Analyze this chess board image and provide the position in FEN notation.
897
 
898
  CRITICAL INSTRUCTIONS:
899
  1. Carefully identify each piece:
900
  - White pieces (UPPERCASE): K=King, Q=Queen, R=Rook, B=Bishop, N=Knight, P=Pawn
901
  - Black pieces (lowercase): k, q, r, b, n, p
902
 
903
+ 2. BOARD ORIENTATION - This is CRITICAL:
904
+ - In chess diagrams, the board is shown from the perspective of the player to move
905
+ - Look at the BOTTOM rank (closest to viewer):
906
+ * If bottom pieces are BLACK (lowercase in FEN) β†’ Black to move β†’ active color = 'b'
907
+ * If bottom pieces are WHITE (uppercase in FEN) β†’ White to move β†’ active color = 'w'
908
+ - The rank labels (1-8) on the side can help:
909
+ * If rank 8 is at bottom and rank 1 at top β†’ Black's perspective β†’ use 'b'
910
+ * If rank 1 is at bottom and rank 8 at top β†’ White's perspective β†’ use 'w'
911
+ {"- OVERRIDE: The question explicitly states BLACK's turn, so use 'b'" if whose_turn == "b" else ""}
912
+ {"- OVERRIDE: The question explicitly states WHITE's turn, so use 'w'" if whose_turn == "w" else ""}
913
+
914
+ 3. FEN Format (read from rank 8 to rank 1, left to right):
915
  - Use numbers (1-8) for consecutive empty squares
916
  - Use '/' to separate ranks
917
+ - IMPORTANT: Always write FEN from White's perspective (rank 8 first, rank 1 last)
918
+ - But set the active_color based on whose perspective the board shows
919
 
920
+ 4. Return ONLY the FEN string in this exact format:
 
 
 
 
 
921
  piece_placement active_color castling en_passant halfmove fullmove
922
+
923
  Example: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
924
 
925
+ DOUBLE-CHECK:
926
+ - Did you identify whose pieces are at the BOTTOM of the board?
927
+ - Did you set active_color correctly based on board orientation?
928
+ - Did you write piece_placement from rank 8 to rank 1?
929
+
930
  Return ONLY the FEN string, nothing else."""
931
 
932
  message = HumanMessage(
 
958
 
959
  print(f"βœ“ Extracted FEN: {fen}")
960
 
961
+ # Override the turn indicator if we know from the question
962
+ if whose_turn:
963
+ fen_parts = fen.split()
964
+ if len(fen_parts) >= 2:
965
+ old_turn = fen_parts[1]
966
+ fen_parts[1] = whose_turn
967
+ fen = ' '.join(fen_parts)
968
+ print(f"πŸ”„ Corrected turn from '{old_turn}' to '{whose_turn}' based on question")
969
+ print(f"βœ“ Corrected FEN: {fen}")
970
+
971
+ # Additional verification: Check if board orientation matches turn
972
+ # In FEN, rank 8 is first, rank 1 is last
973
+ # If bottom of image shows black pieces, it's black's turn
974
+ fen_parts = fen.split()
975
+ piece_placement = fen_parts[0]
976
+ active_color = fen_parts[1] if len(fen_parts) > 1 else 'w'
977
+
978
+ # Get last rank (rank 1 in FEN, which is bottom if white's perspective)
979
+ ranks = piece_placement.split('/')
980
+ rank_1 = ranks[-1] # Last rank in FEN
981
+ rank_8 = ranks[0] # First rank in FEN
982
+
983
+ # Check which color dominates bottom rank
984
+ # If showing from black's perspective, rank 8 should be at bottom
985
+ # and active color should be 'b'
986
+ black_pieces_in_rank8 = sum(1 for c in rank_8 if c.islower() and c.isalpha())
987
+ white_pieces_in_rank8 = sum(1 for c in rank_8 if c.isupper() and c.isalpha())
988
+
989
+ if black_pieces_in_rank8 > white_pieces_in_rank8 and active_color == 'w':
990
+ print(f"⚠️ Warning: Rank 8 has more black pieces, likely black's perspective")
991
+ print(f" Changing active color from 'w' to 'b'")
992
+ fen_parts[1] = 'b'
993
+ fen = ' '.join(fen_parts)
994
+
995
  # ====================================================================
996
  # STEP 2: Validate FEN with python-chess
997
  # ====================================================================