import { readFile } from 'node:fs/promises'; import YAML from 'yaml'; import type { FleetAgent } from '../commands/fleet.js'; const REQUIRED_RUNTIME = 'pi'; const REQUIRED_MODEL = 'openai/gpt-5.6-sol'; const REQUIRED_REASONING = 'high'; const REQUIRED_TOOL_POLICY = 'operator-interaction'; const AGENT_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/; export interface InteractionServiceProfile { runtime: string; model: string; reasoning: string; toolPolicy: string; } export interface EffectiveInteractionPolicy { agentName: string; runtime: string; model: string; reasoning: string; toolPolicy: string; } export class InteractionServiceProfileError extends Error { constructor( readonly code: 'invalid_profile' | 'invalid_request', message: string, ) { super(message); this.name = InteractionServiceProfileError.name; } } export async function readInteractionServiceProfile( path: string, overrides: Partial = {}, ): Promise { const parsed: unknown = YAML.parse(await readFile(path, 'utf8')); if (!isRecord(parsed)) { throw new InteractionServiceProfileError( 'invalid_profile', 'Service profile must be an object', ); } const profile: InteractionServiceProfile = { runtime: valueOrUndefined(overrides.runtime, parsed['runtime']), model: valueOrUndefined(overrides.model, parsed['model']), reasoning: valueOrUndefined(overrides.reasoning, parsed['reasoning']), toolPolicy: valueOrUndefined(overrides.toolPolicy, parsed['tool_policy']), }; assertPinnedPolicy(profile); return profile; } export function provisionInteractionService( profile: InteractionServiceProfile, input: { agentName: string }, ): { rosterAgent: FleetAgent; effectivePolicy: EffectiveInteractionPolicy } { assertPinnedPolicy(profile); if (!AGENT_NAME_PATTERN.test(input.agentName)) { throw new InteractionServiceProfileError( 'invalid_request', 'Agent name must contain only letters, numbers, dots, underscores, or hyphens', ); } const effectivePolicy: EffectiveInteractionPolicy = { agentName: input.agentName, runtime: profile.runtime, model: profile.model, reasoning: profile.reasoning, toolPolicy: profile.toolPolicy, }; return { rosterAgent: { name: input.agentName, runtime: profile.runtime, className: profile.toolPolicy, modelHint: profile.model, reasoningLevel: profile.reasoning, toolPolicy: profile.toolPolicy, persistentPersona: true, }, effectivePolicy, }; } function assertPinnedPolicy(profile: InteractionServiceProfile): void { const invalid = profile.runtime !== REQUIRED_RUNTIME || profile.model !== REQUIRED_MODEL || profile.reasoning !== REQUIRED_REASONING || profile.toolPolicy !== REQUIRED_TOOL_POLICY; if (invalid) { throw new InteractionServiceProfileError( 'invalid_profile', `Service profile must pin ${REQUIRED_RUNTIME}, ${REQUIRED_MODEL}, ${REQUIRED_REASONING}, and ${REQUIRED_TOOL_POLICY}`, ); } } function valueOrUndefined(override: string | undefined, value: unknown): string { if (override !== undefined) return override; return typeof value === 'string' ? value : ''; } function isRecord(value: unknown): value is Record { return typeof value === 'object' && value !== null && !Array.isArray(value); }