Web Dev Cody
Web Dev Cody5mo ago

Error I can't get

Any clue why I'm getting this error. It says it's coming from open api sdk, and I assume it's related to needing 'use node', but the strange thing everything was working fine without needing use node until I refactored the logic into an internalAction and scheduled it from a mutation
No description
3 Replies
Web Dev Cody
Web Dev CodyOP5mo ago
export const startRoughDraftMutation = mutation({
args: {
script: v.string(),
title: v.string(),
},
async handler(ctx, args) {
const userId = await auth.getUserId(ctx);

if (userId === null) {
throw new Error("User is not logged in");
}

const textSegments = await getSegments(args.script);

await consumeCreditsHelper(
ctx,
userId,
textSegments.length * CREDIT_COSTS.IMAGE_GENERATION,
);

const storyId = await ctx.db.insert("story", {
script: args.script,
userId: userId,
title: args.title,
});

await Promise.all(
textSegments.map(async (textSegment, idx) => {
const segmentId = await ctx.db.insert("segments", {
storyId,
text: textSegment,
order: idx,
});

await ctx.scheduler.runAfter(
0,
internal.segments.generateSegmentImageReplicateInternal,
{
segment: {
text: textSegment,
_id: segmentId,
},
},
);
}),
);
},
});
export const startRoughDraftMutation = mutation({
args: {
script: v.string(),
title: v.string(),
},
async handler(ctx, args) {
const userId = await auth.getUserId(ctx);

if (userId === null) {
throw new Error("User is not logged in");
}

const textSegments = await getSegments(args.script);

await consumeCreditsHelper(
ctx,
userId,
textSegments.length * CREDIT_COSTS.IMAGE_GENERATION,
);

const storyId = await ctx.db.insert("story", {
script: args.script,
userId: userId,
title: args.title,
});

await Promise.all(
textSegments.map(async (textSegment, idx) => {
const segmentId = await ctx.db.insert("segments", {
storyId,
text: textSegment,
order: idx,
});

await ctx.scheduler.runAfter(
0,
internal.segments.generateSegmentImageReplicateInternal,
{
segment: {
text: textSegment,
_id: segmentId,
},
},
);
}),
);
},
});
export const generateSegmentImageReplicateInternal = internalAction({
args: {
segment: v.object({
text: v.string(),
_id: v.id("segments"),
}),
},
async handler(ctx, args) {
const prompt = await openai.chat.completions
.create({
messages: [
{
role: "system",
content: `
You will be provided a segment from a story and you need to generate a descriptive set of keywords to be used in an stable diffusion image generation model. Please keep the most important details, obhects, and scenes near the front of your description. This should be for a scary story, so use words that help paint a scary or gloomy image.
`,
},
{
role: "user",
content: args.segment.text,
},
],
model: "gpt-4o-mini",
response_format: zodResponseFormat(
z.object({
prompt: z.string(),
}),
"prompt",
),
})
.then((completion) => {
const content = completion.choices[0].message.content as string;
return JSON.parse(content).prompt;
});

await ctx.scheduler.runAfter(
0,
internal.segments.regenerateSegmentImageUsingPrompt,
{
segmentId: args.segment._id,
prompt: `${prompt}, high quality`,
},
);
},
});
export const generateSegmentImageReplicateInternal = internalAction({
args: {
segment: v.object({
text: v.string(),
_id: v.id("segments"),
}),
},
async handler(ctx, args) {
const prompt = await openai.chat.completions
.create({
messages: [
{
role: "system",
content: `
You will be provided a segment from a story and you need to generate a descriptive set of keywords to be used in an stable diffusion image generation model. Please keep the most important details, obhects, and scenes near the front of your description. This should be for a scary story, so use words that help paint a scary or gloomy image.
`,
},
{
role: "user",
content: args.segment.text,
},
],
model: "gpt-4o-mini",
response_format: zodResponseFormat(
z.object({
prompt: z.string(),
}),
"prompt",
),
})
.then((completion) => {
const content = completion.choices[0].message.content as string;
return JSON.parse(content).prompt;
});

await ctx.scheduler.runAfter(
0,
internal.segments.regenerateSegmentImageUsingPrompt,
{
segmentId: args.segment._id,
prompt: `${prompt}, high quality`,
},
);
},
});
so a mutation which schedules and action, and the action calls openai
lee
lee5mo ago
huh. The error message indicates that the mutation is calling openai directly. Is it possible that getSegments or consumeCreditsHelper calls openai? The stacktrace says that the call is happening on line 71 of story.ts. What's on that line?
Web Dev Cody
Web Dev CodyOP5mo ago
export async function consumeCreditsHelper(
ctx: MutationCtx,
userId: Id<"users">,
amountToUse: number,
) {
const credits = await ctx.db
.query("credits")
.withIndex("userId_index", (q) => q.eq("userId", userId))
.first();

if (!credits) {
throw new ConvexError("No credits found");
}

if (credits.remaining < amountToUse) {
throw new ConvexError("Insufficient credits");
}

await ctx.db.patch(credits._id, {
remaining: credits.remaining - amountToUse,
});
}
export async function consumeCreditsHelper(
ctx: MutationCtx,
userId: Id<"users">,
amountToUse: number,
) {
const credits = await ctx.db
.query("credits")
.withIndex("userId_index", (q) => q.eq("userId", userId))
.first();

if (!credits) {
throw new ConvexError("No credits found");
}

if (credits.remaining < amountToUse) {
throw new ConvexError("Insufficient credits");
}

await ctx.db.patch(credits._id, {
remaining: credits.remaining - amountToUse,
});
}
doesn't seem like it oh yes get segments does ty

Did you find this page helpful?