diff --git a/crates/agent-gateway/internal/proto/v2/gateway.pb.go b/crates/agent-gateway/internal/proto/v2/gateway.pb.go index bccca859a..32b9e8b69 100644 --- a/crates/agent-gateway/internal/proto/v2/gateway.pb.go +++ b/crates/agent-gateway/internal/proto/v2/gateway.pb.go @@ -335,6 +335,7 @@ type GatewayEnvelope struct { // *GatewayEnvelope_HistoryBranch // *GatewayEnvelope_ProviderUsage // *GatewayEnvelope_ChatFileOpen + // *GatewayEnvelope_HistorySetCwd Payload isGatewayEnvelope_Payload `protobuf_oneof:"payload"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -832,6 +833,15 @@ func (x *GatewayEnvelope) GetChatFileOpen() *ChatFileOpenRequest { return nil } +func (x *GatewayEnvelope) GetHistorySetCwd() *HistorySetCwdRequest { + if x != nil { + if x, ok := x.Payload.(*GatewayEnvelope_HistorySetCwd); ok { + return x.HistorySetCwd + } + } + return nil +} + type isGatewayEnvelope_Payload interface { isGatewayEnvelope_Payload() } @@ -1032,6 +1042,10 @@ type GatewayEnvelope_ChatFileOpen struct { ChatFileOpen *ChatFileOpenRequest `protobuf:"bytes,94,opt,name=chat_file_open,json=chatFileOpen,proto3,oneof"` } +type GatewayEnvelope_HistorySetCwd struct { + HistorySetCwd *HistorySetCwdRequest `protobuf:"bytes,95,opt,name=history_set_cwd,json=historySetCwd,proto3,oneof"` +} + func (*GatewayEnvelope_ChatCommand) isGatewayEnvelope_Payload() {} func (*GatewayEnvelope_CronManage) isGatewayEnvelope_Payload() {} @@ -1130,6 +1144,8 @@ func (*GatewayEnvelope_ProviderUsage) isGatewayEnvelope_Payload() {} func (*GatewayEnvelope_ChatFileOpen) isGatewayEnvelope_Payload() {} +func (*GatewayEnvelope_HistorySetCwd) isGatewayEnvelope_Payload() {} + type AgentEnvelope struct { state protoimpl.MessageState `protogen:"open.v1"` RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` @@ -1198,6 +1214,7 @@ type AgentEnvelope struct { // *AgentEnvelope_ChatIngressFragment // *AgentEnvelope_ChatFileOpenResp // *AgentEnvelope_Error + // *AgentEnvelope_HistorySetCwdResp Payload isAgentEnvelope_Payload `protobuf_oneof:"payload"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1812,6 +1829,15 @@ func (x *AgentEnvelope) GetError() *ErrorResponse { return nil } +func (x *AgentEnvelope) GetHistorySetCwdResp() *HistorySetCwdResponse { + if x != nil { + if x, ok := x.Payload.(*AgentEnvelope_HistorySetCwdResp); ok { + return x.HistorySetCwdResp + } + } + return nil +} + type isAgentEnvelope_Payload interface { isAgentEnvelope_Payload() } @@ -2064,6 +2090,10 @@ type AgentEnvelope_Error struct { Error *ErrorResponse `protobuf:"bytes,99,opt,name=error,proto3,oneof"` } +type AgentEnvelope_HistorySetCwdResp struct { + HistorySetCwdResp *HistorySetCwdResponse `protobuf:"bytes,100,opt,name=history_set_cwd_resp,json=historySetCwdResp,proto3,oneof"` +} + func (*AgentEnvelope_ChatEvent) isAgentEnvelope_Payload() {} func (*AgentEnvelope_CronManageResp) isAgentEnvelope_Payload() {} @@ -2188,6 +2218,8 @@ func (*AgentEnvelope_ChatFileOpenResp) isAgentEnvelope_Payload() {} func (*AgentEnvelope_Error) isAgentEnvelope_Payload() {} +func (*AgentEnvelope_HistorySetCwdResp) isAgentEnvelope_Payload() {} + type ChatSelectedModel struct { state protoimpl.MessageState `protogen:"open.v1"` CustomProviderId string `protobuf:"bytes,1,opt,name=custom_provider_id,json=customProviderId,proto3" json:"custom_provider_id,omitempty"` @@ -12533,11 +12565,107 @@ func (x *ChatIngressAck) GetErrorMessage() string { return "" } +type HistorySetCwdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ConversationId string `protobuf:"bytes,1,opt,name=conversation_id,json=conversationId,proto3" json:"conversation_id,omitempty"` + Cwd string `protobuf:"bytes,2,opt,name=cwd,proto3" json:"cwd,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *HistorySetCwdRequest) Reset() { + *x = HistorySetCwdRequest{} + mi := &file_proto_v2_gateway_proto_msgTypes[151] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HistorySetCwdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HistorySetCwdRequest) ProtoMessage() {} + +func (x *HistorySetCwdRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_v2_gateway_proto_msgTypes[151] + 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 HistorySetCwdRequest.ProtoReflect.Descriptor instead. +func (*HistorySetCwdRequest) Descriptor() ([]byte, []int) { + return file_proto_v2_gateway_proto_rawDescGZIP(), []int{151} +} + +func (x *HistorySetCwdRequest) GetConversationId() string { + if x != nil { + return x.ConversationId + } + return "" +} + +func (x *HistorySetCwdRequest) GetCwd() string { + if x != nil { + return x.Cwd + } + return "" +} + +type HistorySetCwdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Conversation *ConversationSummary `protobuf:"bytes,1,opt,name=conversation,proto3" json:"conversation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *HistorySetCwdResponse) Reset() { + *x = HistorySetCwdResponse{} + mi := &file_proto_v2_gateway_proto_msgTypes[152] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *HistorySetCwdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HistorySetCwdResponse) ProtoMessage() {} + +func (x *HistorySetCwdResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_v2_gateway_proto_msgTypes[152] + 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 HistorySetCwdResponse.ProtoReflect.Descriptor instead. +func (*HistorySetCwdResponse) Descriptor() ([]byte, []int) { + return file_proto_v2_gateway_proto_rawDescGZIP(), []int{152} +} + +func (x *HistorySetCwdResponse) GetConversation() *ConversationSummary { + if x != nil { + return x.Conversation + } + return nil +} + var File_proto_v2_gateway_proto protoreflect.FileDescriptor const file_proto_v2_gateway_proto_rawDesc = "" + "\n" + - "\x16proto/v2/gateway.proto\x12\x14liveagent.gateway.v2\"\xb2!\n" + + "\x16proto/v2/gateway.proto\x12\x14liveagent.gateway.v2\"\x88\"\n" + "\x0fGatewayEnvelope\x12\x1d\n" + "\n" + "request_id\x18\x01 \x01(\tR\trequestId\x12\x1c\n" + @@ -12597,8 +12725,9 @@ const file_proto_v2_gateway_proto_rawDesc = "" + "\x17managed_process_request\x18[ \x01(\v2+.liveagent.gateway.v2.ManagedProcessRequestH\x00R\x15managedProcessRequest\x12S\n" + "\x0ehistory_branch\x18\\ \x01(\v2*.liveagent.gateway.v2.HistoryBranchRequestH\x00R\rhistoryBranch\x12S\n" + "\x0eprovider_usage\x18] \x01(\v2*.liveagent.gateway.v2.ProviderUsageRequestH\x00R\rproviderUsage\x12Q\n" + - "\x0echat_file_open\x18^ \x01(\v2).liveagent.gateway.v2.ChatFileOpenRequestH\x00R\fchatFileOpenB\t\n" + - "\apayloadJ\x04\bC\x10DJ\x04\bD\x10EJ\x04\bE\x10FJ\x04\bJ\x10K\"\x8e-\n" + + "\x0echat_file_open\x18^ \x01(\v2).liveagent.gateway.v2.ChatFileOpenRequestH\x00R\fchatFileOpen\x12T\n" + + "\x0fhistory_set_cwd\x18_ \x01(\v2*.liveagent.gateway.v2.HistorySetCwdRequestH\x00R\rhistorySetCwdB\t\n" + + "\apayloadJ\x04\bC\x10DJ\x04\bD\x10EJ\x04\bE\x10FJ\x04\bJ\x10K\"\xee-\n" + "\rAgentEnvelope\x12\x1d\n" + "\n" + "request_id\x18\x01 \x01(\tR\trequestId\x12\x1c\n" + @@ -12668,7 +12797,8 @@ const file_proto_v2_gateway_proto_rawDesc = "" + "\x13chat_ingress_resume\x18` \x01(\v2'.liveagent.gateway.v2.ChatIngressResumeH\x00R\x11chatIngressResume\x12_\n" + "\x15chat_ingress_fragment\x18a \x01(\v2).liveagent.gateway.v2.ChatIngressFragmentH\x00R\x13chatIngressFragment\x12[\n" + "\x13chat_file_open_resp\x18b \x01(\v2*.liveagent.gateway.v2.ChatFileOpenResponseH\x00R\x10chatFileOpenResp\x12;\n" + - "\x05error\x18c \x01(\v2#.liveagent.gateway.v2.ErrorResponseH\x00R\x05errorB\t\n" + + "\x05error\x18c \x01(\v2#.liveagent.gateway.v2.ErrorResponseH\x00R\x05error\x12^\n" + + "\x14history_set_cwd_resp\x18d \x01(\v2+.liveagent.gateway.v2.HistorySetCwdResponseH\x00R\x11historySetCwdRespB\t\n" + "\apayloadJ\x04\bC\x10DJ\x04\bD\x10EJ\x04\bE\x10FJ\x04\bN\x10O\"|\n" + "\x11ChatSelectedModel\x12,\n" + "\x12custom_provider_id\x18\x01 \x01(\tR\x10customProviderId\x12\x14\n" + @@ -13579,7 +13709,12 @@ const file_proto_v2_gateway_proto_rawDesc = "" + "\bCONTINUE\x10\x01\x12\x18\n" + "\x14REPLAY_FROM_EXPECTED\x10\x02\x12\x13\n" + "\x0fSEND_CHECKPOINT\x10\x03\x12\f\n" + - "\bREJECTED\x10\x04*\xc6\x04\n" + + "\bREJECTED\x10\x04\"Q\n" + + "\x14HistorySetCwdRequest\x12'\n" + + "\x0fconversation_id\x18\x01 \x01(\tR\x0econversationId\x12\x10\n" + + "\x03cwd\x18\x02 \x01(\tR\x03cwd\"f\n" + + "\x15HistorySetCwdResponse\x12M\n" + + "\fconversation\x18\x01 \x01(\v2).liveagent.gateway.v2.ConversationSummaryR\fconversation*\xc6\x04\n" + "\x0fTunnelFrameKind\x12!\n" + "\x1dTUNNEL_FRAME_KIND_UNSPECIFIED\x10\x00\x12(\n" + "$TUNNEL_FRAME_KIND_HTTP_REQUEST_START\x10\x01\x12'\n" + @@ -13616,7 +13751,7 @@ func file_proto_v2_gateway_proto_rawDescGZIP() []byte { } var file_proto_v2_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_proto_v2_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 151) +var file_proto_v2_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 153) var file_proto_v2_gateway_proto_goTypes = []any{ (TunnelFrameKind)(0), // 0: liveagent.gateway.v2.TunnelFrameKind (TunnelWsMessageType)(0), // 1: liveagent.gateway.v2.TunnelWsMessageType @@ -13773,6 +13908,8 @@ var file_proto_v2_gateway_proto_goTypes = []any{ (*ChatIngressRunResume)(nil), // 152: liveagent.gateway.v2.ChatIngressRunResume (*ChatIngressFragment)(nil), // 153: liveagent.gateway.v2.ChatIngressFragment (*ChatIngressAck)(nil), // 154: liveagent.gateway.v2.ChatIngressAck + (*HistorySetCwdRequest)(nil), // 155: liveagent.gateway.v2.HistorySetCwdRequest + (*HistorySetCwdResponse)(nil), // 156: liveagent.gateway.v2.HistorySetCwdResponse } var file_proto_v2_gateway_proto_depIdxs = []int32{ 56, // 0: liveagent.gateway.v2.GatewayEnvelope.chat_command:type_name -> liveagent.gateway.v2.ChatCommandRequest @@ -13824,138 +13961,141 @@ var file_proto_v2_gateway_proto_depIdxs = []int32{ 76, // 46: liveagent.gateway.v2.GatewayEnvelope.history_branch:type_name -> liveagent.gateway.v2.HistoryBranchRequest 143, // 47: liveagent.gateway.v2.GatewayEnvelope.provider_usage:type_name -> liveagent.gateway.v2.ProviderUsageRequest 128, // 48: liveagent.gateway.v2.GatewayEnvelope.chat_file_open:type_name -> liveagent.gateway.v2.ChatFileOpenRequest - 60, // 49: liveagent.gateway.v2.AgentEnvelope.chat_event:type_name -> liveagent.gateway.v2.ChatEvent - 66, // 50: liveagent.gateway.v2.AgentEnvelope.cron_manage_resp:type_name -> liveagent.gateway.v2.CronManageResponse - 68, // 51: liveagent.gateway.v2.AgentEnvelope.history_list_resp:type_name -> liveagent.gateway.v2.HistoryListResponse - 71, // 52: liveagent.gateway.v2.AgentEnvelope.history_get_resp:type_name -> liveagent.gateway.v2.HistoryGetResponse - 75, // 53: liveagent.gateway.v2.AgentEnvelope.history_rename_resp:type_name -> liveagent.gateway.v2.HistoryRenameResponse - 91, // 54: liveagent.gateway.v2.AgentEnvelope.history_delete_resp:type_name -> liveagent.gateway.v2.HistoryDeleteResponse - 92, // 55: liveagent.gateway.v2.AgentEnvelope.history_sync:type_name -> liveagent.gateway.v2.HistorySyncEvent - 73, // 56: liveagent.gateway.v2.AgentEnvelope.history_prefix_resp:type_name -> liveagent.gateway.v2.HistoryPrefixResponse - 79, // 57: liveagent.gateway.v2.AgentEnvelope.history_pin_resp:type_name -> liveagent.gateway.v2.HistoryPinResponse - 82, // 58: liveagent.gateway.v2.AgentEnvelope.history_share_get_resp:type_name -> liveagent.gateway.v2.HistoryShareGetResponse - 84, // 59: liveagent.gateway.v2.AgentEnvelope.history_share_set_resp:type_name -> liveagent.gateway.v2.HistoryShareSetResponse - 86, // 60: liveagent.gateway.v2.AgentEnvelope.history_share_resolve_resp:type_name -> liveagent.gateway.v2.HistoryShareResolveResponse - 89, // 61: liveagent.gateway.v2.AgentEnvelope.history_workdirs_resp:type_name -> liveagent.gateway.v2.HistoryWorkdirsResponse - 94, // 62: liveagent.gateway.v2.AgentEnvelope.provider_list_resp:type_name -> liveagent.gateway.v2.ProviderListResponse - 96, // 63: liveagent.gateway.v2.AgentEnvelope.settings_get_resp:type_name -> liveagent.gateway.v2.SettingsGetResponse - 98, // 64: liveagent.gateway.v2.AgentEnvelope.settings_update_resp:type_name -> liveagent.gateway.v2.SettingsUpdateResponse - 101, // 65: liveagent.gateway.v2.AgentEnvelope.settings_sync:type_name -> liveagent.gateway.v2.SettingsSyncEvent - 103, // 66: liveagent.gateway.v2.AgentEnvelope.skill_files_list_resp:type_name -> liveagent.gateway.v2.SkillFilesListResponse - 105, // 67: liveagent.gateway.v2.AgentEnvelope.skill_metadata_read_resp:type_name -> liveagent.gateway.v2.SkillMetadataReadResponse - 107, // 68: liveagent.gateway.v2.AgentEnvelope.skill_text_read_resp:type_name -> liveagent.gateway.v2.SkillTextReadResponse - 112, // 69: liveagent.gateway.v2.AgentEnvelope.file_mention_list_resp:type_name -> liveagent.gateway.v2.FileMentionListResponse - 11, // 70: liveagent.gateway.v2.AgentEnvelope.upload_readable_files_resp:type_name -> liveagent.gateway.v2.UploadReadableFilesResponse - 115, // 71: liveagent.gateway.v2.AgentEnvelope.fs_roots_resp:type_name -> liveagent.gateway.v2.FsRootsResponse - 139, // 72: liveagent.gateway.v2.AgentEnvelope.pong:type_name -> liveagent.gateway.v2.PongResponse - 118, // 73: liveagent.gateway.v2.AgentEnvelope.fs_list_dirs_resp:type_name -> liveagent.gateway.v2.FsListDirsResponse - 13, // 74: liveagent.gateway.v2.AgentEnvelope.uploaded_image_preview_resp:type_name -> liveagent.gateway.v2.UploadedImagePreviewResponse - 32, // 75: liveagent.gateway.v2.AgentEnvelope.memory_manage_resp:type_name -> liveagent.gateway.v2.MemoryManageResponse - 109, // 76: liveagent.gateway.v2.AgentEnvelope.skill_manage_resp:type_name -> liveagent.gateway.v2.SkillManageResponse - 120, // 77: liveagent.gateway.v2.AgentEnvelope.fs_create_project_folder_resp:type_name -> liveagent.gateway.v2.FsCreateProjectFolderResponse - 48, // 78: liveagent.gateway.v2.AgentEnvelope.terminal_response:type_name -> liveagent.gateway.v2.TerminalResponse - 49, // 79: liveagent.gateway.v2.AgentEnvelope.terminal_event:type_name -> liveagent.gateway.v2.TerminalEvent - 123, // 80: liveagent.gateway.v2.AgentEnvelope.fs_list_resp:type_name -> liveagent.gateway.v2.FsListResponse - 131, // 81: liveagent.gateway.v2.AgentEnvelope.fs_write_text_resp:type_name -> liveagent.gateway.v2.FsWriteTextResponse - 133, // 82: liveagent.gateway.v2.AgentEnvelope.fs_create_dir_resp:type_name -> liveagent.gateway.v2.FsCreateDirResponse - 135, // 83: liveagent.gateway.v2.AgentEnvelope.fs_rename_resp:type_name -> liveagent.gateway.v2.FsRenameResponse - 137, // 84: liveagent.gateway.v2.AgentEnvelope.fs_delete_resp:type_name -> liveagent.gateway.v2.FsDeleteResponse - 52, // 85: liveagent.gateway.v2.AgentEnvelope.git_response:type_name -> liveagent.gateway.v2.GitResponse - 125, // 86: liveagent.gateway.v2.AgentEnvelope.fs_read_editable_text_resp:type_name -> liveagent.gateway.v2.FsReadEditableTextResponse - 127, // 87: liveagent.gateway.v2.AgentEnvelope.fs_read_workspace_image_resp:type_name -> liveagent.gateway.v2.FsReadWorkspaceImageResponse - 39, // 88: liveagent.gateway.v2.AgentEnvelope.sftp_response:type_name -> liveagent.gateway.v2.SftpResponse - 40, // 89: liveagent.gateway.v2.AgentEnvelope.sftp_event:type_name -> liveagent.gateway.v2.SftpEvent - 58, // 90: liveagent.gateway.v2.AgentEnvelope.chat_queue_resp:type_name -> liveagent.gateway.v2.ChatQueueResponse - 59, // 91: liveagent.gateway.v2.AgentEnvelope.chat_queue_event:type_name -> liveagent.gateway.v2.ChatQueueEvent - 61, // 92: liveagent.gateway.v2.AgentEnvelope.chat_control:type_name -> liveagent.gateway.v2.ChatControlEvent - 63, // 93: liveagent.gateway.v2.AgentEnvelope.runtime_status:type_name -> liveagent.gateway.v2.RuntimeStatusEvent - 100, // 94: liveagent.gateway.v2.AgentEnvelope.settings_reset_ssh_known_host_resp:type_name -> liveagent.gateway.v2.SettingsResetSshKnownHostResponse - 62, // 95: liveagent.gateway.v2.AgentEnvelope.chat_runtime_snapshot:type_name -> liveagent.gateway.v2.ChatRuntimeSnapshot - 142, // 96: liveagent.gateway.v2.AgentEnvelope.provider_models_resp:type_name -> liveagent.gateway.v2.ProviderModelsResponse - 15, // 97: liveagent.gateway.v2.AgentEnvelope.tunnel_desired:type_name -> liveagent.gateway.v2.TunnelDesiredState - 20, // 98: liveagent.gateway.v2.AgentEnvelope.tunnel_mutation_result:type_name -> liveagent.gateway.v2.TunnelMutationResult - 24, // 99: liveagent.gateway.v2.AgentEnvelope.tunnel_frame:type_name -> liveagent.gateway.v2.TunnelFrame - 22, // 100: liveagent.gateway.v2.AgentEnvelope.tunnel_probe_report:type_name -> liveagent.gateway.v2.TunnelProbeReport - 26, // 101: liveagent.gateway.v2.AgentEnvelope.workspace_activity:type_name -> liveagent.gateway.v2.WorkspaceActivityEvent - 30, // 102: liveagent.gateway.v2.AgentEnvelope.managed_process_response:type_name -> liveagent.gateway.v2.ManagedProcessResponse - 28, // 103: liveagent.gateway.v2.AgentEnvelope.managed_process_snapshot:type_name -> liveagent.gateway.v2.ManagedProcessSnapshot - 77, // 104: liveagent.gateway.v2.AgentEnvelope.history_branch_resp:type_name -> liveagent.gateway.v2.HistoryBranchResponse - 144, // 105: liveagent.gateway.v2.AgentEnvelope.provider_usage_resp:type_name -> liveagent.gateway.v2.ProviderUsageResponse - 145, // 106: liveagent.gateway.v2.AgentEnvelope.chat_ingress_batch:type_name -> liveagent.gateway.v2.ChatIngressBatch - 151, // 107: liveagent.gateway.v2.AgentEnvelope.chat_ingress_resume:type_name -> liveagent.gateway.v2.ChatIngressResume - 153, // 108: liveagent.gateway.v2.AgentEnvelope.chat_ingress_fragment:type_name -> liveagent.gateway.v2.ChatIngressFragment - 129, // 109: liveagent.gateway.v2.AgentEnvelope.chat_file_open_resp:type_name -> liveagent.gateway.v2.ChatFileOpenResponse - 140, // 110: liveagent.gateway.v2.AgentEnvelope.error:type_name -> liveagent.gateway.v2.ErrorResponse - 9, // 111: liveagent.gateway.v2.UploadReadableFilesRequest.files:type_name -> liveagent.gateway.v2.UploadReadableFile - 8, // 112: liveagent.gateway.v2.UploadReadableFilesResponse.files:type_name -> liveagent.gateway.v2.ChatUploadedFile - 14, // 113: liveagent.gateway.v2.TunnelDesiredState.tunnels:type_name -> liveagent.gateway.v2.TunnelSpec - 16, // 114: liveagent.gateway.v2.TunnelStatus.local:type_name -> liveagent.gateway.v2.TunnelHealth - 17, // 115: liveagent.gateway.v2.TunnelStateSnapshot.tunnels:type_name -> liveagent.gateway.v2.TunnelStatus - 16, // 116: liveagent.gateway.v2.TunnelStateSnapshot.relay:type_name -> liveagent.gateway.v2.TunnelHealth - 16, // 117: liveagent.gateway.v2.TunnelProbeResult.local:type_name -> liveagent.gateway.v2.TunnelHealth - 21, // 118: liveagent.gateway.v2.TunnelProbeReport.results:type_name -> liveagent.gateway.v2.TunnelProbeResult - 0, // 119: liveagent.gateway.v2.TunnelFrame.kind:type_name -> liveagent.gateway.v2.TunnelFrameKind - 23, // 120: liveagent.gateway.v2.TunnelFrame.headers:type_name -> liveagent.gateway.v2.TunnelHeader - 1, // 121: liveagent.gateway.v2.TunnelFrame.ws_message_type:type_name -> liveagent.gateway.v2.TunnelWsMessageType - 27, // 122: liveagent.gateway.v2.ManagedProcessSnapshot.processes:type_name -> liveagent.gateway.v2.ManagedProcessRecord - 28, // 123: liveagent.gateway.v2.ManagedProcessResponse.snapshot:type_name -> liveagent.gateway.v2.ManagedProcessSnapshot - 35, // 124: liveagent.gateway.v2.TerminalSession.ssh:type_name -> liveagent.gateway.v2.TerminalSshMetadata - 37, // 125: liveagent.gateway.v2.SftpResponse.entries:type_name -> liveagent.gateway.v2.SftpEntry - 37, // 126: liveagent.gateway.v2.SftpResponse.entry:type_name -> liveagent.gateway.v2.SftpEntry - 38, // 127: liveagent.gateway.v2.SftpResponse.transfer:type_name -> liveagent.gateway.v2.SftpTransfer - 38, // 128: liveagent.gateway.v2.SftpEvent.transfer:type_name -> liveagent.gateway.v2.SftpTransfer - 43, // 129: liveagent.gateway.v2.TerminalSshTabsSnapshot.tabs:type_name -> liveagent.gateway.v2.TerminalSshTab - 45, // 130: liveagent.gateway.v2.TerminalSshLocalForwardsSnapshot.forwards:type_name -> liveagent.gateway.v2.TerminalSshLocalForward - 45, // 131: liveagent.gateway.v2.TerminalSshLocalForwardAction.forward:type_name -> liveagent.gateway.v2.TerminalSshLocalForward - 34, // 132: liveagent.gateway.v2.TerminalResponse.sessions:type_name -> liveagent.gateway.v2.TerminalSession - 34, // 133: liveagent.gateway.v2.TerminalResponse.session:type_name -> liveagent.gateway.v2.TerminalSession - 42, // 134: liveagent.gateway.v2.TerminalResponse.shell_options:type_name -> liveagent.gateway.v2.TerminalShellOption - 41, // 135: liveagent.gateway.v2.TerminalResponse.ssh_prompt:type_name -> liveagent.gateway.v2.TerminalSshPrompt - 44, // 136: liveagent.gateway.v2.TerminalResponse.ssh_tabs:type_name -> liveagent.gateway.v2.TerminalSshTabsSnapshot - 46, // 137: liveagent.gateway.v2.TerminalResponse.ssh_local_forwards:type_name -> liveagent.gateway.v2.TerminalSshLocalForwardsSnapshot - 47, // 138: liveagent.gateway.v2.TerminalResponse.ssh_local_forward:type_name -> liveagent.gateway.v2.TerminalSshLocalForwardAction - 34, // 139: liveagent.gateway.v2.TerminalEvent.session:type_name -> liveagent.gateway.v2.TerminalSession - 44, // 140: liveagent.gateway.v2.TerminalEvent.ssh_tabs:type_name -> liveagent.gateway.v2.TerminalSshTabsSnapshot - 47, // 141: liveagent.gateway.v2.TerminalEvent.ssh_local_forward:type_name -> liveagent.gateway.v2.TerminalSshLocalForwardAction - 34, // 142: liveagent.gateway.v2.TerminalStreamFrame.session:type_name -> liveagent.gateway.v2.TerminalSession - 6, // 143: liveagent.gateway.v2.ChatRequest.selected_model:type_name -> liveagent.gateway.v2.ChatSelectedModel - 8, // 144: liveagent.gateway.v2.ChatRequest.uploaded_files:type_name -> liveagent.gateway.v2.ChatUploadedFile - 7, // 145: liveagent.gateway.v2.ChatRequest.runtime_controls:type_name -> liveagent.gateway.v2.ChatRuntimeControls - 53, // 146: liveagent.gateway.v2.ChatCommandRequest.request:type_name -> liveagent.gateway.v2.ChatRequest - 54, // 147: liveagent.gateway.v2.ChatCommandRequest.base_message_ref:type_name -> liveagent.gateway.v2.ChatMessageRef - 55, // 148: liveagent.gateway.v2.ChatCommandRequest.cancel:type_name -> liveagent.gateway.v2.CancelChatRequest - 2, // 149: liveagent.gateway.v2.ChatEvent.type:type_name -> liveagent.gateway.v2.ChatEvent.ChatEventType - 64, // 150: liveagent.gateway.v2.RuntimeStatusEvent.active_runs:type_name -> liveagent.gateway.v2.ChatRunReport - 64, // 151: liveagent.gateway.v2.RuntimeStatusEvent.finished_runs:type_name -> liveagent.gateway.v2.ChatRunReport - 69, // 152: liveagent.gateway.v2.HistoryListResponse.conversations:type_name -> liveagent.gateway.v2.ConversationSummary - 69, // 153: liveagent.gateway.v2.HistoryGetResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary - 54, // 154: liveagent.gateway.v2.HistoryPrefixRequest.base_message_ref:type_name -> liveagent.gateway.v2.ChatMessageRef - 69, // 155: liveagent.gateway.v2.HistoryPrefixResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary - 69, // 156: liveagent.gateway.v2.HistoryRenameResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary - 54, // 157: liveagent.gateway.v2.HistoryBranchRequest.base_message_ref:type_name -> liveagent.gateway.v2.ChatMessageRef - 69, // 158: liveagent.gateway.v2.HistoryBranchResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary - 69, // 159: liveagent.gateway.v2.HistoryPinResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary - 80, // 160: liveagent.gateway.v2.HistoryShareGetResponse.share:type_name -> liveagent.gateway.v2.HistoryShareStatus - 80, // 161: liveagent.gateway.v2.HistoryShareSetResponse.share:type_name -> liveagent.gateway.v2.HistoryShareStatus - 69, // 162: liveagent.gateway.v2.HistoryShareResolveResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary - 88, // 163: liveagent.gateway.v2.HistoryWorkdirsResponse.workdirs:type_name -> liveagent.gateway.v2.HistoryWorkdirSummary - 69, // 164: liveagent.gateway.v2.HistorySyncEvent.conversation:type_name -> liveagent.gateway.v2.ConversationSummary - 111, // 165: liveagent.gateway.v2.FileMentionListResponse.entries:type_name -> liveagent.gateway.v2.FileMentionEntry - 113, // 166: liveagent.gateway.v2.FsRootsResponse.roots:type_name -> liveagent.gateway.v2.FsRoot - 117, // 167: liveagent.gateway.v2.FsListDirsResponse.entries:type_name -> liveagent.gateway.v2.FsDirEntry - 122, // 168: liveagent.gateway.v2.FsListResponse.entries:type_name -> liveagent.gateway.v2.FsListEntry - 146, // 169: liveagent.gateway.v2.ChatIngressBatch.records:type_name -> liveagent.gateway.v2.ChatIngressRecord - 147, // 170: liveagent.gateway.v2.ChatIngressRecord.delta:type_name -> liveagent.gateway.v2.ChatIngressDelta - 149, // 171: liveagent.gateway.v2.ChatIngressRecord.checkpoint:type_name -> liveagent.gateway.v2.ChatIngressCheckpoint - 150, // 172: liveagent.gateway.v2.ChatIngressRecord.terminal:type_name -> liveagent.gateway.v2.ChatIngressTerminal - 148, // 173: liveagent.gateway.v2.ChatIngressRecord.heartbeat:type_name -> liveagent.gateway.v2.ChatIngressHeartbeat - 152, // 174: liveagent.gateway.v2.ChatIngressResume.runs:type_name -> liveagent.gateway.v2.ChatIngressRunResume - 3, // 175: liveagent.gateway.v2.ChatIngressAck.action:type_name -> liveagent.gateway.v2.ChatIngressAck.Action - 176, // [176:176] is the sub-list for method output_type - 176, // [176:176] is the sub-list for method input_type - 176, // [176:176] is the sub-list for extension type_name - 176, // [176:176] is the sub-list for extension extendee - 0, // [0:176] is the sub-list for field type_name + 155, // 49: liveagent.gateway.v2.GatewayEnvelope.history_set_cwd:type_name -> liveagent.gateway.v2.HistorySetCwdRequest + 60, // 50: liveagent.gateway.v2.AgentEnvelope.chat_event:type_name -> liveagent.gateway.v2.ChatEvent + 66, // 51: liveagent.gateway.v2.AgentEnvelope.cron_manage_resp:type_name -> liveagent.gateway.v2.CronManageResponse + 68, // 52: liveagent.gateway.v2.AgentEnvelope.history_list_resp:type_name -> liveagent.gateway.v2.HistoryListResponse + 71, // 53: liveagent.gateway.v2.AgentEnvelope.history_get_resp:type_name -> liveagent.gateway.v2.HistoryGetResponse + 75, // 54: liveagent.gateway.v2.AgentEnvelope.history_rename_resp:type_name -> liveagent.gateway.v2.HistoryRenameResponse + 91, // 55: liveagent.gateway.v2.AgentEnvelope.history_delete_resp:type_name -> liveagent.gateway.v2.HistoryDeleteResponse + 92, // 56: liveagent.gateway.v2.AgentEnvelope.history_sync:type_name -> liveagent.gateway.v2.HistorySyncEvent + 73, // 57: liveagent.gateway.v2.AgentEnvelope.history_prefix_resp:type_name -> liveagent.gateway.v2.HistoryPrefixResponse + 79, // 58: liveagent.gateway.v2.AgentEnvelope.history_pin_resp:type_name -> liveagent.gateway.v2.HistoryPinResponse + 82, // 59: liveagent.gateway.v2.AgentEnvelope.history_share_get_resp:type_name -> liveagent.gateway.v2.HistoryShareGetResponse + 84, // 60: liveagent.gateway.v2.AgentEnvelope.history_share_set_resp:type_name -> liveagent.gateway.v2.HistoryShareSetResponse + 86, // 61: liveagent.gateway.v2.AgentEnvelope.history_share_resolve_resp:type_name -> liveagent.gateway.v2.HistoryShareResolveResponse + 89, // 62: liveagent.gateway.v2.AgentEnvelope.history_workdirs_resp:type_name -> liveagent.gateway.v2.HistoryWorkdirsResponse + 94, // 63: liveagent.gateway.v2.AgentEnvelope.provider_list_resp:type_name -> liveagent.gateway.v2.ProviderListResponse + 96, // 64: liveagent.gateway.v2.AgentEnvelope.settings_get_resp:type_name -> liveagent.gateway.v2.SettingsGetResponse + 98, // 65: liveagent.gateway.v2.AgentEnvelope.settings_update_resp:type_name -> liveagent.gateway.v2.SettingsUpdateResponse + 101, // 66: liveagent.gateway.v2.AgentEnvelope.settings_sync:type_name -> liveagent.gateway.v2.SettingsSyncEvent + 103, // 67: liveagent.gateway.v2.AgentEnvelope.skill_files_list_resp:type_name -> liveagent.gateway.v2.SkillFilesListResponse + 105, // 68: liveagent.gateway.v2.AgentEnvelope.skill_metadata_read_resp:type_name -> liveagent.gateway.v2.SkillMetadataReadResponse + 107, // 69: liveagent.gateway.v2.AgentEnvelope.skill_text_read_resp:type_name -> liveagent.gateway.v2.SkillTextReadResponse + 112, // 70: liveagent.gateway.v2.AgentEnvelope.file_mention_list_resp:type_name -> liveagent.gateway.v2.FileMentionListResponse + 11, // 71: liveagent.gateway.v2.AgentEnvelope.upload_readable_files_resp:type_name -> liveagent.gateway.v2.UploadReadableFilesResponse + 115, // 72: liveagent.gateway.v2.AgentEnvelope.fs_roots_resp:type_name -> liveagent.gateway.v2.FsRootsResponse + 139, // 73: liveagent.gateway.v2.AgentEnvelope.pong:type_name -> liveagent.gateway.v2.PongResponse + 118, // 74: liveagent.gateway.v2.AgentEnvelope.fs_list_dirs_resp:type_name -> liveagent.gateway.v2.FsListDirsResponse + 13, // 75: liveagent.gateway.v2.AgentEnvelope.uploaded_image_preview_resp:type_name -> liveagent.gateway.v2.UploadedImagePreviewResponse + 32, // 76: liveagent.gateway.v2.AgentEnvelope.memory_manage_resp:type_name -> liveagent.gateway.v2.MemoryManageResponse + 109, // 77: liveagent.gateway.v2.AgentEnvelope.skill_manage_resp:type_name -> liveagent.gateway.v2.SkillManageResponse + 120, // 78: liveagent.gateway.v2.AgentEnvelope.fs_create_project_folder_resp:type_name -> liveagent.gateway.v2.FsCreateProjectFolderResponse + 48, // 79: liveagent.gateway.v2.AgentEnvelope.terminal_response:type_name -> liveagent.gateway.v2.TerminalResponse + 49, // 80: liveagent.gateway.v2.AgentEnvelope.terminal_event:type_name -> liveagent.gateway.v2.TerminalEvent + 123, // 81: liveagent.gateway.v2.AgentEnvelope.fs_list_resp:type_name -> liveagent.gateway.v2.FsListResponse + 131, // 82: liveagent.gateway.v2.AgentEnvelope.fs_write_text_resp:type_name -> liveagent.gateway.v2.FsWriteTextResponse + 133, // 83: liveagent.gateway.v2.AgentEnvelope.fs_create_dir_resp:type_name -> liveagent.gateway.v2.FsCreateDirResponse + 135, // 84: liveagent.gateway.v2.AgentEnvelope.fs_rename_resp:type_name -> liveagent.gateway.v2.FsRenameResponse + 137, // 85: liveagent.gateway.v2.AgentEnvelope.fs_delete_resp:type_name -> liveagent.gateway.v2.FsDeleteResponse + 52, // 86: liveagent.gateway.v2.AgentEnvelope.git_response:type_name -> liveagent.gateway.v2.GitResponse + 125, // 87: liveagent.gateway.v2.AgentEnvelope.fs_read_editable_text_resp:type_name -> liveagent.gateway.v2.FsReadEditableTextResponse + 127, // 88: liveagent.gateway.v2.AgentEnvelope.fs_read_workspace_image_resp:type_name -> liveagent.gateway.v2.FsReadWorkspaceImageResponse + 39, // 89: liveagent.gateway.v2.AgentEnvelope.sftp_response:type_name -> liveagent.gateway.v2.SftpResponse + 40, // 90: liveagent.gateway.v2.AgentEnvelope.sftp_event:type_name -> liveagent.gateway.v2.SftpEvent + 58, // 91: liveagent.gateway.v2.AgentEnvelope.chat_queue_resp:type_name -> liveagent.gateway.v2.ChatQueueResponse + 59, // 92: liveagent.gateway.v2.AgentEnvelope.chat_queue_event:type_name -> liveagent.gateway.v2.ChatQueueEvent + 61, // 93: liveagent.gateway.v2.AgentEnvelope.chat_control:type_name -> liveagent.gateway.v2.ChatControlEvent + 63, // 94: liveagent.gateway.v2.AgentEnvelope.runtime_status:type_name -> liveagent.gateway.v2.RuntimeStatusEvent + 100, // 95: liveagent.gateway.v2.AgentEnvelope.settings_reset_ssh_known_host_resp:type_name -> liveagent.gateway.v2.SettingsResetSshKnownHostResponse + 62, // 96: liveagent.gateway.v2.AgentEnvelope.chat_runtime_snapshot:type_name -> liveagent.gateway.v2.ChatRuntimeSnapshot + 142, // 97: liveagent.gateway.v2.AgentEnvelope.provider_models_resp:type_name -> liveagent.gateway.v2.ProviderModelsResponse + 15, // 98: liveagent.gateway.v2.AgentEnvelope.tunnel_desired:type_name -> liveagent.gateway.v2.TunnelDesiredState + 20, // 99: liveagent.gateway.v2.AgentEnvelope.tunnel_mutation_result:type_name -> liveagent.gateway.v2.TunnelMutationResult + 24, // 100: liveagent.gateway.v2.AgentEnvelope.tunnel_frame:type_name -> liveagent.gateway.v2.TunnelFrame + 22, // 101: liveagent.gateway.v2.AgentEnvelope.tunnel_probe_report:type_name -> liveagent.gateway.v2.TunnelProbeReport + 26, // 102: liveagent.gateway.v2.AgentEnvelope.workspace_activity:type_name -> liveagent.gateway.v2.WorkspaceActivityEvent + 30, // 103: liveagent.gateway.v2.AgentEnvelope.managed_process_response:type_name -> liveagent.gateway.v2.ManagedProcessResponse + 28, // 104: liveagent.gateway.v2.AgentEnvelope.managed_process_snapshot:type_name -> liveagent.gateway.v2.ManagedProcessSnapshot + 77, // 105: liveagent.gateway.v2.AgentEnvelope.history_branch_resp:type_name -> liveagent.gateway.v2.HistoryBranchResponse + 144, // 106: liveagent.gateway.v2.AgentEnvelope.provider_usage_resp:type_name -> liveagent.gateway.v2.ProviderUsageResponse + 145, // 107: liveagent.gateway.v2.AgentEnvelope.chat_ingress_batch:type_name -> liveagent.gateway.v2.ChatIngressBatch + 151, // 108: liveagent.gateway.v2.AgentEnvelope.chat_ingress_resume:type_name -> liveagent.gateway.v2.ChatIngressResume + 153, // 109: liveagent.gateway.v2.AgentEnvelope.chat_ingress_fragment:type_name -> liveagent.gateway.v2.ChatIngressFragment + 129, // 110: liveagent.gateway.v2.AgentEnvelope.chat_file_open_resp:type_name -> liveagent.gateway.v2.ChatFileOpenResponse + 140, // 111: liveagent.gateway.v2.AgentEnvelope.error:type_name -> liveagent.gateway.v2.ErrorResponse + 156, // 112: liveagent.gateway.v2.AgentEnvelope.history_set_cwd_resp:type_name -> liveagent.gateway.v2.HistorySetCwdResponse + 9, // 113: liveagent.gateway.v2.UploadReadableFilesRequest.files:type_name -> liveagent.gateway.v2.UploadReadableFile + 8, // 114: liveagent.gateway.v2.UploadReadableFilesResponse.files:type_name -> liveagent.gateway.v2.ChatUploadedFile + 14, // 115: liveagent.gateway.v2.TunnelDesiredState.tunnels:type_name -> liveagent.gateway.v2.TunnelSpec + 16, // 116: liveagent.gateway.v2.TunnelStatus.local:type_name -> liveagent.gateway.v2.TunnelHealth + 17, // 117: liveagent.gateway.v2.TunnelStateSnapshot.tunnels:type_name -> liveagent.gateway.v2.TunnelStatus + 16, // 118: liveagent.gateway.v2.TunnelStateSnapshot.relay:type_name -> liveagent.gateway.v2.TunnelHealth + 16, // 119: liveagent.gateway.v2.TunnelProbeResult.local:type_name -> liveagent.gateway.v2.TunnelHealth + 21, // 120: liveagent.gateway.v2.TunnelProbeReport.results:type_name -> liveagent.gateway.v2.TunnelProbeResult + 0, // 121: liveagent.gateway.v2.TunnelFrame.kind:type_name -> liveagent.gateway.v2.TunnelFrameKind + 23, // 122: liveagent.gateway.v2.TunnelFrame.headers:type_name -> liveagent.gateway.v2.TunnelHeader + 1, // 123: liveagent.gateway.v2.TunnelFrame.ws_message_type:type_name -> liveagent.gateway.v2.TunnelWsMessageType + 27, // 124: liveagent.gateway.v2.ManagedProcessSnapshot.processes:type_name -> liveagent.gateway.v2.ManagedProcessRecord + 28, // 125: liveagent.gateway.v2.ManagedProcessResponse.snapshot:type_name -> liveagent.gateway.v2.ManagedProcessSnapshot + 35, // 126: liveagent.gateway.v2.TerminalSession.ssh:type_name -> liveagent.gateway.v2.TerminalSshMetadata + 37, // 127: liveagent.gateway.v2.SftpResponse.entries:type_name -> liveagent.gateway.v2.SftpEntry + 37, // 128: liveagent.gateway.v2.SftpResponse.entry:type_name -> liveagent.gateway.v2.SftpEntry + 38, // 129: liveagent.gateway.v2.SftpResponse.transfer:type_name -> liveagent.gateway.v2.SftpTransfer + 38, // 130: liveagent.gateway.v2.SftpEvent.transfer:type_name -> liveagent.gateway.v2.SftpTransfer + 43, // 131: liveagent.gateway.v2.TerminalSshTabsSnapshot.tabs:type_name -> liveagent.gateway.v2.TerminalSshTab + 45, // 132: liveagent.gateway.v2.TerminalSshLocalForwardsSnapshot.forwards:type_name -> liveagent.gateway.v2.TerminalSshLocalForward + 45, // 133: liveagent.gateway.v2.TerminalSshLocalForwardAction.forward:type_name -> liveagent.gateway.v2.TerminalSshLocalForward + 34, // 134: liveagent.gateway.v2.TerminalResponse.sessions:type_name -> liveagent.gateway.v2.TerminalSession + 34, // 135: liveagent.gateway.v2.TerminalResponse.session:type_name -> liveagent.gateway.v2.TerminalSession + 42, // 136: liveagent.gateway.v2.TerminalResponse.shell_options:type_name -> liveagent.gateway.v2.TerminalShellOption + 41, // 137: liveagent.gateway.v2.TerminalResponse.ssh_prompt:type_name -> liveagent.gateway.v2.TerminalSshPrompt + 44, // 138: liveagent.gateway.v2.TerminalResponse.ssh_tabs:type_name -> liveagent.gateway.v2.TerminalSshTabsSnapshot + 46, // 139: liveagent.gateway.v2.TerminalResponse.ssh_local_forwards:type_name -> liveagent.gateway.v2.TerminalSshLocalForwardsSnapshot + 47, // 140: liveagent.gateway.v2.TerminalResponse.ssh_local_forward:type_name -> liveagent.gateway.v2.TerminalSshLocalForwardAction + 34, // 141: liveagent.gateway.v2.TerminalEvent.session:type_name -> liveagent.gateway.v2.TerminalSession + 44, // 142: liveagent.gateway.v2.TerminalEvent.ssh_tabs:type_name -> liveagent.gateway.v2.TerminalSshTabsSnapshot + 47, // 143: liveagent.gateway.v2.TerminalEvent.ssh_local_forward:type_name -> liveagent.gateway.v2.TerminalSshLocalForwardAction + 34, // 144: liveagent.gateway.v2.TerminalStreamFrame.session:type_name -> liveagent.gateway.v2.TerminalSession + 6, // 145: liveagent.gateway.v2.ChatRequest.selected_model:type_name -> liveagent.gateway.v2.ChatSelectedModel + 8, // 146: liveagent.gateway.v2.ChatRequest.uploaded_files:type_name -> liveagent.gateway.v2.ChatUploadedFile + 7, // 147: liveagent.gateway.v2.ChatRequest.runtime_controls:type_name -> liveagent.gateway.v2.ChatRuntimeControls + 53, // 148: liveagent.gateway.v2.ChatCommandRequest.request:type_name -> liveagent.gateway.v2.ChatRequest + 54, // 149: liveagent.gateway.v2.ChatCommandRequest.base_message_ref:type_name -> liveagent.gateway.v2.ChatMessageRef + 55, // 150: liveagent.gateway.v2.ChatCommandRequest.cancel:type_name -> liveagent.gateway.v2.CancelChatRequest + 2, // 151: liveagent.gateway.v2.ChatEvent.type:type_name -> liveagent.gateway.v2.ChatEvent.ChatEventType + 64, // 152: liveagent.gateway.v2.RuntimeStatusEvent.active_runs:type_name -> liveagent.gateway.v2.ChatRunReport + 64, // 153: liveagent.gateway.v2.RuntimeStatusEvent.finished_runs:type_name -> liveagent.gateway.v2.ChatRunReport + 69, // 154: liveagent.gateway.v2.HistoryListResponse.conversations:type_name -> liveagent.gateway.v2.ConversationSummary + 69, // 155: liveagent.gateway.v2.HistoryGetResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 54, // 156: liveagent.gateway.v2.HistoryPrefixRequest.base_message_ref:type_name -> liveagent.gateway.v2.ChatMessageRef + 69, // 157: liveagent.gateway.v2.HistoryPrefixResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 69, // 158: liveagent.gateway.v2.HistoryRenameResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 54, // 159: liveagent.gateway.v2.HistoryBranchRequest.base_message_ref:type_name -> liveagent.gateway.v2.ChatMessageRef + 69, // 160: liveagent.gateway.v2.HistoryBranchResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 69, // 161: liveagent.gateway.v2.HistoryPinResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 80, // 162: liveagent.gateway.v2.HistoryShareGetResponse.share:type_name -> liveagent.gateway.v2.HistoryShareStatus + 80, // 163: liveagent.gateway.v2.HistoryShareSetResponse.share:type_name -> liveagent.gateway.v2.HistoryShareStatus + 69, // 164: liveagent.gateway.v2.HistoryShareResolveResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 88, // 165: liveagent.gateway.v2.HistoryWorkdirsResponse.workdirs:type_name -> liveagent.gateway.v2.HistoryWorkdirSummary + 69, // 166: liveagent.gateway.v2.HistorySyncEvent.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 111, // 167: liveagent.gateway.v2.FileMentionListResponse.entries:type_name -> liveagent.gateway.v2.FileMentionEntry + 113, // 168: liveagent.gateway.v2.FsRootsResponse.roots:type_name -> liveagent.gateway.v2.FsRoot + 117, // 169: liveagent.gateway.v2.FsListDirsResponse.entries:type_name -> liveagent.gateway.v2.FsDirEntry + 122, // 170: liveagent.gateway.v2.FsListResponse.entries:type_name -> liveagent.gateway.v2.FsListEntry + 146, // 171: liveagent.gateway.v2.ChatIngressBatch.records:type_name -> liveagent.gateway.v2.ChatIngressRecord + 147, // 172: liveagent.gateway.v2.ChatIngressRecord.delta:type_name -> liveagent.gateway.v2.ChatIngressDelta + 149, // 173: liveagent.gateway.v2.ChatIngressRecord.checkpoint:type_name -> liveagent.gateway.v2.ChatIngressCheckpoint + 150, // 174: liveagent.gateway.v2.ChatIngressRecord.terminal:type_name -> liveagent.gateway.v2.ChatIngressTerminal + 148, // 175: liveagent.gateway.v2.ChatIngressRecord.heartbeat:type_name -> liveagent.gateway.v2.ChatIngressHeartbeat + 152, // 176: liveagent.gateway.v2.ChatIngressResume.runs:type_name -> liveagent.gateway.v2.ChatIngressRunResume + 3, // 177: liveagent.gateway.v2.ChatIngressAck.action:type_name -> liveagent.gateway.v2.ChatIngressAck.Action + 69, // 178: liveagent.gateway.v2.HistorySetCwdResponse.conversation:type_name -> liveagent.gateway.v2.ConversationSummary + 179, // [179:179] is the sub-list for method output_type + 179, // [179:179] is the sub-list for method input_type + 179, // [179:179] is the sub-list for extension type_name + 179, // [179:179] is the sub-list for extension extendee + 0, // [0:179] is the sub-list for field type_name } func init() { file_proto_v2_gateway_proto_init() } @@ -14013,6 +14153,7 @@ func file_proto_v2_gateway_proto_init() { (*GatewayEnvelope_HistoryBranch)(nil), (*GatewayEnvelope_ProviderUsage)(nil), (*GatewayEnvelope_ChatFileOpen)(nil), + (*GatewayEnvelope_HistorySetCwd)(nil), } file_proto_v2_gateway_proto_msgTypes[1].OneofWrappers = []any{ (*AgentEnvelope_ChatEvent)(nil), @@ -14077,6 +14218,7 @@ func file_proto_v2_gateway_proto_init() { (*AgentEnvelope_ChatIngressFragment)(nil), (*AgentEnvelope_ChatFileOpenResp)(nil), (*AgentEnvelope_Error)(nil), + (*AgentEnvelope_HistorySetCwdResp)(nil), } file_proto_v2_gateway_proto_msgTypes[15].OneofWrappers = []any{} file_proto_v2_gateway_proto_msgTypes[23].OneofWrappers = []any{} @@ -14097,7 +14239,7 @@ func file_proto_v2_gateway_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_v2_gateway_proto_rawDesc), len(file_proto_v2_gateway_proto_rawDesc)), NumEnums: 4, - NumMessages: 151, + NumMessages: 153, NumExtensions: 0, NumServices: 0, }, diff --git a/crates/agent-gateway/internal/protocol/pbws/guard.go b/crates/agent-gateway/internal/protocol/pbws/guard.go index 26edd31a8..3b3ef86a6 100644 --- a/crates/agent-gateway/internal/protocol/pbws/guard.go +++ b/crates/agent-gateway/internal/protocol/pbws/guard.go @@ -34,6 +34,7 @@ func vetAgentRequest(sm session.AgentView, env *gatewayv2.GatewayEnvelope) error *gatewayv2.GatewayEnvelope_HistoryDelete, *gatewayv2.GatewayEnvelope_HistoryPrefix, *gatewayv2.GatewayEnvelope_HistoryPin, + *gatewayv2.GatewayEnvelope_HistorySetCwd, *gatewayv2.GatewayEnvelope_HistoryShareGet, *gatewayv2.GatewayEnvelope_HistoryShareSet, *gatewayv2.GatewayEnvelope_HistoryWorkdirs, diff --git a/crates/agent-gateway/proto/v2/gateway.proto b/crates/agent-gateway/proto/v2/gateway.proto index 5706cab87..65e8ce569 100644 --- a/crates/agent-gateway/proto/v2/gateway.proto +++ b/crates/agent-gateway/proto/v2/gateway.proto @@ -61,6 +61,7 @@ message GatewayEnvelope { HistoryBranchRequest history_branch = 92; ProviderUsageRequest provider_usage = 93; ChatFileOpenRequest chat_file_open = 94; + HistorySetCwdRequest history_set_cwd = 95; } // Legacy tunnel control/frame payloads (pre-rewrite protocol) and the @@ -135,6 +136,7 @@ message AgentEnvelope { ChatIngressFragment chat_ingress_fragment = 97; ChatFileOpenResponse chat_file_open_resp = 98; ErrorResponse error = 99; + HistorySetCwdResponse history_set_cwd_resp = 100; } // Legacy tunnel control/frame payloads (pre-rewrite protocol) and the @@ -1280,3 +1282,12 @@ message ChatIngressAck { REJECTED = 4; } } + +message HistorySetCwdRequest { + string conversation_id = 1; + string cwd = 2; +} + +message HistorySetCwdResponse { + ConversationSummary conversation = 1; +} diff --git a/crates/agent-gateway/test/webui/gateway-socket-client.test.mjs b/crates/agent-gateway/test/webui/gateway-socket-client.test.mjs index e37d00d75..7f297d663 100644 --- a/crates/agent-gateway/test/webui/gateway-socket-client.test.mjs +++ b/crates/agent-gateway/test/webui/gateway-socket-client.test.mjs @@ -1043,6 +1043,44 @@ test("GatewayWebSocketClient sends history branch requests with the base message resetGatewayWebSocketClient(); }); +test("GatewayWebSocketClient sends history cwd update requests", async () => { + installBrowser(); + const { codec, getGatewayWebSocketClient, resetGatewayWebSocketClient } = loadGatewaySocket(); + resetGatewayWebSocketClient(); + + const client = getGatewayWebSocketClient("token"); + const updatePromise = client.setHistoryCwd("conversation-1", "/tmp/project-b"); + const socket = await connectAndAuth(codec); + await waitFor(() => findAgentRequest(codec, socket, "history_set_cwd"), "history cwd frame"); + const request = findAgentRequest(codec, socket, "history_set_cwd"); + assert.deepEqual(request.json.agent_request.history_set_cwd, { + conversation_id: "conversation-1", + cwd: "/tmp/project-b", + }); + socket.receiveBinary( + codec.encodeServerFrame({ + request_id: request.requestId, + agent_response: { + history_set_cwd_resp: { + conversation: { + id: "conversation-1", + title: "Moved conversation", + cwd: "/tmp/project-b", + message_count: 6, + created_at: 1700000000100, + updated_at: 1700000000200, + }, + }, + }, + }), + ); + const updated = await updatePromise; + assert.equal(updated.id, "conversation-1"); + assert.equal(updated.cwd, "/tmp/project-b"); + + resetGatewayWebSocketClient(); +}); + test("GatewayWebSocketClient reconnects before read requests when an authenticated socket goes stale", async () => { installBrowser(); const { codec, getGatewayWebSocketClient, resetGatewayWebSocketClient } = loadGatewaySocket(); diff --git a/crates/agent-gateway/web/src/app/sidebar/GatewaySidebarContainer.tsx b/crates/agent-gateway/web/src/app/sidebar/GatewaySidebarContainer.tsx index 938a1062c..cf8bb65db 100644 --- a/crates/agent-gateway/web/src/app/sidebar/GatewaySidebarContainer.tsx +++ b/crates/agent-gateway/web/src/app/sidebar/GatewaySidebarContainer.tsx @@ -214,6 +214,27 @@ export function GatewaySidebarContainer(props: GatewaySidebarContainerProps) { void store.setPinned(id, isPinned); }); + const handleMoveToWorkspace = useStableCallback((id: string, cwd: string) => { + if (sectionsDisabled) { + return; + } + clearMutationErrors(); + void store.setCwd(id, cwd); + }); + + const handleMoveConversationsToWorkspace = useStableCallback( + async (ids: readonly string[], cwd: string) => { + if (sectionsDisabled) { + return ids; + } + clearMutationErrors(); + const results = await Promise.all( + ids.map(async (id) => ({ id, moved: await store.setCwd(id, cwd) })), + ); + return results.filter((result) => !result.moved).map((result) => result.id); + }, + ); + const handleDeleteConversation = useStableCallback((id: string) => { if (sectionsDisabled) { return; @@ -369,6 +390,8 @@ export function GatewaySidebarContainer(props: GatewaySidebarContainerProps) { onCommitRename={handleCommitRename} onCancelRename={handleCancelRename} onSetPinned={handleSetPinned} + onMoveToWorkspace={handleMoveToWorkspace} + onMoveConversationsToWorkspace={handleMoveConversationsToWorkspace} canShareConversations={props.canShareConversations} sharedConversationCount={props.sharedConversationCount} onShareConversation={props.onShareConversation} diff --git a/crates/agent-gateway/web/src/components/chat/ChatHistorySidebar.tsx b/crates/agent-gateway/web/src/components/chat/ChatHistorySidebar.tsx index d0d33f76b..3c31cfa70 100644 --- a/crates/agent-gateway/web/src/components/chat/ChatHistorySidebar.tsx +++ b/crates/agent-gateway/web/src/components/chat/ChatHistorySidebar.tsx @@ -35,6 +35,7 @@ import { ChevronRight, CirclePlus, Edit3, + Folder, FolderClosed, FolderOpen, FolderTree, @@ -56,12 +57,15 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, DropdownMenuTrigger, } from "../ui/dropdown-menu"; import { Input } from "../ui/input"; export type ChatHistorySidebarListStatus = "initial" | "loading" | "syncing" | "ready"; -export type ChatHistorySidebarMutationKind = "rename" | "pin" | "delete"; +export type ChatHistorySidebarMutationKind = "rename" | "pin" | "move" | "delete"; type ChatHistorySidebarProps = { items: readonly ChatHistorySummary[]; @@ -124,6 +128,11 @@ type ChatHistorySidebarProps = { onCommitRename: () => void; onCancelRename: () => void; onSetPinned: (id: string, isPinned: boolean) => void; + onMoveToWorkspace: (id: string, cwd: string) => void; + onMoveConversationsToWorkspace: ( + ids: readonly string[], + cwd: string, + ) => Promise; canShareConversations: boolean; sharedConversationCount: number; onShareConversation: (item: ChatHistorySummary) => void; @@ -213,6 +222,8 @@ type HistoryRowProps = { onCommitRename: () => void; onCancelRename: () => void; onSetPinned: (id: string, isPinned: boolean) => void; + onMoveToWorkspace: (id: string, cwd: string) => void; + moveWorkspaces: readonly WorkspaceProject[]; onShareConversation: (item: ChatHistorySummary) => void; onDeleteConversation: (id: string) => void; onSetPendingDelete: (id: string | null) => void; @@ -227,6 +238,7 @@ function areRenderedHistoryItemsEqual(previous: ChatHistorySummary, next: ChatHi return ( previous.id === next.id && previous.title === next.title && + previous.cwd === next.cwd && previous.isPinned === next.isPinned && previous.isShared === next.isShared && previous.isPending === next.isPending @@ -257,6 +269,8 @@ function areHistoryRowPropsEqual(previous: HistoryRowProps, next: HistoryRowProp previous.onCommitRename === next.onCommitRename && previous.onCancelRename === next.onCancelRename && previous.onSetPinned === next.onSetPinned && + previous.onMoveToWorkspace === next.onMoveToWorkspace && + previous.moveWorkspaces === next.moveWorkspaces && previous.onShareConversation === next.onShareConversation && previous.onDeleteConversation === next.onDeleteConversation && previous.onSetPendingDelete === next.onSetPendingDelete && @@ -288,6 +302,8 @@ const HistoryRow = memo(function HistoryRow(props: HistoryRowProps) { onCommitRename, onCancelRename, onSetPinned, + onMoveToWorkspace, + moveWorkspaces, onShareConversation, onDeleteConversation, onSetPendingDelete, @@ -364,6 +380,15 @@ const HistoryRow = memo(function HistoryRow(props: HistoryRowProps) { onSetPinned(item.id, item.isPinned !== true); }, [isInteractionDisabled, item.id, item.isPinned, onSetPinned]); + const handleMoveToWorkspace = useCallback( + (cwd: string) => { + if (!isInteractionDisabled) { + onMoveToWorkspace(item.id, cwd); + } + }, + [isInteractionDisabled, item.id, onMoveToWorkspace], + ); + const handleShare = useCallback(() => { if (isInteractionDisabled) { return; @@ -833,6 +858,30 @@ const HistoryRow = memo(function HistoryRow(props: HistoryRowProps) { {t("chat.conversationRename")} + + + + {t("chat.conversationMoveToWorkspace")} + + + {moveWorkspaces.map((workspace) => ( + handleMoveToWorkspace(workspace.path)} + className="gap-2" + > + + {workspace.path} + + ))} + + {canShareConversation && !item.isPending ? ( new Set(), ); const [isBulkDeleting, setIsBulkDeleting] = useState(false); + const [isBulkMoving, setIsBulkMoving] = useState(false); + const [bulkMoveMenuOpen, setBulkMoveMenuOpen] = useState(false); const [pendingProjectRemoveId, setPendingProjectRemoveId] = useState(null); const [showAllProjects, setShowAllProjects] = useState(false); const [openMenuId, setOpenMenuId] = useState(null); @@ -1440,6 +1493,7 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi // Bumped to invalidate an in-flight bulk delete: its shouldStop callback // starts returning true and its continuation stops touching state. const bulkDeleteRunRef = useRef(0); + const bulkMoveRunRef = useRef(0); const { confirm: requestBulkDeleteConfirm, dialog: bulkDeleteDialog } = useConfirmDialog(); const orderedConversationIds = useMemo(() => items.map((item) => item.id), [items]); const selectableConversationIds = useMemo( @@ -1482,6 +1536,19 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi onSetPinned(id, isPinned); } }); + const handleMoveToWorkspace = useStableEvent((id: string, cwd: string) => { + if (!sectionsDisabled) { + onMoveToWorkspace(id, cwd); + } + }); + const handleMoveConversationsToWorkspace = useStableEvent( + (ids: readonly string[], cwd: string) => { + if (sectionsDisabled) { + return Promise.resolve(ids); + } + return onMoveConversationsToWorkspace(ids, cwd); + }, + ); const handleShareConversation = useStableEvent((item: ChatHistorySummary) => { if (!sectionsDisabled) { onShareConversation(item); @@ -1594,7 +1661,10 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi }); const exitSelectionMode = useCallback(() => { bulkDeleteRunRef.current += 1; + bulkMoveRunRef.current += 1; setIsBulkDeleting(false); + setIsBulkMoving(false); + setBulkMoveMenuOpen(false); setSelectionMode(false); setSelectedConversationIds(new Set()); selectionAnchorRef.current = null; @@ -1692,6 +1762,35 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi } } }); + const handleBulkMove = useStableEvent(async (cwd: string) => { + const ids = orderedConversationIds.filter( + (id) => selectedConversationIds.has(id) && selectableConversationIds.has(id), + ); + if (ids.length === 0 || isBulkMoving || sectionsDisabled) { + return; + } + + const runId = bulkMoveRunRef.current + 1; + bulkMoveRunRef.current = runId; + setIsBulkMoving(true); + try { + const failedIds = await handleMoveConversationsToWorkspace(ids, cwd); + if (bulkMoveRunRef.current !== runId) { + return; + } + const orderedConversationIdSet = new Set(orderedConversationIds); + const remainingFailedIds = failedIds.filter((id) => orderedConversationIdSet.has(id)); + setSelectedConversationIds(new Set(remainingFailedIds)); + selectionAnchorRef.current = remainingFailedIds[0] ?? null; + if (remainingFailedIds.length === 0) { + setSelectionMode(false); + } + } finally { + if (bulkMoveRunRef.current === runId) { + setIsBulkMoving(false); + } + } + }); // Archived rows are split into their own collapsed group at the list end; // the render cap only applies to the active rows. const activeProjects = useMemo( @@ -2152,7 +2251,9 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi isPendingDelete={pendingDeleteId === item.id} isSelectionMode={selectionMode} isSelected={selectedConversationIds.has(item.id)} - isSelectionDisabled={isBulkDeleting || !selectableConversationIds.has(item.id)} + isSelectionDisabled={ + isBulkDeleting || isBulkMoving || !selectableConversationIds.has(item.id) + } isInteractionDisabled={sectionsDisabled} isMobileMenuLayout={isMobileMenuLayout} renameDraft={renamingId === item.id ? renameDraft : ""} @@ -2162,6 +2263,8 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi onCommitRename={handleCommitRename} onCancelRename={handleCancelRename} onSetPinned={handleSetPinned} + onMoveToWorkspace={handleMoveToWorkspace} + moveWorkspaces={activeProjects} onShareConversation={handleShareConversation} onDeleteConversation={handleDeleteConversation} onSetPendingDelete={handleSetPendingDelete} @@ -2181,6 +2284,7 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi handleMenuOpenChange, handleRenameDraftChange, handleSelectConversation, + handleMoveToWorkspace, handleSetPinned, handleSetPendingDelete, handleShareConversation, @@ -2189,9 +2293,11 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi canShareConversations, enterSelectionMode, isBulkDeleting, + isBulkMoving, isMobileMenuLayout, menuSide, openMenuId, + activeProjects, pendingDeleteId, renameDraft, renamingId, @@ -2535,13 +2641,65 @@ export const ChatHistorySidebar = memo(function ChatHistorySidebar(props: ChatHi
{selectionMode ? ( <> + { + if (!sectionsDisabled || !open) { + setBulkMoveMenuOpen(open); + } + }} + > + + {isBulkMoving ? ( + + ) : ( + + )} + + + {activeProjects.map((workspace) => ( + void handleBulkMove(workspace.path)} + className="gap-2" + > + + {workspace.path} + + ))} + +