Skip to content

voice_mac_tools

voice_mac_tools

macOS-oriented tools for live voice (calendar, Spotify, files).

Classes

CalendarQueryTool

Bases: BaseTool

Query macOS Calendar for today/tomorrow events (AppleScript).

SpotifyPlayTool

Bases: BaseTool

Search / play music via Spotify URI or AppleScript.

FindFilesTool

Bases: BaseTool

Search files on the Mac (mdfind) or via recursive name match.

MailComposeTool

Bases: BaseTool

Open a Mail.app draft (compose only — never auto-sends).

MessagesComposeTool

Bases: BaseTool

Open a Messages.app draft (compose only — never auto-sends).

MailSendTool

Bases: BaseTool

Send the frontmost Mail draft — only when confirm=true (spoken yes).

MessagesSendTool

Bases: BaseTool

Send an iMessage/SMS — only when confirm=true (spoken yes).

MessagesStatusTool

Bases: BaseTool

L'état réel d'un envoi iMessage — lu dans chat.db, jamais inventé.

FileTrashTool

Bases: BaseTool

Mettre des fichiers à la corbeille — la quarantaine réversible de macOS.

Atlas, panier « Ensuite », 24 août 2026. Aucun outil ne savait déplacer ni supprimer un fichier ; le périmètre choisi est le plus sûr qui soit utile : la CORBEILLE, via le Finder — réversible d'un « Remettre », avec une interface de restauration que l'utilisateur connaît déjà. Pas de déplacement libre vers un dossier arbitraire, pas de glob, pas de récursif : une liste EXPLICITE de chemins, et c'est tout.

Functions:

interpreter_quand

interpreter_quand(quand: str, aujourd_hui=None)

« jeudi », « semaine prochaine », « 2026-08-28 »… → (décalage, durée, étiquette).

Rend None quand la formulation est illisible — l'outil l'AVOUE alors, au lieu de retomber en silence sur aujourd'hui et de donner le mauvais jour avec aplomb (Atlas, 24 août 2026 : seuls today/tomorrow étaient compris, tout le reste devenait « aujourd'hui »).

Source code in src/diapason/tools/voice_mac_tools.py
def interpreter_quand(quand: str, aujourd_hui=None):
    """« jeudi », « semaine prochaine », « 2026-08-28 »… → (décalage, durée, étiquette).

    Rend None quand la formulation est illisible — l'outil l'AVOUE alors,
    au lieu de retomber en silence sur aujourd'hui et de donner le mauvais
    jour avec aplomb (Atlas, 24 août 2026 : seuls today/tomorrow étaient
    compris, tout le reste devenait « aujourd'hui »).
    """
    import datetime as _dt

    if aujourd_hui is None:
        aujourd_hui = _dt.date.today()
    w = (quand or "today").strip().lower().replace("'", "'")
    w = w.replace("l'agenda de ", "").replace("le ", "").strip()

    if w in ("today", "aujourd'hui", "aujourdhui", ""):
        return 0, 1, "aujourd'hui"
    if w in ("tomorrow", "demain"):
        return 1, 1, "demain"
    if w in ("après-demain", "apres-demain", "après demain", "apres demain"):
        return 2, 1, "après-demain"
    if w in ("semaine", "cette semaine", "week", "this week"):
        return 0, 7, "les 7 prochains jours"
    if w in ("semaine prochaine", "la semaine prochaine", "next week"):
        lundi = (7 - aujourd_hui.weekday()) % 7 or 7
        return lundi, 7, "la semaine prochaine"
    if w in ("week-end", "weekend", "ce week-end", "ce weekend"):
        samedi = (5 - aujourd_hui.weekday()) % 7
        return samedi, 2, "le week-end"
    for nom, cible in _JOURS_SEMAINE.items():
        if w == nom or w == f"{nom} prochain":
            ecart = (cible - aujourd_hui.weekday()) % 7
            if ecart == 0 and w.endswith("prochain"):
                ecart = 7
            return ecart, 1, nom
    try:
        cible_date = _dt.date.fromisoformat(w)
        return (cible_date - aujourd_hui).days, 1, cible_date.strftime("%d/%m")
    except ValueError:
        return None