diff --git a/cmd/root/new.go b/cmd/root/new.go index 6716e82ba..f6bd644eb 100644 --- a/cmd/root/new.go +++ b/cmd/root/new.go @@ -12,6 +12,7 @@ import ( "github.com/docker/cagent/pkg/creator" "github.com/docker/cagent/pkg/runtime" "github.com/docker/cagent/pkg/session" + "github.com/docker/cagent/pkg/sessiontitle" "github.com/docker/cagent/pkg/telemetry" "github.com/docker/cagent/pkg/tui" ) @@ -73,6 +74,13 @@ func (f *newFlags) runNewCommand(cmd *cobra.Command, args []string) error { } func runTUI(ctx context.Context, rt runtime.Runtime, sess *session.Session, opts ...app.Opt) error { + // For local runtime, create and pass a title generator. + if pr, ok := rt.(*runtime.PersistentRuntime); ok { + if model := pr.CurrentAgent().Model(); model != nil { + opts = append(opts, app.WithTitleGenerator(sessiontitle.New(model))) + } + } + a := app.New(ctx, rt, sess, opts...) m := tui.New(ctx, a) diff --git a/docs/USAGE.md b/docs/USAGE.md index 8797235a4..18de96964 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -172,6 +172,7 @@ During TUI sessions, you can use special slash commands. Type `/` to see all ava | `/star` | Toggle star on current session | | `/theme` | Change the color theme (see [Theming](#theming)) | | `/think` | Toggle thinking/reasoning mode | +| `/title` | Set or regenerate session title (usage: /title [new title]) | | `/yolo` | Toggle automatic approval of tool calls | #### Runtime Model Switching @@ -279,6 +280,30 @@ Themes can customize colors in three sections: `colors`, `chroma` (syntax highli See the [built-in themes on GitHub](https://github.com/docker/cagent/tree/main/pkg/tui/styles/themes) for complete examples. +#### Session Title Editing + +You can customize session titles to make them more meaningful and easier to find later. By default, cagent automatically generates titles based on your first message, but you can override or regenerate them at any time. + +**Using the `/title` command:** + +``` +/title # Regenerate title using AI (based on at most the last 2 user messages) +/title My Custom Title # Set a specific title +``` + +**Using the sidebar:** + +In the TUI, you can click on the pencil icon (✎) next to the session title in the sidebar to edit it inline: + +1. Click the pencil icon next to the title +2. Type your new title +3. Press Enter to save, or Escape to cancel + +**Notes:** +- Manually set titles are preserved and won't be overwritten by auto-generation +- Title changes are persisted immediately to the session +- Works with both local and remote runtimes + ## 🔧 Configuration Reference ### Agent Properties diff --git a/e2e/runtime_test.go b/e2e/runtime_test.go index d21311d13..47c559abf 100644 --- a/e2e/runtime_test.go +++ b/e2e/runtime_test.go @@ -32,7 +32,7 @@ func TestRuntime_OpenAI_Basic(t *testing.T) { response := sess.GetLastAssistantMessageContent() assert.Equal(t, "2 + 2 equals 4.", response) - assert.Equal(t, "Simple Math: Addition of 2 and 2", sess.Title) + // Title generation is now handled by pkg/app or pkg/server, not the runtime } func TestRuntime_Mistral_Basic(t *testing.T) { @@ -55,5 +55,5 @@ func TestRuntime_Mistral_Basic(t *testing.T) { response := sess.GetLastAssistantMessageContent() assert.Equal(t, "The sum of 2 + 2 is 4.", response) - assert.Equal(t, "Math Basics: Simple Addition", sess.Title) + // Title generation is now handled by pkg/app or pkg/server, not the runtime } diff --git a/e2e/testdata/cassettes/TestRuntime_Mistral_Basic.yaml b/e2e/testdata/cassettes/TestRuntime_Mistral_Basic.yaml index 9e13e4668..d2e2c81c7 100644 --- a/e2e/testdata/cassettes/TestRuntime_Mistral_Basic.yaml +++ b/e2e/testdata/cassettes/TestRuntime_Mistral_Basic.yaml @@ -58,7 +58,7 @@ interactions: proto_minor: 1 content_length: 0 host: api.mistral.ai - body: '{"messages":[{"content":"You are a helpful AI assistant that generates concise, descriptive titles for conversations. You will be given a conversation history and asked to create a single-line title that captures the main topic. Never use newlines or line breaks in your response.","role":"system"},{"content":"Based on the following message a user sent to an AI assistant, generate a short, descriptive title (maximum 50 characters) that captures the main topic or purpose of the conversation. Return ONLY the title text on a single line, nothing else. Do not include any newlines, explanations, or formatting.\n\nUser message: What''s 2+2?\n\n","role":"user"}],"model":"mistral-small","stream_options":{"include_usage":true},"stream":true}' + body: '{"messages":[{"content":"You are a helpful AI assistant that generates concise, descriptive titles for conversations. You will be given up to 2 recent user messages and asked to create a single-line title that captures the main topic. Never use newlines or line breaks in your response.","role":"system"},{"content":"Based on the following recent user messages from a conversation with an AI assistant, generate a short, descriptive title (maximum 50 characters) that captures the main topic or purpose of the conversation. Return ONLY the title text on a single line, nothing else. Do not include any newlines, explanations, or formatting.\n\nRecent user messages:\n1. What''s 2+2?\n\n\n","role":"user"}],"model":"mistral-small","stream_options":{"include_usage":true},"stream":true}' url: https://api.mistral.ai/v1/chat/completions method: POST response: diff --git a/e2e/testdata/cassettes/TestRuntime_OpenAI_Basic.yaml b/e2e/testdata/cassettes/TestRuntime_OpenAI_Basic.yaml index a3282e0ad..1afaf419a 100644 --- a/e2e/testdata/cassettes/TestRuntime_OpenAI_Basic.yaml +++ b/e2e/testdata/cassettes/TestRuntime_OpenAI_Basic.yaml @@ -52,7 +52,7 @@ interactions: proto_minor: 1 content_length: 0 host: api.openai.com - body: '{"messages":[{"content":"You are a helpful AI assistant that generates concise, descriptive titles for conversations. You will be given a conversation history and asked to create a single-line title that captures the main topic. Never use newlines or line breaks in your response.","role":"system"},{"content":"Based on the following message a user sent to an AI assistant, generate a short, descriptive title (maximum 50 characters) that captures the main topic or purpose of the conversation. Return ONLY the title text on a single line, nothing else. Do not include any newlines, explanations, or formatting.\n\nUser message: What''s 2+2?\n\n","role":"user"}],"model":"gpt-3.5-turbo","stream_options":{"include_usage":true},"stream":true}' + body: '{"messages":[{"content":"You are a helpful AI assistant that generates concise, descriptive titles for conversations. You will be given up to 2 recent user messages and asked to create a single-line title that captures the main topic. Never use newlines or line breaks in your response.","role":"system"},{"content":"Based on the following recent user messages from a conversation with an AI assistant, generate a short, descriptive title (maximum 50 characters) that captures the main topic or purpose of the conversation. Return ONLY the title text on a single line, nothing else. Do not include any newlines, explanations, or formatting.\n\nRecent user messages:\n1. What''s 2+2?\n\n\n","role":"user"}],"model":"gpt-3.5-turbo","stream_options":{"include_usage":true},"stream":true}' url: https://api.openai.com/v1/chat/completions method: POST response: diff --git a/gen/cagent/v1/cagent.pb.go b/gen/cagent/v1/cagent.pb.go new file mode 100644 index 000000000..b1a09fd62 --- /dev/null +++ b/gen/cagent/v1/cagent.pb.go @@ -0,0 +1,4917 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc (unknown) +// source: cagent/v1/cagent.proto + +package cagentv1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + 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) +) + +// Agent represents an agent in the system. +type Agent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Multi bool `protobuf:"varint,3,opt,name=multi,proto3" json:"multi,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Agent) Reset() { + *x = Agent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Agent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Agent) ProtoMessage() {} + +func (x *Agent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 Agent.ProtoReflect.Descriptor instead. +func (*Agent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{0} +} + +func (x *Agent) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Agent) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Agent) GetMulti() bool { + if x != nil { + return x.Multi + } + return false +} + +// ListAgentsRequest is the request for ListAgents. +type ListAgentsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListAgentsRequest) Reset() { + *x = ListAgentsRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListAgentsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAgentsRequest) ProtoMessage() {} + +func (x *ListAgentsRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 ListAgentsRequest.ProtoReflect.Descriptor instead. +func (*ListAgentsRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{1} +} + +// ListAgentsResponse is the response for ListAgents. +type ListAgentsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Agents []*Agent `protobuf:"bytes,1,rep,name=agents,proto3" json:"agents,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListAgentsResponse) Reset() { + *x = ListAgentsResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListAgentsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAgentsResponse) ProtoMessage() {} + +func (x *ListAgentsResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 ListAgentsResponse.ProtoReflect.Descriptor instead. +func (*ListAgentsResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{2} +} + +func (x *ListAgentsResponse) GetAgents() []*Agent { + if x != nil { + return x.Agents + } + return nil +} + +// GetAgentRequest is the request for GetAgent. +type GetAgentRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAgentRequest) Reset() { + *x = GetAgentRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAgentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAgentRequest) ProtoMessage() {} + +func (x *GetAgentRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 GetAgentRequest.ProtoReflect.Descriptor instead. +func (*GetAgentRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{3} +} + +func (x *GetAgentRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// GetAgentResponse is the response for GetAgent. +type GetAgentResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The agent configuration as JSON (to preserve flexibility). + ConfigJson []byte `protobuf:"bytes,1,opt,name=config_json,json=configJson,proto3" json:"config_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAgentResponse) Reset() { + *x = GetAgentResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAgentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAgentResponse) ProtoMessage() {} + +func (x *GetAgentResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 GetAgentResponse.ProtoReflect.Descriptor instead. +func (*GetAgentResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{4} +} + +func (x *GetAgentResponse) GetConfigJson() []byte { + if x != nil { + return x.ConfigJson + } + return nil +} + +// SessionSummary is a summary of a session for listing. +type SessionSummary struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + CreatedAt string `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + NumMessages int32 `protobuf:"varint,4,opt,name=num_messages,json=numMessages,proto3" json:"num_messages,omitempty"` + InputTokens int64 `protobuf:"varint,5,opt,name=input_tokens,json=inputTokens,proto3" json:"input_tokens,omitempty"` + OutputTokens int64 `protobuf:"varint,6,opt,name=output_tokens,json=outputTokens,proto3" json:"output_tokens,omitempty"` + WorkingDir string `protobuf:"bytes,7,opt,name=working_dir,json=workingDir,proto3" json:"working_dir,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SessionSummary) Reset() { + *x = SessionSummary{} + mi := &file_cagent_v1_cagent_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionSummary) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionSummary) ProtoMessage() {} + +func (x *SessionSummary) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 SessionSummary.ProtoReflect.Descriptor instead. +func (*SessionSummary) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{5} +} + +func (x *SessionSummary) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *SessionSummary) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *SessionSummary) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +func (x *SessionSummary) GetNumMessages() int32 { + if x != nil { + return x.NumMessages + } + return 0 +} + +func (x *SessionSummary) GetInputTokens() int64 { + if x != nil { + return x.InputTokens + } + return 0 +} + +func (x *SessionSummary) GetOutputTokens() int64 { + if x != nil { + return x.OutputTokens + } + return 0 +} + +func (x *SessionSummary) GetWorkingDir() string { + if x != nil { + return x.WorkingDir + } + return "" +} + +// ListSessionsRequest is the request for ListSessions. +type ListSessionsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListSessionsRequest) Reset() { + *x = ListSessionsRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListSessionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSessionsRequest) ProtoMessage() {} + +func (x *ListSessionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 ListSessionsRequest.ProtoReflect.Descriptor instead. +func (*ListSessionsRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{6} +} + +// ListSessionsResponse is the response for ListSessions. +type ListSessionsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Sessions []*SessionSummary `protobuf:"bytes,1,rep,name=sessions,proto3" json:"sessions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListSessionsResponse) Reset() { + *x = ListSessionsResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListSessionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListSessionsResponse) ProtoMessage() {} + +func (x *ListSessionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 ListSessionsResponse.ProtoReflect.Descriptor instead. +func (*ListSessionsResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{7} +} + +func (x *ListSessionsResponse) GetSessions() []*SessionSummary { + if x != nil { + return x.Sessions + } + return nil +} + +// Message represents a chat message. +type Message struct { + state protoimpl.MessageState `protogen:"open.v1"` + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` + CreatedAt string `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + ToolCallId string `protobuf:"bytes,4,opt,name=tool_call_id,json=toolCallId,proto3" json:"tool_call_id,omitempty"` + ToolCalls []*ToolCall `protobuf:"bytes,5,rep,name=tool_calls,json=toolCalls,proto3" json:"tool_calls,omitempty"` + ReasoningContent string `protobuf:"bytes,6,opt,name=reasoning_content,json=reasoningContent,proto3" json:"reasoning_content,omitempty"` + AgentName string `protobuf:"bytes,7,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Message) Reset() { + *x = Message{} + mi := &file_cagent_v1_cagent_proto_msgTypes[8] + 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_cagent_v1_cagent_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 Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{8} +} + +func (x *Message) GetRole() string { + if x != nil { + return x.Role + } + return "" +} + +func (x *Message) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *Message) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +func (x *Message) GetToolCallId() string { + if x != nil { + return x.ToolCallId + } + return "" +} + +func (x *Message) GetToolCalls() []*ToolCall { + if x != nil { + return x.ToolCalls + } + return nil +} + +func (x *Message) GetReasoningContent() string { + if x != nil { + return x.ReasoningContent + } + return "" +} + +func (x *Message) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ToolCall represents a tool call. +type ToolCall struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Function *FunctionCall `protobuf:"bytes,3,opt,name=function,proto3" json:"function,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolCall) Reset() { + *x = ToolCall{} + mi := &file_cagent_v1_cagent_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolCall) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolCall) ProtoMessage() {} + +func (x *ToolCall) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 ToolCall.ProtoReflect.Descriptor instead. +func (*ToolCall) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{9} +} + +func (x *ToolCall) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ToolCall) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ToolCall) GetFunction() *FunctionCall { + if x != nil { + return x.Function + } + return nil +} + +// FunctionCall represents a function call within a tool call. +type FunctionCall struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Arguments string `protobuf:"bytes,2,opt,name=arguments,proto3" json:"arguments,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FunctionCall) Reset() { + *x = FunctionCall{} + mi := &file_cagent_v1_cagent_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FunctionCall) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FunctionCall) ProtoMessage() {} + +func (x *FunctionCall) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 FunctionCall.ProtoReflect.Descriptor instead. +func (*FunctionCall) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{10} +} + +func (x *FunctionCall) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *FunctionCall) GetArguments() string { + if x != nil { + return x.Arguments + } + return "" +} + +// Session represents a full session with messages. +type Session struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + CreatedAt string `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Messages []*Message `protobuf:"bytes,4,rep,name=messages,proto3" json:"messages,omitempty"` + ToolsApproved bool `protobuf:"varint,5,opt,name=tools_approved,json=toolsApproved,proto3" json:"tools_approved,omitempty"` + InputTokens int64 `protobuf:"varint,6,opt,name=input_tokens,json=inputTokens,proto3" json:"input_tokens,omitempty"` + OutputTokens int64 `protobuf:"varint,7,opt,name=output_tokens,json=outputTokens,proto3" json:"output_tokens,omitempty"` + WorkingDir string `protobuf:"bytes,8,opt,name=working_dir,json=workingDir,proto3" json:"working_dir,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Session) Reset() { + *x = Session{} + mi := &file_cagent_v1_cagent_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Session) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Session) ProtoMessage() {} + +func (x *Session) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 Session.ProtoReflect.Descriptor instead. +func (*Session) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{11} +} + +func (x *Session) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Session) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *Session) GetCreatedAt() string { + if x != nil { + return x.CreatedAt + } + return "" +} + +func (x *Session) GetMessages() []*Message { + if x != nil { + return x.Messages + } + return nil +} + +func (x *Session) GetToolsApproved() bool { + if x != nil { + return x.ToolsApproved + } + return false +} + +func (x *Session) GetInputTokens() int64 { + if x != nil { + return x.InputTokens + } + return 0 +} + +func (x *Session) GetOutputTokens() int64 { + if x != nil { + return x.OutputTokens + } + return 0 +} + +func (x *Session) GetWorkingDir() string { + if x != nil { + return x.WorkingDir + } + return "" +} + +// GetSessionRequest is the request for GetSession. +type GetSessionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetSessionRequest) Reset() { + *x = GetSessionRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSessionRequest) ProtoMessage() {} + +func (x *GetSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 GetSessionRequest.ProtoReflect.Descriptor instead. +func (*GetSessionRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{12} +} + +func (x *GetSessionRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// GetSessionResponse is the response for GetSession. +type GetSessionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Session *Session `protobuf:"bytes,1,opt,name=session,proto3" json:"session,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetSessionResponse) Reset() { + *x = GetSessionResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSessionResponse) ProtoMessage() {} + +func (x *GetSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 GetSessionResponse.ProtoReflect.Descriptor instead. +func (*GetSessionResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{13} +} + +func (x *GetSessionResponse) GetSession() *Session { + if x != nil { + return x.Session + } + return nil +} + +// CreateSessionRequest is the request for CreateSession. +type CreateSessionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + MaxIterations int32 `protobuf:"varint,1,opt,name=max_iterations,json=maxIterations,proto3" json:"max_iterations,omitempty"` + ToolsApproved bool `protobuf:"varint,2,opt,name=tools_approved,json=toolsApproved,proto3" json:"tools_approved,omitempty"` + WorkingDir string `protobuf:"bytes,3,opt,name=working_dir,json=workingDir,proto3" json:"working_dir,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateSessionRequest) Reset() { + *x = CreateSessionRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSessionRequest) ProtoMessage() {} + +func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_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 CreateSessionRequest.ProtoReflect.Descriptor instead. +func (*CreateSessionRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{14} +} + +func (x *CreateSessionRequest) GetMaxIterations() int32 { + if x != nil { + return x.MaxIterations + } + return 0 +} + +func (x *CreateSessionRequest) GetToolsApproved() bool { + if x != nil { + return x.ToolsApproved + } + return false +} + +func (x *CreateSessionRequest) GetWorkingDir() string { + if x != nil { + return x.WorkingDir + } + return "" +} + +// CreateSessionResponse is the response for CreateSession. +type CreateSessionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Session *Session `protobuf:"bytes,1,opt,name=session,proto3" json:"session,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateSessionResponse) Reset() { + *x = CreateSessionResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSessionResponse) ProtoMessage() {} + +func (x *CreateSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[15] + 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 CreateSessionResponse.ProtoReflect.Descriptor instead. +func (*CreateSessionResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{15} +} + +func (x *CreateSessionResponse) GetSession() *Session { + if x != nil { + return x.Session + } + return nil +} + +// DeleteSessionRequest is the request for DeleteSession. +type DeleteSessionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteSessionRequest) Reset() { + *x = DeleteSessionRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteSessionRequest) ProtoMessage() {} + +func (x *DeleteSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[16] + 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 DeleteSessionRequest.ProtoReflect.Descriptor instead. +func (*DeleteSessionRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{16} +} + +func (x *DeleteSessionRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// DeleteSessionResponse is the response for DeleteSession. +type DeleteSessionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteSessionResponse) Reset() { + *x = DeleteSessionResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteSessionResponse) ProtoMessage() {} + +func (x *DeleteSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[17] + 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 DeleteSessionResponse.ProtoReflect.Descriptor instead. +func (*DeleteSessionResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{17} +} + +// ResumeSessionRequest is the request for ResumeSession. +type ResumeSessionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Confirmation string `protobuf:"bytes,2,opt,name=confirmation,proto3" json:"confirmation,omitempty"` // "approve", "approve-session", or "reject" + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` // optional reason for rejection + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResumeSessionRequest) Reset() { + *x = ResumeSessionRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResumeSessionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResumeSessionRequest) ProtoMessage() {} + +func (x *ResumeSessionRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[18] + 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 ResumeSessionRequest.ProtoReflect.Descriptor instead. +func (*ResumeSessionRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{18} +} + +func (x *ResumeSessionRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ResumeSessionRequest) GetConfirmation() string { + if x != nil { + return x.Confirmation + } + return "" +} + +func (x *ResumeSessionRequest) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +// ResumeSessionResponse is the response for ResumeSession. +type ResumeSessionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResumeSessionResponse) Reset() { + *x = ResumeSessionResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResumeSessionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResumeSessionResponse) ProtoMessage() {} + +func (x *ResumeSessionResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[19] + 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 ResumeSessionResponse.ProtoReflect.Descriptor instead. +func (*ResumeSessionResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{19} +} + +// ToggleToolApprovalRequest is the request for ToggleToolApproval. +type ToggleToolApprovalRequest 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 *ToggleToolApprovalRequest) Reset() { + *x = ToggleToolApprovalRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToggleToolApprovalRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToggleToolApprovalRequest) ProtoMessage() {} + +func (x *ToggleToolApprovalRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[20] + 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 ToggleToolApprovalRequest.ProtoReflect.Descriptor instead. +func (*ToggleToolApprovalRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{20} +} + +func (x *ToggleToolApprovalRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +// ToggleToolApprovalResponse is the response for ToggleToolApproval. +type ToggleToolApprovalResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToggleToolApprovalResponse) Reset() { + *x = ToggleToolApprovalResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToggleToolApprovalResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToggleToolApprovalResponse) ProtoMessage() {} + +func (x *ToggleToolApprovalResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[21] + 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 ToggleToolApprovalResponse.ProtoReflect.Descriptor instead. +func (*ToggleToolApprovalResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{21} +} + +// UpdateSessionTitleRequest is the request for UpdateSessionTitle. +type UpdateSessionTitleRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateSessionTitleRequest) Reset() { + *x = UpdateSessionTitleRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateSessionTitleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSessionTitleRequest) ProtoMessage() {} + +func (x *UpdateSessionTitleRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[22] + 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 UpdateSessionTitleRequest.ProtoReflect.Descriptor instead. +func (*UpdateSessionTitleRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{22} +} + +func (x *UpdateSessionTitleRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *UpdateSessionTitleRequest) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +// UpdateSessionTitleResponse is the response for UpdateSessionTitle. +type UpdateSessionTitleResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateSessionTitleResponse) Reset() { + *x = UpdateSessionTitleResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateSessionTitleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSessionTitleResponse) ProtoMessage() {} + +func (x *UpdateSessionTitleResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[23] + 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 UpdateSessionTitleResponse.ProtoReflect.Descriptor instead. +func (*UpdateSessionTitleResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{23} +} + +func (x *UpdateSessionTitleResponse) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *UpdateSessionTitleResponse) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +// ResumeElicitationRequest is the request for ResumeElicitation. +type ResumeElicitationRequest 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"` // "accept", "decline", or "cancel" + ContentJson []byte `protobuf:"bytes,3,opt,name=content_json,json=contentJson,proto3" json:"content_json,omitempty"` // JSON-encoded map[string]any + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResumeElicitationRequest) Reset() { + *x = ResumeElicitationRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResumeElicitationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResumeElicitationRequest) ProtoMessage() {} + +func (x *ResumeElicitationRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[24] + 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 ResumeElicitationRequest.ProtoReflect.Descriptor instead. +func (*ResumeElicitationRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{24} +} + +func (x *ResumeElicitationRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *ResumeElicitationRequest) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *ResumeElicitationRequest) GetContentJson() []byte { + if x != nil { + return x.ContentJson + } + return nil +} + +// ResumeElicitationResponse is the response for ResumeElicitation. +type ResumeElicitationResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResumeElicitationResponse) Reset() { + *x = ResumeElicitationResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResumeElicitationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResumeElicitationResponse) ProtoMessage() {} + +func (x *ResumeElicitationResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[25] + 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 ResumeElicitationResponse.ProtoReflect.Descriptor instead. +func (*ResumeElicitationResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{25} +} + +// InputMessage is a message to send to the agent. +type InputMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` + Content string `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` + MultiContent []*MessagePart `protobuf:"bytes,3,rep,name=multi_content,json=multiContent,proto3" json:"multi_content,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InputMessage) Reset() { + *x = InputMessage{} + mi := &file_cagent_v1_cagent_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InputMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InputMessage) ProtoMessage() {} + +func (x *InputMessage) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[26] + 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 InputMessage.ProtoReflect.Descriptor instead. +func (*InputMessage) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{26} +} + +func (x *InputMessage) GetRole() string { + if x != nil { + return x.Role + } + return "" +} + +func (x *InputMessage) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *InputMessage) GetMultiContent() []*MessagePart { + if x != nil { + return x.MultiContent + } + return nil +} + +// MessagePart represents a part of a multi-content message. +type MessagePart struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // "text" or "image" + Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` + ImageUrl string `protobuf:"bytes,3,opt,name=image_url,json=imageUrl,proto3" json:"image_url,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MessagePart) Reset() { + *x = MessagePart{} + mi := &file_cagent_v1_cagent_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MessagePart) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessagePart) ProtoMessage() {} + +func (x *MessagePart) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[27] + 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 MessagePart.ProtoReflect.Descriptor instead. +func (*MessagePart) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{27} +} + +func (x *MessagePart) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *MessagePart) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *MessagePart) GetImageUrl() string { + if x != nil { + return x.ImageUrl + } + return "" +} + +// RunAgentRequest is the request for RunAgent. +type RunAgentRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Agent string `protobuf:"bytes,2,opt,name=agent,proto3" json:"agent,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` // Optional: specific agent name for multi-agent setups + Messages []*InputMessage `protobuf:"bytes,4,rep,name=messages,proto3" json:"messages,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RunAgentRequest) Reset() { + *x = RunAgentRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RunAgentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RunAgentRequest) ProtoMessage() {} + +func (x *RunAgentRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[28] + 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 RunAgentRequest.ProtoReflect.Descriptor instead. +func (*RunAgentRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{28} +} + +func (x *RunAgentRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *RunAgentRequest) GetAgent() string { + if x != nil { + return x.Agent + } + return "" +} + +func (x *RunAgentRequest) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +func (x *RunAgentRequest) GetMessages() []*InputMessage { + if x != nil { + return x.Messages + } + return nil +} + +// Event is a streaming event from the agent. +// Only one of the event types will be set. +type Event struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Event: + // + // *Event_UserMessage + // *Event_StreamStarted + // *Event_StreamStopped + // *Event_AgentChoice + // *Event_AgentChoiceReasoning + // *Event_PartialToolCall + // *Event_ToolCall + // *Event_ToolCallConfirmation + // *Event_ToolCallResponse + // *Event_Error + // *Event_Warning + // *Event_TokenUsage + // *Event_SessionTitle + // *Event_SessionSummary + // *Event_SessionCompaction + // *Event_ElicitationRequest + // *Event_Authorization + // *Event_MaxIterationsReached + // *Event_McpInitStarted + // *Event_McpInitFinished + // *Event_AgentInfo + // *Event_TeamInfo + // *Event_AgentSwitching + // *Event_ToolsetInfo + // *Event_RagIndexingStarted + // *Event_RagIndexingProgress + // *Event_RagIndexingCompleted + // *Event_HookBlocked + // *Event_ShellOutput + Event isEvent_Event `protobuf_oneof:"event"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Event) Reset() { + *x = Event{} + mi := &file_cagent_v1_cagent_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Event) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event) ProtoMessage() {} + +func (x *Event) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[29] + 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 Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{29} +} + +func (x *Event) GetEvent() isEvent_Event { + if x != nil { + return x.Event + } + return nil +} + +func (x *Event) GetUserMessage() *UserMessageEvent { + if x != nil { + if x, ok := x.Event.(*Event_UserMessage); ok { + return x.UserMessage + } + } + return nil +} + +func (x *Event) GetStreamStarted() *StreamStartedEvent { + if x != nil { + if x, ok := x.Event.(*Event_StreamStarted); ok { + return x.StreamStarted + } + } + return nil +} + +func (x *Event) GetStreamStopped() *StreamStoppedEvent { + if x != nil { + if x, ok := x.Event.(*Event_StreamStopped); ok { + return x.StreamStopped + } + } + return nil +} + +func (x *Event) GetAgentChoice() *AgentChoiceEvent { + if x != nil { + if x, ok := x.Event.(*Event_AgentChoice); ok { + return x.AgentChoice + } + } + return nil +} + +func (x *Event) GetAgentChoiceReasoning() *AgentChoiceReasoningEvent { + if x != nil { + if x, ok := x.Event.(*Event_AgentChoiceReasoning); ok { + return x.AgentChoiceReasoning + } + } + return nil +} + +func (x *Event) GetPartialToolCall() *PartialToolCallEvent { + if x != nil { + if x, ok := x.Event.(*Event_PartialToolCall); ok { + return x.PartialToolCall + } + } + return nil +} + +func (x *Event) GetToolCall() *ToolCallEvent { + if x != nil { + if x, ok := x.Event.(*Event_ToolCall); ok { + return x.ToolCall + } + } + return nil +} + +func (x *Event) GetToolCallConfirmation() *ToolCallConfirmationEvent { + if x != nil { + if x, ok := x.Event.(*Event_ToolCallConfirmation); ok { + return x.ToolCallConfirmation + } + } + return nil +} + +func (x *Event) GetToolCallResponse() *ToolCallResponseEvent { + if x != nil { + if x, ok := x.Event.(*Event_ToolCallResponse); ok { + return x.ToolCallResponse + } + } + return nil +} + +func (x *Event) GetError() *ErrorEvent { + if x != nil { + if x, ok := x.Event.(*Event_Error); ok { + return x.Error + } + } + return nil +} + +func (x *Event) GetWarning() *WarningEvent { + if x != nil { + if x, ok := x.Event.(*Event_Warning); ok { + return x.Warning + } + } + return nil +} + +func (x *Event) GetTokenUsage() *TokenUsageEvent { + if x != nil { + if x, ok := x.Event.(*Event_TokenUsage); ok { + return x.TokenUsage + } + } + return nil +} + +func (x *Event) GetSessionTitle() *SessionTitleEvent { + if x != nil { + if x, ok := x.Event.(*Event_SessionTitle); ok { + return x.SessionTitle + } + } + return nil +} + +func (x *Event) GetSessionSummary() *SessionSummaryEvent { + if x != nil { + if x, ok := x.Event.(*Event_SessionSummary); ok { + return x.SessionSummary + } + } + return nil +} + +func (x *Event) GetSessionCompaction() *SessionCompactionEvent { + if x != nil { + if x, ok := x.Event.(*Event_SessionCompaction); ok { + return x.SessionCompaction + } + } + return nil +} + +func (x *Event) GetElicitationRequest() *ElicitationRequestEvent { + if x != nil { + if x, ok := x.Event.(*Event_ElicitationRequest); ok { + return x.ElicitationRequest + } + } + return nil +} + +func (x *Event) GetAuthorization() *AuthorizationEvent { + if x != nil { + if x, ok := x.Event.(*Event_Authorization); ok { + return x.Authorization + } + } + return nil +} + +func (x *Event) GetMaxIterationsReached() *MaxIterationsReachedEvent { + if x != nil { + if x, ok := x.Event.(*Event_MaxIterationsReached); ok { + return x.MaxIterationsReached + } + } + return nil +} + +func (x *Event) GetMcpInitStarted() *MCPInitStartedEvent { + if x != nil { + if x, ok := x.Event.(*Event_McpInitStarted); ok { + return x.McpInitStarted + } + } + return nil +} + +func (x *Event) GetMcpInitFinished() *MCPInitFinishedEvent { + if x != nil { + if x, ok := x.Event.(*Event_McpInitFinished); ok { + return x.McpInitFinished + } + } + return nil +} + +func (x *Event) GetAgentInfo() *AgentInfoEvent { + if x != nil { + if x, ok := x.Event.(*Event_AgentInfo); ok { + return x.AgentInfo + } + } + return nil +} + +func (x *Event) GetTeamInfo() *TeamInfoEvent { + if x != nil { + if x, ok := x.Event.(*Event_TeamInfo); ok { + return x.TeamInfo + } + } + return nil +} + +func (x *Event) GetAgentSwitching() *AgentSwitchingEvent { + if x != nil { + if x, ok := x.Event.(*Event_AgentSwitching); ok { + return x.AgentSwitching + } + } + return nil +} + +func (x *Event) GetToolsetInfo() *ToolsetInfoEvent { + if x != nil { + if x, ok := x.Event.(*Event_ToolsetInfo); ok { + return x.ToolsetInfo + } + } + return nil +} + +func (x *Event) GetRagIndexingStarted() *RAGIndexingStartedEvent { + if x != nil { + if x, ok := x.Event.(*Event_RagIndexingStarted); ok { + return x.RagIndexingStarted + } + } + return nil +} + +func (x *Event) GetRagIndexingProgress() *RAGIndexingProgressEvent { + if x != nil { + if x, ok := x.Event.(*Event_RagIndexingProgress); ok { + return x.RagIndexingProgress + } + } + return nil +} + +func (x *Event) GetRagIndexingCompleted() *RAGIndexingCompletedEvent { + if x != nil { + if x, ok := x.Event.(*Event_RagIndexingCompleted); ok { + return x.RagIndexingCompleted + } + } + return nil +} + +func (x *Event) GetHookBlocked() *HookBlockedEvent { + if x != nil { + if x, ok := x.Event.(*Event_HookBlocked); ok { + return x.HookBlocked + } + } + return nil +} + +func (x *Event) GetShellOutput() *ShellOutputEvent { + if x != nil { + if x, ok := x.Event.(*Event_ShellOutput); ok { + return x.ShellOutput + } + } + return nil +} + +type isEvent_Event interface { + isEvent_Event() +} + +type Event_UserMessage struct { + UserMessage *UserMessageEvent `protobuf:"bytes,1,opt,name=user_message,json=userMessage,proto3,oneof"` +} + +type Event_StreamStarted struct { + StreamStarted *StreamStartedEvent `protobuf:"bytes,2,opt,name=stream_started,json=streamStarted,proto3,oneof"` +} + +type Event_StreamStopped struct { + StreamStopped *StreamStoppedEvent `protobuf:"bytes,3,opt,name=stream_stopped,json=streamStopped,proto3,oneof"` +} + +type Event_AgentChoice struct { + AgentChoice *AgentChoiceEvent `protobuf:"bytes,4,opt,name=agent_choice,json=agentChoice,proto3,oneof"` +} + +type Event_AgentChoiceReasoning struct { + AgentChoiceReasoning *AgentChoiceReasoningEvent `protobuf:"bytes,5,opt,name=agent_choice_reasoning,json=agentChoiceReasoning,proto3,oneof"` +} + +type Event_PartialToolCall struct { + PartialToolCall *PartialToolCallEvent `protobuf:"bytes,6,opt,name=partial_tool_call,json=partialToolCall,proto3,oneof"` +} + +type Event_ToolCall struct { + ToolCall *ToolCallEvent `protobuf:"bytes,7,opt,name=tool_call,json=toolCall,proto3,oneof"` +} + +type Event_ToolCallConfirmation struct { + ToolCallConfirmation *ToolCallConfirmationEvent `protobuf:"bytes,8,opt,name=tool_call_confirmation,json=toolCallConfirmation,proto3,oneof"` +} + +type Event_ToolCallResponse struct { + ToolCallResponse *ToolCallResponseEvent `protobuf:"bytes,9,opt,name=tool_call_response,json=toolCallResponse,proto3,oneof"` +} + +type Event_Error struct { + Error *ErrorEvent `protobuf:"bytes,10,opt,name=error,proto3,oneof"` +} + +type Event_Warning struct { + Warning *WarningEvent `protobuf:"bytes,11,opt,name=warning,proto3,oneof"` +} + +type Event_TokenUsage struct { + TokenUsage *TokenUsageEvent `protobuf:"bytes,12,opt,name=token_usage,json=tokenUsage,proto3,oneof"` +} + +type Event_SessionTitle struct { + SessionTitle *SessionTitleEvent `protobuf:"bytes,13,opt,name=session_title,json=sessionTitle,proto3,oneof"` +} + +type Event_SessionSummary struct { + SessionSummary *SessionSummaryEvent `protobuf:"bytes,14,opt,name=session_summary,json=sessionSummary,proto3,oneof"` +} + +type Event_SessionCompaction struct { + SessionCompaction *SessionCompactionEvent `protobuf:"bytes,15,opt,name=session_compaction,json=sessionCompaction,proto3,oneof"` +} + +type Event_ElicitationRequest struct { + ElicitationRequest *ElicitationRequestEvent `protobuf:"bytes,16,opt,name=elicitation_request,json=elicitationRequest,proto3,oneof"` +} + +type Event_Authorization struct { + Authorization *AuthorizationEvent `protobuf:"bytes,17,opt,name=authorization,proto3,oneof"` +} + +type Event_MaxIterationsReached struct { + MaxIterationsReached *MaxIterationsReachedEvent `protobuf:"bytes,18,opt,name=max_iterations_reached,json=maxIterationsReached,proto3,oneof"` +} + +type Event_McpInitStarted struct { + McpInitStarted *MCPInitStartedEvent `protobuf:"bytes,19,opt,name=mcp_init_started,json=mcpInitStarted,proto3,oneof"` +} + +type Event_McpInitFinished struct { + McpInitFinished *MCPInitFinishedEvent `protobuf:"bytes,20,opt,name=mcp_init_finished,json=mcpInitFinished,proto3,oneof"` +} + +type Event_AgentInfo struct { + AgentInfo *AgentInfoEvent `protobuf:"bytes,21,opt,name=agent_info,json=agentInfo,proto3,oneof"` +} + +type Event_TeamInfo struct { + TeamInfo *TeamInfoEvent `protobuf:"bytes,22,opt,name=team_info,json=teamInfo,proto3,oneof"` +} + +type Event_AgentSwitching struct { + AgentSwitching *AgentSwitchingEvent `protobuf:"bytes,23,opt,name=agent_switching,json=agentSwitching,proto3,oneof"` +} + +type Event_ToolsetInfo struct { + ToolsetInfo *ToolsetInfoEvent `protobuf:"bytes,24,opt,name=toolset_info,json=toolsetInfo,proto3,oneof"` +} + +type Event_RagIndexingStarted struct { + RagIndexingStarted *RAGIndexingStartedEvent `protobuf:"bytes,25,opt,name=rag_indexing_started,json=ragIndexingStarted,proto3,oneof"` +} + +type Event_RagIndexingProgress struct { + RagIndexingProgress *RAGIndexingProgressEvent `protobuf:"bytes,26,opt,name=rag_indexing_progress,json=ragIndexingProgress,proto3,oneof"` +} + +type Event_RagIndexingCompleted struct { + RagIndexingCompleted *RAGIndexingCompletedEvent `protobuf:"bytes,27,opt,name=rag_indexing_completed,json=ragIndexingCompleted,proto3,oneof"` +} + +type Event_HookBlocked struct { + HookBlocked *HookBlockedEvent `protobuf:"bytes,28,opt,name=hook_blocked,json=hookBlocked,proto3,oneof"` +} + +type Event_ShellOutput struct { + ShellOutput *ShellOutputEvent `protobuf:"bytes,29,opt,name=shell_output,json=shellOutput,proto3,oneof"` +} + +func (*Event_UserMessage) isEvent_Event() {} + +func (*Event_StreamStarted) isEvent_Event() {} + +func (*Event_StreamStopped) isEvent_Event() {} + +func (*Event_AgentChoice) isEvent_Event() {} + +func (*Event_AgentChoiceReasoning) isEvent_Event() {} + +func (*Event_PartialToolCall) isEvent_Event() {} + +func (*Event_ToolCall) isEvent_Event() {} + +func (*Event_ToolCallConfirmation) isEvent_Event() {} + +func (*Event_ToolCallResponse) isEvent_Event() {} + +func (*Event_Error) isEvent_Event() {} + +func (*Event_Warning) isEvent_Event() {} + +func (*Event_TokenUsage) isEvent_Event() {} + +func (*Event_SessionTitle) isEvent_Event() {} + +func (*Event_SessionSummary) isEvent_Event() {} + +func (*Event_SessionCompaction) isEvent_Event() {} + +func (*Event_ElicitationRequest) isEvent_Event() {} + +func (*Event_Authorization) isEvent_Event() {} + +func (*Event_MaxIterationsReached) isEvent_Event() {} + +func (*Event_McpInitStarted) isEvent_Event() {} + +func (*Event_McpInitFinished) isEvent_Event() {} + +func (*Event_AgentInfo) isEvent_Event() {} + +func (*Event_TeamInfo) isEvent_Event() {} + +func (*Event_AgentSwitching) isEvent_Event() {} + +func (*Event_ToolsetInfo) isEvent_Event() {} + +func (*Event_RagIndexingStarted) isEvent_Event() {} + +func (*Event_RagIndexingProgress) isEvent_Event() {} + +func (*Event_RagIndexingCompleted) isEvent_Event() {} + +func (*Event_HookBlocked) isEvent_Event() {} + +func (*Event_ShellOutput) isEvent_Event() {} + +// Tool represents a tool definition. +type Tool struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Category string `protobuf:"bytes,2,opt,name=category,proto3" json:"category,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + ParametersJson []byte `protobuf:"bytes,4,opt,name=parameters_json,json=parametersJson,proto3" json:"parameters_json,omitempty"` // JSON-encoded parameters schema + Annotations *ToolAnnotations `protobuf:"bytes,5,opt,name=annotations,proto3" json:"annotations,omitempty"` + OutputSchemaJson []byte `protobuf:"bytes,6,opt,name=output_schema_json,json=outputSchemaJson,proto3" json:"output_schema_json,omitempty"` // JSON-encoded output schema + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Tool) Reset() { + *x = Tool{} + mi := &file_cagent_v1_cagent_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Tool) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Tool) ProtoMessage() {} + +func (x *Tool) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[30] + 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 Tool.ProtoReflect.Descriptor instead. +func (*Tool) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{30} +} + +func (x *Tool) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Tool) GetCategory() string { + if x != nil { + return x.Category + } + return "" +} + +func (x *Tool) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Tool) GetParametersJson() []byte { + if x != nil { + return x.ParametersJson + } + return nil +} + +func (x *Tool) GetAnnotations() *ToolAnnotations { + if x != nil { + return x.Annotations + } + return nil +} + +func (x *Tool) GetOutputSchemaJson() []byte { + if x != nil { + return x.OutputSchemaJson + } + return nil +} + +// ToolAnnotations represents tool annotations. +type ToolAnnotations struct { + state protoimpl.MessageState `protogen:"open.v1"` + ReadOnlyHint bool `protobuf:"varint,1,opt,name=read_only_hint,json=readOnlyHint,proto3" json:"read_only_hint,omitempty"` + DestructiveHint bool `protobuf:"varint,2,opt,name=destructive_hint,json=destructiveHint,proto3" json:"destructive_hint,omitempty"` + IdempotentHint bool `protobuf:"varint,3,opt,name=idempotent_hint,json=idempotentHint,proto3" json:"idempotent_hint,omitempty"` + OpenWorldHint bool `protobuf:"varint,4,opt,name=open_world_hint,json=openWorldHint,proto3" json:"open_world_hint,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolAnnotations) Reset() { + *x = ToolAnnotations{} + mi := &file_cagent_v1_cagent_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolAnnotations) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolAnnotations) ProtoMessage() {} + +func (x *ToolAnnotations) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[31] + 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 ToolAnnotations.ProtoReflect.Descriptor instead. +func (*ToolAnnotations) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{31} +} + +func (x *ToolAnnotations) GetReadOnlyHint() bool { + if x != nil { + return x.ReadOnlyHint + } + return false +} + +func (x *ToolAnnotations) GetDestructiveHint() bool { + if x != nil { + return x.DestructiveHint + } + return false +} + +func (x *ToolAnnotations) GetIdempotentHint() bool { + if x != nil { + return x.IdempotentHint + } + return false +} + +func (x *ToolAnnotations) GetOpenWorldHint() bool { + if x != nil { + return x.OpenWorldHint + } + return false +} + +// ToolCallResult represents the result of a tool call. +type ToolCallResult struct { + state protoimpl.MessageState `protogen:"open.v1"` + Output string `protobuf:"bytes,1,opt,name=output,proto3" json:"output,omitempty"` + IsError bool `protobuf:"varint,2,opt,name=is_error,json=isError,proto3" json:"is_error,omitempty"` + MetaJson []byte `protobuf:"bytes,3,opt,name=meta_json,json=metaJson,proto3" json:"meta_json,omitempty"` // JSON-encoded metadata + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolCallResult) Reset() { + *x = ToolCallResult{} + mi := &file_cagent_v1_cagent_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolCallResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolCallResult) ProtoMessage() {} + +func (x *ToolCallResult) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[32] + 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 ToolCallResult.ProtoReflect.Descriptor instead. +func (*ToolCallResult) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{32} +} + +func (x *ToolCallResult) GetOutput() string { + if x != nil { + return x.Output + } + return "" +} + +func (x *ToolCallResult) GetIsError() bool { + if x != nil { + return x.IsError + } + return false +} + +func (x *ToolCallResult) GetMetaJson() []byte { + if x != nil { + return x.MetaJson + } + return nil +} + +// UserMessageEvent is sent when a user message is received. +type UserMessageEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserMessageEvent) Reset() { + *x = UserMessageEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserMessageEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserMessageEvent) ProtoMessage() {} + +func (x *UserMessageEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[33] + 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 UserMessageEvent.ProtoReflect.Descriptor instead. +func (*UserMessageEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{33} +} + +func (x *UserMessageEvent) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +// StreamStartedEvent is sent when the stream starts. +type StreamStartedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamStartedEvent) Reset() { + *x = StreamStartedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamStartedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamStartedEvent) ProtoMessage() {} + +func (x *StreamStartedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[34] + 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 StreamStartedEvent.ProtoReflect.Descriptor instead. +func (*StreamStartedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{34} +} + +func (x *StreamStartedEvent) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *StreamStartedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// StreamStoppedEvent is sent when the stream stops. +type StreamStoppedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StreamStoppedEvent) Reset() { + *x = StreamStoppedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StreamStoppedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamStoppedEvent) ProtoMessage() {} + +func (x *StreamStoppedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[35] + 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 StreamStoppedEvent.ProtoReflect.Descriptor instead. +func (*StreamStoppedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{35} +} + +func (x *StreamStoppedEvent) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *StreamStoppedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// AgentChoiceEvent is sent when the agent produces content. +type AgentChoiceEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentChoiceEvent) Reset() { + *x = AgentChoiceEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentChoiceEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentChoiceEvent) ProtoMessage() {} + +func (x *AgentChoiceEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[36] + 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 AgentChoiceEvent.ProtoReflect.Descriptor instead. +func (*AgentChoiceEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{36} +} + +func (x *AgentChoiceEvent) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *AgentChoiceEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// AgentChoiceReasoningEvent is sent when the agent produces reasoning content. +type AgentChoiceReasoningEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentChoiceReasoningEvent) Reset() { + *x = AgentChoiceReasoningEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentChoiceReasoningEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentChoiceReasoningEvent) ProtoMessage() {} + +func (x *AgentChoiceReasoningEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[37] + 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 AgentChoiceReasoningEvent.ProtoReflect.Descriptor instead. +func (*AgentChoiceReasoningEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{37} +} + +func (x *AgentChoiceReasoningEvent) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + +func (x *AgentChoiceReasoningEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// PartialToolCallEvent is sent when a tool call is first received (partial). +type PartialToolCallEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + ToolCall *ToolCall `protobuf:"bytes,1,opt,name=tool_call,json=toolCall,proto3" json:"tool_call,omitempty"` + ToolDefinition *Tool `protobuf:"bytes,2,opt,name=tool_definition,json=toolDefinition,proto3" json:"tool_definition,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PartialToolCallEvent) Reset() { + *x = PartialToolCallEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PartialToolCallEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PartialToolCallEvent) ProtoMessage() {} + +func (x *PartialToolCallEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[38] + 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 PartialToolCallEvent.ProtoReflect.Descriptor instead. +func (*PartialToolCallEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{38} +} + +func (x *PartialToolCallEvent) GetToolCall() *ToolCall { + if x != nil { + return x.ToolCall + } + return nil +} + +func (x *PartialToolCallEvent) GetToolDefinition() *Tool { + if x != nil { + return x.ToolDefinition + } + return nil +} + +func (x *PartialToolCallEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ToolCallEvent is sent when a complete tool call is received. +type ToolCallEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + ToolCall *ToolCall `protobuf:"bytes,1,opt,name=tool_call,json=toolCall,proto3" json:"tool_call,omitempty"` + ToolDefinition *Tool `protobuf:"bytes,2,opt,name=tool_definition,json=toolDefinition,proto3" json:"tool_definition,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolCallEvent) Reset() { + *x = ToolCallEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolCallEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolCallEvent) ProtoMessage() {} + +func (x *ToolCallEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[39] + 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 ToolCallEvent.ProtoReflect.Descriptor instead. +func (*ToolCallEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{39} +} + +func (x *ToolCallEvent) GetToolCall() *ToolCall { + if x != nil { + return x.ToolCall + } + return nil +} + +func (x *ToolCallEvent) GetToolDefinition() *Tool { + if x != nil { + return x.ToolDefinition + } + return nil +} + +func (x *ToolCallEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ToolCallConfirmationEvent is sent when a tool call needs confirmation. +type ToolCallConfirmationEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + ToolCall *ToolCall `protobuf:"bytes,1,opt,name=tool_call,json=toolCall,proto3" json:"tool_call,omitempty"` + ToolDefinition *Tool `protobuf:"bytes,2,opt,name=tool_definition,json=toolDefinition,proto3" json:"tool_definition,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolCallConfirmationEvent) Reset() { + *x = ToolCallConfirmationEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolCallConfirmationEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolCallConfirmationEvent) ProtoMessage() {} + +func (x *ToolCallConfirmationEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[40] + 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 ToolCallConfirmationEvent.ProtoReflect.Descriptor instead. +func (*ToolCallConfirmationEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{40} +} + +func (x *ToolCallConfirmationEvent) GetToolCall() *ToolCall { + if x != nil { + return x.ToolCall + } + return nil +} + +func (x *ToolCallConfirmationEvent) GetToolDefinition() *Tool { + if x != nil { + return x.ToolDefinition + } + return nil +} + +func (x *ToolCallConfirmationEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ToolCallResponseEvent is sent when a tool call completes. +type ToolCallResponseEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + ToolCall *ToolCall `protobuf:"bytes,1,opt,name=tool_call,json=toolCall,proto3" json:"tool_call,omitempty"` + ToolDefinition *Tool `protobuf:"bytes,2,opt,name=tool_definition,json=toolDefinition,proto3" json:"tool_definition,omitempty"` + Response string `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` + Result *ToolCallResult `protobuf:"bytes,4,opt,name=result,proto3" json:"result,omitempty"` + AgentName string `protobuf:"bytes,5,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolCallResponseEvent) Reset() { + *x = ToolCallResponseEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolCallResponseEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolCallResponseEvent) ProtoMessage() {} + +func (x *ToolCallResponseEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[41] + 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 ToolCallResponseEvent.ProtoReflect.Descriptor instead. +func (*ToolCallResponseEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{41} +} + +func (x *ToolCallResponseEvent) GetToolCall() *ToolCall { + if x != nil { + return x.ToolCall + } + return nil +} + +func (x *ToolCallResponseEvent) GetToolDefinition() *Tool { + if x != nil { + return x.ToolDefinition + } + return nil +} + +func (x *ToolCallResponseEvent) GetResponse() string { + if x != nil { + return x.Response + } + return "" +} + +func (x *ToolCallResponseEvent) GetResult() *ToolCallResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *ToolCallResponseEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ErrorEvent is sent when an error occurs. +type ErrorEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ErrorEvent) Reset() { + *x = ErrorEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ErrorEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ErrorEvent) ProtoMessage() {} + +func (x *ErrorEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[42] + 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 ErrorEvent.ProtoReflect.Descriptor instead. +func (*ErrorEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{42} +} + +func (x *ErrorEvent) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *ErrorEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// WarningEvent is sent for warnings. +type WarningEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *WarningEvent) Reset() { + *x = WarningEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *WarningEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WarningEvent) ProtoMessage() {} + +func (x *WarningEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[43] + 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 WarningEvent.ProtoReflect.Descriptor instead. +func (*WarningEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{43} +} + +func (x *WarningEvent) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *WarningEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// TokenUsageEvent is sent with token usage information. +type TokenUsageEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Usage *Usage `protobuf:"bytes,2,opt,name=usage,proto3" json:"usage,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TokenUsageEvent) Reset() { + *x = TokenUsageEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TokenUsageEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TokenUsageEvent) ProtoMessage() {} + +func (x *TokenUsageEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[44] + 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 TokenUsageEvent.ProtoReflect.Descriptor instead. +func (*TokenUsageEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{44} +} + +func (x *TokenUsageEvent) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *TokenUsageEvent) GetUsage() *Usage { + if x != nil { + return x.Usage + } + return nil +} + +func (x *TokenUsageEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// LastMessageUsage contains per-message usage data for the last message. +type LastMessageUsage struct { + state protoimpl.MessageState `protogen:"open.v1"` + InputTokens int64 `protobuf:"varint,1,opt,name=input_tokens,json=inputTokens,proto3" json:"input_tokens,omitempty"` + OutputTokens int64 `protobuf:"varint,2,opt,name=output_tokens,json=outputTokens,proto3" json:"output_tokens,omitempty"` + CachedInputTokens int64 `protobuf:"varint,3,opt,name=cached_input_tokens,json=cachedInputTokens,proto3" json:"cached_input_tokens,omitempty"` + CacheWriteTokens int64 `protobuf:"varint,4,opt,name=cache_write_tokens,json=cacheWriteTokens,proto3" json:"cache_write_tokens,omitempty"` + Cost float64 `protobuf:"fixed64,5,opt,name=cost,proto3" json:"cost,omitempty"` + Model string `protobuf:"bytes,6,opt,name=model,proto3" json:"model,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LastMessageUsage) Reset() { + *x = LastMessageUsage{} + mi := &file_cagent_v1_cagent_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LastMessageUsage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LastMessageUsage) ProtoMessage() {} + +func (x *LastMessageUsage) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[45] + 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 LastMessageUsage.ProtoReflect.Descriptor instead. +func (*LastMessageUsage) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{45} +} + +func (x *LastMessageUsage) GetInputTokens() int64 { + if x != nil { + return x.InputTokens + } + return 0 +} + +func (x *LastMessageUsage) GetOutputTokens() int64 { + if x != nil { + return x.OutputTokens + } + return 0 +} + +func (x *LastMessageUsage) GetCachedInputTokens() int64 { + if x != nil { + return x.CachedInputTokens + } + return 0 +} + +func (x *LastMessageUsage) GetCacheWriteTokens() int64 { + if x != nil { + return x.CacheWriteTokens + } + return 0 +} + +func (x *LastMessageUsage) GetCost() float64 { + if x != nil { + return x.Cost + } + return 0 +} + +func (x *LastMessageUsage) GetModel() string { + if x != nil { + return x.Model + } + return "" +} + +// Usage contains token usage details. +type Usage struct { + state protoimpl.MessageState `protogen:"open.v1"` + InputTokens int64 `protobuf:"varint,1,opt,name=input_tokens,json=inputTokens,proto3" json:"input_tokens,omitempty"` + OutputTokens int64 `protobuf:"varint,2,opt,name=output_tokens,json=outputTokens,proto3" json:"output_tokens,omitempty"` + ContextLength int64 `protobuf:"varint,3,opt,name=context_length,json=contextLength,proto3" json:"context_length,omitempty"` + ContextLimit int64 `protobuf:"varint,4,opt,name=context_limit,json=contextLimit,proto3" json:"context_limit,omitempty"` + Cost float64 `protobuf:"fixed64,5,opt,name=cost,proto3" json:"cost,omitempty"` + LastMessage *LastMessageUsage `protobuf:"bytes,6,opt,name=last_message,json=lastMessage,proto3" json:"last_message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Usage) Reset() { + *x = Usage{} + mi := &file_cagent_v1_cagent_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Usage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Usage) ProtoMessage() {} + +func (x *Usage) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[46] + 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 Usage.ProtoReflect.Descriptor instead. +func (*Usage) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{46} +} + +func (x *Usage) GetInputTokens() int64 { + if x != nil { + return x.InputTokens + } + return 0 +} + +func (x *Usage) GetOutputTokens() int64 { + if x != nil { + return x.OutputTokens + } + return 0 +} + +func (x *Usage) GetContextLength() int64 { + if x != nil { + return x.ContextLength + } + return 0 +} + +func (x *Usage) GetContextLimit() int64 { + if x != nil { + return x.ContextLimit + } + return 0 +} + +func (x *Usage) GetCost() float64 { + if x != nil { + return x.Cost + } + return 0 +} + +func (x *Usage) GetLastMessage() *LastMessageUsage { + if x != nil { + return x.LastMessage + } + return nil +} + +// SessionTitleEvent is sent when the session title is generated. +type SessionTitleEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SessionTitleEvent) Reset() { + *x = SessionTitleEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionTitleEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionTitleEvent) ProtoMessage() {} + +func (x *SessionTitleEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[47] + 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 SessionTitleEvent.ProtoReflect.Descriptor instead. +func (*SessionTitleEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{47} +} + +func (x *SessionTitleEvent) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *SessionTitleEvent) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *SessionTitleEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// SessionSummaryEvent is sent when a session summary is generated. +type SessionSummaryEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SessionSummaryEvent) Reset() { + *x = SessionSummaryEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionSummaryEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionSummaryEvent) ProtoMessage() {} + +func (x *SessionSummaryEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[48] + 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 SessionSummaryEvent.ProtoReflect.Descriptor instead. +func (*SessionSummaryEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{48} +} + +func (x *SessionSummaryEvent) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *SessionSummaryEvent) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *SessionSummaryEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// SessionCompactionEvent is sent during session compaction. +type SessionCompactionEvent 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"` // "started" or "completed" + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SessionCompactionEvent) Reset() { + *x = SessionCompactionEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionCompactionEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionCompactionEvent) ProtoMessage() {} + +func (x *SessionCompactionEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[49] + 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 SessionCompactionEvent.ProtoReflect.Descriptor instead. +func (*SessionCompactionEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{49} +} + +func (x *SessionCompactionEvent) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *SessionCompactionEvent) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *SessionCompactionEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ElicitationRequestEvent is sent when an elicitation request is received. +type ElicitationRequestEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + SchemaJson []byte `protobuf:"bytes,2,opt,name=schema_json,json=schemaJson,proto3" json:"schema_json,omitempty"` // JSON-encoded schema + MetaJson []byte `protobuf:"bytes,3,opt,name=meta_json,json=metaJson,proto3" json:"meta_json,omitempty"` // JSON-encoded metadata + AgentName string `protobuf:"bytes,4,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ElicitationRequestEvent) Reset() { + *x = ElicitationRequestEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ElicitationRequestEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ElicitationRequestEvent) ProtoMessage() {} + +func (x *ElicitationRequestEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[50] + 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 ElicitationRequestEvent.ProtoReflect.Descriptor instead. +func (*ElicitationRequestEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{50} +} + +func (x *ElicitationRequestEvent) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ElicitationRequestEvent) GetSchemaJson() []byte { + if x != nil { + return x.SchemaJson + } + return nil +} + +func (x *ElicitationRequestEvent) GetMetaJson() []byte { + if x != nil { + return x.MetaJson + } + return nil +} + +func (x *ElicitationRequestEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// AuthorizationEvent is sent for authorization events. +type AuthorizationEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Confirmation string `protobuf:"bytes,1,opt,name=confirmation,proto3" json:"confirmation,omitempty"` // "accept", "decline", or "cancel" + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AuthorizationEvent) Reset() { + *x = AuthorizationEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AuthorizationEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AuthorizationEvent) ProtoMessage() {} + +func (x *AuthorizationEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[51] + 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 AuthorizationEvent.ProtoReflect.Descriptor instead. +func (*AuthorizationEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{51} +} + +func (x *AuthorizationEvent) GetConfirmation() string { + if x != nil { + return x.Confirmation + } + return "" +} + +func (x *AuthorizationEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// MaxIterationsReachedEvent is sent when max iterations is reached. +type MaxIterationsReachedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + MaxIterations int32 `protobuf:"varint,1,opt,name=max_iterations,json=maxIterations,proto3" json:"max_iterations,omitempty"` + AgentName string `protobuf:"bytes,2,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MaxIterationsReachedEvent) Reset() { + *x = MaxIterationsReachedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MaxIterationsReachedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MaxIterationsReachedEvent) ProtoMessage() {} + +func (x *MaxIterationsReachedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[52] + 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 MaxIterationsReachedEvent.ProtoReflect.Descriptor instead. +func (*MaxIterationsReachedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{52} +} + +func (x *MaxIterationsReachedEvent) GetMaxIterations() int32 { + if x != nil { + return x.MaxIterations + } + return 0 +} + +func (x *MaxIterationsReachedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// MCPInitStartedEvent is sent when MCP initialization starts. +type MCPInitStartedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + AgentName string `protobuf:"bytes,1,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MCPInitStartedEvent) Reset() { + *x = MCPInitStartedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MCPInitStartedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MCPInitStartedEvent) ProtoMessage() {} + +func (x *MCPInitStartedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[53] + 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 MCPInitStartedEvent.ProtoReflect.Descriptor instead. +func (*MCPInitStartedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{53} +} + +func (x *MCPInitStartedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// MCPInitFinishedEvent is sent when MCP initialization finishes. +type MCPInitFinishedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + AgentName string `protobuf:"bytes,1,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MCPInitFinishedEvent) Reset() { + *x = MCPInitFinishedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MCPInitFinishedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MCPInitFinishedEvent) ProtoMessage() {} + +func (x *MCPInitFinishedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[54] + 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 MCPInitFinishedEvent.ProtoReflect.Descriptor instead. +func (*MCPInitFinishedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{54} +} + +func (x *MCPInitFinishedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// AgentInfoEvent is sent when agent information is available. +type AgentInfoEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + AgentName string `protobuf:"bytes,1,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + Model string `protobuf:"bytes,2,opt,name=model,proto3" json:"model,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + WelcomeMessage string `protobuf:"bytes,4,opt,name=welcome_message,json=welcomeMessage,proto3" json:"welcome_message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentInfoEvent) Reset() { + *x = AgentInfoEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentInfoEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentInfoEvent) ProtoMessage() {} + +func (x *AgentInfoEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[55] + 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 AgentInfoEvent.ProtoReflect.Descriptor instead. +func (*AgentInfoEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{55} +} + +func (x *AgentInfoEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +func (x *AgentInfoEvent) GetModel() string { + if x != nil { + return x.Model + } + return "" +} + +func (x *AgentInfoEvent) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *AgentInfoEvent) GetWelcomeMessage() string { + if x != nil { + return x.WelcomeMessage + } + return "" +} + +// AgentDetails contains information about an agent. +type AgentDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Provider string `protobuf:"bytes,3,opt,name=provider,proto3" json:"provider,omitempty"` + Model string `protobuf:"bytes,4,opt,name=model,proto3" json:"model,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentDetails) Reset() { + *x = AgentDetails{} + mi := &file_cagent_v1_cagent_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentDetails) ProtoMessage() {} + +func (x *AgentDetails) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[56] + 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 AgentDetails.ProtoReflect.Descriptor instead. +func (*AgentDetails) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{56} +} + +func (x *AgentDetails) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *AgentDetails) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *AgentDetails) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *AgentDetails) GetModel() string { + if x != nil { + return x.Model + } + return "" +} + +// TeamInfoEvent is sent when team information is available. +type TeamInfoEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + AvailableAgents []*AgentDetails `protobuf:"bytes,1,rep,name=available_agents,json=availableAgents,proto3" json:"available_agents,omitempty"` + CurrentAgent string `protobuf:"bytes,2,opt,name=current_agent,json=currentAgent,proto3" json:"current_agent,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TeamInfoEvent) Reset() { + *x = TeamInfoEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TeamInfoEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TeamInfoEvent) ProtoMessage() {} + +func (x *TeamInfoEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[57] + 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 TeamInfoEvent.ProtoReflect.Descriptor instead. +func (*TeamInfoEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{57} +} + +func (x *TeamInfoEvent) GetAvailableAgents() []*AgentDetails { + if x != nil { + return x.AvailableAgents + } + return nil +} + +func (x *TeamInfoEvent) GetCurrentAgent() string { + if x != nil { + return x.CurrentAgent + } + return "" +} + +func (x *TeamInfoEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// AgentSwitchingEvent is sent when agent switching occurs. +type AgentSwitchingEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Switching bool `protobuf:"varint,1,opt,name=switching,proto3" json:"switching,omitempty"` + FromAgent string `protobuf:"bytes,2,opt,name=from_agent,json=fromAgent,proto3" json:"from_agent,omitempty"` + ToAgent string `protobuf:"bytes,3,opt,name=to_agent,json=toAgent,proto3" json:"to_agent,omitempty"` + AgentName string `protobuf:"bytes,4,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentSwitchingEvent) Reset() { + *x = AgentSwitchingEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentSwitchingEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentSwitchingEvent) ProtoMessage() {} + +func (x *AgentSwitchingEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[58] + 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 AgentSwitchingEvent.ProtoReflect.Descriptor instead. +func (*AgentSwitchingEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{58} +} + +func (x *AgentSwitchingEvent) GetSwitching() bool { + if x != nil { + return x.Switching + } + return false +} + +func (x *AgentSwitchingEvent) GetFromAgent() string { + if x != nil { + return x.FromAgent + } + return "" +} + +func (x *AgentSwitchingEvent) GetToAgent() string { + if x != nil { + return x.ToAgent + } + return "" +} + +func (x *AgentSwitchingEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ToolsetInfoEvent is sent when toolset information is available. +type ToolsetInfoEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + AvailableTools int32 `protobuf:"varint,1,opt,name=available_tools,json=availableTools,proto3" json:"available_tools,omitempty"` + Loading bool `protobuf:"varint,2,opt,name=loading,proto3" json:"loading,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ToolsetInfoEvent) Reset() { + *x = ToolsetInfoEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ToolsetInfoEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToolsetInfoEvent) ProtoMessage() {} + +func (x *ToolsetInfoEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[59] + 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 ToolsetInfoEvent.ProtoReflect.Descriptor instead. +func (*ToolsetInfoEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{59} +} + +func (x *ToolsetInfoEvent) GetAvailableTools() int32 { + if x != nil { + return x.AvailableTools + } + return 0 +} + +func (x *ToolsetInfoEvent) GetLoading() bool { + if x != nil { + return x.Loading + } + return false +} + +func (x *ToolsetInfoEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// RAGIndexingStartedEvent is sent when RAG indexing starts. +type RAGIndexingStartedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + RagName string `protobuf:"bytes,1,opt,name=rag_name,json=ragName,proto3" json:"rag_name,omitempty"` + StrategyName string `protobuf:"bytes,2,opt,name=strategy_name,json=strategyName,proto3" json:"strategy_name,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RAGIndexingStartedEvent) Reset() { + *x = RAGIndexingStartedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RAGIndexingStartedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RAGIndexingStartedEvent) ProtoMessage() {} + +func (x *RAGIndexingStartedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[60] + 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 RAGIndexingStartedEvent.ProtoReflect.Descriptor instead. +func (*RAGIndexingStartedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{60} +} + +func (x *RAGIndexingStartedEvent) GetRagName() string { + if x != nil { + return x.RagName + } + return "" +} + +func (x *RAGIndexingStartedEvent) GetStrategyName() string { + if x != nil { + return x.StrategyName + } + return "" +} + +func (x *RAGIndexingStartedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// RAGIndexingProgressEvent is sent during RAG indexing progress. +type RAGIndexingProgressEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + RagName string `protobuf:"bytes,1,opt,name=rag_name,json=ragName,proto3" json:"rag_name,omitempty"` + StrategyName string `protobuf:"bytes,2,opt,name=strategy_name,json=strategyName,proto3" json:"strategy_name,omitempty"` + Current int32 `protobuf:"varint,3,opt,name=current,proto3" json:"current,omitempty"` + Total int32 `protobuf:"varint,4,opt,name=total,proto3" json:"total,omitempty"` + AgentName string `protobuf:"bytes,5,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RAGIndexingProgressEvent) Reset() { + *x = RAGIndexingProgressEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RAGIndexingProgressEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RAGIndexingProgressEvent) ProtoMessage() {} + +func (x *RAGIndexingProgressEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[61] + 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 RAGIndexingProgressEvent.ProtoReflect.Descriptor instead. +func (*RAGIndexingProgressEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{61} +} + +func (x *RAGIndexingProgressEvent) GetRagName() string { + if x != nil { + return x.RagName + } + return "" +} + +func (x *RAGIndexingProgressEvent) GetStrategyName() string { + if x != nil { + return x.StrategyName + } + return "" +} + +func (x *RAGIndexingProgressEvent) GetCurrent() int32 { + if x != nil { + return x.Current + } + return 0 +} + +func (x *RAGIndexingProgressEvent) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *RAGIndexingProgressEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// RAGIndexingCompletedEvent is sent when RAG indexing completes. +type RAGIndexingCompletedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + RagName string `protobuf:"bytes,1,opt,name=rag_name,json=ragName,proto3" json:"rag_name,omitempty"` + StrategyName string `protobuf:"bytes,2,opt,name=strategy_name,json=strategyName,proto3" json:"strategy_name,omitempty"` + AgentName string `protobuf:"bytes,3,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RAGIndexingCompletedEvent) Reset() { + *x = RAGIndexingCompletedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RAGIndexingCompletedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RAGIndexingCompletedEvent) ProtoMessage() {} + +func (x *RAGIndexingCompletedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[62] + 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 RAGIndexingCompletedEvent.ProtoReflect.Descriptor instead. +func (*RAGIndexingCompletedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{62} +} + +func (x *RAGIndexingCompletedEvent) GetRagName() string { + if x != nil { + return x.RagName + } + return "" +} + +func (x *RAGIndexingCompletedEvent) GetStrategyName() string { + if x != nil { + return x.StrategyName + } + return "" +} + +func (x *RAGIndexingCompletedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// HookBlockedEvent is sent when a pre-tool hook blocks a tool call. +type HookBlockedEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + ToolCall *ToolCall `protobuf:"bytes,1,opt,name=tool_call,json=toolCall,proto3" json:"tool_call,omitempty"` + ToolDefinition *Tool `protobuf:"bytes,2,opt,name=tool_definition,json=toolDefinition,proto3" json:"tool_definition,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + AgentName string `protobuf:"bytes,4,opt,name=agent_name,json=agentName,proto3" json:"agent_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *HookBlockedEvent) Reset() { + *x = HookBlockedEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HookBlockedEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HookBlockedEvent) ProtoMessage() {} + +func (x *HookBlockedEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[63] + 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 HookBlockedEvent.ProtoReflect.Descriptor instead. +func (*HookBlockedEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{63} +} + +func (x *HookBlockedEvent) GetToolCall() *ToolCall { + if x != nil { + return x.ToolCall + } + return nil +} + +func (x *HookBlockedEvent) GetToolDefinition() *Tool { + if x != nil { + return x.ToolDefinition + } + return nil +} + +func (x *HookBlockedEvent) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *HookBlockedEvent) GetAgentName() string { + if x != nil { + return x.AgentName + } + return "" +} + +// ShellOutputEvent is sent for shell output. +type ShellOutputEvent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Output string `protobuf:"bytes,1,opt,name=output,proto3" json:"output,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ShellOutputEvent) Reset() { + *x = ShellOutputEvent{} + mi := &file_cagent_v1_cagent_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ShellOutputEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShellOutputEvent) ProtoMessage() {} + +func (x *ShellOutputEvent) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[64] + 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 ShellOutputEvent.ProtoReflect.Descriptor instead. +func (*ShellOutputEvent) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{64} +} + +func (x *ShellOutputEvent) GetOutput() string { + if x != nil { + return x.Output + } + return "" +} + +// PingRequest is the request for Ping. +type PingRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PingRequest) Reset() { + *x = PingRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingRequest) ProtoMessage() {} + +func (x *PingRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[65] + 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 PingRequest.ProtoReflect.Descriptor instead. +func (*PingRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{65} +} + +// PingResponse is the response for Ping. +type PingResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PingResponse) Reset() { + *x = PingResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingResponse) ProtoMessage() {} + +func (x *PingResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[66] + 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 PingResponse.ProtoReflect.Descriptor instead. +func (*PingResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{66} +} + +func (x *PingResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +var File_cagent_v1_cagent_proto protoreflect.FileDescriptor + +const file_cagent_v1_cagent_proto_rawDesc = "" + + "\n" + + "\x16cagent/v1/cagent.proto\x12\tcagent.v1\"S\n" + + "\x05Agent\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" + + "\vdescription\x18\x02 \x01(\tR\vdescription\x12\x14\n" + + "\x05multi\x18\x03 \x01(\bR\x05multi\"\x13\n" + + "\x11ListAgentsRequest\">\n" + + "\x12ListAgentsResponse\x12(\n" + + "\x06agents\x18\x01 \x03(\v2\x10.cagent.v1.AgentR\x06agents\"!\n" + + "\x0fGetAgentRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"3\n" + + "\x10GetAgentResponse\x12\x1f\n" + + "\vconfig_json\x18\x01 \x01(\fR\n" + + "configJson\"\xe1\x01\n" + + "\x0eSessionSummary\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12\x1d\n" + + "\n" + + "created_at\x18\x03 \x01(\tR\tcreatedAt\x12!\n" + + "\fnum_messages\x18\x04 \x01(\x05R\vnumMessages\x12!\n" + + "\finput_tokens\x18\x05 \x01(\x03R\vinputTokens\x12#\n" + + "\routput_tokens\x18\x06 \x01(\x03R\foutputTokens\x12\x1f\n" + + "\vworking_dir\x18\a \x01(\tR\n" + + "workingDir\"\x15\n" + + "\x13ListSessionsRequest\"M\n" + + "\x14ListSessionsResponse\x125\n" + + "\bsessions\x18\x01 \x03(\v2\x19.cagent.v1.SessionSummaryR\bsessions\"\xf8\x01\n" + + "\aMessage\x12\x12\n" + + "\x04role\x18\x01 \x01(\tR\x04role\x12\x18\n" + + "\acontent\x18\x02 \x01(\tR\acontent\x12\x1d\n" + + "\n" + + "created_at\x18\x03 \x01(\tR\tcreatedAt\x12 \n" + + "\ftool_call_id\x18\x04 \x01(\tR\n" + + "toolCallId\x122\n" + + "\n" + + "tool_calls\x18\x05 \x03(\v2\x13.cagent.v1.ToolCallR\ttoolCalls\x12+\n" + + "\x11reasoning_content\x18\x06 \x01(\tR\x10reasoningContent\x12\x1d\n" + + "\n" + + "agent_name\x18\a \x01(\tR\tagentName\"c\n" + + "\bToolCall\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x123\n" + + "\bfunction\x18\x03 \x01(\v2\x17.cagent.v1.FunctionCallR\bfunction\"@\n" + + "\fFunctionCall\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" + + "\targuments\x18\x02 \x01(\tR\targuments\"\x8e\x02\n" + + "\aSession\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12\x1d\n" + + "\n" + + "created_at\x18\x03 \x01(\tR\tcreatedAt\x12.\n" + + "\bmessages\x18\x04 \x03(\v2\x12.cagent.v1.MessageR\bmessages\x12%\n" + + "\x0etools_approved\x18\x05 \x01(\bR\rtoolsApproved\x12!\n" + + "\finput_tokens\x18\x06 \x01(\x03R\vinputTokens\x12#\n" + + "\routput_tokens\x18\a \x01(\x03R\foutputTokens\x12\x1f\n" + + "\vworking_dir\x18\b \x01(\tR\n" + + "workingDir\"#\n" + + "\x11GetSessionRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"B\n" + + "\x12GetSessionResponse\x12,\n" + + "\asession\x18\x01 \x01(\v2\x12.cagent.v1.SessionR\asession\"\x85\x01\n" + + "\x14CreateSessionRequest\x12%\n" + + "\x0emax_iterations\x18\x01 \x01(\x05R\rmaxIterations\x12%\n" + + "\x0etools_approved\x18\x02 \x01(\bR\rtoolsApproved\x12\x1f\n" + + "\vworking_dir\x18\x03 \x01(\tR\n" + + "workingDir\"E\n" + + "\x15CreateSessionResponse\x12,\n" + + "\asession\x18\x01 \x01(\v2\x12.cagent.v1.SessionR\asession\"&\n" + + "\x14DeleteSessionRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\x17\n" + + "\x15DeleteSessionResponse\"b\n" + + "\x14ResumeSessionRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\"\n" + + "\fconfirmation\x18\x02 \x01(\tR\fconfirmation\x12\x16\n" + + "\x06reason\x18\x03 \x01(\tR\x06reason\"\x17\n" + + "\x15ResumeSessionResponse\":\n" + + "\x19ToggleToolApprovalRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\"\x1c\n" + + "\x1aToggleToolApprovalResponse\"P\n" + + "\x19UpdateSessionTitleRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\"Q\n" + + "\x1aUpdateSessionTitleResponse\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\"t\n" + + "\x18ResumeElicitationRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + + "\x06action\x18\x02 \x01(\tR\x06action\x12!\n" + + "\fcontent_json\x18\x03 \x01(\fR\vcontentJson\"\x1b\n" + + "\x19ResumeElicitationResponse\"y\n" + + "\fInputMessage\x12\x12\n" + + "\x04role\x18\x01 \x01(\tR\x04role\x12\x18\n" + + "\acontent\x18\x02 \x01(\tR\acontent\x12;\n" + + "\rmulti_content\x18\x03 \x03(\v2\x16.cagent.v1.MessagePartR\fmultiContent\"R\n" + + "\vMessagePart\x12\x12\n" + + "\x04type\x18\x01 \x01(\tR\x04type\x12\x12\n" + + "\x04text\x18\x02 \x01(\tR\x04text\x12\x1b\n" + + "\timage_url\x18\x03 \x01(\tR\bimageUrl\"\x9a\x01\n" + + "\x0fRunAgentRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x14\n" + + "\x05agent\x18\x02 \x01(\tR\x05agent\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\x123\n" + + "\bmessages\x18\x04 \x03(\v2\x17.cagent.v1.InputMessageR\bmessages\"\xef\x10\n" + + "\x05Event\x12@\n" + + "\fuser_message\x18\x01 \x01(\v2\x1b.cagent.v1.UserMessageEventH\x00R\vuserMessage\x12F\n" + + "\x0estream_started\x18\x02 \x01(\v2\x1d.cagent.v1.StreamStartedEventH\x00R\rstreamStarted\x12F\n" + + "\x0estream_stopped\x18\x03 \x01(\v2\x1d.cagent.v1.StreamStoppedEventH\x00R\rstreamStopped\x12@\n" + + "\fagent_choice\x18\x04 \x01(\v2\x1b.cagent.v1.AgentChoiceEventH\x00R\vagentChoice\x12\\\n" + + "\x16agent_choice_reasoning\x18\x05 \x01(\v2$.cagent.v1.AgentChoiceReasoningEventH\x00R\x14agentChoiceReasoning\x12M\n" + + "\x11partial_tool_call\x18\x06 \x01(\v2\x1f.cagent.v1.PartialToolCallEventH\x00R\x0fpartialToolCall\x127\n" + + "\ttool_call\x18\a \x01(\v2\x18.cagent.v1.ToolCallEventH\x00R\btoolCall\x12\\\n" + + "\x16tool_call_confirmation\x18\b \x01(\v2$.cagent.v1.ToolCallConfirmationEventH\x00R\x14toolCallConfirmation\x12P\n" + + "\x12tool_call_response\x18\t \x01(\v2 .cagent.v1.ToolCallResponseEventH\x00R\x10toolCallResponse\x12-\n" + + "\x05error\x18\n" + + " \x01(\v2\x15.cagent.v1.ErrorEventH\x00R\x05error\x123\n" + + "\awarning\x18\v \x01(\v2\x17.cagent.v1.WarningEventH\x00R\awarning\x12=\n" + + "\vtoken_usage\x18\f \x01(\v2\x1a.cagent.v1.TokenUsageEventH\x00R\n" + + "tokenUsage\x12C\n" + + "\rsession_title\x18\r \x01(\v2\x1c.cagent.v1.SessionTitleEventH\x00R\fsessionTitle\x12I\n" + + "\x0fsession_summary\x18\x0e \x01(\v2\x1e.cagent.v1.SessionSummaryEventH\x00R\x0esessionSummary\x12R\n" + + "\x12session_compaction\x18\x0f \x01(\v2!.cagent.v1.SessionCompactionEventH\x00R\x11sessionCompaction\x12U\n" + + "\x13elicitation_request\x18\x10 \x01(\v2\".cagent.v1.ElicitationRequestEventH\x00R\x12elicitationRequest\x12E\n" + + "\rauthorization\x18\x11 \x01(\v2\x1d.cagent.v1.AuthorizationEventH\x00R\rauthorization\x12\\\n" + + "\x16max_iterations_reached\x18\x12 \x01(\v2$.cagent.v1.MaxIterationsReachedEventH\x00R\x14maxIterationsReached\x12J\n" + + "\x10mcp_init_started\x18\x13 \x01(\v2\x1e.cagent.v1.MCPInitStartedEventH\x00R\x0emcpInitStarted\x12M\n" + + "\x11mcp_init_finished\x18\x14 \x01(\v2\x1f.cagent.v1.MCPInitFinishedEventH\x00R\x0fmcpInitFinished\x12:\n" + + "\n" + + "agent_info\x18\x15 \x01(\v2\x19.cagent.v1.AgentInfoEventH\x00R\tagentInfo\x127\n" + + "\tteam_info\x18\x16 \x01(\v2\x18.cagent.v1.TeamInfoEventH\x00R\bteamInfo\x12I\n" + + "\x0fagent_switching\x18\x17 \x01(\v2\x1e.cagent.v1.AgentSwitchingEventH\x00R\x0eagentSwitching\x12@\n" + + "\ftoolset_info\x18\x18 \x01(\v2\x1b.cagent.v1.ToolsetInfoEventH\x00R\vtoolsetInfo\x12V\n" + + "\x14rag_indexing_started\x18\x19 \x01(\v2\".cagent.v1.RAGIndexingStartedEventH\x00R\x12ragIndexingStarted\x12Y\n" + + "\x15rag_indexing_progress\x18\x1a \x01(\v2#.cagent.v1.RAGIndexingProgressEventH\x00R\x13ragIndexingProgress\x12\\\n" + + "\x16rag_indexing_completed\x18\x1b \x01(\v2$.cagent.v1.RAGIndexingCompletedEventH\x00R\x14ragIndexingCompleted\x12@\n" + + "\fhook_blocked\x18\x1c \x01(\v2\x1b.cagent.v1.HookBlockedEventH\x00R\vhookBlocked\x12@\n" + + "\fshell_output\x18\x1d \x01(\v2\x1b.cagent.v1.ShellOutputEventH\x00R\vshellOutputB\a\n" + + "\x05event\"\xed\x01\n" + + "\x04Tool\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1a\n" + + "\bcategory\x18\x02 \x01(\tR\bcategory\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12'\n" + + "\x0fparameters_json\x18\x04 \x01(\fR\x0eparametersJson\x12<\n" + + "\vannotations\x18\x05 \x01(\v2\x1a.cagent.v1.ToolAnnotationsR\vannotations\x12,\n" + + "\x12output_schema_json\x18\x06 \x01(\fR\x10outputSchemaJson\"\xb3\x01\n" + + "\x0fToolAnnotations\x12$\n" + + "\x0eread_only_hint\x18\x01 \x01(\bR\freadOnlyHint\x12)\n" + + "\x10destructive_hint\x18\x02 \x01(\bR\x0fdestructiveHint\x12'\n" + + "\x0fidempotent_hint\x18\x03 \x01(\bR\x0eidempotentHint\x12&\n" + + "\x0fopen_world_hint\x18\x04 \x01(\bR\ropenWorldHint\"`\n" + + "\x0eToolCallResult\x12\x16\n" + + "\x06output\x18\x01 \x01(\tR\x06output\x12\x19\n" + + "\bis_error\x18\x02 \x01(\bR\aisError\x12\x1b\n" + + "\tmeta_json\x18\x03 \x01(\fR\bmetaJson\",\n" + + "\x10UserMessageEvent\x12\x18\n" + + "\amessage\x18\x01 \x01(\tR\amessage\"R\n" + + "\x12StreamStartedEvent\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"R\n" + + "\x12StreamStoppedEvent\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"K\n" + + "\x10AgentChoiceEvent\x12\x18\n" + + "\acontent\x18\x01 \x01(\tR\acontent\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"T\n" + + "\x19AgentChoiceReasoningEvent\x12\x18\n" + + "\acontent\x18\x01 \x01(\tR\acontent\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"\xa1\x01\n" + + "\x14PartialToolCallEvent\x120\n" + + "\ttool_call\x18\x01 \x01(\v2\x13.cagent.v1.ToolCallR\btoolCall\x128\n" + + "\x0ftool_definition\x18\x02 \x01(\v2\x0f.cagent.v1.ToolR\x0etoolDefinition\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\x9a\x01\n" + + "\rToolCallEvent\x120\n" + + "\ttool_call\x18\x01 \x01(\v2\x13.cagent.v1.ToolCallR\btoolCall\x128\n" + + "\x0ftool_definition\x18\x02 \x01(\v2\x0f.cagent.v1.ToolR\x0etoolDefinition\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\xa6\x01\n" + + "\x19ToolCallConfirmationEvent\x120\n" + + "\ttool_call\x18\x01 \x01(\v2\x13.cagent.v1.ToolCallR\btoolCall\x128\n" + + "\x0ftool_definition\x18\x02 \x01(\v2\x0f.cagent.v1.ToolR\x0etoolDefinition\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\xf1\x01\n" + + "\x15ToolCallResponseEvent\x120\n" + + "\ttool_call\x18\x01 \x01(\v2\x13.cagent.v1.ToolCallR\btoolCall\x128\n" + + "\x0ftool_definition\x18\x02 \x01(\v2\x0f.cagent.v1.ToolR\x0etoolDefinition\x12\x1a\n" + + "\bresponse\x18\x03 \x01(\tR\bresponse\x121\n" + + "\x06result\x18\x04 \x01(\v2\x19.cagent.v1.ToolCallResultR\x06result\x12\x1d\n" + + "\n" + + "agent_name\x18\x05 \x01(\tR\tagentName\"A\n" + + "\n" + + "ErrorEvent\x12\x14\n" + + "\x05error\x18\x01 \x01(\tR\x05error\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"G\n" + + "\fWarningEvent\x12\x18\n" + + "\amessage\x18\x01 \x01(\tR\amessage\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"w\n" + + "\x0fTokenUsageEvent\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12&\n" + + "\x05usage\x18\x02 \x01(\v2\x10.cagent.v1.UsageR\x05usage\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\xe2\x01\n" + + "\x10LastMessageUsage\x12!\n" + + "\finput_tokens\x18\x01 \x01(\x03R\vinputTokens\x12#\n" + + "\routput_tokens\x18\x02 \x01(\x03R\foutputTokens\x12.\n" + + "\x13cached_input_tokens\x18\x03 \x01(\x03R\x11cachedInputTokens\x12,\n" + + "\x12cache_write_tokens\x18\x04 \x01(\x03R\x10cacheWriteTokens\x12\x12\n" + + "\x04cost\x18\x05 \x01(\x01R\x04cost\x12\x14\n" + + "\x05model\x18\x06 \x01(\tR\x05model\"\xef\x01\n" + + "\x05Usage\x12!\n" + + "\finput_tokens\x18\x01 \x01(\x03R\vinputTokens\x12#\n" + + "\routput_tokens\x18\x02 \x01(\x03R\foutputTokens\x12%\n" + + "\x0econtext_length\x18\x03 \x01(\x03R\rcontextLength\x12#\n" + + "\rcontext_limit\x18\x04 \x01(\x03R\fcontextLimit\x12\x12\n" + + "\x04cost\x18\x05 \x01(\x01R\x04cost\x12>\n" + + "\flast_message\x18\x06 \x01(\v2\x1b.cagent.v1.LastMessageUsageR\vlastMessage\"g\n" + + "\x11SessionTitleEvent\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"m\n" + + "\x13SessionSummaryEvent\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x18\n" + + "\asummary\x18\x02 \x01(\tR\asummary\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"n\n" + + "\x16SessionCompactionEvent\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + + "\x06status\x18\x02 \x01(\tR\x06status\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\x90\x01\n" + + "\x17ElicitationRequestEvent\x12\x18\n" + + "\amessage\x18\x01 \x01(\tR\amessage\x12\x1f\n" + + "\vschema_json\x18\x02 \x01(\fR\n" + + "schemaJson\x12\x1b\n" + + "\tmeta_json\x18\x03 \x01(\fR\bmetaJson\x12\x1d\n" + + "\n" + + "agent_name\x18\x04 \x01(\tR\tagentName\"W\n" + + "\x12AuthorizationEvent\x12\"\n" + + "\fconfirmation\x18\x01 \x01(\tR\fconfirmation\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"a\n" + + "\x19MaxIterationsReachedEvent\x12%\n" + + "\x0emax_iterations\x18\x01 \x01(\x05R\rmaxIterations\x12\x1d\n" + + "\n" + + "agent_name\x18\x02 \x01(\tR\tagentName\"4\n" + + "\x13MCPInitStartedEvent\x12\x1d\n" + + "\n" + + "agent_name\x18\x01 \x01(\tR\tagentName\"5\n" + + "\x14MCPInitFinishedEvent\x12\x1d\n" + + "\n" + + "agent_name\x18\x01 \x01(\tR\tagentName\"\x90\x01\n" + + "\x0eAgentInfoEvent\x12\x1d\n" + + "\n" + + "agent_name\x18\x01 \x01(\tR\tagentName\x12\x14\n" + + "\x05model\x18\x02 \x01(\tR\x05model\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12'\n" + + "\x0fwelcome_message\x18\x04 \x01(\tR\x0ewelcomeMessage\"v\n" + + "\fAgentDetails\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" + + "\vdescription\x18\x02 \x01(\tR\vdescription\x12\x1a\n" + + "\bprovider\x18\x03 \x01(\tR\bprovider\x12\x14\n" + + "\x05model\x18\x04 \x01(\tR\x05model\"\x97\x01\n" + + "\rTeamInfoEvent\x12B\n" + + "\x10available_agents\x18\x01 \x03(\v2\x17.cagent.v1.AgentDetailsR\x0favailableAgents\x12#\n" + + "\rcurrent_agent\x18\x02 \x01(\tR\fcurrentAgent\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\x8c\x01\n" + + "\x13AgentSwitchingEvent\x12\x1c\n" + + "\tswitching\x18\x01 \x01(\bR\tswitching\x12\x1d\n" + + "\n" + + "from_agent\x18\x02 \x01(\tR\tfromAgent\x12\x19\n" + + "\bto_agent\x18\x03 \x01(\tR\atoAgent\x12\x1d\n" + + "\n" + + "agent_name\x18\x04 \x01(\tR\tagentName\"t\n" + + "\x10ToolsetInfoEvent\x12'\n" + + "\x0favailable_tools\x18\x01 \x01(\x05R\x0eavailableTools\x12\x18\n" + + "\aloading\x18\x02 \x01(\bR\aloading\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"x\n" + + "\x17RAGIndexingStartedEvent\x12\x19\n" + + "\brag_name\x18\x01 \x01(\tR\aragName\x12#\n" + + "\rstrategy_name\x18\x02 \x01(\tR\fstrategyName\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\xa9\x01\n" + + "\x18RAGIndexingProgressEvent\x12\x19\n" + + "\brag_name\x18\x01 \x01(\tR\aragName\x12#\n" + + "\rstrategy_name\x18\x02 \x01(\tR\fstrategyName\x12\x18\n" + + "\acurrent\x18\x03 \x01(\x05R\acurrent\x12\x14\n" + + "\x05total\x18\x04 \x01(\x05R\x05total\x12\x1d\n" + + "\n" + + "agent_name\x18\x05 \x01(\tR\tagentName\"z\n" + + "\x19RAGIndexingCompletedEvent\x12\x19\n" + + "\brag_name\x18\x01 \x01(\tR\aragName\x12#\n" + + "\rstrategy_name\x18\x02 \x01(\tR\fstrategyName\x12\x1d\n" + + "\n" + + "agent_name\x18\x03 \x01(\tR\tagentName\"\xb7\x01\n" + + "\x10HookBlockedEvent\x120\n" + + "\ttool_call\x18\x01 \x01(\v2\x13.cagent.v1.ToolCallR\btoolCall\x128\n" + + "\x0ftool_definition\x18\x02 \x01(\v2\x0f.cagent.v1.ToolR\x0etoolDefinition\x12\x18\n" + + "\amessage\x18\x03 \x01(\tR\amessage\x12\x1d\n" + + "\n" + + "agent_name\x18\x04 \x01(\tR\tagentName\"*\n" + + "\x10ShellOutputEvent\x12\x16\n" + + "\x06output\x18\x01 \x01(\tR\x06output\"\r\n" + + "\vPingRequest\"&\n" + + "\fPingResponse\x12\x16\n" + + "\x06status\x18\x01 \x01(\tR\x06status2\xd1\a\n" + + "\fAgentService\x12I\n" + + "\n" + + "ListAgents\x12\x1c.cagent.v1.ListAgentsRequest\x1a\x1d.cagent.v1.ListAgentsResponse\x12C\n" + + "\bGetAgent\x12\x1a.cagent.v1.GetAgentRequest\x1a\x1b.cagent.v1.GetAgentResponse\x12O\n" + + "\fListSessions\x12\x1e.cagent.v1.ListSessionsRequest\x1a\x1f.cagent.v1.ListSessionsResponse\x12I\n" + + "\n" + + "GetSession\x12\x1c.cagent.v1.GetSessionRequest\x1a\x1d.cagent.v1.GetSessionResponse\x12R\n" + + "\rCreateSession\x12\x1f.cagent.v1.CreateSessionRequest\x1a .cagent.v1.CreateSessionResponse\x12R\n" + + "\rDeleteSession\x12\x1f.cagent.v1.DeleteSessionRequest\x1a .cagent.v1.DeleteSessionResponse\x12R\n" + + "\rResumeSession\x12\x1f.cagent.v1.ResumeSessionRequest\x1a .cagent.v1.ResumeSessionResponse\x12a\n" + + "\x12ToggleToolApproval\x12$.cagent.v1.ToggleToolApprovalRequest\x1a%.cagent.v1.ToggleToolApprovalResponse\x12a\n" + + "\x12UpdateSessionTitle\x12$.cagent.v1.UpdateSessionTitleRequest\x1a%.cagent.v1.UpdateSessionTitleResponse\x12^\n" + + "\x11ResumeElicitation\x12#.cagent.v1.ResumeElicitationRequest\x1a$.cagent.v1.ResumeElicitationResponse\x12:\n" + + "\bRunAgent\x12\x1a.cagent.v1.RunAgentRequest\x1a\x10.cagent.v1.Event0\x01\x127\n" + + "\x04Ping\x12\x16.cagent.v1.PingRequest\x1a\x17.cagent.v1.PingResponseB\x98\x01\n" + + "\rcom.cagent.v1B\vCagentProtoP\x01Z5github.com/docker/cagent/gen/proto/cagent/v1;cagentv1\xa2\x02\x03CXX\xaa\x02\tCagent.V1\xca\x02\tCagent\\V1\xe2\x02\x15Cagent\\V1\\GPBMetadata\xea\x02\n" + + "Cagent::V1b\x06proto3" + +var ( + file_cagent_v1_cagent_proto_rawDescOnce sync.Once + file_cagent_v1_cagent_proto_rawDescData []byte +) + +func file_cagent_v1_cagent_proto_rawDescGZIP() []byte { + file_cagent_v1_cagent_proto_rawDescOnce.Do(func() { + file_cagent_v1_cagent_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cagent_v1_cagent_proto_rawDesc), len(file_cagent_v1_cagent_proto_rawDesc))) + }) + return file_cagent_v1_cagent_proto_rawDescData +} + +var file_cagent_v1_cagent_proto_msgTypes = make([]protoimpl.MessageInfo, 67) +var file_cagent_v1_cagent_proto_goTypes = []any{ + (*Agent)(nil), // 0: cagent.v1.Agent + (*ListAgentsRequest)(nil), // 1: cagent.v1.ListAgentsRequest + (*ListAgentsResponse)(nil), // 2: cagent.v1.ListAgentsResponse + (*GetAgentRequest)(nil), // 3: cagent.v1.GetAgentRequest + (*GetAgentResponse)(nil), // 4: cagent.v1.GetAgentResponse + (*SessionSummary)(nil), // 5: cagent.v1.SessionSummary + (*ListSessionsRequest)(nil), // 6: cagent.v1.ListSessionsRequest + (*ListSessionsResponse)(nil), // 7: cagent.v1.ListSessionsResponse + (*Message)(nil), // 8: cagent.v1.Message + (*ToolCall)(nil), // 9: cagent.v1.ToolCall + (*FunctionCall)(nil), // 10: cagent.v1.FunctionCall + (*Session)(nil), // 11: cagent.v1.Session + (*GetSessionRequest)(nil), // 12: cagent.v1.GetSessionRequest + (*GetSessionResponse)(nil), // 13: cagent.v1.GetSessionResponse + (*CreateSessionRequest)(nil), // 14: cagent.v1.CreateSessionRequest + (*CreateSessionResponse)(nil), // 15: cagent.v1.CreateSessionResponse + (*DeleteSessionRequest)(nil), // 16: cagent.v1.DeleteSessionRequest + (*DeleteSessionResponse)(nil), // 17: cagent.v1.DeleteSessionResponse + (*ResumeSessionRequest)(nil), // 18: cagent.v1.ResumeSessionRequest + (*ResumeSessionResponse)(nil), // 19: cagent.v1.ResumeSessionResponse + (*ToggleToolApprovalRequest)(nil), // 20: cagent.v1.ToggleToolApprovalRequest + (*ToggleToolApprovalResponse)(nil), // 21: cagent.v1.ToggleToolApprovalResponse + (*UpdateSessionTitleRequest)(nil), // 22: cagent.v1.UpdateSessionTitleRequest + (*UpdateSessionTitleResponse)(nil), // 23: cagent.v1.UpdateSessionTitleResponse + (*ResumeElicitationRequest)(nil), // 24: cagent.v1.ResumeElicitationRequest + (*ResumeElicitationResponse)(nil), // 25: cagent.v1.ResumeElicitationResponse + (*InputMessage)(nil), // 26: cagent.v1.InputMessage + (*MessagePart)(nil), // 27: cagent.v1.MessagePart + (*RunAgentRequest)(nil), // 28: cagent.v1.RunAgentRequest + (*Event)(nil), // 29: cagent.v1.Event + (*Tool)(nil), // 30: cagent.v1.Tool + (*ToolAnnotations)(nil), // 31: cagent.v1.ToolAnnotations + (*ToolCallResult)(nil), // 32: cagent.v1.ToolCallResult + (*UserMessageEvent)(nil), // 33: cagent.v1.UserMessageEvent + (*StreamStartedEvent)(nil), // 34: cagent.v1.StreamStartedEvent + (*StreamStoppedEvent)(nil), // 35: cagent.v1.StreamStoppedEvent + (*AgentChoiceEvent)(nil), // 36: cagent.v1.AgentChoiceEvent + (*AgentChoiceReasoningEvent)(nil), // 37: cagent.v1.AgentChoiceReasoningEvent + (*PartialToolCallEvent)(nil), // 38: cagent.v1.PartialToolCallEvent + (*ToolCallEvent)(nil), // 39: cagent.v1.ToolCallEvent + (*ToolCallConfirmationEvent)(nil), // 40: cagent.v1.ToolCallConfirmationEvent + (*ToolCallResponseEvent)(nil), // 41: cagent.v1.ToolCallResponseEvent + (*ErrorEvent)(nil), // 42: cagent.v1.ErrorEvent + (*WarningEvent)(nil), // 43: cagent.v1.WarningEvent + (*TokenUsageEvent)(nil), // 44: cagent.v1.TokenUsageEvent + (*LastMessageUsage)(nil), // 45: cagent.v1.LastMessageUsage + (*Usage)(nil), // 46: cagent.v1.Usage + (*SessionTitleEvent)(nil), // 47: cagent.v1.SessionTitleEvent + (*SessionSummaryEvent)(nil), // 48: cagent.v1.SessionSummaryEvent + (*SessionCompactionEvent)(nil), // 49: cagent.v1.SessionCompactionEvent + (*ElicitationRequestEvent)(nil), // 50: cagent.v1.ElicitationRequestEvent + (*AuthorizationEvent)(nil), // 51: cagent.v1.AuthorizationEvent + (*MaxIterationsReachedEvent)(nil), // 52: cagent.v1.MaxIterationsReachedEvent + (*MCPInitStartedEvent)(nil), // 53: cagent.v1.MCPInitStartedEvent + (*MCPInitFinishedEvent)(nil), // 54: cagent.v1.MCPInitFinishedEvent + (*AgentInfoEvent)(nil), // 55: cagent.v1.AgentInfoEvent + (*AgentDetails)(nil), // 56: cagent.v1.AgentDetails + (*TeamInfoEvent)(nil), // 57: cagent.v1.TeamInfoEvent + (*AgentSwitchingEvent)(nil), // 58: cagent.v1.AgentSwitchingEvent + (*ToolsetInfoEvent)(nil), // 59: cagent.v1.ToolsetInfoEvent + (*RAGIndexingStartedEvent)(nil), // 60: cagent.v1.RAGIndexingStartedEvent + (*RAGIndexingProgressEvent)(nil), // 61: cagent.v1.RAGIndexingProgressEvent + (*RAGIndexingCompletedEvent)(nil), // 62: cagent.v1.RAGIndexingCompletedEvent + (*HookBlockedEvent)(nil), // 63: cagent.v1.HookBlockedEvent + (*ShellOutputEvent)(nil), // 64: cagent.v1.ShellOutputEvent + (*PingRequest)(nil), // 65: cagent.v1.PingRequest + (*PingResponse)(nil), // 66: cagent.v1.PingResponse +} +var file_cagent_v1_cagent_proto_depIdxs = []int32{ + 0, // 0: cagent.v1.ListAgentsResponse.agents:type_name -> cagent.v1.Agent + 5, // 1: cagent.v1.ListSessionsResponse.sessions:type_name -> cagent.v1.SessionSummary + 9, // 2: cagent.v1.Message.tool_calls:type_name -> cagent.v1.ToolCall + 10, // 3: cagent.v1.ToolCall.function:type_name -> cagent.v1.FunctionCall + 8, // 4: cagent.v1.Session.messages:type_name -> cagent.v1.Message + 11, // 5: cagent.v1.GetSessionResponse.session:type_name -> cagent.v1.Session + 11, // 6: cagent.v1.CreateSessionResponse.session:type_name -> cagent.v1.Session + 27, // 7: cagent.v1.InputMessage.multi_content:type_name -> cagent.v1.MessagePart + 26, // 8: cagent.v1.RunAgentRequest.messages:type_name -> cagent.v1.InputMessage + 33, // 9: cagent.v1.Event.user_message:type_name -> cagent.v1.UserMessageEvent + 34, // 10: cagent.v1.Event.stream_started:type_name -> cagent.v1.StreamStartedEvent + 35, // 11: cagent.v1.Event.stream_stopped:type_name -> cagent.v1.StreamStoppedEvent + 36, // 12: cagent.v1.Event.agent_choice:type_name -> cagent.v1.AgentChoiceEvent + 37, // 13: cagent.v1.Event.agent_choice_reasoning:type_name -> cagent.v1.AgentChoiceReasoningEvent + 38, // 14: cagent.v1.Event.partial_tool_call:type_name -> cagent.v1.PartialToolCallEvent + 39, // 15: cagent.v1.Event.tool_call:type_name -> cagent.v1.ToolCallEvent + 40, // 16: cagent.v1.Event.tool_call_confirmation:type_name -> cagent.v1.ToolCallConfirmationEvent + 41, // 17: cagent.v1.Event.tool_call_response:type_name -> cagent.v1.ToolCallResponseEvent + 42, // 18: cagent.v1.Event.error:type_name -> cagent.v1.ErrorEvent + 43, // 19: cagent.v1.Event.warning:type_name -> cagent.v1.WarningEvent + 44, // 20: cagent.v1.Event.token_usage:type_name -> cagent.v1.TokenUsageEvent + 47, // 21: cagent.v1.Event.session_title:type_name -> cagent.v1.SessionTitleEvent + 48, // 22: cagent.v1.Event.session_summary:type_name -> cagent.v1.SessionSummaryEvent + 49, // 23: cagent.v1.Event.session_compaction:type_name -> cagent.v1.SessionCompactionEvent + 50, // 24: cagent.v1.Event.elicitation_request:type_name -> cagent.v1.ElicitationRequestEvent + 51, // 25: cagent.v1.Event.authorization:type_name -> cagent.v1.AuthorizationEvent + 52, // 26: cagent.v1.Event.max_iterations_reached:type_name -> cagent.v1.MaxIterationsReachedEvent + 53, // 27: cagent.v1.Event.mcp_init_started:type_name -> cagent.v1.MCPInitStartedEvent + 54, // 28: cagent.v1.Event.mcp_init_finished:type_name -> cagent.v1.MCPInitFinishedEvent + 55, // 29: cagent.v1.Event.agent_info:type_name -> cagent.v1.AgentInfoEvent + 57, // 30: cagent.v1.Event.team_info:type_name -> cagent.v1.TeamInfoEvent + 58, // 31: cagent.v1.Event.agent_switching:type_name -> cagent.v1.AgentSwitchingEvent + 59, // 32: cagent.v1.Event.toolset_info:type_name -> cagent.v1.ToolsetInfoEvent + 60, // 33: cagent.v1.Event.rag_indexing_started:type_name -> cagent.v1.RAGIndexingStartedEvent + 61, // 34: cagent.v1.Event.rag_indexing_progress:type_name -> cagent.v1.RAGIndexingProgressEvent + 62, // 35: cagent.v1.Event.rag_indexing_completed:type_name -> cagent.v1.RAGIndexingCompletedEvent + 63, // 36: cagent.v1.Event.hook_blocked:type_name -> cagent.v1.HookBlockedEvent + 64, // 37: cagent.v1.Event.shell_output:type_name -> cagent.v1.ShellOutputEvent + 31, // 38: cagent.v1.Tool.annotations:type_name -> cagent.v1.ToolAnnotations + 9, // 39: cagent.v1.PartialToolCallEvent.tool_call:type_name -> cagent.v1.ToolCall + 30, // 40: cagent.v1.PartialToolCallEvent.tool_definition:type_name -> cagent.v1.Tool + 9, // 41: cagent.v1.ToolCallEvent.tool_call:type_name -> cagent.v1.ToolCall + 30, // 42: cagent.v1.ToolCallEvent.tool_definition:type_name -> cagent.v1.Tool + 9, // 43: cagent.v1.ToolCallConfirmationEvent.tool_call:type_name -> cagent.v1.ToolCall + 30, // 44: cagent.v1.ToolCallConfirmationEvent.tool_definition:type_name -> cagent.v1.Tool + 9, // 45: cagent.v1.ToolCallResponseEvent.tool_call:type_name -> cagent.v1.ToolCall + 30, // 46: cagent.v1.ToolCallResponseEvent.tool_definition:type_name -> cagent.v1.Tool + 32, // 47: cagent.v1.ToolCallResponseEvent.result:type_name -> cagent.v1.ToolCallResult + 46, // 48: cagent.v1.TokenUsageEvent.usage:type_name -> cagent.v1.Usage + 45, // 49: cagent.v1.Usage.last_message:type_name -> cagent.v1.LastMessageUsage + 56, // 50: cagent.v1.TeamInfoEvent.available_agents:type_name -> cagent.v1.AgentDetails + 9, // 51: cagent.v1.HookBlockedEvent.tool_call:type_name -> cagent.v1.ToolCall + 30, // 52: cagent.v1.HookBlockedEvent.tool_definition:type_name -> cagent.v1.Tool + 1, // 53: cagent.v1.AgentService.ListAgents:input_type -> cagent.v1.ListAgentsRequest + 3, // 54: cagent.v1.AgentService.GetAgent:input_type -> cagent.v1.GetAgentRequest + 6, // 55: cagent.v1.AgentService.ListSessions:input_type -> cagent.v1.ListSessionsRequest + 12, // 56: cagent.v1.AgentService.GetSession:input_type -> cagent.v1.GetSessionRequest + 14, // 57: cagent.v1.AgentService.CreateSession:input_type -> cagent.v1.CreateSessionRequest + 16, // 58: cagent.v1.AgentService.DeleteSession:input_type -> cagent.v1.DeleteSessionRequest + 18, // 59: cagent.v1.AgentService.ResumeSession:input_type -> cagent.v1.ResumeSessionRequest + 20, // 60: cagent.v1.AgentService.ToggleToolApproval:input_type -> cagent.v1.ToggleToolApprovalRequest + 22, // 61: cagent.v1.AgentService.UpdateSessionTitle:input_type -> cagent.v1.UpdateSessionTitleRequest + 24, // 62: cagent.v1.AgentService.ResumeElicitation:input_type -> cagent.v1.ResumeElicitationRequest + 28, // 63: cagent.v1.AgentService.RunAgent:input_type -> cagent.v1.RunAgentRequest + 65, // 64: cagent.v1.AgentService.Ping:input_type -> cagent.v1.PingRequest + 2, // 65: cagent.v1.AgentService.ListAgents:output_type -> cagent.v1.ListAgentsResponse + 4, // 66: cagent.v1.AgentService.GetAgent:output_type -> cagent.v1.GetAgentResponse + 7, // 67: cagent.v1.AgentService.ListSessions:output_type -> cagent.v1.ListSessionsResponse + 13, // 68: cagent.v1.AgentService.GetSession:output_type -> cagent.v1.GetSessionResponse + 15, // 69: cagent.v1.AgentService.CreateSession:output_type -> cagent.v1.CreateSessionResponse + 17, // 70: cagent.v1.AgentService.DeleteSession:output_type -> cagent.v1.DeleteSessionResponse + 19, // 71: cagent.v1.AgentService.ResumeSession:output_type -> cagent.v1.ResumeSessionResponse + 21, // 72: cagent.v1.AgentService.ToggleToolApproval:output_type -> cagent.v1.ToggleToolApprovalResponse + 23, // 73: cagent.v1.AgentService.UpdateSessionTitle:output_type -> cagent.v1.UpdateSessionTitleResponse + 25, // 74: cagent.v1.AgentService.ResumeElicitation:output_type -> cagent.v1.ResumeElicitationResponse + 29, // 75: cagent.v1.AgentService.RunAgent:output_type -> cagent.v1.Event + 66, // 76: cagent.v1.AgentService.Ping:output_type -> cagent.v1.PingResponse + 65, // [65:77] is the sub-list for method output_type + 53, // [53:65] is the sub-list for method input_type + 53, // [53:53] is the sub-list for extension type_name + 53, // [53:53] is the sub-list for extension extendee + 0, // [0:53] is the sub-list for field type_name +} + +func init() { file_cagent_v1_cagent_proto_init() } +func file_cagent_v1_cagent_proto_init() { + if File_cagent_v1_cagent_proto != nil { + return + } + file_cagent_v1_cagent_proto_msgTypes[29].OneofWrappers = []any{ + (*Event_UserMessage)(nil), + (*Event_StreamStarted)(nil), + (*Event_StreamStopped)(nil), + (*Event_AgentChoice)(nil), + (*Event_AgentChoiceReasoning)(nil), + (*Event_PartialToolCall)(nil), + (*Event_ToolCall)(nil), + (*Event_ToolCallConfirmation)(nil), + (*Event_ToolCallResponse)(nil), + (*Event_Error)(nil), + (*Event_Warning)(nil), + (*Event_TokenUsage)(nil), + (*Event_SessionTitle)(nil), + (*Event_SessionSummary)(nil), + (*Event_SessionCompaction)(nil), + (*Event_ElicitationRequest)(nil), + (*Event_Authorization)(nil), + (*Event_MaxIterationsReached)(nil), + (*Event_McpInitStarted)(nil), + (*Event_McpInitFinished)(nil), + (*Event_AgentInfo)(nil), + (*Event_TeamInfo)(nil), + (*Event_AgentSwitching)(nil), + (*Event_ToolsetInfo)(nil), + (*Event_RagIndexingStarted)(nil), + (*Event_RagIndexingProgress)(nil), + (*Event_RagIndexingCompleted)(nil), + (*Event_HookBlocked)(nil), + (*Event_ShellOutput)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cagent_v1_cagent_proto_rawDesc), len(file_cagent_v1_cagent_proto_rawDesc)), + NumEnums: 0, + NumMessages: 67, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cagent_v1_cagent_proto_goTypes, + DependencyIndexes: file_cagent_v1_cagent_proto_depIdxs, + MessageInfos: file_cagent_v1_cagent_proto_msgTypes, + }.Build() + File_cagent_v1_cagent_proto = out.File + file_cagent_v1_cagent_proto_goTypes = nil + file_cagent_v1_cagent_proto_depIdxs = nil +} diff --git a/gen/cagent/v1/cagentv1connect/cagent.connect.go b/gen/cagent/v1/cagentv1connect/cagent.connect.go new file mode 100644 index 000000000..7aa360109 --- /dev/null +++ b/gen/cagent/v1/cagentv1connect/cagent.connect.go @@ -0,0 +1,447 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: cagent/v1/cagent.proto + +package cagentv1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/docker/cagent/gen/proto/cagent/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // AgentServiceName is the fully-qualified name of the AgentService service. + AgentServiceName = "cagent.v1.AgentService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // AgentServiceListAgentsProcedure is the fully-qualified name of the AgentService's ListAgents RPC. + AgentServiceListAgentsProcedure = "/cagent.v1.AgentService/ListAgents" + // AgentServiceGetAgentProcedure is the fully-qualified name of the AgentService's GetAgent RPC. + AgentServiceGetAgentProcedure = "/cagent.v1.AgentService/GetAgent" + // AgentServiceListSessionsProcedure is the fully-qualified name of the AgentService's ListSessions + // RPC. + AgentServiceListSessionsProcedure = "/cagent.v1.AgentService/ListSessions" + // AgentServiceGetSessionProcedure is the fully-qualified name of the AgentService's GetSession RPC. + AgentServiceGetSessionProcedure = "/cagent.v1.AgentService/GetSession" + // AgentServiceCreateSessionProcedure is the fully-qualified name of the AgentService's + // CreateSession RPC. + AgentServiceCreateSessionProcedure = "/cagent.v1.AgentService/CreateSession" + // AgentServiceDeleteSessionProcedure is the fully-qualified name of the AgentService's + // DeleteSession RPC. + AgentServiceDeleteSessionProcedure = "/cagent.v1.AgentService/DeleteSession" + // AgentServiceResumeSessionProcedure is the fully-qualified name of the AgentService's + // ResumeSession RPC. + AgentServiceResumeSessionProcedure = "/cagent.v1.AgentService/ResumeSession" + // AgentServiceToggleToolApprovalProcedure is the fully-qualified name of the AgentService's + // ToggleToolApproval RPC. + AgentServiceToggleToolApprovalProcedure = "/cagent.v1.AgentService/ToggleToolApproval" + // AgentServiceUpdateSessionTitleProcedure is the fully-qualified name of the AgentService's + // UpdateSessionTitle RPC. + AgentServiceUpdateSessionTitleProcedure = "/cagent.v1.AgentService/UpdateSessionTitle" + // AgentServiceResumeElicitationProcedure is the fully-qualified name of the AgentService's + // ResumeElicitation RPC. + AgentServiceResumeElicitationProcedure = "/cagent.v1.AgentService/ResumeElicitation" + // AgentServiceRunAgentProcedure is the fully-qualified name of the AgentService's RunAgent RPC. + AgentServiceRunAgentProcedure = "/cagent.v1.AgentService/RunAgent" + // AgentServicePingProcedure is the fully-qualified name of the AgentService's Ping RPC. + AgentServicePingProcedure = "/cagent.v1.AgentService/Ping" +) + +// AgentServiceClient is a client for the cagent.v1.AgentService service. +type AgentServiceClient interface { + // ListAgents returns all available agents. + ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) + // GetAgent returns the configuration for a specific agent. + GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) + // ListSessions returns all sessions. + ListSessions(context.Context, *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) + // GetSession returns a specific session by ID. + GetSession(context.Context, *connect.Request[v1.GetSessionRequest]) (*connect.Response[v1.GetSessionResponse], error) + // CreateSession creates a new session. + CreateSession(context.Context, *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error) + // DeleteSession deletes a session by ID. + DeleteSession(context.Context, *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[v1.DeleteSessionResponse], error) + // ResumeSession resumes a paused session (e.g., after tool confirmation). + ResumeSession(context.Context, *connect.Request[v1.ResumeSessionRequest]) (*connect.Response[v1.ResumeSessionResponse], error) + // ToggleToolApproval toggles the YOLO mode for a session. + ToggleToolApproval(context.Context, *connect.Request[v1.ToggleToolApprovalRequest]) (*connect.Response[v1.ToggleToolApprovalResponse], error) + // UpdateSessionTitle updates the title of a session. + UpdateSessionTitle(context.Context, *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) + // ResumeElicitation resumes an elicitation request. + ResumeElicitation(context.Context, *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) + // RunAgent runs an agent loop and streams events. + RunAgent(context.Context, *connect.Request[v1.RunAgentRequest]) (*connect.ServerStreamForClient[v1.Event], error) + // Ping is a health check endpoint. + Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) +} + +// NewAgentServiceClient constructs a client for the cagent.v1.AgentService service. By default, it +// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends +// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewAgentServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AgentServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + agentServiceMethods := v1.File_cagent_v1_cagent_proto.Services().ByName("AgentService").Methods() + return &agentServiceClient{ + listAgents: connect.NewClient[v1.ListAgentsRequest, v1.ListAgentsResponse]( + httpClient, + baseURL+AgentServiceListAgentsProcedure, + connect.WithSchema(agentServiceMethods.ByName("ListAgents")), + connect.WithClientOptions(opts...), + ), + getAgent: connect.NewClient[v1.GetAgentRequest, v1.GetAgentResponse]( + httpClient, + baseURL+AgentServiceGetAgentProcedure, + connect.WithSchema(agentServiceMethods.ByName("GetAgent")), + connect.WithClientOptions(opts...), + ), + listSessions: connect.NewClient[v1.ListSessionsRequest, v1.ListSessionsResponse]( + httpClient, + baseURL+AgentServiceListSessionsProcedure, + connect.WithSchema(agentServiceMethods.ByName("ListSessions")), + connect.WithClientOptions(opts...), + ), + getSession: connect.NewClient[v1.GetSessionRequest, v1.GetSessionResponse]( + httpClient, + baseURL+AgentServiceGetSessionProcedure, + connect.WithSchema(agentServiceMethods.ByName("GetSession")), + connect.WithClientOptions(opts...), + ), + createSession: connect.NewClient[v1.CreateSessionRequest, v1.CreateSessionResponse]( + httpClient, + baseURL+AgentServiceCreateSessionProcedure, + connect.WithSchema(agentServiceMethods.ByName("CreateSession")), + connect.WithClientOptions(opts...), + ), + deleteSession: connect.NewClient[v1.DeleteSessionRequest, v1.DeleteSessionResponse]( + httpClient, + baseURL+AgentServiceDeleteSessionProcedure, + connect.WithSchema(agentServiceMethods.ByName("DeleteSession")), + connect.WithClientOptions(opts...), + ), + resumeSession: connect.NewClient[v1.ResumeSessionRequest, v1.ResumeSessionResponse]( + httpClient, + baseURL+AgentServiceResumeSessionProcedure, + connect.WithSchema(agentServiceMethods.ByName("ResumeSession")), + connect.WithClientOptions(opts...), + ), + toggleToolApproval: connect.NewClient[v1.ToggleToolApprovalRequest, v1.ToggleToolApprovalResponse]( + httpClient, + baseURL+AgentServiceToggleToolApprovalProcedure, + connect.WithSchema(agentServiceMethods.ByName("ToggleToolApproval")), + connect.WithClientOptions(opts...), + ), + updateSessionTitle: connect.NewClient[v1.UpdateSessionTitleRequest, v1.UpdateSessionTitleResponse]( + httpClient, + baseURL+AgentServiceUpdateSessionTitleProcedure, + connect.WithSchema(agentServiceMethods.ByName("UpdateSessionTitle")), + connect.WithClientOptions(opts...), + ), + resumeElicitation: connect.NewClient[v1.ResumeElicitationRequest, v1.ResumeElicitationResponse]( + httpClient, + baseURL+AgentServiceResumeElicitationProcedure, + connect.WithSchema(agentServiceMethods.ByName("ResumeElicitation")), + connect.WithClientOptions(opts...), + ), + runAgent: connect.NewClient[v1.RunAgentRequest, v1.Event]( + httpClient, + baseURL+AgentServiceRunAgentProcedure, + connect.WithSchema(agentServiceMethods.ByName("RunAgent")), + connect.WithClientOptions(opts...), + ), + ping: connect.NewClient[v1.PingRequest, v1.PingResponse]( + httpClient, + baseURL+AgentServicePingProcedure, + connect.WithSchema(agentServiceMethods.ByName("Ping")), + connect.WithClientOptions(opts...), + ), + } +} + +// agentServiceClient implements AgentServiceClient. +type agentServiceClient struct { + listAgents *connect.Client[v1.ListAgentsRequest, v1.ListAgentsResponse] + getAgent *connect.Client[v1.GetAgentRequest, v1.GetAgentResponse] + listSessions *connect.Client[v1.ListSessionsRequest, v1.ListSessionsResponse] + getSession *connect.Client[v1.GetSessionRequest, v1.GetSessionResponse] + createSession *connect.Client[v1.CreateSessionRequest, v1.CreateSessionResponse] + deleteSession *connect.Client[v1.DeleteSessionRequest, v1.DeleteSessionResponse] + resumeSession *connect.Client[v1.ResumeSessionRequest, v1.ResumeSessionResponse] + toggleToolApproval *connect.Client[v1.ToggleToolApprovalRequest, v1.ToggleToolApprovalResponse] + updateSessionTitle *connect.Client[v1.UpdateSessionTitleRequest, v1.UpdateSessionTitleResponse] + resumeElicitation *connect.Client[v1.ResumeElicitationRequest, v1.ResumeElicitationResponse] + runAgent *connect.Client[v1.RunAgentRequest, v1.Event] + ping *connect.Client[v1.PingRequest, v1.PingResponse] +} + +// ListAgents calls cagent.v1.AgentService.ListAgents. +func (c *agentServiceClient) ListAgents(ctx context.Context, req *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) { + return c.listAgents.CallUnary(ctx, req) +} + +// GetAgent calls cagent.v1.AgentService.GetAgent. +func (c *agentServiceClient) GetAgent(ctx context.Context, req *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) { + return c.getAgent.CallUnary(ctx, req) +} + +// ListSessions calls cagent.v1.AgentService.ListSessions. +func (c *agentServiceClient) ListSessions(ctx context.Context, req *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) { + return c.listSessions.CallUnary(ctx, req) +} + +// GetSession calls cagent.v1.AgentService.GetSession. +func (c *agentServiceClient) GetSession(ctx context.Context, req *connect.Request[v1.GetSessionRequest]) (*connect.Response[v1.GetSessionResponse], error) { + return c.getSession.CallUnary(ctx, req) +} + +// CreateSession calls cagent.v1.AgentService.CreateSession. +func (c *agentServiceClient) CreateSession(ctx context.Context, req *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error) { + return c.createSession.CallUnary(ctx, req) +} + +// DeleteSession calls cagent.v1.AgentService.DeleteSession. +func (c *agentServiceClient) DeleteSession(ctx context.Context, req *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[v1.DeleteSessionResponse], error) { + return c.deleteSession.CallUnary(ctx, req) +} + +// ResumeSession calls cagent.v1.AgentService.ResumeSession. +func (c *agentServiceClient) ResumeSession(ctx context.Context, req *connect.Request[v1.ResumeSessionRequest]) (*connect.Response[v1.ResumeSessionResponse], error) { + return c.resumeSession.CallUnary(ctx, req) +} + +// ToggleToolApproval calls cagent.v1.AgentService.ToggleToolApproval. +func (c *agentServiceClient) ToggleToolApproval(ctx context.Context, req *connect.Request[v1.ToggleToolApprovalRequest]) (*connect.Response[v1.ToggleToolApprovalResponse], error) { + return c.toggleToolApproval.CallUnary(ctx, req) +} + +// UpdateSessionTitle calls cagent.v1.AgentService.UpdateSessionTitle. +func (c *agentServiceClient) UpdateSessionTitle(ctx context.Context, req *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) { + return c.updateSessionTitle.CallUnary(ctx, req) +} + +// ResumeElicitation calls cagent.v1.AgentService.ResumeElicitation. +func (c *agentServiceClient) ResumeElicitation(ctx context.Context, req *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) { + return c.resumeElicitation.CallUnary(ctx, req) +} + +// RunAgent calls cagent.v1.AgentService.RunAgent. +func (c *agentServiceClient) RunAgent(ctx context.Context, req *connect.Request[v1.RunAgentRequest]) (*connect.ServerStreamForClient[v1.Event], error) { + return c.runAgent.CallServerStream(ctx, req) +} + +// Ping calls cagent.v1.AgentService.Ping. +func (c *agentServiceClient) Ping(ctx context.Context, req *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) { + return c.ping.CallUnary(ctx, req) +} + +// AgentServiceHandler is an implementation of the cagent.v1.AgentService service. +type AgentServiceHandler interface { + // ListAgents returns all available agents. + ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) + // GetAgent returns the configuration for a specific agent. + GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) + // ListSessions returns all sessions. + ListSessions(context.Context, *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) + // GetSession returns a specific session by ID. + GetSession(context.Context, *connect.Request[v1.GetSessionRequest]) (*connect.Response[v1.GetSessionResponse], error) + // CreateSession creates a new session. + CreateSession(context.Context, *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error) + // DeleteSession deletes a session by ID. + DeleteSession(context.Context, *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[v1.DeleteSessionResponse], error) + // ResumeSession resumes a paused session (e.g., after tool confirmation). + ResumeSession(context.Context, *connect.Request[v1.ResumeSessionRequest]) (*connect.Response[v1.ResumeSessionResponse], error) + // ToggleToolApproval toggles the YOLO mode for a session. + ToggleToolApproval(context.Context, *connect.Request[v1.ToggleToolApprovalRequest]) (*connect.Response[v1.ToggleToolApprovalResponse], error) + // UpdateSessionTitle updates the title of a session. + UpdateSessionTitle(context.Context, *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) + // ResumeElicitation resumes an elicitation request. + ResumeElicitation(context.Context, *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) + // RunAgent runs an agent loop and streams events. + RunAgent(context.Context, *connect.Request[v1.RunAgentRequest], *connect.ServerStream[v1.Event]) error + // Ping is a health check endpoint. + Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) +} + +// NewAgentServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewAgentServiceHandler(svc AgentServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + agentServiceMethods := v1.File_cagent_v1_cagent_proto.Services().ByName("AgentService").Methods() + agentServiceListAgentsHandler := connect.NewUnaryHandler( + AgentServiceListAgentsProcedure, + svc.ListAgents, + connect.WithSchema(agentServiceMethods.ByName("ListAgents")), + connect.WithHandlerOptions(opts...), + ) + agentServiceGetAgentHandler := connect.NewUnaryHandler( + AgentServiceGetAgentProcedure, + svc.GetAgent, + connect.WithSchema(agentServiceMethods.ByName("GetAgent")), + connect.WithHandlerOptions(opts...), + ) + agentServiceListSessionsHandler := connect.NewUnaryHandler( + AgentServiceListSessionsProcedure, + svc.ListSessions, + connect.WithSchema(agentServiceMethods.ByName("ListSessions")), + connect.WithHandlerOptions(opts...), + ) + agentServiceGetSessionHandler := connect.NewUnaryHandler( + AgentServiceGetSessionProcedure, + svc.GetSession, + connect.WithSchema(agentServiceMethods.ByName("GetSession")), + connect.WithHandlerOptions(opts...), + ) + agentServiceCreateSessionHandler := connect.NewUnaryHandler( + AgentServiceCreateSessionProcedure, + svc.CreateSession, + connect.WithSchema(agentServiceMethods.ByName("CreateSession")), + connect.WithHandlerOptions(opts...), + ) + agentServiceDeleteSessionHandler := connect.NewUnaryHandler( + AgentServiceDeleteSessionProcedure, + svc.DeleteSession, + connect.WithSchema(agentServiceMethods.ByName("DeleteSession")), + connect.WithHandlerOptions(opts...), + ) + agentServiceResumeSessionHandler := connect.NewUnaryHandler( + AgentServiceResumeSessionProcedure, + svc.ResumeSession, + connect.WithSchema(agentServiceMethods.ByName("ResumeSession")), + connect.WithHandlerOptions(opts...), + ) + agentServiceToggleToolApprovalHandler := connect.NewUnaryHandler( + AgentServiceToggleToolApprovalProcedure, + svc.ToggleToolApproval, + connect.WithSchema(agentServiceMethods.ByName("ToggleToolApproval")), + connect.WithHandlerOptions(opts...), + ) + agentServiceUpdateSessionTitleHandler := connect.NewUnaryHandler( + AgentServiceUpdateSessionTitleProcedure, + svc.UpdateSessionTitle, + connect.WithSchema(agentServiceMethods.ByName("UpdateSessionTitle")), + connect.WithHandlerOptions(opts...), + ) + agentServiceResumeElicitationHandler := connect.NewUnaryHandler( + AgentServiceResumeElicitationProcedure, + svc.ResumeElicitation, + connect.WithSchema(agentServiceMethods.ByName("ResumeElicitation")), + connect.WithHandlerOptions(opts...), + ) + agentServiceRunAgentHandler := connect.NewServerStreamHandler( + AgentServiceRunAgentProcedure, + svc.RunAgent, + connect.WithSchema(agentServiceMethods.ByName("RunAgent")), + connect.WithHandlerOptions(opts...), + ) + agentServicePingHandler := connect.NewUnaryHandler( + AgentServicePingProcedure, + svc.Ping, + connect.WithSchema(agentServiceMethods.ByName("Ping")), + connect.WithHandlerOptions(opts...), + ) + return "/cagent.v1.AgentService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case AgentServiceListAgentsProcedure: + agentServiceListAgentsHandler.ServeHTTP(w, r) + case AgentServiceGetAgentProcedure: + agentServiceGetAgentHandler.ServeHTTP(w, r) + case AgentServiceListSessionsProcedure: + agentServiceListSessionsHandler.ServeHTTP(w, r) + case AgentServiceGetSessionProcedure: + agentServiceGetSessionHandler.ServeHTTP(w, r) + case AgentServiceCreateSessionProcedure: + agentServiceCreateSessionHandler.ServeHTTP(w, r) + case AgentServiceDeleteSessionProcedure: + agentServiceDeleteSessionHandler.ServeHTTP(w, r) + case AgentServiceResumeSessionProcedure: + agentServiceResumeSessionHandler.ServeHTTP(w, r) + case AgentServiceToggleToolApprovalProcedure: + agentServiceToggleToolApprovalHandler.ServeHTTP(w, r) + case AgentServiceUpdateSessionTitleProcedure: + agentServiceUpdateSessionTitleHandler.ServeHTTP(w, r) + case AgentServiceResumeElicitationProcedure: + agentServiceResumeElicitationHandler.ServeHTTP(w, r) + case AgentServiceRunAgentProcedure: + agentServiceRunAgentHandler.ServeHTTP(w, r) + case AgentServicePingProcedure: + agentServicePingHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedAgentServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedAgentServiceHandler struct{} + +func (UnimplementedAgentServiceHandler) ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.ListAgents is not implemented")) +} + +func (UnimplementedAgentServiceHandler) GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.GetAgent is not implemented")) +} + +func (UnimplementedAgentServiceHandler) ListSessions(context.Context, *connect.Request[v1.ListSessionsRequest]) (*connect.Response[v1.ListSessionsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.ListSessions is not implemented")) +} + +func (UnimplementedAgentServiceHandler) GetSession(context.Context, *connect.Request[v1.GetSessionRequest]) (*connect.Response[v1.GetSessionResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.GetSession is not implemented")) +} + +func (UnimplementedAgentServiceHandler) CreateSession(context.Context, *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.CreateSession is not implemented")) +} + +func (UnimplementedAgentServiceHandler) DeleteSession(context.Context, *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[v1.DeleteSessionResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.DeleteSession is not implemented")) +} + +func (UnimplementedAgentServiceHandler) ResumeSession(context.Context, *connect.Request[v1.ResumeSessionRequest]) (*connect.Response[v1.ResumeSessionResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.ResumeSession is not implemented")) +} + +func (UnimplementedAgentServiceHandler) ToggleToolApproval(context.Context, *connect.Request[v1.ToggleToolApprovalRequest]) (*connect.Response[v1.ToggleToolApprovalResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.ToggleToolApproval is not implemented")) +} + +func (UnimplementedAgentServiceHandler) UpdateSessionTitle(context.Context, *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.UpdateSessionTitle is not implemented")) +} + +func (UnimplementedAgentServiceHandler) ResumeElicitation(context.Context, *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.ResumeElicitation is not implemented")) +} + +func (UnimplementedAgentServiceHandler) RunAgent(context.Context, *connect.Request[v1.RunAgentRequest], *connect.ServerStream[v1.Event]) error { + return connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.RunAgent is not implemented")) +} + +func (UnimplementedAgentServiceHandler) Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.Ping is not implemented")) +} diff --git a/gen/proto/cagent/v1/cagent.pb.go b/gen/proto/cagent/v1/cagent.pb.go index 5dfb8e536..b1a09fd62 100644 --- a/gen/proto/cagent/v1/cagent.pb.go +++ b/gen/proto/cagent/v1/cagent.pb.go @@ -1021,7 +1021,7 @@ type ResumeSessionRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Confirmation string `protobuf:"bytes,2,opt,name=confirmation,proto3" json:"confirmation,omitempty"` // "approve", "approve-session", or "reject" - Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` // Optional rejection reason (used when confirmation is "reject") + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` // optional reason for rejection unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1196,6 +1196,112 @@ func (*ToggleToolApprovalResponse) Descriptor() ([]byte, []int) { return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{21} } +// UpdateSessionTitleRequest is the request for UpdateSessionTitle. +type UpdateSessionTitleRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateSessionTitleRequest) Reset() { + *x = UpdateSessionTitleRequest{} + mi := &file_cagent_v1_cagent_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateSessionTitleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSessionTitleRequest) ProtoMessage() {} + +func (x *UpdateSessionTitleRequest) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[22] + 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 UpdateSessionTitleRequest.ProtoReflect.Descriptor instead. +func (*UpdateSessionTitleRequest) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{22} +} + +func (x *UpdateSessionTitleRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *UpdateSessionTitleRequest) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +// UpdateSessionTitleResponse is the response for UpdateSessionTitle. +type UpdateSessionTitleResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateSessionTitleResponse) Reset() { + *x = UpdateSessionTitleResponse{} + mi := &file_cagent_v1_cagent_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateSessionTitleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSessionTitleResponse) ProtoMessage() {} + +func (x *UpdateSessionTitleResponse) ProtoReflect() protoreflect.Message { + mi := &file_cagent_v1_cagent_proto_msgTypes[23] + 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 UpdateSessionTitleResponse.ProtoReflect.Descriptor instead. +func (*UpdateSessionTitleResponse) Descriptor() ([]byte, []int) { + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{23} +} + +func (x *UpdateSessionTitleResponse) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *UpdateSessionTitleResponse) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + // ResumeElicitationRequest is the request for ResumeElicitation. type ResumeElicitationRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1208,7 +1314,7 @@ type ResumeElicitationRequest struct { func (x *ResumeElicitationRequest) Reset() { *x = ResumeElicitationRequest{} - mi := &file_cagent_v1_cagent_proto_msgTypes[22] + mi := &file_cagent_v1_cagent_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1220,7 +1326,7 @@ func (x *ResumeElicitationRequest) String() string { func (*ResumeElicitationRequest) ProtoMessage() {} func (x *ResumeElicitationRequest) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[22] + mi := &file_cagent_v1_cagent_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1233,7 +1339,7 @@ func (x *ResumeElicitationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeElicitationRequest.ProtoReflect.Descriptor instead. func (*ResumeElicitationRequest) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{22} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{24} } func (x *ResumeElicitationRequest) GetSessionId() string { @@ -1266,7 +1372,7 @@ type ResumeElicitationResponse struct { func (x *ResumeElicitationResponse) Reset() { *x = ResumeElicitationResponse{} - mi := &file_cagent_v1_cagent_proto_msgTypes[23] + mi := &file_cagent_v1_cagent_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1278,7 +1384,7 @@ func (x *ResumeElicitationResponse) String() string { func (*ResumeElicitationResponse) ProtoMessage() {} func (x *ResumeElicitationResponse) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[23] + mi := &file_cagent_v1_cagent_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1291,7 +1397,7 @@ func (x *ResumeElicitationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeElicitationResponse.ProtoReflect.Descriptor instead. func (*ResumeElicitationResponse) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{23} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{25} } // InputMessage is a message to send to the agent. @@ -1306,7 +1412,7 @@ type InputMessage struct { func (x *InputMessage) Reset() { *x = InputMessage{} - mi := &file_cagent_v1_cagent_proto_msgTypes[24] + mi := &file_cagent_v1_cagent_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1318,7 +1424,7 @@ func (x *InputMessage) String() string { func (*InputMessage) ProtoMessage() {} func (x *InputMessage) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[24] + mi := &file_cagent_v1_cagent_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1331,7 +1437,7 @@ func (x *InputMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use InputMessage.ProtoReflect.Descriptor instead. func (*InputMessage) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{24} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{26} } func (x *InputMessage) GetRole() string { @@ -1367,7 +1473,7 @@ type MessagePart struct { func (x *MessagePart) Reset() { *x = MessagePart{} - mi := &file_cagent_v1_cagent_proto_msgTypes[25] + mi := &file_cagent_v1_cagent_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1379,7 +1485,7 @@ func (x *MessagePart) String() string { func (*MessagePart) ProtoMessage() {} func (x *MessagePart) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[25] + mi := &file_cagent_v1_cagent_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1392,7 +1498,7 @@ func (x *MessagePart) ProtoReflect() protoreflect.Message { // Deprecated: Use MessagePart.ProtoReflect.Descriptor instead. func (*MessagePart) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{25} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{27} } func (x *MessagePart) GetType() string { @@ -1429,7 +1535,7 @@ type RunAgentRequest struct { func (x *RunAgentRequest) Reset() { *x = RunAgentRequest{} - mi := &file_cagent_v1_cagent_proto_msgTypes[26] + mi := &file_cagent_v1_cagent_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1441,7 +1547,7 @@ func (x *RunAgentRequest) String() string { func (*RunAgentRequest) ProtoMessage() {} func (x *RunAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[26] + mi := &file_cagent_v1_cagent_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1454,7 +1560,7 @@ func (x *RunAgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RunAgentRequest.ProtoReflect.Descriptor instead. func (*RunAgentRequest) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{26} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{28} } func (x *RunAgentRequest) GetSessionId() string { @@ -1527,7 +1633,7 @@ type Event struct { func (x *Event) Reset() { *x = Event{} - mi := &file_cagent_v1_cagent_proto_msgTypes[27] + mi := &file_cagent_v1_cagent_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1539,7 +1645,7 @@ func (x *Event) String() string { func (*Event) ProtoMessage() {} func (x *Event) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[27] + mi := &file_cagent_v1_cagent_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1552,7 +1658,7 @@ func (x *Event) ProtoReflect() protoreflect.Message { // Deprecated: Use Event.ProtoReflect.Descriptor instead. func (*Event) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{27} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{29} } func (x *Event) GetEvent() isEvent_Event { @@ -2016,7 +2122,7 @@ type Tool struct { func (x *Tool) Reset() { *x = Tool{} - mi := &file_cagent_v1_cagent_proto_msgTypes[28] + mi := &file_cagent_v1_cagent_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2028,7 +2134,7 @@ func (x *Tool) String() string { func (*Tool) ProtoMessage() {} func (x *Tool) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[28] + mi := &file_cagent_v1_cagent_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2041,7 +2147,7 @@ func (x *Tool) ProtoReflect() protoreflect.Message { // Deprecated: Use Tool.ProtoReflect.Descriptor instead. func (*Tool) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{28} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{30} } func (x *Tool) GetName() string { @@ -2099,7 +2205,7 @@ type ToolAnnotations struct { func (x *ToolAnnotations) Reset() { *x = ToolAnnotations{} - mi := &file_cagent_v1_cagent_proto_msgTypes[29] + mi := &file_cagent_v1_cagent_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2111,7 +2217,7 @@ func (x *ToolAnnotations) String() string { func (*ToolAnnotations) ProtoMessage() {} func (x *ToolAnnotations) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[29] + mi := &file_cagent_v1_cagent_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2124,7 +2230,7 @@ func (x *ToolAnnotations) ProtoReflect() protoreflect.Message { // Deprecated: Use ToolAnnotations.ProtoReflect.Descriptor instead. func (*ToolAnnotations) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{29} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{31} } func (x *ToolAnnotations) GetReadOnlyHint() bool { @@ -2167,7 +2273,7 @@ type ToolCallResult struct { func (x *ToolCallResult) Reset() { *x = ToolCallResult{} - mi := &file_cagent_v1_cagent_proto_msgTypes[30] + mi := &file_cagent_v1_cagent_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2179,7 +2285,7 @@ func (x *ToolCallResult) String() string { func (*ToolCallResult) ProtoMessage() {} func (x *ToolCallResult) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[30] + mi := &file_cagent_v1_cagent_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2192,7 +2298,7 @@ func (x *ToolCallResult) ProtoReflect() protoreflect.Message { // Deprecated: Use ToolCallResult.ProtoReflect.Descriptor instead. func (*ToolCallResult) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{30} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{32} } func (x *ToolCallResult) GetOutput() string { @@ -2226,7 +2332,7 @@ type UserMessageEvent struct { func (x *UserMessageEvent) Reset() { *x = UserMessageEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[31] + mi := &file_cagent_v1_cagent_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2238,7 +2344,7 @@ func (x *UserMessageEvent) String() string { func (*UserMessageEvent) ProtoMessage() {} func (x *UserMessageEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[31] + mi := &file_cagent_v1_cagent_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2251,7 +2357,7 @@ func (x *UserMessageEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use UserMessageEvent.ProtoReflect.Descriptor instead. func (*UserMessageEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{31} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{33} } func (x *UserMessageEvent) GetMessage() string { @@ -2272,7 +2378,7 @@ type StreamStartedEvent struct { func (x *StreamStartedEvent) Reset() { *x = StreamStartedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[32] + mi := &file_cagent_v1_cagent_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2284,7 +2390,7 @@ func (x *StreamStartedEvent) String() string { func (*StreamStartedEvent) ProtoMessage() {} func (x *StreamStartedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[32] + mi := &file_cagent_v1_cagent_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2297,7 +2403,7 @@ func (x *StreamStartedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamStartedEvent.ProtoReflect.Descriptor instead. func (*StreamStartedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{32} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{34} } func (x *StreamStartedEvent) GetSessionId() string { @@ -2325,7 +2431,7 @@ type StreamStoppedEvent struct { func (x *StreamStoppedEvent) Reset() { *x = StreamStoppedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[33] + mi := &file_cagent_v1_cagent_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2337,7 +2443,7 @@ func (x *StreamStoppedEvent) String() string { func (*StreamStoppedEvent) ProtoMessage() {} func (x *StreamStoppedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[33] + mi := &file_cagent_v1_cagent_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2350,7 +2456,7 @@ func (x *StreamStoppedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamStoppedEvent.ProtoReflect.Descriptor instead. func (*StreamStoppedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{33} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{35} } func (x *StreamStoppedEvent) GetSessionId() string { @@ -2378,7 +2484,7 @@ type AgentChoiceEvent struct { func (x *AgentChoiceEvent) Reset() { *x = AgentChoiceEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[34] + mi := &file_cagent_v1_cagent_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2390,7 +2496,7 @@ func (x *AgentChoiceEvent) String() string { func (*AgentChoiceEvent) ProtoMessage() {} func (x *AgentChoiceEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[34] + mi := &file_cagent_v1_cagent_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2403,7 +2509,7 @@ func (x *AgentChoiceEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentChoiceEvent.ProtoReflect.Descriptor instead. func (*AgentChoiceEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{34} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{36} } func (x *AgentChoiceEvent) GetContent() string { @@ -2431,7 +2537,7 @@ type AgentChoiceReasoningEvent struct { func (x *AgentChoiceReasoningEvent) Reset() { *x = AgentChoiceReasoningEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[35] + mi := &file_cagent_v1_cagent_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2443,7 +2549,7 @@ func (x *AgentChoiceReasoningEvent) String() string { func (*AgentChoiceReasoningEvent) ProtoMessage() {} func (x *AgentChoiceReasoningEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[35] + mi := &file_cagent_v1_cagent_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2456,7 +2562,7 @@ func (x *AgentChoiceReasoningEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentChoiceReasoningEvent.ProtoReflect.Descriptor instead. func (*AgentChoiceReasoningEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{35} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{37} } func (x *AgentChoiceReasoningEvent) GetContent() string { @@ -2485,7 +2591,7 @@ type PartialToolCallEvent struct { func (x *PartialToolCallEvent) Reset() { *x = PartialToolCallEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[36] + mi := &file_cagent_v1_cagent_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2497,7 +2603,7 @@ func (x *PartialToolCallEvent) String() string { func (*PartialToolCallEvent) ProtoMessage() {} func (x *PartialToolCallEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[36] + mi := &file_cagent_v1_cagent_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2510,7 +2616,7 @@ func (x *PartialToolCallEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use PartialToolCallEvent.ProtoReflect.Descriptor instead. func (*PartialToolCallEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{36} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{38} } func (x *PartialToolCallEvent) GetToolCall() *ToolCall { @@ -2546,7 +2652,7 @@ type ToolCallEvent struct { func (x *ToolCallEvent) Reset() { *x = ToolCallEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[37] + mi := &file_cagent_v1_cagent_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2558,7 +2664,7 @@ func (x *ToolCallEvent) String() string { func (*ToolCallEvent) ProtoMessage() {} func (x *ToolCallEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[37] + mi := &file_cagent_v1_cagent_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2571,7 +2677,7 @@ func (x *ToolCallEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ToolCallEvent.ProtoReflect.Descriptor instead. func (*ToolCallEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{37} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{39} } func (x *ToolCallEvent) GetToolCall() *ToolCall { @@ -2607,7 +2713,7 @@ type ToolCallConfirmationEvent struct { func (x *ToolCallConfirmationEvent) Reset() { *x = ToolCallConfirmationEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[38] + mi := &file_cagent_v1_cagent_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2619,7 +2725,7 @@ func (x *ToolCallConfirmationEvent) String() string { func (*ToolCallConfirmationEvent) ProtoMessage() {} func (x *ToolCallConfirmationEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[38] + mi := &file_cagent_v1_cagent_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2632,7 +2738,7 @@ func (x *ToolCallConfirmationEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ToolCallConfirmationEvent.ProtoReflect.Descriptor instead. func (*ToolCallConfirmationEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{38} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{40} } func (x *ToolCallConfirmationEvent) GetToolCall() *ToolCall { @@ -2670,7 +2776,7 @@ type ToolCallResponseEvent struct { func (x *ToolCallResponseEvent) Reset() { *x = ToolCallResponseEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[39] + mi := &file_cagent_v1_cagent_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2682,7 +2788,7 @@ func (x *ToolCallResponseEvent) String() string { func (*ToolCallResponseEvent) ProtoMessage() {} func (x *ToolCallResponseEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[39] + mi := &file_cagent_v1_cagent_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2695,7 +2801,7 @@ func (x *ToolCallResponseEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ToolCallResponseEvent.ProtoReflect.Descriptor instead. func (*ToolCallResponseEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{39} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{41} } func (x *ToolCallResponseEvent) GetToolCall() *ToolCall { @@ -2744,7 +2850,7 @@ type ErrorEvent struct { func (x *ErrorEvent) Reset() { *x = ErrorEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[40] + mi := &file_cagent_v1_cagent_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2756,7 +2862,7 @@ func (x *ErrorEvent) String() string { func (*ErrorEvent) ProtoMessage() {} func (x *ErrorEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[40] + mi := &file_cagent_v1_cagent_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2769,7 +2875,7 @@ func (x *ErrorEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ErrorEvent.ProtoReflect.Descriptor instead. func (*ErrorEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{40} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{42} } func (x *ErrorEvent) GetError() string { @@ -2797,7 +2903,7 @@ type WarningEvent struct { func (x *WarningEvent) Reset() { *x = WarningEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[41] + mi := &file_cagent_v1_cagent_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2809,7 +2915,7 @@ func (x *WarningEvent) String() string { func (*WarningEvent) ProtoMessage() {} func (x *WarningEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[41] + mi := &file_cagent_v1_cagent_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2822,7 +2928,7 @@ func (x *WarningEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use WarningEvent.ProtoReflect.Descriptor instead. func (*WarningEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{41} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{43} } func (x *WarningEvent) GetMessage() string { @@ -2851,7 +2957,7 @@ type TokenUsageEvent struct { func (x *TokenUsageEvent) Reset() { *x = TokenUsageEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[42] + mi := &file_cagent_v1_cagent_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2863,7 +2969,7 @@ func (x *TokenUsageEvent) String() string { func (*TokenUsageEvent) ProtoMessage() {} func (x *TokenUsageEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[42] + mi := &file_cagent_v1_cagent_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2876,7 +2982,7 @@ func (x *TokenUsageEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use TokenUsageEvent.ProtoReflect.Descriptor instead. func (*TokenUsageEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{42} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{44} } func (x *TokenUsageEvent) GetSessionId() string { @@ -2915,7 +3021,7 @@ type LastMessageUsage struct { func (x *LastMessageUsage) Reset() { *x = LastMessageUsage{} - mi := &file_cagent_v1_cagent_proto_msgTypes[43] + mi := &file_cagent_v1_cagent_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2927,7 +3033,7 @@ func (x *LastMessageUsage) String() string { func (*LastMessageUsage) ProtoMessage() {} func (x *LastMessageUsage) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[43] + mi := &file_cagent_v1_cagent_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2940,7 +3046,7 @@ func (x *LastMessageUsage) ProtoReflect() protoreflect.Message { // Deprecated: Use LastMessageUsage.ProtoReflect.Descriptor instead. func (*LastMessageUsage) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{43} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{45} } func (x *LastMessageUsage) GetInputTokens() int64 { @@ -3000,7 +3106,7 @@ type Usage struct { func (x *Usage) Reset() { *x = Usage{} - mi := &file_cagent_v1_cagent_proto_msgTypes[44] + mi := &file_cagent_v1_cagent_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3012,7 +3118,7 @@ func (x *Usage) String() string { func (*Usage) ProtoMessage() {} func (x *Usage) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[44] + mi := &file_cagent_v1_cagent_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3025,7 +3131,7 @@ func (x *Usage) ProtoReflect() protoreflect.Message { // Deprecated: Use Usage.ProtoReflect.Descriptor instead. func (*Usage) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{44} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{46} } func (x *Usage) GetInputTokens() int64 { @@ -3082,7 +3188,7 @@ type SessionTitleEvent struct { func (x *SessionTitleEvent) Reset() { *x = SessionTitleEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[45] + mi := &file_cagent_v1_cagent_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3094,7 +3200,7 @@ func (x *SessionTitleEvent) String() string { func (*SessionTitleEvent) ProtoMessage() {} func (x *SessionTitleEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[45] + mi := &file_cagent_v1_cagent_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3107,7 +3213,7 @@ func (x *SessionTitleEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionTitleEvent.ProtoReflect.Descriptor instead. func (*SessionTitleEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{45} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{47} } func (x *SessionTitleEvent) GetSessionId() string { @@ -3143,7 +3249,7 @@ type SessionSummaryEvent struct { func (x *SessionSummaryEvent) Reset() { *x = SessionSummaryEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[46] + mi := &file_cagent_v1_cagent_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3155,7 +3261,7 @@ func (x *SessionSummaryEvent) String() string { func (*SessionSummaryEvent) ProtoMessage() {} func (x *SessionSummaryEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[46] + mi := &file_cagent_v1_cagent_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3168,7 +3274,7 @@ func (x *SessionSummaryEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionSummaryEvent.ProtoReflect.Descriptor instead. func (*SessionSummaryEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{46} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{48} } func (x *SessionSummaryEvent) GetSessionId() string { @@ -3204,7 +3310,7 @@ type SessionCompactionEvent struct { func (x *SessionCompactionEvent) Reset() { *x = SessionCompactionEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[47] + mi := &file_cagent_v1_cagent_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3216,7 +3322,7 @@ func (x *SessionCompactionEvent) String() string { func (*SessionCompactionEvent) ProtoMessage() {} func (x *SessionCompactionEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[47] + mi := &file_cagent_v1_cagent_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3229,7 +3335,7 @@ func (x *SessionCompactionEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionCompactionEvent.ProtoReflect.Descriptor instead. func (*SessionCompactionEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{47} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{49} } func (x *SessionCompactionEvent) GetSessionId() string { @@ -3266,7 +3372,7 @@ type ElicitationRequestEvent struct { func (x *ElicitationRequestEvent) Reset() { *x = ElicitationRequestEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[48] + mi := &file_cagent_v1_cagent_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3278,7 +3384,7 @@ func (x *ElicitationRequestEvent) String() string { func (*ElicitationRequestEvent) ProtoMessage() {} func (x *ElicitationRequestEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[48] + mi := &file_cagent_v1_cagent_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3291,7 +3397,7 @@ func (x *ElicitationRequestEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ElicitationRequestEvent.ProtoReflect.Descriptor instead. func (*ElicitationRequestEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{48} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{50} } func (x *ElicitationRequestEvent) GetMessage() string { @@ -3333,7 +3439,7 @@ type AuthorizationEvent struct { func (x *AuthorizationEvent) Reset() { *x = AuthorizationEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[49] + mi := &file_cagent_v1_cagent_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3345,7 +3451,7 @@ func (x *AuthorizationEvent) String() string { func (*AuthorizationEvent) ProtoMessage() {} func (x *AuthorizationEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[49] + mi := &file_cagent_v1_cagent_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3358,7 +3464,7 @@ func (x *AuthorizationEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AuthorizationEvent.ProtoReflect.Descriptor instead. func (*AuthorizationEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{49} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{51} } func (x *AuthorizationEvent) GetConfirmation() string { @@ -3386,7 +3492,7 @@ type MaxIterationsReachedEvent struct { func (x *MaxIterationsReachedEvent) Reset() { *x = MaxIterationsReachedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[50] + mi := &file_cagent_v1_cagent_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3398,7 +3504,7 @@ func (x *MaxIterationsReachedEvent) String() string { func (*MaxIterationsReachedEvent) ProtoMessage() {} func (x *MaxIterationsReachedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[50] + mi := &file_cagent_v1_cagent_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3411,7 +3517,7 @@ func (x *MaxIterationsReachedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use MaxIterationsReachedEvent.ProtoReflect.Descriptor instead. func (*MaxIterationsReachedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{50} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{52} } func (x *MaxIterationsReachedEvent) GetMaxIterations() int32 { @@ -3438,7 +3544,7 @@ type MCPInitStartedEvent struct { func (x *MCPInitStartedEvent) Reset() { *x = MCPInitStartedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[51] + mi := &file_cagent_v1_cagent_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3450,7 +3556,7 @@ func (x *MCPInitStartedEvent) String() string { func (*MCPInitStartedEvent) ProtoMessage() {} func (x *MCPInitStartedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[51] + mi := &file_cagent_v1_cagent_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3463,7 +3569,7 @@ func (x *MCPInitStartedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use MCPInitStartedEvent.ProtoReflect.Descriptor instead. func (*MCPInitStartedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{51} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{53} } func (x *MCPInitStartedEvent) GetAgentName() string { @@ -3483,7 +3589,7 @@ type MCPInitFinishedEvent struct { func (x *MCPInitFinishedEvent) Reset() { *x = MCPInitFinishedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[52] + mi := &file_cagent_v1_cagent_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3495,7 +3601,7 @@ func (x *MCPInitFinishedEvent) String() string { func (*MCPInitFinishedEvent) ProtoMessage() {} func (x *MCPInitFinishedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[52] + mi := &file_cagent_v1_cagent_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3508,7 +3614,7 @@ func (x *MCPInitFinishedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use MCPInitFinishedEvent.ProtoReflect.Descriptor instead. func (*MCPInitFinishedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{52} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{54} } func (x *MCPInitFinishedEvent) GetAgentName() string { @@ -3531,7 +3637,7 @@ type AgentInfoEvent struct { func (x *AgentInfoEvent) Reset() { *x = AgentInfoEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[53] + mi := &file_cagent_v1_cagent_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3543,7 +3649,7 @@ func (x *AgentInfoEvent) String() string { func (*AgentInfoEvent) ProtoMessage() {} func (x *AgentInfoEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[53] + mi := &file_cagent_v1_cagent_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3556,7 +3662,7 @@ func (x *AgentInfoEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentInfoEvent.ProtoReflect.Descriptor instead. func (*AgentInfoEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{53} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{55} } func (x *AgentInfoEvent) GetAgentName() string { @@ -3600,7 +3706,7 @@ type AgentDetails struct { func (x *AgentDetails) Reset() { *x = AgentDetails{} - mi := &file_cagent_v1_cagent_proto_msgTypes[54] + mi := &file_cagent_v1_cagent_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3612,7 +3718,7 @@ func (x *AgentDetails) String() string { func (*AgentDetails) ProtoMessage() {} func (x *AgentDetails) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[54] + mi := &file_cagent_v1_cagent_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3625,7 +3731,7 @@ func (x *AgentDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentDetails.ProtoReflect.Descriptor instead. func (*AgentDetails) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{54} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{56} } func (x *AgentDetails) GetName() string { @@ -3668,7 +3774,7 @@ type TeamInfoEvent struct { func (x *TeamInfoEvent) Reset() { *x = TeamInfoEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[55] + mi := &file_cagent_v1_cagent_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3680,7 +3786,7 @@ func (x *TeamInfoEvent) String() string { func (*TeamInfoEvent) ProtoMessage() {} func (x *TeamInfoEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[55] + mi := &file_cagent_v1_cagent_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3693,7 +3799,7 @@ func (x *TeamInfoEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use TeamInfoEvent.ProtoReflect.Descriptor instead. func (*TeamInfoEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{55} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{57} } func (x *TeamInfoEvent) GetAvailableAgents() []*AgentDetails { @@ -3730,7 +3836,7 @@ type AgentSwitchingEvent struct { func (x *AgentSwitchingEvent) Reset() { *x = AgentSwitchingEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[56] + mi := &file_cagent_v1_cagent_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3742,7 +3848,7 @@ func (x *AgentSwitchingEvent) String() string { func (*AgentSwitchingEvent) ProtoMessage() {} func (x *AgentSwitchingEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[56] + mi := &file_cagent_v1_cagent_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3755,7 +3861,7 @@ func (x *AgentSwitchingEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentSwitchingEvent.ProtoReflect.Descriptor instead. func (*AgentSwitchingEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{56} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{58} } func (x *AgentSwitchingEvent) GetSwitching() bool { @@ -3798,7 +3904,7 @@ type ToolsetInfoEvent struct { func (x *ToolsetInfoEvent) Reset() { *x = ToolsetInfoEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[57] + mi := &file_cagent_v1_cagent_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3810,7 +3916,7 @@ func (x *ToolsetInfoEvent) String() string { func (*ToolsetInfoEvent) ProtoMessage() {} func (x *ToolsetInfoEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[57] + mi := &file_cagent_v1_cagent_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3823,7 +3929,7 @@ func (x *ToolsetInfoEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ToolsetInfoEvent.ProtoReflect.Descriptor instead. func (*ToolsetInfoEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{57} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{59} } func (x *ToolsetInfoEvent) GetAvailableTools() int32 { @@ -3859,7 +3965,7 @@ type RAGIndexingStartedEvent struct { func (x *RAGIndexingStartedEvent) Reset() { *x = RAGIndexingStartedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[58] + mi := &file_cagent_v1_cagent_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3871,7 +3977,7 @@ func (x *RAGIndexingStartedEvent) String() string { func (*RAGIndexingStartedEvent) ProtoMessage() {} func (x *RAGIndexingStartedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[58] + mi := &file_cagent_v1_cagent_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3884,7 +3990,7 @@ func (x *RAGIndexingStartedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RAGIndexingStartedEvent.ProtoReflect.Descriptor instead. func (*RAGIndexingStartedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{58} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{60} } func (x *RAGIndexingStartedEvent) GetRagName() string { @@ -3922,7 +4028,7 @@ type RAGIndexingProgressEvent struct { func (x *RAGIndexingProgressEvent) Reset() { *x = RAGIndexingProgressEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[59] + mi := &file_cagent_v1_cagent_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3934,7 +4040,7 @@ func (x *RAGIndexingProgressEvent) String() string { func (*RAGIndexingProgressEvent) ProtoMessage() {} func (x *RAGIndexingProgressEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[59] + mi := &file_cagent_v1_cagent_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3947,7 +4053,7 @@ func (x *RAGIndexingProgressEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RAGIndexingProgressEvent.ProtoReflect.Descriptor instead. func (*RAGIndexingProgressEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{59} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{61} } func (x *RAGIndexingProgressEvent) GetRagName() string { @@ -3997,7 +4103,7 @@ type RAGIndexingCompletedEvent struct { func (x *RAGIndexingCompletedEvent) Reset() { *x = RAGIndexingCompletedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[60] + mi := &file_cagent_v1_cagent_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4009,7 +4115,7 @@ func (x *RAGIndexingCompletedEvent) String() string { func (*RAGIndexingCompletedEvent) ProtoMessage() {} func (x *RAGIndexingCompletedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[60] + mi := &file_cagent_v1_cagent_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4022,7 +4128,7 @@ func (x *RAGIndexingCompletedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RAGIndexingCompletedEvent.ProtoReflect.Descriptor instead. func (*RAGIndexingCompletedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{60} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{62} } func (x *RAGIndexingCompletedEvent) GetRagName() string { @@ -4059,7 +4165,7 @@ type HookBlockedEvent struct { func (x *HookBlockedEvent) Reset() { *x = HookBlockedEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[61] + mi := &file_cagent_v1_cagent_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4071,7 +4177,7 @@ func (x *HookBlockedEvent) String() string { func (*HookBlockedEvent) ProtoMessage() {} func (x *HookBlockedEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[61] + mi := &file_cagent_v1_cagent_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4084,7 +4190,7 @@ func (x *HookBlockedEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use HookBlockedEvent.ProtoReflect.Descriptor instead. func (*HookBlockedEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{61} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{63} } func (x *HookBlockedEvent) GetToolCall() *ToolCall { @@ -4125,7 +4231,7 @@ type ShellOutputEvent struct { func (x *ShellOutputEvent) Reset() { *x = ShellOutputEvent{} - mi := &file_cagent_v1_cagent_proto_msgTypes[62] + mi := &file_cagent_v1_cagent_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4137,7 +4243,7 @@ func (x *ShellOutputEvent) String() string { func (*ShellOutputEvent) ProtoMessage() {} func (x *ShellOutputEvent) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[62] + mi := &file_cagent_v1_cagent_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4150,7 +4256,7 @@ func (x *ShellOutputEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use ShellOutputEvent.ProtoReflect.Descriptor instead. func (*ShellOutputEvent) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{62} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{64} } func (x *ShellOutputEvent) GetOutput() string { @@ -4169,7 +4275,7 @@ type PingRequest struct { func (x *PingRequest) Reset() { *x = PingRequest{} - mi := &file_cagent_v1_cagent_proto_msgTypes[63] + mi := &file_cagent_v1_cagent_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4181,7 +4287,7 @@ func (x *PingRequest) String() string { func (*PingRequest) ProtoMessage() {} func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[63] + mi := &file_cagent_v1_cagent_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4194,7 +4300,7 @@ func (x *PingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. func (*PingRequest) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{63} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{65} } // PingResponse is the response for Ping. @@ -4207,7 +4313,7 @@ type PingResponse struct { func (x *PingResponse) Reset() { *x = PingResponse{} - mi := &file_cagent_v1_cagent_proto_msgTypes[64] + mi := &file_cagent_v1_cagent_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4219,7 +4325,7 @@ func (x *PingResponse) String() string { func (*PingResponse) ProtoMessage() {} func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_cagent_v1_cagent_proto_msgTypes[64] + mi := &file_cagent_v1_cagent_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4232,7 +4338,7 @@ func (x *PingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. func (*PingResponse) Descriptor() ([]byte, []int) { - return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{64} + return file_cagent_v1_cagent_proto_rawDescGZIP(), []int{66} } func (x *PingResponse) GetStatus() string { @@ -4324,7 +4430,15 @@ const file_cagent_v1_cagent_proto_rawDesc = "" + "\x19ToggleToolApprovalRequest\x12\x1d\n" + "\n" + "session_id\x18\x01 \x01(\tR\tsessionId\"\x1c\n" + - "\x1aToggleToolApprovalResponse\"t\n" + + "\x1aToggleToolApprovalResponse\"P\n" + + "\x19UpdateSessionTitleRequest\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\"Q\n" + + "\x1aUpdateSessionTitleResponse\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\"t\n" + "\x18ResumeElicitationRequest\x12\x1d\n" + "\n" + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x16\n" + @@ -4561,7 +4675,7 @@ const file_cagent_v1_cagent_proto_rawDesc = "" + "\x06output\x18\x01 \x01(\tR\x06output\"\r\n" + "\vPingRequest\"&\n" + "\fPingResponse\x12\x16\n" + - "\x06status\x18\x01 \x01(\tR\x06status2\xee\x06\n" + + "\x06status\x18\x01 \x01(\tR\x06status2\xd1\a\n" + "\fAgentService\x12I\n" + "\n" + "ListAgents\x12\x1c.cagent.v1.ListAgentsRequest\x1a\x1d.cagent.v1.ListAgentsResponse\x12C\n" + @@ -4572,7 +4686,8 @@ const file_cagent_v1_cagent_proto_rawDesc = "" + "\rCreateSession\x12\x1f.cagent.v1.CreateSessionRequest\x1a .cagent.v1.CreateSessionResponse\x12R\n" + "\rDeleteSession\x12\x1f.cagent.v1.DeleteSessionRequest\x1a .cagent.v1.DeleteSessionResponse\x12R\n" + "\rResumeSession\x12\x1f.cagent.v1.ResumeSessionRequest\x1a .cagent.v1.ResumeSessionResponse\x12a\n" + - "\x12ToggleToolApproval\x12$.cagent.v1.ToggleToolApprovalRequest\x1a%.cagent.v1.ToggleToolApprovalResponse\x12^\n" + + "\x12ToggleToolApproval\x12$.cagent.v1.ToggleToolApprovalRequest\x1a%.cagent.v1.ToggleToolApprovalResponse\x12a\n" + + "\x12UpdateSessionTitle\x12$.cagent.v1.UpdateSessionTitleRequest\x1a%.cagent.v1.UpdateSessionTitleResponse\x12^\n" + "\x11ResumeElicitation\x12#.cagent.v1.ResumeElicitationRequest\x1a$.cagent.v1.ResumeElicitationResponse\x12:\n" + "\bRunAgent\x12\x1a.cagent.v1.RunAgentRequest\x1a\x10.cagent.v1.Event0\x01\x127\n" + "\x04Ping\x12\x16.cagent.v1.PingRequest\x1a\x17.cagent.v1.PingResponseB\x98\x01\n" + @@ -4591,7 +4706,7 @@ func file_cagent_v1_cagent_proto_rawDescGZIP() []byte { return file_cagent_v1_cagent_proto_rawDescData } -var file_cagent_v1_cagent_proto_msgTypes = make([]protoimpl.MessageInfo, 65) +var file_cagent_v1_cagent_proto_msgTypes = make([]protoimpl.MessageInfo, 67) var file_cagent_v1_cagent_proto_goTypes = []any{ (*Agent)(nil), // 0: cagent.v1.Agent (*ListAgentsRequest)(nil), // 1: cagent.v1.ListAgentsRequest @@ -4615,49 +4730,51 @@ var file_cagent_v1_cagent_proto_goTypes = []any{ (*ResumeSessionResponse)(nil), // 19: cagent.v1.ResumeSessionResponse (*ToggleToolApprovalRequest)(nil), // 20: cagent.v1.ToggleToolApprovalRequest (*ToggleToolApprovalResponse)(nil), // 21: cagent.v1.ToggleToolApprovalResponse - (*ResumeElicitationRequest)(nil), // 22: cagent.v1.ResumeElicitationRequest - (*ResumeElicitationResponse)(nil), // 23: cagent.v1.ResumeElicitationResponse - (*InputMessage)(nil), // 24: cagent.v1.InputMessage - (*MessagePart)(nil), // 25: cagent.v1.MessagePart - (*RunAgentRequest)(nil), // 26: cagent.v1.RunAgentRequest - (*Event)(nil), // 27: cagent.v1.Event - (*Tool)(nil), // 28: cagent.v1.Tool - (*ToolAnnotations)(nil), // 29: cagent.v1.ToolAnnotations - (*ToolCallResult)(nil), // 30: cagent.v1.ToolCallResult - (*UserMessageEvent)(nil), // 31: cagent.v1.UserMessageEvent - (*StreamStartedEvent)(nil), // 32: cagent.v1.StreamStartedEvent - (*StreamStoppedEvent)(nil), // 33: cagent.v1.StreamStoppedEvent - (*AgentChoiceEvent)(nil), // 34: cagent.v1.AgentChoiceEvent - (*AgentChoiceReasoningEvent)(nil), // 35: cagent.v1.AgentChoiceReasoningEvent - (*PartialToolCallEvent)(nil), // 36: cagent.v1.PartialToolCallEvent - (*ToolCallEvent)(nil), // 37: cagent.v1.ToolCallEvent - (*ToolCallConfirmationEvent)(nil), // 38: cagent.v1.ToolCallConfirmationEvent - (*ToolCallResponseEvent)(nil), // 39: cagent.v1.ToolCallResponseEvent - (*ErrorEvent)(nil), // 40: cagent.v1.ErrorEvent - (*WarningEvent)(nil), // 41: cagent.v1.WarningEvent - (*TokenUsageEvent)(nil), // 42: cagent.v1.TokenUsageEvent - (*LastMessageUsage)(nil), // 43: cagent.v1.LastMessageUsage - (*Usage)(nil), // 44: cagent.v1.Usage - (*SessionTitleEvent)(nil), // 45: cagent.v1.SessionTitleEvent - (*SessionSummaryEvent)(nil), // 46: cagent.v1.SessionSummaryEvent - (*SessionCompactionEvent)(nil), // 47: cagent.v1.SessionCompactionEvent - (*ElicitationRequestEvent)(nil), // 48: cagent.v1.ElicitationRequestEvent - (*AuthorizationEvent)(nil), // 49: cagent.v1.AuthorizationEvent - (*MaxIterationsReachedEvent)(nil), // 50: cagent.v1.MaxIterationsReachedEvent - (*MCPInitStartedEvent)(nil), // 51: cagent.v1.MCPInitStartedEvent - (*MCPInitFinishedEvent)(nil), // 52: cagent.v1.MCPInitFinishedEvent - (*AgentInfoEvent)(nil), // 53: cagent.v1.AgentInfoEvent - (*AgentDetails)(nil), // 54: cagent.v1.AgentDetails - (*TeamInfoEvent)(nil), // 55: cagent.v1.TeamInfoEvent - (*AgentSwitchingEvent)(nil), // 56: cagent.v1.AgentSwitchingEvent - (*ToolsetInfoEvent)(nil), // 57: cagent.v1.ToolsetInfoEvent - (*RAGIndexingStartedEvent)(nil), // 58: cagent.v1.RAGIndexingStartedEvent - (*RAGIndexingProgressEvent)(nil), // 59: cagent.v1.RAGIndexingProgressEvent - (*RAGIndexingCompletedEvent)(nil), // 60: cagent.v1.RAGIndexingCompletedEvent - (*HookBlockedEvent)(nil), // 61: cagent.v1.HookBlockedEvent - (*ShellOutputEvent)(nil), // 62: cagent.v1.ShellOutputEvent - (*PingRequest)(nil), // 63: cagent.v1.PingRequest - (*PingResponse)(nil), // 64: cagent.v1.PingResponse + (*UpdateSessionTitleRequest)(nil), // 22: cagent.v1.UpdateSessionTitleRequest + (*UpdateSessionTitleResponse)(nil), // 23: cagent.v1.UpdateSessionTitleResponse + (*ResumeElicitationRequest)(nil), // 24: cagent.v1.ResumeElicitationRequest + (*ResumeElicitationResponse)(nil), // 25: cagent.v1.ResumeElicitationResponse + (*InputMessage)(nil), // 26: cagent.v1.InputMessage + (*MessagePart)(nil), // 27: cagent.v1.MessagePart + (*RunAgentRequest)(nil), // 28: cagent.v1.RunAgentRequest + (*Event)(nil), // 29: cagent.v1.Event + (*Tool)(nil), // 30: cagent.v1.Tool + (*ToolAnnotations)(nil), // 31: cagent.v1.ToolAnnotations + (*ToolCallResult)(nil), // 32: cagent.v1.ToolCallResult + (*UserMessageEvent)(nil), // 33: cagent.v1.UserMessageEvent + (*StreamStartedEvent)(nil), // 34: cagent.v1.StreamStartedEvent + (*StreamStoppedEvent)(nil), // 35: cagent.v1.StreamStoppedEvent + (*AgentChoiceEvent)(nil), // 36: cagent.v1.AgentChoiceEvent + (*AgentChoiceReasoningEvent)(nil), // 37: cagent.v1.AgentChoiceReasoningEvent + (*PartialToolCallEvent)(nil), // 38: cagent.v1.PartialToolCallEvent + (*ToolCallEvent)(nil), // 39: cagent.v1.ToolCallEvent + (*ToolCallConfirmationEvent)(nil), // 40: cagent.v1.ToolCallConfirmationEvent + (*ToolCallResponseEvent)(nil), // 41: cagent.v1.ToolCallResponseEvent + (*ErrorEvent)(nil), // 42: cagent.v1.ErrorEvent + (*WarningEvent)(nil), // 43: cagent.v1.WarningEvent + (*TokenUsageEvent)(nil), // 44: cagent.v1.TokenUsageEvent + (*LastMessageUsage)(nil), // 45: cagent.v1.LastMessageUsage + (*Usage)(nil), // 46: cagent.v1.Usage + (*SessionTitleEvent)(nil), // 47: cagent.v1.SessionTitleEvent + (*SessionSummaryEvent)(nil), // 48: cagent.v1.SessionSummaryEvent + (*SessionCompactionEvent)(nil), // 49: cagent.v1.SessionCompactionEvent + (*ElicitationRequestEvent)(nil), // 50: cagent.v1.ElicitationRequestEvent + (*AuthorizationEvent)(nil), // 51: cagent.v1.AuthorizationEvent + (*MaxIterationsReachedEvent)(nil), // 52: cagent.v1.MaxIterationsReachedEvent + (*MCPInitStartedEvent)(nil), // 53: cagent.v1.MCPInitStartedEvent + (*MCPInitFinishedEvent)(nil), // 54: cagent.v1.MCPInitFinishedEvent + (*AgentInfoEvent)(nil), // 55: cagent.v1.AgentInfoEvent + (*AgentDetails)(nil), // 56: cagent.v1.AgentDetails + (*TeamInfoEvent)(nil), // 57: cagent.v1.TeamInfoEvent + (*AgentSwitchingEvent)(nil), // 58: cagent.v1.AgentSwitchingEvent + (*ToolsetInfoEvent)(nil), // 59: cagent.v1.ToolsetInfoEvent + (*RAGIndexingStartedEvent)(nil), // 60: cagent.v1.RAGIndexingStartedEvent + (*RAGIndexingProgressEvent)(nil), // 61: cagent.v1.RAGIndexingProgressEvent + (*RAGIndexingCompletedEvent)(nil), // 62: cagent.v1.RAGIndexingCompletedEvent + (*HookBlockedEvent)(nil), // 63: cagent.v1.HookBlockedEvent + (*ShellOutputEvent)(nil), // 64: cagent.v1.ShellOutputEvent + (*PingRequest)(nil), // 65: cagent.v1.PingRequest + (*PingResponse)(nil), // 66: cagent.v1.PingResponse } var file_cagent_v1_cagent_proto_depIdxs = []int32{ 0, // 0: cagent.v1.ListAgentsResponse.agents:type_name -> cagent.v1.Agent @@ -4667,52 +4784,52 @@ var file_cagent_v1_cagent_proto_depIdxs = []int32{ 8, // 4: cagent.v1.Session.messages:type_name -> cagent.v1.Message 11, // 5: cagent.v1.GetSessionResponse.session:type_name -> cagent.v1.Session 11, // 6: cagent.v1.CreateSessionResponse.session:type_name -> cagent.v1.Session - 25, // 7: cagent.v1.InputMessage.multi_content:type_name -> cagent.v1.MessagePart - 24, // 8: cagent.v1.RunAgentRequest.messages:type_name -> cagent.v1.InputMessage - 31, // 9: cagent.v1.Event.user_message:type_name -> cagent.v1.UserMessageEvent - 32, // 10: cagent.v1.Event.stream_started:type_name -> cagent.v1.StreamStartedEvent - 33, // 11: cagent.v1.Event.stream_stopped:type_name -> cagent.v1.StreamStoppedEvent - 34, // 12: cagent.v1.Event.agent_choice:type_name -> cagent.v1.AgentChoiceEvent - 35, // 13: cagent.v1.Event.agent_choice_reasoning:type_name -> cagent.v1.AgentChoiceReasoningEvent - 36, // 14: cagent.v1.Event.partial_tool_call:type_name -> cagent.v1.PartialToolCallEvent - 37, // 15: cagent.v1.Event.tool_call:type_name -> cagent.v1.ToolCallEvent - 38, // 16: cagent.v1.Event.tool_call_confirmation:type_name -> cagent.v1.ToolCallConfirmationEvent - 39, // 17: cagent.v1.Event.tool_call_response:type_name -> cagent.v1.ToolCallResponseEvent - 40, // 18: cagent.v1.Event.error:type_name -> cagent.v1.ErrorEvent - 41, // 19: cagent.v1.Event.warning:type_name -> cagent.v1.WarningEvent - 42, // 20: cagent.v1.Event.token_usage:type_name -> cagent.v1.TokenUsageEvent - 45, // 21: cagent.v1.Event.session_title:type_name -> cagent.v1.SessionTitleEvent - 46, // 22: cagent.v1.Event.session_summary:type_name -> cagent.v1.SessionSummaryEvent - 47, // 23: cagent.v1.Event.session_compaction:type_name -> cagent.v1.SessionCompactionEvent - 48, // 24: cagent.v1.Event.elicitation_request:type_name -> cagent.v1.ElicitationRequestEvent - 49, // 25: cagent.v1.Event.authorization:type_name -> cagent.v1.AuthorizationEvent - 50, // 26: cagent.v1.Event.max_iterations_reached:type_name -> cagent.v1.MaxIterationsReachedEvent - 51, // 27: cagent.v1.Event.mcp_init_started:type_name -> cagent.v1.MCPInitStartedEvent - 52, // 28: cagent.v1.Event.mcp_init_finished:type_name -> cagent.v1.MCPInitFinishedEvent - 53, // 29: cagent.v1.Event.agent_info:type_name -> cagent.v1.AgentInfoEvent - 55, // 30: cagent.v1.Event.team_info:type_name -> cagent.v1.TeamInfoEvent - 56, // 31: cagent.v1.Event.agent_switching:type_name -> cagent.v1.AgentSwitchingEvent - 57, // 32: cagent.v1.Event.toolset_info:type_name -> cagent.v1.ToolsetInfoEvent - 58, // 33: cagent.v1.Event.rag_indexing_started:type_name -> cagent.v1.RAGIndexingStartedEvent - 59, // 34: cagent.v1.Event.rag_indexing_progress:type_name -> cagent.v1.RAGIndexingProgressEvent - 60, // 35: cagent.v1.Event.rag_indexing_completed:type_name -> cagent.v1.RAGIndexingCompletedEvent - 61, // 36: cagent.v1.Event.hook_blocked:type_name -> cagent.v1.HookBlockedEvent - 62, // 37: cagent.v1.Event.shell_output:type_name -> cagent.v1.ShellOutputEvent - 29, // 38: cagent.v1.Tool.annotations:type_name -> cagent.v1.ToolAnnotations + 27, // 7: cagent.v1.InputMessage.multi_content:type_name -> cagent.v1.MessagePart + 26, // 8: cagent.v1.RunAgentRequest.messages:type_name -> cagent.v1.InputMessage + 33, // 9: cagent.v1.Event.user_message:type_name -> cagent.v1.UserMessageEvent + 34, // 10: cagent.v1.Event.stream_started:type_name -> cagent.v1.StreamStartedEvent + 35, // 11: cagent.v1.Event.stream_stopped:type_name -> cagent.v1.StreamStoppedEvent + 36, // 12: cagent.v1.Event.agent_choice:type_name -> cagent.v1.AgentChoiceEvent + 37, // 13: cagent.v1.Event.agent_choice_reasoning:type_name -> cagent.v1.AgentChoiceReasoningEvent + 38, // 14: cagent.v1.Event.partial_tool_call:type_name -> cagent.v1.PartialToolCallEvent + 39, // 15: cagent.v1.Event.tool_call:type_name -> cagent.v1.ToolCallEvent + 40, // 16: cagent.v1.Event.tool_call_confirmation:type_name -> cagent.v1.ToolCallConfirmationEvent + 41, // 17: cagent.v1.Event.tool_call_response:type_name -> cagent.v1.ToolCallResponseEvent + 42, // 18: cagent.v1.Event.error:type_name -> cagent.v1.ErrorEvent + 43, // 19: cagent.v1.Event.warning:type_name -> cagent.v1.WarningEvent + 44, // 20: cagent.v1.Event.token_usage:type_name -> cagent.v1.TokenUsageEvent + 47, // 21: cagent.v1.Event.session_title:type_name -> cagent.v1.SessionTitleEvent + 48, // 22: cagent.v1.Event.session_summary:type_name -> cagent.v1.SessionSummaryEvent + 49, // 23: cagent.v1.Event.session_compaction:type_name -> cagent.v1.SessionCompactionEvent + 50, // 24: cagent.v1.Event.elicitation_request:type_name -> cagent.v1.ElicitationRequestEvent + 51, // 25: cagent.v1.Event.authorization:type_name -> cagent.v1.AuthorizationEvent + 52, // 26: cagent.v1.Event.max_iterations_reached:type_name -> cagent.v1.MaxIterationsReachedEvent + 53, // 27: cagent.v1.Event.mcp_init_started:type_name -> cagent.v1.MCPInitStartedEvent + 54, // 28: cagent.v1.Event.mcp_init_finished:type_name -> cagent.v1.MCPInitFinishedEvent + 55, // 29: cagent.v1.Event.agent_info:type_name -> cagent.v1.AgentInfoEvent + 57, // 30: cagent.v1.Event.team_info:type_name -> cagent.v1.TeamInfoEvent + 58, // 31: cagent.v1.Event.agent_switching:type_name -> cagent.v1.AgentSwitchingEvent + 59, // 32: cagent.v1.Event.toolset_info:type_name -> cagent.v1.ToolsetInfoEvent + 60, // 33: cagent.v1.Event.rag_indexing_started:type_name -> cagent.v1.RAGIndexingStartedEvent + 61, // 34: cagent.v1.Event.rag_indexing_progress:type_name -> cagent.v1.RAGIndexingProgressEvent + 62, // 35: cagent.v1.Event.rag_indexing_completed:type_name -> cagent.v1.RAGIndexingCompletedEvent + 63, // 36: cagent.v1.Event.hook_blocked:type_name -> cagent.v1.HookBlockedEvent + 64, // 37: cagent.v1.Event.shell_output:type_name -> cagent.v1.ShellOutputEvent + 31, // 38: cagent.v1.Tool.annotations:type_name -> cagent.v1.ToolAnnotations 9, // 39: cagent.v1.PartialToolCallEvent.tool_call:type_name -> cagent.v1.ToolCall - 28, // 40: cagent.v1.PartialToolCallEvent.tool_definition:type_name -> cagent.v1.Tool + 30, // 40: cagent.v1.PartialToolCallEvent.tool_definition:type_name -> cagent.v1.Tool 9, // 41: cagent.v1.ToolCallEvent.tool_call:type_name -> cagent.v1.ToolCall - 28, // 42: cagent.v1.ToolCallEvent.tool_definition:type_name -> cagent.v1.Tool + 30, // 42: cagent.v1.ToolCallEvent.tool_definition:type_name -> cagent.v1.Tool 9, // 43: cagent.v1.ToolCallConfirmationEvent.tool_call:type_name -> cagent.v1.ToolCall - 28, // 44: cagent.v1.ToolCallConfirmationEvent.tool_definition:type_name -> cagent.v1.Tool + 30, // 44: cagent.v1.ToolCallConfirmationEvent.tool_definition:type_name -> cagent.v1.Tool 9, // 45: cagent.v1.ToolCallResponseEvent.tool_call:type_name -> cagent.v1.ToolCall - 28, // 46: cagent.v1.ToolCallResponseEvent.tool_definition:type_name -> cagent.v1.Tool - 30, // 47: cagent.v1.ToolCallResponseEvent.result:type_name -> cagent.v1.ToolCallResult - 44, // 48: cagent.v1.TokenUsageEvent.usage:type_name -> cagent.v1.Usage - 43, // 49: cagent.v1.Usage.last_message:type_name -> cagent.v1.LastMessageUsage - 54, // 50: cagent.v1.TeamInfoEvent.available_agents:type_name -> cagent.v1.AgentDetails + 30, // 46: cagent.v1.ToolCallResponseEvent.tool_definition:type_name -> cagent.v1.Tool + 32, // 47: cagent.v1.ToolCallResponseEvent.result:type_name -> cagent.v1.ToolCallResult + 46, // 48: cagent.v1.TokenUsageEvent.usage:type_name -> cagent.v1.Usage + 45, // 49: cagent.v1.Usage.last_message:type_name -> cagent.v1.LastMessageUsage + 56, // 50: cagent.v1.TeamInfoEvent.available_agents:type_name -> cagent.v1.AgentDetails 9, // 51: cagent.v1.HookBlockedEvent.tool_call:type_name -> cagent.v1.ToolCall - 28, // 52: cagent.v1.HookBlockedEvent.tool_definition:type_name -> cagent.v1.Tool + 30, // 52: cagent.v1.HookBlockedEvent.tool_definition:type_name -> cagent.v1.Tool 1, // 53: cagent.v1.AgentService.ListAgents:input_type -> cagent.v1.ListAgentsRequest 3, // 54: cagent.v1.AgentService.GetAgent:input_type -> cagent.v1.GetAgentRequest 6, // 55: cagent.v1.AgentService.ListSessions:input_type -> cagent.v1.ListSessionsRequest @@ -4721,22 +4838,24 @@ var file_cagent_v1_cagent_proto_depIdxs = []int32{ 16, // 58: cagent.v1.AgentService.DeleteSession:input_type -> cagent.v1.DeleteSessionRequest 18, // 59: cagent.v1.AgentService.ResumeSession:input_type -> cagent.v1.ResumeSessionRequest 20, // 60: cagent.v1.AgentService.ToggleToolApproval:input_type -> cagent.v1.ToggleToolApprovalRequest - 22, // 61: cagent.v1.AgentService.ResumeElicitation:input_type -> cagent.v1.ResumeElicitationRequest - 26, // 62: cagent.v1.AgentService.RunAgent:input_type -> cagent.v1.RunAgentRequest - 63, // 63: cagent.v1.AgentService.Ping:input_type -> cagent.v1.PingRequest - 2, // 64: cagent.v1.AgentService.ListAgents:output_type -> cagent.v1.ListAgentsResponse - 4, // 65: cagent.v1.AgentService.GetAgent:output_type -> cagent.v1.GetAgentResponse - 7, // 66: cagent.v1.AgentService.ListSessions:output_type -> cagent.v1.ListSessionsResponse - 13, // 67: cagent.v1.AgentService.GetSession:output_type -> cagent.v1.GetSessionResponse - 15, // 68: cagent.v1.AgentService.CreateSession:output_type -> cagent.v1.CreateSessionResponse - 17, // 69: cagent.v1.AgentService.DeleteSession:output_type -> cagent.v1.DeleteSessionResponse - 19, // 70: cagent.v1.AgentService.ResumeSession:output_type -> cagent.v1.ResumeSessionResponse - 21, // 71: cagent.v1.AgentService.ToggleToolApproval:output_type -> cagent.v1.ToggleToolApprovalResponse - 23, // 72: cagent.v1.AgentService.ResumeElicitation:output_type -> cagent.v1.ResumeElicitationResponse - 27, // 73: cagent.v1.AgentService.RunAgent:output_type -> cagent.v1.Event - 64, // 74: cagent.v1.AgentService.Ping:output_type -> cagent.v1.PingResponse - 64, // [64:75] is the sub-list for method output_type - 53, // [53:64] is the sub-list for method input_type + 22, // 61: cagent.v1.AgentService.UpdateSessionTitle:input_type -> cagent.v1.UpdateSessionTitleRequest + 24, // 62: cagent.v1.AgentService.ResumeElicitation:input_type -> cagent.v1.ResumeElicitationRequest + 28, // 63: cagent.v1.AgentService.RunAgent:input_type -> cagent.v1.RunAgentRequest + 65, // 64: cagent.v1.AgentService.Ping:input_type -> cagent.v1.PingRequest + 2, // 65: cagent.v1.AgentService.ListAgents:output_type -> cagent.v1.ListAgentsResponse + 4, // 66: cagent.v1.AgentService.GetAgent:output_type -> cagent.v1.GetAgentResponse + 7, // 67: cagent.v1.AgentService.ListSessions:output_type -> cagent.v1.ListSessionsResponse + 13, // 68: cagent.v1.AgentService.GetSession:output_type -> cagent.v1.GetSessionResponse + 15, // 69: cagent.v1.AgentService.CreateSession:output_type -> cagent.v1.CreateSessionResponse + 17, // 70: cagent.v1.AgentService.DeleteSession:output_type -> cagent.v1.DeleteSessionResponse + 19, // 71: cagent.v1.AgentService.ResumeSession:output_type -> cagent.v1.ResumeSessionResponse + 21, // 72: cagent.v1.AgentService.ToggleToolApproval:output_type -> cagent.v1.ToggleToolApprovalResponse + 23, // 73: cagent.v1.AgentService.UpdateSessionTitle:output_type -> cagent.v1.UpdateSessionTitleResponse + 25, // 74: cagent.v1.AgentService.ResumeElicitation:output_type -> cagent.v1.ResumeElicitationResponse + 29, // 75: cagent.v1.AgentService.RunAgent:output_type -> cagent.v1.Event + 66, // 76: cagent.v1.AgentService.Ping:output_type -> cagent.v1.PingResponse + 65, // [65:77] is the sub-list for method output_type + 53, // [53:65] is the sub-list for method input_type 53, // [53:53] is the sub-list for extension type_name 53, // [53:53] is the sub-list for extension extendee 0, // [0:53] is the sub-list for field type_name @@ -4747,7 +4866,7 @@ func file_cagent_v1_cagent_proto_init() { if File_cagent_v1_cagent_proto != nil { return } - file_cagent_v1_cagent_proto_msgTypes[27].OneofWrappers = []any{ + file_cagent_v1_cagent_proto_msgTypes[29].OneofWrappers = []any{ (*Event_UserMessage)(nil), (*Event_StreamStarted)(nil), (*Event_StreamStopped)(nil), @@ -4784,7 +4903,7 @@ func file_cagent_v1_cagent_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_cagent_v1_cagent_proto_rawDesc), len(file_cagent_v1_cagent_proto_rawDesc)), NumEnums: 0, - NumMessages: 65, + NumMessages: 67, NumExtensions: 0, NumServices: 1, }, diff --git a/gen/proto/cagent/v1/cagentv1connect/cagent.connect.go b/gen/proto/cagent/v1/cagentv1connect/cagent.connect.go index 526f9dd1c..7aa360109 100644 --- a/gen/proto/cagent/v1/cagentv1connect/cagent.connect.go +++ b/gen/proto/cagent/v1/cagentv1connect/cagent.connect.go @@ -54,6 +54,9 @@ const ( // AgentServiceToggleToolApprovalProcedure is the fully-qualified name of the AgentService's // ToggleToolApproval RPC. AgentServiceToggleToolApprovalProcedure = "/cagent.v1.AgentService/ToggleToolApproval" + // AgentServiceUpdateSessionTitleProcedure is the fully-qualified name of the AgentService's + // UpdateSessionTitle RPC. + AgentServiceUpdateSessionTitleProcedure = "/cagent.v1.AgentService/UpdateSessionTitle" // AgentServiceResumeElicitationProcedure is the fully-qualified name of the AgentService's // ResumeElicitation RPC. AgentServiceResumeElicitationProcedure = "/cagent.v1.AgentService/ResumeElicitation" @@ -81,6 +84,8 @@ type AgentServiceClient interface { ResumeSession(context.Context, *connect.Request[v1.ResumeSessionRequest]) (*connect.Response[v1.ResumeSessionResponse], error) // ToggleToolApproval toggles the YOLO mode for a session. ToggleToolApproval(context.Context, *connect.Request[v1.ToggleToolApprovalRequest]) (*connect.Response[v1.ToggleToolApprovalResponse], error) + // UpdateSessionTitle updates the title of a session. + UpdateSessionTitle(context.Context, *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) // ResumeElicitation resumes an elicitation request. ResumeElicitation(context.Context, *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) // RunAgent runs an agent loop and streams events. @@ -148,6 +153,12 @@ func NewAgentServiceClient(httpClient connect.HTTPClient, baseURL string, opts . connect.WithSchema(agentServiceMethods.ByName("ToggleToolApproval")), connect.WithClientOptions(opts...), ), + updateSessionTitle: connect.NewClient[v1.UpdateSessionTitleRequest, v1.UpdateSessionTitleResponse]( + httpClient, + baseURL+AgentServiceUpdateSessionTitleProcedure, + connect.WithSchema(agentServiceMethods.ByName("UpdateSessionTitle")), + connect.WithClientOptions(opts...), + ), resumeElicitation: connect.NewClient[v1.ResumeElicitationRequest, v1.ResumeElicitationResponse]( httpClient, baseURL+AgentServiceResumeElicitationProcedure, @@ -179,6 +190,7 @@ type agentServiceClient struct { deleteSession *connect.Client[v1.DeleteSessionRequest, v1.DeleteSessionResponse] resumeSession *connect.Client[v1.ResumeSessionRequest, v1.ResumeSessionResponse] toggleToolApproval *connect.Client[v1.ToggleToolApprovalRequest, v1.ToggleToolApprovalResponse] + updateSessionTitle *connect.Client[v1.UpdateSessionTitleRequest, v1.UpdateSessionTitleResponse] resumeElicitation *connect.Client[v1.ResumeElicitationRequest, v1.ResumeElicitationResponse] runAgent *connect.Client[v1.RunAgentRequest, v1.Event] ping *connect.Client[v1.PingRequest, v1.PingResponse] @@ -224,6 +236,11 @@ func (c *agentServiceClient) ToggleToolApproval(ctx context.Context, req *connec return c.toggleToolApproval.CallUnary(ctx, req) } +// UpdateSessionTitle calls cagent.v1.AgentService.UpdateSessionTitle. +func (c *agentServiceClient) UpdateSessionTitle(ctx context.Context, req *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) { + return c.updateSessionTitle.CallUnary(ctx, req) +} + // ResumeElicitation calls cagent.v1.AgentService.ResumeElicitation. func (c *agentServiceClient) ResumeElicitation(ctx context.Context, req *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) { return c.resumeElicitation.CallUnary(ctx, req) @@ -257,6 +274,8 @@ type AgentServiceHandler interface { ResumeSession(context.Context, *connect.Request[v1.ResumeSessionRequest]) (*connect.Response[v1.ResumeSessionResponse], error) // ToggleToolApproval toggles the YOLO mode for a session. ToggleToolApproval(context.Context, *connect.Request[v1.ToggleToolApprovalRequest]) (*connect.Response[v1.ToggleToolApprovalResponse], error) + // UpdateSessionTitle updates the title of a session. + UpdateSessionTitle(context.Context, *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) // ResumeElicitation resumes an elicitation request. ResumeElicitation(context.Context, *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) // RunAgent runs an agent loop and streams events. @@ -320,6 +339,12 @@ func NewAgentServiceHandler(svc AgentServiceHandler, opts ...connect.HandlerOpti connect.WithSchema(agentServiceMethods.ByName("ToggleToolApproval")), connect.WithHandlerOptions(opts...), ) + agentServiceUpdateSessionTitleHandler := connect.NewUnaryHandler( + AgentServiceUpdateSessionTitleProcedure, + svc.UpdateSessionTitle, + connect.WithSchema(agentServiceMethods.ByName("UpdateSessionTitle")), + connect.WithHandlerOptions(opts...), + ) agentServiceResumeElicitationHandler := connect.NewUnaryHandler( AgentServiceResumeElicitationProcedure, svc.ResumeElicitation, @@ -356,6 +381,8 @@ func NewAgentServiceHandler(svc AgentServiceHandler, opts ...connect.HandlerOpti agentServiceResumeSessionHandler.ServeHTTP(w, r) case AgentServiceToggleToolApprovalProcedure: agentServiceToggleToolApprovalHandler.ServeHTTP(w, r) + case AgentServiceUpdateSessionTitleProcedure: + agentServiceUpdateSessionTitleHandler.ServeHTTP(w, r) case AgentServiceResumeElicitationProcedure: agentServiceResumeElicitationHandler.ServeHTTP(w, r) case AgentServiceRunAgentProcedure: @@ -403,6 +430,10 @@ func (UnimplementedAgentServiceHandler) ToggleToolApproval(context.Context, *con return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.ToggleToolApproval is not implemented")) } +func (UnimplementedAgentServiceHandler) UpdateSessionTitle(context.Context, *connect.Request[v1.UpdateSessionTitleRequest]) (*connect.Response[v1.UpdateSessionTitleResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.UpdateSessionTitle is not implemented")) +} + func (UnimplementedAgentServiceHandler) ResumeElicitation(context.Context, *connect.Request[v1.ResumeElicitationRequest]) (*connect.Response[v1.ResumeElicitationResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cagent.v1.AgentService.ResumeElicitation is not implemented")) } diff --git a/pkg/api/types.go b/pkg/api/types.go index 45e96bff7..61f51d9a3 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -159,3 +159,14 @@ type ResumeElicitationRequest struct { Action string `json:"action"` // "accept", "decline", or "cancel" Content map[string]any `json:"content"` // The submitted form data (only present when action is "accept") } + +// UpdateSessionTitleRequest represents a request to update a session's title +type UpdateSessionTitleRequest struct { + Title string `json:"title"` +} + +// UpdateSessionTitleResponse represents the response from updating a session's title +type UpdateSessionTitleResponse struct { + ID string `json:"id"` + Title string `json:"title"` +} diff --git a/pkg/app/app.go b/pkg/app/app.go index 80129d4f8..8ea493d41 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -7,6 +7,7 @@ import ( "os/exec" "slices" "strings" + "sync/atomic" "time" tea "charm.land/bubbletea/v2" @@ -19,6 +20,7 @@ import ( "github.com/docker/cagent/pkg/config/types" "github.com/docker/cagent/pkg/runtime" "github.com/docker/cagent/pkg/session" + "github.com/docker/cagent/pkg/sessiontitle" "github.com/docker/cagent/pkg/tools" mcptools "github.com/docker/cagent/pkg/tools/mcp" "github.com/docker/cagent/pkg/tui/messages" @@ -32,8 +34,10 @@ type App struct { events chan tea.Msg throttleDuration time.Duration cancel context.CancelFunc - currentAgentModel string // Tracks the current agent's model ID from AgentInfoEvent - exitAfterFirstResponse bool // Exit TUI after first assistant response completes + currentAgentModel string // Tracks the current agent's model ID from AgentInfoEvent + exitAfterFirstResponse bool // Exit TUI after first assistant response completes + titleGenerating atomic.Bool // True when title generation is in progress + titleGen *sessiontitle.Generator // Title generator for local runtime (nil for remote) } // Opt is an option for creating a new App. @@ -60,6 +64,14 @@ func WithExitAfterFirstResponse() Opt { } } +// WithTitleGenerator sets the title generator for local title generation. +// If not set, title generation will be handled by the runtime (for remote) or skipped. +func WithTitleGenerator(gen *sessiontitle.Generator) Opt { + return func(a *App) { + a.titleGen = gen + } +} + func New(ctx context.Context, rt runtime.Runtime, sess *session.Session, opts ...Opt) *App { app := &App{ runtime: rt, @@ -222,6 +234,13 @@ func (a *App) EmitStartupInfo(ctx context.Context, events chan runtime.Event) { // Run one agent loop func (a *App) Run(ctx context.Context, cancel context.CancelFunc, message string, attachments map[string]string) { a.cancel = cancel + + // If this is the first message and no title exists, start local title generation + if a.session.Title == "" && a.titleGen != nil { + a.titleGenerating.Store(true) + go a.generateTitle(ctx, []string{message}) + } + go func() { if len(attachments) > 0 { multiContent := []chat.MessagePart{ @@ -247,6 +266,12 @@ func (a *App) Run(ctx context.Context, cancel context.CancelFunc, message string if ctx.Err() != nil { continue } + + // Clear titleGenerating flag when title is generated (from server for remote runtime) + if _, ok := event.(*runtime.SessionTitleEvent); ok { + a.titleGenerating.Store(false) + } + a.events <- event } }() @@ -256,6 +281,23 @@ func (a *App) Run(ctx context.Context, cancel context.CancelFunc, message string // This is used for special cases like image attachments. func (a *App) RunWithMessage(ctx context.Context, cancel context.CancelFunc, msg *session.Message) { a.cancel = cancel + + // If this is the first message and no title exists, start local title generation + if a.session.Title == "" && a.titleGen != nil { + a.titleGenerating.Store(true) + // Extract text content from the message for title generation + userMessage := msg.Message.Content + if userMessage == "" && len(msg.Message.MultiContent) > 0 { + for _, part := range msg.Message.MultiContent { + if part.Type == chat.MessagePartTypeText { + userMessage = part.Text + break + } + } + } + go a.generateTitle(ctx, []string{userMessage}) + } + go func() { a.session.AddMessage(msg) for event := range a.runtime.RunStream(ctx, a.session) { @@ -264,6 +306,12 @@ func (a *App) RunWithMessage(ctx context.Context, cancel context.CancelFunc, msg if ctx.Err() != nil { continue } + + // Clear titleGenerating flag when title is generated (from server for remote runtime) + if _, ok := event.(*runtime.SessionTitleEvent); ok { + a.titleGenerating.Store(false) + } + a.events <- event } }() @@ -724,3 +772,117 @@ func (a *App) ExportHTML(ctx context.Context, filename string) (string, error) { agentInfo := a.runtime.CurrentAgentInfo(ctx) return export.SessionToFile(a.session, agentInfo.Description, filename) } + +// UpdateSessionTitle updates the current session's title and persists it. +// It works with both local and remote runtimes. +// ErrTitleGenerating is returned when attempting to set a title while generation is in progress. +var ErrTitleGenerating = fmt.Errorf("title generation in progress, please wait") + +func (a *App) UpdateSessionTitle(ctx context.Context, title string) error { + if a.session == nil { + return fmt.Errorf("no active session") + } + + // Prevent manual title edits while generation is in progress + if a.titleGenerating.Load() { + return ErrTitleGenerating + } + + // Update in-memory session + a.session.Title = title + + // Check if runtime is a RemoteRuntime and use its UpdateSessionTitle method + if remoteRT, ok := a.runtime.(*runtime.RemoteRuntime); ok { + if err := remoteRT.UpdateSessionTitle(ctx, title); err != nil { + return fmt.Errorf("failed to update session title on remote: %w", err) + } + } else if store := a.runtime.SessionStore(); store != nil { + // For local runtime, persist via session store + if err := store.UpdateSession(ctx, a.session); err != nil { + return fmt.Errorf("failed to persist session title: %w", err) + } + } + + // Emit a SessionTitleEvent to update the UI consistently + a.events <- runtime.SessionTitle(a.session.ID, title) + return nil +} + +// IsTitleGenerating returns true if title generation is currently in progress. +func (a *App) IsTitleGenerating() bool { + return a.titleGenerating.Load() +} + +// generateTitle generates a title using the local title generator. +// This method always clears the titleGenerating flag when done (success or failure). +// It should be called in a goroutine. +func (a *App) generateTitle(ctx context.Context, userMessages []string) { + // Always clear the flag when done, whether success or failure + defer a.titleGenerating.Store(false) + + if a.titleGen == nil { + slog.Debug("No title generator available, skipping title generation") + return + } + + title, err := a.titleGen.Generate(ctx, a.session.ID, userMessages) + if err != nil { + slog.Error("Failed to generate session title", "session_id", a.session.ID, "error", err) + return + } + + if title == "" { + return + } + + // Update the session title + a.session.Title = title + + // Persist the title + if remoteRT, ok := a.runtime.(*runtime.RemoteRuntime); ok { + if err := remoteRT.UpdateSessionTitle(ctx, title); err != nil { + slog.Error("Failed to persist title on remote", "session_id", a.session.ID, "error", err) + } + } else if store := a.runtime.SessionStore(); store != nil { + if err := store.UpdateSession(ctx, a.session); err != nil { + slog.Error("Failed to persist title", "session_id", a.session.ID, "error", err) + } + } + + // Emit the title event to update the UI + a.events <- runtime.SessionTitle(a.session.ID, title) +} + +// RegenerateSessionTitle triggers AI-based title regeneration for the current session. +// Returns ErrTitleGenerating if a title generation is already in progress. +func (a *App) RegenerateSessionTitle(ctx context.Context) error { + if a.session == nil { + return fmt.Errorf("no active session") + } + + // Check if title generation is already in progress + if a.titleGenerating.Load() { + return ErrTitleGenerating + } + + // For local runtime with title generator, use it directly + if a.titleGen != nil { + a.titleGenerating.Store(true) + + // Collect user messages for title generation + var userMessages []string + for _, msg := range a.session.GetAllMessages() { + if msg.Message.Role == chat.MessageRoleUser { + userMessages = append(userMessages, msg.Message.Content) + } + } + + go a.generateTitle(ctx, userMessages) + return nil + } + + // For remote runtime, title regeneration is not yet supported + // (the server would need to implement this) + slog.Debug("Title regeneration not available for remote runtime", "session_id", a.session.ID) + return fmt.Errorf("title regeneration not available") +} diff --git a/pkg/app/app_test.go b/pkg/app/app_test.go index 98574f13f..a9883770d 100644 --- a/pkg/app/app_test.go +++ b/pkg/app/app_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + tea "charm.land/bubbletea/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -140,3 +141,130 @@ func TestApp_NewSession_WithNilSession(t *testing.T) { // Default values assert.False(t, app.Session().Thinking, "NewSession with nil should use default thinking=true") } + +func TestApp_UpdateSessionTitle(t *testing.T) { + t.Parallel() + + ctx := t.Context() + + t.Run("updates title in session", func(t *testing.T) { + t.Parallel() + + rt := &mockRuntime{} + sess := session.New() + events := make(chan tea.Msg, 16) + app := &App{ + runtime: rt, + session: sess, + events: events, + } + + err := app.UpdateSessionTitle(ctx, "New Title") + require.NoError(t, err) + + assert.Equal(t, "New Title", sess.Title) + + // Check that an event was emitted + select { + case event := <-events: + titleEvent, ok := event.(*runtime.SessionTitleEvent) + require.True(t, ok, "should emit SessionTitleEvent") + assert.Equal(t, "New Title", titleEvent.Title) + default: + t.Fatal("expected SessionTitleEvent to be emitted") + } + }) + + t.Run("returns error when no session", func(t *testing.T) { + t.Parallel() + + rt := &mockRuntime{} + app := &App{ + runtime: rt, + session: nil, + } + + err := app.UpdateSessionTitle(ctx, "New Title") + require.Error(t, err) + assert.Contains(t, err.Error(), "no active session") + }) + + t.Run("returns ErrTitleGenerating when generation in progress", func(t *testing.T) { + t.Parallel() + + rt := &mockRuntime{} + sess := session.New() + events := make(chan tea.Msg, 16) + app := &App{ + runtime: rt, + session: sess, + events: events, + } + + // Simulate title generation in progress + app.titleGenerating.Store(true) + + err := app.UpdateSessionTitle(ctx, "New Title") + require.ErrorIs(t, err, ErrTitleGenerating) + + // Title should not be updated + assert.Empty(t, sess.Title) + }) +} + +func TestApp_RegenerateSessionTitle(t *testing.T) { + t.Parallel() + + ctx := t.Context() + + t.Run("returns error when no session", func(t *testing.T) { + t.Parallel() + + rt := &mockRuntime{} + app := &App{ + runtime: rt, + session: nil, + } + + err := app.RegenerateSessionTitle(ctx) + require.Error(t, err) + assert.Contains(t, err.Error(), "no active session") + }) + + t.Run("returns error when no title generator is available", func(t *testing.T) { + t.Parallel() + + rt := &mockRuntime{} + sess := session.New() + events := make(chan tea.Msg, 16) + app := &App{ + runtime: rt, + session: sess, + events: events, + // titleGen is nil - no title generator available + } + + err := app.RegenerateSessionTitle(ctx) + require.Error(t, err) + assert.Contains(t, err.Error(), "title regeneration not available") + }) + + t.Run("returns ErrTitleGenerating when already generating", func(t *testing.T) { + t.Parallel() + + rt := &mockRuntime{} + sess := session.New() + events := make(chan tea.Msg, 16) + app := &App{ + runtime: rt, + session: sess, + events: events, + } + + // Simulate title generation already in progress + app.titleGenerating.Store(true) + + err := app.RegenerateSessionTitle(ctx) + require.ErrorIs(t, err, ErrTitleGenerating) + }) +} diff --git a/pkg/connectrpc/server.go b/pkg/connectrpc/server.go index 303a86159..9683b523e 100644 --- a/pkg/connectrpc/server.go +++ b/pkg/connectrpc/server.go @@ -239,6 +239,17 @@ func (s *Server) ToggleToolApproval(ctx context.Context, req *connect.Request[ca return connect.NewResponse(&cagentv1.ToggleToolApprovalResponse{}), nil } +// UpdateSessionTitle updates the title of a session. +func (s *Server) UpdateSessionTitle(ctx context.Context, req *connect.Request[cagentv1.UpdateSessionTitleRequest]) (*connect.Response[cagentv1.UpdateSessionTitleResponse], error) { + if err := s.sm.UpdateSessionTitle(ctx, req.Msg.SessionId, req.Msg.Title); err != nil { + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to update session title: %w", err)) + } + return connect.NewResponse(&cagentv1.UpdateSessionTitleResponse{ + SessionId: req.Msg.SessionId, + Title: req.Msg.Title, + }), nil +} + // ResumeElicitation resumes an elicitation request. func (s *Server) ResumeElicitation(ctx context.Context, req *connect.Request[cagentv1.ResumeElicitationRequest]) (*connect.Response[cagentv1.ResumeElicitationResponse], error) { var content map[string]any diff --git a/pkg/runtime/client.go b/pkg/runtime/client.go index 9a069b13a..b8bbcd3dc 100644 --- a/pkg/runtime/client.go +++ b/pkg/runtime/client.go @@ -378,3 +378,9 @@ func (c *Client) ResumeElicitation(ctx context.Context, sessionID string, action req := api.ResumeElicitationRequest{Action: string(action), Content: content} return c.doRequest(ctx, http.MethodPost, "/api/sessions/"+sessionID+"/elicitation", req, nil) } + +// UpdateSessionTitle updates the title of a session +func (c *Client) UpdateSessionTitle(ctx context.Context, sessionID, title string) error { + req := api.UpdateSessionTitleRequest{Title: title} + return c.doRequest(ctx, http.MethodPatch, "/api/sessions/"+sessionID+"/title", req, nil) +} diff --git a/pkg/runtime/commands_test.go b/pkg/runtime/commands_test.go index 980999ffb..33d99feb3 100644 --- a/pkg/runtime/commands_test.go +++ b/pkg/runtime/commands_test.go @@ -49,6 +49,9 @@ func (m *mockRuntime) SessionStore() session.Store { return nil } func (m *mockRuntime) Summarize(context.Context, *session.Session, string, chan Event) { } +func (m *mockRuntime) RegenerateTitle(context.Context, *session.Session, chan Event) { +} + func TestResolveCommand_SimpleCommand(t *testing.T) { t.Parallel() diff --git a/pkg/runtime/connectrpc_client.go b/pkg/runtime/connectrpc_client.go index 1631677e0..92c9f5de3 100644 --- a/pkg/runtime/connectrpc_client.go +++ b/pkg/runtime/connectrpc_client.go @@ -172,6 +172,15 @@ func (c *ConnectRPCClient) ToggleToolApproval(ctx context.Context, sessionID str return err } +// UpdateSessionTitle updates the title of a session +func (c *ConnectRPCClient) UpdateSessionTitle(ctx context.Context, sessionID, title string) error { + _, err := c.client.UpdateSessionTitle(ctx, connect.NewRequest(&cagentv1.UpdateSessionTitleRequest{ + SessionId: sessionID, + Title: title, + })) + return err +} + // ResumeElicitation sends an elicitation response func (c *ConnectRPCClient) ResumeElicitation(ctx context.Context, sessionID string, action tools.ElicitationAction, content map[string]any) error { contentJSON, err := json.Marshal(content) diff --git a/pkg/runtime/remote_client.go b/pkg/runtime/remote_client.go index c07d9af7c..26c9036ad 100644 --- a/pkg/runtime/remote_client.go +++ b/pkg/runtime/remote_client.go @@ -29,6 +29,9 @@ type RemoteClient interface { // RunAgentWithAgentName executes an agent with a specific agent name RunAgentWithAgentName(ctx context.Context, sessionID, agent, agentName string, messages []api.Message) (<-chan Event, error) + + // UpdateSessionTitle updates the title of a session + UpdateSessionTitle(ctx context.Context, sessionID, title string) error } // Verify that both clients implement RemoteClient diff --git a/pkg/runtime/remote_runtime.go b/pkg/runtime/remote_runtime.go index c22e8870e..4aef46ca6 100644 --- a/pkg/runtime/remote_runtime.go +++ b/pkg/runtime/remote_runtime.go @@ -415,4 +415,12 @@ func (r *RemoteRuntime) SessionStore() session.Store { func (r *RemoteRuntime) ResetStartupInfo() { } +// UpdateSessionTitle updates the title of the current session on the remote server. +func (r *RemoteRuntime) UpdateSessionTitle(ctx context.Context, title string) error { + if r.sessionID == "" { + return fmt.Errorf("cannot update session title: no session ID available") + } + return r.client.UpdateSessionTitle(ctx, r.sessionID, title) +} + var _ Runtime = (*RemoteRuntime)(nil) diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go index e04f2e2ae..93850fa6a 100644 --- a/pkg/runtime/runtime.go +++ b/pkg/runtime/runtime.go @@ -174,7 +174,6 @@ type LocalRuntime struct { elicitationEventsChannel chan Event // Current events channel for sending elicitation requests elicitationEventsChannelMux sync.RWMutex // Protects elicitationEventsChannel ragInitialized atomic.Bool - titleGen *titleGenerator sessionCompactor *sessionCompactor sessionStore session.Store workingDir string // Working directory for hooks execution @@ -288,8 +287,7 @@ func NewLocalRuntime(agents *team.Team, opts ...Opt) (*LocalRuntime, error) { return nil, fmt.Errorf("agent %s has no valid model", defaultAgent.Name()) } - r.titleGen = newTitleGenerator(model) - r.sessionCompactor = newSessionCompactor(model) + r.sessionCompactor = newSessionCompactor(model, r.sessionStore) slog.Debug("Creating new runtime", "agent", r.currentAgent, "available_agents", agents.Size()) @@ -678,8 +676,6 @@ func (r *LocalRuntime) finalizeEventChannel(ctx context.Context, sess *session.S events <- StreamStopped(sess.ID, r.currentAgent) telemetry.RecordSessionEnd(ctx) - - r.titleGen.Wait() } // RunStream starts the agent's interaction loop and returns a channel of events @@ -734,11 +730,6 @@ func (r *LocalRuntime) RunStream(ctx context.Context, sess *session.Session) <-c r.registerDefaultTools() - if sess.Title == "" { - userMessage := sess.GetLastUserMessageContent() - r.titleGen.Generate(ctx, sess, userMessage, events) - } - iteration := 0 // Use a runtime copy of maxIterations so we don't modify the session's persistent config runtimeMaxIterations := sess.MaxIterations diff --git a/pkg/runtime/session_compaction.go b/pkg/runtime/session_compaction.go index 4af79dc63..f7d979bd7 100644 --- a/pkg/runtime/session_compaction.go +++ b/pkg/runtime/session_compaction.go @@ -29,12 +29,14 @@ Generate a summary for this conversation:` ) type sessionCompactor struct { - model provider.Provider + model provider.Provider + sessionStore session.Store } -func newSessionCompactor(model provider.Provider) *sessionCompactor { +func newSessionCompactor(model provider.Provider, sessionStore session.Store) *sessionCompactor { return &sessionCompactor{ - model: model, + model: model, + sessionStore: sessionStore, } } @@ -61,6 +63,7 @@ func (c *sessionCompactor) Compact(ctx context.Context, sess *session.Session, a } sess.Messages = append(sess.Messages, session.Item{Summary: summary}) + _ = c.sessionStore.UpdateSession(ctx, sess) slog.Debug("Generated session summary", "session_id", sess.ID, "summary_length", len(summary)) events <- SessionSummary(sess.ID, summary, agentName) diff --git a/pkg/runtime/title_generator.go b/pkg/runtime/title_generator.go deleted file mode 100644 index 004e00ca5..000000000 --- a/pkg/runtime/title_generator.go +++ /dev/null @@ -1,111 +0,0 @@ -package runtime - -import ( - "context" - "fmt" - "log/slog" - "strings" - "sync" - - "github.com/docker/cagent/pkg/agent" - "github.com/docker/cagent/pkg/model/provider" - "github.com/docker/cagent/pkg/model/provider/options" - "github.com/docker/cagent/pkg/session" - "github.com/docker/cagent/pkg/team" -) - -const ( - titleSystemPrompt = "You are a helpful AI assistant that generates concise, descriptive titles for conversations. You will be given a conversation history and asked to create a single-line title that captures the main topic. Never use newlines or line breaks in your response." - titleUserPromptFormat = "Based on the following message a user sent to an AI assistant, generate a short, descriptive title (maximum 50 characters) that captures the main topic or purpose of the conversation. Return ONLY the title text on a single line, nothing else. Do not include any newlines, explanations, or formatting.\n\nUser message: %s\n\n" -) - -type titleGenerator struct { - wg sync.WaitGroup - model provider.Provider -} - -func newTitleGenerator(model provider.Provider) *titleGenerator { - return &titleGenerator{ - model: model, - } -} - -func (t *titleGenerator) Generate(ctx context.Context, sess *session.Session, userMessage string, events chan<- Event) { - if userMessage == "" { - return - } - t.wg.Go(func() { - t.generate(ctx, sess, userMessage, events) - }) -} - -func (t *titleGenerator) Wait() { - t.wg.Wait() -} - -func (t *titleGenerator) generate(ctx context.Context, sess *session.Session, firstUserMessage string, events chan<- Event) { - slog.Debug("Generating title for session", "session_id", sess.ID) - - userPrompt := fmt.Sprintf(titleUserPromptFormat, firstUserMessage) - - titleModel := provider.CloneWithOptions( - ctx, - t.model, - options.WithStructuredOutput(nil), - options.WithMaxTokens(20), - options.WithGeneratingTitle(), - options.WithThinking(false), // Disable thinking to avoid max_tokens < thinking_budget errors - ) - - newTeam := team.New( - team.WithAgents(agent.New("root", titleSystemPrompt, agent.WithModel(titleModel))), - ) - - titleSession := session.New( - session.WithUserMessage(userPrompt), - session.WithTitle("Generating title…"), - ) - - titleRuntime, err := New(newTeam, WithSessionCompaction(false)) - if err != nil { - slog.Error("Failed to create title generator runtime", "error", err) - return - } - - _, err = titleRuntime.Run(ctx, titleSession) - if err != nil { - slog.Error("Failed to generate session title", "session_id", sess.ID, "error", err) - return - } - - title := titleSession.GetLastAssistantMessageContent() - if title == "" { - return - } - - // Sanitize the title to ensure it's a single line - title = sanitizeTitle(title) - if title == "" { - return - } - - sess.Title = title - slog.Debug("Generated session title", "session_id", sess.ID, "title", title) - events <- SessionTitle(sess.ID, title) -} - -// sanitizeTitle ensures the title is a single line by taking only the first -// non-empty line and stripping any control characters that could break TUI rendering. -func sanitizeTitle(title string) string { - // Split by newlines and take the first non-empty line - lines := strings.Split(title, "\n") - for _, line := range lines { - line = strings.TrimSpace(line) - if line != "" { - // Remove any remaining carriage returns - line = strings.ReplaceAll(line, "\r", "") - return line - } - } - return "" -} diff --git a/pkg/server/server.go b/pkg/server/server.go index d93ea9f00..16c7b8df8 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -53,6 +53,8 @@ func New(ctx context.Context, sessionStore session.Store, runConfig *config.Runt group.POST("/sessions/:id/thinking/toggle", s.toggleSessionThinking) // Update session permissions group.PATCH("/sessions/:id/permissions", s.updateSessionPermissions) + // Update session title + group.PATCH("/sessions/:id/title", s.updateSessionTitle) // Create a new session group.POST("/sessions", s.createSession) // Delete a session @@ -239,6 +241,23 @@ func (s *Server) updateSessionPermissions(c echo.Context) error { return c.JSON(http.StatusOK, map[string]string{"message": "session permissions updated"}) } +func (s *Server) updateSessionTitle(c echo.Context) error { + sessionID := c.Param("id") + var req api.UpdateSessionTitleRequest + if err := c.Bind(&req); err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("invalid request body: %v", err)) + } + + if err := s.sm.UpdateSessionTitle(c.Request().Context(), sessionID, req.Title); err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to update session title: %v", err)) + } + + return c.JSON(http.StatusOK, api.UpdateSessionTitleResponse{ + ID: sessionID, + Title: req.Title, + }) +} + func (s *Server) deleteSession(c echo.Context) error { sessionID := c.Param("id") diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index dc4f28005..ccfbbdcd8 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -169,6 +169,61 @@ func unmarshal(t *testing.T, buf []byte, v any) { require.NoError(t, err) } +func TestServer_UpdateSessionTitle(t *testing.T) { + t.Parallel() + + ctx := t.Context() + store := session.NewInMemorySessionStore() + lnPath := startServerWithStore(t, ctx, prepareAgentsDir(t), store) + + // Create a session first + createResp := httpDo(t, ctx, http.MethodPost, lnPath, "/api/sessions", map[string]any{}) + var createdSession session.Session + unmarshal(t, createResp, &createdSession) + require.NotEmpty(t, createdSession.ID) + + // Update the session title + newTitle := "My Custom Title" + updateResp := httpDo(t, ctx, http.MethodPatch, lnPath, "/api/sessions/"+createdSession.ID+"/title", api.UpdateSessionTitleRequest{Title: newTitle}) + var titleResp api.UpdateSessionTitleResponse + unmarshal(t, updateResp, &titleResp) + + assert.Equal(t, createdSession.ID, titleResp.ID) + assert.Equal(t, newTitle, titleResp.Title) + + // Verify the session was updated in the store + getResp := httpGET(t, ctx, lnPath, "/api/sessions/"+createdSession.ID) + var sessionResp api.SessionResponse + unmarshal(t, getResp, &sessionResp) + + assert.Equal(t, newTitle, sessionResp.Title) +} + +func startServerWithStore(t *testing.T, ctx context.Context, agentsDir string, store session.Store) string { + t.Helper() + + runConfig := config.RuntimeConfig{} + + sources, err := config.ResolveSources(agentsDir) + require.NoError(t, err) + srv, err := New(ctx, store, &runConfig, 0, sources) + require.NoError(t, err) + + socketPath := "unix://" + filepath.Join(t.TempDir(), "sock") + ln, err := Listen(ctx, socketPath) + require.NoError(t, err) + go func() { + <-ctx.Done() + _ = ln.Close() + }() + + go func() { + _ = srv.Serve(ctx, ln) + }() + + return socketPath +} + type mockStore struct { session.Store } diff --git a/pkg/server/session_manager.go b/pkg/server/session_manager.go index 6151ddf77..35492bc27 100644 --- a/pkg/server/session_manager.go +++ b/pkg/server/session_manager.go @@ -14,8 +14,10 @@ import ( "github.com/docker/cagent/pkg/api" "github.com/docker/cagent/pkg/concurrent" "github.com/docker/cagent/pkg/config" + "github.com/docker/cagent/pkg/model/provider" "github.com/docker/cagent/pkg/runtime" "github.com/docker/cagent/pkg/session" + "github.com/docker/cagent/pkg/sessiontitle" "github.com/docker/cagent/pkg/team" "github.com/docker/cagent/pkg/teamloader" "github.com/docker/cagent/pkg/tools" @@ -24,6 +26,8 @@ import ( type activeRuntimes struct { runtime runtime.Runtime cancel context.CancelFunc + session *session.Session // The actual session object used by the runtime + model provider.Provider // The model provider for title generation } // SessionManager manages sessions for HTTP and Connect-RPC servers. @@ -140,8 +144,14 @@ func (sm *SessionManager) RunSession(ctx context.Context, sessionID, agentFilena rc := sm.runConfig.Clone() rc.WorkingDir = sess.WorkingDir + + // Collect user messages for potential title generation + var userMessages []string for _, msg := range messages { sess.AddMessage(session.UserMessage(msg.Content, msg.MultiContent...)) + if msg.Content != "" { + userMessages = append(userMessages, msg.Content) + } } if err := sm.sessionStore.UpdateSession(ctx, sess); err != nil { @@ -150,8 +160,10 @@ func (sm *SessionManager) RunSession(ctx context.Context, sessionID, agentFilena runtimeSession, exists := sm.runtimeSessions.Load(sessionID) streamCtx, cancel := context.WithCancel(ctx) + var model provider.Provider if !exists { - rt, err := sm.runtimeForSession(ctx, sess, agentFilename, currentAgent, rc) + var rt runtime.Runtime + rt, model, err = sm.runtimeForSession(ctx, sess, agentFilename, currentAgent, rc) if err != nil { cancel() return nil, err @@ -159,13 +171,27 @@ func (sm *SessionManager) RunSession(ctx context.Context, sessionID, agentFilena runtimeSession = &activeRuntimes{ runtime: rt, cancel: cancel, + session: sess, + model: model, } sm.runtimeSessions.Store(sessionID, runtimeSession) + } else { + // Update the session pointer in case it was reloaded + runtimeSession.session = sess + model = runtimeSession.model } streamChan := make(chan runtime.Event) + // Check if we need to generate a title + needsTitle := sess.Title == "" && len(userMessages) > 0 && model != nil + go func() { + // Start title generation in parallel if needed + if needsTitle { + go sm.generateTitle(ctx, sess, model, userMessages, streamChan) + } + stream := runtimeSession.runtime.RunStream(streamCtx, sess) defer cancel() defer close(streamChan) @@ -256,20 +282,82 @@ func (sm *SessionManager) UpdateSessionPermissions(ctx context.Context, sessionI return sm.sessionStore.UpdateSession(ctx, sess) } -func (sm *SessionManager) runtimeForSession(ctx context.Context, sess *session.Session, agentFilename, currentAgent string, rc *config.RuntimeConfig) (runtime.Runtime, error) { +// UpdateSessionTitle updates the title for a session. +// If the session is actively running, it also updates the in-memory session +// object to prevent subsequent runtime saves from overwriting the title. +func (sm *SessionManager) UpdateSessionTitle(ctx context.Context, sessionID, title string) error { + sm.mux.Lock() + defer sm.mux.Unlock() + + // If session is actively running, update the in-memory session object directly. + // This ensures the runtime's saveSession won't overwrite our manual edit. + if rt, ok := sm.runtimeSessions.Load(sessionID); ok && rt.session != nil { + rt.session.Title = title + slog.Debug("Updated title for active session", "session_id", sessionID, "title", title) + return sm.sessionStore.UpdateSession(ctx, rt.session) + } + + // Session is not actively running, load from store and update + sess, err := sm.sessionStore.GetSession(ctx, sessionID) + if err != nil { + return err + } + + sess.Title = title + return sm.sessionStore.UpdateSession(ctx, sess) +} + +// generateTitle generates a title for a session using the sessiontitle package. +// The generated title is stored in the session and persisted to the store. +// A SessionTitleEvent is emitted to notify clients. +func (sm *SessionManager) generateTitle(ctx context.Context, sess *session.Session, model provider.Provider, userMessages []string, events chan<- runtime.Event) { + if model == nil || len(userMessages) == 0 { + return + } + + gen := sessiontitle.New(model) + title, err := gen.Generate(ctx, sess.ID, userMessages) + if err != nil { + slog.Error("Failed to generate session title", "session_id", sess.ID, "error", err) + return + } + + if title == "" { + return + } + + // Update the in-memory session + sess.Title = title + + // Persist the title + if err := sm.sessionStore.UpdateSession(ctx, sess); err != nil { + slog.Error("Failed to persist generated title", "session_id", sess.ID, "error", err) + return + } + + // Emit the title event + select { + case events <- runtime.SessionTitle(sess.ID, title): + slog.Debug("Generated and emitted session title", "session_id", sess.ID, "title", title) + case <-ctx.Done(): + slog.Debug("Context cancelled while emitting title event", "session_id", sess.ID) + } +} + +func (sm *SessionManager) runtimeForSession(ctx context.Context, sess *session.Session, agentFilename, currentAgent string, rc *config.RuntimeConfig) (runtime.Runtime, provider.Provider, error) { rt, exists := sm.runtimeSessions.Load(sess.ID) if exists && rt.runtime != nil { - return rt.runtime, nil + return rt.runtime, rt.model, nil } t, err := sm.loadTeam(ctx, agentFilename, rc) if err != nil { - return nil, err + return nil, nil, err } agent, err := t.Agent(currentAgent) if err != nil { - return nil, err + return nil, nil, err } sess.MaxIterations = agent.MaxIterations() // Initialize thinking state based on whether thinking_budget was explicitly configured @@ -283,16 +371,20 @@ func (sm *SessionManager) runtimeForSession(ctx context.Context, sess *session.S } run, err := runtime.New(t, opts...) if err != nil { - return nil, err + return nil, nil, err } + model := agent.Model() + sm.runtimeSessions.Store(sess.ID, &activeRuntimes{ runtime: run, + session: sess, + model: model, }) slog.Debug("Runtime created for session", "session_id", sess.ID) - return run, nil + return run, model, nil } func (sm *SessionManager) loadTeam(ctx context.Context, agentFilename string, runConfig *config.RuntimeConfig) (*team.Team, error) { diff --git a/pkg/session/session.go b/pkg/session/session.go index b55f81910..3bfe8fc14 100644 --- a/pkg/session/session.go +++ b/pkg/session/session.go @@ -251,6 +251,24 @@ func (s *Session) GetLastUserMessageContent() string { return s.getLastMessageContentByRole(chat.MessageRoleUser) } +// GetLastUserMessages returns up to n most recent user messages, ordered from oldest to newest. +func (s *Session) GetLastUserMessages(n int) []string { + messages := s.GetAllMessages() + var userMessages []string + for i := range messages { + if messages[i].Message.Role == chat.MessageRoleUser { + content := strings.TrimSpace(messages[i].Message.Content) + if content != "" { + userMessages = append(userMessages, content) + } + } + } + if len(userMessages) <= n { + return userMessages + } + return userMessages[len(userMessages)-n:] +} + func (s *Session) getLastMessageContentByRole(role chat.MessageRole) string { messages := s.GetAllMessages() for i := len(messages) - 1; i >= 0; i-- { diff --git a/pkg/session/session_test.go b/pkg/session/session_test.go index 33790bb16..378a8b399 100644 --- a/pkg/session/session_test.go +++ b/pkg/session/session_test.go @@ -318,3 +318,79 @@ func TestUpdateLastAssistantMessageUsage_UpdatesOnlyLast(t *testing.T) { assert.InEpsilon(t, 0.02, messages[2].Message.Cost, 0.0001) assert.Equal(t, "new-model", messages[2].Message.Model) } + +func TestGetLastUserMessages(t *testing.T) { + t.Parallel() + + testAgent := &agent.Agent{} + + t.Run("empty session returns empty slice", func(t *testing.T) { + t.Parallel() + s := New() + assert.Empty(t, s.GetLastUserMessages(2)) + }) + + t.Run("session with fewer messages than requested returns all", func(t *testing.T) { + t.Parallel() + s := New() + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleUser, + Content: "Only message", + })) + msgs := s.GetLastUserMessages(2) + assert.Len(t, msgs, 1) + assert.Equal(t, "Only message", msgs[0]) + }) + + t.Run("session returns last n user messages in order", func(t *testing.T) { + t.Parallel() + s := New() + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleUser, + Content: "First", + })) + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleAssistant, + Content: "Response 1", + })) + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleUser, + Content: "Second", + })) + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleAssistant, + Content: "Response 2", + })) + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleUser, + Content: "Third", + })) + + msgs := s.GetLastUserMessages(2) + assert.Len(t, msgs, 2) + assert.Equal(t, "Second", msgs[0]) // Ordered oldest to newest + assert.Equal(t, "Third", msgs[1]) + }) + + t.Run("skips empty user messages", func(t *testing.T) { + t.Parallel() + s := New() + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleUser, + Content: "First", + })) + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleUser, + Content: " ", // Empty after trim + })) + s.AddMessage(NewAgentMessage(testAgent, &chat.Message{ + Role: chat.MessageRoleUser, + Content: "Third", + })) + + msgs := s.GetLastUserMessages(2) + assert.Len(t, msgs, 2) + assert.Equal(t, "First", msgs[0]) + assert.Equal(t, "Third", msgs[1]) + }) +} diff --git a/pkg/sessiontitle/generator.go b/pkg/sessiontitle/generator.go new file mode 100644 index 000000000..3661b51a1 --- /dev/null +++ b/pkg/sessiontitle/generator.go @@ -0,0 +1,124 @@ +// Package sessiontitle provides session title generation using a one-shot LLM call. +// It is designed to be independent of pkg/runtime to avoid circular dependencies +// and the overhead of spinning up a nested runtime. +package sessiontitle + +import ( + "context" + "errors" + "fmt" + "io" + "log/slog" + "strings" + + "github.com/docker/cagent/pkg/chat" + "github.com/docker/cagent/pkg/model/provider" + "github.com/docker/cagent/pkg/model/provider/options" +) + +const ( + systemPrompt = "You are a helpful AI assistant that generates concise, descriptive titles for conversations. You will be given up to 2 recent user messages and asked to create a single-line title that captures the main topic. Never use newlines or line breaks in your response." + userPromptFormat = "Based on the following recent user messages from a conversation with an AI assistant, generate a short, descriptive title (maximum 50 characters) that captures the main topic or purpose of the conversation. Return ONLY the title text on a single line, nothing else. Do not include any newlines, explanations, or formatting.\n\nRecent user messages:\n%s\n\n" +) + +// Generator generates session titles using a one-shot LLM completion. +type Generator struct { + model provider.Provider +} + +// New creates a new title Generator with the given model provider. +func New(model provider.Provider) *Generator { + return &Generator{ + model: model, + } +} + +// Generate produces a title for a session based on the provided user messages. +// It performs a one-shot LLM call directly via the provider's CreateChatCompletionStream, +// avoiding the overhead of spinning up a nested runtime. +// Returns an empty string if generation fails or no messages are provided. +func (g *Generator) Generate(ctx context.Context, sessionID string, userMessages []string) (string, error) { + if len(userMessages) == 0 { + return "", nil + } + + slog.Debug("Generating title for session", "session_id", sessionID, "message_count", len(userMessages)) + + // Format messages for the prompt + var formattedMessages strings.Builder + for i, msg := range userMessages { + fmt.Fprintf(&formattedMessages, "%d. %s\n", i+1, msg) + } + userPrompt := fmt.Sprintf(userPromptFormat, formattedMessages.String()) + + // Clone the model with title-generation-specific options + titleModel := provider.CloneWithOptions( + ctx, + g.model, + options.WithStructuredOutput(nil), + options.WithMaxTokens(20), + options.WithGeneratingTitle(), + options.WithThinking(false), // Disable thinking to avoid max_tokens < thinking_budget errors + ) + + // Build the messages for the completion request + messages := []chat.Message{ + { + Role: chat.MessageRoleSystem, + Content: systemPrompt, + }, + { + Role: chat.MessageRoleUser, + Content: userPrompt, + }, + } + + // Call the provider directly (no tools needed for title generation) + stream, err := titleModel.CreateChatCompletionStream(ctx, messages, nil) + if err != nil { + slog.Error("Failed to create title generation stream", "session_id", sessionID, "error", err) + return "", fmt.Errorf("creating title stream: %w", err) + } + defer stream.Close() + + // Drain the stream to collect the full title + var title strings.Builder + for { + response, err := stream.Recv() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + slog.Error("Error receiving from title stream", "session_id", sessionID, "error", err) + return "", fmt.Errorf("receiving from title stream: %w", err) + } + + if len(response.Choices) > 0 { + title.WriteString(response.Choices[0].Delta.Content) + } + } + + result := sanitizeTitle(title.String()) + if result == "" { + return "", nil + } + + slog.Debug("Generated session title", "session_id", sessionID, "title", result) + return result, nil +} + +// sanitizeTitle ensures the title is a single line by taking only the first +// non-empty line and stripping any control characters that could break TUI rendering. +func sanitizeTitle(title string) string { + // Split by newlines and take the first non-empty line + lines := strings.Split(title, "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + if line != "" { + // Remove any remaining carriage returns + line = strings.ReplaceAll(line, "\r", "") + return line + } + } + return "" +} diff --git a/pkg/sessiontitle/generator_test.go b/pkg/sessiontitle/generator_test.go new file mode 100644 index 000000000..d9895b2c5 --- /dev/null +++ b/pkg/sessiontitle/generator_test.go @@ -0,0 +1,25 @@ +package sessiontitle + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGenerator_GenerateEmptyMessages(t *testing.T) { + t.Parallel() + + // Create a generator with nil model (won't be used since messages are empty) + gen := New(nil) + + // Call Generate with empty user messages - should return early without doing anything + title, err := gen.Generate(t.Context(), "test-session", []string{}) + require.NoError(t, err) + assert.Empty(t, title) + + // Also test with nil slice + title, err = gen.Generate(t.Context(), "test-session", nil) + require.NoError(t, err) + assert.Empty(t, title) +} diff --git a/pkg/tui/commands/commands.go b/pkg/tui/commands/commands.go index 1f57055ca..f799816be 100644 --- a/pkg/tui/commands/commands.go +++ b/pkg/tui/commands/commands.go @@ -76,6 +76,22 @@ func builtInSessionCommands() []Item { return core.CmdHandler(messages.ToggleSessionStarMsg{}) }, }, + { + ID: "session.title", + Label: "Title", + SlashCommand: "/title", + Description: "Set or regenerate session title (usage: /title [new title])", + Category: "Session", + Execute: func(arg string) tea.Cmd { + arg = strings.TrimSpace(arg) + if arg == "" { + // No argument: regenerate title + return core.CmdHandler(messages.RegenerateTitleMsg{}) + } + // With argument: set title + return core.CmdHandler(messages.SetSessionTitleMsg{Title: arg}) + }, + }, { ID: "session.model", Label: "Model", diff --git a/pkg/tui/commands/commands_test.go b/pkg/tui/commands/commands_test.go new file mode 100644 index 000000000..eb4b4ccb8 --- /dev/null +++ b/pkg/tui/commands/commands_test.go @@ -0,0 +1,124 @@ +package commands + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/docker/cagent/pkg/tui/messages" +) + +func TestParseSlashCommand_Title(t *testing.T) { + t.Parallel() + + t.Run("title with argument sets title", func(t *testing.T) { + t.Parallel() + + cmd := ParseSlashCommand("/title My Custom Title") + require.NotNil(t, cmd, "should return a command for /title with argument") + + // Execute the command and check the message type + msg := cmd() + setTitleMsg, ok := msg.(messages.SetSessionTitleMsg) + require.True(t, ok, "should return SetSessionTitleMsg") + assert.Equal(t, "My Custom Title", setTitleMsg.Title) + }) + + t.Run("title without argument regenerates", func(t *testing.T) { + t.Parallel() + + cmd := ParseSlashCommand("/title") + require.NotNil(t, cmd, "should return a command for /title without argument") + + // Execute the command and check the message type + msg := cmd() + _, ok := msg.(messages.RegenerateTitleMsg) + assert.True(t, ok, "should return RegenerateTitleMsg") + }) + + t.Run("title with only whitespace regenerates", func(t *testing.T) { + t.Parallel() + + cmd := ParseSlashCommand("/title ") + require.NotNil(t, cmd, "should return a command for /title with whitespace") + + // Execute the command and check the message type + msg := cmd() + _, ok := msg.(messages.RegenerateTitleMsg) + assert.True(t, ok, "should return RegenerateTitleMsg for whitespace-only arg") + }) +} + +func TestParseSlashCommand_OtherCommands(t *testing.T) { + t.Parallel() + + t.Run("exit command", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("/exit") + require.NotNil(t, cmd) + msg := cmd() + _, ok := msg.(messages.ExitSessionMsg) + assert.True(t, ok) + }) + + t.Run("new command", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("/new") + require.NotNil(t, cmd) + msg := cmd() + _, ok := msg.(messages.NewSessionMsg) + assert.True(t, ok) + }) + + t.Run("star command", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("/star") + require.NotNil(t, cmd) + msg := cmd() + _, ok := msg.(messages.ToggleSessionStarMsg) + assert.True(t, ok) + }) + + t.Run("unknown command returns nil", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("/unknown") + assert.Nil(t, cmd) + }) + + t.Run("non-slash input returns nil", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("hello world") + assert.Nil(t, cmd) + }) + + t.Run("empty input returns nil", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("") + assert.Nil(t, cmd) + }) +} + +func TestParseSlashCommand_Compact(t *testing.T) { + t.Parallel() + + t.Run("compact without argument", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("/compact") + require.NotNil(t, cmd) + msg := cmd() + compactMsg, ok := msg.(messages.CompactSessionMsg) + require.True(t, ok) + assert.Empty(t, compactMsg.AdditionalPrompt) + }) + + t.Run("compact with argument", func(t *testing.T) { + t.Parallel() + cmd := ParseSlashCommand("/compact focus on the API design") + require.NotNil(t, cmd) + msg := cmd() + compactMsg, ok := msg.(messages.CompactSessionMsg) + require.True(t, ok) + assert.Equal(t, "focus on the API design", compactMsg.AdditionalPrompt) + }) +} diff --git a/pkg/tui/components/sidebar/sidebar.go b/pkg/tui/components/sidebar/sidebar.go index 7297c8966..bca578821 100644 --- a/pkg/tui/components/sidebar/sidebar.go +++ b/pkg/tui/components/sidebar/sidebar.go @@ -9,6 +9,7 @@ import ( "slices" "strings" + "charm.land/bubbles/v2/textinput" tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" @@ -52,8 +53,10 @@ type Model interface { SetQueuedMessages(messages ...string) GetSize() (width, height int) LoadFromSession(sess *session.Session) - // HandleClick checks if click is on the star and returns true if handled + // HandleClick checks if click is on the star or title and returns true if handled HandleClick(x, y int) bool + // HandleClickType returns the type of click (star, title, or none) + HandleClickType(x, y int) ClickResult // IsCollapsed returns whether the sidebar is collapsed IsCollapsed() bool // ToggleCollapsed toggles the collapsed state @@ -68,6 +71,18 @@ type Model interface { SetPreferredWidth(width int) // ClampWidth ensures width is within valid bounds for the given window width ClampWidth(width, windowInnerWidth int) int + // BeginTitleEdit starts inline editing of the session title + BeginTitleEdit() + // IsEditingTitle returns true if the title is being edited + IsEditingTitle() bool + // CommitTitleEdit commits the current title edit and returns the new title + CommitTitleEdit() string + // CancelTitleEdit cancels the current title edit + CancelTitleEdit() + // UpdateTitleInput passes a key message to the title input + UpdateTitleInput(msg tea.Msg) tea.Cmd + // SetTitleRegenerating sets the title regeneration state and returns a command to start/stop spinner + SetTitleRegenerating(regenerating bool) tea.Cmd } // ragIndexingState tracks per-strategy indexing progress @@ -110,7 +125,11 @@ type model struct { streamCancelled bool // true after ESC cancel until next StreamStartedEvent reasoningSupported bool // true if current model supports reasoning (default: true / fail-open) collapsed bool // true when sidebar is collapsed + titleRegenerating bool // true when title is being regenerated by AI + titleGenerated bool // true once a title has been generated or set (hides pencil until then) preferredWidth int // user's preferred width (persisted across collapse/expand) + editingTitle bool // true when inline title editing is active + titleInput textinput.Model } // Option is a functional option for configuring the sidebar. @@ -122,6 +141,11 @@ func WithLayoutConfig(cfg LayoutConfig) Option { } func New(sessionState *service.SessionState, opts ...Option) Model { + ti := textinput.New() + ti.Placeholder = "Session title" + ti.CharLimit = 50 + ti.Prompt = "" // No prompt to maximize usable width in collapsed sidebar + m := &model{ width: 20, layoutCfg: DefaultLayoutConfig(), @@ -137,6 +161,7 @@ func New(sessionState *service.SessionState, opts ...Option) Model { workingDirectory: getCurrentWorkingDirectory(), reasoningSupported: true, preferredWidth: DefaultWidth, + titleInput: ti, } for _, opt := range opts { opt(m) @@ -150,7 +175,7 @@ func (m *model) Init() tea.Cmd { // needsSpinner returns true if any spinner-driving state is active. func (m *model) needsSpinner() bool { - return m.workingAgent != "" || m.toolsLoading || m.mcpInit + return m.workingAgent != "" || m.toolsLoading || m.mcpInit || m.titleRegenerating } // startSpinner registers the spinner with the animation coordinator if not already active. @@ -242,29 +267,78 @@ func (m *model) SetQueuedMessages(queuedMessages ...string) { m.queuedMessages = queuedMessages } -// HandleClick checks if click is on the star and returns true if it was +// SetTitleRegenerating sets the title regeneration state and manages spinner lifecycle. +// Returns a command to start the spinner if regenerating, nil otherwise. +func (m *model) SetTitleRegenerating(regenerating bool) tea.Cmd { + m.titleRegenerating = regenerating + if regenerating { + return m.startSpinner() + } + m.stopSpinner() + return nil +} + +// ClickResult indicates what was clicked in the sidebar +type ClickResult int + +const ( + ClickNone ClickResult = iota + ClickStar + ClickPencil +) + +// pencilIconWidth is the click target width for the pencil edit icon (includes padding) +const pencilIconWidth = 3 // " ✎" = space + pencil character + +// HandleClick checks if click is on the star or title and returns true if it was // x and y are coordinates relative to the sidebar's top-left corner // This does NOT toggle the state - caller should handle that func (m *model) HandleClick(x, y int) bool { - // Don't handle star clicks if session has no content (star isn't shown) - if !m.sessionHasContent { - return false - } + return m.HandleClickType(x, y) != ClickNone +} - // Account for left padding - the star starts after the padding +// HandleClickType returns what was clicked (star, pencil icon, or nothing) +func (m *model) HandleClickType(x, y int) ClickResult { + // Account for left padding adjustedX := x - m.layoutCfg.PaddingLeft - // Check if click is within the star area - if adjustedX < 0 || adjustedX > starClickWidth { - return false - } - if m.mode == ModeCollapsed { // In collapsed mode, star is at the beginning of first line (y=0) - return y == 0 + if y == 0 { + if m.sessionHasContent && adjustedX >= 0 && adjustedX <= starClickWidth { + return ClickStar + } + // Check if click is on pencil icon (at the end of the title line) + // Pencil is only shown when title has been generated + if m.titleGenerated { + starWidth := lipgloss.Width(m.starIndicator()) + titleWidth := lipgloss.Width(m.sessionTitle) + pencilStart := starWidth + titleWidth + if adjustedX >= pencilStart && adjustedX < pencilStart+pencilIconWidth { + return ClickPencil + } + } + } + return ClickNone } - // In vertical mode, star is below tab title and TabStyle padding - return y == verticalStarY + + // In vertical mode, the title line is at verticalStarY + if y == verticalStarY { + if m.sessionHasContent && adjustedX >= 0 && adjustedX <= starClickWidth { + return ClickStar + } + // Check if click is on pencil icon (at the end of the title line) + // Pencil is only shown when title has been generated + if m.titleGenerated { + starWidth := lipgloss.Width(m.starIndicator()) + titleWidth := lipgloss.Width(m.sessionTitle) + pencilStart := starWidth + titleWidth + if adjustedX >= pencilStart && adjustedX < pencilStart+pencilIconWidth { + return ClickPencil + } + } + } + return ClickNone } // LoadFromSession loads sidebar state from a restored session @@ -285,6 +359,7 @@ func (m *model) LoadFromSession(sess *session.Session) { // Load session title if sess.Title != "" { m.sessionTitle = sess.Title + m.titleGenerated = true // Mark as generated since session already has a title } // Load starred status @@ -410,11 +485,22 @@ func (m *model) Update(msg tea.Msg) (layout.Model, tea.Cmd) { return m, nil case *runtime.SessionTitleEvent: m.sessionTitle = msg.Title + // Mark title as generated (enables pencil icon) + m.titleGenerated = true + // Clear regenerating state now that we have a title + if m.titleRegenerating { + m.titleRegenerating = false + m.stopSpinner() + } return m, nil case *runtime.StreamStartedEvent: // New stream starting - reset cancelled flag and enable spinner m.streamCancelled = false m.workingAgent = msg.AgentName + // If title hasn't been generated yet, show the title generation spinner + if !m.titleGenerated { + m.titleRegenerating = true + } cmd := m.startSpinner() return m, cmd case *runtime.StreamStoppedEvent: @@ -487,8 +573,8 @@ func (m *model) Update(msg tea.Msg) (layout.Model, tea.Cmd) { default: var cmds []tea.Cmd - // Update main spinner when MCP is initializing, tools are loading, or an agent is working - if m.mcpInit || m.toolsLoading || m.workingAgent != "" { + // Update main spinner when MCP is initializing, tools are loading, agent is working, or title is regenerating + if m.mcpInit || m.toolsLoading || m.workingAgent != "" || m.titleRegenerating { model, cmd := m.spinner.Update(msg) m.spinner = model.(spinner.Spinner) cmds = append(cmds, cmd) @@ -552,8 +638,34 @@ type collapsedLayout struct { } func (m *model) computeCollapsedLayout(contentWidth int) collapsedLayout { + star := m.starIndicator() + starWidth := lipgloss.Width(star) + + var titleWithStar string + var editing bool + switch { + case m.editingTitle: + editing = true + // Show the text input when editing + // Account for star indicator width and leave room for cursor + inputWidth := contentWidth - starWidth - 1 + if inputWidth < 10 { + inputWidth = 10 // Minimum usable width + } + m.titleInput.SetWidth(inputWidth) + titleWithStar = star + m.titleInput.View() + case m.titleRegenerating: + titleWithStar = star + m.spinner.View() + styles.MutedStyle.Render(" Generating title…") + case m.titleGenerated: + // Title has been generated - show with pencil icon + pencilIcon := styles.MutedStyle.Render(" ✎") + titleWithStar = star + m.sessionTitle + pencilIcon + default: + // Title not yet generated - show without pencil icon + titleWithStar = star + m.sessionTitle + } h := collapsedLayout{ - titleWithStar: m.starIndicator() + m.sessionTitle, + titleWithStar: titleWithStar, workingIndicator: m.workingIndicatorCollapsed(), workingDir: m.workingDirectory, usageSummary: m.tokenUsageSummary(), @@ -566,9 +678,11 @@ func (m *model) computeCollapsedLayout(contentWidth int) collapsedLayout { usageWidth := lipgloss.Width(h.usageSummary) // Title and indicator fit on one line if: + // - editing mode (input is constrained to fit), OR // - no working indicator AND title fits, OR // - both fit together with gap - h.titleAndIndicatorOnOneLine = (h.workingIndicator == "" && titleWidth <= contentWidth) || + h.titleAndIndicatorOnOneLine = editing || + (h.workingIndicator == "" && titleWidth <= contentWidth) || (h.workingIndicator != "" && titleWidth+minGap+wiWidth <= contentWidth) h.wdAndUsageOnOneLine = wdWidth+minGap+usageWidth <= contentWidth @@ -862,8 +976,34 @@ func (m *model) tokenUsageSummary() string { } func (m *model) sessionInfo(contentWidth int) string { + star := m.starIndicator() + starWidth := lipgloss.Width(star) + + var titleLine string + switch { + case m.editingTitle: + // Render the textinput for editing + // Account for star indicator width and leave room for cursor + inputWidth := contentWidth - starWidth - 1 + if inputWidth < 10 { + inputWidth = 10 // Minimum usable width + } + m.titleInput.SetWidth(inputWidth) + titleLine = star + m.titleInput.View() + case m.titleRegenerating: + // Show spinner while regenerating title + titleLine = star + m.spinner.View() + styles.MutedStyle.Render(" Generating title…") + case m.titleGenerated: + // Title has been generated - show with pencil icon for editing + pencilIcon := styles.MutedStyle.Render(" ✎") + titleLine = star + m.sessionTitle + pencilIcon + default: + // Title not yet generated - show title without pencil icon + titleLine = star + m.sessionTitle + } + lines := []string{ - m.starIndicator() + m.sessionTitle, + titleLine, "", } @@ -1119,3 +1259,40 @@ func (m *model) ClampWidth(width, windowInnerWidth int) int { maxWidth := min(int(float64(windowInnerWidth)*MaxWidthPercent), windowInnerWidth-20) return max(MinWidth, min(width, maxWidth)) } + +// BeginTitleEdit starts inline editing of the session title +func (m *model) BeginTitleEdit() { + m.editingTitle = true + m.titleInput.SetValue(m.sessionTitle) + m.titleInput.Focus() + m.titleInput.CursorEnd() +} + +// IsEditingTitle returns true if the title is being edited +func (m *model) IsEditingTitle() bool { + return m.editingTitle +} + +// CommitTitleEdit commits the current title edit and returns the new title +func (m *model) CommitTitleEdit() string { + newTitle := strings.TrimSpace(m.titleInput.Value()) + if newTitle != "" { + m.sessionTitle = newTitle + } + m.editingTitle = false + m.titleInput.Blur() + return m.sessionTitle +} + +// CancelTitleEdit cancels the current title edit +func (m *model) CancelTitleEdit() { + m.editingTitle = false + m.titleInput.Blur() +} + +// UpdateTitleInput passes a key message to the title input +func (m *model) UpdateTitleInput(msg tea.Msg) tea.Cmd { + var cmd tea.Cmd + m.titleInput, cmd = m.titleInput.Update(msg) + return cmd +} diff --git a/pkg/tui/components/sidebar/title_edit_test.go b/pkg/tui/components/sidebar/title_edit_test.go new file mode 100644 index 000000000..fc2567b78 --- /dev/null +++ b/pkg/tui/components/sidebar/title_edit_test.go @@ -0,0 +1,151 @@ +package sidebar + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/docker/cagent/pkg/session" + "github.com/docker/cagent/pkg/tui/service" +) + +func TestSidebar_TitleEditStateTransitions(t *testing.T) { + t.Parallel() + + sess := session.New() + sessionState := service.NewSessionState(sess) + sb := New(sessionState) + + // Initially not editing + assert.False(t, sb.IsEditingTitle(), "should not be editing initially") + + // Begin editing + sb.BeginTitleEdit() + assert.True(t, sb.IsEditingTitle(), "should be editing after BeginTitleEdit") + + // Cancel editing + sb.CancelTitleEdit() + assert.False(t, sb.IsEditingTitle(), "should not be editing after CancelTitleEdit") + + // Begin editing again + sb.BeginTitleEdit() + assert.True(t, sb.IsEditingTitle(), "should be editing after second BeginTitleEdit") + + // Commit editing + title := sb.CommitTitleEdit() + assert.False(t, sb.IsEditingTitle(), "should not be editing after CommitTitleEdit") + require.NotEmpty(t, title, "committed title should not be empty") +} + +func TestSidebar_TitleEditPreservesInput(t *testing.T) { + t.Parallel() + + sess := session.New() + sessionState := service.NewSessionState(sess) + sb := New(sessionState) + + // Set initial title by simulating session load + m := sb.(*model) + m.sessionTitle = "Original Title" + + // Begin editing - should populate input with current title + sb.BeginTitleEdit() + + // The input should have the original title + assert.Equal(t, "Original Title", m.titleInput.Value()) + + // Commit should return the title + title := sb.CommitTitleEdit() + assert.Equal(t, "Original Title", title) +} + +func TestSidebar_TitleEditCancelRestoresOriginal(t *testing.T) { + t.Parallel() + + sess := session.New() + sessionState := service.NewSessionState(sess) + sb := New(sessionState) + + // Set initial title + m := sb.(*model) + m.sessionTitle = "Original Title" + + // Begin editing + sb.BeginTitleEdit() + + // Simulate typing a new title + m.titleInput.SetValue("New Title") + + // Cancel should not change the session title + sb.CancelTitleEdit() + assert.Equal(t, "Original Title", m.sessionTitle, "cancel should preserve original title") +} + +func TestSidebar_HandleClickType(t *testing.T) { + t.Parallel() + + sess := session.New() + sessionState := service.NewSessionState(sess) + sb := New(sessionState) + + m := sb.(*model) + m.sessionHasContent = true // Enable star visibility + + // Default PaddingLeft is 1, so coordinates need to account for this + paddingLeft := m.layoutCfg.PaddingLeft // 1 + + // In vertical mode, the title line is at verticalStarY + // Click on the star area (adjusted x = 0-2, so raw x = 1-3) + result := sb.HandleClickType(paddingLeft+1, verticalStarY) + assert.Equal(t, ClickStar, result, "click on star area should return ClickStar") + + // Click on the pencil icon area (at the end of title) + // For sessionHasContent=true, star indicator is "☆ " (2 chars) + // Set a short title so we can calculate the pencil position + m.sessionTitle = "Hi" + m.titleGenerated = true // Pencil only shows when title has been generated + // Star "☆ " = 2 chars, title "Hi" = 2 chars, pencil " ✎" starts at position 4 + // Add padding to get raw x coordinate + pencilX := paddingLeft + 4 + result = sb.HandleClickType(pencilX, verticalStarY) + assert.Equal(t, ClickPencil, result, "click on pencil icon should return ClickPencil") + + // Click on the title text (not the star, not the pencil) should return ClickNone + // Star ends at position 2, title starts at 2 and ends at 4 + titleX := paddingLeft + 3 // middle of title + result = sb.HandleClickType(titleX, verticalStarY) + assert.Equal(t, ClickNone, result, "click on title text (not pencil) should return ClickNone") + + // Click elsewhere (wrong y) + result = sb.HandleClickType(10, 0) + assert.Equal(t, ClickNone, result, "click elsewhere should return ClickNone") +} + +func TestSidebar_TitleRegenerating(t *testing.T) { + t.Parallel() + + sess := session.New() + sessionState := service.NewSessionState(sess) + sb := New(sessionState) + + m := sb.(*model) + m.sessionTitle = "Original Title" + + // Initially not regenerating + assert.False(t, m.titleRegenerating, "should not be regenerating initially") + assert.False(t, m.needsSpinner(), "should not need spinner initially") + + // Start regenerating + cmd := sb.SetTitleRegenerating(true) + assert.True(t, m.titleRegenerating, "should be regenerating after SetTitleRegenerating(true)") + assert.True(t, m.needsSpinner(), "should need spinner when regenerating") + // The returned command starts the spinner animation + assert.NotNil(t, cmd, "should return a command to start the spinner") + + // Stop regenerating + cmd = sb.SetTitleRegenerating(false) + assert.False(t, m.titleRegenerating, "should not be regenerating after SetTitleRegenerating(false)") + assert.False(t, m.needsSpinner(), "should not need spinner after stopping regeneration") + assert.Nil(t, cmd, "should return nil command when stopping") +} diff --git a/pkg/tui/handlers.go b/pkg/tui/handlers.go index 78bd24515..8d0a00459 100644 --- a/pkg/tui/handlers.go +++ b/pkg/tui/handlers.go @@ -2,6 +2,7 @@ package tui import ( "context" + "errors" "fmt" "log/slog" "os" @@ -10,6 +11,7 @@ import ( tea "charm.land/bubbletea/v2" "github.com/atotto/clipboard" + "github.com/docker/cagent/pkg/app" "github.com/docker/cagent/pkg/browser" "github.com/docker/cagent/pkg/evaluation" "github.com/docker/cagent/pkg/modelsdev" @@ -127,6 +129,41 @@ func (a *appModel) handleToggleSessionStar(sessionID string) (tea.Model, tea.Cmd return a, nil } +func (a *appModel) handleSetSessionTitle(title string) (tea.Model, tea.Cmd) { + if err := a.application.UpdateSessionTitle(context.Background(), title); err != nil { + if errors.Is(err, app.ErrTitleGenerating) { + return a, notification.WarningCmd("Title is being generated, please wait") + } + return a, notification.ErrorCmd(fmt.Sprintf("Failed to set session title: %v", err)) + } + // Title will be updated via SessionTitleEvent emitted by UpdateSessionTitle + return a, notification.SuccessCmd(fmt.Sprintf("Title set to: %s", title)) +} + +func (a *appModel) handleRegenerateTitle() (tea.Model, tea.Cmd) { + sess := a.application.Session() + if sess == nil { + return a, notification.ErrorCmd("No active session") + } + + if len(sess.GetLastUserMessages(1)) == 0 { + return a, notification.ErrorCmd("Cannot regenerate title: no user message in session") + } + + // Trigger regeneration - returns error if already in progress + if err := a.application.RegenerateSessionTitle(context.Background()); err != nil { + if errors.Is(err, app.ErrTitleGenerating) { + return a, notification.WarningCmd("Title is being generated, please wait") + } + return a, notification.ErrorCmd(fmt.Sprintf("Failed to regenerate title: %v", err)) + } + + // Show spinner while regenerating - the spinner will be cleared when SessionTitleEvent arrives + spinnerCmd := a.chatPage.SetTitleRegenerating(true) + + return a, tea.Batch(spinnerCmd, notification.SuccessCmd("Regenerating title...")) +} + func (a *appModel) handleEvalSession(filename string) (tea.Model, tea.Cmd) { evalFile, _ := evaluation.Save(a.application.Session(), filename) return a, notification.SuccessCmd(fmt.Sprintf("Eval saved to file %s", evalFile)) diff --git a/pkg/tui/messages/messages.go b/pkg/tui/messages/messages.go index 5c6996961..17b3635c2 100644 --- a/pkg/tui/messages/messages.go +++ b/pkg/tui/messages/messages.go @@ -25,6 +25,8 @@ type ( OpenSessionBrowserMsg struct{} LoadSessionMsg struct{ SessionID string } ToggleSessionStarMsg struct{ SessionID string } // Toggle star on a session; empty ID means current session + SetSessionTitleMsg struct{ Title string } // Set session title to specified value + RegenerateTitleMsg struct{} // Regenerate the session title using the AI AttachFileMsg struct{ FilePath string } // Attach a file directly or open file picker if empty/directory InsertFileRefMsg struct{ FilePath string } // Insert @filepath reference into editor OpenModelPickerMsg struct{} // Open the model picker dialog diff --git a/pkg/tui/page/chat/chat.go b/pkg/tui/page/chat/chat.go index edeb35180..314774bc8 100644 --- a/pkg/tui/page/chat/chat.go +++ b/pkg/tui/page/chat/chat.go @@ -111,6 +111,8 @@ type Page interface { GetInputHeight() int // SetSessionStarred updates the sidebar star indicator SetSessionStarred(starred bool) + // SetTitleRegenerating sets the title regenerating state on the sidebar + SetTitleRegenerating(regenerating bool) tea.Cmd // InsertText inserts text at the current cursor position in the editor InsertText(text string) // SetRecording sets the recording mode on the editor @@ -996,22 +998,26 @@ func (p *chatPage) SetSessionStarred(starred bool) { p.sidebar.SetSessionStarred(starred) } -// handleSidebarClick checks if a click in the sidebar area should toggle the star. -// Returns true if the click was handled. -func (p *chatPage) handleSidebarClick(x, y int) bool { +func (p *chatPage) SetTitleRegenerating(regenerating bool) tea.Cmd { + return p.sidebar.SetTitleRegenerating(regenerating) +} + +// handleSidebarClickType checks what was clicked in the sidebar area. +// Returns the type of click (star, title, or none). +func (p *chatPage) handleSidebarClickType(x, y int) sidebar.ClickResult { adjustedX := x - styles.AppPaddingLeft sl := p.computeSidebarLayout() switch sl.mode { case sidebarCollapsedNarrow, sidebarCollapsed: - return p.sidebar.HandleClick(adjustedX, y) + return p.sidebar.HandleClickType(adjustedX, y) case sidebarVertical: if sl.isInSidebar(adjustedX) { - return p.sidebar.HandleClick(adjustedX-sl.sidebarStartX, y) + return p.sidebar.HandleClickType(adjustedX-sl.sidebarStartX, y) } } - return false + return sidebar.ClickNone } // routeMouseEvent routes mouse events to the appropriate component based on coordinates. diff --git a/pkg/tui/page/chat/input_handlers.go b/pkg/tui/page/chat/input_handlers.go index 14cc969fa..733005f23 100644 --- a/pkg/tui/page/chat/input_handlers.go +++ b/pkg/tui/page/chat/input_handlers.go @@ -1,11 +1,16 @@ package chat import ( + "context" + "errors" + "charm.land/bubbles/v2/key" tea "charm.land/bubbletea/v2" + "github.com/docker/cagent/pkg/app" "github.com/docker/cagent/pkg/tui/components/editor" "github.com/docker/cagent/pkg/tui/components/messages" + "github.com/docker/cagent/pkg/tui/components/notification" "github.com/docker/cagent/pkg/tui/components/sidebar" "github.com/docker/cagent/pkg/tui/components/tool/editfile" "github.com/docker/cagent/pkg/tui/core" @@ -17,6 +22,22 @@ import ( // handleKeyPress handles keyboard input events for the chat page. // Returns the updated model and command, plus a bool indicating if the event was handled. func (p *chatPage) handleKeyPress(msg tea.KeyPressMsg) (layout.Model, tea.Cmd, bool) { + // When editing title, route keypresses to the sidebar + if p.sidebar.IsEditingTitle() { + switch msg.Key().Code { + case tea.KeyEnter: + newTitle := p.sidebar.CommitTitleEdit() + cmd := p.persistSessionTitle(newTitle) + return p, cmd, true + case tea.KeyEscape: + p.sidebar.CancelTitleEdit() + return p, nil, true + default: + cmd := p.sidebar.UpdateTitleInput(msg) + return p, cmd, true + } + } + switch { case key.Matches(msg, p.keyMap.Tab): if p.focusedPanel == PanelEditor { @@ -61,6 +82,21 @@ func (p *chatPage) handleKeyPress(msg tea.KeyPressMsg) (layout.Model, tea.Cmd, b return p, nil, false } +// persistSessionTitle saves the new session title to the store +func (p *chatPage) persistSessionTitle(newTitle string) tea.Cmd { + return func() tea.Msg { + if err := p.app.UpdateSessionTitle(context.Background(), newTitle); err != nil { + // Show warning if title generation is in progress + if errors.Is(err, app.ErrTitleGenerating) { + return notification.ShowMsg{Text: "Title is being generated, please wait", Type: notification.TypeWarning} + } + // Log other errors but don't show them + return nil + } + return nil + } +} + // handleMouseClick handles mouse click events. func (p *chatPage) handleMouseClick(msg tea.MouseClickMsg) (layout.Model, tea.Cmd) { if p.isOnResizeHandle(msg.X, msg.Y) { @@ -84,13 +120,20 @@ func (p *chatPage) handleMouseClick(msg tea.MouseClickMsg) (layout.Model, tea.Cm return p, nil } - // Check if click is on the star in sidebar - if msg.Button == tea.MouseLeft && p.handleSidebarClick(msg.X, msg.Y) { - sess := p.app.Session() - if sess != nil { - return p, core.CmdHandler(msgtypes.ToggleSessionStarMsg{SessionID: sess.ID}) + // Check if click is on the star or title in sidebar + if msg.Button == tea.MouseLeft { + clickResult := p.handleSidebarClickType(msg.X, msg.Y) + switch clickResult { + case sidebar.ClickStar: + sess := p.app.Session() + if sess != nil { + return p, core.CmdHandler(msgtypes.ToggleSessionStarMsg{SessionID: sess.ID}) + } + return p, nil + case sidebar.ClickPencil: + p.sidebar.BeginTitleEdit() + return p, nil } - return p, nil } cmd := p.routeMouseEvent(msg, msg.Y) diff --git a/pkg/tui/tui.go b/pkg/tui/tui.go index f1f9543af..d3f0001ca 100644 --- a/pkg/tui/tui.go +++ b/pkg/tui/tui.go @@ -318,6 +318,12 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } return a.handleToggleSessionStar(sessionID) + case messages.SetSessionTitleMsg: + return a.handleSetSessionTitle(msg.Title) + + case messages.RegenerateTitleMsg: + return a.handleRegenerateTitle() + case messages.StartShellMsg: return a.startShell() diff --git a/pkg/tui/tui_exit_test.go b/pkg/tui/tui_exit_test.go index fd5224cb1..c04e26269 100644 --- a/pkg/tui/tui_exit_test.go +++ b/pkg/tui/tui_exit_test.go @@ -30,6 +30,7 @@ func (m *mockChatPage) CompactSession(string) tea.Cmd { return nil } func (m *mockChatPage) Cleanup() { m.cleanupCalled = true } func (m *mockChatPage) GetInputHeight() int { return 0 } func (m *mockChatPage) SetSessionStarred(bool) {} +func (m *mockChatPage) SetTitleRegenerating(bool) tea.Cmd { return nil } func (m *mockChatPage) InsertText(string) {} func (m *mockChatPage) SetRecording(bool) tea.Cmd { return nil } func (m *mockChatPage) SendEditorContent() tea.Cmd { return nil } diff --git a/proto/cagent/v1/cagent.proto b/proto/cagent/v1/cagent.proto index cf0ef8382..55384a446 100644 --- a/proto/cagent/v1/cagent.proto +++ b/proto/cagent/v1/cagent.proto @@ -30,6 +30,9 @@ service AgentService { // ToggleToolApproval toggles the YOLO mode for a session. rpc ToggleToolApproval(ToggleToolApprovalRequest) returns (ToggleToolApprovalResponse); + // UpdateSessionTitle updates the title of a session. + rpc UpdateSessionTitle(UpdateSessionTitleRequest) returns (UpdateSessionTitleResponse); + // ResumeElicitation resumes an elicitation request. rpc ResumeElicitation(ResumeElicitationRequest) returns (ResumeElicitationResponse); @@ -155,6 +158,7 @@ message DeleteSessionResponse {} message ResumeSessionRequest { string id = 1; string confirmation = 2; // "approve", "approve-session", or "reject" + string reason = 3; // optional reason for rejection } // ResumeSessionResponse is the response for ResumeSession. @@ -168,6 +172,18 @@ message ToggleToolApprovalRequest { // ToggleToolApprovalResponse is the response for ToggleToolApproval. message ToggleToolApprovalResponse {} +// UpdateSessionTitleRequest is the request for UpdateSessionTitle. +message UpdateSessionTitleRequest { + string session_id = 1; + string title = 2; +} + +// UpdateSessionTitleResponse is the response for UpdateSessionTitle. +message UpdateSessionTitleResponse { + string session_id = 1; + string title = 2; +} + // ResumeElicitationRequest is the request for ResumeElicitation. message ResumeElicitationRequest { string session_id = 1;