v0.0.13 Ability to Clone Sessions (#77)
* feat(storage) Add a route to clone sessions * fix(storage) Add additional test case and fix case conventions for query parameters in clone method * fix(storage) make case conventions consistent and documentation updates * fix(docs) Update docs with newest routes * fix(storage) Add commit to clone method
This commit is contained in:
parent
05a57cffbd
commit
17ff3804ec
|
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.0.13] — 2024-11-07
|
||||
|
||||
### Added
|
||||
|
||||
- Ability to clone session for a user to achieve more [loom-like](https://github.com/socketteer/loom/) behavior
|
||||
|
||||
## [0.0.12] — 2024-10-21
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 🫡 Honcho
|
||||
|
||||

|
||||

|
||||
[](https://discord.gg/plasticlabs)
|
||||
[](https://arxiv.org/abs/2310.06983)
|
||||

|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /v1/apps/{app_id}/users/{user_id}/sessions/{session_id}/clone
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /v1/apps/{app_id}/users/{user_id}/sessions/{session_id}/chat/stream
|
||||
---
|
||||
|
|
@ -109,7 +109,8 @@
|
|||
"api-reference/endpoint/sessions/update-session",
|
||||
"api-reference/endpoint/sessions/delete-session",
|
||||
"api-reference/endpoint/sessions/chat",
|
||||
"api-reference/endpoint/sessions/chat-stream"
|
||||
"api-reference/endpoint/sessions/chat-stream",
|
||||
"api-reference/endpoint/sessions/clone-session"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -159,7 +160,7 @@
|
|||
"github": "https://github.com/plastic-labs",
|
||||
"linkedin": "https://www.linkedin.com/company/plasticlabs"
|
||||
},
|
||||
"openapi": ["/openapi.json"],
|
||||
"openapi": ["/openapi.yml"],
|
||||
"analytics": {
|
||||
"posthog": {
|
||||
"apiKey": "phc_1yrzzcgywqXGcerkkI4g7C0YfyPMcAKNOOvGcjTCiUk"
|
||||
|
|
|
|||
3235
docs/openapi.json
3235
docs/openapi.json
File diff suppressed because it is too large
Load Diff
4358
docs/openapi.json]
4358
docs/openapi.json]
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -5,7 +5,7 @@
|
|||
"main": ".pnp.js",
|
||||
"scripts": {
|
||||
"dev": "mintlify dev",
|
||||
"openapi": "npx @mintlify/scraping openapi-file openapi.json -o api-reference/endpoint",
|
||||
"openapi": "npx @mintlify/scraping openapi-file openapi.yml -o api-reference/endpoint",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[project]
|
||||
name = "honcho"
|
||||
version = "0.0.12"
|
||||
version = "0.0.13"
|
||||
description = "Honcho Server"
|
||||
authors = [
|
||||
{name = "Plastic Labs", email = "hello@plasticlabs.ai"},
|
||||
|
|
|
|||
123
src/crud.py
123
src/crud.py
|
|
@ -4,9 +4,10 @@ from typing import Optional
|
|||
|
||||
from dotenv import load_dotenv
|
||||
from openai import OpenAI
|
||||
from sqlalchemy import Select, select
|
||||
from sqlalchemy import Select, cast, insert, select
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.types import BigInteger
|
||||
|
||||
from . import models, schemas
|
||||
|
||||
|
|
@ -269,6 +270,126 @@ async def delete_session(
|
|||
return True
|
||||
|
||||
|
||||
async def clone_session(
|
||||
db: AsyncSession,
|
||||
app_id: str,
|
||||
user_id: str,
|
||||
original_session_id: str,
|
||||
cutoff_message_id: Optional[str] = None,
|
||||
deep_copy: bool = True,
|
||||
) -> models.Session:
|
||||
"""
|
||||
Clone a session and its messages. If cutoff_message_id is provided,
|
||||
only clone messages up to and including that message.
|
||||
|
||||
Args:
|
||||
db: SQLAlchemy session
|
||||
app_id: ID of the app the target session is in
|
||||
user_id: ID of the user the target session belongs to
|
||||
original_session_id: ID of the session to clone
|
||||
cutoff_message_id: Optional ID of the last message to include in the clone
|
||||
|
||||
Returns:
|
||||
The newly created session
|
||||
"""
|
||||
# Get the original session
|
||||
stmt = (
|
||||
select(models.Session)
|
||||
.join(models.User, models.User.public_id == models.Session.user_id)
|
||||
.where(models.Session.public_id == original_session_id)
|
||||
.where(models.Session.user_id == user_id)
|
||||
.where(models.User.app_id == app_id)
|
||||
)
|
||||
original_session = await db.scalar(stmt)
|
||||
if not original_session:
|
||||
raise ValueError("Original session not found")
|
||||
|
||||
# If cutoff_message_id is provided, verify it belongs to the session
|
||||
cutoff_message = None
|
||||
if cutoff_message_id is not None:
|
||||
stmt = select(models.Message).where(
|
||||
models.Message.public_id == cutoff_message_id,
|
||||
models.Message.session_id == original_session_id,
|
||||
)
|
||||
cutoff_message = await db.scalar(stmt)
|
||||
if not cutoff_message:
|
||||
raise ValueError(
|
||||
"Message not found or doesn't belong to the specified session"
|
||||
)
|
||||
|
||||
# Create new session
|
||||
new_session = models.Session(
|
||||
user_id=original_session.user_id,
|
||||
h_metadata=original_session.h_metadata,
|
||||
)
|
||||
db.add(new_session)
|
||||
await db.flush() # Flush to get the new session ID
|
||||
|
||||
# Build query for messages to clone
|
||||
stmt = select(models.Message).where(
|
||||
models.Message.session_id == original_session_id
|
||||
)
|
||||
if cutoff_message_id is not None and cutoff_message is not None:
|
||||
stmt = stmt.where(models.Message.id <= cast(cutoff_message.id, BigInteger))
|
||||
stmt = stmt.order_by(models.Message.id)
|
||||
|
||||
# Fetch messages to clone
|
||||
messages_to_clone_scalars = await db.scalars(stmt)
|
||||
messages_to_clone = messages_to_clone_scalars.all()
|
||||
|
||||
if not messages_to_clone:
|
||||
return new_session
|
||||
|
||||
# Prepare bulk insert data
|
||||
new_messages = [
|
||||
{
|
||||
"session_id": new_session.public_id,
|
||||
"content": message.content,
|
||||
"is_user": message.is_user,
|
||||
"h_metadata": message.h_metadata,
|
||||
}
|
||||
for message in messages_to_clone
|
||||
]
|
||||
|
||||
stmt = insert(models.Message).returning(models.Message.public_id)
|
||||
result = await db.execute(stmt, new_messages)
|
||||
new_message_ids = result.scalars().all()
|
||||
|
||||
# Create mapping of old to new message IDs
|
||||
message_id_map = dict(
|
||||
zip([message.public_id for message in messages_to_clone], new_message_ids)
|
||||
)
|
||||
|
||||
# Handle metamessages if deep copy is requested
|
||||
if deep_copy and message_id_map:
|
||||
# Fetch all metamessages in a single query
|
||||
stmt = select(models.Metamessage).where(
|
||||
models.Metamessage.message_id.in_(message_id_map.keys())
|
||||
)
|
||||
metamessages_result = await db.scalars(stmt)
|
||||
metamessages = metamessages_result.all()
|
||||
|
||||
if metamessages:
|
||||
# Prepare bulk insert data for metamessages
|
||||
new_metamessages = [
|
||||
{
|
||||
"message_id": message_id_map[meta.message_id],
|
||||
"metamessage_type": meta.metamessage_type,
|
||||
"content": meta.content,
|
||||
"h_metadata": meta.h_metadata,
|
||||
}
|
||||
for meta in metamessages
|
||||
]
|
||||
|
||||
# Bulk insert metamessages using modern insert syntax
|
||||
stmt = insert(models.Metamessage)
|
||||
await db.execute(stmt, new_metamessages)
|
||||
|
||||
await db.commit()
|
||||
|
||||
return new_session
|
||||
|
||||
|
||||
########################################################
|
||||
# Message Methods
|
||||
########################################################
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ app = FastAPI(
|
|||
summary="An API for adding personalization to AI Apps",
|
||||
description="""This API is used to store data and get insights about users for AI
|
||||
applications""",
|
||||
version="0.0.12",
|
||||
version="0.0.13",
|
||||
contact={
|
||||
"name": "Plastic Labs",
|
||||
"url": "https://plasticlabs.ai",
|
||||
|
|
|
|||
|
|
@ -215,3 +215,22 @@ async def get_chat_stream(
|
|||
return StreamingResponse(
|
||||
content=parse_stream(), media_type="text/event-stream", status_code=200
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{session_id}/clone", response_model=schemas.Session)
|
||||
async def clone_session(
|
||||
app_id: str,
|
||||
user_id: str,
|
||||
session_id: str,
|
||||
db=db,
|
||||
message_id: Optional[str] = None,
|
||||
deep_copy: bool = False,
|
||||
):
|
||||
return await crud.clone_session(
|
||||
db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
original_session_id=session_id,
|
||||
cutoff_message_id=message_id,
|
||||
deep_copy=deep_copy,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -80,25 +80,25 @@ async def test_get_metamessages(client, db_session, sample_data):
|
|||
test_metamessage_1 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_2 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_3 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_4 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type_2",
|
||||
)
|
||||
db_session.add(test_metamessage_1)
|
||||
|
|
@ -153,25 +153,25 @@ async def test_get_metamessage_by_user(client, db_session, sample_data):
|
|||
test_metamessage_1 = models.Metamessage(
|
||||
message_id=test_message_1.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_2 = models.Metamessage(
|
||||
message_id=test_message_2.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_3 = models.Metamessage(
|
||||
message_id=test_message_3.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_4 = models.Metamessage(
|
||||
message_id=test_message_3.public_id,
|
||||
content="Test Metamessage",
|
||||
metadata={},
|
||||
h_metadata={},
|
||||
metamessage_type="test_type_2",
|
||||
)
|
||||
db_session.add(test_metamessage_1)
|
||||
|
|
@ -186,9 +186,6 @@ async def test_get_metamessage_by_user(client, db_session, sample_data):
|
|||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
print("=======")
|
||||
print(data)
|
||||
print("=======")
|
||||
assert len(data["items"]) > 0
|
||||
assert len(data["items"]) == 3
|
||||
assert data["items"][0]["content"] == "Test Metamessage"
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ async def test_get_sessions(client, db_session, sample_data):
|
|||
async def test_empty_update_session(client, db_session, sample_data):
|
||||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(user_id=test_user.public_id, metadata={})
|
||||
test_session = models.Session(user_id=test_user.public_id, h_metadata={})
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ async def test_update_delete_metadata(client, db_session, sample_data):
|
|||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(
|
||||
user_id=test_user.public_id, metadata={"default": "value"}
|
||||
user_id=test_user.public_id, h_metadata={"default": "value"}
|
||||
)
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
|
|
@ -93,7 +93,7 @@ async def test_update_delete_metadata(client, db_session, sample_data):
|
|||
async def test_update_session(client, db_session, sample_data):
|
||||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(user_id=test_user.public_id, metadata={})
|
||||
test_session = models.Session(user_id=test_user.public_id, h_metadata={})
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ async def test_update_session(client, db_session, sample_data):
|
|||
async def test_delete_session(client, db_session, sample_data):
|
||||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(user_id=test_user.public_id, metadata={})
|
||||
test_session = models.Session(user_id=test_user.public_id, h_metadata={})
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
response = client.delete(
|
||||
|
|
@ -122,3 +122,324 @@ async def test_delete_session(client, db_session, sample_data):
|
|||
)
|
||||
data = response.json()
|
||||
assert data["is_active"] is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_clone_session(client, db_session, sample_data):
|
||||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(
|
||||
user_id=test_user.public_id, h_metadata={"test": "key"}
|
||||
)
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
|
||||
test_message = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value"},
|
||||
)
|
||||
test_message2 = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message 2",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value2"},
|
||||
)
|
||||
db_session.add(test_message)
|
||||
db_session.add(test_message2)
|
||||
await db_session.commit()
|
||||
|
||||
response = client.get(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{test_session.public_id}/clone",
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["metadata"] == {"test": "key"}
|
||||
|
||||
print(data)
|
||||
|
||||
response = client.post(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{data['id']}/messages/list",
|
||||
json={},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "items" in data
|
||||
assert len(data["items"]) > 0
|
||||
assert len(data["items"]) == 2
|
||||
|
||||
assert data["items"][0]["content"] == "Test message"
|
||||
assert data["items"][0]["is_user"] is True
|
||||
assert data["items"][0]["metadata"] == {"key": "value"}
|
||||
|
||||
assert data["items"][1]["content"] == "Test message 2"
|
||||
assert data["items"][1]["is_user"] is True
|
||||
assert data["items"][1]["metadata"] == {"key": "value2"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_partial_clone_session(client, db_session, sample_data):
|
||||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(
|
||||
user_id=test_user.public_id, h_metadata={"test": "key"}
|
||||
)
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
|
||||
test_message = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value"},
|
||||
)
|
||||
test_message2 = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message 2",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value2"},
|
||||
)
|
||||
|
||||
test_message3 = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message 2",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value2"},
|
||||
)
|
||||
|
||||
db_session.add(test_message)
|
||||
db_session.add(test_message2)
|
||||
db_session.add(test_message3)
|
||||
await db_session.commit()
|
||||
|
||||
response = client.get(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{test_session.public_id}/clone?message_id={test_message2.public_id}",
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["metadata"] == {"test": "key"}
|
||||
|
||||
response = client.post(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{data['id']}/messages/list",
|
||||
json={},
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
assert len(data["items"]) > 0
|
||||
assert len(data["items"]) == 2
|
||||
|
||||
assert data["items"][0]["content"] == "Test message"
|
||||
assert data["items"][0]["is_user"] is True
|
||||
assert data["items"][0]["metadata"] == {"key": "value"}
|
||||
|
||||
assert data["items"][1]["content"] == "Test message 2"
|
||||
assert data["items"][1]["is_user"] is True
|
||||
assert data["items"][1]["metadata"] == {"key": "value2"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_deep_clone_session(client, db_session, sample_data):
|
||||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(
|
||||
user_id=test_user.public_id, h_metadata={"test": "key"}
|
||||
)
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
|
||||
test_message = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value"},
|
||||
)
|
||||
test_message2 = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message 2",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value2"},
|
||||
)
|
||||
db_session.add(test_message)
|
||||
db_session.add(test_message2)
|
||||
await db_session.commit()
|
||||
|
||||
test_metamessage_1 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage 1",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_2 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage 2",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_3 = models.Metamessage(
|
||||
message_id=test_message2.public_id,
|
||||
content="Test Metamessage 3",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_4 = models.Metamessage(
|
||||
message_id=test_message2.public_id,
|
||||
content="Test Metamessage 4",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type_2",
|
||||
)
|
||||
|
||||
db_session.add(test_metamessage_1)
|
||||
db_session.add(test_metamessage_2)
|
||||
db_session.add(test_metamessage_3)
|
||||
db_session.add(test_metamessage_4)
|
||||
await db_session.commit()
|
||||
|
||||
response = client.get(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{test_session.public_id}/clone?deep_copy=true",
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["metadata"] == {"test": "key"}
|
||||
|
||||
cloned_session_id = data["id"]
|
||||
|
||||
response = client.post(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{cloned_session_id}/messages/list",
|
||||
json={},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "items" in data
|
||||
assert len(data["items"]) > 0
|
||||
assert len(data["items"]) == 2
|
||||
|
||||
assert data["items"][0]["content"] == "Test message"
|
||||
assert data["items"][0]["is_user"] is True
|
||||
assert data["items"][0]["metadata"] == {"key": "value"}
|
||||
|
||||
assert data["items"][1]["content"] == "Test message 2"
|
||||
assert data["items"][1]["is_user"] is True
|
||||
assert data["items"][1]["metadata"] == {"key": "value2"}
|
||||
|
||||
response = client.post(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{cloned_session_id}/metamessages/list",
|
||||
json={},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert len(data["items"]) > 0
|
||||
assert len(data["items"]) == 4
|
||||
assert data["items"][0]["content"] == "Test Metamessage 1"
|
||||
assert data["items"][0]["metamessage_type"] == "test_type"
|
||||
assert data["items"][0]["metadata"] == {}
|
||||
assert data["items"][1]["content"] == "Test Metamessage 2"
|
||||
assert data["items"][1]["metamessage_type"] == "test_type"
|
||||
assert data["items"][1]["metadata"] == {}
|
||||
assert data["items"][2]["content"] == "Test Metamessage 3"
|
||||
assert data["items"][2]["metamessage_type"] == "test_type"
|
||||
assert data["items"][2]["metadata"] == {}
|
||||
assert data["items"][3]["content"] == "Test Metamessage 4"
|
||||
assert data["items"][3]["metamessage_type"] == "test_type_2"
|
||||
assert data["items"][3]["metadata"] == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_partial_deep_clone_session(client, db_session, sample_data):
|
||||
test_app, test_user = sample_data
|
||||
# Create a test session
|
||||
test_session = models.Session(
|
||||
user_id=test_user.public_id, h_metadata={"test": "key"}
|
||||
)
|
||||
db_session.add(test_session)
|
||||
await db_session.commit()
|
||||
|
||||
test_message = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value"},
|
||||
)
|
||||
test_message2 = models.Message(
|
||||
session_id=test_session.public_id,
|
||||
content="Test message 2",
|
||||
is_user=True,
|
||||
h_metadata={"key": "value2"},
|
||||
)
|
||||
db_session.add(test_message)
|
||||
db_session.add(test_message2)
|
||||
await db_session.commit()
|
||||
|
||||
test_metamessage_1 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage 1",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_2 = models.Metamessage(
|
||||
message_id=test_message.public_id,
|
||||
content="Test Metamessage 2",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_3 = models.Metamessage(
|
||||
message_id=test_message2.public_id,
|
||||
content="Test Metamessage 3",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type",
|
||||
)
|
||||
test_metamessage_4 = models.Metamessage(
|
||||
message_id=test_message2.public_id,
|
||||
content="Test Metamessage 4",
|
||||
h_metadata={},
|
||||
metamessage_type="test_type_2",
|
||||
)
|
||||
|
||||
db_session.add(test_metamessage_1)
|
||||
db_session.add(test_metamessage_2)
|
||||
db_session.add(test_metamessage_3)
|
||||
db_session.add(test_metamessage_4)
|
||||
await db_session.commit()
|
||||
|
||||
response = client.get(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{test_session.public_id}/clone?deep_copy=true&message_id={test_message.public_id}",
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["metadata"] == {"test": "key"}
|
||||
|
||||
cloned_session_id = data["id"]
|
||||
|
||||
response = client.post(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{cloned_session_id}/messages/list",
|
||||
json={},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "items" in data
|
||||
assert len(data["items"]) > 0
|
||||
assert len(data["items"]) == 1
|
||||
|
||||
assert data["items"][0]["content"] == "Test message"
|
||||
assert data["items"][0]["is_user"] is True
|
||||
assert data["items"][0]["metadata"] == {"key": "value"}
|
||||
|
||||
response = client.post(
|
||||
f"/v1/apps/{test_app.public_id}/users/{test_user.public_id}/sessions/{cloned_session_id}/metamessages/list",
|
||||
json={},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert len(data["items"]) > 0
|
||||
assert len(data["items"]) == 2
|
||||
assert data["items"][0]["content"] == "Test Metamessage 1"
|
||||
assert data["items"][0]["metamessage_type"] == "test_type"
|
||||
assert data["items"][0]["metadata"] == {}
|
||||
assert data["items"][1]["content"] == "Test Metamessage 2"
|
||||
assert data["items"][1]["metamessage_type"] == "test_type"
|
||||
assert data["items"][1]["metadata"] == {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue