1+ // src/app/api/extract-cost-parameters/route.ts
2+ import { openai } from '@ai-sdk/openai' ;
3+ import { generateObject } from 'ai' ;
4+ import { z } from 'zod' ;
5+ import { NextResponse } from 'next/server' ;
6+
7+ // Define the schema for cost parameters
8+ const costParametersSchema = z . object ( {
9+ model : z . string ( ) . nullable ( ) . optional ( ) ,
10+ promptTokenCost : z . number ( ) . nullable ( ) . optional ( ) ,
11+ completionTokenCost : z . number ( ) . nullable ( ) . optional ( ) ,
12+ discount : z . number ( ) . default ( 0 ) . optional ( ) ,
13+ timeframe : z . string ( ) . default ( 'last month' ) . optional ( ) ,
14+ volumeChange : z . number ( ) . default ( 0 ) . optional ( ) ,
15+ start_date : z . string ( ) . optional ( ) ,
16+ end_date : z . string ( ) . optional ( )
17+ } ) ;
18+
19+ // Create a type from the schema
20+ type CostParameters = z . infer < typeof costParametersSchema > ;
21+
22+ export async function POST ( req : Request ) {
23+ try {
24+ const { query } = await req . json ( ) ;
25+
26+ if ( ! query ) {
27+ return NextResponse . json ( { error : 'Query is required' } , { status : 400 } ) ;
28+ }
29+
30+ // Get today's date for the prompt
31+ const today = new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ; // Format: YYYY-MM-DD
32+
33+ const systemPromptText = `
34+ You are a cost prediction parameter extractor. Extract parameters from natural language queries about AI model cost predictions.
35+
36+ Today's date is ${ today } .
37+
38+ Return values for these parameters:
39+ - model: The AI model mentioned (e.g., "gpt-4", "claude-sonnet")
40+ - promptTokenCost: Cost per prompt token (in USD)
41+ - completionTokenCost: Cost per completion token (in USD)
42+ - discount: Any discount percentage mentioned (0-100)
43+ - timeframe: Time period for analysis (e.g., "last month", "last week", "last 3 months", "last year")
44+ - volumeChange: Any volume change percentage mentioned (can be positive or negative)
45+ - start_date: The start date in YYYY-MM-DD format based on the timeframe
46+ - end_date: The end date in YYYY-MM-DD format (usually today: ${ today } )
47+
48+ For timeframes, calculate the appropriate start_date:
49+ - "last week" = 7 days before today
50+ - "last month" = 1 month before today
51+ - "last 3 months" = 3 months before today
52+ - "last year" = 1 year before today
53+
54+ If a parameter is not specified in the query, omit it from your response.
55+ Always include start_date and end_date based on the timeframe (default to "last month" if not specified).
56+ ` ;
57+
58+ const result = await generateObject ( {
59+ model : openai ( 'gpt-3.5-turbo' ) ,
60+ schema : costParametersSchema ,
61+ prompt : query ,
62+ systemPrompt : systemPromptText ,
63+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64+ } as any ) ;
65+
66+ // Type assertion to handle the result object
67+ const extractedParams = result . object as CostParameters ;
68+
69+ // Apply defaults for missing parameters
70+ const processedResult = {
71+ model : extractedParams . model || null ,
72+ promptTokenCost : extractedParams . promptTokenCost || null ,
73+ completionTokenCost : extractedParams . completionTokenCost || null ,
74+ discount : extractedParams . discount || 0 ,
75+ timeframe : extractedParams . timeframe || 'last month' ,
76+ volumeChange : extractedParams . volumeChange || 0 ,
77+ start_date : extractedParams . start_date || getDefaultStartDate ( 'last month' ) ,
78+ end_date : extractedParams . end_date || today
79+ } ;
80+
81+ return NextResponse . json ( processedResult ) ;
82+ } catch ( error ) {
83+ console . error ( 'Error extracting parameters:' , error ) ;
84+ return NextResponse . json ( { error : 'Failed to extract parameters' } , { status : 500 } ) ;
85+ }
86+ }
87+
88+ // Fallback function to calculate start date if the LLM doesn't provide one
89+ function getDefaultStartDate ( timeframe : string ) : string {
90+ const now = new Date ( ) ;
91+ const startDate = new Date ( ) ;
92+
93+ if ( timeframe === 'last week' ) {
94+ startDate . setDate ( now . getDate ( ) - 7 ) ;
95+ } else if ( timeframe === 'last month' ) {
96+ startDate . setMonth ( now . getMonth ( ) - 1 ) ;
97+ } else if ( timeframe === 'last 3 months' ) {
98+ startDate . setMonth ( now . getMonth ( ) - 3 ) ;
99+ } else if ( timeframe === 'last year' ) {
100+ startDate . setFullYear ( now . getFullYear ( ) - 1 ) ;
101+ } else {
102+ // Default to last month
103+ startDate . setMonth ( now . getMonth ( ) - 1 ) ;
104+ }
105+
106+ return startDate . toISOString ( ) . split ( 'T' ) [ 0 ] ;
107+ }
0 commit comments