Sandiago21 commited on
Commit
2b5f879
·
verified ·
1 Parent(s): d65b9e1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +11 -209
app.py CHANGED
@@ -43,15 +43,15 @@ class Config(object):
43
  self.reasoning_max_len = 128
44
  self.temperature = 0.1
45
  self.DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
46
- self.model_name = "mistralai/Mistral-7B-Instruct-v0.2"
47
  # self.model_name = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"
48
  # self.reasoning_model_name = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"
49
  # self.reasoning_model_name = "Qwen/Qwen2.5-7B-Instruct"
50
  # self.reasoning_model_name = "mistralai/Mistral-7B-Instruct-v0.2"
51
 
52
-
53
  config = Config()
54
 
 
55
  tokenizer = AutoTokenizer.from_pretrained(config.model_name)
56
  model = AutoModelForCausalLM.from_pretrained(
57
  config.model_name,
@@ -357,207 +357,6 @@ def web_search(query: str, num_results: int = 10):
357
  return [a.get("href") for a in soup.select(".result__a")[:num_results]]
358
 
359
 
360
- def planner_node(state: AgentState):
361
- """
362
- Planning node for a tool-using LLM agent.
363
-
364
- The planner enforces:
365
- - Strict JSON-only output
366
- - Tool selection constrained to predefined tools
367
- - Argument generation limited to user-provided information
368
-
369
- Parameters
370
- ----------
371
- state : dict
372
- Agent state dictionary containing:
373
- - "messages" (str): The user's natural language request.
374
-
375
- Returns
376
- -------
377
- dict
378
- Updated state dictionary with additional keys:
379
- - "proposed_action" (dict): Parsed JSON tool call in the form:
380
- {
381
- "tool": "<tool_name>",
382
- "args": {...}
383
- }
384
- - "risk_score" (float): Initialized risk score (default 0.0).
385
- - "decision" (str): Initial decision ("allow" by default).
386
-
387
- Behavior
388
- --------
389
- 1. Constructs a planning prompt including:
390
- - Available tools and allowed arguments
391
- - Strict JSON formatting requirements
392
- - Example of valid output
393
- 2. Calls the language model via `generate()`.
394
- 3. Attempts to extract valid JSON from the model output.
395
- 4. Repairs malformed JSON using `repair_json`.
396
- 5. Stores the parsed action into the agent state.
397
-
398
- Security Notes
399
- --------------
400
- - This node does not enforce tool-level authorization.
401
- - It does not validate hallucinated tools.
402
- - It does not perform risk scoring beyond initializing values.
403
- - Downstream nodes must implement:
404
- * Tool whitelist validation
405
- * Argument validation
406
- * Risk scoring and mitigation
407
- * Execution authorization
408
-
409
- Intended Usage
410
- --------------
411
- Designed for multi-agent or LangGraph-style workflows where:
412
- Planner → Risk Assessment → Tool Executor → Logger
413
-
414
- This node represents the *planning layer* of the agent architecture.
415
- """
416
-
417
- user_input = state["messages"][-1].content
418
-
419
- prompt = f"""
420
- You are a planning agent.
421
-
422
- You MUST return ONLY valid JSON as per the tools specs below ONLY.
423
- No extra text.
424
- DO NOT invent anything additional beyond the user request provided. Keep it strict to the user request information provided. The question and the query should be fully relevant to the user request provided, no deviation and hallucination. If possible and makes sense then the query should be exactly the user request.
425
-
426
- The available tools and their respective arguments are: {{
427
- "web_search": ["query"],
428
- "visit_webpage": ["url"],
429
- }}
430
-
431
- Return exactly the following format:
432
- Response:
433
- {{
434
- "tool": "...",
435
- "args": {{...}}
436
- }}
437
-
438
- User request: Who nominated the only Featured Article on English Wikipedia about a dinosaur that was promoted in November 2016?. Example of valid JSON expected:
439
- Response:
440
- {{"tool": "web_search",
441
- "args": {{"query": "Who nominated the only Featured Article on English Wikipedia about a dinosaur that was promoted in November 2016?",
442
- }}
443
- }}
444
-
445
- Return only one Response!
446
-
447
- User request:
448
- {user_input}
449
- """
450
-
451
- output = generate(prompt)
452
-
453
- state["proposed_action"] = output.split("Response:")[-1]
454
- fixed = repair_json(state["proposed_action"])
455
- data = json.loads(fixed)
456
- state["proposed_action"] = data
457
-
458
- return state
459
-
460
- def planner_node(state: AgentState):
461
- """
462
- Planning node for a tool-using LLM agent.
463
-
464
- The planner enforces:
465
- - Strict JSON-only output
466
- - Tool selection constrained to predefined tools
467
- - Argument generation limited to user-provided information
468
-
469
- Parameters
470
- ----------
471
- state : dict
472
- Agent state dictionary containing:
473
- - "messages" (str): The user's natural language request.
474
-
475
- Returns
476
- -------
477
- dict
478
- Updated state dictionary with additional keys:
479
- - "proposed_action" (dict): Parsed JSON tool call in the form:
480
- {
481
- "tool": "<tool_name>",
482
- "args": {...}
483
- }
484
- - "risk_score" (float): Initialized risk score (default 0.0).
485
- - "decision" (str): Initial decision ("allow" by default).
486
-
487
- Behavior
488
- --------
489
- 1. Constructs a planning prompt including:
490
- - Available tools and allowed arguments
491
- - Strict JSON formatting requirements
492
- - Example of valid output
493
- 2. Calls the language model via `generate()`.
494
- 3. Attempts to extract valid JSON from the model output.
495
- 4. Repairs malformed JSON using `repair_json`.
496
- 5. Stores the parsed action into the agent state.
497
-
498
- Security Notes
499
- --------------
500
- - This node does not enforce tool-level authorization.
501
- - It does not validate hallucinated tools.
502
- - It does not perform risk scoring beyond initializing values.
503
- - Downstream nodes must implement:
504
- * Tool whitelist validation
505
- * Argument validation
506
- * Risk scoring and mitigation
507
- * Execution authorization
508
-
509
- Intended Usage
510
- --------------
511
- Designed for multi-agent or LangGraph-style workflows where:
512
- Planner → Risk Assessment → Tool Executor → Logger
513
-
514
- This node represents the *planning layer* of the agent architecture.
515
- """
516
-
517
- user_input = state["messages"][-1].content
518
-
519
- prompt = f"""
520
- You are a planning agent.
521
-
522
- You MUST return ONLY valid JSON as per the tools specs below ONLY.
523
- No extra text.
524
- DO NOT invent anything additional beyond the user request provided. Keep it strict to the user request information provided. The question and the query should be fully relevant to the user request provided, no deviation and hallucination. If possible and makes sense then the query should be exactly the user request.
525
-
526
- The available tools and their respective arguments are: {{
527
- "web_search": ["query"],
528
- "visit_webpage": ["url"],
529
- }}
530
-
531
- Return exactly the following format:
532
- Response:
533
- {{
534
- "tool": "...",
535
- "args": {{...}}
536
- }}
537
-
538
- User request: Who nominated the only Featured Article on English Wikipedia about a dinosaur that was promoted in November 2016?. Example of valid JSON expected:
539
- Response:
540
- {{"tool": "web_search",
541
- "args": {{"query": "Who nominated the only Featured Article on English Wikipedia about a dinosaur that was promoted in November 2016?",
542
- }}
543
- }}
544
-
545
- Return only one Response!
546
-
547
- User request:
548
- {user_input}
549
- """
550
-
551
- output = generate(prompt)
552
-
553
- state["proposed_action"] = output.split("Response:")[-1]
554
- fixed = repair_json(state["proposed_action"])
555
- data = json.loads(fixed)
556
- state["proposed_action"] = data
557
-
558
- return state
559
-
560
-
561
  def planner_node(state: AgentState):
562
  """
563
  Planning node for a tool-using LLM agent.
@@ -672,12 +471,14 @@ You are a response agent.
672
 
673
  You must reason over the user request and the provided information and output the answer to the user's request. Reason well over the information provided, if any, and output the answer that satisfies the user's question exactly.
674
 
675
- You MUST return EXACTLY one line in the following format:
676
  Response: <answer>
677
 
678
- DO NOT invent anything additional and return only what is asked and in the format asked.
 
 
679
 
680
- Only return a response if you are confident about the answer, otherwise return empty string.
681
 
682
  Example of valid json response for user request: Who was the winner of 2025 World Snooker Championship:
683
  Response: Zhao Xintong.
@@ -698,6 +499,7 @@ Information:
698
  logger.info(f"Raw Output: {raw_output}")
699
 
700
  output = raw_output.split("Response:")[-1].strip()
 
701
  # match = re.search(r"Response:\s*(.*)", raw_output, re.IGNORECASE)
702
  # output = match.group(1).strip() if match else ""
703
 
@@ -970,8 +772,8 @@ class BasicAgent:
970
 
971
 
972
  # if question == "Given this table defining * on the set S = {a, b, c, d, e}\n\n|*|a|b|c|d|e|\n|---|---|---|---|---|---|\n|a|a|b|c|b|d|\n|b|b|c|a|e|c|\n|c|c|a|b|b|a|\n|d|b|e|b|e|d|\n|e|d|b|a|d|c|\n\nprovide the subset of S involved in any possible counter-examples that prove * is not commutative. Provide your answer as a comma separated list of the elements in the set in alphabetical order.":
973
- if " image " not in question and " video " not in question:
974
- # if question == "Who nominated the only Featured Article on English Wikipedia about a dinosaur that was promoted in November 2016?":
975
  state = {
976
  "messages": question,
977
  }
@@ -982,7 +784,7 @@ class BasicAgent:
982
  agent_answer = response["output"]
983
  except:
984
  agent_answer = ""
985
-
986
  else:
987
  agent_answer = fixed_answer
988
  # agent_answer = self.agent.run(question)
 
43
  self.reasoning_max_len = 128
44
  self.temperature = 0.1
45
  self.DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
46
+ self.model_name = "Qwen/Qwen2.5-7B-Instruct"
47
  # self.model_name = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"
48
  # self.reasoning_model_name = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"
49
  # self.reasoning_model_name = "Qwen/Qwen2.5-7B-Instruct"
50
  # self.reasoning_model_name = "mistralai/Mistral-7B-Instruct-v0.2"
51
 
 
52
  config = Config()
53
 
54
+
55
  tokenizer = AutoTokenizer.from_pretrained(config.model_name)
56
  model = AutoModelForCausalLM.from_pretrained(
57
  config.model_name,
 
357
  return [a.get("href") for a in soup.select(".result__a")[:num_results]]
358
 
359
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  def planner_node(state: AgentState):
361
  """
362
  Planning node for a tool-using LLM agent.
 
471
 
472
  You must reason over the user request and the provided information and output the answer to the user's request. Reason well over the information provided, if any, and output the answer that satisfies the user's question exactly.
473
 
474
+ You MUST ONLY return EXACTLY the answer to the user's question in the following format:
475
  Response: <answer>
476
 
477
+ DO NOT add anything additional and return ONLY what is asked and in the format asked.
478
+
479
+ ONLY return a response if you are confident about the answer, otherwise return empty string.
480
 
481
+ If you output anything else, it is incorrect.
482
 
483
  Example of valid json response for user request: Who was the winner of 2025 World Snooker Championship:
484
  Response: Zhao Xintong.
 
499
  logger.info(f"Raw Output: {raw_output}")
500
 
501
  output = raw_output.split("Response:")[-1].strip()
502
+ output = output.split("\n")[0].strip()
503
  # match = re.search(r"Response:\s*(.*)", raw_output, re.IGNORECASE)
504
  # output = match.group(1).strip() if match else ""
505
 
 
772
 
773
 
774
  # if question == "Given this table defining * on the set S = {a, b, c, d, e}\n\n|*|a|b|c|d|e|\n|---|---|---|---|---|---|\n|a|a|b|c|b|d|\n|b|b|c|a|e|c|\n|c|c|a|b|b|a|\n|d|b|e|b|e|d|\n|e|d|b|a|d|c|\n\nprovide the subset of S involved in any possible counter-examples that prove * is not commutative. Provide your answer as a comma separated list of the elements in the set in alphabetical order.":
775
+ # if " image " not in question and " video " not in question:
776
+ if question == "Who nominated the only Featured Article on English Wikipedia about a dinosaur that was promoted in November 2016?" or question == "What is the first name of the only Malko Competition recipient from the 20th Century (after 1977) whose nationality on record is a country that no longer exists?":
777
  state = {
778
  "messages": question,
779
  }
 
784
  agent_answer = response["output"]
785
  except:
786
  agent_answer = ""
787
+
788
  else:
789
  agent_answer = fixed_answer
790
  # agent_answer = self.agent.run(question)