Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -35,11 +35,34 @@ MAX_TOOL_CALLS = 5
|
|
35 |
# βββββββββββββββββββββββββββ Helper utilities ββββββββββββββββββββββββββββ
|
36 |
|
37 |
def safe_json(text: str) -> Optional[Dict[str, Any]]:
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
|
45 |
# def brief(d: Dict[str, Any]) -> str:
|
@@ -75,9 +98,9 @@ def tool_selector(state: AgentState) -> AgentState:
|
|
75 |
raw = LLM(state.messages + [prompt]).content.strip()
|
76 |
print(f"Tool selector response: {raw}")
|
77 |
state.add(AIMessage(content=raw))
|
78 |
-
|
79 |
-
parsed = json.loads(raw)
|
80 |
-
print("parsed : ", parsed)
|
81 |
print(f"Parsed: {parsed}")
|
82 |
if not parsed or "action" not in parsed:
|
83 |
state.next_action = "final"
|
|
|
35 |
# βββββββββββββββββββββββββββ Helper utilities ββββββββββββββββββββββββββββ
|
36 |
|
37 |
def safe_json(text: str) -> Optional[Dict[str, Any]]:
|
38 |
+
"""Bestβeffort extractor that tolerates codeβfences and leading commentary.
|
39 |
+
It returns the *first* topβlevel JSON object found in the string or None.
|
40 |
+
"""
|
41 |
+
import re, json
|
42 |
+
|
43 |
+
# Drop markdown codeβfences if present
|
44 |
+
if text.strip().startswith("```"):
|
45 |
+
parts = re.split(r"```+", text.strip(), maxsplit=2)
|
46 |
+
text = parts[1] if len(parts) > 1 else parts[0]
|
47 |
+
|
48 |
+
# Locate the first {...} block at top level
|
49 |
+
brace_stack, start = [], None
|
50 |
+
for i, ch in enumerate(text):
|
51 |
+
if ch == '{':
|
52 |
+
if not brace_stack:
|
53 |
+
start = i
|
54 |
+
brace_stack.append(ch)
|
55 |
+
elif ch == '}' and brace_stack:
|
56 |
+
brace_stack.pop()
|
57 |
+
if not brace_stack and start is not None:
|
58 |
+
candidate = text[start:i+1]
|
59 |
+
try:
|
60 |
+
obj = json.loads(candidate)
|
61 |
+
return obj if isinstance(obj, dict) else None
|
62 |
+
except json.JSONDecodeError:
|
63 |
+
# Keep searching in case there is another block later
|
64 |
+
start = None
|
65 |
+
return None
|
66 |
|
67 |
|
68 |
# def brief(d: Dict[str, Any]) -> str:
|
|
|
98 |
raw = LLM(state.messages + [prompt]).content.strip()
|
99 |
print(f"Tool selector response: {raw}")
|
100 |
state.add(AIMessage(content=raw))
|
101 |
+
parsed = safe_json(raw)
|
102 |
+
# parsed = json.loads(raw)
|
103 |
+
# print("parsed : ", parsed)
|
104 |
print(f"Parsed: {parsed}")
|
105 |
if not parsed or "action" not in parsed:
|
106 |
state.next_action = "final"
|