feat: mock capabilities initial commit
Browse files- app/core/api_response.py +87 -0
- docs/conversation.drawio +90 -0
- resources/mock/chat_completions_GET.json +30 -0
- resources/mock/chat_completions_POST.json +28 -0
- resources/mock/chat_completions_id_GET.json +28 -0
- resources/mock/chat_completions_messages_GET.json +36 -0
- resources/mock/chat_completions_plots_GET.json +28 -0
- resources/mock/conversations_GET.json +67 -0
- resources/mock/conversations_id_GET.json +20 -0
app/core/api_response.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from functools import wraps
|
| 2 |
+
from fastapi import HTTPException, Request, status
|
| 3 |
+
from loguru import logger
|
| 4 |
+
import os
|
| 5 |
+
import json
|
| 6 |
+
from typing import Dict
|
| 7 |
+
from environs import Env
|
| 8 |
+
|
| 9 |
+
env = Env()
|
| 10 |
+
env.read_env()
|
| 11 |
+
|
| 12 |
+
USE_MOCK = env.bool("USE_MOCK", True)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def url_to_filename(url: str, method: str) -> str:
|
| 16 |
+
"""
|
| 17 |
+
Convert API URL to mock filename.
|
| 18 |
+
Example:
|
| 19 |
+
- Input: GET "/v1/chat/completions" -> "chat_completions_GET.json"
|
| 20 |
+
- Input: GET "/v1/chat/completions/{completion_id}" -> "chat_completions_id_GET.json"
|
| 21 |
+
- Input: GET "/v1/chat/completions/123/messages" -> "chat_completions_id_messages_GET.json"
|
| 22 |
+
"""
|
| 23 |
+
logger.trace(f"BEGIN: url: {url} method: {method}")
|
| 24 |
+
# Remove version prefix and leading/trailing slashes
|
| 25 |
+
path = url.strip("/")
|
| 26 |
+
if path.startswith("v1/"):
|
| 27 |
+
path = path[3:]
|
| 28 |
+
|
| 29 |
+
# Replace path parameters with descriptive names
|
| 30 |
+
path = path.replace("{completion_id}", "id")
|
| 31 |
+
path = path.replace("{message_id}", "id")
|
| 32 |
+
|
| 33 |
+
# Convert to filename format
|
| 34 |
+
filename = path.replace("/", "_")
|
| 35 |
+
|
| 36 |
+
# Add method suffix
|
| 37 |
+
result = f"{filename}_{method}"
|
| 38 |
+
logger.trace(f"END: result: {result}")
|
| 39 |
+
return result
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def get_mock_response(url_path: str, method: str) -> Dict:
|
| 43 |
+
"""Get mock response from JSON file."""
|
| 44 |
+
logger.trace(f"BEGIN: url_path: {url_path} method: {method}")
|
| 45 |
+
filename = None
|
| 46 |
+
try:
|
| 47 |
+
# Convert to filename
|
| 48 |
+
filename = url_to_filename(url_path, method)
|
| 49 |
+
|
| 50 |
+
# Load mock response
|
| 51 |
+
file_path = os.path.join(os.path.dirname(__file__), "mock", f"{filename}.json")
|
| 52 |
+
with open(file_path, "r") as f:
|
| 53 |
+
result = json.load(f)
|
| 54 |
+
logger.trace(f"END: result: {result}")
|
| 55 |
+
return result
|
| 56 |
+
except FileNotFoundError:
|
| 57 |
+
raise HTTPException(
|
| 58 |
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 59 |
+
detail=f"{filename} mock file not found for endpoint: {url_path} [{method}]"
|
| 60 |
+
)
|
| 61 |
+
except Exception as e:
|
| 62 |
+
raise HTTPException(
|
| 63 |
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
| 64 |
+
detail=f"{filename} error loading mock response: {str(e)}"
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def api_response():
|
| 69 |
+
"""Decorator to handle mock/real API responses."""
|
| 70 |
+
def decorator(func):
|
| 71 |
+
@wraps(func)
|
| 72 |
+
async def wrapper(request: Request, *args, **kwargs):
|
| 73 |
+
url_path = request.url.path
|
| 74 |
+
method = request.method
|
| 75 |
+
logger.debug(f"BEGIN: url_path: {url_path} method: {method}")
|
| 76 |
+
if USE_MOCK:
|
| 77 |
+
logger.warning("Using mock response")
|
| 78 |
+
result = get_mock_response(url_path, method)
|
| 79 |
+
logger.trace(f"END: result: {result}")
|
| 80 |
+
return result
|
| 81 |
+
else:
|
| 82 |
+
# Call original function for real response
|
| 83 |
+
result = await func(request, *args, **kwargs)
|
| 84 |
+
logger.trace(f"END: result: {result}")
|
| 85 |
+
return result
|
| 86 |
+
return wrapper
|
| 87 |
+
return decorator
|
docs/conversation.drawio
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<mxfile host="65bd71144e">
|
| 2 |
+
<diagram id="RUA-RFROyaZDF0aJ2uCW" name="Page-1">
|
| 3 |
+
<mxGraphModel dx="1098" dy="639" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0" adaptiveColors="simple">
|
| 4 |
+
<root>
|
| 5 |
+
<mxCell id="0"/>
|
| 6 |
+
<mxCell id="1" parent="0"/>
|
| 7 |
+
<mxCell id="4" style="edgeStyle=none;html=1;" edge="1" parent="1" source="2" target="3">
|
| 8 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 9 |
+
</mxCell>
|
| 10 |
+
<mxCell id="2" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
|
| 11 |
+
<mxGeometry x="70" y="230" width="30" height="60" as="geometry"/>
|
| 12 |
+
</mxCell>
|
| 13 |
+
<mxCell id="6" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="3" target="5">
|
| 14 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 15 |
+
</mxCell>
|
| 16 |
+
<mxCell id="3" value="frontend" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
| 17 |
+
<mxGeometry x="230" y="230" width="120" height="60" as="geometry"/>
|
| 18 |
+
</mxCell>
|
| 19 |
+
<mxCell id="8" style="edgeStyle=none;html=1;" edge="1" parent="1" source="5" target="7">
|
| 20 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 21 |
+
</mxCell>
|
| 22 |
+
<mxCell id="10" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="5" target="9">
|
| 23 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 24 |
+
</mxCell>
|
| 25 |
+
<mxCell id="12" style="edgeStyle=none;html=1;" edge="1" parent="1" source="5" target="11">
|
| 26 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 27 |
+
</mxCell>
|
| 28 |
+
<mxCell id="17" style="edgeStyle=none;html=1;" edge="1" parent="1" source="5" target="16">
|
| 29 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 30 |
+
</mxCell>
|
| 31 |
+
<mxCell id="20" style="edgeStyle=none;html=1;" edge="1" parent="1" source="5" target="19">
|
| 32 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 33 |
+
</mxCell>
|
| 34 |
+
<mxCell id="5" value="backend" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
| 35 |
+
<mxGeometry x="500" y="230" width="120" height="60" as="geometry"/>
|
| 36 |
+
</mxCell>
|
| 37 |
+
<mxCell id="7" value="mongo" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
|
| 38 |
+
<mxGeometry x="800" y="220" width="60" height="80" as="geometry"/>
|
| 39 |
+
</mxCell>
|
| 40 |
+
<mxCell id="22" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="9" target="21">
|
| 41 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 42 |
+
</mxCell>
|
| 43 |
+
<mxCell id="24" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="9" target="23">
|
| 44 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 45 |
+
</mxCell>
|
| 46 |
+
<mxCell id="9" value="schema" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
| 47 |
+
<mxGeometry x="180" y="400" width="120" height="60" as="geometry"/>
|
| 48 |
+
</mxCell>
|
| 49 |
+
<mxCell id="14" style="edgeStyle=none;html=1;" edge="1" parent="1" source="11" target="13">
|
| 50 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 51 |
+
</mxCell>
|
| 52 |
+
<mxCell id="11" value="model" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
| 53 |
+
<mxGeometry x="490" y="400" width="120" height="60" as="geometry"/>
|
| 54 |
+
</mxCell>
|
| 55 |
+
<mxCell id="15" style="edgeStyle=none;html=1;" edge="1" parent="1" source="13" target="16">
|
| 56 |
+
<mxGeometry relative="1" as="geometry">
|
| 57 |
+
<mxPoint x="640" y="460" as="targetPoint"/>
|
| 58 |
+
</mxGeometry>
|
| 59 |
+
</mxCell>
|
| 60 |
+
<mxCell id="27" style="edgeStyle=none;html=1;" edge="1" parent="1" source="13" target="23">
|
| 61 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 62 |
+
</mxCell>
|
| 63 |
+
<mxCell id="28" style="edgeStyle=none;html=1;" edge="1" parent="1" source="13" target="21">
|
| 64 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 65 |
+
</mxCell>
|
| 66 |
+
<mxCell id="13" value="chat_completion" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
| 67 |
+
<mxGeometry x="660" y="640" width="120" height="120" as="geometry"/>
|
| 68 |
+
</mxCell>
|
| 69 |
+
<mxCell id="29" style="edgeStyle=none;html=1;" edge="1" parent="1" source="16" target="7">
|
| 70 |
+
<mxGeometry relative="1" as="geometry"/>
|
| 71 |
+
</mxCell>
|
| 72 |
+
<mxCell id="16" value="repository" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
| 73 |
+
<mxGeometry x="670" y="400" width="120" height="60" as="geometry"/>
|
| 74 |
+
</mxCell>
|
| 75 |
+
<mxCell id="18" value="api" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
| 76 |
+
<mxGeometry x="25" y="400" width="120" height="60" as="geometry"/>
|
| 77 |
+
</mxCell>
|
| 78 |
+
<mxCell id="19" value="service" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
| 79 |
+
<mxGeometry x="340" y="400" width="120" height="60" as="geometry"/>
|
| 80 |
+
</mxCell>
|
| 81 |
+
<mxCell id="21" value="conversation" style="ellipse;whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="1">
|
| 82 |
+
<mxGeometry x="180" y="670" width="80" height="80" as="geometry"/>
|
| 83 |
+
</mxCell>
|
| 84 |
+
<mxCell id="23" value="<span style="color: rgb(0, 0, 0);">chat_completion</span>" style="ellipse;whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="1">
|
| 85 |
+
<mxGeometry x="260" y="520" width="120" height="90" as="geometry"/>
|
| 86 |
+
</mxCell>
|
| 87 |
+
</root>
|
| 88 |
+
</mxGraphModel>
|
| 89 |
+
</diagram>
|
| 90 |
+
</mxfile>
|
resources/mock/chat_completions_GET.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "chatcmpl-mock-123",
|
| 4 |
+
"object": "chat.completion",
|
| 5 |
+
"created": 1677858242,
|
| 6 |
+
"model": "gpt-3.5-turbo",
|
| 7 |
+
"choices": [
|
| 8 |
+
{
|
| 9 |
+
"index": 0,
|
| 10 |
+
"message": {
|
| 11 |
+
"role": "assistant",
|
| 12 |
+
"content": "This is a mock response from the assistant.",
|
| 13 |
+
"tool_calls": null,
|
| 14 |
+
"annotations": [],
|
| 15 |
+
"audio": null,
|
| 16 |
+
"refusal": ""
|
| 17 |
+
},
|
| 18 |
+
"finish_reason": "stop",
|
| 19 |
+
"logprobs": null
|
| 20 |
+
}
|
| 21 |
+
],
|
| 22 |
+
"usage": {
|
| 23 |
+
"prompt_tokens": 10,
|
| 24 |
+
"completion_tokens": 20,
|
| 25 |
+
"total_tokens": 30
|
| 26 |
+
},
|
| 27 |
+
"service_tier": "standard",
|
| 28 |
+
"system_fingerprint": "fp_1234567890"
|
| 29 |
+
}
|
| 30 |
+
]
|
resources/mock/chat_completions_POST.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "chatcmpl-mock-123",
|
| 3 |
+
"object": "chat.completion",
|
| 4 |
+
"created": 1677858242,
|
| 5 |
+
"model": "gpt-3.5-turbo",
|
| 6 |
+
"choices": [
|
| 7 |
+
{
|
| 8 |
+
"index": 0,
|
| 9 |
+
"message": {
|
| 10 |
+
"role": "assistant",
|
| 11 |
+
"content": "This is a mock response from the assistant.",
|
| 12 |
+
"tool_calls": null,
|
| 13 |
+
"annotations": [],
|
| 14 |
+
"audio": null,
|
| 15 |
+
"refusal": ""
|
| 16 |
+
},
|
| 17 |
+
"finish_reason": "stop",
|
| 18 |
+
"logprobs": null
|
| 19 |
+
}
|
| 20 |
+
],
|
| 21 |
+
"usage": {
|
| 22 |
+
"prompt_tokens": 10,
|
| 23 |
+
"completion_tokens": 20,
|
| 24 |
+
"total_tokens": 30
|
| 25 |
+
},
|
| 26 |
+
"service_tier": "standard",
|
| 27 |
+
"system_fingerprint": "fp_1234567890"
|
| 28 |
+
}
|
resources/mock/chat_completions_id_GET.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "chatcmpl-mock-123",
|
| 3 |
+
"object": "chat.completion",
|
| 4 |
+
"created": 1677858242,
|
| 5 |
+
"model": "gpt-3.5-turbo",
|
| 6 |
+
"choices": [
|
| 7 |
+
{
|
| 8 |
+
"index": 0,
|
| 9 |
+
"message": {
|
| 10 |
+
"role": "assistant",
|
| 11 |
+
"content": "This is a mock response from the assistant.",
|
| 12 |
+
"tool_calls": null,
|
| 13 |
+
"annotations": [],
|
| 14 |
+
"audio": null,
|
| 15 |
+
"refusal": ""
|
| 16 |
+
},
|
| 17 |
+
"finish_reason": "stop",
|
| 18 |
+
"logprobs": null
|
| 19 |
+
}
|
| 20 |
+
],
|
| 21 |
+
"usage": {
|
| 22 |
+
"prompt_tokens": 10,
|
| 23 |
+
"completion_tokens": 20,
|
| 24 |
+
"total_tokens": 30
|
| 25 |
+
},
|
| 26 |
+
"service_tier": "standard",
|
| 27 |
+
"system_fingerprint": "fp_1234567890"
|
| 28 |
+
}
|
resources/mock/chat_completions_messages_GET.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"object": "list",
|
| 3 |
+
"data": [
|
| 4 |
+
{
|
| 5 |
+
"id": "chatcmpl-mock-123",
|
| 6 |
+
"object": "chat.completion",
|
| 7 |
+
"created": 1677858242,
|
| 8 |
+
"model": "gpt-3.5-turbo",
|
| 9 |
+
"choices": [
|
| 10 |
+
{
|
| 11 |
+
"index": 0,
|
| 12 |
+
"message": {
|
| 13 |
+
"role": "assistant",
|
| 14 |
+
"content": "This is a mock response from the assistant.",
|
| 15 |
+
"tool_calls": null,
|
| 16 |
+
"annotations": [],
|
| 17 |
+
"audio": null,
|
| 18 |
+
"refusal": ""
|
| 19 |
+
},
|
| 20 |
+
"finish_reason": "stop",
|
| 21 |
+
"logprobs": null
|
| 22 |
+
}
|
| 23 |
+
],
|
| 24 |
+
"usage": {
|
| 25 |
+
"prompt_tokens": 10,
|
| 26 |
+
"completion_tokens": 20,
|
| 27 |
+
"total_tokens": 30
|
| 28 |
+
},
|
| 29 |
+
"service_tier": "standard",
|
| 30 |
+
"system_fingerprint": "fp_1234567890"
|
| 31 |
+
}
|
| 32 |
+
],
|
| 33 |
+
"first_id": "chatcmpl-mock-123",
|
| 34 |
+
"last_id": "chatcmpl-mock-123",
|
| 35 |
+
"has_more": false
|
| 36 |
+
}
|
resources/mock/chat_completions_plots_GET.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "chatcmpl-mock-123",
|
| 3 |
+
"name": "Mock Chat",
|
| 4 |
+
"created_at": 1677858242,
|
| 5 |
+
"updated_at": 1677858242,
|
| 6 |
+
"message": {
|
| 7 |
+
"message_id": "msg-mock-123",
|
| 8 |
+
"role": "assistant",
|
| 9 |
+
"content": "This is a mock response from the assistant.",
|
| 10 |
+
"name": null,
|
| 11 |
+
"function_call": null,
|
| 12 |
+
"tool_calls": null,
|
| 13 |
+
"annotations": [],
|
| 14 |
+
"audio": null,
|
| 15 |
+
"refusal": "",
|
| 16 |
+
"created_at": 1677858242
|
| 17 |
+
},
|
| 18 |
+
"plots": [
|
| 19 |
+
{
|
| 20 |
+
"type": "line",
|
| 21 |
+
"data": {
|
| 22 |
+
"x": [1, 2, 3, 4, 5],
|
| 23 |
+
"y": [1, 4, 9, 16, 25]
|
| 24 |
+
},
|
| 25 |
+
"title": "Mock Plot"
|
| 26 |
+
}
|
| 27 |
+
]
|
| 28 |
+
}
|
resources/mock/conversations_GET.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"items": [
|
| 3 |
+
{
|
| 4 |
+
"id": "682f026d-23e8-800f-90a1-a1399b85ae64",
|
| 5 |
+
"title": "Customer status",
|
| 6 |
+
"create_time": "2025-05-22T10:54:37.569747Z",
|
| 7 |
+
"update_time": "2025-05-22T10:55:55.212705Z",
|
| 8 |
+
"mapping": null,
|
| 9 |
+
"current_node": null,
|
| 10 |
+
"conversation_template_id": null,
|
| 11 |
+
"gizmo_id": null,
|
| 12 |
+
"is_archived": false,
|
| 13 |
+
"is_starred": null,
|
| 14 |
+
"is_do_not_remember": false,
|
| 15 |
+
"memory_scope": "global_enabled",
|
| 16 |
+
"workspace_id": null,
|
| 17 |
+
"async_status": null,
|
| 18 |
+
"safe_urls": [],
|
| 19 |
+
"blocked_urls": [],
|
| 20 |
+
"conversation_origin": null,
|
| 21 |
+
"snippet": null
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"id": "682ede89-cd84-800f-b80f-8389bcbee865",
|
| 25 |
+
"title": "Ticket count by status",
|
| 26 |
+
"create_time": "2025-05-22T08:21:30.215436Z",
|
| 27 |
+
"update_time": "2025-05-22T08:22:54.867192Z",
|
| 28 |
+
"mapping": null,
|
| 29 |
+
"current_node": null,
|
| 30 |
+
"conversation_template_id": null,
|
| 31 |
+
"gizmo_id": null,
|
| 32 |
+
"is_archived": false,
|
| 33 |
+
"is_starred": null,
|
| 34 |
+
"is_do_not_remember": false,
|
| 35 |
+
"memory_scope": "global_enabled",
|
| 36 |
+
"workspace_id": null,
|
| 37 |
+
"async_status": null,
|
| 38 |
+
"safe_urls": [],
|
| 39 |
+
"blocked_urls": [],
|
| 40 |
+
"conversation_origin": null,
|
| 41 |
+
"snippet": null
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"id": "682ec852-4014-800f-8a98-d257668a391e",
|
| 45 |
+
"title": "Ticket comments count by customer",
|
| 46 |
+
"create_time": "2025-05-22T06:46:42.703604Z",
|
| 47 |
+
"update_time": "2025-05-22T06:50:05.464929Z",
|
| 48 |
+
"mapping": null,
|
| 49 |
+
"current_node": null,
|
| 50 |
+
"conversation_template_id": null,
|
| 51 |
+
"gizmo_id": null,
|
| 52 |
+
"is_archived": false,
|
| 53 |
+
"is_starred": null,
|
| 54 |
+
"is_do_not_remember": false,
|
| 55 |
+
"memory_scope": "global_enabled",
|
| 56 |
+
"workspace_id": null,
|
| 57 |
+
"async_status": null,
|
| 58 |
+
"safe_urls": [],
|
| 59 |
+
"blocked_urls": [],
|
| 60 |
+
"conversation_origin": null,
|
| 61 |
+
"snippet": null
|
| 62 |
+
}
|
| 63 |
+
],
|
| 64 |
+
"total": 79,
|
| 65 |
+
"limit": 28,
|
| 66 |
+
"offset": 0
|
| 67 |
+
}
|
resources/mock/conversations_id_GET.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "682f026d-23e8-800f-90a1-a1399b85ae64",
|
| 3 |
+
"title": "Customer status",
|
| 4 |
+
"create_time": "2025-05-22T10:54:37.569747Z",
|
| 5 |
+
"update_time": "2025-05-22T10:55:55.212705Z",
|
| 6 |
+
"mapping": null,
|
| 7 |
+
"current_node": null,
|
| 8 |
+
"conversation_template_id": null,
|
| 9 |
+
"gizmo_id": null,
|
| 10 |
+
"is_archived": false,
|
| 11 |
+
"is_starred": null,
|
| 12 |
+
"is_do_not_remember": false,
|
| 13 |
+
"memory_scope": "global_enabled",
|
| 14 |
+
"workspace_id": null,
|
| 15 |
+
"async_status": null,
|
| 16 |
+
"safe_urls": [],
|
| 17 |
+
"blocked_urls": [],
|
| 18 |
+
"conversation_origin": null,
|
| 19 |
+
"snippet": null
|
| 20 |
+
}
|