diff --git a/bun.lock b/bun.lock
index 8d71f40a72..61834997fc 100644
--- a/bun.lock
+++ b/bun.lock
@@ -16,14 +16,17 @@
},
"integrations/1password": {
"name": "@slates-integrations/1password",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/21risk": {
@@ -136,10 +139,11 @@
},
"integrations/activecampaign": {
"name": "@slates-integrations/activecampaign",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -196,10 +200,11 @@
},
"integrations/adobe-sign": {
"name": "@slates-integrations/adobe-sign",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -244,14 +249,17 @@
},
"integrations/affinda": {
"name": "@slates-integrations/affinda",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/affinity": {
@@ -557,14 +565,17 @@
},
"integrations/amplitude": {
"name": "@slates-integrations/amplitude",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/anchor-browser": {
@@ -666,14 +677,17 @@
},
"integrations/api2pdf": {
"name": "@slates-integrations/api2pdf",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/apiflash": {
@@ -835,14 +849,17 @@
},
"integrations/asana": {
"name": "@slates-integrations/asana",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/ascora": {
@@ -871,14 +888,17 @@
},
"integrations/assembly-ai": {
"name": "@slates-integrations/assemblyai",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/astica-ai": {
@@ -919,14 +939,17 @@
},
"integrations/auth0": {
"name": "@slates-integrations/auth0",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/autobound": {
@@ -966,22 +989,26 @@
},
"integrations/aws-cognito": {
"name": "@slates-integrations/aws-cognito",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/aws-dynamodb": {
"name": "@slates-integrations/aws-dynamodb",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -1021,22 +1048,26 @@
},
"integrations/aws-ses": {
"name": "@slates-integrations/aws-ses",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/aws-sns": {
"name": "@slates-integrations/aws-sns",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -1045,26 +1076,32 @@
},
"integrations/aws-sqs": {
"name": "@slates-integrations/aws-sqs",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/aws-transcribe": {
"name": "@slates-integrations/aws-transcribe",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/ayrshare": {
@@ -1136,10 +1173,11 @@
},
"integrations/azure-speech": {
"name": "@slates-integrations/azure-speech",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -1376,14 +1414,17 @@
},
"integrations/bigcommerce": {
"name": "@slates-integrations/bigcommerce",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/bigmailer": {
@@ -1424,10 +1465,11 @@
},
"integrations/bigquery": {
"name": "@slates-integrations/bigquery",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -1677,14 +1719,17 @@
},
"integrations/box": {
"name": "@slates-integrations/box",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/boxhero": {
@@ -1701,10 +1746,11 @@
},
"integrations/braintree": {
"name": "@slates-integrations/braintree",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -1725,14 +1771,17 @@
},
"integrations/braze": {
"name": "@slates-integrations/braze",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/breathehr": {
@@ -1761,13 +1810,15 @@
},
"integrations/brevo": {
"name": "@slates-integrations/brevo",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
},
},
@@ -1821,26 +1872,32 @@
},
"integrations/browserbase-tool": {
"name": "@slates-integrations/browserbase",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/browserless": {
"name": "@slates-integrations/browserless",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/btcpay-server": {
@@ -2013,14 +2070,17 @@
},
"integrations/cal-com": {
"name": "@slates-integrations/calcom",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/calendarhero": {
@@ -2386,10 +2446,11 @@
},
"integrations/clearbit": {
"name": "@slates-integrations/clearbit",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -2447,10 +2508,11 @@
},
"integrations/clickup": {
"name": "@slates-integrations/clickup",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -2532,10 +2594,11 @@
},
"integrations/cloudflare-workers": {
"name": "@slates-integrations/cloudflare-workers",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -2580,10 +2643,11 @@
},
"integrations/coda": {
"name": "@slates-integrations/coda",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -2640,22 +2704,26 @@
},
"integrations/cohere": {
"name": "@slates-integrations/cohere",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/coinbase": {
"name": "@slates-integrations/coinbase",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -2809,14 +2877,17 @@
},
"integrations/convertkit": {
"name": "@slates-integrations/convertkit",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/convex": {
@@ -2917,14 +2988,17 @@
},
"integrations/crisp": {
"name": "@slates-integrations/crisp",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/crowdin": {
@@ -3025,14 +3099,17 @@
},
"integrations/customer-io": {
"name": "@slates-integrations/customerio",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/customgpt": {
@@ -3157,26 +3234,32 @@
},
"integrations/databricks": {
"name": "@slates-integrations/databricks",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/datadog": {
"name": "@slates-integrations/datadog",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/dataforseo": {
@@ -3185,7 +3268,7 @@
"dependencies": {
"@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -3293,14 +3376,17 @@
},
"integrations/deepgram": {
"name": "@slates-integrations/deepgram",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/deepimage": {
@@ -3317,10 +3403,11 @@
},
"integrations/deepseek": {
"name": "@slates-integrations/deepseek",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -3499,10 +3586,11 @@
},
"integrations/docker-hub": {
"name": "@slates-integrations/docker-hub",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -3535,10 +3623,11 @@
},
"integrations/docparser": {
"name": "@slates-integrations/docparser",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -3583,14 +3672,17 @@
},
"integrations/docsumo": {
"name": "@slates-integrations/docsumo",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/docugenerate": {
@@ -3667,14 +3759,17 @@
},
"integrations/docusign": {
"name": "@slates-integrations/docusign",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.8",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/doodle": {
@@ -3775,14 +3870,17 @@
},
"integrations/drift": {
"name": "@slates-integrations/drift",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/drip": {
@@ -3823,14 +3921,17 @@
},
"integrations/dropbox": {
"name": "@slates-integrations/dropbox",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.8",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/dropcontact": {
@@ -3971,14 +4072,17 @@
},
"integrations/eleven-labs": {
"name": "@slates-integrations/elevenlabs",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/elevenreader": {
@@ -4271,14 +4375,17 @@
},
"integrations/evernote": {
"name": "@slates-integrations/evernote",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/eversign": {
@@ -4701,10 +4808,11 @@
},
"integrations/fly-io": {
"name": "@slates-integrations/flyio",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -4857,46 +4965,56 @@
},
"integrations/freshdesk": {
"name": "@slates-integrations/freshdesk",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/freshsales": {
"name": "@slates-integrations/freshsales",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/freshservice": {
"name": "@slates-integrations/freshservice",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/front": {
"name": "@slates-integrations/front",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -4917,14 +5035,17 @@
},
"integrations/fullstory": {
"name": "@slates-integrations/fullstory",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/gagelist": {
@@ -5646,10 +5767,11 @@
},
"integrations/grafana": {
"name": "@slates-integrations/grafana",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -5718,14 +5840,17 @@
},
"integrations/groqcloud": {
"name": "@slates-integrations/groqcloud",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/gtmetrix": {
@@ -5742,14 +5867,17 @@
},
"integrations/gumroad": {
"name": "@slates-integrations/gumroad",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/gusto": {
@@ -5898,13 +6026,15 @@
},
"integrations/hellosign": {
"name": "@slates-integrations/hellosign",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
},
},
@@ -5922,10 +6052,11 @@
},
"integrations/helpscout": {
"name": "@slates-integrations/help-scout",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -6116,10 +6247,11 @@
},
"integrations/hotjar": {
"name": "@slates-integrations/hotjar",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -6179,14 +6311,17 @@
},
"integrations/huggingface": {
"name": "@slates-integrations/hugging-face",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/humanitix": {
@@ -6589,14 +6724,17 @@
},
"integrations/iterable": {
"name": "@slates-integrations/iterable",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/jenkins": {
@@ -6759,13 +6897,15 @@
},
"integrations/kibana": {
"name": "@slates-integrations/kibana",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
},
},
@@ -6783,26 +6923,32 @@
},
"integrations/kit": {
"name": "@slates-integrations/kit",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/klaviyo": {
"name": "@slates-integrations/klaviyo",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/klazify": {
@@ -6891,10 +7037,11 @@
},
"integrations/kubernetes": {
"name": "@slates-integrations/kubernetes",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -6951,14 +7098,17 @@
},
"integrations/langbase": {
"name": "@slates-integrations/langbase",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/laposta": {
@@ -7083,14 +7233,17 @@
},
"integrations/lemon-squeezy": {
"name": "@slates-integrations/lemon-squeezy",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/lessonspace": {
@@ -7396,10 +7549,11 @@
},
"integrations/magento": {
"name": "@slates-integrations/magento",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -7493,14 +7647,17 @@
},
"integrations/mailerlite": {
"name": "@slates-integrations/mailerlite",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/mailersend": {
@@ -7517,14 +7674,17 @@
},
"integrations/mailgun": {
"name": "@slates-integrations/mailgun",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/mails-so": {
@@ -7722,10 +7882,11 @@
},
"integrations/metaads": {
"name": "@slates-integrations/meta-ads",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -7758,14 +7919,15 @@
},
"integrations/metorial-admin": {
"name": "@slates-integrations/metorial-admin",
- "version": "0.1.0-rc.6",
+ "version": "0.1.0-rc.7",
"dependencies": {
"@lowerdeck/error": "^1.1.0",
- "@slates/provider": "1.0.0-rc.15",
+ "@slates/provider": "1.0.0-rc.16",
"@types/node": "^20",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
"vitest": "^3.1.2",
},
@@ -7796,7 +7958,7 @@
},
"integrations/microsoft-fabric": {
"name": "@slates-integrations/microsoft-fabric",
- "version": "0.1.0-rc.3",
+ "version": "0.1.0-rc.5",
"dependencies": {
"@lowerdeck/error": "^1.1.0",
"@slates/provider": "1.0.0-rc.15",
@@ -7825,14 +7987,17 @@
},
"integrations/midjourney": {
"name": "@slates-integrations/midjourney",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/minerstat": {
@@ -7873,14 +8038,17 @@
},
"integrations/mistral-ai": {
"name": "@slates-integrations/mistral-ai",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/mixmax": {
@@ -7897,14 +8065,17 @@
},
"integrations/mixpanel": {
"name": "@slates-integrations/mixpanel",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/mocean": {
@@ -7957,14 +8128,17 @@
},
"integrations/monday": {
"name": "@slates-integrations/mondaycom",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/moneybird": {
@@ -7981,26 +8155,32 @@
},
"integrations/mongodb": {
"name": "@slates-integrations/mongodb",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/mongodb-atlas": {
"name": "@slates-integrations/mongodb-atlas",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/moonclerk": {
@@ -8125,14 +8305,18 @@
},
"integrations/mysql": {
"name": "@slates-integrations/mysql",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "mysql2": "^3.22.5",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/n8n": {
@@ -8161,14 +8345,17 @@
},
"integrations/nano-nets": {
"name": "@slates-integrations/nanonets",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/nasa": {
@@ -8209,14 +8396,17 @@
},
"integrations/neon": {
"name": "@slates-integrations/neon",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/netlify": {
@@ -8282,14 +8472,17 @@
},
"integrations/new-relic": {
"name": "@slates-integrations/new-relic",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/newsdata-io": {
@@ -8475,22 +8668,26 @@
},
"integrations/ocr-web-service": {
"name": "@slates-integrations/ocr-web-service",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/ocrspace": {
"name": "@slates-integrations/ocrspace",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.8",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -8523,10 +8720,11 @@
},
"integrations/okta": {
"name": "@slates-integrations/okta",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -8535,14 +8733,17 @@
},
"integrations/ollama": {
"name": "@slates-integrations/ollama",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/omnisend": {
@@ -8696,26 +8897,32 @@
},
"integrations/openrouter": {
"name": "@slates-integrations/openrouter",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/opsgenie": {
"name": "@slates-integrations/opsgenie",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/optimizely": {
@@ -8808,26 +9015,32 @@
},
"integrations/pagerduty": {
"name": "@slates-integrations/pagerduty",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/pandadoc": {
"name": "@slates-integrations/pandadoc",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.8",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/paperform": {
@@ -9013,10 +9226,11 @@
},
"integrations/pdf-api-io": {
"name": "@slates-integrations/pdf-apiio",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -9025,10 +9239,11 @@
},
"integrations/pdf-co": {
"name": "@slates-integrations/pdfco",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -9037,14 +9252,17 @@
},
"integrations/pdf4me": {
"name": "@slates-integrations/pdf4me",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/pdfless": {
@@ -9061,26 +9279,32 @@
},
"integrations/pdfmonkey": {
"name": "@slates-integrations/pdfmonkey",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/pendo": {
"name": "@slates-integrations/pendo",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/penpot": {
@@ -9121,10 +9345,11 @@
},
"integrations/perplexityai": {
"name": "@slates-integrations/perplexity-ai",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -9217,14 +9442,17 @@
},
"integrations/pinecone": {
"name": "@slates-integrations/pinecone",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/pingdom": {
@@ -9327,14 +9555,17 @@
},
"integrations/planetscale": {
"name": "@slates-integrations/planetscale",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/planly": {
@@ -9508,10 +9739,11 @@
},
"integrations/posthog": {
"name": "@slates-integrations/posthog",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -9532,14 +9764,17 @@
},
"integrations/postmark": {
"name": "@slates-integrations/postmark",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/power-bi": {
@@ -9848,10 +10083,11 @@
},
"integrations/railway": {
"name": "@slates-integrations/railway",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -9969,10 +10205,11 @@
},
"integrations/redis": {
"name": "@slates-integrations/redis",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -10053,14 +10290,17 @@
},
"integrations/render": {
"name": "@slates-integrations/render",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/renderform": {
@@ -10101,14 +10341,17 @@
},
"integrations/replicate": {
"name": "@slates-integrations/replicate",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/reply-io": {
@@ -10125,14 +10368,17 @@
},
"integrations/resend": {
"name": "@slates-integrations/resend",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.8",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/resistant-ai": {
@@ -10655,14 +10901,17 @@
},
"integrations/segment": {
"name": "@slates-integrations/segment",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/segmetrics": {
@@ -10751,14 +11000,17 @@
},
"integrations/sendgrid": {
"name": "@slates-integrations/sendgrid",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.8",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/sendlane": {
@@ -10908,14 +11160,17 @@
},
"integrations/servicenow": {
"name": "@slates-integrations/servicenow",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/sevdesk": {
@@ -11396,10 +11651,11 @@
},
"integrations/splunk": {
"name": "@slates-integrations/splunk",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -11468,10 +11724,11 @@
},
"integrations/square": {
"name": "@slates-integrations/square",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -11480,14 +11737,17 @@
},
"integrations/squarespace": {
"name": "@slates-integrations/squarespace",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/sslmate-cert-spotter-api": {
@@ -11504,14 +11764,17 @@
},
"integrations/stability-ai": {
"name": "@slates-integrations/stability-ai",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/stack-ai": {
@@ -11775,14 +12038,17 @@
},
"integrations/supabase": {
"name": "@slates-integrations/supabase",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/supadata": {
@@ -11947,14 +12213,17 @@
},
"integrations/taggun": {
"name": "@slates-integrations/taggun",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/talenthr": {
@@ -12440,14 +12709,17 @@
},
"integrations/trello": {
"name": "@slates-integrations/trello",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/triggercmd": {
@@ -12549,14 +12821,17 @@
},
"integrations/twilio-sendgrid": {
"name": "@slates-integrations/twilio-sendgrid",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/twitch": {
@@ -13008,14 +13283,17 @@
},
"integrations/webflow": {
"name": "@slates-integrations/webflow",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/webscraper-io": {
@@ -13140,14 +13418,17 @@
},
"integrations/wix": {
"name": "@slates-integrations/wix",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.7",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/wiza": {
@@ -13176,14 +13457,17 @@
},
"integrations/woocommerce": {
"name": "@slates-integrations/woocommerce",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/woodpecker-co": {
@@ -13214,14 +13498,17 @@
},
"integrations/wordpress": {
"name": "@slates-integrations/wordpress",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/workable": {
@@ -13547,14 +13834,17 @@
},
"integrations/zoho-crm": {
"name": "@slates-integrations/zoho-crm",
- "version": "0.2.0-rc.5",
+ "version": "0.2.0-rc.6",
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
"typescript": "^5",
+ "vitest": "^3.1.2",
},
},
"integrations/zoho-desk": {
@@ -13674,7 +13964,7 @@
"@smithy/querystring-builder": "^4.2.14",
"@smithy/types": "^4.14.1",
"axios": "^1.13.2",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
},
"devDependencies": {
"@slates/tsconfig": "1.0.0-rc.1",
@@ -13720,7 +14010,7 @@
"dependencies": {
"@lowerdeck/error": "^1.1.0",
"@slates/tool-recipes": "1.0.0-rc.4",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -13733,7 +14023,7 @@
"name": "@slates/oauth-microsoft",
"version": "1.0.0-rc.5",
"dependencies": {
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
},
"devDependencies": {
"@slates/tsconfig": "1.0.0-rc.1",
@@ -13811,7 +14101,7 @@
"version": "1.0.0-rc.8",
"dependencies": {
"@lowerdeck/error": "^1.1.0",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -13838,11 +14128,11 @@
"version": "1.0.0-rc.9",
"dependencies": {
"@lowerdeck/testing-tools": "latest",
- "@slates/client": "1.0.0-rc.12",
- "@slates/profiles": "1.0.0-rc.10",
+ "@slates/client": "1.0.0-rc.13",
+ "@slates/profiles": "1.0.0-rc.11",
},
"devDependencies": {
- "@slates/provider": "1.0.0-rc.15",
+ "@slates/provider": "1.0.0-rc.16",
"@slates/tsconfig": "1.0.0-rc.1",
"typescript": "5.8.2",
"vitest": "^3.1.2",
@@ -13853,7 +14143,7 @@
"name": "@slates/tool-recipes",
"version": "1.0.0-rc.4",
"dependencies": {
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2",
},
"devDependencies": {
@@ -16910,6 +17200,8 @@
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
+ "aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="],
+
"axios": ["axios@1.16.0", "", { "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w=="],
"babel-plugin-macros": ["babel-plugin-macros@3.1.0", "", { "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" } }, "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg=="],
@@ -17046,6 +17338,8 @@
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
+ "denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
+
"dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
@@ -17138,6 +17432,8 @@
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
+ "generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="],
+
"generator-function": ["generator-function@2.0.1", "", {}, "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g=="],
"generic-names": ["generic-names@4.0.0", "", { "dependencies": { "loader-utils": "^3.2.0" } }, "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A=="],
@@ -17234,6 +17530,8 @@
"is-number-object": ["is-number-object@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw=="],
+ "is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="],
+
"is-reference": ["is-reference@1.2.1", "", { "dependencies": { "@types/estree": "*" } }, "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ=="],
"is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
@@ -17296,10 +17594,14 @@
"lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="],
+ "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
+
"loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="],
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
+ "lru.min": ["lru.min@1.1.4", "", {}, "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA=="],
+
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
"make-dir": ["make-dir@3.1.0", "", { "dependencies": { "semver": "^6.0.0" } }, "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="],
@@ -17330,8 +17632,12 @@
"mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="],
+ "mysql2": ["mysql2@3.22.5", "", { "dependencies": { "aws-ssl-profiles": "^1.1.2", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.2", "long": "^5.3.2", "lru.min": "^1.1.4", "named-placeholders": "^1.1.6", "sql-escaper": "^1.3.3" }, "peerDependencies": { "@types/node": ">= 8" } }, "sha512-95uZ2TrPWAZdwpB3vvvDbmEMcNG8yIeNCyu6GUcr/QnWEE/wXm7+mhOCsdQfWQDTV7qYT/PDUZ4U4UPP4AsXqQ=="],
+
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
+ "named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="],
+
"nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="],
"node-releases": ["node-releases@2.0.44", "", {}, "sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ=="],
@@ -17568,6 +17874,8 @@
"sourcemap-codec": ["sourcemap-codec@1.4.8", "", {}, "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="],
+ "sql-escaper": ["sql-escaper@1.3.3", "", {}, "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw=="],
+
"ssf": ["ssf@0.11.2", "", { "dependencies": { "frac": "~1.1.2" } }, "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g=="],
"stable": ["stable@0.1.8", "", {}, "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w=="],
@@ -17742,8 +18050,6 @@
"@rollup/pluginutils/rollup": ["rollup@2.80.0", "", { "optionalDependencies": { "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ=="],
- "@slates-integrations/1password/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/21risk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/2chat/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17760,8 +18066,6 @@
"@slates-integrations/acculynx/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/activecampaign/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/activetrail/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/acuity-scheduling/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17772,16 +18076,12 @@
"@slates-integrations/adobe-creative-cloud/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/adobe-sign/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/adrapid/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/adyntel/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/aeroleads/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/affinda/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/affinity/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/agencyzoom/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17834,8 +18134,6 @@
"@slates-integrations/amcards/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/amplitude/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/anchor-browser/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/anonyflow/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17850,8 +18148,6 @@
"@slates-integrations/api-sports/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/api2pdf/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/apibible/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/apiflash/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17880,40 +18176,22 @@
"@slates-integrations/aryn/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/asana/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/ascora/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/ashby/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/assemblyai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/astica-ai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/async-interview/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/attio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/auth0/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/autobound/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/aws-cognito/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/aws-dynamodb/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/aws-lambda/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/aws-s3/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/aws-ses/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/aws-sns/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/aws-sqs/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/aws-transcribe/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/ayrshare/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/azure-blob-storage/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17924,8 +18202,6 @@
"@slates-integrations/azure-repos/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/azure-speech/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/backendless/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/bamboohr/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17962,8 +18238,6 @@
"@slates-integrations/bidsketch/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/bigcommerce/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/bigdatacloud/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/bigmailer/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -17972,8 +18246,6 @@
"@slates-integrations/bigpictureio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/bigquery/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/bitbucket/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/bitquery/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18014,22 +18286,14 @@
"@slates-integrations/bouncer/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/box/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/boxhero/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/braintree/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/brandfetch/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/braze/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/breathe-hr/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/breeze/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/brevo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/brex/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/bright-data/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18038,10 +18302,6 @@
"@slates-integrations/browseai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/browserbase/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/browserless/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/btcpay-server/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/bubble/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18070,8 +18330,6 @@
"@slates-integrations/cabinpanda/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/calcom/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/calendarhero/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/calendly/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -18134,8 +18392,6 @@
"@slates-integrations/classmarker/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/clearbit/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/clearout/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/clickhouse/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18144,8 +18400,6 @@
"@slates-integrations/clicksend/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/clickup/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/clientary/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/clockify/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18158,16 +18412,12 @@
"@slates-integrations/cloudflare/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/cloudflare-workers/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/cloudinary/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/cloudlayer/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/coassemble/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/coda/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/codacy/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/codemagic/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18176,10 +18426,6 @@
"@slates-integrations/cody/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/cohere/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/coinbase/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/coinmarketcal/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/coinmarketcap/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18204,8 +18450,6 @@
"@slates-integrations/convertapi/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/convertkit/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/convex/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/conveyor/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18222,8 +18466,6 @@
"@slates-integrations/craftmypdf/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/crisp/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/crowdin/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/crowterminal/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18240,8 +18482,6 @@
"@slates-integrations/cursor/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/customerio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/customgpt/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/customjs/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18262,12 +18502,6 @@
"@slates-integrations/databox/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/databricks/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/datadog/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/dataforseo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/datagma/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/datarobot/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18284,12 +18518,8 @@
"@slates-integrations/deel/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/deepgram/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/deepimage/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/deepseek/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/delighted/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/demio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18318,22 +18548,16 @@
"@slates-integrations/dock-labs-truvera/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/docker-hub/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/docmosis/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/docnify/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/docparser/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/docraptor/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/docsautomator/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/docsbot-ai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/docsumo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/docugenerate/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/documenso/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18346,8 +18570,6 @@
"@slates-integrations/docuseal/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/docusign/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/doodle/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/doppler/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18364,16 +18586,12 @@
"@slates-integrations/dreamstudio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/drift/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/drip/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/dripcel/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/dromo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/dropbox/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/dropcontact/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/dub/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18396,8 +18614,6 @@
"@slates-integrations/elasticsearch/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/elevenlabs/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/elevenreader/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/elorus/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18446,8 +18662,6 @@
"@slates-integrations/everhour/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/evernote/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/eversign/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/exa/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18518,8 +18732,6 @@
"@slates-integrations/fluxguard/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/flyio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/folk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/follow-up-boss/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18544,18 +18756,8 @@
"@slates-integrations/freshbooks/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/freshdesk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/freshsales/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/freshservice/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/front/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/fullenrich/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/fullstory/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/gagelist/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/gamma/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18666,8 +18868,6 @@
"@slates-integrations/gosquared/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/grafana/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/grafbase/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/graphhopper/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18678,12 +18878,8 @@
"@slates-integrations/grist/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/groqcloud/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/gtmetrix/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/gumroad/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/gusto/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/habitica/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18708,10 +18904,6 @@
"@slates-integrations/helloleads/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/hellosign/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/help-scout/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/helpdesk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/helpwise/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18744,8 +18936,6 @@
"@slates-integrations/hootsuite/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/hotjar/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/hotspotsystem/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/html-to-image/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18754,8 +18944,6 @@
"@slates-integrations/hubspot/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/hugging-face/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/humanitix/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/humanloop/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18822,8 +19010,6 @@
"@slates-integrations/item/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/iterable/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/jenkins/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/jigsawstack/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18850,14 +19036,8 @@
"@slates-integrations/keyword/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/kibana/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/kickbox/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/kit/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/klaviyo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/klazify/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/klipfolio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18872,8 +19052,6 @@
"@slates-integrations/krakenio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/kubernetes/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/l2s/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/la-growth-machine/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18882,8 +19060,6 @@
"@slates-integrations/landbot/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/langbase/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/laposta/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/lastpass/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18904,8 +19080,6 @@
"@slates-integrations/lemlist/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/lemon-squeezy/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/lessonspace/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/lever/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18956,8 +19130,6 @@
"@slates-integrations/loyverse/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/magento/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/magnetic/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/mailbluster/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -18972,12 +19144,8 @@
"@slates-integrations/mailercloud/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/mailerlite/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/mailersend/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/mailgun/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/mailsoftly/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/mailsso/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19008,14 +19176,10 @@
"@slates-integrations/membervault/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/meta-ads/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/metabase/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/metatextai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/metorial-admin/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/mezmo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/microsoft-clarity/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19026,20 +19190,14 @@
"@slates-integrations/microsoft-teams/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/midjourney/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/minerstat/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/miro/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/missive/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/mistral-ai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/mixmax/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/mixpanel/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/mocean/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/moco/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19048,14 +19206,8 @@
"@slates-integrations/modelry/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/mondaycom/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/moneybird/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/mongodb/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/mongodb-atlas/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/moonclerk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/moosend/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19076,22 +19228,16 @@
"@slates-integrations/mxtoolbox/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/mysql/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/n8n/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/nango/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/nanonets/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/nasa/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/nasdaq/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/needle/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/neon/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/netlify/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/netsuite/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19102,8 +19248,6 @@
"@slates-integrations/neverbounce/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/new-relic/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/newsapi/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/nextdns/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19134,18 +19278,10 @@
"@slates-integrations/nutshell/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/ocr-web-service/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/ocrspace/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/odoo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/oksign/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/okta/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/ollama/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/omnisend/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/onedesk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19168,14 +19304,10 @@
"@slates-integrations/openperplex/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/openrouter/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/opensea/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/openweathermap/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/opsgenie/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/optimizely/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/optimoroute/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19188,10 +19320,6 @@
"@slates-integrations/page-x/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/pagerduty/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/pandadoc/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/paperform/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/papertrail/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19222,26 +19350,14 @@
"@slates-integrations/paystack/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/pdf-apiio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/pdf4me/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/pdfco/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/pdfless/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/pdfmonkey/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/pendo/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/penpot/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/people-data-labs/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/perigon/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/perplexity-ai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/persistiq/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/persona/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19256,8 +19372,6 @@
"@slates-integrations/pilvio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/pinecone/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/pingdom/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/pinterest/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -19274,8 +19388,6 @@
"@slates-integrations/plain/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/planetscale/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/planly/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/planyo-online-booking/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19304,12 +19416,8 @@
"@slates-integrations/postgrid-verify/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/posthog/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/postman/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/postmark/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/power-bi/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/powerpoint-online/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19360,8 +19468,6 @@
"@slates-integrations/ragie/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/railway/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/raisely/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/ramp/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19380,8 +19486,6 @@
"@slates-integrations/reddit-ads/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/redis/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/referralrock/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/refiner/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19394,20 +19498,14 @@
"@slates-integrations/removebg/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/render/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/renderform/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/rentman/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/repairshopr/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/replicate/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/replyio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/resend/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/resistant-ai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/respondio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19494,8 +19592,6 @@
"@slates-integrations/securitytrails/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/segment/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/segmetrics/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/semantic-scholar/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19510,8 +19606,6 @@
"@slates-integrations/sendfox/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/sendgrid/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/sendlane/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/sendloop/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19536,8 +19630,6 @@
"@slates-integrations/servicem8/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/servicenow/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/sevdesk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/sharepoint/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19614,8 +19706,6 @@
"@slates-integrations/splitwise/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/splunk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/spoki/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/spondyr/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19626,14 +19716,8 @@
"@slates-integrations/sprout-social/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/square/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates-integrations/squarespace/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/sslmate-cert-spotter-api/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/stability-ai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/stack-ai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/stack-exchange/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19676,8 +19760,6 @@
"@slates-integrations/suitedash/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/supabase/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/supadata/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/superchat/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19704,8 +19786,6 @@
"@slates-integrations/tableau/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/taggun/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/talenthr/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/tally/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19800,8 +19880,6 @@
"@slates-integrations/trayio/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/trello/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/triggercmd/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/tripadvisor/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19818,8 +19896,6 @@
"@slates-integrations/twilio-flex/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/twilio-sendgrid/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/twitch/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/twitter/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -19890,8 +19966,6 @@
"@slates-integrations/weaviate/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/webflow/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/webscraper-io/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/webscrapingai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19912,20 +19986,14 @@
"@slates-integrations/witai/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/wix/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/wiza/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/wolfram-alpha-api/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/woocommerce/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/woodpecker-co/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/word-online/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/wordpress/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/workable/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/workato/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19978,8 +20046,6 @@
"@slates-integrations/zoho-books/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates-integrations/zoho-crm/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates-integrations/zoho-desk/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
"@slates-integrations/zoho-inventory/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
@@ -19998,22 +20064,6 @@
"@slates-integrations/zyte-api/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
- "@slates/aws-sdk-http-handler/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates/google-people-recipes/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates/oauth-microsoft/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates/slack-tools/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
- "@slates/test/@slates/client": ["@slates/client@1.0.0-rc.12", "", { "dependencies": { "@slates/proto": "1.0.0-rc.11", "@slates/provider": "1.0.0-rc.15", "@slates/provider-handler": "1.0.0-rc.17" } }, "sha512-wMTBVWoUl0m9UFJeema27rB+9MQDrXPWZX0strrnwvQgZk3tCX+DL5LUK9y7QWZzBnVUhxTK+jnz+TyEEdr+9A=="],
-
- "@slates/test/@slates/profiles": ["@slates/profiles@1.0.0-rc.10", "", { "dependencies": { "@slates/client": "1.0.0-rc.12", "@slates/proto": "1.0.0-rc.11" } }, "sha512-/6ZxhIhUOsrYnbaF0Bd/I6xO5+6w93EcsHtVzKxLwMtaBqT5V4YurMkseQvnT3Y4V9bBh/W2L8nwImd4y2iWcg=="],
-
- "@slates/test/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates/tool-recipes/slates": ["slates@1.0.0-rc.14", "", { "dependencies": { "@slates/provider": "1.0.0-rc.15" } }, "sha512-TDfy7f9eJPCS5IpTwBq0jDOt5azw283YTt7vLTUPKoF4Cx6D6I7EZkV73NoUsL3qWnCQ0KY+vpH+UFGdnXzDtw=="],
-
"@slates/tsconfig/@types/node": ["@types/node@22.19.19", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew=="],
"@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
@@ -20090,8 +20140,6 @@
"@lowerdeck/testing-tools/vite/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="],
- "@slates-integrations/1password/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/21risk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/2chat/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20108,8 +20156,6 @@
"@slates-integrations/acculynx/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/activecampaign/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/activetrail/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/acuity-scheduling/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20120,16 +20166,12 @@
"@slates-integrations/adobe-creative-cloud/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/adobe-sign/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/adrapid/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/adyntel/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/aeroleads/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/affinda/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/affinity/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/agencyzoom/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20182,8 +20224,6 @@
"@slates-integrations/amcards/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/amplitude/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/anchor-browser/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/anonyflow/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20198,8 +20238,6 @@
"@slates-integrations/api-sports/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/api2pdf/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/apibible/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/apiflash/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20226,40 +20264,22 @@
"@slates-integrations/aryn/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/asana/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/ascora/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/ashby/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/assemblyai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/astica-ai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/async-interview/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/attio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/auth0/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/autobound/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/aws-cognito/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/aws-dynamodb/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/aws-lambda/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/aws-s3/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/aws-ses/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/aws-sns/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/aws-sqs/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/aws-transcribe/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/ayrshare/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/azure-blob-storage/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20270,8 +20290,6 @@
"@slates-integrations/azure-repos/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/azure-speech/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/backendless/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/bamboohr/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20308,8 +20326,6 @@
"@slates-integrations/bidsketch/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/bigcommerce/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/bigdatacloud/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/bigmailer/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20318,8 +20334,6 @@
"@slates-integrations/bigpictureio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/bigquery/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/bitquery/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/bitwarden/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20358,22 +20372,14 @@
"@slates-integrations/bouncer/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/box/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/boxhero/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/braintree/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/brandfetch/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/braze/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/breathe-hr/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/breeze/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/brevo/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/brex/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/bright-data/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20382,10 +20388,6 @@
"@slates-integrations/browseai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/browserbase/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/browserless/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/btcpay-server/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/bubble-plan/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20414,8 +20416,6 @@
"@slates-integrations/cabinpanda/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/calcom/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/calendarhero/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/callerapi/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20476,8 +20476,6 @@
"@slates-integrations/classmarker/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/clearbit/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/clearout/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/clickhouse/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20486,8 +20484,6 @@
"@slates-integrations/clicksend/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/clickup/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/clientary/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/clockify/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20498,8 +20494,6 @@
"@slates-integrations/cloudconvert/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/cloudflare-workers/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/cloudflare/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/cloudinary/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20508,8 +20502,6 @@
"@slates-integrations/coassemble/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/coda/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/codacy/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/codemagic/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20518,10 +20510,6 @@
"@slates-integrations/cody/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/cohere/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/coinbase/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/coinmarketcal/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/coinmarketcap/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20544,8 +20532,6 @@
"@slates-integrations/convertapi/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/convertkit/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/convex/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/conveyor/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20562,8 +20548,6 @@
"@slates-integrations/craftmypdf/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/crisp/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/crowdin/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/crowterminal/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20580,8 +20564,6 @@
"@slates-integrations/cursor/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/customerio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/customgpt/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/customjs/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20602,12 +20584,6 @@
"@slates-integrations/databox/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/databricks/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/datadog/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/dataforseo/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/datagma/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/datarobot/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20624,12 +20600,8 @@
"@slates-integrations/deel/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/deepgram/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/deepimage/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/deepseek/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/delighted/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/demio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20654,22 +20626,16 @@
"@slates-integrations/dock-labs-truvera/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/docker-hub/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/docmosis/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/docnify/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/docparser/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/docraptor/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/docsautomator/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/docsbot-ai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/docsumo/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/docugenerate/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/documenso/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20682,8 +20648,6 @@
"@slates-integrations/docuseal/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/docusign/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/doodle/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/doppler-marketing-automation/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20700,16 +20664,12 @@
"@slates-integrations/dreamstudio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/drift/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/drip/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/dripcel/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/dromo/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/dropbox/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/dropcontact/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/dub/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20732,8 +20692,6 @@
"@slates-integrations/elasticsearch/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/elevenlabs/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/elevenreader/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/elorus/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20782,8 +20740,6 @@
"@slates-integrations/everhour/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/evernote/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/eversign/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/exa/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20848,8 +20804,6 @@
"@slates-integrations/fluxguard/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/flyio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/folk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/follow-up-boss/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20874,18 +20828,8 @@
"@slates-integrations/freshbooks/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/freshdesk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/freshsales/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/freshservice/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/front/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/fullenrich/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/fullstory/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/gagelist/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/gamma/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -20994,8 +20938,6 @@
"@slates-integrations/gosquared/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/grafana/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/grafbase/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/graphhopper/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21006,12 +20948,8 @@
"@slates-integrations/grist/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/groqcloud/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/gtmetrix/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/gumroad/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/gusto/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/habitica/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21036,10 +20974,6 @@
"@slates-integrations/helloleads/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/hellosign/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/help-scout/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/helpdesk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/helpwise/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21068,8 +21002,6 @@
"@slates-integrations/hootsuite/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/hotjar/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/hotspotsystem/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/html-to-image/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21078,8 +21010,6 @@
"@slates-integrations/hubspot/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/hugging-face/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/humanitix/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/humanloop/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21142,8 +21072,6 @@
"@slates-integrations/item/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/iterable/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/jenkins/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/jigsawstack/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21166,14 +21094,8 @@
"@slates-integrations/keyword/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/kibana/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/kickbox/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/kit/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/klaviyo/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/klazify/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/klipfolio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21188,8 +21110,6 @@
"@slates-integrations/krakenio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/kubernetes/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/l2s/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/la-growth-machine/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21198,8 +21118,6 @@
"@slates-integrations/landbot/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/langbase/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/laposta/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/lastpass/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21220,8 +21138,6 @@
"@slates-integrations/lemlist/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/lemon-squeezy/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/lessonspace/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/lever/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21272,8 +21188,6 @@
"@slates-integrations/loyverse/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/magento/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/magnetic/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/mailbluster/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21286,12 +21200,8 @@
"@slates-integrations/mailercloud/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/mailerlite/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/mailersend/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/mailgun/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/mailsoftly/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/mailsso/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21322,8 +21232,6 @@
"@slates-integrations/membervault/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/meta-ads/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/metabase/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/metatextai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21336,20 +21244,14 @@
"@slates-integrations/microsoft-teams/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/midjourney/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/minerstat/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/miro/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/missive/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/mistral-ai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/mixmax/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/mixpanel/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/mocean/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/moco/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21358,14 +21260,8 @@
"@slates-integrations/modelry/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/mondaycom/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/moneybird/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/mongodb-atlas/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/mongodb/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/moonclerk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/moosend/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21386,22 +21282,16 @@
"@slates-integrations/mxtoolbox/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/mysql/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/n8n/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/nango/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/nanonets/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/nasa/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/nasdaq/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/needle/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/neon/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/netsuite/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/neuronwriter/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21410,8 +21300,6 @@
"@slates-integrations/neverbounce/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/new-relic/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/newsapi/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/nextdns/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21442,18 +21330,10 @@
"@slates-integrations/nutshell/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/ocr-web-service/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/ocrspace/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/odoo/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/oksign/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/okta/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/ollama/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/omnisend/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/onedesk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21474,14 +21354,10 @@
"@slates-integrations/openperplex/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/openrouter/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/opensea/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/openweathermap/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/opsgenie/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/optimizely/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/optimoroute/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21494,10 +21370,6 @@
"@slates-integrations/page-x/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/pagerduty/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/pandadoc/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/paperform/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/papertrail/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21526,26 +21398,14 @@
"@slates-integrations/paystack/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/pdf-apiio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/pdf4me/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/pdfco/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/pdfless/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/pdfmonkey/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/pendo/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/penpot/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/people-data-labs/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/perigon/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/perplexity-ai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/persistiq/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/persona/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21560,8 +21420,6 @@
"@slates-integrations/pilvio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/pinecone/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/pingdom/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/pipeline-crm/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21574,8 +21432,6 @@
"@slates-integrations/plain/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/planetscale/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/planly/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/planyo-online-booking/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21602,12 +21458,8 @@
"@slates-integrations/postgrid/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/posthog/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/postman/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/postmark/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/power-bi/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/powerpoint-online/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21656,8 +21508,6 @@
"@slates-integrations/ragie/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/railway/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/raisely/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/ramp/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21674,8 +21524,6 @@
"@slates-integrations/reddit-ads/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/redis/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/referralrock/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/refiner/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21688,20 +21536,14 @@
"@slates-integrations/removebg/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/render/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/renderform/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/rentman/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/repairshopr/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/replicate/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/replyio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/resend/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/resistant-ai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/respondio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21788,8 +21630,6 @@
"@slates-integrations/securitytrails/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/segment/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/segmetrics/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/semantic-scholar/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21804,8 +21644,6 @@
"@slates-integrations/sendfox/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/sendgrid/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/sendlane/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/sendloop/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21830,8 +21668,6 @@
"@slates-integrations/servicem8/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/servicenow/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/sevdesk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/sharepoint/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21904,8 +21740,6 @@
"@slates-integrations/splitwise/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/splunk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/spoki/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/spondyr/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21916,14 +21750,8 @@
"@slates-integrations/sprout-social/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/square/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates-integrations/squarespace/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/sslmate-cert-spotter-api/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/stability-ai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/stack-ai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/stack-exchange/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21964,8 +21792,6 @@
"@slates-integrations/suitedash/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/supabase/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/supadata/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/superchat/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -21990,8 +21816,6 @@
"@slates-integrations/tableau/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/taggun/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/talenthr/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/tally/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -22084,8 +21908,6 @@
"@slates-integrations/trayio/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/trello/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/triggercmd/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/tripadvisor/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -22100,8 +21922,6 @@
"@slates-integrations/twilio-flex/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/twilio-sendgrid/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/twitch/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/twocaptcha/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -22166,8 +21986,6 @@
"@slates-integrations/weaviate/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/webflow/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/webscraper-io/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/webscrapingai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -22188,20 +22006,14 @@
"@slates-integrations/witai/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/wix/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/wiza/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/wolfram-alpha-api/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/woocommerce/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/woodpecker-co/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/word-online/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/wordpress/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/workable/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/workato/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -22244,8 +22056,6 @@
"@slates-integrations/zoho-books/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates-integrations/zoho-crm/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"@slates-integrations/zoho-desk/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
"@slates-integrations/zoho-inventory/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
@@ -22264,22 +22074,6 @@
"@slates-integrations/zyte-api/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
- "@slates/aws-sdk-http-handler/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates/google-people-recipes/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates/oauth-microsoft/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates/slack-tools/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
- "@slates/test/@slates/client/@slates/proto": ["@slates/proto@1.0.0-rc.11", "", { "dependencies": { "@lowerdeck/emitter": "^1.0.4", "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-g/MMRAciX5D0UmEiwBy9656qEaade2ZMysIRMYoL64PzwfLC2rorOuTfE+kfBhNfH1IeA9UgmfVT8+8vGbQv3Q=="],
-
- "@slates/test/@slates/client/@slates/provider-handler": ["@slates/provider-handler@1.0.0-rc.17", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@slates/proto": "1.0.0-rc.11", "@slates/provider": "1.0.0-rc.15", "zod": "^4.2.1" } }, "sha512-DrAHi9x83w5vmhgyPwt8OT2HU1lxDFMAQquvHy54f1h0IjSjjQnNgOcbf7eq4wy1sHgRkKXtVSbQ5d64fTIW3w=="],
-
- "@slates/test/@slates/profiles/@slates/proto": ["@slates/proto@1.0.0-rc.11", "", { "dependencies": { "@lowerdeck/emitter": "^1.0.4", "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-g/MMRAciX5D0UmEiwBy9656qEaade2ZMysIRMYoL64PzwfLC2rorOuTfE+kfBhNfH1IeA9UgmfVT8+8vGbQv3Q=="],
-
- "@slates/tool-recipes/slates/@slates/provider": ["@slates/provider@1.0.0-rc.15", "", { "dependencies": { "@lowerdeck/error": "^1.1.0", "@toon-format/toon": "^2.1.0", "axios": "^1.13.2", "zod": "^4.2.1" } }, "sha512-l28Ut+NsRYZ5X7Ml+ERaTFvOJe0G72SGJiHV4DNgFdeETjjDDBOKcj/OwIBQN0l0s6AxxqiXQIyZeQsRaDnDlA=="],
-
"cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
diff --git a/integrations/1password/README.md b/integrations/1password/README.md
index 0add3f0775..0fa1b74f94 100644
--- a/integrations/1password/README.md
+++ b/integrations/1password/README.md
@@ -1,6 +1,6 @@
#
1password
-Manage passwords, secrets, and sensitive credentials stored in encrypted vaults. Retrieve secrets using reference URIs, create/read/update/delete vault items including API keys, passwords, SSH keys, and file attachments. Generate passwords with configurable recipes. Share items securely with expiration and recipient controls. Manage vaults, users, and groups with permissions. Monitor account activity through audit events, item usage events, and sign-in attempt events for SIEM integration.
+Manage passwords, secrets, and sensitive credentials stored in encrypted vaults through the 1Password Connect Server API. Create, read, update, delete, list, and search vault items; inspect vault metadata; download item file attachments as Slate attachments; generate passwords; check Connect server health; and monitor account activity through audit, item usage, and sign-in events.
## Tools
@@ -12,22 +12,46 @@ Create a new item in a 1Password vault. Supports creating logins, passwords, API
Delete an item from a 1Password vault. This permanently removes the item and cannot be undone. To archive an item instead, use the Update Item tool with a patch operation to set the state.
+### Get File Metadata
+
+Retrieve metadata for a specific file attachment on a 1Password item without downloading file bytes.
+
### Generate Password
Generate a secure password using 1Password's password generator. Creates a temporary PASSWORD item in the specified vault with a generated password field, retrieves the generated value, then deletes the temporary item. Supports configuring length, character sets, and excluded characters.
### Get File Content
-Retrieve the content of a file attachment stored on a 1Password item. Use the Get Item tool first to discover file IDs and names attached to an item. Returns the file content as text.
+Download the content of a file attachment stored on a 1Password item. Use Get Item or List Files first to discover file IDs and names attached to an item. Returns file bytes through a Slate attachment and keeps structured output to metadata.
### Get Item
Retrieve the full details of a specific item from a vault, including all fields, sections, files, and metadata. Use this to read passwords, API keys, notes, and other secrets stored in 1Password.
+### Get Prometheus Metrics
+
+Retrieve Prometheus metrics from the 1Password Connect server. Returns metrics text through a Slate attachment.
+
+### Get Server Heartbeat
+
+Ping the 1Password Connect server heartbeat endpoint to verify the server is reachable.
+
### Get Server Health
Check the health and status of the 1Password Connect server, including its version and the status of dependent services. Useful for verifying connectivity and diagnosing issues.
+### Get Vault
+
+Retrieve metadata for a specific vault accessible to the Connect token.
+
+### List API Activity
+
+List recent API activity recorded by the 1Password Connect server, including action, result, actor, and affected resource metadata.
+
+### List Files
+
+List file attachments on a 1Password item. Returns metadata only.
+
### List Items
List items stored in a specific vault. Returns item summaries including titles, categories, tags, and URLs. Use the filter parameter to search by title or tag. For full item details including field values, use the Get Item tool.
diff --git a/integrations/1password/docs/SPEC.md b/integrations/1password/docs/SPEC.md
index 77492e0eab..d577fb8552 100644
--- a/integrations/1password/docs/SPEC.md
+++ b/integrations/1password/docs/SPEC.md
@@ -18,6 +18,7 @@ Each service account has a service account token that you can provide as an envi
- Service account permissions, vault access, and Environment access are immutable. To change them, you must create a new service account.
- Service accounts can't access your built-in Personal, Private, or Employee vault.
- Created via 1Password.com (Developer > Directory) or via 1Password CLI.
+- 1Password service accounts are exposed through the 1Password CLI and SDKs, not the Connect REST endpoints used by this integration's item, vault, file, and server tools. Those tools require the Connect Server Token auth method and a Connect server URL.
### Connect Server Token (Connect REST API)
@@ -45,11 +46,11 @@ Retrieve individual secret values stored in 1Password using secret reference URI
### Item Management
-Full programmatic access to 1Password items, including creating, reading, updating, deleting, listing, and sharing information stored in vaults. Supported field types include API Keys, Passwords, Concealed fields, Text fields, Notes, SSH private keys, One-time passwords, URLs, Credit card numbers, Emails, File attachments, Document items, Passkeys, and more. Items can also be archived.
+Programmatic access to 1Password Connect vault items, including creating, reading, replacing, patching, deleting, listing, and searching items stored in accessible vaults. Supported field types include passwords, concealed fields, text fields, notes, one-time passwords, URLs, emails, and other Connect item fields. Items can be modified with JSON Patch operations where the Connect API supports them.
### Item Sharing
-Securely share items with anyone, whether or not they have a 1Password account. Creates shareable links with configurable expiration (1 hour to 30 days), optional recipient restrictions by email/domain, and one-time view settings. If you have a 1Password Business account, it will also validate the settings against the item sharing policy set by your account owner or administrator.
+1Password service accounts and SDKs support item sharing, but the Connect REST API does not expose item sharing. This integration does not currently provide an item sharing tool.
### Password Generation
@@ -57,17 +58,17 @@ Generate passwords using a PIN, Random, or Memorable password recipe. PIN codes
### Vault Management
-Manage your team's vaults and the permissions groups have in them. Operations include retrieving, creating, updating, deleting, and listing vaults, as well as managing group vault permissions and user vault permissions.
+Retrieve and list vaults accessible to the Connect token. Creating, updating, deleting, and permission management for vaults are service-account/SDK or CLI workflows and are not exposed by this Connect-focused integration.
### User and Group Management
-Provision users, retrieve users, list users, suspend users, retrieve groups, list groups, create groups, and update group membership.
+1Password SDKs list user and group capabilities, but these are not exposed through the Connect REST API tools in this integration.
- These operations typically require desktop app authentication rather than service account authentication.
### File Management
-Store and retrieve file attachments and document items in vaults. Files can be attached to items and shared via item sharing links.
+List file attachments on items, retrieve file metadata, and download file contents through Slate attachments. Connect exposes existing file attachments but does not provide an upload endpoint.
### Events Reporting
diff --git a/integrations/1password/package.json b/integrations/1password/package.json
index 7af8909df2..275c055385 100644
--- a/integrations/1password/package.json
+++ b/integrations/1password/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --config vitest.config.ts --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
- "typescript": "^5"
+ "@slates/test": "1.0.0-rc.9",
+ "typescript": "^5",
+ "vitest": "^3.1.2"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.7"
}
diff --git a/integrations/1password/slate.json b/integrations/1password/slate.json
index 71c9b75a9f..3e5b6a8b1a 100644
--- a/integrations/1password/slate.json
+++ b/integrations/1password/slate.json
@@ -1,15 +1,13 @@
{
"name": "@metorial/1password",
- "description": "Manage passwords, secrets, and sensitive credentials stored in encrypted vaults. Retrieve secrets using reference URIs, create/read/update/delete vault items including API keys, passwords, SSH keys, and file attachments. Generate passwords with configurable recipes. Share items securely with expiration and recipient controls. Manage vaults, users, and groups with permissions. Monitor account activity through audit events, item usage events, and sign-in attempt events for SIEM integration.",
+ "description": "Manage passwords, secrets, and sensitive credentials stored in encrypted vaults through 1Password Connect. Create, read, update, delete, list, and search vault items; inspect vault metadata; retrieve file attachments through Slate attachments; generate passwords; check Connect server health; and monitor audit, item usage, and sign-in events.",
"categories": ["apis-and-http-requests", "security"],
"skills": [
- "resolve secrets by reference",
"manage vault items",
+ "inspect vault metadata",
"generate passwords",
- "share items securely",
- "manage vaults and permissions",
- "manage users and groups",
- "store and retrieve files",
+ "download file attachments",
+ "monitor connect server health",
"monitor audit events",
"track sign-in attempts",
"track item usage events"
diff --git a/integrations/1password/src/index.ts b/integrations/1password/src/index.ts
index 817f81c8b3..d24af0cca5 100644
--- a/integrations/1password/src/index.ts
+++ b/integrations/1password/src/index.ts
@@ -5,8 +5,14 @@ import {
deleteItem,
generatePassword,
getFileContent,
+ getFileMetadata,
getItem,
+ getPrometheusMetrics,
getServerHealth,
+ getServerHeartbeat,
+ getVault,
+ listApiActivity,
+ listFiles,
listItems,
listVaults,
searchItems,
@@ -23,6 +29,7 @@ export let provider = Slate.create({
spec,
tools: [
listVaults,
+ getVault,
listItems,
searchItems,
getItem,
@@ -30,8 +37,13 @@ export let provider = Slate.create({
updateItem,
deleteItem,
generatePassword,
+ listFiles,
+ getFileMetadata,
getFileContent,
- getServerHealth
+ listApiActivity,
+ getServerHeartbeat,
+ getServerHealth,
+ getPrometheusMetrics
],
triggers: [
inboundWebhook,
diff --git a/integrations/1password/src/lib/client.ts b/integrations/1password/src/lib/client.ts
index 8a72746543..ab7640b1eb 100644
--- a/integrations/1password/src/lib/client.ts
+++ b/integrations/1password/src/lib/client.ts
@@ -1,4 +1,5 @@
import { createAxios } from 'slates';
+import { onePasswordApiError } from './errors';
export interface VaultSummary {
id: string;
@@ -44,7 +45,8 @@ export interface FileSummary {
id: string;
name: string;
size: number;
- contentPath: string;
+ contentPath?: string;
+ content_path?: string;
section?: { id: string; label?: string };
}
@@ -88,30 +90,48 @@ export interface PatchOperation {
}
export class ConnectClient {
- private http;
+ private apiHttp;
+ private serverHttp;
constructor(config: { token: string; serverUrl: string }) {
- this.http = createAxios({
- baseURL: `${config.serverUrl.replace(/\/+$/, '')}/v1`,
+ let serverUrl = config.serverUrl.replace(/\/+$/, '');
+ let headers = {
+ Authorization: `Bearer ${config.token}`,
+ 'Content-Type': 'application/json'
+ };
+
+ this.apiHttp = createAxios({
+ baseURL: `${serverUrl}/v1`,
+ headers
+ });
+
+ this.serverHttp = createAxios({
+ baseURL: serverUrl,
headers: {
- Authorization: `Bearer ${config.token}`,
- 'Content-Type': 'application/json'
+ ...headers
}
});
}
+ private async request(operation: string, run: () => Promise<{ data: T }>): Promise {
+ try {
+ let res = await run();
+ return res.data;
+ } catch (error) {
+ throw onePasswordApiError(error, operation);
+ }
+ }
+
// ---- Vaults ----
async listVaults(filter?: string): Promise {
let params: Record = {};
if (filter) params.filter = filter;
- let res = await this.http.get('/vaults', { params });
- return res.data;
+ return this.request('list vaults', () => this.apiHttp.get('/vaults', { params }));
}
async getVault(vaultId: string): Promise {
- let res = await this.http.get(`/vaults/${vaultId}`);
- return res.data;
+ return this.request('get vault', () => this.apiHttp.get(`/vaults/${vaultId}`));
}
// ---- Items ----
@@ -119,23 +139,27 @@ export class ConnectClient {
async listItems(vaultId: string, filter?: string): Promise {
let params: Record = {};
if (filter) params.filter = filter;
- let res = await this.http.get(`/vaults/${vaultId}/items`, { params });
- return res.data;
+ return this.request('list items', () =>
+ this.apiHttp.get(`/vaults/${vaultId}/items`, { params })
+ );
}
async getItem(vaultId: string, itemId: string): Promise {
- let res = await this.http.get(`/vaults/${vaultId}/items/${itemId}`);
- return res.data;
+ return this.request('get item', () =>
+ this.apiHttp.get(`/vaults/${vaultId}/items/${itemId}`)
+ );
}
async createItem(vaultId: string, item: CreateItemInput): Promise {
- let res = await this.http.post(`/vaults/${vaultId}/items`, item);
- return res.data;
+ return this.request('create item', () =>
+ this.apiHttp.post(`/vaults/${vaultId}/items`, item)
+ );
}
async replaceItem(vaultId: string, itemId: string, item: FullItem): Promise {
- let res = await this.http.put(`/vaults/${vaultId}/items/${itemId}`, item);
- return res.data;
+ return this.request('replace item', () =>
+ this.apiHttp.put(`/vaults/${vaultId}/items/${itemId}`, item)
+ );
}
async patchItem(
@@ -143,29 +167,60 @@ export class ConnectClient {
itemId: string,
operations: PatchOperation[]
): Promise {
- let res = await this.http.patch(`/vaults/${vaultId}/items/${itemId}`, operations);
- return res.data;
+ return this.request('patch item', () =>
+ this.apiHttp.patch(`/vaults/${vaultId}/items/${itemId}`, operations)
+ );
}
async deleteItem(vaultId: string, itemId: string): Promise {
- await this.http.delete(`/vaults/${vaultId}/items/${itemId}`);
+ await this.request('delete item', () =>
+ this.apiHttp.delete(`/vaults/${vaultId}/items/${itemId}`)
+ );
}
// ---- Files ----
- async getFileContent(vaultId: string, itemId: string, fileId: string): Promise {
- let res = await this.http.get(
- `/vaults/${vaultId}/items/${itemId}/files/${fileId}/content`,
- {
- responseType: 'text'
- }
+ async listFiles(vaultId: string, itemId: string): Promise {
+ return this.request('list files', () =>
+ this.apiHttp.get(`/vaults/${vaultId}/items/${itemId}/files`)
);
- return res.data;
}
- async listFiles(vaultId: string, itemId: string): Promise {
- let res = await this.http.get(`/vaults/${vaultId}/items/${itemId}/files`);
- return res.data;
+ async getFile(vaultId: string, itemId: string, fileId: string): Promise {
+ return this.request('get file metadata', () =>
+ this.apiHttp.get(`/vaults/${vaultId}/items/${itemId}/files/${fileId}`)
+ );
+ }
+
+ async getFileContent(
+ vaultId: string,
+ itemId: string,
+ fileId: string
+ ): Promise {
+ try {
+ let res = await this.apiHttp.get(
+ `/vaults/${vaultId}/items/${itemId}/files/${fileId}/content`,
+ {
+ responseType: 'arraybuffer'
+ }
+ );
+ let raw = res.data;
+ let buffer = Buffer.isBuffer(raw)
+ ? raw
+ : Buffer.from(raw instanceof ArrayBuffer ? new Uint8Array(raw) : raw);
+ let contentType =
+ typeof res.headers?.['content-type'] === 'string'
+ ? res.headers['content-type']
+ : 'application/octet-stream';
+
+ return {
+ contentBase64: buffer.toString('base64'),
+ contentType,
+ byteLength: buffer.byteLength
+ };
+ } catch (error) {
+ throw onePasswordApiError(error, 'get file content');
+ }
}
// ---- Activity ----
@@ -174,19 +229,55 @@ export class ConnectClient {
let params: Record = {};
if (limit !== undefined) params.limit = limit;
if (offset !== undefined) params.offset = offset;
- let res = await this.http.get('/activity', { params });
- return res.data;
+ return this.request('list API activity', () => this.apiHttp.get('/activity', { params }));
}
// ---- Health ----
async getServerHealth(): Promise {
- let res = await this.http.get('/health');
- return res.data;
+ return this.request('get server health', () => this.serverHttp.get('/health'));
}
+
+ async getServerHeartbeat(): Promise {
+ try {
+ let res = await this.serverHttp.get('/heartbeat');
+ return {
+ ok: res.status >= 200 && res.status < 300,
+ status: res.status
+ };
+ } catch (error) {
+ throw onePasswordApiError(error, 'get server heartbeat');
+ }
+ }
+
+ async getPrometheusMetrics(): Promise {
+ try {
+ let res = await this.serverHttp.get('/metrics', { responseType: 'text' });
+ let content = typeof res.data === 'string' ? res.data : String(res.data ?? '');
+ let contentType =
+ typeof res.headers?.['content-type'] === 'string'
+ ? res.headers['content-type']
+ : 'text/plain; version=0.0.4';
+
+ return {
+ content,
+ contentType,
+ byteLength: Buffer.byteLength(content)
+ };
+ } catch (error) {
+ throw onePasswordApiError(error, 'get Prometheus metrics');
+ }
+ }
+}
+
+export interface DownloadedFileContent {
+ contentBase64: string;
+ contentType: string;
+ byteLength: number;
}
export interface ApiRequest {
+ requestID?: string;
requestId: string;
timestamp: string;
action: string;
@@ -196,6 +287,7 @@ export interface ApiRequest {
account: string;
jti: string;
userAgent: string;
+ ip?: string;
requestIp: string;
};
resource: {
@@ -215,3 +307,14 @@ export interface ServerHealth {
message?: string;
}>;
}
+
+export interface ServerHeartbeat {
+ ok: boolean;
+ status: number;
+}
+
+export interface PrometheusMetrics {
+ content: string;
+ contentType: string;
+ byteLength: number;
+}
diff --git a/integrations/1password/src/lib/connect-tool.ts b/integrations/1password/src/lib/connect-tool.ts
new file mode 100644
index 0000000000..5c87ac4182
--- /dev/null
+++ b/integrations/1password/src/lib/connect-tool.ts
@@ -0,0 +1,31 @@
+import { createApiServiceError } from 'slates';
+import { ConnectClient } from './client';
+
+type ConnectToolContext = {
+ auth: {
+ token: string;
+ authType?: string;
+ };
+ config: {
+ connectServerUrl?: string;
+ };
+};
+
+export let createConnectClient = (ctx: ConnectToolContext) => {
+ if (ctx.auth.authType !== 'connect') {
+ throw createApiServiceError(
+ 'This tool requires the 1Password Connect Server Token auth method. Service Account and Events API tokens cannot call the Connect REST API.'
+ );
+ }
+
+ if (!ctx.config.connectServerUrl) {
+ throw createApiServiceError(
+ 'Connect server URL is required. Set connectServerUrl in the integration configuration.'
+ );
+ }
+
+ return new ConnectClient({
+ token: ctx.auth.token,
+ serverUrl: ctx.config.connectServerUrl
+ });
+};
diff --git a/integrations/1password/src/lib/errors.ts b/integrations/1password/src/lib/errors.ts
new file mode 100644
index 0000000000..95cb9db8f2
--- /dev/null
+++ b/integrations/1password/src/lib/errors.ts
@@ -0,0 +1,21 @@
+import { buildApiServiceError } from 'slates';
+
+export let onePasswordApiError = (error: unknown, operation = 'request') =>
+ buildApiServiceError(error, {
+ providerLabel: '1Password',
+ operation,
+ reason: 'onepassword_api_error',
+ detailKeys: ['message', 'error', 'error_description'],
+ includeNumbers: false,
+ nestedKeys: [],
+ extractStatus: (input, response, helpers) =>
+ response?.status ??
+ (helpers.isRecord(input) && typeof input.status === 'number'
+ ? input.status
+ : undefined) ??
+ (helpers.isRecord(input) &&
+ helpers.isRecord(input.data) &&
+ typeof input.data.status === 'number'
+ ? input.data.status
+ : undefined)
+ });
diff --git a/integrations/1password/src/lib/events-client.ts b/integrations/1password/src/lib/events-client.ts
index 883ed07df2..806f945790 100644
--- a/integrations/1password/src/lib/events-client.ts
+++ b/integrations/1password/src/lib/events-client.ts
@@ -1,4 +1,5 @@
import { createAxios } from 'slates';
+import { onePasswordApiError } from './errors';
let EVENTS_API_BASE_URLS: Record = {
us: 'https://events.1password.com',
@@ -142,24 +143,36 @@ export class EventsClient {
async getAuditEvents(params: EventsCursorRequest): Promise> {
let body = this.buildRequestBody(params);
- let res = await this.http.post('/auditevents', body);
- return res.data;
+ try {
+ let res = await this.http.post('/auditevents', body);
+ return res.data;
+ } catch (error) {
+ throw onePasswordApiError(error, 'get audit events');
+ }
}
async getItemUsageEvents(
params: EventsCursorRequest
): Promise> {
let body = this.buildRequestBody(params);
- let res = await this.http.post('/itemusages', body);
- return res.data;
+ try {
+ let res = await this.http.post('/itemusages', body);
+ return res.data;
+ } catch (error) {
+ throw onePasswordApiError(error, 'get item usage events');
+ }
}
async getSignInAttemptEvents(
params: EventsCursorRequest
): Promise> {
let body = this.buildRequestBody(params);
- let res = await this.http.post('/signinattempts', body);
- return res.data;
+ try {
+ let res = await this.http.post('/signinattempts', body);
+ return res.data;
+ } catch (error) {
+ throw onePasswordApiError(error, 'get sign-in attempt events');
+ }
}
private buildRequestBody(params: EventsCursorRequest): Record {
diff --git a/integrations/1password/src/tools.schema.test.ts b/integrations/1password/src/tools.schema.test.ts
new file mode 100644
index 0000000000..36f4630271
--- /dev/null
+++ b/integrations/1password/src/tools.schema.test.ts
@@ -0,0 +1,4 @@
+import { describeMcpCompatibleToolSchemas } from '@slates/test';
+import { provider } from './index';
+
+describeMcpCompatibleToolSchemas('1Password tool input schemas', provider.actions);
diff --git a/integrations/1password/src/tools/create-item.ts b/integrations/1password/src/tools/create-item.ts
index 5212680b6b..925a54e12b 100644
--- a/integrations/1password/src/tools/create-item.ts
+++ b/integrations/1password/src/tools/create-item.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let createItem = SlateTool.create(spec, {
@@ -95,14 +95,7 @@ export let createItem = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
let sections = (ctx.input.sections || []).map(s => ({
id: s.sectionId,
diff --git a/integrations/1password/src/tools/delete-item.ts b/integrations/1password/src/tools/delete-item.ts
index 1422631d5e..e98033f7d2 100644
--- a/integrations/1password/src/tools/delete-item.ts
+++ b/integrations/1password/src/tools/delete-item.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let deleteItem = SlateTool.create(spec, {
@@ -26,14 +26,7 @@ export let deleteItem = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
ctx.progress('Deleting item...');
await client.deleteItem(ctx.input.vaultId, ctx.input.itemId);
diff --git a/integrations/1password/src/tools/generate-password.ts b/integrations/1password/src/tools/generate-password.ts
index 7d17942dae..b86ef8931c 100644
--- a/integrations/1password/src/tools/generate-password.ts
+++ b/integrations/1password/src/tools/generate-password.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let generatePassword = SlateTool.create(spec, {
@@ -46,14 +46,7 @@ export let generatePassword = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
let charSets = ctx.input.characterSets || ['LETTERS', 'DIGITS'];
diff --git a/integrations/1password/src/tools/get-file-content.ts b/integrations/1password/src/tools/get-file-content.ts
index 1c16745cf1..9929b5c5c5 100644
--- a/integrations/1password/src/tools/get-file-content.ts
+++ b/integrations/1password/src/tools/get-file-content.ts
@@ -1,14 +1,14 @@
-import { SlateTool } from 'slates';
+import { createBase64Attachment, SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let getFileContent = SlateTool.create(spec, {
name: 'Get File Content',
key: 'get_file_content',
- description: `Retrieve the content of a file attachment stored on a 1Password item. Use the Get Item tool first to discover file IDs and names attached to an item. Returns the file content as text.`,
+ description: `Download the content of a file attachment stored on a 1Password item. The file bytes are returned as a Slate attachment, with structured output limited to metadata.`,
instructions: [
- 'Use Get Item first to find the fileId of the attachment you want to retrieve.'
+ 'Use Get Item or List Files first to find the fileId of the attachment you want to retrieve.'
],
tags: {
readOnly: true
@@ -24,21 +24,16 @@ export let getFileContent = SlateTool.create(spec, {
.output(
z.object({
fileId: z.string().describe('ID of the file'),
- content: z.string().describe('Content of the file as text')
+ byteLength: z.number().describe('Decoded byte length of the returned attachment'),
+ mimeType: z.string().describe('MIME type of the returned attachment'),
+ attachmentCount: z.number().describe('Number of attachments returned')
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
ctx.progress('Retrieving file content...');
- let content = await client.getFileContent(
+ let file = await client.getFileContent(
ctx.input.vaultId,
ctx.input.itemId,
ctx.input.fileId
@@ -47,9 +42,12 @@ export let getFileContent = SlateTool.create(spec, {
return {
output: {
fileId: ctx.input.fileId,
- content
+ byteLength: file.byteLength,
+ mimeType: file.contentType,
+ attachmentCount: 1
},
- message: `Retrieved content for file \`${ctx.input.fileId}\` (${content.length} characters).`
+ attachments: [createBase64Attachment(file.contentBase64, file.contentType)],
+ message: `Retrieved file \`${ctx.input.fileId}\` as an attachment (${file.byteLength} bytes).`
};
})
.build();
diff --git a/integrations/1password/src/tools/get-file-metadata.ts b/integrations/1password/src/tools/get-file-metadata.ts
new file mode 100644
index 0000000000..cf1a09cd9e
--- /dev/null
+++ b/integrations/1password/src/tools/get-file-metadata.ts
@@ -0,0 +1,49 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { createConnectClient } from '../lib/connect-tool';
+import { spec } from '../spec';
+
+export let getFileMetadata = SlateTool.create(spec, {
+ name: 'Get File Metadata',
+ key: 'get_file_metadata',
+ description: `Retrieve metadata for a specific file attachment on a 1Password item without downloading the file content.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ vaultId: z.string().describe('ID of the vault containing the item'),
+ itemId: z.string().describe('ID of the item the file is attached to'),
+ fileId: z.string().describe('ID of the file attachment to retrieve')
+ })
+ )
+ .output(
+ z.object({
+ fileId: z.string().describe('Unique identifier of the file'),
+ name: z.string().describe('Filename'),
+ size: z.number().describe('File size in bytes'),
+ contentPath: z.string().optional().describe('API path to retrieve file content'),
+ sectionId: z.string().optional().describe('ID of the section containing the file'),
+ sectionLabel: z.string().optional().describe('Label of the section containing the file')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = createConnectClient(ctx);
+
+ ctx.progress('Fetching file metadata...');
+ let file = await client.getFile(ctx.input.vaultId, ctx.input.itemId, ctx.input.fileId);
+
+ return {
+ output: {
+ fileId: file.id,
+ name: file.name,
+ size: file.size,
+ contentPath: file.contentPath ?? file.content_path,
+ sectionId: file.section?.id,
+ sectionLabel: file.section?.label
+ },
+ message: `Retrieved metadata for file **${file.name}** (${file.size} bytes).`
+ };
+ })
+ .build();
diff --git a/integrations/1password/src/tools/get-item.ts b/integrations/1password/src/tools/get-item.ts
index 1d135e7a09..1ca41745b1 100644
--- a/integrations/1password/src/tools/get-item.ts
+++ b/integrations/1password/src/tools/get-item.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
let fieldSchema = z.object({
@@ -25,7 +25,7 @@ let fileSchema = z.object({
fileId: z.string().describe('Unique identifier of the file'),
name: z.string().describe('Filename'),
size: z.number().describe('File size in bytes'),
- contentPath: z.string().describe('API path to retrieve file content')
+ contentPath: z.string().optional().describe('API path to retrieve file content')
});
export let getItem = SlateTool.create(spec, {
@@ -71,14 +71,7 @@ export let getItem = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
ctx.progress('Fetching item details...');
let item = await client.getItem(ctx.input.vaultId, ctx.input.itemId);
@@ -99,7 +92,7 @@ export let getItem = SlateTool.create(spec, {
fileId: f.id,
name: f.name,
size: f.size,
- contentPath: f.contentPath
+ contentPath: f.contentPath ?? f.content_path
}));
return {
diff --git a/integrations/1password/src/tools/get-prometheus-metrics.ts b/integrations/1password/src/tools/get-prometheus-metrics.ts
new file mode 100644
index 0000000000..121b3ef7ca
--- /dev/null
+++ b/integrations/1password/src/tools/get-prometheus-metrics.ts
@@ -0,0 +1,38 @@
+import { createTextAttachment, SlateTool } from 'slates';
+import { z } from 'zod';
+import { createConnectClient } from '../lib/connect-tool';
+import { spec } from '../spec';
+
+export let getPrometheusMetrics = SlateTool.create(spec, {
+ name: 'Get Prometheus Metrics',
+ key: 'get_prometheus_metrics',
+ description: `Retrieve Prometheus metrics from the 1Password Connect server. Metrics text is returned as a Slate attachment with structured output limited to metadata.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(z.object({}))
+ .output(
+ z.object({
+ byteLength: z.number().describe('Byte length of the returned metrics attachment'),
+ mimeType: z.string().describe('MIME type of the returned metrics attachment'),
+ attachmentCount: z.number().describe('Number of attachments returned')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = createConnectClient(ctx);
+
+ ctx.progress('Fetching Prometheus metrics...');
+ let metrics = await client.getPrometheusMetrics();
+
+ return {
+ output: {
+ byteLength: metrics.byteLength,
+ mimeType: metrics.contentType,
+ attachmentCount: 1
+ },
+ attachments: [createTextAttachment(metrics.content, metrics.contentType)],
+ message: `Retrieved Prometheus metrics as an attachment (${metrics.byteLength} bytes).`
+ };
+ })
+ .build();
diff --git a/integrations/1password/src/tools/get-server-health.ts b/integrations/1password/src/tools/get-server-health.ts
index d5bc276742..2d92e40fd7 100644
--- a/integrations/1password/src/tools/get-server-health.ts
+++ b/integrations/1password/src/tools/get-server-health.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let getServerHealth = SlateTool.create(spec, {
@@ -28,14 +28,7 @@ export let getServerHealth = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
ctx.progress('Checking server health...');
let health = await client.getServerHealth();
diff --git a/integrations/1password/src/tools/get-server-heartbeat.ts b/integrations/1password/src/tools/get-server-heartbeat.ts
new file mode 100644
index 0000000000..6c95e9c658
--- /dev/null
+++ b/integrations/1password/src/tools/get-server-heartbeat.ts
@@ -0,0 +1,32 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { createConnectClient } from '../lib/connect-tool';
+import { spec } from '../spec';
+
+export let getServerHeartbeat = SlateTool.create(spec, {
+ name: 'Get Server Heartbeat',
+ key: 'get_server_heartbeat',
+ description: `Ping the 1Password Connect server heartbeat endpoint to verify that the server process is reachable.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(z.object({}))
+ .output(
+ z.object({
+ ok: z.boolean().describe('Whether the heartbeat endpoint returned a 2xx response'),
+ status: z.number().describe('HTTP status returned by the heartbeat endpoint')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = createConnectClient(ctx);
+
+ ctx.progress('Checking server heartbeat...');
+ let heartbeat = await client.getServerHeartbeat();
+
+ return {
+ output: heartbeat,
+ message: `Connect server heartbeat returned HTTP ${heartbeat.status}.`
+ };
+ })
+ .build();
diff --git a/integrations/1password/src/tools/get-vault.ts b/integrations/1password/src/tools/get-vault.ts
new file mode 100644
index 0000000000..17551a0552
--- /dev/null
+++ b/integrations/1password/src/tools/get-vault.ts
@@ -0,0 +1,53 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { createConnectClient } from '../lib/connect-tool';
+import { spec } from '../spec';
+
+export let getVault = SlateTool.create(spec, {
+ name: 'Get Vault',
+ key: 'get_vault',
+ description: `Retrieve metadata for a specific 1Password vault accessible to the Connect token, including item count, vault type, and content versions.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ vaultId: z.string().describe('ID of the vault to retrieve')
+ })
+ )
+ .output(
+ z.object({
+ vaultId: z.string().describe('Unique identifier of the vault'),
+ name: z.string().describe('Name of the vault'),
+ description: z.string().describe('Description of the vault'),
+ itemCount: z.number().describe('Number of active items in the vault'),
+ type: z.string().describe('Type of vault'),
+ attributeVersion: z.number().describe('Version of the vault metadata'),
+ contentVersion: z.number().describe('Version of the vault contents'),
+ createdAt: z.string().describe('When the vault was created'),
+ updatedAt: z.string().describe('When the vault was last updated')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = createConnectClient(ctx);
+
+ ctx.progress('Fetching vault...');
+ let vault = await client.getVault(ctx.input.vaultId);
+
+ return {
+ output: {
+ vaultId: vault.id,
+ name: vault.name,
+ description: vault.description || '',
+ itemCount: vault.items,
+ type: vault.type,
+ attributeVersion: vault.attributeVersion,
+ contentVersion: vault.contentVersion,
+ createdAt: vault.createdAt,
+ updatedAt: vault.updatedAt
+ },
+ message: `Retrieved vault **${vault.name}** (${vault.items} item(s)).`
+ };
+ })
+ .build();
diff --git a/integrations/1password/src/tools/index.ts b/integrations/1password/src/tools/index.ts
index 5db69bde1a..94198167b8 100644
--- a/integrations/1password/src/tools/index.ts
+++ b/integrations/1password/src/tools/index.ts
@@ -2,8 +2,14 @@ export * from './create-item';
export * from './delete-item';
export * from './generate-password';
export * from './get-file-content';
+export * from './get-file-metadata';
export * from './get-item';
+export * from './get-prometheus-metrics';
export * from './get-server-health';
+export * from './get-server-heartbeat';
+export * from './get-vault';
+export * from './list-api-activity';
+export * from './list-files';
export * from './list-items';
export * from './list-vaults';
export * from './search-items';
diff --git a/integrations/1password/src/tools/list-api-activity.ts b/integrations/1password/src/tools/list-api-activity.ts
new file mode 100644
index 0000000000..dce27170ff
--- /dev/null
+++ b/integrations/1password/src/tools/list-api-activity.ts
@@ -0,0 +1,81 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { createConnectClient } from '../lib/connect-tool';
+import { spec } from '../spec';
+
+export let listApiActivity = SlateTool.create(spec, {
+ name: 'List API Activity',
+ key: 'list_api_activity',
+ description: `List recent API activity recorded by the 1Password Connect server, including action, result, actor, and affected resource metadata.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ limit: z
+ .number()
+ .int()
+ .min(1)
+ .max(100)
+ .optional()
+ .describe('Maximum number of activity records to return'),
+ offset: z
+ .number()
+ .int()
+ .min(0)
+ .optional()
+ .describe('Offset into the activity collection')
+ })
+ )
+ .output(
+ z.object({
+ activities: z.array(
+ z.object({
+ requestId: z.string().describe('Unique identifier for the API request'),
+ timestamp: z.string().describe('When the request occurred'),
+ action: z.string().describe('Action performed by the request'),
+ result: z.string().describe('Result of the request'),
+ actorId: z.string().optional().describe('Connect server actor ID'),
+ accountId: z.string().optional().describe('1Password account ID'),
+ userAgent: z.string().optional().describe('User agent for the request'),
+ ip: z.string().optional().describe('Source IP for the request'),
+ resourceType: z.string().optional().describe('Type of resource accessed'),
+ vaultId: z.string().optional().describe('Vault ID associated with the request'),
+ itemId: z.string().optional().describe('Item ID associated with the request'),
+ itemVersion: z
+ .number()
+ .optional()
+ .describe('Item version associated with the request')
+ })
+ )
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = createConnectClient(ctx);
+
+ ctx.progress('Fetching API activity...');
+ let activities = await client.getActivity(ctx.input.limit, ctx.input.offset);
+ let mapped = activities.map(activity => ({
+ requestId: activity.requestID ?? activity.requestId,
+ timestamp: activity.timestamp,
+ action: activity.action,
+ result: activity.result,
+ actorId: activity.actor?.id,
+ accountId: activity.actor?.account,
+ userAgent: activity.actor?.userAgent,
+ ip: activity.actor?.ip ?? activity.actor?.requestIp,
+ resourceType: activity.resource?.type,
+ vaultId: activity.resource?.vault?.id,
+ itemId: activity.resource?.item?.id,
+ itemVersion: activity.resource?.itemVersion
+ }));
+
+ return {
+ output: {
+ activities: mapped
+ },
+ message: `Found **${mapped.length}** API activity record(s).`
+ };
+ })
+ .build();
diff --git a/integrations/1password/src/tools/list-files.ts b/integrations/1password/src/tools/list-files.ts
new file mode 100644
index 0000000000..a0dd4d567e
--- /dev/null
+++ b/integrations/1password/src/tools/list-files.ts
@@ -0,0 +1,53 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { createConnectClient } from '../lib/connect-tool';
+import { spec } from '../spec';
+
+let fileOutputSchema = z.object({
+ fileId: z.string().describe('Unique identifier of the file'),
+ name: z.string().describe('Filename'),
+ size: z.number().describe('File size in bytes'),
+ contentPath: z.string().optional().describe('API path to retrieve file content'),
+ sectionId: z.string().optional().describe('ID of the section containing the file'),
+ sectionLabel: z.string().optional().describe('Label of the section containing the file')
+});
+
+export let listFiles = SlateTool.create(spec, {
+ name: 'List Files',
+ key: 'list_files',
+ description: `List file attachments on a 1Password item. Returns file metadata only; use Get File Content to download bytes as a Slate attachment.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ vaultId: z.string().describe('ID of the vault containing the item'),
+ itemId: z.string().describe('ID of the item whose files should be listed')
+ })
+ )
+ .output(
+ z.object({
+ files: z.array(fileOutputSchema).describe('File attachments on the item')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = createConnectClient(ctx);
+
+ ctx.progress('Listing files...');
+ let files = await client.listFiles(ctx.input.vaultId, ctx.input.itemId);
+ let mapped = files.map(file => ({
+ fileId: file.id,
+ name: file.name,
+ size: file.size,
+ contentPath: file.contentPath ?? file.content_path,
+ sectionId: file.section?.id,
+ sectionLabel: file.section?.label
+ }));
+
+ return {
+ output: { files: mapped },
+ message: `Found **${mapped.length}** file attachment(s).`
+ };
+ })
+ .build();
diff --git a/integrations/1password/src/tools/list-items.ts b/integrations/1password/src/tools/list-items.ts
index e71c1b0236..e9f796c8d3 100644
--- a/integrations/1password/src/tools/list-items.ts
+++ b/integrations/1password/src/tools/list-items.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let listItems = SlateTool.create(spec, {
@@ -42,14 +42,7 @@ export let listItems = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
ctx.progress('Fetching items...');
let items = await client.listItems(ctx.input.vaultId, ctx.input.filter);
diff --git a/integrations/1password/src/tools/list-vaults.ts b/integrations/1password/src/tools/list-vaults.ts
index f766e16196..6dbba2ca57 100644
--- a/integrations/1password/src/tools/list-vaults.ts
+++ b/integrations/1password/src/tools/list-vaults.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let listVaults = SlateTool.create(spec, {
@@ -35,14 +35,7 @@ export let listVaults = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
ctx.progress('Fetching vaults...');
let vaults = await client.listVaults(ctx.input.filter);
diff --git a/integrations/1password/src/tools/search-items.ts b/integrations/1password/src/tools/search-items.ts
index eb32b3e16b..84f123b8ec 100644
--- a/integrations/1password/src/tools/search-items.ts
+++ b/integrations/1password/src/tools/search-items.ts
@@ -1,6 +1,6 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let searchItems = SlateTool.create(spec, {
@@ -44,14 +44,7 @@ export let searchItems = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
let filterParts: string[] = [];
if (ctx.input.title) filterParts.push(`title co "${ctx.input.title}"`);
diff --git a/integrations/1password/src/tools/update-item.ts b/integrations/1password/src/tools/update-item.ts
index eba2ead0f7..28f0df5721 100644
--- a/integrations/1password/src/tools/update-item.ts
+++ b/integrations/1password/src/tools/update-item.ts
@@ -1,6 +1,7 @@
-import { SlateTool } from 'slates';
+import { createApiServiceError, SlateTool } from 'slates';
import { z } from 'zod';
-import { ConnectClient, type PatchOperation } from '../lib/client';
+import type { PatchOperation } from '../lib/client';
+import { createConnectClient } from '../lib/connect-tool';
import { spec } from '../spec';
export let updateItem = SlateTool.create(spec, {
@@ -63,14 +64,7 @@ export let updateItem = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
- if (!ctx.config.connectServerUrl) {
- throw new Error('Connect server URL is required. Set it in the configuration.');
- }
-
- let client = new ConnectClient({
- token: ctx.auth.token,
- serverUrl: ctx.config.connectServerUrl
- });
+ let client = createConnectClient(ctx);
let hasConvenienceUpdates =
ctx.input.title !== undefined ||
@@ -113,8 +107,8 @@ export let updateItem = SlateTool.create(spec, {
}));
result = await client.patchItem(ctx.input.vaultId, ctx.input.itemId, ops);
} else {
- throw new Error(
- 'No updates provided. Specify at least one of: title, tags, favorite, urls, or patchOperations.'
+ throw createApiServiceError(
+ 'No updates provided. Specify at least one of title, tags, favorite, urls, or patchOperations.'
);
}
diff --git a/integrations/1password/vitest.config.ts b/integrations/1password/vitest.config.ts
new file mode 100644
index 0000000000..0b05bc07ad
--- /dev/null
+++ b/integrations/1password/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['src/**/*.test.ts']
+ }
+});
diff --git a/integrations/activecampaign/README.md b/integrations/activecampaign/README.md
index fdb1417cc1..51598b3e7b 100644
--- a/integrations/activecampaign/README.md
+++ b/integrations/activecampaign/README.md
@@ -8,6 +8,10 @@ Manage contacts, deals, and marketing automation for customer experience. Create
Creates a note on a contact, deal, or account. Specify the resource type and ID along with the note content.
+### Associate Contact with Account
+
+Associates a contact with an account/company using ActiveCampaign account-contact relationships.
+
### Create or Update Account
Creates a new company/organization account or updates an existing one. Accounts can be associated with contacts and deals. Supports custom fields.
@@ -24,6 +28,10 @@ Creates a new deal or updates an existing one. When creating, provide title, con
Creates a new task or updates an existing one. Tasks are typically associated with deals. Supports setting title, due date, task type, assignee, and status.
+### Delete Account
+
+Deletes an ActiveCampaign account/company by ID.
+
### Delete Contact
Permanently deletes a contact from ActiveCampaign. This removes the contact and all associated data.
@@ -32,6 +40,14 @@ Permanently deletes a contact from ActiveCampaign. This removes the contact and
Permanently deletes a deal from ActiveCampaign.
+### Delete Task
+
+Deletes a deal task from ActiveCampaign.
+
+### Get Account
+
+Retrieves an ActiveCampaign account/company by ID.
+
### Get Contact
Retrieves a contact's full details including custom field values, tags, list subscriptions, and deal associations. Can look up by contact ID or search by email.
@@ -40,6 +56,10 @@ Retrieves a contact's full details including custom field values, tags, list sub
Retrieves the full details of a deal by its ID, including associated contact, pipeline, stage, and custom fields.
+### Get Task
+
+Retrieves a deal task by ID, including its related object and assignment fields.
+
### List Automations
Lists all available automations with their names, statuses, and entry counts. Use this to find automation IDs for adding or removing contacts.
@@ -56,6 +76,18 @@ Lists custom field definitions for contacts, deals, or accounts. Use this to dis
Lists all deal pipelines and their stages. Useful for finding pipeline and stage IDs needed when creating or updating deals.
+### List Task Types
+
+Lists configured deal task types. Use this to find taskTypeId values before creating tasks.
+
+### List Tasks
+
+Lists deal tasks with filters for related object, status, task type, assignee, due date, and text fields.
+
+### List Users
+
+Lists ActiveCampaign account users. Use this to find owner, assignee, and list owner IDs for deals, tasks, and lists.
+
### Manage Contact Automation
Adds a contact to an automation or removes them from one. When removing, provide the contactAutomation ID (available from Get Contact).
@@ -76,6 +108,10 @@ Creates, updates, deletes, or retrieves mailing lists. Lists are used for organi
Creates, updates, deletes, or lists tags. Tags can be of type "contact" or "template". Use this to manage tag definitions — to add/remove tags from contacts, use the Manage Contact Tags tool instead.
+### Manage Webhooks
+
+Creates, lists, or deletes ActiveCampaign webhooks for contact, campaign, deal, list, and SMS events.
+
### Search Accounts
Searches and lists company/organization accounts. Supports text search and pagination.
diff --git a/integrations/activecampaign/package.json b/integrations/activecampaign/package.json
index 97f8f8b642..fe85bf055b 100644
--- a/integrations/activecampaign/package.json
+++ b/integrations/activecampaign/package.json
@@ -7,12 +7,13 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
"typescript": "^5"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.6"
}
diff --git a/integrations/activecampaign/src/index.ts b/integrations/activecampaign/src/index.ts
index a0f1bc981d..2660ad4438 100644
--- a/integrations/activecampaign/src/index.ts
+++ b/integrations/activecampaign/src/index.ts
@@ -1,24 +1,33 @@
import { Slate } from 'slates';
import { spec } from './spec';
import {
+ associateContactWithAccount,
createNote,
createOrUpdateAccount,
createOrUpdateContact,
createOrUpdateDeal,
createOrUpdateTask,
+ deleteAccount,
deleteContact,
deleteDeal,
+ deleteTask,
+ getAccount,
getContact,
getDeal,
+ getTask,
listAutomations,
listCampaigns,
listCustomFields,
listPipelinesAndStages,
+ listTasks,
+ listTaskTypes,
+ listUsers,
manageContactAutomation,
manageContactTags,
manageListSubscription,
manageLists,
manageTags,
+ manageWebhooks,
searchAccounts,
searchContacts,
searchDeals
@@ -44,11 +53,20 @@ export let provider = Slate.create({
listCampaigns,
listAutomations,
createOrUpdateAccount,
+ getAccount,
searchAccounts,
+ deleteAccount,
+ associateContactWithAccount,
createNote,
createOrUpdateTask,
+ getTask,
+ listTasks,
+ deleteTask,
+ listTaskTypes,
listPipelinesAndStages,
- listCustomFields
+ listCustomFields,
+ listUsers,
+ manageWebhooks
],
triggers: [contactEvents, dealEvents, campaignEvents, smsEvents]
});
diff --git a/integrations/activecampaign/src/lib/client.ts b/integrations/activecampaign/src/lib/client.ts
index 9645cd6c10..8182078749 100644
--- a/integrations/activecampaign/src/lib/client.ts
+++ b/integrations/activecampaign/src/lib/client.ts
@@ -1,4 +1,5 @@
import { createAxios } from 'slates';
+import { activeCampaignApiError, activeCampaignServiceError } from './errors';
export interface PaginationParams {
limit?: number;
@@ -39,9 +40,12 @@ export interface ListInput {
stringid: string;
senderUrl: string;
senderReminder: string;
+ channel?: 'email' | 'sms';
sendLastBroadcast?: boolean;
+ carboncopy?: string;
subscription_notify?: string;
unsubscription_notify?: string;
+ user?: number;
}
export interface AccountInput {
@@ -74,7 +78,24 @@ export class Client {
private axios;
constructor(params: { token: string; apiUrl: string }) {
- let baseUrl = params.apiUrl.replace(/\/+$/, '');
+ if (!params.token?.trim()) {
+ throw activeCampaignServiceError('ActiveCampaign API key is required.');
+ }
+
+ if (!params.apiUrl?.trim()) {
+ throw activeCampaignServiceError('ActiveCampaign API URL is required.');
+ }
+
+ let baseUrl = params.apiUrl
+ .trim()
+ .replace(/\/+$/, '')
+ .replace(/\/api\/3$/i, '');
+ if (!/^https:\/\//i.test(baseUrl)) {
+ throw activeCampaignServiceError(
+ 'ActiveCampaign API URL must be the full HTTPS URL from Settings > Developer.'
+ );
+ }
+
this.axios = createAxios({
baseURL: `${baseUrl}/api/3`,
headers: {
@@ -82,6 +103,11 @@ export class Client {
'Content-Type': 'application/json'
}
});
+
+ this.axios.interceptors?.response?.use(
+ (response: any) => response,
+ (error: unknown) => Promise.reject(activeCampaignApiError(error))
+ );
}
// ─── Contacts ───────────────────────────────────────────────
@@ -115,9 +141,12 @@ export class Client {
params?: PaginationParams & {
search?: string;
email?: string;
+ email_like?: string;
listid?: string;
tagid?: string;
status?: number;
+ id_greater?: number;
+ 'orders[id]'?: string;
orderBy?: string;
}
) {
@@ -323,7 +352,24 @@ export class Client {
// ─── Lists ─────────────────────────────────────────────────
async createList(list: ListInput) {
- let res = await this.axios.post('/lists', { list });
+ let payload: Record = {
+ name: list.name,
+ stringid: list.stringid,
+ sender_url: list.senderUrl,
+ sender_reminder: list.senderReminder
+ };
+
+ if (list.channel) payload.channel = list.channel;
+ if (list.sendLastBroadcast !== undefined)
+ payload.send_last_broadcast = list.sendLastBroadcast;
+ if (list.carboncopy !== undefined) payload.carboncopy = list.carboncopy;
+ if (list.subscription_notify !== undefined)
+ payload.subscription_notify = list.subscription_notify;
+ if (list.unsubscription_notify !== undefined)
+ payload.unsubscription_notify = list.unsubscription_notify;
+ if (list.user !== undefined) payload.user = list.user;
+
+ let res = await this.axios.post('/lists', { list: payload });
return res.data;
}
@@ -333,7 +379,22 @@ export class Client {
}
async updateList(listId: string, list: Partial) {
- let res = await this.axios.put(`/lists/${listId}`, { list });
+ let payload: Record = {};
+ if (list.name !== undefined) payload.name = list.name;
+ if (list.stringid !== undefined) payload.stringid = list.stringid;
+ if (list.senderUrl !== undefined) payload.sender_url = list.senderUrl;
+ if (list.senderReminder !== undefined) payload.sender_reminder = list.senderReminder;
+ if (list.channel !== undefined) payload.channel = list.channel;
+ if (list.sendLastBroadcast !== undefined)
+ payload.send_last_broadcast = list.sendLastBroadcast;
+ if (list.carboncopy !== undefined) payload.carboncopy = list.carboncopy;
+ if (list.subscription_notify !== undefined)
+ payload.subscription_notify = list.subscription_notify;
+ if (list.unsubscription_notify !== undefined)
+ payload.unsubscription_notify = list.unsubscription_notify;
+ if (list.user !== undefined) payload.user = list.user;
+
+ let res = await this.axios.put(`/lists/${listId}`, { list: payload });
return res.data;
}
@@ -402,7 +463,7 @@ export class Client {
return res.data;
}
- async listAccounts(params?: PaginationParams & { search?: string }) {
+ async listAccounts(params?: PaginationParams & { search?: string; count_deals?: boolean }) {
let res = await this.axios.get('/accounts', { params });
return res.data;
}
@@ -473,10 +534,18 @@ export class Client {
async listTasks(
params?: PaginationParams & {
+ 'filters[title]'?: string;
'filters[reltype]'?: string;
'filters[relid]'?: string;
'filters[status]'?: number;
- 'filters[dealTasktype]'?: string;
+ 'filters[note]'?: string;
+ 'filters[duedate]'?: string;
+ 'filters[due_after]'?: string;
+ 'filters[due_before]'?: string;
+ 'filters[duedate_range]'?: string;
+ 'filters[d_tasktypeid]'?: string;
+ 'filters[assignee_userid]'?: string;
+ 'filters[outcome_id]'?: number;
}
) {
let res = await this.axios.get('/dealTasks', { params });
diff --git a/integrations/activecampaign/src/lib/errors.ts b/integrations/activecampaign/src/lib/errors.ts
new file mode 100644
index 0000000000..d8c74e914f
--- /dev/null
+++ b/integrations/activecampaign/src/lib/errors.ts
@@ -0,0 +1,97 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null && !Array.isArray(value);
+
+let pushDetail = (details: string[], value: unknown) => {
+ if (typeof value !== 'string' && typeof value !== 'number') {
+ return;
+ }
+
+ let detail = String(value).trim();
+ if (detail && !details.includes(detail)) {
+ details.push(detail);
+ }
+};
+
+let collectDetails = (value: unknown, details: string[]) => {
+ if (Array.isArray(value)) {
+ for (let item of value) {
+ collectDetails(item, details);
+ }
+ return;
+ }
+
+ if (!isRecord(value)) {
+ pushDetail(details, value);
+ return;
+ }
+
+ pushDetail(details, value.message);
+ pushDetail(details, value.error);
+ pushDetail(details, value.error_description);
+ pushDetail(details, value.title);
+ pushDetail(details, value.detail);
+ pushDetail(details, value.code);
+ collectDetails(value.errors, details);
+};
+
+let extractActiveCampaignMessage = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let details: string[] = [];
+
+ collectDetails(response?.data, details);
+
+ if (details.length > 0) {
+ return details.join(' - ');
+ }
+
+ if (error instanceof Error && error.message) {
+ return error.message;
+ }
+
+ return 'Unknown error';
+};
+
+let statusLabelFor = (response?: ErrorResponse) =>
+ response?.status !== undefined
+ ? `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+
+let upstreamCodeFor = (response?: ErrorResponse) => {
+ if (!isRecord(response?.data)) {
+ return undefined;
+ }
+
+ let code = response.data.code ?? response.data.error;
+ return typeof code === 'string' || typeof code === 'number' ? String(code) : undefined;
+};
+
+export let activeCampaignServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let activeCampaignApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) {
+ return error;
+ }
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let serviceError = activeCampaignServiceError(
+ `ActiveCampaign API ${operation} failed: ${statusLabelFor(response)}${extractActiveCampaignMessage(error)}`
+ );
+ serviceError.data.reason = 'activecampaign_api_error';
+ serviceError.data.upstreamStatus = response?.status;
+ serviceError.data.upstreamCode = upstreamCodeFor(response);
+
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+
+ return serviceError;
+};
diff --git a/integrations/activecampaign/src/tools/associate-contact-with-account.ts b/integrations/activecampaign/src/tools/associate-contact-with-account.ts
new file mode 100644
index 0000000000..c6f70e6758
--- /dev/null
+++ b/integrations/activecampaign/src/tools/associate-contact-with-account.ts
@@ -0,0 +1,59 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let associateContactWithAccount = SlateTool.create(spec, {
+ name: 'Associate Contact with Account',
+ key: 'associate_contact_with_account',
+ description:
+ 'Associates a contact with an account/company using ActiveCampaign account-contact relationships.',
+ tags: {
+ destructive: false,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ contactId: z.string().describe('ID of the contact to associate'),
+ accountId: z.string().describe('ID of the account/company to associate'),
+ jobTitle: z
+ .string()
+ .optional()
+ .describe('Optional job title for the contact at the account')
+ })
+ )
+ .output(
+ z.object({
+ success: z.boolean(),
+ accountContactId: z.string().optional(),
+ contactId: z.string(),
+ accountId: z.string(),
+ jobTitle: z.string().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ let result = await client.associateContactWithAccount(
+ ctx.input.contactId,
+ ctx.input.accountId,
+ ctx.input.jobTitle
+ );
+ let accountContact = result.accountContact;
+
+ return {
+ output: {
+ success: true,
+ accountContactId: accountContact?.id || undefined,
+ contactId: accountContact?.contact || ctx.input.contactId,
+ accountId: accountContact?.account || ctx.input.accountId,
+ jobTitle: accountContact?.jobTitle || ctx.input.jobTitle || undefined
+ },
+ message: `Contact (ID: ${ctx.input.contactId}) associated with account (ID: ${ctx.input.accountId}).`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/create-or-update-account.ts b/integrations/activecampaign/src/tools/create-or-update-account.ts
index 4113becc7e..7c92f489bf 100644
--- a/integrations/activecampaign/src/tools/create-or-update-account.ts
+++ b/integrations/activecampaign/src/tools/create-or-update-account.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
import { spec } from '../spec';
export let createOrUpdateAccount = SlateTool.create(spec, {
@@ -59,7 +60,9 @@ export let createOrUpdateAccount = SlateTool.create(spec, {
if (ctx.input.accountId) {
result = await client.updateAccount(ctx.input.accountId, accountInput);
} else {
- if (!ctx.input.name) throw new Error('name is required for creating an account');
+ if (!ctx.input.name) {
+ throw activeCampaignServiceError('name is required for creating an account');
+ }
result = await client.createAccount(accountInput);
}
diff --git a/integrations/activecampaign/src/tools/create-or-update-deal.ts b/integrations/activecampaign/src/tools/create-or-update-deal.ts
index 40732f5d73..8aed8c87ae 100644
--- a/integrations/activecampaign/src/tools/create-or-update-deal.ts
+++ b/integrations/activecampaign/src/tools/create-or-update-deal.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
import { spec } from '../spec';
export let createOrUpdateDeal = SlateTool.create(spec, {
@@ -86,6 +87,19 @@ export let createOrUpdateDeal = SlateTool.create(spec, {
if (ctx.input.dealId) {
result = await client.updateDeal(ctx.input.dealId, dealInput);
} else {
+ if (!ctx.input.title) {
+ throw activeCampaignServiceError('title is required when creating a deal');
+ }
+ if (!ctx.input.contactId && !ctx.input.accountId) {
+ throw activeCampaignServiceError(
+ 'contactId or accountId is required when creating a deal'
+ );
+ }
+ if (!ctx.input.pipelineId && !ctx.input.stageId) {
+ throw activeCampaignServiceError(
+ 'pipelineId or stageId is required when creating a deal'
+ );
+ }
result = await client.createDeal(dealInput);
}
diff --git a/integrations/activecampaign/src/tools/delete-account.ts b/integrations/activecampaign/src/tools/delete-account.ts
new file mode 100644
index 0000000000..5046efa9c1
--- /dev/null
+++ b/integrations/activecampaign/src/tools/delete-account.ts
@@ -0,0 +1,38 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let deleteAccount = SlateTool.create(spec, {
+ name: 'Delete Account',
+ key: 'delete_account',
+ description: 'Deletes an ActiveCampaign account/company by ID.',
+ tags: {
+ destructive: true,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ accountId: z.string().describe('ID of the account to delete')
+ })
+ )
+ .output(
+ z.object({
+ deleted: z.boolean()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ await client.deleteAccount(ctx.input.accountId);
+
+ return {
+ output: { deleted: true },
+ message: `Account (ID: ${ctx.input.accountId}) has been deleted.`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/delete-task.ts b/integrations/activecampaign/src/tools/delete-task.ts
new file mode 100644
index 0000000000..6af045d892
--- /dev/null
+++ b/integrations/activecampaign/src/tools/delete-task.ts
@@ -0,0 +1,38 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let deleteTask = SlateTool.create(spec, {
+ name: 'Delete Task',
+ key: 'delete_task',
+ description: 'Deletes a deal task from ActiveCampaign.',
+ tags: {
+ destructive: true,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ taskId: z.string().describe('ID of the task to delete')
+ })
+ )
+ .output(
+ z.object({
+ deleted: z.boolean()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ await client.deleteTask(ctx.input.taskId);
+
+ return {
+ output: { deleted: true },
+ message: `Task (ID: ${ctx.input.taskId}) has been deleted.`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/get-account.ts b/integrations/activecampaign/src/tools/get-account.ts
new file mode 100644
index 0000000000..30ffd247ea
--- /dev/null
+++ b/integrations/activecampaign/src/tools/get-account.ts
@@ -0,0 +1,53 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let getAccount = SlateTool.create(spec, {
+ name: 'Get Account',
+ key: 'get_account',
+ description: 'Retrieves an ActiveCampaign account/company by ID.',
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ accountId: z.string().describe('ID of the account to retrieve')
+ })
+ )
+ .output(
+ z.object({
+ accountId: z.string(),
+ name: z.string(),
+ accountUrl: z.string().optional(),
+ contactCount: z.number().optional(),
+ dealCount: z.number().optional(),
+ createdAt: z.string().optional(),
+ updatedAt: z.string().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ let result = await client.getAccount(ctx.input.accountId);
+ let account = result.account;
+
+ return {
+ output: {
+ accountId: account.id,
+ name: account.name,
+ accountUrl: account.accountUrl || undefined,
+ contactCount: account.contactCount ? Number(account.contactCount) : undefined,
+ dealCount: account.dealCount ? Number(account.dealCount) : undefined,
+ createdAt: account.createdTimestamp || account.cdate || undefined,
+ updatedAt: account.updatedTimestamp || account.udate || undefined
+ },
+ message: `Retrieved account **${account.name}** (ID: ${account.id}).`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/get-contact.ts b/integrations/activecampaign/src/tools/get-contact.ts
index fc94a27ae5..986478cb88 100644
--- a/integrations/activecampaign/src/tools/get-contact.ts
+++ b/integrations/activecampaign/src/tools/get-contact.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
import { spec } from '../spec';
export let getContact = SlateTool.create(spec, {
@@ -56,7 +57,16 @@ export let getContact = SlateTool.create(spec, {
})
)
.optional()
- .describe('List subscriptions')
+ .describe('List subscriptions'),
+ deals: z
+ .array(
+ z.object({
+ contactDealId: z.string().optional(),
+ dealId: z.string().optional()
+ })
+ )
+ .optional()
+ .describe('Deal associations for this contact')
})
)
.handleInvocation(async ctx => {
@@ -72,12 +82,12 @@ export let getContact = SlateTool.create(spec, {
if (searchResult.contacts && searchResult.contacts.length > 0) {
contactId = searchResult.contacts[0].id;
} else {
- throw new Error(`No contact found with email: ${ctx.input.email}`);
+ throw activeCampaignServiceError(`No contact found with email: ${ctx.input.email}`);
}
}
if (!contactId) {
- throw new Error('Either contactId or email must be provided');
+ throw activeCampaignServiceError('Either contactId or email must be provided');
}
let result = await client.getContact(contactId);
@@ -101,6 +111,12 @@ export let getContact = SlateTool.create(spec, {
status: String(cl.status)
}));
+ let dealsResult = await client.getContactDeals(contactId);
+ let deals = (dealsResult.contactDeals || []).map((cd: any) => ({
+ contactDealId: cd.id || undefined,
+ dealId: cd.deal || cd.dealId || undefined
+ }));
+
return {
output: {
contactId: contact.id,
@@ -112,7 +128,8 @@ export let getContact = SlateTool.create(spec, {
updatedAt: contact.udate || undefined,
tags,
fieldValues,
- lists
+ lists,
+ deals
},
message: `Retrieved contact **${contact.email}** (ID: ${contact.id}).`
};
diff --git a/integrations/activecampaign/src/tools/get-task.ts b/integrations/activecampaign/src/tools/get-task.ts
new file mode 100644
index 0000000000..af7aec981e
--- /dev/null
+++ b/integrations/activecampaign/src/tools/get-task.ts
@@ -0,0 +1,62 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let getTask = SlateTool.create(spec, {
+ name: 'Get Task',
+ key: 'get_task',
+ description:
+ 'Retrieves a deal task by ID, including its related object and assignment fields.',
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ taskId: z.string().describe('ID of the task to retrieve')
+ })
+ )
+ .output(
+ z.object({
+ taskId: z.string(),
+ title: z.string().optional(),
+ note: z.string().optional(),
+ duedate: z.string().optional(),
+ status: z.string().optional(),
+ relType: z.string().optional(),
+ relId: z.string().optional(),
+ taskTypeId: z.string().optional(),
+ assigneeId: z.string().optional(),
+ createdAt: z.string().optional(),
+ updatedAt: z.string().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ let result = await client.getTask(ctx.input.taskId);
+ let task = result.dealTask;
+
+ return {
+ output: {
+ taskId: task.id,
+ title: task.title || undefined,
+ note: task.note || undefined,
+ duedate: task.duedate || undefined,
+ status: task.status !== undefined ? String(task.status) : undefined,
+ relType: task.reltype || undefined,
+ relId: task.relid || undefined,
+ taskTypeId: task.dealTasktype || undefined,
+ assigneeId: task.assignee || undefined,
+ createdAt: task.cdate || undefined,
+ updatedAt: task.udate || undefined
+ },
+ message: `Retrieved task **${task.title || task.id}** (ID: ${task.id}).`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/index.ts b/integrations/activecampaign/src/tools/index.ts
index 1538228444..f39b280cc4 100644
--- a/integrations/activecampaign/src/tools/index.ts
+++ b/integrations/activecampaign/src/tools/index.ts
@@ -1,21 +1,30 @@
+export * from './associate-contact-with-account';
export * from './create-note';
export * from './create-or-update-account';
export * from './create-or-update-contact';
export * from './create-or-update-deal';
export * from './create-or-update-task';
+export * from './delete-account';
export * from './delete-contact';
export * from './delete-deal';
+export * from './delete-task';
+export * from './get-account';
export * from './get-contact';
export * from './get-deal';
+export * from './get-task';
export * from './list-automations';
export * from './list-campaigns';
export * from './list-custom-fields';
export * from './list-pipelines-and-stages';
+export * from './list-task-types';
+export * from './list-tasks';
+export * from './list-users';
export * from './manage-contact-automation';
export * from './manage-contact-tags';
export * from './manage-list-subscription';
export * from './manage-lists';
export * from './manage-tags';
+export * from './manage-webhooks';
export * from './search-accounts';
export * from './search-contacts';
export * from './search-deals';
diff --git a/integrations/activecampaign/src/tools/list-custom-fields.ts b/integrations/activecampaign/src/tools/list-custom-fields.ts
index e2c003426a..29849d81bc 100644
--- a/integrations/activecampaign/src/tools/list-custom-fields.ts
+++ b/integrations/activecampaign/src/tools/list-custom-fields.ts
@@ -65,13 +65,20 @@ export let listCustomFields = SlateTool.create(spec, {
let fields = (result[fieldsKey] || []).map((f: any) => ({
fieldId: f.id,
title: f.title || f.fieldLabel || undefined,
- type: f.type || undefined,
- options: f.options
- ? Array.isArray(f.options)
- ? f.options
- : Object.values(f.options)
- : undefined,
- isRequired: f.isRequired === '1' || f.isRequired === 1 ? true : undefined
+ type: f.type || f.fieldType || undefined,
+ options:
+ (f.options ?? f.fieldOptions)
+ ? Array.isArray(f.options ?? f.fieldOptions)
+ ? (f.options ?? f.fieldOptions)
+ : Object.values(f.options ?? f.fieldOptions)
+ : undefined,
+ isRequired:
+ f.isRequired === '1' ||
+ f.isRequired === 1 ||
+ f.isrequired === '1' ||
+ f.isrequired === 1
+ ? true
+ : undefined
}));
return {
diff --git a/integrations/activecampaign/src/tools/list-task-types.ts b/integrations/activecampaign/src/tools/list-task-types.ts
new file mode 100644
index 0000000000..5dff1e0e35
--- /dev/null
+++ b/integrations/activecampaign/src/tools/list-task-types.ts
@@ -0,0 +1,46 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let listTaskTypes = SlateTool.create(spec, {
+ name: 'List Task Types',
+ key: 'list_task_types',
+ description:
+ 'Lists configured deal task types. Use this to find taskTypeId values before creating tasks.',
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(z.object({}))
+ .output(
+ z.object({
+ taskTypes: z.array(
+ z.object({
+ taskTypeId: z.string(),
+ title: z.string().optional(),
+ description: z.string().optional()
+ })
+ )
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ let result = await client.listTaskTypes();
+ let taskTypes = (result.dealTasktypes || []).map((taskType: any) => ({
+ taskTypeId: taskType.id,
+ title: taskType.title || undefined,
+ description: taskType.description || undefined
+ }));
+
+ return {
+ output: { taskTypes },
+ message: `Found **${taskTypes.length}** task types.`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/list-tasks.ts b/integrations/activecampaign/src/tools/list-tasks.ts
new file mode 100644
index 0000000000..03254eb512
--- /dev/null
+++ b/integrations/activecampaign/src/tools/list-tasks.ts
@@ -0,0 +1,103 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+let mapTask = (task: any) => ({
+ taskId: task.id,
+ title: task.title || undefined,
+ note: task.note || undefined,
+ duedate: task.duedate || undefined,
+ status: task.status !== undefined ? String(task.status) : undefined,
+ relType: task.reltype || undefined,
+ relId: task.relid || undefined,
+ taskTypeId: task.dealTasktype || undefined,
+ assigneeId: task.assignee || undefined,
+ createdAt: task.cdate || undefined,
+ updatedAt: task.udate || undefined
+});
+
+export let listTasks = SlateTool.create(spec, {
+ name: 'List Tasks',
+ key: 'list_tasks',
+ description:
+ 'Lists deal tasks with filters for related object, status, task type, assignee, due date, and text fields.',
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ title: z.string().optional().describe('Filter by task title'),
+ relType: z.string().optional().describe('Filter by related object type, such as Deal'),
+ relId: z.string().optional().describe('Filter by related object ID'),
+ status: z.number().optional().describe('Filter by status: 0=incomplete, 1=complete'),
+ note: z.string().optional().describe('Filter by note content'),
+ dueDate: z.string().optional().describe('Filter by exact due date'),
+ dueAfter: z.string().optional().describe('Filter tasks due after this date'),
+ dueBefore: z.string().optional().describe('Filter tasks due before this date'),
+ dueDateRange: z
+ .string()
+ .optional()
+ .describe('Filter by date range or bucket, e.g. upcoming, scheduled, or overdue'),
+ taskTypeId: z.string().optional().describe('Filter by deal task type ID'),
+ assigneeUserId: z.string().optional().describe('Filter by assignee user ID'),
+ outcomeId: z.number().optional().describe('Filter by task outcome ID'),
+ limit: z.number().optional().describe('Maximum number of tasks to return'),
+ offset: z.number().optional().describe('Pagination offset')
+ })
+ )
+ .output(
+ z.object({
+ tasks: z.array(
+ z.object({
+ taskId: z.string(),
+ title: z.string().optional(),
+ note: z.string().optional(),
+ duedate: z.string().optional(),
+ status: z.string().optional(),
+ relType: z.string().optional(),
+ relId: z.string().optional(),
+ taskTypeId: z.string().optional(),
+ assigneeId: z.string().optional(),
+ createdAt: z.string().optional(),
+ updatedAt: z.string().optional()
+ })
+ ),
+ totalCount: z.number().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ let params: Record = {};
+ if (ctx.input.title) params['filters[title]'] = ctx.input.title;
+ if (ctx.input.relType) params['filters[reltype]'] = ctx.input.relType;
+ if (ctx.input.relId) params['filters[relid]'] = ctx.input.relId;
+ if (ctx.input.status !== undefined) params['filters[status]'] = ctx.input.status;
+ if (ctx.input.note) params['filters[note]'] = ctx.input.note;
+ if (ctx.input.dueDate) params['filters[duedate]'] = ctx.input.dueDate;
+ if (ctx.input.dueAfter) params['filters[due_after]'] = ctx.input.dueAfter;
+ if (ctx.input.dueBefore) params['filters[due_before]'] = ctx.input.dueBefore;
+ if (ctx.input.dueDateRange) params['filters[duedate_range]'] = ctx.input.dueDateRange;
+ if (ctx.input.taskTypeId) params['filters[d_tasktypeid]'] = ctx.input.taskTypeId;
+ if (ctx.input.assigneeUserId)
+ params['filters[assignee_userid]'] = ctx.input.assigneeUserId;
+ if (ctx.input.outcomeId !== undefined) params['filters[outcome_id]'] = ctx.input.outcomeId;
+ if (ctx.input.limit) params.limit = ctx.input.limit;
+ if (ctx.input.offset) params.offset = ctx.input.offset;
+
+ let result = await client.listTasks(params);
+ let tasks = (result.dealTasks || []).map(mapTask);
+ let totalCount = result.meta?.total ? Number(result.meta.total) : undefined;
+
+ return {
+ output: { tasks, totalCount },
+ message: `Found **${tasks.length}** tasks${totalCount !== undefined ? ` (out of ${totalCount} total)` : ''}.`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/list-users.ts b/integrations/activecampaign/src/tools/list-users.ts
new file mode 100644
index 0000000000..a44688775e
--- /dev/null
+++ b/integrations/activecampaign/src/tools/list-users.ts
@@ -0,0 +1,70 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+let mapUser = (user: any) => ({
+ userId: user.id,
+ email: user.email || undefined,
+ firstName: user.firstName || user.first_name || undefined,
+ lastName: user.lastName || user.last_name || undefined,
+ username: user.username || undefined,
+ fullName: user.fullName || user.fullname || user.name || undefined
+});
+
+export let listUsers = SlateTool.create(spec, {
+ name: 'List Users',
+ key: 'list_users',
+ description:
+ 'Lists ActiveCampaign account users. Use this to find owner, assignee, and list owner IDs for deals, tasks, and lists.',
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ currentUserOnly: z
+ .boolean()
+ .optional()
+ .describe('When true, only return the authenticated API user')
+ })
+ )
+ .output(
+ z.object({
+ users: z.array(
+ z.object({
+ userId: z.string(),
+ email: z.string().optional(),
+ firstName: z.string().optional(),
+ lastName: z.string().optional(),
+ username: z.string().optional(),
+ fullName: z.string().optional()
+ })
+ )
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ if (ctx.input.currentUserOnly) {
+ let result = await client.getCurrentUser();
+ let user = result.user || result;
+ return {
+ output: { users: [mapUser(user)] },
+ message: 'Retrieved the current ActiveCampaign user.'
+ };
+ }
+
+ let result = await client.listUsers();
+ let users = (result.users || []).map(mapUser);
+
+ return {
+ output: { users },
+ message: `Found **${users.length}** users.`
+ };
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/manage-contact-automation.ts b/integrations/activecampaign/src/tools/manage-contact-automation.ts
index 888c9110b3..f72afe05f5 100644
--- a/integrations/activecampaign/src/tools/manage-contact-automation.ts
+++ b/integrations/activecampaign/src/tools/manage-contact-automation.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
import { spec } from '../spec';
export let manageContactAutomation = SlateTool.create(spec, {
@@ -45,7 +46,9 @@ export let manageContactAutomation = SlateTool.create(spec, {
if (ctx.input.action === 'add') {
if (!ctx.input.automationId) {
- throw new Error('automationId is required when adding a contact to an automation');
+ throw activeCampaignServiceError(
+ 'automationId is required when adding a contact to an automation'
+ );
}
let result = await client.addContactToAutomation(
ctx.input.contactId,
@@ -60,7 +63,7 @@ export let manageContactAutomation = SlateTool.create(spec, {
};
} else {
if (!ctx.input.contactAutomationId) {
- throw new Error(
+ throw activeCampaignServiceError(
'contactAutomationId is required when removing a contact from an automation'
);
}
diff --git a/integrations/activecampaign/src/tools/manage-contact-tags.ts b/integrations/activecampaign/src/tools/manage-contact-tags.ts
index 32716faf8a..585e81bee0 100644
--- a/integrations/activecampaign/src/tools/manage-contact-tags.ts
+++ b/integrations/activecampaign/src/tools/manage-contact-tags.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
import { spec } from '../spec';
export let manageContactTags = SlateTool.create(spec, {
@@ -45,7 +46,7 @@ export let manageContactTags = SlateTool.create(spec, {
if (ctx.input.action === 'add') {
if (!ctx.input.tagId) {
- throw new Error('tagId is required when adding a tag');
+ throw activeCampaignServiceError('tagId is required when adding a tag');
}
let result = await client.addTagToContact(ctx.input.contactId, ctx.input.tagId);
return {
@@ -57,7 +58,7 @@ export let manageContactTags = SlateTool.create(spec, {
};
} else {
if (!ctx.input.contactTagId) {
- throw new Error('contactTagId is required when removing a tag');
+ throw activeCampaignServiceError('contactTagId is required when removing a tag');
}
await client.removeTagFromContact(ctx.input.contactTagId);
return {
diff --git a/integrations/activecampaign/src/tools/manage-lists.ts b/integrations/activecampaign/src/tools/manage-lists.ts
index d08bc0c21e..dfb136f7f2 100644
--- a/integrations/activecampaign/src/tools/manage-lists.ts
+++ b/integrations/activecampaign/src/tools/manage-lists.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
import { spec } from '../spec';
export let manageLists = SlateTool.create(spec, {
@@ -79,7 +80,7 @@ export let manageLists = SlateTool.create(spec, {
!ctx.input.senderUrl ||
!ctx.input.senderReminder
) {
- throw new Error(
+ throw activeCampaignServiceError(
'name, stringId, senderUrl, and senderReminder are required for creating a list'
);
}
@@ -105,7 +106,9 @@ export let manageLists = SlateTool.create(spec, {
};
}
case 'update': {
- if (!ctx.input.listId) throw new Error('listId is required for updating a list');
+ if (!ctx.input.listId) {
+ throw activeCampaignServiceError('listId is required for updating a list');
+ }
let updatePayload: Record = {};
if (ctx.input.name) updatePayload.name = ctx.input.name;
if (ctx.input.stringId) updatePayload.stringid = ctx.input.stringId;
@@ -126,7 +129,9 @@ export let manageLists = SlateTool.create(spec, {
};
}
case 'delete': {
- if (!ctx.input.listId) throw new Error('listId is required for deleting a list');
+ if (!ctx.input.listId) {
+ throw activeCampaignServiceError('listId is required for deleting a list');
+ }
await client.deleteList(ctx.input.listId);
return {
output: { deleted: true },
@@ -134,7 +139,9 @@ export let manageLists = SlateTool.create(spec, {
};
}
case 'get': {
- if (!ctx.input.listId) throw new Error('listId is required for getting a list');
+ if (!ctx.input.listId) {
+ throw activeCampaignServiceError('listId is required for getting a list');
+ }
let result = await client.getList(ctx.input.listId);
let list = result.list;
return {
diff --git a/integrations/activecampaign/src/tools/manage-tags.ts b/integrations/activecampaign/src/tools/manage-tags.ts
index 9ac352dd7d..94924a1974 100644
--- a/integrations/activecampaign/src/tools/manage-tags.ts
+++ b/integrations/activecampaign/src/tools/manage-tags.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
import { spec } from '../spec';
export let manageTags = SlateTool.create(spec, {
@@ -65,7 +66,9 @@ export let manageTags = SlateTool.create(spec, {
switch (ctx.input.action) {
case 'create': {
if (!ctx.input.tagName || !ctx.input.tagType) {
- throw new Error('tagName and tagType are required for creating a tag');
+ throw activeCampaignServiceError(
+ 'tagName and tagType are required for creating a tag'
+ );
}
let result = await client.createTag({
tag: ctx.input.tagName,
@@ -87,7 +90,7 @@ export let manageTags = SlateTool.create(spec, {
}
case 'update': {
if (!ctx.input.tagId) {
- throw new Error('tagId is required for updating a tag');
+ throw activeCampaignServiceError('tagId is required for updating a tag');
}
let updatePayload: Record = {};
if (ctx.input.tagName) updatePayload.tag = ctx.input.tagName;
@@ -111,7 +114,7 @@ export let manageTags = SlateTool.create(spec, {
}
case 'delete': {
if (!ctx.input.tagId) {
- throw new Error('tagId is required for deleting a tag');
+ throw activeCampaignServiceError('tagId is required for deleting a tag');
}
await client.deleteTag(ctx.input.tagId);
return {
diff --git a/integrations/activecampaign/src/tools/manage-webhooks.ts b/integrations/activecampaign/src/tools/manage-webhooks.ts
new file mode 100644
index 0000000000..6f7b27495a
--- /dev/null
+++ b/integrations/activecampaign/src/tools/manage-webhooks.ts
@@ -0,0 +1,161 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { activeCampaignServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let webhookEventSchema = z.enum([
+ 'forward',
+ 'open',
+ 'share',
+ 'sent',
+ 'subscribe',
+ 'subscriber_note',
+ 'contact_tag_added',
+ 'contact_tag_removed',
+ 'unsubscribe',
+ 'update',
+ 'deal_add',
+ 'deal_note_add',
+ 'deal_pipeline_add',
+ 'deal_stage_add',
+ 'deal_task_add',
+ 'deal_task_complete',
+ 'deal_tasktype_add',
+ 'deal_update',
+ 'bounce',
+ 'reply',
+ 'click',
+ 'list_add',
+ 'sms_reply',
+ 'sms_sent',
+ 'sms_unsub'
+]);
+
+let webhookSourceSchema = z.enum(['public', 'admin', 'api', 'system']);
+
+let mapWebhook = (webhook: any) => ({
+ webhookId: webhook.id,
+ name: webhook.name || undefined,
+ url: webhook.url || undefined,
+ events: Array.isArray(webhook.events) ? webhook.events : undefined,
+ sources: Array.isArray(webhook.sources) ? webhook.sources : undefined,
+ listId: webhook.listid || webhook.list || undefined
+});
+
+export let manageWebhooks = SlateTool.create(spec, {
+ name: 'Manage Webhooks',
+ key: 'manage_webhooks',
+ description:
+ 'Creates, lists, or deletes ActiveCampaign webhooks for contact, campaign, deal, list, and SMS events.',
+ tags: {
+ destructive: true,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ action: z.enum(['create', 'list', 'delete']).describe('Action to perform'),
+ webhookId: z.string().optional().describe('Webhook ID required for delete'),
+ name: z.string().optional().describe('Webhook name required for create'),
+ url: z.string().optional().describe('Destination URL required for create'),
+ events: z
+ .array(webhookEventSchema)
+ .optional()
+ .describe('Webhook events required for create'),
+ sources: z
+ .array(webhookSourceSchema)
+ .optional()
+ .describe('Webhook sources required for create'),
+ listId: z.string().optional().describe('Optional list ID to scope the webhook'),
+ limit: z.number().optional().describe('Maximum number of webhooks to return for list'),
+ offset: z.number().optional().describe('Pagination offset for list')
+ })
+ )
+ .output(
+ z.object({
+ webhook: z
+ .object({
+ webhookId: z.string(),
+ name: z.string().optional(),
+ url: z.string().optional(),
+ events: z.array(z.string()).optional(),
+ sources: z.array(z.string()).optional(),
+ listId: z.string().optional()
+ })
+ .optional(),
+ webhooks: z
+ .array(
+ z.object({
+ webhookId: z.string(),
+ name: z.string().optional(),
+ url: z.string().optional(),
+ events: z.array(z.string()).optional(),
+ sources: z.array(z.string()).optional(),
+ listId: z.string().optional()
+ })
+ )
+ .optional(),
+ deleted: z.boolean().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiUrl: ctx.config.apiUrl
+ });
+
+ switch (ctx.input.action) {
+ case 'create': {
+ if (
+ !ctx.input.name ||
+ !ctx.input.url ||
+ !ctx.input.events?.length ||
+ !ctx.input.sources?.length
+ ) {
+ throw activeCampaignServiceError(
+ 'name, url, events, and sources are required for creating a webhook'
+ );
+ }
+
+ let result = await client.createWebhook({
+ name: ctx.input.name,
+ url: ctx.input.url,
+ events: ctx.input.events,
+ sources: ctx.input.sources,
+ listid: ctx.input.listId
+ });
+ let webhook = mapWebhook(result.webhook);
+
+ return {
+ output: { webhook },
+ message: `Webhook **${webhook.name || webhook.webhookId}** created.`
+ };
+ }
+ case 'delete': {
+ if (!ctx.input.webhookId) {
+ throw activeCampaignServiceError('webhookId is required for deleting a webhook');
+ }
+
+ await client.deleteWebhook(ctx.input.webhookId);
+ return {
+ output: { deleted: true },
+ message: `Webhook (ID: ${ctx.input.webhookId}) deleted.`
+ };
+ }
+ case 'list': {
+ let params: Record = {};
+ if (ctx.input.limit) params.limit = ctx.input.limit;
+ if (ctx.input.offset) params.offset = ctx.input.offset;
+
+ let result = await client.listWebhooks(params);
+ let webhooks = (result.webhooks || []).map(mapWebhook);
+
+ return {
+ output: { webhooks },
+ message: `Found **${webhooks.length}** webhooks.`
+ };
+ }
+ }
+ })
+ .build();
diff --git a/integrations/activecampaign/src/tools/search-accounts.ts b/integrations/activecampaign/src/tools/search-accounts.ts
index 057446d7c7..a9b5436f09 100644
--- a/integrations/activecampaign/src/tools/search-accounts.ts
+++ b/integrations/activecampaign/src/tools/search-accounts.ts
@@ -15,6 +15,10 @@ export let searchAccounts = SlateTool.create(spec, {
.input(
z.object({
search: z.string().optional().describe('Search term to filter accounts by name'),
+ includeCounts: z
+ .boolean()
+ .optional()
+ .describe('Whether ActiveCampaign should compute contact and deal counts'),
limit: z.number().optional().describe('Maximum number of accounts to return'),
offset: z.number().optional().describe('Pagination offset')
})
@@ -41,6 +45,7 @@ export let searchAccounts = SlateTool.create(spec, {
let params: Record = {};
if (ctx.input.search) params.search = ctx.input.search;
+ if (ctx.input.includeCounts !== undefined) params.count_deals = ctx.input.includeCounts;
if (ctx.input.limit) params.limit = ctx.input.limit;
if (ctx.input.offset) params.offset = ctx.input.offset;
diff --git a/integrations/activecampaign/src/tools/search-contacts.ts b/integrations/activecampaign/src/tools/search-contacts.ts
index 43ded8df2e..a6e0ca6f1b 100644
--- a/integrations/activecampaign/src/tools/search-contacts.ts
+++ b/integrations/activecampaign/src/tools/search-contacts.ts
@@ -16,6 +16,10 @@ export let searchContacts = SlateTool.create(spec, {
z.object({
search: z.string().optional().describe('Free-text search query across contact fields'),
email: z.string().optional().describe('Filter by exact email address'),
+ emailLike: z
+ .string()
+ .optional()
+ .describe('Filter contacts whose email contains this value'),
listId: z.string().optional().describe('Filter by list ID'),
tagId: z.string().optional().describe('Filter by tag ID'),
status: z
@@ -28,7 +32,15 @@ export let searchContacts = SlateTool.create(spec, {
.number()
.optional()
.describe('Maximum number of contacts to return (default 20, max 100)'),
- offset: z.number().optional().describe('Number of contacts to skip for pagination')
+ offset: z.number().optional().describe('Number of contacts to skip for pagination'),
+ idGreater: z
+ .number()
+ .optional()
+ .describe('Only return contacts with an ID greater than this value'),
+ orderById: z
+ .enum(['asc', 'desc'])
+ .optional()
+ .describe('Order contacts by ID; use with idGreater for large-account pagination')
})
)
.output(
@@ -59,11 +71,14 @@ export let searchContacts = SlateTool.create(spec, {
let params: Record = {};
if (ctx.input.search) params.search = ctx.input.search;
if (ctx.input.email) params.email = ctx.input.email;
+ if (ctx.input.emailLike) params.email_like = ctx.input.emailLike;
if (ctx.input.listId) params.listid = ctx.input.listId;
if (ctx.input.tagId) params.tagid = ctx.input.tagId;
if (ctx.input.status !== undefined) params.status = ctx.input.status;
if (ctx.input.limit) params.limit = ctx.input.limit;
if (ctx.input.offset) params.offset = ctx.input.offset;
+ if (ctx.input.idGreater !== undefined) params.id_greater = ctx.input.idGreater;
+ if (ctx.input.orderById) params['orders[id]'] = ctx.input.orderById;
let result = await client.listContacts(params);
diff --git a/integrations/adobe-sign/README.md b/integrations/adobe-sign/README.md
index 88e15102de..1d5d901d9f 100644
--- a/integrations/adobe-sign/README.md
+++ b/integrations/adobe-sign/README.md
@@ -20,22 +20,50 @@ Create an embeddable web form (widget) that generates a unique signing URL. Each
Download the audit trail PDF for an agreement. The audit trail captures the complete history of events including creation, viewing, signing, delegation, and authentication actions.
+### Download Agreement Document
+
+List or download documents attached to an Adobe Acrobat Sign agreement. Downloads return the file through a Slate attachment; use documentId "combined" or omit documentId to download one combined PDF.
+
### Get Agreement
Retrieve detailed information about a specific agreement including its status, participants, documents, and metadata. Optionally fetch signing URLs, form field data, or event history for the agreement.
+### Get Agreement Members
+
+Retrieve sender, participant set, next participant, CC, and share information for an Adobe Acrobat Sign agreement.
+
+### Get Bulk Send
+
+Retrieve detailed information about a Send in Bulk (MegaSign) parent agreement.
+
### Get Agreement Form Data
-Retrieve form field data from a completed or in-progress agreement. Returns the values that participants have entered into form fields, useful for extracting data from signed documents.
+Retrieve form field data from a completed or in-progress agreement as a Slate attachment.
+
+### Get Library Template
+
+Retrieve detailed information about an Adobe Acrobat Sign library template.
### Get Signing URLs
Retrieve signing URLs for an agreement. These URLs can be used for embedded signing within your application. Only available when the agreement is waiting for one or more participants to sign.
+### Get User
+
+Retrieve detailed information for a user in the Adobe Acrobat Sign account.
+
+### Get Web Form
+
+Retrieve detailed information about an Adobe Acrobat Sign web form (widget).
+
### List Agreements
List agreements in the account with optional filtering. Returns a paginated list of agreements with their basic details and current status.
+### List Bulk Sends
+
+List Send in Bulk (MegaSign) parent agreements in the Adobe Acrobat Sign account with pagination.
+
### List Library Templates
List available library document templates. Returns reusable templates that can be referenced when creating agreements or web forms.
@@ -50,7 +78,7 @@ List web forms (widgets) in the account. Returns embeddable signing forms with t
### Send in Bulk
-Send the same agreement to a large number of recipients simultaneously (MegaSign). Each recipient receives a personalized signing experience. Useful for mass onboarding, policy acknowledgments, or form collection.
+Send the same agreement to many recipients using Adobe Acrobat Sign Send in Bulk (MegaSign). Current v6 bulk sends require a CSV transient document containing child agreement recipient information.
### Send Reminder
@@ -60,6 +88,18 @@ Send a reminder to participants who have not yet completed their actions on an a
Cancel or expire an agreement by updating its state. Use this to cancel agreements that are in progress, or to perform other state transitions.
+### Update Bulk Send State
+
+Update a Send in Bulk (MegaSign) parent agreement state, primarily to cancel an in-progress bulk send.
+
+### Update Library Template State
+
+Update the state of an Adobe Acrobat Sign library template, including activating, returning to authoring, or removing a template.
+
+### Update Web Form State
+
+Update an Adobe Acrobat Sign web form state, such as activating, deactivating, moving to authoring, or cancelling a web form.
+
### Upload Document
Upload a file to Adobe Sign as a transient document. Transient documents are temporary files (valid for 7 days) that can be referenced when creating agreements, web forms, or library templates. You must upload a document before using it in any signing workflow.
diff --git a/integrations/adobe-sign/package.json b/integrations/adobe-sign/package.json
index 5a632ed56f..dcfcd8ee03 100644
--- a/integrations/adobe-sign/package.json
+++ b/integrations/adobe-sign/package.json
@@ -7,12 +7,13 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
"typescript": "^5"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.6"
}
diff --git a/integrations/adobe-sign/src/auth.ts b/integrations/adobe-sign/src/auth.ts
index dd484cd584..3a1727c6b2 100644
--- a/integrations/adobe-sign/src/auth.ts
+++ b/integrations/adobe-sign/src/auth.ts
@@ -1,5 +1,6 @@
import { createAxios, SlateAuth } from 'slates';
import { z } from 'zod';
+import { adobeSignRequest, adobeSignServiceError } from './lib/errors';
let scopes = [
{ title: 'Read Users', description: 'Read user information', scope: 'user_read:account' },
@@ -49,6 +50,16 @@ let scopes = [
description: 'Create and modify workflows',
scope: 'workflow_write:account'
},
+ {
+ title: 'Read Web Forms',
+ description: 'Read web form details',
+ scope: 'widget_read:account'
+ },
+ {
+ title: 'Write Web Forms',
+ description: 'Create and modify web forms',
+ scope: 'widget_write:account'
+ },
{
title: 'Read Webhooks',
description: 'Read webhook configurations',
@@ -84,23 +95,33 @@ function createAdobeSignOauth(name: string, key: string, shard: Shard) {
handleCallback: async (ctx: any) => {
let ax = createAxios({ baseURL: `https://api.${shard}.adobesign.com` });
- let tokenResponse = await ax.post(
- '/oauth/v2/token',
- new URLSearchParams({
- grant_type: 'authorization_code',
- code: ctx.code,
- client_id: ctx.clientId,
- client_secret: ctx.clientSecret,
- redirect_uri: ctx.redirectUri
- }).toString(),
- { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
+ let tokenResponse = await adobeSignRequest('OAuth token exchange', () =>
+ ax.post(
+ '/oauth/v2/token',
+ new URLSearchParams({
+ grant_type: 'authorization_code',
+ code: ctx.code,
+ client_id: ctx.clientId,
+ client_secret: ctx.clientSecret,
+ redirect_uri: ctx.redirectUri
+ }).toString(),
+ { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
+ )
);
let data = tokenResponse.data;
+ if (!data.access_token) {
+ throw adobeSignServiceError(
+ 'Adobe Acrobat Sign OAuth response did not include an access token.'
+ );
+ }
+
let expiresAt = new Date(Date.now() + (data.expires_in || 3600) * 1000).toISOString();
- let baseUriResponse = await ax.get('/api/rest/v6/baseUris', {
- headers: { Authorization: `Bearer ${data.access_token}` }
- });
+ let baseUriResponse = await adobeSignRequest('base URI lookup', () =>
+ ax.get('/api/rest/v6/baseUris', {
+ headers: { Authorization: `Bearer ${data.access_token}` }
+ })
+ );
let apiBaseUrl =
baseUriResponse.data.apiAccessPoint || `https://api.${shard}.adobesign.com/`;
@@ -116,23 +137,35 @@ function createAdobeSignOauth(name: string, key: string, shard: Shard) {
},
handleTokenRefresh: async (ctx: any) => {
+ if (!ctx.output.refreshToken) {
+ throw adobeSignServiceError('No Adobe Acrobat Sign refresh token is available.');
+ }
+
let ax = createAxios({ baseURL: `https://api.${shard}.adobesign.com` });
- let refreshResponse = await ax.post(
- '/oauth/v2/refresh',
- new URLSearchParams({
- grant_type: 'refresh_token',
- refresh_token: ctx.output.refreshToken || '',
- client_id: ctx.clientId,
- client_secret: ctx.clientSecret
- }).toString(),
- { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
+ let refreshResponse = await adobeSignRequest('OAuth token refresh', () =>
+ ax.post(
+ '/oauth/v2/refresh',
+ new URLSearchParams({
+ grant_type: 'refresh_token',
+ refresh_token: ctx.output.refreshToken,
+ client_id: ctx.clientId,
+ client_secret: ctx.clientSecret
+ }).toString(),
+ { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
+ )
);
let data = refreshResponse.data;
+ if (!data.access_token) {
+ throw adobeSignServiceError(
+ 'Adobe Acrobat Sign refresh response did not include an access token.'
+ );
+ }
+
let expiresAt = new Date(Date.now() + (data.expires_in || 3600) * 1000).toISOString();
return {
output: {
token: data.access_token,
- refreshToken: ctx.output.refreshToken,
+ refreshToken: data.refresh_token || ctx.output.refreshToken,
expiresAt,
apiBaseUrl: ctx.output.apiBaseUrl,
shard
@@ -143,9 +176,11 @@ function createAdobeSignOauth(name: string, key: string, shard: Shard) {
getProfile: async (ctx: any) => {
let baseUrl = ctx.output.apiBaseUrl || `https://api.${shard}.adobesign.com/`;
let ax = createAxios({ baseURL: baseUrl });
- let response = await ax.get('/api/rest/v6/users/me', {
- headers: { Authorization: `Bearer ${ctx.output.token}` }
- });
+ let response = await adobeSignRequest('profile lookup', () =>
+ ax.get('/api/rest/v6/users/me', {
+ headers: { Authorization: `Bearer ${ctx.output.token}` }
+ })
+ );
let user = response.data;
return {
profile: {
@@ -172,10 +207,16 @@ function createAdobeSignIntegrationKey(name: string, key: string, shard: Shard)
)
}),
getOutput: async (ctx: { input: { integrationKey: string } }) => {
+ if (!ctx.input.integrationKey.trim()) {
+ throw adobeSignServiceError('integrationKey is required.');
+ }
+
let ax = createAxios({ baseURL: `https://api.${shard}.adobesign.com` });
- let baseUriResponse = await ax.get('/api/rest/v6/baseUris', {
- headers: { Authorization: `Bearer ${ctx.input.integrationKey}` }
- });
+ let baseUriResponse = await adobeSignRequest('base URI lookup', () =>
+ ax.get('/api/rest/v6/baseUris', {
+ headers: { Authorization: `Bearer ${ctx.input.integrationKey}` }
+ })
+ );
let apiBaseUrl =
baseUriResponse.data.apiAccessPoint || `https://api.${shard}.adobesign.com/`;
return {
@@ -189,9 +230,11 @@ function createAdobeSignIntegrationKey(name: string, key: string, shard: Shard)
getProfile: async (ctx: any) => {
let baseUrl = ctx.output.apiBaseUrl || `https://api.${shard}.adobesign.com/`;
let ax = createAxios({ baseURL: baseUrl });
- let response = await ax.get('/api/rest/v6/users/me', {
- headers: { Authorization: `Bearer ${ctx.output.token}` }
- });
+ let response = await adobeSignRequest('profile lookup', () =>
+ ax.get('/api/rest/v6/users/me', {
+ headers: { Authorization: `Bearer ${ctx.output.token}` }
+ })
+ );
let user = response.data;
return {
profile: {
diff --git a/integrations/adobe-sign/src/index.ts b/integrations/adobe-sign/src/index.ts
index 89269f88d5..13afa59414 100644
--- a/integrations/adobe-sign/src/index.ts
+++ b/integrations/adobe-sign/src/index.ts
@@ -4,17 +4,27 @@ import {
createAgreement,
createLibraryTemplate,
createWebForm,
+ downloadAgreementDocument,
downloadAuditTrail,
getAgreement,
+ getAgreementMembers,
+ getBulkSend,
getFormData,
+ getLibraryTemplate,
getSigningUrls,
+ getUser,
+ getWebForm,
listAgreements,
+ listBulkSends,
listLibraryTemplates,
listUsers,
listWebForms,
sendInBulk,
sendReminder,
updateAgreementState,
+ updateBulkSendState,
+ updateLibraryTemplateState,
+ updateWebFormState,
uploadDocument
} from './tools';
import { agreementEvents, megaSignEvents, webFormEvents } from './triggers';
@@ -26,16 +36,26 @@ export let provider = Slate.create({
createAgreement,
getAgreement,
listAgreements,
+ downloadAgreementDocument,
+ getAgreementMembers,
updateAgreementState,
getSigningUrls,
sendReminder,
downloadAuditTrail,
getFormData,
createWebForm,
+ getWebForm,
listWebForms,
+ updateWebFormState,
createLibraryTemplate,
+ getLibraryTemplate,
listLibraryTemplates,
+ updateLibraryTemplateState,
sendInBulk,
+ getBulkSend,
+ listBulkSends,
+ updateBulkSendState,
+ getUser,
listUsers
] as any,
triggers: [agreementEvents, webFormEvents, megaSignEvents] as any
diff --git a/integrations/adobe-sign/src/lib/client.ts b/integrations/adobe-sign/src/lib/client.ts
index 998b6e5707..38c15067e6 100644
--- a/integrations/adobe-sign/src/lib/client.ts
+++ b/integrations/adobe-sign/src/lib/client.ts
@@ -1,13 +1,50 @@
import { createAxios } from 'slates';
+import { adobeSignApiError, adobeSignServiceError } from './errors';
+
+type AgreementFileInfo = {
+ transientDocumentId?: string;
+ libraryDocumentId?: string;
+ urlFileInfo?: { url: string; name?: string; mimeType?: string };
+};
+
+let validateBase64 = (value: string, fieldName: string) => {
+ if (!value.trim()) {
+ throw adobeSignServiceError(`${fieldName} must contain base64-encoded file content.`);
+ }
+
+ try {
+ return atob(value);
+ } catch (error) {
+ let serviceError = adobeSignServiceError(`${fieldName} must be valid base64 data.`);
+ if (error instanceof Error) serviceError.setParent(error);
+ throw serviceError;
+ }
+};
+
+let validateFileInfos = (fileInfos: AgreementFileInfo[], label: string) => {
+ if (fileInfos.length === 0) {
+ throw adobeSignServiceError(`${label} requires at least one fileInfo.`);
+ }
+
+ for (let [index, fileInfo] of fileInfos.entries()) {
+ let sourceCount = [
+ fileInfo.transientDocumentId,
+ fileInfo.libraryDocumentId,
+ fileInfo.urlFileInfo?.url
+ ].filter(Boolean).length;
+
+ if (sourceCount !== 1) {
+ throw adobeSignServiceError(
+ `${label} fileInfos[${index}] must provide exactly one of transientDocumentId, libraryDocumentId, or urlFileInfo.url.`
+ );
+ }
+ }
+};
export class Client {
private ax;
- constructor(config: {
- token: string;
- apiBaseUrl?: string;
- shard?: string;
- }) {
+ constructor(config: { token: string; apiBaseUrl?: string; shard?: string }) {
let baseURL = config.apiBaseUrl || `https://api.${config.shard || 'na1'}.adobesign.com/`;
// Ensure trailing slash is removed for consistent URL joining
if (baseURL.endsWith('/')) {
@@ -19,6 +56,10 @@ export class Client {
Authorization: `Bearer ${config.token}`
}
});
+ this.ax.interceptors.response.use(
+ (response: any) => response,
+ (error: unknown) => Promise.reject(adobeSignApiError(error))
+ );
}
// ── Transient Documents ────────────────────────────────────────────
@@ -28,12 +69,16 @@ export class Client {
fileContent: string; // base64 encoded
mimeType?: string;
}): Promise<{ transientDocumentId: string }> {
+ if (!params.fileName.trim()) {
+ throw adobeSignServiceError('fileName is required.');
+ }
+
// Build multipart form data manually
let boundary = `----SlatesFormBoundary${Date.now().toString(36)}`;
let mimeType = params.mimeType || 'application/pdf';
// Decode base64 to binary
- let binaryString = atob(params.fileContent);
+ let binaryString = validateBase64(params.fileContent, 'fileContent');
let bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
@@ -73,11 +118,7 @@ export class Client {
role: string;
order?: number;
}>;
- fileInfos: Array<{
- transientDocumentId?: string;
- libraryDocumentId?: string;
- urlFileInfo?: { url: string; name?: string; mimeType?: string };
- }>;
+ fileInfos: AgreementFileInfo[];
signatureType?: string;
state?: string;
ccs?: Array<{ email: string }>;
@@ -86,6 +127,8 @@ export class Client {
reminderFrequency?: string;
expirationTime?: string;
}): Promise {
+ validateFileInfos(params.fileInfos, 'Agreement creation');
+
let body: any = {
name: params.name,
participantSetsInfo: params.participantSetsInfo,
@@ -166,8 +209,20 @@ export class Client {
return response.data;
}
- async getAgreementFormData(agreementId: string): Promise {
- let response = await this.ax.get(`/api/rest/v6/agreements/${agreementId}/formData`);
+ async getAgreementCombinedDocument(agreementId: string): Promise {
+ let response = await this.ax.get(
+ `/api/rest/v6/agreements/${agreementId}/combinedDocument`,
+ {
+ responseType: 'arraybuffer'
+ }
+ );
+ return response.data;
+ }
+
+ async getAgreementFormData(agreementId: string): Promise {
+ let response = await this.ax.get(`/api/rest/v6/agreements/${agreementId}/formData`, {
+ responseType: 'text'
+ });
return response.data;
}
@@ -185,17 +240,30 @@ export class Client {
frequency?: string;
firstReminderDelay?: number;
}): Promise {
+ if (!params.recipientParticipantIds || params.recipientParticipantIds.length === 0) {
+ throw adobeSignServiceError(
+ 'recipientParticipantIds is required to create an Adobe Acrobat Sign reminder.'
+ );
+ }
+
let body: any = {
- agreementId: params.agreementId
+ status: 'ACTIVE',
+ recipientParticipantIds: params.recipientParticipantIds
};
- if (params.recipientParticipantIds)
- body.recipientParticipantIds = params.recipientParticipantIds;
- if (params.comment) body.comment = params.comment;
+ if (params.comment) body.note = params.comment;
if (params.frequency) body.frequency = params.frequency;
if (params.firstReminderDelay !== undefined)
body.firstReminderDelay = params.firstReminderDelay;
- let response = await this.ax.post('/api/rest/v6/reminders', body);
+ let response = await this.ax.post(
+ `/api/rest/v6/agreements/${params.agreementId}/reminders`,
+ body
+ );
+ return response.data;
+ }
+
+ async listAgreementReminders(agreementId: string): Promise {
+ let response = await this.ax.get(`/api/rest/v6/agreements/${agreementId}/reminders`);
return response.data;
}
@@ -203,29 +271,34 @@ export class Client {
async createWebForm(params: {
name: string;
- fileInfos: Array<{
- transientDocumentId?: string;
- libraryDocumentId?: string;
- }>;
- participantSetsInfo?: Array<{
- memberInfos: Array<{ email: string }>;
+ fileInfos: AgreementFileInfo[];
+ widgetParticipantSetInfo: {
+ memberInfos: Array<{ email?: string; securityOption?: any }>;
role: string;
- }>;
+ };
state?: string;
additionalParticipantSetsInfo?: Array<{
memberInfos: Array<{ email: string }>;
role: string;
}>;
+ ccs?: Array<{ email: string }>;
}): Promise {
+ validateFileInfos(params.fileInfos, 'Web form creation');
+ if (params.fileInfos.some(fileInfo => fileInfo.libraryDocumentId)) {
+ throw adobeSignServiceError(
+ 'Web form creation does not support libraryDocumentId in current Adobe Acrobat Sign v6.'
+ );
+ }
+
let body: any = {
name: params.name,
fileInfos: params.fileInfos,
+ widgetParticipantSetInfo: params.widgetParticipantSetInfo,
state: params.state || 'ACTIVE'
};
- if (params.participantSetsInfo)
- body.widgetParticipantSetInfo = { participantSetInfos: params.participantSetsInfo };
if (params.additionalParticipantSetsInfo)
body.additionalParticipantSetsInfo = params.additionalParticipantSetsInfo;
+ if (params.ccs) body.ccs = params.ccs;
let response = await this.ax.post('/api/rest/v6/widgets', body);
return response.data;
@@ -247,10 +320,9 @@ export class Client {
async updateWebFormState(widgetId: string, state: string, message?: string): Promise {
let body: any = {
- state,
- widgetStatus: state
+ state
};
- if (message) body.message = message;
+ if (message) body.widgetInActiveInfo = { message };
await this.ax.put(`/api/rest/v6/widgets/${widgetId}/state`, body);
}
@@ -265,13 +337,15 @@ export class Client {
sharingMode?: string;
state?: string;
}): Promise {
+ validateFileInfos(params.fileInfos, 'Library template creation');
+
let body: any = {
name: params.name,
fileInfos: params.fileInfos,
templateTypes: params.templateTypes,
+ sharingMode: params.sharingMode || 'USER',
state: params.state || 'ACTIVE'
};
- if (params.sharingMode) body.sharingMode = params.sharingMode;
let response = await this.ax.post('/api/rest/v6/libraryDocuments', body);
return response.data;
@@ -291,6 +365,10 @@ export class Client {
return response.data;
}
+ async updateLibraryDocumentState(libraryDocumentId: string, state: string): Promise {
+ await this.ax.put(`/api/rest/v6/libraryDocuments/${libraryDocumentId}/state`, { state });
+ }
+
// ── MegaSign (Send in Bulk) ────────────────────────────────────────
async createMegaSign(params: {
@@ -299,26 +377,33 @@ export class Client {
transientDocumentId?: string;
libraryDocumentId?: string;
}>;
- recipientSetInfos: Array<{
- recipientSetMemberInfos: Array<{ email: string }>;
- }>;
+ childAgreementsTransientDocumentId: string;
signatureType?: string;
state?: string;
message?: string;
ccs?: Array<{ email: string }>;
}): Promise {
+ validateFileInfos(params.fileInfos, 'Send in Bulk creation');
+ if (!params.childAgreementsTransientDocumentId.trim()) {
+ throw adobeSignServiceError(
+ 'childAgreementsTransientDocumentId is required for Send in Bulk creation.'
+ );
+ }
+
let body: any = {
name: params.name,
fileInfos: params.fileInfos,
- megaSignInput: {
- recipientSetInfos: params.recipientSetInfos,
- signatureType: params.signatureType || 'ESIGN',
- name: params.name
+ childAgreementsInfo: {
+ fileInfo: {
+ transientDocumentId: params.childAgreementsTransientDocumentId,
+ fileType: 'CSV'
+ }
},
+ signatureType: params.signatureType || 'ESIGN',
state: params.state || 'IN_PROCESS'
};
- if (params.message) body.megaSignInput.message = params.message;
- if (params.ccs) body.megaSignInput.ccs = params.ccs;
+ if (params.message) body.message = params.message;
+ if (params.ccs) body.ccs = params.ccs;
let response = await this.ax.post('/api/rest/v6/megaSigns', body);
return response.data;
@@ -338,6 +423,18 @@ export class Client {
return response.data;
}
+ async updateMegaSignState(
+ megaSignId: string,
+ state: string,
+ params?: { cancellationInfo?: { comment?: string; notifyOthers?: boolean } }
+ ): Promise {
+ let body: any = { state };
+ if (params?.cancellationInfo) {
+ body.megaSignCancellationInfo = params.cancellationInfo;
+ }
+ await this.ax.put(`/api/rest/v6/megaSigns/${megaSignId}/state`, body);
+ }
+
// ── Users ──────────────────────────────────────────────────────────
async listUsers(params?: { cursor?: string; pageSize?: number }): Promise {
diff --git a/integrations/adobe-sign/src/lib/errors.ts b/integrations/adobe-sign/src/lib/errors.ts
new file mode 100644
index 0000000000..c52a46ffce
--- /dev/null
+++ b/integrations/adobe-sign/src/lib/errors.ts
@@ -0,0 +1,90 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null && !Array.isArray(value);
+
+let pushDetail = (details: string[], value: unknown) => {
+ if (typeof value !== 'string' && typeof value !== 'number') return;
+
+ let detail = String(value).trim();
+ if (detail && !details.includes(detail)) details.push(detail);
+};
+
+let collectDetails = (value: unknown, details: string[]) => {
+ if (Array.isArray(value)) {
+ for (let item of value) collectDetails(item, details);
+ return;
+ }
+
+ if (!isRecord(value)) {
+ pushDetail(details, value);
+ return;
+ }
+
+ pushDetail(details, value.reason);
+ pushDetail(details, value.message);
+ pushDetail(details, value.error_description);
+ pushDetail(details, value.error);
+ pushDetail(details, value.code);
+ collectDetails(value.errors, details);
+};
+
+let extractAdobeSignMessage = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let details: string[] = [];
+
+ collectDetails(response?.data, details);
+
+ if (details.length > 0) return details.join(' - ');
+ if (error instanceof Error && error.message) return error.message;
+ return 'Unknown error';
+};
+
+let statusLabelFor = (response?: ErrorResponse) =>
+ response?.status !== undefined
+ ? `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+
+let upstreamCodeFor = (response?: ErrorResponse) => {
+ if (!isRecord(response?.data)) return undefined;
+
+ let code = response.data.code ?? response.data.error;
+ if (typeof code === 'string' || typeof code === 'number') return String(code);
+
+ let reason = response.data.reason;
+ if (typeof reason !== 'string') return undefined;
+ return reason.split(':')[0]?.trim();
+};
+
+export let adobeSignServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let adobeSignApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) return error;
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let serviceError = adobeSignServiceError(
+ `Adobe Acrobat Sign API ${operation} failed: ${statusLabelFor(response)}${extractAdobeSignMessage(error)}`
+ );
+ serviceError.data.reason = 'adobe_sign_api_error';
+ serviceError.data.upstreamStatus = response?.status;
+ serviceError.data.upstreamCode = upstreamCodeFor(response);
+
+ if (error instanceof Error) serviceError.setParent(error);
+
+ return serviceError;
+};
+
+export let adobeSignRequest = async (operation: string, run: () => Promise) => {
+ try {
+ return await run();
+ } catch (error) {
+ throw adobeSignApiError(error, operation);
+ }
+};
diff --git a/integrations/adobe-sign/src/tools/create-web-form.ts b/integrations/adobe-sign/src/tools/create-web-form.ts
index ec9fcabeb0..b339e7eaaf 100644
--- a/integrations/adobe-sign/src/tools/create-web-form.ts
+++ b/integrations/adobe-sign/src/tools/create-web-form.ts
@@ -9,7 +9,8 @@ export let createWebForm = SlateTool.create(spec, {
description: `Create an embeddable web form (widget) that generates a unique signing URL. Each time a participant fills in the web form, a new agreement is generated. Web forms can be embedded on websites or shared via link.`,
instructions: [
'Upload the document first using the Upload Document tool, then reference the transientDocumentId.',
- 'A library template ID can also be used instead of a transient document.'
+ 'Current Adobe Acrobat Sign v6 web form creation supports transientDocumentId or urlFileInfo documents, not libraryDocumentId.',
+ 'The primary web form participant has an unknown email at creation time; set participantRole and optional participantSecurityOption instead of an email address.'
],
tags: {
destructive: false,
@@ -26,14 +27,31 @@ export let createWebForm = SlateTool.create(spec, {
.string()
.optional()
.describe('ID of a previously uploaded transient document'),
- libraryDocumentId: z
- .string()
+ urlFileInfo: z
+ .object({
+ url: z.string().describe('Public URL of the document'),
+ name: z.string().optional().describe('Display name for the document'),
+ mimeType: z.string().optional().describe('MIME type of the document')
+ })
.optional()
- .describe('ID of a library document template')
+ .describe('URL-based document reference')
})
)
.describe('Documents to use in the web form'),
- participantSetsInfo: z
+ participantRole: z
+ .enum(['SIGNER', 'APPROVER', 'ACCEPTOR', 'FORM_FILLER', 'CERTIFIED_RECIPIENT'])
+ .optional()
+ .describe('Role of the unknown primary web form participant. Defaults to SIGNER.'),
+ participantSecurityOption: z
+ .object({
+ authenticationMethod: z
+ .enum(['NONE', 'PASSWORD', 'PHONE', 'KBA', 'EMAIL_OTP'])
+ .optional()
+ .describe('Authentication method for the unknown primary participant')
+ })
+ .optional()
+ .describe('Optional security settings for the unknown primary web form participant'),
+ additionalParticipantSetsInfo: z
.array(
z.object({
memberInfos: z
@@ -49,7 +67,15 @@ export let createWebForm = SlateTool.create(spec, {
})
)
.optional()
- .describe('Pre-defined participant sets for the web form'),
+ .describe('Additional participants that act after the web form signer'),
+ ccs: z
+ .array(
+ z.object({
+ email: z.string().describe('Email address to CC')
+ })
+ )
+ .optional()
+ .describe('Email addresses to CC when web form agreements complete'),
state: z
.enum(['ACTIVE', 'DRAFT', 'AUTHORING'])
.optional()
@@ -73,7 +99,16 @@ export let createWebForm = SlateTool.create(spec, {
let result = await client.createWebForm({
name: ctx.input.name,
fileInfos: ctx.input.fileInfos,
- participantSetsInfo: ctx.input.participantSetsInfo,
+ widgetParticipantSetInfo: {
+ role: ctx.input.participantRole || 'SIGNER',
+ memberInfos: [
+ ctx.input.participantSecurityOption
+ ? { securityOption: ctx.input.participantSecurityOption }
+ : {}
+ ]
+ },
+ additionalParticipantSetsInfo: ctx.input.additionalParticipantSetsInfo,
+ ccs: ctx.input.ccs,
state: ctx.input.state
});
diff --git a/integrations/adobe-sign/src/tools/download-agreement-document.ts b/integrations/adobe-sign/src/tools/download-agreement-document.ts
new file mode 100644
index 0000000000..3ed95098d4
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/download-agreement-document.ts
@@ -0,0 +1,126 @@
+import { createBase64Attachment, SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+let toBase64AttachmentContent = (data: unknown) => {
+ if (typeof data === 'string') {
+ let buffer = Buffer.from(data, 'binary');
+ return { base64: buffer.toString('base64'), byteLength: buffer.byteLength };
+ }
+
+ if (data instanceof ArrayBuffer) {
+ let buffer = Buffer.from(data);
+ return { base64: buffer.toString('base64'), byteLength: buffer.byteLength };
+ }
+
+ if (ArrayBuffer.isView(data)) {
+ let buffer = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
+ return { base64: buffer.toString('base64'), byteLength: buffer.byteLength };
+ }
+
+ let buffer = Buffer.from(JSON.stringify(data), 'utf8');
+ return { base64: buffer.toString('base64'), byteLength: buffer.byteLength };
+};
+
+export let downloadAgreementDocument = SlateTool.create(spec, {
+ name: 'Download Agreement Document',
+ key: 'download_agreement_document',
+ description: `List or download documents attached to an Adobe Acrobat Sign agreement. Downloads return the file through a Slate attachment; use documentId "combined" or omit documentId to download one combined PDF.`,
+ instructions: [
+ 'Set listOnly to true to inspect available document IDs before downloading.',
+ 'Omit documentId, or set it to "combined", to download the combined agreement PDF.',
+ 'Use a specific documentId from listOnly output to download one agreement document.'
+ ],
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ agreementId: z.string().describe('ID of the agreement containing the document'),
+ documentId: z
+ .string()
+ .optional()
+ .describe('Document ID to download. Use "combined" or omit for the combined PDF.'),
+ listOnly: z
+ .boolean()
+ .optional()
+ .default(false)
+ .describe('If true, only list available documents without downloading content')
+ })
+ )
+ .output(
+ z.object({
+ agreementId: z.string().describe('ID of the agreement'),
+ documents: z
+ .array(
+ z.object({
+ documentId: z.string().describe('ID of the document'),
+ label: z.string().optional().describe('Document label or name'),
+ createdDate: z.string().optional().describe('Document creation date'),
+ numPages: z.number().optional().describe('Number of pages')
+ })
+ )
+ .describe('Available agreement documents'),
+ documentId: z.string().optional().describe('Downloaded document ID or "combined"'),
+ documentName: z.string().optional().describe('Best-effort display name'),
+ mimeType: z.string().optional().describe('MIME type of the attachment'),
+ byteLength: z.number().optional().describe('Attachment size in bytes'),
+ attachmentCount: z.number().optional().describe('Number of attachments returned')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ let documentList = await client.getAgreementDocuments(ctx.input.agreementId);
+ let documents = (documentList.documents || []).map((document: any) => ({
+ documentId: document.id,
+ label: document.label,
+ createdDate: document.createdDate,
+ numPages: document.numPages
+ }));
+
+ if (ctx.input.listOnly) {
+ return {
+ output: {
+ agreementId: ctx.input.agreementId,
+ documents
+ },
+ message: `Agreement \`${ctx.input.agreementId}\` has **${documents.length}** document(s).`
+ };
+ }
+
+ let targetDocumentId = ctx.input.documentId || 'combined';
+ let data =
+ targetDocumentId === 'combined'
+ ? await client.getAgreementCombinedDocument(ctx.input.agreementId)
+ : await client.downloadAgreementDocument(ctx.input.agreementId, targetDocumentId);
+ let attachment = toBase64AttachmentContent(data);
+ let targetDocument = documents.find(
+ (document: { documentId: string }) => document.documentId === targetDocumentId
+ );
+ let documentName =
+ targetDocumentId === 'combined'
+ ? 'Combined Agreement Document'
+ : targetDocument?.label || `Document ${targetDocumentId}`;
+
+ return {
+ output: {
+ agreementId: ctx.input.agreementId,
+ documents,
+ documentId: targetDocumentId,
+ documentName,
+ mimeType: 'application/pdf',
+ byteLength: attachment.byteLength,
+ attachmentCount: 1
+ },
+ attachments: [createBase64Attachment(attachment.base64, 'application/pdf')],
+ message: `Downloaded **${documentName}** for agreement \`${ctx.input.agreementId}\`.`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/get-agreement-members.ts b/integrations/adobe-sign/src/tools/get-agreement-members.ts
new file mode 100644
index 0000000000..0a82379466
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/get-agreement-members.ts
@@ -0,0 +1,54 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let getAgreementMembers = SlateTool.create(spec, {
+ name: 'Get Agreement Members',
+ key: 'get_agreement_members',
+ description: `Retrieve sender, participant set, next participant, CC, and share information for an Adobe Acrobat Sign agreement. Use this to find participant IDs needed for reminders or recipient-level operations.`,
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ agreementId: z.string().describe('ID of the agreement whose members should be retrieved')
+ })
+ )
+ .output(
+ z.object({
+ agreementId: z.string().describe('ID of the agreement'),
+ senderInfo: z.any().optional().describe('Sender information'),
+ participantSets: z.array(z.any()).describe('All participant sets on the agreement'),
+ nextParticipantSets: z
+ .array(z.any())
+ .describe('Participant sets currently expected to act next'),
+ ccsInfo: z.array(z.any()).describe('CC participants on the agreement'),
+ sharesInfo: z.array(z.any()).describe('Agreement share participants')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ let result = await client.getAgreementMembers(ctx.input.agreementId);
+ let participantSets = result.participantSets || [];
+ let nextParticipantSets = result.nextParticipantSets || [];
+
+ return {
+ output: {
+ agreementId: ctx.input.agreementId,
+ senderInfo: result.senderInfo,
+ participantSets,
+ nextParticipantSets,
+ ccsInfo: result.ccsInfo || [],
+ sharesInfo: result.sharesInfo || []
+ },
+ message: `Agreement \`${ctx.input.agreementId}\` has **${participantSets.length}** participant set(s) and **${nextParticipantSets.length}** next participant set(s).`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/get-agreement.ts b/integrations/adobe-sign/src/tools/get-agreement.ts
index f28f786100..fc4b5dbca8 100644
--- a/integrations/adobe-sign/src/tools/get-agreement.ts
+++ b/integrations/adobe-sign/src/tools/get-agreement.ts
@@ -1,4 +1,4 @@
-import { SlateTool } from 'slates';
+import { createTextAttachment, SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
import { spec } from '../spec';
@@ -50,12 +50,18 @@ export let getAgreement = SlateTool.create(spec, {
.describe(
'Signing URLs for pending signers (only populated if includeSigningUrls is true)'
),
- formData: z
- .any()
+ formDataMimeType: z
+ .string()
.optional()
- .describe(
- 'Form field data from the agreement (only populated if includeFormData is true)'
- ),
+ .describe('MIME type of the form data attachment, if requested'),
+ formDataByteLength: z
+ .number()
+ .optional()
+ .describe('Size of the form data attachment in bytes, if requested'),
+ formDataAttachmentCount: z
+ .number()
+ .optional()
+ .describe('Number of form data attachments returned, if requested'),
events: z
.array(z.any())
.optional()
@@ -82,6 +88,8 @@ export let getAgreement = SlateTool.create(spec, {
documentVisibilityEnabled: agreement.documentVisibilityEnabled
};
+ let attachments: ReturnType[] = [];
+
if (ctx.input.includeSigningUrls) {
try {
let signingUrlsData = await client.getSigningUrls(ctx.input.agreementId);
@@ -95,7 +103,11 @@ export let getAgreement = SlateTool.create(spec, {
if (ctx.input.includeFormData) {
try {
let formData = await client.getAgreementFormData(ctx.input.agreementId);
- output.formData = formData;
+ let content = typeof formData === 'string' ? formData : JSON.stringify(formData);
+ output.formDataMimeType = 'text/csv';
+ output.formDataByteLength = Buffer.byteLength(content, 'utf8');
+ output.formDataAttachmentCount = 1;
+ attachments.push(createTextAttachment(content, 'text/csv'));
} catch (e: any) {
ctx.warn(`Could not fetch form data: ${e.message}`);
}
@@ -112,6 +124,7 @@ export let getAgreement = SlateTool.create(spec, {
return {
output,
+ attachments,
message: `Agreement **${agreement.name}** is in status **${agreement.status}**.`
};
});
diff --git a/integrations/adobe-sign/src/tools/get-bulk-send.ts b/integrations/adobe-sign/src/tools/get-bulk-send.ts
new file mode 100644
index 0000000000..1c76e6c4e1
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/get-bulk-send.ts
@@ -0,0 +1,56 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let getBulkSend = SlateTool.create(spec, {
+ name: 'Get Bulk Send',
+ key: 'get_bulk_send',
+ description: `Retrieve detailed information about a Send in Bulk (MegaSign) parent agreement, including status, sender, child agreement metadata, recipient configuration, and reminder settings.`,
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ bulkSendId: z.string().describe('ID of the Send in Bulk parent agreement')
+ })
+ )
+ .output(
+ z.object({
+ bulkSendId: z.string().describe('ID of the Send in Bulk parent agreement'),
+ name: z.string().optional().describe('Name of the Send in Bulk operation'),
+ status: z.string().optional().describe('Current status'),
+ state: z.string().optional().describe('Current state'),
+ senderEmail: z.string().optional().describe('Email address of the sender'),
+ numChildren: z.number().optional().describe('Number of child agreements'),
+ signatureType: z.string().optional().describe('Signature type'),
+ childAgreementsInfo: z.any().optional().describe('Child agreement metadata'),
+ raw: z.any().describe('Raw Send in Bulk detail returned by Adobe Acrobat Sign')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ let bulkSend = await client.getMegaSign(ctx.input.bulkSendId);
+
+ return {
+ output: {
+ bulkSendId: bulkSend.id || ctx.input.bulkSendId,
+ name: bulkSend.name,
+ status: bulkSend.status,
+ state: bulkSend.state,
+ senderEmail: bulkSend.senderEmail,
+ numChildren: bulkSend.numChildren,
+ signatureType: bulkSend.signatureType,
+ childAgreementsInfo: bulkSend.childAgreementsInfo,
+ raw: bulkSend
+ },
+ message: `Retrieved Send in Bulk \`${bulkSend.id || ctx.input.bulkSendId}\`${bulkSend.status ? ` in status **${bulkSend.status}**` : ''}.`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/get-form-data.ts b/integrations/adobe-sign/src/tools/get-form-data.ts
index 0ab6e68ba4..6c5bdb9ac5 100644
--- a/integrations/adobe-sign/src/tools/get-form-data.ts
+++ b/integrations/adobe-sign/src/tools/get-form-data.ts
@@ -1,4 +1,4 @@
-import { SlateTool } from 'slates';
+import { createTextAttachment, SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
import { spec } from '../spec';
@@ -20,9 +20,9 @@ export let getFormData = SlateTool.create(spec, {
.output(
z.object({
agreementId: z.string().describe('ID of the agreement'),
- formData: z
- .any()
- .describe('Form field data as CSV or structured content from the agreement')
+ mimeType: z.string().describe('MIME type of the returned attachment'),
+ byteLength: z.number().describe('Size of the returned attachment in bytes'),
+ attachmentCount: z.number().describe('Number of attachments returned')
})
)
.handleInvocation(async ctx => {
@@ -33,12 +33,16 @@ export let getFormData = SlateTool.create(spec, {
});
let result = await client.getAgreementFormData(ctx.input.agreementId);
+ let content = typeof result === 'string' ? result : JSON.stringify(result);
return {
output: {
agreementId: ctx.input.agreementId,
- formData: result
+ mimeType: 'text/csv',
+ byteLength: Buffer.byteLength(content, 'utf8'),
+ attachmentCount: 1
},
+ attachments: [createTextAttachment(content, 'text/csv')],
message: `Retrieved form data for agreement \`${ctx.input.agreementId}\`.`
};
});
diff --git a/integrations/adobe-sign/src/tools/get-library-template.ts b/integrations/adobe-sign/src/tools/get-library-template.ts
new file mode 100644
index 0000000000..e81c0a317b
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/get-library-template.ts
@@ -0,0 +1,58 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let getLibraryTemplate = SlateTool.create(spec, {
+ name: 'Get Library Template',
+ key: 'get_library_template',
+ description: `Retrieve detailed information about an Adobe Acrobat Sign library template, including sharing mode, template types, state/status, owner, and file metadata.`,
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ libraryDocumentId: z.string().describe('ID of the library template to retrieve')
+ })
+ )
+ .output(
+ z.object({
+ libraryDocumentId: z.string().describe('ID of the library template'),
+ name: z.string().optional().describe('Template name'),
+ status: z.string().optional().describe('Template status'),
+ state: z.string().optional().describe('Template state'),
+ sharingMode: z.string().optional().describe('Template sharing scope'),
+ templateTypes: z.array(z.string()).optional().describe('Template types'),
+ ownerEmail: z.string().optional().describe('Email of the template owner'),
+ createdDate: z.string().optional().describe('Date the template was created'),
+ modifiedDate: z.string().optional().describe('Date the template was last modified'),
+ raw: z.any().describe('Raw library template detail returned by Adobe Acrobat Sign')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ let template = await client.getLibraryDocument(ctx.input.libraryDocumentId);
+
+ return {
+ output: {
+ libraryDocumentId: template.id || ctx.input.libraryDocumentId,
+ name: template.name,
+ status: template.status,
+ state: template.state,
+ sharingMode: template.sharingMode,
+ templateTypes: template.templateTypes,
+ ownerEmail: template.ownerEmail,
+ createdDate: template.createdDate,
+ modifiedDate: template.modifiedDate,
+ raw: template
+ },
+ message: `Retrieved library template \`${template.id || ctx.input.libraryDocumentId}\`${template.status ? ` in status **${template.status}**` : ''}.`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/get-user.ts b/integrations/adobe-sign/src/tools/get-user.ts
new file mode 100644
index 0000000000..fd34142447
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/get-user.ts
@@ -0,0 +1,56 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let getUser = SlateTool.create(spec, {
+ name: 'Get User',
+ key: 'get_user',
+ description: `Retrieve detailed information for a user in the Adobe Acrobat Sign account, including status, role flags, locale, company, and group/account metadata returned by the API.`,
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ userId: z.string().describe('ID of the Adobe Acrobat Sign user to retrieve')
+ })
+ )
+ .output(
+ z.object({
+ userId: z.string().describe('ID of the user'),
+ email: z.string().optional().describe('Email address'),
+ firstName: z.string().optional().describe('First name'),
+ lastName: z.string().optional().describe('Last name'),
+ company: z.string().optional().describe('Company name'),
+ locale: z.string().optional().describe('User locale'),
+ status: z.string().optional().describe('User status'),
+ isAccountAdmin: z.boolean().optional().describe('Whether the user is an account admin'),
+ raw: z.any().describe('Raw user detail returned by Adobe Acrobat Sign')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ let user = await client.getUser(ctx.input.userId);
+
+ return {
+ output: {
+ userId: user.id || ctx.input.userId,
+ email: user.email,
+ firstName: user.firstName,
+ lastName: user.lastName,
+ company: user.company,
+ locale: user.locale,
+ status: user.status,
+ isAccountAdmin: user.isAccountAdmin,
+ raw: user
+ },
+ message: `Retrieved Adobe Acrobat Sign user \`${user.id || ctx.input.userId}\`${user.email ? ` (${user.email})` : ''}.`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/get-web-form.ts b/integrations/adobe-sign/src/tools/get-web-form.ts
new file mode 100644
index 0000000000..5ed6c4b156
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/get-web-form.ts
@@ -0,0 +1,63 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let getWebForm = SlateTool.create(spec, {
+ name: 'Get Web Form',
+ key: 'get_web_form',
+ description: `Retrieve detailed information about an Adobe Acrobat Sign web form (widget), including status, URL, owner, participants, files, and creation/modification metadata.`,
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ webFormId: z.string().describe('ID of the web form to retrieve')
+ })
+ )
+ .output(
+ z.object({
+ webFormId: z.string().describe('ID of the web form'),
+ name: z.string().optional().describe('Name of the web form'),
+ status: z.string().optional().describe('Current web form status'),
+ url: z.string().optional().describe('Public web form URL'),
+ javascript: z.string().optional().describe('Embeddable JavaScript snippet'),
+ ownerEmail: z.string().optional().describe('Email of the web form owner'),
+ createdDate: z.string().optional().describe('Date the web form was created'),
+ modifiedDate: z.string().optional().describe('Date the web form was last modified'),
+ participantSetInfo: z.any().optional().describe('Primary web form participant set'),
+ additionalParticipantSetsInfo: z
+ .array(z.any())
+ .optional()
+ .describe('Additional participant sets on the web form'),
+ raw: z.any().describe('Raw web form detail returned by Adobe Acrobat Sign')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ let webForm = await client.getWebForm(ctx.input.webFormId);
+
+ return {
+ output: {
+ webFormId: webForm.id || ctx.input.webFormId,
+ name: webForm.name,
+ status: webForm.status,
+ url: webForm.url,
+ javascript: webForm.javascript,
+ ownerEmail: webForm.ownerEmail,
+ createdDate: webForm.createdDate,
+ modifiedDate: webForm.modifiedDate,
+ participantSetInfo: webForm.widgetParticipantSetInfo,
+ additionalParticipantSetsInfo: webForm.additionalParticipantSetsInfo,
+ raw: webForm
+ },
+ message: `Retrieved web form \`${webForm.id || ctx.input.webFormId}\`${webForm.status ? ` in status **${webForm.status}**` : ''}.`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/index.ts b/integrations/adobe-sign/src/tools/index.ts
index 7930316208..d50db6523c 100644
--- a/integrations/adobe-sign/src/tools/index.ts
+++ b/integrations/adobe-sign/src/tools/index.ts
@@ -1,15 +1,25 @@
export * from './create-agreement';
export * from './create-library-template';
export * from './create-web-form';
+export * from './download-agreement-document';
export * from './download-audit-trail';
export * from './get-agreement';
+export * from './get-agreement-members';
+export * from './get-bulk-send';
export * from './get-form-data';
+export * from './get-library-template';
export * from './get-signing-urls';
+export * from './get-user';
+export * from './get-web-form';
export * from './list-agreements';
+export * from './list-bulk-sends';
export * from './list-library-templates';
export * from './list-users';
export * from './list-web-forms';
export * from './send-in-bulk';
export * from './send-reminder';
export * from './update-agreement-state';
+export * from './update-bulk-send-state';
+export * from './update-library-template-state';
+export * from './update-web-form-state';
export * from './upload-document';
diff --git a/integrations/adobe-sign/src/tools/list-bulk-sends.ts b/integrations/adobe-sign/src/tools/list-bulk-sends.ts
new file mode 100644
index 0000000000..5937f80d11
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/list-bulk-sends.ts
@@ -0,0 +1,64 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let listBulkSends = SlateTool.create(spec, {
+ name: 'List Bulk Sends',
+ key: 'list_bulk_sends',
+ description: `List Send in Bulk (MegaSign) parent agreements in the Adobe Acrobat Sign account with pagination.`,
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ cursor: z.string().optional().describe('Pagination cursor from a previous response'),
+ pageSize: z.number().optional().describe('Number of bulk sends per page')
+ })
+ )
+ .output(
+ z.object({
+ bulkSends: z
+ .array(
+ z.object({
+ bulkSendId: z.string().describe('ID of the Send in Bulk parent agreement'),
+ name: z.string().optional().describe('Name of the Send in Bulk operation'),
+ status: z.string().optional().describe('Current status'),
+ displayDate: z.string().optional().describe('Display date')
+ })
+ )
+ .describe('List of Send in Bulk parent agreements'),
+ cursor: z.string().optional().describe('Cursor for next page, if more results exist'),
+ totalHits: z.number().optional().describe('Total number of matching results')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ let result = await client.listMegaSigns({
+ cursor: ctx.input.cursor,
+ pageSize: ctx.input.pageSize
+ });
+
+ let bulkSends = (result.megaSignList || []).map((bulkSend: any) => ({
+ bulkSendId: bulkSend.id,
+ name: bulkSend.name,
+ status: bulkSend.status,
+ displayDate: bulkSend.displayDate
+ }));
+
+ return {
+ output: {
+ bulkSends,
+ cursor: result.page?.nextCursor,
+ totalHits: result.page?.totalHits
+ },
+ message: `Found **${bulkSends.length}** Send in Bulk item(s).`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/send-in-bulk.ts b/integrations/adobe-sign/src/tools/send-in-bulk.ts
index 30bcf175a7..6f825987c2 100644
--- a/integrations/adobe-sign/src/tools/send-in-bulk.ts
+++ b/integrations/adobe-sign/src/tools/send-in-bulk.ts
@@ -6,10 +6,11 @@ import { spec } from '../spec';
export let sendInBulk = SlateTool.create(spec, {
name: 'Send in Bulk',
key: 'send_in_bulk',
- description: `Send the same agreement to a large number of recipients simultaneously (MegaSign). Each recipient receives a personalized signing experience. Useful for mass onboarding, policy acknowledgments, or form collection.`,
+ description: `Send the same agreement to many recipients using Adobe Acrobat Sign Send in Bulk (MegaSign). Current v6 bulk sends require a CSV transient document that contains the child agreement recipient information.`,
instructions: [
- 'Upload the document first using the Upload Document tool, or use a library template ID.',
- 'Each recipient set gets their own copy of the agreement.'
+ 'Upload the agreement document first using Upload Document, or use a library template ID.',
+ 'Upload the Adobe Acrobat Sign Send in Bulk recipient CSV using Upload Document with mimeType "text/csv", then pass its transientDocumentId as childAgreementsTransientDocumentId.',
+ 'Each CSV row creates a child agreement for the corresponding recipient data.'
],
tags: {
destructive: false,
@@ -33,7 +34,11 @@ export let sendInBulk = SlateTool.create(spec, {
})
)
.describe('Documents to include'),
- recipientEmails: z.array(z.string()).describe('List of recipient email addresses'),
+ childAgreementsTransientDocumentId: z
+ .string()
+ .describe(
+ 'Transient document ID of the Send in Bulk CSV containing child agreement recipient information'
+ ),
signatureType: z
.enum(['ESIGN', 'WRITTEN'])
.optional()
@@ -51,8 +56,7 @@ export let sendInBulk = SlateTool.create(spec, {
)
.output(
z.object({
- megaSignId: z.string().describe('ID of the bulk send operation'),
- totalRecipients: z.number().describe('Number of recipients')
+ bulkSendId: z.string().describe('ID of the Send in Bulk operation')
})
)
.handleInvocation(async ctx => {
@@ -62,14 +66,10 @@ export let sendInBulk = SlateTool.create(spec, {
shard: ctx.auth.shard
});
- let recipientSetInfos = ctx.input.recipientEmails.map(email => ({
- recipientSetMemberInfos: [{ email }]
- }));
-
let result = await client.createMegaSign({
name: ctx.input.name,
fileInfos: ctx.input.fileInfos,
- recipientSetInfos,
+ childAgreementsTransientDocumentId: ctx.input.childAgreementsTransientDocumentId,
signatureType: ctx.input.signatureType,
message: ctx.input.message,
ccs: ctx.input.ccs
@@ -77,9 +77,8 @@ export let sendInBulk = SlateTool.create(spec, {
return {
output: {
- megaSignId: result.id,
- totalRecipients: ctx.input.recipientEmails.length
+ bulkSendId: result.id
},
- message: `Sent **${ctx.input.name}** in bulk to **${ctx.input.recipientEmails.length}** recipients. MegaSign ID: \`${result.id}\`.`
+ message: `Created Send in Bulk **${ctx.input.name}** with ID \`${result.id}\`.`
};
});
diff --git a/integrations/adobe-sign/src/tools/send-reminder.ts b/integrations/adobe-sign/src/tools/send-reminder.ts
index f1ce340661..b878fea76d 100644
--- a/integrations/adobe-sign/src/tools/send-reminder.ts
+++ b/integrations/adobe-sign/src/tools/send-reminder.ts
@@ -1,8 +1,24 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { adobeSignServiceError } from '../lib/errors';
import { spec } from '../spec';
+let collectParticipantIds = (members: any) => {
+ let sets = [...(members.nextParticipantSets || []), ...(members.participantSets || [])];
+ let ids: string[] = [];
+
+ for (let set of sets) {
+ for (let member of set.memberInfos || []) {
+ if (typeof member.id === 'string' && !ids.includes(member.id)) {
+ ids.push(member.id);
+ }
+ }
+ }
+
+ return ids;
+};
+
export let sendReminder = SlateTool.create(spec, {
name: 'Send Reminder',
key: 'send_reminder',
@@ -32,7 +48,7 @@ export let sendReminder = SlateTool.create(spec, {
.array(z.string())
.optional()
.describe(
- 'Specific participant IDs to send reminders to. If omitted, sends to all pending participants.'
+ 'Specific participant IDs to send reminders to. If omitted, the tool uses the agreement member list to target pending participants.'
),
firstReminderDelay: z
.number()
@@ -42,7 +58,12 @@ export let sendReminder = SlateTool.create(spec, {
)
.output(
z.object({
- reminderId: z.string().describe('ID of the created reminder')
+ agreementId: z.string().describe('ID of the agreement'),
+ reminderId: z.string().optional().describe('ID of the created reminder, if returned'),
+ recipientParticipantIds: z
+ .array(z.string())
+ .describe('Participant IDs targeted by the reminder'),
+ status: z.string().describe('Requested reminder status')
})
)
.handleInvocation(async ctx => {
@@ -52,16 +73,33 @@ export let sendReminder = SlateTool.create(spec, {
shard: ctx.auth.shard
});
+ let recipientParticipantIds = ctx.input.recipientParticipantIds;
+ if (!recipientParticipantIds || recipientParticipantIds.length === 0) {
+ let members = await client.getAgreementMembers(ctx.input.agreementId);
+ recipientParticipantIds = collectParticipantIds(members);
+ }
+
+ if (recipientParticipantIds.length === 0) {
+ throw adobeSignServiceError(
+ 'No participant IDs were available for this reminder. Provide recipientParticipantIds explicitly.'
+ );
+ }
+
let result = await client.createReminder({
agreementId: ctx.input.agreementId,
comment: ctx.input.comment,
frequency: ctx.input.frequency,
- recipientParticipantIds: ctx.input.recipientParticipantIds,
+ recipientParticipantIds,
firstReminderDelay: ctx.input.firstReminderDelay
});
return {
- output: { reminderId: result.id },
+ output: {
+ agreementId: ctx.input.agreementId,
+ reminderId: result?.reminderId || result?.id,
+ recipientParticipantIds,
+ status: result?.status || 'ACTIVE'
+ },
message: `Reminder sent for agreement \`${ctx.input.agreementId}\` with frequency **${ctx.input.frequency || 'ONCE'}**.`
};
});
diff --git a/integrations/adobe-sign/src/tools/update-bulk-send-state.ts b/integrations/adobe-sign/src/tools/update-bulk-send-state.ts
new file mode 100644
index 0000000000..004d46914b
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/update-bulk-send-state.ts
@@ -0,0 +1,60 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let updateBulkSendState = SlateTool.create(spec, {
+ name: 'Update Bulk Send State',
+ key: 'update_bulk_send_state',
+ description: `Update a Send in Bulk (MegaSign) parent agreement state, primarily to cancel an in-progress bulk send.`,
+ instructions: ['Use CANCELLED to recall an in-progress Send in Bulk operation.'],
+ tags: {
+ destructive: true,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ bulkSendId: z.string().describe('ID of the Send in Bulk parent agreement'),
+ state: z.enum(['IN_PROCESS', 'CANCELLED']).describe('Target state'),
+ cancellationComment: z
+ .string()
+ .optional()
+ .describe('Comment explaining why the bulk send is being cancelled'),
+ notifyOthers: z
+ .boolean()
+ .optional()
+ .describe('Whether to notify participants about the cancellation. Defaults to true.')
+ })
+ )
+ .output(
+ z.object({
+ bulkSendId: z.string().describe('ID of the updated Send in Bulk operation'),
+ state: z.string().describe('Requested new state')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ await client.updateMegaSignState(ctx.input.bulkSendId, ctx.input.state, {
+ cancellationInfo:
+ ctx.input.cancellationComment || ctx.input.notifyOthers !== undefined
+ ? {
+ comment: ctx.input.cancellationComment,
+ notifyOthers: ctx.input.notifyOthers ?? true
+ }
+ : undefined
+ });
+
+ return {
+ output: {
+ bulkSendId: ctx.input.bulkSendId,
+ state: ctx.input.state
+ },
+ message: `Send in Bulk \`${ctx.input.bulkSendId}\` state update requested: **${ctx.input.state}**.`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/update-library-template-state.ts b/integrations/adobe-sign/src/tools/update-library-template-state.ts
new file mode 100644
index 0000000000..bb4b08da7b
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/update-library-template-state.ts
@@ -0,0 +1,46 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let updateLibraryTemplateState = SlateTool.create(spec, {
+ name: 'Update Library Template State',
+ key: 'update_library_template_state',
+ description: `Update the state of an Adobe Acrobat Sign library template, including activating, returning to authoring, or removing a template.`,
+ instructions: ['Use REMOVED to retire a suite-owned or obsolete template.'],
+ tags: {
+ destructive: true,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ libraryDocumentId: z.string().describe('ID of the library template to update'),
+ state: z
+ .enum(['AUTHORING', 'ACTIVE', 'REMOVED'])
+ .describe('Target state for the library template')
+ })
+ )
+ .output(
+ z.object({
+ libraryDocumentId: z.string().describe('ID of the updated library template'),
+ state: z.string().describe('Requested new state')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ await client.updateLibraryDocumentState(ctx.input.libraryDocumentId, ctx.input.state);
+
+ return {
+ output: {
+ libraryDocumentId: ctx.input.libraryDocumentId,
+ state: ctx.input.state
+ },
+ message: `Library template \`${ctx.input.libraryDocumentId}\` state update requested: **${ctx.input.state}**.`
+ };
+ });
diff --git a/integrations/adobe-sign/src/tools/update-web-form-state.ts b/integrations/adobe-sign/src/tools/update-web-form-state.ts
new file mode 100644
index 0000000000..92cdc0122c
--- /dev/null
+++ b/integrations/adobe-sign/src/tools/update-web-form-state.ts
@@ -0,0 +1,53 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let updateWebFormState = SlateTool.create(spec, {
+ name: 'Update Web Form State',
+ key: 'update_web_form_state',
+ description: `Update an Adobe Acrobat Sign web form state, such as activating, deactivating, moving to authoring, or cancelling a web form.`,
+ instructions: [
+ 'Use INACTIVE to disable an active web form without deleting historical agreements.',
+ 'Use CANCELLED only for web forms that should no longer be used.'
+ ],
+ tags: {
+ destructive: true,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ webFormId: z.string().describe('ID of the web form to update'),
+ state: z
+ .enum(['ACTIVE', 'INACTIVE', 'AUTHORING', 'CANCELLED'])
+ .describe('Target state for the web form'),
+ message: z
+ .string()
+ .optional()
+ .describe('Optional inactive-state message shown to visitors')
+ })
+ )
+ .output(
+ z.object({
+ webFormId: z.string().describe('ID of the updated web form'),
+ state: z.string().describe('Requested new state')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ apiBaseUrl: ctx.auth.apiBaseUrl,
+ shard: ctx.auth.shard
+ });
+
+ await client.updateWebFormState(ctx.input.webFormId, ctx.input.state, ctx.input.message);
+
+ return {
+ output: {
+ webFormId: ctx.input.webFormId,
+ state: ctx.input.state
+ },
+ message: `Web form \`${ctx.input.webFormId}\` state update requested: **${ctx.input.state}**.`
+ };
+ });
diff --git a/integrations/affinda/package.json b/integrations/affinda/package.json
index 96f4650d73..c72e2779fb 100644
--- a/integrations/affinda/package.json
+++ b/integrations/affinda/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
- "typescript": "^5"
+ "@slates/test": "1.0.0-rc.9",
+ "typescript": "^5",
+ "vitest": "^3.1.2"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.6"
}
diff --git a/integrations/affinda/src/auth.ts b/integrations/affinda/src/auth.ts
index c903407708..41a52a232a 100644
--- a/integrations/affinda/src/auth.ts
+++ b/integrations/affinda/src/auth.ts
@@ -1,5 +1,6 @@
import { createAxios, SlateAuth } from 'slates';
import { z } from 'zod';
+import { affindaApiError } from './lib/errors';
export let auth = SlateAuth.create()
.output(
@@ -33,15 +34,19 @@ export let auth = SlateAuth.create()
}
});
- let response = await httpClient.get('/organizations');
- let orgs = response.data as Array<{ identifier: string; name: string }>;
- let firstOrg = orgs[0];
+ try {
+ let response = await httpClient.get('/organizations');
+ let orgs = response.data as Array<{ identifier: string; name: string }>;
+ let firstOrg = orgs[0];
- return {
- profile: {
- id: firstOrg?.identifier,
- name: firstOrg?.name
- }
- };
+ return {
+ profile: {
+ id: firstOrg?.identifier,
+ name: firstOrg?.name
+ }
+ };
+ } catch (error) {
+ throw affindaApiError(error, 'load auth profile');
+ }
}
});
diff --git a/integrations/affinda/src/index.ts b/integrations/affinda/src/index.ts
index c5d53d45ca..9c9ab4ef77 100644
--- a/integrations/affinda/src/index.ts
+++ b/integrations/affinda/src/index.ts
@@ -10,10 +10,14 @@ import {
listDocuments,
listDocumentTypes,
listOrganizations,
+ listValidationResults,
listWorkspaces,
+ manageSearchIndexes,
+ manageTags,
matchResumeToJob,
redactResume,
searchAndMatch,
+ updateDocument,
uploadDocument
} from './tools';
import { documentEvents } from './triggers';
@@ -33,6 +37,10 @@ export let provider = Slate.create({
deleteWorkspace,
listAnnotations,
batchUpdateAnnotations,
+ updateDocument,
+ manageTags,
+ manageSearchIndexes,
+ listValidationResults,
listDocumentTypes,
listOrganizations
],
diff --git a/integrations/affinda/src/lib/client.ts b/integrations/affinda/src/lib/client.ts
index 84d510c24b..24ae19cd33 100644
--- a/integrations/affinda/src/lib/client.ts
+++ b/integrations/affinda/src/lib/client.ts
@@ -1,5 +1,6 @@
import { Buffer } from 'buffer';
import { createAxios } from 'slates';
+import { affindaApiError } from './errors';
let BASE_URLS: Record = {
global: 'https://api.affinda.com/v3',
@@ -25,10 +26,19 @@ export class Client {
});
}
+ private async request(operation: string, run: () => Promise<{ data: T }>): Promise {
+ try {
+ let response = await run();
+ return response.data;
+ } catch (error) {
+ throw affindaApiError(error, operation);
+ }
+ }
+
// ---- Documents ----
async uploadDocument(params: {
- file?: { name: string; data: string };
+ file?: { name: string; data: string; mimeType?: string };
url?: string;
workspace?: string;
collection?: string;
@@ -43,6 +53,10 @@ export class Client {
compact?: boolean;
deleteAfterParse?: boolean;
enableValidationTool?: boolean;
+ expiryTime?: string;
+ useOcr?: boolean;
+ llmHint?: string;
+ limitToExamples?: string[];
}): Promise {
let data: Record = {};
@@ -51,35 +65,37 @@ export class Client {
}
if (params.workspace) data.workspace = params.workspace;
if (params.collection) data.collection = params.collection;
- if (params.documentType) data.document_type = params.documentType;
+ if (params.documentType) data.documentType = params.documentType;
if (params.wait !== undefined) data.wait = params.wait;
if (params.identifier) data.identifier = params.identifier;
- if (params.customIdentifier) data.custom_identifier = params.customIdentifier;
- if (params.fileName) data.file_name = params.fileName;
+ if (params.customIdentifier) data.customIdentifier = params.customIdentifier;
+ if (params.fileName) data.fileName = params.fileName;
if (params.language) data.language = params.language;
- if (params.rejectDuplicates !== undefined)
- data.reject_duplicates = params.rejectDuplicates;
- if (params.lowPriority !== undefined) data.low_priority = params.lowPriority;
+ if (params.rejectDuplicates !== undefined) data.rejectDuplicates = params.rejectDuplicates;
+ if (params.lowPriority !== undefined) data.lowPriority = params.lowPriority;
if (params.compact !== undefined) data.compact = params.compact;
- if (params.deleteAfterParse !== undefined)
- data.delete_after_parse = params.deleteAfterParse;
+ if (params.deleteAfterParse !== undefined) data.deleteAfterParse = params.deleteAfterParse;
if (params.enableValidationTool !== undefined)
- data.enable_validation_tool = params.enableValidationTool;
+ data.enableValidationTool = params.enableValidationTool;
+ if (params.expiryTime) data.expiryTime = params.expiryTime;
+ if (params.useOcr !== undefined) data.useOcr = params.useOcr;
+ if (params.llmHint) data.llmHint = params.llmHint;
+ if (params.limitToExamples) data.limitToExamples = JSON.stringify(params.limitToExamples);
+ let formData = new FormData();
if (params.file) {
let buffer = Buffer.from(params.file.data, 'base64');
- let blob = new Blob([buffer]);
- let formData = new FormData();
+ let blob = new Blob([buffer], {
+ type: params.file.mimeType ?? 'application/octet-stream'
+ });
formData.append('file', blob, params.file.name);
- for (let [key, value] of Object.entries(data)) {
- formData.append(key, String(value));
- }
- let response = await this.axios.post('/documents', formData);
- return response.data;
}
- let response = await this.axios.post('/documents', data);
- return response.data;
+ for (let [key, value] of Object.entries(data)) {
+ formData.append(key, String(value));
+ }
+
+ return this.request('upload document', () => this.axios.post('/documents', formData));
}
async getDocument(
@@ -89,20 +105,23 @@ export class Client {
let queryParams: Record = {};
if (params?.format) queryParams.format = params.format;
if (params?.compact !== undefined) queryParams.compact = params.compact;
- let response = await this.axios.get(`/documents/${identifier}`, { params: queryParams });
- return response.data;
+ return this.request('get document', () =>
+ this.axios.get(`/documents/${identifier}`, { params: queryParams })
+ );
}
async listDocuments(params?: {
workspace?: string;
collection?: string;
state?: string;
- tags?: string[];
+ tags?: number[];
search?: string;
+ createdDt?: string;
offset?: number;
limit?: number;
- ordering?: string;
+ ordering?: string[];
includeData?: boolean;
+ exclude?: string[];
inReview?: boolean;
failed?: boolean;
ready?: boolean;
@@ -110,6 +129,7 @@ export class Client {
hasChallenges?: boolean;
customIdentifier?: string;
compact?: boolean;
+ count?: boolean;
}): Promise {
let queryParams: Record = {};
if (params?.workspace) queryParams.workspace = params.workspace;
@@ -117,10 +137,12 @@ export class Client {
if (params?.state) queryParams.state = params.state;
if (params?.tags) queryParams.tags = params.tags;
if (params?.search) queryParams.search = params.search;
+ if (params?.createdDt) queryParams.created_dt = params.createdDt;
if (params?.offset !== undefined) queryParams.offset = params.offset;
if (params?.limit !== undefined) queryParams.limit = params.limit;
if (params?.ordering) queryParams.ordering = params.ordering;
if (params?.includeData !== undefined) queryParams.include_data = params.includeData;
+ if (params?.exclude) queryParams.exclude = params.exclude;
if (params?.inReview !== undefined) queryParams.in_review = params.inReview;
if (params?.failed !== undefined) queryParams.failed = params.failed;
if (params?.ready !== undefined) queryParams.ready = params.ready;
@@ -128,58 +150,46 @@ export class Client {
if (params?.hasChallenges !== undefined) queryParams.has_challenges = params.hasChallenges;
if (params?.customIdentifier) queryParams.custom_identifier = params.customIdentifier;
if (params?.compact !== undefined) queryParams.compact = params.compact;
+ if (params?.count !== undefined) queryParams.count = params.count;
- let response = await this.axios.get('/documents', { params: queryParams });
- return response.data;
+ return this.request('list documents', () =>
+ this.axios.get('/documents', { params: queryParams })
+ );
}
- async updateDocument(identifier: string, data: Record): Promise {
- let response = await this.axios.patch(`/documents/${identifier}`, data);
- return response.data;
- }
+ async updateDocument(
+ identifier: string,
+ data: Record,
+ params?: { compact?: boolean }
+ ): Promise {
+ let queryParams: Record = {};
+ if (params?.compact !== undefined) queryParams.compact = params.compact;
- async deleteDocument(identifier: string): Promise {
- await this.axios.delete(`/documents/${identifier}`);
+ return this.request('update document', () =>
+ this.axios.patch(`/documents/${identifier}`, data, { params: queryParams })
+ );
}
- async getRedactedDocument(
- identifier: string,
- params?: {
- redactHeadshot?: boolean;
- redactPersonalDetails?: boolean;
- redactWorkDetails?: boolean;
- redactEducationDetails?: boolean;
- redactReferees?: boolean;
- redactLocations?: boolean;
- redactDates?: boolean;
- redactGender?: boolean;
- redactPdfMetadata?: boolean;
- }
- ): Promise {
- let queryParams: Record = {};
- if (params?.redactHeadshot !== undefined)
- queryParams.redact_headshot = params.redactHeadshot;
- if (params?.redactPersonalDetails !== undefined)
- queryParams.redact_personal_details = params.redactPersonalDetails;
- if (params?.redactWorkDetails !== undefined)
- queryParams.redact_work_details = params.redactWorkDetails;
- if (params?.redactEducationDetails !== undefined)
- queryParams.redact_education_details = params.redactEducationDetails;
- if (params?.redactReferees !== undefined)
- queryParams.redact_referees = params.redactReferees;
- if (params?.redactLocations !== undefined)
- queryParams.redact_locations = params.redactLocations;
- if (params?.redactDates !== undefined) queryParams.redact_dates = params.redactDates;
- if (params?.redactGender !== undefined) queryParams.redact_gender = params.redactGender;
- if (params?.redactPdfMetadata !== undefined)
- queryParams.redact_pdf_metadata = params.redactPdfMetadata;
-
- let response = await this.axios.get(`/documents/${identifier}/redacted`, {
- params: queryParams,
- responseType: 'arraybuffer'
- });
- let buffer = Buffer.from(response.data as ArrayBuffer);
- return buffer.toString('base64');
+ async deleteDocument(identifier: string): Promise {
+ await this.request('delete document', () => this.axios.delete(`/documents/${identifier}`));
+ }
+
+ async getRedactedDocument(identifier: string): Promise<{
+ contentBase64: string;
+ mimeType: string;
+ byteLength: number;
+ }> {
+ let data = await this.request('get redacted document', () =>
+ this.axios.get(`/documents/${identifier}/redacted`, {
+ responseType: 'arraybuffer'
+ })
+ );
+ let buffer = Buffer.from(data);
+ return {
+ contentBase64: buffer.toString('base64'),
+ mimeType: 'application/pdf',
+ byteLength: buffer.byteLength
+ };
}
// ---- Workspaces ----
@@ -187,39 +197,39 @@ export class Client {
async listWorkspaces(organization: string, name?: string): Promise {
let params: Record = { organization };
if (name) params.name = name;
- let response = await this.axios.get('/workspaces', { params });
- return response.data;
+ return this.request('list workspaces', () => this.axios.get('/workspaces', { params }));
}
async getWorkspace(identifier: string): Promise {
- let response = await this.axios.get(`/workspaces/${identifier}`);
- return response.data;
+ return this.request('get workspace', () => this.axios.get(`/workspaces/${identifier}`));
}
async createWorkspace(data: Record): Promise {
- let response = await this.axios.post('/workspaces', data);
- return response.data;
+ return this.request('create workspace', () => this.axios.post('/workspaces', data));
}
async updateWorkspace(identifier: string, data: Record): Promise {
- let response = await this.axios.patch(`/workspaces/${identifier}`, data);
- return response.data;
+ return this.request('update workspace', () =>
+ this.axios.patch(`/workspaces/${identifier}`, data)
+ );
}
async deleteWorkspace(identifier: string): Promise {
- await this.axios.delete(`/workspaces/${identifier}`);
+ await this.request('delete workspace', () =>
+ this.axios.delete(`/workspaces/${identifier}`)
+ );
}
// ---- Organizations ----
async listOrganizations(): Promise {
- let response = await this.axios.get('/organizations');
- return response.data;
+ return this.request('list organizations', () => this.axios.get('/organizations'));
}
async getOrganization(identifier: string): Promise {
- let response = await this.axios.get(`/organizations/${identifier}`);
- return response.data;
+ return this.request('get organization', () =>
+ this.axios.get(`/organizations/${identifier}`)
+ );
}
// ---- Document Types ----
@@ -228,96 +238,132 @@ export class Client {
organization?: string;
workspace?: string;
}): Promise {
- let response = await this.axios.get('/document_types', { params });
- return response.data;
+ return this.request('list document types', () =>
+ this.axios.get('/document_types', { params })
+ );
}
async getDocumentType(identifier: string): Promise {
- let response = await this.axios.get(`/document_types/${identifier}`);
- return response.data;
+ return this.request('get document type', () =>
+ this.axios.get(`/document_types/${identifier}`)
+ );
}
// ---- Annotations ----
async listAnnotations(documentIdentifier: string): Promise {
- let response = await this.axios.get('/annotations', {
- params: { document: documentIdentifier }
- });
- return response.data;
+ return this.request('list annotations', () =>
+ this.axios.get('/annotations', {
+ params: { document: documentIdentifier }
+ })
+ );
}
async updateAnnotation(annotationId: number, data: Record): Promise {
- let response = await this.axios.patch(`/annotations/${annotationId}`, data);
- return response.data;
+ return this.request('update annotation', () =>
+ this.axios.patch(`/annotations/${annotationId}`, data)
+ );
}
async batchUpdateAnnotations(data: Record[]): Promise {
- let response = await this.axios.post('/annotations/batch_update', data);
- return response.data;
+ return this.request('batch update annotations', () =>
+ this.axios.post('/annotations/batch_update', data)
+ );
}
async batchCreateAnnotations(data: Record[]): Promise {
- let response = await this.axios.post('/annotations/batch_create', data);
- return response.data;
+ return this.request('batch create annotations', () =>
+ this.axios.post('/annotations/batch_create', data)
+ );
}
async batchDeleteAnnotations(data: number[]): Promise {
- let response = await this.axios.post('/annotations/batch_delete', data);
- return response.data;
+ return this.request('batch delete annotations', () =>
+ this.axios.post('/annotations/batch_delete', data)
+ );
}
// ---- Validation Results ----
- async listValidationResults(documentIdentifier: string): Promise {
- let response = await this.axios.get('/validation_results', {
- params: { document: documentIdentifier }
- });
- return response.data;
+ async listValidationResults(params: {
+ documentIdentifier: string;
+ offset?: number;
+ limit?: number;
+ }): Promise {
+ let queryParams: Record = {
+ document: params.documentIdentifier
+ };
+ if (params.offset !== undefined) queryParams.offset = params.offset;
+ if (params.limit !== undefined) queryParams.limit = params.limit;
+
+ return this.request('list validation results', () =>
+ this.axios.get('/validation_results', {
+ params: queryParams
+ })
+ );
}
async createValidationResult(data: Record): Promise {
- let response = await this.axios.post('/validation_results', data);
- return response.data;
+ return this.request('create validation result', () =>
+ this.axios.post('/validation_results', data)
+ );
}
// ---- Tags ----
- async listTags(workspace: string): Promise {
- let response = await this.axios.get('/tags', { params: { workspace } });
- return response.data;
+ async listTags(params?: {
+ workspace?: string;
+ name?: string;
+ limit?: number;
+ offset?: number;
+ }): Promise {
+ return this.request('list tags', () => this.axios.get('/tags', { params }));
+ }
+
+ async getTag(tagId: number): Promise {
+ return this.request('get tag', () => this.axios.get(`/tags/${tagId}`));
}
async createTag(data: { name: string; workspace: string }): Promise {
- let response = await this.axios.post('/tags', data);
- return response.data;
+ return this.request('create tag', () => this.axios.post('/tags', data));
+ }
+
+ async updateTag(tagId: number, data: { name?: string; workspace?: string }): Promise {
+ return this.request('update tag', () => this.axios.patch(`/tags/${tagId}`, data));
+ }
+
+ async deleteTag(tagId: number): Promise {
+ await this.request('delete tag', () => this.axios.delete(`/tags/${tagId}`));
}
async batchAddTag(tagId: number, documentIdentifiers: string[]): Promise {
- let response = await this.axios.post('/documents/batch_add_tag', {
- tag: tagId,
- documents: documentIdentifiers
- });
- return response.data;
+ return this.request('add tag to documents', () =>
+ this.axios.post('/documents/batch_add_tag', {
+ tag: tagId,
+ identifiers: documentIdentifiers
+ })
+ );
}
async batchRemoveTag(tagId: number, documentIdentifiers: string[]): Promise {
- let response = await this.axios.post('/documents/batch_remove_tag', {
- tag: tagId,
- documents: documentIdentifiers
- });
- return response.data;
+ return this.request('remove tag from documents', () =>
+ this.axios.post('/documents/batch_remove_tag', {
+ tag: tagId,
+ identifiers: documentIdentifiers
+ })
+ );
}
// ---- Search & Match ----
async searchResumes(params: Record): Promise {
- let response = await this.axios.post('/resume_search', params);
- return response.data;
+ return this.request('search resumes', () => this.axios.post('/resume_search', params));
}
async getResumeSearchDetails(identifier: string, params: Record): Promise {
- let response = await this.axios.post(`/resume_search/details/${identifier}`, params);
- return response.data;
+ return this.request('get resume search details', () =>
+ this.axios.post(`/resume_search/details/${identifier}`, params)
+ );
}
async matchResumeToJob(
@@ -330,13 +376,15 @@ export class Client {
job_description: jobDescriptionIdentifier,
...params
};
- let response = await this.axios.get('/resume_search/match', { params: queryParams });
- return response.data;
+ return this.request('match resume to job', () =>
+ this.axios.get('/resume_search/match', { params: queryParams })
+ );
}
async searchJobDescriptions(params: Record): Promise {
- let response = await this.axios.post('/job_description_search', params);
- return response.data;
+ return this.request('search job descriptions', () =>
+ this.axios.post('/job_description_search', params)
+ );
}
// ---- Resthook Subscriptions ----
@@ -348,33 +396,95 @@ export class Client {
workspace?: string;
version?: string;
}): Promise {
- let response = await this.axios.post('/resthook_subscriptions', data);
- return response.data;
+ return this.request('create resthook subscription', () =>
+ this.axios.post('/resthook_subscriptions', data)
+ );
}
async activateResthookSubscription(hookSecret: string): Promise {
- let response = await this.axios.post('/resthook_subscriptions/activate', null, {
- headers: { 'X-Hook-Secret': hookSecret }
- });
- return response.data;
+ return this.request('activate resthook subscription', () =>
+ this.axios.post('/resthook_subscriptions/activate', null, {
+ headers: { 'X-Hook-Secret': hookSecret }
+ })
+ );
}
async listResthookSubscriptions(params?: { offset?: number; limit?: number }): Promise {
- let response = await this.axios.get('/resthook_subscriptions', { params });
- return response.data;
+ return this.request('list resthook subscriptions', () =>
+ this.axios.get('/resthook_subscriptions', { params })
+ );
}
async deleteResthookSubscription(subscriptionId: number): Promise {
- await this.axios.delete(`/resthook_subscriptions/${subscriptionId}`);
+ await this.request('delete resthook subscription', () =>
+ this.axios.delete(`/resthook_subscriptions/${subscriptionId}`)
+ );
}
// ---- Indexes ----
- async listIndexes(params?: { documentType?: string; name?: string }): Promise {
+ async listIndexes(params?: {
+ documentType?: string;
+ name?: string;
+ offset?: number;
+ limit?: number;
+ }): Promise {
let queryParams: Record = {};
if (params?.documentType) queryParams.document_type = params.documentType;
if (params?.name) queryParams.name = params.name;
- let response = await this.axios.get('/index', { params: queryParams });
- return response.data;
+ if (params?.offset !== undefined) queryParams.offset = params.offset;
+ if (params?.limit !== undefined) queryParams.limit = params.limit;
+ return this.request('list search indexes', () =>
+ this.axios.get('/index', { params: queryParams })
+ );
+ }
+
+ async createIndex(data: { name: string; docType: string }): Promise {
+ return this.request('create search index', () => this.axios.post('/index', data));
+ }
+
+ async updateIndex(name: string, data: { name: string }): Promise {
+ return this.request('update search index', () =>
+ this.axios.patch(`/index/${encodeURIComponent(name)}`, data)
+ );
+ }
+
+ async deleteIndex(name: string): Promise {
+ await this.request('delete search index', () =>
+ this.axios.delete(`/index/${encodeURIComponent(name)}`)
+ );
+ }
+
+ async listIndexedDocuments(
+ name: string,
+ params?: { offset?: number; limit?: number }
+ ): Promise {
+ return this.request('list indexed documents', () =>
+ this.axios.get(`/index/${encodeURIComponent(name)}/documents`, { params })
+ );
+ }
+
+ async indexDocument(name: string, documentIdentifier: string): Promise {
+ return this.request('index document', () =>
+ this.axios.post(`/index/${encodeURIComponent(name)}/documents`, {
+ document: documentIdentifier
+ })
+ );
+ }
+
+ async deleteIndexedDocument(name: string, documentIdentifier: string): Promise {
+ await this.request('delete indexed document', () =>
+ this.axios.delete(
+ `/index/${encodeURIComponent(name)}/documents/${encodeURIComponent(documentIdentifier)}`
+ )
+ );
+ }
+
+ async reindexDocument(name: string, documentIdentifier: string): Promise {
+ await this.request('re-index document', () =>
+ this.axios.post(
+ `/index/${encodeURIComponent(name)}/documents/${encodeURIComponent(documentIdentifier)}/re_index`
+ )
+ );
}
}
diff --git a/integrations/affinda/src/lib/errors.ts b/integrations/affinda/src/lib/errors.ts
new file mode 100644
index 0000000000..49d1ebaf77
--- /dev/null
+++ b/integrations/affinda/src/lib/errors.ts
@@ -0,0 +1,100 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null;
+
+let addMessage = (messages: string[], value: unknown) => {
+ if (typeof value !== 'string') return;
+
+ let trimmed = value.trim();
+ if (trimmed && !messages.includes(trimmed)) {
+ messages.push(trimmed);
+ }
+};
+
+let collectAffindaMessages = (value: unknown, messages: string[]) => {
+ if (!isRecord(value)) {
+ addMessage(messages, value);
+ return;
+ }
+
+ for (let key of ['message', 'detail', 'error', 'type', 'code']) {
+ addMessage(messages, value[key]);
+ }
+
+ let nestedError = isRecord(value.error) ? value.error : undefined;
+ if (nestedError) {
+ for (let key of ['errorCode', 'errorDetail', 'message', 'detail']) {
+ addMessage(messages, nestedError[key]);
+ }
+ }
+
+ if (Array.isArray(value.errors)) {
+ for (let error of value.errors) {
+ collectAffindaMessages(error, messages);
+ }
+ } else if (isRecord(value.errors)) {
+ collectAffindaMessages(value.errors, messages);
+ }
+};
+
+let extractAffindaMessage = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let messages: string[] = [];
+
+ collectAffindaMessages(response?.data, messages);
+ if (isRecord(error)) {
+ collectAffindaMessages(error.data, messages);
+ }
+
+ if (messages.length > 0) {
+ return messages.join(' - ');
+ }
+
+ if (error instanceof Error && error.message) {
+ return error.message;
+ }
+
+ return 'Unknown error';
+};
+
+let getAffindaErrorStatus = (error: unknown) => {
+ if (!isRecord(error)) return undefined;
+
+ let response = error.response as ErrorResponse | undefined;
+ return (
+ response?.status ?? error.status ?? (isRecord(error.data) ? error.data.status : undefined)
+ );
+};
+
+export let affindaServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let affindaApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) return error;
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let status = getAffindaErrorStatus(error);
+ let statusLabel =
+ status !== undefined
+ ? `HTTP ${status}${response?.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+
+ let serviceError = affindaServiceError(
+ `Affinda API ${operation} failed: ${statusLabel}${extractAffindaMessage(error)}`
+ );
+ serviceError.data.reason = 'affinda_api_error';
+ serviceError.data.upstreamStatus = status;
+
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+
+ return serviceError;
+};
diff --git a/integrations/affinda/src/tools.schema.test.ts b/integrations/affinda/src/tools.schema.test.ts
new file mode 100644
index 0000000000..58d3ff59b4
--- /dev/null
+++ b/integrations/affinda/src/tools.schema.test.ts
@@ -0,0 +1,4 @@
+import { describeMcpCompatibleToolSchemas } from '@slates/test';
+import { provider } from './index';
+
+describeMcpCompatibleToolSchemas('Affinda tool input schemas', provider.actions);
diff --git a/integrations/affinda/src/tools/get-document.ts b/integrations/affinda/src/tools/get-document.ts
index 183191c618..3fe6fc9e0a 100644
--- a/integrations/affinda/src/tools/get-document.ts
+++ b/integrations/affinda/src/tools/get-document.ts
@@ -17,7 +17,7 @@ export let getDocument = SlateTool.create(spec, {
.string()
.describe('Unique identifier of the document to retrieve.'),
format: z
- .enum(['json', 'xml'])
+ .enum(['json', 'xml', 'hr-xml'])
.optional()
.describe('Response format for the extracted data.'),
compact: z
@@ -31,8 +31,14 @@ export let getDocument = SlateTool.create(spec, {
documentIdentifier: z.string().describe('Unique identifier of the document.'),
fileName: z.string().optional().describe('Name of the processed file.'),
state: z.string().optional().describe('Current processing state of the document.'),
+ customIdentifier: z.string().optional().describe('Custom document identifier.'),
ready: z.boolean().optional().describe('Whether the document has finished processing.'),
failed: z.boolean().optional().describe('Whether parsing has failed.'),
+ reviewUrl: z.string().optional().describe('Affinda validation/review URL.'),
+ pdfUrl: z
+ .string()
+ .optional()
+ .describe('Temporary URL for the source PDF, if available.'),
workspaceIdentifier: z
.string()
.optional()
@@ -41,6 +47,8 @@ export let getDocument = SlateTool.create(spec, {
.string()
.optional()
.describe('Collection the document belongs to.'),
+ documentTypeIdentifier: z.string().optional().describe('Document type identifier.'),
+ tags: z.array(z.any()).optional().describe('Tags attached to the document.'),
extractedData: z
.any()
.optional()
@@ -65,10 +73,15 @@ export let getDocument = SlateTool.create(spec, {
documentIdentifier: meta.identifier ?? ctx.input.documentIdentifier,
fileName: meta.fileName,
state: meta.state,
+ customIdentifier: meta.customIdentifier,
ready: meta.ready,
failed: meta.failed,
+ reviewUrl: meta.reviewUrl,
+ pdfUrl: meta.pdf,
workspaceIdentifier: meta.workspace?.identifier,
collectionIdentifier: meta.collection?.identifier,
+ documentTypeIdentifier: meta.documentType,
+ tags: meta.tags,
extractedData: result.data
},
message: `Retrieved document **${meta.fileName ?? ctx.input.documentIdentifier}** (state: ${meta.state ?? 'unknown'}).`
diff --git a/integrations/affinda/src/tools/index.ts b/integrations/affinda/src/tools/index.ts
index d5c9c8aced..3cfa3b2455 100644
--- a/integrations/affinda/src/tools/index.ts
+++ b/integrations/affinda/src/tools/index.ts
@@ -3,9 +3,13 @@ export * from './get-document';
export * from './list-document-types';
export * from './list-documents';
export * from './list-organizations';
+export * from './manage-search-indexes';
+export * from './manage-tags';
export * from './manage-workspace';
export * from './match-resume-to-job';
export * from './redact-resume';
export * from './search-and-match';
export * from './update-annotations';
+export * from './update-document';
export * from './upload-document';
+export * from './validation-results';
diff --git a/integrations/affinda/src/tools/list-documents.ts b/integrations/affinda/src/tools/list-documents.ts
index 0ff417f473..2774dbd1c8 100644
--- a/integrations/affinda/src/tools/list-documents.ts
+++ b/integrations/affinda/src/tools/list-documents.ts
@@ -21,12 +21,15 @@ export let listDocuments = SlateTool.create(spec, {
),
collectionIdentifier: z.string().optional().describe('Filter by collection identifier.'),
state: z
- .string()
+ .enum(['uploaded', 'review', 'validated', 'archived', 'rejected'])
.optional()
- .describe(
- 'Filter by document state (e.g., "uploaded", "parsed", "validated", "rejected").'
- ),
+ .describe('Filter by document state.'),
+ tagIds: z.array(z.number()).optional().describe('Filter by tag IDs.'),
search: z.string().optional().describe('Search by filename or tag name.'),
+ createdDate: z
+ .enum(['today', 'yesterday', 'week', 'month', 'year'])
+ .optional()
+ .describe('Filter by created date bucket.'),
inReview: z.boolean().optional().describe('Filter for documents currently in review.'),
failed: z.boolean().optional().describe('Filter for documents that failed parsing.'),
ready: z.boolean().optional().describe('Filter for documents that are ready.'),
@@ -34,17 +37,25 @@ export let listDocuments = SlateTool.create(spec, {
offset: z.number().optional().describe('Pagination offset (number of items to skip).'),
limit: z.number().optional().describe('Maximum number of documents to return.'),
ordering: z
- .string()
+ .array(z.string())
.optional()
- .describe('Sort field (e.g., "created_dt", "-created_dt", "file_name").'),
+ .describe('Sort fields, e.g. ["created_dt"] or ["-created_dt", "file_name"].'),
includeData: z
.boolean()
.optional()
.describe('If true, includes a summary of parsed data for each document.'),
+ excludeDocumentIdentifiers: z
+ .array(z.string())
+ .optional()
+ .describe('Document identifiers to exclude from the list response.'),
compact: z
.boolean()
.optional()
- .describe('If true, returns compact document representations.')
+ .describe('If true, returns compact document representations.'),
+ includeCount: z
+ .boolean()
+ .optional()
+ .describe('If false, skips computing the total count for large result sets.')
})
)
.output(
@@ -56,12 +67,16 @@ export let listDocuments = SlateTool.create(spec, {
documentIdentifier: z.string().describe('Unique identifier of the document.'),
fileName: z.string().optional().describe('Name of the file.'),
state: z.string().optional().describe('Current processing state.'),
+ customIdentifier: z.string().optional().describe('Custom document identifier.'),
ready: z
.boolean()
.optional()
.describe('Whether the document has finished processing.'),
failed: z.boolean().optional().describe('Whether parsing has failed.'),
createdAt: z.string().optional().describe('ISO 8601 creation timestamp.'),
+ workspaceIdentifier: z.string().optional().describe('Workspace identifier.'),
+ collectionIdentifier: z.string().optional().describe('Collection identifier.'),
+ tags: z.array(z.any()).optional().describe('Tags attached to the document.'),
extractedData: z
.any()
.optional()
@@ -83,7 +98,9 @@ export let listDocuments = SlateTool.create(spec, {
workspace,
collection: ctx.input.collectionIdentifier,
state: ctx.input.state,
+ tags: ctx.input.tagIds,
search: ctx.input.search,
+ createdDt: ctx.input.createdDate,
inReview: ctx.input.inReview,
failed: ctx.input.failed,
ready: ctx.input.ready,
@@ -92,7 +109,9 @@ export let listDocuments = SlateTool.create(spec, {
limit: ctx.input.limit,
ordering: ctx.input.ordering,
includeData: ctx.input.includeData,
- compact: ctx.input.compact
+ exclude: ctx.input.excludeDocumentIdentifiers,
+ compact: ctx.input.compact,
+ count: ctx.input.includeCount
});
let results = result.results ?? result;
@@ -102,9 +121,13 @@ export let listDocuments = SlateTool.create(spec, {
documentIdentifier: meta.identifier ?? '',
fileName: meta.fileName,
state: meta.state,
+ customIdentifier: meta.customIdentifier,
ready: meta.ready,
failed: meta.failed,
createdAt: meta.createdDt,
+ workspaceIdentifier: meta.workspace?.identifier,
+ collectionIdentifier: meta.collection?.identifier,
+ tags: meta.tags,
extractedData: doc.data
};
});
diff --git a/integrations/affinda/src/tools/manage-search-indexes.ts b/integrations/affinda/src/tools/manage-search-indexes.ts
new file mode 100644
index 0000000000..e93729eaf7
--- /dev/null
+++ b/integrations/affinda/src/tools/manage-search-indexes.ts
@@ -0,0 +1,241 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { affindaServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let documentTypeSchema = z.enum(['resumes', 'job_descriptions']);
+
+let searchIndexSchema = z.object({
+ name: z.string().describe('Search index name.'),
+ documentType: documentTypeSchema.optional().describe('Indexed document type.'),
+ user: z.any().optional().describe('Affinda user metadata returned for the index.')
+});
+
+let indexedDocumentSchema = z.object({
+ documentIdentifier: z.string().describe('Indexed Affinda document identifier.')
+});
+
+let mapIndex = (index: any) => ({
+ name: index.name,
+ documentType: index.docType,
+ user: index.user
+});
+
+let mapIndexedDocument = (document: any) => ({
+ documentIdentifier: document.document ?? document.identifier ?? document
+});
+
+let requireIndexName = (indexName: string | undefined, action: string) => {
+ if (!indexName) {
+ throw affindaServiceError(`indexName is required for "${action}".`);
+ }
+
+ return indexName;
+};
+
+let requireDocumentIdentifier = (documentIdentifier: string | undefined, action: string) => {
+ if (!documentIdentifier) {
+ throw affindaServiceError(`documentIdentifier is required for "${action}".`);
+ }
+
+ return documentIdentifier;
+};
+
+export let manageSearchIndexes = SlateTool.create(spec, {
+ name: 'Manage Search Indexes',
+ key: 'manage_search_indexes',
+ description: `List and manage Affinda Search & Match indexes and indexed documents. Use indexes to make parsed resumes or job descriptions searchable before calling Search & Match tools.`,
+ instructions: [
+ 'For "list", optional filters are documentType, indexName, offset, and limit.',
+ 'For "create", provide indexName and documentType.',
+ 'For "update", provide indexName and newIndexName.',
+ 'For "delete" and "list_documents", provide indexName.',
+ 'For "add_document", "delete_document", or "reindex_document", provide indexName and documentIdentifier.'
+ ],
+ tags: {
+ destructive: true
+ }
+})
+ .input(
+ z.object({
+ action: z
+ .enum([
+ 'list',
+ 'create',
+ 'update',
+ 'delete',
+ 'list_documents',
+ 'add_document',
+ 'delete_document',
+ 'reindex_document'
+ ])
+ .describe('Search index operation to perform.'),
+ indexName: z
+ .string()
+ .optional()
+ .describe('Index name. Required for every action except list.'),
+ newIndexName: z.string().optional().describe('New index name for update.'),
+ documentType: documentTypeSchema
+ .optional()
+ .describe('Index document type for create or list filtering.'),
+ documentIdentifier: z
+ .string()
+ .optional()
+ .describe('Document identifier for add/delete/reindex document actions.'),
+ offset: z.number().optional().describe('Pagination offset for list actions.'),
+ limit: z.number().optional().describe('Maximum number of results to return.')
+ })
+ )
+ .output(
+ z.object({
+ action: z.string().describe('Operation that was performed.'),
+ index: searchIndexSchema.optional().describe('Index returned by create/update.'),
+ indexes: z.array(searchIndexSchema).optional().describe('Indexes returned by list.'),
+ documents: z
+ .array(indexedDocumentSchema)
+ .optional()
+ .describe('Documents returned by list_documents.'),
+ count: z.number().optional().describe('Number of returned items.'),
+ documentIdentifier: z.string().optional().describe('Indexed document identifier.'),
+ deleted: z.boolean().optional().describe('Whether an item was deleted.'),
+ reindexed: z.boolean().optional().describe('Whether a document was re-indexed.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ if (ctx.input.action === 'list') {
+ let result = await client.listIndexes({
+ documentType: ctx.input.documentType,
+ name: ctx.input.indexName,
+ offset: ctx.input.offset,
+ limit: ctx.input.limit
+ });
+ let indexes = (Array.isArray(result) ? result : (result.results ?? [])).map(mapIndex);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ indexes,
+ count: result.count ?? indexes.length
+ },
+ message: `Found **${result.count ?? indexes.length}** search index(es).`
+ };
+ }
+
+ if (ctx.input.action === 'create') {
+ if (!ctx.input.documentType) {
+ throw affindaServiceError('documentType is required for "create".');
+ }
+
+ let result = await client.createIndex({
+ name: requireIndexName(ctx.input.indexName, ctx.input.action),
+ docType: ctx.input.documentType
+ });
+
+ return {
+ output: {
+ action: ctx.input.action,
+ index: mapIndex(result)
+ },
+ message: `Created search index **${result.name}**.`
+ };
+ }
+
+ if (ctx.input.action === 'update') {
+ let indexName = requireIndexName(ctx.input.indexName, ctx.input.action);
+ if (!ctx.input.newIndexName) {
+ throw affindaServiceError('newIndexName is required for "update".');
+ }
+
+ let result = await client.updateIndex(indexName, { name: ctx.input.newIndexName });
+
+ return {
+ output: {
+ action: ctx.input.action,
+ index: mapIndex(result)
+ },
+ message: `Updated search index **${indexName}**.`
+ };
+ }
+
+ if (ctx.input.action === 'delete') {
+ let indexName = requireIndexName(ctx.input.indexName, ctx.input.action);
+ await client.deleteIndex(indexName);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ deleted: true
+ },
+ message: `Deleted search index **${indexName}**.`
+ };
+ }
+
+ if (ctx.input.action === 'list_documents') {
+ let indexName = requireIndexName(ctx.input.indexName, ctx.input.action);
+ let result = await client.listIndexedDocuments(indexName, {
+ offset: ctx.input.offset,
+ limit: ctx.input.limit
+ });
+ let documents = (Array.isArray(result) ? result : (result.results ?? [])).map(
+ mapIndexedDocument
+ );
+
+ return {
+ output: {
+ action: ctx.input.action,
+ documents,
+ count: result.count ?? documents.length
+ },
+ message: `Found **${result.count ?? documents.length}** indexed document(s).`
+ };
+ }
+
+ let indexName = requireIndexName(ctx.input.indexName, ctx.input.action);
+ let documentIdentifier = requireDocumentIdentifier(
+ ctx.input.documentIdentifier,
+ ctx.input.action
+ );
+
+ if (ctx.input.action === 'add_document') {
+ let result = await client.indexDocument(indexName, documentIdentifier);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ documentIdentifier: result.document ?? documentIdentifier
+ },
+ message: `Indexed document \`${documentIdentifier}\` in **${indexName}**.`
+ };
+ }
+
+ if (ctx.input.action === 'delete_document') {
+ await client.deleteIndexedDocument(indexName, documentIdentifier);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ deleted: true,
+ documentIdentifier
+ },
+ message: `Deleted indexed document \`${documentIdentifier}\` from **${indexName}**.`
+ };
+ }
+
+ await client.reindexDocument(indexName, documentIdentifier);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ reindexed: true,
+ documentIdentifier
+ },
+ message: `Re-indexed document \`${documentIdentifier}\` in **${indexName}**.`
+ };
+ })
+ .build();
diff --git a/integrations/affinda/src/tools/manage-tags.ts b/integrations/affinda/src/tools/manage-tags.ts
new file mode 100644
index 0000000000..08c4ad5b78
--- /dev/null
+++ b/integrations/affinda/src/tools/manage-tags.ts
@@ -0,0 +1,233 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { affindaServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let tagOutputSchema = z.object({
+ tagId: z.number().describe('Affinda tag ID.'),
+ name: z.string().optional().describe('Tag name.'),
+ workspaceIdentifier: z.string().optional().describe('Workspace identifier.'),
+ documentCount: z.number().optional().describe('Number of documents using this tag.')
+});
+
+let mapTag = (tag: any) => ({
+ tagId: tag.id,
+ name: tag.name,
+ workspaceIdentifier: tag.workspace,
+ documentCount: tag.documentCount
+});
+
+let requireTagId = (tagId: number | undefined, action: string) => {
+ if (tagId === undefined) {
+ throw affindaServiceError(`tagId is required for "${action}".`);
+ }
+
+ return tagId;
+};
+
+let requireWorkspace = (workspace: string | undefined, action: string) => {
+ if (!workspace) {
+ throw affindaServiceError(`workspaceIdentifier is required for "${action}".`);
+ }
+
+ return workspace;
+};
+
+let requireName = (name: string | undefined, action: string) => {
+ if (!name) {
+ throw affindaServiceError(`name is required for "${action}".`);
+ }
+
+ return name;
+};
+
+let requireDocuments = (documentIdentifiers: string[] | undefined, action: string) => {
+ if (!documentIdentifiers || documentIdentifiers.length === 0) {
+ throw affindaServiceError(`documentIdentifiers is required for "${action}".`);
+ }
+
+ return documentIdentifiers;
+};
+
+export let manageTags = SlateTool.create(spec, {
+ name: 'Manage Tags',
+ key: 'manage_tags',
+ description: `List, get, create, update, delete, add, and remove Affinda tags. Tags group documents and can be used as filters when listing documents.`,
+ instructions: [
+ 'For "create", provide name and workspaceIdentifier.',
+ 'For "update", provide tagId plus at least one of name or workspaceIdentifier.',
+ 'For "get" or "delete", provide tagId.',
+ 'For "add_to_documents" or "remove_from_documents", provide tagId and documentIdentifiers.'
+ ],
+ tags: {
+ destructive: true
+ }
+})
+ .input(
+ z.object({
+ action: z
+ .enum([
+ 'list',
+ 'get',
+ 'create',
+ 'update',
+ 'delete',
+ 'add_to_documents',
+ 'remove_from_documents'
+ ])
+ .describe('Tag operation to perform.'),
+ tagId: z
+ .number()
+ .optional()
+ .describe(
+ 'Required for get, update, delete, add_to_documents, and remove_from_documents.'
+ ),
+ name: z
+ .string()
+ .optional()
+ .describe('Tag name for create/update, or name filter for list.'),
+ workspaceIdentifier: z
+ .string()
+ .optional()
+ .describe('Workspace identifier for create/update, or workspace filter for list.'),
+ documentIdentifiers: z
+ .array(z.string())
+ .optional()
+ .describe('Document identifiers for add_to_documents and remove_from_documents.'),
+ limit: z.number().optional().describe('Maximum number of tags to return for list.'),
+ offset: z.number().optional().describe('Pagination offset for list.')
+ })
+ )
+ .output(
+ z.object({
+ action: z.string().describe('Operation that was performed.'),
+ tag: tagOutputSchema.optional().describe('Tag returned by get/create/update.'),
+ tags: z.array(tagOutputSchema).optional().describe('Tags returned by list.'),
+ count: z.number().optional().describe('Number of tags returned.'),
+ affectedDocumentCount: z
+ .number()
+ .optional()
+ .describe('Number of documents affected by add/remove operations.'),
+ deleted: z.boolean().optional().describe('Whether a tag was deleted.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ if (ctx.input.action === 'list') {
+ let result = await client.listTags({
+ workspace: ctx.input.workspaceIdentifier,
+ name: ctx.input.name,
+ limit: ctx.input.limit,
+ offset: ctx.input.offset
+ });
+ let tags = (Array.isArray(result) ? result : (result.results ?? [])).map(mapTag);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ tags,
+ count: result.count ?? tags.length
+ },
+ message: `Found **${result.count ?? tags.length}** tag(s).`
+ };
+ }
+
+ if (ctx.input.action === 'get') {
+ let tagId = requireTagId(ctx.input.tagId, ctx.input.action);
+ let result = await client.getTag(tagId);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ tag: mapTag(result)
+ },
+ message: `Retrieved tag \`${tagId}\`.`
+ };
+ }
+
+ if (ctx.input.action === 'create') {
+ let result = await client.createTag({
+ name: requireName(ctx.input.name, ctx.input.action),
+ workspace: requireWorkspace(ctx.input.workspaceIdentifier, ctx.input.action)
+ });
+
+ return {
+ output: {
+ action: ctx.input.action,
+ tag: mapTag(result)
+ },
+ message: `Created tag **${result.name}**.`
+ };
+ }
+
+ if (ctx.input.action === 'update') {
+ let tagId = requireTagId(ctx.input.tagId, ctx.input.action);
+ if (!ctx.input.name && !ctx.input.workspaceIdentifier) {
+ throw affindaServiceError('Provide name or workspaceIdentifier for "update".');
+ }
+
+ let result = await client.updateTag(tagId, {
+ name: ctx.input.name,
+ workspace: ctx.input.workspaceIdentifier
+ });
+
+ return {
+ output: {
+ action: ctx.input.action,
+ tag: mapTag(result)
+ },
+ message: `Updated tag \`${tagId}\`.`
+ };
+ }
+
+ if (ctx.input.action === 'delete') {
+ let tagId = requireTagId(ctx.input.tagId, ctx.input.action);
+ await client.deleteTag(tagId);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ deleted: true
+ },
+ message: `Deleted tag \`${tagId}\`.`
+ };
+ }
+
+ if (ctx.input.action === 'add_to_documents') {
+ let tagId = requireTagId(ctx.input.tagId, ctx.input.action);
+ let documentIdentifiers = requireDocuments(
+ ctx.input.documentIdentifiers,
+ ctx.input.action
+ );
+ await client.batchAddTag(tagId, documentIdentifiers);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ affectedDocumentCount: documentIdentifiers.length
+ },
+ message: `Added tag \`${tagId}\` to **${documentIdentifiers.length}** document(s).`
+ };
+ }
+
+ let tagId = requireTagId(ctx.input.tagId, ctx.input.action);
+ let documentIdentifiers = requireDocuments(
+ ctx.input.documentIdentifiers,
+ ctx.input.action
+ );
+ await client.batchRemoveTag(tagId, documentIdentifiers);
+
+ return {
+ output: {
+ action: ctx.input.action,
+ affectedDocumentCount: documentIdentifiers.length
+ },
+ message: `Removed tag \`${tagId}\` from **${documentIdentifiers.length}** document(s).`
+ };
+ })
+ .build();
diff --git a/integrations/affinda/src/tools/match-resume-to-job.ts b/integrations/affinda/src/tools/match-resume-to-job.ts
index 1c2da6db29..deeaab8598 100644
--- a/integrations/affinda/src/tools/match-resume-to-job.ts
+++ b/integrations/affinda/src/tools/match-resume-to-job.ts
@@ -20,6 +20,10 @@ Both the resume and job description must already be uploaded and parsed in Affin
.string()
.describe('Identifier of the parsed job description document.'),
indexName: z.string().optional().describe('Specific index to use for matching.'),
+ searchExpression: z
+ .string()
+ .optional()
+ .describe('Keywords to add to the search criteria.'),
jobTitlesWeight: z.number().optional().describe('Weight for job titles (0 to 1).'),
skillsWeight: z.number().optional().describe('Weight for skills (0 to 1).'),
educationWeight: z.number().optional().describe('Weight for education (0 to 1).'),
@@ -32,7 +36,12 @@ Both the resume and job description must already be uploaded and parsed in Affin
managementLevelWeight: z
.number()
.optional()
- .describe('Weight for management level (0 to 1).')
+ .describe('Weight for management level (0 to 1).'),
+ searchExpressionWeight: z
+ .number()
+ .optional()
+ .describe('Weight for keyword search expression (0 to 1).'),
+ socCodesWeight: z.number().optional().describe('Weight for SOC codes (0 to 1).')
})
)
.output(
@@ -49,6 +58,7 @@ Both the resume and job description must already be uploaded and parsed in Affin
let extraParams: Record = {};
if (ctx.input.indexName) extraParams.index = ctx.input.indexName;
+ if (ctx.input.searchExpression) extraParams.search_expression = ctx.input.searchExpression;
if (ctx.input.jobTitlesWeight !== undefined)
extraParams.job_titles_weight = ctx.input.jobTitlesWeight;
if (ctx.input.skillsWeight !== undefined)
@@ -63,6 +73,10 @@ Both the resume and job description must already be uploaded and parsed in Affin
extraParams.languages_weight = ctx.input.languagesWeight;
if (ctx.input.managementLevelWeight !== undefined)
extraParams.management_level_weight = ctx.input.managementLevelWeight;
+ if (ctx.input.searchExpressionWeight !== undefined)
+ extraParams.search_expression_weight = ctx.input.searchExpressionWeight;
+ if (ctx.input.socCodesWeight !== undefined)
+ extraParams.soc_codes_weight = ctx.input.socCodesWeight;
let result = await client.matchResumeToJob(
ctx.input.resumeIdentifier,
diff --git a/integrations/affinda/src/tools/redact-resume.ts b/integrations/affinda/src/tools/redact-resume.ts
index edc05fe4a2..251edbadb7 100644
--- a/integrations/affinda/src/tools/redact-resume.ts
+++ b/integrations/affinda/src/tools/redact-resume.ts
@@ -1,17 +1,15 @@
-import { SlateTool } from 'slates';
+import { createBase64Attachment, SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
import { spec } from '../spec';
export let redactResume = SlateTool.create(spec, {
- name: 'Redact Resume',
+ name: 'Get Redacted Document',
key: 'redact_resume',
- description: `Generate a redacted version of a parsed resume document. Select which categories of personally identifiable information (PII) to redact, including personal details (name, address, phone, email), work details (company names), education details (university names), headshots, referees, locations, dates, gender, and PDF metadata.
-
-Returns a base64-encoded PDF with the selected fields redacted. The original document is not modified.`,
+ description: `Retrieve Affinda's redacted PDF for a parsed document. The original document is not modified. The PDF file is returned as a Slate attachment and structured output is limited to metadata.`,
instructions: [
'The document must already be uploaded and parsed in Affinda before redaction.',
- 'All redaction options default to true if not specified — set specific options to false to preserve those fields.'
+ 'Affinda applies redaction according to the document and account configuration for this endpoint.'
],
tags: {
readOnly: true
@@ -21,47 +19,15 @@ Returns a base64-encoded PDF with the selected fields redacted. The original doc
z.object({
documentIdentifier: z
.string()
- .describe('Identifier of the parsed resume document to redact.'),
- redactHeadshot: z
- .boolean()
- .optional()
- .describe('Redact the candidate headshot photo. Defaults to true.'),
- redactPersonalDetails: z
- .boolean()
- .optional()
- .describe('Redact personal details (name, address, phone, email). Defaults to true.'),
- redactWorkDetails: z
- .boolean()
- .optional()
- .describe('Redact work details such as company names. Defaults to true.'),
- redactEducationDetails: z
- .boolean()
- .optional()
- .describe('Redact education details such as university names. Defaults to true.'),
- redactReferees: z
- .boolean()
- .optional()
- .describe('Redact referee information. Defaults to true.'),
- redactLocations: z
- .boolean()
- .optional()
- .describe('Redact location names. Defaults to true.'),
- redactDates: z.boolean().optional().describe('Redact dates. Defaults to true.'),
- redactGender: z
- .boolean()
- .optional()
- .describe('Redact gender information. Defaults to true.'),
- redactPdfMetadata: z
- .boolean()
- .optional()
- .describe('Redact PDF metadata. Defaults to true.')
+ .describe('Identifier of the parsed document to retrieve redacted PDF for.')
})
)
.output(
z.object({
- redactedPdfBase64: z
- .string()
- .describe('Base64-encoded content of the redacted PDF file.')
+ documentIdentifier: z.string().describe('Identifier of the redacted document.'),
+ mimeType: z.string().describe('MIME type of the returned attachment.'),
+ byteLength: z.number().describe('Decoded byte length of the returned attachment.'),
+ attachmentCount: z.number().describe('Number of Slate attachments returned.')
})
)
.handleInvocation(async ctx => {
@@ -72,23 +38,17 @@ Returns a base64-encoded PDF with the selected fields redacted. The original doc
ctx.info('Generating redacted document...');
- let base64Pdf = await client.getRedactedDocument(ctx.input.documentIdentifier, {
- redactHeadshot: ctx.input.redactHeadshot,
- redactPersonalDetails: ctx.input.redactPersonalDetails,
- redactWorkDetails: ctx.input.redactWorkDetails,
- redactEducationDetails: ctx.input.redactEducationDetails,
- redactReferees: ctx.input.redactReferees,
- redactLocations: ctx.input.redactLocations,
- redactDates: ctx.input.redactDates,
- redactGender: ctx.input.redactGender,
- redactPdfMetadata: ctx.input.redactPdfMetadata
- });
+ let file = await client.getRedactedDocument(ctx.input.documentIdentifier);
return {
output: {
- redactedPdfBase64: base64Pdf
+ documentIdentifier: ctx.input.documentIdentifier,
+ mimeType: file.mimeType,
+ byteLength: file.byteLength,
+ attachmentCount: 1
},
- message: `Redacted PDF generated for document \`${ctx.input.documentIdentifier}\`.`
+ attachments: [createBase64Attachment(file.contentBase64, file.mimeType)],
+ message: `Redacted PDF generated for document \`${ctx.input.documentIdentifier}\` as an attachment.`
};
})
.build();
diff --git a/integrations/affinda/src/tools/search-and-match.ts b/integrations/affinda/src/tools/search-and-match.ts
index b3d1198d52..6e8a72a26f 100644
--- a/integrations/affinda/src/tools/search-and-match.ts
+++ b/integrations/affinda/src/tools/search-and-match.ts
@@ -5,8 +5,13 @@ import { spec } from '../spec';
let locationSchema = z.object({
name: z.string().optional().describe('Location name.'),
- latitude: z.number().optional().describe('Latitude coordinate.'),
- longitude: z.number().optional().describe('Longitude coordinate.'),
+ coordinates: z
+ .object({
+ latitude: z.number().describe('Latitude coordinate.'),
+ longitude: z.number().describe('Longitude coordinate.')
+ })
+ .optional()
+ .describe('Location coordinates.'),
distance: z.number().optional().describe('Search radius distance.'),
unit: z.string().optional().describe('Distance unit (e.g., "km", "mi").')
});
@@ -62,6 +67,10 @@ Returns a ranked shortlist with matching scores for each category.`,
.boolean()
.optional()
.describe('Whether job title match is required.'),
+ jobTitlesCurrentOnly: z
+ .boolean()
+ .optional()
+ .describe('Match only current job titles when searching resumes.'),
skills: z.array(skillSchema).optional().describe('Skills to search for.'),
skillsWeight: z.number().optional().describe('Weight for skills matching (0 to 1).'),
locations: z.array(locationSchema).optional().describe('Locations to search for.'),
@@ -140,6 +149,8 @@ Returns a ranked shortlist with matching scores for each category.`,
searchParams.jobTitlesWeight = ctx.input.jobTitlesWeight;
if (ctx.input.jobTitlesRequired !== undefined)
searchParams.jobTitlesRequired = ctx.input.jobTitlesRequired;
+ if (ctx.input.jobTitlesCurrentOnly !== undefined)
+ searchParams.jobTitlesCurrentOnly = ctx.input.jobTitlesCurrentOnly;
if (ctx.input.skills) searchParams.skills = ctx.input.skills;
if (ctx.input.skillsWeight !== undefined)
searchParams.skillsWeight = ctx.input.skillsWeight;
diff --git a/integrations/affinda/src/tools/update-document.ts b/integrations/affinda/src/tools/update-document.ts
new file mode 100644
index 0000000000..a00fdddf15
--- /dev/null
+++ b/integrations/affinda/src/tools/update-document.ts
@@ -0,0 +1,131 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { affindaServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+export let updateDocument = SlateTool.create(spec, {
+ name: 'Update Document',
+ key: 'update_document',
+ description: `Update Affinda document metadata and lifecycle state. Use this to rename a document, move it to another workspace or collection, update custom identifiers, set an expiry time, archive, confirm, reject, or skip parsing.`,
+ instructions: [
+ 'Provide at least one field to update.',
+ 'Use delete_document only when the document should be permanently removed.'
+ ],
+ tags: {
+ destructive: false
+ }
+})
+ .input(
+ z.object({
+ documentIdentifier: z.string().describe('Identifier of the document to update.'),
+ workspaceIdentifier: z
+ .string()
+ .optional()
+ .describe('Move the document to this workspace.'),
+ collectionIdentifier: z
+ .string()
+ .optional()
+ .describe('Move the document to this collection.'),
+ documentTypeIdentifier: z
+ .string()
+ .optional()
+ .describe('Set the document type identifier.'),
+ fileName: z.string().optional().describe('New document file name.'),
+ expiryTime: z
+ .string()
+ .optional()
+ .describe('ISO-8601 date-time when Affinda should automatically delete the document.'),
+ isConfirmed: z.boolean().optional().describe('Mark the document as confirmed.'),
+ isRejected: z.boolean().optional().describe('Mark the document as rejected.'),
+ isArchived: z.boolean().optional().describe('Mark the document as archived.'),
+ skipParse: z.boolean().optional().describe('Skip parsing for this document.'),
+ language: z.string().optional().describe('Language code in ISO 639-1 format.'),
+ identifier: z
+ .string()
+ .optional()
+ .describe('Deprecated Affinda identifier override. Prefer customIdentifier.'),
+ customIdentifier: z
+ .string()
+ .optional()
+ .describe('Custom identifier for external reference.'),
+ llmHint: z
+ .string()
+ .optional()
+ .describe(
+ 'Optional hint inserted into the LLM prompt while processing this document.'
+ ),
+ compact: z
+ .boolean()
+ .optional()
+ .describe('If true, returns compact parsed data in the response.')
+ })
+ )
+ .output(
+ z.object({
+ documentIdentifier: z.string().describe('Identifier of the updated document.'),
+ fileName: z.string().optional().describe('Updated file name.'),
+ state: z.string().optional().describe('Current processing state.'),
+ customIdentifier: z.string().optional().describe('Custom identifier.'),
+ ready: z.boolean().optional().describe('Whether the document has finished processing.'),
+ failed: z.boolean().optional().describe('Whether parsing has failed.'),
+ isConfirmed: z.boolean().optional().describe('Whether the document is confirmed.'),
+ isRejected: z.boolean().optional().describe('Whether the document is rejected.'),
+ isArchived: z.boolean().optional().describe('Whether the document is archived.'),
+ workspaceIdentifier: z.string().optional().describe('Workspace identifier.'),
+ collectionIdentifier: z.string().optional().describe('Collection identifier.'),
+ documentTypeIdentifier: z.string().optional().describe('Document type identifier.'),
+ extractedData: z.any().optional().describe('Updated parsed data, when returned.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let data: Record = {};
+
+ if (ctx.input.workspaceIdentifier) data.workspace = ctx.input.workspaceIdentifier;
+ if (ctx.input.collectionIdentifier) data.collection = ctx.input.collectionIdentifier;
+ if (ctx.input.documentTypeIdentifier) data.documentType = ctx.input.documentTypeIdentifier;
+ if (ctx.input.fileName) data.fileName = ctx.input.fileName;
+ if (ctx.input.expiryTime) data.expiryTime = ctx.input.expiryTime;
+ if (ctx.input.isConfirmed !== undefined) data.isConfirmed = ctx.input.isConfirmed;
+ if (ctx.input.isRejected !== undefined) data.isRejected = ctx.input.isRejected;
+ if (ctx.input.isArchived !== undefined) data.isArchived = ctx.input.isArchived;
+ if (ctx.input.skipParse !== undefined) data.skipParse = ctx.input.skipParse;
+ if (ctx.input.language) data.language = ctx.input.language;
+ if (ctx.input.identifier) data.identifier = ctx.input.identifier;
+ if (ctx.input.customIdentifier) data.customIdentifier = ctx.input.customIdentifier;
+ if (ctx.input.llmHint) data.llmHint = ctx.input.llmHint;
+
+ if (Object.keys(data).length === 0) {
+ throw affindaServiceError('Provide at least one document field to update.');
+ }
+
+ let client = new Client({
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ let result = await client.updateDocument(ctx.input.documentIdentifier, data, {
+ compact: ctx.input.compact
+ });
+ let meta = result.meta ?? result;
+
+ return {
+ output: {
+ documentIdentifier: meta.identifier ?? ctx.input.documentIdentifier,
+ fileName: meta.fileName,
+ state: meta.state,
+ customIdentifier: meta.customIdentifier,
+ ready: meta.ready,
+ failed: meta.failed,
+ isConfirmed: meta.isConfirmed,
+ isRejected: meta.isRejected,
+ isArchived: meta.isArchived,
+ workspaceIdentifier: meta.workspace?.identifier,
+ collectionIdentifier: meta.collection?.identifier,
+ documentTypeIdentifier: meta.documentType,
+ extractedData: result.data
+ },
+ message: `Updated document \`${meta.identifier ?? ctx.input.documentIdentifier}\`.`
+ };
+ })
+ .build();
diff --git a/integrations/affinda/src/tools/upload-document.ts b/integrations/affinda/src/tools/upload-document.ts
index a9ac45b942..3eef1fa906 100644
--- a/integrations/affinda/src/tools/upload-document.ts
+++ b/integrations/affinda/src/tools/upload-document.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { affindaServiceError } from '../lib/errors';
import { spec } from '../spec';
export let uploadDocument = SlateTool.create(spec, {
@@ -10,7 +11,7 @@ export let uploadDocument = SlateTool.create(spec, {
Set **wait** to \`true\` to receive parsed results immediately, or \`false\` to get the document identifier and poll later.`,
instructions: [
- 'Either a URL or a workspace/collection must be provided.',
+ 'Provide exactly one document source: fileContentBase64 or url.',
'If uploading to a workspace without specifying a collection, the document will be automatically classified and routed.',
'If uploading to a specific collection, the extractor associated with that collection will be applied.'
],
@@ -25,6 +26,10 @@ Set **wait** to \`true\` to receive parsed results immediately, or \`false\` to
.string()
.optional()
.describe('Publicly accessible URL of the document to process.'),
+ fileContentBase64: z
+ .string()
+ .optional()
+ .describe('Base64-encoded document file content to upload directly.'),
workspaceIdentifier: z
.string()
.optional()
@@ -55,7 +60,12 @@ Set **wait** to \`true\` to receive parsed results immediately, or \`false\` to
fileName: z
.string()
.optional()
- .describe('Override file name for the uploaded document.'),
+ .describe('File name for file uploads or override file name for URL uploads.'),
+ fileMimeType: z.string().optional().describe('MIME type for fileContentBase64 uploads.'),
+ expiryTime: z
+ .string()
+ .optional()
+ .describe('ISO-8601 date-time when Affinda should automatically delete the document.'),
language: z
.string()
.optional()
@@ -78,7 +88,21 @@ Set **wait** to \`true\` to receive parsed results immediately, or \`false\` to
enableValidationTool: z
.boolean()
.optional()
- .describe('If true, makes the document viewable in the Affinda validation interface.')
+ .describe('If true, makes the document viewable in the Affinda validation interface.'),
+ useOcr: z
+ .boolean()
+ .optional()
+ .describe('Force OCR on or off. If omitted, Affinda chooses automatically.'),
+ llmHint: z
+ .string()
+ .optional()
+ .describe(
+ 'Optional hint inserted into the LLM prompt while processing this document.'
+ ),
+ limitToExamples: z
+ .array(z.string())
+ .optional()
+ .describe('Restrict LLM example selection to these document identifiers.')
})
)
.output(
@@ -86,15 +110,39 @@ Set **wait** to \`true\` to receive parsed results immediately, or \`false\` to
documentIdentifier: z.string().describe('Unique identifier of the uploaded document.'),
fileName: z.string().optional().describe('Name of the processed file.'),
state: z.string().optional().describe('Current processing state of the document.'),
+ ready: z.boolean().optional().describe('Whether the document has finished processing.'),
+ failed: z.boolean().optional().describe('Whether parsing has failed.'),
+ customIdentifier: z
+ .string()
+ .optional()
+ .describe('Custom identifier assigned to the document.'),
+ reviewUrl: z
+ .string()
+ .optional()
+ .describe('Affinda validation/review URL for the document.'),
extractedData: z
.any()
.optional()
.describe(
'Structured JSON data extracted from the document (only present when wait is true).'
- )
+ ),
+ warnings: z.array(z.any()).optional().describe('Warnings returned by Affinda.')
})
)
.handleInvocation(async ctx => {
+ let hasUrl = typeof ctx.input.url === 'string' && ctx.input.url.length > 0;
+ let hasFile =
+ typeof ctx.input.fileContentBase64 === 'string' &&
+ ctx.input.fileContentBase64.length > 0;
+
+ if (hasUrl === hasFile) {
+ throw affindaServiceError('Provide exactly one of url or fileContentBase64.');
+ }
+
+ if (hasFile && !ctx.input.fileName) {
+ throw affindaServiceError('fileName is required when uploading fileContentBase64.');
+ }
+
let client = new Client({
token: ctx.auth.token,
region: ctx.config.region
@@ -105,6 +153,13 @@ Set **wait** to \`true\` to receive parsed results immediately, or \`false\` to
ctx.info('Uploading document to Affinda...');
let result = await client.uploadDocument({
+ file: hasFile
+ ? {
+ name: ctx.input.fileName!,
+ data: ctx.input.fileContentBase64!,
+ mimeType: ctx.input.fileMimeType
+ }
+ : undefined,
url: ctx.input.url,
workspace,
collection: ctx.input.collectionIdentifier,
@@ -113,24 +168,34 @@ Set **wait** to \`true\` to receive parsed results immediately, or \`false\` to
identifier: ctx.input.identifier,
customIdentifier: ctx.input.customIdentifier,
fileName: ctx.input.fileName,
+ expiryTime: ctx.input.expiryTime,
language: ctx.input.language,
rejectDuplicates: ctx.input.rejectDuplicates,
lowPriority: ctx.input.lowPriority,
compact: ctx.input.compact,
deleteAfterParse: ctx.input.deleteAfterParse,
- enableValidationTool: ctx.input.enableValidationTool
+ enableValidationTool: ctx.input.enableValidationTool,
+ useOcr: ctx.input.useOcr,
+ llmHint: ctx.input.llmHint,
+ limitToExamples: ctx.input.limitToExamples
});
+ let meta = result.meta ?? result;
return {
output: {
- documentIdentifier: result.meta?.identifier ?? result.identifier ?? '',
- fileName: result.meta?.fileName ?? result.fileName,
- state: result.meta?.state ?? result.state,
- extractedData: result.data
+ documentIdentifier: meta.identifier ?? '',
+ fileName: meta.fileName,
+ state: meta.state,
+ ready: meta.ready,
+ failed: meta.failed,
+ customIdentifier: meta.customIdentifier,
+ reviewUrl: meta.reviewUrl,
+ extractedData: result.data,
+ warnings: result.warnings
},
message: ctx.input.wait
- ? `Document **${result.meta?.fileName ?? result.fileName ?? 'uploaded'}** has been parsed successfully.`
- : `Document uploaded and processing has started. Document identifier: \`${result.meta?.identifier ?? result.identifier}\``
+ ? `Document **${meta.fileName ?? 'uploaded'}** has been parsed successfully.`
+ : `Document uploaded and processing has started. Document identifier: \`${meta.identifier}\``
};
})
.build();
diff --git a/integrations/affinda/src/tools/validation-results.ts b/integrations/affinda/src/tools/validation-results.ts
new file mode 100644
index 0000000000..c2382091ed
--- /dev/null
+++ b/integrations/affinda/src/tools/validation-results.ts
@@ -0,0 +1,74 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+let validationResultSchema = z.object({
+ validationResultId: z.number().describe('Affinda validation result ID.'),
+ annotationIds: z
+ .array(z.number())
+ .optional()
+ .describe('Annotation IDs that were validated.'),
+ passed: z.boolean().nullable().optional().describe('Whether validation passed.'),
+ ruleSlug: z.string().optional().describe('Validation rule slug.'),
+ message: z.string().optional().describe('Validation message.'),
+ documentIdentifier: z.string().optional().describe('Document identifier.')
+});
+
+let mapValidationResult = (result: any) => ({
+ validationResultId: result.id,
+ annotationIds: result.annotations,
+ passed: result.passed,
+ ruleSlug: result.ruleSlug,
+ message: result.message,
+ documentIdentifier: result.document
+});
+
+export let listValidationResults = SlateTool.create(spec, {
+ name: 'List Validation Results',
+ key: 'list_validation_results',
+ description: `List Affinda validation results for a document. Use this to inspect validation rule outcomes after a document has been parsed and reviewed.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ documentIdentifier: z
+ .string()
+ .describe('Document identifier to filter validation results by.'),
+ offset: z.number().optional().describe('Pagination offset.'),
+ limit: z.number().optional().describe('Maximum number of validation results to return.')
+ })
+ )
+ .output(
+ z.object({
+ count: z.number().describe('Number of validation results returned.'),
+ validationResults: z
+ .array(validationResultSchema)
+ .describe('Validation results for the document.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ let result = await client.listValidationResults({
+ documentIdentifier: ctx.input.documentIdentifier,
+ offset: ctx.input.offset,
+ limit: ctx.input.limit
+ });
+ let results = Array.isArray(result) ? result : (result.results ?? []);
+ let validationResults = results.map(mapValidationResult);
+
+ return {
+ output: {
+ count: result.count ?? validationResults.length,
+ validationResults
+ },
+ message: `Found **${result.count ?? validationResults.length}** validation result(s).`
+ };
+ })
+ .build();
diff --git a/integrations/affinda/src/triggers/document-events.ts b/integrations/affinda/src/triggers/document-events.ts
index 3598ecd0ec..95b2212fbd 100644
--- a/integrations/affinda/src/triggers/document-events.ts
+++ b/integrations/affinda/src/triggers/document-events.ts
@@ -1,6 +1,7 @@
import { SlateTrigger } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { affindaServiceError } from '../lib/errors';
import { spec } from '../spec';
export let documentEvents = SlateTrigger.create(spec, {
@@ -53,7 +54,7 @@ export let documentEvents = SlateTrigger.create(spec, {
let orgIdentifier = orgList[0]?.identifier;
if (!orgIdentifier) {
- throw new Error(
+ throw affindaServiceError(
'No organization found. An organization is required to register webhooks.'
);
}
diff --git a/integrations/affinda/vitest.config.ts b/integrations/affinda/vitest.config.ts
new file mode 100644
index 0000000000..0b05bc07ad
--- /dev/null
+++ b/integrations/affinda/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['src/**/*.test.ts']
+ }
+});
diff --git a/integrations/amplitude/README.md b/integrations/amplitude/README.md
index 4845e4cfaa..313c8abe9d 100644
--- a/integrations/amplitude/README.md
+++ b/integrations/amplitude/README.md
@@ -1,6 +1,6 @@
#
Amplitude
-Track user behavior, analyze engagement, and run experiments on a product analytics platform. Ingest event data via HTTP or batch APIs, query dashboard analytics including segmentation, funnels, retention, and session metrics. Export raw event data, look up user profiles, and manage behavioral cohorts. Create and manage feature flags and experiments, evaluate flag variants for users. Manage taxonomy (event types, event properties, user properties), upload lookup tables to enrich event data, and handle chart annotations. Modify user and group properties via Identify APIs, merge user identities, and manage user privacy including GDPR/CCPA deletion and data subject access requests. Provision users and permission groups via SCIM. Stream events, user updates, and cohort membership changes to external webhooks, and receive alerts when KPIs change.
+Track user behavior, query product analytics, export raw events, and maintain core Amplitude project data. Ingest events through HTTP V2 or Batch APIs, update user and group properties, map identities, query Dashboard REST analytics, retrieve saved chart CSV results, manage behavioral cohorts, maintain taxonomy metadata, handle chart annotations, look up US-region user profiles, and submit or inspect user privacy deletion jobs. Enterprise/admin-only APIs such as Experiment, SCIM, lookup tables, releases, DSAR exports, and outbound streaming are not exposed by this integration.
## Tools
@@ -8,9 +8,13 @@ Track user behavior, analyze engagement, and run experiments on a product analyt
Request deletion of user data from Amplitude for privacy compliance (GDPR/CCPA). Supports deleting a single user or multiple users in bulk. You can also check the status of pending deletion jobs.
+### Export Events
+
+Export raw Amplitude event files for an uploaded-time range as a ZIP attachment. Structured output contains only metadata such as MIME type, byte length, and attachment count.
+
### Get Chart Results
-Fetch results from a saved chart in Amplitude by its chart ID. Returns the same data that the chart displays in the Amplitude dashboard. The chart ID can be found in the URL when viewing a chart.
+Fetch CSV results from a saved chart in Amplitude by its chart ID. The chart ID can be found in the URL when viewing a chart, and CSV content is returned as a Slate attachment.
### Get User Profile
@@ -26,7 +30,7 @@ Manage chart annotations in Amplitude. Annotations mark important events on time
### Manage Cohorts
-List, retrieve, create, or update behavioral cohorts in Amplitude. Cohorts are groups of users defined by shared behavior or characteristics. Use this to list all cohorts, get details of a specific cohort, or upload/update a cohort with specific user IDs.
+List cohorts, retrieve a cohort from the discoverable cohort list, check Behavioral Cohorts Download API usage, upload static cohorts, and incrementally add or remove cohort membership.
### Manage Taxonomy
diff --git a/integrations/amplitude/package.json b/integrations/amplitude/package.json
index ec83372fbf..a3ccc3c6ca 100644
--- a/integrations/amplitude/package.json
+++ b/integrations/amplitude/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --config vitest.config.ts --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
- "typescript": "^5"
+ "@slates/test": "1.0.0-rc.9",
+ "typescript": "^5",
+ "vitest": "^3.1.2"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.6"
}
diff --git a/integrations/amplitude/src/index.ts b/integrations/amplitude/src/index.ts
index c190ee33b5..a7fbd366ea 100644
--- a/integrations/amplitude/src/index.ts
+++ b/integrations/amplitude/src/index.ts
@@ -2,6 +2,7 @@ import { Slate } from 'slates';
import { spec } from './spec';
import {
deleteUserDataTool,
+ exportEventsTool,
getChartResultsTool,
getUserProfileTool,
identifyUserTool,
@@ -29,6 +30,7 @@ export let provider = Slate.create({
queryRetentionTool,
querySessionsTool,
queryUserCompositionTool,
+ exportEventsTool,
getUserProfileTool,
getChartResultsTool,
manageCohortsTool,
diff --git a/integrations/amplitude/src/lib/client.ts b/integrations/amplitude/src/lib/client.ts
index 9f785f9175..be0887ebd8 100644
--- a/integrations/amplitude/src/lib/client.ts
+++ b/integrations/amplitude/src/lib/client.ts
@@ -1,4 +1,6 @@
+import { Buffer } from 'node:buffer';
import { createAxios } from 'slates';
+import { amplitudeApiError, amplitudeServiceError } from './errors';
export type AmplitudeRegion = 'US' | 'EU';
@@ -16,6 +18,10 @@ let getIngestionBaseUrl = (region: AmplitudeRegion) => {
return region === 'EU' ? 'https://api.eu.amplitude.com' : 'https://api2.amplitude.com';
};
+let getUserMappingBaseUrl = (region: AmplitudeRegion) => {
+ return region === 'EU' ? 'https://api.eu.amplitude.com' : 'https://api.amplitude.com';
+};
+
let getProfileBaseUrl = (region: AmplitudeRegion) => {
return region === 'EU'
? 'https://profile-api.eu.amplitude.com'
@@ -73,12 +79,67 @@ export class AmplitudeClient {
this.config = config;
}
+ private withErrorHandling(ax: ReturnType) {
+ ax.interceptors.response.use(
+ response => response,
+ error => Promise.reject(amplitudeApiError(error))
+ );
+ return ax;
+ }
+
+ private getIngestionAxios() {
+ return this.withErrorHandling(
+ createAxios({
+ baseURL: getIngestionBaseUrl(this.config.region)
+ })
+ );
+ }
+
+ private getUserMappingAxios() {
+ return this.withErrorHandling(
+ createAxios({
+ baseURL: getUserMappingBaseUrl(this.config.region)
+ })
+ );
+ }
+
+ private getAnalyticsAxios() {
+ return this.withErrorHandling(
+ createAxios({
+ baseURL: getApiBaseUrl(this.config.region),
+ headers: {
+ Authorization: `Basic ${this.config.token}`
+ }
+ })
+ );
+ }
+
+ private getProfileAxios() {
+ return this.withErrorHandling(
+ createAxios({
+ baseURL: getProfileBaseUrl(this.config.region),
+ headers: {
+ Authorization: `Api-Key ${this.config.secretKey}`
+ }
+ })
+ );
+ }
+
+ private getExportAxios() {
+ return this.withErrorHandling(
+ createAxios({
+ baseURL: getBaseUrl(this.config.region),
+ headers: {
+ Authorization: `Basic ${this.config.token}`
+ }
+ })
+ );
+ }
+
// --- Event Ingestion ---
async trackEvents(events: AmplitudeEvent[], options?: { minIdLength?: number }) {
- let ax = createAxios({
- baseURL: getIngestionBaseUrl(this.config.region)
- });
+ let ax = this.getIngestionAxios();
let body: Record = {
api_key: this.config.apiKey,
@@ -94,9 +155,7 @@ export class AmplitudeClient {
}
async batchTrackEvents(events: AmplitudeEvent[], options?: { minIdLength?: number }) {
- let ax = createAxios({
- baseURL: getIngestionBaseUrl(this.config.region)
- });
+ let ax = this.getIngestionAxios();
let body: Record = {
api_key: this.config.apiKey,
@@ -158,9 +217,7 @@ export class AmplitudeClient {
deviceId?: string;
userProperties: Record;
}) {
- let ax = createAxios({
- baseURL: getIngestionBaseUrl(this.config.region)
- });
+ let ax = this.getIngestionAxios();
let identifyPayload = {
user_id: identification.userId,
@@ -182,9 +239,7 @@ export class AmplitudeClient {
groupValue: string,
groupProperties: Record
) {
- let ax = createAxios({
- baseURL: getIngestionBaseUrl(this.config.region)
- });
+ let ax = this.getIngestionAxios();
let identifyPayload = {
group_type: groupType,
@@ -204,9 +259,7 @@ export class AmplitudeClient {
// --- User Mapping (Aliasing) ---
async mapUserIdentities(mapping: { userId: string; globalUserId: string }) {
- let ax = createAxios({
- baseURL: getIngestionBaseUrl(this.config.region)
- });
+ let ax = this.getUserMappingAxios();
let response = await ax.post('/usermap', null, {
params: {
@@ -222,15 +275,6 @@ export class AmplitudeClient {
// --- Dashboard REST API ---
- private getAnalyticsAxios() {
- return createAxios({
- baseURL: getApiBaseUrl(this.config.region),
- headers: {
- Authorization: `Basic ${this.config.token}`
- }
- });
- }
-
async getActiveAndNewUserCounts(params: {
start: string;
end: string;
@@ -307,19 +351,28 @@ export class AmplitudeClient {
async getChartResults(chartId: string) {
let ax = this.getAnalyticsAxios();
- let response = await ax.get(`/3/chart/${chartId}/query`);
- return response.data;
+ let response = await ax.get(`/3/chart/${chartId}/csv`, {
+ responseType: 'text'
+ });
+ let content =
+ typeof response.data === 'string' ? response.data : JSON.stringify(response.data);
+ let contentTypeHeader = response.headers?.['content-type'];
+ let contentType =
+ typeof contentTypeHeader === 'string'
+ ? contentTypeHeader.split(';')[0]?.trim()
+ : undefined;
+
+ return {
+ content,
+ contentType: contentType || 'text/csv',
+ byteLength: Buffer.byteLength(content)
+ };
}
// --- User Profile API ---
async getUserProfile(params: { userId?: string; amplitudeId?: number }) {
- let ax = createAxios({
- baseURL: getProfileBaseUrl(this.config.region),
- headers: {
- Authorization: `Api-Key ${this.config.secretKey}`
- }
- });
+ let ax = this.getProfileAxios();
let queryParams: Record = {};
if (params.userId) queryParams.user_id = params.userId;
@@ -338,9 +391,18 @@ export class AmplitudeClient {
}
async getCohort(cohortId: string) {
- let ax = this.getAnalyticsAxios();
- let response = await ax.get(`/3/cohorts/${cohortId}`);
- return response.data;
+ let result = await this.listCohorts();
+ let cohorts = Array.isArray(result) ? result : (result.cohorts ?? []);
+ let cohort = cohorts.find((item: any) => {
+ let id = item.id ?? item.cohort_id;
+ return id !== undefined && String(id) === cohortId;
+ });
+
+ if (!cohort) {
+ throw amplitudeServiceError(`Amplitude cohort "${cohortId}" was not found.`);
+ }
+
+ return cohort;
}
async downloadCohort(cohortId: string, props?: boolean) {
@@ -353,7 +415,7 @@ export class AmplitudeClient {
async getCohortDownloadStatus(requestId: string) {
let ax = this.getAnalyticsAxios();
- let response = await ax.get(`/5/cohorts/request/status/${requestId}`);
+ let response = await ax.get(`/5/cohorts/request-status/${requestId}`);
return response.data;
}
@@ -363,6 +425,10 @@ export class AmplitudeClient {
idType: 'BY_AMP_ID' | 'BY_USER_ID';
ids: string[];
owner?: string;
+ published?: boolean;
+ skipSave?: boolean;
+ skipInvalidIds?: boolean;
+ countGroup?: string;
existingCohortId?: string;
}) {
let ax = this.getAnalyticsAxios();
@@ -373,12 +439,48 @@ export class AmplitudeClient {
ids: params.ids
};
if (params.owner) body.owner = params.owner;
+ if (params.published !== undefined) body.published = params.published;
+ if (params.skipSave !== undefined) body.skip_save = params.skipSave;
+ if (params.skipInvalidIds !== undefined) body.skip_invalid_ids = params.skipInvalidIds;
+ if (params.countGroup) body.cg = params.countGroup;
if (params.existingCohortId) body.existing_cohort_id = params.existingCohortId;
let response = await ax.post('/3/cohorts/upload', body);
return response.data;
}
+ async getCohortUsage() {
+ let ax = this.getAnalyticsAxios();
+ let response = await ax.get('/3/cohorts/usage');
+ return response.data;
+ }
+
+ async updateCohortMembership(params: {
+ cohortId: string;
+ memberships: Array<{
+ ids: string[];
+ idType: 'BY_ID' | 'BY_NAME';
+ operation: 'ADD' | 'REMOVE';
+ }>;
+ countGroup?: string;
+ skipInvalidIds?: boolean;
+ }) {
+ let ax = this.getAnalyticsAxios();
+ let body: Record = {
+ cohort_id: params.cohortId,
+ memberships: params.memberships.map(membership => ({
+ ids: membership.ids,
+ id_type: membership.idType,
+ operation: membership.operation
+ }))
+ };
+ if (params.countGroup) body.count_group = params.countGroup;
+ if (params.skipInvalidIds !== undefined) body.skip_invalid_ids = params.skipInvalidIds;
+
+ let response = await ax.post('/3/cohorts/membership', body);
+ return response.data;
+ }
+
// --- Taxonomy API ---
async getEventTypes() {
@@ -599,25 +701,35 @@ export class AmplitudeClient {
async listAnnotations() {
let ax = this.getAnalyticsAxios();
- let response = await ax.get('/2/annotations');
+ let response = await ax.get('/3/annotations');
return response.data;
}
async getAnnotation(annotationId: string) {
let ax = this.getAnalyticsAxios();
- let response = await ax.get(`/2/annotations/${annotationId}`);
+ let response = await ax.get(`/3/annotations/${annotationId}`);
return response.data;
}
- async createAnnotation(params: { label: string; date: string; details?: string }) {
+ async createAnnotation(params: {
+ label: string;
+ start: string;
+ details?: string;
+ end?: string;
+ category?: string;
+ chartId?: string;
+ }) {
let ax = this.getAnalyticsAxios();
let body: Record = {
label: params.label,
- date: params.date
+ start: params.start
};
if (params.details) body.details = params.details;
+ if (params.end) body.end = params.end;
+ if (params.category) body.category = params.category;
+ if (params.chartId) body.chart_id = params.chartId;
- let response = await ax.post('/2/annotations', body);
+ let response = await ax.post('/3/annotations', body);
return response.data;
}
@@ -625,39 +737,53 @@ export class AmplitudeClient {
annotationId: string,
params: {
label?: string;
- date?: string;
+ start?: string;
details?: string;
+ end?: string | null;
+ category?: string;
+ chartId?: string | null;
}
) {
let ax = this.getAnalyticsAxios();
let body: Record = {};
if (params.label) body.label = params.label;
- if (params.date) body.date = params.date;
- if (params.details) body.details = params.details;
+ if (params.start) body.start = params.start;
+ if (params.details !== undefined) body.details = params.details;
+ if (params.end !== undefined) body.end = params.end;
+ if (params.category) body.category = params.category;
+ if (params.chartId !== undefined) body.chart_id = params.chartId;
- let response = await ax.put(`/2/annotations/${annotationId}`, body);
+ let response = await ax.put(`/3/annotations/${annotationId}`, body);
return response.data;
}
async deleteAnnotation(annotationId: string) {
let ax = this.getAnalyticsAxios();
- let response = await ax.delete(`/2/annotations/${annotationId}`);
+ let response = await ax.delete(`/3/annotations/${annotationId}`);
return response.data;
}
// --- Export API ---
async exportEvents(params: { start: string; end: string }) {
- let ax = createAxios({
- baseURL: getBaseUrl(this.config.region),
- headers: {
- Authorization: `Basic ${this.config.token}`
- }
- });
+ let ax = this.getExportAxios();
let response = await ax.get('/api/2/export', {
- params: { start: params.start, end: params.end }
+ params: { start: params.start, end: params.end },
+ responseType: 'arraybuffer'
});
- return response.data;
+
+ let buffer = Buffer.isBuffer(response.data) ? response.data : Buffer.from(response.data);
+ let contentTypeHeader = response.headers?.['content-type'];
+ let contentType =
+ typeof contentTypeHeader === 'string'
+ ? contentTypeHeader.split(';')[0]?.trim()
+ : undefined;
+
+ return {
+ contentBase64: buffer.toString('base64'),
+ contentType: contentType || 'application/zip',
+ byteLength: buffer.byteLength
+ };
}
// --- User Privacy / Deletion ---
diff --git a/integrations/amplitude/src/lib/errors.ts b/integrations/amplitude/src/lib/errors.ts
new file mode 100644
index 0000000000..b24e2fc34e
--- /dev/null
+++ b/integrations/amplitude/src/lib/errors.ts
@@ -0,0 +1,77 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null;
+
+let addDetail = (details: string[], value: unknown) => {
+ let text = typeof value === 'string' ? value.trim() : '';
+ if (text && !details.includes(text)) {
+ details.push(text);
+ }
+};
+
+let getErrorResponse = (error: unknown) =>
+ isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+
+let extractAmplitudeMessage = (error: unknown) => {
+ let data = getErrorResponse(error)?.data;
+ let details: string[] = [];
+
+ if (isRecord(data)) {
+ addDetail(details, data.error);
+ addDetail(details, data.message);
+ addDetail(details, data.type);
+ addDetail(details, data.status);
+
+ let metadata = data.metadata;
+ if (isRecord(metadata)) {
+ addDetail(details, metadata.message);
+ addDetail(details, metadata.reason);
+ }
+ } else if (typeof data === 'string') {
+ addDetail(details, data);
+ }
+
+ if (details.length > 0) {
+ return details.join(' - ');
+ }
+
+ if (error instanceof Error && error.message) {
+ return error.message;
+ }
+
+ return 'Unknown error';
+};
+
+export let amplitudeServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let amplitudeApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) {
+ return error;
+ }
+
+ let response = getErrorResponse(error);
+ let statusLabel =
+ response?.status !== undefined
+ ? `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+ let serviceError = amplitudeServiceError(
+ `Amplitude API ${operation} failed: ${statusLabel}${extractAmplitudeMessage(error)}`
+ );
+
+ serviceError.data.reason = 'amplitude_api_error';
+ serviceError.data.upstreamStatus = response?.status;
+
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+
+ return serviceError;
+};
diff --git a/integrations/amplitude/src/tools.schema.test.ts b/integrations/amplitude/src/tools.schema.test.ts
new file mode 100644
index 0000000000..51c92493f8
--- /dev/null
+++ b/integrations/amplitude/src/tools.schema.test.ts
@@ -0,0 +1,4 @@
+import { describeMcpCompatibleToolSchemas } from '@slates/test';
+import { provider } from './index';
+
+describeMcpCompatibleToolSchemas('Amplitude tool input schemas', provider.actions);
diff --git a/integrations/amplitude/src/tools/delete-user-data.ts b/integrations/amplitude/src/tools/delete-user-data.ts
index 7ad5a335a8..00dd21b24d 100644
--- a/integrations/amplitude/src/tools/delete-user-data.ts
+++ b/integrations/amplitude/src/tools/delete-user-data.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
export let deleteUserDataTool = SlateTool.create(spec, {
@@ -78,6 +79,14 @@ export let deleteUserDataTool = SlateTool.create(spec, {
});
if (ctx.input.action === 'delete') {
+ if (!ctx.input.userId && ctx.input.amplitudeId === undefined) {
+ throw amplitudeServiceError('Provide userId or amplitudeId for "delete" action.');
+ }
+
+ if (ctx.input.userId && ctx.input.amplitudeId !== undefined) {
+ throw amplitudeServiceError('Provide only one of userId or amplitudeId.');
+ }
+
let result = await client.requestUserDeletion({
userId: ctx.input.userId,
amplitudeId: ctx.input.amplitudeId,
@@ -90,7 +99,22 @@ export let deleteUserDataTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'bulk_delete') {
- if (!ctx.input.bulkDelete) throw new Error('bulkDelete parameters are required.');
+ if (!ctx.input.bulkDelete) {
+ throw amplitudeServiceError('bulkDelete parameters are required.');
+ }
+
+ let count =
+ (ctx.input.bulkDelete.userIds?.length ?? 0) +
+ (ctx.input.bulkDelete.amplitudeIds?.length ?? 0);
+ if (count === 0) {
+ throw amplitudeServiceError(
+ 'bulkDelete must include at least one userId or amplitudeId.'
+ );
+ }
+ if (count > 100) {
+ throw amplitudeServiceError('Bulk deletion accepts at most 100 IDs.');
+ }
+
let result = await client.requestBulkUserDeletion({
userIds: ctx.input.bulkDelete.userIds,
amplitudeIds: ctx.input.bulkDelete.amplitudeIds,
@@ -98,9 +122,6 @@ export let deleteUserDataTool = SlateTool.create(spec, {
deleteFromOrg: ctx.input.bulkDelete.deleteFromOrg,
ignoreInvalidId: ctx.input.bulkDelete.ignoreInvalidId
});
- let count =
- (ctx.input.bulkDelete.userIds?.length ?? 0) +
- (ctx.input.bulkDelete.amplitudeIds?.length ?? 0);
return {
output: { deletionResult: result },
message: `Bulk deletion requested for **${count}** user(s).`
@@ -115,6 +136,6 @@ export let deleteUserDataTool = SlateTool.create(spec, {
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw amplitudeServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/amplitude/src/tools/export-events.ts b/integrations/amplitude/src/tools/export-events.ts
new file mode 100644
index 0000000000..4cf84ff059
--- /dev/null
+++ b/integrations/amplitude/src/tools/export-events.ts
@@ -0,0 +1,63 @@
+import { createBase64Attachment, SlateTool } from 'slates';
+import { z } from 'zod';
+import { AmplitudeClient } from '../lib/client';
+import { spec } from '../spec';
+
+export let exportEventsTool = SlateTool.create(spec, {
+ name: 'Export Events',
+ key: 'export_events',
+ description: `Export Amplitude raw event files for an uploaded-time range as a ZIP attachment. Use this for downstream archival, warehouse backfills, or offline inspection of raw JSON event exports.`,
+ constraints: [
+ 'The Export API returns data by server upload time, not event time.',
+ 'Data may take up to two hours to become available.',
+ 'Use whole-day ranges from T00 to T23 when exporting a full day.',
+ 'Each export may be up to 4 GB and date ranges may not exceed 365 days.'
+ ],
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ start: z
+ .string()
+ .regex(/^\d{8}T\d{2}$/)
+ .describe('Start hour in YYYYMMDDTHH format, for example 20260131T00.'),
+ end: z
+ .string()
+ .regex(/^\d{8}T\d{2}$/)
+ .describe('End hour in YYYYMMDDTHH format, for example 20260131T23.')
+ })
+ )
+ .output(
+ z.object({
+ contentType: z.string().describe('MIME type of the exported attachment.'),
+ byteLength: z.number().describe('Size of the exported ZIP attachment in bytes.'),
+ attachmentCount: z.number().describe('Number of attachments returned.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new AmplitudeClient({
+ apiKey: ctx.auth.apiKey,
+ secretKey: ctx.auth.secretKey,
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ let result = await client.exportEvents({
+ start: ctx.input.start,
+ end: ctx.input.end
+ });
+
+ return {
+ output: {
+ contentType: result.contentType,
+ byteLength: result.byteLength,
+ attachmentCount: 1
+ },
+ attachments: [createBase64Attachment(result.contentBase64, result.contentType)],
+ message: `Exported Amplitude events from ${ctx.input.start} to ${ctx.input.end} as a ZIP attachment.`
+ };
+ })
+ .build();
diff --git a/integrations/amplitude/src/tools/get-chart-results.ts b/integrations/amplitude/src/tools/get-chart-results.ts
index d8629edf6f..7a79580ef1 100644
--- a/integrations/amplitude/src/tools/get-chart-results.ts
+++ b/integrations/amplitude/src/tools/get-chart-results.ts
@@ -1,4 +1,4 @@
-import { SlateTool } from 'slates';
+import { createTextAttachment, SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
import { spec } from '../spec';
@@ -6,7 +6,7 @@ import { spec } from '../spec';
export let getChartResultsTool = SlateTool.create(spec, {
name: 'Get Chart Results',
key: 'get_chart_results',
- description: `Fetch results from a saved chart in Amplitude by its chart ID. Returns the same data that the chart displays in the Amplitude dashboard. The chart ID can be found in the URL when viewing a chart.`,
+ description: `Fetch CSV results from a saved chart in Amplitude by its chart ID. The chart ID can be found in the URL when viewing a chart. The CSV content is returned as a Slate attachment.`,
tags: {
destructive: false,
readOnly: true
@@ -21,7 +21,9 @@ export let getChartResultsTool = SlateTool.create(spec, {
)
.output(
z.object({
- chartData: z.any().describe('Full chart data including series, labels, and metadata.')
+ contentType: z.string().describe('MIME type of the exported chart attachment.'),
+ byteLength: z.number().describe('Size of the exported chart CSV in bytes.'),
+ attachmentCount: z.number().describe('Number of attachments returned.')
})
)
.handleInvocation(async ctx => {
@@ -35,8 +37,13 @@ export let getChartResultsTool = SlateTool.create(spec, {
let result = await client.getChartResults(ctx.input.chartId);
return {
- output: { chartData: result.data ?? result },
- message: `Retrieved results for chart **${ctx.input.chartId}**.`
+ output: {
+ contentType: result.contentType,
+ byteLength: result.byteLength,
+ attachmentCount: 1
+ },
+ attachments: [createTextAttachment(result.content, result.contentType)],
+ message: `Retrieved CSV results for chart **${ctx.input.chartId}** as an attachment.`
};
})
.build();
diff --git a/integrations/amplitude/src/tools/get-user-profile.ts b/integrations/amplitude/src/tools/get-user-profile.ts
index 79aaa63902..36f1fac35d 100644
--- a/integrations/amplitude/src/tools/get-user-profile.ts
+++ b/integrations/amplitude/src/tools/get-user-profile.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
export let getUserProfileTool = SlateTool.create(spec, {
@@ -49,6 +50,20 @@ export let getUserProfileTool = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
+ if (ctx.config.region === 'EU') {
+ throw amplitudeServiceError(
+ 'Amplitude User Profile API is not available for EU data region projects.'
+ );
+ }
+
+ if (!ctx.input.userId && ctx.input.amplitudeId === undefined) {
+ throw amplitudeServiceError('Provide either userId or amplitudeId.');
+ }
+
+ if (ctx.input.userId && ctx.input.amplitudeId !== undefined) {
+ throw amplitudeServiceError('Provide only one of userId or amplitudeId.');
+ }
+
let client = new AmplitudeClient({
apiKey: ctx.auth.apiKey,
secretKey: ctx.auth.secretKey,
diff --git a/integrations/amplitude/src/tools/identify-user.ts b/integrations/amplitude/src/tools/identify-user.ts
index 59529d1e9c..0c21291a68 100644
--- a/integrations/amplitude/src/tools/identify-user.ts
+++ b/integrations/amplitude/src/tools/identify-user.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
export let identifyUserTool = SlateTool.create(spec, {
@@ -62,6 +63,28 @@ export let identifyUserTool = SlateTool.create(spec, {
let actions: string[] = [];
+ if (ctx.input.userProperties && !ctx.input.userId && !ctx.input.deviceId) {
+ throw amplitudeServiceError(
+ 'userId or deviceId is required when setting userProperties.'
+ );
+ }
+
+ if (
+ ctx.input.groupType !== undefined ||
+ ctx.input.groupValue !== undefined ||
+ ctx.input.groupProperties !== undefined
+ ) {
+ if (!ctx.input.groupType || !ctx.input.groupValue || !ctx.input.groupProperties) {
+ throw amplitudeServiceError(
+ 'groupType, groupValue, and groupProperties are all required for group identification.'
+ );
+ }
+ }
+
+ if (ctx.input.mapToGlobalUserId && !ctx.input.userId) {
+ throw amplitudeServiceError('userId is required when mapToGlobalUserId is provided.');
+ }
+
if (ctx.input.userProperties && (ctx.input.userId || ctx.input.deviceId)) {
await client.identify({
userId: ctx.input.userId,
@@ -90,6 +113,12 @@ export let identifyUserTool = SlateTool.create(spec, {
actions.push(`user mapped to global ID "${ctx.input.mapToGlobalUserId}"`);
}
+ if (actions.length === 0) {
+ throw amplitudeServiceError(
+ 'Provide userProperties, group identification fields, or mapToGlobalUserId.'
+ );
+ }
+
return {
output: { success: true },
message: `Identification complete: ${actions.join(', ')}.`
diff --git a/integrations/amplitude/src/tools/index.ts b/integrations/amplitude/src/tools/index.ts
index 657dd10050..05faede21a 100644
--- a/integrations/amplitude/src/tools/index.ts
+++ b/integrations/amplitude/src/tools/index.ts
@@ -1,4 +1,5 @@
export * from './delete-user-data';
+export * from './export-events';
export * from './get-chart-results';
export * from './get-user-profile';
export * from './identify-user';
diff --git a/integrations/amplitude/src/tools/manage-annotations.ts b/integrations/amplitude/src/tools/manage-annotations.ts
index 60f23144d3..105fbcc318 100644
--- a/integrations/amplitude/src/tools/manage-annotations.ts
+++ b/integrations/amplitude/src/tools/manage-annotations.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
export let manageAnnotationsTool = SlateTool.create(spec, {
@@ -29,8 +30,20 @@ export let manageAnnotationsTool = SlateTool.create(spec, {
.string()
.optional()
.describe(
- 'Date for the annotation in MM-DD-YYYY format. Required for "create", optional for "update".'
+ 'Deprecated legacy date field. Prefer start. Used as start when start is omitted.'
),
+ start: z
+ .string()
+ .optional()
+ .describe(
+ 'Annotation start time in ISO 8601 format. Required for "create", optional for "update".'
+ ),
+ end: z.string().optional().describe('Optional annotation end time in ISO 8601 format.'),
+ category: z.string().optional().describe('Optional annotation category.'),
+ chartId: z
+ .string()
+ .optional()
+ .describe('Optional Amplitude chart ID to associate with the annotation.'),
details: z
.string()
.optional()
@@ -44,7 +57,10 @@ export let manageAnnotationsTool = SlateTool.create(spec, {
z.object({
annotationId: z.string().optional(),
label: z.string().optional(),
- date: z.string().optional(),
+ start: z.string().optional(),
+ end: z.string().optional(),
+ category: z.string().optional(),
+ chartId: z.string().optional(),
details: z.string().optional()
})
)
@@ -68,14 +84,26 @@ export let manageAnnotationsTool = SlateTool.create(spec, {
region: ctx.config.region
});
+ let normalizeAnnotation = (annotation: any) => ({
+ annotationId: annotation.id !== undefined ? String(annotation.id) : undefined,
+ label: annotation.label,
+ start: annotation.start ?? annotation.date,
+ end: annotation.end,
+ category: annotation.category,
+ chartId: annotation.chart_id !== undefined ? String(annotation.chart_id) : undefined,
+ details: annotation.details
+ });
+
if (ctx.input.action === 'list') {
let result = await client.listAnnotations();
- let annotations = (result.data ?? result ?? []).map((a: any) => ({
- annotationId: String(a.id),
- label: a.label,
- date: a.date,
- details: a.details
- }));
+ let rawAnnotations = Array.isArray(result.data)
+ ? result.data
+ : Array.isArray(result.annotations)
+ ? result.annotations
+ : Array.isArray(result)
+ ? result
+ : [];
+ let annotations = rawAnnotations.map(normalizeAnnotation);
return {
output: { annotations },
message: `Found **${annotations.length}** annotation(s).`
@@ -83,8 +111,9 @@ export let manageAnnotationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.annotationId)
- throw new Error('annotationId is required for "get" action.');
+ if (!ctx.input.annotationId) {
+ throw amplitudeServiceError('annotationId is required for "get" action.');
+ }
let result = await client.getAnnotation(ctx.input.annotationId);
return {
output: { annotation: result.data ?? result },
@@ -93,26 +122,35 @@ export let manageAnnotationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.label || !ctx.input.date)
- throw new Error('label and date are required for "create" action.');
+ let start = ctx.input.start ?? ctx.input.date;
+ if (!ctx.input.label || !start) {
+ throw amplitudeServiceError('label and start are required for "create" action.');
+ }
let result = await client.createAnnotation({
label: ctx.input.label,
- date: ctx.input.date,
- details: ctx.input.details
+ start,
+ details: ctx.input.details,
+ end: ctx.input.end,
+ category: ctx.input.category,
+ chartId: ctx.input.chartId
});
return {
output: { annotation: result.data ?? result },
- message: `Created annotation "${ctx.input.label}" on ${ctx.input.date}.`
+ message: `Created annotation "${ctx.input.label}" starting ${start}.`
};
}
if (ctx.input.action === 'update') {
- if (!ctx.input.annotationId)
- throw new Error('annotationId is required for "update" action.');
+ if (!ctx.input.annotationId) {
+ throw amplitudeServiceError('annotationId is required for "update" action.');
+ }
let result = await client.updateAnnotation(ctx.input.annotationId, {
label: ctx.input.label,
- date: ctx.input.date,
- details: ctx.input.details
+ start: ctx.input.start ?? ctx.input.date,
+ details: ctx.input.details,
+ end: ctx.input.end,
+ category: ctx.input.category,
+ chartId: ctx.input.chartId
});
return {
output: { annotation: result.data ?? result },
@@ -121,8 +159,9 @@ export let manageAnnotationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.annotationId)
- throw new Error('annotationId is required for "delete" action.');
+ if (!ctx.input.annotationId) {
+ throw amplitudeServiceError('annotationId is required for "delete" action.');
+ }
await client.deleteAnnotation(ctx.input.annotationId);
return {
output: { success: true },
@@ -130,6 +169,6 @@ export let manageAnnotationsTool = SlateTool.create(spec, {
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw amplitudeServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/amplitude/src/tools/manage-cohorts.ts b/integrations/amplitude/src/tools/manage-cohorts.ts
index 3712a61fde..eb73f65023 100644
--- a/integrations/amplitude/src/tools/manage-cohorts.ts
+++ b/integrations/amplitude/src/tools/manage-cohorts.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
export let manageCohortsTool = SlateTool.create(spec, {
@@ -19,25 +20,69 @@ export let manageCohortsTool = SlateTool.create(spec, {
.input(
z.object({
action: z
- .enum(['list', 'get', 'upload'])
+ .enum(['list', 'get', 'upload', 'get_usage', 'update_membership'])
.describe(
- 'Action to perform: "list" all cohorts, "get" a specific cohort, or "upload" a new/updated cohort.'
+ 'Action to perform: "list" cohorts, "get" one cohort, "get_usage" for download quota, "upload" a static cohort, or "update_membership" incrementally.'
),
- cohortId: z.string().optional().describe('Cohort ID for "get" action.'),
+ cohortId: z
+ .string()
+ .optional()
+ .describe('Cohort ID for "get" and "update_membership" actions.'),
upload: z
.object({
name: z.string().describe('Name for the cohort.'),
appId: z.number().describe('Amplitude project/app ID.'),
idType: z.enum(['BY_AMP_ID', 'BY_USER_ID']).describe('Type of IDs being uploaded.'),
- ids: z.array(z.string()).describe('Array of user IDs or Amplitude IDs.'),
- owner: z.string().optional().describe('Email of the cohort owner.'),
+ ids: z.array(z.string()).min(1).describe('Array of user IDs or Amplitude IDs.'),
+ owner: z.string().optional().describe('Required email of the cohort owner.'),
+ published: z
+ .boolean()
+ .optional()
+ .describe('Required by Amplitude. Whether the cohort is discoverable.'),
+ skipSave: z
+ .boolean()
+ .optional()
+ .describe('Validate the upload without saving a cohort.'),
+ skipInvalidIds: z
+ .boolean()
+ .optional()
+ .describe('Skip invalid IDs and upload the remaining valid IDs.'),
+ countGroup: z
+ .string()
+ .optional()
+ .describe('Optional group name for group cohorts, sent as cg.'),
existingCohortId: z
.string()
.optional()
.describe('ID of existing cohort to update instead of creating new.')
})
.optional()
- .describe('Upload parameters. Required for "upload" action.')
+ .describe('Upload parameters. Required for "upload" action.'),
+ membership: z
+ .object({
+ memberships: z
+ .array(
+ z.object({
+ ids: z.array(z.string()).min(1).describe('IDs to add or remove.'),
+ idType: z
+ .enum(['BY_ID', 'BY_NAME'])
+ .describe('BY_ID is Amplitude ID/group ID; BY_NAME is user ID/group name.'),
+ operation: z.enum(['ADD', 'REMOVE']).describe('Membership operation.')
+ })
+ )
+ .min(1)
+ .describe('Membership operations to apply.'),
+ countGroup: z
+ .string()
+ .optional()
+ .describe('Count group for the given IDs. Defaults to User in Amplitude.'),
+ skipInvalidIds: z
+ .boolean()
+ .optional()
+ .describe('Skip invalid IDs instead of rejecting the full update.')
+ })
+ .optional()
+ .describe('Membership update parameters. Required for "update_membership" action.')
})
)
.output(
@@ -56,7 +101,12 @@ export let manageCohortsTool = SlateTool.create(spec, {
.optional()
.describe('List of cohorts (for "list" action).'),
cohort: z.any().optional().describe('Cohort details (for "get" action).'),
- uploadResult: z.any().optional().describe('Upload result (for "upload" action).')
+ usage: z.any().optional().describe('Cohort download quota usage.'),
+ uploadResult: z.any().optional().describe('Upload result (for "upload" action).'),
+ membershipResult: z
+ .any()
+ .optional()
+ .describe('Membership update result (for "update_membership" action).')
})
)
.handleInvocation(async ctx => {
@@ -85,7 +135,9 @@ export let manageCohortsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.cohortId) throw new Error('cohortId is required for "get" action.');
+ if (!ctx.input.cohortId) {
+ throw amplitudeServiceError('cohortId is required for "get" action.');
+ }
let result = await client.getCohort(ctx.input.cohortId);
return {
output: { cohort: result },
@@ -93,16 +145,52 @@ export let manageCohortsTool = SlateTool.create(spec, {
};
}
+ if (ctx.input.action === 'get_usage') {
+ let result = await client.getCohortUsage();
+ return {
+ output: { usage: result },
+ message: 'Retrieved Behavioral Cohorts Download API usage.'
+ };
+ }
+
if (ctx.input.action === 'upload') {
- if (!ctx.input.upload)
- throw new Error('upload parameters are required for "upload" action.');
+ if (!ctx.input.upload) {
+ throw amplitudeServiceError('upload parameters are required for "upload" action.');
+ }
+ if (!ctx.input.upload.owner) {
+ throw amplitudeServiceError('upload.owner is required by Amplitude.');
+ }
+ if (ctx.input.upload.published === undefined) {
+ throw amplitudeServiceError('upload.published is required by Amplitude.');
+ }
let result = await client.uploadCohort(ctx.input.upload);
return {
output: { uploadResult: result },
- message: `${ctx.input.upload.existingCohortId ? 'Updated' : 'Created'} cohort "${ctx.input.upload.name}" with **${ctx.input.upload.ids.length}** users.`
+ message: `${ctx.input.upload.skipSave ? 'Validated' : ctx.input.upload.existingCohortId ? 'Updated' : 'Created'} cohort "${ctx.input.upload.name}" with **${ctx.input.upload.ids.length}** users.`
+ };
+ }
+
+ if (ctx.input.action === 'update_membership') {
+ if (!ctx.input.cohortId) {
+ throw amplitudeServiceError('cohortId is required for "update_membership" action.');
+ }
+ if (!ctx.input.membership) {
+ throw amplitudeServiceError(
+ 'membership parameters are required for "update_membership" action.'
+ );
+ }
+ let result = await client.updateCohortMembership({
+ cohortId: ctx.input.cohortId,
+ memberships: ctx.input.membership.memberships,
+ countGroup: ctx.input.membership.countGroup,
+ skipInvalidIds: ctx.input.membership.skipInvalidIds
+ });
+ return {
+ output: { membershipResult: result },
+ message: `Updated membership for cohort **${ctx.input.cohortId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw amplitudeServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/amplitude/src/tools/manage-taxonomy.ts b/integrations/amplitude/src/tools/manage-taxonomy.ts
index 9ddf37b7a8..3601400b52 100644
--- a/integrations/amplitude/src/tools/manage-taxonomy.ts
+++ b/integrations/amplitude/src/tools/manage-taxonomy.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
export let manageTaxonomyTool = SlateTool.create(spec, {
@@ -111,7 +112,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
};
}
if (action === 'get') {
- if (!ctx.input.eventType) throw new Error('eventType is required.');
+ if (!ctx.input.eventType) throw amplitudeServiceError('eventType is required.');
let result = await client.getEventType(ctx.input.eventType);
return {
output: { item: result.data ?? result },
@@ -119,7 +120,9 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
};
}
if (action === 'create') {
- if (!ctx.input.create) throw new Error('create parameters are required.');
+ if (!ctx.input.create) {
+ throw amplitudeServiceError('create parameters are required.');
+ }
let result = await client.createEventType({
eventType: ctx.input.create.name,
category: ctx.input.create.category,
@@ -132,7 +135,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
}
if (action === 'update') {
if (!ctx.input.eventType || !ctx.input.update)
- throw new Error('eventType and update parameters are required.');
+ throw amplitudeServiceError('eventType and update parameters are required.');
let result = await client.updateEventType(ctx.input.eventType, {
newEventType: ctx.input.update.newName,
category: ctx.input.update.category,
@@ -144,7 +147,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
};
}
if (action === 'delete') {
- if (!ctx.input.eventType) throw new Error('eventType is required.');
+ if (!ctx.input.eventType) throw amplitudeServiceError('eventType is required.');
let result = await client.deleteEventType(ctx.input.eventType);
return {
output: { result: result.data ?? result },
@@ -157,7 +160,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
if (resourceType === 'event_property') {
if (action === 'list') {
if (!ctx.input.eventType)
- throw new Error('eventType is required to list event properties.');
+ throw amplitudeServiceError('eventType is required to list event properties.');
let result = await client.getEventProperties(ctx.input.eventType);
return {
output: { items: result.data ?? result },
@@ -166,7 +169,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
}
if (action === 'create') {
if (!ctx.input.create || !ctx.input.eventType)
- throw new Error('create parameters and eventType are required.');
+ throw amplitudeServiceError('create parameters and eventType are required.');
let result = await client.createEventProperty({
eventType: ctx.input.eventType,
eventProperty: ctx.input.create.name,
@@ -184,7 +187,9 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
}
if (action === 'update') {
if (!ctx.input.eventProperty || !ctx.input.eventType || !ctx.input.update)
- throw new Error('eventProperty, eventType, and update parameters are required.');
+ throw amplitudeServiceError(
+ 'eventProperty, eventType, and update parameters are required.'
+ );
let result = await client.updateEventProperty(
ctx.input.eventProperty,
ctx.input.eventType,
@@ -205,7 +210,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
}
if (action === 'delete') {
if (!ctx.input.eventProperty || !ctx.input.eventType)
- throw new Error('eventProperty and eventType are required.');
+ throw amplitudeServiceError('eventProperty and eventType are required.');
let result = await client.deleteEventProperty(
ctx.input.eventProperty,
ctx.input.eventType
@@ -227,7 +232,9 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
};
}
if (action === 'create') {
- if (!ctx.input.create) throw new Error('create parameters are required.');
+ if (!ctx.input.create) {
+ throw amplitudeServiceError('create parameters are required.');
+ }
let result = await client.createUserProperty({
userProperty: ctx.input.create.name,
description: ctx.input.create.description,
@@ -243,7 +250,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
}
if (action === 'update') {
if (!ctx.input.userProperty || !ctx.input.update)
- throw new Error('userProperty and update parameters are required.');
+ throw amplitudeServiceError('userProperty and update parameters are required.');
let result = await client.updateUserProperty(ctx.input.userProperty, {
newUserPropertyValue: ctx.input.update.newName,
description: ctx.input.update.description,
@@ -258,7 +265,9 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
};
}
if (action === 'delete') {
- if (!ctx.input.userProperty) throw new Error('userProperty is required.');
+ if (!ctx.input.userProperty) {
+ throw amplitudeServiceError('userProperty is required.');
+ }
let result = await client.deleteUserProperty(ctx.input.userProperty);
return {
output: { result: result.data ?? result },
@@ -277,7 +286,9 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
};
}
if (action === 'create') {
- if (!ctx.input.create) throw new Error('create parameters are required.');
+ if (!ctx.input.create) {
+ throw amplitudeServiceError('create parameters are required.');
+ }
let result = await client.createEventCategory({ name: ctx.input.create.name });
return {
output: { result: result.data ?? result },
@@ -285,7 +296,7 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
};
}
if (action === 'delete') {
- if (!ctx.input.categoryId) throw new Error('categoryId is required.');
+ if (!ctx.input.categoryId) throw amplitudeServiceError('categoryId is required.');
let result = await client.deleteEventCategory(ctx.input.categoryId);
return {
output: { result: result.data ?? result },
@@ -294,6 +305,8 @@ export let manageTaxonomyTool = SlateTool.create(spec, {
}
}
- throw new Error(`Unsupported action "${action}" for resource type "${resourceType}".`);
+ throw amplitudeServiceError(
+ `Unsupported action "${action}" for resource type "${resourceType}".`
+ );
})
.build();
diff --git a/integrations/amplitude/src/tools/query-funnel.ts b/integrations/amplitude/src/tools/query-funnel.ts
index 188ecd4417..00901aa93b 100644
--- a/integrations/amplitude/src/tools/query-funnel.ts
+++ b/integrations/amplitude/src/tools/query-funnel.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
export let queryFunnelTool = SlateTool.create(spec, {
@@ -58,6 +59,23 @@ export let queryFunnelTool = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
+ let parsedEvents: unknown;
+ try {
+ parsedEvents = JSON.parse(ctx.input.events);
+ } catch (error) {
+ let serviceError = amplitudeServiceError(
+ 'events must be a JSON-encoded array of event objects.'
+ );
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+ throw serviceError;
+ }
+
+ if (!Array.isArray(parsedEvents)) {
+ throw amplitudeServiceError('events must be a JSON-encoded array of event objects.');
+ }
+
let client = new AmplitudeClient({
apiKey: ctx.auth.apiKey,
secretKey: ctx.auth.secretKey,
@@ -83,7 +101,7 @@ export let queryFunnelTool = SlateTool.create(spec, {
events: data.events,
funnelData: data
},
- message: `Funnel analysis completed for **${ctx.input.start}** to **${ctx.input.end}** with ${JSON.parse(ctx.input.events).length} steps.`
+ message: `Funnel analysis completed for **${ctx.input.start}** to **${ctx.input.end}** with ${parsedEvents.length} steps.`
};
})
.build();
diff --git a/integrations/amplitude/src/tools/track-events.ts b/integrations/amplitude/src/tools/track-events.ts
index a5944c244b..08d8f0cf98 100644
--- a/integrations/amplitude/src/tools/track-events.ts
+++ b/integrations/amplitude/src/tools/track-events.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { AmplitudeClient } from '../lib/client';
+import { amplitudeServiceError } from '../lib/errors';
import { spec } from '../spec';
let eventSchema = z.object({
@@ -110,6 +111,18 @@ export let trackEventsTool = SlateTool.create(spec, {
})
)
.handleInvocation(async ctx => {
+ if (ctx.input.events.length > 2000) {
+ throw amplitudeServiceError('Amplitude accepts at most 2000 events per request.');
+ }
+
+ for (let [index, event] of ctx.input.events.entries()) {
+ if (!event.userId && !event.deviceId) {
+ throw amplitudeServiceError(
+ `Event at index ${index} must include at least one of userId or deviceId.`
+ );
+ }
+ }
+
let client = new AmplitudeClient({
apiKey: ctx.auth.apiKey,
secretKey: ctx.auth.secretKey,
diff --git a/integrations/amplitude/vitest.config.ts b/integrations/amplitude/vitest.config.ts
new file mode 100644
index 0000000000..0b05bc07ad
--- /dev/null
+++ b/integrations/amplitude/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['src/**/*.test.ts']
+ }
+});
diff --git a/integrations/api2pdf/README.md b/integrations/api2pdf/README.md
index e80dfe2f35..792fe48524 100644
--- a/integrations/api2pdf/README.md
+++ b/integrations/api2pdf/README.md
@@ -1,6 +1,6 @@
#
API 2 Pdf
-Generate PDFs from HTML, URLs, and Markdown. Convert Microsoft Office documents, images, and email files to PDF. Capture screenshots of websites and HTML content. Merge multiple PDFs, extract specific page ranges, and reorder pages. Password-protect PDFs for secure delivery. Generate barcodes and QR codes. Create thumbnail previews for PDFs, Office documents, and email files. Extract structured data from PDFs. Convert HTML to Word (DOCX) and Excel (XLSX). Compress files into ZIP archives. Delete generated files on demand.
+Generate PDFs from HTML, URLs, and Markdown. Convert Microsoft Office documents, images, and email files to PDF. Capture screenshots of websites and HTML content. Merge multiple PDFs, extract specific page ranges, and reorder pages. Password-protect PDFs for secure delivery. Generate barcodes and QR codes. Create thumbnail previews for PDFs, Office documents, and email files. Extract structured data from PDFs. Convert HTML to Word (DOCX) and Excel (XLSX). Compress files into ZIP archives. Generated files are returned as Slate attachments with metadata, and generated API2PDF files can be deleted on demand.
## License
diff --git a/integrations/api2pdf/docs/SPEC.md b/integrations/api2pdf/docs/SPEC.md
index 738573bac9..56f9441a14 100644
--- a/integrations/api2pdf/docs/SPEC.md
+++ b/integrations/api2pdf/docs/SPEC.md
@@ -2,7 +2,7 @@
## Overview
-API2PDF is a REST API for PDF generation, document conversion, and file transformation. It supports HTML to PDF, URL to PDF, HTML to image, URL to image, Microsoft Office document conversion, email and image file conversion, PDF page extraction, PDF password protection, file zipping, barcode and QR code generation, markdown conversion, structured PDF data extraction, and image previews or thumbnails for PDF, office, and email files. It is built on engines including wkhtmltopdf, Headless Chrome, PdfSharp, LibreOffice, and related tools.
+API2PDF is a REST API for PDF generation, document conversion, and file transformation. It supports HTML to PDF, URL to PDF, HTML to image, URL to image, Microsoft Office document conversion, email and image file conversion, PDF page extraction, PDF password protection, file zipping, barcode and QR code generation, markdown conversion, structured PDF data extraction, and image previews or thumbnails for PDF, office, and email files. It is built on engines including Headless Chrome, PdfSharp, LibreOffice, wkhtmltopdf, and related tools.
## Authentication
@@ -22,15 +22,15 @@ The base URL for the API is `https://v2.api2pdf.com`. An XL cluster is also avai
### PDF Generation from HTML and URLs
-Convert raw HTML or a publicly accessible URL into a PDF document. Supports Markdown, HTML, and URLs to PDF using Headless Chrome. Also available via the wkhtmltopdf engine as an alternative renderer. Configurable options include landscape orientation, custom headers/footers, page size, margins, and extra HTTP headers for authenticated source URLs.
+Convert raw HTML, Markdown, or a publicly accessible URL into a PDF document using Headless Chrome. Configurable options include landscape orientation, custom headers/footers, page size, margins, tagged PDFs, outlines, print CSS, and extra HTTP headers for authenticated source URLs. The official API still exposes wkhtmltopdf endpoints, but recommends Chrome for new usage, so this integration keeps Chrome as the practical PDF generation surface.
### Screenshot / Image Capture
-Capture a website, URL, or raw HTML as a screenshot when PDF is not the deliverable. Uses Headless Chrome for rendering.
+Capture a website, URL, raw HTML, or Markdown as a screenshot when PDF is not the deliverable. Uses Headless Chrome for rendering and supports viewport and Puppeteer wait options.
### Office Document Conversion
-Convert Word, PowerPoint, Excel, and images into PDF with LibreOffice. Also supports converting HTML to Word (DOCX), HTML to Excel (XLSX), and PDF to HTML. Any file format that LibreOffice can open is supported as input.
+Convert Word, PowerPoint, Excel, images, and other LibreOffice-supported files into PDF. Also supports converting HTML or a URL to Word (DOCX), and HTML or a URL to Excel (XLSX).
### PDF Merging
@@ -64,9 +64,13 @@ Extract structured data from existing PDF documents for automated content proces
Compress multiple files into a single ZIP archive.
+### API Status and Balance
+
+Check the current API2PDF service status and the remaining account balance for the authenticated API key.
+
### File Management
-By default, API2PDF will delete your generated file 24 hours after it has been generated. For those with high security needs, you can delete your file on command using the responseId returned from the original request.
+Generated files are returned as Slate attachments with metadata including response ID, source file URL, MIME type, byte length, API-reported file size, cost, and processing time. By default, API2PDF deletes generated files 24 hours after they have been generated. For high-security use cases, delete a generated file immediately using the responseId returned from the original request.
## Events
diff --git a/integrations/api2pdf/package.json b/integrations/api2pdf/package.json
index 5cbf9c0489..a4b3dbc87a 100644
--- a/integrations/api2pdf/package.json
+++ b/integrations/api2pdf/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --config vitest.config.ts --dir . --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
- "typescript": "^5"
+ "@slates/test": "1.0.0-rc.9",
+ "typescript": "^5",
+ "vitest": "^3.1.2"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.7"
}
diff --git a/integrations/api2pdf/src/index.ts b/integrations/api2pdf/src/index.ts
index 0f745aa39d..3ff2e20d36 100644
--- a/integrations/api2pdf/src/index.ts
+++ b/integrations/api2pdf/src/index.ts
@@ -3,6 +3,7 @@ import { spec } from './spec';
import {
captureScreenshot,
checkBalance,
+ checkStatus,
convertDocument,
convertToMarkdown,
createZip,
@@ -35,7 +36,8 @@ export let provider = Slate.create({
createZip,
convertToMarkdown,
deleteFile,
- checkBalance
+ checkBalance,
+ checkStatus
],
triggers: [inboundWebhook]
});
diff --git a/integrations/api2pdf/src/lib/client.ts b/integrations/api2pdf/src/lib/client.ts
index 326d0017af..31c1e38adb 100644
--- a/integrations/api2pdf/src/lib/client.ts
+++ b/integrations/api2pdf/src/lib/client.ts
@@ -1,8 +1,13 @@
import { createAxios } from 'slates';
+import { api2PdfApiError, api2PdfServiceError } from './errors';
import type {
AnyToPdfParams,
+ Api2PdfFileAttachment,
Api2PdfResponse,
BarcodeParams,
+ BaseRequestParams,
+ ChromeImageOptions,
+ ChromePdfOptions,
DataLoaderParams,
ExtractPagesParams,
HtmlToDocxParams,
@@ -23,6 +28,110 @@ import type {
ZipParams
} from './types';
+type Api2PdfRawResponse = Partial & {
+ ResponseId?: string;
+ Success?: boolean;
+ FileUrl?: string;
+ MbOut?: number;
+ Cost?: number;
+ Seconds?: number;
+ Error?: string;
+};
+
+let cleanObject = >(input: T) =>
+ Object.fromEntries(
+ Object.entries(input).filter(([, value]) => value !== undefined)
+ ) as Partial;
+
+let mapStorage = (storage: BaseRequestParams['storage']) => {
+ if (!storage) return undefined;
+
+ return cleanObject({
+ Method: storage.method,
+ Url: storage.url,
+ ExtraHTTPHeaders: storage.extraHTTPHeaders
+ });
+};
+
+let mapBaseRequest = (params: BaseRequestParams) =>
+ cleanObject({
+ FileName: params.fileName,
+ Inline: params.inline,
+ UseCustomStorage: params.useCustomStorage,
+ Storage: mapStorage(params.storage)
+ });
+
+let mapChromePdfOptions = (options?: ChromePdfOptions) => {
+ if (!options) return undefined;
+
+ return cleanObject({
+ Delay: options.delay,
+ Scale: options.scale,
+ DisplayHeaderFooter: options.displayHeaderFooter,
+ HeaderTemplate: options.headerTemplate,
+ FooterTemplate: options.footerTemplate,
+ PrintBackground: options.printBackground,
+ Landscape: options.landscape,
+ PageRanges: options.pageRanges,
+ Width: options.width,
+ Height: options.height,
+ MarginTop: options.marginTop,
+ MarginBottom: options.marginBottom,
+ MarginLeft: options.marginLeft,
+ MarginRight: options.marginRight,
+ PreferCSSPageSize: options.preferCSSPageSize,
+ OmitBackground: options.omitBackground,
+ Tagged: options.tagged,
+ Outline: options.outline,
+ UsePrintCss: options.usePrintCss,
+ PuppeteerWaitForMethod: options.puppeteerWaitForMethod,
+ PuppeteerWaitForValue: options.puppeteerWaitForValue
+ });
+};
+
+let mapChromeImageOptions = (options?: ChromeImageOptions) => {
+ if (!options) return undefined;
+
+ return cleanObject({
+ Delay: options.delay,
+ FullPage: options.fullPage,
+ ViewPortOptions: options.viewPortOptions
+ ? cleanObject({
+ Width: options.viewPortOptions.width,
+ Height: options.viewPortOptions.height,
+ IsMobile: options.viewPortOptions.isMobile,
+ DeviceScaleFactor: options.viewPortOptions.deviceScaleFactor,
+ IsLandscape: options.viewPortOptions.isLandscape,
+ HasTouch: options.viewPortOptions.hasTouch
+ })
+ : undefined,
+ PuppeteerWaitForMethod: options.puppeteerWaitForMethod,
+ PuppeteerWaitForValue: options.puppeteerWaitForValue
+ });
+};
+
+let stringValue = (value: unknown) =>
+ typeof value === 'string'
+ ? value
+ : value === undefined || value === null
+ ? ''
+ : String(value);
+
+let numberValue = (value: unknown) => {
+ let parsed = typeof value === 'number' ? value : Number(value ?? 0);
+ return Number.isFinite(parsed) ? parsed : 0;
+};
+
+let normalizeApi2PdfResponse = (data: Api2PdfRawResponse): Api2PdfResponse => ({
+ responseId: stringValue(data.responseId ?? data.ResponseId),
+ success: data.success ?? data.Success ?? false,
+ fileUrl: stringValue(data.fileUrl ?? data.FileUrl),
+ mbOut: numberValue(data.mbOut ?? data.MbOut),
+ cost: numberValue(data.cost ?? data.Cost),
+ seconds: numberValue(data.seconds ?? data.Seconds),
+ error: data.error ?? data.Error
+});
+
export class Api2PdfClient {
private axios: ReturnType;
@@ -38,158 +147,402 @@ export class Api2PdfClient {
});
}
+ private async postFile(
+ path: string,
+ params: Record,
+ operation: string
+ ): Promise {
+ try {
+ let res = await this.axios.post(path, cleanObject(params));
+ return normalizeApi2PdfResponse(res.data);
+ } catch (error) {
+ throw api2PdfApiError(error, operation);
+ }
+ }
+
+ private async getFile(
+ path: string,
+ params: Record,
+ operation: string
+ ): Promise {
+ try {
+ let res = await this.axios.get(path, {
+ params: cleanObject(params)
+ });
+ return normalizeApi2PdfResponse(res.data);
+ } catch (error) {
+ throw api2PdfApiError(error, operation);
+ }
+ }
+
// --- Chrome PDF Endpoints ---
async chromeHtmlToPdf(params: HtmlToPdfParams): Promise {
- let res = await this.axios.post('/chrome/pdf/html', params);
- return res.data;
+ return await this.postFile(
+ '/chrome/pdf/html',
+ {
+ ...mapBaseRequest(params),
+ Html: params.html,
+ Options: mapChromePdfOptions(params.options)
+ },
+ 'Chrome HTML to PDF'
+ );
}
async chromeUrlToPdf(params: UrlToPdfParams): Promise {
- let res = await this.axios.post('/chrome/pdf/url', params);
- return res.data;
+ return await this.postFile(
+ '/chrome/pdf/url',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ Options: mapChromePdfOptions(params.options),
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'Chrome URL to PDF'
+ );
}
async chromeMarkdownToPdf(params: MarkdownToPdfParams): Promise {
- let res = await this.axios.post('/chrome/pdf/markdown', params);
- return res.data;
+ return await this.postFile(
+ '/chrome/pdf/markdown',
+ {
+ ...mapBaseRequest(params),
+ Markdown: params.markdown,
+ Options: mapChromePdfOptions(params.options)
+ },
+ 'Chrome Markdown to PDF'
+ );
}
// --- Chrome Image Endpoints ---
async chromeHtmlToImage(params: HtmlToImageParams): Promise {
- let res = await this.axios.post('/chrome/image/html', params);
- return res.data;
+ return await this.postFile(
+ '/chrome/image/html',
+ {
+ ...mapBaseRequest(params),
+ Html: params.html,
+ Options: mapChromeImageOptions(params.options)
+ },
+ 'Chrome HTML to image'
+ );
}
async chromeUrlToImage(params: UrlToImageParams): Promise {
- let res = await this.axios.post('/chrome/image/url', params);
- return res.data;
+ return await this.postFile(
+ '/chrome/image/url',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ Options: mapChromeImageOptions(params.options),
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'Chrome URL to image'
+ );
}
async chromeMarkdownToImage(params: MarkdownToImageParams): Promise {
- let res = await this.axios.post('/chrome/image/markdown', params);
- return res.data;
+ return await this.postFile(
+ '/chrome/image/markdown',
+ {
+ ...mapBaseRequest(params),
+ Markdown: params.markdown,
+ Options: mapChromeImageOptions(params.options)
+ },
+ 'Chrome Markdown to image'
+ );
}
// --- LibreOffice Endpoints ---
async libreOfficeAnyToPdf(params: AnyToPdfParams): Promise {
- let res = await this.axios.post('/libreoffice/any-to-pdf', params);
- return res.data;
+ return await this.postFile(
+ '/libreoffice/any-to-pdf',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'LibreOffice file to PDF'
+ );
}
async libreOfficeThumbnail(params: ThumbnailParams): Promise {
- let res = await this.axios.post('/libreoffice/thumbnail', params);
- return res.data;
+ return await this.postFile(
+ '/libreoffice/thumbnail',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'LibreOffice thumbnail'
+ );
}
async libreOfficeHtmlToDocx(params: HtmlToDocxParams): Promise {
- let res = await this.axios.post('/libreoffice/html-to-docx', params);
- return res.data;
+ return await this.postFile(
+ '/libreoffice/html-to-docx',
+ {
+ ...mapBaseRequest(params),
+ Html: params.html,
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'LibreOffice HTML to DOCX'
+ );
}
async libreOfficeHtmlToXlsx(params: HtmlToXlsxParams): Promise {
- let res = await this.axios.post('/libreoffice/html-to-xlsx', params);
- return res.data;
+ return await this.postFile(
+ '/libreoffice/html-to-xlsx',
+ {
+ ...mapBaseRequest(params),
+ Html: params.html,
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'LibreOffice HTML to XLSX'
+ );
}
// --- PdfSharp Endpoints ---
async pdfSharpMerge(params: MergePdfsParams): Promise {
- let res = await this.axios.post('/pdfsharp/merge', params);
- return res.data;
+ return await this.postFile(
+ '/pdfsharp/merge',
+ {
+ ...mapBaseRequest(params),
+ Urls: params.urls,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'PdfSharp merge'
+ );
}
async pdfSharpPassword(params: PasswordPdfParams): Promise {
- let res = await this.axios.post('/pdfsharp/password', params);
- return res.data;
+ return await this.postFile(
+ '/pdfsharp/password',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ UserPassword: params.userpassword,
+ OwnerPassword: params.ownerpassword,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'PdfSharp password'
+ );
}
async pdfSharpExtractPages(params: ExtractPagesParams): Promise {
- let res = await this.axios.post('/pdfsharp/extract-pages', params);
- return res.data;
+ return await this.postFile(
+ '/pdfsharp/extract-pages',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ Start: params.start,
+ End: params.end,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'PdfSharp extract pages'
+ );
}
async pdfSharpWatermark(params: WatermarkPdfParams): Promise {
- let res = await this.axios.post('/pdfsharp/watermark', params);
- return res.data;
+ return await this.postFile(
+ '/pdfsharp/watermark',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ Text: params.text,
+ FontSize: params.fontSize,
+ Color: params.color,
+ Opacity: params.opacity,
+ Rotation: params.rotation,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'PdfSharp watermark'
+ );
}
// --- Barcode Endpoint ---
async generateBarcode(params: BarcodeParams): Promise {
- let res = await this.axios.get('/zebra', {
- params: {
+ return await this.getFile(
+ '/zebra',
+ {
format: params.format,
value: params.value,
- ...(params.width !== undefined && { width: params.width }),
- ...(params.height !== undefined && { height: params.height }),
- ...(params.showlabel !== undefined && { showlabel: params.showlabel }),
+ width: params.width,
+ height: params.height,
+ showlabel: params.showlabel,
outputBinary: false
- }
- });
- return res.data;
+ },
+ 'barcode generation'
+ );
}
// --- Zip Endpoint ---
async createZip(params: ZipParams): Promise {
- let res = await this.axios.post('/zip', params, {
- params: { outputBinary: false }
- });
- return res.data;
+ return await this.postFile(
+ '/zip',
+ {
+ ...mapBaseRequest(params),
+ Files: params.files.map(file =>
+ cleanObject({
+ Url: file.url,
+ FileName: file.fileName
+ })
+ ),
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'ZIP archive creation'
+ );
}
// --- Markitdown Endpoint ---
async convertToMarkdown(params: MarkitdownParams): Promise {
- let res = await this.axios.post('/markitdown', params);
- return res.data;
+ return await this.postFile(
+ '/markitdown',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'MarkItDown conversion'
+ );
}
// --- OpenDataLoader Endpoints ---
async extractJsonFromPdf(params: DataLoaderParams): Promise {
- let res = await this.axios.post('/opendataloader/json', params);
- return res.data;
+ return await this.postFile(
+ '/opendataloader/json',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'OpenDataLoader JSON extraction'
+ );
}
async extractMarkdownFromPdf(params: DataLoaderParams): Promise {
- let res = await this.axios.post('/opendataloader/markdown', params);
- return res.data;
+ return await this.postFile(
+ '/opendataloader/markdown',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'OpenDataLoader Markdown extraction'
+ );
}
async extractHtmlFromPdf(params: DataLoaderParams): Promise {
- let res = await this.axios.post('/opendataloader/html', params);
- return res.data;
+ return await this.postFile(
+ '/opendataloader/html',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'OpenDataLoader HTML extraction'
+ );
}
// --- Wkhtml Endpoints ---
async wkhtmlHtmlToPdf(params: WkhtmlHtmlToPdfParams): Promise {
- let res = await this.axios.post('/wkhtml/pdf/html', params);
- return res.data;
+ return await this.postFile(
+ '/wkhtml/pdf/html',
+ {
+ ...mapBaseRequest(params),
+ Html: params.html,
+ Options: params.options,
+ EnableToc: params.enableToc,
+ TocOptions: params.tocOptions
+ },
+ 'wkhtml HTML to PDF'
+ );
}
async wkhtmlUrlToPdf(params: WkhtmlUrlToPdfParams): Promise {
- let res = await this.axios.post('/wkhtml/pdf/url', params);
- return res.data;
+ return await this.postFile(
+ '/wkhtml/pdf/url',
+ {
+ ...mapBaseRequest(params),
+ Url: params.url,
+ Options: params.options,
+ EnableToc: params.enableToc,
+ TocOptions: params.tocOptions,
+ ExtraHTTPHeaders: params.extraHTTPHeaders
+ },
+ 'wkhtml URL to PDF'
+ );
}
// --- Utility Endpoints ---
async deleteFile(responseId: string): Promise {
- await this.axios.delete(`/file/${responseId}`);
+ try {
+ await this.axios.delete(`/file/${responseId}`);
+ } catch (error) {
+ throw api2PdfApiError(error, 'file deletion');
+ }
}
async getBalance(): Promise<{ balance: number }> {
- let res = await this.axios.get<{ balance: number }>('/balance');
- return res.data;
+ try {
+ let res = await this.axios.get<{ balance?: number; Balance?: number }>('/balance');
+ return {
+ balance: numberValue(res.data.balance ?? res.data.Balance)
+ };
+ } catch (error) {
+ throw api2PdfApiError(error, 'balance check');
+ }
}
async getStatus(): Promise<{ status: string }> {
- let res = await this.axios.get<{ status: string }>('/status');
- return res.data;
+ try {
+ let res = await this.axios.get<{ status?: string; Status?: string }>('/status');
+ return {
+ status: stringValue(res.data.status ?? res.data.Status) || 'unknown'
+ };
+ } catch (error) {
+ throw api2PdfApiError(error, 'status check');
+ }
+ }
+
+ async downloadFile(fileUrl: string): Promise {
+ let response: globalThis.Response;
+
+ try {
+ response = await fetch(fileUrl);
+ } catch (error) {
+ throw api2PdfApiError(error, 'generated file download');
+ }
+
+ if (!response.ok) {
+ throw api2PdfServiceError(
+ `API2PDF generated file download failed: HTTP ${response.status} ${response.statusText}`
+ );
+ }
+
+ let contentType = response.headers.get('content-type')?.split(';')[0]?.trim();
+ let bytes: Buffer;
+
+ try {
+ bytes = Buffer.from(await response.arrayBuffer());
+ } catch (error) {
+ throw api2PdfApiError(error, 'generated file download');
+ }
+
+ return {
+ contentBase64: bytes.toString('base64'),
+ mimeType: contentType || 'application/octet-stream',
+ byteLength: bytes.byteLength
+ };
}
}
diff --git a/integrations/api2pdf/src/lib/errors.ts b/integrations/api2pdf/src/lib/errors.ts
new file mode 100644
index 0000000000..56a3f81dee
--- /dev/null
+++ b/integrations/api2pdf/src/lib/errors.ts
@@ -0,0 +1,80 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null;
+
+let pushDetail = (details: string[], value: unknown) => {
+ if (typeof value !== 'string' && typeof value !== 'number') return;
+
+ let detail = String(value).trim();
+ if (detail && !details.includes(detail)) details.push(detail);
+};
+
+let collectDetails = (value: unknown, details: string[]) => {
+ if (Array.isArray(value)) {
+ for (let item of value) collectDetails(item, details);
+ return;
+ }
+
+ if (!isRecord(value)) {
+ pushDetail(details, value);
+ return;
+ }
+
+ pushDetail(details, value.message);
+ pushDetail(details, value.Message);
+ pushDetail(details, value.error);
+ pushDetail(details, value.Error);
+ pushDetail(details, value.detail);
+ pushDetail(details, value.title);
+ pushDetail(details, value.code);
+ collectDetails(value.errors, details);
+};
+
+let extractApi2PdfMessage = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let details: string[] = [];
+
+ collectDetails(response?.data, details);
+
+ if (details.length > 0) return details.join(' - ');
+ if (error instanceof Error && error.message) return error.message;
+ return 'Unknown error';
+};
+
+let statusLabelFor = (response?: ErrorResponse) =>
+ response?.status !== undefined
+ ? `HTTP ${response.status}${response.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+
+let upstreamCodeFor = (response?: ErrorResponse) => {
+ if (!isRecord(response?.data)) return undefined;
+
+ let code = response.data.code ?? response.data.error ?? response.data.Error;
+ return typeof code === 'string' || typeof code === 'number' ? String(code) : undefined;
+};
+
+export let api2PdfServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let api2PdfApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) return error;
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let serviceError = api2PdfServiceError(
+ `API2PDF API ${operation} failed: ${statusLabelFor(response)}${extractApi2PdfMessage(error)}`
+ );
+ serviceError.data.reason = 'api2pdf_api_error';
+ serviceError.data.upstreamStatus = response?.status;
+ serviceError.data.upstreamCode = upstreamCodeFor(response);
+
+ if (error instanceof Error) serviceError.setParent(error);
+
+ return serviceError;
+};
diff --git a/integrations/api2pdf/src/lib/types.ts b/integrations/api2pdf/src/lib/types.ts
index 93b536f555..e8b787e4e6 100644
--- a/integrations/api2pdf/src/lib/types.ts
+++ b/integrations/api2pdf/src/lib/types.ts
@@ -8,6 +8,12 @@ export interface Api2PdfResponse {
error?: string;
}
+export interface Api2PdfFileAttachment {
+ contentBase64: string;
+ mimeType: string;
+ byteLength: number;
+}
+
export interface ChromePdfOptions {
delay?: number;
scale?: number;
@@ -43,6 +49,8 @@ export interface ChromeImageOptions {
isLandscape?: boolean;
hasTouch?: boolean;
};
+ puppeteerWaitForMethod?: string;
+ puppeteerWaitForValue?: string;
}
export interface StorageOptions {
diff --git a/integrations/api2pdf/src/tools.schema.test.ts b/integrations/api2pdf/src/tools.schema.test.ts
new file mode 100644
index 0000000000..7208ba765c
--- /dev/null
+++ b/integrations/api2pdf/src/tools.schema.test.ts
@@ -0,0 +1,4 @@
+import { describeMcpCompatibleToolSchemas } from '@slates/test';
+import { provider } from './index';
+
+describeMcpCompatibleToolSchemas('API2PDF tool input schemas', provider.actions);
diff --git a/integrations/api2pdf/src/tools/capture-screenshot.ts b/integrations/api2pdf/src/tools/capture-screenshot.ts
index ab47f01bfb..94b3d68813 100644
--- a/integrations/api2pdf/src/tools/capture-screenshot.ts
+++ b/integrations/api2pdf/src/tools/capture-screenshot.ts
@@ -1,7 +1,14 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
+import { api2PdfServiceError } from '../lib/errors';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
let imageOptionsSchema = z
.object({
@@ -23,7 +30,15 @@ let imageOptionsSchema = z
hasTouch: z.boolean().optional().describe('Simulate touch-enabled device')
})
.optional()
- .describe('Viewport configuration for the screenshot')
+ .describe('Viewport configuration for the screenshot'),
+ puppeteerWaitForMethod: z
+ .string()
+ .optional()
+ .describe('Puppeteer wait method, e.g. "WaitForNavigation" or "WaitForExpression"'),
+ puppeteerWaitForValue: z
+ .string()
+ .optional()
+ .describe('Value to pass to the Puppeteer wait method')
})
.optional()
.describe('Screenshot capture options');
@@ -59,17 +74,7 @@ export let captureScreenshot = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source URL')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the generated screenshot image'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -80,7 +85,7 @@ export let captureScreenshot = SlateTool.create(spec, {
Boolean
).length;
if (sourceCount !== 1) {
- throw new Error('Provide exactly one of: html, url, or markdown');
+ throw api2PdfServiceError('Provide exactly one of: html, url, or markdown');
}
let result: any;
@@ -109,21 +114,14 @@ export let captureScreenshot = SlateTool.create(spec, {
});
}
- if (!result.success) {
- throw new Error(result.error || 'Screenshot capture failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'Screenshot capture failed');
let sourceType = ctx.input.html ? 'HTML' : ctx.input.url ? 'URL' : 'Markdown';
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Captured screenshot from ${sourceType} (${result.mbOut} MB, ${result.seconds}s). [Download Image](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Captured screenshot from ${sourceType} (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/check-status.ts b/integrations/api2pdf/src/tools/check-status.ts
new file mode 100644
index 0000000000..fbe6648b98
--- /dev/null
+++ b/integrations/api2pdf/src/tools/check-status.ts
@@ -0,0 +1,36 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Api2PdfClient } from '../lib/client';
+import { spec } from '../spec';
+
+export let checkStatus = SlateTool.create(spec, {
+ name: 'Check Status',
+ key: 'check_status',
+ description: `Check the API2PDF service health status endpoint. Use this to distinguish account or request issues from a broader API availability problem.`,
+ tags: {
+ destructive: false,
+ readOnly: true
+ }
+})
+ .input(z.object({}))
+ .output(
+ z.object({
+ status: z.string().describe('Current API2PDF service status')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Api2PdfClient({
+ token: ctx.auth.token,
+ useXlCluster: ctx.config.useXlCluster
+ });
+
+ let result = await client.getStatus();
+
+ return {
+ output: {
+ status: result.status
+ },
+ message: `API2PDF status: **${result.status}**`
+ };
+ })
+ .build();
diff --git a/integrations/api2pdf/src/tools/convert-document.ts b/integrations/api2pdf/src/tools/convert-document.ts
index 827313b867..11e83dc049 100644
--- a/integrations/api2pdf/src/tools/convert-document.ts
+++ b/integrations/api2pdf/src/tools/convert-document.ts
@@ -1,7 +1,14 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
+import { api2PdfServiceError } from '../lib/errors';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let convertDocument = SlateTool.create(spec, {
name: 'Convert Document',
@@ -35,17 +42,7 @@ export let convertDocument = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source URL')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the converted document'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -56,7 +53,7 @@ export let convertDocument = SlateTool.create(spec, {
if (ctx.input.outputFormat === 'pdf') {
if (!ctx.input.url) {
- throw new Error('A url is required for PDF conversion');
+ throw api2PdfServiceError('A url is required for PDF conversion');
}
result = await client.libreOfficeAnyToPdf({
url: ctx.input.url,
@@ -66,41 +63,36 @@ export let convertDocument = SlateTool.create(spec, {
});
} else if (ctx.input.outputFormat === 'docx') {
if (!ctx.input.html && !ctx.input.url) {
- throw new Error('Either html or url is required for DOCX conversion');
+ throw api2PdfServiceError('Either html or url is required for DOCX conversion');
}
result = await client.libreOfficeHtmlToDocx({
html: ctx.input.html,
url: ctx.input.url,
fileName: ctx.input.fileName,
+ inline: ctx.input.inline,
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
} else {
if (!ctx.input.html && !ctx.input.url) {
- throw new Error('Either html or url is required for XLSX conversion');
+ throw api2PdfServiceError('Either html or url is required for XLSX conversion');
}
result = await client.libreOfficeHtmlToXlsx({
html: ctx.input.html,
url: ctx.input.url,
fileName: ctx.input.fileName,
+ inline: ctx.input.inline,
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
}
- if (!result.success) {
- throw new Error(result.error || 'Document conversion failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'Document conversion failed');
let formatLabel = ctx.input.outputFormat.toUpperCase();
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Converted document to ${formatLabel} (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Converted document to ${formatLabel} (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/convert-to-markdown.ts b/integrations/api2pdf/src/tools/convert-to-markdown.ts
index 429225cb59..87371668af 100644
--- a/integrations/api2pdf/src/tools/convert-to-markdown.ts
+++ b/integrations/api2pdf/src/tools/convert-to-markdown.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let convertToMarkdown = SlateTool.create(spec, {
name: 'Convert to Markdown',
@@ -21,23 +27,17 @@ export let convertToMarkdown = SlateTool.create(spec, {
.string()
.optional()
.describe('Desired file name for the output Markdown file'),
+ inline: z
+ .boolean()
+ .optional()
+ .describe('If true, opens in browser; if false, triggers download'),
extraHttpHeaders: z
.record(z.string(), z.string())
.optional()
.describe('Extra HTTP headers when fetching the source document')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the generated Markdown file'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -47,22 +47,16 @@ export let convertToMarkdown = SlateTool.create(spec, {
let result = await client.convertToMarkdown({
url: ctx.input.url,
fileName: ctx.input.fileName,
+ inline: ctx.input.inline,
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
- if (!result.success) {
- throw new Error(result.error || 'Markdown conversion failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'Markdown conversion failed');
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Converted document to Markdown (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Converted document to Markdown (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/create-zip.ts b/integrations/api2pdf/src/tools/create-zip.ts
index 6dbb3d5e7b..47eea1f06a 100644
--- a/integrations/api2pdf/src/tools/create-zip.ts
+++ b/integrations/api2pdf/src/tools/create-zip.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let createZip = SlateTool.create(spec, {
name: 'Create ZIP Archive',
@@ -34,17 +40,7 @@ export let createZip = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source files')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the ZIP archive'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -58,19 +54,12 @@ export let createZip = SlateTool.create(spec, {
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
- if (!result.success) {
- throw new Error(result.error || 'ZIP archive creation failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'ZIP archive creation failed');
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Created ZIP archive with **${ctx.input.files.length}** file(s) (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Created ZIP archive with **${ctx.input.files.length}** file(s) (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/extract-pdf-data.ts b/integrations/api2pdf/src/tools/extract-pdf-data.ts
index 3e94b2dde3..60403436d1 100644
--- a/integrations/api2pdf/src/tools/extract-pdf-data.ts
+++ b/integrations/api2pdf/src/tools/extract-pdf-data.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let extractPdfData = SlateTool.create(spec, {
name: 'Extract PDF Data',
@@ -27,23 +33,17 @@ export let extractPdfData = SlateTool.create(spec, {
.string()
.optional()
.describe('Desired file name for the extracted data file'),
+ inline: z
+ .boolean()
+ .optional()
+ .describe('If true, opens in browser; if false, triggers download'),
extraHttpHeaders: z
.record(z.string(), z.string())
.optional()
.describe('Extra HTTP headers when fetching the source PDF')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the extracted data file'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -56,35 +56,31 @@ export let extractPdfData = SlateTool.create(spec, {
result = await client.extractJsonFromPdf({
url: ctx.input.url,
fileName: ctx.input.fileName,
+ inline: ctx.input.inline,
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
} else if (ctx.input.outputFormat === 'markdown') {
result = await client.extractMarkdownFromPdf({
url: ctx.input.url,
fileName: ctx.input.fileName,
+ inline: ctx.input.inline,
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
} else {
result = await client.extractHtmlFromPdf({
url: ctx.input.url,
fileName: ctx.input.fileName,
+ inline: ctx.input.inline,
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
}
- if (!result.success) {
- throw new Error(result.error || 'PDF data extraction failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'PDF data extraction failed');
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Extracted data from PDF as ${ctx.input.outputFormat.toUpperCase()} (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Extracted data from PDF as ${ctx.input.outputFormat.toUpperCase()} (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/extract-pdf-pages.ts b/integrations/api2pdf/src/tools/extract-pdf-pages.ts
index da964f8fa4..277ae9cd9a 100644
--- a/integrations/api2pdf/src/tools/extract-pdf-pages.ts
+++ b/integrations/api2pdf/src/tools/extract-pdf-pages.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let extractPdfPages = SlateTool.create(spec, {
name: 'Extract PDF Pages',
@@ -40,17 +46,7 @@ export let extractPdfPages = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source PDF')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the extracted PDF'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -66,9 +62,7 @@ export let extractPdfPages = SlateTool.create(spec, {
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
- if (!result.success) {
- throw new Error(result.error || 'Page extraction failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'Page extraction failed');
let rangeDesc = '';
if (ctx.input.start !== undefined && ctx.input.end !== undefined) {
@@ -82,14 +76,9 @@ export let extractPdfPages = SlateTool.create(spec, {
}
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Extracted ${rangeDesc} from PDF (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Extracted ${rangeDesc} from PDF (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/generate-barcode.ts b/integrations/api2pdf/src/tools/generate-barcode.ts
index e681892282..8aeba7738c 100644
--- a/integrations/api2pdf/src/tools/generate-barcode.ts
+++ b/integrations/api2pdf/src/tools/generate-barcode.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let generateBarcode = SlateTool.create(spec, {
name: 'Generate Barcode',
@@ -31,17 +37,7 @@ export let generateBarcode = SlateTool.create(spec, {
.describe('Whether to display the encoded value as a label below the barcode')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the generated barcode image'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -56,19 +52,12 @@ export let generateBarcode = SlateTool.create(spec, {
showlabel: ctx.input.showLabel
});
- if (!result.success) {
- throw new Error(result.error || 'Barcode generation failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'Barcode generation failed');
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Generated ${ctx.input.format} barcode (${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Generated ${ctx.input.format} barcode (${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/generate-pdf.ts b/integrations/api2pdf/src/tools/generate-pdf.ts
index d0c98d92b8..666942f8fe 100644
--- a/integrations/api2pdf/src/tools/generate-pdf.ts
+++ b/integrations/api2pdf/src/tools/generate-pdf.ts
@@ -1,7 +1,14 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
+import { api2PdfServiceError } from '../lib/errors';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
let chromePdfOptionsSchema = z
.object({
@@ -46,6 +53,9 @@ let chromePdfOptionsSchema = z
.boolean()
.optional()
.describe('Omit default white background for transparent PDFs'),
+ tagged: z.boolean().optional().describe('Generate a tagged, accessible PDF'),
+ outline: z.boolean().optional().describe('Embed a document outline/bookmarks'),
+ usePrintCss: z.boolean().optional().describe('Use print media CSS styles while rendering'),
puppeteerWaitForMethod: z
.string()
.optional()
@@ -65,7 +75,7 @@ export let generatePdf = SlateTool.create(spec, {
instructions: [
'Provide exactly one of: html, url, or markdown as the source content.',
'For URLs requiring authentication, pass the necessary headers via extraHttpHeaders.',
- 'Use the options object to customize page layout, margins, orientation, and header/footer templates.'
+ 'Use the options object to customize page layout, margins, orientation, header/footer templates, accessibility tagging, and print CSS.'
],
tags: {
destructive: false,
@@ -89,17 +99,7 @@ export let generatePdf = SlateTool.create(spec, {
.describe('Extra HTTP headers to send when fetching the source URL')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the generated PDF'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -110,7 +110,7 @@ export let generatePdf = SlateTool.create(spec, {
Boolean
).length;
if (sourceCount !== 1) {
- throw new Error('Provide exactly one of: html, url, or markdown');
+ throw api2PdfServiceError('Provide exactly one of: html, url, or markdown');
}
let result: any;
@@ -139,21 +139,14 @@ export let generatePdf = SlateTool.create(spec, {
});
}
- if (!result.success) {
- throw new Error(result.error || 'PDF generation failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'PDF generation failed');
let sourceType = ctx.input.html ? 'HTML' : ctx.input.url ? 'URL' : 'Markdown';
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Generated PDF from ${sourceType} (${result.mbOut} MB, ${result.seconds}s). [Download PDF](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Generated PDF from ${sourceType} (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/generate-thumbnail.ts b/integrations/api2pdf/src/tools/generate-thumbnail.ts
index 6133bb7714..fe5341d729 100644
--- a/integrations/api2pdf/src/tools/generate-thumbnail.ts
+++ b/integrations/api2pdf/src/tools/generate-thumbnail.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let generateThumbnail = SlateTool.create(spec, {
name: 'Generate Thumbnail',
@@ -30,17 +36,7 @@ export let generateThumbnail = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source document')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the generated thumbnail image'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -54,19 +50,12 @@ export let generateThumbnail = SlateTool.create(spec, {
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
- if (!result.success) {
- throw new Error(result.error || 'Thumbnail generation failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'Thumbnail generation failed');
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Generated thumbnail preview (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Generated thumbnail preview (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/index.ts b/integrations/api2pdf/src/tools/index.ts
index eaddb0779d..e92f5bd78b 100644
--- a/integrations/api2pdf/src/tools/index.ts
+++ b/integrations/api2pdf/src/tools/index.ts
@@ -1,5 +1,6 @@
export * from './capture-screenshot';
export * from './check-balance';
+export * from './check-status';
export * from './convert-document';
export * from './convert-to-markdown';
export * from './create-zip';
diff --git a/integrations/api2pdf/src/tools/merge-pdfs.ts b/integrations/api2pdf/src/tools/merge-pdfs.ts
index ed78b2a38c..1b42ff29a6 100644
--- a/integrations/api2pdf/src/tools/merge-pdfs.ts
+++ b/integrations/api2pdf/src/tools/merge-pdfs.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let mergePdfs = SlateTool.create(spec, {
name: 'Merge PDFs',
@@ -33,17 +39,7 @@ export let mergePdfs = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source PDFs')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the merged PDF'),
- mbOut: z.number().describe('Size of the merged file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -57,19 +53,12 @@ export let mergePdfs = SlateTool.create(spec, {
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
- if (!result.success) {
- throw new Error(result.error || 'PDF merge failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'PDF merge failed');
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Merged **${ctx.input.urls.length}** PDFs into one document (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Merged **${ctx.input.urls.length}** PDFs into one document (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/protect-pdf.ts b/integrations/api2pdf/src/tools/protect-pdf.ts
index 31a565d9fd..cbd1ad2fdb 100644
--- a/integrations/api2pdf/src/tools/protect-pdf.ts
+++ b/integrations/api2pdf/src/tools/protect-pdf.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let protectPdf = SlateTool.create(spec, {
name: 'Protect PDF',
@@ -33,17 +39,7 @@ export let protectPdf = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source PDF')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the password-protected PDF'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -59,19 +55,12 @@ export let protectPdf = SlateTool.create(spec, {
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
- if (!result.success) {
- throw new Error(result.error || 'PDF password protection failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'PDF password protection failed');
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Added password protection to PDF (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Added password protection to PDF (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/src/tools/shared.ts b/integrations/api2pdf/src/tools/shared.ts
new file mode 100644
index 0000000000..36175a83af
--- /dev/null
+++ b/integrations/api2pdf/src/tools/shared.ts
@@ -0,0 +1,51 @@
+import { createBase64Attachment } from 'slates';
+import { z } from 'zod';
+import type { Api2PdfClient } from '../lib/client';
+import { api2PdfServiceError } from '../lib/errors';
+import type { Api2PdfFileAttachment, Api2PdfResponse } from '../lib/types';
+
+export let api2PdfFileOutputSchema = z.object({
+ responseId: z
+ .string()
+ .describe('Unique ID for this request, can be used to delete the file later'),
+ fileUrl: z.string().describe('API2PDF URL for the generated file'),
+ mbOut: z.number().describe('Size of the generated file in megabytes, reported by API2PDF'),
+ cost: z.number().describe('Cost of this API call in USD'),
+ seconds: z.number().describe('Processing time in seconds'),
+ mimeType: z.string().describe('MIME type of the returned Slate attachment'),
+ byteLength: z.number().describe('Decoded byte length of the returned attachment'),
+ attachmentCount: z.number().describe('Number of Slate attachments returned')
+});
+
+export let requireApi2PdfSuccess = (result: Api2PdfResponse, fallback: string) => {
+ if (!result.success) {
+ throw api2PdfServiceError(result.error || fallback);
+ }
+
+ if (!result.fileUrl) {
+ throw api2PdfServiceError('API2PDF succeeded but did not return a generated file URL.');
+ }
+};
+
+export let fetchApi2PdfAttachment = async (
+ client: Api2PdfClient,
+ result: Api2PdfResponse,
+ fallback: string
+) => {
+ requireApi2PdfSuccess(result, fallback);
+ return await client.downloadFile(result.fileUrl);
+};
+
+export let fileOutput = (result: Api2PdfResponse, file: Api2PdfFileAttachment) => ({
+ responseId: result.responseId,
+ fileUrl: result.fileUrl,
+ mbOut: result.mbOut,
+ cost: result.cost,
+ seconds: result.seconds,
+ mimeType: file.mimeType,
+ byteLength: file.byteLength,
+ attachmentCount: 1
+});
+
+export let fileAttachment = (file: Api2PdfFileAttachment) =>
+ createBase64Attachment(file.contentBase64, file.mimeType);
diff --git a/integrations/api2pdf/src/tools/watermark-pdf.ts b/integrations/api2pdf/src/tools/watermark-pdf.ts
index 662f975d5b..e1a96feb2e 100644
--- a/integrations/api2pdf/src/tools/watermark-pdf.ts
+++ b/integrations/api2pdf/src/tools/watermark-pdf.ts
@@ -2,6 +2,12 @@ import { SlateTool } from 'slates';
import { z } from 'zod';
import { Api2PdfClient } from '../lib/client';
import { spec } from '../spec';
+import {
+ api2PdfFileOutputSchema,
+ fetchApi2PdfAttachment,
+ fileAttachment,
+ fileOutput
+} from './shared';
export let watermarkPdf = SlateTool.create(spec, {
name: 'Watermark PDF',
@@ -37,17 +43,7 @@ export let watermarkPdf = SlateTool.create(spec, {
.describe('Extra HTTP headers when fetching the source PDF')
})
)
- .output(
- z.object({
- responseId: z
- .string()
- .describe('Unique ID for this request, can be used to delete the file later'),
- fileUrl: z.string().describe('URL to download the watermarked PDF'),
- mbOut: z.number().describe('Size of the generated file in megabytes'),
- cost: z.number().describe('Cost of this API call in USD'),
- seconds: z.number().describe('Processing time in seconds')
- })
- )
+ .output(api2PdfFileOutputSchema)
.handleInvocation(async ctx => {
let client = new Api2PdfClient({
token: ctx.auth.token,
@@ -66,21 +62,14 @@ export let watermarkPdf = SlateTool.create(spec, {
extraHTTPHeaders: ctx.input.extraHttpHeaders
});
- if (!result.success) {
- throw new Error(result.error || 'PDF watermarking failed');
- }
+ let file = await fetchApi2PdfAttachment(client, result, 'PDF watermarking failed');
let watermarkText = ctx.input.text || 'DRAFT';
return {
- output: {
- responseId: result.responseId,
- fileUrl: result.fileUrl,
- mbOut: result.mbOut,
- cost: result.cost,
- seconds: result.seconds
- },
- message: `Added "${watermarkText}" watermark to PDF (${result.mbOut} MB, ${result.seconds}s). [Download](${result.fileUrl})`
+ output: fileOutput(result, file),
+ attachments: [fileAttachment(file)],
+ message: `Added "${watermarkText}" watermark to PDF (${result.mbOut} MB, ${result.seconds}s) and returned it as a Slate attachment.`
};
})
.build();
diff --git a/integrations/api2pdf/vitest.config.ts b/integrations/api2pdf/vitest.config.ts
new file mode 100644
index 0000000000..0b05bc07ad
--- /dev/null
+++ b/integrations/api2pdf/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['src/**/*.test.ts']
+ }
+});
diff --git a/integrations/asana/README.md b/integrations/asana/README.md
index 4dc23f1a3c..c426091c43 100644
--- a/integrations/asana/README.md
+++ b/integrations/asana/README.md
@@ -16,6 +16,10 @@ Create a new task in a project or workspace. Supports setting name, notes, assig
Permanently delete a project. This action cannot be undone.
+### Delete Section
+
+Delete an empty project section. Asana does not allow deleting the last remaining section.
+
### Delete Task
Permanently delete a task. This action cannot be undone.
@@ -48,6 +52,10 @@ List tasks filtered by project, section, or assignee. At least one filter must b
List all teams in an organization workspace.
+### List Time Tracking Entries
+
+List Asana time tracking entries for a task, or retrieve one entry by GID.
+
### List Users
List users in a workspace. Returns user GIDs and names for referencing in other tools.
@@ -72,10 +80,30 @@ List all sections in a project. Sections are used to organize tasks within a pro
List all tags in a workspace.
+### Manage Attachments
+
+List, inspect, attach, upload, or delete Asana attachments on tasks, projects, and project briefs. File bytes are accepted only as input for uploads; downloaded file contents are not returned inline.
+
+### Manage Custom Fields
+
+List, inspect, create, update, and maintain Asana custom field metadata for a workspace.
+
+### Manage Project Templates
+
+List, inspect, and instantiate Asana project templates.
+
### Search Tasks
Search for tasks in a workspace using various filters like text, assignee, projects, tags, completion status, and date ranges. Supports full-text search across task names and descriptions.
+### Typeahead Search
+
+Search Asana workspace objects with the low-latency typeahead endpoint. Use this to discover project, project template, portfolio, tag, task, user, or custom field GIDs for other tools.
+
+### Update Section
+
+Rename an existing project section.
+
### Update Project
Update an existing project's name, notes, dates, color, layout, archived status, or privacy setting.
diff --git a/integrations/asana/docs/SPEC.md b/integrations/asana/docs/SPEC.md
index b028bee704..70ace7352f 100644
--- a/integrations/asana/docs/SPEC.md
+++ b/integrations/asana/docs/SPEC.md
@@ -42,7 +42,7 @@ OAuth is a mechanism for applications to access the Asana API on behalf of a use
- `teams:read`
- `time_tracking_entries:read`
- `timesheet_approval_statuses:read`, `timesheet_approval_statuses:write`
-- `workspace.typeahead:read`
+- `workspaces.typeahead:read`
- `users:read`
- `webhooks:read`, `webhooks:write`, `webhooks:delete`
- `workspaces:read`
diff --git a/integrations/asana/package.json b/integrations/asana/package.json
index 22fdc1f26e..bf27d1d7e0 100644
--- a/integrations/asana/package.json
+++ b/integrations/asana/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
- "typescript": "^5"
+ "@slates/test": "1.0.0-rc.9",
+ "typescript": "^5",
+ "vitest": "^3.1.2"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.6"
}
diff --git a/integrations/asana/src/auth.ts b/integrations/asana/src/auth.ts
index f95bbe6f45..feed683d2c 100644
--- a/integrations/asana/src/auth.ts
+++ b/integrations/asana/src/auth.ts
@@ -1,5 +1,6 @@
import { createAxios, SlateAuth } from 'slates';
import { z } from 'zod';
+import { asanaApiError, asanaServiceError } from './lib/errors';
let asanaApi = createAxios({
baseURL: 'https://app.asana.com/api/1.0'
@@ -18,11 +19,16 @@ let outputSchema = z.object({
type AuthOutput = z.infer;
let fetchProfile = async (token: string) => {
- let response = await asanaApi.get('/users/me', {
- headers: {
- Authorization: `Bearer ${token}`
- }
- });
+ let response: any;
+ try {
+ response = await asanaApi.get('/users/me', {
+ headers: {
+ Authorization: `Bearer ${token}`
+ }
+ });
+ } catch (error) {
+ throw asanaApiError(error, 'fetch profile');
+ }
let user = response.data.data;
@@ -176,7 +182,7 @@ export let auth = SlateAuth.create()
{
title: 'Typeahead Read',
description: 'Use workspace typeahead search',
- scope: 'workspace.typeahead:read'
+ scope: 'workspaces.typeahead:read'
},
{
title: 'OpenID Connect',
@@ -202,23 +208,32 @@ export let auth = SlateAuth.create()
},
handleCallback: async ctx => {
- let response = await asanaAuth.post(
- '/-/oauth_token',
- new URLSearchParams({
- grant_type: 'authorization_code',
- client_id: ctx.clientId,
- client_secret: ctx.clientSecret,
- redirect_uri: ctx.redirectUri,
- code: ctx.code
- }).toString(),
- {
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
+ let response: any;
+ try {
+ response = await asanaAuth.post(
+ '/-/oauth_token',
+ new URLSearchParams({
+ grant_type: 'authorization_code',
+ client_id: ctx.clientId,
+ client_secret: ctx.clientSecret,
+ redirect_uri: ctx.redirectUri,
+ code: ctx.code
+ }).toString(),
+ {
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ }
}
- }
- );
+ );
+ } catch (error) {
+ throw asanaApiError(error, 'exchange OAuth code');
+ }
let data = response.data;
+ if (!data.access_token) {
+ throw asanaServiceError('Asana OAuth token exchange did not return an access token.');
+ }
+
let expiresAt = data.expires_in
? new Date(Date.now() + data.expires_in * 1000).toISOString()
: undefined;
@@ -234,25 +249,34 @@ export let auth = SlateAuth.create()
handleTokenRefresh: async (ctx: any) => {
if (!ctx.output.refreshToken) {
- throw new Error('No refresh token available');
+ throw asanaServiceError('No Asana refresh token is available.');
}
- let response = await asanaAuth.post(
- '/-/oauth_token',
- new URLSearchParams({
- grant_type: 'refresh_token',
- client_id: ctx.clientId,
- client_secret: ctx.clientSecret,
- refresh_token: ctx.output.refreshToken
- }).toString(),
- {
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
+ let response: any;
+ try {
+ response = await asanaAuth.post(
+ '/-/oauth_token',
+ new URLSearchParams({
+ grant_type: 'refresh_token',
+ client_id: ctx.clientId,
+ client_secret: ctx.clientSecret,
+ refresh_token: ctx.output.refreshToken
+ }).toString(),
+ {
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ }
}
- }
- );
+ );
+ } catch (error) {
+ throw asanaApiError(error, 'refresh OAuth token');
+ }
let data = response.data;
+ if (!data.access_token) {
+ throw asanaServiceError('Asana OAuth refresh did not return an access token.');
+ }
+
let expiresAt = data.expires_in
? new Date(Date.now() + data.expires_in * 1000).toISOString()
: undefined;
diff --git a/integrations/asana/src/index.ts b/integrations/asana/src/index.ts
index 935f5be46f..aa94c00cf9 100644
--- a/integrations/asana/src/index.ts
+++ b/integrations/asana/src/index.ts
@@ -8,6 +8,7 @@ import {
createTag,
createTask,
deleteProject,
+ deleteSection,
deleteTask,
getGoal,
getPortfolio,
@@ -23,11 +24,17 @@ import {
listTags,
listTasks,
listTeams,
+ listTimeTrackingEntries,
listUsers,
listWorkspaces,
+ manageAttachments,
+ manageCustomFields,
+ manageProjectTemplates,
searchTasks,
+ typeaheadSearch,
updatePortfolio,
updateProject,
+ updateSection,
updateTask
} from './tools';
import { projectEvents, taskChangesWebhook, taskEvents } from './triggers';
@@ -50,19 +57,26 @@ export let provider = Slate.create({
listSubtasks,
listSections,
createSection,
+ updateSection,
+ deleteSection,
listComments,
addComment,
listTags,
createTag,
+ manageAttachments,
+ manageCustomFields,
listPortfolios,
getPortfolio,
createPortfolio,
updatePortfolio,
+ manageProjectTemplates,
listGoals,
getGoal,
listUsers,
getUser,
- listTeams
+ listTeams,
+ listTimeTrackingEntries,
+ typeaheadSearch
],
triggers: [projectEvents, taskEvents, taskChangesWebhook]
});
diff --git a/integrations/asana/src/lib/client.ts b/integrations/asana/src/lib/client.ts
index 6f9a00e229..4e6a25bd46 100644
--- a/integrations/asana/src/lib/client.ts
+++ b/integrations/asana/src/lib/client.ts
@@ -1,4 +1,5 @@
import { createAxios } from 'slates';
+import { asanaApiError } from './errors';
export class Client {
private axios: ReturnType;
@@ -11,6 +12,11 @@ export class Client {
'Content-Type': 'application/json'
}
});
+
+ this.axios.interceptors.response.use(
+ response => response,
+ error => Promise.reject(asanaApiError(error))
+ );
}
// ── Workspaces ──
@@ -55,13 +61,14 @@ export class Client {
workspaceId: string,
params?: { limit?: number; offset?: string; archived?: boolean; team?: string }
) {
- let response = await this.axios.get('/projects', {
+ let path = params?.team
+ ? `/teams/${params.team}/projects`
+ : `/workspaces/${workspaceId}/projects`;
+ let response = await this.axios.get(path, {
params: {
- workspace: workspaceId,
limit: params?.limit ?? 100,
offset: params?.offset,
archived: params?.archived,
- team: params?.team,
opt_fields:
'name,gid,archived,color,created_at,current_status,due_on,start_on,modified_at,owner,team,workspace,notes,public,default_view'
}
@@ -80,9 +87,9 @@ export class Client {
}
async createProject(workspaceId: string, data: Record) {
- let response = await this.axios.post('/projects', {
- data: { ...data, workspace: workspaceId }
- });
+ let { team, ...projectData } = data;
+ let path = team ? `/teams/${team}/projects` : `/workspaces/${workspaceId}/projects`;
+ let response = await this.axios.post(path, { data: projectData });
return response.data.data;
}
@@ -212,6 +219,12 @@ export class Client {
});
}
+ async removeDependentsFromTask(taskId: string, dependentIds: string[]) {
+ await this.axios.post(`/tasks/${taskId}/removeDependents`, {
+ data: { dependents: dependentIds }
+ });
+ }
+
async addProjectToTask(
taskId: string,
projectId: string,
@@ -483,6 +496,18 @@ export class Client {
return response.data.data;
}
+ async createEnumOption(customFieldId: string, data: Record) {
+ let response = await this.axios.post(`/custom_fields/${customFieldId}/enum_options`, {
+ data
+ });
+ return response.data.data;
+ }
+
+ async updateEnumOption(enumOptionId: string, data: Record) {
+ let response = await this.axios.put(`/enum_options/${enumOptionId}`, { data });
+ return response.data.data;
+ }
+
// ── Teams ──
async listTeamsInWorkspace(
@@ -522,16 +547,19 @@ export class Client {
async typeahead(workspaceId: string, resourceType: string, query: string, count?: number) {
let response = await this.axios.get(`/workspaces/${workspaceId}/typeahead`, {
- params: { resource_type: resourceType, query, count: count ?? 10 }
+ params: { resource_type: resourceType, query, count: count ?? 20 }
});
return response.data;
}
// ── Attachments ──
- async listAttachments(parentId: string, parentType: string = 'task') {
- let response = await this.axios.get(`/${parentType}s/${parentId}/attachments`, {
+ async listAttachments(parentId: string, params?: { limit?: number; offset?: string }) {
+ let response = await this.axios.get('/attachments', {
params: {
+ parent: parentId,
+ limit: params?.limit ?? 100,
+ offset: params?.offset,
opt_fields:
'name,gid,resource_type,created_at,download_url,host,parent,view_url,resource_subtype,size'
}
@@ -540,14 +568,50 @@ export class Client {
}
async getAttachment(attachmentId: string) {
- let response = await this.axios.get(`/attachments/${attachmentId}`);
+ let response = await this.axios.get(`/attachments/${attachmentId}`, {
+ params: {
+ opt_fields:
+ 'name,gid,resource_type,created_at,download_url,host,parent,view_url,resource_subtype,size'
+ }
+ });
+ return response.data.data;
+ }
+
+ async createExternalAttachment(params: {
+ parentId: string;
+ url: string;
+ name: string;
+ connectToApp?: boolean;
+ }) {
+ let form = new FormData();
+ form.append('parent', params.parentId);
+ form.append('resource_subtype', 'external');
+ form.append('url', params.url);
+ form.append('name', params.name);
+ if (params.connectToApp !== undefined) {
+ form.append('connect_to_app', String(params.connectToApp));
+ }
+
+ let response = await this.axios.post('/attachments', form);
return response.data.data;
}
- async createAttachmentFromUrl(parentId: string, url: string, name: string) {
- let response = await this.axios.post(`/tasks/${parentId}/attachments`, {
- data: { resource_subtype: 'external', url, name, parent: parentId }
+ async uploadAttachment(params: {
+ parentId: string;
+ fileName: string;
+ contentBase64: string;
+ mimeType?: string;
+ }) {
+ let fileBytes = Buffer.from(params.contentBase64, 'base64');
+ let form = new FormData();
+ let blob = new Blob([fileBytes], {
+ type: params.mimeType ?? 'application/octet-stream'
});
+
+ form.append('parent', params.parentId);
+ form.append('file', blob, params.fileName);
+
+ let response = await this.axios.post('/attachments', form);
return response.data.data;
}
@@ -571,7 +635,11 @@ export class Client {
let payload: any = response.data;
return {
webhook: payload?.data,
- hookSecret: payload?.['X-Hook-Secret'] ?? null
+ hookSecret:
+ response.headers?.['x-hook-secret'] ??
+ response.headers?.['X-Hook-Secret'] ??
+ payload?.['X-Hook-Secret'] ??
+ null
};
}
@@ -595,21 +663,33 @@ export class Client {
// ── Project Templates ──
- async listProjectTemplates(
- workspaceId: string,
- params?: { limit?: number; offset?: string }
- ) {
- let response = await this.axios.get(`/project_templates`, {
+ async listProjectTemplates(params: {
+ workspaceId?: string;
+ teamId?: string;
+ limit?: number;
+ offset?: string;
+ }) {
+ let response = await this.axios.get('/project_templates', {
params: {
- workspace: workspaceId,
- limit: params?.limit ?? 100,
- offset: params?.offset,
- opt_fields: 'name,gid,description,color,public,requested_dates,team'
+ workspace: params.workspaceId,
+ team: params.teamId,
+ limit: params.limit ?? 100,
+ offset: params.offset,
+ opt_fields: 'name,gid,description,color,public,requested_dates,team,workspace'
}
});
return response.data;
}
+ async getProjectTemplate(templateId: string) {
+ let response = await this.axios.get(`/project_templates/${templateId}`, {
+ params: {
+ opt_fields: 'name,gid,description,color,public,requested_dates,team,workspace'
+ }
+ });
+ return response.data.data;
+ }
+
async instantiateProjectTemplate(templateId: string, data: Record) {
let response = await this.axios.post(
`/project_templates/${templateId}/instantiateProject`,
@@ -632,6 +712,16 @@ export class Client {
return response.data;
}
+ async getTimeTrackingEntry(timeTrackingEntryId: string) {
+ let response = await this.axios.get(`/time_tracking_entries/${timeTrackingEntryId}`, {
+ params: {
+ opt_fields:
+ 'gid,created_by,created_by.name,duration_minutes,entered_on,created_at,task'
+ }
+ });
+ return response.data.data;
+ }
+
// ── User Task Lists ──
async getUserTaskList(userId: string, workspaceId: string) {
diff --git a/integrations/asana/src/lib/errors.ts b/integrations/asana/src/lib/errors.ts
new file mode 100644
index 0000000000..2b52baaafa
--- /dev/null
+++ b/integrations/asana/src/lib/errors.ts
@@ -0,0 +1,94 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null;
+
+let addDetail = (details: string[], value: unknown) => {
+ if (typeof value !== 'string') {
+ return;
+ }
+
+ let trimmed = value.trim();
+ if (trimmed && !details.includes(trimmed)) {
+ details.push(trimmed);
+ }
+};
+
+let extractAsanaMessage = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let data = response?.data ?? (isRecord(error) ? error.data : undefined);
+ let details: string[] = [];
+
+ if (isRecord(data)) {
+ let errors = data.errors;
+ if (Array.isArray(errors)) {
+ for (let item of errors) {
+ if (!isRecord(item)) continue;
+ addDetail(details, item.message);
+ addDetail(details, item.phrase);
+ addDetail(details, item.help);
+ }
+ }
+
+ for (let key of ['message', 'error', 'error_description']) {
+ addDetail(details, data[key]);
+ }
+ } else {
+ addDetail(details, data);
+ }
+
+ if (details.length > 0) {
+ return details.join(' - ');
+ }
+
+ if (error instanceof Error && error.message) {
+ return error.message;
+ }
+
+ return 'Unknown error';
+};
+
+let getAsanaErrorStatus = (error: unknown) => {
+ if (!isRecord(error)) {
+ return undefined;
+ }
+
+ let response = error.response as ErrorResponse | undefined;
+ return (
+ response?.status ?? error.status ?? (isRecord(error.data) ? error.data.status : undefined)
+ );
+};
+
+export let asanaServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let asanaApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) {
+ return error;
+ }
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let status = getAsanaErrorStatus(error);
+ let statusLabel =
+ status !== undefined
+ ? `HTTP ${status}${response?.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+
+ let serviceError = asanaServiceError(
+ `Asana API ${operation} failed: ${statusLabel}${extractAsanaMessage(error)}`
+ );
+ serviceError.data.reason = 'asana_api_error';
+ serviceError.data.upstreamStatus = status;
+
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+
+ return serviceError;
+};
diff --git a/integrations/asana/src/tools.schema.test.ts b/integrations/asana/src/tools.schema.test.ts
new file mode 100644
index 0000000000..116f2e59cc
--- /dev/null
+++ b/integrations/asana/src/tools.schema.test.ts
@@ -0,0 +1,4 @@
+import { describeMcpCompatibleToolSchemas } from '@slates/test';
+import { provider } from './index';
+
+describeMcpCompatibleToolSchemas('Asana tool input schemas', provider.actions);
diff --git a/integrations/asana/src/tools/index.ts b/integrations/asana/src/tools/index.ts
index 73900af545..a2d06d06b6 100644
--- a/integrations/asana/src/tools/index.ts
+++ b/integrations/asana/src/tools/index.ts
@@ -9,12 +9,17 @@ export * from './list-projects';
export * from './list-subtasks';
export * from './list-tasks';
export * from './list-teams';
+export * from './list-time-tracking-entries';
export * from './list-users';
export * from './list-workspaces';
+export * from './manage-attachments';
export * from './manage-comments';
+export * from './manage-custom-fields';
export * from './manage-portfolios';
+export * from './manage-project-templates';
export * from './manage-sections';
export * from './manage-tags';
export * from './search-tasks';
+export * from './typeahead-search';
export * from './update-project';
export * from './update-task';
diff --git a/integrations/asana/src/tools/list-time-tracking-entries.ts b/integrations/asana/src/tools/list-time-tracking-entries.ts
new file mode 100644
index 0000000000..d9a7e2b355
--- /dev/null
+++ b/integrations/asana/src/tools/list-time-tracking-entries.ts
@@ -0,0 +1,83 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { asanaServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let formatTimeTrackingEntry = (entry: any) => ({
+ timeTrackingEntryId: entry.gid,
+ durationMinutes: entry.duration_minutes,
+ enteredOn: entry.entered_on,
+ createdAt: entry.created_at,
+ createdBy: entry.created_by,
+ task: entry.task
+});
+
+export let listTimeTrackingEntries = SlateTool.create(spec, {
+ name: 'List Time Tracking Entries',
+ key: 'list_time_tracking_entries',
+ description: `List Asana time tracking entries for a task, or retrieve one entry by GID.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ taskId: z.string().optional().describe('Task GID whose time entries should be listed.'),
+ timeTrackingEntryId: z
+ .string()
+ .optional()
+ .describe('Specific time tracking entry GID to retrieve.'),
+ limit: z.number().optional().describe('Maximum entries to return when listing.')
+ })
+ )
+ .output(
+ z.object({
+ timeTrackingEntries: z
+ .array(
+ z.object({
+ timeTrackingEntryId: z.string(),
+ durationMinutes: z.number().optional(),
+ enteredOn: z.string().optional(),
+ createdAt: z.string().optional(),
+ createdBy: z.any().optional(),
+ task: z.any().optional()
+ })
+ )
+ .optional(),
+ timeTrackingEntry: z.any().optional(),
+ timeTrackingEntryCount: z.number()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({ token: ctx.auth.token });
+
+ if (ctx.input.timeTrackingEntryId) {
+ let timeTrackingEntry = formatTimeTrackingEntry(
+ await client.getTimeTrackingEntry(ctx.input.timeTrackingEntryId)
+ );
+
+ return {
+ output: { timeTrackingEntry, timeTrackingEntryCount: 1 },
+ message: `Retrieved time tracking entry ${timeTrackingEntry.timeTrackingEntryId}.`
+ };
+ }
+
+ if (!ctx.input.taskId) {
+ throw asanaServiceError('taskId is required when timeTrackingEntryId is not provided.');
+ }
+
+ let result = await client.listTimeTrackingEntries(ctx.input.taskId, {
+ limit: ctx.input.limit
+ });
+ let timeTrackingEntries = (result.data || []).map(formatTimeTrackingEntry);
+
+ return {
+ output: {
+ timeTrackingEntries,
+ timeTrackingEntryCount: timeTrackingEntries.length
+ },
+ message: `Found **${timeTrackingEntries.length}** time tracking entr(y/ies).`
+ };
+ })
+ .build();
diff --git a/integrations/asana/src/tools/manage-attachments.ts b/integrations/asana/src/tools/manage-attachments.ts
new file mode 100644
index 0000000000..083a23714e
--- /dev/null
+++ b/integrations/asana/src/tools/manage-attachments.ts
@@ -0,0 +1,176 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { asanaServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let attachmentSchema = z.object({
+ attachmentId: z.string(),
+ name: z.string().optional(),
+ resourceType: z.string().optional(),
+ resourceSubtype: z.string().optional(),
+ host: z.string().optional(),
+ createdAt: z.string().optional(),
+ downloadUrl: z.string().nullable().optional(),
+ viewUrl: z.string().nullable().optional(),
+ size: z.number().nullable().optional(),
+ parent: z.any().optional()
+});
+
+let formatAttachment = (attachment: any) => ({
+ attachmentId: attachment.gid,
+ name: attachment.name,
+ resourceType: attachment.resource_type,
+ resourceSubtype: attachment.resource_subtype,
+ host: attachment.host,
+ createdAt: attachment.created_at,
+ downloadUrl: attachment.download_url,
+ viewUrl: attachment.view_url,
+ size: attachment.size,
+ parent: attachment.parent
+});
+
+let requireField = (value: T | undefined | null, label: string, action: string): T => {
+ if (value === undefined || value === null || value === '') {
+ throw asanaServiceError(`${label} is required for "${action}".`);
+ }
+
+ return value;
+};
+
+let validateBase64 = (value: string) => {
+ let normalized = value.trim();
+ let bytes = Buffer.from(normalized, 'base64');
+ let roundTrip = bytes.toString('base64').replace(/=+$/, '');
+ let input = normalized.replace(/=+$/, '');
+
+ if (bytes.length === 0 || roundTrip !== input) {
+ throw asanaServiceError('contentBase64 must be valid non-empty base64 content.');
+ }
+};
+
+export let manageAttachments = SlateTool.create(spec, {
+ name: 'Manage Attachments',
+ key: 'manage_attachments',
+ description: `List, inspect, attach, upload, or delete Asana attachments on tasks, projects, and project briefs. File bytes are accepted only as input for uploads; downloaded file contents are not returned inline.`,
+ instructions: [
+ 'Use action "list" with parentId to list attachment metadata for a task, project, or project brief.',
+ 'Use action "attach_external" with parentId, url, and name to attach an external URL.',
+ 'Use action "upload" with parentId, fileName, and contentBase64 to upload file bytes to Asana.',
+ 'Use action "get" or "delete" with attachmentId for a specific attachment.'
+ ]
+})
+ .input(
+ z.object({
+ action: z
+ .enum(['list', 'get', 'attach_external', 'upload', 'delete'])
+ .describe('Attachment operation to perform.'),
+ parentId: z
+ .string()
+ .optional()
+ .describe('Parent task, project, or project brief GID for list/create actions.'),
+ attachmentId: z.string().optional().describe('Attachment GID for get/delete actions.'),
+ name: z.string().optional().describe('Display name for an external attachment.'),
+ url: z.string().optional().describe('Public URL for an external attachment.'),
+ connectToApp: z
+ .boolean()
+ .optional()
+ .describe('For OAuth external task attachments, connect the current app widget.'),
+ fileName: z.string().optional().describe('File name for upload action.'),
+ contentBase64: z
+ .string()
+ .optional()
+ .describe('Base64-encoded file content for upload action.'),
+ mimeType: z.string().optional().describe('MIME type for uploaded file content.'),
+ limit: z.number().optional().describe('Maximum attachments to return for list action.')
+ })
+ )
+ .output(
+ z.object({
+ attachments: z.array(attachmentSchema).optional(),
+ attachment: attachmentSchema.optional(),
+ deleted: z.boolean().optional(),
+ attachmentCount: z.number().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({ token: ctx.auth.token });
+
+ if (ctx.input.action === 'list') {
+ let parentId = requireField(ctx.input.parentId, 'parentId', ctx.input.action);
+ let result = await client.listAttachments(parentId, { limit: ctx.input.limit });
+ let attachments = (result.data || []).map(formatAttachment);
+
+ return {
+ output: { attachments, attachmentCount: attachments.length },
+ message: `Found **${attachments.length}** attachment(s).`
+ };
+ }
+
+ if (ctx.input.action === 'get') {
+ let attachmentId = requireField(
+ ctx.input.attachmentId,
+ 'attachmentId',
+ ctx.input.action
+ );
+ let attachment = formatAttachment(await client.getAttachment(attachmentId));
+
+ return {
+ output: { attachment, attachmentCount: 1 },
+ message: `Retrieved attachment **${attachment.name ?? attachment.attachmentId}**.`
+ };
+ }
+
+ if (ctx.input.action === 'attach_external') {
+ let parentId = requireField(ctx.input.parentId, 'parentId', ctx.input.action);
+ let name = requireField(ctx.input.name, 'name', ctx.input.action);
+ let url = requireField(ctx.input.url, 'url', ctx.input.action);
+ let attachment = formatAttachment(
+ await client.createExternalAttachment({
+ parentId,
+ name,
+ url,
+ connectToApp: ctx.input.connectToApp
+ })
+ );
+
+ return {
+ output: { attachment, attachmentCount: 1 },
+ message: `Attached external resource **${attachment.name ?? name}**.`
+ };
+ }
+
+ if (ctx.input.action === 'upload') {
+ let parentId = requireField(ctx.input.parentId, 'parentId', ctx.input.action);
+ let fileName = requireField(ctx.input.fileName, 'fileName', ctx.input.action);
+ let contentBase64 = requireField(
+ ctx.input.contentBase64,
+ 'contentBase64',
+ ctx.input.action
+ );
+ validateBase64(contentBase64);
+
+ let attachment = formatAttachment(
+ await client.uploadAttachment({
+ parentId,
+ fileName,
+ contentBase64,
+ mimeType: ctx.input.mimeType
+ })
+ );
+
+ return {
+ output: { attachment, attachmentCount: 1 },
+ message: `Uploaded attachment **${attachment.name ?? fileName}**.`
+ };
+ }
+
+ let attachmentId = requireField(ctx.input.attachmentId, 'attachmentId', ctx.input.action);
+ await client.deleteAttachment(attachmentId);
+
+ return {
+ output: { deleted: true, attachmentCount: 0 },
+ message: `Deleted attachment ${attachmentId}.`
+ };
+ })
+ .build();
diff --git a/integrations/asana/src/tools/manage-custom-fields.ts b/integrations/asana/src/tools/manage-custom-fields.ts
new file mode 100644
index 0000000000..47c5fa1d13
--- /dev/null
+++ b/integrations/asana/src/tools/manage-custom-fields.ts
@@ -0,0 +1,242 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { asanaServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let enumOptionInputSchema = z.object({
+ name: z.string(),
+ color: z.string().optional(),
+ enabled: z.boolean().optional()
+});
+
+let customFieldSchema = z.object({
+ customFieldId: z.string(),
+ name: z.string().optional(),
+ type: z.string().optional(),
+ resourceSubtype: z.string().optional(),
+ description: z.string().nullable().optional(),
+ enumOptions: z.array(z.any()).optional(),
+ precision: z.number().nullable().optional(),
+ format: z.string().nullable().optional(),
+ currencyCode: z.string().nullable().optional(),
+ hasNotificationsEnabled: z.boolean().optional()
+});
+
+let formatCustomField = (field: any) => ({
+ customFieldId: field.gid,
+ name: field.name,
+ type: field.type,
+ resourceSubtype: field.resource_subtype,
+ description: field.description,
+ enumOptions: field.enum_options,
+ precision: field.precision,
+ format: field.format,
+ currencyCode: field.currency_code,
+ hasNotificationsEnabled: field.has_notifications_enabled
+});
+
+let requireField = (value: T | undefined | null, label: string, action: string): T => {
+ if (value === undefined || value === null || value === '') {
+ throw asanaServiceError(`${label} is required for "${action}".`);
+ }
+
+ return value;
+};
+
+let buildCustomFieldData = (input: {
+ name?: string;
+ fieldType?: string;
+ description?: string | null;
+ enumOptions?: z.infer[];
+ precision?: number;
+ format?: string;
+ currencyCode?: string;
+ hasNotificationsEnabled?: boolean;
+}) => {
+ let data: Record = {};
+ if (input.name !== undefined) data.name = input.name;
+ if (input.fieldType !== undefined) data.resource_subtype = input.fieldType;
+ if (input.description !== undefined) data.description = input.description;
+ if (input.enumOptions !== undefined) data.enum_options = input.enumOptions;
+ if (input.precision !== undefined) data.precision = input.precision;
+ if (input.format !== undefined) data.format = input.format;
+ if (input.currencyCode !== undefined) data.currency_code = input.currencyCode;
+ if (input.hasNotificationsEnabled !== undefined) {
+ data.has_notifications_enabled = input.hasNotificationsEnabled;
+ }
+ return data;
+};
+
+export let manageCustomFields = SlateTool.create(spec, {
+ name: 'Manage Custom Fields',
+ key: 'manage_custom_fields',
+ description: `List, inspect, create, update, and maintain Asana custom field metadata for a workspace.`,
+ instructions: [
+ 'Use action "list" with workspaceId to discover custom field GIDs.',
+ 'Use action "get" with customFieldId before setting task customFields values.',
+ 'Use action "create" with workspaceId, name, and fieldType.',
+ 'Use action "create_enum_option" with customFieldId and enumOptionName for enum or multi_enum fields.'
+ ]
+})
+ .input(
+ z.object({
+ action: z
+ .enum(['list', 'get', 'create', 'update', 'create_enum_option', 'update_enum_option'])
+ .describe('Custom field metadata operation to perform.'),
+ workspaceId: z.string().optional().describe('Workspace GID for list/create actions.'),
+ customFieldId: z
+ .string()
+ .optional()
+ .describe('Custom field GID for get/update/enum option actions.'),
+ enumOptionId: z.string().optional().describe('Enum option GID for update_enum_option.'),
+ name: z.string().optional().describe('Custom field name for create/update.'),
+ fieldType: z
+ .enum(['text', 'enum', 'multi_enum', 'number', 'date', 'people'])
+ .optional()
+ .describe('Custom field resource subtype for create.'),
+ description: z
+ .string()
+ .nullable()
+ .optional()
+ .describe('Custom field description, or null to clear when supported.'),
+ enumOptions: z
+ .array(enumOptionInputSchema)
+ .optional()
+ .describe('Enum options for enum or multi_enum field creation.'),
+ enumOptionName: z
+ .string()
+ .optional()
+ .describe('Enum option name for create/update enum option actions.'),
+ enumOptionColor: z
+ .string()
+ .optional()
+ .describe('Enum option color for create/update enum option actions.'),
+ enumOptionEnabled: z
+ .boolean()
+ .optional()
+ .describe('Enable or disable an enum option on update.'),
+ precision: z.number().optional().describe('Decimal precision for number fields.'),
+ format: z.string().optional().describe('Number field format.'),
+ currencyCode: z.string().optional().describe('Currency code for currency fields.'),
+ hasNotificationsEnabled: z
+ .boolean()
+ .optional()
+ .describe('Whether notifications are enabled for custom field changes.'),
+ limit: z.number().optional().describe('Maximum custom fields to return for list action.')
+ })
+ )
+ .output(
+ z.object({
+ customFields: z.array(customFieldSchema).optional(),
+ customField: customFieldSchema.optional(),
+ enumOption: z.any().optional(),
+ customFieldCount: z.number().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({ token: ctx.auth.token });
+
+ if (ctx.input.action === 'list') {
+ let workspaceId = requireField(ctx.input.workspaceId, 'workspaceId', ctx.input.action);
+ let result = await client.listCustomFieldsInWorkspace(workspaceId, {
+ limit: ctx.input.limit
+ });
+ let customFields = (result.data || []).map(formatCustomField);
+
+ return {
+ output: { customFields, customFieldCount: customFields.length },
+ message: `Found **${customFields.length}** custom field(s).`
+ };
+ }
+
+ if (ctx.input.action === 'get') {
+ let customFieldId = requireField(
+ ctx.input.customFieldId,
+ 'customFieldId',
+ ctx.input.action
+ );
+ let customField = formatCustomField(await client.getCustomField(customFieldId));
+
+ return {
+ output: { customField, customFieldCount: 1 },
+ message: `Retrieved custom field **${customField.name ?? customField.customFieldId}**.`
+ };
+ }
+
+ if (ctx.input.action === 'create') {
+ let workspaceId = requireField(ctx.input.workspaceId, 'workspaceId', ctx.input.action);
+ requireField(ctx.input.name, 'name', ctx.input.action);
+ requireField(ctx.input.fieldType, 'fieldType', ctx.input.action);
+
+ let customField = formatCustomField(
+ await client.createCustomField(workspaceId, buildCustomFieldData(ctx.input))
+ );
+
+ return {
+ output: { customField, customFieldCount: 1 },
+ message: `Created custom field **${customField.name ?? customField.customFieldId}**.`
+ };
+ }
+
+ if (ctx.input.action === 'update') {
+ let customFieldId = requireField(
+ ctx.input.customFieldId,
+ 'customFieldId',
+ ctx.input.action
+ );
+ let {
+ resource_subtype: _resourceSubtype,
+ enum_options: _enumOptions,
+ ...data
+ } = buildCustomFieldData(ctx.input);
+
+ if (Object.keys(data).length === 0) {
+ throw asanaServiceError('Provide at least one custom field property to update.');
+ }
+
+ let customField = formatCustomField(await client.updateCustomField(customFieldId, data));
+
+ return {
+ output: { customField, customFieldCount: 1 },
+ message: `Updated custom field **${customField.name ?? customField.customFieldId}**.`
+ };
+ }
+
+ if (ctx.input.action === 'create_enum_option') {
+ let customFieldId = requireField(
+ ctx.input.customFieldId,
+ 'customFieldId',
+ ctx.input.action
+ );
+ let name = requireField(ctx.input.enumOptionName, 'enumOptionName', ctx.input.action);
+ let enumOption = await client.createEnumOption(customFieldId, {
+ name,
+ color: ctx.input.enumOptionColor
+ });
+
+ return {
+ output: { enumOption },
+ message: `Created enum option **${enumOption.name ?? name}**.`
+ };
+ }
+
+ let enumOptionId = requireField(ctx.input.enumOptionId, 'enumOptionId', ctx.input.action);
+ let enumData: Record = {};
+ if (ctx.input.enumOptionName !== undefined) enumData.name = ctx.input.enumOptionName;
+ if (ctx.input.enumOptionColor !== undefined) enumData.color = ctx.input.enumOptionColor;
+ if (ctx.input.enumOptionEnabled !== undefined) {
+ enumData.enabled = ctx.input.enumOptionEnabled;
+ }
+ if (Object.keys(enumData).length === 0) {
+ throw asanaServiceError('Provide at least one enum option property to update.');
+ }
+
+ let enumOption = await client.updateEnumOption(enumOptionId, enumData);
+
+ return {
+ output: { enumOption },
+ message: `Updated enum option **${enumOption.name ?? enumOptionId}**.`
+ };
+ })
+ .build();
diff --git a/integrations/asana/src/tools/manage-project-templates.ts b/integrations/asana/src/tools/manage-project-templates.ts
new file mode 100644
index 0000000000..608e1dd216
--- /dev/null
+++ b/integrations/asana/src/tools/manage-project-templates.ts
@@ -0,0 +1,139 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { asanaServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let projectTemplateSchema = z.object({
+ projectTemplateId: z.string(),
+ name: z.string().optional(),
+ description: z.string().nullable().optional(),
+ color: z.string().nullable().optional(),
+ isPublic: z.boolean().optional(),
+ requestedDates: z.array(z.any()).optional(),
+ team: z.any().optional(),
+ workspace: z.any().optional()
+});
+
+let formatProjectTemplate = (template: any) => ({
+ projectTemplateId: template.gid,
+ name: template.name,
+ description: template.description,
+ color: template.color,
+ isPublic: template.public,
+ requestedDates: template.requested_dates,
+ team: template.team,
+ workspace: template.workspace
+});
+
+let requireField = (value: T | undefined | null, label: string, action: string): T => {
+ if (value === undefined || value === null || value === '') {
+ throw asanaServiceError(`${label} is required for "${action}".`);
+ }
+
+ return value;
+};
+
+export let manageProjectTemplates = SlateTool.create(spec, {
+ name: 'Manage Project Templates',
+ key: 'manage_project_templates',
+ description: `List, inspect, and instantiate Asana project templates.`,
+ instructions: [
+ 'Use action "list" with workspaceId or teamId to discover templates.',
+ 'Use action "get" before instantiating to inspect requestedDates.',
+ 'Use action "instantiate" with projectTemplateId and name; Asana returns an async job.'
+ ]
+})
+ .input(
+ z.object({
+ action: z
+ .enum(['list', 'get', 'instantiate'])
+ .describe('Project template operation to perform.'),
+ workspaceId: z.string().optional().describe('Workspace GID for list action.'),
+ teamId: z.string().optional().describe('Team GID for list or instantiate action.'),
+ projectTemplateId: z
+ .string()
+ .optional()
+ .describe('Project template GID for get/instantiate actions.'),
+ name: z.string().optional().describe('Name for the instantiated project.'),
+ requestedDates: z
+ .array(
+ z.object({
+ gid: z.string().describe('Requested date variable GID from the template.'),
+ value: z.string().describe('Date value in YYYY-MM-DD format.')
+ })
+ )
+ .optional()
+ .describe('Requested date values required by the template.'),
+ public: z
+ .boolean()
+ .optional()
+ .describe('Whether the instantiated project is public when supported.'),
+ limit: z.number().optional().describe('Maximum project templates to return.')
+ })
+ )
+ .output(
+ z.object({
+ projectTemplates: z.array(projectTemplateSchema).optional(),
+ projectTemplate: projectTemplateSchema.optional(),
+ job: z.any().optional(),
+ jobId: z.string().optional(),
+ projectTemplateCount: z.number().optional()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({ token: ctx.auth.token });
+
+ if (ctx.input.action === 'list') {
+ if (!ctx.input.workspaceId && !ctx.input.teamId) {
+ throw asanaServiceError('workspaceId or teamId is required for "list".');
+ }
+
+ let result = await client.listProjectTemplates({
+ workspaceId: ctx.input.workspaceId,
+ teamId: ctx.input.teamId,
+ limit: ctx.input.limit
+ });
+ let projectTemplates = (result.data || []).map(formatProjectTemplate);
+
+ return {
+ output: { projectTemplates, projectTemplateCount: projectTemplates.length },
+ message: `Found **${projectTemplates.length}** project template(s).`
+ };
+ }
+
+ if (ctx.input.action === 'get') {
+ let projectTemplateId = requireField(
+ ctx.input.projectTemplateId,
+ 'projectTemplateId',
+ ctx.input.action
+ );
+ let projectTemplate = formatProjectTemplate(
+ await client.getProjectTemplate(projectTemplateId)
+ );
+
+ return {
+ output: { projectTemplate, projectTemplateCount: 1 },
+ message: `Retrieved project template **${projectTemplate.name ?? projectTemplateId}**.`
+ };
+ }
+
+ let projectTemplateId = requireField(
+ ctx.input.projectTemplateId,
+ 'projectTemplateId',
+ ctx.input.action
+ );
+ let name = requireField(ctx.input.name, 'name', ctx.input.action);
+ let data: Record = { name };
+ if (ctx.input.teamId) data.team = ctx.input.teamId;
+ if (ctx.input.requestedDates) data.requested_dates = ctx.input.requestedDates;
+ if (ctx.input.public !== undefined) data.public = ctx.input.public;
+
+ let job = await client.instantiateProjectTemplate(projectTemplateId, data);
+
+ return {
+ output: { job, jobId: job.gid },
+ message: `Started project template instantiation job ${job.gid ?? ''}.`
+ };
+ })
+ .build();
diff --git a/integrations/asana/src/tools/manage-sections.ts b/integrations/asana/src/tools/manage-sections.ts
index e6d5b940e3..e013b22fb3 100644
--- a/integrations/asana/src/tools/manage-sections.ts
+++ b/integrations/asana/src/tools/manage-sections.ts
@@ -80,3 +80,63 @@ export let createSection = SlateTool.create(spec, {
};
})
.build();
+
+export let updateSection = SlateTool.create(spec, {
+ name: 'Update Section',
+ key: 'update_section',
+ description: `Rename an existing project section.`
+})
+ .input(
+ z.object({
+ sectionId: z.string().describe('Section GID to update'),
+ name: z.string().describe('New section name')
+ })
+ )
+ .output(
+ z.object({
+ sectionId: z.string(),
+ name: z.string()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({ token: ctx.auth.token });
+ let section = await client.updateSection(ctx.input.sectionId, ctx.input.name);
+
+ return {
+ output: {
+ sectionId: section.gid,
+ name: section.name
+ },
+ message: `Updated section **${section.name}** (${section.gid}).`
+ };
+ })
+ .build();
+
+export let deleteSection = SlateTool.create(spec, {
+ name: 'Delete Section',
+ key: 'delete_section',
+ description: `Delete an empty project section. Asana does not allow deleting the last remaining section.`,
+ tags: {
+ destructive: true
+ }
+})
+ .input(
+ z.object({
+ sectionId: z.string().describe('Section GID to delete')
+ })
+ )
+ .output(
+ z.object({
+ deleted: z.boolean()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({ token: ctx.auth.token });
+ await client.deleteSection(ctx.input.sectionId);
+
+ return {
+ output: { deleted: true },
+ message: `Deleted section ${ctx.input.sectionId}.`
+ };
+ })
+ .build();
diff --git a/integrations/asana/src/tools/typeahead-search.ts b/integrations/asana/src/tools/typeahead-search.ts
new file mode 100644
index 0000000000..40df832e05
--- /dev/null
+++ b/integrations/asana/src/tools/typeahead-search.ts
@@ -0,0 +1,67 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { spec } from '../spec';
+
+export let typeaheadSearch = SlateTool.create(spec, {
+ name: 'Typeahead Search',
+ key: 'typeahead_search',
+ description: `Search Asana workspace objects with the low-latency typeahead endpoint. Use this to discover project, project template, portfolio, tag, task, user, or custom field GIDs for other tools.`,
+ tags: {
+ readOnly: true
+ }
+})
+ .input(
+ z.object({
+ workspaceId: z.string().describe('Workspace GID to search in.'),
+ resourceType: z
+ .enum([
+ 'custom_field',
+ 'project',
+ 'project_template',
+ 'portfolio',
+ 'tag',
+ 'task',
+ 'user'
+ ])
+ .describe('Type of Asana resource to search for.'),
+ query: z
+ .string()
+ .optional()
+ .describe('Search text. Omit or pass an empty string for relevant defaults.'),
+ count: z.number().optional().describe('Maximum number of results to return.')
+ })
+ )
+ .output(
+ z.object({
+ results: z.array(
+ z.object({
+ id: z.string(),
+ name: z.string().optional(),
+ resourceType: z.string().optional()
+ })
+ ),
+ resultCount: z.number()
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Client({ token: ctx.auth.token });
+ let result = await client.typeahead(
+ ctx.input.workspaceId,
+ ctx.input.resourceType,
+ ctx.input.query ?? '',
+ ctx.input.count
+ );
+
+ let results = (result.data || []).map((item: any) => ({
+ id: item.gid,
+ name: item.name,
+ resourceType: item.resource_type
+ }));
+
+ return {
+ output: { results, resultCount: results.length },
+ message: `Found **${results.length}** typeahead result(s).`
+ };
+ })
+ .build();
diff --git a/integrations/asana/src/tools/update-task.ts b/integrations/asana/src/tools/update-task.ts
index 86a17cbc53..5b09e7690c 100644
--- a/integrations/asana/src/tools/update-task.ts
+++ b/integrations/asana/src/tools/update-task.ts
@@ -76,6 +76,10 @@ export let updateTask = SlateTool.create(spec, {
.array(z.string())
.optional()
.describe('Task GIDs that depend on this task'),
+ removeDependentIds: z
+ .array(z.string())
+ .optional()
+ .describe('Dependent task GIDs to remove'),
parentId: z
.string()
.nullable()
@@ -149,6 +153,9 @@ export let updateTask = SlateTool.create(spec, {
if (ctx.input.addDependentIds?.length) {
operations.push(client.addDependentsToTask(taskId, ctx.input.addDependentIds));
}
+ if (ctx.input.removeDependentIds?.length) {
+ operations.push(client.removeDependentsFromTask(taskId, ctx.input.removeDependentIds));
+ }
if (ctx.input.parentId !== undefined) {
operations.push(client.setParentForTask(taskId, ctx.input.parentId));
}
diff --git a/integrations/asana/src/triggers/task-changes-webhook.ts b/integrations/asana/src/triggers/task-changes-webhook.ts
index 4667fe3790..1f9a8910ca 100644
--- a/integrations/asana/src/triggers/task-changes-webhook.ts
+++ b/integrations/asana/src/triggers/task-changes-webhook.ts
@@ -2,6 +2,7 @@ import { createHmac, timingSafeEqual } from 'crypto';
import { SlateTrigger } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { asanaServiceError } from '../lib/errors';
import { spec } from '../spec';
function verifyAsanaSignature(
@@ -49,7 +50,7 @@ export let taskChangesWebhook = SlateTrigger.create(spec, {
.webhook({
autoRegisterWebhook: async ctx => {
if (!ctx.config.webhookProjectId) {
- throw new Error(
+ throw asanaServiceError(
'config.webhookProjectId is required to auto-register Asana webhooks (project GID that will receive task events).'
);
}
diff --git a/integrations/asana/vitest.config.ts b/integrations/asana/vitest.config.ts
new file mode 100644
index 0000000000..0b05bc07ad
--- /dev/null
+++ b/integrations/asana/vitest.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+ test: {
+ include: ['src/**/*.test.ts']
+ }
+});
diff --git a/integrations/assembly-ai/README.md b/integrations/assembly-ai/README.md
index 90bf04bd3c..1335a8fdaa 100644
--- a/integrations/assembly-ai/README.md
+++ b/integrations/assembly-ai/README.md
@@ -1,9 +1,17 @@
#
Assembly Ai
-Transcribe pre-recorded and live audio/video to text with support for 99+ languages, speaker diarization, and multichannel audio. Apply audio intelligence models to extract summaries, sentiment analysis, entity detection, topic detection, key phrases, and content moderation from transcripts. Redact personally identifiable information from text and audio. Generate SRT/VTT subtitles and segment transcripts into paragraphs, sentences, or auto-chapters. Stream real-time speech-to-text via WebSocket connections. Upload audio/video files for processing. Manage and delete transcripts. Access an LLM gateway to apply large language models (Claude, GPT, Gemini) to transcribed speech data for summarization, Q&A, and custom analysis. Translate transcripts across 99+ languages. Receive webhook notifications when transcriptions complete or fail.
+Transcribe pre-recorded and live audio/video to text with support for 99+ languages, speaker diarization, code switching, and multichannel audio. Apply audio intelligence models to extract sentiment analysis, entity detection, topic detection, key phrases, and content moderation from transcripts. Redact personally identifiable information from text and audio. Generate SRT/VTT subtitles and segment transcripts into paragraphs or sentences. Upload audio/video files for processing. Manage and delete transcripts. Use AssemblyAI's LLM Gateway for transcript-aware summarization, Q&A, and custom analysis, and Speech Understanding for transcript translation, speaker identification, and custom formatting. Stream real-time speech-to-text via WebSocket connections with temporary tokens. Receive webhook notifications when transcriptions complete or fail.
## Tools
+### Create Chat Completion
+
+Create a completion with AssemblyAI's LLM Gateway. Use prompt for a simple request, or messages for a conversation. Provide transcriptId to inject an AssemblyAI transcript into the first {{ transcript }} tag in the prompt.
+
+### Create Speech Understanding
+
+Apply AssemblyAI Speech Understanding to a completed transcript. Supports translation, advanced speaker identification, and custom formatting in one request.
+
### Create Streaming Token
Generate a temporary authentication token for use with AssemblyAI's real-time streaming speech-to-text WebSocket API. Use this to securely authenticate client-side streaming without exposing your main API key. Each token is single-use and valid for one streaming session.
@@ -14,7 +22,7 @@ Delete a transcript by removing its data and marking it as deleted. The transcri
### Get Redacted Audio
-Retrieve the URL for a PII-redacted audio file. The original transcription must have been submitted with PII audio redaction enabled (\
+Retrieve the URL for a PII-redacted audio file. The original transcription must have been submitted with PII audio redaction enabled.
### Get Subtitles
@@ -28,10 +36,6 @@ Retrieve a completed transcript's text segmented into sentences or paragraphs. T
Retrieve a transcript by its ID. Returns the full transcript object including text, words with timestamps, speaker labels, and any enabled audio intelligence results (summary, sentiment, entities, topics, chapters, content safety, key phrases). Use this to poll for completion after submitting a transcription, or to retrieve results of a completed transcript.
-### LeMUR Task
-
-Apply a large language model to one or more transcripts using AssemblyAI's LeMUR framework. Submit a custom prompt along with transcript IDs or raw text input, and receive an LLM-generated response. Use this for summarizing transcripts, extracting insights, answering questions about audio content, generating action items, or any custom analysis task. Supports multiple LLM providers including Claude, GPT, and Gemini models.
-
### List Transcripts
List transcripts with pagination and optional filters. Returns transcript summaries sorted from newest to oldest. Supports filtering by status and creation date, and cursor-based pagination using before/after IDs.
@@ -42,7 +46,11 @@ Search through a completed transcript for specific keywords. You can search for
### Submit Transcription
-Submit an audio or video file for asynchronous transcription. Provide a publicly accessible URL to the media file. Optionally enable audio intelligence features like summarization, sentiment analysis, entity detection, topic detection, content moderation, key phrases, auto chapters, and PII redaction. Returns the transcript object with a status of "queued" — poll using the **Get Transcript** tool to check for completion.
+Submit an audio or video file for asynchronous transcription. Provide a publicly accessible media URL or an AssemblyAI upload URL from Upload Media File. Optionally enable current transcription features like code switching, speech model priority routing, keyterms prompting, sentiment analysis, entity detection, topic detection, content moderation, and PII redaction. Returns the transcript object with a status of "queued" — poll using the **Get Transcript** tool to check for completion.
+
+### Upload Media File
+
+Upload local audio or video bytes to AssemblyAI and receive an AssemblyAI-only upload URL. Use the returned uploadUrl as audioUrl in Submit Transcription when the media is not already publicly accessible.
## License
diff --git a/integrations/assembly-ai/docs/SPEC.md b/integrations/assembly-ai/docs/SPEC.md
index 164317c170..86eb8d1038 100644
--- a/integrations/assembly-ai/docs/SPEC.md
+++ b/integrations/assembly-ai/docs/SPEC.md
@@ -2,7 +2,7 @@
## Overview
-AssemblyAI is a Speech AI platform that provides APIs for speech-to-text transcription (both async and real-time streaming), audio intelligence models (summarization, sentiment analysis, entity detection, etc.), and an LLM Gateway for applying large language models to transcribed speech data. It offers models for converting audio files, video files, and live speech into text, an LLM Gateway framework for applying LLMs to spoken data, and models for interpreting audio for business and personal workflows.
+AssemblyAI is a Speech AI platform that provides APIs for speech-to-text transcription (both async and real-time streaming), audio intelligence models (sentiment analysis, entity detection, topic detection, key phrases, content moderation, PII redaction, etc.), Speech Understanding, and an LLM Gateway for applying large language models to transcribed speech data. It offers models for converting audio files, video files, and live speech into text, current LLM Gateway endpoints for transcript-aware reasoning, and models for interpreting audio for business and personal workflows.
## Authentication
@@ -36,8 +36,8 @@ Transcribe pre-recorded audio and video files by submitting a URL or uploading t
- **Speaker diarization**: Identifies and labels different speakers within audio.
- **Advanced Speaker Identification**: Maps speaker clusters to real names or roles via the Speech Understanding API, using audio context and optional known values you provide.
- **Multichannel transcription**: Transcribe each audio channel separately.
-- **Custom vocabulary / word boost**: Provide a list of specific words or terms to improve recognition accuracy.
-- **Speech model selection**: Choose between different models (e.g., Universal, Slam-1) depending on accuracy and language needs.
+- **Keyterms prompting**: Provide a list of domain-specific words or phrases to improve recognition accuracy.
+- **Speech model selection**: Provide a priority list of speech models (for example Universal-3 Pro and Universal-2) depending on accuracy and language needs.
- **Subtitle/caption generation**: Get transcripts formatted as SRT or VTT subtitles.
- **Paragraph and sentence segmentation**: Retrieve transcripts split into semantically meaningful paragraphs or sentences.
@@ -52,14 +52,12 @@ Transcribe live audio streams in real-time via WebSocket connections. Provides p
### Audio Intelligence
-A suite of models that run alongside transcription to extract insights, including: summarization, content moderation, sentiment analysis, entity detection, topic detection, auto chapters, key phrases, and PII redaction.
+A suite of models that run alongside transcription to extract insights, including: content moderation, sentiment analysis, entity detection, topic detection, key phrases, and PII redaction. Flexible summaries and chapters should be generated through LLM Gateway with transcript injection rather than deprecated transcript-time summary parameters.
-- **Summarization**: Choose summary types (bullets, bullets_verbose, gist, headline, paragraph) and models (informative, conversational, catchy).
- **Sentiment Analysis**: Detects positive, negative, and neutral sentiments in speech segments.
- **Entity Detection**: Supports 44 entity types to automatically identify and categorize key information in transcripts with timestamps.
- **Topic Detection**: Predicts topics spoken in audio using the standardized IAB Taxonomy.
- **Content Moderation**: Detects sensitive content with confidence and severity scores.
-- **Auto Chapters**: Automatically segments transcripts into chapters with summaries.
- **Key Phrases**: Extracts key phrases from the transcript.
- **PII Redaction**: Automatically identifies and removes personally identifiable information from transcripts. Supports text redaction (hash or entity name substitution) and audio redaction (beeping out sensitive data). Configurable PII policies (names, credit cards, SSNs, etc.). Available in multiple languages.
@@ -67,14 +65,14 @@ A suite of models that run alongside transcription to extract insights, includin
A unified interface that allows you to connect with multiple LLM providers including Claude, GPT, and Gemini to build sophisticated AI applications through a single API.
-- Provides access to 15+ models with support for basic chat completions, multi-turn conversations, tool/function calling, and agentic workflows.
-- Can be used standalone or combined with transcripts to apply LLMs to spoken data (summarization, Q&A, custom analysis).
+- Provides access to multiple models with support for chat completions, multi-turn conversations, tool/function calling, and agentic workflows.
+- Can be used standalone or combined with transcripts by injecting transcript text into prompts for summarization, Q&A, custom analysis, and chapter generation.
- Unified billing and usage tracking across all providers.
-- LLM Gateway is not currently supported in the EU.
+- Uses the `https://llm-gateway.assemblyai.com` base URL in the default region and `https://llm-gateway.eu.assemblyai.com` for EU data residency.
### Speech Understanding
-Pre-built, LLM-powered features that transform raw transcripts into structured, actionable data. Includes translation (99+ languages), advanced speaker identification, text normalization (dates, phone numbers, emails), and customizable summarization.
+Pre-built, LLM-powered features that transform completed transcripts into structured, actionable data. Includes translation, advanced speaker identification, and custom formatting for dates, phone numbers, and emails.
### File Upload
diff --git a/integrations/assembly-ai/package.json b/integrations/assembly-ai/package.json
index 65cd1b96e4..d8c7b3dd27 100644
--- a/integrations/assembly-ai/package.json
+++ b/integrations/assembly-ai/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
- "typescript": "^5"
+ "@slates/test": "1.0.0-rc.9",
+ "typescript": "^5",
+ "vitest": "^3.1.2"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.6"
}
diff --git a/integrations/assembly-ai/slate.json b/integrations/assembly-ai/slate.json
index d905b9b3ed..1480438b0c 100644
--- a/integrations/assembly-ai/slate.json
+++ b/integrations/assembly-ai/slate.json
@@ -1,6 +1,6 @@
{
"name": "@metorial/assemblyai",
- "description": "Transcribe pre-recorded and live audio/video to text with support for 99+ languages, speaker diarization, and multichannel audio. Apply audio intelligence models to extract summaries, sentiment analysis, entity detection, topic detection, key phrases, and content moderation from transcripts. Redact personally identifiable information from text and audio. Generate SRT/VTT subtitles and segment transcripts into paragraphs, sentences, or auto-chapters. Stream real-time speech-to-text via WebSocket connections. Upload audio/video files for processing. Manage and delete transcripts. Access an LLM gateway to apply large language models (Claude, GPT, Gemini) to transcribed speech data for summarization, Q&A, and custom analysis. Translate transcripts across 99+ languages. Receive webhook notifications when transcriptions complete or fail.",
+ "description": "Transcribe pre-recorded and live audio/video to text with support for 99+ languages, code switching, speaker diarization, and multichannel audio. Apply audio intelligence models to extract sentiment analysis, entity detection, topic detection, key phrases, and content moderation from transcripts. Redact personally identifiable information from text and audio. Generate SRT/VTT subtitles and segment transcripts into paragraphs or sentences. Upload audio/video files for processing. Manage and delete transcripts. Use AssemblyAI's LLM Gateway for transcript-aware summarization, Q&A, and custom analysis, and Speech Understanding for transcript translation, speaker identification, and custom formatting. Stream real-time speech-to-text via WebSocket connections with temporary tokens. Receive webhook notifications when transcriptions complete or fail.",
"categories": [
"apis-and-http-requests",
"language-translation",
diff --git a/integrations/assembly-ai/src/index.ts b/integrations/assembly-ai/src/index.ts
index 14268a5d05..9cdb8ad2a7 100644
--- a/integrations/assembly-ai/src/index.ts
+++ b/integrations/assembly-ai/src/index.ts
@@ -1,22 +1,25 @@
import { Slate } from 'slates';
import { spec } from './spec';
import {
+ createChatCompletion,
+ createSpeechUnderstanding,
createStreamingToken,
deleteTranscript,
getRedactedAudio,
getSubtitles,
getTranscript,
getTranscriptText,
- lemurTask,
listTranscripts,
searchTranscript,
- submitTranscription
+ submitTranscription,
+ uploadMediaFile
} from './tools';
import { inboundWebhook, transcriptionCompleted } from './triggers';
export let provider = Slate.create({
spec,
tools: [
+ uploadMediaFile,
submitTranscription,
getTranscript,
listTranscripts,
@@ -25,7 +28,8 @@ export let provider = Slate.create({
getSubtitles,
searchTranscript,
getRedactedAudio,
- lemurTask,
+ createChatCompletion,
+ createSpeechUnderstanding,
createStreamingToken
],
triggers: [inboundWebhook, transcriptionCompleted]
diff --git a/integrations/assembly-ai/src/lib/client.ts b/integrations/assembly-ai/src/lib/client.ts
index b2f77ab1fc..6ff32640da 100644
--- a/integrations/assembly-ai/src/lib/client.ts
+++ b/integrations/assembly-ai/src/lib/client.ts
@@ -1,4 +1,6 @@
+import { Buffer } from 'node:buffer';
import { createAxios } from 'slates';
+import { assemblyAiApiError } from './errors';
let getBaseUrl = (region: string) => {
if (region === 'eu') {
@@ -14,6 +16,13 @@ let getStreamingBaseUrl = (region: string) => {
return 'https://streaming.assemblyai.com';
};
+let getLlmGatewayBaseUrl = (region: string) => {
+ if (region === 'eu') {
+ return 'https://llm-gateway.eu.assemblyai.com';
+ }
+ return 'https://llm-gateway.assemblyai.com';
+};
+
export interface TranscribeParams {
audioUrl: string;
languageCode?: string;
@@ -21,6 +30,7 @@ export interface TranscribeParams {
languageDetection?: boolean;
languageConfidenceThreshold?: number;
speechModel?: string;
+ speechModels?: string[];
punctuate?: boolean;
formatText?: boolean;
disfluencies?: boolean;
@@ -38,6 +48,7 @@ export interface TranscribeParams {
contentSafety?: boolean;
contentSafetyConfidence?: number;
iabCategories?: boolean;
+ keytermsPrompt?: string[];
summarization?: boolean;
summaryModel?: string;
summaryType?: string;
@@ -46,11 +57,16 @@ export interface TranscribeParams {
redactPiiAudioQuality?: string;
redactPiiPolicies?: string[];
redactPiiSub?: string;
+ redactPiiReturnUnredacted?: boolean;
+ redactStaticEntities?: Record;
customSpelling?: Array<{ from: string[]; to: string }>;
audioStartFrom?: number;
audioEndAt?: number;
speechThreshold?: number;
prompt?: string;
+ temperature?: number;
+ domain?: string;
+ removeAudioTags?: string;
}
export interface ListTranscriptsParams {
@@ -62,15 +78,38 @@ export interface ListTranscriptsParams {
throttledOnly?: boolean;
}
-export interface LemurTaskParams {
- transcriptIds?: string[];
- inputText?: string;
- prompt: string;
- finalModel?: string;
- maxOutputSize?: number;
+export interface ChatCompletionParams {
+ model: string;
+ messages?: Array<{ role: string; content: string }>;
+ prompt?: string;
+ transcriptId?: string;
+ modelRegion?: 'global';
+ maxTokens?: number;
temperature?: number;
}
+export interface SpeechUnderstandingSpeaker {
+ name?: string;
+ role?: string;
+ description?: string;
+ company?: string;
+ title?: string;
+}
+
+export interface SpeechUnderstandingParams {
+ transcriptId: string;
+ targetLanguages?: string[];
+ formal?: boolean;
+ matchOriginalUtterance?: boolean;
+ speakerType?: string;
+ speakers?: SpeechUnderstandingSpeaker[];
+ customFormatting?: {
+ date?: string;
+ phoneNumber?: string;
+ email?: string;
+ };
+}
+
export class Client {
private token: string;
private region: string;
@@ -100,6 +139,35 @@ export class Client {
});
}
+ private get llmGatewayAxios() {
+ return createAxios({
+ baseURL: getLlmGatewayBaseUrl(this.region),
+ headers: {
+ Authorization: this.token,
+ 'Content-Type': 'application/json'
+ }
+ });
+ }
+
+ private async request(operation: string, run: () => Promise<{ data: T }>): Promise {
+ try {
+ let response = await run();
+ return response.data;
+ } catch (error) {
+ throw assemblyAiApiError(error, operation);
+ }
+ }
+
+ async uploadMediaFile(contentBase64: string): Promise {
+ return this.request('upload media file', () =>
+ this.axios.post('/v2/upload', Buffer.from(contentBase64, 'base64'), {
+ headers: {
+ 'Content-Type': 'application/octet-stream'
+ }
+ })
+ );
+ }
+
async submitTranscription(params: TranscribeParams): Promise {
let body: Record = {
audio_url: params.audioUrl
@@ -112,6 +180,7 @@ export class Client {
if (params.languageConfidenceThreshold !== undefined)
body.language_confidence_threshold = params.languageConfidenceThreshold;
if (params.speechModel !== undefined) body.speech_model = params.speechModel;
+ if (params.speechModels !== undefined) body.speech_models = params.speechModels;
if (params.punctuate !== undefined) body.punctuate = params.punctuate;
if (params.formatText !== undefined) body.format_text = params.formatText;
if (params.disfluencies !== undefined) body.disfluencies = params.disfluencies;
@@ -134,6 +203,7 @@ export class Client {
if (params.contentSafetyConfidence !== undefined)
body.content_safety_confidence = params.contentSafetyConfidence;
if (params.iabCategories !== undefined) body.iab_categories = params.iabCategories;
+ if (params.keytermsPrompt !== undefined) body.keyterms_prompt = params.keytermsPrompt;
if (params.summarization !== undefined) body.summarization = params.summarization;
if (params.summaryModel !== undefined) body.summary_model = params.summaryModel;
if (params.summaryType !== undefined) body.summary_type = params.summaryType;
@@ -144,6 +214,10 @@ export class Client {
if (params.redactPiiPolicies !== undefined)
body.redact_pii_policies = params.redactPiiPolicies;
if (params.redactPiiSub !== undefined) body.redact_pii_sub = params.redactPiiSub;
+ if (params.redactPiiReturnUnredacted !== undefined)
+ body.redact_pii_return_unredacted = params.redactPiiReturnUnredacted;
+ if (params.redactStaticEntities !== undefined)
+ body.redact_static_entities = params.redactStaticEntities;
if (params.customSpelling !== undefined) {
body.custom_spelling = params.customSpelling.map(s => ({
from: s.from,
@@ -154,14 +228,17 @@ export class Client {
if (params.audioEndAt !== undefined) body.audio_end_at = params.audioEndAt;
if (params.speechThreshold !== undefined) body.speech_threshold = params.speechThreshold;
if (params.prompt !== undefined) body.prompt = params.prompt;
+ if (params.temperature !== undefined) body.temperature = params.temperature;
+ if (params.domain !== undefined) body.domain = params.domain;
+ if (params.removeAudioTags !== undefined) body.remove_audio_tags = params.removeAudioTags;
- let response = await this.axios.post('/v2/transcript', body);
- return response.data;
+ return this.request('submit transcription', () => this.axios.post('/v2/transcript', body));
}
async getTranscript(transcriptId: string): Promise {
- let response = await this.axios.get(`/v2/transcript/${transcriptId}`);
- return response.data;
+ return this.request('get transcript', () =>
+ this.axios.get(`/v2/transcript/${transcriptId}`)
+ );
}
async listTranscripts(params?: ListTranscriptsParams): Promise {
@@ -173,23 +250,27 @@ export class Client {
if (params?.afterId !== undefined) queryParams.after_id = params.afterId;
if (params?.throttledOnly !== undefined) queryParams.throttled_only = params.throttledOnly;
- let response = await this.axios.get('/v2/transcript', { params: queryParams });
- return response.data;
+ return this.request('list transcripts', () =>
+ this.axios.get('/v2/transcript', { params: queryParams })
+ );
}
async deleteTranscript(transcriptId: string): Promise {
- let response = await this.axios.delete(`/v2/transcript/${transcriptId}`);
- return response.data;
+ return this.request('delete transcript', () =>
+ this.axios.delete(`/v2/transcript/${transcriptId}`)
+ );
}
async getSentences(transcriptId: string): Promise {
- let response = await this.axios.get(`/v2/transcript/${transcriptId}/sentences`);
- return response.data;
+ return this.request('get transcript sentences', () =>
+ this.axios.get(`/v2/transcript/${transcriptId}/sentences`)
+ );
}
async getParagraphs(transcriptId: string): Promise {
- let response = await this.axios.get(`/v2/transcript/${transcriptId}/paragraphs`);
- return response.data;
+ return this.request('get transcript paragraphs', () =>
+ this.axios.get(`/v2/transcript/${transcriptId}/paragraphs`)
+ );
}
async getSubtitles(
@@ -199,41 +280,25 @@ export class Client {
): Promise {
let params: Record = {};
if (charsPerCaption !== undefined) params.chars_per_caption = charsPerCaption;
- let response = await this.axios.get(`/v2/transcript/${transcriptId}/${format}`, {
- params
- });
- return response.data;
+ return this.request('get subtitles', () =>
+ this.axios.get(`/v2/transcript/${transcriptId}/${format}`, {
+ params
+ })
+ );
}
async wordSearch(transcriptId: string, words: string[]): Promise {
- let response = await this.axios.get(`/v2/transcript/${transcriptId}/word-search`, {
- params: { words: words.join(',') }
- });
- return response.data;
+ return this.request('word search', () =>
+ this.axios.get(`/v2/transcript/${transcriptId}/word-search`, {
+ params: { words: words.join(',') }
+ })
+ );
}
async getRedactedAudio(transcriptId: string): Promise {
- let response = await this.axios.get(`/v2/transcript/${transcriptId}/redacted-audio`);
- return response.data;
- }
-
- async lemurTask(params: LemurTaskParams): Promise {
- let body: Record = {
- prompt: params.prompt
- };
- if (params.transcriptIds !== undefined) body.transcript_ids = params.transcriptIds;
- if (params.inputText !== undefined) body.input_text = params.inputText;
- if (params.finalModel !== undefined) body.final_model = params.finalModel;
- if (params.maxOutputSize !== undefined) body.max_output_size = params.maxOutputSize;
- if (params.temperature !== undefined) body.temperature = params.temperature;
-
- let response = await this.axios.post('/lemur/v3/generate/task', body);
- return response.data;
- }
-
- async lemurPurge(requestId: string): Promise {
- let response = await this.axios.delete(`/lemur/v3/${requestId}`);
- return response.data;
+ return this.request('get redacted audio', () =>
+ this.axios.get(`/v2/transcript/${transcriptId}/redacted-audio`)
+ );
}
async createStreamingToken(
@@ -246,7 +311,71 @@ export class Client {
if (maxSessionDurationSeconds !== undefined) {
params.max_session_duration_seconds = maxSessionDurationSeconds;
}
- let response = await this.streamingAxios.get('/v3/token', { params });
- return response.data;
+ return this.request('create streaming token', () =>
+ this.streamingAxios.get('/v3/token', { params })
+ );
+ }
+
+ async createChatCompletion(params: ChatCompletionParams): Promise {
+ let body: Record = {
+ model: params.model
+ };
+
+ if (params.messages !== undefined) body.messages = params.messages;
+ if (params.prompt !== undefined) body.prompt = params.prompt;
+ if (params.transcriptId !== undefined) body.transcript_id = params.transcriptId;
+ if (params.modelRegion !== undefined) body.model_region = params.modelRegion;
+ if (params.maxTokens !== undefined) body.max_tokens = params.maxTokens;
+ if (params.temperature !== undefined) body.temperature = params.temperature;
+
+ return this.request('create chat completion', () =>
+ this.llmGatewayAxios.post('/v1/chat/completions', body)
+ );
+ }
+
+ async createSpeechUnderstanding(params: SpeechUnderstandingParams): Promise {
+ let request: Record = {};
+
+ if (params.targetLanguages !== undefined) {
+ request.translation = {
+ target_languages: params.targetLanguages
+ };
+ if (params.formal !== undefined) request.translation.formal = params.formal;
+ if (params.matchOriginalUtterance !== undefined) {
+ request.translation.match_original_utterance = params.matchOriginalUtterance;
+ }
+ }
+
+ if (params.speakerType !== undefined || params.speakers !== undefined) {
+ request.speaker_identification = {};
+ if (params.speakerType !== undefined) {
+ request.speaker_identification.speaker_type = params.speakerType;
+ }
+ if (params.speakers !== undefined) {
+ request.speaker_identification.speakers = params.speakers;
+ }
+ }
+
+ if (params.customFormatting !== undefined) {
+ request.custom_formatting = {};
+ if (params.customFormatting.date !== undefined) {
+ request.custom_formatting.date = params.customFormatting.date;
+ }
+ if (params.customFormatting.phoneNumber !== undefined) {
+ request.custom_formatting.phone_number = params.customFormatting.phoneNumber;
+ }
+ if (params.customFormatting.email !== undefined) {
+ request.custom_formatting.email = params.customFormatting.email;
+ }
+ }
+
+ return this.request('create speech understanding', () =>
+ this.llmGatewayAxios.post('/v1/understanding', {
+ transcript_id: params.transcriptId,
+ speech_understanding: {
+ request
+ }
+ })
+ );
}
}
diff --git a/integrations/assembly-ai/src/lib/errors.ts b/integrations/assembly-ai/src/lib/errors.ts
new file mode 100644
index 0000000000..006de1077a
--- /dev/null
+++ b/integrations/assembly-ai/src/lib/errors.ts
@@ -0,0 +1,75 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null;
+
+let addMessage = (messages: string[], value: unknown) => {
+ if (typeof value !== 'string') return;
+ let trimmed = value.trim();
+ if (trimmed && !messages.includes(trimmed)) {
+ messages.push(trimmed);
+ }
+};
+
+let extractAssemblyAiMessage = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let data = response?.data;
+ let messages: string[] = [];
+
+ if (isRecord(data)) {
+ addMessage(messages, data.error);
+ addMessage(messages, data.message);
+ addMessage(messages, data.detail);
+
+ if (isRecord(data.error)) {
+ addMessage(messages, data.error.message);
+ addMessage(messages, data.error.type);
+ }
+ } else {
+ addMessage(messages, data);
+ }
+
+ if (messages.length > 0) {
+ return messages.join(' - ');
+ }
+
+ if (error instanceof Error && error.message) {
+ return error.message;
+ }
+
+ return 'Unknown error';
+};
+
+export let assemblyAiServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let assemblyAiApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) {
+ return error;
+ }
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let status = response?.status;
+ let statusLabel =
+ status !== undefined
+ ? `HTTP ${status}${response?.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+
+ let serviceError = assemblyAiServiceError(
+ `AssemblyAI API ${operation} failed: ${statusLabel}${extractAssemblyAiMessage(error)}`
+ );
+ serviceError.data.reason = 'assembly_ai_api_error';
+ serviceError.data.upstreamStatus = status;
+
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+
+ return serviceError;
+};
diff --git a/integrations/assembly-ai/src/tools.schema.test.ts b/integrations/assembly-ai/src/tools.schema.test.ts
new file mode 100644
index 0000000000..b52199d76f
--- /dev/null
+++ b/integrations/assembly-ai/src/tools.schema.test.ts
@@ -0,0 +1,4 @@
+import { describeMcpCompatibleToolSchemas } from '@slates/test';
+import { provider } from './index';
+
+describeMcpCompatibleToolSchemas('AssemblyAI tool input schemas', provider.actions);
diff --git a/integrations/assembly-ai/src/tools/create-chat-completion.ts b/integrations/assembly-ai/src/tools/create-chat-completion.ts
new file mode 100644
index 0000000000..4d8403453c
--- /dev/null
+++ b/integrations/assembly-ai/src/tools/create-chat-completion.ts
@@ -0,0 +1,130 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { assemblyAiServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let messageSchema = z.object({
+ role: z
+ .enum(['system', 'user', 'assistant', 'tool'])
+ .describe('Message role for the LLM Gateway request.'),
+ content: z.string().describe('Message content.')
+});
+
+export let createChatCompletion = SlateTool.create(spec, {
+ name: 'Create Chat Completion',
+ key: 'create_chat_completion',
+ description: `Create a completion with AssemblyAI's LLM Gateway. Use prompt for a simple request, or messages for a conversation. Provide transcriptId to inject an AssemblyAI transcript into the first {{ transcript }} tag in the prompt.`,
+ instructions: [
+ 'Provide either prompt or messages.',
+ 'To analyze a transcript, set transcriptId and include {{ transcript }} in the prompt.'
+ ],
+ tags: {
+ destructive: false,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ model: z
+ .string()
+ .describe('LLM Gateway model ID, such as "claude-sonnet-4-5-20250929".'),
+ prompt: z
+ .string()
+ .optional()
+ .describe('Simple prompt. Use {{ transcript }} to inject transcriptId text.'),
+ messages: z
+ .array(messageSchema)
+ .optional()
+ .describe('Conversation messages. Alternative to prompt.'),
+ transcriptId: z
+ .string()
+ .optional()
+ .describe(
+ 'AssemblyAI transcript ID whose text replaces the first {{ transcript }} tag in prompt.'
+ ),
+ modelRegion: z
+ .enum(['global'])
+ .optional()
+ .describe('Route supported models to the provider global endpoint.'),
+ maxTokens: z
+ .number()
+ .int()
+ .min(1)
+ .optional()
+ .describe('Maximum output tokens. Defaults to AssemblyAI LLM Gateway default.'),
+ temperature: z
+ .number()
+ .min(0)
+ .max(2)
+ .optional()
+ .describe('Controls randomness. Lower values are more deterministic.')
+ })
+ )
+ .output(
+ z.object({
+ requestId: z.string().describe('AssemblyAI LLM Gateway request ID.'),
+ content: z.string().optional().nullable().describe('First response message content.'),
+ choices: z
+ .array(
+ z.object({
+ role: z.string().optional().nullable(),
+ content: z.string().optional().nullable(),
+ finishReason: z.string().optional().nullable()
+ })
+ )
+ .describe('Returned completion choices.'),
+ usage: z
+ .object({
+ inputTokens: z.number().optional(),
+ outputTokens: z.number().optional(),
+ totalTokens: z.number().optional()
+ })
+ .optional()
+ .describe('Token usage when returned by the LLM Gateway.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ if (!ctx.input.prompt && !ctx.input.messages?.length) {
+ throw assemblyAiServiceError('Provide either prompt or messages.');
+ }
+
+ if (ctx.input.prompt && ctx.input.messages?.length) {
+ throw assemblyAiServiceError('Provide either prompt or messages, not both.');
+ }
+
+ if (ctx.input.transcriptId && !ctx.input.prompt?.includes('{{ transcript }}')) {
+ throw assemblyAiServiceError(
+ 'prompt must include {{ transcript }} when transcriptId is provided.'
+ );
+ }
+
+ let client = new Client({
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ let result = await client.createChatCompletion(ctx.input);
+ let choices = (result.choices || []).map((choice: any) => ({
+ role: choice.message?.role ?? null,
+ content: choice.message?.content ?? null,
+ finishReason: choice.finish_reason ?? null
+ }));
+
+ return {
+ output: {
+ requestId: result.request_id,
+ content: choices[0]?.content ?? null,
+ choices,
+ usage: result.usage
+ ? {
+ inputTokens: result.usage.input_tokens,
+ outputTokens: result.usage.output_tokens,
+ totalTokens: result.usage.total_tokens
+ }
+ : undefined
+ },
+ message: `Created AssemblyAI LLM Gateway completion **${result.request_id}**.`
+ };
+ })
+ .build();
diff --git a/integrations/assembly-ai/src/tools/create-speech-understanding.ts b/integrations/assembly-ai/src/tools/create-speech-understanding.ts
new file mode 100644
index 0000000000..73869d8cbf
--- /dev/null
+++ b/integrations/assembly-ai/src/tools/create-speech-understanding.ts
@@ -0,0 +1,128 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { assemblyAiServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let speakerSchema = z.object({
+ name: z.string().optional().describe('Known speaker name.'),
+ role: z.string().optional().describe('Known speaker role.'),
+ description: z.string().optional().describe('Context describing the speaker.'),
+ company: z.string().optional().describe('Speaker company or organization.'),
+ title: z.string().optional().describe('Speaker title.')
+});
+
+let customFormattingSchema = z.object({
+ date: z.string().optional().describe('Desired date format, such as "mm/dd/yyyy".'),
+ phoneNumber: z
+ .string()
+ .optional()
+ .describe('Desired phone number format, such as "(xxx)xxx-xxxx".'),
+ email: z.string().optional().describe('Desired email format.')
+});
+
+export let createSpeechUnderstanding = SlateTool.create(spec, {
+ name: 'Create Speech Understanding',
+ key: 'create_speech_understanding',
+ description: `Apply AssemblyAI Speech Understanding to a completed transcript. Supports translation, advanced speaker identification, and custom formatting in one request.`,
+ instructions: [
+ 'The transcript must already be completed.',
+ 'Provide at least one capability: targetLanguages, speakerType/speakers, or customFormatting.'
+ ],
+ tags: {
+ destructive: false,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ transcriptId: z.string().describe('Completed AssemblyAI transcript ID to process.'),
+ targetLanguages: z
+ .array(z.string())
+ .optional()
+ .describe('Language codes to translate the transcript into, such as ["es", "de"].'),
+ formal: z
+ .boolean()
+ .optional()
+ .describe('Use formal translation tone when targetLanguages is provided.'),
+ matchOriginalUtterance: z
+ .boolean()
+ .optional()
+ .describe(
+ 'Return translated utterances aligned to original utterances when targetLanguages is provided.'
+ ),
+ speakerType: z
+ .enum(['name', 'role'])
+ .optional()
+ .describe('Speaker identification type to map diarized labels to names or roles.'),
+ speakers: z
+ .array(speakerSchema)
+ .optional()
+ .describe('Known speakers to help speaker identification.'),
+ customFormatting: customFormattingSchema
+ .optional()
+ .describe('Formatting preferences for dates, phone numbers, and emails.')
+ })
+ )
+ .output(
+ z.object({
+ transcriptId: z.string().describe('Transcript ID that was processed.'),
+ speechUnderstanding: z
+ .any()
+ .optional()
+ .describe('Speech Understanding request and response status details.'),
+ translatedTexts: z
+ .record(z.string(), z.string())
+ .optional()
+ .describe('Translated text keyed by target language.'),
+ utterances: z
+ .array(z.any())
+ .optional()
+ .describe('Utterances returned by Speech Understanding.'),
+ words: z.array(z.any()).optional().describe('Words returned by Speech Understanding.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let hasTranslation = Boolean(ctx.input.targetLanguages?.length);
+ let hasSpeakerIdentification = Boolean(
+ ctx.input.speakerType || ctx.input.speakers?.length
+ );
+ let hasCustomFormatting =
+ ctx.input.customFormatting !== undefined &&
+ Object.values(ctx.input.customFormatting).some(value => value !== undefined);
+
+ if (!hasTranslation && !hasSpeakerIdentification && !hasCustomFormatting) {
+ throw assemblyAiServiceError(
+ 'Provide targetLanguages, speakerType/speakers, or customFormatting.'
+ );
+ }
+
+ if ((ctx.input.formal || ctx.input.matchOriginalUtterance) && !hasTranslation) {
+ throw assemblyAiServiceError(
+ 'formal and matchOriginalUtterance require targetLanguages.'
+ );
+ }
+
+ if (ctx.input.speakers?.length && !ctx.input.speakerType) {
+ throw assemblyAiServiceError('speakerType is required when speakers are provided.');
+ }
+
+ let client = new Client({
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ let result = await client.createSpeechUnderstanding(ctx.input);
+
+ return {
+ output: {
+ transcriptId: ctx.input.transcriptId,
+ speechUnderstanding: result.speech_understanding,
+ translatedTexts: result.translated_texts,
+ utterances: result.utterances,
+ words: result.words
+ },
+ message: `Created Speech Understanding results for transcript **${ctx.input.transcriptId}**.`
+ };
+ })
+ .build();
diff --git a/integrations/assembly-ai/src/tools/get-subtitles.ts b/integrations/assembly-ai/src/tools/get-subtitles.ts
index ec7202b010..41fe87e5df 100644
--- a/integrations/assembly-ai/src/tools/get-subtitles.ts
+++ b/integrations/assembly-ai/src/tools/get-subtitles.ts
@@ -1,4 +1,5 @@
-import { SlateTool } from 'slates';
+import { Buffer } from 'node:buffer';
+import { createTextAttachment, SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
import { spec } from '../spec';
@@ -25,8 +26,10 @@ Optionally limit the number of characters per caption line.`,
)
.output(
z.object({
- subtitleContent: z.string().describe('The subtitle content in the requested format.'),
- format: z.string().describe('The subtitle format (srt or vtt).')
+ format: z.string().describe('The subtitle format (srt or vtt).'),
+ contentType: z.string().describe('MIME type of the returned subtitle attachment.'),
+ byteLength: z.number().describe('UTF-8 byte length of the subtitle attachment.'),
+ attachmentCount: z.number().describe('Number of subtitle attachments returned.')
})
)
.handleInvocation(async ctx => {
@@ -42,12 +45,16 @@ Optionally limit the number of characters per caption line.`,
);
let content = typeof result === 'string' ? result : JSON.stringify(result);
+ let contentType = ctx.input.subtitleFormat === 'srt' ? 'application/x-subrip' : 'text/vtt';
return {
output: {
- subtitleContent: content,
- format: ctx.input.subtitleFormat
+ format: ctx.input.subtitleFormat,
+ contentType,
+ byteLength: Buffer.byteLength(content, 'utf8'),
+ attachmentCount: 1
},
+ attachments: [createTextAttachment(content, contentType)],
message: `Generated **${ctx.input.subtitleFormat.toUpperCase()}** subtitles for transcript **${ctx.input.transcriptId}**.`
};
})
diff --git a/integrations/assembly-ai/src/tools/get-transcript-text.ts b/integrations/assembly-ai/src/tools/get-transcript-text.ts
index 36cfa39881..07b805d301 100644
--- a/integrations/assembly-ai/src/tools/get-transcript-text.ts
+++ b/integrations/assembly-ai/src/tools/get-transcript-text.ts
@@ -8,6 +8,7 @@ let segmentSchema = z.object({
start: z.number().describe('Start time in milliseconds.'),
end: z.number().describe('End time in milliseconds.'),
confidence: z.number().describe('Confidence score.'),
+ speaker: z.string().optional().nullable().describe('Speaker label if available.'),
words: z
.array(
z.object({
@@ -69,6 +70,7 @@ Choose "sentences" or "paragraphs" segmentation depending on how granular you ne
start: s.start,
end: s.end,
confidence: s.confidence,
+ speaker: s.speaker ?? null,
words: s.words
}));
diff --git a/integrations/assembly-ai/src/tools/index.ts b/integrations/assembly-ai/src/tools/index.ts
index f344967af9..f528facf47 100644
--- a/integrations/assembly-ai/src/tools/index.ts
+++ b/integrations/assembly-ai/src/tools/index.ts
@@ -1,10 +1,12 @@
+export * from './create-chat-completion';
+export * from './create-speech-understanding';
export * from './create-streaming-token';
export * from './delete-transcript';
export * from './get-redacted-audio';
export * from './get-subtitles';
export * from './get-transcript';
export * from './get-transcript-text';
-export * from './lemur-task';
export * from './list-transcripts';
export * from './search-transcript';
export * from './submit-transcription';
+export * from './upload-media-file';
diff --git a/integrations/assembly-ai/src/tools/lemur-task.ts b/integrations/assembly-ai/src/tools/lemur-task.ts
deleted file mode 100644
index 4dd9cb84e8..0000000000
--- a/integrations/assembly-ai/src/tools/lemur-task.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import { SlateTool } from 'slates';
-import { z } from 'zod';
-import { Client } from '../lib/client';
-import { spec } from '../spec';
-
-export let lemurTask = SlateTool.create(spec, {
- name: 'LeMUR Task',
- key: 'lemur_task',
- description: `Apply a large language model to one or more transcripts using AssemblyAI's LeMUR framework. Submit a custom prompt along with transcript IDs or raw text input, and receive an LLM-generated response.
-Use this for summarizing transcripts, extracting insights, answering questions about audio content, generating action items, or any custom analysis task.
-Supports multiple LLM providers including Claude, GPT, and Gemini models.`,
- instructions: [
- 'Provide either transcriptIds (for transcripts already on AssemblyAI) or inputText (for custom text input), not both.',
- 'The prompt should clearly describe what you want the LLM to do with the transcript data.'
- ],
- constraints: [
- 'Up to 100 transcript IDs or 100 hours of audio can be processed per request.',
- 'LeMUR is not supported on the EU endpoint.'
- ],
- tags: {
- destructive: false,
- readOnly: true
- }
-})
- .input(
- z.object({
- prompt: z
- .string()
- .describe('The LLM prompt describing what to do with the transcript data.'),
- transcriptIds: z
- .array(z.string())
- .optional()
- .describe('List of completed transcript IDs to process.'),
- inputText: z
- .string()
- .optional()
- .describe('Custom text input to process (alternative to transcriptIds).'),
- finalModel: z
- .string()
- .optional()
- .describe(
- 'LLM model to use (e.g., "anthropic/claude-3-5-sonnet", "openai/gpt-4o"). Defaults to the platform default.'
- ),
- maxOutputSize: z.number().optional().describe('Maximum output size in tokens.'),
- temperature: z
- .number()
- .optional()
- .describe('Model temperature (higher = more creative, lower = more conservative).')
- })
- )
- .output(
- z.object({
- requestId: z
- .string()
- .describe('The LeMUR request ID. Can be used to purge the data later.'),
- response: z.string().describe('The LLM-generated response text.'),
- usage: z
- .object({
- inputTokens: z.number().optional().describe('Number of input tokens used.'),
- outputTokens: z.number().optional().describe('Number of output tokens generated.')
- })
- .optional()
- .describe('Token usage information.')
- })
- )
- .handleInvocation(async ctx => {
- let client = new Client({
- token: ctx.auth.token,
- region: ctx.config.region
- });
-
- let result = await client.lemurTask({
- prompt: ctx.input.prompt,
- transcriptIds: ctx.input.transcriptIds,
- inputText: ctx.input.inputText,
- finalModel: ctx.input.finalModel,
- maxOutputSize: ctx.input.maxOutputSize,
- temperature: ctx.input.temperature
- });
-
- return {
- output: {
- requestId: result.request_id,
- response: result.response,
- usage: result.usage
- ? {
- inputTokens: result.usage.input_tokens,
- outputTokens: result.usage.output_tokens
- }
- : undefined
- },
- message: `LeMUR task completed. Request ID: **${result.request_id}**.`
- };
- })
- .build();
diff --git a/integrations/assembly-ai/src/tools/search-transcript.ts b/integrations/assembly-ai/src/tools/search-transcript.ts
index 2fccbc808e..f3aa087ff1 100644
--- a/integrations/assembly-ai/src/tools/search-transcript.ts
+++ b/integrations/assembly-ai/src/tools/search-transcript.ts
@@ -3,6 +3,20 @@ import { z } from 'zod';
import { Client } from '../lib/client';
import { spec } from '../spec';
+let mapTimestamp = (timestamp: any) => {
+ if (Array.isArray(timestamp)) {
+ return {
+ start: timestamp[0],
+ end: timestamp[1]
+ };
+ }
+
+ return {
+ start: timestamp.start,
+ end: timestamp.end
+ };
+};
+
export let searchTranscript = SlateTool.create(spec, {
name: 'Search Transcript',
key: 'search_transcript',
@@ -18,6 +32,7 @@ Returns match counts and timestamps for each keyword found.`,
transcriptId: z.string().describe('The unique transcript ID.'),
words: z
.array(z.string())
+ .min(1)
.describe('Keywords or phrases to search for (each up to 5 words).')
})
)
@@ -55,10 +70,7 @@ Returns match counts and timestamps for each keyword found.`,
let matches = (result.matches || []).map((m: any) => ({
text: m.text,
count: m.count,
- timestamps: (m.timestamps || []).map((t: any) => ({
- start: t.start,
- end: t.end
- })),
+ timestamps: (m.timestamps || []).map(mapTimestamp),
indexes: m.indexes || []
}));
diff --git a/integrations/assembly-ai/src/tools/submit-transcription.ts b/integrations/assembly-ai/src/tools/submit-transcription.ts
index 51cf6f163c..afa114fbb0 100644
--- a/integrations/assembly-ai/src/tools/submit-transcription.ts
+++ b/integrations/assembly-ai/src/tools/submit-transcription.ts
@@ -1,17 +1,19 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Client } from '../lib/client';
+import { assemblyAiServiceError } from '../lib/errors';
import { spec } from '../spec';
export let submitTranscription = SlateTool.create(spec, {
name: 'Submit Transcription',
key: 'submit_transcription',
description: `Submit an audio or video file for asynchronous transcription. Provide a publicly accessible URL to the media file.
-Optionally enable audio intelligence features like summarization, sentiment analysis, entity detection, topic detection, content moderation, key phrases, auto chapters, and PII redaction.
+Optionally enable audio intelligence features like sentiment analysis, entity detection, topic detection, content moderation, key phrases, and PII redaction.
Returns the transcript object with a status of "queued" — poll using the **Get Transcript** tool to check for completion.`,
instructions: [
'The audio URL must be a direct link to a media file (not a webpage).',
- 'To enable summarization, set both summarization=true and provide summaryType and optionally summaryModel.',
+ 'Use speechModels for current model selection. speechModel is deprecated by AssemblyAI and only remains for backwards compatibility.',
+ 'For flexible summaries and chapters, prefer the Create Chat Completion tool with transcriptId over deprecated transcript-time summarization and auto chapters.',
'PII redaction requires redactPii=true and at least one policy in redactPiiPolicies.'
],
constraints: [
@@ -30,6 +32,10 @@ Returns the transcript object with a status of "queued" — poll using the **Get
.string()
.optional()
.describe('Language code (e.g., "en_us", "es", "fr"). Defaults to "en_us".'),
+ languageCodes: z
+ .array(z.string())
+ .optional()
+ .describe('Language codes for code-switching audio that contains multiple languages.'),
languageDetection: z
.boolean()
.optional()
@@ -41,7 +47,13 @@ Returns the transcript object with a status of "queued" — poll using the **Get
speechModel: z
.string()
.optional()
- .describe('Speech model to use (e.g., "universal", "slam-1").'),
+ .describe('Deprecated AssemblyAI speech_model parameter. Prefer speechModels.'),
+ speechModels: z
+ .array(z.string())
+ .optional()
+ .describe(
+ 'Current speech model priority list, such as ["universal-3-pro", "universal-2"].'
+ ),
punctuate: z
.boolean()
.optional()
@@ -80,7 +92,12 @@ Returns the transcript object with a status of "queued" — poll using the **Get
.optional()
.describe('Custom header value for webhook authentication.'),
autoHighlights: z.boolean().optional().describe('Enable key phrase extraction.'),
- autoChapters: z.boolean().optional().describe('Enable automatic chapter generation.'),
+ autoChapters: z
+ .boolean()
+ .optional()
+ .describe(
+ 'Deprecated AssemblyAI auto_chapters parameter. Prefer Create Chat Completion with transcriptId for flexible chapter summaries.'
+ ),
entityDetection: z
.boolean()
.optional()
@@ -101,15 +118,24 @@ Returns the transcript object with a status of "queued" — poll using the **Get
.boolean()
.optional()
.describe('Enable topic detection using IAB taxonomy.'),
- summarization: z.boolean().optional().describe('Enable transcript summarization.'),
+ keytermsPrompt: z
+ .array(z.string())
+ .optional()
+ .describe('Domain-specific words or phrases to improve recognition accuracy.'),
+ summarization: z
+ .boolean()
+ .optional()
+ .describe(
+ 'Deprecated AssemblyAI summarization parameter. Prefer Create Chat Completion with transcriptId.'
+ ),
summaryModel: z
.enum(['informative', 'conversational', 'catchy'])
.optional()
- .describe('Summarization model to use.'),
+ .describe('Deprecated summarization model to use.'),
summaryType: z
.enum(['bullets', 'bullets_verbose', 'gist', 'headline', 'paragraph'])
.optional()
- .describe('Summary output format.'),
+ .describe('Deprecated summary output format.'),
redactPii: z
.boolean()
.optional()
@@ -132,6 +158,18 @@ Returns the transcript object with a status of "queued" — poll using the **Get
.enum(['entity_name', 'hash'])
.optional()
.describe('How to replace PII in text: "entity_name" or "hash".'),
+ redactPiiReturnUnredacted: z
+ .boolean()
+ .optional()
+ .describe(
+ 'Return unredacted text, words, and utterances alongside redacted fields. Requires redactPii=true.'
+ ),
+ redactStaticEntities: z
+ .record(z.string(), z.array(z.string()))
+ .optional()
+ .describe(
+ 'User-defined exact terms to redact, keyed by redaction label. Requires redactPii=true.'
+ ),
audioStartFrom: z
.number()
.optional()
@@ -149,6 +187,22 @@ Returns the transcript object with a status of "queued" — poll using the **Get
.optional()
.describe(
'Natural language context (up to 1500 words) to guide transcription. Only supported for Universal-3-Pro.'
+ ),
+ temperature: z
+ .number()
+ .min(0)
+ .max(1)
+ .optional()
+ .describe('Universal-3 Pro transcription randomness.'),
+ domain: z
+ .enum(['medical-v1'])
+ .optional()
+ .describe('Domain-specific transcription model, currently "medical-v1".'),
+ removeAudioTags: z
+ .enum(['all', 'speaker'])
+ .optional()
+ .describe(
+ 'Universal-3 Pro option to remove inline annotations: all annotations or speaker cues only.'
)
})
)
@@ -171,6 +225,52 @@ Returns the transcript object with a status of "queued" — poll using the **Get
region: ctx.config.region
});
+ if (ctx.input.languageCode && ctx.input.languageCodes?.length) {
+ throw assemblyAiServiceError('Provide either languageCode or languageCodes, not both.');
+ }
+
+ if (ctx.input.speechModel && ctx.input.speechModels?.length) {
+ throw assemblyAiServiceError(
+ 'Provide either deprecated speechModel or current speechModels, not both.'
+ );
+ }
+
+ if (
+ (ctx.input.webhookAuthHeaderName && !ctx.input.webhookAuthHeaderValue) ||
+ (!ctx.input.webhookAuthHeaderName && ctx.input.webhookAuthHeaderValue)
+ ) {
+ throw assemblyAiServiceError(
+ 'webhookAuthHeaderName and webhookAuthHeaderValue must be provided together.'
+ );
+ }
+
+ if (ctx.input.summarization && !ctx.input.summaryType) {
+ throw assemblyAiServiceError(
+ 'summaryType is required when using deprecated summarization=true.'
+ );
+ }
+
+ if (
+ (ctx.input.redactPiiAudio ||
+ ctx.input.redactPiiReturnUnredacted ||
+ ctx.input.redactStaticEntities) &&
+ !ctx.input.redactPii
+ ) {
+ throw assemblyAiServiceError(
+ 'redactPii must be true when using audio redaction, unredacted returns, or static entity redaction.'
+ );
+ }
+
+ if (
+ ctx.input.redactPii &&
+ !ctx.input.redactPiiPolicies?.length &&
+ !ctx.input.redactStaticEntities
+ ) {
+ throw assemblyAiServiceError(
+ 'redactPiiPolicies or redactStaticEntities is required when redactPii is true.'
+ );
+ }
+
let result = await client.submitTranscription(ctx.input);
return {
diff --git a/integrations/assembly-ai/src/tools/upload-media-file.ts b/integrations/assembly-ai/src/tools/upload-media-file.ts
new file mode 100644
index 0000000000..29b37dc9d3
--- /dev/null
+++ b/integrations/assembly-ai/src/tools/upload-media-file.ts
@@ -0,0 +1,82 @@
+import { Buffer } from 'node:buffer';
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Client } from '../lib/client';
+import { assemblyAiServiceError } from '../lib/errors';
+import { spec } from '../spec';
+
+let decodeBase64 = (value: string) => {
+ let normalized = value.trim().replace(/\s/g, '');
+ let buffer = Buffer.from(normalized, 'base64');
+
+ if (buffer.length === 0) {
+ throw assemblyAiServiceError('contentBase64 must contain at least one byte.');
+ }
+
+ let canonical = buffer.toString('base64').replace(/=+$/, '');
+ let provided = normalized.replace(/=+$/, '');
+ if (canonical !== provided) {
+ throw assemblyAiServiceError('contentBase64 must be valid base64-encoded media.');
+ }
+
+ return buffer;
+};
+
+export let uploadMediaFile = SlateTool.create(spec, {
+ name: 'Upload Media File',
+ key: 'upload_media_file',
+ description: `Upload local audio or video bytes to AssemblyAI and receive an AssemblyAI-only upload URL. Use the returned uploadUrl as audioUrl in Submit Transcription when the media is not already publicly accessible.`,
+ instructions: [
+ 'The upload URL is only accessible to AssemblyAI servers.',
+ 'Submit the returned uploadUrl with Submit Transcription to process the media.'
+ ],
+ tags: {
+ destructive: false,
+ readOnly: false
+ }
+})
+ .input(
+ z.object({
+ contentBase64: z
+ .string()
+ .describe('Base64-encoded audio or video file content to upload.'),
+ filename: z
+ .string()
+ .optional()
+ .describe('Original filename for user-facing metadata only.'),
+ mimeType: z
+ .string()
+ .optional()
+ .describe('Original MIME type for user-facing metadata only.')
+ })
+ )
+ .output(
+ z.object({
+ uploadUrl: z
+ .string()
+ .describe('AssemblyAI upload URL to pass as audioUrl to Submit Transcription.'),
+ filename: z.string().optional().describe('Original filename if provided.'),
+ mimeType: z.string().optional().describe('Original MIME type if provided.'),
+ byteLength: z.number().describe('Decoded upload size in bytes.')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let content = decodeBase64(ctx.input.contentBase64);
+ let client = new Client({
+ token: ctx.auth.token,
+ region: ctx.config.region
+ });
+
+ let result = await client.uploadMediaFile(ctx.input.contentBase64);
+
+ return {
+ output: {
+ uploadUrl: result.upload_url,
+ filename: ctx.input.filename,
+ mimeType: ctx.input.mimeType,
+ byteLength: content.byteLength
+ },
+ message: `Uploaded media file${ctx.input.filename ? ` **${ctx.input.filename}**` : ''} to AssemblyAI (${content.byteLength} bytes). Use the upload URL with Submit Transcription.`
+ };
+ })
+ .build();
diff --git a/integrations/assembly-ai/vitest.config.ts b/integrations/assembly-ai/vitest.config.ts
new file mode 100644
index 0000000000..77375364da
--- /dev/null
+++ b/integrations/assembly-ai/vitest.config.ts
@@ -0,0 +1,7 @@
+import { createSlatesVitestConfig } from '@slates/test/config';
+
+export default createSlatesVitestConfig({
+ test: {
+ include: ['src/**/*.test.ts']
+ }
+});
diff --git a/integrations/auth0/README.md b/integrations/auth0/README.md
index 20a73d2bb1..f31847e468 100644
--- a/integrations/auth0/README.md
+++ b/integrations/auth0/README.md
@@ -36,6 +36,14 @@ Create, update, delete, or list client grants. Client grants authorize applicati
Create, update, delete, or list identity provider connections. Connections define how users authenticate — database, social (Google, Facebook), enterprise (SAML, OIDC), or passwordless (SMS, email).
+### Manage Log Streams
+
+Create, update, delete, get, or list Auth0 log streams for delivering tenant logs to HTTP webhooks and supported event destinations.
+
+### Manage Organization Member Roles
+
+List, assign, or remove roles for a user inside a specific Auth0 Organization membership.
+
### Manage Organization Members
List, add, or remove members from an organization. Members are Auth0 users associated with an organization for multi-tenant B2B scenarios.
@@ -44,6 +52,10 @@ List, add, or remove members from an organization. Members are Auth0 users assoc
Create, update, delete, or list organizations for multi-tenant B2B scenarios. Organizations group users and can have their own connections, branding, and member roles.
+### Manage Role Permissions
+
+List, assign, or remove permissions granted to an Auth0 role. Permissions reference API resource-server identifiers and scope names.
+
### Manage Resource Servers
Create, update, delete, or list API resource servers. Resource servers represent APIs protected by Auth0, with defined scopes/permissions and token settings.
@@ -52,6 +64,10 @@ Create, update, delete, or list API resource servers. Resource servers represent
Create, update, delete, or list roles. Roles define sets of permissions that can be assigned to users for role-based access control (RBAC).
+### Manage User Permissions
+
+List, assign, or remove direct Auth0 permissions for a user. Permissions reference API resource-server identifiers and scope names.
+
### Manage User Roles
List, assign, or remove roles for a user. Use the action parameter to specify the operation: "list" to get current roles, "assign" to add roles, or "remove" to remove roles.
diff --git a/integrations/auth0/docs/SPEC.md b/integrations/auth0/docs/SPEC.md
index 360d06d762..15f4f5b851 100644
--- a/integrations/auth0/docs/SPEC.md
+++ b/integrations/auth0/docs/SPEC.md
@@ -38,11 +38,11 @@ Register and manage applications that use Auth0 for authentication. Configure ap
### Roles and Permissions (RBAC)
-Define roles with associated permissions and assign them to users. Permissions are scoped to specific APIs (Resource Servers). Supports role-based access control for fine-grained authorization.
+Define roles with associated permissions and assign them to users. Permissions are scoped to specific APIs (Resource Servers). Supports role-based access control for fine-grained authorization. The integration supports role CRUD, user-role assignment, role-permission assignment, and direct user-permission assignment.
### Organizations
-Manage multi-tenant B2B scenarios by grouping users into organizations. Configure organization-specific connections, branding, and member roles. Invite users to organizations.
+Manage multi-tenant B2B scenarios by grouping users into organizations. Configure organization-specific connections, branding, and member roles. Invite users to organizations. The integration supports organization CRUD, organization member add/remove/list, and organization-scoped member roles.
### Multi-Factor Authentication (MFA)
@@ -76,6 +76,10 @@ Customize the look and feel of the Universal Login page, including colors, logos
Manage which applications are authorized to request access tokens for specific APIs, along with the permitted scopes.
+### Log Streams
+
+Create, update, delete, retrieve, and list log streams for delivering tenant log events to HTTP webhooks and supported event destinations.
+
### Jobs (Bulk Operations)
Import or export users in bulk using background jobs. Useful for migration scenarios or generating user data exports.
diff --git a/integrations/auth0/package.json b/integrations/auth0/package.json
index cc53d51867..677085a348 100644
--- a/integrations/auth0/package.json
+++ b/integrations/auth0/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
+ "@slates/test": "1.0.0-rc.9",
+ "vitest": "^3.1.2",
"typescript": "^5"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.7"
}
diff --git a/integrations/auth0/src/auth.ts b/integrations/auth0/src/auth.ts
index 4d4dfc74c2..ae998be4ce 100644
--- a/integrations/auth0/src/auth.ts
+++ b/integrations/auth0/src/auth.ts
@@ -1,5 +1,6 @@
import { createAxios, SlateAuth } from 'slates';
import { z } from 'zod';
+import { auth0ApiError, auth0ServiceError } from './lib/errors';
export let auth = SlateAuth.create()
.output(
@@ -20,18 +21,30 @@ export let auth = SlateAuth.create()
}),
getOutput: async ctx => {
- let domain = ctx.input.domain;
+ let domain = ctx.input.domain
+ .trim()
+ .replace(/^https?:\/\//, '')
+ .replace(/\/+$/, '');
+
+ if (!domain) {
+ throw auth0ServiceError('Auth0 tenant domain is required.');
+ }
let http = createAxios({
baseURL: `https://${domain}`
});
- let response = await http.post('/oauth/token', {
- grant_type: 'client_credentials',
- client_id: ctx.input.clientId,
- client_secret: ctx.input.clientSecret,
- audience: `https://${domain}/api/v2/`
- });
+ let response: any;
+ try {
+ response = await http.post('/oauth/token', {
+ grant_type: 'client_credentials',
+ client_id: ctx.input.clientId,
+ client_secret: ctx.input.clientSecret,
+ audience: `https://${domain}/api/v2/`
+ });
+ } catch (error) {
+ throw auth0ApiError(error, 'exchange client credentials token');
+ }
return {
output: {
diff --git a/integrations/auth0/src/index.ts b/integrations/auth0/src/index.ts
index 21dd1c93ef..1af3f6256d 100644
--- a/integrations/auth0/src/index.ts
+++ b/integrations/auth0/src/index.ts
@@ -9,10 +9,14 @@ import {
manageApplicationsTool,
manageClientGrantsTool,
manageConnectionsTool,
+ manageLogStreamsTool,
+ manageOrganizationMemberRolesTool,
manageOrganizationMembersTool,
manageOrganizationsTool,
manageResourceServersTool,
+ manageRolePermissionsTool,
manageRolesTool,
+ manageUserPermissionsTool,
manageUserRolesTool,
searchUsersTool,
updateUserTool
@@ -29,12 +33,16 @@ export let provider = Slate.create({
deleteUserTool,
manageUserRolesTool,
manageRolesTool,
+ manageRolePermissionsTool,
manageConnectionsTool,
manageApplicationsTool,
manageOrganizationsTool,
manageOrganizationMembersTool,
+ manageOrganizationMemberRolesTool,
getLogsTool,
+ manageLogStreamsTool,
manageResourceServersTool,
+ manageUserPermissionsTool,
manageActionsTool,
manageClientGrantsTool
],
diff --git a/integrations/auth0/src/lib/client.ts b/integrations/auth0/src/lib/client.ts
index 57494bb547..da88154de2 100644
--- a/integrations/auth0/src/lib/client.ts
+++ b/integrations/auth0/src/lib/client.ts
@@ -1,4 +1,5 @@
import { createAxios } from 'slates';
+import { auth0ApiError } from './errors';
export class Auth0Client {
private http: ReturnType;
@@ -13,6 +14,23 @@ export class Auth0Client {
});
}
+ private async request(operation: string, run: () => Promise<{ data: any }>): Promise {
+ try {
+ let response = await run();
+ return response.data;
+ } catch (error) {
+ throw auth0ApiError(error, operation);
+ }
+ }
+
+ private async send(operation: string, run: () => Promise) {
+ try {
+ await run();
+ } catch (error) {
+ throw auth0ApiError(error, operation);
+ }
+ }
+
// ─── Users ───
async listUsers(params?: {
@@ -26,25 +44,27 @@ export class Auth0Client {
includeFields?: boolean;
searchEngine?: string;
}) {
- let response = await this.http.get('/users', {
- params: {
- q: params?.q,
- page: params?.page,
- per_page: params?.perPage,
- include_totals: params?.includeTotals,
- sort: params?.sort,
- connection: params?.connection,
- fields: params?.fields,
- include_fields: params?.includeFields,
- search_engine: params?.searchEngine ?? 'v3'
- }
- });
- return response.data;
+ return await this.request('list users', () =>
+ this.http.get('/users', {
+ params: {
+ q: params?.q,
+ page: params?.page,
+ per_page: params?.perPage,
+ include_totals: params?.includeTotals,
+ sort: params?.sort,
+ connection: params?.connection,
+ fields: params?.fields,
+ include_fields: params?.includeFields,
+ search_engine: params?.searchEngine ?? 'v3'
+ }
+ })
+ );
}
async getUser(userId: string) {
- let response = await this.http.get(`/users/${encodeURIComponent(userId)}`);
- return response.data;
+ return await this.request('get user', () =>
+ this.http.get(`/users/${encodeURIComponent(userId)}`)
+ );
}
async createUser(data: {
@@ -60,20 +80,21 @@ export class Auth0Client {
verifyEmail?: boolean;
phoneVerified?: boolean;
}) {
- let response = await this.http.post('/users', {
- connection: data.connection,
- email: data.email,
- password: data.password,
- username: data.username,
- phone_number: data.phoneNumber,
- user_metadata: data.userMetadata,
- app_metadata: data.appMetadata,
- blocked: data.blocked,
- email_verified: data.emailVerified,
- verify_email: data.verifyEmail,
- phone_verified: data.phoneVerified
- });
- return response.data;
+ return await this.request('create user', () =>
+ this.http.post('/users', {
+ connection: data.connection,
+ email: data.email,
+ password: data.password,
+ username: data.username,
+ phone_number: data.phoneNumber,
+ user_metadata: data.userMetadata,
+ app_metadata: data.appMetadata,
+ blocked: data.blocked,
+ email_verified: data.emailVerified,
+ verify_email: data.verifyEmail,
+ phone_verified: data.phoneVerified
+ })
+ );
}
async updateUser(
@@ -97,81 +118,94 @@ export class Auth0Client {
familyName?: string;
}
) {
- let response = await this.http.patch(`/users/${encodeURIComponent(userId)}`, {
- email: data.email,
- password: data.password,
- username: data.username,
- phone_number: data.phoneNumber,
- user_metadata: data.userMetadata,
- app_metadata: data.appMetadata,
- blocked: data.blocked,
- email_verified: data.emailVerified,
- phone_verified: data.phoneVerified,
- connection: data.connection,
- client_id: data.clientId,
- name: data.name,
- nickname: data.nickname,
- picture: data.picture,
- given_name: data.givenName,
- family_name: data.familyName
- });
- return response.data;
+ return await this.request('update user', () =>
+ this.http.patch(`/users/${encodeURIComponent(userId)}`, {
+ email: data.email,
+ password: data.password,
+ username: data.username,
+ phone_number: data.phoneNumber,
+ user_metadata: data.userMetadata,
+ app_metadata: data.appMetadata,
+ blocked: data.blocked,
+ email_verified: data.emailVerified,
+ phone_verified: data.phoneVerified,
+ connection: data.connection,
+ client_id: data.clientId,
+ name: data.name,
+ nickname: data.nickname,
+ picture: data.picture,
+ given_name: data.givenName,
+ family_name: data.familyName
+ })
+ );
}
async deleteUser(userId: string) {
- await this.http.delete(`/users/${encodeURIComponent(userId)}`);
+ await this.send('delete user', () =>
+ this.http.delete(`/users/${encodeURIComponent(userId)}`)
+ );
}
async getUserRoles(userId: string, params?: { page?: number; perPage?: number }) {
- let response = await this.http.get(`/users/${encodeURIComponent(userId)}/roles`, {
- params: { page: params?.page, per_page: params?.perPage }
- });
- return response.data;
+ return await this.request('get user roles', () =>
+ this.http.get(`/users/${encodeURIComponent(userId)}/roles`, {
+ params: { page: params?.page, per_page: params?.perPage }
+ })
+ );
}
async assignUserRoles(userId: string, roleIds: string[]) {
- await this.http.post(`/users/${encodeURIComponent(userId)}/roles`, {
- roles: roleIds
- });
+ await this.send('assign user roles', () =>
+ this.http.post(`/users/${encodeURIComponent(userId)}/roles`, {
+ roles: roleIds
+ })
+ );
}
async removeUserRoles(userId: string, roleIds: string[]) {
- await this.http.delete(`/users/${encodeURIComponent(userId)}/roles`, {
- data: { roles: roleIds }
- });
+ await this.send('remove user roles', () =>
+ this.http.delete(`/users/${encodeURIComponent(userId)}/roles`, {
+ data: { roles: roleIds }
+ })
+ );
}
async getUserPermissions(userId: string, params?: { page?: number; perPage?: number }) {
- let response = await this.http.get(`/users/${encodeURIComponent(userId)}/permissions`, {
- params: { page: params?.page, per_page: params?.perPage }
- });
- return response.data;
+ return await this.request('get user permissions', () =>
+ this.http.get(`/users/${encodeURIComponent(userId)}/permissions`, {
+ params: { page: params?.page, per_page: params?.perPage }
+ })
+ );
}
async assignUserPermissions(
userId: string,
permissions: Array<{ resourceServerIdentifier: string; permissionName: string }>
) {
- await this.http.post(`/users/${encodeURIComponent(userId)}/permissions`, {
- permissions: permissions.map(p => ({
- resource_server_identifier: p.resourceServerIdentifier,
- permission_name: p.permissionName
- }))
- });
+ await this.send('assign user permissions', () =>
+ this.http.post(`/users/${encodeURIComponent(userId)}/permissions`, {
+ permissions: permissions.map(p => ({
+ resource_server_identifier: p.resourceServerIdentifier,
+ permission_name: p.permissionName
+ }))
+ })
+ );
}
async removeUserPermissions(
userId: string,
permissions: Array<{ resourceServerIdentifier: string; permissionName: string }>
) {
- await this.http.delete(`/users/${encodeURIComponent(userId)}/permissions`, {
- data: {
- permissions: permissions.map(p => ({
- resource_server_identifier: p.resourceServerIdentifier,
- permission_name: p.permissionName
- }))
- }
- });
+ await this.send('remove user permissions', () =>
+ this.http.delete(`/users/${encodeURIComponent(userId)}/permissions`, {
+ data: {
+ permissions: permissions.map(p => ({
+ resource_server_identifier: p.resourceServerIdentifier,
+ permission_name: p.permissionName
+ }))
+ }
+ })
+ );
}
// ─── Roles ───
@@ -182,67 +216,76 @@ export class Auth0Client {
includeTotals?: boolean;
nameFilter?: string;
}) {
- let response = await this.http.get('/roles', {
- params: {
- page: params?.page,
- per_page: params?.perPage,
- include_totals: params?.includeTotals,
- name_filter: params?.nameFilter
- }
- });
- return response.data;
+ return await this.request('list roles', () =>
+ this.http.get('/roles', {
+ params: {
+ page: params?.page,
+ per_page: params?.perPage,
+ include_totals: params?.includeTotals,
+ name_filter: params?.nameFilter
+ }
+ })
+ );
}
async getRole(roleId: string) {
- let response = await this.http.get(`/roles/${encodeURIComponent(roleId)}`);
- return response.data;
+ return await this.request('get role', () =>
+ this.http.get(`/roles/${encodeURIComponent(roleId)}`)
+ );
}
async createRole(data: { name: string; description?: string }) {
- let response = await this.http.post('/roles', data);
- return response.data;
+ return await this.request('create role', () => this.http.post('/roles', data));
}
async updateRole(roleId: string, data: { name?: string; description?: string }) {
- let response = await this.http.patch(`/roles/${encodeURIComponent(roleId)}`, data);
- return response.data;
+ return await this.request('update role', () =>
+ this.http.patch(`/roles/${encodeURIComponent(roleId)}`, data)
+ );
}
async deleteRole(roleId: string) {
- await this.http.delete(`/roles/${encodeURIComponent(roleId)}`);
+ await this.send('delete role', () =>
+ this.http.delete(`/roles/${encodeURIComponent(roleId)}`)
+ );
}
async getRolePermissions(roleId: string, params?: { page?: number; perPage?: number }) {
- let response = await this.http.get(`/roles/${encodeURIComponent(roleId)}/permissions`, {
- params: { page: params?.page, per_page: params?.perPage }
- });
- return response.data;
+ return await this.request('get role permissions', () =>
+ this.http.get(`/roles/${encodeURIComponent(roleId)}/permissions`, {
+ params: { page: params?.page, per_page: params?.perPage }
+ })
+ );
}
async addRolePermissions(
roleId: string,
permissions: Array<{ resourceServerIdentifier: string; permissionName: string }>
) {
- await this.http.post(`/roles/${encodeURIComponent(roleId)}/permissions`, {
- permissions: permissions.map(p => ({
- resource_server_identifier: p.resourceServerIdentifier,
- permission_name: p.permissionName
- }))
- });
+ await this.send('add role permissions', () =>
+ this.http.post(`/roles/${encodeURIComponent(roleId)}/permissions`, {
+ permissions: permissions.map(p => ({
+ resource_server_identifier: p.resourceServerIdentifier,
+ permission_name: p.permissionName
+ }))
+ })
+ );
}
async removeRolePermissions(
roleId: string,
permissions: Array<{ resourceServerIdentifier: string; permissionName: string }>
) {
- await this.http.delete(`/roles/${encodeURIComponent(roleId)}/permissions`, {
- data: {
- permissions: permissions.map(p => ({
- resource_server_identifier: p.resourceServerIdentifier,
- permission_name: p.permissionName
- }))
- }
- });
+ await this.send('remove role permissions', () =>
+ this.http.delete(`/roles/${encodeURIComponent(roleId)}/permissions`, {
+ data: {
+ permissions: permissions.map(p => ({
+ resource_server_identifier: p.resourceServerIdentifier,
+ permission_name: p.permissionName
+ }))
+ }
+ })
+ );
}
// ─── Connections ───
@@ -255,22 +298,24 @@ export class Auth0Client {
name?: string;
fields?: string;
}) {
- let response = await this.http.get('/connections', {
- params: {
- page: params?.page,
- per_page: params?.perPage,
- include_totals: params?.includeTotals,
- strategy: params?.strategy,
- name: params?.name,
- fields: params?.fields
- }
- });
- return response.data;
+ return await this.request('list connections', () =>
+ this.http.get('/connections', {
+ params: {
+ page: params?.page,
+ per_page: params?.perPage,
+ include_totals: params?.includeTotals,
+ strategy: params?.strategy,
+ name: params?.name,
+ fields: params?.fields
+ }
+ })
+ );
}
async getConnection(connectionId: string) {
- let response = await this.http.get(`/connections/${encodeURIComponent(connectionId)}`);
- return response.data;
+ return await this.request('get connection', () =>
+ this.http.get(`/connections/${encodeURIComponent(connectionId)}`)
+ );
}
async createConnection(data: {
@@ -280,14 +325,15 @@ export class Auth0Client {
enabledClients?: string[];
metadata?: Record;
}) {
- let response = await this.http.post('/connections', {
- name: data.name,
- strategy: data.strategy,
- options: data.options,
- enabled_clients: data.enabledClients,
- metadata: data.metadata
- });
- return response.data;
+ return await this.request('create connection', () =>
+ this.http.post('/connections', {
+ name: data.name,
+ strategy: data.strategy,
+ options: data.options,
+ enabled_clients: data.enabledClients,
+ metadata: data.metadata
+ })
+ );
}
async updateConnection(
@@ -298,16 +344,19 @@ export class Auth0Client {
metadata?: Record;
}
) {
- let response = await this.http.patch(`/connections/${encodeURIComponent(connectionId)}`, {
- options: data.options,
- enabled_clients: data.enabledClients,
- metadata: data.metadata
- });
- return response.data;
+ return await this.request('update connection', () =>
+ this.http.patch(`/connections/${encodeURIComponent(connectionId)}`, {
+ options: data.options,
+ enabled_clients: data.enabledClients,
+ metadata: data.metadata
+ })
+ );
}
async deleteConnection(connectionId: string) {
- await this.http.delete(`/connections/${encodeURIComponent(connectionId)}`);
+ await this.send('delete connection', () =>
+ this.http.delete(`/connections/${encodeURIComponent(connectionId)}`)
+ );
}
// ─── Applications (Clients) ───
@@ -319,21 +368,23 @@ export class Auth0Client {
fields?: string;
appType?: string;
}) {
- let response = await this.http.get('/clients', {
- params: {
- page: params?.page,
- per_page: params?.perPage,
- include_totals: params?.includeTotals,
- fields: params?.fields,
- app_type: params?.appType
- }
- });
- return response.data;
+ return await this.request('list applications', () =>
+ this.http.get('/clients', {
+ params: {
+ page: params?.page,
+ per_page: params?.perPage,
+ include_totals: params?.includeTotals,
+ fields: params?.fields,
+ app_type: params?.appType
+ }
+ })
+ );
}
async getClient(clientId: string) {
- let response = await this.http.get(`/clients/${encodeURIComponent(clientId)}`);
- return response.data;
+ return await this.request('get application', () =>
+ this.http.get(`/clients/${encodeURIComponent(clientId)}`)
+ );
}
async createClient(data: {
@@ -346,17 +397,18 @@ export class Auth0Client {
allowedLogoutUrls?: string[];
logoUri?: string;
}) {
- let response = await this.http.post('/clients', {
- name: data.name,
- app_type: data.appType,
- description: data.description,
- callbacks: data.callbacks,
- allowed_origins: data.allowedOrigins,
- web_origins: data.webOrigins,
- allowed_logout_urls: data.allowedLogoutUrls,
- logo_uri: data.logoUri
- });
- return response.data;
+ return await this.request('create application', () =>
+ this.http.post('/clients', {
+ name: data.name,
+ app_type: data.appType,
+ description: data.description,
+ callbacks: data.callbacks,
+ allowed_origins: data.allowedOrigins,
+ web_origins: data.webOrigins,
+ allowed_logout_urls: data.allowedLogoutUrls,
+ logo_uri: data.logoUri
+ })
+ );
}
async updateClient(
@@ -372,21 +424,24 @@ export class Auth0Client {
logoUri?: string;
}
) {
- let response = await this.http.patch(`/clients/${encodeURIComponent(clientId)}`, {
- name: data.name,
- app_type: data.appType,
- description: data.description,
- callbacks: data.callbacks,
- allowed_origins: data.allowedOrigins,
- web_origins: data.webOrigins,
- allowed_logout_urls: data.allowedLogoutUrls,
- logo_uri: data.logoUri
- });
- return response.data;
+ return await this.request('update application', () =>
+ this.http.patch(`/clients/${encodeURIComponent(clientId)}`, {
+ name: data.name,
+ app_type: data.appType,
+ description: data.description,
+ callbacks: data.callbacks,
+ allowed_origins: data.allowedOrigins,
+ web_origins: data.webOrigins,
+ allowed_logout_urls: data.allowedLogoutUrls,
+ logo_uri: data.logoUri
+ })
+ );
}
async deleteClient(clientId: string) {
- await this.http.delete(`/clients/${encodeURIComponent(clientId)}`);
+ await this.send('delete application', () =>
+ this.http.delete(`/clients/${encodeURIComponent(clientId)}`)
+ );
}
// ─── Organizations ───
@@ -396,24 +451,27 @@ export class Auth0Client {
perPage?: number;
includeTotals?: boolean;
}) {
- let response = await this.http.get('/organizations', {
- params: {
- page: params?.page,
- per_page: params?.perPage,
- include_totals: params?.includeTotals
- }
- });
- return response.data;
+ return await this.request('list organizations', () =>
+ this.http.get('/organizations', {
+ params: {
+ page: params?.page,
+ per_page: params?.perPage,
+ include_totals: params?.includeTotals
+ }
+ })
+ );
}
async getOrganization(organizationId: string) {
- let response = await this.http.get(`/organizations/${encodeURIComponent(organizationId)}`);
- return response.data;
+ return await this.request('get organization', () =>
+ this.http.get(`/organizations/${encodeURIComponent(organizationId)}`)
+ );
}
async getOrganizationByName(name: string) {
- let response = await this.http.get(`/organizations/name/${encodeURIComponent(name)}`);
- return response.data;
+ return await this.request('get organization by name', () =>
+ this.http.get(`/organizations/name/${encodeURIComponent(name)}`)
+ );
}
async createOrganization(data: {
@@ -422,18 +480,19 @@ export class Auth0Client {
branding?: { logoUrl?: string; colors?: Record };
metadata?: Record;
}) {
- let response = await this.http.post('/organizations', {
- name: data.name,
- display_name: data.displayName,
- branding: data.branding
- ? {
- logo_url: data.branding.logoUrl,
- colors: data.branding.colors
- }
- : undefined,
- metadata: data.metadata
- });
- return response.data;
+ return await this.request('create organization', () =>
+ this.http.post('/organizations', {
+ name: data.name,
+ display_name: data.displayName,
+ branding: data.branding
+ ? {
+ logo_url: data.branding.logoUrl,
+ colors: data.branding.colors
+ }
+ : undefined,
+ metadata: data.metadata
+ })
+ );
}
async updateOrganization(
@@ -445,9 +504,8 @@ export class Auth0Client {
metadata?: Record;
}
) {
- let response = await this.http.patch(
- `/organizations/${encodeURIComponent(organizationId)}`,
- {
+ return await this.request('update organization', () =>
+ this.http.patch(`/organizations/${encodeURIComponent(organizationId)}`, {
name: data.name,
display_name: data.displayName,
branding: data.branding
@@ -457,38 +515,86 @@ export class Auth0Client {
}
: undefined,
metadata: data.metadata
- }
+ })
);
- return response.data;
}
async deleteOrganization(organizationId: string) {
- await this.http.delete(`/organizations/${encodeURIComponent(organizationId)}`);
+ await this.send('delete organization', () =>
+ this.http.delete(`/organizations/${encodeURIComponent(organizationId)}`)
+ );
}
async listOrganizationMembers(
organizationId: string,
params?: { page?: number; perPage?: number }
) {
- let response = await this.http.get(
- `/organizations/${encodeURIComponent(organizationId)}/members`,
- {
+ return await this.request('list organization members', () =>
+ this.http.get(`/organizations/${encodeURIComponent(organizationId)}/members`, {
params: { page: params?.page, per_page: params?.perPage }
- }
+ })
);
- return response.data;
}
async addOrganizationMembers(organizationId: string, memberIds: string[]) {
- await this.http.post(`/organizations/${encodeURIComponent(organizationId)}/members`, {
- members: memberIds
- });
+ await this.send('add organization members', () =>
+ this.http.post(`/organizations/${encodeURIComponent(organizationId)}/members`, {
+ members: memberIds
+ })
+ );
}
async removeOrganizationMembers(organizationId: string, memberIds: string[]) {
- await this.http.delete(`/organizations/${encodeURIComponent(organizationId)}/members`, {
- data: { members: memberIds }
- });
+ await this.send('remove organization members', () =>
+ this.http.delete(`/organizations/${encodeURIComponent(organizationId)}/members`, {
+ data: { members: memberIds }
+ })
+ );
+ }
+
+ async getOrganizationMemberRoles(
+ organizationId: string,
+ userId: string,
+ params?: { page?: number; perPage?: number }
+ ) {
+ return await this.request('get organization member roles', () =>
+ this.http.get(
+ `/organizations/${encodeURIComponent(organizationId)}/members/${encodeURIComponent(userId)}/roles`,
+ {
+ params: { page: params?.page, per_page: params?.perPage }
+ }
+ )
+ );
+ }
+
+ async assignOrganizationMemberRoles(
+ organizationId: string,
+ userId: string,
+ roleIds: string[]
+ ) {
+ await this.send('assign organization member roles', () =>
+ this.http.post(
+ `/organizations/${encodeURIComponent(organizationId)}/members/${encodeURIComponent(userId)}/roles`,
+ {
+ roles: roleIds
+ }
+ )
+ );
+ }
+
+ async removeOrganizationMemberRoles(
+ organizationId: string,
+ userId: string,
+ roleIds: string[]
+ ) {
+ await this.send('remove organization member roles', () =>
+ this.http.delete(
+ `/organizations/${encodeURIComponent(organizationId)}/members/${encodeURIComponent(userId)}/roles`,
+ {
+ data: { roles: roleIds }
+ }
+ )
+ );
}
// ─── Logs ───
@@ -504,25 +610,27 @@ export class Auth0Client {
from?: string;
take?: number;
}) {
- let response = await this.http.get('/logs', {
- params: {
- q: params?.q,
- page: params?.page,
- per_page: params?.perPage,
- sort: params?.sort,
- fields: params?.fields,
- include_fields: params?.includeFields,
- include_totals: params?.includeTotals,
- from: params?.from,
- take: params?.take
- }
- });
- return response.data;
+ return await this.request('get logs', () =>
+ this.http.get('/logs', {
+ params: {
+ q: params?.q,
+ page: params?.page,
+ per_page: params?.perPage,
+ sort: params?.sort,
+ fields: params?.fields,
+ include_fields: params?.includeFields,
+ include_totals: params?.includeTotals,
+ from: params?.from,
+ take: params?.take
+ }
+ })
+ );
}
async getLogEvent(logEventId: string) {
- let response = await this.http.get(`/logs/${encodeURIComponent(logEventId)}`);
- return response.data;
+ return await this.request('get log event', () =>
+ this.http.get(`/logs/${encodeURIComponent(logEventId)}`)
+ );
}
// ─── Resource Servers (APIs) ───
@@ -532,21 +640,21 @@ export class Auth0Client {
perPage?: number;
includeTotals?: boolean;
}) {
- let response = await this.http.get('/resource-servers', {
- params: {
- page: params?.page,
- per_page: params?.perPage,
- include_totals: params?.includeTotals
- }
- });
- return response.data;
+ return await this.request('list resource servers', () =>
+ this.http.get('/resource-servers', {
+ params: {
+ page: params?.page,
+ per_page: params?.perPage,
+ include_totals: params?.includeTotals
+ }
+ })
+ );
}
async getResourceServer(resourceServerId: string) {
- let response = await this.http.get(
- `/resource-servers/${encodeURIComponent(resourceServerId)}`
+ return await this.request('get resource server', () =>
+ this.http.get(`/resource-servers/${encodeURIComponent(resourceServerId)}`)
);
- return response.data;
}
async createResourceServer(data: {
@@ -558,17 +666,18 @@ export class Auth0Client {
tokenDialect?: string;
skipConsentForVerifiableFirstPartyClients?: boolean;
}) {
- let response = await this.http.post('/resource-servers', {
- name: data.name,
- identifier: data.identifier,
- scopes: data.scopes,
- signing_alg: data.signingAlg,
- token_lifetime: data.tokenLifetime,
- token_dialect: data.tokenDialect,
- skip_consent_for_verifiable_first_party_clients:
- data.skipConsentForVerifiableFirstPartyClients
- });
- return response.data;
+ return await this.request('create resource server', () =>
+ this.http.post('/resource-servers', {
+ name: data.name,
+ identifier: data.identifier,
+ scopes: data.scopes,
+ signing_alg: data.signingAlg,
+ token_lifetime: data.tokenLifetime,
+ token_dialect: data.tokenDialect,
+ skip_consent_for_verifiable_first_party_clients:
+ data.skipConsentForVerifiableFirstPartyClients
+ })
+ );
}
async updateResourceServer(
@@ -582,9 +691,8 @@ export class Auth0Client {
skipConsentForVerifiableFirstPartyClients?: boolean;
}
) {
- let response = await this.http.patch(
- `/resource-servers/${encodeURIComponent(resourceServerId)}`,
- {
+ return await this.request('update resource server', () =>
+ this.http.patch(`/resource-servers/${encodeURIComponent(resourceServerId)}`, {
name: data.name,
scopes: data.scopes,
signing_alg: data.signingAlg,
@@ -592,13 +700,14 @@ export class Auth0Client {
token_dialect: data.tokenDialect,
skip_consent_for_verifiable_first_party_clients:
data.skipConsentForVerifiableFirstPartyClients
- }
+ })
);
- return response.data;
}
async deleteResourceServer(resourceServerId: string) {
- await this.http.delete(`/resource-servers/${encodeURIComponent(resourceServerId)}`);
+ await this.send('delete resource server', () =>
+ this.http.delete(`/resource-servers/${encodeURIComponent(resourceServerId)}`)
+ );
}
// ─── Client Grants ───
@@ -609,47 +718,52 @@ export class Auth0Client {
audience?: string;
clientId?: string;
}) {
- let response = await this.http.get('/client-grants', {
- params: {
- page: params?.page,
- per_page: params?.perPage,
- audience: params?.audience,
- client_id: params?.clientId
- }
- });
- return response.data;
+ return await this.request('list client grants', () =>
+ this.http.get('/client-grants', {
+ params: {
+ page: params?.page,
+ per_page: params?.perPage,
+ audience: params?.audience,
+ client_id: params?.clientId
+ }
+ })
+ );
}
async createClientGrant(data: { clientId: string; audience: string; scope: string[] }) {
- let response = await this.http.post('/client-grants', {
- client_id: data.clientId,
- audience: data.audience,
- scope: data.scope
- });
- return response.data;
+ return await this.request('create client grant', () =>
+ this.http.post('/client-grants', {
+ client_id: data.clientId,
+ audience: data.audience,
+ scope: data.scope
+ })
+ );
}
async updateClientGrant(grantId: string, data: { scope: string[] }) {
- let response = await this.http.patch(`/client-grants/${encodeURIComponent(grantId)}`, {
- scope: data.scope
- });
- return response.data;
+ return await this.request('update client grant', () =>
+ this.http.patch(`/client-grants/${encodeURIComponent(grantId)}`, {
+ scope: data.scope
+ })
+ );
}
async deleteClientGrant(grantId: string) {
- await this.http.delete(`/client-grants/${encodeURIComponent(grantId)}`);
+ await this.send('delete client grant', () =>
+ this.http.delete(`/client-grants/${encodeURIComponent(grantId)}`)
+ );
}
// ─── Log Streams ───
async listLogStreams() {
- let response = await this.http.get('/log-streams');
- return response.data;
+ return await this.request('list log streams', () => this.http.get('/log-streams'));
}
async getLogStream(logStreamId: string) {
- let response = await this.http.get(`/log-streams/${encodeURIComponent(logStreamId)}`);
- return response.data;
+ return await this.request('get log stream', () =>
+ this.http.get(`/log-streams/${encodeURIComponent(logStreamId)}`)
+ );
}
async createLogStream(data: {
@@ -658,35 +772,57 @@ export class Auth0Client {
sink: Record;
filters?: Array<{ type: string; name: string }>;
}) {
- let response = await this.http.post('/log-streams', {
- name: data.name,
- type: data.type,
- sink: data.sink,
- filters: data.filters
- });
- return response.data;
+ return await this.request('create log stream', () =>
+ this.http.post('/log-streams', {
+ name: data.name,
+ type: data.type,
+ sink: data.sink,
+ filters: data.filters
+ })
+ );
+ }
+
+ async updateLogStream(
+ logStreamId: string,
+ data: {
+ name?: string;
+ status?: string;
+ filters?: Array<{ type: string; name: string }>;
+ }
+ ) {
+ return await this.request('update log stream', () =>
+ this.http.patch(`/log-streams/${encodeURIComponent(logStreamId)}`, {
+ name: data.name,
+ status: data.status,
+ filters: data.filters
+ })
+ );
}
async deleteLogStream(logStreamId: string) {
- await this.http.delete(`/log-streams/${encodeURIComponent(logStreamId)}`);
+ await this.send('delete log stream', () =>
+ this.http.delete(`/log-streams/${encodeURIComponent(logStreamId)}`)
+ );
}
// ─── Actions ───
async listActions(params?: { triggerId?: string; deployed?: boolean; installed?: boolean }) {
- let response = await this.http.get('/actions/actions', {
- params: {
- triggerId: params?.triggerId,
- deployed: params?.deployed,
- installed: params?.installed
- }
- });
- return response.data;
+ return await this.request('list actions', () =>
+ this.http.get('/actions/actions', {
+ params: {
+ triggerId: params?.triggerId,
+ deployed: params?.deployed,
+ installed: params?.installed
+ }
+ })
+ );
}
async getAction(actionId: string) {
- let response = await this.http.get(`/actions/actions/${encodeURIComponent(actionId)}`);
- return response.data;
+ return await this.request('get action', () =>
+ this.http.get(`/actions/actions/${encodeURIComponent(actionId)}`)
+ );
}
async createAction(data: {
@@ -696,14 +832,15 @@ export class Auth0Client {
dependencies?: Array<{ name: string; version: string }>;
secrets?: Array<{ name: string; value: string }>;
}) {
- let response = await this.http.post('/actions/actions', {
- name: data.name,
- supported_triggers: data.supportedTriggers,
- code: data.code,
- dependencies: data.dependencies,
- secrets: data.secrets
- });
- return response.data;
+ return await this.request('create action', () =>
+ this.http.post('/actions/actions', {
+ name: data.name,
+ supported_triggers: data.supportedTriggers,
+ code: data.code,
+ dependencies: data.dependencies,
+ secrets: data.secrets
+ })
+ );
}
async updateAction(
@@ -715,23 +852,25 @@ export class Auth0Client {
secrets?: Array<{ name: string; value: string }>;
}
) {
- let response = await this.http.patch(`/actions/actions/${encodeURIComponent(actionId)}`, {
- name: data.name,
- code: data.code,
- dependencies: data.dependencies,
- secrets: data.secrets
- });
- return response.data;
+ return await this.request('update action', () =>
+ this.http.patch(`/actions/actions/${encodeURIComponent(actionId)}`, {
+ name: data.name,
+ code: data.code,
+ dependencies: data.dependencies,
+ secrets: data.secrets
+ })
+ );
}
async deleteAction(actionId: string) {
- await this.http.delete(`/actions/actions/${encodeURIComponent(actionId)}`);
+ await this.send('delete action', () =>
+ this.http.delete(`/actions/actions/${encodeURIComponent(actionId)}`)
+ );
}
async deployAction(actionId: string) {
- let response = await this.http.post(
- `/actions/actions/${encodeURIComponent(actionId)}/deploy`
+ return await this.request('deploy action', () =>
+ this.http.post(`/actions/actions/${encodeURIComponent(actionId)}/deploy`)
);
- return response.data;
}
}
diff --git a/integrations/auth0/src/lib/errors.ts b/integrations/auth0/src/lib/errors.ts
new file mode 100644
index 0000000000..ca0498005f
--- /dev/null
+++ b/integrations/auth0/src/lib/errors.ts
@@ -0,0 +1,104 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null;
+
+let addDetail = (details: string[], value: unknown) => {
+ if (typeof value !== 'string') {
+ return;
+ }
+
+ let trimmed = value.trim();
+ if (trimmed && !details.includes(trimmed)) {
+ details.push(trimmed);
+ }
+};
+
+let extractAuth0Message = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let data = response?.data;
+ let details: string[] = [];
+
+ if (isRecord(data)) {
+ for (let key of ['message', 'error_description', 'error', 'errorCode', 'code']) {
+ addDetail(details, data[key]);
+ }
+ } else {
+ addDetail(details, data);
+ }
+
+ if (details.length > 0) {
+ return details.join(' - ');
+ }
+
+ if (error instanceof Error && error.message) {
+ return error.message;
+ }
+
+ return 'Unknown error';
+};
+
+let getAuth0ErrorStatus = (error: unknown) => {
+ if (!isRecord(error)) {
+ return undefined;
+ }
+
+ let response = error.response as ErrorResponse | undefined;
+ return (
+ response?.status ?? error.status ?? (isRecord(error.data) ? error.data.status : undefined)
+ );
+};
+
+export let auth0ServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let auth0ApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) {
+ return error;
+ }
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let status = getAuth0ErrorStatus(error);
+ let statusLabel =
+ status !== undefined
+ ? `HTTP ${status}${response?.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+
+ let serviceError = auth0ServiceError(
+ `Auth0 API ${operation} failed: ${statusLabel}${extractAuth0Message(error)}`
+ );
+ serviceError.data.reason = 'auth0_api_error';
+ serviceError.data.upstreamStatus = status;
+
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+
+ return serviceError;
+};
+
+export let requireField = (value: T | undefined | null, label: string, action: string) => {
+ if (value === undefined || value === null || value === '') {
+ throw auth0ServiceError(`${label} is required for ${action} action.`);
+ }
+
+ return value;
+};
+
+export let requireNonEmptyArray = (
+ value: T[] | undefined | null,
+ label: string,
+ action: string
+) => {
+ if (!Array.isArray(value) || value.length === 0) {
+ throw auth0ServiceError(`${label} must contain at least one item for ${action} action.`);
+ }
+
+ return value;
+};
diff --git a/integrations/auth0/src/tools.schema.test.ts b/integrations/auth0/src/tools.schema.test.ts
new file mode 100644
index 0000000000..e494e329e7
--- /dev/null
+++ b/integrations/auth0/src/tools.schema.test.ts
@@ -0,0 +1,4 @@
+import { describeMcpCompatibleToolSchemas } from '@slates/test';
+import { provider } from './index';
+
+describeMcpCompatibleToolSchemas('Auth0 tool input schemas', provider.actions);
diff --git a/integrations/auth0/src/tools/index.ts b/integrations/auth0/src/tools/index.ts
index 5914af76f5..959131ae11 100644
--- a/integrations/auth0/src/tools/index.ts
+++ b/integrations/auth0/src/tools/index.ts
@@ -6,10 +6,14 @@ export { manageActionsTool } from './manage-actions';
export { manageApplicationsTool } from './manage-applications';
export { manageClientGrantsTool } from './manage-client-grants';
export { manageConnectionsTool } from './manage-connections';
+export { manageLogStreamsTool } from './manage-log-streams';
+export { manageOrganizationMemberRolesTool } from './manage-organization-member-roles';
export { manageOrganizationMembersTool } from './manage-organization-members';
export { manageOrganizationsTool } from './manage-organizations';
export { manageResourceServersTool } from './manage-resource-servers';
+export { manageRolePermissionsTool } from './manage-role-permissions';
export { manageRolesTool } from './manage-roles';
+export { manageUserPermissionsTool } from './manage-user-permissions';
export { manageUserRolesTool } from './manage-user-roles';
export { searchUsersTool } from './search-users';
export { updateUserTool } from './update-user';
diff --git a/integrations/auth0/src/tools/manage-actions.ts b/integrations/auth0/src/tools/manage-actions.ts
index d815de71fd..0c86f05318 100644
--- a/integrations/auth0/src/tools/manage-actions.ts
+++ b/integrations/auth0/src/tools/manage-actions.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField } from '../lib/errors';
import { spec } from '../spec';
export let manageActionsTool = SlateTool.create(spec, {
@@ -109,8 +110,8 @@ export let manageActionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.actionId) throw new Error('actionId is required for get action');
- let a = await client.getAction(ctx.input.actionId);
+ let actionId = requireField(ctx.input.actionId, 'actionId', 'get');
+ let a = await client.getAction(actionId);
return {
output: { actionDetails: mapAction(a) },
message: `Retrieved action **${a.name}** (${a.status}).`
@@ -118,15 +119,13 @@ export let manageActionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.name) throw new Error('name is required for create action');
- if (!ctx.input.triggerId) throw new Error('triggerId is required for create action');
- if (!ctx.input.code) throw new Error('code is required for create action');
+ let name = requireField(ctx.input.name, 'name', 'create');
+ let triggerId = requireField(ctx.input.triggerId, 'triggerId', 'create');
+ let code = requireField(ctx.input.code, 'code', 'create');
let a = await client.createAction({
- name: ctx.input.name,
- supportedTriggers: [
- { id: ctx.input.triggerId, version: ctx.input.triggerVersion || 'v3' }
- ],
- code: ctx.input.code,
+ name,
+ supportedTriggers: [{ id: triggerId, version: ctx.input.triggerVersion || 'v3' }],
+ code,
dependencies: ctx.input.dependencies,
secrets: ctx.input.secrets
});
@@ -137,8 +136,8 @@ export let manageActionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'update') {
- if (!ctx.input.actionId) throw new Error('actionId is required for update action');
- let a = await client.updateAction(ctx.input.actionId, {
+ let actionId = requireField(ctx.input.actionId, 'actionId', 'update');
+ let a = await client.updateAction(actionId, {
name: ctx.input.name,
code: ctx.input.code,
dependencies: ctx.input.dependencies,
@@ -151,8 +150,8 @@ export let manageActionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'deploy') {
- if (!ctx.input.actionId) throw new Error('actionId is required for deploy action');
- let _a = await client.deployAction(ctx.input.actionId);
+ let actionId = requireField(ctx.input.actionId, 'actionId', 'deploy');
+ let _a = await client.deployAction(actionId);
return {
output: { deployed: true },
message: `Deployed action successfully.`
@@ -160,14 +159,14 @@ export let manageActionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.actionId) throw new Error('actionId is required for delete action');
- await client.deleteAction(ctx.input.actionId);
+ let actionId = requireField(ctx.input.actionId, 'actionId', 'delete');
+ await client.deleteAction(actionId);
return {
output: { deleted: true },
- message: `Deleted action **${ctx.input.actionId}**.`
+ message: `Deleted action **${actionId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/auth0/src/tools/manage-applications.ts b/integrations/auth0/src/tools/manage-applications.ts
index ce9c6a731d..182da6e5be 100644
--- a/integrations/auth0/src/tools/manage-applications.ts
+++ b/integrations/auth0/src/tools/manage-applications.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField } from '../lib/errors';
import { spec } from '../spec';
export let manageApplicationsTool = SlateTool.create(spec, {
@@ -98,8 +99,8 @@ export let manageApplicationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.clientId) throw new Error('clientId is required for get action');
- let app = await client.getClient(ctx.input.clientId);
+ let clientId = requireField(ctx.input.clientId, 'clientId', 'get');
+ let app = await client.getClient(clientId);
return {
output: { application: mapApp(app) },
message: `Retrieved application **${app.name}**.`
@@ -107,9 +108,9 @@ export let manageApplicationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.name) throw new Error('name is required for create action');
+ let name = requireField(ctx.input.name, 'name', 'create');
let app = await client.createClient({
- name: ctx.input.name,
+ name,
appType: ctx.input.appType,
description: ctx.input.description,
callbacks: ctx.input.callbacks,
@@ -125,8 +126,8 @@ export let manageApplicationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'update') {
- if (!ctx.input.clientId) throw new Error('clientId is required for update action');
- let app = await client.updateClient(ctx.input.clientId, {
+ let clientId = requireField(ctx.input.clientId, 'clientId', 'update');
+ let app = await client.updateClient(clientId, {
name: ctx.input.name,
appType: ctx.input.appType,
description: ctx.input.description,
@@ -143,14 +144,14 @@ export let manageApplicationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.clientId) throw new Error('clientId is required for delete action');
- await client.deleteClient(ctx.input.clientId);
+ let clientId = requireField(ctx.input.clientId, 'clientId', 'delete');
+ await client.deleteClient(clientId);
return {
output: { deleted: true },
- message: `Deleted application **${ctx.input.clientId}**.`
+ message: `Deleted application **${clientId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/auth0/src/tools/manage-client-grants.ts b/integrations/auth0/src/tools/manage-client-grants.ts
index 66168d6a62..dc1fe1e063 100644
--- a/integrations/auth0/src/tools/manage-client-grants.ts
+++ b/integrations/auth0/src/tools/manage-client-grants.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField, requireNonEmptyArray } from '../lib/errors';
import { spec } from '../spec';
export let manageClientGrantsTool = SlateTool.create(spec, {
@@ -86,13 +87,13 @@ export let manageClientGrantsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.clientId) throw new Error('clientId is required for create action');
- if (!ctx.input.audience) throw new Error('audience is required for create action');
- if (!ctx.input.scope) throw new Error('scope is required for create action');
+ let clientId = requireField(ctx.input.clientId, 'clientId', 'create');
+ let audience = requireField(ctx.input.audience, 'audience', 'create');
+ let scope = requireNonEmptyArray(ctx.input.scope, 'scope', 'create');
let grant = await client.createClientGrant({
- clientId: ctx.input.clientId,
- audience: ctx.input.audience,
- scope: ctx.input.scope
+ clientId,
+ audience,
+ scope
});
return {
output: { grant: mapGrant(grant) },
@@ -101,10 +102,10 @@ export let manageClientGrantsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'update') {
- if (!ctx.input.grantId) throw new Error('grantId is required for update action');
- if (!ctx.input.scope) throw new Error('scope is required for update action');
- let grant = await client.updateClientGrant(ctx.input.grantId, {
- scope: ctx.input.scope
+ let grantId = requireField(ctx.input.grantId, 'grantId', 'update');
+ let scope = requireNonEmptyArray(ctx.input.scope, 'scope', 'update');
+ let grant = await client.updateClientGrant(grantId, {
+ scope
});
return {
output: { grant: mapGrant(grant) },
@@ -113,14 +114,14 @@ export let manageClientGrantsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.grantId) throw new Error('grantId is required for delete action');
- await client.deleteClientGrant(ctx.input.grantId);
+ let grantId = requireField(ctx.input.grantId, 'grantId', 'delete');
+ await client.deleteClientGrant(grantId);
return {
output: { deleted: true },
- message: `Deleted client grant **${ctx.input.grantId}**.`
+ message: `Deleted client grant **${grantId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/auth0/src/tools/manage-connections.ts b/integrations/auth0/src/tools/manage-connections.ts
index cc47561e25..fd7bb394df 100644
--- a/integrations/auth0/src/tools/manage-connections.ts
+++ b/integrations/auth0/src/tools/manage-connections.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField } from '../lib/errors';
import { spec } from '../spec';
export let manageConnectionsTool = SlateTool.create(spec, {
@@ -95,8 +96,8 @@ export let manageConnectionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.connectionId) throw new Error('connectionId is required for get action');
- let conn = await client.getConnection(ctx.input.connectionId);
+ let connectionId = requireField(ctx.input.connectionId, 'connectionId', 'get');
+ let conn = await client.getConnection(connectionId);
return {
output: { connection: mapConn(conn) },
message: `Retrieved connection **${conn.name}** (${conn.strategy}).`
@@ -104,11 +105,11 @@ export let manageConnectionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.name) throw new Error('name is required for create action');
- if (!ctx.input.strategy) throw new Error('strategy is required for create action');
+ let name = requireField(ctx.input.name, 'name', 'create');
+ let strategy = requireField(ctx.input.strategy, 'strategy', 'create');
let conn = await client.createConnection({
- name: ctx.input.name,
- strategy: ctx.input.strategy,
+ name,
+ strategy,
options: ctx.input.options,
enabledClients: ctx.input.enabledClients,
metadata: ctx.input.metadata
@@ -120,9 +121,8 @@ export let manageConnectionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'update') {
- if (!ctx.input.connectionId)
- throw new Error('connectionId is required for update action');
- let conn = await client.updateConnection(ctx.input.connectionId, {
+ let connectionId = requireField(ctx.input.connectionId, 'connectionId', 'update');
+ let conn = await client.updateConnection(connectionId, {
options: ctx.input.options,
enabledClients: ctx.input.enabledClients,
metadata: ctx.input.metadata
@@ -134,15 +134,14 @@ export let manageConnectionsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.connectionId)
- throw new Error('connectionId is required for delete action');
- await client.deleteConnection(ctx.input.connectionId);
+ let connectionId = requireField(ctx.input.connectionId, 'connectionId', 'delete');
+ await client.deleteConnection(connectionId);
return {
output: { deleted: true },
- message: `Deleted connection **${ctx.input.connectionId}**.`
+ message: `Deleted connection **${connectionId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/auth0/src/tools/manage-log-streams.ts b/integrations/auth0/src/tools/manage-log-streams.ts
new file mode 100644
index 0000000000..e0b5a8c5b7
--- /dev/null
+++ b/integrations/auth0/src/tools/manage-log-streams.ts
@@ -0,0 +1,159 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField } from '../lib/errors';
+import { spec } from '../spec';
+
+let filterSchema = z.object({
+ type: z.string().describe('Filter type, such as category'),
+ name: z.string().describe('Filter value/name')
+});
+
+let mapLogStream = (stream: any) => ({
+ logStreamId: stream.id,
+ name: stream.name,
+ type: stream.type,
+ status: stream.status,
+ sink: stream.sink,
+ filters: stream.filters
+});
+
+export let manageLogStreamsTool = SlateTool.create(spec, {
+ name: 'Manage Log Streams',
+ key: 'manage_log_streams',
+ description:
+ 'Create, update, delete, get, or list Auth0 log streams for delivering tenant logs to HTTP webhooks and supported event destinations.',
+ instructions: [
+ 'For create, provide type and sink. For HTTP streams, sink commonly includes httpEndpoint, httpContentType, httpContentFormat, and optional httpAuthorization.',
+ 'For update, provide logStreamId plus any of name, status, or filters.'
+ ],
+ tags: {
+ destructive: false
+ }
+})
+ .input(
+ z.object({
+ action: z
+ .enum(['list', 'get', 'create', 'update', 'delete'])
+ .describe('Action to perform'),
+ logStreamId: z
+ .string()
+ .optional()
+ .describe('Log stream ID; required for get, update, and delete'),
+ name: z.string().optional().describe('Log stream name; required for create'),
+ type: z
+ .string()
+ .optional()
+ .describe(
+ 'Log stream type, such as http, eventbridge, eventgrid, splunk, sumo, or datadog'
+ ),
+ sink: z
+ .record(z.string(), z.unknown())
+ .optional()
+ .describe('Destination-specific sink configuration; required for create'),
+ status: z
+ .enum(['active', 'paused'])
+ .optional()
+ .describe('Log stream status for update action'),
+ filters: z
+ .array(filterSchema)
+ .optional()
+ .describe('Optional log stream filters for create or update')
+ })
+ )
+ .output(
+ z.object({
+ logStream: z
+ .object({
+ logStreamId: z.string(),
+ name: z.string(),
+ type: z.string(),
+ status: z.string().optional(),
+ sink: z.record(z.string(), z.unknown()).optional(),
+ filters: z.array(filterSchema).optional()
+ })
+ .optional()
+ .describe('Log stream details'),
+ logStreams: z
+ .array(
+ z.object({
+ logStreamId: z.string(),
+ name: z.string(),
+ type: z.string(),
+ status: z.string().optional(),
+ sink: z.record(z.string(), z.unknown()).optional(),
+ filters: z.array(filterSchema).optional()
+ })
+ )
+ .optional()
+ .describe('List of log streams'),
+ deleted: z.boolean().optional().describe('Whether the log stream was deleted')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Auth0Client({
+ token: ctx.auth.token,
+ domain: ctx.auth.domain
+ });
+
+ if (ctx.input.action === 'list') {
+ let result = await client.listLogStreams();
+ let logStreams = (Array.isArray(result) ? result : (result.log_streams ?? [])).map(
+ mapLogStream
+ );
+ return {
+ output: { logStreams },
+ message: `Found **${logStreams.length}** log stream(s).`
+ };
+ }
+
+ if (ctx.input.action === 'get') {
+ let logStreamId = requireField(ctx.input.logStreamId, 'logStreamId', 'get');
+ let logStream = await client.getLogStream(logStreamId);
+ return {
+ output: { logStream: mapLogStream(logStream) },
+ message: `Retrieved log stream **${logStream.name}**.`
+ };
+ }
+
+ if (ctx.input.action === 'create') {
+ let name = requireField(ctx.input.name, 'name', 'create');
+ let type = requireField(ctx.input.type, 'type', 'create');
+ let sink = requireField(ctx.input.sink, 'sink', 'create');
+ let logStream = await client.createLogStream({
+ name,
+ type,
+ sink,
+ filters: ctx.input.filters
+ });
+ return {
+ output: { logStream: mapLogStream(logStream) },
+ message: `Created log stream **${logStream.name}**.`
+ };
+ }
+
+ if (ctx.input.action === 'update') {
+ let logStreamId = requireField(ctx.input.logStreamId, 'logStreamId', 'update');
+ let logStream = await client.updateLogStream(logStreamId, {
+ name: ctx.input.name,
+ status: ctx.input.status,
+ filters: ctx.input.filters
+ });
+ return {
+ output: { logStream: mapLogStream(logStream) },
+ message: `Updated log stream **${logStream.name}**.`
+ };
+ }
+
+ if (ctx.input.action === 'delete') {
+ let logStreamId = requireField(ctx.input.logStreamId, 'logStreamId', 'delete');
+ await client.deleteLogStream(logStreamId);
+ return {
+ output: { deleted: true },
+ message: `Deleted log stream **${logStreamId}**.`
+ };
+ }
+
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
+ })
+ .build();
diff --git a/integrations/auth0/src/tools/manage-organization-member-roles.ts b/integrations/auth0/src/tools/manage-organization-member-roles.ts
new file mode 100644
index 0000000000..2ee6890a0d
--- /dev/null
+++ b/integrations/auth0/src/tools/manage-organization-member-roles.ts
@@ -0,0 +1,101 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Auth0Client } from '../lib/client';
+import { requireNonEmptyArray } from '../lib/errors';
+import { spec } from '../spec';
+import { dispatchAuth0Action } from './shared';
+
+let mapRole = (role: any) => ({
+ roleId: role.id,
+ name: role.name,
+ description: role.description
+});
+
+export let manageOrganizationMemberRolesTool = SlateTool.create(spec, {
+ name: 'Manage Organization Member Roles',
+ key: 'manage_organization_member_roles',
+ description:
+ 'List, assign, or remove roles for a user inside a specific Auth0 Organization membership.',
+ tags: {
+ destructive: false
+ }
+})
+ .input(
+ z.object({
+ organizationId: z.string().describe('The Auth0 organization ID'),
+ userId: z.string().describe('The Auth0 user ID of the organization member'),
+ action: z.enum(['list', 'assign', 'remove']).describe('Action to perform'),
+ roleIds: z
+ .array(z.string())
+ .optional()
+ .describe('Role IDs to assign or remove; required for assign/remove'),
+ page: z.number().optional().describe('Page number for list action'),
+ perPage: z.number().optional().describe('Results per page for list action')
+ })
+ )
+ .output(
+ z.object({
+ roles: z
+ .array(
+ z.object({
+ roleId: z.string(),
+ name: z.string(),
+ description: z.string().optional()
+ })
+ )
+ .optional()
+ .describe('Organization member roles for list action'),
+ success: z.boolean().describe('Whether the operation succeeded')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Auth0Client({
+ token: ctx.auth.token,
+ domain: ctx.auth.domain
+ });
+
+ return dispatchAuth0Action(ctx.input.action, {
+ list: async () => {
+ let result = await client.getOrganizationMemberRoles(
+ ctx.input.organizationId,
+ ctx.input.userId,
+ {
+ page: ctx.input.page,
+ perPage: ctx.input.perPage
+ }
+ );
+ let roles = (Array.isArray(result) ? result : (result.roles ?? [])).map(mapRole);
+ return {
+ output: { roles, success: true },
+ message: `Organization member has **${roles.length}** role(s).`
+ };
+ },
+
+ assign: async () => {
+ let roleIds = requireNonEmptyArray(ctx.input.roleIds, 'roleIds', 'assign');
+ await client.assignOrganizationMemberRoles(
+ ctx.input.organizationId,
+ ctx.input.userId,
+ roleIds
+ );
+ return {
+ output: { success: true },
+ message: `Assigned **${roleIds.length}** organization member role(s).`
+ };
+ },
+
+ remove: async () => {
+ let roleIds = requireNonEmptyArray(ctx.input.roleIds, 'roleIds', 'remove');
+ await client.removeOrganizationMemberRoles(
+ ctx.input.organizationId,
+ ctx.input.userId,
+ roleIds
+ );
+ return {
+ output: { success: true },
+ message: `Removed **${roleIds.length}** organization member role(s).`
+ };
+ }
+ });
+ })
+ .build();
diff --git a/integrations/auth0/src/tools/manage-organization-members.ts b/integrations/auth0/src/tools/manage-organization-members.ts
index 4075a14c91..78c64b117d 100644
--- a/integrations/auth0/src/tools/manage-organization-members.ts
+++ b/integrations/auth0/src/tools/manage-organization-members.ts
@@ -1,7 +1,9 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { requireNonEmptyArray } from '../lib/errors';
import { spec } from '../spec';
+import { dispatchAuth0Action } from './shared';
export let manageOrganizationMembersTool = SlateTool.create(spec, {
name: 'Manage Organization Members',
@@ -45,44 +47,43 @@ export let manageOrganizationMembersTool = SlateTool.create(spec, {
domain: ctx.auth.domain
});
- if (ctx.input.action === 'list') {
- let result = await client.listOrganizationMembers(ctx.input.organizationId, {
- page: ctx.input.page,
- perPage: ctx.input.perPage
- });
- let members = (Array.isArray(result) ? result : (result.members ?? [])).map(
- (m: any) => ({
- userId: m.user_id,
- email: m.email,
- name: m.name,
- picture: m.picture
- })
- );
- return {
- output: { members, success: true },
- message: `Organization has **${members.length}** member(s).`
- };
- }
-
- if (ctx.input.action === 'add') {
- if (!ctx.input.userIds?.length) throw new Error('userIds are required for add action');
- await client.addOrganizationMembers(ctx.input.organizationId, ctx.input.userIds);
- return {
- output: { success: true },
- message: `Added **${ctx.input.userIds.length}** member(s) to organization.`
- };
- }
+ return dispatchAuth0Action(ctx.input.action, {
+ list: async () => {
+ let result = await client.listOrganizationMembers(ctx.input.organizationId, {
+ page: ctx.input.page,
+ perPage: ctx.input.perPage
+ });
+ let members = (Array.isArray(result) ? result : (result.members ?? [])).map(
+ (m: any) => ({
+ userId: m.user_id,
+ email: m.email,
+ name: m.name,
+ picture: m.picture
+ })
+ );
+ return {
+ output: { members, success: true },
+ message: `Organization has **${members.length}** member(s).`
+ };
+ },
- if (ctx.input.action === 'remove') {
- if (!ctx.input.userIds?.length)
- throw new Error('userIds are required for remove action');
- await client.removeOrganizationMembers(ctx.input.organizationId, ctx.input.userIds);
- return {
- output: { success: true },
- message: `Removed **${ctx.input.userIds.length}** member(s) from organization.`
- };
- }
+ add: async () => {
+ let userIds = requireNonEmptyArray(ctx.input.userIds, 'userIds', 'add');
+ await client.addOrganizationMembers(ctx.input.organizationId, userIds);
+ return {
+ output: { success: true },
+ message: `Added **${userIds.length}** member(s) to organization.`
+ };
+ },
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ remove: async () => {
+ let userIds = requireNonEmptyArray(ctx.input.userIds, 'userIds', 'remove');
+ await client.removeOrganizationMembers(ctx.input.organizationId, userIds);
+ return {
+ output: { success: true },
+ message: `Removed **${userIds.length}** member(s) from organization.`
+ };
+ }
+ });
})
.build();
diff --git a/integrations/auth0/src/tools/manage-organizations.ts b/integrations/auth0/src/tools/manage-organizations.ts
index 7921849a36..aef59cc533 100644
--- a/integrations/auth0/src/tools/manage-organizations.ts
+++ b/integrations/auth0/src/tools/manage-organizations.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField } from '../lib/errors';
import { spec } from '../spec';
export let manageOrganizationsTool = SlateTool.create(spec, {
@@ -83,9 +84,8 @@ export let manageOrganizationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.organizationId)
- throw new Error('organizationId is required for get action');
- let org = await client.getOrganization(ctx.input.organizationId);
+ let organizationId = requireField(ctx.input.organizationId, 'organizationId', 'get');
+ let org = await client.getOrganization(organizationId);
return {
output: { organization: mapOrg(org) },
message: `Retrieved organization **${org.display_name || org.name}**.`
@@ -93,7 +93,7 @@ export let manageOrganizationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.name) throw new Error('name is required for create action');
+ let name = requireField(ctx.input.name, 'name', 'create');
let branding =
ctx.input.logoUrl || ctx.input.primaryColor || ctx.input.pageBackgroundColor
? {
@@ -107,7 +107,7 @@ export let manageOrganizationsTool = SlateTool.create(spec, {
}
: undefined;
let org = await client.createOrganization({
- name: ctx.input.name,
+ name,
displayName: ctx.input.displayName,
branding,
metadata: ctx.input.metadata
@@ -119,8 +119,7 @@ export let manageOrganizationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'update') {
- if (!ctx.input.organizationId)
- throw new Error('organizationId is required for update action');
+ let organizationId = requireField(ctx.input.organizationId, 'organizationId', 'update');
let branding =
ctx.input.logoUrl || ctx.input.primaryColor || ctx.input.pageBackgroundColor
? {
@@ -133,7 +132,7 @@ export let manageOrganizationsTool = SlateTool.create(spec, {
}
}
: undefined;
- let org = await client.updateOrganization(ctx.input.organizationId, {
+ let org = await client.updateOrganization(organizationId, {
name: ctx.input.name,
displayName: ctx.input.displayName,
branding,
@@ -146,15 +145,14 @@ export let manageOrganizationsTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.organizationId)
- throw new Error('organizationId is required for delete action');
- await client.deleteOrganization(ctx.input.organizationId);
+ let organizationId = requireField(ctx.input.organizationId, 'organizationId', 'delete');
+ await client.deleteOrganization(organizationId);
return {
output: { deleted: true },
- message: `Deleted organization **${ctx.input.organizationId}**.`
+ message: `Deleted organization **${organizationId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/auth0/src/tools/manage-resource-servers.ts b/integrations/auth0/src/tools/manage-resource-servers.ts
index 31522fb116..321901e528 100644
--- a/integrations/auth0/src/tools/manage-resource-servers.ts
+++ b/integrations/auth0/src/tools/manage-resource-servers.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField } from '../lib/errors';
import { spec } from '../spec';
export let manageResourceServersTool = SlateTool.create(spec, {
@@ -107,9 +108,12 @@ export let manageResourceServersTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.resourceServerId)
- throw new Error('resourceServerId is required for get action');
- let rs = await client.getResourceServer(ctx.input.resourceServerId);
+ let resourceServerId = requireField(
+ ctx.input.resourceServerId,
+ 'resourceServerId',
+ 'get'
+ );
+ let rs = await client.getResourceServer(resourceServerId);
return {
output: { resourceServer: mapRS(rs) },
message: `Retrieved resource server **${rs.name}**.`
@@ -117,11 +121,11 @@ export let manageResourceServersTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.name) throw new Error('name is required for create action');
- if (!ctx.input.identifier) throw new Error('identifier is required for create action');
+ let name = requireField(ctx.input.name, 'name', 'create');
+ let identifier = requireField(ctx.input.identifier, 'identifier', 'create');
let rs = await client.createResourceServer({
- name: ctx.input.name,
- identifier: ctx.input.identifier,
+ name,
+ identifier,
scopes: ctx.input.scopes,
signingAlg: ctx.input.signingAlg,
tokenLifetime: ctx.input.tokenLifetime,
@@ -135,9 +139,12 @@ export let manageResourceServersTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'update') {
- if (!ctx.input.resourceServerId)
- throw new Error('resourceServerId is required for update action');
- let rs = await client.updateResourceServer(ctx.input.resourceServerId, {
+ let resourceServerId = requireField(
+ ctx.input.resourceServerId,
+ 'resourceServerId',
+ 'update'
+ );
+ let rs = await client.updateResourceServer(resourceServerId, {
name: ctx.input.name,
scopes: ctx.input.scopes,
signingAlg: ctx.input.signingAlg,
@@ -152,15 +159,18 @@ export let manageResourceServersTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.resourceServerId)
- throw new Error('resourceServerId is required for delete action');
- await client.deleteResourceServer(ctx.input.resourceServerId);
+ let resourceServerId = requireField(
+ ctx.input.resourceServerId,
+ 'resourceServerId',
+ 'delete'
+ );
+ await client.deleteResourceServer(resourceServerId);
return {
output: { deleted: true },
- message: `Deleted resource server **${ctx.input.resourceServerId}**.`
+ message: `Deleted resource server **${resourceServerId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/auth0/src/tools/manage-role-permissions.ts b/integrations/auth0/src/tools/manage-role-permissions.ts
new file mode 100644
index 0000000000..31544457cf
--- /dev/null
+++ b/integrations/auth0/src/tools/manage-role-permissions.ts
@@ -0,0 +1,99 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Auth0Client } from '../lib/client';
+import { requireNonEmptyArray } from '../lib/errors';
+import { spec } from '../spec';
+import { dispatchAuth0Action } from './shared';
+
+let permissionSchema = z.object({
+ resourceServerIdentifier: z
+ .string()
+ .describe('API identifier/audience that owns the permission'),
+ permissionName: z.string().describe('Permission/scope name')
+});
+
+let mapPermission = (permission: any) => ({
+ resourceServerIdentifier: permission.resource_server_identifier,
+ resourceServerName: permission.resource_server_name,
+ permissionName: permission.permission_name,
+ description: permission.description
+});
+
+export let manageRolePermissionsTool = SlateTool.create(spec, {
+ name: 'Manage Role Permissions',
+ key: 'manage_role_permissions',
+ description:
+ 'List, assign, or remove Auth0 permissions granted to a role. Permissions reference API resource-server identifiers and scope names.',
+ tags: {
+ destructive: false
+ }
+})
+ .input(
+ z.object({
+ roleId: z.string().describe('The Auth0 role ID'),
+ action: z.enum(['list', 'assign', 'remove']).describe('Action to perform'),
+ permissions: z
+ .array(permissionSchema)
+ .optional()
+ .describe('Permissions to assign or remove; required for assign/remove'),
+ page: z.number().optional().describe('Page number for list action'),
+ perPage: z.number().optional().describe('Results per page for list action')
+ })
+ )
+ .output(
+ z.object({
+ permissions: z
+ .array(
+ z.object({
+ resourceServerIdentifier: z.string().optional(),
+ resourceServerName: z.string().optional(),
+ permissionName: z.string(),
+ description: z.string().optional()
+ })
+ )
+ .optional()
+ .describe('Role permissions for list action'),
+ success: z.boolean().describe('Whether the operation succeeded')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Auth0Client({
+ token: ctx.auth.token,
+ domain: ctx.auth.domain
+ });
+
+ return dispatchAuth0Action(ctx.input.action, {
+ list: async () => {
+ let result = await client.getRolePermissions(ctx.input.roleId, {
+ page: ctx.input.page,
+ perPage: ctx.input.perPage
+ });
+ let permissions = (Array.isArray(result) ? result : (result.permissions ?? [])).map(
+ mapPermission
+ );
+ return {
+ output: { permissions, success: true },
+ message: `Role has **${permissions.length}** permission(s).`
+ };
+ },
+
+ assign: async () => {
+ let permissions = requireNonEmptyArray(ctx.input.permissions, 'permissions', 'assign');
+ await client.addRolePermissions(ctx.input.roleId, permissions);
+ return {
+ output: { success: true },
+ message: `Assigned **${permissions.length}** permission(s) to role.`
+ };
+ },
+
+ remove: async () => {
+ let permissions = requireNonEmptyArray(ctx.input.permissions, 'permissions', 'remove');
+ await client.removeRolePermissions(ctx.input.roleId, permissions);
+ return {
+ output: { success: true },
+ message: `Removed **${permissions.length}** permission(s) from role.`
+ };
+ }
+ });
+ })
+ .build();
diff --git a/integrations/auth0/src/tools/manage-roles.ts b/integrations/auth0/src/tools/manage-roles.ts
index e0498931c6..5f75ea7661 100644
--- a/integrations/auth0/src/tools/manage-roles.ts
+++ b/integrations/auth0/src/tools/manage-roles.ts
@@ -1,6 +1,7 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { auth0ServiceError, requireField } from '../lib/errors';
import { spec } from '../spec';
export let manageRolesTool = SlateTool.create(spec, {
@@ -76,8 +77,8 @@ export let manageRolesTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'get') {
- if (!ctx.input.roleId) throw new Error('roleId is required for get action');
- let role = await client.getRole(ctx.input.roleId);
+ let roleId = requireField(ctx.input.roleId, 'roleId', 'get');
+ let role = await client.getRole(roleId);
return {
output: { role: mapRole(role) },
message: `Retrieved role **${role.name}**.`
@@ -85,9 +86,9 @@ export let manageRolesTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'create') {
- if (!ctx.input.name) throw new Error('name is required for create action');
+ let name = requireField(ctx.input.name, 'name', 'create');
let role = await client.createRole({
- name: ctx.input.name,
+ name,
description: ctx.input.description
});
return {
@@ -97,8 +98,8 @@ export let manageRolesTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'update') {
- if (!ctx.input.roleId) throw new Error('roleId is required for update action');
- let role = await client.updateRole(ctx.input.roleId, {
+ let roleId = requireField(ctx.input.roleId, 'roleId', 'update');
+ let role = await client.updateRole(roleId, {
name: ctx.input.name,
description: ctx.input.description
});
@@ -109,14 +110,14 @@ export let manageRolesTool = SlateTool.create(spec, {
}
if (ctx.input.action === 'delete') {
- if (!ctx.input.roleId) throw new Error('roleId is required for delete action');
- await client.deleteRole(ctx.input.roleId);
+ let roleId = requireField(ctx.input.roleId, 'roleId', 'delete');
+ await client.deleteRole(roleId);
return {
output: { deleted: true },
- message: `Deleted role **${ctx.input.roleId}**.`
+ message: `Deleted role **${roleId}**.`
};
}
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ throw auth0ServiceError(`Unknown action: ${ctx.input.action}`);
})
.build();
diff --git a/integrations/auth0/src/tools/manage-user-permissions.ts b/integrations/auth0/src/tools/manage-user-permissions.ts
new file mode 100644
index 0000000000..5529ad2755
--- /dev/null
+++ b/integrations/auth0/src/tools/manage-user-permissions.ts
@@ -0,0 +1,99 @@
+import { SlateTool } from 'slates';
+import { z } from 'zod';
+import { Auth0Client } from '../lib/client';
+import { requireNonEmptyArray } from '../lib/errors';
+import { spec } from '../spec';
+import { dispatchAuth0Action } from './shared';
+
+let permissionSchema = z.object({
+ resourceServerIdentifier: z
+ .string()
+ .describe('API identifier/audience that owns the permission'),
+ permissionName: z.string().describe('Permission/scope name')
+});
+
+let mapPermission = (permission: any) => ({
+ resourceServerIdentifier: permission.resource_server_identifier,
+ resourceServerName: permission.resource_server_name,
+ permissionName: permission.permission_name,
+ description: permission.description
+});
+
+export let manageUserPermissionsTool = SlateTool.create(spec, {
+ name: 'Manage User Permissions',
+ key: 'manage_user_permissions',
+ description:
+ 'List, assign, or remove direct Auth0 permissions for a user. Permissions reference API resource-server identifiers and scope names.',
+ tags: {
+ destructive: false
+ }
+})
+ .input(
+ z.object({
+ userId: z.string().describe('The Auth0 user ID'),
+ action: z.enum(['list', 'assign', 'remove']).describe('Action to perform'),
+ permissions: z
+ .array(permissionSchema)
+ .optional()
+ .describe('Permissions to assign or remove; required for assign/remove'),
+ page: z.number().optional().describe('Page number for list action'),
+ perPage: z.number().optional().describe('Results per page for list action')
+ })
+ )
+ .output(
+ z.object({
+ permissions: z
+ .array(
+ z.object({
+ resourceServerIdentifier: z.string().optional(),
+ resourceServerName: z.string().optional(),
+ permissionName: z.string(),
+ description: z.string().optional()
+ })
+ )
+ .optional()
+ .describe('Current direct permissions for list action'),
+ success: z.boolean().describe('Whether the operation succeeded')
+ })
+ )
+ .handleInvocation(async ctx => {
+ let client = new Auth0Client({
+ token: ctx.auth.token,
+ domain: ctx.auth.domain
+ });
+
+ return dispatchAuth0Action(ctx.input.action, {
+ list: async () => {
+ let result = await client.getUserPermissions(ctx.input.userId, {
+ page: ctx.input.page,
+ perPage: ctx.input.perPage
+ });
+ let permissions = (Array.isArray(result) ? result : (result.permissions ?? [])).map(
+ mapPermission
+ );
+ return {
+ output: { permissions, success: true },
+ message: `User has **${permissions.length}** direct permission(s).`
+ };
+ },
+
+ assign: async () => {
+ let permissions = requireNonEmptyArray(ctx.input.permissions, 'permissions', 'assign');
+ await client.assignUserPermissions(ctx.input.userId, permissions);
+ return {
+ output: { success: true },
+ message: `Assigned **${permissions.length}** direct permission(s) to user.`
+ };
+ },
+
+ remove: async () => {
+ let permissions = requireNonEmptyArray(ctx.input.permissions, 'permissions', 'remove');
+ await client.removeUserPermissions(ctx.input.userId, permissions);
+ return {
+ output: { success: true },
+ message: `Removed **${permissions.length}** direct permission(s) from user.`
+ };
+ }
+ });
+ })
+ .build();
diff --git a/integrations/auth0/src/tools/manage-user-roles.ts b/integrations/auth0/src/tools/manage-user-roles.ts
index c4b900b7fa..570e2f9124 100644
--- a/integrations/auth0/src/tools/manage-user-roles.ts
+++ b/integrations/auth0/src/tools/manage-user-roles.ts
@@ -1,7 +1,9 @@
import { SlateTool } from 'slates';
import { z } from 'zod';
import { Auth0Client } from '../lib/client';
+import { requireNonEmptyArray } from '../lib/errors';
import { spec } from '../spec';
+import { dispatchAuth0Action } from './shared';
export let manageUserRolesTool = SlateTool.create(spec, {
name: 'Manage User Roles',
@@ -42,41 +44,37 @@ export let manageUserRolesTool = SlateTool.create(spec, {
domain: ctx.auth.domain
});
- if (ctx.input.action === 'list') {
- let roles = await client.getUserRoles(ctx.input.userId);
- let mapped = (Array.isArray(roles) ? roles : (roles.roles ?? [])).map((r: any) => ({
- roleId: r.id,
- name: r.name,
- description: r.description
- }));
- return {
- output: { roles: mapped, success: true },
- message: `User has **${mapped.length}** role(s) assigned.`
- };
- }
+ return dispatchAuth0Action(ctx.input.action, {
+ list: async () => {
+ let roles = await client.getUserRoles(ctx.input.userId);
+ let mapped = (Array.isArray(roles) ? roles : (roles.roles ?? [])).map((r: any) => ({
+ roleId: r.id,
+ name: r.name,
+ description: r.description
+ }));
+ return {
+ output: { roles: mapped, success: true },
+ message: `User has **${mapped.length}** role(s) assigned.`
+ };
+ },
- if (ctx.input.action === 'assign') {
- if (!ctx.input.roleIds?.length) {
- throw new Error('roleIds are required for assign action');
- }
- await client.assignUserRoles(ctx.input.userId, ctx.input.roleIds);
- return {
- output: { success: true },
- message: `Assigned **${ctx.input.roleIds.length}** role(s) to user.`
- };
- }
+ assign: async () => {
+ let roleIds = requireNonEmptyArray(ctx.input.roleIds, 'roleIds', 'assign');
+ await client.assignUserRoles(ctx.input.userId, roleIds);
+ return {
+ output: { success: true },
+ message: `Assigned **${roleIds.length}** role(s) to user.`
+ };
+ },
- if (ctx.input.action === 'remove') {
- if (!ctx.input.roleIds?.length) {
- throw new Error('roleIds are required for remove action');
+ remove: async () => {
+ let roleIds = requireNonEmptyArray(ctx.input.roleIds, 'roleIds', 'remove');
+ await client.removeUserRoles(ctx.input.userId, roleIds);
+ return {
+ output: { success: true },
+ message: `Removed **${roleIds.length}** role(s) from user.`
+ };
}
- await client.removeUserRoles(ctx.input.userId, ctx.input.roleIds);
- return {
- output: { success: true },
- message: `Removed **${ctx.input.roleIds.length}** role(s) from user.`
- };
- }
-
- throw new Error(`Unknown action: ${ctx.input.action}`);
+ });
})
.build();
diff --git a/integrations/auth0/src/tools/shared.ts b/integrations/auth0/src/tools/shared.ts
new file mode 100644
index 0000000000..81ecf88935
--- /dev/null
+++ b/integrations/auth0/src/tools/shared.ts
@@ -0,0 +1,15 @@
+import { createApiServiceError } from 'slates';
+
+type ActionHandler = () => T | Promise;
+
+export let dispatchAuth0Action = async (
+ action: string,
+ handlers: Record>
+) => {
+ let handler = handlers[action];
+ if (!handler) {
+ throw createApiServiceError(`Unknown action: ${action}`);
+ }
+
+ return handler();
+};
diff --git a/integrations/auth0/vitest.config.ts b/integrations/auth0/vitest.config.ts
new file mode 100644
index 0000000000..77375364da
--- /dev/null
+++ b/integrations/auth0/vitest.config.ts
@@ -0,0 +1,7 @@
+import { createSlatesVitestConfig } from '@slates/test/config';
+
+export default createSlatesVitestConfig({
+ test: {
+ include: ['src/**/*.test.ts']
+ }
+});
diff --git a/integrations/aws-cognito/README.md b/integrations/aws-cognito/README.md
index 6c65cf23e0..e2d5ff035e 100644
--- a/integrations/aws-cognito/README.md
+++ b/integrations/aws-cognito/README.md
@@ -32,14 +32,26 @@ Create, get, update, or delete a group in a Cognito user pool. Groups provide ro
Create, get, update, delete, or list Cognito identity pools (federated identities). Identity pools issue temporary AWS credentials to authenticated and guest users, enabling direct access to AWS services.
+### Manage Identity Pool Roles
+
+Get or set IAM roles for a Cognito identity pool. Identity pool roles control the AWS credentials issued to authenticated and unauthenticated identities.
+
### Manage Identity Provider
Create, get, update, delete, or list federated identity providers (SAML, OIDC, Google, Facebook, Apple, Amazon) in a Cognito user pool. Manages federation configuration for external sign-in sources.
+### Manage Resource Server
+
+Create, get, update, delete, or list Cognito resource servers for a user pool. Resource servers define custom OAuth scopes for external APIs and machine-to-machine authorization.
+
### Manage User Pool
Create, update, get, or delete a Cognito user pool. When creating, only the pool name is required. When updating, provide the user pool ID and the fields to change. Supports configuring password policies, MFA, auto-verification, and deletion protection.
+### Manage User Pool Domain
+
+Create, get, update, or delete a Cognito user pool domain. User pool domains host managed login, OAuth authorization endpoints, and authentication pages for applications.
+
### Manage User
Create, get, update, disable, enable, confirm, reset password, set password, or delete a user in a Cognito user pool. Combines all administrative user operations into a single flexible tool.
diff --git a/integrations/aws-cognito/package.json b/integrations/aws-cognito/package.json
index 970763ffc1..2af75fc80f 100644
--- a/integrations/aws-cognito/package.json
+++ b/integrations/aws-cognito/package.json
@@ -4,15 +4,19 @@
"type": "module",
"scripts": {
"build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
+ "test": "vitest run --config vitest.config.ts --passWithNoTests",
"typecheck": "tsc --noEmit"
},
"dependencies": {
+ "@lowerdeck/error": "^1.1.0",
"@types/node": "^20",
- "slates": "1.0.0-rc.14",
+ "slates": "1.0.0-rc.15",
"zod": "^4.2"
},
"devDependencies": {
- "typescript": "^5"
+ "@slates/test": "1.0.0-rc.9",
+ "typescript": "^5",
+ "vitest": "^3.1.2"
},
- "version": "0.2.0-rc.5"
+ "version": "0.2.0-rc.6"
}
diff --git a/integrations/aws-cognito/src/index.ts b/integrations/aws-cognito/src/index.ts
index f89f20913d..532b29418c 100644
--- a/integrations/aws-cognito/src/index.ts
+++ b/integrations/aws-cognito/src/index.ts
@@ -8,9 +8,12 @@ import {
manageGroup,
manageGroupMembership,
manageIdentityPool,
+ manageIdentityPoolRoles,
manageIdentityProvider,
+ manageResourceServer,
manageUser,
- manageUserPool
+ manageUserPool,
+ manageUserPoolDomain
} from './tools';
import { groupChanges, inboundWebhook, userChanges } from './triggers';
@@ -26,7 +29,10 @@ export let provider = Slate.create({
manageGroupMembership,
manageIdentityProvider,
manageAppClient,
- manageIdentityPool
+ manageIdentityPool,
+ manageIdentityPoolRoles,
+ manageResourceServer,
+ manageUserPoolDomain
],
triggers: [inboundWebhook, userChanges, groupChanges]
});
diff --git a/integrations/aws-cognito/src/lib/client.ts b/integrations/aws-cognito/src/lib/client.ts
index d9b537de52..7696f9ce57 100644
--- a/integrations/aws-cognito/src/lib/client.ts
+++ b/integrations/aws-cognito/src/lib/client.ts
@@ -1,4 +1,5 @@
import { createAxios } from 'slates';
+import { cognitoApiError } from './errors';
import { signRequest } from './signing';
export interface CognitoClientConfig {
@@ -45,8 +46,12 @@ export class CognitoClient {
baseURL: `https://${host}`
});
- let response = await ax.post('/', bodyStr, { headers });
- return response.data;
+ try {
+ let response = await ax.post('/', bodyStr, { headers });
+ return response.data;
+ } catch (error) {
+ throw cognitoApiError(error, action);
+ }
}
// ---- User Pool Operations ----
@@ -326,4 +331,25 @@ export class CognitoClient {
Identifier: identifier
});
}
+
+ // ---- User Pool Domain Operations ----
+
+ async createUserPoolDomain(params: Record): Promise {
+ return this.request('CreateUserPoolDomain', params);
+ }
+
+ async describeUserPoolDomain(domain: string): Promise {
+ return this.request('DescribeUserPoolDomain', { Domain: domain });
+ }
+
+ async updateUserPoolDomain(params: Record): Promise {
+ return this.request('UpdateUserPoolDomain', params);
+ }
+
+ async deleteUserPoolDomain(userPoolId: string, domain: string): Promise {
+ return this.request('DeleteUserPoolDomain', {
+ UserPoolId: userPoolId,
+ Domain: domain
+ });
+ }
}
diff --git a/integrations/aws-cognito/src/lib/errors.ts b/integrations/aws-cognito/src/lib/errors.ts
new file mode 100644
index 0000000000..63b94dc63c
--- /dev/null
+++ b/integrations/aws-cognito/src/lib/errors.ts
@@ -0,0 +1,104 @@
+import { badRequestError, ServiceError } from '@lowerdeck/error';
+
+type ErrorResponse = {
+ status?: number;
+ statusText?: string;
+ data?: unknown;
+};
+
+let isRecord = (value: unknown): value is Record =>
+ typeof value === 'object' && value !== null;
+
+let pushString = (messages: string[], value: unknown) => {
+ if (typeof value === 'string' && value.trim() && !messages.includes(value.trim())) {
+ messages.push(value.trim());
+ }
+};
+
+let extractCognitoMessage = (error: unknown) => {
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let data = response?.data;
+ let messages: string[] = [];
+
+ if (isRecord(data)) {
+ for (let key of ['message', 'Message', 'error', 'Error', 'code', 'Code', '__type']) {
+ pushString(messages, data[key]);
+ }
+ } else {
+ pushString(messages, data);
+ }
+
+ if (isRecord(error)) {
+ for (let key of ['message', 'Message', 'name', 'Code', 'code', '__type']) {
+ pushString(messages, error[key]);
+ }
+ }
+
+ if (error instanceof Error) {
+ pushString(messages, error.message);
+ }
+
+ return messages.length > 0 ? [...new Set(messages)].join(' - ') : 'Unknown error';
+};
+
+let extractCognitoStatus = (error: unknown) => {
+ if (!isRecord(error)) return undefined;
+
+ let response = error.response as ErrorResponse | undefined;
+ let metadata = isRecord(error.$metadata) ? error.$metadata : undefined;
+ let status =
+ response?.status ?? metadata?.httpStatusCode ?? error.statusCode ?? error.status;
+
+ return typeof status === 'number' || typeof status === 'string' ? status : undefined;
+};
+
+let extractCognitoCode = (error: unknown) => {
+ if (!isRecord(error)) return undefined;
+
+ if (typeof error.Code === 'string') return error.Code;
+ if (typeof error.code === 'string' && !error.code.startsWith('upstream.')) {
+ return error.code;
+ }
+ if (typeof error.name === 'string' && error.name !== 'Error') return error.name;
+
+ let response = error.response as ErrorResponse | undefined;
+ let data = response?.data;
+ if (isRecord(data)) {
+ if (typeof data.Code === 'string') return data.Code;
+ if (typeof data.code === 'string') return data.code;
+ if (typeof data.__type === 'string') return data.__type.split('#').at(-1);
+ }
+
+ return undefined;
+};
+
+export let cognitoServiceError = (message: string) =>
+ new ServiceError(badRequestError({ message }));
+
+export let cognitoApiError = (error: unknown, operation = 'request') => {
+ if (error instanceof ServiceError) {
+ return error;
+ }
+
+ let response = isRecord(error) ? (error.response as ErrorResponse | undefined) : undefined;
+ let status = extractCognitoStatus(error);
+ let code = extractCognitoCode(error);
+ let statusLabel =
+ status !== undefined
+ ? `HTTP ${status}${response?.statusText ? ` ${response.statusText}` : ''}: `
+ : '';
+ let codeLabel = code ? `${code} - ` : '';
+ let serviceError = cognitoServiceError(
+ `Amazon Cognito API ${operation} failed: ${statusLabel}${codeLabel}${extractCognitoMessage(error)}`
+ );
+
+ serviceError.data.reason = 'aws_cognito_api_error';
+ serviceError.data.upstreamStatus = status;
+ serviceError.data.upstreamCode = code;
+
+ if (error instanceof Error) {
+ serviceError.setParent(error);
+ }
+
+ return serviceError;
+};
diff --git a/integrations/aws-cognito/src/lib/identity-client.ts b/integrations/aws-cognito/src/lib/identity-client.ts
index 12457314ca..8fc9a4f2ad 100644
--- a/integrations/aws-cognito/src/lib/identity-client.ts
+++ b/integrations/aws-cognito/src/lib/identity-client.ts
@@ -1,4 +1,5 @@
import { createAxios } from 'slates';
+import { cognitoApiError } from './errors';
import { signRequest } from './signing';
export interface IdentityClientConfig {
@@ -45,8 +46,12 @@ export class CognitoIdentityClient {
baseURL: `https://${host}`
});
- let response = await ax.post('/', bodyStr, { headers });
- return response.data;
+ try {
+ let response = await ax.post('/', bodyStr, { headers });
+ return response.data;
+ } catch (error) {
+ throw cognitoApiError(error, action);
+ }
}
async listIdentityPools(maxResults: number = 60, nextToken?: string): Promise