vectorgov-cli 0.2.5__tar.gz → 0.2.7__tar.gz

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.
Files changed (30) hide show
  1. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/PKG-INFO +12 -18
  2. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/README.md +11 -17
  3. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/pyproject.toml +1 -1
  4. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/__init__.py +1 -1
  5. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/ask.py +27 -0
  6. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/lookup.py +33 -11
  7. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/main.py +1 -1
  8. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/.gitignore +0 -0
  9. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/__init__.py +0 -0
  10. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/audit.py +0 -0
  11. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/auth.py +0 -0
  12. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/config.py +0 -0
  13. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/context.py +0 -0
  14. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/docs.py +0 -0
  15. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/explain.py +0 -0
  16. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/feedback.py +0 -0
  17. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/fs_search.py +0 -0
  18. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/grep_cmd.py +0 -0
  19. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/hybrid.py +0 -0
  20. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/init.py +0 -0
  21. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/merged.py +0 -0
  22. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/prompts.py +0 -0
  23. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/quota.py +0 -0
  24. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/read.py +0 -0
  25. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/search.py +0 -0
  26. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/smart_search.py +0 -0
  27. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/commands/tokens.py +0 -0
  28. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/utils/__init__.py +0 -0
  29. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/utils/config.py +0 -0
  30. {vectorgov_cli-0.2.5 → vectorgov_cli-0.2.7}/src/vectorgov/cli/utils/output.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vectorgov-cli
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: CLI para a API VectorGov - Busca semântica em legislação brasileira
5
5
  Project-URL: Homepage, https://vectorgov.io
6
6
  Project-URL: Documentation, https://vectorgov.io/documentacao
@@ -136,7 +136,6 @@ vectorgov search --raw "dispensa de licitação" | jq -r '.hits[] | "- \(.docume
136
136
  | Comando | Descrição |
137
137
  |---------|-----------|
138
138
  | `search` | Busca semântica em legislação (filtros: `--tipo`, `--ano`, `--doc`) |
139
- | `ask` | Contexto para LLMs (busca + system prompt) |
140
139
  | `smart-search` | Busca inteligente MOC v4 com análise de confiança |
141
140
  | `hybrid` | Busca semântica + expansão por grafo normativo |
142
141
  | `lookup` | Consulta de artigo específico por referência legal |
@@ -205,22 +204,16 @@ vectorgov search "licitação" --raw | jq '.hits[0].text'
205
204
  - `--output/-o` (table/json/text/markdown)
206
205
  - `--raw` — saída JSON bruto para piping
207
206
 
208
- ### Perguntas (contexto para LLM)
207
+ ### Contexto para LLMs
209
208
 
210
- O comando `ask` busca contexto relevante para você usar com seu próprio LLM (OpenAI, Anthropic, Google, etc).
209
+ Use o comando `context` para gerar um bloco completo (busca + system prompt) pronto para colar em qualquer LLM (OpenAI, Anthropic, Google, etc).
211
210
 
212
211
  ```bash
213
- # Busca contexto para pergunta
214
- vectorgov ask "O que é ETP?"
212
+ # Bloco de contexto em texto puro
213
+ vectorgov context "O que é ETP?"
215
214
 
216
- # Com mais contexto
217
- vectorgov ask "Quando o ETP pode ser dispensado?" --top-k 10 --mode precise
218
-
219
- # Saída em formato messages (pronto para LLM)
220
- vectorgov ask "critérios de julgamento" --output json
221
-
222
- # Mostrar código de exemplo para integração
223
- vectorgov ask "O que é ETP?" --code
215
+ # Formato messages (OpenAI-compatible)
216
+ vectorgov context "critérios de julgamento" --format messages
224
217
  ```
225
218
 
226
219
  **Exemplo de integração com OpenAI:**
@@ -663,9 +656,6 @@ vectorgov search "licitação" --output json > resultados.json
663
656
  QUERY_ID=$(vectorgov search "ETP" --raw | jq -r '.query_id')
664
657
  vectorgov feedback send $QUERY_ID --like
665
658
 
666
- # Obter contexto para LLM
667
- vectorgov ask "O que é ETP?" --raw | jq '.messages'
668
-
669
659
  # Contexto completo para colar no ChatGPT/Claude
670
660
  vectorgov context "dispensa de licitação" --format raw
671
661
 
@@ -707,7 +697,11 @@ vectorgov --help
707
697
 
708
698
  # Ajuda de comando específico
709
699
  vectorgov search --help
710
- vectorgov ask --help
700
+ vectorgov context --help
701
+
702
+ # Versão do CLI
703
+ vectorgov --version # ou -V
704
+ vectorgov version # subcomando (alternativa)
711
705
  ```
712
706
 
713
707
  ## Links
@@ -83,7 +83,6 @@ vectorgov search --raw "dispensa de licitação" | jq -r '.hits[] | "- \(.docume
83
83
  | Comando | Descrição |
84
84
  |---------|-----------|
85
85
  | `search` | Busca semântica em legislação (filtros: `--tipo`, `--ano`, `--doc`) |
86
- | `ask` | Contexto para LLMs (busca + system prompt) |
87
86
  | `smart-search` | Busca inteligente MOC v4 com análise de confiança |
88
87
  | `hybrid` | Busca semântica + expansão por grafo normativo |
89
88
  | `lookup` | Consulta de artigo específico por referência legal |
@@ -152,22 +151,16 @@ vectorgov search "licitação" --raw | jq '.hits[0].text'
152
151
  - `--output/-o` (table/json/text/markdown)
153
152
  - `--raw` — saída JSON bruto para piping
154
153
 
155
- ### Perguntas (contexto para LLM)
154
+ ### Contexto para LLMs
156
155
 
157
- O comando `ask` busca contexto relevante para você usar com seu próprio LLM (OpenAI, Anthropic, Google, etc).
156
+ Use o comando `context` para gerar um bloco completo (busca + system prompt) pronto para colar em qualquer LLM (OpenAI, Anthropic, Google, etc).
158
157
 
159
158
  ```bash
160
- # Busca contexto para pergunta
161
- vectorgov ask "O que é ETP?"
159
+ # Bloco de contexto em texto puro
160
+ vectorgov context "O que é ETP?"
162
161
 
163
- # Com mais contexto
164
- vectorgov ask "Quando o ETP pode ser dispensado?" --top-k 10 --mode precise
165
-
166
- # Saída em formato messages (pronto para LLM)
167
- vectorgov ask "critérios de julgamento" --output json
168
-
169
- # Mostrar código de exemplo para integração
170
- vectorgov ask "O que é ETP?" --code
162
+ # Formato messages (OpenAI-compatible)
163
+ vectorgov context "critérios de julgamento" --format messages
171
164
  ```
172
165
 
173
166
  **Exemplo de integração com OpenAI:**
@@ -610,9 +603,6 @@ vectorgov search "licitação" --output json > resultados.json
610
603
  QUERY_ID=$(vectorgov search "ETP" --raw | jq -r '.query_id')
611
604
  vectorgov feedback send $QUERY_ID --like
612
605
 
613
- # Obter contexto para LLM
614
- vectorgov ask "O que é ETP?" --raw | jq '.messages'
615
-
616
606
  # Contexto completo para colar no ChatGPT/Claude
617
607
  vectorgov context "dispensa de licitação" --format raw
618
608
 
@@ -654,7 +644,11 @@ vectorgov --help
654
644
 
655
645
  # Ajuda de comando específico
656
646
  vectorgov search --help
657
- vectorgov ask --help
647
+ vectorgov context --help
648
+
649
+ # Versão do CLI
650
+ vectorgov --version # ou -V
651
+ vectorgov version # subcomando (alternativa)
658
652
  ```
659
653
 
660
654
  ## Links
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "vectorgov-cli"
7
- version = "0.2.5"
7
+ version = "0.2.7"
8
8
  description = "CLI para a API VectorGov - Busca semântica em legislação brasileira"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -7,7 +7,7 @@ Uso:
7
7
  vectorgov auth login
8
8
  """
9
9
 
10
- __version__ = "0.2.5"
10
+ __version__ = "0.2.7"
11
11
 
12
12
  from .main import app
13
13
 
@@ -22,6 +22,27 @@ console = Console()
22
22
  config_manager = ConfigManager()
23
23
 
24
24
 
25
+ def _check_admin(api_key: str) -> bool:
26
+ """
27
+ Verifica se a API key tem scope admin.
28
+
29
+ Chama GET /api/v1/sdk/me com a key e checa is_admin.
30
+ Retorna False em qualquer erro (fail-closed).
31
+ """
32
+ try:
33
+ import httpx
34
+ resp = httpx.get(
35
+ "https://vectorgov.io/api/v1/sdk/me",
36
+ headers={"Authorization": f"Bearer {api_key}"},
37
+ timeout=10.0,
38
+ )
39
+ if resp.status_code != 200:
40
+ return False
41
+ return bool(resp.json().get("is_admin", False))
42
+ except Exception:
43
+ return False
44
+
45
+
25
46
  @app.callback(invoke_without_command=True)
26
47
  def ask(
27
48
  query: str = typer.Argument(..., help="Pergunta em linguagem natural"),
@@ -58,6 +79,12 @@ def ask(
58
79
  console.print(" Use 'vectorgov auth login' para configurar.")
59
80
  raise typer.Exit(1)
60
81
 
82
+ # Verifica se a key tem scope admin (comando restrito)
83
+ if not _check_admin(api_key):
84
+ console.print("[red]Erro:[/red] Este comando é restrito a administradores.")
85
+ console.print(" Use [cyan]vectorgov search[/cyan] para busca regular.")
86
+ raise typer.Exit(1)
87
+
61
88
  # Valida parâmetros
62
89
  if top_k < 1 or top_k > 20:
63
90
  console.print("[red]Erro:[/red] top_k deve estar entre 1 e 20.")
@@ -279,22 +279,44 @@ def lookup( # noqa: C901
279
279
  print(render_llm_output(hits, query, metadata))
280
280
  return
281
281
 
282
+ # hits pode conter dict (fallback _build_match_from_raw) OU objeto
283
+ # (SDK Hit). Helper para ler campos de ambos uniformemente — usar
284
+ # getattr direto em dict não lê chaves, então str(h) acabava
285
+ # serializando o dict inteiro dentro do campo `text` do output JSON.
286
+ def _get(obj, key, default=""):
287
+ if obj is None:
288
+ return default
289
+ if isinstance(obj, dict):
290
+ return obj.get(key, default)
291
+ return getattr(obj, key, default)
292
+
282
293
  if output == "json":
283
- data = [
284
- {
285
- "source": getattr(h, "source", ""),
286
- "text": getattr(h, "text", str(h)),
287
- "span_id": getattr(h, "span_id", ""),
288
- }
289
- for h in hits
290
- ]
294
+ data = {
295
+ "status": status,
296
+ "query": query,
297
+ "evidence_url": evidence_url,
298
+ "document_url": document_url,
299
+ "total": len(hits),
300
+ "hits": [
301
+ {
302
+ "source": _get(h, "source") or _get(h, "document_id"),
303
+ "text": _get(h, "text"),
304
+ "span_id": _get(h, "span_id"),
305
+ "device_type": _get(h, "device_type"),
306
+ "document_id": _get(h, "document_id"),
307
+ "article_number": _get(h, "article_number"),
308
+ "breadcrumb": _get(h, "breadcrumb"),
309
+ }
310
+ for h in hits
311
+ ],
312
+ }
291
313
  console.print_json(json.dumps(data, ensure_ascii=False))
292
314
  else:
293
315
  for h in hits:
294
- source = getattr(h, "source", getattr(h, "document_id", ""))
295
- span = getattr(h, "span_id", "")
316
+ source = _get(h, "source") or _get(h, "document_id")
317
+ span = _get(h, "span_id")
296
318
  title = f"{source} — {span}" if span else source
297
- text = getattr(h, "text", str(h))
319
+ text = _get(h, "text") or str(h)
298
320
  console.print(Panel(text, title=title, border_style="cyan"))
299
321
 
300
322
  # Links de evidência (extraídos do result, não dos hits — o backend
@@ -23,7 +23,7 @@ app = typer.Typer(
23
23
  # Registra subcomandos
24
24
  app.add_typer(auth.app, name="auth", help="Autenticação e gerenciamento de credenciais")
25
25
  app.add_typer(search.app, name="search", help="Buscar documentos na base de legislação")
26
- app.add_typer(ask.app, name="ask", help="Fazer perguntas com resposta de IA")
26
+ app.add_typer(ask.app, name="ask", help="[ADMIN] Fazer perguntas com resposta de IA", hidden=True)
27
27
  app.add_typer(feedback.app, name="feedback", help="Enviar feedback sobre respostas")
28
28
  app.add_typer(docs.app, name="docs", help="Listar e consultar documentos disponíveis")
29
29
  app.add_typer(config.app, name="config", help="Gerenciar configurações")
File without changes