gemini-cli-pro 0.0.8-snapshot → 0.0.10-snapshot
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/gemini_tool.py +69 -10
- package/package.json +5 -2
- package/scripts/install-global.js +1 -1
package/README.md
CHANGED
package/gemini_tool.py
CHANGED
|
@@ -279,8 +279,8 @@ def search_local_context_via_rag_server(query: str) -> str:
|
|
|
279
279
|
return ""
|
|
280
280
|
|
|
281
281
|
runner_code = r'''
|
|
282
|
-
import importlib.util
|
|
283
282
|
import pathlib
|
|
283
|
+
import runpy
|
|
284
284
|
import sys
|
|
285
285
|
|
|
286
286
|
server_file = pathlib.Path(sys.argv[1]).expanduser().resolve()
|
|
@@ -288,21 +288,17 @@ query = sys.argv[2]
|
|
|
288
288
|
top_k = int(sys.argv[3])
|
|
289
289
|
mode = sys.argv[4]
|
|
290
290
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
mod = importlib.util.module_from_spec(spec)
|
|
295
|
-
spec.loader.exec_module(mod)
|
|
296
|
-
|
|
297
|
-
if not hasattr(mod, "semantic_search_code"):
|
|
291
|
+
namespace = runpy.run_path(str(server_file), run_name="mcp_rag_server_runtime")
|
|
292
|
+
search_fn = namespace.get("semantic_search_code")
|
|
293
|
+
if not callable(search_fn):
|
|
298
294
|
raise RuntimeError("semantic_search_code nao encontrado no mcp-rag-server")
|
|
299
295
|
|
|
300
|
-
result =
|
|
296
|
+
result = search_fn(query=query, top_k=top_k, mode=mode)
|
|
301
297
|
print(result if isinstance(result, str) else str(result))
|
|
302
298
|
'''
|
|
303
299
|
|
|
304
300
|
py_exec = _python_for_script(server_path)
|
|
305
|
-
result = _run_command([py_exec, "-c", runner_code, server_path, query, "6", "
|
|
301
|
+
result = _run_command([py_exec, "-c", runner_code, server_path, query, "6", "ensemble"], timeout=180)
|
|
306
302
|
stdout = (result.stdout or "").strip()
|
|
307
303
|
stderr = (result.stderr or "").strip()
|
|
308
304
|
if result.returncode == 0:
|
|
@@ -600,6 +596,47 @@ class GeminiToolCLI:
|
|
|
600
596
|
return text
|
|
601
597
|
return ""
|
|
602
598
|
|
|
599
|
+
def _extract_response_text(self, response: Any) -> str:
|
|
600
|
+
try:
|
|
601
|
+
text = getattr(response, "text", None)
|
|
602
|
+
if isinstance(text, str) and text.strip():
|
|
603
|
+
return text.strip()
|
|
604
|
+
except Exception:
|
|
605
|
+
pass
|
|
606
|
+
|
|
607
|
+
candidates = getattr(response, "candidates", None) or []
|
|
608
|
+
parts_text: list[str] = []
|
|
609
|
+
for candidate in candidates:
|
|
610
|
+
content = getattr(candidate, "content", None)
|
|
611
|
+
parts = getattr(content, "parts", None) or []
|
|
612
|
+
for part in parts:
|
|
613
|
+
part_text = getattr(part, "text", None)
|
|
614
|
+
if isinstance(part_text, str) and part_text.strip():
|
|
615
|
+
parts_text.append(part_text)
|
|
616
|
+
return "\n".join(parts_text).strip()
|
|
617
|
+
|
|
618
|
+
def _diagnose_empty_response(self, response: Any) -> str:
|
|
619
|
+
prompt_feedback = getattr(response, "prompt_feedback", None)
|
|
620
|
+
block_reason = getattr(prompt_feedback, "block_reason", None) if prompt_feedback else None
|
|
621
|
+
block_reason_message = getattr(prompt_feedback, "block_reason_message", None) if prompt_feedback else None
|
|
622
|
+
|
|
623
|
+
if block_reason or block_reason_message:
|
|
624
|
+
return f"Resposta bloqueada pelo provedor (reason={block_reason}, msg={block_reason_message})."
|
|
625
|
+
|
|
626
|
+
candidates = getattr(response, "candidates", None) or []
|
|
627
|
+
if not candidates:
|
|
628
|
+
return "Sem candidatos de resposta retornados pelo modelo."
|
|
629
|
+
|
|
630
|
+
finish_reasons = []
|
|
631
|
+
for candidate in candidates:
|
|
632
|
+
finish_reason = getattr(candidate, "finish_reason", None)
|
|
633
|
+
if finish_reason:
|
|
634
|
+
finish_reasons.append(str(finish_reason))
|
|
635
|
+
if finish_reasons:
|
|
636
|
+
return f"Modelo retornou sem texto (finish_reason={','.join(finish_reasons)})."
|
|
637
|
+
|
|
638
|
+
return "Modelo retornou sem texto."
|
|
639
|
+
|
|
603
640
|
def _append_to_history(self, role: str, text: str) -> None:
|
|
604
641
|
self.history.append({"role": role, "parts": [text]})
|
|
605
642
|
|
|
@@ -721,6 +758,26 @@ class GeminiToolCLI:
|
|
|
721
758
|
full_response += piece
|
|
722
759
|
print(piece, end="", flush=True)
|
|
723
760
|
print(ANSI_RESET)
|
|
761
|
+
|
|
762
|
+
if not full_response.strip():
|
|
763
|
+
# Fallback: tenta resposta não-stream e injeta contexto RAG manualmente.
|
|
764
|
+
rag_context = search_local_context(raw) if self.rag_server_found else ""
|
|
765
|
+
fallback_prompt = raw
|
|
766
|
+
if rag_context.strip():
|
|
767
|
+
fallback_prompt = (
|
|
768
|
+
f"Pergunta do usuario:\n{raw}\n\n"
|
|
769
|
+
"Contexto local recuperado do rag-codebase:\n"
|
|
770
|
+
f"{rag_context}\n\n"
|
|
771
|
+
"Responda de forma direta, em PT-BR, citando o que encontrou no contexto."
|
|
772
|
+
)
|
|
773
|
+
fallback_response = self.chat.send_message(fallback_prompt, stream=False)
|
|
774
|
+
full_response = self._extract_response_text(fallback_response)
|
|
775
|
+
if full_response.strip():
|
|
776
|
+
print(ANSI_CYAN + full_response + ANSI_RESET)
|
|
777
|
+
else:
|
|
778
|
+
diagnostic = self._diagnose_empty_response(fallback_response)
|
|
779
|
+
self._print_warn(f"Sem resposta textual do modelo. {diagnostic}")
|
|
780
|
+
|
|
724
781
|
emit_plin()
|
|
725
782
|
except Exception as exc:
|
|
726
783
|
self._print_error(f"Erro ao gerar resposta: {exc}")
|
|
@@ -728,6 +785,8 @@ class GeminiToolCLI:
|
|
|
728
785
|
emit_plin()
|
|
729
786
|
continue
|
|
730
787
|
|
|
788
|
+
if not full_response.strip():
|
|
789
|
+
full_response = "[Sem resposta textual do modelo]"
|
|
731
790
|
self._append_to_history("model", full_response)
|
|
732
791
|
save_history(self.history)
|
|
733
792
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gemini-cli-pro",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10-snapshot",
|
|
4
4
|
"description": "Gemini CLI em Python com sync de RAG local e roteamento Flash/Pro",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -30,5 +30,8 @@
|
|
|
30
30
|
"python",
|
|
31
31
|
"rag",
|
|
32
32
|
"automation"
|
|
33
|
-
]
|
|
33
|
+
],
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"gemini-cli-pro": "^0.0.7-snapshot"
|
|
36
|
+
}
|
|
34
37
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const { spawnSync } = require("child_process");
|
|
3
3
|
|
|
4
4
|
function install(pkgName) {
|
|
5
|
-
const result = spawnSync("npm", ["install", "-g", pkgName], { stdio: "inherit" });
|
|
5
|
+
const result = spawnSync("npm", ["install", "-g", pkgName, "--force"], { stdio: "inherit" });
|
|
6
6
|
return result.status === 0;
|
|
7
7
|
}
|
|
8
8
|
|