mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-17 12:16:21 +02:00
Phase 4 : boucle agentique, outils fichiers et aperçu live
Backend : - tools.py : read_file / write_file / list_dir confinés au workspace (anti-traversal) - agent.py : boucle de tool-calling itérative au-dessus d'Ollama, génère des événements (token, tool_call, tool_result, final) - routes/chat.py : pilote run_agent, relaie les événements en SSE, persiste la réponse finale + le récap des outils (meta) - routes/files.py : arborescence et contenu du workspace (confiné) - db.py : colonne meta sur messages (+ migration douce), list_messages_for_model Frontend : - ToolCard : carte d'appel d'outil dans le fil (statut en cours/terminé/échec) - streamChat : événements tool_call / tool_result - store : streamTools, fileTree, preview (ouverture auto d'un HTML écrit) - LeftPanel : arborescence réelle du workspace, clic -> aperçu - PreviewPanel : rendu HTML en iframe + onglet Code - ChatPanel : rendu des outils dans les bulles agent (streaming + persisté) Tests manuels : outils + confinement, boucle agent (mock Ollama), chat HTTP de bout en bout (SSE, persistance meta, fichiers écrits, confinement route). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
This commit is contained in:
1 parent
48cbcaafaf
commit
b6bf4edf97
13 files changed
+677
-80
No files matched your search
@@ -0,0 +1,84 @@
|
||||
import type { ToolCall } from "../api/client";
|
||||
|
||||
/** Carte d'appel d'outil rendue dans le fil (fidèle à la maquette). */
|
||||
export function ToolCard({ call }: { call: ToolCall }) {
|
||||
const running = call.status === "running";
|
||||
const error = call.status === "error";
|
||||
|
||||
// Argument principal affiché entre parenthèses (path le plus souvent).
|
||||
const argPreview =
|
||||
typeof call.args?.path === "string"
|
||||
? `("${call.args.path}")`
|
||||
: Object.keys(call.args ?? {}).length
|
||||
? "(…)"
|
||||
: "()";
|
||||
|
||||
return (
|
||||
<div className="mb-[9px] overflow-hidden rounded-[11px] border border-line bg-card-deep">
|
||||
<div className="flex items-center gap-2.5 px-[13px] py-2.5">
|
||||
<span
|
||||
className="flex h-6 w-6 items-center justify-center rounded-[7px] text-accent"
|
||||
style={{ background: "rgba(240,161,92,.13)" }}
|
||||
>
|
||||
<ToolGlyph name={call.name} />
|
||||
</span>
|
||||
<span className="font-mono text-[12.5px] font-semibold text-[#e7ddcd]">
|
||||
{call.name}
|
||||
</span>
|
||||
<span className="font-mono text-xs text-muted-2">{argPreview}</span>
|
||||
<div className="flex-1" />
|
||||
{running ? (
|
||||
<span className="flex items-center gap-1.5 font-mono text-[11px] text-muted">
|
||||
<span className="h-2.5 w-2.5 animate-spin rounded-full border-2 border-muted-3 border-t-accent" />
|
||||
en cours
|
||||
</span>
|
||||
) : (
|
||||
<span
|
||||
className={`flex items-center gap-1.5 font-mono text-[11px] ${
|
||||
error ? "text-warn" : "text-ok"
|
||||
}`}
|
||||
>
|
||||
{error ? "✕ échec" : "✓ terminé"}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{call.summary && !running && (
|
||||
<div className="border-t border-line-soft px-[13px] py-2.5 font-mono text-[11.5px] text-muted-3">
|
||||
→ {call.summary}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ToolGlyph({ name }: { name: string }) {
|
||||
const common = {
|
||||
width: 13,
|
||||
height: 13,
|
||||
viewBox: "0 0 24 24",
|
||||
fill: "none",
|
||||
stroke: "currentColor",
|
||||
strokeWidth: 1.9,
|
||||
strokeLinecap: "round" as const,
|
||||
strokeLinejoin: "round" as const,
|
||||
};
|
||||
if (name === "write_file")
|
||||
return (
|
||||
<svg {...common}>
|
||||
<path d="M5 19h14M7 14l9-9 3 3-9 9-4 1z" />
|
||||
</svg>
|
||||
);
|
||||
if (name === "list_dir")
|
||||
return (
|
||||
<svg {...common}>
|
||||
<path d="M4 7h6l2 2h8v9H4z" />
|
||||
</svg>
|
||||
);
|
||||
// read_file (défaut)
|
||||
return (
|
||||
<svg {...common}>
|
||||
<path d="M7 4h7l4 4v12H7z" />
|
||||
<path d="M14 4v4h4" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user