More robust log step class, and new examples
This commit is contained in:
		
							parent
							
								
									146ee3dd32
								
							
						
					
					
						commit
						a830b1721a
					
				|  | @ -156,7 +156,7 @@ class AgentImage(AgentType, ImageType): | |||
|             directory = tempfile.mkdtemp() | ||||
|             self._path = os.path.join(directory, str(uuid.uuid4()) + ".png") | ||||
| 
 | ||||
|             img.save(self._path) | ||||
|             img.save(self._path, format="png") | ||||
| 
 | ||||
|             return self._path | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										377
									
								
								agents/agents.py
								
								
								
								
							
							
						
						
									
										377
									
								
								agents/agents.py
								
								
								
								
							|  | @ -15,16 +15,14 @@ | |||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
| import json | ||||
| import logging | ||||
| import re | ||||
| import time | ||||
| from typing import Any, Callable, Dict, List, Optional, Tuple, Union | ||||
| import rich | ||||
| from rich import markdown as rich_markdown | ||||
| from dataclasses import dataclass | ||||
| 
 | ||||
| from transformers.utils import is_torch_available | ||||
| import logging | ||||
| from .utils import console | ||||
| from .utils import console, parse_code_blob, parse_json_tool_call | ||||
| from .agent_types import AgentAudio, AgentImage | ||||
| from .default_tools import BASE_PYTHON_TOOLS, FinalAnswerTool, setup_default_tools | ||||
| from .llm_engine import HfApiEngine, MessageRole | ||||
|  | @ -47,200 +45,15 @@ from .tools import ( | |||
|     Tool, | ||||
|     get_tool_description_with_args, | ||||
|     load_tool, | ||||
|     Toolbox, | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| def parse_json_blob(json_blob: str) -> Dict[str, str]: | ||||
|     try: | ||||
|         first_accolade_index = json_blob.find("{") | ||||
|         last_accolade_index = [a.start() for a in list(re.finditer("}", json_blob))][-1] | ||||
|         json_blob = json_blob[first_accolade_index : last_accolade_index + 1].replace('\\"', "'") | ||||
|         json_data = json.loads(json_blob, strict=False) | ||||
|         return json_data | ||||
|     except json.JSONDecodeError as e: | ||||
|         place = e.pos | ||||
|         if json_blob[place - 1 : place + 2] == "},\n": | ||||
|             raise ValueError( | ||||
|                 "JSON is invalid: you probably tried to provide multiple tool calls in one action. PROVIDE ONLY ONE TOOL CALL." | ||||
|             ) | ||||
|         raise ValueError( | ||||
|             f"The JSON blob you used is invalid due to the following error: {e}.\n" | ||||
|             f"JSON blob was: {json_blob}, decoding failed on that specific part of the blob:\n" | ||||
|             f"'{json_blob[place-4:place+5]}'." | ||||
|         ) | ||||
|     except Exception as e: | ||||
|         raise ValueError(f"Error in parsing the JSON blob: {e}") | ||||
| 
 | ||||
| 
 | ||||
| def parse_code_blob(code_blob: str) -> str: | ||||
|     try: | ||||
|         pattern = r"```(?:py|python)?\n(.*?)\n```" | ||||
|         match = re.search(pattern, code_blob, re.DOTALL) | ||||
|         return match.group(1).strip() | ||||
|     except Exception as e: | ||||
|         raise ValueError( | ||||
|             f""" | ||||
| The code blob you used is invalid: due to the following error: {e} | ||||
| This means that the regex pattern {pattern} was not respected: make sure to include code with the correct pattern, for instance: | ||||
| Thoughts: Your thoughts | ||||
| Code: | ||||
| ```py | ||||
| # Your python code here | ||||
| ```<end_action>""" | ||||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| def parse_json_tool_call(json_blob: str) -> Tuple[str, Dict[str, str]]: | ||||
|     json_blob = json_blob.replace("```json", "").replace("```", "") | ||||
|     tool_call = parse_json_blob(json_blob) | ||||
|     if "action" in tool_call and "action_input" in tool_call: | ||||
|         return tool_call["action"], tool_call["action_input"] | ||||
|     elif "action" in tool_call: | ||||
|         return tool_call["action"], None | ||||
|     else: | ||||
|         missing_keys = [key for key in ['action', 'action_input'] if key not in tool_call] | ||||
|         error_msg = f"Missing keys: {missing_keys} in blob {tool_call}" | ||||
|         console.print(f"[bold red]{error_msg}[/bold red]") | ||||
|         raise ValueError(error_msg) | ||||
| 
 | ||||
| 
 | ||||
| def parse_text_tool_call(text: str) -> Tuple[str, Union[str, Dict[str, str]]]: | ||||
|     """ | ||||
|     Expects a text in the format: 'Action:', 'Action input:', 'Observation:'. 'Action input:' contains a json string with input arguments. | ||||
|     """ | ||||
|     try: | ||||
|         if "Observation:" in text: | ||||
|             text = text.split("Observation:")[0] | ||||
|         if "Action:" in text: | ||||
|             text = text.split("Action:")[1] | ||||
|         tool_name, tool_input = text.split("Action input:") | ||||
|         if "{" in tool_input: | ||||
|             tool_input = parse_json_blob(tool_input) | ||||
|         else: | ||||
|             tool_input = tool_input.strip().replace('"', "") | ||||
|         return tool_name.strip().replace('"', "").replace("\\", ""), tool_input | ||||
|     except Exception as e: | ||||
|         raise ValueError( | ||||
|             f"Error in parsing the text tool call: {e}. Be sure to provide the correct format. DO NOT repeat your previous incorrect tool call." | ||||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| def to_text(input: Union[List[Dict[str, str]], Dict[str, str], str]) -> str: | ||||
|     if isinstance(input, list): | ||||
|         return "\n".join([m["content"] for m in input]) | ||||
|     elif isinstance(input, dict): | ||||
|         return input["content"] | ||||
|     else: | ||||
|         return input | ||||
| LENGTH_TRUNCATE_REPORTS = 10000 | ||||
| 
 | ||||
| 
 | ||||
| HUGGINGFACE_DEFAULT_TOOLS = {} | ||||
| _tools_are_initialized = False | ||||
| 
 | ||||
| 
 | ||||
| class Toolbox: | ||||
|     """ | ||||
|     The toolbox contains all tools that the agent can perform operations with, as well as a few methods to | ||||
|     manage them. | ||||
| 
 | ||||
|     Args: | ||||
|         tools (`List[Tool]`): | ||||
|             The list of tools to instantiate the toolbox with | ||||
|         add_base_tools (`bool`, defaults to `False`, *optional*, defaults to `False`): | ||||
|             Whether to add the tools available within `transformers` to the toolbox. | ||||
|     """ | ||||
| 
 | ||||
|     def __init__(self, tools: List[Tool], add_base_tools: bool = False): | ||||
|         self._tools = {tool.name: tool for tool in tools} | ||||
|         if add_base_tools: | ||||
|             self.add_base_tools() | ||||
|         # self._load_tools_if_needed() | ||||
| 
 | ||||
|     def add_base_tools(self, add_python_interpreter: bool = False): | ||||
|         global _tools_are_initialized | ||||
|         global HUGGINGFACE_DEFAULT_TOOLS | ||||
|         if not _tools_are_initialized: | ||||
|             HUGGINGFACE_DEFAULT_TOOLS = setup_default_tools() | ||||
|             _tools_are_initialized = True | ||||
|         for tool in HUGGINGFACE_DEFAULT_TOOLS.values(): | ||||
|             if tool.name != "python_interpreter" or add_python_interpreter: | ||||
|                 self.add_tool(tool) | ||||
|         # self._load_tools_if_needed() | ||||
| 
 | ||||
|     @property | ||||
|     def tools(self) -> Dict[str, Tool]: | ||||
|         """Get all tools currently in the toolbox""" | ||||
|         return self._tools | ||||
| 
 | ||||
|     def show_tool_descriptions(self, tool_description_template: str = None) -> str: | ||||
|         """ | ||||
|         Returns the description of all tools in the toolbox | ||||
| 
 | ||||
|         Args: | ||||
|             tool_description_template (`str`, *optional*): | ||||
|                 The template to use to describe the tools. If not provided, the default template will be used. | ||||
|         """ | ||||
|         return "\n".join( | ||||
|             [get_tool_description_with_args(tool, tool_description_template) for tool in self._tools.values()] | ||||
|         ) | ||||
| 
 | ||||
|     def add_tool(self, tool: Tool): | ||||
|         """ | ||||
|         Adds a tool to the toolbox | ||||
| 
 | ||||
|         Args: | ||||
|             tool (`Tool`): | ||||
|                 The tool to add to the toolbox. | ||||
|         """ | ||||
|         if tool.name in self._tools: | ||||
|             raise KeyError(f"Error: tool '{tool.name}' already exists in the toolbox.") | ||||
|         self._tools[tool.name] = tool | ||||
| 
 | ||||
|     def remove_tool(self, tool_name: str): | ||||
|         """ | ||||
|         Removes a tool from the toolbox | ||||
| 
 | ||||
|         Args: | ||||
|             tool_name (`str`): | ||||
|                 The tool to remove from the toolbox. | ||||
|         """ | ||||
|         if tool_name not in self._tools: | ||||
|             raise KeyError( | ||||
|                 f"Error: tool {tool_name} not found in toolbox for removal, should be instead one of {list(self._tools.keys())}." | ||||
|             ) | ||||
|         del self._tools[tool_name] | ||||
| 
 | ||||
|     def update_tool(self, tool: Tool): | ||||
|         """ | ||||
|         Updates a tool in the toolbox according to its name. | ||||
| 
 | ||||
|         Args: | ||||
|             tool (`Tool`): | ||||
|                 The tool to update to the toolbox. | ||||
|         """ | ||||
|         if tool.name not in self._tools: | ||||
|             raise KeyError( | ||||
|                 f"Error: tool {tool.name} not found in toolbox for update, should be instead one of {list(self._tools.keys())}." | ||||
|             ) | ||||
|         self._tools[tool.name] = tool | ||||
| 
 | ||||
|     def clear_toolbox(self): | ||||
|         """Clears the toolbox""" | ||||
|         self._tools = {} | ||||
| 
 | ||||
|     # def _load_tools_if_needed(self): | ||||
|     #     for name, tool in self._tools.items(): | ||||
|     #         if not isinstance(tool, Tool): | ||||
|     #             task_or_repo_id = tool.task if tool.repo_id is None else tool.repo_id | ||||
|     #             self._tools[name] = load_tool(task_or_repo_id) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         toolbox_description = "Toolbox contents:\n" | ||||
|         for tool in self._tools.values(): | ||||
|             toolbox_description += f"\t{tool.name}: {tool.description}\n" | ||||
|         return toolbox_description | ||||
| 
 | ||||
| 
 | ||||
| class AgentError(Exception): | ||||
|     """Base class for other agent-related exceptions""" | ||||
| 
 | ||||
|  | @ -274,6 +87,25 @@ class AgentGenerationError(AgentError): | |||
| 
 | ||||
|     pass | ||||
| 
 | ||||
| @dataclass | ||||
| class ActionStep: | ||||
|     tool_call: str | None = None | ||||
|     start_time: float | None = None | ||||
|     end_time: float | None = None | ||||
|     iteration: int | None = None | ||||
|     final_answer: Any = None | ||||
|     error: AgentError | None = None | ||||
|     step_duration: float | None = None | ||||
| 
 | ||||
| @dataclass | ||||
| class PlanningStep: | ||||
|     plan: str | ||||
|     facts: str | ||||
| 
 | ||||
| @dataclass | ||||
| class TaskStep: | ||||
|     system_prompt: str | ||||
|     task: str | ||||
| 
 | ||||
| def format_prompt_with_tools(toolbox: Toolbox, prompt_template: str, tool_description_template: str) -> str: | ||||
|     tool_descriptions = toolbox.show_tool_descriptions(tool_description_template) | ||||
|  | @ -392,7 +224,7 @@ class Agent: | |||
|             self.system_prompt = format_prompt_with_imports( | ||||
|                 self.system_prompt, list(set(LIST_SAFE_MODULES) | set(self.authorized_imports)) | ||||
|             ) | ||||
|         self.logs = [{"system_prompt": self.system_prompt, "task": self.task}] | ||||
|         self.logs = [TaskStep(system_prompt=self.system_prompt, task=self.task)] | ||||
|         console.rule("New task", characters='=') | ||||
|         console.print(self.task) | ||||
| 
 | ||||
|  | @ -401,55 +233,58 @@ class Agent: | |||
|         Reads past llm_outputs, actions, and observations or errors from the logs into a series of messages | ||||
|         that can be used as input to the LLM. | ||||
|         """ | ||||
|         prompt_message = {"role": MessageRole.SYSTEM, "content": self.logs[0]["system_prompt"]} | ||||
|         prompt_message = {"role": MessageRole.SYSTEM, "content": self.logs[0].system_prompt} | ||||
|         task_message = { | ||||
|             "role": MessageRole.USER, | ||||
|             "content": "Task: " + self.logs[0]["task"], | ||||
|             "content": "Task: " + self.logs[0].task, | ||||
|         } | ||||
|         if summary_mode: | ||||
|             memory = [task_message] | ||||
|         else: | ||||
|             memory = [prompt_message, task_message] | ||||
|         for i, step_log in enumerate(self.logs[1:]): | ||||
|             if "llm_output" in step_log and not summary_mode: | ||||
|                 thought_message = {"role": MessageRole.ASSISTANT, "content": step_log["llm_output"].strip()} | ||||
|                 memory.append(thought_message) | ||||
|             if "facts" in step_log: | ||||
| 
 | ||||
|             if isinstance(step_log, PlanningStep): | ||||
|                 thought_message = { | ||||
|                     "role": MessageRole.ASSISTANT, | ||||
|                     "content": "[FACTS LIST]:\n" + step_log["facts"].strip(), | ||||
|                     "content": "[FACTS LIST]:\n" + step_log.facts.strip(), | ||||
|                 } | ||||
|                 memory.append(thought_message) | ||||
| 
 | ||||
|             if "plan" in step_log and not summary_mode: | ||||
|                 thought_message = {"role": MessageRole.ASSISTANT, "content": "[PLAN]:\n" + step_log["plan"].strip()} | ||||
|                 memory.append(thought_message) | ||||
|                 if not summary_mode: | ||||
|                     thought_message = {"role": MessageRole.ASSISTANT, "content": "[PLAN]:\n" + step_log.plan.strip()} | ||||
|                     memory.append(thought_message) | ||||
| 
 | ||||
|             if "tool_call" in step_log and summary_mode: | ||||
|                 tool_call_message = { | ||||
|                     "role": MessageRole.ASSISTANT, | ||||
|                     "content": f"[STEP {i} TOOL CALL]: " + str(step_log["tool_call"]).strip(), | ||||
|                 } | ||||
|                 memory.append(tool_call_message) | ||||
| 
 | ||||
|             if "task" in step_log: | ||||
|                 tool_call_message = { | ||||
|             elif isinstance(step_log, TaskStep): | ||||
|                 task_message = { | ||||
|                     "role": MessageRole.USER, | ||||
|                     "content": "New task:\n" + step_log["task"], | ||||
|                     "content": "New task:\n" + step_log.task, | ||||
|                 } | ||||
|                 memory.append(tool_call_message) | ||||
|                 memory.append(task_message) | ||||
| 
 | ||||
|             if "error" in step_log or "observation" in step_log: | ||||
|                 if "error" in step_log: | ||||
|                     message_content = ( | ||||
|                         f"[OUTPUT OF STEP {i}] -> Error:\n" | ||||
|                         + str(step_log["error"]) | ||||
|                         + "\nNow let's retry: take care not to repeat previous errors! If you have retried several times, try a completely different approach.\n" | ||||
|                     ) | ||||
|                 elif "observation" in step_log: | ||||
|                     message_content = f"[OUTPUT OF STEP {i}] -> Observation:\n{step_log['observation']}" | ||||
|                 tool_response_message = {"role": MessageRole.TOOL_RESPONSE, "content": message_content} | ||||
|                 memory.append(tool_response_message) | ||||
|             elif isinstance(step_log, ActionStep): | ||||
|                 if step_log.llm_output is not None and not summary_mode: | ||||
|                     thought_message = {"role": MessageRole.ASSISTANT, "content": step_log.llm_output.strip()} | ||||
|                     memory.append(thought_message) | ||||
| 
 | ||||
|                 if step_log.tool_call is not None and summary_mode: | ||||
|                     tool_call_message = { | ||||
|                         "role": MessageRole.ASSISTANT, | ||||
|                         "content": f"[STEP {i} TOOL CALL]: " + str(step_log.tool_call).strip(), | ||||
|                     } | ||||
|                     memory.append(tool_call_message) | ||||
| 
 | ||||
|                 if step_log.error is not None or step_log.observation is not None: | ||||
|                     if step_log.error is not None: | ||||
|                         message_content = ( | ||||
|                             f"[OUTPUT OF STEP {i}] -> Error:\n" | ||||
|                             + str(step_log.error) | ||||
|                             + "\nNow let's retry: take care not to repeat previous errors! If you have retried several times, try a completely different approach.\n" | ||||
|                         ) | ||||
|                     elif step_log.observation is not None: | ||||
|                         message_content = f"[OUTPUT OF STEP {i}] -> Observation:\n{step_log.observation}" | ||||
|                     tool_response_message = {"role": MessageRole.TOOL_RESPONSE, "content": message_content} | ||||
|                     memory.append(tool_response_message) | ||||
| 
 | ||||
|         return memory | ||||
| 
 | ||||
|  | @ -742,7 +577,7 @@ class ReactAgent(Agent): | |||
|         if reset: | ||||
|             self.initialize_for_run() | ||||
|         else: | ||||
|             self.logs.append({"task": task}) | ||||
|             self.logs.append(TaskStep(task=task)) | ||||
|         if stream: | ||||
|             return self.stream_run(task) | ||||
|         else: | ||||
|  | @ -756,31 +591,31 @@ class ReactAgent(Agent): | |||
|         iteration = 0 | ||||
|         while final_answer is None and iteration < self.max_iterations: | ||||
|             step_start_time = time.time() | ||||
|             step_log_entry = {"iteration": iteration, "start_time": step_start_time} | ||||
|             step_log = ActionStep(iteration=iteration, start_time=step_start_time) | ||||
|             try: | ||||
|                 self.step(step_log_entry) | ||||
|                 if "final_answer" in step_log_entry: | ||||
|                     final_answer = step_log_entry["final_answer"] | ||||
|                 self.step(step_log) | ||||
|                 if step_log.final_answer is not None: | ||||
|                     final_answer = step_log.final_answer | ||||
|             except AgentError as e: | ||||
|                 step_log_entry["error"] = e | ||||
|                 step_log.error = e | ||||
|             finally: | ||||
|                 step_end_time = time.time() | ||||
|                 step_log_entry["step_end_time"] = step_end_time | ||||
|                 step_log_entry["step_duration"] = step_end_time - step_start_time | ||||
|                 self.logs.append(step_log_entry) | ||||
|                 step_log.step_end_time = time.time() | ||||
|                 step_log.step_duration = step_log.step_end_time - step_start_time | ||||
|                 self.logs.append(step_log) | ||||
|                 for callback in self.step_callbacks: | ||||
|                     callback(step_log_entry) | ||||
|                     callback(step_log) | ||||
|                 iteration += 1 | ||||
|                 yield step_log_entry | ||||
|                 yield step_log | ||||
| 
 | ||||
|         if final_answer is None and iteration == self.max_iterations: | ||||
|             error_message = "Reached max iterations." | ||||
|             final_step_log = {"error": AgentMaxIterationsError(error_message)} | ||||
|             self.logs.append(final_step_log) | ||||
|             console.print(f"[bold red]{error_message}") | ||||
|             final_step_log = ActionStep(error=AgentMaxIterationsError(error_message)) | ||||
|             self.logs.append(final_step_log) | ||||
|             final_answer = self.provide_final_answer(task) | ||||
|             final_step_log["final_answer"] = final_answer | ||||
|             final_step_log["step_duration"] = 0 | ||||
|             final_step_log.final_answer = final_answer | ||||
|             final_step_log.step_end_time = time.time() | ||||
|             final_step_log.step_duration = step_log.step_end_time - step_start_time | ||||
|             for callback in self.step_callbacks: | ||||
|                 callback(final_step_log) | ||||
|             yield final_step_log | ||||
|  | @ -795,32 +630,32 @@ class ReactAgent(Agent): | |||
|         iteration = 0 | ||||
|         while final_answer is None and iteration < self.max_iterations: | ||||
|             step_start_time = time.time() | ||||
|             step_log_entry = {"iteration": iteration, "start_time": step_start_time} | ||||
|             step_log = ActionStep(iteration=iteration, start_time=step_start_time) | ||||
|             try: | ||||
|                 if self.planning_interval is not None and iteration % self.planning_interval == 0: | ||||
|                     self.planning_step(task, is_first_step=(iteration == 0), iteration=iteration) | ||||
|                 self.step(step_log_entry) | ||||
|                 if "final_answer" in step_log_entry: | ||||
|                     final_answer = step_log_entry["final_answer"] | ||||
|                 self.step(step_log) | ||||
|                 if step_log.final_answer is not None: | ||||
|                     final_answer = step_log.final_answer | ||||
|             except AgentError as e: | ||||
|                 step_log_entry["error"] = e | ||||
|                 step_log.error = e | ||||
|             finally: | ||||
|                 step_end_time = time.time() | ||||
|                 step_log_entry["step_end_time"] = step_end_time | ||||
|                 step_log_entry["step_duration"] = step_end_time - step_start_time | ||||
|                 self.logs.append(step_log_entry) | ||||
|                 step_log.step_end_time = step_end_time | ||||
|                 step_log.step_duration = step_end_time - step_start_time | ||||
|                 self.logs.append(step_log) | ||||
|                 for callback in self.step_callbacks: | ||||
|                     callback(step_log_entry) | ||||
|                     callback(step_log) | ||||
|                 iteration += 1 | ||||
| 
 | ||||
|         if final_answer is None and iteration == self.max_iterations: | ||||
|             error_message = "Reached max iterations." | ||||
|             final_step_log = {"error": AgentMaxIterationsError(error_message)} | ||||
|             final_step_log = ActionStep(error=AgentMaxIterationsError(error_message)) | ||||
|             self.logs.append(final_step_log) | ||||
|             console.print(f"[bold red]{error_message}") | ||||
|             final_answer = self.provide_final_answer(task) | ||||
|             final_step_log["final_answer"] = final_answer | ||||
|             final_step_log["step_duration"] = 0 | ||||
|             final_step_log.final_answer = final_answer | ||||
|             final_step_log.step_duration = 0 | ||||
|             for callback in self.step_callbacks: | ||||
|                 callback(final_step_log) | ||||
| 
 | ||||
|  | @ -875,7 +710,7 @@ Now begin!""", | |||
| ``` | ||||
| {answer_facts} | ||||
| ```""".strip() | ||||
|             self.logs.append({"plan": final_plan_redaction, "facts": final_facts_redaction}) | ||||
|             self.logs.append(PlanningStep(plan=final_plan_redaction, facts=final_facts_redaction)) | ||||
|             console.rule("[orange]Initial plan") | ||||
|             console.print(final_plan_redaction) | ||||
|         else:  # update plan | ||||
|  | @ -921,8 +756,8 @@ Now begin!""", | |||
| ``` | ||||
| {facts_update} | ||||
| ```""" | ||||
|             self.logs.append({"plan": final_plan_redaction, "facts": final_facts_redaction}) | ||||
|             console.rule("Updated plan") | ||||
|             self.logs.append(PlanningStep(plan=final_plan_redaction, facts=final_facts_redaction)) | ||||
|             console.rule("[orange]Updated plan") | ||||
|             console.print(final_plan_redaction) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -959,7 +794,7 @@ class ReactJsonAgent(ReactAgent): | |||
|             **kwargs, | ||||
|         ) | ||||
| 
 | ||||
|     def step(self, log_entry: Dict[str, Any]): | ||||
|     def step(self, log_entry: ActionStep): | ||||
|         """ | ||||
|         Perform one step in the ReAct framework: the agent thinks, acts, and observes the result. | ||||
|         The errors are raised here, they are caught and logged in the run() method. | ||||
|  | @ -970,7 +805,7 @@ class ReactJsonAgent(ReactAgent): | |||
|         console.rule("New step") | ||||
| 
 | ||||
|         # Add new step in logs | ||||
|         log_entry["agent_memory"] = agent_memory.copy() | ||||
|         log_entry.agent_memory = agent_memory.copy() | ||||
| 
 | ||||
|         if self.verbose: | ||||
|             console.rule("Calling LLM with this last message:") | ||||
|  | @ -985,7 +820,7 @@ class ReactJsonAgent(ReactAgent): | |||
|             raise AgentGenerationError(f"Error in generating llm output: {e}.") | ||||
|         console.rule("===== Output message of the LLM: =====") | ||||
|         console.print(llm_output) | ||||
|         log_entry["llm_output"] = llm_output | ||||
|         log_entry.llm_output = llm_output | ||||
| 
 | ||||
|         # Parse | ||||
|         console.rule("===== Extracting action =====") | ||||
|  | @ -996,8 +831,8 @@ class ReactJsonAgent(ReactAgent): | |||
|         except Exception as e: | ||||
|             raise AgentParsingError(f"Could not parse the given action: {e}.") | ||||
| 
 | ||||
|         log_entry["rationale"] = rationale | ||||
|         log_entry["tool_call"] = {"tool_name": tool_name, "tool_arguments": arguments} | ||||
|         log_entry.rationale = rationale | ||||
|         log_entry.tool_call = {"tool_name": tool_name, "tool_arguments": arguments} | ||||
| 
 | ||||
|         # Execute | ||||
|         console.print("=== Agent thoughts:") | ||||
|  | @ -1015,7 +850,7 @@ class ReactJsonAgent(ReactAgent): | |||
|                     answer = arguments | ||||
|             else: | ||||
|                 answer = arguments | ||||
|             log_entry["final_answer"] = answer | ||||
|             log_entry.final_answer = answer | ||||
|             return answer | ||||
|         else: | ||||
|             if arguments is None: | ||||
|  | @ -1033,7 +868,7 @@ class ReactJsonAgent(ReactAgent): | |||
|                 updated_information = f"Stored '{observation_name}' in memory." | ||||
|             else: | ||||
|                 updated_information = str(observation).strip() | ||||
|             log_entry["observation"] = updated_information | ||||
|             log_entry.observation = updated_information | ||||
|             return log_entry | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1088,7 +923,7 @@ class ReactCodeAgent(ReactAgent): | |||
|         console.rule("New step") | ||||
| 
 | ||||
|         # Add new step in logs | ||||
|         log_entry["agent_memory"] = agent_memory.copy() | ||||
|         log_entry.agent_memory = agent_memory.copy() | ||||
| 
 | ||||
|         if self.verbose: | ||||
|             console.print("===== Calling LLM with these last messages: =====") | ||||
|  | @ -1105,7 +940,7 @@ class ReactCodeAgent(ReactAgent): | |||
|         if self.verbose: | ||||
|             console.rule("Output message of the LLM:") | ||||
|             console.print(llm_output) | ||||
|         log_entry["llm_output"] = llm_output | ||||
|         log_entry.llm_output = llm_output | ||||
| 
 | ||||
|         # Parse | ||||
|         try: | ||||
|  | @ -1120,8 +955,8 @@ class ReactCodeAgent(ReactAgent): | |||
|             error_msg = f"Error in code parsing: {e}. Make sure to provide correct code" | ||||
|             raise AgentParsingError(error_msg) | ||||
| 
 | ||||
|         log_entry["rationale"] = rationale | ||||
|         log_entry["tool_call"] = {"tool_name": "code interpreter", "tool_arguments": code_action} | ||||
|         log_entry.rationale = rationale | ||||
|         log_entry.tool_call = {"tool_name": "code interpreter", "tool_arguments": code_action} | ||||
| 
 | ||||
|         # Execute | ||||
|         self.log_rationale_code_action(rationale, code_action) | ||||
|  | @ -1145,8 +980,8 @@ class ReactCodeAgent(ReactAgent): | |||
|             if result is not None: | ||||
|                 console.print("Last output from code snippet:") | ||||
|                 console.print(str(result)) | ||||
|                 observation += "Last output from code snippet:\n" + str(result)[:100000] | ||||
|             log_entry["observation"] = observation | ||||
|                 observation += "Last output from code snippet:\n" + str(result)[:LENGTH_TRUNCATE_REPORTS] | ||||
|             log_entry.observation = observation | ||||
|         except Exception as e: | ||||
|             error_msg = f"Code execution failed due to the following error:\n{str(e)}" | ||||
|             if "'dict' object has no attribute 'read'" in str(e): | ||||
|  | @ -1156,13 +991,9 @@ class ReactCodeAgent(ReactAgent): | |||
|             if line[: len("final_answer")] == "final_answer": | ||||
|                 console.print("Final answer:") | ||||
|                 console.print(f"[bold]{result}") | ||||
|                 log_entry["final_answer"] = result | ||||
|                 log_entry.final_answer = result | ||||
|         return result | ||||
| 
 | ||||
| 
 | ||||
| LENGTH_TRUNCATE_REPORTS = 1000 | ||||
| 
 | ||||
| 
 | ||||
| class ManagedAgent: | ||||
|     def __init__(self, agent, name, description, additional_prompting=None, provide_run_summary=False): | ||||
|         self.agent = agent | ||||
|  |  | |||
|  | @ -102,7 +102,7 @@ class Monitor: | |||
|             self.total_output_token_count = 0 | ||||
| 
 | ||||
|     def update_metrics(self, step_log): | ||||
|         step_duration = step_log["step_duration"] | ||||
|         step_duration = step_log.step_duration | ||||
|         self.step_durations.append(step_duration) | ||||
|         console.print(f"Step {len(self.step_durations)}:") | ||||
|         console.print(f"- Time taken: {step_duration:.2f} seconds") | ||||
|  | @ -110,6 +110,6 @@ class Monitor: | |||
|         if getattr(self.tracked_llm_engine, "last_input_token_count", None) is not None: | ||||
|             self.total_input_token_count += self.tracked_llm_engine.last_input_token_count | ||||
|             self.total_output_token_count += self.tracked_llm_engine.last_output_token_count | ||||
|             console.print(f"- Input tokens: {self.total_input_token_count}") | ||||
|             console.print(f"- Output tokens: {self.total_output_token_count}") | ||||
|             console.print(f"- Input tokens: {self.total_input_token_count:,}") | ||||
|             console.print(f"- Output tokens: {self.total_output_token_count:,}") | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										103
									
								
								agents/tools.py
								
								
								
								
							
							
						
						
									
										103
									
								
								agents/tools.py
								
								
								
								
							|  | @ -1000,3 +1000,106 @@ def tool(tool_function: Callable) -> Tool: | |||
| 
 | ||||
|     SpecificTool.__name__ = class_name | ||||
|     return SpecificTool() | ||||
| 
 | ||||
| 
 | ||||
| class Toolbox: | ||||
|     """ | ||||
|     The toolbox contains all tools that the agent can perform operations with, as well as a few methods to | ||||
|     manage them. | ||||
| 
 | ||||
|     Args: | ||||
|         tools (`List[Tool]`): | ||||
|             The list of tools to instantiate the toolbox with | ||||
|         add_base_tools (`bool`, defaults to `False`, *optional*, defaults to `False`): | ||||
|             Whether to add the tools available within `transformers` to the toolbox. | ||||
|     """ | ||||
| 
 | ||||
|     def __init__(self, tools: List[Tool], add_base_tools: bool = False): | ||||
|         self._tools = {tool.name: tool for tool in tools} | ||||
|         if add_base_tools: | ||||
|             self.add_base_tools() | ||||
|         # self._load_tools_if_needed() | ||||
| 
 | ||||
|     def add_base_tools(self, add_python_interpreter: bool = False): | ||||
|         global _tools_are_initialized | ||||
|         global HUGGINGFACE_DEFAULT_TOOLS | ||||
|         if not _tools_are_initialized: | ||||
|             HUGGINGFACE_DEFAULT_TOOLS = setup_default_tools() | ||||
|             _tools_are_initialized = True | ||||
|         for tool in HUGGINGFACE_DEFAULT_TOOLS.values(): | ||||
|             if tool.name != "python_interpreter" or add_python_interpreter: | ||||
|                 self.add_tool(tool) | ||||
|         # self._load_tools_if_needed() | ||||
| 
 | ||||
|     @property | ||||
|     def tools(self) -> Dict[str, Tool]: | ||||
|         """Get all tools currently in the toolbox""" | ||||
|         return self._tools | ||||
| 
 | ||||
|     def show_tool_descriptions(self, tool_description_template: str = None) -> str: | ||||
|         """ | ||||
|         Returns the description of all tools in the toolbox | ||||
| 
 | ||||
|         Args: | ||||
|             tool_description_template (`str`, *optional*): | ||||
|                 The template to use to describe the tools. If not provided, the default template will be used. | ||||
|         """ | ||||
|         return "\n".join( | ||||
|             [get_tool_description_with_args(tool, tool_description_template) for tool in self._tools.values()] | ||||
|         ) | ||||
| 
 | ||||
|     def add_tool(self, tool: Tool): | ||||
|         """ | ||||
|         Adds a tool to the toolbox | ||||
| 
 | ||||
|         Args: | ||||
|             tool (`Tool`): | ||||
|                 The tool to add to the toolbox. | ||||
|         """ | ||||
|         if tool.name in self._tools: | ||||
|             raise KeyError(f"Error: tool '{tool.name}' already exists in the toolbox.") | ||||
|         self._tools[tool.name] = tool | ||||
| 
 | ||||
|     def remove_tool(self, tool_name: str): | ||||
|         """ | ||||
|         Removes a tool from the toolbox | ||||
| 
 | ||||
|         Args: | ||||
|             tool_name (`str`): | ||||
|                 The tool to remove from the toolbox. | ||||
|         """ | ||||
|         if tool_name not in self._tools: | ||||
|             raise KeyError( | ||||
|                 f"Error: tool {tool_name} not found in toolbox for removal, should be instead one of {list(self._tools.keys())}." | ||||
|             ) | ||||
|         del self._tools[tool_name] | ||||
| 
 | ||||
|     def update_tool(self, tool: Tool): | ||||
|         """ | ||||
|         Updates a tool in the toolbox according to its name. | ||||
| 
 | ||||
|         Args: | ||||
|             tool (`Tool`): | ||||
|                 The tool to update to the toolbox. | ||||
|         """ | ||||
|         if tool.name not in self._tools: | ||||
|             raise KeyError( | ||||
|                 f"Error: tool {tool.name} not found in toolbox for update, should be instead one of {list(self._tools.keys())}." | ||||
|             ) | ||||
|         self._tools[tool.name] = tool | ||||
| 
 | ||||
|     def clear_toolbox(self): | ||||
|         """Clears the toolbox""" | ||||
|         self._tools = {} | ||||
| 
 | ||||
|     # def _load_tools_if_needed(self): | ||||
|     #     for name, tool in self._tools.items(): | ||||
|     #         if not isinstance(tool, Tool): | ||||
|     #             task_or_repo_id = tool.task if tool.repo_id is None else tool.repo_id | ||||
|     #             self._tools[name] = load_tool(task_or_repo_id) | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         toolbox_description = "Toolbox contents:\n" | ||||
|         for tool in self._tools.values(): | ||||
|             toolbox_description += f"\t{tool.name}: {tool.description}\n" | ||||
|         return toolbox_description | ||||
|  |  | |||
|  | @ -1,3 +1,22 @@ | |||
| #!/usr/bin/env python | ||||
| # coding=utf-8 | ||||
| 
 | ||||
| # Copyright 2023 The HuggingFace Inc. team. All rights reserved. | ||||
| # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software | ||||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
| import json | ||||
| import re | ||||
| from typing import Tuple, Dict | ||||
| 
 | ||||
| from transformers.utils.import_utils import _is_package_available | ||||
| 
 | ||||
|  | @ -8,3 +27,57 @@ def is_pygments_available(): | |||
| 
 | ||||
| from rich.console import Console | ||||
| console = Console() | ||||
| 
 | ||||
| 
 | ||||
| def parse_json_blob(json_blob: str) -> Dict[str, str]: | ||||
|     try: | ||||
|         first_accolade_index = json_blob.find("{") | ||||
|         last_accolade_index = [a.start() for a in list(re.finditer("}", json_blob))][-1] | ||||
|         json_blob = json_blob[first_accolade_index : last_accolade_index + 1].replace('\\"', "'") | ||||
|         json_data = json.loads(json_blob, strict=False) | ||||
|         return json_data | ||||
|     except json.JSONDecodeError as e: | ||||
|         place = e.pos | ||||
|         if json_blob[place - 1 : place + 2] == "},\n": | ||||
|             raise ValueError( | ||||
|                 "JSON is invalid: you probably tried to provide multiple tool calls in one action. PROVIDE ONLY ONE TOOL CALL." | ||||
|             ) | ||||
|         raise ValueError( | ||||
|             f"The JSON blob you used is invalid due to the following error: {e}.\n" | ||||
|             f"JSON blob was: {json_blob}, decoding failed on that specific part of the blob:\n" | ||||
|             f"'{json_blob[place-4:place+5]}'." | ||||
|         ) | ||||
|     except Exception as e: | ||||
|         raise ValueError(f"Error in parsing the JSON blob: {e}") | ||||
| 
 | ||||
| 
 | ||||
| def parse_code_blob(code_blob: str) -> str: | ||||
|     try: | ||||
|         pattern = r"```(?:py|python)?\n(.*?)\n```" | ||||
|         match = re.search(pattern, code_blob, re.DOTALL) | ||||
|         return match.group(1).strip() | ||||
|     except Exception as e: | ||||
|         raise ValueError( | ||||
|             f""" | ||||
| The code blob you used is invalid: due to the following error: {e} | ||||
| This means that the regex pattern {pattern} was not respected: make sure to include code with the correct pattern, for instance: | ||||
| Thoughts: Your thoughts | ||||
| Code: | ||||
| ```py | ||||
| # Your python code here | ||||
| ```<end_action>""" | ||||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| def parse_json_tool_call(json_blob: str) -> Tuple[str, Dict[str, str]]: | ||||
|     json_blob = json_blob.replace("```json", "").replace("```", "") | ||||
|     tool_call = parse_json_blob(json_blob) | ||||
|     if "action" in tool_call and "action_input" in tool_call: | ||||
|         return tool_call["action"], tool_call["action_input"] | ||||
|     elif "action" in tool_call: | ||||
|         return tool_call["action"], None | ||||
|     else: | ||||
|         missing_keys = [key for key in ['action', 'action_input'] if key not in tool_call] | ||||
|         error_msg = f"Missing keys: {missing_keys} in blob {tool_call}" | ||||
|         console.print(f"[bold red]{error_msg}[/bold red]") | ||||
|         raise ValueError(error_msg) | ||||
|  | @ -0,0 +1,36 @@ | |||
| from agents import load_tool, ReactCodeAgent, ReactJsonAgent, HfApiEngine | ||||
| from agents.default_tools import PythonInterpreterTool | ||||
| 
 | ||||
| # Import tool from Hub | ||||
| image_generation_tool = load_tool("m-ric/text-to-image", cache=False) | ||||
| 
 | ||||
| from agents.search import DuckDuckGoSearchTool | ||||
| 
 | ||||
| search_tool = DuckDuckGoSearchTool() | ||||
| 
 | ||||
| llm_engine = HfApiEngine("Qwen/Qwen2.5-72B-Instruct") | ||||
| 
 | ||||
| agent = ReactCodeAgent(tools=[search_tool], llm_engine=llm_engine, planning_interval=3) | ||||
| 
 | ||||
| # Run it! | ||||
| print("Let's run the Code agent:") | ||||
| 
 | ||||
| result = agent.run( | ||||
|     "How long would a cheetah at full speed take to run the length of Pont Alexandre III?", | ||||
| ) | ||||
| 
 | ||||
| print("RESULT:", result) | ||||
| 
 | ||||
| 
 | ||||
| code_tool = PythonInterpreterTool() | ||||
| 
 | ||||
| agent = ReactJsonAgent(tools=[search_tool, code_tool], llm_engine=llm_engine, planning_interval=3) | ||||
| 
 | ||||
| print("====================") | ||||
| print("====================") | ||||
| print("Now let's run the JSON agent:") | ||||
| result = agent.run( | ||||
|     "How long would a cheetah at full speed take to run the length of Pont Alexandre III?", | ||||
| ) | ||||
| 
 | ||||
| print("RESULT:", result) | ||||
|  | @ -1,11 +1,9 @@ | |||
| from agents import load_tool, ReactCodeAgent, HfApiEngine | ||||
| from agents.search import DuckDuckGoSearchTool | ||||
| 
 | ||||
| # Import tool from Hub | ||||
| image_generation_tool = load_tool("m-ric/text-to-image", cache=False) | ||||
| 
 | ||||
| # Import tool from LangChain | ||||
| from agents.search import DuckDuckGoSearchTool | ||||
| 
 | ||||
| search_tool = DuckDuckGoSearchTool() | ||||
| 
 | ||||
| llm_engine = HfApiEngine("Qwen/Qwen2.5-72B-Instruct") | ||||
|  |  | |||
|  | @ -0,0 +1,116 @@ | |||
| from agents.llm_engine import TransformersEngine | ||||
| from agents import CodeAgent, ReactJsonAgent | ||||
| 
 | ||||
| import requests | ||||
| from datetime import datetime | ||||
| 
 | ||||
| model_repo="andito/SmolLM2-1.7B-Instruct-F16-GGUF" | ||||
| model_filename="smollm2-1.7b-8k-dpo-f16.gguf" | ||||
| 
 | ||||
| import random | ||||
| from llama_cpp import Llama | ||||
| 
 | ||||
| model = Llama.from_pretrained( | ||||
|     repo_id=model_repo, | ||||
|     filename=model_filename, | ||||
|     n_ctx=8192, | ||||
|     verbose=False | ||||
| ) | ||||
| print("Model initialized") | ||||
| 
 | ||||
| def llm_engine(messages, stop_sequences=["Task", "<|endoftext|>"]) -> str: | ||||
|     output = "" | ||||
|     for chunk in model.create_chat_completion( | ||||
|         messages=messages, | ||||
|         max_tokens=2048, | ||||
|         temperature=0.0, | ||||
|         top_p=1.0, | ||||
|         top_k=50, | ||||
|         repeat_penalty=1.0, | ||||
|         stream=True | ||||
|     ): | ||||
|         content = chunk['choices'][0]['delta'].get('content') | ||||
|         if content: | ||||
|             if content in ["<end_action>", "<|endoftext|>"]: | ||||
|                 break | ||||
|             output += content | ||||
|     return output | ||||
| 
 | ||||
| system_prompt = """You are an expert in composing functions. You are given a question and a set of possible functions.  | ||||
| Based on the question, you will need to make one or more function/tool calls to achieve the purpose.  | ||||
| If none of the functions can be used, point it out and refuse to answer.  | ||||
| If the given question lacks the parameters required by the function, also point it out. | ||||
| 
 | ||||
| You have access to the following tools: | ||||
| <<tool_descriptions>> | ||||
| 
 | ||||
| <<managed_agents_descriptions>> | ||||
| 
 | ||||
| You can use imports in your code, but only from the following list of modules: <<authorized_imports>> | ||||
| 
 | ||||
| The output MUST strictly adhere to the following format, and NO other text MUST be included. | ||||
| The example format is as follows. Please make sure the parameter type is correct. If no function call is needed, please make the tool calls an empty list '[]'. | ||||
| <tool_call>[ | ||||
| {"name": "func_name1", "arguments": {"argument1": "value1", "argument2": "value2"}}, | ||||
| ... (more tool calls as required) | ||||
| ]</tool_call>""" | ||||
| 
 | ||||
| 
 | ||||
| from agents import tool | ||||
| import webbrowser | ||||
| 
 | ||||
| @tool | ||||
| def get_random_number_between(min: int, max: int) -> int: | ||||
|     """ | ||||
|     Gets a random number between min and max. | ||||
| 
 | ||||
|     Args: | ||||
|         min: The minimum number. | ||||
|         max: The maximum number. | ||||
| 
 | ||||
|     Returns: | ||||
|         A random number between min and max. | ||||
|     """ | ||||
|     return random.randint(min, max) | ||||
| 
 | ||||
| 
 | ||||
| @tool | ||||
| def get_weather(city: str) -> str: | ||||
|     """ | ||||
|     Returns the weather forecast for a given city. | ||||
| 
 | ||||
|     Args: | ||||
|         city: The name of the city. | ||||
| 
 | ||||
|     Returns: | ||||
|         A string with a mock weather forecast. | ||||
|     """ | ||||
|     url = 'https://wttr.in/{}?format=+%C,+%t'.format(city) | ||||
|     res = requests.get(url).text | ||||
| 
 | ||||
|     return f"The weather in {city} is {res.split(',')[0]} with a high of {res.split(',')[1][:-2]} degrees Celsius." | ||||
| 
 | ||||
| @tool | ||||
| def get_current_time() -> str: | ||||
|     """ | ||||
|     This is a tool that returns the current time. | ||||
|     It returns the current time as HH:MM. | ||||
|     """ | ||||
|     return f"The current time is {datetime.now().hour}:{datetime.now().minute}." | ||||
| 
 | ||||
| @tool | ||||
| def open_webbrowser(url: str) -> str: | ||||
|     """ | ||||
|     This is a tool that opens a web browser to the given website. | ||||
|     If the user asks to open a website or a browser, you should use this tool. | ||||
| 
 | ||||
|     Args: | ||||
|         url: The url to open. | ||||
|     """ | ||||
|     webbrowser.open(url) | ||||
|     return f"I opened {url.replace('https://', '').replace('www.', '')} in the browser." | ||||
| 
 | ||||
| 
 | ||||
| agent = ReactJsonAgent(llm_engine = llm_engine, tools=[get_current_time, open_webbrowser, get_random_number_between, get_weather]) | ||||
| print("Agent initialized!") | ||||
| agent.run("What's the weather like in London?") | ||||
|  | @ -136,6 +136,17 @@ files = [ | |||
|     {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "diskcache" | ||||
| version = "5.6.3" | ||||
| description = "Disk Cache -- Disk and file backed persistent cache." | ||||
| optional = false | ||||
| python-versions = ">=3" | ||||
| files = [ | ||||
|     {file = "diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19"}, | ||||
|     {file = "diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "exceptiongroup" | ||||
| version = "1.2.2" | ||||
|  | @ -264,6 +275,45 @@ files = [ | |||
|     {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "jinja2" | ||||
| version = "3.1.4" | ||||
| description = "A very fast and expressive template engine." | ||||
| optional = false | ||||
| python-versions = ">=3.7" | ||||
| files = [ | ||||
|     {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, | ||||
|     {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, | ||||
| ] | ||||
| 
 | ||||
| [package.dependencies] | ||||
| MarkupSafe = ">=2.0" | ||||
| 
 | ||||
| [package.extras] | ||||
| i18n = ["Babel (>=2.7)"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "llama-cpp-python" | ||||
| version = "0.3.4" | ||||
| description = "Python bindings for the llama.cpp library" | ||||
| optional = false | ||||
| python-versions = ">=3.8" | ||||
| files = [ | ||||
|     {file = "llama_cpp_python-0.3.4.tar.gz", hash = "sha256:52b37129c282753edf89213e852b8b46664b059116ae2213da9cb4a45374d23d"}, | ||||
| ] | ||||
| 
 | ||||
| [package.dependencies] | ||||
| diskcache = ">=5.6.1" | ||||
| jinja2 = ">=2.11.3" | ||||
| numpy = ">=1.20.0" | ||||
| typing-extensions = ">=4.5.0" | ||||
| 
 | ||||
| [package.extras] | ||||
| all = ["llama_cpp_python[dev,server,test]"] | ||||
| dev = ["black (>=23.3.0)", "httpx (>=0.24.1)", "mkdocs (>=1.4.3)", "mkdocs-material (>=9.1.18)", "mkdocstrings[python] (>=0.22.0)", "pytest (>=7.4.0)", "twine (>=4.0.2)"] | ||||
| server = ["PyYAML (>=5.1)", "fastapi (>=0.100.0)", "pydantic-settings (>=2.0.1)", "sse-starlette (>=1.6.1)", "starlette-context (>=0.3.6,<0.4)", "uvicorn (>=0.22.0)"] | ||||
| test = ["fastapi (>=0.100.0)", "httpx (>=0.24.1)", "huggingface-hub (>=0.23.0)", "pydantic-settings (>=2.0.1)", "pytest (>=7.4.0)", "scipy (>=1.10)", "sse-starlette (>=1.6.1)", "starlette-context (>=0.3.6,<0.4)"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "markdown-it-py" | ||||
| version = "3.0.0" | ||||
|  | @ -288,6 +338,76 @@ profiling = ["gprof2dot"] | |||
| rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] | ||||
| testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "markupsafe" | ||||
| version = "3.0.2" | ||||
| description = "Safely add untrusted strings to HTML/XML markup." | ||||
| optional = false | ||||
| python-versions = ">=3.9" | ||||
| files = [ | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, | ||||
|     {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, | ||||
|     {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "mdurl" | ||||
| version = "0.1.2" | ||||
|  | @ -374,6 +494,184 @@ files = [ | |||
|     {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pandas" | ||||
| version = "2.2.3" | ||||
| description = "Powerful data structures for data analysis, time series, and statistics" | ||||
| optional = false | ||||
| python-versions = ">=3.9" | ||||
| files = [ | ||||
|     {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, | ||||
|     {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, | ||||
|     {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, | ||||
|     {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, | ||||
|     {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, | ||||
|     {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, | ||||
|     {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, | ||||
|     {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, | ||||
|     {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, | ||||
|     {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, | ||||
|     {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, | ||||
|     {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, | ||||
|     {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, | ||||
|     {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, | ||||
|     {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, | ||||
|     {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, | ||||
|     {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, | ||||
|     {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, | ||||
|     {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, | ||||
|     {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, | ||||
|     {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, | ||||
|     {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, | ||||
|     {file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"}, | ||||
|     {file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"}, | ||||
|     {file = "pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c"}, | ||||
|     {file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"}, | ||||
|     {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea"}, | ||||
|     {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"}, | ||||
|     {file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"}, | ||||
|     {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, | ||||
| ] | ||||
| 
 | ||||
| [package.dependencies] | ||||
| numpy = [ | ||||
|     {version = ">=1.22.4", markers = "python_version < \"3.11\""}, | ||||
|     {version = ">=1.23.2", markers = "python_version == \"3.11\""}, | ||||
|     {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, | ||||
| ] | ||||
| python-dateutil = ">=2.8.2" | ||||
| pytz = ">=2020.1" | ||||
| tzdata = ">=2022.7" | ||||
| 
 | ||||
| [package.extras] | ||||
| all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] | ||||
| aws = ["s3fs (>=2022.11.0)"] | ||||
| clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] | ||||
| compression = ["zstandard (>=0.19.0)"] | ||||
| computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] | ||||
| consortium-standard = ["dataframe-api-compat (>=0.1.7)"] | ||||
| excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] | ||||
| feather = ["pyarrow (>=10.0.1)"] | ||||
| fss = ["fsspec (>=2022.11.0)"] | ||||
| gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] | ||||
| hdf5 = ["tables (>=3.8.0)"] | ||||
| html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] | ||||
| mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] | ||||
| output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] | ||||
| parquet = ["pyarrow (>=10.0.1)"] | ||||
| performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] | ||||
| plot = ["matplotlib (>=3.6.3)"] | ||||
| postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] | ||||
| pyarrow = ["pyarrow (>=10.0.1)"] | ||||
| spss = ["pyreadstat (>=1.2.0)"] | ||||
| sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] | ||||
| test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] | ||||
| xml = ["lxml (>=4.9.2)"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pillow" | ||||
| version = "11.0.0" | ||||
| description = "Python Imaging Library (Fork)" | ||||
| optional = false | ||||
| python-versions = ">=3.9" | ||||
| files = [ | ||||
|     {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, | ||||
|     {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, | ||||
|     {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, | ||||
|     {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, | ||||
|     {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, | ||||
|     {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, | ||||
|     {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, | ||||
|     {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, | ||||
|     {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, | ||||
|     {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, | ||||
|     {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, | ||||
|     {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, | ||||
|     {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, | ||||
|     {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, | ||||
|     {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, | ||||
|     {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, | ||||
|     {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, | ||||
|     {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, | ||||
| ] | ||||
| 
 | ||||
| [package.extras] | ||||
| docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] | ||||
| fpx = ["olefile"] | ||||
| mic = ["olefile"] | ||||
| tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] | ||||
| typing = ["typing-extensions"] | ||||
| xmp = ["defusedxml"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pluggy" | ||||
| version = "1.5.0" | ||||
|  | @ -425,6 +723,31 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} | |||
| [package.extras] | ||||
| dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "python-dateutil" | ||||
| version = "2.9.0.post0" | ||||
| description = "Extensions to the standard Python datetime module" | ||||
| optional = false | ||||
| python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" | ||||
| files = [ | ||||
|     {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, | ||||
|     {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, | ||||
| ] | ||||
| 
 | ||||
| [package.dependencies] | ||||
| six = ">=1.5" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pytz" | ||||
| version = "2024.2" | ||||
| description = "World timezone definitions, modern and historical" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
| files = [ | ||||
|     {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, | ||||
|     {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "pyyaml" | ||||
| version = "6.0.2" | ||||
|  | @ -762,6 +1085,17 @@ tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] | |||
| testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] | ||||
| torch = ["safetensors[numpy]", "torch (>=1.10)"] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "six" | ||||
| version = "1.17.0" | ||||
| description = "Python 2 and 3 compatibility utilities" | ||||
| optional = false | ||||
| python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" | ||||
| files = [ | ||||
|     {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, | ||||
|     {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "tokenizers" | ||||
| version = "0.21.0" | ||||
|  | @ -936,6 +1270,17 @@ files = [ | |||
|     {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "tzdata" | ||||
| version = "2024.2" | ||||
| description = "Provider of IANA time zone data" | ||||
| optional = false | ||||
| python-versions = ">=2" | ||||
| files = [ | ||||
|     {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, | ||||
|     {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "urllib3" | ||||
| version = "2.2.3" | ||||
|  | @ -956,4 +1301,4 @@ zstd = ["zstandard (>=0.18.0)"] | |||
| [metadata] | ||||
| lock-version = "2.0" | ||||
| python-versions = ">=3.10,<3.13" | ||||
| content-hash = "985797a96ac1b58e4892479d96bbd1c696b452d760fa421a28b91ea8b3dbf977" | ||||
| content-hash = "6c3841968936d66bf70e11c6c8e0a16fec6c2f4d88d79cd8ac5a412225e7cf56" | ||||
|  |  | |||
|  | @ -63,6 +63,10 @@ transformers = ">=4.0.0" | |||
| pytest = {version = ">=8.1.0", optional = true} | ||||
| requests = "^2.32.3" | ||||
| rich = "^13.9.4" | ||||
| pandas = "^2.2.3" | ||||
| jinja2 = "^3.1.4" | ||||
| pillow = "^11.0.0" | ||||
| llama-cpp-python = "^0.3.4" | ||||
| 
 | ||||
| 
 | ||||
| [build-system] | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue