feat: Working tool calls

o
	new file:   llm_interface.py
This commit is contained in:
2025-09-12 15:32:03 +01:00
parent fd2432df38
commit 30989e62ca
8 changed files with 6347 additions and 169 deletions
+50 -74
View File
@@ -1,91 +1,51 @@
from rich import print
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, BarColumn, track
from rich.markdown import Markdown
from rich.syntax import Syntax
from rich.live import Live
from rich.prompt import Prompt
import requests
import sys
from tools import ToolExecutor
import random
import time
LM_STUDIO_URL = "http://127.0.0.1:1234/v1/chat/completions"
EXIT_STRINGS = ['exit','goodbye','go away','fuck off']
import sys
import time
import config
from llm_interface import llm
import logging
#TODO: add context for llm calls so we have history and can chain messages
console = Console()
PRE_PROMPT = '''You have the following tools available, only use the tools if you need to.
please reply with only the tool call if you need to
{
"name": "get_weather",
"description": "Get current weather for a location",
"examples": [
{
"input": {"tool": "get_weather", "parameters":{"city":"New York"}},
"output": {"temperature": 22, "condition": "partly cloudy", "humidity": 65}
},
{
"input": {"tool": "get_weather", "parameters":{"city":"London"}},
"output": {"temperature": 18, "condition": "rainy", "humidity": 80}
}
]
}'''
class RichConsoleHandler(logging.StreamHandler):
def emit(self, record):
if record.levelno >= logging.CRITICAL:
console.print(f"[bold magenta]CRITICAL:[/bold magenta] {record.getMessage()}")
elif record.levelno >= logging.ERROR:
console.print(f"[bold red]ERROR:[/bold red] {record.getMessage()}")
elif record.levelno >= logging.WARNING:
console.print(f"[bold yellow]WARNING:[/bold yellow] {record.getMessage()}")
# elif record.levelno >= logging.INFO:
# console.print(f"[bold blue]INFO:[/bold blue] {record.getMessage()}")
# elif record.levelno >= logging.DEBUG:
# console.print(f"[bold green]DEBUG:[/bold green] {record.getMessage()}")
def ask_model(prompt: str, url=LM_STUDIO_URL) -> str:
payload = {
"model": 'qwen/qwen3-coder-30b',
"messages": [{"role": "user", "content": PRE_PROMPT+prompt}],
"temperature": 0.7,
"max_tokens": 2048,
}
resp = requests.post(url, json=payload)
resp.raise_for_status()
return resp.json()["choices"][0]["message"]["content"].strip()
def ask_model_no_pre(prompt: str, url=LM_STUDIO_URL) -> str:
payload = {
#"model": 'qwen/qwen3-coder-30b',
"model": 'openai/gpt-oss-20b',
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.7,
"max_tokens": 2048,
}
resp = requests.post(url, json=payload)
resp.raise_for_status()
return resp.json()["choices"][0]["message"]["content"].strip()
def get_llm_prompt():
def main(logger):
logger.info('Application Started')
language_model = llm(logger)
while True:
llm_prompt = Prompt.ask("[bold cyan]Ask your local llm[/]")
if llm_prompt.strip():
return llm_prompt.strip()
console.print("[red]Cannot be empty![/]", style="bold")
return llm_prompt
def handle_llm_reply(llm_reply:str):
architect = ToolExecutor()
return architect.process_llm_response(llm_output=llm_reply)
def main():
while True:
llm_prompt = get_llm_prompt()
if llm_prompt.lower() in EXIT_STRINGS:
llm_prompt = language_model.get_llm_prompt()
if llm_prompt.lower() in config.EXIT_STRINGS:
sys.exit()
start = time.time()
llm_reply = ask_model(llm_prompt)
print(llm_reply)
handled_response = handle_llm_reply(llm_reply)
print(handled_response)
print(handled_response == llm_reply)
llm_reply = language_model.ask_model(llm_prompt)
logger.info(f"LLM Reply: {llm_reply}")
handled_response = language_model.handle_llm_reply(llm_reply)
logger.info(f"Handled Response: {handled_response}")
logger.info(f"Response equals original: {handled_response == llm_reply}")
if handled_response != llm_reply:
output = ask_model_no_pre(prompt=f'Make this lovely markdown, use fun emojis {handled_response}')
output = language_model.tool_response(prompt=f'Make this lovely markdown, use fun emojis {handled_response}')
elif handled_response == llm_reply:
output = handled_response
@@ -99,5 +59,21 @@ def main():
console.print(panel_narrow)
if __name__ == "__main__":
main()
# Setup logging with custom handler for warnings and errors
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log')
]
)
logger = logging.getLogger(__name__)
logger.addHandler(RichConsoleHandler())
logger.info("Logging Instantiated")
main(logger)