-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b452d49
commit 6e55b46
Showing
2 changed files
with
81 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import OpenAI from "https://deno.land/x/[email protected]/mod.ts"; | ||
|
||
export default function createOpenAi() { | ||
return new OpenAI({ | ||
apiKey: Deno.env.get("OPENAI_API_KEY")!, // This is the default and can be omitted | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import "https://esm.sh/@supabase/functions-js/src/edge-runtime.d.ts"; | ||
import { createSupabase } from "../create-supabase.ts"; | ||
import { isAdmin } from "../check-admin.ts"; | ||
import { buildResponse } from "../build-response.ts"; | ||
import createOpenAi from "../create-openai.ts"; | ||
import { TextContentBlock } from "https://deno.land/x/[email protected]/resources/beta/threads/messages.ts"; | ||
|
||
function restrictInputLength(input: string, length: number) { | ||
return input.length <= length ? input : input.substring(0, length); | ||
} | ||
|
||
Deno.serve(async (req) => { | ||
const supabase = createSupabase(); | ||
const openai = createOpenAi(); | ||
|
||
if (!isAdmin(req)) { | ||
return buildResponse({ message: "Unauthorised." }, 401); | ||
} | ||
|
||
// Generate the summary for the most recent bills first because we assume they are the most important | ||
const { data: row_with_null_summary, error: selectError } = await supabase | ||
.from("bill") | ||
.select("id, original_text, summary") | ||
.not("original_text", "is", null) | ||
.is("summary", null) | ||
.order("date_introduced", { ascending: false }) | ||
.limit(1) | ||
.maybeSingle(); | ||
if (selectError) throw selectError; | ||
if (!row_with_null_summary) | ||
return buildResponse({ message: "No bills need summary generation." }); | ||
|
||
console.log( | ||
`Attempting to generate summary for bill from row ID ${row_with_null_summary.id}...`, | ||
); | ||
const run = await openai.beta.threads.createAndRunPoll({ | ||
assistant_id: Deno.env.get("OPENAI_BILL_SUMMARY_ASSISTANT_ID")!, | ||
thread: { | ||
messages: [ | ||
{ | ||
role: "user", | ||
// The input length limit is 256,000 characters for GPT 4o mini, independent of the token limit | ||
content: restrictInputLength( | ||
row_with_null_summary.original_text!, | ||
256000, | ||
), | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
if (run.status == "completed") { | ||
const responses = await openai.beta.threads.messages.list(run.thread_id, { | ||
run_id: run.id, | ||
}); | ||
const summary = (responses.data[0].content[0] as TextContentBlock).text | ||
.value; | ||
console.log(`Summary generated: ${summary}`); | ||
|
||
const { error: updateError } = await supabase | ||
.from("bill") | ||
.update({ summary }) | ||
.eq("id", row_with_null_summary.id); | ||
if (updateError) throw updateError; | ||
|
||
return buildResponse({ | ||
message: `Added generated summary to row ID ${row_with_null_summary.id}.`, | ||
}); | ||
} else { | ||
throw new Error( | ||
`Summary generation failed. The run dump is as follows: ${JSON.stringify(run)}`, | ||
); | ||
} | ||
}); |