From 72ccc8f9b6dc4990e051e0292581d53a88ec6372 Mon Sep 17 00:00:00 2001
From: Rami Abdou <38056800+ramiAbdou@users.noreply.github.com>
Date: Fri, 20 Dec 2024 23:30:30 -0800
Subject: [PATCH] =?UTF-8?q?fix:=20potential=20ai=20hallucination=20with=20?=
=?UTF-8?q?opportunity=20refinement=20=E2=9D=97=EF=B8=8F=20(#689)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/core/src/modules/opportunities.ts | 24 ++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/packages/core/src/modules/opportunities.ts b/packages/core/src/modules/opportunities.ts
index 11e2f1da..9298dbff 100644
--- a/packages/core/src/modules/opportunities.ts
+++ b/packages/core/src/modules/opportunities.ts
@@ -461,6 +461,10 @@ const REFINE_OPPORTUNITY_PROMPT = dedent`
Follow these guidelines:
- If you cannot confidently infer a field, set it to null.
+ - If the page is not found, expired, or otherwise not a valid opportunity,
+ set all fields to null.
+ - Double check that your output is based on the website content. Don't make
+ up information that you cannot confidently infer from the website content.
Your output should be a single JSON object containing these fields. Do not
provide any explanation or text outside of the JSON object. Ensure your JSON
@@ -469,20 +473,20 @@ const REFINE_OPPORTUNITY_PROMPT = dedent`
`;
const RefineOpportunityResponse = z.object({
company: z.string().trim().min(1).nullable(),
- description: z.string().trim().min(1).max(500),
+ description: z.string().trim().min(1).max(500).nullable(),
expiresAt: z.string().nullable(),
- tags: z.array(z.string().trim().min(1)).min(1),
- title: z.string().trim().min(1).max(100),
+ tags: z.array(z.string().trim().min(1)).min(1).nullable(),
+ title: z.string().trim().min(1).max(100).nullable(),
});
type RefineOpportunityResponse = z.infer;
@@ -569,10 +573,10 @@ export async function refineOpportunity(
const opportunity = await trx
.updateTable('opportunities')
.set({
+ ...(data.description && { description: data.description }),
+ ...(data.title && { title: data.title }),
companyId,
- description: data.description,
expiresAt,
- title: data.title,
})
.where('id', '=', input.opportunityId)
.returning(['id', 'refinedAt', 'slackChannelId', 'slackMessageId'])
@@ -587,6 +591,10 @@ export async function refineOpportunity(
.where('refinedAt', 'is', null)
.executeTakeFirst();
+ if (!data.tags) {
+ return opportunity;
+ }
+
const upsertedTags = await trx
.insertInto('opportunityTags')
.values(