HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/agentcloud/webapp/src/components/StartSessionForm.tsx
import {
	PaperAirplaneIcon,
} from '@heroicons/react/20/solid';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import Select from 'react-tailwindcss-select';
import { toast } from 'react-toastify';

import * as API from '../api';
// import CreateAgentModal from '../components/CreateAgentModal';
// import CreateCrewModal from '../components/CreateCrewModal';
import { useAccountContext } from '../context/account';
import handleShiftNewlines from '../lib/misc/handleshiftnewlines';
import SelectClassNames, { SelectClassNamesInverted } from '../lib/styles/SelectClassNames';

export default function StartSessionForm({ agents = [], crews = [], setOpen, fetchSessions, inverted = false }) {

	const [accountContext]: any = useAccountContext();
	const { account, csrf } = accountContext as any;
	const router = useRouter();
	const { resourceSlug } = router.query;
	const { stripeCustomerId } = account?.stripe || {};
	const [error, setError] = useState();
	const [promptValue, setPromptValue] = useState('');
	const [selected, setSelected] = useState(null);
	const [addedId, setAddedId] = useState(null);
	const [modalOpen, setModalOpen]: any = useState(false);

	async function addSession(e) {
		e.preventDefault();
		if (!selected?.value && !selected?.value) {
			toast.error('Please select an agent or crew from the dropdown');
			return null;
		}
		const target = e.target.form ? e.target.form : e.target;
		await API.addSession({
			_csrf: target._csrf.value,
			resourceSlug,
			id: selected?.value,
		}, null, setError, router);
	}

	async function callback(id: string) {
		setAddedId(id);
		await fetchSessions();
	}

	//When agents or crews change set the selected crew from the callback
	useEffect(() => {
		if (!addedId) { return; }
		const foundAgent = agents.find(a => a._id === addedId);
		foundAgent && setSelected({ label: foundAgent.name, value: foundAgent._id, tools: foundAgent.toolIds?.length > 0, rag: foundAgent.datasourceIds?.length > 0 });
		const foundCrew = crews.find(g => g._id === addedId);
		foundCrew && setSelected({ label: foundCrew.name, value: foundCrew._id });
		setAddedId(null);
		setModalOpen(false);
	}, [agents, crews]);

	const crewOptions: any[] = crews
		.map(g => ({
			label: g.name,
			value: g._id,
			//TODO: rag true/false capability
		}));/*.concat([{
			label: '+ New app',
			value: null,
			crew: true,
		} as any]);*/

	const agentOptions: any[] = agents
		.map(a => ({
			label: a.name,
			value: a._id,
			rag: a.datasourceIds?.length > 0,
			tools: a.toolIds?.length > 0,
		} as any)).concat([{
			label: '+ New agent',
			value: null,
			crew: false,
		} as any]);

	return (<div className='flex flex-col'>

		{/*modalOpen === 'crew'
			? <CreateCrewModal open={modalOpen !== false} setOpen={setModalOpen} callback={callback} />
			: <CreateAgentModal open={modalOpen !== false} setOpen={setModalOpen} callback={callback} />*/}

		<div className='flex flex-row justify-start'>
			<div className='flex items-start space-x-4 w-full'>
				<div className='min-w-0 flex-1'>
					<form action='/forms/session/add' onSubmit={addSession}>
						<input type='hidden' name='_csrf' value={csrf} />
						<div className='flex flex-row space-x-3'>
							<Select
								isSearchable={crewOptions.length > 5}
								isClearable
								primaryColor={'indigo'}
								value={selected}
								classNames={inverted ? SelectClassNamesInverted : SelectClassNames}
								onChange={(e: any) => {
									if (e?.value === null) {
										return setModalOpen(e.crew ? 'crew' : 'single');
									}
									setSelected(e);
								}}
								options={[/*{
									label: 'Single Agent',
									options: agentOptions,
									}, */{
										label: 'Apps',
										options: crewOptions,
									},
								]}
								formatOptionLabel={(data: any) => (
					                <li
					                    className={`block transition duration-200 px-2 py-2 cursor-pointer select-none truncate rounded hover:bg-blue-${data.isSelected?'500 text-white':'100'} ${data.isSelected?'bg-blue-500':''}`}
					                >
					                    {data.label}
					                    {data.rag && <span className='inline-flex items-center rounded-md bg-green-100 mx-1 px-2 py-1 text-xs font-semibold text-green-700'>
											ʀᴀɢ
										</span>}
					                    {data.tools && <span className='inline-flex items-center rounded-md bg-yellow-100 mx-1 px-2 py-1 text-xs font-semibold text-yellow-700'>
											ᴛᴏᴏʟs
										</span>}
					                </li>
					            )}
								formatGroupLabel={data => (
									<div className='py-2 text-xs flex items-center justify-between'>
										<span className='font-bold'>{data.label}</span>
										<span className='bg-gray-200 h-5 h-5 p-1.5 flex items-center justify-center rounded-ful'>
											{data.options.length}
										</span>
									</div>
								)}
							/>
							
							<div className='transition-all pointer-events-none h-[36px]'>
								<div className='flex-shrink-0'>
									<button
										type='submit'
										className='h-[37px] pointer-events-auto inline-flex items-center rounded-md px-3 py-2 text-sm font-semibold text-white shadow-sm bg-indigo-600 hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600'
									>
										<PaperAirplaneIcon className='h-4 w-4' />
									</button>
								</div>
							</div>
						</div>
					</form>
				</div>
			</div>
		</div>

	</div>);
}