From 8c49339452ebcd994ed1aa8749f28777f07ca0f6 Mon Sep 17 00:00:00 2001 From: Rune Olsen Date: Thu, 8 Jan 2026 15:00:59 +0100 Subject: [PATCH] Minor bug fixes --- README.md | 21 ++++++------------- oai.py | 63 ++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index a3c2e5d..c07b3af 100644 --- a/README.md +++ b/README.md @@ -101,24 +101,10 @@ Download platform-specific binaries: # Extract and install unzip oai_vx.x.x_mac_arm64.zip # or `oai_vx.x.x-linux-x86_64.zip` chmod +x oai -mkdir -p ~/.local/bin +mkdir -p ~/.local/bin # Remember to add this to your path. Or just move to folder already in your $PATH mv oai ~/.local/bin/ ``` -### Option 3: Build Your Own Binary - -```bash -# Install build dependencies -pip install -r requirements.txt -pip install nuitka ordered-set zstandard - -# Run build script -chmod +x build.sh -./build.sh - -# Binary will be in dist/oai -cp dist/oai ~/.local/bin/ -``` ### Alternative: Shell Alias @@ -508,6 +494,7 @@ Full license: https://opensource.org/licenses/MIT **Rune Olsen** +- Homepage: https://ai.fubar.pm/ - Blog: https://blog.rune.pm - Project: https://iurl.no/oai @@ -527,3 +514,7 @@ Contributions welcome! Please: --- **Star ⭐ this project if you find it useful!** + +--- + +Did you really read all the way down here? WOW! You deserve a 🍾 🥂! diff --git a/oai.py b/oai.py index d58266b..339c744 100644 --- a/oai.py +++ b/oai.py @@ -4650,25 +4650,55 @@ def chat(): file_attachments = [] content_blocks = [] - # Smart file detection with extension whitelist - # Only matches files with known extensions or clear path prefixes - # - # Valid matches: - # @/path/to/file - # @~/file.txt - # @./script.py - # @report.pdf - # - # Excludes: - # @domain.com (no whitelisted extension) - # @mail.server.eu (TLD not in whitelist) - # user@domain.com (email pattern) - # Diagnostic-Code: @server.eu (TLD not in whitelist) + # Smart file detection: Simple pattern + extension validation + # This avoids extremely long regex that can cause binary signing issues - file_pattern = r'(?:^|\s)@((?:[~/][\S]+)|(?:\.[\S]+)|(?:[\w][\w-]*\.(?:py|txt|md|log|json|csv|pdf|png|jpg|jpeg|gif|bmp|webp|svg|ico|zip|tar|gz|bz2|7z|rar|xz|js|ts|jsx|tsx|vue|html|css|scss|sass|less|xml|yaml|yml|toml|ini|conf|cfg|env|properties|sh|bash|zsh|fish|bat|cmd|ps1|c|cpp|cc|cxx|h|hpp|hxx|java|class|jar|war|rb|go|rs|swift|kt|kts|php|sql|db|sqlite|sqlite3|lock|gitignore|dockerignore|editorconfig|eslintrc|prettierrc|babelrc|nvmrc|npmrc|pyc|pyo|pyd|so|dll|dylib|exe|app|dmg|pkg|deb|rpm|apk|ipa|wasm|proto|graphql|graphqls|grpc|avro|parquet|orc|feather|arrow|hdf5|h5|mat|r|rdata|rds|pkl|pickle|joblib|npy|npz|safetensors|onnx|pt|pth|ckpt|pb|tflite|mlmodel|coreml|rknn)))(?=\s|$)' + # Common file extensions we support + ALLOWED_FILE_EXTENSIONS = { + # Code + '.py', '.js', '.ts', '.jsx', '.tsx', '.vue', '.java', '.c', '.cpp', '.cc', '.cxx', + '.h', '.hpp', '.hxx', '.rb', '.go', '.rs', '.swift', '.kt', '.kts', '.php', + '.sh', '.bash', '.zsh', '.fish', '.bat', '.cmd', '.ps1', + # Data + '.json', '.csv', '.yaml', '.yml', '.toml', '.xml', '.sql', '.db', '.sqlite', '.sqlite3', + # Documents + '.txt', '.md', '.log', '.conf', '.cfg', '.ini', '.env', '.properties', + # Images + '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.svg', '.ico', + # Archives + '.zip', '.tar', '.gz', '.bz2', '.7z', '.rar', '.xz', + # Config files + '.lock', '.gitignore', '.dockerignore', '.editorconfig', '.eslintrc', + '.prettierrc', '.babelrc', '.nvmrc', '.npmrc', + # Binary/Compiled + '.pyc', '.pyo', '.pyd', '.so', '.dll', '.dylib', '.exe', '.app', + '.dmg', '.pkg', '.deb', '.rpm', '.apk', '.ipa', + # ML/AI + '.pkl', '.pickle', '.joblib', '.npy', '.npz', '.safetensors', '.onnx', + '.pt', '.pth', '.ckpt', '.pb', '.tflite', '.mlmodel', '.coreml', '.rknn', + # Data formats + '.wasm', '.proto', '.graphql', '.graphqls', '.grpc', '.avro', '.parquet', + '.orc', '.feather', '.arrow', '.hdf5', '.h5', '.mat', '.r', '.rdata', '.rds', + # Other + '.pdf', '.class', '.jar', '.war' + } + + # Simple pattern: @filepath where filepath starts with ~, /, . or has an extension + # Much shorter than listing all extensions in the regex + file_pattern = r'(?:^|\s)@([~/\.][\S]+|[\w][\w-]*\.[\w]+)(?=\s|$)' for match in re.finditer(file_pattern, user_input, re.IGNORECASE): file_path = match.group(1) + + # Get the extension + file_ext = os.path.splitext(file_path)[1].lower() + + # Skip if it doesn't start with a path char and has no allowed extension + if not file_path.startswith(('/', '~', '.', '\\')): + if not file_ext or file_ext not in ALLOWED_FILE_EXTENSIONS: + # This looks like a domain name, not a file + continue + expanded_path = os.path.expanduser(os.path.abspath(file_path)) if not os.path.exists(expanded_path) or os.path.isdir(expanded_path): @@ -4681,7 +4711,6 @@ def chat(): continue mime_type, _ = mimetypes.guess_type(expanded_path) - file_ext = os.path.splitext(expanded_path)[1].lower() try: with open(expanded_path, 'rb') as f: @@ -4729,7 +4758,7 @@ def chat(): app_logger.error(f"File read error for {expanded_path}: {e}") continue - # Remove file attachments from text (use same pattern as file detection) + # Remove file attachments from text (use same simple pattern) text_part = re.sub(file_pattern, lambda m: m.group(0)[0] if m.group(0)[0].isspace() else '', text_part).strip() # Build message content