@@ -17,9 +17,13 @@ import { useQueryParams } from "../hooks/use-query-params";
1717import {
1818 AGENT_INBOX_GITHUB_README_URL ,
1919 NO_INBOXES_FOUND_PARAM ,
20+ LANGCHAIN_API_KEY_LOCAL_STORAGE_KEY ,
2021} from "../constants" ;
2122import { PasswordInput } from "@/components/ui/password-input" ;
22- import { isDeployedUrl } from "../utils" ;
23+ import { isDeployedUrl , fetchDeploymentInfo } from "../utils" ;
24+ import { useLocalStorage } from "../hooks/use-local-storage" ;
25+ import { LoaderCircle } from "lucide-react" ;
26+ import { logger } from "../utils/logger" ;
2327
2428export function AddAgentInboxDialog ( {
2529 hideTrigger,
@@ -38,10 +42,13 @@ export function AddAgentInboxDialog({
3842 const { searchParams, updateQueryParams } = useQueryParams ( ) ;
3943 const { toast } = useToast ( ) ;
4044 const { addAgentInbox } = useThreadsContext ( ) ;
45+ const { getItem } = useLocalStorage ( ) ;
4146 const [ open , setOpen ] = React . useState ( false ) ;
4247 const [ graphId , setGraphId ] = React . useState ( "" ) ;
4348 const [ deploymentUrl , setDeploymentUrl ] = React . useState ( "" ) ;
4449 const [ name , setName ] = React . useState ( "" ) ;
50+ const [ isSubmitting , setIsSubmitting ] = React . useState ( false ) ;
51+ const [ errorMessage , setErrorMessage ] = React . useState < string | null > ( null ) ;
4552
4653 const noInboxesFoundParam = searchParams . get ( NO_INBOXES_FOUND_PARAM ) ;
4754
@@ -54,35 +61,108 @@ export function AddAgentInboxDialog({
5461 setOpen ( true ) ;
5562 }
5663 } catch ( e ) {
57- console . error ( "Error getting/setting no inboxes found param" , e ) ;
64+ logger . error ( "Error getting/setting no inboxes found param" , e ) ;
5865 }
5966 } , [ noInboxesFoundParam ] ) ;
6067
61- const handleSubmit = ( event : React . FormEvent < HTMLFormElement > ) => {
68+ const handleSubmit = async ( event : React . FormEvent < HTMLFormElement > ) => {
6269 event . preventDefault ( ) ;
63- addAgentInbox ( {
64- id : uuidv4 ( ) ,
65- graphId,
66- deploymentUrl,
67- name,
68- selected : true ,
69- } ) ;
70- toast ( {
71- title : "Success" ,
72- description : "Agent inbox added successfully" ,
73- duration : 3000 ,
74- } ) ;
75- updateQueryParams ( NO_INBOXES_FOUND_PARAM ) ;
76-
77- setGraphId ( "" ) ;
78- setDeploymentUrl ( "" ) ;
79- setName ( "" ) ;
80- setOpen ( false ) ;
70+ setIsSubmitting ( true ) ;
71+ setErrorMessage ( null ) ;
72+
73+ try {
74+ const isDeployed = isDeployedUrl ( deploymentUrl ) ;
75+ let inboxId = uuidv4 ( ) ;
76+ let tenantId : string | undefined = undefined ;
77+
78+ // For deployed graphs, get the deployment info to generate the ID
79+ if ( isDeployed ) {
80+ logger . log (
81+ "Deployed graph detected, getting info from:" ,
82+ deploymentUrl
83+ ) ;
84+
85+ // Get the LangChain API key from local storage or props
86+ const storedApiKey =
87+ getItem ( LANGCHAIN_API_KEY_LOCAL_STORAGE_KEY ) || undefined ;
88+ const apiKey = langchainApiKey || storedApiKey ;
89+
90+ // Note: The API key is still required for deployed graphs for other operations,
91+ // but not for fetching deployment info
92+ if ( ! apiKey && isDeployed ) {
93+ setErrorMessage (
94+ "API key is required for deployed LangGraph instances"
95+ ) ;
96+ setIsSubmitting ( false ) ;
97+ return ;
98+ }
99+
100+ // Fetch deployment info
101+ try {
102+ const deploymentInfo = await fetchDeploymentInfo ( deploymentUrl ) ;
103+ logger . log ( "Got deployment info:" , deploymentInfo ) ;
104+
105+ if (
106+ deploymentInfo ?. host ?. project_id &&
107+ deploymentInfo ?. host ?. tenant_id
108+ ) {
109+ // Generate ID in format: project_id:graphId
110+ inboxId = `${ deploymentInfo . host . project_id } :${ graphId } ` ;
111+ tenantId = deploymentInfo . host . tenant_id ;
112+ logger . log ( `Created new inbox ID: ${ inboxId } ` ) ;
113+ } else {
114+ logger . log ( "No project_id in deployment info, using UUID" ) ;
115+ }
116+ } catch ( error ) {
117+ logger . error ( "Error fetching deployment info:" , error ) ;
118+ setErrorMessage (
119+ "Failed to get deployment info. Check your deployment URL."
120+ ) ;
121+ setIsSubmitting ( false ) ;
122+ return ;
123+ }
124+ } else {
125+ logger . log ( "Local graph, using UUID for inbox ID" ) ;
126+ }
127+
128+ // Add the inbox with the generated ID
129+ logger . log ( "Adding inbox with ID:" , inboxId ) ;
130+ addAgentInbox ( {
131+ id : inboxId ,
132+ graphId,
133+ deploymentUrl,
134+ name,
135+ selected : true ,
136+ tenantId,
137+ } ) ;
138+
139+ toast ( {
140+ title : "Success" ,
141+ description : "Agent inbox added successfully" ,
142+ duration : 3000 ,
143+ } ) ;
144+ updateQueryParams ( NO_INBOXES_FOUND_PARAM ) ;
145+
146+ setGraphId ( "" ) ;
147+ setDeploymentUrl ( "" ) ;
148+ setName ( "" ) ;
149+ setOpen ( false ) ;
150+
151+ // Force page reload to ensure the new inbox appears
152+ window . location . reload ( ) ;
153+ } catch ( error ) {
154+ logger . error ( "Error adding agent inbox:" , error ) ;
155+ setErrorMessage (
156+ "Failed to add the agent inbox. Please try again or check the console for details."
157+ ) ;
158+ } finally {
159+ setIsSubmitting ( false ) ;
160+ }
81161 } ;
82162
83163 const isDeployedGraph = isDeployedUrl ( deploymentUrl ) ;
84164 const showLangChainApiKeyField =
85- noInboxesFoundParam === "true" &&
165+ ( noInboxesFoundParam === "true" || isDeployedGraph ) &&
86166 langchainApiKey !== undefined &&
87167 handleChangeLangChainApiKey &&
88168 isDeployedGraph ;
@@ -203,9 +283,26 @@ export function AddAgentInboxDialog({
203283 />
204284 </ div >
205285 ) }
286+
287+ { errorMessage && (
288+ < div className = "text-red-500 text-sm w-full" > { errorMessage } </ div >
289+ ) }
290+
206291 < div className = "grid grid-cols-2 gap-4" >
207- < Button variant = "brand" type = "submit" >
208- Submit
292+ < Button
293+ variant = "outline"
294+ className = "w-full"
295+ type = "submit"
296+ disabled = { isSubmitting }
297+ >
298+ { isSubmitting ? (
299+ < >
300+ < LoaderCircle className = "mr-2 h-4 w-4 animate-spin" />
301+ Adding...
302+ </ >
303+ ) : (
304+ "Add Inbox"
305+ ) }
209306 </ Button >
210307 < Button
211308 variant = "outline"
0 commit comments