From 622eca78cbd629f0d1f3c1d34f61b34d057b25e9 Mon Sep 17 00:00:00 2001 From: charles Date: Tue, 24 Mar 2026 21:11:45 -0700 Subject: [PATCH] add: some proto stuff --- .gitignore | 1 + Makefile | 23 + README.md | 2 + buf.gen.yaml | 8 + buf.yaml | 10 + go.mod | 14 + go.sum | 34 + pkg/api/webstory/v1/api.pb.go | 1231 ++++++++++++++++++++++++++++ pkg/api/webstory/v1/api_grpc.pb.go | 291 +++++++ proto/webstory/v1/api.proto | 138 ++++ 10 files changed, 1752 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 buf.gen.yaml create mode 100644 buf.yaml create mode 100644 go.sum create mode 100644 pkg/api/webstory/v1/api.pb.go create mode 100644 pkg/api/webstory/v1/api_grpc.pb.go create mode 100644 proto/webstory/v1/api.proto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2849ccd --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +.PHONY: proto proto-deps help + +# Default target +all: help + +# Generate Go code from proto files using buf +proto: proto-deps + @echo "Generating Go code from proto files..." + buf generate || exit 1 + @echo "Proto generation complete!" + +# Ensure buf is available +proto-deps: + @which buf >/dev/null 2>&1 || (echo "Error: buf is not installed. Please install Buf first." && exit 1) + +# Help target +help: + @echo "Webstory Makefile" + @echo "" + @echo "Available targets:" + @echo " make all - Show this help message" + @echo " make proto - Generate Go code from proto files" + @echo " make proto-deps - Ensure buf is installed" diff --git a/README.md b/README.md index a2f67eb..cca6173 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,8 @@ pkg/ollama -- manages access to the Ollama backend pkg/api -- contains code implementing the webstory API +The backend is implemented in gRPC, but exposes a traditional REST API. + ### Frontend All frontend code resides in web/. diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 0000000..18a15c8 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,8 @@ +version: v1 +plugins: + - name: go + out: pkg/api + opt: paths=source_relative + - name: go-grpc + out: pkg/api + opt: paths=source_relative diff --git a/buf.yaml b/buf.yaml new file mode 100644 index 0000000..a851a10 --- /dev/null +++ b/buf.yaml @@ -0,0 +1,10 @@ +# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml +version: v2 +lint: + use: + - STANDARD +breaking: + use: + - FILE +modules: + - path: proto diff --git a/go.mod b/go.mod index d07f2c7..fe22120 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,17 @@ module git.tipsy.codes/charles/webstory go 1.26.1 + +require ( + google.golang.org/grpc v1.70.0 + google.golang.org/protobuf v1.36.11 +) + +require ( + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..29fdc61 --- /dev/null +++ b/go.sum @@ -0,0 +1,34 @@ +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/pkg/api/webstory/v1/api.pb.go b/pkg/api/webstory/v1/api.pb.go new file mode 100644 index 0000000..5d0b44a --- /dev/null +++ b/pkg/api/webstory/v1/api.pb.go @@ -0,0 +1,1231 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: webstory/v1/api.proto + +package api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +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) +) + +// Story represents the current state of an interactive fiction session +type Story struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` // Unique identifier for this story session + CurrentScene string `protobuf:"bytes,2,opt,name=current_scene,json=currentScene,proto3" json:"current_scene,omitempty"` // Current scene/location identifier + Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` // Current story status (playing, paused, completed) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Story) Reset() { + *x = Story{} + mi := &file_webstory_v1_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Story) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Story) ProtoMessage() {} + +func (x *Story) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Story.ProtoReflect.Descriptor instead. +func (*Story) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{0} +} + +func (x *Story) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *Story) GetCurrentScene() string { + if x != nil { + return x.CurrentScene + } + return "" +} + +func (x *Story) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +// Visualization represents an image or visual element to display +type Visualization struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Type of visualization: portrait, scene, map, etc. + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` // URL or path to the visualization + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // Description of what should be shown + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Visualization) Reset() { + *x = Visualization{} + mi := &file_webstory_v1_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Visualization) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Visualization) ProtoMessage() {} + +func (x *Visualization) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Visualization.ProtoReflect.Descriptor instead. +func (*Visualization) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{1} +} + +func (x *Visualization) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Visualization) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *Visualization) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +// Choice represents an option the user can select +type Choice struct { + state protoimpl.MessageState `protogen:"open.v1"` + Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"` // Text displayed on the button + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` // Action to trigger when selected + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Additional metadata (optional) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Choice) Reset() { + *x = Choice{} + mi := &file_webstory_v1_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Choice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Choice) ProtoMessage() {} + +func (x *Choice) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Choice.ProtoReflect.Descriptor instead. +func (*Choice) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{2} +} + +func (x *Choice) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *Choice) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *Choice) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// Message represents a communication between client and server +type Message struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Unique message identifier + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` // Message type: user_input, story_text, system, etc. + Content string `protobuf:"bytes,3,opt,name=content,proto3" json:"content,omitempty"` // Message content + Choices []*Choice `protobuf:"bytes,4,rep,name=choices,proto3" json:"choices,omitempty"` // Available choices (if any) + Visualization *Visualization `protobuf:"bytes,5,opt,name=visualization,proto3" json:"visualization,omitempty"` // Associated visualization (if any) + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when message was created + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when message was last updated + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Message) Reset() { + *x = Message{} + mi := &file_webstory_v1_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{3} +} + +func (x *Message) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Message) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Message) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *Message) GetChoices() []*Choice { + if x != nil { + return x.Choices + } + return nil +} + +func (x *Message) GetVisualization() *Visualization { + if x != nil { + return x.Visualization + } + return nil +} + +func (x *Message) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Message) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +// ChatHistory represents the conversation history +type ChatHistory struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Messages []*Message `protobuf:"bytes,2,rep,name=messages,proto3" json:"messages,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when chat history was created + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // Timestamp when chat history was last updated + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatHistory) Reset() { + *x = ChatHistory{} + mi := &file_webstory_v1_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatHistory) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatHistory) ProtoMessage() {} + +func (x *ChatHistory) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatHistory.ProtoReflect.Descriptor instead. +func (*ChatHistory) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{4} +} + +func (x *ChatHistory) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *ChatHistory) GetMessages() []*Message { + if x != nil { + return x.Messages + } + return nil +} + +func (x *ChatHistory) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *ChatHistory) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +// Request for starting a new story +type StartStoryRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` // Optional: client-provided session ID + InitialScene string `protobuf:"bytes,2,opt,name=initial_scene,json=initialScene,proto3" json:"initial_scene,omitempty"` // Starting scene or scenario prompt + StoryGenre string `protobuf:"bytes,3,opt,name=story_genre,json=storyGenre,proto3" json:"story_genre,omitempty"` // Genre preferences (fantasy, sci-fi, etc.) + Options map[string]string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Additional configuration options + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when request was created + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StartStoryRequest) Reset() { + *x = StartStoryRequest{} + mi := &file_webstory_v1_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StartStoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartStoryRequest) ProtoMessage() {} + +func (x *StartStoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartStoryRequest.ProtoReflect.Descriptor instead. +func (*StartStoryRequest) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{5} +} + +func (x *StartStoryRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *StartStoryRequest) GetInitialScene() string { + if x != nil { + return x.InitialScene + } + return "" +} + +func (x *StartStoryRequest) GetStoryGenre() string { + if x != nil { + return x.StoryGenre + } + return "" +} + +func (x *StartStoryRequest) GetOptions() map[string]string { + if x != nil { + return x.Options + } + return nil +} + +func (x *StartStoryRequest) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +// Response for starting a story +type StartStoryResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + InitialMessage *Message `protobuf:"bytes,3,opt,name=initial_message,json=initialMessage,proto3" json:"initial_message,omitempty"` + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when response was created + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StartStoryResponse) Reset() { + *x = StartStoryResponse{} + mi := &file_webstory_v1_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StartStoryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StartStoryResponse) ProtoMessage() {} + +func (x *StartStoryResponse) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StartStoryResponse.ProtoReflect.Descriptor instead. +func (*StartStoryResponse) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{6} +} + +func (x *StartStoryResponse) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *StartStoryResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *StartStoryResponse) GetInitialMessage() *Message { + if x != nil { + return x.InitialMessage + } + return nil +} + +func (x *StartStoryResponse) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *StartStoryResponse) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +// Request for continuing the story +type ContinueStoryRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` // User's choice or input + ChoiceId string `protobuf:"bytes,3,opt,name=choice_id,json=choiceId,proto3" json:"choice_id,omitempty"` // If selecting a specific choice + Options map[string]string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Optional parameters + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Timestamp when request was created + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContinueStoryRequest) Reset() { + *x = ContinueStoryRequest{} + mi := &file_webstory_v1_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContinueStoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContinueStoryRequest) ProtoMessage() {} + +func (x *ContinueStoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContinueStoryRequest.ProtoReflect.Descriptor instead. +func (*ContinueStoryRequest) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{7} +} + +func (x *ContinueStoryRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *ContinueStoryRequest) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *ContinueStoryRequest) GetChoiceId() string { + if x != nil { + return x.ChoiceId + } + return "" +} + +func (x *ContinueStoryRequest) GetOptions() map[string]string { + if x != nil { + return x.Options + } + return nil +} + +func (x *ContinueStoryRequest) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +// Response for continuing the story +type ContinueStoryResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + ResponseMessage *Message `protobuf:"bytes,3,opt,name=response_message,json=responseMessage,proto3" json:"response_message,omitempty"` + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContinueStoryResponse) Reset() { + *x = ContinueStoryResponse{} + mi := &file_webstory_v1_api_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContinueStoryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContinueStoryResponse) ProtoMessage() {} + +func (x *ContinueStoryResponse) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContinueStoryResponse.ProtoReflect.Descriptor instead. +func (*ContinueStoryResponse) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{8} +} + +func (x *ContinueStoryResponse) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *ContinueStoryResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ContinueStoryResponse) GetResponseMessage() *Message { + if x != nil { + return x.ResponseMessage + } + return nil +} + +func (x *ContinueStoryResponse) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +// Request to get story state +type GetStoryRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStoryRequest) Reset() { + *x = GetStoryRequest{} + mi := &file_webstory_v1_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStoryRequest) ProtoMessage() {} + +func (x *GetStoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStoryRequest.ProtoReflect.Descriptor instead. +func (*GetStoryRequest) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{9} +} + +func (x *GetStoryRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +// Response with current story state +type GetStoryResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Story *Story `protobuf:"bytes,2,opt,name=story,proto3" json:"story,omitempty"` + RecentMessages []*Message `protobuf:"bytes,3,rep,name=recent_messages,json=recentMessages,proto3" json:"recent_messages,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetStoryResponse) Reset() { + *x = GetStoryResponse{} + mi := &file_webstory_v1_api_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetStoryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetStoryResponse) ProtoMessage() {} + +func (x *GetStoryResponse) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetStoryResponse.ProtoReflect.Descriptor instead. +func (*GetStoryResponse) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{10} +} + +func (x *GetStoryResponse) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *GetStoryResponse) GetStory() *Story { + if x != nil { + return x.Story + } + return nil +} + +func (x *GetStoryResponse) GetRecentMessages() []*Message { + if x != nil { + return x.RecentMessages + } + return nil +} + +// Request to reset/stop a story +type ResetStoryRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResetStoryRequest) Reset() { + *x = ResetStoryRequest{} + mi := &file_webstory_v1_api_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResetStoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetStoryRequest) ProtoMessage() {} + +func (x *ResetStoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetStoryRequest.ProtoReflect.Descriptor instead. +func (*ResetStoryRequest) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{11} +} + +func (x *ResetStoryRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +type ResetStoryResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResetStoryResponse) Reset() { + *x = ResetStoryResponse{} + mi := &file_webstory_v1_api_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResetStoryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetStoryResponse) ProtoMessage() {} + +func (x *ResetStoryResponse) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetStoryResponse.ProtoReflect.Descriptor instead. +func (*ResetStoryResponse) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{12} +} + +func (x *ResetStoryResponse) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *ResetStoryResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +// Request for streaming story responses +type StreamStoryRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` + ChoiceId string `protobuf:"bytes,3,opt,name=choice_id,json=choiceId,proto3" json:"choice_id,omitempty"` + Options map[string]string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamStoryRequest) Reset() { + *x = StreamStoryRequest{} + mi := &file_webstory_v1_api_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamStoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamStoryRequest) ProtoMessage() {} + +func (x *StreamStoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamStoryRequest.ProtoReflect.Descriptor instead. +func (*StreamStoryRequest) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{13} +} + +func (x *StreamStoryRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *StreamStoryRequest) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *StreamStoryRequest) GetChoiceId() string { + if x != nil { + return x.ChoiceId + } + return "" +} + +func (x *StreamStoryRequest) GetOptions() map[string]string { + if x != nil { + return x.Options + } + return nil +} + +// Response for streaming story responses +type StreamStoryResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + PartialMessage *Message `protobuf:"bytes,2,opt,name=partial_message,json=partialMessage,proto3" json:"partial_message,omitempty"` // Partial message being built + CompleteMessage *Message `protobuf:"bytes,3,opt,name=complete_message,json=completeMessage,proto3" json:"complete_message,omitempty"` // Complete message when finalized + IsFinal bool `protobuf:"varint,4,opt,name=is_final,json=isFinal,proto3" json:"is_final,omitempty"` // Indicates if this is the final chunk + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamStoryResponse) Reset() { + *x = StreamStoryResponse{} + mi := &file_webstory_v1_api_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamStoryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamStoryResponse) ProtoMessage() {} + +func (x *StreamStoryResponse) ProtoReflect() protoreflect.Message { + mi := &file_webstory_v1_api_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamStoryResponse.ProtoReflect.Descriptor instead. +func (*StreamStoryResponse) Descriptor() ([]byte, []int) { + return file_webstory_v1_api_proto_rawDescGZIP(), []int{14} +} + +func (x *StreamStoryResponse) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *StreamStoryResponse) GetPartialMessage() *Message { + if x != nil { + return x.PartialMessage + } + return nil +} + +func (x *StreamStoryResponse) GetCompleteMessage() *Message { + if x != nil { + return x.CompleteMessage + } + return nil +} + +func (x *StreamStoryResponse) GetIsFinal() bool { + if x != nil { + return x.IsFinal + } + return false +} + +var File_webstory_v1_api_proto protoreflect.FileDescriptor + +const file_webstory_v1_api_proto_rawDesc = "" + + "\n" + + "\x15webstory/v1/api.proto\x12\vwebstory.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"c\n" + + "\x05Story\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12#\n" + + "\rcurrent_scene\x18\x02 \x01(\tR\fcurrentScene\x12\x16\n" + + "\x06status\x18\x03 \x01(\tR\x06status\"W\n" + + "\rVisualization\x12\x12\n" + + "\x04type\x18\x01 \x01(\tR\x04type\x12\x10\n" + + "\x03url\x18\x02 \x01(\tR\x03url\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\"\xb2\x01\n" + + "\x06Choice\x12\x14\n" + + "\x05label\x18\x01 \x01(\tR\x05label\x12\x16\n" + + "\x06action\x18\x02 \x01(\tR\x06action\x12=\n" + + "\bmetadata\x18\x03 \x03(\v2!.webstory.v1.Choice.MetadataEntryR\bmetadata\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xae\x02\n" + + "\aMessage\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12\x18\n" + + "\acontent\x18\x03 \x01(\tR\acontent\x12-\n" + + "\achoices\x18\x04 \x03(\v2\x13.webstory.v1.ChoiceR\achoices\x12@\n" + + "\rvisualization\x18\x05 \x01(\v2\x1a.webstory.v1.VisualizationR\rvisualization\x129\n" + + "\n" + + "created_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"\xd4\x01\n" + + "\vChatHistory\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x120\n" + + "\bmessages\x18\x02 \x03(\v2\x14.webstory.v1.MessageR\bmessages\x129\n" + + "\n" + + "created_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"\xb6\x02\n" + + "\x11StartStoryRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12#\n" + + "\rinitial_scene\x18\x02 \x01(\tR\finitialScene\x12\x1f\n" + + "\vstory_genre\x18\x03 \x01(\tR\n" + + "storyGenre\x12E\n" + + "\aoptions\x18\x04 \x03(\v2+.webstory.v1.StartStoryRequest.OptionsEntryR\aoptions\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x1a:\n" + + "\fOptionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xcd\x02\n" + + "\x12StartStoryResponse\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + + "\x06status\x18\x02 \x01(\tR\x06status\x12=\n" + + "\x0finitial_message\x18\x03 \x01(\v2\x14.webstory.v1.MessageR\x0einitialMessage\x12I\n" + + "\bmetadata\x18\x04 \x03(\v2-.webstory.v1.StartStoryResponse.MetadataEntryR\bmetadata\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xab\x02\n" + + "\x14ContinueStoryRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + + "\x06action\x18\x02 \x01(\tR\x06action\x12\x1b\n" + + "\tchoice_id\x18\x03 \x01(\tR\bchoiceId\x12H\n" + + "\aoptions\x18\x04 \x03(\v2..webstory.v1.ContinueStoryRequest.OptionsEntryR\aoptions\x129\n" + + "\n" + + "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x1a:\n" + + "\fOptionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x9a\x02\n" + + "\x15ContinueStoryResponse\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + + "\x06status\x18\x02 \x01(\tR\x06status\x12?\n" + + "\x10response_message\x18\x03 \x01(\v2\x14.webstory.v1.MessageR\x0fresponseMessage\x12L\n" + + "\bmetadata\x18\x04 \x03(\v20.webstory.v1.ContinueStoryResponse.MetadataEntryR\bmetadata\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"0\n" + + "\x0fGetStoryRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\"\x9a\x01\n" + + "\x10GetStoryResponse\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12(\n" + + "\x05story\x18\x02 \x01(\v2\x12.webstory.v1.StoryR\x05story\x12=\n" + + "\x0frecent_messages\x18\x03 \x03(\v2\x14.webstory.v1.MessageR\x0erecentMessages\"2\n" + + "\x11ResetStoryRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\"K\n" + + "\x12ResetStoryResponse\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + + "\x06status\x18\x02 \x01(\tR\x06status\"\xec\x01\n" + + "\x12StreamStoryRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + + "\x06action\x18\x02 \x01(\tR\x06action\x12\x1b\n" + + "\tchoice_id\x18\x03 \x01(\tR\bchoiceId\x12F\n" + + "\aoptions\x18\x04 \x03(\v2,.webstory.v1.StreamStoryRequest.OptionsEntryR\aoptions\x1a:\n" + + "\fOptionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xcf\x01\n" + + "\x13StreamStoryResponse\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12=\n" + + "\x0fpartial_message\x18\x02 \x01(\v2\x14.webstory.v1.MessageR\x0epartialMessage\x12?\n" + + "\x10complete_message\x18\x03 \x01(\v2\x14.webstory.v1.MessageR\x0fcompleteMessage\x12\x19\n" + + "\bis_final\x18\x04 \x01(\bR\aisFinal2\xa4\x03\n" + + "\x0fWebstoryService\x12M\n" + + "\n" + + "StartStory\x12\x1e.webstory.v1.StartStoryRequest\x1a\x1f.webstory.v1.StartStoryResponse\x12V\n" + + "\rContinueStory\x12!.webstory.v1.ContinueStoryRequest\x1a\".webstory.v1.ContinueStoryResponse\x12G\n" + + "\bGetStory\x12\x1c.webstory.v1.GetStoryRequest\x1a\x1d.webstory.v1.GetStoryResponse\x12M\n" + + "\n" + + "ResetStory\x12\x1e.webstory.v1.ResetStoryRequest\x1a\x1f.webstory.v1.ResetStoryResponse\x12R\n" + + "\vStreamStory\x12\x1f.webstory.v1.StreamStoryRequest\x1a .webstory.v1.StreamStoryResponse0\x01B*Z(git.tipsy.codes/charles/webstory/pkg/apib\x06proto3" + +var ( + file_webstory_v1_api_proto_rawDescOnce sync.Once + file_webstory_v1_api_proto_rawDescData []byte +) + +func file_webstory_v1_api_proto_rawDescGZIP() []byte { + file_webstory_v1_api_proto_rawDescOnce.Do(func() { + file_webstory_v1_api_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_webstory_v1_api_proto_rawDesc), len(file_webstory_v1_api_proto_rawDesc))) + }) + return file_webstory_v1_api_proto_rawDescData +} + +var file_webstory_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_webstory_v1_api_proto_goTypes = []any{ + (*Story)(nil), // 0: webstory.v1.Story + (*Visualization)(nil), // 1: webstory.v1.Visualization + (*Choice)(nil), // 2: webstory.v1.Choice + (*Message)(nil), // 3: webstory.v1.Message + (*ChatHistory)(nil), // 4: webstory.v1.ChatHistory + (*StartStoryRequest)(nil), // 5: webstory.v1.StartStoryRequest + (*StartStoryResponse)(nil), // 6: webstory.v1.StartStoryResponse + (*ContinueStoryRequest)(nil), // 7: webstory.v1.ContinueStoryRequest + (*ContinueStoryResponse)(nil), // 8: webstory.v1.ContinueStoryResponse + (*GetStoryRequest)(nil), // 9: webstory.v1.GetStoryRequest + (*GetStoryResponse)(nil), // 10: webstory.v1.GetStoryResponse + (*ResetStoryRequest)(nil), // 11: webstory.v1.ResetStoryRequest + (*ResetStoryResponse)(nil), // 12: webstory.v1.ResetStoryResponse + (*StreamStoryRequest)(nil), // 13: webstory.v1.StreamStoryRequest + (*StreamStoryResponse)(nil), // 14: webstory.v1.StreamStoryResponse + nil, // 15: webstory.v1.Choice.MetadataEntry + nil, // 16: webstory.v1.StartStoryRequest.OptionsEntry + nil, // 17: webstory.v1.StartStoryResponse.MetadataEntry + nil, // 18: webstory.v1.ContinueStoryRequest.OptionsEntry + nil, // 19: webstory.v1.ContinueStoryResponse.MetadataEntry + nil, // 20: webstory.v1.StreamStoryRequest.OptionsEntry + (*timestamppb.Timestamp)(nil), // 21: google.protobuf.Timestamp +} +var file_webstory_v1_api_proto_depIdxs = []int32{ + 15, // 0: webstory.v1.Choice.metadata:type_name -> webstory.v1.Choice.MetadataEntry + 2, // 1: webstory.v1.Message.choices:type_name -> webstory.v1.Choice + 1, // 2: webstory.v1.Message.visualization:type_name -> webstory.v1.Visualization + 21, // 3: webstory.v1.Message.created_at:type_name -> google.protobuf.Timestamp + 21, // 4: webstory.v1.Message.updated_at:type_name -> google.protobuf.Timestamp + 3, // 5: webstory.v1.ChatHistory.messages:type_name -> webstory.v1.Message + 21, // 6: webstory.v1.ChatHistory.created_at:type_name -> google.protobuf.Timestamp + 21, // 7: webstory.v1.ChatHistory.updated_at:type_name -> google.protobuf.Timestamp + 16, // 8: webstory.v1.StartStoryRequest.options:type_name -> webstory.v1.StartStoryRequest.OptionsEntry + 21, // 9: webstory.v1.StartStoryRequest.created_at:type_name -> google.protobuf.Timestamp + 3, // 10: webstory.v1.StartStoryResponse.initial_message:type_name -> webstory.v1.Message + 17, // 11: webstory.v1.StartStoryResponse.metadata:type_name -> webstory.v1.StartStoryResponse.MetadataEntry + 21, // 12: webstory.v1.StartStoryResponse.created_at:type_name -> google.protobuf.Timestamp + 18, // 13: webstory.v1.ContinueStoryRequest.options:type_name -> webstory.v1.ContinueStoryRequest.OptionsEntry + 21, // 14: webstory.v1.ContinueStoryRequest.created_at:type_name -> google.protobuf.Timestamp + 3, // 15: webstory.v1.ContinueStoryResponse.response_message:type_name -> webstory.v1.Message + 19, // 16: webstory.v1.ContinueStoryResponse.metadata:type_name -> webstory.v1.ContinueStoryResponse.MetadataEntry + 0, // 17: webstory.v1.GetStoryResponse.story:type_name -> webstory.v1.Story + 3, // 18: webstory.v1.GetStoryResponse.recent_messages:type_name -> webstory.v1.Message + 20, // 19: webstory.v1.StreamStoryRequest.options:type_name -> webstory.v1.StreamStoryRequest.OptionsEntry + 3, // 20: webstory.v1.StreamStoryResponse.partial_message:type_name -> webstory.v1.Message + 3, // 21: webstory.v1.StreamStoryResponse.complete_message:type_name -> webstory.v1.Message + 5, // 22: webstory.v1.WebstoryService.StartStory:input_type -> webstory.v1.StartStoryRequest + 7, // 23: webstory.v1.WebstoryService.ContinueStory:input_type -> webstory.v1.ContinueStoryRequest + 9, // 24: webstory.v1.WebstoryService.GetStory:input_type -> webstory.v1.GetStoryRequest + 11, // 25: webstory.v1.WebstoryService.ResetStory:input_type -> webstory.v1.ResetStoryRequest + 13, // 26: webstory.v1.WebstoryService.StreamStory:input_type -> webstory.v1.StreamStoryRequest + 6, // 27: webstory.v1.WebstoryService.StartStory:output_type -> webstory.v1.StartStoryResponse + 8, // 28: webstory.v1.WebstoryService.ContinueStory:output_type -> webstory.v1.ContinueStoryResponse + 10, // 29: webstory.v1.WebstoryService.GetStory:output_type -> webstory.v1.GetStoryResponse + 12, // 30: webstory.v1.WebstoryService.ResetStory:output_type -> webstory.v1.ResetStoryResponse + 14, // 31: webstory.v1.WebstoryService.StreamStory:output_type -> webstory.v1.StreamStoryResponse + 27, // [27:32] is the sub-list for method output_type + 22, // [22:27] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name +} + +func init() { file_webstory_v1_api_proto_init() } +func file_webstory_v1_api_proto_init() { + if File_webstory_v1_api_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_webstory_v1_api_proto_rawDesc), len(file_webstory_v1_api_proto_rawDesc)), + NumEnums: 0, + NumMessages: 21, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_webstory_v1_api_proto_goTypes, + DependencyIndexes: file_webstory_v1_api_proto_depIdxs, + MessageInfos: file_webstory_v1_api_proto_msgTypes, + }.Build() + File_webstory_v1_api_proto = out.File + file_webstory_v1_api_proto_goTypes = nil + file_webstory_v1_api_proto_depIdxs = nil +} diff --git a/pkg/api/webstory/v1/api_grpc.pb.go b/pkg/api/webstory/v1/api_grpc.pb.go new file mode 100644 index 0000000..3c2a3a5 --- /dev/null +++ b/pkg/api/webstory/v1/api_grpc.pb.go @@ -0,0 +1,291 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.1 +// - protoc (unknown) +// source: webstory/v1/api.proto + +package api + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + WebstoryService_StartStory_FullMethodName = "/webstory.v1.WebstoryService/StartStory" + WebstoryService_ContinueStory_FullMethodName = "/webstory.v1.WebstoryService/ContinueStory" + WebstoryService_GetStory_FullMethodName = "/webstory.v1.WebstoryService/GetStory" + WebstoryService_ResetStory_FullMethodName = "/webstory.v1.WebstoryService/ResetStory" + WebstoryService_StreamStory_FullMethodName = "/webstory.v1.WebstoryService/StreamStory" +) + +// WebstoryServiceClient is the client API for WebstoryService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// WebstoryService defines the RPC methods for the interactive fiction service +type WebstoryServiceClient interface { + // Start a new story session + StartStory(ctx context.Context, in *StartStoryRequest, opts ...grpc.CallOption) (*StartStoryResponse, error) + // Continue the story with user input or choice + ContinueStory(ctx context.Context, in *ContinueStoryRequest, opts ...grpc.CallOption) (*ContinueStoryResponse, error) + // Get the current state of a story + GetStory(ctx context.Context, in *GetStoryRequest, opts ...grpc.CallOption) (*GetStoryResponse, error) + // Reset or terminate a story session + ResetStory(ctx context.Context, in *ResetStoryRequest, opts ...grpc.CallOption) (*ResetStoryResponse, error) + // Stream story responses in real-time + StreamStory(ctx context.Context, in *StreamStoryRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamStoryResponse], error) +} + +type webstoryServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewWebstoryServiceClient(cc grpc.ClientConnInterface) WebstoryServiceClient { + return &webstoryServiceClient{cc} +} + +func (c *webstoryServiceClient) StartStory(ctx context.Context, in *StartStoryRequest, opts ...grpc.CallOption) (*StartStoryResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(StartStoryResponse) + err := c.cc.Invoke(ctx, WebstoryService_StartStory_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webstoryServiceClient) ContinueStory(ctx context.Context, in *ContinueStoryRequest, opts ...grpc.CallOption) (*ContinueStoryResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ContinueStoryResponse) + err := c.cc.Invoke(ctx, WebstoryService_ContinueStory_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webstoryServiceClient) GetStory(ctx context.Context, in *GetStoryRequest, opts ...grpc.CallOption) (*GetStoryResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetStoryResponse) + err := c.cc.Invoke(ctx, WebstoryService_GetStory_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webstoryServiceClient) ResetStory(ctx context.Context, in *ResetStoryRequest, opts ...grpc.CallOption) (*ResetStoryResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ResetStoryResponse) + err := c.cc.Invoke(ctx, WebstoryService_ResetStory_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webstoryServiceClient) StreamStory(ctx context.Context, in *StreamStoryRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[StreamStoryResponse], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &WebstoryService_ServiceDesc.Streams[0], WebstoryService_StreamStory_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &grpc.GenericClientStream[StreamStoryRequest, StreamStoryResponse]{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type WebstoryService_StreamStoryClient = grpc.ServerStreamingClient[StreamStoryResponse] + +// WebstoryServiceServer is the server API for WebstoryService service. +// All implementations must embed UnimplementedWebstoryServiceServer +// for forward compatibility. +// +// WebstoryService defines the RPC methods for the interactive fiction service +type WebstoryServiceServer interface { + // Start a new story session + StartStory(context.Context, *StartStoryRequest) (*StartStoryResponse, error) + // Continue the story with user input or choice + ContinueStory(context.Context, *ContinueStoryRequest) (*ContinueStoryResponse, error) + // Get the current state of a story + GetStory(context.Context, *GetStoryRequest) (*GetStoryResponse, error) + // Reset or terminate a story session + ResetStory(context.Context, *ResetStoryRequest) (*ResetStoryResponse, error) + // Stream story responses in real-time + StreamStory(*StreamStoryRequest, grpc.ServerStreamingServer[StreamStoryResponse]) error + mustEmbedUnimplementedWebstoryServiceServer() +} + +// UnimplementedWebstoryServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedWebstoryServiceServer struct{} + +func (UnimplementedWebstoryServiceServer) StartStory(context.Context, *StartStoryRequest) (*StartStoryResponse, error) { + return nil, status.Error(codes.Unimplemented, "method StartStory not implemented") +} +func (UnimplementedWebstoryServiceServer) ContinueStory(context.Context, *ContinueStoryRequest) (*ContinueStoryResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ContinueStory not implemented") +} +func (UnimplementedWebstoryServiceServer) GetStory(context.Context, *GetStoryRequest) (*GetStoryResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetStory not implemented") +} +func (UnimplementedWebstoryServiceServer) ResetStory(context.Context, *ResetStoryRequest) (*ResetStoryResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ResetStory not implemented") +} +func (UnimplementedWebstoryServiceServer) StreamStory(*StreamStoryRequest, grpc.ServerStreamingServer[StreamStoryResponse]) error { + return status.Error(codes.Unimplemented, "method StreamStory not implemented") +} +func (UnimplementedWebstoryServiceServer) mustEmbedUnimplementedWebstoryServiceServer() {} +func (UnimplementedWebstoryServiceServer) testEmbeddedByValue() {} + +// UnsafeWebstoryServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WebstoryServiceServer will +// result in compilation errors. +type UnsafeWebstoryServiceServer interface { + mustEmbedUnimplementedWebstoryServiceServer() +} + +func RegisterWebstoryServiceServer(s grpc.ServiceRegistrar, srv WebstoryServiceServer) { + // If the following call panics, it indicates UnimplementedWebstoryServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&WebstoryService_ServiceDesc, srv) +} + +func _WebstoryService_StartStory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StartStoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebstoryServiceServer).StartStory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebstoryService_StartStory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebstoryServiceServer).StartStory(ctx, req.(*StartStoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebstoryService_ContinueStory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ContinueStoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebstoryServiceServer).ContinueStory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebstoryService_ContinueStory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebstoryServiceServer).ContinueStory(ctx, req.(*ContinueStoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebstoryService_GetStory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebstoryServiceServer).GetStory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebstoryService_GetStory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebstoryServiceServer).GetStory(ctx, req.(*GetStoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebstoryService_ResetStory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResetStoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebstoryServiceServer).ResetStory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebstoryService_ResetStory_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebstoryServiceServer).ResetStory(ctx, req.(*ResetStoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebstoryService_StreamStory_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(StreamStoryRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(WebstoryServiceServer).StreamStory(m, &grpc.GenericServerStream[StreamStoryRequest, StreamStoryResponse]{ServerStream: stream}) +} + +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type WebstoryService_StreamStoryServer = grpc.ServerStreamingServer[StreamStoryResponse] + +// WebstoryService_ServiceDesc is the grpc.ServiceDesc for WebstoryService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var WebstoryService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "webstory.v1.WebstoryService", + HandlerType: (*WebstoryServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "StartStory", + Handler: _WebstoryService_StartStory_Handler, + }, + { + MethodName: "ContinueStory", + Handler: _WebstoryService_ContinueStory_Handler, + }, + { + MethodName: "GetStory", + Handler: _WebstoryService_GetStory_Handler, + }, + { + MethodName: "ResetStory", + Handler: _WebstoryService_ResetStory_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamStory", + Handler: _WebstoryService_StreamStory_Handler, + ServerStreams: true, + }, + }, + Metadata: "webstory/v1/api.proto", +} diff --git a/proto/webstory/v1/api.proto b/proto/webstory/v1/api.proto new file mode 100644 index 0000000..95defa2 --- /dev/null +++ b/proto/webstory/v1/api.proto @@ -0,0 +1,138 @@ +syntax = "proto3"; + +package webstory.v1; + +import "google/protobuf/timestamp.proto"; + +option go_package = "git.tipsy.codes/charles/webstory/pkg/api"; + +// Story represents the current state of an interactive fiction session +message Story { + string session_id = 1; // Unique identifier for this story session + string current_scene = 2; // Current scene/location identifier + string status = 3; // Current story status (playing, paused, completed) +} + +// Visualization represents an image or visual element to display +message Visualization { + string type = 1; // Type of visualization: portrait, scene, map, etc. + string url = 2; // URL or path to the visualization + string description = 3; // Description of what should be shown +} + +// Choice represents an option the user can select +message Choice { + string label = 1; // Text displayed on the button + string action = 2; // Action to trigger when selected + map metadata = 3; // Additional metadata (optional) +} + +// Message represents a communication between client and server +message Message { + string id = 1; // Unique message identifier + string type = 2; // Message type: user_input, story_text, system, etc. + string content = 3; // Message content + repeated Choice choices = 4; // Available choices (if any) + Visualization visualization = 5; // Associated visualization (if any) + google.protobuf.Timestamp created_at = 6; // Timestamp when message was created + google.protobuf.Timestamp updated_at = 7; // Timestamp when message was last updated +} + +// ChatHistory represents the conversation history +message ChatHistory { + string session_id = 1; + repeated Message messages = 2; + google.protobuf.Timestamp created_at = 3; // Timestamp when chat history was created + google.protobuf.Timestamp updated_at = 4; // Timestamp when chat history was last updated +} + +// Request for starting a new story +message StartStoryRequest { + string session_id = 1; // Optional: client-provided session ID + string initial_scene = 2; // Starting scene or scenario prompt + string story_genre = 3; // Genre preferences (fantasy, sci-fi, etc.) + map options = 4; // Additional configuration options + google.protobuf.Timestamp created_at = 5; // Timestamp when request was created +} + +// Response for starting a story +message StartStoryResponse { + string session_id = 1; + string status = 2; + Message initial_message = 3; + map metadata = 4; + google.protobuf.Timestamp created_at = 5; // Timestamp when response was created +} + +// Request for continuing the story +message ContinueStoryRequest { + string session_id = 1; + string action = 2; // User's choice or input + string choice_id = 3; // If selecting a specific choice + map options = 4; // Optional parameters + google.protobuf.Timestamp created_at = 5; // Timestamp when request was created +} + +// Response for continuing the story +message ContinueStoryResponse { + string session_id = 1; + string status = 2; + Message response_message = 3; + map metadata = 4; +} + +// Request to get story state +message GetStoryRequest { + string session_id = 1; +} + +// Response with current story state +message GetStoryResponse { + string session_id = 1; + Story story = 2; + repeated Message recent_messages = 3; +} + +// Request to reset/stop a story +message ResetStoryRequest { + string session_id = 1; +} + +message ResetStoryResponse { + string session_id = 1; + string status = 2; +} + +// WebstoryService defines the RPC methods for the interactive fiction service +service WebstoryService { + // Start a new story session + rpc StartStory(StartStoryRequest) returns (StartStoryResponse); + + // Continue the story with user input or choice + rpc ContinueStory(ContinueStoryRequest) returns (ContinueStoryResponse); + + // Get the current state of a story + rpc GetStory(GetStoryRequest) returns (GetStoryResponse); + + // Reset or terminate a story session + rpc ResetStory(ResetStoryRequest) returns (ResetStoryResponse); + + // Stream story responses in real-time + rpc StreamStory(StreamStoryRequest) returns (stream StreamStoryResponse); +} + +// Request for streaming story responses +message StreamStoryRequest { + string session_id = 1; + string action = 2; + string choice_id = 3; + map options = 4; +} + +// Response for streaming story responses +message StreamStoryResponse { + string session_id = 1; + Message partial_message = 2; // Partial message being built + Message complete_message = 3; // Complete message when finalized + bool is_final = 4; // Indicates if this is the final chunk +}