posit-dev / posit-dev/chatlas

Conditional flow with tool calls

Open
#33 13 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
176
Forks
28
Avg merge
18h 42m
Merged PRs (30d)
16

Description

Hi there,

I'm interested in this package for a more complex chatbot that I've been developing. I need to preferably stream openAI responses with tools. Getting this to work with the shiny chat component has been a little tricky, but then I came across a reference to chatlas in the docstring for the shiny Chat class. Working through your docs and examples, I can get so far with it.

This approach allows for streaming responses with tool calls and shiny ui
widgets. Though the tool calls need to be self-contained. Whatever the tool
returns is fed into the model for a subsequent response, rather than being
available for additional conditional flow.

I would like to instead receive the function name and parameter values and
call get_current_temperature(), passing the json response back to model.
This would allow me to display a notification without relying on a side
effect.

from chatlas import ChatOpenAI, Turn
from shiny.express import ui
import dotenv
import requests

openai_key = dotenv.dotenv_values()["OPENAI_KEY"]
messages = [Turn(role="system", contents="You are a helpful but terse assistant.")]
messages.append(Turn(role="assistant", contents = "Hi! How can I help you today?"))


# func contains side effect which I would prefer to handle outside
def get_current_temperature(latitude: float, longitude: float):
    """
    Get the current weather given a latitude and longitude.

    Parameters
    ----------
    latitude
        The latitude of the location.
    longitude
        The longitude of the location.
    """
    lat_lng = f"latitude={latitude}&longitude={longitude}"
    url = f"https://api.open-meteo.com/v1/forecast?{lat_lng}&current=temperature_2m,wind_speed_10m&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m"
    response = requests.get(url)
    json = response.json()
    weather_now = json['current']
    ui.notification_show(f"Queried weather API... {weather_now}")
    return weather_now


chat_model = ChatOpenAI(
    api_key=openai_key,
    turns=messages,
    )
chat_model.register_tool(get_current_temperature)
chat = ui.Chat(
    id="ui_chat",
    messages=["Hi! How can I help you today?"],
)
chat.ui()


@chat.on_user_submit
async def handle_user_input():
    response = chat_model.stream(chat.user_input())
    await chat.append_message_stream(response)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the ChatOpenAI, register_tool, and stream usage shown in the issue, then reproduce the example with the Shiny Chat component. Trace how tool-call results are currently returned to the model and determine how callers could receive the function name and parameters instead. Done means conditional callers can handle the tool invocation, display a notification, and pass the returned JSON back for a subsequent response.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
ai
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.