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.
- hyperforge/__init__.py +16 -0
- hyperforge/agent.py +81 -0
- hyperforge/api/__init__.py +20 -0
- hyperforge/api/app.py +155 -0
- hyperforge/api/authentication.py +271 -0
- hyperforge/api/commands.py +33 -0
- hyperforge/api/internal/__init__.py +4 -0
- hyperforge/api/internal/inspect.py +30 -0
- hyperforge/api/internal/router.py +3 -0
- hyperforge/api/logging.py +18 -0
- hyperforge/api/models.py +129 -0
- hyperforge/api/session.py +197 -0
- hyperforge/api/settings.py +38 -0
- hyperforge/api/utils.py +354 -0
- hyperforge/api/v1/__init__.py +23 -0
- hyperforge/api/v1/agents.py +531 -0
- hyperforge/api/v1/interaction.py +430 -0
- hyperforge/api/v1/mcp_content.py +311 -0
- hyperforge/api/v1/mcp_interaction.py +322 -0
- hyperforge/api/v1/oauth.py +60 -0
- hyperforge/api/v1/prompt.py +129 -0
- hyperforge/api/v1/router.py +3 -0
- hyperforge/api/v1/schema.py +56 -0
- hyperforge/api/v1/session.py +182 -0
- hyperforge/api/v1/utils.py +12 -0
- hyperforge/api/v1/workflows.py +643 -0
- hyperforge/arag.py +28 -0
- hyperforge/broker/__init__.py +52 -0
- hyperforge/broker/local.py +116 -0
- hyperforge/broker/redis.py +161 -0
- hyperforge/configure.py +571 -0
- hyperforge/context/__init__.py +0 -0
- hyperforge/context/agent.py +377 -0
- hyperforge/context/config.py +103 -0
- hyperforge/database.py +3 -0
- hyperforge/db/__init__.py +6 -0
- hyperforge/db/agents.py +1521 -0
- hyperforge/db/encryption.py +91 -0
- hyperforge/db/exceptions.py +26 -0
- hyperforge/db/settings.py +16 -0
- hyperforge/db/workflow_cleanup.py +69 -0
- hyperforge/definition.py +13 -0
- hyperforge/driver.py +31 -0
- hyperforge/dummy.py +28 -0
- hyperforge/engine.py +189 -0
- hyperforge/exceptions.py +14 -0
- hyperforge/feature_flag.py +105 -0
- hyperforge/fixtures.py +602 -0
- hyperforge/interaction.py +116 -0
- hyperforge/llm.py +75 -0
- hyperforge/manager.py +432 -0
- hyperforge/memory/__init__.py +5 -0
- hyperforge/memory/memory.py +974 -0
- hyperforge/minimal_fixtures.py +75 -0
- hyperforge/models.py +336 -0
- hyperforge/nua.py +336 -0
- hyperforge/openapi.py +63 -0
- hyperforge/prompts.py +188 -0
- hyperforge/pubsub.py +90 -0
- hyperforge/py.typed +0 -0
- hyperforge/redis_utils.py +82 -0
- hyperforge/retrieval/__init__.py +0 -0
- hyperforge/retrieval/agent.py +169 -0
- hyperforge/retrieval/config.py +94 -0
- hyperforge/server/__init__.py +5 -0
- hyperforge/server/cache.py +131 -0
- hyperforge/server/run.py +109 -0
- hyperforge/server/sandbox.py +60 -0
- hyperforge/server/session.py +421 -0
- hyperforge/server/settings.py +47 -0
- hyperforge/server/utils.py +57 -0
- hyperforge/server/web.py +31 -0
- hyperforge/settings.py +18 -0
- hyperforge/standalone/__init__.py +5 -0
- hyperforge/standalone/agent.py +189 -0
- hyperforge/standalone/app.py +264 -0
- hyperforge/standalone/config.py +137 -0
- hyperforge/standalone/const.py +1 -0
- hyperforge/standalone/run.py +60 -0
- hyperforge/standalone/settings.py +133 -0
- hyperforge/standalone/ui_router.py +241 -0
- hyperforge/trace.py +42 -0
- hyperforge/utils/__init__.py +112 -0
- hyperforge/utils/http.py +48 -0
- hyperforge/workflows.py +44 -0
- hyperforge-1.0.0.post19.dist-info/METADATA +95 -0
- hyperforge-1.0.0.post19.dist-info/RECORD +90 -0
- hyperforge-1.0.0.post19.dist-info/WHEEL +5 -0
- hyperforge-1.0.0.post19.dist-info/entry_points.txt +8 -0
- hyperforge-1.0.0.post19.dist-info/top_level.txt +1 -0
hyperforge/api/models.py
ADDED
|
@@ -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"]
|