@mondaydotcomorg/atp-protocol
Version:
Core protocol types and interfaces for Agent Tool Protocol
553 lines (547 loc) • 16.8 kB
JavaScript
;
var atpProvenance = require('@mondaydotcomorg/atp-provenance');
var zod = require('zod');
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
exports.CallbackType = void 0;
(function(CallbackType2) {
CallbackType2["LLM"] = "llm";
CallbackType2["APPROVAL"] = "approval";
CallbackType2["EMBEDDING"] = "embedding";
CallbackType2["TOOL"] = "tool";
})(exports.CallbackType || (exports.CallbackType = {}));
exports.ToolOperation = void 0;
(function(ToolOperation2) {
ToolOperation2["CALL"] = "call";
})(exports.ToolOperation || (exports.ToolOperation = {}));
exports.ToolOperationType = void 0;
(function(ToolOperationType2) {
ToolOperationType2["READ"] = "read";
ToolOperationType2["WRITE"] = "write";
ToolOperationType2["DESTRUCTIVE"] = "destructive";
})(exports.ToolOperationType || (exports.ToolOperationType = {}));
exports.ToolSensitivityLevel = void 0;
(function(ToolSensitivityLevel2) {
ToolSensitivityLevel2["PUBLIC"] = "public";
ToolSensitivityLevel2["INTERNAL"] = "internal";
ToolSensitivityLevel2["SENSITIVE"] = "sensitive";
})(exports.ToolSensitivityLevel || (exports.ToolSensitivityLevel = {}));
exports.ExecutionStatus = void 0;
(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";
})(exports.ExecutionStatus || (exports.ExecutionStatus = {}));
exports.ExecutionErrorCode = void 0;
(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";
})(exports.ExecutionErrorCode || (exports.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 = zod.z.object({
timeout: zod.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: zod.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: zod.z.number({
invalid_type_error: "maxLLMCalls must be a number"
}).nonnegative("maxLLMCalls cannot be negative").max(1e3, "maxLLMCalls cannot exceed 1000").optional(),
allowedAPIs: zod.z.array(zod.z.string().refine((val) => val.trim().length > 0, {
message: "allowedAPIs must contain non-empty strings"
})).optional(),
allowLLMCalls: zod.z.boolean({
invalid_type_error: "allowLLMCalls must be a boolean"
}).optional(),
progressCallback: zod.z.function().optional(),
customLLMHandler: zod.z.function().optional(),
clientServices: zod.z.any().optional(),
provenanceMode: zod.z.any().optional(),
securityPolicies: zod.z.array(zod.z.any()).optional(),
provenanceHints: zod.z.array(zod.z.string()).optional()
});
function validateExecutionConfig(config) {
try {
executionConfigSchema.parse(config);
} catch (error) {
if (error instanceof zod.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()));
}
};
Object.defineProperty(exports, "ProvenanceMode", {
enumerable: true,
get: function () { return atpProvenance.ProvenanceMode; }
});
exports.AgentToolProtocolRequestSchema = AgentToolProtocolRequestSchema;
exports.AgentToolProtocolResponseSchema = AgentToolProtocolResponseSchema;
exports.ConfigValidationError = ConfigValidationError;
exports.CredentialResolver = CredentialResolver;
exports.ExecutionConfigSchema = ExecutionConfigSchema;
exports.MAX_CODE_SIZE = MAX_CODE_SIZE;
exports.MultiAuditSink = MultiAuditSink;
exports.SearchOptionsSchema = SearchOptionsSchema;
exports.SecurityViolationError = SecurityViolationError;
exports.executionConfigSchema = executionConfigSchema;
exports.frameCodeExecution = frameCodeExecution;
exports.sanitizeInput = sanitizeInput;
exports.validateClientId = validateClientId;
exports.validateExecutionConfig = validateExecutionConfig;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map