	async def test_registry_action_decorator(self):
		"""Test the action decorator with filters"""
		registry = Registry()

		# Define actions with different filters
		@registry.action(
			description='No filter action',
		)
		def no_filter_action():
			pass

		@registry.action(description='Domain filter action', domains=['example.com'])
		def domain_filter_action():
			pass

		@registry.action(description='Page filter action', page_filter=lambda page: 'admin' in page.url)
		def page_filter_action():
			pass

		# Check that system prompt only includes the no_filter_action
		system_description = registry.get_prompt_description()
		assert 'No filter action' in system_description
		assert 'Domain filter action' not in system_description
		assert 'Page filter action' not in system_description

		# Check that page-specific prompt includes the right actions
		mock_page = MagicMock(spec=Page)
		mock_page.url = 'https://example.com/admin'

		page_description = registry.get_prompt_description(mock_page)
		assert 'Domain filter action' in page_description
		assert 'Page filter action' in page_description


def finger(a):
    return numpy.dot(a.ravel(), numpy.cos(numpy.arange(a.size)))


def handle_inquiries(selected_actions: List[str], parameters: dict, llm_api_key: str):
    """
    Decide which function to call based on the selected user actions.

    :param selected_actions: List of actions selected by the user.
    :param parameters: Configuration parameters dictionary.
    :param llm_api_key: API key for the language model.
    """
    try:
        if selected_actions:
            if "Generate Resume" == selected_actions:
                logger.info("Crafting a standout professional resume...")
                create_resume_pdf(parameters, llm_api_key)

            if "Generate Resume Tailored for Job Description" == selected_actions:
                logger.info("Customizing your resume to enhance your job application...")
                create_resume_pdf_job_tailored(parameters, llm_api_key)

            if "Generate Tailored Cover Letter for Job Description" == selected_actions:
                logger.info("Designing a personalized cover letter to enhance your job application...")
                create_cover_letter(parameters, llm_api_key)

        else:
            logger.warning("No actions selected. Nothing to execute.")
    except Exception as e:
        logger.exception(f"An error occurred while handling inquiries: {e}")
        raise


def reduce_tensor(tensor, n):
    rt = tensor.clone()
    dist.all_reduce(rt, op=dist.ReduceOp.SUM)
    rt /= n
    return rt


    def test_err_broken_sans(self, tdata):
        with open(tdata.path("mitmproxy/net/data/text_cert_weird1"), "rb") as f:
            d = f.read()
        c = certs.Cert.from_pem(d)
        # This breaks unless we ignore a decoding error.
        assert c.altnames is not None


    def handle_error(self):
        raise


    def __init__(self, code, obj, strFields=None, trace=None):
        self.label = catalog.alert[code]['label']
        self.code = catalog.alert[code]['code']
        self.cat = catalog.alert[code]['cat']
        self.url = catalog.alert[code]['url']
        self.obj = obj

        if hasattr(obj, 'type'):
            self.type = obj.type
        else:
            self.type = None

        if hasattr(obj, "params"):
            self.name = obj.params['name'].val
        else:
            self.name = None

        if strFields:
            self.msg = _translate(catalog.alert[code]['msg']).format(**strFields)
        else:
            self.msg = _translate(catalog.alert[code]['msg'])

        if trace:
            self.trace = ''.join(traceback.format_exception(
                trace[0], trace[1], trace[2]))
        else:
            self.trace = None


    def indices(self):
        if len(self.metapartitions) > 1:
            raise AttributeError(
                "Accessing `indices` attribute is not allowed while nested"
            )
        return self.metapartitions[0]["indices"]


def fast_unpickle(path: str) -> Any:
    with copy_to_shm(path) as tmp_path:
        with open(tmp_path, "rb") as f:
            return pickle.load(f)


def colored(text, color=None, bold=False):
    fmt = []
    if color== 'red':
        fmt.append('31')
    elif color == 'green':
        fmt.append('32')
    if bold:
        fmt.append('1')

    return f"\033[{';'.join(fmt)}m{text}\033[0m"


def get_db_path():
    """Get the database path from environment or use default"""
    config = Config.from_env()
    db_path = config.get("SQLITE_DB_PATH", os.path.join(project_root, "data", "sqlite", "lpm.db"))
    return db_path


def patched_torch_load(*args, **kwargs):
    if 'map_location' not in kwargs:
        kwargs['map_location'] = map_location
    return torch_load_original(*args, **kwargs)


    def initialize_options(self):
        """Set default values for all the options that this command
        supports.  Note that these defaults may be overridden by other
        commands, by the setup script, by config files, or by the
        command-line.  Thus, this is not the place to code dependencies
        between options; generally, 'initialize_options()' implementations
        are just a bunch of "self.foo = None" assignments.

        This method must be implemented by all command classes.
        """
        raise RuntimeError("abstract method -- subclass %s must override"
                           % self.__class__)


def main():
    parser = argparse.ArgumentParser('export_quantized')
    parser.add_argument('hf_repo')
    parser.add_argument('new_hf_repo', nargs='?', default=None)

    args = parser.parse_args()
    api = get_api()

    repo = args.hf_repo

    print("Downloading base model.")
    info = loaders.CheckpointInfo.from_hf_repo(args.hf_repo)
    print("Creating model.")
    model = info.get_moshi(fuse_lora=True, device='cuda')
    print("Quantizing model.")
    replace_linear_with_qlinear(model)

    if args.new_hf_repo is None:
        new_repo = repo.rsplit('-', 1)[0] + '-q8'
    else:
        new_repo = args.new_hf_repo
    if not api.repo_exists(new_repo):
        api.create_repo(new_repo, repo_type='model')
        print("Repo created.")

    to_copy = ['README.md']
    for file in to_copy:
        if not api.file_exists(repo, file):
            continue
        if not api.file_exists(new_repo, file):
            print("File", file, "is missing")
            old_file = hf_hub_download(repo, file)
            api.upload_file(
                path_or_fileobj=old_file,
                path_in_repo=file,
                repo_id=new_repo,
                repo_type="model")
    with tempfile.NamedTemporaryFile(suffix='.safetensors', delete=True) as file:
        save_file(model.state_dict(), file.name)
        size = Path(file.name).stat().st_size / 1e9
        print(f"Checkpoint size: {size:.1f}GB")
        old_name, old_ext = info.moshi_weights.name.rsplit('.', 1)
        new_name = old_name + '.q8.' + old_ext
        api.upload_file(
            path_or_fileobj=file.name,
            path_in_repo=new_name,
            repo_id=new_repo,
            repo_type="model")
    config = json.load(open(hf_hub_download(repo, 'config.json')))
    config['moshi_name'] = new_name
    config['quantize'] = True
    if not config['mimi_name'].startswith('hf://'):
        config['mimi_name'] = f'hf://{repo}/{config["mimi_name"]}'
    if not config['tokenizer_name'].startswith('hf://'):
        config['tokenizer_name'] = f'hf://{repo}/{config["tokenizer_name"]}'
    with tempfile.NamedTemporaryFile(mode='w') as file:
        json.dump(config, file, indent=2)
        file.flush()
        api.upload_file(
            path_or_fileobj=file.name,
            path_in_repo='config.json',
            repo_id=new_repo,
            repo_type="model")


    def transcribe(self, ref_audio, language=None):
        return transcribe(ref_audio, language)


    def get_output_video_path(self, name):
        os.makedirs(f"{self.work_path}/output_videos", exist_ok=True)
        return f"{self.work_path}/output_videos/{name}"


def get_requirements(path: str):
    return [l.strip() for l in open(path)]


def process_audio():
    with st.spinner(t("Generate audio tasks")):
        _8_1_audio_task.gen_audio_task_main()
        _8_2_dub_chunks.gen_dub_chunks()
    with st.spinner(t("Extract refer audio")):
        _9_refer_audio.extract_refer_audio_main()
    with st.spinner(t("Generate all audio")):
        _10_gen_audio.gen_audio()
    with st.spinner(t("Merge full audio")):
        _11_merge_audio.merge_full_audio()
    with st.spinner(t("Merge dubbing to the video")):
        _12_dub_to_vid.merge_video_audio()

    st.success(t("Audio processing complete! 🎇"))
    st.balloons()


async def test_scrape_method_unsupported_backend():
    """Test that the scrape method raises a ValueError when an unsupported backend is provided."""
    loader = ChromiumLoader(["http://example.com"], backend="unsupported")
    with pytest.raises(ValueError):
        await loader.scrape("http://example.com")


    def _load_tools(self) -> List[Dict[str, Any]]:
        """
        Dynamically load all tool classes from the tools directory.
        If a dependency is missing, prompt the user to install it via uvpackagemanager.

        Returns:
            A list of tools (dicts) containing their 'name', 'description', and 'input_schema'.
        """
        tools = []
        tools_path = getattr(Config, 'TOOLS_DIR', None)

        if tools_path is None:
            self.console.print("[red]TOOLS_DIR not set in Config[/red]")
            return tools

        # Clear cached tool modules for fresh import
        for module_name in list(sys.modules.keys()):
            if module_name.startswith('tools.') and module_name != 'tools.base':
                del sys.modules[module_name]

        try:
            for module_info in pkgutil.iter_modules([str(tools_path)]):
                if module_info.name == 'base':
                    continue

                # Attempt loading the tool module
                try:
                    module = importlib.import_module(f'tools.{module_info.name}')
                    self._extract_tools_from_module(module, tools)
                except ImportError as e:
                    # Handle missing dependencies
                    missing_module = self._parse_missing_dependency(str(e))
                    self.console.print(f"\n[yellow]Missing dependency:[/yellow] {missing_module} for tool {module_info.name}")
                    user_response = input(f"Would you like to install {missing_module}? (y/n): ").lower()

                    if user_response == 'y':
                        success = self._execute_uv_install(missing_module)
                        if success:
                            # Retry loading the module after installation
                            try:
                                module = importlib.import_module(f'tools.{module_info.name}')
                                self._extract_tools_from_module(module, tools)
                            except Exception as retry_err:
                                self.console.print(f"[red]Failed to load tool after installation: {str(retry_err)}[/red]")
                        else:
                            self.console.print(f"[red]Installation of {missing_module} failed. Skipping this tool.[/red]")
                    else:
                        self.console.print(f"[yellow]Skipping tool {module_info.name} due to missing dependency[/yellow]")
                except Exception as mod_err:
                    self.console.print(f"[red]Error loading module {module_info.name}:[/red] {str(mod_err)}")
        except Exception as overall_err:
            self.console.print(f"[red]Error in tool loading process:[/red] {str(overall_err)}")

        return tools


	def get_EndCreateTime(self):
		return self.get_query_params().get('EndCreateTime')


def _is_explicitly_marked(mark_name: str, metafunc: Metafunc) -> bool:
  if hasattr(metafunc.function, 'pytestmark'):
    for mark in metafunc.function.pytestmark:
      if mark.name == 'parametrize' and mark.args[0] == mark_name:
        return True
  return False


    def __init__(self, model: Transformer, tokenizer: Tokenizer):
        self.model = model
        self.tokenizer = tokenizer
        self.formatter = ChatFormat(tokenizer)


def create_mock_response(message, function_calls=[], model="gpt-4o"):
    role = message.get("role", "assistant")
    content = message.get("content", "")
    tool_calls = (
        [
            ChatCompletionMessageToolCall(
                id="mock_tc_id",
                type="function",
                function=Function(
                    name=call.get("name", ""),
                    arguments=json.dumps(call.get("args", {})),
                ),
            )
            for call in function_calls
        ]
        if function_calls
        else None
    )

    return ChatCompletion(
        id="mock_cc_id",
        created=1234567890,
        model=model,
        object="chat.completion",
        choices=[
            Choice(
                message=ChatCompletionMessage(
                    role=role, content=content, tool_calls=tool_calls
                ),
                finish_reason="stop",
                index=0,
            )
        ],
    )


def patched_init(self, scope, receive=None, send=None):
    if 'session' not in scope:
        scope['session'] = dict()
    _original_init(self, scope, receive, send)
    return


def print_logo():
    print("\033[96m" + CURSOR_LOGO + "\033[0m")
    print("\033[93m" + "Building Cursor Keep Alive...".center(56) + "\033[0m\n")


def pad_dataproto_to_divisor(data: "DataProto", size_divisor: int):
    """Pad a DataProto to size divisible by size_divisor

    Args:
        size_divisor (int): size divisor

    Returns:
        data: (DataProto): the padded DataProto
        pad_size (int)
    """
    assert isinstance(data, DataProto), "data must be a DataProto"
    if len(data) % size_divisor != 0:
        pad_size = size_divisor - len(data) % size_divisor
        padding_protos = []
        remaining_pad = pad_size
        while remaining_pad > 0:
            take_size = min(remaining_pad, len(data))
            padding_protos.append(data[:take_size])
            remaining_pad -= take_size
        data_padded = DataProto.concat([data] + padding_protos)
    else:
        if len(data) == 0:
            logging.warning("padding a DataProto with no item, no changed made")
        pad_size = 0
        data_padded = data
    return data_padded, pad_size


	def get_BeginCreateTime(self):
		return self.get_query_params().get('BeginCreateTime')


    def voice_creation(text, gender, pitch, speed):
        """
        Gradio callback to create a synthetic voice with adjustable parameters.
        - text: The input text for synthesis.
        - gender: 'male' or 'female'.
        - pitch/speed: Ranges mapped by LEVELS_MAP_UI.
        """
        pitch_val = LEVELS_MAP_UI[int(pitch)]
        speed_val = LEVELS_MAP_UI[int(speed)]
        audio_output_path = run_tts(
            text,
            model,
            gender=gender,
            pitch=pitch_val,
            speed=speed_val
        )
        return audio_output_path


def extract_gaussian(state: dict, req: gr.Request) -> Tuple[str, str]:
    """
    Extract a Gaussian file from the 3D model.

    Args:
        state (dict): The state of the generated 3D model.

    Returns:
        str: The path to the extracted Gaussian file.
    """
    user_dir = os.path.join(TMP_DIR, str(req.session_hash))
    gs, _ = unpack_state(state)
    gaussian_path = os.path.join(user_dir, 'sample.ply')
    gs.save_ply(gaussian_path)
    torch.cuda.empty_cache()
    return gaussian_path, gaussian_path


async def test_exclude_no_types():
    """Test normal behavior when no types are excluded (baseline test)."""
    graphiti = Graphiti(NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD)

    try:
        await graphiti.build_indices_and_constraints()

        entity_types = {
            'Person': Person,
            'Organization': Organization,
        }

        # Don't exclude any types
        result = await graphiti.add_episode(
            name='Normal Behavior',
            episode_body='Alice Smith works at TechCorp.',
            source_description='Normal test',
            reference_time=datetime.now(timezone.utc),
            entity_types=entity_types,
            excluded_entity_types=None,  # No exclusions
            group_id='test_exclude_none',
        )

        assert result is not None

        # Search for nodes - should find entities of all types
        search_results = await graphiti.search_(
            query='Alice Smith TechCorp', group_ids=['test_exclude_none']
        )

        found_nodes = search_results.nodes
        assert len(found_nodes) > 0, 'Should have found some entities'

        # Should have both Person and Organization entities
        person_nodes = [n for n in found_nodes if 'Person' in n.labels]
        org_nodes = [n for n in found_nodes if 'Organization' in n.labels]

        assert len(person_nodes) > 0, 'Should have found Person entities'
        assert len(org_nodes) > 0, 'Should have found Organization entities'

        # Clean up
        await _cleanup_test_nodes(graphiti, 'test_exclude_none')

    finally:
        await graphiti.close()


def load_data():
    dirname = "cifar-10-batches-py"
    origin = "http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz"
    path = get_file(dirname, origin=origin, untar=True)

    nb_test_samples = 10000
    nb_train_samples = 50000

    X_train = np.zeros((nb_train_samples, 3, 32, 32), dtype="uint8")
    y_train = np.zeros((nb_train_samples,), dtype="uint8")

    for i in range(1, 6):
        fpath = os.path.join(path, 'data_batch_' + str(i))
        data, labels = load_batch(fpath)
        X_train[(i-1)*10000:i*10000, :, :, :] = data
        y_train[(i-1)*10000:i*10000] = labels

    fpath = os.path.join(path, 'test_batch')
    X_test, y_test = load_batch(fpath)

    y_train = np.reshape(y_train, (len(y_train), 1))
    y_test = np.reshape(y_test, (len(y_test), 1))

    return (X_train, y_train), (X_test, y_test)


def test(
        weights=ROOT / 'yolo.pt',  # weights path
        imgsz=640,  # inference size (pixels)
        batch_size=1,  # batch size
        data=ROOT / 'data/coco128.yaml',  # dataset.yaml path
        device='',  # cuda device, i.e. 0 or 0,1,2,3 or cpu
        half=False,  # use FP16 half-precision inference
        test=False,  # test exports only
        pt_only=False,  # test PyTorch only
        hard_fail=False,  # throw error on benchmark failure
):
    y, t = [], time.time()
    device = select_device(device)
    for i, (name, f, suffix, gpu) in export.export_formats().iterrows():  # index, (name, file, suffix, gpu-capable)
        try:
            w = weights if f == '-' else \
                export.run(weights=weights, imgsz=[imgsz], include=[f], device=device, half=half)[-1]  # weights
            assert suffix in str(w), 'export failed'
            y.append([name, True])
        except Exception:
            y.append([name, False])  # mAP, t_inference

    # Print results
    LOGGER.info('\n')
    parse_opt()
    notebook_init()  # print system info
    py = pd.DataFrame(y, columns=['Format', 'Export'])
    LOGGER.info(f'\nExports complete ({time.time() - t:.2f}s)')
    LOGGER.info(str(py))
    return py


    def __delitem__(self, i):
        """Detect list del events and emit change events."""
        list.__delitem__(self, i)
        self.changed()


def test_execute_tools_false(mock_openai_client: MockOpenAIClient):
    expected_location = "San Francisco"

    # set up mock to record function calls
    get_weather_mock = Mock()

    def get_weather(location):
        get_weather_mock(location=location)
        return "It's sunny today."

    agent = Agent(name="Test Agent", functions=[get_weather])
    messages = [
        {"role": "user", "content": "What's the weather like in San Francisco?"}
    ]

    # set mock to return a response that triggers function call
    mock_openai_client.set_sequential_responses(
        [
            create_mock_response(
                message={"role": "assistant", "content": ""},
                function_calls=[
                    {"name": "get_weather", "args": {"location": expected_location}}
                ],
            ),
            create_mock_response(
                {"role": "assistant", "content": DEFAULT_RESPONSE_CONTENT}
            ),
        ]
    )

    # set up client and run
    client = Swarm(client=mock_openai_client)
    response = client.run(agent=agent, messages=messages, execute_tools=False)
    print(response)

    # assert function not called
    get_weather_mock.assert_not_called()

    # assert tool call is present in last response
    tool_calls = response.messages[-1].get("tool_calls")
    assert tool_calls is not None and len(tool_calls) == 1
    tool_call = tool_calls[0]
    assert tool_call["function"]["name"] == "get_weather"
    assert json.loads(tool_call["function"]["arguments"]) == {
        "location": expected_location
    }


    def test_string_translate(self):
        m = str.maketrans({"a": "X", "e": "Y", "i": None})
        self.check_func(lambda x: x.str.translate(m))


  def _CheckConfigureNetwork(self):
    """Enables RNDIS and configures it, retrying until we have connectivity."""
    force = False
    for _ in range(3):
      device_iface, host_iface = self._CheckEnableRndis(force)
      self._ConfigureNetwork(device_iface, host_iface)
      self.OverrideRoutingPolicy()
      # Sometimes the first packet will wake up the connection.
      for _ in range(3):
        if self._TestConnectivity():
          return
      force = True
    self.RestoreRoutingPolicy()
    raise Exception('No connectivity, giving up.')


  def test_multiple_handlers(self):
    perf_stream = StringIO.StringIO("""
        0000 foo(bar)
        1234 BytecodeHandler:first
        5678 a::random::call<to>(something, else)
        9abc BytecodeHandler:second
        def0 otherIrrelevant(stuff)
        1111 entrypoint
    """)
    callchains = list(ipr.collapsed_callchains_generator(perf_stream, False))
    self.assertListEqual(callchains, [
      ["foo", "BytecodeHandler:first", "[interpreter]"],
    ])


def check_env_file():
    """
    检查.env文件是否存在，如果不存在则发出警告
    返回True表示应该继续执行，False表示应该退出
    """
    if not os.path.exists(".env"):
        warning_msg = "警告: 当前目录中没有找到.env文件，这可能会影响存储配置的加载。"
        ASCIIColors.yellow(warning_msg)

        # 检查是否在交互式终端中运行
        if sys.stdin.isatty():
            response = input("是否继续执行? (yes/no): ")
            if response.lower() != "yes":
                ASCIIColors.red("测试程序已取消")
                return False
    return True


    def __image_clicked_cb(self, button):
        if self._preview_palette is None:
            self._preview_palette = get_preview_palette(
                self._api, self.data, relative_to=button)
        self._preview_palette.show()


def normalize_image(x):
    """Rescale image pixels to span range [0, 1]
    """
    ma = float(x.max().cpu().data)
    mi = float(x.min().cpu().data)
    d = ma - mi if ma != mi else 1e5
    return (x - mi) / d


    def test_atomic_min_uint64(self):
        self.check_atomic_min(dtype=np.uint64, lo=0, hi=65535)


    def do_event(self, event):
        shortcuts = {
            'a': (self.get_toplevel().goto_sublist,
                  ['/u/{}'.format(self.data['author'])]),
        }
        if self.data.get('subreddit'):
            shortcuts['s'] = (
                self.get_toplevel().goto_sublist,
                ['/r/{}'.format(self.data['subreddit'])],
            )
        return process_shortcuts(shortcuts, event)


def audio_processing_section():
    st.header(t("c. Dubbing"))
    with st.container(border=True):
        st.markdown(f"""

        {t("This stage includes the following steps:")}

            1. {t("Generate audio tasks and chunks")}

            2. {t("Extract reference audio")}

            3. {t("Generate and merge audio files")}

            4. {t("Merge final audio into video")}
        """, unsafe_allow_html=True)
        if not os.path.exists(DUB_VIDEO):
            if st.button(t("Start Audio Processing"), key="audio_processing_button"):
                process_audio()
                st.rerun()
        else:
            st.success(t("Audio processing is complete! You can check the audio files in the `output` folder."))
            if load_key("burn_subtitles"):
                st.video(DUB_VIDEO)
            if st.button(t("Delete dubbing files"), key="delete_dubbing_files"):
                delete_dubbing_files()
                st.rerun()
            if st.button(t("Archive to 'history'"), key="cleanup_in_audio_processing"):
                cleanup()
                st.rerun()


def allow_model_requests():
    with pydantic_ai.models.override_allow_model_requests(True):
        yield


    def test_from_array_int_event(surv_arrays):
        event, time = surv_arrays

        expected = numpy.empty(dtype=[('event', bool), ('time', float)], shape=100)
        expected['event'] = event.astype(bool)
        expected['time'] = time

        y = Surv.from_arrays(event, time)
        assert_array_equal(y, expected)


    def set_hardcoded_usage(self, usage: Usage):
        self.hardcoded_usage = usage


def _update_previous_errors(
    previous_errors: List[Flake8Error], replacement_window: Tuple[int, int], replacement_n_lines: int
) -> List[Flake8Error]:
    """Update the line numbers of the previous errors to what they would be after the edit window.
    This is a helper function for `_filter_previous_errors`.

    All previous errors that are inside of the edit window should not be ignored,
    so they are removed from the previous errors list.

    Args:
        previous_errors: list of errors with old line numbers
        replacement_window: the window of the edit/lines that will be replaced
        replacement_n_lines: the number of lines that will be used to replace the text

    Returns:
        list of errors with updated line numbers
    """
    updated = []
    lines_added = replacement_n_lines - (replacement_window[1] - replacement_window[0] + 1)
    for error in previous_errors:
        if error.line_number < replacement_window[0]:
            # no need to adjust the line number
            updated.append(error)
            continue
        if replacement_window[0] <= error.line_number <= replacement_window[1]:
            # The error is within the edit window, so let's not ignore it
            # either way (we wouldn't know how to adjust the line number anyway)
            continue
        # We're out of the edit window, so we need to adjust the line number
        updated.append(Flake8Error(error.filename, error.line_number + lines_added, error.col_number, error.problem))
    return updated


    def mock_fun(_m=""):
        return "mock"


def get_arch_info(a):
    return (a.cc, a.update_flags, a.writeback, copy_ctypes_list(a.operands[:a.op_count]))


        def on_update(rng):
            if not rng:
                del self.headers['content-range']
            else:
                self.headers['Content-Range'] = rng.to_header()


  def testDelegateUploadFileToObjectGzipEncodedComposite(self, mock_lock):
    mock_stream = mock.Mock()
    mock_stream.close = mock.Mock()

    def DelegateUpload():
      # Ensure the lock was not aquired before the delegate was called.
      self.assertFalse(mock_lock.__enter__.called)
      return 'a', 'b'

    elapsed_time, uploaded_object = _DelegateUploadFileToObject(
        DelegateUpload, 'url', mock_stream, False, True, True, None)
    # Ensure results are passed through.
    self.assertEqual(elapsed_time, 'a')
    self.assertEqual(uploaded_object, 'b')
    # Ensure close was called.
    self.assertTrue(mock_stream.close.called)
    # Ensure the lock was released.
    self.assertFalse(mock_lock.__exit__.called)


    def _load_func(index):
        y, name = ground_truth[index], images[index]
        im = imread(archive.extractfile(name), num_channels=3)
        x = _resize_image(im, args.width, args.height, args.mode == 'padding')
        return x, np.array([y]).astype(np.int32)


def qa_generator():
    """Process chat history CSV files to generate Q&A pair datasets."""
    from weclone.data.qa_generator import DataProcessor

    processor = DataProcessor()
    processor.main()


def act_quant(x: torch.Tensor, block_size: int = 128) -> Tuple[torch.Tensor, torch.Tensor]:
    """
    Quantizes the input tensor `x` using block-wise quantization.

    Args:
        x (torch.Tensor): The input tensor to be quantized. Must be contiguous and its last dimension size must be divisible by `block_size`.
        block_size (int, optional): The size of the blocks to be used for quantization. Default is 128.

    Returns:
        Tuple[torch.Tensor, torch.Tensor]: A tuple containing:
            - The quantized tensor with dtype `torch.float8_e4m3fn`.
            - A tensor of scaling factors with dtype `torch.float32`.
    """
    assert x.is_contiguous(), 'Input tensor must be contiguous'
    assert x.size(-1) % block_size == 0, f'Last dimension size must be divisible by block_size (block_size={block_size})'
    y = torch.empty_like(x, dtype=torch.float8_e4m3fn)
    s = x.new_empty(*x.size()[:-1], x.size(-1) // block_size, dtype=torch.float32)
    grid = lambda meta: (triton.cdiv(x.numel(), meta['BLOCK_SIZE']), )
    act_quant_kernel[grid](x, y, s, BLOCK_SIZE=block_size)
    return y, s


def setup_logging():
    """Configure logging system to output logs to file, memory queue, and console"""
    # Create logs directory (if it doesn't exist)
    logs_dir = os.path.join(os.path.dirname(__file__), "logs")
    os.makedirs(logs_dir, exist_ok=True)

    # Generate log filename (using current date)
    current_date = datetime.datetime.now().strftime("%Y-%m-%d")
    log_file = os.path.join(logs_dir, f"gradio_log_{current_date}.txt")

    # Configure root logger (captures all logs)
    root_logger = logging.getLogger()

    # Clear existing handlers to avoid duplicate logs
    for handler in root_logger.handlers[:]:
        root_logger.removeHandler(handler)

    root_logger.setLevel(logging.INFO)

    # Create file handler
    file_handler = logging.FileHandler(log_file, encoding="utf-8", mode="a")
    file_handler.setLevel(logging.INFO)

    # Create console handler
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)

    # Create formatter
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)

    # Add handlers to root logger
    root_logger.addHandler(file_handler)
    root_logger.addHandler(console_handler)

    logging.info("Logging system initialized, log file: %s", log_file)
    return log_file


def resize_img():
	dirs = os.listdir("split_pic//6")
	for filename in dirs:
		im = tf.gfile.FastGFile("split_pic//6//{}".format(filename), 'rb').read()
		# print("正在处理第%d张照片"%counter)
		with tf.Session() as sess:
			img_data = tf.image.decode_jpeg(im)
			image_float = tf.image.convert_image_dtype(img_data, tf.float32)
			resized = tf.image.resize_images(image_float, [64, 64], method=3)
			resized_im = resized.eval()
			# new_mat = np.asarray(resized_im).reshape(1, 64, 64, 3)
			scipy.misc.imsave("resized_img6//{}".format(filename),resized_im)


def load_module(m):
    global module_in_gpu

    if module_in_gpu == m:
        return

    unload_module()

    model_memory = memory_management.module_size(m)
    current_free_mem = memory_management.get_free_memory(gpu)
    inference_memory = 1.5 * 1024 * 1024 * 1024  # memory_management.minimum_inference_memory() # TODO: connect to main memory system
    estimated_remaining_memory = current_free_mem - model_memory - inference_memory

    print(f"[Memory Management] Current Free GPU Memory: {current_free_mem / (1024 * 1024):.2f} MB")
    print(f"[Memory Management] Required Model Memory: {model_memory / (1024 * 1024):.2f} MB")
    print(f"[Memory Management] Required Inference Memory: {inference_memory / (1024 * 1024):.2f} MB")
    print(f"[Memory Management] Estimated Remaining GPU Memory: {estimated_remaining_memory / (1024 * 1024):.2f} MB")

    is_torch_jit = 'ScriptModule' in type(m).__name__

    if is_torch_jit:
        print(f'Detected torch jit module: {type(m).__name__}')

    if (ALWAYS_SWAP or estimated_remaining_memory < 0) and not is_torch_jit:
        print(f'Move module to SWAP: {type(m).__name__}')
        DynamicSwapInstaller.install_model(m, target_device=gpu)
        model_gpu_memory_when_using_cpu_swap = memory_management.compute_model_gpu_memory_when_using_cpu_swap(current_free_mem, inference_memory)
        greedy_move_to_gpu(m, model_gpu_memory_when_using_cpu_swap)
    else:
        print(f'Move module to GPU: {type(m).__name__}')
        m.to(gpu)

    module_in_gpu = m
    return


def mock_vcr_aiohttp_content(mocker: MockerFixture):
    try:
        from vcr.stubs import aiohttp_stubs
    except ImportError:
        return

    # google-genai calls `self.response_stream.content.readline()` where `self.response_stream` is a `MockClientResponse`,
    # which creates a new `MockStream` each time instead of returning the same one, resulting in the readline cursor not being respected.
    # So we turn `content` into a cached property to return the same one each time.
    # VCR issue: https://github.com/kevin1024/vcrpy/issues/927. Once that's is resolved, we can remove this patch.
    cached_content = cached_property(aiohttp_stubs.MockClientResponse.content.fget)  # type: ignore
    cached_content.__set_name__(aiohttp_stubs.MockClientResponse, 'content')
    mocker.patch('vcr.stubs.aiohttp_stubs.MockClientResponse.content', new=cached_content)
    mocker.patch('vcr.stubs.aiohttp_stubs.MockStream.set_exception', return_value=None)


    def files(self):
        if len(self.metapartitions) > 1:
            raise AttributeError(
                "Accessing `files` attribute is not allowed while nested"
            )
        return self.metapartitions[0]["files"]


def get_models(name: str, device: torch.device, offload: bool, is_schnell: bool):
    t5 = load_t5(device, max_length=256 if is_schnell else 512)
    clip = load_clip(device)
    model = load_flow_model(name, device="cpu" if offload else device)
    ae = load_ae(name, device="cpu" if offload else device)
    nsfw_classifier = pipeline("image-classification", model="Falconsai/nsfw_image_detection", device=device)
    return model, ae, t5, clip, nsfw_classifier


        def fget(self):
            def on_update(header_set):
                if not header_set and name in self.headers:
                    del self.headers[name]
                elif header_set:
                    self.headers[name] = header_set.to_header()
            return parse_set_header(self.headers.get(name), on_update)


def load_env_vars():
    """Load environment variables and return as dictionary format

    Returns:
        dict: Environment variable dictionary, each value is a tuple containing value and source (value, source)
    """
    dotenv_path = init_env_file()
    load_dotenv(dotenv_path, override=True)

    # Read environment variables from .env file
    env_file_vars = {}
    with open(dotenv_path, "r") as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#"):
                if "=" in line:
                    key, value = line.split("=", 1)
                    env_file_vars[key.strip()] = value.strip().strip("\"'")

    # Get from system environment variables
    system_env_vars = {
        k: v
        for k, v in os.environ.items()
        if k not in env_file_vars and k not in WEB_FRONTEND_ENV_VARS
    }

    # Merge environment variables and mark sources
    env_vars = {}

    # Add system environment variables (lowest priority)
    for key, value in system_env_vars.items():
        env_vars[key] = (value, "System")

    # Add .env file environment variables (medium priority)
    for key, value in env_file_vars.items():
        env_vars[key] = (value, ".env file")

    # Add frontend configured environment variables (highest priority)
    for key, value in WEB_FRONTEND_ENV_VARS.items():
        env_vars[key] = (value, "Frontend configuration")
        # Ensure operating system environment variables are also updated
        os.environ[key] = value

    return env_vars


    def plot_containment_vs_energy(
        self, ax=None, fractions=[0.68, 0.8, 0.95], **kwargs
    ):
        """Plot containment versus energy."""
        import matplotlib.pyplot as plt

        ax = plt.gca() if ax is None else ax

        for fraction in fractions:
            rad = self.containment_radius(self.energy, fraction)
            label = f"{100 * fraction:.1f}% Containment"
            ax.plot(self.energy.value, rad.value, label=label, **kwargs)

        ax.semilogx()
        ax.legend(loc="best")
        ax.set_xlabel("Energy (GeV)")
        ax.set_ylabel("Containment radius (deg)")


    def __init__(self, translator=None):
        self.translator = translator
        self.accounts_file = 'cursor_accounts.txt'


    def __init__(self, max_debate_rounds=1, max_risk_discuss_rounds=1):
        """Initialize with configuration parameters."""
        self.max_debate_rounds = max_debate_rounds
        self.max_risk_discuss_rounds = max_risk_discuss_rounds


    def prepare_inputs(batch):
        inp = dict()
        x = batch.pop("video")
        y = batch.pop("text")
        bs = x.shape[0]

        # == encode video ==
        with nsys.range("encode_video"), timers["encode_video"]:
            # == prepare condition ==
            if cfg.get("condition_config", None) is not None:
                # condition for i2v & v2v
                x_0, cond = prepare_visual_condition(x, cfg.condition_config, model_ae)
                cond = pack(cond, patch_size=cfg.get("patch_size", 2))
                inp["cond"] = cond
            else:
                if cfg.get("cached_video", False):
                    x_0 = batch.pop("video_latents").to(device=device, dtype=dtype)
                else:
                    x_0 = model_ae.encode(x)

        # == prepare timestep ==
        # follow SD3 time shift, shift_alpha = 1 for 256px and shift_alpha = 3 for 1024px
        shift_alpha = get_res_lin_function()((x_0.shape[-1] * x_0.shape[-2]) // 4)
        # add temporal influence
        shift_alpha *= math.sqrt(x_0.shape[-3])  # for image, T=1 so no effect
        t = torch.sigmoid(torch.randn((bs), device=device))
        t = time_shift(shift_alpha, t).to(dtype)

        if cfg.get("cached_text", False):
            # == encode text ==
            t5_embedding = batch.pop("text_t5").to(device=device, dtype=dtype)
            clip_embedding = batch.pop("text_clip").to(device=device, dtype=dtype)
            with nsys.range("encode_text"), timers["encode_text"]:
                inp_ = prepare_ids(x_0, t5_embedding, clip_embedding)
                inp.update(inp_)
                x_0 = pack(x_0, patch_size=cfg.get("patch_size", 2))
        else:
            # == encode text ==
            with nsys.range("encode_text"), timers["encode_text"]:
                inp_ = prepare(
                    model_t5,
                    model_clip,
                    x_0,
                    prompt=y,
                    seq_align=seq_align,
                    patch_size=cfg.get("patch_size", 2),
                )
                inp.update(inp_)
                x_0 = pack(x_0, patch_size=cfg.get("patch_size", 2))

        # == dropout ==
        if cfg.get("dropout_ratio", None) is not None:
            cur_null_txt = null_txt
            num_pad_null_txt = inp["txt"].shape[1] - cur_null_txt.shape[1]
            if num_pad_null_txt > 0:
                cur_null_txt = torch.cat([cur_null_txt] + [cur_null_txt[:, -1:]] * num_pad_null_txt, dim=1)
            inp["txt"] = dropout_condition(
                cfg.dropout_ratio.get("t5", 0.0),
                inp["txt"],
                cur_null_txt,
            )
            inp["y_vec"] = dropout_condition(
                cfg.dropout_ratio.get("clip", 0.0),
                inp["y_vec"],
                null_vec,
            )

        # == prepare noise vector ==
        x_1 = torch.randn_like(x_0, dtype=torch.float32).to(device, dtype)
        t_rev = 1 - t
        x_t = t_rev[:, None, None] * x_0 + (1 - (1 - sigma_min) * t_rev[:, None, None]) * x_1
        inp["img"] = x_t
        inp["timesteps"] = t.to(dtype)
        inp["guidance"] = torch.full((x_t.shape[0],), cfg.get("guidance", 4), device=x_t.device, dtype=x_t.dtype)

        return inp, x_0, x_1


    def test_engine_distinction(self):
        """Test that cache distinguishes between different translation engines"""
        cache1 = cache.TranslationCache("engine1")
        cache2 = cache.TranslationCache("engine2")

        # Set same text with different engines
        cache1.set("hello", "你好 1")
        cache2.set("hello", "你好 2")

        # Verify each engine gets its own translation
        self.assertEqual(cache1.get("hello"), "你好 1")
        self.assertEqual(cache2.get("hello"), "你好 2")


def test_asr_pipeline_conversion(test_audio_path):
    """Test ASR pipeline conversion using whisper_turbo model on sample_10s.mp3."""
    # Check if the test audio file exists
    assert test_audio_path.exists(), f"Test audio file not found: {test_audio_path}"

    converter = get_asr_converter()

    # Convert the audio file
    doc_result: ConversionResult = converter.convert(test_audio_path)

    # Verify conversion was successful
    assert doc_result.status == ConversionStatus.SUCCESS, (
        f"Conversion failed with status: {doc_result.status}"
    )

    # Verify we have a document
    assert doc_result.document is not None, "No document was created"

    # Verify we have text content (transcribed audio)
    texts = doc_result.document.texts
    assert len(texts) > 0, "No text content found in transcribed audio"

    # Print transcribed text for verification (optional, for debugging)
    print(f"Transcribed text from {test_audio_path.name}:")
    for i, text_item in enumerate(texts):
        print(f"  {i + 1}: {text_item.text}")


    def system_methodHelp(self, method_name):
        """system.methodHelp('add') => "Adds two integers together"

        Returns a string containing documentation for the specified method."""

        method = None
        if method_name in self.funcs:
            method = self.funcs[method_name]
        elif self.instance is not None:
            # Instance can implement _methodHelp to return help for a method
            if hasattr(self.instance, '_methodHelp'):
                return self.instance._methodHelp(method_name)
            # if the instance has a _dispatch method then we
            # don't have enough information to provide help
            elif not hasattr(self.instance, '_dispatch'):
                try:
                    method = resolve_dotted_attribute(
                                self.instance,
                                method_name,
                                self.allow_dotted_names
                                )
                except AttributeError:
                    pass

        # Note that we aren't checking that the method actually
        # be a callable object of some kind
        if method is None:
            return ""
        else:
            return pydoc.getdoc(method)


    def test_1d_slicing4(self, flags=enable_pyobj_flags):
        pyfunc = slicing_1d_usecase4
        arraytype = types.Array(types.int32, 1, 'C')
        argtys = (arraytype,)
        cr = compile_isolated(pyfunc, argtys, flags=flags)
        cfunc = cr.entry_point

        a = np.arange(10, dtype='i4')
        self.assertEqual(pyfunc(a), cfunc(a))

        # Any
        arraytype = types.Array(types.int32, 1, 'A')
        argtys = (arraytype,)
        cr = compile_isolated(pyfunc, argtys, flags=flags)
        cfunc = cr.entry_point

        a = np.arange(20, dtype='i4')[::2]
        self.assertFalse(a.flags['C_CONTIGUOUS'])
        self.assertFalse(a.flags['F_CONTIGUOUS'])
        self.assertEqual(pyfunc(a), cfunc(a))


def check_nvidia_gpu():
    install_package("pynvml")
    import pynvml
    from translations.translations import translate as t
    initialized = False
    try:
        pynvml.nvmlInit()
        initialized = True
        device_count = pynvml.nvmlDeviceGetCount()
        if device_count > 0:
            print(t("Detected NVIDIA GPU(s)"))
            for i in range(device_count):
                handle = pynvml.nvmlDeviceGetHandleByIndex(i)
                name = pynvml.nvmlDeviceGetName(handle)
                print(f"GPU {i}: {name}")
            return True
        else:
            print(t("No NVIDIA GPU detected"))
            return False
    except pynvml.NVMLError:
        print(t("No NVIDIA GPU detected or NVIDIA drivers not properly installed"))
        return False
    finally:
        if initialized:
            pynvml.nvmlShutdown()


    def show_boxes(self, img, target):
        bbox_np = target.bbox.data.cpu().numpy()
        # print('image shape:', img.size())
        np_img = np.transpose(np.uint8(img.data.cpu().numpy()), (1, 2, 0))
        img_pil = Image.fromarray(np_img)
        # print('bbox_np:', bbox_np)
        draw_img = vis_image(img_pil, bbox_np)
        draw_img.save('gt_show.jpg', 'jpeg')
        polys = target.get_field('masks')
        # print('polys:', polys.polygons)
        mask_gt = vis_masks(polys.polygons, img_pil.size)
        mask_gt.save('gt_show_masks.jpg', 'jpeg')

        # print('Sleep for show...')
        time.sleep(2)


def extract_port_from_command(cmd: str, server_type: str) -> int:
    port_match = re.search(r"--port[= ](\d+)", cmd)
    if port_match:
        return int(port_match.group(1))
    return SERVER_DEFAULTS.get(server_type, ServerConfig("", [], 8000)).default_port


  def test_calculate_samples_count_per_callchain(self):
    counters = ipr.calculate_samples_count_per_callchain([
      ["foo", "BytecodeHandler:bar"],
      ["foo", "BytecodeHandler:bar"],
      ["beep", "BytecodeHandler:bar"],
      ["hello", "v8::internal::Compiler", "[compiler]"],
    ])
    self.assertItemsEqual(counters, [
      ('BytecodeHandler:bar;foo', 2),
      ('BytecodeHandler:bar;beep', 1),
      ('[compiler];v8::internal::Compiler;hello', 1),
    ])


    def test_removes_fragment(self):
        """Fragment should be removed per RFC 8707."""
        assert resource_url_from_server_url("https://example.com/path#fragment") == "https://example.com/path"
        assert resource_url_from_server_url("https://example.com/#fragment") == "https://example.com/"


    def test_from_array_event_value_wrong_4(surv_arrays):
        event, time = surv_arrays
        event[1] = 3

        with pytest.raises(ValueError,
                           match="event indicator must be binary"):
            Surv.from_arrays(event, time)


    def test_hillclimb(self):
        # arrange
        initial_alignment = AlignmentInfo((0, 3, 2), None, None, None)

        def neighboring_mock(a, j):
            if a.alignment == (0, 3, 2):
                return set(
                    [
                        AlignmentInfo((0, 2, 2), None, None, None),
                        AlignmentInfo((0, 1, 1), None, None, None),
                    ]
                )
            elif a.alignment == (0, 2, 2):
                return set(
                    [
                        AlignmentInfo((0, 3, 3), None, None, None),
                        AlignmentInfo((0, 4, 4), None, None, None),
                    ]
                )
            return set()

        def prob_t_a_given_s_mock(a):
            prob_values = {
                (0, 3, 2): 0.5,
                (0, 2, 2): 0.6,
                (0, 1, 1): 0.4,
                (0, 3, 3): 0.6,
                (0, 4, 4): 0.7,
            }
            return prob_values.get(a.alignment, 0.01)

        ibm_model = IBMModel([])
        ibm_model.neighboring = neighboring_mock
        ibm_model.prob_t_a_given_s = prob_t_a_given_s_mock

        # act
        best_alignment = ibm_model.hillclimb(initial_alignment)

        # assert: hill climbing goes from (0, 3, 2) -> (0, 2, 2) -> (0, 4, 4)
        self.assertEqual(best_alignment.alignment, (0, 4, 4))


async def computer():
    """Shared Computer instance for all test cases."""
    # Create a remote Linux computer with C/ua
    computer = Computer(
        os_type="linux",
        api_key=os.getenv("CUA_API_KEY"),
        name=str(os.getenv("CUA_CONTAINER_NAME")),
        provider_type=VMProviderType.CLOUD,
    )

    # Create a local macOS computer with C/ua
    # computer = Computer()

    # Connect to host computer
    # computer = Computer(use_host_computer_server=True)

    try:
        await computer.run()
        yield computer
    finally:
        await computer.disconnect()


  def get_prior_mean(self):
    """If un-chunked data is available, set initial level to the first value."""
    with variable_scope.variable_scope(self._variable_scope):
      if self._input_statistics is not None:
        # TODO(allenl): Better support for multivariate series here.
        initial_value = array_ops.stack([
            math_ops.reduce_mean(
                self._scale_data(
                    self._input_statistics.series_start_moments.mean)),
            0.
        ])
        return initial_value + variable_scope.get_variable(
            name="prior_state_mean",
            shape=initial_value.get_shape(),
            initializer=init_ops.zeros_initializer(),
            dtype=self.dtype,
            trainable=self._configuration.trainable_start_state)
      else:
        return super(AdderStateSpaceModel, self).get_prior_mean()


    def hvac_action(self):
        """Return current operation ie. heat, cool, idle."""
        return self._hvac_action


def gradio_demo(
    target_dir,
    conf_thres=3.0,
    frame_filter="All",
    mask_black_bg=False,
    mask_white_bg=False,
    show_cam=True,
    mask_sky=False,
    prediction_mode="Pointmap Regression",
):
    """
    Perform reconstruction using the already-created target_dir/images.
    """
    if not os.path.isdir(target_dir) or target_dir == "None":
        return None, "No valid target directory found. Please upload first.", None, None

    start_time = time.time()
    gc.collect()
    torch.cuda.empty_cache()

    # Prepare frame_filter dropdown
    target_dir_images = os.path.join(target_dir, "images")
    all_files = sorted(os.listdir(target_dir_images)) if os.path.isdir(target_dir_images) else []
    all_files = [f"{i}: {filename}" for i, filename in enumerate(all_files)]
    frame_filter_choices = ["All"] + all_files

    print("Running run_model...")
    with torch.no_grad():
        predictions = run_model(target_dir, model)

    # Save predictions
    prediction_save_path = os.path.join(target_dir, "predictions.npz")
    np.savez(prediction_save_path, **predictions)

    # Handle None frame_filter
    if frame_filter is None:
        frame_filter = "All"

    # Build a GLB file name
    glbfile = os.path.join(
        target_dir,
        f"glbscene_{conf_thres}_{frame_filter.replace('.', '_').replace(':', '').replace(' ', '_')}_maskb{mask_black_bg}_maskw{mask_white_bg}_cam{show_cam}_sky{mask_sky}_pred{prediction_mode.replace(' ', '_')}.glb",
    )

    # Convert predictions to GLB
    glbscene = predictions_to_glb(
        predictions,
        conf_thres=conf_thres,
        filter_by_frames=frame_filter,
        mask_black_bg=mask_black_bg,
        mask_white_bg=mask_white_bg,
        show_cam=show_cam,
        mask_sky=mask_sky,
        target_dir=target_dir,
        prediction_mode=prediction_mode,
    )
    glbscene.export(file_obj=glbfile)

    # Cleanup
    del predictions
    gc.collect()
    torch.cuda.empty_cache()

    end_time = time.time()
    print(f"Total time: {end_time - start_time:.2f} seconds (including IO)")
    log_msg = f"Reconstruction Success ({len(all_files)} frames). Waiting for visualization."

    return glbfile, log_msg, gr.Dropdown(choices=frame_filter_choices, value=frame_filter, interactive=True)


    def filter(self, *args, **kwargs):
        """Apply filter for querying document

        Apply where filter as many as you want

        Parameters
        ---------
        args: Tuple
            Contain three things 1- field name, 2-operation, 3-value

        kwargs:
            keyword args Direct assign for equal filter

        Returns
        -------
        self:
            Return self object
        """
        if args:
            self.select_query.append(args)
        elif kwargs:
            for k, v in kwargs.items():
                self.select_query.append((k, '==', v))
        return self


    def digest(self):
        return msdcc.encrypt(self._data[:64], user=self._user).decode('hex')


def pytest_json_runtest_metadata(item, call):
    """Add model and case_id to pytest-json report metadata."""
    metadata = {}
    nodeid = item.nodeid

    # 1. Extract model from callspec if available
    model = item.callspec.params.get("model") if hasattr(item, "callspec") else None
    if model:
        metadata["model"] = model
    else:
        # Fallback: Try parsing from nodeid (less reliable)
        match_model = re.search(r"\[(.*?)-", nodeid)
        if match_model:
            model = match_model.group(1)  # Store model even if found via fallback
            metadata["model"] = model
        else:
            print(f"Warning: Could not determine model for test {nodeid}")
            model = None  # Ensure model is None if not found

    # 2. Extract case_id using the known model string if possible
    if model:
        # Construct a regex pattern to find the case_id *after* the model name and a hyphen.
        # Escape the model name in case it contains regex special characters.
        pattern = re.escape(model) + r"-(.*?)\]$"
        match_case = re.search(pattern, nodeid)
        if match_case:
            case_id = match_case.group(1)
            metadata["case_id"] = case_id
        else:
            # Fallback if the pattern didn't match (e.g., nodeid format unexpected)
            # Try the old less specific regex as a last resort.
            match_case_fallback = re.search(r"-(.*?)\]$", nodeid)
            if match_case_fallback:
                case_id = match_case_fallback.group(1)
                metadata["case_id"] = case_id
                print(f"Warning: Used fallback regex to parse case_id from nodeid {nodeid}")
            else:
                print(f"Warning: Could not parse case_id from nodeid {nodeid} even with fallback.")
                if "case" in (item.callspec.params if hasattr(item, "callspec") else {}):
                    metadata["case_id"] = "parsing_failed"
    elif "case" in (item.callspec.params if hasattr(item, "callspec") else {}):
        # Cannot reliably parse case_id without model, but we know it's a case test.
        # Try the generic fallback regex.
        match_case_fallback = re.search(r"-(.*?)\]$", nodeid)
        if match_case_fallback:
            case_id = match_case_fallback.group(1)
            metadata["case_id"] = case_id
            print(f"Warning: Used fallback regex to parse case_id from nodeid {nodeid} (model unknown)")
        else:
            print(f"Warning: Could not parse case_id from nodeid {nodeid} (model unknown)")
            metadata["case_id"] = "parsing_failed_no_model"
    # else: Not a test with a model or case param we need to handle.

    return metadata


def split_line(text: str) -> List[str]:
    """Split text into lines based on terminal width."""
    term_width = shutil.get_terminal_size().columns or 80
    if not text.strip():
        return []
    # Split by explicit newlines and wrap long lines
    lines = []
    for line in text.split('\n'):
        while len(line) > term_width:
            lines.append(line[:term_width])
            line = line[term_width:]
        if line:
            lines.append(line)
    return lines


    def __init__(self, name, value=None):
        RegistryValue.__init__(self, name, 'REG_MULTI_SZ', value)


def build_ui(model_dir, device=0):

    # Initialize model
    model = initialize_model(model_dir, device=device)

    # Define callback function for voice cloning
    def voice_clone(text, prompt_text, prompt_wav_upload, prompt_wav_record):
        """
        Gradio callback to clone voice using text and optional prompt speech.
        - text: The input text to be synthesised.
        - prompt_text: Additional textual info for the prompt (optional).
        - prompt_wav_upload/prompt_wav_record: Audio files used as reference.
        """
        prompt_speech = prompt_wav_upload if prompt_wav_upload else prompt_wav_record
        prompt_text_clean = None if len(prompt_text) < 2 else prompt_text

        audio_output_path = run_tts(
            text,
            model,
            prompt_text=prompt_text_clean,
            prompt_speech=prompt_speech
        )
        return audio_output_path

    # Define callback function for creating new voices
    def voice_creation(text, gender, pitch, speed):
        """
        Gradio callback to create a synthetic voice with adjustable parameters.
        - text: The input text for synthesis.
        - gender: 'male' or 'female'.
        - pitch/speed: Ranges mapped by LEVELS_MAP_UI.
        """
        pitch_val = LEVELS_MAP_UI[int(pitch)]
        speed_val = LEVELS_MAP_UI[int(speed)]
        audio_output_path = run_tts(
            text,
            model,
            gender=gender,
            pitch=pitch_val,
            speed=speed_val
        )
        return audio_output_path

    with gr.Blocks() as demo:
        # Use HTML for centered title
        gr.HTML('
Spark-TTS by SparkAudio
')
        with gr.Tabs():
            # Voice Clone Tab
            with gr.TabItem("Voice Clone"):
                gr.Markdown(
                    "### Upload reference audio or recording （上传参考音频或者录音）"
                )

                with gr.Row():
                    prompt_wav_upload = gr.Audio(
                        sources="upload",
                        type="filepath",
                        label="Choose the prompt audio file, ensuring the sampling rate is no lower than 16kHz.",
                    )
                    prompt_wav_record = gr.Audio(
                        sources="microphone",
                        type="filepath",
                        label="Record the prompt audio file.",
                    )

                with gr.Row():
                    text_input = gr.Textbox(
                        label="Text", lines=3, placeholder="Enter text here"
                    )
                    prompt_text_input = gr.Textbox(
                        label="Text of prompt speech (Optional; recommended for cloning in the same language.)",
                        lines=3,
                        placeholder="Enter text of the prompt speech.",
                    )

                audio_output = gr.Audio(
                    label="Generated Audio", autoplay=True, streaming=True
                )

                generate_buttom_clone = gr.Button("Generate")

                generate_buttom_clone.click(
                    voice_clone,
                    inputs=[
                        text_input,
                        prompt_text_input,
                        prompt_wav_upload,
                        prompt_wav_record,
                    ],
                    outputs=[audio_output],
                )

            # Voice Creation Tab
            with gr.TabItem("Voice Creation"):
                gr.Markdown(
                    "### Create your own voice based on the following parameters"
                )

                with gr.Row():
                    with gr.Column():
                        gender = gr.Radio(
                            choices=["male", "female"], value="male", label="Gender"
                        )
                        pitch = gr.Slider(
                            minimum=1, maximum=5, step=1, value=3, label="Pitch"
                        )
                        speed = gr.Slider(
                            minimum=1, maximum=5, step=1, value=3, label="Speed"
                        )
                    with gr.Column():
                        text_input_creation = gr.Textbox(
                            label="Input Text",
                            lines=3,
                            placeholder="Enter text here",
                            value="You can generate a customized voice by adjusting parameters such as pitch and speed.",
                        )
                        create_button = gr.Button("Create Voice")

                audio_output = gr.Audio(
                    label="Generated Audio", autoplay=True, streaming=True
                )
                create_button.click(
                    voice_creation,
                    inputs=[text_input_creation, gender, pitch, speed],
                    outputs=[audio_output],
                )

    return demo


    def from_dict(cls, conv_turn_dict: Dict):
        raw_retrieved_info = [
            Information.from_dict(info) for info in conv_turn_dict["raw_retrieved_info"]
        ]

        return cls(
            utterance=conv_turn_dict["utterance"],
            raw_utterance=conv_turn_dict["raw_utterance"],
            role=f"{conv_turn_dict['role']}: {conv_turn_dict['role_description']}",
            queries=conv_turn_dict["queries"],
            raw_retrieved_info=raw_retrieved_info,
            cited_info=None,
            utterance_type=conv_turn_dict["utterance_type"],
            claim_to_make=conv_turn_dict["claim_to_make"],
        )


    def __init__(self, locale, has_enough_context, thought, title, steps):
        self.locale = locale
        self.has_enough_context = has_enough_context
        self.thought = thought
        self.title = title
        self.steps = steps


    def initialize(self) -> None:
        """Initialize."""
        super().initialize()
        self.door_sensor = self.args["mail_door_sensor"]
        self.slot_sensor = self.args["mail_slot_sensor"]
        self.mail_status = self.args["mail_status"]
        self.state = self.get_state(self.mail_status)

        self.newState = ""
        self.just_opened_door = False
        self.just_notified = False

        self.listen_state(self.just_opened, self.args["door"])

        if "mail_slot_sensor" in self.args:
            self.listen_state(self.mailbox_opened, self.slot_sensor)
        if "mail_door_sensor" in self.args:
            self.listen_state(self.mailbox_opened, self.door_sensor)


    def _convert_write_data(self, tag, data_type, write_values):
        """
        In order to handle write requests that are larger than a single
        packet, we'll break up the values to write into multiple lists
        of values.  The size of each list will be calculated based on the
        connection size, length of the tag name and the data type.
        """
        # packet header is always 110 bytes
        packet_overhead = 110
        # calculate number of bytes tag name will occupy
        tag_length = len(tag) + len(tag) % 2
        # calculate the available space (in bytes) for the write values
        space_for_payload = self.ConnectionSize - packet_overhead - tag_length

        # calculate how many bytes per value are required
        bytes_per_value  = self.CIPTypes[data_type][0]
        # calculate the limit for values in each request
        limit = int(space_for_payload / bytes_per_value)
        # split the list up into multiple smaller lists
        chunks = [write_values[x:x+limit] for x in range(0, len(write_values), limit)]
        return chunks


def chat(prompt, model:str,llm_auth_token:str,llm_base_url:str,using_custom_llm=False,stream=True, debug=False):
    openai.base_url = "http://127.0.0.1:3040/v1/"

    if model == "gpt3.5":
        openai.base_url = "http://llm-freegpt35:3040/v1/"

    if model == "kimi":
        openai.base_url = "http://llm-kimi:8000/v1/"
    if model == "glm4":
        openai.base_url = "http://llm-glm4:8000/v1/"
    if model == "qwen":
        openai.base_url = "http://llm-qwen:8000/v1/"

    if llm_auth_token == '':
        llm_auth_token = "CUSTOM"

    openai.api_key = llm_auth_token

    if using_custom_llm:
        openai.base_url = llm_base_url
        openai.api_key = llm_auth_token

    total_content = ""
    for chunk in openai.chat.completions.create(
        model=model,
        messages=[{
            "role": "user",
            "content": prompt
        }],
        stream=True,
        max_tokens=1024,temperature=0.2
    ):
        stream_resp = chunk.dict()
        token = stream_resp["choices"][0]["delta"].get("content", "")
        if token:

            total_content += token
            yield token
    if debug:
        print(total_content)


def create_message_content(text, image_path=None):
    content = [{"type": "text", "text": text}]
    image_format = "png" if image_path and image_path.endswith(".png") else "jpeg"
    if image_path:
        from src.utils import utils
        image_data = utils.encode_image(image_path)
        content.append({
            "type": "image_url",
            "image_url": {"url": f"data:image/{image_format};base64,{image_data}"}
        })
    return content


def progress_bar(progress, total, prefix="", length=50):
    filled = int(length * progress // total)
    bar = "█" * filled + "░" * (length - filled)
    percent = f"{100 * progress / total:.1f}"
    print(f"\r{prefix} |{bar}| {percent}% Complete", end="", flush=True)
    if progress == total:
        print()


    def test_delitem_with_1_invalid_key(self):
        d = {
            'a': 1,
        }
        b = KeypathDict(d)
        with self.assertRaises(KeyError):
            del b['b']
        self.assertEqual(b.get('b'), None)


    def __init__(
        self,
        t3: T3,
        s3gen: S3Gen,
        ve: VoiceEncoder,
        tokenizer: EnTokenizer,
        device: str,
        conds: Conditionals = None,
    ):
        self.sr = S3GEN_SR  # sample rate of synthesized audio
        self.t3 = t3
        self.s3gen = s3gen
        self.ve = ve
        self.tokenizer = tokenizer
        self.device = device
        self.conds = conds
        self.watermarker = perth.PerthImplicitWatermarker()


  def _log_prob(self, x):
    x = control_flow_ops.with_dependencies([check_ops.assert_positive(x)] if
                                           self.validate_args else [], x)
    contrib_tensor_util.assert_same_float_dtype(tensors=[x],
                                                dtype=self.dtype)
    return (self.alpha * math_ops.log(self.beta) +
            (self.alpha - 1.) * math_ops.log(x) -
            self.beta * x -
            math_ops.lgamma(self.alpha))


    def __init__(self, serialport):
        self.serialport = serialport
        self.logger = logging.getLogger('umap2')
        self.reset()


  def testExecuteUpdateJobsSuccessMultiplePendingDepsOneCloudStorageCollision(
      self, uploader_cs_mock):
    uploader_cs_mock.Exists.side_effect = [False, True]
    self.fs.CreateFile(self.file_path,
                       contents='\n'.join(self.expected_file_lines))
    config = dependency_manager.BaseConfig(self.file_path, writable=True)
    config._config_data = self.final_dependencies.copy()
    config._pending_uploads = [self.new_pending_upload,
                               self.final_pending_upload]
    self.assertEqual(self.final_dependencies, config._config_data)
    self.assertTrue(config._IsDirty())
    self.assertEqual(2, len(config._pending_uploads))
    self.assertEqual(self.new_pending_upload, config._pending_uploads[0])
    self.assertEqual(self.final_pending_upload, config._pending_uploads[1])

    expected_exists_calls = [mock.call(self.new_bucket, self.new_remote_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path)]
    expected_insert_calls = [mock.call(self.new_bucket, self.new_remote_path,
                                       self.new_dep_path),
                             mock.call(self.final_bucket,
                                       self.final_remote_path,
                                       self.final_dep_path)]
    expected_copy_calls = [mock.call(self.final_bucket, self.final_bucket,
                                     self.final_remote_path,
                                     self.expected_final_backup_path)]

    self.assertTrue(config.ExecuteUpdateJobs(force=True))
    self.assertFalse(config._IsDirty())
    self.assertFalse(config._pending_uploads)
    self.assertEqual(self.final_dependencies, config._config_data)
    file_module = fake_filesystem.FakeFileOpen(self.fs)
    expected_file_lines = list(self.final_expected_file_lines)
    for line in file_module(self.file_path):
      self.assertEqual(expected_file_lines.pop(0), line.strip())
    self.fs.CloseOpenFile(file_module(self.file_path))
    self.assertFalse(config._pending_uploads)
    self.assertEqual(expected_insert_calls,
                     uploader_cs_mock.Insert.call_args_list)
    self.assertEqual(expected_exists_calls,
                     uploader_cs_mock.Exists.call_args_list)
    self.assertEqual(expected_copy_calls,
                     uploader_cs_mock.Copy.call_args_list)


def test_run_with_simple_message(mock_openai_client: MockOpenAIClient):
    agent = Agent()
    # set up client and run
    client = Swarm(client=mock_openai_client)
    messages = [{"role": "user", "content": "Hello, how are you?"}]
    response = client.run(agent=agent, messages=messages)

    # assert response content
    assert response.messages[-1]["role"] == "assistant"
    assert response.messages[-1]["content"] == DEFAULT_RESPONSE_CONTENT


def chat():
    data = request.json
    message = data.get('message', '')
    image_data = data.get('image')  # Get the base64 image data

    # Prepare the message content
    if image_data:
        # Create a message with both text and image in correct order
        message_content = [
            {
                "type": "image",
                "source": {
                    "type": "base64",
                    "media_type": "image/jpeg",  # We should detect this from the image
                    "data": image_data.split(',')[1] if ',' in image_data else image_data  # Remove data URL prefix if present
                }
            }
        ]

        # Only add text message if there is actual text
        if message.strip():
            message_content.append({
                "type": "text",
                "text": message
            })
    else:
        # Text-only message
        message_content = message

    try:
        # Handle the chat message with the appropriate content
        response = assistant.chat(message_content)

        # Get token usage from assistant
        token_usage = {
            'total_tokens': assistant.total_tokens_used,
            'max_tokens': Config.MAX_CONVERSATION_TOKENS
        }

        # Get the last used tool from the conversation history
        tool_name = None
        if assistant.conversation_history:
            for msg in reversed(assistant.conversation_history):
                if msg.get('role') == 'assistant' and msg.get('content'):
                    content = msg['content']
                    if isinstance(content, list):
                        for block in content:
                            if isinstance(block, dict) and block.get('type') == 'tool_use':
                                tool_name = block.get('name')
                                break
                    if tool_name:
                        break

        return jsonify({
            'response': response,
            'thinking': False,
            'tool_name': tool_name,
            'token_usage': token_usage
        })

    except Exception as e:
        return jsonify({
            'response': f"Error: {str(e)}",
            'thinking': False,
            'tool_name': None,
            'token_usage': None
        }), 200  # Return 200 even for errors to handle them gracefully in frontend


    def test_from_array_event_value_wrong_2(surv_arrays):
        event, time = surv_arrays
        event -= 1

        with pytest.raises(ValueError,
                           match="non-boolean event indicator must contain 0 and 1 only"):
            Surv.from_arrays(event, time)


def loader_with_dummy(monkeypatch):
    """Fixture returning a ChromiumLoader instance with dummy scraping methods patched."""
    urls = ["http://example.com", "http://test.com"]
    loader = ChromiumLoader(urls, backend="playwright", requires_js_support=False)
    monkeypatch.setattr(loader, "ascrape_playwright", dummy_scraper)
    monkeypatch.setattr(loader, "ascrape_with_js_support", dummy_scraper)
    monkeypatch.setattr(loader, "ascrape_undetected_chromedriver", dummy_scraper)
    return loader


def postprocess(speech, top_db=60, hop_length=220, win_length=440):
    speech, _ = librosa.effects.trim(
        speech, top_db=top_db,
        frame_length=win_length,
        hop_length=hop_length
    )
    if speech.abs().max() > max_val:
        speech = speech / speech.abs().max() * max_val
    speech = torch.concat([speech, torch.zeros(1, int(cosyvoice.sample_rate * 0.2))], dim=1)
    return speech


    def valGranuleUR(self, obj):
        """Function to add GranuleUR

        :param obj: element to add GranuleUR
        """
        values = []
        for i in self.parModis:
            values.append(i.retGranuleUR())
        for i in set(values):
            gur = self.ElementTree.SubElement(obj, 'GranuleUR')
            gur.text = i


    def test_preserves_query(self):
        """Query parameters should be preserved."""
        assert resource_url_from_server_url("https://example.com/path?foo=bar") == "https://example.com/path?foo=bar"
        assert resource_url_from_server_url("https://example.com/?key=value") == "https://example.com/?key=value"


def load_llama3_tokenizer():
    """
    https://github.com/huggingface/transformers/issues/22794#issuecomment-2092623992
    """
    tokenizer_name = "meta-llama/Llama-3.2-1B"
    tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
    bos = tokenizer.bos_token
    eos = tokenizer.eos_token
    tokenizer._tokenizer.post_processor = TemplateProcessing(
        single=f"{bos}:0 $A:0 {eos}:0",
        pair=f"{bos}:0 $A:0 {eos}:0 {bos}:1 $B:1 {eos}:1",
        special_tokens=[(f"{bos}", tokenizer.bos_token_id), (f"{eos}", tokenizer.eos_token_id)],
    )

    return tokenizer


def main(
    ckpt_dir: str,
    tokenizer_path: str,
    temperature: float = 0.6,
    top_p: float = 0.9,
    max_seq_len: int = 128,
    max_gen_len: int = 64,
    max_batch_size: int = 4,
):
    """
    Examples to run with the pre-trained models (no fine-tuning). Prompts are
    usually in the form of an incomplete text prefix that the model can then try to complete.

    The context window of llama3 models is 8192 tokens, so `max_seq_len` needs to be <= 8192.
    `max_gen_len` is needed because pre-trained models usually do not stop completions naturally.
    """
    generator = Llama.build(
        ckpt_dir=ckpt_dir,
        tokenizer_path=tokenizer_path,
        max_seq_len=max_seq_len,
        max_batch_size=max_batch_size,
    )

    prompts: List[str] = [
        # For these prompts, the expected answer is the natural continuation of the prompt
        "I believe the meaning of life is",
        "Simply put, the theory of relativity states that ",
        """A brief message congratulating the team on the launch:

        Hi everyone,

        I just """,
        # Few shot prompt (providing a few examples before asking model to complete more);
        """Translate English to French:

        sea otter => loutre de mer
        peppermint => menthe poivrée
        plush girafe => girafe peluche
        cheese =>""",
    ]
    results = generator.text_completion(
        prompts,
        max_gen_len=max_gen_len,
        temperature=temperature,
        top_p=top_p,
    )
    for prompt, result in zip(prompts, results):
        print(prompt)
        print(f"> {result['generation']}")
        print("\n==================================\n")


	def history(self):
		""" Return an iterator over Row-tasks which iterates over all the
		tasks in existence, sorted by their date of creation."""
		c = self.connection.cursor()
		c.execute("""
			SELECT t.*, c.path as ctx_path
			FROM Task t JOIN Context c
			ON t.context = c.id
			ORDER BY t.created
		""")
		return c


    def current_humidity(self):
        """Return the current humidity."""
        return self._current_humidity


def process(input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache, mp4_crf):
    global stream
    assert input_image is not None, 'No input image!'

    yield None, None, '', '', gr.update(interactive=False), gr.update(interactive=True)

    stream = AsyncStream()

    async_run(worker, input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache, mp4_crf)

    output_filename = None

    while True:
        flag, data = stream.output_queue.next()

        if flag == 'file':
            output_filename = data
            yield output_filename, gr.update(), gr.update(), gr.update(), gr.update(interactive=False), gr.update(interactive=True)

        if flag == 'progress':
            preview, desc, html = data
            yield gr.update(), gr.update(visible=True, value=preview), desc, html, gr.update(interactive=False), gr.update(interactive=True)

        if flag == 'end':
            yield output_filename, gr.update(visible=False), gr.update(), '', gr.update(interactive=True), gr.update(interactive=False)
            break


def main():
    torch.set_grad_enabled(False)
    # ======================================================
    # configs & runtime variables
    # ======================================================
    # == parse configs ==
    cfg = parse_configs()

    # == get dtype & device ==
    dtype = to_torch_dtype(cfg.get("dtype", "bf16"))
    device = "cuda" if torch.cuda.is_available() else "cpu"
    if is_distributed():
        colossalai.launch_from_torch({})
        device = get_current_device()
    set_seed(cfg.get("seed", 1024))

    # == init logger ==
    logger = create_logger()
    logger.info("Inference configuration:\n %s", pformat(cfg.to_dict()))
    verbose = cfg.get("verbose", 1)

    # ======================================================
    # build model & loss
    # ======================================================
    if cfg.get("ckpt_path", None) is not None:
        cfg.model.from_pretrained = cfg.ckpt_path
    logger.info("Building models...")
    model = build_module(cfg.model, MODELS, device_map=device, torch_dtype=dtype).eval()
    log_model_params(model)

    # ======================================================
    # build dataset and dataloader
    # ======================================================
    logger.info("Building dataset...")
    # == build dataset ==
    dataset = build_module(cfg.dataset, DATASETS)
    logger.info("Dataset contains %s samples.", len(dataset))
    # == build dataloader ==
    dataloader_args = dict(
        dataset=dataset,
        batch_size=cfg.get("batch_size", None),
        num_workers=cfg.get("num_workers", 4),
        seed=cfg.get("seed", 1024),
        shuffle=False,
        drop_last=False,
        pin_memory=True,
        process_group=get_data_parallel_group(),
        prefetch_factor=cfg.get("prefetch_factor", None),
    )

    if cfg.get("eval_setting", None) is not None:
        # e.g. 32x256x256, 1x1024x1024
        num_frames = int(cfg.eval_setting.split("x")[0])
        resolution = str(cfg.eval_setting.split("x")[-1])
        bucket_config = {
            resolution + "px_ar1:1": {num_frames: (1.0, 1)},
        }
        print("eval setting:\n", bucket_config)
    else:
        bucket_config = cfg.get("bucket_config", None)

    dataloader, _ = prepare_dataloader(
        bucket_config=bucket_config,
        num_bucket_build_workers=cfg.get("num_bucket_build_workers", 1),
        **dataloader_args,
    )
    dataiter = iter(dataloader)
    num_steps_per_epoch = len(dataloader)

    # ======================================================
    # inference
    # ======================================================
    num_samples = 0
    running_sum = running_var = 0.0

    # Iter over the dataset
    with tqdm(
        enumerate(dataiter),
        disable=not is_main_process() or verbose < 1,
        total=num_steps_per_epoch,
        initial=0,
    ) as pbar:
        for _, batch in pbar:
            # == load data ==
            x = batch["video"].to(device, dtype)  # [B, C, T, H, W]

            # == vae encoding & decoding ===
            z = model.encode(x)

            num_samples += 1
            running_sum += z.mean().item()
            running_var += (z - running_sum / num_samples).pow(2).mean().item()
            shift = running_sum / num_samples
            scale = (running_var / num_samples) ** 0.5
            pbar.set_postfix({"mean": shift, "std": scale})

    logger.info("Mean: %.4f, std: %.4f", shift, scale)
    log_cuda_max_memory("inference")


def main():
    parser = argparse.ArgumentParser(description="Chat with MiniMind")
    parser.add_argument('--lora_name', default='None', type=str)
    parser.add_argument('--out_dir', default='out', type=str)
    parser.add_argument('--temperature', default=0.85, type=float)
    parser.add_argument('--top_p', default=0.85, type=float)
    parser.add_argument('--device', default='cuda' if torch.cuda.is_available() else 'cpu', type=str)
    # 此处max_seq_len（最大输出长度）并不意味模型具有对应的长文本的性能，仅防止QA出现被截断的问题
    # MiniMind2-moe (145M)：(hidden_size=640, num_hidden_layers=8, use_moe=True)
    # MiniMind2-Small (26M)：(hidden_size=512, num_hidden_layers=8)
    # MiniMind2 (104M)：(hidden_size=768, num_hidden_layers=16)
    parser.add_argument('--hidden_size', default=512, type=int)
    parser.add_argument('--num_hidden_layers', default=8, type=int)
    parser.add_argument('--max_seq_len', default=8192, type=int)
    parser.add_argument('--use_moe', default=False, type=bool)
    # 携带历史对话上下文条数
    # history_cnt需要设为偶数，即【用户问题, 模型回答】为1组；设置为0时，即当前query不携带历史上文
    # 模型未经过外推微调时，在更长的上下文的chat_template时难免出现性能的明显退化，因此需要注意此处设置
    parser.add_argument('--history_cnt', default=0, type=int)
    parser.add_argument('--load', default=0, type=int, help="0: 原生torch权重，1: transformers加载")
    parser.add_argument('--model_mode', default=1, type=int,
                        help="0: 预训练模型，1: SFT-Chat模型，2: RLHF-Chat模型，3: Reason模型，4: RLAIF-Chat模型")
    args = parser.parse_args()

    model, tokenizer = init_model(args)

    prompts = get_prompt_datas(args)
    test_mode = int(input('[0] 自动测试\n[1] 手动输入\n'))
    streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)

    messages = []
    for idx, prompt in enumerate(prompts if test_mode == 0 else iter(lambda: input('👶: '), '')):
        setup_seed(random.randint(0, 2048))
        # setup_seed(2025)  # 如需固定每次输出则换成【固定】的随机种子
        if test_mode == 0: print(f'👶: {prompt}')

        messages = messages[-args.history_cnt:] if args.history_cnt else []
        messages.append({"role": "user", "content": prompt})

        new_prompt = tokenizer.apply_chat_template(
            messages,
            tokenize=False,
            add_generation_prompt=True
        ) if args.model_mode != 0 else (tokenizer.bos_token + prompt)

        inputs = tokenizer(
            new_prompt,
            return_tensors="pt",
            truncation=True
        ).to(args.device)

        print('🤖: ', end='')
        generated_ids = model.generate(
            inputs["input_ids"],
            max_new_tokens=args.max_seq_len,
            num_return_sequences=1,
            do_sample=True,
            attention_mask=inputs["attention_mask"],
            pad_token_id=tokenizer.pad_token_id,
            eos_token_id=tokenizer.eos_token_id,
            streamer=streamer,
            top_p=args.top_p,
            temperature=args.temperature
        )

        response = tokenizer.decode(generated_ids[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
        messages.append({"role": "assistant", "content": response})
        print('\n\n')


    def __repr__(self):
        return self.__class__.__name__ + ' (' \
               + str(self.in_features) + ' -> ' \
               + str(self.out_features) + ')'


    def do_event(self, event):
        shortcuts = {
            'u': (self._sbb.vote, [+1]),
            'd': (self._sbb.vote, [-1]),
            'n': (self._sbb.vote, [0]),
            'c': (self.goto_comments.emit, []),
            'a': (self.get_toplevel().goto_sublist,
                  ['/u/{}'.format(self.data['author'])]),
            's': (self.get_toplevel().goto_sublist,
                  ['/r/{}'.format(self.data['subreddit'])]),
        }
        return process_shortcuts(shortcuts, event)


def generate():
    try:
        # Set global variable
        global GENERATING
        GENERATING = True

        # Clean
        clean_dir("../temp/")
        clean_dir("../subtitles/")

        # Parse JSON
        data = request.get_json()
        paragraph_number = int(data.get('paragraphNumber', 1))  # Default to 1 if not provided
        ai_model = data.get('aiModel')  # Get the AI model selected by the user
        n_threads = data.get('threads')  # Amount of threads to use for video generation
        subtitles_position = data.get('subtitlesPosition')  # Position of the subtitles in the video
        text_color = data.get('color') # Color of subtitle text

        # Get 'useMusic' from the request data and default to False if not provided
        use_music = data.get('useMusic', False)

        # Get 'automateYoutubeUpload' from the request data and default to False if not provided
        automate_youtube_upload = data.get('automateYoutubeUpload', False)

        # Get the ZIP Url of the songs
        songs_zip_url = data.get('zipUrl')

        # Download songs
        if use_music:
            # Downloads a ZIP file containing popular TikTok Songs
            if songs_zip_url:
                fetch_songs(songs_zip_url)
            else:
                # Default to a ZIP file containing popular TikTok Songs
                fetch_songs("https://filebin.net/2avx134kdibc4c3q/drive-download-20240209T180019Z-001.zip")

        # Print little information about the video which is to be generated
        print(colored("[Video to be generated]", "blue"))
        print(colored("   Subject: " + data["videoSubject"], "blue"))
        print(colored("   AI Model: " + ai_model, "blue"))  # Print the AI model being used
        print(colored("   Custom Prompt: " + data["customPrompt"], "blue"))  # Print the AI model being used

        if not GENERATING:
            return jsonify(
                {
                    "status": "error",
                    "message": "Video generation was cancelled.",
                    "data": [],
                }
            )

        voice = data["voice"]
        voice_prefix = voice[:2]

        if not voice:
            print(colored("[!] No voice was selected. Defaulting to \"en_us_001\"", "yellow"))
            voice = "en_us_001"
            voice_prefix = voice[:2]

        # Generate a script
        script = generate_script(data["videoSubject"], paragraph_number, ai_model, voice, data["customPrompt"])  # Pass the AI model to the script generation

        # Generate search terms
        search_terms = get_search_terms(
            data["videoSubject"], AMOUNT_OF_STOCK_VIDEOS, script, ai_model
        )

        # Search for a video of the given search term
        video_urls = []

        # Defines how many results it should query and search through
        it = 15

        # Defines the minimum duration of each clip
        min_dur = 10

        # Loop through all search terms,
        # and search for a video of the given search term
        for search_term in search_terms:
            if not GENERATING:
                return jsonify(
                    {
                        "status": "error",
                        "message": "Video generation was cancelled.",
                        "data": [],
                    }
                )
            found_urls = search_for_stock_videos(
                search_term, os.getenv("PEXELS_API_KEY"), it, min_dur
            )
            # Check for duplicates
            for url in found_urls:
                if url not in video_urls:
                    video_urls.append(url)
                    break

        # Check if video_urls is empty
        if not video_urls:
            print(colored("[-] No videos found to download.", "red"))
            return jsonify(
                {
                    "status": "error",
                    "message": "No videos found to download.",
                    "data": [],
                }
            )

        # Define video_paths
        video_paths = []

        # Let user know
        print(colored(f"[+] Downloading {len(video_urls)} videos...", "blue"))

        # Save the videos
        for video_url in video_urls:
            if not GENERATING:
                return jsonify(
                    {
                        "status": "error",
                        "message": "Video generation was cancelled.",
                        "data": [],
                    }
                )
            try:
                saved_video_path = save_video(video_url)
                video_paths.append(saved_video_path)
            except Exception:
                print(colored(f"[-] Could not download video: {video_url}", "red"))

        # Let user know
        print(colored("[+] Videos downloaded!", "green"))

        # Let user know
        print(colored("[+] Script generated!\n", "green"))

        if not GENERATING:
            return jsonify(
                {
                    "status": "error",
                    "message": "Video generation was cancelled.",
                    "data": [],
                }
            )

        # Split script into sentences
        sentences = script.split(". ")

        # Remove empty strings
        sentences = list(filter(lambda x: x != "", sentences))
        paths = []

        # Generate TTS for every sentence
        for sentence in sentences:
            if not GENERATING:
                return jsonify(
                    {
                        "status": "error",
                        "message": "Video generation was cancelled.",
                        "data": [],
                    }
                )
            current_tts_path = f"../temp/{uuid4()}.mp3"
            tts(sentence, voice, filename=current_tts_path)
            audio_clip = AudioFileClip(current_tts_path)
            paths.append(audio_clip)

        # Combine all TTS files using moviepy
        final_audio = concatenate_audioclips(paths)
        tts_path = f"../temp/{uuid4()}.mp3"
        final_audio.write_audiofile(tts_path)

        try:
            subtitles_path = generate_subtitles(audio_path=tts_path, sentences=sentences, audio_clips=paths, voice=voice_prefix)
        except Exception as e:
            print(colored(f"[-] Error generating subtitles: {e}", "red"))
            subtitles_path = None

        # Concatenate videos
        temp_audio = AudioFileClip(tts_path)
        combined_video_path = combine_videos(video_paths, temp_audio.duration, 5, n_threads or 2)

        # Put everything together
        try:
            final_video_path = generate_video(combined_video_path, tts_path, subtitles_path, n_threads or 2, subtitles_position, text_color or "#FFFF00")
        except Exception as e:
            print(colored(f"[-] Error generating final video: {e}", "red"))
            final_video_path = None

        # Define metadata for the video, we will display this to the user, and use it for the YouTube upload
        title, description, keywords = generate_metadata(data["videoSubject"], script, ai_model)

        print(colored("[-] Metadata for YouTube upload:", "blue"))
        print(colored("   Title: ", "blue"))
        print(colored(f"   {title}", "blue"))
        print(colored("   Description: ", "blue"))
        print(colored(f"   {description}", "blue"))
        print(colored("   Keywords: ", "blue"))
        print(colored(f"  {', '.join(keywords)}", "blue"))

        if automate_youtube_upload:
            # Start Youtube Uploader
            # Check if the CLIENT_SECRETS_FILE exists
            client_secrets_file = os.path.abspath("./client_secret.json")
            SKIP_YT_UPLOAD = False
            if not os.path.exists(client_secrets_file):
                SKIP_YT_UPLOAD = True
                print(colored("[-] Client secrets file missing. YouTube upload will be skipped.", "yellow"))
                print(colored("[-] Please download the client_secret.json from Google Cloud Platform and store this inside the /Backend directory.", "red"))

            # Only proceed with YouTube upload if the toggle is True  and client_secret.json exists.
            if not SKIP_YT_UPLOAD:
                # Choose the appropriate category ID for your videos
                video_category_id = "28"  # Science & Technology
                privacyStatus = "private"  # "public", "private", "unlisted"
                video_metadata = {
                    'video_path': os.path.abspath(f"../temp/{final_video_path}"),
                    'title': title,
                    'description': description,
                    'category': video_category_id,
                    'keywords': ",".join(keywords),
                    'privacyStatus': privacyStatus,
                }

                # Upload the video to YouTube
                try:
                    # Unpack the video_metadata dictionary into individual arguments
                    video_response = upload_video(
                        video_path=video_metadata['video_path'],
                        title=video_metadata['title'],
                        description=video_metadata['description'],
                        category=video_metadata['category'],
                        keywords=video_metadata['keywords'],
                        privacy_status=video_metadata['privacyStatus']
                    )
                    print(f"Uploaded video ID: {video_response.get('id')}")
                except HttpError as e:
                    print(f"An HTTP error {e.resp.status} occurred:\n{e.content}")

        video_clip = VideoFileClip(f"../temp/{final_video_path}")
        if use_music:
            # Select a random song
            song_path = choose_random_song()

            # Add song to video at 30% volume using moviepy
            original_duration = video_clip.duration
            original_audio = video_clip.audio
            song_clip = AudioFileClip(song_path).set_fps(44100)

            # Set the volume of the song to 10% of the original volume
            song_clip = song_clip.volumex(0.1).set_fps(44100)

            # Add the song to the video
            comp_audio = CompositeAudioClip([original_audio, song_clip])
            video_clip = video_clip.set_audio(comp_audio)
            video_clip = video_clip.set_fps(30)
            video_clip = video_clip.set_duration(original_duration)
            video_clip.write_videofile(f"../{final_video_path}", threads=n_threads or 1)
        else:
            video_clip.write_videofile(f"../{final_video_path}", threads=n_threads or 1)

        # Let user know
        print(colored(f"[+] Video generated: {final_video_path}!", "green"))

        # Stop FFMPEG processes
        if os.name == "nt":
            # Windows
            os.system("taskkill /f /im ffmpeg.exe")
        else:
            # Other OS
            os.system("pkill -f ffmpeg")

        GENERATING = False

        # Return JSON
        return jsonify(
            {
                "status": "success",
                "message": "Video generated! See MoneyPrinter/output.mp4 for result.",
                "data": final_video_path,
            }
        )
    except Exception as err:
        print(colored(f"[-] Error: {str(err)}", "red"))
        return jsonify(
            {
                "status": "error",
                "message": f"Could not retrieve stock videos: {str(err)}",
                "data": [],
            }
        )


def get_notebooks_dir() -> Path:
    return (Path(__file__).parent.parent / "notebooks").resolve()


def create_prompt(user_input: str) -> str:
    conversation = [
        {
            "role": "User",
            "content": user_input,
        },
        {"role": "Assistant", "content": ""},
    ]

    sft_format = vl_chat_processor.apply_sft_template_for_multi_turn_prompts(
        conversations=conversation,
        sft_format=vl_chat_processor.sft_format,
        system_prompt="",
    )
    prompt = sft_format + vl_chat_processor.image_start_tag
    return prompt


def test_print():
    print(lerobot.available_envs)
    print(lerobot.available_tasks_per_env)
    print(lerobot.available_datasets)
    print(lerobot.available_datasets_per_env)
    print(lerobot.available_real_world_datasets)
    print(lerobot.available_policies)
    print(lerobot.available_policies_per_env)


    def find_window(self, wid):
        window = self.windows_map.get(wid)
        if window:
            if not window.group.screen:
                self.current_screen.set_group(window.group)
            window.group.focus(window, False)


def get_map(self) -> Mapping[_FileObject, SelectorKey]: ...


def create_app():
    app = Flask(__name__)

    # Initialize database connection
    try:
        DatabaseSession.initialize()
        logger.info("Database connection initialized successfully")

    except Exception as e:
        logger.error(f"Failed to initialize database connection: {str(e)}")
        raise

        # Add CORS support

    @app.after_request
    def after_request(response):
        # Allow all origins in development environment
        response.headers.add("Access-Control-Allow-Origin", "*")
        response.headers.add(
            "Access-Control-Allow-Headers", "Content-Type,Authorization"
        )
        response.headers.add(
            "Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS"
        )
        return response

    # Create file server handler
    file_handler = FileServerHandler(
        os.path.join(os.getenv("APP_ROOT", "/app"), "resources", "raw_content")
    )

    @app.route("/raw_content/", defaults={"path": ""})
    @app.route("/raw_content/<path:path>")
    def serve_content(path=""):
        return file_handler.handle_request(path, request.path)

    # Register all routes
    init_routes(app)

    # Clean up database connection only when the application shuts down
    @app.teardown_appcontext
    def cleanup_db(exception):
        pass

    return app