Skip to content

Commit 5ba44d6

Browse files
committed
Merge remote-tracking branch 'upstream/dev' into dev
2 parents 198aade + f714027 commit 5ba44d6

File tree

79 files changed

+7399
-1742
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+7399
-1742
lines changed

docker/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,4 @@ websockets==15.0.1
159159
xlrd==2.0.2
160160
xlsxwriter==3.2.5
161161
prometheus-client==0.23.1
162+
pymilvus==2.5.12

examples/api/product_api.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,23 @@ def chat_stream(query: str, session_id: str, history: list | None = None):
119119
print(payload)
120120

121121

122+
def feedback_memory(feedback_content: str, history: list | None = None):
123+
url = f"{BASE_URL}/feedback"
124+
data = {
125+
"user_id": USER_ID,
126+
"writable_cube_ids": [MEM_CUBE_ID],
127+
"history": history,
128+
"feedback_content": feedback_content,
129+
"async_mode": "sync",
130+
"corrected_answer": "false",
131+
}
132+
133+
print("[*] Feedbacking memory ...")
134+
resp = requests.post(url, headers=HEADERS, data=json.dumps(data), timeout=30)
135+
print(resp.status_code, resp.text)
136+
return resp.json()
137+
138+
122139
if __name__ == "__main__":
123140
print("===== STEP 1: Register User =====")
124141
register_user()
@@ -140,5 +157,14 @@ def chat_stream(query: str, session_id: str, history: list | None = None):
140157
],
141158
)
142159

143-
print("\n===== STEP 4: Stream Chat =====")
160+
print("\n===== STEP 5: Stream Chat =====")
144161
chat_stream("我刚和你说什么了呢", SESSION_ID2, history=[])
162+
163+
print("\n===== STEP 6: Feedback Memory =====")
164+
feedback_memory(
165+
feedback_content="错啦,我今天没有吃拉面",
166+
history=[
167+
{"role": "user", "content": "我刚和你说什么了呢"},
168+
{"role": "assistant", "content": "你今天吃了好吃的拉面"},
169+
],
170+
)

examples/api/server_router_api.py

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,91 @@ def example_03_assistant_with_tool_calls():
181181

182182
# ===========================================================================
183183
# 4. MultiModel messages
184+
def example_03b_tool_message_with_result():
185+
"""
186+
Tool message returning the result of a tool call.
187+
188+
- `role = tool`, `content` contains the tool execution result.
189+
- `tool_call_id` links this message to the original tool call.
190+
- This is the standard format for tool execution results in OpenAI-style conversations.
191+
"""
192+
payload = {
193+
"user_id": USER_ID,
194+
"writable_cube_ids": [MEM_CUBE_ID],
195+
"messages": [
196+
{
197+
"role": "assistant",
198+
"content": None,
199+
"tool_calls": [
200+
{
201+
"id": "tool-call-weather-1",
202+
"type": "function",
203+
"function": {
204+
"name": "get_weather",
205+
"arguments": '{"location": "北京"}',
206+
},
207+
}
208+
],
209+
"chat_time": "2025-11-24T10:12:00Z",
210+
"message_id": "assistant-with-call-1",
211+
},
212+
{
213+
"role": "tool",
214+
"content": "北京今天天气晴朗,温度25°C,湿度60%。",
215+
"tool_call_id": "tool-call-weather-1",
216+
"chat_time": "2025-11-24T10:12:05Z",
217+
"message_id": "tool-result-1",
218+
},
219+
],
220+
"info": {"source_type": "tool_execution"},
221+
}
222+
call_add_api("03b_tool_message_with_result", payload)
223+
224+
225+
def example_03c_tool_description_input_output():
226+
"""
227+
Custom tool message format: tool_description, tool_input, tool_output.
228+
229+
- This demonstrates the custom tool message format (not OpenAI standard).
230+
- `tool_description`: describes the tool/function definition.
231+
- `tool_input`: the input parameters for the tool call.
232+
- `tool_output`: the result/output from the tool execution.
233+
- These are alternative formats for representing tool interactions.
234+
"""
235+
payload = {
236+
"user_id": USER_ID,
237+
"writable_cube_ids": [MEM_CUBE_ID],
238+
"messages": [
239+
{
240+
"type": "tool_description",
241+
"name": "get_weather",
242+
"description": "获取指定地点的当前天气信息",
243+
"parameters": {
244+
"type": "object",
245+
"properties": {"location": {"type": "string", "description": "城市名称"}},
246+
"required": ["location"],
247+
},
248+
},
249+
{
250+
"type": "tool_input",
251+
"call_id": "call_123",
252+
"name": "get_weather",
253+
"argument": {"location": "北京"},
254+
},
255+
{
256+
"type": "tool_output",
257+
"call_id": "call_123",
258+
"name": "get_weather",
259+
"output": {"weather": "晴朗", "temperature": 25, "humidity": 60},
260+
},
261+
],
262+
"info": {"source_type": "custom_tool_format"},
263+
}
264+
call_add_api("03c_tool_description_input_output", payload)
265+
266+
267+
# ===========================================================================
268+
# 4. Multimodal messages
184269
# ===========================================================================
185270

186271

@@ -414,6 +499,56 @@ def example_09b_pure_file_input_by_file_data():
414499
call_add_api("09b_pure_file_input_by_file_data", payload)
415500

416501

502+
def example_09c_pure_file_input_by_oss_url():
503+
"""
504+
Pure file input item using file_data with OSS URL.
505+
506+
- Uses `file_data` with OSS URL (object storage service URL).
507+
- This format is used when files are stored in cloud storage (e.g., Alibaba Cloud OSS).
508+
- The file_data field accepts both base64-encoded content and OSS URLs.
509+
"""
510+
payload = {
511+
"user_id": USER_ID,
512+
"writable_cube_ids": [MEM_CUBE_ID],
513+
"messages": [
514+
{
515+
"type": "file",
516+
"file": {
517+
"file_data": "oss_url", # OSS URL instead of base64
518+
"filename": "document.pdf",
519+
},
520+
}
521+
],
522+
"info": {"source_type": "file_ingestion_oss"},
523+
}
524+
call_add_api("09c_pure_file_input_by_oss_url", payload)
525+
526+
527+
def example_09d_pure_image_input():
528+
"""
529+
Pure image input item without dialog context.
530+
531+
- This demonstrates adding an image as a standalone input item (not part of a conversation).
532+
- Uses the same format as pure text/file inputs, but with image_url type.
533+
- Useful for batch image ingestion or when images don't have associated dialog.
534+
"""
535+
payload = {
536+
"user_id": USER_ID,
537+
"writable_cube_ids": [MEM_CUBE_ID],
538+
"messages": [
539+
{
540+
"type": "image_url",
541+
"image_url": {
542+
"url": "https://example.com/standalone_image.jpg",
543+
"detail": "high",
544+
},
545+
}
546+
],
547+
"info": {"source_type": "image_ingestion"},
548+
}
549+
call_add_api("09d_pure_image_input", payload)
550+
551+
417552
def example_10_mixed_text_file_image():
418553
"""
419554
Mixed multimodal message: text + file + image in a single user message.
@@ -619,6 +754,96 @@ def example_16_feedback_add():
619754
call_add_api("16_feedback_add", payload)
620755

621756

757+
def example_17_family_travel_conversation():
758+
"""
759+
Multi-turn conversation example: family travel planning.
760+
761+
- Demonstrates a complete conversation with multiple user-assistant exchanges.
762+
- Shows how to add a full conversation history in a single request.
763+
- Uses async_mode for asynchronous processing.
764+
- This example shows a Chinese conversation about summer travel planning for families.
765+
"""
766+
payload = {
767+
"user_id": "memos_automated_testing",
768+
"writable_cube_ids": [MEM_CUBE_ID],
769+
"session_id": "0610",
770+
"async_mode": "async",
771+
"messages": [
772+
{
773+
"role": "user",
774+
"content": "我想暑假出去玩,你能帮我推荐下吗?",
775+
},
776+
{
777+
"role": "assistant",
778+
"content": "好的!是自己出行还是和家人朋友一起呢?",
779+
},
780+
{
781+
"role": "user",
782+
"content": "肯定要带孩子啊,我们家出门都是全家一起。",
783+
},
784+
{
785+
"role": "assistant",
786+
"content": "明白了,所以你们是父母带孩子一块儿旅行,对吗?",
787+
},
788+
{
789+
"role": "user",
790+
"content": "对,带上孩子和老人,一般都是全家行动。",
791+
},
792+
{
793+
"role": "assistant",
794+
"content": "收到,那我会帮你推荐适合家庭出游的目的地。",
795+
},
796+
],
797+
"custom_tags": [],
798+
"info": {
799+
"source_type": "chat",
800+
"conversation_id": "0610",
801+
},
802+
}
803+
call_add_api("17_family_travel_conversation", payload)
804+
805+
806+
def example_18_add_with_chat_history():
807+
"""
808+
Add memory with chat_history field.
809+
810+
- `chat_history` provides additional conversation context separate from `messages`.
811+
- This is useful when you want to add specific messages while providing broader context.
812+
- The chat_history helps the system understand the conversation flow better.
813+
"""
814+
payload = {
815+
"user_id": USER_ID,
816+
"writable_cube_ids": [MEM_CUBE_ID],
817+
"session_id": "session_with_history",
818+
"messages": [
819+
{
820+
"role": "user",
821+
"content": "我想了解一下这个产品的价格。",
822+
},
823+
{
824+
"role": "assistant",
825+
"content": "好的,我来为您查询价格信息。",
826+
},
827+
],
828+
"chat_history": [
829+
{
830+
"role": "system",
831+
"content": "You are a helpful product assistant.",
832+
},
833+
{
834+
"role": "user",
835+
"content": "你好,我想咨询产品信息。",
836+
},
837+
{
838+
"role": "assistant",
839+
"content": "您好!我很乐意为您提供产品信息。",
840+
},
841+
],
842+
"info": {"source_type": "chat_with_history"},
843+
}
844+
call_add_api("18_add_with_chat_history", payload)
845+
846+
622847
# ===========================================================================
623848
# Entry point
624849
# ===========================================================================
@@ -628,17 +853,23 @@ def example_16_feedback_add():
628853
example_01_string_message_minimal()
629854
example_02_standard_chat_triplet()
630855
example_03_assistant_with_tool_calls()
856+
example_03b_tool_message_with_result()
857+
example_03c_tool_description_input_output()
631858
example_04_extreme_multimodal_single_message()
632859
example_05_multimodal_text_and_image()
633860
example_06_multimodal_text_and_file()
634861
example_07_audio_only_message()
635862
example_08_pure_text_input_items()
636863
example_09_pure_file_input_by_file_id()
637864
example_09b_pure_file_input_by_file_data()
865+
example_09c_pure_file_input_by_oss_url()
866+
example_09d_pure_image_input()
638867
example_10_mixed_text_file_image()
639868
example_11_deprecated_memory_content_and_doc_path()
640869
example_12_async_default_pipeline()
641870
example_13_sync_fast_pipeline()
642871
example_14_sync_fine_pipeline()
643872
example_15_async_with_task_id()
644873
example_16_feedback_add()
874+
example_17_family_travel_conversation()
875+
example_18_add_with_chat_history()

0 commit comments

Comments
 (0)