Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an openai with function calls example #110

Merged
merged 10 commits into from
Dec 12, 2023

Conversation

MarcSkovMadsen
Copy link
Collaborator

@MarcSkovMadsen MarcSkovMadsen commented Dec 9, 2023

This adds an openai with function calls example.

I've based it on hvPlot. A lot could be invested in polishing the tool_hvplot.json file such that most of hvplots api would be available.

Bugs and Feature Requests identified

When the bugs below are fixed or features implemented it would be possible to make this even more awesome.

Assets

chat-with-hvplot

@ahuang11
Copy link
Collaborator

ahuang11 commented Dec 9, 2023

Looking to be great! Maybe @sophiamyang can write a blog post about this too :)

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 10, 2023

This is ready for review.

One day someone with more time might

  • Extend the tool_hvplot.json file to support more or all of hvPlots arguments.
  • Add possibility to upload data.
  • Support changing to another data set using the chat interface. For example it could be possible to change between all the bokeh_sample_data data sets.

@MarcSkovMadsen
Copy link
Collaborator Author

All the openai tests fails. My guess is the OPENAI_API_KEY is no longer valid @ahuang11

@ahuang11
Copy link
Collaborator

ahuang11 commented Dec 10, 2023

I refreshed the key.

Seems like it doesn't recognize the actions env key.

packages/bokeh/application/handlers/code_runner.py", line 229, in run
    exec(self._code, module.__dict__)
  File "/home/runner/work/panel-chat-examples/panel-chat-examples/docs/examples/openai/openai_authentication.py", line 58, in <module>
    aclient = AsyncOpenAI()
  File "/home/runner/.local/share/hatch/env/virtual/panel-chat-examples/wGgBc7bP/panel-chat-examples/lib/python3.9/site-packages/openai/_client.py", line 303, in __init__
    raise OpenAIError(
openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable

@ahuang11
Copy link
Collaborator

Trying to fix it here. #112

@ahuang11
Copy link
Collaborator

I will review this in detail tomorrow.

@MarcSkovMadsen
Copy link
Collaborator Author

MarcSkovMadsen commented Dec 11, 2023

Try adding a hvPlot argument to the tool_hvplot.json file and then play around with it in the chat interface. Its quite fun and a good learning experience.

Copy link
Collaborator

@ahuang11 ahuang11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing this; I think if things were moved around, it would improve understandability. Also potentially use serialize if possible.

The JSON schema reminds me of the time when I experimented with hvplot using marvin + pydantic; might be another useful example!

from marvin import ai_model
from collections import Mapping
from pydantic import BaseModel, Field
from typing import List, Union, Tuple, Dict, Any


@ai_model
class HoloViewsConfig(BaseModel, Mapping):
    class Config:
        arbitrary_types_allowed = True

    cnorm: str = Field(
        "linear",
        description="Color scaling which must be one of 'linear', 'log' or 'eq_hist'",
    )
    colorbar: bool = Field(False, description="Enables a colorbar")
    fontscale: float = Field(
        1.0, description="Scales the size of all fonts by the same amount"
    )
    fontsize: Union[float, Dict[str, Union[str, int]]] = Field(
        12.0, description="Set title, label and legend text to the same fontsize."
    )
    flip_xaxis: bool = Field(
        False, description="Whether to flip the axis left to right"
    )
    flip_yaxis: bool = Field(False, description="Whether to flip the axis up and down")
    grid: bool = Field(False, description="Whether to show a grid")
    hover: bool = Field(True, description="Whether to show hover tooltips")
    hover_cols: List[Union[str, List[str]]] = Field(
        [], description="Additional columns to add to the hover tool"
    )
    invert: bool = Field(False, description="Swaps x- and y-axis")
    frame_width: int = Field(800, description="The width of the data area of the plot")
    frame_height: int = Field(
        600, description="The height of the data area of the plot"
    )
    logx: bool = Field(False, description="Enables logarithmic x-axis")
    logy: bool = Field(False, description="Enables logarithmic y-axis")
    logz: bool = Field(False, description="Enables logarithmic colormapping")
    loglog: bool = Field(False, description="Enables logarithmic x- and y-axis")
    max_width: int = Field(
        800, description="The maximum width of the plot for responsive modes"
    )
    max_height: int = Field(
        600, description="The maximum height of the plot for responsive modes"
    )
    min_width: int = Field(
        300, description="The minimum width of the plot for responsive modes"
    )
    min_height: int = Field(
        300, description="The minimum height of the plot for responsive modes"
    )
    rescale_discrete_levels: bool = Field(
        True,
        description="If cnorm='eq_hist' and there are only a few discrete values, then rescale_discrete_levels=True",
    )
    responsive: bool = Field(
        False,
        description="Whether the plot should responsively resize depending on the size of the browser",
    )
    rot: float = Field(
        0.0,
        description="Rotates the axis ticks along the x-axis by the specified number of degrees",
    )
    shared_axes: bool = Field(True, description="Whether to link axes between plots")
    transforms: Dict[str, Any] = Field(
        default_factory=dict,
        description="A dictionary of HoloViews dim transforms to apply before plotting",
    )
    title: str = Field("", description="Title for the plot")
    tools: List[Union[str, BaseModel]] = Field(
        default_factory=list, description="List of tool instances or strings"
    )
    xaxis: Union[str, None] = Field(True, description="Whether to show the x-axis")
    yaxis: Union[str, None] = Field(True, description="Whether to show the y-axis")
    xformatter: Union[str, BaseModel, None] = Field(
        None, description="Formatter for the x-axis"
    )
    yformatter: Union[str, BaseModel, None] = Field(
        None, description="Formatter for the y-axis"
    )
    xlabel: Union[str, None] = Field(None, description="Axis labels for the x-axis")
    ylabel: Union[str, None] = Field(None, description="Axis labels for the y-axis")
    clabel: Union[str, None] = Field(None, description="Axis label for the colorbar")
    xlim: Union[Tuple, List[float], None] = Field(
        None, description="Plot limits of the x-axis"
    )
    ylim: Union[Tuple, List[float], None] = Field(
        None, description="Plot limits of the y-axis"
    )
    xticks: Union[int, List[Union[int, Tuple]], None] = Field(
        None, description="Ticks along x-axis"
    )
    yticks: Union[int, List[Union[int, Tuple]], None] = Field(
        None, description="Ticks along y-axis"
    )
    width: int = Field(700, description="The width of the plot in pixels")
    height: int = Field(300, description="The height of the plot in pixels")
    attr_labels: Union[bool, None] = Field(
        None, description="Whether to use an xarray object's attributes as labels"
    )
    check_symmetric_max: int = Field(
        1000000,
        description="Size above which to stop checking for symmetry by default on the data",
    )

    x: str = Field(..., description="The 'x' parameter")
    y: str = Field(..., description="The 'y' parameter")
    kind: Union[str, None] = Field(None, description="The 'kind' parameter")
    by: Union[str, None] = Field(None, description="The 'by' parameter")
    group_label: Union[str, None] = Field(
        None, description="The 'group_label' parameter"
    )
    value_label: str = Field("value", description="The 'value_label' parameter")
    backlog: int = Field(1000, description="The 'backlog' parameter")
    crs: Union[str, None] = Field(None, description="The 'crs' parameter")
    fields: Dict[str, Any] = Field(
        default_factory=dict, description="The 'fields' parameter"
    )
    groupby: Union[str, None] = Field(None, description="The 'groupby' parameter")
    dynamic: bool = Field(True, description="The 'dynamic' parameter")
    grid: Union[bool, None] = Field(None, description="The 'grid' parameter")
    legend: Union[bool, str, None] = Field(None, description="The 'legend' parameter")

    def __iter__(self):
        return self.dict().items()

    def __getitem__(self, x):
        return self.__dict__[x]

    def __iter__(self):
        return iter(self.dict())

    def __len__(self):
        return len(self.dict())
import pandas as pd
import hvplot.pandas

# pandas dataframe
df = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv")
df.hvplot(**HoloViewsConfig("scatter plot of bill_length_mm vs bill_depth_mm; groupby species, grid, larger font size"))

Outputs
image

@ahuang11
Copy link
Collaborator

Okay looks good to me!

@ahuang11 ahuang11 merged commit 45397fc into main Dec 12, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants