UNPKG

@mondaydotcomorg/atp-protocol

Version:

Core protocol types and interfaces for Agent Tool Protocol

534 lines (529 loc) 16.1 kB
export { ProvenanceMode } from '@mondaydotcomorg/atp-provenance'; import { z } from 'zod'; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var CallbackType; (function(CallbackType2) { CallbackType2["LLM"] = "llm"; CallbackType2["APPROVAL"] = "approval"; CallbackType2["EMBEDDING"] = "embedding"; CallbackType2["TOOL"] = "tool"; })(CallbackType || (CallbackType = {})); var ToolOperation; (function(ToolOperation2) { ToolOperation2["CALL"] = "call"; })(ToolOperation || (ToolOperation = {})); var ToolOperationType; (function(ToolOperationType2) { ToolOperationType2["READ"] = "read"; ToolOperationType2["WRITE"] = "write"; ToolOperationType2["DESTRUCTIVE"] = "destructive"; })(ToolOperationType || (ToolOperationType = {})); var ToolSensitivityLevel; (function(ToolSensitivityLevel2) { ToolSensitivityLevel2["PUBLIC"] = "public"; ToolSensitivityLevel2["INTERNAL"] = "internal"; ToolSensitivityLevel2["SENSITIVE"] = "sensitive"; })(ToolSensitivityLevel || (ToolSensitivityLevel = {})); var ExecutionStatus; (function(ExecutionStatus2) { ExecutionStatus2["COMPLETED"] = "completed"; ExecutionStatus2["FAILED"] = "failed"; ExecutionStatus2["TIMEOUT"] = "timeout"; ExecutionStatus2["CANCELLED"] = "cancelled"; ExecutionStatus2["PAUSED"] = "paused"; ExecutionStatus2["MEMORY_EXCEEDED"] = "memory_exceeded"; ExecutionStatus2["LLM_CALLS_EXCEEDED"] = "llm_calls_exceeded"; ExecutionStatus2["SECURITY_VIOLATION"] = "security_violation"; ExecutionStatus2["VALIDATION_FAILED"] = "validation_failed"; ExecutionStatus2["LOOP_DETECTED"] = "loop_detected"; ExecutionStatus2["RATE_LIMITED"] = "rate_limited"; ExecutionStatus2["NETWORK_ERROR"] = "network_error"; ExecutionStatus2["PARSE_ERROR"] = "parse_error"; })(ExecutionStatus || (ExecutionStatus = {})); var ExecutionErrorCode; (function(ExecutionErrorCode2) { ExecutionErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR"; ExecutionErrorCode2["EXECUTION_FAILED"] = "EXECUTION_FAILED"; ExecutionErrorCode2["TIMEOUT_ERROR"] = "TIMEOUT_ERROR"; ExecutionErrorCode2["MEMORY_LIMIT_EXCEEDED"] = "MEMORY_LIMIT_EXCEEDED"; ExecutionErrorCode2["LLM_CALL_LIMIT_EXCEEDED"] = "LLM_CALL_LIMIT_EXCEEDED"; ExecutionErrorCode2["HTTP_CALL_LIMIT_EXCEEDED"] = "HTTP_CALL_LIMIT_EXCEEDED"; ExecutionErrorCode2["SECURITY_VIOLATION"] = "SECURITY_VIOLATION"; ExecutionErrorCode2["VALIDATION_FAILED"] = "VALIDATION_FAILED"; ExecutionErrorCode2["FORBIDDEN_OPERATION"] = "FORBIDDEN_OPERATION"; ExecutionErrorCode2["PARSE_ERROR"] = "PARSE_ERROR"; ExecutionErrorCode2["SYNTAX_ERROR"] = "SYNTAX_ERROR"; ExecutionErrorCode2["TYPE_ERROR"] = "TYPE_ERROR"; ExecutionErrorCode2["REFERENCE_ERROR"] = "REFERENCE_ERROR"; ExecutionErrorCode2["INFINITE_LOOP_DETECTED"] = "INFINITE_LOOP_DETECTED"; ExecutionErrorCode2["LOOP_TIMEOUT"] = "LOOP_TIMEOUT"; ExecutionErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR"; ExecutionErrorCode2["HTTP_ERROR"] = "HTTP_ERROR"; ExecutionErrorCode2["DNS_ERROR"] = "DNS_ERROR"; ExecutionErrorCode2["RATE_LIMIT_EXCEEDED"] = "RATE_LIMIT_EXCEEDED"; ExecutionErrorCode2["CONCURRENT_LIMIT_EXCEEDED"] = "CONCURRENT_LIMIT_EXCEEDED"; })(ExecutionErrorCode || (ExecutionErrorCode = {})); // src/schemas.ts var ExecutionConfigSchema = { type: "object", properties: { timeout: { type: "number", minimum: 1e3, maximum: 3e5 }, maxMemory: { type: "number", minimum: 1048576, maximum: 536870912 }, maxLLMCalls: { type: "number", minimum: 0, maximum: 100 }, allowedAPIs: { type: "array", items: { type: "string" } }, allowLLMCalls: { type: "boolean" } }, required: [ "timeout", "maxMemory", "maxLLMCalls", "allowedAPIs", "allowLLMCalls" ] }; var SearchOptionsSchema = { type: "object", properties: { query: { type: "string", minLength: 1 }, apiGroups: { type: "array", items: { type: "string" } }, maxResults: { type: "number", minimum: 1, maximum: 100 }, useEmbeddings: { type: "boolean" }, embeddingModel: { type: "string" } }, required: [ "query" ] }; var AgentToolProtocolRequestSchema = { type: "object", properties: { jsonrpc: { type: "string", enum: [ "2.0" ] }, id: { type: [ "string", "number" ] }, method: { type: "string" }, params: { type: "object" } }, required: [ "jsonrpc", "id", "method", "params" ] }; var AgentToolProtocolResponseSchema = { type: "object", properties: { jsonrpc: { type: "string", enum: [ "2.0" ] }, id: { type: [ "string", "number" ] }, result: {}, error: { type: "object", properties: { code: { type: "number" }, message: { type: "string" }, data: {} }, required: [ "code", "message" ] } }, required: [ "jsonrpc", "id" ] }; var MAX_CODE_SIZE = 1e6; var ConfigValidationError = class extends Error { static { __name(this, "ConfigValidationError"); } field; value; constructor(message, field, value) { super(message); this.field = field; this.value = value; this.name = "ConfigValidationError"; } }; var SecurityViolationError = class extends Error { static { __name(this, "SecurityViolationError"); } violations; constructor(message, violations) { super(message); this.violations = violations; this.name = "SecurityViolationError"; } }; function sanitizeInput(input, maxLength = MAX_CODE_SIZE) { if (typeof input !== "string") { return ""; } let sanitized = input.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/g, ""); sanitized = sanitized.replace(/[\u200B-\u200D\uFEFF]/g, ""); sanitized = sanitized.replace(/\n{10,}/g, "\n\n\n"); if (sanitized.length > maxLength) { sanitized = sanitized.substring(0, maxLength); } return sanitized; } __name(sanitizeInput, "sanitizeInput"); function frameCodeExecution(userCode) { const cleaned = sanitizeInput(userCode); return ` (async function __user_code_context__() { "use strict"; ${cleaned} })(); `.trim(); } __name(frameCodeExecution, "frameCodeExecution"); var executionConfigSchema = z.object({ timeout: z.number({ invalid_type_error: "timeout must be a number" }).positive("timeout must be positive").max(3e5, "timeout cannot exceed 300000ms (5 minutes)").optional(), maxMemory: z.number({ invalid_type_error: "maxMemory must be a number" }).positive("maxMemory must be positive").max(512 * 1024 * 1024, "maxMemory cannot exceed 512MB").optional(), maxLLMCalls: z.number({ invalid_type_error: "maxLLMCalls must be a number" }).nonnegative("maxLLMCalls cannot be negative").max(1e3, "maxLLMCalls cannot exceed 1000").optional(), allowedAPIs: z.array(z.string().refine((val) => val.trim().length > 0, { message: "allowedAPIs must contain non-empty strings" })).optional(), allowLLMCalls: z.boolean({ invalid_type_error: "allowLLMCalls must be a boolean" }).optional(), progressCallback: z.function().optional(), customLLMHandler: z.function().optional(), clientServices: z.any().optional(), provenanceMode: z.any().optional(), securityPolicies: z.array(z.any()).optional(), provenanceHints: z.array(z.string()).optional() }); function validateExecutionConfig(config) { try { executionConfigSchema.parse(config); } catch (error) { if (error instanceof z.ZodError) { const errors = error.errors.map((err) => err.message); throw new ConfigValidationError(`Invalid ExecutionConfig: ${errors.join(", ")}`, "ExecutionConfig", config); } throw error; } } __name(validateExecutionConfig, "validateExecutionConfig"); function validateClientId(clientId) { if (typeof clientId !== "string") { throw new ConfigValidationError("clientId must be a string", "clientId", clientId); } if (clientId.trim().length === 0) { throw new ConfigValidationError("clientId cannot be empty", "clientId", clientId); } if (clientId.length > 256) { throw new ConfigValidationError("clientId cannot exceed 256 characters", "clientId", clientId); } if (!/^[a-zA-Z0-9_-]+$/.test(clientId)) { throw new ConfigValidationError("clientId can only contain alphanumeric characters, dashes, and underscores", "clientId", clientId); } } __name(validateClientId, "validateClientId"); // src/auth.ts var CredentialResolver = class { static { __name(this, "CredentialResolver"); } providers = /* @__PURE__ */ new Map(); /** * Registers a runtime credential provider */ registerProvider(provider) { this.providers.set(provider.name, provider); } /** * Resolves auth configuration to credentials */ async resolve(authConfig) { if (authConfig.provider) { const provider = this.providers.get(authConfig.provider); if (!provider) { throw new Error(`Credential provider '${authConfig.provider}' not found`); } return await provider.resolve(); } switch (authConfig.scheme) { case "apiKey": return this.resolveAPIKey(authConfig); case "bearer": return this.resolveBearer(authConfig); case "basic": return this.resolveBasic(authConfig); case "oauth2": return this.resolveOAuth2(authConfig); case "custom": return this.resolveCustom(authConfig); case "composite": return this.resolveComposite(authConfig); default: throw new Error(`Unsupported auth scheme: ${authConfig.scheme}`); } } resolveAPIKey(config) { const value = this.getValue(config); if (!value) { throw new Error(`API key not provided for '${config.name}'`); } if (config.in === "header") { return { headers: { [config.name]: value } }; } else { return { queryParams: { [config.name]: value } }; } } resolveBearer(config) { const token = this.getValue(config); if (!token) { throw new Error("Bearer token not provided"); } return { headers: { Authorization: `Bearer ${token}` } }; } resolveBasic(config) { const username = config.usernameEnvVar ? process.env[config.usernameEnvVar] : config.username; const password = config.passwordEnvVar ? process.env[config.passwordEnvVar] : this.getValue(config); if (!username || !password) { throw new Error("Basic auth username and password not provided"); } const credentials = Buffer.from(`${username}:${password}`).toString("base64"); return { headers: { Authorization: `Basic ${credentials}` } }; } async resolveOAuth2(config) { const clientId = config.clientIdEnvVar ? process.env[config.clientIdEnvVar] : config.clientId; const clientSecret = config.clientSecretEnvVar ? process.env[config.clientSecretEnvVar] : void 0; if (!clientId || !clientSecret) { throw new Error("OAuth2 client credentials not provided"); } if (config.flow === "clientCredentials") { const token2 = await this.fetchOAuth2Token(config.tokenUrl, clientId, clientSecret, config.scopes); return { headers: { Authorization: `Bearer ${token2}` } }; } const token = this.getValue(config); if (token) { return { headers: { Authorization: `Bearer ${token}` } }; } throw new Error(`OAuth2 flow '${config.flow}' requires manual token setup`); } resolveCustom(config) { const headers = {}; const queryParams = {}; Object.assign(headers, config.headers); if (config.headerEnvVars) { for (const [headerName, envVar] of Object.entries(config.headerEnvVars)) { const value = process.env[envVar]; if (value) { headers[headerName] = value; } } } if (config.queryParams) { Object.assign(queryParams, config.queryParams); } if (config.queryParamEnvVars) { for (const [paramName, envVar] of Object.entries(config.queryParamEnvVars)) { const value = process.env[envVar]; if (value) { queryParams[paramName] = value; } } } return { headers: Object.keys(headers).length > 0 ? headers : void 0, queryParams: Object.keys(queryParams).length > 0 ? queryParams : void 0 }; } resolveComposite(config) { const headers = {}; const queryParams = {}; for (const [credName, credConfig] of Object.entries(config.credentials)) { const value = credConfig.envVar ? process.env[credConfig.envVar] : credConfig.value; if (!value) { if (credConfig.required !== false) { throw new Error(`Required credential '${credName}' not provided`); } continue; } const injectAs = config.injectAs || "header"; if ((injectAs === "header" || injectAs === "both") && credConfig.headerName) { headers[credConfig.headerName] = value; } if ((injectAs === "query" || injectAs === "both") && credConfig.queryParamName) { queryParams[credConfig.queryParamName] = value; } if (!credConfig.headerName && !credConfig.queryParamName) { if (injectAs === "query" || injectAs === "both") { queryParams[credName] = value; } else { headers[`X-${credName}`] = value; } } } return { headers: Object.keys(headers).length > 0 ? headers : void 0, queryParams: Object.keys(queryParams).length > 0 ? queryParams : void 0 }; } /** * Gets credential value from config (env var or direct value) */ getValue(config) { if (config.envVar) { return process.env[config.envVar]; } return config.value; } /** * Fetches OAuth2 token using client credentials flow */ async fetchOAuth2Token(tokenUrl, clientId, clientSecret, scopes) { const params = new URLSearchParams({ grant_type: "client_credentials", client_id: clientId, client_secret: clientSecret }); if (scopes && scopes.length > 0) { params.append("scope", scopes.join(" ")); } const response = await fetch(tokenUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: params.toString() }); if (!response.ok) { throw new Error(`OAuth2 token fetch failed: ${response.statusText}`); } const data = await response.json(); return data.access_token; } }; // src/providers.ts var MultiAuditSink = class { static { __name(this, "MultiAuditSink"); } name = "multi"; sinks; constructor(sinks) { this.sinks = sinks; } async write(event) { await Promise.all(this.sinks.map((sink) => sink.write(event))); } async writeBatch(events) { await Promise.all(this.sinks.map((sink) => sink.writeBatch(events))); } async query(filter) { for (const sink of this.sinks) { if (sink.query) { return await sink.query(filter); } } throw new Error("No queryable audit sink available"); } async disconnect() { await Promise.all(this.sinks.map((sink) => sink.disconnect ? sink.disconnect() : Promise.resolve())); } }; export { AgentToolProtocolRequestSchema, AgentToolProtocolResponseSchema, CallbackType, ConfigValidationError, CredentialResolver, ExecutionConfigSchema, ExecutionErrorCode, ExecutionStatus, MAX_CODE_SIZE, MultiAuditSink, SearchOptionsSchema, SecurityViolationError, ToolOperation, ToolOperationType, ToolSensitivityLevel, executionConfigSchema, frameCodeExecution, sanitizeInput, validateClientId, validateExecutionConfig }; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map