openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
158 lines (157 loc) • 6.36 kB
JavaScript
import { t as ErrorCodes } from "./gateway-error-details-w0nAGBBp.js";
import { li as validateSessionsGoalClearParams, ui as validateSessionsGoalUpdateParams } from "./src-BiL5aQto.js";
import { d as errorShape } from "./error-codes-Bo8q2D1o.js";
import { H as SessionGoalOperationError, W as mutateSessionGoal } from "./session-accessor-YsytfDtG.js";
import { d as recordSessionGoalChanged } from "./session-state-events-DNCKmH78.js";
import { h as gatewayClientSessionCreator } from "./operator-role-policy-wsr1DeJv.js";
import { n as resolveRequestedSessionAgentId } from "./session-request-agent-CCRSEGCB.js";
import { H as SessionMutationAuthorizationChangedError, a as resolveSessionMutationAuthorization, z as resolveSessionSharingTarget } from "./session-sharing-B7MI8hNo.js";
import { t as assertValidParams } from "./validation-pzrlzFvo.js";
import { t as resolvePluginSessionOwnershipError } from "./session-plugin-ownership-421Ior05.js";
import { n as emitSessionsChanged } from "./session-change-event-DzmH4zlz.js";
import { t as fingerprintSessionGoalRequest } from "./session-goal-request-DNfoPNll.js";
//#region src/gateway/server-methods/sessions-goal.ts
async function handleSessionGoalMutation(options, request) {
const { client, context, respond } = options;
const method = request.action === "clear" ? "sessions.goal.clear" : "sessions.goal.update";
try {
const authorization = options.sessionMutationAuthorization ? {
authorization: options.sessionMutationAuthorization,
error: null
} : resolveSessionMutationAuthorization({
client,
method,
requestParams: request,
context
});
if (authorization.error) {
respond(false, void 0, authorization.error);
return;
}
const cfg = context.getRuntimeConfig();
const requestedAgent = resolveRequestedSessionAgentId(cfg, request.sessionKey, request.agentId);
if (!requestedAgent.ok) {
respond(false, void 0, requestedAgent.error);
return;
}
const target = resolveSessionSharingTarget({
cfg,
sessionKey: request.sessionKey,
agentId: requestedAgent.agentId
});
if (!target || request.sessionId && target.entry.sessionId !== request.sessionId) {
respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, "Session changed or was removed; refresh its Goal."));
return;
}
const assertCurrent = () => {
options.sessionMutationCommitGuard?.();
authorization.authorization?.assertCurrent();
const current = resolveSessionSharingTarget({
cfg: context.getRuntimeConfig(),
sessionKey: request.sessionKey,
agentId: requestedAgent.agentId
});
if (!current || current.agentId !== target.agentId || current.storePath !== target.storePath || current.storeKey !== target.storeKey || current.entry.sessionId !== target.entry.sessionId || current.entry.lifecycleRevision !== target.entry.lifecycleRevision) throw new SessionMutationAuthorizationChangedError(errorShape(ErrorCodes.INVALID_REQUEST, "Session changed before its Goal update; retry."));
const ownershipError = resolvePluginSessionOwnershipError({
action: "patch",
entry: current.entry,
key: current.canonicalKey,
pluginOwnerId: client?.internal?.pluginRuntimeOwnerId
});
if (ownershipError) throw new SessionMutationAuthorizationChangedError(ownershipError);
};
assertCurrent();
const identity = {
operationId: request.operationId,
issuedAtMs: request.issuedAtMs,
requestFingerprint: fingerprintSessionGoalRequest({
method,
...request
}),
goalId: request.goalId
};
if (request.action === "resume") {
const { handleSessionGoalResumeChat } = await import("./chat-send-handler-CZYRI5Zs.js");
await handleSessionGoalResumeChat({
...options,
sessionMutationAuthorization: {
assertCurrent,
assertTargetCurrent: assertCurrent
},
params: {
sessionKey: target.canonicalKey,
agentId: target.agentId,
sessionId: target.entry.sessionId,
message: request.note ? `Continue pursuing the current goal.\nOperator note: ${request.note}` : "Continue pursuing the current goal.",
idempotencyKey: request.operationId,
deliver: false
}
}, {
...identity,
action: "resume",
...request.note ? { note: request.note } : {}
});
return;
}
const operation = request.action === "edit" ? {
...identity,
action: "edit",
objective: request.objective
} : {
...identity,
action: request.action,
..."note" in request && request.note ? { note: request.note } : {}
};
const committed = await mutateSessionGoal({
agentId: target.agentId,
sessionKey: target.storeKey,
storePath: target.storePath,
expectedSessionId: target.entry.sessionId,
operation,
assertCurrent
});
if (!committed.replayed && committed.sessionEntry) {
recordSessionGoalChanged({
sessionKey: target.canonicalKey,
agentId: target.agentId,
entry: committed.sessionEntry,
actor: gatewayClientSessionCreator(client),
summary: `goal ${request.action}`
});
emitSessionsChanged(context, {
sessionKey: target.canonicalKey,
agentId: target.agentId,
reason: "goal"
});
}
respond(true, {
...committed.result,
...committed.replayed ? { replayed: true } : {}
}, void 0);
} catch (error) {
if (error instanceof SessionMutationAuthorizationChangedError) respond(false, void 0, error.error);
else if (error instanceof SessionGoalOperationError) respond(false, void 0, errorShape(ErrorCodes.INVALID_REQUEST, error.message, { details: {
code: "GOAL_OPERATION_REJECTED",
reason: error.code
} }));
else {
context.logGateway.warn(`Goal update failed: ${String(error)}`);
respond(false, void 0, errorShape(ErrorCodes.UNAVAILABLE, "Unable to update the Goal; retry the request."));
}
}
}
const sessionGoalHandlers = {
"sessions.goal.update": async (options) => {
const { params, respond } = options;
if (assertValidParams(params, validateSessionsGoalUpdateParams, "sessions.goal.update", respond)) await handleSessionGoalMutation(options, params);
},
"sessions.goal.clear": async (options) => {
const { params, respond } = options;
if (assertValidParams(params, validateSessionsGoalClearParams, "sessions.goal.clear", respond)) await handleSessionGoalMutation(options, {
...params,
action: "clear"
});
}
};
//#endregion
export { sessionGoalHandlers };