classify.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { generateText, Output } from 'ai'
  2. import { NextApiRequest, NextApiResponse } from 'next'
  3. import { z } from 'zod'
  4. import { getModel } from '@/lib/ai/model'
  5. import { DEFAULT_COMPLETION_MODEL } from '@/lib/ai/model.utils'
  6. import apiWrapper from '@/lib/api/apiWrapper'
  7. async function handler(req: NextApiRequest, res: NextApiResponse) {
  8. const { method } = req
  9. switch (method) {
  10. case 'POST':
  11. return handlePost(req, res)
  12. default:
  13. res.setHeader('Allow', ['POST'])
  14. res.status(405).json({ data: null, error: { message: `Method ${method} Not Allowed` } })
  15. }
  16. }
  17. export async function handlePost(req: NextApiRequest, res: NextApiResponse) {
  18. const {
  19. body: { prompt },
  20. } = req
  21. if (!prompt) {
  22. return res.status(400).json({
  23. error: 'Prompt is required',
  24. })
  25. }
  26. try {
  27. const { modelParams, error: modelError } = await getModel({
  28. provider: 'openai',
  29. modelEntry: DEFAULT_COMPLETION_MODEL,
  30. })
  31. if (modelError) {
  32. return res.status(500).json({ error: modelError.message })
  33. }
  34. const { output } = await generateText({
  35. ...modelParams,
  36. output: Output.object({
  37. schema: z.object({
  38. feedback_category: z.enum(['support', 'feedback', 'unknown']),
  39. }),
  40. }),
  41. temperature: 0,
  42. prompt: `
  43. Classify the following feedback as ONE of: support, feedback, unknown.
  44. - support: bug reports, help requests, or issues
  45. - feedback: feature requests or suggestions
  46. - unknown: unclear or unrelated
  47. If you can't determine support or feedback, always output "unknown".
  48. Only output a JSON object in this format: { "feedback_category": "support|feedback|unknown" }
  49. Examples:
  50. Feedback: "Whenever I try to invite a team member, the invite email doesn't get sent."
  51. Response: { "feedback_category": "support" }
  52. Feedback: "I have reached the storage limit for my project and my plan. I cannot understand how I can expand the storage space in my project."
  53. Response: { "feedback_category": "support" }
  54. Feedback: "Please delete the project x in my account"
  55. Response: { "feedback_category": "support" }
  56. Feedback: "My billing page is broken"
  57. Response: { "feedback_category": "support" }
  58. Feedback: "I accidentally deleted my database—can it be recovered?"
  59. Response: { "feedback_category": "support" }
  60. Feedback: "My login tokens are expiring too quickly, even though I didn't change any settings."
  61. Response: { "feedback_category": "support" }
  62. Feedback: "Can you add more integrations?"
  63. Response: { "feedback_category": "feedback" }
  64. Feedback: "I'm getting charged for a project I thought I deleted. Can you help me stop billing?"
  65. Response: { "feedback_category": "support" }
  66. Feedback: "Could you support OAuth login for more providers like Apple or LinkedIn?"
  67. Response: { "feedback_category": "feedback" }
  68. Feedback: "It's unclear in the docs how to set up row-level security with multiple roles."
  69. Response: { "feedback_category": "feedback" }
  70. Feedback: "I am trying to pause my Pro project"
  71. Response: { "feedback_category": "feedback" }
  72. Feedback: "${prompt}"
  73. Response:
  74. `,
  75. })
  76. return res.json({ feedback_category: output.feedback_category })
  77. } catch (error) {
  78. if (error instanceof Error) {
  79. console.error(`Classifying this feedback failed`)
  80. // Check for context length error
  81. if (error.message.includes('context_length') || error.message.includes('too long')) {
  82. return res.status(400).json({
  83. error: 'This prompt is too large to ingest',
  84. })
  85. }
  86. } else {
  87. console.error(`Unknown error: ${error}`)
  88. }
  89. return res.status(500).json({
  90. error: 'There was an unknown error generating the feedback category.',
  91. })
  92. }
  93. }
  94. const wrapper = (req: NextApiRequest, res: NextApiResponse) =>
  95. apiWrapper(req, res, handler, { withAuth: true })
  96. export default wrapper