AshokGakr commited on
Commit
db1e4cb
Β·
verified Β·
1 Parent(s): ac314a2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -43
app.py CHANGED
@@ -483,15 +483,20 @@ You are **GAKR AI**, an expert assistant specializing in depth-calibrated respon
483
  def normalize_tool_name(name: str) -> str:
484
  if not name:
485
  return ""
 
486
  normalized = name.strip().lower().replace(" ", "_").replace("-", "_")
 
 
 
487
  if normalized == "websearch":
488
  return "web_search"
489
  return normalized
490
 
491
  def parse_tool_call(text: str) -> Optional[Dict[str, Any]]:
492
- # ==== ENHANCED DETECTOR: Handle incomplete tool calls ====
493
  # When <|tool_call_start|> is detected, it's 100% confirmation of a tool call
494
  # The model may not always generate <|tool_call_end|>, so we extract what we can
 
495
 
496
  if "<|tool_call_start|>" in text:
497
  start_pos = text.find("<|tool_call_start|>") + len("<|tool_call_start|>")
@@ -503,24 +508,27 @@ You are **GAKR AI**, an expert assistant specializing in depth-calibrated respon
503
  print(f"πŸ” [PARSE] Complete token pair detected. Payload: {payload[:80]}")
504
  else:
505
  # Case 2: Incomplete - only start token, extract what we have
506
- # Look for the tool call pattern: [web_search(...)] or web_search(...)
507
  remaining = text[start_pos:].strip()
508
  print(f"πŸ” [PARSE] Incomplete token pair. Remaining buffer: {remaining[:80]}")
 
509
 
510
- # Try to extract from brackets first: [web_search(query="...")]
511
- bracket_match = re.search(r'\[([a-zA-Z_]\w*)\s*\((.*?)\)\]', remaining)
 
512
  if bracket_match:
513
- payload = f"{bracket_match.group(1)}({bracket_match.group(2)})"
514
- print(f"πŸ” [PARSE] Extracted from brackets: {payload}")
 
 
515
  else:
516
- # Try bare function call: web_search(query="...")
517
- func_match = re.search(r'([a-zA-Z_]\w*)\s*\((.*?)\)', remaining)
 
518
  if func_match:
519
- # Extract until first complete closing paren
520
- func_name = func_match.group(1)
521
- args_part = func_match.group(2)
522
- payload = f"{func_name}({args_part})"
523
- print(f"πŸ” [PARSE] Extracted bare function: {payload}")
524
  else:
525
  print(f"⚠️ [PARSE] Could not extract tool call from: {remaining[:50]}")
526
  return None
@@ -543,9 +551,11 @@ You are **GAKR AI**, an expert assistant specializing in depth-calibrated respon
543
  if clean_payload.startswith("[") and clean_payload.endswith("]"):
544
  clean_payload = clean_payload[1:-1].strip()
545
 
546
- m = re.match(r"^([a-zA-Z_]\w*)\s*\((.*)\)\s*$", clean_payload)
547
  if m:
548
- name = normalize_tool_name(m.group(1))
 
 
549
  args_str = m.group(2).strip()
550
  args: Dict[str, Any] = {}
551
 
@@ -576,38 +586,33 @@ You are **GAKR AI**, an expert assistant specializing in depth-calibrated respon
576
  if isinstance(tc, dict) and "name" in tc and "args" in tc:
577
  return {"name": normalize_tool_name(tc.get("name", "")), "args": tc.get("args", {})}
578
 
579
- # 3) Bare Pythonic call without special tokens (fallback)
580
  stripped = text.strip()
581
  raw = stripped
582
  if raw.startswith("[") and raw.endswith("]"):
583
  raw = raw[1:-1].strip()
584
- if raw.startswith("web_search(") and raw.endswith(")"):
585
- args_str = raw[len("web_search("):-1].strip()
586
- args: Dict[str, Any] = {}
587
- mq = re.search(r'query\s*=\s*\"(.*?)\"|query\s*=\s*\'(.*?)\'', args_str)
588
- if mq:
589
- args["query"] = mq.group(1) or mq.group(2) or ""
590
- else:
591
- mpos = re.match(r'^\"(.*)\"$|^\'(.*)\'$', args_str)
592
- if mpos:
593
- pos = mpos.group(1) or mpos.group(2)
594
- if pos is not None:
595
- args["query"] = pos
596
- return {"name": "web_search", "args": args}
597
-
598
- if raw.startswith("websearch(") and raw.endswith(")"):
599
- args_str = raw[len("websearch("):-1].strip()
600
- args: Dict[str, Any] = {}
601
- mq = re.search(r'query\s*=\s*\"(.*?)\"|query\s*=\s*\'(.*?)\'', args_str)
602
- if mq:
603
- args["query"] = mq.group(1) or mq.group(2) or ""
604
- else:
605
- mpos = re.match(r'^\"(.*)\"$|^\'(.*)\'$', args_str)
606
- if mpos:
607
- pos = mpos.group(1) or mpos.group(2)
608
- if pos is not None:
609
- args["query"] = pos
610
- return {"name": "web_search", "args": args}
611
 
612
  return None
613
 
 
483
  def normalize_tool_name(name: str) -> str:
484
  if not name:
485
  return ""
486
+ # Remove spaces, convert to lowercase, normalize underscores
487
  normalized = name.strip().lower().replace(" ", "_").replace("-", "_")
488
+ # Handle variations: "web search", "websearch", "web_search" -> "web_search"
489
+ if "web" in normalized and "search" in normalized:
490
+ return "web_search"
491
  if normalized == "websearch":
492
  return "web_search"
493
  return normalized
494
 
495
  def parse_tool_call(text: str) -> Optional[Dict[str, Any]]:
496
+ # ==== ENHANCED DETECTOR: Handle incomplete tool calls & variations ====
497
  # When <|tool_call_start|> is detected, it's 100% confirmation of a tool call
498
  # The model may not always generate <|tool_call_end|>, so we extract what we can
499
+ # Also handles variations like "web_ Search" (with space/case variations)
500
 
501
  if "<|tool_call_start|>" in text:
502
  start_pos = text.find("<|tool_call_start|>") + len("<|tool_call_start|>")
 
508
  print(f"πŸ” [PARSE] Complete token pair detected. Payload: {payload[:80]}")
509
  else:
510
  # Case 2: Incomplete - only start token, extract what we have
 
511
  remaining = text[start_pos:].strip()
512
  print(f"πŸ” [PARSE] Incomplete token pair. Remaining buffer: {remaining[:80]}")
513
+ payload = None
514
 
515
+ # Try to extract from brackets first: [web_search(...)] or [web_ Search(...)]
516
+ # Pattern: [word(args)] - allowing for spaces and case variations
517
+ bracket_match = re.search(r'\[([a-zA-Z_\s]+?)\s*\((.*?)\)\s*\]', remaining)
518
  if bracket_match:
519
+ func_base = bracket_match.group(1).replace(" ", "_").lower() # Normalize spaces
520
+ func_args = bracket_match.group(2)
521
+ payload = f"{func_base}({func_args})"
522
+ print(f"πŸ” [PARSE] Extracted from brackets (normalized): {payload}")
523
  else:
524
+ # Try bare function call: web_search(...) or web_ Search(...)
525
+ # Allow for spaces: web_ search, web_search, etc.
526
+ func_match = re.search(r'([a-zA-Z_]+(?:\s+[a-zA-Z_]+)?)\s*\((.*?)\)', remaining)
527
  if func_match:
528
+ func_base = func_match.group(1).replace(" ", "_").lower() # Normalize spaces
529
+ func_args = func_match.group(2)
530
+ payload = f"{func_base}({func_args})"
531
+ print(f"πŸ” [PARSE] Extracted bare function (normalized): {payload}")
 
532
  else:
533
  print(f"⚠️ [PARSE] Could not extract tool call from: {remaining[:50]}")
534
  return None
 
551
  if clean_payload.startswith("[") and clean_payload.endswith("]"):
552
  clean_payload = clean_payload[1:-1].strip()
553
 
554
+ m = re.match(r"^([a-zA-Z_]+(?:\s+[a-zA-Z_]+)?)\s*\((.*)\)\s*$", clean_payload)
555
  if m:
556
+ # Normalize function name: remove spaces, convert to lowercase
557
+ name_raw = m.group(1)
558
+ name = normalize_tool_name(name_raw)
559
  args_str = m.group(2).strip()
560
  args: Dict[str, Any] = {}
561
 
 
586
  if isinstance(tc, dict) and "name" in tc and "args" in tc:
587
  return {"name": normalize_tool_name(tc.get("name", "")), "args": tc.get("args", {})}
588
 
589
+ # 3) Bare Pythonic call without special tokens (fallback) - also handle spacing
590
  stripped = text.strip()
591
  raw = stripped
592
  if raw.startswith("[") and raw.endswith("]"):
593
  raw = raw[1:-1].strip()
594
+
595
+ # Handle: web_search(...), web_Search(...), web_ search(...), etc.
596
+ bare_match = re.match(r'([a-zA-Z_]+(?:\s+[a-zA-Z_]+)?)\s*\((.*?)\)\s*$', raw)
597
+ if bare_match:
598
+ func_name_raw = bare_match.group(1)
599
+ func_name = normalize_tool_name(func_name_raw)
600
+
601
+ # Only process if it's a recognized tool (web_search)
602
+ if func_name == "web_search":
603
+ args_str = bare_match.group(2).strip()
604
+ args: Dict[str, Any] = {}
605
+ mq = re.search(r'query\s*=\s*\"(.*?)\"|query\s*=\s*\'(.*?)\'', args_str)
606
+ if mq:
607
+ args["query"] = mq.group(1) or mq.group(2) or ""
608
+ else:
609
+ mpos = re.match(r'^\"(.*)\"$|^\'(.*)\'$', args_str)
610
+ if mpos:
611
+ pos = mpos.group(1) or mpos.group(2)
612
+ if pos is not None:
613
+ args["query"] = pos
614
+ print(f"βœ… [PARSE] Bare tool call found: {func_name}({args})")
615
+ return {"name": func_name, "args": args}
 
 
 
 
 
616
 
617
  return None
618