Version de développement
Cette documentation décrit la version « next » (develop), non encore publiée. Pour la version stable, basculez sur « v5 » dans l'en-tête.
Développeurs

Grove dans Flow

Référence développeur du fournisseur grove de Flow : clé ai_keys de la configuration du site, ajout automatique du fournisseur, routage des modèles vers la passerelle et messages d'erreur.

Grove dans Flow

Grove est la passerelle d'IA de Frappe. Une seule clé donne accès à deux API : l'API OpenAI sous /openai/v1 et l'API Anthropic sous /anthropic. Flow utilise Grove comme un fournisseur de modèles appelé grove. La clé n'est pas enregistrée dans Flow : elle est lue dans la configuration du site.

Cette page décrit la clé du site, l'ajout automatique du fournisseur, le routage des appels et les erreurs. Pour le comportement vu par l'utilisateur, voir Assistant Flow.

Clé du site : ai_keys

Flow lit la première entrée de la liste ai_keys du fichier site_config.json. Cette entrée doit contenir gateway_url et api_key :

{
  "ai_keys": [
    {"gateway_url": "https://ai.example.com", "api_key": "grove-key"}
  ]
}
  • site_key() (frappe/flow/lib/model.py) renvoie cette entrée, ou None si l'entrée est absente ou si un des deux champs est vide.
  • site_key() lit d'abord frappe.conf. Si la clé n'y est pas, elle relit le fichier avec frappe.get_site_config(), car la configuration en cache peut avoir jusqu'à une minute de retard.
  • Seule la première entrée compte. Les entrées suivantes sont ignorées.

Dodock lit cette clé mais ne l'écrit jamais. Sur Frappe Cloud, Press écrit ai_keys dans la configuration d'un site d'essai de produit (Product Trial), avec une clé Grove d'essai à plafond de crédits. Dokos ne fournit pas de clé Grove. Sur un site auto-hébergé, un administrateur peut écrire l'entrée lui-même s'il a une clé Grove, par exemple avec bench --site <site> set-config -p ai_keys '[{"gateway_url": "…", "api_key": "…"}]'.

Fournisseur grove

La constante SITE_PROVIDER = "grove" (frappe/flow/lib/model.py) nomme le fournisseur. Le document Flow Provider grove n'a pas de clé. LiteLLM ne connaît pas ce fournisseur : la validation de Flow Provider et de Flow Model ne vérifie pas son nom auprès de LiteLLM quand le fournisseur est grove.

resolve_provider_credentials(model_id, provider) prend le fournisseur du modèle en second argument. Pour grove :

  1. Si le Flow Provider grove est désactivé, la fonction lève l'erreur « Grove is turned off. Turn it on, or pick another model, in Settings → Models. ».
  2. Sinon, site_credentials() renvoie api_key et base_url (la valeur de gateway_url) depuis site_key().
  3. Si la configuration n'a plus de clé, site_credentials() lève l'erreur « This site no longer has a Grove key. Connect another provider in Settings → Models. ».

Dans model_config(), une clé saisie sur le Flow Model a priorité sur la clé du site. L'adresse de la passerelle vient toujours de la configuration du site, sauf si le Flow Model a sa propre base_url.

Ajout automatique au premier affichage

boot() (frappe/flow/api/api.py) appelle sync_site_provider() (frappe/flow/api/setup.py) à chaque ouverture de Flow. La fonction :

  1. Ne fait rien si le Flow Provider grove existe déjà, si la valeur de cache flow_grove_down est présente ou si site_key() ne renvoie rien.
  2. Demande GET <gateway_url>/openai/v1/models avec la clé du site, avec un délai maximal de 5 secondes.
  3. Cherche dans la réponse le modèle openai/gpt-6-luna (constante GROVE_MODEL). C'est le seul modèle Grove pris en charge par Flow dans cette version.
  4. Si la passerelle ne répond pas ou ne liste pas ce modèle, écrit flow_grove_down dans le cache pour 5 minutes et s'arrête.
  5. Sinon, crée le Flow Provider grove (activé), puis un Flow Model activé pour openai/gpt-6-luna.

Les deux documents sont créés avec ignore_permissions=True. Un point de sauvegarde protège la création du fournisseur : si une autre ouverture simultanée l'a déjà créé, la fonction annule sa création et s'arrête.

Le titre du Flow Model vient de _title() : gpt-6-luna devient « GPT-6 luna ». Si un Flow Model de ce titre existe déjà, le titre devient « GPT-6 luna (Grove) ». À l'enregistrement, Flow Model préfixe l'identifiant par le fournisseur : l'identifiant enregistré est grove/openai/gpt-6-luna.

Après la création du fournisseur, sync_site_provider() ne fait plus rien. Le retrait de la clé de la configuration ne supprime pas le fournisseur : les appels échouent avec le message « This site no longer has a Grove key… ».

Les points d'entrée connect() et add_model() de setup.py ne gèrent pas Grove. connect() refuse un fournisseur absent de MODEL_ENDPOINTS, et grove n'y est pas. add_model() vérifie le modèle avec LiteLLM sans litellm_route() et sans la clé du site.

Routage des modèles Grove

Un modèle Grove se nomme grove/<identifiant du modèle>. Le moteur de Flow (flow_harness) enregistre le fournisseur grove avec grove_model() (flow/harness/src/flow_harness/model/providers/grove.py). Cette fonction appelle grove_route(name, api_base) puis crée un LiteLLMModel avec le fournisseur grove.

grove_route() choisit l'API de la passerelle :

Identifiant du modèleModèle LiteLLMAdresse appelée
commence par claudeanthropic/<identifiant><gateway_url>/anthropic
autreopenai/<identifiant><gateway_url>/openai/v1

grove_route() lève ValueError si le nom n'a pas d'identifiant après grove/ ou si api_base est vide. La prise en charge des images est celle du modèle de l'éditeur, lue sur le modèle LiteLLM routé.

Les appels faits hors du moteur de Flow passent par litellm_route(model_id, api_base) (frappe/flow/lib/model.py). Cette fonction applique grove_route() aux modèles grove/… et renvoie les autres modèles sans changement. Elle sert au test de connexion de Flow Model et au calcul des vecteurs (frappe/flow/knowledge/embedder.py).

Erreurs

  • Crédits épuisés. La passerelle répond par HTTP 402 quand les crédits de la clé sont épuisés. Dans l'interface, presentEvent() (flow/frontend/src/api/events.js) remplace le message d'un événement run_error de code 402 par la constante CREDIT_SPENT si le modèle de la conversation a le fournisseur grove. L'événement reçoit aussi settings_tab: "models" : la page affiche alors le bouton « Connect a provider » à un utilisateur qui a le droit d'écriture sur Flow Model.
  • Message d'un fournisseur. _run_error() (flow/harness/src/flow_harness/session/session.py) écrit le message sous la forme <fournisseur> (<code HTTP>): <détail>. Le fournisseur est son nom d'affichage dans le catalogue, sinon son identifiant. Grove n'est pas dans le catalogue : son message commence par grove. ProviderError retire l'enveloppe de LiteLLM (litellm.APIError: …Exception - ) pour ne garder que le texte du fournisseur.