Update TOOLS.md, cron jobs, KB index; add discord file sender + pocket-tts plan

Pre-existing work committed before starting Ralph self-improvement run on
ralph/echo-improve branch, so that branch's diff stays isolated to the
pocket-tts integration.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 09:54:36 +00:00
parent 738dc0181a
commit 155d6cb9c1
8 changed files with 345 additions and 17 deletions

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env python3
"""Trimite un fișier (audio, imagine, etc.) direct într-un canal Discord.
De ce există: `__AUDIO__:<path>` (folosit de fast_commands.py) e interceptat
de discord_bot.py DOAR când niciun bloc de text n-a fost deja streamat pe
canal în turul curent. Într-un răspuns conversațional normal (acest proces,
`claude_session.py`), fiecare bloc de text pe care Claude îl produce e
trimis live prin `on_text` înainte ca răspunsul final să fie evaluat —
deci prefixul `__AUDIO__:` ajunge mereu trimis ca text brut, nu convertit
în attachment. Singura cale de a atașa un fișier dintr-un răspuns Claude
obișnuit e apelul direct la REST API-ul Discord, cu tokenul botului.
CLI:
python3 tools/discord_send_file.py --channel <id> --file /path/audio.wav [--text "mesaj"]
Modul:
from tools.discord_send_file import send_file
send_file(channel_id, "/path/audio.wav", content="mesaj opțional")
Channel ID: dacă nu-l știi din conversație, citește `sessions/active.json`
(cheia e channel_id-ul; de obicei există o singură sesiune activă).
"""
import argparse
import mimetypes
import sys
import httpx
sys.path.insert(0, "/home/moltbot/echo-core")
from src.credential_store import get_secret
def send_file(channel_id: str, path: str, content: str | None = None, filename: str | None = None) -> dict:
"""Trimite un fișier direct pe canalul Discord dat, via REST API.
Returns: {"ok": True, "message_id": "..."} sau {"ok": False, "error": "..."}
"""
token = get_secret("discord_token")
if not token:
return {"ok": False, "error": "discord_token lipsește din keyring (echo-core)."}
filename = filename or path.rsplit("/", 1)[-1]
mime = mimetypes.guess_type(filename)[0] or "application/octet-stream"
try:
with httpx.Client(timeout=30) as client, open(path, "rb") as f:
resp = client.post(
f"https://discord.com/api/v10/channels/{channel_id}/messages",
headers={"Authorization": f"Bot {token}"},
files={"file": (filename, f, mime)},
data={"content": content} if content else {},
)
if resp.status_code not in (200, 201):
return {"ok": False, "error": f"HTTP {resp.status_code}: {resp.text[:300]}"}
return {"ok": True, "message_id": resp.json().get("id")}
except Exception as e:
return {"ok": False, "error": str(e)}
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Trimite un fișier direct pe un canal Discord")
parser.add_argument("--channel", required=True, help="Channel ID Discord")
parser.add_argument("--file", required=True, help="Cale către fișierul de trimis")
parser.add_argument("--text", default=None, help="Text opțional care însoțește fișierul")
args = parser.parse_args()
result = send_file(args.channel, args.file, content=args.text)
print(result)
sys.exit(0 if result.get("ok") else 1)