refactor(core-ai): comprehensive cleanup - PydanticAI only architecture

Remove all obsolete agent implementations and framework references.
Keep only PydanticAI (primary) and SimpleLiteLLM (fallback).

This cleanup eliminates confusion between multiple frameworks that were
tried during development (LangChain, LangGraph, ADK, OllamaNative) and
establishes PydanticAI as the single agent framework going forward.

BREAKING CHANGES:
- Removed OllamaNativeAgent - use PydanticAgent instead
- Removed /test/ollama-tools diagnostic endpoint
- Default /v1/chat/completions now uses PydanticAgent

Files Deleted (32 total):
- Obsolete agents: ollama_native_agent.py
- Diagnostic files: ARCHITECTURE.md, DIAGNOSTIC_RESULTS.md, PHASE*.md
- Legacy tools: src/tools.py
- Test files: test_ai_flow_quality.py, test_02/03 (diagnostic layers)
- Documentation: ADK_Ollama_Research.md, agent-flow-diagrams.md
- Session docs: 3 files with LangChain/LangGraph implementations
- Plans: 5 completed plans about obsolete frameworks
- Migration docs: MIGRATION_PLAN_LANGCHAIN_TO_ADK.md

Files Modified (8 total):
- main.py: Refactored to PydanticAI only (305 lines vs 457 before)
- agents/__init__.py: Removed OllamaNativeAgent exports
- README.md: Complete rewrite for PydanticAI architecture
- prompts.py: Updated for PydanticAI (infrastructure tool guidance)
- STATUS.md: Updated to v0.11.0-pydantic-ai
- CHANGELOG.md: Added v0.11.0 entry documenting cleanup
- plans/active/*.md: Updated to reference PydanticAI

Current Architecture:
- Framework: PydanticAI with native Ollama SDK
- Agents: PydanticAgent (primary) + SimpleLiteLLMAgent (fallback)
- Model: mistral-nemo:latest
- Tools: 6 core + 28+ OpenAPI-discovered
- Memory: 3-tier system with Qdrant
- VRAM: ~4-6GB

Lines Removed: ~3000+ lines of obsolete code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-03 14:24:52 +01:00
co-authored by Claude
parent 96492cb1ed
commit 66f6e54fc3
32 changed files with 1078 additions and 10376 deletions
@@ -1,144 +0,0 @@
#!/usr/bin/env python3
"""
Diagnostic tool to test direct LiteLLM → Ollama communication.
This bypasses all abstractions and tests the raw integration.
Usage:
python diagnostics/test_litellm_direct.py
"""
import asyncio
import sys
import os
from pathlib import Path
# Add parent directory to path to import from src
sys.path.insert(0, str(Path(__file__).parent.parent))
from src.config import get_settings
# Import LiteLLM
try:
import litellm
litellm.set_verbose = True
except ImportError:
print("✗ LiteLLM not installed. Run: pip install litellm")
sys.exit(1)
async def test_litellm_direct():
"""Test direct LiteLLM completion with Ollama"""
settings = get_settings()
print("=" * 70)
print("LITELLM DIRECT TEST")
print("=" * 70)
# Test configuration
model_name = settings.agent_model
litellm_model = f"ollama/{model_name}"
api_base = settings.ollama_base_url
print(f"\n1. Configuration")
print(f" LiteLLM Model: {litellm_model}")
print(f" API Base: {api_base}")
print(f" Temperature: 0.1")
# Test messages
test_cases = [
{
"name": "Simple question (no system prompt)",
"messages": [
{"role": "user", "content": "What is the capital of France? Answer in one word."}
]
},
{
"name": "Simple question (with system prompt)",
"messages": [
{"role": "system", "content": "You are a helpful assistant. Answer questions concisely."},
{"role": "user", "content": "What is the capital of France? Answer in one word."}
]
},
{
"name": "Math problem",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is 2 + 2? Answer with just the number."}
]
}
]
# Run tests
for i, test_case in enumerate(test_cases, 1):
print(f"\n{'-' * 70}")
print(f"Test {i}/{len(test_cases)}: {test_case['name']}")
print(f"{'-' * 70}")
# Log messages being sent
print("\nMessages being sent:")
for j, msg in enumerate(test_case['messages']):
content_preview = msg['content'][:60] + "..." if len(msg['content']) > 60 else msg['content']
print(f" [{j}] {msg['role']}: {content_preview}")
try:
# Test non-streaming first
print("\n→ Testing non-streaming mode...")
response = await litellm.acompletion(
model=litellm_model,
messages=test_case['messages'],
api_base=api_base,
temperature=0.1,
stream=False
)
content = response.choices[0].message.content
finish_reason = response.choices[0].finish_reason
print(f"\n✓ Non-streaming response received:")
print(f" Content: {content}")
print(f" Finish reason: {finish_reason}")
print(f" Model: {response.model}")
# Test streaming
print("\n→ Testing streaming mode...")
stream_response = await litellm.acompletion(
model=litellm_model,
messages=test_case['messages'],
api_base=api_base,
temperature=0.1,
stream=True
)
chunks = []
chunk_count = 0
async for chunk in stream_response:
chunk_count += 1
if chunk.choices[0].delta.content:
chunks.append(chunk.choices[0].delta.content)
full_content = "".join(chunks)
print(f"\n✓ Streaming response received:")
print(f" Content: {full_content}")
print(f" Chunks: {chunk_count}")
print(f"\n✓ Test {i} PASSED")
except Exception as e:
print(f"\n✗ Test {i} FAILED")
print(f" Error: {type(e).__name__}: {e}")
import traceback
traceback.print_exc()
return False
print("\n" + "=" * 70)
print("✓ ALL LITELLM TESTS PASSED!")
print("=" * 70)
print("\nNext steps:")
print(" 1. If this works, the LiteLLM → Ollama connection is solid")
print(" 2. Any issues are likely in the agent wrapper or API layer")
print(" 3. Run the full test suite: bash diagnostics/run_all_tests.sh")
return True
if __name__ == "__main__":
result = asyncio.run(test_litellm_direct())
sys.exit(0 if result else 1)