mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 19:48:27 +00:00
fix: preserve bootstrap paths and expose failed mutations (#16131)
Merged via /review-pr -> /prepare-pr -> /merge-pr.
Prepared head SHA: 385dcbd8a9
Co-authored-by: Swader <1430603+Swader@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import type { AgentEvent } from "@mariozechner/pi-agent-core";
|
||||
import type { PluginHookAfterToolCallEvent } from "../plugins/types.js";
|
||||
import type { EmbeddedPiSubscribeContext } from "./pi-embedded-subscribe.handlers.types.js";
|
||||
import type {
|
||||
EmbeddedPiSubscribeContext,
|
||||
ToolCallSummary,
|
||||
} from "./pi-embedded-subscribe.handlers.types.js";
|
||||
import { emitAgentEvent } from "../infra/agent-events.js";
|
||||
import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
|
||||
import { normalizeTextForComparison } from "./pi-embedded-helpers.js";
|
||||
@@ -13,10 +16,21 @@ import {
|
||||
sanitizeToolResult,
|
||||
} from "./pi-embedded-subscribe.tools.js";
|
||||
import { inferToolMetaFromArgs } from "./pi-embedded-utils.js";
|
||||
import { buildToolMutationState, isSameToolMutationAction } from "./tool-mutation.js";
|
||||
import { normalizeToolName } from "./tool-policy.js";
|
||||
|
||||
/** Track tool execution start times and args for after_tool_call hook */
|
||||
const toolStartData = new Map<string, { startTime: number; args: unknown }>();
|
||||
|
||||
function buildToolCallSummary(toolName: string, args: unknown, meta?: string): ToolCallSummary {
|
||||
const mutation = buildToolMutationState(toolName, args, meta);
|
||||
return {
|
||||
meta,
|
||||
mutatingAction: mutation.mutatingAction,
|
||||
actionFingerprint: mutation.actionFingerprint,
|
||||
};
|
||||
}
|
||||
|
||||
function extendExecMeta(toolName: string, args: unknown, meta?: string): string | undefined {
|
||||
const normalized = toolName.trim().toLowerCase();
|
||||
if (normalized !== "exec" && normalized !== "bash") {
|
||||
@@ -70,7 +84,7 @@ export async function handleToolExecutionStart(
|
||||
}
|
||||
|
||||
const meta = extendExecMeta(toolName, args, inferToolMetaFromArgs(toolName, args));
|
||||
ctx.state.toolMetaById.set(toolCallId, meta);
|
||||
ctx.state.toolMetaById.set(toolCallId, buildToolCallSummary(toolName, args, meta));
|
||||
ctx.log.debug(
|
||||
`embedded run tool start: runId=${ctx.params.runId} tool=${toolName} toolCallId=${toolCallId}`,
|
||||
);
|
||||
@@ -167,7 +181,8 @@ export async function handleToolExecutionEnd(
|
||||
const result = evt.result;
|
||||
const isToolError = isError || isToolResultError(result);
|
||||
const sanitizedResult = sanitizeToolResult(result);
|
||||
const meta = ctx.state.toolMetaById.get(toolCallId);
|
||||
const callSummary = ctx.state.toolMetaById.get(toolCallId);
|
||||
const meta = callSummary?.meta;
|
||||
ctx.state.toolMetas.push({ toolName, meta });
|
||||
ctx.state.toolMetaById.delete(toolCallId);
|
||||
ctx.state.toolSummaryById.delete(toolCallId);
|
||||
@@ -177,7 +192,24 @@ export async function handleToolExecutionEnd(
|
||||
toolName,
|
||||
meta,
|
||||
error: errorMessage,
|
||||
mutatingAction: callSummary?.mutatingAction,
|
||||
actionFingerprint: callSummary?.actionFingerprint,
|
||||
};
|
||||
} else if (ctx.state.lastToolError) {
|
||||
// Keep unresolved mutating failures until the same action succeeds.
|
||||
if (ctx.state.lastToolError.mutatingAction) {
|
||||
if (
|
||||
isSameToolMutationAction(ctx.state.lastToolError, {
|
||||
toolName,
|
||||
meta,
|
||||
actionFingerprint: callSummary?.actionFingerprint,
|
||||
})
|
||||
) {
|
||||
ctx.state.lastToolError = undefined;
|
||||
}
|
||||
} else {
|
||||
ctx.state.lastToolError = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Commit messaging tool text on success, discard on error.
|
||||
|
||||
Reference in New Issue
Block a user