futurehouse-client 0.4.0__tar.gz → 0.4.1__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.
- {futurehouse_client-0.4.0/futurehouse_client.egg-info → futurehouse_client-0.4.1}/PKG-INFO +1 -1
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/__init__.py +8 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/clients/rest_client.py +73 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/models/app.py +4 -7
- futurehouse_client-0.4.1/futurehouse_client/utils/world_model_tools.py +70 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/version.py +3 -16
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1/futurehouse_client.egg-info}/PKG-INFO +1 -1
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client.egg-info/SOURCES.txt +1 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/LICENSE +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/README.md +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/docs/__init__.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/docs/client_notebook.ipynb +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/clients/__init__.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/clients/job_client.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/models/__init__.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/models/client.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/models/rest.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/py.typed +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/utils/__init__.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/utils/auth.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/utils/general.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/utils/module_utils.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/utils/monitoring.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client.egg-info/dependency_links.txt +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client.egg-info/requires.txt +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client.egg-info/top_level.txt +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/pyproject.toml +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/setup.cfg +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/tests/test_client.py +0 -0
- {futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/tests/test_rest.py +0 -0
@@ -8,6 +8,11 @@ from .models.app import (
|
|
8
8
|
TaskResponse,
|
9
9
|
TaskResponseVerbose,
|
10
10
|
)
|
11
|
+
from .utils.world_model_tools import (
|
12
|
+
create_world_model_tool,
|
13
|
+
make_world_model_tools,
|
14
|
+
search_world_model_tool,
|
15
|
+
)
|
11
16
|
|
12
17
|
__all__ = [
|
13
18
|
"FinchTaskResponse",
|
@@ -19,4 +24,7 @@ __all__ = [
|
|
19
24
|
"TaskRequest",
|
20
25
|
"TaskResponse",
|
21
26
|
"TaskResponseVerbose",
|
27
|
+
"create_world_model_tool",
|
28
|
+
"make_world_model_tools",
|
29
|
+
"search_world_model_tool",
|
22
30
|
]
|
{futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/clients/rest_client.py
RENAMED
@@ -136,6 +136,10 @@ class WorldModelCreationError(RestClientError):
|
|
136
136
|
"""Raised when there's an error creating a world model."""
|
137
137
|
|
138
138
|
|
139
|
+
class WorldModelDeletionError(RestClientError):
|
140
|
+
"""Raised when there's an error deleting a world model."""
|
141
|
+
|
142
|
+
|
139
143
|
class ProjectError(RestClientError):
|
140
144
|
"""Raised when there's an error with trajectory group operations."""
|
141
145
|
|
@@ -1593,6 +1597,49 @@ class RestClient:
|
|
1593
1597
|
except Exception as e:
|
1594
1598
|
raise WorldModelFetchError(f"An unexpected error occurred: {e!r}.") from e
|
1595
1599
|
|
1600
|
+
@retry(
|
1601
|
+
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
1602
|
+
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
1603
|
+
retry=retry_if_connection_error,
|
1604
|
+
)
|
1605
|
+
def search_world_models(
|
1606
|
+
self,
|
1607
|
+
query: str,
|
1608
|
+
size: int = 10,
|
1609
|
+
total_search_size: int = 50,
|
1610
|
+
search_all_versions: bool = False,
|
1611
|
+
) -> list[str]:
|
1612
|
+
"""Search for world models.
|
1613
|
+
|
1614
|
+
Args:
|
1615
|
+
query: The search query.
|
1616
|
+
size: The number of results to return.
|
1617
|
+
total_search_size: The number of results to search for.
|
1618
|
+
search_all_versions: Whether to search all versions of the world model or just the latest one.
|
1619
|
+
|
1620
|
+
Returns:
|
1621
|
+
A list of world model names.
|
1622
|
+
"""
|
1623
|
+
try:
|
1624
|
+
# Use the consolidated endpoint with search parameters
|
1625
|
+
response = self.client.get(
|
1626
|
+
"/v0.1/world-models",
|
1627
|
+
params={
|
1628
|
+
"q": query,
|
1629
|
+
"size": size,
|
1630
|
+
"search_all_versions": search_all_versions,
|
1631
|
+
},
|
1632
|
+
)
|
1633
|
+
response.raise_for_status()
|
1634
|
+
# The new endpoint returns a list of models directly
|
1635
|
+
return response.json()
|
1636
|
+
except HTTPStatusError as e:
|
1637
|
+
raise WorldModelFetchError(
|
1638
|
+
f"Error searching world models: {e.response.status_code} - {e.response.text}"
|
1639
|
+
) from e
|
1640
|
+
except Exception as e:
|
1641
|
+
raise WorldModelFetchError(f"An unexpected error occurred: {e!r}.") from e
|
1642
|
+
|
1596
1643
|
@retry(
|
1597
1644
|
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
1598
1645
|
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
@@ -1668,6 +1715,32 @@ class RestClient:
|
|
1668
1715
|
f"An unexpected error occurred during world model creation: {e!r}."
|
1669
1716
|
) from e
|
1670
1717
|
|
1718
|
+
@retry(
|
1719
|
+
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
1720
|
+
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
1721
|
+
retry=retry_if_connection_error,
|
1722
|
+
)
|
1723
|
+
async def delete_world_model(self, world_model_id: UUID) -> None:
|
1724
|
+
"""Delete a world model snapshot by its ID.
|
1725
|
+
|
1726
|
+
Args:
|
1727
|
+
world_model_id: The unique ID of the world model snapshot to delete.
|
1728
|
+
|
1729
|
+
Raises:
|
1730
|
+
WorldModelDeletionError: If the API call fails.
|
1731
|
+
"""
|
1732
|
+
try:
|
1733
|
+
response = await self.async_client.delete(
|
1734
|
+
f"/v0.1/world-models/{world_model_id}"
|
1735
|
+
)
|
1736
|
+
response.raise_for_status()
|
1737
|
+
except HTTPStatusError as e:
|
1738
|
+
raise WorldModelDeletionError(
|
1739
|
+
f"Error deleting world model: {e.response.status_code} - {e.response.text}"
|
1740
|
+
) from e
|
1741
|
+
except Exception as e:
|
1742
|
+
raise WorldModelDeletionError(f"An unexpected error occurred: {e}") from e
|
1743
|
+
|
1671
1744
|
@retry(
|
1672
1745
|
stop=stop_after_attempt(MAX_RETRY_ATTEMPTS),
|
1673
1746
|
wait=wait_exponential(multiplier=RETRY_MULTIPLIER, max=MAX_RETRY_WAIT),
|
@@ -27,10 +27,7 @@ if TYPE_CHECKING:
|
|
27
27
|
MAX_CROW_JOB_RUN_TIMEOUT = 60 * 60 * 24 # 24 hours in sec
|
28
28
|
MIN_CROW_JOB_RUN_TIMEOUT = 0 # sec
|
29
29
|
|
30
|
-
|
31
|
-
class PythonVersion(StrEnum):
|
32
|
-
V3_11 = "3.11"
|
33
|
-
V3_12 = "3.12"
|
30
|
+
DEFAULT_PYTHON_VERSION_USED_FOR_JOB_BUILDS = "3.13"
|
34
31
|
|
35
32
|
|
36
33
|
class AuthType(StrEnum):
|
@@ -420,9 +417,9 @@ class JobDeploymentConfig(BaseModel):
|
|
420
417
|
description="The configuration for the cloud run container.",
|
421
418
|
)
|
422
419
|
|
423
|
-
python_version:
|
424
|
-
default=
|
425
|
-
description="The python version your docker image should build with.",
|
420
|
+
python_version: str = Field(
|
421
|
+
default=DEFAULT_PYTHON_VERSION_USED_FOR_JOB_BUILDS,
|
422
|
+
description="The python version your docker image should build with (e.g., '3.11', '3.12', '3.13').",
|
426
423
|
)
|
427
424
|
|
428
425
|
agent: Agent | AgentConfig | str = Field(
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import os
|
2
|
+
from uuid import UUID
|
3
|
+
|
4
|
+
from aviary.core import Tool
|
5
|
+
|
6
|
+
from futurehouse_client.clients.rest_client import RestClient
|
7
|
+
from futurehouse_client.models.app import Stage
|
8
|
+
from futurehouse_client.models.rest import WorldModel
|
9
|
+
|
10
|
+
|
11
|
+
class WorldModelTools:
|
12
|
+
_client: RestClient | None = None
|
13
|
+
|
14
|
+
@classmethod
|
15
|
+
def _get_client(cls) -> RestClient:
|
16
|
+
"""Lazy initialization of the RestClient to avoid validation errors during import."""
|
17
|
+
if cls._client is None:
|
18
|
+
api_key = os.getenv("FH_PLATFORM_API_KEY")
|
19
|
+
if not api_key:
|
20
|
+
raise ValueError(
|
21
|
+
"FH_PLATFORM_API_KEY environment variable is required for WorldModelTools"
|
22
|
+
)
|
23
|
+
cls._client = RestClient(
|
24
|
+
stage=Stage.from_string(os.getenv("CROW_ENV", "dev")),
|
25
|
+
api_key=api_key,
|
26
|
+
)
|
27
|
+
return cls._client
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def create_world_model(name: str, description: str, content: str) -> UUID:
|
31
|
+
"""Create a new world model.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
name: The name of the world model.
|
35
|
+
description: A description of the world model.
|
36
|
+
content: The content/data of the world model.
|
37
|
+
|
38
|
+
Returns:
|
39
|
+
UUID: The ID of the newly created world model.
|
40
|
+
"""
|
41
|
+
world_model = WorldModel(
|
42
|
+
name=name,
|
43
|
+
description=description,
|
44
|
+
content=content,
|
45
|
+
)
|
46
|
+
return WorldModelTools._get_client().create_world_model(world_model)
|
47
|
+
|
48
|
+
@staticmethod
|
49
|
+
def search_world_models(query: str, size: int = 10) -> list[str]:
|
50
|
+
"""Search for world models using a text query.
|
51
|
+
|
52
|
+
Args:
|
53
|
+
query: The search query string to match against world model content.
|
54
|
+
size: The number of results to return (default: 10).
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
list[str]: A list of world model IDs that match the search query.
|
58
|
+
"""
|
59
|
+
return WorldModelTools._get_client().search_world_models(query, size=size)
|
60
|
+
|
61
|
+
|
62
|
+
create_world_model_tool = Tool.from_function(WorldModelTools.create_world_model)
|
63
|
+
search_world_model_tool = Tool.from_function(WorldModelTools.search_world_models)
|
64
|
+
|
65
|
+
|
66
|
+
def make_world_model_tools() -> list[Tool]:
|
67
|
+
return [
|
68
|
+
search_world_model_tool,
|
69
|
+
create_world_model_tool,
|
70
|
+
]
|
@@ -1,14 +1,7 @@
|
|
1
1
|
# file generated by setuptools-scm
|
2
2
|
# don't change, don't track in version control
|
3
3
|
|
4
|
-
__all__ = [
|
5
|
-
"__version__",
|
6
|
-
"__version_tuple__",
|
7
|
-
"version",
|
8
|
-
"version_tuple",
|
9
|
-
"__commit_id__",
|
10
|
-
"commit_id",
|
11
|
-
]
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
12
5
|
|
13
6
|
TYPE_CHECKING = False
|
14
7
|
if TYPE_CHECKING:
|
@@ -16,19 +9,13 @@ if TYPE_CHECKING:
|
|
16
9
|
from typing import Union
|
17
10
|
|
18
11
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
19
|
-
COMMIT_ID = Union[str, None]
|
20
12
|
else:
|
21
13
|
VERSION_TUPLE = object
|
22
|
-
COMMIT_ID = object
|
23
14
|
|
24
15
|
version: str
|
25
16
|
__version__: str
|
26
17
|
__version_tuple__: VERSION_TUPLE
|
27
18
|
version_tuple: VERSION_TUPLE
|
28
|
-
commit_id: COMMIT_ID
|
29
|
-
__commit_id__: COMMIT_ID
|
30
19
|
|
31
|
-
__version__ = version = '0.4.
|
32
|
-
__version_tuple__ = version_tuple = (0, 4,
|
33
|
-
|
34
|
-
__commit_id__ = commit_id = 'g5229864ab'
|
20
|
+
__version__ = version = '0.4.1'
|
21
|
+
__version_tuple__ = version_tuple = (0, 4, 1)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/clients/__init__.py
RENAMED
File without changes
|
{futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/clients/job_client.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
|
{futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/utils/module_utils.py
RENAMED
File without changes
|
{futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client/utils/monitoring.py
RENAMED
File without changes
|
File without changes
|
{futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client.egg-info/requires.txt
RENAMED
File without changes
|
{futurehouse_client-0.4.0 → futurehouse_client-0.4.1}/futurehouse_client.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|