Files
portainer-core/services/core-ai/PHASE1_COMPLETE.md
T
jpmschweitzerandClaude 53267e1665 feat(ai): migrate from Google ADK to PydanticAI with working tool calling
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>
2025-11-30 10:31:14 +01:00

7.3 KiB

Phase 1: ADK Agent Setup - COMPLETE ✓

Date: 2025-11-27 Status: Implementation Complete, Testing in Progress


What Was Accomplished

1. Code Restructuring ✓

Before:

src/
├── agent.py        # Single SimpleLiteLLMAgent
├── config.py
└── prompts.py

After:

src/
├── agents/
│   ├── __init__.py
│   ├── simple.py       # SimpleLiteLLMAgent (moved)
│   └── adk_agent.py    # ADKAgent (new)
├── config.py            # Updated with ADK settings
└── prompts.py           # Updated with ADK prompt

2. ADK Agent Implementation ✓

File: src/agents/adk_agent.py

Features:

  • Google ADK integration with LiteLLM backend
  • Streaming and non-streaming support
  • Tool calling framework (ready for Phase 2)
  • Event-driven architecture (tool_call, tool_result, content)
  • Comprehensive logging

API:

agent = ADKAgent(tools=[])
response = await agent.chat_completion(messages)
async for event in agent.chat(messages, stream=True):
    # Handle events

3. Configuration Updates ✓

File: src/config.py

New Settings:

adk_system_prompt_variant: str = "adk_agent"  # Separate prompt for ADK
simple_enabled: bool = True                    # Feature flag
adk_enabled: bool = True                       # Feature flag

4. Prompt System ✓

File: src/prompts.py

New Prompts:

  • minimal_agent - Simple mode (existing)
  • adk_agent - ADK mode with tool guidance (new)

5. Diagnostic Tools ✓

File: diagnostics/test_adk_direct.py

Tests:

  • ADK initialization
  • Simple questions without tools
  • Math problems
  • Multi-step reasoning
  • Streaming vs non-streaming

6. Test Suite Layer 6 ✓

File: tests/test_06_adk_setup.py

Tests:

  • ADK import verification
  • Prompt existence
  • Agent initialization
  • Simple completion
  • Streaming mode
  • "Capital of France" test
  • System prompt loading

Testing Strategy

Phase 1 Tests (No Tools)

# Diagnostic test
docker exec core-ai python diagnostics/test_adk_direct.py

# Unit tests
docker exec core-ai pytest tests/test_06_adk_setup.py -v -s

What We're Testing

ADK Runtime

  • Can import Google ADK
  • Can initialize LiteLLM backend
  • Can create ADK agent

Basic Completion

  • Simple questions work
  • Math works
  • Streaming works
  • Non-streaming works

Configuration

  • Prompts load correctly
  • Settings are applied
  • Feature flags work

NOT Testing Yet (Phase 2)

  • Tool registration
  • Tool calling
  • REST integration

Architecture

Current State (Phase 1)

┌─────────────────────────────────────────┐
│           Core-AI Service               │
│                                         │
│  ┌─────────────────┐                   │
│  │ SimpleLiteLLM   │  (Existing)       │
│  │    Agent        │                   │
│  └────────┬────────┘                   │
│           │                             │
│  ┌────────▼────────┐                   │
│  │   ADK Agent     │  (New - No Tools) │
│  │                 │                   │
│  │  • LiteLLM      │                   │
│  │  • Streaming    │                   │
│  │  • Basic Q&A    │                   │
│  └────────┬────────┘                   │
│           │                             │
│    ┌──────▼──────┐                     │
│    │   LiteLLM   │                     │
│    └──────┬──────┘                     │
│           │                             │
│    ┌──────▼──────┐                     │
│    │   Ollama    │                     │
│    └─────────────┘                     │
└─────────────────────────────────────────┘

Next State (Phase 2)

┌─────────────────────────────────────────┐
│           Core-AI Service               │
│                                         │
│  ┌────────────────┐                    │
│  │   ADK Agent    │                    │
│  │  with Tools    │                    │
│  │                │                    │
│  │  ┌──────────┐  │                    │
│  │  │  Tools   │──┼────► Core-API     │
│  │  │ Registry │  │      (REST calls) │
│  │  └──────────┘  │                    │
│  └────────┬───────┘                    │
│           │                             │
│    ┌──────▼──────┐                     │
│    │   LiteLLM   │                     │
│    └─────────────┘                     │
└─────────────────────────────────────────┘

Files Modified/Created

Modified

  • ✏️ src/config.py - Added ADK settings
  • ✏️ src/prompts.py - Added ADK prompt
  • ✏️ main.py - Updated import path

Created

  • 📄 src/agents/__init__.py
  • 📄 src/agents/simple.py (moved from src/agent.py)
  • 📄 src/agents/adk_agent.py
  • 📄 diagnostics/test_adk_direct.py
  • 📄 tests/test_06_adk_setup.py
  • 📄 ARCHITECTURE.md
  • 📄 PHASE1_COMPLETE.md (this file)

Next Steps

Rebuild & Test Phase 1

# Rebuild container
docker compose -f /mnt/media/Projects/portainer-core/stacks/core-ai.yml build

# Restart
docker compose -f /mnt/media/Projects/portainer-core/stacks/core-ai.yml up -d

# Test ADK
docker exec core-ai python diagnostics/test_adk_direct.py

# Run test suite
docker exec core-ai pytest tests/test_06_adk_setup.py -v -s

Phase 2: Tool Integration

Once Phase 1 tests pass:

  1. Create src/tools/registry.py
  2. Implement REST-based tools
  3. Create tests/test_07_adk_tools.py
  4. Test tool registration and discovery

Known Limitations (Phase 1)

⚠️ No Tools Yet

  • ADK agent has no tools in Phase 1
  • Can only do basic Q&A like SimpleLiteLLMAgent
  • Tool calling framework is ready but unused

⚠️ No HTTP Endpoints Yet

  • ADK agent not exposed via HTTP
  • Only testable via diagnostics
  • Phase 4 will add API routes

⚠️ No Core-API Integration

  • Tools will call Core-API REST endpoints
  • Integration happens in Phase 2

Success Criteria for Phase 1

  • ADK imports successfully
  • ADKAgent class created
  • Agent initializes with Ollama/LiteLLM
  • Can answer simple questions
  • Streaming works
  • Non-streaming works
  • Diagnostic tool created
  • Test layer 6 created
  • Tests pass in Docker container

Status: Implementation complete, awaiting rebuild and testing.


Last Updated: 2025-11-27 Next Phase: Tool Integration (Phase 2)