hyperforge 1.0.0.post326__tar.gz → 1.0.0.post332__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.
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/PKG-INFO +1 -1
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/pyproject.toml +1 -1
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/pyproject.toml.orig +1 -1
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/codemode/sandbox.py +53 -21
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/__init__.py +2 -1
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/agents.py +5 -3
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/harness.py +6 -4
- hyperforge-1.0.0.post332/src/hyperforge/harness_sdk/tools/__init__.py +9 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/tools/codemode.py +8 -3
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/tools/core.py +22 -19
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/tools/utils.py +21 -7
- hyperforge-1.0.0.post326/src/hyperforge/harness_sdk/tools/__init__.py +0 -8
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/README.md +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/VERSION +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/auth.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/card.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/context.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/executor.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/run.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/server.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/settings.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/a2a/task_store.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/agent.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/README +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/env.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/script.py.mako +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/049a4aed19e1_create_generation_table.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/1416cb41bd49_add_downloads_table.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/2847934e2d59_unique_driver.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/4d89a36c8bda_memory.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/72b997edb05d_identifier_for_drivers.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/9c6f6a1b4e7f_workflows_default_fk.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/b8edb72295e0_.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic/versions/f3d2c1b0a9e8_soft_delete_workflows.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/alembic.ini +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/app.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/authentication.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/commands.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/logging.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/models.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/session.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/settings.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/utils.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/agents.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/interaction.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/mcp_content.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/mcp_interaction.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/oauth.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/prompt.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/router.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/schema.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/session.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/utils.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/workflows.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/arag.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/broker/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/broker/local.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/broker/redis.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/codemode/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/codemode/model.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/codemode/worker.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/configure.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/context/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/context/agent.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/context/config.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/database.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/agents.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/encryption.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/exceptions.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/llm_migration_utils.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/settings.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/workflow_cleanup.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/definition.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/driver.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/dummy.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/engine.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/exceptions.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/feature_flag.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/fixtures.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness/agent.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness/config.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/clients.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/context.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/models.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/schema.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/storage.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/usage.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/interaction.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/llm.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/llm_config.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/manager.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/memory/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/memory/memory.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/minimal_fixtures.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/models.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/openapi.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/prompts.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/pubsub.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/py.typed +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/redis_utils.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/result_payload.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/retrieval/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/retrieval/agent.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/retrieval/config.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/cache.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/run.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/sandbox.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/session.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/settings.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/utils.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/server/web.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/settings.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/agent.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/app.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/config.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/const.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/oauth.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/run.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/settings.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/ui_router.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/static/assets/index-DLejS5jC.js +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/static/assets/index-MoxkZ1_3.css +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/static/favicon.svg +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/static/index.html +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/trace.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/utils/__init__.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/utils/http.py +0 -0
- {hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/workflows.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hyperforge"
|
|
7
|
-
version = "1.0.0.
|
|
7
|
+
version = "1.0.0.post332"
|
|
8
8
|
authors = [{ name = "AI Data Team", email = "learning@nuclia.com" }]
|
|
9
9
|
description = "Agentic Framework for Orchestrated Runtime, Governance, and Execution"
|
|
10
10
|
readme = "README.md"
|
|
@@ -8,7 +8,7 @@ from concurrent.futures import Executor, ThreadPoolExecutor
|
|
|
8
8
|
from concurrent.futures import Future as ConcurrentFuture
|
|
9
9
|
from multiprocessing import Pipe, Process
|
|
10
10
|
from multiprocessing.connection import Connection
|
|
11
|
-
from typing import Any, Callable, Coroutine
|
|
11
|
+
from typing import Any, Awaitable, Callable, Coroutine
|
|
12
12
|
|
|
13
13
|
import httpx
|
|
14
14
|
import nucliadb_telemetry.metrics
|
|
@@ -25,7 +25,6 @@ from .model import (
|
|
|
25
25
|
from .worker import PythonAgentWorker
|
|
26
26
|
|
|
27
27
|
logger = logging.getLogger("hyperforge_codemode_sandbox")
|
|
28
|
-
WORKER_CPU_LIMIT = 1
|
|
29
28
|
WORKER_EXIT_TIMEOUT = 1
|
|
30
29
|
MAX_PACKET_BYTES = 16 * 1024 * 1024
|
|
31
30
|
|
|
@@ -35,6 +34,7 @@ class SandboxSettings(BaseSettings):
|
|
|
35
34
|
sandbox_socket: str | None = None
|
|
36
35
|
sandbox_metrics_port: int = 8091
|
|
37
36
|
sandbox_token: str | None = None
|
|
37
|
+
sandbox_callback_wait_seconds: float = 1.0
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
settings = SandboxSettings()
|
|
@@ -60,8 +60,16 @@ class SandboxRunner:
|
|
|
60
60
|
socket: str,
|
|
61
61
|
callback: Callable[[RestrictedPythonTask], Coroutine[Any, Any, WorkerTypes]],
|
|
62
62
|
debug: bool = False,
|
|
63
|
+
*,
|
|
64
|
+
token: str | Callable[[], str] | None = None,
|
|
63
65
|
) -> "SandboxRunner":
|
|
64
|
-
return cls(
|
|
66
|
+
return cls(
|
|
67
|
+
pool=None,
|
|
68
|
+
socket=socket,
|
|
69
|
+
callback=callback,
|
|
70
|
+
debug=debug,
|
|
71
|
+
token=token,
|
|
72
|
+
)
|
|
65
73
|
|
|
66
74
|
@classmethod
|
|
67
75
|
def isolated_process(
|
|
@@ -78,12 +86,14 @@ class SandboxRunner:
|
|
|
78
86
|
socket: str | None,
|
|
79
87
|
callback: Callable[[RestrictedPythonTask], Coroutine[Any, Any, WorkerTypes]],
|
|
80
88
|
debug: bool,
|
|
89
|
+
token: str | Callable[[], str] | None = None,
|
|
81
90
|
):
|
|
82
91
|
self.pool = pool
|
|
83
92
|
self.socket = socket
|
|
84
93
|
self.callback = callback
|
|
85
94
|
self.debug = debug
|
|
86
95
|
self.isolated = False
|
|
96
|
+
self.token = token
|
|
87
97
|
|
|
88
98
|
async def run(self, request: WorkerExecutionRequest):
|
|
89
99
|
if self.pool is not None:
|
|
@@ -137,14 +147,19 @@ class SandboxRunner:
|
|
|
137
147
|
await asyncio.gather(controller_task, return_exceptions=True)
|
|
138
148
|
|
|
139
149
|
async def _run_remotely(self, request: WorkerExecutionRequest):
|
|
140
|
-
|
|
150
|
+
token_source = self.token
|
|
151
|
+
if token_source is None:
|
|
152
|
+
token = SandboxSettings().sandbox_token
|
|
153
|
+
elif isinstance(token_source, str):
|
|
154
|
+
token = token_source
|
|
155
|
+
else:
|
|
156
|
+
token = token_source()
|
|
157
|
+
if token is None:
|
|
141
158
|
raise RuntimeError("SANDBOX_TOKEN is required for remote codemode")
|
|
142
159
|
rx, tx = await asyncio.open_unix_connection(self.socket)
|
|
143
160
|
reader, writer = SandboxReader(rx), SandboxWriter(tx)
|
|
144
161
|
try:
|
|
145
|
-
await writer.write_message(
|
|
146
|
-
SandboxMessage.Run(run=request, token=settings.sandbox_token)
|
|
147
|
-
)
|
|
162
|
+
await writer.write_message(SandboxMessage.Run(run=request, token=token))
|
|
148
163
|
while True:
|
|
149
164
|
try:
|
|
150
165
|
msg = await reader.read_message()
|
|
@@ -291,9 +306,15 @@ class SandboxReader:
|
|
|
291
306
|
|
|
292
307
|
|
|
293
308
|
class SandboxSession:
|
|
294
|
-
def __init__(
|
|
309
|
+
def __init__(
|
|
310
|
+
self,
|
|
311
|
+
reader: SandboxReader,
|
|
312
|
+
writer: SandboxWriter,
|
|
313
|
+
callback_wait_seconds: float = 1.0,
|
|
314
|
+
):
|
|
295
315
|
self.reader = reader
|
|
296
316
|
self.writer = writer
|
|
317
|
+
self.callback_wait_seconds = callback_wait_seconds
|
|
297
318
|
self.runner = SandboxRunner(
|
|
298
319
|
pool=None, socket=None, callback=self._callback, debug=False
|
|
299
320
|
)
|
|
@@ -303,7 +324,7 @@ class SandboxSession:
|
|
|
303
324
|
async def run(self, request: WorkerExecutionRequest):
|
|
304
325
|
self.task, self.process = self.runner.run_in_process(request)
|
|
305
326
|
try:
|
|
306
|
-
await self._start_timeout(
|
|
327
|
+
await self._start_timeout(self.callback_wait_seconds)
|
|
307
328
|
if request.max_runtime_seconds is None:
|
|
308
329
|
clean_exit = await self.task
|
|
309
330
|
else:
|
|
@@ -358,7 +379,7 @@ class SandboxSession:
|
|
|
358
379
|
self.task.cancel()
|
|
359
380
|
return None
|
|
360
381
|
assert isinstance(response, SandboxMessage.Response)
|
|
361
|
-
await self._start_timeout(
|
|
382
|
+
await self._start_timeout(self.callback_wait_seconds)
|
|
362
383
|
return response.result
|
|
363
384
|
|
|
364
385
|
async def _start_timeout(self, timeout: float):
|
|
@@ -382,12 +403,15 @@ agents_running = prometheus_client.Gauge(
|
|
|
382
403
|
execution_observer = nucliadb_telemetry.metrics.Observer("arag_sandbox_execution")
|
|
383
404
|
|
|
384
405
|
|
|
385
|
-
async def run_sandbox_server(
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
406
|
+
async def run_sandbox_server(
|
|
407
|
+
*, token_verifier: Callable[[str], Awaitable[bool]] | None = None
|
|
408
|
+
):
|
|
409
|
+
server_settings = SandboxSettings()
|
|
410
|
+
assert server_settings.sandbox_socket is not None
|
|
411
|
+
sandbox_token = server_settings.sandbox_token
|
|
412
|
+
if token_verifier is None and sandbox_token is None:
|
|
389
413
|
raise RuntimeError("SANDBOX_TOKEN is required for the sandbox server")
|
|
390
|
-
if
|
|
414
|
+
if server_settings.sandbox_verify:
|
|
391
415
|
_verify_connectivity()
|
|
392
416
|
|
|
393
417
|
async def handler(rx: asyncio.StreamReader, tx: asyncio.StreamWriter):
|
|
@@ -397,10 +421,16 @@ async def run_sandbox_server():
|
|
|
397
421
|
async with asyncio.timeout(1):
|
|
398
422
|
msg = await reader.read_message()
|
|
399
423
|
assert isinstance(msg, SandboxMessage.Run)
|
|
400
|
-
|
|
424
|
+
token = msg.token or ""
|
|
425
|
+
valid_token = (
|
|
426
|
+
await token_verifier(token)
|
|
427
|
+
if token_verifier is not None
|
|
428
|
+
else hmac.compare_digest(token, sandbox_token or "")
|
|
429
|
+
)
|
|
430
|
+
if not valid_token:
|
|
401
431
|
raise PermissionError("Invalid sandbox token")
|
|
402
|
-
except
|
|
403
|
-
logger.warning("Rejected invalid sandbox connection")
|
|
432
|
+
except Exception as exc:
|
|
433
|
+
logger.warning("Rejected invalid sandbox connection: %r", exc)
|
|
404
434
|
writer.close()
|
|
405
435
|
await writer.wait_closed()
|
|
406
436
|
return
|
|
@@ -409,7 +439,9 @@ async def run_sandbox_server():
|
|
|
409
439
|
observation = execution_observer()
|
|
410
440
|
observation.start()
|
|
411
441
|
try:
|
|
412
|
-
session = SandboxSession(
|
|
442
|
+
session = SandboxSession(
|
|
443
|
+
reader, writer, SandboxSettings().sandbox_callback_wait_seconds
|
|
444
|
+
)
|
|
413
445
|
await session.run(msg.run)
|
|
414
446
|
except Exception as exc:
|
|
415
447
|
observation.set_status("error")
|
|
@@ -420,7 +452,7 @@ async def run_sandbox_server():
|
|
|
420
452
|
writer.close()
|
|
421
453
|
await writer.wait_closed()
|
|
422
454
|
|
|
423
|
-
server = await asyncio.start_unix_server(handler,
|
|
424
|
-
os.chmod(
|
|
455
|
+
server = await asyncio.start_unix_server(handler, server_settings.sandbox_socket)
|
|
456
|
+
os.chmod(server_settings.sandbox_socket, 0o600)
|
|
425
457
|
async with server:
|
|
426
458
|
await server.serve_forever()
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/__init__.py
RENAMED
|
@@ -39,13 +39,14 @@ from .models import (
|
|
|
39
39
|
HarnessToolCall,
|
|
40
40
|
)
|
|
41
41
|
from .storage import HarnessStorageProtocol, InMemoryHarnessStorage
|
|
42
|
-
from .tools import HarnessTool, tool
|
|
42
|
+
from .tools import HarnessTool, ToolCallContext, tool
|
|
43
43
|
from .tools.codemode import CodemodeInput, CodemodeOutput, codemode
|
|
44
44
|
from .usage import HarnessUsage, UsageLimitExceeded, UsageLimits
|
|
45
45
|
|
|
46
46
|
__all__ = [
|
|
47
47
|
"SYSTEM_PROMPT",
|
|
48
48
|
"AgentHarness",
|
|
49
|
+
"ToolCallContext",
|
|
49
50
|
"AgentResult",
|
|
50
51
|
"ChatCompletionChunk",
|
|
51
52
|
"ChatCompletionChoice",
|
|
@@ -23,7 +23,7 @@ from hyperforge.memory.memory import BaseSessionMemory
|
|
|
23
23
|
from hyperforge.models import Context, MemoryConfig, Rules
|
|
24
24
|
|
|
25
25
|
from .models import HarnessContextReference, HarnessContextType
|
|
26
|
-
from .tools import HarnessTool
|
|
26
|
+
from .tools import HarnessTool, ToolCallContext
|
|
27
27
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
29
|
from hyperforge.agent import Agent as HyperforgeAgent
|
|
@@ -64,8 +64,9 @@ class HarnessAgentToTool:
|
|
|
64
64
|
|
|
65
65
|
def as_tool(self) -> HarnessTool[AgentToolInput, AgentToolOutput]:
|
|
66
66
|
async def execute(
|
|
67
|
-
|
|
67
|
+
context: ToolCallContext, input_value: AgentToolInput
|
|
68
68
|
) -> AgentToolOutput:
|
|
69
|
+
harness = context.harness
|
|
69
70
|
memory = self.memory_factory(harness, input_value.prompt)
|
|
70
71
|
if inspect.isawaitable(memory):
|
|
71
72
|
memory = await memory
|
|
@@ -143,8 +144,9 @@ def _published_function_tool(
|
|
|
143
144
|
input_model = _published_input_model(method, function_id, definition)
|
|
144
145
|
|
|
145
146
|
async def execute(
|
|
146
|
-
|
|
147
|
+
context: ToolCallContext, input_value: BaseModel
|
|
147
148
|
) -> PublishedFunctionOutput:
|
|
149
|
+
harness = context.harness
|
|
148
150
|
compat_manager = manager or _compat_manager(harness)
|
|
149
151
|
memory = harness.execution_context.get("memory")
|
|
150
152
|
if memory is None:
|
|
@@ -23,7 +23,7 @@ from .models import (
|
|
|
23
23
|
HarnessToolCall,
|
|
24
24
|
)
|
|
25
25
|
from .storage import HarnessStorageProtocol, InMemoryHarnessStorage
|
|
26
|
-
from .tools import HarnessTool
|
|
26
|
+
from .tools import HarnessTool, ToolCallContext
|
|
27
27
|
from .tools.core import DictOutput, SendMessageInput, SpawnAgentInput, create_core_tools
|
|
28
28
|
from .usage import HarnessUsage, UsageLimitExceeded, UsageLimits
|
|
29
29
|
|
|
@@ -955,7 +955,8 @@ class AgentHarness:
|
|
|
955
955
|
async def _execute_tool_call(self, call: HarnessToolCall) -> HarnessMessage:
|
|
956
956
|
assert call.id is not None
|
|
957
957
|
await self.emit(
|
|
958
|
-
HarnessEventType.TOOL_REQUESTED,
|
|
958
|
+
HarnessEventType.TOOL_REQUESTED,
|
|
959
|
+
{"call": call.model_dump(mode="json")},
|
|
959
960
|
)
|
|
960
961
|
tool = self._tools.get(call.name)
|
|
961
962
|
try:
|
|
@@ -965,7 +966,8 @@ class AgentHarness:
|
|
|
965
966
|
elif tool.lazy_load and tool.name not in self._active_lazy_tools:
|
|
966
967
|
raise ValueError(f"Tool is not active: {call.name}")
|
|
967
968
|
else:
|
|
968
|
-
|
|
969
|
+
context = ToolCallContext(harness=self, name=call.name, id=call.id)
|
|
970
|
+
output = await tool.execute(context, call.arguments)
|
|
969
971
|
result = output.model_dump(mode="json")
|
|
970
972
|
reference = tool.context(output)
|
|
971
973
|
content = format_context(reference)
|
|
@@ -981,7 +983,7 @@ class AgentHarness:
|
|
|
981
983
|
context=reference,
|
|
982
984
|
)
|
|
983
985
|
except Exception as exc:
|
|
984
|
-
logger.
|
|
986
|
+
logger.info(
|
|
985
987
|
"Agent tool execution failed: tool=%s call_id=%s error_type=%s error=%s",
|
|
986
988
|
call.name,
|
|
987
989
|
call.id,
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/tools/codemode.py
RENAMED
|
@@ -10,7 +10,7 @@ from hyperforge.codemode import (
|
|
|
10
10
|
from hyperforge.codemode.sandbox import settings
|
|
11
11
|
from hyperforge.definition import FunctionDefinition
|
|
12
12
|
|
|
13
|
-
from . import HarnessTool, tool
|
|
13
|
+
from . import HarnessTool, ToolCallContext, tool
|
|
14
14
|
|
|
15
15
|
CODEMODE_TOOL_NAME = "codemode"
|
|
16
16
|
OUTPUT_FUNCTION_NAME = "output"
|
|
@@ -31,7 +31,10 @@ class CodemodeOutput(BaseModel):
|
|
|
31
31
|
"call output(value) to return a result."
|
|
32
32
|
),
|
|
33
33
|
)
|
|
34
|
-
async def codemode(
|
|
34
|
+
async def codemode(
|
|
35
|
+
context: ToolCallContext, input_value: CodemodeInput
|
|
36
|
+
) -> CodemodeOutput:
|
|
37
|
+
harness = context.harness
|
|
35
38
|
tools = {
|
|
36
39
|
tool.name: tool
|
|
37
40
|
for tool in harness.iter_tools()
|
|
@@ -54,7 +57,9 @@ async def codemode(harness: Any, input_value: CodemodeInput) -> CodemodeOutput:
|
|
|
54
57
|
harness.usage.tool_calls += 1
|
|
55
58
|
harness._check_limit("max_tool_calls", harness.usage.tool_calls)
|
|
56
59
|
arguments = _tool_arguments(tool, task.args, task.keyword_args)
|
|
57
|
-
output = await tool.execute(
|
|
60
|
+
output = await tool.execute(
|
|
61
|
+
ToolCallContext(harness=harness, name=tool.name), arguments
|
|
62
|
+
)
|
|
58
63
|
return output.model_dump(mode="json")
|
|
59
64
|
|
|
60
65
|
runner = (
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/tools/core.py
RENAMED
|
@@ -2,15 +2,12 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import uuid
|
|
4
4
|
from re import findall
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Any
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel
|
|
8
8
|
|
|
9
9
|
from ..models import HarnessEventType, HarnessMemory, HarnessMessage
|
|
10
|
-
from . import HarnessTool, tool
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from ..harness import AgentHarness
|
|
10
|
+
from . import HarnessTool, ToolCallContext, tool
|
|
14
11
|
|
|
15
12
|
|
|
16
13
|
class RememberInput(BaseModel):
|
|
@@ -78,8 +75,9 @@ def _search_terms(value: str) -> set[str]:
|
|
|
78
75
|
|
|
79
76
|
@tool(description="Search for additional tools that can be activated.")
|
|
80
77
|
async def search_tools(
|
|
81
|
-
|
|
78
|
+
context: ToolCallContext, input_value: SearchToolsInput
|
|
82
79
|
) -> ListOutput:
|
|
80
|
+
harness = context.harness
|
|
83
81
|
terms = _search_terms(input_value.query)
|
|
84
82
|
candidates: list[tuple[int, HarnessTool[Any, Any]]] = []
|
|
85
83
|
for candidate in harness._external_tools:
|
|
@@ -104,8 +102,9 @@ async def search_tools(
|
|
|
104
102
|
|
|
105
103
|
@tool(description="Activate additional tools by their exact names.")
|
|
106
104
|
async def activate_tools(
|
|
107
|
-
|
|
105
|
+
context: ToolCallContext, input_value: ActivateToolsInput
|
|
108
106
|
) -> DictOutput:
|
|
107
|
+
harness = context.harness
|
|
109
108
|
names = list(dict.fromkeys(input_value.names))
|
|
110
109
|
unknown = [
|
|
111
110
|
name
|
|
@@ -119,7 +118,8 @@ async def activate_tools(
|
|
|
119
118
|
|
|
120
119
|
|
|
121
120
|
@tool()
|
|
122
|
-
async def remember(
|
|
121
|
+
async def remember(context: ToolCallContext, input_value: RememberInput) -> DictOutput:
|
|
122
|
+
harness = context.harness
|
|
123
123
|
memory = HarnessMemory(
|
|
124
124
|
id=uuid.uuid4().hex,
|
|
125
125
|
text=input_value.text,
|
|
@@ -135,7 +135,8 @@ async def remember(harness: AgentHarness, input_value: RememberInput) -> DictOut
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
@tool()
|
|
138
|
-
async def recall(
|
|
138
|
+
async def recall(context: ToolCallContext, input_value: RecallInput) -> ListOutput:
|
|
139
|
+
harness = context.harness
|
|
139
140
|
memories = await harness.storage.recall(
|
|
140
141
|
scope=input_value.scope,
|
|
141
142
|
query=input_value.query,
|
|
@@ -144,7 +145,8 @@ async def recall(harness: AgentHarness, input_value: RecallInput) -> ListOutput:
|
|
|
144
145
|
|
|
145
146
|
|
|
146
147
|
@tool()
|
|
147
|
-
async def forget(
|
|
148
|
+
async def forget(context: ToolCallContext, input_value: ForgetInput) -> DictOutput:
|
|
149
|
+
harness = context.harness
|
|
148
150
|
await harness.storage.forget(input_value.id)
|
|
149
151
|
await harness.emit(HarnessEventType.MEMORY_FORGOTTEN, {"id": input_value.id})
|
|
150
152
|
return DictOutput(value={"id": input_value.id})
|
|
@@ -152,25 +154,26 @@ async def forget(harness: AgentHarness, input_value: ForgetInput) -> DictOutput:
|
|
|
152
154
|
|
|
153
155
|
@tool()
|
|
154
156
|
async def spawn_agent(
|
|
155
|
-
|
|
157
|
+
context: ToolCallContext, input_value: SpawnAgentInput
|
|
156
158
|
) -> DictOutput:
|
|
157
|
-
return await harness._child_agents.spawn(input_value)
|
|
159
|
+
return await context.harness._child_agents.spawn(input_value)
|
|
158
160
|
|
|
159
161
|
|
|
160
162
|
@tool()
|
|
161
163
|
async def send_message(
|
|
162
|
-
|
|
164
|
+
context: ToolCallContext, input_value: SendMessageInput
|
|
163
165
|
) -> DictOutput:
|
|
164
|
-
return await harness._child_agents.send_message(input_value)
|
|
166
|
+
return await context.harness._child_agents.send_message(input_value)
|
|
165
167
|
|
|
166
168
|
|
|
167
169
|
@tool()
|
|
168
|
-
async def wait_agent(
|
|
169
|
-
return await harness._child_agents.wait(input_value.agent_id)
|
|
170
|
+
async def wait_agent(context: ToolCallContext, input_value: AgentIdInput) -> DictOutput:
|
|
171
|
+
return await context.harness._child_agents.wait(input_value.agent_id)
|
|
170
172
|
|
|
171
173
|
|
|
172
174
|
@tool()
|
|
173
|
-
async def compact(
|
|
175
|
+
async def compact(context: ToolCallContext, input_value: CompactInput) -> DictOutput:
|
|
176
|
+
harness = context.harness
|
|
174
177
|
harness.messages = [
|
|
175
178
|
HarnessMessage(role="system", content=harness.system_prompt),
|
|
176
179
|
HarnessMessage(
|
|
@@ -185,8 +188,8 @@ async def compact(harness: AgentHarness, input_value: CompactInput) -> DictOutpu
|
|
|
185
188
|
|
|
186
189
|
|
|
187
190
|
@tool()
|
|
188
|
-
async def feedback(
|
|
189
|
-
response = await harness.request_feedback(
|
|
191
|
+
async def feedback(context: ToolCallContext, input_value: FeedbackInput) -> DictOutput:
|
|
192
|
+
response = await context.harness.request_feedback(
|
|
190
193
|
question=input_value.question,
|
|
191
194
|
response_schema={
|
|
192
195
|
"type": "object",
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/harness_sdk/tools/utils.py
RENAMED
|
@@ -16,11 +16,24 @@ if TYPE_CHECKING:
|
|
|
16
16
|
from ..harness import AgentHarness
|
|
17
17
|
|
|
18
18
|
type ToolHandler[InputT: BaseModel, OutputT: BaseModel] = Callable[
|
|
19
|
-
[
|
|
19
|
+
[ToolCallContext, InputT], Awaitable[OutputT]
|
|
20
20
|
]
|
|
21
21
|
type ContextFactory[OutputT: BaseModel] = Callable[[OutputT], HarnessContextReference]
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class ToolCallContext:
|
|
26
|
+
"""Execution context passed to a tool handler.
|
|
27
|
+
|
|
28
|
+
Provides the harness along with the identity of the tool call
|
|
29
|
+
currently being executed.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
harness: "AgentHarness"
|
|
33
|
+
name: str
|
|
34
|
+
id: str | None = None
|
|
35
|
+
|
|
36
|
+
|
|
24
37
|
@dataclass(frozen=True)
|
|
25
38
|
class HarnessTool[InputT: BaseModel, OutputT: BaseModel]:
|
|
26
39
|
name: str
|
|
@@ -38,10 +51,11 @@ class HarnessTool[InputT: BaseModel, OutputT: BaseModel]:
|
|
|
38
51
|
parameters = list(inspect.signature(self.handler).parameters.values())
|
|
39
52
|
if len(parameters) != 2:
|
|
40
53
|
raise TypeError(
|
|
41
|
-
f"Tool handler {self.name!r} must accept
|
|
54
|
+
f"Tool handler {self.name!r} must accept context and input parameters"
|
|
42
55
|
)
|
|
43
56
|
globalns = dict(getattr(self.handler, "__globals__", {}))
|
|
44
57
|
globalns.setdefault("AgentHarness", object)
|
|
58
|
+
globalns.setdefault("ToolCallContext", ToolCallContext)
|
|
45
59
|
hints = get_type_hints(self.handler, globalns=globalns)
|
|
46
60
|
input_model = hints.get(parameters[1].name)
|
|
47
61
|
output_model = hints.get("return")
|
|
@@ -65,12 +79,12 @@ class HarnessTool[InputT: BaseModel, OutputT: BaseModel]:
|
|
|
65
79
|
return self._parameters
|
|
66
80
|
|
|
67
81
|
def __call__(
|
|
68
|
-
self,
|
|
82
|
+
self, context: ToolCallContext, input_value: InputT
|
|
69
83
|
) -> Awaitable[OutputT]:
|
|
70
|
-
return self.handler(
|
|
84
|
+
return self.handler(context, input_value)
|
|
71
85
|
|
|
72
86
|
async def execute(
|
|
73
|
-
self,
|
|
87
|
+
self, context: ToolCallContext, arguments: dict[str, Any]
|
|
74
88
|
) -> OutputT:
|
|
75
89
|
if error := arguments.get("_tool_error"):
|
|
76
90
|
raise ValueError(str(error))
|
|
@@ -85,7 +99,7 @@ class HarnessTool[InputT: BaseModel, OutputT: BaseModel]:
|
|
|
85
99
|
value = self.input_model.model_validate(arguments)
|
|
86
100
|
except ValidationError as exc:
|
|
87
101
|
raise ValueError(f"Invalid {self.name} arguments: {exc}") from exc
|
|
88
|
-
result = await self.handler(
|
|
102
|
+
result = await self.handler(context, value)
|
|
89
103
|
return self.output_model.model_validate(result)
|
|
90
104
|
|
|
91
105
|
def context(self, output: OutputT) -> HarnessContextReference:
|
|
@@ -123,4 +137,4 @@ def _is_model_type(value: Any) -> bool:
|
|
|
123
137
|
return isinstance(value, type) and issubclass(value, BaseModel)
|
|
124
138
|
|
|
125
139
|
|
|
126
|
-
__all__ = ["ContextFactory", "HarnessTool", "ToolHandler", "tool"]
|
|
140
|
+
__all__ = ["ContextFactory", "HarnessTool", "ToolCallContext", "ToolHandler", "tool"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/api/v1/mcp_interaction.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/db/llm_migration_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/standalone/ui_router.py
RENAMED
|
File without changes
|
{hyperforge-1.0.0.post326 → hyperforge-1.0.0.post332}/src/hyperforge/static/assets/index-DLejS5jC.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|