Skip to content

Commit

Permalink
Feature o1 branch (#154)
Browse files Browse the repository at this point in the history
* feat: Code for function calling using 01/o3 models

* fix:wrong file pushed

* fix: Provide python file for function calling testing with CLI

* fix: rempve notebook file code
  • Loading branch information
dhruvj07 authored Feb 28, 2025
1 parent d59b63c commit bfccecc
Showing 1 changed file with 394 additions and 0 deletions.
394 changes: 394 additions & 0 deletions examples/openai/o1-03_function-calling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,394 @@
#!/usr/bin/env python
import os
import json
import re
import argparse
from dotenv import load_dotenv
from openai import OpenAI, AzureOpenAI
from javelin_sdk import JavelinClient, JavelinConfig, RouteNotFoundError

# Load environment variables once at the start
load_dotenv()

# ---------------------------
# OpenAI – Unified Endpoint Examples
# ---------------------------
def init_openai_client():
api_key = os.getenv("OPENAI_API_KEY")
return OpenAI(api_key=api_key)

def init_javelin_client(openai_client, route_name="openai_univ"):
javelin_api_key = os.getenv("JAVELIN_API_KEY")
config = JavelinConfig(javelin_api_key=javelin_api_key)
client = JavelinClient(config)
client.register_openai(openai_client, route_name=route_name)
return client

def openai_function_call_non_stream():
print("\n==== Running OpenAI Non-Streaming Function Calling Example ====")
client = init_openai_client()
init_javelin_client(client)
response = client.chat.completions.create(
model="o3-mini", # Latest o1 model
messages=[
{"role": "user", "content": "What is the current weather in New York?"}
],
functions=[
{
"name": "get_current_weather",
"description": "Retrieves current weather information",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and state (e.g., New York, NY)"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
],
function_call="auto"
)
print("OpenAI Non-Streaming Response:")
print(response.model_dump_json(indent=2))

def openai_function_call_stream():
print("\n==== Running OpenAI Streaming Function Calling Example ====")
client = init_openai_client()
init_javelin_client(client)
stream = client.chat.completions.create(
model="o3-mini",
messages=[
{"role": "user", "content": "Tell me a fun fact and then call a function."}
],
functions=[
{
"name": "tell_fun_fact",
"description": "Returns a fun fact",
"parameters": {
"type": "object",
"properties": {
"fact": {
"type": "string",
"description": "A fun fact about the topic"
}
},
"required": ["fact"]
}
}
],
function_call="auto",
stream=True
)
collected = []
print("OpenAI Streaming Response:")
for chunk in stream:
delta = chunk.choices[0].delta
print(chunk)
if hasattr(delta, "content") and delta.content:
collected.append(delta.content)
print("".join(collected))

def openai_structured_output_call_generic():
print("\n==== Running OpenAI Structured Output Function Calling Example ====")
openai_client = init_openai_client()
init_javelin_client(openai_client)
messages = [
{
"role": "system",
"content": "You are an assistant that always responds in valid JSON format without any additional text."
},
{
"role": "user",
"content": (
"Provide a generic example of structured data output in JSON format. "
"The JSON should include the keys: 'id', 'name', 'description', "
"and 'attributes' (which should be a nested object with arbitrary key-value pairs)."
)
}
]

response = openai_client.chat.completions.create(
model="o3-mini", # can use o1 model as well
messages=messages,
)

print("Structured Output (JSON) Response:")
print(response.model_dump_json(indent=2))

try:
reply_content = response.choices[0].message.content
except (IndexError, AttributeError) as e:
print("Error extracting message content:", e)
reply_content = ""

try:
json_output = json.loads(reply_content)
print("\nParsed JSON Output:")
print(json.dumps(json_output, indent=2))
except Exception as e:
print("\nFailed to parse JSON output. Error:", e)
print("Raw content:", reply_content)

# ---------------------------
# Azure OpenAI – Unified Endpoint Examples
# ---------------------------
def init_azure_client():
azure_api_key = os.getenv("AZURE_OPENAI_API_KEY")
return AzureOpenAI(
api_version="2023-07-01-preview",
azure_endpoint="https://javelinpreview.openai.azure.com",
api_key=azure_api_key
)

def init_javelin_client_azure(azure_client, route_name="azureopenai_univ"):
javelin_api_key = os.getenv("JAVELIN_API_KEY")
config = JavelinConfig(javelin_api_key=javelin_api_key)
client = JavelinClient(config)
client.register_azureopenai(azure_client, route_name=route_name)
return client

def azure_function_call_non_stream():
print("\n==== Running Azure OpenAI Non-Streaming Function Calling Example ====")
azure_client = init_azure_client()
init_javelin_client_azure(azure_client)
response = azure_client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": "Schedule a meeting at 10 AM tomorrow."}
],
functions=[
{
"name": "schedule_meeting",
"description": "Schedules a meeting in the calendar",
"parameters": {
"type": "object",
"properties": {
"time": {"type": "string", "description": "Meeting time (ISO format)"},
"date": {"type": "string", "description": "Meeting date (YYYY-MM-DD)"}
},
"required": ["time", "date"]
}
}
],
function_call="auto"
)
print("Azure OpenAI Non-Streaming Response:")
print(response.to_json())

def azure_function_call_stream():
print("\n==== Running Azure OpenAI Streaming Function Calling Example ====")
azure_client = init_azure_client()
init_javelin_client_azure(azure_client)
stream = azure_client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": "Schedule a meeting at 10 AM tomorrow."}
],
functions=[
{
"name": "schedule_meeting",
"description": "Schedules a meeting in the calendar",
"parameters": {
"type": "object",
"properties": {
"time": {"type": "string", "description": "Meeting time (ISO format)"},
"date": {"type": "string", "description": "Meeting date (YYYY-MM-DD)"}
},
"required": ["time", "date"]
}
}
],
function_call="auto",
stream=True
)
print("Azure OpenAI Streaming Response:")
for chunk in stream:
print(chunk)

def extract_json_from_markdown(text: str) -> str:
"""
Extracts JSON content from a markdown code block if present.
Removes leading and trailing triple backticks.
"""
match = re.search(r"```(?:json)?\s*(\{.*\})\s*```", text, re.DOTALL)
if match:
return match.group(1)
return text.strip()

def azure_structured_output_call():
print("\n==== Running Azure OpenAI Structured Output Function Calling Example ====")
azure_client = init_azure_client()
init_javelin_client_azure(azure_client)
messages = [
{
"role": "system",
"content": "You are an assistant that always responds in valid JSON format without any additional text."
},
{
"role": "user",
"content": (
"Provide structured data in JSON format. "
"The JSON should contain the following keys: 'id' (integer), 'title' (string), "
"'description' (string), and 'metadata' (a nested object with arbitrary key-value pairs)."
)
}
]

response = azure_client.chat.completions.create(
model="gpt-4o",
messages=messages
)

print("Structured Output (JSON) Response:")
print(response.to_json())

try:
reply_content = response.choices[0].message.content
reply_content_clean = extract_json_from_markdown(reply_content)
json_output = json.loads(reply_content_clean)
print("\nParsed JSON Output:")
print(json.dumps(json_output, indent=2))
except Exception as e:
print("\nFailed to parse JSON output. Error:", e)
print("Raw content:", reply_content)

# ---------------------------
# OpenAI – Regular Route Endpoint Examples
# ---------------------------
def openai_regular_non_stream():
print("\n==== Running OpenAI Regular Route Non-Streaming Function Calling Example ====")
javelin_api_key = os.getenv('JAVELIN_API_KEY')
llm_api_key = os.getenv("OPENAI_API_KEY")
if not javelin_api_key or not llm_api_key:
raise ValueError("Both JAVELIN_API_KEY and OPENAI_API_KEY must be set.")
print("OpenAI LLM API Key:", llm_api_key)
config = JavelinConfig(
base_url="https://api-dev.javelin.live",
javelin_api_key=javelin_api_key,
llm_api_key=llm_api_key,
)
client = JavelinClient(config)
print("Successfully connected to Javelin Client for OpenAI")

query_data = {
"messages": [
{"role": "system", "content": "You are a helpful assistant that translates English to French."},
{"role": "user", "content": "AI has the power to transform humanity and make the world a better place."},
]
}

try:
response = client.query_route("openai", query_data)
print("Response from OpenAI Regular Endpoint:")
print(response)
except RouteNotFoundError:
print("Route 'openai' Not Found")
except Exception as e:
print("Error querying OpenAI endpoint:", e)

def openai_regular_stream():
print("\n==== Running OpenAI Regular Route Streaming Function Calling Example ====")
javelin_api_key = os.getenv('JAVELIN_API_KEY')
llm_api_key = os.getenv("OPENAI_API_KEY")
if not javelin_api_key or not llm_api_key:
raise ValueError("Both JAVELIN_API_KEY and OPENAI_API_KEY must be set.")
config = JavelinConfig(
base_url="https://api-dev.javelin.live",
javelin_api_key=javelin_api_key,
llm_api_key=llm_api_key,
)
client = JavelinClient(config)
print("Successfully connected to Javelin Client for OpenAI")

query_data = {
"messages": [
{"role": "system", "content": "You are a helpful assistant that translates English to French."},
{"role": "user", "content": "AI has the power to transform humanity and make the world a better place."},
],
"functions": [
{
"name": "translate_text",
"description": "Translates English text to French",
"parameters": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "Text to translate"
}
},
"required": ["text"]
}
}
],
"function_call": "auto",
"stream": True
}

try:
response = client.query_route("openai", query_data)
print("Response from OpenAI Regular Endpoint (Streaming):")
if query_data.get("stream"):
for chunk in response:
print(chunk)
else:
print(response)
except RouteNotFoundError as e:
print(f"Route 'openai' not found: {str(e)}")
except Exception as e:
print(f"Error occurred while getting response: {str(e)}")


# ---------------------------
# Main function and argument parsing
# ---------------------------
def main():
parser = argparse.ArgumentParser(description="Run Unified Endpoint Examples")
parser.add_argument(
"--example",
type=str,
default="all",
choices=[
"all", "openai_non_stream", "openai_stream", "openai_structured",
"azure_non_stream", "azure_stream", "azure_structured",
"openai_regular_non_stream", "openai_regular_stream"
],
help="The example to run (or 'all' to run every example)"
)
args = parser.parse_args()

if args.example == "all":
openai_function_call_non_stream()
openai_function_call_stream()
openai_structured_output_call_generic()
azure_function_call_non_stream()
azure_function_call_stream()
azure_structured_output_call()
openai_regular_non_stream()
openai_regular_stream()
elif args.example == "openai_non_stream":
openai_function_call_non_stream()
elif args.example == "openai_stream":
openai_function_call_stream()
elif args.example == "openai_structured":
openai_structured_output_call_generic()
elif args.example == "azure_non_stream":
azure_function_call_non_stream()
elif args.example == "azure_stream":
azure_function_call_stream()
elif args.example == "azure_structured":
azure_structured_output_call()
elif args.example == "openai_regular_non_stream":
openai_regular_non_stream()
elif args.example == "openai_regular_stream":
openai_regular_stream()

if __name__ == "__main__":
main()

0 comments on commit bfccecc

Please sign in to comment.