From 356007346846ac494c80f5eb7aae30ad570625bf Mon Sep 17 00:00:00 2001 From: Dhruvj07 Date: Mon, 10 Feb 2025 11:28:31 +0530 Subject: [PATCH 1/6] feat : Added Universal javelin rout endpoints for openai, azureopen-ai, gemini, langchain openai with seperate directory notebooks --- examples/{ => agents}/agents.yaml | 0 examples/{ => agents}/crewai_javelin.ipynb | 0 examples/{ => agents}/langgraph_javelin.ipynb | 0 examples/{ => agents}/tasks.yaml | 0 .../azure_openai-unversal-rout.ipynb | 0 examples/bedrock/bedrock_client.ipynb | 0 examples/bedrock_client.py | 47 ---- examples/gemini/gemini_universal-rout.ipynb | 212 ++++++++++++++++++ .../langchain-openai-universal-rout.ipynb | 0 examples/openai/openai_universal-rout.ipynb | 0 .../{ => rag}/rag_implemetation_javelin.ipynb | 0 11 files changed, 212 insertions(+), 47 deletions(-) rename examples/{ => agents}/agents.yaml (100%) rename examples/{ => agents}/crewai_javelin.ipynb (100%) rename examples/{ => agents}/langgraph_javelin.ipynb (100%) rename examples/{ => agents}/tasks.yaml (100%) create mode 100644 examples/azure-openai/azure_openai-unversal-rout.ipynb create mode 100644 examples/bedrock/bedrock_client.ipynb delete mode 100644 examples/bedrock_client.py create mode 100644 examples/gemini/gemini_universal-rout.ipynb create mode 100644 examples/openai/langchain-openai-universal-rout.ipynb create mode 100644 examples/openai/openai_universal-rout.ipynb rename examples/{ => rag}/rag_implemetation_javelin.ipynb (100%) diff --git a/examples/agents.yaml b/examples/agents/agents.yaml similarity index 100% rename from examples/agents.yaml rename to examples/agents/agents.yaml diff --git a/examples/crewai_javelin.ipynb b/examples/agents/crewai_javelin.ipynb similarity index 100% rename from examples/crewai_javelin.ipynb rename to examples/agents/crewai_javelin.ipynb diff --git a/examples/langgraph_javelin.ipynb b/examples/agents/langgraph_javelin.ipynb similarity index 100% rename from examples/langgraph_javelin.ipynb rename to examples/agents/langgraph_javelin.ipynb diff --git a/examples/tasks.yaml b/examples/agents/tasks.yaml similarity index 100% rename from examples/tasks.yaml rename to examples/agents/tasks.yaml diff --git a/examples/azure-openai/azure_openai-unversal-rout.ipynb b/examples/azure-openai/azure_openai-unversal-rout.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/examples/bedrock/bedrock_client.ipynb b/examples/bedrock/bedrock_client.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/examples/bedrock_client.py b/examples/bedrock_client.py deleted file mode 100644 index 1a55273..0000000 --- a/examples/bedrock_client.py +++ /dev/null @@ -1,47 +0,0 @@ -import json -import os -import boto3 -import dotenv -from javelin_sdk import ( - JavelinClient, - JavelinConfig, -) - -dotenv.load_dotenv() - -# Retrieve environment variables -javelin_api_key = os.getenv("JAVELIN_API_KEY") - -# Initialize Bedrock Client -bedrock_client = boto3.client( - service_name="bedrock-runtime", - region_name="us-east-1" -) - - -# Initialize Javelin Client -config = JavelinConfig( - base_url="https://api-dev.javelin.live", - javelin_api_key=javelin_api_key, -) -client = JavelinClient(config) -client.register_bedrock_runtime(bedrock_client) - - -# Call Bedrock Model -response = bedrock_client.invoke_model( - modelId="anthropic.claude-3-sonnet-20240229-v1:0", - body=json.dumps({ - "anthropic_version": "bedrock-2023-05-31", - "max_tokens": 100, - "messages": [ - { - "content": "What is machine learning?", - "role": "user" - } - ] - }), - contentType="application/json" - ) -response_body = json.loads(response["body"].read()) -print(f"Invoke Response: {json.dumps(response_body, indent=2)}") diff --git a/examples/gemini/gemini_universal-rout.ipynb b/examples/gemini/gemini_universal-rout.ipynb new file mode 100644 index 0000000..6eadbab --- /dev/null +++ b/examples/gemini/gemini_universal-rout.ipynb @@ -0,0 +1,212 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Gemini Notebook \n", + "This notebook demonstrates the usage of Gemini APIs integrated with Javelin.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initializing Gemini client...\n" + ] + }, + { + "ename": "ValueError", + "evalue": "GEMINI_API_KEY is not set!", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 17\u001b[0m\n\u001b[1;32m 15\u001b[0m gemini_api_key \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39mgetenv(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGEMINI_API_KEY\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 16\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m gemini_api_key:\n\u001b[0;32m---> 17\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGEMINI_API_KEY is not set!\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 18\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGemini API Key loaded successfully.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 19\u001b[0m \u001b[38;5;66;03m# Create an OpenAI client configured for Gemini with the appropriate base URL\u001b[39;00m\n", + "\u001b[0;31mValueError\u001b[0m: GEMINI_API_KEY is not set!" + ] + } + ], + "source": [ + "import json\n", + "import os\n", + "from openai import OpenAI\n", + "from javelin_sdk import (\n", + " JavelinClient,\n", + " JavelinConfig,\n", + ")\n", + "\n", + "# -------------------------------\n", + "# Gemini API Example\n", + "# -------------------------------\n", + "print(\"Initializing Gemini client...\")\n", + "\n", + "# Retrieve the Gemini API key from the environment variable\n", + "gemini_api_key = os.getenv(\"GEMINI_API_KEY\")\n", + "if not gemini_api_key:\n", + " raise ValueError(\"GEMINI_API_KEY is not set!\")\n", + "print(\"Gemini API Key loaded successfully.\")\n", + "# Create an OpenAI client configured for Gemini with the appropriate base URL\n", + "openai_client = OpenAI(\n", + " api_key=gemini_api_key,\n", + " base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\"\n", + ")\n", + "\n", + "# Initialize the Javelin Client (using the same javelin_api_key as before)\n", + "javelin_api_key = os.getenv('JAVELIN_API_KEY')\n", + "config = JavelinConfig(\n", + " base_url=\"https://api-dev.javelin.live\",\n", + " # Uncomment the following line to use a local server:\n", + " # base_url=\"http://localhost:8000\",\n", + " javelin_api_key=javelin_api_key,\n", + ")\n", + "client = JavelinClient(config)\n", + "\n", + "# Register the Gemini client with Javelin\n", + "client.register_gemini(openai_client, route_name=\"testing\")\n", + "\n", + "print(\"Gemini: 1 - Chat completions\")\n", + "response = openai_client.chat.completions.create(\n", + " model=\"gemini-1.5-flash\",\n", + " n=1,\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + " {\"role\": \"user\", \"content\": \"Explain to me how AI works\"}\n", + " ]\n", + ")\n", + "print(response.model_dump_json(indent=2))\n", + "\n", + "print(\"Gemini: 2 - Streaming\")\n", + "response = openai_client.chat.completions.create(\n", + " model=\"gemini-1.5-flash\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"You are a helpful assistant.\"},\n", + " {\"role\": \"user\", \"content\": \"Hello!\"}\n", + " ],\n", + " stream=True\n", + ")\n", + "for chunk in response:\n", + " # Debug print: output each streaming chunk's delta\n", + " print(chunk.choices[0].delta)\n", + "\n", + "print(\"Gemini: 3 - Function calling\")\n", + "tools = [\n", + " {\n", + " \"type\": \"function\",\n", + " \"function\": {\n", + " \"name\": \"get_weather\",\n", + " \"description\": \"Get the weather in a given location\",\n", + " \"parameters\": {\n", + " \"type\": \"object\",\n", + " \"properties\": {\n", + " \"location\": {\n", + " \"type\": \"string\",\n", + " \"description\": \"The city and state, e.g. Chicago, IL\",\n", + " },\n", + " \"unit\": {\"type\": \"string\", \"enum\": [\"celsius\", \"fahrenheit\"]},\n", + " },\n", + " \"required\": [\"location\"],\n", + " },\n", + " }\n", + " }\n", + "]\n", + "messages = [{\"role\": \"user\", \"content\": \"What's the weather like in Chicago today?\"}]\n", + "response = openai_client.chat.completions.create(\n", + " model=\"gemini-1.5-flash\",\n", + " messages=messages,\n", + " tools=tools,\n", + " tool_choice=\"auto\"\n", + ")\n", + "print(response.model_dump_json(indent=2))\n", + "\n", + "# --- Gemini Image Understanding Example (Commented Out) ---\n", + "'''\n", + "print(\"Gemini: 4 - Image understanding\")\n", + "import base64\n", + "\n", + "# Function to encode the image in base64 format\n", + "def encode_image(image_path):\n", + " with open(image_path, \"rb\") as image_file:\n", + " return base64.b64encode(image_file.read()).decode('utf-8')\n", + "\n", + "# Convert an image to a base64 string\n", + "base64_image = encode_image(\"Path/to/agi/image.jpeg\")\n", + "\n", + "response = client.chat.completions.create(\n", + " model=\"gemini-1.5-flash\",\n", + " messages=[\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": [\n", + " {\"type\": \"text\", \"text\": \"What is in this image?\"},\n", + " {\"type\": \"image_url\", \"image_url\": {\"url\": f\"data:image/jpeg;base64,{base64_image}\"}},\n", + " ],\n", + " }\n", + " ],\n", + ")\n", + "print(response.model_dump_json(indent=2))\n", + "'''\n", + "\n", + "print(\"Gemini: 5 - Structured output\")\n", + "from pydantic import BaseModel\n", + "class CalendarEvent(BaseModel):\n", + " name: str\n", + " date: str\n", + " participants: list[str]\n", + "\n", + "completion = openai_client.beta.chat.completions.parse(\n", + " model=\"gemini-1.5-flash\",\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": \"Extract the event information.\"},\n", + " {\"role\": \"user\", \"content\": \"John and Susan are going to an AI conference on Friday.\"},\n", + " ],\n", + " response_format=CalendarEvent,\n", + ")\n", + "print(completion.model_dump_json(indent=2))\n", + "\n", + "print(\"Gemini: 6 - Embeddings\")\n", + "response = openai_client.embeddings.create(\n", + " input=\"Your text string goes here\",\n", + " model=\"text-embedding-004\"\n", + ")\n", + "print(response.model_dump_json(indent=2))\n", + "\n", + "# Prints two blank lines for clarity\n", + "print(\"\\n\\n\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/openai/langchain-openai-universal-rout.ipynb b/examples/openai/langchain-openai-universal-rout.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/examples/openai/openai_universal-rout.ipynb b/examples/openai/openai_universal-rout.ipynb new file mode 100644 index 0000000..e69de29 diff --git a/examples/rag_implemetation_javelin.ipynb b/examples/rag/rag_implemetation_javelin.ipynb similarity index 100% rename from examples/rag_implemetation_javelin.ipynb rename to examples/rag/rag_implemetation_javelin.ipynb From c30ddaa7596c4bb5691bd234a8d0e6f3fb298224 Mon Sep 17 00:00:00 2001 From: Dhruvj07 Date: Mon, 10 Feb 2025 13:56:13 +0530 Subject: [PATCH 2/6] fix: No open ai credentials passed --- .../langchain-openai-universal-rout.ipynb | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/examples/openai/langchain-openai-universal-rout.ipynb b/examples/openai/langchain-openai-universal-rout.ipynb index e69de29..a8fcb37 100644 --- a/examples/openai/langchain-openai-universal-rout.ipynb +++ b/examples/openai/langchain-openai-universal-rout.ipynb @@ -0,0 +1,108 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "import nest_asyncio\n", + "nest_asyncio.apply()" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Answer: The chemical composition of water is H2O, which means it is made up of two hydrogen atoms and one oxygen atom.\n" + ] + } + ], + "source": [ + "from langchain_openai import ChatOpenAI\n", + "from langchain_core.prompts import ChatPromptTemplate\n", + "from langchain_core.output_parsers import StrOutputParser\n", + "import os\n", + "from dotenv import load_dotenv\n", + "\n", + "# Load environment variables if desired\n", + "load_dotenv()\n", + "\n", + "# API keys – replace these with your actual keys or use os.getenv\n", + "openai_api_key = \"\" # set your open ai key here\n", + "javelin_api_key = \"\" # set your javelin api key here\n", + "\n", + "\n", + "# Set the model dynamically (change this value as needed)\n", + "model_choice = \"gpt-4\" # For example, change to \"gpt-4\" for testing\n", + "route_name = \"\" #set your route name here\n", + "# Create LangChain OpenAI client using Javelin’s universal endpoint\n", + "# Here, the base URL is set to the provider's endpoint (\"/openai\")\n", + "# and the header \"x-javelin-route\" is set to the registered route (\"openai-univ\").\n", + "llm = ChatOpenAI(\n", + " openai_api_key=openai_api_key,\n", + " openai_api_base=\"https://api-dev.javelin.live/v1/openai\",\n", + " model_name=model_choice, # dynamically set the model here\n", + " default_headers={\n", + " \"x-api-key\": javelin_api_key,\n", + " \"x-javelin-route\": route_name, # the route name registered via Javelin\n", + " }\n", + ")\n", + "\n", + "# Define a simple prompt template\n", + "prompt = ChatPromptTemplate.from_messages([\n", + " (\"system\", \"You are a helpful assistant.\"),\n", + " (\"user\", \"{input}\")\n", + "])\n", + "\n", + "# Use a simple output parser (string output)\n", + "output_parser = StrOutputParser()\n", + "\n", + "# Create the processing chain (prompt -> LLM -> parser)\n", + "chain = prompt | llm | output_parser\n", + "\n", + "def ask_question(question: str) -> str:\n", + " return chain.invoke({\"input\": question})\n", + "\n", + "# Example usage:\n", + "if __name__ == \"__main__\":\n", + " question = \"What is the chemical composition of water?\"\n", + " answer = ask_question(question)\n", + " print(\"Answer:\", answer)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 8f922731720d9ca7420fa8e97b3420084cc0902d Mon Sep 17 00:00:00 2001 From: Dhruvj07 Date: Mon, 10 Feb 2025 20:35:26 +0530 Subject: [PATCH 3/6] feat: added universal endpoint files --- .../azure_openai-unversal-rout.ipynb | 220 +++++++++++++++ examples/bedrock/bedrock_client.ipynb | 73 +++++ .../langchain-openai-universal-rout.ipynb | 22 +- examples/openai/openai_universal-rout.ipynb | 264 ++++++++++++++++++ 4 files changed, 569 insertions(+), 10 deletions(-) diff --git a/examples/azure-openai/azure_openai-unversal-rout.ipynb b/examples/azure-openai/azure_openai-unversal-rout.ipynb index e69de29..235420a 100644 --- a/examples/azure-openai/azure_openai-unversal-rout.ipynb +++ b/examples/azure-openai/azure_openai-unversal-rout.ipynb @@ -0,0 +1,220 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Azure OpenAI Notebook \n", + "This notebook demonstrates the Azure OpenAI integration with Javelin. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Azure OpenAI: 1 - Chat completions\n", + "JAVELIN_API_KEY found.\n", + "AZURE_OPENAI_API_KEY found.\n", + "Azure OpenAI Response:\n", + "{\n", + " \"id\": \"chatcmpl-AzNxNrIUPWZYkyKZ3kk4UbsVIofN7\",\n", + " \"choices\": [\n", + " {\n", + " \"finish_reason\": \"stop\",\n", + " \"index\": 0,\n", + " \"message\": {\n", + " \"content\": \"You can use the `os` module to list all files in a directory. Here is an example on how to do it:\\n\\n```python\\nimport os\\n\\ndirectory_path = 'path/to/directory'\\n\\nfor file_name in os.listdir(directory_path):\\n file_path = os.path.join(directory_path, file_name)\\n if os.path.isfile(file_path):\\n print(file_name)\\n```\\n\\nThis script imports the `os` module, specifies the directory path, and then iterates over each item in the directory using `os.listdir()`. It checks if the item is a file using `os.path.isfile()` and if it is, prints the file name. Remember to replace `'path/to/directory'` with the actual path to the directory you want to list the files from.\",\n", + " \"role\": \"assistant\"\n", + " },\n", + " \"content_filter_results\": {\n", + " \"hate\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " },\n", + " \"protected_material_code\": {\n", + " \"detected\": false,\n", + " \"filtered\": false\n", + " },\n", + " \"protected_material_text\": {\n", + " \"detected\": false,\n", + " \"filtered\": false\n", + " },\n", + " \"self_harm\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " },\n", + " \"sexual\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " },\n", + " \"violence\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " }\n", + " }\n", + " }\n", + " ],\n", + " \"created\": 1739193461,\n", + " \"model\": \"gpt-4-turbo-2024-04-09\",\n", + " \"object\": \"chat.completion\",\n", + " \"system_fingerprint\": \"fp_5603ee5e2e\",\n", + " \"usage\": {\n", + " \"completion_tokens\": 157,\n", + " \"prompt_tokens\": 19,\n", + " \"total_tokens\": 176\n", + " },\n", + " \"javelin\": {\n", + " \"archive_enabled\": true,\n", + " \"correlation_id\": \"01JKR04ADSN6V7BSYMYC3WWBYJ\",\n", + " \"model_endpoint_url\": \"https://javelinpreview.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2023-07-01-preview\",\n", + " \"model_latency\": \"6.660289685s\",\n", + " \"model_name\": \"gpt-4\",\n", + " \"processor_outputs\": {\n", + " \"request.chain.archive_processor_20250210131747.844624394\": {\n", + " \"duration\": \"4.476699ms\",\n", + " \"success\": \"successfully archived memory\"\n", + " },\n", + " \"request.chain.dlp_gcp_processor_20250210131747.844562167\": {\n", + " \"duration\": \"108.063µs\",\n", + " \"skipped\": \"warn: sensitive data protection is disabled for route:openai-univ\"\n", + " },\n", + " \"request.chain.promptinjectiondetection_processor_20250210131747.844523092\": {\n", + " \"duration\": \"142.292µs\",\n", + " \"skipped\": \"warn: prompt safety is disabled for route:openai-univ\"\n", + " },\n", + " \"request.chain.ratelimit_processor_20250210131747.844543051\": {\n", + " \"duration\": \"57.734µs\"\n", + " },\n", + " \"request.chain.secrets_processor_20250210131747.844592731\": {\n", + " \"duration\": \"13µs\"\n", + " },\n", + " \"response.chain.response_processor_20250210131747.844410535\": {\n", + " \"duration\": \"0s\"\n", + " },\n", + " \"response.chain.trustsafety_processor_20250210131747.844386942\": {\n", + " \"duration\": \"55.392µs\",\n", + " \"skipped\": \"warn: trust safety is disabled for route:openai-univ\"\n", + " }\n", + " },\n", + " \"route_name\": \"openai-univ\"\n", + " },\n", + " \"prompt_filter_results\": [\n", + " {\n", + " \"content_filter_results\": {\n", + " \"hate\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " },\n", + " \"jailbreak\": {\n", + " \"detected\": false,\n", + " \"filtered\": false\n", + " },\n", + " \"self_harm\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " },\n", + " \"sexual\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " },\n", + " \"violence\": {\n", + " \"filtered\": false,\n", + " \"severity\": \"safe\"\n", + " }\n", + " },\n", + " \"prompt_index\": 0\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "import os\n", + "from openai import AzureOpenAI\n", + "from javelin_sdk import JavelinClient, JavelinConfig\n", + "\n", + "print(\"Azure OpenAI: 1 - Chat completions\")\n", + "\n", + "# Retrieve the Javelin API key.\n", + "javelin_api_key = \"\" # add your javelin key here\n", + "if not javelin_api_key:\n", + " print(\"Error: JAVELIN_API_KEY environment variable is not set!\")\n", + "else:\n", + " print(\"JAVELIN_API_KEY found.\")\n", + "\n", + "# Retrieve the Azure OpenAI API key.\n", + "azure_openai_api_key = \"\" # add your azure openai key here\n", + "if not azure_openai_api_key:\n", + " print(\"Warning: AZURE_OPENAI_API_KEY environment variable is not set!\")\n", + "else:\n", + " print(\"AZURE_OPENAI_API_KEY found.\")\n", + "\n", + "# Create the AzureOpenAI client.\n", + "# IMPORTANT: Specify the azure_deployment parameter to match your Azure model deployment name.\n", + "openai_client = AzureOpenAI(\n", + " api_version=\"2023-07-01-preview\",\n", + " azure_endpoint=\"https://javelinpreview.openai.azure.com\",\n", + " api_key=azure_openai_api_key\n", + ")\n", + "\n", + "# Initialize the Javelin Client.\n", + "config = JavelinConfig(\n", + " base_url=\"https://api-dev.javelin.live\",\n", + " # base_url=\"http://localhost:8000\",\n", + " javelin_api_key=javelin_api_key,\n", + ")\n", + "client = JavelinClient(config)\n", + "client.register_azureopenai(openai_client, route_name=\"openai-univ\")\n", + "\n", + "# Call the Azure OpenAI endpoint for chat completions.\n", + "completion = openai_client.chat.completions.create(\n", + " model=\"gpt-4\", # e.g. gpt-35-instant\n", + " messages=[\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"How do I output all files in a directory using Python?\",\n", + " },\n", + " ],\n", + ")\n", + "\n", + "# Print the response as JSON.\n", + "print(\"Azure OpenAI Response:\")\n", + "print(completion.to_json())\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/bedrock/bedrock_client.ipynb b/examples/bedrock/bedrock_client.ipynb index e69de29..87bc2c1 100644 --- a/examples/bedrock/bedrock_client.ipynb +++ b/examples/bedrock/bedrock_client.ipynb @@ -0,0 +1,73 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Bedrock Notebook" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import os\n", + "import boto3\n", + "import dotenv\n", + "from javelin_sdk import (\n", + " JavelinClient,\n", + " JavelinConfig,\n", + ")\n", + "\n", + "dotenv.load_dotenv()\n", + "\n", + "# Retrieve environment variables\n", + "javelin_api_key = os.getenv(\"JAVELIN_API_KEY\")\n", + "\n", + "# Initialize Bedrock Client\n", + "bedrock_client = boto3.client(\n", + " service_name=\"bedrock-runtime\",\n", + " region_name=\"us-east-1\"\n", + ")\n", + "\n", + "\n", + "# Initialize Javelin Client\n", + "config = JavelinConfig(\n", + " base_url=\"https://api-dev.javelin.live\",\n", + " javelin_api_key=javelin_api_key,\n", + ")\n", + "client = JavelinClient(config)\n", + "client.register_bedrock_runtime(bedrock_client)\n", + "\n", + "\n", + "# Call Bedrock Model\n", + "response = bedrock_client.invoke_model(\n", + " modelId=\"anthropic.claude-3-sonnet-20240229-v1:0\",\n", + " body=json.dumps({\n", + " \"anthropic_version\": \"bedrock-2023-05-31\",\n", + " \"max_tokens\": 100,\n", + " \"messages\": [\n", + " {\n", + " \"content\": \"What is machine learning?\",\n", + " \"role\": \"user\"\n", + " }\n", + " ]\n", + " }),\n", + " contentType=\"application/json\"\n", + " )\n", + "response_body = json.loads(response[\"body\"].read())\n", + "print(f\"Invoke Response: {json.dumps(response_body, indent=2)}\")" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/openai/langchain-openai-universal-rout.ipynb b/examples/openai/langchain-openai-universal-rout.ipynb index a8fcb37..395ae96 100644 --- a/examples/openai/langchain-openai-universal-rout.ipynb +++ b/examples/openai/langchain-openai-universal-rout.ipynb @@ -12,14 +12,14 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Answer: The chemical composition of water is H2O, which means it is made up of two hydrogen atoms and one oxygen atom.\n" + "Answer: Water is a simple molecule with a chemical composition of H2O, which means that each water molecule consists of two hydrogen atoms bonded to one oxygen atom.\n" ] } ], @@ -28,32 +28,34 @@ "from langchain_core.prompts import ChatPromptTemplate\n", "from langchain_core.output_parsers import StrOutputParser\n", "import os\n", - "from dotenv import load_dotenv\n", "\n", - "# Load environment variables if desired\n", - "load_dotenv()\n", "\n", "# API keys – replace these with your actual keys or use os.getenv\n", "openai_api_key = \"\" # set your open ai key here\n", - "javelin_api_key = \"\" # set your javelin api key here\n", + "javelin_api_key = \"\" #ser your javelin key here\n", "\n", "\n", "# Set the model dynamically (change this value as needed)\n", - "model_choice = \"gpt-4\" # For example, change to \"gpt-4\" for testing\n", - "route_name = \"\" #set your route name here\n", + "model_choice = \"gpt-3.5-turbo\" # For example, change to \"gpt-4\" for testing\n", + "route_name = \"openai-univ\" #set your route name here\n", "# Create LangChain OpenAI client using Javelin’s universal endpoint\n", "# Here, the base URL is set to the provider's endpoint (\"/openai\")\n", "# and the header \"x-javelin-route\" is set to the registered route (\"openai-univ\").\n", + "\n", + "\n", "llm = ChatOpenAI(\n", " openai_api_key=openai_api_key,\n", " openai_api_base=\"https://api-dev.javelin.live/v1/openai\",\n", - " model_name=model_choice, # dynamically set the model here\n", " default_headers={\n", " \"x-api-key\": javelin_api_key,\n", - " \"x-javelin-route\": route_name, # the route name registered via Javelin\n", + " \"x-javelin-route\": route_name,\n", + " # \"x-javelin-provider\": \"https://api.openai.com/v1\",\n", + " \"x-javelin-model\":model_choice\n", + " \n", " }\n", ")\n", "\n", + "\n", "# Define a simple prompt template\n", "prompt = ChatPromptTemplate.from_messages([\n", " (\"system\", \"You are a helpful assistant.\"),\n", diff --git a/examples/openai/openai_universal-rout.ipynb b/examples/openai/openai_universal-rout.ipynb index e69de29..75d9723 100644 --- a/examples/openai/openai_universal-rout.ipynb +++ b/examples/openai/openai_universal-rout.ipynb @@ -0,0 +1,264 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# OpenAI Notebook \n", + "This notebook demonstrates the usage of synchronous and asynchronous OpenAI endpoints integrated with Javelin.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Initializing Synchronous OpenAI client...\n", + "sk-proj-bF54IwKWyN9SbdpGrnS4T3BlbkFJ6PyfIsqqoifSnyMzx9ae\n", + "OpenAI: 1 - Chat completions\n", + "{\n", + " \"id\": \"chatcmpl-AzKXhek0wiLY41sTGfT6qBW5sT1EA\",\n", + " \"choices\": [\n", + " {\n", + " \"finish_reason\": \"stop\",\n", + " \"index\": 0,\n", + " \"logprobs\": null,\n", + " \"message\": {\n", + " \"content\": \"Machine learning is a subset of artificial intelligence (AI) that involves constructing algorithms and statistical models that allow computers to learn from and make predictions or decisions based on data without being explicitly programmed. Machine learning algorithms identify patterns in data and use that information to improve their performance over time. This technology is used in a wide range of applications, including image and speech recognition, recommendation systems, fraud detection, medical diagnosis, and many others.\",\n", + " \"refusal\": null,\n", + " \"role\": \"assistant\",\n", + " \"audio\": null,\n", + " \"function_call\": null,\n", + " \"tool_calls\": null\n", + " }\n", + " }\n", + " ],\n", + " \"created\": 1739180337,\n", + " \"model\": \"gpt-3.5-turbo-0125\",\n", + " \"object\": \"chat.completion\",\n", + " \"service_tier\": \"default\",\n", + " \"system_fingerprint\": null,\n", + " \"usage\": {\n", + " \"completion_tokens\": 86,\n", + " \"prompt_tokens\": 12,\n", + " \"total_tokens\": 98,\n", + " \"completion_tokens_details\": {\n", + " \"accepted_prediction_tokens\": 0,\n", + " \"audio_tokens\": 0,\n", + " \"reasoning_tokens\": 0,\n", + " \"rejected_prediction_tokens\": 0\n", + " },\n", + " \"prompt_tokens_details\": {\n", + " \"audio_tokens\": 0,\n", + " \"cached_tokens\": 0\n", + " }\n", + " },\n", + " \"javelin\": {\n", + " \"archive_enabled\": true,\n", + " \"correlation_id\": \"01JKQKKTFANF3PA3GB7866VMGV\",\n", + " \"model_endpoint_url\": \"https://api.openai.com/v1/chat/completions\",\n", + " \"model_latency\": \"943.195026ms\",\n", + " \"model_name\": \"gpt-3.5-turbo\",\n", + " \"processor_outputs\": {\n", + " \"request.chain.archive_processor_20250210093858.597264197\": {\n", + " \"duration\": \"4.985534ms\",\n", + " \"success\": \"successfully archived memory\"\n", + " },\n", + " \"request.chain.dlp_gcp_processor_20250210093858.597381862\": {\n", + " \"duration\": \"66.605µs\",\n", + " \"skipped\": \"warn: sensitive data protection is disabled for route:openai-univ\"\n", + " },\n", + " \"request.chain.promptinjectiondetection_processor_20250210093858.597346110\": {\n", + " \"duration\": \"82.097µs\",\n", + " \"skipped\": \"warn: prompt safety is disabled for route:openai-univ\"\n", + " },\n", + " \"request.chain.ratelimit_processor_20250210093858.597364325\": {\n", + " \"duration\": \"52.993µs\"\n", + " },\n", + " \"request.chain.secrets_processor_20250210093858.597439995\": {\n", + " \"duration\": \"10.313µs\"\n", + " },\n", + " \"response.chain.response_processor_20250210093858.597321120\": {\n", + " \"duration\": \"0s\"\n", + " },\n", + " \"response.chain.trustsafety_processor_20250210093858.597283100\": {\n", + " \"duration\": \"53.485µs\",\n", + " \"skipped\": \"warn: trust safety is disabled for route:openai-univ\"\n", + " }\n", + " },\n", + " \"route_name\": \"openai-univ\"\n", + " }\n", + "}\n" + ] + } + ], + "source": [ + "import json\n", + "import os\n", + "import sys\n", + "import asyncio\n", + "from openai import OpenAI\n", + "from openai import AsyncOpenAI\n", + "from openai import AzureOpenAI # Imported for consistency, though not used in this notebook\n", + "import dotenv\n", + "from javelin_sdk import (\n", + " JavelinClient,\n", + " JavelinConfig,\n", + ")\n", + "\n", + "# -------------------------------\n", + "# Synchronous OpenAI Example\n", + "# -------------------------------\n", + "print(\"Initializing Synchronous OpenAI client...\")\n", + "\n", + "# Create OpenAI client using the API key from the environment variable\n", + "openai_api_key = os.environ[\"OPENAI_API_KEY\"] = \"\"\n", + "print(openai_api_key)\n", + "openai_client = OpenAI(api_key=openai_api_key)\n", + "\n", + "# Initialize Javelin Client with your API key and base URL\n", + "javelin_api_key = os.environ['JAVELIN_API_KEY'] = \"\"\n", + "config = JavelinConfig(\n", + " base_url=\"https://api-dev.javelin.live\",\n", + " # Uncomment the following line to use a local server:\n", + " # base_url=\"http://localhost:8000\",\n", + " javelin_api_key=javelin_api_key,\n", + ")\n", + "client = JavelinClient(config)\n", + "\n", + "# Register the OpenAI client with Javelin using the route name \"openai\"\n", + "client.register_openai(openai_client, route_name=\"openai-univ\")\n", + "\n", + "# --- Call OpenAI Endpoints ---\n", + "\n", + "print(\"OpenAI: 1 - Chat completions\")\n", + "chat_completions = openai_client.chat.completions.create(\n", + " model=\"gpt-3.5-turbo\",\n", + " messages=[{\"role\": \"user\", \"content\": \"What is machine learning?\"}],\n", + ")\n", + "print(chat_completions.model_dump_json(indent=2))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "print(\"OpenAI: 2 - Completions\")\n", + "completions = openai_client.completions.create(\n", + " model=\"gpt-3.5-turbo-instruct\",\n", + " prompt=\"What is machine learning?\",\n", + " max_tokens=7,\n", + " temperature=0\n", + ")\n", + "print(completions.model_dump_json(indent=2))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "print(\"OpenAI: 3 - Embeddings\")\n", + "embeddings = openai_client.embeddings.create(\n", + " model=\"text-embedding-ada-002\",\n", + " input=\"The food was delicious and the waiter...\",\n", + " encoding_format=\"float\"\n", + ")\n", + "print(embeddings.model_dump_json(indent=2))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "print(\"OpenAI: 4 - Streaming\")\n", + "stream = openai_client.chat.completions.create(\n", + " messages=[\n", + " {\"role\": \"user\", \"content\": \"Say this is a test\"}\n", + " ],\n", + " model=\"gpt-4o\",\n", + " stream=True,\n", + ")\n", + "for chunk in stream:\n", + " # Debug print: show each streaming chunk\n", + " print(chunk.choices[0].delta.content or \"\", end=\"\")\n", + "\n", + "# Prints two blank lines for clarity\n", + "print(\"\\n\\n\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# -------------------------------\n", + "# Asynchronous OpenAI Example\n", + "# -------------------------------\n", + "print(\"Initializing AsyncOpenAI client...\")\n", + "\n", + "# Create AsyncOpenAI client\n", + "openai_async_client = AsyncOpenAI(\n", + " api_key=os.environ.get(\"OPENAI_API_KEY\"), # This is the default and can be omitted\n", + ")\n", + "\n", + "# Reinitialize Javelin Client for Async usage (using the same config)\n", + "javelin_api_key = os.getenv('JAVELIN_API_KEY')\n", + "config = JavelinConfig(\n", + " base_url=\"https://api-dev.javelin.live\",\n", + " # base_url=\"http://localhost:8000\",\n", + " javelin_api_key=javelin_api_key,\n", + ")\n", + "client = JavelinClient(config)\n", + "client.register_openai(openai_async_client, route_name=\"openai\")\n", + "\n", + "async def main() -> None:\n", + " chat_completion = await openai_async_client.chat.completions.create(\n", + " messages=[\n", + " {\"role\": \"user\", \"content\": \"Say this is a test\"}\n", + " ],\n", + " model=\"gpt-4o\",\n", + " )\n", + " print(chat_completion.model_dump_json(indent=2))\n", + "\n", + "print(\"AsyncOpenAI: 5 - Chat completions\")\n", + "asyncio.run(main())\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 423b8950cb07e7da12731665f05adf688d3279d6 Mon Sep 17 00:00:00 2001 From: Dhruvj07 Date: Tue, 11 Feb 2025 10:13:45 +0530 Subject: [PATCH 4/6] fix: Removed rout from javelin config --- .../azure_openai-unversal-rout.ipynb | 46 +++++++++---------- examples/openai/openai_universal-rout.ipynb | 44 +++++++++--------- 2 files changed, 43 insertions(+), 47 deletions(-) diff --git a/examples/azure-openai/azure_openai-unversal-rout.ipynb b/examples/azure-openai/azure_openai-unversal-rout.ipynb index 235420a..07750a9 100644 --- a/examples/azure-openai/azure_openai-unversal-rout.ipynb +++ b/examples/azure-openai/azure_openai-unversal-rout.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -22,13 +22,13 @@ "AZURE_OPENAI_API_KEY found.\n", "Azure OpenAI Response:\n", "{\n", - " \"id\": \"chatcmpl-AzNxNrIUPWZYkyKZ3kk4UbsVIofN7\",\n", + " \"id\": \"chatcmpl-AzcJkS7tUwH78qRCND7kIBKuxS1d9\",\n", " \"choices\": [\n", " {\n", " \"finish_reason\": \"stop\",\n", " \"index\": 0,\n", " \"message\": {\n", - " \"content\": \"You can use the `os` module to list all files in a directory. Here is an example on how to do it:\\n\\n```python\\nimport os\\n\\ndirectory_path = 'path/to/directory'\\n\\nfor file_name in os.listdir(directory_path):\\n file_path = os.path.join(directory_path, file_name)\\n if os.path.isfile(file_path):\\n print(file_name)\\n```\\n\\nThis script imports the `os` module, specifies the directory path, and then iterates over each item in the directory using `os.listdir()`. It checks if the item is a file using `os.path.isfile()` and if it is, prints the file name. Remember to replace `'path/to/directory'` with the actual path to the directory you want to list the files from.\",\n", + " \"content\": \"To output all files in a directory using Python, you can use the `os` module, which provides functions for interacting with the operating system. Here's an example of how you can list all files in a directory:\\n\\n```python\\nimport os\\n\\n# Specify the directory path\\ndirectory_path = '/path/to/directory'\\n\\n# List all files in the directory\\nfiles = os.listdir(directory_path)\\n\\n# Loop through the files and print their names\\nfor file in files:\\n full_path = os.path.join(directory_path, file)\\n if os.path.isfile(full_path):\\n print(file)\\n```\\n\\nIn this example, you need to replace `'/path/to/directory'` with the path to the directory where you want to list the files. The `os.listdir()` function returns a list of all files and directories in the specified directory. The `os.path.join()` function is used to get the full path of each file, and `os.path.isfile()` checks if the path points to a file (as opposed to a directory). Finally, the program prints the names of all files in the directory.\",\n", " \"role\": \"assistant\"\n", " },\n", " \"content_filter_results\": {\n", @@ -59,45 +59,45 @@ " }\n", " }\n", " ],\n", - " \"created\": 1739193461,\n", + " \"created\": 1739248664,\n", " \"model\": \"gpt-4-turbo-2024-04-09\",\n", " \"object\": \"chat.completion\",\n", " \"system_fingerprint\": \"fp_5603ee5e2e\",\n", " \"usage\": {\n", - " \"completion_tokens\": 157,\n", + " \"completion_tokens\": 223,\n", " \"prompt_tokens\": 19,\n", - " \"total_tokens\": 176\n", + " \"total_tokens\": 242\n", " },\n", " \"javelin\": {\n", " \"archive_enabled\": true,\n", - " \"correlation_id\": \"01JKR04ADSN6V7BSYMYC3WWBYJ\",\n", + " \"correlation_id\": \"01JKSMS04GVV657Y9AQEDRD7YP\",\n", " \"model_endpoint_url\": \"https://javelinpreview.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2023-07-01-preview\",\n", - " \"model_latency\": \"6.660289685s\",\n", + " \"model_latency\": \"5.762334998s\",\n", " \"model_name\": \"gpt-4\",\n", " \"processor_outputs\": {\n", - " \"request.chain.archive_processor_20250210131747.844624394\": {\n", - " \"duration\": \"4.476699ms\",\n", + " \"request.chain.archive_processor_20250211043750.507405930\": {\n", + " \"duration\": \"11.410459ms\",\n", " \"success\": \"successfully archived memory\"\n", " },\n", - " \"request.chain.dlp_gcp_processor_20250210131747.844562167\": {\n", - " \"duration\": \"108.063µs\",\n", + " \"request.chain.dlp_gcp_processor_20250211043750.507367878\": {\n", + " \"duration\": \"65.46µs\",\n", " \"skipped\": \"warn: sensitive data protection is disabled for route:openai-univ\"\n", " },\n", - " \"request.chain.promptinjectiondetection_processor_20250210131747.844523092\": {\n", - " \"duration\": \"142.292µs\",\n", + " \"request.chain.promptinjectiondetection_processor_20250211043750.507321700\": {\n", + " \"duration\": \"1.111771ms\",\n", " \"skipped\": \"warn: prompt safety is disabled for route:openai-univ\"\n", " },\n", - " \"request.chain.ratelimit_processor_20250210131747.844543051\": {\n", - " \"duration\": \"57.734µs\"\n", + " \"request.chain.ratelimit_processor_20250211043750.507335915\": {\n", + " \"duration\": \"84.056µs\"\n", " },\n", - " \"request.chain.secrets_processor_20250210131747.844592731\": {\n", - " \"duration\": \"13µs\"\n", + " \"request.chain.secrets_processor_20250211043750.507386623\": {\n", + " \"duration\": \"11.141µs\"\n", " },\n", - " \"response.chain.response_processor_20250210131747.844410535\": {\n", + " \"response.chain.response_processor_20250211043750.507279521\": {\n", " \"duration\": \"0s\"\n", " },\n", - " \"response.chain.trustsafety_processor_20250210131747.844386942\": {\n", - " \"duration\": \"55.392µs\",\n", + " \"response.chain.trustsafety_processor_20250211043750.507265312\": {\n", + " \"duration\": \"64.001µs\",\n", " \"skipped\": \"warn: trust safety is disabled for route:openai-univ\"\n", " }\n", " },\n", @@ -159,14 +159,12 @@ "# IMPORTANT: Specify the azure_deployment parameter to match your Azure model deployment name.\n", "openai_client = AzureOpenAI(\n", " api_version=\"2023-07-01-preview\",\n", - " azure_endpoint=\"https://javelinpreview.openai.azure.com\",\n", + " azure_endpoint=\"https://javelinpreview.openai.azure.com\", # Azure Univeral Route\n", " api_key=azure_openai_api_key\n", ")\n", "\n", "# Initialize the Javelin Client.\n", "config = JavelinConfig(\n", - " base_url=\"https://api-dev.javelin.live\",\n", - " # base_url=\"http://localhost:8000\",\n", " javelin_api_key=javelin_api_key,\n", ")\n", "client = JavelinClient(config)\n", diff --git a/examples/openai/openai_universal-rout.ipynb b/examples/openai/openai_universal-rout.ipynb index 75d9723..d3631eb 100644 --- a/examples/openai/openai_universal-rout.ipynb +++ b/examples/openai/openai_universal-rout.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -21,14 +21,14 @@ "sk-proj-bF54IwKWyN9SbdpGrnS4T3BlbkFJ6PyfIsqqoifSnyMzx9ae\n", "OpenAI: 1 - Chat completions\n", "{\n", - " \"id\": \"chatcmpl-AzKXhek0wiLY41sTGfT6qBW5sT1EA\",\n", + " \"id\": \"chatcmpl-AzSpIE70igz2obmW1QmIOPyQBjAl3\",\n", " \"choices\": [\n", " {\n", " \"finish_reason\": \"stop\",\n", " \"index\": 0,\n", " \"logprobs\": null,\n", " \"message\": {\n", - " \"content\": \"Machine learning is a subset of artificial intelligence (AI) that involves constructing algorithms and statistical models that allow computers to learn from and make predictions or decisions based on data without being explicitly programmed. Machine learning algorithms identify patterns in data and use that information to improve their performance over time. This technology is used in a wide range of applications, including image and speech recognition, recommendation systems, fraud detection, medical diagnosis, and many others.\",\n", + " \"content\": \"Machine learning is a subset of artificial intelligence that involves the development of algorithms and models that allow computers to learn from data and make predictions or decisions without being explicitly programmed. In other words, machine learning enables computers to learn and improve from experience, rather than being programmed with specific instructions for every task. It is used in various applications, such as image and speech recognition, recommendation systems, and predictive analytics.\",\n", " \"refusal\": null,\n", " \"role\": \"assistant\",\n", " \"audio\": null,\n", @@ -37,15 +37,15 @@ " }\n", " }\n", " ],\n", - " \"created\": 1739180337,\n", + " \"created\": 1739212180,\n", " \"model\": \"gpt-3.5-turbo-0125\",\n", " \"object\": \"chat.completion\",\n", " \"service_tier\": \"default\",\n", " \"system_fingerprint\": null,\n", " \"usage\": {\n", - " \"completion_tokens\": 86,\n", + " \"completion_tokens\": 81,\n", " \"prompt_tokens\": 12,\n", - " \"total_tokens\": 98,\n", + " \"total_tokens\": 93,\n", " \"completion_tokens_details\": {\n", " \"accepted_prediction_tokens\": 0,\n", " \"audio_tokens\": 0,\n", @@ -59,34 +59,34 @@ " },\n", " \"javelin\": {\n", " \"archive_enabled\": true,\n", - " \"correlation_id\": \"01JKQKKTFANF3PA3GB7866VMGV\",\n", + " \"correlation_id\": \"01JKRHZHQVKT52HB1DZ66JS2J2\",\n", " \"model_endpoint_url\": \"https://api.openai.com/v1/chat/completions\",\n", - " \"model_latency\": \"943.195026ms\",\n", + " \"model_latency\": \"1.718661856s\",\n", " \"model_name\": \"gpt-3.5-turbo\",\n", " \"processor_outputs\": {\n", - " \"request.chain.archive_processor_20250210093858.597264197\": {\n", - " \"duration\": \"4.985534ms\",\n", + " \"request.chain.archive_processor_20250210182940.965083629\": {\n", + " \"duration\": \"15.043426ms\",\n", " \"success\": \"successfully archived memory\"\n", " },\n", - " \"request.chain.dlp_gcp_processor_20250210093858.597381862\": {\n", - " \"duration\": \"66.605µs\",\n", + " \"request.chain.dlp_gcp_processor_20250210182940.965023472\": {\n", + " \"duration\": \"90.247µs\",\n", " \"skipped\": \"warn: sensitive data protection is disabled for route:openai-univ\"\n", " },\n", - " \"request.chain.promptinjectiondetection_processor_20250210093858.597346110\": {\n", - " \"duration\": \"82.097µs\",\n", + " \"request.chain.promptinjectiondetection_processor_20250210182940.965147011\": {\n", + " \"duration\": \"394.597µs\",\n", " \"skipped\": \"warn: prompt safety is disabled for route:openai-univ\"\n", " },\n", - " \"request.chain.ratelimit_processor_20250210093858.597364325\": {\n", - " \"duration\": \"52.993µs\"\n", + " \"request.chain.ratelimit_processor_20250210182940.965168720\": {\n", + " \"duration\": \"2.675224ms\"\n", " },\n", - " \"request.chain.secrets_processor_20250210093858.597439995\": {\n", - " \"duration\": \"10.313µs\"\n", + " \"request.chain.secrets_processor_20250210182940.965039958\": {\n", + " \"duration\": \"16.296µs\"\n", " },\n", - " \"response.chain.response_processor_20250210093858.597321120\": {\n", + " \"response.chain.response_processor_20250210182940.965123146\": {\n", " \"duration\": \"0s\"\n", " },\n", - " \"response.chain.trustsafety_processor_20250210093858.597283100\": {\n", - " \"duration\": \"53.485µs\",\n", + " \"response.chain.trustsafety_processor_20250210182940.965105478\": {\n", + " \"duration\": \"70.339µs\",\n", " \"skipped\": \"warn: trust safety is disabled for route:openai-univ\"\n", " }\n", " },\n", @@ -219,8 +219,6 @@ "# Reinitialize Javelin Client for Async usage (using the same config)\n", "javelin_api_key = os.getenv('JAVELIN_API_KEY')\n", "config = JavelinConfig(\n", - " base_url=\"https://api-dev.javelin.live\",\n", - " # base_url=\"http://localhost:8000\",\n", " javelin_api_key=javelin_api_key,\n", ")\n", "client = JavelinClient(config)\n", From dfd7f68e6c8c6317c2085cb966c15f7f489d2993 Mon Sep 17 00:00:00 2001 From: Dhruvj07 Date: Tue, 11 Feb 2025 11:18:45 +0530 Subject: [PATCH 5/6] fix: Fixed agents examples in seperate /agents --- examples/agents/{ => agents}/agents.yaml | 0 examples/agents/{ => agents}/tasks.yaml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/agents/{ => agents}/agents.yaml (100%) rename examples/agents/{ => agents}/tasks.yaml (100%) diff --git a/examples/agents/agents.yaml b/examples/agents/agents/agents.yaml similarity index 100% rename from examples/agents/agents.yaml rename to examples/agents/agents/agents.yaml diff --git a/examples/agents/tasks.yaml b/examples/agents/agents/tasks.yaml similarity index 100% rename from examples/agents/tasks.yaml rename to examples/agents/agents/tasks.yaml From f33b8d7d1fe6e6676035967754aae21b94cc3c8c Mon Sep 17 00:00:00 2001 From: Dhruvj07 Date: Wed, 12 Feb 2025 09:07:02 +0530 Subject: [PATCH 6/6] feat: Added langchain respected providers , having .py file with seperate functionalities --- examples/azure-openai/azure-universal.py | 142 +++++++++++ .../azure_openai-unversal-rout.ipynb | 218 ----------------- .../azure-openai/langchain_azure_universal.py | 166 +++++++++++++ examples/bedrock/bedrock_client.ipynb | 73 ------ examples/bedrock/bedrock_client_universal.py | 117 +++++++++ .../bedrock/langchain-bedrock-universal.py | 158 ++++++++++++ examples/gemini/gemini-universal.py | 230 ++++++++++++++++++ examples/gemini/langchain-gemini.py | 0 .../langchain-openai-universal-rout.ipynb | 110 --------- examples/openai/langchain-openai-universal.py | 206 ++++++++++++++++ examples/openai/openai-universal.py | 195 +++++++++++++++ examples/openai/openai_universal-rout.ipynb | 89 +------ 12 files changed, 1217 insertions(+), 487 deletions(-) create mode 100644 examples/azure-openai/azure-universal.py delete mode 100644 examples/azure-openai/azure_openai-unversal-rout.ipynb create mode 100644 examples/azure-openai/langchain_azure_universal.py delete mode 100644 examples/bedrock/bedrock_client.ipynb create mode 100644 examples/bedrock/bedrock_client_universal.py create mode 100644 examples/bedrock/langchain-bedrock-universal.py create mode 100644 examples/gemini/gemini-universal.py create mode 100644 examples/gemini/langchain-gemini.py delete mode 100644 examples/openai/langchain-openai-universal-rout.ipynb create mode 100644 examples/openai/langchain-openai-universal.py create mode 100644 examples/openai/openai-universal.py diff --git a/examples/azure-openai/azure-universal.py b/examples/azure-openai/azure-universal.py new file mode 100644 index 0000000..108b8f7 --- /dev/null +++ b/examples/azure-openai/azure-universal.py @@ -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() diff --git a/examples/azure-openai/azure_openai-unversal-rout.ipynb b/examples/azure-openai/azure_openai-unversal-rout.ipynb deleted file mode 100644 index 07750a9..0000000 --- a/examples/azure-openai/azure_openai-unversal-rout.ipynb +++ /dev/null @@ -1,218 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Azure OpenAI Notebook \n", - "This notebook demonstrates the Azure OpenAI integration with Javelin. " - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Azure OpenAI: 1 - Chat completions\n", - "JAVELIN_API_KEY found.\n", - "AZURE_OPENAI_API_KEY found.\n", - "Azure OpenAI Response:\n", - "{\n", - " \"id\": \"chatcmpl-AzcJkS7tUwH78qRCND7kIBKuxS1d9\",\n", - " \"choices\": [\n", - " {\n", - " \"finish_reason\": \"stop\",\n", - " \"index\": 0,\n", - " \"message\": {\n", - " \"content\": \"To output all files in a directory using Python, you can use the `os` module, which provides functions for interacting with the operating system. Here's an example of how you can list all files in a directory:\\n\\n```python\\nimport os\\n\\n# Specify the directory path\\ndirectory_path = '/path/to/directory'\\n\\n# List all files in the directory\\nfiles = os.listdir(directory_path)\\n\\n# Loop through the files and print their names\\nfor file in files:\\n full_path = os.path.join(directory_path, file)\\n if os.path.isfile(full_path):\\n print(file)\\n```\\n\\nIn this example, you need to replace `'/path/to/directory'` with the path to the directory where you want to list the files. The `os.listdir()` function returns a list of all files and directories in the specified directory. The `os.path.join()` function is used to get the full path of each file, and `os.path.isfile()` checks if the path points to a file (as opposed to a directory). Finally, the program prints the names of all files in the directory.\",\n", - " \"role\": \"assistant\"\n", - " },\n", - " \"content_filter_results\": {\n", - " \"hate\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " },\n", - " \"protected_material_code\": {\n", - " \"detected\": false,\n", - " \"filtered\": false\n", - " },\n", - " \"protected_material_text\": {\n", - " \"detected\": false,\n", - " \"filtered\": false\n", - " },\n", - " \"self_harm\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " },\n", - " \"sexual\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " },\n", - " \"violence\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"created\": 1739248664,\n", - " \"model\": \"gpt-4-turbo-2024-04-09\",\n", - " \"object\": \"chat.completion\",\n", - " \"system_fingerprint\": \"fp_5603ee5e2e\",\n", - " \"usage\": {\n", - " \"completion_tokens\": 223,\n", - " \"prompt_tokens\": 19,\n", - " \"total_tokens\": 242\n", - " },\n", - " \"javelin\": {\n", - " \"archive_enabled\": true,\n", - " \"correlation_id\": \"01JKSMS04GVV657Y9AQEDRD7YP\",\n", - " \"model_endpoint_url\": \"https://javelinpreview.openai.azure.com/openai/deployments/gpt-4/chat/completions?api-version=2023-07-01-preview\",\n", - " \"model_latency\": \"5.762334998s\",\n", - " \"model_name\": \"gpt-4\",\n", - " \"processor_outputs\": {\n", - " \"request.chain.archive_processor_20250211043750.507405930\": {\n", - " \"duration\": \"11.410459ms\",\n", - " \"success\": \"successfully archived memory\"\n", - " },\n", - " \"request.chain.dlp_gcp_processor_20250211043750.507367878\": {\n", - " \"duration\": \"65.46µs\",\n", - " \"skipped\": \"warn: sensitive data protection is disabled for route:openai-univ\"\n", - " },\n", - " \"request.chain.promptinjectiondetection_processor_20250211043750.507321700\": {\n", - " \"duration\": \"1.111771ms\",\n", - " \"skipped\": \"warn: prompt safety is disabled for route:openai-univ\"\n", - " },\n", - " \"request.chain.ratelimit_processor_20250211043750.507335915\": {\n", - " \"duration\": \"84.056µs\"\n", - " },\n", - " \"request.chain.secrets_processor_20250211043750.507386623\": {\n", - " \"duration\": \"11.141µs\"\n", - " },\n", - " \"response.chain.response_processor_20250211043750.507279521\": {\n", - " \"duration\": \"0s\"\n", - " },\n", - " \"response.chain.trustsafety_processor_20250211043750.507265312\": {\n", - " \"duration\": \"64.001µs\",\n", - " \"skipped\": \"warn: trust safety is disabled for route:openai-univ\"\n", - " }\n", - " },\n", - " \"route_name\": \"openai-univ\"\n", - " },\n", - " \"prompt_filter_results\": [\n", - " {\n", - " \"content_filter_results\": {\n", - " \"hate\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " },\n", - " \"jailbreak\": {\n", - " \"detected\": false,\n", - " \"filtered\": false\n", - " },\n", - " \"self_harm\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " },\n", - " \"sexual\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " },\n", - " \"violence\": {\n", - " \"filtered\": false,\n", - " \"severity\": \"safe\"\n", - " }\n", - " },\n", - " \"prompt_index\": 0\n", - " }\n", - " ]\n", - "}\n" - ] - } - ], - "source": [ - "import os\n", - "from openai import AzureOpenAI\n", - "from javelin_sdk import JavelinClient, JavelinConfig\n", - "\n", - "print(\"Azure OpenAI: 1 - Chat completions\")\n", - "\n", - "# Retrieve the Javelin API key.\n", - "javelin_api_key = \"\" # add your javelin key here\n", - "if not javelin_api_key:\n", - " print(\"Error: JAVELIN_API_KEY environment variable is not set!\")\n", - "else:\n", - " print(\"JAVELIN_API_KEY found.\")\n", - "\n", - "# Retrieve the Azure OpenAI API key.\n", - "azure_openai_api_key = \"\" # add your azure openai key here\n", - "if not azure_openai_api_key:\n", - " print(\"Warning: AZURE_OPENAI_API_KEY environment variable is not set!\")\n", - "else:\n", - " print(\"AZURE_OPENAI_API_KEY found.\")\n", - "\n", - "# Create the AzureOpenAI client.\n", - "# IMPORTANT: Specify the azure_deployment parameter to match your Azure model deployment name.\n", - "openai_client = AzureOpenAI(\n", - " api_version=\"2023-07-01-preview\",\n", - " azure_endpoint=\"https://javelinpreview.openai.azure.com\", # Azure Univeral Route\n", - " api_key=azure_openai_api_key\n", - ")\n", - "\n", - "# Initialize the Javelin Client.\n", - "config = JavelinConfig(\n", - " javelin_api_key=javelin_api_key,\n", - ")\n", - "client = JavelinClient(config)\n", - "client.register_azureopenai(openai_client, route_name=\"openai-univ\")\n", - "\n", - "# Call the Azure OpenAI endpoint for chat completions.\n", - "completion = openai_client.chat.completions.create(\n", - " model=\"gpt-4\", # e.g. gpt-35-instant\n", - " messages=[\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"How do I output all files in a directory using Python?\",\n", - " },\n", - " ],\n", - ")\n", - "\n", - "# Print the response as JSON.\n", - "print(\"Azure OpenAI Response:\")\n", - "print(completion.to_json())\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/azure-openai/langchain_azure_universal.py b/examples/azure-openai/langchain_azure_universal.py new file mode 100644 index 0000000..e1a8f6d --- /dev/null +++ b/examples/azure-openai/langchain_azure_universal.py @@ -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() diff --git a/examples/bedrock/bedrock_client.ipynb b/examples/bedrock/bedrock_client.ipynb deleted file mode 100644 index 87bc2c1..0000000 --- a/examples/bedrock/bedrock_client.ipynb +++ /dev/null @@ -1,73 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Bedrock Notebook" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import os\n", - "import boto3\n", - "import dotenv\n", - "from javelin_sdk import (\n", - " JavelinClient,\n", - " JavelinConfig,\n", - ")\n", - "\n", - "dotenv.load_dotenv()\n", - "\n", - "# Retrieve environment variables\n", - "javelin_api_key = os.getenv(\"JAVELIN_API_KEY\")\n", - "\n", - "# Initialize Bedrock Client\n", - "bedrock_client = boto3.client(\n", - " service_name=\"bedrock-runtime\",\n", - " region_name=\"us-east-1\"\n", - ")\n", - "\n", - "\n", - "# Initialize Javelin Client\n", - "config = JavelinConfig(\n", - " base_url=\"https://api-dev.javelin.live\",\n", - " javelin_api_key=javelin_api_key,\n", - ")\n", - "client = JavelinClient(config)\n", - "client.register_bedrock_runtime(bedrock_client)\n", - "\n", - "\n", - "# Call Bedrock Model\n", - "response = bedrock_client.invoke_model(\n", - " modelId=\"anthropic.claude-3-sonnet-20240229-v1:0\",\n", - " body=json.dumps({\n", - " \"anthropic_version\": \"bedrock-2023-05-31\",\n", - " \"max_tokens\": 100,\n", - " \"messages\": [\n", - " {\n", - " \"content\": \"What is machine learning?\",\n", - " \"role\": \"user\"\n", - " }\n", - " ]\n", - " }),\n", - " contentType=\"application/json\"\n", - " )\n", - "response_body = json.loads(response[\"body\"].read())\n", - "print(f\"Invoke Response: {json.dumps(response_body, indent=2)}\")" - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/bedrock/bedrock_client_universal.py b/examples/bedrock/bedrock_client_universal.py new file mode 100644 index 0000000..dee38b4 --- /dev/null +++ b/examples/bedrock/bedrock_client_universal.py @@ -0,0 +1,117 @@ +import boto3 +import json +from javelin_sdk import JavelinClient, JavelinConfig + +def init_bedrock(): + """ + 1) Configure Bedrock clients using boto3, + 2) Register them with Javelin (optional but often recommended), + 3) Return the bedrock_runtime_client for direct 'invoke_model' calls. + """ + # Configure the bedrock-runtime and bedrock service clients + bedrock_runtime_client = boto3.client( + service_name="bedrock-runtime", + region_name="us-east-1" + ) + bedrock_client = boto3.client( + service_name="bedrock", + region_name="us-east-1" + ) + + # Initialize Javelin Client (if you want the route registered) + config = JavelinConfig( + base_url="https://api-dev.javelin.live/v1", + javelin_api_key="" # add your javelin api key here + ) + javelin_client = JavelinClient(config) + + # Register the bedrock clients with Javelin under route "bedrock" + javelin_client.register_bedrock( + bedrock_runtime_client=bedrock_runtime_client, + bedrock_client=bedrock_client, + route_name="bedrock" + ) + return bedrock_runtime_client + +def bedrock_invoke_example(bedrock_runtime_client): + """ + Demonstrates a basic 'invoke' style call (non-streaming). + Returns a JSON-formatted string of the response. + """ + response = bedrock_runtime_client.invoke_model( + modelId="anthropic.claude-3-sonnet-20240229-v1:0", # Example model ID + body=json.dumps({ + "anthropic_version": "bedrock-2023-05-31", + "max_tokens": 100, + "messages": [ + {"role": "user", "content": "What is machine learning?"} + ] + }), + contentType="application/json" + ) + + response_body = json.loads(response["body"].read()) + return json.dumps(response_body, indent=2) + + +def bedrock_converse_example(bedrock_runtime_client): + """ + Demonstrates a 'converse' style call by including 'system' text plus a user message. + Still uses 'invoke_model', but the request body includes additional fields. + """ + response = bedrock_runtime_client.invoke_model( + modelId="anthropic.claude-3-sonnet-20240229-v1:0", # Example model ID + body=json.dumps({ + "anthropic_version": "bedrock-2023-05-31", + "max_tokens": 500, + # 'system' text for instructions/context + "system": [ + {"text": "You are an economist with access to lots of data"} + ], + # 'messages' containing the user content + "messages": [ + { + "role": "user", + "content": [ + { + "text": "Write an article about impact of high inflation to GDP of a country" + } + ] + } + ] + }), + contentType="application/json" + ) + + response_body = json.loads(response["body"].read()) + return json.dumps(response_body, indent=2) + + +def main(): + try: + bedrock_runtime_client = init_bedrock() + except Exception as e: + print("Error initializing Bedrock + Javelin:", e) + return + + # 1) Basic 'invoke' + print("\n--- Bedrock Invoke Example ---") + try: + invoke_resp = bedrock_invoke_example(bedrock_runtime_client) + print("Invoke Response:\n", invoke_resp) + except Exception as e: + print("Error in bedrock_invoke_example:", e) + + # 2) 'Converse' style + print("\n--- Bedrock Converse Example ---") + try: + converse_resp = bedrock_converse_example(bedrock_runtime_client) + print("Converse Response:\n", converse_resp) + except Exception as e: + print("Error in bedrock_converse_example:", e) + + print("\n--- Script complete. ---") + + +if __name__ == "__main__": + main() diff --git a/examples/bedrock/langchain-bedrock-universal.py b/examples/bedrock/langchain-bedrock-universal.py new file mode 100644 index 0000000..f0518eb --- /dev/null +++ b/examples/bedrock/langchain-bedrock-universal.py @@ -0,0 +1,158 @@ +import boto3 +from javelin_sdk import JavelinClient, JavelinConfig + +# This import is from the "langchain_community" extension package +# Make sure to install it: +# pip install git+https://github.com/hwchase17/langchain.git@#subdirectory=plugins/langchain-community +from langchain_community.llms.bedrock import Bedrock as BedrockLLM + + +def init_bedrock(): + """ + 1) Configure Bedrock clients via boto3, + 2) Register them with Javelin, + 3) Return the bedrock_runtime_client for direct usage in LangChain. + """ + # Create Bedrock boto3 clients + bedrock_runtime_client = boto3.client( + service_name="bedrock-runtime", + region_name="us-east-1" + ) + bedrock_client = boto3.client( + service_name="bedrock", + region_name="us-east-1" + ) + + # Initialize Javelin client + config = JavelinConfig( + base_url="https://api-dev.javelin.live/v1", + javelin_api_key="" # add your javelin api key here + ) + javelin_client = JavelinClient(config) + + # Register them with the route "bedrock" (optional but recommended) + javelin_client.register_bedrock( + bedrock_runtime_client=bedrock_runtime_client, + bedrock_client=bedrock_client, + route_name="bedrock" + ) + + return bedrock_runtime_client + + +# +# 1) Non-Streaming Example +# +def bedrock_langchain_non_stream(bedrock_runtime_client) -> str: + """ + Demonstrates a single prompt with a synchronous, non-streaming response. + """ + # Create the Bedrock LLM + llm = BedrockLLM( + client=bedrock_runtime_client, + model_id="anthropic.claude-v2:1", # Example model ID + model_kwargs={ + "max_tokens_to_sample": 256, + "temperature": 0.7, + } + ) + # Call the model with a single string prompt + prompt = "What is machine learning?" + response = llm(prompt) + return response + + +# +# 2) Streaming Example +# +def bedrock_langchain_stream(bedrock_runtime_client) -> str: + """ + Demonstrates streaming partial responses from Bedrock. + Returns the concatenated final text. + """ + llm = BedrockLLM( + client=bedrock_runtime_client, + model_id="anthropic.claude-v2:1", + model_kwargs={ + "max_tokens_to_sample": 256, + "temperature": 0.7, + } + ) + + prompt = "Tell me a short joke." + stream_gen = llm.stream(prompt) + + collected_chunks = [] + for chunk in stream_gen: + # 'chunk' is a partial piece of text + collected_chunks.append(chunk) + # Optional live printing: + print(chunk, end="", flush=True) + + # Return the combined text + return "".join(collected_chunks) + + +# +# 3) Converse Example (System + User) +# +def bedrock_langchain_converse(bedrock_runtime_client) -> str: + """ + Simulates a 'system' plus 'user' message in one call. + Because the Bedrock LLM interface accepts a single prompt string, + we'll combine them. If you need a multi-message format, craft your + prompt accordingly. + """ + llm = BedrockLLM( + client=bedrock_runtime_client, + model_id="anthropic.claude-v2:1", + model_kwargs={ + "max_tokens_to_sample": 500, + "temperature": 0.7, + } + ) + + system_text = "You are an economist with access to lots of data." + user_text = "Write an article about the impact of high inflation on GDP." + + # Construct a single prompt that merges system instructions + user request. + # This is a common pattern when the LLM only accepts a single text input. + combined_prompt = f"System: {system_text}\nUser: {user_text}\n" + + response = llm(combined_prompt) + return response + + +def main(): + try: + bedrock_runtime_client = init_bedrock() + except Exception as e: + print("Error initializing Bedrock + Javelin:", e) + return + + print("\n[1) Non-Streaming Example]") + try: + resp_non_stream = bedrock_langchain_non_stream(bedrock_runtime_client) + print("Response:", resp_non_stream) + except Exception as e: + print("Error in non-stream example:", e) + + print("\n[2) Streaming Example]") + try: + resp_stream = bedrock_langchain_stream(bedrock_runtime_client) + print("\nFinal Combined Streamed Text:\n", resp_stream) + except Exception as e: + print("Error in streaming example:", e) + + print("\n[3) Converse Example (System + User)") + try: + resp_converse = bedrock_langchain_converse(bedrock_runtime_client) + print("Converse Response:\n", resp_converse) + except Exception as e: + print("Error in converse example:", e) + + print("\n--- Script Complete. ---") + + +if __name__ == "__main__": + main() diff --git a/examples/gemini/gemini-universal.py b/examples/gemini/gemini-universal.py new file mode 100644 index 0000000..b31f19f --- /dev/null +++ b/examples/gemini/gemini-universal.py @@ -0,0 +1,230 @@ +import os +import json + +# The official OpenAI Python library with Gemini support (via Javelin) +from openai import OpenAI +from javelin_sdk import JavelinClient, JavelinConfig +from pydantic import BaseModel + +# ----------------------------------------------------------------------------- +# 1) Initialize Gemini + Javelin +# ----------------------------------------------------------------------------- +def init_gemini_client(): + """ + Sets environment variables for Gemini and Javelin, creates an OpenAI client, + registers it with Javelin, and returns the configured client. + """ + print("Initializing Gemini client...") + + # Hard-coded environment variable assignment (for demonstration) + # You may prefer to do: gemini_api_key = os.environ.get("GEMINI_API_KEY") in real usage. + os.environ["GEMINI_API_KEY"] = "" # add your gemini api key here + gemini_api_key = os.environ["GEMINI_API_KEY"] + if not gemini_api_key: + raise ValueError("GEMINI_API_KEY is not set!") + print("Gemini API Key loaded successfully.") + + # Create an OpenAI client configured for Gemini + openai_client = OpenAI( + api_key=gemini_api_key, + base_url="https://generativelanguage.googleapis.com/v1beta/openai/" + ) + + # Javelin configuration + os.environ["JAVELIN_API_KEY"] = "" # add your javelin api key here + javelin_api_key = os.environ["JAVELIN_API_KEY"] + config = JavelinConfig(javelin_api_key=javelin_api_key) + client = JavelinClient(config) + + # Register the Gemini client with Javelin + client.register_gemini(openai_client, route_name="gemini-univ") + + return openai_client + + +# ----------------------------------------------------------------------------- +# 2) Chat Completions +# ----------------------------------------------------------------------------- +def gemini_chat_completions(client): + """ + Demonstrates a basic chat completion with Gemini. + Returns the JSON string of the response. + """ + response = client.chat.completions.create( + model="gemini-1.5-flash", + n=1, + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "Explain to me how AI works"} + ] + ) + return response.model_dump_json(indent=2) + + +# ----------------------------------------------------------------------------- +# 3) Streaming +# ----------------------------------------------------------------------------- +def gemini_streaming(client): + """ + Demonstrates streaming a response from Gemini. + Returns a concatenated string of all streamed tokens for demonstration. + """ + response = client.chat.completions.create( + model="gemini-1.5-flash", + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": "Hello!"} + ], + stream=True + ) + + # Accumulate partial content in a list + streamed_content = [] + for chunk in response: + if chunk.choices and chunk.choices[0].delta: + delta_content = chunk.choices[0].delta + # Just store the dictionary or the text portion. + # We'll store the entire dict as JSON for demonstration: + streamed_content.append(json.dumps(delta_content)) + + # Join all chunk data with newlines + return "\n".join(streamed_content) + + +# ----------------------------------------------------------------------------- +# 4) Function calling +# ----------------------------------------------------------------------------- +def gemini_function_calling(client): + """ + Demonstrates a function-calling scenario with Gemini (like OpenAI Tools). + Returns JSON string of the response. + """ + tools = [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "Get the weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Chicago, IL", + }, + "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, + }, + "required": ["location"], + }, + } + } + ] + messages = [{"role": "user", "content": "What's the weather like in Chicago today?"}] + response = client.chat.completions.create( + model="gemini-1.5-flash", + messages=messages, + tools=tools, + tool_choice="auto" + ) + return response.model_dump_json(indent=2) + + +# ----------------------------------------------------------------------------- +# 5) Structured output +# ----------------------------------------------------------------------------- +class CalendarEvent(BaseModel): + name: str + date: str + participants: list[str] + +def gemini_structured_output(client): + """ + Demonstrates how to request structured JSON output from Gemini + using the 'parse' endpoint (beta). + Returns the JSON string of the structured result. + """ + completion = client.beta.chat.completions.parse( + model="gemini-1.5-flash", + messages=[ + {"role": "system", "content": "Extract the event information."}, + {"role": "user", "content": "John and Susan are going to an AI conference on Friday."}, + ], + response_format=CalendarEvent, + ) + return completion.model_dump_json(indent=2) + + +# ----------------------------------------------------------------------------- +# 6) Embeddings +# ----------------------------------------------------------------------------- +def gemini_embeddings(client): + """ + Demonstrates generating embeddings using Gemini. + Returns the JSON string of the embeddings response. + """ + response = client.embeddings.create( + input="Your text string goes here", + model="text-embedding-004" + ) + return response.model_dump_json(indent=2) + + +# ----------------------------------------------------------------------------- +# 7) Main +# ----------------------------------------------------------------------------- +def main(): + # 1. Initialize the Gemini (PaLM) client via Javelin + try: + gemini_client = init_gemini_client() + except Exception as e: + print("Error initializing Gemini client:", e) + return + + print("\nGemini: 1 - Chat completions") + try: + chat_response = gemini_chat_completions(gemini_client) + print(chat_response) + except Exception as e: + print("Error in chat completions:", e) + + print("\nGemini: 2 - Streaming") + try: + stream_response = gemini_streaming(gemini_client) + print("Streaming output:") + print(stream_response) + except Exception as e: + print("Error in streaming:", e) + + print("\nGemini: 3 - Function calling") + try: + func_response = gemini_function_calling(gemini_client) + print(func_response) + except Exception as e: + print("Error in function calling:", e) + + # (Commented out) Gemini Image Understanding Example: + # If you want, create a function `gemini_image_understanding()` + # and call it similarly in a try/except block here. + + print("\nGemini: 4 - Structured output") + try: + structured_response = gemini_structured_output(gemini_client) + print(structured_response) + except Exception as e: + print("Error in structured output:", e) + + print("\nGemini: 5 - Embeddings") + try: + embeddings_response = gemini_embeddings(gemini_client) + print(embeddings_response) + except Exception as e: + print("Error in embeddings:", e) + + print("\n--- Script complete. ---") + + +# ----------------------------------------------------------------------------- +# 8) Run main if executed directly +# ----------------------------------------------------------------------------- +if __name__ == "__main__": + main() diff --git a/examples/gemini/langchain-gemini.py b/examples/gemini/langchain-gemini.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/openai/langchain-openai-universal-rout.ipynb b/examples/openai/langchain-openai-universal-rout.ipynb deleted file mode 100644 index 395ae96..0000000 --- a/examples/openai/langchain-openai-universal-rout.ipynb +++ /dev/null @@ -1,110 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "import nest_asyncio\n", - "nest_asyncio.apply()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Answer: Water is a simple molecule with a chemical composition of H2O, which means that each water molecule consists of two hydrogen atoms bonded to one oxygen atom.\n" - ] - } - ], - "source": [ - "from langchain_openai import ChatOpenAI\n", - "from langchain_core.prompts import ChatPromptTemplate\n", - "from langchain_core.output_parsers import StrOutputParser\n", - "import os\n", - "\n", - "\n", - "# API keys – replace these with your actual keys or use os.getenv\n", - "openai_api_key = \"\" # set your open ai key here\n", - "javelin_api_key = \"\" #ser your javelin key here\n", - "\n", - "\n", - "# Set the model dynamically (change this value as needed)\n", - "model_choice = \"gpt-3.5-turbo\" # For example, change to \"gpt-4\" for testing\n", - "route_name = \"openai-univ\" #set your route name here\n", - "# Create LangChain OpenAI client using Javelin’s universal endpoint\n", - "# Here, the base URL is set to the provider's endpoint (\"/openai\")\n", - "# and the header \"x-javelin-route\" is set to the registered route (\"openai-univ\").\n", - "\n", - "\n", - "llm = ChatOpenAI(\n", - " openai_api_key=openai_api_key,\n", - " openai_api_base=\"https://api-dev.javelin.live/v1/openai\",\n", - " default_headers={\n", - " \"x-api-key\": javelin_api_key,\n", - " \"x-javelin-route\": route_name,\n", - " # \"x-javelin-provider\": \"https://api.openai.com/v1\",\n", - " \"x-javelin-model\":model_choice\n", - " \n", - " }\n", - ")\n", - "\n", - "\n", - "# Define a simple prompt template\n", - "prompt = ChatPromptTemplate.from_messages([\n", - " (\"system\", \"You are a helpful assistant.\"),\n", - " (\"user\", \"{input}\")\n", - "])\n", - "\n", - "# Use a simple output parser (string output)\n", - "output_parser = StrOutputParser()\n", - "\n", - "# Create the processing chain (prompt -> LLM -> parser)\n", - "chain = prompt | llm | output_parser\n", - "\n", - "def ask_question(question: str) -> str:\n", - " return chain.invoke({\"input\": question})\n", - "\n", - "# Example usage:\n", - "if __name__ == \"__main__\":\n", - " question = \"What is the chemical composition of water?\"\n", - " answer = ask_question(question)\n", - " print(\"Answer:\", answer)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "venv", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/openai/langchain-openai-universal.py b/examples/openai/langchain-openai-universal.py new file mode 100644 index 0000000..4cf5c7d --- /dev/null +++ b/examples/openai/langchain-openai-universal.py @@ -0,0 +1,206 @@ +import os +import json +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.output_parsers import StrOutputParser +from langchain_core.callbacks import BaseCallbackHandler +from langchain.callbacks.manager import CallbackManager + +# LLM classes from langchain_openai +from langchain_openai import ChatOpenAI, OpenAIEmbeddings + +# ----------------------------------------------------------------------------- +# 1) Configuration +# ----------------------------------------------------------------------------- +OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") # add your openai api key here +JAVELIN_API_KEY = os.environ.get("JAVELIN_API_KEY") # add your javelin api key here +MODEL_NAME_CHAT = "gpt-3.5-turbo" # For chat +MODEL_NAME_EMBED = "text-embedding-ada-002" +ROUTE_NAME = "openai-univ" + +def init_chat_llm_non_streaming(): + """ + Returns a non-streaming ChatOpenAI instance (for synchronous chat). + """ + return ChatOpenAI( + openai_api_key=OPENAI_API_KEY, + openai_api_base="https://api-dev.javelin.live/v1/openai", + default_headers={ + "x-api-key": JAVELIN_API_KEY, + "x-javelin-route": ROUTE_NAME, + "x-javelin-provider": "https://api.openai.com/v1", + "x-javelin-model": MODEL_NAME_CHAT + }, + streaming=False + ) + +def init_chat_llm_streaming(): + """ + Returns a streaming ChatOpenAI instance (for streaming chat). + """ + return ChatOpenAI( + openai_api_key=OPENAI_API_KEY, + openai_api_base="https://api-dev.javelin.live/v1/openai", + default_headers={ + "x-api-key": JAVELIN_API_KEY, + "x-javelin-route": ROUTE_NAME, + "x-javelin-provider": "https://api.openai.com/v1", + "x-javelin-model": MODEL_NAME_CHAT + }, + streaming=True + ) + +def init_embeddings_llm(): + """ + Returns an OpenAIEmbeddings instance for embeddings (e.g., text-embedding-ada-002). + """ + return OpenAIEmbeddings( + openai_api_key=OPENAI_API_KEY, + openai_api_base="https://api-dev.javelin.live/v1/openai", + default_headers={ + "x-api-key": JAVELIN_API_KEY, + "x-javelin-route": ROUTE_NAME, + "x-javelin-provider": "https://api.openai.com/v1", + "x-javelin-model": MODEL_NAME_EMBED + } + ) + +# ----------------------------------------------------------------------------- +# 2) Chat Completion (Synchronous) +# ----------------------------------------------------------------------------- +def chat_completion_sync(question: str) -> str: + """ + Single-turn chat, non-streaming. Returns the final text. + """ + llm = init_chat_llm_non_streaming() + + prompt = ChatPromptTemplate.from_messages([ + ("system", "You are a helpful assistant."), + ("user", "{input}") + ]) + parser = StrOutputParser() + chain = prompt | llm | parser + + return chain.invoke({"input": question}) + +# ----------------------------------------------------------------------------- +# 3) Chat Completion (Streaming) +# ----------------------------------------------------------------------------- +class StreamCallbackHandler(BaseCallbackHandler): + def __init__(self): + self.tokens = [] + def on_llm_new_token(self, token: str, **kwargs): + self.tokens.append(token) + # Prevent argument errors in some versions: + def on_chat_model_start(self, serialized, messages, **kwargs): + pass + +def chat_completion_stream(question: str) -> str: + """ + Single-turn chat, streaming. Returns the combined partial tokens. + """ + llm = init_chat_llm_streaming() + callback_handler = StreamCallbackHandler() + callback_manager = CallbackManager([callback_handler]) + # In some versions, you might pass callbacks to llm + llm.callbacks = [callback_handler] + + prompt = ChatPromptTemplate.from_messages([ + ("system", "You are a helpful assistant."), + ("user", "{input}") + ]) + parser = StrOutputParser() + streaming_chain = prompt | llm | parser + + streaming_chain.invoke({"input": question}) + return "".join(callback_handler.tokens) + +# ----------------------------------------------------------------------------- +# 4) Embeddings Example +# ----------------------------------------------------------------------------- +def get_embeddings(text: str) -> str: + """ + Example generating embeddings from text-embedding-ada-002. + Returns a string representation of the vector. + """ + emb = init_embeddings_llm() + # We'll embed a single query + vector = emb.embed_query(text) + return json.dumps(vector) + +# ----------------------------------------------------------------------------- +# 5) Conversation Demo (Manual, Non-Streaming) +# ----------------------------------------------------------------------------- +def conversation_demo() -> None: + """ + Multi-turn chat by manually rebuilding the prompt each turn. + """ + llm = init_chat_llm_non_streaming() + parser = StrOutputParser() + + # Start with a list of messages + messages = [("system", "You are a friendly assistant.")] + + # 1) Turn 1 + user_q1 = "Hello, how are you?" + messages.append(("user", user_q1)) + + prompt_1 = ChatPromptTemplate.from_messages(messages) + chain_1 = prompt_1 | llm | parser + ans1 = chain_1.invoke({}) + messages.append(("assistant", ans1)) + print(f"User: {user_q1}\nAssistant: {ans1}\n") + + # 2) Turn 2 + user_q2 = "Can you tell me a fun fact about dolphins?" + messages.append(("user", user_q2)) + + prompt_2 = ChatPromptTemplate.from_messages(messages) + chain_2 = prompt_2 | llm | parser + ans2 = chain_2.invoke({}) + messages.append(("assistant", ans2)) + print(f"User: {user_q2}\nAssistant: {ans2}\n") + +# ----------------------------------------------------------------------------- +# 6) Main +# ----------------------------------------------------------------------------- +def main(): + print("=== LangChain + OpenAI Javelin Examples (No Text Completion) ===") + + # 1) Chat Completion (Sync) + print("\n[Chat Completion: Synchronous]") + try: + question = "What is machine learning?" + result = chat_completion_sync(question) + print(f"Prompt: {question}\nAnswer:\n{result}") + except Exception as e: + print("Error in synchronous chat completion:", e) + + # 2) Chat Completion (Streaming) + print("\n[Chat Completion: Streaming]") + try: + question2 = "Tell me a short joke." + result_stream = chat_completion_stream(question2) + print(f"\nPrompt: {question2}\nStreamed Answer:\n{result_stream}") + except Exception as e: + print("Error in streaming chat completion:", e) + + # 3) Embeddings + print("\n[Embeddings Example]") + try: + sample_text = "The quick brown fox jumps over the lazy dog." + embed_vec = get_embeddings(sample_text) + print(f"Text: {sample_text}\nEmbedding Vector:\n{embed_vec[:100]} ...") + except Exception as e: + print("Error in embeddings:", e) + + # 4) Conversation Demo + print("\n[Conversation Demo (Manual, Non-Streaming)]") + try: + conversation_demo() + except Exception as e: + print("Error in conversation demo:", e) + + print("\n=== Script Complete ===") + +if __name__ == "__main__": + main() diff --git a/examples/openai/openai-universal.py b/examples/openai/openai-universal.py new file mode 100644 index 0000000..9c4ee0a --- /dev/null +++ b/examples/openai/openai-universal.py @@ -0,0 +1,195 @@ +import json +import os +import sys +import asyncio +import dotenv + +from openai import OpenAI +from openai import AsyncOpenAI +# from openai import AzureOpenAI # Not used, but imported for completeness + +from javelin_sdk import ( + JavelinClient, + JavelinConfig, +) + +# ------------------------------- +# Helper Functions +# ------------------------------- + +def init_sync_openai_client(): + """Initialize and return a synchronous OpenAI client.""" + try: + # Set (and print) the OpenAI key + openai_api_key = "" # add your openai api key here + print(f"Synchronous OpenAI client key: {openai_api_key}") + print("hello",openai_api_key) + return OpenAI(api_key=openai_api_key) + except Exception as e: + raise e + +def init_javelin_client_sync(openai_client): + """Initialize JavelinClient for synchronous usage and register the OpenAI route.""" + try: + # Set (and print) the Javelin key + javelin_api_key ="" # add your javelin api key here + config = JavelinConfig( + base_url="https://api-dev.javelin.live", + javelin_api_key=javelin_api_key, + ) + client = JavelinClient(config) + client.register_openai(openai_client, route_name="openai-univ") + return client + except Exception as e: + raise e + +def sync_openai_chat_completions(openai_client): + """Call OpenAI's Chat Completions endpoint (synchronously).""" + try: + response = openai_client.chat.completions.create( + model="gpt-3.5-turbo", + messages=[{"role": "user", "content": "What is machine learning?"}], + ) + return response.model_dump_json(indent=2) + except Exception as e: + raise e + +def sync_openai_completions(openai_client): + """Call OpenAI's Completions endpoint (synchronously).""" + try: + response = openai_client.completions.create( + model="gpt-3.5-turbo-instruct", + prompt="What is machine learning?", + max_tokens=7, + temperature=0 + ) + return response.model_dump_json(indent=2) + except Exception as e: + raise e + +def sync_openai_embeddings(openai_client): + """Call OpenAI's Embeddings endpoint (synchronously).""" + try: + response = openai_client.embeddings.create( + model="text-embedding-ada-002", + input="The food was delicious and the waiter...", + encoding_format="float" + ) + return response.model_dump_json(indent=2) + except Exception as e: + raise e + +def sync_openai_stream(openai_client): + """Call OpenAI's Chat Completions endpoint with streaming.""" + try: + stream = openai_client.chat.completions.create( + messages=[{"role": "user", "content": "Say this is a test"}], + model="gpt-3.5-turbo", + stream=True, + ) + collected_chunks = [] + for chunk in stream: + text_chunk = chunk.choices[0].delta.content or "" + collected_chunks.append(text_chunk) + return "".join(collected_chunks) + except Exception as e: + raise e + +# Async part +def init_async_openai_client(): + """Initialize and return an asynchronous OpenAI client.""" + try: + openai_api_key = "" # add your openai api key here + return AsyncOpenAI(api_key=openai_api_key) + except Exception as e: + raise e + +def init_javelin_client_async(openai_async_client): + """Initialize JavelinClient for async usage and register the OpenAI route.""" + try: + javelin_api_key = "" # add your javelin api key here + config = JavelinConfig(javelin_api_key=javelin_api_key) + client = JavelinClient(config) + client.register_openai(openai_async_client, route_name="openai") + return client + except Exception as e: + raise e + +async def async_openai_chat_completions(openai_async_client): + """Call OpenAI's Chat Completions endpoint (asynchronously).""" + try: + chat_completion = await openai_async_client.chat.completions.create( + messages=[{"role": "user", "content": "Say this is a test"}], + model="gpt-3.5-turbo", + ) + return chat_completion.model_dump_json(indent=2) + except Exception as e: + raise e + +# ------------------------------- +# Main Function +# ------------------------------- +def main(): + print("=== Synchronous OpenAI Example ===") + try: + # Initialize sync client + openai_client = init_sync_openai_client() + javelin_sync_client = init_javelin_client_sync(openai_client) + except Exception as e: + print(f"Error initializing synchronous clients: {e}") + return + + # 1. Chat completions + print("\nOpenAI: 1 - Chat completions") + try: + chat_completions_response = sync_openai_chat_completions(openai_client) + print(chat_completions_response) + except Exception as e: + print(f"Error in chat completions: {e}") + + # 2. Completions + print("\nOpenAI: 2 - Completions") + try: + completions_response = sync_openai_completions(openai_client) + print(completions_response) + except Exception as e: + print(f"Error in completions: {e}") + + # 3. Embeddings + print("\nOpenAI: 3 - Embeddings") + try: + embeddings_response = sync_openai_embeddings(openai_client) + print(embeddings_response) + except Exception as e: + print(f"Error in embeddings: {e}") + + # 4. Streaming + print("\nOpenAI: 4 - Streaming") + try: + stream_result = sync_openai_stream(openai_client) + print("Streaming response:", stream_result) + except Exception as e: + print(f"Error in streaming: {e}") + + # ------------------------------- + # Asynchronous OpenAI Example + # ------------------------------- + print("\n=== Asynchronous OpenAI Example ===") + try: + openai_async_client = init_async_openai_client() + javelin_async_client = init_javelin_client_async(openai_async_client) + except Exception as e: + print(f"Error initializing async clients: {e}") + return + + # 5. Chat completions (async) + print("\nAsyncOpenAI: 5 - Chat completions") + try: + async_response = asyncio.run(async_openai_chat_completions(openai_async_client)) + print(async_response) + except Exception as e: + print(f"Error in async chat completions: {e}") + + +if __name__ == "__main__": + main() diff --git a/examples/openai/openai_universal-rout.ipynb b/examples/openai/openai_universal-rout.ipynb index d3631eb..e5fbf16 100644 --- a/examples/openai/openai_universal-rout.ipynb +++ b/examples/openai/openai_universal-rout.ipynb @@ -10,92 +10,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 13, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initializing Synchronous OpenAI client...\n", - "sk-proj-bF54IwKWyN9SbdpGrnS4T3BlbkFJ6PyfIsqqoifSnyMzx9ae\n", - "OpenAI: 1 - Chat completions\n", - "{\n", - " \"id\": \"chatcmpl-AzSpIE70igz2obmW1QmIOPyQBjAl3\",\n", - " \"choices\": [\n", - " {\n", - " \"finish_reason\": \"stop\",\n", - " \"index\": 0,\n", - " \"logprobs\": null,\n", - " \"message\": {\n", - " \"content\": \"Machine learning is a subset of artificial intelligence that involves the development of algorithms and models that allow computers to learn from data and make predictions or decisions without being explicitly programmed. In other words, machine learning enables computers to learn and improve from experience, rather than being programmed with specific instructions for every task. It is used in various applications, such as image and speech recognition, recommendation systems, and predictive analytics.\",\n", - " \"refusal\": null,\n", - " \"role\": \"assistant\",\n", - " \"audio\": null,\n", - " \"function_call\": null,\n", - " \"tool_calls\": null\n", - " }\n", - " }\n", - " ],\n", - " \"created\": 1739212180,\n", - " \"model\": \"gpt-3.5-turbo-0125\",\n", - " \"object\": \"chat.completion\",\n", - " \"service_tier\": \"default\",\n", - " \"system_fingerprint\": null,\n", - " \"usage\": {\n", - " \"completion_tokens\": 81,\n", - " \"prompt_tokens\": 12,\n", - " \"total_tokens\": 93,\n", - " \"completion_tokens_details\": {\n", - " \"accepted_prediction_tokens\": 0,\n", - " \"audio_tokens\": 0,\n", - " \"reasoning_tokens\": 0,\n", - " \"rejected_prediction_tokens\": 0\n", - " },\n", - " \"prompt_tokens_details\": {\n", - " \"audio_tokens\": 0,\n", - " \"cached_tokens\": 0\n", - " }\n", - " },\n", - " \"javelin\": {\n", - " \"archive_enabled\": true,\n", - " \"correlation_id\": \"01JKRHZHQVKT52HB1DZ66JS2J2\",\n", - " \"model_endpoint_url\": \"https://api.openai.com/v1/chat/completions\",\n", - " \"model_latency\": \"1.718661856s\",\n", - " \"model_name\": \"gpt-3.5-turbo\",\n", - " \"processor_outputs\": {\n", - " \"request.chain.archive_processor_20250210182940.965083629\": {\n", - " \"duration\": \"15.043426ms\",\n", - " \"success\": \"successfully archived memory\"\n", - " },\n", - " \"request.chain.dlp_gcp_processor_20250210182940.965023472\": {\n", - " \"duration\": \"90.247µs\",\n", - " \"skipped\": \"warn: sensitive data protection is disabled for route:openai-univ\"\n", - " },\n", - " \"request.chain.promptinjectiondetection_processor_20250210182940.965147011\": {\n", - " \"duration\": \"394.597µs\",\n", - " \"skipped\": \"warn: prompt safety is disabled for route:openai-univ\"\n", - " },\n", - " \"request.chain.ratelimit_processor_20250210182940.965168720\": {\n", - " \"duration\": \"2.675224ms\"\n", - " },\n", - " \"request.chain.secrets_processor_20250210182940.965039958\": {\n", - " \"duration\": \"16.296µs\"\n", - " },\n", - " \"response.chain.response_processor_20250210182940.965123146\": {\n", - " \"duration\": \"0s\"\n", - " },\n", - " \"response.chain.trustsafety_processor_20250210182940.965105478\": {\n", - " \"duration\": \"70.339µs\",\n", - " \"skipped\": \"warn: trust safety is disabled for route:openai-univ\"\n", - " }\n", - " },\n", - " \"route_name\": \"openai-univ\"\n", - " }\n", - "}\n" - ] - } - ], + "outputs": [], "source": [ "import json\n", "import os\n", @@ -121,7 +38,7 @@ "openai_client = OpenAI(api_key=openai_api_key)\n", "\n", "# Initialize Javelin Client with your API key and base URL\n", - "javelin_api_key = os.environ['JAVELIN_API_KEY'] = \"\"\n", + "javelin_api_key = os.environ['JAVELIN_API_KEY'] = \"\" \n", "config = JavelinConfig(\n", " base_url=\"https://api-dev.javelin.live\",\n", " # Uncomment the following line to use a local server:\n",