integrate-sdk 0.9.2-dev.0 → 0.9.4-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.d.ts.map +1 -1
- package/dist/adapters/auto-routes.js +727 -17
- package/dist/adapters/base-handler.d.ts.map +1 -1
- package/dist/adapters/index.js +722 -16
- package/dist/adapters/nextjs.d.ts.map +1 -1
- package/dist/adapters/nextjs.js +722 -16
- package/dist/adapters/node.js +722 -16
- package/dist/adapters/svelte-kit.js +722 -16
- package/dist/adapters/tanstack-start.js +722 -16
- package/dist/ai/anthropic.d.ts +11 -0
- package/dist/ai/anthropic.d.ts.map +1 -1
- package/dist/ai/anthropic.js +552 -2
- package/dist/ai/google.d.ts +11 -0
- package/dist/ai/google.d.ts.map +1 -1
- package/dist/ai/google.js +561 -2
- package/dist/ai/index.js +648 -8
- package/dist/ai/openai.d.ts +11 -0
- package/dist/ai/openai.d.ts.map +1 -1
- package/dist/ai/openai.js +550 -2
- package/dist/ai/vercel-ai.d.ts +13 -0
- package/dist/ai/vercel-ai.d.ts.map +1 -1
- package/dist/ai/vercel-ai.js +536 -2
- package/dist/code-mode/executor.d.ts +99 -0
- package/dist/code-mode/executor.d.ts.map +1 -0
- package/dist/code-mode/executor.js +207 -0
- package/dist/code-mode/index.d.ts +12 -0
- package/dist/code-mode/index.d.ts.map +1 -0
- package/dist/code-mode/index.js +527 -0
- package/dist/code-mode/runtime-stub.d.ts +16 -0
- package/dist/code-mode/runtime-stub.d.ts.map +1 -0
- package/dist/code-mode/runtime-stub.js +72 -0
- package/dist/code-mode/tool-builder.d.ts +83 -0
- package/dist/code-mode/tool-builder.d.ts.map +1 -0
- package/dist/code-mode/tool-builder.js +524 -0
- package/dist/code-mode/type-generator.d.ts +22 -0
- package/dist/code-mode/type-generator.d.ts.map +1 -0
- package/dist/code-mode/type-generator.js +217 -0
- package/dist/index.js +722 -16
- package/dist/oauth.js +727 -17
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +733 -17
- package/dist/src/adapters/auto-routes.d.ts.map +1 -1
- package/dist/src/adapters/base-handler.d.ts.map +1 -1
- package/dist/src/adapters/nextjs.d.ts.map +1 -1
- package/dist/src/ai/anthropic.d.ts +11 -0
- package/dist/src/ai/anthropic.d.ts.map +1 -1
- package/dist/src/ai/google.d.ts +11 -0
- package/dist/src/ai/google.d.ts.map +1 -1
- package/dist/src/ai/openai.d.ts +11 -0
- package/dist/src/ai/openai.d.ts.map +1 -1
- package/dist/src/ai/vercel-ai.d.ts +13 -0
- package/dist/src/ai/vercel-ai.d.ts.map +1 -1
- package/dist/src/code-mode/executor.d.ts +99 -0
- package/dist/src/code-mode/executor.d.ts.map +1 -0
- package/dist/src/code-mode/index.d.ts +12 -0
- package/dist/src/code-mode/index.d.ts.map +1 -0
- package/dist/src/code-mode/runtime-stub.d.ts +16 -0
- package/dist/src/code-mode/runtime-stub.d.ts.map +1 -0
- package/dist/src/code-mode/tool-builder.d.ts +83 -0
- package/dist/src/code-mode/tool-builder.d.ts.map +1 -0
- package/dist/src/code-mode/type-generator.d.ts +22 -0
- package/dist/src/code-mode/type-generator.d.ts.map +1 -0
- package/dist/src/config/types.d.ts +55 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/package.json +15 -6
- package/server.ts +9 -0
package/dist/oauth.js
CHANGED
|
@@ -507,10 +507,17 @@ var init_errors = __esm(() => {
|
|
|
507
507
|
function camelToSnake(str) {
|
|
508
508
|
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
509
509
|
}
|
|
510
|
+
function snakeToCamel(str) {
|
|
511
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
512
|
+
}
|
|
510
513
|
function methodToToolName(methodName, integrationId) {
|
|
511
514
|
const snakeCaseMethod = camelToSnake(methodName);
|
|
512
515
|
return `${integrationId}_${snakeCaseMethod}`;
|
|
513
516
|
}
|
|
517
|
+
function toolNameToMethod(toolName) {
|
|
518
|
+
const withoutPrefix = toolName.replace(/^[^_]+_/, "");
|
|
519
|
+
return snakeToCamel(withoutPrefix);
|
|
520
|
+
}
|
|
514
521
|
|
|
515
522
|
// src/triggers/client.ts
|
|
516
523
|
class TriggerClient {
|
|
@@ -2648,7 +2655,11 @@ function createNextOAuthHandler(config) {
|
|
|
2648
2655
|
}
|
|
2649
2656
|
return response;
|
|
2650
2657
|
} catch (error) {
|
|
2651
|
-
|
|
2658
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
2659
|
+
logger6.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
2660
|
+
} else {
|
|
2661
|
+
logger6.error("[OAuth Refresh] Error:", error);
|
|
2662
|
+
}
|
|
2652
2663
|
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
2653
2664
|
}
|
|
2654
2665
|
},
|
|
@@ -8553,6 +8564,508 @@ var init_trigger_tools = __esm(() => {
|
|
|
8553
8564
|
init_utils2();
|
|
8554
8565
|
});
|
|
8555
8566
|
|
|
8567
|
+
// src/code-mode/type-generator.ts
|
|
8568
|
+
function safeIdent(name) {
|
|
8569
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) || RESERVED_TS.has(name)) {
|
|
8570
|
+
return JSON.stringify(name);
|
|
8571
|
+
}
|
|
8572
|
+
return name;
|
|
8573
|
+
}
|
|
8574
|
+
function integrationFromToolName(toolName) {
|
|
8575
|
+
const idx = toolName.indexOf("_");
|
|
8576
|
+
return idx === -1 ? toolName : toolName.slice(0, idx);
|
|
8577
|
+
}
|
|
8578
|
+
function jsonSchemaToTs(schema, indent) {
|
|
8579
|
+
if (!schema || typeof schema !== "object")
|
|
8580
|
+
return "unknown";
|
|
8581
|
+
const s = schema;
|
|
8582
|
+
if (Array.isArray(s.enum) && s.enum.length > 0) {
|
|
8583
|
+
return s.enum.map((v) => typeof v === "string" ? JSON.stringify(v) : typeof v === "number" || typeof v === "boolean" ? String(v) : "unknown").join(" | ");
|
|
8584
|
+
}
|
|
8585
|
+
if (Array.isArray(s.type)) {
|
|
8586
|
+
return s.type.map((t2) => jsonSchemaToTs({ ...s, type: t2 }, indent)).join(" | ");
|
|
8587
|
+
}
|
|
8588
|
+
const t = s.type;
|
|
8589
|
+
switch (t) {
|
|
8590
|
+
case "string":
|
|
8591
|
+
return "string";
|
|
8592
|
+
case "number":
|
|
8593
|
+
case "integer":
|
|
8594
|
+
return "number";
|
|
8595
|
+
case "boolean":
|
|
8596
|
+
return "boolean";
|
|
8597
|
+
case "null":
|
|
8598
|
+
return "null";
|
|
8599
|
+
case "array": {
|
|
8600
|
+
const items = s.items;
|
|
8601
|
+
if (Array.isArray(items))
|
|
8602
|
+
return "unknown[]";
|
|
8603
|
+
const inner = jsonSchemaToTs(items, indent);
|
|
8604
|
+
return /[|&]/.test(inner) ? `Array<${inner}>` : `${inner}[]`;
|
|
8605
|
+
}
|
|
8606
|
+
case "object":
|
|
8607
|
+
return objectShape(s, indent);
|
|
8608
|
+
default:
|
|
8609
|
+
if (s.properties && typeof s.properties === "object")
|
|
8610
|
+
return objectShape(s, indent);
|
|
8611
|
+
return "unknown";
|
|
8612
|
+
}
|
|
8613
|
+
}
|
|
8614
|
+
function objectShape(schema, indent) {
|
|
8615
|
+
const props = schema.properties && typeof schema.properties === "object" ? schema.properties : {};
|
|
8616
|
+
const keys = Object.keys(props);
|
|
8617
|
+
if (keys.length === 0) {
|
|
8618
|
+
return schema.additionalProperties === false ? "Record<string, never>" : "Record<string, unknown>";
|
|
8619
|
+
}
|
|
8620
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
8621
|
+
const inner = indent + " ";
|
|
8622
|
+
const lines = ["{"];
|
|
8623
|
+
for (const key of keys) {
|
|
8624
|
+
const prop = props[key];
|
|
8625
|
+
const desc = prop && typeof prop.description === "string" ? prop.description : undefined;
|
|
8626
|
+
if (desc)
|
|
8627
|
+
lines.push(`${inner}/** ${desc.replace(/\*\//g, "*\\/")} */`);
|
|
8628
|
+
const optional = required.has(key) ? "" : "?";
|
|
8629
|
+
const type = jsonSchemaToTs(prop, inner);
|
|
8630
|
+
lines.push(`${inner}${safeIdent(key)}${optional}: ${type};`);
|
|
8631
|
+
}
|
|
8632
|
+
lines.push(`${indent}}`);
|
|
8633
|
+
return lines.join(`
|
|
8634
|
+
`);
|
|
8635
|
+
}
|
|
8636
|
+
function argsType(schema) {
|
|
8637
|
+
if (!schema)
|
|
8638
|
+
return "Record<string, unknown>";
|
|
8639
|
+
const hasProps = schema.properties && Object.keys(schema.properties).length > 0;
|
|
8640
|
+
if (!hasProps)
|
|
8641
|
+
return "Record<string, unknown>";
|
|
8642
|
+
return objectShape(schema, " ");
|
|
8643
|
+
}
|
|
8644
|
+
function methodHasRequiredArgs(schema) {
|
|
8645
|
+
if (!schema || !schema.properties)
|
|
8646
|
+
return false;
|
|
8647
|
+
const req = Array.isArray(schema.required) ? schema.required : [];
|
|
8648
|
+
return req.length > 0;
|
|
8649
|
+
}
|
|
8650
|
+
function formatDescription(desc, indent) {
|
|
8651
|
+
if (!desc)
|
|
8652
|
+
return "";
|
|
8653
|
+
const cleaned = desc.replace(/\*\//g, "*\\/").trim();
|
|
8654
|
+
if (!cleaned.includes(`
|
|
8655
|
+
`))
|
|
8656
|
+
return `${indent}/** ${cleaned} */
|
|
8657
|
+
`;
|
|
8658
|
+
const lines = cleaned.split(`
|
|
8659
|
+
`).map((l) => `${indent} * ${l}`).join(`
|
|
8660
|
+
`);
|
|
8661
|
+
return `${indent}/**
|
|
8662
|
+
${lines}
|
|
8663
|
+
${indent} */
|
|
8664
|
+
`;
|
|
8665
|
+
}
|
|
8666
|
+
function generateCodeModeTypes(tools) {
|
|
8667
|
+
const byIntegration = {};
|
|
8668
|
+
for (const tool of tools) {
|
|
8669
|
+
const integration = integrationFromToolName(tool.name);
|
|
8670
|
+
(byIntegration[integration] ??= []).push(tool);
|
|
8671
|
+
}
|
|
8672
|
+
const methodMap = {};
|
|
8673
|
+
const integrationCounts = {};
|
|
8674
|
+
const sections = [];
|
|
8675
|
+
const integrationIds = Object.keys(byIntegration).sort();
|
|
8676
|
+
sections.push("/**");
|
|
8677
|
+
sections.push(" * Integrate SDK — available APIs inside `execute_code`.");
|
|
8678
|
+
sections.push(" * Every method is async and returns the MCP tool-call response.");
|
|
8679
|
+
sections.push(" * Call them via the exported `client` object, e.g.");
|
|
8680
|
+
sections.push(" * const repos = await client.github.listRepos();");
|
|
8681
|
+
sections.push(" */");
|
|
8682
|
+
sections.push("");
|
|
8683
|
+
for (const integrationId of integrationIds) {
|
|
8684
|
+
const integrationTools = byIntegration[integrationId].slice().sort((a, b) => a.name.localeCompare(b.name));
|
|
8685
|
+
integrationCounts[integrationId] = integrationTools.length;
|
|
8686
|
+
const interfaceName = pascalCase(integrationId) + "Client";
|
|
8687
|
+
sections.push(`export interface ${interfaceName} {`);
|
|
8688
|
+
for (const tool of integrationTools) {
|
|
8689
|
+
const methodName = toolNameToMethod(tool.name);
|
|
8690
|
+
methodMap[`${integrationId}.${methodName}`] = tool.name;
|
|
8691
|
+
sections.push(formatDescription(tool.description, " "));
|
|
8692
|
+
const argType = argsType(tool.inputSchema);
|
|
8693
|
+
const argIsOptional = !methodHasRequiredArgs(tool.inputSchema);
|
|
8694
|
+
const paramName = argIsOptional ? "args?" : "args";
|
|
8695
|
+
sections.push(` ${safeIdent(methodName)}(${paramName}: ${argType}): Promise<ToolResult>;`);
|
|
8696
|
+
}
|
|
8697
|
+
sections.push("}");
|
|
8698
|
+
sections.push("");
|
|
8699
|
+
}
|
|
8700
|
+
sections.push("export interface ToolResult {");
|
|
8701
|
+
sections.push(" content: Array<{ type: 'text' | 'image' | 'resource'; text?: string; data?: string; mimeType?: string; [key: string]: unknown }>;");
|
|
8702
|
+
sections.push(" isError?: boolean;");
|
|
8703
|
+
sections.push(" structuredContent?: Record<string, unknown>;");
|
|
8704
|
+
sections.push("}");
|
|
8705
|
+
sections.push("");
|
|
8706
|
+
sections.push("export interface Client {");
|
|
8707
|
+
for (const integrationId of integrationIds) {
|
|
8708
|
+
const interfaceName = pascalCase(integrationId) + "Client";
|
|
8709
|
+
sections.push(` ${safeIdent(integrationId)}: ${interfaceName};`);
|
|
8710
|
+
}
|
|
8711
|
+
sections.push("}");
|
|
8712
|
+
sections.push("");
|
|
8713
|
+
sections.push("export declare const client: Client;");
|
|
8714
|
+
return {
|
|
8715
|
+
source: sections.filter((line, idx, arr) => !(line === "" && arr[idx - 1] === "")).join(`
|
|
8716
|
+
`),
|
|
8717
|
+
methodMap,
|
|
8718
|
+
integrationCounts
|
|
8719
|
+
};
|
|
8720
|
+
}
|
|
8721
|
+
function pascalCase(id) {
|
|
8722
|
+
return id.split(/[^A-Za-z0-9]/).filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("") || "Unknown";
|
|
8723
|
+
}
|
|
8724
|
+
var RESERVED_TS;
|
|
8725
|
+
var init_type_generator = __esm(() => {
|
|
8726
|
+
RESERVED_TS = new Set([
|
|
8727
|
+
"break",
|
|
8728
|
+
"case",
|
|
8729
|
+
"catch",
|
|
8730
|
+
"class",
|
|
8731
|
+
"const",
|
|
8732
|
+
"continue",
|
|
8733
|
+
"debugger",
|
|
8734
|
+
"default",
|
|
8735
|
+
"delete",
|
|
8736
|
+
"do",
|
|
8737
|
+
"else",
|
|
8738
|
+
"enum",
|
|
8739
|
+
"export",
|
|
8740
|
+
"extends",
|
|
8741
|
+
"false",
|
|
8742
|
+
"finally",
|
|
8743
|
+
"for",
|
|
8744
|
+
"function",
|
|
8745
|
+
"if",
|
|
8746
|
+
"import",
|
|
8747
|
+
"in",
|
|
8748
|
+
"instanceof",
|
|
8749
|
+
"new",
|
|
8750
|
+
"null",
|
|
8751
|
+
"return",
|
|
8752
|
+
"super",
|
|
8753
|
+
"switch",
|
|
8754
|
+
"this",
|
|
8755
|
+
"throw",
|
|
8756
|
+
"true",
|
|
8757
|
+
"try",
|
|
8758
|
+
"typeof",
|
|
8759
|
+
"var",
|
|
8760
|
+
"void",
|
|
8761
|
+
"while",
|
|
8762
|
+
"with",
|
|
8763
|
+
"as",
|
|
8764
|
+
"implements",
|
|
8765
|
+
"interface",
|
|
8766
|
+
"let",
|
|
8767
|
+
"package",
|
|
8768
|
+
"private",
|
|
8769
|
+
"protected",
|
|
8770
|
+
"public",
|
|
8771
|
+
"static",
|
|
8772
|
+
"yield"
|
|
8773
|
+
]);
|
|
8774
|
+
});
|
|
8775
|
+
|
|
8776
|
+
// src/code-mode/runtime-stub.ts
|
|
8777
|
+
var RUNTIME_STUB_SOURCE = `// runtime.mjs — generated by integrate-sdk code mode
|
|
8778
|
+
const MCP_URL = process.env.INTEGRATE_MCP_URL;
|
|
8779
|
+
const SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;
|
|
8780
|
+
const PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';
|
|
8781
|
+
const INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';
|
|
8782
|
+
const CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';
|
|
8783
|
+
|
|
8784
|
+
if (!MCP_URL) {
|
|
8785
|
+
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
8786
|
+
}
|
|
8787
|
+
|
|
8788
|
+
function camelToSnake(str) {
|
|
8789
|
+
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
8790
|
+
}
|
|
8791
|
+
|
|
8792
|
+
async function callTool(toolName, args) {
|
|
8793
|
+
const headers = {
|
|
8794
|
+
'Content-Type': 'application/json',
|
|
8795
|
+
'x-integrate-code-mode': '1',
|
|
8796
|
+
};
|
|
8797
|
+
if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;
|
|
8798
|
+
if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;
|
|
8799
|
+
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
8800
|
+
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
8801
|
+
|
|
8802
|
+
const res = await fetch(MCP_URL, {
|
|
8803
|
+
method: 'POST',
|
|
8804
|
+
headers,
|
|
8805
|
+
body: JSON.stringify({ name: toolName, arguments: args || {} }),
|
|
8806
|
+
});
|
|
8807
|
+
|
|
8808
|
+
const text = await res.text();
|
|
8809
|
+
let payload;
|
|
8810
|
+
try {
|
|
8811
|
+
payload = text ? JSON.parse(text) : null;
|
|
8812
|
+
} catch {
|
|
8813
|
+
payload = { content: [{ type: 'text', text }] };
|
|
8814
|
+
}
|
|
8815
|
+
|
|
8816
|
+
if (!res.ok) {
|
|
8817
|
+
const message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;
|
|
8818
|
+
const err = new Error(message);
|
|
8819
|
+
err.status = res.status;
|
|
8820
|
+
err.toolName = toolName;
|
|
8821
|
+
throw err;
|
|
8822
|
+
}
|
|
8823
|
+
|
|
8824
|
+
return payload;
|
|
8825
|
+
}
|
|
8826
|
+
|
|
8827
|
+
function createIntegrationProxy(integrationId) {
|
|
8828
|
+
return new Proxy({}, {
|
|
8829
|
+
get(_target, methodName) {
|
|
8830
|
+
if (typeof methodName !== 'string') return undefined;
|
|
8831
|
+
return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);
|
|
8832
|
+
},
|
|
8833
|
+
});
|
|
8834
|
+
}
|
|
8835
|
+
|
|
8836
|
+
export const client = new Proxy({}, {
|
|
8837
|
+
get(_target, integrationId) {
|
|
8838
|
+
if (typeof integrationId !== 'string') return undefined;
|
|
8839
|
+
return createIntegrationProxy(integrationId);
|
|
8840
|
+
},
|
|
8841
|
+
});
|
|
8842
|
+
|
|
8843
|
+
export { callTool };
|
|
8844
|
+
`;
|
|
8845
|
+
|
|
8846
|
+
// src/code-mode/executor.ts
|
|
8847
|
+
var exports_executor = {};
|
|
8848
|
+
__export(exports_executor, {
|
|
8849
|
+
executeSandboxCode: () => executeSandboxCode,
|
|
8850
|
+
__setSandboxFactoryForTests: () => __setSandboxFactoryForTests
|
|
8851
|
+
});
|
|
8852
|
+
function __setSandboxFactoryForTests(factory) {
|
|
8853
|
+
sandboxFactoryOverride = factory;
|
|
8854
|
+
}
|
|
8855
|
+
async function loadSandboxFactory() {
|
|
8856
|
+
if (sandboxFactoryOverride)
|
|
8857
|
+
return sandboxFactoryOverride;
|
|
8858
|
+
try {
|
|
8859
|
+
const dynamicImport = new Function("specifier", "return import(specifier)");
|
|
8860
|
+
const pkg = "@" + "vercel/sandbox";
|
|
8861
|
+
const mod = await dynamicImport(pkg);
|
|
8862
|
+
return mod.Sandbox ?? mod.default?.Sandbox ?? mod;
|
|
8863
|
+
} catch (err) {
|
|
8864
|
+
throw new Error("Code Mode requires the optional peer dependency `@vercel/sandbox`. " + "Install it with `npm install @vercel/sandbox` (or `bun add @vercel/sandbox`).");
|
|
8865
|
+
}
|
|
8866
|
+
}
|
|
8867
|
+
function wrapUserCode(code) {
|
|
8868
|
+
return `// user.mjs — wrapped by integrate-sdk code mode
|
|
8869
|
+
import { client, callTool } from './runtime.mjs';
|
|
8870
|
+
|
|
8871
|
+
(async () => {
|
|
8872
|
+
try {
|
|
8873
|
+
const __result = await (async () => {
|
|
8874
|
+
${code}
|
|
8875
|
+
})();
|
|
8876
|
+
if (typeof __result !== 'undefined') {
|
|
8877
|
+
process.stdout.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify(__result) + '\\n');
|
|
8878
|
+
}
|
|
8879
|
+
} catch (err) {
|
|
8880
|
+
const payload = {
|
|
8881
|
+
message: err && err.message ? err.message : String(err),
|
|
8882
|
+
name: err && err.name,
|
|
8883
|
+
stack: err && err.stack,
|
|
8884
|
+
toolName: err && err.toolName,
|
|
8885
|
+
status: err && err.status,
|
|
8886
|
+
};
|
|
8887
|
+
process.stderr.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify({ error: payload }) + '\\n');
|
|
8888
|
+
process.exit(1);
|
|
8889
|
+
}
|
|
8890
|
+
})();
|
|
8891
|
+
`;
|
|
8892
|
+
}
|
|
8893
|
+
function defaultNetworkPolicy(mcpUrl) {
|
|
8894
|
+
try {
|
|
8895
|
+
const host = new URL(mcpUrl).hostname;
|
|
8896
|
+
return { allow: [host] };
|
|
8897
|
+
} catch {
|
|
8898
|
+
return { allow: [] };
|
|
8899
|
+
}
|
|
8900
|
+
}
|
|
8901
|
+
function extractResult(stream) {
|
|
8902
|
+
const idx = stream.lastIndexOf(RESULT_SENTINEL);
|
|
8903
|
+
if (idx === -1)
|
|
8904
|
+
return { cleaned: stream };
|
|
8905
|
+
const before = stream.slice(0, idx).replace(/\n$/, "");
|
|
8906
|
+
const rest = stream.slice(idx + RESULT_SENTINEL.length);
|
|
8907
|
+
const newlineIdx = rest.indexOf(`
|
|
8908
|
+
`);
|
|
8909
|
+
const payload = newlineIdx === -1 ? rest : rest.slice(0, newlineIdx);
|
|
8910
|
+
const after = newlineIdx === -1 ? "" : rest.slice(newlineIdx + 1);
|
|
8911
|
+
try {
|
|
8912
|
+
return { cleaned: (before + after).trimEnd(), result: JSON.parse(payload) };
|
|
8913
|
+
} catch {
|
|
8914
|
+
return { cleaned: stream };
|
|
8915
|
+
}
|
|
8916
|
+
}
|
|
8917
|
+
async function executeSandboxCode(options) {
|
|
8918
|
+
const startedAt = Date.now();
|
|
8919
|
+
const runtime = options.runtime ?? "node22";
|
|
8920
|
+
const timeoutMs = options.timeoutMs ?? 60000;
|
|
8921
|
+
const networkPolicy = options.networkPolicy ?? defaultNetworkPolicy(options.mcpUrl);
|
|
8922
|
+
let sandbox = null;
|
|
8923
|
+
try {
|
|
8924
|
+
const Sandbox = await loadSandboxFactory();
|
|
8925
|
+
sandbox = await Sandbox.create({
|
|
8926
|
+
runtime,
|
|
8927
|
+
timeout: timeoutMs,
|
|
8928
|
+
resources: options.vcpus ? { vcpus: options.vcpus } : undefined,
|
|
8929
|
+
networkPolicy
|
|
8930
|
+
});
|
|
8931
|
+
const runtimeContent = Buffer.from(RUNTIME_STUB_SOURCE, "utf-8");
|
|
8932
|
+
const userContent = Buffer.from(wrapUserCode(options.code), "utf-8");
|
|
8933
|
+
await sandbox.writeFiles([
|
|
8934
|
+
{ path: "runtime.mjs", content: runtimeContent },
|
|
8935
|
+
{ path: "user.mjs", content: userContent }
|
|
8936
|
+
]);
|
|
8937
|
+
const env = {
|
|
8938
|
+
INTEGRATE_MCP_URL: options.mcpUrl
|
|
8939
|
+
};
|
|
8940
|
+
if (options.sessionToken)
|
|
8941
|
+
env.INTEGRATE_SESSION_TOKEN = options.sessionToken;
|
|
8942
|
+
if (options.providerTokens && Object.keys(options.providerTokens).length > 0) {
|
|
8943
|
+
env.INTEGRATE_PROVIDER_TOKENS = JSON.stringify(options.providerTokens);
|
|
8944
|
+
}
|
|
8945
|
+
if (options.integrationsHeader)
|
|
8946
|
+
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
8947
|
+
if (options.context)
|
|
8948
|
+
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
8949
|
+
const cmd = await sandbox.runCommand({
|
|
8950
|
+
cmd: "node",
|
|
8951
|
+
args: ["user.mjs"],
|
|
8952
|
+
env
|
|
8953
|
+
});
|
|
8954
|
+
const [stdoutRaw, stderrRaw] = await Promise.all([cmd.stdout(), cmd.stderr()]);
|
|
8955
|
+
const stdoutExtract = extractResult(stdoutRaw);
|
|
8956
|
+
const stderrExtract = extractResult(stderrRaw);
|
|
8957
|
+
return {
|
|
8958
|
+
success: cmd.exitCode === 0,
|
|
8959
|
+
exitCode: cmd.exitCode,
|
|
8960
|
+
result: stdoutExtract.result ?? stderrExtract.result,
|
|
8961
|
+
stdout: stdoutExtract.cleaned,
|
|
8962
|
+
stderr: stderrExtract.cleaned,
|
|
8963
|
+
durationMs: Date.now() - startedAt
|
|
8964
|
+
};
|
|
8965
|
+
} catch (err) {
|
|
8966
|
+
return {
|
|
8967
|
+
success: false,
|
|
8968
|
+
exitCode: -1,
|
|
8969
|
+
stdout: "",
|
|
8970
|
+
stderr: "",
|
|
8971
|
+
durationMs: Date.now() - startedAt,
|
|
8972
|
+
error: err instanceof Error ? err.message : String(err)
|
|
8973
|
+
};
|
|
8974
|
+
} finally {
|
|
8975
|
+
if (sandbox) {
|
|
8976
|
+
try {
|
|
8977
|
+
await sandbox.stop();
|
|
8978
|
+
} catch {}
|
|
8979
|
+
}
|
|
8980
|
+
}
|
|
8981
|
+
}
|
|
8982
|
+
var sandboxFactoryOverride = null, RESULT_SENTINEL = "__INTEGRATE_RESULT__";
|
|
8983
|
+
var init_executor = () => {};
|
|
8984
|
+
|
|
8985
|
+
// src/code-mode/tool-builder.ts
|
|
8986
|
+
function resolveCodeModeClientConfig(client) {
|
|
8987
|
+
const oauthConfig = client.__oauthConfig;
|
|
8988
|
+
return oauthConfig?.codeMode ?? {};
|
|
8989
|
+
}
|
|
8990
|
+
function buildCodeModeTool(client, options) {
|
|
8991
|
+
const { tools, providerTokens, context, integrationIds } = options;
|
|
8992
|
+
const generated = generateCodeModeTypes(tools);
|
|
8993
|
+
const serverCodeModeConfig = resolveCodeModeClientConfig(client);
|
|
8994
|
+
const sandboxOverrides = options.sandbox ?? {};
|
|
8995
|
+
const description = `${DEFAULT_INSTRUCTIONS}
|
|
8996
|
+
|
|
8997
|
+
\`\`\`typescript
|
|
8998
|
+
${generated.source}
|
|
8999
|
+
\`\`\``;
|
|
9000
|
+
const execute = async ({ code }) => {
|
|
9001
|
+
const publicUrl = sandboxOverrides.publicUrl ?? serverCodeModeConfig.publicUrl ?? getEnv("INTEGRATE_PUBLIC_URL");
|
|
9002
|
+
if (!publicUrl) {
|
|
9003
|
+
return {
|
|
9004
|
+
success: false,
|
|
9005
|
+
exitCode: -1,
|
|
9006
|
+
stdout: "",
|
|
9007
|
+
stderr: "",
|
|
9008
|
+
durationMs: 0,
|
|
9009
|
+
error: "Code Mode requires `codeMode.publicUrl` in createMCPServer config (or the INTEGRATE_PUBLIC_URL env var). " + "The sandbox uses it to call back into /api/integrate/mcp."
|
|
9010
|
+
};
|
|
9011
|
+
}
|
|
9012
|
+
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
9013
|
+
return executeSandboxCode({
|
|
9014
|
+
code,
|
|
9015
|
+
mcpUrl,
|
|
9016
|
+
providerTokens,
|
|
9017
|
+
context,
|
|
9018
|
+
integrationsHeader: integrationIds && integrationIds.length > 0 ? integrationIds.join(",") : undefined,
|
|
9019
|
+
runtime: sandboxOverrides.runtime ?? serverCodeModeConfig.runtime,
|
|
9020
|
+
timeoutMs: sandboxOverrides.timeoutMs ?? serverCodeModeConfig.timeoutMs,
|
|
9021
|
+
vcpus: sandboxOverrides.vcpus ?? serverCodeModeConfig.vcpus,
|
|
9022
|
+
networkPolicy: sandboxOverrides.networkPolicy ?? serverCodeModeConfig.networkPolicy
|
|
9023
|
+
});
|
|
9024
|
+
};
|
|
9025
|
+
return {
|
|
9026
|
+
name: CODE_MODE_TOOL_NAME,
|
|
9027
|
+
description,
|
|
9028
|
+
parameters: {
|
|
9029
|
+
type: "object",
|
|
9030
|
+
properties: {
|
|
9031
|
+
code: {
|
|
9032
|
+
type: "string",
|
|
9033
|
+
description: "The TypeScript/JavaScript snippet to execute. It is wrapped in an async IIFE, so you may use top-level await and return a final value."
|
|
9034
|
+
}
|
|
9035
|
+
},
|
|
9036
|
+
required: ["code"],
|
|
9037
|
+
additionalProperties: false
|
|
9038
|
+
},
|
|
9039
|
+
execute
|
|
9040
|
+
};
|
|
9041
|
+
}
|
|
9042
|
+
var CODE_MODE_TOOL_NAME = "execute_code", DEFAULT_INSTRUCTIONS;
|
|
9043
|
+
var init_tool_builder = __esm(() => {
|
|
9044
|
+
init_type_generator();
|
|
9045
|
+
init_executor();
|
|
9046
|
+
DEFAULT_INSTRUCTIONS = [
|
|
9047
|
+
"You are given a single tool: `execute_code`. Instead of calling individual MCP tools,",
|
|
9048
|
+
"you write a short async TypeScript/JavaScript snippet that uses the typed `client`",
|
|
9049
|
+
"object below, and the snippet runs in an isolated sandbox which dispatches the actual",
|
|
9050
|
+
"tool calls. Chain multiple operations together in one snippet whenever possible —",
|
|
9051
|
+
"that is the whole point of this tool.",
|
|
9052
|
+
"",
|
|
9053
|
+
"Rules:",
|
|
9054
|
+
"- The snippet is the body of an `async` function. Use `await` freely.",
|
|
9055
|
+
"- Use `return <value>` at the end to hand a structured result back to the caller;",
|
|
9056
|
+
" the caller receives it as JSON.",
|
|
9057
|
+
"- Use `console.log(...)` for intermediate observations you want to read later.",
|
|
9058
|
+
"- Throw / let errors propagate; the runtime will surface them with a non-zero exit.",
|
|
9059
|
+
"- Each method call returns an object of shape `ToolResult` (see types below).",
|
|
9060
|
+
" The payload usually lives in `result.content[0].text` as JSON — parse it if needed.",
|
|
9061
|
+
"- You cannot import npm packages. Only the pre-imported `client` and standard",
|
|
9062
|
+
" globals (`fetch`, `console`, `JSON`, ...) are available.",
|
|
9063
|
+
"",
|
|
9064
|
+
"API surface:"
|
|
9065
|
+
].join(`
|
|
9066
|
+
`);
|
|
9067
|
+
});
|
|
9068
|
+
|
|
8556
9069
|
// src/ai/vercel-ai.ts
|
|
8557
9070
|
function convertMCPToolToVercelAI(mcpTool, client, options) {
|
|
8558
9071
|
return {
|
|
@@ -8577,8 +9090,25 @@ async function getVercelAITools(client, options) {
|
|
|
8577
9090
|
await ensureClientConnected(client);
|
|
8578
9091
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
8579
9092
|
const vercelTools = {};
|
|
8580
|
-
|
|
8581
|
-
|
|
9093
|
+
const mode = options?.mode ?? "code";
|
|
9094
|
+
if (mode === "code") {
|
|
9095
|
+
const codeTool = buildCodeModeTool(client, {
|
|
9096
|
+
tools: mcpTools,
|
|
9097
|
+
providerTokens,
|
|
9098
|
+
context: options?.context,
|
|
9099
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id) ?? client.integrations?.map?.((i) => i.id)
|
|
9100
|
+
});
|
|
9101
|
+
vercelTools[CODE_MODE_TOOL_NAME] = {
|
|
9102
|
+
description: codeTool.description,
|
|
9103
|
+
inputSchema: exports_external.object({
|
|
9104
|
+
code: exports_external.string().describe(codeTool.parameters.properties.code.description)
|
|
9105
|
+
}),
|
|
9106
|
+
execute: async (args) => codeTool.execute(args)
|
|
9107
|
+
};
|
|
9108
|
+
} else {
|
|
9109
|
+
for (const mcpTool of mcpTools) {
|
|
9110
|
+
vercelTools[mcpTool.name] = convertMCPToolToVercelAI(mcpTool, client, finalOptions);
|
|
9111
|
+
}
|
|
8582
9112
|
}
|
|
8583
9113
|
const triggerConfig = client.__triggerConfig;
|
|
8584
9114
|
if (triggerConfig) {
|
|
@@ -8588,8 +9118,10 @@ async function getVercelAITools(client, options) {
|
|
|
8588
9118
|
return vercelTools;
|
|
8589
9119
|
}
|
|
8590
9120
|
var init_vercel_ai = __esm(() => {
|
|
9121
|
+
init_zod();
|
|
8591
9122
|
init_utils();
|
|
8592
9123
|
init_trigger_tools();
|
|
9124
|
+
init_tool_builder();
|
|
8593
9125
|
});
|
|
8594
9126
|
|
|
8595
9127
|
// node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
@@ -10017,7 +10549,22 @@ async function getOpenAITools(client, options) {
|
|
|
10017
10549
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10018
10550
|
await ensureClientConnected(client);
|
|
10019
10551
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10020
|
-
const
|
|
10552
|
+
const mode = options?.mode ?? "code";
|
|
10553
|
+
const openaiTools = mode === "code" ? (() => {
|
|
10554
|
+
const codeTool = buildCodeModeTool(client, {
|
|
10555
|
+
tools: mcpTools,
|
|
10556
|
+
providerTokens,
|
|
10557
|
+
context: options?.context,
|
|
10558
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10559
|
+
});
|
|
10560
|
+
return [{
|
|
10561
|
+
type: "function",
|
|
10562
|
+
name: CODE_MODE_TOOL_NAME,
|
|
10563
|
+
description: codeTool.description,
|
|
10564
|
+
parameters: codeTool.parameters,
|
|
10565
|
+
strict: options?.strict ?? null
|
|
10566
|
+
}];
|
|
10567
|
+
})() : mcpTools.map((mcpTool) => convertMCPToolToOpenAI(mcpTool, client, finalOptions));
|
|
10021
10568
|
const triggerConfig = client.__triggerConfig;
|
|
10022
10569
|
if (triggerConfig) {
|
|
10023
10570
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10042,6 +10589,19 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
|
|
|
10042
10589
|
const toolOutputs = [];
|
|
10043
10590
|
const triggerConfig = client.__triggerConfig;
|
|
10044
10591
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
10592
|
+
let cachedCodeModeTool = null;
|
|
10593
|
+
const getCodeModeTool = async () => {
|
|
10594
|
+
if (cachedCodeModeTool)
|
|
10595
|
+
return cachedCodeModeTool;
|
|
10596
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
10597
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
10598
|
+
tools: mcpTools,
|
|
10599
|
+
providerTokens: options?.providerTokens,
|
|
10600
|
+
context: options?.context,
|
|
10601
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10602
|
+
});
|
|
10603
|
+
return cachedCodeModeTool;
|
|
10604
|
+
};
|
|
10045
10605
|
for (const output of toolCalls) {
|
|
10046
10606
|
if (output.type === "function_call") {
|
|
10047
10607
|
const toolCall = {
|
|
@@ -10052,7 +10612,10 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
|
|
|
10052
10612
|
try {
|
|
10053
10613
|
const args = JSON.parse(toolCall.arguments);
|
|
10054
10614
|
let result;
|
|
10055
|
-
if (
|
|
10615
|
+
if (toolCall.name === CODE_MODE_TOOL_NAME) {
|
|
10616
|
+
const codeTool = await getCodeModeTool();
|
|
10617
|
+
result = await codeTool.execute(args);
|
|
10618
|
+
} else if (triggerTools && triggerTools[toolCall.name]) {
|
|
10056
10619
|
result = await triggerTools[toolCall.name].execute(args);
|
|
10057
10620
|
} else {
|
|
10058
10621
|
result = await executeToolWithToken(client, toolCall.name, args, options);
|
|
@@ -10093,6 +10656,7 @@ async function handleOpenAIResponse(client, response, options) {
|
|
|
10093
10656
|
var init_openai = __esm(() => {
|
|
10094
10657
|
init_utils();
|
|
10095
10658
|
init_trigger_tools();
|
|
10659
|
+
init_tool_builder();
|
|
10096
10660
|
init_esm();
|
|
10097
10661
|
});
|
|
10098
10662
|
|
|
@@ -10112,11 +10676,27 @@ async function handleAnthropicToolCalls(client, messageContent, options) {
|
|
|
10112
10676
|
const toolResults = [];
|
|
10113
10677
|
const triggerConfig = client.__triggerConfig;
|
|
10114
10678
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
10679
|
+
let cachedCodeModeTool = null;
|
|
10680
|
+
const getCodeModeTool = async () => {
|
|
10681
|
+
if (cachedCodeModeTool)
|
|
10682
|
+
return cachedCodeModeTool;
|
|
10683
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
10684
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
10685
|
+
tools: mcpTools,
|
|
10686
|
+
providerTokens: options?.providerTokens,
|
|
10687
|
+
context: options?.context,
|
|
10688
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10689
|
+
});
|
|
10690
|
+
return cachedCodeModeTool;
|
|
10691
|
+
};
|
|
10115
10692
|
const toolUseBlocks = messageContent.filter((block) => block.type === "tool_use" && ("id" in block) && ("name" in block) && ("input" in block));
|
|
10116
10693
|
for (const toolUse of toolUseBlocks) {
|
|
10117
10694
|
try {
|
|
10118
10695
|
let result;
|
|
10119
|
-
if (
|
|
10696
|
+
if (toolUse.name === CODE_MODE_TOOL_NAME) {
|
|
10697
|
+
const codeTool = await getCodeModeTool();
|
|
10698
|
+
result = await codeTool.execute(toolUse.input);
|
|
10699
|
+
} else if (triggerTools && triggerTools[toolUse.name]) {
|
|
10120
10700
|
result = await triggerTools[toolUse.name].execute(toolUse.input);
|
|
10121
10701
|
} else {
|
|
10122
10702
|
result = await executeToolWithToken(client, toolUse.name, toolUse.input, options);
|
|
@@ -10149,7 +10729,24 @@ async function getAnthropicTools(client, options) {
|
|
|
10149
10729
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10150
10730
|
await ensureClientConnected(client);
|
|
10151
10731
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10152
|
-
const
|
|
10732
|
+
const mode = options?.mode ?? "code";
|
|
10733
|
+
const anthropicTools = mode === "code" ? (() => {
|
|
10734
|
+
const codeTool = buildCodeModeTool(client, {
|
|
10735
|
+
tools: mcpTools,
|
|
10736
|
+
providerTokens,
|
|
10737
|
+
context: options?.context,
|
|
10738
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10739
|
+
});
|
|
10740
|
+
return [{
|
|
10741
|
+
name: CODE_MODE_TOOL_NAME,
|
|
10742
|
+
description: codeTool.description,
|
|
10743
|
+
input_schema: {
|
|
10744
|
+
type: "object",
|
|
10745
|
+
properties: codeTool.parameters.properties,
|
|
10746
|
+
required: [...codeTool.parameters.required]
|
|
10747
|
+
}
|
|
10748
|
+
}];
|
|
10749
|
+
})() : mcpTools.map((mcpTool) => convertMCPToolToAnthropic(mcpTool, client, finalOptions));
|
|
10153
10750
|
const triggerConfig = client.__triggerConfig;
|
|
10154
10751
|
if (triggerConfig) {
|
|
10155
10752
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10194,6 +10791,7 @@ async function handleAnthropicMessage(client, message, options) {
|
|
|
10194
10791
|
var init_anthropic = __esm(() => {
|
|
10195
10792
|
init_utils();
|
|
10196
10793
|
init_trigger_tools();
|
|
10794
|
+
init_tool_builder();
|
|
10197
10795
|
init_esm();
|
|
10198
10796
|
});
|
|
10199
10797
|
|
|
@@ -10279,13 +10877,29 @@ async function executeGoogleFunctionCalls(client, functionCalls, options) {
|
|
|
10279
10877
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10280
10878
|
const triggerConfig = client.__triggerConfig;
|
|
10281
10879
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
10880
|
+
let cachedCodeModeTool = null;
|
|
10881
|
+
const getCodeModeTool = async () => {
|
|
10882
|
+
if (cachedCodeModeTool)
|
|
10883
|
+
return cachedCodeModeTool;
|
|
10884
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
10885
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
10886
|
+
tools: mcpTools,
|
|
10887
|
+
providerTokens: finalOptions?.providerTokens,
|
|
10888
|
+
context: options?.context,
|
|
10889
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10890
|
+
});
|
|
10891
|
+
return cachedCodeModeTool;
|
|
10892
|
+
};
|
|
10282
10893
|
const results = await Promise.all(functionCalls.map(async (call) => {
|
|
10283
10894
|
if (!call?.name) {
|
|
10284
10895
|
throw new Error("Function call must have a name");
|
|
10285
10896
|
}
|
|
10286
10897
|
const args = call.args || {};
|
|
10287
10898
|
let result;
|
|
10288
|
-
if (
|
|
10899
|
+
if (call.name === CODE_MODE_TOOL_NAME) {
|
|
10900
|
+
const codeTool = await getCodeModeTool();
|
|
10901
|
+
result = await codeTool.execute(args);
|
|
10902
|
+
} else if (triggerTools && triggerTools[call.name]) {
|
|
10289
10903
|
result = await triggerTools[call.name].execute(args);
|
|
10290
10904
|
} else {
|
|
10291
10905
|
result = await executeToolWithToken(client, call.name, args, finalOptions);
|
|
@@ -10304,7 +10918,33 @@ async function getGoogleTools(client, options) {
|
|
|
10304
10918
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10305
10919
|
await ensureClientConnected(client);
|
|
10306
10920
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10307
|
-
const
|
|
10921
|
+
const mode = options?.mode ?? "code";
|
|
10922
|
+
let googleTools;
|
|
10923
|
+
if (mode === "code") {
|
|
10924
|
+
const TypeEnum = await getGoogleType();
|
|
10925
|
+
const codeTool = buildCodeModeTool(client, {
|
|
10926
|
+
tools: mcpTools,
|
|
10927
|
+
providerTokens,
|
|
10928
|
+
context: options?.context,
|
|
10929
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10930
|
+
});
|
|
10931
|
+
googleTools = [{
|
|
10932
|
+
name: CODE_MODE_TOOL_NAME,
|
|
10933
|
+
description: codeTool.description,
|
|
10934
|
+
parameters: {
|
|
10935
|
+
type: TypeEnum.OBJECT,
|
|
10936
|
+
properties: {
|
|
10937
|
+
code: {
|
|
10938
|
+
type: TypeEnum.STRING,
|
|
10939
|
+
description: codeTool.parameters.properties.code.description
|
|
10940
|
+
}
|
|
10941
|
+
},
|
|
10942
|
+
required: ["code"]
|
|
10943
|
+
}
|
|
10944
|
+
}];
|
|
10945
|
+
} else {
|
|
10946
|
+
googleTools = await Promise.all(mcpTools.map((mcpTool) => convertMCPToolToGoogle(mcpTool, client, finalOptions)));
|
|
10947
|
+
}
|
|
10308
10948
|
const triggerConfig = client.__triggerConfig;
|
|
10309
10949
|
if (triggerConfig) {
|
|
10310
10950
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10382,6 +11022,7 @@ function convertJsonSchemaToGoogleSchema(jsonSchema, TypeEnum) {
|
|
|
10382
11022
|
var init_google = __esm(() => {
|
|
10383
11023
|
init_utils();
|
|
10384
11024
|
init_trigger_tools();
|
|
11025
|
+
init_tool_builder();
|
|
10385
11026
|
init_esm();
|
|
10386
11027
|
});
|
|
10387
11028
|
|
|
@@ -10447,8 +11088,8 @@ var init_webhooks = __esm(() => {
|
|
|
10447
11088
|
var MAX_TRIGGER_STEPS = 20, WEBHOOK_DELIVERY_TIMEOUT_MS = 1e4;
|
|
10448
11089
|
|
|
10449
11090
|
// src/triggers/executor.ts
|
|
10450
|
-
var
|
|
10451
|
-
__export(
|
|
11091
|
+
var exports_executor2 = {};
|
|
11092
|
+
__export(exports_executor2, {
|
|
10452
11093
|
executeTrigger: () => executeTrigger
|
|
10453
11094
|
});
|
|
10454
11095
|
async function executeTrigger(trigger, config, context) {
|
|
@@ -10595,7 +11236,7 @@ async function executeTrigger(trigger, config, context) {
|
|
|
10595
11236
|
return { success: false, steps, error: limitError };
|
|
10596
11237
|
}
|
|
10597
11238
|
var logger31;
|
|
10598
|
-
var
|
|
11239
|
+
var init_executor2 = __esm(() => {
|
|
10599
11240
|
init_logger();
|
|
10600
11241
|
init_utils2();
|
|
10601
11242
|
init_webhooks();
|
|
@@ -10740,7 +11381,8 @@ function createMCPServer(config) {
|
|
|
10740
11381
|
integrations: updatedIntegrations,
|
|
10741
11382
|
getSessionContext: config.getSessionContext,
|
|
10742
11383
|
setProviderToken: config.setProviderToken,
|
|
10743
|
-
removeProviderToken: config.removeProviderToken
|
|
11384
|
+
removeProviderToken: config.removeProviderToken,
|
|
11385
|
+
codeMode: config.codeMode
|
|
10744
11386
|
};
|
|
10745
11387
|
client.__triggerConfig = config.triggers ? {
|
|
10746
11388
|
callbacks: config.triggers,
|
|
@@ -10810,8 +11452,21 @@ function createMCPServer(config) {
|
|
|
10810
11452
|
if (action === "mcp" && method === "POST") {
|
|
10811
11453
|
try {
|
|
10812
11454
|
const body = await webRequest.json();
|
|
10813
|
-
|
|
11455
|
+
let authHeader = webRequest.headers.get("authorization");
|
|
10814
11456
|
const integrationsHeader = webRequest.headers.get("x-integrations");
|
|
11457
|
+
if (!authHeader) {
|
|
11458
|
+
const tokensHeader = webRequest.headers.get("x-integrate-tokens");
|
|
11459
|
+
const toolName = typeof body?.name === "string" ? body.name : "";
|
|
11460
|
+
if (tokensHeader && toolName) {
|
|
11461
|
+
try {
|
|
11462
|
+
const tokens = JSON.parse(tokensHeader);
|
|
11463
|
+
const provider = toolName.split("_")[0];
|
|
11464
|
+
if (provider && tokens[provider]) {
|
|
11465
|
+
authHeader = `Bearer ${tokens[provider]}`;
|
|
11466
|
+
}
|
|
11467
|
+
} catch {}
|
|
11468
|
+
}
|
|
11469
|
+
}
|
|
10815
11470
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
10816
11471
|
const oauthHandler = new OAuthHandler2({
|
|
10817
11472
|
providers,
|
|
@@ -10832,6 +11487,53 @@ function createMCPServer(config) {
|
|
|
10832
11487
|
return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
|
|
10833
11488
|
}
|
|
10834
11489
|
}
|
|
11490
|
+
if (action === "code" && method === "POST") {
|
|
11491
|
+
try {
|
|
11492
|
+
const body = await webRequest.json();
|
|
11493
|
+
if (typeof body?.code !== "string" || body.code.length === 0) {
|
|
11494
|
+
return Response.json({ error: "`code` is required and must be a non-empty string." }, { status: 400 });
|
|
11495
|
+
}
|
|
11496
|
+
const { executeSandboxCode: executeSandboxCode2 } = await Promise.resolve().then(() => (init_executor(), exports_executor));
|
|
11497
|
+
const codeModeConfig = config.codeMode ?? {};
|
|
11498
|
+
const publicUrl = codeModeConfig.publicUrl ?? getEnv("INTEGRATE_PUBLIC_URL");
|
|
11499
|
+
if (!publicUrl) {
|
|
11500
|
+
return Response.json({
|
|
11501
|
+
error: "Code Mode requires `codeMode.publicUrl` in createMCPServer config (or the INTEGRATE_PUBLIC_URL env var). Set it to the public origin where /api/integrate/mcp is reachable."
|
|
11502
|
+
}, { status: 500 });
|
|
11503
|
+
}
|
|
11504
|
+
let contextOverride = body.context;
|
|
11505
|
+
if (!contextOverride && config.getSessionContext) {
|
|
11506
|
+
try {
|
|
11507
|
+
contextOverride = await config.getSessionContext(webRequest);
|
|
11508
|
+
} catch {}
|
|
11509
|
+
}
|
|
11510
|
+
let providerTokens = body.providerTokens;
|
|
11511
|
+
if (!providerTokens) {
|
|
11512
|
+
const headerTokens = webRequest.headers.get("x-integrate-tokens");
|
|
11513
|
+
if (headerTokens) {
|
|
11514
|
+
try {
|
|
11515
|
+
providerTokens = JSON.parse(headerTokens);
|
|
11516
|
+
} catch {}
|
|
11517
|
+
}
|
|
11518
|
+
}
|
|
11519
|
+
const integrationIds = updatedIntegrations.map((i) => i.id);
|
|
11520
|
+
const result = await executeSandboxCode2({
|
|
11521
|
+
code: body.code,
|
|
11522
|
+
mcpUrl: publicUrl.replace(/\/$/, "") + "/api/integrate/mcp",
|
|
11523
|
+
providerTokens,
|
|
11524
|
+
context: contextOverride,
|
|
11525
|
+
integrationsHeader: integrationIds.join(","),
|
|
11526
|
+
runtime: codeModeConfig.runtime,
|
|
11527
|
+
timeoutMs: codeModeConfig.timeoutMs,
|
|
11528
|
+
vcpus: codeModeConfig.vcpus,
|
|
11529
|
+
networkPolicy: codeModeConfig.networkPolicy
|
|
11530
|
+
});
|
|
11531
|
+
return Response.json(result, { status: result.success ? 200 : 500 });
|
|
11532
|
+
} catch (error) {
|
|
11533
|
+
logger32.error("[Code Mode] Error:", error);
|
|
11534
|
+
return Response.json({ error: error?.message || "Failed to execute code" }, { status: 500 });
|
|
11535
|
+
}
|
|
11536
|
+
}
|
|
10835
11537
|
if (action === "integrations" && method === "GET") {
|
|
10836
11538
|
const integrations = updatedIntegrations.map((integration) => ({
|
|
10837
11539
|
id: integration.id,
|
|
@@ -10867,7 +11569,7 @@ function createMCPServer(config) {
|
|
|
10867
11569
|
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
10868
11570
|
}
|
|
10869
11571
|
const triggerContext = trigger.userId ? { userId: trigger.userId } : undefined;
|
|
10870
|
-
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (
|
|
11572
|
+
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
|
|
10871
11573
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
10872
11574
|
const oauthHandler = new OAuthHandler2({
|
|
10873
11575
|
providers,
|
|
@@ -11030,7 +11732,7 @@ function createMCPServer(config) {
|
|
|
11030
11732
|
if (!trigger.provider) {
|
|
11031
11733
|
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
11032
11734
|
}
|
|
11033
|
-
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (
|
|
11735
|
+
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
|
|
11034
11736
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
11035
11737
|
const oauthHandler = new OAuthHandler2({
|
|
11036
11738
|
providers,
|
|
@@ -12106,6 +12808,10 @@ class OAuthHandler {
|
|
|
12106
12808
|
});
|
|
12107
12809
|
if (!response.ok) {
|
|
12108
12810
|
const error = await response.text();
|
|
12811
|
+
const lowerError = error.toLowerCase();
|
|
12812
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
12813
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
12814
|
+
}
|
|
12109
12815
|
throw new Error(`Token refresh failed: ${error}`);
|
|
12110
12816
|
}
|
|
12111
12817
|
const data = await response.json();
|
|
@@ -12228,7 +12934,11 @@ async function POST2(req, context) {
|
|
|
12228
12934
|
}
|
|
12229
12935
|
return createErrorResponse(`Unknown action: ${action}`, 404);
|
|
12230
12936
|
} catch (error) {
|
|
12231
|
-
|
|
12937
|
+
if (action === "refresh" && error.message?.toLowerCase().includes("not supported")) {
|
|
12938
|
+
logger34.info(`[OAuth ${action}] Not supported for this provider:`, error.message);
|
|
12939
|
+
} else {
|
|
12940
|
+
logger34.error(`[OAuth ${action}] Error:`, error);
|
|
12941
|
+
}
|
|
12232
12942
|
return createErrorResponse(error.message, 500);
|
|
12233
12943
|
}
|
|
12234
12944
|
}
|