sapiens_tools 0.10.2

The tools - Sapiens
Documentation
//! Tests
#[cfg(feature = "hue")]
mod hue_test {
    use indoc::indoc;
    use insta::{assert_display_snapshot, assert_yaml_snapshot};
    use pyo3::PyResult;
    use sapiens::tools::toolbox::{invoke_tool, InvokeResult, Toolbox};
    use sapiens_tools::conclude::ConcludeTool;
    use sapiens_tools::hue::room::fake::FakeRoomTool;
    use sapiens_tools::hue::status::fake::FakeStatusTool;
    use sapiens_tools::python::PythonTool;

    #[pyo3_asyncio::tokio::test]
    async fn test_python_hue() -> PyResult<()> {
        let data = indoc! {r#"
    # Action
    ```yaml
    tool_name: SandboxedPython
    parameters:
      code: |
        room_name = "Bedroom"
    
        import json
    
        # Get the list of room objects with names and Lights ID lists.
        rooms = tools.Room(room_filter=[]).get('rooms')
    
        # Find the relevant room and get only its lights IDs.
        room_lights = next(room for room in rooms if room_name in room.get('name'))
        room_lights_ids = room_lights.get('lights')
                        
        # Get the statuses of Lights in the Bedroom.
        Bedroom_lights_status = tools.LightStatus(light_filter=room_lights_ids).get('lights')
    
        # Conclude the task with the result.
        tools.Conclude(
            original_question="what is the status of the lights in the Bedroom?",
            conclusion=f"The light(s) status in {room_name} is {json.dumps(Bedroom_lights_status)}"
        )
    ```
    "#};

        let mut toolbox = Toolbox::default();
        toolbox.add_advanced_tool(PythonTool::default()).await;
        toolbox.add_terminal_tool(ConcludeTool::default()).await;
        toolbox.add_tool(FakeRoomTool::default()).await;
        toolbox.add_tool(FakeStatusTool::default()).await;

        let res = invoke_tool(toolbox.clone(), data).await;

        match res {
            InvokeResult::Success {
                tool_name, result, ..
            } => {
                assert_eq!(tool_name, "SandboxedPython");
                assert_display_snapshot!(result);
            }
            _ => panic!("Unexpected response: {:?}", res),
        }

        // collect the conclusion
        let termination_messages = toolbox.termination_messages().await;

        assert_yaml_snapshot!(termination_messages);

        Ok(())
    }
}

#[cfg(feature = "arxiv")]
mod arxiv {
    use indoc::indoc;
    use insta::{assert_display_snapshot, assert_yaml_snapshot};
    use pyo3::PyResult;
    use sapiens::tools::toolbox::{invoke_tool, InvokeResult, Toolbox};
    use sapiens_tools::arxiv::ArxivTool;
    use sapiens_tools::conclude::ConcludeTool;
    use sapiens_tools::python::PythonTool;

    #[pyo3_asyncio::tokio::test]
    async fn test_python_arxiv() -> PyResult<()> {
        let mut toolbox = Toolbox::default();
        toolbox.add_tool(ArxivTool::new().await).await;
        toolbox.add_advanced_tool(PythonTool::default()).await;

        let data = indoc! {r#"```yaml
   tool_name: SandboxedPython
   parameters:
     code: |           
           import datetime               
           search_query = f'cat:cs.AI'
           input = {
               'search_query': search_query,
               'start': 0,
               'max_results': 10,
               'sort_by': 'lastUpdatedDate',
               'sort_order': 'ascending'
           }
           arxiv_output = tools.Arxiv(**input)
           papers = arxiv_output['result']               
           conclusion = f"Yes, there are {len(papers)} published papers of AI category on ArXiv this week." if papers else "No, there are no published papers of AI category on ArXiv this week."
           print(conclusion)
   ```
"#};

        let res = invoke_tool(toolbox, data).await;

        match res {
            InvokeResult::Success {
                tool_name, result, ..
            } => {
                assert_eq!(tool_name, "SandboxedPython");
                assert_display_snapshot!(result);
            }
            _ => panic!("Unexpected response: {:?}", res),
        }

        Ok(())
    }

    #[pyo3_asyncio::tokio::test]
    async fn test_python_arxiv_2() -> PyResult<()> {
        let mut toolbox = Toolbox::default();
        toolbox.add_tool(ArxivTool::new().await).await;
        toolbox.add_advanced_tool(PythonTool::default()).await;

        let data = indoc! {r#"```yaml
   tool_name: SandboxedPython
   parameters:
     code: |           
           import datetime               
           search_query = f'cat:cs.AI'               
           arxiv_output = tools.Arxiv(search_query=search_query, start=0, max_results=10, sort_by='lastUpdatedDate', sort_order='ascending')               
           papers = arxiv_output['result']               
           conclusion = f"Yes, there are {len(papers)} published papers of AI category on ArXiv this week." if papers else "No, there are no published papers of AI category on ArXiv this week."
           print(conclusion)
   ```
"#};

        let res = invoke_tool(toolbox, data).await;

        match res {
            InvokeResult::Success {
                tool_name, result, ..
            } => {
                assert_eq!(tool_name, "SandboxedPython");
                assert_display_snapshot!(result);
            }
            _ => panic!("Unexpected response: {:?}", res),
        }

        Ok(())
    }

    #[pyo3_asyncio::tokio::test]
    async fn test_python_arxiv_3() -> PyResult<()> {
        let mut toolbox = Toolbox::default();
        toolbox.add_tool(ArxivTool::new().await).await;
        toolbox.add_advanced_tool(PythonTool::default()).await;

        let data = indoc! {r#"```yaml
   tool_name: SandboxedPython
   parameters:
     code: |
        latest_papers = tools.Arxiv(
          search_query="cat:cs.DB",
          max_results=4,
          show_summary=True,
          show_pdf_url=True
          )["result"]           
        print(latest_papers)
   ```
"#};

        let res = invoke_tool(toolbox, data).await;

        match res {
            InvokeResult::Success {
                tool_name, result, ..
            } => {
                assert_eq!(tool_name, "SandboxedPython");
                assert_display_snapshot!(result);
            }
            _ => panic!("Unexpected response: {:?}", res),
        }

        Ok(())
    }

    #[pyo3_asyncio::tokio::test]
    async fn test_python_arxiv_4() -> PyResult<()> {
        let mut toolbox = Toolbox::default();
        toolbox.add_tool(ArxivTool::new().await).await;
        toolbox.add_terminal_tool(ConcludeTool::default()).await;
        toolbox.add_advanced_tool(PythonTool::default()).await;

        let data = indoc! {r#"```yaml
    tool_name: SandboxedPython
    parameters:
      code: |
        latest_papers = tools.Arxiv(
          search_query="cat:cs.DB",
          max_results=4,
          show_summary=True,
          show_pdf_url=True,
          sort_order="ascending",
          )["result"]
    
        summaries = []
        for paper in latest_papers:
            summary = paper["summary"]
            summaries.append(summary)
    
        task_conclusion = "\n\n\n".join([f"Title: {paper['title']}\nSummary: {summary}\nPDF Url: {paper['pdf_url']}"
                                        for paper, summary in zip(latest_papers, summaries)])
    
        tools.Conclude(
                original_question="What are the 4 latest papers on database published on arXiv? What are they about?",
                conclusion=task_conclusion)
   ```
"#};

        let res = invoke_tool(toolbox.clone(), data).await;

        match res {
            InvokeResult::Success {
                tool_name, result, ..
            } => {
                assert_eq!(tool_name, "SandboxedPython");
                assert_display_snapshot!(result);
            }
            _ => panic!("Unexpected response: {:?}", res),
        }

        let termination_messages = toolbox.termination_messages().await;
        let done = !termination_messages.is_empty();
        assert!(done);

        assert_yaml_snapshot!(termination_messages);

        Ok(())
    }
}

mod python;

#[cfg(all(feature = "search", not(feature = "disable-test-dependabot")))]
mod search {
    use indoc::indoc;
    use insta::assert_display_snapshot;
    use pyo3::PyResult;
    use sapiens::tools::toolbox::{invoke_tool, InvokeResult, Toolbox};
    use sapiens_tools::python::PythonTool;
    use sapiens_tools::search::SearchTool;

    #[pyo3_asyncio::tokio::test]
    async fn test_python_search() -> PyResult<()> {
        let mut toolbox = Toolbox::default();
        toolbox.add_tool(SearchTool::default()).await;
        toolbox.add_advanced_tool(PythonTool::default()).await;

        let data = indoc! {r#"```yaml
   tool_name: SandboxedPython
   parameters:
     code: |                
         input = {"q": "rust" }     
         output = tools.Search(**input)                                     
         print(len(output['results']))
   ```
"#};

        let res = invoke_tool(toolbox, data).await;

        match res {
            InvokeResult::Success {
                tool_name, result, ..
            } => {
                assert_eq!(tool_name, "SandboxedPython");
                assert_display_snapshot!(result);
            }
            _ => panic!("Unexpected response: {:?}", res),
        }

        Ok(())
    }
}

#[pyo3_asyncio::tokio::main(flavor = "multi_thread")]
async fn main() -> pyo3::PyResult<()> {
    let _ = dotenvy::dotenv();

    pyo3_asyncio::testing::main().await
}