Harshith Mullapudi 8836849310 1. Remove chat and deep-search from trigger
2. Add ai/sdk for chat UI
3. Added a better model manager
2025-10-26 01:10:28 +05:30

156 lines
5.0 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-explicit-any */
import { logger } from "@trigger.dev/sdk/v3";
import * as fs from "fs";
import * as path from "path";
import { prisma } from "./prisma";
export const fetchAndSaveStdioIntegrations = async () => {
try {
logger.info("Starting stdio integrations fetch and save process");
// Get all integration definitions
const integrationDefinitions =
await prisma.integrationDefinitionV2.findMany({
where: {
deleted: null, // Only active integrations
},
});
logger.info(
`Found ${integrationDefinitions.length} integration definitions`,
);
for (const integration of integrationDefinitions) {
try {
const spec = integration.spec as any;
// Check if this integration has MCP config and is stdio type
if (spec?.mcp?.type === "stdio" && spec?.mcp?.url) {
logger.info(`Processing stdio integration: ${integration.slug}`);
const integrationDir = path.join(
process.cwd(),
"integrations",
integration.slug,
);
const targetFile = path.join(integrationDir, "main");
// Create directory if it doesn't exist
if (!fs.existsSync(integrationDir)) {
fs.mkdirSync(integrationDir, { recursive: true });
logger.info(`Created directory: ${integrationDir}`);
}
// Skip if file already exists
if (fs.existsSync(targetFile)) {
logger.info(
`Integration ${integration.slug} already exists, skipping`,
);
continue;
}
const urlOrPath = spec.mcp.url;
// If urlOrPath looks like a URL, use fetch, otherwise treat as local path
let isUrl = false;
try {
// Try to parse as URL
const parsed = new URL(urlOrPath);
isUrl = ["http:", "https:"].includes(parsed.protocol);
} catch {
isUrl = false;
}
if (isUrl) {
// Fetch the URL content
logger.info(`Fetching content from URL: ${urlOrPath}`);
const response = await fetch(urlOrPath);
if (!response.ok) {
logger.error(
`Failed to fetch ${urlOrPath}: ${response.status} ${response.statusText}`,
);
continue;
}
// Check if the response is binary (executable) or text
const contentType = response.headers.get("content-type");
const isBinary =
contentType &&
(contentType.includes("application/octet-stream") ||
contentType.includes("application/executable") ||
contentType.includes("application/x-executable") ||
contentType.includes("binary") ||
!contentType.includes("text/"));
let content: string | Buffer;
if (isBinary) {
// Handle binary files
const arrayBuffer = await response.arrayBuffer();
content = Buffer.from(arrayBuffer);
} else {
// Handle text files
content = await response.text();
}
// Save the content to the target file
if (typeof content === "string") {
fs.writeFileSync(targetFile, content);
} else {
fs.writeFileSync(targetFile, content);
}
// Make the file executable if it's a script
if (process.platform !== "win32") {
fs.chmodSync(targetFile, "755");
}
logger.info(
`Successfully saved stdio integration: ${integration.slug} to ${targetFile}`,
);
} else {
// Treat as local file path
const sourcePath = path.isAbsolute(urlOrPath)
? urlOrPath
: path.join(process.cwd(), urlOrPath);
logger.info(`Copying content from local path: ${sourcePath}`);
if (!fs.existsSync(sourcePath)) {
logger.error(`Source file does not exist: ${sourcePath}`);
continue;
}
fs.copyFileSync(sourcePath, targetFile);
// Make the file executable if it's a script
if (process.platform !== "win32") {
fs.chmodSync(targetFile, "755");
}
logger.info(
`Successfully copied stdio integration: ${integration.slug} to ${targetFile}`,
);
}
} else {
logger.debug(
`Skipping integration ${integration.slug}: not a stdio type or missing URL`,
);
}
} catch (error) {
logger.error(`Error processing integration ${integration.slug}:`, {
error,
});
}
}
logger.info("Completed stdio integrations fetch and save process");
} catch (error) {
logger.error("Failed to fetch and save stdio integrations:", { error });
throw error;
}
};