hyperforge-nucliadb 1.0.0.post111__tar.gz → 1.0.0.post113__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 (42) hide show
  1. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/PKG-INFO +1 -1
  2. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/pyproject.toml +1 -1
  3. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/basic_ask_agent.py +16 -1
  4. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb.egg-info/PKG-INFO +1 -1
  5. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb.egg-info/SOURCES.txt +1 -0
  6. hyperforge_nucliadb-1.0.0.post113/tests/test_facets_count.py +72 -0
  7. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/README.md +0 -0
  8. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/setup.cfg +0 -0
  9. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/__init__.py +0 -0
  10. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/advanced_ask_agent.py +0 -0
  11. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/advanced_ask_config.py +0 -0
  12. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/__init__.py +0 -0
  13. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/analysis.py +0 -0
  14. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/ask.py +0 -0
  15. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/config.py +0 -0
  16. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/hydrate.py +0 -0
  17. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/kb_analysis.py +0 -0
  18. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/knowledge_scan.py +0 -0
  19. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/models.py +0 -0
  20. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/multi.py +0 -0
  21. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/nucliadb.py +0 -0
  22. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/prompt_analysis.py +0 -0
  23. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/query_analysis.py +0 -0
  24. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/rerank.py +0 -0
  25. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask/utils.py +0 -0
  26. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/ask_utils.py +0 -0
  27. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/basic_ask_config.py +0 -0
  28. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/driver.py +0 -0
  29. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/driver_config.py +0 -0
  30. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/py.typed +0 -0
  31. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/sync/__init__.py +0 -0
  32. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/sync/agent.py +0 -0
  33. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/sync/config.py +0 -0
  34. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/sync/config_driver.py +0 -0
  35. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb/sync/driver.py +0 -0
  36. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb.egg-info/dependency_links.txt +0 -0
  37. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb.egg-info/requires.txt +0 -0
  38. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/src/hyperforge_nucliadb.egg-info/top_level.txt +0 -0
  39. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/tests/test_ask_utils.py +0 -0
  40. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/tests/test_driver.py +0 -0
  41. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/tests/test_nucliadb.py +0 -0
  42. {hyperforge_nucliadb-1.0.0.post111 → hyperforge_nucliadb-1.0.0.post113}/tests/test_sync.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperforge_nucliadb
3
- Version: 1.0.0.post111
3
+ Version: 1.0.0.post113
4
4
  Summary: NucliaDB Hyperforge agent
5
5
  Author-email: Nuclia <nucliadb@nuclia.com>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hyperforge_nucliadb"
7
- version = "1.0.0.post111"
7
+ version = "1.0.0.post113"
8
8
  license = "Apache-2.0"
9
9
  description = "NucliaDB Hyperforge agent"
10
10
  authors = [{ name = "Nuclia", email = "nucliadb@nuclia.com" }]
@@ -1554,6 +1554,17 @@ class BasicAskAgent(ContextAgent, Agent[BasicAskAgentConfig]):
1554
1554
  logger.info(
1555
1555
  f"No labels selected for faceted search on question {question}, skipping."
1556
1556
  )
1557
+ context = Context(
1558
+ agent_id=self.agent_id,
1559
+ original_question_uuid=memory.original_question_uuid,
1560
+ actual_question_uuid=None,
1561
+ missing=question,
1562
+ question=question,
1563
+ source=source.id,
1564
+ chunks=[],
1565
+ agent="basic_ask_facets",
1566
+ title=f"Faceted search on {source.id} Knowledge Box",
1567
+ )
1557
1568
  else:
1558
1569
  # We are assuming resources equals fields here
1559
1570
  facets, total = await ndb.field_labels(labelsets=labels_selected)
@@ -1593,7 +1604,11 @@ class BasicAskAgent(ContextAgent, Agent[BasicAskAgentConfig]):
1593
1604
  await memory.add_step(
1594
1605
  step_module=self.config.module,
1595
1606
  step_title=self.step_title("Faceted count"),
1596
- step_reason="Faceted search performed",
1607
+ step_reason=(
1608
+ "Faceted search performed"
1609
+ if labels_selected
1610
+ else "Faceted search skipped"
1611
+ ),
1597
1612
  step_value=selected_labels.get("reasoning", ""),
1598
1613
  timeit=time() - t0,
1599
1614
  input_nuclia_tokens=input_nt,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperforge_nucliadb
3
- Version: 1.0.0.post111
3
+ Version: 1.0.0.post113
4
4
  Summary: NucliaDB Hyperforge agent
5
5
  Author-email: Nuclia <nucliadb@nuclia.com>
6
6
  License-Expression: Apache-2.0
@@ -35,5 +35,6 @@ src/hyperforge_nucliadb/sync/config_driver.py
35
35
  src/hyperforge_nucliadb/sync/driver.py
36
36
  tests/test_ask_utils.py
37
37
  tests/test_driver.py
38
+ tests/test_facets_count.py
38
39
  tests/test_nucliadb.py
39
40
  tests/test_sync.py
@@ -0,0 +1,72 @@
1
+ from unittest.mock import AsyncMock, Mock
2
+
3
+ import pytest
4
+ from hyperforge.models import Context, Source
5
+
6
+ from hyperforge_nucliadb.basic_ask_agent import BasicAskAgent
7
+ from hyperforge_nucliadb.basic_ask_config import BasicAskAgentConfig
8
+
9
+
10
+ @pytest.mark.asyncio
11
+ @pytest.mark.parametrize("label_sets", [[], ["topic"]])
12
+ async def test_facets_count_handles_label_selection(mocker, label_sets):
13
+ agent = BasicAskAgent(BasicAskAgentConfig(sources=["kb"]), agent_id="facets-agent")
14
+ source = Source.model_construct(id="kb")
15
+ mocker.patch(
16
+ "hyperforge_nucliadb.basic_ask_agent.choose_source",
17
+ new=AsyncMock(return_value=[source]),
18
+ )
19
+ driver = Mock(
20
+ labels=AsyncMock(return_value={"topic": ["science"]}),
21
+ field_labels=AsyncMock(return_value=({"topic": {"science": 2}}, 2)),
22
+ )
23
+ mocker.patch(
24
+ "hyperforge_nucliadb.basic_ask_agent.get_ndb_driver", return_value=driver
25
+ )
26
+ memory = Mock(original_question_uuid="question-id", add_step=AsyncMock())
27
+ manager = Mock(
28
+ execute_json=AsyncMock(
29
+ return_value=(
30
+ {"label_sets": label_sets, "reasoning": "Label selection"},
31
+ 1,
32
+ 2,
33
+ )
34
+ ),
35
+ execute=AsyncMock(return_value=("There are 2 science documents.", 3, 4, 0)),
36
+ )
37
+
38
+ contexts = await agent.facets_count(memory, manager, question="How many?")
39
+
40
+ assert len(contexts) == 1
41
+ context = contexts[0]
42
+ assert isinstance(context, Context)
43
+ assert context.agent_id == "facets-agent"
44
+ assert context.original_question_uuid == "question-id"
45
+ assert context.actual_question_uuid is None
46
+ assert context.question == "How many?"
47
+ assert context.source == "kb"
48
+ assert context.agent == "basic_ask_facets"
49
+ assert context.title == "Faceted search on kb Knowledge Box"
50
+ memory.add_step.assert_awaited_once()
51
+ step = memory.add_step.call_args.kwargs
52
+ assert step["step_value"] == "Label selection"
53
+ assert step["step_agent_path"] == "/context/facets-agent/facets_count"
54
+
55
+ if label_sets:
56
+ assert context.missing is None
57
+ assert len(context.chunks) == 1
58
+ assert context.chunks[0].chunk_id == "facets_count_result-0"
59
+ assert context.chunks[0].text == "There are 2 science documents."
60
+ driver.field_labels.assert_awaited_once_with(labelsets=label_sets)
61
+ manager.execute.assert_awaited_once()
62
+ assert step["step_reason"] == "Faceted search performed"
63
+ assert step["input_nuclia_tokens"] == 4
64
+ assert step["output_nuclia_tokens"] == 6
65
+ else:
66
+ assert context.missing == "How many?"
67
+ assert context.chunks == []
68
+ driver.field_labels.assert_not_awaited()
69
+ manager.execute.assert_not_awaited()
70
+ assert step["step_reason"] == "Faceted search skipped"
71
+ assert step["input_nuclia_tokens"] == 1
72
+ assert step["output_nuclia_tokens"] == 2