Documentation
¶
Overview ¶
Package schedule provides schedule-related AI agent utilities.
Package schedule provides schedule-related AI agent utilities.
Package schedule provides schedule-related AI agent utilities.
Package schedule provides schedule-related AI agent utilities.
Package schedule provides schedule-related AI agent utilities.
Package schedule provides timezone-aware validation for schedule creation. This module handles Daylight Saving Time (DST) edge cases including:
- Invalid local times (spring forward gap)
- Ambiguous local times (fall back duplicate)
Index ¶
- Constants
- Variables
- func FormatConfirmationMessage(schedule *ScheduleRequest, confidence float64) string
- func MarshalReminders(reminders []*v1pb.Reminder) (string, error)
- func UnmarshalReminders(data string) ([]*v1pb.Reminder, error)
- type Action
- type AgentResponse
- type AlternativeSlot
- type BatchCreateRequest
- type BatchCreateResult
- type BatchScheduleParser
- type BatchScheduleService
- type ClassifyResult
- type DSTTransition
- type DSTTransitionType
- type FastCreateHandler
- type FastCreateParser
- type FastCreateResult
- type ParseResult
- type Parser
- type PrecheckError
- type PrecheckRequest
- type PrecheckResponse
- type PrecheckService
- type PrecheckSuggestion
- type PrecheckWarning
- type RecurrenceIterator
- type RecurrenceRule
- type RecurrenceType
- type ResponseType
- type ScheduleIntent
- type ScheduleIntentClassifier
- type ScheduleRequest
- type ScheduleStore
- type TimeHardener
- func (h *TimeHardener) HardenTime(ctx context.Context, input string) (time.Time, error)
- func (h *TimeHardener) HardenTimeWithDefaults(ctx context.Context, input string, defaultHour int) (time.Time, error)
- func (h *TimeHardener) ValidateTimeRange(start, end time.Time) error
- func (h *TimeHardener) WithTimezone(tz *time.Location) *TimeHardener
- type TimeRangeValidationResult
- type TimezoneValidator
- func (v *TimezoneValidator) GetDSTTransitionInfo(startTs, endTs int64) []*DSTTransition
- func (v *TimezoneValidator) GetLocation() *time.Location
- func (v *TimezoneValidator) GetTimezone() string
- func (v *TimezoneValidator) ValidateLocalTime(year int, month time.Month, day, hour, min int) *ValidationResult
- func (v *TimezoneValidator) ValidateTimeRange(startTs, endTs int64) *TimeRangeValidationResult
- func (v *TimezoneValidator) ValidateTimestamp(ts int64) *ValidationResult
- type ValidationResult
Constants ¶
const ( ErrCodeMissingStartTime = "MISSING_START_TIME" ErrCodePastTime = "PAST_TIME" ErrCodeTimeTooFar = "TIME_TOO_FAR" ErrCodeEndBeforeStart = "END_BEFORE_START" ErrCodeTimeConflict = "TIME_CONFLICT" )
PrecheckError codes for schedule validation errors.
const ( WarnCodeBufferConflict = "BUFFER_CONFLICT" WarnCodeLongDuration = "LONG_DURATION" WarnCodeOutsideWorkHours = "OUTSIDE_WORK_HOURS" WarnCodeLongTitle = "LONG_TITLE" WarnCodeWeekendSchedule = "WEEKEND_SCHEDULE" WarnCodeConflictCheckFailed = "CONFLICT_CHECK_FAILED" )
PrecheckWarning codes for schedule validation warnings.
const ( BufferMinutes = 15 // Minimum gap between schedules (minutes) MaxDurationMinutes = 480 // Maximum schedule duration (8 hours) WorkStartHour = 8 // Work hours start WorkEndHour = 22 // Work hours end MaxTitleLength = 100 // Maximum title length MaxFutureYears = 1 // Maximum years in advance for scheduling )
Business rule constants.
const ( // Validation constants. MaxInputLength = 500 // characters )
Variables ¶
var ErrTimeServiceNotConfigured = errors.New("time service not configured")
ErrTimeServiceNotConfigured is returned when time service is not available.
Functions ¶
func FormatConfirmationMessage ¶
func FormatConfirmationMessage(schedule *ScheduleRequest, confidence float64) string
FormatConfirmationMessage formats the confirmation message for display.
func MarshalReminders ¶
MarshalReminders converts protobuf reminders to JSON string.
Types ¶
type Action ¶
type Action struct {
Data any `json:"data,omitempty"`
Type string `json:"type"`
Label string `json:"label"`
}
Action represents a user action button.
type AgentResponse ¶
type AgentResponse struct {
Type ResponseType `json:"type"`
Message string `json:"message"`
Data map[string]any `json:"data,omitempty"`
Actions []Action `json:"actions,omitempty"`
}
AgentResponse represents the response from the fast create handler.
type AlternativeSlot ¶
type AlternativeSlot struct {
StartTime time.Time `json:"start_time"`
EndTime time.Time `json:"end_time"`
Label string `json:"label"` // "同日稍后", "明天同一时间"
}
AlternativeSlot represents an available time slot.
type BatchCreateRequest ¶
type BatchCreateRequest struct {
StartTime time.Time `json:"start_time"`
Recurrence *RecurrenceRule `json:"recurrence"`
EndDate *time.Time `json:"end_date,omitempty"`
Title string `json:"title"`
Location string `json:"location,omitempty"`
Duration int `json:"duration"`
Count int `json:"count,omitempty"`
}
BatchCreateRequest represents a batch schedule creation request.
type BatchCreateResult ¶
type BatchCreateResult struct {
Request *BatchCreateRequest `json:"request,omitempty"`
Preview []*ScheduleRequest `json:"preview,omitempty"`
MissingFields []string `json:"missing_fields,omitempty"`
TotalCount int `json:"total_count"`
Confidence float64 `json:"confidence"`
CanBatchCreate bool `json:"can_batch_create"`
}
BatchCreateResult represents the result of batch schedule parsing.
type BatchScheduleParser ¶
type BatchScheduleParser struct {
// contains filtered or unexported fields
}
BatchScheduleParser parses user input for batch schedule creation.
func NewBatchScheduleParser ¶
func NewBatchScheduleParser(timeSvc *aitime.Service) *BatchScheduleParser
NewBatchScheduleParser creates a new BatchScheduleParser.
func (*BatchScheduleParser) Parse ¶
func (p *BatchScheduleParser) Parse(ctx context.Context, input string) (*BatchCreateResult, error)
Parse parses user input for batch schedule creation.
type BatchScheduleService ¶
type BatchScheduleService struct {
// contains filtered or unexported fields
}
BatchScheduleService provides batch schedule operations.
func NewBatchScheduleService ¶
func NewBatchScheduleService(timeSvc *aitime.Service) *BatchScheduleService
NewBatchScheduleService creates a new BatchScheduleService.
func (*BatchScheduleService) GenerateSchedules ¶
func (s *BatchScheduleService) GenerateSchedules(req *BatchCreateRequest) ([]*ScheduleRequest, error)
GenerateSchedules generates the actual schedule objects from a validated request.
func (*BatchScheduleService) ParseAndPreview ¶
func (s *BatchScheduleService) ParseAndPreview(ctx context.Context, input string) (*BatchCreateResult, error)
ParseAndPreview parses input and returns a preview of schedules.
func (*BatchScheduleService) ValidateRequest ¶
func (s *BatchScheduleService) ValidateRequest(req *BatchCreateRequest) error
ValidateRequest validates a batch create request.
type ClassifyResult ¶
type ClassifyResult struct {
Intent ScheduleIntent
Confidence float32
UsedLLM bool // Whether LLM was used for classification
}
ClassifyResult holds the classification result.
type DSTTransition ¶
type DSTTransition struct {
Time time.Time
ZoneName string
ZoneNameNew string
Type DSTTransitionType
FromOffset int
ToOffset int
}
DSTTransition represents a DST transition event.
func (*DSTTransition) String ¶
func (t *DSTTransition) String() string
String returns a human-readable description of the transition.
type DSTTransitionType ¶
type DSTTransitionType int
DSTTransitionType represents the type of DST transition.
const ( DSTTransitionTypeUnknown DSTTransitionType = iota DSTTransitionSpringForward // Clocks move forward (gap in time) DSTTransitionFallBack // Clocks move back (repeated hour) )
type FastCreateHandler ¶
type FastCreateHandler struct {
// contains filtered or unexported fields
}
FastCreateHandler handles fast schedule creation.
func NewFastCreateHandler ¶
func NewFastCreateHandler(parser *FastCreateParser) *FastCreateHandler
NewFastCreateHandler creates a new FastCreateHandler.
func (*FastCreateHandler) Handle ¶
func (h *FastCreateHandler) Handle(ctx context.Context, userID int32, input string) (*AgentResponse, error)
Handle processes user input for fast schedule creation.
func (*FastCreateHandler) TryFastCreate ¶
func (h *FastCreateHandler) TryFastCreate(ctx context.Context, userID int32, input string) (*FastCreateResult, bool)
TryFastCreate attempts fast creation and returns whether it succeeded. This can be used by the scheduler agent to decide whether to use fast path.
type FastCreateParser ¶
type FastCreateParser struct {
// contains filtered or unexported fields
}
FastCreateParser parses user input for fast schedule creation.
func NewFastCreateParser ¶
func NewFastCreateParser(timeSvc *aitime.Service, habitApplier *habit.HabitApplier) *FastCreateParser
NewFastCreateParser creates a new FastCreateParser.
func (*FastCreateParser) Parse ¶
func (p *FastCreateParser) Parse(ctx context.Context, userID int32, input string) (*FastCreateResult, error)
Parse parses user input and returns a FastCreateResult.
type FastCreateResult ¶
type FastCreateResult struct {
Schedule *ScheduleRequest
MissingFields []string
Confidence float64
CanFastCreate bool
}
FastCreateResult represents the result of fast create parsing.
type ParseResult ¶
type ParseResult struct {
Recurrence *RecurrenceRule
Title string
Description string
Location string
Timezone string
Reminders []*v1pb.Reminder
StartTs int64
EndTs int64
AllDay bool
}
ParseResult represents the parsed schedule information.
func (*ParseResult) ToSchedule ¶
func (r *ParseResult) ToSchedule() *v1pb.Schedule
ToSchedule converts ParseResult to v1pb.Schedule.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser handles natural language parsing for schedules.
type PrecheckError ¶
type PrecheckError struct {
Code string `json:"code"` // Error code like "TIME_CONFLICT"
Message string `json:"message"` // Human-readable message
Field string `json:"field,omitempty"` // Field that caused the error
}
PrecheckError represents a validation error.
type PrecheckRequest ¶
type PrecheckRequest struct {
StartTime time.Time `json:"start_time"`
EndTime time.Time `json:"end_time"`
Title string `json:"title"`
Location string `json:"location,omitempty"`
Duration int `json:"duration"`
}
PrecheckRequest represents a schedule precheck request.
type PrecheckResponse ¶
type PrecheckResponse struct {
Errors []PrecheckError `json:"errors,omitempty"`
Warnings []PrecheckWarning `json:"warnings,omitempty"`
Suggestions []PrecheckSuggestion `json:"suggestions,omitempty"`
Valid bool `json:"valid"`
}
PrecheckResponse represents a schedule precheck result.
type PrecheckService ¶
type PrecheckService struct {
// contains filtered or unexported fields
}
PrecheckService provides schedule precheck functionality.
func NewPrecheckService ¶
func NewPrecheckService(scheduleStore ScheduleStore) *PrecheckService
NewPrecheckService creates a new PrecheckService.
func (*PrecheckService) Precheck ¶
func (s *PrecheckService) Precheck(ctx context.Context, userID int32, req *PrecheckRequest) *PrecheckResponse
Precheck validates a schedule creation request before actual creation.
type PrecheckSuggestion ¶
PrecheckSuggestion represents a suggestion for schedule correction.
type PrecheckWarning ¶
type PrecheckWarning struct {
Code string `json:"code"` // Warning code like "OUTSIDE_WORK_HOURS"
Message string `json:"message"` // Human-readable message
}
PrecheckWarning represents a validation warning.
type RecurrenceIterator ¶
type RecurrenceIterator struct {
// contains filtered or unexported fields
}
RecurrenceIterator provides lazy-loading iteration over recurrence instances. This is more memory-efficient than generating all instances upfront.
func (*RecurrenceIterator) CountInRange ¶
func (it *RecurrenceIterator) CountInRange(startTs, endTs int64) int
CountInRange returns the number of instances in the given range without materializing all of them.
func (*RecurrenceIterator) GetUntil ¶
func (it *RecurrenceIterator) GetUntil(endTs int64) []int64
GetUntil returns all instances up to the given end timestamp. Results are cached for efficient repeated calls with increasing ranges.
func (*RecurrenceIterator) Next ¶
func (it *RecurrenceIterator) Next() int64
Next returns the next instance in the sequence, or 0 if exhausted.
func (*RecurrenceIterator) Reset ¶
func (it *RecurrenceIterator) Reset()
Reset resets the iterator to the beginning.
type RecurrenceRule ¶
type RecurrenceRule struct {
Type RecurrenceType `json:"type"`
Weekdays []int `json:"weekdays"`
Interval int `json:"interval"`
MonthDay int `json:"month_day"`
}
RecurrenceRule represents a simplified recurrence rule. We use a custom JSON format instead of full RFC 5545 RRULE for simplicity.
func ParseRecurrence ¶
func ParseRecurrence(jsonStr string) (*RecurrenceRule, error)
ParseRecurrence is an alias for ParseRecurrenceRuleFromJSON.
func ParseRecurrenceRule ¶
func ParseRecurrenceRule(text string) (*RecurrenceRule, error)
ParseRecurrenceRule parses a natural language recurrence pattern. Examples:
- "每天" → {Type: RecurrenceTypeDaily, Interval: 1}
- "每3天" → {Type: RecurrenceTypeDaily, Interval: 3}
- "每周一" → {Type: RecurrenceTypeWeekly, Weekdays: [1]}
- "每周" → {Type: RecurrenceTypeWeekly, Interval: 1}
- "每两周" → {Type: RecurrenceTypeDaily, Interval: 14}
- "每月15号" → {Type: RecurrenceTypeMonthly, MonthDay: 15}
func ParseRecurrenceRuleFromJSON ¶
func ParseRecurrenceRuleFromJSON(jsonStr string) (*RecurrenceRule, error)
ParseRecurrenceRuleFromJSON parses a recurrence rule from JSON string.
func (*RecurrenceRule) GenerateInstances ¶
func (r *RecurrenceRule) GenerateInstances(startTs int64, endTs int64) []int64
GenerateInstances generates all occurrence timestamps within a time range. startTs: The start timestamp of the first occurrence (Unix timestamp, always UTC) endTs: The end timestamp for generating instances (0 means no limit) Returns a slice of timestamps for each occurrence (Unix timestamps).
Note on timezone handling: - Unix timestamps are always UTC - The startTs is assumed to be pre-converted to UTC by the caller based on user's timezone - For example, if user in Asia/Shanghai (UTC+8) schedules 9:00 AM, startTs is 01:00 UTC - Instances are generated using UTC arithmetic (adding 24h for daily, 7 days for weekly, etc.) - This ensures consistent behavior across timezones and simplifies the implementation
For proper timezone-aware scheduling (e.g., "9:00 AM local time" regardless of DST changes), the caller should handle timezone conversion before/after calling this method.
func (*RecurrenceRule) Iterator ¶
func (r *RecurrenceRule) Iterator(startTs int64) *RecurrenceIterator
Iterator creates a new iterator for this recurrence rule.
func (*RecurrenceRule) ToJSON ¶
func (r *RecurrenceRule) ToJSON() (string, error)
ToJSON converts the recurrence rule to JSON string.
func (*RecurrenceRule) Validate ¶
func (r *RecurrenceRule) Validate() error
Validate checks if the recurrence rule is valid.
type RecurrenceType ¶
type RecurrenceType string
RecurrenceType represents the type of recurrence pattern.
const ( // RecurrenceTypeDaily represents daily recurrence. RecurrenceTypeDaily RecurrenceType = "daily" // RecurrenceTypeWeekly represents weekly recurrence. RecurrenceTypeWeekly RecurrenceType = "weekly" // RecurrenceTypeMonthly represents monthly recurrence. RecurrenceTypeMonthly RecurrenceType = "monthly" )
func (RecurrenceType) IsValid ¶
func (rt RecurrenceType) IsValid() bool
IsValid checks if the recurrence type is valid.
func (RecurrenceType) String ¶
func (rt RecurrenceType) String() string
String returns the string representation of RecurrenceType.
type ResponseType ¶
type ResponseType string
ResponseType represents the type of agent response.
const ( ResponseTypeFastCreate ResponseType = "fast_create" ResponseTypeFallback ResponseType = "fallback" ResponseTypeError ResponseType = "error" )
type ScheduleIntent ¶
type ScheduleIntent int
ScheduleIntent represents the type of schedule task intent.
const ( // IntentUnknown is for unrecognized intents. IntentUnknown ScheduleIntent = iota // IntentSimpleCreate is for simple single schedule creation. IntentSimpleCreate // IntentSimpleQuery is for simple schedule queries. IntentSimpleQuery // IntentSimpleUpdate is for simple schedule modifications. IntentSimpleUpdate // IntentBatchCreate is for batch schedule creation (e.g., "每天", "每周"). IntentBatchCreate )
func (ScheduleIntent) String ¶
func (i ScheduleIntent) String() string
String returns the string representation of ScheduleIntent.
type ScheduleIntentClassifier ¶
type ScheduleIntentClassifier struct {
// contains filtered or unexported fields
}
ScheduleIntentClassifier classifies user input into schedule task intents. It uses rule-based matching first (0ms) and falls back to RouterService (~400ms).
func NewScheduleIntentClassifier ¶
func NewScheduleIntentClassifier(routerService router.RouterService) *ScheduleIntentClassifier
NewScheduleIntentClassifier creates a new ScheduleIntentClassifier.
func (*ScheduleIntentClassifier) Classify ¶
func (c *ScheduleIntentClassifier) Classify(ctx context.Context, input string) ClassifyResult
Classify determines the schedule intent of the user input. Returns the intent, confidence score (0-1), and whether LLM was used.
func (*ScheduleIntentClassifier) ClassifyAndRoute ¶
func (c *ScheduleIntentClassifier) ClassifyAndRoute(ctx context.Context, input string) (ScheduleIntent, bool, float32)
ClassifyAndRoute is a convenience method that classifies and returns execution mode.
func (*ScheduleIntentClassifier) ShouldUsePlanExecute ¶
func (c *ScheduleIntentClassifier) ShouldUsePlanExecute(intent ScheduleIntent) bool
ShouldUsePlanExecute returns true if the intent should use Plan-Execute mode.
type ScheduleRequest ¶
type ScheduleRequest struct {
StartTime time.Time `json:"start_time"`
EndTime time.Time `json:"end_time"`
Title string `json:"title"`
Location string `json:"location,omitempty"`
Description string `json:"description,omitempty"`
Duration int `json:"duration"`
ReminderMinutes int `json:"reminder_minutes,omitempty"`
}
ScheduleRequest represents a schedule creation request.
type ScheduleStore ¶
type ScheduleStore interface {
ListSchedules(ctx context.Context, find *store.FindSchedule) ([]*store.Schedule, error)
}
ScheduleStore defines the interface for schedule storage operations.
type TimeHardener ¶
type TimeHardener struct {
// contains filtered or unexported fields
}
TimeHardener provides time parsing hardening for LLM outputs. It preprocesses various time formats before delegating to TimeService.
func NewTimeHardener ¶
func NewTimeHardener(timeService aitime.TimeService, timezone *time.Location) *TimeHardener
NewTimeHardener creates a new TimeHardener instance.
func (*TimeHardener) HardenTime ¶
3. Validate the result for reasonableness.
func (*TimeHardener) HardenTimeWithDefaults ¶
func (h *TimeHardener) HardenTimeWithDefaults(ctx context.Context, input string, defaultHour int) (time.Time, error)
HardenTimeWithDefaults parses time with default values for missing components. defaultHour is used when time has a period but no specific hour.
func (*TimeHardener) ValidateTimeRange ¶
func (h *TimeHardener) ValidateTimeRange(start, end time.Time) error
ValidateTimeRange validates a time range.
func (*TimeHardener) WithTimezone ¶
func (h *TimeHardener) WithTimezone(tz *time.Location) *TimeHardener
WithTimezone returns a new TimeHardener with the specified timezone.
type TimeRangeValidationResult ¶
type TimeRangeValidationResult struct {
StartValidTime time.Time
EndValidTime time.Time
Warnings []string
IsValid bool
}
TimeRangeValidationResult contains the result of validating a time range.
type TimezoneValidator ¶
type TimezoneValidator struct {
// contains filtered or unexported fields
}
TimezoneValidator handles DST edge cases for a specific timezone.
func NewTimezoneValidator ¶
func NewTimezoneValidator(tz string) *TimezoneValidator
NewTimezoneValidator creates a new validator for the given timezone.
func (*TimezoneValidator) GetDSTTransitionInfo ¶
func (v *TimezoneValidator) GetDSTTransitionInfo(startTs, endTs int64) []*DSTTransition
GetDSTTransitionInfo returns information about upcoming DST transitions for the given date range.
func (*TimezoneValidator) GetLocation ¶
func (v *TimezoneValidator) GetLocation() *time.Location
GetLocation returns the validator's timezone location.
func (*TimezoneValidator) GetTimezone ¶
func (v *TimezoneValidator) GetTimezone() string
GetTimezone returns the validator's timezone name.
func (*TimezoneValidator) ValidateLocalTime ¶
func (v *TimezoneValidator) ValidateLocalTime(year int, month time.Month, day, hour, min int) *ValidationResult
ValidateLocalTime validates and normalizes a local time, handling DST edge cases.
Parameters:
- year, month, day, hour, min: The local time components to validate
Returns:
- ValidationResult: Contains the validated time and any warnings
DST Edge Cases Handled:
Spring Forward (Invalid Time): When clocks "spring forward", times in the gap don't exist. Example: In America/New_York on 2024-03-10, time jumps from 1:59:59 AM to 3:00:00 AM. Times like 2:30 AM don't exist - they're adjusted forward to 3:00 AM.
Fall Back (Ambiguous Time): When clocks "fall back", the same hour occurs twice. Example: In America/New_York on 2024-11-03, 1:30 AM occurs twice (before and after the switch). The first occurrence (Eastern Daylight Time) is used by default.
func (*TimezoneValidator) ValidateTimeRange ¶
func (v *TimezoneValidator) ValidateTimeRange(startTs, endTs int64) *TimeRangeValidationResult
ValidateTimeRange validates both start and end times for a schedule.
func (*TimezoneValidator) ValidateTimestamp ¶
func (v *TimezoneValidator) ValidateTimestamp(ts int64) *ValidationResult
ValidateTimestamp validates a Unix timestamp, converting it to the local timezone and checking for any issues.