Skip to content

Commit

Permalink
feat: expand shell environment variables and home in function argumen…
Browse files Browse the repository at this point in the history
…ts (#16)
  • Loading branch information
schneiderfelipe committed Sep 23, 2023
1 parent 5191d36 commit 605d3d2
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ log = "0.4.20"
pretty_env_logger = "0.5.0"
serde = { version = "1.0.188", default-features = false }
serde_json = { version = "1.0.105", default-features = false }
shellexpand = "3.1.0"
tiktoken-rs = { version = "0.5.3", features = ["async-openai"] }
tokio = { version = "1.32.0", features = ["rt-multi-thread", "io-std"], default-features = false }
toml = { features = ["parse"], default-features = false, version = "0.7.6" }
10 changes: 6 additions & 4 deletions get_current_weather.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from sys import argv
import sys
import json

match argv[1:]: # ignore "get_current_weather.py"
match sys.argv[1:]: # ignore script name
case []:
print(
json.dumps(
Expand All @@ -10,7 +10,8 @@
"temperature": "72",
"unit": None,
"forecast": ["sunny", "windy"],
}
},
separators=(",", ":"),
)
)
case ["spec"]:
Expand All @@ -33,6 +34,7 @@
},
},
},
}
},
separators=(",", ":"),
)
)
47 changes: 36 additions & 11 deletions src/functions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
use async_openai::types::ChatCompletionFunctions;
use color_eyre::eyre;

#[inline]
fn get_project_dirs() -> color_eyre::Result<directories::ProjectDirs> {
use eyre::ContextCompat as _;

directories::ProjectDirs::from("io.github", "schneiderfelipe", "ellie")
.context("getting project directories")
}

/// Trim text
/// and try to produce a compact JSON string out of it,
/// returning an owned trimmed string if serialization fails.
Expand Down Expand Up @@ -40,23 +48,29 @@ pub struct Provider {

impl Provider {
#[inline]
pub(super) fn call(&self, arguments: &str) -> std::io::Result<String> {
pub(super) fn call(&self, arguments: &str) -> color_eyre::Result<String> {
use eyre::Context as _;

let content = duct::cmd(&self.command, &self.args)
.stdin_bytes(arguments)
.read()?;
.read()
.context("calling function")?;
Ok(try_compact_json(&content))
}

#[inline]
fn specification(&self) -> eyre::Result<ChatCompletionFunctions> {
use eyre::Context as _;

let spec = duct::cmd(
&self.command,
self.args
.iter()
.map(AsRef::as_ref)
.chain(std::iter::once("spec")),
)
.read()?;
.read()
.context("getting function specification")?;

let mut spec: ChatCompletionFunctions = serde_json::from_str(&spec)?;
if spec.name != self.name {
Expand All @@ -79,15 +93,10 @@ pub struct Functions {
impl Functions {
#[inline]
pub(super) fn load() -> eyre::Result<Self> {
use eyre::ContextCompat as _;
use itertools::Itertools as _;

let content = std::fs::read_to_string(
directories::ProjectDirs::from("io.github", "schneiderfelipe", "ellie")
.context("getting project directories")?
.config_dir()
.join("functions.toml"),
)?;
let content =
std::fs::read_to_string(get_project_dirs()?.config_dir().join("functions.toml"))?;
let Self { provider, function } = toml::from_str(&content)?;

let provider: Vec<_> = provider
Expand All @@ -100,7 +109,23 @@ impl Functions {
}
})
.map(|(_, provider)| provider)
.collect();
.map(
|Provider {
name,
command,
args,
}| {
args.into_iter()
.map(|arg| shellexpand::full(&arg).map(Into::into))
.collect::<Result<_, _>>()
.map(|args| Provider {
name,
command,
args,
})
},
)
.collect::<Result<_, _>>()?;
let function = function
.into_iter()
.sorted_by(|f, g| f.name.cmp(&g.name))
Expand Down

0 comments on commit 605d3d2

Please sign in to comment.