blob: 2fb502ca632a21db6570d25c53906d41bb416f9b [file]
import type { BackendStopMode, SteeringLease } from '@maka/core/backend-types';
import type { RootExecutionDescriptor } from '@maka/core/agent-run';
import type { MessageContent, SessionEvent } from '@maka/core/events';
export interface RuntimeMessageRunIdentity {
readonly sessionId: string;
readonly turnId: string;
readonly runId: string;
}
/** Synchronous lease bridge owned by the Runtime Host for one live root run. */
export interface RuntimeMessageRunOwner extends RuntimeMessageRunIdentity {
pull(): readonly SteeringLease[];
ack(leaseIds: readonly string[]): void;
nack(leaseIds: readonly string[]): void;
/** Ends Runtime access; the Host closes admission at its terminal transition cut. */
release(): void;
}
/** Process-wide factory. Queue admission and projection remain Host responsibilities. */
export interface RuntimeMessageAuthority {
bindRun(identity: RuntimeMessageRunIdentity): RuntimeMessageRunOwner;
}
export interface RuntimeHostedRootExecutionInput extends RuntimeMessageRunIdentity {
readonly userMessageId: string | null;
readonly execution: RootExecutionDescriptor;
readonly content: MessageContent;
/**
* First-admission control-plane gate. Existing durable admissions bypass it
* so recovery never depends on mutable scheduling state.
*/
readonly admitExecution?: () => Promise<'executing' | 'cancelled'>;
readonly start: (input: {
readonly runId: string;
readonly userMessageId: string | null;
readonly onRunStarted: () => void | Promise<void>;
}) => AsyncIterable<SessionEvent>;
readonly onEvent?: (event: SessionEvent) => void;
readonly onReady?: () => void | Promise<void>;
}
/** Host-only root lifecycle capability. Embedded compositions must omit it. */
export interface RuntimeHostedRootAuthority extends RuntimeMessageAuthority {
executeRoot(input: RuntimeHostedRootExecutionInput): Promise<void>;
stopRoot(
identity: RuntimeMessageRunIdentity,
input?: {
source?: 'stop_button' | 'benchmark_deadline' | 'graph_supervisor';
mode?: BackendStopMode;
},
): Promise<void>;
stopSession(
sessionId: string,
input?: {
source?: 'stop_button' | 'benchmark_deadline' | 'graph_supervisor';
mode?: BackendStopMode;
},
): Promise<void>;
}
export function isRuntimeHostedRootAuthority(
authority: RuntimeMessageAuthority | undefined,
): authority is RuntimeHostedRootAuthority {
return (
authority !== undefined &&
'executeRoot' in authority &&
typeof authority.executeRoot === 'function' &&
'stopRoot' in authority &&
typeof authority.stopRoot === 'function' &&
'stopSession' in authority &&
typeof authority.stopSession === 'function'
);
}
export class RuntimeMessageAuthorityInvariantError extends Error {
readonly name = 'RuntimeMessageAuthorityInvariantError';
}
export class RuntimeHostedRootConflictError extends Error {
readonly name = 'RuntimeHostedRootConflictError';
readonly code = 'session_busy';
readonly scope: { readonly kind: 'session'; readonly sessionId: string };
constructor(sessionId: string, message: string) {
super(message);
this.scope = { kind: 'session', sessionId };
}
}