Pass additional parameter to API Resource

Laravel Version: 5.5
PHP Version: 5.7
Database Driver & Version:

Description:
What if my api resource class need additional parameters besides the resource itself, from outside like caller controller class? How could I pass parameter to the api resource class(both single resource and resource collection), should I declare a new Json Resource class to extends?
Any comments or solutions are welcome, Thank you in advance!

Hi there,
Welcome to Laravel and we are glad to have you as part of the community.
Unfortunately this GitHub area is not a support area for general application issues. This is only for issues/bugs with the framework code itself.
Can I suggest closing your issue ticket here? Instead try asking your question on one of the many great community support areas that will likely give you a better answer more quickly:

Laravel Slack (https://larachat.co/)
Laravel.io Forum (https://laravel.io/forum)
Laracasts Forum (https://laracasts.com/discuss)
StackOverflow (http://stackoverflow.com/questions/tagged/laravel)

Thanks in advance.

@yanhao-li This is very much possible - you just have to overload the constructor of the Resource you want to pass extra params to e.g.

class PostResource extends Resource
{
    /**
     * @var
     */
    private $foo;

    /**
     * Create a new resource instance.
     *
     * @param  mixed  $resource
     * @return void
     */
    public function __construct($resource, $foo)
    {
        // Ensure you call the parent constructor
        parent::__construct($resource);
        $this->resource = $resource;

        $this->foo = $foo;
    }

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'title' => $this->title,
            'foo' => $this->foo
        ];
    }
}

Then you can add the params to your resource like so:
return new PostResource($post, 'my variable');

Hope that helps

@fourstacks Informative, thank you very much sir

@yanhao-li i have some issue.

This is my approach.
class UserResource extends Resource{

    protected $foo;

    public function foo($value){
        $this->foo = $value;
        return $this;
    }

    public function toArray($request){
        return [
            'id' => $this->id,
            'name' => $this->name,
            'foo' => $this->foo,
         ];
    }

    public static function collection($resource){
        return new UserResourceCollection($resource);
    }
}

class UserResourceCollection extends ResourceCollection{

    protected $foo;

    public function foo($value){
        $this->foo = $value;
        return $this;
    }

    public function toArray($request){
        return $this->collection->map(function(UserResource $resource) use($request){
            return $resource->foo($this->foo)->toArray($request);
        })->all();

        // or use HigherOrderCollectionProxy
        // return $this->collection->map->foo($this->foo)->map->toArray($request)->all()
    }
}

(new UserResource($user))->foo('bar');
(new UserResourceCollection($user))->foo('bar');

UserResource::make($user)->foo('bar');
UserResource::collection($users)->foo('bar');

Any good idea?

@yanhao-li Did you ever figure this out?

Why not override the constructor in the ResourceCollection class instead of the Resource class and use Resource Collections instead (https://laravel.com/docs/5.6/eloquent-resources#generating-resources)?
For example, you could create a new ResourceCollection class
php artisan make:resource NoteCollection

The above command will create a NoteCollection for you to use in the /resources folder.  Inside this class, just override the constructor with parameters you want to pass in:
class NoteCollection extends ResourceCollection
{
    protected $user;
    /**
     * Create a new resource instance.
     *
     * @param  mixed  $resource
     * @return void
     */
    public function __construct($resource, User $user = null)
    {
        $this->user = $user;

        parent::__construct($resource);
    }
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection->map(function($n){
                return [
                    'note' => $n->note,
                    'public' => $this->when($this->user->isAwesome(),'secret'),
                    'created_at' => $n->created_at->timestamp,
                    'updated_at' => $n->updated_at->timestamp
                ];
            })
        ];
    }
}

Why not override the constructor in the ResourceCollection class instead of the Resource class and use Resource Collections instead (https://laravel.com/docs/5.6/eloquent-resources#generating-resources)?
For example, you could create a new ResourceCollection class
php artisan make:resource NoteCollection

The above command will create a NoteCollection for you to use in the /resources folder. Inside this class, just override the constructor with parameters you want to pass in:
class NoteCollection extends ResourceCollection
{
    protected $user;
    /**
     * Create a new resource instance.
     *
     * @param  mixed  $resource
     * @return void
     */
    public function __construct($resource, User $user = null)
    {
        $this->user = $user;

        parent::__construct($resource);
    }
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection->map(function($n){
                return [
                    'note' => $n->note,
                    'public' => $this->when($this->user->isAwesome(),'secret'),
                    'created_at' => $n->created_at->timestamp,
                    'updated_at' => $n->updated_at->timestamp
                ];
            })
        ];
    }
}

I tried this with typehinting to inject a service and it doesn't work. Error is it expects two arguments and only 1 given. How to inject a service into a Resource collection?

@yanhao-li Did you ever figure this out?
@lokielse I see this works, but is repeating code, is there any better way anyone? Ideally passing from the constructor like @fourstacks solution but for a collection. Any better way to solve this?

did you solve this somehow?

@Almusamim Nope, just went with @lokielse solution as it worked and it was taking too long to figure out another way.

I created a pull request that adds a function to pass extra data to an API resource: https://github.com/laravel/framework/pull/28358

I am using another solution. Its definitely not the best one but since taylor already declined your pull request i would like to give my answer to this problem.
I extended the JsonResource and added a static variable named using:
<?php

namespace App\Responses;

use Illuminate\Http\Resources\Json\JsonResource as BaseResource;

class JsonResource extends BaseResource
{
    protected static $using = [];

    public static function using($using = [])
    {
        static::$using = $using;
    }
}

Now if you use this JsonResource in your Resource you may set this variable by calling:
MyResource::using(['my_extra_data' => 123]);
MyResource::collection($resources);

and in your Resource:
$this->merge(static::$using)

Hi @alkin ,
your solution is good but it can only be applied with 1 fixed variable, if each resource returned in Resource::collection needs a variable containing different values, your method cannot be used.
Can you fix it?

This is my approach.
class UserResource extends Resource{

    protected $foo;

    public function foo($value){
        $this->foo = $value;
        return $this;
    }

    public function toArray($request){
        return [
            'id' => $this->id,
            'name' => $this->name,
            'foo' => $this->foo,
         ];
    }

    public static function collection($resource){
        return new UserResourceCollection($resource);
    }
}

class UserResourceCollection extends ResourceCollection{

    protected $foo;

    public function foo($value){
        $this->foo = $value;
        return $this;
    }

    public function toArray($request){
        return $this->collection->map(function(UserResource $resource) use($request){
            return $resource->foo($this->foo)->toArray($request);
        })->all();

        // or use HigherOrderCollectionProxy
        // return $this->collection->each->foo($this->foo)->map->toArray($request)->all()

        // or simple
        // $this->collection->each->foo($this->foo);
        // return parent::toArray($request);
    }
}

(new UserResource($user))->foo('bar');
(new UserResourceCollection($user))->foo('bar');

UserResource::make($user)->foo('bar');
UserResourceCollection::make($users)->foo('bar');
UserResource::collection($users)->foo('bar');

Any good idea?

thanks, your solution works with me

You can use this method.
`<?php
namespace App\Http\Resources;
use App\Http\Resources\Child as ChildResource;
use App\Http\Resources\Event as EventResource;
use Illuminate\Http\Resources\Json\JsonResource;
class School extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param  \Illuminate\Http\Request  $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'events' => $this->when(request()->get('events'), function () {
return EventResource::collection($this->events);
}),
'children' => $this->when(request()->get('children'), function () {
return ChildResource::collection($this->children);
}),
];
}
}
`

what about "hacking" the request:
$request->request->add(['foo' => 'foovalue']);

@BenoitDesrosiers - thanks for sharing that.  It's not the ideal solution but it is a necessary requirement for the framework.
In my case I am passing an array of fields into the resource that is used to dynamically format the array.  I call this resource from many different models to build arrays for datatables and want to control the scope of array flowing back to the browser.
I tried to pass this array (of fields I want to display) to the Eloquent select however I have Accessors in some models and these alias fields can't be used in the Eloquent select, so trimming at the toArray stage was vital.

@yanhao-li This is very much possible - you just have to overload the constructor of the Resource you want to pass extra params to e.g.

class PostResource extends Resource
{
    /**
     * @var
     */
    private $foo;

    /**
     * Create a new resource instance.
     *
     * @param  mixed  $resource
     * @return void
     */
    public function __construct($resource, $foo)
    {
        // Ensure you call the parent constructor
        parent::__construct($resource);
        $this->resource = $resource;

        $this->foo = $foo;
    }

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'title' => $this->title,
            'foo' => $this->foo
        ];
    }
}

Then you can add the params to your resource like so:
return new PostResource($post, 'my variable');

Hope that helps

Thanks, I think this is the best solution and probably the reason no special method for "importing parameters" was introduced. Anyway, for those who want to optimize their code in PHP 8, the following would work as well:
/**
* Create a new resource instance.
*
* @param  mixed  $resource
* @param  mixed  $foo
* @return void
*/
public function __construct(public $resource, protected $foo)
{
     parent::__construct($resource);
}

return new PostResource($post')->with('username' , 'sushansht');

what about "hacking" the request: $request->request->add(['foo' => 'foovalue']);

I do the "hacking" request, thanks @BenoitDesrosiers
It's my approach
Controller :
        //...
        request()->request->add([
            'extra_data' => [
                'foo' => 'foo-value',
                'other' => 'something',
            ],
        ]);
        // ...

Resource :
        // ...
        'bar' => $this->when(array_key_exists('foo', request()->get('extra_data') ?? []), function () {
            $foo = request()->get('extra_data')['foo'];

            // do some logic or just return the value
            return $foo;

            // or return using a resource if the $foo is an instance of a model
            return $foo
                ? (new FooResource($foo))
                : null;
        }),
        // ...

The bar will be shown if the foo key exists in the extra_data array from request, even if the value of foo is null, the bar still showed as I expected. It can be used in a single resource or resource collection.

It can be much simpler, you add a public set method in the resource and don't pass it in the constructor.
class PostResource extends Resource
{
    private Type|null $foo;

    public function setFoo(?Type $foo): self
    {
        $this->foo = $foo;
        return $this;
    }

    public function toArray()
    {
       return [
         'title' => $this->title,
        'foo'  => $foo // do any manipulations on foo here
       ];
    }
}

When you want to return the resource
return new PostResource($post)->setFoo('I love Laravel');

This approach doesn't involve a constructor and hence works with PostResourceCollection too.

It can be much simpler, you add a public set method in the resource and don't pass it in the constructor.
class PostResource extends Resource
{
    private ?Type $foo;

    public function setFoo(?Type $foo): self
    {
        $this->foo = $foo;
        return $this;
    }

    public function toArray()
    {
       return [
         'title' => $this->title,
         'foo'  => $this->foo // do any manipulations on foo here
       ];
    }
}

When you want to return the resource
return (new PostResource($post))->setFoo('I love Laravel');

This approach (although a bit unconventional) doesn't involve a constructor and hence works with PostResourceCollection too.

Personally I wouldn't agree on the elegance of this method. Especially since it breaks whenever you're building a resource collection and it makes use of the given resource as its collects parameter.
Currently I have solves this problem by adding the following method to my resource collection class:
    /**
     * Create a new resource instance.
     *
     * @param  mixed  $resource
     * @param  ?Type  $foo
     * @return void
     */
    public function __construct($resource, protected Type $foo)
    {
        parent::__construct($resource);
    }

     /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return $this->collection
            ->transform(fn ($item) => $item::make($item->resource, $this->foo))
            ->toArray();
    }

And the following to my resource class:

     /**
     * Create a new resource instance.
     *
     * @param  mixed  $resource
     * @param  ?Type  $foo
     * @return void
     */
    public function __construct($resource, protected Type $foo)
    {
        parent::__construct($resource);
    }
``

@marknuyens I guess it depends on the use case.
In my case, the passed $foo is only relevant when we think about the PostResource individually.
My exact use-case: This resource(here PostResource) is nested under a parent resource and the parent resource is passing the $foo to the child resource. Hence the $foo isn't relevant in the context of a resource collection in this case.
Also, it doesn't break the resource collection because the resource collection is very specific to the resource.
class PostCollection extends ResourceCollection
{
    /**
     * The resource that this resource collects.
     *
     * @var string
     */
    public $collects = PostResource::class;

    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return ['data' => $this->collection];
    }
}

This is in context to Laravel 8.x.

@Sudheer121 But what happens when that PostCollection is instantiated, it will not be aware of $foo, right? How would the setFoo() method be used in that case? That's the thing I considered to be challenging when I first faced this scenario.

@marknuyens handling of ResourceCollection would be like this
We just need to modify the toArray() method and add optional parameter in the constructor
class PostResourceCollection extends ResourceCollection
{

    public function __construct($resource, private ?FooType $foo = null)
    {
        parent::__construct($resource);
    }

    /**
     * The resource that this resource collects.
     *
     * @var string
     */
    public $collects = Post::class;

    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return ['data' => $this->collection->map(
         fn (PostResource $postResource) => $postResource->setFoo($this->foo)
        )];
    }
}

Usage
$collection = new PortResourceCollection($model)
// or
$collection = new PortResourceCollection($model, $foo)

In short, using this approach when defining the resource and this approach when defining the resourceCollection would do.
Note: This is in context to Laravel 8.x

i create this and work perfect for me
first create a custom JsonResource
AdditionalResource.php
`<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Resources\Json\JsonResource;
class AdditionalResource extends JsonResource
{
public static $extra_additional = [];
public function setAdditional($value)
{
    self::$extra_additional = $value;
    $this->additional($value);
    return $this;
}

public static function additionalCollection($resource, $data): AnonymousResourceCollection
{
    self::$extra_additional = $data;
    return parent::collection($resource);
}

}
`
an use in controller for one item or collection
YourResource::additionalCollection($items, ['extra_attributes' => 25])
YourResource::make($item)->setAdditional(['extra_attributes',25]);

My approach is a little close to what @sajadsoft1 done here.
I add a protected static $attribute to my resource class.
Then I override make() and collection() methods.
Something just like this (UserResource extracted from docs)
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
	protected static $short;

	public static function make(...$parameters)
	{
		$resource = $parameters["resource"] ?? $parameters[0];
		self::$short = $parameters["short"] ?? $parameters[1] ?? null;
		return parent::make($resource);
	}

	public static function collection(...$parameters)
	{
		$resource = $parameters["resource"] ?? $parameters[0];
		self::$short = $parameters["short"] ?? $parameters[1] ?? null;
		return parent::collection($resource);
	}

	public function toArray($request)
	{
		return [
			'id' => $this->id,
			'name' => $this->name,
			'email' => $this->email,
			$this->mergeWhen(!self::$short, [
				'created_at' => $this->created_at,
				'updated_at' => $this->updated_at,
			]),
		];
	}
}

TeamsAuthController.php
return new TeamsAuthResource([
    'user' => $user,
    'token' => $token,
]);

TeamsAuthResource.php
<?php

declare(strict_types=1);

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class TeamsAuthResource extends JsonResource
{
    /**
     * @param Request $request
     * @return array<string, mixed>
     */
    public function toArray($request): array
    {
        return [
            'success' => true,
            'user' => [
                'uuid' => $this->resource['user']->uuid,
                'display_name' => $this->resource['user']->display_name,
                'email' => $this->resource['user']->email,
                'created_at' => $this->resource['user']->created_at,
            ],
            'token' => [
                'abilities' => $this->resource['token']->accessToken->abilities,
                'accessToken' =>  $this->resource['token']->plainTextToken,
                'expires_at' => $this->resource['token']->accessToken->expires_at
            ],
        ];
    }
}

@nathandaly great approach, and I think it work great w/ ::make() too.
I didn't try wet, but is a good way to solve the 'problem'.
But I don't know about using it with ::collection(), because it is a collection of many models/data/objects, etc. Only if going through every item of collection and mapping/adding. Or maybe there's another possibility that Idk.

Why not just merge new input field in the controller, then access the request in the resource class, like this:
Controller:
public function index()
{
    request()->merge(['additional_data' => 'some_value']);

    return new YourResource::collection(Model::all());
}

YourResource:
class YourResource extends JsonResource
{
    public function toArray($request)
    {
         $request->additional_data;
    }
}


UAI: Animations

Task Description
Designing entry and exit animations for UAIs to enhance user engagement and feedback. It includes creating visually appealing animations that grab user attention and smoothly transition UI elements in and out of view.

[x] Designing Animation for UAIs @summikhan11
[ ] Implement Animation for UAIs @Raheel1258

This also means there is an empty state before and after the animation. The empty state will have no action - "You are all caught up" kind of piece.

All the inputs have been provided.

Implemented the animation, shared the branch and communicated the update with @pratyakxx.

Animation and integration for UAIs have been completed

Entry animations are triggered on login, leading to the home screen.
Skip actions trigger exit animations.
The implementation of the top 3 UAIs is scheduled for sprint 34

Completed


tlaplus-toolbox: Update to version 1.8.0 and fix checkver

tlaplus-toolbox: couldn't match 'TLAToolbox-([\d.]+)-win32.win32.x86_64.zip' in https://api.github.com/repos/tlaplus/tlaplus/releases/latest

[X] I have read the Contributing Guide.

/verify


Add Pod Stats.

Please, go through these steps before you submit a PR.

[x] My Pod Leader knows I'm working on this Pull Request
[x] I've explained what the Pull Request is adding.
[x] I've explained why this is important.

This PR resolves issue #4.

closes #4

Remove me
Add a horizontal line before footer

@akshitadixit Fixed the minor issues. Kindly review it.
Thanks!


[RFC]: Support sparse KV cache

Motivation
For current large model inference, KV cache occupies a significant portion of GPU memory, so reducing the size of KV cache is an important direction for improvement. Recently, several papers have approached this issue from different angles, detailed comparison in the table, including:

FastDecode: This method offloads all computation of KV cache to the CPU. The computation and storage of KV cache occurs on CPU.

Compression methods based on quantization (GEAR, Mixed Precision): By applying various quantization techniques, the size of individual token KV caches is reduced without decreasing the number of tokens stored in the KV cache. This method may also result in corresponding residual and outlier matrices, which need to be stored in memory but not in the KV cache. It may also involve quantizing unimportant token KV caches to reduce the memory footprint of the KV cache.

Partial KV cache eviction (H2O, SnapKV, LESS, Adaptive Compression, Scissorhands, Dynamic Memory Compression, StreamingLLM): By removing some relatively useless KV cache entries, the memory footprint of the KV cache is reduced. Essentially, this reduces the number of tokens stored in the KV cache without reducing the size of individual token KV caches.

When addressing the sparse KV cache issue, we have previously considered supporting quantization (VLLM has already implemented this), implementing quantization + outlier + residual like GEAR (not widely applicable as it requires generating outlier and residual for each token generation, which is costly), and implementing KV cache accumulation + appendix (not widely applicable as it requires models to be trained using the same method). Finally, the idea is to implement partial KV cache eviction, primarily aiming for generality and abstraction rather than being specific to one or two approaches. Considering that six of the sparse KV cache methods we found are based on evicting cache entries, this method is also suitable for modification as part of a framework to be integrated into VLLM.
Sparse KV Cache Workflow
First, let's clarify the required parameters, including:

An optional flag "--sparse-kv-cache-type" indicating if we want to specify any sparse KV cache type. Default is ‘auto’ without using any sparse KV cache type, otherwise, there could be various methods, such as attention scores for H2O.

Compression ratio for evicting KV cache entries: 20% if we want to achieve 80% reduction of KV cache usage. We can calculate the value of 'n' for recreating KV cache every 'n' step based on the compression ratio.

The entire workflow includes:

During the first decoding pass, besides computing the KV values for all input tokens, we also need to calculate and retain information about the priority ranking of all token pairs, such as attention scores in H2O.

During each scheduling of VLLM, we need to check whether 'n' steps have been completed, indicating the necessity for KV cache compression. If necessary, based on the priority ranking of tokens, one or more new KV cache blocks will be allocated, modifying the position information of input positions. The block manager will then manage the transfer of corresponding KV blocks from the original sequence group to the latest KV block. Finally, the reference count of the original KV block will be decremented, and the corresponding original KV blocks may even be released.

The corresponding KV values are added to the KV cache until the next compression of the KV cache after 'n' steps, repeating this process until the entire process is completed.

Proposed Change
Modified files mainly include

Modify vllm/core/scheduler.py: Add the corresponding logic for checking if sparse KV cache actions should be taken or not.

Modify vllm/core/block_manager_v1.py: Add the corresponding logic for updating block table mapping and manage the related allocated/free blocks.

Modify vllm/worker/model_runner.py: Update the position related code after sparse KV cache and pass the blocks_to_sparse_copy to the corresponding models.

Modify models, such as vllm/model_executor/models/opt.py: Indicating which KV should be filtered out.

Modify csrc/attention/attention_kernels.cu, csrc/cache_kernels.cu: Calculate attention score for selecting "important" tokens' KV and support sparse_cache_copy for copying "important" tokens' KV.

PR
PR link: https://github.com/vllm-project/vllm/pull/5752
Design doc
https://docs.google.com/document/d/13_cpb31P9VOmPGa_tZ70s7z1vXGP_UenXf1WVuIppCk/
Feedback Period.
No response
CC List.
No response
Any Other Things.
No response

Very exciting!

how many gpu memory can be saved?  do you have any benchmark data?

how many gpu memory can be saved? do you have any benchmark data?

This depends on the Sparse KV cache compression ratio, from current paper, 20% compression ratio is a rough number, which means 80% reduction. Now is pending feedback from community, there is no benchmark data yet.

Would you mind adding newly-proposed KV cache compression methods other than SnapKV and H2O? (i.e. PyramidKV)

Would you mind adding newly-proposed KV cache compression methods other than SnapKV and H2O? (i.e. PyramidKV)

Sure, it should not be difficult to add based on the current framework. Will be on my radar. Thanks!

Would you mind adding newly-proposed KV cache compression methods other than SnapKV and H2O? (i.e. PyramidKV)

Sure, it should not be difficult to add based on the current framework. Will be on my radar. Thanks!

Super cool! Thank you so much for your efforts!

This is exciting indeed. Few things

I think this can help the https://github.com/vllm-project/vllm/pull/3515 (streaming LLM) in particular with the block manager changes.
@cadedaniel please help review the block manager changes.
@WoosukKwon please help review the paged attention kernel interface change.

Would you mind adding newly-proposed KV cache compression methods other than SnapKV and H2O? (i.e. PyramidKV)

Sure, it should not be difficult to add based on the current framework. Will be on my radar. Thanks!

Would you mind @ me when the new method is added? can't wait to have a try with vLLM!

https://github.com/microsoft/MInference
Is there a combination of dynamic sparse attention and sparse KV cache?

https://github.com/microsoft/MInference Is there a combination of dynamic sparse attention and sparse KV cache? The vllm implementation is provided here

This repo does not provide sparse KV cache implementation in vLLM. They only provide HF ones.

https://github.com/microsoft/MInference Is there a combination of dynamic sparse attention and sparse KV cache? The vllm implementation is provided here

This repo does not provide sparse KV cache implementation in vLLM. They only provide HF ones.

for vLLM,
from vllm import LLM, SamplingParams

from minference import MInference

llm = LLM(model_name, max_num_seqs=1, enforce_eager=True, max_model_len=128000)
Patch MInference Module
+minference_patch = MInference("vllm", model_name)
+llm = minference_patch(llm)
outputs = llm.generate(prompts, sampling_params)
using only the kernel,
from minference import vertical_slash_sparse_attention, block_sparse_attention, streaming_forward
attn_output = vertical_slash_sparse_attention(q, k, v, vertical_topk, slash)
attn_output = block_sparse_attention(q, k, v, topk)
attn_output = streaming_forward(q, k, v, init_num, local_window_num)
For more details, please refer to our Examples and Experiments. You can find more information about the dynamic compiler PIT in this paper and on GitHub.

https://github.com/microsoft/MInference Is there a combination of dynamic sparse attention and sparse KV cache? The vllm implementation is provided here

This repo does not provide sparse KV cache implementation in vLLM. They only provide HF ones.

for vLLM,
from vllm import LLM, SamplingParams

from minference import MInference

llm = LLM(model_name, max_num_seqs=1, enforce_eager=True, max_model_len=128000)
Patch MInference Module
+minference_patch = MInference("vllm", model_name) +llm = minference_patch(llm)
outputs = llm.generate(prompts, sampling_params) using only the kernel,
from minference import vertical_slash_sparse_attention, block_sparse_attention, streaming_forward
attn_output = vertical_slash_sparse_attention(q, k, v, vertical_topk, slash) attn_output = block_sparse_attention(q, k, v, topk) attn_output = streaming_forward(q, k, v, init_num, local_window_num) For more details, please refer to our Examples and Experiments. You can find more information about the dynamic compiler PIT in this paper and on GitHub.

Are you an author of this repo? Your attached code seems not containing sparse kv cache implementation. and the Examples folder neither. Do I miss something?

an

I am not the author of this repo. It's not sparse kv cache, it's sparse attention. Isn't there something in common?

https://github.com/microsoft/MInference Is there a combination of dynamic sparse attention and sparse KV cache? The vllm implementation is provided here

This repo does not provide sparse KV cache implementation in vLLM. They only provide HF ones.

for vLLM,
from vllm import LLM, SamplingParams

from minference import MInference

llm = LLM(model_name, max_num_seqs=1, enforce_eager=True, max_model_len=128000)
Patch MInference Module
+minference_patch = MInference("vllm", model_name) +llm = minference_patch(llm)
outputs = llm.generate(prompts, sampling_params) using only the kernel,
from minference import vertical_slash_sparse_attention, block_sparse_attention, streaming_forward
attn_output = vertical_slash_sparse_attention(q, k, v, vertical_topk, slash) attn_output = block_sparse_attention(q, k, v, topk) attn_output = streaming_forward(q, k, v, init_num, local_window_num) For more details, please refer to our Examples and Experiments. You can find more information about the dynamic compiler PIT in this paper and on GitHub.

Are you an author of this repo? Your attached code seems not containing sparse kv cache implementation. and the Examples folder neither. Do I miss something?

an
I am not the author of this repo. It's not sparse kv cache, it's sparse attention. Isn't there something in common?

Great work! However, I noticed that your implementation only adapts for memory-friendly attention for xformers. Do you think it would be a lot of work to adapt it for Flash-Attention 2 with the current architecture? Or do you have plans to adapt for FlashAttention 2 in the future?
https://github.com/vllm-project/vllm/blob/main/vllm/attention/backends/flash_attn.py

btw, I tried long prompt in your framework, found that in long prompt scenario (approximately 3k tokens) the outputs make no sense just repeat some tokens to its outputs limit. I think maybe it is related to the sparse kv implementation?


Warn users about migration mode

It has come to my attention that many users forget to remove their old permission plugin when migrating or try to use two perm plugins.
Since LP already detects that (for migration purposes) I think it would make sense to warn players that another permission plugin is installed at that theý need to remove it (after the migration if they want to migrate) when they use LP commands and at the end of the migration command.
Maybe also display a warning to players with the log permission when they log in.
Just a quality of life feature but I think it could help a lot of people.

Something like [Migration] Done! Remember to stop your server and remove your old permission plugin, to make the migration take affect. perhaps?

And when running a normal command something like Hey. You still have another permission plugin installed. If you want to migrate from that, please migrate, else remove it, or LuckPerms won't manage your permissions


botocore.vendored.requests is becoming deprecated

It looks like botocore.vendored.requests is being deprecated from botocore. We should instead move towards using requests directly.
This may increase the complexity of installing, so maybe I should vendor a copy of requests directly in the library. Need to review options.

Decided not to include the vendored copy as request is a bit of a mess in terms of other dependencies and finding a way to reliably vend the library may be difficult.

Waiting for 1.1 release

3.8 Lambda environment uses an old version of botocore. Used this to test, and confident new logic works. Waiting for 1.1 release.


Self update functionality

Would be pretty wicked if the tool could have a flag to update itself automatically from github releases.

Awesome idea.

Implemented in https://github.com/bennothommo/october-cli/commit/96cf2074ee0c8b3d95ac9f6c1f5b42d4a79d7e12.

Wicked awesome dude :)


escaping &_acute and &_tilde

Even with "default_lowercase_only_ascii": truethe only way to exclude Spanish "tildes" (Camión, último) and España was by adding one by one id_replacements for each letter. My user-settings look like this:
{
  "default_autolink": true,
  "default_bracket": "round",
  "default_depth": 2,
  "default_autoanchor": true,
  "default_lowercase_only_ascii": true,
  "default_style": "unordered",
  "id_replacements": {
    "-": " ",
    "a": ["&aacute", "á"],
    "e": ["&eacute", "é"],
    "i": ["&iacute", "í"],
    "o": ["&oacute", "ó"],
    "u": ["&uacute", "ú"],
    "A": ["&Aacute", "Á"],
    "E": ["&Eacute", "É"],
    "I": ["&Iacute", "Í"],
    "O": ["&Oacute", "Ó"],
    "U": ["&Uacute", "Ú"],
    "n": ["&ntilde", "ñ"],
    "N": ["&ntilde", "Ñ"],

    "" : ["<",">","&","'",""","<",">","&","'",""","!","#","$","&","'","(",")","*","+",",","/",":",";","=","?","@","[","]","`","\"", ".","<",">","{","}","™","®","©"]
    }

}

Any idea to make this more efficiently? There are still a bunch of "weird" characters that won't work as anchors in a html file.

hmmmm @naokazuterada is it possible to detect the encoding of the text/file in SL? - based on that a conversion could be made to a simpler format. I work with DNS and punycode springs to mind as a solution to a somewhat similar problem.

@ghost
I'm sooo sorry for late reply. 🤕
Today I added a new feature URI encoding. And I saw all links are working correctly on Gitlab(sample) and Github(sample).
I hope this fix your problem. 🦊  I'm looking forward to your response if you don't mind.

Hi @naokazuterada,
I recommend we close this issue, lets reopen if the issue persists. An expected fix has been implemented and shipped.

@jonasbn OK, thanks. Close it.


Add Vim swap files to .gitignore

Split this out from https://github.com/sirupsen/logrus/pull/612, as it's a separate change.
I noticed this when working on a new computer for which I hadn't yet copied my standard .gitignore_global. While it's true that Vim swap files, OS X .DS_Store files, and the like should be in a global gitignore, in my experience, if these aren't also in the per-project gitignore, it's easy for them to make their way into the project by accident.

:-1:.
These should absolutely be in your global gitignore, and we cannot add all swap files for all IDEs in every project.


How to put the slots as mandatory.

Rasa Core version: 0.9.0a5
Issue:
Example: " I want to book a movie ticket."
Then Bot should ask to user that please provide the time & locations. Until the slots :- locations & time is not fill the Bot will repeat the question.

You can use Rasa's FormAction class to achieve this. Forms make it easier to define required fields and it handles most of the stuff for you. Relevant documentation with examples can be found here.

Ya, I have tried that, but still not getting that. Please help me if  I'm doing any mistake here.
Yaml file
intents:
  - greetings
  - booking
  - confirm
  - goodbye

entities:
- city
- destination_location
- source_location

slots:
  city:
    type: text
  source_location:
    type: text
  destination_location:
    type: text
  requested_slot:
    type: unfeaturized

templates:
  act_greet:
    - "Hi there!!"
    - "Greetings for the day"
    - "Hello, Have a good day"
    - "How can I help you"

  act_booking:
    - "booking a ride"
  act_confirm:
    - "Your travelling from {source_location}, {city} to {destination_location}, {city} on {travel_date} {travel_time}
    Are you want to Book this ?"
  act_goodbye:
    - "Good Bye"
  act_cancel:
    - "you have cancel your booking!!"
  utter_ask_source_location:
    - "Please provide me source location"
  utter_ask_destination_location:
    - "please provide me destination location"
  utter_ask_city:
    - "in which city you currently living"

actions:
- act_greet
- act_confirm
- act_booking
- act_goodbye
- act_cancel
- actions.ActionBooking
#- bot.ActionSuggest

Stories.md file

## story_1
* greet
 - act_greet
* booking
 - action_booking
 - slot{"requested_slot": "source_location"}
 - slot{"requested_slot": "destination_location"}
 - slot{"requested_slot": "city"}

* bye
 - act_goodbye

custom action class of actions.py file
class RestaurantAPI(object):
   def search(self, info):
       return "papi’s pizza place"

class ActionBooking(FormAction):

   RANDOMIZE = False

   @staticmethod
   def required_fields():
       return [
           FreeTextFormField("destination_location", "destination_location"),
           FreeTextFormField("source_location", "source_location"),
           FreeTextFormField("city", "city")
       ]

   def name(self):
       return "action_booking"

   def run(self, dispatcher, tracker, domain):
       dispatcher.utter_message("looking for restaurants")
       restaurant_api = RestaurantAPI()
       restaurants = restaurant_api.search(tracker.get_slot("city"))
       return

output with debug command, Here the slots source & destination locations are filled, but the bot not asked regarding missing slot city.

I think in our actions.py file we declared  method which name is required_fields() as per the documents.
but it seems to that method is not executing while calling our action. So for checking purpose I have put logs in that required_fields() method but, that logs were not generating in our output, while we are run our bot.so, I think problem is in required_fields method.
if i am right can anyone please assist why it is not calling. or if i am wrong, assist me how to apply required slots in bot.
below are the custom action file that I put in our action.py file
class RestaurantAPI(object):
   def search(self, info):
       return "papi’s pizza place"

class ActionBooking(FormAction):

   RANDOMIZE = False

   @staticmethod
   def required_fields():
       logger.debug("---------------------------calling required field in action.py  file------------- ")
       return [
           EntityFormField("destination_location", "destination_location")
       ]

   def name(self):
       return "action_booking"

   def run(self, dispatcher, tracker, domain):
       dispatcher.utter_message("looking for restaurants")
       restaurant_api = RestaurantAPI()
       restaurants = restaurant_api.search(tracker.get_slot("city"))
       return

Here I'm attaching source file.Taxi bot.zip

The suggested solution is a part of version 0.9 . It has not been released yet. How do I get it through 'pip' ?

You can download the latest version from Github.
Unzip the folder..

Change the current directory to the folder to which you unzipped
After that, Type this in the command line: python setup.py install
Thanks,
Santhosh.
Sent from my iPhone

On 24-May-2018, at 2:24 PM, Medam Mahesh<EMAIL_ADDRESS>wrote:
The suggested solution is a part of version 0.9 . It has not been released yet. How do I get it through 'pip' ?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

or pip install rasa_core==0.9.0a3

Great !!
It worked. Thanks guys.

Hi @memahesh, I have a question. How come it worked for you '''@staticmethod
def required_fields():
return [
FreeTextFormField("destination_location", "destination_location"),
FreeTextFormField("source_location", "source_location"),
FreeTextFormField("city", "city")
]'''
FreeTextFormField does not take 2 named entities, while you are passing 2 args.
In https://github.com/RasaHQ/rasa_core/blob/master/rasa_core/actions/forms.py
'''class FreeTextFormField(FormField):
def __init__(self, slot_name):
    self.slot_name = slot_name'''

Do let me know how you were able to work with FreeTextFormField. Thanks.

I haven't worked with FreeTextFormField . I was using EntityFormField and BooleanFormField for my use case. Now that I look at the code in the question, it is written wrongly.
If you want to use the FreeTextFormField , just give it the slot name you want to be filled. Whenever the value in requested_slot is set to the slot name given in FreeTextFormField, the slot will be filled with the next user message.

My issue is still unresolved , any hint or suggestion is appreciated. Thanks

ActionBooking is taking object FormAction and there is no submit.

@DhruvMevada you need to give more details as to what's not working now. Have you tried all the suggestions given in the thread here?


fix: Apply design changes from figma

This is mainly fixing the layout for space delegates page
Other changes:

Add divider in the sidebar
Fix delegate card layout
If not following show Join button as primary, otherwise show delegate/new proposal as primary button

Also missing spacing after the loading placeholder

This page is work in progress and not been changes in this PR


Package request: Swig 4.1.1

Project description
Nix already packages SWIG 4.0.2, but 4.1.1 adds some new features, such as support for unique_ptr.
@ryantm @orivej
Metadata

homepage URL: https://www.swig.org
source URL: https://github.com/swig/swig
license: GPL3
platforms: linux, darwin

JFYI, Swig 4.2.0 is available
https://github.com/swig/swig/blob/master/RELEASENOTES


Twister pytest

Update #29427 here.

why are you starting a new PR?

why are you starting a new PR?

Youhua's working pc is used by other people and working environment is changed, I cherry pick these PR and push to my repo, I have no password to access youhua's repo

@enjiamai, @Zhaoningx, please review the PR.

My comments from the origin of this PR haven't been addressed so I don't know why you re-requested my review. TBH I am seeing a lot of issues with this PR from the beginning and was already reviewing it several times. I find the idea behind the workflow and the implementation confusing. It took me a lot of time to figure out what was changed and what not since my last reviews and this process repeats with each iteration of this PR. Therefore, I won't review it again. I am marking this PR as "requires changes". I believe I already provided a lot of feedback in all my previous comments, which are still valid. If other reviewers decide that this PR is fine, feel free to dismiss my review. Please don't ask me to re-review it anymore.

@PerMac Hi PerMac, I'm so sorry for my bad behavior, I should respond in time, I apologize. It took me a lot of time to comprehend #29427 after I took over this patch, thanks to your comments I've got this patch much better even though it's not so perfect now. Thank you for your help PerMac, I appreciate it.

Some test cases of tracing feature depend on this PR. Can the PR be merged now?

@nashif, Xianglin has addressed the all comments. Can the PR be merged?

@PerMac thank you for you advice. pytest harness aim to handle artifact generated by test case, so I provide a simplified handle() interface of pytest harness to handle test case itself, and call pytest tool in another function pytest_run() which is irrelevant to console output.

@nashif As per PerMac's advice, this patch is refined, can you help to review?

@PerMac Thank you for your comments, I think I've addressed them, if I haven't please let know, I'll try my best to refine it.

The code looks better. But have you tried doing some basic testing? This refers also to all other reviewers, that's why I asked all of them to re-review. Some reviews are positive from the beginning even though a lot has changed... Now you will always get a PASSED result. You can even delete the whole pytest folder with your test and it still "will pass"

@PerMac , I had a discussion with Xianglin. Yes, you are right. It looks like that there is a bug in the latest code. Xianglin will update the PR to fix it soon.

The code looks better. But have you tried doing some basic testing? This refers also to all other reviewers, that's why I asked all of them to re-review. Some reviews are positive from the beginning even though a lot has changed... Now you will always get a PASSED result. You can even delete the whole pytest folder with your test and it still "will pass"

@PerMac I place pytest_run() in wrong place and pytest report test result after twister collect test results, so it always pass.
when test failed, twister let you see handler.log, if there is not that file, it let you see build.log, it is strange. so I create handler.log in pytest_run() function no matter pytest pass or not and append pytest output in it.

@nashif now I append output of pytest tool in handler.log to provide more info than report.xml, if there is any thing to refine, let know please.


dhcp: Kea not allowing to specify pools per interface

Important notices
Before you add a new report, we ask you kindly to acknowledge the following:

[x] I have read the contributing guide lines at https://github.com/opnsense/core/blob/master/CONTRIBUTING.md
[x] I am convinced that my issue is new after having checked both open and closed issues at https://github.com/opnsense/core/issues?q=is%3Aissue

Is your feature request related to a problem? Please describe.
Trying to migrate from ISC DHCP, where I have a LAN interface which dishes out addresses from it's own pool (say, <IP_ADDRESS>-199) and a WIFI interface which dishes out addresses from it's pool (say, <IP_ADDRESS>-199), and various other ranges which should only apply to certain interfaces.
This allows me to then trust/treat connections from each range differently from a security standpoint.
I can't see how the current approach of having one set of pools which apply to all configured interfaces would allow me to accomplish this arrangement. It seems to make some awkwardly simplistic topology/routing assumptions.
Describe the solution you like
I guess a field per pool definition which could be used to apply it to one or more interfaces, if that's even possible with Kea.
Describe alternatives you considered
N/A
Additional context
N/A

You did try to add both subnets and inspect the leases? I would expect that kea prefers an address that fits the interface subnet. Their documentation is available at https://kea.readthedocs.io/en/latest/arm/intro.html when you would like to deep dive into the options it offers.

@AdSchellevis - no, I didn't try that, but it makes sense now. I'll give that a try later and re-open this if it's still an issue. Thanks!


Peers and block height not updated during IBD

Peers and Block Height is not updated in the Overview during initial blockchain download.
Block Height stays at zero, although siac status reports the correct block height.

An odd error. Wasn't a problem before, and why is it only a problem during IBD?

This issue seems to have been fixed


Alignment issue

I tried to align in Windows using Alt+ctrl+a.
but i found the alignment was not proper in my ejs file.
it's not at all working in js file.
please help

could you please share some screenshots to explain the issue?
have you already checked the plugin settings?

can you give us some more informations?


Is it expected when get_device_properties is called on multiple devices at them same time?

Hi, I've just found driver.utils.get_device_properties is slow when multiple devices call it at the same time. Here is the test code:
from triton.runtime import driver
import timeit
import torch

device = torch.cuda.current_device()
print(driver.utils.get_device_properties(device)["max_shared_mem"])
n = 1000
total = timeit.timeit(lambda: driver.utils.get_device_properties(device), number=n)
print(total / n)

When run it using python xxx.py, it costs less than 1 ms with A100 GPU. But if run it using torchrun --nproc-per-node=8 xxx.py, it is about 10x times slower. Is this behavior expected?

Sounds suspiciously like the GPU driver is holding a global lock while we retrieve the properties.  If so, there's nothing that can be done about it in Triton.


remove google analytics bower component from CDNizer and rename to avoid being blocked by browser adblockers

We recently switched from hosting our own js components to loading as many as possible from CDN, but this reverts a fix that was made awhile back to avoid being blocked by various adblockers, as the default name of the library contains 'google-analytics', which is included on many blocklists.

Relevant issue: https://github.com/angulartics/angulartics/issues/58


Server updater doesn't seem to work all the time

Mostly happens once it updates big or lots of files like kits.

Can't really explain exactly what happened. Will re-open this once this issue happens again.


Add IGSN - International Generic Sample Number - to PIDMR Backend

Provider to Add:
IGSN - International Generic Sample Number

Done.
Resolution mode implemented: landingpage
Check and close please with the following IGSN:
AU124


Access control on IOU request

Details

This PR adds AccesOrNotFoundWrapper to IOU request flow
Fixed Issues

$ https://github.com/Expensify/App/issues/41305
PROPOSAL: https://github.com/Expensify/App/issues/41305#issuecomment-2095931761
Tests

Precondition: User does not have a workspace

Navigate to send invoice by URL/deep link (create/invoice/start/1/7783051691252045)
Verify not found page shows

[x] Verify that no errors appear in the JS console

Offline tests

NA
QA Steps

Precondition: User does not have a workspace

Navigate to send invoice by URL/deep link (create/invoice/start/1/7783051691252045)
Verify not found page shows

[x] Verify that no errors appear in the JS console

PR Author Checklist

[x] I linked the correct issue in the ### Fixed Issues section above
[x] I wrote clear testing steps that cover the changes made in this PR

[x] I added steps for local testing in the Tests section
[x] I added steps for the expected offline behavior in the Offline steps section
[x] I added steps for Staging and/or Production testing in the QA steps section
[x] I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
[x] I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
[x] I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).

[x] I included screenshots or videos for tests on all platforms
[x] I ran the tests on all platforms & verified they passed on:

[x] Android: Native
[x] Android: mWeb Chrome
[x] iOS: Native
[x] iOS: mWeb Safari
[x] MacOS: Chrome / Safari
[x] MacOS: Desktop

[x] I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
[x] I followed proper code patterns (see Reviewing the code)

[x] I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
[x] I verified that the left part of a conditional rendering a React component is a boolean and NOT a string, e.g. myBool && <MyComponent />.
[x] I verified that comments were added to code that is not self explanatory
[x] I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
[x] I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method

[x] If any non-english text was added/modified, I verified the translation was requested/reviewed in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:

[x] I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
[x] I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
[x] I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
[x] I verified the JSDocs style guidelines (in STYLE.md) were followed

[x] If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
[x] I followed the guidelines as stated in the Review Guidelines
[x] I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
[x] I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
[x] I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
[x] I verified that if a function's arguments changed that all usages have also been updated correctly
[x] If any new file was added I verified that:

[x] The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory

[x] If a new CSS style is added I verified that:

[x] A similar style doesn't already exist
[x] The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))

[x] If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
[x] If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
[x] If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
[x] If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
[x] If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:

[x] I verified that all the inputs inside a form are aligned with each other.
[x] I added Design label and/or tagged @Expensify/design so the design team can review the changes.

[x] If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
[x] If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native

Android: mWeb Chrome

https://github.com/Expensify/App/assets/113963320/748355b7-c4c9-4a83-9578-35d8aae424d2

iOS: Native

https://github.com/Expensify/App/assets/113963320/5567039a-38ef-44a1-bcc7-d757a7d8bacf

iOS: mWeb Safari

https://github.com/Expensify/App/assets/113963320/8ad27c0b-a8f3-4b62-b6a2-20b7147d069a

MacOS: Chrome / Safari

MacOS: Desktop

Now the the merge freeze is lifted, could you possibly resolve the conflicts, @tienifr? 🙏

:hand: This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

🚀 Deployed to staging by https://github.com/cristipaval in version: 1.4.77-11 🚀

platform
result

🤖 android 🤖
failure ❌

🖥 desktop 🖥
success ✅

🍎 iOS 🍎
success ✅

🕸 web 🕸
success ✅

🚀 Deployed to staging by https://github.com/cristipaval in version: 1.4.77-11 🚀

platform
result

🤖 android 🤖
success ✅

🖥 desktop 🖥
success ✅

🍎 iOS 🍎
success ✅

🕸 web 🕸
success ✅

🚀 Deployed to production by https://github.com/mountiny in version: 1.4.78-5 🚀

platform
result

🤖 android 🤖
success ✅

🖥 desktop 🖥
success ✅

🍎 iOS 🍎
success ✅

🕸 web 🕸
success ✅