Skip to content

Commit

Permalink
Merge pull request #877 from Undertone0809/v1.18.1/docs-add-streamlit…
Browse files Browse the repository at this point in the history
…-widget

add e2b code-interpreter
  • Loading branch information
Undertone0809 authored Aug 23, 2024
2 parents 6e0211e + 4da6798 commit fa59270
Show file tree
Hide file tree
Showing 37 changed files with 2,081 additions and 1,608 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,3 @@ venv.bak/
.mypy_cache/
_trial_temp
.idea

# vscode
.vscode
8 changes: 8 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"recommendations": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
"charliermarsh.ruff"
]
}
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,10 @@ install-docs:
pre-commit-install:
poetry run pre-commit install

polish-codestyle:
format:
poetry run ruff format --config pyproject.toml promptulate tests example
poetry run ruff check --fix --config pyproject.toml promptulate tests example

formatting: polish-codestyle
format: polish-codestyle

test:
$(TEST_COMMAND)

Expand All @@ -52,6 +49,8 @@ check-codestyle:
poetry run ruff format --check --config pyproject.toml promptulate tests example
poetry run ruff check --config pyproject.toml promptulate tests example

check-format: check-codestyle

lint: check-codestyle test

# https://github.com/Maxlinn/linn-jupyter-site-template/blob/main/.github/workflows/linn-jupyter-site-template-deploy.yml
Expand Down Expand Up @@ -95,10 +94,11 @@ help:
@echo "install-docs: Install the dependencies for building docs"
@echo "pre-commit-install: Install the pre-commit hooks"
@echo "polish-codestyle: Format the code"
@echo "formatting: Format the code"
@echo "format: Format the code"
@echo "check-format: Check the code format"
@echo "check-codestyle: Check the code style, the same as make check-format"
@echo "test: Run the tests"
@echo "test-prod: Run the tests for production"
@echo "check-codestyle: Check the code style"
@echo "lint: Run the tests and check the code style"
@echo "build-docs: Build the docs"
@echo "start-docs: Start the docs server"
Expand All @@ -109,4 +109,4 @@ help:
@echo "build-remove: Remove the build directory"
@echo "cleanup: Remove all the cache files"

.PHONY: lock install install-integration install-docs pre-commit-install polish-codestyle formatting format test test-prod check-codestyle lint build-docs start-docs pycache-remove dsstore-remove ipynbcheckpoints-remove pytestcache-remove build-remove cleanup help
.PHONY: lock install install-integration install-docs pre-commit-install polish-codestyle formatting format test test-prod check-codestyle lint build-docs start-docs pycache-remove dsstore-remove ipynbcheckpoints-remove pytestcache-remove build-remove cleanup help check-format
1 change: 1 addition & 0 deletions example/agent/tool_agent_terminal.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""A Agent with duckduckgo search"""

from promptulate.agents import ToolAgent
from promptulate.tools import DuckDuckGoTool

Expand Down
31 changes: 31 additions & 0 deletions example/ai-code-interpreter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# AI-Code-Interpreter

This example is an example of building ai code interpreter using promptulate.

You see try the live demo [here](https://pne-chatbot.streamlit.app/).

# Quick Start

1. Clone the repository and install the dependencies

```shell
git clone https://www.github.com/Undertone0809/promptulate
```

2. Switch the current directory to the example

```shell
cd ./example/ai-code-interpreter
```

3. Install the dependencies

```shell
pip install -r requirements.txt
```

4. Run the application

```shell
streamlit run app.py
```
171 changes: 171 additions & 0 deletions example/ai-code-interpreter/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import base64
import os
import re
from io import BytesIO
from typing import Optional

import pne
import streamlit as st
from e2b_code_interpreter import CodeInterpreter
from prompt import system_prompt


def extract_code(text) -> list:
pattern = r"```python\n(.*?)\n```"
matches = re.findall(pattern, text, re.DOTALL)
return matches


def render_model() -> dict:
e2b_key = st.text_input("E2B Key")
return {"e2b_key": e2b_key}


def handle_code_block(
code: str, config, code_interpreter: Optional[CodeInterpreter] = None
):
code_interpreter = code_interpreter or CodeInterpreter()
max_retries = 3
retry_count = 0

st.write("Running code:")
st.code(code, language="python")

while retry_count < max_retries:
exec = code_interpreter.notebook.exec_cell(code)

if exec.logs:
st.write("Run Logs:")
st.text(exec.logs)

if exec.error:
error_message = f"An error occurred: {exec.error}"
st.error(error_message)

error_response = pne.chat(
model=config.model_name,
messages=[
*st.session_state.messages,
{
"role": "assistant",
"content": "I encountered an error while executing the code.",
},
{
"role": "user",
"content": f"The code execution resulted in an error: {error_message}. Can you explain what went wrong and provide a corrected version of the code?", # noqa
},
],
model_config={
"api_base": config.api_base,
"api_key": config.api_key,
},
)

# st.write("Let me help you fix that eror:")
st.write(error_response)

corrected_code_blocks = extract_code(error_response)
if corrected_code_blocks:
code = corrected_code_blocks[0]
st.write("Corrected code:")
st.code(code, language="python")

retry_count += 1
else:
st.success("Code executed successfully!")
for output in exec.results:
if output.png:
image = BytesIO(base64.b64decode(output.png))
st.image(image)
elif output.text:
st.text(output.text)
break

if retry_count == max_retries:
st.error(
f"Failed to execute the code after {max_retries} attempts. Please review the code and try again." # noqa
)


def additional_config() -> dict:
e2b_api_key = st.text_input("E2B API Key")
return {"e2b_api_key": e2b_api_key}


def main():
st.set_page_config(layout="wide")
config = pne.beta.st.model_sidebar(additional_sidebar_fn=additional_config)
os.environ["E2B_API_KEY"] = config.e2b_api_key

st.title("💬 Code-Interpreter")
st.caption(
"🚀 Code-Interpreter is a tool that helps you run Python code snippets in your chat messages." # noqa
)

# Initialize session state
if "show_code_results" not in st.session_state:
st.session_state.show_code_results = False
if "code_blocks" not in st.session_state:
st.session_state.code_blocks = []

# Create a layout with a dynamic right column
left_col, right_col = st.columns([2, 1])

with left_col:
if "messages" not in st.session_state:
st.session_state["messages"] = [
{
"role": "assistant",
"content": system_prompt,
}
]

for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])

if prompt := st.chat_input("How can I help you?"):
if not config.api_key:
st.info("Please add your API key to continue.")
st.stop()

st.session_state.messages.append({"role": "user", "content": prompt})
st.chat_message("user").write(prompt)

stream = pne.chat(
model=config.model_name,
stream=True,
messages=st.session_state.messages,
model_config={"api_base": config.api_base, "api_key": config.api_key},
)
response = st.chat_message("assistant").write_stream(stream)

st.session_state.code_blocks = extract_code(response)

if st.session_state.code_blocks:
st.session_state.show_code_results = True
st.chat_message("assistant").write(
f"Found {len(st.session_state.code_blocks)} code blocks."
)

st.session_state.messages.append({"role": "assistant", "content": response})

if st.session_state.code_blocks:
st.button(
"Toggle Code Results",
on_click=lambda: setattr(
st.session_state,
"show_code_results",
not st.session_state.show_code_results,
),
)

if st.session_state.show_code_results:
with right_col:
st.header("Code Execution Results")
with CodeInterpreter() as interpreter:
for code in st.session_state.code_blocks:
handle_code_block(code, config, interpreter)


if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions example/ai-code-interpreter/prompt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
system_prompt = """
You are a helpful assistant. When you output markdown python code, code-interpreter interprets the code blocks and executes the code. so You don't need to output result.
If you are using some third-party library, you need to first output as follows, then generate the code.
```python
!pip install {package}
```
""" # noqa
3 changes: 3 additions & 0 deletions example/ai-code-interpreter/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
streamlit>=1.28
pne
e2b_code_interpreter
Loading

0 comments on commit fa59270

Please sign in to comment.