mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-26 09:16:22 +02:00
Merge pull request #756 from AnishSarkar22/fix/google-calendar-connectors
fix: google calendar issues (composio & non-composio)
This commit is contained in:
commit
4e04b4053a
8 changed files with 54 additions and 39 deletions
|
|
@ -246,15 +246,18 @@ class GoogleCalendarConnector:
|
|||
dt_start = isoparse(start_date)
|
||||
dt_end = isoparse(end_date)
|
||||
|
||||
# Set start to beginning of day (00:00:00) and end to end of day (23:59:59)
|
||||
# This ensures same-date queries work (e.g., start=2026-01-23, end=2026-01-23)
|
||||
# and matches the Composio connector behavior
|
||||
if dt_start.tzinfo is None:
|
||||
dt_start = dt_start.replace(tzinfo=pytz.UTC)
|
||||
dt_start = dt_start.replace(hour=0, minute=0, second=0, tzinfo=pytz.UTC)
|
||||
else:
|
||||
dt_start = dt_start.astimezone(pytz.UTC)
|
||||
dt_start = dt_start.astimezone(pytz.UTC).replace(hour=0, minute=0, second=0)
|
||||
|
||||
if dt_end.tzinfo is None:
|
||||
dt_end = dt_end.replace(tzinfo=pytz.UTC)
|
||||
dt_end = dt_end.replace(hour=23, minute=59, second=59, tzinfo=pytz.UTC)
|
||||
else:
|
||||
dt_end = dt_end.astimezone(pytz.UTC)
|
||||
dt_end = dt_end.astimezone(pytz.UTC).replace(hour=23, minute=59, second=59)
|
||||
|
||||
if dt_start >= dt_end:
|
||||
return [], (
|
||||
|
|
|
|||
|
|
@ -191,10 +191,10 @@ async def index_google_calendar_events(
|
|||
)
|
||||
else:
|
||||
calculated_start_date = datetime.now() - timedelta(
|
||||
days=30
|
||||
) # Use 30 days as default for calendar events
|
||||
days=365
|
||||
) # Use 365 days as default for calendar events (matches frontend)
|
||||
logger.info(
|
||||
f"No last_indexed_at found, using {calculated_start_date.strftime('%Y-%m-%d')} (30 days ago) as start date"
|
||||
f"No last_indexed_at found, using {calculated_start_date.strftime('%Y-%m-%d')} (365 days ago) as start date"
|
||||
)
|
||||
|
||||
# Use calculated dates if not provided
|
||||
|
|
@ -209,23 +209,6 @@ async def index_google_calendar_events(
|
|||
start_date_str = start_date
|
||||
end_date_str = end_date
|
||||
|
||||
# If start_date and end_date are the same, adjust end_date to be one day later
|
||||
# to ensure valid date range (start_date must be strictly before end_date)
|
||||
if start_date_str == end_date_str:
|
||||
# Parse the date and add one day to ensure valid range
|
||||
dt = isoparse(end_date_str)
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=pytz.UTC)
|
||||
else:
|
||||
dt = dt.astimezone(pytz.UTC)
|
||||
# Add one day to end_date to make it strictly after start_date
|
||||
dt_end = dt + timedelta(days=1)
|
||||
end_date_str = dt_end.strftime("%Y-%m-%d")
|
||||
logger.info(
|
||||
f"Adjusted end_date from {end_date} to {end_date_str} "
|
||||
f"to ensure valid date range (start_date must be strictly before end_date)"
|
||||
)
|
||||
|
||||
await task_logger.log_task_progress(
|
||||
log_entry,
|
||||
f"Fetching Google Calendar events from {start_date_str} to {end_date_str}",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,13 @@ def get_model_context_window(model_name: str) -> int:
|
|||
"""Get the total context window size for a model (input + output tokens)."""
|
||||
try:
|
||||
model_info = get_model_info(model_name)
|
||||
context_window = model_info.get("max_input_tokens", 4096) # Default fallback
|
||||
context_window = model_info.get("max_input_tokens")
|
||||
# Handle case where key exists but value is None
|
||||
if context_window is None:
|
||||
print(
|
||||
f"Warning: max_input_tokens is None for {model_name}, using default 4096 tokens."
|
||||
)
|
||||
return 4096 # Conservative fallback
|
||||
return context_window
|
||||
except Exception as e:
|
||||
print(
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ interface DateRangeSelectorProps {
|
|||
onStartDateChange: (date: Date | undefined) => void;
|
||||
onEndDateChange: (date: Date | undefined) => void;
|
||||
allowFutureDates?: boolean; // Allow future dates for calendar connectors
|
||||
lastIndexedAt?: string | null; // Last sync timestamp to show in default placeholder
|
||||
}
|
||||
|
||||
export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
|
||||
|
|
@ -23,7 +24,21 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
|
|||
onStartDateChange,
|
||||
onEndDateChange,
|
||||
allowFutureDates = false,
|
||||
lastIndexedAt,
|
||||
}) => {
|
||||
// Get the placeholder text for start date based on whether connector was previously indexed
|
||||
const getStartDatePlaceholder = () => {
|
||||
if (lastIndexedAt) {
|
||||
const date = new Date(lastIndexedAt);
|
||||
const currentYear = new Date().getFullYear();
|
||||
const indexedYear = date.getFullYear();
|
||||
// Show year only if different from current year
|
||||
const formatStr = indexedYear === currentYear ? "MMM d, HH:mm" : "MMM d, yyyy HH:mm";
|
||||
const formattedDate = format(date, formatStr);
|
||||
return `Since (${formattedDate})`;
|
||||
}
|
||||
return "Default (1 year ago)";
|
||||
};
|
||||
const handleLast30Days = () => {
|
||||
const today = new Date();
|
||||
onStartDateChange(subDays(today, 30));
|
||||
|
|
@ -73,7 +88,7 @@ export const DateRangeSelector: FC<DateRangeSelectorProps> = ({
|
|||
)}
|
||||
>
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
{startDate ? format(startDate, "PPP") : "Default (1 year ago)"}
|
||||
{startDate ? format(startDate, "PPP") : getStartDatePlaceholder()}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0 z-[100]" align="start">
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
|
|||
connector.connector_type === "COMPOSIO_GOOGLE_CALENDAR_CONNECTOR" ||
|
||||
connector.connector_type === "LUMA_CONNECTOR"
|
||||
}
|
||||
lastIndexedAt={connector.last_indexed_at}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ export const IndexingConfigurationView: FC<IndexingConfigurationViewProps> = ({
|
|||
config.connectorType === "COMPOSIO_GOOGLE_CALENDAR_CONNECTOR" ||
|
||||
config.connectorType === "LUMA_CONNECTOR"
|
||||
}
|
||||
lastIndexedAt={connector?.last_indexed_at}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ const DialogContent = React.forwardRef<
|
|||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] rounded-lg focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0",
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 rounded-lg focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -49,12 +49,14 @@ class ConnectorsApiService {
|
|||
throw new ValidationError(`Invalid request: ${errorMessage}`);
|
||||
}
|
||||
|
||||
// Transform query params to be string values
|
||||
// Transform query params to be string values, filtering out undefined/null
|
||||
const transformedQueryParams = parsedRequest.data.queryParams
|
||||
? Object.fromEntries(
|
||||
Object.entries(parsedRequest.data.queryParams).map(([k, v]) => {
|
||||
return [k, String(v)];
|
||||
})
|
||||
Object.entries(parsedRequest.data.queryParams)
|
||||
.filter(([_, v]) => v !== undefined && v !== null)
|
||||
.map(([k, v]) => {
|
||||
return [k, String(v)];
|
||||
})
|
||||
)
|
||||
: undefined;
|
||||
|
||||
|
|
@ -102,11 +104,13 @@ class ConnectorsApiService {
|
|||
|
||||
const { data, queryParams } = parsedRequest.data;
|
||||
|
||||
// Transform query params to be string values
|
||||
// Transform query params to be string values, filtering out undefined/null
|
||||
const transformedQueryParams = Object.fromEntries(
|
||||
Object.entries(queryParams).map(([k, v]) => {
|
||||
return [k, String(v)];
|
||||
})
|
||||
Object.entries(queryParams)
|
||||
.filter(([_, v]) => v !== undefined && v !== null)
|
||||
.map(([k, v]) => {
|
||||
return [k, String(v)];
|
||||
})
|
||||
);
|
||||
|
||||
const queryString = new URLSearchParams(transformedQueryParams).toString();
|
||||
|
|
@ -174,11 +178,13 @@ class ConnectorsApiService {
|
|||
|
||||
const { connector_id, queryParams, body } = parsedRequest.data;
|
||||
|
||||
// Transform query params to be string values
|
||||
// Transform query params to be string values, filtering out undefined/null
|
||||
const transformedQueryParams = Object.fromEntries(
|
||||
Object.entries(queryParams).map(([k, v]) => {
|
||||
return [k, String(v)];
|
||||
})
|
||||
Object.entries(queryParams)
|
||||
.filter(([_, v]) => v !== undefined && v !== null)
|
||||
.map(([k, v]) => {
|
||||
return [k, String(v)];
|
||||
})
|
||||
);
|
||||
|
||||
const queryString = new URLSearchParams(transformedQueryParams).toString();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue