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.
Files changed (68) hide show
  1. package/dist/adapters/auto-routes.d.ts.map +1 -1
  2. package/dist/adapters/auto-routes.js +727 -17
  3. package/dist/adapters/base-handler.d.ts.map +1 -1
  4. package/dist/adapters/index.js +722 -16
  5. package/dist/adapters/nextjs.d.ts.map +1 -1
  6. package/dist/adapters/nextjs.js +722 -16
  7. package/dist/adapters/node.js +722 -16
  8. package/dist/adapters/svelte-kit.js +722 -16
  9. package/dist/adapters/tanstack-start.js +722 -16
  10. package/dist/ai/anthropic.d.ts +11 -0
  11. package/dist/ai/anthropic.d.ts.map +1 -1
  12. package/dist/ai/anthropic.js +552 -2
  13. package/dist/ai/google.d.ts +11 -0
  14. package/dist/ai/google.d.ts.map +1 -1
  15. package/dist/ai/google.js +561 -2
  16. package/dist/ai/index.js +648 -8
  17. package/dist/ai/openai.d.ts +11 -0
  18. package/dist/ai/openai.d.ts.map +1 -1
  19. package/dist/ai/openai.js +550 -2
  20. package/dist/ai/vercel-ai.d.ts +13 -0
  21. package/dist/ai/vercel-ai.d.ts.map +1 -1
  22. package/dist/ai/vercel-ai.js +536 -2
  23. package/dist/code-mode/executor.d.ts +99 -0
  24. package/dist/code-mode/executor.d.ts.map +1 -0
  25. package/dist/code-mode/executor.js +207 -0
  26. package/dist/code-mode/index.d.ts +12 -0
  27. package/dist/code-mode/index.d.ts.map +1 -0
  28. package/dist/code-mode/index.js +527 -0
  29. package/dist/code-mode/runtime-stub.d.ts +16 -0
  30. package/dist/code-mode/runtime-stub.d.ts.map +1 -0
  31. package/dist/code-mode/runtime-stub.js +72 -0
  32. package/dist/code-mode/tool-builder.d.ts +83 -0
  33. package/dist/code-mode/tool-builder.d.ts.map +1 -0
  34. package/dist/code-mode/tool-builder.js +524 -0
  35. package/dist/code-mode/type-generator.d.ts +22 -0
  36. package/dist/code-mode/type-generator.d.ts.map +1 -0
  37. package/dist/code-mode/type-generator.js +217 -0
  38. package/dist/index.js +722 -16
  39. package/dist/oauth.js +727 -17
  40. package/dist/server.d.ts +1 -0
  41. package/dist/server.d.ts.map +1 -1
  42. package/dist/server.js +733 -17
  43. package/dist/src/adapters/auto-routes.d.ts.map +1 -1
  44. package/dist/src/adapters/base-handler.d.ts.map +1 -1
  45. package/dist/src/adapters/nextjs.d.ts.map +1 -1
  46. package/dist/src/ai/anthropic.d.ts +11 -0
  47. package/dist/src/ai/anthropic.d.ts.map +1 -1
  48. package/dist/src/ai/google.d.ts +11 -0
  49. package/dist/src/ai/google.d.ts.map +1 -1
  50. package/dist/src/ai/openai.d.ts +11 -0
  51. package/dist/src/ai/openai.d.ts.map +1 -1
  52. package/dist/src/ai/vercel-ai.d.ts +13 -0
  53. package/dist/src/ai/vercel-ai.d.ts.map +1 -1
  54. package/dist/src/code-mode/executor.d.ts +99 -0
  55. package/dist/src/code-mode/executor.d.ts.map +1 -0
  56. package/dist/src/code-mode/index.d.ts +12 -0
  57. package/dist/src/code-mode/index.d.ts.map +1 -0
  58. package/dist/src/code-mode/runtime-stub.d.ts +16 -0
  59. package/dist/src/code-mode/runtime-stub.d.ts.map +1 -0
  60. package/dist/src/code-mode/tool-builder.d.ts +83 -0
  61. package/dist/src/code-mode/tool-builder.d.ts.map +1 -0
  62. package/dist/src/code-mode/type-generator.d.ts +22 -0
  63. package/dist/src/code-mode/type-generator.d.ts.map +1 -0
  64. package/dist/src/config/types.d.ts +55 -0
  65. package/dist/src/config/types.d.ts.map +1 -1
  66. package/dist/src/server.d.ts.map +1 -1
  67. package/package.json +15 -6
  68. 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
- logger6.error("[OAuth Refresh] Error:", error);
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
- for (const mcpTool of mcpTools) {
8747
- vercelTools[mcpTool.name] = convertMCPToolToVercelAI(mcpTool, client, finalOptions);
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 openaiTools = mcpTools.map((mcpTool) => convertMCPToolToOpenAI(mcpTool, client, finalOptions));
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 (triggerTools && triggerTools[toolCall.name]) {
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 (triggerTools && triggerTools[toolUse.name]) {
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 anthropicTools = mcpTools.map((mcpTool) => convertMCPToolToAnthropic(mcpTool, client, finalOptions));
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 (triggerTools && triggerTools[call.name]) {
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 googleTools = await Promise.all(mcpTools.map((mcpTool) => convertMCPToolToGoogle(mcpTool, client, finalOptions)));
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 exports_executor = {};
10617
- __export(exports_executor, {
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 init_executor = __esm(() => {
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
- const authHeader = webRequest.headers.get("authorization");
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(() => (init_executor(), exports_executor));
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(() => (init_executor(), exports_executor));
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();