integrate-sdk 0.9.3-dev.0 → 0.9.5-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 (65) hide show
  1. package/dist/adapters/auto-routes.js +720 -22
  2. package/dist/adapters/index.js +720 -22
  3. package/dist/adapters/nextjs.js +720 -22
  4. package/dist/adapters/node.js +720 -22
  5. package/dist/adapters/svelte-kit.js +720 -22
  6. package/dist/adapters/tanstack-start.js +720 -22
  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 +559 -9
  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 +568 -9
  13. package/dist/ai/index.js +655 -15
  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 +557 -9
  17. package/dist/ai/trigger-tools.d.ts +7 -7
  18. package/dist/ai/trigger-tools.js +7 -7
  19. package/dist/ai/vercel-ai.d.ts +13 -0
  20. package/dist/ai/vercel-ai.d.ts.map +1 -1
  21. package/dist/ai/vercel-ai.js +543 -9
  22. package/dist/code-mode/executor.d.ts +99 -0
  23. package/dist/code-mode/executor.d.ts.map +1 -0
  24. package/dist/code-mode/executor.js +207 -0
  25. package/dist/code-mode/index.d.ts +12 -0
  26. package/dist/code-mode/index.d.ts.map +1 -0
  27. package/dist/code-mode/index.js +527 -0
  28. package/dist/code-mode/runtime-stub.d.ts +16 -0
  29. package/dist/code-mode/runtime-stub.d.ts.map +1 -0
  30. package/dist/code-mode/runtime-stub.js +72 -0
  31. package/dist/code-mode/tool-builder.d.ts +83 -0
  32. package/dist/code-mode/tool-builder.d.ts.map +1 -0
  33. package/dist/code-mode/tool-builder.js +524 -0
  34. package/dist/code-mode/type-generator.d.ts +22 -0
  35. package/dist/code-mode/type-generator.d.ts.map +1 -0
  36. package/dist/code-mode/type-generator.js +217 -0
  37. package/dist/index.js +720 -22
  38. package/dist/oauth.js +720 -22
  39. package/dist/server.d.ts +1 -0
  40. package/dist/server.d.ts.map +1 -1
  41. package/dist/server.js +731 -23
  42. package/dist/src/ai/anthropic.d.ts +11 -0
  43. package/dist/src/ai/anthropic.d.ts.map +1 -1
  44. package/dist/src/ai/google.d.ts +11 -0
  45. package/dist/src/ai/google.d.ts.map +1 -1
  46. package/dist/src/ai/openai.d.ts +11 -0
  47. package/dist/src/ai/openai.d.ts.map +1 -1
  48. package/dist/src/ai/trigger-tools.d.ts +7 -7
  49. package/dist/src/ai/vercel-ai.d.ts +13 -0
  50. package/dist/src/ai/vercel-ai.d.ts.map +1 -1
  51. package/dist/src/code-mode/executor.d.ts +99 -0
  52. package/dist/src/code-mode/executor.d.ts.map +1 -0
  53. package/dist/src/code-mode/index.d.ts +12 -0
  54. package/dist/src/code-mode/index.d.ts.map +1 -0
  55. package/dist/src/code-mode/runtime-stub.d.ts +16 -0
  56. package/dist/src/code-mode/runtime-stub.d.ts.map +1 -0
  57. package/dist/src/code-mode/tool-builder.d.ts +83 -0
  58. package/dist/src/code-mode/tool-builder.d.ts.map +1 -0
  59. package/dist/src/code-mode/type-generator.d.ts +22 -0
  60. package/dist/src/code-mode/type-generator.d.ts.map +1 -0
  61. package/dist/src/config/types.d.ts +55 -0
  62. package/dist/src/config/types.d.ts.map +1 -1
  63. package/dist/src/server.d.ts.map +1 -1
  64. package/package.json +15 -6
  65. package/server.ts +9 -0
package/dist/ai/google.js CHANGED
@@ -4251,7 +4251,7 @@ function calculateHasMore(offset, returnedCount, total) {
4251
4251
  function createTriggerTools(config, context) {
4252
4252
  const { callbacks } = config;
4253
4253
  return {
4254
- create_trigger: {
4254
+ trigger_create: {
4255
4255
  description: "Schedule a tool to run at a specific time or on a recurring schedule. Use this when the user wants to do something later.",
4256
4256
  inputSchema: exports_external.object({
4257
4257
  name: exports_external.string().optional().describe("Human-readable trigger name"),
@@ -4285,7 +4285,7 @@ function createTriggerTools(config, context) {
4285
4285
  return callbacks.create(trigger, context);
4286
4286
  }
4287
4287
  },
4288
- list_triggers: {
4288
+ trigger_list: {
4289
4289
  description: "List all scheduled triggers with optional filtering by status or tool name",
4290
4290
  inputSchema: exports_external.object({
4291
4291
  status: exports_external.enum(["active", "paused", "completed", "failed"]).optional().describe("Filter by trigger status"),
@@ -4309,7 +4309,7 @@ function createTriggerTools(config, context) {
4309
4309
  };
4310
4310
  }
4311
4311
  },
4312
- get_trigger: {
4312
+ trigger_get: {
4313
4313
  description: "Get details of a specific trigger by its ID",
4314
4314
  inputSchema: exports_external.object({
4315
4315
  triggerId: exports_external.string().describe("The trigger ID to retrieve")
@@ -4322,7 +4322,7 @@ function createTriggerTools(config, context) {
4322
4322
  return trigger;
4323
4323
  }
4324
4324
  },
4325
- update_trigger: {
4325
+ trigger_update: {
4326
4326
  description: "Update a trigger's properties like name, description, arguments, or schedule",
4327
4327
  inputSchema: exports_external.object({
4328
4328
  triggerId: exports_external.string().describe("The trigger ID to update"),
@@ -4349,7 +4349,7 @@ function createTriggerTools(config, context) {
4349
4349
  return callbacks.update(triggerId, updatesWithTimestamp, context);
4350
4350
  }
4351
4351
  },
4352
- delete_trigger: {
4352
+ trigger_delete: {
4353
4353
  description: "Delete a trigger permanently. This cannot be undone.",
4354
4354
  inputSchema: exports_external.object({
4355
4355
  triggerId: exports_external.string().describe("The trigger ID to delete")
@@ -4359,7 +4359,7 @@ function createTriggerTools(config, context) {
4359
4359
  return { success: true, message: `Trigger ${args.triggerId} deleted` };
4360
4360
  }
4361
4361
  },
4362
- pause_trigger: {
4362
+ trigger_pause: {
4363
4363
  description: "Pause a trigger to temporarily stop it from executing. Can be resumed later.",
4364
4364
  inputSchema: exports_external.object({
4365
4365
  triggerId: exports_external.string().describe("The trigger ID to pause")
@@ -4379,7 +4379,7 @@ function createTriggerTools(config, context) {
4379
4379
  }, context);
4380
4380
  }
4381
4381
  },
4382
- resume_trigger: {
4382
+ trigger_resume: {
4383
4383
  description: "Resume a paused trigger to start executing it again on schedule",
4384
4384
  inputSchema: exports_external.object({
4385
4385
  triggerId: exports_external.string().describe("The trigger ID to resume")
@@ -4402,6 +4402,523 @@ function createTriggerTools(config, context) {
4402
4402
  };
4403
4403
  }
4404
4404
 
4405
+ // ../utils/naming.ts
4406
+ function snakeToCamel(str) {
4407
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
4408
+ }
4409
+ function toolNameToMethod(toolName) {
4410
+ const withoutPrefix = toolName.replace(/^[^_]+_/, "");
4411
+ return snakeToCamel(withoutPrefix);
4412
+ }
4413
+
4414
+ // ../code-mode/type-generator.ts
4415
+ var RESERVED_TS = new Set([
4416
+ "break",
4417
+ "case",
4418
+ "catch",
4419
+ "class",
4420
+ "const",
4421
+ "continue",
4422
+ "debugger",
4423
+ "default",
4424
+ "delete",
4425
+ "do",
4426
+ "else",
4427
+ "enum",
4428
+ "export",
4429
+ "extends",
4430
+ "false",
4431
+ "finally",
4432
+ "for",
4433
+ "function",
4434
+ "if",
4435
+ "import",
4436
+ "in",
4437
+ "instanceof",
4438
+ "new",
4439
+ "null",
4440
+ "return",
4441
+ "super",
4442
+ "switch",
4443
+ "this",
4444
+ "throw",
4445
+ "true",
4446
+ "try",
4447
+ "typeof",
4448
+ "var",
4449
+ "void",
4450
+ "while",
4451
+ "with",
4452
+ "as",
4453
+ "implements",
4454
+ "interface",
4455
+ "let",
4456
+ "package",
4457
+ "private",
4458
+ "protected",
4459
+ "public",
4460
+ "static",
4461
+ "yield"
4462
+ ]);
4463
+ function safeIdent(name) {
4464
+ if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) || RESERVED_TS.has(name)) {
4465
+ return JSON.stringify(name);
4466
+ }
4467
+ return name;
4468
+ }
4469
+ function integrationFromToolName(toolName) {
4470
+ const idx = toolName.indexOf("_");
4471
+ return idx === -1 ? toolName : toolName.slice(0, idx);
4472
+ }
4473
+ function jsonSchemaToTs(schema, indent) {
4474
+ if (!schema || typeof schema !== "object")
4475
+ return "unknown";
4476
+ const s = schema;
4477
+ if (Array.isArray(s.enum) && s.enum.length > 0) {
4478
+ return s.enum.map((v) => typeof v === "string" ? JSON.stringify(v) : typeof v === "number" || typeof v === "boolean" ? String(v) : "unknown").join(" | ");
4479
+ }
4480
+ if (Array.isArray(s.type)) {
4481
+ return s.type.map((t2) => jsonSchemaToTs({ ...s, type: t2 }, indent)).join(" | ");
4482
+ }
4483
+ const t = s.type;
4484
+ switch (t) {
4485
+ case "string":
4486
+ return "string";
4487
+ case "number":
4488
+ case "integer":
4489
+ return "number";
4490
+ case "boolean":
4491
+ return "boolean";
4492
+ case "null":
4493
+ return "null";
4494
+ case "array": {
4495
+ const items = s.items;
4496
+ if (Array.isArray(items))
4497
+ return "unknown[]";
4498
+ const inner = jsonSchemaToTs(items, indent);
4499
+ return /[|&]/.test(inner) ? `Array<${inner}>` : `${inner}[]`;
4500
+ }
4501
+ case "object":
4502
+ return objectShape(s, indent);
4503
+ default:
4504
+ if (s.properties && typeof s.properties === "object")
4505
+ return objectShape(s, indent);
4506
+ return "unknown";
4507
+ }
4508
+ }
4509
+ function objectShape(schema, indent) {
4510
+ const props = schema.properties && typeof schema.properties === "object" ? schema.properties : {};
4511
+ const keys = Object.keys(props);
4512
+ if (keys.length === 0) {
4513
+ return schema.additionalProperties === false ? "Record<string, never>" : "Record<string, unknown>";
4514
+ }
4515
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
4516
+ const inner = indent + " ";
4517
+ const lines = ["{"];
4518
+ for (const key of keys) {
4519
+ const prop = props[key];
4520
+ const desc = prop && typeof prop.description === "string" ? prop.description : undefined;
4521
+ if (desc)
4522
+ lines.push(`${inner}/** ${desc.replace(/\*\//g, "*\\/")} */`);
4523
+ const optional = required.has(key) ? "" : "?";
4524
+ const type = jsonSchemaToTs(prop, inner);
4525
+ lines.push(`${inner}${safeIdent(key)}${optional}: ${type};`);
4526
+ }
4527
+ lines.push(`${indent}}`);
4528
+ return lines.join(`
4529
+ `);
4530
+ }
4531
+ function argsType(schema) {
4532
+ if (!schema)
4533
+ return "Record<string, unknown>";
4534
+ const hasProps = schema.properties && Object.keys(schema.properties).length > 0;
4535
+ if (!hasProps)
4536
+ return "Record<string, unknown>";
4537
+ return objectShape(schema, " ");
4538
+ }
4539
+ function methodHasRequiredArgs(schema) {
4540
+ if (!schema || !schema.properties)
4541
+ return false;
4542
+ const req = Array.isArray(schema.required) ? schema.required : [];
4543
+ return req.length > 0;
4544
+ }
4545
+ function formatDescription(desc, indent) {
4546
+ if (!desc)
4547
+ return "";
4548
+ const cleaned = desc.replace(/\*\//g, "*\\/").trim();
4549
+ if (!cleaned.includes(`
4550
+ `))
4551
+ return `${indent}/** ${cleaned} */
4552
+ `;
4553
+ const lines = cleaned.split(`
4554
+ `).map((l) => `${indent} * ${l}`).join(`
4555
+ `);
4556
+ return `${indent}/**
4557
+ ${lines}
4558
+ ${indent} */
4559
+ `;
4560
+ }
4561
+ function generateCodeModeTypes(tools) {
4562
+ const byIntegration = {};
4563
+ for (const tool of tools) {
4564
+ const integration = integrationFromToolName(tool.name);
4565
+ (byIntegration[integration] ??= []).push(tool);
4566
+ }
4567
+ const methodMap = {};
4568
+ const integrationCounts = {};
4569
+ const sections = [];
4570
+ const integrationIds = Object.keys(byIntegration).sort();
4571
+ sections.push("/**");
4572
+ sections.push(" * Integrate SDK — available APIs inside `execute_code`.");
4573
+ sections.push(" * Every method is async and returns the MCP tool-call response.");
4574
+ sections.push(" * Call them via the exported `client` object, e.g.");
4575
+ sections.push(" * const repos = await client.github.listRepos();");
4576
+ sections.push(" */");
4577
+ sections.push("");
4578
+ for (const integrationId of integrationIds) {
4579
+ const integrationTools = byIntegration[integrationId].slice().sort((a, b) => a.name.localeCompare(b.name));
4580
+ integrationCounts[integrationId] = integrationTools.length;
4581
+ const interfaceName = pascalCase(integrationId) + "Client";
4582
+ sections.push(`export interface ${interfaceName} {`);
4583
+ for (const tool of integrationTools) {
4584
+ const methodName = toolNameToMethod(tool.name);
4585
+ methodMap[`${integrationId}.${methodName}`] = tool.name;
4586
+ sections.push(formatDescription(tool.description, " "));
4587
+ const argType = argsType(tool.inputSchema);
4588
+ const argIsOptional = !methodHasRequiredArgs(tool.inputSchema);
4589
+ const paramName = argIsOptional ? "args?" : "args";
4590
+ sections.push(` ${safeIdent(methodName)}(${paramName}: ${argType}): Promise<ToolResult>;`);
4591
+ }
4592
+ sections.push("}");
4593
+ sections.push("");
4594
+ }
4595
+ sections.push("export interface ToolResult {");
4596
+ sections.push(" content: Array<{ type: 'text' | 'image' | 'resource'; text?: string; data?: string; mimeType?: string; [key: string]: unknown }>;");
4597
+ sections.push(" isError?: boolean;");
4598
+ sections.push(" structuredContent?: Record<string, unknown>;");
4599
+ sections.push("}");
4600
+ sections.push("");
4601
+ sections.push("export interface Client {");
4602
+ for (const integrationId of integrationIds) {
4603
+ const interfaceName = pascalCase(integrationId) + "Client";
4604
+ sections.push(` ${safeIdent(integrationId)}: ${interfaceName};`);
4605
+ }
4606
+ sections.push("}");
4607
+ sections.push("");
4608
+ sections.push("export declare const client: Client;");
4609
+ return {
4610
+ source: sections.filter((line, idx, arr) => !(line === "" && arr[idx - 1] === "")).join(`
4611
+ `),
4612
+ methodMap,
4613
+ integrationCounts
4614
+ };
4615
+ }
4616
+ function pascalCase(id) {
4617
+ return id.split(/[^A-Za-z0-9]/).filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("") || "Unknown";
4618
+ }
4619
+
4620
+ // ../code-mode/runtime-stub.ts
4621
+ var RUNTIME_STUB_SOURCE = `// runtime.mjs — generated by integrate-sdk code mode
4622
+ const MCP_URL = process.env.INTEGRATE_MCP_URL;
4623
+ const SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;
4624
+ const PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';
4625
+ const INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';
4626
+ const CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';
4627
+
4628
+ if (!MCP_URL) {
4629
+ throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
4630
+ }
4631
+
4632
+ function camelToSnake(str) {
4633
+ return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
4634
+ }
4635
+
4636
+ async function callTool(toolName, args) {
4637
+ const headers = {
4638
+ 'Content-Type': 'application/json',
4639
+ 'x-integrate-code-mode': '1',
4640
+ };
4641
+ if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;
4642
+ if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;
4643
+ if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
4644
+ if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
4645
+
4646
+ const res = await fetch(MCP_URL, {
4647
+ method: 'POST',
4648
+ headers,
4649
+ body: JSON.stringify({ name: toolName, arguments: args || {} }),
4650
+ });
4651
+
4652
+ const text = await res.text();
4653
+ let payload;
4654
+ try {
4655
+ payload = text ? JSON.parse(text) : null;
4656
+ } catch {
4657
+ payload = { content: [{ type: 'text', text }] };
4658
+ }
4659
+
4660
+ if (!res.ok) {
4661
+ const message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;
4662
+ const err = new Error(message);
4663
+ err.status = res.status;
4664
+ err.toolName = toolName;
4665
+ throw err;
4666
+ }
4667
+
4668
+ return payload;
4669
+ }
4670
+
4671
+ function createIntegrationProxy(integrationId) {
4672
+ return new Proxy({}, {
4673
+ get(_target, methodName) {
4674
+ if (typeof methodName !== 'string') return undefined;
4675
+ return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);
4676
+ },
4677
+ });
4678
+ }
4679
+
4680
+ export const client = new Proxy({}, {
4681
+ get(_target, integrationId) {
4682
+ if (typeof integrationId !== 'string') return undefined;
4683
+ return createIntegrationProxy(integrationId);
4684
+ },
4685
+ });
4686
+
4687
+ export { callTool };
4688
+ `;
4689
+
4690
+ // ../code-mode/executor.ts
4691
+ var sandboxFactoryOverride = null;
4692
+ async function loadSandboxFactory() {
4693
+ if (sandboxFactoryOverride)
4694
+ return sandboxFactoryOverride;
4695
+ try {
4696
+ const dynamicImport = new Function("specifier", "return import(specifier)");
4697
+ const pkg = "@" + "vercel/sandbox";
4698
+ const mod = await dynamicImport(pkg);
4699
+ return mod.Sandbox ?? mod.default?.Sandbox ?? mod;
4700
+ } catch (err) {
4701
+ throw new Error("Code Mode requires the optional peer dependency `@vercel/sandbox`. " + "Install it with `npm install @vercel/sandbox` (or `bun add @vercel/sandbox`).");
4702
+ }
4703
+ }
4704
+ var RESULT_SENTINEL = "__INTEGRATE_RESULT__";
4705
+ function wrapUserCode(code) {
4706
+ return `// user.mjs — wrapped by integrate-sdk code mode
4707
+ import { client, callTool } from './runtime.mjs';
4708
+
4709
+ (async () => {
4710
+ try {
4711
+ const __result = await (async () => {
4712
+ ${code}
4713
+ })();
4714
+ if (typeof __result !== 'undefined') {
4715
+ process.stdout.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify(__result) + '\\n');
4716
+ }
4717
+ } catch (err) {
4718
+ const payload = {
4719
+ message: err && err.message ? err.message : String(err),
4720
+ name: err && err.name,
4721
+ stack: err && err.stack,
4722
+ toolName: err && err.toolName,
4723
+ status: err && err.status,
4724
+ };
4725
+ process.stderr.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify({ error: payload }) + '\\n');
4726
+ process.exit(1);
4727
+ }
4728
+ })();
4729
+ `;
4730
+ }
4731
+ function defaultNetworkPolicy(mcpUrl) {
4732
+ try {
4733
+ const host = new URL(mcpUrl).hostname;
4734
+ return { allow: [host] };
4735
+ } catch {
4736
+ return { allow: [] };
4737
+ }
4738
+ }
4739
+ function extractResult(stream) {
4740
+ const idx = stream.lastIndexOf(RESULT_SENTINEL);
4741
+ if (idx === -1)
4742
+ return { cleaned: stream };
4743
+ const before = stream.slice(0, idx).replace(/\n$/, "");
4744
+ const rest = stream.slice(idx + RESULT_SENTINEL.length);
4745
+ const newlineIdx = rest.indexOf(`
4746
+ `);
4747
+ const payload = newlineIdx === -1 ? rest : rest.slice(0, newlineIdx);
4748
+ const after = newlineIdx === -1 ? "" : rest.slice(newlineIdx + 1);
4749
+ try {
4750
+ return { cleaned: (before + after).trimEnd(), result: JSON.parse(payload) };
4751
+ } catch {
4752
+ return { cleaned: stream };
4753
+ }
4754
+ }
4755
+ async function executeSandboxCode(options) {
4756
+ const startedAt = Date.now();
4757
+ const runtime = options.runtime ?? "node22";
4758
+ const timeoutMs = options.timeoutMs ?? 60000;
4759
+ const networkPolicy = options.networkPolicy ?? defaultNetworkPolicy(options.mcpUrl);
4760
+ let sandbox = null;
4761
+ try {
4762
+ const Sandbox = await loadSandboxFactory();
4763
+ sandbox = await Sandbox.create({
4764
+ runtime,
4765
+ timeout: timeoutMs,
4766
+ resources: options.vcpus ? { vcpus: options.vcpus } : undefined,
4767
+ networkPolicy
4768
+ });
4769
+ const runtimeContent = Buffer.from(RUNTIME_STUB_SOURCE, "utf-8");
4770
+ const userContent = Buffer.from(wrapUserCode(options.code), "utf-8");
4771
+ await sandbox.writeFiles([
4772
+ { path: "runtime.mjs", content: runtimeContent },
4773
+ { path: "user.mjs", content: userContent }
4774
+ ]);
4775
+ const env = {
4776
+ INTEGRATE_MCP_URL: options.mcpUrl
4777
+ };
4778
+ if (options.sessionToken)
4779
+ env.INTEGRATE_SESSION_TOKEN = options.sessionToken;
4780
+ if (options.providerTokens && Object.keys(options.providerTokens).length > 0) {
4781
+ env.INTEGRATE_PROVIDER_TOKENS = JSON.stringify(options.providerTokens);
4782
+ }
4783
+ if (options.integrationsHeader)
4784
+ env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
4785
+ if (options.context)
4786
+ env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
4787
+ const cmd = await sandbox.runCommand({
4788
+ cmd: "node",
4789
+ args: ["user.mjs"],
4790
+ env
4791
+ });
4792
+ const [stdoutRaw, stderrRaw] = await Promise.all([cmd.stdout(), cmd.stderr()]);
4793
+ const stdoutExtract = extractResult(stdoutRaw);
4794
+ const stderrExtract = extractResult(stderrRaw);
4795
+ return {
4796
+ success: cmd.exitCode === 0,
4797
+ exitCode: cmd.exitCode,
4798
+ result: stdoutExtract.result ?? stderrExtract.result,
4799
+ stdout: stdoutExtract.cleaned,
4800
+ stderr: stderrExtract.cleaned,
4801
+ durationMs: Date.now() - startedAt
4802
+ };
4803
+ } catch (err) {
4804
+ return {
4805
+ success: false,
4806
+ exitCode: -1,
4807
+ stdout: "",
4808
+ stderr: "",
4809
+ durationMs: Date.now() - startedAt,
4810
+ error: err instanceof Error ? err.message : String(err)
4811
+ };
4812
+ } finally {
4813
+ if (sandbox) {
4814
+ try {
4815
+ await sandbox.stop();
4816
+ } catch {}
4817
+ }
4818
+ }
4819
+ }
4820
+
4821
+ // ../utils/env.ts
4822
+ function getEnv(key) {
4823
+ try {
4824
+ const getImportMeta = new Function('return typeof import.meta !== "undefined" ? import.meta : undefined');
4825
+ const importMeta = getImportMeta();
4826
+ if (importMeta && typeof importMeta.env === "object" && importMeta.env !== null) {
4827
+ const value = importMeta.env[key];
4828
+ if (value !== undefined && value !== null && value !== "") {
4829
+ return String(value);
4830
+ }
4831
+ }
4832
+ } catch {}
4833
+ if (typeof process !== "undefined" && process.env) {
4834
+ const value = process.env[key];
4835
+ if (value !== undefined && value !== null && value !== "") {
4836
+ return value;
4837
+ }
4838
+ }
4839
+ return;
4840
+ }
4841
+
4842
+ // ../code-mode/tool-builder.ts
4843
+ var CODE_MODE_TOOL_NAME = "execute_code";
4844
+ var DEFAULT_INSTRUCTIONS = [
4845
+ "You are given a single tool: `execute_code`. Instead of calling individual MCP tools,",
4846
+ "you write a short async TypeScript/JavaScript snippet that uses the typed `client`",
4847
+ "object below, and the snippet runs in an isolated sandbox which dispatches the actual",
4848
+ "tool calls. Chain multiple operations together in one snippet whenever possible —",
4849
+ "that is the whole point of this tool.",
4850
+ "",
4851
+ "Rules:",
4852
+ "- The snippet is the body of an `async` function. Use `await` freely.",
4853
+ "- Use `return <value>` at the end to hand a structured result back to the caller;",
4854
+ " the caller receives it as JSON.",
4855
+ "- Use `console.log(...)` for intermediate observations you want to read later.",
4856
+ "- Throw / let errors propagate; the runtime will surface them with a non-zero exit.",
4857
+ "- Each method call returns an object of shape `ToolResult` (see types below).",
4858
+ " The payload usually lives in `result.content[0].text` as JSON — parse it if needed.",
4859
+ "- You cannot import npm packages. Only the pre-imported `client` and standard",
4860
+ " globals (`fetch`, `console`, `JSON`, ...) are available.",
4861
+ "",
4862
+ "API surface:"
4863
+ ].join(`
4864
+ `);
4865
+ function resolveCodeModeClientConfig(client) {
4866
+ const oauthConfig = client.__oauthConfig;
4867
+ return oauthConfig?.codeMode ?? {};
4868
+ }
4869
+ function buildCodeModeTool(client, options) {
4870
+ const { tools, providerTokens, context, integrationIds } = options;
4871
+ const generated = generateCodeModeTypes(tools);
4872
+ const serverCodeModeConfig = resolveCodeModeClientConfig(client);
4873
+ const sandboxOverrides = options.sandbox ?? {};
4874
+ const description = `${DEFAULT_INSTRUCTIONS}
4875
+
4876
+ \`\`\`typescript
4877
+ ${generated.source}
4878
+ \`\`\``;
4879
+ const execute = async ({ code }) => {
4880
+ const publicUrl = sandboxOverrides.publicUrl ?? serverCodeModeConfig.publicUrl ?? getEnv("INTEGRATE_PUBLIC_URL");
4881
+ if (!publicUrl) {
4882
+ return {
4883
+ success: false,
4884
+ exitCode: -1,
4885
+ stdout: "",
4886
+ stderr: "",
4887
+ durationMs: 0,
4888
+ 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."
4889
+ };
4890
+ }
4891
+ const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
4892
+ return executeSandboxCode({
4893
+ code,
4894
+ mcpUrl,
4895
+ providerTokens,
4896
+ context,
4897
+ integrationsHeader: integrationIds && integrationIds.length > 0 ? integrationIds.join(",") : undefined,
4898
+ runtime: sandboxOverrides.runtime ?? serverCodeModeConfig.runtime,
4899
+ timeoutMs: sandboxOverrides.timeoutMs ?? serverCodeModeConfig.timeoutMs,
4900
+ vcpus: sandboxOverrides.vcpus ?? serverCodeModeConfig.vcpus,
4901
+ networkPolicy: sandboxOverrides.networkPolicy ?? serverCodeModeConfig.networkPolicy
4902
+ });
4903
+ };
4904
+ return {
4905
+ name: CODE_MODE_TOOL_NAME,
4906
+ description,
4907
+ parameters: {
4908
+ type: "object",
4909
+ properties: {
4910
+ code: {
4911
+ type: "string",
4912
+ 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."
4913
+ }
4914
+ },
4915
+ required: ["code"],
4916
+ additionalProperties: false
4917
+ },
4918
+ execute
4919
+ };
4920
+ }
4921
+
4405
4922
  // google.ts
4406
4923
  import { zodToJsonSchema } from "zod-to-json-schema";
4407
4924
  async function getGoogleType() {
@@ -4485,13 +5002,29 @@ async function executeGoogleFunctionCalls(client, functionCalls, options) {
4485
5002
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
4486
5003
  const triggerConfig = client.__triggerConfig;
4487
5004
  const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
5005
+ let cachedCodeModeTool = null;
5006
+ const getCodeModeTool = async () => {
5007
+ if (cachedCodeModeTool)
5008
+ return cachedCodeModeTool;
5009
+ const mcpTools = await client.getEnabledToolsAsync();
5010
+ cachedCodeModeTool = buildCodeModeTool(client, {
5011
+ tools: mcpTools,
5012
+ providerTokens: finalOptions?.providerTokens,
5013
+ context: options?.context,
5014
+ integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
5015
+ });
5016
+ return cachedCodeModeTool;
5017
+ };
4488
5018
  const results = await Promise.all(functionCalls.map(async (call) => {
4489
5019
  if (!call?.name) {
4490
5020
  throw new Error("Function call must have a name");
4491
5021
  }
4492
5022
  const args = call.args || {};
4493
5023
  let result;
4494
- if (triggerTools && triggerTools[call.name]) {
5024
+ if (call.name === CODE_MODE_TOOL_NAME) {
5025
+ const codeTool = await getCodeModeTool();
5026
+ result = await codeTool.execute(args);
5027
+ } else if (triggerTools && triggerTools[call.name]) {
4495
5028
  result = await triggerTools[call.name].execute(args);
4496
5029
  } else {
4497
5030
  result = await executeToolWithToken(client, call.name, args, finalOptions);
@@ -4510,7 +5043,33 @@ async function getGoogleTools(client, options) {
4510
5043
  const finalOptions = providerTokens ? { ...options, providerTokens } : options;
4511
5044
  await ensureClientConnected(client);
4512
5045
  const mcpTools = await client.getEnabledToolsAsync();
4513
- const googleTools = await Promise.all(mcpTools.map((mcpTool) => convertMCPToolToGoogle(mcpTool, client, finalOptions)));
5046
+ const mode = options?.mode ?? "code";
5047
+ let googleTools;
5048
+ if (mode === "code") {
5049
+ const TypeEnum = await getGoogleType();
5050
+ const codeTool = buildCodeModeTool(client, {
5051
+ tools: mcpTools,
5052
+ providerTokens,
5053
+ context: options?.context,
5054
+ integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
5055
+ });
5056
+ googleTools = [{
5057
+ name: CODE_MODE_TOOL_NAME,
5058
+ description: codeTool.description,
5059
+ parameters: {
5060
+ type: TypeEnum.OBJECT,
5061
+ properties: {
5062
+ code: {
5063
+ type: TypeEnum.STRING,
5064
+ description: codeTool.parameters.properties.code.description
5065
+ }
5066
+ },
5067
+ required: ["code"]
5068
+ }
5069
+ }];
5070
+ } else {
5071
+ googleTools = await Promise.all(mcpTools.map((mcpTool) => convertMCPToolToGoogle(mcpTool, client, finalOptions)));
5072
+ }
4514
5073
  const triggerConfig = client.__triggerConfig;
4515
5074
  if (triggerConfig) {
4516
5075
  const triggerTools = createTriggerTools(triggerConfig, options?.context);