| … | … | @@ -0,0 +1,24 @@ |
| 1 | # Python bytecode | |
| 2 | __pycache__/ | |
| 3 | *.py[cod] | |
| 4 | *$py.class | |
| 5 | ||
| 6 | # Distribution / packaging | |
| 7 | dist/ | |
| 8 | build/ | |
| 9 | *.egg-info/ | |
| 10 | ||
| 11 | # Virtual environments | |
| 12 | venv/ | |
| 13 | env/ | |
| 14 | .env/ | |
| 15 | ||
| 16 | # IDE files | |
| 17 | .idea/ | |
| 18 | .vscode/ | |
| 19 | *.swp | |
| 20 | *.swo | |
| 21 | ||
| 22 | # Local configuration | |
| 23 | .DS_Store | |
| 24 |
| … | … | @@ -0,0 +1,36 @@ |
| 1 | flowchart TD | |
| 2 | subgraph OllamaTools | |
| 3 | Agent[OllamaAgent] | |
| 4 | ||
| 5 | subgraph Security | |
| 6 | PermMgr[PermissionManager] | |
| 7 | end | |
| 8 | ||
| 9 | subgraph Tools | |
| 10 | SysTool[SystemTools] | |
| 11 | WebTool[WebTools] | |
| 12 | DocTool[DocTools] | |
| 13 | end | |
| 14 | ||
| 15 | subgraph Utils | |
| 16 | Config[Configuration] | |
| 17 | Logger[Logger] | |
| 18 | end | |
| 19 | ||
| 20 | Agent --> PermMgr | |
| 21 | Agent --> SysTool | |
| 22 | Agent --> WebTool | |
| 23 | Agent --> DocTool | |
| 24 | Agent --> Config | |
| 25 | Agent --> Logger | |
| 26 | end | |
| 27 | ||
| 28 | subgraph External | |
| 29 | Ollama[Ollama API] | |
| 30 | Linux[Linux Commands] | |
| 31 | Web[Web Services] | |
| 32 | end | |
| 33 | ||
| 34 | Agent <--> Ollama | |
| 35 | SysTool <--> Linux | |
| 36 | WebTool <--> Web |
| … | … | @@ -0,0 +1,53 @@ |
| 1 | classDiagram | |
| 2 | class OllamaAgent { | |
| 3 | -model: str | |
| 4 | -host: str | |
| 5 | -permission_prompts: bool | |
| 6 | -sudo_always_prompt: bool | |
| 7 | -client: Client | |
| 8 | -permission_manager: PermissionManager | |
| 9 | +__init__(model, host, permission_prompts, sudo_always_prompt) | |
| 10 | +chat(message, system_prompt, context) str | |
| 11 | +register_tools() None | |
| 12 | +process_function_calls(function_calls) List | |
| 13 | } | |
| 14 | ||
| 15 | class PermissionManager { | |
| 16 | -prompt_enabled: bool | |
| 17 | -sudo_always_prompt: bool | |
| 18 | +__init__(prompt_enabled, sudo_always_prompt) | |
| 19 | +request_permission(function_name, args, is_sudo) bool | |
| 20 | +detect_sudo(command) bool | |
| 21 | } | |
| 22 | ||
| 23 | class SystemTools { | |
| 24 | +execute_command(command, args, timeout) Dict | |
| 25 | +read_file(path, max_size) str | |
| 26 | +write_file(path, content, mode) bool | |
| 27 | +find_files(pattern, directory, recursive) List | |
| 28 | } | |
| 29 | ||
| 30 | class WebTools { | |
| 31 | +fetch_url(url, method, params, headers, data, timeout) Dict | |
| 32 | +get_weather(location, days, units) Dict | |
| 33 | +search_web(query, num_results) List | |
| 34 | } | |
| 35 | ||
| 36 | class DocTools { | |
| 37 | +generate_markdown(content, title, format_type) str | |
| 38 | +extract_context(query, documents, max_length) str | |
| 39 | +summarize_text(text, max_length) str | |
| 40 | } | |
| 41 | ||
| 42 | class Config { | |
| 43 | +permission_prompts: bool | |
| 44 | +sudo_always_prompt: bool | |
| 45 | +load() None | |
| 46 | +save() None | |
| 47 | } | |
| 48 | ||
| 49 | OllamaAgent -- PermissionManager : uses | |
| 50 | OllamaAgent -- SystemTools : registers | |
| 51 | OllamaAgent -- WebTools : registers | |
| 52 | OllamaAgent -- DocTools : registers | |
| 53 | OllamaAgent -- Config : configured by |
| … | … | @@ -0,0 +1,53 @@ |
| 1 | graph TD | |
| 2 | subgraph "OllamaTools Package Structure" | |
| 3 | Root["OllamaTools/"] | |
| 4 | ||
| 5 | OllamaDir["ollamatools/"] | |
| 6 | Tests["tests/"] | |
| 7 | Examples["examples/"] | |
| 8 | Docs["docs/"] | |
| 9 | Setup["setup.py"] | |
| 10 | Readme["README.md"] | |
| 11 | License["LICENSE"] | |
| 12 | Req["requirements.txt"] | |
| 13 | ||
| 14 | InitPy["__init__.py"] | |
| 15 | AgentPy["agent.py"] | |
| 16 | SecurityPy["security.py"] | |
| 17 | ConfigPy["config.py"] | |
| 18 | ||
| 19 | ToolDir["tools/"] | |
| 20 | UtilDir["utils/"] | |
| 21 | ||
| 22 | ToolInit["__init__.py"] | |
| 23 | SystemPy["system_tools.py"] | |
| 24 | WebPy["web_tools.py"] | |
| 25 | DocPy["doc_tools.py"] | |
| 26 | ||
| 27 | UtilInit["__init__.py"] | |
| 28 | LoggerPy["logger.py"] | |
| 29 | ||
| 30 | Root --> OllamaDir | |
| 31 | Root --> Tests | |
| 32 | Root --> Examples | |
| 33 | Root --> Docs | |
| 34 | Root --> Setup | |
| 35 | Root --> Readme | |
| 36 | Root --> License | |
| 37 | Root --> Req | |
| 38 | ||
| 39 | OllamaDir --> InitPy | |
| 40 | OllamaDir --> AgentPy | |
| 41 | OllamaDir --> SecurityPy | |
| 42 | OllamaDir --> ConfigPy | |
| 43 | OllamaDir --> ToolDir | |
| 44 | OllamaDir --> UtilDir | |
| 45 | ||
| 46 | ToolDir --> ToolInit | |
| 47 | ToolDir --> SystemPy | |
| 48 | ToolDir --> WebPy | |
| 49 | ToolDir --> DocPy | |
| 50 | ||
| 51 | UtilDir --> UtilInit | |
| 52 | UtilDir --> LoggerPy | |
| 53 | end |
| … | … | @@ -0,0 +1,36 @@ |
| 1 | stateDiagram-v2 | |
| 2 | [*] --> FunctionDetected | |
| 3 | ||
| 4 | FunctionDetected --> CheckIfSudo | |
| 5 | ||
| 6 | CheckIfSudo --> SudoCommand: is sudo | |
| 7 | CheckIfSudo --> CheckPromptSetting: not sudo | |
| 8 | ||
| 9 | SudoCommand --> CheckSudoSetting | |
| 10 | ||
| 11 | CheckSudoSetting --> PromptUser: sudo_always_prompt=True | |
| 12 | CheckSudoSetting --> AutoGrant: sudo_always_prompt=False | |
| 13 | ||
| 14 | CheckPromptSetting --> PromptUser: prompt_enabled=True | |
| 15 | CheckPromptSetting --> AutoGrant: prompt_enabled=False | |
| 16 | ||
| 17 | PromptUser --> UserDecision | |
| 18 | ||
| 19 | UserDecision --> ExecuteFunction: Allow | |
| 20 | UserDecision --> GrantForSession: Allow for session | |
| 21 | UserDecision --> DenyFunction: Deny | |
| 22 | UserDecision --> ModifyCommand: Modify | |
| 23 | ||
| 24 | AutoGrant --> ExecuteFunction | |
| 25 | ||
| 26 | GrantForSession --> ExecuteFunction | |
| 27 | GrantForSession --> UpdatePermissions | |
| 28 | ||
| 29 | ModifyCommand --> PromptUser | |
| 30 | ||
| 31 | ExecuteFunction --> ReturnResult | |
| 32 | DenyFunction --> ReturnDeniedMessage | |
| 33 | ||
| 34 | ReturnResult --> [*] | |
| 35 | ReturnDeniedMessage --> [*] | |
| 36 | UpdatePermissions --> [*] |
| … | … | @@ -0,0 +1,36 @@ |
| 1 | sequenceDiagram | |
| 2 | participant User | |
| 3 | participant OllamaAgent | |
| 4 | participant Ollama | |
| 5 | participant PermissionManager | |
| 6 | participant Functions | |
| 7 | ||
| 8 | User->>OllamaAgent: chat(query) | |
| 9 | OllamaAgent->>Ollama: Send query with registered tools | |
| 10 | Ollama-->>OllamaAgent: Detect function call(s) | |
| 11 | ||
| 12 | alt Function detected | |
| 13 | OllamaAgent->>PermissionManager: request_permission() | |
| 14 | ||
| 15 | alt sudo command detected | |
| 16 | PermissionManager->>User: Always prompt for sudo | |
| 17 | else normal command and prompts enabled | |
| 18 | PermissionManager->>User: Prompt for permission | |
| 19 | else prompts disabled | |
| 20 | PermissionManager-->>OllamaAgent: Auto-grant permission | |
| 21 | end | |
| 22 | ||
| 23 | alt Permission granted | |
| 24 | OllamaAgent->>Functions: Execute function | |
| 25 | Functions-->>OllamaAgent: Return result | |
| 26 | OllamaAgent->>Ollama: Send function result | |
| 27 | Ollama-->>OllamaAgent: Generate final response | |
| 28 | else Permission denied | |
| 29 | OllamaAgent->>Ollama: Send permission denied | |
| 30 | Ollama-->>OllamaAgent: Generate alternative response | |
| 31 | end | |
| 32 | else No function detected | |
| 33 | Ollama-->>OllamaAgent: Regular response | |
| 34 | end | |
| 35 | ||
| 36 | OllamaAgent-->>User: Return response |
| … | … | @@ -0,0 +1,60 @@ |
| 1 | # OllamaTools: Function Library for Ollama LLMs | |
| 2 | ||
| 3 | A Python library that extends Ollama with semantic function calling capabilities, enabling automatic invocation of system commands, web requests, and documentation utilities based on conversational context. | |
| 4 | ||
| 5 | ## Project Overview | |
| 6 | ||
| 7 | OllamaTools allows Ollama LLMs to execute external functions based on semantic understanding of user queries without requiring explicit enabling/disabling of tools. | |
| 8 | ||
| 9 | ## Features | |
| 10 | ||
| 11 | - Automatic function detection and execution | |
| 12 | - Secure permission system for sensitive operations | |
| 13 | - System command execution and file operations | |
| 14 | - Web request capabilities and API integrations | |
| 15 | - Documentation generation and processing utilities | |
| 16 | ||
| 17 | ## Installation | |
| 18 | ||
| 19 | ### Prerequisites | |
| 20 | ||
| 21 | - Python 3.8+ | |
| 22 | - Ollama 0.4.0+ with function calling support | |
| 23 | - Linux-based operating system (primary target) | |
| 24 | ||
| 25 | ### Install from source | |
| 26 | ||
| 27 | ```bash | |
| 28 | git clone https://github.com/yourusername/ollamatools.git | |
| 29 | cd ollamatools | |
| 30 | pip install -e . | |
| 31 | ``` | |
| 32 | ||
| 33 | ## Quick Start | |
| 34 | ||
| 35 | ```python | |
| 36 | from ollamatools import OllamaAgent | |
| 37 | ||
| 38 | # Create agent with default settings | |
| 39 | agent = OllamaAgent(model="llama3.1") | |
| 40 | ||
| 41 | # Chat with automatic function detection | |
| 42 | response = agent.chat("What's the weather like in San Francisco?") | |
| 43 | print(response) | |
| 44 | ||
| 45 | # Execute a system command | |
| 46 | response = agent.chat("Show me the largest files in the current directory") | |
| 47 | print(response) | |
| 48 | ||
| 49 | # Generate documentation | |
| 50 | response = agent.chat("Create documentation for a function that calculates prime numbers") | |
| 51 | print(response) | |
| 52 | ``` | |
| 53 | ||
| 54 | ## Security Considerations | |
| 55 | ||
| 56 | OllamaTools uses a prompt-based permission system by default, requiring user confirmation before executing potentially sensitive operations. Special care is taken with sudo commands which always require permission by default. | |
| 57 | ||
| 58 | ## License | |
| 59 | ||
| 60 | MIT License |
| … | … | @@ -0,0 +1,24 @@ |
| 1 | """ | |
| 2 | Basic usage example for OllamaTools. | |
| 3 | """ | |
| 4 | ||
| 5 | from ollamatools import OllamaAgent | |
| 6 | ||
| 7 | # Create agent with default settings | |
| 8 | agent = OllamaAgent(model="llama3.1") | |
| 9 | ||
| 10 | # Chat with automatic function detection | |
| 11 | response = agent.chat("Hello, what can you do?") | |
| 12 | print(response) | |
| 13 | ||
| 14 | # Example of system command execution | |
| 15 | response = agent.chat("Can you list the files in the current directory?") | |
| 16 | print(response) | |
| 17 | ||
| 18 | # Example of web request | |
| 19 | response = agent.chat("What's the weather like in San Francisco?") | |
| 20 | print(response) | |
| 21 | ||
| 22 | # Example of documentation generation | |
| 23 | response = agent.chat("Create documentation for a function that calculates prime numbers") | |
| 24 | print(response) |
| … | … | @@ -0,0 +1,78 @@ |
| 1 | #!/usr/bin/env python3 | |
| 2 | """ | |
| 3 | Example script demonstrating the basic usage of the PermissionManager. | |
| 4 | ||
| 5 | This script shows how to initialize the PermissionManager and request | |
| 6 | permissions for various operations. | |
| 7 | """ | |
| 8 | ||
| 9 | # Add parent directory to path to allow importing the package | |
| 10 | import sys | |
| 11 | import os | |
| 12 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) | |
| 13 | ||
| 14 | # Now import from the package | |
| 15 | from ollamatools.security import PermissionManager | |
| 16 | ||
| 17 | ||
| 18 | def main(): | |
| 19 | # Create a permission manager with default settings | |
| 20 | # (prompts enabled, sudo always prompts) | |
| 21 | pm = PermissionManager() | |
| 22 | ||
| 23 | print("=== Basic Permission Example ===") | |
| 24 | ||
| 25 | # Example 1: Request permission for a simple function | |
| 26 | print("\nExample 1: Simple function") | |
| 27 | result = pm.request_permission( | |
| 28 | "read_file", | |
| 29 | {"path": "/etc/hosts"} | |
| 30 | ) | |
| 31 | print(f"Permission granted: {result}") | |
| 32 | ||
| 33 | # Example 2: Request permission for a function with sudo | |
| 34 | print("\nExample 2: Function with sudo") | |
| 35 | result = pm.request_permission( | |
| 36 | "execute_command", | |
| 37 | {"command": "apt update"}, | |
| 38 | is_sudo=True | |
| 39 | ) | |
| 40 | print(f"Permission granted: {result}") | |
| 41 | ||
| 42 | # Example 3: Detect sudo in a command | |
| 43 | print("\nExample 3: Sudo detection") | |
| 44 | commands = [ | |
| 45 | "ls -la", | |
| 46 | "sudo apt update", | |
| 47 | "echo 'This is not sudo'", | |
| 48 | "sudo reboot" | |
| 49 | ] | |
| 50 | ||
| 51 | for cmd in commands: | |
| 52 | is_sudo = pm.detect_sudo(cmd) | |
| 53 | print(f"Command: {cmd}") | |
| 54 | print(f"Uses sudo: {is_sudo}") | |
| 55 | print() | |
| 56 | ||
| 57 | # Example 4: Create a permission manager with prompts disabled | |
| 58 | print("\nExample 4: Disabled prompts") | |
| 59 | pm_no_prompts = PermissionManager(prompt_enabled=False) | |
| 60 | result = pm_no_prompts.request_permission( | |
| 61 | "execute_command", | |
| 62 | {"command": "ls -la"} | |
| 63 | ) | |
| 64 | print(f"Permission granted: {result}") | |
| 65 | ||
| 66 | # Example 5: Create a permission manager with sudo prompts disabled | |
| 67 | print("\nExample 5: Disabled sudo prompts") | |
| 68 | pm_no_sudo_prompts = PermissionManager(sudo_always_prompt=False) | |
| 69 | result = pm_no_sudo_prompts.request_permission( | |
| 70 | "execute_command", | |
| 71 | {"command": "sudo apt update"}, | |
| 72 | is_sudo=True | |
| 73 | ) | |
| 74 | print(f"Permission granted: {result}") | |
| 75 | ||
| 76 | ||
| 77 | if __name__ == "__main__": | |
| 78 | main() |
| … | … | @@ -0,0 +1,21 @@ |
| 1 | """ | |
| 2 | OllamaTools: Function Library for Ollama LLMs | |
| 3 | ||
| 4 | A Python library that extends Ollama with semantic function calling capabilities, | |
| 5 | enabling automatic invocation of system commands, web requests, and documentation | |
| 6 | utilities based on conversational context. | |
| 7 | """ | |
| 8 | ||
| 9 | __version__ = "0.1.0" | |
| 10 | ||
| 11 | # Import key classes for direct access | |
| 12 | from ollamatools.security import PermissionManager | |
| 13 | # Import Config from config module (assuming it was implemented in step 1.2) | |
| 14 | from ollamatools.config import Config | |
| 15 | ||
| 16 | # For now, we'll expose these modules directly | |
| 17 | # More components will be added as they are implemented | |
| 18 | __all__ = [ | |
| 19 | "PermissionManager", | |
| 20 | "Config" | |
| 21 | ] |
| … | … | @@ -0,0 +1,63 @@ |
| 1 | """ | |
| 2 | Main agent interface for OllamaTools. | |
| 3 | ||
| 4 | This module contains the OllamaAgent class, which serves as the primary interface | |
| 5 | for interacting with the Ollama LLM and handling function detection and execution. | |
| 6 | """ | |
| 7 | ||
| 8 | from typing import Optional, List, Dict, Any | |
| 9 | ||
| 10 | ||
| 11 | class OllamaAgent: | |
| 12 | """ | |
| 13 | Primary interface that manages communication with Ollama and handles function | |
| 14 | detection and execution. | |
| 15 | """ | |
| 16 | ||
| 17 | def __init__( | |
| 18 | self, | |
| 19 | model: str = "llama3.1", | |
| 20 | host: str = "http://localhost:11434", | |
| 21 | permission_prompts: bool = True, | |
| 22 | sudo_always_prompt: bool = True | |
| 23 | ): | |
| 24 | """ | |
| 25 | Initialize the OllamaAgent with specified configuration. | |
| 26 | ||
| 27 | Args: | |
| 28 | model: Name of the Ollama model to use | |
| 29 | host: Ollama server address | |
| 30 | permission_prompts: Whether to prompt for function execution permission | |
| 31 | sudo_always_prompt: Whether to always prompt for sudo commands | |
| 32 | """ | |
| 33 | self.model = model | |
| 34 | self.host = host | |
| 35 | self.permission_prompts = permission_prompts | |
| 36 | self.sudo_always_prompt = sudo_always_prompt | |
| 37 | ||
| 38 | def chat( | |
| 39 | self, | |
| 40 | message: str, | |
| 41 | system_prompt: Optional[str] = None, | |
| 42 | context: Optional[List[Dict[str, str]]] = None | |
| 43 | ) -> str: | |
| 44 | """ | |
| 45 | Send a message to Ollama, automatically detecting and executing functions. | |
| 46 | ||
| 47 | Args: | |
| 48 | message: User message | |
| 49 | system_prompt: Optional system prompt | |
| 50 | context: Optional conversation context | |
| 51 | ||
| 52 | Returns: | |
| 53 | str: Response from Ollama, potentially after executing functions | |
| 54 | """ | |
| 55 | # Placeholder implementation | |
| 56 | return f"Placeholder response for message: {message}" | |
| 57 | ||
| 58 | def register_tools(self): | |
| 59 | """ | |
| 60 | Register all available tools with the Ollama client. | |
| 61 | """ | |
| 62 | # Placeholder implementation | |
| 63 | pass |
| … | … | @@ -0,0 +1,107 @@ |
| 1 | """ | |
| 2 | Configuration management for OllamaTools. | |
| 3 | ||
| 4 | This module contains the Config class, which handles configuration settings for | |
| 5 | the OllamaTools library. | |
| 6 | """ | |
| 7 | ||
| 8 | import json | |
| 9 | import os | |
| 10 | from typing import Optional, Dict, Any | |
| 11 | ||
| 12 | from pydantic import BaseModel, validator, Field | |
| 13 | ||
| 14 | ||
| 15 | class Config(BaseModel): | |
| 16 | """ | |
| 17 | Configuration class for OllamaTools. | |
| 18 | ||
| 19 | This class manages configuration settings for the OllamaTools library using | |
| 20 | Pydantic for validation. It provides methods for loading and saving configuration | |
| 21 | to a file. | |
| 22 | """ | |
| 23 | ||
| 24 | model: str = "llama3.1" | |
| 25 | host: str = "http://localhost:11434" | |
| 26 | permission_prompts: bool = True | |
| 27 | sudo_always_prompt: bool = True | |
| 28 | timeout_seconds: int = 60 | |
| 29 | max_file_size: Optional[int] = None | |
| 30 | ||
| 31 | @validator('timeout_seconds') | |
| 32 | def validate_timeout(cls, v): | |
| 33 | """Validate that timeout is positive.""" | |
| 34 | if v <= 0: | |
| 35 | raise ValueError("Timeout must be positive") | |
| 36 | return v | |
| 37 | ||
| 38 | @validator('max_file_size') | |
| 39 | def validate_max_file_size(cls, v): | |
| 40 | """Validate that max_file_size is positive if provided.""" | |
| 41 | if v is not None and v <= 0: | |
| 42 | raise ValueError("Max file size must be positive") | |
| 43 | return v | |
| 44 | ||
| 45 | @classmethod | |
| 46 | def load_from_file(cls, file_path: str) -> "Config": | |
| 47 | """ | |
| 48 | Load configuration from a JSON file. | |
| 49 | ||
| 50 | Args: | |
| 51 | file_path: Path to the configuration file | |
| 52 | ||
| 53 | Returns: | |
| 54 | Config: Configuration object | |
| 55 | ||
| 56 | Raises: | |
| 57 | FileNotFoundError: If the file does not exist | |
| 58 | json.JSONDecodeError: If the file contains invalid JSON | |
| 59 | ValueError: If the configuration is invalid | |
| 60 | """ | |
| 61 | if not os.path.exists(file_path): | |
| 62 | raise FileNotFoundError(f"Configuration file not found: {file_path}") | |
| 63 | ||
| 64 | with open(file_path, 'r') as f: | |
| 65 | try: | |
| 66 | config_data = json.load(f) | |
| 67 | return cls(**config_data) | |
| 68 | except json.JSONDecodeError: | |
| 69 | raise json.JSONDecodeError(f"Invalid JSON in configuration file: {file_path}", "", 0) | |
| 70 | ||
| 71 | def save_to_file(self, file_path: str) -> None: | |
| 72 | """ | |
| 73 | Save configuration to a JSON file. | |
| 74 | ||
| 75 | Args: | |
| 76 | file_path: Path to the configuration file | |
| 77 | ||
| 78 | Raises: | |
| 79 | PermissionError: If the file cannot be written | |
| 80 | """ | |
| 81 | try: | |
| 82 | # Create directory if it doesn't exist | |
| 83 | os.makedirs(os.path.dirname(os.path.abspath(file_path)), exist_ok=True) | |
| 84 | ||
| 85 | with open(file_path, 'w') as f: | |
| 86 | json.dump(self.dict(), f, indent=2) | |
| 87 | except PermissionError: | |
| 88 | raise PermissionError(f"Cannot write to configuration file: {file_path}") | |
| 89 | ||
| 90 | def to_dict(self) -> Dict[str, Any]: | |
| 91 | """ | |
| 92 | Convert configuration to a dictionary. | |
| 93 | ||
| 94 | Returns: | |
| 95 | Dict[str, Any]: Configuration as a dictionary | |
| 96 | """ | |
| 97 | return self.dict(exclude_none=True) | |
| 98 | ||
| 99 | @classmethod | |
| 100 | def default_config_path(cls) -> str: | |
| 101 | """ | |
| 102 | Get the default configuration file path. | |
| 103 | ||
| 104 | Returns: | |
| 105 | str: Default configuration file path | |
| 106 | """ | |
| 107 | return os.path.expanduser("~/.config/ollamatools/config.json") |
| … | … | @@ -0,0 +1,94 @@ |
| 1 | """ | |
| 2 | Permission management system for OllamaTools. | |
| 3 | ||
| 4 | This module provides security controls for executing functions, | |
| 5 | with a focus on a prompt-based permission system. | |
| 6 | """ | |
| 7 | from typing import Dict, Any, Optional | |
| 8 | ||
| 9 | ||
| 10 | class PermissionManager: | |
| 11 | """ | |
| 12 | Manages security permissions for function execution. | |
| 13 | ||
| 14 | The PermissionManager controls access to potentially sensitive | |
| 15 | operations such as executing system commands or making web requests. | |
| 16 | It provides a prompt-based approach to security, allowing users to | |
| 17 | approve or deny operations at runtime. | |
| 18 | ||
| 19 | Attributes: | |
| 20 | prompt_enabled (bool): Whether to prompt for permission before operations | |
| 21 | sudo_always_prompt (bool): Whether to always prompt for sudo commands | |
| 22 | """ | |
| 23 | ||
| 24 | def __init__( | |
| 25 | self, | |
| 26 | prompt_enabled: bool = True, | |
| 27 | sudo_always_prompt: bool = True | |
| 28 | ): | |
| 29 | """ | |
| 30 | Initialize the permission manager. | |
| 31 | ||
| 32 | Args: | |
| 33 | prompt_enabled: Whether to prompt for permissions | |
| 34 | sudo_always_prompt: Whether to always prompt for sudo commands | |
| 35 | """ | |
| 36 | self.prompt_enabled = prompt_enabled | |
| 37 | self.sudo_always_prompt = sudo_always_prompt | |
| 38 | ||
| 39 | def request_permission( | |
| 40 | self, | |
| 41 | function_name: str, | |
| 42 | args: Dict[str, Any], | |
| 43 | is_sudo: bool = False | |
| 44 | ) -> bool: | |
| 45 | """ | |
| 46 | Request permission to execute a function. | |
| 47 | ||
| 48 | This method handles the permission request workflow, which may involve | |
| 49 | prompting the user for approval depending on configuration settings. | |
| 50 | ||
| 51 | Args: | |
| 52 | function_name: Name of the function | |
| 53 | args: Function arguments | |
| 54 | is_sudo: Whether the command uses sudo | |
| 55 | ||
| 56 | Returns: | |
| 57 | bool: True if permission granted, False otherwise | |
| 58 | """ | |
| 59 | # For now, simply print the request and return True | |
| 60 | # Will be enhanced with actual prompting in the future | |
| 61 | ||
| 62 | # Format the arguments as a readable string | |
| 63 | args_str = ', '.join(f"{k}={v!r}" for k, v in args.items()) | |
| 64 | ||
| 65 | # Print information about the permission request | |
| 66 | print(f"Permission request for: {function_name}({args_str})") | |
| 67 | if is_sudo: | |
| 68 | print("Note: This operation requires elevated permissions (sudo)") | |
| 69 | ||
| 70 | # In this basic implementation, always grant permission | |
| 71 | # This will be replaced with actual prompting in step 2.2 | |
| 72 | return True | |
| 73 | ||
| 74 | def detect_sudo(self, command: str) -> bool: | |
| 75 | """ | |
| 76 | Detect if a command uses sudo. | |
| 77 | ||
| 78 | Args: | |
| 79 | command: Command string | |
| 80 | ||
| 81 | Returns: | |
| 82 | bool: True if command uses sudo | |
| 83 | """ | |
| 84 | # Basic detection for sudo command | |
| 85 | if not command: | |
| 86 | return False | |
| 87 | ||
| 88 | # Split the command to handle commands with arguments | |
| 89 | cmd_parts = command.strip().split() | |
| 90 | if not cmd_parts: | |
| 91 | return False | |
| 92 | ||
| 93 | # Check if the command starts with sudo | |
| 94 | return cmd_parts[0].lower() == "sudo" |
| … | … | @@ -0,0 +1,5 @@ |
| 1 | """ | |
| 2 | Function groups for OllamaTools. | |
| 3 | ||
| 4 | This package contains various function groups that can be used by the OllamaAgent. | |
| 5 | """ |
| … | … | @@ -0,0 +1,28 @@ |
| 1 | """ | |
| 2 | Documentation tools for OllamaTools. | |
| 3 | ||
| 4 | This module contains functions for creating and processing documentation. | |
| 5 | """ | |
| 6 | ||
| 7 | ||
| 8 | def generate_markdown( | |
| 9 | content: str, | |
| 10 | title: str, | |
| 11 | format_type: str = 'markdown' | |
| 12 | ) -> str: | |
| 13 | """ | |
| 14 | Generate formatted documentation. | |
| 15 | ||
| 16 | Args: | |
| 17 | content: Document content | |
| 18 | title: Document title | |
| 19 | format_type: Output format ('markdown' or 'html') | |
| 20 | ||
| 21 | Returns: | |
| 22 | str: Formatted documentation | |
| 23 | """ | |
| 24 | # Placeholder implementation | |
| 25 | if format_type == 'markdown': | |
| 26 | return f"# {title}\n\n{content}" | |
| 27 | else: | |
| 28 | return f"<h1>{title}</h1><p>{content}</p>" |
| … | … | @@ -0,0 +1,32 @@ |
| 1 | """ | |
| 2 | System tools for OllamaTools. | |
| 3 | ||
| 4 | This module contains functions for executing system commands and performing | |
| 5 | file operations. | |
| 6 | """ | |
| 7 | ||
| 8 | from typing import Optional, List, Dict, Any | |
| 9 | ||
| 10 | ||
| 11 | def execute_command( | |
| 12 | command: str, | |
| 13 | args: Optional[List[str]] = None, | |
| 14 | timeout: int = 60 | |
| 15 | ) -> Dict[str, Any]: | |
| 16 | """ | |
| 17 | Execute a shell command with arguments. | |
| 18 | ||
| 19 | Args: | |
| 20 | command: Command to execute | |
| 21 | args: Command arguments | |
| 22 | timeout: Command timeout in seconds | |
| 23 | ||
| 24 | Returns: | |
| 25 | dict: Result with stdout, stderr, and exit code | |
| 26 | """ | |
| 27 | # Placeholder implementation | |
| 28 | return { | |
| 29 | "stdout": "Command execution placeholder", | |
| 30 | "stderr": "", | |
| 31 | "exit_code": 0 | |
| 32 | } |
| … | … | @@ -0,0 +1,37 @@ |
| 1 | """ | |
| 2 | Web tools for OllamaTools. | |
| 3 | ||
| 4 | This module contains functions for making web requests and processing responses. | |
| 5 | """ | |
| 6 | ||
| 7 | from typing import Optional, Dict, Any | |
| 8 | ||
| 9 | ||
| 10 | def fetch_url( | |
| 11 | url: str, | |
| 12 | method: str = 'GET', | |
| 13 | params: Optional[Dict[str, str]] = None, | |
| 14 | headers: Optional[Dict[str, str]] = None, | |
| 15 | data: Optional[Dict[str, Any]] = None, | |
| 16 | timeout: int = 30 | |
| 17 | ) -> Dict[str, Any]: | |
| 18 | """ | |
| 19 | Fetch a URL with specified parameters. | |
| 20 | ||
| 21 | Args: | |
| 22 | url: URL to fetch | |
| 23 | method: HTTP method | |
| 24 | params: URL parameters | |
| 25 | headers: HTTP headers | |
| 26 | data: Request data | |
| 27 | timeout: Request timeout in seconds | |
| 28 | ||
| 29 | Returns: | |
| 30 | dict: Response with status, headers, and content | |
| 31 | """ | |
| 32 | # Placeholder implementation | |
| 33 | return { | |
| 34 | "status": 200, | |
| 35 | "headers": {}, | |
| 36 | "content": "URL fetch placeholder" | |
| 37 | } |
| … | … | @@ -0,0 +1,7 @@ |
| 1 | """ | |
| 2 | Utility functions for OllamaTools. | |
| 3 | ||
| 4 | This package contains various utility functions used by the OllamaTools library. | |
| 5 | """ | |
| 6 | ||
| 7 | from ollamatools.utils.logger import get_logger, enable_debug_logging, disable_logging, get_ollamatools_logger |
| … | … | @@ -0,0 +1,144 @@ |
| 1 | """ | |
| 2 | Logging utilities for OllamaTools. | |
| 3 | ||
| 4 | This module contains logging utilities used by the OllamaTools library. | |
| 5 | """ | |
| 6 | ||
| 7 | import logging | |
| 8 | import os | |
| 9 | import sys | |
| 10 | from typing import Optional, Union, Dict, Any, List | |
| 11 | ||
| 12 | ||
| 13 | def get_logger( | |
| 14 | name: str, | |
| 15 | level: Union[int, str] = logging.INFO, | |
| 16 | log_file: Optional[str] = None, | |
| 17 | log_format: Optional[str] = None, | |
| 18 | propagate: bool = False, | |
| 19 | additional_handlers: Optional[List[logging.Handler]] = None, | |
| 20 | extra: Optional[Dict[str, Any]] = None | |
| 21 | ) -> logging.Logger: | |
| 22 | """ | |
| 23 | Get a configured logger instance. | |
| 24 | ||
| 25 | Args: | |
| 26 | name: Logger name | |
| 27 | level: Log level (can be integer or string like 'INFO', 'DEBUG') | |
| 28 | log_file: Optional log file path | |
| 29 | log_format: Optional custom log format | |
| 30 | propagate: Whether to propagate logs to parent loggers | |
| 31 | additional_handlers: Optional list of additional handlers to add | |
| 32 | extra: Optional extra fields to add to all log records | |
| 33 | ||
| 34 | Returns: | |
| 35 | logging.Logger: Configured logger instance | |
| 36 | """ | |
| 37 | # Convert string level to integer if needed | |
| 38 | if isinstance(level, str): | |
| 39 | level = getattr(logging, level.upper()) | |
| 40 | ||
| 41 | # Create or get the logger | |
| 42 | logger = logging.getLogger(name) | |
| 43 | logger.setLevel(level) | |
| 44 | logger.propagate = propagate | |
| 45 | ||
| 46 | # Remove existing handlers to avoid duplicates if the logger already exists | |
| 47 | for handler in logger.handlers[:]: | |
| 48 | logger.removeHandler(handler) | |
| 49 | ||
| 50 | # Default format if none provided | |
| 51 | if log_format is None: | |
| 52 | log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
| 53 | ||
| 54 | formatter = logging.Formatter(log_format) | |
| 55 | ||
| 56 | # Add console handler | |
| 57 | console_handler = logging.StreamHandler(stream=sys.stdout) | |
| 58 | console_handler.setLevel(level) | |
| 59 | console_handler.setFormatter(formatter) | |
| 60 | logger.addHandler(console_handler) | |
| 61 | ||
| 62 | # Add file handler if specified | |
| 63 | if log_file: | |
| 64 | # Create directory if it doesn't exist | |
| 65 | log_dir = os.path.dirname(os.path.abspath(log_file)) | |
| 66 | if log_dir: | |
| 67 | os.makedirs(log_dir, exist_ok=True) | |
| 68 | ||
| 69 | file_handler = logging.FileHandler(log_file) | |
| 70 | file_handler.setLevel(level) | |
| 71 | file_handler.setFormatter(formatter) | |
| 72 | logger.addHandler(file_handler) | |
| 73 | ||
| 74 | # Add any additional handlers | |
| 75 | if additional_handlers: | |
| 76 | for handler in additional_handlers: | |
| 77 | logger.addHandler(handler) | |
| 78 | ||
| 79 | # Add a filter for extra fields if provided | |
| 80 | if extra: | |
| 81 | class ExtraFilter(logging.Filter): | |
| 82 | def filter(self, record): | |
| 83 | for key, value in extra.items(): | |
| 84 | setattr(record, key, value) | |
| 85 | return True | |
| 86 | ||
| 87 | extra_filter = ExtraFilter() | |
| 88 | logger.addFilter(extra_filter) | |
| 89 | ||
| 90 | return logger | |
| 91 | ||
| 92 | ||
| 93 | def enable_debug_logging(logger_names: Optional[List[str]] = None) -> None: | |
| 94 | """ | |
| 95 | Enable debug logging for specified loggers or all loggers. | |
| 96 | ||
| 97 | Args: | |
| 98 | logger_names: Optional list of logger names to enable debug logging for, | |
| 99 | if None, enables for root logger | |
| 100 | """ | |
| 101 | if logger_names is None: | |
| 102 | # Enable debug logging for the root logger | |
| 103 | logging.getLogger().setLevel(logging.DEBUG) | |
| 104 | else: | |
| 105 | # Enable debug logging for specific loggers | |
| 106 | for name in logger_names: | |
| 107 | logging.getLogger(name).setLevel(logging.DEBUG) | |
| 108 | ||
| 109 | ||
| 110 | def disable_logging(logger_names: Optional[List[str]] = None) -> None: | |
| 111 | """ | |
| 112 | Disable logging for specified loggers or all loggers. | |
| 113 | ||
| 114 | Args: | |
| 115 | logger_names: Optional list of logger names to disable logging for, | |
| 116 | if None, disables for root logger | |
| 117 | """ | |
| 118 | if logger_names is None: | |
| 119 | # Disable logging for the root logger | |
| 120 | logging.getLogger().setLevel(logging.CRITICAL + 1) | |
| 121 | else: | |
| 122 | # Disable logging for specific loggers | |
| 123 | for name in logger_names: | |
| 124 | logging.getLogger(name).setLevel(logging.CRITICAL + 1) | |
| 125 | ||
| 126 | ||
| 127 | def get_ollamatools_logger( | |
| 128 | component: str, | |
| 129 | level: Union[int, str] = logging.INFO, | |
| 130 | log_file: Optional[str] = None | |
| 131 | ) -> logging.Logger: | |
| 132 | """ | |
| 133 | Get a logger for a specific OllamaTools component. | |
| 134 | ||
| 135 | Args: | |
| 136 | component: Component name (e.g., 'agent', 'system_tools') | |
| 137 | level: Log level | |
| 138 | log_file: Optional log file path | |
| 139 | ||
| 140 | Returns: | |
| 141 | logging.Logger: Configured logger instance | |
| 142 | """ | |
| 143 | logger_name = f"ollamatools.{component}" | |
| 144 | return get_logger(logger_name, level, log_file) |
| … | … | @@ -0,0 +1,7 @@ |
| 1 | ollama-python>=0.4.0 | |
| 2 | requests>=2.28.0 | |
| 3 | beautifulsoup4>=4.11.0 | |
| 4 | pydantic>=1.10.0 | |
| 5 | markdown>=3.4.0 | |
| 6 | typing-extensions>=4.4.0 | |
| 7 | pytest>=7.0.0 |
| … | … | @@ -0,0 +1,44 @@ |
| 1 | """ | |
| 2 | Setup script for OllamaTools. | |
| 3 | """ | |
| 4 | ||
| 5 | from setuptools import setup, find_packages | |
| 6 | ||
| 7 | setup( | |
| 8 | name="ollamatools", | |
| 9 | version="0.1.0", | |
| 10 | packages=find_packages(), | |
| 11 | install_requires=[ | |
| 12 | "ollama-python>=0.4.0", | |
| 13 | "requests>=2.28.0", | |
| 14 | "beautifulsoup4>=4.11.0", | |
| 15 | "pydantic>=1.10.0", | |
| 16 | "markdown>=3.4.0", | |
| 17 | "typing-extensions>=4.4.0", | |
| 18 | ], | |
| 19 | extras_require={ | |
| 20 | "dev": [ | |
| 21 | "pytest>=7.0.0", | |
| 22 | "pytest-cov>=2.12.1", | |
| 23 | "black>=22.3.0", | |
| 24 | "isort>=5.10.1", | |
| 25 | "flake8>=4.0.1", | |
| 26 | ], | |
| 27 | }, | |
| 28 | python_requires=">=3.8", | |
| 29 | author="Your Name", | |
| 30 | author_email="your.email@example.com", | |
| 31 | description="Function Library for Ollama LLMs", | |
| 32 | long_description=open("README.md").read(), | |
| 33 | long_description_content_type="text/markdown", | |
| 34 | url="https://github.com/yourusername/ollamatools", | |
| 35 | classifiers=[ | |
| 36 | "Development Status :: 3 - Alpha", | |
| 37 | "Intended Audience :: Developers", | |
| 38 | "License :: OSI Approved :: MIT License", | |
| 39 | "Programming Language :: Python :: 3", | |
| 40 | "Programming Language :: Python :: 3.8", | |
| 41 | "Programming Language :: Python :: 3.9", | |
| 42 | "Programming Language :: Python :: 3.10", | |
| 43 | ], | |
| 44 | ) |
| … | … | @@ -0,0 +1,7 @@ |
| 1 | """ | |
| 2 | Utility functions for OllamaTools. | |
| 3 | ||
| 4 | This package contains various utility functions used by the OllamaTools library. | |
| 5 | """ | |
| 6 | ||
| 7 | from ollamatools.utils.logger import get_logger, enable_debug_logging, disable_logging, get_ollamatools_logger |
| … | … | @@ -0,0 +1,149 @@ |
| 1 | """ | |
| 2 | Tests for the configuration module. | |
| 3 | """ | |
| 4 | ||
| 5 | import json | |
| 6 | import os | |
| 7 | import tempfile | |
| 8 | from unittest.mock import patch, mock_open | |
| 9 | ||
| 10 | import pytest | |
| 11 | from pydantic import ValidationError | |
| 12 | ||
| 13 | from ollamatools.config import Config | |
| 14 | ||
| 15 | ||
| 16 | def test_config_defaults(): | |
| 17 | """Test that default configuration values are set correctly.""" | |
| 18 | config = Config() | |
| 19 | assert config.model == "llama3.1" | |
| 20 | assert config.host == "http://localhost:11434" | |
| 21 | assert config.permission_prompts is True | |
| 22 | assert config.sudo_always_prompt is True | |
| 23 | assert config.timeout_seconds == 60 | |
| 24 | assert config.max_file_size is None | |
| 25 | ||
| 26 | ||
| 27 | def test_config_custom_values(): | |
| 28 | """Test that custom configuration values are set correctly.""" | |
| 29 | config = Config( | |
| 30 | model="custom-model", | |
| 31 | host="http://custom-host:11434", | |
| 32 | permission_prompts=False, | |
| 33 | sudo_always_prompt=False, | |
| 34 | timeout_seconds=30, | |
| 35 | max_file_size=1024 | |
| 36 | ) | |
| 37 | assert config.model == "custom-model" | |
| 38 | assert config.host == "http://custom-host:11434" | |
| 39 | assert config.permission_prompts is False | |
| 40 | assert config.sudo_always_prompt is False | |
| 41 | assert config.timeout_seconds == 30 | |
| 42 | assert config.max_file_size == 1024 | |
| 43 | ||
| 44 | ||
| 45 | def test_config_validation(): | |
| 46 | """Test configuration validation.""" | |
| 47 | # Test invalid timeout | |
| 48 | with pytest.raises(ValidationError): | |
| 49 | Config(timeout_seconds=0) | |
| 50 | ||
| 51 | with pytest.raises(ValidationError): | |
| 52 | Config(timeout_seconds=-10) | |
| 53 | ||
| 54 | # Test invalid max_file_size | |
| 55 | with pytest.raises(ValidationError): | |
| 56 | Config(max_file_size=0) | |
| 57 | ||
| 58 | with pytest.raises(ValidationError): | |
| 59 | Config(max_file_size=-1024) | |
| 60 | ||
| 61 | ||
| 62 | def test_config_load_from_file(): | |
| 63 | """Test loading configuration from a file.""" | |
| 64 | config_data = { | |
| 65 | "model": "file-model", | |
| 66 | "host": "http://file-host:11434", | |
| 67 | "permission_prompts": False, | |
| 68 | "sudo_always_prompt": False, | |
| 69 | "timeout_seconds": 45, | |
| 70 | "max_file_size": 2048 | |
| 71 | } | |
| 72 | ||
| 73 | # Mock the open function to return a file-like object | |
| 74 | with patch("builtins.open", mock_open(read_data=json.dumps(config_data))): | |
| 75 | # Mock os.path.exists to return True | |
| 76 | with patch("os.path.exists", return_value=True): | |
| 77 | config = Config.load_from_file("fake_path.json") | |
| 78 | ||
| 79 | assert config.model == "file-model" | |
| 80 | assert config.host == "http://file-host:11434" | |
| 81 | assert config.permission_prompts is False | |
| 82 | assert config.sudo_always_prompt is False | |
| 83 | assert config.timeout_seconds == 45 | |
| 84 | assert config.max_file_size == 2048 | |
| 85 | ||
| 86 | ||
| 87 | def test_config_load_from_file_not_found(): | |
| 88 | """Test loading configuration from a non-existent file.""" | |
| 89 | with patch("os.path.exists", return_value=False): | |
| 90 | with pytest.raises(FileNotFoundError): | |
| 91 | Config.load_from_file("non_existent_file.json") | |
| 92 | ||
| 93 | ||
| 94 | def test_config_load_from_file_invalid_json(): | |
| 95 | """Test loading configuration from a file with invalid JSON.""" | |
| 96 | with patch("builtins.open", mock_open(read_data="invalid json")): | |
| 97 | with patch("os.path.exists", return_value=True): | |
| 98 | with pytest.raises(json.JSONDecodeError): | |
| 99 | Config.load_from_file("invalid_json.json") | |
| 100 | ||
| 101 | ||
| 102 | def test_config_save_to_file(): | |
| 103 | """Test saving configuration to a file.""" | |
| 104 | config = Config( | |
| 105 | model="save-model", | |
| 106 | timeout_seconds=90 | |
| 107 | ) | |
| 108 | ||
| 109 | # Use a temporary file for testing | |
| 110 | with tempfile.NamedTemporaryFile(delete=False) as temp_file: | |
| 111 | temp_path = temp_file.name | |
| 112 | ||
| 113 | try: | |
| 114 | # Save configuration to the temporary file | |
| 115 | config.save_to_file(temp_path) | |
| 116 | ||
| 117 | # Read the saved configuration | |
| 118 | with open(temp_path, 'r') as f: | |
| 119 | saved_data = json.load(f) | |
| 120 | ||
| 121 | # Verify saved data | |
| 122 | assert saved_data["model"] == "save-model" | |
| 123 | assert saved_data["timeout_seconds"] == 90 | |
| 124 | assert saved_data["permission_prompts"] is True # Default value | |
| 125 | finally: | |
| 126 | # Clean up | |
| 127 | if os.path.exists(temp_path): | |
| 128 | os.unlink(temp_path) | |
| 129 | ||
| 130 | ||
| 131 | def test_config_to_dict(): | |
| 132 | """Test converting configuration to a dictionary.""" | |
| 133 | config = Config( | |
| 134 | model="dict-model", | |
| 135 | timeout_seconds=120 | |
| 136 | ) | |
| 137 | ||
| 138 | config_dict = config.to_dict() | |
| 139 | ||
| 140 | assert isinstance(config_dict, dict) | |
| 141 | assert config_dict["model"] == "dict-model" | |
| 142 | assert config_dict["timeout_seconds"] == 120 | |
| 143 | assert config_dict["permission_prompts"] is True # Default value | |
| 144 | ||
| 145 | ||
| 146 | def test_default_config_path(): | |
| 147 | """Test getting the default configuration path.""" | |
| 148 | expected_path = os.path.expanduser("~/.config/ollamatools/config.json") | |
| 149 | assert Config.default_config_path() == expected_path |
| … | … | @@ -0,0 +1,190 @@ |
| 1 | """ | |
| 2 | Tests for the logging utilities. | |
| 3 | """ | |
| 4 | ||
| 5 | import logging | |
| 6 | import os | |
| 7 | import tempfile | |
| 8 | from unittest.mock import patch, MagicMock | |
| 9 | ||
| 10 | import pytest | |
| 11 | ||
| 12 | from ollamatools.utils.logger import get_logger, enable_debug_logging, disable_logging, get_ollamatools_logger | |
| 13 | ||
| 14 | ||
| 15 | def test_get_logger_basic(): | |
| 16 | """Test basic logger creation.""" | |
| 17 | logger = get_logger("test_logger") | |
| 18 | ||
| 19 | assert logger.name == "test_logger" | |
| 20 | assert logger.level == logging.INFO | |
| 21 | assert len(logger.handlers) == 1 # Console handler | |
| 22 | assert isinstance(logger.handlers[0], logging.StreamHandler) | |
| 23 | ||
| 24 | ||
| 25 | def test_get_logger_with_level(): | |
| 26 | """Test logger creation with custom level.""" | |
| 27 | # Test with integer level | |
| 28 | logger_int = get_logger("test_int_level", level=logging.DEBUG) | |
| 29 | assert logger_int.level == logging.DEBUG | |
| 30 | ||
| 31 | # Test with string level | |
| 32 | logger_str = get_logger("test_str_level", level="ERROR") | |
| 33 | assert logger_str.level == logging.ERROR | |
| 34 | ||
| 35 | ||
| 36 | def test_get_logger_with_file(): | |
| 37 | """Test logger creation with file output.""" | |
| 38 | # Use a temporary file for testing | |
| 39 | with tempfile.NamedTemporaryFile(delete=False) as temp_file: | |
| 40 | temp_path = temp_file.name | |
| 41 | ||
| 42 | try: | |
| 43 | logger = get_logger("test_file_logger", log_file=temp_path) | |
| 44 | ||
| 45 | # Check handlers | |
| 46 | assert len(logger.handlers) == 2 # Console + file | |
| 47 | assert isinstance(logger.handlers[1], logging.FileHandler) | |
| 48 | assert logger.handlers[1].baseFilename == temp_path | |
| 49 | ||
| 50 | # Test logging to file | |
| 51 | test_message = "Test file logging" | |
| 52 | logger.info(test_message) | |
| 53 | ||
| 54 | # Verify message was written to file | |
| 55 | with open(temp_path, 'r') as f: | |
| 56 | content = f.read() | |
| 57 | assert test_message in content | |
| 58 | finally: | |
| 59 | # Clean up | |
| 60 | if os.path.exists(temp_path): | |
| 61 | os.unlink(temp_path) | |
| 62 | ||
| 63 | ||
| 64 | def test_get_logger_with_format(): | |
| 65 | """Test logger creation with custom format.""" | |
| 66 | custom_format = '%(levelname)s - %(message)s' | |
| 67 | logger = get_logger("test_format", log_format=custom_format) | |
| 68 | ||
| 69 | # Check formatter | |
| 70 | handler = logger.handlers[0] | |
| 71 | assert handler.formatter._fmt == custom_format | |
| 72 | ||
| 73 | ||
| 74 | def test_get_logger_with_propagate(): | |
| 75 | """Test logger creation with propagation enabled.""" | |
| 76 | logger = get_logger("test_propagate", propagate=True) | |
| 77 | assert logger.propagate is True | |
| 78 | ||
| 79 | logger_no_propagate = get_logger("test_no_propagate", propagate=False) | |
| 80 | assert logger_no_propagate.propagate is False | |
| 81 | ||
| 82 | ||
| 83 | def test_get_logger_with_additional_handlers(): | |
| 84 | """Test logger creation with additional handlers.""" | |
| 85 | mock_handler = MagicMock(spec=logging.Handler) | |
| 86 | # Add required level attribute to mock | |
| 87 | mock_handler.level = logging.INFO | |
| 88 | logger = get_logger("test_handlers", additional_handlers=[mock_handler]) | |
| 89 | ||
| 90 | assert len(logger.handlers) == 2 # Console + mock | |
| 91 | assert logger.handlers[1] == mock_handler | |
| 92 | ||
| 93 | ||
| 94 | def test_get_logger_with_extra(): | |
| 95 | """Test logger creation with extra fields.""" | |
| 96 | extra = {"app_name": "test_app", "environment": "testing"} | |
| 97 | logger = get_logger("test_extra", extra=extra) | |
| 98 | ||
| 99 | # Create a mock handler to capture log records | |
| 100 | mock_handler = MagicMock(spec=logging.Handler) | |
| 101 | # Add the required level attribute to the mock | |
| 102 | mock_handler.level = logging.INFO | |
| 103 | logger.addHandler(mock_handler) | |
| 104 | ||
| 105 | # Log a message | |
| 106 | logger.info("Test message with extra") | |
| 107 | ||
| 108 | # Check extra fields in the log record | |
| 109 | record = mock_handler.handle.call_args[0][0] | |
| 110 | assert record.app_name == "test_app" | |
| 111 | assert record.environment == "testing" | |
| 112 | ||
| 113 | ||
| 114 | def test_enable_debug_logging(): | |
| 115 | """Test enabling debug logging.""" | |
| 116 | # Setup test loggers | |
| 117 | root_logger = logging.getLogger() | |
| 118 | original_root_level = root_logger.level | |
| 119 | ||
| 120 | test_logger1 = logging.getLogger("test_enable1") | |
| 121 | test_logger1.setLevel(logging.INFO) | |
| 122 | ||
| 123 | test_logger2 = logging.getLogger("test_enable2") | |
| 124 | test_logger2.setLevel(logging.WARNING) | |
| 125 | ||
| 126 | try: | |
| 127 | # Test enabling debug for specific loggers | |
| 128 | enable_debug_logging(["test_enable1", "test_enable2"]) | |
| 129 | assert test_logger1.level == logging.DEBUG | |
| 130 | assert test_logger2.level == logging.DEBUG | |
| 131 | ||
| 132 | # Test enabling debug for root logger | |
| 133 | enable_debug_logging() | |
| 134 | assert root_logger.level == logging.DEBUG | |
| 135 | finally: | |
| 136 | # Restore original levels | |
| 137 | root_logger.setLevel(original_root_level) | |
| 138 | test_logger1.setLevel(logging.INFO) | |
| 139 | test_logger2.setLevel(logging.WARNING) | |
| 140 | ||
| 141 | ||
| 142 | def test_disable_logging(): | |
| 143 | """Test disabling logging.""" | |
| 144 | # Setup test loggers | |
| 145 | root_logger = logging.getLogger() | |
| 146 | original_root_level = root_logger.level | |
| 147 | ||
| 148 | test_logger1 = logging.getLogger("test_disable1") | |
| 149 | test_logger1.setLevel(logging.INFO) | |
| 150 | ||
| 151 | test_logger2 = logging.getLogger("test_disable2") | |
| 152 | test_logger2.setLevel(logging.WARNING) | |
| 153 | ||
| 154 | try: | |
| 155 | # Test disabling for specific loggers | |
| 156 | disable_logging(["test_disable1", "test_disable2"]) | |
| 157 | assert test_logger1.level > logging.CRITICAL | |
| 158 | assert test_logger2.level > logging.CRITICAL | |
| 159 | ||
| 160 | # Test disabling for root logger | |
| 161 | disable_logging() | |
| 162 | assert root_logger.level > logging.CRITICAL | |
| 163 | finally: | |
| 164 | # Restore original levels | |
| 165 | root_logger.setLevel(original_root_level) | |
| 166 | test_logger1.setLevel(logging.INFO) | |
| 167 | test_logger2.setLevel(logging.WARNING) | |
| 168 | ||
| 169 | ||
| 170 | def test_get_ollamatools_logger(): | |
| 171 | """Test getting an OllamaTools component logger.""" | |
| 172 | logger = get_ollamatools_logger("agent") | |
| 173 | ||
| 174 | assert logger.name == "ollamatools.agent" | |
| 175 | assert logger.level == logging.INFO | |
| 176 | assert len(logger.handlers) == 1 # Console handler | |
| 177 | ||
| 178 | # Test with custom level and file | |
| 179 | with tempfile.NamedTemporaryFile(delete=False) as temp_file: | |
| 180 | temp_path = temp_file.name | |
| 181 | ||
| 182 | try: | |
| 183 | logger = get_ollamatools_logger("system_tools", level="DEBUG", log_file=temp_path) | |
| 184 | assert logger.name == "ollamatools.system_tools" | |
| 185 | assert logger.level == logging.DEBUG | |
| 186 | assert len(logger.handlers) == 2 # Console + file | |
| 187 | finally: | |
| 188 | # Clean up | |
| 189 | if os.path.exists(temp_path): | |
| 190 | os.unlink(temp_path) |
| … | … | @@ -0,0 +1,60 @@ |
| 1 | """ | |
| 2 | Tests for the permission management system. | |
| 3 | """ | |
| 4 | import pytest | |
| 5 | from ollamatools.security import PermissionManager | |
| 6 | ||
| 7 | ||
| 8 | def test_permission_manager_init(): | |
| 9 | """Test PermissionManager initialization with default and custom parameters.""" | |
| 10 | # Test default initialization | |
| 11 | pm = PermissionManager() | |
| 12 | assert pm.prompt_enabled is True | |
| 13 | assert pm.sudo_always_prompt is True | |
| 14 | ||
| 15 | # Test custom initialization | |
| 16 | pm = PermissionManager(prompt_enabled=False, sudo_always_prompt=False) | |
| 17 | assert pm.prompt_enabled is False | |
| 18 | assert pm.sudo_always_prompt is False | |
| 19 | ||
| 20 | ||
| 21 | def test_request_permission(capfd): | |
| 22 | """Test the basic request_permission method.""" | |
| 23 | pm = PermissionManager() | |
| 24 | ||
| 25 | # Test basic function | |
| 26 | result = pm.request_permission("test_function", {"arg1": "value1"}) | |
| 27 | assert result is True # In basic implementation, should always return True | |
| 28 | ||
| 29 | # Check if appropriate information was printed | |
| 30 | captured = capfd.readouterr() | |
| 31 | assert "Permission request for: test_function" in captured.out | |
| 32 | assert "arg1='value1'" in captured.out | |
| 33 | ||
| 34 | # Test with sudo | |
| 35 | result = pm.request_permission("test_function", {"arg1": "value1"}, is_sudo=True) | |
| 36 | assert result is True | |
| 37 | ||
| 38 | # Check if sudo warning was printed | |
| 39 | captured = capfd.readouterr() | |
| 40 | assert "elevated permissions (sudo)" in captured.out | |
| 41 | ||
| 42 | ||
| 43 | def test_detect_sudo(): | |
| 44 | """Test the detect_sudo method with various commands.""" | |
| 45 | pm = PermissionManager() | |
| 46 | ||
| 47 | # Test sudo commands | |
| 48 | assert pm.detect_sudo("sudo ls -la") is True | |
| 49 | assert pm.detect_sudo("sudo apt update") is True | |
| 50 | assert pm.detect_sudo("SUDO rm -rf /") is True # Case insensitive check | |
| 51 | ||
| 52 | # Test non-sudo commands | |
| 53 | assert pm.detect_sudo("ls -la") is False | |
| 54 | assert pm.detect_sudo("apt update") is False | |
| 55 | assert pm.detect_sudo("echo 'sudo is not at start'") is False | |
| 56 | ||
| 57 | # Test edge cases | |
| 58 | assert pm.detect_sudo("") is False | |
| 59 | assert pm.detect_sudo(" ") is False | |
| 60 | assert pm.detect_sudo(None) is False |
| … | … | @@ -0,0 +1,587 @@ |
| 1 | # OllamaTools: Function Library for Ollama LLMs | |
| 2 | ||
| 3 | ## Technical Specification Document | |
| 4 | ||
| 5 | ### 1. Project Overview | |
| 6 | ||
| 7 | **Project Name:** OllamaTools | |
| 8 | ||
| 9 | **Description:** A Python library that extends Ollama with semantic function calling capabilities, enabling automatic invocation of system commands, web requests, and documentation utilities based on conversational context. | |
| 10 | ||
| 11 | **Primary Goal:** Allow Ollama LLMs to execute external functions based on semantic understanding of user queries without requiring explicit enabling/disabling of tools. | |
| 12 | ||
| 13 | ### 2. System Requirements | |
| 14 | ||
| 15 | #### 2.1 Software Requirements | |
| 16 | - Python 3.8+ | |
| 17 | - Ollama 0.4.0+ with function calling support | |
| 18 | - Linux-based operating system (primary target) | |
| 19 | - Optional: Windows/macOS support may be added in future releases | |
| 20 | ||
| 21 | #### 2.2 Dependencies | |
| 22 | - ollama-python >= 0.4.0 | |
| 23 | - requests >= 2.28.0 | |
| 24 | - beautifulsoup4 >= 4.11.0 | |
| 25 | - pydantic >= 1.10.0 | |
| 26 | - markdown >= 3.4.0 | |
| 27 | - typing-extensions >= 4.4.0 | |
| 28 | - pytest >= 7.0.0 (for testing) | |
| 29 | ||
| 30 | ### 3. Architecture | |
| 31 | ||
| 32 | #### 3.1 System Architecture | |
| 33 | OllamaTools is designed as a Python package that extends the functionality of the official Ollama Python client, adding semantic function detection and execution capabilities. | |
| 34 | ||
| 35 | ``` | |
| 36 | OllamaTools/ | |
| 37 | ├── ollamatools/ | |
| 38 | │ ├── __init__.py | |
| 39 | │ ├── agent.py # Main agent interface | |
| 40 | │ ├── security.py # Permission management | |
| 41 | │ ├── config.py # Configuration management | |
| 42 | │ ├── tools/ # Function groups | |
| 43 | │ │ ├── __init__.py | |
| 44 | │ │ ├── system_tools.py # Linux command execution | |
| 45 | │ │ ├── web_tools.py # Web requests | |
| 46 | │ │ └── doc_tools.py # Documentation utilities | |
| 47 | │ └── utils/ | |
| 48 | │ ├── __init__.py | |
| 49 | │ └── logger.py # Logging utilities | |
| 50 | ├── tests/ # Unit and integration tests | |
| 51 | ├── examples/ # Example scripts | |
| 52 | ├── README.md | |
| 53 | ├── LICENSE | |
| 54 | ├── setup.py | |
| 55 | └── requirements.txt | |
| 56 | ``` | |
| 57 | ||
| 58 | #### 3.2 Core Components | |
| 59 | ||
| 60 | 1. **OllamaAgent**: Primary interface that manages communication with Ollama and handles function detection and execution. | |
| 61 | ||
| 62 | 2. **PermissionManager**: Handles security and permissions for executing functions, especially system commands. | |
| 63 | ||
| 64 | 3. **Function Libraries**: | |
| 65 | - System Tools: Execute Linux commands and file operations | |
| 66 | - Web Tools: Make web requests and process responses | |
| 67 | - Documentation Tools: Generate and process documentation | |
| 68 | ||
| 69 | ### 4. Detailed Component Specifications | |
| 70 | ||
| 71 | #### 4.1 OllamaAgent | |
| 72 | ||
| 73 | The OllamaAgent class serves as the main entry point for the library. It extends the standard Ollama client with function execution capabilities. | |
| 74 | ||
| 75 | ```python | |
| 76 | class OllamaAgent: | |
| 77 | def __init__( | |
| 78 | self, | |
| 79 | model: str = "llama3.1", | |
| 80 | host: str = "http://localhost:11434", | |
| 81 | permission_prompts: bool = True, | |
| 82 | sudo_always_prompt: bool = True | |
| 83 | ): | |
| 84 | """ | |
| 85 | Initialize the OllamaAgent with specified configuration. | |
| 86 | ||
| 87 | Args: | |
| 88 | model: Name of the Ollama model to use | |
| 89 | host: Ollama server address | |
| 90 | permission_prompts: Whether to prompt for function execution permission | |
| 91 | sudo_always_prompt: Whether to always prompt for sudo commands | |
| 92 | """ | |
| 93 | ||
| 94 | def chat( | |
| 95 | self, | |
| 96 | message: str, | |
| 97 | system_prompt: Optional[str] = None, | |
| 98 | context: Optional[List[Dict[str, str]]] = None | |
| 99 | ) -> str: | |
| 100 | """ | |
| 101 | Send a message to Ollama, automatically detecting and executing functions. | |
| 102 | ||
| 103 | Args: | |
| 104 | message: User message | |
| 105 | system_prompt: Optional system prompt | |
| 106 | context: Optional conversation context | |
| 107 | ||
| 108 | Returns: | |
| 109 | str: Response from Ollama, potentially after executing functions | |
| 110 | """ | |
| 111 | ||
| 112 | def register_tools(self): | |
| 113 | """ | |
| 114 | Register all available tools with the Ollama client. | |
| 115 | """ | |
| 116 | ||
| 117 | def process_function_calls( | |
| 118 | self, | |
| 119 | function_calls: List[Dict[str, Any]] | |
| 120 | ) -> List[Dict[str, Any]]: | |
| 121 | """ | |
| 122 | Process function calls detected by Ollama. | |
| 123 | ||
| 124 | Args: | |
| 125 | function_calls: List of function calls from Ollama | |
| 126 | ||
| 127 | Returns: | |
| 128 | List of function call results | |
| 129 | """ | |
| 130 | ``` | |
| 131 | ||
| 132 | #### 4.2 PermissionManager | |
| 133 | ||
| 134 | The PermissionManager handles security for function execution, with a focus on a prompt-based approach. | |
| 135 | ||
| 136 | ```python | |
| 137 | class PermissionManager: | |
| 138 | def __init__( | |
| 139 | self, | |
| 140 | prompt_enabled: bool = True, | |
| 141 | sudo_always_prompt: bool = True | |
| 142 | ): | |
| 143 | """ | |
| 144 | Initialize the permission manager. | |
| 145 | ||
| 146 | Args: | |
| 147 | prompt_enabled: Whether to prompt for permissions | |
| 148 | sudo_always_prompt: Whether to always prompt for sudo commands | |
| 149 | """ | |
| 150 | ||
| 151 | def request_permission( | |
| 152 | self, | |
| 153 | function_name: str, | |
| 154 | args: Dict[str, Any], | |
| 155 | is_sudo: bool = False | |
| 156 | ) -> bool: | |
| 157 | """ | |
| 158 | Request permission to execute a function. | |
| 159 | ||
| 160 | Args: | |
| 161 | function_name: Name of the function | |
| 162 | args: Function arguments | |
| 163 | is_sudo: Whether the command uses sudo | |
| 164 | ||
| 165 | Returns: | |
| 166 | bool: True if permission granted | |
| 167 | """ | |
| 168 | ||
| 169 | def detect_sudo(self, command: str) -> bool: | |
| 170 | """ | |
| 171 | Detect if a command uses sudo. | |
| 172 | ||
| 173 | Args: | |
| 174 | command: Command string | |
| 175 | ||
| 176 | Returns: | |
| 177 | bool: True if command uses sudo | |
| 178 | """ | |
| 179 | ``` | |
| 180 | ||
| 181 | #### 4.3 System Tools | |
| 182 | ||
| 183 | System tools provide functions to execute Linux commands and perform file operations. | |
| 184 | ||
| 185 | ```python | |
| 186 | def execute_command( | |
| 187 | command: str, | |
| 188 | args: Optional[List[str]] = None, | |
| 189 | timeout: int = 60 | |
| 190 | ) -> Dict[str, Any]: | |
| 191 | """ | |
| 192 | Execute a shell command with arguments. | |
| 193 | ||
| 194 | Args: | |
| 195 | command: Command to execute | |
| 196 | args: Command arguments | |
| 197 | timeout: Command timeout in seconds | |
| 198 | ||
| 199 | Returns: | |
| 200 | dict: Result with stdout, stderr, and exit code | |
| 201 | """ | |
| 202 | ||
| 203 | def read_file( | |
| 204 | path: str, | |
| 205 | max_size: Optional[int] = None | |
| 206 | ) -> str: | |
| 207 | """ | |
| 208 | Read file contents. | |
| 209 | ||
| 210 | Args: | |
| 211 | path: File path | |
| 212 | max_size: Maximum file size to read in bytes | |
| 213 | ||
| 214 | Returns: | |
| 215 | str: File contents | |
| 216 | """ | |
| 217 | ||
| 218 | def write_file( | |
| 219 | path: str, | |
| 220 | content: str, | |
| 221 | mode: str = 'w' | |
| 222 | ) -> bool: | |
| 223 | """ | |
| 224 | Write content to a file. | |
| 225 | ||
| 226 | Args: | |
| 227 | path: File path | |
| 228 | content: Content to write | |
| 229 | mode: Write mode ('w' for write, 'a' for append) | |
| 230 | ||
| 231 | Returns: | |
| 232 | bool: True if successful | |
| 233 | """ | |
| 234 | ||
| 235 | def find_files( | |
| 236 | pattern: str, | |
| 237 | directory: str = '.', | |
| 238 | recursive: bool = True | |
| 239 | ) -> List[str]: | |
| 240 | """ | |
| 241 | Find files matching a pattern. | |
| 242 | ||
| 243 | Args: | |
| 244 | pattern: File pattern | |
| 245 | directory: Search directory | |
| 246 | recursive: Whether to search recursively | |
| 247 | ||
| 248 | Returns: | |
| 249 | List[str]: Matching file paths | |
| 250 | """ | |
| 251 | ``` | |
| 252 | ||
| 253 | #### 4.4 Web Tools | |
| 254 | ||
| 255 | Web tools provide functions for making web requests and processing responses. | |
| 256 | ||
| 257 | ```python | |
| 258 | def fetch_url( | |
| 259 | url: str, | |
| 260 | method: str = 'GET', | |
| 261 | params: Optional[Dict[str, str]] = None, | |
| 262 | headers: Optional[Dict[str, str]] = None, | |
| 263 | data: Optional[Dict[str, Any]] = None, | |
| 264 | timeout: int = 30 | |
| 265 | ) -> Dict[str, Any]: | |
| 266 | """ | |
| 267 | Fetch a URL with specified parameters. | |
| 268 | ||
| 269 | Args: | |
| 270 | url: URL to fetch | |
| 271 | method: HTTP method | |
| 272 | params: URL parameters | |
| 273 | headers: HTTP headers | |
| 274 | data: Request data | |
| 275 | timeout: Request timeout in seconds | |
| 276 | ||
| 277 | Returns: | |
| 278 | dict: Response with status, headers, and content | |
| 279 | """ | |
| 280 | ||
| 281 | def get_weather( | |
| 282 | location: str, | |
| 283 | days: int = 3, | |
| 284 | units: str = 'metric' | |
| 285 | ) -> Dict[str, Any]: | |
| 286 | """ | |
| 287 | Get weather information for a location. | |
| 288 | ||
| 289 | Args: | |
| 290 | location: Location name or coordinates | |
| 291 | days: Number of forecast days | |
| 292 | units: Temperature units ('metric' or 'imperial') | |
| 293 | ||
| 294 | Returns: | |
| 295 | dict: Weather information | |
| 296 | """ | |
| 297 | ||
| 298 | def search_web( | |
| 299 | query: str, | |
| 300 | num_results: int = 5 | |
| 301 | ) -> List[Dict[str, str]]: | |
| 302 | """ | |
| 303 | Search the web for a query. | |
| 304 | ||
| 305 | Args: | |
| 306 | query: Search query | |
| 307 | num_results: Number of results to return | |
| 308 | ||
| 309 | Returns: | |
| 310 | List[dict]: Search results with title, URL, and snippet | |
| 311 | """ | |
| 312 | ``` | |
| 313 | ||
| 314 | #### 4.5 Documentation Tools | |
| 315 | ||
| 316 | Documentation tools provide functions for creating and processing documentation. | |
| 317 | ||
| 318 | ```python | |
| 319 | def generate_markdown( | |
| 320 | content: str, | |
| 321 | title: str, | |
| 322 | format_type: str = 'markdown' | |
| 323 | ) -> str: | |
| 324 | """ | |
| 325 | Generate formatted documentation. | |
| 326 | ||
| 327 | Args: | |
| 328 | content: Document content | |
| 329 | title: Document title | |
| 330 | format_type: Output format ('markdown' or 'html') | |
| 331 | ||
| 332 | Returns: | |
| 333 | str: Formatted documentation | |
| 334 | """ | |
| 335 | ||
| 336 | def extract_context( | |
| 337 | query: str, | |
| 338 | documents: List[str], | |
| 339 | max_length: int = 1000 | |
| 340 | ) -> str: | |
| 341 | """ | |
| 342 | Extract relevant context from documents based on a query. | |
| 343 | ||
| 344 | Args: | |
| 345 | query: Search query | |
| 346 | documents: List of document contents | |
| 347 | max_length: Maximum context length | |
| 348 | ||
| 349 | Returns: | |
| 350 | str: Extracted context | |
| 351 | """ | |
| 352 | ||
| 353 | def summarize_text( | |
| 354 | text: str, | |
| 355 | max_length: int = 500 | |
| 356 | ) -> str: | |
| 357 | """ | |
| 358 | Generate a summary of text. | |
| 359 | ||
| 360 | Args: | |
| 361 | text: Text to summarize | |
| 362 | max_length: Maximum summary length | |
| 363 | ||
| 364 | Returns: | |
| 365 | str: Text summary | |
| 366 | """ | |
| 367 | ``` | |
| 368 | ||
| 369 | ### 5. Security Considerations | |
| 370 | ||
| 371 | #### 5.1 Permission System | |
| 372 | ||
| 373 | The permission system is designed to be secure by default while allowing flexibility. | |
| 374 | ||
| 375 | 1. **Prompt-Based Permissions**: | |
| 376 | - By default, prompts user for permission before executing potentially sensitive operations | |
| 377 | - Clear, informative prompts explaining the operation and potential risks | |
| 378 | - Option to disable prompts for non-sudo commands through configuration | |
| 379 | ||
| 380 | 2. **Special Handling for Sudo**: | |
| 381 | - Sudo commands always require permission by default | |
| 382 | - This behavior can be configured but is separate from the general permission setting | |
| 383 | ||
| 384 | 3. **Permission Response Options**: | |
| 385 | - Allow: Grant permission for this operation | |
| 386 | - Allow for session: Grant permission for similar operations in this session | |
| 387 | - Deny: Reject the operation | |
| 388 | - Modify: Allow modifying the operation before execution | |
| 389 | ||
| 390 | #### 5.2 Command Execution Security | |
| 391 | ||
| 392 | 1. **Sanitization**: | |
| 393 | - All command inputs are sanitized to prevent injection attacks | |
| 394 | - Arguments are properly escaped and validated | |
| 395 | ||
| 396 | 2. **Timeouts**: | |
| 397 | - Commands have configurable timeouts to prevent hanging processes | |
| 398 | ||
| 399 | 3. **Resource Limits**: | |
| 400 | - Options to limit resource usage (CPU, memory) for commands | |
| 401 | ||
| 402 | ### 6. Error Handling | |
| 403 | ||
| 404 | #### 6.1 Error Types | |
| 405 | ||
| 406 | 1. **PermissionError**: Raised when permission is denied for an operation | |
| 407 | 2. **CommandExecutionError**: Raised when a command fails to execute | |
| 408 | 3. **WebRequestError**: Raised when a web request fails | |
| 409 | 4. **TimeoutError**: Raised when an operation times out | |
| 410 | 5. **ValidationError**: Raised when input validation fails | |
| 411 | ||
| 412 | #### 6.2 Error Handling Strategy | |
| 413 | ||
| 414 | 1. **Graceful Degradation**: | |
| 415 | - When a function fails, the system attempts to continue with alternative approaches | |
| 416 | - Clear error messages are provided to the user | |
| 417 | ||
| 418 | 2. **Detailed Logging**: | |
| 419 | - All errors are logged with detailed information | |
| 420 | - Optional debug mode for extensive logging | |
| 421 | ||
| 422 | 3. **User Feedback**: | |
| 423 | - Informative error messages returned to the user | |
| 424 | - Suggestions for resolving common errors | |
| 425 | ||
| 426 | ### 7. Testing Strategy | |
| 427 | ||
| 428 | #### 7.1 Unit Testing | |
| 429 | ||
| 430 | 1. **Component Tests**: | |
| 431 | - Tests for each individual function | |
| 432 | - Tests for error handling and edge cases | |
| 433 | - Mocked dependencies for isolated testing | |
| 434 | ||
| 435 | 2. **Security Tests**: | |
| 436 | - Tests for permission system | |
| 437 | - Tests for command sanitization | |
| 438 | - Tests for input validation | |
| 439 | ||
| 440 | #### 7.2 Integration Testing | |
| 441 | ||
| 442 | 1. **Function Integration**: | |
| 443 | - Tests for function detection and execution | |
| 444 | - Tests for proper function argument passing | |
| 445 | - Tests for result handling | |
| 446 | ||
| 447 | 2. **Ollama Integration**: | |
| 448 | - Tests for integration with the Ollama API | |
| 449 | - Tests with different models and configurations | |
| 450 | ||
| 451 | #### 7.3 System Testing | |
| 452 | ||
| 453 | 1. **End-to-End Tests**: | |
| 454 | - Complete workflow tests with realistic scenarios | |
| 455 | - Performance testing under various conditions | |
| 456 | ||
| 457 | 2. **Security Auditing**: | |
| 458 | - Systematic security review of command execution | |
| 459 | - Testing of permission system effectiveness | |
| 460 | ||
| 461 | ### 8. Implementation Guidelines | |
| 462 | ||
| 463 | #### 8.1 Coding Standards | |
| 464 | ||
| 465 | 1. **Code Style**: | |
| 466 | - Follow PEP 8 for Python code style | |
| 467 | - Use type hints for all functions | |
| 468 | - Document all functions with detailed docstrings | |
| 469 | ||
| 470 | 2. **Error Handling**: | |
| 471 | - Use appropriate exception classes | |
| 472 | - Provide informative error messages | |
| 473 | - Log all errors with context | |
| 474 | ||
| 475 | 3. **Testing**: | |
| 476 | - Write tests for all functions | |
| 477 | - Aim for high test coverage | |
| 478 | - Include edge cases and error conditions | |
| 479 | ||
| 480 | #### 8.2 Documentation | |
| 481 | ||
| 482 | 1. **Code Documentation**: | |
| 483 | - Detailed docstrings for all public functions | |
| 484 | - Module-level documentation explaining purpose and usage | |
| 485 | - Inline comments for complex code sections | |
| 486 | ||
| 487 | 2. **User Documentation**: | |
| 488 | - Installation and setup guide | |
| 489 | - API reference | |
| 490 | - Usage examples | |
| 491 | - Security best practices | |
| 492 | ||
| 493 | ### 9. Usage Examples | |
| 494 | ||
| 495 | #### 9.1 Basic Usage | |
| 496 | ||
| 497 | ```python | |
| 498 | from ollamatools import OllamaAgent | |
| 499 | ||
| 500 | # Create agent with default settings | |
| 501 | agent = OllamaAgent(model="llama3.1") | |
| 502 | ||
| 503 | # Chat with automatic function detection | |
| 504 | response = agent.chat("What's the weather like in San Francisco?") | |
| 505 | print(response) | |
| 506 | ||
| 507 | # Execute a system command | |
| 508 | response = agent.chat("Show me the largest files in the current directory") | |
| 509 | print(response) | |
| 510 | ||
| 511 | # Generate documentation | |
| 512 | response = agent.chat("Create documentation for a function that calculates prime numbers") | |
| 513 | print(response) | |
| 514 | ``` | |
| 515 | ||
| 516 | #### 9.2 Configuration | |
| 517 | ||
| 518 | ```python | |
| 519 | from ollamatools import OllamaAgent, Config | |
| 520 | ||
| 521 | # Configure the agent | |
| 522 | config = Config() | |
| 523 | config.permission_prompts = False # Disable permission prompts | |
| 524 | config.sudo_always_prompt = True # Still prompt for sudo commands | |
| 525 | ||
| 526 | # Create agent with configuration | |
| 527 | agent = OllamaAgent(model="llama3.1", config=config) | |
| 528 | ||
| 529 | # Use configured agent | |
| 530 | response = agent.chat("Count the number of files in /etc") | |
| 531 | print(response) | |
| 532 | ``` | |
| 533 | ||
| 534 | ### 10. Implementation Plan | |
| 535 | ||
| 536 | #### 10.1 Phase 1: Core Infrastructure | |
| 537 | - Set up project structure | |
| 538 | - Implement basic OllamaAgent | |
| 539 | - Implement permission system | |
| 540 | - Implement configuration management | |
| 541 | ||
| 542 | #### 10.2 Phase 2: System Tools | |
| 543 | - Implement command execution | |
| 544 | - Implement file operations | |
| 545 | - Add security features | |
| 546 | - Test system integration | |
| 547 | ||
| 548 | #### 10.3 Phase 3: Web Tools | |
| 549 | - Implement web request functions | |
| 550 | - Implement weather API | |
| 551 | - Implement web search | |
| 552 | - Test web integration | |
| 553 | ||
| 554 | #### 10.4 Phase 4: Documentation Tools | |
| 555 | - Implement markdown generation | |
| 556 | - Implement context extraction | |
| 557 | - Implement summarization | |
| 558 | - Test documentation integration | |
| 559 | ||
| 560 | #### 10.5 Phase 5: Testing and Refinement | |
| 561 | - Comprehensive testing | |
| 562 | - Performance optimization | |
| 563 | - Security auditing | |
| 564 | - Documentation completion | |
| 565 | ||
| 566 | ### 11. Extension Points | |
| 567 | ||
| 568 | The library is designed to be extensible in the following ways: | |
| 569 | ||
| 570 | 1. **Custom Tool Addition**: | |
| 571 | - Create new tool modules by adding Python files to the tools directory | |
| 572 | - Use docstrings and type hints for automatic registration | |
| 573 | - Follow the existing tool pattern for consistency | |
| 574 | ||
| 575 | 2. **Custom Permission Handlers**: | |
| 576 | - Extend or replace the permission system with custom implementations | |
| 577 | - Implement the PermissionManager interface | |
| 578 | ||
| 579 | 3. **Integration with Other Systems**: | |
| 580 | - Add adapters for other AI systems | |
| 581 | - Extend to support additional platforms | |
| 582 | ||
| 583 | ### 12. Conclusion | |
| 584 | ||
| 585 | This specification outlines the design and implementation of the OllamaTools library, a Python package that extends Ollama with semantic function calling capabilities. By following this specification, developers can create a robust, secure, and flexible library that enhances Ollama's capabilities with system command execution, web requests, and documentation utilities. | |
| 586 | ||
| 587 | The implementation should prioritize security, ease of use, and extensibility, while maintaining compatibility with the existing Ollama ecosystem. The prompt-based permission system ensures security while allowing users to disable prompts for convenience when appropriate. |
| … | … | @@ -0,0 +1,338 @@ |
| 1 | # OllamaTools: Building a Secure and Effective Function Calling Library for LLMs | |
| 2 | ||
| 3 | **White Paper** | |
| 4 | ||
| 5 | **Abstract** | |
| 6 | ||
| 7 | This white paper explores OllamaTools, a Python library that extends Ollama with semantic function calling capabilities. We analyze the library's architecture, security framework, and implementation approach, with a focus on identifying potential challenges and solutions. By examining current practices in LLM agent development and security, we propose an iterative development roadmap that prioritizes both functionality and safety. This paper will benefit developers and organizations looking to implement secure, effective function calling systems for local large language models. | |
| 8 | ||
| 9 | ## 1. Introduction | |
| 10 | ||
| 11 | The integration of large language models (LLMs) with external tools through function calling represents a significant advancement in AI capabilities. Function calling allows LLMs to interact with external systems, execute commands, and access real-time information beyond their training data. While commercial LLM providers like OpenAI and Anthropic have established function calling frameworks, the open-source community has been developing similar capabilities for locally-run models. | |
| 12 | ||
| 13 | Ollama, a popular framework for running LLMs locally, has recently introduced function calling capabilities in its Python library (version 0.4.0+). OllamaTools builds upon this foundation to create a more comprehensive framework that enables semantic understanding and execution of system commands, web requests, and documentation utilities based on conversational context. | |
| 14 | ||
| 15 | This white paper examines the proposed OllamaTools library, identifies key challenges and security considerations, and provides a roadmap for iterative development to enhance both functionality and security. | |
| 16 | ||
| 17 | ## 2. Current State of Function Calling in Ollama | |
| 18 | ||
| 19 | Ollama's Python library (version 0.4.0+) now supports function calling through a tools interface. This implementation allows developers to pass Python functions as tools to the model, enabling integration between code and language models by annotating parameter and return value types with docstrings for better results. | |
| 20 | ||
| 21 | The current implementation requires developers to: | |
| 22 | ||
| 23 | 1. Define regular Python functions with proper type annotations | |
| 24 | 2. Pass these functions as tools to Ollama in the chat request | |
| 25 | 3. Process the model's response to identify function calls | |
| 26 | 4. Execute the identified functions with the arguments provided by the model | |
| 27 | ||
| 28 | This approach provides basic function calling capabilities but lacks a comprehensive framework for security, permission management, and seamless integration with system commands and web services. | |
| 29 | ||
| 30 | ## 3. OllamaTools: Architecture and Key Components | |
| 31 | ||
| 32 | The proposed OllamaTools library extends the basic function calling capabilities of Ollama with a more structured and secure framework. Its architecture consists of several key components: | |
| 33 | ||
| 34 | ### 3.1 OllamaAgent | |
| 35 | ||
| 36 | The OllamaAgent serves as the main interface, managing communication with Ollama and handling function detection and execution. It extends the standard Ollama client with: | |
| 37 | ||
| 38 | - Tool registration and management | |
| 39 | - Security and permission controls | |
| 40 | - Context management for conversations | |
| 41 | - Automated function execution based on semantic understanding | |
| 42 | ||
| 43 | ### 3.2 PermissionManager | |
| 44 | ||
| 45 | The PermissionManager handles security and permissions for executing functions, with a focus on system commands. It implements: | |
| 46 | ||
| 47 | - Prompt-based permission requests | |
| 48 | - Special handling for sudo commands | |
| 49 | - Session-based permission management | |
| 50 | - Command sanitization and validation | |
| 51 | ||
| 52 | ### 3.3 Function Libraries | |
| 53 | ||
| 54 | OllamaTools provides several function libraries: | |
| 55 | ||
| 56 | - **System Tools**: Execute Linux commands, read/write files, and perform file operations | |
| 57 | - **Web Tools**: Make web requests, retrieve weather information, and search the web | |
| 58 | - **Documentation Tools**: Generate documentation, extract context, and summarize text | |
| 59 | ||
| 60 | ## 4. Security Challenges and Solutions | |
| 61 | ||
| 62 | ### 4.1 Command Execution Risks | |
| 63 | ||
| 64 | The execution of system commands poses significant security risks. Recent research has shown that LLM agents can exploit cybersecurity vulnerabilities using various approaches, including leveraging agent integration for remote code execution. This highlights the critical importance of implementing robust security measures. | |
| 65 | ||
| 66 | **Challenges:** | |
| 67 | ||
| 68 | 1. Command injection attacks | |
| 69 | 2. Privilege escalation through sudo | |
| 70 | 3. Resource exhaustion | |
| 71 | 4. Information disclosure | |
| 72 | 5. System damage through destructive commands | |
| 73 | ||
| 74 | **Proposed Solutions:** | |
| 75 | ||
| 76 | 1. **Sandbox Execution Environment**: Implement container-based isolation for command execution to limit potential damage. | |
| 77 | ||
| 78 | 2. **Command Sanitization and Validation**: Thoroughly validate and sanitize all command inputs to prevent injection attacks. | |
| 79 | ||
| 80 | 3. **Least Privilege Principle**: Limit the functionality and permissions of LLM agents to the minimum necessary for their intended purpose. | |
| 81 | ||
| 82 | 4. **Permission System Enhancements**: Implement a multi-layered permission system: | |
| 83 | - Global permissions (configured by the user) | |
| 84 | - Session-specific permissions | |
| 85 | - Command-specific permissions | |
| 86 | - Resource limit controls | |
| 87 | ||
| 88 | 5. **Secure Input Handling**: Implement fine-grained prompt control instead of allowing free-text prompts, designing templates or guided input frameworks to reduce the risk of malicious commands. | |
| 89 | ||
| 90 | ### 4.2 Web Tool Security | |
| 91 | ||
| 92 | Web tools present different security challenges related to data privacy, API authentication, and potential misuse of external services. | |
| 93 | ||
| 94 | **Challenges:** | |
| 95 | ||
| 96 | 1. API key exposure | |
| 97 | 2. Data privacy concerns with third-party services | |
| 98 | 3. Rate limiting and service abuse | |
| 99 | 4. Request forgery attacks | |
| 100 | 5. Information leakage through web queries | |
| 101 | ||
| 102 | **Proposed Solutions:** | |
| 103 | ||
| 104 | 1. **API Key Management**: Implement secure storage and handling of API keys. | |
| 105 | ||
| 106 | 2. **Request Validation**: Validate all outgoing requests to prevent request forgery. | |
| 107 | ||
| 108 | 3. **Rate Limiting**: Implement rate limiting to prevent abuse of external services. | |
| 109 | ||
| 110 | 4. **Data Privacy Controls**: Provide options to limit the types of data sent to external services. | |
| 111 | ||
| 112 | 5. **Logging and Monitoring**: Log all web requests for security auditing and monitoring. | |
| 113 | ||
| 114 | ## 5. Iterative Development Approach | |
| 115 | ||
| 116 | Developing a secure and effective function calling library requires an iterative approach that gradually enhances functionality while maintaining security. We propose the following phased development roadmap: | |
| 117 | ||
| 118 | ### 5.1 Phase 1: Core Infrastructure (MVP) | |
| 119 | ||
| 120 | **Focus Areas:** | |
| 121 | - Basic OllamaAgent implementation | |
| 122 | - Simple permission system (prompt-based) | |
| 123 | - Limited set of safe system commands | |
| 124 | - Logging and error handling | |
| 125 | ||
| 126 | **Security Measures:** | |
| 127 | - Command whitelist | |
| 128 | - Basic sanitization | |
| 129 | - Prompt-based permissions for all operations | |
| 130 | ||
| 131 | **Evaluation Metrics:** | |
| 132 | - Function call success rate | |
| 133 | - Permission system effectiveness | |
| 134 | - User experience with permission prompts | |
| 135 | ||
| 136 | ### 5.2 Phase 2: Enhanced Security Framework | |
| 137 | ||
| 138 | **Focus Areas:** | |
| 139 | - Advanced permission system | |
| 140 | - Improved command sanitization | |
| 141 | - Sandboxed execution environment | |
| 142 | - Session-based permissions | |
| 143 | ||
| 144 | **Security Measures:** | |
| 145 | - Comprehensive command validation | |
| 146 | - Execution isolation | |
| 147 | - Resource limitations | |
| 148 | - Detailed security logging | |
| 149 | ||
| 150 | **Evaluation Metrics:** | |
| 151 | - Security penetration testing results | |
| 152 | - Permission system usability | |
| 153 | - Command execution safety metrics | |
| 154 | ||
| 155 | ### 5.3 Phase 3: Expanded Tool Set | |
| 156 | ||
| 157 | **Focus Areas:** | |
| 158 | - Full system tools implementation | |
| 159 | - Web tools integration | |
| 160 | - Documentation tools | |
| 161 | - Custom tool registration framework | |
| 162 | ||
| 163 | **Security Measures:** | |
| 164 | - Tool-specific security controls | |
| 165 | - API key management | |
| 166 | - Data privacy controls | |
| 167 | ||
| 168 | **Evaluation Metrics:** | |
| 169 | - Tool usage statistics | |
| 170 | - Security incidents | |
| 171 | - User feedback on tool effectiveness | |
| 172 | ||
| 173 | ### 5.4 Phase 4: Advanced Features | |
| 174 | ||
| 175 | **Focus Areas:** | |
| 176 | - Multi-agent coordination | |
| 177 | - Memory and context management | |
| 178 | - Advanced planning capabilities | |
| 179 | - Tool composition for complex tasks | |
| 180 | ||
| 181 | **Security Measures:** | |
| 182 | - Agent interaction controls | |
| 183 | - Context validation | |
| 184 | - Plan validation and safety checks | |
| 185 | ||
| 186 | **Evaluation Metrics:** | |
| 187 | - Task completion success rates | |
| 188 | - Security in complex workflows | |
| 189 | - User productivity improvements | |
| 190 | ||
| 191 | ### 5.5 Phase 5: Enterprise Integration | |
| 192 | ||
| 193 | **Focus Areas:** | |
| 194 | - Enterprise authentication integration | |
| 195 | - Role-based access controls | |
| 196 | - Compliance features (logging, auditing) | |
| 197 | - Organization-specific tool libraries | |
| 198 | ||
| 199 | **Security Measures:** | |
| 200 | - Integration with enterprise security frameworks | |
| 201 | - Compliance monitoring | |
| 202 | - Advanced auditing | |
| 203 | ||
| 204 | **Evaluation Metrics:** | |
| 205 | - Enterprise security compliance | |
| 206 | - Integration effectiveness | |
| 207 | - Organizational adoption metrics | |
| 208 | ||
| 209 | ## 6. Iterative Security Improvements | |
| 210 | ||
| 211 | Building secure LLM function calling systems requires continuous improvement based on emerging threats and user feedback. The following iterative security improvements should be implemented throughout the development lifecycle: | |
| 212 | ||
| 213 | ### 6.1 Initial Implementation (Phase 1) | |
| 214 | ||
| 215 | 1. **Basic Permission System**: | |
| 216 | - Implement prompt-based permissions for all operations | |
| 217 | - Special handling for sudo commands | |
| 218 | - User confirmation for all system-modifying actions | |
| 219 | ||
| 220 | 2. **Command Sanitization**: | |
| 221 | - Basic command whitelist | |
| 222 | - Argument validation | |
| 223 | - Command string sanitation | |
| 224 | ||
| 225 | 3. **Execution Controls**: | |
| 226 | - Timeout limits for all commands | |
| 227 | - Output size limitations | |
| 228 | - Error handling and safe failures | |
| 229 | ||
| 230 | ### 6.2 Enhanced Security (Phase 2) | |
| 231 | ||
| 232 | 1. **Advanced Permission Framework**: | |
| 233 | - Persistent permission profiles | |
| 234 | - Granular permission categories | |
| 235 | - Command categorization by risk level | |
| 236 | ||
| 237 | 2. **Execution Isolation**: | |
| 238 | - Implement isolation by segregating the LLM from other system processes and networks to prevent lateral movement in case of a breach | |
| 239 | - Resource quotas and limitations | |
| 240 | - Separate user space for command execution | |
| 241 | ||
| 242 | 3. **Security Monitoring**: | |
| 243 | - Comprehensive logging of all actions | |
| 244 | - Anomaly detection for suspicious patterns | |
| 245 | - Security audit trails | |
| 246 | ||
| 247 | ### 6.3 Comprehensive Security (Phase 3+) | |
| 248 | ||
| 249 | 1. **Advanced Threat Mitigation**: | |
| 250 | - Deploy a "red teaming" approach to test LLM vulnerabilities by simulating attacks such as prompt injection, model manipulation, and data exfiltration | |
| 251 | - Prompt injection defenses | |
| 252 | - Regular security updates based on new threats | |
| 253 | ||
| 254 | 2. **Enterprise Security Integration**: | |
| 255 | - Role-based access controls | |
| 256 | - Integration with enterprise authentication systems | |
| 257 | - Compliance monitoring and reporting | |
| 258 | ||
| 259 | 3. **Continuous Security Assessment**: | |
| 260 | - Regular security audits | |
| 261 | - Penetration testing | |
| 262 | - Community vulnerability reporting system | |
| 263 | ||
| 264 | ## 7. Best Practices for Implementation | |
| 265 | ||
| 266 | Based on current research and industry practices, we recommend the following best practices for implementing OllamaTools: | |
| 267 | ||
| 268 | ### 7.1 Development Practices | |
| 269 | ||
| 270 | 1. **Test-Driven Development**: Implement comprehensive testing for all security features. | |
| 271 | ||
| 272 | 2. **Continuous Security Testing**: Integrate security testing into the development pipeline. | |
| 273 | ||
| 274 | 3. **Code Reviews**: Conduct thorough code reviews focusing on security aspects. | |
| 275 | ||
| 276 | 4. **Documentation**: Maintain detailed documentation for all security features and practices. | |
| 277 | ||
| 278 | ### 7.2 Operational Practices | |
| 279 | ||
| 280 | 1. **Regular Updates**: Keep the library updated with the latest security patches. | |
| 281 | ||
| 282 | 2. **Security Monitoring**: Implement logging and monitoring for security events. | |
| 283 | ||
| 284 | 3. **User Education**: Provide guidance to users on secure configuration and usage. | |
| 285 | ||
| 286 | 4. **Incident Response**: Develop a plan for responding to security incidents. | |
| 287 | ||
| 288 | ### 7.3 Design Patterns | |
| 289 | ||
| 290 | Several design patterns from LLM agent development can enhance OllamaTools: | |
| 291 | ||
| 292 | 1. **ReAct Pattern**: The ReAct approach combines reasoning and action in an iterative cycle where the LLM reasons about a situation, decides on tools to use, observes results, and updates its knowledge. | |
| 293 | ||
| 294 | 2. **Reflection Pattern**: The Reflexion pattern enables agents to learn from their mistakes via natural language feedback, allowing for rapid improvement on complex tasks. | |
| 295 | ||
| 296 | 3. **Planning Pattern**: Implementing structured planning capabilities allows the agent to break down complex tasks into manageable steps. | |
| 297 | ||
| 298 | 4. **Permission Control Pattern**: Developing a consistent pattern for permission requests and management that balances security with usability. | |
| 299 | ||
| 300 | ## 8. Alignment with Industry Trends | |
| 301 | ||
| 302 | OllamaTools aligns with several emerging trends in LLM agent development: | |
| 303 | ||
| 304 | 1. **Local LLM Execution**: The trend toward running LLMs locally for privacy, cost, and latency benefits. | |
| 305 | ||
| 306 | 2. **Function Calling Standardization**: The movement toward standardized approaches to function calling across different LLM frameworks. | |
| 307 | ||
| 308 | 3. **Agent-Based Architectures**: The development of more sophisticated agent architectures that combine planning, memory, and tool use. | |
| 309 | ||
| 310 | 4. **Security-First Design**: The growing recognition of security as a primary consideration in LLM application design. | |
| 311 | ||
| 312 | ## 9. Conclusion | |
| 313 | ||
| 314 | OllamaTools represents an important step in extending the capabilities of locally-run LLMs with secure function calling. By implementing an iterative development approach that prioritizes both functionality and security, the library can provide a valuable tool for developers while addressing the significant security challenges inherent in function calling systems. | |
| 315 | ||
| 316 | The proposed roadmap provides a structured approach to building a robust, secure, and effective library that balances power with responsibility. As the field of LLM agents continues to evolve, OllamaTools can serve as a model for secure implementation of function calling in open-source LLM frameworks. | |
| 317 | ||
| 318 | ## References | |
| 319 | ||
| 320 | 1. Ollama Python library 0.4 with function calling improvements. Ollama Blog. https://ollama.com/blog/functions-as-tools | |
| 321 | ||
| 322 | 2. Advanced Guide - Ollama Function Calling with Python. Toolworks.dev. https://toolworks.dev/docs/Guides/Advanced/call-functions-ollama-python.md | |
| 323 | ||
| 324 | 3. Using Ollama with Python: Step-by-Step Guide. Cohorte Projects. https://www.cohorte.co/blog/using-ollama-with-python-step-by-step-guide | |
| 325 | ||
| 326 | 4. Why LLM Security Matters: Top 10 Threats and Best Practices. Perception Point. https://perception-point.io/guides/ai-security/why-llm-security-matters-top-10-threats-and-best-practices/ | |
| 327 | ||
| 328 | 5. Exploiting cyber security vulnerabilities via LLM agents. Vulcan Cyber. https://vulcan.io/blog/exploiting-cyber-security-vulnerabilities-via-llm-agents/ | |
| 329 | ||
| 330 | 6. LLM Security: Top 10 Risks and 7 Security Best Practices. Exabeam. https://www.exabeam.com/explainers/ai-cyber-security/llm-security-top-10-risks-and-7-security-best-practices/ | |
| 331 | ||
| 332 | 7. LLM Powered Autonomous Agents. Lil'Log. https://lilianweng.github.io/posts/2023-06-23-agent/ | |
| 333 | ||
| 334 | 8. Exploring LLM Vulnerabilities and Security Best Practices. Vaadata. https://www.vaadata.com/blog/exploring-llm-vulnerabilities-and-security-best-practices/ | |
| 335 | ||
| 336 | 9. ReAct agents vs function calling agents. LeewayHertz. https://www.leewayhertz.com/react-agents-vs-function-calling-agents/ | |
| 337 | ||
| 338 | 10. LLM agents: The ultimate guide 2025. SuperAnnotate. https://www.superannotate.com/blog/llm-agents |
| … | … | @@ -0,0 +1,786 @@ |
| 1 | # OllamaTools Implementation Blueprint | |
| 2 | ||
| 3 | ## Overall Strategy | |
| 4 | ||
| 5 | The implementation will follow these phases: | |
| 6 | 1. Project setup and core infrastructure | |
| 7 | 2. Permission system implementation | |
| 8 | 3. System tools development | |
| 9 | 4. Web tools development | |
| 10 | 5. Documentation tools development | |
| 11 | 6. Testing and refinement | |
| 12 | ||
| 13 | Each phase will be broken down into small, iterative steps with clear deliverables and tests. | |
| 14 | ||
| 15 | ## Detailed Step-by-Step Implementation Plan | |
| 16 | ||
| 17 | ### Phase 1: Project Setup and Core Infrastructure | |
| 18 | ||
| 19 | #### Step 1.1: Project Structure and Configuration | |
| 20 | ||
| 21 | ``` | |
| 22 | # Prompt 1: Project Structure Setup | |
| 23 | ||
| 24 | Create the basic project structure for OllamaTools according to the specification. | |
| 25 | This should include: | |
| 26 | ||
| 27 | 1. Create a proper Python package structure with the following files and directories: | |
| 28 | - `ollamatools/` (main package directory) | |
| 29 | - `__init__.py` (package initialization) | |
| 30 | - `agent.py` (placeholder for main agent class) | |
| 31 | - `security.py` (placeholder for permission management) | |
| 32 | - `config.py` (configuration management) | |
| 33 | - `tools/` (directory for function groups) | |
| 34 | - `__init__.py` | |
| 35 | - `system_tools.py` (placeholder) | |
| 36 | - `web_tools.py` (placeholder) | |
| 37 | - `doc_tools.py` (placeholder) | |
| 38 | - `utils/` | |
| 39 | - `__init__.py` | |
| 40 | - `logger.py` (logging utilities) | |
| 41 | - `tests/` (test directory) | |
| 42 | - `__init__.py` | |
| 43 | - `test_config.py` (placeholder) | |
| 44 | - `examples/` (example scripts directory) | |
| 45 | - `basic_usage.py` (placeholder) | |
| 46 | - `setup.py` (package setup file) | |
| 47 | - `requirements.txt` (dependencies) | |
| 48 | - `README.md` (project documentation) | |
| 49 | ||
| 50 | 2. Implement a basic `setup.py` file with: | |
| 51 | - Package name: "ollamatools" | |
| 52 | - Version: "0.1.0" | |
| 53 | - Required dependencies from specification | |
| 54 | - Appropriate metadata (author, description, etc.) | |
| 55 | ||
| 56 | 3. Create a simple `requirements.txt` with necessary dependencies: | |
| 57 | - ollama-python >= 0.4.0 | |
| 58 | - requests >= 2.28.0 | |
| 59 | - beautifulsoup4 >= 4.11.0 | |
| 60 | - pydantic >= 1.10.0 | |
| 61 | - markdown >= 3.4.0 | |
| 62 | - typing-extensions >= 4.4.0 | |
| 63 | - pytest >= 7.0.0 | |
| 64 | ||
| 65 | 4. Implement a basic README.md with: | |
| 66 | - Project title and description | |
| 67 | - Installation instructions | |
| 68 | - Placeholder for usage examples | |
| 69 | ||
| 70 | Each file should include appropriate docstrings and basic placeholder content where applicable. | |
| 71 | ``` | |
| 72 | ||
| 73 | #### Step 1.2: Configuration Management | |
| 74 | ||
| 75 | ``` | |
| 76 | # Prompt 2: Configuration Management Implementation | |
| 77 | ||
| 78 | Now, let's implement the configuration management system for OllamaTools. This will provide a central place to manage settings across the library. | |
| 79 | ||
| 80 | 1. Implement the `config.py` module: | |
| 81 | - Create a `Config` class using Pydantic for validation | |
| 82 | - Include configuration parameters: | |
| 83 | - model (str, default="llama3.1") | |
| 84 | - host (str, default="http://localhost:11434") | |
| 85 | - permission_prompts (bool, default=True) | |
| 86 | - sudo_always_prompt (bool, default=True) | |
| 87 | - timeout_seconds (int, default=60) | |
| 88 | - max_file_size (optional int, default=None) | |
| 89 | - Add methods to load/save configuration from/to a file | |
| 90 | - Include docstrings for all methods and classes | |
| 91 | ||
| 92 | 2. Create tests for the configuration in `tests/test_config.py`: | |
| 93 | - Test creating a configuration with default values | |
| 94 | - Test creating a configuration with custom values | |
| 95 | - Test validation of configuration values | |
| 96 | - Test loading configuration from a file (mock the file I/O) | |
| 97 | - Test saving configuration to a file (mock the file I/O) | |
| 98 | ||
| 99 | 3. Update `__init__.py` to expose the Config class: | |
| 100 | - Add appropriate imports and exports | |
| 101 | ||
| 102 | Make sure to follow PEP 8 style guidelines, add type hints, and provide comprehensive docstrings. Handle potential errors gracefully, including file not found, invalid configuration, etc. | |
| 103 | ``` | |
| 104 | ||
| 105 | #### Step 1.3: Logging Utilities | |
| 106 | ||
| 107 | ``` | |
| 108 | # Prompt 3: Logging Utilities Implementation | |
| 109 | ||
| 110 | Let's implement the logging utilities for OllamaTools. This will provide consistent logging throughout the library. | |
| 111 | ||
| 112 | 1. Implement the `utils/logger.py` module: | |
| 113 | - Create a configurable logger function that returns a logger instance | |
| 114 | - Include log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL) | |
| 115 | - Add options for console and file output | |
| 116 | - Include formatting options for log messages | |
| 117 | - Add documentation for usage | |
| 118 | ||
| 119 | 2. Create tests for the logger in a new file `tests/test_logger.py`: | |
| 120 | - Test logger creation | |
| 121 | - Test log level setting | |
| 122 | - Test log formatting | |
| 123 | - Test console output (using mock/capture) | |
| 124 | - Test file output (using mock) | |
| 125 | ||
| 126 | 3. Update `utils/__init__.py` to expose the logger functionality: | |
| 127 | - Add appropriate imports and exports | |
| 128 | ||
| 129 | 4. Update the main `__init__.py` to expose the logger functionality: | |
| 130 | - Add appropriate imports from the utils package | |
| 131 | ||
| 132 | The logging system should be simple to use but flexible enough to support different logging needs across the library. Make sure to handle errors gracefully and provide clear documentation. | |
| 133 | ``` | |
| 134 | ||
| 135 | ### Phase 2: Permission System Implementation | |
| 136 | ||
| 137 | #### Step 2.1: Basic Permission Manager | |
| 138 | ||
| 139 | ``` | |
| 140 | # Prompt 4: Basic Permission Manager Implementation | |
| 141 | ||
| 142 | Let's implement the core permission system for OllamaTools. This will manage security for function execution, focusing on a prompt-based approach as outlined in the specification. | |
| 143 | ||
| 144 | 1. Implement the `security.py` module with a `PermissionManager` class: | |
| 145 | - Include initialization with parameters: | |
| 146 | - prompt_enabled (bool, default=True) | |
| 147 | - sudo_always_prompt (bool, default=True) | |
| 148 | - Implement a basic `request_permission` method that: | |
| 149 | - Takes function_name, args, and is_sudo parameters | |
| 150 | - Returns a boolean indicating whether permission was granted | |
| 151 | - For now, simply print the request and return True (we'll add actual prompting later) | |
| 152 | - Add a `detect_sudo` method that detects if a command uses sudo | |
| 153 | - Include comprehensive docstrings | |
| 154 | ||
| 155 | 2. Create tests for the permission manager in a new file `tests/test_security.py`: | |
| 156 | - Test initialization with different parameters | |
| 157 | - Test the basic `request_permission` method | |
| 158 | - Test the `detect_sudo` method with various commands | |
| 159 | - Use mocks where appropriate | |
| 160 | ||
| 161 | 3. Update the main `__init__.py` to expose the PermissionManager: | |
| 162 | - Add appropriate imports | |
| 163 | ||
| 164 | Focus on getting the basic structure right with proper error handling, type hints, and docstrings. We'll enhance the permission system in subsequent steps. | |
| 165 | ``` | |
| 166 | ||
| 167 | #### Step 2.2: Interactive Permission Prompts | |
| 168 | ||
| 169 | ``` | |
| 170 | # Prompt 5: Interactive Permission Prompts | |
| 171 | ||
| 172 | Now, let's enhance the permission system to include interactive prompts for the user. This is a key security feature of OllamaTools. | |
| 173 | ||
| 174 | 1. Update the `security.py` module's `PermissionManager` class: | |
| 175 | - Enhance the `request_permission` method to: | |
| 176 | - Display a clear, informative prompt about the operation | |
| 177 | - Show the function name and arguments | |
| 178 | - Highlight potential risks, especially for sudo commands | |
| 179 | - Provide user response options: | |
| 180 | - Allow: Grant permission for this operation | |
| 181 | - Allow for session: Grant permission for similar operations in this session | |
| 182 | - Deny: Reject the operation | |
| 183 | - Modify: Allow modifying the operation before execution | |
| 184 | - Return appropriate boolean result based on user input | |
| 185 | - Store "Allow for session" permissions to avoid repeated prompts | |
| 186 | - Add a `modify_command` method to handle command modification | |
| 187 | - Add proper input validation for user responses | |
| 188 | ||
| 189 | 2. Update tests in `tests/test_security.py`: | |
| 190 | - Test the enhanced `request_permission` method with mocked user input | |
| 191 | - Test the "Allow for session" functionality | |
| 192 | - Test the command modification feature | |
| 193 | - Test input validation for user responses | |
| 194 | ||
| 195 | 3. Implement a simple interactive example in `examples/permission_example.py`: | |
| 196 | - Show how to use the permission system | |
| 197 | - Include examples of different permission scenarios | |
| 198 | ||
| 199 | Make sure to handle edge cases, such as invalid input, and ensure the code is secure against potential bypasses. The prompts should be clear enough for users to make informed decisions about permissions. | |
| 200 | ``` | |
| 201 | ||
| 202 | ### Phase 3: System Tools Development | |
| 203 | ||
| 204 | #### Step 3.1: Command Execution | |
| 205 | ||
| 206 | ``` | |
| 207 | # Prompt 6: Command Execution Implementation | |
| 208 | ||
| 209 | Let's implement the command execution functionality in the system tools module. This will allow OllamaTools to execute shell commands. | |
| 210 | ||
| 211 | 1. Implement the basic functions in `tools/system_tools.py`: | |
| 212 | - Create an `execute_command` function that: | |
| 213 | - Takes command, args, and timeout parameters | |
| 214 | - Safely executes the command using subprocess | |
| 215 | - Returns a dictionary with stdout, stderr, and exit code | |
| 216 | - Handles timeout and other potential errors | |
| 217 | - Includes proper input sanitization to prevent injection attacks | |
| 218 | - Add comprehensive docstrings | |
| 219 | - Include type hints | |
| 220 | ||
| 221 | 2. Create tests for the command execution in a new file `tests/test_system_tools.py`: | |
| 222 | - Test executing a simple command (e.g., "echo hello") | |
| 223 | - Test command with arguments | |
| 224 | - Test command with timeout | |
| 225 | - Test handling of invalid commands | |
| 226 | - Test sanitization of potentially dangerous inputs | |
| 227 | ||
| 228 | 3. Update `tools/__init__.py` to expose the system tools: | |
| 229 | - Add appropriate imports | |
| 230 | ||
| 231 | 4. Create a simple example in `examples/command_execution.py`: | |
| 232 | - Show how to use the command execution function with various examples | |
| 233 | ||
| 234 | Focus on security in this implementation. Ensure commands are properly sanitized and executed safely. The function should handle errors gracefully and provide informative error messages. | |
| 235 | ``` | |
| 236 | ||
| 237 | #### Step 3.2: File Operations | |
| 238 | ||
| 239 | ``` | |
| 240 | # Prompt 7: File Operations Implementation | |
| 241 | ||
| 242 | Now, let's implement the file operation functions in the system tools module. These will allow reading, writing, and finding files. | |
| 243 | ||
| 244 | 1. Add the following functions to `tools/system_tools.py`: | |
| 245 | - `read_file`: | |
| 246 | - Takes path and max_size parameters | |
| 247 | - Reads and returns file contents | |
| 248 | - Handles file not found and other errors | |
| 249 | - Respects max_size parameter | |
| 250 | - `write_file`: | |
| 251 | - Takes path, content, and mode parameters | |
| 252 | - Writes content to the file | |
| 253 | - Returns a boolean indicating success | |
| 254 | - Handles permission errors and other issues | |
| 255 | - `find_files`: | |
| 256 | - Takes pattern, directory, and recursive parameters | |
| 257 | - Returns a list of matching file paths | |
| 258 | - Uses glob or similar for pattern matching | |
| 259 | - Include proper input validation, error handling, and security checks | |
| 260 | - Add comprehensive docstrings and type hints | |
| 261 | ||
| 262 | 2. Update tests in `tests/test_system_tools.py`: | |
| 263 | - Test `read_file` with various scenarios (existing file, non-existent file, etc.) | |
| 264 | - Test `write_file` (mocking the file operations) | |
| 265 | - Test `find_files` with different patterns and options | |
| 266 | - Test error handling for all functions | |
| 267 | ||
| 268 | 3. Update the example in `examples/command_execution.py` or create a new example: | |
| 269 | - Show how to use the file operation functions | |
| 270 | ||
| 271 | Ensure the implementation is secure, handles errors gracefully, and provides clear error messages. Pay special attention to path handling to prevent path traversal vulnerabilities. | |
| 272 | ``` | |
| 273 | ||
| 274 | #### Step 3.3: Integration with Permission System | |
| 275 | ||
| 276 | ``` | |
| 277 | # Prompt 8: System Tools Integration with Permission System | |
| 278 | ||
| 279 | Let's integrate the system tools with the permission system to ensure security for command execution and file operations. | |
| 280 | ||
| 281 | 1. Update the `tools/system_tools.py` module: | |
| 282 | - Modify the `execute_command` function to: | |
| 283 | - Accept a permission_manager parameter | |
| 284 | - Use the permission manager to request permission before execution | |
| 285 | - Only execute the command if permission is granted | |
| 286 | - Similarly update `read_file`, `write_file`, and `find_files` functions | |
| 287 | - Add appropriate error handling for permission denied scenarios | |
| 288 | - Update docstrings to reflect these changes | |
| 289 | ||
| 290 | 2. Update tests in `tests/test_system_tools.py`: | |
| 291 | - Test integration with the permission system (using mocks) | |
| 292 | - Test permission denied scenarios | |
| 293 | - Test permission granted scenarios | |
| 294 | ||
| 295 | 3. Create a new example in `examples/secure_system_tools.py`: | |
| 296 | - Show how to use the system tools with the permission system | |
| 297 | - Include examples of permission prompts and responses | |
| 298 | ||
| 299 | The integration should be seamless, with clear error messages when permission is denied. The functions should respect the permission system settings and handle edge cases properly. | |
| 300 | ``` | |
| 301 | ||
| 302 | ### Phase 4: Web Tools Development | |
| 303 | ||
| 304 | #### Step 4.1: Basic Web Request Functions | |
| 305 | ||
| 306 | ``` | |
| 307 | # Prompt 9: Basic Web Request Functions | |
| 308 | ||
| 309 | Let's implement the basic web request functions in the web tools module. These will allow OllamaTools to make HTTP requests and fetch web content. | |
| 310 | ||
| 311 | 1. Implement basic functions in `tools/web_tools.py`: | |
| 312 | - Create a `fetch_url` function that: | |
| 313 | - Takes url, method, params, headers, data, and timeout parameters | |
| 314 | - Makes an HTTP request using the requests library | |
| 315 | - Returns a dictionary with status, headers, and content | |
| 316 | - Handles various HTTP errors and timeouts | |
| 317 | - Includes proper input validation | |
| 318 | - Add comprehensive docstrings and type hints | |
| 319 | ||
| 320 | 2. Create tests for the web tools in a new file `tests/test_web_tools.py`: | |
| 321 | - Test successful requests (using mocks) | |
| 322 | - Test error handling for various HTTP errors | |
| 323 | - Test timeout handling | |
| 324 | - Test different HTTP methods | |
| 325 | - Test parameter handling | |
| 326 | ||
| 327 | 3. Update `tools/__init__.py` to expose the web tools: | |
| 328 | - Add appropriate imports | |
| 329 | ||
| 330 | 4. Create a simple example in `examples/web_request.py`: | |
| 331 | - Show how to use the fetch_url function with various examples | |
| 332 | ||
| 333 | Ensure the implementation handles errors gracefully, provides informative error messages, and includes proper timeout handling. Security considerations should include validation of URLs and proper handling of responses. | |
| 334 | ``` | |
| 335 | ||
| 336 | #### Step 4.2: Advanced Web Tools | |
| 337 | ||
| 338 | ``` | |
| 339 | # Prompt 10: Advanced Web Tools Implementation | |
| 340 | ||
| 341 | Now, let's implement the more advanced web tools: weather information fetching and web search functionality. | |
| 342 | ||
| 343 | 1. Add the following functions to `tools/web_tools.py`: | |
| 344 | - `get_weather`: | |
| 345 | - Takes location, days, and units parameters | |
| 346 | - Uses an appropriate weather API (e.g., OpenWeatherMap) | |
| 347 | - Returns structured weather information | |
| 348 | - Handles API errors and limits | |
| 349 | - `search_web`: | |
| 350 | - Takes query and num_results parameters | |
| 351 | - Uses an appropriate search API | |
| 352 | - Returns structured search results | |
| 353 | - Handles API errors and limits | |
| 354 | - Include proper input validation, error handling, and API key management | |
| 355 | - Add comprehensive docstrings and type hints | |
| 356 | ||
| 357 | 2. Update tests in `tests/test_web_tools.py`: | |
| 358 | - Test `get_weather` with mocked API responses | |
| 359 | - Test `search_web` with mocked API responses | |
| 360 | - Test error handling for API failures | |
| 361 | - Test parameter validation | |
| 362 | ||
| 363 | 3. Create or update example scripts: | |
| 364 | - Add examples of weather fetching to `examples/web_tools_examples.py` | |
| 365 | - Add examples of web search to the same file | |
| 366 | ||
| 367 | 4. Update the config module to include API key configuration: | |
| 368 | - Add weather_api_key and search_api_key parameters | |
| 369 | - Update the Config class accordingly | |
| 370 | ||
| 371 | For the weather API, consider using a free service like OpenWeatherMap. For web search, you might use a free search API or web scraping with BeautifulSoup (with proper consideration for terms of service). Ensure API keys are handled securely and not hardcoded. | |
| 372 | ``` | |
| 373 | ||
| 374 | #### Step 4.3: Integration with Permission System | |
| 375 | ||
| 376 | ``` | |
| 377 | # Prompt 11: Web Tools Integration with Permission System | |
| 378 | ||
| 379 | Let's integrate the web tools with the permission system to ensure security for web requests. | |
| 380 | ||
| 381 | 1. Update the `tools/web_tools.py` module: | |
| 382 | - Modify the `fetch_url`, `get_weather`, and `search_web` functions to: | |
| 383 | - Accept a permission_manager parameter | |
| 384 | - Use the permission manager to request permission before making requests | |
| 385 | - Only proceed if permission is granted | |
| 386 | - Add appropriate error handling for permission denied scenarios | |
| 387 | - Update docstrings to reflect these changes | |
| 388 | ||
| 389 | 2. Update tests in `tests/test_web_tools.py`: | |
| 390 | - Test integration with the permission system (using mocks) | |
| 391 | - Test permission denied scenarios | |
| 392 | - Test permission granted scenarios | |
| 393 | ||
| 394 | 3. Create a new example in `examples/secure_web_tools.py`: | |
| 395 | - Show how to use the web tools with the permission system | |
| 396 | - Include examples of permission prompts and responses | |
| 397 | ||
| 398 | The integration should be seamless, with clear error messages when permission is denied. The functions should respect the permission system settings and handle edge cases properly. Consider adding special permission checks for certain URLs or API calls that might be sensitive. | |
| 399 | ``` | |
| 400 | ||
| 401 | ### Phase 5: Documentation Tools Development | |
| 402 | ||
| 403 | #### Step 5.1: Basic Documentation Tools | |
| 404 | ||
| 405 | ``` | |
| 406 | # Prompt 12: Basic Documentation Tools Implementation | |
| 407 | ||
| 408 | Let's implement the basic documentation tools that will generate and process documentation. | |
| 409 | ||
| 410 | 1. Implement basic functions in `tools/doc_tools.py`: | |
| 411 | - Create a `generate_markdown` function that: | |
| 412 | - Takes content, title, and format_type parameters | |
| 413 | - Generates formatted documentation (markdown or HTML) | |
| 414 | - Returns the formatted document as a string | |
| 415 | - Includes proper input validation | |
| 416 | - Add comprehensive docstrings and type hints | |
| 417 | ||
| 418 | 2. Create tests for the documentation tools in a new file `tests/test_doc_tools.py`: | |
| 419 | - Test markdown generation with various inputs | |
| 420 | - Test HTML generation (if supported) | |
| 421 | - Test with empty or invalid inputs | |
| 422 | - Test formatting features | |
| 423 | ||
| 424 | 3. Update `tools/__init__.py` to expose the documentation tools: | |
| 425 | - Add appropriate imports | |
| 426 | ||
| 427 | 4. Create a simple example in `examples/documentation_tools.py`: | |
| 428 | - Show how to use the generate_markdown function | |
| 429 | ||
| 430 | Ensure the implementation handles different inputs gracefully and produces well-formatted output. The function should validate inputs and handle edge cases appropriately. | |
| 431 | ``` | |
| 432 | ||
| 433 | #### Step 5.2: Advanced Documentation Tools | |
| 434 | ||
| 435 | ``` | |
| 436 | # Prompt 13: Advanced Documentation Tools Implementation | |
| 437 | ||
| 438 | Now, let's implement the more advanced documentation tools: context extraction and text summarization. | |
| 439 | ||
| 440 | 1. Add the following functions to `tools/doc_tools.py`: | |
| 441 | - `extract_context`: | |
| 442 | - Takes query, documents, and max_length parameters | |
| 443 | - Extracts relevant context from documents based on the query | |
| 444 | - Returns the extracted context as a string | |
| 445 | - Uses a simple keyword-based approach for now | |
| 446 | - `summarize_text`: | |
| 447 | - Takes text and max_length parameters | |
| 448 | - Generates a summary of the text | |
| 449 | - Returns the summary as a string | |
| 450 | - Uses a simple extractive summarization approach for now | |
| 451 | - Include proper input validation and error handling | |
| 452 | - Add comprehensive docstrings and type hints | |
| 453 | ||
| 454 | 2. Update tests in `tests/test_doc_tools.py`: | |
| 455 | - Test `extract_context` with various documents and queries | |
| 456 | - Test `summarize_text` with different texts | |
| 457 | - Test with empty or invalid inputs | |
| 458 | - Test length limitations | |
| 459 | ||
| 460 | 3. Update the example in `examples/documentation_tools.py`: | |
| 461 | - Add examples of context extraction and text summarization | |
| 462 | ||
| 463 | Implement the functions using simple but effective algorithms. For context extraction, a keyword-based approach might be sufficient. For summarization, an extractive approach (selecting important sentences) can work well for a first implementation. Ensure the functions handle different inputs gracefully and provide useful output even for edge cases. | |
| 464 | ``` | |
| 465 | ||
| 466 | #### Step 5.3: Integration with Permission System | |
| 467 | ||
| 468 | ``` | |
| 469 | # Prompt 14: Documentation Tools Integration with Permission System | |
| 470 | ||
| 471 | Let's integrate the documentation tools with the permission system to ensure security when processing potentially sensitive documents. | |
| 472 | ||
| 473 | 1. Update the `tools/doc_tools.py` module: | |
| 474 | - Modify the `generate_markdown`, `extract_context`, and `summarize_text` functions to: | |
| 475 | - Accept a permission_manager parameter | |
| 476 | - Use the permission manager to request permission before processing documents | |
| 477 | - Only proceed if permission is granted | |
| 478 | - Add appropriate error handling for permission denied scenarios | |
| 479 | - Update docstrings to reflect these changes | |
| 480 | ||
| 481 | 2. Update tests in `tests/test_doc_tools.py`: | |
| 482 | - Test integration with the permission system (using mocks) | |
| 483 | - Test permission denied scenarios | |
| 484 | - Test permission granted scenarios | |
| 485 | ||
| 486 | 3. Create a new example in `examples/secure_doc_tools.py`: | |
| 487 | - Show how to use the documentation tools with the permission system | |
| 488 | - Include examples of permission prompts and responses | |
| 489 | ||
| 490 | The integration should be seamless, with clear error messages when permission is denied. The functions should respect the permission system settings and handle edge cases properly. Consider adding special permission checks for certain document types or content that might be sensitive. | |
| 491 | ``` | |
| 492 | ||
| 493 | ### Phase 6: Core Agent Implementation | |
| 494 | ||
| 495 | #### Step 6.1: Basic OllamaAgent | |
| 496 | ||
| 497 | ``` | |
| 498 | # Prompt 15: Basic OllamaAgent Implementation | |
| 499 | ||
| 500 | Let's implement the core OllamaAgent class that will serve as the main interface for OllamaTools. | |
| 501 | ||
| 502 | 1. Implement the `agent.py` module with an `OllamaAgent` class: | |
| 503 | - Include initialization with parameters matching the specification: | |
| 504 | - model (str, default="llama3.1") | |
| 505 | - host (str, default="http://localhost:11434") | |
| 506 | - permission_prompts (bool, default=True) | |
| 507 | - sudo_always_prompt (bool, default=True) | |
| 508 | - Initialize a permission manager based on the parameters | |
| 509 | - Include a basic `chat` method that simply forwards messages to Ollama | |
| 510 | - This should use the ollama-python client | |
| 511 | - It should accept message, system_prompt, and context parameters | |
| 512 | - It should return the Ollama response | |
| 513 | - Add a `register_tools` method (placeholder for now) | |
| 514 | - Include comprehensive docstrings and type hints | |
| 515 | ||
| 516 | 2. Create tests for the OllamaAgent in a new file `tests/test_agent.py`: | |
| 517 | - Test initialization with various parameters | |
| 518 | - Test the basic chat functionality (using mocks for Ollama) | |
| 519 | - Test error handling for Ollama client issues | |
| 520 | ||
| 521 | 3. Update the main `__init__.py` to expose the OllamaAgent: | |
| 522 | - Add appropriate imports | |
| 523 | ||
| 524 | 4. Create a simple example in `examples/basic_agent.py`: | |
| 525 | - Show how to create and use the OllamaAgent for basic chat | |
| 526 | ||
| 527 | Focus on getting the basic structure right, with proper integration with the Ollama client. We'll add function detection and execution in subsequent steps. | |
| 528 | ``` | |
| 529 | ||
| 530 | #### Step 6.2: Function Registration | |
| 531 | ||
| 532 | ``` | |
| 533 | # Prompt 16: Function Registration Implementation | |
| 534 | ||
| 535 | Now, let's implement the function registration system that will allow OllamaTools to register available functions with Ollama. | |
| 536 | ||
| 537 | 1. Update the `agent.py` module's `OllamaAgent` class: | |
| 538 | - Implement the `register_tools` method to: | |
| 539 | - Collect function definitions from the tools modules | |
| 540 | - Format them according to Ollama's function calling schema | |
| 541 | - Register them with the Ollama client | |
| 542 | - Add a method to parse function definitions from docstrings and type hints | |
| 543 | - Include proper error handling for registration issues | |
| 544 | - Update docstrings to reflect these changes | |
| 545 | ||
| 546 | 2. Update tests in `tests/test_agent.py`: | |
| 547 | - Test the function registration process | |
| 548 | - Test parsing of function definitions | |
| 549 | - Test handling of invalid function definitions | |
| 550 | ||
| 551 | 3. Update `tools/__init__.py` to expose function metadata: | |
| 552 | - Add a mechanism to annotate functions for automatic registration | |
| 553 | ||
| 554 | 4. Update the example in `examples/basic_agent.py`: | |
| 555 | - Show how function registration works | |
| 556 | ||
| 557 | The registration system should be flexible and robust, handling various function signatures and providing clear error messages for issues. It should use Python's introspection capabilities to automatically extract function signatures and documentation. | |
| 558 | ``` | |
| 559 | ||
| 560 | #### Step 6.3: Function Detection and Execution | |
| 561 | ||
| 562 | ``` | |
| 563 | # Prompt 17: Function Detection and Execution Implementation | |
| 564 | ||
| 565 | Let's implement the function detection and execution system that will allow OllamaAgent to automatically detect and execute functions based on conversation context. | |
| 566 | ||
| 567 | 1. Update the `agent.py` module's `OllamaAgent` class: | |
| 568 | - Enhance the `chat` method to: | |
| 569 | - Detect function calls in Ollama's response | |
| 570 | - Process those function calls | |
| 571 | - Return the updated response | |
| 572 | - Implement a `process_function_calls` method that: | |
| 573 | - Takes a list of function calls | |
| 574 | - Executes the corresponding functions with appropriate arguments | |
| 575 | - Returns the function call results | |
| 576 | - Uses the permission manager for security | |
| 577 | - Include proper error handling for function execution issues | |
| 578 | - Update docstrings to reflect these changes | |
| 579 | ||
| 580 | 2. Update tests in `tests/test_agent.py`: | |
| 581 | - Test function detection in Ollama responses | |
| 582 | - Test function execution with various scenarios | |
| 583 | - Test error handling for invalid function calls | |
| 584 | - Test integration with the permission system | |
| 585 | ||
| 586 | 3. Create a new example in `examples/function_execution.py`: | |
| 587 | - Show how the OllamaAgent automatically detects and executes functions | |
| 588 | - Include examples of various function calls | |
| 589 | ||
| 590 | The implementation should be robust, handling various function call formats and providing clear error messages for issues. It should integrate seamlessly with the permission system and handle edge cases appropriately. | |
| 591 | ``` | |
| 592 | ||
| 593 | ### Phase 7: Integration and Final Testing | |
| 594 | ||
| 595 | #### Step 7.1: Comprehensive Integration | |
| 596 | ||
| 597 | ``` | |
| 598 | # Prompt 18: Comprehensive Integration | |
| 599 | ||
| 600 | Let's integrate all the components of OllamaTools into a cohesive system and ensure they work together properly. | |
| 601 | ||
| 602 | 1. Update the `agent.py` module's `OllamaAgent` class: | |
| 603 | - Ensure proper integration with: | |
| 604 | - Configuration management | |
| 605 | - Permission system | |
| 606 | - System tools | |
| 607 | - Web tools | |
| 608 | - Documentation tools | |
| 609 | - Add any missing connections or interfaces | |
| 610 | - Ensure consistent error handling across all components | |
| 611 | - Update docstrings to reflect the integrated system | |
| 612 | ||
| 613 | 2. Create comprehensive integration tests in a new file `tests/test_integration.py`: | |
| 614 | - Test the complete workflow with various scenarios | |
| 615 | - Test interaction between different components | |
| 616 | - Test error propagation across components | |
| 617 | ||
| 618 | 3. Create a comprehensive example in `examples/complete_example.py`: | |
| 619 | - Show the full functionality of OllamaTools | |
| 620 | - Include examples of different types of function calls | |
| 621 | - Show how the components work together | |
| 622 | ||
| 623 | 4. Update the README.md with: | |
| 624 | - Detailed installation instructions | |
| 625 | - Comprehensive usage examples | |
| 626 | - Documentation for all main features | |
| 627 | ||
| 628 | The integration should be seamless, with clear interfaces between components and consistent error handling. The system should work as a cohesive whole, providing a smooth user experience. | |
| 629 | ``` | |
| 630 | ||
| 631 | #### Step 7.2: Error Handling and Edge Cases | |
| 632 | ||
| 633 | ``` | |
| 634 | # Prompt 19: Error Handling and Edge Cases | |
| 635 | ||
| 636 | Let's improve error handling throughout OllamaTools and ensure it handles edge cases gracefully. | |
| 637 | ||
| 638 | 1. Review and update error handling in all modules: | |
| 639 | - Ensure all functions have appropriate error handling | |
| 640 | - Use consistent error types and messages | |
| 641 | - Add custom exception classes if needed | |
| 642 | - Improve error messages to be informative and helpful | |
| 643 | ||
| 644 | 2. Add tests for edge cases in all test files: | |
| 645 | - Test with invalid inputs | |
| 646 | - Test with extreme values (very large files, long timeouts, etc.) | |
| 647 | - Test with unexpected responses from external systems | |
| 648 | - Test error propagation and handling | |
| 649 | ||
| 650 | 3. Create an example in `examples/error_handling.py`: | |
| 651 | - Show how to handle various errors in OllamaTools | |
| 652 | - Include examples of custom error handling | |
| 653 | ||
| 654 | 4. Update documentation to include information about error handling: | |
| 655 | - Add sections on error types and how to handle them | |
| 656 | - Include examples of error handling in the README | |
| 657 | ||
| 658 | The error handling should be comprehensive, covering all possible error conditions and providing clear, informative messages. The system should degrade gracefully when errors occur, maintaining security and stability. | |
| 659 | ``` | |
| 660 | ||
| 661 | #### Step 7.3: Performance Optimization | |
| 662 | ||
| 663 | ``` | |
| 664 | # Prompt 20: Performance Optimization | |
| 665 | ||
| 666 | Let's optimize the performance of OllamaTools and ensure it works efficiently, especially for resource-intensive operations. | |
| 667 | ||
| 668 | 1. Review and optimize performance in all modules: | |
| 669 | - Add caching where appropriate | |
| 670 | - Optimize resource-intensive operations | |
| 671 | - Add options for controlling resource usage | |
| 672 | - Implement asynchronous operations where beneficial | |
| 673 | ||
| 674 | 2. Add performance tests in a new file `tests/test_performance.py`: | |
| 675 | - Test execution time for various operations | |
| 676 | - Test memory usage | |
| 677 | - Test concurrent operations | |
| 678 | - Compare performance with and without optimizations | |
| 679 | ||
| 680 | 3. Update the configuration system to include performance options: | |
| 681 | - Add parameters for controlling caching | |
| 682 | - Add parameters for limiting resource usage | |
| 683 | - Add parameters for concurrency control | |
| 684 | ||
| 685 | 4. Create an example in `examples/performance_optimization.py`: | |
| 686 | - Show how to optimize performance for various scenarios | |
| 687 | - Include examples of different performance configurations | |
| 688 | ||
| 689 | The optimizations should focus on real-world usage patterns, addressing the most common performance bottlenecks. They should be configurable, allowing users to balance performance and resource usage according to their needs. | |
| 690 | ``` | |
| 691 | ||
| 692 | #### Step 7.4: Documentation and Examples | |
| 693 | ||
| 694 | ``` | |
| 695 | # Prompt 21: Documentation and Examples | |
| 696 | ||
| 697 | Let's complete the documentation and examples for OllamaTools, ensuring they are comprehensive and user-friendly. | |
| 698 | ||
| 699 | 1. Update the README.md to include: | |
| 700 | - Detailed project overview | |
| 701 | - Installation instructions | |
| 702 | - Quick start guide | |
| 703 | - Configuration options | |
| 704 | - Security considerations | |
| 705 | - API reference | |
| 706 | - Examples for common use cases | |
| 707 | - Troubleshooting section | |
| 708 | ||
| 709 | 2. Create a comprehensive API documentation: | |
| 710 | - Use docstrings compatible with tools like Sphinx | |
| 711 | - Include detailed descriptions of all classes and methods | |
| 712 | - Provide examples for each function | |
| 713 | - Document all parameters and return values | |
| 714 | ||
| 715 | 3. Enhance the examples directory: | |
| 716 | - Ensure examples for all major features | |
| 717 | - Add comments explaining each example | |
| 718 | - Organize examples by complexity or feature area | |
| 719 | ||
| 720 | 4. Create a user guide in `docs/user_guide.md`: | |
| 721 | - Provide step-by-step instructions for different use cases | |
| 722 | - Include best practices and security recommendations | |
| 723 | - Address common questions and issues | |
| 724 | ||
| 725 | The documentation should be clear, comprehensive, and user-friendly, making it easy for users to understand and use OllamaTools effectively. The examples should cover a wide range of use cases and be well-documented themselves. | |
| 726 | ``` | |
| 727 | ||
| 728 | ### Finalization Steps | |
| 729 | ||
| 730 | ``` | |
| 731 | # Prompt 22: Finalization and Packaging | |
| 732 | ||
| 733 | Let's finalize OllamaTools and prepare it for distribution. | |
| 734 | ||
| 735 | 1. Complete the `setup.py` file: | |
| 736 | - Ensure all dependencies are correctly specified | |
| 737 | - Add entry points if applicable | |
| 738 | - Include all necessary package data | |
| 739 | - Set up proper version numbering | |
| 740 | ||
| 741 | 2. Create a CHANGELOG.md: | |
| 742 | - Document the initial release | |
| 743 | - Prepare for future version tracking | |
| 744 | ||
| 745 | 3. Add a LICENSE file: | |
| 746 | - Choose an appropriate open-source license | |
| 747 | - Include the full license text | |
| 748 | ||
| 749 | 4. Create a CONTRIBUTING.md: | |
| 750 | - Guidelines for contributors | |
| 751 | - Development setup instructions | |
| 752 | - Pull request process | |
| 753 | ||
| 754 | 5. Set up continuous integration: | |
| 755 | - Add a basic GitHub Actions workflow for testing | |
| 756 | - Include linting and code quality checks | |
| 757 | ||
| 758 | 6. Prepare a release checklist: | |
| 759 | - Final testing steps | |
| 760 | - Documentation review | |
| 761 | - Version number confirmation | |
| 762 | - Distribution preparation | |
| 763 | ||
| 764 | The finalization should ensure OllamaTools is ready for distribution and use by others. It should follow best practices for open-source Python packages and provide a solid foundation for future development. | |
| 765 | ``` | |
| 766 | ||
| 767 | ## Summary of Implementation Steps | |
| 768 | ||
| 769 | This blueprint breaks down the OllamaTools implementation into 22 discrete steps, each building on the previous ones. The steps are designed to be small enough to implement safely with strong testing, but large enough to make meaningful progress. | |
| 770 | ||
| 771 | Each step includes: | |
| 772 | 1. Clear implementation tasks | |
| 773 | 2. Testing requirements | |
| 774 | 3. Documentation updates | |
| 775 | 4. Examples for demonstrating functionality | |
| 776 | ||
| 777 | The implementation follows a logical progression: | |
| 778 | 1. Setting up the basic infrastructure | |
| 779 | 2. Implementing the core security system | |
| 780 | 3. Adding system tools for command execution and file operations | |
| 781 | 4. Adding web tools for making requests and processing responses | |
| 782 | 5. Adding documentation tools for generating and processing documentation | |
| 783 | 6. Implementing the core agent for integrating with Ollama | |
| 784 | 7. Final integration, testing, and optimization | |
| 785 | ||
| 786 | Following this blueprint will result in a robust, secure, and well-tested implementation of OllamaTools that adheres to the specification. |
| … | … | @@ -0,0 +1,450 @@ |
| 1 | # OllamaTools Implementation Checklist | |
| 2 | ||
| 3 | ## Phase 1: Project Setup and Core Infrastructure | |
| 4 | ||
| 5 | ### Step 1.1: Project Structure and Configuration | |
| 6 | - [ ] Create basic package structure with all required directories | |
| 7 | - [ ] Create `ollamatools/` main package directory | |
| 8 | - [ ] Create `__init__.py` package initialization file | |
| 9 | - [ ] Create placeholder files for `agent.py`, `security.py`, `config.py` | |
| 10 | - [ ] Create `tools/` directory with placeholder files | |
| 11 | - [ ] Create `utils/` directory with placeholder files | |
| 12 | - [ ] Create `tests/` directory with placeholder files | |
| 13 | - [ ] Create `examples/` directory with placeholder files | |
| 14 | - [ ] Implement `setup.py` with package information and dependencies | |
| 15 | - [ ] Set package name, version, and metadata | |
| 16 | - [ ] Add all required dependencies | |
| 17 | - [ ] Create `requirements.txt` with all dependencies | |
| 18 | - [ ] ollama-python >= 0.4.0 | |
| 19 | - [ ] requests >= 2.28.0 | |
| 20 | - [ ] beautifulsoup4 >= 4.11.0 | |
| 21 | - [ ] pydantic >= 1.10.0 | |
| 22 | - [ ] markdown >= 3.4.0 | |
| 23 | - [ ] typing-extensions >= 4.4.0 | |
| 24 | - [ ] pytest >= 7.0.0 | |
| 25 | - [ ] Write initial README.md | |
| 26 | - [ ] Add project title and description | |
| 27 | - [ ] Add basic installation instructions | |
| 28 | - [ ] Add placeholder for usage examples | |
| 29 | ||
| 30 | ### Step 1.2: Configuration Management | |
| 31 | - [ ] Implement `config.py` module | |
| 32 | - [ ] Create `Config` class with Pydantic validation | |
| 33 | - [ ] Implement configuration parameters | |
| 34 | - [ ] model (default="llama3.1") | |
| 35 | - [ ] host (default="http://localhost:11434") | |
| 36 | - [ ] permission_prompts (default=True) | |
| 37 | - [ ] sudo_always_prompt (default=True) | |
| 38 | - [ ] timeout_seconds (default=60) | |
| 39 | - [ ] max_file_size (default=None) | |
| 40 | - [ ] Add load/save configuration methods | |
| 41 | - [ ] Add comprehensive docstrings | |
| 42 | - [ ] Create tests for configuration management | |
| 43 | - [ ] Test default configuration | |
| 44 | - [ ] Test custom configuration | |
| 45 | - [ ] Test configuration validation | |
| 46 | - [ ] Test configuration loading | |
| 47 | - [ ] Test configuration saving | |
| 48 | - [ ] Update `__init__.py` to expose Config class | |
| 49 | ||
| 50 | ### Step 1.3: Logging Utilities | |
| 51 | - [ ] Implement `utils/logger.py` module | |
| 52 | - [ ] Create configurable logger function | |
| 53 | - [ ] Add support for different log levels | |
| 54 | - [ ] Add console and file output options | |
| 55 | - [ ] Add formatting options | |
| 56 | - [ ] Write usage documentation | |
| 57 | - [ ] Create tests for logger | |
| 58 | - [ ] Test logger creation | |
| 59 | - [ ] Test log level setting | |
| 60 | - [ ] Test log formatting | |
| 61 | - [ ] Test console output | |
| 62 | - [ ] Test file output | |
| 63 | - [ ] Update `utils/__init__.py` to expose logger | |
| 64 | - [ ] Update main `__init__.py` to expose logger | |
| 65 | ||
| 66 | ## Phase 2: Permission System Implementation | |
| 67 | ||
| 68 | ### Step 2.1: Basic Permission Manager | |
| 69 | - [ ] Implement `security.py` module with `PermissionManager` class | |
| 70 | - [ ] Add initialization with parameters | |
| 71 | - [ ] prompt_enabled (default=True) | |
| 72 | - [ ] sudo_always_prompt (default=True) | |
| 73 | - [ ] Implement basic `request_permission` method | |
| 74 | - [ ] Implement `detect_sudo` method | |
| 75 | - [ ] Add comprehensive docstrings | |
| 76 | - [ ] Create tests for permission manager | |
| 77 | - [ ] Test initialization | |
| 78 | - [ ] Test `request_permission` method | |
| 79 | - [ ] Test `detect_sudo` method | |
| 80 | - [ ] Update main `__init__.py` to expose PermissionManager | |
| 81 | ||
| 82 | ### Step 2.2: Interactive Permission Prompts | |
| 83 | - [ ] Enhance `PermissionManager` class | |
| 84 | - [ ] Update `request_permission` method with interactive prompts | |
| 85 | - [ ] Implement user response options (Allow, Allow for session, Deny, Modify) | |
| 86 | - [ ] Add session permission storage | |
| 87 | - [ ] Add `modify_command` method | |
| 88 | - [ ] Add input validation | |
| 89 | - [ ] Update tests for enhanced permission system | |
| 90 | - [ ] Test enhanced `request_permission` method | |
| 91 | - [ ] Test "Allow for session" functionality | |
| 92 | - [ ] Test command modification | |
| 93 | - [ ] Test input validation | |
| 94 | - [ ] Create example script for permission system | |
| 95 | - [ ] Implement `examples/permission_example.py` | |
| 96 | ||
| 97 | ## Phase 3: System Tools Development | |
| 98 | ||
| 99 | ### Step 3.1: Command Execution | |
| 100 | - [ ] Implement basic functions in `tools/system_tools.py` | |
| 101 | - [ ] Create `execute_command` function | |
| 102 | - [ ] Add command execution with subprocess | |
| 103 | - [ ] Add timeout handling | |
| 104 | - [ ] Add input sanitization | |
| 105 | - [ ] Add error handling | |
| 106 | - [ ] Add comprehensive docstrings and type hints | |
| 107 | - [ ] Create tests for command execution | |
| 108 | - [ ] Test simple command execution | |
| 109 | - [ ] Test command with arguments | |
| 110 | - [ ] Test command with timeout | |
| 111 | - [ ] Test invalid command handling | |
| 112 | - [ ] Test input sanitization | |
| 113 | - [ ] Update `tools/__init__.py` to expose system tools | |
| 114 | - [ ] Create example script for command execution | |
| 115 | - [ ] Implement `examples/command_execution.py` | |
| 116 | ||
| 117 | ### Step 3.2: File Operations | |
| 118 | - [ ] Add file operation functions to `tools/system_tools.py` | |
| 119 | - [ ] Implement `read_file` function | |
| 120 | - [ ] Add file reading with size limit | |
| 121 | - [ ] Add error handling | |
| 122 | - [ ] Implement `write_file` function | |
| 123 | - [ ] Add file writing with mode options | |
| 124 | - [ ] Add error handling | |
| 125 | - [ ] Implement `find_files` function | |
| 126 | - [ ] Add pattern matching with glob | |
| 127 | - [ ] Add recursive option | |
| 128 | - [ ] Add error handling | |
| 129 | - [ ] Add input validation and security checks | |
| 130 | - [ ] Add comprehensive docstrings and type hints | |
| 131 | - [ ] Update tests for file operations | |
| 132 | - [ ] Test `read_file` function | |
| 133 | - [ ] Test `write_file` function | |
| 134 | - [ ] Test `find_files` function | |
| 135 | - [ ] Test error handling | |
| 136 | - [ ] Update or create example script for file operations | |
| 137 | ||
| 138 | ### Step 3.3: Integration with Permission System | |
| 139 | - [ ] Update system tools to integrate with permission system | |
| 140 | - [ ] Modify `execute_command` to use permission manager | |
| 141 | - [ ] Modify `read_file` to use permission manager | |
| 142 | - [ ] Modify `write_file` to use permission manager | |
| 143 | - [ ] Modify `find_files` to use permission manager | |
| 144 | - [ ] Add error handling for permission denied | |
| 145 | - [ ] Update docstrings | |
| 146 | - [ ] Update tests for permission integration | |
| 147 | - [ ] Test permission granted scenarios | |
| 148 | - [ ] Test permission denied scenarios | |
| 149 | - [ ] Create example script for secure system tools | |
| 150 | - [ ] Implement `examples/secure_system_tools.py` | |
| 151 | ||
| 152 | ## Phase 4: Web Tools Development | |
| 153 | ||
| 154 | ### Step 4.1: Basic Web Request Functions | |
| 155 | - [ ] Implement basic functions in `tools/web_tools.py` | |
| 156 | - [ ] Create `fetch_url` function | |
| 157 | - [ ] Add HTTP request handling with requests library | |
| 158 | - [ ] Add support for different HTTP methods | |
| 159 | - [ ] Add error handling | |
| 160 | - [ ] Add timeout handling | |
| 161 | - [ ] Add input validation | |
| 162 | - [ ] Add comprehensive docstrings and type hints | |
| 163 | - [ ] Create tests for web tools | |
| 164 | - [ ] Test successful requests | |
| 165 | - [ ] Test error handling | |
| 166 | - [ ] Test timeout handling | |
| 167 | - [ ] Test different HTTP methods | |
| 168 | - [ ] Test parameter handling | |
| 169 | - [ ] Update `tools/__init__.py` to expose web tools | |
| 170 | - [ ] Create example script for web requests | |
| 171 | - [ ] Implement `examples/web_request.py` | |
| 172 | ||
| 173 | ### Step 4.2: Advanced Web Tools | |
| 174 | - [ ] Add advanced web tools to `tools/web_tools.py` | |
| 175 | - [ ] Implement `get_weather` function | |
| 176 | - [ ] Add weather API integration | |
| 177 | - [ ] Add error handling | |
| 178 | - [ ] Add input validation | |
| 179 | - [ ] Implement `search_web` function | |
| 180 | - [ ] Add search API integration | |
| 181 | - [ ] Add error handling | |
| 182 | - [ ] Add input validation | |
| 183 | - [ ] Add API key management | |
| 184 | - [ ] Add comprehensive docstrings and type hints | |
| 185 | - [ ] Update tests for advanced web tools | |
| 186 | - [ ] Test `get_weather` function | |
| 187 | - [ ] Test `search_web` function | |
| 188 | - [ ] Test error handling | |
| 189 | - [ ] Test parameter validation | |
| 190 | - [ ] Create or update example scripts | |
| 191 | - [ ] Implement `examples/web_tools_examples.py` | |
| 192 | - [ ] Update config module for API keys | |
| 193 | - [ ] Add weather_api_key parameter | |
| 194 | - [ ] Add search_api_key parameter | |
| 195 | ||
| 196 | ### Step 4.3: Integration with Permission System | |
| 197 | - [ ] Update web tools to integrate with permission system | |
| 198 | - [ ] Modify `fetch_url` to use permission manager | |
| 199 | - [ ] Modify `get_weather` to use permission manager | |
| 200 | - [ ] Modify `search_web` to use permission manager | |
| 201 | - [ ] Add error handling for permission denied | |
| 202 | - [ ] Update docstrings | |
| 203 | - [ ] Update tests for permission integration | |
| 204 | - [ ] Test permission granted scenarios | |
| 205 | - [ ] Test permission denied scenarios | |
| 206 | - [ ] Create example script for secure web tools | |
| 207 | - [ ] Implement `examples/secure_web_tools.py` | |
| 208 | ||
| 209 | ## Phase 5: Documentation Tools Development | |
| 210 | ||
| 211 | ### Step 5.1: Basic Documentation Tools | |
| 212 | - [ ] Implement basic functions in `tools/doc_tools.py` | |
| 213 | - [ ] Create `generate_markdown` function | |
| 214 | - [ ] Add markdown generation | |
| 215 | - [ ] Add HTML generation option | |
| 216 | - [ ] Add input validation | |
| 217 | - [ ] Add comprehensive docstrings and type hints | |
| 218 | - [ ] Create tests for documentation tools | |
| 219 | - [ ] Test markdown generation | |
| 220 | - [ ] Test HTML generation | |
| 221 | - [ ] Test with various inputs | |
| 222 | - [ ] Test with empty or invalid inputs | |
| 223 | - [ ] Update `tools/__init__.py` to expose documentation tools | |
| 224 | - [ ] Create example script for documentation tools | |
| 225 | - [ ] Implement `examples/documentation_tools.py` | |
| 226 | ||
| 227 | ### Step 5.2: Advanced Documentation Tools | |
| 228 | - [ ] Add advanced documentation tools to `tools/doc_tools.py` | |
| 229 | - [ ] Implement `extract_context` function | |
| 230 | - [ ] Add keyword-based context extraction | |
| 231 | - [ ] Add length limitation | |
| 232 | - [ ] Add error handling | |
| 233 | - [ ] Implement `summarize_text` function | |
| 234 | - [ ] Add extractive summarization | |
| 235 | - [ ] Add length limitation | |
| 236 | - [ ] Add error handling | |
| 237 | - [ ] Add input validation | |
| 238 | - [ ] Add comprehensive docstrings and type hints | |
| 239 | - [ ] Update tests for advanced documentation tools | |
| 240 | - [ ] Test `extract_context` function | |
| 241 | - [ ] Test `summarize_text` function | |
| 242 | - [ ] Test with various inputs | |
| 243 | - [ ] Test with empty or invalid inputs | |
| 244 | - [ ] Update example script for documentation tools | |
| 245 | ||
| 246 | ### Step 5.3: Integration with Permission System | |
| 247 | - [ ] Update documentation tools to integrate with permission system | |
| 248 | - [ ] Modify `generate_markdown` to use permission manager | |
| 249 | - [ ] Modify `extract_context` to use permission manager | |
| 250 | - [ ] Modify `summarize_text` to use permission manager | |
| 251 | - [ ] Add error handling for permission denied | |
| 252 | - [ ] Update docstrings | |
| 253 | - [ ] Update tests for permission integration | |
| 254 | - [ ] Test permission granted scenarios | |
| 255 | - [ ] Test permission denied scenarios | |
| 256 | - [ ] Create example script for secure documentation tools | |
| 257 | - [ ] Implement `examples/secure_doc_tools.py` | |
| 258 | ||
| 259 | ## Phase 6: Core Agent Implementation | |
| 260 | ||
| 261 | ### Step 6.1: Basic OllamaAgent | |
| 262 | - [ ] Implement `agent.py` module with `OllamaAgent` class | |
| 263 | - [ ] Add initialization with parameters | |
| 264 | - [ ] model (default="llama3.1") | |
| 265 | - [ ] host (default="http://localhost:11434") | |
| 266 | - [ ] permission_prompts (default=True) | |
| 267 | - [ ] sudo_always_prompt (default=True) | |
| 268 | - [ ] Initialize permission manager | |
| 269 | - [ ] Implement basic `chat` method | |
| 270 | - [ ] Add Ollama client integration | |
| 271 | - [ ] Add message forwarding | |
| 272 | - [ ] Add placeholder for `register_tools` method | |
| 273 | - [ ] Add comprehensive docstrings and type hints | |
| 274 | - [ ] Create tests for OllamaAgent | |
| 275 | - [ ] Test initialization | |
| 276 | - [ ] Test basic chat functionality | |
| 277 | - [ ] Test error handling | |
| 278 | - [ ] Update main `__init__.py` to expose OllamaAgent | |
| 279 | - [ ] Create example script for basic agent | |
| 280 | - [ ] Implement `examples/basic_agent.py` | |
| 281 | ||
| 282 | ### Step 6.2: Function Registration | |
| 283 | - [ ] Update `OllamaAgent` class for function registration | |
| 284 | - [ ] Implement `register_tools` method | |
| 285 | - [ ] Add function collection from tools modules | |
| 286 | - [ ] Add formatting for Ollama schema | |
| 287 | - [ ] Add registration with Ollama client | |
| 288 | - [ ] Add function definition parsing | |
| 289 | - [ ] Add error handling | |
| 290 | - [ ] Update docstrings | |
| 291 | - [ ] Update tests for function registration | |
| 292 | - [ ] Test function registration process | |
| 293 | - [ ] Test function definition parsing | |
| 294 | - [ ] Test error handling | |
| 295 | - [ ] Update `tools/__init__.py` for function metadata | |
| 296 | - [ ] Add annotation mechanism for functions | |
| 297 | - [ ] Update example script for function registration | |
| 298 | ||
| 299 | ### Step 6.3: Function Detection and Execution | |
| 300 | - [ ] Update `OllamaAgent` class for function execution | |
| 301 | - [ ] Enhance `chat` method for function detection | |
| 302 | - [ ] Implement `process_function_calls` method | |
| 303 | - [ ] Add function execution | |
| 304 | - [ ] Add result handling | |
| 305 | - [ ] Add permission system integration | |
| 306 | - [ ] Add error handling | |
| 307 | - [ ] Update docstrings | |
| 308 | - [ ] Update tests for function detection and execution | |
| 309 | - [ ] Test function detection | |
| 310 | - [ ] Test function execution | |
| 311 | - [ ] Test error handling | |
| 312 | - [ ] Test permission integration | |
| 313 | - [ ] Create example script for function execution | |
| 314 | - [ ] Implement `examples/function_execution.py` | |
| 315 | ||
| 316 | ## Phase 7: Integration and Final Testing | |
| 317 | ||
| 318 | ### Step 7.1: Comprehensive Integration | |
| 319 | - [ ] Update `OllamaAgent` class for full integration | |
| 320 | - [ ] Ensure integration with configuration management | |
| 321 | - [ ] Ensure integration with permission system | |
| 322 | - [ ] Ensure integration with system tools | |
| 323 | - [ ] Ensure integration with web tools | |
| 324 | - [ ] Ensure integration with documentation tools | |
| 325 | - [ ] Add missing connections | |
| 326 | - [ ] Ensure consistent error handling | |
| 327 | - [ ] Update docstrings | |
| 328 | - [ ] Create comprehensive integration tests | |
| 329 | - [ ] Implement `tests/test_integration.py` | |
| 330 | - [ ] Test complete workflow | |
| 331 | - [ ] Test component interactions | |
| 332 | - [ ] Test error propagation | |
| 333 | - [ ] Create comprehensive example script | |
| 334 | - [ ] Implement `examples/complete_example.py` | |
| 335 | - [ ] Update README.md with comprehensive documentation | |
| 336 | - [ ] Add detailed installation instructions | |
| 337 | - [ ] Add comprehensive usage examples | |
| 338 | - [ ] Add documentation for all features | |
| 339 | ||
| 340 | ### Step 7.2: Error Handling and Edge Cases | |
| 341 | - [ ] Review and update error handling in all modules | |
| 342 | - [ ] Ensure consistent error types and messages | |
| 343 | - [ ] Add custom exception classes if needed | |
| 344 | - [ ] Improve error messages | |
| 345 | - [ ] Add tests for edge cases | |
| 346 | - [ ] Test with invalid inputs | |
| 347 | - [ ] Test with extreme values | |
| 348 | - [ ] Test with unexpected responses | |
| 349 | - [ ] Test error propagation | |
| 350 | - [ ] Create example script for error handling | |
| 351 | - [ ] Implement `examples/error_handling.py` | |
| 352 | - [ ] Update documentation for error handling | |
| 353 | - [ ] Add sections on error types | |
| 354 | - [ ] Add examples of error handling | |
| 355 | ||
| 356 | ### Step 7.3: Performance Optimization | |
| 357 | - [ ] Review and optimize performance in all modules | |
| 358 | - [ ] Add caching where appropriate | |
| 359 | - [ ] Optimize resource-intensive operations | |
| 360 | - [ ] Add resource usage control options | |
| 361 | - [ ] Implement asynchronous operations where beneficial | |
| 362 | - [ ] Add performance tests | |
| 363 | - [ ] Implement `tests/test_performance.py` | |
| 364 | - [ ] Test execution time | |
| 365 | - [ ] Test memory usage | |
| 366 | - [ ] Test concurrent operations | |
| 367 | - [ ] Compare optimized and non-optimized performance | |
| 368 | - [ ] Update configuration system for performance options | |
| 369 | - [ ] Add caching parameters | |
| 370 | - [ ] Add resource limitation parameters | |
| 371 | - [ ] Add concurrency parameters | |
| 372 | - [ ] Create example script for performance optimization | |
| 373 | - [ ] Implement `examples/performance_optimization.py` | |
| 374 | ||
| 375 | ### Step 7.4: Documentation and Examples | |
| 376 | - [ ] Complete README.md documentation | |
| 377 | - [ ] Add detailed project overview | |
| 378 | - [ ] Add installation instructions | |
| 379 | - [ ] Add quick start guide | |
| 380 | - [ ] Add configuration options | |
| 381 | - [ ] Add security considerations | |
| 382 | - [ ] Add API reference | |
| 383 | - [ ] Add usage examples | |
| 384 | - [ ] Add troubleshooting section | |
| 385 | - [ ] Create comprehensive API documentation | |
| 386 | - [ ] Use Sphinx-compatible docstrings | |
| 387 | - [ ] Document all classes and methods | |
| 388 | - [ ] Add examples for each function | |
| 389 | - [ ] Document all parameters and return values | |
| 390 | - [ ] Enhance examples directory | |
| 391 | - [ ] Ensure examples for all features | |
| 392 | - [ ] Add comments to all examples | |
| 393 | - [ ] Organize examples logically | |
| 394 | - [ ] Create user guide | |
| 395 | - [ ] Implement `docs/user_guide.md` | |
| 396 | - [ ] Add step-by-step instructions | |
| 397 | - [ ] Add best practices | |
| 398 | - [ ] Add security recommendations | |
| 399 | - [ ] Address common questions | |
| 400 | ||
| 401 | ## Finalization Steps | |
| 402 | ||
| 403 | ### Packaging and Distribution | |
| 404 | - [ ] Complete `setup.py` file | |
| 405 | - [ ] Verify all dependencies | |
| 406 | - [ ] Add entry points if needed | |
| 407 | - [ ] Include package data | |
| 408 | - [ ] Set up version numbering | |
| 409 | - [ ] Create CHANGELOG.md | |
| 410 | - [ ] Document initial release | |
| 411 | - [ ] Prepare for version tracking | |
| 412 | - [ ] Add LICENSE file | |
| 413 | - [ ] Choose appropriate license | |
| 414 | - [ ] Include license text | |
| 415 | - [ ] Create CONTRIBUTING.md | |
| 416 | - [ ] Add contributor guidelines | |
| 417 | - [ ] Add development setup instructions | |
| 418 | - [ ] Add pull request process | |
| 419 | - [ ] Set up continuous integration | |
| 420 | - [ ] Add GitHub Actions workflow | |
| 421 | - [ ] Add linting and code quality checks | |
| 422 | - [ ] Prepare final release | |
| 423 | - [ ] Perform final testing | |
| 424 | - [ ] Review documentation | |
| 425 | - [ ] Confirm version number | |
| 426 | - [ ] Prepare distribution files | |
| 427 | ||
| 428 | ## Additional Tasks | |
| 429 | ||
| 430 | ### Project Management | |
| 431 | - [ ] Set up issue tracking | |
| 432 | - [ ] Create development milestones | |
| 433 | - [ ] Establish project roadmap | |
| 434 | - [ ] Set up project documentation site | |
| 435 | ||
| 436 | ### Community | |
| 437 | - [ ] Create communication channels (e.g., Discord, Slack) | |
| 438 | - [ ] Prepare community guidelines | |
| 439 | - [ ] Plan for initial community outreach | |
| 440 | ||
| 441 | ### Security | |
| 442 | - [ ] Perform security audit | |
| 443 | - [ ] Document security practices | |
| 444 | - [ ] Set up vulnerability reporting process | |
| 445 | ||
| 446 | ### Maintenance | |
| 447 | - [ ] Create maintenance plan | |
| 448 | - [ ] Set up release schedule | |
| 449 | - [ ] Establish deprecation policy | |
| 450 | - [ ] Plan for backward compatibility |