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/index.js
CHANGED
|
@@ -416,10 +416,17 @@ var init_errors = __esm(() => {
|
|
|
416
416
|
function camelToSnake(str) {
|
|
417
417
|
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
418
418
|
}
|
|
419
|
+
function snakeToCamel(str) {
|
|
420
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
421
|
+
}
|
|
419
422
|
function methodToToolName(methodName, integrationId) {
|
|
420
423
|
const snakeCaseMethod = camelToSnake(methodName);
|
|
421
424
|
return `${integrationId}_${snakeCaseMethod}`;
|
|
422
425
|
}
|
|
426
|
+
function toolNameToMethod(toolName) {
|
|
427
|
+
const withoutPrefix = toolName.replace(/^[^_]+_/, "");
|
|
428
|
+
return snakeToCamel(withoutPrefix);
|
|
429
|
+
}
|
|
423
430
|
|
|
424
431
|
// src/triggers/client.ts
|
|
425
432
|
class TriggerClient {
|
|
@@ -2826,7 +2833,11 @@ function createNextOAuthHandler(config) {
|
|
|
2826
2833
|
}
|
|
2827
2834
|
return response;
|
|
2828
2835
|
} catch (error) {
|
|
2829
|
-
|
|
2836
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
2837
|
+
logger6.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
2838
|
+
} else {
|
|
2839
|
+
logger6.error("[OAuth Refresh] Error:", error);
|
|
2840
|
+
}
|
|
2830
2841
|
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
2831
2842
|
}
|
|
2832
2843
|
},
|
|
@@ -8719,6 +8730,508 @@ var init_trigger_tools = __esm(() => {
|
|
|
8719
8730
|
init_utils2();
|
|
8720
8731
|
});
|
|
8721
8732
|
|
|
8733
|
+
// src/code-mode/type-generator.ts
|
|
8734
|
+
function safeIdent(name) {
|
|
8735
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) || RESERVED_TS.has(name)) {
|
|
8736
|
+
return JSON.stringify(name);
|
|
8737
|
+
}
|
|
8738
|
+
return name;
|
|
8739
|
+
}
|
|
8740
|
+
function integrationFromToolName(toolName) {
|
|
8741
|
+
const idx = toolName.indexOf("_");
|
|
8742
|
+
return idx === -1 ? toolName : toolName.slice(0, idx);
|
|
8743
|
+
}
|
|
8744
|
+
function jsonSchemaToTs(schema, indent) {
|
|
8745
|
+
if (!schema || typeof schema !== "object")
|
|
8746
|
+
return "unknown";
|
|
8747
|
+
const s = schema;
|
|
8748
|
+
if (Array.isArray(s.enum) && s.enum.length > 0) {
|
|
8749
|
+
return s.enum.map((v) => typeof v === "string" ? JSON.stringify(v) : typeof v === "number" || typeof v === "boolean" ? String(v) : "unknown").join(" | ");
|
|
8750
|
+
}
|
|
8751
|
+
if (Array.isArray(s.type)) {
|
|
8752
|
+
return s.type.map((t2) => jsonSchemaToTs({ ...s, type: t2 }, indent)).join(" | ");
|
|
8753
|
+
}
|
|
8754
|
+
const t = s.type;
|
|
8755
|
+
switch (t) {
|
|
8756
|
+
case "string":
|
|
8757
|
+
return "string";
|
|
8758
|
+
case "number":
|
|
8759
|
+
case "integer":
|
|
8760
|
+
return "number";
|
|
8761
|
+
case "boolean":
|
|
8762
|
+
return "boolean";
|
|
8763
|
+
case "null":
|
|
8764
|
+
return "null";
|
|
8765
|
+
case "array": {
|
|
8766
|
+
const items = s.items;
|
|
8767
|
+
if (Array.isArray(items))
|
|
8768
|
+
return "unknown[]";
|
|
8769
|
+
const inner = jsonSchemaToTs(items, indent);
|
|
8770
|
+
return /[|&]/.test(inner) ? `Array<${inner}>` : `${inner}[]`;
|
|
8771
|
+
}
|
|
8772
|
+
case "object":
|
|
8773
|
+
return objectShape(s, indent);
|
|
8774
|
+
default:
|
|
8775
|
+
if (s.properties && typeof s.properties === "object")
|
|
8776
|
+
return objectShape(s, indent);
|
|
8777
|
+
return "unknown";
|
|
8778
|
+
}
|
|
8779
|
+
}
|
|
8780
|
+
function objectShape(schema, indent) {
|
|
8781
|
+
const props = schema.properties && typeof schema.properties === "object" ? schema.properties : {};
|
|
8782
|
+
const keys = Object.keys(props);
|
|
8783
|
+
if (keys.length === 0) {
|
|
8784
|
+
return schema.additionalProperties === false ? "Record<string, never>" : "Record<string, unknown>";
|
|
8785
|
+
}
|
|
8786
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
8787
|
+
const inner = indent + " ";
|
|
8788
|
+
const lines = ["{"];
|
|
8789
|
+
for (const key of keys) {
|
|
8790
|
+
const prop = props[key];
|
|
8791
|
+
const desc = prop && typeof prop.description === "string" ? prop.description : undefined;
|
|
8792
|
+
if (desc)
|
|
8793
|
+
lines.push(`${inner}/** ${desc.replace(/\*\//g, "*\\/")} */`);
|
|
8794
|
+
const optional = required.has(key) ? "" : "?";
|
|
8795
|
+
const type = jsonSchemaToTs(prop, inner);
|
|
8796
|
+
lines.push(`${inner}${safeIdent(key)}${optional}: ${type};`);
|
|
8797
|
+
}
|
|
8798
|
+
lines.push(`${indent}}`);
|
|
8799
|
+
return lines.join(`
|
|
8800
|
+
`);
|
|
8801
|
+
}
|
|
8802
|
+
function argsType(schema) {
|
|
8803
|
+
if (!schema)
|
|
8804
|
+
return "Record<string, unknown>";
|
|
8805
|
+
const hasProps = schema.properties && Object.keys(schema.properties).length > 0;
|
|
8806
|
+
if (!hasProps)
|
|
8807
|
+
return "Record<string, unknown>";
|
|
8808
|
+
return objectShape(schema, " ");
|
|
8809
|
+
}
|
|
8810
|
+
function methodHasRequiredArgs(schema) {
|
|
8811
|
+
if (!schema || !schema.properties)
|
|
8812
|
+
return false;
|
|
8813
|
+
const req = Array.isArray(schema.required) ? schema.required : [];
|
|
8814
|
+
return req.length > 0;
|
|
8815
|
+
}
|
|
8816
|
+
function formatDescription(desc, indent) {
|
|
8817
|
+
if (!desc)
|
|
8818
|
+
return "";
|
|
8819
|
+
const cleaned = desc.replace(/\*\//g, "*\\/").trim();
|
|
8820
|
+
if (!cleaned.includes(`
|
|
8821
|
+
`))
|
|
8822
|
+
return `${indent}/** ${cleaned} */
|
|
8823
|
+
`;
|
|
8824
|
+
const lines = cleaned.split(`
|
|
8825
|
+
`).map((l) => `${indent} * ${l}`).join(`
|
|
8826
|
+
`);
|
|
8827
|
+
return `${indent}/**
|
|
8828
|
+
${lines}
|
|
8829
|
+
${indent} */
|
|
8830
|
+
`;
|
|
8831
|
+
}
|
|
8832
|
+
function generateCodeModeTypes(tools) {
|
|
8833
|
+
const byIntegration = {};
|
|
8834
|
+
for (const tool of tools) {
|
|
8835
|
+
const integration = integrationFromToolName(tool.name);
|
|
8836
|
+
(byIntegration[integration] ??= []).push(tool);
|
|
8837
|
+
}
|
|
8838
|
+
const methodMap = {};
|
|
8839
|
+
const integrationCounts = {};
|
|
8840
|
+
const sections = [];
|
|
8841
|
+
const integrationIds = Object.keys(byIntegration).sort();
|
|
8842
|
+
sections.push("/**");
|
|
8843
|
+
sections.push(" * Integrate SDK — available APIs inside `execute_code`.");
|
|
8844
|
+
sections.push(" * Every method is async and returns the MCP tool-call response.");
|
|
8845
|
+
sections.push(" * Call them via the exported `client` object, e.g.");
|
|
8846
|
+
sections.push(" * const repos = await client.github.listRepos();");
|
|
8847
|
+
sections.push(" */");
|
|
8848
|
+
sections.push("");
|
|
8849
|
+
for (const integrationId of integrationIds) {
|
|
8850
|
+
const integrationTools = byIntegration[integrationId].slice().sort((a, b) => a.name.localeCompare(b.name));
|
|
8851
|
+
integrationCounts[integrationId] = integrationTools.length;
|
|
8852
|
+
const interfaceName = pascalCase(integrationId) + "Client";
|
|
8853
|
+
sections.push(`export interface ${interfaceName} {`);
|
|
8854
|
+
for (const tool of integrationTools) {
|
|
8855
|
+
const methodName = toolNameToMethod(tool.name);
|
|
8856
|
+
methodMap[`${integrationId}.${methodName}`] = tool.name;
|
|
8857
|
+
sections.push(formatDescription(tool.description, " "));
|
|
8858
|
+
const argType = argsType(tool.inputSchema);
|
|
8859
|
+
const argIsOptional = !methodHasRequiredArgs(tool.inputSchema);
|
|
8860
|
+
const paramName = argIsOptional ? "args?" : "args";
|
|
8861
|
+
sections.push(` ${safeIdent(methodName)}(${paramName}: ${argType}): Promise<ToolResult>;`);
|
|
8862
|
+
}
|
|
8863
|
+
sections.push("}");
|
|
8864
|
+
sections.push("");
|
|
8865
|
+
}
|
|
8866
|
+
sections.push("export interface ToolResult {");
|
|
8867
|
+
sections.push(" content: Array<{ type: 'text' | 'image' | 'resource'; text?: string; data?: string; mimeType?: string; [key: string]: unknown }>;");
|
|
8868
|
+
sections.push(" isError?: boolean;");
|
|
8869
|
+
sections.push(" structuredContent?: Record<string, unknown>;");
|
|
8870
|
+
sections.push("}");
|
|
8871
|
+
sections.push("");
|
|
8872
|
+
sections.push("export interface Client {");
|
|
8873
|
+
for (const integrationId of integrationIds) {
|
|
8874
|
+
const interfaceName = pascalCase(integrationId) + "Client";
|
|
8875
|
+
sections.push(` ${safeIdent(integrationId)}: ${interfaceName};`);
|
|
8876
|
+
}
|
|
8877
|
+
sections.push("}");
|
|
8878
|
+
sections.push("");
|
|
8879
|
+
sections.push("export declare const client: Client;");
|
|
8880
|
+
return {
|
|
8881
|
+
source: sections.filter((line, idx, arr) => !(line === "" && arr[idx - 1] === "")).join(`
|
|
8882
|
+
`),
|
|
8883
|
+
methodMap,
|
|
8884
|
+
integrationCounts
|
|
8885
|
+
};
|
|
8886
|
+
}
|
|
8887
|
+
function pascalCase(id) {
|
|
8888
|
+
return id.split(/[^A-Za-z0-9]/).filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("") || "Unknown";
|
|
8889
|
+
}
|
|
8890
|
+
var RESERVED_TS;
|
|
8891
|
+
var init_type_generator = __esm(() => {
|
|
8892
|
+
RESERVED_TS = new Set([
|
|
8893
|
+
"break",
|
|
8894
|
+
"case",
|
|
8895
|
+
"catch",
|
|
8896
|
+
"class",
|
|
8897
|
+
"const",
|
|
8898
|
+
"continue",
|
|
8899
|
+
"debugger",
|
|
8900
|
+
"default",
|
|
8901
|
+
"delete",
|
|
8902
|
+
"do",
|
|
8903
|
+
"else",
|
|
8904
|
+
"enum",
|
|
8905
|
+
"export",
|
|
8906
|
+
"extends",
|
|
8907
|
+
"false",
|
|
8908
|
+
"finally",
|
|
8909
|
+
"for",
|
|
8910
|
+
"function",
|
|
8911
|
+
"if",
|
|
8912
|
+
"import",
|
|
8913
|
+
"in",
|
|
8914
|
+
"instanceof",
|
|
8915
|
+
"new",
|
|
8916
|
+
"null",
|
|
8917
|
+
"return",
|
|
8918
|
+
"super",
|
|
8919
|
+
"switch",
|
|
8920
|
+
"this",
|
|
8921
|
+
"throw",
|
|
8922
|
+
"true",
|
|
8923
|
+
"try",
|
|
8924
|
+
"typeof",
|
|
8925
|
+
"var",
|
|
8926
|
+
"void",
|
|
8927
|
+
"while",
|
|
8928
|
+
"with",
|
|
8929
|
+
"as",
|
|
8930
|
+
"implements",
|
|
8931
|
+
"interface",
|
|
8932
|
+
"let",
|
|
8933
|
+
"package",
|
|
8934
|
+
"private",
|
|
8935
|
+
"protected",
|
|
8936
|
+
"public",
|
|
8937
|
+
"static",
|
|
8938
|
+
"yield"
|
|
8939
|
+
]);
|
|
8940
|
+
});
|
|
8941
|
+
|
|
8942
|
+
// src/code-mode/runtime-stub.ts
|
|
8943
|
+
var RUNTIME_STUB_SOURCE = `// runtime.mjs — generated by integrate-sdk code mode
|
|
8944
|
+
const MCP_URL = process.env.INTEGRATE_MCP_URL;
|
|
8945
|
+
const SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;
|
|
8946
|
+
const PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';
|
|
8947
|
+
const INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';
|
|
8948
|
+
const CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';
|
|
8949
|
+
|
|
8950
|
+
if (!MCP_URL) {
|
|
8951
|
+
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
8952
|
+
}
|
|
8953
|
+
|
|
8954
|
+
function camelToSnake(str) {
|
|
8955
|
+
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
8956
|
+
}
|
|
8957
|
+
|
|
8958
|
+
async function callTool(toolName, args) {
|
|
8959
|
+
const headers = {
|
|
8960
|
+
'Content-Type': 'application/json',
|
|
8961
|
+
'x-integrate-code-mode': '1',
|
|
8962
|
+
};
|
|
8963
|
+
if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;
|
|
8964
|
+
if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;
|
|
8965
|
+
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
8966
|
+
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
8967
|
+
|
|
8968
|
+
const res = await fetch(MCP_URL, {
|
|
8969
|
+
method: 'POST',
|
|
8970
|
+
headers,
|
|
8971
|
+
body: JSON.stringify({ name: toolName, arguments: args || {} }),
|
|
8972
|
+
});
|
|
8973
|
+
|
|
8974
|
+
const text = await res.text();
|
|
8975
|
+
let payload;
|
|
8976
|
+
try {
|
|
8977
|
+
payload = text ? JSON.parse(text) : null;
|
|
8978
|
+
} catch {
|
|
8979
|
+
payload = { content: [{ type: 'text', text }] };
|
|
8980
|
+
}
|
|
8981
|
+
|
|
8982
|
+
if (!res.ok) {
|
|
8983
|
+
const message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;
|
|
8984
|
+
const err = new Error(message);
|
|
8985
|
+
err.status = res.status;
|
|
8986
|
+
err.toolName = toolName;
|
|
8987
|
+
throw err;
|
|
8988
|
+
}
|
|
8989
|
+
|
|
8990
|
+
return payload;
|
|
8991
|
+
}
|
|
8992
|
+
|
|
8993
|
+
function createIntegrationProxy(integrationId) {
|
|
8994
|
+
return new Proxy({}, {
|
|
8995
|
+
get(_target, methodName) {
|
|
8996
|
+
if (typeof methodName !== 'string') return undefined;
|
|
8997
|
+
return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);
|
|
8998
|
+
},
|
|
8999
|
+
});
|
|
9000
|
+
}
|
|
9001
|
+
|
|
9002
|
+
export const client = new Proxy({}, {
|
|
9003
|
+
get(_target, integrationId) {
|
|
9004
|
+
if (typeof integrationId !== 'string') return undefined;
|
|
9005
|
+
return createIntegrationProxy(integrationId);
|
|
9006
|
+
},
|
|
9007
|
+
});
|
|
9008
|
+
|
|
9009
|
+
export { callTool };
|
|
9010
|
+
`;
|
|
9011
|
+
|
|
9012
|
+
// src/code-mode/executor.ts
|
|
9013
|
+
var exports_executor = {};
|
|
9014
|
+
__export(exports_executor, {
|
|
9015
|
+
executeSandboxCode: () => executeSandboxCode,
|
|
9016
|
+
__setSandboxFactoryForTests: () => __setSandboxFactoryForTests
|
|
9017
|
+
});
|
|
9018
|
+
function __setSandboxFactoryForTests(factory) {
|
|
9019
|
+
sandboxFactoryOverride = factory;
|
|
9020
|
+
}
|
|
9021
|
+
async function loadSandboxFactory() {
|
|
9022
|
+
if (sandboxFactoryOverride)
|
|
9023
|
+
return sandboxFactoryOverride;
|
|
9024
|
+
try {
|
|
9025
|
+
const dynamicImport = new Function("specifier", "return import(specifier)");
|
|
9026
|
+
const pkg = "@" + "vercel/sandbox";
|
|
9027
|
+
const mod = await dynamicImport(pkg);
|
|
9028
|
+
return mod.Sandbox ?? mod.default?.Sandbox ?? mod;
|
|
9029
|
+
} catch (err) {
|
|
9030
|
+
throw new Error("Code Mode requires the optional peer dependency `@vercel/sandbox`. " + "Install it with `npm install @vercel/sandbox` (or `bun add @vercel/sandbox`).");
|
|
9031
|
+
}
|
|
9032
|
+
}
|
|
9033
|
+
function wrapUserCode(code) {
|
|
9034
|
+
return `// user.mjs — wrapped by integrate-sdk code mode
|
|
9035
|
+
import { client, callTool } from './runtime.mjs';
|
|
9036
|
+
|
|
9037
|
+
(async () => {
|
|
9038
|
+
try {
|
|
9039
|
+
const __result = await (async () => {
|
|
9040
|
+
${code}
|
|
9041
|
+
})();
|
|
9042
|
+
if (typeof __result !== 'undefined') {
|
|
9043
|
+
process.stdout.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify(__result) + '\\n');
|
|
9044
|
+
}
|
|
9045
|
+
} catch (err) {
|
|
9046
|
+
const payload = {
|
|
9047
|
+
message: err && err.message ? err.message : String(err),
|
|
9048
|
+
name: err && err.name,
|
|
9049
|
+
stack: err && err.stack,
|
|
9050
|
+
toolName: err && err.toolName,
|
|
9051
|
+
status: err && err.status,
|
|
9052
|
+
};
|
|
9053
|
+
process.stderr.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify({ error: payload }) + '\\n');
|
|
9054
|
+
process.exit(1);
|
|
9055
|
+
}
|
|
9056
|
+
})();
|
|
9057
|
+
`;
|
|
9058
|
+
}
|
|
9059
|
+
function defaultNetworkPolicy(mcpUrl) {
|
|
9060
|
+
try {
|
|
9061
|
+
const host = new URL(mcpUrl).hostname;
|
|
9062
|
+
return { allow: [host] };
|
|
9063
|
+
} catch {
|
|
9064
|
+
return { allow: [] };
|
|
9065
|
+
}
|
|
9066
|
+
}
|
|
9067
|
+
function extractResult(stream) {
|
|
9068
|
+
const idx = stream.lastIndexOf(RESULT_SENTINEL);
|
|
9069
|
+
if (idx === -1)
|
|
9070
|
+
return { cleaned: stream };
|
|
9071
|
+
const before = stream.slice(0, idx).replace(/\n$/, "");
|
|
9072
|
+
const rest = stream.slice(idx + RESULT_SENTINEL.length);
|
|
9073
|
+
const newlineIdx = rest.indexOf(`
|
|
9074
|
+
`);
|
|
9075
|
+
const payload = newlineIdx === -1 ? rest : rest.slice(0, newlineIdx);
|
|
9076
|
+
const after = newlineIdx === -1 ? "" : rest.slice(newlineIdx + 1);
|
|
9077
|
+
try {
|
|
9078
|
+
return { cleaned: (before + after).trimEnd(), result: JSON.parse(payload) };
|
|
9079
|
+
} catch {
|
|
9080
|
+
return { cleaned: stream };
|
|
9081
|
+
}
|
|
9082
|
+
}
|
|
9083
|
+
async function executeSandboxCode(options) {
|
|
9084
|
+
const startedAt = Date.now();
|
|
9085
|
+
const runtime = options.runtime ?? "node22";
|
|
9086
|
+
const timeoutMs = options.timeoutMs ?? 60000;
|
|
9087
|
+
const networkPolicy = options.networkPolicy ?? defaultNetworkPolicy(options.mcpUrl);
|
|
9088
|
+
let sandbox = null;
|
|
9089
|
+
try {
|
|
9090
|
+
const Sandbox = await loadSandboxFactory();
|
|
9091
|
+
sandbox = await Sandbox.create({
|
|
9092
|
+
runtime,
|
|
9093
|
+
timeout: timeoutMs,
|
|
9094
|
+
resources: options.vcpus ? { vcpus: options.vcpus } : undefined,
|
|
9095
|
+
networkPolicy
|
|
9096
|
+
});
|
|
9097
|
+
const runtimeContent = Buffer.from(RUNTIME_STUB_SOURCE, "utf-8");
|
|
9098
|
+
const userContent = Buffer.from(wrapUserCode(options.code), "utf-8");
|
|
9099
|
+
await sandbox.writeFiles([
|
|
9100
|
+
{ path: "runtime.mjs", content: runtimeContent },
|
|
9101
|
+
{ path: "user.mjs", content: userContent }
|
|
9102
|
+
]);
|
|
9103
|
+
const env = {
|
|
9104
|
+
INTEGRATE_MCP_URL: options.mcpUrl
|
|
9105
|
+
};
|
|
9106
|
+
if (options.sessionToken)
|
|
9107
|
+
env.INTEGRATE_SESSION_TOKEN = options.sessionToken;
|
|
9108
|
+
if (options.providerTokens && Object.keys(options.providerTokens).length > 0) {
|
|
9109
|
+
env.INTEGRATE_PROVIDER_TOKENS = JSON.stringify(options.providerTokens);
|
|
9110
|
+
}
|
|
9111
|
+
if (options.integrationsHeader)
|
|
9112
|
+
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
9113
|
+
if (options.context)
|
|
9114
|
+
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
9115
|
+
const cmd = await sandbox.runCommand({
|
|
9116
|
+
cmd: "node",
|
|
9117
|
+
args: ["user.mjs"],
|
|
9118
|
+
env
|
|
9119
|
+
});
|
|
9120
|
+
const [stdoutRaw, stderrRaw] = await Promise.all([cmd.stdout(), cmd.stderr()]);
|
|
9121
|
+
const stdoutExtract = extractResult(stdoutRaw);
|
|
9122
|
+
const stderrExtract = extractResult(stderrRaw);
|
|
9123
|
+
return {
|
|
9124
|
+
success: cmd.exitCode === 0,
|
|
9125
|
+
exitCode: cmd.exitCode,
|
|
9126
|
+
result: stdoutExtract.result ?? stderrExtract.result,
|
|
9127
|
+
stdout: stdoutExtract.cleaned,
|
|
9128
|
+
stderr: stderrExtract.cleaned,
|
|
9129
|
+
durationMs: Date.now() - startedAt
|
|
9130
|
+
};
|
|
9131
|
+
} catch (err) {
|
|
9132
|
+
return {
|
|
9133
|
+
success: false,
|
|
9134
|
+
exitCode: -1,
|
|
9135
|
+
stdout: "",
|
|
9136
|
+
stderr: "",
|
|
9137
|
+
durationMs: Date.now() - startedAt,
|
|
9138
|
+
error: err instanceof Error ? err.message : String(err)
|
|
9139
|
+
};
|
|
9140
|
+
} finally {
|
|
9141
|
+
if (sandbox) {
|
|
9142
|
+
try {
|
|
9143
|
+
await sandbox.stop();
|
|
9144
|
+
} catch {}
|
|
9145
|
+
}
|
|
9146
|
+
}
|
|
9147
|
+
}
|
|
9148
|
+
var sandboxFactoryOverride = null, RESULT_SENTINEL = "__INTEGRATE_RESULT__";
|
|
9149
|
+
var init_executor = () => {};
|
|
9150
|
+
|
|
9151
|
+
// src/code-mode/tool-builder.ts
|
|
9152
|
+
function resolveCodeModeClientConfig(client) {
|
|
9153
|
+
const oauthConfig = client.__oauthConfig;
|
|
9154
|
+
return oauthConfig?.codeMode ?? {};
|
|
9155
|
+
}
|
|
9156
|
+
function buildCodeModeTool(client, options) {
|
|
9157
|
+
const { tools, providerTokens, context, integrationIds } = options;
|
|
9158
|
+
const generated = generateCodeModeTypes(tools);
|
|
9159
|
+
const serverCodeModeConfig = resolveCodeModeClientConfig(client);
|
|
9160
|
+
const sandboxOverrides = options.sandbox ?? {};
|
|
9161
|
+
const description = `${DEFAULT_INSTRUCTIONS}
|
|
9162
|
+
|
|
9163
|
+
\`\`\`typescript
|
|
9164
|
+
${generated.source}
|
|
9165
|
+
\`\`\``;
|
|
9166
|
+
const execute = async ({ code }) => {
|
|
9167
|
+
const publicUrl = sandboxOverrides.publicUrl ?? serverCodeModeConfig.publicUrl ?? getEnv("INTEGRATE_PUBLIC_URL");
|
|
9168
|
+
if (!publicUrl) {
|
|
9169
|
+
return {
|
|
9170
|
+
success: false,
|
|
9171
|
+
exitCode: -1,
|
|
9172
|
+
stdout: "",
|
|
9173
|
+
stderr: "",
|
|
9174
|
+
durationMs: 0,
|
|
9175
|
+
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."
|
|
9176
|
+
};
|
|
9177
|
+
}
|
|
9178
|
+
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
9179
|
+
return executeSandboxCode({
|
|
9180
|
+
code,
|
|
9181
|
+
mcpUrl,
|
|
9182
|
+
providerTokens,
|
|
9183
|
+
context,
|
|
9184
|
+
integrationsHeader: integrationIds && integrationIds.length > 0 ? integrationIds.join(",") : undefined,
|
|
9185
|
+
runtime: sandboxOverrides.runtime ?? serverCodeModeConfig.runtime,
|
|
9186
|
+
timeoutMs: sandboxOverrides.timeoutMs ?? serverCodeModeConfig.timeoutMs,
|
|
9187
|
+
vcpus: sandboxOverrides.vcpus ?? serverCodeModeConfig.vcpus,
|
|
9188
|
+
networkPolicy: sandboxOverrides.networkPolicy ?? serverCodeModeConfig.networkPolicy
|
|
9189
|
+
});
|
|
9190
|
+
};
|
|
9191
|
+
return {
|
|
9192
|
+
name: CODE_MODE_TOOL_NAME,
|
|
9193
|
+
description,
|
|
9194
|
+
parameters: {
|
|
9195
|
+
type: "object",
|
|
9196
|
+
properties: {
|
|
9197
|
+
code: {
|
|
9198
|
+
type: "string",
|
|
9199
|
+
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."
|
|
9200
|
+
}
|
|
9201
|
+
},
|
|
9202
|
+
required: ["code"],
|
|
9203
|
+
additionalProperties: false
|
|
9204
|
+
},
|
|
9205
|
+
execute
|
|
9206
|
+
};
|
|
9207
|
+
}
|
|
9208
|
+
var CODE_MODE_TOOL_NAME = "execute_code", DEFAULT_INSTRUCTIONS;
|
|
9209
|
+
var init_tool_builder = __esm(() => {
|
|
9210
|
+
init_type_generator();
|
|
9211
|
+
init_executor();
|
|
9212
|
+
DEFAULT_INSTRUCTIONS = [
|
|
9213
|
+
"You are given a single tool: `execute_code`. Instead of calling individual MCP tools,",
|
|
9214
|
+
"you write a short async TypeScript/JavaScript snippet that uses the typed `client`",
|
|
9215
|
+
"object below, and the snippet runs in an isolated sandbox which dispatches the actual",
|
|
9216
|
+
"tool calls. Chain multiple operations together in one snippet whenever possible —",
|
|
9217
|
+
"that is the whole point of this tool.",
|
|
9218
|
+
"",
|
|
9219
|
+
"Rules:",
|
|
9220
|
+
"- The snippet is the body of an `async` function. Use `await` freely.",
|
|
9221
|
+
"- Use `return <value>` at the end to hand a structured result back to the caller;",
|
|
9222
|
+
" the caller receives it as JSON.",
|
|
9223
|
+
"- Use `console.log(...)` for intermediate observations you want to read later.",
|
|
9224
|
+
"- Throw / let errors propagate; the runtime will surface them with a non-zero exit.",
|
|
9225
|
+
"- Each method call returns an object of shape `ToolResult` (see types below).",
|
|
9226
|
+
" The payload usually lives in `result.content[0].text` as JSON — parse it if needed.",
|
|
9227
|
+
"- You cannot import npm packages. Only the pre-imported `client` and standard",
|
|
9228
|
+
" globals (`fetch`, `console`, `JSON`, ...) are available.",
|
|
9229
|
+
"",
|
|
9230
|
+
"API surface:"
|
|
9231
|
+
].join(`
|
|
9232
|
+
`);
|
|
9233
|
+
});
|
|
9234
|
+
|
|
8722
9235
|
// src/ai/vercel-ai.ts
|
|
8723
9236
|
function convertMCPToolToVercelAI(mcpTool, client, options) {
|
|
8724
9237
|
return {
|
|
@@ -8743,8 +9256,25 @@ async function getVercelAITools(client, options) {
|
|
|
8743
9256
|
await ensureClientConnected(client);
|
|
8744
9257
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
8745
9258
|
const vercelTools = {};
|
|
8746
|
-
|
|
8747
|
-
|
|
9259
|
+
const mode = options?.mode ?? "code";
|
|
9260
|
+
if (mode === "code") {
|
|
9261
|
+
const codeTool = buildCodeModeTool(client, {
|
|
9262
|
+
tools: mcpTools,
|
|
9263
|
+
providerTokens,
|
|
9264
|
+
context: options?.context,
|
|
9265
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id) ?? client.integrations?.map?.((i) => i.id)
|
|
9266
|
+
});
|
|
9267
|
+
vercelTools[CODE_MODE_TOOL_NAME] = {
|
|
9268
|
+
description: codeTool.description,
|
|
9269
|
+
inputSchema: exports_external.object({
|
|
9270
|
+
code: exports_external.string().describe(codeTool.parameters.properties.code.description)
|
|
9271
|
+
}),
|
|
9272
|
+
execute: async (args) => codeTool.execute(args)
|
|
9273
|
+
};
|
|
9274
|
+
} else {
|
|
9275
|
+
for (const mcpTool of mcpTools) {
|
|
9276
|
+
vercelTools[mcpTool.name] = convertMCPToolToVercelAI(mcpTool, client, finalOptions);
|
|
9277
|
+
}
|
|
8748
9278
|
}
|
|
8749
9279
|
const triggerConfig = client.__triggerConfig;
|
|
8750
9280
|
if (triggerConfig) {
|
|
@@ -8754,8 +9284,10 @@ async function getVercelAITools(client, options) {
|
|
|
8754
9284
|
return vercelTools;
|
|
8755
9285
|
}
|
|
8756
9286
|
var init_vercel_ai = __esm(() => {
|
|
9287
|
+
init_zod();
|
|
8757
9288
|
init_utils();
|
|
8758
9289
|
init_trigger_tools();
|
|
9290
|
+
init_tool_builder();
|
|
8759
9291
|
});
|
|
8760
9292
|
|
|
8761
9293
|
// node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
@@ -10183,7 +10715,22 @@ async function getOpenAITools(client, options) {
|
|
|
10183
10715
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10184
10716
|
await ensureClientConnected(client);
|
|
10185
10717
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10186
|
-
const
|
|
10718
|
+
const mode = options?.mode ?? "code";
|
|
10719
|
+
const openaiTools = mode === "code" ? (() => {
|
|
10720
|
+
const codeTool = buildCodeModeTool(client, {
|
|
10721
|
+
tools: mcpTools,
|
|
10722
|
+
providerTokens,
|
|
10723
|
+
context: options?.context,
|
|
10724
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10725
|
+
});
|
|
10726
|
+
return [{
|
|
10727
|
+
type: "function",
|
|
10728
|
+
name: CODE_MODE_TOOL_NAME,
|
|
10729
|
+
description: codeTool.description,
|
|
10730
|
+
parameters: codeTool.parameters,
|
|
10731
|
+
strict: options?.strict ?? null
|
|
10732
|
+
}];
|
|
10733
|
+
})() : mcpTools.map((mcpTool) => convertMCPToolToOpenAI(mcpTool, client, finalOptions));
|
|
10187
10734
|
const triggerConfig = client.__triggerConfig;
|
|
10188
10735
|
if (triggerConfig) {
|
|
10189
10736
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10208,6 +10755,19 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
|
|
|
10208
10755
|
const toolOutputs = [];
|
|
10209
10756
|
const triggerConfig = client.__triggerConfig;
|
|
10210
10757
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
10758
|
+
let cachedCodeModeTool = null;
|
|
10759
|
+
const getCodeModeTool = async () => {
|
|
10760
|
+
if (cachedCodeModeTool)
|
|
10761
|
+
return cachedCodeModeTool;
|
|
10762
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
10763
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
10764
|
+
tools: mcpTools,
|
|
10765
|
+
providerTokens: options?.providerTokens,
|
|
10766
|
+
context: options?.context,
|
|
10767
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10768
|
+
});
|
|
10769
|
+
return cachedCodeModeTool;
|
|
10770
|
+
};
|
|
10211
10771
|
for (const output of toolCalls) {
|
|
10212
10772
|
if (output.type === "function_call") {
|
|
10213
10773
|
const toolCall = {
|
|
@@ -10218,7 +10778,10 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
|
|
|
10218
10778
|
try {
|
|
10219
10779
|
const args = JSON.parse(toolCall.arguments);
|
|
10220
10780
|
let result;
|
|
10221
|
-
if (
|
|
10781
|
+
if (toolCall.name === CODE_MODE_TOOL_NAME) {
|
|
10782
|
+
const codeTool = await getCodeModeTool();
|
|
10783
|
+
result = await codeTool.execute(args);
|
|
10784
|
+
} else if (triggerTools && triggerTools[toolCall.name]) {
|
|
10222
10785
|
result = await triggerTools[toolCall.name].execute(args);
|
|
10223
10786
|
} else {
|
|
10224
10787
|
result = await executeToolWithToken(client, toolCall.name, args, options);
|
|
@@ -10259,6 +10822,7 @@ async function handleOpenAIResponse(client, response, options) {
|
|
|
10259
10822
|
var init_openai = __esm(() => {
|
|
10260
10823
|
init_utils();
|
|
10261
10824
|
init_trigger_tools();
|
|
10825
|
+
init_tool_builder();
|
|
10262
10826
|
init_esm();
|
|
10263
10827
|
});
|
|
10264
10828
|
|
|
@@ -10278,11 +10842,27 @@ async function handleAnthropicToolCalls(client, messageContent, options) {
|
|
|
10278
10842
|
const toolResults = [];
|
|
10279
10843
|
const triggerConfig = client.__triggerConfig;
|
|
10280
10844
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
10845
|
+
let cachedCodeModeTool = null;
|
|
10846
|
+
const getCodeModeTool = async () => {
|
|
10847
|
+
if (cachedCodeModeTool)
|
|
10848
|
+
return cachedCodeModeTool;
|
|
10849
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
10850
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
10851
|
+
tools: mcpTools,
|
|
10852
|
+
providerTokens: options?.providerTokens,
|
|
10853
|
+
context: options?.context,
|
|
10854
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10855
|
+
});
|
|
10856
|
+
return cachedCodeModeTool;
|
|
10857
|
+
};
|
|
10281
10858
|
const toolUseBlocks = messageContent.filter((block) => block.type === "tool_use" && ("id" in block) && ("name" in block) && ("input" in block));
|
|
10282
10859
|
for (const toolUse of toolUseBlocks) {
|
|
10283
10860
|
try {
|
|
10284
10861
|
let result;
|
|
10285
|
-
if (
|
|
10862
|
+
if (toolUse.name === CODE_MODE_TOOL_NAME) {
|
|
10863
|
+
const codeTool = await getCodeModeTool();
|
|
10864
|
+
result = await codeTool.execute(toolUse.input);
|
|
10865
|
+
} else if (triggerTools && triggerTools[toolUse.name]) {
|
|
10286
10866
|
result = await triggerTools[toolUse.name].execute(toolUse.input);
|
|
10287
10867
|
} else {
|
|
10288
10868
|
result = await executeToolWithToken(client, toolUse.name, toolUse.input, options);
|
|
@@ -10315,7 +10895,24 @@ async function getAnthropicTools(client, options) {
|
|
|
10315
10895
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10316
10896
|
await ensureClientConnected(client);
|
|
10317
10897
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10318
|
-
const
|
|
10898
|
+
const mode = options?.mode ?? "code";
|
|
10899
|
+
const anthropicTools = mode === "code" ? (() => {
|
|
10900
|
+
const codeTool = buildCodeModeTool(client, {
|
|
10901
|
+
tools: mcpTools,
|
|
10902
|
+
providerTokens,
|
|
10903
|
+
context: options?.context,
|
|
10904
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
10905
|
+
});
|
|
10906
|
+
return [{
|
|
10907
|
+
name: CODE_MODE_TOOL_NAME,
|
|
10908
|
+
description: codeTool.description,
|
|
10909
|
+
input_schema: {
|
|
10910
|
+
type: "object",
|
|
10911
|
+
properties: codeTool.parameters.properties,
|
|
10912
|
+
required: [...codeTool.parameters.required]
|
|
10913
|
+
}
|
|
10914
|
+
}];
|
|
10915
|
+
})() : mcpTools.map((mcpTool) => convertMCPToolToAnthropic(mcpTool, client, finalOptions));
|
|
10319
10916
|
const triggerConfig = client.__triggerConfig;
|
|
10320
10917
|
if (triggerConfig) {
|
|
10321
10918
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10360,6 +10957,7 @@ async function handleAnthropicMessage(client, message, options) {
|
|
|
10360
10957
|
var init_anthropic = __esm(() => {
|
|
10361
10958
|
init_utils();
|
|
10362
10959
|
init_trigger_tools();
|
|
10960
|
+
init_tool_builder();
|
|
10363
10961
|
init_esm();
|
|
10364
10962
|
});
|
|
10365
10963
|
|
|
@@ -10445,13 +11043,29 @@ async function executeGoogleFunctionCalls(client, functionCalls, options) {
|
|
|
10445
11043
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10446
11044
|
const triggerConfig = client.__triggerConfig;
|
|
10447
11045
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
11046
|
+
let cachedCodeModeTool = null;
|
|
11047
|
+
const getCodeModeTool = async () => {
|
|
11048
|
+
if (cachedCodeModeTool)
|
|
11049
|
+
return cachedCodeModeTool;
|
|
11050
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
11051
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
11052
|
+
tools: mcpTools,
|
|
11053
|
+
providerTokens: finalOptions?.providerTokens,
|
|
11054
|
+
context: options?.context,
|
|
11055
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11056
|
+
});
|
|
11057
|
+
return cachedCodeModeTool;
|
|
11058
|
+
};
|
|
10448
11059
|
const results = await Promise.all(functionCalls.map(async (call) => {
|
|
10449
11060
|
if (!call?.name) {
|
|
10450
11061
|
throw new Error("Function call must have a name");
|
|
10451
11062
|
}
|
|
10452
11063
|
const args = call.args || {};
|
|
10453
11064
|
let result;
|
|
10454
|
-
if (
|
|
11065
|
+
if (call.name === CODE_MODE_TOOL_NAME) {
|
|
11066
|
+
const codeTool = await getCodeModeTool();
|
|
11067
|
+
result = await codeTool.execute(args);
|
|
11068
|
+
} else if (triggerTools && triggerTools[call.name]) {
|
|
10455
11069
|
result = await triggerTools[call.name].execute(args);
|
|
10456
11070
|
} else {
|
|
10457
11071
|
result = await executeToolWithToken(client, call.name, args, finalOptions);
|
|
@@ -10470,7 +11084,33 @@ async function getGoogleTools(client, options) {
|
|
|
10470
11084
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10471
11085
|
await ensureClientConnected(client);
|
|
10472
11086
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10473
|
-
const
|
|
11087
|
+
const mode = options?.mode ?? "code";
|
|
11088
|
+
let googleTools;
|
|
11089
|
+
if (mode === "code") {
|
|
11090
|
+
const TypeEnum = await getGoogleType();
|
|
11091
|
+
const codeTool = buildCodeModeTool(client, {
|
|
11092
|
+
tools: mcpTools,
|
|
11093
|
+
providerTokens,
|
|
11094
|
+
context: options?.context,
|
|
11095
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11096
|
+
});
|
|
11097
|
+
googleTools = [{
|
|
11098
|
+
name: CODE_MODE_TOOL_NAME,
|
|
11099
|
+
description: codeTool.description,
|
|
11100
|
+
parameters: {
|
|
11101
|
+
type: TypeEnum.OBJECT,
|
|
11102
|
+
properties: {
|
|
11103
|
+
code: {
|
|
11104
|
+
type: TypeEnum.STRING,
|
|
11105
|
+
description: codeTool.parameters.properties.code.description
|
|
11106
|
+
}
|
|
11107
|
+
},
|
|
11108
|
+
required: ["code"]
|
|
11109
|
+
}
|
|
11110
|
+
}];
|
|
11111
|
+
} else {
|
|
11112
|
+
googleTools = await Promise.all(mcpTools.map((mcpTool) => convertMCPToolToGoogle(mcpTool, client, finalOptions)));
|
|
11113
|
+
}
|
|
10474
11114
|
const triggerConfig = client.__triggerConfig;
|
|
10475
11115
|
if (triggerConfig) {
|
|
10476
11116
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10548,6 +11188,7 @@ function convertJsonSchemaToGoogleSchema(jsonSchema, TypeEnum) {
|
|
|
10548
11188
|
var init_google = __esm(() => {
|
|
10549
11189
|
init_utils();
|
|
10550
11190
|
init_trigger_tools();
|
|
11191
|
+
init_tool_builder();
|
|
10551
11192
|
init_esm();
|
|
10552
11193
|
});
|
|
10553
11194
|
|
|
@@ -10613,8 +11254,8 @@ var init_webhooks = __esm(() => {
|
|
|
10613
11254
|
var MAX_TRIGGER_STEPS = 20, WEBHOOK_DELIVERY_TIMEOUT_MS = 1e4;
|
|
10614
11255
|
|
|
10615
11256
|
// src/triggers/executor.ts
|
|
10616
|
-
var
|
|
10617
|
-
__export(
|
|
11257
|
+
var exports_executor2 = {};
|
|
11258
|
+
__export(exports_executor2, {
|
|
10618
11259
|
executeTrigger: () => executeTrigger
|
|
10619
11260
|
});
|
|
10620
11261
|
async function executeTrigger(trigger, config, context) {
|
|
@@ -10761,7 +11402,7 @@ async function executeTrigger(trigger, config, context) {
|
|
|
10761
11402
|
return { success: false, steps, error: limitError };
|
|
10762
11403
|
}
|
|
10763
11404
|
var logger31;
|
|
10764
|
-
var
|
|
11405
|
+
var init_executor2 = __esm(() => {
|
|
10765
11406
|
init_logger();
|
|
10766
11407
|
init_utils2();
|
|
10767
11408
|
init_webhooks();
|
|
@@ -10906,7 +11547,8 @@ function createMCPServer(config) {
|
|
|
10906
11547
|
integrations: updatedIntegrations,
|
|
10907
11548
|
getSessionContext: config.getSessionContext,
|
|
10908
11549
|
setProviderToken: config.setProviderToken,
|
|
10909
|
-
removeProviderToken: config.removeProviderToken
|
|
11550
|
+
removeProviderToken: config.removeProviderToken,
|
|
11551
|
+
codeMode: config.codeMode
|
|
10910
11552
|
};
|
|
10911
11553
|
client.__triggerConfig = config.triggers ? {
|
|
10912
11554
|
callbacks: config.triggers,
|
|
@@ -10976,8 +11618,21 @@ function createMCPServer(config) {
|
|
|
10976
11618
|
if (action === "mcp" && method === "POST") {
|
|
10977
11619
|
try {
|
|
10978
11620
|
const body = await webRequest.json();
|
|
10979
|
-
|
|
11621
|
+
let authHeader = webRequest.headers.get("authorization");
|
|
10980
11622
|
const integrationsHeader = webRequest.headers.get("x-integrations");
|
|
11623
|
+
if (!authHeader) {
|
|
11624
|
+
const tokensHeader = webRequest.headers.get("x-integrate-tokens");
|
|
11625
|
+
const toolName = typeof body?.name === "string" ? body.name : "";
|
|
11626
|
+
if (tokensHeader && toolName) {
|
|
11627
|
+
try {
|
|
11628
|
+
const tokens = JSON.parse(tokensHeader);
|
|
11629
|
+
const provider = toolName.split("_")[0];
|
|
11630
|
+
if (provider && tokens[provider]) {
|
|
11631
|
+
authHeader = `Bearer ${tokens[provider]}`;
|
|
11632
|
+
}
|
|
11633
|
+
} catch {}
|
|
11634
|
+
}
|
|
11635
|
+
}
|
|
10981
11636
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
10982
11637
|
const oauthHandler = new OAuthHandler2({
|
|
10983
11638
|
providers,
|
|
@@ -10998,6 +11653,53 @@ function createMCPServer(config) {
|
|
|
10998
11653
|
return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
|
|
10999
11654
|
}
|
|
11000
11655
|
}
|
|
11656
|
+
if (action === "code" && method === "POST") {
|
|
11657
|
+
try {
|
|
11658
|
+
const body = await webRequest.json();
|
|
11659
|
+
if (typeof body?.code !== "string" || body.code.length === 0) {
|
|
11660
|
+
return Response.json({ error: "`code` is required and must be a non-empty string." }, { status: 400 });
|
|
11661
|
+
}
|
|
11662
|
+
const { executeSandboxCode: executeSandboxCode2 } = await Promise.resolve().then(() => (init_executor(), exports_executor));
|
|
11663
|
+
const codeModeConfig = config.codeMode ?? {};
|
|
11664
|
+
const publicUrl = codeModeConfig.publicUrl ?? getEnv("INTEGRATE_PUBLIC_URL");
|
|
11665
|
+
if (!publicUrl) {
|
|
11666
|
+
return Response.json({
|
|
11667
|
+
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."
|
|
11668
|
+
}, { status: 500 });
|
|
11669
|
+
}
|
|
11670
|
+
let contextOverride = body.context;
|
|
11671
|
+
if (!contextOverride && config.getSessionContext) {
|
|
11672
|
+
try {
|
|
11673
|
+
contextOverride = await config.getSessionContext(webRequest);
|
|
11674
|
+
} catch {}
|
|
11675
|
+
}
|
|
11676
|
+
let providerTokens = body.providerTokens;
|
|
11677
|
+
if (!providerTokens) {
|
|
11678
|
+
const headerTokens = webRequest.headers.get("x-integrate-tokens");
|
|
11679
|
+
if (headerTokens) {
|
|
11680
|
+
try {
|
|
11681
|
+
providerTokens = JSON.parse(headerTokens);
|
|
11682
|
+
} catch {}
|
|
11683
|
+
}
|
|
11684
|
+
}
|
|
11685
|
+
const integrationIds = updatedIntegrations.map((i) => i.id);
|
|
11686
|
+
const result = await executeSandboxCode2({
|
|
11687
|
+
code: body.code,
|
|
11688
|
+
mcpUrl: publicUrl.replace(/\/$/, "") + "/api/integrate/mcp",
|
|
11689
|
+
providerTokens,
|
|
11690
|
+
context: contextOverride,
|
|
11691
|
+
integrationsHeader: integrationIds.join(","),
|
|
11692
|
+
runtime: codeModeConfig.runtime,
|
|
11693
|
+
timeoutMs: codeModeConfig.timeoutMs,
|
|
11694
|
+
vcpus: codeModeConfig.vcpus,
|
|
11695
|
+
networkPolicy: codeModeConfig.networkPolicy
|
|
11696
|
+
});
|
|
11697
|
+
return Response.json(result, { status: result.success ? 200 : 500 });
|
|
11698
|
+
} catch (error) {
|
|
11699
|
+
logger32.error("[Code Mode] Error:", error);
|
|
11700
|
+
return Response.json({ error: error?.message || "Failed to execute code" }, { status: 500 });
|
|
11701
|
+
}
|
|
11702
|
+
}
|
|
11001
11703
|
if (action === "integrations" && method === "GET") {
|
|
11002
11704
|
const integrations = updatedIntegrations.map((integration) => ({
|
|
11003
11705
|
id: integration.id,
|
|
@@ -11033,7 +11735,7 @@ function createMCPServer(config) {
|
|
|
11033
11735
|
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
11034
11736
|
}
|
|
11035
11737
|
const triggerContext = trigger.userId ? { userId: trigger.userId } : undefined;
|
|
11036
|
-
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (
|
|
11738
|
+
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
|
|
11037
11739
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
11038
11740
|
const oauthHandler = new OAuthHandler2({
|
|
11039
11741
|
providers,
|
|
@@ -11196,7 +11898,7 @@ function createMCPServer(config) {
|
|
|
11196
11898
|
if (!trigger.provider) {
|
|
11197
11899
|
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
11198
11900
|
}
|
|
11199
|
-
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (
|
|
11901
|
+
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
|
|
11200
11902
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
11201
11903
|
const oauthHandler = new OAuthHandler2({
|
|
11202
11904
|
providers,
|
|
@@ -12272,6 +12974,10 @@ class OAuthHandler {
|
|
|
12272
12974
|
});
|
|
12273
12975
|
if (!response.ok) {
|
|
12274
12976
|
const error = await response.text();
|
|
12977
|
+
const lowerError = error.toLowerCase();
|
|
12978
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
12979
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
12980
|
+
}
|
|
12275
12981
|
throw new Error(`Token refresh failed: ${error}`);
|
|
12276
12982
|
}
|
|
12277
12983
|
const data = await response.json();
|