Feat: add conversation API

This commit is contained in:
Harshith Mullapudi 2025-07-08 10:36:14 +05:30
parent 12453954b7
commit 158d26f7c2
27 changed files with 1349 additions and 209 deletions

View File

@ -382,7 +382,6 @@ export const Graph = forwardRef<GraphRef, GraphProps>(
// Node click handler
sigma.on("clickNode", (event) => {
console.log(event);
const { node } = event;
// resetHighlights();
if (onNodeClick) {

View File

@ -0,0 +1,39 @@
import { json } from "@remix-run/node";
import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
import { getWorkspaceByUser } from "~/models/workspace.server";
import {
createConversation,
CreateConversationSchema,
readConversation,
} from "~/services/conversation.server";
import { z } from "zod";
export const ConversationIdSchema = z.object({
conversationId: z.string(),
});
const { action, loader } = createActionApiRoute(
{
params: ConversationIdSchema,
allowJWT: true,
authorization: {
action: "oauth",
},
corsStrategy: "all",
},
async ({ authentication, params }) => {
const workspace = await getWorkspaceByUser(authentication.userId);
if (!workspace) {
throw new Error("No workspace found");
}
// Call the service to get the redirect URL
const read = await readConversation(params.conversationId);
return json(read);
},
);
export { action, loader };

View File

@ -0,0 +1,44 @@
import { json } from "@remix-run/node";
import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
import { getWorkspaceByUser } from "~/models/workspace.server";
import {
createConversation,
CreateConversationSchema,
getCurrentConversationRun,
readConversation,
stopConversation,
} from "~/services/conversation.server";
import { z } from "zod";
export const ConversationIdSchema = z.object({
conversationId: z.string(),
});
const { action, loader } = createActionApiRoute(
{
params: ConversationIdSchema,
allowJWT: true,
authorization: {
action: "oauth",
},
corsStrategy: "all",
},
async ({ authentication, params }) => {
const workspace = await getWorkspaceByUser(authentication.userId);
if (!workspace) {
throw new Error("No workspace found");
}
// Call the service to get the redirect URL
const run = await getCurrentConversationRun(
params.conversationId,
workspace?.id,
);
return json(run);
},
);
export { action, loader };

View File

@ -0,0 +1,40 @@
import { json } from "@remix-run/node";
import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
import { getWorkspaceByUser } from "~/models/workspace.server";
import {
createConversation,
CreateConversationSchema,
readConversation,
stopConversation,
} from "~/services/conversation.server";
import { z } from "zod";
export const ConversationIdSchema = z.object({
conversationId: z.string(),
});
const { action, loader } = createActionApiRoute(
{
params: ConversationIdSchema,
allowJWT: true,
authorization: {
action: "oauth",
},
corsStrategy: "all",
},
async ({ authentication, params }) => {
const workspace = await getWorkspaceByUser(authentication.userId);
if (!workspace) {
throw new Error("No workspace found");
}
// Call the service to get the redirect URL
const stop = await stopConversation(params.conversationId, workspace?.id);
return json(stop);
},
);
export { action, loader };

View File

@ -0,0 +1,50 @@
import { json } from "@remix-run/node";
import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
import { getWorkspaceByUser } from "~/models/workspace.server";
import {
getConversation,
deleteConversation,
} from "~/services/conversation.server";
import { z } from "zod";
export const ConversationIdSchema = z.object({
conversationId: z.string(),
});
const { action, loader } = createActionApiRoute(
{
params: ConversationIdSchema,
allowJWT: true,
authorization: {
action: "oauth",
},
corsStrategy: "all",
},
async ({ params, authentication, request }) => {
const workspace = await getWorkspaceByUser(authentication.userId);
if (!workspace) {
throw new Error("No workspace found");
}
const method = request.method;
if (method === "GET") {
// Get a conversation by ID
const conversation = await getConversation(params.conversationId);
return json(conversation);
}
if (method === "DELETE") {
// Soft delete a conversation
const deleted = await deleteConversation(params.conversationId);
return json(deleted);
}
// Method not allowed
return new Response("Method Not Allowed", { status: 405 });
},
);
export { action, loader };

View File

@ -0,0 +1,37 @@
import { json } from "@remix-run/node";
import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
import { getWorkspaceByUser } from "~/models/workspace.server";
import {
createConversation,
CreateConversationSchema,
} from "~/services/conversation.server";
const { action, loader } = createActionApiRoute(
{
body: CreateConversationSchema,
allowJWT: true,
authorization: {
action: "oauth",
},
corsStrategy: "all",
},
async ({ body, authentication }) => {
const workspace = await getWorkspaceByUser(authentication.userId);
if (!workspace) {
throw new Error("No workspace found");
}
// Call the service to get the redirect URL
const conversation = await createConversation(
workspace?.id,
authentication.userId,
body,
);
return json(conversation);
},
);
export { action, loader };

View File

@ -0,0 +1,228 @@
import { UserTypeEnum } from "@core/types";
import { auth, runs, tasks } from "@trigger.dev/sdk/v3";
import { prisma } from "~/db.server";
import { getOrCreatePersonalAccessToken } from "./personalAccessToken.server";
import { createConversationTitle } from "~/trigger/conversation/create-conversation-title";
import { z } from "zod";
export const CreateConversationSchema = z.object({
message: z.string(),
title: z.string().optional(),
conversationId: z.string().optional(),
});
export type CreateConversationDto = z.infer<typeof CreateConversationSchema>;
// Create a new conversation
export async function createConversation(
workspaceId: string,
userId: string,
conversationData: CreateConversationDto,
) {
const { title, conversationId, ...otherData } = conversationData;
// Ensure PAT exists for the user
await getOrCreatePersonalAccessToken({ name: "trigger", userId });
if (conversationId) {
// Add a new message to an existing conversation
const conversationHistory = await prisma.conversationHistory.create({
data: {
...otherData,
userType: UserTypeEnum.User,
...(userId && {
user: {
connect: { id: userId },
},
}),
conversation: {
connect: { id: conversationId },
},
},
include: {
conversation: true,
},
});
// No context logic here
const handler = await tasks.trigger(
"chat",
{
conversationHistoryId: conversationHistory.id,
conversationId: conversationHistory.conversation.id,
},
{ tags: [conversationHistory.id, workspaceId, conversationId] },
);
return {
id: handler.id,
token: handler.publicAccessToken,
conversationId: conversationHistory.conversation.id,
conversationHistoryId: conversationHistory.id,
};
}
// Create a new conversation and its first message
const conversation = await prisma.conversation.create({
data: {
workspaceId,
userId,
title:
title?.substring(0, 100) ?? conversationData.message.substring(0, 100),
ConversationHistory: {
create: {
userId,
userType: UserTypeEnum.User,
...otherData,
},
},
},
include: {
ConversationHistory: true,
},
});
const conversationHistory = conversation.ConversationHistory[0];
// Trigger conversation title task
await tasks.trigger<typeof createConversationTitle>(
createConversationTitle.id,
{
conversationId: conversation.id,
message: conversationData.message,
},
{ tags: [conversation.id, workspaceId] },
);
const handler = await tasks.trigger(
"chat",
{
conversationHistoryId: conversationHistory.id,
conversationId: conversation.id,
},
{ tags: [conversationHistory.id, workspaceId, conversation.id] },
);
return {
id: handler.id,
token: handler.publicAccessToken,
conversationId: conversation.id,
conversationHistoryId: conversationHistory.id,
};
}
// Get a conversation by ID
export async function getConversation(conversationId: string) {
return prisma.conversation.findUnique({
where: { id: conversationId },
});
}
// Delete a conversation (soft delete)
export async function deleteConversation(conversationId: string) {
return prisma.conversation.update({
where: { id: conversationId },
data: {
deleted: new Date().toISOString(),
},
});
}
// Mark a conversation as read
export async function readConversation(conversationId: string) {
return prisma.conversation.update({
where: { id: conversationId },
data: { unread: false },
});
}
export async function getCurrentConversationRun(
conversationId: string,
workspaceId: string,
) {
const conversationHistory = await prisma.conversationHistory.findFirst({
where: {
conversationId,
conversation: {
workspaceId,
},
},
orderBy: {
updatedAt: "desc",
},
});
if (!conversationHistory) {
throw new Error("No run found");
}
const response = await runs.list({
tag: [conversationId, conversationHistory.id],
status: ["QUEUED", "EXECUTING"],
limit: 1,
});
const run = response.data[0];
if (!run) {
return undefined;
}
const publicToken = await auth.createPublicToken({
scopes: {
read: {
runs: [run.id],
},
},
});
return {
id: run.id,
token: publicToken,
conversationId,
conversationHistoryId: conversationHistory.id,
};
}
export async function stopConversation(
conversationId: string,
workspaceId: string,
) {
const conversationHistory = await prisma.conversationHistory.findFirst({
where: {
conversationId,
conversation: {
workspaceId,
},
},
orderBy: {
updatedAt: "desc",
},
});
if (!conversationHistory) {
throw new Error("No run found");
}
const response = await runs.list({
tag: [conversationId, conversationHistory.id],
status: ["QUEUED", "EXECUTING"],
limit: 1,
});
const run = response.data[0];
if (!run) {
await prisma.conversation.update({
where: {
id: conversationId,
},
data: {
status: "failed",
},
});
return undefined;
}
return await runs.cancel(run.id);
}

View File

@ -397,8 +397,6 @@ export function createActionApiRoute<
maxContentLength,
} = options;
console.log(options);
async function loader({ request, params }: LoaderFunctionArgs) {
if (corsStrategy !== "none" && request.method.toUpperCase() === "OPTIONS") {
return apiCors(request, json({}));

View File

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ActionStatusEnum, LLMMappings } from "@core/types";
import { ActionStatusEnum } from "@core/types";
import { logger } from "@trigger.dev/sdk/v3";
import {
type CoreMessage,

View File

@ -0,0 +1,62 @@
import { PrismaClient } from "@prisma/client";
import { LLMMappings } from "@core/types";
import { logger, task } from "@trigger.dev/sdk/v3";
import { generate } from "../chat/stream-utils";
import { conversationTitlePrompt } from "./prompt";
const prisma = new PrismaClient();
export const createConversationTitle = task({
id: "create-conversation-title",
run: async (payload: { conversationId: string; message: string }) => {
let conversationTitleResponse = "";
const gen = generate(
[
{
role: "user",
content: conversationTitlePrompt.replace(
"{{message}}",
payload.message,
),
},
],
false,
() => {},
undefined,
"",
LLMMappings.CLAUDESONNET,
);
for await (const chunk of gen) {
if (typeof chunk === "string") {
conversationTitleResponse += chunk;
} else if (chunk && typeof chunk === "object" && chunk.message) {
conversationTitleResponse += chunk.message;
}
}
const outputMatch = conversationTitleResponse.match(
/<output>(.*?)<\/output>/s,
);
logger.info(`Conversation title data: ${JSON.stringify(outputMatch)}`);
if (!outputMatch) {
logger.error("No output found in recurrence response");
throw new Error("Invalid response format from AI");
}
const jsonStr = outputMatch[1].trim();
const conversationTitleData = JSON.parse(jsonStr);
if (conversationTitleData) {
await prisma.conversation.update({
where: {
id: payload.conversationId,
},
data: {
title: conversationTitleData.title,
},
});
}
},
});

View File

@ -0,0 +1,28 @@
export const conversationTitlePrompt = `You are an AI assistant specialized in generating concise and informative conversation titles. Your task is to analyze the given message and context to create an appropriate title.
Here is the message:
<message>
{{message}}
</message>
Please follow these steps:
- Extract the core topic/intent from the message
- Create a clear, concise title
- Focus on the main subject or action
- Avoid unnecessary words
- Maximum length: 60 characters
Before providing output, analyze in <title_analysis> tags:
- Key elements from message
- Main topic/action
- Relevant actors/context
- Your title formation process
Provide final output in this format:
<output>
{
"title": "Your generated title"
}
</output>
If message is empty or contains no meaningful content, return {"title": "New Conversation"}`;

View File

@ -1,38 +1,38 @@
import { PrismaClient } from '@prisma/client';
import { IntegrationPayloadEventType } from '@redplanethq/sol-sdk';
import { logger, schedules, tasks } from '@trigger.dev/sdk/v3';
// import { PrismaClient } from "@prisma/client";
// import { IntegrationPayloadEventType } from "@core/types";
// import { logger, schedules, tasks } from "@trigger.dev/sdk/v3";
import { integrationRun } from './integration-run';
// import { integrationRun } from "./integration-run";
const prisma = new PrismaClient();
// const prisma = new PrismaClient();
export const integrationRunSchedule = schedules.task({
id: 'integration-run-schedule',
run: async (payload) => {
const { externalId } = payload;
const integrationAccount = await prisma.integrationAccount.findUnique({
where: { id: externalId },
include: {
integrationDefinition: true,
workspace: true,
},
});
// export const integrationRunSchedule = schedules.task({
// id: "integration-run-schedule",
// run: async (payload) => {
// const { externalId } = payload;
// const integrationAccount = await prisma.integrationAccount.findUnique({
// where: { id: externalId },
// include: {
// integrationDefinition: true,
// workspace: true,
// },
// });
if (!integrationAccount) {
const deletedSchedule = await schedules.del(externalId);
logger.info('Deleting schedule as integration account is not there');
return deletedSchedule;
}
// if (!integrationAccount) {
// const deletedSchedule = await schedules.del(externalId);
// logger.info("Deleting schedule as integration account is not there");
// return deletedSchedule;
// }
const pat = await prisma.personalAccessToken.findFirst({
where: { userId: integrationAccount.workspace.userId, name: 'default' },
});
// const pat = await prisma.personalAccessToken.findFirst({
// where: { userId: integrationAccount.workspace.userId, name: "default" },
// });
return await tasks.trigger<typeof integrationRun>('integration-run', {
event: IntegrationPayloadEventType.SCHEDULED_SYNC,
pat: pat.token,
integrationAccount,
integrationDefinition: integrationAccount.integrationDefinition,
});
},
});
// return await tasks.trigger<typeof integrationRun>("integration-run", {
// event: IntegrationPayloadEventType.SCHEDULED_SYNC,
// pat: pat.token,
// integrationAccount,
// integrationDefinition: integrationAccount.integrationDefinition,
// });
// },
// });

View File

@ -1,90 +1,87 @@
import createLoadRemoteModule, {
createRequires,
} from '@paciolan/remote-module-loader';
import {
IntegrationAccount,
IntegrationDefinition,
} from '@redplanethq/sol-sdk';
import { logger, task } from '@trigger.dev/sdk/v3';
import axios from 'axios';
// import createLoadRemoteModule, {
// createRequires,
// } from "@paciolan/remote-module-loader";
const fetcher = async (url: string) => {
// Handle remote URLs with axios
const response = await axios.get(url);
// import { logger, task } from "@trigger.dev/sdk/v3";
// import axios from "axios";
return response.data;
};
// const fetcher = async (url: string) => {
// // Handle remote URLs with axios
// const response = await axios.get(url);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const loadRemoteModule = async (requires: any) =>
createLoadRemoteModule({ fetcher, requires });
// return response.data;
// };
function createAxiosInstance(token: string) {
const instance = axios.create();
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// const loadRemoteModule = async (requires: any) =>
// createLoadRemoteModule({ fetcher, requires });
instance.interceptors.request.use((config) => {
// Check if URL starts with /api and doesn't have a full host
if (config.url?.startsWith('/api')) {
config.url = `${process.env.BACKEND_HOST}${config.url.replace('/api/', '/')}`;
}
// function createAxiosInstance(token: string) {
// const instance = axios.create();
if (
config.url.includes(process.env.FRONTEND_HOST) ||
config.url.includes(process.env.BACKEND_HOST)
) {
config.headers.Authorization = `Bearer ${token}`;
}
// instance.interceptors.request.use((config) => {
// // Check if URL starts with /api and doesn't have a full host
// if (config.url?.startsWith("/api")) {
// config.url = `${process.env.BACKEND_HOST}${config.url.replace("/api/", "/")}`;
// }
return config;
});
// if (
// config.url.includes(process.env.FRONTEND_HOST) ||
// config.url.includes(process.env.BACKEND_HOST)
// ) {
// config.headers.Authorization = `Bearer ${token}`;
// }
return instance;
}
// return config;
// });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getRequires = (axios: any) => createRequires({ axios });
// return instance;
// }
export const integrationRun = task({
id: 'integration-run',
run: async ({
pat,
eventBody,
integrationAccount,
integrationDefinition,
event,
}: {
pat: string;
// This is the event you want to pass to the integration
// eslint-disable-next-line @typescript-eslint/no-explicit-any
event: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
eventBody?: any;
integrationDefinition: IntegrationDefinition;
integrationAccount?: IntegrationAccount;
}) => {
const remoteModuleLoad = await loadRemoteModule(
getRequires(createAxiosInstance(pat)),
);
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// const getRequires = (axios: any) => createRequires({ axios });
logger.info(
`${integrationDefinition.url}/${integrationDefinition.version}/backend/index.js`,
);
// export const integrationRun = task({
// id: "integration-run",
// run: async ({
// pat,
// eventBody,
// integrationAccount,
// integrationDefinition,
// event,
// }: {
// pat: string;
// // This is the event you want to pass to the integration
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// event: any;
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// eventBody?: any;
// integrationDefinition: IntegrationDefinition;
// integrationAccount?: IntegrationAccount;
// }) => {
// const remoteModuleLoad = await loadRemoteModule(
// getRequires(createAxiosInstance(pat)),
// );
const integrationFunction = await remoteModuleLoad(
`${integrationDefinition.url}/${integrationDefinition.version}/backend/index.js`,
);
// logger.info(
// `${integrationDefinition.url}/${integrationDefinition.version}/backend/index.js`,
// );
// const integrationFunction = await remoteModuleLoad(
// `${integrationDefinition.url}`,
// );
// const integrationFunction = await remoteModuleLoad(
// `${integrationDefinition.url}/${integrationDefinition.version}/backend/index.js`,
// );
return await integrationFunction.run({
integrationAccount,
integrationDefinition,
event,
eventBody: {
...(eventBody ? eventBody : {}),
},
});
},
});
// // const integrationFunction = await remoteModuleLoad(
// // `${integrationDefinition.url}`,
// // );
// return await integrationFunction.run({
// integrationAccount,
// integrationDefinition,
// event,
// eventBody: {
// ...(eventBody ? eventBody : {}),
// },
// });
// },
// });

View File

@ -1,64 +1,64 @@
import { PrismaClient } from "@prisma/client";
import { logger, schedules, task } from "@trigger.dev/sdk/v3";
// import { PrismaClient } from "@prisma/client";
// import { logger, schedules, task } from "@trigger.dev/sdk/v3";
import { integrationRunSchedule } from "./integration-run-schedule";
// import { integrationRunSchedule } from "./integration-run-schedule";
const prisma = new PrismaClient();
// const prisma = new PrismaClient();
export const scheduler = task({
id: "scheduler",
run: async (payload: { integrationAccountId: string }) => {
const { integrationAccountId } = payload;
// export const scheduler = task({
// id: "scheduler",
// run: async (payload: { integrationAccountId: string }) => {
// const { integrationAccountId } = payload;
const integrationAccount = await prisma.integrationAccount.findUnique({
where: { id: integrationAccountId, deleted: null },
include: {
integrationDefinition: true,
workspace: true,
},
});
// const integrationAccount = await prisma.integrationAccount.findUnique({
// where: { id: integrationAccountId, deleted: null },
// include: {
// integrationDefinition: true,
// workspace: true,
// },
// });
if (!integrationAccount) {
logger.error("Integration account not found");
return null;
}
// if (!integrationAccount) {
// logger.error("Integration account not found");
// return null;
// }
if (!integrationAccount.workspace) {
return null;
}
// if (!integrationAccount.workspace) {
// return null;
// }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const spec = integrationAccount.integrationDefinition.spec as any;
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// const spec = integrationAccount.integrationDefinition.spec as any;
if (spec.schedule && spec.schedule.frequency) {
const createdSchedule = await schedules.create({
// The id of the scheduled task you want to attach to.
task: integrationRunSchedule.id,
// The schedule in cron format.
cron: spec.schedule.frequency,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
timezone: (integrationAccount.workspace.preferences as any).timezone,
// this is required, it prevents you from creating duplicate schedules. It will update the schedule if it already exists.
deduplicationKey: integrationAccount.id,
externalId: integrationAccount.id,
});
// if (spec.schedule && spec.schedule.frequency) {
// const createdSchedule = await schedules.create({
// // The id of the scheduled task you want to attach to.
// task: integrationRunSchedule.id,
// // The schedule in cron format.
// cron: spec.schedule.frequency,
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// timezone: (integrationAccount.workspace.preferences as any).timezone,
// // this is required, it prevents you from creating duplicate schedules. It will update the schedule if it already exists.
// deduplicationKey: integrationAccount.id,
// externalId: integrationAccount.id,
// });
await prisma.integrationAccount.update({
where: {
id: integrationAccount.id,
},
data: {
settings: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...(integrationAccount.settings as any),
scheduleId: createdSchedule.id,
},
},
});
// await prisma.integrationAccount.update({
// where: {
// id: integrationAccount.id,
// },
// data: {
// settings: {
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
// ...(integrationAccount.settings as any),
// scheduleId: createdSchedule.id,
// },
// },
// });
return createdSchedule;
}
// return createdSchedule;
// }
return "No schedule for this task";
},
});
// return "No schedule for this task";
// },
// });

View File

@ -8,7 +8,8 @@
"dev": "node ./server.mjs",
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
"start": "remix-serve ./build/server/index.js",
"typecheck": "tsc"
"typecheck": "tsc",
"trigger:dev": "npx trigger.dev@latest dev"
},
"dependencies": {
"@ai-sdk/anthropic": "^1.2.12",
@ -20,6 +21,7 @@
"@core/database": "workspace:*",
"@core/types": "workspace:*",
"@mjackson/headers": "0.11.1",
"@modelcontextprotocol/sdk": "1.13.2",
"@nichtsam/remix-auth-email-link": "3.0.0",
"@opentelemetry/api": "1.9.0",
"@prisma/client": "*",

View File

@ -1,8 +1,7 @@
import { defineConfig } from "@trigger.dev/sdk/v3";
import { env } from "~/env.server";
export default defineConfig({
project: env.TRIGGER_PROJECT_ID,
project: process.env.TRIGGER_PROJECT_ID as string,
runtime: "node",
logLevel: "log",
// The max compute seconds a task is allowed to run. If the task run exceeds this duration, it will be stopped.

View File

@ -17,7 +17,8 @@
"db:seed": "dotenv -- turbo run db:seed",
"db:studio": "dotenv -- turbo run db:studio",
"db:populate": "dotenv -- turbo run db:populate",
"generate": "dotenv -- turbo run generate"
"generate": "dotenv -- turbo run generate",
"trigger:dev": "dotenv -- turbo run trigger:dev"
},
"devDependencies": {
"dotenv-cli": "^7.4.4",

View File

@ -0,0 +1,9 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ['@redplanethq/eslint-config/internal.js'],
parser: '@typescript-eslint/parser',
rules: {
'no-redeclare': 'off',
},
};

View File

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}

49
packages/sdk/package.json Normal file
View File

@ -0,0 +1,49 @@
{
"name": "@redplanethq/sol-sdk",
"version": "0.2.18",
"description": "Sol Node.JS SDK",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"module": "./dist/index.mjs",
"publishConfig": {
"access": "public"
},
"files": [
"dist"
],
"exports": {
".": {
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json"
},
"scripts": {
"clean": "rimraf dist",
"build": "npm run clean && npm run build:tsup",
"build:tsup": "tsup --dts-resolve",
"typecheck": "tsc --noEmit"
},
"dependencies": {
},
"devDependencies": {
"@core/types": "workspace:*",
"@types/configstore": "^6.0.2",
"@types/debug": "^4.1.7",
"@types/node": "18",
"@types/slug": "^5.0.3",
"@types/uuid": "^9.0.0",
"encoding": "^0.1.13",
"rimraf": "^6.0.1",
"tsup": "^8.0.1",
"typescript": "^5.3.0"
},
"engines": {
"node": ">=18.0.0"
},
"packageManager": "pnpm@10.3.0"
}

View File

@ -0,0 +1 @@
export * from '@core/types';

View File

@ -0,0 +1,38 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"include": ["./src/**/*.ts", "tsup.config.ts"],
"compilerOptions": {
"baseUrl": "src",
"moduleResolution": "node",
"strictNullChecks": false,
"preserveConstEnums": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"noFallthroughCasesInSwitch": true,
"useUnknownInCatchVariables": false,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"sourceMap": true,
"removeComments": true,
"module": "commonjs",
"target": "ES2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"lib": ["DOM", "DOM.Iterable"],
"declaration": false,
"declarationMap": false,
"stripInternal": true
},
"exclude": ["node_modules", "dist"]
}

View File

@ -0,0 +1,22 @@
import { Options, defineConfig as defineConfigTSUP } from 'tsup';
const options: Options = {
name: 'main',
config: 'tsconfig.json',
entry: ['./src/index.ts'],
outDir: './dist',
platform: 'node',
format: ['cjs', 'esm'],
legacyOutput: false,
sourcemap: true,
clean: true,
bundle: true,
splitting: false,
dts: true,
treeshake: {
preset: 'recommended',
},
external: ['axios'],
};
export default defineConfigTSUP(options);

View File

@ -3,3 +3,4 @@ export * from "./graph";
export * from "./conversation-execution-step";
export * from "./oauth";
export * from "./integration";
export * from "./user";

View File

@ -0,0 +1,5 @@
export enum UserTypeEnum {
Agent = "Agent",
User = "User",
System = "System",
}

564
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,9 @@
},
"generate": {
"dependsOn": [ "^generate" ]
},
"trigger:dev": {
}
},
"globalDependencies": [ ".env" ],