
    Hj>                    B   d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	 ddl
mZmZ ddlmZmZmZ dd	lmZ dd
lmZmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl m!Z!  edg      Z" G d de      Z# G d de      Z$d dZ%e"jM                  d      d ee       ee      fd!d       Z'e"jQ                  d       ee       ee      fd"d       Z)e"jM                  d       ee       ee      fd#d       Z*e"jQ                  d       ee       ee      fd$d       Z+y)%z'Optional Claude reviews of a draft run.    )annotationsN)	APIRouterDependsHTTPException)
Connection)	BaseModelField   )Usercurrent_userrequire_center)config_by_id)Jsonbfetchallfetchoneget_conn)find_analogs)claude)get_settings   )_query_from_inputs)	_load_runai)tagsc                  B    e Zd ZU ded<    ed      Zded<   dZded	<   y)
ReviewInintrun_idz/^(review_draft|draft_bottom_line|sanity_check)$)patternstrmodeN
str | Nonemodel)__name__
__module____qualname____annotations__r	   r!   r#        +/var/www/avy-guidance/api/app/routers/ai.pyr   r      s!    KOPD#PE:r)   r   c                  :    e Zd ZU  edd      Zded<   dZded<   y)	
FeedbackInr   )geler   feedbackNr"   note)r$   r%   r&   r	   r0   r'   r1   r(   r)   r*   r,   r,      s    RA&Hc&D*r)   r,   c                :    t        | d|f      }t        |d         S )NzxSELECT coalesce(sum(cost_usd), 0) AS s FROM ai_reviews WHERE center_id = %s AND created_at >= date_trunc('month', now())s)r   float)conn	center_idrows      r*   _month_spendr8   !   s*    
 	C	C
 S?r)   z
/ai/statusc                    t               }t        j                         |j                  |j                  |j
                  d}| t        ||        t        ||       |d<   |S )N)enabledmodelsdefault_modelmonthly_cap_usdmonth_spend_usd)r   r   r:   ai_allowed_modelsai_default_modelai_monthly_cap_usdr   r8   )r6   r5   userr3   outs        r*   statusrD   *   s[    Ann&!2E2EXYXjXj224CtY'!-dI!>Jr)   z
/ai/reviewc                   t               }t        j                         st        dd      | j                  xs |j
                  }||j                  vrt        dd|j                         t        || j                  |      }t        ||d         |j                  k\  rt        dd      t        ||d         d	   }t        ||d   t        |d
   |      |d   |d   d      d   }t        j                  |||d   || j                  |      }	 t        j                   |      }	t1        |d|d   |d   |j2                  | j                  |t        j4                  |D cg c]  }|d   	 c}|	d   t7        |	d         nd |	d   |	d   |	d   |	d   |	d   |	d   |	d   |	d    f      S # t        j"                  $ r}
t        dt%        |
            |
d }
~
wt&        j(                  $ r}
t        dd      |
d }
~
wt&        j*                  $ r }
t        dd|
j,                   d      |
d }
~
wt&        j.                  $ r}
t        dd      |
d }
~
ww xY wc c}w )!Ni  z+AI review is not configured on this server.i  zModel must be one of r6   i  z5This center has reached its monthly AI review budget.	config_idconfiginputs
valid_datezone_id   )kitemscenter_namez4Claude is rate limited right now; try again shortly.i  zClaude API error (z).zCould not reach the Claude API.ad  INSERT INTO ai_reviews (center_id, tool_run_id, user_id, mode, model, prompt_version, retrieved_forecast_ids,
               output, stop_reason, fallback_model, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,
               cost_usd, error)
           VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING *idoutputstop_reasonfallback_modelinput_tokensoutput_tokenscache_read_tokenscache_write_tokenscost_usderror)r   r   r:   r   r#   r@   r?   r   r   r8   rA   r   r   r   build_requestr!   
run_reviewAIUnavailabler    	anthropicRateLimitErrorAPIStatusErrorstatus_codeAPIConnectionErrorr   rO   PROMPT_VERSIONr   )bodyr5   rB   r3   r#   runrG   analogsparamsresulteas               r*   reviewri   5   s   A>>C!NOOJJ,!,,EA'''C#89L9L8M!NOO
D$++t
,CD#k*+q/C/CCC!XYY$K 01(;F4[!13Ec(mU[3\^abn^oqtu~q  DE  F  GN  OG!!#vs=/A7DIIW\]F	K""6* 	b 
[	3t9dggtyy%AVAVjqXrefYZ[_Y`Xr$*8$4$@vh	 dFS`Lacijzc{		!8&AT:UW]^rWs	
	VG_	.
 
  0CQ(a/## `C!WX^__## PC#5amm_B!GHaO'' KC!BCJK YssB   F% I%I
8GI
$G11I
H""I
8II
z/runs/{run_id}/reviewsc                8    t        || |       t        |d| f      S )NzHSELECT * FROM ai_reviews WHERE tool_run_id = %s ORDER BY created_at DESC)r   r   )r   r5   rB   s      r*   list_reviewsrk   Z   s"    dFD!Ddgmfoppr)   z /ai/reviews/{review_id}/feedbackc                    t        |d| f      }|st        dd      t        ||d          |j                  d|j                  |j
                  | f       ddiS )Nz.SELECT center_id FROM ai_reviews WHERE id = %si  zReview not foundr6   zEUPDATE ai_reviews SET feedback = %s, feedback_note = %s WHERE id = %sokT)r   r   r   executer0   r1   )	review_idrb   r5   rB   r7   s        r*   r0   r0   `   se    
4II<
XCC!3444[)*LLX[_[h[hjnjsjsu~Z  A$<r)   )r5   r   r6   r   returnr4   )r6   z
int | Noner5   r   rB   r   )rb   r   r5   r   rB   r   )r   r   r5   r   rB   r   )ro   r   rb   r,   r5   r   rB   r   ),__doc__
__future__r   r\   fastapir   r   r   psycopgr   pydanticr   r	   authr   r   r   configsr   dbr   r   r   r   	retrievalr   servicesr   settingsr   	forecastsr   runsr   routerr   r,   r8   getrD   postri   rk   r0   r(   r)   r*   <module>r      s   - "  5 5  % 5 5 " 4 4 $  # ) 		y  
 L#'GH<M\cdp\q   \.5h.?gVbNc ! !H $%181BQXYeQf q &q
 /0BI(BSbijvbw  1r)   