hyperforge 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.
Files changed (90) hide show
  1. hyperforge/__init__.py +16 -0
  2. hyperforge/agent.py +81 -0
  3. hyperforge/api/__init__.py +20 -0
  4. hyperforge/api/app.py +155 -0
  5. hyperforge/api/authentication.py +271 -0
  6. hyperforge/api/commands.py +33 -0
  7. hyperforge/api/internal/__init__.py +4 -0
  8. hyperforge/api/internal/inspect.py +30 -0
  9. hyperforge/api/internal/router.py +3 -0
  10. hyperforge/api/logging.py +18 -0
  11. hyperforge/api/models.py +129 -0
  12. hyperforge/api/session.py +197 -0
  13. hyperforge/api/settings.py +38 -0
  14. hyperforge/api/utils.py +354 -0
  15. hyperforge/api/v1/__init__.py +23 -0
  16. hyperforge/api/v1/agents.py +531 -0
  17. hyperforge/api/v1/interaction.py +430 -0
  18. hyperforge/api/v1/mcp_content.py +311 -0
  19. hyperforge/api/v1/mcp_interaction.py +322 -0
  20. hyperforge/api/v1/oauth.py +60 -0
  21. hyperforge/api/v1/prompt.py +129 -0
  22. hyperforge/api/v1/router.py +3 -0
  23. hyperforge/api/v1/schema.py +56 -0
  24. hyperforge/api/v1/session.py +182 -0
  25. hyperforge/api/v1/utils.py +12 -0
  26. hyperforge/api/v1/workflows.py +643 -0
  27. hyperforge/arag.py +28 -0
  28. hyperforge/broker/__init__.py +52 -0
  29. hyperforge/broker/local.py +116 -0
  30. hyperforge/broker/redis.py +161 -0
  31. hyperforge/configure.py +571 -0
  32. hyperforge/context/__init__.py +0 -0
  33. hyperforge/context/agent.py +377 -0
  34. hyperforge/context/config.py +103 -0
  35. hyperforge/database.py +3 -0
  36. hyperforge/db/__init__.py +6 -0
  37. hyperforge/db/agents.py +1521 -0
  38. hyperforge/db/encryption.py +91 -0
  39. hyperforge/db/exceptions.py +26 -0
  40. hyperforge/db/settings.py +16 -0
  41. hyperforge/db/workflow_cleanup.py +69 -0
  42. hyperforge/definition.py +13 -0
  43. hyperforge/driver.py +31 -0
  44. hyperforge/dummy.py +28 -0
  45. hyperforge/engine.py +189 -0
  46. hyperforge/exceptions.py +14 -0
  47. hyperforge/feature_flag.py +105 -0
  48. hyperforge/fixtures.py +602 -0
  49. hyperforge/interaction.py +116 -0
  50. hyperforge/llm.py +75 -0
  51. hyperforge/manager.py +432 -0
  52. hyperforge/memory/__init__.py +5 -0
  53. hyperforge/memory/memory.py +974 -0
  54. hyperforge/minimal_fixtures.py +75 -0
  55. hyperforge/models.py +336 -0
  56. hyperforge/nua.py +336 -0
  57. hyperforge/openapi.py +63 -0
  58. hyperforge/prompts.py +188 -0
  59. hyperforge/pubsub.py +90 -0
  60. hyperforge/py.typed +0 -0
  61. hyperforge/redis_utils.py +82 -0
  62. hyperforge/retrieval/__init__.py +0 -0
  63. hyperforge/retrieval/agent.py +169 -0
  64. hyperforge/retrieval/config.py +94 -0
  65. hyperforge/server/__init__.py +5 -0
  66. hyperforge/server/cache.py +131 -0
  67. hyperforge/server/run.py +109 -0
  68. hyperforge/server/sandbox.py +60 -0
  69. hyperforge/server/session.py +421 -0
  70. hyperforge/server/settings.py +47 -0
  71. hyperforge/server/utils.py +57 -0
  72. hyperforge/server/web.py +31 -0
  73. hyperforge/settings.py +18 -0
  74. hyperforge/standalone/__init__.py +5 -0
  75. hyperforge/standalone/agent.py +189 -0
  76. hyperforge/standalone/app.py +264 -0
  77. hyperforge/standalone/config.py +137 -0
  78. hyperforge/standalone/const.py +1 -0
  79. hyperforge/standalone/run.py +60 -0
  80. hyperforge/standalone/settings.py +133 -0
  81. hyperforge/standalone/ui_router.py +241 -0
  82. hyperforge/trace.py +42 -0
  83. hyperforge/utils/__init__.py +112 -0
  84. hyperforge/utils/http.py +48 -0
  85. hyperforge/workflows.py +44 -0
  86. hyperforge-1.0.0.post19.dist-info/METADATA +95 -0
  87. hyperforge-1.0.0.post19.dist-info/RECORD +90 -0
  88. hyperforge-1.0.0.post19.dist-info/WHEEL +5 -0
  89. hyperforge-1.0.0.post19.dist-info/entry_points.txt +8 -0
  90. hyperforge-1.0.0.post19.dist-info/top_level.txt +1 -0
@@ -0,0 +1,129 @@
1
+ from enum import Enum
2
+ from typing import Any, Dict, List, Literal, Optional
3
+
4
+ from nucliadb_models import TextFormat
5
+ from pydantic import BaseModel, Field
6
+
7
+ from hyperforge.driver import DriverConfig
8
+ from hyperforge.models import Rules
9
+
10
+
11
+ class StashRoles(str, Enum):
12
+ # Can do anything at the stash
13
+ OWNER = "SOWNER"
14
+
15
+ # Can access the stash
16
+ MEMBER = "SMEMBER"
17
+
18
+ # Can access the stash
19
+ CONTRIBUTOR = "SCONTRIBUTOR"
20
+
21
+
22
+ class AccountRoles(str, Enum):
23
+ OWNER = "AOWNER"
24
+ MEMBER = "AMEMBER"
25
+
26
+
27
+ class AgentRole(str, Enum):
28
+ MEMBER = "SESSIONMEMBER"
29
+
30
+
31
+ class NucliaDBRoles(str, Enum):
32
+ MANAGER = "MANAGER"
33
+ READER = "READER"
34
+ WRITER = "WRITER"
35
+
36
+
37
+ class UserType(str, Enum):
38
+ ROOT = "ROOT"
39
+ DEALER = "DEALER"
40
+ USER = "USER"
41
+ READONLY = "READONLY"
42
+ MANAGER = "MANAGER"
43
+ SALES = "SALES"
44
+
45
+
46
+ class AccountTypes(str, Enum):
47
+ TRIAL = "stash-trial"
48
+ STARTER = "stash-starter"
49
+ GROWTH = "stash-growth"
50
+ STARTUP = "stash-startup"
51
+ ENTERPRISE = "stash-enterprise"
52
+
53
+ # will be removed at some point in the near future
54
+ DEVELOPER = "stash-developer"
55
+ BUSINESS = "stash-business"
56
+
57
+ # V3 account types
58
+ V3_STARTER = "v3starter"
59
+ V3_FLY = "v3fly"
60
+ V3_GROWTH = "v3growth"
61
+ V3_PRO = "v3pro"
62
+ V3_ENTERPRISE = "v3enterprise"
63
+ COWORK = "cowork"
64
+
65
+
66
+ class SessionData(BaseModel):
67
+ slug: str
68
+ name: str
69
+ summary: str
70
+ data: str
71
+ format: TextFormat
72
+
73
+
74
+ INFO_FIELD_ID = "info"
75
+
76
+ DEFAULT_RESOURCE_LIST_PAGE_SIZE = 20
77
+
78
+
79
+ class InspectData(BaseModel):
80
+ contexts: List[Any]
81
+ driver: List[DriverConfig]
82
+ postprocess: List[Any]
83
+ preprocess: List[Any]
84
+ rules: Rules
85
+
86
+
87
+ class AgentID(BaseModel):
88
+ id: str
89
+
90
+
91
+ class DriverID(BaseModel):
92
+ id: str
93
+
94
+
95
+ class PromptID(BaseModel):
96
+ id: str
97
+
98
+
99
+ class InteractionsAuditDownloadRequest(BaseModel):
100
+ session_id: Optional[str] = Field(default=None, description="Filter by session ID")
101
+ year: Optional[int] = Field(
102
+ default=None,
103
+ description="Filter by year (e.g., 2024). If not specified, defaults to the current year.",
104
+ )
105
+ month: Optional[int] = Field(
106
+ default=None,
107
+ description="Filter by month (1-12). If not specified, defaults to the past month.",
108
+ )
109
+
110
+
111
+ class DownloadStatus(BaseModel):
112
+ id: str
113
+ type: str
114
+ status: Literal["pending", "ready"]
115
+ download_url: str | None
116
+ query: dict[str, Any]
117
+
118
+
119
+ class InteractionOperation(int, Enum):
120
+ QUESTION = 0
121
+ QUIT = 1
122
+
123
+
124
+ class InteractionRequest(BaseModel):
125
+ question: str
126
+ headers: Dict[str, str] = {}
127
+ arguments: Dict[str, str] = {}
128
+ operation: InteractionOperation = InteractionOperation.QUESTION
129
+ streaming: bool = False
@@ -0,0 +1,197 @@
1
+ """Session management functions for ARAG agents with NucliaDB memory."""
2
+
3
+ from typing import Optional
4
+
5
+ from nucliadb_models import (
6
+ CreateResourcePayload,
7
+ ResourceCreated,
8
+ TextField,
9
+ TextFormat,
10
+ UpdateResourcePayload,
11
+ )
12
+ from nucliadb_models.conversation import InputConversationField
13
+ from nucliadb_models.resource import Resource, ResourceList
14
+ from nucliadb_sdk import NucliaDBAsync
15
+ from nucliadb_sdk.v2.exceptions import NotFoundError
16
+
17
+ from hyperforge import logger
18
+ from hyperforge.api.models import INFO_FIELD_ID
19
+ from hyperforge.memory.memory import QUESTION_ANSWERS_FIELD
20
+
21
+
22
+ async def create_session_resource(
23
+ ndb: NucliaDBAsync,
24
+ agent_id: str,
25
+ slug: str,
26
+ title: str,
27
+ summary: str,
28
+ data: str,
29
+ format: TextFormat = TextFormat.PLAIN,
30
+ ) -> ResourceCreated:
31
+ """Create a new session resource in the agent's memory KB.
32
+
33
+ Args:
34
+ ndb: NucliaDB client instance
35
+ agent_id: The agent/KB ID
36
+ slug: Optional resource slug (ID)
37
+ title: Optional session title
38
+ summary: Optional session summary
39
+ data: Session data text content
40
+ format: Text format (default: PLAIN)
41
+
42
+ Returns:
43
+ ResourceCreated with the new session details
44
+
45
+ Raises:
46
+ Exception: If session creation fails
47
+ """
48
+ try:
49
+ created = await ndb.create_resource(
50
+ kbid=agent_id,
51
+ content=CreateResourcePayload(
52
+ title=title,
53
+ slug=slug,
54
+ summary=summary,
55
+ texts={INFO_FIELD_ID: TextField(body=data, format=format)},
56
+ conversations={QUESTION_ANSWERS_FIELD: InputConversationField()},
57
+ ),
58
+ )
59
+ logger.info(f"Created session {created.uuid} for agent {agent_id}")
60
+ return created
61
+ except Exception as e:
62
+ logger.exception(f"Error creating session for agent {agent_id}: {e}")
63
+ raise
64
+
65
+
66
+ async def get_session_resource(
67
+ ndb: NucliaDBAsync,
68
+ agent_id: str,
69
+ session_id: str,
70
+ show: Optional[list[str]] = None,
71
+ ) -> Resource:
72
+ """Get a session resource by ID.
73
+
74
+ Args:
75
+ ndb: NucliaDB client instance
76
+ agent_id: The agent/KB ID
77
+ session_id: The session resource ID
78
+ show: Optional list of fields to include (e.g., ["basic", "values"])
79
+
80
+ Returns:
81
+ Resource object
82
+
83
+ Raises:
84
+ NotFoundError: If session doesn't exist
85
+ """
86
+ query_params = {}
87
+ if show:
88
+ query_params["show"] = show
89
+
90
+ return await ndb.get_resource_by_id(
91
+ rid=session_id,
92
+ kbid=agent_id,
93
+ query_params=query_params,
94
+ )
95
+
96
+
97
+ async def session_exists(
98
+ ndb: NucliaDBAsync,
99
+ agent_id: str,
100
+ session_id: str,
101
+ ) -> bool:
102
+ """Check if a session resource exists.
103
+
104
+ Args:
105
+ ndb: NucliaDB client instance
106
+ agent_id: The agent/KB ID
107
+ session_id: The session resource ID
108
+
109
+ Returns:
110
+ True if session exists, False otherwise
111
+ """
112
+ try:
113
+ await ndb.get_resource_by_id(
114
+ rid=session_id,
115
+ kbid=agent_id,
116
+ query_params={"show": ["basic"]},
117
+ )
118
+ return True
119
+ except NotFoundError:
120
+ return False
121
+
122
+
123
+ async def update_session_resource(
124
+ ndb: NucliaDBAsync,
125
+ agent_id: str,
126
+ session_id: str,
127
+ title: str,
128
+ summary: str,
129
+ data: str,
130
+ format: TextFormat,
131
+ ) -> None:
132
+ """Update a session resource.
133
+
134
+ Args:
135
+ ndb: NucliaDB client instance
136
+ agent_id: The agent/KB ID
137
+ session_id: The session resource ID
138
+ title: Optional new title
139
+ summary: Optional new summary
140
+ data: Optional new data text content
141
+ format: Optional text format
142
+
143
+ Raises:
144
+ NotFoundError: If session doesn't exist
145
+ """
146
+ await ndb.update_resource(
147
+ rid=session_id,
148
+ kbid=agent_id,
149
+ content=UpdateResourcePayload(
150
+ title=title,
151
+ summary=summary,
152
+ texts={INFO_FIELD_ID: TextField(body=data, format=format)},
153
+ ),
154
+ )
155
+
156
+
157
+ async def delete_session_resource(
158
+ ndb: NucliaDBAsync,
159
+ agent_id: str,
160
+ session_id: str,
161
+ ) -> None:
162
+ """Delete a session resource.
163
+
164
+ Args:
165
+ ndb: NucliaDB client instance
166
+ agent_id: The agent/KB ID
167
+ session_id: The session resource ID
168
+
169
+ Raises:
170
+ NotFoundError: If session doesn't exist
171
+ """
172
+ await ndb.delete_resource(
173
+ rid=session_id,
174
+ kbid=agent_id,
175
+ )
176
+
177
+
178
+ async def list_session_resources(
179
+ ndb: NucliaDBAsync,
180
+ agent_id: str,
181
+ page: int = 0,
182
+ size: int = 20,
183
+ ) -> ResourceList:
184
+ """List session resources for an agent.
185
+
186
+ Args:
187
+ ndb: NucliaDB client instance
188
+ agent_id: The agent/KB ID
189
+ page: Page number (0-based)
190
+ size: Page size
191
+
192
+ Returns:
193
+ ResourceList with sessions
194
+ """
195
+ return await ndb.list_resources(
196
+ kbid=agent_id, query_params={"page": page, "size": size}
197
+ )
@@ -0,0 +1,38 @@
1
+ from typing import Optional
2
+
3
+ from pydantic_settings import BaseSettings
4
+
5
+
6
+ class Settings(BaseSettings):
7
+ debug: bool = False
8
+ log_level: str = "ERROR"
9
+ http_host: str = "0.0.0.0"
10
+ http_port: int = 8080
11
+
12
+ memory_apikey_nucliadb: Optional[str] = None
13
+ memory_reader_nucliadb: str = "reader.nucliadb.svc.cluster.local:8080"
14
+ memory_writer_nucliadb: str = "writer.nucliadb.svc.cluster.local:8080"
15
+ memory_search_nucliadb: str = "search.nucliadb.svc.cluster.local:8080"
16
+
17
+ idp_regional_grpc: str = "idp-grpc.idp-regional.svc.cluster.local:9090"
18
+ dummy_idp: bool = False
19
+
20
+ sentry_url: Optional[str] = None
21
+ running_environment: str = "stage"
22
+ zone: str = "stashify"
23
+ grpc_port: int = 8030
24
+
25
+ valkey_url: str = "redis://arag-valkey-cluster"
26
+ valkey_cluster_mode: bool = False
27
+ answers_subject: str = (
28
+ "arag.{account}.{agent_id}.{workflow_id}.{session}.{question}.answer"
29
+ )
30
+ oauth_subject: str = "arag.{account}.{agent_id}.{workflow_id}.{session}.{question}.oauth.{oauth_uuid}"
31
+ activate_subject: str = "arag.activate"
32
+ pubsub_keepalive_seconds: float = 20
33
+
34
+ load_modules: list[str] = []
35
+
36
+ # Hydra settings for MCP Oauth
37
+ hydra_public_url: str = "https://oauth.progress.cloud"
38
+ hydra_scopes_supported: list[str] = ["offline_access", "openid"]