Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 5 additions & 3 deletions libs/shinkai-tools-runner/src/tools/python_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
use toml_edit::DocumentMut;

use crate::tools::{
check_utils::normalize_error_message, execution_error::ExecutionError, file_name_utils::normalize_for_docker_path, path_buf_ext::PathBufExt, run_result::RunResult
check_utils::normalize_error_message, execution_error::ExecutionError,
file_name_utils::normalize_for_docker_path, path_buf_ext::PathBufExt, run_result::RunResult,
};

use super::{
Expand Down Expand Up @@ -204,8 +205,9 @@
}

pub async fn check(&self) -> anyhow::Result<Vec<String>> {
let execution_storage =
ExecutionStorage::new(self.code.clone(), self.options.context.clone());
let mut code = Self::extend_with_pyproject_toml(self.code.clone())

Check warning on line 208 in libs/shinkai-tools-runner/src/tools/python_runner.rs

View workflow job for this annotation

GitHub Actions / check

variable does not need to be mutable

Check warning on line 208 in libs/shinkai-tools-runner/src/tools/python_runner.rs

View workflow job for this annotation

GitHub Actions / check

variable does not need to be mutable

Check warning on line 208 in libs/shinkai-tools-runner/src/tools/python_runner.rs

View workflow job for this annotation

GitHub Actions / check

variable does not need to be mutable

Check warning on line 208 in libs/shinkai-tools-runner/src/tools/python_runner.rs

View workflow job for this annotation

GitHub Actions / check

variable does not need to be mutable
.map_err(|e| anyhow::anyhow!("failed to create pyproject.toml: {}", e))?;
let execution_storage = ExecutionStorage::new(code.clone(), self.options.context.clone());
execution_storage.init_for_python(None)?;

let uv_binary_path = path::absolute(self.options.uv_binary_path.clone())
Expand Down
83 changes: 79 additions & 4 deletions libs/shinkai-tools-runner/src/tools/python_runner.test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1412,7 +1412,9 @@ async def run(c: CONFIG, p: INPUTS) -> OUTPUT:
let context_id = nanoid::nanoid!();
let context = ExecutionContext {
storage: match (cfg!(windows), runner_type.clone()) {
(true, RunnerType::Host) => PathBuf::from("C:/shinkai-tools-runner-execution-storage/storage"),
(true, RunnerType::Host) => {
PathBuf::from("C:/shinkai-tools-runner-execution-storage/storage")
}
_ => PathBuf::from("./shinkai-tools-runner-execution-storage/storage"),
},
context_id: context_id.clone(),
Expand Down Expand Up @@ -1443,7 +1445,7 @@ async def run(c: CONFIG, p: INPUTS) -> OUTPUT:
e
});
assert!(result.is_ok());

let output_path = context.storage.join(context_id).join("home/output.png");
assert!(output_path.exists());
}
Expand Down Expand Up @@ -1484,5 +1486,78 @@ output = OUTPUT(success=False, file_path="None")

let check_result = python_runner.check().await.unwrap();
assert!(!check_result.is_empty());
assert!(check_result.iter().any(|err| err.contains("No parameter named \"success\"")));
}
assert!(check_result
.iter()
.any(|err| err.contains("No parameter named \"success\"")));
}

#[tokio::test]
async fn check_code_with_third_party_library() {
let _ = env_logger::builder()
.filter_level(log::LevelFilter::Info)
.is_test(true)
.try_init();

let code_files = CodeFiles {
files: HashMap::from([(
"main.py".to_string(),
String::from(
r#"
# /// script
# requires-python = ">=3.10,<3.12"
# dependencies = [
# "requests",
# "faster-whisper",
# ]
# ///
import os
from faster_whisper import WhisperModel

class CONFIG:
# configure model-size / device via these fields if you like
model_name: str = "base" # "tiny" | "small" | "medium" | "large-v2" ...
device: str = "cpu" # "cuda" or "cpu"
compute_type: str = "float32" # "int8" | "float16" | "float32"
# int8 = fastest CPU; float16 = fastest GPU

class INPUTS:
audio_file_path: str

class OUTPUT:
transcript: str

async def run(config: CONFIG, inputs: INPUTS) -> OUTPUT:
if not os.path.exists(inputs.audio_file_path):
raise FileNotFoundError(f"Audio file not found: {inputs.audio_file_path}")

# initialise faster-whisper
model = WhisperModel(
config.model_name,
device=config.device,
compute_type=config.compute_type,
)

# transcribe and concatenate segment texts
segments, _ = model.transcribe(inputs.audio_file_path)
transcription: str = "".join(seg.text for seg in segments).strip()

out = OUTPUT()
out.transcript = transcription
return out
"#,
),
)]),
entrypoint: "main.py".to_string(),
};

let python_runner = PythonRunner::new(
code_files,
Value::Null,
Some(PythonRunnerOptions {
..Default::default()
}),
);

let check_result = python_runner.check().await.unwrap();
assert!(check_result.is_empty());
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shinkai_protocol/source",
"version": "0.9.11",
"version": "0.9.12",
"description": "This repository serves as the ecosystem to execute Shinkai tools, provided by the Shinkai team or third-party developers, in a secure environment. It provides a sandboxed space for executing these tools, ensuring that they run safely and efficiently, while also allowing for seamless integration with Rust code.",
"main": "index.js",
"author": "",
Expand Down
Loading