feat: preconfigure session sharing with GOOSE_BASE_URL_SHARE (#1885)
Co-authored-by: Lily Delalande <ldelalande@squareup.com>
This commit is contained in:
@@ -1,30 +1,37 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { Input } from '../../ui/input';
|
import { Input } from '../../ui/input';
|
||||||
import { Check } from 'lucide-react';
|
import { Check, Lock } from 'lucide-react';
|
||||||
|
|
||||||
export default function SessionSharingSection() {
|
export default function SessionSharingSection() {
|
||||||
|
const envBaseUrlShare = window.appConfig.get('GOOSE_BASE_URL_SHARE');
|
||||||
|
console.log('envBaseUrlShare', envBaseUrlShare);
|
||||||
|
|
||||||
|
// If env is set, force sharing enabled and set the baseUrl accordingly.
|
||||||
const [sessionSharingConfig, setSessionSharingConfig] = useState({
|
const [sessionSharingConfig, setSessionSharingConfig] = useState({
|
||||||
enabled: false,
|
enabled: envBaseUrlShare ? true : false,
|
||||||
baseUrl: '',
|
baseUrl: envBaseUrlShare || '',
|
||||||
});
|
});
|
||||||
const [urlError, setUrlError] = useState('');
|
const [urlError, setUrlError] = useState('');
|
||||||
// Show a checkmark temporarily when the user’s input is valid
|
// isUrlConfigured is true if the user has configured a baseUrl and it is valid.
|
||||||
const [urlSaved, setUrlSaved] = useState(false);
|
const isUrlConfigured =
|
||||||
|
!envBaseUrlShare && sessionSharingConfig.enabled && isValidUrl(sessionSharingConfig.baseUrl);
|
||||||
|
|
||||||
// Load session sharing config from localStorage
|
// Only load saved config from localStorage if the env variable is not provided.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const savedSessionConfig = localStorage.getItem('session_sharing_config');
|
if (!envBaseUrlShare) {
|
||||||
if (savedSessionConfig) {
|
const savedSessionConfig = localStorage.getItem('session_sharing_config');
|
||||||
try {
|
if (savedSessionConfig) {
|
||||||
const config = JSON.parse(savedSessionConfig);
|
try {
|
||||||
setSessionSharingConfig(config);
|
const config = JSON.parse(savedSessionConfig);
|
||||||
} catch (error) {
|
setSessionSharingConfig(config);
|
||||||
console.error('Error parsing session sharing config:', error);
|
} catch (error) {
|
||||||
|
console.error('Error parsing session sharing config:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, []);
|
}, [envBaseUrlShare]);
|
||||||
|
|
||||||
// Helper to check if the user’s input is a valid URL
|
// Helper to check if the user's input is a valid URL
|
||||||
function isValidUrl(value: string): boolean {
|
function isValidUrl(value: string): boolean {
|
||||||
if (!value) return false;
|
if (!value) return false;
|
||||||
try {
|
try {
|
||||||
@@ -35,8 +42,11 @@ export default function SessionSharingSection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle toggling "Enable Session Sharing"
|
// Toggle sharing (only allowed when env is not set).
|
||||||
const handleEnableToggle = () => {
|
const toggleSharing = () => {
|
||||||
|
if (envBaseUrlShare) {
|
||||||
|
return; // Do nothing if the environment variable forces sharing.
|
||||||
|
}
|
||||||
setSessionSharingConfig((prev) => {
|
setSessionSharingConfig((prev) => {
|
||||||
const updated = { ...prev, enabled: !prev.enabled };
|
const updated = { ...prev, enabled: !prev.enabled };
|
||||||
localStorage.setItem('session_sharing_config', JSON.stringify(updated));
|
localStorage.setItem('session_sharing_config', JSON.stringify(updated));
|
||||||
@@ -56,12 +66,6 @@ export default function SessionSharingSection() {
|
|||||||
setUrlError('');
|
setUrlError('');
|
||||||
const updated = { ...sessionSharingConfig, baseUrl: newBaseUrl };
|
const updated = { ...sessionSharingConfig, baseUrl: newBaseUrl };
|
||||||
localStorage.setItem('session_sharing_config', JSON.stringify(updated));
|
localStorage.setItem('session_sharing_config', JSON.stringify(updated));
|
||||||
|
|
||||||
// Show the checkmark temporarily
|
|
||||||
setUrlSaved(true);
|
|
||||||
setTimeout(() => {
|
|
||||||
setUrlSaved(false);
|
|
||||||
}, 2000);
|
|
||||||
} else {
|
} else {
|
||||||
setUrlError('Invalid URL format. Please enter a valid URL (e.g. https://example.com/api).');
|
setUrlError('Invalid URL format. Please enter a valid URL (e.g. https://example.com/api).');
|
||||||
}
|
}
|
||||||
@@ -74,30 +78,46 @@ export default function SessionSharingSection() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="px-8">
|
<div className="px-8">
|
||||||
<p className="text-sm text-textStandard mb-4">
|
{envBaseUrlShare ? (
|
||||||
You can enable session sharing to share your sessions with others. You'll then need to
|
<p className="text-sm text-textStandard mb-4">
|
||||||
enter the base URL for the session sharing API endpoint. Anyone with access to the same
|
Session sharing is configured but fully opt-in — your sessions are only shared when you
|
||||||
API and sharing session enabled will be able to see your sessions.
|
explicitly click the share button.
|
||||||
</p>
|
</p>
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-textStandard mb-4">
|
||||||
|
You can enable session sharing to share your sessions with others. You'll then need to
|
||||||
|
enter the base URL for the session sharing API endpoint. Anyone with access to the same
|
||||||
|
API and sharing session enabled will be able to see your sessions.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{/* Enable Session Sharing toggle */}
|
{/* Toggle for enabling session sharing */}
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<label className="text-sm font-medium text-textStandard cursor-pointer">
|
<label className="text-sm font-medium text-textStandard cursor-pointer">
|
||||||
Enable Session Sharing
|
{envBaseUrlShare
|
||||||
|
? 'Session sharing has already been configured'
|
||||||
|
: 'Enable session sharing'}
|
||||||
</label>
|
</label>
|
||||||
<button
|
{envBaseUrlShare ? (
|
||||||
onClick={handleEnableToggle}
|
<Lock className="w-5 h-5 text-gray-600" />
|
||||||
className={`relative inline-flex h-6 w-11 items-center rounded-full ${
|
) : (
|
||||||
sessionSharingConfig.enabled ? 'bg-indigo-500' : 'bg-bgProminent'
|
<button
|
||||||
} transition-colors duration-200 ease-in-out focus:outline-none`}
|
onClick={toggleSharing}
|
||||||
>
|
disabled={!!envBaseUrlShare}
|
||||||
<span
|
className={`relative inline-flex h-6 w-11 items-center rounded-full ${
|
||||||
className={`inline-block h-5 w-5 transform rounded-full bg-white shadow ${
|
sessionSharingConfig.enabled ? 'bg-indigo-500' : 'bg-bgProminent'
|
||||||
sessionSharingConfig.enabled ? 'translate-x-[22px]' : 'translate-x-[2px]'
|
} transition-colors duration-200 ease-in-out focus:outline-none ${
|
||||||
} transition-transform duration-200 ease-in-out`}
|
envBaseUrlShare ? 'cursor-not-allowed' : ''
|
||||||
/>
|
}`}
|
||||||
</button>
|
>
|
||||||
|
<span
|
||||||
|
className={`inline-block h-5 w-5 transform rounded-full bg-white shadow ${
|
||||||
|
sessionSharingConfig.enabled ? 'translate-x-[22px]' : 'translate-x-[2px]'
|
||||||
|
} transition-transform duration-200 ease-in-out`}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Base URL field (only visible if enabled) */}
|
{/* Base URL field (only visible if enabled) */}
|
||||||
@@ -110,7 +130,7 @@ export default function SessionSharingSection() {
|
|||||||
>
|
>
|
||||||
Base URL
|
Base URL
|
||||||
</label>
|
</label>
|
||||||
{urlSaved && <Check className="w-5 h-5 text-green-500" />}
|
{isUrlConfigured && <Check className="w-5 h-5 text-green-500" />}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Input
|
<Input
|
||||||
@@ -118,7 +138,8 @@ export default function SessionSharingSection() {
|
|||||||
type="url"
|
type="url"
|
||||||
placeholder="https://example.com/api"
|
placeholder="https://example.com/api"
|
||||||
value={sessionSharingConfig.baseUrl}
|
value={sessionSharingConfig.baseUrl}
|
||||||
onChange={handleBaseUrlChange}
|
disabled={!!envBaseUrlShare}
|
||||||
|
onChange={envBaseUrlShare ? undefined : handleBaseUrlChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{urlError && <p className="text-red-500 text-sm">{urlError}</p>}
|
{urlError && <p className="text-red-500 text-sm">{urlError}</p>}
|
||||||
|
|||||||
@@ -122,8 +122,18 @@ const generateSecretKey = () => {
|
|||||||
return key;
|
return key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getSharingUrl = () => {
|
||||||
|
// checks app env for sharing url
|
||||||
|
loadShellEnv(app.isPackaged); // will try to take it from the zshrc file
|
||||||
|
// if GOOSE_BASE_URL_SHARE is found, we will set process.env.GOOSE_BASE_URL_SHARE, otherwise we return what it is set
|
||||||
|
// to in the env at bundle time
|
||||||
|
return process.env.GOOSE_BASE_URL_SHARE;
|
||||||
|
};
|
||||||
|
|
||||||
let [provider, model] = getGooseProvider();
|
let [provider, model] = getGooseProvider();
|
||||||
|
|
||||||
|
let sharingUrl = getSharingUrl();
|
||||||
|
|
||||||
let appConfig = {
|
let appConfig = {
|
||||||
GOOSE_PROVIDER: provider,
|
GOOSE_PROVIDER: provider,
|
||||||
GOOSE_MODEL: model,
|
GOOSE_MODEL: model,
|
||||||
@@ -170,6 +180,7 @@ const createChat = async (
|
|||||||
GOOSE_PORT: port,
|
GOOSE_PORT: port,
|
||||||
GOOSE_WORKING_DIR: working_dir,
|
GOOSE_WORKING_DIR: working_dir,
|
||||||
REQUEST_DIR: dir,
|
REQUEST_DIR: dir,
|
||||||
|
GOOSE_BASE_URL_SHARE: sharingUrl,
|
||||||
botConfig: botConfig,
|
botConfig: botConfig,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user