Skip to main content

work_buddy/tools/
write_md.rs

1//! A tool to just write out markdown files
2
3use anyhow::{Result, anyhow};
4use helpers::TruncatedDisplay;
5use llimorse::{Agent, CallableTool};
6use std::io::Write;
7use std::path::PathBuf;
8use std::{fmt, fs};
9
10llimorse::tool! {
11    'name: "write_markdown";
12
13    /// Write a full markdown file for example with design specifications developed in a
14    /// conversation with the user, to save for later viewing.
15    #[derive(Debug)]
16    'params: pub struct WriteMarkdownParams {
17        /// Filename for the file (no path components, just plain filename)
18        filename: PathBuf,
19
20        /// What to write into the file (full content)
21        content: String,
22    }
23
24    /// Result of writing the markdown file
25    #[derive(Debug)]
26    'result: pub struct WriteMarkdownResult {
27        /// Filename of the file written
28        filename: PathBuf,
29
30        /// How many bytes were written
31        bytes_written: usize,
32    }
33
34    /// Write a full markdown file for example with design specifications developed in a
35    /// conversation with the user, to save for later viewing.
36    #[derive(Debug)]
37    'state: pub struct WriteMarkdown {
38        /// Directory where to store markdown output files
39        dir: PathBuf,
40    }
41}
42
43impl fmt::Display for WriteMarkdownParams {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(
46            f,
47            "filename={} content={:?}",
48            self.filename.display(),
49            self.content.truncated_display(100)
50        )?;
51        Ok(())
52    }
53}
54
55impl fmt::Display for WriteMarkdownResult {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        write!(
58            f,
59            "filename={} bytes_written={}",
60            self.filename.display(),
61            self.bytes_written
62        )
63    }
64}
65
66impl WriteMarkdown {
67    /// Create a new `write_markdown` tool, allowing to put markdown files into `dir`.
68    pub fn new(dir: PathBuf) -> Self {
69        WriteMarkdown { dir }
70    }
71}
72
73impl CallableTool for WriteMarkdown {
74    async fn execute(
75        &self,
76        _agent: &Agent,
77        params: WriteMarkdownParams,
78    ) -> Result<WriteMarkdownResult> {
79        let path = self.dir.join(&params.filename);
80        let mut file = fs::File::create_new(&path)
81            .map_err(|err| anyhow!("Failed to create {}: {err}", path.display()))?;
82        let bytes = params.content.as_bytes();
83        file.write_all(bytes)
84            .map_err(|err| anyhow!("Failed to write to {}: {err}", path.display()))?;
85
86        Ok(WriteMarkdownResult {
87            filename: params.filename,
88            bytes_written: bytes.len(),
89        })
90    }
91}