@almadar/integrations 2.36.0 → 2.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,8 +55,8 @@ var serviceCredentials = {
55
55
  { envVar: "TWILIO_PHONE_NUMBER", required: false, description: "Default sender phone number" }
56
56
  ],
57
57
  email: [
58
- { envVar: "SENDGRID_API_KEY", required: false, description: "SendGrid API key (use this OR RESEND_API_KEY)" },
59
- { envVar: "RESEND_API_KEY", required: false, description: "Resend API key (use this OR SENDGRID_API_KEY)" },
58
+ { envVar: "SENDGRID_API_KEY", required: false, oneOf: "provider", description: "SendGrid API key (use this OR RESEND_API_KEY)" },
59
+ { envVar: "RESEND_API_KEY", required: false, oneOf: "provider", description: "Resend API key (use this OR SENDGRID_API_KEY)" },
60
60
  { envVar: "FROM_EMAIL", required: false, description: "Default sender email address" }
61
61
  ],
62
62
  webhook: [
@@ -75,9 +75,9 @@ var serviceCredentials = {
75
75
  { envVar: "GOOGLE_CALENDAR_CHANNEL_TOKEN", required: false, description: "Watch-channel verification token \u2014 required to receive inbound calendar hooks (two-way sync)" }
76
76
  ],
77
77
  drive: [
78
- { envVar: "GOOGLE_DRIVE_SA_KEY", required: false, description: "Google service-account key JSON (raw or base64) with drive scope \u2014 serves reads; store in Secret Manager, bind as env" },
78
+ { envVar: "GOOGLE_DRIVE_SA_KEY", required: false, oneOf: "auth", description: "Google service-account key JSON (raw or base64) with drive scope \u2014 serves reads; store in Secret Manager, bind as env" },
79
79
  { envVar: "GOOGLE_DRIVE_SUBJECT", required: false, description: "Workspace user to impersonate (domain-wide delegation); empty = act as the service account" },
80
- { envVar: "GOOGLE_DRIVE_REFRESH_TOKEN", required: false, description: "User OAuth refresh token (drive-consent.mjs) \u2014 serves writes; SA uploads are impossible on personal accounts (no SA storage quota)" },
80
+ { envVar: "GOOGLE_DRIVE_REFRESH_TOKEN", required: false, oneOf: "auth", description: "User OAuth refresh token (drive-consent.mjs) \u2014 serves writes; SA uploads are impossible on personal accounts (no SA storage quota)" },
81
81
  { envVar: "GOOGLE_DRIVE_FOLDER_ID", required: false, description: "Default parent folder for uploads/new folders when the call names none" }
82
82
  ],
83
83
  metaAds: [
@@ -94,12 +94,13 @@ var serviceCredentials = {
94
94
  { envVar: "DOCUSIGN_ACCESS_TOKEN", required: true, description: "DocuSign OAuth access token (JWT grant rotation is the deployment concern)" }
95
95
  ],
96
96
  llm: [
97
- { envVar: "ANTHROPIC_API_KEY", required: false, description: "Anthropic API key (use this OR OPENAI_API_KEY)" },
98
- { envVar: "OPENAI_API_KEY", required: false, description: "OpenAI API key (use this OR ANTHROPIC_API_KEY)" }
97
+ { envVar: "ANTHROPIC_API_KEY", required: false, oneOf: "provider", description: "Anthropic API key (use this OR OPENAI_API_KEY)" },
98
+ { envVar: "OPENAI_API_KEY", required: false, oneOf: "provider", description: "OpenAI API key (use this OR ANTHROPIC_API_KEY)" },
99
+ { envVar: "LLM_PROVIDER", required: false, description: "Chat provider when several keys are set: anthropic | openai | deepseek | kimi | openrouter (default: the first key found)" }
99
100
  ],
100
101
  "llm-integration": [
101
- { envVar: "ANTHROPIC_API_KEY", required: false, description: "Anthropic API key" },
102
- { envVar: "OPENAI_API_KEY", required: false, description: "OpenAI API key" }
102
+ { envVar: "ANTHROPIC_API_KEY", required: false, oneOf: "provider", description: "Anthropic API key" },
103
+ { envVar: "OPENAI_API_KEY", required: false, oneOf: "provider", description: "OpenAI API key" }
103
104
  ],
104
105
  ml: [
105
106
  { envVar: "MASAR_URL", required: true, description: "Base URL of the deployed model-serving orbital" },
@@ -246,13 +247,14 @@ function validateParams(integration, action, params) {
246
247
  }
247
248
  }
248
249
  for (const paramDef of actionDef.params) {
249
- if (paramDef.required && !(paramDef.name in params)) {
250
+ const provided = params[paramDef.name] !== void 0;
251
+ if (paramDef.required && !provided) {
250
252
  errors.push({
251
253
  param: paramDef.name,
252
254
  message: `Missing required parameter: ${paramDef.name}`
253
255
  });
254
256
  }
255
- if (paramDef.name in params) {
257
+ if (provided) {
256
258
  const value = params[paramDef.name];
257
259
  const expectedType = paramDef.type;
258
260
  const actualType = typeof value;
@@ -333,6 +335,14 @@ var BaseIntegration = class {
333
335
  validateParams(action, params) {
334
336
  return validateParams(this.config.name, action, params);
335
337
  }
338
+ /** A rejected call: a real IntegrationError naming every failing param (kept in `details`). */
339
+ validationFailure(action, errors) {
340
+ const reasons = errors.map((e) => `${e.param}: ${e.message}`).join("; ");
341
+ const error = new IntegrationError(`Validation failed for ${this.config.name}.${action}: ${reasons}`, "VALIDATION_ERROR", errors);
342
+ error.integration = this.config.name;
343
+ error.action = action;
344
+ return { success: false, error, metadata: this.createMetadata(action, 0) };
345
+ }
336
346
  /**
337
347
  * Handle errors uniformly
338
348
  */
@@ -387,6 +397,9 @@ function registerIntegration(name, constructor) {
387
397
  function getIntegration(name) {
388
398
  return INTEGRATION_REGISTRY[name];
389
399
  }
400
+ function getRegisteredIntegrations() {
401
+ return Object.keys(INTEGRATION_REGISTRY);
402
+ }
390
403
 
391
404
  // src/factory.ts
392
405
  function instanceKey(name, principal) {
@@ -417,13 +430,13 @@ var IntegrationFactory = class {
417
430
  }
418
431
  const Constructor = getIntegration(name);
419
432
  if (!Constructor) {
420
- throw new Error(`Unknown integration: ${name}. Make sure it's imported.`);
433
+ throw new IntegrationError(`Unknown integration: ${name}. Make sure it's imported.`, "UNKNOWN_INTEGRATION");
421
434
  }
422
435
  const config = this.configs.get(key) ?? this.configs.get(name);
423
436
  if (!config) {
424
- throw new Error(
425
- `Integration not configured: ${name}. Call configure() first.`
426
- );
437
+ const envVars = (serviceCredentials[name] ?? []).map((c) => c.envVar);
438
+ const needs = envVars.length > 0 ? ` Set ${envVars.join(" / ")}.` : "";
439
+ throw new IntegrationError(`Integration not configured: ${name}.${needs}`, "NOT_CONFIGURED");
427
440
  }
428
441
  const instance = new Constructor(config);
429
442
  this.instances.set(key, instance);
@@ -572,18 +585,7 @@ var StripeIntegration = class extends BaseIntegration {
572
585
  }
573
586
  async execute(action, params) {
574
587
  const validation = this.validateParams(action, params);
575
- if (!validation.valid) {
576
- return {
577
- success: false,
578
- error: {
579
- name: "IntegrationError",
580
- message: "Validation failed",
581
- code: "VALIDATION_ERROR",
582
- details: validation.errors
583
- },
584
- metadata: this.createMetadata(action, 0)
585
- };
586
- }
588
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
587
589
  const startTime = Date.now();
588
590
  const retries = 0;
589
591
  try {
@@ -801,18 +803,7 @@ var YouTubeIntegration = class extends BaseIntegration {
801
803
  }
802
804
  async execute(action, params) {
803
805
  const validation = this.validateParams(action, params);
804
- if (!validation.valid) {
805
- return {
806
- success: false,
807
- error: {
808
- name: "IntegrationError",
809
- message: "Validation failed",
810
- code: "VALIDATION_ERROR",
811
- details: validation.errors
812
- },
813
- metadata: this.createMetadata(action, 0)
814
- };
815
- }
806
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
816
807
  const startTime = Date.now();
817
808
  let retries = 0;
818
809
  try {
@@ -906,18 +897,7 @@ var TwilioIntegration = class extends BaseIntegration {
906
897
  }
907
898
  async execute(action, params) {
908
899
  const validation = this.validateParams(action, params);
909
- if (!validation.valid) {
910
- return {
911
- success: false,
912
- error: {
913
- name: "IntegrationError",
914
- message: "Validation failed",
915
- code: "VALIDATION_ERROR",
916
- details: validation.errors
917
- },
918
- metadata: this.createMetadata(action, 0)
919
- };
920
- }
900
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
921
901
  const startTime = Date.now();
922
902
  let retries = 0;
923
903
  try {
@@ -991,18 +971,7 @@ var EmailIntegration = class extends BaseIntegration {
991
971
  }
992
972
  async execute(action, params) {
993
973
  const validation = this.validateParams(action, params);
994
- if (!validation.valid) {
995
- return {
996
- success: false,
997
- error: {
998
- name: "IntegrationError",
999
- message: "Validation failed",
1000
- code: "VALIDATION_ERROR",
1001
- details: validation.errors
1002
- },
1003
- metadata: this.createMetadata(action, 0)
1004
- };
1005
- }
974
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1006
975
  const startTime = Date.now();
1007
976
  let retries = 0;
1008
977
  try {
@@ -1075,8 +1044,11 @@ var EmailIntegration = class extends BaseIntegration {
1075
1044
  ...message.htmlBody ? { text: message.body } : {},
1076
1045
  ...message.replyTo ? { replyTo: message.replyTo } : {}
1077
1046
  });
1047
+ if (response.error || !response.data) {
1048
+ throw new Error(`Resend rejected the email: ${response.error?.message ?? "no message id returned"}`);
1049
+ }
1078
1050
  return {
1079
- id: response.data?.id,
1051
+ id: response.data.id,
1080
1052
  status: "sent"
1081
1053
  };
1082
1054
  }
@@ -1091,18 +1063,7 @@ var WebhookIntegration = class extends BaseIntegration {
1091
1063
  }
1092
1064
  async execute(action, params) {
1093
1065
  const validation = this.validateParams(action, params);
1094
- if (!validation.valid) {
1095
- return {
1096
- success: false,
1097
- error: {
1098
- name: "IntegrationError",
1099
- message: "Validation failed",
1100
- code: "VALIDATION_ERROR",
1101
- details: validation.errors
1102
- },
1103
- metadata: this.createMetadata(action, 0)
1104
- };
1105
- }
1066
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1106
1067
  const startTime = Date.now();
1107
1068
  let retries = 0;
1108
1069
  try {
@@ -1182,18 +1143,7 @@ var PushIntegration = class extends BaseIntegration {
1182
1143
  }
1183
1144
  async execute(action, params) {
1184
1145
  const validation = this.validateParams(action, params);
1185
- if (!validation.valid) {
1186
- return {
1187
- success: false,
1188
- error: {
1189
- name: "IntegrationError",
1190
- message: "Validation failed",
1191
- code: "VALIDATION_ERROR",
1192
- details: validation.errors
1193
- },
1194
- metadata: this.createMetadata(action, 0)
1195
- };
1196
- }
1146
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1197
1147
  const startTime = Date.now();
1198
1148
  let retries = 0;
1199
1149
  try {
@@ -1273,18 +1223,7 @@ var CalendarIntegration = class extends BaseIntegration {
1273
1223
  }
1274
1224
  async execute(action, params) {
1275
1225
  const validation = this.validateParams(action, params);
1276
- if (!validation.valid) {
1277
- return {
1278
- success: false,
1279
- error: {
1280
- name: "IntegrationError",
1281
- message: "Validation failed",
1282
- code: "VALIDATION_ERROR",
1283
- details: validation.errors
1284
- },
1285
- metadata: this.createMetadata(action, 0)
1286
- };
1287
- }
1226
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1288
1227
  const startTime = Date.now();
1289
1228
  let retries = 0;
1290
1229
  try {
@@ -1525,18 +1464,7 @@ var DriveIntegration = class extends BaseIntegration {
1525
1464
  }
1526
1465
  async execute(action, params) {
1527
1466
  const validation = this.validateParams(action, params);
1528
- if (!validation.valid) {
1529
- return {
1530
- success: false,
1531
- error: {
1532
- name: "IntegrationError",
1533
- message: "Validation failed",
1534
- code: "VALIDATION_ERROR",
1535
- details: validation.errors
1536
- },
1537
- metadata: this.createMetadata(action, 0)
1538
- };
1539
- }
1467
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1540
1468
  const startTime = Date.now();
1541
1469
  try {
1542
1470
  let data;
@@ -1672,18 +1600,7 @@ var MetaAdsIntegration = class extends BaseIntegration {
1672
1600
  }
1673
1601
  async execute(action, params) {
1674
1602
  const validation = this.validateParams(action, params);
1675
- if (!validation.valid) {
1676
- return {
1677
- success: false,
1678
- error: {
1679
- name: "IntegrationError",
1680
- message: "Validation failed",
1681
- code: "VALIDATION_ERROR",
1682
- details: validation.errors
1683
- },
1684
- metadata: this.createMetadata(action, 0)
1685
- };
1686
- }
1603
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1687
1604
  const startTime = Date.now();
1688
1605
  try {
1689
1606
  let data;
@@ -1771,18 +1688,7 @@ var AccountingIntegration = class extends BaseIntegration {
1771
1688
  }
1772
1689
  async execute(action, params) {
1773
1690
  const validation = this.validateParams(action, params);
1774
- if (!validation.valid) {
1775
- return {
1776
- success: false,
1777
- error: {
1778
- name: "IntegrationError",
1779
- message: "Validation failed",
1780
- code: "VALIDATION_ERROR",
1781
- details: validation.errors
1782
- },
1783
- metadata: this.createMetadata(action, 0)
1784
- };
1785
- }
1691
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1786
1692
  const startTime = Date.now();
1787
1693
  try {
1788
1694
  let data;
@@ -1850,18 +1756,7 @@ var BankingIntegration = class extends BaseIntegration {
1850
1756
  }
1851
1757
  async execute(action, params) {
1852
1758
  const validation = this.validateParams(action, params);
1853
- if (!validation.valid) {
1854
- return {
1855
- success: false,
1856
- error: {
1857
- name: "IntegrationError",
1858
- message: "Validation failed",
1859
- code: "VALIDATION_ERROR",
1860
- details: validation.errors
1861
- },
1862
- metadata: this.createMetadata(action, 0)
1863
- };
1864
- }
1759
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1865
1760
  const startTime = Date.now();
1866
1761
  try {
1867
1762
  let data;
@@ -1974,18 +1869,7 @@ var EsignIntegration = class extends BaseIntegration {
1974
1869
  }
1975
1870
  async execute(action, params) {
1976
1871
  const validation = this.validateParams(action, params);
1977
- if (!validation.valid) {
1978
- return {
1979
- success: false,
1980
- error: {
1981
- name: "IntegrationError",
1982
- message: "Validation failed",
1983
- code: "VALIDATION_ERROR",
1984
- details: validation.errors
1985
- },
1986
- metadata: this.createMetadata(action, 0)
1987
- };
1988
- }
1872
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
1989
1873
  const startTime = Date.now();
1990
1874
  try {
1991
1875
  let data;
@@ -2122,18 +2006,7 @@ var LLMIntegration = class extends BaseIntegration {
2122
2006
  }
2123
2007
  async execute(action, params) {
2124
2008
  const validation = this.validateParams(action, params);
2125
- if (!validation.valid) {
2126
- return {
2127
- success: false,
2128
- error: {
2129
- name: "IntegrationError",
2130
- message: "Validation failed",
2131
- code: "VALIDATION_ERROR",
2132
- details: validation.errors
2133
- },
2134
- metadata: this.createMetadata(action, 0)
2135
- };
2136
- }
2009
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
2137
2010
  const startTime = Date.now();
2138
2011
  try {
2139
2012
  let data;
@@ -2174,16 +2047,14 @@ var LLMIntegration = class extends BaseIntegration {
2174
2047
  maxTokens
2175
2048
  } = params;
2176
2049
  this.logger.debug("Generating content", { model, temperature });
2177
- const client = model ? new LLMClient({ provider: this.provider, model, temperature: temperature ?? 0.7 }) : this.getClient();
2178
- const response = await client.callWithMetadata({
2050
+ const client = model !== void 0 || temperature !== void 0 ? new LLMClient({ provider: this.provider, model, temperature: temperature ?? 0.7 }) : this.getClient();
2051
+ const response = await client.callRawWithMetadata({
2179
2052
  systemPrompt: systemPrompt || "You are a helpful assistant.",
2180
2053
  userPrompt,
2181
- maxTokens: maxTokens ?? 1024,
2182
- temperature,
2183
- skipSchemaValidation: true
2054
+ maxTokens: maxTokens ?? 1024
2184
2055
  });
2185
2056
  return {
2186
- content: response.data,
2057
+ content: response.raw,
2187
2058
  usage: response.usage ? {
2188
2059
  promptTokens: response.usage.promptTokens,
2189
2060
  completionTokens: response.usage.completionTokens,
@@ -2300,18 +2171,7 @@ var MLIntegration = class extends BaseIntegration {
2300
2171
  }
2301
2172
  async execute(action, params) {
2302
2173
  const validation = this.validateParams(action, params);
2303
- if (!validation.valid) {
2304
- return {
2305
- success: false,
2306
- error: {
2307
- name: "IntegrationError",
2308
- message: "Validation failed",
2309
- code: "VALIDATION_ERROR",
2310
- details: validation.errors
2311
- },
2312
- metadata: this.createMetadata(action, 0)
2313
- };
2314
- }
2174
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
2315
2175
  const startTime = Date.now();
2316
2176
  try {
2317
2177
  let data;
@@ -2420,18 +2280,7 @@ var DeepAgentIntegration = class extends BaseIntegration {
2420
2280
  }
2421
2281
  async execute(action, params) {
2422
2282
  const validation = this.validateParams(action, params);
2423
- if (!validation.valid) {
2424
- return {
2425
- success: false,
2426
- error: {
2427
- name: "IntegrationError",
2428
- message: "Validation failed",
2429
- code: "VALIDATION_ERROR",
2430
- details: validation.errors
2431
- },
2432
- metadata: this.createMetadata(action, 0)
2433
- };
2434
- }
2283
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
2435
2284
  const startTime = Date.now();
2436
2285
  let retries = 0;
2437
2286
  try {
@@ -2865,18 +2714,7 @@ var GitHubIntegration = class extends BaseIntegration {
2865
2714
  */
2866
2715
  async execute(action, params) {
2867
2716
  const validation = this.validateParams(action, params);
2868
- if (!validation.valid) {
2869
- return {
2870
- success: false,
2871
- error: {
2872
- name: "IntegrationError",
2873
- message: "Validation failed",
2874
- code: "VALIDATION_ERROR",
2875
- details: validation.errors
2876
- },
2877
- metadata: this.createMetadata(action, 0)
2878
- };
2879
- }
2717
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
2880
2718
  const startTime = Date.now();
2881
2719
  let retries = 0;
2882
2720
  try {
@@ -3167,18 +3005,7 @@ var RedisIntegration = class extends BaseIntegration {
3167
3005
  }
3168
3006
  async execute(action, params) {
3169
3007
  const validation = this.validateParams(action, params);
3170
- if (!validation.valid) {
3171
- return {
3172
- success: false,
3173
- error: {
3174
- name: "IntegrationError",
3175
- message: "Validation failed",
3176
- code: "VALIDATION_ERROR",
3177
- details: validation.errors
3178
- },
3179
- metadata: this.createMetadata(action, 0)
3180
- };
3181
- }
3008
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
3182
3009
  const startTime = Date.now();
3183
3010
  try {
3184
3011
  let data;
@@ -3381,18 +3208,7 @@ var QueueIntegration = class extends BaseIntegration {
3381
3208
  }
3382
3209
  async execute(action, params) {
3383
3210
  const validation = this.validateParams(action, params);
3384
- if (!validation.valid) {
3385
- return {
3386
- success: false,
3387
- error: {
3388
- name: "IntegrationError",
3389
- message: "Validation failed",
3390
- code: "VALIDATION_ERROR",
3391
- details: validation.errors
3392
- },
3393
- metadata: this.createMetadata(action, 0)
3394
- };
3395
- }
3211
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
3396
3212
  const startTime = Date.now();
3397
3213
  try {
3398
3214
  let data;
@@ -3591,18 +3407,7 @@ var OtelIntegration = class extends BaseIntegration {
3591
3407
  }
3592
3408
  async execute(action, params) {
3593
3409
  const validation = this.validateParams(action, params);
3594
- if (!validation.valid) {
3595
- return {
3596
- success: false,
3597
- error: {
3598
- name: "IntegrationError",
3599
- message: "Validation failed",
3600
- code: "VALIDATION_ERROR",
3601
- details: validation.errors
3602
- },
3603
- metadata: this.createMetadata(action, 0)
3604
- };
3605
- }
3410
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
3606
3411
  const startTime = Date.now();
3607
3412
  try {
3608
3413
  let data;
@@ -3790,18 +3595,7 @@ var OAuthIntegration = class extends BaseIntegration {
3790
3595
  }
3791
3596
  async execute(action, params) {
3792
3597
  const validation = this.validateParams(action, params);
3793
- if (!validation.valid) {
3794
- return {
3795
- success: false,
3796
- error: {
3797
- name: "IntegrationError",
3798
- message: "Validation failed",
3799
- code: "VALIDATION_ERROR",
3800
- details: validation.errors
3801
- },
3802
- metadata: this.createMetadata(action, 0)
3803
- };
3804
- }
3598
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
3805
3599
  const startTime = Date.now();
3806
3600
  try {
3807
3601
  let data;
@@ -4103,18 +3897,7 @@ var CredentialsIntegration = class extends BaseIntegration {
4103
3897
  }
4104
3898
  }
4105
3899
  const validation = this.validateParams(action, params);
4106
- if (!validation.valid) {
4107
- return {
4108
- success: false,
4109
- error: {
4110
- name: "IntegrationError",
4111
- message: "Validation failed",
4112
- code: "VALIDATION_ERROR",
4113
- details: validation.errors
4114
- },
4115
- metadata: this.createMetadata(action, 0)
4116
- };
4117
- }
3900
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
4118
3901
  const startTime = Date.now();
4119
3902
  try {
4120
3903
  let data;
@@ -4315,18 +4098,7 @@ var StorageIntegration = class extends BaseIntegration {
4315
4098
  }
4316
4099
  async execute(action, params) {
4317
4100
  const validation = this.validateParams(action, params);
4318
- if (!validation.valid) {
4319
- return {
4320
- success: false,
4321
- error: {
4322
- name: "IntegrationError",
4323
- message: "Validation failed",
4324
- code: "VALIDATION_ERROR",
4325
- details: validation.errors
4326
- },
4327
- metadata: this.createMetadata(action, 0)
4328
- };
4329
- }
4101
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
4330
4102
  const startTime = Date.now();
4331
4103
  try {
4332
4104
  let data;
@@ -4605,18 +4377,7 @@ var DockerIntegration = class extends BaseIntegration {
4605
4377
  }
4606
4378
  async execute(action, params) {
4607
4379
  const validation = this.validateParams(action, params);
4608
- if (!validation.valid) {
4609
- return {
4610
- success: false,
4611
- error: {
4612
- name: "IntegrationError",
4613
- message: "Validation failed",
4614
- code: "VALIDATION_ERROR",
4615
- details: validation.errors
4616
- },
4617
- metadata: this.createMetadata(action, 0)
4618
- };
4619
- }
4380
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
4620
4381
  const startTime = Date.now();
4621
4382
  try {
4622
4383
  let data;
@@ -5041,18 +4802,7 @@ var DatabaseIntegration = class extends BaseIntegration {
5041
4802
  }
5042
4803
  async execute(action, params) {
5043
4804
  const validation = this.validateParams(action, params);
5044
- if (!validation.valid) {
5045
- return {
5046
- success: false,
5047
- error: {
5048
- name: "IntegrationError",
5049
- message: "Validation failed",
5050
- code: "VALIDATION_ERROR",
5051
- details: validation.errors
5052
- },
5053
- metadata: this.createMetadata(action, 0)
5054
- };
5055
- }
4805
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
5056
4806
  const startTime = Date.now();
5057
4807
  try {
5058
4808
  let data;
@@ -5120,18 +4870,7 @@ var WikimediaIntegration = class extends BaseIntegration {
5120
4870
  }
5121
4871
  async execute(action, params) {
5122
4872
  const validation = this.validateParams(action, params);
5123
- if (!validation.valid) {
5124
- return {
5125
- success: false,
5126
- error: {
5127
- name: "IntegrationError",
5128
- message: "Validation failed",
5129
- code: "VALIDATION_ERROR",
5130
- details: validation.errors
5131
- },
5132
- metadata: this.createMetadata(action, 0)
5133
- };
5134
- }
4873
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
5135
4874
  const startTime = Date.now();
5136
4875
  try {
5137
4876
  let data;
@@ -5189,18 +4928,7 @@ var IconifyIntegration = class extends BaseIntegration {
5189
4928
  }
5190
4929
  async execute(action, params) {
5191
4930
  const validation = this.validateParams(action, params);
5192
- if (!validation.valid) {
5193
- return {
5194
- success: false,
5195
- error: {
5196
- name: "IntegrationError",
5197
- message: "Validation failed",
5198
- code: "VALIDATION_ERROR",
5199
- details: validation.errors
5200
- },
5201
- metadata: this.createMetadata(action, 0)
5202
- };
5203
- }
4931
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
5204
4932
  const startTime = Date.now();
5205
4933
  try {
5206
4934
  let data;
@@ -5299,18 +5027,7 @@ var ArxivIntegration = class extends BaseIntegration {
5299
5027
  }
5300
5028
  async execute(action, params) {
5301
5029
  const validation = this.validateParams(action, params);
5302
- if (!validation.valid) {
5303
- return {
5304
- success: false,
5305
- error: {
5306
- name: "IntegrationError",
5307
- message: "Validation failed",
5308
- code: "VALIDATION_ERROR",
5309
- details: validation.errors
5310
- },
5311
- metadata: this.createMetadata(action, 0)
5312
- };
5313
- }
5030
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
5314
5031
  const startTime = Date.now();
5315
5032
  try {
5316
5033
  let data;
@@ -5382,32 +5099,10 @@ var RiggerIntegration = class extends BaseIntegration {
5382
5099
  }
5383
5100
  async execute(action, params) {
5384
5101
  const validation = this.validateParams(action, params);
5385
- if (!validation.valid) {
5386
- return {
5387
- success: false,
5388
- error: {
5389
- name: "IntegrationError",
5390
- message: "Validation failed",
5391
- code: "VALIDATION_ERROR",
5392
- details: validation.errors
5393
- },
5394
- metadata: this.createMetadata(action, 0)
5395
- };
5396
- }
5102
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
5397
5103
  if (action === "generate") {
5398
5104
  const invalid = generateParamErrors(params);
5399
- if (invalid.length > 0) {
5400
- return {
5401
- success: false,
5402
- error: {
5403
- name: "IntegrationError",
5404
- message: "Validation failed",
5405
- code: "VALIDATION_ERROR",
5406
- details: invalid
5407
- },
5408
- metadata: this.createMetadata(action, 0)
5409
- };
5410
- }
5105
+ if (invalid.length > 0) return this.validationFailure(action, invalid.map((message) => ({ param: "params", message })));
5411
5106
  }
5412
5107
  const startTime = Date.now();
5413
5108
  try {
@@ -5680,7 +5375,6 @@ var RuntimeIntegrationManager = class {
5680
5375
  this.storeEnvBase = null;
5681
5376
  this.storeFirst = false;
5682
5377
  this.factory = new IntegrationFactory();
5683
- this.installNotConfiguredFallback();
5684
5378
  installActiveFactory(this.factory);
5685
5379
  }
5686
5380
  /**
@@ -5740,37 +5434,6 @@ var RuntimeIntegrationManager = class {
5740
5434
  }
5741
5435
  this.configureFromEnv({ ...base, ...this.credentialStore.snapshotEnv() });
5742
5436
  }
5743
- /**
5744
- * Wrap `factory.execute` so an unknown/unconfigured service echoes its
5745
- * params instead of throwing. This makes the manager safe to install as a
5746
- * default `callService` handler (e.g. the playground sidecar) without every
5747
- * service being configured. REAL execution errors (API failures, bad
5748
- * params, schema violations) still propagate so the circuit's failure
5749
- * events fire — only the two "not set up" errors (`Unknown integration`,
5750
- * `Integration not configured`) are caught. Subsumes the broader wrapper
5751
- * that previously lived inside `configureMockMode`.
5752
- *
5753
- * In production the fallback is OFF: a missing key must surface as the
5754
- * circuit's failure event and a degraded health check, never a fake success.
5755
- */
5756
- installNotConfiguredFallback() {
5757
- const originalExecute = this.factory.execute.bind(this.factory);
5758
- this.factory.execute = async (integration, action, params, context) => {
5759
- try {
5760
- return await originalExecute(integration, action, params, context);
5761
- } catch (err) {
5762
- const msg = err instanceof Error ? err.message : String(err);
5763
- if (process.env.NODE_ENV !== "production" && /Unknown integration|not configured/i.test(msg)) {
5764
- return {
5765
- success: true,
5766
- data: { ...params, _mock: true, _service: integration, _action: action },
5767
- metadata: { integration, action, duration: 0, retries: 0, timestamp: Date.now() }
5768
- };
5769
- }
5770
- throw err;
5771
- }
5772
- };
5773
- }
5774
5437
  /**
5775
5438
  * Configure from environment variables.
5776
5439
  * In mock mode (USE_MOCK_DATA=true), all services return realistic mock data.
@@ -5927,7 +5590,7 @@ var RuntimeIntegrationManager = class {
5927
5590
  for (const k of ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "DEEPSEEK_API_KEY", "KIMI_API_KEY", "OPEN_ROUTER_API_KEY"]) {
5928
5591
  if (env[k]) llmEnv[k] = env[k];
5929
5592
  }
5930
- if (env.PROVIDER) llmEnv.PROVIDER = env.PROVIDER;
5593
+ if (env.LLM_PROVIDER) llmEnv.PROVIDER = env.LLM_PROVIDER;
5931
5594
  for (const k of ["EMBEDDING_PROVIDER", "EMBEDDING_MODEL", "EMBEDDING_API_KEY"]) {
5932
5595
  if (env[k]) llmEnv[k] = env[k];
5933
5596
  }
@@ -5961,6 +5624,27 @@ var RuntimeIntegrationManager = class {
5961
5624
  }
5962
5625
  });
5963
5626
  }
5627
+ this.configureFromDeclaredCredentials(env);
5628
+ }
5629
+ /**
5630
+ * Every registered service the blocks above did not configure, configured
5631
+ * from its declared credentials (`serviceCredentials`) once all its required
5632
+ * ones are present: keyless services always, keyed ones only with their keys.
5633
+ */
5634
+ configureFromDeclaredCredentials(env) {
5635
+ for (const name of getRegisteredIntegrations()) {
5636
+ if (this.factory.isConfigured(name)) continue;
5637
+ const declared = serviceCredentials[name] ?? [];
5638
+ if (declared.some((c) => c.required && !env[c.envVar])) continue;
5639
+ const groups = new Set(declared.flatMap((c) => c.oneOf ? [c.oneOf] : []));
5640
+ if ([...groups].some((g) => !declared.some((c) => c.oneOf === g && env[c.envVar]))) continue;
5641
+ const serviceEnv = {};
5642
+ for (const { envVar } of declared) {
5643
+ const value = env[envVar];
5644
+ if (value) serviceEnv[envVar] = value;
5645
+ }
5646
+ this.factory.configure(name, { env: serviceEnv });
5647
+ }
5964
5648
  }
5965
5649
  /**
5966
5650
  * Configure mock mode: register MockIntegration for all known services