File size: 2,408 Bytes
53b2ac9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# SPDX-License-Identifier: MIT
"""
Hash Plugin for TrashClaw

Compute cryptographic hashes (MD5, SHA-1, SHA-256, SHA-512) of text or files.

Plugin contract:
  TOOL_DEF = dict with name, description, parameters (OpenAI function schema)
  run(**kwargs) -> str  (called with the parsed arguments)
"""

import hashlib
import os

TOOL_DEF = {
    "name": "hash",
    "description": "Compute cryptographic hash (MD5, SHA-1, SHA-256, SHA-512) of text or a file.",
    "parameters": {
        "type": "object",
        "properties": {
            "text": {
                "type": "string",
                "description": "Text to hash"
            },
            "file": {
                "type": "string",
                "description": "Path to file to hash (optional)"
            },
            "algorithm": {
                "type": "string",
                "description": "Hash algorithm: md5, sha1, sha256, sha512 (default: sha256)"
            }
        },
        "required": []
    }
}


def _hash_text(text: str, algorithm: str) -> str:
    try:
        h = hashlib.new(algorithm)
        h.update(text.encode("utf-8"))
        return h.hexdigest()
    except ValueError:
        return f"Error: unsupported algorithm '{algorithm}'"


def _hash_file(path: str, algorithm: str) -> str:
    if not os.path.exists(path):
        return f"Error: file not found: {path}"
    try:
        h = hashlib.new(algorithm)
        with open(path, "rb") as f:
            for chunk in iter(lambda: f.read(8192), b""):
                h.update(chunk)
        return h.hexdigest()
    except ValueError:
        return f"Error: unsupported algorithm '{algorithm}'"
    except Exception as e:
        return f"Error: {e}"


def run(text: str = "", file: str = "", algorithm: str = "sha256", **kwargs) -> str:
    algorithm = algorithm.lower().replace("-", "")
    supported = ["md5", "sha1", "sha256", "sha512"]

    if algorithm not in supported:
        return f"Unsupported algorithm '{algorithm}'. Use: {', '.join(supported)}"

    results = []

    if file:
        digest = _hash_file(file, algorithm)
        results.append(f"{algorithm.upper()}({file}):\n{digest}")

    if text:
        digest = _hash_text(text, algorithm)
        results.append(f"{algorithm.upper()}(text):\n{digest}")

    if not text and not file:
        return "Error: provide 'text' or 'file' to hash."

    return "\n\n".join(results)