Add ollama llm#67
Conversation
Dependency ReviewThe following issues were found:
Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. License Issues.github/workflows/dependency-scan.yml
OpenSSF Scorecard
Scanned Files
|
🤖 New Features: - OllamaClient utility for local LLM integration - Smart Arch Linux roasts using LLM (optional, env-controlled) - Contextual, personalized responses based on message content - Graceful fallback to classic regex jokes if Ollama unavailable 🎯 Arch Banter Enhancements: - ARCH_BANTER_LLM env var enables LLM mode - Generates contextual roasts from actual user messages - Falls back to 90+ classic jokes automatically - Maintains cooldowns and statistics 📚 Infrastructure: - penguin-overlord/utils/ollama_client.py - Async LLM client - Configurable via OLLAMA_MODEL, OLLAMA_ENABLED env vars - 8-second timeout with async processing (non-blocking) - Supports gemma2:2b, llama3.2, llama3.1 models 🔧 Configuration: - requirements.txt: Added ollama==0.6.1 - Comprehensive docs/OLLAMA_LLM.md with setup guide - Default: LLM disabled, opt-in feature - Privacy-first: 100% local processing, no cloud APIs 💡 Future Ready: - Quote search with semantic understanding - Contextual quote insights/explanations - Smart recommendations - Conversational trivia Tested with gemma2:2b model. Falls back gracefully if Ollama not installed/running. Zero breaking changes - fully backward compatible.
📦 Dependency Updates: - boto3: 1.41.2 → 1.42.30 - aiohttp: 3.13.2 → 3.13.3 (security fix) - matplotlib: 3.10.7 → 3.10.8 - GitHub Actions upload-artifact: v5 → v6 🤖 Robust Multi-Model LLM Support: - Added MODEL_CONFIGS with optimal settings for 17+ models - Gemma 2/3 (2b, 4b, 9b, 12b) - Google's efficient models - Llama 3.x (1b, 3b, 8b, 70b) - Meta's powerful models - Phi 3/4 (mini, medium, latest) - Microsoft's compact models - Qwen 2.5 (0.5b, 3b, 7b) - Alibaba's multilingual models - Mistral/Mixtral (7b, 8x7b) - High-quality open models 🎯 Smart Configuration: - Model-specific temperature, token limits, top_k values - Context window sizes (8K to 128K tokens) - Automatic fallback for unknown models - Partial matching (gemma3:4b-instruct matches gemma3:4b) - Family matching for variants All changes maintain backward compatibility
335b506 to
be1ce7f
Compare
Changes to ollama_client.py: - Support configurable OLLAMA_HOST and OLLAMA_PORT env vars (previously hardcoded to localhost, couldn't use remote server) - Use ollama.Client(host=...) instead of module-level ollama.generate() for proper remote server support - Fix asyncio.get_event_loop() deprecation (Python 3.10+) by using asyncio.get_running_loop() instead - Add qwen3:14b to MODEL_CONFIGS - Smart URL construction: auto-prepend http://, handle port in URL Changes to .env.example: - Document all Ollama configuration variables: OLLAMA_ENABLED, OLLAMA_HOST, OLLAMA_PORT, OLLAMA_MODEL, ARCH_BANTER_LLM Tested with Ollama server at 192.168.214.10:11434.
|
|
||
| EMOJI_PATTERN = re.compile( | ||
| "[" | ||
| "\U0001F600-\U0001F64F" # emoticons |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range Medium
|
|
||
| EMOJI_PATTERN = re.compile( | ||
| "[" | ||
| "\U0001F600-\U0001F64F" # emoticons |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range Medium
|
|
||
| EMOJI_PATTERN = re.compile( | ||
| "[" | ||
| "\U0001F600-\U0001F64F" # emoticons |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range Medium
|
|
||
| EMOJI_PATTERN = re.compile( | ||
| "[" | ||
| "\U0001F600-\U0001F64F" # emoticons |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range Medium
|
|
||
| EMOJI_PATTERN = re.compile( | ||
| "[" | ||
| "\U0001F600-\U0001F64F" # emoticons |
Check warning
Code scanning / CodeQL
Overly permissive regular expression range Medium
| from ai.features.moderation import ( | ||
| ModerationCategory, ModerationResult, | ||
| ACTIONS_REQUIRING_REVIEW, ACTION_SEVERITY, | ||
| ) |
Check notice
Code scanning / CodeQL
Unused import Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
In general, to fix an unused-import problem you either (a) remove the imported names from the import statement, or (b) if none of the imported names are used, remove the entire import block. If there is a fallback definition for the same unused names (as here), that fallback code can also be removed to keep the file consistent and avoid dead code.
In this file, the best targeted change is to stop importing ACTIONS_REQUIRING_REVIEW and ACTION_SEVERITY from ai.features.moderation / penguin_overlord.ai.features.moderation, and to remove the corresponding default assignments in the deepest except ImportError block, while leaving the rest of the imports and logic intact. Concretely:
- In the first
tryblock at lines 64–67, keep importingModerationCategoryandModerationResult, but dropACTIONS_REQUIRING_REVIEWandACTION_SEVERITYfrom the import list. - In the inner
tryblock at lines 70–73, do the same. - In the final
except ImportErrorblock at lines 75–76, remove the assignments toACTIONS_REQUIRING_REVIEWandACTION_SEVERITY, because those names are no longer needed.
No new methods, imports, or definitions are required to implement this; we are only narrowing the imported symbols and deleting the now-unnecessary fallbacks.
| @@ -62,20 +62,20 @@ | ||
| # Try to import moderation types | ||
| try: | ||
| from ai.features.moderation import ( | ||
| ModerationCategory, ModerationResult, | ||
| ACTIONS_REQUIRING_REVIEW, ACTION_SEVERITY, | ||
| ModerationCategory, | ||
| ModerationResult, | ||
| ) | ||
| except ImportError: | ||
| try: | ||
| from penguin_overlord.ai.features.moderation import ( | ||
| ModerationCategory, ModerationResult, | ||
| ACTIONS_REQUIRING_REVIEW, ACTION_SEVERITY, | ||
| ModerationCategory, | ||
| ModerationResult, | ||
| ) | ||
| except ImportError: | ||
| ACTIONS_REQUIRING_REVIEW = {'kick', 'ban'} | ||
| ACTION_SEVERITY = {} | ||
| pass | ||
|
|
||
|
|
||
|
|
||
| def _get_env_list(key: str) -> List[str]: | ||
| """Get a comma-separated env var as a list of strings.""" | ||
| val = os.getenv(key, '').strip() |
| import logging | ||
| import os | ||
| from datetime import datetime, timedelta, timezone | ||
| from typing import Optional, List |
Check notice
Code scanning / CodeQL
Unused import Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the problem, we should remove the unused symbol Optional from the typing import while keeping List, which is used in the return annotation of _get_env_list. This removes an unnecessary dependency and quiets the static analysis warning without changing runtime behavior.
Concretely, in penguin-overlord/cogs/ai_moderation.py, adjust the import on line 32 from from typing import Optional, List to from typing import List. No other code changes are required, and no additional methods or imports are needed.
| @@ -29,7 +29,7 @@ | ||
| import logging | ||
| import os | ||
| from datetime import datetime, timedelta, timezone | ||
| from typing import Optional, List | ||
| from typing import List | ||
|
|
||
| import discord | ||
| from discord.ext import commands |
| from .ollama_provider import OllamaProvider | ||
| from .gemini_provider import GeminiProvider | ||
| from .queue import RequestQueue | ||
| from .guardrails import Guardrails, GuardrailConfig, GuardrailResult, FEATURE_GUARDRAIL_DEFAULTS |
Check notice
Code scanning / CodeQL
Unused import Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the issue, remove the unused GuardrailResult name from the import statement while keeping the other imported names intact. This eliminates the unnecessary dependency on that symbol without altering functionality, since it is not referenced anywhere in the module.
Concretely, in penguin-overlord/ai/manager.py, locate the line:
from .guardrails import Guardrails, GuardrailConfig, GuardrailResult, FEATURE_GUARDRAIL_DEFAULTSand edit it to:
from .guardrails import Guardrails, GuardrailConfig, FEATURE_GUARDRAIL_DEFAULTSNo other code changes or additional imports are needed.
| @@ -30,7 +30,7 @@ | ||
| from .ollama_provider import OllamaProvider | ||
| from .gemini_provider import GeminiProvider | ||
| from .queue import RequestQueue | ||
| from .guardrails import Guardrails, GuardrailConfig, GuardrailResult, FEATURE_GUARDRAIL_DEFAULTS | ||
| from .guardrails import Guardrails, GuardrailConfig, FEATURE_GUARDRAIL_DEFAULTS | ||
| from .features import ArchRoaster, NewsAnalyzer, CVEAnalyzer, ModerationAnalyzer, LegislationAnalyzer | ||
|
|
||
| logger = logging.getLogger(__name__) |
| from collections import deque | ||
| from dataclasses import dataclass, field | ||
| from enum import Enum | ||
| from typing import Dict, List, Optional, Set, Tuple |
Check notice
Code scanning / CodeQL
Unused import Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the problem, remove the unused symbol Set from the typing import so that only the actually used types remain imported. This preserves existing functionality and behavior while cleaning up the dependency surface and satisfying the static analysis rule.
Concretely, in penguin-overlord/ai/guardrails.py, locate the line:
from typing import Dict, List, Optional, Set, Tupleand edit it to remove Set from the imported names:
from typing import Dict, List, Optional, TupleNo other code changes are required, and no new methods, imports, or definitions are needed.
| @@ -20,7 +20,7 @@ | ||
| from collections import deque | ||
| from dataclasses import dataclass, field | ||
| from enum import Enum | ||
| from typing import Dict, List, Optional, Set, Tuple | ||
| from typing import Dict, List, Optional, Tuple | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
|
|
||
| import logging | ||
| import re | ||
| import time |
Check notice
Code scanning / CodeQL
Unused import Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix an unused import, you remove the import statement for the module that is not referenced anywhere in the file. This does not change runtime behavior if the module truly isn’t used, but it cleans up the dependency graph and the code.
In this file, the single best fix is to delete the line import time at line 19 in penguin-overlord/ai/guardrails.py, leaving all other imports intact. No additional methods, definitions, or imports are required; we are only removing the unused import. Ensure that only this line is removed and that the surrounding imports remain unchanged.
| @@ -16,7 +16,6 @@ | ||
|
|
||
| import logging | ||
| import re | ||
| import time | ||
| from collections import deque | ||
| from dataclasses import dataclass, field | ||
| from enum import Enum |
No description provided.