Skip to main content

Scholaris

![CI Status](https://github.com/nicomarr/scholaris/actions/workflows/test.yaml/badge.svg) ![PyPI Version](https://img.shields.io/pypi/v/scholaris.svg)

Key features

  • Local setup: No dependency on cloud-hosted LLMs for inference.
  • Extract data from local files: Built-in tools to extract data from PDFs, py files, and plain text or markdown files.
  • External data retrieval: Built-in tools to make API calls to external data sources, such as OpenAlex, Semantic Scholar, or NCBI’s Any ID converter.
  • Customizable and extensible architecture: Easily extend the functionality of the assistant by adding new tools with only a few lines of code.

Installation

Step 1. Download Ollama and follow the instructions to install Ollama for your operating system. Then, pull and run llama3.1 (parameters: 8B, quantization: Q4_0, size: 4.7 GB) according to the ollama documentation.

Step 2. Go to your terminal and setup a new virtual environment, such as with Conda:

$ conda create -n scholaris-env python=3.12

Step 3. Activate the virtual environment:

$ conda activate scholaris-env

Step 4. Install latest scholaris Python package:

from PyPI

$ pip install scholaris

from the GitHub repository

$ pip install git+https://github.com/nicomarr/scholaris.git

Getting started

Step 1. Open a Jupyter notebook, IPython environment, or start Python from the terminal and import the scholaris core module:

from scholaris.core import *

Step 2. Initialize the Assistant class:

Initialize the Assistant class with the default parameters:

assistant = Assistant()
Loaded Semantic Scholar API key from the environment variables.
Loaded email address from the environment variables.
A local directory /Users/user2/GitHub/scholaris/data already exists for storing data files. No of files: 1

Explicitly set or change the model by passing the model name as an argument to the Assistant class:

assistant = Assistant(model="llama3.1:latest")
Loaded Semantic Scholar API key from the environment variables.
Loaded email address from the environment variables.
A local directory /Users/user2/GitHub/scholaris/data already exists for storing data files. No of files: 1

How to use

Chat

To chat with the assistant, simply call the chat() method with your prompt as input. You also can store the response in a variable, but this is optional. By default, the assistant will stream the response and store the conversation history.

response = assistant.chat("Briefly tell me about the tools you have available.")
I can summarize research articles from various sources, provide information on scientific topics, and help with general knowledge queries. I have access to a range of tools that allow me to extract specific details from PDF documents, convert IDs between different formats (e.g., PubMed ID, DOI), and query OpenAlex and Semantic Scholar APIs for article metadata. Additionally, I can describe the purpose and content of local Python files. However, my capabilities are limited to the information provided by the available tools, so if a tool's content is empty or unavailable, I may not be able to provide a response.

By setting show_progress=True, you can see the step-by-step progress of the fuction calling. This includes the tool choice, selected arguments, if applicable, and the output of the called function that is being passed back to the LLM to generate the final response.

response = assistant.chat("Which PDF files do you have access to in the local data directory", show_progress=True)
Selecting tools...

[{'function': {'name': 'get_file_names', 'arguments': {'ext': 'pdf'}}}]
Calling get_file_names() with arguments {'ext': 'pdf'}...

Generating final response...
I have access to a single PDF file named "jci.insight.144499.v2.pdf" in the local data directory.

By default, streaming is enabled. If you like to disable streaming, set stream=False. This will store the entire conversation history in the messages attribute, which can be accessed as shown above.

response = assistant.chat("Does this document have a title?", stream_response=False)
Extracting titles and first authors: 100%|██████████| 1/1 [00:07<00:00,  7.72s/it]



Yes, the PDF file "jci.insight.144499.v2.pdf" has a title: "Distinct antibody repertoires against endemic human coronaviruses in children and adults".

Conversation history

Show the conversation history by calling the assistant’s show_conversation_history() method:

assistant.show_conversation_history()
User: Briefly tell me about the tools you have available.

Assistant response: I can summarize research articles from various sources, provide information on scientific topics, and help with general knowledge queries. I have access to a range of tools that allow me to extract specific details from PDF documents, convert IDs between different formats (e.g., PubMed ID, DOI), and query OpenAlex and Semantic Scholar APIs for article metadata. Additionally, I can describe the purpose and content of local Python files. However, my capabilities are limited to the information provided by the available tools, so if a tool's content is empty or unavailable, I may not be able to provide a response.

User: Which PDF files do you have access to in the local data directory

Assistant response: I have access to a single PDF file named "jci.insight.144499.v2.pdf" in the local data directory.

User: Does this document have a title?

Assistant response: Yes, the PDF file "jci.insight.144499.v2.pdf" has a title: "Distinct antibody repertoires against endemic human coronaviruses in children and adults".

Clear the conversation history by calling the assistant’s clear_conversation_history() method:

assistant.clear_conversation_history()

Assistant parameters

Show the model by printing the assistant object:

assistant
Assistant, powered by llama3.1

Or show the model by accessing the assistant’s model attribute:

assistant.model
'llama3.1:latest'

Show the system messages by accessing the assistant’s sys_message attribute:

print(assistant.sys_message)
You are an AI assistant specialized in analyzing research articles.
        Your role is to provide concise, human-readable responses based on information from tools and conversation history.

        Key instructions:
        1. Use provided tools to gather information before answering.
        2. Interpret tool results and provide clear, concise answers in natural language.
        3. If you can't answer with available tools, state this clearly.
        4. Don't provide information if tool content is empty.
        5. Never include raw JSON, tool outputs, or formatting tags in responses.
        6. Format responses as plain text for direct human communication.
        7. Use clear formatting (e.g., numbered or bulleted lists) when appropriate.
        8. Provide article details (e.g., DOI, citation count) in a conversational manner.

        Act as a knowledgeable research assistant, offering clear and helpful information based on available tools and data.

Local data access

By default, the assistant has access to a single directory, called data. Within this directory, the assistant can list and read the following file formats and extensions: pdf, txt, md, markdown, csv, and py. If not already present, the directory is created when the assistant is initialized. If you want to change the directory name, you can do so by passing the desired directory name as an argument to the Assistant class when it is initialized. For example, to create a directory called proprietary_data, you would initialize the assistant as follows:

assistant = Assistant(dir_path="../proprietary_data")

Tools

By default, the assistant can call a set of core tools or functions which are passed to the Assistant as a dictionary when it is initialized. With these tools or functions, the assistant will be able to get a list of file names in a specific data directory, can extract content from these files, and summarize them. In addition, the assistant can make API calls to external data sources, such as OpenAlex or Semantic Scholar, to retrieve information about a large number of scholarly articles. The tools available to the assistant can be viewed by accessing the assistant’s list_tools() method as follows:

assistant.list_tools()
get_file_names
extract_text_from_pdf
get_titles_and_first_authors
summarize_local_document
describe_python_code
id_converter_tool
query_openalex_api
query_semantic_scholar_api
respond_to_generic_queries
describe_tools

Authentication for tool calling and API access (optional)

Some tools take optional authentication parameters, such as an API key or email. For example, the query_semantic_scholar tool takes an optional API key to access the Semantic Scholar API, which will increase the API rate limit. Request a Semantic Scholar API Key here. Similarly, the query_openaplex_api tool takes an optional email parameter to access the OpenAlex API, which is recommended as a best practice and kindly requested by the API provider.

The best way to pass these parameters is to set them as environment variables, with the following key names: SEMANTIC_SCHOLAR_API_KEY and EMAIL. The Assistant class will automatically read these environment variables when initialized and pass them to the tools that require them. Alternatively, you can pass the Semantic Scholar API key and your email by simply adding the authentication argument when initializing the Assistant class, as shown below:

authentication = {
    "SEMANTIC_SCHOLAR_API_KEY": "your_api_key",
    "EMAIL": "your_email@example.com"
}
assistant = Assistant(authentication=authentication)
A local directory /Users/user2/GitHub/scholaris/data already exists for storing data files. No of files: 1

If you want to change the core functions, you can do so by passing the desired core functions as an argument to the Assistant class when it is initialized. For example, to limit the assitant’s ability to respond to generic questions and to access external data by making requests to the OpenAlex and Semantic Scholar API’s, you would initialize the assistant as follows:

assistant = Assistant(tools = {
    "query_openalex_api": query_openalex_api,
    "query_semantic_scholar_api": query_semantic_scholar_api,
    "respond_to_generic_queries": respond_to_generic_queries,
    })
Loaded Semantic Scholar API key from the environment variables.
Loaded email address from the environment variables.
A local directory /Users/user2/GitHub/scholaris/data already exists for storing data files. No of files: 1

Developer Guide

Defining new tools

You can define new functions to be used by the assistant as tools. To simplify this process, a decorator called @json_schema_decorator is provided so it is not necessary to define the schema for the function. The schema is automatically generated based on the function’s annotation and docstring.

The following example shows how to define a new tool to multiply two numbers, which takes as input two integers or strings that can be converted to integers, and returns the product of the two numbers as a string:

from typing import Union

@json_schema_decorator
def multiply_two_numbers(a: Union[int, str], b: Union[int, str]) -> str:
    """
    A function to multiply two numbers.

    Args:
        a: First number, can be an integer or a string representation of an integer.
        b: Second number, can be an integer or a string representation of an integer.

    Returns:
        str: The product of the two numbers, as a string.

    Raises:
        ValueError: If the inputs cannot be converted to integers.
    """
    try:
        int_a = int(a)
        int_b = int(b)
        return str(int_a * int_b)
    except ValueError:
        return "Error: Inputs must be integers or string representations of integers."

To ensure the JSON schema is generated correctly, you can call the json_schema attribute of the function:

multiply_two_numbers.json_schema
{'type': 'function',
 'function': {'name': 'multiply_two_numbers',
  'description': 'A function to multiply two numbers.',
  'parameters': {'type': 'object',
   'properties': {'a': {'type': 'object',
     'description': 'First number, can be an integer or a string representation of an integer.'},
    'b': {'type': 'object',
     'description': 'Second number, can be an integer or a string representation of an integer.'}},
   'required': ['a', 'b']}}}

Alternatively, you can use the generate_json_schema function:

generate_json_schema(multiply_two_numbers)

Adding tools

You can add new tools by passing a dictionary of new tools to the Assistant class when it is initialized. Use the add_tools argument to add new tools to the assistant. This will merge the new tools with the existing tools. For example, to add the new tool called multiply_two_integers to the assistant, you would initialize the assistant as follows:

assistant = Assistant(add_tools = {"multiply_two_numbers": multiply_two_numbers})
Loaded Semantic Scholar API key from the environment variables.
Loaded email address from the environment variables.
A local directory /Users/user2/GitHub/scholaris/data already exists for storing data files. No of files: 1

You can confirm that the new tool has been added to the list of existing tools by using the list_tools() method:

assistant.list_tools()
get_file_names
extract_text_from_pdf
get_titles_and_first_authors
summarize_local_document
describe_python_code
id_converter_tool
query_openalex_api
query_semantic_scholar_api
respond_to_generic_queries
describe_tools
multiply_two_numbers
response = assistant.chat("What is the product of 4173 and 351?", show_progress=True)
Selecting tools...

[{'function': {'name': 'multiply_two_numbers', 'arguments': {'a': '4173', 'b': '351'}}}]
Calling multiply_two_numbers() with arguments {'a': '4173', 'b': '351'}...

Generating final response...
The product of 4173 and 351 is 1,464,723.

Adding methods

You can add new methods to the Assistant class by using the add_to_class() decorator function, like so:

@add_to_class(Assistant)
def new_method(self):
    # Method implementation
    pass

Contributing to Scholaris

This Python package has been developed using nbdev. To contribute to this package, install nbdev and follow the nbdev documentation to set up your development environment.

Acknowledgements

Many thanks to the developers of Ollama and the Ollama Python Library for providing the core functionality that Scholaris is built upon, and thanks to all the providers of open-source and open-weight models. Special thanks to the developers of nbdev for making it easy to develop and document this package, and for many insightful tutorials and inspirations!

Metadata

Release files for scholaris 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scholaris 0.0.3
File Size Uploaded
scholaris-0.0.3.tar.gz 37.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for scholaris 0.0.3
File Interpreter ABI Platform
scholaris-0.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 67.4 kB

Release files / scholaris-0.0.3.tar.gz

Download URL scholaris-0.0.3.tar.gz
Size 37.3 kB
Tags Source
SHA-256 checksum
How to use checksums
268331cfe748b12bdb69041bb0e0d8da9894599b5c92197e9f0f4119524f5280
BLAKE2b-256 checksum
How to use checksums
696c077de9a723b85174c193e15557846ff7091e0d6dc4d2ff6214fbd2acd5c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.12.5

Release files / scholaris-0.0.3-py3-none-any.whl

Download URL scholaris-0.0.3-py3-none-any.whl
Size 30.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd5d21efbb33d9b5efd4eb4d4af2ea36ec33d6e9fb2a758a22b155f88d60338f
BLAKE2b-256 checksum
How to use checksums
0fa15798bd30b3edc2e4c0052e647cfd2239e0e7c53b72191758775d6eb76f94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.1 CPython/3.12.5

Release history Release notifications | RSS feed

This release

0.0.3 This release

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page