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` { "company": "string | null", - "description": "string", + "description": "string | null", "expiresAt": "string | null", - "tags": "string[]", - "title": "string" + "tags": "string[] | null", + "title": "string | null" } `; 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(