mirror of
https://github.com/katanemo/plano.git
synced 2026-05-15 11:02:39 +02:00
Fix errors and improve Doc (#143)
* Fix link issues and add icons * Improve Doc * fix test * making minor modifications to shuguangs' doc changes --------- Co-authored-by: Salman Paracha <salmanparacha@MacBook-Pro-261.local> Co-authored-by: Adil Hafeez <adil@katanemo.com>
This commit is contained in:
parent
3ed50e61d2
commit
b30ad791f7
27 changed files with 396 additions and 329 deletions
|
|
@ -10,6 +10,7 @@ app = Flask(__name__)
|
|||
# Global dictionary to keep track of user memories
|
||||
user_memories = {}
|
||||
|
||||
|
||||
def get_user_conversation(user_id):
|
||||
"""
|
||||
Retrieve the user's conversation memory using LangChain.
|
||||
|
|
@ -19,6 +20,7 @@ def get_user_conversation(user_id):
|
|||
user_memories[user_id] = ConversationBufferMemory(return_messages=True)
|
||||
return user_memories[user_id]
|
||||
|
||||
|
||||
def update_user_conversation(user_id, client_messages, intent_changed):
|
||||
"""
|
||||
Update the user's conversation memory with new messages using LangChain.
|
||||
|
|
@ -34,26 +36,26 @@ def update_user_conversation(user_id, client_messages, intent_changed):
|
|||
|
||||
# Process each new message
|
||||
for index, message in enumerate(new_messages):
|
||||
role = message.get('role')
|
||||
content = message.get('content')
|
||||
role = message.get("role")
|
||||
content = message.get("content")
|
||||
metadata = {
|
||||
'uuid': str(uuid.uuid4()),
|
||||
'timestamp': datetime.utcnow().isoformat(),
|
||||
'intent_changed': False # Default value
|
||||
"uuid": str(uuid.uuid4()),
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"intent_changed": False, # Default value
|
||||
}
|
||||
|
||||
# Mark the intent change on the last message if detected
|
||||
if intent_changed and index == len(new_messages) - 1:
|
||||
metadata['intent_changed'] = True
|
||||
metadata["intent_changed"] = True
|
||||
|
||||
# Create a new message with metadata
|
||||
if role == 'user':
|
||||
if role == "user":
|
||||
memory.chat_memory.add_message(
|
||||
HumanMessage(content=content, additional_kwargs={'metadata': metadata})
|
||||
HumanMessage(content=content, additional_kwargs={"metadata": metadata})
|
||||
)
|
||||
elif role == 'assistant':
|
||||
elif role == "assistant":
|
||||
memory.chat_memory.add_message(
|
||||
AIMessage(content=content, additional_kwargs={'metadata': metadata})
|
||||
AIMessage(content=content, additional_kwargs={"metadata": metadata})
|
||||
)
|
||||
else:
|
||||
# Handle other roles if necessary
|
||||
|
|
@ -61,6 +63,7 @@ def update_user_conversation(user_id, client_messages, intent_changed):
|
|||
|
||||
return memory
|
||||
|
||||
|
||||
def get_messages_since_last_intent(messages):
|
||||
"""
|
||||
Retrieve messages from the last intent change onwards using LangChain.
|
||||
|
|
@ -69,12 +72,14 @@ def get_messages_since_last_intent(messages):
|
|||
for message in reversed(messages):
|
||||
# Insert message at the beginning to maintain correct order
|
||||
messages_since_intent.insert(0, message)
|
||||
metadata = message.additional_kwargs.get('metadata', {})
|
||||
metadata = message.additional_kwargs.get("metadata", {})
|
||||
# Break if intent_changed is True
|
||||
if metadata.get('intent_changed', False) == True:
|
||||
if metadata.get("intent_changed", False) == True:
|
||||
break
|
||||
|
||||
return messages_since_intent
|
||||
|
||||
|
||||
def forward_to_llm(messages):
|
||||
"""
|
||||
Forward messages to an upstream LLM using LangChain.
|
||||
|
|
@ -82,7 +87,7 @@ def forward_to_llm(messages):
|
|||
# Convert messages to a conversation string
|
||||
conversation = ""
|
||||
for message in messages:
|
||||
role = 'User' if isinstance(message, HumanMessage) else 'Assistant'
|
||||
role = "User" if isinstance(message, HumanMessage) else "Assistant"
|
||||
content = message.content
|
||||
conversation += f"{role}: {content}\n"
|
||||
# Use LangChain's LLM to get a response. This call is proxied through Arch for end-to-end observability and traffic management
|
||||
|
|
@ -92,28 +97,31 @@ def forward_to_llm(messages):
|
|||
response = llm(prompt)
|
||||
return response
|
||||
|
||||
@app.route('/process_rag', methods=['POST'])
|
||||
|
||||
@app.route("/process_rag", methods=["POST"])
|
||||
def process_rag():
|
||||
# Extract JSON data from the request
|
||||
data = request.get_json()
|
||||
|
||||
user_id = data.get('user_id')
|
||||
user_id = data.get("user_id")
|
||||
if not user_id:
|
||||
return jsonify({'error': 'User ID is required'}), 400
|
||||
return jsonify({"error": "User ID is required"}), 400
|
||||
|
||||
client_messages = data.get('messages')
|
||||
client_messages = data.get("messages")
|
||||
if not client_messages or not isinstance(client_messages, list):
|
||||
return jsonify({'error': 'Messages array is required'}), 400
|
||||
return jsonify({"error": "Messages array is required"}), 400
|
||||
|
||||
# Extract the intent change marker from Arch's headers if present for the current prompt
|
||||
intent_changed_header = request.headers.get('x-arch-intent-marker', '').lower()
|
||||
if intent_changed_header in ['', 'false']:
|
||||
intent_changed_header = request.headers.get("x-arch-intent-marker", "").lower()
|
||||
if intent_changed_header in ["", "false"]:
|
||||
intent_changed = False
|
||||
elif intent_changed_header == 'true':
|
||||
elif intent_changed_header == "true":
|
||||
intent_changed = True
|
||||
else:
|
||||
# Invalid value provided
|
||||
return jsonify({'error': 'Invalid value for x-arch-prompt-intent-change header'}), 400
|
||||
return jsonify(
|
||||
{"error": "Invalid value for x-arch-prompt-intent-change header"}
|
||||
), 400
|
||||
|
||||
# Update user conversation based on intent change
|
||||
memory = update_user_conversation(user_id, client_messages, intent_changed)
|
||||
|
|
@ -127,26 +135,27 @@ def process_rag():
|
|||
# Prepare the messages to return
|
||||
messages_to_return = []
|
||||
for message in memory.chat_memory.messages:
|
||||
role = 'user' if isinstance(message, HumanMessage) else 'assistant'
|
||||
role = "user" if isinstance(message, HumanMessage) else "assistant"
|
||||
content = message.content
|
||||
metadata = message.additional_kwargs.get('metadata', {})
|
||||
metadata = message.additional_kwargs.get("metadata", {})
|
||||
message_entry = {
|
||||
'uuid': metadata.get('uuid'),
|
||||
'timestamp': metadata.get('timestamp'),
|
||||
'role': role,
|
||||
'content': content,
|
||||
'intent_changed': metadata.get('intent_changed', False)
|
||||
"uuid": metadata.get("uuid"),
|
||||
"timestamp": metadata.get("timestamp"),
|
||||
"role": role,
|
||||
"content": content,
|
||||
"intent_changed": metadata.get("intent_changed", False),
|
||||
}
|
||||
messages_to_return.append(message_entry)
|
||||
|
||||
# Prepare the response
|
||||
response = {
|
||||
'user_id': user_id,
|
||||
'messages': messages_to_return,
|
||||
'llm_response': llm_response
|
||||
"user_id": user_id,
|
||||
"messages": messages_to_return,
|
||||
"llm_response": llm_response,
|
||||
}
|
||||
|
||||
return jsonify(response), 200
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ from flask import Flask, request, jsonify
|
|||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/agent/device_summary', methods=['POST'])
|
||||
|
||||
@app.route("/agent/device_summary", methods=["POST"])
|
||||
def get_device_summary():
|
||||
"""
|
||||
Endpoint to retrieve device statistics based on device IDs and an optional time range.
|
||||
|
|
@ -10,14 +11,16 @@ def get_device_summary():
|
|||
data = request.get_json()
|
||||
|
||||
# Validate 'device_ids' parameter
|
||||
device_ids = data.get('device_ids')
|
||||
device_ids = data.get("device_ids")
|
||||
if not device_ids or not isinstance(device_ids, list):
|
||||
return jsonify({'error': "'device_ids' parameter is required and must be a list"}), 400
|
||||
return jsonify(
|
||||
{"error": "'device_ids' parameter is required and must be a list"}
|
||||
), 400
|
||||
|
||||
# Validate 'time_range' parameter (optional, defaults to 7)
|
||||
time_range = data.get('time_range', 7)
|
||||
time_range = data.get("time_range", 7)
|
||||
if not isinstance(time_range, int):
|
||||
return jsonify({'error': "'time_range' must be an integer"}), 400
|
||||
return jsonify({"error": "'time_range' must be an integer"}), 400
|
||||
|
||||
# Simulate retrieving statistics for the given device IDs and time range
|
||||
# In a real application, you would query your database or external service here
|
||||
|
|
@ -25,17 +28,16 @@ def get_device_summary():
|
|||
for device_id in device_ids:
|
||||
# Placeholder for actual data retrieval
|
||||
stats = {
|
||||
'device_id': device_id,
|
||||
'time_range': f'Last {time_range} days',
|
||||
'data': f'Statistics data for device {device_id} over the last {time_range} days.'
|
||||
"device_id": device_id,
|
||||
"time_range": f"Last {time_range} days",
|
||||
"data": f"Statistics data for device {device_id} over the last {time_range} days.",
|
||||
}
|
||||
statistics.append(stats)
|
||||
|
||||
response = {
|
||||
'statistics': statistics
|
||||
}
|
||||
response = {"statistics": statistics}
|
||||
|
||||
return jsonify(response), 200
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
|
|
|
|||
|
|
@ -1,21 +1,15 @@
|
|||
prompt_targets:
|
||||
- name: get_device_statistics
|
||||
description: >
|
||||
This prompt target ensures that when users request device-related statistics, the system accurately retrieves and presents the relevant data
|
||||
based on the specified devices and time range. Examples of user prompts, include:
|
||||
|
||||
- "Show me the performance stats for device 12345 over the past week."
|
||||
- "What are the error rates for my devices in the last 24 hours?"
|
||||
- "I need statistics on device 789 over the last 10 days."
|
||||
description: Retrieve and present the relevant data based on the specified devices and time range
|
||||
|
||||
path: /agent/device_summary
|
||||
parameters:
|
||||
- name: "device_ids"
|
||||
type: list # Options: integer | float | list | dictionary | set
|
||||
description: "A list of device identifiers (IDs) for which the statistics are requested."
|
||||
- name: device_ids
|
||||
type: list
|
||||
description: A list of device identifiers (IDs) to reboot.
|
||||
required: true
|
||||
- name: "time_range"
|
||||
type: integer # Options: integer | float | list | dictionary | set
|
||||
description: "The number of days in the past over which to retrieve device statistics. Defaults to 7 days if not specified."
|
||||
- name: time_range
|
||||
type: int
|
||||
description: The number of days in the past over which to retrieve device statistics
|
||||
required: false
|
||||
default: 7
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue