feat: Add multi-turn conversation support and OpenResponses/Ollama providers#111
Conversation
Adds first-class conversation primitives for multi-turn workflows: - New types: `Message` (role + content) and `Role` enum (user/assistant/system/developer) - All text entrypoints now accept `messages=` parameter: * Namespace: `celeste.text.generate(...)`, `celeste.text.stream.generate(...)`, `celeste.text.sync.generate(...)` * Client: `create_client(modality="text", ...).generate(...)` and `.analyze(...)` - When `messages` are provided, they take precedence over `prompt` (which becomes optional) - Provider normalization handles different API formats: * Anthropic: system/developer messages lifted to top-level `system` * Google: system/developer messages lifted to `system_instruction`; assistant role becomes `model` * Chat-style providers: `messages=[...]` arrays (Cohere/Mistral/Groq/DeepSeek/Moonshot) * Responses-style providers: `input=[...]` arrays (OpenAI/xAI) - Foundation for agents and multi-step workflows requiring conversation state persistence Files changed: - Core types: `src/celeste/types.py` - Text IO: `src/celeste/modalities/text/io.py` - Text client: `src/celeste/modalities/text/client.py` - All 9 text provider clients updated - Namespace API: `src/celeste/namespaces/domains.py` - Public exports: `src/celeste/__init__.py`
Adds support for OpenAI Responses-compatible APIs and local model hosting: OpenResponses Provider: - New `Provider.OPENRESPONSES` implementing OpenAI Responses API surface - Compatible with `POST /v1/responses` endpoint + SSE parsing - Supports structured outputs via `output_schema` → `text.format = json_schema` - Normalizes usage fields to Celeste's unified usage model - Supports `base_url=` parameter for custom API gateways Ollama Provider: - New `Provider.OLLAMA` as a local wrapper over OpenResponses protocol - Default base URL: `http://localhost:11434` - Uses `NoAuth` authentication (no headers required) - Supports unregistered local models with parameter validation warnings Infrastructure: - Added `NoAuth` class for local providers that don't require authentication - Added `base_url=` plumbing on text APIs for targeting local gateways - Supports rapid local iteration with unregistered models Files added: - `src/celeste/providers/openresponses/` (full provider implementation) - `src/celeste/modalities/text/providers/openresponses/` (text modality client) - `src/celeste/providers/ollama/` (Ollama wrapper) - `src/celeste/modalities/text/providers/ollama/` (Ollama text client) Files modified: - `src/celeste/core.py` (Provider enums) - `src/celeste/auth.py` (NoAuth) - `src/celeste/client.py` (base_url support) - `src/celeste/modalities/text/models.py` (OLLAMA_MODELS) - Provider exports updated
- Fix variable name collision in anthropic client (content -> prompt_content) - Apply ruff formatting fixes to provider clients and namespace API
- Convert OllamaClient from alias to proper class inheriting OpenResponsesClient - Apply ruff formatting fixes to openresponses provider files
- Revert OllamaClient to simple alias (it's just a wrapper) - Update test to skip wrapper providers like ollama that re-export another provider's client - Wrapper providers don't need to match the template contract since they delegate to the wrapped provider
PR Review: Multi-turn Conversation Support and OpenResponses/Ollama ProvidersSummaryThis PR adds two significant features to Celeste v1:
The implementation is well-structured and follows the existing architecture patterns. Below is my detailed review. ✅ Strengths1. Clean Type System Design
2. Consistent API Surface
3. Provider-Specific Normalization
4. NoAuth Implementation
5. Test Infrastructure
🔍 Issues & ConcernsCRITICAL: Missing Test Coverage for Multi-turn ConversationsThe core feature of this PR—multi-turn conversation support—has no dedicated test coverage. I could not find:
Recommendation: Add comprehensive tests before merging: # Example test structure needed:
async def test_generate_with_messages():
messages = [
Message(role=Role.SYSTEM, content="You are a helpful assistant"),
Message(role=Role.USER, content="Hello"),
Message(role=Role.ASSISTANT, content="Hi there!"),
Message(role=Role.USER, content="How are you?")
]
result = await celeste.text.generate(messages=messages, model="gpt-4o")
assert result.content
async def test_anthropic_system_message_extraction():
# Verify system messages go to system parameter
async def test_google_role_mapping():
# Verify assistant -> model mapping
async def test_messages_precedence_over_prompt():
# Verify messages takes priority when both providedMEDIUM: Type Safety Concerns
MEDIUM: Documentation Gaps
LOW: Code Quality Observations
🛡️ Security Considerations✅ No security concerns identified:
🚀 Performance Considerations✅ No significant performance concerns:
Minor optimization opportunity:
📝 Recommendations SummaryBefore Merge (Critical):
Consider for Follow-up:
🎯 Overall AssessmentArchitecture: 9/10 - Clean design that fits well with existing patterns Recommendation: Request test coverage for multi-turn conversations before approving for merge. The implementation is sound, but without tests, we can't confidently validate:
The OpenResponses and Ollama provider additions look solid and follow the established patterns well. 📚 Testing Guideline ReferencePer
Great work on the architecture! Looking forward to seeing the test coverage added. |
PR Review: Multi-turn conversation support and OpenResponses/Ollama providersSummaryThis PR adds significant new capabilities to Celeste v1, introducing multi-turn conversation support via first-class Code Quality and Best Practices ✅Strengths:
Areas for Improvement:1. Message Validation (src/celeste/types.py:32-39)The class Message(BaseModel):
model_config = ConfigDict(extra="allow") # Is this needed?
role: Role
content: ContentRecommendation: Document why 2. Input Precedence Logic (src/celeste/namespaces/domains.py:190-192)The precedence of 3. Error Handling in OpenResponses (client.py:143-178)The content parsing has a fallback to empty string but no logging. Add logging when falling back to empty content to aid debugging. Potential Bugs or Issues 🔍Critical:None identified - The code appears solid. Medium Priority:1. Missing None Check in Message Handling (openresponses/client.py:145-146)If 2. Video Support Not ImplementedThe Low Priority:3. Test Template Exclusion (test_provider_api_templates.py:98)Ollama is excluded as a "wrapper provider" - consider adding a comment explaining the exclusion criteria. Performance Considerations ⚡Strengths:
Considerations:1. Default Base URL Repetition (ollama/client.py)The default base URL is repeated in three methods. Consider consolidating: base_url = base_url or DEFAULT_BASE_URL # Repeated 3 timesSecurity Concerns 🔒Strengths:
Considerations:1. Local Provider SecurityUsing Assessment: Overall security posture is good with proper credential handling. Test Coverage 📊Current State:
Gaps:1. Message Role ValidationNo tests for:
2. OpenResponses/Ollama Integration TestsMissing tests for:
3. Provider-Specific Message NormalizationThe PR mentions "Provider normalization handles different API formats" but no tests verify Anthropic/Google system message handling. Recommendations:# Add tests like:
def test_message_precedence_over_prompt():
"""Verify messages take precedence when both provided."""
def test_empty_messages_list():
"""Test behavior with empty messages list."""
def test_openresponses_streaming_with_messages():
"""Test streaming with multi-turn conversation."""Documentation and Type Hints 📝Strengths:
Minor Improvements:
Overall Assessment 🎯Verdict: APPROVE with Minor Suggestions ✅This is a high-quality PR that adds significant value while maintaining code quality and architectural consistency. The implementation follows best practices and integrates well with the existing codebase. Priority Action Items:
Breaking Changes:None - the changes are additive and maintain backwards compatibility. Merge Recommendation:Ready to merge after addressing the high-priority testing gaps. The code quality is excellent, and the architectural decisions are sound. The minor suggestions can be addressed in follow-up PRs if needed. Great work on this feature! The multi-turn conversation support and local model integration are valuable additions to Celeste. 🚀 |
Summary
This PR adds two major features to Celeste v1:
MessageandRoletypes for building conversational workflowsChanges
Messages (Multi-Turn Support)
MessageandRoletypes (user,assistant,system,developer)generate,analyze, namespace APIs) now acceptmessages=parametermessagesare provided, they take precedence overpromptOpenResponses + Local Support
Provider.OPENRESPONSESimplementing OpenAI Responses-compatible API (POST /v1/responses+ SSE)Provider.OLLAMAas local wrapper with defaulthttp://localhost:11434NoAuthfor local providersbase_url=parameter for custom API gatewaysTesting
analyze()withmessagesparameterDocumentation
CHANGELOG_V1.mdwith dedicated sections for both features