diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 72ddaded..c9a1723d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -72,7 +72,6 @@ repos: - fastapi>=0.109 # Match pyproject.toml - fhaviary>=0.8.2 # Match pyproject.toml - httpx - - litellm>=1.40.15,!=1.49.4,!=1.49.5,!=1.49.6 # Match pyproject.toml - numpy>=1.20 # Match pyproject.toml - pydantic~=2.0 # Match pyproject.toml - tenacity diff --git a/ldp/alg/optimizer/ape.py b/ldp/alg/optimizer/ape.py index b0eceaad..110eb7b4 100644 --- a/ldp/alg/optimizer/ape.py +++ b/ldp/alg/optimizer/ape.py @@ -7,6 +7,8 @@ from typing import Any, Self, cast from aviary.core import Message +from llmclient import LLMResult +from llmclient import MultipleCompletionLLMModel as LLMModel from pydantic import ( BaseModel, ConfigDict, @@ -21,7 +23,6 @@ from ldp.alg.optimizer.opt import Optimizer from ldp.data_structures import Trajectory from ldp.graph import LLMCallOp, OpResult, PromptOp -from ldp.llms import LLMModel, LLMResult logger = logging.getLogger(__name__) @@ -285,7 +286,7 @@ async def _get_updated_prompt( ) ), ] - result = await self.llm.call(messages, output_type=OutputPrompt) + result = await self.llm.call_single(messages, output_type=OutputPrompt) message_content = cast(str, cast(list[Message], result.messages)[-1].content) try: return OutputPrompt.model_validate_json(message_content).prompt diff --git a/ldp/graph/common_ops.py b/ldp/graph/common_ops.py index 25b4ac6d..ac83b2e0 100644 --- a/ldp/graph/common_ops.py +++ b/ldp/graph/common_ops.py @@ -13,16 +13,15 @@ import numpy as np import tree from aviary.core import Message, Tool, ToolRequestMessage, is_coroutine_callable -from pydantic import BaseModel - -from ldp.llms import ( +from llmclient import ( EmbeddingModel, HybridEmbeddingModel, - LiteEmbeddingModel, - LLMModel, + LiteLLMEmbeddingModel, LLMResult, SparseEmbeddingModel, ) +from llmclient import MultipleCompletionLLMModel as LLMModel +from pydantic import BaseModel from .gradient_estimators import assign_constant_grads from .memory import Memory, MemoryModel, UIndexMemoryModel @@ -254,7 +253,9 @@ async def forward( # if no tools are provided, tool_choice must be 'none' tool_choice = "none" - result = await model.call(messages=msgs, tools=tools, tool_choice=tool_choice) + result = await model.call_single( + messages=msgs, tools=tools, tool_choice=tool_choice + ) if result.messages is None: raise ValueError("No messages returned") @@ -306,7 +307,7 @@ async def compute_logprob( # are consistent - not sure we'd be sampling from the same distribution as N independent samples. # TODO: think about whether sampling params besides temperature need to be accounted for, like top_p results = await asyncio.gather(*[ - model.call(temperature=1, **model_kwargs) + model.call_single(temperature=1, **model_kwargs) for _ in range(self.num_samples_partition_estimate) ]) temp_factor = 1.0 / temperature - 1.0 @@ -406,18 +407,18 @@ def __init__( emb_models: list[EmbeddingModel] = [] if dense_embedding_dim > 0: emb_models.append( - LiteEmbeddingModel( + LiteLLMEmbeddingModel( name=dense_embedding, - dimensions=dense_embedding_dim, + ndim=dense_embedding_dim, embed_kwargs=embedding_model_kwargs, ) ) if sparse_embedding_dim > 0: - emb_models.append(SparseEmbeddingModel(dimensions=sparse_embedding_dim)) + emb_models.append(SparseEmbeddingModel(ndim=sparse_embedding_dim)) self.embedding = HybridEmbeddingModel(models=emb_models) async def forward(self, string_input: str) -> np.ndarray: - return await self.embedding.embed_text(string_input) + return np.array(await self.embedding.embed_document(string_input)) @classmethod def backward( diff --git a/ldp/graph/memory.py b/ldp/graph/memory.py index 5e820576..293f66cb 100644 --- a/ldp/graph/memory.py +++ b/ldp/graph/memory.py @@ -7,6 +7,7 @@ import numpy as np import numpy.typing as npt +from llmclient import EmbeddingModel from pydantic import ( BaseModel, ConfigDict, @@ -18,8 +19,6 @@ ) from usearch.index import Index -from ldp.llms import EmbeddingModel - if TYPE_CHECKING: from .common_ops import MemoryOp from .op_utils import CallID @@ -128,7 +127,7 @@ def enforce_empty(cls, v: dict) -> dict: async def add_memory(self, memory: Memory) -> None: key = await self._add_to_index( - embedding=await self.embedding_model.embed_text(memory.query) + embedding=np.array(await self.embedding_model.embed_document(memory.query)) ) self.memories[key] = memory @@ -138,7 +137,8 @@ async def get_memory( self, query: str, matches: int = DEFAULT_MEMORY_MATCHES ) -> list[Memory]: return await self._search_index( - embedding=await self.embedding_model.embed_text(query), matches=matches + embedding=np.array(await self.embedding_model.embed_document(query)), + matches=matches, ) def __len__(self) -> int: @@ -148,7 +148,7 @@ def __len__(self) -> int: async def safe_access_index(self) -> AsyncIterator[TIndex]: """Get the internal Index under the protection of an internal Lock.""" # pylint bug, SEE: https://github.com/pylint-dev/pylint/issues/9813 - async with self._index_lock: # pylint: disable=not-async-context-manager + async with self._index_lock: yield self._index @abstractmethod @@ -167,9 +167,9 @@ class UIndexMemoryModel(MemoryModel[Index]): def __init__(self, **kwargs): super().__init__(**kwargs) - if not self.embedding_model.dimensions: + if not self.embedding_model.ndim: raise TypeError("Specify dimensions to the embedding model.") - self._index = Index(ndim=self.embedding_model.dimensions) + self._index = Index(ndim=self.embedding_model.ndim) async def _add_to_index(self, embedding: np.ndarray) -> int: async with self.safe_access_index() as index: diff --git a/ldp/graph/modules/reflect.py b/ldp/graph/modules/reflect.py index 40af0bd7..ab60a603 100644 --- a/ldp/graph/modules/reflect.py +++ b/ldp/graph/modules/reflect.py @@ -5,8 +5,7 @@ from ldp.graph import ConfigOp, FxnOp, LLMCallOp, PromptOp, compute_graph from ldp.graph.ops import ResultOrValue -from ldp.llms import append_to_sys -from ldp.llms.prompts import indent_xml +from ldp.llms import append_to_sys, indent_xml class ReflectModuleConfig(BaseModel): diff --git a/ldp/llms/__init__.py b/ldp/llms/__init__.py index 7795d172..d4df5bb6 100644 --- a/ldp/llms/__init__.py +++ b/ldp/llms/__init__.py @@ -1,21 +1,24 @@ -from .chat import ( - JSONSchemaValidationError, - LLMModel, +from llmclient import ( LLMResult, - MultipleCompletionLLMModel, sum_logprobs, validate_json_completion, ) -from .embeddings import ( +from llmclient import MultipleCompletionLLMModel as LLMModel +from llmclient.embeddings import ( EmbeddingModel, EmbeddingModes, HybridEmbeddingModel, - LiteEmbeddingModel, + LiteLLMEmbeddingModel, SparseEmbeddingModel, ) +from llmclient.exceptions import ( + JSONSchemaValidationError, +) + from .prompts import ( append_to_messages, append_to_sys, + indent_xml, prepend_sys, prepend_sys_and_append_sys, ) @@ -27,11 +30,11 @@ "JSONSchemaValidationError", "LLMModel", "LLMResult", - "LiteEmbeddingModel", - "MultipleCompletionLLMModel", + "LiteLLMEmbeddingModel", "SparseEmbeddingModel", "append_to_messages", "append_to_sys", + "indent_xml", "prepend_sys", "prepend_sys_and_append_sys", "sum_logprobs", diff --git a/ldp/llms/chat.py b/ldp/llms/chat.py deleted file mode 100644 index 4aa506a5..00000000 --- a/ldp/llms/chat.py +++ /dev/null @@ -1,371 +0,0 @@ -import asyncio -import json -from collections.abc import AsyncGenerator, Callable, Iterable, Mapping -from datetime import datetime -from typing import Any, ClassVar, Self, TypeAlias, cast -from uuid import UUID, uuid4 - -import litellm -from aviary.core import ( - Message, - Tool, - ToolRequestMessage, - ToolsAdapter, - is_coroutine_callable, -) -from pydantic import BaseModel, ConfigDict, Field, ValidationError, model_validator - -# Yes, this is a hack, it mostly matches -# https://github.com/python-jsonschema/referencing/blob/v0.35.1/referencing/jsonschema.py#L20-L21 -JSONSchema: TypeAlias = Mapping[str, Any] - - -class JSONSchemaValidationError(ValueError): - """Raised when the completion does not match the specified schema.""" - - -class LLMResult(BaseModel): - """A class to hold the result of a LLM completion.""" - - id: UUID = Field(default_factory=uuid4) - config: dict | None = None - prompt: list[Message] | None = Field( - default=None, description="Messages sent to the LLM." - ) - messages: list[Message] | None = Field( - default=None, description="Messages received from the LLM." - ) - prompt_count: int = Field(default=0, description="Count of prompt tokens.") - completion_count: int = Field(default=0, description="Count of completion tokens.") - model: str - date: str = Field(default_factory=datetime.now().isoformat) - seconds_to_first_token: float | None = None - seconds_to_last_token: float = 0 - logprob: float | None = Field( - default=None, description="Sum of logprobs in the completion." - ) - system_fingerprint: str | None = Field( - default=None, description="System fingerprint received from the LLM." - ) - - @property - def prompt_and_completion_costs(self) -> tuple[float, float]: - """Get a two-tuple of prompt tokens cost and completion tokens cost, in USD.""" - return litellm.cost_per_token( - self.model, - prompt_tokens=self.prompt_count, - completion_tokens=self.completion_count, - ) - - @property - def provider(self) -> str: - """Get the model provider's name (e.g. "openai", "mistral").""" - return litellm.get_llm_provider(self.model)[1] - - def get_supported_openai_params(self) -> list[str] | None: - """Get the supported OpenAI parameters for the model.""" - return litellm.get_supported_openai_params(self.model) - - -def sum_logprobs(choice: litellm.utils.Choices) -> float | None: - """Calculate the sum of the log probabilities of an LLM completion (a Choices object). - - Args: - choice: A sequence of choices from the completion. - - Returns: - The sum of the log probabilities of the choice. - """ - try: - logprob_obj = choice.logprobs - except AttributeError: - return None - if isinstance(logprob_obj, dict): - if logprob_obj.get("content"): - return sum( - logprob_info["logprob"] for logprob_info in logprob_obj["content"] - ) - elif choice.logprobs.content: - return sum(logprob_info.logprob for logprob_info in choice.logprobs.content) - return None - - -def validate_json_completion( - completion: litellm.ModelResponse, output_type: type[BaseModel] | JSONSchema -) -> None: - """Validate a completion against a JSON schema. - - Args: - completion: The completion to validate. - output_type: A JSON schema or a Pydantic model to validate the completion. - """ - try: - for choice in completion.choices: - if not hasattr(choice, "message") or not choice.message.content: - continue - # make sure it is a JSON completion, even if None - # We do want to modify the underlying message - # so that users of it can just parse it as expected - choice.message.content = ( - choice.message.content.split("```json")[-1].split("```")[0] or "" - ) - if isinstance(output_type, Mapping): # JSON schema - litellm.litellm_core_utils.json_validation_rule.validate_schema( - schema=dict(output_type), response=choice.message.content - ) - else: - output_type.model_validate_json(choice.message.content) - except ValidationError as err: - raise JSONSchemaValidationError( - "The completion does not match the specified schema." - ) from err - - -class MultipleCompletionLLMModel(BaseModel): - """Run n completions at once, all starting from the same messages.""" - - model_config = ConfigDict(extra="forbid") - - # this should keep the original model - # if fine-tuned, this should still refer to the base model - name: str = "unknown" - config: dict = Field( - default={ - "model": "gpt-3.5-turbo", # Default model should have cheap input/output for testing - "temperature": 0.1, - } - ) - encoding: Any | None = None - - def __str__(self) -> str: - return f"{type(self).__name__} {self.name}" - - @model_validator(mode="after") - def set_model_name(self) -> Self: - if ( - self.config.get("model") in {"gpt-3.5-turbo", None} - and self.name != "unknown" - ) or (self.name != "unknown" and "model" not in self.config): - self.config["model"] = self.name - elif "model" in self.config and self.name == "unknown": - self.name = self.config["model"] - # note we do not consider case where both are set - # because that could be true if the model is fine-tuned - return self - - async def achat( - self, messages: Iterable[Message], **kwargs - ) -> litellm.ModelResponse: - return await litellm.acompletion( - messages=[m.model_dump(by_alias=True) for m in messages], - **(self.config | kwargs), - ) - - async def achat_iter(self, messages: Iterable[Message], **kwargs) -> AsyncGenerator: - return cast( - AsyncGenerator, - await litellm.acompletion( - messages=[m.model_dump(by_alias=True) for m in messages], - stream=True, - stream_options={ - "include_usage": True, # Included to get prompt token counts - }, - **(self.config | kwargs), - ), - ) - - # SEE: https://platform.openai.com/docs/api-reference/chat/create#chat-create-tool_choice - # > `none` means the model will not call any tool and instead generates a message. - # > `auto` means the model can pick between generating a message or calling one or more tools. - # > `required` means the model must call one or more tools. - NO_TOOL_CHOICE: ClassVar[str] = "none" - MODEL_CHOOSES_TOOL: ClassVar[str] = "auto" - TOOL_CHOICE_REQUIRED: ClassVar[str] = "required" - # None means we won't provide a tool_choice to the LLM API - UNSPECIFIED_TOOL_CHOICE: ClassVar[None] = None - - async def call( # noqa: C901, PLR0915 - self, - messages: list[Message], - callbacks: list[Callable] | None = None, - output_type: type[BaseModel] | JSONSchema | None = None, - tools: list[Tool] | None = None, - tool_choice: Tool | str | None = TOOL_CHOICE_REQUIRED, - **chat_kwargs, - ) -> list[LLMResult]: - start_clock = asyncio.get_running_loop().time() - - # Deal with tools. Note OpenAI throws a 400 response if tools is empty: - # > Invalid 'tools': empty array. Expected an array with minimum length 1, - # > but got an empty array instead. - # So, circumvent this behavior if tools in (None, []) - if tools: - chat_kwargs["tools"] = ToolsAdapter.dump_python( - tools, exclude_none=True, by_alias=True - ) - if tool_choice is not None: - chat_kwargs["tool_choice"] = ( - { - "type": "function", - "function": {"name": tool_choice.info.name}, - } - if isinstance(tool_choice, Tool) - else tool_choice - ) - - if isinstance(output_type, Mapping): # Use structured outputs - chat_kwargs["response_format"] = { - "type": "json_schema", - "json_schema": { - "strict": True, - # SEE: https://platform.openai.com/docs/guides/structured-outputs#additionalproperties-false-must-always-be-set-in-objects - "schema": dict(output_type) | {"additionalProperties": False}, - "name": output_type["title"], # Required by OpenAI as of 12/3/2024 - }, - } - elif output_type is not None: # Use JSON mode - schema = json.dumps(output_type.model_json_schema(mode="serialization")) - schema_msg = f"Respond following this JSON schema:\n\n{schema}" - # Get the system prompt and its index, or the index to add it - i, system_prompt = next( - ((i, m) for i, m in enumerate(messages) if m.role == "system"), - (0, None), - ) - messages = [ - *messages[:i], - ( - system_prompt.append_text(schema_msg, inplace=False) - if system_prompt - else Message(role="system", content=schema_msg) - ), - *messages[i + 1 if system_prompt else i :], - ] - chat_kwargs["response_format"] = {"type": "json_object"} - - # add static configuration to kwargs - chat_kwargs = self.config | chat_kwargs - n = chat_kwargs.get("n", 1) # number of completions - if n < 1: - raise ValueError("Number of completions (n) must be >= 1.") - - prompt = [ - ( - m - if not isinstance(m, ToolRequestMessage) or m.tool_calls - # OpenAI doesn't allow for empty tool_calls lists, so downcast empty - # ToolRequestMessage to Message here - else Message(role=m.role, content=m.content) - ) - for m in messages - ] - results: list[LLMResult] = [] - - if callbacks is None: - completion: litellm.ModelResponse = await self.achat(prompt, **chat_kwargs) - if output_type is not None: - validate_json_completion(completion, output_type) - - for choice in completion.choices: - if isinstance(choice, litellm.utils.StreamingChoices): - raise NotImplementedError("Streaming is not yet supported.") - - if ( - tools is not None # Allows for empty tools list - or choice.finish_reason == "tool_calls" - or (getattr(choice.message, "tool_calls", None) is not None) - ): - serialized_choice_message = choice.message.model_dump() - serialized_choice_message["tool_calls"] = ( - serialized_choice_message.get("tool_calls") or [] - ) - output_messages: list[Message | ToolRequestMessage] = [ - ToolRequestMessage(**serialized_choice_message) - ] - else: - output_messages = [Message(**choice.message.model_dump())] - - results.append( - LLMResult( - model=self.name, - config=chat_kwargs, - prompt=prompt, - messages=output_messages, - logprob=sum_logprobs(choice), - system_fingerprint=completion.system_fingerprint, - # Note that these counts are aggregated over all choices - completion_count=completion.usage.completion_tokens, # type: ignore[attr-defined,unused-ignore] - prompt_count=completion.usage.prompt_tokens, # type: ignore[attr-defined,unused-ignore] - ) - ) - else: - if tools: - raise NotImplementedError("Using tools with callbacks is not supported") - if n > 1: - raise NotImplementedError( - "Multiple completions with callbacks is not supported" - ) - result = LLMResult(model=self.name, config=chat_kwargs, prompt=prompt) - - sync_callbacks = [f for f in callbacks if not is_coroutine_callable(f)] - async_callbacks = [f for f in callbacks if is_coroutine_callable(f)] - stream_completion = await self.achat_iter(messages, **chat_kwargs) - text_result = [] - role = "assistant" - - async for chunk in stream_completion: - delta = chunk.choices[0].delta - role = delta.role or role - if delta.content: - s = delta.content - if result.seconds_to_first_token == 0: - result.seconds_to_first_token = ( - asyncio.get_running_loop().time() - start_clock - ) - text_result.append(s) - [await f(s) for f in async_callbacks] - [f(s) for f in sync_callbacks] - if hasattr(chunk, "usage"): - result.prompt_count = chunk.usage.prompt_tokens - - output = "".join(text_result) - result.completion_count = litellm.token_counter( - model=self.name, - text=output, - ) - # TODO: figure out how tools stream, and log probs - result.messages = [Message(role=role, content=output)] - results.append(result) - - if not results: - # This happens in unit tests. We should probably not keep this block around - # long-term. Previously, we would emit an empty ToolRequestMessage if - # completion.choices were empty, so I am replicating that here. - results.append( - LLMResult( - model=self.name, - config=chat_kwargs, - prompt=prompt, - messages=[ToolRequestMessage(tool_calls=[])], - ) - ) - - end_clock = asyncio.get_running_loop().time() - - for result in results: - # Manually update prompt count if not set, which can - # happen if the target model doesn't support 'include_usage' - if not result.prompt_count: - result.prompt_count = litellm.token_counter( - model=self.name, - messages=[m.model_dump() for m in result.messages], # type: ignore[union-attr] - ) - - # update with server-side counts - result.seconds_to_last_token = end_clock - start_clock - - return results - - -class LLMModel(MultipleCompletionLLMModel): - async def call(self, *args, **kwargs) -> LLMResult: # type: ignore[override] - return (await super().call(*args, **kwargs))[0] diff --git a/ldp/llms/embeddings.py b/ldp/llms/embeddings.py deleted file mode 100644 index d809948d..00000000 --- a/ldp/llms/embeddings.py +++ /dev/null @@ -1,134 +0,0 @@ -import asyncio -from abc import ABC, abstractmethod -from enum import StrEnum -from typing import Any - -import litellm -import numpy as np -import tiktoken -from pydantic import BaseModel, ConfigDict, Field, model_validator - - -class EmbeddingModes(StrEnum): - """Enum representing the different modes of an embedding model.""" - - DOCUMENT = "document" - QUERY = "query" - - -class EmbeddingModel(ABC, BaseModel): - name: str - dimensions: int | None = None - - def set_mode(self, mode: EmbeddingModes) -> None: - """Several embedding models have a 'mode' or prompt which affects output.""" - - @abstractmethod - async def embed_texts(self, texts: list[str]) -> list[np.ndarray]: - pass - - async def embed_text(self, text: str) -> np.ndarray: - return (await self.embed_texts([text]))[0] - - @staticmethod - def from_name(embedding: str, **kwargs) -> "EmbeddingModel": - if embedding.startswith("hybrid"): - dense_model = LiteEmbeddingModel(name="-".join(embedding.split("-")[1:])) - return HybridEmbeddingModel( - name=embedding, models=[dense_model, SparseEmbeddingModel(**kwargs)] - ) - if embedding == "sparse": - return SparseEmbeddingModel(**kwargs) - return LiteEmbeddingModel(name=embedding, **kwargs) - - -class LiteEmbeddingModel(EmbeddingModel): - name: str = Field(default="text-embedding-3-small") - dimensions: int | None = Field( - default=None, - description=( - "The length an embedding will have. If left unspecified, we attempt to" - " infer an un-truncated length via LiteLLM's internal model map. If this" - " inference fails, the embedding will be un-truncated." - ), - ) - batch_size: int = 16 - embed_kwargs: dict[str, Any] = Field( - default_factory=dict, - description="Extra kwargs to pass to litellm.aembedding.", - ) - - @model_validator(mode="before") - @classmethod - def infer_dimensions(cls, data: dict[str, Any]) -> dict[str, Any]: - if data.get("dimensions") is not None: - return data - # Let's infer the dimensions - config: dict[str, dict[str, Any]] = litellm.get_model_cost_map( - url="https://raw.githubusercontent.com/BerriAI/litellm/main/litellm/model_prices_and_context_window_backup.json" - ) - output_vector_size: int | None = config.get(data.get("name", ""), {}).get( # noqa: FURB184 - "output_vector_size" - ) - if output_vector_size: - data["dimensions"] = output_vector_size - return data - - async def embed_texts(self, texts: list[str]) -> list[np.ndarray]: - embeddings = [] - # Before you get excited to asyncio.gather this: - # The point of this is to not hit the API rate limit - for i in range(0, len(texts), self.batch_size): - response = await litellm.aembedding( - model=self.name, - input=texts[i : i + self.batch_size], - encoding_format="float", - dimensions=self.dimensions, - **self.embed_kwargs, - ) - embeddings.extend([ - np.array(e["embedding"], dtype=np.float32) for e in response.data - ]) - return embeddings - - -class SparseEmbeddingModel(EmbeddingModel): - """This is a very simple keyword search model - probably best to be mixed with others.""" - - model_config = ConfigDict(arbitrary_types_allowed=True) - - name: str = "sparse" - dimensions: int = 256 - enc: tiktoken.Encoding = Field( - default_factory=lambda: tiktoken.get_encoding("cl100k_base") - ) - - async def embed_texts(self, texts) -> list[np.ndarray]: - enc_batch = self.enc.encode_ordinary_batch(texts) - # now get frequency of each token rel to length - return [ - np.bincount( - [xi % self.dimensions for xi in x], minlength=self.dimensions - ).astype(np.float32) - / len(x) - for x in enc_batch - ] - - -class HybridEmbeddingModel(EmbeddingModel): - name: str = "hybrid-embed" - models: list[EmbeddingModel] - - @model_validator(mode="before") - @classmethod - def infer_dimensions(cls, data: dict[str, Any]) -> dict[str, Any]: - if data.get("dimensions") is not None: - raise ValueError(f"Don't specify dimensions to {cls.__name__}.") - if not data.get("models") or any(m.dimensions is None for m in data["models"]): - return data - data["dimensions"] = sum(m.dimensions for m in data["models"]) - return data - - async def embed_texts(self, texts): - all_embeds = await asyncio.gather(*[m.embed_texts(texts) for m in self.models]) - return np.concatenate(all_embeds, axis=1) diff --git a/ldp/utils.py b/ldp/utils.py index d00c761b..96eadd04 100644 --- a/ldp/utils.py +++ b/ldp/utils.py @@ -1,38 +1,7 @@ import logging import logging.config -import os from typing import Any -import litellm - - -def configure_log_levels() -> None: - """Configure log levels.""" - # Set sane default LiteLLM logging configuration - # SEE: https://docs.litellm.ai/docs/observability/telemetry - litellm.telemetry = False - if ( - logging.getLevelNamesMapping().get( - os.environ.get("LITELLM_LOG", ""), logging.WARNING - ) - < logging.WARNING - ): - # If LITELLM_LOG is DEBUG or INFO, don't change the LiteLLM log levels - litellm_loggers_config: dict[str, Any] = {} - else: - litellm_loggers_config = { - "LiteLLM": {"level": "WARNING"}, - "LiteLLM Proxy": {"level": "WARNING"}, - "LiteLLM Router": {"level": "WARNING"}, - } - - logging.config.dictConfig({ - "version": 1, - "disable_existing_loggers": False, - # Lower level for httpx and LiteLLM - "loggers": {"httpx": {"level": "WARNING"}} | litellm_loggers_config, - }) - def configure_stdout_logs( name: str = "root", diff --git a/pyproject.toml b/pyproject.toml index a046d47c..c3adf380 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,9 +24,9 @@ classifiers = [ dependencies = [ "aiofiles", "dm-tree", + "fh-llm-client", "fhaviary>=0.8.2", # For core namespace "httpx", - "litellm>=1.52.15", # For litellm.ssl_verify "networkx[default]~=3.4", # Pin for pydot fix "numpy>=1.20", # For numpy.typing "pydantic~=2.0", @@ -48,7 +48,7 @@ dev = [ "fhaviary[xml]", "ipython>=8", # Pin to keep recent "ldp[monitor,nn,rich,server,typing,visualization]", - "litellm!=1.49.4,!=1.49.5,!=1.49.6", # For https://github.com/BerriAI/litellm/issues/6216 + "litellm>=1.52.15", "mypy>=1.8", # Pin for mutable-override "pre-commit>=3.4", # Pin to keep recent "pydantic~=2.9", # Pydantic 2.9 changed JSON schema exports 'allOf', so ensure tests match diff --git a/tests/cassettes/TestMemoryOpt.test_lessons_memory_optimizer.yaml b/tests/cassettes/TestMemoryOpt.test_lessons_memory_optimizer.yaml index effff073..b8861fac 100644 --- a/tests/cassettes/TestMemoryOpt.test_lessons_memory_optimizer.yaml +++ b/tests/cassettes/TestMemoryOpt.test_lessons_memory_optimizer.yaml @@ -1,9 +1,8 @@ interactions: - request: body: - '{"messages": [{"role": "user", "content": "Guess a number based on the - input word."}, {"role": "user", "content": "Previous attempts:\n\n-----\n\nHello"}], - "model": "gpt-4-turbo", "temperature": 0}' + '{"messages":[{"role":"user","content":"Guess a number based on the input + word."},{"role":"user","content":"Previous attempts:\n\n-----\n\nHello"}],"model":"gpt-4-turbo","n":1,"temperature":0}' headers: accept: - application/json @@ -12,13 +11,13 @@ interactions: connection: - keep-alive content-length: - - "197" + - "191" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -28,11 +27,11 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: - - "1" + - "0" x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -42,22 +41,22 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xTTY/TMBC991cMvgDatGrSpuxW6qGLkBYJBMtyWKCocuxJYnBsy56wVKv+d+Sm - bVo+JC62NG/emw8/Pw4AmJJsDkzUnETj9HD54U4a/rKavL3+9P6+kP6hVsXtrLiqb++nLIkMW3xD - QQfWSNjGaSRlTQcLj5wwqqYvJmk6vpyk+Q5orEQdaZWj4XRIrS/sMBtn0+F4Ohxf7dm1VQIDm8OX - AQDA4+6MfRqJP9kcxskh0mAIvEI2PyYBMG91jDAeggrEDbGkB4U1hGbX+g1qbZ/ARwtViyEAB9M2 - BXooeEAJ1gDVCMq4luDBegmrjpKsGLx+qjW0AYFDUHF4aJBqK6HYQKxbGWUqQC5q0EiEvlNHrwTX - 8IPrFvsyigI4G1RcIKiuLNeu5gUSPFsu0gSuF1kCo9Eogc+LbPYcuJExzUBomyaWohoDdsJhtDIr - cwMLuFyZV7CAfGXewALSrL/fxTuPeUspez7ZCqlGP4dLuIAcLiDNjkcepbLIubPJ+ZJ+X0+z2e+0 - tL7fqwqQZ6PT1/BYtoFHR5hW6318e3xebSvnbRH2+DFeKqNCvfbIgzXxKQNZx3bodgDwdWej9swZ - zHnbOFqT/Y4mCmZ5J8d68/Zgmu09xsgS1yfA9EA701tLJK50ODEiE1zUKHtq71reSmVPgMHJ1H+2 - 8zftbnJlqv+R7wEh0BHKtfMolTgfuU/zGD/3v9KOW941zMImEDbrUpkKvfOq+1qlW+eymIwns0lZ - ssF28AsAAP//AwAIUB2raAQAAA== + H4sIAAAAAAAAAwAAAP//jFNdjxIxFH3nV1z7omYHMswyCCQ8YLKKyWY3cX1aMaTTXmaqnba2d1Tc + 8N9NGWDAj8SXNrnnnnM/evrUA2BKshkwUXEStdP9hUzvy59vF4/5ZPx1dJu/CXKq7h7u3i+nNwVL + IsMWn1HQkTUQtnYaSVnTwsIjJ4yqw1fX15N8Op5ke6C2EnWklY76oz41vrD9LM1G/XTUT6cHdmWV + wMBm8LEHAPC0P2OfRuIPNoM0OUZqDIGXyGanJADmrY4RxkNQgbghlnSgsIbQ7Ftfotb2GXywUDYY + AnAwTV2gh4IHlGANUIWgjGsIvlsvYdVSkhWDd8+1hiYgcAgqDg81UmUlFFuIdUujTAnIRQUaidC3 + 6uiV4Bq+cd1gV0ZRAGeDigsE1Zbl2lW8QIIXi/kwgdfzLIHBYJDA4zwbvwRuZEwzEJq6jqWowoCt + cBiszMosYQ6TlbmBOeQrcwtzGGbdfR/vPOYtpOz4ZEukCv0MJnAFOVzBMDsdeZTKIufBJpdL+n09 + 9faw04313V5VgDwbnL+Gx00TeHSEabQ+xHen59W2dN4W4YCf4htlVKjWHnmwJj5lIOvYHt31AD7t + bdRcOIM5b2tHa7Jf0ETBLG/lWGfeDhxmB48xssT1GTA60i701hKJKx3OjMgEFxXKjtq5ljdS2TOg + dzb1n+38TbudXJnyf+Q7QAh0hHLtPEolLkfu0jzGz/2vtNOW9w2zsA2E9XqjTIneedV+rY1bp5tx + mmFRSM56u94vAAAA//8DAOGAL6hoBAAA headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df9523c6fee17e6-SJC + - 8effb64679542289-SJC Connection: - keep-alive Content-Encoding: @@ -65,9 +64,15 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:25:19 GMT + - Tue, 10 Dec 2024 19:41:26 GMT Server: - cloudflare + Set-Cookie: + - __cf_bm=mMdeNhgsijzLQWo1eS7oWCKtWSlI7vGGbMfe387TW2o-1733859686-1.0.1.1-DUZOKAzl79eqH_N1Fv4.foYQ9VPZ.wGufm_V8WVD.HwzlWQkvcEJSAah_NbuiZEeEagW4JINDfDr3Y.MaKhp7g; + path=/; expires=Tue, 10-Dec-24 20:11:26 GMT; domain=.api.openai.com; HttpOnly; + Secure; SameSite=None + - _cfuvid=caE6vH.B1YK84P8vrxF1dX_gwfnPB9lipTGU3rCdq30-1733859686280-0.0.1.1-604800000; + path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked X-Content-Type-Options: @@ -79,33 +84,32 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "3379" + - "3867" openai-version: - "2020-10-01" strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - "3000" + - "10000" x-ratelimit-limit-tokens: - - "250000" + - "2000000" x-ratelimit-remaining-requests: - - "2999" + - "9999" x-ratelimit-remaining-tokens: - - "249964" + - "1999963" x-ratelimit-reset-requests: - - 20ms + - 6ms x-ratelimit-reset-tokens: - - 8ms + - 1ms x-request-id: - - req_6acb7ca6b0eedb5dd7042354724ae613 + - req_cbc976d488c682233276db4ac2c209fd status: code: 200 message: OK - request: body: - '{"messages": [{"role": "user", "content": "Guess a number based on the - input word."}, {"role": "user", "content": "Previous attempts:\n\n-----\n\nDay"}], - "model": "gpt-4-turbo", "temperature": 0}' + '{"messages":[{"role":"user","content":"Guess a number based on the input + word."},{"role":"user","content":"Previous attempts:\n\n-----\n\nDay"}],"model":"gpt-4-turbo","n":1,"temperature":0}' headers: accept: - application/json @@ -114,13 +118,13 @@ interactions: connection: - keep-alive content-length: - - "195" + - "189" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -130,7 +134,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -144,19 +148,19 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSQW7bMBC86xULXnqxAlmRU9u3pkaKoocWza1JIdDkSmJKcQkuidQI/PdCsmPZ - aAr0wsPMznBmyZcMQBgt1iBUJ6Pqvc0/fL/XofWf2G/ubzfFt6fUfLn78dWmu2f+KGaDgrZPqOKr - 6kpR7y1GQ+5Aq4Ay4uA6f389nxfL6/lqJHrSaAdZ62Ne5TGFLeVlUVZ5UeXF6qjuyChksYaHDADg - ZTyHnE7jb7GGYvaK9MgsWxTr0xCACGQHREhmw1G6KGYTqchFdGP0W8mogRzEDuGZgoZHsZG72aOA - z++shTYh80i61G8xQFnNQI5IQJABoaygoxQYjAMJWu6uzq8K2CSWQ12XrD3i+1N2S60PtOUjf8Ib - 4wx3dUDJ5IacHMmLkd1nAD/HHaWL2sIH6n2sI/1CNxiWi4OdmF7mDTJSlHbCF8e9XrrVGqM0ls92 - LJRUHepJOT2ITNrQGZGddf47zFveh97Gtf9jPxFKoY+oax9QG3VZeBoLOPzbf42ddjwGFrzjiH3d - GNdi8MEcfk3ja73Qy+pmubpBke2zPwAAAP//AwCpLLoXQwMAAA== + H4sIAAAAAAAAAwAAAP//jFKxbtswFNz1FQ9cukiBIstu4i1NOnRqiy4tmkKgyCeJCcXHkE9xjcD/ + Xkh2LBtNgS4c7t4d7x75kgAIo8UahOokq97b7Ebnnx+fvupvt8rrxfc7/PHUq81z+bz5mH8R6aig + +gEVv6ouFPXeIhtye1oFlIyj6+X7xeJqeb26Wk1ETxrtKGs9Z2XGQ6gpK/KizPIyy68P6o6MwijW + 8DMBAHiZzjGn0/hbrCFPX5EeY5QtivVxCEAEsiMiZIwmsnQs0plU5BjdFP2DjKiBHHCHsKGg4V7c + yW16L+DTO2uhHTDGiXRDX2OAokxBTkhAkAGhKKGjIUQwDiRoub04vSpgM0Q51nWDtQd8d8xuqfWB + 6njgj3hjnIldFVBGcmPOyOTFxO4SgF/Tjoaz2sIH6j1XTI/oRsNiubcT88u8QTKxtDO+POz13K3S + yNLYeLJjoaTqUM/K+UHkoA2dEMlJ57/DvOW9721c+z/2M6EUekZd+YDaqPPC81jA8d/+a+y44ymw + iNvI2FeNcS0GH8z+1zS+yptVXmBdaymSXfIHAAD//wMAOWqgiUMDAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df95252cb1017e6-SJC + - 8effb65f7b522289-SJC Connection: - keep-alive Content-Encoding: @@ -164,7 +168,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:25:20 GMT + - Tue, 10 Dec 2024 19:41:27 GMT Server: - cloudflare Transfer-Encoding: @@ -178,33 +182,32 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "1385" + - "708" openai-version: - "2020-10-01" strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - "3000" + - "10000" x-ratelimit-limit-tokens: - - "250000" + - "2000000" x-ratelimit-remaining-requests: - - "2999" + - "9999" x-ratelimit-remaining-tokens: - - "249964" + - "1999963" x-ratelimit-reset-requests: - - 20ms + - 6ms x-ratelimit-reset-tokens: - - 8ms + - 1ms x-request-id: - - req_f3bdd2b659f522b3a80f9b62e2a8789a + - req_46e66130e4ac25fcd1f0215ce253d587 status: code: 200 message: OK - request: body: - '{"messages": [{"role": "user", "content": "Guess a number based on the - input word."}, {"role": "user", "content": "Previous attempts:\n\n-----\n\nBar"}], - "model": "gpt-4-turbo", "temperature": 0}' + '{"messages":[{"role":"user","content":"Guess a number based on the input + word."},{"role":"user","content":"Previous attempts:\n\n-----\n\nBar"}],"model":"gpt-4-turbo","n":1,"temperature":0}' headers: accept: - application/json @@ -213,13 +216,13 @@ interactions: connection: - keep-alive content-length: - - "195" + - "189" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -229,7 +232,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -243,19 +246,19 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSsW7bMBDd9RUHLl2kQJbsJvGWdMpQoEiCLnUhUORJYkvxWPKEpA3874Vkx1La - BMjC4b17D+/d8SkBEEaLLQjVSVa9t9nV7Z2OV+H+5vHu62ep7J8vF/dcPPw6l5/oVqSjguofqPhZ - daao9xbZkDvQKqBkHF1X5+VqlV+URT4RPWm0o6z1nK0zHkJNWZEX6yxfZ/nlUd2RURjFFr4lAABP - 0zvmdBofxRYmrwnpMUbZotiehgBEIDsiQsZoIkvHIp1JRY7RTdGvZUQN5IA7hAcKGnbiWoZ0J+Dm - g7XQDhjjRLqhrzFAmYKMYBh603YMAa1kBKZphruACBaZMUQw/7qe7cQyRsBmiHJchRusPeL7Uy9L - rQ9UxyN/whvjTOyqgDKSGztEJi8mdp8AfJ/2N7xYifCBes8V0090o2GxOdiJ+WoL8vJIMrG0M75Z - p6+4VRpZGhsX+xdKqg71rJyPJQdtaEEki87/h3nN+9DbuPY99jOhFHpGXfmA2qiXheexgOOffmvs - tOMpsIi/I2NfNca1GHwwhx/V+Gqj6zIvP5ZNI5J98hcAAP//AwAHHYUcXwMAAA== + H4sIAAAAAAAAA4xSy27bMBC86ysWvPQiBYpfsXyLURTtKYcCDYo6EChyJTGlSIK7aloE/vdCsmMp + bQr0wsPMzmBml88JgDBa7ECoVrLqgs1udX5n86cf3N8/VurzHdf3H79s923xYfP+q0gHha8eUfGL + 6kr5Llhk492JVhEl4+B6fbNcbtfFZnszEp3XaAdZEzhbZdzHymeLfLHK8lWWF2d1641CEjv4lgAA + PI/vkNNp/Cl2kKcvSIdEskGxuwwBiOjtgAhJZIilY5FOpPKO0Y3R95JQg3fALcKTjxoOYi9jehDw + 6Z210PRINJKu7yqMsExBEhiGzjQtQ0QrGYH9OMNtRASLzBgJzJ+uVwcxjxGx7kkOq3C9tWf8eOll + fROir+jMX/DaOENtGVGSd0MHYh/EyB4TgIdxf/2rlYgQfRe4ZP8d3WC4WJ/sxHS1GVmcSfYs7YSv + V+kbbqVGlsbSbP9CSdWinpTTsWSvjZ8Ryazz32He8j71Nq75H/uJUAoDoy5DRG3U68LTWMThT/9r + 7LLjMbCgX8TYlbVxDcYQzelH1aHMsViqTb6RK5Eck98AAAD//wMApNW1P18DAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df9525c3edd17e6-SJC + - 8effb664d90d2289-SJC Connection: - keep-alive Content-Encoding: @@ -263,7 +266,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:25:21 GMT + - Tue, 10 Dec 2024 19:41:29 GMT Server: - cloudflare Transfer-Encoding: @@ -277,43 +280,42 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "816" + - "2204" openai-version: - "2020-10-01" strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - "3000" + - "10000" x-ratelimit-limit-tokens: - - "250000" + - "2000000" x-ratelimit-remaining-requests: - - "2999" + - "9999" x-ratelimit-remaining-tokens: - - "249964" + - "1999963" x-ratelimit-reset-requests: - - 20ms + - 6ms x-ratelimit-reset-tokens: - - 8ms + - 1ms x-request-id: - - req_626e2457e60ac7dfe254e4f3731892ff + - req_8ad74985c93735a2b9ad1a1c53c42b6f status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Respond following this JSON - schema:\n\n{\"description\": \"Entry for a lesson created from some example - data.\", \"properties\": {\"query\": {\"description\": \"Plain text string for - retrieving this lesson from a database of lessons.\", \"title\": \"Query\", - \"type\": \"string\"}, \"lesson\": {\"description\": \"Lesson generated from - past attempts.\", \"title\": \"Lesson\", \"type\": \"string\"}}, \"required\": - [\"query\", \"lesson\"], \"title\": \"LessonEntry\", \"type\": \"object\"}"}, - {"role": "user", "content": "We are trying to guess a number based on the input - word. We just tried 3 times, and collected rewards where a higher reward is - better. Here are the results in three-tuples of input, output, reward:\n- (''Hello'', - ''Hello! To guess a number based on the input word \"Hello,\" I\\''ll use a - simple method by assigning each letter a numerical value based on its position - in the alphabet (A=1, B=2, ..., Z=26) and then summing these values.\\n\\nH + '{"messages":[{"role":"system","content":"Respond following this JSON schema:\n\n{\"description\": + \"Entry for a lesson created from some example data.\", \"properties\": {\"query\": + {\"description\": \"Plain text string for retrieving this lesson from a database + of lessons.\", \"title\": \"Query\", \"type\": \"string\"}, \"lesson\": {\"description\": + \"Lesson generated from past attempts.\", \"title\": \"Lesson\", \"type\": \"string\"}}, + \"required\": [\"query\", \"lesson\"], \"title\": \"LessonEntry\", \"type\": + \"object\"}"},{"role":"user","content":"We are trying to guess a number based + on the input word. We just tried 3 times, and collected rewards where a higher + reward is better. Here are the results in three-tuples of input, output, reward:\n- + (''Hello'', ''Hello! To guess a number based on the input word \"Hello,\" I\\''ll + use a simple method by assigning each letter a numerical value based on its + position in the alphabet (A=1, B=2, ..., Z=26) and then summing these values.\\n\\nH = 8\\nE = 5\\nL = 12\\nL = 12\\nO = 15\\n\\nAdding these together: 8 + 5 + 12 + 12 + 15 = 52\\n\\nSo, based on the word \"Hello,\" my guess for a number is 52.'', -300.0)\n-(''Day'', ''Based on the word \"Day,\" I\\''ll guess the number @@ -321,8 +323,7 @@ interactions: \"Bar,\" I\\''ll guess the number 3, as it might relate to the three letters in the word \"Bar.\"'', -100.0)\n\nPlease create a lesson based on this data referencing the relative success or failure associated with the reward, use - concise wording and don''t repeat yourself."}], "model": "gpt-4o-mini-2024-07-18", - "response_format": {"type": "json_object"}}' + concise wording and don''t repeat yourself."}],"model":"gpt-4o-mini-2024-07-18","n":1,"response_format":{"type":"json_object"}}' headers: accept: - application/json @@ -331,13 +332,13 @@ interactions: connection: - keep-alive content-length: - - "1667" + - "1660" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -347,7 +348,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -361,25 +362,25 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xUTY/jNgy951cQuszFGeRjvja3LoqiLbCX3S0waFMEtETb6tKSK1HJegfz3xey - nTiDtkAvPvCJj++RJl8WAMoatQOlGxTddrz84eMnI5+fVv69X/16+p2fP7XPv23Txw+nD/ysipzh - y79IyznrVvu2YxLr3QjrQCiUWdeP2/V69bTdrAeg9YY4p9WdLO/8srXOLjerzd1y9bhcP03Zjbea - otrBHwsAgJfhm3U6Q1/VDlbFOdJSjFiT2l0eAajgOUcUxmijoBNVzKD2TsgN0l/26u9Eod+rHexV - nShG62pwqS0pRCgxkgHvwLouCZx8MHGvCtgrphi9G9N+cSCNjTDGCjgRoEPuvxGgCLWdRBAPAzvg - RA5pqHRFfAufGwKfpEsS4YjBkingZKUBaQhKigKBYmKBknIuxui1zV2eX2UmuPmZmH1xA6fG6gZ6 - S2zIAIJG1omHjFGNr+B+M9tkEqEAR+REsQBpfKobsLmuJnscONifINAJg8nZy+1qNQofK/+I/Q3U - 5CgMVRCGZn+VhDyX3NwVEKiiQE5nI1n41BVfQeNTiGAdIBjsCyjTm/qRbd0I91COYq+0bLKWn6xD - 5r64asd7DDfAZPIUcJaxvZqvxLN57ZOTYur0OKKBqrF1M47gUm89erdZrbEahSJIg5L7zgStDwSB - mI7o5NyICC3240hGyrODWAAyz39MFMs8ySCTVTiqUexx+Ee0b/OEqO0ajPbbuYu6QWZyNWV9bN2X - DAx/V/buUkvBauRpwkBVRTpTcn+7V6/XSxKoShHzorrEPMVfL1vHvu6CL+OEX+KVdTY2h0AYvcsb - FsV3akBfFwB/Dtud3iys6oJvOzmI/0IuE27fPY58aj4qM7p+2E6oeEGegfuH6Si8JTwYErQcrw6E - 0qgbMnPqfE0wGeuvgMWV7X/K+Tfu0bp19f+hnwGtqRMyhy6Qsfqt5flZoHx0/+vZpc2DYBX7KNQe - KutqCl2w48mrusO78vGpfFjr+41avC6+AwAA//8DABQKeBEABgAA + H4sIAAAAAAAAAwAAAP//jFTBjttGDL37K4i5+CIbttfuet1T2iBo0aA5BEgOdWGMZ2iJyWioDik7 + xmL/PRjJtrxoCvQiYPjI90iK5PMIwJA3GzCusurqJkze+NmH+PSruNUf7z/9Kd/efJwv3ra2cqvm + 88kUOYL3X9DpNWrquG4CKnHsYZfQKmbW+ePDw3r19NP6qQNq9hhyWNnoZMmTmiJNFrPFcjJ7nMzX + l+iKyaGYDfw1AgB47r45z+jxm9nArLhaahSxJZrNzQnAJA7ZYqwIidqophhAx1Exdqk/byPA1vzT + YjpvzQa2pmxRhGIJsa33mGBvBT1wBIpNq3Di5CGhtEFla4o+PKAIxz7+9wjcJrCqWDcqoAwdJdgr + 4yFxfccmBZwQeC+YjujhaNM5y3OrjmuUIQGtMCs3HAUFmsRH8uin8I4TjH/DEHhcdE69nsdEmbCT + y2YbmsruUcnZAEcbWhTgA5AKBFTFJJfC0ANFsCBURjqQs1HDGQKfIOHJJp+jJg+z2RQ+Uk3BpnAu + 4Na3W77jt/Y8hjNh8OgzXaCyykz7Tu2ebDGbFRAofs0EQwnK3cNxdNho9qy4TdJn5+15Cu+taFbP + bt2vGf9i0zg3x7cOfWevqKxQ9F5vnvWsCDuy+lrzRFp1z8vf4sOtOxRvOlP4cMRkQ+ilKeZx78rv + VQQohFY0WUWwkDBYpSOCtM6hyM9Q8QmPmAqwIQzDct//iGUfc52EAih6cn3CibmGAyegOk8C1hh1 + ujXb+HI/6QkPrdi8bbEN4WJ/ua1O4LJJvJcLfrMfKJJUu1wSx7wmotyYDn0ZAfzdrWj7autMk7hu + dKf8FWMmfHh67PnMcBkGdL68ospqwwCslsviB4Q7j2opyN2WG2ddhX4IHU6CbT3xHTC6K/vf6fyI + uy+dYvl/6AfA5TlFv2sSenKvSx7cEubL+V9utzZ3CRs5i2K9O1AsMTWJ+rt1aHbr+dot1svZ48qM + XkbfAQAA//8DABEhtZvFBQAA headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df952625d0e6802-SJC + - 8effb6742d1526ae-SJC Connection: - keep-alive Content-Encoding: @@ -387,14 +388,14 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:25:24 GMT + - Tue, 10 Dec 2024 19:41:30 GMT Server: - cloudflare Set-Cookie: - - __cf_bm=h5U8y_cnXjJFRsO9gNGsRDfVg_WNTd.dD8V2ECnaukI-1731108324-1.0.1.1-TZg1ChocRLk67ht1baVmu58G2FMju83G108rLn81ugzgzE3ZsnFObSzCamjfv_DQoXJUQ49Pr4SdHHzZS3CW0A; - path=/; expires=Fri, 08-Nov-24 23:55:24 GMT; domain=.api.openai.com; HttpOnly; + - __cf_bm=Ychzvrqm8ii5aDVzJRWeETd1lUPwQFgXTorbDzGbNxQ-1733859690-1.0.1.1-GhlacpRZRjQA5bckMgo4iHyT5aFoEvsx6Cg1zdNWJbuNZGIETllv3S8pYHROiRFxmNz8.TU6FMaj9oOlXsdElg; + path=/; expires=Tue, 10-Dec-24 20:11:30 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None - - _cfuvid=seDaU9NsvV__5EgEMm84fbcz.hGsr9A6pkA0d2BYwng-1731108324458-0.0.1.1-604800000; + - _cfuvid=Gs6FAfK3UMx7rqMV9YrWcviJA6JZhiKo7WktWRVE4qw-1733859690932-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked @@ -407,7 +408,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "2701" + - "1206" openai-version: - "2020-10-01" strict-transport-security: @@ -419,13 +420,13 @@ interactions: x-ratelimit-remaining-requests: - "29999" x-ratelimit-remaining-tokens: - - "149999625" + - "149999624" x-ratelimit-reset-requests: - 2ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_2335626956aed6bc9770d9d796e88db9 + - req_954e73c5b4c64b2d1a3b3be6fd3176ab status: code: 200 message: OK diff --git a/tests/cassettes/TestReActAgent.test_agent_grad[False-gpt-4o].yaml b/tests/cassettes/TestReActAgent.test_agent_grad[False-gpt-4o].yaml index 19bfa9fa..1a0b4044 100644 --- a/tests/cassettes/TestReActAgent.test_agent_grad[False-gpt-4o].yaml +++ b/tests/cassettes/TestReActAgent.test_agent_grad[False-gpt-4o].yaml @@ -1,24 +1,18 @@ interactions: - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Write - a 5 word story via print_story"}], "model": "gpt-4o", "stop": ["Observation:", - "Action:"], "temperature": 0.1, "tool_choice": "none", "tools": [{"type": "function", - "function": {"name": "print_story", "description": "Print a story.", "parameters": - {"type": "object", "properties": {"story": {"description": "Story to print.", - "title": "Story", "type": "string"}}, "required": ["story"]}}}, {"type": "function", - "function": {"name": "cast_float", "description": "Cast the input argument x - to a float.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", "function": - {"name": "cast_int", "description": "Cast the input argument x to an integer.", - "parameters": {"type": "object", "properties": {"x": {"title": "X", "type": - "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Write a + 5 word story via print_story"}],"model":"gpt-4o","n":1,"stop":["Observation:","Action:"],"temperature":0.1,"tool_choice":"none","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -27,13 +21,13 @@ interactions: connection: - keep-alive content-length: - - "1413" + - "1345" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -43,11 +37,11 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: - - "1" + - "0" x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -57,19 +51,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSTYvbMBC9+1cMOseLHWezaW6lpZBDobSlhX5gtNLYVitrVGlMGpb89yLbG2fp - FnrRYd4H783oIQMQRos9CNVJVr23+cv3H3RR/Bre+rY4vBteGTqeXh/e9J+/VJ9YrJKC7n+g4kfV - jaLeW2RDboJVQMmYXMu7qiyL3Xq7HYGeNNokaz3nG8rXxXqTF7u82M7CjozCKPbwNQMAeBjfFNFp - /C32UKweJz3GKFsU+wsJQASyaSJkjCaydFPcGVTkGN2Y+mNHQ9vxHg5wNNbCEBG4Q/DBOK4jUzhB - MziVKgETTIVAwi0cKWgYGTff3LV9wGaIMrVzg7Xz/HzJa6n1ge7jjF/mjXEmdnVAGcmlbJHJixE9 - ZwDfx70MT6oKH6j3XDP9RJcM1+V28hPLJRa0vJtBJpb2SlVVq2f8ao0sjY1XmxVKqg71Il3OIAdt - 6ArIrlr/neY576m5ce3/2C+AUugZde0DaqOeNl5oAdNH/RftsuUxsIinyNjXjXEthvErpHs0vi5v - X+hdtSmVEtk5+wMAAP//AwBwQI8jNAMAAA== + H4sIAAAAAAAAAwAAAP//jFJNSwMxFLzvrwjv3JXtt92boqigBykVqciSJq+70WwSkqxUS/+7ZLtt + t7SClxxm3kxmXrKOCAHBISXACupZaWR8xZPpzfzpa3b9+vzC5qu7h/vpz+2wkr2ZeYROUOjFBzK/ + U10wXRqJXmi1pZlF6jG4dsf9/uVwMkm6NVFqjjLIcuPjgY57SW8QJ5dxMmqEhRYMHaTkLSKEkHV9 + hoiK4wpSknR2SInO0Rwh3Q8RAlbLgAB1TjhPlYfOgWRaeVR16jZscVk5GlKpSsoG3+zvkTo3Vi9c + w+/xpVDCFZlF6rQKns5rAzW7iQh5r/tURxHBWF0an3n9iSoY9rqjrR8cNnhgm67gtafynOjILuPo + qZCutRBglBXITxwJAVpxoVtE1Cp9Guac97a4UPl/7A8EY2g88sxY5IKdLVybh//119h+yXVgcN/O + Y5kthcrRGiu2T7w0GRszmuCCMgrRJvoFAAD//wMAyt7DnOsCAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df951066fb0cf22-SJC + - 8effbba17cc7173e-SJC Connection: - keep-alive Content-Encoding: @@ -77,7 +70,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:26 GMT + - Tue, 10 Dec 2024 19:45:02 GMT Server: - cloudflare Transfer-Encoding: @@ -91,7 +84,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "427" + - "401" openai-version: - "2020-10-01" strict-transport-security: @@ -109,33 +102,25 @@ interactions: x-ratelimit-reset-tokens: - 0s x-request-id: - - req_5e6850c1a253c1c7006e3680cc9df401 + - req_d795cef300521e5425ec74e7a7a21d33 status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Write - a 5 word story via print_story"}, {"role": "assistant", "content": "Thought: - I will use the print_story function to create a 5 word story.\n. Based on this - reasoning, let''s select the appropriate tool!\nAction: "}, {"role": "user", - "content": "Continue..."}], "model": "gpt-4o", "stop": ["Observation:", "Action:"], - "temperature": 0.1, "tool_choice": "required", "tools": [{"type": "function", - "function": {"name": "print_story", "description": "Print a story.", "parameters": - {"type": "object", "properties": {"story": {"description": "Story to print.", - "title": "Story", "type": "string"}}, "required": ["story"]}}}, {"type": "function", - "function": {"name": "cast_float", "description": "Cast the input argument x - to a float.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", "function": - {"name": "cast_int", "description": "Cast the input argument x to an integer.", - "parameters": {"type": "object", "properties": {"x": {"title": "X", "type": - "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Write a + 5 word story via print_story"},{"role":"assistant","content":"Thought: . Based + on this reasoning, let''s select the appropriate tool!\nAction: "},{"role":"user","content":"Continue..."}],"model":"gpt-4o","n":1,"stop":["Observation:","Action:"],"temperature":0.1,"tool_choice":"required","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -144,13 +129,13 @@ interactions: connection: - keep-alive content-length: - - "1642" + - "1503" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -160,7 +145,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -174,20 +159,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xTTW/bMAy9+1cIPCeF89F8+DZsK9B1ly6nrRkMVaZtpbIkSDS2JMh/HywntpN1 - wHwQBD6+R/KJPkaMgcwgYSBKTqKyavzh2yaLZf72kG/o02PMn9ffC7/Zfy0f1vMDjBqGed2hoAvr - TpjKKiRpdAsLh5ywUZ0sZ5NJvJouFgGoTIaqoRWWxnMznsbT+ThejePFmVgaKdBDwl4ixhg7hrNp - UWf4GxIWjy6RCr3nBULSJTEGzqgmAtx76YlrglEPCqMJddO1rpUaAGSMSgVXqi/cfsfBvfeJK5Xy - L0+r5Wo3P8i6evoo8tnz58Pjj2o3qNdK721oKK+16PwZ4F08uSnGGGheBa51UlPqybj9DZ0x4K6o - K9TUtA7HLYS0LSRb2NTaI7FfpfQWnWcehUPyjAzTsijpbgsnuJI7Re/dfw6ccpjXnquzhef4qXsT - ZQrrzKu/sRhyqaUvU4fch1GHjkeXaqEO1FePCtaZylJK5g11Izu9X7aq0O/cAD2vB5Ahrgbx5YV1 - pZdmSFyGV+8WTXBRYtZT+4XjdSbNAIgGs//dzXva7fxSF/8j3wNCoCXMUuswk+J64j7NYfNL/iut - czk0DH7vCas0l7pAF/YrLKlNJ/frbDWbT4SA6BT9AQAA//8DAPrQwbQeBAAA + H4sIAAAAAAAAA4xTTW/bMAy9+1cIPCeF52RN4ltXdMCwDSvW7rAthaHIjK1OX5BoNEGQ/z5YSWwn + 7YD5IAh8fI/kE71LGANZQs5A1JyEdmp8U6YPdwv7XT3/nE1u7eabuX98/Dz9+uFF3xoYtQy7ekZB + J9aVsNopJGmPsPDICVvVd7PJZP5+sUizCGhbompplaPx1I6zNJuO0/k4vT4SaysFBsjZ74Qxxnbx + bFs0JW4gZ+noFNEYAq8Q8i6JMfBWtRHgIchA3BCMelBYQ2jark2j1AAga1UhuFJ94cO3G9x7n7hS + xY+5+LUw2aePZnt3f/NFbypabydGD+odpLcuNrRujOj8GeBdPL8oxhgYriPXeWmoCGT99oLOGHBf + NRoNta3DbgkxbQn5Eh4aE5DYSy2DQx9YQOGRAiPLjKxqulrCHs7k9slb96eBUx7XTeDqaOExvu/e + RNnKebsKFxbDWhoZ6sIjD3HUoePJqVqsA83Zo4LzVjsqyP5B08pm0+ygCv3ODdDjegBZ4moQvz6x + zvSKEonL+Ordogkuaix7ar9wvCmlHQDJYPbX3bylfZhfmup/5HtACHSEZeE8llKcT9yneWx/yX+l + dS7HhiFsA6Eu1tJU6ON+xSV1hZgJnuKKCw7JPvkLAAD//wMAGNjVLB4EAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df9510b297fcf22-SJC + - 8effbba4a856173e-SJC Connection: - keep-alive Content-Encoding: @@ -195,7 +180,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:27 GMT + - Tue, 10 Dec 2024 19:45:02 GMT Server: - cloudflare Transfer-Encoding: @@ -209,7 +194,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "432" + - "702" openai-version: - "2020-10-01" strict-transport-security: @@ -221,13 +206,13 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999812" + - "29999828" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_13ac2ef5dca0872702df350e4094e09d + - req_c220edc212005e09ccfdb6d91be9822d status: code: 200 message: OK diff --git a/tests/cassettes/TestReActAgent.test_agent_grad[True-gpt-4-turbo].yaml b/tests/cassettes/TestReActAgent.test_agent_grad[True-gpt-4-turbo].yaml index f77a5374..387c3804 100644 --- a/tests/cassettes/TestReActAgent.test_agent_grad[True-gpt-4-turbo].yaml +++ b/tests/cassettes/TestReActAgent.test_agent_grad[True-gpt-4-turbo].yaml @@ -1,7 +1,7 @@ interactions: - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can. You have access to the following tools:\n\nNAME: print_story\n\nSYNOPSIS:\n print_story(string story)\n\nDESCRIPTION:\n Print a story.\n\nPARAMETERS:\n story (string): Story to print.\n\nNAME: cast_float\n\nSYNOPSIS:\n cast_float(string x)\n\nDESCRIPTION:\n Cast @@ -14,9 +14,8 @@ interactions: tuple\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather\nAction Input: \"New York\", 7\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Write - a 5 word story via print_story"}], "model": "gpt-4-turbo", "stop": ["Observation:"], - "temperature": 0.1}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Write a + 5 word story via print_story"}],"model":"gpt-4-turbo","n":1,"stop":["Observation:"],"temperature":0.1}' headers: accept: - application/json @@ -25,13 +24,13 @@ interactions: connection: - keep-alive content-length: - - "1289" + - "1281" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -41,7 +40,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -55,20 +54,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSy27bMBC8+ysWPLWAZci26oduORVpD0WanloXAk2uJCYUlyBXbYwg/15QfshB - U6CXBbizM5jZ5fMEQBgtShCqlaw6b7Obr/fq0B70g84Ls97cfdp+ueu7etl9//j4WUwTg/YPqPjM - minqvEU25I6wCigZk+p8vZzP881iVQxARxptojWesyLjPuwpW+SLIsuLLN+e2C0ZhVGU8GMCAPA8 - 1OTTaXwSJeTTc6fDGGWDorwMAYhANnWEjNFElo7FdAQVOUY3WP/WUt+0XMItOEQNTHA0DhJiS4Eh - MoUDKHJJyLgGqAZ8kortAWrzC+E3BR1nO3ejUvgSfDCOq4F2bsKt8z2X8G4n7o1Fx+BM0/IUYq81 - OtiH9ASb6mwn3u/ctd2AdR9lWpnrrT31Xy75LTU+0D6e8Eu/Ns7EtgooI7mUNTJ5MaAvE4Cfw577 - V6sTPlDnuWJ6RJcEF6v1UU+M5x3R5eIEMrG0V6ztdvqGXqWRpbHx6lJCSdWiHqnjWWWvDV0Bk6vU - f7t5S/uY3Ljmf+RHQCn0jLryAbVRrxOPYwHT7//X2GXLg2ERD5Gxq2rjGgzD/0j3qH2lP+hNsdps - VygmL5M/AAAA//8DAB72J5aJAwAA + H4sIAAAAAAAAAwAAAP//jFJda9tAEHzXr1juqQXLKLbrxHoLLaWGkkCbPNVFnO9W0tXS7XG3SmKC + /3s5+UM2bSAv97CzM8zM3msCIIwWOQhVS1ata9Jbnf1Ap+/n4fOXr8u7u+enh8ern2GD9033TYwi + g9Z/UPGRNVbUugbZkN3DyqNkjKpX19PpzafFzXzeAy1pbCKtcpzOUu78mtJJNpml2SzNFgd2TUZh + EDn8SgAAXvs3+rQaX0QO2eg4aTEEWaHIT0sAwlMTJ0KGYAJLy2I0gIoso+2tP9TUVTXnsASLqIEJ + 9sZBQqjJMwQmvwVFNgoZWwGVgC9ScbOF0jwhPJPXYbyytyqGz8F5Y7noacchLK3rOIcPK/GdAsMG + twFK6qyGzmr0EKiU45X4uLLnPj2WXZCxK9s1zWG+OwVvqHKe1uGAn+alsSbUhUcZyMaQgcmJHt0l + AL/7gruLzoTz1DoumDZoo+Bkfr3XE8NdB3R6aF8wsWzOWIsj60Kv0MjSNOHsREJJVaMeqMM9ZacN + nQHJWep/3fxPe5/c2Oo98gOgFDpGXTiP2qjLxMOax/jt31o7tdwbFmEbGNuiNLZC33+MeI/SFVk5 + zya4Xmspkl3yFwAA//8DACRd5fOCAwAA headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df950f96ed8faae-SJC + - 8effbac5be2496e1-SJC Connection: - keep-alive Content-Encoding: @@ -76,14 +75,14 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:25 GMT + - Tue, 10 Dec 2024 19:44:28 GMT Server: - cloudflare Set-Cookie: - - __cf_bm=c7R6O3UrELUEXjWCIWuHSeoyVC1vPQtK74gF209bv.I-1731108265-1.0.1.1-qxdVapBa_Vl._sXTClR4FY281YRtDM4513iEjeHJQj0zbbbpo3LwsmZ12jByo0rkXaGs4naidbkg3JyMO6Uz0w; - path=/; expires=Fri, 08-Nov-24 23:54:25 GMT; domain=.api.openai.com; HttpOnly; + - __cf_bm=w4eA4W7pA8IYO1k8Lkje9HzTMqj9Y5npKaWaeWkwIFM-1733859868-1.0.1.1-oYA98x3oha4XXhNiHiGW7FWjNP9SjrC5O3AejXBmNlzFjvWoOEQsZY0fxQO_Ug.GqL9nnHTdlD74c7WY_AC9Eg; + path=/; expires=Tue, 10-Dec-24 20:14:28 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None - - _cfuvid=dNbf6A6B09bSG6qPpcCLepBZLGf76gH8k8N9P034eD0-1731108265380-0.0.1.1-604800000; + - _cfuvid=XW2FDZWQR_WIY.n9cSueh3jWdAwWZ17PpS5rlwQFrEc-1733859868656-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked @@ -96,25 +95,25 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "1367" + - "2032" openai-version: - "2020-10-01" strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - "3000" + - "10000" x-ratelimit-limit-tokens: - - "250000" + - "2000000" x-ratelimit-remaining-requests: - - "2999" + - "9999" x-ratelimit-remaining-tokens: - - "249709" + - "1999710" x-ratelimit-reset-requests: - - 20ms + - 6ms x-ratelimit-reset-tokens: - - 69ms + - 8ms x-request-id: - - req_e76a93ae982fe7053672aa6cc9582e62 + - req_f1e1966b85d8c1b6d48c54a361a48331 status: code: 200 message: OK diff --git a/tests/cassettes/TestReActAgent.test_multi_step[False].yaml b/tests/cassettes/TestReActAgent.test_multi_step[False].yaml index 11121c35..22141319 100644 --- a/tests/cassettes/TestReActAgent.test_multi_step[False].yaml +++ b/tests/cassettes/TestReActAgent.test_multi_step[False].yaml @@ -1,25 +1,19 @@ interactions: - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}], "model": "gpt-4o-2024-08-06", "parallel_tool_calls": - false, "stop": ["Observation:", "Action:"], "tool_choice": "none", "tools": - [{"type": "function", "function": {"name": "print_story", "description": "Print - a story.", "parameters": {"type": "object", "properties": {"story": {"description": - "Story to print.", "title": "Story", "type": "string"}}, "required": ["story"]}}}, - {"type": "function", "function": {"name": "cast_float", "description": "Cast - the input argument x to a float.", "parameters": {"type": "object", "properties": - {"x": {"title": "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", - "function": {"name": "cast_int", "description": "Cast the input argument x to - an integer.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."}],"model":"gpt-4o-2024-08-06","n":1,"parallel_tool_calls":false,"stop":["Observation:","Action:"],"tool_choice":"none","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -28,13 +22,13 @@ interactions: connection: - keep-alive content-length: - - "1496" + - "1428" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -44,11 +38,11 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: - - "0" + - "1" x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -58,19 +52,19 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSwWrcMBC9+ysGXXJZL/bGToJvgUIJ7SVtD4W2GEUa2+rKkqoZl7Zh/73Iu1k7 - NIVcBJo37/HeYx4zAGG0aECoQbIag81vP3zc8/378M7c73/c7d8wlZWmtz9rmj7/EZvE8A/fUfET - a6v8GCyy8e4Iq4iSMamW15dlWdxc1/UMjF6jTbQ+cF75fFfsqry4yYurE3HwRiGJBr5kAACP85ss - Oo2/RAPF5mkyIpHsUTTnJQARvU0TIYkMsXQsNguovGN0s+tPg5/6gRu4A4eogT0oSQwX9ba+SD8J - nfWSoTORePvVrXUidhPJFMNN1p7mh7Mx6/sQ/QOd8PO8M87Q0EaU5F0yQeyDmNFDBvBtLmB6lkmE - 6MfALfs9uiS4u6yPemKpfEHLqxPInqVdsepy84Jeq5GlsbSqUCipBtQLdelbTtr4FZCtUv/r5iXt - Y3Lj+tfIL4BSGBh1GyJqo54nXtYipov839q55dmwoN/EOLadcT3GEM3xKLrQVrXq6kqjRJEdsr8A - AAD//wMAmAtgtR0DAAA= + H4sIAAAAAAAAAwAAAP//jJI/b9swEMV3fYoDlyySodhWYmnLkABFhwJNprSFQJEniQ1FsuQJ+Qd/ + 94KyYyloCmThcL97D+8d+JoAMCVZBUz0nMTgdHYl8+/9n+uX+5u20Q/6+rb52n3b9vePz0+7S5ZG + hW1+o6A31UrYwWkkZc0BC4+cMLqeX242u6LcXZQTGKxEHWWdo2xrs3W+3mb5LssvjsLeKoGBVfAj + AQB4nd4Y0Uh8YhXk6dtkwBB4h6w6LQEwb3WcMB6CCsQNsXSGwhpCM6W+6+3Y9VTBjfKBUvgCBlEC + WRA8EFCPEMgr08FZsSrOIuDQastp9dMsPT22Y+Cxkhm1Ps73p5Dads7bJhz5ad4qo0Jfe+TBmhgo + kHVsovsE4Nd0jPFdP+a8HRzVZB/QRMP1pjj4sfn8Mz0vj5Ascb1QFdv0A79aInGlw+KcTHDRo5yl + 8+35KJVdgGTR+t80H3kfmivTfcZ+BkKgI5S18yiVeN94XvMYf+f/1k5XngKz8BwIh7pVpkPvvDp8 + kNbVpSxyIcsyb1iyT/4CAAD//wMAzORJUikDAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df95cfbef009651-SJC + - 8effbad9fb7067c4-SJC Connection: - keep-alive Content-Encoding: @@ -78,15 +72,9 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:32:36 GMT + - Tue, 10 Dec 2024 19:44:30 GMT Server: - cloudflare - Set-Cookie: - - __cf_bm=WKotkLMRrc2Xef4Wt20THwR7B3nUMnqvEep67nlhetk-1731108756-1.0.1.1-6i3zk77orf_J7hJlSoW3c2v1yn1wRxvKWgWnrcbwUhcsEDUx5FnpaQ6ayIN6AoYYodGSIlrfv7DQv3sm_B75mA; - path=/; expires=Sat, 09-Nov-24 00:02:36 GMT; domain=.api.openai.com; HttpOnly; - Secure; SameSite=None - - _cfuvid=LgwtIHBxPREoiqN9o6k_ZNhA5wCEXzPApu7fgAc1UTQ-1731108756267-0.0.1.1-604800000; - path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked X-Content-Type-Options: @@ -98,7 +86,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "344" + - "551" openai-version: - "2020-10-01" strict-transport-security: @@ -116,34 +104,27 @@ interactions: x-ratelimit-reset-tokens: - 0s x-request-id: - - req_daf830881bc887390fc604ba46cfa2fd + - req_f77c374c33390f9d18b0a5f3b86ac75f status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}, {"role": "assistant", "content": "Thought: I need to - cast ''5.5'' to a float first.\n. Based on this reasoning, let''s select the - appropriate tool!\nAction: "}, {"role": "user", "content": "Continue..."}], - "model": "gpt-4o-2024-08-06", "parallel_tool_calls": false, "stop": ["Observation:", - "Action:"], "tool_choice": "required", "tools": [{"type": "function", "function": - {"name": "print_story", "description": "Print a story.", "parameters": {"type": - "object", "properties": {"story": {"description": "Story to print.", "title": - "Story", "type": "string"}}, "required": ["story"]}}}, {"type": "function", - "function": {"name": "cast_float", "description": "Cast the input argument x - to a float.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", "function": - {"name": "cast_int", "description": "Cast the input argument x to an integer.", - "parameters": {"type": "object", "properties": {"x": {"title": "X", "type": - "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."},{"role":"assistant","content":"Thought: First, I need to cast + the string ''5.5'' to a float.\n. Based on this reasoning, let''s select the + appropriate tool!\nAction: "},{"role":"user","content":"Continue..."}],"model":"gpt-4o-2024-08-06","n":1,"parallel_tool_calls":false,"stop":["Observation:","Action:"],"tool_choice":"required","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -152,13 +133,13 @@ interactions: connection: - keep-alive content-length: - - "1702" + - "1638" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -168,7 +149,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -182,20 +163,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xTTW+bQBC98ytWczYR2GCn3HKKqqpN5TRVq7pCm2XA6+xXd5cmruX/HgE2YMeR - ymG1mjfvzczbYRcQAryAjABbU8+kEeHN8v6prr9spTf3dnP35/sy+ey2t+JZPPwUMGkY+nGDzB9Z - V0xLI9BzrTqYWaQeG9V4MYvj6HqRzltA6gJFQ6uMDxMdTqNpEkbXYTQ/ENeaM3SQkV8BIYTs2rNp - URX4AhmJJseIROdohZD1SYSA1aKJAHWOO0+Vh8kAMq08qqZrVQsxArzWImdUiKFw9+1G98EnKkT+ - 6e+/29lDqpYb+eOumn7dPNOPcvbtZlSvk96atqGyVqz3Z4T38eysGCGgqMSuoPN5KTT1Z2xCgNqq - lqh80znsVvCygmwF6VW6gj2cJO+DS/ffIxsslrWj4uDPIb7vDRe6MlY/ujP/oOSKu3Vukbp2jrGd - wbFaWwfqkxcDY7U0Pvf6CVUjO12knSoMCzWg8fwAeu2pGLE+xJMLenmBnvL2SfstYpStsRiowzbR - uuB6BASj2d92c0m7m5+r6n/kB4AxNB6L3FgsODudeEiz2Pxv76X1LrcNg9s6jzIvuarQGsvblYfS - 5EnKyjQpkCIE++AVAAD//wMAouRTjfsDAAA= + H4sIAAAAAAAAAwAAAP//jFPbitswEH33V4h5ThavE+fity29Qktp2bK0zWJkaexoVzckuSSE/Pti + O2s7aQr1gxBz5pyZORofIkJAcMgIsC0NTFk5vePxd7F79/HL++Jhlyy1Kn6YZPb100+bLp5g0jBM + 8YQsvLJumFFWYhBGdzBzSAM2qrfL2WyVrlfLuAWU4SgbWmXDdG6mSZzMp/FqGi9OxK0RDD1k5HdE + CCGH9mxa1Bx3kJFWpo0o9J5WCFmfRAg4I5sIUO+FD1QHmAwgMzqgbrrWtZQjIBgjc0alHAp332F0 + H3yiUubP8/rNZ8OK2f5Pcn+v+UP69pv6pT6M6nXSe9s2VNaa9f6M8D6eXRQjBDRV2BX0IS+loeGC + TQhQV9UKdWg6h8MGdhvINpDepBs4wlnyMbp2fxzZ4LCsPZUnf07xY2+4NJV1pvAX/kEptPDb3CH1 + 7RxjO6PXam0dqM9eDKwzyoY8mGfUjWyyXHWqMCzUgN4uTmAwgcoRaz2fXNHLOQYq2iftt4hRtkU+ + UIdtojUXZgREo9n/7uaadje/0NX/yA8AY2gD8tw65IKdTzykOWz+t3+l9S63DYPf+4AqL4Wu0Fkn + 2pWH0uZrnsaMr9dxAdExegEAAP//AwB1X7QN+wMAAA== headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df95cfef9fe9651-SJC + - 8effbade2f5e67c4-SJC Connection: - keep-alive Content-Encoding: @@ -203,7 +184,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:32:36 GMT + - Tue, 10 Dec 2024 19:44:31 GMT Server: - cloudflare Transfer-Encoding: @@ -217,7 +198,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "359" + - "510" openai-version: - "2020-10-01" strict-transport-security: @@ -229,43 +210,34 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999802" + - "29999800" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_d9470d313a7c0717e7dae8a16beed8ef + - req_a22592e960787b9681a567be8f799fb9 status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}, {"role": "assistant", "content": "Thought: I need to - cast ''5.5'' to a float first.\n. Based on this reasoning, let''s select the - appropriate tool!\nAction: "}, {"role": "user", "content": "Continue..."}, {"role": - "assistant", "content": null, "function_call": null, "tool_calls": [{"id": "call_KvzG3U5nRjmXOg2PjwaIm3TA", - "type": "function", "function": {"arguments": "{\"x\": \"5.5\"}", "name": "cast_float"}}]}, - {"role": "tool", "content": "Observation: 5.5", "name": "cast_float", "tool_call_id": - "call_KvzG3U5nRjmXOg2PjwaIm3TA"}], "model": "gpt-4o-2024-08-06", "parallel_tool_calls": - false, "stop": ["Observation:", "Action:"], "tool_choice": "none", "tools": - [{"type": "function", "function": {"name": "print_story", "description": "Print - a story.", "parameters": {"type": "object", "properties": {"story": {"description": - "Story to print.", "title": "Story", "type": "string"}}, "required": ["story"]}}}, - {"type": "function", "function": {"name": "cast_float", "description": "Cast - the input argument x to a float.", "parameters": {"type": "object", "properties": - {"x": {"title": "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", - "function": {"name": "cast_int", "description": "Cast the input argument x to - an integer.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."},{"role":"assistant","content":"Thought: First, I need to cast + the string ''5.5'' to a float.\n. Based on this reasoning, let''s select the + appropriate tool!\nAction: "},{"role":"user","content":"Continue..."},{"role":"assistant","content":null,"function_call":null,"tool_calls":[{"id":"call_k4uBLocb3yv2TTndW5DQmZmG","type":"function","function":{"arguments":"{\"x\": + \"5.5\"}","name":"cast_float"}}]},{"role":"tool","content":"Observation: 5.5","name":"cast_float","tool_call_id":"call_k4uBLocb3yv2TTndW5DQmZmG"}],"model":"gpt-4o-2024-08-06","n":1,"parallel_tool_calls":false,"stop":["Observation:","Action:"],"tool_choice":"none","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -274,13 +246,13 @@ interactions: connection: - keep-alive content-length: - - "2027" + - "1939" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -290,7 +262,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -304,19 +276,19 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSPW/bMBDd9SsOXLJIhmxLjqutYzrUQdoCDdpCYKiTyFjiEeSpaRH4vxeSFUtB - U6ALh3sffO/I5whAmEoUIJSWrDrXJu/vPh17c9D35D8cvhwPj++2dHd7n3l3+9WKeFDQwyMqflGt - FHWuRTY0wcqjZBxc19fb9TrdX+e7EeiownaQNY6TjJJNusmSdJ+ku0moySgMooBvEQDA83gOEW2F - v0QBafwy6TAE2aAoLiQA4akdJkKGYAJLyyKeQUWW0Y6pP2vqG80FfKQnYC0ZbkDLnwhKBoarfJVf - ARNIqFuSHMOTNkqDCZCv8hhuwCJWA2GkGx65FoxlbNCvvtvltR7rPsihte3bdpqfLj1aapynhzDh - l3ltrAm69CgD2SFzYHJiRE8RwI9xX/2rFQjnqXNcMh3RDobbdHf2E/MLLdDNBDKxbBfz7T5+w6+s - kKVpw2LjQkmlsZql8/PIvjK0AKJF67/TvOV9bm5s8z/2M6AUOsaqdB4ro143nmkehw/8L9ply2Ng - EX4Hxq6sjW3QO2/Of6h2ZZarOs8qlCiiU/QHAAD//wMAe66zYUwDAAA= + H4sIAAAAAAAAAwAAAP//jJJBb9swDIXv/hWELr3YgZvEbZLbtl4CBMM29DKsg6FItKVMlgSJ3lYU + +e+DnDR2sA7YRYf3kQ98pF4yAKYl2wATipPovCneyfLL4cPdp1btHrdCrb5aH3YPu88Ph/dzyfLU + 4fYHFPTaNROu8wZJO3vCIiAnTK6394vFqlqv7m8H0DmJJrW1noqlK+blfFmUq6K8OzcqpwVGtoFv + GQDAy/CmEa3E32wDZf6qdBgjb5FtLkUALDiTFMZj1JG4JZaPUDhLaIepH5XrW0Ub+Oh+ASlOsAXF + fyLEXgiMsemNeQbBI8FNNatugByQQmiM4wTVrMphCxZRJjCUXdGkcgvaErYYZk92OkbApo88bcH2 + xpz14yWXca0Pbh/P/KI32uqo6oA8OpsyRHKeDfSYAXwf9tdfrYT54DpPNbkfaJPholyf/Nh4sQmt + zpAccTPRl8v8Db9aInFt4uQCTHChUI6t47l4L7WbgGyS+u9p3vI+Jde2/R/7EQiBnlDWPqDU4jrx + WBYwfeh/lV22PAzM4nMk7OpG2xaDD/r0pxpfr2VVCrlel3uWHbM/AAAA//8DAJ7rg2RcAwAA headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df95d022cb59651-SJC + - 8effbae21a9367c4-SJC Connection: - keep-alive Content-Encoding: @@ -324,7 +296,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:32:37 GMT + - Tue, 10 Dec 2024 19:44:32 GMT Server: - cloudflare Transfer-Encoding: @@ -338,7 +310,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "579" + - "1085" openai-version: - "2020-10-01" strict-transport-security: @@ -350,46 +322,37 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999796" + - "29999793" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_53a5f569ed5dd9384ae363644dbf2f4f + - req_a936bbebea97c7fc58839d6d0f1e735d status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}, {"role": "assistant", "content": "Thought: I need to - cast ''5.5'' to a float first.\n. Based on this reasoning, let''s select the - appropriate tool!\nAction: "}, {"role": "user", "content": "Continue..."}, {"role": - "assistant", "content": null, "function_call": null, "tool_calls": [{"id": "call_KvzG3U5nRjmXOg2PjwaIm3TA", - "type": "function", "function": {"arguments": "{\"x\": \"5.5\"}", "name": "cast_float"}}]}, - {"role": "tool", "content": "Observation: 5.5", "name": "cast_float", "tool_call_id": - "call_KvzG3U5nRjmXOg2PjwaIm3TA"}, {"role": "assistant", "content": "Thought: - Now that I have cast ''5.5'' to a float, which is 5.5, I need to cast it to - an integer.\n. Based on this reasoning, let''s select the appropriate tool!\nAction: - "}, {"role": "user", "content": "Continue..."}], "model": "gpt-4o-2024-08-06", - "parallel_tool_calls": false, "stop": ["Observation:", "Action:"], "tool_choice": - "required", "tools": [{"type": "function", "function": {"name": "print_story", - "description": "Print a story.", "parameters": {"type": "object", "properties": - {"story": {"description": "Story to print.", "title": "Story", "type": "string"}}, - "required": ["story"]}}}, {"type": "function", "function": {"name": "cast_float", - "description": "Cast the input argument x to a float.", "parameters": {"type": - "object", "properties": {"x": {"title": "X", "type": "string"}}, "required": - ["x"]}}}, {"type": "function", "function": {"name": "cast_int", "description": - "Cast the input argument x to an integer.", "parameters": {"type": "object", - "properties": {"x": {"title": "X", "type": "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."},{"role":"assistant","content":"Thought: First, I need to cast + the string ''5.5'' to a float.\n. Based on this reasoning, let''s select the + appropriate tool!\nAction: "},{"role":"user","content":"Continue..."},{"role":"assistant","content":null,"function_call":null,"tool_calls":[{"id":"call_k4uBLocb3yv2TTndW5DQmZmG","type":"function","function":{"arguments":"{\"x\": + \"5.5\"}","name":"cast_float"}}]},{"role":"tool","content":"Observation: 5.5","name":"cast_float","tool_call_id":"call_k4uBLocb3yv2TTndW5DQmZmG"},{"role":"assistant","content":"Thought: + Now that I have successfully cast ''5.5'' to the float 5.5, I need to cast the + float 5.5 to an integer.\n. Based on this reasoning, let''s select the appropriate + tool!\nAction: "},{"role":"user","content":"Continue..."}],"model":"gpt-4o-2024-08-06","n":1,"parallel_tool_calls":false,"stop":["Observation:","Action:"],"tool_choice":"required","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -398,13 +361,13 @@ interactions: connection: - keep-alive content-length: - - "2280" + - "2200" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -414,7 +377,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -428,20 +391,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xTUW+bMBB+51dY9xyqhEIS8RatU7dp67T1aVon5JoD3Brbs481WZT/PgEJkC6T - xoNl3Xf3fXefj33AGMgcUgai4iRqq8LN1/vnXzfF7u5JF+/jkqroPv9y8/slutv+XMKsrTCPTyjo - VHUlTG0VkjS6h4VDTtiyLlbXi8V8vUpWHVCbHFVbVloKYxNG8ygO5+twfuQVlZECPaTse8AYY/vu - bFvUOW4hZfPZKVKj97xESIckxsAZ1UaAey89cU0wG0FhNKFuu9aNUhOAjFGZ4EqNwv23n9xHn7hS - 2dsFfbyNNs27jaRvu/L2DS9eig+fP030euqd7RoqGi0Gfyb4EE9fiTEGmtfYC3rK5NksxwzuyqZG - TW3fsH+A7QOkyVVygLPEQ3Dp/mNigMOi8VwdnTnGD4PVypTWmUf/yjkopJa+yhxy300wNTI4qXU6 - 0Jy9FVhnaksZmWfULe31MupZYVylEV0sjyAZ4mpStVrPLvBlORKX3WMO+yO4qDAfS8c94k0uzQQI - JrP/3c0l7n5+qcv/oR8BIdAS5pl1mEtxPvGY5rD90/6VNrjcNQx+5wnrrJC6RGed7JYdCpvFiSiS - OEeOEByCPwAAAP//AwBsxhCV9QMAAA== + H4sIAAAAAAAAAwAAAP//jFNNi9swEL37V4g5x4s3cRLHty0tpZCWsqWnbjGKNHbU1VclmU0a8t+L + P2I72yzUByHmzbw38zQ+RYSA4JATYHsamLIyfuDJ4/M38cfL9Qe33R75IavM55f0++GQfoJZU2F2 + v5CFS9UdM8pKDMLoDmYOacCG9X69WGTLTbaet4AyHGVTVtkQpyaeJ/M0TrI4WfWFeyMYesjJj4gQ + Qk7t2bSoOR4gJ8nsElHoPa0Q8iGJEHBGNhGg3gsfqA4wG0FmdEDddK1rKSdAMEYWjEo5CnffaXIf + faJSFunaqq/i99a8Xz2+kzv1or5kWfWxnuh11EfbNlTWmg3+TPAhnr8SIwQ0VdgJ+lCIq1n6DOqq + WqEOTd9weoLDE+TLu+UZrhLP0a37z4kBDsvaU9k708fPg9XSVNaZnX/lHJRCC78vHFLfTjA1Mrqo + tTpQX70VWGeUDUUwz6gb2sUq61hhXKURvV/1YDCByklVls5u8BUcAxXtYw77wyjbIx9Lxz2iNRdm + AkST2f/t5hZ3N7/Q1f/QjwBjaAPywjrkgl1PPKY5bP60t9IGl9uGwR99QFWUQlforBPtskNpiw1f + JoxvNskOonP0FwAA//8DAFcMvhr1AwAA headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df95d0698c99651-SJC + - 8effbae9f94c67c4-SJC Connection: - keep-alive Content-Encoding: @@ -449,7 +412,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:32:38 GMT + - Tue, 10 Dec 2024 19:44:33 GMT Server: - cloudflare Transfer-Encoding: @@ -463,7 +426,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "804" + - "888" openai-version: - "2020-10-01" strict-transport-security: @@ -475,50 +438,38 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999750" + - "29999744" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_5ba19ba130b00d9cc8726cdb6aacfd79 + - req_9f0fb599bd9aa3cbc99412fbeee4d0c8 status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}, {"role": "assistant", "content": "Thought: I need to - cast ''5.5'' to a float first.\n. Based on this reasoning, let''s select the - appropriate tool!\nAction: "}, {"role": "user", "content": "Continue..."}, {"role": - "assistant", "content": null, "function_call": null, "tool_calls": [{"id": "call_KvzG3U5nRjmXOg2PjwaIm3TA", - "type": "function", "function": {"arguments": "{\"x\": \"5.5\"}", "name": "cast_float"}}]}, - {"role": "tool", "content": "Observation: 5.5", "name": "cast_float", "tool_call_id": - "call_KvzG3U5nRjmXOg2PjwaIm3TA"}, {"role": "assistant", "content": "Thought: - Now that I have cast ''5.5'' to a float, which is 5.5, I need to cast it to - an integer.\n. Based on this reasoning, let''s select the appropriate tool!\nAction: - "}, {"role": "user", "content": "Continue..."}, {"role": "assistant", "content": - null, "function_call": null, "tool_calls": [{"id": "call_E1tLG2AuHAitYygGCafwfJOM", - "type": "function", "function": {"arguments": "{\"x\": 5.5}", "name": "cast_int"}}]}, - {"role": "tool", "content": "Observation: 5", "name": "cast_int", "tool_call_id": - "call_E1tLG2AuHAitYygGCafwfJOM"}], "model": "gpt-4o-2024-08-06", "parallel_tool_calls": - false, "stop": ["Observation:", "Action:"], "tool_choice": "none", "tools": - [{"type": "function", "function": {"name": "print_story", "description": "Print - a story.", "parameters": {"type": "object", "properties": {"story": {"description": - "Story to print.", "title": "Story", "type": "string"}}, "required": ["story"]}}}, - {"type": "function", "function": {"name": "cast_float", "description": "Cast - the input argument x to a float.", "parameters": {"type": "object", "properties": - {"x": {"title": "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", - "function": {"name": "cast_int", "description": "Cast the input argument x to - an integer.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."},{"role":"assistant","content":"Thought: First, I need to cast + the string ''5.5'' to a float.\n. Based on this reasoning, let''s select the + appropriate tool!\nAction: "},{"role":"user","content":"Continue..."},{"role":"assistant","content":null,"function_call":null,"tool_calls":[{"id":"call_k4uBLocb3yv2TTndW5DQmZmG","type":"function","function":{"arguments":"{\"x\": + \"5.5\"}","name":"cast_float"}}]},{"role":"tool","content":"Observation: 5.5","name":"cast_float","tool_call_id":"call_k4uBLocb3yv2TTndW5DQmZmG"},{"role":"assistant","content":"Thought: + Now that I have successfully cast ''5.5'' to the float 5.5, I need to cast the + float 5.5 to an integer.\n. Based on this reasoning, let''s select the appropriate + tool!\nAction: "},{"role":"user","content":"Continue..."},{"role":"assistant","content":null,"function_call":null,"tool_calls":[{"id":"call_47pmPiqLoD6RBlbmwmN88gGu","type":"function","function":{"arguments":"{\"x\": + 5.5}","name":"cast_int"}}]},{"role":"tool","content":"Observation: 5","name":"cast_int","tool_call_id":"call_47pmPiqLoD6RBlbmwmN88gGu"}],"model":"gpt-4o-2024-08-06","n":1,"parallel_tool_calls":false,"stop":["Observation:","Action:"],"tool_choice":"none","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -527,13 +478,13 @@ interactions: connection: - keep-alive content-length: - - "2595" + - "2491" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -543,7 +494,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -557,19 +508,19 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSwWrcMBS8+yseOu8Ge2MnW98ChRJKF9rk0NIUo0jPthpZT0jPcTZh/73Yu1lv - aAq96DDzZjTzpJcEQBgtShCqlaw6b5dX324ehufvX9PnT/XNx82PbvjyWV7dbjJ1YWuxGBV0/xsV - v6rOFHXeIhtye1oFlIyja3Z5nmXp+rJYT0RHGu0oazwvc1qu0lW+TNfL9OIgbMkojKKEnwkAwMt0 - jhGdxidRQrp4RTqMUTYoyuMQgAhkR0TIGE1k6VgsZlKRY3RT6tuW+qblEjY0ALeS4Rpa+YjALYJx - jA0GeJS2RygWcA0OUQMTDMEwgoTIFLYwGG4Bn6Riu4UCBgo6nt250zsD1n2UY2XXW3vAd8cSlhof - 6D4e+CNeG2diWwWUkdwYODJ5MbG7BODXtKz+TX/hA3WeK6YHdKPh+Yds7yfm55nZVX4gmVjaGc+z - YvGOX6WRpbHxZN1CSdWinqXz28heGzohkpPWf6d5z3vf3Ljmf+xnQin0jLryAbVRbxvPYwHH3/uv - seOWp8AibiNjV9XGNRh8MPsPVPsqL1Rd5BolimSX/AEAAP//AwCJYBnBSQMAAA== + H4sIAAAAAAAAAwAAAP//jFLBjtMwFLznK558blbZpqFNbwiJZUFaaRFwARS59mti6vhZ9st2q1X/ + HSXNNq0AiYsPM2/GM89+SQCE0WINQjWSVett+lZnn+37x9t3n4q7XXb34Wv39PAx5KGsH3ffxKxX + 0OYXKn5V3ShqvUU25E60CigZe9fbZZ6vinK1zAeiJY22l9We0wWl82y+SLNVmr0ZhQ0ZhVGs4XsC + APAynH1Ep/FZrCGbvSItxihrFOvzEIAIZHtEyBhNZOlYzCZSkWN0Q+ovDXV1w2t4oD1wIxnuoZFP + CNwgGMdYY4BiBvfgEDUwwT4YRpAQmcIBeitpnHE14LNUbA9QwJ6Cjjc/3OWdAbddlH1l11k74sdz + CUu1D7SJI3/Gt8aZ2FQBZSTXB45MXgzsMQH4OSyru+ovfKDWc8W0Q9cb5uXy5Cem55nYeT6STCzt + hC/m44qv/SqNLI2NF+sWSqoG9SSd3kZ22tAFkVy0/jPN37xPzY2r/8d+IpRCz6grH1Abdd14GgvY + /95/jZ23PAQW8RAZ22prXI3BB3P6QFtflbrIlC7LbCOSY/IbAAD//wMArvA5aEkDAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df95d0d1eab9651-SJC + - 8effbaf05e8b67c4-SJC Connection: - keep-alive Content-Encoding: @@ -577,7 +528,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:32:39 GMT + - Tue, 10 Dec 2024 19:44:34 GMT Server: - cloudflare Transfer-Encoding: @@ -591,7 +542,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "486" + - "742" openai-version: - "2020-10-01" strict-transport-security: @@ -603,53 +554,41 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999745" + - "29999739" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_fad1c5ae2dfe136d6124a1bc3f567a70 + - req_647d24cea03da8cc711d8d751099c15a status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}, {"role": "assistant", "content": "Thought: I need to - cast ''5.5'' to a float first.\n. Based on this reasoning, let''s select the - appropriate tool!\nAction: "}, {"role": "user", "content": "Continue..."}, {"role": - "assistant", "content": null, "function_call": null, "tool_calls": [{"id": "call_KvzG3U5nRjmXOg2PjwaIm3TA", - "type": "function", "function": {"arguments": "{\"x\": \"5.5\"}", "name": "cast_float"}}]}, - {"role": "tool", "content": "Observation: 5.5", "name": "cast_float", "tool_call_id": - "call_KvzG3U5nRjmXOg2PjwaIm3TA"}, {"role": "assistant", "content": "Thought: - Now that I have cast ''5.5'' to a float, which is 5.5, I need to cast it to - an integer.\n. Based on this reasoning, let''s select the appropriate tool!\nAction: - "}, {"role": "user", "content": "Continue..."}, {"role": "assistant", "content": - null, "function_call": null, "tool_calls": [{"id": "call_E1tLG2AuHAitYygGCafwfJOM", - "type": "function", "function": {"arguments": "{\"x\": 5.5}", "name": "cast_int"}}]}, - {"role": "tool", "content": "Observation: 5", "name": "cast_int", "tool_call_id": - "call_E1tLG2AuHAitYygGCafwfJOM"}, {"role": "assistant", "content": "Thought: - Now that I have the integer value 5, I need to write a story with exactly 5 + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."},{"role":"assistant","content":"Thought: First, I need to cast + the string ''5.5'' to a float.\n. Based on this reasoning, let''s select the + appropriate tool!\nAction: "},{"role":"user","content":"Continue..."},{"role":"assistant","content":null,"function_call":null,"tool_calls":[{"id":"call_k4uBLocb3yv2TTndW5DQmZmG","type":"function","function":{"arguments":"{\"x\": + \"5.5\"}","name":"cast_float"}}]},{"role":"tool","content":"Observation: 5.5","name":"cast_float","tool_call_id":"call_k4uBLocb3yv2TTndW5DQmZmG"},{"role":"assistant","content":"Thought: + Now that I have successfully cast ''5.5'' to the float 5.5, I need to cast the + float 5.5 to an integer.\n. Based on this reasoning, let''s select the appropriate + tool!\nAction: "},{"role":"user","content":"Continue..."},{"role":"assistant","content":null,"function_call":null,"tool_calls":[{"id":"call_47pmPiqLoD6RBlbmwmN88gGu","type":"function","function":{"arguments":"{\"x\": + 5.5}","name":"cast_int"}}]},{"role":"tool","content":"Observation: 5","name":"cast_int","tool_call_id":"call_47pmPiqLoD6RBlbmwmN88gGu"},{"role":"assistant","content":"Thought: + Now that I have the integer 5, I need to write a story containing exactly 5 words.\n. Based on this reasoning, let''s select the appropriate tool!\nAction: - "}, {"role": "user", "content": "Continue..."}], "model": "gpt-4o-2024-08-06", - "parallel_tool_calls": false, "stop": ["Observation:", "Action:"], "tool_choice": - "required", "tools": [{"type": "function", "function": {"name": "print_story", - "description": "Print a story.", "parameters": {"type": "object", "properties": - {"story": {"description": "Story to print.", "title": "Story", "type": "string"}}, - "required": ["story"]}}}, {"type": "function", "function": {"name": "cast_float", - "description": "Cast the input argument x to a float.", "parameters": {"type": - "object", "properties": {"x": {"title": "X", "type": "string"}}, "required": - ["x"]}}}, {"type": "function", "function": {"name": "cast_int", "description": - "Cast the input argument x to an integer.", "parameters": {"type": "object", - "properties": {"x": {"title": "X", "type": "number"}}, "required": ["x"]}}}]}' + "},{"role":"user","content":"Continue..."}],"model":"gpt-4o-2024-08-06","n":1,"parallel_tool_calls":false,"stop":["Observation:","Action:"],"tool_choice":"required","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -658,13 +597,13 @@ interactions: connection: - keep-alive content-length: - - "2845" + - "2733" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -674,7 +613,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -688,20 +627,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xTTW/bMAy9+1cIPCdFvpP61m7YMAzYIRvWFstgKDJta5UlTaKHZEH++2A5sZ2s - BeqDIPDxPZJP9CFiDGQKMQNRcBKlVcO79dfnnfj9x/5Ffa8X24978f39Mnv8tP6sH2BQM8z2Fwo6 - s26EKa1CkkY3sHDICWvV8XI6Ho9Wy/ltAEqToqppuaXhzAwno8lsOFoNR4sTsTBSoIeY/YgYY+wQ - zrpFneIOYjYanCMles9zhLhNYgycUXUEuPfSE9cEgw4URhPqumtdKdUDyBiVCK5UV7j5Dr175xNX - KrG7p3fpl4fVeu0mH8wdPbr7p8V0Ne3Va6T3NjSUVVq0/vTwNh5fFWMMNC8D1zqpKfFk3P6Kzhhw - l1claqpbh8MGQtoG4g18K5AJTsxzYkYzKpCVnG42cIQLkWP00v1nzx+HWeW5Ohl3ih/bl1Amt85s - /ZWxkEktfZE45D4M2Pc5OlcLdaC6eEqwzpSWEjLPqGvZ2fS2UYVu0zp0cloKIENc9VjzM+tCL0mR - uAxv3a6X4KLAtKN2a8arVJoeEPVm/7+bl7Sb+aXO3yLfAUKgJUwT6zCV4nLiLs1h/SO+lta6HBoG - v/eEZZJJnaMLWxVW0yazucjmsxQ5QnSM/gEAAP//AwDPufswFAQAAA== + H4sIAAAAAAAAAwAAAP//jFNNi9swEL37V4g5J4ubePPhW9nuIZTdQFuW3TTFKNLY0VZfSDJsCPnv + xUpiO2kK9UGIefPezDyN9wkhIDjkBNiWBqasHH7m6Tf15D5Wj4uvi4e3xcp9efu+eX5+dPVyBoOG + YTbvyMKZdceMshKDMPoIM4c0YKP6aToez+7ns2kWAWU4yoZW2TDMzHCUjrJhOhumkxNxawRDDzn5 + mRBCyD6eTYua4wfkJB2cIwq9pxVC3iYRAs7IJgLUe+ED1QEGHciMDqibrnUtZQ8IxsiCUSm7wsdv + 37t3PlEpi6WZ7p4mD6P3lx91iQv3qsbl62r20qt3lN7Z2FBZa9b608PbeH5VjBDQVEWudUKHwgfj + dld0QoC6qlaoQ9M67NcQ09aQr2GpGZLaGk0oCULhgGyptUKj98ShqDTyuzUc4ELxkNy6/+qZ5bCs + PZUnF0/xQ/ss0lTWmY2/chlKoYXfFg6pj9P2TU/O1WIdqC/eFawzyoYimN+oG9ksy46q0K1dh45G + JzCYQGWPNZkMbugVHAMV8eHbXWOUbZF31G7naM2F6QFJb/a/u7mlfZxf6Op/5DuAMbQBeWEdcsEu + J+7SHDZ/5b/SWpdjw+B3PqAqSqErdHHF4p7aYs7vU8bn83QDySH5AwAA//8DAGfXRGQhBAAA headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df95d118aa49651-SJC + - 8effbaf5daeb67c4-SJC Connection: - keep-alive Content-Encoding: @@ -709,7 +648,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:32:39 GMT + - Tue, 10 Dec 2024 19:44:35 GMT Server: - cloudflare Transfer-Encoding: @@ -723,7 +662,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "409" + - "690" openai-version: - "2020-10-01" strict-transport-security: @@ -735,13 +674,13 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999699" + - "29999692" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_da74a5eb9bca14038fce7bd69d7a5a10 + - req_3dc231dbb4775d7cb77a7e910a5c5910 status: code: 200 message: OK diff --git a/tests/cassettes/TestReActAgent.test_multi_step[True].yaml b/tests/cassettes/TestReActAgent.test_multi_step[True].yaml index 7eb97e33..d98bab28 100644 --- a/tests/cassettes/TestReActAgent.test_multi_step[True].yaml +++ b/tests/cassettes/TestReActAgent.test_multi_step[True].yaml @@ -1,7 +1,7 @@ interactions: - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can. You have access to the following tools:\n\nNAME: print_story\n\nSYNOPSIS:\n print_story(string story)\n\nDESCRIPTION:\n Print a story.\n\nPARAMETERS:\n story (string): Story to print.\n\nNAME: cast_float\n\nSYNOPSIS:\n cast_float(string x)\n\nDESCRIPTION:\n Cast @@ -14,9 +14,9 @@ interactions: tuple\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather\nAction Input: \"New York\", 7\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}], "model": "gpt-4o-2024-08-06", "stop": ["Observation:"]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."}],"model":"gpt-4o-2024-08-06","n":1,"stop":["Observation:"]}' headers: accept: - application/json @@ -25,13 +25,13 @@ interactions: connection: - keep-alive content-length: - - "1337" + - "1331" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -41,11 +41,11 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: - - "1" + - "0" x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -55,19 +55,19 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4yST2+cMBDF73yKkS9pJVgBu5ul3PZUbS9VuqsqUlMhxx7AKdiuPVSNov3uldk/ - EDWVeuHwfn6PeWO/RABMSVYCEy0n0dsu2X7Zy+wXffz8fH/3k9zubnN/2G+/PjX74tOBxcFhHp9Q - 0MW1EKa3HZIy+oSFQ04YUrPNMsvSIr/djKA3ErtgaywlK5Pkab5K0iJJb8/G1iiBnpXwLQIAeBm/ - YUQt8TcrIY0vSo/e8wZZeT0EwJzpgsK498oT18TiCQqjCfU49aE1Q9NSCTvQiBLIgOCegFoET07p - Bm7Wi/VNABzqznCCWjlPiwe9FaFoORqqEV002Gk7UAnvRm/8/kHPf++wHjwP7fXQdWf9eO3TmcY6 - 8+jP/KrXSivfVg65NzrM7slYNtJjBPB93NvwahXMOtNbqsj8QB0C82J5ymPTTU10mZ8hGeLdTM/W - 8Rt5lUTiqvOzzTPBRYtysk7XxAepzAxEs9Z/T/NW9qm50s3/xE9ACLSEsrIOpRKvG0/HHIaH/K9j - 1y2PAzP/7An7qla6QWedOr2l2lbZ+oMslqtMCBYdoz8AAAD//wMAtQxDr1QDAAA= + H4sIAAAAAAAAA4xSTWvcMBS8+1c8dEkL9uLdjTe7vgVCIYdCUxba0C1GKz3bamVJlZ5pStj/XuT9 + sENTyEWHmTfDzHt6TgCYkqwEJlpOonM6u5X5ZyweHraP+y9f1fxJf3z88Kn9Je62v/0NS6PC7n+g + oLNqJmznNJKy5kgLj5wwus5vlst1sVmvVgPRWYk6yhpH2bXNFvniOsvXWb46CVurBAZWwrcEAOB5 + eGNEI/GJlZCnZ6TDEHiDrLwMATBvdUQYD0EF4oZYOpLCGkIzpN62tm9aKuEeDKIEslArHwgEDwTU + IgTyyjRwVcyKq0hzqLXlNNuZWxGLlsNoNYBnDO6N66mEdztWzIodS9/vzDSAx7oPPPY3vdYn/HBp + pG3jvN2HE3/Ba2VUaCuPPFgT0weyjg3sIQH4Pmyuf7EM5rztHFVkf6KJhov18ujHxluN7HJxIskS + 1xN8XqSv+FUSiSsdJrtngosW5SgdD8V7qeyESCat/03zmvexuTLNW+xHQgh0hLJyHqUSLxuPYx7j + V/7f2GXLQ2AW/gTCrqqVadA7r46/qXbVRha5kJtNvmfJIfkLAAD//wMA5RGCp1YDAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df9510c9f0c22ba-SJC + - 8effbac5baf7d039-SJC Connection: - keep-alive Content-Encoding: @@ -75,9 +75,15 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:27 GMT + - Tue, 10 Dec 2024 19:44:27 GMT Server: - cloudflare + Set-Cookie: + - __cf_bm=r6dZddUDWfN_Os.WIvmSRteRx9TQDrAqu8ra.Qbl9Rg-1733859867-1.0.1.1-bHAbl3a2MCrOO2KjtKMQsO2qa26vpz8SS4okiAhw16opeBH13XEmOd8TzokuXcMbLWibxkSbI.69x8G.cQ2EHA; + path=/; expires=Tue, 10-Dec-24 20:14:27 GMT; domain=.api.openai.com; HttpOnly; + Secure; SameSite=None + - _cfuvid=gioa0R.ivKqZKaFec_dzeeGl_QNH0QCLOItZoOpXstA-1733859867523-0.0.1.1-604800000; + path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked X-Content-Type-Options: @@ -89,7 +95,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "652" + - "895" openai-version: - "2020-10-01" strict-transport-security: @@ -107,13 +113,13 @@ interactions: x-ratelimit-reset-tokens: - 0s x-request-id: - - req_fab28d5f04ad57fc92dc973d8cfb2413 + - req_5fc910e91f3fcf4bd0193ba919285ab0 status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can. You have access to the following tools:\n\nNAME: print_story\n\nSYNOPSIS:\n print_story(string story)\n\nDESCRIPTION:\n Print a story.\n\nPARAMETERS:\n story (string): Story to print.\n\nNAME: cast_float\n\nSYNOPSIS:\n cast_float(string x)\n\nDESCRIPTION:\n Cast @@ -126,12 +132,11 @@ interactions: tuple\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather\nAction Input: \"New York\", 7\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}, {"role": "assistant", "content": "Thought: I need to - cast the string ''5.5'' to a float first.\nAction: cast_float\nAction Input: - (''5.5'',)"}, {"role": "user", "content": "Observation: 5.5"}], "model": "gpt-4o-2024-08-06", - "stop": ["Observation:"]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."},{"role":"assistant","content":"Thought: I need to first cast the + string ''5.5'' to a float.\nAction: cast_float\nAction Input: (\"5.5\",)"},{"role":"user","content":"Observation: + 5.5"}],"model":"gpt-4o-2024-08-06","n":1,"stop":["Observation:"]}' headers: accept: - application/json @@ -140,13 +145,13 @@ interactions: connection: - keep-alive content-length: - - "1526" + - "1514" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -156,7 +161,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -170,19 +175,19 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSTYvbMBS8+1c8dGohDnYS58O3pZCytJTS7G1bjFZ6trWVJVV6ZluW/Pci58MO - baEXHWbejGae9JoAMCVZCUy0nETndHr35SBzsX+Q+bp9PnSfXzYffuzfvV/x/cfdgc2iwj49o6CL - ai5s5zSSsuZEC4+cMLrmm2WeZ9vFejMQnZWoo6xxlK5susgWqzTbptn6LGytEhhYCY8JAMDrcMaI - RuJPVkI2uyAdhsAbZOV1CIB5qyPCeAgqEDfEZiMprCE0Q+qH1vZNSyV8si9wDwZRAlkQPBBQi1Br - ywmKeRFRbkAZwgb9/Ku5E7FmOYxWytAFgXvjeirhTTEvZm+n13qs+8Bja9NrfcaP1x7aNs7bp3Dm - r3itjApt5ZEHa2LmQNaxgT0mAN+GffU3K2DO285RRfY7mmi4XOxOfmx8oQl7XiYjS1xP8OKiuvGr - JBJXOkw2zgQXLcpROj4P76WyEyKZtP4zzd+8T82Vaf7HfiSEQEcoK+dRKnHbeBzzGD/wv8auWx4C - s/ArEHZVrUyD3nl1+kO1q/JiJ7fLVS4ES47JbwAAAP//AwClrP+KTAMAAA== + H4sIAAAAAAAAAwAAAP//jJJNa9wwEIbv/hWDTi3sLu5+r2+BUthLD20oLU0xWmlsq5U1ijRuG8L+ + 9yLvhx2aQC7GvM/My7wzeswAhNGiAKEayar1dnqj809V83B//0HHfW0Pn7/c0pY2X/ff3ru1mKQO + OvxExZeumaLWW2RD7oRVQMmYXN9tFovtarddb3rQkkab2mrP0yVN5/l8Oc230/zsqxoyCqMo4HsG + APDYf9OITuNfUUA+uSgtxihrFMW1CEAEskkRMkYTWToWkwEqcoyun/q2oa5uuICP9Ae4kQx7aORv + BG4QKkuSYTVbTWAPDlEDEygZGQynX+nAOMYaw+zO3agUu+h5aRxfFNg733EBb5LP2/EYAasuyrQF + 11l71o/XXJZqH+gQz/yqV8aZ2JQBZSSXMkQmL3p6zAB+9PvrnqxE+ECt55LpF7pkuJjvTn5iuNiI + rs6QiaUd6evl5Bm/UiNLY+PoAkJJ1aAeWodzyU4bGoFslPr/aZ7zPiU3rn6N/QCUQs+oSx9QG/U0 + 8VAWMD3ol8quW+4HFvEhMrZlZVyNwQdzelOVL3d6lSu92+UHkR2zfwAAAP//AwBU5kw4XAMAAA== headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df951116d5022ba-SJC + - 8effbacc28d6d039-SJC Connection: - keep-alive Content-Encoding: @@ -190,7 +195,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:28 GMT + - Tue, 10 Dec 2024 19:44:28 GMT Server: - cloudflare Transfer-Encoding: @@ -204,7 +209,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "647" + - "625" openai-version: - "2020-10-01" strict-transport-security: @@ -222,13 +227,13 @@ interactions: x-ratelimit-reset-tokens: - 0s x-request-id: - - req_c798eb70cb8171a0bfb79f4535ae68b9 + - req_21906eb43abccec10d343df6ef16ef82 status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can. You have access to the following tools:\n\nNAME: print_story\n\nSYNOPSIS:\n print_story(string story)\n\nDESCRIPTION:\n Print a story.\n\nPARAMETERS:\n story (string): Story to print.\n\nNAME: cast_float\n\nSYNOPSIS:\n cast_float(string x)\n\nDESCRIPTION:\n Cast @@ -241,14 +246,13 @@ interactions: tuple\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather\nAction Input: \"New York\", 7\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Cast - ''5.5'' to a float, then to an integer, and finally use it to write a story - of that many words."}, {"role": "assistant", "content": "Thought: I need to - cast the string ''5.5'' to a float first.\nAction: cast_float\nAction Input: - (''5.5'',)"}, {"role": "user", "content": "Observation: 5.5"}, {"role": "assistant", - "content": "Thought: Now I need to cast the float 5.5 to an integer.\nAction: - cast_int\nAction Input: (5.5,)"}, {"role": "user", "content": "Observation: - 5"}], "model": "gpt-4o-2024-08-06", "stop": ["Observation:"]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Cast ''5.5'' + to a float, then to an integer, and finally use it to write a story of that + many words."},{"role":"assistant","content":"Thought: I need to first cast the + string ''5.5'' to a float.\nAction: cast_float\nAction Input: (\"5.5\",)"},{"role":"user","content":"Observation: + 5.5"},{"role":"assistant","content":"Thought: Now that I have the float 5.5, + I need to cast it to an integer.\nAction: cast_int\nAction Input: (5.5,)"},{"role":"user","content":"Observation: + 5"}],"model":"gpt-4o-2024-08-06","n":1,"stop":["Observation:"]}' headers: accept: - application/json @@ -257,13 +261,13 @@ interactions: connection: - keep-alive content-length: - - "1707" + - "1703" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -273,7 +277,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -287,20 +291,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSy27bMBC86ysWPLWAbEh+R7cccynQNgUC1IVAk2uJrsRlyVUdN/C/F5QfctAU - yIWHmZ3BzC5fEgBhtChAqFqyal0zuv/yVU++Led6t5lUv6ZPn7s/eVerTf5k5lKkUUGbHSq+qMaK - WtcgG7InWnmUjNE1X07zPFtNFqueaEljE2WV49GMRpNsMhtlq1G2OAtrMgqDKOB7AgDw0r8xotX4 - LArI0gvSYgiyQlFchwCEpyYiQoZgAkvLIh1IRZbR9qkfa+qqmgv4RPsUHsAiamCCvTeMICEw+QNw - LRlMAHyWipsDzGFPXgdoyFbjtb1XsXEBzhvLZS+5gPBgXccFfFiLxxpBSYZd1zrUQL/RA9cILZEd - r0X68Taix20XZNyQ7ZrmjB+vnRuqnKdNOPNXfGusCXXpUQaysV9gcqJnjwnAj3633at1CeepdVwy - /UQbDafL/OQnhmvesPMzycSyGfBZtkjf8Cs1sjRNuLmOUFLVqAfpcErZaUM3RHLT+t80b3mfmhtb - vcd+IJRCx6hL51Eb9brxMOYxfvb/jV233AcW4RAY23JrbIW+/xnxHltX5vM7vZrOcqVEckz+AgAA - //8DAKIozat4AwAA + H4sIAAAAAAAAAwAAAP//jFNNj9owEL3nV4x8aqWAsgsskBu3UlVtVe2hUllFxh4SU8fj2hNYuuK/ + VwkfYdWt1EsO7817evPGeUkAhNEiB6Eqyar2drDQ2bdyPJ/W9PHX9PsHre1uQb/11+1i++lRpK2C + 1ltUfFENFdXeIhtyJ1oFlIyt6910NJpN5rOHWUfUpNG2stLzYEyD++x+PMhmg+zhLKzIKIwihx8J + AMBL920jOo3PIocsvSA1xihLFPl1CEAEsi0iZIwmsnQs0p5U5Bhdl/qxoqasOIfPtAeuJMMSKrlD + 4ArBOMYSA+ykbRAmKSxhb6yFfTCMICEyhcNJZSLgs1RsDzCBPQUdwZIrhyu3UG0dOfhgHBed5ALC + 0vmGc3i3El+cQmg8OZDApsYUKum9cRjjcCXe36YPuGmibMtzjbVn/Hitw1LpA63jmb/iG+NMrIqA + MpJrV49MXnTsMQF46mpvXjUpfKDac8H0E11rOJo+nPxEf+ieHd+dSSaW9hafpm/4FRpZGhtvDieU + VBXqXtpfWTba0A2R3Gz9d5q3vE+bG1f+j31PKIWeURc+oDbq9cb9WMD2P/jX2LXlLrCIh8hYFxvj + Sgzdu2jvsfHFXE8ypefzbC2SY/IHAAD//wMAOh6TDpMDAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df951162b0c22ba-SJC + - 8effbad0cd60d039-SJC Connection: - keep-alive Content-Encoding: @@ -308,7 +312,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:29 GMT + - Tue, 10 Dec 2024 19:44:29 GMT Server: - cloudflare Transfer-Encoding: @@ -322,7 +326,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "688" + - "888" openai-version: - "2020-10-01" strict-transport-security: @@ -334,13 +338,13 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999634" + - "29999630" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_9f63fa5e62d5dc9d364dfe622359f34a + - req_d1f9a64806371bef60e98109cc7df15e status: code: 200 message: OK diff --git a/tests/cassettes/TestReActAgent.test_react_dummyenv[False-gpt-4o].yaml b/tests/cassettes/TestReActAgent.test_react_dummyenv[False-gpt-4o].yaml index 10a596d7..ae04e3a1 100644 --- a/tests/cassettes/TestReActAgent.test_react_dummyenv[False-gpt-4o].yaml +++ b/tests/cassettes/TestReActAgent.test_react_dummyenv[False-gpt-4o].yaml @@ -1,24 +1,18 @@ interactions: - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Write - a 5 word story via print_story"}], "model": "gpt-4o", "stop": ["Observation:", - "Action:"], "temperature": 0.1, "tool_choice": "none", "tools": [{"type": "function", - "function": {"name": "print_story", "description": "Print a story.", "parameters": - {"type": "object", "properties": {"story": {"description": "Story to print.", - "title": "Story", "type": "string"}}, "required": ["story"]}}}, {"type": "function", - "function": {"name": "cast_float", "description": "Cast the input argument x - to a float.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", "function": - {"name": "cast_int", "description": "Cast the input argument x to an integer.", - "parameters": {"type": "object", "properties": {"x": {"title": "X", "type": - "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Write a + 5 word story via print_story"}],"model":"gpt-4o","n":1,"stop":["Observation:","Action:"],"temperature":0.1,"tool_choice":"none","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -27,13 +21,13 @@ interactions: connection: - keep-alive content-length: - - "1413" + - "1345" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -43,7 +37,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -57,19 +51,18 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSTW/UMBC951eMfN5Um+xH09x6QIgLQrQcEKDItSeJi+Ox7ImWUu1/R85uN6ko - Ehcf5n3ovRk/ZwDCaFGDUL1kNXib336+U7/l+850n6pt9fEr3t3fPpae7Jf9u0qskoIeHlHxi+pK - 0eAtsiF3glVAyZhci+tNUayrcr+bgIE02iTrPOdbyst1uc3XVb7en4U9GYVR1PAtAwB4nt4U0Wn8 - JWpYr14mA8YoOxT1hQQgAtk0ETJGE1k6FqsZVOQY3ZT6vqex67mGD3Aw1sIYEbhH8ME4biJTeIJ2 - dCpVAiY4BMMIEnb5gYKGiXD13S3dA7ZjlKmcG609z4+XuJY6H+ghnvHLvDXOxL4JKCO5FC0yeTGh - xwzgx7SW8VVT4QMNnhumn+iSYVnsT35iPsSMFtdnkImlXag2m9Ubfo1GlsbGxWKFkqpHPUvnK8hR - G1oA2aL132ne8j41N677H/sZUAo9o258QG3U68YzLWD6p/+iXbY8BRbxKTIOTWtch2H6CekerW+K - 3Y2uNttCKZEdsz8AAAD//wMAni45nzMDAAA= + H4sIAAAAAAAAAwAAAP//jFLLTsMwELznK6w9Nyh9t7kBF46o4oBAKHLtTeLieC3bQbRV/x05LX2o + ReLiw8zOeGbtbcIYKAk5A1HzIBqr03uZLerNyD4+NJq+NqvN4mX9Wg7fJs9y/AS9qKDlCkX4Vd0J + aqzGoMjsaeGQB4yu/elwOBvPZ5N5RzQkUUdZZUM6onSQDUZpNkuzyUFYkxLoIWfvCWOMbbszRjQS + vyFnWe8XadB7XiHkxyHGwJGOCHDvlQ/cBOidSEEmoOlSn8MOy9bzmMq0Wh/w3fEeTZV1tPQH/oiX + yihfFw65JxM9fSALHbtLGPvo+rQXEcE6amwoAn2iiYaD/mTvB6cNnthDVwgUuL4lurArJAautD9b + CAguapRXjowBb6WiMyI5K30d5pb3vrgy1X/sT4QQaAPKwjqUStws3JnH//XX2HHJXWDwax+wKUpl + KnTWqf0Tl7YQU8EzXHLBIdklPwAAAP//AwBFYrKZ6wIAAA== headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df951038956ce5c-SJC + - 8effbad2dcbc9e56-SJC Connection: - keep-alive Content-Encoding: @@ -77,7 +70,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:25 GMT + - Tue, 10 Dec 2024 19:44:29 GMT Server: - cloudflare Transfer-Encoding: @@ -91,7 +84,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "367" + - "896" openai-version: - "2020-10-01" strict-transport-security: @@ -109,33 +102,25 @@ interactions: x-ratelimit-reset-tokens: - 0s x-request-id: - - req_a8309d869726cb11a8aad907378120f7 + - req_6b16e63e79e61ae7b962cfe7d7a4aac2 status: code: 200 message: OK - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can, using the provided tools.\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of the provided tools with necessary arguments\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather(\"New York\", 7)\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Write - a 5 word story via print_story"}, {"role": "assistant", "content": "Thought: - I will use the print_story function to write a 5-word story.\n. Based on this - reasoning, let''s select the appropriate tool!\nAction: "}, {"role": "user", - "content": "Continue..."}], "model": "gpt-4o", "stop": ["Observation:", "Action:"], - "temperature": 0.1, "tool_choice": "required", "tools": [{"type": "function", - "function": {"name": "print_story", "description": "Print a story.", "parameters": - {"type": "object", "properties": {"story": {"description": "Story to print.", - "title": "Story", "type": "string"}}, "required": ["story"]}}}, {"type": "function", - "function": {"name": "cast_float", "description": "Cast the input argument x - to a float.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", "function": - {"name": "cast_int", "description": "Cast the input argument x to an integer.", - "parameters": {"type": "object", "properties": {"x": {"title": "X", "type": - "number"}}, "required": ["x"]}}}]}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Write a + 5 word story via print_story"},{"role":"assistant","content":"Thought: . Based + on this reasoning, let''s select the appropriate tool!\nAction: "},{"role":"user","content":"Continue..."}],"model":"gpt-4o","n":1,"stop":["Observation:","Action:"],"temperature":0.1,"tool_choice":"required","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -144,13 +129,13 @@ interactions: connection: - keep-alive content-length: - - "1641" + - "1503" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -160,7 +145,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -174,20 +159,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xTTY/TMBC951dYc25XSb83t+UALCCE6FYrlqLI60wTg2Nb9gSoqv53FKdN0rJI - 5GBZ8+a9mXmeHCLGQOaQMhAlJ1FZNb77vM7jvZh/eHg3fZCvna0XP83m0+39ev20h1HDMM/fUdCZ - dSNMZRWSNLqFhUNO2Kgmy2mSxKvJYhGAyuSoGlphaTwz40k8mY3j1ThenIilkQI9pOxrxBhjh3A2 - Leocf0PK4tE5UqH3vEBIuyTGwBnVRIB7Lz1xTTDqQWE0oW661rVSA4CMUZngSvWF2+8wuPc+caWy - x/n7DdZvnubrV2b39k59XE4fN/dfkkG9VnpvQ0O7WovOnwHexdOrYoyB5lXgWic1ZZ6M21/RGQPu - irpCTU3rcNhCSNtCuoV1rT0S+1VKb9F55lE4JM/IMC2Lkm62cIQLuWP00v3bwCmHu9pzdbLwFD92 - b6JMYZ159lcWw05q6cvMIfdh1KHj0blaqAP1xaOCdaaylJH5gbqRncyXrSr0OzdAT+sBZIirQXx5 - Zl3oZTkSl+HVu0UTXJSY99R+4XidSzMAosHsf3fzknY7v9TF/8j3gBBoCfPMOsyluJy4T3PY/JL/ - SutcDg2D33vCKttJXaAL+xWW1GbJ/DZfTWeJEBAdoz8AAAD//wMA8IZlSh4EAAA= + H4sIAAAAAAAAAwAAAP//jFPBbtswDL37KwSek8JL0jj1rdiAnVpgyYBhWApDkRlbnSxpEr0mDfLv + g+XEdrIWqA+CwMf3SD7Rh4gxkDmkDETJSVRWje/zeFl+/V4k/svt9pvQO4MP8z8/fibJ5+UURg3D + bJ5R0Jl1I0xlFZI0uoWFQ07YqH5KptPF7d1ifheAyuSoGlphaTwz40k8mY3jxTien4ilkQI9pOxX + xBhjh3A2Leocd5CyeHSOVOg9LxDSLokxcEY1EeDeS09cE4x6UBhNqJuuda3UACBjVCa4Un3h9jsM + 7r1PXKlsVeySh+dXuv9bvarlZEnx46NdvcwG9VrpvQ0NbWstOn8GeBdPr4oxBppXgWud1JR5Mm5/ + RWcMuCvqCjU1rcNhDSFtDekaVrX2SOyllN6i88yjcEiekWFaFiXdrOEIF3LH6K3708Aph9vac3Wy + 8BQ/dm+iTGGd2fgri2ErtfRl5pD7MOrQ8ehcLdSB+uJRwTpTWcrI/EbdyE5mk1YV+p0boKf1ADLE + 1SA+P7Mu9LIcicvw6t2iCS5KzHtqv3C8zqUZANFg9v+7eUu7nV/q4iPyPSAEWsI8sw5zKS4n7tMc + Nr/ke2mdy6Fh8HtPWGVbqQt0Yb/CktpMJILHuOGCQ3SM/gEAAP//AwBbSysBHgQAAA== headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df951068d23ce5c-SJC + - 8effbad959279e56-SJC Connection: - keep-alive Content-Encoding: @@ -195,7 +180,7 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:26 GMT + - Tue, 10 Dec 2024 19:44:30 GMT Server: - cloudflare Transfer-Encoding: @@ -209,7 +194,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "413" + - "560" openai-version: - "2020-10-01" strict-transport-security: @@ -221,13 +206,13 @@ interactions: x-ratelimit-remaining-requests: - "9999" x-ratelimit-remaining-tokens: - - "29999812" + - "29999828" x-ratelimit-reset-requests: - 6ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_1a8816a1d18402ce51ea115d4b0ef4e8 + - req_c68421e4837ba73aad651c4790c88a0d status: code: 200 message: OK diff --git a/tests/cassettes/TestReActAgent.test_react_dummyenv[True-gpt-4-turbo].yaml b/tests/cassettes/TestReActAgent.test_react_dummyenv[True-gpt-4-turbo].yaml index e031caa5..b4bb04fa 100644 --- a/tests/cassettes/TestReActAgent.test_react_dummyenv[True-gpt-4-turbo].yaml +++ b/tests/cassettes/TestReActAgent.test_react_dummyenv[True-gpt-4-turbo].yaml @@ -1,7 +1,7 @@ interactions: - request: body: - '{"messages": [{"role": "system", "content": "Answer the following questions + '{"messages":[{"role":"system","content":"Answer the following questions as best you can. You have access to the following tools:\n\nNAME: print_story\n\nSYNOPSIS:\n print_story(string story)\n\nDESCRIPTION:\n Print a story.\n\nPARAMETERS:\n story (string): Story to print.\n\nNAME: cast_float\n\nSYNOPSIS:\n cast_float(string x)\n\nDESCRIPTION:\n Cast @@ -14,9 +14,8 @@ interactions: tuple\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\n\nExample:\n\nThought: I need to use the get_weather tool\nAction: get_weather\nAction Input: \"New York\", 7\nObservation: - The 7 day forecast for New York is [...]"}, {"role": "user", "content": "Write - a 5 word story via print_story"}], "model": "gpt-4-turbo", "stop": ["Observation:"], - "temperature": 0.1}' + The 7 day forecast for New York is [...]"},{"role":"user","content":"Write a + 5 word story via print_story"}],"model":"gpt-4-turbo","n":1,"stop":["Observation:"],"temperature":0.1}' headers: accept: - application/json @@ -25,13 +24,13 @@ interactions: connection: - keep-alive content-length: - - "1289" + - "1281" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -41,7 +40,7 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: @@ -55,20 +54,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xSTa/TMBC851esfAKpqdq+kra5VeLygAN6lBNFkWtvEtPEa+zN41VP/e/I6Uda - ARIXH3Z2RjOzfk0AhNEiB6Fqyap1Tbp++qIOmdrQJvz88PX5/eeneqGyj+tqTYu9GEUG7X6g4gtr - rKh1DbIhe4KVR8kYVaeLh+l0spxl8x5oSWMTaZXjdJ5y53eUziazeTqZp5PVmV2TURhEDt8SAIDX - /o0+rcYXkcNkdJm0GIKsUOTXJQDhqYkTIUMwgaVlMRpARZbR9tY3NXVVzTk8gkXUwAQn4yBh5w2W - EJj8ARTZKGRsBVQCvkjFzQFK84zwi7wO461dqxg+B+eN5aKnXYbwaF3HObzZik8UGPZ4CFBSZzV0 - VqOHQKUcb8Xbrb316bHsgoxd2a5pzvPjNXhDlfO0C2f8Oi+NNaEuPMpANoYMTE706DEB+N4X3N11 - Jpyn1nHBtEcbBWfZ4qQnhrsO6MO5fcHEsrlhrS6sO71CI0vThJsTCSVVjXqgDveUnTZ0AyQ3qf90 - 8zftU3Jjq/+RHwCl0DHqwnnURt0nHtY8xm//r7Vry71hEQ6BsS1KYyv0/ceI9yhdod/p5TxbrjIU - yTH5DQAA//8DAIt6yEiCAwAA + H4sIAAAAAAAAAwAAAP//jFJdi9swEHz3r1j01EIc3CTNXfyWUsodHH0ohUKbYmRpbevO1uqk9TXp + cf/9kPPhhLbQFz3s7Awzs3pOAITRIgehGsmqc2261tkXpNWnx8dwX/3++KFbW9x+/v7tZntz9yQm + kUHlPSo+sqaKOtciG7J7WHmUjFH13dV8fv1+db1cDkBHGttIqx2ni5R7X1I6y2aLNFuk2erAbsgo + DCKHHwkAwPPwRp9W41bkkE2Okw5DkDWK/LQEIDy1cSJkCCawtCwmI6jIMtrB+teG+rrhHG7BImpg + gr1xkFB6gxUEJr8DRTYKGVsDVYBbqbjdQWWeEH6R12G6sWsVw+fgvLFcDLTjEG6t6zmHNxtxR4Hh + AXcBKuqtht5q9BCoktONeLux5z49Vn2QsSvbt+1h/nIK3lLtPJXhgJ/mlbEmNIVHGcjGkIHJiQF9 + SQB+DgX3F50J56lzXDA9oI2Cs+XVXk+Mdx3R+aF9wcSyPWOtjqwLvUIjS9OGsxMJJVWDeqSO95S9 + NnQGJGep/3TzN+19cmPr/5EfAaXQMerCedRGXSYe1zzGb/+vtVPLg2ERdoGxKypja/TDx4j3qFyR + VctshmWppUheklcAAAD//wMAcM+lToIDAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df950f96961253c-SJC + - 8effbac5ebcf6807-SJC Connection: - keep-alive Content-Encoding: @@ -76,14 +75,14 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:24 GMT + - Tue, 10 Dec 2024 19:44:28 GMT Server: - cloudflare Set-Cookie: - - __cf_bm=zHuQMrOnwgyJc9MJ4XFrqssgthlTjUOSHpl0GoPmrwQ-1731108264-1.0.1.1-8_IgZ7QNlTyIRRQKL02MJJiYMzDbXtU8Pcl.bpULr32wFLZAG0DgBW2mUXVsh4Y7Lbysh33MgfiQwnM.YfmIfQ; - path=/; expires=Fri, 08-Nov-24 23:54:24 GMT; domain=.api.openai.com; HttpOnly; + - __cf_bm=ag5bmY5z6vTF_IKcj4m7ElEJQwLmTYjziW1tNojZH9U-1733859868-1.0.1.1-9GB6fsuRS4E08Ss199SiOE..koXUywi4OS4mOD0zj6m5y1e1s4BUGY5DOQxg3YQy9SyvDvo9I7_squiXUt0tZw; + path=/; expires=Tue, 10-Dec-24 20:14:28 GMT; domain=.api.openai.com; HttpOnly; Secure; SameSite=None - - _cfuvid=JT28sKsW8c619.li_Qj8b5CEv0QVhb4OxfDhw2Aft8Q-1731108264989-0.0.1.1-604800000; + - _cfuvid=biQ.Z.yDV53jhZ6_fSkBuJv_RcF3Ie8_kw3D3Nb81WU-1733859868146-0.0.1.1-604800000; path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked @@ -96,25 +95,25 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "964" + - "1450" openai-version: - "2020-10-01" strict-transport-security: - max-age=31536000; includeSubDomains; preload x-ratelimit-limit-requests: - - "3000" + - "10000" x-ratelimit-limit-tokens: - - "250000" + - "2000000" x-ratelimit-remaining-requests: - - "2998" + - "9999" x-ratelimit-remaining-tokens: - - "249472" + - "1999710" x-ratelimit-reset-requests: - - 27ms + - 6ms x-ratelimit-reset-tokens: - - 126ms + - 8ms x-request-id: - - req_bd4575cd1b4a7b53a973861d90b72214 + - req_db2829aa97ebbcfcfa11b8136e71e575 status: code: 200 message: OK diff --git a/tests/cassettes/TestSimpleAgent.test_agent_grad[gpt-4o-mini-2024-07-18].yaml b/tests/cassettes/TestSimpleAgent.test_agent_grad[gpt-4o-mini-2024-07-18].yaml index 10620d4c..cc1d9015 100644 --- a/tests/cassettes/TestSimpleAgent.test_agent_grad[gpt-4o-mini-2024-07-18].yaml +++ b/tests/cassettes/TestSimpleAgent.test_agent_grad[gpt-4o-mini-2024-07-18].yaml @@ -1,17 +1,11 @@ interactions: - request: body: - '{"messages": [{"role": "user", "content": "Write a 5 word story via print_story"}], - "model": "gpt-4o-mini-2024-07-18", "temperature": 0.1, "tool_choice": "required", - "tools": [{"type": "function", "function": {"name": "print_story", "description": - "Print a story.", "parameters": {"type": "object", "properties": {"story": {"description": - "Story to print.", "title": "Story", "type": "string"}}, "required": ["story"]}}}, - {"type": "function", "function": {"name": "cast_float", "description": "Cast - the input argument x to a float.", "parameters": {"type": "object", "properties": - {"x": {"title": "X", "type": "string"}}, "required": ["x"]}}}, {"type": "function", - "function": {"name": "cast_int", "description": "Cast the input argument x to - an integer.", "parameters": {"type": "object", "properties": {"x": {"title": - "X", "type": "number"}}, "required": ["x"]}}}]}' + '{"messages":[{"role":"user","content":"Write a 5 word story via print_story"}],"model":"gpt-4o-mini-2024-07-18","n":1,"temperature":0.1,"tool_choice":"required","tools":[{"type":"function","function":{"name":"print_story","description":"Print + a story.","parameters":{"type":"object","properties":{"story":{"description":"Story + to print.","title":"Story","type":"string"}},"required":["story"]}}},{"type":"function","function":{"name":"cast_float","description":"Cast + the input argument x to a float.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"string"}},"required":["x"]}}},{"type":"function","function":{"name":"cast_int","description":"Cast + the input argument x to an integer.","parameters":{"type":"object","properties":{"x":{"title":"X","type":"number"}},"required":["x"]}}}]}' headers: accept: - application/json @@ -20,13 +14,13 @@ interactions: connection: - keep-alive content-length: - - "867" + - "806" content-type: - application/json host: - api.openai.com user-agent: - - AsyncOpenAI/Python 1.54.3 + - AsyncOpenAI/Python 1.56.2 x-stainless-arch: - arm64 x-stainless-async: @@ -36,11 +30,11 @@ interactions: x-stainless-os: - MacOS x-stainless-package-version: - - 1.54.3 + - 1.56.2 x-stainless-raw-response: - "true" x-stainless-retry-count: - - "1" + - "0" x-stainless-runtime: - CPython x-stainless-runtime-version: @@ -50,20 +44,20 @@ interactions: response: body: string: !!binary | - H4sIAAAAAAAAA4xTTW+bQBC98ytWczYREKcm3HyJqqqtrNSt+uEKbXYHvPWyQ3aXKK7l/16BbcBu - IoUDQvPmvZl5M+wCxkBJyBiINfeiqnU4v/8ik7lO7pZfo01FOk3WT/Pm7+3i52IZwaRl0MMfFP7E - uhJU1Rq9InOAhUXusVWNZ9dxHKXJu7QDKpKoW1pZ+3BKYaWMCpMomYbRLIzTI3tNSqCDjP0KGGNs - 173bPo3EZ8hYNDlFKnSOlwhZn8QYWNJtBLhzynluPEwGUJDxaNrWTaP1CPBEOhdc66Hw4dmNvgez - uNb5N/8j/vBYLW6Kz+/v8dP27jld0uP0+6jeQXpbdw0VjRG9SSO8j2cXxRgDw6uOW1tlfO482e0F - nTHgtmwqNL5tHXYr6NJWkK3gIznPNridMElkWUEWn9AyTWKD8moFezjT2gcvff8e2WSxaBzXR/+O - 8X2/EE1lbenBXfgLhTLKrXOL3HVzju0OTtW6OtCcbRRqS1Xtc08bNK1sHB/XD8PVDWhyAj15rkes - 6xNwppdL9Fx1K++vTHCxRjlQh2vjjVQ0AoLR7P9385L2YX5lyrfID4AQWHuUeW1RKnE+8ZBmsf0p - X0vrXe4aBrd1Hqu8UKZE2x1Xd6F1Xtzc8jSeJrMCgn3wDwAA//8DAH4X1SggBAAA + H4sIAAAAAAAAAwAAAP//jFNNj9MwEL3nV1hzblb9WHZDbgg4IAGLkBbKUhQ59jR11/FYtgMbVf3v + q7htkpZFIocomjfvzcybyS5hDJSEnIHY8CBqq9M3cvoVl7M7H9Dq7cN3zO5U+eOdfpLYVjDpGFRu + UYQT60pQbTUGReYAC4c8YKc6u10sslevs5ubCNQkUXe0yob0mtJaGZXOp/PrdHqbzrIje0NKoIec + /UwYY2wX312fRuIT5Gw6OUVq9J5XCHmfxBg40l0EuPfKB24CTAZQkAloutZNo/UICES6EFzrofDh + 2Y2+B7O41oX4zO+3+v2fpW+X3x4+fPmU+fvGibejegfp1saG1o0RvUkjvI/nF8UYA8PryLVOmVD4 + QK69oDMG3FVNjSZ0rcNuBTFtBfkKPpIP7BHbCZNEjq3J4W90TGjyKK9WsIczrX3y0vevkU0O143n + +ujfMb7vF6Kpso5Kf+EvrJVRflM45D7OObY7OVWLdaA52yhYR7UNRaBHNJ3sbHZcPwxXN6DzExgo + cD1iLU7AmV4hMXAVV95fmeBig3KgDtfGG6loBCSj2f/u5iXtw/zKVP8jPwBCoA0oC+tQKnE+8ZDm + sPsp/5XWuxwbBt/6gHWxVqZCF48rXqgtypIvRIa30xKSffIMAAD//wMA+2fWYyAEAAA= headers: CF-Cache-Status: - DYNAMIC CF-RAY: - - 8df951176dbe2393-SJC + - 8effbac5ffef06ad-SJC Connection: - keep-alive Content-Encoding: @@ -71,9 +65,15 @@ interactions: Content-Type: - application/json Date: - - Fri, 08 Nov 2024 23:24:29 GMT + - Tue, 10 Dec 2024 19:44:27 GMT Server: - cloudflare + Set-Cookie: + - __cf_bm=C3dbW6zJBRY8Ys1xbYeud2RLlyCwWrInFVnA9iWonSk-1733859867-1.0.1.1-5lhE.LwvBpR3mP40cazViwFSprKDhNS5YV_RCYO89CtNv.WGTlUqQBdOduKwDRmvqh3tk8qwZb5NjWIKagwiiw; + path=/; expires=Tue, 10-Dec-24 20:14:27 GMT; domain=.api.openai.com; HttpOnly; + Secure; SameSite=None + - _cfuvid=B3mlsyUvxiiy3LKopH3ULUQ1oGGbfbGZe6GTMgcgc5A-1733859867079-0.0.1.1-604800000; + path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None Transfer-Encoding: - chunked X-Content-Type-Options: @@ -85,7 +85,7 @@ interactions: openai-organization: - future-house-xr4tdh openai-processing-ms: - - "527" + - "423" openai-version: - "2020-10-01" strict-transport-security: @@ -97,13 +97,13 @@ interactions: x-ratelimit-remaining-requests: - "29999" x-ratelimit-remaining-tokens: - - "149999974" + - "149999973" x-ratelimit-reset-requests: - 2ms x-ratelimit-reset-tokens: - 0s x-request-id: - - req_9794c5d3946c0779e2ae985662592f7c + - req_97968b8e2e2867ddebbdd0b6f8ee79ee status: code: 200 message: OK diff --git a/tests/conftest.py b/tests/conftest.py index ecb934f6..60ae7f4e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,8 +6,7 @@ import pytest import torch from aviary.core import DummyEnv - -from ldp.utils import configure_log_levels +from llmclient import configure_llm_logs from . import CASSETTES_DIR @@ -21,7 +20,7 @@ def fixture_dummy_env() -> DummyEnv: @pytest.fixture(scope="session", autouse=True) def _fixture_set_up_environment() -> None: - configure_log_levels() + configure_llm_logs() def set_seed(seed: int | None) -> None: diff --git a/tests/test_agents.py b/tests/test_agents.py index 0c34a2cd..1a488607 100644 --- a/tests/test_agents.py +++ b/tests/test_agents.py @@ -11,6 +11,7 @@ from aviary.core import DummyEnv, Message, Tool, ToolCall, ToolRequestMessage from aviary.message import EnvStateMessage from httpx import ASGITransport, AsyncClient +from llmclient import MultipleCompletionLLMModel as LLMModel from pydantic import BaseModel, Field from ldp.agent import ( @@ -34,7 +35,6 @@ ReActModuleSinglePrompt, ToolDescriptionMethods, ) -from ldp.llms import LLMModel from . import CILLMModelNames from .conftest import IN_GITHUB_ACTIONS, VCR_DEFAULT_MATCH_ON diff --git a/tests/test_embeddings.py b/tests/test_embeddings.py deleted file mode 100644 index 514a846f..00000000 --- a/tests/test_embeddings.py +++ /dev/null @@ -1,139 +0,0 @@ -import asyncio -from unittest.mock import MagicMock, patch - -import litellm -import numpy as np -import pytest -from litellm.caching import Cache, InMemoryCache -from pytest_subtests import SubTests - -from ldp.llms import ( - EmbeddingModel, - HybridEmbeddingModel, - LiteEmbeddingModel, - SparseEmbeddingModel, -) - - -class TestLiteEmbeddingModel: - @pytest.mark.asyncio - async def test_embed_texts(self) -> None: - texts = ["Hello", "World"] - batch_size = 1 # NOTE: this affects the mock below - model = LiteEmbeddingModel(name="stub", batch_size=1) - with patch( - "litellm.aembedding", - autospec=True, - side_effect=[ - MagicMock(data=[{"embedding": [1.0, 2.0]}]), - MagicMock(data=[{"embedding": [3.0, 4.0]}]), - ], - ) as mock_aembedding: - embeddings = await model.embed_texts(texts) - - assert np.allclose(embeddings[0], [1.0, 2.0]) - assert np.allclose(embeddings[1], [3.0, 4.0]) - assert mock_aembedding.call_count == len(texts) / batch_size - - @pytest.mark.parametrize( - ("model_name", "expected_dimensions"), - [ - ("stub", None), - ("text-embedding-ada-002", 1536), - ("text-embedding-3-small", 1536), - ], - ) - def test_model_dimension_inference( - self, model_name: str, expected_dimensions: int | None - ) -> None: - assert LiteEmbeddingModel(name=model_name).dimensions == expected_dimensions - - @pytest.mark.asyncio - async def test_can_change_dimension(self) -> None: - """We run this one for real, because want to test end to end.""" - stub_texts = ["test1", "test2"] - - model = LiteEmbeddingModel(name="text-embedding-3-small") - assert model.dimensions == 1536 - - model = LiteEmbeddingModel(name="text-embedding-3-small", dimensions=8) - assert model.dimensions == 8 - etext1, etext2 = await model.embed_texts(stub_texts) - assert len(etext1) == len(etext2) == 8 - - @pytest.mark.vcr - @pytest.mark.asyncio - async def test_caching(self) -> None: - model = LiteEmbeddingModel( - name="text-embedding-3-small", dimensions=8, embed_kwargs={"caching": True} - ) - # Make sure there is no existing cache. - with patch("litellm.cache", None): - # now create a new cache - litellm.cache = Cache() - assert isinstance(litellm.cache.cache, InMemoryCache) - assert len(litellm.cache.cache.cache_dict) == 0 - - _ = await model.embed_texts(["test1"]) - # need to do this to see the data propagated to cache - await asyncio.sleep(0.0) - - # Check the cache entry was made - assert len(litellm.cache.cache.cache_dict) == 1 - - -@pytest.mark.asyncio -async def test_sparse_embedding_model(subtests: SubTests): - with subtests.test("1D sparse"): - ndim = 1 - expected_output = [[1.0], [1.0]] - - model = SparseEmbeddingModel(dimensions=ndim) - result = await model.embed_texts(["test1", "test2"]) - - assert result == expected_output - - with subtests.test("large sparse"): - ndim = 1024 - - model = SparseEmbeddingModel(dimensions=ndim) - result = await model.embed_texts(["hello test", "go hello"]) - - assert max(result[0]) == max(result[1]) == 0.5 - - with subtests.test("default sparse"): - model = SparseEmbeddingModel() - result = await model.embed_texts(["test1 hello", "test2 hello"]) - - assert pytest.approx(sum(result[0]), abs=1e-6) == pytest.approx( - sum(result[1]), abs=1e-6 - ) - - -@pytest.mark.asyncio -async def test_hybrid_embedding_model() -> None: - hybrid_model = HybridEmbeddingModel( - models=[LiteEmbeddingModel(), SparseEmbeddingModel()] - ) - - # Mock the embedded documents of Lite and Sparse models - with ( - patch.object(LiteEmbeddingModel, "embed_texts", return_value=[[1.0], [2.0]]), - patch.object(SparseEmbeddingModel, "embed_texts", return_value=[[3.0], [4.0]]), - ): - result = await hybrid_model.embed_texts(["hello", "world"]) - assert result.tolist() == [[1.0, 3.0], [2.0, 4.0]] - - -@pytest.mark.asyncio -async def test_class_constructor() -> None: - original_name = "hybrid-text-embedding-3-small" - model = EmbeddingModel.from_name(original_name) - assert isinstance(model, HybridEmbeddingModel) - assert model.name == original_name - dense_model, sparse_model = model.models - assert dense_model.name == "text-embedding-3-small" - assert dense_model.dimensions == 1536 - assert sparse_model.name == "sparse" - assert sparse_model.dimensions == 256 - assert model.dimensions == 1792 diff --git a/tests/test_llms.py b/tests/test_llms.py deleted file mode 100644 index f9037718..00000000 --- a/tests/test_llms.py +++ /dev/null @@ -1,356 +0,0 @@ -from typing import Any, ClassVar -from unittest.mock import Mock - -import litellm -import numpy as np -import pytest -from aviary.core import DummyEnv, Message, Tool, ToolRequestMessage -from pydantic import BaseModel, Field - -from ldp.llms import ( - JSONSchemaValidationError, - LLMModel, - LLMResult, - MultipleCompletionLLMModel, - validate_json_completion, -) - -from . import CILLMModelNames - - -def test_json_schema_validation() -> None: - # Invalid JSON - mock_completion1 = Mock() - mock_completion1.choices = [Mock()] - mock_completion1.choices[0].message.content = "not a json" - # Invalid schema - mock_completion2 = Mock() - mock_completion2.choices = [Mock()] - mock_completion2.choices[0].message.content = '{"name": "John", "age": "nan"}' - # Valid schema - mock_completion3 = Mock() - mock_completion3.choices = [Mock()] - mock_completion3.choices[0].message.content = '{"name": "John", "age": 30}' - - class DummyModel(BaseModel): - name: str - age: int - - with pytest.raises(JSONSchemaValidationError): - validate_json_completion(mock_completion1, DummyModel) - with pytest.raises(JSONSchemaValidationError): - validate_json_completion(mock_completion2, DummyModel) - validate_json_completion(mock_completion3, DummyModel) - - -@pytest.mark.parametrize( - "model_name", ["gpt-3.5-turbo", CILLMModelNames.ANTHROPIC.value] -) -@pytest.mark.asyncio -async def test_achat(model_name: str) -> None: - model = LLMModel(name=model_name) - response = await model.achat( - messages=[ - Message(content="What are three things I should do today?"), - ] - ) - - assert len(response.choices) == 1 - - # Check we can iterate through the response - async for chunk in await model.achat_iter( - messages=[ - Message(content="What are three things I should do today?"), - ] - ): - assert len(chunk.choices) == 1 - - -@pytest.mark.parametrize( - "model_name", [CILLMModelNames.OPENAI.value, CILLMModelNames.ANTHROPIC.value] -) -@pytest.mark.flaky(reruns=3, only_on=[litellm.exceptions.APIConnectionError]) -@pytest.mark.asyncio -async def test_tools(dummy_env: DummyEnv, model_name: str) -> None: - model = LLMModel(name=model_name) - messages = [ - Message(content="What are three things I should do today?"), - ] - - def get_todo_list(n: int) -> str: - """Get todo list for today. - - Args: - n: number of items to return - """ - return "\n".join(["Go for a walk", "Read a book", "Call a friend"][:n]) - - tool = Tool.from_function(get_todo_list) - dummy_env.tools = [tool] - result = await model.call(messages, tools=dummy_env.tools) - assert result.completion_count > 0 - - # try specifying tool choice - result = await model.call(messages, tools=dummy_env.tools, tool_choice=tool) - assert result.completion_count > 0, "Tool choice failed to execute tool" - assert result.messages - (tool_request_message,) = result.messages - assert isinstance(tool_request_message, ToolRequestMessage) - - new_messages = await dummy_env.exec_tool_calls(tool_request_message) - (new_message,) = new_messages - assert new_message.content == "Go for a walk\nRead a book\nCall a friend" - assert new_message.tool_call_id == tool_request_message.tool_calls[0].id - - def get_todo_list_no_args() -> str: - """Get todo list for today.""" - return "\n".join(["Go for a walk", "Read a book", "Call a friend"]) - - tool = Tool.from_function(get_todo_list_no_args) - dummy_env.tools = [tool] - result = await model.call(messages, tools=dummy_env.tools) - assert result.completion_count > 0 - assert result.messages - (tool_request_message,) = result.messages - assert isinstance(tool_request_message, ToolRequestMessage) - - new_messages = await dummy_env.exec_tool_calls(tool_request_message) - (new_message,) = new_messages - assert new_message.content == "Go for a walk\nRead a book\nCall a friend" - assert new_message.tool_call_id == tool_request_message.tool_calls[0].id - - # ok now try with multiple functions - messages = [ - Message( - content=( - "What items will I have time to accomplish on my todo list today based" - " on my calendar?" - ) - ), - ] - - def get_calendar() -> str: - """Get text version of calendar for today.""" - return "9:00am Wake-up\n10:00pm Go to bed\n" - - tool2 = Tool.from_function(get_calendar) - dummy_env.tools = [tool, tool2] - result = await model.call(messages, tools=dummy_env.tools) - assert result.messages - (tool_request_message,) = result.messages - assert isinstance(tool_request_message, ToolRequestMessage) - new_messages = await dummy_env.exec_tool_calls(tool_request_message) - if model_name.startswith("claude"): - # Anthropic not always so smart - assert 1 <= len(new_messages) <= 2 - else: - assert len(new_messages) == 2 - - # ok now try continuation - I AM NOT SURE IF THIS IS VALID? - # TODO: - supported on openai, but not litellm - # messages = messages + result.messages + new_messages - # result = await model.call(messages) - - -class DummyOutputSchema(BaseModel): - name: str - age: int - - -class TestMultipleCompletionLLMModel: - NUM_COMPLETIONS: ClassVar[int] = 2 - DEFAULT_CONFIG: ClassVar[dict] = {"n": NUM_COMPLETIONS} - MODEL_CLS: ClassVar[type[MultipleCompletionLLMModel]] = MultipleCompletionLLMModel - - async def call_model( - self, model: MultipleCompletionLLMModel, *args, **kwargs - ) -> list[LLMResult]: - return await model.call(*args, **kwargs) - - @pytest.mark.vcr - @pytest.mark.parametrize("model_name", ["gpt-3.5-turbo"]) - @pytest.mark.asyncio - async def test_model(self, model_name: str) -> None: - # Make model_name an arg so that TestLLMModel can parametrize it - # only testing OpenAI, as other APIs don't support n>1 - model = self.MODEL_CLS(name=model_name, config=self.DEFAULT_CONFIG) - messages = [ - Message(role="system", content="Respond with single words."), - Message(content="Hello, how are you?"), - ] - results = await self.call_model(model, messages) - assert len(results) == self.NUM_COMPLETIONS - - for result in results: - assert result.prompt_count > 0 - assert result.completion_count > 0 - prompt_cost, completion_cost = result.prompt_and_completion_costs - assert prompt_cost > 0 - assert completion_cost > 0 - assert result.logprob is None or result.logprob <= 0 - - @pytest.mark.parametrize( - "model_name", [CILLMModelNames.ANTHROPIC.value, "gpt-3.5-turbo"] - ) - @pytest.mark.asyncio - async def test_streaming(self, model_name: str) -> None: - model = self.MODEL_CLS(name=model_name, config=self.DEFAULT_CONFIG) - messages = [ - Message(role="system", content="Respond with single words."), - Message(content="Hello, how are you?"), - ] - - def callback(_) -> None: - return - - with pytest.raises( - NotImplementedError, - match="Multiple completions with callbacks is not supported", - ): - await self.call_model(model, messages, [callback]) - - @pytest.mark.vcr - @pytest.mark.asyncio - async def test_parameterizing_tool_from_arg_union(self) -> None: - def play(move: int | None) -> None: - """Play one turn by choosing a move. - - Args: - move: Choose an integer to lose, choose None to win. - """ - - results = await self.call_model( - self.MODEL_CLS(name="gpt-3.5-turbo", config=self.DEFAULT_CONFIG), - messages=[Message(content="Please win.")], - tools=[Tool.from_function(play)], - ) - assert len(results) == self.NUM_COMPLETIONS - for result in results: - assert result.messages - assert len(result.messages) == 1 - assert isinstance(result.messages[0], ToolRequestMessage) - assert result.messages[0].tool_calls - assert result.messages[0].tool_calls[0].function.arguments["move"] is None - - @pytest.mark.asyncio - @pytest.mark.vcr - @pytest.mark.parametrize( - ("model_name", "output_type"), - [ - pytest.param("gpt-3.5-turbo", DummyOutputSchema, id="json-mode"), - pytest.param( - "gpt-4o", DummyOutputSchema.model_json_schema(), id="structured-outputs" - ), - ], - ) - async def test_output_schema( - self, model_name: str, output_type: type[BaseModel] | dict[str, Any] - ) -> None: - model = self.MODEL_CLS(name=model_name, config=self.DEFAULT_CONFIG) - messages = [ - Message( - content=( - "My name is Claude and I am 1 year old. What is my name and age?" - ) - ), - ] - results = await self.call_model(model, messages, output_type=output_type) - assert len(results) == self.NUM_COMPLETIONS - for result in results: - assert result.messages - assert len(result.messages) == 1 - assert result.messages[0].content - DummyOutputSchema.model_validate_json(result.messages[0].content) - - @pytest.mark.parametrize("model_name", [CILLMModelNames.OPENAI.value]) - @pytest.mark.asyncio - @pytest.mark.vcr - async def test_text_image_message(self, model_name: str) -> None: - model = self.MODEL_CLS(name=model_name, config=self.DEFAULT_CONFIG) - - # An RGB image of a red square - image = np.zeros((32, 32, 3), dtype=np.uint8) - image[:] = [255, 0, 0] # (255 red, 0 green, 0 blue) is maximum red in RGB - - results = await self.call_model( - model, - messages=[ - Message.create_message( - text="What color is this square? Respond only with the color name.", - image=image, - ) - ], - ) - assert len(results) == self.NUM_COMPLETIONS - for result in results: - assert result.messages is not None, ( - "Expected messages in result, but got None" - ) - assert result.messages[-1].content is not None, ( - "Expected content in message, but got None" - ) - assert "red" in result.messages[-1].content.lower() - - -class TestLLMModel(TestMultipleCompletionLLMModel): - NUM_COMPLETIONS: ClassVar[int] = 1 - DEFAULT_CONFIG: ClassVar[dict] = {} - MODEL_CLS: ClassVar[type[MultipleCompletionLLMModel]] = LLMModel - - async def call_model(self, model: LLMModel, *args, **kwargs) -> list[LLMResult]: # type: ignore[override] - return [await model.call(*args, **kwargs)] - - @pytest.mark.parametrize( - "model_name", [CILLMModelNames.ANTHROPIC.value, "gpt-3.5-turbo"] - ) - @pytest.mark.asyncio - @pytest.mark.vcr - async def test_model(self, model_name: str) -> None: - await super().test_model(model_name) - - @pytest.mark.vcr - @pytest.mark.parametrize( - "model_name", [CILLMModelNames.ANTHROPIC.value, "gpt-3.5-turbo"] - ) - @pytest.mark.asyncio - async def test_streaming(self, model_name: str) -> None: - model = LLMModel(name=model_name) - messages = [ - Message(role="system", content="Respond with single words."), - Message(content="Hello, how are you?"), - ] - content = [] - - def callback(s): - content.append(s) - - result = await model.call(messages, [callback]) - assert result.completion_count > 0 - assert content - - @pytest.mark.vcr - @pytest.mark.asyncio - async def test_parameterizing_tool_from_arg_union(self) -> None: - await super().test_parameterizing_tool_from_arg_union() - - @pytest.mark.vcr - @pytest.mark.asyncio - async def test_output_type_rejected_validation(self) -> None: - class InstructionList(BaseModel): - instructions: list[str] = Field(description="list of instructions") - - model = self.MODEL_CLS(name=CILLMModelNames.ANTHROPIC.value) - with pytest.raises(litellm.BadRequestError, match="anthropic"): - await model.call( - [Message(content="What are three things I should do today?")], - output_type=InstructionList, - ) - - @pytest.mark.parametrize( - "model_name", - [CILLMModelNames.ANTHROPIC.value, "gpt-4-turbo", CILLMModelNames.OPENAI.value], - ) - @pytest.mark.asyncio - @pytest.mark.vcr - async def test_text_image_message(self, model_name: str) -> None: - await super().test_text_image_message(model_name) diff --git a/tests/test_memory.py b/tests/test_memory.py index 5ec2d89e..8b9509f2 100644 --- a/tests/test_memory.py +++ b/tests/test_memory.py @@ -1,9 +1,9 @@ import pytest +from llmclient import EmbeddingModel from pytest_subtests import SubTests from ldp.graph import Memory from ldp.graph.memory import UIndexMemoryModel -from ldp.llms import EmbeddingModel @pytest.fixture(name="sample_memory") diff --git a/tests/test_ops.py b/tests/test_ops.py index 42b15089..b1585d4a 100644 --- a/tests/test_ops.py +++ b/tests/test_ops.py @@ -9,6 +9,7 @@ import pytest import tree from aviary.core import DummyEnv, Message, Tool, ToolRequestMessage +from llmclient import MultipleCompletionLLMModel as LLMModel from ldp.graph import ( CallID, @@ -28,7 +29,7 @@ ) from ldp.graph.gradient_estimators import straight_through_estimator as ste from ldp.graph.ops import GradInType, ResultOrValue, TOutput -from ldp.llms import LLMModel, append_to_sys +from ldp.llms.prompts import append_to_sys class StatefulFxnOp(FxnOp[TOutput]): @@ -151,9 +152,7 @@ async def generate_story() -> str: # LLMCallOp track cost using run context result = llm_op.ctx.get(op_result.call_id, "result") - prompt_cost, completion_cost = result.prompt_and_completion_costs - assert prompt_cost > 0 - assert completion_cost > 0 + assert result.cost > 0 # Environment tracks its internal costs assert env.total_cost > 0 diff --git a/tests/test_optimizer.py b/tests/test_optimizer.py index 3f48d456..67e1eb22 100644 --- a/tests/test_optimizer.py +++ b/tests/test_optimizer.py @@ -7,6 +7,7 @@ import tenacity import tree from aviary.core import Message +from llmclient import MultipleCompletionLLMModel as LLMModel from pydantic import BaseModel, Field, JsonValue from ldp.agent import Agent, MemoryAgent, ReActAgent @@ -38,7 +39,7 @@ straight_through_estimator as ste, ) from ldp.graph.ops import GradInType -from ldp.llms import LLMModel, append_to_sys +from ldp.llms.prompts import append_to_sys from tests import CILLMModelNames from tests.conftest import VCR_DEFAULT_MATCH_ON @@ -349,7 +350,7 @@ async def memory_factory( ) for mem_call_id, output_call_id, d_return, metadata in example_buffer ] - response = await memory_distiller.call( + response = await memory_distiller.call_single( messages=[ Message( content=LessonEntry.make_prompt(query_airesponse_dreturns) diff --git a/uv.lock b/uv.lock index d22fbd6f..ae486459 100644 --- a/uv.lock +++ b/uv.lock @@ -5,10 +5,14 @@ resolution-markers = [ "python_full_version < '3.12' and platform_python_implementation == 'PyPy' and sys_platform != 'linux'", "python_full_version < '3.12' and platform_python_implementation != 'PyPy' and sys_platform == 'linux'", "python_full_version < '3.12' and platform_python_implementation != 'PyPy' and sys_platform != 'linux'", - "python_full_version >= '3.12' and platform_python_implementation == 'PyPy' and sys_platform == 'linux'", - "python_full_version >= '3.12' and platform_python_implementation == 'PyPy' and sys_platform != 'linux'", - "python_full_version >= '3.12' and platform_python_implementation != 'PyPy' and sys_platform == 'linux'", - "python_full_version >= '3.12' and platform_python_implementation != 'PyPy' and sys_platform != 'linux'", + "python_full_version == '3.12.*' and platform_python_implementation == 'PyPy' and sys_platform == 'linux'", + "python_full_version >= '3.13' and platform_python_implementation == 'PyPy' and sys_platform == 'linux'", + "python_full_version == '3.12.*' and platform_python_implementation == 'PyPy' and sys_platform != 'linux'", + "python_full_version >= '3.13' and platform_python_implementation == 'PyPy' and sys_platform != 'linux'", + "python_full_version == '3.12.*' and platform_python_implementation != 'PyPy' and sys_platform == 'linux'", + "python_full_version >= '3.13' and platform_python_implementation != 'PyPy' and sys_platform == 'linux'", + "python_full_version == '3.12.*' and platform_python_implementation != 'PyPy' and sys_platform != 'linux'", + "python_full_version >= '3.13' and platform_python_implementation != 'PyPy' and sys_platform != 'linux'", ] [[package]] @@ -153,6 +157,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, ] +[[package]] +name = "async-timeout" +version = "4.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, +] + [[package]] name = "attrs" version = "24.2.0" @@ -403,6 +416,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c1/31/1ae946f11dfbd229222e6d6ad8e7bd1891d3d48bde5fbf7a0beb9491f8e3/contourpy-1.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:287ccc248c9e0d0566934e7d606201abd74761b5703d804ff3df8935f523d546", size = 236668 }, ] +[[package]] +name = "coredis" +version = "4.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout" }, + { name = "deprecated" }, + { name = "packaging" }, + { name = "pympler" }, + { name = "typing-extensions" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/0c/0f2fb1cedd224666ef08e898447bb9cf4d1e98a86b03119f1c6513093ddc/coredis-4.17.0.tar.gz", hash = "sha256:04e9976e71a42004dfe19a862c648b4047bf813e15184cddfd3cb37eb704b83f", size = 243157 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/2c/2335e476f0c0b33eea53c307169bcafe9c19a4b277738258eb80354ee90c/coredis-4.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f3050806b4854a6624e3c2efa013b540265d88e766f815963d447c116240d75d", size = 330690 }, + { url = "https://files.pythonhosted.org/packages/6a/b1/3c24a708b24f8e2566b1b91b64b4dc75f74633b875def19f2ac0fa03a0a0/coredis-4.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5f0f1044bdafc93f421e59e711da762c6c741ab76df0c12a42c447c1db1fcd75", size = 328051 }, + { url = "https://files.pythonhosted.org/packages/0f/a6/e5a8add1ae7b31240248528f669127e5fd347c69625a9b423965a5902302/coredis-4.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1befa7db121978fd0995151af5d15ce5e37a14847797c3fbd9403882f21b48c", size = 352651 }, + { url = "https://files.pythonhosted.org/packages/b8/d1/0ece1b888547ec26f4d33be30513cd44c77df25c9f943e7d3c20b49cc634/coredis-4.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52583dcef671c8d3a1cbecbf81cd630b1a72f946cf46601016c4f85d3f12a4a1", size = 355472 }, + { url = "https://files.pythonhosted.org/packages/00/c2/771bafa43c37d8c968804b6bb34063eb631b5d2377db31bca6d784131f48/coredis-4.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:845f5c0bb7012609a1f41f8308e5166c01f162599af33cb001bd2b0d6a4386f5", size = 358740 }, + { url = "https://files.pythonhosted.org/packages/fb/d3/90846efc003d692c46f2988ddaffaac47f2c95f378102dad490e911de157/coredis-4.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e3638c9a894ac7d0a04fa14515f24d0f717c431266ee0ac612ddb3a142862258", size = 330509 }, + { url = "https://files.pythonhosted.org/packages/4c/2d/1f97441d377b457831bd9327dbdaa29888effa2edf6318cb4138a425538f/coredis-4.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73cb260bf96eacb4e455c300b5e41382bc52d9a2125f3f7e55657662a627e0cb", size = 327735 }, + { url = "https://files.pythonhosted.org/packages/3a/3f/1dcd57f6df67b7a20b1c27abcf768cf6789be5f33d173739f482d672e9d1/coredis-4.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9421423bb109eb62b7595e1d0c84d8c9399bf160826ee478b6b7771bf6ad831e", size = 353755 }, + { url = "https://files.pythonhosted.org/packages/38/24/de68bdd4b3549a8a05674f0952e646d45afd15453543e0e679dc6899174c/coredis-4.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a74abdeda89ff5ea40d0da771d2871148b64b2f1c758f11485397adc1928b08e", size = 357309 }, + { url = "https://files.pythonhosted.org/packages/ab/66/2bd9f9e1c10b307caf8f4e77527c620a0320291aa83a9e0e98e8df5a326c/coredis-4.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ddad826c5bc91f05e5fe36435086cdbe51019b2f4f0faf96d40250823548fee", size = 360856 }, + { url = "https://files.pythonhosted.org/packages/08/1c/7249845c0f6105290d70d90c9ad48b550f5bcb989766819d38aa0f784aec/coredis-4.17.0-py3-none-any.whl", hash = "sha256:a8254fcc746efd72990d565d87e5399646ad737b7a61d86ef129df846e86b0d3", size = 239667 }, +] + [[package]] name = "coverage" version = "7.6.9" @@ -507,6 +547,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, ] +[[package]] +name = "deprecated" +version = "1.2.15" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/a3/53e7d78a6850ffdd394d7048a31a6f14e44900adedf190f9a165f6b69439/deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d", size = 2977612 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/8f/c7f227eb42cfeaddce3eb0c96c60cbca37797fa7b34f8e1aeadf6c5c0983/Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320", size = 9941 }, +] + [[package]] name = "dicttoxml" version = "1.7.16" @@ -632,6 +684,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/b3/7e4df40e585df024fac2f80d1a2d579c854ac37109675db2b0cc22c0bb9e/fastapi-0.115.6-py3-none-any.whl", hash = "sha256:e9240b29e36fa8f4bb7290316988e90c381e5092e0cbe84e7818cc3713bcf305", size = 94843 }, ] +[[package]] +name = "fh-llm-client" +version = "0.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coredis" }, + { name = "fhaviary" }, + { name = "limits" }, + { name = "litellm" }, + { name = "pydantic" }, + { name = "tiktoken" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/ba/0395955b6dc64bdfe5724f0b5d8a8e8c916454d1fa0000c0686cd8432d4a/fh_llm_client-0.0.6.tar.gz", hash = "sha256:71ffa711f1bfe2c16b422ee4762a668e443c8351c485924ceb6745db4359dab0", size = 195993 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/30/de/ee766cd71dec5a12cbb0c7bc8d8a90764bde730376ddee466902f239e756/fh_llm_client-0.0.6-py3-none-any.whl", hash = "sha256:7c20364b465db784c0320132c216cadd933fb56972c7bdff3996bd4a14769926", size = 31801 }, +] + [[package]] name = "fhaviary" version = "0.11.0" @@ -1112,14 +1182,14 @@ wheels = [ [[package]] name = "ldp" -version = "0.14.6.dev9+g261607d" +version = "0.14.4.dev26+gc677c6b.d20241211" source = { editable = "." } dependencies = [ { name = "aiofiles" }, { name = "dm-tree" }, + { name = "fh-llm-client" }, { name = "fhaviary" }, { name = "httpx" }, - { name = "litellm" }, { name = "networkx", extra = ["default"] }, { name = "numpy" }, { name = "pydantic" }, @@ -1184,10 +1254,62 @@ visualization = [ [package.dev-dependencies] codeflash = [ { name = "codeflash" }, - { name = "ldp", extra = ["dev"] }, + { name = "fastapi" }, + { name = "fhaviary", extra = ["xml"] }, + { name = "ipython" }, + { name = "litellm" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pydantic" }, + { name = "pydot" }, + { name = "pylint" }, + { name = "pylint-pydantic" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-mock" }, + { name = "pytest-recording" }, + { name = "pytest-rerunfailures" }, + { name = "pytest-subtests" }, + { name = "pytest-sugar" }, + { name = "pytest-timer", extra = ["colorama"] }, + { name = "pytest-xdist" }, + { name = "refurb" }, + { name = "rich" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "types-aiofiles" }, + { name = "types-tqdm" }, + { name = "vcrpy" }, + { name = "wandb" }, ] dev = [ - { name = "ldp", extra = ["dev"] }, + { name = "fastapi" }, + { name = "fhaviary", extra = ["xml"] }, + { name = "ipython" }, + { name = "litellm" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pydantic" }, + { name = "pydot" }, + { name = "pylint" }, + { name = "pylint-pydantic" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-mock" }, + { name = "pytest-recording" }, + { name = "pytest-rerunfailures" }, + { name = "pytest-subtests" }, + { name = "pytest-sugar" }, + { name = "pytest-timer", extra = ["colorama"] }, + { name = "pytest-xdist" }, + { name = "refurb" }, + { name = "rich" }, + { name = "torch" }, + { name = "tqdm" }, + { name = "types-aiofiles" }, + { name = "types-tqdm" }, + { name = "vcrpy" }, + { name = "wandb" }, ] [package.metadata] @@ -1195,13 +1317,13 @@ requires-dist = [ { name = "aiofiles" }, { name = "dm-tree" }, { name = "fastapi", marker = "extra == 'server'", specifier = ">=0.109" }, + { name = "fh-llm-client" }, { name = "fhaviary", specifier = ">=0.8.2" }, { name = "fhaviary", extras = ["xml"], marker = "extra == 'dev'" }, { name = "httpx" }, { name = "ipython", marker = "extra == 'dev'", specifier = ">=8" }, { name = "ldp", extras = ["monitor", "nn", "rich", "server", "typing", "visualization"], marker = "extra == 'dev'" }, - { name = "litellm", specifier = ">=1.52.15" }, - { name = "litellm", marker = "extra == 'dev'", specifier = "!=1.49.4,!=1.49.5,!=1.49.6" }, + { name = "litellm", marker = "extra == 'dev'", specifier = ">=1.52.15" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.8" }, { name = "networkx", extras = ["default"], specifier = "~=3.4" }, { name = "numpy", specifier = ">=1.20" }, @@ -1277,6 +1399,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/53/54/3bf26fc2cd9f3b5a1ce4f574ddd1238b96d6e4a9c1c0fccd0c10f7e84e59/libcst-1.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:b5a0d3c632aa2b21c5fa145e4e8dbf86f45c9b37a64c0b7221a5a45caf58915a", size = 2032277 }, ] +[[package]] +name = "limits" +version = "3.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "deprecated" }, + { name = "packaging" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/2f/686912cae32c690ced2cda741965d717b4d376679d7202502000972a5443/limits-3.14.1.tar.gz", hash = "sha256:cad16a9b3cf3924e27da48e78bdab33ef312ecb7194fdb50e509cc8111c8d0bb", size = 70368 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/5d/150c6f0b3a9e20acd785a6f27e1b2959b136483d39b2ac0a6ae87d3b3f92/limits-3.14.1-py3-none-any.whl", hash = "sha256:051aca02da56e6932599a25cb8e70543959294f5d587d57bcd7e38df234e697b", size = 45651 }, +] + [[package]] name = "litellm" version = "1.53.3" @@ -1809,7 +1945,7 @@ wheels = [ [[package]] name = "openai" -version = "1.57.0" +version = "1.56.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1821,9 +1957,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fa/64/4acd9331b3c0e1069f36692d4c29d2c8deea6649a1e150f45a096f91b339/openai-1.57.0.tar.gz", hash = "sha256:76f91971c4bdbd78380c9970581075e0337b5d497c2fbf7b5255078f4b31abf9", size = 315514 } +sdist = { url = "https://files.pythonhosted.org/packages/e1/97/302669f5888d1adf8ce0e93f1e5b2337b6c9db47d9877bd344a29db314be/openai-1.56.2.tar.gz", hash = "sha256:17312af69bc7670d4048f98ab5849f8784d98c39ac64fcde19406e3774a0c1e5", size = 315404 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/2d/eb8539a2d5809eb78508633a8faa8df7745960e99af0388310c43b2c0be1/openai-1.57.0-py3-none-any.whl", hash = "sha256:972e36960b821797952da3dc4532f486c28e28a2a332d7d0c5407f242e9d9c39", size = 389854 }, + { url = "https://files.pythonhosted.org/packages/23/36/c60fffa518d82952335e2ef4a6b93b0427c57eb49469879dee1cbe59d551/openai-1.56.2-py3-none-any.whl", hash = "sha256:82d0c48f9504e04c7797e9b799dcf7f49a246d99b6cbfd90f3193ea80815b69e", size = 389854 }, ] [[package]] @@ -2132,16 +2268,16 @@ wheels = [ [[package]] name = "pydantic" -version = "2.10.3" +version = "2.10.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/45/0f/27908242621b14e649a84e62b133de45f84c255eecb350ab02979844a788/pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9", size = 786486 } +sdist = { url = "https://files.pythonhosted.org/packages/c4/bd/7fc610993f616d2398958d0028d15eaf53bde5f80cb2edb7aa4f1feaf3a7/pydantic-2.10.1.tar.gz", hash = "sha256:a4daca2dc0aa429555e0656d6bf94873a7dc5f54ee42b1f5873d666fb3f35560", size = 783717 } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/51/72c18c55cf2f46ff4f91ebcc8f75aa30f7305f3d726be3f4ebffb4ae972b/pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d", size = 456997 }, + { url = "https://files.pythonhosted.org/packages/e0/fc/fda48d347bd50a788dd2a0f318a52160f911b86fc2d8b4c86f4d7c9bceea/pydantic-2.10.1-py3-none-any.whl", hash = "sha256:a8d20db84de64cf4a7d59e899c2caf0fe9d660c7cfc482528e7020d7dd189a7e", size = 455329 }, ] [[package]] @@ -2274,6 +2410,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1c/00/adca2ef68fde34bf6b84870cd3d0e2d3f8e116263628af99e00c4e393111/pylint_pydantic-0.3.4-py3-none-any.whl", hash = "sha256:f82fdf6b05045102fef2bd8b553a118aadf80155116f374a76eb201c47160a68", size = 16122 }, ] +[[package]] +name = "pympler" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywin32", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dd/37/c384631908029676d8e7213dd956bb686af303a80db7afbc9be36bc49495/pympler-1.1.tar.gz", hash = "sha256:1eaa867cb8992c218430f1708fdaccda53df064144d1c5656b1e6f1ee6000424", size = 179954 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/4f/a6a2e2b202d7fd97eadfe90979845b8706676b41cbd3b42ba75adf329d1f/Pympler-1.1-py3-none-any.whl", hash = "sha256:5b223d6027d0619584116a0cbc28e8d2e378f7a79c1e5e024f9ff3b673c58506", size = 165766 }, +] + [[package]] name = "pyparsing" version = "3.2.0" @@ -2447,6 +2595,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, ] +[[package]] +name = "pywin32" +version = "308" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/e2/02652007469263fe1466e98439831d65d4ca80ea1a2df29abecedf7e47b7/pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a", size = 5928156 }, + { url = "https://files.pythonhosted.org/packages/48/ef/f4fb45e2196bc7ffe09cad0542d9aff66b0e33f6c0954b43e49c33cad7bd/pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b", size = 6559559 }, + { url = "https://files.pythonhosted.org/packages/79/ef/68bb6aa865c5c9b11a35771329e95917b5559845bd75b65549407f9fc6b4/pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6", size = 7972495 }, + { url = "https://files.pythonhosted.org/packages/00/7c/d00d6bdd96de4344e06c4afbf218bc86b54436a94c01c71a8701f613aa56/pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897", size = 5939729 }, + { url = "https://files.pythonhosted.org/packages/21/27/0c8811fbc3ca188f93b5354e7c286eb91f80a53afa4e11007ef661afa746/pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47", size = 6543015 }, + { url = "https://files.pythonhosted.org/packages/9d/0f/d40f8373608caed2255781a3ad9a51d03a594a1248cd632d6a298daca693/pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091", size = 7976033 }, + { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 }, + { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 }, + { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, +] + [[package]] name = "pyyaml" version = "6.0.2" @@ -3058,7 +3222,7 @@ name = "triton" version = "3.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "filelock" }, + { name = "filelock", marker = "python_full_version < '3.13'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/86/17/d9a5cf4fcf46291856d1e90762e36cbabd2a56c7265da0d1d9508c8e3943/triton-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f34f6e7885d1bf0eaaf7ba875a5f0ce6f3c13ba98f9503651c1e6dc6757ed5c", size = 209506424 },