File size: 2,654 Bytes
5cb63c1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | /**
* Configured binding target lifecycle helpers.
*
* Ensures or resets stateful binding targets through registered target drivers.
*/
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import type { ConfiguredBindingResolution } from "./binding-types.js";
import {
ensureStatefulTargetBuiltinsRegistered,
isStatefulTargetBuiltinDriverId,
} from "./stateful-target-builtins.js";
import {
getStatefulBindingTargetDriver,
resolveStatefulBindingTargetBySessionKey,
type StatefulBindingTargetResetResult,
} from "./stateful-target-drivers.js";
/**
* Ensures the stateful target driver for a configured binding is ready to receive traffic.
*/
export async function ensureConfiguredBindingTargetReady(params: {
cfg: OpenClawConfig;
bindingResolution: ConfiguredBindingResolution | null;
}): Promise<{ ok: true } | { ok: false; error: string }> {
if (!params.bindingResolution) {
return { ok: true };
}
const driverId = params.bindingResolution.statefulTarget.driverId;
let driver = getStatefulBindingTargetDriver(driverId);
// Built-in drivers are registered lazily so normal channel startup does not load every
// stateful target implementation before a binding actually needs one.
if (!driver && isStatefulTargetBuiltinDriverId(driverId)) {
await ensureStatefulTargetBuiltinsRegistered();
driver = getStatefulBindingTargetDriver(driverId);
}
if (!driver) {
return {
ok: false,
error: `Configured binding target driver unavailable: ${driverId}`,
};
}
return await driver.ensureReady({
cfg: params.cfg,
bindingResolution: params.bindingResolution,
});
}
/**
* Resets a stateful configured binding target in place when its driver supports reset.
*/
export async function resetConfiguredBindingTargetInPlace(params: {
cfg: OpenClawConfig;
sessionKey: string;
agentId?: string;
reason: "new" | "reset";
commandSource?: string;
}): Promise<StatefulBindingTargetResetResult> {
let resolved = resolveStatefulBindingTargetBySessionKey({
cfg: params.cfg,
sessionKey: params.sessionKey,
agentId: params.agentId,
});
if (!resolved) {
await ensureStatefulTargetBuiltinsRegistered();
resolved = resolveStatefulBindingTargetBySessionKey({
cfg: params.cfg,
sessionKey: params.sessionKey,
agentId: params.agentId,
});
}
if (!resolved?.driver.resetInPlace) {
// A missing reset hook is a valid skip, not a hard routing failure.
return {
ok: false,
skipped: true,
};
}
return await resolved.driver.resetInPlace({
...params,
bindingTarget: resolved.bindingTarget,
});
}
|