mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-15 19:29:16 +02:00
Phase 7 : outils web_search et run_shell avec validation
Backend : - tools.py : web_search (DuckDuckGo HTML sans clé, ou SearxNG via SEARX_URL) et run_shell (confiné au workspace, sortie bornée, timeout) - agent.py : run_shell sensible -> émet tool_confirm et ne s'exécute pas tant que l'utilisateur n'a pas validé (confirm_shell) - agent_config.py : web_search/run_shell désactivés par défaut, flag confirm_shell - routes/shell.py : POST /api/shell/run exécute une commande validée - routes/chat.py : relaie l'événement tool_confirm, passe confirm_shell Frontend : - streamChat : événement tool_confirm - store : pendingShell + approveShell/rejectShell (réinjecte le résultat à l'agent) - ChatPanel : carte de validation de commande (Approuver / Refuser) - SettingsView : toggles web_search/run_shell, marqueur sensible, switch confirm_shell - ToolCard : glyphes web_search/run_shell, statut 'à valider', aperçu d'argument Tests : run_shell confiné, gate de confirmation (commande dangereuse non exécutée), route shell, parser DuckDuckGo. 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
2db6beea5c
commit
de2befe31e
12 files changed
+398
-26
No files matched your search
@@ -42,7 +42,7 @@ export interface ToolCall {
|
||||
name: string;
|
||||
args: Record<string, unknown>;
|
||||
summary?: string;
|
||||
status?: "ok" | "error" | "running";
|
||||
status?: "ok" | "error" | "running" | "pending";
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
@@ -62,6 +62,18 @@ export interface AgentConfig {
|
||||
top_k: number;
|
||||
max_tokens: number;
|
||||
tools: Record<string, boolean>;
|
||||
confirm_shell: boolean;
|
||||
}
|
||||
|
||||
export async function runShell(
|
||||
command: string
|
||||
): Promise<{ command: string; exit_code: number; output: string }> {
|
||||
const res = await fetch("/api/shell/run", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ command }),
|
||||
});
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function getConfig(): Promise<{
|
||||
@@ -134,6 +146,7 @@ export async function streamChat(
|
||||
onToken: (t: string) => void;
|
||||
onToolCall: (call: ToolCall) => void;
|
||||
onToolResult: (call: ToolCall) => void;
|
||||
onToolConfirm: (command: string) => void;
|
||||
onDone: (full: string) => void;
|
||||
onError: (msg: string) => void;
|
||||
}
|
||||
@@ -173,6 +186,7 @@ export async function streamChat(
|
||||
else if (event === "tool_call")
|
||||
handlers.onToolCall({ ...payload, status: "running" });
|
||||
else if (event === "tool_result") handlers.onToolResult(payload);
|
||||
else if (event === "tool_confirm") handlers.onToolConfirm(payload.command);
|
||||
else if (event === "done") handlers.onDone(payload.content);
|
||||
else if (event === "error") handlers.onError(payload.message);
|
||||
} catch {
|
||||
|
||||
Reference in new issue
Block a user