/**
 * Detectors for relaycast `agent_token_invalid` responses.
 *
 * Mirrors the recovery contract introduced in upstream PR #137. The Agent Relay
 * MCP server (and any SDK consumer) uses these helpers to recognise when a
 * Relaycast agent token has been invalidated mid-session so the stale
 * credential can be cleared and the caller pointed at a fresh
 * `register_agent` call.
 *
 * Detection is intentionally structural: the upstream `@relaycast/sdk`
 * RelayError surfaces a `code` field once PR #137 ships, but until then
 * (and as a defensive fallback) the status + message pair is enough to
 * identify an invalid agent token.
 */
export const INVALID_AGENT_TOKEN_CODE = 'agent_token_invalid';
export const INVALID_AGENT_TOKEN_MESSAGE = 'Invalid agent token';
function normalizeCode(value) {
    if (typeof value !== 'string')
        return null;
    const trimmed = value.trim();
    return trimmed.length > 0 ? trimmed.toLowerCase() : null;
}
function readStatus(value) {
    if (typeof value === 'number' && Number.isFinite(value))
        return value;
    if (typeof value === 'string') {
        const parsed = Number.parseInt(value, 10);
        return Number.isFinite(parsed) ? parsed : null;
    }
    return null;
}
function readBodyError(body) {
    if (!body || typeof body !== 'object')
        return null;
    const root = body;
    const errorField = root.error;
    if (errorField && typeof errorField === 'object') {
        const e = errorField;
        return {
            code: typeof e.code === 'string' ? e.code : undefined,
            message: typeof e.message === 'string' ? e.message : undefined,
        };
    }
    return {
        code: typeof root.code === 'string' ? root.code : undefined,
        message: typeof root.message === 'string' ? root.message : undefined,
    };
}
/**
 * True when `error` looks like an invalid-agent-token response from
 * Relaycast. Recognises both the typed `agent_token_invalid` code (PR #137)
 * and the legacy status-401 + "Invalid agent token" message pair.
 *
 * The optional `visited` set guards against cyclic `cause` graphs
 * (`a.cause = b; b.cause = a`) — a `WeakSet` so we don't leak references.
 */
export function isInvalidAgentTokenError(error, visited = new WeakSet()) {
    if (!error || typeof error !== 'object')
        return false;
    if (visited.has(error))
        return false;
    visited.add(error);
    const err = error;
    if (normalizeCode(err.code) === INVALID_AGENT_TOKEN_CODE)
        return true;
    const bodyError = readBodyError(err.body);
    if (bodyError && normalizeCode(bodyError.code) === INVALID_AGENT_TOKEN_CODE)
        return true;
    const status = readStatus(err.statusCode) ?? readStatus(err.status);
    const message = (typeof err.message === 'string' ? err.message.trim() : '') || (bodyError?.message?.trim() ?? '');
    if (status === 401 && message === INVALID_AGENT_TOKEN_MESSAGE)
        return true;
    if (err.cause) {
        return isInvalidAgentTokenError(err.cause, visited);
    }
    return false;
}
/**
 * True when a tool result swallowed an invalid-token error into its
 * content array (the pattern the Agent Relay MCP server uses when an upstream
 * call returns `Invalid agent token` in a 401 body).
 */
export function isInvalidAgentTokenToolResult(result) {
    if (!result || typeof result !== 'object')
        return false;
    const r = result;
    if (!Array.isArray(r.content))
        return false;
    return r.content.some((entry) => {
        if (!entry || typeof entry !== 'object')
            return false;
        const e = entry;
        if (e.type !== 'text' || typeof e.text !== 'string')
            return false;
        return e.text.trim() === INVALID_AGENT_TOKEN_MESSAGE;
    });
}
/**
 * Human-readable guidance returned to the MCP client after invalidating a
 * stale agent token. Matches the wording surfaced by the Agent Relay MCP
 * server so prompts that key on this string keep working across both
 * implementations.
 */
export function agentTokenRecoveryMessage() {
    return [
        `${INVALID_AGENT_TOKEN_CODE}: The selected Relaycast agent token is no longer valid.`,
        'The stale token was cleared from this MCP session.',
        'Call the "register_agent" tool with the configured agent name to obtain a fresh token, then retry the failed operation.',
    ].join(' ');
}
//# sourceMappingURL=relaycast-errors.js.map