Spaces:
Paused
Paused
| # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # | |
| # 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 re | |
| from frame.clients import Client | |
| def namify_model_path(hf_model_path: str) -> str: | |
| return hf_model_path.replace("/", "_").replace("-", "_").replace(" ", "_") | |
| class Errand: | |
| def __init__(self, pre_prompt: str, prompt: str) -> None: | |
| self.pre_prompt = pre_prompt | |
| self.prompt = prompt | |
| def run(self, runner: Client, args: dict, completion_config: dict = {}) -> str: | |
| prompt_with_args = self.prompt | |
| for arg_name, arg_value in args.items(): | |
| prompt_with_args = prompt_with_args.replace("{" + arg_name + "}", arg_value) | |
| ret = runner.run(self.pre_prompt, prompt_with_args, completion_config) | |
| return ret | |
| class FileErrand( | |
| Errand | |
| ): # NOTE: this is only for easier debug for now; production code should use errands directly | |
| def __init__(self, errand_path: str) -> None: | |
| with open(errand_path, "r") as f: | |
| errand = f.read() | |
| errand_parts = errand.split("===SEPARATOR===") | |
| if len(errand_parts) != 2: | |
| raise ValueError( | |
| f"Errand file {errand_path} is not valid. It should contain exactly one separator." | |
| ) | |
| pre_prompt = errand_parts[0].strip() | |
| prompt = errand_parts[1].strip() | |
| super().__init__(pre_prompt, prompt) | |
| class MultipleChoiceErrand(FileErrand): | |
| def __init__(self, errand_path: str, choices: list[str]) -> None: | |
| super().__init__(errand_path) | |
| self.choices = choices | |
| def run( | |
| self, runner: Client, args: dict, completion_config: dict = {} | |
| ) -> str | None: | |
| raw_completion = super().run(runner, args, completion_config) | |
| for choice in self.choices: | |
| if choice in raw_completion: | |
| return choice | |
| return None | |
| import os | |
| from pathlib import Path | |
| class MessageTypeErrand(MultipleChoiceErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_type.txt" | |
| ) | |
| choices = [ | |
| "code_skill", | |
| "routine_skill", | |
| "query_skill", | |
| "code", | |
| "routine", | |
| "query", | |
| "data", | |
| ] | |
| super().__init__(errand_path, choices) | |
| class MessageCodeProcessingErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_code_processing.txt" | |
| ) | |
| super().__init__(errand_path) | |
| class MessageCodeSkillProcessingErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_code_skill_processing.txt" | |
| ) | |
| super().__init__(errand_path) | |
| class MessageCodeCallErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_code_call.txt" | |
| ) | |
| super().__init__(errand_path) | |
| class MessageCodeVariablesErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_code_variables.txt" | |
| ) | |
| super().__init__(errand_path) | |
| class MessageRoutineProcessingErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_routine_processing.txt" | |
| ) | |
| super().__init__(errand_path) | |
| class MessageGeneratingRoutineProcessingErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, | |
| "errands/message_generating_routine_processing.txt", | |
| ) | |
| super().__init__(errand_path) | |
| class MessageRoutineCallErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_routine_call.txt" | |
| ) | |
| super().__init__(errand_path) | |
| class MessageGeneratingRoutineCallErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, | |
| "errands/message_generating_routine_call.txt", | |
| ) | |
| super().__init__(errand_path) | |
| class MessageRoutineVariablesErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_routine_variables.txt" | |
| ) | |
| super().__init__(errand_path) | |
| class MessageDataProcessingErrand(FileErrand): | |
| def __init__(self) -> None: | |
| errand_path = os.path.join( | |
| Path(__file__).resolve().parent, "errands/message_data_processing.txt" | |
| ) | |
| super().__init__(errand_path) | |
| default_errand_profile: dict[str, type[Errand] | None] = { | |
| "message_type": MessageTypeErrand, | |
| "message_code_processing": MessageCodeProcessingErrand, | |
| "message_code_skill_processing": MessageCodeSkillProcessingErrand, | |
| "message_code_call": MessageCodeCallErrand, | |
| "message_code_variables": MessageCodeVariablesErrand, | |
| "message_routine_processing": MessageRoutineProcessingErrand, | |
| "message_generating_routine_processing": MessageGeneratingRoutineProcessingErrand, | |
| "message_routine_call": MessageRoutineCallErrand, | |
| "message_generating_routine_call": MessageGeneratingRoutineCallErrand, | |
| "message_routine_variables": MessageRoutineVariablesErrand, | |
| "message_data_processing": MessageDataProcessingErrand, | |
| "language_model": None, # on purpose, currently there is no errand but there might be a client profile # TODO: double-check if this is still needed in V4 | |
| } | |