Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,7 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
#.idea/

# ignore .DS_Store file on macOS
.DS_Store
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ To run this sample code follow these steps:
2. **Run the script** - run the `python main.py`
3. **Command line argument** - Optionally you can add `--input "new input here"` to overide the default user input text.

### Chatbot UI
To run the chatbot interface, follow these steps:

1. Start the chatbot interface by running the following command:
```bash
python chatbot_interface.py
```
You should see output similar to:
```
Running on local URL: http://127.0.0.1:7860

To create a public link, set `share=True` in `launch()`.
```
2. Open the provided local URL in your web browser to start chatting.

3. The UI will look like the following: ![Chatbot UI](images/chatbot_ui.png)

### Example

**Default prompt**: "What is the current stock price of amazon stock in pounds?
Expand Down
107 changes: 107 additions & 0 deletions chatbot_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import sys
from loguru import logger
from pkg.ask import generate_text
from tools.ticker import parse_and_run_get_stock_price
from tools.currency import parse_and_run_convert_currency
import argparse
import json
import gradio as gr


def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument(
"input",
type=str,
nargs="?",
help="Input text for the LLM",
default="What is the current stock price of amazon stock in pounds?",
)
parser.add_argument(
"--log-level",
type=str,
default="INFO",
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
help="Set the logging level",
)
return parser.parse_known_args()


def build_message(input_text: str) -> list[dict]:
"""
Build the message to send to the LLM from the input test
:param input_text: the input text to send to the LLM
:return: a list containing containing the role, content and user input as text
"""
return [{"role": "user", "content": [{"text": input_text}]}]


def chatbot(input_text: str) -> str:
logger.info("Starting")
msg = build_message(input_text)
logger.info(f"input text: {input_text}")

stop_reason: str = None
answer: str = None

# Run until the model end_turn
while stop_reason != "end_turn":
stop_reason, tools_requested, messages = generate_text(msg)
logger.debug(f"stop reason is {stop_reason}, continue work till final answer")

# Amazon Bedrock LLM ended turn and responded the final answer
if stop_reason == "end_turn":
logger.info("The question asked the LLM ended turn and this is the answer")
answers = messages.get("content", {})
# iterate over the returned answers from Amazon Bedrock LLM
answers_text = [a.get("text", "\n") for a in answers]
answer = "".join(answers_text)
break

if stop_reason == "tool_use":
# find from the content returned form tools_requested the tool to use
for content in tools_requested:
if "toolUse" in content:
tool_use_id = content.get("toolUse", {}).get("toolUseId")
tool_use_name = content.get("toolUse", {}).get("name")
tool_use_input = content.get("toolUse", {}).get("input")
logger.info(
f"tool use id is {tool_use_id}, tool use name is {tool_use_name}"
)
# stock price tool
if tool_use_name == "get_stock_price":
message = parse_and_run_get_stock_price(
tool_use_id, tool_use_input
)
messages.append(message)

# currency conversion tool
if tool_use_name == "convert_currency":
message = parse_and_run_convert_currency(
tool_use_id, tool_use_input
)
messages.append(message)

# See the messages appended that are being built for the LLM, this will allow the Bedrock LLM to provide the final answer.
logger.debug(f"messages:\n{json.dumps(messages)}")

else:
# Stop reasons can be: 'end_turn'|'tool_use'|'max_tokens'|'stop_sequence'|'guardrail_intervened'|'content_filtered'
# This code sample only covers end_turn, and tool_use, you may need to implement additional code to cover all the rest of the responses.
logger.warning(
f"llm didn't end_turn, or asked to use a tool, he asked to {stop_reason}"
)
return "An error occurred."

# Printing the final response from the model
logger.info(answer)
return answer


if __name__ == "__main__":
args, _ = parse_args()
logger.remove() # Remove the default logger
logger.add(sys.stderr, level=args.log_level.upper())

iface = gr.Interface(fn=chatbot, inputs="text", outputs="text", title="Chatbot")
iface.launch()
Binary file added images/chatbot_ui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
boto3>=1.34.141
loguru>=0.7.2
yfinance==0.2.40
currencyconverter==0.17.25
currencyconverter==0.17.25
gradio==4.44.1