vectorgov-cli 0.2.6__tar.gz → 0.2.8__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.6 → vectorgov_cli-0.2.8}/PKG-INFO +1 -1
  2. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/pyproject.toml +1 -1
  3. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/__init__.py +1 -1
  4. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/lookup.py +99 -11
  5. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/.gitignore +0 -0
  6. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/README.md +0 -0
  7. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/__init__.py +0 -0
  8. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/ask.py +0 -0
  9. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/audit.py +0 -0
  10. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/auth.py +0 -0
  11. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/config.py +0 -0
  12. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/context.py +0 -0
  13. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/docs.py +0 -0
  14. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/explain.py +0 -0
  15. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/feedback.py +0 -0
  16. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/fs_search.py +0 -0
  17. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/grep_cmd.py +0 -0
  18. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/hybrid.py +0 -0
  19. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/init.py +0 -0
  20. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/merged.py +0 -0
  21. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/prompts.py +0 -0
  22. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/quota.py +0 -0
  23. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/read.py +0 -0
  24. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/search.py +0 -0
  25. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/smart_search.py +0 -0
  26. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/commands/tokens.py +0 -0
  27. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/main.py +0 -0
  28. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/utils/__init__.py +0 -0
  29. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/src/vectorgov/cli/utils/config.py +0 -0
  30. {vectorgov_cli-0.2.6 → vectorgov_cli-0.2.8}/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.6
3
+ Version: 0.2.8
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "vectorgov-cli"
7
- version = "0.2.6"
7
+ version = "0.2.8"
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.6"
10
+ __version__ = "0.2.8"
11
11
 
12
12
  from .main import app
13
13
 
@@ -130,6 +130,72 @@ def lookup( # noqa: C901
130
130
 
131
131
  status = getattr(result, "status", None)
132
132
 
133
+ # Backend faz auto-split quando a query contem multiplas referencias
134
+ # separadas por virgula ou "e" (ex: "inc. I do Art. 4, inc. II do Art. 4").
135
+ # Nesse caso retorna status=batch com a lista em `results`.
136
+ if status == "batch":
137
+ batch_results = getattr(result, "results", None) or []
138
+ if raw or effective_output == "raw":
139
+ data = {
140
+ "batch": True,
141
+ "total": len(batch_results),
142
+ "results": [],
143
+ }
144
+ for r in batch_results:
145
+ raw_r = getattr(r, "_raw_response", None) or {}
146
+ data["results"].append({
147
+ "reference": getattr(r, "query", ""),
148
+ "status": getattr(r, "status", "unknown"),
149
+ "text": raw_r.get("text") or getattr(r, "stitched_text", "") or "",
150
+ "evidence_url": absolute_url(
151
+ getattr(r, "evidence_url", None) or raw_r.get("evidence_url")
152
+ ),
153
+ "document_url": absolute_url(
154
+ getattr(r, "document_url", None) or raw_r.get("document_url")
155
+ ),
156
+ "document_id": raw_r.get("document_id", ""),
157
+ "device_type": raw_r.get("device_type", ""),
158
+ "breadcrumb": raw_r.get("breadcrumb", ""),
159
+ })
160
+ print(json.dumps(data, ensure_ascii=False, indent=2))
161
+ return
162
+
163
+ # Text / json / llm output
164
+ if effective_output == "llm":
165
+ for i, r in enumerate(batch_results):
166
+ raw_r = getattr(r, "_raw_response", None) or {}
167
+ r_status = getattr(r, "status", "unknown")
168
+ r_text = raw_r.get("text") or getattr(r, "stitched_text", "") or ""
169
+ r_ref = getattr(r, "query", f"ref {i+1}")
170
+ r_ev = absolute_url(getattr(r, "evidence_url", None) or raw_r.get("evidence_url"))
171
+ r_doc = absolute_url(getattr(r, "document_url", None) or raw_r.get("document_url"))
172
+ print(f"[{i+1}/{len(batch_results)}] {r_ref} ({r_status})")
173
+ if r_text:
174
+ print(r_text)
175
+ if r_ev:
176
+ print(f"EVIDENCE: {r_ev}")
177
+ if r_doc:
178
+ print(f"PDF: {r_doc}")
179
+ if i < len(batch_results) - 1:
180
+ print("---")
181
+ else:
182
+ console.print(f"[bold]Batch:[/bold] {len(batch_results)} referencias encontradas")
183
+ for i, r in enumerate(batch_results):
184
+ raw_r = getattr(r, "_raw_response", None) or {}
185
+ r_status = getattr(r, "status", "unknown")
186
+ r_text = raw_r.get("text") or getattr(r, "stitched_text", "") or ""
187
+ r_ref = getattr(r, "query", f"ref {i+1}")
188
+ r_breadcrumb = raw_r.get("breadcrumb", "")
189
+ title = f"[{i+1}] {r_ref} [{r_status}]"
190
+ if r_breadcrumb:
191
+ title += f"\n {r_breadcrumb}"
192
+ if r_text:
193
+ console.print(Panel(r_text, title=title, border_style="cyan"))
194
+ else:
195
+ console.print(f"\n[yellow]{title}[/yellow]")
196
+ console.print(f" Nenhum texto retornado.")
197
+ return
198
+
133
199
  # Fallback: SDK v0.16 falha ao parsear `match` quando o backend aplica
134
200
  # _strip_lookup_internals (remove node_id/span_id por segurança). O
135
201
  # backend envia text/document_id/device_type no root do response mas
@@ -279,22 +345,44 @@ def lookup( # noqa: C901
279
345
  print(render_llm_output(hits, query, metadata))
280
346
  return
281
347
 
348
+ # hits pode conter dict (fallback _build_match_from_raw) OU objeto
349
+ # (SDK Hit). Helper para ler campos de ambos uniformemente — usar
350
+ # getattr direto em dict não lê chaves, então str(h) acabava
351
+ # serializando o dict inteiro dentro do campo `text` do output JSON.
352
+ def _get(obj, key, default=""):
353
+ if obj is None:
354
+ return default
355
+ if isinstance(obj, dict):
356
+ return obj.get(key, default)
357
+ return getattr(obj, key, default)
358
+
282
359
  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
- ]
360
+ data = {
361
+ "status": status,
362
+ "query": query,
363
+ "evidence_url": evidence_url,
364
+ "document_url": document_url,
365
+ "total": len(hits),
366
+ "hits": [
367
+ {
368
+ "source": _get(h, "source") or _get(h, "document_id"),
369
+ "text": _get(h, "text"),
370
+ "span_id": _get(h, "span_id"),
371
+ "device_type": _get(h, "device_type"),
372
+ "document_id": _get(h, "document_id"),
373
+ "article_number": _get(h, "article_number"),
374
+ "breadcrumb": _get(h, "breadcrumb"),
375
+ }
376
+ for h in hits
377
+ ],
378
+ }
291
379
  console.print_json(json.dumps(data, ensure_ascii=False))
292
380
  else:
293
381
  for h in hits:
294
- source = getattr(h, "source", getattr(h, "document_id", ""))
295
- span = getattr(h, "span_id", "")
382
+ source = _get(h, "source") or _get(h, "document_id")
383
+ span = _get(h, "span_id")
296
384
  title = f"{source} — {span}" if span else source
297
- text = getattr(h, "text", str(h))
385
+ text = _get(h, "text") or str(h)
298
386
  console.print(Panel(text, title=title, border_style="cyan"))
299
387
 
300
388
  # Links de evidência (extraídos do result, não dos hits — o backend
File without changes
File without changes