hyperforge-perplexity 1.0.0.post30__tar.gz → 1.0.0.post47__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 (15) hide show
  1. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/PKG-INFO +2 -2
  2. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/pyproject.toml +5 -2
  3. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity/perplexity.py +11 -7
  4. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity.egg-info/PKG-INFO +2 -2
  5. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/tests/test_perplexity.py +14 -5
  6. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/README.md +0 -0
  7. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/setup.cfg +0 -0
  8. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity/__init__.py +0 -0
  9. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity/config.py +0 -0
  10. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity/driver.py +0 -0
  11. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity/py.typed +0 -0
  12. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity.egg-info/SOURCES.txt +0 -0
  13. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity.egg-info/dependency_links.txt +0 -0
  14. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity.egg-info/requires.txt +0 -0
  15. {hyperforge_perplexity-1.0.0.post30 → hyperforge_perplexity-1.0.0.post47}/src/hyperforge_perplexity.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperforge_perplexity
3
- Version: 1.0.0.post30
3
+ Version: 1.0.0.post47
4
4
  Summary: Perplexity Hyperforge agent
5
5
  Author-email: Nuclia <nucliadb@nuclia.com>
6
6
  License-Expression: Apache-2.0
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Programming Language :: Python :: 3 :: Only
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
- Requires-Python: <4,>=3.10
16
+ Requires-Python: <4,>=3.12
17
17
  Description-Content-Type: text/markdown
18
18
  Requires-Dist: hyperforge
19
19
  Requires-Dist: httpx
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hyperforge_perplexity"
7
- version = "1.0.0.post30"
7
+ version = "1.0.0.post47"
8
8
  license = "Apache-2.0"
9
9
  description = "Perplexity Hyperforge agent"
10
10
  authors = [{ name = "Nuclia", email = "nucliadb@nuclia.com" }]
@@ -17,7 +17,7 @@ classifiers = [
17
17
  "Programming Language :: Python :: 3 :: Only",
18
18
  "Topic :: Software Development :: Libraries :: Python Modules",
19
19
  ]
20
- requires-python = ">=3.10, <4"
20
+ requires-python = ">=3.12, <4"
21
21
  dependencies = [
22
22
  "hyperforge",
23
23
  "httpx",
@@ -45,3 +45,6 @@ asyncio_mode = "auto"
45
45
 
46
46
  # Exclude specific files from being packaged
47
47
  source-exclude = ["tests/**", "*.pyc"]
48
+
49
+ [tool.ruff]
50
+ extend = "../../ruff.toml"
@@ -9,6 +9,7 @@ from hyperforge.context.agent import ContextAgent
9
9
  from hyperforge.definition import FunctionDefinition
10
10
  from hyperforge.manager import Manager
11
11
  from hyperforge.memory import Chunk, Context, QuestionMemory
12
+ from hyperforge.models import ExternalUsage
12
13
  from hyperforge.utils.http import safe_http_client
13
14
  from nuclia.lib.nua_responses import Image
14
15
  from perplexity.types import ChatMessageInput
@@ -135,8 +136,6 @@ class PerplexityAgent(ContextAgent, Agent[PerplexityAgentConfig]):
135
136
  )
136
137
  context.chunks.append(chunk)
137
138
 
138
- # for chunk in response add to context
139
- input_nuclia_tokens = 0
140
139
  context.summary = text if text is not None else ""
141
140
 
142
141
  if (
@@ -147,9 +146,7 @@ class PerplexityAgent(ContextAgent, Agent[PerplexityAgentConfig]):
147
146
  questions: List[str] = cast(List[str], response.related_questions)
148
147
  memory.add_future_questions(questions)
149
148
 
150
- # TODO: Report nuclia tokens correctly
151
- if response.usage is not None and response.usage.total_tokens is not None:
152
- input_nuclia_tokens += response.usage.total_tokens
149
+ usage = response.usage
153
150
 
154
151
  await memory.add_step(
155
152
  step_module=self.config.module,
@@ -158,8 +155,15 @@ class PerplexityAgent(ContextAgent, Agent[PerplexityAgentConfig]):
158
155
  step_agent_path=f"/context/{self.config.id or self.agent_id}",
159
156
  step_value=text if text is not None else "",
160
157
  timeit=time() - t0,
161
- input_nuclia_tokens=input_nuclia_tokens,
162
- output_nuclia_tokens=0,
158
+ external_usage=[
159
+ ExternalUsage(
160
+ provider="perplexity",
161
+ model="sonar-pro",
162
+ input_tokens=(usage.prompt_tokens or 0) if usage else 0,
163
+ output_tokens=(usage.completion_tokens or 0) if usage else 0,
164
+ requests=1,
165
+ )
166
+ ],
163
167
  )
164
168
  return context
165
169
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperforge_perplexity
3
- Version: 1.0.0.post30
3
+ Version: 1.0.0.post47
4
4
  Summary: Perplexity Hyperforge agent
5
5
  Author-email: Nuclia <nucliadb@nuclia.com>
6
6
  License-Expression: Apache-2.0
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Programming Language :: Python :: 3 :: Only
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
- Requires-Python: <4,>=3.10
16
+ Requires-Python: <4,>=3.12
17
17
  Description-Content-Type: text/markdown
18
18
  Requires-Dist: hyperforge
19
19
  Requires-Dist: httpx
@@ -8,9 +8,10 @@ from hyperforge.memory import Context
8
8
  from hyperforge.memory.memory import EphemeralSessionMemory
9
9
  from hyperforge.minimal_fixtures import cassette_nua_key
10
10
  from hyperforge.models import MemoryConfig, Rules
11
+ from nuclia.lib.nua import AsyncNuaClient
12
+
11
13
  from hyperforge_perplexity.config import PerplexityAgentConfig
12
14
  from hyperforge_perplexity.perplexity import PerplexityAgent
13
- from nuclia.lib.nua import AsyncNuaClient
14
15
 
15
16
  NUA_KEY = os.environ.get(
16
17
  "NUA_KEY",
@@ -37,7 +38,7 @@ async def _run_question(
37
38
  drivers: list[dict],
38
39
  question: str,
39
40
  config_overrides: dict | None = None,
40
- ) -> list[Context]:
41
+ ) -> tuple[list[Context], EphemeralSessionMemory]:
41
42
  """Build a manager from driver configs, run the agent, return contexts."""
42
43
  load_all_configurations("hyperforge_perplexity")
43
44
  # Perplexity agent doesn't use nua — construct client directly with test values
@@ -74,17 +75,25 @@ async def _run_question(
74
75
  question=question,
75
76
  flow_id=flow_id,
76
77
  )
77
- return memory.get_agent_contexts(flow_id=flow_id, agent_id=agent.agent_id)
78
+ return memory.get_agent_contexts(flow_id=flow_id, agent_id=agent.agent_id), memory
78
79
 
79
80
 
80
81
  async def test_perplexity():
81
- contexts = await _run_question(
82
+ contexts, memory = await _run_question(
82
83
  DRIVERS,
83
84
  "What is Nuclia?",
84
85
  config_overrides={"domain": ["nuclia.com"], "related_questions": True},
85
86
  )
86
87
  assert len(contexts) > 0
87
88
  assert any(ctx.chunks for ctx in contexts)
89
+ usage = next(step.external_usage for step in memory.steps if step.external_usage)
90
+ assert len(usage) == 1
91
+ event = usage[0]
92
+ assert event.provider == "perplexity"
93
+ assert event.model == "sonar-pro"
94
+ assert event.input_tokens > 0
95
+ assert event.output_tokens > 0
96
+ assert event.requests == 1
88
97
 
89
98
 
90
99
  @pytest.mark.skipif(
@@ -92,7 +101,7 @@ async def test_perplexity():
92
101
  reason="Only run when LOCAL_TESTING env var is set.",
93
102
  )
94
103
  async def test_perplexity_images():
95
- contexts = await _run_question(
104
+ contexts, _ = await _run_question(
96
105
  DRIVERS,
97
106
  "What colors are 'duppi' usually?",
98
107
  config_overrides={"images": True, "related_questions": True},