openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
205 lines (204 loc) • 13.3 kB
JavaScript
import { a as getPluginRuntimeGatewayRequestScope, n as getInProcessGatewayRequestContext, s as withPluginRuntimeGatewayContextResolver } from "./gateway-request-scope-BSmCVVpP.mjs";
import { s as resolveLeastPrivilegeOperatorScopesForMethod } from "./method-scopes-BrMPjfvW.mjs";
import { a as getGatewayToolCallerIdentity, c as resolveGatewayToolOperatorSelection, p as withoutGatewayToolCallerIdentity, t as captureGatewayToolCallerAssertion } from "./gateway-caller-context-DWr-fdGt.mjs";
import { l as runWithGatewaySessionSpawnContext, t as callGatewayTool } from "./gateway-0EbWS5cg.mjs";
import { r as createCronMutationCompletion } from "./mutation-completion-DRIubopj.mjs";
import { c as runWithOperatorToolGatewayContinuationContext, s as runWithOperatorToolGatewayCleanupContext, t as dispatchGatewayMethodInProcess, u as withInProcessAgentRuntimeIdentity } from "./server-plugin-in-process-dispatch-DiO-p5Qs.mjs";
import { n as readInProcessSessionDeliveryGeneration } from "./in-process-session-delivery-CX7--QA6.mjs";
import { a as bindInProcessSubagentResume, o as readInProcessSubagentResume } from "./server-plugin-runtime-client-Bn0mfXdW.mjs";
import { AsyncLocalStorage } from "node:async_hooks";
//#region src/agents/tools/in-process-gateway.ts
const agentToolGatewayRuntimeIdentities = /* @__PURE__ */ new WeakMap();
/** Carry trusted runtime identity without making it enumerable or transportable. */
function withAgentToolGatewayRuntimeIdentity(request, identity) {
if (!identity) return request;
const carried = { ...request };
agentToolGatewayRuntimeIdentities.set(carried, identity);
return bindInProcessSubagentResume(carried, readInProcessSubagentResume(request));
}
const DEFAULT_IN_PROCESS_GATEWAY_REQUEST_TIMEOUT_MS = 1e4;
function callerGatewayContextResolver(explicit) {
return explicit ?? getGatewayToolCallerIdentity()?.gatewayContextResolver;
}
/** Transfer already-owned cleanup to its Gateway, without retaining the finished turn. */
function runWithGatewayToolCleanupContext(run, explicitResolver) {
const resolveGatewayContext = callerGatewayContextResolver(explicitResolver);
return withoutGatewayToolCallerIdentity(() => runWithOperatorToolGatewayCleanupContext(() => resolveGatewayContext ? withPluginRuntimeGatewayContextResolver(resolveGatewayContext, run) : run()));
}
/** Transfers accepted reply work to a bounded source-authority hold, not the tool lifetime. */
function runWithGatewayToolContinuationContext(run) {
const resolveGatewayContext = callerGatewayContextResolver();
return runWithOperatorToolGatewayContinuationContext(() => withoutGatewayToolCallerIdentity(() => resolveGatewayContext ? withPluginRuntimeGatewayContextResolver(resolveGatewayContext, run) : run()));
}
function bindInProcessGatewayContext(method, resolveGatewayContext) {
const admittedContext = resolveGatewayContext();
if (!admittedContext) throw new Error(`Gateway instance unavailable for ${method}`);
const assertCurrent = () => {
if (resolveGatewayContext() !== admittedContext) throw new Error(`Gateway instance unavailable for ${method}`);
};
return {
assertCurrent,
resolve: () => {
assertCurrent();
return admittedContext;
}
};
}
async function runBoundInProcessGatewayCall(boundGateway, run, assertCallerCurrent, revalidateOnCompletion = true, completion) {
const assertCurrent = (afterDispatch = false) => {
boundGateway?.assertCurrent();
if (!afterDispatch || (completion ? !completion.isCommitted() : revalidateOnCompletion)) assertCallerCurrent?.();
};
try {
assertCurrent();
const result = completion ? await completion.run(() => run(boundGateway?.resolve)) : await run(boundGateway?.resolve);
assertCurrent(true);
return result;
} catch (error) {
assertCurrent(true);
throw error;
}
}
function hasInProcessGatewayToolContext() {
return Boolean(getInProcessGatewayRequestContext(callerGatewayContextResolver()));
}
/** Whether Gateway routing belongs to this caller or the hosting process. */
function hasGatewayToolRoutingContext() {
const resolver = callerGatewayContextResolver() ?? getPluginRuntimeGatewayRequestScope()?.resolveGatewayContext;
const context = getInProcessGatewayRequestContext(resolver);
return context?.localEmbedded !== true && Boolean(resolver || context);
}
function getInProcessGatewayToolContext(explicitResolver) {
return getInProcessGatewayRequestContext(callerGatewayContextResolver(explicitResolver));
}
/**
* Dispatches a request-shaped built-in tool call through the local Gateway
* router without opening a loopback transport. Outside a Gateway process, the
* same request falls back to the ordinary Gateway client.
*/
async function callAgentToolGatewayRequestBound(request, resolveGatewayContext, runtimeIdentity, assertCallerCurrent, forceTransport = false, revalidateOnCompletion = true, positional) {
const method = request.method;
const assertDispatchCurrent = request.assertDispatchCurrent;
const completion = positional ? void 0 : createCronMutationCompletion(method);
const assertCurrent = assertCallerCurrent || assertDispatchCurrent || (!revalidateOnCompletion || completion) && request.signal ? () => {
assertCallerCurrent?.(method);
assertDispatchCurrent?.();
if (!revalidateOnCompletion || completion) request.signal?.throwIfAborted();
} : void 0;
assertCurrent?.();
const boundGateway = resolveGatewayContext ? bindInProcessGatewayContext(method, resolveGatewayContext) : void 0;
const scopes = request.scopes ?? resolveLeastPrivilegeOperatorScopesForMethod(method, request.params);
if (forceTransport || !getInProcessGatewayRequestContext(boundGateway?.resolve)) {
if (boundGateway && !forceTransport) throw new Error(`Gateway instance unavailable for ${method}`);
if (getGatewayToolCallerIdentity()?.operatorAuthority) throw new Error("operator run authority requires its admitted Gateway");
if (positional) return await runBoundInProcessGatewayCall(boundGateway, () => positional.fallback(scopes), assertCurrent);
if (request.sessionMutationCommitGuard) throw new Error("Guarded session control requires its admitted in-process Gateway.");
if (readInProcessSessionDeliveryGeneration(request.params)) throw new Error("Session-bound delivery requires its admitted in-process Gateway.");
if (readInProcessSubagentResume(request)) throw new Error("Task resume requires trusted in-process Gateway dispatch.");
if (runtimeIdentity) throw new Error("trusted agent runtime identity requires in-process Gateway dispatch");
const { callGateway } = await import("./call-DLG6_hH-.mjs");
const { agentRunTracking: _agentRunTracking, agentToolCaller: _agentToolCaller, sessionMutationCommitGuard: _sessionMutationCommitGuard, ...wireRequest } = request;
return await runBoundInProcessGatewayCall(boundGateway, () => callGateway({
...wireRequest,
method
}), assertCurrent, revalidateOnCompletion);
}
const syntheticScopeMode = request.scopes === void 0 ? "minimum" : "exact";
const timeoutMs = request.timeoutMs === null ? void 0 : request.timeoutMs ?? DEFAULT_IN_PROCESS_GATEWAY_REQUEST_TIMEOUT_MS;
const transfersCreatedInput = method === "sessions.create" && positional?.sessionCreation?.via === "spawn" && request.agentToolCaller !== void 0;
const assertMutationCurrent = assertCurrent && !transfersCreatedInput ? () => {
assertCurrent();
request.sessionMutationCommitGuard?.();
} : request.sessionMutationCommitGuard;
const dispatchOptions = {
forceSyntheticClient: true,
operatorRoleActor: { kind: "system" },
...request.agentRunTracking ? { agentRunTracking: request.agentRunTracking } : {},
...request.agentToolCaller ? { agentToolCaller: request.agentToolCaller } : {},
...positional?.sessionCreation ? { sessionCreation: positional.sessionCreation } : {},
...positional?.onExecution ? { onExecution: positional.onExecution } : {},
syntheticScopes: scopes,
syntheticScopeMode,
...request.expectFinal !== void 0 ? { expectFinal: request.expectFinal } : {},
...request.onAccepted ? { onAccepted: request.onAccepted } : {},
...request.onSignalAbort ? { onSignalAbort: () => runWithGatewayToolCleanupContext(() => request.onSignalAbort?.((cleanupMethod, params, options) => callAgentToolGatewayRequestBound({
method: cleanupMethod,
params,
...options
}, boundGateway?.resolve ?? resolveGatewayContext, void 0, void 0)), boundGateway?.resolve ?? resolveGatewayContext) } : {},
...request.signal && revalidateOnCompletion && !completion ? { signal: request.signal } : {},
...timeoutMs !== void 0 ? { timeoutMs } : {},
...boundGateway ? { resolveGatewayContext: boundGateway.resolve } : {},
...assertMutationCurrent ? { sessionMutationCommitGuard: assertMutationCurrent } : {}
};
return await runBoundInProcessGatewayCall(boundGateway, async () => await dispatchGatewayMethodInProcess(method, request.params ?? {}, bindInProcessSubagentResume(withInProcessAgentRuntimeIdentity(dispatchOptions, runtimeIdentity), readInProcessSubagentResume(request))), assertCurrent, revalidateOnCompletion, completion);
}
/** Capture one Gateway and caller for a multi-request operation. */
function bindAgentToolGatewayRequest(options) {
const scope = getPluginRuntimeGatewayRequestScope();
const resolver = callerGatewayContextResolver(options?.resolveGatewayContext) ?? scope?.resolveGatewayContext;
const admitted = getInProcessGatewayRequestContext(resolver);
const resolveGatewayContext = resolver ? () => resolver() === admitted ? admitted : void 0 : admitted ? () => admitted : void 0;
const assertCallerCurrent = captureGatewayToolCallerAssertion();
const runInCallerContext = AsyncLocalStorage.snapshot();
return async (request) => await runInCallerContext(() => callAgentToolGatewayRequestBound(request, resolveGatewayContext, agentToolGatewayRuntimeIdentities.get(request), assertCallerCurrent, !resolver && !admitted || options?.hostedOnly === true && admitted?.localEmbedded === true, options?.revalidateOnCompletion));
}
const callAgentToolGatewayRequest = async (request) => await bindAgentToolGatewayRequest()(request);
async function callInProcessGatewayToolBound(method, params, options, fallback) {
const assertCallerCurrent = captureGatewayToolCallerAssertion();
const caller = getGatewayToolCallerIdentity();
return await callAgentToolGatewayRequestBound({
method,
params,
agentToolCaller: options.sessionCreation?.via === "spawn" && caller && assertCallerCurrent ? {
agentId: caller.agentId,
sessionKey: caller.sessionKey,
assertCurrent: assertCallerCurrent
} : void 0,
sessionMutationCommitGuard: options.sessionMutationCommitGuard,
signal: options.signal,
timeoutMs: options.timeoutMs ?? null
}, callerGatewayContextResolver(options.resolveGatewayContext), void 0, assertCallerCurrent, false, true, {
sessionCreation: options.sessionCreation,
onExecution: options.onExecution,
fallback
});
}
const callInProcessGatewayTool = async (method, params, options = {}) => {
return await callInProcessGatewayToolBound(method, params, options, async (scopes) => callGatewayTool(method, options.timeoutMs == null ? {} : { timeoutMs: options.timeoutMs }, params, {
scopes,
...options.signal ? { signal: options.signal } : {}
}));
};
async function callInProcessGatewayToolWithCreation(method, params, creation, options = {}) {
const requesterProfileId = resolveGatewayToolOperatorSelection().operatorAuthority?.profileId;
const trustedCreation = creation.via === "spawn" && requesterProfileId ? {
...creation,
requesterProfileId
} : creation;
return await callInProcessGatewayToolBound(method, params, {
...options,
sessionCreation: trustedCreation
}, async (scopes) => {
const gatewayOptions = options.timeoutMs == null ? {} : { timeoutMs: options.timeoutMs };
if (trustedCreation.via !== "spawn" || !trustedCreation.inheritedToolPolicy) return await callGatewayTool(method, gatewayOptions, params, {
scopes,
...options.signal ? { signal: options.signal } : {}
});
return await runWithGatewaySessionSpawnContext({
...trustedCreation.requesterProfileId ? { requesterProfileId: trustedCreation.requesterProfileId } : {},
...trustedCreation.completionOwnerSessionKey ? { completionOwnerSessionKey: trustedCreation.completionOwnerSessionKey } : {},
requesterSenderIsOwner: trustedCreation.requesterSenderIsOwner,
inheritedToolPolicy: trustedCreation.inheritedToolPolicy,
...trustedCreation.inheritedPermissionMode ? { inheritedPermissionMode: trustedCreation.inheritedPermissionMode } : {},
...trustedCreation.resolvedModel ? { resolvedModel: trustedCreation.resolvedModel } : {},
...trustedCreation.spawnModelAutoSelection ? { spawnModelAutoSelection: trustedCreation.spawnModelAutoSelection } : {}
}, () => callGatewayTool(method, gatewayOptions, params, {
scopes,
requireAgentRuntimeIdentity: true,
...options.signal ? { signal: options.signal } : {}
}));
});
}
//#endregion
export { getInProcessGatewayToolContext as a, runWithGatewayToolCleanupContext as c, callInProcessGatewayToolWithCreation as i, runWithGatewayToolContinuationContext as l, callAgentToolGatewayRequest as n, hasGatewayToolRoutingContext as o, callInProcessGatewayTool as r, hasInProcessGatewayToolContext as s, bindAgentToolGatewayRequest as t, withAgentToolGatewayRuntimeIdentity as u };