Loading...
Loading...
This skill should be used when working with Convex actions, HTTP endpoints, validators, schemas, environment variables, scheduling, file storage, and TypeScript patterns. It provides comprehensive guidelines for function definitions, API design, database limits, and advanced Convex features.
npx skill4agent add sstobo/convex-skills convex-actions-generalreferences/actions-and-general.md"use node"convex/http.tsv.object()v.array()v.string()v.number()v.id()v.boolean()v.null()v.union()v.literal()querymutationactioninternalQueryinternalMutationinternalActionapiinternalconvex/convex/schema.ts_id_creationTimeprocess.envcrons.interval()crons.cron()ctx.scheduler.runAfter()ctx.storage.generateUploadUrl()ctx.storage.getUrl()_storageId<'tableName'>Doc<'tableName'>Record<KeyType, ValueType>as const@types/nodereferences/actions-and-general.mdId// convex/ai.ts
"use node";
import { action } from "./_generated/server";
import { v } from "convex/values";
import { internal } from "./_generated/api";
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
export const generateResponse = action({
args: {
channelId: v.id("channels"),
},
handler: async (ctx, args) => {
// Actions can't access ctx.db, but can call mutations
const context = await ctx.runQuery(internal.functions.loadContext, {
channelId: args.channelId,
});
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: context,
});
const content = response.choices[0].message.content;
if (!content) throw new Error("No content in response");
await ctx.runMutation(internal.functions.writeAgentResponse, {
channelId: args.channelId,
content,
});
return null;
},
});// convex/http.ts
import { httpRouter } from "convex/server";
import { httpAction } from "./_generated/server";
const http = httpRouter();
http.route({
path: "/webhook",
method: "POST",
handler: httpAction(async (ctx, req) => {
const body = await req.json();
// Process webhook payload
return new Response(JSON.stringify({ success: true }), { status: 200 });
}),
});
export default http;