diff --git a/common/prompts.ts b/common/prompts.ts index 4d74f28..96f6b4f 100644 --- a/common/prompts.ts +++ b/common/prompts.ts @@ -81,6 +81,23 @@ And now, here are the claims: \${claims} `; +export const defaultCruxPrompt = ` +I'm going to give you a topic with a description and a list of high-level claims about this topic made by different participants, +identified by pseudonyms like "Person 1" or "A". I want you to formulate a new, specific statement called a "cruxClaim" +which would best split the participants into two groups, based on all their +statements on this topic: one group which would agree with the statement, and one which would disagree. +Please explain your reasoning and assign participants into "agree" and "disagree" groups. +return a JSON object of the form +{ + "crux" : { + "cruxClaim" : string // the new extracted claim + "agree" : list of strings // list of the given participants who would agree with the cruxClaim + "disagree" : list strings // list of the given participants who would disagree with the cruxClaim + "explanation" : string // reasoning for why you synthesized this cruxClaim from the participants' perspective + } +} +`; + /** * Takes a prompt and data, and then inserts those values into the prompt. * The reason for this is that the string the user provides can't actually be a template literal. diff --git a/common/schema.ts b/common/schema.ts index b245d61..d3e354e 100644 --- a/common/schema.ts +++ b/common/schema.ts @@ -71,6 +71,7 @@ export const llmUserConfig = z.object({ extractionInstructions: z.string().min(1), dedupInstructions: z.string().min(1), cruxInstructions: z.string().optional(), + cruxesEnabled: z.boolean().optional(), }); export type LLMUserConfig = z.infer; @@ -96,6 +97,7 @@ export const oldOptions = z.object({ extractionInstructions: z.string(), dedupInstructions: z.string(), cruxInstructions: z.string().optional(), + cruxesEnabled: z.boolean().optional(), batchSize: z.number(), filename: z.string(), googleSheet: z diff --git a/express-server/src/workers.ts b/express-server/src/workers.ts index 47f69ba..7e2e4d9 100644 --- a/express-server/src/workers.ts +++ b/express-server/src/workers.ts @@ -72,6 +72,7 @@ const setupPipelineWorker = (connection: Redis) => { extractionInstructions: "", dedupInstructions: "", cruxInstructions: "", + cruxesEnabled: false, batchSize: 2, // lower to avoid rate limits! initial was 10, }; @@ -83,6 +84,7 @@ const setupPipelineWorker = (connection: Redis) => { }); const options: schema.OldOptions = { ...defaultConfig, ...config }; + console.log("CRUX OPTIONS: ", options.cruxesEnabled); const [ topicTreeLLMConfig, @@ -164,6 +166,7 @@ const setupPipelineWorker = (connection: Redis) => { }); logTokensInTracker(tracker_step2); + console.log("CRUX OPTIONS: ", options.cruxesEnabled); console.log("Step 2.5: Optionally extract cruxes"); const { cruxClaims, diff --git a/next-client/src/components/create/CreateReport.tsx b/next-client/src/components/create/CreateReport.tsx index a6f02d0..6135ce7 100644 --- a/next-client/src/components/create/CreateReport.tsx +++ b/next-client/src/components/create/CreateReport.tsx @@ -48,6 +48,7 @@ import { User } from "firebase/auth"; import { useFormStatus } from "react-dom"; import { useRouter } from "next/navigation"; import { signInWithGoogle } from "@/lib/firebase/auth"; +import { crux } from "tttc-common/schema"; const fetchToken = async ( user: User | null, @@ -85,6 +86,8 @@ const form = z.object({ clusteringInstructions: z.string().min(1), extractionInstructions: z.string().min(1), dedupInstructions: z.string().min(1), + cruxInstructions: z.string().optional(), + cruxesEnabled: z.boolean().optional(), }); function Center({ children }: React.PropsWithChildren) { @@ -179,6 +182,8 @@ function CreateReportComponent({ token }: { token: string | null }) { clusteringInstructions: prompts.defaultClusteringPrompt, extractionInstructions: prompts.defaultExtractionPrompt, dedupInstructions: prompts.defaultDedupPrompt, + cruxInstructions: prompts.defaultCruxPrompt, + cruxesEnabled: false, }, }); @@ -196,6 +201,7 @@ function CreateReportComponent({ token }: { token: string | null }) { +
@@ -524,6 +530,42 @@ const FormOpenAIKey = () => { ); }; +const EnableResearchFeatures = () => { + const [areCruxesEnabled, setCruxesEnabled] = React.useState(false); + const handleChange = (event) => { + setCruxesEnabled((areCruxesEnabled) => !areCruxesEnabled); + console.log("ARE CRUXES ENABLED? : ", areCruxesEnabled.toString()); + }; + return ( + +

Enable Research Features

+ + + +

+ As an extra processing step, suggest pairs of + perspective-summarizing statements which would best split the + respondents (into agree/disagree sides/groups of about equal size). +

+
+ + +
+ + + + ); +}; + const CustomizePrompts = () => ( @@ -555,6 +597,11 @@ const CustomizePrompts = () => ( subheader="In the last step, AI collects very similar or near-duplicate statements under one representative claim" inputName="dedupInstructions" /> + ); diff --git a/next-client/src/features/submission/actions/SubmitAction.ts b/next-client/src/features/submission/actions/SubmitAction.ts index 2ef8f9b..fc81d2d 100644 --- a/next-client/src/features/submission/actions/SubmitAction.ts +++ b/next-client/src/features/submission/actions/SubmitAction.ts @@ -34,21 +34,6 @@ export default async function submitAction( throw new Error("Missing data. Check your csv file"); } - const tempCruxInstructions = `I'm going to give you a topic with a description and a list of high-level claims about this topic made by different participants, - identified by pseudonyms like "Person 1" or "A". I want you to formulate a new, specific statement called a "cruxClaim" - which would best split the participants into two groups, based on all their - statements on this topic: one group which would agree with the statement, and one which would disagree. - Please explain your reasoning and assign participants into "agree" and "disagree" groups. - return a JSON object of the form - { - "crux" : { - "cruxClaim" : string // the new extracted claim - "agree" : list of strings // list of the given participants who would agree with the cruxClaim - "disagree" : list strings // list of the given participants who would disagree with the cruxClaim - "explanation" : string // reasoning for why you synthesized this cruxClaim from the participants' perspective - } - } - `; const config: LLMUserConfig = llmUserConfig.parse({ apiKey: formData.get("apiKey"), title: formData.get("title"), @@ -58,7 +43,8 @@ export default async function submitAction( systemInstructions: formData.get("systemInstructions"), extractionInstructions: formData.get("extractionInstructions"), dedupInstructions: formData.get("dedupInstructions"), - cruxInstructions: tempCruxInstructions, + cruxInstructions: formData.get("cruxInstructions"), + cruxesEnabled: formData.get("cruxesEnabled"), }); const dataPayload: DataPayload = ["csv", data];