De-hardcode orchestrator and interaction agent names (#748)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful

This commit was merged in pull request #748.
This commit is contained in:
2026-07-13 18:59:27 +00:00
parent 8dd4e9d541
commit 405984af5a
33 changed files with 579 additions and 304 deletions

View File

@@ -1,10 +1,10 @@
import { describe, expect, it, vi } from 'vitest';
import {
InMemoryMosCoordinationPort,
MosCoordinationClient,
InMemoryInteractionCoordinationPort,
InteractionCoordinationClient,
type CoordinationScope,
type MosCoordinationAuthorityError,
type MosCoordinationPort,
type InteractionCoordinationAuthorityError,
type InteractionCoordinationPort,
} from '../index.js';
const scope: CoordinationScope = {
@@ -15,19 +15,19 @@ const scope: CoordinationScope = {
};
function client(
port: MosCoordinationPort,
port: InteractionCoordinationPort,
handoffIdFactory: () => string = (): string => 'handoff-1',
): MosCoordinationClient {
return new MosCoordinationClient(
): InteractionCoordinationClient {
return new InteractionCoordinationClient(
{ interactionAgentId: 'Nova', orchestrationAgentId: 'Conductor' },
port,
handoffIdFactory,
);
}
describe('MosCoordinationClient', (): void => {
describe('InteractionCoordinationClient', (): void => {
it('round-trips handoff, observation, and result through the native port with identities as data', async (): Promise<void> => {
const adapter = new InMemoryMosCoordinationPort();
const adapter = new InMemoryInteractionCoordinationPort();
const coordination = client(adapter);
await expect(
@@ -42,8 +42,8 @@ describe('MosCoordinationClient', (): void => {
correlationId: 'corr-1',
});
adapter.recordActivity('handoff-1', 'running', 'Mos accepted the request');
adapter.recordResult('handoff-1', 'completed', 'Merged by Mos');
adapter.recordActivity('handoff-1', 'running', 'Orchestrator accepted the request');
adapter.recordResult('handoff-1', 'completed', 'Merged by orchestrator');
await expect(coordination.observe('handoff-1', scope)).resolves.toMatchObject({
status: 'completed',
@@ -59,7 +59,7 @@ describe('MosCoordinationClient', (): void => {
targetAgentId: 'Conductor',
status: 'completed',
correlationId: 'corr-1',
summary: 'Merged by Mos',
summary: 'Merged by orchestrator',
});
expect(coordination).not.toHaveProperty('dispatch');
@@ -69,8 +69,8 @@ describe('MosCoordinationClient', (): void => {
expect(coordination).not.toHaveProperty('cancel');
});
it('fails closed before delivery when an unconfigured agent requests Mos work', async (): Promise<void> => {
const adapter = new InMemoryMosCoordinationPort();
it('fails closed before delivery when an unconfigured agent requests orchestrator work', async (): Promise<void> => {
const adapter = new InMemoryInteractionCoordinationPort();
await expect(
client(adapter).handoff(
@@ -79,31 +79,31 @@ describe('MosCoordinationClient', (): void => {
),
).rejects.toMatchObject({
code: 'requester_forbidden',
} satisfies Partial<MosCoordinationAuthorityError>);
} satisfies Partial<InteractionCoordinationAuthorityError>);
});
it('rejects self-delegation configuration before constructing a client', (): void => {
expect(
(): MosCoordinationClient =>
new MosCoordinationClient(
(): InteractionCoordinationClient =>
new InteractionCoordinationClient(
{ interactionAgentId: 'Nova', orchestrationAgentId: 'Nova' },
new InMemoryMosCoordinationPort(),
new InMemoryInteractionCoordinationPort(),
),
).toThrow('Interaction and orchestration identities must differ');
});
it('rejects whitespace-equivalent self-delegation identities', (): void => {
expect(
(): MosCoordinationClient =>
new MosCoordinationClient(
(): InteractionCoordinationClient =>
new InteractionCoordinationClient(
{ interactionAgentId: 'Nova ', orchestrationAgentId: 'Nova' },
new InMemoryMosCoordinationPort(),
new InMemoryInteractionCoordinationPort(),
),
).toThrow('Interaction and orchestration identities must differ');
});
it('does not expose another tenant handoff to observe or result', async (): Promise<void> => {
const adapter = new InMemoryMosCoordinationPort();
const adapter = new InMemoryInteractionCoordinationPort();
const coordination = client(adapter);
await coordination.handoff(
{ idempotencyKey: 'handoff-request-1', summary: 'Implement the requested feature' },
@@ -120,7 +120,7 @@ describe('MosCoordinationClient', (): void => {
});
it('bounds native handoff retention by evicting the oldest handoff', async (): Promise<void> => {
const adapter = new InMemoryMosCoordinationPort({ maxHandoffs: 1 });
const adapter = new InMemoryInteractionCoordinationPort({ maxHandoffs: 1 });
const first = client(adapter, (): string => 'handoff-1');
const second = client(adapter, (): string => 'handoff-2');
await first.handoff({ idempotencyKey: 'handoff-request-1', summary: 'First request' }, scope);
@@ -131,7 +131,7 @@ describe('MosCoordinationClient', (): void => {
});
it('fails closed when a transport reports target drift', async (): Promise<void> => {
const adapter: MosCoordinationPort = {
const adapter: InteractionCoordinationPort = {
handoff: vi.fn(async () => ({
handoffId: 'handoff-1',
targetAgentId: 'Unexpected',
@@ -149,6 +149,6 @@ describe('MosCoordinationClient', (): void => {
),
).rejects.toMatchObject({
code: 'target_drift',
} satisfies Partial<MosCoordinationAuthorityError>);
} satisfies Partial<InteractionCoordinationAuthorityError>);
});
});