integrate-sdk 0.9.3-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 (62) hide show
  1. package/dist/adapters/auto-routes.js +713 -15
  2. package/dist/adapters/index.js +713 -15
  3. package/dist/adapters/nextjs.js +713 -15
  4. package/dist/adapters/node.js +713 -15
  5. package/dist/adapters/svelte-kit.js +713 -15
  6. package/dist/adapters/tanstack-start.js +713 -15
  7. package/dist/ai/anthropic.d.ts +11 -0
  8. package/dist/ai/anthropic.d.ts.map +1 -1
  9. package/dist/ai/anthropic.js +552 -2
  10. package/dist/ai/google.d.ts +11 -0
  11. package/dist/ai/google.d.ts.map +1 -1
  12. package/dist/ai/google.js +561 -2
  13. package/dist/ai/index.js +648 -8
  14. package/dist/ai/openai.d.ts +11 -0
  15. package/dist/ai/openai.d.ts.map +1 -1
  16. package/dist/ai/openai.js +550 -2
  17. package/dist/ai/vercel-ai.d.ts +13 -0
  18. package/dist/ai/vercel-ai.d.ts.map +1 -1
  19. package/dist/ai/vercel-ai.js +536 -2
  20. package/dist/code-mode/executor.d.ts +99 -0
  21. package/dist/code-mode/executor.d.ts.map +1 -0
  22. package/dist/code-mode/executor.js +207 -0
  23. package/dist/code-mode/index.d.ts +12 -0
  24. package/dist/code-mode/index.d.ts.map +1 -0
  25. package/dist/code-mode/index.js +527 -0
  26. package/dist/code-mode/runtime-stub.d.ts +16 -0
  27. package/dist/code-mode/runtime-stub.d.ts.map +1 -0
  28. package/dist/code-mode/runtime-stub.js +72 -0
  29. package/dist/code-mode/tool-builder.d.ts +83 -0
  30. package/dist/code-mode/tool-builder.d.ts.map +1 -0
  31. package/dist/code-mode/tool-builder.js +524 -0
  32. package/dist/code-mode/type-generator.d.ts +22 -0
  33. package/dist/code-mode/type-generator.d.ts.map +1 -0
  34. package/dist/code-mode/type-generator.js +217 -0
  35. package/dist/index.js +713 -15
  36. package/dist/oauth.js +713 -15
  37. package/dist/server.d.ts +1 -0
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +724 -16
  40. package/dist/src/ai/anthropic.d.ts +11 -0
  41. package/dist/src/ai/anthropic.d.ts.map +1 -1
  42. package/dist/src/ai/google.d.ts +11 -0
  43. package/dist/src/ai/google.d.ts.map +1 -1
  44. package/dist/src/ai/openai.d.ts +11 -0
  45. package/dist/src/ai/openai.d.ts.map +1 -1
  46. package/dist/src/ai/vercel-ai.d.ts +13 -0
  47. package/dist/src/ai/vercel-ai.d.ts.map +1 -1
  48. package/dist/src/code-mode/executor.d.ts +99 -0
  49. package/dist/src/code-mode/executor.d.ts.map +1 -0
  50. package/dist/src/code-mode/index.d.ts +12 -0
  51. package/dist/src/code-mode/index.d.ts.map +1 -0
  52. package/dist/src/code-mode/runtime-stub.d.ts +16 -0
  53. package/dist/src/code-mode/runtime-stub.d.ts.map +1 -0
  54. package/dist/src/code-mode/tool-builder.d.ts +83 -0
  55. package/dist/src/code-mode/tool-builder.d.ts.map +1 -0
  56. package/dist/src/code-mode/type-generator.d.ts +22 -0
  57. package/dist/src/code-mode/type-generator.d.ts.map +1 -0
  58. package/dist/src/config/types.d.ts +55 -0
  59. package/dist/src/config/types.d.ts.map +1 -1
  60. package/dist/src/server.d.ts.map +1 -1
  61. package/package.json +15 -6
  62. 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 {
@@ -8557,6 +8564,508 @@ var init_trigger_tools = __esm(() => {
8557
8564
  init_utils2();
8558
8565
  });
8559
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
+
8560
9069
  // src/ai/vercel-ai.ts
8561
9070
  function convertMCPToolToVercelAI(mcpTool, client, options) {
8562
9071
  return {
@@ -8581,8 +9090,25 @@ async function getVercelAITools(client, options) {
8581
9090
  await ensureClientConnected(client);
8582
9091
  const mcpTools = await client.getEnabledToolsAsync();
8583
9092
  const vercelTools = {};
8584
- for (const mcpTool of mcpTools) {
8585
- vercelTools[mcpTool.name] = convertMCPToolToVercelAI(mcpTool, client, finalOptions);
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
+ }
8586
9112
  }
8587
9113
  const triggerConfig = client.__triggerConfig;
8588
9114
  if (triggerConfig) {
@@ -8592,8 +9118,10 @@ async function getVercelAITools(client, options) {
8592
9118
  return vercelTools;
8593
9119
  }
8594
9120
  var init_vercel_ai = __esm(() => {
9121
+ init_zod();
8595
9122
  init_utils();
8596
9123
  init_trigger_tools();
9124
+ init_tool_builder();
8597
9125
  });
8598
9126
 
8599
9127
  // node_modules/zod-to-json-schema/dist/esm/Options.js
@@ -10021,7 +10549,22 @@ async function getOpenAITools(client, options) {
10021
10549
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
10022
10550
  await ensureClientConnected(client);
10023
10551
  const mcpTools = await client.getEnabledToolsAsync();
10024
- const openaiTools = mcpTools.map((mcpTool) => convertMCPToolToOpenAI(mcpTool, client, finalOptions));
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));
10025
10568
  const triggerConfig = client.__triggerConfig;
10026
10569
  if (triggerConfig) {
10027
10570
  const triggerTools = createTriggerTools(triggerConfig, options?.context);
@@ -10046,6 +10589,19 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
10046
10589
  const toolOutputs = [];
10047
10590
  const triggerConfig = client.__triggerConfig;
10048
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
+ };
10049
10605
  for (const output of toolCalls) {
10050
10606
  if (output.type === "function_call") {
10051
10607
  const toolCall = {
@@ -10056,7 +10612,10 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
10056
10612
  try {
10057
10613
  const args = JSON.parse(toolCall.arguments);
10058
10614
  let result;
10059
- if (triggerTools && triggerTools[toolCall.name]) {
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]) {
10060
10619
  result = await triggerTools[toolCall.name].execute(args);
10061
10620
  } else {
10062
10621
  result = await executeToolWithToken(client, toolCall.name, args, options);
@@ -10097,6 +10656,7 @@ async function handleOpenAIResponse(client, response, options) {
10097
10656
  var init_openai = __esm(() => {
10098
10657
  init_utils();
10099
10658
  init_trigger_tools();
10659
+ init_tool_builder();
10100
10660
  init_esm();
10101
10661
  });
10102
10662
 
@@ -10116,11 +10676,27 @@ async function handleAnthropicToolCalls(client, messageContent, options) {
10116
10676
  const toolResults = [];
10117
10677
  const triggerConfig = client.__triggerConfig;
10118
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
+ };
10119
10692
  const toolUseBlocks = messageContent.filter((block) => block.type === "tool_use" && ("id" in block) && ("name" in block) && ("input" in block));
10120
10693
  for (const toolUse of toolUseBlocks) {
10121
10694
  try {
10122
10695
  let result;
10123
- if (triggerTools && triggerTools[toolUse.name]) {
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]) {
10124
10700
  result = await triggerTools[toolUse.name].execute(toolUse.input);
10125
10701
  } else {
10126
10702
  result = await executeToolWithToken(client, toolUse.name, toolUse.input, options);
@@ -10153,7 +10729,24 @@ async function getAnthropicTools(client, options) {
10153
10729
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
10154
10730
  await ensureClientConnected(client);
10155
10731
  const mcpTools = await client.getEnabledToolsAsync();
10156
- const anthropicTools = mcpTools.map((mcpTool) => convertMCPToolToAnthropic(mcpTool, client, finalOptions));
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));
10157
10750
  const triggerConfig = client.__triggerConfig;
10158
10751
  if (triggerConfig) {
10159
10752
  const triggerTools = createTriggerTools(triggerConfig, options?.context);
@@ -10198,6 +10791,7 @@ async function handleAnthropicMessage(client, message, options) {
10198
10791
  var init_anthropic = __esm(() => {
10199
10792
  init_utils();
10200
10793
  init_trigger_tools();
10794
+ init_tool_builder();
10201
10795
  init_esm();
10202
10796
  });
10203
10797
 
@@ -10283,13 +10877,29 @@ async function executeGoogleFunctionCalls(client, functionCalls, options) {
10283
10877
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
10284
10878
  const triggerConfig = client.__triggerConfig;
10285
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
+ };
10286
10893
  const results = await Promise.all(functionCalls.map(async (call) => {
10287
10894
  if (!call?.name) {
10288
10895
  throw new Error("Function call must have a name");
10289
10896
  }
10290
10897
  const args = call.args || {};
10291
10898
  let result;
10292
- if (triggerTools && triggerTools[call.name]) {
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]) {
10293
10903
  result = await triggerTools[call.name].execute(args);
10294
10904
  } else {
10295
10905
  result = await executeToolWithToken(client, call.name, args, finalOptions);
@@ -10308,7 +10918,33 @@ async function getGoogleTools(client, options) {
10308
10918
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
10309
10919
  await ensureClientConnected(client);
10310
10920
  const mcpTools = await client.getEnabledToolsAsync();
10311
- const googleTools = await Promise.all(mcpTools.map((mcpTool) => convertMCPToolToGoogle(mcpTool, client, finalOptions)));
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
+ }
10312
10948
  const triggerConfig = client.__triggerConfig;
10313
10949
  if (triggerConfig) {
10314
10950
  const triggerTools = createTriggerTools(triggerConfig, options?.context);
@@ -10386,6 +11022,7 @@ function convertJsonSchemaToGoogleSchema(jsonSchema, TypeEnum) {
10386
11022
  var init_google = __esm(() => {
10387
11023
  init_utils();
10388
11024
  init_trigger_tools();
11025
+ init_tool_builder();
10389
11026
  init_esm();
10390
11027
  });
10391
11028
 
@@ -10451,8 +11088,8 @@ var init_webhooks = __esm(() => {
10451
11088
  var MAX_TRIGGER_STEPS = 20, WEBHOOK_DELIVERY_TIMEOUT_MS = 1e4;
10452
11089
 
10453
11090
  // src/triggers/executor.ts
10454
- var exports_executor = {};
10455
- __export(exports_executor, {
11091
+ var exports_executor2 = {};
11092
+ __export(exports_executor2, {
10456
11093
  executeTrigger: () => executeTrigger
10457
11094
  });
10458
11095
  async function executeTrigger(trigger, config, context) {
@@ -10599,7 +11236,7 @@ async function executeTrigger(trigger, config, context) {
10599
11236
  return { success: false, steps, error: limitError };
10600
11237
  }
10601
11238
  var logger31;
10602
- var init_executor = __esm(() => {
11239
+ var init_executor2 = __esm(() => {
10603
11240
  init_logger();
10604
11241
  init_utils2();
10605
11242
  init_webhooks();
@@ -10744,7 +11381,8 @@ function createMCPServer(config) {
10744
11381
  integrations: updatedIntegrations,
10745
11382
  getSessionContext: config.getSessionContext,
10746
11383
  setProviderToken: config.setProviderToken,
10747
- removeProviderToken: config.removeProviderToken
11384
+ removeProviderToken: config.removeProviderToken,
11385
+ codeMode: config.codeMode
10748
11386
  };
10749
11387
  client.__triggerConfig = config.triggers ? {
10750
11388
  callbacks: config.triggers,
@@ -10814,8 +11452,21 @@ function createMCPServer(config) {
10814
11452
  if (action === "mcp" && method === "POST") {
10815
11453
  try {
10816
11454
  const body = await webRequest.json();
10817
- const authHeader = webRequest.headers.get("authorization");
11455
+ let authHeader = webRequest.headers.get("authorization");
10818
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
+ }
10819
11470
  const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
10820
11471
  const oauthHandler = new OAuthHandler2({
10821
11472
  providers,
@@ -10836,6 +11487,53 @@ function createMCPServer(config) {
10836
11487
  return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
10837
11488
  }
10838
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
+ }
10839
11537
  if (action === "integrations" && method === "GET") {
10840
11538
  const integrations = updatedIntegrations.map((integration) => ({
10841
11539
  id: integration.id,
@@ -10871,7 +11569,7 @@ function createMCPServer(config) {
10871
11569
  return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
10872
11570
  }
10873
11571
  const triggerContext = trigger.userId ? { userId: trigger.userId } : undefined;
10874
- const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor(), exports_executor));
11572
+ const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
10875
11573
  const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
10876
11574
  const oauthHandler = new OAuthHandler2({
10877
11575
  providers,
@@ -11034,7 +11732,7 @@ function createMCPServer(config) {
11034
11732
  if (!trigger.provider) {
11035
11733
  return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
11036
11734
  }
11037
- const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor(), exports_executor));
11735
+ const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
11038
11736
  const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
11039
11737
  const oauthHandler = new OAuthHandler2({
11040
11738
  providers,