Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/JAVA/Openclaw/extensions/matrix/src/matrix/   (KI Agentensystem Version 22©)  Datei vom 26.3.2026 mit Größe 26 kB image not shown  

Quelle  subagent-hooks.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import type { OpenClawPluginApi as MatrixEntryPluginApi } from "openclaw/plugin-sdk/channel-entry-contract";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
  getRequiredHookHandler,
  registerHookHandlersForTest,
} from "../../../../test/helpers/plugins/subagent-hooks.js";
import { registerMatrixSubagentHooks } from "../../subagent-hooks-api.js";

// Hoisted stubs referenced in vi.mock factories below
const bindMock = vi.hoisted(() => vi.fn());
const unbindMock = vi.hoisted(() => vi.fn());
const getManagerMock = vi.hoisted(() => vi.fn());
const listAllBindingsMock = vi.hoisted(() => vi.fn((): any[] => []));
const listBindingsForAccountMock = vi.hoisted(() => vi.fn((): any[] => []));
const removeBindingRecordMock = vi.hoisted(() => vi.fn(() => false));
const resolveMatrixBaseConfigMock = vi.hoisted(() => vi.fn((): any => ({})));
const findMatrixAccountConfigMock = vi.hoisted(() => vi.fn((): any => undefined));

vi.mock("openclaw/plugin-sdk/conversation-binding-runtime", () => ({
  getSessionBindingService: () => ({ bind: bindMock, unbind: unbindMock }),
}));

vi.mock("./account-config.js", () => ({
  resolveMatrixBaseConfig: resolveMatrixBaseConfigMock,
  findMatrixAccountConfig: findMatrixAccountConfigMock,
}));

vi.mock("./thread-bindings-shared.js", () => ({
  getMatrixThreadBindingManager: getManagerMock,
  listAllBindings: listAllBindingsMock,
  listBindingsForAccount: listBindingsForAccountMock,
  removeBindingRecord: removeBindingRecordMock,
  resolveBindingKey: (params: {
    accountId: string;
    conversationId: string;
    parentConversationId?: string;
  }) =>
    `${params.accountId}:${params.parentConversationId?.trim() || "-"}:${params.conversationId}`,
}));

import {
  handleMatrixSubagentDeliveryTarget,
  handleMatrixSubagentEnded,
  handleMatrixSubagentSpawning,
} from "./subagent-hooks.js";

// A minimal fake api — only config is used by these hooks
const fakeApi = { config: {} } as never;

function registerHandlersForTest(config: Record<string, unknown> = {}) {
  return registerHookHandlersForTest<MatrixEntryPluginApi>({
    config,
    register: registerMatrixSubagentHooks,
  });
}

function makeSpawnEvent(
  overrides: Partial<{
    threadRequested: boolean;
    channel: string;
    accountId: string;
    to: string;
    childSessionKey: string;
    agentId: string;
    label: string;
  }> = {},
) {
  return {
    threadRequested: overrides.threadRequested ?? true,
    requester: {
      channel: overrides.channel ?? "matrix",
      accountId: overrides.accountId ?? "default",
      to: overrides.to ?? "room:!room123:example.org",
    },
    childSessionKey: overrides.childSessionKey ?? "agent:default:subagent:child",
    agentId: overrides.agentId ?? "worker",
    label: overrides.label,
  };
}

describe("handleMatrixSubagentSpawning", () => {
  beforeEach(() => {
    bindMock.mockReset();
    getManagerMock.mockReset();
    resolveMatrixBaseConfigMock.mockReset();
    findMatrixAccountConfigMock.mockReset();
    // Default: bindings enabled, spawn enabled
    resolveMatrixBaseConfigMock.mockReturnValue({
      threadBindings: { enabled: true, spawnSubagentSessions: true },
    });
    findMatrixAccountConfigMock.mockReturnValue(undefined);
    // Default: manager exists
    getManagerMock.mockReturnValue({ persist: vi.fn() });
    // Default: bind resolves ok
    bindMock.mockResolvedValue({
      conversation: {
        accountId: "default",
        conversationId: "$thread-root",
        parentConversationId: "!room123:example.org",
      },
    });
  });

  it("returns undefined when threadRequested is false", async () => {
    const result = await handleMatrixSubagentSpawning(
      fakeApi,
      makeSpawnEvent({ threadRequested: false }),
    );
    expect(result).toBeUndefined();
    expect(bindMock).not.toHaveBeenCalled();
  });

  it("returns undefined when channel is not matrix", async () => {
    const result = await handleMatrixSubagentSpawning(
      fakeApi,
      makeSpawnEvent({ channel: "slack" }),
    );
    expect(result).toBeUndefined();
    expect(bindMock).not.toHaveBeenCalled();
  });

  it("proceeds past channel check when channel is 'matrix' with mixed casing", async () => {
    // channel.trim().toLowerCase() must equal "matrix" — mixed case is accepted
    const result = await handleMatrixSubagentSpawning(
      fakeApi,
      makeSpawnEvent({ channel: " Matrix " }),
    );
    expect(result).not.toBeUndefined();
  });

  it("returns error when thread bindings are disabled", async () => {
    resolveMatrixBaseConfigMock.mockReturnValue({
      threadBindings: { enabled: false, spawnSubagentSessions: true },
    });
    const result = await handleMatrixSubagentSpawning(fakeApi, makeSpawnEvent());
    expect(result).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("thread bindings are disabled"),
      }),
    );
  });

  it("returns error when spawnSubagentSessions is false", async () => {
    resolveMatrixBaseConfigMock.mockReturnValue({
      threadBindings: { enabled: true, spawnSubagentSessions: false },
    });
    const result = await handleMatrixSubagentSpawning(fakeApi, makeSpawnEvent());
    expect(result).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("spawnSubagentSessions"),
      }),
    );
  });

  it("returns error when spawnSubagentSessions defaults to false (no config)", async () => {
    resolveMatrixBaseConfigMock.mockReturnValue({});
    const result = await handleMatrixSubagentSpawning(fakeApi, makeSpawnEvent());
    expect(result).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("spawnSubagentSessions"),
      }),
    );
  });

  it("returns error when requester.to has no room target", async () => {
    const result = await handleMatrixSubagentSpawning(
      fakeApi,
      makeSpawnEvent({ to: "@user:example.org" }),
    );
    expect(result).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("no room target"),
      }),
    );
  });

  it("returns error when requester.to is empty", async () => {
    const result = await handleMatrixSubagentSpawning(fakeApi, makeSpawnEvent({ to: "" }));
    expect(result).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("no room target"),
      }),
    );
  });

  it("returns error when no binding manager is available for the account", async () => {
    getManagerMock.mockReturnValue(null);
    const result = await handleMatrixSubagentSpawning(fakeApi, makeSpawnEvent());
    expect(result).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("No Matrix thread binding manager"),
      }),
    );
  });

  it("calls bind with the resolved room id and returns ok", async () => {
    bindMock.mockResolvedValue({
      conversation: {
        accountId: "ops",
        conversationId: "$thread-ops",
        parentConversationId: "!roomAbc:technerik.com",
      },
    });
    const result = await handleMatrixSubagentSpawning(
      fakeApi,
      makeSpawnEvent({
        accountId: "ops",
        to: "room:!roomAbc:technerik.com",
        childSessionKey: "agent:ops:subagent:worker",
        agentId: "builder",
        label: "Build Agent",
      }),
    );

    expect(bindMock).toHaveBeenCalledWith(
      expect.objectContaining({
        targetSessionKey: "agent:ops:subagent:worker",
        targetKind: "subagent",
        conversation: expect.objectContaining({
          channel: "matrix",
          accountId: "ops",
          conversationId: "!roomAbc:technerik.com",
        }),
        placement: "child",
        metadata: expect.objectContaining({
          agentId: "builder",
          label: "Build Agent",
        }),
      }),
    );
    expect(result).toMatchObject({
      status: "ok",
      threadBindingReady: true,
      deliveryOrigin: {
        channel: "matrix",
        accountId: "ops",
        to: "room:!roomAbc:technerik.com",
        threadId: "$thread-ops",
      },
    });
  });

  it("uses 'default' as accountId when requester.accountId is absent", async () => {
    bindMock.mockResolvedValue({
      conversation: {
        accountId: "default",
        conversationId: "$thread-default",
        parentConversationId: "!room123:example.org",
      },
    });
    await handleMatrixSubagentSpawning(fakeApi, makeSpawnEvent({ accountId: undefined as never }));
    expect(getManagerMock).toHaveBeenCalledWith("default");
    expect(bindMock).toHaveBeenCalledWith(
      expect.objectContaining({
        conversation: expect.objectContaining({ accountId: "default" }),
      }),
    );
  });

  it("returns error when bind() throws", async () => {
    bindMock.mockRejectedValue(new Error("provider auth failed"));
    const result = await handleMatrixSubagentSpawning(fakeApi, makeSpawnEvent());
    expect(result).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("provider auth failed"),
      }),
    );
  });

  it("respects per-account threadBindings override over base config", async () => {
    // Base says spawnSubagentSessions=false; account override says true
    resolveMatrixBaseConfigMock.mockReturnValue({
      threadBindings: { enabled: true, spawnSubagentSessions: false },
    });
    findMatrixAccountConfigMock.mockReturnValue({
      threadBindings: { spawnSubagentSessions: true },
    });
    bindMock.mockResolvedValue({ conversation: {} });

    const result = await handleMatrixSubagentSpawning(
      fakeApi,
      makeSpawnEvent({ accountId: "forge" }),
    );
    expect(result).toMatchObject({ status: "ok", threadBindingReady: true });
  });
});

describe("matrix subagent hook registration", () => {
  beforeEach(() => {
    bindMock.mockReset();
    getManagerMock.mockReset();
    resolveMatrixBaseConfigMock.mockReset();
    findMatrixAccountConfigMock.mockReset();
    listBindingsForAccountMock.mockReset();
    listAllBindingsMock.mockReset();
    resolveMatrixBaseConfigMock.mockReturnValue({
      threadBindings: { enabled: true, spawnSubagentSessions: true },
    });
    findMatrixAccountConfigMock.mockReturnValue(undefined);
    getManagerMock.mockReturnValue({ persist: vi.fn() });
    bindMock.mockResolvedValue({
      conversation: {
        accountId: "default",
        conversationId: "$thread-root",
        parentConversationId: "!room123:example.org",
      },
    });
  });

  it("binds thread routing through the lazy registration barrel", async () => {
    const handlers = registerHandlersForTest();
    const handler = getRequiredHookHandler(handlers, "subagent_spawning");

    const result = await handler(makeSpawnEvent(), {});

    expect(bindMock).toHaveBeenCalledTimes(1);
    expect(result).toMatchObject({
      status: "ok",
      threadBindingReady: true,
      deliveryOrigin: {
        channel: "matrix",
        accountId: "default",
        to: "room:!room123:example.org",
        threadId: "$thread-root",
      },
    });
  });

  it("resolves delivery targets through the lazy registration barrel", async () => {
    listBindingsForAccountMock.mockReturnValue([
      {
        accountId: "ops",
        conversationId: "$thread-ops",
        parentConversationId: "!roomAbc:technerik.com",
        targetSessionKey: "agent:ops:subagent:worker",
        targetKind: "subagent",
      },
    ]);
    const handlers = registerHandlersForTest();
    const handler = getRequiredHookHandler(handlers, "subagent_delivery_target");

    await expect(
      handler(
        {
          childSessionKey: "agent:ops:subagent:worker",
          requesterOrigin: {
            channel: "matrix",
            accountId: "ops",
            to: "room:!roomAbc:technerik.com",
            threadId: "$thread-ops",
          },
          expectsCompletionMessage: true,
        },
        {},
      ),
    ).resolves.toEqual({
      origin: {
        channel: "matrix",
        accountId: "ops",
        to: "room:!roomAbc:technerik.com",
        threadId: "$thread-ops",
      },
    });
  });
});

describe("handleMatrixSubagentEnded", () => {
  const mockManager = { persist: vi.fn() };

  beforeEach(() => {
    getManagerMock.mockReset();
    listAllBindingsMock.mockReset();
    listBindingsForAccountMock.mockReset();
    removeBindingRecordMock.mockReset();
    unbindMock.mockReset();
    mockManager.persist.mockReset();
  });

  it("does nothing when no matching bindings exist", async () => {
    listBindingsForAccountMock.mockReturnValue([]);
    await handleMatrixSubagentEnded({
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
    });
    expect(getManagerMock).not.toHaveBeenCalled();
  });

  it("removes matching bindings and calls persist on the manager", async () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "$thread",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listBindingsForAccountMock.mockReturnValue([binding]);
    removeBindingRecordMock.mockReturnValue(true);
    getManagerMock.mockReturnValue(mockManager);
    mockManager.persist.mockResolvedValue(undefined);

    await handleMatrixSubagentEnded({
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
    });

    expect(removeBindingRecordMock).toHaveBeenCalledWith(binding);
    expect(getManagerMock).toHaveBeenCalledWith("ops");
    expect(mockManager.persist).toHaveBeenCalled();
  });

  it("sends farewell through the binding service when requested", async () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "$thread",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listBindingsForAccountMock.mockReturnValue([binding]);
    unbindMock.mockResolvedValue([
      {
        bindingId: "ops:!room:example:$thread",
        targetSessionKey: "agent:ops:subagent:child",
        targetKind: "subagent",
        conversation: {
          channel: "matrix",
          accountId: "ops",
          conversationId: "$thread",
          parentConversationId: "!room:example",
        },
        status: "active",
        boundAt: 0,
      },
    ]);

    await handleMatrixSubagentEnded({
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      reason: "spawn-failed",
      sendFarewell: true,
    });

    expect(unbindMock).toHaveBeenCalledWith({
      bindingId: "ops:!room:example:$thread",
      reason: "spawn-failed",
    });
    expect(removeBindingRecordMock).not.toHaveBeenCalled();
    expect(getManagerMock).not.toHaveBeenCalled();
  });

  it("skips persist when removeBindingRecord returns false (binding not found in store)", async () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:orphan",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "$thread",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listBindingsForAccountMock.mockReturnValue([binding]);
    removeBindingRecordMock.mockReturnValue(false);

    await handleMatrixSubagentEnded({
      targetSessionKey: "agent:ops:subagent:orphan",
      targetKind: "subagent",
      accountId: "ops",
    });

    expect(getManagerMock).not.toHaveBeenCalled();
  });

  it("falls back to listAllBindings when accountId is absent", async () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "$thread",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listAllBindingsMock.mockReturnValue([binding]);
    removeBindingRecordMock.mockReturnValue(true);
    getManagerMock.mockReturnValue(mockManager);
    mockManager.persist.mockResolvedValue(undefined);

    await handleMatrixSubagentEnded({
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
    });

    expect(listAllBindingsMock).toHaveBeenCalled();
    expect(listBindingsForAccountMock).not.toHaveBeenCalled();
    expect(mockManager.persist).toHaveBeenCalled();
  });

  it("does not double-persist when multiple bindings share the same account", async () => {
    const mkBinding = (conversationId: string) => ({
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId,
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    });
    listBindingsForAccountMock.mockReturnValue([mkBinding("$t1"), mkBinding("$t2")]);
    removeBindingRecordMock.mockReturnValue(true);
    getManagerMock.mockReturnValue(mockManager);
    mockManager.persist.mockResolvedValue(undefined);

    await handleMatrixSubagentEnded({
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
    });

    // persist must be called exactly once per unique accountId, not once per binding
    expect(mockManager.persist).toHaveBeenCalledTimes(1);
  });
});

describe("handleMatrixSubagentDeliveryTarget", () => {
  beforeEach(() => {
    listAllBindingsMock.mockReset();
    listBindingsForAccountMock.mockReset();
  });

  it("returns undefined when expectsCompletionMessage is false", () => {
    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix", accountId: "ops" },
      expectsCompletionMessage: false,
    });
    expect(result).toBeUndefined();
  });

  it("returns undefined when requester channel is not matrix", () => {
    listBindingsForAccountMock.mockReturnValue([]);
    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "slack", accountId: "ops" },
      expectsCompletionMessage: true,
    });
    expect(result).toBeUndefined();
  });

  it("returns undefined when no bindings match the child session key", () => {
    listBindingsForAccountMock.mockReturnValue([
      {
        targetSessionKey: "agent:ops:subagent:OTHER",
        targetKind: "subagent",
        accountId: "ops",
        conversationId: "$thread",
        parentConversationId: "!room:example",
        boundAt: 0,
        lastActivityAt: 0,
      },
    ]);
    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix", accountId: "ops" },
      expectsCompletionMessage: true,
    });
    expect(result).toBeUndefined();
  });

  it("returns origin with threadId when binding has a distinct parentConversationId", () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "$thread123",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listBindingsForAccountMock.mockReturnValue([binding]);

    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix", accountId: "ops", threadId: "$thread123" },
      expectsCompletionMessage: true,
    });

    expect(result).toEqual({
      origin: {
        channel: "matrix",
        accountId: "ops",
        to: "room:!room:example",
        threadId: "$thread123",
      },
    });
  });

  it("returns origin without threadId when conversationId equals parentConversationId", () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "!room:example",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listBindingsForAccountMock.mockReturnValue([binding]);

    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix", accountId: "ops" },
      expectsCompletionMessage: true,
    });

    expect(result).toEqual({
      origin: {
        channel: "matrix",
        accountId: "ops",
        to: "room:!room:example",
      },
    });
    expect(result?.origin).not.toHaveProperty("threadId");
  });

  it("returns origin without threadId when binding has no parentConversationId", () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listBindingsForAccountMock.mockReturnValue([binding]);

    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix", accountId: "ops" },
      expectsCompletionMessage: true,
    });

    expect(result).toEqual({
      origin: {
        channel: "matrix",
        accountId: "ops",
        to: "room:!room:example",
      },
    });
  });

  it("falls back to the single binding when requesterOrigin threadId does not match any binding", () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "$thread123",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listBindingsForAccountMock.mockReturnValue([binding]);

    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix", accountId: "ops", threadId: "$threadOTHER" },
      expectsCompletionMessage: true,
    });

    // No threadId match, but single binding → falls back to it
    expect(result).toEqual({
      origin: {
        channel: "matrix",
        accountId: "ops",
        to: "room:!room:example",
        threadId: "$thread123",
      },
    });
  });

  it("returns undefined when multiple bindings exist and threadId matches none", () => {
    const mkBinding = (threadId: string) => ({
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: threadId,
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    });
    listBindingsForAccountMock.mockReturnValue([mkBinding("$t1"), mkBinding("$t2")]);

    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix", accountId: "ops", threadId: "$tNONE" },
      expectsCompletionMessage: true,
    });

    expect(result).toBeUndefined();
  });

  it("uses listAllBindings when requesterOrigin has no accountId", () => {
    const binding = {
      targetSessionKey: "agent:ops:subagent:child",
      targetKind: "subagent",
      accountId: "ops",
      conversationId: "$thread123",
      parentConversationId: "!room:example",
      boundAt: 0,
      lastActivityAt: 0,
    };
    listAllBindingsMock.mockReturnValue([binding]);

    const result = handleMatrixSubagentDeliveryTarget({
      childSessionKey: "agent:ops:subagent:child",
      requesterOrigin: { channel: "matrix" },
      expectsCompletionMessage: true,
    });

    expect(listAllBindingsMock).toHaveBeenCalled();
    expect(listBindingsForAccountMock).not.toHaveBeenCalled();
    expect(result).toBeDefined();
  });
});

describe("concurrent spawns across accounts", () => {
  function spawnForAccount(accountId: "ops" | "forge") {
    return handleMatrixSubagentSpawning(fakeApi, {
      threadRequested: true,
      requester: {
        channel: "matrix",
        accountId,
        to: `room:!room-${accountId}:example.org`,
      },
      childSessionKey: `agent:${accountId}:subagent:child-${accountId}`,
      agentId: `worker-${accountId}`,
    });
  }

  beforeEach(() => {
    bindMock.mockReset();
    getManagerMock.mockReset();
    resolveMatrixBaseConfigMock.mockReset();
    findMatrixAccountConfigMock.mockReset();
    resolveMatrixBaseConfigMock.mockReturnValue({
      threadBindings: { enabled: true, spawnSubagentSessions: true },
    });
    findMatrixAccountConfigMock.mockReturnValue(undefined);
    getManagerMock.mockReturnValue({ persist: vi.fn() });
  });

  it("resolves both spawns independently when two accounts fire simultaneously", async () => {
    // Each account gets its own bind call that resolves with a distinct conversation
    bindMock
      .mockResolvedValueOnce({ conversation: { accountId: "ops", conversationId: "$t-ops" } })
      .mockResolvedValueOnce({ conversation: { accountId: "forge", conversationId: "$t-forge" } });

    const [opsResult, forgeResult] = await Promise.all([
      spawnForAccount("ops"),
      spawnForAccount("forge"),
    ]);

    expect(opsResult).toMatchObject({ status: "ok", threadBindingReady: true });
    expect(forgeResult).toMatchObject({ status: "ok", threadBindingReady: true });
    expect(bindMock).toHaveBeenCalledTimes(2);

    // Each bind call targeted the correct account's room
    expect(bindMock).toHaveBeenCalledWith(
      expect.objectContaining({
        targetSessionKey: "agent:ops:subagent:child-ops",
        conversation: expect.objectContaining({
          accountId: "ops",
          conversationId: "!room-ops:example.org",
        }),
      }),
    );
    expect(bindMock).toHaveBeenCalledWith(
      expect.objectContaining({
        targetSessionKey: "agent:forge:subagent:child-forge",
        conversation: expect.objectContaining({
          accountId: "forge",
          conversationId: "!room-forge:example.org",
        }),
      }),
    );
  });

  it("one account bind failure does not affect the other account's spawn", async () => {
    bindMock
      .mockRejectedValueOnce(new Error("ops provider auth failed"))
      .mockResolvedValueOnce({ conversation: { accountId: "forge", conversationId: "$t-forge" } });

    const [opsResult, forgeResult] = await Promise.all([
      spawnForAccount("ops"),
      spawnForAccount("forge"),
    ]);

    expect(opsResult).toEqual(
      expect.objectContaining({
        status: "error",
        error: expect.stringContaining("ops provider auth failed"),
      }),
    );
    expect(forgeResult).toMatchObject({ status: "ok", threadBindingReady: true });
  });
});

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.