UNPKG

@kya-os/cli

Version:

CLI for MCP-I setup and management

149 lines 4.91 kB
/** * Know-That-AI (KTA) API utilities * Handles delegation checking and other KTA API interactions */ import { z } from "zod"; import contractsRegistry from "@kya-os/contracts/registry"; const { KTA_BASE_URL, AgentStatusSchema } = contractsRegistry; /** * Delegation status response from KTA * Accept both kid and keyId for backward compatibility */ export const DelegationStatusSchema = z.object({ did: z.string(), // Accept either kid or keyId (server may use either during transition) kid: z.string().optional(), keyId: z.string().optional(), status: z.enum(["active", "revoked", "not_found"]), delegatedTo: z.string().optional(), expiresAt: z.number().optional(), lastUpdated: z.number(), }).refine((data) => data.kid || data.keyId, { message: "Either kid or keyId must be provided", }).transform((data) => ({ ...data, // Normalize: ensure kid is always present (safe due to refine check) kid: data.kid || data.keyId, })); /** * KTA API client for delegation checking */ export class KTAApiClient { constructor(baseURL = KTA_BASE_URL, apiKey) { this.baseURL = baseURL; this.apiKey = apiKey || process.env.KYA_VOUCHED_API_KEY || process.env.VOUCHED_API_KEY; } /** * Check delegation status for a DID/KeyID pair * This is the exact KTA lookup API used for delegation confirmation */ async checkDelegation(did, kid) { const url = new URL(`/api/v1/delegations/status`, this.baseURL); url.searchParams.set("did", did); // Send both kid and keyId for backward compatibility // Server may expect either parameter name during transition period url.searchParams.set("kid", kid); url.searchParams.set("keyId", kid); const headers = { "Content-Type": "application/json", "User-Agent": "mcpi-cli/1.0.0", }; if (this.apiKey) { headers["Authorization"] = `Bearer ${this.apiKey}`; } try { const response = await fetch(url.toString(), { method: "GET", headers, }); if (!response.ok) { if (response.status === 404) { return { did, kid, status: "not_found", lastUpdated: Date.now(), }; } throw new Error(`KTA API error: ${response.status} ${response.statusText}`); } const data = await response.json(); return DelegationStatusSchema.parse(data); } catch (error) { if (error instanceof Error) { throw new Error(`Failed to check delegation: ${error.message}`); } throw new Error("Failed to check delegation: Unknown error"); } } /** * Check if KTA is reachable */ async isReachable() { try { const response = await fetch(`${this.baseURL}/api/health`, { method: "GET", headers: { "User-Agent": "mcpi-cli/1.0.0", }, // Short timeout for health check signal: AbortSignal.timeout(5000), }); return response.ok; } catch { return false; } } /** * Get agent status from KTA */ async getAgentStatus(did) { const url = new URL(`/api/v1/agents/status`, this.baseURL); url.searchParams.set("did", did); const headers = { "Content-Type": "application/json", "User-Agent": "mcpi-cli/1.0.0", }; if (this.apiKey) { headers["Authorization"] = `Bearer ${this.apiKey}`; } const response = await fetch(url.toString(), { method: "GET", headers, }); if (!response.ok) { throw new Error(`KTA API error: ${response.status} ${response.statusText}`); } const data = await response.json(); return AgentStatusSchema.parse(data); } } /** * Default KTA API client instance */ export const ktaApi = new KTAApiClient(); /** * Check if a delegation exists for the given DID/KeyID pair * Returns true if delegation is active, false otherwise */ export async function hasDelegation(did, kid) { try { const status = await ktaApi.checkDelegation(did, kid); return status.status === "active"; } catch (error) { // If we can't check delegation, assume false for safety console.warn(`Warning: Could not check delegation status: ${error}`); return false; } } /** * Check if KTA is available */ export async function isKTAAvailable() { return ktaApi.isReachable(); } //# sourceMappingURL=kta-api.js.map