You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add the plant expert: reference base, diagnosis and questions
- Reference base of 170 common plants (houseplants, balcony, herbs): names
checked against Wikidata, toxicity from the ASPCA lists. Known species get
their figures from the base and Gemma only writes the advice.
- One shared expert for scan, sheet, diagnosis and chat, given the plant's
context (species, sheet, recent care, room, season).
- Health diagnosis from a close-up photo, kept with its photo in a Health
section, with a one-tap watering interval change.
- "Demande à Plantule": per-plant conversation, streamed as it is written.
- Migration 3: diagnoses and chat_messages tables.
Claude-Session: https://claude.ai/code/session_01Jg25nsPfSVmrDW93LK1Wby
Copy file name to clipboardExpand all lines: README.md
+7-3Lines changed: 7 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,13 +14,16 @@ Tout reste sur le téléphone : pas de compte, pas de serveur. Les données sont
14
14
-**Journal** : tout ce qui a été fait ou reporté, par plante.
15
15
-**Résumé quotidien** : une notification locale par jour, à l'heure choisie.
16
16
-**Scan** : on photographie une plante, Gemma 4 E2B propose l'espèce, puis rédige sa fiche d'entretien et les soins à programmer. Le modèle tourne sur le téléphone : il se télécharge une fois (2,6 Go, en Wi-Fi) et aucune photo ne sort du téléphone. Il faut un téléphone Android avec 6 Go de RAM. Voir [docs/ai-engine.md](docs/ai-engine.md).
17
+
-**Base de référence** : 170 plantes courantes (intérieur, balcon, aromatiques) embarquées dans l’app : noms vérifiés sur Wikidata, toxicité d’après l’ASPCA, et des chiffres d’entretien fixés à l’avance. Pour une espèce connue, la fiche prend ses chiffres dans la base et Gemma n’écrit que les conseils : elle est plus rapide et plus juste. La fiche l’indique par « Données vérifiées ».
18
+
-**Diagnostic** : une photo de près de ce qui inquiète, et Gemma donne l’état de la plante (saine, à surveiller, à soigner), jusqu’à 3 pistes avec quoi faire, en tenant compte des derniers arrosages, de la pièce et de la saison. Si l’arrosage est en cause, l’app propose de changer l’intervalle en un clic. Les diagnostics sont gardés avec leur photo dans la section Santé de la plante.
19
+
-**Demande à Plantule** : poser ses questions sur une plante, avec la réponse qui s’écrit au fil de l’eau. La conversation est gardée pour chaque plante.
17
20
18
21
## Développer
19
22
20
23
```bash
21
24
npm install
22
25
npx expo start # puis « a » pour Android (Expo Go ou émulateur)
23
-
npm test# tests unitaires (règles de récurrence, dates, résumé)
26
+
npm test# tests unitaires (règles, dates, fiche, diagnostic, base de référence)
24
27
npx tsc --noEmit # typecheck
25
28
npx expo lint # lint
26
29
```
@@ -31,10 +34,11 @@ Structure :
31
34
32
35
```
33
36
src/app/ écrans (Expo Router)
34
-
src/ai/ modèle sur le téléphone (téléchargement, exécution) et questions du scan
37
+
src/ai/ modèle sur le téléphone (téléchargement, exécution) et questions posées à l’expert (scan, fiche, diagnostic, conversation)
35
38
src/components/ composants, dont le design system dans components/ui
39
+
src/data/ base de référence des plantes (chiffres d’entretien, toxicité)
36
40
src/db/ base SQLite : schéma et migrations, requêtes, hooks réactifs
37
-
src/lib/ règles de récurrence, dates, libellés, fiche espèceet sa validation
41
+
src/lib/ règles de récurrence, dates, libellés, fiche espèce, diagnostic et leur validation
38
42
src/notifications/ résumé quotidien
39
43
src/theme/ couleurs, typographie, espacements (clair et sombre)
Copy file name to clipboardExpand all lines: docs/ai-engine.md
+42-2Lines changed: 42 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Moteur IA sur le téléphone
2
2
3
-
Décision du 23/09/2026 pour la phase 2 (scan). Code : `src/ai/engine.ts` et `src/ai/model-*.ts`, derrière le contrat `src/ai/types.ts`.
3
+
Décision du 23/09/2026 pour la phase 2 (scan). Code : `src/ai/engine.ts` et `src/ai/model-*.ts`, derrière le contrat `src/ai/types.ts`. Ce qu’on demande au modèle (scan, fiche, diagnostic, questions) est dans `src/ai/plant-ai.ts` ; la base de référence dans `src/data/plants.ts` (voir plus bas).
4
4
5
5
## Choix
6
6
@@ -49,8 +49,48 @@ L'app exige **6 Go de RAM** (seuil technique : `Device.totalMemory` ≥ 5 Go, un
- Photo redimensionnée à 1024 px de côté au plus, en JPEG.
51
51
-`jsonSchema` passé à LLGuidance. Si le moteur refuse le schéma, la demande est relancée sans contrainte (la réponse est de toute façon validée par l'appelant).
52
+
- Réponse au fil de l’eau : avec `onText`, le moteur écrit la réponse morceau par morceau (`execute(parts, onToken, options)`) et `onText` reçoit tout le texte déjà écrit, au plus toutes les 100 ms, puis le texte final (`src/ai/text-stream.ts`). Plus rien n’est envoyé après une annulation.
52
53
- Téléchargement : `DownloadTask` d'expo-file-system (SDK 57) avec progression, annulation et reprise (en-tête `Range`), même après un redémarrage de l'app. Écrit en `.part`, vérifié (taille et en-tête `LITERTLM`) puis renommé. Espace disque vérifié avant (+300 Mo de marge). Refus hors Wi-Fi sauf accord explicite (expo-network).
53
54
55
+
## L’expert Plantule
56
+
57
+
Toutes les demandes partagent les mêmes instructions, `EXPERT_SYSTEM` (`src/ai/plant-context.ts`) : un jardinier prudent qui conseille des particuliers en France, en phrases courtes et en tutoyant ; il dit quand il ne sait pas, s’appuie sur les données vérifiées sans inventer d’autres chiffres, et conseille le vétérinaire si un animal a mangé une plante toxique. Les tâches en JSON (identification, fiche, diagnostic) y ajoutent « réponds uniquement avec un objet JSON » ; les questions répondent en texte libre.
58
+
59
+
Pour le diagnostic et les questions, le modèle reçoit ce que l’app sait de la plante (`buildPlantContext`, `contextText`) : espèce, chiffres de la base (ou de la fiche), problèmes fréquents de la fiche, pièce (nom, intérieur ou dehors, lumière), pot et substrat, mois et saison, rappel d’arrosage (intervalle, retard, « terreau encore humide » de suite), les 8 derniers soins (l’arrosage d’abord) et les notes. Le tout tient en 2 000 caractères au plus, environ 600 jetons : les textes libres sont raccourcis et les soins les plus anciens sautent d’abord.
Une nouvelle tentative ajoute la réponse précédente (1 500 caractères au plus) et les erreurs : le diagnostic reste vers 3 000 jetons sur 4 096.
70
+
71
+
## Base de référence
72
+
73
+
`src/data/plants.ts` : **170 plantes** (109 d’intérieur, 42 de balcon et de terrasse, 19 aromatiques), avec noms latins et français, lumière, arrosage (intervalle et facteur d’hiver), humidité, températures supportées, toxicité pour les chats et les chiens, engrais, brumisation et rempotage. Recherche (`findReference`) sans tenir compte de la casse, des accents, du signe d’hybride, d’un cultivar entre guillemets, de « spp. », d’un article ou d’un pluriel ; jamais sur un genre seul (« Ficus alii » n’est pas le Ficus benjamina).
74
+
75
+
Utilisation :
76
+
77
+
-**Identification** : chaque candidat est relié à la base (`reference_id`), par son nom latin, ou par son nom commun si le genre concorde. Il prend alors le nom latin de la base, et son premier nom commun si celui du modèle n’y figure pas.
78
+
-**Fiche** : pour une espèce de la base, les chiffres viennent de la base et Gemma n’écrit que les textes (conseils d’arrosage et de rempotage, substrat, pot, bouturage, problèmes, astuces), avec les faits de la base dans la demande et la consigne de ne pas écrire d’autres chiffres. La fiche a `reference_id` et est enregistrée avec la source `reference`. Sinon, Gemma écrit toute la fiche, comme avant.
79
+
-**Diagnostic et questions** : les chiffres de la base font partie du contexte de la plante.
80
+
81
+
D’où viennent les données, et sous quelle licence :
82
+
83
+
-**Noms** : chaque nom latin vérifié sur **Wikidata** (licence CC0, domaine public), dont l’identifiant est dans `sources`. Wikidata a aussi fourni une partie des noms français. Pour quelques plantes vendues sous un ancien nom (Echinocactus grusonii, Osteospermum, Schefflera, Dracaena marginata), c’est ce nom qui est gardé et le nom accepté va dans les synonymes.
84
+
-**Toxicité** : les listes de l’**ASPCA** (Animal Poison Control Center) pour les chats et les chiens, vérifiées par script pour chaque plante (espèce, ou genre quand l’espèce n’y est pas), avec le lien dans `sources`. On n’en garde que le fait (toxique ou non), pas le texte. Une plante absente des listes est « inconnue », sauf quatre plantes irritantes gardées « toxiques » par prudence (Rhaphidophora, Zamioculcas, croton, agave), commentées dans le fichier.
85
+
-**Chiffres d’entretien** (lumière, arrosage, humidité, températures, engrais, brumisation, rempotage) : écrits par nous pour la culture en pot en France, à partir des conseils horticoles courants, et marqués `Plantule` dans `sources`. Aucune source ouverte trouvée pour ces chiffres : FloraDB (échantillon en CC BY-NC), Open Plantbook (compte obligatoire, plages de capteurs plutôt que des rythmes), OpenPlantDB (CC0 mais cultures potagères des États-Unis). Ce sont des repères de départ : chaque plante les ajuste ensuite (« terreau encore humide », diagnostic).
86
+
87
+
Les tests (`src/lib/plant-reference.test.ts`) vérifient au moins 150 plantes, des identifiants et des noms uniques, qu’aucun nom ne désigne deux plantes, des intervalles entre 1 et 730 jours, un facteur d’hiver parmi 1, 1,5, 2 et 3, un minimum de température inférieur au maximum, et une source pour chaque toxicité connue.
88
+
89
+
## Diagnostic et questions
90
+
91
+
-**Diagnostic** (`diagnosePlant`) : la photo et le contexte de la plante dans le même appel. Le modèle liste d’abord jusqu’à 3 problèmes (nom, type, confiance, signes, actions), puis l’état, le résumé et les changements d’arrosage et de lumière. La demande insiste sur trop d’eau ou pas assez, d’après les derniers arrosages et les « terreau encore humide », et sur ce que la photo ne montre pas (racines, petits parasites). Validation stricte (`validateDiagnosis`) avec 2 nouvelles tentatives ; à la relecture d’un diagnostic enregistré, la validation est indulgente. `suggestedWateringInterval` propose ×1,3 pour « moins d’eau » et ×0,75 pour « plus », d’au moins un jour, entre 1 et 730.
92
+
-**Questions** (`askPlant`) : contexte de la plante, les 6 derniers messages raccourcis à 400 caractères, puis la question. Réponse courte en texte libre, envoyée au fil de l’eau par `onText`, sans nouvelle tentative.
93
+
54
94
## Limites connues
55
95
56
96
-**Pas d'arrêt en cours de génération** : la 0.7.0 n'expose pas `cancelProcess()` (corrigé sur la branche principale de la lib, pas encore publié). `signal` rejette tout de suite, mais le calcul continue en arrière-plan jusqu'à la fin de la réponse et la demande suivante attend.
@@ -64,4 +104,4 @@ L'app exige **6 Go de RAM** (seuil technique : `Device.totalMemory` ≥ 5 Go, un
64
104
65
105
## À mesurer sur un vrai téléphone
66
106
67
-
Temps de chargement, temps d'une identification avec photo, RAM, repli CPU/GPU, justesse sur nos plantes (et comparaison avec Pl@ntNet).
107
+
Temps de chargement, temps d'une identification avec photo, RAM, repli CPU/GPU, justesse sur nos plantes (et comparaison avec Pl@ntNet). Et depuis la phase 3 : le temps d’un diagnostic, le rythme de la réponse au fil de l’eau, la justesse du diagnostic sur des plantes vraiment malades, et le temps d’une fiche d’espèce connue (texte seul) comparé à une fiche complète.
'Des feuilles qui jaunissent viennent le plus souvent d’un excès d’eau. Touche le terreau : s’il est encore humide à deux doigts de profondeur, attends avant d’arroser et vide la soucoupe. Si seules les vieilles feuilles du bas jaunissent, c’est souvent normal.',
309
+
},
310
+
{
311
+
words: /rempot/i,
312
+
answer:
313
+
'Le meilleur moment pour la rempoter, c’est au printemps, de mars à mai. Fais-le quand les racines sortent par le trou du pot. Prends un pot 2 à 3 cm plus large, percé, avec un terreau frais, puis arrose bien.',
314
+
},
315
+
{
316
+
words: /plac|où|lumi|soleil|fenêtre/i,
317
+
answer:
318
+
'Mets-la près d’une fenêtre lumineuse, mais sans soleil direct l’après-midi, qui brûle les feuilles. Évite les radiateurs et les courants d’air. Si ses tiges s’étirent, c’est qu’elle manque de lumière.',
319
+
},
320
+
];
321
+
constCHAT_FALLBACK=
322
+
'Je ne peux pas te répondre avec certitude sans en savoir plus. Décris-moi ce que tu vois sur la plante, ou fais un diagnostic avec une photo prise de près.';
323
+
324
+
/** The texts of a sheet, as asked for a species of the reference base. */
325
+
functionsheetTexts(sheet: CareSheet){
326
+
return{
327
+
watering_advice: sheet.watering.advice,
328
+
repotting_advice: sheet.repotting.advice,
329
+
substrate: sheet.substrate,
330
+
pot: sheet.pot,
331
+
propagation: sheet.propagation,
332
+
problems: sheet.problems,
333
+
tips: sheet.tips,
334
+
};
335
+
}
336
+
337
+
/** Field names the request's JSON Schema asks for. */
0 commit comments