Guest User

OpenWebUI agent as model

a guest
Apr 14th, 2025
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.45 KB | None | 0 0
  1. from flask import Flask, request, jsonify
  2. import boto3
  3. import time
  4. import uuid
  5. import base64
  6. from langchain.memory import ConversationBufferMemory # LangChain for context
  7.  
  8. app = Flask(__name__)
  9.  
  10. # Initialize AWS Bedrock client
  11. bedrock_runtime = boto3.client('bedrock-agent-runtime', region_name="yourregionhere")
  12.  
  13. # Mapping of agents with their aliases. repeat the line each time you need to define a new agent
  14. AGENTS = {
  15. "agent1": {"id": "AgentID", "alias": "AgentAlias"},
  16. "agent2": {"id": "AgentID", "alias": "AgentAlias"}
  17. }
  18.  
  19. # API key for request authentication
  20. API_KEY = "mysecretkey123"
  21.  
  22. # Dictionary to store conversation memories
  23. # Key format: "user_id:conversation_id"
  24. conversation_memories = {}
  25.  
  26. def get_conversation_memory(user_id, conversation_id):
  27. """
  28. Retrieves or initializes a conversation memory for a given user and conversation.
  29. """
  30. key = f"{user_id}:{conversation_id}"
  31. if key not in conversation_memories:
  32. conversation_memories[key] = ConversationBufferMemory(return_messages=True)
  33. return conversation_memories[key]
  34.  
  35. def call_bedrock_agent(agent_id, agent_alias, user_id, conversation_id, user_message, history):
  36. """
  37. Sends a user message to the Bedrock agent while maintaining context using LangChain.
  38. """
  39. memory = get_conversation_memory(user_id, conversation_id)
  40.  
  41. # Add user message to memory
  42. memory.chat_memory.add_user_message(user_message)
  43.  
  44. # Build the full prompt with context
  45. full_prompt = "\n".join(history) + f"\nUser: {user_message}"
  46.  
  47. session_id = str(uuid.uuid4()) # Generate a unique session ID for this request
  48.  
  49. try:
  50. # Invoke Bedrock agent with the contextualized prompt
  51. response_stream = bedrock_runtime.invoke_agent(
  52. agentId=agent_id,
  53. agentAliasId=agent_alias,
  54. sessionId=session_id,
  55. inputText=full_prompt
  56. )["completion"]
  57.  
  58. response_text = ""
  59.  
  60. # Process streaming response
  61. for event in response_stream:
  62. if "chunk" in event:
  63. chunk_data = event["chunk"].get("bytes", b"")
  64. if isinstance(chunk_data, bytes):
  65. try:
  66. decoded_chunk = chunk_data.decode("utf-8")
  67. except UnicodeDecodeError:
  68. decoded_chunk = base64.b64encode(chunk_data).decode("utf-8")
  69. else:
  70. decoded_chunk = str(chunk_data)
  71. response_text += decoded_chunk
  72.  
  73. # Add agent response to memory
  74. memory.chat_memory.add_ai_message(response_text)
  75.  
  76. # Return the response along with user_id and conversation_id for tracking
  77. return jsonify({
  78. "id": f"chatcmpl-{agent_id[:8]}",
  79. "object": "chat.completion",
  80. "created": int(time.time()),
  81. "model": f"bedrock-agent-{agent_id}",
  82. "choices": [{
  83. "index": 0,
  84. "message": {
  85. "role": "assistant",
  86. "content": response_text
  87. },
  88. "finish_reason": "stop"
  89. }],
  90. "user_id": user_id,
  91. "conversation_id": conversation_id
  92. })
  93.  
  94. except Exception as e:
  95. return jsonify({"error": str(e)}), 500
  96.  
  97. @app.before_request
  98. def check_api_key():
  99. """
  100. Validates the API key in the request headers.
  101. """
  102. api_key = request.headers.get("Authorization")
  103. if not api_key or not api_key.startswith("Bearer "):
  104. return jsonify({"error": "Unauthorized"}), 401
  105.  
  106. key_value = api_key.split("Bearer ")[1]
  107. if key_value != API_KEY:
  108. return jsonify({"error": "Forbidden"}), 403
  109.  
  110. @app.route("/v1/chat/completions", methods=["POST"])
  111. def handle_chat_completions():
  112. """
  113. Handles chat completions requests.
  114. """
  115. data = request.json
  116. if not data or "model" not in data:
  117. return jsonify({"error": "Missing 'model' field in request"}), 400
  118.  
  119. model_id = data["model"]
  120. agent_id = model_id.replace("bedrock-agent-", "")
  121.  
  122. agent_info = next((info for info in AGENTS.values() if info["id"] == agent_id), None)
  123. if not agent_info:
  124. return jsonify({"error": "Invalid model specified"}), 400
  125.  
  126. user_message = data["messages"][-1]["content"]
  127.  
  128. # Extract user_id and conversation_id from request
  129. user_id = data.get("user_id") or request.headers.get("X-User-ID")
  130. conversation_id = data.get("conversation_id") or request.headers.get("X-Conversation-ID")
  131.  
  132. if not user_id:
  133. user_id = str(uuid.uuid4())
  134.  
  135. if not conversation_id:
  136. conversation_id = str(uuid.uuid4())
  137.  
  138. # Retrieve the conversation history
  139. history = [f"{msg['role']}: {msg['content']}" for msg in data["messages"][:-1]]
  140.  
  141. return call_bedrock_agent(agent_info["id"], agent_info["alias"], user_id, conversation_id, user_message, history)
  142.  
  143. @app.route("/v1/models", methods=["GET"])
  144. def list_models():
  145. """
  146. Returns a list of available Bedrock agents.
  147. """
  148. models = [{"id": f"bedrock-agent-{agent_info['id']}", "object": "model"} for agent_info in AGENTS.values()]
  149. return jsonify({"object": "list", "data": models})
  150.  
  151. # Dynamically create routes for each agent
  152. def create_agent_view(agent_id, agent_alias):
  153. def agent_view():
  154. data = request.json
  155. if not data or "messages" not in data or not data["messages"]:
  156. return jsonify({"error": "Invalid request format"}), 400
  157.  
  158. user_message = data["messages"][-1]["content"]
  159.  
  160. user_id = data.get("user_id") or request.headers.get("X-User-ID")
  161. conversation_id = data.get("conversation_id") or request.headers.get("X-Conversation-ID")
  162.  
  163. if not user_id:
  164. user_id = str(uuid.uuid4())
  165.  
  166. if not conversation_id:
  167. conversation_id = str(uuid.uuid4())
  168.  
  169. # Retrieve the conversation history
  170. history = [f"{msg['role']}: {msg['content']}" for msg in data["messages"][:-1]]
  171.  
  172. return call_bedrock_agent(agent_id, agent_alias, user_id, conversation_id, user_message, history)
  173.  
  174. return agent_view
  175.  
  176. for agent_name, agent_info in AGENTS.items():
  177. app.add_url_rule(
  178. f"/v1/chat/completions/{agent_name}",
  179. endpoint=f"agent_{agent_name}",
  180. view_func=create_agent_view(agent_info["id"], agent_info["alias"]),
  181. methods=["POST"]
  182. )
  183.  
  184. if __name__ == "__main__":
  185. app.run(host="0.0.0.0", port=5001)
  186.  
Add Comment
Please, Sign In to add comment