Skip to main content
Glama
result-helpers.ts4.97 kB
import { parseStandardResult, StandardResultPayload, stripTaggedResultLines } from './python-output.js'; export interface InterpretedStandardResult { success: boolean; message: string; error?: string; warnings?: string[]; details?: string[]; payload: StandardResultPayload & Record<string, unknown>; cleanText?: string; rawText: string; raw: unknown; } export function interpretStandardResult( response: unknown, defaults: { successMessage: string; failureMessage: string } ): InterpretedStandardResult { const parsed = parseStandardResult(response); const payload = (parsed.data ?? {}) as StandardResultPayload & Record<string, unknown>; const success = payload.success === true; const rawText = typeof parsed.text === 'string' ? parsed.text : String(parsed.text ?? ''); const cleanedText = cleanResultText(rawText, { fallback: undefined }); const messageFromPayload = typeof payload.message === 'string' ? payload.message.trim() : ''; const errorFromPayload = typeof payload.error === 'string' ? payload.error.trim() : ''; const message = messageFromPayload || (success ? defaults.successMessage : defaults.failureMessage); const error = success ? undefined : errorFromPayload || messageFromPayload || defaults.failureMessage; return { success, message, error, warnings: coerceStringArray(payload.warnings), details: coerceStringArray(payload.details), payload, cleanText: cleanedText, rawText, raw: parsed.raw }; } export function cleanResultText( text: string | undefined, options: { tag?: string; fallback?: string } = {} ): string | undefined { const { tag = 'RESULT:', fallback } = options; if (!text) { return fallback; } const cleaned = stripTaggedResultLines(text, tag).trim(); if (cleaned.length > 0) { return cleaned; } return fallback; } export function bestEffortInterpretedText( interpreted: Pick<InterpretedStandardResult, 'cleanText' | 'rawText'>, fallback?: string ): string | undefined { const cleaned = interpreted.cleanText?.trim(); if (cleaned) { return cleaned; } const raw = interpreted.rawText?.trim?.(); if (raw && !raw.startsWith('RESULT:')) { return raw; } return fallback; } export function coerceString(value: unknown): string | undefined { if (typeof value === 'string') { const trimmed = value.trim(); return trimmed.length > 0 ? trimmed : undefined; } return undefined; } export function coerceStringArray(value: unknown): string[] | undefined { if (!Array.isArray(value)) { return undefined; } const items: string[] = []; for (const entry of value) { if (typeof entry !== 'string') { continue; } const trimmed = entry.trim(); if (!trimmed) { continue; } items.push(trimmed); } return items.length > 0 ? items : undefined; } export function coerceBoolean(value: unknown, fallback?: boolean): boolean | undefined { if (typeof value === 'boolean') { return value; } if (typeof value === 'string') { const normalized = value.trim().toLowerCase(); if (['true', '1', 'yes', 'on'].includes(normalized)) { return true; } if (['false', '0', 'no', 'off'].includes(normalized)) { return false; } } if (typeof value === 'number') { if (value === 1) { return true; } if (value === 0) { return false; } } return fallback; } export function coerceNumber(value: unknown): number | undefined { if (typeof value === 'number' && Number.isFinite(value)) { return value; } if (typeof value === 'string') { const parsed = Number(value); if (Number.isFinite(parsed)) { return parsed; } } return undefined; } export function coerceVector3(value: unknown): [number, number, number] | undefined { const toNumber = (entry: unknown): number | undefined => { if (typeof entry === 'number' && Number.isFinite(entry)) { return entry; } if (typeof entry === 'string') { const parsed = Number(entry.trim()); if (Number.isFinite(parsed)) { return parsed; } } return undefined; }; const fromArray = (arr: unknown[]): [number, number, number] | undefined => { if (arr.length !== 3) { return undefined; } const mapped = arr.map(toNumber); if (mapped.every((entry): entry is number => typeof entry === 'number')) { return mapped as [number, number, number]; } return undefined; }; if (Array.isArray(value)) { const parsed = fromArray(value); if (parsed) { return parsed; } } if (value && typeof value === 'object') { const obj = value as Record<string, unknown>; const candidate = fromArray([obj.x, obj.y, obj.z]); if (candidate) { return candidate; } const alternate = fromArray([obj.pitch, obj.yaw, obj.roll]); if (alternate) { return alternate; } } return undefined; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ChiR24/Unreal_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server