@almadar/integrations 2.35.0 → 2.37.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;
@@ -5349,6 +5066,18 @@ registerIntegration("arxiv", ArxivIntegration);
5349
5066
  var DEFAULT_BASE_URL = "http://127.0.0.1:8181";
5350
5067
  var DEFAULT_TIMEOUT_MS5 = 3e4;
5351
5068
  var DEFAULT_GENERATE_TIMEOUT_MS = 6e5;
5069
+ var GENERATE_MODELS = ["z-image-turbo", "kontext"];
5070
+ function generateParamErrors(params) {
5071
+ const errors = [];
5072
+ const model = params.model;
5073
+ if (typeof model !== "string" || !GENERATE_MODELS.includes(model)) {
5074
+ errors.push(`model must be one of ${GENERATE_MODELS.join(", ")}`);
5075
+ }
5076
+ if (model === "kontext" && (typeof params.sourcePath !== "string" || params.sourcePath === "")) {
5077
+ errors.push("sourcePath is required when model is kontext");
5078
+ }
5079
+ return errors;
5080
+ }
5352
5081
  async function riggerError(path, response) {
5353
5082
  let detail = "";
5354
5083
  try {
@@ -5370,17 +5099,10 @@ var RiggerIntegration = class extends BaseIntegration {
5370
5099
  }
5371
5100
  async execute(action, params) {
5372
5101
  const validation = this.validateParams(action, params);
5373
- if (!validation.valid) {
5374
- return {
5375
- success: false,
5376
- error: {
5377
- name: "IntegrationError",
5378
- message: "Validation failed",
5379
- code: "VALIDATION_ERROR",
5380
- details: validation.errors
5381
- },
5382
- metadata: this.createMetadata(action, 0)
5383
- };
5102
+ if (!validation.valid) return this.validationFailure(action, validation.errors);
5103
+ if (action === "generate") {
5104
+ const invalid = generateParamErrors(params);
5105
+ if (invalid.length > 0) return this.validationFailure(action, invalid.map((message) => ({ param: "params", message })));
5384
5106
  }
5385
5107
  const startTime = Date.now();
5386
5108
  try {
@@ -5407,6 +5129,12 @@ var RiggerIntegration = class extends BaseIntegration {
5407
5129
  case "ownership":
5408
5130
  data = await this.executeWithRetry(() => this.ownership(params));
5409
5131
  break;
5132
+ case "buildLayers":
5133
+ data = await this.executeWithRetry(() => this.buildLayers(params));
5134
+ break;
5135
+ case "pose":
5136
+ data = await this.executeWithRetry(() => this.pose(params));
5137
+ break;
5410
5138
  case "generate":
5411
5139
  data = await this.executeWithRetry(() => this.generate(params));
5412
5140
  break;
@@ -5502,6 +5230,32 @@ var RiggerIntegration = class extends BaseIntegration {
5502
5230
  }
5503
5231
  return await response.json();
5504
5232
  }
5233
+ async buildLayers(params) {
5234
+ const { imagePath, rig, outDir } = params;
5235
+ const response = await fetch(`${this.baseUrl}/layers`, {
5236
+ method: "POST",
5237
+ headers: { "Content-Type": "application/json" },
5238
+ body: JSON.stringify({ imagePath, rig, outDir }),
5239
+ signal: AbortSignal.timeout(this.timeoutMs)
5240
+ });
5241
+ if (!response.ok) {
5242
+ throw await riggerError("/layers", response);
5243
+ }
5244
+ return await response.json();
5245
+ }
5246
+ async pose(params) {
5247
+ const { imagePath, rig, roles, preset, overrides } = params;
5248
+ const response = await fetch(`${this.baseUrl}/pose`, {
5249
+ method: "POST",
5250
+ headers: { "Content-Type": "application/json" },
5251
+ body: JSON.stringify({ imagePath, rig, roles, preset, overrides }),
5252
+ signal: AbortSignal.timeout(this.timeoutMs)
5253
+ });
5254
+ if (!response.ok) {
5255
+ throw await riggerError("/pose", response);
5256
+ }
5257
+ return await response.json();
5258
+ }
5505
5259
  async generate(params) {
5506
5260
  const { model, prompt, seed, size, steps, sourcePath, outDir } = params;
5507
5261
  const response = await fetch(`${this.baseUrl}/generate`, {
@@ -5577,29 +5331,42 @@ function createCallServiceHandler(factory) {
5577
5331
  }
5578
5332
 
5579
5333
  // src/runtime/RuntimeIntegrationManager.ts
5580
- function generateMockFromShape(shape) {
5581
- const data = {};
5582
- for (const [key, type] of Object.entries(shape)) {
5583
- switch (type) {
5334
+ function mockValueForDescriptor(key, descriptor) {
5335
+ if (typeof descriptor === "string") {
5336
+ if (descriptor.endsWith("[]")) return [];
5337
+ switch (descriptor) {
5584
5338
  case "string":
5585
- data[key] = `mock_${key}`;
5586
- break;
5339
+ return `mock_${key}`;
5587
5340
  case "number":
5588
- data[key] = 42;
5589
- break;
5341
+ return 42;
5590
5342
  case "boolean":
5591
- data[key] = true;
5592
- break;
5343
+ return true;
5593
5344
  case "object":
5594
- data[key] = {};
5595
- break;
5596
- case "string[]":
5597
- data[key] = [];
5598
- break;
5345
+ return {};
5599
5346
  default:
5600
- data[key] = `mock_${key}`;
5347
+ return `mock_${key}`;
5601
5348
  }
5602
5349
  }
5350
+ if (descriptor.type === "array") {
5351
+ return descriptor.items ? [mockValueForDescriptor(`${key}Item`, descriptor.items)] : [];
5352
+ }
5353
+ if (descriptor.properties) {
5354
+ const obj = {};
5355
+ for (const [propKey, propDescriptor] of Object.entries(descriptor.properties)) {
5356
+ obj[propKey] = mockValueForDescriptor(propKey, propDescriptor);
5357
+ }
5358
+ return obj;
5359
+ }
5360
+ if (descriptor.mapValue) {
5361
+ return { sample: mockValueForDescriptor("sample", descriptor.mapValue) };
5362
+ }
5363
+ return {};
5364
+ }
5365
+ function generateMockFromShape(shape) {
5366
+ const data = {};
5367
+ for (const [key, descriptor] of Object.entries(shape)) {
5368
+ data[key] = mockValueForDescriptor(key, descriptor);
5369
+ }
5603
5370
  return data;
5604
5371
  }
5605
5372
  var RuntimeIntegrationManager = class {
@@ -5608,7 +5375,6 @@ var RuntimeIntegrationManager = class {
5608
5375
  this.storeEnvBase = null;
5609
5376
  this.storeFirst = false;
5610
5377
  this.factory = new IntegrationFactory();
5611
- this.installNotConfiguredFallback();
5612
5378
  installActiveFactory(this.factory);
5613
5379
  }
5614
5380
  /**
@@ -5668,37 +5434,6 @@ var RuntimeIntegrationManager = class {
5668
5434
  }
5669
5435
  this.configureFromEnv({ ...base, ...this.credentialStore.snapshotEnv() });
5670
5436
  }
5671
- /**
5672
- * Wrap `factory.execute` so an unknown/unconfigured service echoes its
5673
- * params instead of throwing. This makes the manager safe to install as a
5674
- * default `callService` handler (e.g. the playground sidecar) without every
5675
- * service being configured. REAL execution errors (API failures, bad
5676
- * params, schema violations) still propagate so the circuit's failure
5677
- * events fire — only the two "not set up" errors (`Unknown integration`,
5678
- * `Integration not configured`) are caught. Subsumes the broader wrapper
5679
- * that previously lived inside `configureMockMode`.
5680
- *
5681
- * In production the fallback is OFF: a missing key must surface as the
5682
- * circuit's failure event and a degraded health check, never a fake success.
5683
- */
5684
- installNotConfiguredFallback() {
5685
- const originalExecute = this.factory.execute.bind(this.factory);
5686
- this.factory.execute = async (integration, action, params, context) => {
5687
- try {
5688
- return await originalExecute(integration, action, params, context);
5689
- } catch (err) {
5690
- const msg = err instanceof Error ? err.message : String(err);
5691
- if (process.env.NODE_ENV !== "production" && /Unknown integration|not configured/i.test(msg)) {
5692
- return {
5693
- success: true,
5694
- data: { ...params, _mock: true, _service: integration, _action: action },
5695
- metadata: { integration, action, duration: 0, retries: 0, timestamp: Date.now() }
5696
- };
5697
- }
5698
- throw err;
5699
- }
5700
- };
5701
- }
5702
5437
  /**
5703
5438
  * Configure from environment variables.
5704
5439
  * In mock mode (USE_MOCK_DATA=true), all services return realistic mock data.
@@ -5855,7 +5590,7 @@ var RuntimeIntegrationManager = class {
5855
5590
  for (const k of ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "DEEPSEEK_API_KEY", "KIMI_API_KEY", "OPEN_ROUTER_API_KEY"]) {
5856
5591
  if (env[k]) llmEnv[k] = env[k];
5857
5592
  }
5858
- if (env.PROVIDER) llmEnv.PROVIDER = env.PROVIDER;
5593
+ if (env.LLM_PROVIDER) llmEnv.PROVIDER = env.LLM_PROVIDER;
5859
5594
  for (const k of ["EMBEDDING_PROVIDER", "EMBEDDING_MODEL", "EMBEDDING_API_KEY"]) {
5860
5595
  if (env[k]) llmEnv[k] = env[k];
5861
5596
  }
@@ -5889,6 +5624,27 @@ var RuntimeIntegrationManager = class {
5889
5624
  }
5890
5625
  });
5891
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
+ }
5892
5648
  }
5893
5649
  /**
5894
5650
  * Configure mock mode: register MockIntegration for all known services