-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #133 from getjavelin/new-feature
New feature
- Loading branch information
Showing
16 changed files
with
1,605 additions
and
47 deletions.
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import os | ||
from openai import AzureOpenAI | ||
from javelin_sdk import JavelinClient, JavelinConfig | ||
|
||
def initialize_client(): | ||
""" | ||
Creates the AzureOpenAI client and registers it with Javelin. | ||
Returns the AzureOpenAI client object if successful, else None. | ||
""" | ||
javelin_api_key = "" # add your javelin api key here | ||
azure_openai_api_key = "" # Add your Azure OpenAI key | ||
|
||
if not javelin_api_key: | ||
print("Error: JAVELIN_API_KEY is not set!") | ||
return None | ||
else: | ||
print("JAVELIN_API_KEY found.") | ||
|
||
if not azure_openai_api_key: | ||
print("Warning: AZURE_OPENAI_API_KEY is not set!") | ||
else: | ||
print("AZURE_OPENAI_API_KEY found.") | ||
|
||
# Create the Azure client | ||
azure_client = AzureOpenAI( | ||
# Typically "2023-07-01-preview" or a more recent version | ||
api_version="2023-07-01-preview", | ||
azure_endpoint="https://javelinpreview.openai.azure.com", | ||
api_key=azure_openai_api_key | ||
) | ||
|
||
# Initialize the Javelin client and register the Azure client | ||
config = JavelinConfig(javelin_api_key=javelin_api_key) | ||
javelin_client = JavelinClient(config) | ||
javelin_client.register_azureopenai(azure_client, route_name="azureopenai-univ") | ||
|
||
return azure_client | ||
|
||
|
||
def get_chat_completion_sync(azure_client, messages): | ||
""" | ||
Calls the Azure Chat Completions endpoint (non-streaming). | ||
Takes a list of message dicts, returns JSON response as a string. | ||
Example model: 'gpt-4' or your deployed name (like 'gpt-4o'). | ||
""" | ||
response = azure_client.chat.completions.create( | ||
model="gpt-4", # Adjust to your Azure deployment name | ||
messages=messages | ||
) | ||
return response.to_json() | ||
|
||
|
||
def get_chat_completion_stream(azure_client, messages): | ||
""" | ||
Calls the Azure Chat Completions endpoint with streaming=True. | ||
Returns the concatenated text from the streamed chunks (for demonstration). | ||
""" | ||
response = azure_client.chat.completions.create( | ||
model="gpt-4", # Adjust to your Azure deployment name | ||
messages=messages, | ||
stream=True | ||
) | ||
|
||
# Accumulate streamed text | ||
streamed_text = [] | ||
for chunk in response: | ||
# chunk is an OpenAIObject with partial content in chunk.choices[0].delta | ||
if hasattr(chunk, "choices") and chunk.choices and chunk.choices[0].delta: | ||
streamed_text.append(chunk.choices[0].delta.get("content", "")) | ||
|
||
return "".join(streamed_text) | ||
|
||
|
||
def get_text_completion(azure_client, prompt): | ||
""" | ||
Demonstrates Azure text completion (non-chat). | ||
For this, your Azure resource must have a 'completions' model deployed, | ||
e.g. 'text-davinci-003'. | ||
""" | ||
response = azure_client.completions.create( | ||
model="gpt-4o", # Adjust to your actual Azure completions model name | ||
prompt=prompt, | ||
max_tokens=50, | ||
temperature=0.7 | ||
) | ||
return response.to_json() | ||
|
||
|
||
def get_embeddings(azure_client, text): | ||
""" | ||
Demonstrates Azure embeddings endpoint. | ||
Your Azure resource must have an embeddings model, e.g. 'text-embedding-ada-002'. | ||
""" | ||
response = azure_client.embeddings.create( | ||
model="text-embedding-ada-002", # Adjust to your embeddings model name | ||
input=text | ||
) | ||
return response.to_json() | ||
|
||
|
||
def main(): | ||
print("Azure OpenAI via Javelin Testing:") | ||
azure_client = initialize_client() | ||
if azure_client is None: | ||
print("Client initialization failed.") | ||
return | ||
|
||
# Example chat messages | ||
messages = [ | ||
{"role": "user", "content": "say hello"} | ||
] | ||
|
||
# 1) Chat Completion (Synchronous) | ||
try: | ||
print("\n--- Chat Completion (Non-Streaming) ---") | ||
response_chat_sync = get_chat_completion_sync(azure_client, messages) | ||
print("Response:\n", response_chat_sync) | ||
except Exception as e: | ||
print("Error in chat completion (sync):", e) | ||
|
||
# 2) Chat Completion (Streaming) | ||
try: | ||
print("\n--- Chat Completion (Streaming) ---") | ||
response_streamed = get_chat_completion_stream(azure_client, messages) | ||
print("Streamed Content:\n", response_streamed) | ||
except Exception as e: | ||
print("Error in chat completion (streaming):", e) | ||
|
||
# 3) Embeddings | ||
try: | ||
print("\n--- Embeddings ---") | ||
embed_text = "Sample text to embed." | ||
embed_resp = get_embeddings(azure_client, embed_text) | ||
print("Response:\n", embed_resp) | ||
except Exception as e: | ||
print("Error in embeddings:", e) | ||
|
||
print("\n--- Script complete. ---") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
import os | ||
import dotenv | ||
dotenv.load_dotenv() | ||
|
||
from langchain_openai import AzureChatOpenAI | ||
from langchain.schema import HumanMessage, SystemMessage, AIMessage | ||
from langchain.callbacks.base import BaseCallbackHandler | ||
from langchain.callbacks.manager import CallbackManager | ||
|
||
# | ||
# 1) Keys and Route Setup | ||
# | ||
print("Initializing environment variables...") | ||
|
||
azure_openai_api_key = os.getenv("AZURE_OPENAI_API_KEY") | ||
javelin_api_key = os.getenv("JAVELIN_API_KEY") | ||
|
||
# The name of your Azure deployment (e.g., "gpt-4") | ||
# or whatever you’ve set in Azure. | ||
# Must also match x-javelin-model if Javelin expects that. | ||
model_choice = "gpt-4" | ||
|
||
# Javelin route name, as registered in your javelin route dashboard | ||
route_name = "saviour" | ||
|
||
print("Azure OpenAI key:", "FOUND" if azure_openai_api_key else "MISSING") | ||
print("Javelin key:", "FOUND" if javelin_api_key else "MISSING") | ||
|
||
# | ||
# 2) Non-Streaming Client | ||
# | ||
llm_non_streaming = AzureChatOpenAI( | ||
openai_api_key=azure_openai_api_key, | ||
# Provide your actual API version | ||
api_version="2024-08-01-preview", | ||
# The base_url is Javelin’s universal route | ||
# pointing to your Azure endpoint: | ||
base_url="https://api-dev.javelin.live/v1/azureopenai/deployments/gpt-4/", | ||
validate_base_url=False, | ||
verbose=True, | ||
default_headers={ | ||
"x-api-key": javelin_api_key, | ||
"x-javelin-route": route_name, | ||
"x-javelin-model": model_choice, | ||
"x-javelin-provider": "https://javelinpreview.openai.azure.com/openai", | ||
}, | ||
streaming=False # Non-streaming | ||
) | ||
|
||
# | ||
# 3) Single-Turn Invoke (Non-Streaming) | ||
# | ||
def invoke_non_streaming(question: str) -> str: | ||
""" | ||
Sends a single user message to the non-streaming LLM | ||
and returns the text response. | ||
""" | ||
# Build the messages | ||
messages = [HumanMessage(content=question)] | ||
# Use .invoke(...) to get the LLM’s response | ||
response = llm_non_streaming.invoke(messages) | ||
# The response is usually an AIMessage. Return its content. | ||
return response.content | ||
|
||
# | ||
# 4) Single-Turn Streaming | ||
# We'll create a new LLM with streaming=True, plus a callback handler. | ||
# | ||
|
||
class StreamCallbackHandler(BaseCallbackHandler): | ||
""" | ||
Collects tokens as they are streamed, so we can return the final text. | ||
""" | ||
def __init__(self): | ||
self.tokens = [] | ||
|
||
def on_llm_new_token(self, token: str, **kwargs) -> None: | ||
self.tokens.append(token) | ||
|
||
|
||
def invoke_streaming(question: str) -> str: | ||
""" | ||
Sends a single user message to the LLM (streaming=True). | ||
Collects the tokens from the callback and returns them as a string. | ||
""" | ||
callback_handler = StreamCallbackHandler() | ||
callback_manager = CallbackManager([callback_handler]) | ||
|
||
# Create a streaming LLM | ||
llm_streaming = AzureChatOpenAI( | ||
openai_api_key=azure_openai_api_key, | ||
api_version="2024-08-01-preview", | ||
base_url="https://api-dev.javelin.live/v1/azureopenai/deployments/gpt-4/", | ||
validate_base_url=False, | ||
verbose=True, | ||
default_headers={ | ||
"x-api-key": javelin_api_key, | ||
"x-javelin-route": route_name, | ||
"x-javelin-model": model_choice, | ||
"x-javelin-provider": "https://javelinpreview.openai.azure.com/openai", | ||
}, | ||
streaming=True, # <-- streaming on | ||
callbacks=[callback_handler] # <-- our custom callback | ||
) | ||
|
||
messages = [HumanMessage(content=question)] | ||
response = llm_streaming.invoke(messages) | ||
# We could check response, but it's usually an AIMessage with partial content | ||
# The real text is captured in the callback tokens | ||
return "".join(callback_handler.tokens) | ||
|
||
# | ||
|
||
def conversation_demo(): | ||
""" | ||
Demonstrates a multi-turn conversation by manually | ||
appending messages to a list and re-invoking the LLM. | ||
No memory objects are used, so it’s purely manual. | ||
""" | ||
|
||
conversation_llm = llm_non_streaming | ||
|
||
# Start with a system message | ||
messages = [SystemMessage(content="You are a friendly assistant.")] | ||
|
||
user_q1 = "Hello, how are you?" | ||
messages.append(HumanMessage(content=user_q1)) | ||
response_1 = conversation_llm.invoke(messages) | ||
messages.append(response_1) # add AIMessage to context | ||
print(f"User: {user_q1}\nAssistant: {response_1.content}\n") | ||
|
||
user_q2 = "Can you tell me a fun fact about dolphins?" | ||
messages.append(HumanMessage(content=user_q2)) | ||
response_2 = conversation_llm.invoke(messages) | ||
messages.append(response_2) | ||
print(f"User: {user_q2}\nAssistant: {response_2.content}\n") | ||
|
||
return "Conversation done!" | ||
|
||
# | ||
# 6) Main function | ||
# | ||
|
||
def main(): | ||
print("=== LangChain AzureOpenAI Example ===") | ||
|
||
# 1) Single-turn non-streaming | ||
print("\n[1) Single-turn Non-Streaming Invoke]") | ||
question_a = "What is the capital of France?" | ||
response_a = invoke_non_streaming(question_a) | ||
print(f"Question: {question_a}\nAnswer: {response_a}") | ||
|
||
# 2) Single-turn streaming | ||
print("\n[2) Single-turn Streaming Invoke]") | ||
question_b = "Tell me a quick joke." | ||
response_b = invoke_streaming(question_b) | ||
print(f"Question: {question_b}\nStreamed Answer: {response_b}") | ||
|
||
# 3) Multi-turn conversation (non-streaming) | ||
print("\n[3) Simple Conversation Demo]") | ||
conversation_demo() | ||
|
||
print("\n=== All done! ===") | ||
|
||
if __name__ == "__main__": | ||
main() |
Oops, something went wrong.