Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
1ddf94f
changes for using fsspec in non-sdk experiment functions
deep1401 Nov 3, 2025
3123544
bump versions
deep1401 Nov 3, 2025
ea34b24
fix dataset bug for locally uploaded files and convert dataset to use…
deep1401 Nov 3, 2025
2089faa
change everything in shared.py
deep1401 Nov 3, 2025
6495513
ruff
deep1401 Nov 3, 2025
970d1e5
Merge branch 'main' into add/use-fsspec
deep1401 Nov 3, 2025
b767e25
fsspec for export
deep1401 Nov 3, 2025
c010015
Merge branch 'add/use-fsspec' of https://github.com/transformerlab/tr…
deep1401 Nov 3, 2025
a2b227f
changes for diffusion
deep1401 Nov 3, 2025
ac76bcb
convert for train, tasks and serverinfo routers
deep1401 Nov 3, 2025
2567e1b
convert for tasks library
deep1401 Nov 3, 2025
b72177b
remove blockages limiting to a local filesystem and use posixpath
deep1401 Nov 3, 2025
8625df7
More changes in shared and for the model router
deep1401 Nov 3, 2025
9848ac1
fix bugs
deep1401 Nov 3, 2025
ec87cb8
fix
deep1401 Nov 3, 2025
94ab13a
major changes for rag.py
deep1401 Nov 3, 2025
0dfdab3
add changes for conversations
deep1401 Nov 3, 2025
da94868
add changes for documents
deep1401 Nov 3, 2025
7e4de16
add changes for experiment router
deep1401 Nov 3, 2025
cf2a6c5
add changes for evals router
deep1401 Nov 3, 2025
2471579
add changes for export router
deep1401 Nov 3, 2025
0b577bf
add changes for generations router
deep1401 Nov 3, 2025
f3db4be
add changes for jobs router and fix bugs
deep1401 Nov 3, 2025
b158367
remove imports
deep1401 Nov 3, 2025
b2fc928
make changes for local models
deep1401 Nov 3, 2025
d7ed38f
security and fixes
deep1401 Nov 3, 2025
5618d07
use fsspec for prompt log and audio uploads in fastchat_openai_api
deep1401 Nov 3, 2025
5cb18ff
changes for api.py
deep1401 Nov 3, 2025
0c63e34
fix merge conflicts
deep1401 Nov 4, 2025
367ba06
fix merge conflicts
deep1401 Nov 4, 2025
65ec773
convert plugin sdk - evals
deep1401 Nov 4, 2025
52be6dd
convert plugin sdk - generate
deep1401 Nov 4, 2025
249c290
convert plugin sdk - train
deep1401 Nov 4, 2025
1531ad3
convert plugin sdk - tlab_plugin and plugin
deep1401 Nov 4, 2025
efd0a12
add changes for common eleuther plugins
deep1401 Nov 4, 2025
85e25ac
add changes for eleuther plugins
deep1401 Nov 4, 2025
11149c3
make changes to diffusion_trainer
deep1401 Nov 4, 2025
3768630
make changes to dpo orpo trainer
deep1401 Nov 4, 2025
5e4d4a9
changes for embedding_model_trainer
deep1401 Nov 4, 2025
1356465
changes for gguf_exporter
deep1401 Nov 4, 2025
38d136e
changes for grpo multi gpu trainer
deep1401 Nov 4, 2025
a993275
changes for image_diffusion
deep1401 Nov 4, 2025
0289764
changes for llama_trainer and llama_trainer_multi_gpu
deep1401 Nov 4, 2025
c65a2f5
changes for llamafile exporter
deep1401 Nov 4, 2025
15f20e6
changes to rag plugin
deep1401 Nov 4, 2025
b5203f5
changes to mlx audio plugin
deep1401 Nov 4, 2025
7fe1ed7
changes to mlx lora trainer
deep1401 Nov 4, 2025
5239a0b
Merge branch 'main' of https://github.com/transformerlab/transformerl…
deep1401 Nov 4, 2025
738d819
changes to mlx rlaif trainer
deep1401 Nov 4, 2025
9b3403d
changes to ollama server
deep1401 Nov 4, 2025
2054d90
changes to reward modelling llama factory
deep1401 Nov 4, 2025
d43bf2c
changes to sft llama factory
deep1401 Nov 4, 2025
5607e3f
changes to synthesize_docs
deep1401 Nov 4, 2025
08d332f
changes to synthetic dataset kit
deep1401 Nov 4, 2025
c3156fe
changes to synthetic_dataset_rag
deep1401 Nov 4, 2025
da1dfab
changes to t5 lora trainer
deep1401 Nov 4, 2025
38f28b2
changes to unsloth grpo trainer
deep1401 Nov 4, 2025
d143076
changes to unsloth tts trainer
deep1401 Nov 4, 2025
a31739a
changes to unsloth tts server
deep1401 Nov 4, 2025
1ee6c0a
changes to vllm server
deep1401 Nov 4, 2025
5b4cec9
changes to vlm trainer
deep1401 Nov 4, 2025
083aece
ruff
deep1401 Nov 4, 2025
f894a81
add changes for wd14_captioner
deep1401 Nov 4, 2025
c1de567
add changes for yourbench_data_gen
deep1401 Nov 4, 2025
f3fa72f
test fixes
deep1401 Nov 4, 2025
9f466b6
disable mounting
deep1401 Nov 4, 2025
092f25c
fix bugs saying experiment with id experiments not found
deep1401 Nov 4, 2025
667ae36
ruff
deep1401 Nov 4, 2025
af5e4f2
Merge branch 'main' into add/use-fsspec
deep1401 Nov 4, 2025
30e851c
Merge branch 'main' into add/use-fsspec
deep1401 Nov 5, 2025
f158ade
merge conflict
deep1401 Nov 5, 2025
0949e63
make new things use fsspec
deep1401 Nov 5, 2025
70ada68
merge conflict
deep1401 Nov 6, 2025
62ca327
changes converted to fsspec based on new model loading fixes
deep1401 Nov 6, 2025
6a50d3b
Merge branch 'main' into add/use-fsspec
deep1401 Nov 10, 2025
aa08774
add new methods to also use the fsspec storage api
deep1401 Nov 11, 2025
5df7a13
merge conflicts
deep1401 Nov 11, 2025
ce74f50
apply changes to three new routes
deep1401 Nov 11, 2025
a55d136
Merge branch 'main' of https://github.com/transformerlab/transformerl…
deep1401 Nov 11, 2025
8abe740
update version
deep1401 Nov 11, 2025
f74d17d
update all new things to use fsspec
deep1401 Nov 11, 2025
4835ce0
fix merge conflicts
deep1401 Nov 12, 2025
a894a3d
fix merge conflicts
deep1401 Nov 12, 2025
81e9667
bump sdk
deep1401 Nov 12, 2025
dbb06ca
ruff
deep1401 Nov 12, 2025
bf0b59b
fix issue of mtime being float
deep1401 Nov 12, 2025
42a664e
merge conflicts
deep1401 Nov 14, 2025
3210f80
changes to fsspec for new code in conversations
deep1401 Nov 14, 2025
11307df
ruff
deep1401 Nov 14, 2025
5080d60
fix tests
deep1401 Nov 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions api.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
)
from transformerlab.shared.request_context import set_current_org_id
from lab.dirs import set_organization_id as lab_set_org_id
from lab import storage

from dotenv import load_dotenv

Expand All @@ -91,7 +92,7 @@
# to be overriden by the user.
os.environ["_TFL_SOURCE_CODE_DIR"] = dirs.TFL_SOURCE_CODE_DIR
# The temporary image directory for transformerlab (default; per-request overrides computed in routes)
temp_image_dir = os.path.join(get_workspace_dir(), "temp", "images")
temp_image_dir = storage.join(get_workspace_dir(), "temp", "images")
os.environ["TLAB_TEMP_IMAGE_DIR"] = str(temp_image_dir)

# Check if anything is stored in GPU_ORCHESTRATION_SERVER, and if so, print a message
Expand Down Expand Up @@ -243,7 +244,10 @@ async def validation_exception_handler(request, exc):

def spawn_fastchat_controller_subprocess():
global controller_process
logfile = open(os.path.join(dirs.FASTCHAT_LOGS_DIR, "controller.log"), "w")
controller_log_path = storage.join(dirs.FASTCHAT_LOGS_DIR, "controller.log")
# Note: subprocess requires a local file handle, so we use open() directly
# but construct the path using storage.join for workspace consistency
logfile = open(controller_log_path, "w")
port = "21001"

controller_process = subprocess.Popen(
Expand All @@ -254,7 +258,7 @@ def spawn_fastchat_controller_subprocess():
"--port",
port,
"--log-file",
os.path.join(dirs.FASTCHAT_LOGS_DIR, "controller.log"),
controller_log_path,
],
stdout=logfile,
stderr=logfile,
Expand Down Expand Up @@ -379,7 +383,7 @@ async def server_worker_start(

from lab.dirs import get_global_log_path

with open(get_global_log_path(), "a") as global_log:
with storage.open(get_global_log_path(), "a") as global_log:
global_log.write(f"🏃 Loading Inference Server for {model_name} with {inference_params}\n")

process = await shared.async_run_python_daemon_and_update_status(
Expand All @@ -392,7 +396,7 @@ async def server_worker_start(
if exitcode == 99:
from lab.dirs import get_global_log_path

with open(get_global_log_path(), "a") as global_log:
with storage.open(get_global_log_path(), "a") as global_log:
global_log.write(
"GPU (CUDA) Out of Memory: Please try a smaller model or a different inference engine. Restarting the server may free up resources.\n"
)
Expand All @@ -403,7 +407,7 @@ async def server_worker_start(
if exitcode is not None and exitcode != 0:
from lab.dirs import get_global_log_path

with open(get_global_log_path(), "a") as global_log:
with storage.open(get_global_log_path(), "a") as global_log:
global_log.write(f"Error loading model: {model_name} with exit code {exitcode}\n")
job = job_get(job_id)
error_msg = None
Expand All @@ -415,7 +419,7 @@ async def server_worker_start(
return {"status": "error", "message": error_msg}
from lab.dirs import get_global_log_path

with open(get_global_log_path(), "a") as global_log:
with storage.open(get_global_log_path(), "a") as global_log:
global_log.write(f"Model loaded successfully: {model_name}\n")
return {"status": "success", "job_id": job_id}

Expand Down
2 changes: 1 addition & 1 deletion requirements-no-gpu-uv.txt
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ tqdm==4.66.5
# peft
# sentence-transformers
# transformers
transformerlab==0.0.44
transformerlab==0.0.45
# via
# -r requirements.in
# transformerlab-inference
Expand Down
2 changes: 1 addition & 1 deletion requirements-rocm-uv.txt
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ tqdm==4.66.5
# peft
# sentence-transformers
# transformers
transformerlab==0.0.44
transformerlab==0.0.45
# via
# -r requirements-rocm.in
# transformerlab-inference
Expand Down
2 changes: 1 addition & 1 deletion requirements-rocm.in
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ hf_xet
macmon-python
mcp[cli]
transformerlab-inference==0.2.51
transformerlab==0.0.44
transformerlab==0.0.45
diffusers==0.33.1
pyrsmi
controlnet_aux==0.0.10
Expand Down
2 changes: 1 addition & 1 deletion requirements-uv.txt
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ tqdm==4.66.5
# peft
# sentence-transformers
# transformers
transformerlab==0.0.44
transformerlab==0.0.45
# via
# -r requirements.in
# transformerlab-inference
Expand Down
2 changes: 1 addition & 1 deletion requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ markitdown[all]
hf_xet
macmon-python
transformerlab-inference==0.2.51
transformerlab==0.0.44
transformerlab==0.0.45
diffusers==0.33.1
nvidia-ml-py
mcp[cli]
Expand Down
60 changes: 30 additions & 30 deletions test/api/test_diffusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ def test_get_image_by_id_index_out_of_range(client):
with (
patch("transformerlab.routers.experiment.diffusion.find_image_by_id") as mock_find_image,
patch("transformerlab.routers.experiment.diffusion.get_images_dir", return_value="/fake/images"),
patch("os.path.exists", return_value=True),
patch("os.path.isdir", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.isdir", return_value=True),
):
# Create mock image with folder-format
mock_image = MagicMock()
Expand All @@ -272,9 +272,9 @@ def test_get_image_info_by_id_success(client):
"""Test getting image metadata by ID"""
with (
patch("transformerlab.routers.experiment.diffusion.find_image_by_id") as mock_find_image,
patch("os.path.exists", return_value=True),
patch("os.path.isdir", return_value=True),
patch("os.listdir", return_value=["0.png", "1.png", "2.png"]),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.isdir", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.ls", return_value=["0.png", "1.png", "2.png"]),
):
# Create mock image
mock_image = MagicMock()
Expand All @@ -295,9 +295,9 @@ def test_get_image_count_success(client):
"""Test getting image count for an image set"""
with (
patch("transformerlab.routers.experiment.diffusion.find_image_by_id") as mock_find_image,
patch("os.path.exists", return_value=True),
patch("os.path.isdir", return_value=True),
patch("os.listdir", return_value=["0.png", "1.png"]),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.isdir", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.ls", return_value=["0.png", "1.png"]),
):
# Create mock image
mock_image = MagicMock()
Expand All @@ -317,8 +317,8 @@ def test_delete_image_from_history_not_found(client):
"""Test deleting a non-existent image from history"""
with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=True),
patch("builtins.open", mock_open(read_data='[{"id": "other-id", "image_path": "/fake/path.png"}]')),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.open", mock_open(read_data='[{"id": "other-id", "image_path": "/fake/path.png"}]')),
):
resp = client.delete("/experiment/test-exp-name/diffusion/history/non-existent-id")
assert resp.status_code == 500
Expand All @@ -331,12 +331,12 @@ def test_create_dataset_from_history_success(client):
patch("transformerlab.routers.experiment.diffusion.find_image_by_id") as mock_find_image,
patch("transformerlab.routers.experiment.diffusion.Dataset.get") as mock_dataset_get,
patch("transformerlab.routers.experiment.diffusion.create_local_dataset") as mock_create_dataset,
patch("os.makedirs"),
patch("os.path.exists", return_value=True),
patch("os.path.isdir", return_value=True),
patch("os.listdir", return_value=["0.png", "1.png"]),
patch("shutil.copy2"),
patch("builtins.open", mock_open()),
patch("transformerlab.routers.experiment.diffusion.storage.makedirs"),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.isdir", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.ls", return_value=["/fake/path/folder/0.png", "/fake/path/folder/1.png"]),
patch("transformerlab.routers.experiment.diffusion.storage.copy_file"),
patch("transformerlab.routers.experiment.diffusion.storage.open", mock_open()),
):
# Mock Dataset.get to raise FileNotFoundError for non-existent dataset (new behavior)
mock_dataset_get.side_effect = FileNotFoundError("Directory for Dataset with id 'test-dataset' not found")
Expand Down Expand Up @@ -610,9 +610,9 @@ def test_load_history_success():
"""Test loading history with valid data"""
with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch(
"builtins.open",
"transformerlab.routers.experiment.diffusion.storage.open",
mock_open(
read_data='[{"id": "test-id", "model": "test-model", "prompt": "test prompt", "adaptor": "", "adaptor_scale": 1.0, "num_inference_steps": 20, "guidance_scale": 7.5, "seed": 42, "image_path": "/fake/path.png", "timestamp": "2023-01-01T00:00:00", "upscaled": false, "upscale_factor": 1, "negative_prompt": "", "eta": 0.0, "clip_skip": 0, "guidance_rescale": 0.0, "height": 512, "width": 512, "generation_time": 5.0, "num_images": 1, "input_image_path": "", "strength": 0.8, "is_img2img": false, "mask_image_path": "", "is_inpainting": false}]'
),
Expand Down Expand Up @@ -665,8 +665,8 @@ def test_load_history_with_pagination():

with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=True),
patch("builtins.open", mock_open(read_data=json.dumps(history_data))),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.open", mock_open(read_data=json.dumps(history_data))),
):
from transformerlab.routers.experiment.diffusion import load_history

Expand All @@ -683,7 +683,7 @@ def test_load_history_no_file():
"""Test loading history when history file doesn't exist"""
with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=False),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=False),
):
from transformerlab.routers.experiment.diffusion import load_history

Expand All @@ -697,8 +697,8 @@ def test_load_history_invalid_json():
"""Test loading history with corrupted JSON file"""
with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=True),
patch("builtins.open", mock_open(read_data="invalid json")),
patch("lab.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.open", mock_open(read_data="invalid json")),
):
from transformerlab.routers.experiment.diffusion import load_history

Expand Down Expand Up @@ -769,8 +769,8 @@ def test_find_image_by_id_success():

with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=True),
patch("builtins.open", mock_open(read_data=json.dumps(history_data))),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.open", mock_open(read_data=json.dumps(history_data))),
):
from transformerlab.routers.experiment.diffusion import find_image_by_id

Expand Down Expand Up @@ -816,8 +816,8 @@ def test_find_image_by_id_not_found(client):

with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=True),
patch("builtins.open", mock_open(read_data=json.dumps(history_data))),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.open", mock_open(read_data=json.dumps(history_data))),
):
from transformerlab.routers.experiment.diffusion import find_image_by_id

Expand All @@ -830,7 +830,7 @@ def test_find_image_by_id_no_file():
"""Test finding an image by ID when history file doesn't exist"""
with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=False),
patch("transformerlab.routers.experiment.diffusion.storage.exists", return_value=False),
):
from transformerlab.routers.experiment.diffusion import find_image_by_id

Expand All @@ -843,8 +843,8 @@ def test_find_image_by_id_invalid_json():
"""Test finding an image by ID with corrupted JSON file"""
with (
patch("transformerlab.routers.experiment.diffusion.get_history_file_path", return_value="/fake/history.json"),
patch("os.path.exists", return_value=True),
patch("builtins.open", mock_open(read_data="invalid json")),
patch("lab.storage.exists", return_value=True),
patch("transformerlab.routers.experiment.diffusion.storage.open", mock_open(read_data="invalid json")),
):
from transformerlab.routers.experiment.diffusion import find_image_by_id

Expand Down
13 changes: 7 additions & 6 deletions test/api/test_experiment_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from transformerlab.services import experiment_service
from transformerlab.services.tasks_service import tasks_service
from lab.dirs import get_workspace_dir
from lab import storage


async def test_export_experiment(client):
Expand Down Expand Up @@ -66,13 +67,13 @@ async def test_export_experiment(client):
# The response should be a JSON file
assert response.headers["content-type"] == "application/json"

WORKSPACE_DIR = get_workspace_dir()
workspace_dir = get_workspace_dir()

# Read the exported file from workspace directory
export_file = os.path.join(WORKSPACE_DIR, f"{test_experiment_name}_export.json")
assert os.path.exists(export_file)
export_file = storage.join(workspace_dir, f"{test_experiment_name}_export.json")
assert storage.exists(export_file)

with open(export_file, "r") as f:
with storage.open(export_file, "r") as f:
exported_data = json.load(f)

# Verify the exported data structure
Expand Down Expand Up @@ -104,5 +105,5 @@ async def test_export_experiment(client):

# Clean up
experiment_service.experiment_delete(experiment_id)
if os.path.exists(export_file):
os.remove(export_file)
if storage.exists(export_file):
storage.rm(export_file)
1 change: 0 additions & 1 deletion transformerlab/db/constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# --- Centralized Database Configuration ---
from lab import HOME_DIR


db = None # This will hold the aiosqlite connection
DATABASE_FILE_NAME = f"{HOME_DIR}/llmlab.sqlite3"
DATABASE_URL = f"sqlite+aiosqlite:///{DATABASE_FILE_NAME}"
46 changes: 28 additions & 18 deletions transformerlab/fastchat_openai_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
UsageInfo,
)
from pydantic import BaseModel as PydanticBaseModel
from lab import Experiment
from lab import Experiment, storage

WORKER_API_TIMEOUT = 3600

Expand Down Expand Up @@ -233,16 +233,23 @@ def log_prompt(prompt):
from lab.dirs import get_logs_dir

logs_dir = get_logs_dir()
if os.path.exists(os.path.join(logs_dir, "prompt.log")):
if os.path.getsize(os.path.join(logs_dir, "prompt.log")) > MAX_LOG_SIZE_BEFORE_ROTATE:
with open(os.path.join(logs_dir, "prompt.log"), "r") as f:
prompt_log_path = storage.join(logs_dir, "prompt.log")
if storage.exists(prompt_log_path):
# Get file size - for remote storage, we may need to read the file to check size
try:
with storage.open(prompt_log_path, "r") as f:
lines = f.readlines()
with open(os.path.join(logs_dir, "prompt.log"), "w") as f:
f.writelines(lines[-1000:])
with open(os.path.join(logs_dir, f"prompt_{time.strftime('%Y%m%d%H%M%S')}.log"), "w") as f:
f.writelines(lines[:-1000])

with open(os.path.join(logs_dir, "prompt.log"), "a") as f:
file_size = sum(len(line.encode('utf-8')) for line in lines)
if file_size > MAX_LOG_SIZE_BEFORE_ROTATE:
with storage.open(prompt_log_path, "w") as f:
f.writelines(lines[-1000:])
with storage.open(storage.join(logs_dir, f"prompt_{time.strftime('%Y%m%d%H%M%S')}.log"), "w") as f:
f.writelines(lines[:-1000])
except Exception:
# If we can't read the file, just continue with appending
pass

with storage.open(prompt_log_path, "a") as f:
log_entry = {}
log_entry["date"] = time.strftime("%Y-%m-%d %H:%M:%S")
log_entry["log"] = prompt
Expand All @@ -254,7 +261,10 @@ def log_prompt(prompt):
async def get_prompt_log():
from lab.dirs import get_logs_dir

return FileResponse(os.path.join(get_logs_dir(), "prompt.log"))
prompt_log_path = storage.join(get_logs_dir(), "prompt.log")
# FileResponse needs a local file path, so use the path string directly
# For remote storage, this would need special handling
return FileResponse(prompt_log_path)


async def check_length(request, prompt, max_tokens):
Expand Down Expand Up @@ -526,8 +536,8 @@ async def create_audio_tts(request: AudioGenerationRequest):
exp_obj = Experiment.get(request.experiment_id)
experiment_dir = exp_obj.get_dir()

audio_dir = os.path.join(experiment_dir, "audio")
os.makedirs(audio_dir, exist_ok=True)
audio_dir = storage.join(experiment_dir, "audio")
storage.makedirs(audio_dir, exist_ok=True)

gen_params = {
"audio_dir": audio_dir,
Expand Down Expand Up @@ -560,16 +570,16 @@ async def create_audio_tts(request: AudioGenerationRequest):
async def upload_audio_reference(experimentId: str, audio: UploadFile = File(...)):
exp_obj = Experiment(experimentId)
experiment_dir = exp_obj.get_dir()
uploaded_audio_dir = os.path.join(experiment_dir, "uploaded_audio")
os.makedirs(uploaded_audio_dir, exist_ok=True)
uploaded_audio_dir = storage.join(experiment_dir, "uploaded_audio")
storage.makedirs(uploaded_audio_dir, exist_ok=True)

file_prefix = str(uuid.uuid4())
_, ext = os.path.splitext(audio.filename)
file_path = os.path.join(uploaded_audio_dir, file_prefix + ext)
file_path = storage.join(uploaded_audio_dir, file_prefix + ext)

# Save the uploaded file
with open(file_path, "wb") as f:
content = await audio.read()
content = await audio.read()
with storage.open(file_path, "wb") as f:
f.write(content)

return JSONResponse({"audioPath": file_path})
Expand Down
Loading
Loading