czrrr commited on
Commit
82e979c
·
verified ·
1 Parent(s): 17f4eb2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -89
app.py CHANGED
@@ -23,7 +23,7 @@ RESULT_COLUMNS = ["Task ID", "Question", "Submitted Answer"]
23
  HTTP_TIMEOUT = 45
24
  MAX_EXTRACTED_CHARS = 35_000
25
  DEFAULT_HF_MODEL = "huggingface/openai/gpt-oss-120b"
26
- DEFAULT_GEMINI_MODEL = "gemini/gemini-3.5-flash"
27
  TASK_FILE_CACHE = {}
28
 
29
 
@@ -458,90 +458,27 @@ class AnalyzeGaiaImageTool(Tool):
458
  return f"Could not analyze the GAIA image: {exc}"
459
 
460
 
461
- class ConsultGeminiTool(Tool):
462
- name = "consult_gemini"
463
- description = (
464
- "Asks Gemini for an independent second opinion on a difficult question "
465
- "or on evidence already collected. Use it to verify reasoning, resolve "
466
- "conflicting sources, or check the exact requested answer format. Do "
467
- "not use it as a substitute for inspecting official attachments."
468
- )
469
- inputs = {
470
- "request": {
471
- "type": "string",
472
- "description": (
473
- "The complete question plus any relevant evidence and the "
474
- "specific point Gemini should verify."
475
- ),
476
- }
477
- }
478
- output_type = "string"
479
-
480
- def forward(self, request: str) -> str:
481
- api_key = os.getenv("GEMINI_API_KEY")
482
- if not api_key:
483
- return "Gemini consultation unavailable: GEMINI_API_KEY is missing."
484
-
485
- model = os.getenv(
486
- "GAIA_GEMINI_TOOL_MODEL", DEFAULT_GEMINI_MODEL
487
- )
488
- try:
489
- response = completion(
490
- model=model,
491
- api_key=api_key,
492
- messages=[
493
- {
494
- "role": "system",
495
- "content": (
496
- "You are a verification specialist assisting another "
497
- "GAIA agent. Analyze the supplied question and evidence "
498
- "critically. Identify uncertainty or contradictions, "
499
- "then provide your recommended exact answer. Be concise "
500
- "and never claim to have opened sources that were not "
501
- "included in the request."
502
- ),
503
- },
504
- {"role": "user", "content": str(request)},
505
- ],
506
- temperature=0,
507
- max_tokens=900,
508
- )
509
- return str(response.choices[0].message.content).strip()
510
- except Exception as exc:
511
- return f"Gemini consultation failed: {exc}"
512
-
513
-
514
  class BasicAgent:
515
  def __init__(self):
516
  print("Inicializando o agente GAIA...")
517
 
518
  hf_token = os.getenv("HF_TOKEN")
519
- gemini_api_key = os.getenv("GEMINI_API_KEY")
520
  configured_model = os.getenv("GAIA_MODEL_ID")
521
 
522
  model_id = configured_model or DEFAULT_HF_MODEL
523
-
524
- if model_id.startswith("gemini/"):
525
- model_api_key = gemini_api_key
526
- required_secret = "GEMINI_API_KEY"
527
- else:
528
- model_api_key = hf_token
529
- required_secret = "HF_TOKEN"
530
-
531
- if not model_api_key:
532
  raise RuntimeError(
533
- f"O secret {required_secret} não está configurado. "
534
  "Adicione a chave em Settings > Variables and secrets > Secrets."
535
  )
536
 
537
  self.model = LiteLLMModel(
538
  model_id=model_id,
539
- api_key=model_api_key,
540
  temperature=0,
541
  max_tokens=2_000,
542
  )
543
  self.hf_token = hf_token
544
- self.gemini_api_key = gemini_api_key
545
  self.model_id = model_id
546
  print(f"Modelo principal selecionado: {model_id}")
547
 
@@ -573,8 +510,6 @@ class BasicAgent:
573
  YouTubeTranscriptTool(),
574
  AnalyzeGaiaImageTool(),
575
  ]
576
- if gemini_api_key:
577
- agent_tools.append(ConsultGeminiTool())
578
 
579
  self.agent = CodeAgent(
580
  tools=agent_tools,
@@ -613,9 +548,6 @@ TOOL ROUTING POLICY:
613
  chess positions, or questions that visually depend on an attached image.
614
  6. youtube_transcript retrieves spoken subtitles. Use it when asked what a
615
  person said. It cannot answer purely visual video questions.
616
- 7. consult_gemini gives a second opinion. Use it after gathering evidence when
617
- sources conflict or the candidate answer is uncertain. Include the complete
618
- question, evidence, and candidate answer.
619
 
620
  Research carefully, prefer primary or official sources, and cross-check
621
  uncertain facts. A search snippet alone is insufficient when the source page
@@ -681,12 +613,12 @@ include reasoning, explanations, labels, Markdown, citations, or the words
681
  ):
682
  raise RuntimeError(
683
  f"Falha de autenticação no modelo {self.model_id}. "
684
- "Verifique a chave secreta correspondente ao provedor "
685
- "(GEMINI_API_KEY para Gemini ou HF_TOKEN para Hugging Face)."
686
  ) from exc
687
  raise
688
  candidate = self.format_exact_answer(question, str(result))
689
- return self.review_answer_with_gemini(
690
  question=question,
691
  candidate=candidate,
692
  task_id=task_id,
@@ -754,18 +686,19 @@ include reasoning, explanations, labels, Markdown, citations, or the words
754
 
755
  return self.deterministic_answer_cleanup(cleaned)
756
 
757
- def review_answer_with_gemini(
758
  self, question: str, candidate: str, task_id: str | None = None
759
  ) -> str:
760
- """Revisa obrigatoriamente conteúdo e formato antes de salvar a resposta."""
761
- if not self.gemini_api_key:
 
762
  fallback = self.deterministic_answer_cleanup(candidate)
763
- print("Gemini review status: SKIPPED — GEMINI_API_KEY is missing")
764
  print(f"Primary answer preserved: {fallback}")
765
  return fallback
766
 
767
  reviewer_model = os.getenv(
768
- "GAIA_GEMINI_REVIEW_MODEL", DEFAULT_GEMINI_MODEL
769
  )
770
  review_prompt = f"""
771
  You are the mandatory final reviewer for a GAIA exact-match answer.
@@ -811,7 +744,7 @@ Do not return JSON. Do not wrap the fields in Markdown or a code block.
811
  )
812
  response = completion(
813
  model=reviewer_model,
814
- api_key=self.gemini_api_key,
815
  messages=[
816
  {
817
  "role": "user",
@@ -837,13 +770,13 @@ Do not return JSON. Do not wrap the fields in Markdown or a code block.
837
  )
838
  if not answer_match:
839
  raise ValueError(
840
- "Gemini did not return the <final_answer> field."
841
  )
842
  final_answer = self.deterministic_answer_cleanup(
843
  answer_match.group(1)
844
  )
845
  if not final_answer:
846
- raise ValueError("Gemini returned an empty final_answer.")
847
 
848
  changed = final_answer != candidate
849
  note = (
@@ -852,9 +785,9 @@ Do not return JSON. Do not wrap the fields in Markdown or a code block.
852
  else "Review completed without a note."
853
  )
854
  print(f"Candidate answer: {candidate}")
855
- print(f"Gemini reviewed answer: {final_answer}")
856
- print(f"Gemini changed answer: {changed}")
857
- print(f"Gemini review note: {note}")
858
  return final_answer
859
  except Exception as exc:
860
  last_error = exc
@@ -862,13 +795,13 @@ Do not return JSON. Do not wrap the fields in Markdown or a code block.
862
  fallback = self.deterministic_answer_cleanup(candidate)
863
  if not fallback:
864
  raise RuntimeError(
865
- "A revisão do Gemini falhou e a resposta primária estava vazia. "
866
  f"Detalhe: {last_error}"
867
  )
868
 
869
  print(f"Candidate answer: {fallback}")
870
- print("Gemini review status: FAILED — primary answer preserved")
871
- print(f"Gemini review error: {last_error}")
872
  return fallback
873
 
874
 
 
23
  HTTP_TIMEOUT = 45
24
  MAX_EXTRACTED_CHARS = 35_000
25
  DEFAULT_HF_MODEL = "huggingface/openai/gpt-oss-120b"
26
+ DEFAULT_GROQ_REVIEW_MODEL = "groq/qwen/qwen3.6-27b"
27
  TASK_FILE_CACHE = {}
28
 
29
 
 
458
  return f"Could not analyze the GAIA image: {exc}"
459
 
460
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  class BasicAgent:
462
  def __init__(self):
463
  print("Inicializando o agente GAIA...")
464
 
465
  hf_token = os.getenv("HF_TOKEN")
 
466
  configured_model = os.getenv("GAIA_MODEL_ID")
467
 
468
  model_id = configured_model or DEFAULT_HF_MODEL
469
+ if not hf_token:
 
 
 
 
 
 
 
 
470
  raise RuntimeError(
471
+ "O secret HF_TOKEN não está configurado. "
472
  "Adicione a chave em Settings > Variables and secrets > Secrets."
473
  )
474
 
475
  self.model = LiteLLMModel(
476
  model_id=model_id,
477
+ api_key=hf_token,
478
  temperature=0,
479
  max_tokens=2_000,
480
  )
481
  self.hf_token = hf_token
 
482
  self.model_id = model_id
483
  print(f"Modelo principal selecionado: {model_id}")
484
 
 
510
  YouTubeTranscriptTool(),
511
  AnalyzeGaiaImageTool(),
512
  ]
 
 
513
 
514
  self.agent = CodeAgent(
515
  tools=agent_tools,
 
548
  chess positions, or questions that visually depend on an attached image.
549
  6. youtube_transcript retrieves spoken subtitles. Use it when asked what a
550
  person said. It cannot answer purely visual video questions.
 
 
 
551
 
552
  Research carefully, prefer primary or official sources, and cross-check
553
  uncertain facts. A search snippet alone is insufficient when the source page
 
613
  ):
614
  raise RuntimeError(
615
  f"Falha de autenticação no modelo {self.model_id}. "
616
+ "Verifique se HF_TOKEN possui permissão para usar "
617
+ "Inference Providers."
618
  ) from exc
619
  raise
620
  candidate = self.format_exact_answer(question, str(result))
621
+ return self.review_answer_with_groq(
622
  question=question,
623
  candidate=candidate,
624
  task_id=task_id,
 
686
 
687
  return self.deterministic_answer_cleanup(cleaned)
688
 
689
+ def review_answer_with_groq(
690
  self, question: str, candidate: str, task_id: str | None = None
691
  ) -> str:
692
+ """Solicita uma segunda opinião gratuita no Groq, com fallback local."""
693
+ groq_api_key = os.getenv("GROQ_API_KEY")
694
+ if not groq_api_key:
695
  fallback = self.deterministic_answer_cleanup(candidate)
696
+ print("Groq review status: SKIPPED — GROQ_API_KEY is missing")
697
  print(f"Primary answer preserved: {fallback}")
698
  return fallback
699
 
700
  reviewer_model = os.getenv(
701
+ "GAIA_GROQ_REVIEW_MODEL", DEFAULT_GROQ_REVIEW_MODEL
702
  )
703
  review_prompt = f"""
704
  You are the mandatory final reviewer for a GAIA exact-match answer.
 
744
  )
745
  response = completion(
746
  model=reviewer_model,
747
+ api_key=groq_api_key,
748
  messages=[
749
  {
750
  "role": "user",
 
770
  )
771
  if not answer_match:
772
  raise ValueError(
773
+ "Groq did not return the <final_answer> field."
774
  )
775
  final_answer = self.deterministic_answer_cleanup(
776
  answer_match.group(1)
777
  )
778
  if not final_answer:
779
+ raise ValueError("Groq returned an empty final_answer.")
780
 
781
  changed = final_answer != candidate
782
  note = (
 
785
  else "Review completed without a note."
786
  )
787
  print(f"Candidate answer: {candidate}")
788
+ print(f"Groq reviewed answer: {final_answer}")
789
+ print(f"Groq changed answer: {changed}")
790
+ print(f"Groq review note: {note}")
791
  return final_answer
792
  except Exception as exc:
793
  last_error = exc
 
795
  fallback = self.deterministic_answer_cleanup(candidate)
796
  if not fallback:
797
  raise RuntimeError(
798
+ "A revisão do Groq falhou e a resposta primária estava vazia. "
799
  f"Detalhe: {last_error}"
800
  )
801
 
802
  print(f"Candidate answer: {fallback}")
803
+ print("Groq review status: FAILED — primary answer preserved")
804
+ print(f"Groq review error: {last_error}")
805
  return fallback
806
 
807