fix: use /api/chat endpoint for proper multi-turn conversations (issue #10)
- Replace /api/generate with /api/chat endpoint - Send messages as proper list with role/content structure - Preserve multi-turn semantics (system/user/assistant roles) - Compatible with OpenAI-compatible endpoints - Filter invalid message roles before sending
This commit is contained in:
parent
b25fb3c1c6
commit
3bb50c4925
@ -106,15 +106,18 @@ class APIClient:
|
||||
self, messages: list, model: str = None, **kwargs
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
Get a completion from the LLM using Ollama chat endpoint
|
||||
Get a completion from the LLM using Ollama chat endpoint.
|
||||
|
||||
Uses /api/chat with proper message list format to preserve
|
||||
multi-turn conversation semantics (system, user, assistant roles).
|
||||
|
||||
Args:
|
||||
messages (list): List of message dictionaries (roles and content)
|
||||
messages (list): List of message dictionaries with 'role' and 'content'
|
||||
model (str): Model to use
|
||||
**kwargs: Additional parameters for the API
|
||||
|
||||
Returns:
|
||||
dict: Response from the LLM
|
||||
dict: Response from the LLM in OpenAI-compatible format
|
||||
"""
|
||||
if model is None:
|
||||
# Reload config to get latest model setting
|
||||
@ -123,40 +126,53 @@ class APIClient:
|
||||
current_config = load_config()
|
||||
model = current_config.get("model", "qwen3-coder:30b")
|
||||
|
||||
# Convert messages to prompt format expected by Ollama generate endpoint
|
||||
prompt_text = ""
|
||||
# Filter messages to only include valid roles for chat endpoint
|
||||
chat_messages = []
|
||||
for message in messages:
|
||||
role = message.get("role", "user")
|
||||
content = message.get("content", "")
|
||||
if role in ("system", "user", "assistant"):
|
||||
chat_messages.append({"role": role, "content": content})
|
||||
|
||||
# Format messages properly for the model
|
||||
if role == "system":
|
||||
prompt_text += f"System: {content}\n\n"
|
||||
elif role == "assistant":
|
||||
prompt_text += f"Assistant: {content}\n\n"
|
||||
else: # user
|
||||
prompt_text += f"User: {content}\n\n"
|
||||
if not chat_messages:
|
||||
return {"error": "No valid messages provided for chat completion"}
|
||||
|
||||
# Add instruction for assistant response
|
||||
prompt_text += "Assistant:"
|
||||
# Use Ollama chat endpoint with proper message format
|
||||
data = {
|
||||
"model": model,
|
||||
"messages": chat_messages,
|
||||
"stream": False,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
# Prepare the data for Ollama generate endpoint
|
||||
data = {"model": model, "prompt": prompt_text, "stream": False, **kwargs}
|
||||
|
||||
result = self._make_request("/api/generate", "POST", data)
|
||||
result = self._make_request("/api/chat", "POST", data)
|
||||
if not result["success"]:
|
||||
return {"error": result["error"]}
|
||||
|
||||
# Extract the response from Ollama's generate format
|
||||
# Extract the response from Ollama's chat format
|
||||
try:
|
||||
response_data = result["data"]
|
||||
# In Ollama generate responses, the actual text is in the "response" field
|
||||
if "response" in response_data:
|
||||
# Ollama chat endpoint returns message in message.content
|
||||
if "message" in response_data:
|
||||
return {
|
||||
"choices": [
|
||||
{
|
||||
"message": {
|
||||
"role": response_data["message"].get(
|
||||
"role", "assistant"
|
||||
),
|
||||
"content": response_data["message"].get(
|
||||
"content", ""
|
||||
),
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
elif "response" in response_data:
|
||||
return {
|
||||
"choices": [{"message": {"content": response_data["response"]}}]
|
||||
}
|
||||
else:
|
||||
# If we get a different format, return what we found
|
||||
return response_data
|
||||
except Exception as e:
|
||||
return {"error": f"Failed to process chat completion result: {str(e)}"}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user