# cedric-ai

**cedric-ai** est une bibliothèque Python qui te permet d'interagir avec **Cédric**, une intelligence artificielle conversationnelle rapide, sans filtre et disponible à la demande.

Cédric répond à tes questions, discute de n'importe quel sujet, génère du texte, et s'adapte à n'importe quelle personnalité que tu lui donnes. La lib gère automatiquement les cas où le serveur est temporairement hors ligne grâce à un système de **file d'attente persistante** — tes requêtes ne sont jamais perdues.

---

## Installation

```bash
pip install cedric-ai
```

Aucune dépendance externe sauf `requests`. Compatible Python 3.8+.

---

## Accès & Limites

- **Aucun token requis** — l'accès est identifié par ton adresse IP automatiquement
- **500 requêtes gratuites par jour** par adresse IP
- Au delà du quota, les requêtes sont mises en file et traitées le lendemain
- Aucune inscription, aucune clé API à gérer

---

## Démarrage rapide

```python
from cedric_ai import CedricAI

ai = CedricAI()
reponse = ai.ask("C'est quoi Python ?")
print(reponse)
```

---

## Fonctionnalités

- **Requêtes directes** — pose une question, reçois une réponse immédiatement
- **File d'attente automatique** — si le serveur est éteint ou le quota atteint, la requête attend et s'exécute automatiquement
- **Persistance** — la file est sauvegardée sur disque, même si ton script redémarre les jobs reprennent
- **Callbacks** — sois notifié dès qu'une réponse arrive
- **Personnalité personnalisable** — donne un contexte ou une personnalité à Cédric via le paramètre `system`
- **Quota automatique** — 500 requêtes/jour par IP, remis à zéro chaque nuit à minuit

---

## Guide complet

### Requête directe

La façon la plus simple. Bloquant — attend la réponse avant de continuer.

```python
from cedric_ai import CedricAI

ai = CedricAI()

reponse = ai.ask("Explique moi la gravité en deux phrases")
print(reponse)
```

Si le serveur est temporairement indisponible, la lib attend automatiquement jusqu'à `max_wait` secondes (défaut 10 minutes) puis réessaie.

```python
# Attendre max 5 minutes que le serveur revienne
reponse = ai.ask("Bonjour !", max_wait=300)

# Ne pas attendre — lève une erreur si hors ligne
reponse = ai.ask("Bonjour !", wait_if_offline=False)
```

---

### Requête asynchrone avec file d'attente

Idéal quand tu veux envoyer une requête sans bloquer ton programme, ou quand le serveur peut être indisponible.

```python
from cedric_ai import CedricAI

ai = CedricAI()

# Ajoute la requête en file — retourne immédiatement un job_id
job_id = ai.ask_async("Écris moi un poème sur la pluie")
print(f"Job créé : {job_id}")

# Récupère le résultat plus tard (bloquant, max 10 min)
result = ai.wait_for_result(job_id, timeout=600)
print(result)
```

---

### Vérifier le résultat sans bloquer

```python
job_id = ai.ask_async("Raconte moi une blague")

# Vérification non bloquante
result = ai.get_result(job_id)
if result is None:
    print("Pas encore prêt...")
else:
    print(result)
```

---

### Callback — être notifié quand la réponse arrive

```python
def quand_ca_repond(job_id, reponse):
    print(f"[Job {job_id}] Réponse reçue :")
    print(reponse)

job_id = ai.ask_async(
    "Donne moi 5 idées de projets Python",
    callback=quand_ca_repond
)

# Ton programme continue de tourner...
import time
time.sleep(60)  # la réponse arrivera via le callback
```

---

### Personnalité personnalisée

Tu peux donner un contexte ou une personnalité à Cédric via le paramètre `system`.

```python
ASSISTANT_RH = """
Tu es un assistant RH professionnel. Tu réponds de manière formelle,
tu aides à rédiger des offres d'emploi, des contrats, et tu donnes
des conseils en droit du travail français.
"""

reponse = ai.ask(
    "Rédige une offre d'emploi pour un développeur Python senior",
    system=ASSISTANT_RH
)
print(reponse)
```

```python
PROF_MATHS = "Tu es un professeur de mathématiques du lycée. Tu expliques clairement avec des exemples concrets."

reponse = ai.ask("Comment résoudre une équation du second degré ?", system=PROF_MATHS)
```

---

### Statut de la file d'attente

```python
status = ai.queue_status()
print(status)
# {
#   "online": True,
#   "pending": 2,
#   "done": 8,
#   "errors": 0,
#   "total": 10
# }
```

---

### Nettoyer les jobs terminés

```python
ai.clear_done()  # supprime les jobs avec status "done" du fichier de file
```

---

### Vérifier si le serveur est disponible

```python
if ai.is_online():
    print("Serveur disponible ✅")
else:
    print("Serveur hors ligne ❌")
```

---

## Référence des paramètres

### `CedricAI(...)`

| Paramètre        | Type   | Défaut                  | Description                                                  |
|------------------|--------|-------------------------|--------------------------------------------------------------|
| `queue_mode`     | `bool` | `True`                  | Active la file d'attente automatique si serveur hors ligne  |
| `queue_file`     | `str`  | `"cedric_queue.json"`   | Chemin du fichier de persistance de la file                  |
| `retry_interval` | `int`  | `30`                    | Secondes entre chaque tentative de reconnexion               |
| `timeout`        | `int`  | `120`                   | Timeout maximum par requête en secondes                      |

### `ask(prompt, system, wait_if_offline, max_wait)`

| Paramètre         | Type   | Défaut | Description                                        |
|-------------------|--------|--------|----------------------------------------------------|
| `prompt`          | `str`  | —      | Ta question ou instruction                         |
| `system`          | `str`  | `None` | Contexte / personnalité donnée à Cédric            |
| `wait_if_offline` | `bool` | `True` | Attend que le serveur soit disponible si `True`    |
| `max_wait`        | `int`  | `600`  | Secondes max d'attente si serveur indisponible    |

### `ask_async(prompt, system, callback)`

| Paramètre  | Type       | Défaut | Description                                                      |
|------------|------------|--------|------------------------------------------------------------------|
| `prompt`   | `str`      | —      | Ta question ou instruction                                       |
| `system`   | `str`      | `None` | Contexte / personnalité                                          |
| `callback` | `callable` | `None` | Fonction appelée avec `(job_id, reponse)` quand c'est prêt      |

### `wait_for_result(job_id, timeout)`

| Paramètre | Type  | Défaut | Description                       |
|-----------|-------|--------|-----------------------------------|
| `job_id`  | `str` | —      | L'ID retourné par `ask_async()`  |
| `timeout` | `int` | `600`  | Secondes max avant `TimeoutError` |

---

## Gestion des erreurs

```python
from cedric_ai import CedricAI

ai = CedricAI()

try:
    reponse = ai.ask("Bonjour", wait_if_offline=False)
except ConnectionError:
    print("Serveur indisponible")
except PermissionError:
    print("Quota journalier atteint (500 requêtes/jour)")
except TimeoutError:
    print("Timeout dépassé")
except Exception as e:
    print(f"Erreur inattendue : {e}")
```

---

## Exemple complet — chatbot en ligne de commande

```python
from cedric_ai import CedricAI

ai = CedricAI(retry_interval=15)

print(f"Serveur en ligne : {ai.is_online()}")
print("Tape 'exit' pour quitter\n")

while True:
    question = input("Toi : ").strip()
    if question.lower() == "exit":
        break
    if not question:
        continue
    try:
        reponse = ai.ask(question, max_wait=120)
        print(f"Cédric : {reponse}\n")
    except PermissionError:
        print("⚠️ Quota de 500 requêtes/jour atteint\n")
    except TimeoutError:
        print("⏱️ Serveur pas disponible, réessaie plus tard\n")
    except Exception as e:
        print(f"❌ Erreur : {e}\n")
```

---

## Licence

MIT
