futurehouse-client 0.4.0__py3-none-any.whl → 0.4.1__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.
@@ -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
  ]
@@ -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: PythonVersion = Field(
424
- default=PythonVersion.V3_12,
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.0'
32
- __version_tuple__ = version_tuple = (0, 4, 0)
33
-
34
- __commit_id__ = commit_id = None
20
+ __version__ = version = '0.4.1'
21
+ __version_tuple__ = version_tuple = (0, 4, 1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: futurehouse-client
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: A client for interacting with endpoints of the FutureHouse service.
5
5
  Author-email: FutureHouse technical staff <hello@futurehouse.org>
6
6
  License: Apache License
@@ -1,11 +1,11 @@
1
- futurehouse_client/__init__.py,sha256=BztM_ntbgmIEjzvnBWcvPhvLjM8xGDFCK0Upf3-nIn8,488
1
+ futurehouse_client/__init__.py,sha256=PvFTkocA-hobsWoDEBEdrUgLIbuVbDs_0nvMdImJmHk,707
2
2
  futurehouse_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- futurehouse_client/version.py,sha256=2_0GUP7yBCXRus-qiJKxQD62z172WSs1sQ6DVpPsbmM,704
3
+ futurehouse_client/version.py,sha256=yF2DwGUoQKNnLhAbpZX8kCQKjw77EZzhRk7_OTftets,511
4
4
  futurehouse_client/clients/__init__.py,sha256=-HXNj-XJ3LRO5XM6MZ709iPs29YpApss0Q2YYg1qMZw,280
5
5
  futurehouse_client/clients/job_client.py,sha256=D51_qTxya6g5Wfg_ZfJdP031TV_YDJeXkGMiYAJ1qRc,11962
6
- futurehouse_client/clients/rest_client.py,sha256=iGBMTdtSVRA2eaqdLVsHrQoF8ToKOnFfbIVhfibjzFs,97022
6
+ futurehouse_client/clients/rest_client.py,sha256=NyK6-YDcvswWcRmvMjUWvvfuE4eYMmI0bWM4Qnkgr8Y,99684
7
7
  futurehouse_client/models/__init__.py,sha256=kQ4R7VEuRxO0IQEW_sk9CndBL7zzl8rUKI24ddyYLM0,647
8
- futurehouse_client/models/app.py,sha256=TGoAeENNPc5mSBkMHjh-Z8VIlnaUNcoWUJLxUhRIkEE,31868
8
+ futurehouse_client/models/app.py,sha256=UUg17I3zk6cH_7mrdojHGYvQfm_SeDkuUxsPlRyIYz0,31895
9
9
  futurehouse_client/models/client.py,sha256=n4HD0KStKLm6Ek9nL9ylP-bkK10yzAaD1uIDF83Qp_A,1828
10
10
  futurehouse_client/models/rest.py,sha256=ybelLsyTsKYud7DYUCF0sFF6u81bl8WmS_wWAnbX-0M,3382
11
11
  futurehouse_client/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -13,8 +13,9 @@ futurehouse_client/utils/auth.py,sha256=tgWELjKfg8eWme_qdcRmc8TjQN9DVZuHHaVXZNHL
13
13
  futurehouse_client/utils/general.py,sha256=A_rtTiYW30ELGEZlWCIArO7q1nEmqi8hUlmBRYkMQ_c,767
14
14
  futurehouse_client/utils/module_utils.py,sha256=aFyd-X-pDARXz9GWpn8SSViUVYdSbuy9vSkrzcVIaGI,4955
15
15
  futurehouse_client/utils/monitoring.py,sha256=UjRlufe67kI3VxRHOd5fLtJmlCbVA2Wqwpd4uZhXkQM,8728
16
- futurehouse_client-0.4.0.dist-info/licenses/LICENSE,sha256=oQ9ZHjUi-_6GfP3gs14FlPb0OlGwE1QCCKFGnJ4LD2I,11341
17
- futurehouse_client-0.4.0.dist-info/METADATA,sha256=cDJvUHmNJHAFw6kELrjYIOHyIeSeYZuaDwHJskg8wjs,26797
18
- futurehouse_client-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- futurehouse_client-0.4.0.dist-info/top_level.txt,sha256=TRuLUCt_qBnggdFHCX4O_BoCu1j2X43lKfIZC-ElwWY,19
20
- futurehouse_client-0.4.0.dist-info/RECORD,,
16
+ futurehouse_client/utils/world_model_tools.py,sha256=Ctiy-EfK7EXrjmKO_nI6V5VhOJyHKWc0sKwa8Q0HAAo,2292
17
+ futurehouse_client-0.4.1.dist-info/licenses/LICENSE,sha256=oQ9ZHjUi-_6GfP3gs14FlPb0OlGwE1QCCKFGnJ4LD2I,11341
18
+ futurehouse_client-0.4.1.dist-info/METADATA,sha256=ucpuTCGRrKqqgXT8KEhy9XNLT1_e3LQdtPK-IcEKB0g,26797
19
+ futurehouse_client-0.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
+ futurehouse_client-0.4.1.dist-info/top_level.txt,sha256=TRuLUCt_qBnggdFHCX4O_BoCu1j2X43lKfIZC-ElwWY,19
21
+ futurehouse_client-0.4.1.dist-info/RECORD,,