mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 22:48:11 +02:00
Navigateur piloté, images redressées : reprises d'AJEAN
L'amont (AJEAN 0.15) donne à l'IA le contrôle d'un navigateur ; Loki embarquait déjà un Chromium pour `web_screenshot` sans jamais le piloter. Contrôle du navigateur (computer_use.go, computer_cdp.go, browser_grid.go, portés d'AJEAN) : l'IA ouvre une page en CDP, en reçoit les éléments interactifs NUMÉROTÉS et agit par numéro (browser_open/snapshot/find/click/ type/key/scroll). Aucune vision requise — un petit modèle texte s'en sort. Avec un projecteur chargé s'ajoutent browser_screenshot (image quadrillée) et browser_click_xy. Interrupteur dédié (Réglages, `loki computer`, /api/computer), sous le mode agent : cliquer et taper dans une page sont des actions réelles, même niveau de confiance que bash. Adaptation au conteneur : chromePath cherche D'ABORD le Chromium de Playwright (PLAYWRIGHT_BROWSERS_PATH, /opt/pw-browsers), le seul navigateur de l'image — sinon la fonctionnalité se déclarait absente là où le navigateur est présent. LOKI_CHROME force un chemin, LOKI_CU_HEADFUL ouvre une vraie fenêtre. Préparation des images (web_upload_orient.go, porté d'AJEAN) : l'orientation EXIF est cuite dans les pixels — le projecteur l'ignore et voyait les photos de téléphone couchées — et le grand côté ramené sous 1568 px. Appliquée aux pièces jointes, à see_image et aux captures. Dédup des appels d'outils : bash, bash_bg, bash_tail, see_image et les browser_* ne sont plus court-circuités sur un appel identique. Relancer la même commande après avoir modifié un fichier est légitime, et un outil qui porte une image dans un message à part renvoyait « [déjà fait] » SANS l'image — le modèle tournait en boucle. Mode code : le builder ne publie plus de lui-même (pas de commit/push/reset/ rebase ni de redémarrage de service sans demande explicite), reprise de la leçon d'AJEAN 0.15.4 ; l'inspection en lecture seule reste encouragée. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K6CAgoLJzufeA8rZTSpSpY
This commit is contained in:
21 files changed
+2503
-19
No files matched your search
@@ -80,7 +80,17 @@ func toolSeeImage(path string) (string, map[string]any) {
|
||||
if len(b) == 0 {
|
||||
return "[erreur] fichier vide : " + path, nil
|
||||
}
|
||||
return "[ok] image chargée : " + filepath.Base(abs), map[string]any{
|
||||
// Même préparation que les pièces jointes : orientation EXIF redressée et
|
||||
// grand côté ramené sous maxImageDim (voir web_upload_orient.go).
|
||||
b, mime = prepareImageForModel(b, mime)
|
||||
return "[ok] image chargée : " + filepath.Base(abs), imageURLPart(b, mime)
|
||||
}
|
||||
|
||||
// imageURLPart construit la partie multimodale {type:image_url, image_url:{url}}
|
||||
// à partir d'octets image déjà préparés — le SEUL format qu'un llama-server
|
||||
// --mmproj comprend. Partagé par see_image, web_screenshot et browser_screenshot.
|
||||
func imageURLPart(b []byte, mime string) map[string]any {
|
||||
return map[string]any{
|
||||
"type": "image_url",
|
||||
"image_url": map[string]any{
|
||||
"url": "data:" + mime + ";base64," + base64.StdEncoding.EncodeToString(b),
|
||||
@@ -93,8 +103,14 @@ func toolSeeImage(path string) (string, map[string]any) {
|
||||
// restera qu'elle et imageLostMarker, et « Image demandée : » tout court ne
|
||||
// dirait pas LAQUELLE rouvrir.
|
||||
func seeImageMessage(label string, img map[string]any) Message {
|
||||
// Sans parenthèses vides : browser_screenshot n'a pas d'argument (label=""),
|
||||
// là où see_image porte le chemin du fichier.
|
||||
text := "Image :"
|
||||
if label != "" {
|
||||
text = "Image demandée (" + label + ") :"
|
||||
}
|
||||
return Message{Role: "user", Content: []map[string]any{
|
||||
{"type": "text", "text": "Image demandée (" + label + ") :"},
|
||||
{"type": "text", "text": text},
|
||||
img,
|
||||
}}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user