Files
stack/packages/mosaic/src/fleet/interaction-service-profile.ts
jason.woltje e3b5113be2
All checks were successful
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
feat(tess): add configurable Pi interaction service (#728)
2026-07-13 02:59:27 +00:00

111 lines
3.3 KiB
TypeScript

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<InteractionServiceProfile> = {},
): Promise<InteractionServiceProfile> {
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<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}