
























@@ -40,7 +40,11 @@ import {
4040import { buildPluginAgentTurnPrepareContext, isPluginJsonValue } from "../host-hooks.js";
4141import { createEmptyPluginRegistry } from "../registry-empty.js";
4242import { createPluginRegistry } from "../registry.js";
43-import { setActivePluginRegistry } from "../runtime.js";
43+import {
44+pinActivePluginSessionExtensionRegistry,
45+releasePinnedPluginSessionExtensionRegistry,
46+setActivePluginRegistry,
47+} from "../runtime.js";
4448import type { PluginRuntime } from "../runtime/types.js";
4549import { createPluginRecord } from "../status.test-helpers.js";
4650import { runTrustedToolPolicies } from "../trusted-tool-policy.js";
@@ -120,6 +124,7 @@ async function withHostHookState(
120124121125describe("host-hook fixture plugin contract", () => {
122126afterEach(() => {
127+releasePinnedPluginSessionExtensionRegistry();
123128setActivePluginRegistry(createEmptyPluginRegistry());
124129clearPluginHostRuntimeState();
125130resetAgentEventsForTest();
@@ -1558,6 +1563,69 @@ describe("host-hook fixture plugin contract", () => {
15581563});
15591564});
156015651566+it("patches and projects pinned session extensions after active registry churn", async () => {
1567+const { config, registry } = createPluginRegistryFixture();
1568+registerTestPlugin({
1569+ registry,
1570+ config,
1571+record: createPluginRecord({
1572+id: "session-pin-fixture",
1573+name: "Session Pin Fixture",
1574+}),
1575+register(api) {
1576+api.registerSessionExtension({
1577+namespace: "workflow",
1578+description: "Pinned workflow state",
1579+});
1580+},
1581+});
1582+setActivePluginRegistry(registry.registry);
1583+pinActivePluginSessionExtensionRegistry(registry.registry);
1584+setActivePluginRegistry(createEmptyPluginRegistry());
1585+1586+await withHostHookState(
1587+"openclaw-host-hooks-session-pin-",
1588+async ({ storePath, tempConfig }) => {
1589+await updateSessionStore(storePath, (store) => {
1590+store["agent:main:main"] = {
1591+sessionId: "session-1",
1592+updatedAt: Date.now(),
1593+};
1594+return undefined;
1595+});
1596+1597+await expect(
1598+patchPluginSessionExtension({
1599+cfg: tempConfig,
1600+sessionKey: "agent:main:main",
1601+pluginId: "session-pin-fixture",
1602+namespace: "workflow",
1603+value: { state: "approved" },
1604+}),
1605+).resolves.toEqual({
1606+ok: true,
1607+key: "agent:main:main",
1608+value: { state: "approved" },
1609+});
1610+1611+const entry = loadSessionStore(storePath)["agent:main:main"];
1612+expect(entry).toBeDefined();
1613+expect(
1614+projectPluginSessionExtensionsSync({
1615+sessionKey: "agent:main:main",
1616+entry: entry!,
1617+}),
1618+).toEqual([
1619+{
1620+pluginId: "session-pin-fixture",
1621+namespace: "workflow",
1622+value: { state: "approved" },
1623+},
1624+]);
1625+},
1626+);
1627+});
1628+15611629it("models queued next-turn injections and agent_turn_prepare as one prompt context", async () => {
15621630const { config, registry } = createPluginRegistryFixture();
15631631registerTestPlugin({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。