Skip to content
This repository was archived by the owner on Nov 3, 2024. It is now read-only.

Commit c26b38a

Browse files
authored
[HN-137/HN-275] feat: added chat history and updated chat endpoint (#19)
1 parent 19370aa commit c26b38a

File tree

7 files changed

+203
-37
lines changed

7 files changed

+203
-37
lines changed

README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,22 @@ To use the `HiveAgentClient` library, you first need to ensure that you have Pyt
1212
1. **Install Poetry**
1313

1414
If you don't have Poetry installed, you can install it using the following commands:
15-
`$ curl -sSL https://install.python-poetry.org | python3 -`
16-
`$ export PATH="$HOME/.local/bin:$PATH"`
15+
```sh
16+
$ curl -sSL https://install.python-poetry.org | python3 -
17+
$ export PATH="$HOME/.local/bin:$PATH"
18+
```
1719

1820
2. **Activate the Virtual Environment**
1921
Activate the virtual environment created by Poetry with the following command:
20-
`$ poetry shell`
22+
```sh
23+
$ poetry shell
24+
```
2125

2226
3. **Install Dependencies**
2327

24-
`$ poetry install --no-root`
25-
28+
```sh
29+
$ poetry install --no-root
30+
```
2631

2732
## Usage
2833

@@ -36,7 +41,7 @@ client = HiveAgentClient(base_url="http://localhost:8000", timeout=30)
3641
3742
# send a message and receive the response
3843
try:
39-
response = client.chat("Hello, Hive Agent!")
44+
response = await client.chat(user_id="user123", session_id="session123", content="Hello, Hive Agent!")
4045
print(response)
4146
except Exception as e:
4247
print(f"an error occurred: {e}")

hive_agent_client/chat/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .chat import send_chat_message
1+
from .chat import send_chat_message, get_chat_history

hive_agent_client/chat/chat.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import logging
33
import os
44
import sys
5+
from typing import List, Dict
56

67

78
def get_log_level():
@@ -17,13 +18,15 @@ def get_log_level():
1718

1819

1920
async def send_chat_message(
20-
http_client: httpx.AsyncClient, base_url: str, content: str
21+
http_client: httpx.AsyncClient, base_url: str, user_id: str, session_id: str, content: str
2122
) -> str:
2223
"""
2324
Sends a chat message to the Hive Agent API and returns the response.
2425
2526
:param http_client: An instance of httpx.AsyncClient to make HTTP requests.
2627
:param base_url: The base URL of the Hive Agent API.
28+
:param user_id: The user ID.
29+
:param session_id: The session ID.
2730
:param content: The content of the message to be sent.
2831
:return: The response text from the API.
2932
:raises ValueError: If the content is empty.
@@ -35,7 +38,11 @@ async def send_chat_message(
3538

3639
endpoint = "/chat"
3740
url = f"{base_url}{endpoint}"
38-
payload = {"messages": [{"role": "user", "content": content}]}
41+
payload = {
42+
"user_id": user_id,
43+
"session_id": session_id,
44+
"chat_data": {"messages": [{"role": "user", "content": content}]}
45+
}
3946

4047
try:
4148
logging.debug(f"Sending chat message to {url}: {content}")
@@ -62,3 +69,49 @@ async def send_chat_message(
6269
raise Exception(
6370
f"An unexpected error occurred when sending message to the chat API: {e}"
6471
)
72+
73+
74+
async def get_chat_history(
75+
http_client: httpx.AsyncClient, base_url: str, user_id: str, session_id: str
76+
) -> List[Dict]:
77+
"""
78+
Retrieves the chat history from the Hive Agent API.
79+
80+
:param http_client: An instance of httpx.AsyncClient to make HTTP requests.
81+
:param base_url: The base URL of the Hive Agent API.
82+
:param user_id: The user ID.
83+
:param session_id: The session ID.
84+
:return: The chat history as a list of dictionaries.
85+
:raises httpx.HTTPStatusError: If the request fails due to a network error or returns a 4xx/5xx response.
86+
:raises Exception: For other types of errors.
87+
"""
88+
endpoint = "/chat_history"
89+
url = f"{base_url}{endpoint}"
90+
params = {"user_id": user_id, "session_id": session_id}
91+
92+
try:
93+
logging.debug(f"Fetching chat history from {url} with params: {params}")
94+
response = await http_client.get(url, params=params)
95+
response.raise_for_status()
96+
chat_history = response.json()
97+
logger.debug(f"Chat history for user {user_id} and session {session_id}: {chat_history}")
98+
return chat_history
99+
except httpx.HTTPStatusError as e:
100+
logging.error(
101+
f"HTTP error occurred when fetching chat history from {url}: {e.response.status_code} - {e.response.text}"
102+
)
103+
raise Exception(
104+
f"HTTP error occurred when fetching chat history from the chat API: {e.response.status_code} - {e.response.text}"
105+
)
106+
except httpx.RequestError as e:
107+
logging.error(f"Request error occurred when fetching chat history from {url}: {e}")
108+
raise Exception(
109+
f"Request error occurred when fetching chat history from the chat API: {e}"
110+
)
111+
except Exception as e:
112+
logging.error(
113+
f"An unexpected error occurred when fetching chat history from {url}: {e}"
114+
)
115+
raise Exception(
116+
f"An unexpected error occurred when fetching chat history from the chat API: {e}"
117+
)

hive_agent_client/client.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
from typing import Dict, List
44

5-
from hive_agent_client.chat import send_chat_message
5+
from hive_agent_client.chat import send_chat_message, get_chat_history
66
from hive_agent_client.database import (
77
create_table,
88
insert_data,
@@ -34,20 +34,36 @@ def __init__(self, base_url: str, version: str = "v1"):
3434
self.base_url = f"{base_url}/{version}"
3535
self.http_client = httpx.AsyncClient()
3636

37-
async def chat(self, content: str) -> str:
37+
async def chat(self, user_id: str, session_id: str, content: str) -> str:
3838
"""
3939
Send a message to the chat endpoint.
4040
41+
:param user_id: The user ID.
42+
:param session_id: The session ID.
4143
:param content: The content of the message to send.
4244
:return: The response from the chat API as a string.
4345
"""
4446
try:
4547
logger.debug(f"Sending message to chat endpoint: {content}")
46-
return await send_chat_message(self.http_client, self.base_url, content)
48+
return await send_chat_message(self.http_client, self.base_url, user_id, session_id, content)
4749
except Exception as e:
4850
logger.error(f"Failed to send chat message - {content}: {e}")
4951
raise Exception(f"Failed to send chat message: {e}")
5052

53+
async def get_chat_history(self, user_id: str, session_id: str) -> List[Dict]:
54+
"""
55+
Retrieve the chat history for a specified user and session.
56+
57+
:param user_id: The user ID.
58+
:param session_id: The session ID.
59+
:return: The chat history as a list of dictionaries.
60+
"""
61+
try:
62+
return await get_chat_history(self.http_client, self.base_url, user_id, session_id)
63+
except Exception as e:
64+
logger.error(f"Failed to get chat history for user {user_id} and session {session_id}: {e}")
65+
raise Exception(f"Failed to get chat history: {e}")
66+
5167
async def create_table(self, table_name: str, columns: dict) -> Dict:
5268
"""
5369
Create a new table in the database.

tests/chat/test_chat.py

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import httpx
22
import pytest
33

4-
54
from unittest.mock import AsyncMock
6-
from hive_agent_client.chat import send_chat_message
5+
from hive_agent_client.chat import send_chat_message, get_chat_history
76

87

98
@pytest.mark.asyncio
@@ -15,25 +14,33 @@ async def test_send_chat_message_success():
1514
mock_client.post.return_value = mock_response
1615

1716
base_url = "http://example.com/api/v1"
17+
user_id = "user123"
18+
session_id = "session123"
1819
content = "Hello, how are you?"
1920

20-
result = await send_chat_message(mock_client, base_url, content)
21+
result = await send_chat_message(mock_client, base_url, user_id, session_id, content)
2122

2223
assert result == "Hello, world!"
2324
mock_client.post.assert_called_once_with(
2425
"http://example.com/api/v1/chat",
25-
json={"messages": [{"role": "user", "content": content}]},
26+
json={
27+
"user_id": user_id,
28+
"session_id": session_id,
29+
"chat_data": {"messages": [{"role": "user", "content": content}]}
30+
},
2631
)
2732

2833

2934
@pytest.mark.asyncio
3035
async def test_send_chat_message_empty_content():
3136
mock_client = AsyncMock(spec=httpx.AsyncClient)
3237
base_url = "http://example.com"
38+
user_id = "user123"
39+
session_id = "session123"
3340
content = ""
3441

3542
with pytest.raises(ValueError, match="Content must not be empty"):
36-
await send_chat_message(mock_client, base_url, content)
43+
await send_chat_message(mock_client, base_url, user_id, session_id, content)
3744

3845

3946
@pytest.mark.asyncio
@@ -42,34 +49,67 @@ async def test_send_chat_message_http_error():
4249
mock_response = AsyncMock(spec=httpx.Response)
4350
mock_response.status_code = 400
4451
mock_response.text = "Bad request"
52+
mock_response.raise_for_status.side_effect = httpx.HTTPStatusError(
53+
message="Bad request", request=mock_response.request, response=mock_response
54+
)
4555
mock_client.post.return_value = mock_response
4656

4757
base_url = "http://example.com"
58+
user_id = "user123"
59+
session_id = "session123"
4860
content = "Hello, how are you?"
4961

5062
with pytest.raises(
51-
Exception,
52-
match="HTTP error occurred when sending message to the chat API: 400 - Bad request",
63+
Exception,
64+
match="HTTP error occurred when sending message to the chat API: 400 - Bad request",
5365
):
54-
await send_chat_message(mock_client, base_url, content)
66+
await send_chat_message(mock_client, base_url, user_id, session_id, content)
5567

5668

5769
@pytest.mark.asyncio
58-
async def test_send_chat_message_http_error():
70+
async def test_get_chat_history_success():
71+
mock_client = AsyncMock(spec=httpx.AsyncClient)
72+
mock_response = AsyncMock(spec=httpx.Response)
73+
mock_response.status_code = 200
74+
expected_history = [
75+
{"user_id": "user123", "session_id": "session123", "message": "Hello", "role": "user",
76+
"timestamp": "2023-01-01T00:00:00Z"},
77+
{"user_id": "user123", "session_id": "session123", "message": "Hi there", "role": "assistant",
78+
"timestamp": "2023-01-01T00:00:01Z"}
79+
]
80+
mock_response.json.return_value = expected_history
81+
mock_client.get.return_value = mock_response
82+
83+
base_url = "http://example.com/api/v1"
84+
user_id = "user123"
85+
session_id = "session123"
86+
87+
result = await get_chat_history(mock_client, base_url, user_id, session_id)
88+
89+
assert result == expected_history
90+
mock_client.get.assert_called_once_with(
91+
f"http://example.com/api/v1/chat_history",
92+
params={"user_id": user_id, "session_id": session_id},
93+
)
94+
95+
96+
@pytest.mark.asyncio
97+
async def test_get_chat_history_failure():
5998
mock_client = AsyncMock(spec=httpx.AsyncClient)
6099
mock_response = AsyncMock(spec=httpx.Response)
61100
mock_response.status_code = 400
62101
mock_response.text = "Bad request"
63102
mock_response.raise_for_status.side_effect = httpx.HTTPStatusError(
64103
message="Bad request", request=mock_response.request, response=mock_response
65104
)
66-
mock_client.post.return_value = mock_response
105+
mock_client.get.return_value = mock_response
67106

68-
base_url = "http://example.com"
69-
content = "Hello, how are you?"
107+
base_url = "http://example.com/api/v1"
108+
user_id = "user123"
109+
session_id = "session123"
70110

71111
with pytest.raises(
72-
Exception,
73-
match="HTTP error occurred when sending message to the chat API: 400 - Bad request",
112+
Exception,
113+
match="HTTP error occurred when fetching chat history from the chat API: 400 - Bad request",
74114
):
75-
await send_chat_message(mock_client, base_url, content)
115+
await get_chat_history(mock_client, base_url, user_id, session_id)

tests/test_client.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def temp_files():
3030

3131
@pytest.mark.asyncio
3232
async def test_chat_success():
33+
user_id = "user123"
34+
session_id = "session123"
3335
content = "Hello"
3436
expected_response = "Response from chat"
3537

@@ -39,23 +41,58 @@ async def test_chat_success():
3941
)
4042

4143
client = HiveAgentClient(base_url, version)
42-
response = await client.chat(content)
44+
response = await client.chat(user_id, session_id, content)
4345
assert response == expected_response
4446

4547

4648
@pytest.mark.asyncio
4749
async def test_chat_failure():
50+
user_id = "user123"
51+
session_id = "session123"
4852
content = "Hello"
4953

5054
with respx.mock() as mock:
5155
mock.post(f"{base_url}/v1/chat").mock(return_value=httpx.Response(400))
5256

53-
client = HiveAgentClient(base_url)
57+
client = HiveAgentClient(base_url, version)
5458
with pytest.raises(Exception) as excinfo:
55-
await client.chat(content)
59+
await client.chat(user_id, session_id, content)
5660
assert "Failed to send chat message" in str(excinfo.value)
5761

5862

63+
@pytest.mark.asyncio
64+
async def test_get_chat_history_success():
65+
user_id = "user123"
66+
session_id = "session123"
67+
expected_history = [
68+
{"user_id": user_id, "session_id": session_id, "message": "Hello", "role": "user", "timestamp": "2023-01-01T00:00:00Z"},
69+
{"user_id": user_id, "session_id": session_id, "message": "Hi there", "role": "assistant", "timestamp": "2023-01-01T00:00:01Z"}
70+
]
71+
72+
with respx.mock() as mock:
73+
mock.get(f"{base_url}/v1/chat_history").mock(
74+
return_value=httpx.Response(200, json=expected_history)
75+
)
76+
77+
client = HiveAgentClient(base_url, version)
78+
history = await client.get_chat_history(user_id, session_id)
79+
assert history == expected_history
80+
81+
82+
@pytest.mark.asyncio
83+
async def test_get_chat_history_failure():
84+
user_id = "user123"
85+
session_id = "session123"
86+
87+
with respx.mock() as mock:
88+
mock.get(f"{base_url}/v1/chat_history").mock(return_value=httpx.Response(400))
89+
90+
client = HiveAgentClient(base_url, version)
91+
with pytest.raises(Exception) as excinfo:
92+
await client.get_chat_history(user_id, session_id)
93+
assert "HTTP error occurred when fetching chat history from the chat API: 400" in str(excinfo.value)
94+
95+
5996
@pytest.mark.asyncio
6097
async def test_create_table_success():
6198
table_name = "test_table"

0 commit comments

Comments
 (0)