openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
147 lines (146 loc) • 6.4 kB
JavaScript
import { t as AsyncWorkScope } from "./async-work-scope-BYeX3gh6.mjs";
import { i as getOrCreatePromise } from "./lazy-promise-DGqyc4Y4.mjs";
import { o as getPluginValueInstance } from "./plugin-instance-scope-DEzoxqBj.mjs";
import { a as capturePluginLifecycleAuthority, f as getPluginRegistryLifetime } from "./registry-lifecycle-CZIcWb1R.mjs";
import { t as acquirePluginRegistryForInspection, v as isPluginRegistryLoadInFlight, y as resolvePluginRegistryLoadCacheKey } from "./loader-runtime-load-BrZtlYge.mjs";
import { i as collectRegistryInvocationInstances, n as getPluginRegistryInspectionResources, r as PluginInvocationScope } from "./registry-inspection-resources-Bz03kUly.mjs";
import "./loader-DHES6hdQ.mjs";
import { n as preparePluginCapabilityProviderLookup, o as acquireBundledCapabilityRuntimeRegistry, r as preparePluginCapabilityProviderResolution } from "./capability-provider-runtime-DMiCsZ75.mjs";
//#region src/plugins/capability-provider-acquisition.ts
/** Retains owned registrations while external hosts keep their own custody. */
async function acquirePluginCapabilityProviders(params) {
const work = new AsyncWorkScope();
const releases = [];
const loads = /* @__PURE__ */ new Map();
const retained = /* @__PURE__ */ new Map();
const authorities = /* @__PURE__ */ new Map();
const captureAuthority = (registry) => {
if (!authorities.has(registry)) authorities.set(registry, capturePluginLifecycleAuthority(registry, void 0, { scopedRuntime: true }));
};
const dispose = () => {
for (const invocations of retained.values()) invocations?.forEach((invocation) => invocation.release());
return Promise.allSettled(releases.map(async (releaseClaim) => await releaseClaim())).then((results) => {
const errors = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
if (errors.length > 0) throw new AggregateError(errors, "Capability registration cleanup failed");
});
};
const retain = (registry, providerId) => {
if (!registry) return;
const resources = getPluginRegistryInspectionResources(registry);
if (!retained.has(registry)) {
captureAuthority(registry);
const release = resources?.retain().release ?? getPluginRegistryLifetime(registry)?.retain();
if (release) releases.push(release);
retained.set(registry, release ? /* @__PURE__ */ new Map() : void 0);
}
const invocations = retained.get(registry);
if (!invocations) return;
return (provider) => {
const instance = providerId === void 0 ? void 0 : getPluginValueInstance(provider);
if (providerId !== void 0 && !instance) return provider;
const key = instance ?? registry;
let invocation = invocations.get(key);
if (!invocation) {
invocation = resources ? resources.createInvocationScope(registry, instance && [instance]) : new PluginInvocationScope(registry, instance ? [instance] : collectRegistryInvocationInstances(registry), { retained: true });
invocations.set(key, invocation);
}
return invocation.wrap(provider);
};
};
let releaseCompletion;
const release = () => releaseCompletion ??= Promise.resolve().then(async () => {
work.beginClose();
try {
await work.runWhenIdle(dispose);
} finally {
await work.drain();
}
});
const run = (operation) => releaseCompletion ? Promise.reject(/* @__PURE__ */ new Error("Capability provider acquisition has been released")) : work.track(operation);
const execute = async (resolution) => {
let entries = [];
if (resolution.load) {
const load = resolution.prepareLoad();
let registry = load.loadedRegistry;
if (!registry) {
const loadOptions = load.resolveLoadOptions();
if (!isPluginRegistryLoadInFlight(loadOptions)) {
const key = resolvePluginRegistryLoadCacheKey(loadOptions);
registry = await getOrCreatePromise(loads, key, () => acquirePluginRegistryForInspection(loadOptions).then((acquired) => {
releases.push(acquired.release);
captureAuthority(acquired.registry);
return acquired.registry;
}));
}
}
const fallback = load.fallback(registry);
entries = fallback.entries;
if (fallback.pluginIds.length > 0) {
const captured = await acquireBundledCapabilityRuntimeRegistry({
...resolution.load.loadOptions,
pluginIds: fallback.pluginIds
});
releases.push(captured.release);
captureAuthority(captured.registry);
entries = load.merge(entries, captured.registry);
}
}
return resolution.resolve(entries);
};
const resolveProviders = (query) => run(() => execute(preparePluginCapabilityProviderResolution({
...query,
key: params.key
}, retain)));
const resolveProvider = (query) => run(() => execute(preparePluginCapabilityProviderLookup({
...query,
key: params.key
}, (registry) => retain(registry, query.providerId))));
try {
return {
providers: params.providerId === void 0 ? await resolveProviders(params) : [await resolveProvider({
providerId: params.providerId,
cfg: params.cfg
})].filter((provider) => provider !== void 0),
run,
resolveProviders,
resolveProvider,
assertOpen: () => {
if (releaseCompletion || [...authorities.values()].some((isCurrent) => !isCurrent?.())) throw new Error("The provider setup changed while preparing this request. Retry with the current provider setup.");
},
release
};
} catch (error) {
return await finishCapabilityOperation({
ok: false,
error
}, release);
}
}
async function finishCapabilityOperation(outcome, release) {
try {
await release();
} catch (cleanupError) {
throw outcome.ok ? cleanupError : new AggregateError([outcome.error, cleanupError], "Capability operation and registration cleanup failed", { cause: outcome.error });
}
if (!outcome.ok) throw outcome.error;
return outcome.value;
}
/** Keeps callback-shaped operations on the same acquisition and actual-work owner. */
async function withAcquiredPluginCapabilityProviders(params, run) {
const acquired = await acquirePluginCapabilityProviders(params);
let outcome;
try {
outcome = {
ok: true,
value: await acquired.run(() => run(acquired.providers, acquired))
};
} catch (error) {
outcome = {
ok: false,
error
};
}
return await finishCapabilityOperation(outcome, acquired.release);
}
//#endregion
export { finishCapabilityOperation as n, withAcquiredPluginCapabilityProviders as r, acquirePluginCapabilityProviders as t };