refactor(#747): de-hardcode interaction coordination names
This commit is contained in:
@@ -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>);
|
||||
});
|
||||
});
|
||||
@@ -2,25 +2,25 @@ import {
|
||||
type CoordinationObservation,
|
||||
type CoordinationResult,
|
||||
type CoordinationScope,
|
||||
type MosCoordinationActivity,
|
||||
type MosCoordinationPort,
|
||||
type MosHandoff,
|
||||
type MosHandoffReceipt,
|
||||
type MosHandoffStatus,
|
||||
} from './mos-coordination.js';
|
||||
type InteractionCoordinationActivity,
|
||||
type InteractionCoordinationPort,
|
||||
type Handoff,
|
||||
type HandoffReceipt,
|
||||
type HandoffStatus,
|
||||
} from './interaction-coordination.js';
|
||||
|
||||
const DEFAULT_HANDOFF_TTL_MS = 60 * 60 * 1_000;
|
||||
const DEFAULT_MAX_HANDOFFS = 1_000;
|
||||
|
||||
interface StoredHandoff {
|
||||
readonly handoff: MosHandoff;
|
||||
status: MosHandoffStatus;
|
||||
readonly activity: MosCoordinationActivity[];
|
||||
readonly handoff: Handoff;
|
||||
status: HandoffStatus;
|
||||
readonly activity: InteractionCoordinationActivity[];
|
||||
readonly expiresAt: number;
|
||||
result?: CoordinationResult;
|
||||
}
|
||||
|
||||
export interface InMemoryMosCoordinationPortOptions {
|
||||
export interface InMemoryInteractionCoordinationPortOptions {
|
||||
now?: () => Date;
|
||||
handoffTtlMs?: number;
|
||||
maxHandoffs?: number;
|
||||
@@ -29,21 +29,21 @@ export interface InMemoryMosCoordinationPortOptions {
|
||||
/**
|
||||
* Native deterministic queue/port adapter for the coordination boundary.
|
||||
* It intentionally has no fleet/tmux dependency. A future deployment adapter
|
||||
* implements MosCoordinationPort without changing interaction-plane callers.
|
||||
* implements InteractionCoordinationPort without changing interaction-plane callers.
|
||||
*/
|
||||
export class InMemoryMosCoordinationPort implements MosCoordinationPort {
|
||||
export class InMemoryInteractionCoordinationPort implements InteractionCoordinationPort {
|
||||
private readonly handoffs = new Map<string, StoredHandoff>();
|
||||
private readonly now: () => Date;
|
||||
private readonly handoffTtlMs: number;
|
||||
private readonly maxHandoffs: number;
|
||||
|
||||
constructor(options: InMemoryMosCoordinationPortOptions = {}) {
|
||||
constructor(options: InMemoryInteractionCoordinationPortOptions = {}) {
|
||||
this.now = options.now ?? (() => new Date());
|
||||
this.handoffTtlMs = options.handoffTtlMs ?? DEFAULT_HANDOFF_TTL_MS;
|
||||
this.maxHandoffs = options.maxHandoffs ?? DEFAULT_MAX_HANDOFFS;
|
||||
}
|
||||
|
||||
async handoff(handoff: MosHandoff): Promise<MosHandoffReceipt> {
|
||||
async handoff(handoff: Handoff): Promise<HandoffReceipt> {
|
||||
this.pruneExpiredHandoffs();
|
||||
const existing = this.handoffs.get(handoff.handoffId);
|
||||
if (existing !== undefined) {
|
||||
@@ -88,14 +88,14 @@ export class InMemoryMosCoordinationPort implements MosCoordinationPort {
|
||||
}
|
||||
|
||||
/** Host-side progression seam; interaction clients never receive this capability. */
|
||||
recordActivity(handoffId: string, status: MosHandoffStatus, summary: string): void {
|
||||
recordActivity(handoffId: string, status: HandoffStatus, summary: string): void {
|
||||
this.pruneExpiredHandoffs();
|
||||
const stored = this.requireHandoff(handoffId);
|
||||
stored.status = status;
|
||||
stored.activity.push(activity(status, summary, this.now));
|
||||
}
|
||||
|
||||
/** Host-side result seam for deterministic qualification; not a Mos consumer. */
|
||||
/** Host-side result seam for deterministic qualification; not an orchestrator consumer. */
|
||||
recordResult(handoffId: string, status: 'completed' | 'failed', summary: string): void {
|
||||
this.pruneExpiredHandoffs();
|
||||
const stored = this.requireHandoff(handoffId);
|
||||
@@ -110,7 +110,7 @@ export class InMemoryMosCoordinationPort implements MosCoordinationPort {
|
||||
};
|
||||
}
|
||||
|
||||
private receipt(handoff: MosHandoff, status: MosHandoffStatus): MosHandoffReceipt {
|
||||
private receipt(handoff: Handoff, status: HandoffStatus): HandoffReceipt {
|
||||
return {
|
||||
handoffId: handoff.handoffId,
|
||||
targetAgentId: handoff.targetAgentId,
|
||||
@@ -141,7 +141,7 @@ export class InMemoryMosCoordinationPort implements MosCoordinationPort {
|
||||
stored.handoff.scope.actorId !== scope.actorId ||
|
||||
stored.handoff.scope.requesterAgentId !== scope.requesterAgentId
|
||||
) {
|
||||
throw new InMemoryMosCoordinationError('forbidden', 'Handoff scope does not match');
|
||||
throw new InMemoryInteractionCoordinationError('forbidden', 'Handoff scope does not match');
|
||||
}
|
||||
return stored;
|
||||
}
|
||||
@@ -149,12 +149,12 @@ export class InMemoryMosCoordinationPort implements MosCoordinationPort {
|
||||
private requireHandoff(handoffId: string): StoredHandoff {
|
||||
const stored = this.handoffs.get(handoffId);
|
||||
if (stored === undefined) {
|
||||
throw new InMemoryMosCoordinationError('not_found', 'Handoff was not found');
|
||||
throw new InMemoryInteractionCoordinationError('not_found', 'Handoff was not found');
|
||||
}
|
||||
return stored;
|
||||
}
|
||||
|
||||
private assertSameHandoff(existing: MosHandoff, incoming: MosHandoff): void {
|
||||
private assertSameHandoff(existing: Handoff, incoming: Handoff): void {
|
||||
if (
|
||||
existing.targetAgentId !== incoming.targetAgentId ||
|
||||
existing.request.idempotencyKey !== incoming.request.idempotencyKey ||
|
||||
@@ -166,7 +166,7 @@ export class InMemoryMosCoordinationPort implements MosCoordinationPort {
|
||||
existing.scope.correlationId !== incoming.scope.correlationId ||
|
||||
existing.scope.requesterAgentId !== incoming.scope.requesterAgentId
|
||||
) {
|
||||
throw new InMemoryMosCoordinationError(
|
||||
throw new InMemoryInteractionCoordinationError(
|
||||
'conflict',
|
||||
'Handoff ID is already bound to different immutable input',
|
||||
);
|
||||
@@ -174,31 +174,31 @@ export class InMemoryMosCoordinationPort implements MosCoordinationPort {
|
||||
}
|
||||
}
|
||||
|
||||
export type InMemoryMosCoordinationErrorCode = 'conflict' | 'forbidden' | 'not_found';
|
||||
export type InMemoryInteractionCoordinationErrorCode = 'conflict' | 'forbidden' | 'not_found';
|
||||
|
||||
export class InMemoryMosCoordinationError extends Error {
|
||||
export class InMemoryInteractionCoordinationError extends Error {
|
||||
constructor(
|
||||
readonly code: InMemoryMosCoordinationErrorCode,
|
||||
readonly code: InMemoryInteractionCoordinationErrorCode,
|
||||
message: string,
|
||||
) {
|
||||
super(message);
|
||||
this.name = InMemoryMosCoordinationError.name;
|
||||
this.name = InMemoryInteractionCoordinationError.name;
|
||||
}
|
||||
}
|
||||
|
||||
function activity(
|
||||
status: MosHandoffStatus,
|
||||
status: HandoffStatus,
|
||||
summary: string,
|
||||
now: () => Date,
|
||||
): MosCoordinationActivity {
|
||||
): InteractionCoordinationActivity {
|
||||
return { occurredAt: now().toISOString(), status, summary };
|
||||
}
|
||||
|
||||
function copyActivity(entry: MosCoordinationActivity): MosCoordinationActivity {
|
||||
function copyActivity(entry: InteractionCoordinationActivity): InteractionCoordinationActivity {
|
||||
return { ...entry };
|
||||
}
|
||||
|
||||
function snapshotHandoff(handoff: MosHandoff): MosHandoff {
|
||||
function snapshotHandoff(handoff: Handoff): Handoff {
|
||||
return Object.freeze({
|
||||
handoffId: handoff.handoffId,
|
||||
targetAgentId: handoff.targetAgentId,
|
||||
@@ -3,22 +3,25 @@ export { parseTasksFile, updateTaskStatus, writeTasksFile } from './tasks-file.j
|
||||
export { runTask, resumeTask } from './runner.js';
|
||||
export { getMissionStatus, getTaskStatus } from './status.js';
|
||||
export {
|
||||
InMemoryMosCoordinationError,
|
||||
InMemoryMosCoordinationPort,
|
||||
} from './in-memory-mos-coordination-port.js';
|
||||
export { MosCoordinationAuthorityError, MosCoordinationClient } from './mos-coordination.js';
|
||||
InMemoryInteractionCoordinationError,
|
||||
InMemoryInteractionCoordinationPort,
|
||||
} from './in-memory-interaction-coordination-port.js';
|
||||
export {
|
||||
InteractionCoordinationAuthorityError,
|
||||
InteractionCoordinationClient,
|
||||
} from './interaction-coordination.js';
|
||||
export type {
|
||||
CoordinationObservation,
|
||||
CoordinationResult,
|
||||
CoordinationScope,
|
||||
MosCoordinationActivity,
|
||||
MosCoordinationIdentity,
|
||||
MosCoordinationPort,
|
||||
MosHandoff,
|
||||
MosHandoffReceipt,
|
||||
MosHandoffRequest,
|
||||
MosHandoffStatus,
|
||||
} from './mos-coordination.js';
|
||||
InteractionCoordinationActivity,
|
||||
InteractionCoordinationIdentity,
|
||||
InteractionCoordinationPort,
|
||||
Handoff,
|
||||
HandoffReceipt,
|
||||
HandoffRequest,
|
||||
HandoffStatus,
|
||||
} from './interaction-coordination.js';
|
||||
export type {
|
||||
CreateMissionOptions,
|
||||
Mission,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type MosHandoffStatus = 'queued' | 'accepted' | 'running' | 'completed' | 'failed';
|
||||
export type HandoffStatus = 'queued' | 'accepted' | 'running' | 'completed' | 'failed';
|
||||
|
||||
export interface CoordinationScope {
|
||||
readonly actorId: string;
|
||||
@@ -8,44 +8,44 @@ export interface CoordinationScope {
|
||||
readonly requesterAgentId: string;
|
||||
}
|
||||
|
||||
export interface MosCoordinationIdentity {
|
||||
export interface InteractionCoordinationIdentity {
|
||||
readonly interactionAgentId: string;
|
||||
readonly orchestrationAgentId: string;
|
||||
}
|
||||
|
||||
export interface MosHandoffRequest {
|
||||
export interface HandoffRequest {
|
||||
readonly idempotencyKey: string;
|
||||
readonly summary: string;
|
||||
readonly context?: string;
|
||||
readonly missionId?: string;
|
||||
}
|
||||
|
||||
export interface MosHandoff {
|
||||
export interface Handoff {
|
||||
readonly handoffId: string;
|
||||
readonly targetAgentId: string;
|
||||
readonly request: MosHandoffRequest;
|
||||
readonly request: HandoffRequest;
|
||||
readonly scope: CoordinationScope;
|
||||
}
|
||||
|
||||
export interface MosHandoffReceipt {
|
||||
export interface HandoffReceipt {
|
||||
readonly handoffId: string;
|
||||
readonly targetAgentId: string;
|
||||
readonly status: 'queued' | 'accepted';
|
||||
readonly correlationId: string;
|
||||
}
|
||||
|
||||
export interface MosCoordinationActivity {
|
||||
export interface InteractionCoordinationActivity {
|
||||
readonly occurredAt: string;
|
||||
readonly status: MosHandoffStatus;
|
||||
readonly status: HandoffStatus;
|
||||
readonly summary: string;
|
||||
}
|
||||
|
||||
export interface CoordinationObservation {
|
||||
readonly handoffId: string;
|
||||
readonly targetAgentId: string;
|
||||
readonly status: MosHandoffStatus;
|
||||
readonly status: HandoffStatus;
|
||||
readonly correlationId: string;
|
||||
readonly activity: readonly MosCoordinationActivity[];
|
||||
readonly activity: readonly InteractionCoordinationActivity[];
|
||||
}
|
||||
|
||||
export interface CoordinationResult {
|
||||
@@ -61,25 +61,25 @@ export interface CoordinationResult {
|
||||
* its progress/result, but it cannot issue worker, review, merge, or other
|
||||
* general orchestration commands.
|
||||
*/
|
||||
export interface MosCoordinationPort {
|
||||
handoff(handoff: MosHandoff): Promise<MosHandoffReceipt>;
|
||||
export interface InteractionCoordinationPort {
|
||||
handoff(handoff: Handoff): Promise<HandoffReceipt>;
|
||||
observe(handoffId: string, scope: CoordinationScope): Promise<CoordinationObservation>;
|
||||
result(handoffId: string, scope: CoordinationScope): Promise<CoordinationResult>;
|
||||
}
|
||||
|
||||
export type MosCoordinationAuthorityErrorCode =
|
||||
export type InteractionCoordinationAuthorityErrorCode =
|
||||
| 'invalid_identity'
|
||||
| 'requester_forbidden'
|
||||
| 'target_drift'
|
||||
| 'correlation_drift';
|
||||
|
||||
export class MosCoordinationAuthorityError extends Error {
|
||||
export class InteractionCoordinationAuthorityError extends Error {
|
||||
constructor(
|
||||
readonly code: MosCoordinationAuthorityErrorCode,
|
||||
readonly code: InteractionCoordinationAuthorityErrorCode,
|
||||
message: string,
|
||||
) {
|
||||
super(message);
|
||||
this.name = MosCoordinationAuthorityError.name;
|
||||
this.name = InteractionCoordinationAuthorityError.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,20 +87,20 @@ export class MosCoordinationAuthorityError extends Error {
|
||||
* Enforces the interaction-to-orchestration authority boundary before a
|
||||
* transport is reached. Identity names remain configuration data.
|
||||
*/
|
||||
export class MosCoordinationClient {
|
||||
private readonly identity: MosCoordinationIdentity;
|
||||
export class InteractionCoordinationClient {
|
||||
private readonly identity: InteractionCoordinationIdentity;
|
||||
|
||||
constructor(
|
||||
identity: MosCoordinationIdentity,
|
||||
private readonly port: MosCoordinationPort,
|
||||
identity: InteractionCoordinationIdentity,
|
||||
private readonly port: InteractionCoordinationPort,
|
||||
private readonly handoffIdFactory: () => string = (): string => crypto.randomUUID(),
|
||||
) {
|
||||
this.identity = normalizeIdentity(identity);
|
||||
}
|
||||
|
||||
async handoff(request: MosHandoffRequest, scope: CoordinationScope): Promise<MosHandoffReceipt> {
|
||||
async handoff(request: HandoffRequest, scope: CoordinationScope): Promise<HandoffReceipt> {
|
||||
this.assertRequester(scope);
|
||||
const handoff: MosHandoff = {
|
||||
const handoff: Handoff = {
|
||||
handoffId: this.handoffIdFactory(),
|
||||
targetAgentId: this.identity.orchestrationAgentId,
|
||||
request: snapshotRequest(request),
|
||||
@@ -111,15 +111,15 @@ export class MosCoordinationClient {
|
||||
receipt.handoffId !== handoff.handoffId ||
|
||||
receipt.targetAgentId !== handoff.targetAgentId
|
||||
) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'target_drift',
|
||||
'Mos coordination transport returned a mismatched handoff target',
|
||||
'Interaction coordination transport returned a mismatched handoff target',
|
||||
);
|
||||
}
|
||||
if (receipt.correlationId !== handoff.scope.correlationId) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'correlation_drift',
|
||||
'Mos coordination transport returned a mismatched correlation ID',
|
||||
'Interaction coordination transport returned a mismatched correlation ID',
|
||||
);
|
||||
}
|
||||
return receipt;
|
||||
@@ -137,7 +137,7 @@ export class MosCoordinationClient {
|
||||
|
||||
private assertRequester(scope: CoordinationScope): void {
|
||||
if (scope.requesterAgentId !== this.identity.interactionAgentId) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'requester_forbidden',
|
||||
'Requester is not the configured interaction agent',
|
||||
);
|
||||
@@ -149,15 +149,15 @@ export class MosCoordinationClient {
|
||||
scope: CoordinationScope,
|
||||
): CoordinationObservation {
|
||||
if (observation.targetAgentId !== this.identity.orchestrationAgentId) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'target_drift',
|
||||
'Mos coordination transport returned an unexpected observation target',
|
||||
'Interaction coordination transport returned an unexpected observation target',
|
||||
);
|
||||
}
|
||||
if (observation.correlationId !== scope.correlationId) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'correlation_drift',
|
||||
'Mos coordination transport returned a mismatched observation correlation ID',
|
||||
'Interaction coordination transport returned a mismatched observation correlation ID',
|
||||
);
|
||||
}
|
||||
return observation;
|
||||
@@ -165,32 +165,34 @@ export class MosCoordinationClient {
|
||||
|
||||
private assertResult(result: CoordinationResult, scope: CoordinationScope): CoordinationResult {
|
||||
if (result.targetAgentId !== this.identity.orchestrationAgentId) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'target_drift',
|
||||
'Mos coordination transport returned an unexpected result target',
|
||||
'Interaction coordination transport returned an unexpected result target',
|
||||
);
|
||||
}
|
||||
if (result.correlationId !== scope.correlationId) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'correlation_drift',
|
||||
'Mos coordination transport returned a mismatched result correlation ID',
|
||||
'Interaction coordination transport returned a mismatched result correlation ID',
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeIdentity(identity: MosCoordinationIdentity): MosCoordinationIdentity {
|
||||
function normalizeIdentity(
|
||||
identity: InteractionCoordinationIdentity,
|
||||
): InteractionCoordinationIdentity {
|
||||
const interactionAgentId = identity.interactionAgentId.trim();
|
||||
const orchestrationAgentId = identity.orchestrationAgentId.trim();
|
||||
if (interactionAgentId.length === 0 || orchestrationAgentId.length === 0) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'invalid_identity',
|
||||
'Interaction and orchestration identities are required',
|
||||
);
|
||||
}
|
||||
if (interactionAgentId === orchestrationAgentId) {
|
||||
throw new MosCoordinationAuthorityError(
|
||||
throw new InteractionCoordinationAuthorityError(
|
||||
'invalid_identity',
|
||||
'Interaction and orchestration identities must differ',
|
||||
);
|
||||
@@ -198,7 +200,7 @@ function normalizeIdentity(identity: MosCoordinationIdentity): MosCoordinationId
|
||||
return Object.freeze({ interactionAgentId, orchestrationAgentId });
|
||||
}
|
||||
|
||||
function snapshotRequest(request: MosHandoffRequest): MosHandoffRequest {
|
||||
function snapshotRequest(request: HandoffRequest): HandoffRequest {
|
||||
return Object.freeze({ ...request });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user