hyperforge-restart 1.0.0.post19__py3-none-any.whl

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.
File without changes
@@ -0,0 +1,118 @@
1
+ from time import time
2
+
3
+ from hyperforge.agent import Agent
4
+ from hyperforge.exceptions import MaxRetries
5
+ from hyperforge.manager import Manager
6
+ from hyperforge.memory import QuestionMemory
7
+ from hyperforge.trace import trace_agent
8
+
9
+ from hyperforge_restart.config import RestartAgentConfig
10
+ from hyperforge import PROMPT_ENVIRONMENT, logger
11
+
12
+ REPHRASE_PROMPT = """
13
+ You are an expert assistant helping to answer complex questions using the provided context and any partial answers already available.
14
+ Your goal is to identify only the missing information needed to fully answer the main question.
15
+
16
+ Instructions:
17
+ 1. Carefully review the main question and the context, which may include partial answers or relevant details.
18
+ 2. If the main question is not fully answered by the context, generate only the specific sub-questions or clarifications needed to obtain the missing information.
19
+ 3. Briefly explain why each new question is necessary.
20
+ 4. If the context is sufficient to answer the main question, simply state that no additional questions are needed. Fill the questions list with an empty string. And answer true in the answered parameter.
21
+ Be concise and focus on actionable, relevant questions that address only the gaps in information.
22
+
23
+ # Main Question:
24
+ {{question}}
25
+
26
+ #Context (may include partial answers or supporting information):
27
+ {{context}}
28
+ """
29
+ JSON_SCHEMA = {
30
+ "title": "questions",
31
+ "description": (
32
+ "An object containing a list of specific sub-questions or clarifications needed "
33
+ "to fully answer the main question, and a brief explanation for each. "
34
+ "Focus only on actionable, relevant questions that address gaps in information."
35
+ ),
36
+ "type": "object",
37
+ "properties": {
38
+ "questions": {
39
+ "type": "array",
40
+ "items": {
41
+ "type": "string",
42
+ "description": "A concise, actionable sub-question or clarification needed to fill a gap in the answer.",
43
+ },
44
+ "description": "List of missing sub-questions or clarifications required to fully answer the main question.",
45
+ },
46
+ "reason": {
47
+ "type": "string",
48
+ "description": "A brief explanation of why these questions are necessary to complete the answer.",
49
+ },
50
+ "answered": {
51
+ "type": "boolean",
52
+ "description": "Indicates whether the main question can be answered with the provided context.",
53
+ },
54
+ },
55
+ "required": ["questions"],
56
+ }
57
+
58
+ REPHRASE_PROMPT_TEMPLATE = PROMPT_ENVIRONMENT.from_string(REPHRASE_PROMPT)
59
+
60
+
61
+ class RestartAgent(Agent[RestartAgentConfig]):
62
+ @trace_agent
63
+ async def __call__(
64
+ self,
65
+ memory: QuestionMemory,
66
+ manager: Manager,
67
+ ):
68
+ # check how many restart options
69
+
70
+ retry = 0
71
+ for step in memory.steps:
72
+ if step.module == "restart":
73
+ retry += 1
74
+
75
+ question = memory.original_question
76
+
77
+ prompt = REPHRASE_PROMPT_TEMPLATE.render(
78
+ context=memory.contexts_minimal(), question=question
79
+ )
80
+ t0 = time()
81
+ # Ask the LLM to define which information is needed to answer.
82
+ information, input, output = await manager.execute_json(
83
+ model=self.config.model,
84
+ user_id="rephrase",
85
+ prompt=prompt,
86
+ schema=JSON_SCHEMA,
87
+ tracking=memory.get_tracking_info(),
88
+ )
89
+
90
+ # retrieve all paragraphs and ask to rephrase on the NUA API
91
+ new_questions = information.get("questions", [])
92
+ reason = information.get("reason", [])
93
+ answered = information.get("answered", False)
94
+
95
+ if retry >= self.config.retries and not answered:
96
+ error_message = (
97
+ f"Maximum retries reached ({self.config.retries}). "
98
+ "Unable to generate new questions to answer the original question."
99
+ )
100
+ logger.error(error_message)
101
+ raise MaxRetries(error_message)
102
+ if answered:
103
+ logger.info("No additional questions needed to answer the main question.")
104
+ memory.restart = False
105
+ return
106
+ await memory.add_step(
107
+ step_module="restart",
108
+ step_title=self.step_title("Rephrase"),
109
+ step_value=f"New questions: {', '.join(new_questions)}",
110
+ step_reason=reason,
111
+ timeit=time() - t0,
112
+ step_agent_path=f"/postprocess/{self.config.id if self.config.id else 'default'}",
113
+ input_nuclia_tokens=input,
114
+ output_nuclia_tokens=output,
115
+ )
116
+
117
+ memory.add_context_questions(new_questions)
118
+ memory.restart = True
@@ -0,0 +1,11 @@
1
+ from typing import Literal
2
+
3
+ from hyperforge.agent import AgentConfig
4
+ from pydantic.config import ConfigDict
5
+
6
+
7
+ class RestartAgentConfig(AgentConfig):
8
+ model_config = ConfigDict(title="Restart")
9
+ module: Literal["restart"] = "restart"
10
+ model: str
11
+ retries: int = 2
@@ -0,0 +1,19 @@
1
+ Metadata-Version: 2.4
2
+ Name: hyperforge_restart
3
+ Version: 1.0.0.post19
4
+ Summary: Restart Hyperforge agent
5
+ Author-email: Nuclia <nucliadb@nuclia.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://progress.com
8
+ Project-URL: Repository, https://github.com/nuclia/forge
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Requires-Python: <4,>=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: hyperforge
18
+
19
+ # Rephrase Hyperforge agents
@@ -0,0 +1,7 @@
1
+ hyperforge_restart/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ hyperforge_restart/agent.py,sha256=eNWGsasBa8cPWaW2sKBj_glstKvM2mle3uueJs6KVbs,4653
3
+ hyperforge_restart/config.py,sha256=iecT8zp8CsvEtG0s1jQyAAngpnePREPuC2vGrsArI_U,275
4
+ hyperforge_restart-1.0.0.post19.dist-info/METADATA,sha256=Ax3z-ayKP5ZHHMGJ7q6Gx3TYfk2QfZfrwJt8LrqRahc,726
5
+ hyperforge_restart-1.0.0.post19.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
6
+ hyperforge_restart-1.0.0.post19.dist-info/top_level.txt,sha256=CrcsSdnNl5D_kNuceDbD8uzyJD3aZ6tFJWMo5LuO0yc,19
7
+ hyperforge_restart-1.0.0.post19.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ hyperforge_restart