integrate-sdk 0.9.2-dev.0 → 0.9.4-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/auto-routes.d.ts.map +1 -1
- package/dist/adapters/auto-routes.js +727 -17
- package/dist/adapters/base-handler.d.ts.map +1 -1
- package/dist/adapters/index.js +722 -16
- package/dist/adapters/nextjs.d.ts.map +1 -1
- package/dist/adapters/nextjs.js +722 -16
- package/dist/adapters/node.js +722 -16
- package/dist/adapters/svelte-kit.js +722 -16
- package/dist/adapters/tanstack-start.js +722 -16
- package/dist/ai/anthropic.d.ts +11 -0
- package/dist/ai/anthropic.d.ts.map +1 -1
- package/dist/ai/anthropic.js +552 -2
- package/dist/ai/google.d.ts +11 -0
- package/dist/ai/google.d.ts.map +1 -1
- package/dist/ai/google.js +561 -2
- package/dist/ai/index.js +648 -8
- package/dist/ai/openai.d.ts +11 -0
- package/dist/ai/openai.d.ts.map +1 -1
- package/dist/ai/openai.js +550 -2
- package/dist/ai/vercel-ai.d.ts +13 -0
- package/dist/ai/vercel-ai.d.ts.map +1 -1
- package/dist/ai/vercel-ai.js +536 -2
- package/dist/code-mode/executor.d.ts +99 -0
- package/dist/code-mode/executor.d.ts.map +1 -0
- package/dist/code-mode/executor.js +207 -0
- package/dist/code-mode/index.d.ts +12 -0
- package/dist/code-mode/index.d.ts.map +1 -0
- package/dist/code-mode/index.js +527 -0
- package/dist/code-mode/runtime-stub.d.ts +16 -0
- package/dist/code-mode/runtime-stub.d.ts.map +1 -0
- package/dist/code-mode/runtime-stub.js +72 -0
- package/dist/code-mode/tool-builder.d.ts +83 -0
- package/dist/code-mode/tool-builder.d.ts.map +1 -0
- package/dist/code-mode/tool-builder.js +524 -0
- package/dist/code-mode/type-generator.d.ts +22 -0
- package/dist/code-mode/type-generator.d.ts.map +1 -0
- package/dist/code-mode/type-generator.js +217 -0
- package/dist/index.js +722 -16
- package/dist/oauth.js +727 -17
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +733 -17
- package/dist/src/adapters/auto-routes.d.ts.map +1 -1
- package/dist/src/adapters/base-handler.d.ts.map +1 -1
- package/dist/src/adapters/nextjs.d.ts.map +1 -1
- package/dist/src/ai/anthropic.d.ts +11 -0
- package/dist/src/ai/anthropic.d.ts.map +1 -1
- package/dist/src/ai/google.d.ts +11 -0
- package/dist/src/ai/google.d.ts.map +1 -1
- package/dist/src/ai/openai.d.ts +11 -0
- package/dist/src/ai/openai.d.ts.map +1 -1
- package/dist/src/ai/vercel-ai.d.ts +13 -0
- package/dist/src/ai/vercel-ai.d.ts.map +1 -1
- package/dist/src/code-mode/executor.d.ts +99 -0
- package/dist/src/code-mode/executor.d.ts.map +1 -0
- package/dist/src/code-mode/index.d.ts +12 -0
- package/dist/src/code-mode/index.d.ts.map +1 -0
- package/dist/src/code-mode/runtime-stub.d.ts +16 -0
- package/dist/src/code-mode/runtime-stub.d.ts.map +1 -0
- package/dist/src/code-mode/tool-builder.d.ts +83 -0
- package/dist/src/code-mode/tool-builder.d.ts.map +1 -0
- package/dist/src/code-mode/type-generator.d.ts +22 -0
- package/dist/src/code-mode/type-generator.d.ts.map +1 -0
- package/dist/src/config/types.d.ts +55 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/package.json +15 -6
- package/server.ts +9 -0
package/dist/server.js
CHANGED
|
@@ -405,10 +405,17 @@ var init_errors = __esm(() => {
|
|
|
405
405
|
function camelToSnake(str) {
|
|
406
406
|
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
407
407
|
}
|
|
408
|
+
function snakeToCamel(str) {
|
|
409
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
410
|
+
}
|
|
408
411
|
function methodToToolName(methodName, integrationId) {
|
|
409
412
|
const snakeCaseMethod = camelToSnake(methodName);
|
|
410
413
|
return `${integrationId}_${snakeCaseMethod}`;
|
|
411
414
|
}
|
|
415
|
+
function toolNameToMethod(toolName) {
|
|
416
|
+
const withoutPrefix = toolName.replace(/^[^_]+_/, "");
|
|
417
|
+
return snakeToCamel(withoutPrefix);
|
|
418
|
+
}
|
|
412
419
|
|
|
413
420
|
// src/triggers/client.ts
|
|
414
421
|
class TriggerClient {
|
|
@@ -3162,6 +3169,10 @@ class OAuthHandler {
|
|
|
3162
3169
|
});
|
|
3163
3170
|
if (!response.ok) {
|
|
3164
3171
|
const error = await response.text();
|
|
3172
|
+
const lowerError = error.toLowerCase();
|
|
3173
|
+
if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
|
|
3174
|
+
throw new Error(`Token refresh not supported: ${error}`);
|
|
3175
|
+
}
|
|
3165
3176
|
throw new Error(`Token refresh failed: ${error}`);
|
|
3166
3177
|
}
|
|
3167
3178
|
const data = await response.json();
|
|
@@ -3324,7 +3335,11 @@ function createNextOAuthHandler(config) {
|
|
|
3324
3335
|
}
|
|
3325
3336
|
return response;
|
|
3326
3337
|
} catch (error) {
|
|
3327
|
-
|
|
3338
|
+
if (error.message?.toLowerCase().includes("not supported")) {
|
|
3339
|
+
logger7.info("[OAuth Refresh] Not supported for this provider:", error.message);
|
|
3340
|
+
} else {
|
|
3341
|
+
logger7.error("[OAuth Refresh] Error:", error);
|
|
3342
|
+
}
|
|
3328
3343
|
return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
|
|
3329
3344
|
}
|
|
3330
3345
|
},
|
|
@@ -9229,6 +9244,508 @@ var init_trigger_tools = __esm(() => {
|
|
|
9229
9244
|
init_utils2();
|
|
9230
9245
|
});
|
|
9231
9246
|
|
|
9247
|
+
// src/code-mode/type-generator.ts
|
|
9248
|
+
function safeIdent(name) {
|
|
9249
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) || RESERVED_TS.has(name)) {
|
|
9250
|
+
return JSON.stringify(name);
|
|
9251
|
+
}
|
|
9252
|
+
return name;
|
|
9253
|
+
}
|
|
9254
|
+
function integrationFromToolName(toolName) {
|
|
9255
|
+
const idx = toolName.indexOf("_");
|
|
9256
|
+
return idx === -1 ? toolName : toolName.slice(0, idx);
|
|
9257
|
+
}
|
|
9258
|
+
function jsonSchemaToTs(schema, indent) {
|
|
9259
|
+
if (!schema || typeof schema !== "object")
|
|
9260
|
+
return "unknown";
|
|
9261
|
+
const s = schema;
|
|
9262
|
+
if (Array.isArray(s.enum) && s.enum.length > 0) {
|
|
9263
|
+
return s.enum.map((v) => typeof v === "string" ? JSON.stringify(v) : typeof v === "number" || typeof v === "boolean" ? String(v) : "unknown").join(" | ");
|
|
9264
|
+
}
|
|
9265
|
+
if (Array.isArray(s.type)) {
|
|
9266
|
+
return s.type.map((t2) => jsonSchemaToTs({ ...s, type: t2 }, indent)).join(" | ");
|
|
9267
|
+
}
|
|
9268
|
+
const t = s.type;
|
|
9269
|
+
switch (t) {
|
|
9270
|
+
case "string":
|
|
9271
|
+
return "string";
|
|
9272
|
+
case "number":
|
|
9273
|
+
case "integer":
|
|
9274
|
+
return "number";
|
|
9275
|
+
case "boolean":
|
|
9276
|
+
return "boolean";
|
|
9277
|
+
case "null":
|
|
9278
|
+
return "null";
|
|
9279
|
+
case "array": {
|
|
9280
|
+
const items = s.items;
|
|
9281
|
+
if (Array.isArray(items))
|
|
9282
|
+
return "unknown[]";
|
|
9283
|
+
const inner = jsonSchemaToTs(items, indent);
|
|
9284
|
+
return /[|&]/.test(inner) ? `Array<${inner}>` : `${inner}[]`;
|
|
9285
|
+
}
|
|
9286
|
+
case "object":
|
|
9287
|
+
return objectShape(s, indent);
|
|
9288
|
+
default:
|
|
9289
|
+
if (s.properties && typeof s.properties === "object")
|
|
9290
|
+
return objectShape(s, indent);
|
|
9291
|
+
return "unknown";
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
9294
|
+
function objectShape(schema, indent) {
|
|
9295
|
+
const props = schema.properties && typeof schema.properties === "object" ? schema.properties : {};
|
|
9296
|
+
const keys = Object.keys(props);
|
|
9297
|
+
if (keys.length === 0) {
|
|
9298
|
+
return schema.additionalProperties === false ? "Record<string, never>" : "Record<string, unknown>";
|
|
9299
|
+
}
|
|
9300
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
9301
|
+
const inner = indent + " ";
|
|
9302
|
+
const lines = ["{"];
|
|
9303
|
+
for (const key of keys) {
|
|
9304
|
+
const prop = props[key];
|
|
9305
|
+
const desc = prop && typeof prop.description === "string" ? prop.description : undefined;
|
|
9306
|
+
if (desc)
|
|
9307
|
+
lines.push(`${inner}/** ${desc.replace(/\*\//g, "*\\/")} */`);
|
|
9308
|
+
const optional = required.has(key) ? "" : "?";
|
|
9309
|
+
const type = jsonSchemaToTs(prop, inner);
|
|
9310
|
+
lines.push(`${inner}${safeIdent(key)}${optional}: ${type};`);
|
|
9311
|
+
}
|
|
9312
|
+
lines.push(`${indent}}`);
|
|
9313
|
+
return lines.join(`
|
|
9314
|
+
`);
|
|
9315
|
+
}
|
|
9316
|
+
function argsType(schema) {
|
|
9317
|
+
if (!schema)
|
|
9318
|
+
return "Record<string, unknown>";
|
|
9319
|
+
const hasProps = schema.properties && Object.keys(schema.properties).length > 0;
|
|
9320
|
+
if (!hasProps)
|
|
9321
|
+
return "Record<string, unknown>";
|
|
9322
|
+
return objectShape(schema, " ");
|
|
9323
|
+
}
|
|
9324
|
+
function methodHasRequiredArgs(schema) {
|
|
9325
|
+
if (!schema || !schema.properties)
|
|
9326
|
+
return false;
|
|
9327
|
+
const req = Array.isArray(schema.required) ? schema.required : [];
|
|
9328
|
+
return req.length > 0;
|
|
9329
|
+
}
|
|
9330
|
+
function formatDescription(desc, indent) {
|
|
9331
|
+
if (!desc)
|
|
9332
|
+
return "";
|
|
9333
|
+
const cleaned = desc.replace(/\*\//g, "*\\/").trim();
|
|
9334
|
+
if (!cleaned.includes(`
|
|
9335
|
+
`))
|
|
9336
|
+
return `${indent}/** ${cleaned} */
|
|
9337
|
+
`;
|
|
9338
|
+
const lines = cleaned.split(`
|
|
9339
|
+
`).map((l) => `${indent} * ${l}`).join(`
|
|
9340
|
+
`);
|
|
9341
|
+
return `${indent}/**
|
|
9342
|
+
${lines}
|
|
9343
|
+
${indent} */
|
|
9344
|
+
`;
|
|
9345
|
+
}
|
|
9346
|
+
function generateCodeModeTypes(tools) {
|
|
9347
|
+
const byIntegration = {};
|
|
9348
|
+
for (const tool of tools) {
|
|
9349
|
+
const integration = integrationFromToolName(tool.name);
|
|
9350
|
+
(byIntegration[integration] ??= []).push(tool);
|
|
9351
|
+
}
|
|
9352
|
+
const methodMap = {};
|
|
9353
|
+
const integrationCounts = {};
|
|
9354
|
+
const sections = [];
|
|
9355
|
+
const integrationIds = Object.keys(byIntegration).sort();
|
|
9356
|
+
sections.push("/**");
|
|
9357
|
+
sections.push(" * Integrate SDK — available APIs inside `execute_code`.");
|
|
9358
|
+
sections.push(" * Every method is async and returns the MCP tool-call response.");
|
|
9359
|
+
sections.push(" * Call them via the exported `client` object, e.g.");
|
|
9360
|
+
sections.push(" * const repos = await client.github.listRepos();");
|
|
9361
|
+
sections.push(" */");
|
|
9362
|
+
sections.push("");
|
|
9363
|
+
for (const integrationId of integrationIds) {
|
|
9364
|
+
const integrationTools = byIntegration[integrationId].slice().sort((a, b) => a.name.localeCompare(b.name));
|
|
9365
|
+
integrationCounts[integrationId] = integrationTools.length;
|
|
9366
|
+
const interfaceName = pascalCase(integrationId) + "Client";
|
|
9367
|
+
sections.push(`export interface ${interfaceName} {`);
|
|
9368
|
+
for (const tool of integrationTools) {
|
|
9369
|
+
const methodName = toolNameToMethod(tool.name);
|
|
9370
|
+
methodMap[`${integrationId}.${methodName}`] = tool.name;
|
|
9371
|
+
sections.push(formatDescription(tool.description, " "));
|
|
9372
|
+
const argType = argsType(tool.inputSchema);
|
|
9373
|
+
const argIsOptional = !methodHasRequiredArgs(tool.inputSchema);
|
|
9374
|
+
const paramName = argIsOptional ? "args?" : "args";
|
|
9375
|
+
sections.push(` ${safeIdent(methodName)}(${paramName}: ${argType}): Promise<ToolResult>;`);
|
|
9376
|
+
}
|
|
9377
|
+
sections.push("}");
|
|
9378
|
+
sections.push("");
|
|
9379
|
+
}
|
|
9380
|
+
sections.push("export interface ToolResult {");
|
|
9381
|
+
sections.push(" content: Array<{ type: 'text' | 'image' | 'resource'; text?: string; data?: string; mimeType?: string; [key: string]: unknown }>;");
|
|
9382
|
+
sections.push(" isError?: boolean;");
|
|
9383
|
+
sections.push(" structuredContent?: Record<string, unknown>;");
|
|
9384
|
+
sections.push("}");
|
|
9385
|
+
sections.push("");
|
|
9386
|
+
sections.push("export interface Client {");
|
|
9387
|
+
for (const integrationId of integrationIds) {
|
|
9388
|
+
const interfaceName = pascalCase(integrationId) + "Client";
|
|
9389
|
+
sections.push(` ${safeIdent(integrationId)}: ${interfaceName};`);
|
|
9390
|
+
}
|
|
9391
|
+
sections.push("}");
|
|
9392
|
+
sections.push("");
|
|
9393
|
+
sections.push("export declare const client: Client;");
|
|
9394
|
+
return {
|
|
9395
|
+
source: sections.filter((line, idx, arr) => !(line === "" && arr[idx - 1] === "")).join(`
|
|
9396
|
+
`),
|
|
9397
|
+
methodMap,
|
|
9398
|
+
integrationCounts
|
|
9399
|
+
};
|
|
9400
|
+
}
|
|
9401
|
+
function pascalCase(id) {
|
|
9402
|
+
return id.split(/[^A-Za-z0-9]/).filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("") || "Unknown";
|
|
9403
|
+
}
|
|
9404
|
+
var RESERVED_TS;
|
|
9405
|
+
var init_type_generator = __esm(() => {
|
|
9406
|
+
RESERVED_TS = new Set([
|
|
9407
|
+
"break",
|
|
9408
|
+
"case",
|
|
9409
|
+
"catch",
|
|
9410
|
+
"class",
|
|
9411
|
+
"const",
|
|
9412
|
+
"continue",
|
|
9413
|
+
"debugger",
|
|
9414
|
+
"default",
|
|
9415
|
+
"delete",
|
|
9416
|
+
"do",
|
|
9417
|
+
"else",
|
|
9418
|
+
"enum",
|
|
9419
|
+
"export",
|
|
9420
|
+
"extends",
|
|
9421
|
+
"false",
|
|
9422
|
+
"finally",
|
|
9423
|
+
"for",
|
|
9424
|
+
"function",
|
|
9425
|
+
"if",
|
|
9426
|
+
"import",
|
|
9427
|
+
"in",
|
|
9428
|
+
"instanceof",
|
|
9429
|
+
"new",
|
|
9430
|
+
"null",
|
|
9431
|
+
"return",
|
|
9432
|
+
"super",
|
|
9433
|
+
"switch",
|
|
9434
|
+
"this",
|
|
9435
|
+
"throw",
|
|
9436
|
+
"true",
|
|
9437
|
+
"try",
|
|
9438
|
+
"typeof",
|
|
9439
|
+
"var",
|
|
9440
|
+
"void",
|
|
9441
|
+
"while",
|
|
9442
|
+
"with",
|
|
9443
|
+
"as",
|
|
9444
|
+
"implements",
|
|
9445
|
+
"interface",
|
|
9446
|
+
"let",
|
|
9447
|
+
"package",
|
|
9448
|
+
"private",
|
|
9449
|
+
"protected",
|
|
9450
|
+
"public",
|
|
9451
|
+
"static",
|
|
9452
|
+
"yield"
|
|
9453
|
+
]);
|
|
9454
|
+
});
|
|
9455
|
+
|
|
9456
|
+
// src/code-mode/runtime-stub.ts
|
|
9457
|
+
var RUNTIME_STUB_SOURCE = `// runtime.mjs — generated by integrate-sdk code mode
|
|
9458
|
+
const MCP_URL = process.env.INTEGRATE_MCP_URL;
|
|
9459
|
+
const SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;
|
|
9460
|
+
const PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';
|
|
9461
|
+
const INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';
|
|
9462
|
+
const CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';
|
|
9463
|
+
|
|
9464
|
+
if (!MCP_URL) {
|
|
9465
|
+
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
9466
|
+
}
|
|
9467
|
+
|
|
9468
|
+
function camelToSnake(str) {
|
|
9469
|
+
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
9470
|
+
}
|
|
9471
|
+
|
|
9472
|
+
async function callTool(toolName, args) {
|
|
9473
|
+
const headers = {
|
|
9474
|
+
'Content-Type': 'application/json',
|
|
9475
|
+
'x-integrate-code-mode': '1',
|
|
9476
|
+
};
|
|
9477
|
+
if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;
|
|
9478
|
+
if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;
|
|
9479
|
+
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
9480
|
+
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
9481
|
+
|
|
9482
|
+
const res = await fetch(MCP_URL, {
|
|
9483
|
+
method: 'POST',
|
|
9484
|
+
headers,
|
|
9485
|
+
body: JSON.stringify({ name: toolName, arguments: args || {} }),
|
|
9486
|
+
});
|
|
9487
|
+
|
|
9488
|
+
const text = await res.text();
|
|
9489
|
+
let payload;
|
|
9490
|
+
try {
|
|
9491
|
+
payload = text ? JSON.parse(text) : null;
|
|
9492
|
+
} catch {
|
|
9493
|
+
payload = { content: [{ type: 'text', text }] };
|
|
9494
|
+
}
|
|
9495
|
+
|
|
9496
|
+
if (!res.ok) {
|
|
9497
|
+
const message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;
|
|
9498
|
+
const err = new Error(message);
|
|
9499
|
+
err.status = res.status;
|
|
9500
|
+
err.toolName = toolName;
|
|
9501
|
+
throw err;
|
|
9502
|
+
}
|
|
9503
|
+
|
|
9504
|
+
return payload;
|
|
9505
|
+
}
|
|
9506
|
+
|
|
9507
|
+
function createIntegrationProxy(integrationId) {
|
|
9508
|
+
return new Proxy({}, {
|
|
9509
|
+
get(_target, methodName) {
|
|
9510
|
+
if (typeof methodName !== 'string') return undefined;
|
|
9511
|
+
return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);
|
|
9512
|
+
},
|
|
9513
|
+
});
|
|
9514
|
+
}
|
|
9515
|
+
|
|
9516
|
+
export const client = new Proxy({}, {
|
|
9517
|
+
get(_target, integrationId) {
|
|
9518
|
+
if (typeof integrationId !== 'string') return undefined;
|
|
9519
|
+
return createIntegrationProxy(integrationId);
|
|
9520
|
+
},
|
|
9521
|
+
});
|
|
9522
|
+
|
|
9523
|
+
export { callTool };
|
|
9524
|
+
`;
|
|
9525
|
+
|
|
9526
|
+
// src/code-mode/executor.ts
|
|
9527
|
+
var exports_executor = {};
|
|
9528
|
+
__export(exports_executor, {
|
|
9529
|
+
executeSandboxCode: () => executeSandboxCode,
|
|
9530
|
+
__setSandboxFactoryForTests: () => __setSandboxFactoryForTests
|
|
9531
|
+
});
|
|
9532
|
+
function __setSandboxFactoryForTests(factory) {
|
|
9533
|
+
sandboxFactoryOverride = factory;
|
|
9534
|
+
}
|
|
9535
|
+
async function loadSandboxFactory() {
|
|
9536
|
+
if (sandboxFactoryOverride)
|
|
9537
|
+
return sandboxFactoryOverride;
|
|
9538
|
+
try {
|
|
9539
|
+
const dynamicImport = new Function("specifier", "return import(specifier)");
|
|
9540
|
+
const pkg = "@" + "vercel/sandbox";
|
|
9541
|
+
const mod = await dynamicImport(pkg);
|
|
9542
|
+
return mod.Sandbox ?? mod.default?.Sandbox ?? mod;
|
|
9543
|
+
} catch (err) {
|
|
9544
|
+
throw new Error("Code Mode requires the optional peer dependency `@vercel/sandbox`. " + "Install it with `npm install @vercel/sandbox` (or `bun add @vercel/sandbox`).");
|
|
9545
|
+
}
|
|
9546
|
+
}
|
|
9547
|
+
function wrapUserCode(code) {
|
|
9548
|
+
return `// user.mjs — wrapped by integrate-sdk code mode
|
|
9549
|
+
import { client, callTool } from './runtime.mjs';
|
|
9550
|
+
|
|
9551
|
+
(async () => {
|
|
9552
|
+
try {
|
|
9553
|
+
const __result = await (async () => {
|
|
9554
|
+
${code}
|
|
9555
|
+
})();
|
|
9556
|
+
if (typeof __result !== 'undefined') {
|
|
9557
|
+
process.stdout.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify(__result) + '\\n');
|
|
9558
|
+
}
|
|
9559
|
+
} catch (err) {
|
|
9560
|
+
const payload = {
|
|
9561
|
+
message: err && err.message ? err.message : String(err),
|
|
9562
|
+
name: err && err.name,
|
|
9563
|
+
stack: err && err.stack,
|
|
9564
|
+
toolName: err && err.toolName,
|
|
9565
|
+
status: err && err.status,
|
|
9566
|
+
};
|
|
9567
|
+
process.stderr.write('\\n' + ${JSON.stringify(RESULT_SENTINEL)} + JSON.stringify({ error: payload }) + '\\n');
|
|
9568
|
+
process.exit(1);
|
|
9569
|
+
}
|
|
9570
|
+
})();
|
|
9571
|
+
`;
|
|
9572
|
+
}
|
|
9573
|
+
function defaultNetworkPolicy(mcpUrl) {
|
|
9574
|
+
try {
|
|
9575
|
+
const host = new URL(mcpUrl).hostname;
|
|
9576
|
+
return { allow: [host] };
|
|
9577
|
+
} catch {
|
|
9578
|
+
return { allow: [] };
|
|
9579
|
+
}
|
|
9580
|
+
}
|
|
9581
|
+
function extractResult(stream) {
|
|
9582
|
+
const idx = stream.lastIndexOf(RESULT_SENTINEL);
|
|
9583
|
+
if (idx === -1)
|
|
9584
|
+
return { cleaned: stream };
|
|
9585
|
+
const before = stream.slice(0, idx).replace(/\n$/, "");
|
|
9586
|
+
const rest = stream.slice(idx + RESULT_SENTINEL.length);
|
|
9587
|
+
const newlineIdx = rest.indexOf(`
|
|
9588
|
+
`);
|
|
9589
|
+
const payload = newlineIdx === -1 ? rest : rest.slice(0, newlineIdx);
|
|
9590
|
+
const after = newlineIdx === -1 ? "" : rest.slice(newlineIdx + 1);
|
|
9591
|
+
try {
|
|
9592
|
+
return { cleaned: (before + after).trimEnd(), result: JSON.parse(payload) };
|
|
9593
|
+
} catch {
|
|
9594
|
+
return { cleaned: stream };
|
|
9595
|
+
}
|
|
9596
|
+
}
|
|
9597
|
+
async function executeSandboxCode(options) {
|
|
9598
|
+
const startedAt = Date.now();
|
|
9599
|
+
const runtime = options.runtime ?? "node22";
|
|
9600
|
+
const timeoutMs = options.timeoutMs ?? 60000;
|
|
9601
|
+
const networkPolicy = options.networkPolicy ?? defaultNetworkPolicy(options.mcpUrl);
|
|
9602
|
+
let sandbox = null;
|
|
9603
|
+
try {
|
|
9604
|
+
const Sandbox = await loadSandboxFactory();
|
|
9605
|
+
sandbox = await Sandbox.create({
|
|
9606
|
+
runtime,
|
|
9607
|
+
timeout: timeoutMs,
|
|
9608
|
+
resources: options.vcpus ? { vcpus: options.vcpus } : undefined,
|
|
9609
|
+
networkPolicy
|
|
9610
|
+
});
|
|
9611
|
+
const runtimeContent = Buffer.from(RUNTIME_STUB_SOURCE, "utf-8");
|
|
9612
|
+
const userContent = Buffer.from(wrapUserCode(options.code), "utf-8");
|
|
9613
|
+
await sandbox.writeFiles([
|
|
9614
|
+
{ path: "runtime.mjs", content: runtimeContent },
|
|
9615
|
+
{ path: "user.mjs", content: userContent }
|
|
9616
|
+
]);
|
|
9617
|
+
const env = {
|
|
9618
|
+
INTEGRATE_MCP_URL: options.mcpUrl
|
|
9619
|
+
};
|
|
9620
|
+
if (options.sessionToken)
|
|
9621
|
+
env.INTEGRATE_SESSION_TOKEN = options.sessionToken;
|
|
9622
|
+
if (options.providerTokens && Object.keys(options.providerTokens).length > 0) {
|
|
9623
|
+
env.INTEGRATE_PROVIDER_TOKENS = JSON.stringify(options.providerTokens);
|
|
9624
|
+
}
|
|
9625
|
+
if (options.integrationsHeader)
|
|
9626
|
+
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
9627
|
+
if (options.context)
|
|
9628
|
+
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
9629
|
+
const cmd = await sandbox.runCommand({
|
|
9630
|
+
cmd: "node",
|
|
9631
|
+
args: ["user.mjs"],
|
|
9632
|
+
env
|
|
9633
|
+
});
|
|
9634
|
+
const [stdoutRaw, stderrRaw] = await Promise.all([cmd.stdout(), cmd.stderr()]);
|
|
9635
|
+
const stdoutExtract = extractResult(stdoutRaw);
|
|
9636
|
+
const stderrExtract = extractResult(stderrRaw);
|
|
9637
|
+
return {
|
|
9638
|
+
success: cmd.exitCode === 0,
|
|
9639
|
+
exitCode: cmd.exitCode,
|
|
9640
|
+
result: stdoutExtract.result ?? stderrExtract.result,
|
|
9641
|
+
stdout: stdoutExtract.cleaned,
|
|
9642
|
+
stderr: stderrExtract.cleaned,
|
|
9643
|
+
durationMs: Date.now() - startedAt
|
|
9644
|
+
};
|
|
9645
|
+
} catch (err) {
|
|
9646
|
+
return {
|
|
9647
|
+
success: false,
|
|
9648
|
+
exitCode: -1,
|
|
9649
|
+
stdout: "",
|
|
9650
|
+
stderr: "",
|
|
9651
|
+
durationMs: Date.now() - startedAt,
|
|
9652
|
+
error: err instanceof Error ? err.message : String(err)
|
|
9653
|
+
};
|
|
9654
|
+
} finally {
|
|
9655
|
+
if (sandbox) {
|
|
9656
|
+
try {
|
|
9657
|
+
await sandbox.stop();
|
|
9658
|
+
} catch {}
|
|
9659
|
+
}
|
|
9660
|
+
}
|
|
9661
|
+
}
|
|
9662
|
+
var sandboxFactoryOverride = null, RESULT_SENTINEL = "__INTEGRATE_RESULT__";
|
|
9663
|
+
var init_executor = () => {};
|
|
9664
|
+
|
|
9665
|
+
// src/code-mode/tool-builder.ts
|
|
9666
|
+
function resolveCodeModeClientConfig(client) {
|
|
9667
|
+
const oauthConfig = client.__oauthConfig;
|
|
9668
|
+
return oauthConfig?.codeMode ?? {};
|
|
9669
|
+
}
|
|
9670
|
+
function buildCodeModeTool(client, options) {
|
|
9671
|
+
const { tools, providerTokens, context, integrationIds } = options;
|
|
9672
|
+
const generated = generateCodeModeTypes(tools);
|
|
9673
|
+
const serverCodeModeConfig = resolveCodeModeClientConfig(client);
|
|
9674
|
+
const sandboxOverrides = options.sandbox ?? {};
|
|
9675
|
+
const description = `${DEFAULT_INSTRUCTIONS}
|
|
9676
|
+
|
|
9677
|
+
\`\`\`typescript
|
|
9678
|
+
${generated.source}
|
|
9679
|
+
\`\`\``;
|
|
9680
|
+
const execute = async ({ code }) => {
|
|
9681
|
+
const publicUrl = sandboxOverrides.publicUrl ?? serverCodeModeConfig.publicUrl ?? getEnv("INTEGRATE_PUBLIC_URL");
|
|
9682
|
+
if (!publicUrl) {
|
|
9683
|
+
return {
|
|
9684
|
+
success: false,
|
|
9685
|
+
exitCode: -1,
|
|
9686
|
+
stdout: "",
|
|
9687
|
+
stderr: "",
|
|
9688
|
+
durationMs: 0,
|
|
9689
|
+
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."
|
|
9690
|
+
};
|
|
9691
|
+
}
|
|
9692
|
+
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
9693
|
+
return executeSandboxCode({
|
|
9694
|
+
code,
|
|
9695
|
+
mcpUrl,
|
|
9696
|
+
providerTokens,
|
|
9697
|
+
context,
|
|
9698
|
+
integrationsHeader: integrationIds && integrationIds.length > 0 ? integrationIds.join(",") : undefined,
|
|
9699
|
+
runtime: sandboxOverrides.runtime ?? serverCodeModeConfig.runtime,
|
|
9700
|
+
timeoutMs: sandboxOverrides.timeoutMs ?? serverCodeModeConfig.timeoutMs,
|
|
9701
|
+
vcpus: sandboxOverrides.vcpus ?? serverCodeModeConfig.vcpus,
|
|
9702
|
+
networkPolicy: sandboxOverrides.networkPolicy ?? serverCodeModeConfig.networkPolicy
|
|
9703
|
+
});
|
|
9704
|
+
};
|
|
9705
|
+
return {
|
|
9706
|
+
name: CODE_MODE_TOOL_NAME,
|
|
9707
|
+
description,
|
|
9708
|
+
parameters: {
|
|
9709
|
+
type: "object",
|
|
9710
|
+
properties: {
|
|
9711
|
+
code: {
|
|
9712
|
+
type: "string",
|
|
9713
|
+
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."
|
|
9714
|
+
}
|
|
9715
|
+
},
|
|
9716
|
+
required: ["code"],
|
|
9717
|
+
additionalProperties: false
|
|
9718
|
+
},
|
|
9719
|
+
execute
|
|
9720
|
+
};
|
|
9721
|
+
}
|
|
9722
|
+
var CODE_MODE_TOOL_NAME = "execute_code", DEFAULT_INSTRUCTIONS;
|
|
9723
|
+
var init_tool_builder = __esm(() => {
|
|
9724
|
+
init_type_generator();
|
|
9725
|
+
init_executor();
|
|
9726
|
+
DEFAULT_INSTRUCTIONS = [
|
|
9727
|
+
"You are given a single tool: `execute_code`. Instead of calling individual MCP tools,",
|
|
9728
|
+
"you write a short async TypeScript/JavaScript snippet that uses the typed `client`",
|
|
9729
|
+
"object below, and the snippet runs in an isolated sandbox which dispatches the actual",
|
|
9730
|
+
"tool calls. Chain multiple operations together in one snippet whenever possible —",
|
|
9731
|
+
"that is the whole point of this tool.",
|
|
9732
|
+
"",
|
|
9733
|
+
"Rules:",
|
|
9734
|
+
"- The snippet is the body of an `async` function. Use `await` freely.",
|
|
9735
|
+
"- Use `return <value>` at the end to hand a structured result back to the caller;",
|
|
9736
|
+
" the caller receives it as JSON.",
|
|
9737
|
+
"- Use `console.log(...)` for intermediate observations you want to read later.",
|
|
9738
|
+
"- Throw / let errors propagate; the runtime will surface them with a non-zero exit.",
|
|
9739
|
+
"- Each method call returns an object of shape `ToolResult` (see types below).",
|
|
9740
|
+
" The payload usually lives in `result.content[0].text` as JSON — parse it if needed.",
|
|
9741
|
+
"- You cannot import npm packages. Only the pre-imported `client` and standard",
|
|
9742
|
+
" globals (`fetch`, `console`, `JSON`, ...) are available.",
|
|
9743
|
+
"",
|
|
9744
|
+
"API surface:"
|
|
9745
|
+
].join(`
|
|
9746
|
+
`);
|
|
9747
|
+
});
|
|
9748
|
+
|
|
9232
9749
|
// src/ai/vercel-ai.ts
|
|
9233
9750
|
function convertMCPToolToVercelAI(mcpTool, client, options) {
|
|
9234
9751
|
return {
|
|
@@ -9253,8 +9770,25 @@ async function getVercelAITools(client, options) {
|
|
|
9253
9770
|
await ensureClientConnected(client);
|
|
9254
9771
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
9255
9772
|
const vercelTools = {};
|
|
9256
|
-
|
|
9257
|
-
|
|
9773
|
+
const mode = options?.mode ?? "code";
|
|
9774
|
+
if (mode === "code") {
|
|
9775
|
+
const codeTool = buildCodeModeTool(client, {
|
|
9776
|
+
tools: mcpTools,
|
|
9777
|
+
providerTokens,
|
|
9778
|
+
context: options?.context,
|
|
9779
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id) ?? client.integrations?.map?.((i) => i.id)
|
|
9780
|
+
});
|
|
9781
|
+
vercelTools[CODE_MODE_TOOL_NAME] = {
|
|
9782
|
+
description: codeTool.description,
|
|
9783
|
+
inputSchema: exports_external.object({
|
|
9784
|
+
code: exports_external.string().describe(codeTool.parameters.properties.code.description)
|
|
9785
|
+
}),
|
|
9786
|
+
execute: async (args) => codeTool.execute(args)
|
|
9787
|
+
};
|
|
9788
|
+
} else {
|
|
9789
|
+
for (const mcpTool of mcpTools) {
|
|
9790
|
+
vercelTools[mcpTool.name] = convertMCPToolToVercelAI(mcpTool, client, finalOptions);
|
|
9791
|
+
}
|
|
9258
9792
|
}
|
|
9259
9793
|
const triggerConfig = client.__triggerConfig;
|
|
9260
9794
|
if (triggerConfig) {
|
|
@@ -9264,8 +9798,10 @@ async function getVercelAITools(client, options) {
|
|
|
9264
9798
|
return vercelTools;
|
|
9265
9799
|
}
|
|
9266
9800
|
var init_vercel_ai = __esm(() => {
|
|
9801
|
+
init_zod();
|
|
9267
9802
|
init_utils();
|
|
9268
9803
|
init_trigger_tools();
|
|
9804
|
+
init_tool_builder();
|
|
9269
9805
|
});
|
|
9270
9806
|
|
|
9271
9807
|
// node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
@@ -10693,7 +11229,22 @@ async function getOpenAITools(client, options) {
|
|
|
10693
11229
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10694
11230
|
await ensureClientConnected(client);
|
|
10695
11231
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10696
|
-
const
|
|
11232
|
+
const mode = options?.mode ?? "code";
|
|
11233
|
+
const openaiTools = mode === "code" ? (() => {
|
|
11234
|
+
const codeTool = buildCodeModeTool(client, {
|
|
11235
|
+
tools: mcpTools,
|
|
11236
|
+
providerTokens,
|
|
11237
|
+
context: options?.context,
|
|
11238
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11239
|
+
});
|
|
11240
|
+
return [{
|
|
11241
|
+
type: "function",
|
|
11242
|
+
name: CODE_MODE_TOOL_NAME,
|
|
11243
|
+
description: codeTool.description,
|
|
11244
|
+
parameters: codeTool.parameters,
|
|
11245
|
+
strict: options?.strict ?? null
|
|
11246
|
+
}];
|
|
11247
|
+
})() : mcpTools.map((mcpTool) => convertMCPToolToOpenAI(mcpTool, client, finalOptions));
|
|
10697
11248
|
const triggerConfig = client.__triggerConfig;
|
|
10698
11249
|
if (triggerConfig) {
|
|
10699
11250
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10718,6 +11269,19 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
|
|
|
10718
11269
|
const toolOutputs = [];
|
|
10719
11270
|
const triggerConfig = client.__triggerConfig;
|
|
10720
11271
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
11272
|
+
let cachedCodeModeTool = null;
|
|
11273
|
+
const getCodeModeTool = async () => {
|
|
11274
|
+
if (cachedCodeModeTool)
|
|
11275
|
+
return cachedCodeModeTool;
|
|
11276
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
11277
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
11278
|
+
tools: mcpTools,
|
|
11279
|
+
providerTokens: options?.providerTokens,
|
|
11280
|
+
context: options?.context,
|
|
11281
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11282
|
+
});
|
|
11283
|
+
return cachedCodeModeTool;
|
|
11284
|
+
};
|
|
10721
11285
|
for (const output of toolCalls) {
|
|
10722
11286
|
if (output.type === "function_call") {
|
|
10723
11287
|
const toolCall = {
|
|
@@ -10728,7 +11292,10 @@ async function handleOpenAIToolCalls(client, toolCalls, options) {
|
|
|
10728
11292
|
try {
|
|
10729
11293
|
const args = JSON.parse(toolCall.arguments);
|
|
10730
11294
|
let result;
|
|
10731
|
-
if (
|
|
11295
|
+
if (toolCall.name === CODE_MODE_TOOL_NAME) {
|
|
11296
|
+
const codeTool = await getCodeModeTool();
|
|
11297
|
+
result = await codeTool.execute(args);
|
|
11298
|
+
} else if (triggerTools && triggerTools[toolCall.name]) {
|
|
10732
11299
|
result = await triggerTools[toolCall.name].execute(args);
|
|
10733
11300
|
} else {
|
|
10734
11301
|
result = await executeToolWithToken(client, toolCall.name, args, options);
|
|
@@ -10769,6 +11336,7 @@ async function handleOpenAIResponse(client, response, options) {
|
|
|
10769
11336
|
var init_openai = __esm(() => {
|
|
10770
11337
|
init_utils();
|
|
10771
11338
|
init_trigger_tools();
|
|
11339
|
+
init_tool_builder();
|
|
10772
11340
|
init_esm();
|
|
10773
11341
|
});
|
|
10774
11342
|
|
|
@@ -10788,11 +11356,27 @@ async function handleAnthropicToolCalls(client, messageContent, options) {
|
|
|
10788
11356
|
const toolResults = [];
|
|
10789
11357
|
const triggerConfig = client.__triggerConfig;
|
|
10790
11358
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
11359
|
+
let cachedCodeModeTool = null;
|
|
11360
|
+
const getCodeModeTool = async () => {
|
|
11361
|
+
if (cachedCodeModeTool)
|
|
11362
|
+
return cachedCodeModeTool;
|
|
11363
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
11364
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
11365
|
+
tools: mcpTools,
|
|
11366
|
+
providerTokens: options?.providerTokens,
|
|
11367
|
+
context: options?.context,
|
|
11368
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11369
|
+
});
|
|
11370
|
+
return cachedCodeModeTool;
|
|
11371
|
+
};
|
|
10791
11372
|
const toolUseBlocks = messageContent.filter((block) => block.type === "tool_use" && ("id" in block) && ("name" in block) && ("input" in block));
|
|
10792
11373
|
for (const toolUse of toolUseBlocks) {
|
|
10793
11374
|
try {
|
|
10794
11375
|
let result;
|
|
10795
|
-
if (
|
|
11376
|
+
if (toolUse.name === CODE_MODE_TOOL_NAME) {
|
|
11377
|
+
const codeTool = await getCodeModeTool();
|
|
11378
|
+
result = await codeTool.execute(toolUse.input);
|
|
11379
|
+
} else if (triggerTools && triggerTools[toolUse.name]) {
|
|
10796
11380
|
result = await triggerTools[toolUse.name].execute(toolUse.input);
|
|
10797
11381
|
} else {
|
|
10798
11382
|
result = await executeToolWithToken(client, toolUse.name, toolUse.input, options);
|
|
@@ -10825,7 +11409,24 @@ async function getAnthropicTools(client, options) {
|
|
|
10825
11409
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10826
11410
|
await ensureClientConnected(client);
|
|
10827
11411
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10828
|
-
const
|
|
11412
|
+
const mode = options?.mode ?? "code";
|
|
11413
|
+
const anthropicTools = mode === "code" ? (() => {
|
|
11414
|
+
const codeTool = buildCodeModeTool(client, {
|
|
11415
|
+
tools: mcpTools,
|
|
11416
|
+
providerTokens,
|
|
11417
|
+
context: options?.context,
|
|
11418
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11419
|
+
});
|
|
11420
|
+
return [{
|
|
11421
|
+
name: CODE_MODE_TOOL_NAME,
|
|
11422
|
+
description: codeTool.description,
|
|
11423
|
+
input_schema: {
|
|
11424
|
+
type: "object",
|
|
11425
|
+
properties: codeTool.parameters.properties,
|
|
11426
|
+
required: [...codeTool.parameters.required]
|
|
11427
|
+
}
|
|
11428
|
+
}];
|
|
11429
|
+
})() : mcpTools.map((mcpTool) => convertMCPToolToAnthropic(mcpTool, client, finalOptions));
|
|
10829
11430
|
const triggerConfig = client.__triggerConfig;
|
|
10830
11431
|
if (triggerConfig) {
|
|
10831
11432
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -10870,6 +11471,7 @@ async function handleAnthropicMessage(client, message, options) {
|
|
|
10870
11471
|
var init_anthropic = __esm(() => {
|
|
10871
11472
|
init_utils();
|
|
10872
11473
|
init_trigger_tools();
|
|
11474
|
+
init_tool_builder();
|
|
10873
11475
|
init_esm();
|
|
10874
11476
|
});
|
|
10875
11477
|
|
|
@@ -10955,13 +11557,29 @@ async function executeGoogleFunctionCalls(client, functionCalls, options) {
|
|
|
10955
11557
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10956
11558
|
const triggerConfig = client.__triggerConfig;
|
|
10957
11559
|
const triggerTools = triggerConfig ? createTriggerTools(triggerConfig, options?.context) : null;
|
|
11560
|
+
let cachedCodeModeTool = null;
|
|
11561
|
+
const getCodeModeTool = async () => {
|
|
11562
|
+
if (cachedCodeModeTool)
|
|
11563
|
+
return cachedCodeModeTool;
|
|
11564
|
+
const mcpTools = await client.getEnabledToolsAsync();
|
|
11565
|
+
cachedCodeModeTool = buildCodeModeTool(client, {
|
|
11566
|
+
tools: mcpTools,
|
|
11567
|
+
providerTokens: finalOptions?.providerTokens,
|
|
11568
|
+
context: options?.context,
|
|
11569
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11570
|
+
});
|
|
11571
|
+
return cachedCodeModeTool;
|
|
11572
|
+
};
|
|
10958
11573
|
const results = await Promise.all(functionCalls.map(async (call) => {
|
|
10959
11574
|
if (!call?.name) {
|
|
10960
11575
|
throw new Error("Function call must have a name");
|
|
10961
11576
|
}
|
|
10962
11577
|
const args = call.args || {};
|
|
10963
11578
|
let result;
|
|
10964
|
-
if (
|
|
11579
|
+
if (call.name === CODE_MODE_TOOL_NAME) {
|
|
11580
|
+
const codeTool = await getCodeModeTool();
|
|
11581
|
+
result = await codeTool.execute(args);
|
|
11582
|
+
} else if (triggerTools && triggerTools[call.name]) {
|
|
10965
11583
|
result = await triggerTools[call.name].execute(args);
|
|
10966
11584
|
} else {
|
|
10967
11585
|
result = await executeToolWithToken(client, call.name, args, finalOptions);
|
|
@@ -10980,7 +11598,33 @@ async function getGoogleTools(client, options) {
|
|
|
10980
11598
|
const finalOptions = providerTokens ? { ...options, providerTokens } : options;
|
|
10981
11599
|
await ensureClientConnected(client);
|
|
10982
11600
|
const mcpTools = await client.getEnabledToolsAsync();
|
|
10983
|
-
const
|
|
11601
|
+
const mode = options?.mode ?? "code";
|
|
11602
|
+
let googleTools;
|
|
11603
|
+
if (mode === "code") {
|
|
11604
|
+
const TypeEnum = await getGoogleType();
|
|
11605
|
+
const codeTool = buildCodeModeTool(client, {
|
|
11606
|
+
tools: mcpTools,
|
|
11607
|
+
providerTokens,
|
|
11608
|
+
context: options?.context,
|
|
11609
|
+
integrationIds: client.__oauthConfig?.integrations?.map((i) => i.id)
|
|
11610
|
+
});
|
|
11611
|
+
googleTools = [{
|
|
11612
|
+
name: CODE_MODE_TOOL_NAME,
|
|
11613
|
+
description: codeTool.description,
|
|
11614
|
+
parameters: {
|
|
11615
|
+
type: TypeEnum.OBJECT,
|
|
11616
|
+
properties: {
|
|
11617
|
+
code: {
|
|
11618
|
+
type: TypeEnum.STRING,
|
|
11619
|
+
description: codeTool.parameters.properties.code.description
|
|
11620
|
+
}
|
|
11621
|
+
},
|
|
11622
|
+
required: ["code"]
|
|
11623
|
+
}
|
|
11624
|
+
}];
|
|
11625
|
+
} else {
|
|
11626
|
+
googleTools = await Promise.all(mcpTools.map((mcpTool) => convertMCPToolToGoogle(mcpTool, client, finalOptions)));
|
|
11627
|
+
}
|
|
10984
11628
|
const triggerConfig = client.__triggerConfig;
|
|
10985
11629
|
if (triggerConfig) {
|
|
10986
11630
|
const triggerTools = createTriggerTools(triggerConfig, options?.context);
|
|
@@ -11058,6 +11702,7 @@ function convertJsonSchemaToGoogleSchema(jsonSchema, TypeEnum) {
|
|
|
11058
11702
|
var init_google = __esm(() => {
|
|
11059
11703
|
init_utils();
|
|
11060
11704
|
init_trigger_tools();
|
|
11705
|
+
init_tool_builder();
|
|
11061
11706
|
init_esm();
|
|
11062
11707
|
});
|
|
11063
11708
|
|
|
@@ -11123,8 +11768,8 @@ var init_webhooks = __esm(() => {
|
|
|
11123
11768
|
var MAX_TRIGGER_STEPS = 20, WEBHOOK_DELIVERY_TIMEOUT_MS = 1e4;
|
|
11124
11769
|
|
|
11125
11770
|
// src/triggers/executor.ts
|
|
11126
|
-
var
|
|
11127
|
-
__export(
|
|
11771
|
+
var exports_executor2 = {};
|
|
11772
|
+
__export(exports_executor2, {
|
|
11128
11773
|
executeTrigger: () => executeTrigger
|
|
11129
11774
|
});
|
|
11130
11775
|
async function executeTrigger(trigger, config, context) {
|
|
@@ -11271,7 +11916,7 @@ async function executeTrigger(trigger, config, context) {
|
|
|
11271
11916
|
return { success: false, steps, error: limitError };
|
|
11272
11917
|
}
|
|
11273
11918
|
var logger32;
|
|
11274
|
-
var
|
|
11919
|
+
var init_executor2 = __esm(() => {
|
|
11275
11920
|
init_logger();
|
|
11276
11921
|
init_utils2();
|
|
11277
11922
|
init_webhooks();
|
|
@@ -11416,7 +12061,8 @@ function createMCPServer(config) {
|
|
|
11416
12061
|
integrations: updatedIntegrations,
|
|
11417
12062
|
getSessionContext: config.getSessionContext,
|
|
11418
12063
|
setProviderToken: config.setProviderToken,
|
|
11419
|
-
removeProviderToken: config.removeProviderToken
|
|
12064
|
+
removeProviderToken: config.removeProviderToken,
|
|
12065
|
+
codeMode: config.codeMode
|
|
11420
12066
|
};
|
|
11421
12067
|
client.__triggerConfig = config.triggers ? {
|
|
11422
12068
|
callbacks: config.triggers,
|
|
@@ -11486,8 +12132,21 @@ function createMCPServer(config) {
|
|
|
11486
12132
|
if (action === "mcp" && method === "POST") {
|
|
11487
12133
|
try {
|
|
11488
12134
|
const body = await webRequest.json();
|
|
11489
|
-
|
|
12135
|
+
let authHeader = webRequest.headers.get("authorization");
|
|
11490
12136
|
const integrationsHeader = webRequest.headers.get("x-integrations");
|
|
12137
|
+
if (!authHeader) {
|
|
12138
|
+
const tokensHeader = webRequest.headers.get("x-integrate-tokens");
|
|
12139
|
+
const toolName = typeof body?.name === "string" ? body.name : "";
|
|
12140
|
+
if (tokensHeader && toolName) {
|
|
12141
|
+
try {
|
|
12142
|
+
const tokens = JSON.parse(tokensHeader);
|
|
12143
|
+
const provider = toolName.split("_")[0];
|
|
12144
|
+
if (provider && tokens[provider]) {
|
|
12145
|
+
authHeader = `Bearer ${tokens[provider]}`;
|
|
12146
|
+
}
|
|
12147
|
+
} catch {}
|
|
12148
|
+
}
|
|
12149
|
+
}
|
|
11491
12150
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
11492
12151
|
const oauthHandler = new OAuthHandler2({
|
|
11493
12152
|
providers,
|
|
@@ -11508,6 +12167,53 @@ function createMCPServer(config) {
|
|
|
11508
12167
|
return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
|
|
11509
12168
|
}
|
|
11510
12169
|
}
|
|
12170
|
+
if (action === "code" && method === "POST") {
|
|
12171
|
+
try {
|
|
12172
|
+
const body = await webRequest.json();
|
|
12173
|
+
if (typeof body?.code !== "string" || body.code.length === 0) {
|
|
12174
|
+
return Response.json({ error: "`code` is required and must be a non-empty string." }, { status: 400 });
|
|
12175
|
+
}
|
|
12176
|
+
const { executeSandboxCode: executeSandboxCode2 } = await Promise.resolve().then(() => (init_executor(), exports_executor));
|
|
12177
|
+
const codeModeConfig = config.codeMode ?? {};
|
|
12178
|
+
const publicUrl = codeModeConfig.publicUrl ?? getEnv("INTEGRATE_PUBLIC_URL");
|
|
12179
|
+
if (!publicUrl) {
|
|
12180
|
+
return Response.json({
|
|
12181
|
+
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."
|
|
12182
|
+
}, { status: 500 });
|
|
12183
|
+
}
|
|
12184
|
+
let contextOverride = body.context;
|
|
12185
|
+
if (!contextOverride && config.getSessionContext) {
|
|
12186
|
+
try {
|
|
12187
|
+
contextOverride = await config.getSessionContext(webRequest);
|
|
12188
|
+
} catch {}
|
|
12189
|
+
}
|
|
12190
|
+
let providerTokens = body.providerTokens;
|
|
12191
|
+
if (!providerTokens) {
|
|
12192
|
+
const headerTokens = webRequest.headers.get("x-integrate-tokens");
|
|
12193
|
+
if (headerTokens) {
|
|
12194
|
+
try {
|
|
12195
|
+
providerTokens = JSON.parse(headerTokens);
|
|
12196
|
+
} catch {}
|
|
12197
|
+
}
|
|
12198
|
+
}
|
|
12199
|
+
const integrationIds = updatedIntegrations.map((i) => i.id);
|
|
12200
|
+
const result = await executeSandboxCode2({
|
|
12201
|
+
code: body.code,
|
|
12202
|
+
mcpUrl: publicUrl.replace(/\/$/, "") + "/api/integrate/mcp",
|
|
12203
|
+
providerTokens,
|
|
12204
|
+
context: contextOverride,
|
|
12205
|
+
integrationsHeader: integrationIds.join(","),
|
|
12206
|
+
runtime: codeModeConfig.runtime,
|
|
12207
|
+
timeoutMs: codeModeConfig.timeoutMs,
|
|
12208
|
+
vcpus: codeModeConfig.vcpus,
|
|
12209
|
+
networkPolicy: codeModeConfig.networkPolicy
|
|
12210
|
+
});
|
|
12211
|
+
return Response.json(result, { status: result.success ? 200 : 500 });
|
|
12212
|
+
} catch (error) {
|
|
12213
|
+
logger33.error("[Code Mode] Error:", error);
|
|
12214
|
+
return Response.json({ error: error?.message || "Failed to execute code" }, { status: 500 });
|
|
12215
|
+
}
|
|
12216
|
+
}
|
|
11511
12217
|
if (action === "integrations" && method === "GET") {
|
|
11512
12218
|
const integrations = updatedIntegrations.map((integration) => ({
|
|
11513
12219
|
id: integration.id,
|
|
@@ -11543,7 +12249,7 @@ function createMCPServer(config) {
|
|
|
11543
12249
|
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
11544
12250
|
}
|
|
11545
12251
|
const triggerContext = trigger.userId ? { userId: trigger.userId } : undefined;
|
|
11546
|
-
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (
|
|
12252
|
+
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
|
|
11547
12253
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
11548
12254
|
const oauthHandler = new OAuthHandler2({
|
|
11549
12255
|
providers,
|
|
@@ -11706,7 +12412,7 @@ function createMCPServer(config) {
|
|
|
11706
12412
|
if (!trigger.provider) {
|
|
11707
12413
|
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
11708
12414
|
}
|
|
11709
|
-
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (
|
|
12415
|
+
const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor2(), exports_executor2));
|
|
11710
12416
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
|
|
11711
12417
|
const oauthHandler = new OAuthHandler2({
|
|
11712
12418
|
providers,
|
|
@@ -12218,6 +12924,11 @@ init_base_handler();
|
|
|
12218
12924
|
|
|
12219
12925
|
// server.ts
|
|
12220
12926
|
init_ai();
|
|
12927
|
+
|
|
12928
|
+
// src/code-mode/index.ts
|
|
12929
|
+
init_type_generator();
|
|
12930
|
+
init_executor();
|
|
12931
|
+
init_tool_builder();
|
|
12221
12932
|
export {
|
|
12222
12933
|
zendeskIntegration,
|
|
12223
12934
|
youtubeIntegration,
|
|
@@ -12253,9 +12964,11 @@ export {
|
|
|
12253
12964
|
getCodeVerifier,
|
|
12254
12965
|
getAnthropicTools,
|
|
12255
12966
|
genericOAuthIntegration,
|
|
12967
|
+
generateCodeModeTypes,
|
|
12256
12968
|
gcalIntegration,
|
|
12257
12969
|
fromNodeHeaders,
|
|
12258
12970
|
figmaIntegration,
|
|
12971
|
+
executeSandboxCode,
|
|
12259
12972
|
executeGoogleFunctionCalls,
|
|
12260
12973
|
cursorIntegration,
|
|
12261
12974
|
createTriggerTools,
|
|
@@ -12264,8 +12977,11 @@ export {
|
|
|
12264
12977
|
createNextOAuthHandler,
|
|
12265
12978
|
createMCPServer,
|
|
12266
12979
|
calcomIntegration,
|
|
12980
|
+
buildCodeModeTool,
|
|
12267
12981
|
airtableIntegration,
|
|
12982
|
+
RUNTIME_STUB_SOURCE,
|
|
12268
12983
|
POST,
|
|
12269
12984
|
OAuthHandler,
|
|
12270
|
-
GET
|
|
12985
|
+
GET,
|
|
12986
|
+
CODE_MODE_TOOL_NAME
|
|
12271
12987
|
};
|