Simplify tool approval chat flow
This commit is contained in:
+26
-18
@@ -175,35 +175,39 @@ function formatToolCommand(tool, args) {
|
||||
}
|
||||
|
||||
function formatToolStart(tool, args) {
|
||||
const lines = [formatToolCommand(tool, args)];
|
||||
const serializedArgs = JSON.stringify(args || {}, null, 2);
|
||||
if (serializedArgs !== "{}") lines.push(serializedArgs);
|
||||
return lines.join("\n");
|
||||
return formatToolCommand(tool, args);
|
||||
}
|
||||
|
||||
function appendToolTerminal(article, eventPayload) {
|
||||
const paragraph = article?.querySelector("p");
|
||||
const payload = eventPayload.payload || eventPayload;
|
||||
const existing = findToolTerminal(article, payload.index);
|
||||
if (existing) return existing;
|
||||
const terminal = createToolTerminal(eventPayload);
|
||||
paragraph?.before(terminal);
|
||||
document.querySelector("#messages").scrollTop = document.querySelector("#messages").scrollHeight;
|
||||
return terminal;
|
||||
}
|
||||
|
||||
function findToolTerminal(article, index) {
|
||||
return article?.querySelector(`.tool-terminal[data-tool-index="${index || ""}"]`);
|
||||
}
|
||||
|
||||
function updateToolTerminal(article, eventPayload) {
|
||||
const payload = eventPayload.payload || eventPayload;
|
||||
const terminal = article?.querySelector(`.tool-terminal[data-tool-index="${payload.index || ""}"]`);
|
||||
const terminal = findToolTerminal(article, payload.index);
|
||||
const body = terminal?.querySelector(".tool-terminal-body");
|
||||
const status = terminal?.querySelector(".tool-terminal-status");
|
||||
const result = payload.result || {};
|
||||
if (!body || !status) return;
|
||||
terminal.classList.toggle("is-error", !result.ok);
|
||||
terminal.classList.remove("is-waiting");
|
||||
status.textContent = result.ok ? "ok" : "error";
|
||||
|
||||
const parts = [body.textContent.trim()];
|
||||
const title = terminal.querySelector(".tool-terminal-title")?.textContent || body.textContent.trim();
|
||||
const parts = [title];
|
||||
if (result.output) parts.push("\nstdout\n" + result.output.trimEnd());
|
||||
if (result.error) parts.push("\nstderr\n" + result.error.trimEnd());
|
||||
if (result.metadata && Object.keys(result.metadata).length) {
|
||||
parts.push("\nmetadata\n" + JSON.stringify(result.metadata, null, 2));
|
||||
}
|
||||
body.textContent = parts.join("\n");
|
||||
document.querySelector("#messages").scrollTop = document.querySelector("#messages").scrollHeight;
|
||||
}
|
||||
@@ -211,14 +215,13 @@ function updateToolTerminal(article, eventPayload) {
|
||||
function appendApprovalTerminal(article, eventPayload) {
|
||||
const payload = eventPayload.payload || eventPayload;
|
||||
const action = payload.action || {};
|
||||
appendToolTerminal(article, {
|
||||
const terminal = appendToolTerminal(article, {
|
||||
payload: {
|
||||
index: payload.index,
|
||||
tool: payload.tool,
|
||||
args: action.args || {},
|
||||
},
|
||||
});
|
||||
const terminal = article?.querySelector(`.tool-terminal[data-tool-index="${payload.index || ""}"]`);
|
||||
const body = terminal?.querySelector(".tool-terminal-body");
|
||||
const status = terminal?.querySelector(".tool-terminal-status");
|
||||
const command = formatToolCommand(action.tool || payload.tool, action.args || {});
|
||||
@@ -228,14 +231,15 @@ function appendApprovalTerminal(article, eventPayload) {
|
||||
if (status) status.textContent = "approval";
|
||||
if (body) {
|
||||
body.textContent = [
|
||||
body.textContent,
|
||||
"",
|
||||
"approval required",
|
||||
command,
|
||||
"",
|
||||
"Требуется разрешение на выполнение.",
|
||||
payload.reason || "",
|
||||
].filter(Boolean).join("\n");
|
||||
}
|
||||
terminal?.append(createInlineApprovalActions(payload.approval_id, command));
|
||||
if (!terminal?.querySelector(".tool-approval-actions")) {
|
||||
terminal?.append(createInlineApprovalActions(payload.approval_id, command));
|
||||
}
|
||||
}
|
||||
|
||||
function appendPasswordPrompt(article, eventPayload) {
|
||||
@@ -318,9 +322,13 @@ async function resolveInlineApproval(button) {
|
||||
const decision = action === "deny" ? "denied" : "allowed";
|
||||
|
||||
terminal.classList.toggle("is-error", action === "deny");
|
||||
terminal.classList.remove("is-waiting");
|
||||
if (status) status.textContent = decision;
|
||||
if (body) body.textContent = `${command}\n\n${decision}: ${humanApprovalDecision(action)}`;
|
||||
terminal.classList.toggle("is-waiting", action !== "deny");
|
||||
if (status) status.textContent = action === "deny" ? decision : "running";
|
||||
if (body) {
|
||||
body.textContent = action === "deny"
|
||||
? `${command}\n\n${decision}: ${humanApprovalDecision(action)}`
|
||||
: `${command}\n\nРазрешено. Выполняю команду...`;
|
||||
}
|
||||
actions?.remove();
|
||||
if (taskId) {
|
||||
await continueAfterInlineApproval(terminal.closest(".message"), taskId, approvalId);
|
||||
|
||||
Reference in New Issue
Block a user