Major Changes: - Replace Google ADK with PydanticAI framework for agent orchestration - Implement OpenAI-compatible API endpoint for Ollama integration - Fix streaming response to send deltas instead of cumulative text - Add /chat/completions route alias for Open-WebUI compatibility - Enable tool calling with 5 local tools (calculate, date/time utilities) Architecture: - Core-AI service: Standalone Python service with PydanticAI agent - PydanticAI: Uses OpenAI-compatible Ollama API at /v1 endpoint - Tool Registry: Shared tool system between core-ai and core-api - Streaming: Fixed async context issues and delta calculation Verified Working: ✅ Chat completion (streaming & non-streaming) ✅ Tool calling with mistral-nemo and mistral-tools models ✅ Open-WebUI integration via core-ai:8086 ✅ 5 tools: calculate, get_current_time, get_current_date, calculate_date_difference, add_days_to_date ✅ Proper streaming deltas (no repetition) Technical Details: - PydanticAI 1.25.0+ with full Ollama support - Async context manager issue resolved via chunk collection - Delta calculation: chunk[len(previous):] to extract new content only - Routes: /v1/chat/completions and /chat/completions (Open-WebUI compat) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
12 KiB
Phase 4: API Routes - COMPLETE ✓
Date: 2025-11-27 Status: COMPLETE WITH KNOWN ISSUES
🎉 Achievement
Core-AI now has complete HTTP API endpoints:
- ✅
/v1/chat/completions- Default endpoint (simple agent) - ✅
/v1/chat/simple- Explicit simple agent (no tools) - ✅
/v1/chat/adk- ADK agent with tools - ✅
/v1/tools- List all available tools - ✅
/health- Enhanced health check with agent status
Test Results: 7/8 tests passing (87.5% pass rate)
API Endpoints
POST /v1/chat/completions
Description: Default chat endpoint (uses SimpleLiteLLMAgent) Status: ✅ Working
Request:
{
"messages": [
{"role": "user", "content": "What is 2+2?"}
],
"stream": false
}
Response:
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1701234567,
"model": "default_model",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "4"},
"finish_reason": "stop"
}]
}
POST /v1/chat/simple
Description: Explicit simple agent endpoint (no tools) Status: ✅ Working
Request:
{
"messages": [{"role": "user", "content": "Hello"}],
"stream": false
}
Response: Same format as /v1/chat/completions with "model": "simple"
POST /v1/chat/adk
Description: ADK agent endpoint with tool support Status: ⚠️ Working but tool execution needs improvement
Request:
{
"messages": [{"role": "user", "content": "What is the current date?"}],
"stream": false,
"enable_tools": true
}
Response:
{
"id": "chatcmpl-xyz789",
"object": "chat.completion",
"created": 1701234567,
"model": "adk",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "..."},
"finish_reason": "stop"
}],
"tools_enabled": true,
"tools_count": 5
}
Parameters:
enable_tools(boolean, default: true) - Enable/disable tool usagestream(boolean, default: false) - Enable streaming responses
GET /v1/tools
Description: List all available tools Status: ✅ Working
Response:
{
"tools": [
{
"name": "get_current_time",
"description": "Get the current time in UTC timezone...",
"type": "local"
},
...
],
"count": 5,
"adk_available": true
}
GET /health
Description: Enhanced health check Status: ✅ Working
Response:
{
"status": "ok",
"service": "core-ai",
"agents": {
"simple": true,
"adk": true
},
"tools_count": 5
}
Test Results
Layer 10: API Integration Tests
docker exec core-ai pytest tests/test_10_adk_api.py -v
Results: ✅ 7/8 PASSED (87.5%)
| Test | Status | Description |
|---|---|---|
test_health_check |
✅ PASS | Health endpoint returns correct status |
test_list_tools |
✅ PASS | Tools listing endpoint works |
test_chat_completions_simple |
✅ PASS | Default endpoint works |
test_chat_simple_endpoint |
✅ PASS | Simple agent endpoint works |
test_chat_adk_endpoint |
❌ FAIL | ADK endpoint timeout (30s) |
test_chat_adk_with_calculator |
✅ PASS | ADK with calculator works |
test_streaming_simple |
✅ PASS | Streaming responses work |
test_adk_without_tools |
✅ PASS | ADK without tools works |
What Was Implemented
1. HTTP Endpoints ✓
File: main.py
New Handlers:
chat_simple()- SimpleLiteLLMAgent endpointchat_adk()- ADKAgent endpoint with tool supportlist_tools()- Tool listing endpoint- Enhanced
health_check()- Shows agent and tool status
Features:
- OpenAI-compatible response format
- Streaming and non-streaming support
- Tool enable/disable control
- Proper error handling and logging
- Request logging with agent identifiers
2. Test Suite ✓
File: tests/test_10_adk_api.py
Tests Created:
- Health check validation
- Tools listing validation
- Simple agent endpoint testing
- ADK agent endpoint testing
- Streaming response testing
- Tool execution testing
- Error handling testing
Architecture
Request Flow
┌─────────────────────────────────────────────────────────────┐
│ HTTP Client │
└────────────┬────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ aiohttp Server │
│ (main.py) │
│ │
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ /v1/chat/ │ │ /v1/chat/adk │ │
│ │ completions │ │ │ │
│ │ /v1/chat/simple │ │ • enable_tools param │ │
│ │ │ │ • Tool discovery │ │
│ │ → Simple Agent │ │ → ADK Agent │ │
│ └──────────────────┘ └──────────────────────────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ /v1/tools │ │ /health │ │
│ │ → List tools │ │ → Status check │ │
│ └──────────────────┘ └──────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Endpoint Comparison
| Feature | /v1/chat/simple | /v1/chat/adk |
|---|---|---|
| Agent | SimpleLiteLLMAgent | ADKAgent |
| Tools | ❌ No | ✅ Yes (optional) |
| Performance | Fast | Slower (with tools) |
| Streaming | ✅ Yes | ✅ Yes |
| Use Case | Quick Q&A | Complex tasks with tools |
Usage Examples
Simple Query (No Tools)
curl -X POST http://localhost:8086/v1/chat/simple \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "What is 2+2?"}],
"stream": false
}'
ADK Query (With Tools)
curl -X POST http://localhost:8086/v1/chat/adk \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "What is the current date?"}],
"stream": false,
"enable_tools": true
}'
List Available Tools
curl -X GET http://localhost:8086/v1/tools
Streaming Request
curl -N -X POST http://localhost:8086/v1/chat/simple \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "Count to 5"}],
"stream": true
}'
Known Issues & Limitations
1. ADK Tool Execution Timeout
Issue: test_chat_adk_endpoint times out after 30 seconds
Impact: Medium - ADK agent with tool discovery takes too long for some queries
Symptoms:
- Request times out waiting for response
- Happens when ADK tries to determine which tool to use
- Works fine when tools are disabled
Possible Causes:
- ADK runner processing all events before returning final response
- Tool call event handling incomplete
- Model taking too long to decide on tool usage
Workaround:
- Increase timeout to 60 seconds
- Disable tools for simple queries
- Use
/v1/chat/simplefor basic Q&A
TODO: Investigate ADK event loop and tool execution flow
2. Tool Call Format
Issue: ADK sometimes returns tool call JSON instead of executing tools Impact: Low - Appears to be intermittent Symptoms:
{
"toolCalls": [{
"id": "call_xxx",
"type": "function",
"function": {"name": "get_current_date", "arguments": {}}
}]
}
Possible Causes:
- ADK runner not processing all events
- Breaking out of event loop too early
- Missing event type handling
TODO: Review adk_agent.py event processing logic
3. No REST Tool Discovery Yet
Status: Not implemented in this phase Impact: Low - Phase 2 implemented the framework, Phase 3 will test it Next Steps: Test with real core-api OpenAPI documentation
Files Modified/Created
Modified Files
- ✏️
main.py- Added 4 new endpoints and enhanced health check
New Files
- 📄
tests/test_10_adk_api.py- API integration tests - 📄
PHASE4_COMPLETE.md- This file
Performance Metrics
Response Times (Approximate)
/health: < 50ms/v1/tools: < 100ms/v1/chat/simple: 1-5 seconds (depends on model)/v1/chat/adk(no tools): 2-8 seconds/v1/chat/adk(with tools): 5-30+ seconds
Concurrent Requests
- Simple endpoint: Handles multiple concurrent requests well
- ADK endpoint: One request at a time recommended (caching helps)
Next Steps
Immediate Fixes
- Investigate and fix ADK tool execution timeout
- Improve ADK event processing to handle tool calls properly
- Add request timeout configuration
Phase 5 (Future)
- Add authentication/authorization
- Add rate limiting
- Add request/response logging to database
- Add metrics/monitoring endpoints
- Implement conversation history persistence
Phase 3 (Revisit)
- Test REST tool discovery with real core-api
- Add core-api OpenAPI documentation
- Verify cross-service tool calling
Success Criteria
/v1/chat/completionsendpoint working/v1/chat/simpleendpoint working/v1/chat/adkendpoint working (with known issues)/v1/toolsendpoint working- Enhanced
/healthendpoint - Streaming support for all chat endpoints
- OpenAI-compatible response format
- Test suite created (8 tests)
- 87.5% test pass rate (7/8 passing)
- 100% test pass rate (pending timeout fix)
Phase 4 Status: ✅ COMPLETE WITH KNOWN ISSUES
Testing
Quick Manual Tests
# Health check
curl -s http://localhost:8086/health | jq .
# List tools
curl -s http://localhost:8086/v1/tools | jq .tools[].name
# Simple chat
curl -s -X POST http://localhost:8086/v1/chat/simple \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "Hello"}], "stream": false}' \
| jq .choices[0].message.content
# ADK chat (no tools)
curl -s -X POST http://localhost:8086/v1/chat/adk \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "Hello"}], "stream": false, "enable_tools": false}' \
| jq .choices[0].message.content
Full Test Suite
docker exec core-ai pytest tests/test_10_adk_api.py -v -s
Last Updated: 2025-11-27 Next Phase: Fix tool execution issues, then proceed to Phase 3 (Core-API integration) Recommendation: Address ADK timeout issue before production use