diff --git a/apps/webapp/app/components/spaces/space-pattern-card.tsx b/apps/webapp/app/components/spaces/space-pattern-card.tsx
index e61201f..a278d87 100644
--- a/apps/webapp/app/components/spaces/space-pattern-card.tsx
+++ b/apps/webapp/app/components/spaces/space-pattern-card.tsx
@@ -22,7 +22,7 @@ export function SpacePatternCard({ pattern }: SpacePatternCardProps) {
actionType,
patternId: pattern.id,
},
- { method: "POST" }
+ { method: "POST" },
);
setDialog(false);
};
@@ -77,19 +77,19 @@ export function SpacePatternCard({ pattern }: SpacePatternCardProps) {
-
-
diff --git a/apps/webapp/app/models/workspace.server.ts b/apps/webapp/app/models/workspace.server.ts
index d9cb78d..76d9125 100644
--- a/apps/webapp/app/models/workspace.server.ts
+++ b/apps/webapp/app/models/workspace.server.ts
@@ -1,5 +1,6 @@
import { type Workspace } from "@core/database";
import { prisma } from "~/db.server";
+import { sendEmail } from "~/services/email.server";
import { SpaceService } from "~/services/space.server";
interface CreateWorkspaceDto {
@@ -31,7 +32,7 @@ export async function createWorkspace(
},
});
- await prisma.user.update({
+ const user = await prisma.user.update({
where: { id: input.userId },
data: {
confirmedBasicDetails: true,
@@ -45,6 +46,8 @@ export async function createWorkspace(
workspaceId: workspace.id,
});
+ await sendEmail({ email: "welcome", to: user.email });
+
return workspace;
}
diff --git a/apps/webapp/app/routes/api.v1.search.tsx b/apps/webapp/app/routes/api.v1.search.tsx
index ad1553f..ddf3b3c 100644
--- a/apps/webapp/app/routes/api.v1.search.tsx
+++ b/apps/webapp/app/routes/api.v1.search.tsx
@@ -1,5 +1,8 @@
import { z } from "zod";
-import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server";
+import {
+ createActionApiRoute,
+ createHybridActionApiRoute,
+} from "~/services/routeBuilders/apiBuilder.server";
import { SearchService } from "~/services/search.server";
import { json } from "@remix-run/node";
@@ -19,7 +22,7 @@ export const SearchBodyRequest = z.object({
});
const searchService = new SearchService();
-const { action, loader } = createActionApiRoute(
+const { action, loader } = createHybridActionApiRoute(
{
body: SearchBodyRequest,
allowJWT: true,
diff --git a/apps/webapp/app/routes/confirm-basic-details.tsx b/apps/webapp/app/routes/confirm-basic-details.tsx
index 2653034..44e82ea 100644
--- a/apps/webapp/app/routes/confirm-basic-details.tsx
+++ b/apps/webapp/app/routes/confirm-basic-details.tsx
@@ -1,5 +1,5 @@
import { z } from "zod";
-import { useActionData, useLoaderData } from "@remix-run/react";
+import { useActionData } from "@remix-run/react";
import {
type ActionFunctionArgs,
json,
@@ -17,12 +17,7 @@ import {
} from "~/components/ui/card";
import { Button } from "~/components/ui";
import { Input } from "~/components/ui/input";
-import { useState } from "react";
-import {
- requireUser,
- requireUserId,
- requireWorkpace,
-} from "~/services/session.server";
+import { requireUser, requireUserId } from "~/services/session.server";
import { redirectWithSuccessMessage } from "~/models/message.server";
import { rootPath } from "~/utils/pathBuilder";
import { createWorkspace, getWorkspaceByUser } from "~/models/workspace.server";
@@ -76,7 +71,6 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
export default function ConfirmBasicDetails() {
const lastSubmission = useActionData();
- const { workspace } = useLoaderData();
const [form, fields] = useForm({
lastSubmission: lastSubmission as any,
diff --git a/apps/webapp/app/services/email.server.ts b/apps/webapp/app/services/email.server.ts
index feecd5e..55e2190 100644
--- a/apps/webapp/app/services/email.server.ts
+++ b/apps/webapp/app/services/email.server.ts
@@ -16,8 +16,8 @@ const client = singleton(
new EmailClient({
transport: buildTransportOptions(),
imagesBaseUrl: env.APP_ORIGIN,
- from: env.FROM_EMAIL ?? "Harshith ",
- replyTo: env.REPLY_TO_EMAIL ?? "harshith@tegon.ai",
+ from: env.FROM_EMAIL ?? "Manik ",
+ replyTo: env.REPLY_TO_EMAIL ?? "manik@poozle.dev",
}),
);
@@ -85,5 +85,9 @@ export async function scheduleEmail(
) {}
export async function sendEmail(data: DeliverEmail) {
- return client.send(data);
+ try {
+ return client.send(data);
+ } catch (e) {
+ logger.error(`Error: ${e}`);
+ }
}
diff --git a/apps/webapp/app/trigger/chat/chat.ts b/apps/webapp/app/trigger/chat/chat.ts
index 99de2fc..f72b5eb 100644
--- a/apps/webapp/app/trigger/chat/chat.ts
+++ b/apps/webapp/app/trigger/chat/chat.ts
@@ -6,6 +6,7 @@ import { MCP } from "../utils/mcp";
import { type HistoryStep } from "../utils/types";
import {
createConversationHistoryForAgent,
+ deletePersonalAccessToken,
getCreditsForUser,
getPreviousExecutionHistory,
init,
@@ -120,9 +121,15 @@ export const chat = task({
);
usageCredits && (await updateUserCredits(usageCredits, 1));
+
+ if (init?.tokenId) {
+ await deletePersonalAccessToken(init.tokenId);
+ }
} catch (e) {
await updateConversationStatus("failed", payload.conversationId);
-
+ if (init?.tokenId) {
+ await deletePersonalAccessToken(init.tokenId);
+ }
throw new Error(e as string);
}
},
diff --git a/apps/webapp/app/trigger/extension/search.ts b/apps/webapp/app/trigger/extension/search.ts
index 78b5a94..8e0be5a 100644
--- a/apps/webapp/app/trigger/extension/search.ts
+++ b/apps/webapp/app/trigger/extension/search.ts
@@ -4,8 +4,12 @@ import { z } from "zod";
import { openai } from "@ai-sdk/openai";
import { logger } from "~/services/logger.service";
-import { getOrCreatePersonalAccessToken } from "../utils/utils";
+import {
+ deletePersonalAccessToken,
+ getOrCreatePersonalAccessToken,
+} from "../utils/utils";
import axios from "axios";
+import { nanoid } from "nanoid";
export const ExtensionSearchBodyRequest = z.object({
userInput: z.string().min(1, "User input is required"),
@@ -24,8 +28,10 @@ export const extensionSearch = task({
const { userInput, userId, context } =
ExtensionSearchBodyRequest.parse(body);
+ const randomKeyName = `extensionSearch_${nanoid(10)}`;
+
const pat = await getOrCreatePersonalAccessToken({
- name: "extensionSearch",
+ name: randomKeyName,
userId: userId as string,
});
@@ -106,8 +112,12 @@ If no relevant information is found, provide a brief statement indicating that.`
finalText = finalText + chunk;
}
+ await deletePersonalAccessToken(pat?.id);
+
return finalText;
} catch (error) {
+ await deletePersonalAccessToken(pat?.id);
+
logger.error(`SearchMemoryAgent error: ${error}`);
return `Context related to: ${userInput}. Looking for relevant background information, previous discussions, and related concepts that would help provide a comprehensive answer.`;
diff --git a/apps/webapp/app/trigger/utils/utils.ts b/apps/webapp/app/trigger/utils/utils.ts
index da3279c..18a9699 100644
--- a/apps/webapp/app/trigger/utils/utils.ts
+++ b/apps/webapp/app/trigger/utils/utils.ts
@@ -170,7 +170,7 @@ export const init = async ({ payload }: { payload: InitChatPayload }) => {
return { conversation, conversationHistory };
}
- const randomKeyName = `chat`;
+ const randomKeyName = `chat_${nanoid(10)}`;
const pat = await getOrCreatePersonalAccessToken({
name: randomKeyName,
userId: workspace.userId as string,
diff --git a/packages/emails/emails/components/Footer.tsx b/packages/emails/emails/components/Footer.tsx
index 0c8cef4..a046eac 100644
--- a/packages/emails/emails/components/Footer.tsx
+++ b/packages/emails/emails/components/Footer.tsx
@@ -1,16 +1,16 @@
-import { Hr, Link, Text } from "@react-email/components";
+import { Hr, Text } from "@react-email/components";
import React from "react";
-import { footer, footerAnchor, hr } from "./styles";
+import { footer, hr, paragraphLight } from "./styles";
export function Footer() {
return (
<>
+ happy building your digital brain!
- ©Sol.ai
-
- C.O.R.E
-
+ the Core team P.S Questions?
+
+ Just hit reply - we're here to help.
>
);
diff --git a/packages/emails/emails/components/styles.ts b/packages/emails/emails/components/styles.ts
index 6c07873..e7ca8c5 100644
--- a/packages/emails/emails/components/styles.ts
+++ b/packages/emails/emails/components/styles.ts
@@ -8,10 +8,7 @@ export const h1 = {
padding: "0",
};
-export const main = {
- backgroundColor: "#15171A",
- padding: "0 20px",
-};
+export const main = {};
export const container = {
backgroundColor: "#15171A",
@@ -30,29 +27,42 @@ export const hr = {
};
export const paragraph = {
- color: "#878C99",
+ color: "black",
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
- fontSize: "16px",
+ fontSize: "14px",
lineHeight: "24px",
textAlign: "left" as const,
};
export const paragraphLight = {
- color: "#D7D9DD",
+ color: "black",
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
- fontSize: "16px",
+ fontSize: "14px",
lineHeight: "24px",
textAlign: "left" as const,
+ margin: 0,
+};
+
+export const heading = {
+ color: "black",
+ fontFamily:
+ '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
+ fontSize: "14px",
+ lineHeight: "24px",
+ textAlign: "left" as const,
+ fontWeight: "bold",
+ margin: 0,
+ marginTop: "20px",
};
export const paragraphTight = {
- color: "#D7D9DD",
+ color: "black",
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
- fontSize: "16px",
- lineHeight: "16px",
+ fontSize: "14px",
+ lineHeight: "14px",
textAlign: "left" as const,
};
@@ -60,18 +70,19 @@ export const bullets = {
color: "#D7D9DD",
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
- fontSize: "16px",
+ fontSize: "14px",
lineHeight: "24px",
textAlign: "left" as const,
margin: "0",
};
export const anchor = {
- color: "#826DFF",
+ marginRight: "3px",
fontFamily:
"-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
- fontSize: "16px",
+ fontSize: "14px",
textDecoration: "underline",
+ color: "black",
};
export const button = {
@@ -80,7 +91,7 @@ export const button = {
color: "#D7D9DD",
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
- fontSize: "16px",
+ fontSize: "14px",
fontWeight: "bold",
textDecoration: "none",
textAlign: "center" as const,
@@ -92,7 +103,7 @@ export const footer = {
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
fontSize: "12px",
- lineHeight: "16px",
+ lineHeight: "14px",
};
export const footerItalic = {
@@ -101,7 +112,7 @@ export const footerItalic = {
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
fontSize: "12px",
- lineHeight: "16px",
+ lineHeight: "14px",
};
export const footerAnchor = {
diff --git a/packages/emails/emails/welcome.tsx b/packages/emails/emails/welcome.tsx
index abd2880..76a2bdf 100644
--- a/packages/emails/emails/welcome.tsx
+++ b/packages/emails/emails/welcome.tsx
@@ -1,59 +1,86 @@
-import { Body, Head, Html, Link, Preview, Section, Text } from "@react-email/components";
+import { Body, Head, Html, Img, Link, Preview, Text } from "@react-email/components";
import { Footer } from "./components/Footer";
-import { anchor, bullets, footerItalic, main, paragraphLight } from "./components/styles";
+import { anchor, heading, main, paragraphLight } from "./components/styles";
import { z } from "zod";
export const WelcomeEmailSchema = z.object({
email: z.literal("welcome"),
- orgName: z.string(),
- inviterName: z.string().optional(),
- inviterEmail: z.string(),
- inviteLink: z.string().url(),
});
-export function WelcomeEmail({ orgName }: { orgName?: string }) {
+export default function WelcomeEmail() {
return (
- Welcome to C.O.R.E. - Your Personal AI Assistant
+ building your digital brain
- Hey {orgName ?? "there"},
- Welcome to C.O.R.E., your new personal AI assistant!
-
- I'm excited to help you streamline your daily tasks, boost your productivity, and make
- your work life easier. C.O.R.E. is designed to be intuitive and powerful, adapting to your
- unique needs and preferences.
-
-
- To get started, you can{" "}
-
- visit your dashboard
- {" "}
- where you'll find all the features and capabilities at your disposal. Whether it's
- managing your schedule, handling communications, or automating repetitive tasks, I'm here
- to help.
-
-
-
- If you have any questions or need assistance, don't hesitate to reach out. You can:{"\n"}•
- Ask me directly through the chat interface{"\n"}•{" "}
-
- Visit our support center
+ hi there,
+
+
+ Manik
- {"\n"}• Join our{" "}
-
- Discord community
- {" "}
- to connect with other users and our team
+ from core here. welcome to core. when i first tried core memory, two actions made it click
+ for me. each came down to the same thing: understanding how I can add relevant context
+ about everything that matters to me in core memory and recall it wherever I want.
+ core mcp
+
+ seamlessly add your code context from cursor/claude-code, project context from linear, or
+ brainstorming sessions from claude desktop via mcp. solve context loss problems across ai
+ tools with persistent, cross-session memory. add this url and get started
+
+
+ https://core.heysol.ai/api/v1/mcp?source='Your Coding Agent'
+
+
+ browser extension
+
+ recall relevant context from core memory in chatgpt, grok, and gemini. save conversations
+ and content from chatgpt, grok, gemini, twitter, youtube, blog posts, and any webpage
+ directly into your Core memory with simple text selection.
+
+
- Looking forward to being your trusted assistant!
-
- Best regards,
- C.O.R.E.
- Your AI Assistant
-
- You can customize your notification preferences anytime in your account settings.
+ need real-time, human help to get started?
+
+ - join our discord community & get direct help from our team + over 100+ enthusiasts using
+ Core memory
+
+
+ - We are open-source us on our repo -{" "}
+
+ https://github.com/RedPlanetHQ/core
+
diff --git a/packages/emails/src/index.tsx b/packages/emails/src/index.tsx
index 6f7dc84..98a0928 100644
--- a/packages/emails/src/index.tsx
+++ b/packages/emails/src/index.tsx
@@ -4,7 +4,7 @@ import { z } from "zod";
import { setGlobalBasePath } from "../emails/components/BasePath";
-import { WelcomeEmail, WelcomeEmailSchema } from "../emails/welcome";
+import WelcomeEmail, { WelcomeEmailSchema } from "../emails/welcome";
import { constructMailTransport, MailTransport, MailTransportOptions } from "./transports";
import MagicLinkEmail from "../emails/magic-link";
@@ -73,14 +73,14 @@ export class EmailClient {
switch (data.email) {
case "magic_link":
return {
- subject: "Magic sign-in link for Trigger.dev",
+ subject: "Magic sign-in link for Core",
component: ,
};
case "welcome":
return {
- subject: `You've been invited to join ${data.orgName} on C.O.R.E.`,
- component: ,
+ subject: `You've been invited to join on C.O.R.E.`,
+ component: ,
};
}
}
diff --git a/packages/emails/src/transports/resend.ts b/packages/emails/src/transports/resend.ts
index 9241dd4..ce2bd0a 100644
--- a/packages/emails/src/transports/resend.ts
+++ b/packages/emails/src/transports/resend.ts
@@ -2,20 +2,20 @@ import { EmailError, MailMessage, MailTransport, PlainTextMailMessage } from "./
import { Resend } from "resend";
export type ResendMailTransportOptions = {
- type: 'resend',
+ type: "resend";
config: {
- apiKey?: string
- }
-}
+ apiKey?: string;
+ };
+};
export class ResendMailTransport implements MailTransport {
#client: Resend;
constructor(options: ResendMailTransportOptions) {
- this.#client = new Resend(options.config.apiKey)
+ this.#client = new Resend(options.config.apiKey);
}
- async send({to, from, replyTo, subject, react}: MailMessage): Promise {
+ async send({ to, from, replyTo, subject, react }: MailMessage): Promise {
const result = await this.#client.emails.send({
from: from,
to,
@@ -25,6 +25,7 @@ export class ResendMailTransport implements MailTransport {
});
if (result.error) {
+ console.log(result);
console.error(
`Failed to send email to ${to}, ${subject}. Error ${result.error.name}: ${result.error.message}`
);
@@ -32,7 +33,7 @@ export class ResendMailTransport implements MailTransport {
}
}
- async sendPlainText({to, from, replyTo, subject, text}: PlainTextMailMessage): Promise {
+ async sendPlainText({ to, from, replyTo, subject, text }: PlainTextMailMessage): Promise {
const result = await this.#client.emails.send({
from: from,
to,
diff --git a/turbo.json b/turbo.json
index 9787ad1..13dc00a 100644
--- a/turbo.json
+++ b/turbo.json
@@ -74,6 +74,11 @@
"TRIGGER_API_URL",
"TRIGGER_SECRET_KEY",
"EMBEDDING_MODEL",
- "MODEL"
+ "MODEL",
+ "COHERE_API_KEY",
+ "RESEND_API_KEY",
+ "FROM_EMAIL",
+ "REPLY_TO_EMAIL",
+ "EMAIL_TRANSPORT"
]
}