openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
888 lines (887 loc) • 40.3 kB
JavaScript
import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js";
import { C as createChildDiagnosticTraceContext, D as freezeDiagnosticTraceContext, N as runWithDiagnosticTraceContext, O as getActiveDiagnosticTraceContext, o as emitTrustedDiagnosticEvent, s as emitTrustedDiagnosticEventWithPrivateData, w as createDiagnosticTraceContext } from "./diagnostic-events-Cwe92uV3.js";
import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js";
import { r as isKnownCoreToolId } from "./tool-catalog-79RBtNnN.js";
import { a as expandToolGroups, c as normalizeToolPolicyName } from "./tool-policy-shared-DIyS0iQC.js";
import { d as toolPolicyRestrictsTools, l as mergeAlsoAllowPolicy } from "./tool-policy-Wi0C45cX.js";
import { p as resolveProviderRefOwnership } from "./providers-DCe4UB6a.js";
import { a as resolveAgentHarnessOwnerPluginId, r as listRegisteredAgentHarnesses } from "./registry-D1_C7waJ.js";
import { a as unwrapSecretSentinelsForProviderEgress, i as unwrapModelHeaderSentinelsForProviderEgress } from "./provider-secret-egress-C-JiHB7J.js";
import { t as resolveAgentHarnessAutoSelectionHint } from "./auto-selection-Br-mlD8Y.js";
import { i as compareHarnessSupport, o as resolveAgentHarnessPreparedAuthSupport, r as buildAgentHarnessSupportContext, s as resolveAgentHarnessPreparedRouteSupport, t as resolveAgentHarnessAvailabilityDecision } from "./availability-DrQ2OOVX.js";
import { i as isCliRuntimeAliasForProvider } from "./model-runtime-aliases-BJ2qM8I_.js";
import { d as normalizeAgentRunAttemptTerminal, f as projectAgentRunAttemptTerminal } from "./agent-run-terminal-outcome-CigeY75d.js";
import { s as resolveAdmittedRunActiveAssertion } from "./admitted-run-context-CHY5SdVF.js";
import { r as resolveGroupToolPolicy } from "./agent-tools.policy-NF_9Y4S4.js";
import { n as resolveSandboxRuntimeStatus } from "./runtime-status-6c8Jb1Kg.js";
import { n as isBuiltInOpenClawAgentHarness, t as createOpenClawAgentHarness } from "./builtin-openclaw-B_H1oNzF.js";
import { o as recordAgentHarnessPreflightOwner, r as MissingAgentHarnessError, t as AgentHarnessPreflightError } from "./errors-70ml6R0Z.js";
import { r as diagnosticErrorMessage, t as diagnosticErrorCategory } from "./diagnostic-error-metadata-BgNm5seU.js";
import { N as runWithAgentRingZeroTools, j as isHostScopedAgentToolActive } from "./local-model-lean-B52ThaBJ.js";
import { t as isHeartbeatLifecycleRunKind } from "./bootstrap-mode-HvSedbJl.js";
import { t as resolveConversationCapabilityProfile } from "./conversation-capability-profile-B6PkMXFD.js";
import { n as copyCoreTtsAttemptResultProvenance } from "./tool-runtime-config-DiXD8jMf.js";
import { r as assertContextEngineHostSupport } from "./host-compat-xESS3bi6.js";
import { i as EmptySettledTurnFinalizationError, t as assertSettledTurnFinalizationResult } from "./settled-turn-finalization-result-CuiDqyLX.js";
import { a as selectContextEngineForTranscriptHost, n as drainPendingContextEngineTurnsBeforeRun } from "./context-engine-turn-attempt-DYtIyzTH.js";
import { t as createAgentHarnessHostCapabilities } from "./host-capability-BrnTBmSB.js";
//#region src/agents/harness/result-classification.ts
/** Applies a harness classifier while replacing any stale prior classification. */
function applyAgentHarnessResultClassification(harness, result, params) {
if (!harness.classify) return {
...result,
agentHarnessId: harness.id
};
const { agentHarnessResultClassification: _previousClassification, ...resultWithoutPrevious } = result;
const classification = harness.classify(resultWithoutPrevious, params);
if (!classification || classification === "ok") return {
...resultWithoutPrevious,
agentHarnessId: harness.id
};
return {
...resultWithoutPrevious,
agentHarnessId: harness.id,
agentHarnessResultClassification: classification
};
}
//#endregion
//#region src/agents/harness/lifecycle.ts
/**
* Agent harness lifecycle diagnostics wrapper.
*
* This module wraps harness attempts with context-engine support checks,
* diagnostic events, trace propagation, and result classification.
*/
function buildAgentHarnessContextEngineHostSupport(harness) {
return {
id: `agent-harness:${harness.id}`,
label: `agent harness "${harness.id}"`,
capabilities: harness.contextEngineHostCapabilities ?? []
};
}
function assertAgentHarnessContextEngineSupport(harness, params) {
if (!params.contextEngine || params.contextEngine.info.id === "legacy") return;
assertContextEngineHostSupport({
contextEngine: params.contextEngine,
operation: "agent-run",
host: buildAgentHarnessContextEngineHostSupport(harness)
});
}
function agentHarnessDiagnosticBase(harness, params, trace) {
const diagnosticTrace = trace ?? getActiveDiagnosticTraceContext();
const channel = diagnosticChannel(params);
return {
runId: params.runId,
sessionId: params.sessionId,
provider: params.provider,
model: params.modelId,
harnessId: harness.id,
...harness.pluginId ? { pluginId: harness.pluginId } : {},
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.trigger ? { trigger: params.trigger } : {},
...channel ? { channel } : {},
...diagnosticTrace ? { trace: freezeDiagnosticTraceContext(diagnosticTrace) } : {}
};
}
function normalizeAgentHarnessAttemptResult(result) {
const { aborted, externalAbort, idleTimedOut, promptError, promptErrorSource, timedOut, timedOutByRunBudget, timedOutDuringCompaction, timedOutDuringToolExecution, ...canonical } = result;
const currentAttemptProvenance = Object.hasOwn(result, "currentAttemptAssistant") ? { currentAttemptAssistant: result.currentAttemptAssistant } : result.lastAssistant ? { currentAttemptAssistant: result.lastAssistant } : {};
const canonicalWithAttemptProvenance = {
...canonical,
...currentAttemptProvenance
};
if ("terminal" in canonicalWithAttemptProvenance) return canonicalWithAttemptProvenance;
const terminal = normalizeAgentRunAttemptTerminal({
aborted,
externalAbort,
idleTimedOut,
promptError,
promptErrorSource,
timedOut,
timedOutByRunBudget,
timedOutDuringCompaction,
timedOutDuringToolExecution
});
return {
...canonicalWithAttemptProvenance,
terminal
};
}
function agentHarnessRunOutcome(result) {
const terminal = projectAgentRunAttemptTerminal(result.terminal);
if (terminal.timedOut) return "timed_out";
if (terminal.externalAbort || terminal.aborted) return "aborted";
if (terminal.promptErrorSource !== null) return "error";
return "completed";
}
function shouldEmitAgentRunDiagnostics(harness) {
return harness.id !== "openclaw";
}
function diagnosticChannel(params) {
return params.messageChannel ?? params.messageProvider;
}
function agentRunDiagnosticBase(params, trace) {
const channel = diagnosticChannel(params);
return {
runId: params.runId,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.sessionId ? { sessionId: params.sessionId } : {},
provider: params.provider,
model: params.modelId,
...params.trigger ? { trigger: params.trigger } : {},
...channel ? { channel } : {},
trace
};
}
function agentRunCompletion(result) {
const terminal = projectAgentRunAttemptTerminal(result.terminal);
if (terminal.timedOut || terminal.externalAbort || terminal.aborted) return { outcome: "aborted" };
if (terminal.promptErrorSource === "hook:before_agent_run") return {
outcome: "blocked",
blockedBy: "before_agent_run"
};
if (terminal.promptErrorSource !== null) return {
outcome: "error",
error: terminal.promptError
};
return { outcome: "completed" };
}
function withFallbackDiagnosticTrace(result, trace) {
if (result.diagnosticTrace || !trace) return result;
return copyCoreTtsAttemptResultProvenance(result, {
...result,
diagnosticTrace: freezeDiagnosticTraceContext(trace)
});
}
function withFallbackFinalizationDiagnosticTrace(result, trace) {
if (result.diagnosticTrace || !trace) return result;
return {
...result,
diagnosticTrace: freezeDiagnosticTraceContext(trace)
};
}
function emitAgentHarnessRunStarted(harness, params, trace) {
emitTrustedDiagnosticEvent({
type: "harness.run.started",
...agentHarnessDiagnosticBase(harness, params, trace)
});
}
function emitAgentHarnessRunCompleted(params) {
const { harness, attemptParams, result, startedAt, trace } = params;
const outcome = agentHarnessRunOutcome(result);
const terminal = projectAgentRunAttemptTerminal(result.terminal);
const errorMessage = outcome === "error" ? diagnosticErrorMessage(terminal.promptError) : void 0;
emitTrustedDiagnosticEventWithPrivateData({
type: "harness.run.completed",
...agentHarnessDiagnosticBase(harness, attemptParams, trace ?? result.diagnosticTrace),
durationMs: Date.now() - startedAt,
outcome,
...result.agentHarnessResultClassification ? { resultClassification: result.agentHarnessResultClassification } : {},
...typeof result.yieldDetected === "boolean" ? { yieldDetected: result.yieldDetected } : {},
itemLifecycle: { ...result.itemLifecycle }
}, errorMessage ? { errorMessage } : void 0);
}
function emitAgentHarnessRunError(params) {
const { harness, attemptParams, startedAt, phase, error, trace } = params;
const errorMessage = diagnosticErrorMessage(error);
emitTrustedDiagnosticEventWithPrivateData({
type: "harness.run.error",
...agentHarnessDiagnosticBase(harness, attemptParams, trace),
durationMs: Date.now() - startedAt,
phase,
errorCategory: diagnosticErrorCategory(error)
}, errorMessage ? { errorMessage } : void 0);
}
/** Runs one harness attempt with diagnostics, tracing, and result classification. */
async function runAgentHarnessLifecycleAttempt(harness, params, execute = (attemptParams) => harness.runAttempt(attemptParams)) {
let result;
let phase = "prepare";
const startedAt = Date.now();
const activeHarnessTrace = getActiveDiagnosticTraceContext();
let agentRunTrace;
let agentRunStartedAt = 0;
let agentRunCompleted = false;
const emitAgentRunCompleted = (completion) => {
if (!agentRunTrace || agentRunCompleted) return;
agentRunCompleted = true;
const failed = completion.outcome === "error" && completion.error != null;
const errorMessage = failed ? diagnosticErrorMessage(completion.error) : void 0;
emitTrustedDiagnosticEventWithPrivateData({
type: "run.completed",
...agentRunDiagnosticBase(params, agentRunTrace),
durationMs: Date.now() - agentRunStartedAt,
outcome: completion.outcome,
...completion.blockedBy ? { blockedBy: completion.blockedBy } : {},
...failed ? { errorCategory: diagnosticErrorCategory(completion.error) } : {}
}, errorMessage ? { errorMessage } : void 0);
};
emitAgentHarnessRunStarted(harness, params, activeHarnessTrace);
try {
phase = "prepare";
assertAgentHarnessContextEngineSupport(harness, params);
if (shouldEmitAgentRunDiagnostics(harness) && activeHarnessTrace) {
agentRunTrace = freezeDiagnosticTraceContext(createChildDiagnosticTraceContext(activeHarnessTrace));
agentRunStartedAt = Date.now();
emitTrustedDiagnosticEvent({
type: "run.started",
...agentRunDiagnosticBase(params, agentRunTrace)
});
}
const runAndClassify = async () => {
phase = "send";
const rawResult = await execute(params);
phase = "resolve";
return copyCoreTtsAttemptResultProvenance(rawResult, normalizeAgentHarnessAttemptResult(applyAgentHarnessResultClassification(harness, rawResult, params)));
};
result = agentRunTrace ? await runWithDiagnosticTraceContext(agentRunTrace, runAndClassify) : await runAndClassify();
result = withFallbackDiagnosticTrace(result, activeHarnessTrace);
} catch (error) {
recordAgentHarnessPreflightOwner(error, harness.id);
emitAgentHarnessRunError({
harness,
attemptParams: params,
startedAt,
phase,
error,
trace: activeHarnessTrace
});
emitAgentRunCompleted({
outcome: "error",
error
});
throw error;
}
emitAgentRunCompleted(agentRunCompletion(result));
emitAgentHarnessRunCompleted({
harness,
attemptParams: params,
result,
startedAt,
trace: activeHarnessTrace
});
return result;
}
/** Runs one isolated finalization with diagnostics and its narrow result validator. */
async function runAgentHarnessLifecycleFinalization(harness, params, execute) {
let phase = "prepare";
const startedAt = Date.now();
const activeHarnessTrace = getActiveDiagnosticTraceContext();
const agentRunTrace = shouldEmitAgentRunDiagnostics(harness) && activeHarnessTrace ? freezeDiagnosticTraceContext(createChildDiagnosticTraceContext(activeHarnessTrace)) : void 0;
emitAgentHarnessRunStarted(harness, params, activeHarnessTrace);
if (agentRunTrace) emitTrustedDiagnosticEvent({
type: "run.started",
...agentRunDiagnosticBase(params, agentRunTrace)
});
try {
const runAndValidate = async () => {
phase = "send";
try {
const rawResult = await execute();
phase = "resolve";
return {
outcome: "answered",
result: assertSettledTurnFinalizationResult(rawResult)
};
} catch (error) {
if (error instanceof EmptySettledTurnFinalizationError) return {
outcome: "empty",
result: error.result
};
throw error;
}
};
const rawResult = agentRunTrace ? await runWithDiagnosticTraceContext(agentRunTrace, runAndValidate) : await runAndValidate();
const result = {
...rawResult,
result: withFallbackFinalizationDiagnosticTrace(rawResult.result, activeHarnessTrace)
};
if (agentRunTrace) emitTrustedDiagnosticEvent({
type: "run.completed",
...agentRunDiagnosticBase(params, agentRunTrace),
durationMs: Date.now() - startedAt,
outcome: "completed"
});
emitTrustedDiagnosticEvent({
type: "harness.run.completed",
...agentHarnessDiagnosticBase(harness, params, result.result.diagnosticTrace ?? activeHarnessTrace),
durationMs: Date.now() - startedAt,
outcome: "completed",
itemLifecycle: {
startedCount: 0,
completedCount: 0,
activeCount: 0
}
});
return result;
} catch (error) {
emitAgentHarnessRunError({
harness,
attemptParams: params,
startedAt,
phase,
error,
trace: activeHarnessTrace
});
if (agentRunTrace) {
const errorMessage = diagnosticErrorMessage(error);
emitTrustedDiagnosticEventWithPrivateData({
type: "run.completed",
...agentRunDiagnosticBase(params, agentRunTrace),
durationMs: Date.now() - startedAt,
outcome: "error",
errorCategory: diagnosticErrorCategory(error)
}, errorMessage ? { errorMessage } : void 0);
}
throw error;
}
}
//#endregion
//#region src/agents/harness/selection.ts
const log = createSubsystemLogger("agents/harness");
const PLUGIN_HARNESS_SENDER_DENY_ALL_PROMPT = "Tool and file actions are disabled for this sender by chat policy. If asked to edit files or use tools, say this sender is not allowed by policy; do not imply retrying will help.";
const PLUGIN_HARNESS_GROUP_DENY_ALL_PROMPT = "Tool and file actions are disabled for this chat by policy. If asked to edit files or use tools, say this chat is not allowed by policy.";
const PLUGIN_HARNESS_RUNTIME_DENY_ALL_PROMPT = "Tool and file actions are disabled by runtime policy. If asked to edit files or use tools, say tools are disabled by policy.";
function listPluginAgentHarnesses() {
return listRegisteredAgentHarnesses().map((entry) => entry.harness);
}
function selectAgentHarness(params) {
return selectAgentHarnessDecision(params).harness;
}
/** Selects one harness that can preserve every prepared route/auth retry candidate. */
function selectAgentHarnessForPreparedModelProviders(params) {
const { modelProviders, ...selectionParams } = params;
if (modelProviders.length === 0) return selectAgentHarness(selectionParams);
const decisions = modelProviders.map((modelProvider) => selectAgentHarnessDecision({
...selectionParams,
modelProvider,
preparedModelProvider: true
}));
const first = decisions[0];
if (!first || decisions.every((decision) => decision.selectedHarnessId === first.selectedHarnessId)) return first?.harness ?? selectAgentHarness(selectionParams);
return decisions.find((decision) => decision.selectedHarnessId === "openclaw")?.harness ?? createOpenClawAgentHarness();
}
/** Returns whether a plugin harness constructs OpenClaw tools inside its runtime. */
function agentHarnessBuildsOpenClawTools(harnessId) {
return harnessId === "codex" || harnessId === "copilot";
}
/** Returns whether the selected harness exposes OpenClaw's agent-tool surface. */
function agentHarnessExposesOpenClawTools(harnessId) {
return harnessId === "openclaw" || agentHarnessBuildsOpenClawTools(harnessId);
}
function selectAgentHarnessDecision(params) {
const pluginHarnesses = listPluginAgentHarnesses();
const availability = resolveAgentHarnessAvailabilityDecision({
...params,
resolveProviderOwnership: () => resolveProviderRefOwnership({
provider: params.provider,
config: params.config
})
});
const policy = availability.policy;
const openClawHarness = createOpenClawAgentHarness();
const runtime = policy.runtime;
if (runtime === "openclaw") return buildSelectionDecision({
harness: openClawHarness,
policy,
selectedReason: availability.kind === "implicit-unavailable" ? "implicit_plugin_unavailable_openclaw" : availability.kind === "implicit-unsupported" ? "implicit_plugin_unsupported_openclaw" : availability.kind === "declared-fallback" ? "plugin_declared_fallback_openclaw" : "forced_openclaw",
candidates: listHarnessCandidates(pluginHarnesses)
});
if (runtime !== "auto") {
const forced = pluginHarnesses.find((entry) => entry.id === runtime);
if (forced) {
const support = availability.support;
if (!support || support.supported || support.fallbackRuntime === "openclaw") {
if (support && !support.supported) log.info(`agent harness selected requested=${runtime} selected=${forced.id} reason=private_qa_forced_runtime`);
return buildSelectionDecision({
harness: forced,
policy,
selectedReason: "forced_plugin",
candidates: listHarnessCandidates(pluginHarnesses)
});
}
if (isCliRuntimeAliasForProvider({
runtime,
provider: params.provider
})) return buildSelectionDecision({
harness: openClawHarness,
policy: {
...policy,
runtime: "openclaw"
},
selectedReason: "cli_runtime_passthrough_openclaw",
candidates: listHarnessCandidates(pluginHarnesses)
});
throw new Error(`Requested agent harness "${runtime}" does not support ${formatProviderModel(params)}${support.reason ? ` (${support.reason})` : ""}.`);
}
if (isCliRuntimeAliasForProvider({
runtime,
provider: params.provider,
cfg: params.config
})) return buildSelectionDecision({
harness: openClawHarness,
policy: {
...policy,
runtime: "openclaw"
},
selectedReason: "cli_runtime_passthrough_openclaw",
candidates: listHarnessCandidates(pluginHarnesses)
});
throw new MissingAgentHarnessError(runtime);
}
const hintedCandidates = pluginHarnesses.map((harness) => ({
harness,
support: resolveAgentHarnessAutoSelectionHint({
harness,
provider: params.provider
})
}));
const candidates = hintedCandidates.some((entry) => entry.support === void 0) ? (() => {
const supportContext = buildAgentHarnessSupportContext({
provider: params.provider,
modelId: params.modelId,
modelProvider: params.modelProvider,
requestedRuntime: runtime,
config: params.config,
agentId: params.agentId,
sessionKey: params.sessionKey,
preparedModelProvider: params.preparedModelProvider,
providerOwnership: resolveProviderRefOwnership({
provider: params.provider,
config: params.config
})
});
return hintedCandidates.map(({ harness, support }) => ({
harness,
support: support ?? harness.supports(supportContext)
}));
})() : hintedCandidates.map(({ harness, support }) => ({
harness,
support
}));
const selected = candidates.filter((entry) => entry.support.supported).toSorted(compareHarnessSupport)[0]?.harness;
if (selected) return buildSelectionDecision({
harness: selected,
policy,
selectedReason: "auto_plugin",
candidates: candidates.map(toSelectionCandidate)
});
return buildSelectionDecision({
harness: openClawHarness,
policy,
selectedReason: "auto_openclaw",
candidates: candidates.map(toSelectionCandidate)
});
}
/** Runs the selected harness's fail-closed settled-turn finalization operation. */
async function runAgentHarnessSettledTurnFinalization(params, settledAttempt, harness) {
const internalParams = params;
const finalizeSettledTurn = harness.finalizeSettledTurn?.bind(harness);
if (!finalizeSettledTurn) throw new Error(`Agent harness ${harness.id} cannot safely finalize a settled tool turn.`);
if (internalParams.systemAgentTool && !isSystemAgentOnlyAllowlist(internalParams.toolsAllow)) throw new Error("OpenClaw host authority requires toolsAllow: [\"openclaw\"]");
const attemptParams = prepareHarnessFinalizationParams({
...internalParams,
operation: "settled-tool-finalization"
}, isBuiltInOpenClawAgentHarness(harness));
return await runAgentHarnessOperation(harness, params, () => runWithAgentRingZeroTools([], () => runAgentHarnessLifecycleFinalization(harness, attemptParams, () => finalizeSettledTurn({
attempt: attemptParams,
settledAttempt
}))));
}
async function runAgentHarnessAttempt(params, nativeSessionRuntime) {
let internalParams = params;
if (nativeSessionRuntime) await nativeSessionRuntime.assertCurrent();
const selection = nativeSessionRuntime?.auth === "native" ? buildSelectionDecision({
harness: nativeSessionRuntime.harness,
policy: {
runtime: nativeSessionRuntime.harness.id,
runtimeSource: "model"
},
selectedReason: "forced_plugin",
candidates: []
}) : selectPreparedAgentHarness(params);
const harness = selection.harness;
if (nativeSessionRuntime && harness !== nativeSessionRuntime.harness) throw new AgentHarnessPreflightError("Native session runtime changed before dispatch. Reattach the original native session before retrying.");
if (internalParams.contextEngineLogicalTurnLease) {
selectContextEngineForTranscriptHost({
lease: internalParams.contextEngineLogicalTurnLease,
host: {
id: `agent-harness:${harness.id}`,
label: `agent harness "${harness.id}"`,
capabilities: harness.contextEngineHostCapabilities ?? []
},
operation: "agent-run",
recorder: internalParams.userTurnTranscriptRecorder
});
await drainPendingContextEngineTurnsBeforeRun({
admission: internalParams.userTurnTranscriptRecorder?.getAdmissionReceipt(),
isHeartbeat: isHeartbeatLifecycleRunKind(internalParams.bootstrapContextRunKind),
lease: internalParams.contextEngineLogicalTurnLease,
recorder: internalParams.userTurnTranscriptRecorder,
sessionTarget: internalParams.sessionTarget
});
const effective = internalParams.contextEngineLogicalTurnLease.begin();
internalParams = {
...internalParams,
contextEngine: effective.engine.info.id === "legacy" ? void 0 : effective.engine
};
}
if (internalParams.systemAgentTool && !isSystemAgentOnlyAllowlist(internalParams.toolsAllow)) throw new Error("OpenClaw host authority requires toolsAllow: [\"openclaw\"]");
const ringZeroTools = internalParams.systemAgentTool ? [(await import("./system-agent-tool-CgJexaQa.js")).createSystemAgentTool(internalParams.systemAgentTool)] : [];
if (!selection.builtIn && !internalParams.suppressNextUserMessagePersistence && internalParams.userTurnTranscriptRecorder) {
const assertCurrent = resolveAdmittedRunActiveAssertion(internalParams.admittedRunContext, internalParams.abortSignal);
if (!assertCurrent) throw new Error("agent harness requires active admitted run authority");
assertCurrent();
await internalParams.userTurnTranscriptRecorder.persistApproved({ cwd: internalParams.cwd ?? internalParams.workspaceDir });
assertCurrent();
}
if (nativeSessionRuntime) await nativeSessionRuntime.assertCurrent();
const pluginAttempt = withoutInternalHarnessAuthority(withoutHarnessSetupAuthority(internalParams), harness, selection.builtIn, selection.ownerPluginId);
logAgentHarnessSelection(selection, {
provider: params.provider,
modelId: params.modelId,
sessionKey: params.sessionKey,
agentId: params.agentId
});
let result;
try {
result = await runAgentHarnessOperation(harness, params, () => runWithAgentRingZeroTools(ringZeroTools, () => {
const hostOpenClawAuthority = isHostScopedAgentToolActive("openclaw") && isSystemAgentOnlyAllowlist(pluginAttempt.params.toolsAllow);
const preparedParams = selection.builtIn ? pluginAttempt.params : preparePluginHarnessParams(pluginAttempt.params, harness);
const effectiveAttemptParams = hostOpenClawAuthority && preparedParams.pluginHarnessToolPolicyRestricted ? {
...preparedParams,
pluginHarnessToolPolicyRestricted: false
} : preparedParams;
assertPluginHarnessConversationToolPolicySupport(harness, effectiveAttemptParams.pluginHarnessToolPolicyRestricted === true);
return import("./tool-authority.runtime.js").then(({ withPreparedEmbeddedRunToolAuthority }) => withPreparedEmbeddedRunToolAuthority(internalParams, effectiveAttemptParams, selection.builtIn ? void 0 : (input) => {
return resolvePluginHarnessDenyAllToolPolicyPrompt(resolvePluginHarnessToolPolicies({
...input.run,
modelId: input.run.model,
sandboxSessionKey: input.run.runtimePolicySessionKey,
messageChannel: input.originatingChannel,
toolsAllow: input.toolsAllow,
disableTools: input.disableTools
})) ? {
...input,
toolsAllow: []
} : input;
}, (prepared) => pluginAttempt.runWithHostScope(() => runAgentHarnessLifecycleAttempt(harness, prepared))));
}));
} finally {
pluginAttempt.closeHostCapabilities();
}
const admission = internalParams.userTurnTranscriptRecorder?.getAdmissionReceipt();
if (internalParams.onContextEngineTurnCandidate && admission && result.contextEngineTerminalAnchor) internalParams.onContextEngineTurnCandidate({
boundary: {
admission,
terminal: result.contextEngineTerminalAnchor
},
sessionIdUsed: result.sessionIdUsed,
sessionKey: internalParams.sessionKey,
sessionTarget: internalParams.sessionTarget,
promptError: result.terminal.kind === "failed",
aborted: result.terminal.kind === "aborted" || result.terminal.kind === "timeout" && "aborted" in result.terminal && result.terminal.aborted === true,
yieldAborted: result.terminal.kind === "aborted" && result.terminal.source === "yield_cleanup",
isHeartbeat: isHeartbeatLifecycleRunKind(internalParams.bootstrapContextRunKind)
});
const { contextEngineTerminalAnchor: _contextEngineTerminalAnchor, ...publicResult } = result;
return copyCoreTtsAttemptResultProvenance(result, publicResult);
}
function selectPreparedAgentHarness(params) {
return selectAgentHarnessDecision({
provider: params.provider,
modelId: params.modelId,
modelProvider: {
api: params.model.api,
baseUrl: params.model.baseUrl,
...resolveAgentHarnessPreparedRouteSupport(params.runtimePlan?.auth),
preparedAuth: resolveAgentHarnessPreparedAuthSupport({ plan: params.runtimePlan?.auth })
},
config: params.config,
agentId: params.agentId,
sessionKey: params.sessionKey,
agentHarnessId: params.agentHarnessId,
agentHarnessRuntimeOverride: params.agentHarnessRuntimeOverride,
preparedModelProvider: params.runtimePlan?.auth !== void 0
});
}
async function runAgentHarnessOperation(harness, params, execute) {
const activeTrace = getActiveDiagnosticTraceContext();
const harnessTrace = freezeDiagnosticTraceContext(activeTrace ? createChildDiagnosticTraceContext(activeTrace) : createDiagnosticTraceContext());
if (isBuiltInOpenClawAgentHarness(harness)) return await runWithDiagnosticTraceContext(harnessTrace, execute);
try {
return await runWithDiagnosticTraceContext(harnessTrace, execute);
} catch (error) {
log.warn(`${harness.label} failed; not falling back to embedded OpenClaw backend`, {
harnessId: harness.id,
provider: params.provider,
modelId: params.modelId,
error: formatErrorMessage(error)
});
throw error;
}
}
function isSystemAgentOnlyAllowlist(toolsAllow) {
return toolsAllow?.length === 1 && normalizeToolPolicyName(toolsAllow[0] ?? "") === "openclaw";
}
function withoutHarnessSetupAuthority(params) {
const { contextEngineLogicalTurnLease: _contextEngineLogicalTurnLease, systemAgentTool: _systemAgentTool, ...attemptParams } = params;
return attemptParams;
}
function withoutInternalHarnessAuthority(params, harness, builtIn, ownerPluginId) {
if (builtIn) return {
params: {
...params,
operationalRunInstance: params.admittedRunContext.operationalRunInstance
},
closeHostCapabilities: () => {},
runWithHostScope: (run) => run()
};
const pluginParams = withoutPluginHarnessPrivateState(params);
const host = createAgentHarnessHostCapabilities({
attempt: params,
requiredNodeCommands: harness.cloudPlacement?.devicePlacement?.requiredNodeCommands,
pluginId: ownerPluginId ?? (() => {
throw new Error(`Agent harness ${harness.id} has no authoritative registry owner.`);
})()
});
return {
params: {
...pluginParams,
hostCapabilities: host.capabilities
},
closeHostCapabilities: host.close,
runWithHostScope: host.runWithScope
};
}
function prepareHarnessFinalizationParams(params, builtIn) {
const { hostCapabilities: _hostCapabilities, systemAgentTool: _systemAgentTool, ...withoutCapabilities } = params;
if (builtIn) return withoutCapabilities;
const pluginParams = withoutPluginHarnessPrivateState(withoutCapabilities);
const boundary = "plugin harness finalization handoff";
return {
...pluginParams,
model: unwrapModelHeaderSentinelsForProviderEgress(pluginParams.model, boundary),
resolvedApiKey: pluginParams.resolvedApiKey ? unwrapSecretSentinelsForProviderEgress(pluginParams.resolvedApiKey, boundary) : pluginParams.resolvedApiKey
};
}
function withoutPluginHarnessPrivateState(params) {
const { admittedRunContext: _admittedRunContext, compactionCountOwner: _compactionCountOwner, onContextAccountingEvent: _onContextAccountingEvent, contextEngineLogicalTurnLease: _contextEngineLogicalTurnLease, hostCapabilities: _hostCapabilities, onContextEngineTurnCandidate: _onContextEngineTurnCandidate, trajectoryRecorder: _trajectoryRecorder, __openclawSourceReplyDeliveryRuntime: _sourceReplyDeliveryRuntime, ...pluginParams } = params;
return pluginParams;
}
function preparePluginHarnessParams(params, harness) {
const boundary = "plugin harness handoff";
const resolvedApiKey = params.resolvedApiKey ? unwrapSecretSentinelsForProviderEgress(params.resolvedApiKey, boundary) : params.resolvedApiKey;
const model = unwrapModelHeaderSentinelsForProviderEgress(params.model, boundary);
const preparedParams = model === params.model && resolvedApiKey === params.resolvedApiKey ? params : {
...params,
model,
resolvedApiKey
};
const policies = resolvePluginHarnessToolPolicies(preparedParams, harness.conversationToolPolicySupport === "exact" ? harness.conversationToolPolicySafeDenyTools : void 0);
return applyPluginHarnessDenyAllToolPolicy({
...preparedParams,
pluginHarnessToolPolicySafeDeniedTools: policies.safeDeniedToolNames.length > 0 ? policies.safeDeniedToolNames : void 0,
pluginHarnessToolPolicyRestricted: policies.toolPolicyRestricted
}, policies);
}
function assertPluginHarnessConversationToolPolicySupport(harness, restricted) {
if (harness.id !== "openclaw" && restricted && harness.conversationToolPolicySupport !== "exact") throw new AgentHarnessPreflightError(`${harness.label} cannot enforce this conversation's tool policy. Use the embedded runtime or ask in the main conversation.`, { scope: "harness" });
}
function applyPluginHarnessDenyAllToolPolicy(params, policies) {
if (isHostScopedAgentToolActive("openclaw") && params.toolsAllow?.length === 1 && normalizeToolPolicyName(params.toolsAllow[0] ?? "") === "openclaw") return params;
const prompt = resolvePluginHarnessDenyAllToolPolicyPrompt(policies);
if (!prompt) return params;
return {
...params,
toolsAllow: [],
extraSystemPrompt: appendPluginHarnessToolPolicyPrompt(params.extraSystemPrompt, prompt)
};
}
function resolvePluginHarnessPolicyToolsAllow(params) {
const policies = resolvePluginHarnessToolPolicies(params);
return [
policies.senderPolicy,
policies.groupPolicy,
...policies.runtimePolicies
].some(toolPolicyRestrictsTools) ? [] : void 0;
}
/** Resolves whether a harness operation must remove its ambient native tool surface. */
function resolveAgentHarnessNativeToolPolicyRestricted(params, harness) {
return resolvePluginHarnessToolPolicies(params, harness.conversationToolPolicySupport === "exact" ? harness.conversationToolPolicySafeDenyTools : void 0).toolPolicyRestricted;
}
function resolvePluginHarnessDenyAllToolPolicyPrompt(policies) {
if (policyDeniesAllTools(policies.senderPolicy) || policyDeniesAllTools(policies.senderScopedGroupPolicy)) return PLUGIN_HARNESS_SENDER_DENY_ALL_PROMPT;
if (policyDeniesAllTools(policies.groupPolicy)) return PLUGIN_HARNESS_GROUP_DENY_ALL_PROMPT;
return policies.runtimePolicies.some(policyDeniesAllTools) ? PLUGIN_HARNESS_RUNTIME_DENY_ALL_PROMPT : void 0;
}
function resolvePluginHarnessToolPolicies(params, safeDenyToolNames) {
const messageProvider = params.messageProvider ?? params.messageChannel;
const sandboxSessionKey = params.sandboxSessionKey ?? params.sessionKey;
const sandboxRuntime = resolveSandboxRuntimeStatus({
cfg: params.config,
agentId: params.agentId,
sessionKey: params.sessionKey ?? (params.agentId ? void 0 : sandboxSessionKey),
classificationSessionKey: sandboxSessionKey,
classificationAgentId: params.sandboxAgentId
});
const sandboxPolicy = sandboxRuntime.sandboxed ? sandboxRuntime.toolPolicy : void 0;
const capabilityProfile = resolveConversationCapabilityProfile({
config: params.config,
sessionId: params.sessionId,
sessionKey: params.sessionKey,
sandboxSessionKey,
agentId: params.agentId,
modelProvider: params.provider,
modelId: params.modelId,
messageProvider,
messageChannel: params.messageChannel,
conversationToolPolicy: params.conversationToolPolicy,
agentAccountId: params.agentAccountId,
groupId: params.groupId,
groupChannel: params.groupChannel,
groupSpace: params.groupSpace,
memberRoleIds: params.memberRoleIds,
spawnedBy: params.spawnedBy,
senderId: params.senderId,
senderName: params.senderName,
senderUsername: params.senderUsername,
senderE164: params.senderE164,
senderIsOwner: params.senderIsOwner,
sandboxToolPolicy: sandboxPolicy,
inputProvenance: params.inputProvenance,
trustedInternalHandoff: params.trustedInternalHandoff,
scheduledToolPolicy: params.scheduledToolPolicy,
runtimePluginToolGrant: params.runtimePluginToolGrant
});
const groupPolicyParams = {
config: params.config,
sessionKey: params.scheduledToolPolicy?.ownerSessionKey ?? params.sessionKey,
spawnedBy: params.spawnedBy,
messageProvider,
groupId: params.groupId,
groupChannel: params.groupChannel,
groupSpace: params.groupSpace,
accountId: params.scheduledToolPolicy?.ownerAccountId ?? params.agentAccountId,
requireConfiguredAccount: params.scheduledToolPolicy?.mode === "account",
senderId: params.senderId,
senderName: params.senderName,
senderUsername: params.senderUsername,
senderE164: params.senderE164,
senderPolicyMode: params.scheduledToolPolicy ? "never" : "always"
};
const { policy } = capabilityProfile;
const requestedToolPolicy = params.disableTools ? { allow: [] } : params.toolsAllow ? { allow: params.toolsAllow } : void 0;
const explicitPolicies = [
policy.globalPolicy,
policy.globalProviderPolicy,
policy.agentPolicy,
policy.agentProviderPolicy,
policy.groupPolicy,
policy.senderPolicy,
policy.sandboxPolicy,
policy.subagentPolicy,
policy.inheritedToolPolicy,
policy.runtimeToolPolicyForInheritance,
requestedToolPolicy
];
const safeDenyToolNameSet = safeDenyToolNames ? new Set(safeDenyToolNames.map(normalizeToolPolicyName)) : void 0;
return {
senderPolicy: policy.senderPolicy,
senderScopedGroupPolicy: resolveSenderScopedGroupToolPolicy(params, groupPolicyParams, policy.groupPolicy),
groupPolicy: policy.groupPolicy,
runtimePolicies: [
mergeAlsoAllowPolicy(policy.profilePolicy, policy.profileAlsoAllow),
mergeAlsoAllowPolicy(policy.providerProfilePolicy, policy.providerProfileAlsoAllow),
policy.globalPolicy,
policy.globalProviderPolicy,
policy.agentPolicy,
policy.agentProviderPolicy,
sandboxPolicy,
policy.subagentPolicy,
policy.inheritedToolPolicy,
requestedToolPolicy
],
safeDeniedToolNames: collectHarnessSafeDeniedToolNames(explicitPolicies, safeDenyToolNameSet),
toolPolicyRestricted: params.swarmCollector === true || explicitPolicies.some((explicitPolicy) => toolPolicyRestrictsHarnessNativeTools(explicitPolicy, safeDenyToolNameSet))
};
}
function collectHarnessSafeDeniedToolNames(policies, safeDenyToolNames) {
if (!safeDenyToolNames) return [];
return [...new Set(policies.flatMap((policy) => expandToolGroups(policy?.deny ?? [])).map(normalizeToolPolicyName).filter((name) => isKnownCoreToolId(name) && safeDenyToolNames.has(name)))].toSorted();
}
function toolPolicyRestrictsHarnessNativeTools(policy, safeDenyToolNames) {
if (!safeDenyToolNames) return toolPolicyRestrictsTools(policy);
if (!policy || toolPolicyRestrictsTools({ allow: policy.allow })) return toolPolicyRestrictsTools(policy);
return expandToolGroups(policy.deny ?? []).some((deniedName) => {
const normalized = normalizeToolPolicyName(deniedName);
return !isKnownCoreToolId(normalized) || !safeDenyToolNames.has(normalized);
});
}
function resolveSenderScopedGroupToolPolicy(params, groupPolicyParams, groupPolicy) {
if (!policyDeniesAllTools(groupPolicy) || !hasSenderIdentity(params)) return;
return policyDeniesAllTools(resolveGroupToolPolicy({
...groupPolicyParams,
senderId: void 0,
senderName: void 0,
senderUsername: void 0,
senderE164: void 0
})) ? void 0 : groupPolicy;
}
function hasSenderIdentity(params) {
return Boolean(params.senderId?.trim() || params.senderName?.trim() || params.senderUsername?.trim() || params.senderE164?.trim());
}
function appendPluginHarnessToolPolicyPrompt(existing, prompt) {
const trimmed = existing?.trim();
if (!trimmed) return prompt;
return trimmed.includes(prompt) ? trimmed : `${trimmed}\n\n${prompt}`;
}
function policyDeniesAllTools(policy) {
return expandToolGroups(policy?.deny ?? []).some((entry) => normalizeToolPolicyName(entry) === "*");
}
function listHarnessCandidates(harnesses) {
return harnesses.map((harness) => ({
id: harness.id,
label: harness.label,
pluginId: harness.pluginId
}));
}
function toSelectionCandidate(entry) {
return {
id: entry.harness.id,
label: entry.harness.label,
pluginId: entry.harness.pluginId,
supported: entry.support.supported,
priority: entry.support.supported ? entry.support.priority : void 0,
reason: entry.support.reason
};
}
function buildSelectionDecision(params) {
const builtIn = isBuiltInOpenClawAgentHarness(params.harness);
return {
harness: params.harness,
builtIn,
...!builtIn ? { ownerPluginId: resolveAgentHarnessOwnerPluginId(params.harness) } : {},
policy: params.policy,
selectedHarnessId: params.harness.id,
selectedReason: params.selectedReason,
candidates: params.candidates
};
}
function logAgentHarnessSelection(selection, params) {
if (!log.isEnabled("debug")) return;
log.debug("agent harness selected", {
provider: params.provider,
modelId: params.modelId,
sessionKey: params.sessionKey,
agentId: params.agentId,
selectedHarnessId: selection.selectedHarnessId,
selectedReason: selection.selectedReason,
runtime: selection.policy.runtime,
candidates: selection.candidates
});
}
function formatProviderModel(params) {
return params.modelId ? `${params.provider}/${params.modelId}` : params.provider;
}
//#endregion
export { resolvePluginHarnessToolPolicies as a, selectAgentHarness as c, resolvePluginHarnessPolicyToolsAllow as i, selectAgentHarnessForPreparedModelProviders as l, agentHarnessExposesOpenClawTools as n, runAgentHarnessAttempt as o, resolveAgentHarnessNativeToolPolicyRestricted as r, runAgentHarnessSettledTurnFinalization as s, agentHarnessBuildsOpenClawTools as t };