11import { Anthropic } from "@anthropic-ai/sdk"
2+ import OpenAI from "openai"
23
3- import { rooDefaultModelId , rooModels , type RooModelId } from "@roo-code/types"
4+ import { AuthState , rooDefaultModelId , rooModels , type RooModelId } from "@roo-code/types"
45import { CloudService } from "@roo-code/cloud"
56
67import type { ApiHandlerOptions } from "../../shared/api"
78import { ApiStream } from "../transform/stream"
89
910import type { ApiHandlerCreateMessageMetadata } from "../index"
11+ import { DEFAULT_HEADERS } from "./constants"
1012import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider"
1113
1214export class RooHandler extends BaseOpenAiCompatibleProvider < RooModelId > {
15+ private authStateListener ?: ( state : { state : AuthState } ) => void
16+
1317 constructor ( options : ApiHandlerOptions ) {
14- // Get the session token if available, but don't throw if not.
15- // The server will handle authentication errors and return appropriate status codes.
16- let sessionToken = ""
18+ let sessionToken : string | undefined = undefined
1719
1820 if ( CloudService . hasInstance ( ) ) {
19- sessionToken = CloudService . instance . authService ?. getSessionToken ( ) || ""
21+ sessionToken = CloudService . instance . authService ?. getSessionToken ( )
2022 }
2123
2224 // Always construct the handler, even without a valid token.
@@ -25,11 +27,39 @@ export class RooHandler extends BaseOpenAiCompatibleProvider<RooModelId> {
2527 ...options ,
2628 providerName : "Roo Code Cloud" ,
2729 baseURL : process . env . ROO_CODE_PROVIDER_URL ?? "https://api.roocode.com/proxy/v1" ,
28- apiKey : sessionToken || "unauthenticated" , // Use a placeholder if no token
30+ apiKey : sessionToken || "unauthenticated" , // Use a placeholder if no token.
2931 defaultProviderModelId : rooDefaultModelId ,
3032 providerModels : rooModels ,
3133 defaultTemperature : 0.7 ,
3234 } )
35+
36+ if ( CloudService . hasInstance ( ) ) {
37+ const cloudService = CloudService . instance
38+
39+ this . authStateListener = ( state : { state : AuthState } ) => {
40+ if ( state . state === "active-session" ) {
41+ this . client = new OpenAI ( {
42+ baseURL : this . baseURL ,
43+ apiKey : cloudService . authService ?. getSessionToken ( ) ?? "unauthenticated" ,
44+ defaultHeaders : DEFAULT_HEADERS ,
45+ } )
46+ } else if ( state . state === "logged-out" ) {
47+ this . client = new OpenAI ( {
48+ baseURL : this . baseURL ,
49+ apiKey : "unauthenticated" ,
50+ defaultHeaders : DEFAULT_HEADERS ,
51+ } )
52+ }
53+ }
54+
55+ cloudService . on ( "auth-state-changed" , this . authStateListener )
56+ }
57+ }
58+
59+ dispose ( ) {
60+ if ( this . authStateListener && CloudService . hasInstance ( ) ) {
61+ CloudService . instance . off ( "auth-state-changed" , this . authStateListener )
62+ }
3363 }
3464
3565 override async * createMessage (
0 commit comments