integrate-sdk 0.9.19-dev.0 → 0.9.21-dev.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.
- package/dist/adapters/auto-routes.js +22 -2
- package/dist/adapters/base-handler.d.ts.map +1 -1
- package/dist/adapters/base-handler.js +22 -2
- package/dist/adapters/index.js +22 -2
- package/dist/adapters/nextjs.js +22 -2
- package/dist/adapters/solid-start.js +22 -2
- package/dist/adapters/svelte-kit.js +22 -2
- package/dist/ai/anthropic.js +52 -0
- package/dist/ai/google.js +52 -0
- package/dist/ai/index.js +52 -0
- package/dist/ai/openai.js +52 -0
- package/dist/ai/vercel-ai.js +52 -0
- package/dist/code-mode/executor.d.ts.map +1 -1
- package/dist/code-mode/executor.js +35 -0
- package/dist/code-mode/index.js +105 -0
- package/dist/code-mode/runtime-stub.d.ts +1 -1
- package/dist/code-mode/runtime-stub.d.ts.map +1 -1
- package/dist/code-mode/runtime-stub.js +25 -0
- package/dist/code-mode/tool-builder.d.ts.map +1 -1
- package/dist/code-mode/tool-builder.js +105 -0
- package/dist/index.js +22 -2
- package/dist/oauth.js +22 -2
- package/dist/server.js +171 -57
- package/dist/src/adapters/base-handler.d.ts.map +1 -1
- package/dist/src/code-mode/executor.d.ts.map +1 -1
- package/dist/src/code-mode/runtime-stub.d.ts +1 -1
- package/dist/src/code-mode/runtime-stub.d.ts.map +1 -1
- package/dist/src/code-mode/tool-builder.d.ts.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/ai/vercel-ai.js
CHANGED
|
@@ -4677,6 +4677,21 @@ if (!MCP_URL) {
|
|
|
4677
4677
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
4678
4678
|
}
|
|
4679
4679
|
|
|
4680
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
4681
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
4682
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
4683
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
4684
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
4685
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
4686
|
+
if (PROVIDER_TOKENS) {
|
|
4687
|
+
try {
|
|
4688
|
+
const _parsed = JSON.parse(PROVIDER_TOKENS);
|
|
4689
|
+
const _keys = Object.keys(_parsed);
|
|
4690
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
4691
|
+
console.error('[sandbox-diag] TOKEN_LENGTHS=' + _keys.map(k => k + ':' + (typeof _parsed[k] === 'string' ? _parsed[k].length : typeof _parsed[k])).join(','));
|
|
4692
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
4693
|
+
}
|
|
4694
|
+
|
|
4680
4695
|
function camelToSnake(str) {
|
|
4681
4696
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
4682
4697
|
}
|
|
@@ -4692,6 +4707,14 @@ async function callTool(toolName, args) {
|
|
|
4692
4707
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
4693
4708
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
4694
4709
|
|
|
4710
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
4711
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
4712
|
+
hasAuth: !!headers['Authorization'],
|
|
4713
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
4714
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
4715
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
4716
|
+
}));
|
|
4717
|
+
|
|
4695
4718
|
const res = await fetch(MCP_URL, {
|
|
4696
4719
|
method: 'POST',
|
|
4697
4720
|
headers,
|
|
@@ -4699,6 +4722,8 @@ async function callTool(toolName, args) {
|
|
|
4699
4722
|
});
|
|
4700
4723
|
|
|
4701
4724
|
const text = await res.text();
|
|
4725
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
4726
|
+
|
|
4702
4727
|
let payload;
|
|
4703
4728
|
try {
|
|
4704
4729
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -4876,6 +4901,16 @@ async function executeSandboxCode(options) {
|
|
|
4876
4901
|
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
4877
4902
|
if (options.context)
|
|
4878
4903
|
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
4904
|
+
console.debug("[integrate-sdk] Sandbox env:", JSON.stringify({
|
|
4905
|
+
mcpUrl: options.mcpUrl,
|
|
4906
|
+
hasApiKey: !!options.apiKey,
|
|
4907
|
+
hasSessionToken: !!options.sessionToken,
|
|
4908
|
+
providerTokenKeys: options.providerTokens ? Object.keys(options.providerTokens) : [],
|
|
4909
|
+
hasIntegrations: !!options.integrationsHeader,
|
|
4910
|
+
hasContext: !!options.context,
|
|
4911
|
+
runtime,
|
|
4912
|
+
timeoutMs
|
|
4913
|
+
}));
|
|
4879
4914
|
const cmd = await sandbox.runCommand({
|
|
4880
4915
|
cmd: "node",
|
|
4881
4916
|
args: ["user.mjs"],
|
|
@@ -5002,6 +5037,15 @@ ${generated.compact}`;
|
|
|
5002
5037
|
}
|
|
5003
5038
|
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
5004
5039
|
let resolvedTokens = providerTokens;
|
|
5040
|
+
let tokenSource = resolvedTokens && Object.keys(resolvedTokens).length > 0 ? "build-time" : "none";
|
|
5041
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
5042
|
+
try {
|
|
5043
|
+
resolvedTokens = await getProviderTokens();
|
|
5044
|
+
if (resolvedTokens && Object.keys(resolvedTokens).length > 0) {
|
|
5045
|
+
tokenSource = "request-header";
|
|
5046
|
+
}
|
|
5047
|
+
} catch {}
|
|
5048
|
+
}
|
|
5005
5049
|
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
5006
5050
|
const oauthManager = client.oauthManager;
|
|
5007
5051
|
if (oauthManager) {
|
|
@@ -5020,9 +5064,17 @@ ${generated.compact}`;
|
|
|
5020
5064
|
}
|
|
5021
5065
|
if (Object.keys(resolvedTokens).length === 0) {
|
|
5022
5066
|
resolvedTokens = undefined;
|
|
5067
|
+
} else {
|
|
5068
|
+
tokenSource = "oauthManager";
|
|
5023
5069
|
}
|
|
5024
5070
|
}
|
|
5025
5071
|
}
|
|
5072
|
+
console.debug("[integrate-sdk] execute_code token resolution:", JSON.stringify({
|
|
5073
|
+
source: tokenSource,
|
|
5074
|
+
keys: resolvedTokens ? Object.keys(resolvedTokens) : [],
|
|
5075
|
+
hasApiKey: !!apiKey,
|
|
5076
|
+
mcpUrl
|
|
5077
|
+
}));
|
|
5026
5078
|
return executeSandboxCode({
|
|
5027
5079
|
code,
|
|
5028
5080
|
mcpUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/code-mode/executor.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/code-mode/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD;;;;GAIG;AACH,UAAU,WAAW;IACnB,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,UAAU,CACR,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GACA,OAAO,CAAC;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED,UAAU,cAAc;IACtB,MAAM,CAAC,OAAO,EAAE;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1B;AAWD,8DAA8D;AAC9D,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAKhF;AAED,0EAA0E;AAC1E,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAMpE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAoC3D;AAoBD,MAAM,WAAW,yBAAyB;IACxC,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,qDAAqD;IACrD,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC9B,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,aAAa,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAA;KAAE,CAAC;CAClH;AAED,MAAM,WAAW,wBAAwB;IACvC,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA4DD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAsF9G"}
|
|
@@ -30,6 +30,21 @@ if (!MCP_URL) {
|
|
|
30
30
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
34
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
35
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
36
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
37
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
38
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
39
|
+
if (PROVIDER_TOKENS) {
|
|
40
|
+
try {
|
|
41
|
+
const _parsed = JSON.parse(PROVIDER_TOKENS);
|
|
42
|
+
const _keys = Object.keys(_parsed);
|
|
43
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
44
|
+
console.error('[sandbox-diag] TOKEN_LENGTHS=' + _keys.map(k => k + ':' + (typeof _parsed[k] === 'string' ? _parsed[k].length : typeof _parsed[k])).join(','));
|
|
45
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
function camelToSnake(str) {
|
|
34
49
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
35
50
|
}
|
|
@@ -45,6 +60,14 @@ async function callTool(toolName, args) {
|
|
|
45
60
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
46
61
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
47
62
|
|
|
63
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
64
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
65
|
+
hasAuth: !!headers['Authorization'],
|
|
66
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
67
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
68
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
69
|
+
}));
|
|
70
|
+
|
|
48
71
|
const res = await fetch(MCP_URL, {
|
|
49
72
|
method: 'POST',
|
|
50
73
|
headers,
|
|
@@ -52,6 +75,8 @@ async function callTool(toolName, args) {
|
|
|
52
75
|
});
|
|
53
76
|
|
|
54
77
|
const text = await res.text();
|
|
78
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
79
|
+
|
|
55
80
|
let payload;
|
|
56
81
|
try {
|
|
57
82
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -240,6 +265,16 @@ async function executeSandboxCode(options) {
|
|
|
240
265
|
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
241
266
|
if (options.context)
|
|
242
267
|
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
268
|
+
console.debug("[integrate-sdk] Sandbox env:", JSON.stringify({
|
|
269
|
+
mcpUrl: options.mcpUrl,
|
|
270
|
+
hasApiKey: !!options.apiKey,
|
|
271
|
+
hasSessionToken: !!options.sessionToken,
|
|
272
|
+
providerTokenKeys: options.providerTokens ? Object.keys(options.providerTokens) : [],
|
|
273
|
+
hasIntegrations: !!options.integrationsHeader,
|
|
274
|
+
hasContext: !!options.context,
|
|
275
|
+
runtime,
|
|
276
|
+
timeoutMs
|
|
277
|
+
}));
|
|
243
278
|
const cmd = await sandbox.runCommand({
|
|
244
279
|
cmd: "node",
|
|
245
280
|
args: ["user.mjs"],
|
package/dist/code-mode/index.js
CHANGED
|
@@ -275,6 +275,21 @@ if (!MCP_URL) {
|
|
|
275
275
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
279
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
280
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
281
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
282
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
283
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
284
|
+
if (PROVIDER_TOKENS) {
|
|
285
|
+
try {
|
|
286
|
+
const _parsed = JSON.parse(PROVIDER_TOKENS);
|
|
287
|
+
const _keys = Object.keys(_parsed);
|
|
288
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
289
|
+
console.error('[sandbox-diag] TOKEN_LENGTHS=' + _keys.map(k => k + ':' + (typeof _parsed[k] === 'string' ? _parsed[k].length : typeof _parsed[k])).join(','));
|
|
290
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
291
|
+
}
|
|
292
|
+
|
|
278
293
|
function camelToSnake(str) {
|
|
279
294
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
280
295
|
}
|
|
@@ -290,6 +305,14 @@ async function callTool(toolName, args) {
|
|
|
290
305
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
291
306
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
292
307
|
|
|
308
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
309
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
310
|
+
hasAuth: !!headers['Authorization'],
|
|
311
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
312
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
313
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
314
|
+
}));
|
|
315
|
+
|
|
293
316
|
const res = await fetch(MCP_URL, {
|
|
294
317
|
method: 'POST',
|
|
295
318
|
headers,
|
|
@@ -297,6 +320,8 @@ async function callTool(toolName, args) {
|
|
|
297
320
|
});
|
|
298
321
|
|
|
299
322
|
const text = await res.text();
|
|
323
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
324
|
+
|
|
300
325
|
let payload;
|
|
301
326
|
try {
|
|
302
327
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -485,6 +510,16 @@ async function executeSandboxCode(options) {
|
|
|
485
510
|
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
486
511
|
if (options.context)
|
|
487
512
|
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
513
|
+
console.debug("[integrate-sdk] Sandbox env:", JSON.stringify({
|
|
514
|
+
mcpUrl: options.mcpUrl,
|
|
515
|
+
hasApiKey: !!options.apiKey,
|
|
516
|
+
hasSessionToken: !!options.sessionToken,
|
|
517
|
+
providerTokenKeys: options.providerTokens ? Object.keys(options.providerTokens) : [],
|
|
518
|
+
hasIntegrations: !!options.integrationsHeader,
|
|
519
|
+
hasContext: !!options.context,
|
|
520
|
+
runtime,
|
|
521
|
+
timeoutMs
|
|
522
|
+
}));
|
|
488
523
|
const cmd = await sandbox.runCommand({
|
|
489
524
|
cmd: "node",
|
|
490
525
|
args: ["user.mjs"],
|
|
@@ -540,6 +575,59 @@ function getEnv(key) {
|
|
|
540
575
|
return;
|
|
541
576
|
}
|
|
542
577
|
|
|
578
|
+
// ../utils/request-tokens.ts
|
|
579
|
+
async function getProviderTokens(manualTokens) {
|
|
580
|
+
if (manualTokens) {
|
|
581
|
+
return manualTokens;
|
|
582
|
+
}
|
|
583
|
+
let tokensString = null;
|
|
584
|
+
if (!tokensString) {
|
|
585
|
+
try {
|
|
586
|
+
const getNextHeadersPath = () => {
|
|
587
|
+
const parts = ["next", "/headers"];
|
|
588
|
+
return parts.join("");
|
|
589
|
+
};
|
|
590
|
+
const nextHeaders = await import(getNextHeadersPath()).catch(() => null);
|
|
591
|
+
if (nextHeaders && typeof nextHeaders.headers === "function") {
|
|
592
|
+
const headersList = await Promise.resolve(nextHeaders.headers());
|
|
593
|
+
tokensString = headersList.get("x-integrate-tokens");
|
|
594
|
+
}
|
|
595
|
+
} catch {}
|
|
596
|
+
}
|
|
597
|
+
if (!tokensString) {
|
|
598
|
+
try {
|
|
599
|
+
const getNuxtHeaders = new Function(`
|
|
600
|
+
try {
|
|
601
|
+
if (typeof useRequestHeaders === 'function') {
|
|
602
|
+
return useRequestHeaders();
|
|
603
|
+
}
|
|
604
|
+
} catch {}
|
|
605
|
+
return null;
|
|
606
|
+
`);
|
|
607
|
+
const headers = getNuxtHeaders();
|
|
608
|
+
if (headers && typeof headers === "object") {
|
|
609
|
+
tokensString = headers["x-integrate-tokens"];
|
|
610
|
+
}
|
|
611
|
+
} catch {}
|
|
612
|
+
}
|
|
613
|
+
if (!tokensString) {
|
|
614
|
+
if (typeof process !== "undefined" && process.env) {
|
|
615
|
+
tokensString = process.env.PROVIDER_TOKENS;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (tokensString) {
|
|
619
|
+
try {
|
|
620
|
+
const parsed = JSON.parse(tokensString);
|
|
621
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
622
|
+
return parsed;
|
|
623
|
+
}
|
|
624
|
+
} catch (error) {
|
|
625
|
+
throw new Error(`Failed to parse provider tokens: ${error instanceof Error ? error.message : "Invalid JSON"}`);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
throw new Error("Provider tokens not found. Please pass tokens manually via options.providerTokens or set the x-integrate-tokens header in your request.");
|
|
629
|
+
}
|
|
630
|
+
|
|
543
631
|
// tool-builder.ts
|
|
544
632
|
var CODE_MODE_TOOL_NAME = "execute_code";
|
|
545
633
|
var TYPES_TOOL_NAME = "get_integration_types";
|
|
@@ -617,6 +705,15 @@ ${generated.compact}`;
|
|
|
617
705
|
}
|
|
618
706
|
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
619
707
|
let resolvedTokens = providerTokens;
|
|
708
|
+
let tokenSource = resolvedTokens && Object.keys(resolvedTokens).length > 0 ? "build-time" : "none";
|
|
709
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
710
|
+
try {
|
|
711
|
+
resolvedTokens = await getProviderTokens();
|
|
712
|
+
if (resolvedTokens && Object.keys(resolvedTokens).length > 0) {
|
|
713
|
+
tokenSource = "request-header";
|
|
714
|
+
}
|
|
715
|
+
} catch {}
|
|
716
|
+
}
|
|
620
717
|
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
621
718
|
const oauthManager = client.oauthManager;
|
|
622
719
|
if (oauthManager) {
|
|
@@ -635,9 +732,17 @@ ${generated.compact}`;
|
|
|
635
732
|
}
|
|
636
733
|
if (Object.keys(resolvedTokens).length === 0) {
|
|
637
734
|
resolvedTokens = undefined;
|
|
735
|
+
} else {
|
|
736
|
+
tokenSource = "oauthManager";
|
|
638
737
|
}
|
|
639
738
|
}
|
|
640
739
|
}
|
|
740
|
+
console.debug("[integrate-sdk] execute_code token resolution:", JSON.stringify({
|
|
741
|
+
source: tokenSource,
|
|
742
|
+
keys: resolvedTokens ? Object.keys(resolvedTokens) : [],
|
|
743
|
+
hasApiKey: !!apiKey,
|
|
744
|
+
mcpUrl
|
|
745
|
+
}));
|
|
641
746
|
return executeSandboxCode({
|
|
642
747
|
code,
|
|
643
748
|
mcpUrl,
|
|
@@ -12,5 +12,5 @@
|
|
|
12
12
|
* dependencies. It is NOT imported by the host SDK — it only ships as a
|
|
13
13
|
* literal payload to the sandbox.
|
|
14
14
|
*/
|
|
15
|
-
export declare const RUNTIME_STUB_SOURCE = "// runtime.mjs \u2014 generated by integrate-sdk code mode\nconst MCP_URL = process.env.INTEGRATE_MCP_URL;\nconst SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;\nconst API_KEY = process.env.INTEGRATE_API_KEY || '';\nconst PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';\nconst INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';\nconst CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';\n\nif (!MCP_URL) {\n throw new Error('INTEGRATE_MCP_URL is not set \u2014 the sandbox cannot reach the MCP route.');\n}\n\nfunction camelToSnake(str) {\n return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());\n}\n\nasync function callTool(toolName, args) {\n const headers = {\n 'Content-Type': 'application/json',\n 'x-integrate-code-mode': '1',\n };\n if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;\n if (API_KEY) headers['x-integrate-api-key'] = API_KEY;\n if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;\n if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;\n if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;\n\n const res = await fetch(MCP_URL, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name: toolName, arguments: args || {} }),\n });\n\n const text = await res.text();\n let payload;\n try {\n payload = text ? JSON.parse(text) : null;\n } catch {\n payload = { content: [{ type: 'text', text }] };\n }\n\n if (!res.ok) {\n let message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;\n if ((res.status === 401 || res.status === 403) && typeof text === 'string' && text.indexOf('Authorization header') !== -1) {\n message =\n 'Code Mode callback was rejected by the MCP server (HTTP ' + res.status + '). ' +\n 'The SDK route could not synthesize an Authorization header. Check the host-side ' +\n 'createMCPServer config (apiKey, getProviderToken) or pass providerTokens to the ' +\n 'AI helper. Original upstream message: ' + text;\n }\n const err = new Error(message);\n err.status = res.status;\n err.toolName = toolName;\n throw err;\n }\n\n return payload;\n}\n\nfunction createIntegrationProxy(integrationId) {\n return new Proxy({}, {\n get(_target, methodName) {\n if (typeof methodName !== 'string') return undefined;\n return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);\n },\n });\n}\n\nexport const client = new Proxy({}, {\n get(_target, integrationId) {\n if (typeof integrationId !== 'string') return undefined;\n return createIntegrationProxy(integrationId);\n },\n});\n\nexport { callTool };\n";
|
|
15
|
+
export declare const RUNTIME_STUB_SOURCE = "// runtime.mjs \u2014 generated by integrate-sdk code mode\nconst MCP_URL = process.env.INTEGRATE_MCP_URL;\nconst SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;\nconst API_KEY = process.env.INTEGRATE_API_KEY || '';\nconst PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';\nconst INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';\nconst CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';\n\nif (!MCP_URL) {\n throw new Error('INTEGRATE_MCP_URL is not set \u2014 the sandbox cannot reach the MCP route.');\n}\n\n// Diagnostic: log sandbox env summary to stderr so it shows up in the\n// execute_code result's stderr field for debugging auth issues.\nconsole.error('[sandbox-diag] MCP_URL=' + MCP_URL);\nconsole.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);\nconsole.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);\nconsole.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);\nif (PROVIDER_TOKENS) {\n try {\n const _parsed = JSON.parse(PROVIDER_TOKENS);\n const _keys = Object.keys(_parsed);\n console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));\n console.error('[sandbox-diag] TOKEN_LENGTHS=' + _keys.map(k => k + ':' + (typeof _parsed[k] === 'string' ? _parsed[k].length : typeof _parsed[k])).join(','));\n } catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }\n}\n\nfunction camelToSnake(str) {\n return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());\n}\n\nasync function callTool(toolName, args) {\n const headers = {\n 'Content-Type': 'application/json',\n 'x-integrate-code-mode': '1',\n };\n if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;\n if (API_KEY) headers['x-integrate-api-key'] = API_KEY;\n if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;\n if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;\n if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;\n\n console.error('[sandbox-diag] callTool: ' + toolName + ' \u2192 ' + MCP_URL);\n console.error('[sandbox-diag] headers: ' + JSON.stringify({\n hasAuth: !!headers['Authorization'],\n hasApiKey: !!headers['x-integrate-api-key'],\n hasTokens: !!headers['x-integrate-tokens'],\n hasCodeMode: !!headers['x-integrate-code-mode'],\n }));\n\n const res = await fetch(MCP_URL, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name: toolName, arguments: args || {} }),\n });\n\n const text = await res.text();\n console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);\n\n let payload;\n try {\n payload = text ? JSON.parse(text) : null;\n } catch {\n payload = { content: [{ type: 'text', text }] };\n }\n\n if (!res.ok) {\n let message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;\n if ((res.status === 401 || res.status === 403) && typeof text === 'string' && text.indexOf('Authorization header') !== -1) {\n message =\n 'Code Mode callback was rejected by the MCP server (HTTP ' + res.status + '). ' +\n 'The SDK route could not synthesize an Authorization header. Check the host-side ' +\n 'createMCPServer config (apiKey, getProviderToken) or pass providerTokens to the ' +\n 'AI helper. Original upstream message: ' + text;\n }\n const err = new Error(message);\n err.status = res.status;\n err.toolName = toolName;\n throw err;\n }\n\n return payload;\n}\n\nfunction createIntegrationProxy(integrationId) {\n return new Proxy({}, {\n get(_target, methodName) {\n if (typeof methodName !== 'string') return undefined;\n return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);\n },\n });\n}\n\nexport const client = new Proxy({}, {\n get(_target, integrationId) {\n if (typeof integrationId !== 'string') return undefined;\n return createIntegrationProxy(integrationId);\n },\n});\n\nexport { callTool };\n";
|
|
16
16
|
//# sourceMappingURL=runtime-stub.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-stub.d.ts","sourceRoot":"","sources":["../../../src/code-mode/runtime-stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"runtime-stub.d.ts","sourceRoot":"","sources":["../../../src/code-mode/runtime-stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,mBAAmB,s8HAqG/B,CAAC"}
|
|
@@ -30,6 +30,21 @@ if (!MCP_URL) {
|
|
|
30
30
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
34
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
35
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
36
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
37
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
38
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
39
|
+
if (PROVIDER_TOKENS) {
|
|
40
|
+
try {
|
|
41
|
+
const _parsed = JSON.parse(PROVIDER_TOKENS);
|
|
42
|
+
const _keys = Object.keys(_parsed);
|
|
43
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
44
|
+
console.error('[sandbox-diag] TOKEN_LENGTHS=' + _keys.map(k => k + ':' + (typeof _parsed[k] === 'string' ? _parsed[k].length : typeof _parsed[k])).join(','));
|
|
45
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
function camelToSnake(str) {
|
|
34
49
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
35
50
|
}
|
|
@@ -45,6 +60,14 @@ async function callTool(toolName, args) {
|
|
|
45
60
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
46
61
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
47
62
|
|
|
63
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
64
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
65
|
+
hasAuth: !!headers['Authorization'],
|
|
66
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
67
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
68
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
69
|
+
}));
|
|
70
|
+
|
|
48
71
|
const res = await fetch(MCP_URL, {
|
|
49
72
|
method: 'POST',
|
|
50
73
|
headers,
|
|
@@ -52,6 +75,8 @@ async function callTool(toolName, args) {
|
|
|
52
75
|
});
|
|
53
76
|
|
|
54
77
|
const text = await res.text();
|
|
78
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
79
|
+
|
|
55
80
|
let payload;
|
|
56
81
|
try {
|
|
57
82
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-builder.d.ts","sourceRoot":"","sources":["../../../src/code-mode/tool-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-builder.d.ts","sourceRoot":"","sources":["../../../src/code-mode/tool-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -275,6 +275,21 @@ if (!MCP_URL) {
|
|
|
275
275
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
279
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
280
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
281
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
282
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
283
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
284
|
+
if (PROVIDER_TOKENS) {
|
|
285
|
+
try {
|
|
286
|
+
const _parsed = JSON.parse(PROVIDER_TOKENS);
|
|
287
|
+
const _keys = Object.keys(_parsed);
|
|
288
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
289
|
+
console.error('[sandbox-diag] TOKEN_LENGTHS=' + _keys.map(k => k + ':' + (typeof _parsed[k] === 'string' ? _parsed[k].length : typeof _parsed[k])).join(','));
|
|
290
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
291
|
+
}
|
|
292
|
+
|
|
278
293
|
function camelToSnake(str) {
|
|
279
294
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
280
295
|
}
|
|
@@ -290,6 +305,14 @@ async function callTool(toolName, args) {
|
|
|
290
305
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
291
306
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
292
307
|
|
|
308
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
309
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
310
|
+
hasAuth: !!headers['Authorization'],
|
|
311
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
312
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
313
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
314
|
+
}));
|
|
315
|
+
|
|
293
316
|
const res = await fetch(MCP_URL, {
|
|
294
317
|
method: 'POST',
|
|
295
318
|
headers,
|
|
@@ -297,6 +320,8 @@ async function callTool(toolName, args) {
|
|
|
297
320
|
});
|
|
298
321
|
|
|
299
322
|
const text = await res.text();
|
|
323
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
324
|
+
|
|
300
325
|
let payload;
|
|
301
326
|
try {
|
|
302
327
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -485,6 +510,16 @@ async function executeSandboxCode(options) {
|
|
|
485
510
|
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
486
511
|
if (options.context)
|
|
487
512
|
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
513
|
+
console.debug("[integrate-sdk] Sandbox env:", JSON.stringify({
|
|
514
|
+
mcpUrl: options.mcpUrl,
|
|
515
|
+
hasApiKey: !!options.apiKey,
|
|
516
|
+
hasSessionToken: !!options.sessionToken,
|
|
517
|
+
providerTokenKeys: options.providerTokens ? Object.keys(options.providerTokens) : [],
|
|
518
|
+
hasIntegrations: !!options.integrationsHeader,
|
|
519
|
+
hasContext: !!options.context,
|
|
520
|
+
runtime,
|
|
521
|
+
timeoutMs
|
|
522
|
+
}));
|
|
488
523
|
const cmd = await sandbox.runCommand({
|
|
489
524
|
cmd: "node",
|
|
490
525
|
args: ["user.mjs"],
|
|
@@ -540,6 +575,59 @@ function getEnv(key) {
|
|
|
540
575
|
return;
|
|
541
576
|
}
|
|
542
577
|
|
|
578
|
+
// ../utils/request-tokens.ts
|
|
579
|
+
async function getProviderTokens(manualTokens) {
|
|
580
|
+
if (manualTokens) {
|
|
581
|
+
return manualTokens;
|
|
582
|
+
}
|
|
583
|
+
let tokensString = null;
|
|
584
|
+
if (!tokensString) {
|
|
585
|
+
try {
|
|
586
|
+
const getNextHeadersPath = () => {
|
|
587
|
+
const parts = ["next", "/headers"];
|
|
588
|
+
return parts.join("");
|
|
589
|
+
};
|
|
590
|
+
const nextHeaders = await import(getNextHeadersPath()).catch(() => null);
|
|
591
|
+
if (nextHeaders && typeof nextHeaders.headers === "function") {
|
|
592
|
+
const headersList = await Promise.resolve(nextHeaders.headers());
|
|
593
|
+
tokensString = headersList.get("x-integrate-tokens");
|
|
594
|
+
}
|
|
595
|
+
} catch {}
|
|
596
|
+
}
|
|
597
|
+
if (!tokensString) {
|
|
598
|
+
try {
|
|
599
|
+
const getNuxtHeaders = new Function(`
|
|
600
|
+
try {
|
|
601
|
+
if (typeof useRequestHeaders === 'function') {
|
|
602
|
+
return useRequestHeaders();
|
|
603
|
+
}
|
|
604
|
+
} catch {}
|
|
605
|
+
return null;
|
|
606
|
+
`);
|
|
607
|
+
const headers = getNuxtHeaders();
|
|
608
|
+
if (headers && typeof headers === "object") {
|
|
609
|
+
tokensString = headers["x-integrate-tokens"];
|
|
610
|
+
}
|
|
611
|
+
} catch {}
|
|
612
|
+
}
|
|
613
|
+
if (!tokensString) {
|
|
614
|
+
if (typeof process !== "undefined" && process.env) {
|
|
615
|
+
tokensString = process.env.PROVIDER_TOKENS;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (tokensString) {
|
|
619
|
+
try {
|
|
620
|
+
const parsed = JSON.parse(tokensString);
|
|
621
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
622
|
+
return parsed;
|
|
623
|
+
}
|
|
624
|
+
} catch (error) {
|
|
625
|
+
throw new Error(`Failed to parse provider tokens: ${error instanceof Error ? error.message : "Invalid JSON"}`);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
throw new Error("Provider tokens not found. Please pass tokens manually via options.providerTokens or set the x-integrate-tokens header in your request.");
|
|
629
|
+
}
|
|
630
|
+
|
|
543
631
|
// tool-builder.ts
|
|
544
632
|
var CODE_MODE_TOOL_NAME = "execute_code";
|
|
545
633
|
var TYPES_TOOL_NAME = "get_integration_types";
|
|
@@ -617,6 +705,15 @@ ${generated.compact}`;
|
|
|
617
705
|
}
|
|
618
706
|
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
619
707
|
let resolvedTokens = providerTokens;
|
|
708
|
+
let tokenSource = resolvedTokens && Object.keys(resolvedTokens).length > 0 ? "build-time" : "none";
|
|
709
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
710
|
+
try {
|
|
711
|
+
resolvedTokens = await getProviderTokens();
|
|
712
|
+
if (resolvedTokens && Object.keys(resolvedTokens).length > 0) {
|
|
713
|
+
tokenSource = "request-header";
|
|
714
|
+
}
|
|
715
|
+
} catch {}
|
|
716
|
+
}
|
|
620
717
|
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
621
718
|
const oauthManager = client.oauthManager;
|
|
622
719
|
if (oauthManager) {
|
|
@@ -635,9 +732,17 @@ ${generated.compact}`;
|
|
|
635
732
|
}
|
|
636
733
|
if (Object.keys(resolvedTokens).length === 0) {
|
|
637
734
|
resolvedTokens = undefined;
|
|
735
|
+
} else {
|
|
736
|
+
tokenSource = "oauthManager";
|
|
638
737
|
}
|
|
639
738
|
}
|
|
640
739
|
}
|
|
740
|
+
console.debug("[integrate-sdk] execute_code token resolution:", JSON.stringify({
|
|
741
|
+
source: tokenSource,
|
|
742
|
+
keys: resolvedTokens ? Object.keys(resolvedTokens) : [],
|
|
743
|
+
hasApiKey: !!apiKey,
|
|
744
|
+
mcpUrl
|
|
745
|
+
}));
|
|
641
746
|
return executeSandboxCode({
|
|
642
747
|
code,
|
|
643
748
|
mcpUrl,
|
package/dist/index.js
CHANGED
|
@@ -3396,11 +3396,31 @@ class OAuthHandler {
|
|
|
3396
3396
|
arguments: request.arguments || {}
|
|
3397
3397
|
}
|
|
3398
3398
|
};
|
|
3399
|
-
|
|
3399
|
+
console.warn("[integrate-sdk] handleToolCall →", url, JSON.stringify({
|
|
3400
|
+
tool: request.name,
|
|
3401
|
+
hasAuth: !!headers["Authorization"],
|
|
3402
|
+
hasApiKey: !!headers["X-API-KEY"],
|
|
3403
|
+
headerKeys: Object.keys(headers)
|
|
3404
|
+
}));
|
|
3405
|
+
let response = await fetch(url, {
|
|
3400
3406
|
method: "POST",
|
|
3401
3407
|
headers,
|
|
3402
|
-
body: JSON.stringify(jsonRpcRequest)
|
|
3408
|
+
body: JSON.stringify(jsonRpcRequest),
|
|
3409
|
+
redirect: "manual"
|
|
3403
3410
|
});
|
|
3411
|
+
if (response.status >= 300 && response.status < 400) {
|
|
3412
|
+
const location = response.headers.get("location");
|
|
3413
|
+
if (location) {
|
|
3414
|
+
const redirectUrl = new URL(location, url).href;
|
|
3415
|
+
console.warn(`[integrate-sdk] handleToolCall: following redirect ${response.status} → ${redirectUrl} (preserving Authorization header)`);
|
|
3416
|
+
response = await fetch(redirectUrl, {
|
|
3417
|
+
method: "POST",
|
|
3418
|
+
headers,
|
|
3419
|
+
body: JSON.stringify(jsonRpcRequest),
|
|
3420
|
+
redirect: "manual"
|
|
3421
|
+
});
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3404
3424
|
if (!response.ok) {
|
|
3405
3425
|
const error = await response.text();
|
|
3406
3426
|
throw new Error(`MCP server failed to execute tool call: ${error}`);
|
package/dist/oauth.js
CHANGED
|
@@ -831,11 +831,31 @@ class OAuthHandler {
|
|
|
831
831
|
arguments: request.arguments || {}
|
|
832
832
|
}
|
|
833
833
|
};
|
|
834
|
-
|
|
834
|
+
console.warn("[integrate-sdk] handleToolCall →", url, JSON.stringify({
|
|
835
|
+
tool: request.name,
|
|
836
|
+
hasAuth: !!headers["Authorization"],
|
|
837
|
+
hasApiKey: !!headers["X-API-KEY"],
|
|
838
|
+
headerKeys: Object.keys(headers)
|
|
839
|
+
}));
|
|
840
|
+
let response = await fetch(url, {
|
|
835
841
|
method: "POST",
|
|
836
842
|
headers,
|
|
837
|
-
body: JSON.stringify(jsonRpcRequest)
|
|
843
|
+
body: JSON.stringify(jsonRpcRequest),
|
|
844
|
+
redirect: "manual"
|
|
838
845
|
});
|
|
846
|
+
if (response.status >= 300 && response.status < 400) {
|
|
847
|
+
const location = response.headers.get("location");
|
|
848
|
+
if (location) {
|
|
849
|
+
const redirectUrl = new URL(location, url).href;
|
|
850
|
+
console.warn(`[integrate-sdk] handleToolCall: following redirect ${response.status} → ${redirectUrl} (preserving Authorization header)`);
|
|
851
|
+
response = await fetch(redirectUrl, {
|
|
852
|
+
method: "POST",
|
|
853
|
+
headers,
|
|
854
|
+
body: JSON.stringify(jsonRpcRequest),
|
|
855
|
+
redirect: "manual"
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
}
|
|
839
859
|
if (!response.ok) {
|
|
840
860
|
const error = await response.text();
|
|
841
861
|
throw new Error(`MCP server failed to execute tool call: ${error}`);
|