aboutsummaryrefslogtreecommitdiff
path: root/cmd/mimi/modules
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-06-30 10:32:55 -0400
committerXe Iaso <me@xeiaso.net>2024-06-30 10:32:55 -0400
commit050aff00512028ffc1989c7485cb2cb1258c7537 (patch)
tree3de72fe24e48dd039a1dfc91e35ec32652b35b0f /cmd/mimi/modules
parent759e3c8b09253990a8c3e09a359ed9a552121d72 (diff)
downloadx-050aff00512028ffc1989c7485cb2cb1258c7537.tar.xz
x-050aff00512028ffc1989c7485cb2cb1258c7537.zip
update generated files
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd/mimi/modules')
-rw-r--r--cmd/mimi/modules/scheduling/scheduling.go103
-rw-r--r--cmd/mimi/modules/scheduling/scheduling.pb.go383
-rw-r--r--cmd/mimi/modules/scheduling/scheduling.twirp.go1115
-rw-r--r--cmd/mimi/modules/scheduling/scheduling.valid.go45
-rw-r--r--cmd/mimi/modules/scheduling/scheduling_grpc.pb.go109
5 files changed, 0 insertions, 1755 deletions
diff --git a/cmd/mimi/modules/scheduling/scheduling.go b/cmd/mimi/modules/scheduling/scheduling.go
deleted file mode 100644
index 0e52fbf..0000000
--- a/cmd/mimi/modules/scheduling/scheduling.go
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-Package scheduling provides the scheduling module for Mimi.
-
-This module allows authorized users to CC Nise in their emails to schedule meetings and events.
-When Nise is CCed in an email, she will parse the email and extract the date, time, and
-location of the event. Nise will then create a Google Calendar event and send an invitation.
-*/
-package scheduling
-
-import (
- "bytes"
- "context"
- _ "embed"
- "encoding/json"
- "fmt"
- "log/slog"
- "text/template"
- "time"
-
- "github.com/cenkalti/backoff/v4"
- "within.website/x/cmd/mimi/internal"
- "within.website/x/web/ollama"
-)
-
-//go:generate protoc --proto_path=. --go_out=. --go_opt=paths=source_relative --twirp_out=. scheduling.proto
-
-func p[T any](t T) *T {
- return &t
-}
-
-const timeFormat string = "Monday January 2, 2006 at 3:04 PM"
-
-//go:embed nise_template.txt
-var niseTemplate string
-
-type Module struct {
- cli *ollama.Client
- model string
-
- UnimplementedSchedulingServer
-}
-
-func New() *Module {
- return &Module{
- cli: internal.OllamaClient(),
- model: internal.OllamaModel(),
- }
-}
-
-func (m *Module) ParseEmail(ctx context.Context, req *ParseReq) (*ParseResp, error) {
- bo := backoff.NewExponentialBackOff()
-
- return backoff.RetryNotifyWithData[*ParseResp](func() (*ParseResp, error) {
- return m.parseEmail(ctx, req)
- }, bo, func(err error, t time.Duration) {
- slog.Error("error parsing email", "err", err, "t", t.String())
- })
-}
-
-func (m *Module) parseEmail(ctx context.Context, req *ParseReq) (*ParseResp, error) {
- tmpl := template.Must(template.New("nise").Parse(niseTemplate))
- var buf bytes.Buffer
- if err := tmpl.Execute(&buf, req); err != nil {
- return nil, backoff.Permanent(fmt.Errorf("scheduling: error executing template: %w", err))
- }
-
- resp, err := m.cli.Chat(ctx, &ollama.CompleteRequest{
- Model: m.model,
- Messages: []ollama.Message{
- {
- Role: "system",
- Content: `You are Nise, a scheduling assistant. You have been CCed in an email to schedule a meeting. Your task is to read this email and extract the following information into a JSON object:
-
- * The start time of the meeting
- * The duration of the meeting
- * A summary of the meeting
- * The attendees in the meeting with their name and email address
- * If a location is given, add it as an optional field named "location"
-
- The JSON object should be formatted like this:
-
- {"start_time": "Monday April 25, 2024 at 12:45 PM", duration: "30m", "summary": "A brief summary of the email", "attendees": [{"name": "From address name", "email": "from_user@domain.tld"}, {"name": "Any CC names", "email": "cc_user@domain.tld"]}`,
- },
- {
- Role: "user",
- Content: buf.String(),
- },
- },
- Format: p("json"),
- Stream: false,
- })
- if err != nil {
- return nil, fmt.Errorf("scheduling: error summarizing email: %w", err)
- }
-
- var niseResp ParseResp
-
- if err := json.Unmarshal([]byte(resp.Message.Content), &niseResp); err != nil {
- return nil, fmt.Errorf("scheduling: error unmarshaling response: %w", err)
- }
-
- return &niseResp, nil
-}
diff --git a/cmd/mimi/modules/scheduling/scheduling.pb.go b/cmd/mimi/modules/scheduling/scheduling.pb.go
deleted file mode 100644
index 582eb7d..0000000
--- a/cmd/mimi/modules/scheduling/scheduling.pb.go
+++ /dev/null
@@ -1,383 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// protoc-gen-go v1.32.0
-// protoc v4.24.4
-// source: scheduling.proto
-
-package scheduling
-
-import (
- protoreflect "google.golang.org/protobuf/reflect/protoreflect"
- protoimpl "google.golang.org/protobuf/runtime/protoimpl"
- _ "google.golang.org/protobuf/types/known/durationpb"
- _ "google.golang.org/protobuf/types/known/timestamppb"
- reflect "reflect"
- sync "sync"
-)
-
-const (
- // Verify that this generated code is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
- // Verify that runtime/protoimpl is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type ConversationMember struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"`
- Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
- Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"`
-}
-
-func (x *ConversationMember) Reset() {
- *x = ConversationMember{}
- if protoimpl.UnsafeEnabled {
- mi := &file_scheduling_proto_msgTypes[0]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *ConversationMember) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ConversationMember) ProtoMessage() {}
-
-func (x *ConversationMember) ProtoReflect() protoreflect.Message {
- mi := &file_scheduling_proto_msgTypes[0]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use ConversationMember.ProtoReflect.Descriptor instead.
-func (*ConversationMember) Descriptor() ([]byte, []int) {
- return file_scheduling_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *ConversationMember) GetRole() string {
- if x != nil {
- return x.Role
- }
- return ""
-}
-
-func (x *ConversationMember) GetName() string {
- if x != nil {
- return x.Name
- }
- return ""
-}
-
-func (x *ConversationMember) GetEmail() string {
- if x != nil {
- return x.Email
- }
- return ""
-}
-
-type ParseReq struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- Month string `protobuf:"bytes,1,opt,name=month,proto3" json:"month,omitempty"`
- ConversationMembers []*ConversationMember `protobuf:"bytes,2,rep,name=conversation_members,json=conversationMembers,proto3" json:"conversation_members,omitempty"`
- Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
- Date string `protobuf:"bytes,4,opt,name=date,proto3" json:"date,omitempty"`
-}
-
-func (x *ParseReq) Reset() {
- *x = ParseReq{}
- if protoimpl.UnsafeEnabled {
- mi := &file_scheduling_proto_msgTypes[1]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *ParseReq) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ParseReq) ProtoMessage() {}
-
-func (x *ParseReq) ProtoReflect() protoreflect.Message {
- mi := &file_scheduling_proto_msgTypes[1]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use ParseReq.ProtoReflect.Descriptor instead.
-func (*ParseReq) Descriptor() ([]byte, []int) {
- return file_scheduling_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *ParseReq) GetMonth() string {
- if x != nil {
- return x.Month
- }
- return ""
-}
-
-func (x *ParseReq) GetConversationMembers() []*ConversationMember {
- if x != nil {
- return x.ConversationMembers
- }
- return nil
-}
-
-func (x *ParseReq) GetMessage() string {
- if x != nil {
- return x.Message
- }
- return ""
-}
-
-func (x *ParseReq) GetDate() string {
- if x != nil {
- return x.Date
- }
- return ""
-}
-
-type ParseResp struct {
- state protoimpl.MessageState
- sizeCache protoimpl.SizeCache
- unknownFields protoimpl.UnknownFields
-
- StartTime string `protobuf:"bytes,1,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`
- Duration string `protobuf:"bytes,2,opt,name=duration,proto3" json:"duration,omitempty"`
- Summary string `protobuf:"bytes,3,opt,name=summary,proto3" json:"summary,omitempty"`
- Attendees []*ConversationMember `protobuf:"bytes,4,rep,name=attendees,proto3" json:"attendees,omitempty"`
- Location string `protobuf:"bytes,5,opt,name=location,proto3" json:"location,omitempty"`
-}
-
-func (x *ParseResp) Reset() {
- *x = ParseResp{}
- if protoimpl.UnsafeEnabled {
- mi := &file_scheduling_proto_msgTypes[2]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
- }
-}
-
-func (x *ParseResp) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*ParseResp) ProtoMessage() {}
-
-func (x *ParseResp) ProtoReflect() protoreflect.Message {
- mi := &file_scheduling_proto_msgTypes[2]
- if protoimpl.UnsafeEnabled && x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use ParseResp.ProtoReflect.Descriptor instead.
-func (*ParseResp) Descriptor() ([]byte, []int) {
- return file_scheduling_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *ParseResp) GetStartTime() string {
- if x != nil {
- return x.StartTime
- }
- return ""
-}
-
-func (x *ParseResp) GetDuration() string {
- if x != nil {
- return x.Duration
- }
- return ""
-}
-
-func (x *ParseResp) GetSummary() string {
- if x != nil {
- return x.Summary
- }
- return ""
-}
-
-func (x *ParseResp) GetAttendees() []*ConversationMember {
- if x != nil {
- return x.Attendees
- }
- return nil
-}
-
-func (x *ParseResp) GetLocation() string {
- if x != nil {
- return x.Location
- }
- return ""
-}
-
-var File_scheduling_proto protoreflect.FileDescriptor
-
-var file_scheduling_proto_rawDesc = []byte{
- 0x0a, 0x10, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x12, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69,
- 0x74, 0x65, 0x2e, 0x78, 0x2e, 0x6d, 0x69, 0x6d, 0x69, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
- 0x6c, 0x69, 0x6e, 0x67, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x52, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x72,
- 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12,
- 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
- 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xb7, 0x01, 0x0a, 0x08, 0x50, 0x61,
- 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x12, 0x67, 0x0a, 0x14,
- 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x6d,
- 0x62, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x77, 0x69, 0x74,
- 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x78, 0x2e, 0x6d, 0x69,
- 0x6d, 0x69, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x6f,
- 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72,
- 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65,
- 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
- 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64,
- 0x61, 0x74, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x73, 0x65, 0x52, 0x65, 0x73,
- 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65,
- 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07,
- 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,
- 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x52, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x64,
- 0x65, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x77, 0x69, 0x74, 0x68,
- 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x78, 0x2e, 0x6d, 0x69, 0x6d,
- 0x69, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x43, 0x6f, 0x6e,
- 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52,
- 0x09, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f,
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x73, 0x0a, 0x0a, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75,
- 0x6c, 0x69, 0x6e, 0x67, 0x12, 0x65, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x45, 0x6d, 0x61,
- 0x69, 0x6c, 0x12, 0x2a, 0x2e, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73,
- 0x69, 0x74, 0x65, 0x2e, 0x78, 0x2e, 0x6d, 0x69, 0x6d, 0x69, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
- 0x75, 0x6c, 0x69, 0x6e, 0x67, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x2b,
- 0x2e, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e,
- 0x78, 0x2e, 0x6d, 0x69, 0x6d, 0x69, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x69, 0x6e,
- 0x67, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x42, 0x2e, 0x5a, 0x2c, 0x77,
- 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x78, 0x2f,
- 0x63, 0x6d, 0x64, 0x2f, 0x6d, 0x69, 0x6d, 0x69, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73,
- 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x33,
-}
-
-var (
- file_scheduling_proto_rawDescOnce sync.Once
- file_scheduling_proto_rawDescData = file_scheduling_proto_rawDesc
-)
-
-func file_scheduling_proto_rawDescGZIP() []byte {
- file_scheduling_proto_rawDescOnce.Do(func() {
- file_scheduling_proto_rawDescData = protoimpl.X.CompressGZIP(file_scheduling_proto_rawDescData)
- })
- return file_scheduling_proto_rawDescData
-}
-
-var file_scheduling_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
-var file_scheduling_proto_goTypes = []interface{}{
- (*ConversationMember)(nil), // 0: within.website.x.mimi.scheduling.ConversationMember
- (*ParseReq)(nil), // 1: within.website.x.mimi.scheduling.ParseReq
- (*ParseResp)(nil), // 2: within.website.x.mimi.scheduling.ParseResp
-}
-var file_scheduling_proto_depIdxs = []int32{
- 0, // 0: within.website.x.mimi.scheduling.ParseReq.conversation_members:type_name -> within.website.x.mimi.scheduling.ConversationMember
- 0, // 1: within.website.x.mimi.scheduling.ParseResp.attendees:type_name -> within.website.x.mimi.scheduling.ConversationMember
- 1, // 2: within.website.x.mimi.scheduling.Scheduling.ParseEmail:input_type -> within.website.x.mimi.scheduling.ParseReq
- 2, // 3: within.website.x.mimi.scheduling.Scheduling.ParseEmail:output_type -> within.website.x.mimi.scheduling.ParseResp
- 3, // [3:4] is the sub-list for method output_type
- 2, // [2:3] is the sub-list for method input_type
- 2, // [2:2] is the sub-list for extension type_name
- 2, // [2:2] is the sub-list for extension extendee
- 0, // [0:2] is the sub-list for field type_name
-}
-
-func init() { file_scheduling_proto_init() }
-func file_scheduling_proto_init() {
- if File_scheduling_proto != nil {
- return
- }
- if !protoimpl.UnsafeEnabled {
- file_scheduling_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ConversationMember); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_scheduling_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ParseReq); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- file_scheduling_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*ParseResp); i {
- case 0:
- return &v.state
- case 1:
- return &v.sizeCache
- case 2:
- return &v.unknownFields
- default:
- return nil
- }
- }
- }
- type x struct{}
- out := protoimpl.TypeBuilder{
- File: protoimpl.DescBuilder{
- GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
- RawDescriptor: file_scheduling_proto_rawDesc,
- NumEnums: 0,
- NumMessages: 3,
- NumExtensions: 0,
- NumServices: 1,
- },
- GoTypes: file_scheduling_proto_goTypes,
- DependencyIndexes: file_scheduling_proto_depIdxs,
- MessageInfos: file_scheduling_proto_msgTypes,
- }.Build()
- File_scheduling_proto = out.File
- file_scheduling_proto_rawDesc = nil
- file_scheduling_proto_goTypes = nil
- file_scheduling_proto_depIdxs = nil
-}
diff --git a/cmd/mimi/modules/scheduling/scheduling.twirp.go b/cmd/mimi/modules/scheduling/scheduling.twirp.go
deleted file mode 100644
index bbe329d..0000000
--- a/cmd/mimi/modules/scheduling/scheduling.twirp.go
+++ /dev/null
@@ -1,1115 +0,0 @@
-// Code generated by protoc-gen-twirp v8.1.3, DO NOT EDIT.
-// source: scheduling.proto
-
-package scheduling
-
-import context "context"
-import fmt "fmt"
-import http "net/http"
-import io "io"
-import json "encoding/json"
-import strconv "strconv"
-import strings "strings"
-
-import protojson "google.golang.org/protobuf/encoding/protojson"
-import proto "google.golang.org/protobuf/proto"
-import twirp "github.com/twitchtv/twirp"
-import ctxsetters "github.com/twitchtv/twirp/ctxsetters"
-
-import bytes "bytes"
-import errors "errors"
-import path "path"
-import url "net/url"
-
-// Version compatibility assertion.
-// If the constant is not defined in the package, that likely means
-// the package needs to be updated to work with this generated code.
-// See https://twitchtv.github.io/twirp/docs/version_matrix.html
-const _ = twirp.TwirpPackageMinVersion_8_1_0
-
-// ====================
-// Scheduling Interface
-// ====================
-
-type Scheduling interface {
- ParseEmail(context.Context, *ParseReq) (*ParseResp, error)
-}
-
-// ==========================
-// Scheduling Protobuf Client
-// ==========================
-
-type schedulingProtobufClient struct {
- client HTTPClient
- urls [1]string
- interceptor twirp.Interceptor
- opts twirp.ClientOptions
-}
-
-// NewSchedulingProtobufClient creates a Protobuf client that implements the Scheduling interface.
-// It communicates using Protobuf and can be configured with a custom HTTPClient.
-func NewSchedulingProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Scheduling {
- if c, ok := client.(*http.Client); ok {
- client = withoutRedirects(c)
- }
-
- clientOpts := twirp.ClientOptions{}
- for _, o := range opts {
- o(&clientOpts)
- }
-
- // Using ReadOpt allows backwards and forwards compatibility with new options in the future
- literalURLs := false
- _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
- var pathPrefix string
- if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
- pathPrefix = "/twirp" // default prefix
- }
-
- // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
- serviceURL := sanitizeBaseURL(baseURL)
- serviceURL += baseServicePath(pathPrefix, "within.website.x.mimi.scheduling", "Scheduling")
- urls := [1]string{
- serviceURL + "ParseEmail",
- }
-
- return &schedulingProtobufClient{
- client: client,
- urls: urls,
- interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
- opts: clientOpts,
- }
-}
-
-func (c *schedulingProtobufClient) ParseEmail(ctx context.Context, in *ParseReq) (*ParseResp, error) {
- ctx = ctxsetters.WithPackageName(ctx, "within.website.x.mimi.scheduling")
- ctx = ctxsetters.WithServiceName(ctx, "Scheduling")
- ctx = ctxsetters.WithMethodName(ctx, "ParseEmail")
- caller := c.callParseEmail
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *ParseReq) (*ParseResp, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*ParseReq)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*ParseReq) when calling interceptor")
- }
- return c.callParseEmail(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*ParseResp)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*ParseResp) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *schedulingProtobufClient) callParseEmail(ctx context.Context, in *ParseReq) (*ParseResp, error) {
- out := new(ParseResp)
- ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-// ======================
-// Scheduling JSON Client
-// ======================
-
-type schedulingJSONClient struct {
- client HTTPClient
- urls [1]string
- interceptor twirp.Interceptor
- opts twirp.ClientOptions
-}
-
-// NewSchedulingJSONClient creates a JSON client that implements the Scheduling interface.
-// It communicates using JSON and can be configured with a custom HTTPClient.
-func NewSchedulingJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Scheduling {
- if c, ok := client.(*http.Client); ok {
- client = withoutRedirects(c)
- }
-
- clientOpts := twirp.ClientOptions{}
- for _, o := range opts {
- o(&clientOpts)
- }
-
- // Using ReadOpt allows backwards and forwards compatibility with new options in the future
- literalURLs := false
- _ = clientOpts.ReadOpt("literalURLs", &literalURLs)
- var pathPrefix string
- if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
- pathPrefix = "/twirp" // default prefix
- }
-
- // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
- serviceURL := sanitizeBaseURL(baseURL)
- serviceURL += baseServicePath(pathPrefix, "within.website.x.mimi.scheduling", "Scheduling")
- urls := [1]string{
- serviceURL + "ParseEmail",
- }
-
- return &schedulingJSONClient{
- client: client,
- urls: urls,
- interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
- opts: clientOpts,
- }
-}
-
-func (c *schedulingJSONClient) ParseEmail(ctx context.Context, in *ParseReq) (*ParseResp, error) {
- ctx = ctxsetters.WithPackageName(ctx, "within.website.x.mimi.scheduling")
- ctx = ctxsetters.WithServiceName(ctx, "Scheduling")
- ctx = ctxsetters.WithMethodName(ctx, "ParseEmail")
- caller := c.callParseEmail
- if c.interceptor != nil {
- caller = func(ctx context.Context, req *ParseReq) (*ParseResp, error) {
- resp, err := c.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*ParseReq)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*ParseReq) when calling interceptor")
- }
- return c.callParseEmail(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*ParseResp)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*ParseResp) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
- return caller(ctx, in)
-}
-
-func (c *schedulingJSONClient) callParseEmail(ctx context.Context, in *ParseReq) (*ParseResp, error) {
- out := new(ParseResp)
- ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
- if err != nil {
- twerr, ok := err.(twirp.Error)
- if !ok {
- twerr = twirp.InternalErrorWith(err)
- }
- callClientError(ctx, c.opts.Hooks, twerr)
- return nil, err
- }
-
- callClientResponseReceived(ctx, c.opts.Hooks)
-
- return out, nil
-}
-
-// =========================
-// Scheduling Server Handler
-// =========================
-
-type schedulingServer struct {
- Scheduling
- interceptor twirp.Interceptor
- hooks *twirp.ServerHooks
- pathPrefix string // prefix for routing
- jsonSkipDefaults bool // do not include unpopulated fields (default values) in the response
- jsonCamelCase bool // JSON fields are serialized as lowerCamelCase rather than keeping the original proto names
-}
-
-// NewSchedulingServer builds a TwirpServer that can be used as an http.Handler to handle
-// HTTP requests that are routed to the right method in the provided svc implementation.
-// The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks).
-func NewSchedulingServer(svc Scheduling, opts ...interface{}) TwirpServer {
- serverOpts := newServerOpts(opts)
-
- // Using ReadOpt allows backwards and forwards compatibility with new options in the future
- jsonSkipDefaults := false
- _ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults)
- jsonCamelCase := false
- _ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase)
- var pathPrefix string
- if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok {
- pathPrefix = "/twirp" // default prefix
- }
-
- return &schedulingServer{
- Scheduling: svc,
- hooks: serverOpts.Hooks,
- interceptor: twirp.ChainInterceptors(serverOpts.Interceptors...),
- pathPrefix: pathPrefix,
- jsonSkipDefaults: jsonSkipDefaults,
- jsonCamelCase: jsonCamelCase,
- }
-}
-
-// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
-// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
-func (s *schedulingServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
- writeError(ctx, resp, err, s.hooks)
-}
-
-// handleRequestBodyError is used to handle error when the twirp server cannot read request
-func (s *schedulingServer) handleRequestBodyError(ctx context.Context, resp http.ResponseWriter, msg string, err error) {
- if context.Canceled == ctx.Err() {
- s.writeError(ctx, resp, twirp.NewError(twirp.Canceled, "failed to read request: context canceled"))
- return
- }
- if context.DeadlineExceeded == ctx.Err() {
- s.writeError(ctx, resp, twirp.NewError(twirp.DeadlineExceeded, "failed to read request: deadline exceeded"))
- return
- }
- s.writeError(ctx, resp, twirp.WrapError(malformedRequestError(msg), err))
-}
-
-// SchedulingPathPrefix is a convenience constant that may identify URL paths.
-// Should be used with caution, it only matches routes generated by Twirp Go clients,
-// with the default "/twirp" prefix and default CamelCase service and method names.
-// More info: https://twitchtv.github.io/twirp/docs/routing.html
-const SchedulingPathPrefix = "/twirp/within.website.x.mimi.scheduling.Scheduling/"
-
-func (s *schedulingServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
- ctx := req.Context()
- ctx = ctxsetters.WithPackageName(ctx, "within.website.x.mimi.scheduling")
- ctx = ctxsetters.WithServiceName(ctx, "Scheduling")
- ctx = ctxsetters.WithResponseWriter(ctx, resp)
-
- var err error
- ctx, err = callRequestReceived(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- if req.Method != "POST" {
- msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
-
- // Verify path format: [<prefix>]/<package>.<Service>/<Method>
- prefix, pkgService, method := parseTwirpPath(req.URL.Path)
- if pkgService != "within.website.x.mimi.scheduling.Scheduling" {
- msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
- if prefix != s.pathPrefix {
- msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
-
- switch method {
- case "ParseEmail":
- s.serveParseEmail(ctx, resp, req)
- return
- default:
- msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
- s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
- return
- }
-}
-
-func (s *schedulingServer) serveParseEmail(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- header := req.Header.Get("Content-Type")
- i := strings.Index(header, ";")
- if i == -1 {
- i = len(header)
- }
- switch strings.TrimSpace(strings.ToLower(header[:i])) {
- case "application/json":
- s.serveParseEmailJSON(ctx, resp, req)
- case "application/protobuf":
- s.serveParseEmailProtobuf(ctx, resp, req)
- default:
- msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
- twerr := badRouteError(msg, req.Method, req.URL.Path)
- s.writeError(ctx, resp, twerr)
- }
-}
-
-func (s *schedulingServer) serveParseEmailJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "ParseEmail")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- d := json.NewDecoder(req.Body)
- rawReqBody := json.RawMessage{}
- if err := d.Decode(&rawReqBody); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
- reqContent := new(ParseReq)
- unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true}
- if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil {
- s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err)
- return
- }
-
- handler := s.Scheduling.ParseEmail
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *ParseReq) (*ParseResp, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*ParseReq)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*ParseReq) when calling interceptor")
- }
- return s.Scheduling.ParseEmail(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*ParseResp)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*ParseResp) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *ParseResp
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *ParseResp and nil error while calling ParseEmail. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults}
- respBytes, err := marshaler.Marshal(respContent)
- if err != nil {
- s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
- return
- }
-
- ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
- resp.Header().Set("Content-Type", "application/json")
- resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
- resp.WriteHeader(http.StatusOK)
-
- if n, err := resp.Write(respBytes); err != nil {
- msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
- twerr := twirp.NewError(twirp.Unknown, msg)
- ctx = callError(ctx, s.hooks, twerr)
- }
- callResponseSent(ctx, s.hooks)
-}
-
-func (s *schedulingServer) serveParseEmailProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
- var err error
- ctx = ctxsetters.WithMethodName(ctx, "ParseEmail")
- ctx, err = callRequestRouted(ctx, s.hooks)
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
-
- buf, err := io.ReadAll(req.Body)
- if err != nil {
- s.handleRequestBodyError(ctx, resp, "failed to read request body", err)
- return
- }
- reqContent := new(ParseReq)
- if err = proto.Unmarshal(buf, reqContent); err != nil {
- s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
- return
- }
-
- handler := s.Scheduling.ParseEmail
- if s.interceptor != nil {
- handler = func(ctx context.Context, req *ParseReq) (*ParseResp, error) {
- resp, err := s.interceptor(
- func(ctx context.Context, req interface{}) (interface{}, error) {
- typedReq, ok := req.(*ParseReq)
- if !ok {
- return nil, twirp.InternalError("failed type assertion req.(*ParseReq) when calling interceptor")
- }
- return s.Scheduling.ParseEmail(ctx, typedReq)
- },
- )(ctx, req)
- if resp != nil {
- typedResp, ok := resp.(*ParseResp)
- if !ok {
- return nil, twirp.InternalError("failed type assertion resp.(*ParseResp) when calling interceptor")
- }
- return typedResp, err
- }
- return nil, err
- }
- }
-
- // Call service method
- var respContent *ParseResp
- func() {
- defer ensurePanicResponses(ctx, resp, s.hooks)
- respContent, err = handler(ctx, reqContent)
- }()
-
- if err != nil {
- s.writeError(ctx, resp, err)
- return
- }
- if respContent == nil {
- s.writeError(ctx, resp, twirp.InternalError("received a nil *ParseResp and nil error while calling ParseEmail. nil responses are not supported"))
- return
- }
-
- ctx = callResponsePrepared(ctx, s.hooks)
-
- re