🍬  3 ans · 1 000 000+ utilisateurs · Cedric8-Thinking · v21 BETA

Trois ans à vos côtés.
candy v21 — notre version la plus ambitieuse.

En avril 2023, la première ligne de candy était poussée avec une seule personnalité. Aujourd'hui, plus d'un million de personnes — étudiants, startups, chercheurs, ingénieurs séniors — l'utilisent quotidiennement. Merci. La v21 est pour vous.

3
années d'existence
1M+
utilisateurs
120
personnalités
21
versions majeures
✦ ✦ ✦ ✦ ✦

Démarrage

Installation

Une seule commande. Aucune clé API. Aucun compte. Python 3.10+.

terminal
# Stable
pip install candy-ai

# v21 BETA
pip install candy-ai==21.0.0b1

candy se connecte automatiquement au moteur Cedric8-Thinking. Fonctionne sur Windows, macOS et Linux.


Démarrage

Premier appel

Un import, une ligne. Comme depuis le premier jour.

hello.py
from candy import Coding
print(Coding.ask("Écris une fonction Python qui inverse une chaîne"))

Personnalités

120 personnalités spécialisées

On a commencé à 50 en 2023. On est maintenant à 120. Chacune optimisée pour son domaine.

persos.py
from candy import Math, Writing, Medicine, Law, Finance

print(Math.ask("Quelle est la dérivée de x³ + 2x ?"))
print(Writing.ask("Écris un email pour décliner une réunion"))
print(Medicine.ask("Symptômes du diabète de type 2 ?"))
print(Finance.ask("Explique les intérêts composés"))

Configuration

Système de profils

Contrôle la langue, le style, le ton, la longueur, la température. Tout.

profils.py
from candy import cfg, Coding

cfg.A.lang        = "FR"
cfg.A.style       = "detailed"
cfg.A.tone        = "encouraging"
cfg.A.expertise   = "beginner"
cfg.A.max_tokens  = 2000
cfg.A.temperature = 0.7
cfg.A.max_retries = 3

print(Coding.use("A").ask("Explique la récursivité"))
ParamètreTypeValeurs
langstrFR, EN, ES, DE, IT, PT, JA, ZH, AR, RU…
stylestrdetailed, concise, technical, casual, bullet, markdown, eli5
tonestrneutral, encouraging, strict, humorous, empathetic, socratic
expertisestrbeginner, intermediate, expert
max_tokensinttokens max dans la réponse
temperaturefloat0.0 (précis) → 2.0 (très créatif)
output_formatstrtext, markdown, json, html
max_retriesinttentatives en cas d'échec — défaut 3

Configuration

Presets

14 profils prêts à l'emploi.

presets.py
cfg.A = cfg.preset("coder")            # expert, markdown, 3000 tokens
cfg.B = cfg.preset("french_beginner")  # FR, détaillé, encourageant
cfg.C = cfg.preset("creative")         # casual, temp=1.1
cfg.D = cfg.preset("quick")            # concis, 120 tokens
PresetLangueStyleTokens
french_beginnerFRdetailed · encouraging
french_expertFRconcise · strict · expert
coderENmarkdown · expert3000
academicENmarkdown · expert2000
creativeENcasual · temp=1.11500
teacherENdetailed · encouraging2000
quickENconcise120
storytellerENcasual · temp=1.24096
analystENbullet · expert2000
debugENmarkdown · expert3000

Fonctionnalités

Streaming

Réponses token par token pour les interfaces terminal et les apps web.

streaming.py
from candy import Writing

Writing.stream_print("Raconte une histoire courte")

for token in Writing.stream("Raconte une histoire courte"):
    print(token, end="", flush=True)

Fonctionnalités

Batch

Plusieurs prompts en un seul appel. En parallèle avec batch_async.

batch.py
from candy import cfg, Summarizer

cfg.A.lang = "FR" ; cfg.A.max_tokens = 300
textes = ["Article 1…", "Article 2…", "Article 3…"]

resumes = Summarizer.use("A").batch([f"Résume :\n{t}" for t in textes])
for r in resumes: print(r)

Fonctionnalités

Conversations multi-tours

Sessions avec mémoire du contexte. Sauvegarde JSON. Rechargement possible.

conversation.py
from candy import cfg, Tutor

cfg.s.lang = "FR" ; cfg.s.tone = "encouraging"
session = Tutor.chat(profile="s")

print(session.say("Je veux apprendre Python. Par où commencer ?"))
print(session.say("Et les listes ?"))

session.save("session.json")
session.show_history()
session.clear()

Intégration

Intégration web

Flask, FastAPI, Django. Avec ask_async pour FastAPI natif.

Flask

app.py
from flask import Flask, request, jsonify
from candy import cfg, Full

app = Flask(__name__) ; cfg.web.lang = "FR"

@app.route("/ask", methods=["POST"])
def ask():
    q = request.get_json().get("question", "")
    return jsonify({"answer": Full.use("web").ask(q)})

FastAPI — async natif

main.py
from fastapi import FastAPI
from pydantic import BaseModel
from candy import Full

app = FastAPI()

class Query(BaseModel):
    question: str

@app.post("/ask")
async def ask(q: Query):
    answer = await Full.ask_async(q.question)
    return {"answer": answer}

CLI

CLI & fichiers .cdy

candy est aussi une commande système complète.

terminal
candy --ask "mon prompt"    # one-liner
candy --score "prompt"      # score qualité 0-100
candy --fix "prompt"        # auto-optimise
candy --status              # statut API
candy helper                # fenêtre Helper graphique
candy -- script.cdy         # exécuter un fichier .cdy

Helper

Helper — génération de code

Génère du code candy complet depuis un template ou une description.

helper.py
from candy import Helper

Helper.list()
Helper.run("chatbot", lang="FR", module="Full")
Helper.run("traduction", texte="Bonjour", langues=["ES","DE","JA"])

Fonctionnalités

Candy — One-liner universel

Détecte automatiquement la meilleure personnalité selon le prompt.

candy.py
from candy import Candy

print(Candy.ask("Explique les décorateurs Python"))  # → Coding
print(Candy.ask("Recette de tiramisu", lang="FR"))   # → Cooking

score = Candy.score("fais un truc")
print(score["score"], score["grade"])              # → 20  F

print(Candy.fix("fais un truc en python"))

Fonctionnalités

Multi-agents

Orchestre plusieurs personnalités en séquence.

agents.py
from candy import Agent, Coding, Debugger, Reviewer

result = Agent.run(
    modules=[Coding, Debugger, Reviewer],
    task="Écris un client REST Python",
    verbose=True
)
print(result["final"])

Fonctionnalités

Mémoire persistante

Sessions nommées dans ~/.candy/sessions/. Auto-versioning inclus.

memory.py
from candy import Memory

mem = Memory("mon_projet")
mem.add("user", "Bonjour !")
mem.save()
mem.save_version("avant-refactor")
print(Memory("mon_projet").as_context(last_n=5))

Fonctionnalités

Validation & JSON

Format garanti. Régénère automatiquement si non conforme.

validation.py
from candy import Cooking, Analytic, ask_validated, ask_json

page = ask_validated(Cooking, "default",
    prompt="Recette. Format:\n- Plat:\n- Ingrédients:\n- Étapes:",
    required_fields=["- Plat:", "- Ingrédients:", "- Étapes:"])

result = ask_json(Analytic, "default",
    prompt='JSON: {"ton": "", "score": 0}\nTexte: Super !')
print(result["ton"], result["score"])

Utilitaires

candy.utils — 20 fonctions

Importables directement depuis candy, sans profil ni config.

utils.py
from candy import detect_lang, translate, summarize, sentiment, keywords
from candy import codegen, cached_ask, pipeline, full_report

print(detect_lang("Hello world"))       # → EN
print(translate("Hello", to="FR"))      # → Bonjour
s = sentiment("Ce produit est fantastique !")
print(s["label"], s["score"])          # → positive  0.95

Fonctionnalités

ImageGen — Génération d'images

Images, variations, descriptions et batch via Cedric8-Thinking.

imagegen.py
from candy import ImageGen

ImageGen.create("un chat astronaute", save="chat.png")
ImageGen.create("robot steampunk", style="photorealistic", size="1024x1024")
ImageGen.variation("orig.png", strength=0.6, save="var.png")
desc = ImageGen.describe("photo.jpg", lang="FR")
print(ImageGen.styles())

Nouveautés v20

Async natif

Async — toutes les méthodes

Toutes les personnalités supportent l'async natif. Compatible FastAPI, asyncio, Jupyter.

// Pourquoi l'async ?

ask_async() est non-bloquant. batch_async() parallélise toutes les requêtes — 10× plus rapide qu'un batch séquentiel.

async.py
import asyncio
from candy import Coding, Math, Writing

result = asyncio.run(Coding.ask_async("Write a bubble sort"))

async def stream_it():
    async for token in Writing.stream_async("Raconte une histoire"):
        print(token, end="", flush=True)

results = asyncio.run(Coding.batch_async(["sort", "reverse", "search"]))

async def multi():
    code, math, text = await asyncio.gather(
        Coding.ask_async("Write a REST client"),
        Math.ask_async("Solve: ∫x²sin(x)dx"),
        Writing.ask_async("Write a haiku about AI"),
    )

Nouveautés v20

Mix & Chain

Mix & Chain — Fusion d'expertises

Mix combine plusieurs expertises en une requête. Chain les enchaîne séquentiellement.

mix.py
from candy import Mix, Chain, Coding, Security, Reviewer, Debugger

result = Mix(Coding, Security).ask("Écris un serveur HTTP sécurisé")
result = Mix(Coding, Security).use("A").ask("Audite ce code")

result = Chain([Coding, Reviewer, Debugger]).run("Écris une API REST")
print(result["final"])    # réponse finale
print(result["steps"])    # résultats intermédiaires

result = Chain([Coding, Reviewer], profile="A").run("...")

Nouveautés v20

Retry + Cache offline

Retry & Cache

Backoff exponentiel automatique. Si l'API est down, candy répond depuis son cache local.

retry.py
from candy import cfg, Coding

cfg.A.max_retries = 5  # 1.5s → 3s → 6s → 12s → 24s

result = Coding.use("A").ask("Explain decorators", use_cache=True)

from candy.client import _client
_client.clear_response_cache()

Nouveautés v20

Conversation+

Conversation+ — Titre, compression, Markdown

Titre auto, compression intelligente de l'historique, export Markdown.

conv_v20.py
from candy import Conversation, Coding

chat = Conversation(Coding, profile="A", auto_compress=True)
print(chat.say("Explique les décorateurs Python"))
print(chat.title)                       # → "Décorateurs Python — exemples"
chat.export_md("conversation.md")
chat.save("chat.json", append=True)    # fusionne

Nouveautés v20

ImageGen Edit & Upscale

ImageGen+ — Inpainting & Upscale

Édition ciblée par masque et amélioration de résolution x2 ou x4.

imagegen_v20.py
from candy import ImageGen

ImageGen.edit("photo.jpg", mask="mask.png",
    prompt="remplace le fond par un coucher de soleil",
    save="editee.png")

ImageGen.upscale("small.png", scale=4, save="big.png")
ImageGen.upscale("photo.jpg", scale=2, save="hd.jpg")

Nouveautés v20

CLI Doctor & Update

CLI+ — candy --doctor & --update

Diagnostic complet et mise à jour automatique en une commande.

terminal
candy --doctor
  [1/4] Version      candy-ai v21.0.0b1 · Cedric8-Thinking
  [2/4] Connexion    ● en ligne  (42 ms)
  [3/4] Quota        ████████░░░░  82/500  (418 restants)
  [4/4] Cache        12 fichiers  (38 Ko)

candy --update       # pip install --upgrade candy-ai

Nouveautés v21

AutoMemory — Mémoire inter-sessions

AutoMemory

candy se souvient automatiquement de tes préférences entre les conversations, sans rechargement manuel. Persisté dans ~/.candy/user_memory.json.

// Comment ça marche

Quand AutoMemory est activée, chaque message de l'utilisateur est analysé. Si candy détecte une préférence ou un fait ("je travaille avec FastAPI", "je préfère le FR"), il le stocke. À la prochaine conversation, ce contexte est injecté automatiquement dans chaque requête.

auto_memory.py
from candy import AutoMemory, Coding

AutoMemory.enable()

chat = Coding.chat()
chat.say("Je préfère toujours des réponses en français")
chat.say("Je travaille sur un projet FastAPI avec Python 3.12")

# La prochaine fois, candy s'en souvient automatiquement
chat2 = Coding.chat()
# → répond en FR, avec le contexte FastAPI/Python 3.12

print(AutoMemory.summary())
AutoMemory.remember("Mon stack : React + FastAPI + PostgreSQL")
AutoMemory.forget("FastAPI")   # oublier un fait précis
AutoMemory.forget()             # tout effacer
AutoMemory.disable()            # désactiver sans effacer

Nouveautés v21

Compare — même prompt, plusieurs personnalités

Compare

Pose la même question à plusieurs personnalités en parallèle et compare les réponses côte à côte.

compare.py
from candy import Compare, Coding, Security, Reviewer
import asyncio

result = Compare(Coding, Security, Reviewer).ask("Comment sécuriser une API REST ?")

result.show()                   # affichage formaté terminal
print(result["coding"])        # réponse de Coding
print(result["security"])      # réponse de Security
name, resp = result.best()      # la plus longue
md = result.to_markdown()       # export Markdown

# Async — toutes en parallèle
result = asyncio.run(Compare(Coding, Security).ask_async("..."))

# Avec profil
result = Compare(Coding, Security).use("A").ask("...")

Nouveautés v21

stream_to_file — Génération longue sans saturer la RAM

stream_to_file

Streame la réponse directement dans un fichier. Idéal pour les romans, les rapports de 10 000 mots, les bases de code volumineuses.

stream_file.py
from candy import Writing, Coding

# Génère et écrit directement sur disque, barre de progression incluse
Writing.stream_to_file(
    "roman.txt",
    "Écris un roman de science-fiction de 5000 mots",
    show_progress=True
)
# → [candy] ✓ 24,831 chars → roman.txt  (18.3s)

Coding.stream_to_file("api.py", "Génère une API REST complète avec FastAPI")

# Append mode — ajoute à un fichier existant
Writing.stream_to_file("journal.txt", "Entrée du jour…", append=True)

# Avec profil personnalisé
Writing.use("A").stream_to_file("article.md", "Écris un article complet sur le RAG")

Nouveautés v21

CandyLogger — Logs structurés JSON

CandyLogger

Loggue chaque appel API en JSONL avec timestamp, personnalité, latence et prompt. Utile pour auditer, débugger en production, analyser les usages.

logger.py
from candy import CandyLogger, Coding

CandyLogger.enable()                  # → ~/.candy/logs/candy.jsonl
CandyLogger.enable("mes_logs.jsonl")   # fichier custom

Coding.ask("Write a sort")             # loggué automatiquement
Coding.ask("Explain recursion")

CandyLogger.tail(n=10)               # 10 derniers appels
print(CandyLogger.stats())            # stats complètes
# → {"total_calls": 42, "avg_latency_ms": 312, "top_personality": "coding", …}

logs = CandyLogger.read(last_n=50, personality="coding")
CandyLogger.clear()
CandyLogger.disable()

Nouveautés v21

ImageGen Animate · StyleTransfer · CompareStyles

ImageGen++ — Animate, StyleTransfer, CompareStyles

Trois nouvelles opérations : génération d'animations GIF, transfert de style artistique, et comparaison de tous les styles en batch.

imagegen_v21.py
from candy import ImageGen

# animate() — génère un GIF animé
ImageGen.animate("un chat qui saute sur la lune", frames=8, save="anim.gif")
ImageGen.animate("vague de l'océan", frames=16, style="watercolor", save="vague.gif")

# style_transfer() — applique le style d'une image sur une autre
ImageGen.style_transfer(
    "mon_portrait.jpg",       # image source (contenu)
    "van_gogh.jpg",            # image style
    strength=0.8,
    save="portrait_van_gogh.png"
)

# compare_styles() — génère la même image dans tous les styles
# → styles/default.png, styles/anime.png, styles/painting.png …
ImageGen.compare_styles("un château médiéval", save_dir="./styles/")

Nouveautés v21

CLI candy logs

CLI+ — candy logs

Consulte et analyse tes logs directement depuis le terminal.

terminal
candy logs              # 10 derniers appels
candy logs --n 50       # 50 derniers appels
candy logs --stats      # statistiques complètes
candy logs --clear      # vider les logs

# Toutes les commandes CLI v21 :
candy --ask "prompt"     candy --score "prompt"
candy --fix "prompt"     candy --dry-run "prompt"
candy --status           candy --doctor
candy --update           candy --version
candy logs               candy helper
candy -- script.cdy

Référence

Toutes les méthodes

MéthodeRetourDescription
.ask(prompt)strAppel simple
.ask(prompt, use_cache=True)strAvec cache offline
.ask_async(prompt)Coroutine[str]Async non-bloquant — v20
.stream_async(prompt)AsyncGeneratorStreaming async — v20
.batch_async(prompts)Coroutine[list]Batch parallèle — v20
.stream_to_file(path, prompt)dictStreaming vers fichier — v21
.use("profil")BoundModuleAttache un profil nommé
.stream(prompt)GeneratorTokens un par un
.stream_print(prompt)strAffiche les tokens
.batch(prompts)list[str]Batch séquentiel
.chat(profile)ConversationSession multi-tours
session.say(msg)strEnvoie un message
session.titlestrTitre auto-généré — v20
session.export_md(path)NoneExport Markdown — v20
session.save(path, append)NoneSauvegarde JSON
Mix(*modules).ask(prompt)strFusion d'expertises — v20
Chain([...]).run(prompt)dictPipeline séquentiel — v20
Compare(*modules).ask(prompt)CompareResultComparaison parallèle — v21
AutoMemory.enable()NoneActive la mémoire inter-sessions — v21
AutoMemory.remember(fact)NoneMémorise un fait — v21
CandyLogger.enable(path?)NoneActive les logs JSONL — v21
CandyLogger.stats()dictStatistiques d'utilisation — v21
ImageGen.animate(prompt)bytesGIF animé — v21
ImageGen.style_transfer(c,s)bytesTransfert de style — v21
ImageGen.compare_styles(prompt)dictTous les styles en batch — v21
ImageGen.edit(img, prompt)bytesInpainting — v20
ImageGen.upscale(img, scale)bytesUpscale x2/x4 — v20
ping()floatLatence en ms
is_online()boolVérifie la connexion
Copié !