mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-22 22:48:11 +02:00
API interne : critères changés par un outil, fichiers seuls au reset
/internal/v1/tool/exec rend la liste des critères après un appel de l'outil criteria qui l'a changée (add, set, clear) : critNotify la pousse au journal du Go, une conversation tenue par la façade la reçoit ici. /internal/v1/conv/dropped accepte files_only : Reset vide la discussion et ses fichiers, sans la supprimer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
3 files changed
+49
-5
No files matched your search
@@ -58,10 +58,29 @@ func handleInternalToolExec(w http.ResponseWriter, r *http.Request) {
|
|||||||
sendJSON(w, http.StatusOK, struct {
|
sendJSON(w, http.StatusOK, struct {
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
toolExecResult
|
toolExecResult
|
||||||
Image string `json:"image,omitempty"`
|
Image string `json:"image,omitempty"`
|
||||||
Shot string `json:"shot,omitempty"`
|
Shot string `json:"shot,omitempty"`
|
||||||
Relay *Message `json:"relay,omitempty"`
|
Relay *Message `json:"relay,omitempty"`
|
||||||
}{label, res, image, shot, relay})
|
Criteria []Criterion `json:"criteria,omitempty"`
|
||||||
|
}{label, res, image, shot, relay, criteriaAfter(in.Name, in.Args, res)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// criteriaAfter : la liste des critères après un appel qui l'a changée
|
||||||
|
// (critNotify la pousse au journal du Go ; une conversation tenue par la
|
||||||
|
// façade la reçoit ici). nil sinon.
|
||||||
|
func criteriaAfter(name string, args map[string]any, res toolExecResult) []Criterion {
|
||||||
|
if name != "criteria" || strings.HasPrefix(res.Result, "[erreur]") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
switch a, _ := args["action"].(string); a {
|
||||||
|
case "add", "set", "clear":
|
||||||
|
list := critList(convActiveID())
|
||||||
|
if list == nil {
|
||||||
|
list = []Criterion{}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// toolStepExtras : ce que runChatLoop tire d'un résultat d'outil après
|
// toolStepExtras : ce que runChatLoop tire d'un résultat d'outil après
|
||||||
|
|||||||
@@ -84,3 +84,19 @@ func TestOutilInterneSuitesDuResultat(t *testing.T) {
|
|||||||
t.Fatalf("aperçu après une erreur : %q", shot)
|
t.Fatalf("aperçu après une erreur : %q", shot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Les critères changés par l'outil reviennent avec son résultat : une
|
||||||
|
// conversation tenue par la façade les pousse à son journal.
|
||||||
|
func TestOutilInterneCriteres(t *testing.T) {
|
||||||
|
testHome(t)
|
||||||
|
t.Setenv(internalTokenEnv, jetonTest)
|
||||||
|
got := appelOutil(t, `{"name":"criteria","args":{"action":"add","texts":["les tests passent"]},"caps":{"Agent":true,"Code":true}}`)
|
||||||
|
list, _ := got["criteria"].([]any)
|
||||||
|
if len(list) != 1 {
|
||||||
|
t.Fatalf("critères après add : %v", got)
|
||||||
|
}
|
||||||
|
got = appelOutil(t, `{"name":"criteria","args":{"action":"list"},"caps":{"Agent":true,"Code":true}}`)
|
||||||
|
if _, ok := got["criteria"]; ok {
|
||||||
|
t.Fatalf("une lecture ne pousse rien : %v", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,8 @@ import (
|
|||||||
// POST /internal/v1/turn/done {"ms":N} → 204 (Web Push si abonnés)
|
// POST /internal/v1/turn/done {"ms":N} → 204 (Web Push si abonnés)
|
||||||
// POST /internal/v1/conv/active {"id":…} → 204 (discussion active des outils)
|
// POST /internal/v1/conv/active {"id":…} → 204 (discussion active des outils)
|
||||||
// POST /internal/v1/conv/dropped {"id":…} → 204 (fichiers, jobs, critères,
|
// POST /internal/v1/conv/dropped {"id":…} → 204 (fichiers, jobs, critères,
|
||||||
// mode, résultats d'outils)
|
// mode, résultats d'outils ;
|
||||||
|
// "files_only" : les fichiers)
|
||||||
|
|
||||||
const internalTurnMaxBody = 8 << 20
|
const internalTurnMaxBody = 8 << 20
|
||||||
|
|
||||||
@@ -147,6 +148,9 @@ func handleInternalConvActive(w http.ResponseWriter, r *http.Request) {
|
|||||||
func handleInternalConvDropped(w http.ResponseWriter, r *http.Request) {
|
func handleInternalConvDropped(w http.ResponseWriter, r *http.Request) {
|
||||||
var in struct {
|
var in struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
// FilesOnly : seulement les fichiers (Reset vide la discussion, il ne
|
||||||
|
// la supprime pas).
|
||||||
|
FilesOnly bool `json:"files_only"`
|
||||||
}
|
}
|
||||||
if !readInternalJSON(w, r, &in) {
|
if !readInternalJSON(w, r, &in) {
|
||||||
return
|
return
|
||||||
@@ -155,6 +159,11 @@ func handleInternalConvDropped(w http.ResponseWriter, r *http.Request) {
|
|||||||
sendJSON(w, http.StatusBadRequest, map[string]any{"error": "id manquant"})
|
sendJSON(w, http.StatusBadRequest, map[string]any{"error": "id manquant"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if in.FilesOnly {
|
||||||
|
dropConvFiles(in.ID)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
return
|
||||||
|
}
|
||||||
stopConvJobs(in.ID)
|
stopConvJobs(in.ID)
|
||||||
critDrop(in.ID)
|
critDrop(in.ID)
|
||||||
dropConvMode(in.ID)
|
dropConvMode(in.ID)
|
||||||
|
|||||||
Reference in new issue
Block a user